xref: /openbmc/linux/drivers/media/i2c/adp1653.c (revision d7a3d85e)
1 /*
2  * drivers/media/i2c/adp1653.c
3  *
4  * Copyright (C) 2008--2011 Nokia Corporation
5  *
6  * Contact: Sakari Ailus <sakari.ailus@iki.fi>
7  *
8  * Contributors:
9  *	Sakari Ailus <sakari.ailus@iki.fi>
10  *	Tuukka Toivonen <tuukkat76@gmail.com>
11  *
12  * This program is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU General Public License
14  * version 2 as published by the Free Software Foundation.
15  *
16  * This program is distributed in the hope that it will be useful, but
17  * WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19  * General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
24  * 02110-1301 USA
25  *
26  * TODO:
27  * - fault interrupt handling
28  * - hardware strobe
29  * - power doesn't need to be ON if all lights are off
30  *
31  */
32 
33 #include <linux/delay.h>
34 #include <linux/module.h>
35 #include <linux/i2c.h>
36 #include <linux/slab.h>
37 #include <media/adp1653.h>
38 #include <media/v4l2-device.h>
39 
40 #define TIMEOUT_MAX		820000
41 #define TIMEOUT_STEP		54600
42 #define TIMEOUT_MIN		(TIMEOUT_MAX - ADP1653_REG_CONFIG_TMR_SET_MAX \
43 				 * TIMEOUT_STEP)
44 #define TIMEOUT_US_TO_CODE(t)	((TIMEOUT_MAX + (TIMEOUT_STEP / 2) - (t)) \
45 				 / TIMEOUT_STEP)
46 #define TIMEOUT_CODE_TO_US(c)	(TIMEOUT_MAX - (c) * TIMEOUT_STEP)
47 
48 /* Write values into ADP1653 registers. */
49 static int adp1653_update_hw(struct adp1653_flash *flash)
50 {
51 	struct i2c_client *client = v4l2_get_subdevdata(&flash->subdev);
52 	u8 out_sel;
53 	u8 config = 0;
54 	int rval;
55 
56 	out_sel = ADP1653_INDICATOR_INTENSITY_uA_TO_REG(
57 		flash->indicator_intensity->val)
58 		<< ADP1653_REG_OUT_SEL_ILED_SHIFT;
59 
60 	switch (flash->led_mode->val) {
61 	case V4L2_FLASH_LED_MODE_NONE:
62 		break;
63 	case V4L2_FLASH_LED_MODE_FLASH:
64 		/* Flash mode, light on with strobe, duration from timer */
65 		config = ADP1653_REG_CONFIG_TMR_CFG;
66 		config |= TIMEOUT_US_TO_CODE(flash->flash_timeout->val)
67 			  << ADP1653_REG_CONFIG_TMR_SET_SHIFT;
68 		break;
69 	case V4L2_FLASH_LED_MODE_TORCH:
70 		/* Torch mode, light immediately on, duration indefinite */
71 		out_sel |= ADP1653_FLASH_INTENSITY_mA_TO_REG(
72 			flash->torch_intensity->val)
73 			<< ADP1653_REG_OUT_SEL_HPLED_SHIFT;
74 		break;
75 	}
76 
77 	rval = i2c_smbus_write_byte_data(client, ADP1653_REG_OUT_SEL, out_sel);
78 	if (rval < 0)
79 		return rval;
80 
81 	rval = i2c_smbus_write_byte_data(client, ADP1653_REG_CONFIG, config);
82 	if (rval < 0)
83 		return rval;
84 
85 	return 0;
86 }
87 
88 static int adp1653_get_fault(struct adp1653_flash *flash)
89 {
90 	struct i2c_client *client = v4l2_get_subdevdata(&flash->subdev);
91 	int fault;
92 	int rval;
93 
94 	fault = i2c_smbus_read_byte_data(client, ADP1653_REG_FAULT);
95 	if (IS_ERR_VALUE(fault))
96 		return fault;
97 
98 	flash->fault |= fault;
99 
100 	if (!flash->fault)
101 		return 0;
102 
103 	/* Clear faults. */
104 	rval = i2c_smbus_write_byte_data(client, ADP1653_REG_OUT_SEL, 0);
105 	if (IS_ERR_VALUE(rval))
106 		return rval;
107 
108 	flash->led_mode->val = V4L2_FLASH_LED_MODE_NONE;
109 
110 	rval = adp1653_update_hw(flash);
111 	if (IS_ERR_VALUE(rval))
112 		return rval;
113 
114 	return flash->fault;
115 }
116 
117 static int adp1653_strobe(struct adp1653_flash *flash, int enable)
118 {
119 	struct i2c_client *client = v4l2_get_subdevdata(&flash->subdev);
120 	u8 out_sel = ADP1653_INDICATOR_INTENSITY_uA_TO_REG(
121 		flash->indicator_intensity->val)
122 		<< ADP1653_REG_OUT_SEL_ILED_SHIFT;
123 	int rval;
124 
125 	if (flash->led_mode->val != V4L2_FLASH_LED_MODE_FLASH)
126 		return -EBUSY;
127 
128 	if (!enable)
129 		return i2c_smbus_write_byte_data(client, ADP1653_REG_OUT_SEL,
130 						 out_sel);
131 
132 	out_sel |= ADP1653_FLASH_INTENSITY_mA_TO_REG(
133 		flash->flash_intensity->val)
134 		<< ADP1653_REG_OUT_SEL_HPLED_SHIFT;
135 	rval = i2c_smbus_write_byte_data(client, ADP1653_REG_OUT_SEL, out_sel);
136 	if (rval)
137 		return rval;
138 
139 	/* Software strobe using i2c */
140 	rval = i2c_smbus_write_byte_data(client, ADP1653_REG_SW_STROBE,
141 		ADP1653_REG_SW_STROBE_SW_STROBE);
142 	if (rval)
143 		return rval;
144 	return i2c_smbus_write_byte_data(client, ADP1653_REG_SW_STROBE, 0);
145 }
146 
147 /* --------------------------------------------------------------------------
148  * V4L2 controls
149  */
150 
151 static int adp1653_get_ctrl(struct v4l2_ctrl *ctrl)
152 {
153 	struct adp1653_flash *flash =
154 		container_of(ctrl->handler, struct adp1653_flash, ctrls);
155 	int rval;
156 
157 	rval = adp1653_get_fault(flash);
158 	if (IS_ERR_VALUE(rval))
159 		return rval;
160 
161 	ctrl->cur.val = 0;
162 
163 	if (flash->fault & ADP1653_REG_FAULT_FLT_SCP)
164 		ctrl->cur.val |= V4L2_FLASH_FAULT_SHORT_CIRCUIT;
165 	if (flash->fault & ADP1653_REG_FAULT_FLT_OT)
166 		ctrl->cur.val |= V4L2_FLASH_FAULT_OVER_TEMPERATURE;
167 	if (flash->fault & ADP1653_REG_FAULT_FLT_TMR)
168 		ctrl->cur.val |= V4L2_FLASH_FAULT_TIMEOUT;
169 	if (flash->fault & ADP1653_REG_FAULT_FLT_OV)
170 		ctrl->cur.val |= V4L2_FLASH_FAULT_OVER_VOLTAGE;
171 
172 	flash->fault = 0;
173 
174 	return 0;
175 }
176 
177 static int adp1653_set_ctrl(struct v4l2_ctrl *ctrl)
178 {
179 	struct adp1653_flash *flash =
180 		container_of(ctrl->handler, struct adp1653_flash, ctrls);
181 	int rval;
182 
183 	rval = adp1653_get_fault(flash);
184 	if (IS_ERR_VALUE(rval))
185 		return rval;
186 	if ((rval & (ADP1653_REG_FAULT_FLT_SCP |
187 		     ADP1653_REG_FAULT_FLT_OT |
188 		     ADP1653_REG_FAULT_FLT_OV)) &&
189 	    (ctrl->id == V4L2_CID_FLASH_STROBE ||
190 	     ctrl->id == V4L2_CID_FLASH_TORCH_INTENSITY ||
191 	     ctrl->id == V4L2_CID_FLASH_LED_MODE))
192 		return -EBUSY;
193 
194 	switch (ctrl->id) {
195 	case V4L2_CID_FLASH_STROBE:
196 		return adp1653_strobe(flash, 1);
197 	case V4L2_CID_FLASH_STROBE_STOP:
198 		return adp1653_strobe(flash, 0);
199 	}
200 
201 	return adp1653_update_hw(flash);
202 }
203 
204 static const struct v4l2_ctrl_ops adp1653_ctrl_ops = {
205 	.g_volatile_ctrl = adp1653_get_ctrl,
206 	.s_ctrl = adp1653_set_ctrl,
207 };
208 
209 static int adp1653_init_controls(struct adp1653_flash *flash)
210 {
211 	struct v4l2_ctrl *fault;
212 
213 	v4l2_ctrl_handler_init(&flash->ctrls, 9);
214 
215 	flash->led_mode =
216 		v4l2_ctrl_new_std_menu(&flash->ctrls, &adp1653_ctrl_ops,
217 				       V4L2_CID_FLASH_LED_MODE,
218 				       V4L2_FLASH_LED_MODE_TORCH, ~0x7, 0);
219 	v4l2_ctrl_new_std_menu(&flash->ctrls, &adp1653_ctrl_ops,
220 			       V4L2_CID_FLASH_STROBE_SOURCE,
221 			       V4L2_FLASH_STROBE_SOURCE_SOFTWARE, ~0x1, 0);
222 	v4l2_ctrl_new_std(&flash->ctrls, &adp1653_ctrl_ops,
223 			  V4L2_CID_FLASH_STROBE, 0, 0, 0, 0);
224 	v4l2_ctrl_new_std(&flash->ctrls, &adp1653_ctrl_ops,
225 			  V4L2_CID_FLASH_STROBE_STOP, 0, 0, 0, 0);
226 	flash->flash_timeout =
227 		v4l2_ctrl_new_std(&flash->ctrls, &adp1653_ctrl_ops,
228 				  V4L2_CID_FLASH_TIMEOUT, TIMEOUT_MIN,
229 				  flash->platform_data->max_flash_timeout,
230 				  TIMEOUT_STEP,
231 				  flash->platform_data->max_flash_timeout);
232 	flash->flash_intensity =
233 		v4l2_ctrl_new_std(&flash->ctrls, &adp1653_ctrl_ops,
234 				  V4L2_CID_FLASH_INTENSITY,
235 				  ADP1653_FLASH_INTENSITY_MIN,
236 				  flash->platform_data->max_flash_intensity,
237 				  1, flash->platform_data->max_flash_intensity);
238 	flash->torch_intensity =
239 		v4l2_ctrl_new_std(&flash->ctrls, &adp1653_ctrl_ops,
240 				  V4L2_CID_FLASH_TORCH_INTENSITY,
241 				  ADP1653_TORCH_INTENSITY_MIN,
242 				  flash->platform_data->max_torch_intensity,
243 				  ADP1653_FLASH_INTENSITY_STEP,
244 				  flash->platform_data->max_torch_intensity);
245 	flash->indicator_intensity =
246 		v4l2_ctrl_new_std(&flash->ctrls, &adp1653_ctrl_ops,
247 				  V4L2_CID_FLASH_INDICATOR_INTENSITY,
248 				  ADP1653_INDICATOR_INTENSITY_MIN,
249 				  flash->platform_data->max_indicator_intensity,
250 				  ADP1653_INDICATOR_INTENSITY_STEP,
251 				  ADP1653_INDICATOR_INTENSITY_MIN);
252 	fault = v4l2_ctrl_new_std(&flash->ctrls, &adp1653_ctrl_ops,
253 				  V4L2_CID_FLASH_FAULT, 0,
254 				  V4L2_FLASH_FAULT_OVER_VOLTAGE
255 				  | V4L2_FLASH_FAULT_OVER_TEMPERATURE
256 				  | V4L2_FLASH_FAULT_SHORT_CIRCUIT, 0, 0);
257 
258 	if (flash->ctrls.error)
259 		return flash->ctrls.error;
260 
261 	fault->flags |= V4L2_CTRL_FLAG_VOLATILE;
262 
263 	flash->subdev.ctrl_handler = &flash->ctrls;
264 	return 0;
265 }
266 
267 /* --------------------------------------------------------------------------
268  * V4L2 subdev operations
269  */
270 
271 static int
272 adp1653_init_device(struct adp1653_flash *flash)
273 {
274 	struct i2c_client *client = v4l2_get_subdevdata(&flash->subdev);
275 	int rval;
276 
277 	/* Clear FAULT register by writing zero to OUT_SEL */
278 	rval = i2c_smbus_write_byte_data(client, ADP1653_REG_OUT_SEL, 0);
279 	if (rval < 0) {
280 		dev_err(&client->dev, "failed writing fault register\n");
281 		return -EIO;
282 	}
283 
284 	mutex_lock(flash->ctrls.lock);
285 	/* Reset faults before reading new ones. */
286 	flash->fault = 0;
287 	rval = adp1653_get_fault(flash);
288 	mutex_unlock(flash->ctrls.lock);
289 	if (rval > 0) {
290 		dev_err(&client->dev, "faults detected: 0x%1.1x\n", rval);
291 		return -EIO;
292 	}
293 
294 	mutex_lock(flash->ctrls.lock);
295 	rval = adp1653_update_hw(flash);
296 	mutex_unlock(flash->ctrls.lock);
297 	if (rval) {
298 		dev_err(&client->dev,
299 			"adp1653_update_hw failed at %s\n", __func__);
300 		return -EIO;
301 	}
302 
303 	return 0;
304 }
305 
306 static int
307 __adp1653_set_power(struct adp1653_flash *flash, int on)
308 {
309 	int ret;
310 
311 	ret = flash->platform_data->power(&flash->subdev, on);
312 	if (ret < 0)
313 		return ret;
314 
315 	if (!on)
316 		return 0;
317 
318 	ret = adp1653_init_device(flash);
319 	if (ret < 0)
320 		flash->platform_data->power(&flash->subdev, 0);
321 
322 	return ret;
323 }
324 
325 static int
326 adp1653_set_power(struct v4l2_subdev *subdev, int on)
327 {
328 	struct adp1653_flash *flash = to_adp1653_flash(subdev);
329 	int ret = 0;
330 
331 	mutex_lock(&flash->power_lock);
332 
333 	/* If the power count is modified from 0 to != 0 or from != 0 to 0,
334 	 * update the power state.
335 	 */
336 	if (flash->power_count == !on) {
337 		ret = __adp1653_set_power(flash, !!on);
338 		if (ret < 0)
339 			goto done;
340 	}
341 
342 	/* Update the power count. */
343 	flash->power_count += on ? 1 : -1;
344 	WARN_ON(flash->power_count < 0);
345 
346 done:
347 	mutex_unlock(&flash->power_lock);
348 	return ret;
349 }
350 
351 static int adp1653_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
352 {
353 	return adp1653_set_power(sd, 1);
354 }
355 
356 static int adp1653_close(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
357 {
358 	return adp1653_set_power(sd, 0);
359 }
360 
361 static const struct v4l2_subdev_core_ops adp1653_core_ops = {
362 	.s_power = adp1653_set_power,
363 };
364 
365 static const struct v4l2_subdev_ops adp1653_ops = {
366 	.core = &adp1653_core_ops,
367 };
368 
369 static const struct v4l2_subdev_internal_ops adp1653_internal_ops = {
370 	.open = adp1653_open,
371 	.close = adp1653_close,
372 };
373 
374 /* --------------------------------------------------------------------------
375  * I2C driver
376  */
377 #ifdef CONFIG_PM
378 
379 static int adp1653_suspend(struct device *dev)
380 {
381 	struct i2c_client *client = to_i2c_client(dev);
382 	struct v4l2_subdev *subdev = i2c_get_clientdata(client);
383 	struct adp1653_flash *flash = to_adp1653_flash(subdev);
384 
385 	if (!flash->power_count)
386 		return 0;
387 
388 	return __adp1653_set_power(flash, 0);
389 }
390 
391 static int adp1653_resume(struct device *dev)
392 {
393 	struct i2c_client *client = to_i2c_client(dev);
394 	struct v4l2_subdev *subdev = i2c_get_clientdata(client);
395 	struct adp1653_flash *flash = to_adp1653_flash(subdev);
396 
397 	if (!flash->power_count)
398 		return 0;
399 
400 	return __adp1653_set_power(flash, 1);
401 }
402 
403 #else
404 
405 #define adp1653_suspend	NULL
406 #define adp1653_resume	NULL
407 
408 #endif /* CONFIG_PM */
409 
410 static int adp1653_probe(struct i2c_client *client,
411 			 const struct i2c_device_id *devid)
412 {
413 	struct adp1653_flash *flash;
414 	int ret;
415 
416 	/* we couldn't work without platform data */
417 	if (client->dev.platform_data == NULL)
418 		return -ENODEV;
419 
420 	flash = devm_kzalloc(&client->dev, sizeof(*flash), GFP_KERNEL);
421 	if (flash == NULL)
422 		return -ENOMEM;
423 
424 	flash->platform_data = client->dev.platform_data;
425 
426 	mutex_init(&flash->power_lock);
427 
428 	v4l2_i2c_subdev_init(&flash->subdev, client, &adp1653_ops);
429 	flash->subdev.internal_ops = &adp1653_internal_ops;
430 	flash->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
431 
432 	ret = adp1653_init_controls(flash);
433 	if (ret)
434 		goto free_and_quit;
435 
436 	ret = media_entity_init(&flash->subdev.entity, 0, NULL, 0);
437 	if (ret < 0)
438 		goto free_and_quit;
439 
440 	flash->subdev.entity.type = MEDIA_ENT_T_V4L2_SUBDEV_FLASH;
441 
442 	return 0;
443 
444 free_and_quit:
445 	v4l2_ctrl_handler_free(&flash->ctrls);
446 	return ret;
447 }
448 
449 static int adp1653_remove(struct i2c_client *client)
450 {
451 	struct v4l2_subdev *subdev = i2c_get_clientdata(client);
452 	struct adp1653_flash *flash = to_adp1653_flash(subdev);
453 
454 	v4l2_device_unregister_subdev(&flash->subdev);
455 	v4l2_ctrl_handler_free(&flash->ctrls);
456 	media_entity_cleanup(&flash->subdev.entity);
457 
458 	return 0;
459 }
460 
461 static const struct i2c_device_id adp1653_id_table[] = {
462 	{ ADP1653_NAME, 0 },
463 	{ }
464 };
465 MODULE_DEVICE_TABLE(i2c, adp1653_id_table);
466 
467 static struct dev_pm_ops adp1653_pm_ops = {
468 	.suspend	= adp1653_suspend,
469 	.resume		= adp1653_resume,
470 };
471 
472 static struct i2c_driver adp1653_i2c_driver = {
473 	.driver		= {
474 		.name	= ADP1653_NAME,
475 		.pm	= &adp1653_pm_ops,
476 	},
477 	.probe		= adp1653_probe,
478 	.remove		= adp1653_remove,
479 	.id_table	= adp1653_id_table,
480 };
481 
482 module_i2c_driver(adp1653_i2c_driver);
483 
484 MODULE_AUTHOR("Sakari Ailus <sakari.ailus@nokia.com>");
485 MODULE_DESCRIPTION("Analog Devices ADP1653 LED flash driver");
486 MODULE_LICENSE("GPL");
487