锐单电子商城 , 一站式电子元器件采购平台!
  • 电话:400-990-0325

高通开发笔记---Yangtze worknote

时间:2023-02-02 23:00:01 105e电阻

点击打开链接

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百科大全!

相关文章