瑞芯微Rockchip开发者社区
直播中

孙成红

7年用户 1412经验值
私信 关注
[问答]

如何对Android 7.1 RK3288 PMU进行调试呢

如何对Android 7.1 RK3288 PMU进行调试呢?

回帖(1)

唐般远

2022-3-4 11:47:58
【平台信息】

平台:Rockchip
CPU:RK3288
PMU:RK808-B
开机流程:
1)当有接适配器时:VDC 电压升高; VSYS 上电; PMIC 上电并输出。
2)当只接电池时,按开机键:PWRON 拉高; PMIC 上电并输出。PMIC 启动,实现 EPROM 中的默认设置,各路上电完成后,发送 reset 信号,芯片上电,系统启动,PMIC 设备挂载,通过I2C 重新配置 PMIC。

【流程梳理】

1、设备树配置
kernel/arch/arm/boot/dts/rk808.dtsi

&rk808 {
        compatible = "rockchip,rk808";

        regulators {
                #address-cells = <1>;
                #size-cells = <0>;

                rk808_dcdc1_reg: regulator@0 {
                        reg = <0>;
                        regulator-compatible = "rk_dcdc1";
                        regulator-min-microvolt = <700000>;
                        regulator-max-microvolt = <1500000>;
                        regulator-initial-mode = <0x2>;
                        regulator-initial-state = <3>;
                        regulator-state-mem {
                                regulator-state-mode = <0x2>;
                                regulator-state-disabled;//disabled
                                regulator-state-uv = <900000>;
                        };
                };
                ...
                rk808_ldo1_reg: regulator@4 {
                        reg = <4>;
                        regulator-compatible = "rk_ldo1";
                        regulator-initial-state = <3>;
                        regulator-state-mem {
                                regulator-state-enabled;
                                regulator-state-uv = <3300000>;
                        };
                };
                                ...               

kernel/arch/arm/boot/dts/rk3288-n1904.dts

&i2c0 {
        status = "okay";
        rk808: rk808@1b {
                reg = <0x1b>;
                status = "okay";
        };
        ...
}
&rk808 {
        gpios =<&gpio0 GPIO_A4 GPIO_ACTIVE_HIGH>,<&gpio0 GPIO_A0 GPIO_ACTIVE_HIGH>;
        rk808,system-power-controller;

        regulators {
                rk808_dcdc1_reg: regulator@0{
                        regulator-name= "vdd_arm";
                        regulator-min-microvolt = <700000>;
                        regulator-max-microvolt = <1500000>;
                        regulator-always-on;
                        regulator-boot-on;
                };
                ...
                rk808_ldo1_reg: regulator@4 {
                        regulator-name= "rk_ldo1";
                        regulator-min-microvolt = <1800000>;
                        regulator-max-microvolt = <1800000>;
                        regulator-always-on;
                        regulator-boot-on;
                };
                ...
        };
};
参考文档:
Documentation/devicetree/bindings/mfd/rk808.txt
Documentation/devicetree/bindings/regulator/regulator.txt

2、驱动代码
kernel/drivers/mfd/rk808.c

static struct rk808_board *rk808_parse_dt(struct rk808 *rk808)
{
        struct rk808_board *pdata;
        struct device_node *regs,*rk808_pmic_np;
        int i, count;

        rk808_pmic_np = of_node_get(rk808->dev->of_node);
        if (!rk808_pmic_np) {
                printk("could not find pmic sub-noden");
                return NULL;
        }

        regs = of_find_node_by_name(rk808_pmic_np, "regulators");
        if (!regs)
                return NULL;

        count = of_regulator_match(rk808->dev, regs, rk808_reg_matches,
                                   rk808_NUM_REGULATORS); // 匹配并查找设备树中regulator个数
        of_node_put(regs);
        if ((count < 0) || (count > rk808_NUM_REGULATORS))
                return NULL;

        pdata = devm_kzalloc(rk808->dev, sizeof(*pdata), GFP_KERNEL);
        if (!pdata)
                return NULL;

        for (i = 0; i < count; i++) {
                if (!rk808_reg_matches.init_data || !rk808_reg_matches.of_node)
                        continue;

                pdata->rk808_init_data = rk808_reg_matches.init_data;
                pdata->of_node = rk808_reg_matches.of_node;
        }
        pdata->irq = rk808->chip_irq;
        pdata->irq_base = -1;
      
        pdata->irq_gpio = of_get_named_gpio(rk808_pmic_np,"gpios",0);
                if (!gpio_is_valid(pdata->irq_gpio)) {
                        printk("invalid gpio: %dn",  pdata->irq_gpio);
                        return NULL;
                }

        pdata->pmic_sleep_gpio = of_get_named_gpio(rk808_pmic_np,"gpios",1);
                        if (!gpio_is_valid(pdata->pmic_sleep_gpio)) {
                                printk("invalid gpio: %dn",  pdata->pmic_sleep_gpio);
                }
        pdata->pmic_sleep = true;
      
        pdata->pm_off = of_property_read_bool(rk808_pmic_np,"rk808,system-power-controller");
               
        return pdata;
}
static int rk808_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id)
{
        struct rk808 *rk808;
        ...
        rk808 = devm_kzalloc(&i2c->dev,sizeof(struct rk808), GFP_KERNEL);
        rk808->i2c = i2c;
        rk808->dev = &i2c->dev;
        i2c_set_clientdata(i2c, rk808);
        ...
        ret = rk808_pre_init(rk808); //rk808工作状态初始化,配置一堆寄存器
      
        if (rk808->dev->of_node)
                pdev = rk808_parse_dt(rk808); //设备树解析
        /******************************set sleep vol & dcdc mode******************/
        #ifdef CONFIG_OF
        rk808->pmic_sleep_gpio = pdev->pmic_sleep_gpio;
        if (rk808->pmic_sleep_gpio) {
                        ret = gpio_request(rk808->pmic_sleep_gpio, "rk808_pmic_sleep");
                        if (ret < 0) {
                                dev_err(rk808->dev,"Failed to request gpio %d with ret:""%dn",        rk808->pmic_sleep_gpio, ret);
                                return IRQ_NONE;
                        }
                        gpio_direction_output(rk808->pmic_sleep_gpio,0);
                        ret = gpio_get_value(rk808->pmic_sleep_gpio);
                        gpio_free(rk808->pmic_sleep_gpio);
                        pr_info("%s: rk808_pmic_sleep=%xn", __func__, ret);
        }      
        #endif
        if (pdev) {
                rk808->num_regulators = rk808_NUM_REGULATORS;
                rk808->rdev = kcalloc(rk808_NUM_REGULATORS,sizeof(struct regulator_dev *), GFP_KERNEL);
                if (!rk808->rdev) {
                        return -ENOMEM;
                }
                /* Instantiate the regulators */
                for (i = 0; i < rk808_NUM_REGULATORS; i++) {
                        reg_data = pdev->rk808_init_data;
                        if (!reg_data)
                                continue;
                        config.dev = rk808->dev;
                        config.driver_data = rk808;
                        config.regmap = rk808->regmap;
                        if (rk808->dev->of_node)
                                config.of_node = pdev->of_node;
                        if (reg_data && reg_data->constraints.name)
                                rail_name = reg_data->constraints.name;
                        else
                                rail_name = regulators.name;
                        reg_data->supply_regulator = rail_name;
      
                        config.init_data =reg_data;

                        rk808_rdev = regulator_register(®ulators,&config);
                        if (IS_ERR(rk808_rdev)) {
                                printk("failed to register %d regulatorn",i);
                                goto err;
                        }
                        rk808->rdev = rk808_rdev;
                } // end for
        } // end if
      
        rk808->irq_gpio = pdev->irq_gpio;
        ret = rk808_irq_init(rk808, rk808->irq_gpio, pdev);
        if (ret < 0)
                goto err;

        ret = mfd_add_devices(rk808->dev, -1,
                              rk808s, ARRAY_SIZE(rk808s),
                              NULL, 0,NULL);
        g_rk808 = rk808;
        if (pdev->pm_off && !pm_power_off) {
                pm_power_off = rk808_device_shutdown;
        }

        #ifdef CONFIG_HAS_EARLYSUSPEND
        rk808->rk808_suspend.suspend = rk808_early_suspend,
        rk808->rk808_suspend.resume = rk808_late_resume,
        rk808->rk808_suspend.level = EARLY_SUSPEND_LEVEL_DISABLE_FB + 1,
        register_early_suspend(&rk808->rk808_suspend);
        #endif

        rk808_kobj = kobject_create_and_add("rk808", NULL);
        if (!rk808_kobj)
                return -ENOMEM;
        for (i = 0; i < ARRAY_SIZE(rk808_attrs); i++) {
                ret = sysfs_create_file(rk808_kobj, &rk808_attrs.attr);
                if (ret != 0) {
                        printk("create index %d errorn", i);
                        return ret;
                }
        }

        register_syscore_ops(&rk808_syscore_ops);
        return 0;
}

static const struct i2c_device_id rk808_i2c_id[] = {
       { "rk808", 0 },
       { }
};
MODULE_DEVICE_TABLE(i2c, rk808_i2c_id);
static struct i2c_driver rk808_i2c_driver = {
        .driver = {
                .name = "rk808",
                .owner = THIS_MODULE,
                #ifdef CONFIG_PM
                .pm = &rk808_pm_ops,
                #endif
                .of_match_table =of_match_ptr(rk808_of_match),
        },
        .probe    = rk808_i2c_probe,
        .remove   = rk808_i2c_remove,
        .id_table = rk808_i2c_id,
};
static int __init rk808_module_init(void)
{
        int ret;
        ret = i2c_add_driver(&rk808_i2c_driver);
        if (ret != 0)
                pr_err("Failed to register I2C driver: %dn", ret);
        return ret;
}
subsys_initcall_sync(rk808_module_init);


【调试记录】


1、内核加载rk808驱动日志

rk808_i2c_probe,line=1355
rk808_pre_init,line=1224
of_get_named_gpio_flags exited with status 4
of_get_named_gpio_flags exited with status 0
vdd_arm: 712 <--> 1500 mV at 1312 mV
vdd_gpu: 712 <--> 1500 mV at 900 mV
rk_dcdc3: 1200 mV
vccio: 1800 <--> 3300 mV at 3300 mV
rk_ldo1: 1800 mV
rk_ldo2: 3300 mV
rk_ldo3: 1000 mV
rk_ldo4: 1800 mV
rk_ldo5: 3300 mV
rk_ldo6: 1800 mV
rk_ldo7: 1800 mV
rk_battery_charger_detect_cb , battery_charger_detect 1
rk_ldo8: 1800 mV
rk_ldo9: at 3300 mV
rk_ldo10: at 3300 mV
rk808_irq_init: rk808_pmic_irq=1
rk808_rtc_probe,line=540
rk808-rtc rk808-rtc: rtc core: registered rk808 as rtc0
rk808_rtc_probe:ok


举报

更多回帖

发帖
×
20
完善资料,
赚取积分