1 // SPDX-License-Identifier: GPL-2.0
2 // Copyright (c) 2012 Intel Corporation
3 
4 /*
5  * Based on linux/modules/camera/drivers/media/i2c/imx/dw9719.c from:
6  * https://github.com/ZenfoneArea/android_kernel_asus_zenfone5 and
7  * latte-l-oss/drivers/external_drivers/camera/drivers/media/i2c/micam/dw9761.c
8  * from: https://github.com/MiCode/Xiaomi_Kernel_OpenSource/
9  */
10 
11 #include <linux/delay.h>
12 #include <linux/i2c.h>
13 #include <linux/pm_runtime.h>
14 #include <linux/regulator/consumer.h>
15 #include <linux/types.h>
16 
17 #include <media/v4l2-cci.h>
18 #include <media/v4l2-common.h>
19 #include <media/v4l2-ctrls.h>
20 #include <media/v4l2-subdev.h>
21 
22 #define DW9719_MAX_FOCUS_POS	1023
23 #define DW9719_CTRL_STEPS	16
24 #define DW9719_CTRL_DELAY_US	1000
25 
26 #define DW9719_INFO			CCI_REG8(0)
27 #define DW9719_ID			0xF1
28 #define DW9761_ID			0xF4
29 
30 #define DW9719_CONTROL			CCI_REG8(2)
31 #define DW9719_STANDBY			0x00
32 #define DW9719_SHUTDOWN			0x01
33 #define DW9719_ENABLE_RINGING		0x02
34 
35 #define DW9719_VCM_CURRENT		CCI_REG16(3)
36 
37 #define DW9719_STATUS			CCI_REG16(5)
38 #define DW9719_STATUS_BUSY		BIT(0)
39 
40 #define DW9719_MODE			CCI_REG8(6)
41 #define DW9719_MODE_SAC_SHIFT		4
42 #define DW9719_DEFAULT_SAC		4
43 #define DW9761_DEFAULT_SAC		6
44 
45 #define DW9719_VCM_FREQ			CCI_REG8(7)
46 #define DW9719_DEFAULT_VCM_FREQ		0x60
47 #define DW9761_DEFAULT_VCM_FREQ		0x3E
48 
49 #define DW9761_VCM_PRELOAD		CCI_REG8(8)
50 #define DW9761_DEFAULT_VCM_PRELOAD	0x73
51 
52 
53 #define to_dw9719_device(x) container_of(x, struct dw9719_device, sd)
54 
55 enum dw9719_model {
56 	DW9719,
57 	DW9761,
58 };
59 
60 struct dw9719_device {
61 	struct v4l2_subdev sd;
62 	struct device *dev;
63 	struct regmap *regmap;
64 	struct regulator *regulator;
65 	enum dw9719_model model;
66 	u32 mode_low_bits;
67 	u32 sac_mode;
68 	u32 vcm_freq;
69 
70 	struct dw9719_v4l2_ctrls {
71 		struct v4l2_ctrl_handler handler;
72 		struct v4l2_ctrl *focus;
73 	} ctrls;
74 };
75 
dw9719_power_down(struct dw9719_device * dw9719)76 static int dw9719_power_down(struct dw9719_device *dw9719)
77 {
78 	return regulator_disable(dw9719->regulator);
79 }
80 
dw9719_power_up(struct dw9719_device * dw9719,bool detect)81 static int dw9719_power_up(struct dw9719_device *dw9719, bool detect)
82 {
83 	u64 val;
84 	int ret;
85 
86 	ret = regulator_enable(dw9719->regulator);
87 	if (ret)
88 		return ret;
89 
90 	/* Jiggle SCL pin to wake up device */
91 	cci_write(dw9719->regmap, DW9719_CONTROL, DW9719_SHUTDOWN, &ret);
92 	fsleep(100);
93 	cci_write(dw9719->regmap, DW9719_CONTROL, DW9719_STANDBY, &ret);
94 	/* Need 100us to transit from SHUTDOWN to STANDBY */
95 	fsleep(100);
96 
97 	if (detect) {
98 		ret = cci_read(dw9719->regmap, DW9719_INFO, &val, NULL);
99 		if (ret < 0)
100 			return ret;
101 
102 		switch (val) {
103 		case DW9719_ID:
104 			dw9719->model = DW9719;
105 			dw9719->mode_low_bits = 0x00;
106 			dw9719->sac_mode = DW9719_DEFAULT_SAC;
107 			dw9719->vcm_freq = DW9719_DEFAULT_VCM_FREQ;
108 			break;
109 		case DW9761_ID:
110 			dw9719->model = DW9761;
111 			dw9719->mode_low_bits = 0x01;
112 			dw9719->sac_mode = DW9761_DEFAULT_SAC;
113 			dw9719->vcm_freq = DW9761_DEFAULT_VCM_FREQ;
114 			break;
115 		default:
116 			dev_err(dw9719->dev,
117 				"Error unknown device id 0x%02llx\n", val);
118 			return -ENXIO;
119 		}
120 
121 		/* Optional indication of SAC mode select */
122 		device_property_read_u32(dw9719->dev, "dongwoon,sac-mode",
123 					 &dw9719->sac_mode);
124 
125 		/* Optional indication of VCM frequency */
126 		device_property_read_u32(dw9719->dev, "dongwoon,vcm-freq",
127 					 &dw9719->vcm_freq);
128 	}
129 
130 	cci_write(dw9719->regmap, DW9719_CONTROL, DW9719_ENABLE_RINGING, &ret);
131 	cci_write(dw9719->regmap, DW9719_MODE, dw9719->mode_low_bits |
132 			  (dw9719->sac_mode << DW9719_MODE_SAC_SHIFT), &ret);
133 	cci_write(dw9719->regmap, DW9719_VCM_FREQ, dw9719->vcm_freq, &ret);
134 
135 	if (dw9719->model == DW9761)
136 		cci_write(dw9719->regmap, DW9761_VCM_PRELOAD,
137 			  DW9761_DEFAULT_VCM_PRELOAD, &ret);
138 
139 	if (ret)
140 		dw9719_power_down(dw9719);
141 
142 	return ret;
143 }
144 
dw9719_t_focus_abs(struct dw9719_device * dw9719,s32 value)145 static int dw9719_t_focus_abs(struct dw9719_device *dw9719, s32 value)
146 {
147 	return cci_write(dw9719->regmap, DW9719_VCM_CURRENT, value, NULL);
148 }
149 
dw9719_set_ctrl(struct v4l2_ctrl * ctrl)150 static int dw9719_set_ctrl(struct v4l2_ctrl *ctrl)
151 {
152 	struct dw9719_device *dw9719 = container_of(ctrl->handler,
153 						    struct dw9719_device,
154 						    ctrls.handler);
155 	int ret;
156 
157 	/* Only apply changes to the controls if the device is powered up */
158 	if (!pm_runtime_get_if_in_use(dw9719->dev))
159 		return 0;
160 
161 	switch (ctrl->id) {
162 	case V4L2_CID_FOCUS_ABSOLUTE:
163 		ret = dw9719_t_focus_abs(dw9719, ctrl->val);
164 		break;
165 	default:
166 		ret = -EINVAL;
167 	}
168 
169 	pm_runtime_put(dw9719->dev);
170 
171 	return ret;
172 }
173 
174 static const struct v4l2_ctrl_ops dw9719_ctrl_ops = {
175 	.s_ctrl = dw9719_set_ctrl,
176 };
177 
dw9719_suspend(struct device * dev)178 static int dw9719_suspend(struct device *dev)
179 {
180 	struct v4l2_subdev *sd = dev_get_drvdata(dev);
181 	struct dw9719_device *dw9719 = to_dw9719_device(sd);
182 	int ret;
183 	int val;
184 
185 	for (val = dw9719->ctrls.focus->val; val >= 0;
186 	     val -= DW9719_CTRL_STEPS) {
187 		ret = dw9719_t_focus_abs(dw9719, val);
188 		if (ret)
189 			return ret;
190 
191 		usleep_range(DW9719_CTRL_DELAY_US, DW9719_CTRL_DELAY_US + 10);
192 	}
193 
194 	return dw9719_power_down(dw9719);
195 }
196 
dw9719_resume(struct device * dev)197 static int dw9719_resume(struct device *dev)
198 {
199 	struct v4l2_subdev *sd = dev_get_drvdata(dev);
200 	struct dw9719_device *dw9719 = to_dw9719_device(sd);
201 	int current_focus = dw9719->ctrls.focus->val;
202 	int ret;
203 	int val;
204 
205 	ret = dw9719_power_up(dw9719, false);
206 	if (ret)
207 		return ret;
208 
209 	for (val = current_focus % DW9719_CTRL_STEPS; val < current_focus;
210 	     val += DW9719_CTRL_STEPS) {
211 		ret = dw9719_t_focus_abs(dw9719, val);
212 		if (ret)
213 			goto err_power_down;
214 
215 		usleep_range(DW9719_CTRL_DELAY_US, DW9719_CTRL_DELAY_US + 10);
216 	}
217 
218 	return 0;
219 
220 err_power_down:
221 	dw9719_power_down(dw9719);
222 	return ret;
223 }
224 
dw9719_open(struct v4l2_subdev * sd,struct v4l2_subdev_fh * fh)225 static int dw9719_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
226 {
227 	return pm_runtime_resume_and_get(sd->dev);
228 }
229 
dw9719_close(struct v4l2_subdev * sd,struct v4l2_subdev_fh * fh)230 static int dw9719_close(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
231 {
232 	pm_runtime_put(sd->dev);
233 
234 	return 0;
235 }
236 
237 static const struct v4l2_subdev_internal_ops dw9719_internal_ops = {
238 	.open = dw9719_open,
239 	.close = dw9719_close,
240 };
241 
dw9719_init_controls(struct dw9719_device * dw9719)242 static int dw9719_init_controls(struct dw9719_device *dw9719)
243 {
244 	const struct v4l2_ctrl_ops *ops = &dw9719_ctrl_ops;
245 	int ret;
246 
247 	v4l2_ctrl_handler_init(&dw9719->ctrls.handler, 1);
248 
249 	dw9719->ctrls.focus = v4l2_ctrl_new_std(&dw9719->ctrls.handler, ops,
250 						V4L2_CID_FOCUS_ABSOLUTE, 0,
251 						DW9719_MAX_FOCUS_POS, 1, 0);
252 
253 	if (dw9719->ctrls.handler.error) {
254 		dev_err(dw9719->dev, "Error initialising v4l2 ctrls\n");
255 		ret = dw9719->ctrls.handler.error;
256 		goto err_free_handler;
257 	}
258 
259 	dw9719->sd.ctrl_handler = &dw9719->ctrls.handler;
260 	return 0;
261 
262 err_free_handler:
263 	v4l2_ctrl_handler_free(&dw9719->ctrls.handler);
264 	return ret;
265 }
266 
267 static const struct v4l2_subdev_ops dw9719_ops = { };
268 
dw9719_probe(struct i2c_client * client)269 static int dw9719_probe(struct i2c_client *client)
270 {
271 	struct dw9719_device *dw9719;
272 	int ret;
273 
274 	dw9719 = devm_kzalloc(&client->dev, sizeof(*dw9719), GFP_KERNEL);
275 	if (!dw9719)
276 		return -ENOMEM;
277 
278 	dw9719->regmap = devm_cci_regmap_init_i2c(client, 8);
279 	if (IS_ERR(dw9719->regmap))
280 		return PTR_ERR(dw9719->regmap);
281 
282 	dw9719->dev = &client->dev;
283 
284 	dw9719->regulator = devm_regulator_get(&client->dev, "vdd");
285 	if (IS_ERR(dw9719->regulator))
286 		return dev_err_probe(&client->dev, PTR_ERR(dw9719->regulator),
287 				     "getting regulator\n");
288 
289 	v4l2_i2c_subdev_init(&dw9719->sd, client, &dw9719_ops);
290 	dw9719->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
291 	dw9719->sd.internal_ops = &dw9719_internal_ops;
292 
293 	ret = dw9719_init_controls(dw9719);
294 	if (ret)
295 		return ret;
296 
297 	ret = media_entity_pads_init(&dw9719->sd.entity, 0, NULL);
298 	if (ret < 0)
299 		goto err_free_ctrl_handler;
300 
301 	dw9719->sd.entity.function = MEDIA_ENT_F_LENS;
302 
303 	/*
304 	 * We need the driver to work in the event that pm runtime is disable in
305 	 * the kernel, so power up and verify the chip now. In the event that
306 	 * runtime pm is disabled this will leave the chip on, so that the lens
307 	 * will work.
308 	 */
309 
310 	ret = dw9719_power_up(dw9719, true);
311 	if (ret)
312 		goto err_cleanup_media;
313 
314 	pm_runtime_set_active(&client->dev);
315 	pm_runtime_get_noresume(&client->dev);
316 	pm_runtime_enable(&client->dev);
317 
318 	ret = v4l2_async_register_subdev(&dw9719->sd);
319 	if (ret < 0)
320 		goto err_pm_runtime;
321 
322 	pm_runtime_set_autosuspend_delay(&client->dev, 1000);
323 	pm_runtime_use_autosuspend(&client->dev);
324 	pm_runtime_put_autosuspend(&client->dev);
325 
326 	return ret;
327 
328 err_pm_runtime:
329 	pm_runtime_disable(&client->dev);
330 	pm_runtime_put_noidle(&client->dev);
331 	dw9719_power_down(dw9719);
332 err_cleanup_media:
333 	media_entity_cleanup(&dw9719->sd.entity);
334 err_free_ctrl_handler:
335 	v4l2_ctrl_handler_free(&dw9719->ctrls.handler);
336 
337 	return ret;
338 }
339 
dw9719_remove(struct i2c_client * client)340 static void dw9719_remove(struct i2c_client *client)
341 {
342 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
343 	struct dw9719_device *dw9719 =
344 		container_of(sd, struct dw9719_device, sd);
345 
346 	v4l2_async_unregister_subdev(sd);
347 	v4l2_ctrl_handler_free(&dw9719->ctrls.handler);
348 	media_entity_cleanup(&dw9719->sd.entity);
349 
350 	pm_runtime_disable(&client->dev);
351 	if (!pm_runtime_status_suspended(&client->dev))
352 		dw9719_power_down(dw9719);
353 	pm_runtime_set_suspended(&client->dev);
354 }
355 
356 static const struct i2c_device_id dw9719_id_table[] = {
357 	{ "dw9719" },
358 	{ "dw9761" },
359 	{ }
360 };
361 MODULE_DEVICE_TABLE(i2c, dw9719_id_table);
362 
363 static DEFINE_RUNTIME_DEV_PM_OPS(dw9719_pm_ops, dw9719_suspend, dw9719_resume,
364 				 NULL);
365 
366 static struct i2c_driver dw9719_i2c_driver = {
367 	.driver = {
368 		.name = "dw9719",
369 		.pm = pm_sleep_ptr(&dw9719_pm_ops),
370 	},
371 	.probe = dw9719_probe,
372 	.remove = dw9719_remove,
373 	.id_table = dw9719_id_table,
374 };
375 module_i2c_driver(dw9719_i2c_driver);
376 
377 MODULE_AUTHOR("Daniel Scally <djrscally@gmail.com>");
378 MODULE_DESCRIPTION("DW9719 VCM Driver");
379 MODULE_LICENSE("GPL");
380