2 * drivers/media/video/adp1653.c
4 * Copyright (C) 2008--2011 Nokia Corporation
6 * Contact: Sakari Ailus <sakari.ailus@maxwell.research.nokia.com>
9 * Sakari Ailus <sakari.ailus@maxwell.research.nokia.com>
10 * Tuukka Toivonen <tuukkat76@gmail.com>
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.
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.
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
27 * - fault interrupt handling
29 * - power doesn't need to be ON if all lights are off
33 #include <linux/delay.h>
34 #include <linux/module.h>
35 #include <linux/i2c.h>
36 #include <linux/slab.h>
37 #include <linux/version.h>
38 #include <media/adp1653.h>
39 #include <media/v4l2-device.h>
41 #define TIMEOUT_MAX 820000
42 #define TIMEOUT_STEP 54600
43 #define TIMEOUT_MIN (TIMEOUT_MAX - ADP1653_REG_CONFIG_TMR_SET_MAX \
45 #define TIMEOUT_US_TO_CODE(t) ((TIMEOUT_MAX + (TIMEOUT_STEP / 2) - (t)) \
47 #define TIMEOUT_CODE_TO_US(c) (TIMEOUT_MAX - (c) * TIMEOUT_STEP)
49 /* Write values into ADP1653 registers. */
50 static int adp1653_update_hw(struct adp1653_flash
*flash
)
52 struct i2c_client
*client
= v4l2_get_subdevdata(&flash
->subdev
);
57 out_sel
= ADP1653_INDICATOR_INTENSITY_uA_TO_REG(
58 flash
->indicator_intensity
->val
)
59 << ADP1653_REG_OUT_SEL_ILED_SHIFT
;
61 switch (flash
->led_mode
->val
) {
62 case V4L2_FLASH_LED_MODE_NONE
:
64 case V4L2_FLASH_LED_MODE_FLASH
:
65 /* Flash mode, light on with strobe, duration from timer */
66 config
= ADP1653_REG_CONFIG_TMR_CFG
;
67 config
|= TIMEOUT_US_TO_CODE(flash
->flash_timeout
->val
)
68 << ADP1653_REG_CONFIG_TMR_SET_SHIFT
;
70 case V4L2_FLASH_LED_MODE_TORCH
:
71 /* Torch mode, light immediately on, duration indefinite */
72 out_sel
|= ADP1653_FLASH_INTENSITY_mA_TO_REG(
73 flash
->torch_intensity
->val
)
74 << ADP1653_REG_OUT_SEL_HPLED_SHIFT
;
78 rval
= i2c_smbus_write_byte_data(client
, ADP1653_REG_OUT_SEL
, out_sel
);
82 rval
= i2c_smbus_write_byte_data(client
, ADP1653_REG_CONFIG
, config
);
89 static int adp1653_get_fault(struct adp1653_flash
*flash
)
91 struct i2c_client
*client
= v4l2_get_subdevdata(&flash
->subdev
);
95 fault
= i2c_smbus_read_byte_data(client
, ADP1653_REG_FAULT
);
96 if (IS_ERR_VALUE(fault
))
99 flash
->fault
|= fault
;
105 rval
= i2c_smbus_write_byte_data(client
, ADP1653_REG_OUT_SEL
, 0);
106 if (IS_ERR_VALUE(rval
))
109 flash
->led_mode
->val
= V4L2_FLASH_LED_MODE_NONE
;
111 rval
= adp1653_update_hw(flash
);
112 if (IS_ERR_VALUE(rval
))
118 static int adp1653_strobe(struct adp1653_flash
*flash
, int enable
)
120 struct i2c_client
*client
= v4l2_get_subdevdata(&flash
->subdev
);
121 u8 out_sel
= ADP1653_INDICATOR_INTENSITY_uA_TO_REG(
122 flash
->indicator_intensity
->val
)
123 << ADP1653_REG_OUT_SEL_ILED_SHIFT
;
126 if (flash
->led_mode
->val
!= V4L2_FLASH_LED_MODE_FLASH
)
130 return i2c_smbus_write_byte_data(client
, ADP1653_REG_OUT_SEL
,
133 out_sel
|= ADP1653_FLASH_INTENSITY_mA_TO_REG(
134 flash
->flash_intensity
->val
)
135 << ADP1653_REG_OUT_SEL_HPLED_SHIFT
;
136 rval
= i2c_smbus_write_byte_data(client
, ADP1653_REG_OUT_SEL
, out_sel
);
140 /* Software strobe using i2c */
141 rval
= i2c_smbus_write_byte_data(client
, ADP1653_REG_SW_STROBE
,
142 ADP1653_REG_SW_STROBE_SW_STROBE
);
145 return i2c_smbus_write_byte_data(client
, ADP1653_REG_SW_STROBE
, 0);
148 /* --------------------------------------------------------------------------
152 static int adp1653_get_ctrl(struct v4l2_ctrl
*ctrl
)
154 struct adp1653_flash
*flash
=
155 container_of(ctrl
->handler
, struct adp1653_flash
, ctrls
);
158 rval
= adp1653_get_fault(flash
);
159 if (IS_ERR_VALUE(rval
))
164 if (flash
->fault
& ADP1653_REG_FAULT_FLT_SCP
)
165 ctrl
->cur
.val
|= V4L2_FLASH_FAULT_SHORT_CIRCUIT
;
166 if (flash
->fault
& ADP1653_REG_FAULT_FLT_OT
)
167 ctrl
->cur
.val
|= V4L2_FLASH_FAULT_OVER_TEMPERATURE
;
168 if (flash
->fault
& ADP1653_REG_FAULT_FLT_TMR
)
169 ctrl
->cur
.val
|= V4L2_FLASH_FAULT_TIMEOUT
;
170 if (flash
->fault
& ADP1653_REG_FAULT_FLT_OV
)
171 ctrl
->cur
.val
|= V4L2_FLASH_FAULT_OVER_VOLTAGE
;
178 static int adp1653_set_ctrl(struct v4l2_ctrl
*ctrl
)
180 struct adp1653_flash
*flash
=
181 container_of(ctrl
->handler
, struct adp1653_flash
, ctrls
);
184 rval
= adp1653_get_fault(flash
);
185 if (IS_ERR_VALUE(rval
))
187 if ((rval
& (ADP1653_REG_FAULT_FLT_SCP
|
188 ADP1653_REG_FAULT_FLT_OT
|
189 ADP1653_REG_FAULT_FLT_OV
)) &&
190 (ctrl
->id
== V4L2_CID_FLASH_STROBE
||
191 ctrl
->id
== V4L2_CID_FLASH_TORCH_INTENSITY
||
192 ctrl
->id
== V4L2_CID_FLASH_LED_MODE
))
196 case V4L2_CID_FLASH_STROBE
:
197 return adp1653_strobe(flash
, 1);
198 case V4L2_CID_FLASH_STROBE_STOP
:
199 return adp1653_strobe(flash
, 0);
202 return adp1653_update_hw(flash
);
205 static const struct v4l2_ctrl_ops adp1653_ctrl_ops
= {
206 .g_volatile_ctrl
= adp1653_get_ctrl
,
207 .s_ctrl
= adp1653_set_ctrl
,
210 static int adp1653_init_controls(struct adp1653_flash
*flash
)
212 struct v4l2_ctrl
*fault
;
214 v4l2_ctrl_handler_init(&flash
->ctrls
, 9);
217 v4l2_ctrl_new_std_menu(&flash
->ctrls
, &adp1653_ctrl_ops
,
218 V4L2_CID_FLASH_LED_MODE
,
219 V4L2_FLASH_LED_MODE_TORCH
, ~0x7, 0);
220 v4l2_ctrl_new_std_menu(&flash
->ctrls
, &adp1653_ctrl_ops
,
221 V4L2_CID_FLASH_STROBE_SOURCE
,
222 V4L2_FLASH_STROBE_SOURCE_SOFTWARE
, ~0x1, 0);
223 v4l2_ctrl_new_std(&flash
->ctrls
, &adp1653_ctrl_ops
,
224 V4L2_CID_FLASH_STROBE
, 0, 0, 0, 0);
225 v4l2_ctrl_new_std(&flash
->ctrls
, &adp1653_ctrl_ops
,
226 V4L2_CID_FLASH_STROBE_STOP
, 0, 0, 0, 0);
227 flash
->flash_timeout
=
228 v4l2_ctrl_new_std(&flash
->ctrls
, &adp1653_ctrl_ops
,
229 V4L2_CID_FLASH_TIMEOUT
, TIMEOUT_MIN
,
230 flash
->platform_data
->max_flash_timeout
,
232 flash
->platform_data
->max_flash_timeout
);
233 flash
->flash_intensity
=
234 v4l2_ctrl_new_std(&flash
->ctrls
, &adp1653_ctrl_ops
,
235 V4L2_CID_FLASH_INTENSITY
,
236 ADP1653_FLASH_INTENSITY_MIN
,
237 flash
->platform_data
->max_flash_intensity
,
238 1, flash
->platform_data
->max_flash_intensity
);
239 flash
->torch_intensity
=
240 v4l2_ctrl_new_std(&flash
->ctrls
, &adp1653_ctrl_ops
,
241 V4L2_CID_FLASH_TORCH_INTENSITY
,
242 ADP1653_TORCH_INTENSITY_MIN
,
243 flash
->platform_data
->max_torch_intensity
,
244 ADP1653_FLASH_INTENSITY_STEP
,
245 flash
->platform_data
->max_torch_intensity
);
246 flash
->indicator_intensity
=
247 v4l2_ctrl_new_std(&flash
->ctrls
, &adp1653_ctrl_ops
,
248 V4L2_CID_FLASH_INDICATOR_INTENSITY
,
249 ADP1653_INDICATOR_INTENSITY_MIN
,
250 flash
->platform_data
->max_indicator_intensity
,
251 ADP1653_INDICATOR_INTENSITY_STEP
,
252 ADP1653_INDICATOR_INTENSITY_MIN
);
253 fault
= v4l2_ctrl_new_std(&flash
->ctrls
, &adp1653_ctrl_ops
,
254 V4L2_CID_FLASH_FAULT
, 0,
255 V4L2_FLASH_FAULT_OVER_VOLTAGE
256 | V4L2_FLASH_FAULT_OVER_TEMPERATURE
257 | V4L2_FLASH_FAULT_SHORT_CIRCUIT
, 0, 0);
259 if (flash
->ctrls
.error
)
260 return flash
->ctrls
.error
;
262 fault
->is_volatile
= 1;
264 flash
->subdev
.ctrl_handler
= &flash
->ctrls
;
268 /* --------------------------------------------------------------------------
269 * V4L2 subdev operations
273 adp1653_init_device(struct adp1653_flash
*flash
)
275 struct i2c_client
*client
= v4l2_get_subdevdata(&flash
->subdev
);
278 /* Clear FAULT register by writing zero to OUT_SEL */
279 rval
= i2c_smbus_write_byte_data(client
, ADP1653_REG_OUT_SEL
, 0);
281 dev_err(&client
->dev
, "failed writing fault register\n");
285 mutex_lock(&flash
->ctrls
.lock
);
286 /* Reset faults before reading new ones. */
288 rval
= adp1653_get_fault(flash
);
289 mutex_unlock(&flash
->ctrls
.lock
);
291 dev_err(&client
->dev
, "faults detected: 0x%1.1x\n", rval
);
295 mutex_lock(&flash
->ctrls
.lock
);
296 rval
= adp1653_update_hw(flash
);
297 mutex_unlock(&flash
->ctrls
.lock
);
299 dev_err(&client
->dev
,
300 "adp1653_update_hw failed at %s\n", __func__
);
308 __adp1653_set_power(struct adp1653_flash
*flash
, int on
)
312 ret
= flash
->platform_data
->power(&flash
->subdev
, on
);
319 ret
= adp1653_init_device(flash
);
321 flash
->platform_data
->power(&flash
->subdev
, 0);
327 adp1653_set_power(struct v4l2_subdev
*subdev
, int on
)
329 struct adp1653_flash
*flash
= to_adp1653_flash(subdev
);
332 mutex_lock(&flash
->power_lock
);
334 /* If the power count is modified from 0 to != 0 or from != 0 to 0,
335 * update the power state.
337 if (flash
->power_count
== !on
) {
338 ret
= __adp1653_set_power(flash
, !!on
);
343 /* Update the power count. */
344 flash
->power_count
+= on
? 1 : -1;
345 WARN_ON(flash
->power_count
< 0);
348 mutex_unlock(&flash
->power_lock
);
352 static int adp1653_open(struct v4l2_subdev
*sd
, struct v4l2_subdev_fh
*fh
)
354 return adp1653_set_power(sd
, 1);
357 static int adp1653_close(struct v4l2_subdev
*sd
, struct v4l2_subdev_fh
*fh
)
359 return adp1653_set_power(sd
, 0);
362 static const struct v4l2_subdev_core_ops adp1653_core_ops
= {
363 .s_power
= adp1653_set_power
,
366 static const struct v4l2_subdev_ops adp1653_ops
= {
367 .core
= &adp1653_core_ops
,
370 static const struct v4l2_subdev_internal_ops adp1653_internal_ops
= {
371 .open
= adp1653_open
,
372 .close
= adp1653_close
,
375 /* --------------------------------------------------------------------------
380 static int adp1653_suspend(struct device
*dev
)
382 struct i2c_client
*client
= to_i2c_client(dev
);
383 struct v4l2_subdev
*subdev
= i2c_get_clientdata(client
);
384 struct adp1653_flash
*flash
= to_adp1653_flash(subdev
);
386 if (!flash
->power_count
)
389 return __adp1653_set_power(flash
, 0);
392 static int adp1653_resume(struct device
*dev
)
394 struct i2c_client
*client
= to_i2c_client(dev
);
395 struct v4l2_subdev
*subdev
= i2c_get_clientdata(client
);
396 struct adp1653_flash
*flash
= to_adp1653_flash(subdev
);
398 if (!flash
->power_count
)
401 return __adp1653_set_power(flash
, 1);
406 #define adp1653_suspend NULL
407 #define adp1653_resume NULL
409 #endif /* CONFIG_PM */
411 static int adp1653_probe(struct i2c_client
*client
,
412 const struct i2c_device_id
*devid
)
414 struct adp1653_flash
*flash
;
417 flash
= kzalloc(sizeof(*flash
), GFP_KERNEL
);
421 flash
->platform_data
= client
->dev
.platform_data
;
423 mutex_init(&flash
->power_lock
);
425 v4l2_i2c_subdev_init(&flash
->subdev
, client
, &adp1653_ops
);
426 flash
->subdev
.internal_ops
= &adp1653_internal_ops
;
427 flash
->subdev
.flags
|= V4L2_SUBDEV_FL_HAS_DEVNODE
;
429 adp1653_init_controls(flash
);
431 ret
= media_entity_init(&flash
->subdev
.entity
, 0, NULL
, 0);
438 static int __exit
adp1653_remove(struct i2c_client
*client
)
440 struct v4l2_subdev
*subdev
= i2c_get_clientdata(client
);
441 struct adp1653_flash
*flash
= to_adp1653_flash(subdev
);
443 v4l2_device_unregister_subdev(&flash
->subdev
);
444 v4l2_ctrl_handler_free(&flash
->ctrls
);
445 media_entity_cleanup(&flash
->subdev
.entity
);
450 static const struct i2c_device_id adp1653_id_table
[] = {
454 MODULE_DEVICE_TABLE(i2c
, adp1653_id_table
);
456 static struct dev_pm_ops adp1653_pm_ops
= {
457 .suspend
= adp1653_suspend
,
458 .resume
= adp1653_resume
,
461 static struct i2c_driver adp1653_i2c_driver
= {
463 .name
= ADP1653_NAME
,
464 .pm
= &adp1653_pm_ops
,
466 .probe
= adp1653_probe
,
467 .remove
= __exit_p(adp1653_remove
),
468 .id_table
= adp1653_id_table
,
471 static int __init
adp1653_init(void)
475 rval
= i2c_add_driver(&adp1653_i2c_driver
);
477 printk(KERN_ALERT
"%s: failed at i2c_add_driver\n", __func__
);
482 static void __exit
adp1653_exit(void)
484 i2c_del_driver(&adp1653_i2c_driver
);
487 module_init(adp1653_init
);
488 module_exit(adp1653_exit
);
490 MODULE_AUTHOR("Sakari Ailus <sakari.ailus@nokia.com>");
491 MODULE_DESCRIPTION("Analog Devices ADP1653 LED flash driver");
492 MODULE_LICENSE("GPL");