深度解析RK806 PMIC驱动:从寄存器到实际应用(实现长按电源键开机)

电子说

1.4w人已加入

描述

 

 

 

 

RK806是瑞芯微(Rockchip)推出的一款高性能电源管理ICPMIC),广泛应用于基于瑞芯微芯片的嵌入式设备中。其Linux驱动基于MFDMulti-Function Device)框架开发,集成了电源键、电压调节、中断处理等核心功能。本文将从驱动架构、核心代码、关键功能到实际扩展,全面解析RK806驱动的实现逻辑。

 

 

一、RK806驱动整体架构

 

 

RK806驱动采用Linux MFD框架设计,将PMIC的多个功能(如引脚控制、电源键、电压调节器)拆分为独立的子设备,核心特点如下:

 

 

基于regmap管理寄存器读写,简化底层硬件操作;

 

 

通过reg_field抽象寄存器位段,降低位操作复杂度;

 

 

基于中断芯片(regmap_irq_chip)处理各类硬件中断;

 

 

支持设备树(DT)配置,实现驱动参数的灵活定制;

 

 

提供sysfs调试接口,方便寄存器读写调试。

 

 

驱动核心文件为rk806-core.c,整体流程可概括为:寄存器字段定义→ 设备初始化 → 子设备注册 → 中断初始化 → 功能配置

 

 

二、核心代码模块解析

 

 

1. 寄存器字段抽象:reg_field数组

 

 

RK806的寄存器操作是驱动的基础,代码中通过rk806_reg_fields数组定义了所有关键寄存器的位段映射,涵盖:

 

 

电源使能(BUCK/LDOEN位):如BUCK1_ENNLDO1_EN等;

 

 

电压配置(ON/SLP模式电压):如BUCK1_ON_VSELPLDO3_SLP_VSEL等;

 

 

中断状态/配置:如INT_POLVB_LO_STS等;

 

 

系统配置:如PWRON_ON_TIME(电源键开机延时)、DEV_OFF(设备关机)等。

 

 

示例代码(电源使能位段):

 

 

  •  
  •  
  •  
[BUCK1_EN] = REG_FIELD(0X0000),    // 0x00寄存器的0位为BUCK1使能[NLDO1_EN] = REG_FIELD(0x0300),    // 0x03寄存器的0位为NLDO1使能[DEV_OFF] = REG_FIELD(0x7200),     // 0x72寄存器的0位为设备关机控制

通过regmap_field_read/write接口,可直接操作这些位段,无需手动计算寄存器偏移和掩码,大幅简化代码。

 

 

2. MFD子设备注册

 

 

RK806驱动通过mfd_cell数组注册子设备,对应PMIC的不同功能模块:

 

 

  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
static const struct mfd_cell rk806_cells[] = {    { .name = "rk806-pinctrl", },        // 引脚控制子设备    {        .name = "rk805-pwrkey",         // 电源键子设备        .num_resources = ARRAY_SIZE(rk806_pwrkey_resources),        .resources = &rk806_pwrkey_resources[0],    },    { .name = "rk806-regulator", },     // 电压调节器子设备};

子设备通过devm_mfd_add_devices接口注册,由MFD框架管理,实现功能解耦。

 

 

3. 中断处理机制

 

 

RK806的中断包括电源键、低电压(VB_LO)、VDC电压变化等,驱动通过regmap_irq_chip实现中断管理:

 

 

1)中断定义

 

 

  •  
  •  
  •  
  •  
  •  
static const struct regmap_irq rk806_irqs[] = {    REGMAP_IRQ_REG(RK806_IRQ_PWRON_FALL, 0, RK806_INT_STS_PWRON_FALL),    REGMAP_IRQ_REG(RK806_IRQ_VB_LO, 0, RK806_INT_STS_VB_LO),    REGMAP_IRQ_REG(RK806_IRQ_VDC_RISE, 0, RK806_INT_STS_VDC_RISE),};

2)中断初始化

 

 

  •  
  •  
  •  
  •  
  •  
  •  
  •  
ret = devm_regmap_add_irq_chip(rk806->dev,                               rk806->regmap,                               rk806->irq,                               IRQF_ONESHOT | IRQF_SHARED,                               0,                               &rk806_irq_chip,                               &rk806->irq_data);

3)典型中断处理

 

 

以低电压(VB_LO)中断为例,驱动实现了低电压阈值配置和中断注册:

 

 

  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
