^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * dw9800w vcm driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2022 Rockchip Electronics Co., Ltd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) //#define DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/i2c.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/pm_runtime.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/rk-camera-module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/version.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <media/v4l2-ctrls.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <media/v4l2-device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/rk_vcm_head.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/compat.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #define DRIVER_VERSION KERNEL_VERSION(0, 0x01, 0x0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #define DW9800W_NAME "dw9800w"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #define DW9800W_MAX_CURRENT 1023U
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #define DW9800W_MAX_REG 1023U
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define DW9800W_DEFAULT_START_CURRENT 553
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define DW9800W_DEFAULT_RATED_CURRENT 853
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define DW9800W_DEFAULT_STEP_MODE 0x0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define DW9800W_DEFAULT_T_SACT 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define DW9800W_DEFAULT_T_DIV 0x1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define REG_NULL 0xFF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define DW9800W_CHIP_ID 0xF2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define DW9800W_REG_CHIP_ID 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) enum mode_e {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) SAC2_MODE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) SAC3_MODE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) SAC4_MODE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) SAC5_MODE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) DIRECT_MODE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) LSC_MODE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) /* dw9800w device structure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) struct dw9800w_device {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) struct v4l2_ctrl_handler ctrls_vcm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) struct i2c_client *client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) struct v4l2_subdev sd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) struct v4l2_device vdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) u16 current_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) struct gpio_desc *power_gpio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) unsigned short current_related_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) unsigned short current_lens_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) unsigned int start_current;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) unsigned int rated_current;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) unsigned int step;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) unsigned int step_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) unsigned int vcm_movefull_t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) unsigned int t_src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) unsigned int t_div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) struct __kernel_old_timeval start_move_tv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) struct __kernel_old_timeval end_move_tv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) unsigned long move_us;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) u32 module_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) const char *module_facing;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) struct rk_cam_vcm_cfg vcm_cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) int max_ma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) struct mutex lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) static inline struct dw9800w_device *to_dw9800w_vcm(struct v4l2_ctrl *ctrl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) return container_of(ctrl->handler, struct dw9800w_device, ctrls_vcm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) static inline struct dw9800w_device *sd_to_dw9800w_vcm(struct v4l2_subdev *subdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) return container_of(subdev, struct dw9800w_device, sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) static int dw9800w_write_reg(struct i2c_client *client, u8 reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) u32 len, u32 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) u32 buf_i, val_i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) u8 buf[5];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) u8 *val_p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) __be32 val_be;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) if (len > 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) buf[0] = reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) val_be = cpu_to_be32(val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) val_p = (u8 *)&val_be;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) buf_i = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) val_i = 4 - len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) while (val_i < 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) buf[buf_i++] = val_p[val_i++];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) if (i2c_master_send(client, buf, len + 1) != len + 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) dev_err(&client->dev, "Failed to write 0x%04x,0x%x\n", reg, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) static int dw9800w_read_reg(struct i2c_client *client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) u8 reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) unsigned int len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) u32 *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) struct i2c_msg msgs[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) u8 *data_be_p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) __be32 data_be = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) if (len > 4 || !len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) data_be_p = (u8 *)&data_be;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) /* Write register address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) msgs[0].addr = client->addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) msgs[0].flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) msgs[0].len = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) msgs[0].buf = (u8 *)®
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) /* Read data from register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) msgs[1].addr = client->addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) msgs[1].flags = I2C_M_RD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) msgs[1].len = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) msgs[1].buf = &data_be_p[4 - len];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) if (ret != ARRAY_SIZE(msgs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) *val = be32_to_cpu(data_be);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) static unsigned int dw9800w_move_time_div(struct dw9800w_device *dev_vcm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) unsigned int move_time_us)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) struct i2c_client *client = dev_vcm->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) unsigned int move_time = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) switch (dev_vcm->t_div) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) move_time = move_time_us * 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) move_time = move_time_us;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) move_time = move_time_us / 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) move_time = move_time_us / 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) move_time = move_time_us * 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) case 5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) move_time = move_time_us * 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) dev_err(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) "%s: t_div parameter err %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) __func__, dev_vcm->t_div);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) return move_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) static unsigned int dw9800w_move_time(struct dw9800w_device *dev_vcm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) unsigned int move_pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) struct i2c_client *client = dev_vcm->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) unsigned int move_time_us = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) switch (dev_vcm->step_mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) case LSC_MODE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) move_time_us = 252 + dev_vcm->t_src * 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) move_time_us = move_time_us * move_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) case SAC2_MODE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) case SAC3_MODE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) case SAC4_MODE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) case SAC5_MODE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) move_time_us = 6300 + dev_vcm->t_src * 100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) move_time_us = dw9800w_move_time_div(dev_vcm, move_time_us);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) case DIRECT_MODE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) move_time_us = 30000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) dev_err(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) "%s: step_mode is error %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) __func__, dev_vcm->step_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) dev_err(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) "%s: vcm_movefull_t is: %d us\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) __func__, move_time_us);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) return move_time_us;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) static int dw9800w_get_pos(struct dw9800w_device *dev_vcm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) unsigned int *cur_pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) struct i2c_client *client = dev_vcm->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) unsigned int abs_step;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) ret = dw9800w_read_reg(client, 0x03, 2, &abs_step);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) if (ret != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) if (abs_step <= dev_vcm->start_current)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) abs_step = VCMDRV_MAX_LOG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) else if ((abs_step > dev_vcm->start_current) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) (abs_step <= dev_vcm->rated_current))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) abs_step = (dev_vcm->rated_current - abs_step) / dev_vcm->step;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) abs_step = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) *cur_pos = abs_step;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) dev_dbg(&client->dev, "%s: get position %d\n", __func__, *cur_pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) dev_err(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) "%s: failed with error %d\n", __func__, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) static int dw9800w_set_pos(struct dw9800w_device *dev_vcm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) unsigned int dest_pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) unsigned int position = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) struct i2c_client *client = dev_vcm->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) u32 is_busy, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) if (dest_pos >= VCMDRV_MAX_LOG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) position = dev_vcm->start_current;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) position = dev_vcm->start_current +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) (dev_vcm->step * (VCMDRV_MAX_LOG - dest_pos));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) if (position > DW9800W_MAX_REG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) position = DW9800W_MAX_REG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) dev_vcm->current_lens_pos = position;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) dev_vcm->current_related_pos = dest_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) for (i = 0; i < 100; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) ret = dw9800w_read_reg(client, 0x05, 1, &is_busy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) if (!ret && !(is_busy & 0x01))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) usleep_range(100, 200);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) ret = dw9800w_write_reg(client, 0x03, 2, dev_vcm->current_lens_pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) if (ret != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) dev_info(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) "%s: set reg val %d\n", __func__, dev_vcm->current_lens_pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) dev_err(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) "%s: failed with error %d\n", __func__, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) static int dw9800w_get_ctrl(struct v4l2_ctrl *ctrl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) struct dw9800w_device *dev_vcm = to_dw9800w_vcm(ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) if (ctrl->id == V4L2_CID_FOCUS_ABSOLUTE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) return dw9800w_get_pos(dev_vcm, &ctrl->val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) static int dw9800w_set_ctrl(struct v4l2_ctrl *ctrl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) struct dw9800w_device *dev_vcm = to_dw9800w_vcm(ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) struct i2c_client *client = dev_vcm->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) unsigned int dest_pos = ctrl->val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) int move_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) long mv_us;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) dev_dbg(&client->dev, "ctrl->id: 0x%x, ctrl->val: 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) ctrl->id, ctrl->val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) if (ctrl->id == V4L2_CID_FOCUS_ABSOLUTE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) if (dest_pos > VCMDRV_MAX_LOG) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) dev_info(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) "%s dest_pos is error. %d > %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) __func__, dest_pos, VCMDRV_MAX_LOG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) /* calculate move time */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) move_pos = dev_vcm->current_related_pos - dest_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) if (move_pos < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) move_pos = -move_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) ret = dw9800w_set_pos(dev_vcm, dest_pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) if (dev_vcm->step_mode == LSC_MODE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) dev_vcm->move_us = ((dev_vcm->vcm_movefull_t * (uint32_t)move_pos) /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) VCMDRV_MAX_LOG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) dev_vcm->move_us = dev_vcm->vcm_movefull_t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) dev_dbg(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) "dest_pos %d, move_us %ld\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) dest_pos, dev_vcm->move_us);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) dev_vcm->start_move_tv = ns_to_kernel_old_timeval(ktime_get_ns());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) mv_us = dev_vcm->start_move_tv.tv_usec +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) dev_vcm->move_us;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) if (mv_us >= 1000000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) dev_vcm->end_move_tv.tv_sec =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) dev_vcm->start_move_tv.tv_sec + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) dev_vcm->end_move_tv.tv_usec = mv_us - 1000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) dev_vcm->end_move_tv.tv_sec =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) dev_vcm->start_move_tv.tv_sec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) dev_vcm->end_move_tv.tv_usec = mv_us;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) static const struct v4l2_ctrl_ops dw9800w_vcm_ctrl_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) .g_volatile_ctrl = dw9800w_get_ctrl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) .s_ctrl = dw9800w_set_ctrl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) static int dw9800w_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) int rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) rval = pm_runtime_get_sync(sd->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) if (rval < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) pm_runtime_put_noidle(sd->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) static int dw9800w_close(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) pm_runtime_put(sd->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) static const struct v4l2_subdev_internal_ops dw9800w_int_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) .open = dw9800w_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) .close = dw9800w_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) static void dw9800w_update_vcm_cfg(struct dw9800w_device *dev_vcm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) struct i2c_client *client = dev_vcm->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) int cur_dist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) if (dev_vcm->max_ma == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) dev_err(&client->dev, "max current is zero");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) cur_dist = dev_vcm->vcm_cfg.rated_ma - dev_vcm->vcm_cfg.start_ma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) cur_dist = cur_dist * DW9800W_MAX_REG / dev_vcm->max_ma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) dev_vcm->step = (cur_dist + (VCMDRV_MAX_LOG - 1)) / VCMDRV_MAX_LOG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) dev_vcm->start_current = dev_vcm->vcm_cfg.start_ma *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) DW9800W_MAX_REG / dev_vcm->max_ma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) dev_vcm->rated_current = dev_vcm->vcm_cfg.rated_ma *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) DW9800W_MAX_REG / dev_vcm->max_ma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) dev_vcm->step_mode = dev_vcm->vcm_cfg.step_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) dev_info(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) "vcm_cfg: %d, %d, %d, max_ma %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) dev_vcm->vcm_cfg.start_ma,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) dev_vcm->vcm_cfg.rated_ma,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) dev_vcm->vcm_cfg.step_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) dev_vcm->max_ma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) static long dw9800w_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) struct dw9800w_device *dev_vcm = sd_to_dw9800w_vcm(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) struct i2c_client *client = dev_vcm->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) struct rk_cam_vcm_tim *vcm_tim;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) struct rk_cam_vcm_cfg *vcm_cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) if (cmd == RK_VIDIOC_VCM_TIMEINFO) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) vcm_tim = (struct rk_cam_vcm_tim *)arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) vcm_tim->vcm_start_t.tv_sec = dev_vcm->start_move_tv.tv_sec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) vcm_tim->vcm_start_t.tv_usec =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) dev_vcm->start_move_tv.tv_usec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) vcm_tim->vcm_end_t.tv_sec = dev_vcm->end_move_tv.tv_sec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) vcm_tim->vcm_end_t.tv_usec = dev_vcm->end_move_tv.tv_usec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) dev_dbg(&client->dev, "dw9800w_get_move_res 0x%lx, 0x%lx, 0x%lx, 0x%lx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) vcm_tim->vcm_start_t.tv_sec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) vcm_tim->vcm_start_t.tv_usec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) vcm_tim->vcm_end_t.tv_sec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) vcm_tim->vcm_end_t.tv_usec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) } else if (cmd == RK_VIDIOC_GET_VCM_CFG) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) vcm_cfg = (struct rk_cam_vcm_cfg *)arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) vcm_cfg->start_ma = dev_vcm->vcm_cfg.start_ma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) vcm_cfg->rated_ma = dev_vcm->vcm_cfg.rated_ma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) vcm_cfg->step_mode = dev_vcm->vcm_cfg.step_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) } else if (cmd == RK_VIDIOC_SET_VCM_CFG) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) vcm_cfg = (struct rk_cam_vcm_cfg *)arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) if (vcm_cfg->start_ma == 0 && vcm_cfg->rated_ma == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) dev_err(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) "vcm_cfg err, start_ma %d, rated_ma %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) vcm_cfg->start_ma, vcm_cfg->rated_ma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) dev_vcm->vcm_cfg.start_ma = vcm_cfg->start_ma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) dev_vcm->vcm_cfg.rated_ma = vcm_cfg->rated_ma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) dev_vcm->vcm_cfg.step_mode = vcm_cfg->step_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) dw9800w_update_vcm_cfg(dev_vcm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) dev_err(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) "cmd 0x%x not supported\n", cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) #ifdef CONFIG_COMPAT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) static long dw9800w_compat_ioctl32(struct v4l2_subdev *sd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) unsigned int cmd, unsigned long arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) struct dw9800w_device *dev_vcm = sd_to_dw9800w_vcm(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) struct i2c_client *client = dev_vcm->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) void __user *up = compat_ptr(arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) struct rk_cam_compat_vcm_tim compat_vcm_tim;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) struct rk_cam_vcm_tim vcm_tim;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) struct rk_cam_vcm_cfg vcm_cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) long ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) if (cmd == RK_VIDIOC_COMPAT_VCM_TIMEINFO) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) struct rk_cam_compat_vcm_tim __user *p32 = up;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) ret = dw9800w_ioctl(sd, RK_VIDIOC_VCM_TIMEINFO, &vcm_tim);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) compat_vcm_tim.vcm_start_t.tv_sec = vcm_tim.vcm_start_t.tv_sec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) compat_vcm_tim.vcm_start_t.tv_usec = vcm_tim.vcm_start_t.tv_usec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) compat_vcm_tim.vcm_end_t.tv_sec = vcm_tim.vcm_end_t.tv_sec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) compat_vcm_tim.vcm_end_t.tv_usec = vcm_tim.vcm_end_t.tv_usec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) put_user(compat_vcm_tim.vcm_start_t.tv_sec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) &p32->vcm_start_t.tv_sec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) put_user(compat_vcm_tim.vcm_start_t.tv_usec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) &p32->vcm_start_t.tv_usec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) put_user(compat_vcm_tim.vcm_end_t.tv_sec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) &p32->vcm_end_t.tv_sec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) put_user(compat_vcm_tim.vcm_end_t.tv_usec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) &p32->vcm_end_t.tv_usec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) } else if (cmd == RK_VIDIOC_GET_VCM_CFG) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) ret = dw9800w_ioctl(sd, RK_VIDIOC_GET_VCM_CFG, &vcm_cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) if (!ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) ret = copy_to_user(up, &vcm_cfg, sizeof(vcm_cfg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) ret = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) } else if (cmd == RK_VIDIOC_SET_VCM_CFG) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) ret = copy_from_user(&vcm_cfg, up, sizeof(vcm_cfg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) ret = dw9800w_ioctl(sd, cmd, &vcm_cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) ret = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) dev_err(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) "cmd 0x%x not supported\n", cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) static const struct v4l2_subdev_core_ops dw9800w_core_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) .ioctl = dw9800w_ioctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) #ifdef CONFIG_COMPAT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) .compat_ioctl32 = dw9800w_compat_ioctl32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) static const struct v4l2_subdev_ops dw9800w_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) .core = &dw9800w_core_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) static void dw9800w_subdev_cleanup(struct dw9800w_device *dw9800w_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) v4l2_device_unregister_subdev(&dw9800w_dev->sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) v4l2_device_unregister(&dw9800w_dev->vdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) v4l2_ctrl_handler_free(&dw9800w_dev->ctrls_vcm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) media_entity_cleanup(&dw9800w_dev->sd.entity);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) static int dw9800w_init_controls(struct dw9800w_device *dev_vcm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) struct v4l2_ctrl_handler *hdl = &dev_vcm->ctrls_vcm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) const struct v4l2_ctrl_ops *ops = &dw9800w_vcm_ctrl_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) v4l2_ctrl_handler_init(hdl, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) v4l2_ctrl_new_std(hdl, ops, V4L2_CID_FOCUS_ABSOLUTE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) 0, VCMDRV_MAX_LOG, 1, 32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) if (hdl->error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) dev_err(dev_vcm->sd.dev, "%s fail error: 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) __func__, hdl->error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) dev_vcm->sd.ctrl_handler = hdl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) return hdl->error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) static int __dw9800w_set_power(struct dw9800w_device *dw9800w_dev, bool on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) if (dw9800w_dev->power_gpio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) gpiod_direction_output(dw9800w_dev->power_gpio, on);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) static int dw9800w_check_id(struct dw9800w_device *dw9800w_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) unsigned int pid = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) struct i2c_client *client = dw9800w_dev->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) struct device *dev = &client->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) __dw9800w_set_power(dw9800w_dev, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) ret = dw9800w_read_reg(client, DW9800W_REG_CHIP_ID, 1, &pid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) if (pid != DW9800W_CHIP_ID) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) dev_err(dev, "Unexpected sensor id(%06x), ret(%d)\n", pid, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) dev_info(&dw9800w_dev->client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) "Detected dw9800w vcm id:0x%x\n", DW9800W_CHIP_ID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) static int dw9800w_probe_init(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) /* Default goto power down mode when finished probe */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) ret = dw9800w_write_reg(client, 0x02, 1, 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) dev_err(&client->dev, "probe init failed with error %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) static int dw9800w_probe(struct i2c_client *client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) const struct i2c_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) struct device_node *np = of_node_get(client->dev.of_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) struct dw9800w_device *dw9800w_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) unsigned int max_ma, start_ma, rated_ma, step_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) unsigned int t_src, t_div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) struct v4l2_subdev *sd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) char facing[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) dev_info(&client->dev, "probing...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) if (of_property_read_u32(np,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) OF_CAMERA_VCMDRV_MAX_CURRENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) (unsigned int *)&max_ma)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) max_ma = DW9800W_MAX_CURRENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) dev_info(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) "could not get module %s from dts!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) OF_CAMERA_VCMDRV_MAX_CURRENT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) if (max_ma == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) max_ma = DW9800W_MAX_CURRENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) if (of_property_read_u32(np,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) OF_CAMERA_VCMDRV_START_CURRENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) (unsigned int *)&start_ma)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) start_ma = DW9800W_DEFAULT_START_CURRENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) dev_info(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) "could not get module %s from dts!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) OF_CAMERA_VCMDRV_START_CURRENT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) if (of_property_read_u32(np,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) OF_CAMERA_VCMDRV_RATED_CURRENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) (unsigned int *)&rated_ma)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) rated_ma = DW9800W_DEFAULT_RATED_CURRENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) dev_info(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) "could not get module %s from dts!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) OF_CAMERA_VCMDRV_RATED_CURRENT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) if (of_property_read_u32(np,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) OF_CAMERA_VCMDRV_STEP_MODE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) (unsigned int *)&step_mode)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) step_mode = DW9800W_DEFAULT_STEP_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) dev_info(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) "could not get module %s from dts!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) OF_CAMERA_VCMDRV_STEP_MODE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) if (of_property_read_u32(np,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) OF_CAMERA_VCMDRV_T_SRC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) (unsigned int *)&t_src)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) t_src = DW9800W_DEFAULT_T_SACT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) dev_info(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) "could not get module %s from dts!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) OF_CAMERA_VCMDRV_T_SRC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) if (of_property_read_u32(np,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) OF_CAMERA_VCMDRV_T_DIV,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) (unsigned int *)&t_div)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) t_div = DW9800W_DEFAULT_T_DIV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) dev_info(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) "could not get module %s from dts!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) OF_CAMERA_VCMDRV_T_DIV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) dw9800w_dev = devm_kzalloc(&client->dev, sizeof(*dw9800w_dev),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) if (dw9800w_dev == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) ret = of_property_read_u32(np, RKMODULE_CAMERA_MODULE_INDEX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) &dw9800w_dev->module_index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) ret |= of_property_read_string(np, RKMODULE_CAMERA_MODULE_FACING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) &dw9800w_dev->module_facing);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) dev_err(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) "could not get module information!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) dw9800w_dev->client = client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) dw9800w_dev->power_gpio = devm_gpiod_get(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) "power", GPIOD_OUT_LOW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) if (IS_ERR(dw9800w_dev->power_gpio)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) dw9800w_dev->power_gpio = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) dev_warn(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) "Failed to get power-gpios, maybe no use\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) ret = dw9800w_check_id(dw9800w_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) goto err_power_off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) /* enter power down mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) dw9800w_probe_init(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) v4l2_i2c_subdev_init(&dw9800w_dev->sd, client, &dw9800w_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) dw9800w_dev->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) dw9800w_dev->sd.internal_ops = &dw9800w_int_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) ret = dw9800w_init_controls(dw9800w_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) goto err_cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) ret = media_entity_pads_init(&dw9800w_dev->sd.entity, 0, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) goto err_cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) sd = &dw9800w_dev->sd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) sd->entity.function = MEDIA_ENT_F_LENS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) memset(facing, 0, sizeof(facing));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) if (strcmp(dw9800w_dev->module_facing, "back") == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) facing[0] = 'b';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) facing[0] = 'f';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) snprintf(sd->name, sizeof(sd->name), "m%02d_%s_%s %s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) dw9800w_dev->module_index, facing,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) DW9800W_NAME, dev_name(sd->dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) ret = v4l2_async_register_subdev(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) dev_err(&client->dev, "v4l2 async register subdev failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) dw9800w_dev->max_ma = max_ma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) dw9800w_dev->vcm_cfg.start_ma = start_ma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) dw9800w_dev->vcm_cfg.rated_ma = rated_ma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) dw9800w_dev->vcm_cfg.step_mode = step_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) dw9800w_update_vcm_cfg(dw9800w_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) dw9800w_dev->move_us = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) dw9800w_dev->current_related_pos = VCMDRV_MAX_LOG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) dw9800w_dev->start_move_tv = ns_to_kernel_old_timeval(ktime_get_ns());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) dw9800w_dev->end_move_tv = ns_to_kernel_old_timeval(ktime_get_ns());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) dw9800w_dev->t_src = t_src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) dw9800w_dev->t_div = t_div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) i2c_set_clientdata(client, dw9800w_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) mutex_init(&dw9800w_dev->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) dw9800w_dev->vcm_movefull_t =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) dw9800w_move_time(dw9800w_dev, DW9800W_MAX_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) pm_runtime_set_active(&client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) pm_runtime_enable(&client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) pm_runtime_idle(&client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) dev_info(&client->dev, "probing successful\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) err_cleanup:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) dw9800w_subdev_cleanup(dw9800w_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) err_power_off:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) __dw9800w_set_power(dw9800w_dev, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) dev_err(&client->dev, "Probe failed: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) static int dw9800w_remove(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) struct dw9800w_device *dw9800w_dev = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) mutex_destroy(&dw9800w_dev->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) pm_runtime_disable(&client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) dw9800w_subdev_cleanup(dw9800w_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) static int dw9800w_init(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) struct dw9800w_device *dev_vcm = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) u32 ring = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) u32 mode_val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) u32 algo_time = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) /* Delay 200us~300us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) usleep_range(200, 300);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) ret = dw9800w_write_reg(client, 0x02, 1, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) usleep_range(100, 200);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) if (dev_vcm->step_mode != DIRECT_MODE &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) dev_vcm->step_mode != LSC_MODE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) ring = 0x02;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) ret = dw9800w_write_reg(client, 0x02, 1, ring);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) switch (dev_vcm->step_mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) case SAC2_MODE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) case SAC3_MODE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) case SAC4_MODE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) case SAC5_MODE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) mode_val |= dev_vcm->step_mode << 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) case LSC_MODE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) mode_val |= 0x80;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) mode_val |= ((dev_vcm->t_div >> 2) & 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) algo_time = dev_vcm->t_div << 6 | dev_vcm->t_src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) ret = dw9800w_write_reg(client, 0x06, 1, mode_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) ret = dw9800w_write_reg(client, 0x07, 1, algo_time);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) usleep_range(100, 200);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) dev_err(&client->dev, "init failed with error %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) static int __maybe_unused dw9800w_vcm_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) struct i2c_client *client = to_i2c_client(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) /* set to power down mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) ret = dw9800w_write_reg(client, 0x02, 1, 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) dev_err(&client->dev, "failed to set power down mode!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) static int __maybe_unused dw9800w_vcm_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) struct i2c_client *client = to_i2c_client(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) struct dw9800w_device *dev_vcm = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) dw9800w_init(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) dw9800w_set_pos(dev_vcm, dev_vcm->current_related_pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) static const struct i2c_device_id dw9800w_id_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) { DW9800W_NAME, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) { { 0 } }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) MODULE_DEVICE_TABLE(i2c, dw9800w_id_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) static const struct of_device_id dw9800w_of_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) { .compatible = "dongwoon,dw9800w" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) { { 0 } }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) MODULE_DEVICE_TABLE(of, dw9800w_of_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) static const struct dev_pm_ops dw9800w_pm_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) SET_SYSTEM_SLEEP_PM_OPS(dw9800w_vcm_suspend, dw9800w_vcm_resume)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) SET_RUNTIME_PM_OPS(dw9800w_vcm_suspend, dw9800w_vcm_resume, NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) static struct i2c_driver dw9800w_i2c_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) .name = DW9800W_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) .pm = &dw9800w_pm_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) .of_match_table = dw9800w_of_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) .probe = &dw9800w_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) .remove = &dw9800w_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) .id_table = dw9800w_id_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) module_i2c_driver(dw9800w_i2c_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) MODULE_DESCRIPTION("DW9800W VCM driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) MODULE_LICENSE("GPL");