RK806是瑞芯微(Rockchip)推出的一款高性能電源管理IC(PMIC),廣泛應(yīng)用于基于瑞芯微芯片的嵌入式設(shè)備中。其Linux驅(qū)動基于MFD(Multi-Function Device)框架開發(fā),集成了電源鍵、電壓調(diào)節(jié)、中斷處理等核心功能。本文將從驅(qū)動架構(gòu)、核心代碼、關(guān)鍵功能到實際擴展,全面解析RK806驅(qū)動的實現(xiàn)邏輯。
一、RK806驅(qū)動整體架構(gòu)
RK806驅(qū)動采用Linux MFD框架設(shè)計,將PMIC的多個功能(如引腳控制、電源鍵、電壓調(diào)節(jié)器)拆分為獨立的子設(shè)備,核心特點如下:
?基于regmap管理寄存器讀寫,簡化底層硬件操作;
?通過reg_field抽象寄存器位段,降低位操作復(fù)雜度;
?基于中斷芯片(regmap_irq_chip)處理各類硬件中斷;
?支持設(shè)備樹(DT)配置,實現(xiàn)驅(qū)動參數(shù)的靈活定制;
?提供sysfs調(diào)試接口,方便寄存器讀寫調(diào)試。
驅(qū)動核心文件為rk806-core.c,整體流程可概括為:寄存器字段定義→設(shè)備初始化→子設(shè)備注冊→中斷初始化→功能配置。
二、核心代碼模塊解析
1.寄存器字段抽象:reg_field數(shù)組
RK806的寄存器操作是驅(qū)動的基礎(chǔ),代碼中通過rk806_reg_fields數(shù)組定義了所有關(guān)鍵寄存器的位段映射,涵蓋:
?電源使能(BUCK/LDO的EN位):如BUCK1_EN、NLDO1_EN等;
?電壓配置(ON/SLP模式電壓):如BUCK1_ON_VSEL、PLDO3_SLP_VSEL等;
?中斷狀態(tài)/配置:如INT_POL、VB_LO_STS等;
?系統(tǒng)配置:如PWRON_ON_TIME(電源鍵開機延時)、DEV_OFF(設(shè)備關(guān)機)等。
示例代碼(電源使能位段):
[] = REG_FIELD(0X00,0,0), // 0x00寄存器的0位為BUCK1使能[] = REG_FIELD(0x03,0,0), // 0x03寄存器的0位為NLDO1使能[] = REG_FIELD(0x72,0,0), // 0x72寄存器的0位為設(shè)備關(guān)機控制
通過regmap_field_read/write接口,可直接操作這些位段,無需手動計算寄存器偏移和掩碼,大幅簡化代碼。
2. MFD子設(shè)備注冊
RK806驅(qū)動通過mfd_cell數(shù)組注冊子設(shè)備,對應(yīng)PMIC的不同功能模塊:
staticconststructmfd_cell rk806_cells[] = {{ .name ="rk806-pinctrl", }, // 引腳控制子設(shè)備{.name ="rk805-pwrkey", // 電源鍵子設(shè)備.num_resources = ARRAY_SIZE(rk806_pwrkey_resources),.resources = &rk806_pwrkey_resources[0],},{ .name ="rk806-regulator", }, // 電壓調(diào)節(jié)器子設(shè)備};
子設(shè)備通過devm_mfd_add_devices接口注冊,由MFD框架管理,實現(xiàn)功能解耦。
3.中斷處理機制
RK806的中斷包括電源鍵、低電壓(VB_LO)、VDC電壓變化等,驅(qū)動通過regmap_irq_chip實現(xiàn)中斷管理:
(1)中斷定義
staticconststructregmap_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)中斷為例,驅(qū)動實現(xiàn)了低電壓閾值配置和中斷注冊:
staticintrk806_low_power_irqs(structrk806 *rk806){// 配置低電壓觸發(fā)方式為中斷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);// 注冊中斷處理函數(shù)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.設(shè)備初始化流程
rk806_device_init是驅(qū)動的核心初始化函數(shù),流程如下:
1.分配寄存器字段映射(devm_regmap_field_alloc);
2.讀取芯片ID/版本信息(CHIP_NAME_H/L、CHIP_VER);
3.解析設(shè)備樹參數(shù)(rk806_parse_dt):如低電壓閾值、關(guān)機電壓閾值、VDC喚醒使能等;
4.中斷初始化(rk806_irq_init):配置中斷極性(如INT_POL為低電平有效);
5.注冊中斷芯片和MFD子設(shè)備;
6.引腳控制初始化(rk806_pinctrl_init);
7.低電壓/VDC中斷初始化(rk806_low_power_irqs/rk806_vdc_irqs_init);
8.創(chuàng)建sysfs調(diào)試節(jié)點。
5.調(diào)試接口:sysfs節(jié)點
驅(qū)動提供了debugsysfs節(jié)點(對應(yīng)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;
該接口可快速調(diào)試寄存器配置,無需修改驅(qū)動代碼,是開發(fā)/調(diào)試階段的重要工具。
三、關(guān)鍵功能擴展:電源鍵3秒檢測邏輯
在嵌入式設(shè)備中,常需實現(xiàn)“電源鍵長按3秒開機/短按關(guān)機”的邏輯,代碼中注釋的rk806_check_pwrkey_3s函數(shù)正是該需求的實現(xiàn),核心思路:
1.循環(huán)檢測PWRON_STS(電源鍵狀態(tài)),每100ms檢測一次,累計3秒;
2.若中途檢測到按鍵松開,觸發(fā)硬件關(guān)機(寫入DEV_OFF字段);
3.若3秒內(nèi)按鍵持續(xù)按下,配置開機參數(shù)并喚醒系統(tǒng)。
核心代碼實現(xiàn):
staticintrk806_check_pwrkey_3s(structrk806 *rk806){intcheck_count =0;intmax_check =30;// 30×100ms=3000msintpwr_on_sts;while(check_count < max_check) {// 讀取電源鍵狀態(tài)pwr_on_sts = rk806_field_read(rk806, PWRON_STS);if(pwr_on_sts 0)returnpwr_on_sts;// 按鍵松開,觸發(fā)關(guān)機if(pwr_on_sts ==1) {dev_info(rk806->dev,"PWRON released, trigger shutdown...n");returnrk806_field_write(rk806, DEV_OFF,0x01);}msleep(100);check_count++;}// 3秒長按,觸發(fā)開機dev_info(rk806->dev,"PWRON pressed 3s, trigger boot...n");rk806_field_write(rk806, PWRON_ON_TIME,0x00);// 配置開機延時500mspm_wakeup_dev_event(rk806->dev,5000,true);// 喚醒系統(tǒng)return0;}
該邏輯可直接集成到rk806_device_init中,實現(xiàn)電源鍵的定制化操作。
四、實際應(yīng)用與調(diào)試技巧
1.設(shè)備樹配置示例
RK806的參數(shù)可通過設(shè)備樹靈活配置,無需修改驅(qū)動代碼:
rk806: pmic@0{compatible ="rockchip,rk806";low_voltage_threshold = <3000>;//低電壓閾值3000mVshutdown_voltage_threshold = <2700>;//關(guān)機電壓閾值2700mVvdc-wakeup-enable;//使能VDC電壓變化喚醒pwron-on-time-500ms;//電源鍵開機延時500ms};
驅(qū)動通過device_property_read_u32解析這些參數(shù),適配不同硬件需求。

2.調(diào)試技巧
?讀取芯片版本:通過CHIP_NAME_H/L和CHIP_VER字段,確認(rèn)芯片型號和版本;
?調(diào)試寄存器:使用sysfs的debug節(jié)點讀寫寄存器,驗證配置是否生效;
?中斷調(diào)試:通過cat /proc/interrupts查看中斷觸發(fā)次數(shù),確認(rèn)中斷是否正常;
?電源鍵狀態(tài):讀取PWRON_STS字段,確認(rèn)按鍵狀態(tài)是否正確識別。
五、總結(jié)
RK806驅(qū)動是典型的MFD框架應(yīng)用,其設(shè)計思路對PMIC驅(qū)動開發(fā)具有重要參考意義:
1.采用regmap和reg_field抽象寄存器操作,降低硬件耦合;
2.基于MFD框架拆分功能模塊,提高代碼可維護性;
3.充分利用設(shè)備樹,實現(xiàn)驅(qū)動參數(shù)的靈活配置;
4.提供完善的調(diào)試接口,降低開發(fā)/調(diào)試成本。
5.這個邏輯移植到uboot下效果會更好
無論是基礎(chǔ)的電壓配置、中斷處理,還是定制化的電源鍵邏輯,RK806驅(qū)動都提供了清晰的實現(xiàn)思路。掌握該驅(qū)動的核心邏輯,可快速適配瑞芯微平臺的PMIC定制需求,也為其他品牌PMIC驅(qū)動開發(fā)提供參考。
審核編輯 黃宇
-
寄存器
+關(guān)注
關(guān)注
31文章
5608瀏覽量
130003 -
PMIC
+關(guān)注
關(guān)注
15文章
481瀏覽量
113076
發(fā)布評論請先 登錄
開關(guān)電源pcb設(shè)計實例 分析RK806電源方案的PCB設(shè)計
一文解析Matlab如何實現(xiàn)移位寄存器
淺析從寄存器到用戶態(tài)與內(nèi)核態(tài)
?PLC從HTTP服務(wù)端獲取JSON文件,解析數(shù)據(jù)到寄存器
RK3588 EVB開發(fā)板原理圖講解【三】
RK3588 EVB開發(fā)板原理圖講解【七】
RK3128 Android 7.1 進(jìn)入深度休眠流程分析
求助: rk3399 android9如何實現(xiàn)短按電源鍵開機?
RK806電源方案的PCB設(shè)計注意事項
解決RK806+RK3588休眠異常!從硬件特性到軟件優(yōu)化的完整方案
深度拆解RK806 PMIC電源處理流程:從SPI通信到DVS動態(tài)調(diào)壓
RK806中斷處理流程深度解析:從架構(gòu)到調(diào)試實戰(zhàn)
深度解析RK806 PMIC驅(qū)動:從寄存器到實際應(yīng)用(實現(xiàn)長按電源鍵開機)
評論