static int rk806_low_power_irqs(struct rk806 *rk806) {    // 配置低电压触发方式为中断    rk806_field_write(rk806, VB_LO_ACT, VB_LO_ACT_INT);    // 配置低电压阈值(2800~3500mV)    rk806_field_write(rk806, VB_LO_SEL, (pdata->low_voltage_threshold - 2800) / 100);    // 注册中断处理函数    ret = devm_request_threaded_irq(rk806->dev, vb_lo_irq,                                    NULL, rk806_vb_low_irq,                                    IRQF_TRIGGER_HIGH | IRQF_ONESHOT,                                    "rk806_vb_low", rk806);}

4. 设备初始化流程

 

 

rk806_device_init是驱动的核心初始化函数,流程如下:

 

 

1.分配寄存器字段映射(devm_regmap_field_alloc);

 

 

2.读取芯片ID/版本信息(CHIP_NAME_H/LCHIP_VER);

 

 

3.解析设备树参数(rk806_parse_dt):如低电压阈值、关机电压阈值、VDC唤醒使能等;

 

 

4.中断初始化(rk806_irq_init):配置中断极性(如INT_POL为低电平有效);

 

 

5.注册中断芯片和MFD子设备;

 

 

6.引脚控制初始化(rk806_pinctrl_init);

 

 

7.低电压/VDC中断初始化(rk806_low_power_irqs/rk806_vdc_irqs_init);

 

 

8.创建sysfs调试节点。

 

 

5. 调试接口:sysfs节点

 

 

驱动提供了debug sysfs节点(对应rk806_master_attrs/rk806_slaver_attrs),支持读写寄存器:

 

 

写操作:echo w [addr] [value] > debug(写入寄存器);

 

 

读操作:echo r [addr] > debug(读取寄存器)。

 

 

示例代码(写寄存器逻辑):

 

 

  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
case 'w':    ret = sscanf(buf, "%c %x %x", &cmd, &input[0], &input[1]);    addr = input[0] & 0xff;    data = input[1] & 0xff;    regmap_write(rk806->regmap, addr, data);    regmap_read(rk806->regmap, addr, &data); // 回读验证    pr_info("new: %x %xn", addr, data);    break;

该接口可快速调试寄存器配置,无需修改驱动代码,是开发/调试阶段的重要工具。

 

 

三、关键功能扩展:电源键3秒检测逻辑

 

 

在嵌入式设备中,常需实现电源键长按3秒开机/短按关机的逻辑,代码中注释的rk806_check_pwrkey_3s函数正是该需求的实现,核心思路:

 

 

1.循环检测PWRON_STS(电源键状态),每100ms检测一次,累计3秒;

 

 

2.若中途检测到按键松开,触发硬件关机(写入DEV_OFF字段);

 

 

3.3秒内按键持续按下,配置开机参数并唤醒系统。

 

 

核心代码实现:

 

 

  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
static int rk806_check_pwrkey_3s(struct rk806 *rk806) {    int check_count = 0;    int max_check = 30// 30×100ms=3000ms    int pwr_on_sts;    while (check_count < max_check) {        // 读取电源键状态        pwr_on_sts = rk806_field_read(rk806, PWRON_STS);        if (pwr_on_sts < 0return pwr_on_sts;        // 按键松开,触发关机        if (pwr_on_sts == 1) {            dev_info(rk806->dev, "PWRON released, trigger shutdown...n");            return rk806_field_write(rk806, DEV_OFF, 0x01);        }        msleep(100);        check_count++;    }    // 3秒长按,触发开机    dev_info(rk806->dev, "PWRON pressed 3s, trigger boot...n");    rk806_field_write(rk806, PWRON_ON_TIME, 0x00); // 配置开机延时500ms    pm_wakeup_dev_event(rk806->dev, 5000true); // 唤醒系统    return 0;}

该逻辑可直接集成到rk806_device_init中,实现电源键的定制化操作。

 

 

四、实际应用与调试技巧

 

 

1. 设备树配置示例

 

 

RK806的参数可通过设备树灵活配置,无需修改驱动代码:

 

 

  •  
  •  
  •  
  •  
  •  
  •  
  •  
rk806: pmic@0 {    compatible = "rockchip,rk806";    low_voltage_threshold = <3000>; // 低电压阈值3000mV    shutdown_voltage_threshold = <2700>; // 关机电压阈值2700mV    vdc-wakeup-enable; // 使能VDC电压变化唤醒    pwron-on-time-500ms; // 电源键开机延时500ms};

驱动通过device_property_read_u32解析这些参数,适配不同硬件需求。

寄存器

2. 调试技巧

 

 

读取芯片版本:通过CHIP_NAME_H/LCHIP_VER字段,确认芯片型号和版本;

 

 

调试寄存器:使用sysfsdebug节点读写寄存器,验证配置是否生效;

 

 

中断调试:通过cat /proc/interrupts查看中断触发次数,确认中断是否正常;

 

 

电源键状态:读取PWRON_STS字段,确认按键状态是否正确识别。

 

 

五、总结

 

 

RK806驱动是典型的MFD框架应用,其设计思路对PMIC驱动开发具有重要参考意义:

 

 

1.采用regmapreg_field抽象寄存器操作,降低硬件耦合;

 

 

2.基于MFD框架拆分功能模块,提高代码可维护性;

 

 

3.充分利用设备树,实现驱动参数的灵活配置;

 

 

4.提供完善的调试接口,降低开发/调试成本。

5.这个逻辑移植到uboot下效果会更好

无论是基础的电压配置、中断处理,还是定制化的电源键逻辑,RK806驱动都提供了清晰的实现思路。掌握该驱动的核心逻辑,可快速适配瑞芯微平台的PMIC定制需求,也为其他品牌PMIC驱动开发提供参考。


审核编辑 黄宇

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分