| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> C++知识库 -> MTK平台前后摄使用PMIC供电无法设置不同的DVDD电压 -> 正文阅读 |
|
[C++知识库]MTK平台前后摄使用PMIC供电无法设置不同的DVDD电压 |
xx项目前后摄DVDD共用PMIC供电,一供后摄DVDD电压设置为1.2V,二供后摄DVDD电压设置为1.1V,一二供前摄DVDD电压设置为1.2V,但实际测试过程中发现二供机器前摄的DVDD电压只有1.1V。 分析过程如下: 1.查看开机camera相关上电log,设置电压时无明显报错,怀疑模组硬件本身影响 2.拆掉前摄模组,DVDD依然是1.1V,达不到1.2V 3.因为此项目前后摄共用PMU的VCAMD给DVDD供电,怀疑后摄影响前摄的供电,将后摄模组拆掉,前摄的DVDD上电依然是1.1V 4.将二供后摄DVDD电压改为1.2V上电,此时前摄DVDD电压可以达到1.2V 5.给MTK提case,MTK提供用adb命令控制PMU输出的方法,发现写adb命令可以让DVDD达到1.2V,说明还是软件问题 6.修改软件,将二供后摄放在一供后摄之前上电,此方案可以在一供机器上实现前摄DVDD达到1.2V,但在二供机器上前摄DVDD还是1.1V 7.在上电过程中打开log开关以及增加log,发现二供机器在设置DVDD电压时设置失败了,log如下: [??? 8.890901] (0)[659:camerahalserver][imgsensor][imgsensor_hw_power] sensor_idx 1, power 1 curr_sensor_name fh10_hi846_front_st_mipi_raw, enable list fh10_hi846_front_st_mipi_raw fh10_gc5035_front_lhyx_mipi_raw fh10_hi556_front_st_mipi_raw [??? 8.890917] (0)[659:camerahalserver]vcamd: Restricting voltage, 1200000-1100000uV [??? 8.890926] (0)[659:camerahalserver][imgsensor][regulator_set] [regulator]fail to regulator_set_voltage, powertype:4 powerId:1200000 追踪代码发现问题出在kernel-4.19/drivers/regulator/core.c中的regulator_check_consumer函数中,进一步在此函数中添加log,log打印如下: <6>[??? 8.511500]? (1)[682:camerahalserver][imgsensor][imgsensor_hw_power] sensor_idx 1, power 1 curr_sensor_name fh10_hi846_front_st_mipi_raw, enable list fh10_hi846_front_st_mipi_raw fh10_gc5035_front_lhyx_mipi_raw fh10_hi556_front_st_mipi_raw <4>[??? 8.511509]? (1)[682:camerahalserver]3056, zm: voltage->min_uV = 0, min_uv = 1200000, voltage->max_uV = 0, max_uV = 1200000 <4>[??? 8.511513]? (1)[682:camerahalserver]3081, zm: call regulator_check_voltage <4>[??? 8.511518]? (1)[682:camerahalserver]3086, zm: compare min_uV:1200000, max_uV:1200000 <4>[??? 8.511523]? (1)[682:camerahalserver]3092, zm: compare voltage->min_uV:1200000, voltage->max_uV:1200000 <4>[??? 8.511528]? (1)[682:camerahalserver]3093, zm: call regulator_check_consumers <4>[? ? 8.511533]? (1)[682:camerahalserver]332, zm: min_uV:1200000, max_uV:1200000 <4>[??? 8.511560]? (1)[682:camerahalserver]342, zm: voltage->min_uV:1200000, voltage->max_uV:1200000 <4>[??? 8.511590] ?(1)[682:camerahalserver]342, zm: voltage->min_uV:1100000, voltage->max_uV:1100000 <4>[??? 8.511597]? (1)[682:camerahalserver]349, zm: max_uV:1100000 <4>[??? 8.511602]? (1)[682:camerahalserver]357, zm: compare min_uV:1200000, max_uV:1100000 <3>[??? 8.511614]? (1)[682:camerahalserver]vcamd: Restricting voltage, 1200000-1100000uV <3>[??? 8.511627]? (1)[682:camerahalserver][imgsensor][regulator_set] 273, [regulator]fail to regulator_set_voltage, powertype:4 powerId:1200000 添加log后的regulator_check_consumers函数如下: static int regulator_check_consumers(struct regulator_dev *rdev, ????????????????????? int *min_uV, int *max_uV, ????????????????????? suspend_state_t state) { ???? struct regulator *regulator; ???? struct regulator_voltage *voltage; ???? printk("%d, zm: min_uV:%d, max_uV:%d", __LINE__, *min_uV, *max_uV); ???? list_for_each_entry(regulator, &rdev->consumer_list, list) { ???????? voltage = ®ulator->voltage[state]; ???????? /* ????????? * Assume consumers that didn't say anything are OK ?????? ???* with anything in the constraint range. ????????? */ ???????? printk("%d, zm: voltage->min_uV:%d, voltage->max_uV:%d", __LINE__, voltage->min_uV, voltage->max_uV); ???????? if (!voltage->min_uV && !voltage->max_uV) ???????????? continue; ???????? if (*max_uV > voltage->max_uV) ???????? { ???????????? *max_uV = voltage->max_uV; ???????????? printk("%d, zm: max_uV:%d", __LINE__, *max_uV); ???????? } ???????? if (*min_uV < voltage->min_uV) ???????? { ???????????? *min_uV = voltage->min_uV; ???????????? printk("%d, zm: min_uV:%d", __LINE__, *min_uV); ???????? } ???? } ???? printk("%d, zm: compare min_uV:%d, max_uV:%d", __LINE__, *min_uV, *max_uV); ???? if (*min_uV > *max_uV) { ???????? rdev_err(rdev, "Restricting voltage, %u-%uuV\n", ???????????? *min_uV, *max_uV); ???????? return -EINVAL; ???? } ??? return 0; } 从以上log中可以看到在设置前摄的DVDD电压时consumer_list中有2个consumer,第一个consumer是1.2V,第二个consumer是1.1V,而要设置的电压值为1.2V,大于consumer_list中较小的那个电压值了,所以导致最终设置的电压值为1.1V。 8.再次给MTK提case,MTK回复是Linux内核regulator的保护机制造成的,Linux ?regulator ?framework允许针对某个LDO取得多个consumer ?regulator ?instance,并且会记录该LDO使用的consumer ?list,安全起见会使用该list中电压设值最小的来供电,因此当不同regulator ?instance设定为不同电压时就会出现Restricting voltage这样的错误log。 解决机制: 在每次对regulator下电时把对应的regulator consumer list也释放掉,即调用regulator_put函数,在每次上电时再重新获取regulator。 提供patch如下: diff --git a/drivers/misc/mediatek/imgsensor/src/mt6765/camera_hw/regulator/regulator.c b/drivers/misc/mediatek/imgsensor/src/mt6765/camera_hw/regulator/regulator.c index 106f917..caa77ba 100644 --- a/drivers/misc/mediatek/imgsensor/src/mt6765/camera_hw/regulator/regulator.c +++ b/drivers/misc/mediatek/imgsensor/src/mt6765/camera_hw/regulator/regulator.c @@ -25,6 +25,15 @@ struct reg_oc_debug_t { ? }; ? static struct reg_oc_debug_t reg_oc_debug[REGULATOR_TYPE_MAX_NUM]; +//+ Bug 577281, zhoumin.wt, add, 2020.01.27, resolve problem: the DVDD voltage of front camera can not set to be 1.2V +static bool regulator_status[IMGSENSOR_SENSOR_IDX_MAX_NUM][REGULATOR_TYPE_MAX_NUM] = {{false}}; +static void check_for_regulator_get(struct REGULATOR *preg, +??? struct device *pdevice, unsigned int sensor_index, unsigned int regulator_index); +static void check_for_regulator_put(struct REGULATOR *preg, +??? unsigned int sensor_index, unsigned int regulator_index); +static struct device_node *of_node_record = NULL; +static DEFINE_MUTEX(g_regulator_state_mutex); +//- Bug 577281, zhoumin.wt, add, 2020.01.27, resolve problem: the DVDD voltage of front camera can not set to be 1.2V ? static const int regulator_voltage[] = { ????? REGULATOR_VOLTAGE_0, @@ -177,7 +186,8 @@ static enum IMGSENSOR_RETURN regulator_init(void *pinstance) ????????? pdevice->of_node = pof_node; ????????? return IMGSENSOR_RETURN_ERROR; ????? } - +??? //Bug 577281, zhoumin.wt, add, 2020.01.27, resolve problem: the DVDD voltage of front camera can not set to be 1.2V +??? of_node_record = pdevice->of_node; ????? for (j = IMGSENSOR_SENSOR_IDX_MIN_NUM; ????????? j < IMGSENSOR_SENSOR_IDX_MAX_NUM; ????????? j++) { @@ -197,6 +207,8 @@ static enum IMGSENSOR_RETURN regulator_init(void *pinstance) ????????????????????? j, i, str_regulator_name); ????????????? atomic_set(&preg->enable_cnt[j][i], 0); +??????????? //Bug 577281, zhoumin.wt, add, 2020.01.27, resolve problem: the DVDD voltage of front camera can not set to be 1.2V +??? ????????regulator_status[j][i] = true; ????????? } ????? } ????? pdevice->of_node = pof_node; @@ -247,7 +259,9 @@ static enum IMGSENSOR_RETURN regulator_set( ????????? return IMGSENSOR_RETURN_ERROR; ????? reg_type_offset = REGULATOR_TYPE_VCAMA; - +??? //Bug 577281, zhoumin.wt, add, 2020.01.27, resolve problem: the DVDD voltage of front camera can not set to be 1.2V +??? check_for_regulator_get(preg, gimgsensor_device, sensor_idx, +??????? (reg_type_offset + pin - IMGSENSOR_HW_PIN_AVDD)); ????? pregulator = ????????? preg->pregulator[sensor_idx][ ????????????? reg_type_offset + pin - IMGSENSOR_HW_PIN_AVDD]; @@ -271,6 +285,7 @@ static enum IMGSENSOR_RETURN regulator_set( ????????????????????? pin, ????????????????????? regulator_voltage[ ???????????????????? pin_state - IMGSENSOR_HW_PIN_STATE_LEVEL_0]); + ????????????? } ????????????? if (regulator_enable(pregulator)) { ????????????????? pr_err( @@ -278,6 +293,9 @@ static enum IMGSENSOR_RETURN regulator_set( ????????????????????? pin, ????????????????????? regulator_voltage[ ???????????????????? pin_state - IMGSENSOR_HW_PIN_STATE_LEVEL_0]); +??????????????? //Bug 577281, zhoumin.wt, add, 2020.01.27, resolve problem: the DVDD voltage of front camera can not set to be 1.2V +??????????????? check_for_regulator_put(preg, sensor_idx, +??????????????????? (reg_type_offset + pin - IMGSENSOR_HW_PIN_AVDD)); ????????????????? return IMGSENSOR_RETURN_ERROR; ????????????? } @@ -290,9 +308,16 @@ static enum IMGSENSOR_RETURN regulator_set( ????????????????????? pr_err( ? ????????????????????????"[regulator]fail to regulator_disable, powertype: %d\n", ????????????????????????? pin); +??????????????????? //Bug 577281, zhoumin.wt, add, 2020.01.27, resolve problem: the DVDD voltage of front camera can not set to be 1.2V +???? ???????????????check_for_regulator_put(preg, sensor_idx, +??????????????????????? (reg_type_offset + pin - IMGSENSOR_HW_PIN_AVDD)); + ????????????????????? return IMGSENSOR_RETURN_ERROR; ????????????????? } ????????????? } +??????????? //Bug 577281, zhoumin.wt, add, 2020.01.27, resolve problem: the DVDD voltage of front camera can not set to be 1.2V +??????????? check_for_regulator_put(preg, sensor_idx, +??????????????? (reg_type_offset + pin - IMGSENSOR_HW_PIN_AVDD)); ????????????? atomic_dec(enable_cnt); ????????? } ????? } else { @@ -305,6 +330,80 @@ static enum IMGSENSOR_RETURN regulator_set( ????? return IMGSENSOR_RETURN_SUCCESS; ? } +//+ Bug 577281, zhoumin.wt, add, 2020.01.27, resolve problem: the DVDD voltage of front camera can not set to be 1.2V +static void check_for_regulator_get(struct REGULATOR *preg, +??? struct device *pdevice, unsigned int sensor_index, +??? unsigned int regulator_index) +{ +??? struct device_node *pof_node = NULL; +??? char str_regulator_name[LENGTH_FOR_SNPRINTF]; + +??? if (!preg || !pdevice) { +??????? pr_err("Fatal: Null ptr.preg:%pK,pdevice:%pK\n", preg, pdevice); +??????? return; +??? } + +??? if (sensor_index >= IMGSENSOR_SENSOR_IDX_MAX_NUM || +???????? regulator_index >= REGULATOR_TYPE_MAX_NUM ) { +???????? pr_err("[%s]Invalid sensor_idx:%d regulator_idx: %d\n", +???????? __func__, sensor_index, regulator_index); +???????? return; +??? } + +???? mutex_lock(&g_regulator_state_mutex); + +???? if (regulator_status[sensor_index][regulator_index] == false) { +???????? pof_node = pdevice->of_node; +???????? pdevice->of_node = of_node_record; + +???????? snprintf(str_regulator_name, +???????????? sizeof(str_regulator_name), +???????????? "cam%d_%s", +???????????? sensor_index, +???????????? regulator_control[regulator_index].pregulator_type); +???????? preg->pregulator[sensor_index][regulator_index] = +???????????? regulator_get(pdevice, str_regulator_name); + +???????? if (preg != NULL) +??????????? regulator_status[sensor_index][regulator_index] = true; +???????? else + ???????????pr_err("get regulator failed.\n"); +???????? pdevice->of_node = pof_node; +???? } + +???? mutex_unlock(&g_regulator_state_mutex); + +???? return; +} + +static void check_for_regulator_put(struct REGULATOR *preg, +??? unsigned int sensor_index, unsigned int regulator_index) +{ +???? if (!preg) { +???????? pr_err("Fatal: Null ptr.\n"); +???????? return; +???? } + +???? if (sensor_index >= IMGSENSOR_SENSOR_IDX_MAX_NUM || +???????? regulator_index >= REGULATOR_TYPE_MAX_NUM ) { +???????? pr_err("[%s]Invalid sensor_idx:%d regulator_idx: %d\n", +???????? __func__, sensor_index, regulator_index); +???????? return; +???? } + +???? mutex_lock(&g_regulator_state_mutex); + +???? if (regulator_status[sensor_index][regulator_index] == true) { +? regulator_put(preg->pregulator[sensor_index][regulator_index]); +???????? regulator_status[sensor_index][regulator_index] = false; +???? } + +???? mutex_unlock(&g_regulator_state_mutex); + +???? return; +} +//Bug 577281, zhoumin.wt, add, 2020.01.27, resolve problem: the DVDD voltage of front camera can not set to be 1.2V + ? static struct IMGSENSOR_HW_DEVICE device = { ????? .pinstance = (void *)®_instance, ????? .init????? = regulator_init, |
|
C++知识库 最新文章 |
【C++】友元、嵌套类、异常、RTTI、类型转换 |
通讯录的思路与实现(C语言) |
C++PrimerPlus 第七章 函数-C++的编程模块( |
Problem C: 算法9-9~9-12:平衡二叉树的基本 |
MSVC C++ UTF-8编程 |
C++进阶 多态原理 |
简单string类c++实现 |
我的年度总结 |
【C语言】以深厚地基筑伟岸高楼-基础篇(六 |
c语言常见错误合集 |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/24 2:24:18- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |