[COMMON] fimc-is2: add function for dw9839 actuator actual ADC position read
authorWooyeon Kim <wooy88.kim@samsung.com>
Wed, 14 Nov 2018 02:42:48 +0000 (11:42 +0900)
committerxiest1 <xiest1@lenovo.com>
Tue, 5 Nov 2019 09:29:56 +0000 (17:29 +0800)
 - dw9839 actuator supports a actual ADC position

 PR JIRA ID: CPR-397

Change-Id: I24e70c6666013d7f3c485a8f1fc2aa7aee83c0a7
Signed-off-by: Wooyeon Kim <wooy88.kim@samsung.com>
drivers/media/platform/exynos/fimc-is2/sensor/module_framework/actuator/fimc-is-actuator-dw9839.c

index e04f837c1a465f659b250c667883dd7136766e45..d07f7063c779aede101061a82574df8ff1b8dd03 100644 (file)
@@ -154,6 +154,24 @@ skip_cal:
        actuator_info->pcal = (pcal_msb << 8) | pcal_lsb;
        actuator_info->ncal = (ncal_msb << 8) | ncal_lsb;
 
+       /* read pcal, ncal */
+       actuator_info = (struct dw9839_actuator_info *)actuator->priv_info;
+       ret = fimc_is_sensor_addr8_read8(client, REG_PCAL_MSB, &pcal_msb);
+       if (ret < 0)
+               goto p_err;
+       ret = fimc_is_sensor_addr8_read8(client, REG_PCAL_LSB, &pcal_lsb);
+       if (ret < 0)
+               goto p_err;
+       ret = fimc_is_sensor_addr8_read8(client, REG_NCAL_MSB, &ncal_msb);
+       if (ret < 0)
+               goto p_err;
+       ret = fimc_is_sensor_addr8_read8(client, REG_NCAL_LSB, &ncal_lsb);
+       if (ret < 0)
+               goto p_err;
+
+       actuator_info->pcal = (pcal_msb << 8) | pcal_lsb;
+       actuator_info->ncal = (ncal_msb << 8) | ncal_lsb;
+
        info("%s done\n", __func__);
 p_err:
        return ret;
@@ -480,6 +498,72 @@ p_err:
        return ret;
 }
 
+int sensor_dw9839_actuator_get_actual_position(struct v4l2_subdev *subdev, u32 *info)
+{
+       int ret = 0;
+       struct fimc_is_actuator *actuator;
+       struct i2c_client *client;
+       struct dw9839_actuator_info *actuator_info;
+       u8 pos_msb = 0, pos_lsb = 0;
+       u32 adc_pos;
+       u64 temp;
+
+#ifdef DEBUG_ACTUATOR_TIME
+       struct timeval st, end;
+
+       do_gettimeofday(&st);
+#endif
+
+       FIMC_BUG(!subdev);
+       FIMC_BUG(!info);
+
+       actuator = (struct fimc_is_actuator *)v4l2_get_subdevdata(subdev);
+       FIMC_BUG(!actuator);
+
+       client = actuator->client;
+       if (unlikely(!client)) {
+               err("client is NULL");
+               ret = -EINVAL;
+               goto p_err;
+       }
+
+       FIMC_BUG(!actuator->priv_info);
+       actuator_info = (struct dw9839_actuator_info *)actuator->priv_info;
+
+       ret = fimc_is_sensor_addr8_write8(client, REG_ADC_R_EN, 1);
+       if (ret < 0)
+               goto p_err;
+       ret = fimc_is_sensor_addr8_read8(client, REG_ADC_R_MSB, &pos_msb);
+       if (ret < 0)
+               goto p_err;
+       ret = fimc_is_sensor_addr8_read8(client, REG_ADC_R_LSB, &pos_lsb);
+       if (ret < 0)
+               goto p_err;
+
+       adc_pos = (pos_msb << 8) | pos_lsb;
+
+       /* convert adc_pos to 10bit position
+        * ncal <= adc_pos <= pcal ------> 0 <= 10bit_pos <= 1023
+        */
+       temp = (u64)(adc_pos - actuator_info->ncal) << ACTUATOR_POS_SIZE_10BIT;
+       *info = (u32)(temp / (u64)(actuator_info->pcal - actuator_info->ncal));
+
+       if (*info > 1023)
+               *info = 1023;
+
+       dbg_actuator("%s: pcal(%d), ncal(%d), adc_pos(%d) --> target_pos(%d) actual pos(%d)\n",
+                       __func__, actuator_info->pcal, actuator_info->ncal, adc_pos,
+                       actuator->position, *info);
+
+#ifdef DEBUG_ACTUATOR_TIME
+       do_gettimeofday(&end);
+       pr_info("[%s] time %lu us", __func__, (end.tv_sec - st.tv_sec) * 1000000 + (end.tv_usec - st.tv_usec));
+#endif
+
+p_err:
+       return ret;
+}
+
 static int sensor_dw9839_actuator_g_ctrl(struct v4l2_subdev *subdev, struct v4l2_control *ctrl)
 {
        int ret = 0;