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,

MTK平台前后摄使用PMIC供电无法设置不同的DVDD电压相关推荐

  1. MTK平台点亮sensor以及mtk开机初始化

    MTK点亮sensor Probe:上电–>matach id–>下电 Driver:Kernel部分和Hal部分 dtsi:主要配置GPI的上电逻辑,把camera的上电管脚与平台管脚相 ...

  2. MTK平台发展及各芯片功能介绍2

    近几年MTK手机大行其道,从网络上摘抄了一份介绍MTK芯片的资料,现分享给大家. 目前联发科技已开发出MT6205.MT6217.MT6218.MT6219.MT6226.MT6227.MT6228等 ...

  3. MTK 平台相机点亮介绍

    和你一起终身学习,这里是程序员Android 经典好文推荐,通过阅读本文,您将收获以下知识点: 1.Camera 框架介绍: Camera 的框架分为 Kernel 部分和 hal 部分,其中kern ...

  4. MTK 驱动(67)---深入MTK平台bootloader启动之【 lk -amp;gt; kernel】分析笔记

    Pre-loader 运行在ISRAM,待完成 DRAM 的初始化后,再将lk载入DRAM中,最后通过特殊sys call手段实现跳转到lk的执行入口,正式进入lk初始化阶段. 一.lk执行入口: 位 ...

  5. Android 功耗(4)---MTK平台待机功耗分析流程

    MTK平台待机功耗分析流程 MTK平台待机功耗分析流程 1.目的 2.MTK平台各个场景功耗数据测试方法 很多功耗问题都是因为测试手法不对,列出一些常用场景功耗测试手法.  测试功耗数据之前,请先确认 ...

  6. android 系统优化(20)---MTK 平台唤醒时间优化1

    MTK 平台唤醒流程: 一.唤醒流程: MTK平台唤醒流程是从power键或者其他按键按下开始,本文以mt6753n平台为例,通过分析kernel log来看驱动中整个唤醒的流程,上层的唤醒流程后续再 ...

  7. MTK 平台TP调试遇坑

    #前言 最近在调试我们项目上的TP驱动,奈何一直不能使用,而且这个项目的硬件确定是没有问题的「这个是前提」,我们在软件上提升了SDK基线,在之前的基线版本上软件是没有问题的. 然后我就赶紧检查了两个方 ...

  8. 对mtk平台的一些认识

    +++++++++++++++++++ 微博搜索 bindingfly 欢迎关注 +++++++++++++++++++ 一. 目的       来到这里近两月,更近距离的接近了MTK.身处基于MTK ...

  9. 深入MTK平台bootloader启动之【 lk -> kernel】分析笔记

    接上一篇分析: <深入MTK平台bootloader启动之[ Pre-loader -> Lk]分析笔记> Pre-loader 运行在ISRAM,待完成 DRAM 的初始化后,再将 ...

  10. MTK平台安卓Q 10.0 camera驱动移植——sensor

    平台MTK676X 安卓:Q/10.0 1. 添加驱动程序文件 将模组厂商提供的驱动程序及调试参数文件拷贝到以下目录.厂商可能会自行客制化,但都是kernel和vendor两处下面,不一定和下面列出的 ...

最新文章

  1. 08Factory Method(工厂方法)模式
  2. spring InitializingBean接口
  3. 深度学习总结:Tensorboard可视化里面的events, graph, histogram
  4. linux文件读写 文件锁、select、poll【转】
  5. A new start!
  6. JS-面向对象-改变This的指向---使用call方法改变this的指向 / 使用apply方法改变this的指向 / 使用bind方法改变this的指向
  7. 如何获取LanuchImage
  8. meta refresh 刷新
  9. Unity3d 周分享(22期 2019.8.30 )
  10. 国内外计算机视觉领域优秀研究团队汇总
  11. 厦门大学继续教育计算机科学毕业难吗,厦门大学工资待遇
  12. php+uc+client_uc_client是如何与UCenter进行通信的
  13. 2022-2027年中国聚酯瓶片行业发展监测及投资战略研究报告
  14. P1867 【Mc生存】经验值 java题解
  15. 空气清爽才是真正的上班的地方
  16. 京东云视频云全面支持AVS2标准
  17. 收不到手机验证码怎么办
  18. 最新云智推任务提交版拉新任务分销系统源码+功能强大
  19. 成大事,赚大钱,都要有股永不服输的精神
  20. window.onload的使用

热门文章

  1. Android青翼蝠王之ContentProvider
  2. PLC1200 模拟量采集
  3. 网络对抗实验报告 | 逆向与Bof基础实验报告
  4. 读书百客:《千秋岁·淡烟平楚》赏析
  5. Python + Scrapy 小小爬虫有大大梦想
  6. matlab quadratic,请教几个quadratic programming的问题
  7. 电子科技大学计算机专业考什么,2015年电子科技大学081203计算机应用技术考研专业目录及考试科目...
  8. 在linux系统下ping不通windows主机问题
  9. 996下的程序员,该如何保证自己的身体健康?
  10. Security注解:@PreAuthorize,@PostAuthorize, @Secured