185989122SDongchun Zhu // SPDX-License-Identifier: GPL-2.0 285989122SDongchun Zhu // Copyright (c) 2020 MediaTek Inc. 385989122SDongchun Zhu 485989122SDongchun Zhu #include <linux/delay.h> 585989122SDongchun Zhu #include <linux/i2c.h> 685989122SDongchun Zhu #include <linux/module.h> 785989122SDongchun Zhu #include <linux/pm_runtime.h> 885989122SDongchun Zhu #include <linux/regulator/consumer.h> 985989122SDongchun Zhu #include <media/v4l2-async.h> 1085989122SDongchun Zhu #include <media/v4l2-ctrls.h> 1185989122SDongchun Zhu #include <media/v4l2-device.h> 1285989122SDongchun Zhu #include <media/v4l2-fwnode.h> 1385989122SDongchun Zhu #include <media/v4l2-subdev.h> 1485989122SDongchun Zhu 1585989122SDongchun Zhu #define DW9768_NAME "dw9768" 1685989122SDongchun Zhu #define DW9768_MAX_FOCUS_POS (1024 - 1) 1785989122SDongchun Zhu /* 1885989122SDongchun Zhu * This sets the minimum granularity for the focus positions. 1985989122SDongchun Zhu * A value of 1 gives maximum accuracy for a desired focus position 2085989122SDongchun Zhu */ 2185989122SDongchun Zhu #define DW9768_FOCUS_STEPS 1 2285989122SDongchun Zhu 2385989122SDongchun Zhu /* 2485989122SDongchun Zhu * Ring control and Power control register 2585989122SDongchun Zhu * Bit[1] RING_EN 2685989122SDongchun Zhu * 0: Direct mode 2785989122SDongchun Zhu * 1: AAC mode (ringing control mode) 2885989122SDongchun Zhu * Bit[0] PD 2985989122SDongchun Zhu * 0: Normal operation mode 3085989122SDongchun Zhu * 1: Power down mode 3185989122SDongchun Zhu * DW9768 requires waiting time of Topr after PD reset takes place. 3285989122SDongchun Zhu */ 3385989122SDongchun Zhu #define DW9768_RING_PD_CONTROL_REG 0x02 3485989122SDongchun Zhu #define DW9768_PD_MODE_OFF 0x00 3585989122SDongchun Zhu #define DW9768_PD_MODE_EN BIT(0) 3685989122SDongchun Zhu #define DW9768_AAC_MODE_EN BIT(1) 3785989122SDongchun Zhu 3885989122SDongchun Zhu /* 3985989122SDongchun Zhu * DW9768 separates two registers to control the VCM position. 4085989122SDongchun Zhu * One for MSB value, another is LSB value. 4185989122SDongchun Zhu * DAC_MSB: D[9:8] (ADD: 0x03) 4285989122SDongchun Zhu * DAC_LSB: D[7:0] (ADD: 0x04) 4385989122SDongchun Zhu * D[9:0] DAC data input: positive output current = D[9:0] / 1023 * 100[mA] 4485989122SDongchun Zhu */ 4585989122SDongchun Zhu #define DW9768_MSB_ADDR 0x03 4685989122SDongchun Zhu #define DW9768_LSB_ADDR 0x04 4785989122SDongchun Zhu #define DW9768_STATUS_ADDR 0x05 4885989122SDongchun Zhu 4985989122SDongchun Zhu /* 5085989122SDongchun Zhu * AAC mode control & prescale register 5185989122SDongchun Zhu * Bit[7:5] Namely AC[2:0], decide the VCM mode and operation time. 5285989122SDongchun Zhu * 001 AAC2 0.48 x Tvib 5385989122SDongchun Zhu * 010 AAC3 0.70 x Tvib 5485989122SDongchun Zhu * 011 AAC4 0.75 x Tvib 5585989122SDongchun Zhu * 101 AAC8 1.13 x Tvib 5685989122SDongchun Zhu * Bit[2:0] Namely PRESC[2:0], set the internal clock dividing rate as follow. 5785989122SDongchun Zhu * 000 2 5885989122SDongchun Zhu * 001 1 5985989122SDongchun Zhu * 010 1/2 6085989122SDongchun Zhu * 011 1/4 6185989122SDongchun Zhu * 100 8 6285989122SDongchun Zhu * 101 4 6385989122SDongchun Zhu */ 6485989122SDongchun Zhu #define DW9768_AAC_PRESC_REG 0x06 6585989122SDongchun Zhu #define DW9768_AAC_MODE_SEL_MASK GENMASK(7, 5) 6685989122SDongchun Zhu #define DW9768_CLOCK_PRE_SCALE_SEL_MASK GENMASK(2, 0) 6785989122SDongchun Zhu 6885989122SDongchun Zhu /* 6985989122SDongchun Zhu * VCM period of vibration register 7085989122SDongchun Zhu * Bit[5:0] Defined as VCM rising periodic time (Tvib) together with PRESC[2:0] 7185989122SDongchun Zhu * Tvib = (6.3ms + AACT[5:0] * 0.1ms) * Dividing Rate 7285989122SDongchun Zhu * Dividing Rate is the internal clock dividing rate that is defined at 7385989122SDongchun Zhu * PRESCALE register (ADD: 0x06) 7485989122SDongchun Zhu */ 7585989122SDongchun Zhu #define DW9768_AAC_TIME_REG 0x07 7685989122SDongchun Zhu 7785989122SDongchun Zhu /* 7885989122SDongchun Zhu * DW9768 requires waiting time (delay time) of t_OPR after power-up, 7985989122SDongchun Zhu * or in the case of PD reset taking place. 8085989122SDongchun Zhu */ 8185989122SDongchun Zhu #define DW9768_T_OPR_US 1000 8285989122SDongchun Zhu #define DW9768_TVIB_MS_BASE10 (64 - 1) 8385989122SDongchun Zhu #define DW9768_AAC_MODE_DEFAULT 2 8485989122SDongchun Zhu #define DW9768_AAC_TIME_DEFAULT 0x20 8585989122SDongchun Zhu #define DW9768_CLOCK_PRE_SCALE_DEFAULT 1 8685989122SDongchun Zhu 8785989122SDongchun Zhu /* 8885989122SDongchun Zhu * This acts as the minimum granularity of lens movement. 8985989122SDongchun Zhu * Keep this value power of 2, so the control steps can be 9085989122SDongchun Zhu * uniformly adjusted for gradual lens movement, with desired 9185989122SDongchun Zhu * number of control steps. 9285989122SDongchun Zhu */ 9385989122SDongchun Zhu #define DW9768_MOVE_STEPS 16 9485989122SDongchun Zhu 9585989122SDongchun Zhu static const char * const dw9768_supply_names[] = { 9685989122SDongchun Zhu "vin", /* Digital I/O power */ 9785989122SDongchun Zhu "vdd", /* Digital core power */ 9885989122SDongchun Zhu }; 9985989122SDongchun Zhu 10085989122SDongchun Zhu /* dw9768 device structure */ 10185989122SDongchun Zhu struct dw9768 { 10285989122SDongchun Zhu struct regulator_bulk_data supplies[ARRAY_SIZE(dw9768_supply_names)]; 10385989122SDongchun Zhu struct v4l2_ctrl_handler ctrls; 10485989122SDongchun Zhu struct v4l2_ctrl *focus; 10585989122SDongchun Zhu struct v4l2_subdev sd; 10685989122SDongchun Zhu 10785989122SDongchun Zhu u32 aac_mode; 10885989122SDongchun Zhu u32 aac_timing; 10985989122SDongchun Zhu u32 clock_presc; 11085989122SDongchun Zhu u32 move_delay_us; 11185989122SDongchun Zhu }; 11285989122SDongchun Zhu 11385989122SDongchun Zhu static inline struct dw9768 *sd_to_dw9768(struct v4l2_subdev *subdev) 11485989122SDongchun Zhu { 11585989122SDongchun Zhu return container_of(subdev, struct dw9768, sd); 11685989122SDongchun Zhu } 11785989122SDongchun Zhu 11885989122SDongchun Zhu struct regval_list { 11985989122SDongchun Zhu u8 reg_num; 12085989122SDongchun Zhu u8 value; 12185989122SDongchun Zhu }; 12285989122SDongchun Zhu 12385989122SDongchun Zhu struct dw9768_aac_mode_ot_multi { 12485989122SDongchun Zhu u32 aac_mode_enum; 12585989122SDongchun Zhu u32 ot_multi_base100; 12685989122SDongchun Zhu }; 12785989122SDongchun Zhu 12885989122SDongchun Zhu struct dw9768_clk_presc_dividing_rate { 12985989122SDongchun Zhu u32 clk_presc_enum; 13085989122SDongchun Zhu u32 dividing_rate_base100; 13185989122SDongchun Zhu }; 13285989122SDongchun Zhu 13385989122SDongchun Zhu static const struct dw9768_aac_mode_ot_multi aac_mode_ot_multi[] = { 13485989122SDongchun Zhu {1, 48}, 13585989122SDongchun Zhu {2, 70}, 13685989122SDongchun Zhu {3, 75}, 13785989122SDongchun Zhu {5, 113}, 13885989122SDongchun Zhu }; 13985989122SDongchun Zhu 14085989122SDongchun Zhu static const struct dw9768_clk_presc_dividing_rate presc_dividing_rate[] = { 14185989122SDongchun Zhu {0, 200}, 14285989122SDongchun Zhu {1, 100}, 14385989122SDongchun Zhu {2, 50}, 14485989122SDongchun Zhu {3, 25}, 14585989122SDongchun Zhu {4, 800}, 14685989122SDongchun Zhu {5, 400}, 14785989122SDongchun Zhu }; 14885989122SDongchun Zhu 14985989122SDongchun Zhu static u32 dw9768_find_ot_multi(u32 aac_mode_param) 15085989122SDongchun Zhu { 15185989122SDongchun Zhu u32 cur_ot_multi_base100 = 70; 15285989122SDongchun Zhu unsigned int i; 15385989122SDongchun Zhu 15485989122SDongchun Zhu for (i = 0; i < ARRAY_SIZE(aac_mode_ot_multi); i++) { 15585989122SDongchun Zhu if (aac_mode_ot_multi[i].aac_mode_enum == aac_mode_param) { 15685989122SDongchun Zhu cur_ot_multi_base100 = 15785989122SDongchun Zhu aac_mode_ot_multi[i].ot_multi_base100; 15885989122SDongchun Zhu } 15985989122SDongchun Zhu } 16085989122SDongchun Zhu 16185989122SDongchun Zhu return cur_ot_multi_base100; 16285989122SDongchun Zhu } 16385989122SDongchun Zhu 16485989122SDongchun Zhu static u32 dw9768_find_dividing_rate(u32 presc_param) 16585989122SDongchun Zhu { 16685989122SDongchun Zhu u32 cur_clk_dividing_rate_base100 = 100; 16785989122SDongchun Zhu unsigned int i; 16885989122SDongchun Zhu 16985989122SDongchun Zhu for (i = 0; i < ARRAY_SIZE(presc_dividing_rate); i++) { 17085989122SDongchun Zhu if (presc_dividing_rate[i].clk_presc_enum == presc_param) { 17185989122SDongchun Zhu cur_clk_dividing_rate_base100 = 17285989122SDongchun Zhu presc_dividing_rate[i].dividing_rate_base100; 17385989122SDongchun Zhu } 17485989122SDongchun Zhu } 17585989122SDongchun Zhu 17685989122SDongchun Zhu return cur_clk_dividing_rate_base100; 17785989122SDongchun Zhu } 17885989122SDongchun Zhu 17985989122SDongchun Zhu /* 18085989122SDongchun Zhu * DW9768_AAC_PRESC_REG & DW9768_AAC_TIME_REG determine VCM operation time. 18185989122SDongchun Zhu * For current VCM mode: AAC3, Operation Time would be 0.70 x Tvib. 18285989122SDongchun Zhu * Tvib = (6.3ms + AACT[5:0] * 0.1MS) * Dividing Rate. 18385989122SDongchun Zhu * Below is calculation of the operation delay for each step. 18485989122SDongchun Zhu */ 18585989122SDongchun Zhu static inline u32 dw9768_cal_move_delay(u32 aac_mode_param, u32 presc_param, 18685989122SDongchun Zhu u32 aac_timing_param) 18785989122SDongchun Zhu { 18885989122SDongchun Zhu u32 Tvib_us; 18985989122SDongchun Zhu u32 ot_multi_base100; 19085989122SDongchun Zhu u32 clk_dividing_rate_base100; 19185989122SDongchun Zhu 19285989122SDongchun Zhu ot_multi_base100 = dw9768_find_ot_multi(aac_mode_param); 19385989122SDongchun Zhu 19485989122SDongchun Zhu clk_dividing_rate_base100 = dw9768_find_dividing_rate(presc_param); 19585989122SDongchun Zhu 19685989122SDongchun Zhu Tvib_us = (DW9768_TVIB_MS_BASE10 + aac_timing_param) * 19785989122SDongchun Zhu clk_dividing_rate_base100; 19885989122SDongchun Zhu 19985989122SDongchun Zhu return Tvib_us * ot_multi_base100 / 100; 20085989122SDongchun Zhu } 20185989122SDongchun Zhu 20285989122SDongchun Zhu static int dw9768_mod_reg(struct dw9768 *dw9768, u8 reg, u8 mask, u8 val) 20385989122SDongchun Zhu { 20485989122SDongchun Zhu struct i2c_client *client = v4l2_get_subdevdata(&dw9768->sd); 20585989122SDongchun Zhu int ret; 20685989122SDongchun Zhu 20785989122SDongchun Zhu ret = i2c_smbus_read_byte_data(client, reg); 20885989122SDongchun Zhu if (ret < 0) 20985989122SDongchun Zhu return ret; 21085989122SDongchun Zhu 21185989122SDongchun Zhu val = ((unsigned char)ret & ~mask) | (val & mask); 21285989122SDongchun Zhu 21385989122SDongchun Zhu return i2c_smbus_write_byte_data(client, reg, val); 21485989122SDongchun Zhu } 21585989122SDongchun Zhu 21685989122SDongchun Zhu static int dw9768_set_dac(struct dw9768 *dw9768, u16 val) 21785989122SDongchun Zhu { 21885989122SDongchun Zhu struct i2c_client *client = v4l2_get_subdevdata(&dw9768->sd); 21985989122SDongchun Zhu 22085989122SDongchun Zhu /* Write VCM position to registers */ 22185989122SDongchun Zhu return i2c_smbus_write_word_swapped(client, DW9768_MSB_ADDR, val); 22285989122SDongchun Zhu } 22385989122SDongchun Zhu 22485989122SDongchun Zhu static int dw9768_init(struct dw9768 *dw9768) 22585989122SDongchun Zhu { 22685989122SDongchun Zhu struct i2c_client *client = v4l2_get_subdevdata(&dw9768->sd); 22785989122SDongchun Zhu int ret, val; 22885989122SDongchun Zhu 22985989122SDongchun Zhu /* Reset DW9768_RING_PD_CONTROL_REG to default status 0x00 */ 23085989122SDongchun Zhu ret = i2c_smbus_write_byte_data(client, DW9768_RING_PD_CONTROL_REG, 23185989122SDongchun Zhu DW9768_PD_MODE_OFF); 23285989122SDongchun Zhu if (ret < 0) 23385989122SDongchun Zhu return ret; 23485989122SDongchun Zhu 23585989122SDongchun Zhu /* 23685989122SDongchun Zhu * DW9769 requires waiting delay time of t_OPR 23785989122SDongchun Zhu * after PD reset takes place. 23885989122SDongchun Zhu */ 23985989122SDongchun Zhu usleep_range(DW9768_T_OPR_US, DW9768_T_OPR_US + 100); 24085989122SDongchun Zhu 24185989122SDongchun Zhu /* Set DW9768_RING_PD_CONTROL_REG to DW9768_AAC_MODE_EN(0x01) */ 24285989122SDongchun Zhu ret = i2c_smbus_write_byte_data(client, DW9768_RING_PD_CONTROL_REG, 24385989122SDongchun Zhu DW9768_AAC_MODE_EN); 24485989122SDongchun Zhu if (ret < 0) 24585989122SDongchun Zhu return ret; 24685989122SDongchun Zhu 24785989122SDongchun Zhu /* Set AAC mode */ 24885989122SDongchun Zhu ret = dw9768_mod_reg(dw9768, DW9768_AAC_PRESC_REG, 24985989122SDongchun Zhu DW9768_AAC_MODE_SEL_MASK, 25085989122SDongchun Zhu dw9768->aac_mode << 5); 25185989122SDongchun Zhu if (ret < 0) 25285989122SDongchun Zhu return ret; 25385989122SDongchun Zhu 25485989122SDongchun Zhu /* Set clock presc */ 25585989122SDongchun Zhu if (dw9768->clock_presc != DW9768_CLOCK_PRE_SCALE_DEFAULT) { 25685989122SDongchun Zhu ret = dw9768_mod_reg(dw9768, DW9768_AAC_PRESC_REG, 25785989122SDongchun Zhu DW9768_CLOCK_PRE_SCALE_SEL_MASK, 25885989122SDongchun Zhu dw9768->clock_presc); 25985989122SDongchun Zhu if (ret < 0) 26085989122SDongchun Zhu return ret; 26185989122SDongchun Zhu } 26285989122SDongchun Zhu 26385989122SDongchun Zhu /* Set AAC Timing */ 26485989122SDongchun Zhu if (dw9768->aac_timing != DW9768_AAC_TIME_DEFAULT) { 26585989122SDongchun Zhu ret = i2c_smbus_write_byte_data(client, DW9768_AAC_TIME_REG, 26685989122SDongchun Zhu dw9768->aac_timing); 26785989122SDongchun Zhu if (ret < 0) 26885989122SDongchun Zhu return ret; 26985989122SDongchun Zhu } 27085989122SDongchun Zhu 27185989122SDongchun Zhu for (val = dw9768->focus->val % DW9768_MOVE_STEPS; 27285989122SDongchun Zhu val <= dw9768->focus->val; 27385989122SDongchun Zhu val += DW9768_MOVE_STEPS) { 27485989122SDongchun Zhu ret = dw9768_set_dac(dw9768, val); 27585989122SDongchun Zhu if (ret) { 27685989122SDongchun Zhu dev_err(&client->dev, "I2C failure: %d", ret); 27785989122SDongchun Zhu return ret; 27885989122SDongchun Zhu } 27985989122SDongchun Zhu usleep_range(dw9768->move_delay_us, 28085989122SDongchun Zhu dw9768->move_delay_us + 1000); 28185989122SDongchun Zhu } 28285989122SDongchun Zhu 28385989122SDongchun Zhu return 0; 28485989122SDongchun Zhu } 28585989122SDongchun Zhu 28685989122SDongchun Zhu static int dw9768_release(struct dw9768 *dw9768) 28785989122SDongchun Zhu { 28885989122SDongchun Zhu struct i2c_client *client = v4l2_get_subdevdata(&dw9768->sd); 28985989122SDongchun Zhu int ret, val; 29085989122SDongchun Zhu 29185989122SDongchun Zhu val = round_down(dw9768->focus->val, DW9768_MOVE_STEPS); 29285989122SDongchun Zhu for ( ; val >= 0; val -= DW9768_MOVE_STEPS) { 29385989122SDongchun Zhu ret = dw9768_set_dac(dw9768, val); 29485989122SDongchun Zhu if (ret) { 29585989122SDongchun Zhu dev_err(&client->dev, "I2C write fail: %d", ret); 29685989122SDongchun Zhu return ret; 29785989122SDongchun Zhu } 29885989122SDongchun Zhu usleep_range(dw9768->move_delay_us, 29985989122SDongchun Zhu dw9768->move_delay_us + 1000); 30085989122SDongchun Zhu } 30185989122SDongchun Zhu 30285989122SDongchun Zhu ret = i2c_smbus_write_byte_data(client, DW9768_RING_PD_CONTROL_REG, 30385989122SDongchun Zhu DW9768_PD_MODE_EN); 30485989122SDongchun Zhu if (ret < 0) 30585989122SDongchun Zhu return ret; 30685989122SDongchun Zhu 30785989122SDongchun Zhu /* 30885989122SDongchun Zhu * DW9769 requires waiting delay time of t_OPR 30985989122SDongchun Zhu * after PD reset takes place. 31085989122SDongchun Zhu */ 31185989122SDongchun Zhu usleep_range(DW9768_T_OPR_US, DW9768_T_OPR_US + 100); 31285989122SDongchun Zhu 31385989122SDongchun Zhu return 0; 31485989122SDongchun Zhu } 31585989122SDongchun Zhu 31685989122SDongchun Zhu static int dw9768_runtime_suspend(struct device *dev) 31785989122SDongchun Zhu { 31885989122SDongchun Zhu struct i2c_client *client = to_i2c_client(dev); 31985989122SDongchun Zhu struct v4l2_subdev *sd = i2c_get_clientdata(client); 32085989122SDongchun Zhu struct dw9768 *dw9768 = sd_to_dw9768(sd); 32185989122SDongchun Zhu 32285989122SDongchun Zhu dw9768_release(dw9768); 32385989122SDongchun Zhu regulator_bulk_disable(ARRAY_SIZE(dw9768_supply_names), 32485989122SDongchun Zhu dw9768->supplies); 32585989122SDongchun Zhu 32685989122SDongchun Zhu return 0; 32785989122SDongchun Zhu } 32885989122SDongchun Zhu 32985989122SDongchun Zhu static int dw9768_runtime_resume(struct device *dev) 33085989122SDongchun Zhu { 33185989122SDongchun Zhu struct i2c_client *client = to_i2c_client(dev); 33285989122SDongchun Zhu struct v4l2_subdev *sd = i2c_get_clientdata(client); 33385989122SDongchun Zhu struct dw9768 *dw9768 = sd_to_dw9768(sd); 33485989122SDongchun Zhu int ret; 33585989122SDongchun Zhu 33685989122SDongchun Zhu ret = regulator_bulk_enable(ARRAY_SIZE(dw9768_supply_names), 33785989122SDongchun Zhu dw9768->supplies); 33885989122SDongchun Zhu if (ret < 0) { 33985989122SDongchun Zhu dev_err(dev, "failed to enable regulators\n"); 34085989122SDongchun Zhu return ret; 34185989122SDongchun Zhu } 34285989122SDongchun Zhu 34385989122SDongchun Zhu /* 34485989122SDongchun Zhu * The datasheet refers to t_OPR that needs to be waited before sending 34585989122SDongchun Zhu * I2C commands after power-up. 34685989122SDongchun Zhu */ 34785989122SDongchun Zhu usleep_range(DW9768_T_OPR_US, DW9768_T_OPR_US + 100); 34885989122SDongchun Zhu 34985989122SDongchun Zhu ret = dw9768_init(dw9768); 35085989122SDongchun Zhu if (ret < 0) 35185989122SDongchun Zhu goto disable_regulator; 35285989122SDongchun Zhu 35385989122SDongchun Zhu return 0; 35485989122SDongchun Zhu 35585989122SDongchun Zhu disable_regulator: 35685989122SDongchun Zhu regulator_bulk_disable(ARRAY_SIZE(dw9768_supply_names), 35785989122SDongchun Zhu dw9768->supplies); 35885989122SDongchun Zhu 35985989122SDongchun Zhu return ret; 36085989122SDongchun Zhu } 36185989122SDongchun Zhu 36285989122SDongchun Zhu static int dw9768_set_ctrl(struct v4l2_ctrl *ctrl) 36385989122SDongchun Zhu { 36485989122SDongchun Zhu struct dw9768 *dw9768 = container_of(ctrl->handler, 36585989122SDongchun Zhu struct dw9768, ctrls); 36685989122SDongchun Zhu 36785989122SDongchun Zhu if (ctrl->id == V4L2_CID_FOCUS_ABSOLUTE) 36885989122SDongchun Zhu return dw9768_set_dac(dw9768, ctrl->val); 36985989122SDongchun Zhu 37085989122SDongchun Zhu return 0; 37185989122SDongchun Zhu } 37285989122SDongchun Zhu 37385989122SDongchun Zhu static const struct v4l2_ctrl_ops dw9768_ctrl_ops = { 37485989122SDongchun Zhu .s_ctrl = dw9768_set_ctrl, 37585989122SDongchun Zhu }; 37685989122SDongchun Zhu 37785989122SDongchun Zhu static int dw9768_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) 37885989122SDongchun Zhu { 37985989122SDongchun Zhu int ret; 38085989122SDongchun Zhu 38185989122SDongchun Zhu ret = pm_runtime_get_sync(sd->dev); 38285989122SDongchun Zhu if (ret < 0) { 38385989122SDongchun Zhu pm_runtime_put_noidle(sd->dev); 38485989122SDongchun Zhu return ret; 38585989122SDongchun Zhu } 38685989122SDongchun Zhu 38785989122SDongchun Zhu return 0; 38885989122SDongchun Zhu } 38985989122SDongchun Zhu 39085989122SDongchun Zhu static int dw9768_close(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) 39185989122SDongchun Zhu { 39285989122SDongchun Zhu pm_runtime_put(sd->dev); 39385989122SDongchun Zhu 39485989122SDongchun Zhu return 0; 39585989122SDongchun Zhu } 39685989122SDongchun Zhu 39785989122SDongchun Zhu static const struct v4l2_subdev_internal_ops dw9768_int_ops = { 39885989122SDongchun Zhu .open = dw9768_open, 39985989122SDongchun Zhu .close = dw9768_close, 40085989122SDongchun Zhu }; 40185989122SDongchun Zhu 40285989122SDongchun Zhu static const struct v4l2_subdev_ops dw9768_ops = { }; 40385989122SDongchun Zhu 40485989122SDongchun Zhu static int dw9768_init_controls(struct dw9768 *dw9768) 40585989122SDongchun Zhu { 40685989122SDongchun Zhu struct v4l2_ctrl_handler *hdl = &dw9768->ctrls; 40785989122SDongchun Zhu const struct v4l2_ctrl_ops *ops = &dw9768_ctrl_ops; 40885989122SDongchun Zhu 40985989122SDongchun Zhu v4l2_ctrl_handler_init(hdl, 1); 41085989122SDongchun Zhu 41185989122SDongchun Zhu dw9768->focus = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_FOCUS_ABSOLUTE, 0, 41285989122SDongchun Zhu DW9768_MAX_FOCUS_POS, 41385989122SDongchun Zhu DW9768_FOCUS_STEPS, 0); 41485989122SDongchun Zhu 41585989122SDongchun Zhu if (hdl->error) 41685989122SDongchun Zhu return hdl->error; 41785989122SDongchun Zhu 41885989122SDongchun Zhu dw9768->sd.ctrl_handler = hdl; 41985989122SDongchun Zhu 42085989122SDongchun Zhu return 0; 42185989122SDongchun Zhu } 42285989122SDongchun Zhu 42385989122SDongchun Zhu static int dw9768_probe(struct i2c_client *client) 42485989122SDongchun Zhu { 42585989122SDongchun Zhu struct device *dev = &client->dev; 42685989122SDongchun Zhu struct dw9768 *dw9768; 42785989122SDongchun Zhu unsigned int i; 42885989122SDongchun Zhu int ret; 42985989122SDongchun Zhu 43085989122SDongchun Zhu dw9768 = devm_kzalloc(dev, sizeof(*dw9768), GFP_KERNEL); 43185989122SDongchun Zhu if (!dw9768) 43285989122SDongchun Zhu return -ENOMEM; 43385989122SDongchun Zhu 43485989122SDongchun Zhu /* Initialize subdev */ 43585989122SDongchun Zhu v4l2_i2c_subdev_init(&dw9768->sd, client, &dw9768_ops); 43685989122SDongchun Zhu 43785989122SDongchun Zhu dw9768->aac_mode = DW9768_AAC_MODE_DEFAULT; 43885989122SDongchun Zhu dw9768->aac_timing = DW9768_AAC_TIME_DEFAULT; 43985989122SDongchun Zhu dw9768->clock_presc = DW9768_CLOCK_PRE_SCALE_DEFAULT; 44085989122SDongchun Zhu 44185989122SDongchun Zhu /* Optional indication of AAC mode select */ 44285989122SDongchun Zhu fwnode_property_read_u32(dev_fwnode(dev), "dongwoon,aac-mode", 44385989122SDongchun Zhu &dw9768->aac_mode); 44485989122SDongchun Zhu 44585989122SDongchun Zhu /* Optional indication of clock pre-scale select */ 44685989122SDongchun Zhu fwnode_property_read_u32(dev_fwnode(dev), "dongwoon,clock-presc", 44785989122SDongchun Zhu &dw9768->clock_presc); 44885989122SDongchun Zhu 44985989122SDongchun Zhu /* Optional indication of AAC Timing */ 45085989122SDongchun Zhu fwnode_property_read_u32(dev_fwnode(dev), "dongwoon,aac-timing", 45185989122SDongchun Zhu &dw9768->aac_timing); 45285989122SDongchun Zhu 45385989122SDongchun Zhu dw9768->move_delay_us = dw9768_cal_move_delay(dw9768->aac_mode, 45485989122SDongchun Zhu dw9768->clock_presc, 45585989122SDongchun Zhu dw9768->aac_timing); 45685989122SDongchun Zhu 45785989122SDongchun Zhu for (i = 0; i < ARRAY_SIZE(dw9768_supply_names); i++) 45885989122SDongchun Zhu dw9768->supplies[i].supply = dw9768_supply_names[i]; 45985989122SDongchun Zhu 46085989122SDongchun Zhu ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(dw9768_supply_names), 46185989122SDongchun Zhu dw9768->supplies); 46285989122SDongchun Zhu if (ret) { 46385989122SDongchun Zhu dev_err(dev, "failed to get regulators\n"); 46485989122SDongchun Zhu return ret; 46585989122SDongchun Zhu } 46685989122SDongchun Zhu 46785989122SDongchun Zhu /* Initialize controls */ 46885989122SDongchun Zhu ret = dw9768_init_controls(dw9768); 46985989122SDongchun Zhu if (ret) 47085989122SDongchun Zhu goto err_free_handler; 47185989122SDongchun Zhu 47285989122SDongchun Zhu /* Initialize subdev */ 47385989122SDongchun Zhu dw9768->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; 47485989122SDongchun Zhu dw9768->sd.internal_ops = &dw9768_int_ops; 47585989122SDongchun Zhu 47685989122SDongchun Zhu ret = media_entity_pads_init(&dw9768->sd.entity, 0, NULL); 47785989122SDongchun Zhu if (ret < 0) 47885989122SDongchun Zhu goto err_free_handler; 47985989122SDongchun Zhu 48085989122SDongchun Zhu dw9768->sd.entity.function = MEDIA_ENT_F_LENS; 48185989122SDongchun Zhu 48285989122SDongchun Zhu pm_runtime_enable(dev); 48385989122SDongchun Zhu if (!pm_runtime_enabled(dev)) { 48485989122SDongchun Zhu ret = dw9768_runtime_resume(dev); 48585989122SDongchun Zhu if (ret < 0) { 48685989122SDongchun Zhu dev_err(dev, "failed to power on: %d\n", ret); 48785989122SDongchun Zhu goto err_clean_entity; 48885989122SDongchun Zhu } 48985989122SDongchun Zhu } 49085989122SDongchun Zhu 49185989122SDongchun Zhu ret = v4l2_async_register_subdev(&dw9768->sd); 49285989122SDongchun Zhu if (ret < 0) { 49385989122SDongchun Zhu dev_err(dev, "failed to register V4L2 subdev: %d", ret); 49485989122SDongchun Zhu goto err_power_off; 49585989122SDongchun Zhu } 49685989122SDongchun Zhu 49785989122SDongchun Zhu return 0; 49885989122SDongchun Zhu 49985989122SDongchun Zhu err_power_off: 50085989122SDongchun Zhu if (pm_runtime_enabled(dev)) 50185989122SDongchun Zhu pm_runtime_disable(dev); 50285989122SDongchun Zhu else 50385989122SDongchun Zhu dw9768_runtime_suspend(dev); 50485989122SDongchun Zhu err_clean_entity: 50585989122SDongchun Zhu media_entity_cleanup(&dw9768->sd.entity); 50685989122SDongchun Zhu err_free_handler: 50785989122SDongchun Zhu v4l2_ctrl_handler_free(&dw9768->ctrls); 50885989122SDongchun Zhu 50985989122SDongchun Zhu return ret; 51085989122SDongchun Zhu } 51185989122SDongchun Zhu 51285989122SDongchun Zhu static int dw9768_remove(struct i2c_client *client) 51385989122SDongchun Zhu { 51485989122SDongchun Zhu struct v4l2_subdev *sd = i2c_get_clientdata(client); 51585989122SDongchun Zhu struct dw9768 *dw9768 = sd_to_dw9768(sd); 51685989122SDongchun Zhu 51785989122SDongchun Zhu v4l2_async_unregister_subdev(&dw9768->sd); 51885989122SDongchun Zhu v4l2_ctrl_handler_free(&dw9768->ctrls); 51985989122SDongchun Zhu media_entity_cleanup(&dw9768->sd.entity); 52085989122SDongchun Zhu pm_runtime_disable(&client->dev); 52185989122SDongchun Zhu if (!pm_runtime_status_suspended(&client->dev)) 52285989122SDongchun Zhu dw9768_runtime_suspend(&client->dev); 52385989122SDongchun Zhu pm_runtime_set_suspended(&client->dev); 52485989122SDongchun Zhu 52585989122SDongchun Zhu return 0; 52685989122SDongchun Zhu } 52785989122SDongchun Zhu 52885989122SDongchun Zhu static const struct of_device_id dw9768_of_table[] = { 52985989122SDongchun Zhu { .compatible = "dongwoon,dw9768" }, 53085989122SDongchun Zhu { .compatible = "giantec,gt9769" }, 53185989122SDongchun Zhu {} 53285989122SDongchun Zhu }; 53385989122SDongchun Zhu MODULE_DEVICE_TABLE(of, dw9768_of_table); 53485989122SDongchun Zhu 53585989122SDongchun Zhu static const struct dev_pm_ops dw9768_pm_ops = { 53685989122SDongchun Zhu SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, 53785989122SDongchun Zhu pm_runtime_force_resume) 53885989122SDongchun Zhu SET_RUNTIME_PM_OPS(dw9768_runtime_suspend, dw9768_runtime_resume, NULL) 53985989122SDongchun Zhu }; 54085989122SDongchun Zhu 54185989122SDongchun Zhu static struct i2c_driver dw9768_i2c_driver = { 54285989122SDongchun Zhu .driver = { 54385989122SDongchun Zhu .name = DW9768_NAME, 54485989122SDongchun Zhu .pm = &dw9768_pm_ops, 54585989122SDongchun Zhu .of_match_table = dw9768_of_table, 54685989122SDongchun Zhu }, 54785989122SDongchun Zhu .probe_new = dw9768_probe, 54885989122SDongchun Zhu .remove = dw9768_remove, 54985989122SDongchun Zhu }; 55085989122SDongchun Zhu module_i2c_driver(dw9768_i2c_driver); 55185989122SDongchun Zhu 55285989122SDongchun Zhu MODULE_AUTHOR("Dongchun Zhu <dongchun.zhu@mediatek.com>"); 55385989122SDongchun Zhu MODULE_DESCRIPTION("DW9768 VCM driver"); 55485989122SDongchun Zhu MODULE_LICENSE("GPL v2"); 555