|
发表于 2021-6-24 19:34:11
10338 浏览 0 回复
[FAQ20676] [Android P] Camera Sensor Regulator Restricting voltage 的处理...
[DESCRIPTION]
Camera Sensor 不同电压的引脚共用regulator 时,regulator 为了保护低电压引脚不被被烧坏,会把低电压引脚的电压设置成regulator的最高电压,从而使高电压引脚无法上电。
关键log为 "Restricting voltage":
- 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平台,其他平台可参考示例代码做修改):
- /drivers/misc/mediatek/imgsensor/src/mt6739/camera_hw/regulator/regulator.c
-
- #include "regulator.h"
- -
- +static int regulator_status[REGULATOR_TYPE_MAX_NUM] = {0};
- +static void check_for_regulator_get(struct REGULATOR *preg, struct device *pdevice, int index);
- +static void check_for_regulator_put(struct REGULATOR *preg, int index);
- +static struct device_node *of_node_record = NULL;
- +static DEFINE_MUTEX(g_regulator_state_mutex);
-
- static const int regulator_voltage[] = {
- REGULATOR_VOLTAGE_0,
- @@ -58,6 +61,7 @@ static enum IMGSENSOR_RETURN regulator_init(void *pinstance)
- pdevice = gimgsensor_device;
- pof_node = pdevice->of_node;
- pdevice->of_node = of_find_compatible_node(NULL, NULL, "mediatek,camera_hw");
- + of_node_record = pdevice->of_node;
-
- if (pdevice->of_node == NULL) {
- PK_PR_ERR("regulator get cust camera node failed!\n");
- @@ -71,6 +75,7 @@ static enum IMGSENSOR_RETURN regulator_init(void *pinstance)
- PK_PR_ERR("regulator[%d] %s fail!\n",
- i, pregulator_ctrl->pregulator_type);
- atomic_set(&preg->enable_cnt[i], 0);
- + regulator_status[i] = 1;
- }
-
-
- @@ -116,7 +121,8 @@ static enum IMGSENSOR_RETURN regulator_set(
- (sensor_idx == IMGSENSOR_SENSOR_IDX_SUB) ? REGULATOR_TYPE_SUB_VCAMA :
- (sensor_idx == IMGSENSOR_SENSOR_IDX_MAIN2) ? REGULATOR_TYPE_MAIN2_VCAMA :
- REGULATOR_TYPE_SUB2_VCAMA;
- -
- + //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)]);
- + check_for_regulator_get(preg, gimgsensor_device, (reg_type_offset + pin - IMGSENSOR_HW_PIN_AVDD));
- pregulator = preg->pregulator[reg_type_offset + pin - IMGSENSOR_HW_PIN_AVDD];
- enable_cnt = preg->enable_cnt + (reg_type_offset + pin - IMGSENSOR_HW_PIN_AVDD);
-
- @@ -145,6 +151,7 @@ static enum IMGSENSOR_RETURN regulator_set(
- PK_PR_ERR("[regulator]fail to regulator_disable, powertype: %d\n", pin);
- return IMGSENSOR_RETURN_ERROR;
- }
- + check_for_regulator_put(preg, (reg_type_offset + pin - IMGSENSOR_HW_PIN_AVDD));
- atomic_dec(enable_cnt);
- }
- } else {
- @@ -170,3 +177,28 @@ enum IMGSENSOR_RETURN imgsensor_hw_regulator_open(
- return IMGSENSOR_RETURN_SUCCESS;
- }
-
- +static void check_for_regulator_get(struct REGULATOR *preg, struct device *pdevice, int index)
- +{
- + struct device_node *pof_node;
- + mutex_lock(&g_regulator_state_mutex);
- + if(regulator_status[index]==0)
- + {
- + pof_node = pdevice->of_node;
- + pdevice->of_node = of_node_record;
- +
- + preg->pregulator[index] = regulator_get(pdevice, regulator_control[index].pregulator_type);
- +
- + pdevice->of_node = pof_node;
- + regulator_status[index] = 1;
- + //pr_err("regulator_dbg regulator_get %s, of_node:%p\n", regulator_control[index].pregulator_type, of_node_record);
- + }
- + mutex_unlock(&g_regulator_state_mutex);
- +}
- +
- +static void check_for_regulator_put(struct REGULATOR *preg, int index)
- +{
- + mutex_lock(&g_regulator_state_mutex);
- + if(regulator_status[index]==1)
- + {
- + regulator_put(preg->pregulator[index]);
- + preg->pregulator[index] = NULL;
- + regulator_status[index]=0;
- + //pr_err("regulator_dbg regulator_put %s\n", regulator_control[index].pregulator_type);
- + }
- + mutex_unlock(&g_regulator_state_mutex);
- +}
- --
复制代码
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
|
手机微信同号:13682654092
|
|
|
|
|
登录或注册
|