IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: 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 = &regulator->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 *)&reg_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语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-10-15 11:36:23  更:2021-10-15 11:37:45 
 
开发: 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-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码