int dw9714_vcm_init(struct v4l2_subdev *sd) { /* set VCM to home position and vcm mode to direct*/ dw9714_dev.vcm_mode = DW9714_DIRECT; dw9714_dev.vcm_settings.update = false; dw9714_dev.platform_data = camera_get_af_platform_data(); return (NULL == dw9714_dev.platform_data) ? -ENODEV : 0; }
int ad5816g_vcm_init(struct v4l2_subdev *sd) { ad5816g_dev.platform_data = camera_get_af_platform_data(); return (NULL == ad5816g_dev.platform_data) ? -ENODEV : 0; }
static int dw9719_i2c_wr16(struct i2c_client *client, u8 reg, u16 val) { struct i2c_msg msg; u8 buf[3] = { reg, (u8)(val >> 8), (u8)(val & 0xff)}; msg.addr = DW9719_VCM_ADDR; msg.flags = 0; msg.len = sizeof(buf); msg.buf = buf; if (i2c_transfer(client->adapter, &msg, 1) != 1) return -EIO; return 0; } int dw9719_vcm_power_up(struct v4l2_subdev *sd) { struct i2c_client *client = v4l2_get_subdevdata(sd); int ret; u8 value; /* Enable power */ ret = dw9719_dev.platform_data->power_ctrl(sd, 1); /* waiting time requested by DW9714A(vcm) */ if (ret) return ret; /* Wait for VBAT to stabilize */ udelay(1); /* * Jiggle SCL pin to wake up device. */ ret = dw9719_i2c_wr8(client, DW9719_CONTROL, 1); /* Need 100us to transit from SHUTDOWN to STANDBY*/ usleep_range(100, 1000); /* Enable the ringing compensation */ ret = dw9719_i2c_wr8(client, DW9719_CONTROL, DW9719_ENABLE_RINGING); if (ret < 0) goto fail_powerdown; /* Use SAC3 mode */ ret = dw9719_i2c_wr8(client, DW9719_MODE, DW9719_MODE_SAC3); if (ret < 0) goto fail_powerdown; /* Set the resonance frequency */ ret = dw9719_i2c_wr8(client, DW9719_VCM_FREQ, DW9719_DEFAULT_VCM_FREQ); if (ret < 0) goto fail_powerdown; /* Detect device */ ret = dw9719_i2c_rd8(client, DW9719_INFO, &value); if (ret < 0) goto fail_powerdown; if (value != DW9719_ID) { ret = -ENXIO; goto fail_powerdown; } dw9719_dev.focus = 0; dw9719_dev.initialized = true; return 0; fail_powerdown: dw9719_dev.platform_data->power_ctrl(sd, 0); return ret; } int dw9719_vcm_power_down(struct v4l2_subdev *sd) { return dw9719_dev.platform_data->power_ctrl(sd, 0); } int dw9719_q_focus_status(struct v4l2_subdev *sd, s32 *value) { static const struct timespec move_time = { .tv_sec = 0, .tv_nsec = 60000000 }; struct timespec current_time, finish_time, delta_time; getnstimeofday(¤t_time); finish_time = timespec_add(dw9719_dev.focus_time, move_time); delta_time = timespec_sub(current_time, finish_time); if (delta_time.tv_sec >= 0 && delta_time.tv_nsec >= 0) { *value = ATOMISP_FOCUS_HP_COMPLETE | ATOMISP_FOCUS_STATUS_ACCEPTS_NEW_MOVE; } else { *value = ATOMISP_FOCUS_STATUS_MOVING | ATOMISP_FOCUS_HP_IN_PROGRESS; } return 0; } int dw9719_t_focus_vcm(struct v4l2_subdev *sd, u16 val) { return -EINVAL; } int dw9719_t_focus_abs(struct v4l2_subdev *sd, s32 value) { struct i2c_client *client = v4l2_get_subdevdata(sd); int ret; value = clamp(value, 0, DW9719_MAX_FOCUS_POS); ret = dw9719_i2c_wr16(client, DW9719_VCM_CURRENT, value); if (ret < 0) return ret; getnstimeofday(&dw9719_dev.focus_time); dw9719_dev.focus = value; return 0; } int dw9719_t_focus_rel(struct v4l2_subdev *sd, s32 value) { return dw9719_t_focus_abs(sd, dw9719_dev.focus + value); } int dw9719_q_focus_abs(struct v4l2_subdev *sd, s32 *value) { *value = dw9719_dev.focus ; return 0; } int dw9719_t_vcm_slew(struct v4l2_subdev *sd, s32 value) { return 0; } int dw9719_t_vcm_timing(struct v4l2_subdev *sd, s32 value) { return 0; } int dw9719_vcm_init(struct v4l2_subdev *sd) { dw9719_dev.platform_data = camera_get_af_platform_data(); return (NULL == dw9719_dev.platform_data) ? -ENODEV : 0; }
int drv201_vcm_init(struct v4l2_subdev *sd) { drv201_dev.platform_data = camera_get_af_platform_data(); return (NULL == drv201_dev.platform_data) ? -ENODEV : 0; }