搜索

451

主题

663

帖子

5343

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
5343
QQ
发表于 2021-6-24 19:19:45 10009 浏览 0 回复

[FAQ22659] [Android Q] Camera Sensor Regulator Restricting voltage 的处理...

[DESCRIPTION]

Linux regulator framework允许针对某个LDO取得多个consumer regulator instance,并且会纪录该LDO使用的consumer list,安全起见会使用该list中电压设值最小的来供电,因此当不同regulator instance设定为不同电压时就会出现Restricting voltage这样的错误log:
关键log为 "Restricting voltage":

01-01 00:05:54.771655   517   517 E [  124.722793].(0)[517:camerahalserver][name:core&]vcamd: Restricting voltage, 1200000-1100000uV


[SOLUTION]


Power off时一并释放regulator(Call regulator_put()),然后于power on时重新取得regulator。用这个做法时,需要注意确保thread safe,regulator取得与释放时需要互斥锁定。
当前的FAQ中提供了Android Q下MT6873和MT6765平台上的修改方案,其他平台可参考修改。
Android P下该问题的解决办法可以参考FAQ20676 [Android P] Camera Sensor Regulator Restricting voltage 的处理方法。

MT6873
  1.   diff --git a/drivers/misc/mediatek/imgsensor/src/mt6873/camera_hw/regulator/regulator.c b/drivers/misc/mediatek/imgsensor/src/mt6873/camera_hw/regulator/regulator.c
  2. index 2132cc748f08..9de92138cd66
  3. --- a/drivers/misc/mediatek/imgsensor/src/mt6873/camera_hw/regulator/regulator.c
  4. +++ b/drivers/misc/mediatek/imgsensor/src/mt6873/camera_hw/regulator/regulator.c
  5. @@ -13,7 +13,17 @@

  6. #include "regulator.h"

  7. +static bool regulator_status[IMGSENSOR_SENSOR_IDX_MAX_NUM][
  8. + REGULATOR_TYPE_MAX_NUM] = {{false}};
  9. +static void check_for_regulator_get(struct REGULATOR *preg,
  10. + struct device *pdevice, unsigned int sensor_index,
  11. + unsigned int regulator_index);
  12. +static void check_for_regulator_put(struct REGULATOR *preg,
  13. + unsigned int sensor_index, unsigned int regulator_index);
  14. +static struct device_node *of_node_record;
  15. +static struct IMGSENSOR_HW_DEVICE_COMMON *ghw_device_common;

  16. +static DEFINE_MUTEX(g_regulator_state_mutex);
  17. static const int regulator_voltage[] = {
  18. REGULATOR_VOLTAGE_0,
  19. REGULATOR_VOLTAGE_1000,
  20. @@ -43,7 +53,10 @@ static enum IMGSENSOR_RETURN regulator_init(
  21. struct REGULATOR *preg = (struct REGULATOR *)pinstance;
  22. int type, idx;
  23. char str_regulator_name[LENGTH_FOR_SNPRINTF];
  24. -
  25. +
  26. + ghw_device_common = pcommon;
  27. + of_node_record = pcommon->pplatform_device->dev.of_node;
  28. +
  29. for (idx = IMGSENSOR_SENSOR_IDX_MIN_NUM;
  30. idx < IMGSENSOR_SENSOR_IDX_MAX_NUM;
  31. idx++) {
  32. @@ -113,7 +126,11 @@ static enum IMGSENSOR_RETURN regulator_set(
  33. return IMGSENSOR_RETURN_ERROR;

  34. reg_type_offset = REGULATOR_TYPE_VCAMA;
  35. -
  36. +
  37. + if (ghw_device_common)
  38. + check_for_regulator_get(preg, &ghw_device_common->pplatform_device->dev, sensor_idx,
  39. + (reg_type_offset + pin - IMGSENSOR_HW_PIN_AVDD));
  40. +
  41. pregulator =
  42. preg->pregulator[sensor_idx][
  43. reg_type_offset + pin - IMGSENSOR_HW_PIN_AVDD];
  44. @@ -142,6 +159,10 @@ static enum IMGSENSOR_RETURN regulator_set(
  45. pin,
  46. regulator_voltage[
  47. pin_state - IMGSENSOR_HW_PIN_STATE_LEVEL_0]);
  48. +
  49. + check_for_regulator_put(preg, sensor_idx,
  50. + (reg_type_offset + pin - IMGSENSOR_HW_PIN_AVDD));
  51. +
  52. return IMGSENSOR_RETURN_ERROR;
  53. }
  54. atomic_inc(enable_cnt);
  55. @@ -153,8 +174,16 @@ static enum IMGSENSOR_RETURN regulator_set(
  56. PK_PR_ERR(
  57. "[regulator]fail to regulator_disable, powertype: %d\n",
  58. pin);
  59. +
  60. + check_for_regulator_put(preg, sensor_idx,
  61. + (reg_type_offset + pin - IMGSENSOR_HW_PIN_AVDD));
  62. +
  63. return IMGSENSOR_RETURN_ERROR;
  64. }
  65. +
  66. + check_for_regulator_put(preg, sensor_idx,
  67. + (reg_type_offset + pin - IMGSENSOR_HW_PIN_AVDD));
  68. +
  69. atomic_dec(enable_cnt);
  70. }
  71. } else {
  72. @@ -166,7 +195,77 @@ static enum IMGSENSOR_RETURN regulator_set(

  73. return IMGSENSOR_RETURN_SUCCESS;
  74. }
  75. +static void check_for_regulator_get(struct REGULATOR *preg,
  76. + struct device *pdevice, unsigned int sensor_index,
  77. + unsigned int regulator_index)
  78. +{
  79. + struct device_node *pof_node = NULL;
  80. + char str_regulator_name[LENGTH_FOR_SNPRINTF];
  81. +
  82. + if (!preg || !pdevice) {
  83. + pr_err("Fatal: Null ptr.preg:%pK,pdevice:%pK\n", preg, pdevice);
  84. + return;
  85. + }
  86. +
  87. + if (sensor_index >= IMGSENSOR_SENSOR_IDX_MAX_NUM ||
  88. + regulator_index >= REGULATOR_TYPE_MAX_NUM ) {
  89. + pr_err("[%s]Invalid sensor_idx:%d regulator_idx: %d\n",
  90. + __func__, sensor_index, regulator_index);
  91. + return;
  92. + }
  93. +
  94. + mutex_lock(&g_regulator_state_mutex);
  95. +
  96. + if (regulator_status[sensor_index][regulator_index] == false) {
  97. + pof_node = pdevice->of_node;
  98. + pdevice->of_node = of_node_record;
  99. +
  100. + snprintf(str_regulator_name,
  101. + sizeof(str_regulator_name),
  102. + "cam%d_%s",
  103. + sensor_index,
  104. + regulator_control[regulator_index].pregulator_type);
  105. + preg->pregulator[sensor_index][regulator_index] =
  106. + regulator_get(pdevice, str_regulator_name);
  107. +
  108. + if (preg != NULL)
  109. + regulator_status[sensor_index][regulator_index] = true;
  110. + else
  111. + pr_err("get regulator failed.\n");
  112. + pdevice->of_node = pof_node;
  113. + }
  114. +
  115. + mutex_unlock(&g_regulator_state_mutex);

  116. + return;
  117. +}
  118. +
  119. +static void check_for_regulator_put(struct REGULATOR *preg,
  120. + unsigned int sensor_index, unsigned int regulator_index)
  121. +{
  122. + if (!preg) {
  123. + pr_err("Fatal: Null ptr.\n");
  124. + return;
  125. + }
  126. +
  127. + if (sensor_index >= IMGSENSOR_SENSOR_IDX_MAX_NUM ||
  128. + regulator_index >= REGULATOR_TYPE_MAX_NUM ) {
  129. + pr_err("[%s]Invalid sensor_idx:%d regulator_idx: %d\n",
  130. + __func__, sensor_index, regulator_index);
  131. + return;
  132. + }
  133. +
  134. + mutex_lock(&g_regulator_state_mutex);
  135. +
  136. + if (regulator_status[sensor_index][regulator_index] == true) {
  137. + regulator_put(preg->pregulator[sensor_index][regulator_index]);
  138. + preg->pregulator[sensor_index][regulator_index] = NULL;
  139. + regulator_status[sensor_index][regulator_index] = false;
  140. + }
  141. +
  142. + mutex_unlock(&g_regulator_state_mutex);
  143. +
  144. + return;
  145. +}
  146. static enum IMGSENSOR_RETURN regulator_dump(void *pinstance)
  147. {
  148. struct REGULATOR *preg = (struct REGULATOR *)pinstance;
复制代码

MT6765

  1. +static bool regulator_status[IMGSENSOR_SENSOR_IDX_MAX_NUM][
  2. + REGULATOR_TYPE_MAX_NUM] = {false};
  3. +static void check_for_regulator_get(struct REGULATOR *preg,
  4. + struct device *pdevice, unsigned int sensor_index,
  5. + unsigned int regulator_index);
  6. +static void check_for_regulator_put(struct REGULATOR *preg,
  7. + unsigned int sensor_index, unsigned int regulator_index);
  8. +static struct device_node *of_node_record = NULL;
  9. +
  10. +static DEFINE_MUTEX(g_regulator_state_mutex);
  11. +
  12. static const int regulator_voltage[] = {
  13. REGULATOR_VOLTAGE_0,
  14. REGULATOR_VOLTAGE_1000,
  15. @@ -183,12 +194,12 @@
  16. pof_node = pdevice->of_node;
  17. pdevice->of_node =
  18. of_find_compatible_node(NULL, NULL, "mediatek,camera_hw");
  19. -
  20. if (pdevice->of_node == NULL) {
  21. pr_err("regulator get cust camera node failed!\n");
  22. pdevice->of_node = pof_node;
  23. return IMGSENSOR_RETURN_ERROR;
  24. }
  25. + of_node_record = pdevice->of_node;

  26. for (j = IMGSENSOR_SENSOR_IDX_MIN_NUM;
  27. j < IMGSENSOR_SENSOR_IDX_MAX_NUM;
  28. @@ -207,6 +218,7 @@
  29. j, i, str_regulator_name);

  30. atomic_set(&preg->enable_cnt[j][i], 0);
  31. + regulator_status[j][i] = true;
  32. }
  33. }
  34. pdevice->of_node = pof_node;
  35. @@ -257,7 +269,8 @@
  36. return IMGSENSOR_RETURN_ERROR;

  37. reg_type_offset = REGULATOR_TYPE_VCAMA;
  38. -
  39. + check_for_regulator_get(preg, gimgsensor_device, sensor_idx,
  40. + (reg_type_offset + pin - IMGSENSOR_HW_PIN_AVDD));
  41. pregulator =
  42. preg->pregulator[sensor_idx][
  43. reg_type_offset + pin - IMGSENSOR_HW_PIN_AVDD];
  44. @@ -300,7 +313,8 @@
  45. pin,
  46. regulator_voltage[
  47. pin_state - IMGSENSOR_HW_PIN_STATE_LEVEL_0]);
  48. -
  49. + check_for_regulator_put(preg, sensor_idx,
  50. + (reg_type_offset + pin - IMGSENSOR_HW_PIN_AVDD));
  51. return IMGSENSOR_RETURN_ERROR;
  52. }
  53. atomic_inc(enable_cnt);
  54. @@ -312,9 +326,13 @@
  55. pr_err(
  56. "[regulator]fail to regulator_disable, powertype: %d\n",
  57. pin);
  58. + check_for_regulator_put(preg, sensor_idx,
  59. + (reg_type_offset + pin - IMGSENSOR_HW_PIN_AVDD));
  60. return IMGSENSOR_RETURN_ERROR;
  61. }
  62. }
  63. + check_for_regulator_put(preg, sensor_idx,
  64. + (reg_type_offset + pin - IMGSENSOR_HW_PIN_AVDD));
  65. atomic_dec(enable_cnt);
  66. }
  67. } else {
  68. @@ -327,6 +345,78 @@
  69. return IMGSENSOR_RETURN_SUCCESS;
  70. }

  71. +static void check_for_regulator_get(struct REGULATOR *preg,
  72. + struct device *pdevice, unsigned int sensor_index,
  73. + unsigned int regulator_index)
  74. +{
  75. + struct device_node *pof_node = NULL;
  76. + char str_regulator_name[LENGTH_FOR_SNPRINTF];
  77. +
  78. + if (!preg || !pdevice) {
  79. + pr_err("Fatal: Null ptr.preg:%pK,pdevice:%pK\n", preg, pdevice);
  80. + return;
  81. + }
  82. +
  83. + if (sensor_index >= IMGSENSOR_SENSOR_IDX_MAX_NUM ||
  84. + regulator_index >= REGULATOR_TYPE_MAX_NUM ) {
  85. + pr_err("[%s]Invalid sensor_idx:%d regulator_idx: %d\n",
  86. + __func__, sensor_index, regulator_index);
  87. + return;
  88. + }
  89. +
  90. + mutex_lock(&g_regulator_state_mutex);
  91. +
  92. + if (regulator_status[sensor_index][regulator_index] == false) {
  93. + pof_node = pdevice->of_node;
  94. + pdevice->of_node = of_node_record;
  95. +
  96. + snprintf(str_regulator_name,
  97. + sizeof(str_regulator_name),
  98. + "cam%d_%s",
  99. + sensor_index,
  100. + regulator_control[regulator_index].pregulator_type);
  101. + preg->pregulator[sensor_index][regulator_index] =
  102. + regulator_get(pdevice, str_regulator_name);
  103. +
  104. + if (preg != NULL)
  105. + regulator_status[sensor_index][regulator_index] = true;
  106. + else
  107. + pr_err("get regulator failed.\n");
  108. + pdevice->of_node = pof_node;
  109. + }
  110. +
  111. + mutex_unlock(&g_regulator_state_mutex);
  112. +
  113. + return;
  114. +}
  115. +
  116. +static void check_for_regulator_put(struct REGULATOR *preg,
  117. + unsigned int sensor_index, unsigned int regulator_index)
  118. +{
  119. + if (!preg) {
  120. + pr_err("Fatal: Null ptr.\n");
  121. + return;
  122. + }
  123. +
  124. + if (sensor_index >= IMGSENSOR_SENSOR_IDX_MAX_NUM ||
  125. + regulator_index >= REGULATOR_TYPE_MAX_NUM ) {
  126. + pr_err("[%s]Invalid sensor_idx:%d regulator_idx: %d\n",
  127. + __func__, sensor_index, regulator_index);
  128. + return;
  129. + }
  130. +
  131. + mutex_lock(&g_regulator_state_mutex);
  132. +
  133. + if (regulator_status[sensor_index][regulator_index] == true) {
  134. + regulator_put(preg->pregulator[sensor_index][regulator_index]);
  135. + preg->pregulator[sensor_index][regulator_index] = NULL;
  136. + regulator_status[sensor_index][regulator_index] = false;
  137. + }
  138. +
  139. + mutex_unlock(&g_regulator_state_mutex);
  140. +
  141. + return;
  142. +}
  143. +
  144. static struct IMGSENSOR_HW_DEVICE device = {
  145. .pinstance = (void *)&reg_instance,
  146. .init = regulator_init,
复制代码




本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
手机微信同号:13682654092
回复

使用道具 举报

返回列表
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则


登录或注册
快速回复 返回顶部 返回列表