高通开发笔记---Yangtze worknote
时间:2023-02-02 23:00:01
1. repo init -u git://review.sonyericsson.net/platform/manifest -b volatile-jb-mr1-yangtze
2. https://wiki.sonyericsson.net/androiki/CN3-II/Bringup_Trail_FC34 如何编译3. https://wiki.sonyericsson.net/androiki/PLD_CM/Yangtze 如何编译和flash
4. https://wiki.sonyericsson.net/androiki/MIB_Tokyo/Rhine/Hardware_Watchdog_debugging
小技巧:
MISCTA 2473控制kernel log输出: 01 输出,00 无输出
repo sync [目录路径] 比如: kenel,system/vold
repo sync kernel 则只是同步kernel目录下的代码
grep "ifelse" * -r 在当前目录下(递归)搜索所有文件ifelse的内容
owner:xiaoguang2.lu@sonymobile.com status:merged //查找谁提交并且已经merged的gerrit
printk("func = %pf",func)可打印函数名称
充电缩写:(acronym)
FSM: Finite State Machine
CC: Coulcomb Counter
FCC: Full Charge Capacity
OCV: Open Circuit Voltage
PMIC: Power Management IC
PC: Percentage Charge
RC: Remaining Charge
SOC: State of Charge
RUC: Remaining Usable Charge
UUC: Unusable Charge
一、DTS 学习
1. kernel/arch/arm/boot/dts 目录下包含所有的dts.
a. board , msm8226.dtsi
b. pmic, msm-pm8226.dtsi
2. kernel/Androidkernel.mk; Android makefile to build kernel as a part of Android Build
3. kernel/arch/arm/configs 目录下保存对应的config定义, CONFIG_XXXXXX
4. 可参考 jb-mr1-rhine/kernel/arch/arm/boot/dts/msm8974-rhine_togari_row.dtsi
二、LCD Porting
1. http://review.sonyericsson.net/#/c/508903
三、Charger bringup
1. 和battery and hw guys 确定相关 硬件参数
2. http://review.sonyericsson.net/#/c/516297/
3. kernel 发送给battery_logging的uevent格式?
power_supply_uevent@kernel/drivers/power/power_supply_sysfs.c 该函数添加发送的信息到uevent
ret = add_uevent_var(env, "POWER_SUPPLY_NAME=%s", psy->name); //psy->name="battery"
for (j = 0; j < psy->num_properties; j++) {
attr = &power_supply_attrs[psy->properties[j]]; //得到对应的power supply attr,
attrname = kstruprdup(attr->attr.name, GFP_KERNEL);//会把属性名字转成大写,比如“status”->"STATUS"
ret = add_uevent_var(env, "POWER_SUPPLY_%s=%s", attrname, prop_buf); //增加该属性的信息到uevent buffer中
}
qpnp_charger_probe@kernel/drivers/power/qpnp-charger.c中会定义"battery"的properties = msm_batt_power_props
static enum power_supply_property msm_batt_power_props[] = { //对应power_supply_attrs[]@kernel/drivers/power/power_supply_sysfs.c
POWER_SUPPLY_PROP_CHARGING_ENABLED, //表示这些属性是被battery psy所需要的属性,具体如何得到可查看
POWER_SUPPLY_PROP_STATUS, //qpnp_batt_power_get_property 函数
POWER_SUPPLY_PROP_CHARGE_TYPE, //这些属性会添加到/sys/class/power_supply/battery
POWER_SUPPLY_PROP_HEALTH,
POWER_SUPPLY_PROP_PRESENT,
POWER_SUPPLY_PROP_TECHNOLOGY,
POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN,
POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
POWER_SUPPLY_PROP_VOLTAGE_NOW,
POWER_SUPPLY_PROP_CAPACITY,
POWER_SUPPLY_PROP_CURRENT_NOW,
POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
POWER_SUPPLY_PROP_TEMP,
POWER_SUPPLY_PROP_SYSTEM_TEMP_LEVEL,
};
static struct device_attribute power_supply_attrs[] = {
/* Properties of type `int' */
POWER_SUPPLY_ATTR(status), //表示attr.name = "status"
POWER_SUPPLY_ATTR(charge_type),
...
}
4. parse_uevent@vendor/semc/hardware/power/charge-log/battery_logging/battery_logging.c会分析从kernel传上来的power uevent格式
发送该uevent的path '\0'
POWER_SUPPLY_NAME=battery '\0'
POWER_SUPPLY_CHARGING_ENABLE=%d '\0'
POWER_SUPPLY_CHARGING_STATUS=%d '\0'
...
5. 顺便分析下UEvent如何传递给user space?
a. @kernel/drivers/power/qpnp-charger.c中只要有任何关于charger的变化,比如charger的各种irq handler
b. @kernel/drivers/power/qpnp-bms.c中calculate_soc_from_voltage和calculate_state_of_charge
c. @kernel/arch/arm/boot/dts/msm-pm8226.dtsi中有pm8226_bms的device定义,msm8226-cn3ii.dtsi中有pm8226_bms的定义补充
其中没有 qcom,use-voltage-soc 的定义所以chip->use_voltage_soc=false, 也就是只用calculate_state_of_charge计算soc
顺便chip->use_external_rsense=true,表示用外部的rsense.
d. @kernel/driver/power/power_supply_core.c中的power_supply_changed会被以上内容调用
schedule_work(&psy->changed_work);
e. power_supply_changed_work@kernel/driver/power/power_supply_core.c
kobject_uevent(&psy->dev->kobj, KOBJ_CHANGE); //action=KOBJ_CHANGE
f. kobject_uevent_env@kernel/lib/kobject_uevent.c
static const char *kobject_actions[] = {
[KOBJ_ADD] = "add",
[KOBJ_REMOVE] = "remove",
[KOBJ_CHANGE] = "change",
[KOBJ_MOVE] = "move",
[KOBJ_ONLINE] = "online",
[KOBJ_OFFLINE] = "offline",
};
以下为添加到uevent buffer中发送的内容
/* default keys */
retval = add_uevent_var(env, "ACTION=%s", action_string);//action_string="change"
retval = add_uevent_var(env, "DEVPATH=%s", devpath);//devpath = kobject_get_path(kobj, GFP_KERNEL);
retval = add_uevent_var(env, "SUBSYSTEM=%s", subsystem);//也就是uevent 的name
retval = uevent_ops->uevent(kset, kobj, env); //会调用到power_supply_uevent@kernel/drivers/power/power_supply_sysfs.c
//也就是会添加具体的power battery信息到uevent buffer中了
retval = add_uevent_var(env, "SEQNUM=%llu", (unsigned long long)++uevent_seqnum); //增加uevent发送的计数,
//KERNEL_ATTR_RO(uevent_seqnum); 用cat sys/kernel/uevent_seqnum 可以查看
CONFIG_NET=y被定义,以下代码是发送uevent到userspace 的关键代码
#if defined(CONFIG_NET)
/* send netlink message */
list_for_each_entry(ue_sk, &uevent_sock_list, list) { //uevent_net_init会初始化一个uevent_sock,也只有一个
if (!netlink_has_listeners(uevent_sock, 1))
continue;
/* allocate message with the maximum possible size */
len = strlen(action_string) + strlen(devpath) + 2;
skb = alloc_skb(len + env->buflen, GFP_KERNEL);
if (skb) {
retval = netlink_broadcast_filtered(uevent_sock, skb,
0, 1, GFP_KERNEL,
kobj_bcast_filter,
kobj);
} else
retval = -ENOMEM;
}
#endif
6. Battery充满的识别
1). @kernel/arch/arm/boot/dts/msm-pm8226.dtsi和msm8226-cn3ii.dtsi
qcom,chg-chgr@1000 {
status = "disabled";
reg = <0x1000 0x100>;
interrupts = <0x0 0x10 0x0>,
<0x0 0x10 0x1>,
<0x0 0x10 0x2>,
<0x0 0x10 0x3>,
<0x0 0x10 0x4>,
<0x0 0x10 0x5>,
<0x0 0x10 0x6>,
<0x0 0x10 0x7>; //具体的含义?
interrupt-names = "vbat-det-lo",
"vbat-det-hi",
"chgwdog",
"state-change",
"trkl-chg-on",
"fast-chg-on",
"chg-failed",
"chg-done";
};
2). qpnp_chg_hwinit@kernel/drivers/power
chip->chg_done_irq = spmi_get_irq_byname(chip->spmi,spmi_resource, "chg-done");
如何触发"chg-done"这个interrupt?
3).获取当前充电状态
rc = qpnp_chg_read(chip, &chgr_sts,INT_RT_STS(chip->chgr_base), 1);
如果chgr_sts&CHG_DONE_IRQ == 1则表示充电完成
4).http://review.sonyericsson.net/#/c/480849, workaround for fake charge done
6. 如何查看当前的charger信息?
/sys/devices/qpnp-charger-eab16c00
7. 手机/sys/class/power_supply/battery和bms和usb的来源
1)qpnp_charger_proble@kernel/drivers/power/qpnp-charger.c
if (chip->bat_if_base){
chip->batt_psy.name = "battery";
chip->batt_psy.type = POWER_SUPPLY_TYPE_BATTERY;
chip->batt_psy.properties = msm_batt_power_props;//所选择的属性
rc = power_supply_register(chip->dev, &chip->batt_psy);//注册到/sys/class/power_supply/battery
}
2)qpnp_bms_probe@kernel/drivers/power/qpnp-bms.c
chip->bms_psy.name = "bms";
chip->bms_psy.type = POWER_SUPPLY_TYPE_BMS;
chip->bms_psy.properties = msm_bms_power_props;
rc = power_supply_register(chip->dev, &chip->bms_psy);//注册到/sys/class/power_supply/bms
3)msm_otg_proble@kernel/drivers/usb/otg, 注意CONFIG_USB_MSM_OTG的定义在kernel/drivers/usb/gadget/Kconfig: config USB_CI13XXX_MSM-->select USB_MSM_OTG
motg->usb_psy.name = "usb";
motg->usb_psy.type = POWER_SUPPLY_TYPE_USB;
motg->usb_psy.supplied_to = otg_pm_power_supplied_to;
msm_otg_register_power_supply(pdev, motg))->power_supply_register(&pdev->dev, &motg->usb_psy);
4)充电器的识别过程
msm_chg_detect_work@kernel/drivers/usb/otg/msm_otg.c 主要完成充电器类别的识别过程
->msm_otg_notify_chg_type@msm_otg.c
->power_supply_set_supply_type(psy, charger_type)@msm_otg.c;//psy=motg->usb_psy
->psy->set_property(psy, POWER_SUPPLY_PROP_TYPE,&ret); //@kernel/drivers/power/power_supply_core.c, 最后会call
->otg_power_set_property_usb@msm_otg.c 但是该函数中没有POWER_SUPPLY_PROP_TYPE属性的设置??
->queue_work(system_nrt_wq, &motg->sm_work);->msm_otg_sm_work[otg->phy->state=OTG_STATE_B_IDLE]
-->msm_otg_notify_charger->msm_otg_notify_power_supply->power_supply_set_online//设置是否online
四、Audio Jack Porting
0. HW Guys: Wang, Junchao(9601), Liu,Xun
1. kernel/sound/soc/msm/msm8226.c;
kernel/sound/soc/codecs/wcd9306.c,Wcd9xxx-mbhc.c
tapan_slimbus_irq
2. adb shell 'echo -n "file wcd9xxx-mbhc.c +p" > /sys/kernel/debug/dynamic_debug/control'
3. wcd9xxx_insert_detect_setup@Wcd9xxx-mbhc.c
0x6c-->0x68 //参考80-NC836-2 WCD9306 AUDIO CODEC SOFTWARE INTERFACE.pdf 中0x14B MBHC_INSERT_DET_STATUS寄存器的说明,PLUG_TYPE 0:NC 1:NO (注意原来的文档有错)
Audio Jack不插入耳机时MBHC_HSDET是低,插入耳机时MBHC_HSDET是高,所以是Normal Close(NC)类型的Audio Jack
4. @kernel/sound/soc/msm/msm8226.c;
S(v_no_mic, 30);
S(v_hs_max, 1650);
5. @kernel/sound/soc/codecs/Wcd9xxx-mbhc.c
wcd9xxx_codec_get_plug_type->
wcd9xxx_find_plug_type
6. Audio jack检测耳机的流程
在函数wcd9xxx_mbhc_decide_swch_plug中如果检测到是headset则不重复多次检测,如果是headphone则需要
wcd9xxx_schedule_hs_detect_plug(mbhc,&mbhc->correct_plug_swch);启动重复检测以确认正确
插入headphone耳机
<7>[ 105.233608] wcd9xxx_mech_plug_detect_irq: enter
<7>[ 105.233625] wcd9xxx_swch_irq_handler: enter
<7>[ 105.238692] wcd9xxx_swch_irq_handler: Acquiring BCL
<7>[ 105.238706] wcd9xxx_swch_irq_handler: Acquiring BCL done
<7>[ 105.238864] wcd9xxx_swch_irq_handler: Current plug type 0, insert 1
<7>[ 105.238876] wcd9xxx_cancel_hs_detect_plug: Canceling correct_plug_swch
<7>[ 105.238885] wcd9xxx_cancel_hs_detect_plug: Release BCL
<7>[ 105.238897] wcd9xxx_cancel_hs_detect_plug: Acquiring BCL
<7>[ 105.238907] wcd9xxx_cancel_hs_detect_plug: Acquiring BCL done
<7>[ 105.239014] wcd9xxx_mbhc_detect_plug_type: enter
<7>[ 105.497933] wcd9xxx_mbhc_decide_swch_plug: enter
<7>[ 105.498378] wcd9xxx_codec_get_plug_type: enter
<7>[ 105.501350] wcd9xxx_mbhc_setup_hs_polling: enter
...
<7>[ 105.590299] wcd9xxx_find_plug_type: DCE #0, fc06, V 0008(0008), GND 0, VDDIO 0, HPHL 1 TYPE 2
<7>[ 105.590317] wcd9xxx_find_plug_type: DCE #1, fc06, V 0008(0008), GND 0, VDDIO 0, HPHL 1 TYPE 2
<7>[ 105.590332] wcd9xxx_find_plug_type: DCE #2, fc06, V 0008(0008), GND 1, VDDIO 0, HPHL 1 TYPE 2
<7>[ 105.590346] wcd9xxx_find_plug_type: DCE #3, fc06, V 0008(0008), GND 0, VDDIO 0, HPHL 1 TYPE 2
<7>[ 105.590359] wcd9xxx_find_plug_type: Plug type 2 detected
<7>[ 105.590368] wcd9xxx_codec_get_plug_type: leave
<7>[ 105.590655] wcd9xxx_report_plug: enter insertion 1 hph_status 0
<7>[ 105.590666] wcd9xxx_report_plug: Reporting insertion 1(1)
继续进行检测wcd9xxx_correct_swch_plug,用以确认检测正确,如果检测到是PLUG_TYPE_HEADPHONE则需要在 HS_DETECT_PLUG_TIME_MS=5000毫秒内多次检测
<7>[ 105.717321] wcd9xxx_correct_swch_plug: Acquiring BCL
<7>[ 105.717335] wcd9xxx_correct_swch_plug: Acquiring BCL done
<7>[ 105.717344] wcd9xxx_codec_get_plug_type: enter
<7>[ 105.720967] wcd9xxx_mbhc_setup_hs_polling: enter
<7>[ 105.804823] wcd9xxx_find_plug_type: DCE #0, fc08, V 0010(0010), GND 0, VDDIO 0, HPHL 1 TYPE 2
<7>[ 105.804841] wcd9xxx_find_plug_type: DCE #1, fc08, V 0010(0010), GND 0, VDDIO 0, HPHL 1 TYPE 2
<7>[ 105.804856] wcd9xxx_find_plug_type: DCE #2, fc08, V 0010(0010), GND 1, VDDIO 0, HPHL 1 TYPE 2
元器件数据手册、IC替代型号,打造电子元器件IC百科大全!