bcm27xx: switch to kernel v6.1
[openwrt/openwrt.git] / target / linux / bcm27xx / patches-5.15 / 950-0773-media-i2c-Add-driver-for-AD5398-VCM-lens-driver.patch
1 From 838b1d352c8b7a8380fc2f00c42948e8307f51de Mon Sep 17 00:00:00 2001
2 From: Dave Stevenson <dave.stevenson@raspberrypi.com>
3 Date: Wed, 29 Sep 2021 14:04:28 +0100
4 Subject: [PATCH] media: i2c: Add driver for AD5398 VCM lens driver
5
6 Adds a driver for the Analog Devices AD5398 10 bit
7 I2C DAC which is commonly used for driving VCM lens
8 mechanisms.
9
10 Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
11 ---
12 drivers/media/i2c/Kconfig | 7 +
13 drivers/media/i2c/Makefile | 1 +
14 drivers/media/i2c/ad5398.c | 342 +++++++++++++++++++++++++++++++++++++
15 3 files changed, 350 insertions(+)
16 create mode 100644 drivers/media/i2c/ad5398.c
17
18 --- a/drivers/media/i2c/Kconfig
19 +++ b/drivers/media/i2c/Kconfig
20 @@ -1451,6 +1451,13 @@ endmenu
21 menu "Lens drivers"
22 visible if MEDIA_CAMERA_SUPPORT
23
24 +config VIDEO_AD5398
25 + tristate "AD5398 lens voice coil support"
26 + depends on GPIOLIB && I2C && VIDEO_V4L2
27 + select MEDIA_CONTROLLER
28 + help
29 + This is a driver for the AD5398 camera lens voice coil.
30 +
31 config VIDEO_AD5820
32 tristate "AD5820 lens voice coil support"
33 depends on GPIOLIB && I2C && VIDEO_V4L2
34 --- a/drivers/media/i2c/Makefile
35 +++ b/drivers/media/i2c/Makefile
36 @@ -21,6 +21,7 @@ obj-$(CONFIG_VIDEO_SAA717X) += saa717x.o
37 obj-$(CONFIG_VIDEO_SAA7127) += saa7127.o
38 obj-$(CONFIG_VIDEO_SAA7185) += saa7185.o
39 obj-$(CONFIG_VIDEO_SAA6752HS) += saa6752hs.o
40 +obj-$(CONFIG_VIDEO_AD5398) += ad5398.o
41 obj-$(CONFIG_VIDEO_AD5820) += ad5820.o
42 obj-$(CONFIG_VIDEO_AK7375) += ak7375.o
43 obj-$(CONFIG_VIDEO_DW9714) += dw9714.o
44 --- /dev/null
45 +++ b/drivers/media/i2c/ad5398.c
46 @@ -0,0 +1,342 @@
47 +// SPDX-License-Identifier: GPL-2.0-only
48 +/*
49 + * AD5398 DAC driver for camera voice coil focus.
50 + * Copyright (C) 2021 Raspberry Pi (Trading) Ltd.
51 + *
52 + * Based on AD5820 DAC driver by Nokia and TI.
53 + *
54 + * This driver uses the regulator framework notification hooks on the
55 + * assumption that the VCM and sensor share a regulator. This means the VCM
56 + * position will be restored when either the sensor or VCM subdevices are opened
57 + * or powered up. The client can therefore choose to ignore the VCM subdevice,
58 + * and the lens position will be as previously requested. Without that, there
59 + * is a hard requirement to have the VCM subdevice open in order for the VCM
60 + * to be powered and at the requested position.
61 + */
62 +
63 +#include <linux/errno.h>
64 +#include <linux/i2c.h>
65 +#include <linux/kernel.h>
66 +#include <linux/module.h>
67 +#include <linux/regulator/consumer.h>
68 +#include <linux/gpio/consumer.h>
69 +
70 +#include <media/v4l2-ctrls.h>
71 +#include <media/v4l2-device.h>
72 +#include <media/v4l2-subdev.h>
73 +
74 +/* Register definitions */
75 +#define AD5398_POWER_DOWN BIT(15)
76 +#define AD5398_DAC_SHIFT 4
77 +
78 +#define to_ad5398_device(sd) container_of(sd, struct ad5398_device, subdev)
79 +
80 +struct ad5398_device {
81 + struct v4l2_subdev subdev;
82 + struct ad5398_platform_data *platform_data;
83 + struct regulator *vana;
84 + struct notifier_block nb;
85 +
86 + struct v4l2_ctrl_handler ctrls;
87 + u32 focus_absolute;
88 +
89 + bool standby;
90 +};
91 +
92 +static int ad5398_write(struct ad5398_device *coil, u16 data)
93 +{
94 + struct i2c_client *client = v4l2_get_subdevdata(&coil->subdev);
95 + struct i2c_msg msg;
96 + __be16 be_data;
97 + int r;
98 +
99 + if (!client->adapter)
100 + return -ENODEV;
101 +
102 + be_data = cpu_to_be16(data);
103 + msg.addr = client->addr;
104 + msg.flags = 0;
105 + msg.len = 2;
106 + msg.buf = (u8 *)&be_data;
107 +
108 + r = i2c_transfer(client->adapter, &msg, 1);
109 + if (r < 0) {
110 + dev_err(&client->dev, "write failed, error %d\n", r);
111 + return r;
112 + }
113 +
114 + return 0;
115 +}
116 +
117 +/*
118 + * Calculate status word and write it to the device based on current
119 + * values of V4L2 controls. It is assumed that the stored V4L2 control
120 + * values are properly limited and rounded.
121 + */
122 +static int ad5398_update_hw(struct ad5398_device *coil)
123 +{
124 + u16 status;
125 +
126 + status = coil->focus_absolute << AD5398_DAC_SHIFT;
127 +
128 + if (coil->standby)
129 + status |= AD5398_POWER_DOWN;
130 +
131 + return ad5398_write(coil, status);
132 +}
133 +
134 +/*
135 + * Power handling
136 + */
137 +static int ad5398_power_off(struct ad5398_device *coil)
138 +{
139 + int ret = 0;
140 +
141 + coil->standby = true;
142 + ret = ad5398_update_hw(coil);
143 +
144 + return ret;
145 +}
146 +
147 +static int ad5398_power_on(struct ad5398_device *coil)
148 +{
149 + int ret;
150 +
151 + /* Restore the hardware settings. */
152 + coil->standby = false;
153 + ret = ad5398_update_hw(coil);
154 + if (ret)
155 + goto fail;
156 +
157 + return 0;
158 +
159 +fail:
160 + coil->standby = true;
161 +
162 + return ret;
163 +}
164 +
165 +/*
166 + * V4L2 controls
167 + */
168 +static int ad5398_set_ctrl(struct v4l2_ctrl *ctrl)
169 +{
170 + struct ad5398_device *coil =
171 + container_of(ctrl->handler, struct ad5398_device, ctrls);
172 +
173 + switch (ctrl->id) {
174 + case V4L2_CID_FOCUS_ABSOLUTE:
175 + coil->focus_absolute = ctrl->val;
176 + return ad5398_update_hw(coil);
177 + }
178 +
179 + return 0;
180 +}
181 +
182 +static const struct v4l2_ctrl_ops ad5398_ctrl_ops = {
183 + .s_ctrl = ad5398_set_ctrl,
184 +};
185 +
186 +static int ad5398_init_controls(struct ad5398_device *coil)
187 +{
188 + v4l2_ctrl_handler_init(&coil->ctrls, 1);
189 +
190 + /*
191 + * V4L2_CID_FOCUS_ABSOLUTE
192 + *
193 + * Minimum current is 0 mA, maximum is 120 mA. Thus, 1 code is
194 + * equivalent to 120/1023 = 0.1173 mA. Nevertheless, we do not use [mA]
195 + * for focus position, because it is meaningless for user. Meaningful
196 + * would be to use focus distance or even its inverse, but since the
197 + * driver doesn't have sufficient knowledge to do the conversion, we
198 + * will just use abstract codes here. In any case, smaller value = focus
199 + * position farther from camera. The default zero value means focus at
200 + * infinity, and also least current consumption.
201 + */
202 + v4l2_ctrl_new_std(&coil->ctrls, &ad5398_ctrl_ops,
203 + V4L2_CID_FOCUS_ABSOLUTE, 0, 1023, 1, 0);
204 +
205 + if (coil->ctrls.error)
206 + return coil->ctrls.error;
207 +
208 + coil->focus_absolute = 0;
209 +
210 + coil->subdev.ctrl_handler = &coil->ctrls;
211 +
212 + return 0;
213 +}
214 +
215 +/*
216 + * V4L2 subdev operations
217 + */
218 +static int ad5398_registered(struct v4l2_subdev *subdev)
219 +{
220 + struct ad5398_device *coil = to_ad5398_device(subdev);
221 +
222 + return ad5398_init_controls(coil);
223 +}
224 +
225 +static int
226 +ad5398_set_power(struct v4l2_subdev *subdev, int on)
227 +{
228 + struct ad5398_device *coil = to_ad5398_device(subdev);
229 + int ret;
230 +
231 + if (on)
232 + ret = regulator_enable(coil->vana);
233 + else
234 + ret = regulator_disable(coil->vana);
235 +
236 + return ret;
237 +}
238 +
239 +static int ad5398_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
240 +{
241 + struct ad5398_device *coil = to_ad5398_device(sd);
242 +
243 + return regulator_enable(coil->vana);
244 +}
245 +
246 +static int ad5398_close(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
247 +{
248 + struct ad5398_device *coil = to_ad5398_device(sd);
249 +
250 + return regulator_disable(coil->vana);
251 +}
252 +
253 +static const struct v4l2_subdev_core_ops ad5398_core_ops = {
254 + .s_power = ad5398_set_power,
255 +};
256 +
257 +static const struct v4l2_subdev_ops ad5398_ops = {
258 + .core = &ad5398_core_ops,
259 +};
260 +
261 +static const struct v4l2_subdev_internal_ops ad5398_internal_ops = {
262 + .registered = ad5398_registered,
263 + .open = ad5398_open,
264 + .close = ad5398_close,
265 +};
266 +
267 +/*
268 + * I2C driver
269 + */
270 +static int __maybe_unused ad5398_suspend(struct device *dev)
271 +{
272 + struct i2c_client *client = container_of(dev, struct i2c_client, dev);
273 + struct v4l2_subdev *subdev = i2c_get_clientdata(client);
274 + struct ad5398_device *coil = to_ad5398_device(subdev);
275 +
276 + return regulator_enable(coil->vana);
277 +}
278 +
279 +static int __maybe_unused ad5398_resume(struct device *dev)
280 +{
281 + struct i2c_client *client = container_of(dev, struct i2c_client, dev);
282 + struct v4l2_subdev *subdev = i2c_get_clientdata(client);
283 + struct ad5398_device *coil = to_ad5398_device(subdev);
284 +
285 + return regulator_disable(coil->vana);
286 +}
287 +
288 +static int ad5398_regulator_notifier(struct notifier_block *nb,
289 + unsigned long event,
290 + void *ignored)
291 +{
292 + struct ad5398_device *coil = container_of(nb, struct ad5398_device, nb);
293 +
294 + if (event == REGULATOR_EVENT_ENABLE)
295 + ad5398_power_on(coil);
296 + else if (event == REGULATOR_EVENT_PRE_DISABLE)
297 + ad5398_power_off(coil);
298 +
299 + return NOTIFY_OK;
300 +}
301 +
302 +static int ad5398_probe(struct i2c_client *client,
303 + const struct i2c_device_id *devid)
304 +{
305 + struct ad5398_device *coil;
306 + int ret;
307 +
308 + coil = devm_kzalloc(&client->dev, sizeof(*coil), GFP_KERNEL);
309 + if (!coil)
310 + return -ENOMEM;
311 +
312 + coil->vana = devm_regulator_get(&client->dev, "VANA");
313 + if (IS_ERR(coil->vana)) {
314 + ret = PTR_ERR(coil->vana);
315 + if (ret != -EPROBE_DEFER)
316 + dev_err(&client->dev, "could not get regulator for vana\n");
317 + return ret;
318 + }
319 +
320 + v4l2_i2c_subdev_init(&coil->subdev, client, &ad5398_ops);
321 + coil->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
322 + coil->subdev.internal_ops = &ad5398_internal_ops;
323 + coil->subdev.entity.function = MEDIA_ENT_F_LENS;
324 + strscpy(coil->subdev.name, "ad5398 focus", sizeof(coil->subdev.name));
325 +
326 + coil->nb.notifier_call = &ad5398_regulator_notifier;
327 + ret = regulator_register_notifier(coil->vana, &coil->nb);
328 + if (ret < 0)
329 + return ret;
330 +
331 + ret = media_entity_pads_init(&coil->subdev.entity, 0, NULL);
332 + if (ret < 0)
333 + goto cleanup2;
334 +
335 + ret = v4l2_async_register_subdev(&coil->subdev);
336 + if (ret < 0)
337 + goto cleanup;
338 +
339 + return ret;
340 +
341 +cleanup:
342 + media_entity_cleanup(&coil->subdev.entity);
343 +cleanup2:
344 + regulator_unregister_notifier(coil->vana, &coil->nb);
345 + return ret;
346 +}
347 +
348 +static int ad5398_remove(struct i2c_client *client)
349 +{
350 + struct v4l2_subdev *subdev = i2c_get_clientdata(client);
351 + struct ad5398_device *coil = to_ad5398_device(subdev);
352 +
353 + v4l2_async_unregister_subdev(&coil->subdev);
354 + v4l2_ctrl_handler_free(&coil->ctrls);
355 + media_entity_cleanup(&coil->subdev.entity);
356 + return 0;
357 +}
358 +
359 +static const struct i2c_device_id ad5398_id_table[] = {
360 + { "ad5398", 0 },
361 + { }
362 +};
363 +MODULE_DEVICE_TABLE(i2c, ad5398_id_table);
364 +
365 +static const struct of_device_id ad5398_of_table[] = {
366 + { .compatible = "adi,ad5398" },
367 + { }
368 +};
369 +MODULE_DEVICE_TABLE(of, ad5398_of_table);
370 +
371 +static SIMPLE_DEV_PM_OPS(ad5398_pm, ad5398_suspend, ad5398_resume);
372 +
373 +static struct i2c_driver ad5398_i2c_driver = {
374 + .driver = {
375 + .name = "ad5398",
376 + .pm = &ad5398_pm,
377 + .of_match_table = ad5398_of_table,
378 + },
379 + .probe = ad5398_probe,
380 + .remove = ad5398_remove,
381 + .id_table = ad5398_id_table,
382 +};
383 +
384 +module_i2c_driver(ad5398_i2c_driver);
385 +
386 +MODULE_AUTHOR("Dave Stevenson <dave.stevenson@raspberrypi.com>");
387 +MODULE_DESCRIPTION("AD5398 camera lens driver");
388 +MODULE_LICENSE("GPL");