搜索

451

主题

662

帖子

4963

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
4963
QQ
发表于 2021-6-24 19:34:11 7293 浏览 0 回复

[FAQ20676] [Android P] Camera Sensor Regulator Restricting voltage 的处理...


[DESCRIPTION]

Camera Sensor 不同电压的引脚共用regulator 时,regulator 为了保护低电压引脚不被被烧坏,会把低电压引脚的电压设置成regulator的最高电压,从而使高电压引脚无法上电。
关键log为 "Restricting voltage":
  1. 01-01 00:00:22.329088 447 447 E [ 18.437858].(1)[447:camerahalserver]vcamd: Restricting voltage, 1200000-1100000uV
复制代码


[SOLUTION]

1. 对于共用regulator ,但电压需求不同的引脚:

(1) 下电后,调用 regulator_put 函数,释放掉 regulator。
(2) 上电前,调用 regulator_get 函数,重新申请 regulator。
(3) Android Q下该问题的解决办法可以参考FAQ22659 [Android Q] Camera Sensor Regulator Restricting voltage 的处理方法。

2. 示例代码如下(示例代码基于6739平台,其他平台可参考示例代码做修改):

  1. /drivers/misc/mediatek/imgsensor/src/mt6739/camera_hw/regulator/regulator.c

  2. #include "regulator.h"
  3. -
  4. +static int regulator_status[REGULATOR_TYPE_MAX_NUM] = {0};
  5. +static void check_for_regulator_get(struct REGULATOR *preg, struct device *pdevice, int index);
  6. +static void check_for_regulator_put(struct REGULATOR *preg, int index);
  7. +static struct device_node *of_node_record = NULL;
  8. +static DEFINE_MUTEX(g_regulator_state_mutex);


  9. static const int regulator_voltage[] = {
  10. REGULATOR_VOLTAGE_0,
  11. @@ -58,6 +61,7 @@ static enum IMGSENSOR_RETURN regulator_init(void *pinstance)
  12. pdevice = gimgsensor_device;
  13. pof_node = pdevice->of_node;
  14. pdevice->of_node = of_find_compatible_node(NULL, NULL, "mediatek,camera_hw");
  15. + of_node_record = pdevice->of_node;

  16. if (pdevice->of_node == NULL) {
  17. PK_PR_ERR("regulator get cust camera node failed!\n");
  18. @@ -71,6 +75,7 @@ static enum IMGSENSOR_RETURN regulator_init(void *pinstance)
  19. PK_PR_ERR("regulator[%d] %s fail!\n",
  20. i, pregulator_ctrl->pregulator_type);
  21. atomic_set(&preg->enable_cnt[i], 0);
  22. + regulator_status[i] = 1;
  23. }


  24. @@ -116,7 +121,8 @@ static enum IMGSENSOR_RETURN regulator_set(
  25. (sensor_idx == IMGSENSOR_SENSOR_IDX_SUB) ? REGULATOR_TYPE_SUB_VCAMA :
  26. (sensor_idx == IMGSENSOR_SENSOR_IDX_MAIN2) ? REGULATOR_TYPE_MAIN2_VCAMA :
  27. REGULATOR_TYPE_SUB2_VCAMA;
  28. -
  29. + //pr_err("regulator_dbg regulator_set sensor_idx %d, regulator %s, status %d\n", sensor_idx, regulator_control[(reg_type_offset + pin - IMGSENSOR_HW_PIN_AVDD)].pregulator_type,regulator_status[(reg_type_offset + pin - IMGSENSOR_HW_PIN_AVDD)]);
  30. + check_for_regulator_get(preg, gimgsensor_device, (reg_type_offset + pin - IMGSENSOR_HW_PIN_AVDD));
  31. pregulator = preg->pregulator[reg_type_offset + pin - IMGSENSOR_HW_PIN_AVDD];
  32. enable_cnt = preg->enable_cnt + (reg_type_offset + pin - IMGSENSOR_HW_PIN_AVDD);

  33. @@ -145,6 +151,7 @@ static enum IMGSENSOR_RETURN regulator_set(
  34. PK_PR_ERR("[regulator]fail to regulator_disable, powertype: %d\n", pin);
  35. return IMGSENSOR_RETURN_ERROR;
  36. }
  37. + check_for_regulator_put(preg, (reg_type_offset + pin - IMGSENSOR_HW_PIN_AVDD));
  38. atomic_dec(enable_cnt);
  39. }
  40. } else {
  41. @@ -170,3 +177,28 @@ enum IMGSENSOR_RETURN imgsensor_hw_regulator_open(
  42. return IMGSENSOR_RETURN_SUCCESS;
  43. }

  44. +static void check_for_regulator_get(struct REGULATOR *preg, struct device *pdevice, int index)
  45. +{
  46. + struct device_node *pof_node;
  47. + mutex_lock(&g_regulator_state_mutex);
  48. + if(regulator_status[index]==0)
  49. + {
  50. + pof_node = pdevice->of_node;
  51. + pdevice->of_node = of_node_record;
  52. +
  53. + preg->pregulator[index] = regulator_get(pdevice, regulator_control[index].pregulator_type);
  54. +
  55. + pdevice->of_node = pof_node;
  56. + regulator_status[index] = 1;
  57. + //pr_err("regulator_dbg regulator_get %s, of_node:%p\n", regulator_control[index].pregulator_type, of_node_record);
  58. + }
  59. + mutex_unlock(&g_regulator_state_mutex);
  60. +}
  61. +
  62. +static void check_for_regulator_put(struct REGULATOR *preg, int index)
  63. +{
  64. + mutex_lock(&g_regulator_state_mutex);
  65. + if(regulator_status[index]==1)
  66. + {
  67. + regulator_put(preg->pregulator[index]);
  68. + preg->pregulator[index] = NULL;
  69. + regulator_status[index]=0;
  70. + //pr_err("regulator_dbg regulator_put %s\n", regulator_control[index].pregulator_type);
  71. + }
  72. + mutex_unlock(&g_regulator_state_mutex);
  73. +}
  74. --

复制代码



本帖子中包含更多资源

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

x
手机微信同号:13682654092
回复

使用道具 举报

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

本版积分规则


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