Linux Regulator Framework(2) - regulator driver
- 编写regulator control driver
1.regulator driver实现步骤
1.1. regulators 硬件组成
以NVIDIA Tegra Dalmore A04开发板为例(arch\arm\boot\dts\tegra114 dalmore.dts):
CPU通过I2C controller,连接一个降压控制器tps51632,该控制器输出名称为“vdd-cpu”的电压,虚拟一个vdd-cpu regulator。
CPU通过I2C controller,连接一个前端电源管理芯片(tps65090),该芯片除了具备充电管理功能外,内置了多个regulator,例如dcdc1、dcdc2等等。
CPU通过I2C controller,连接另一个电源管理芯片(tps65913),该芯片具有两个功能:GPIO输出和PMIC。PMIC内置了多个regulator,如vddio-ddr、vdd-core等等。
CPU内部也集成了一些regulator,如vdd_ac_bat等等。
2.驱动编写
1).如果使用静态注册的方法,则需要自定义结构体struct regulator_desc 和struct regulator_config,然后调用devm_regulator_register注册。
drivers/regulator/da903x.c:309 #define DA903x_LDO(_pmic, _id, min, max, step, vreg, shift, nbits, ereg, ebit) \310 { \311 .desc = { \312 .name = "LDO" #_id, \313 .ops = &da903x_regulator_ldo_ops, \314 .type = REGULATOR_VOLTAGE, \315 .id = _pmic##_ID_LDO##_id, \316 .n_voltages = (step) ? ((max - min) / step + 1) : 1, \317 .owner = THIS_MODULE, \318 .min_uV = (min) * 1000, \319 .uV_step = (step) * 1000, \320 }, \ 321 .max_uV = (max) * 1000, \322 .vol_reg = _pmic##_##vreg, \323 .vol_shift = (shift), \324 .vol_nbits = (nbits), \325 .enable_reg = _pmic##_##ereg, \326 .enable_bit = (ebit), \327 }354 #define DA9030_LDO(_id, min, max, step, vreg, shift, nbits, ereg, ebit) \355 DA903x_LDO(DA9030, _id, min, max, step, vreg, shift, nbits, ereg, ebit) //封装 regulator_desc 369 static struct da903x_regulator_info da903x_regulator_info[] = {370 /* DA9030 */371 DA9030_DVC(BUCK2, 850, 1625, 25, BUCK2DVM1, 5, BUCK2DVM1, 7, RCTL11, 0),372 373 DA9030_LDO( 1, 1200, 3200, 100, LDO1, 0, 5, RCTL12, 1),374 DA9030_LDO( 2, 1800, 3200, 100, LDO23, 0, 4, RCTL12, 2),375 DA9030_LDO( 3, 1800, 3200, 100, LDO23, 4, 4, RCTL12, 3),376 DA9030_LDO( 4, 1800, 3200, 100, LDO45, 0, 4, RCTL12, 4),377 ...378 }//封装 regulator_config456 config.dev = &pdev->dev;457 config.init_data = dev_get_platdata(&pdev->dev);458 config.driver_data = ri;
2).使用DTS定义的方式(推荐)
arch/arm/boot/dts/exynos4210-trats.dts:
277 max8997_pmic@66 {
278 compatible = "maxim,max8997-pmic";
279 interrupts-extended = <&gpx0 7 0>, <&gpx2 3 0>;
280
281 reg = <0x66>;
282 interrupt-parent = <&gpx0>;
283 interrupts = <7 IRQ_TYPE_NONE>;
284
285 regulators {
312 valive_reg: LDO2 {
313 regulator-name = "VALIVE_1.1V_C210";
314 regulator-min-microvolt = <1100000>;
315 regulator-max-microvolt = <1100000>;
316 regulator-always-on;
317 };
318
319 vusb_reg: LDO3 {
320 regulator-name = "VUSB_1.1V_C210";
321 regulator-min-microvolt = <1100000>;
322 regulator-max-microvolt = <1100000>;
323 };
首先使用max8997_pmic_dt_parse_pdata,进行dtsi数据,然后调用devm_regulator_register注册。
drivers/regulator/max8997-regulator.c:1026 if (iodev->dev->of_node) {1027 ret = max8997_pmic_dt_parse_pdata(pdev, pdata); 1030 }
3).填充 struct regulator_ops:
267 static const struct regulator_ops da9030_regulator_ldo14_ops = { 268 .set_voltage_sel = da903x_set_voltage_sel,269 .get_voltage_sel = da903x_get_voltage_sel,270 .list_voltage = da9030_list_ldo14_voltage,271 .map_voltage = da9030_map_ldo14_voltage,272 .enable = da903x_enable,273 .disable = da903x_disable,274 .is_enabled = da903x_is_enabled,275 };
2.遇到问题
在操作同一个regulator,设置不同的电压时,出现"Restricteing voltage" 错误,具体代码位置:
drivers/regulator/core.c:
regulator_set_voltage->regulator_check_consumers
分析:
当调用regulator_get获取regulator,会将该regulator添加到链表regulator->list,然后调用regulator_set_voltage设置电压为3.3v;当再次设置电压为1.8v时,由于regulator_set_voltage会调用regulator_check_consumers检查电压范围,即:
list_for_each_entry(regulator, &rdev->consumer_list, list) 轮训链表上的所有电压,最终出现"Restricteing voltage" 。
解决思路:
设置完电压之后,需要regulator_put,释放该regulator。
Linux Regulator Framework(2) - regulator driver相关推荐
- linux怎么看tty连接哪个端口,Linux TTY framework(4)_TTY driver
Linux TTY framework(4)_TTY driver 作者:wowo 发布于:2016-10-25 22:40 分类:TTY子系统 1. 前言 本文将从驱动工程师的角度去看TTY fra ...
- linux cpufreq framework(3)_cpufreq core
1. 前言 前文(Linux cpufreq framework(2)_cpufreq driver)从平台驱动工程师的角度,简单的介绍了编写一个cpufreq driver的大概步骤.但要更深入理解 ...
- linux MMC framework(4) - mmc host driver
了解mmc host driver. 1.host相关数据结构 1.1.struct mmc_host struct mmc_host是mmc core由host controller抽象出来的结 ...
- Linux cpuidle framework(3)_ARM64 generic CPU idle driver
1. 前言 本文以ARM64平台下的cpuidle driver为例,说明怎样在cpuidle framework的框架下,编写cpuidle driver.另外,本文在描述cpuidle drive ...
- Linux cpuidle framework(1)_概述和软件架构 -- wowo
文章目录 1. 前言 2. 功能概述 3. 软件架构 1)kernel schedule模块 2)cpuidle core 3)cpuidle drivers 4)cpuidle governors ...
- linux cpu do idle,Linux cpuidle framework(1)_概述和软件架构
1. 前言 在计算机系统中,CPU的功能是执行程序,总结起来就是我们在教科书上学到的:取指.译码.执行.那么问题来了,如果没有程序要执行,CPU要怎么办?也许您会说,停掉就是了啊.确实,是要停掉,但何 ...
- Linux cpuidle framework(4)_menu governor
Linux cpuidle framework(4)_menu governor menu governor的主要任务就转化为两个:1. 根据系统的运行情况,预测CPU将在C state中停留的时间( ...
- 浅谈Linux media framework
基本概念 通过调试camera过程中对接触的v4l2,意外发现了Linux一个不是很起眼的子系统--Linux media framework,那它存在的意义是什么? 节选一段来自Linux源码中的文 ...
- linux cpufreq framework(4)_cpufreq governor
1. 前言 由"linux cpufreq framework(3)_cpufreq core"的描述可知,cpufreq policy负责设定cpu调频的一个大致范围,而cpu的 ...
- 【Linux SPI Framework】
Linux SPI Framework 1.1 SPI 总线简介 1.2 LINUX驱动分层 1.3 LINUX设备模型 1.4 LINUX SPI 核心层: 1.4.1 SPI Host Maste ...
最新文章
- Linux安装HDF5及遇到的问题总结
- Android中Fragment+ViewPager的配合使用
- maven配置阿里云镜像后Eclipse不生效解决办法
- Spark 精品文章转载(目录)
- HTTP-FLV的两种方式
- JS组件系列——Bootstrap Table 表格行拖拽(二:多行拖拽)
- OpenLayers相关资料
- Confluence5.8部分空间名称显示为问号的解决方案
- java成神之——Fork/Join基本使用
- 10岁女程序员,婉拒谷歌Offer,研发全球首款AI桌游,现在是一名CEO
- java 项目开发流程_详解JAVA开发之JAVA项目开发的基本流程
- bs 网站获取电子秤重量方案
- 更改我的网页默认的暴风影音播放器
- keil symbol外部符号定义
- 影片剪辑app android,猫饼剪辑app
- View事件分发机制分析
- jvm配置垃圾收集参数
- 2022年Android官方模拟器安装Xposed教程+测试工具PatDroid安装教程
- 关于ucore实验一的资料查找
- 小型餐饮管理系统(c++/win32 SDK/MYSQL 数据库)