1 // SPDX-License-Identifier: GPL-2.0
2 // Copyright (C) 2018 Intel Corporation
4 #include <linux/acpi.h>
5 #include <linux/delay.h>
7 #include <linux/module.h>
8 #include <linux/pm_runtime.h>
9 #include <linux/regulator/consumer.h>
10 #include <media/v4l2-ctrls.h>
11 #include <media/v4l2-device.h>
13 struct ak73xx_chipdef
{
19 bool has_standby
; /* Some chips may not have standby mode */
22 * This sets the minimum granularity for the focus positions.
23 * A value of 1 gives maximum accuracy for a desired focus position
27 * This acts as the minimum granularity of lens movement.
28 * Keep this value power of 2, so the control steps can be
29 * uniformly adjusted for gradual lens movement, with desired
30 * number of control steps.
35 * The vcm may take time (tDELAY) to power on and start taking
41 static const struct ak73xx_chipdef ak7345_cdef
= {
44 .shift_pos
= 7, /* 9 bits position values, need to << 7 */
50 .ctrl_delay_us
= 1000,
51 .power_delay_us
= 20000,
54 static const struct ak73xx_chipdef ak7375_cdef
= {
57 .shift_pos
= 4, /* 12 bits position values, need to << 4 */
61 .focus_pos_max
= 4095,
64 .ctrl_delay_us
= 1000,
65 .power_delay_us
= 10000,
68 static const char * const ak7375_supply_names
[] = {
73 /* ak7375 device structure */
74 struct ak7375_device
{
75 const struct ak73xx_chipdef
*cdef
;
76 struct v4l2_ctrl_handler ctrls_vcm
;
77 struct v4l2_subdev sd
;
78 struct v4l2_ctrl
*focus
;
79 struct regulator_bulk_data supplies
[ARRAY_SIZE(ak7375_supply_names
)];
81 /* active or standby mode */
85 static inline struct ak7375_device
*to_ak7375_vcm(struct v4l2_ctrl
*ctrl
)
87 return container_of(ctrl
->handler
, struct ak7375_device
, ctrls_vcm
);
90 static inline struct ak7375_device
*sd_to_ak7375_vcm(struct v4l2_subdev
*subdev
)
92 return container_of(subdev
, struct ak7375_device
, sd
);
95 static int ak7375_i2c_write(struct ak7375_device
*ak7375
,
96 u8 addr
, u16 data
, u8 size
)
98 struct i2c_client
*client
= v4l2_get_subdevdata(&ak7375
->sd
);
102 if (size
!= 1 && size
!= 2)
105 buf
[size
] = data
& 0xff;
107 buf
[1] = (data
>> 8) & 0xff;
108 ret
= i2c_master_send(client
, (const char *)buf
, size
+ 1);
117 static int ak7375_set_ctrl(struct v4l2_ctrl
*ctrl
)
119 struct ak7375_device
*dev_vcm
= to_ak7375_vcm(ctrl
);
120 const struct ak73xx_chipdef
*cdef
= dev_vcm
->cdef
;
122 if (ctrl
->id
== V4L2_CID_FOCUS_ABSOLUTE
)
123 return ak7375_i2c_write(dev_vcm
, cdef
->reg_position
,
124 ctrl
->val
<< cdef
->shift_pos
, 2);
129 static const struct v4l2_ctrl_ops ak7375_vcm_ctrl_ops
= {
130 .s_ctrl
= ak7375_set_ctrl
,
133 static int ak7375_open(struct v4l2_subdev
*sd
, struct v4l2_subdev_fh
*fh
)
135 return pm_runtime_resume_and_get(sd
->dev
);
138 static int ak7375_close(struct v4l2_subdev
*sd
, struct v4l2_subdev_fh
*fh
)
140 pm_runtime_put(sd
->dev
);
145 static const struct v4l2_subdev_internal_ops ak7375_int_ops
= {
147 .close
= ak7375_close
,
150 static const struct v4l2_subdev_ops ak7375_ops
= { };
152 static void ak7375_subdev_cleanup(struct ak7375_device
*ak7375_dev
)
154 v4l2_async_unregister_subdev(&ak7375_dev
->sd
);
155 v4l2_ctrl_handler_free(&ak7375_dev
->ctrls_vcm
);
156 media_entity_cleanup(&ak7375_dev
->sd
.entity
);
159 static int ak7375_init_controls(struct ak7375_device
*dev_vcm
)
161 struct v4l2_ctrl_handler
*hdl
= &dev_vcm
->ctrls_vcm
;
162 const struct v4l2_ctrl_ops
*ops
= &ak7375_vcm_ctrl_ops
;
163 const struct ak73xx_chipdef
*cdef
= dev_vcm
->cdef
;
165 v4l2_ctrl_handler_init(hdl
, 1);
167 dev_vcm
->focus
= v4l2_ctrl_new_std(hdl
, ops
, V4L2_CID_FOCUS_ABSOLUTE
,
168 0, cdef
->focus_pos_max
, cdef
->focus_steps
, 0);
171 dev_err(dev_vcm
->sd
.dev
, "%s fail error: 0x%x\n",
172 __func__
, hdl
->error
);
173 dev_vcm
->sd
.ctrl_handler
= hdl
;
178 static int ak7375_probe(struct i2c_client
*client
)
180 struct ak7375_device
*ak7375_dev
;
184 ak7375_dev
= devm_kzalloc(&client
->dev
, sizeof(*ak7375_dev
),
189 ak7375_dev
->cdef
= device_get_match_data(&client
->dev
);
191 for (i
= 0; i
< ARRAY_SIZE(ak7375_supply_names
); i
++)
192 ak7375_dev
->supplies
[i
].supply
= ak7375_supply_names
[i
];
194 ret
= devm_regulator_bulk_get(&client
->dev
,
195 ARRAY_SIZE(ak7375_supply_names
),
196 ak7375_dev
->supplies
);
198 dev_err_probe(&client
->dev
, ret
, "Failed to get regulators\n");
202 v4l2_i2c_subdev_init(&ak7375_dev
->sd
, client
, &ak7375_ops
);
203 ak7375_dev
->sd
.flags
|= V4L2_SUBDEV_FL_HAS_DEVNODE
;
204 ak7375_dev
->sd
.internal_ops
= &ak7375_int_ops
;
205 ak7375_dev
->sd
.entity
.function
= MEDIA_ENT_F_LENS
;
207 ret
= ak7375_init_controls(ak7375_dev
);
211 ret
= media_entity_pads_init(&ak7375_dev
->sd
.entity
, 0, NULL
);
215 ret
= v4l2_async_register_subdev(&ak7375_dev
->sd
);
219 pm_runtime_set_active(&client
->dev
);
220 pm_runtime_enable(&client
->dev
);
221 pm_runtime_idle(&client
->dev
);
226 v4l2_ctrl_handler_free(&ak7375_dev
->ctrls_vcm
);
227 media_entity_cleanup(&ak7375_dev
->sd
.entity
);
232 static void ak7375_remove(struct i2c_client
*client
)
234 struct v4l2_subdev
*sd
= i2c_get_clientdata(client
);
235 struct ak7375_device
*ak7375_dev
= sd_to_ak7375_vcm(sd
);
237 ak7375_subdev_cleanup(ak7375_dev
);
238 pm_runtime_disable(&client
->dev
);
239 pm_runtime_set_suspended(&client
->dev
);
243 * This function sets the vcm position, so it consumes least current
244 * The lens position is gradually moved in units of ctrl_steps,
245 * to make the movements smoothly.
247 static int __maybe_unused
ak7375_vcm_suspend(struct device
*dev
)
249 struct v4l2_subdev
*sd
= dev_get_drvdata(dev
);
250 struct ak7375_device
*ak7375_dev
= sd_to_ak7375_vcm(sd
);
251 const struct ak73xx_chipdef
*cdef
= ak7375_dev
->cdef
;
254 if (!ak7375_dev
->active
)
257 for (val
= ak7375_dev
->focus
->val
& ~(cdef
->ctrl_steps
- 1);
258 val
>= 0; val
-= cdef
->ctrl_steps
) {
259 ret
= ak7375_i2c_write(ak7375_dev
, cdef
->reg_position
,
260 val
<< cdef
->shift_pos
, 2);
262 dev_err_once(dev
, "%s I2C failure: %d\n",
264 usleep_range(cdef
->ctrl_delay_us
, cdef
->ctrl_delay_us
+ 10);
267 if (cdef
->has_standby
) {
268 ret
= ak7375_i2c_write(ak7375_dev
, cdef
->reg_cont
,
269 cdef
->mode_standby
, 1);
271 dev_err(dev
, "%s I2C failure: %d\n", __func__
, ret
);
274 ret
= regulator_bulk_disable(ARRAY_SIZE(ak7375_supply_names
),
275 ak7375_dev
->supplies
);
279 ak7375_dev
->active
= false;
285 * This function sets the vcm position to the value set by the user
286 * through v4l2_ctrl_ops s_ctrl handler
287 * The lens position is gradually moved in units of ctrl_steps,
288 * to make the movements smoothly.
290 static int __maybe_unused
ak7375_vcm_resume(struct device
*dev
)
292 struct v4l2_subdev
*sd
= dev_get_drvdata(dev
);
293 struct ak7375_device
*ak7375_dev
= sd_to_ak7375_vcm(sd
);
294 const struct ak73xx_chipdef
*cdef
= ak7375_dev
->cdef
;
297 if (ak7375_dev
->active
)
300 ret
= regulator_bulk_enable(ARRAY_SIZE(ak7375_supply_names
),
301 ak7375_dev
->supplies
);
305 /* Wait for vcm to become ready */
306 usleep_range(cdef
->power_delay_us
, cdef
->power_delay_us
+ 500);
308 ret
= ak7375_i2c_write(ak7375_dev
, cdef
->reg_cont
,
309 cdef
->mode_active
, 1);
311 dev_err(dev
, "%s I2C failure: %d\n", __func__
, ret
);
315 for (val
= ak7375_dev
->focus
->val
% cdef
->ctrl_steps
;
316 val
<= ak7375_dev
->focus
->val
;
317 val
+= cdef
->ctrl_steps
) {
318 ret
= ak7375_i2c_write(ak7375_dev
, cdef
->reg_position
,
319 val
<< cdef
->shift_pos
, 2);
321 dev_err_ratelimited(dev
, "%s I2C failure: %d\n",
323 usleep_range(cdef
->ctrl_delay_us
, cdef
->ctrl_delay_us
+ 10);
326 ak7375_dev
->active
= true;
331 static const struct of_device_id ak7375_of_table
[] = {
332 { .compatible
= "asahi-kasei,ak7345", .data
= &ak7345_cdef
, },
333 { .compatible
= "asahi-kasei,ak7375", .data
= &ak7375_cdef
, },
336 MODULE_DEVICE_TABLE(of
, ak7375_of_table
);
338 static const struct dev_pm_ops ak7375_pm_ops
= {
339 SET_SYSTEM_SLEEP_PM_OPS(ak7375_vcm_suspend
, ak7375_vcm_resume
)
340 SET_RUNTIME_PM_OPS(ak7375_vcm_suspend
, ak7375_vcm_resume
, NULL
)
343 static struct i2c_driver ak7375_i2c_driver
= {
346 .pm
= &ak7375_pm_ops
,
347 .of_match_table
= ak7375_of_table
,
349 .probe
= ak7375_probe
,
350 .remove
= ak7375_remove
,
352 module_i2c_driver(ak7375_i2c_driver
);
354 MODULE_AUTHOR("Tianshu Qiu <tian.shu.qiu@intel.com>");
355 MODULE_AUTHOR("Bingbu Cao <bingbu.cao@intel.com>");
356 MODULE_DESCRIPTION("AK7375 VCM driver");
357 MODULE_LICENSE("GPL v2");