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/module.h>
37 #include <linux/slab.h>
38 #include <linux/version.h>
39 #include <media/adp1653.h>
40 #include <media/v4l2-device.h>
42 #define TIMEOUT_MAX 820000
43 #define TIMEOUT_STEP 54600
44 #define TIMEOUT_MIN (TIMEOUT_MAX - ADP1653_REG_CONFIG_TMR_SET_MAX \
46 #define TIMEOUT_US_TO_CODE(t) ((TIMEOUT_MAX + (TIMEOUT_STEP / 2) - (t)) \
48 #define TIMEOUT_CODE_TO_US(c) (TIMEOUT_MAX - (c) * TIMEOUT_STEP)
50 /* Write values into ADP1653 registers. */
51 static int adp1653_update_hw(struct adp1653_flash
*flash
)
53 struct i2c_client
*client
= v4l2_get_subdevdata(&flash
->subdev
);
58 out_sel
= ADP1653_INDICATOR_INTENSITY_uA_TO_REG(
59 flash
->indicator_intensity
->val
)
60 << ADP1653_REG_OUT_SEL_ILED_SHIFT
;
62 switch (flash
->led_mode
->val
) {
63 case V4L2_FLASH_LED_MODE_NONE
:
65 case V4L2_FLASH_LED_MODE_FLASH
:
66 /* Flash mode, light on with strobe, duration from timer */
67 config
= ADP1653_REG_CONFIG_TMR_CFG
;
68 config
|= TIMEOUT_US_TO_CODE(flash
->flash_timeout
->val
)
69 << ADP1653_REG_CONFIG_TMR_SET_SHIFT
;
71 case V4L2_FLASH_LED_MODE_TORCH
:
72 /* Torch mode, light immediately on, duration indefinite */
73 out_sel
|= ADP1653_FLASH_INTENSITY_mA_TO_REG(
74 flash
->torch_intensity
->val
)
75 << ADP1653_REG_OUT_SEL_HPLED_SHIFT
;
79 rval
= i2c_smbus_write_byte_data(client
, ADP1653_REG_OUT_SEL
, out_sel
);
83 rval
= i2c_smbus_write_byte_data(client
, ADP1653_REG_CONFIG
, config
);
90 static int adp1653_get_fault(struct adp1653_flash
*flash
)
92 struct i2c_client
*client
= v4l2_get_subdevdata(&flash
->subdev
);
96 fault
= i2c_smbus_read_byte_data(client
, ADP1653_REG_FAULT
);
97 if (IS_ERR_VALUE(fault
))
100 flash
->fault
|= fault
;
106 rval
= i2c_smbus_write_byte_data(client
, ADP1653_REG_OUT_SEL
, 0);
107 if (IS_ERR_VALUE(rval
))
110 flash
->led_mode
->val
= V4L2_FLASH_LED_MODE_NONE
;
112 rval
= adp1653_update_hw(flash
);
113 if (IS_ERR_VALUE(rval
))
119 static int adp1653_strobe(struct adp1653_flash
*flash
, int enable
)
121 struct i2c_client
*client
= v4l2_get_subdevdata(&flash
->subdev
);
122 u8 out_sel
= ADP1653_INDICATOR_INTENSITY_uA_TO_REG(
123 flash
->indicator_intensity
->val
)
124 << ADP1653_REG_OUT_SEL_ILED_SHIFT
;
127 if (flash
->led_mode
->val
!= V4L2_FLASH_LED_MODE_FLASH
)
131 return i2c_smbus_write_byte_data(client
, ADP1653_REG_OUT_SEL
,
134 out_sel
|= ADP1653_FLASH_INTENSITY_mA_TO_REG(
135 flash
->flash_intensity
->val
)
136 << ADP1653_REG_OUT_SEL_HPLED_SHIFT
;
137 rval
= i2c_smbus_write_byte_data(client
, ADP1653_REG_OUT_SEL
, out_sel
);
141 /* Software strobe using i2c */
142 rval
= i2c_smbus_write_byte_data(client
, ADP1653_REG_SW_STROBE
,
143 ADP1653_REG_SW_STROBE_SW_STROBE
);
146 return i2c_smbus_write_byte_data(client
, ADP1653_REG_SW_STROBE
, 0);
149 /* --------------------------------------------------------------------------
153 static int adp1653_get_ctrl(struct v4l2_ctrl
*ctrl
)
155 struct adp1653_flash
*flash
=
156 container_of(ctrl
->handler
, struct adp1653_flash
, ctrls
);
159 rval
= adp1653_get_fault(flash
);
160 if (IS_ERR_VALUE(rval
))
165 if (flash
->fault
& ADP1653_REG_FAULT_FLT_SCP
)
166 ctrl
->cur
.val
|= V4L2_FLASH_FAULT_SHORT_CIRCUIT
;
167 if (flash
->fault
& ADP1653_REG_FAULT_FLT_OT
)
168 ctrl
->cur
.val
|= V4L2_FLASH_FAULT_OVER_TEMPERATURE
;
169 if (flash
->fault
& ADP1653_REG_FAULT_FLT_TMR
)
170 ctrl
->cur
.val
|= V4L2_FLASH_FAULT_TIMEOUT
;
171 if (flash
->fault
& ADP1653_REG_FAULT_FLT_OV
)
172 ctrl
->cur
.val
|= V4L2_FLASH_FAULT_OVER_VOLTAGE
;
179 static int adp1653_set_ctrl(struct v4l2_ctrl
*ctrl
)
181 struct adp1653_flash
*flash
=
182 container_of(ctrl
->handler
, struct adp1653_flash
, ctrls
);
185 rval
= adp1653_get_fault(flash
);
186 if (IS_ERR_VALUE(rval
))
188 if ((rval
& (ADP1653_REG_FAULT_FLT_SCP
|
189 ADP1653_REG_FAULT_FLT_OT
|
190 ADP1653_REG_FAULT_FLT_OV
)) &&
191 (ctrl
->id
== V4L2_CID_FLASH_STROBE
||
192 ctrl
->id
== V4L2_CID_FLASH_TORCH_INTENSITY
||
193 ctrl
->id
== V4L2_CID_FLASH_LED_MODE
))
197 case V4L2_CID_FLASH_STROBE
:
198 return adp1653_strobe(flash
, 1);
199 case V4L2_CID_FLASH_STROBE_STOP
:
200 return adp1653_strobe(flash
, 0);
203 return adp1653_update_hw(flash
);
206 static const struct v4l2_ctrl_ops adp1653_ctrl_ops
= {
207 .g_volatile_ctrl
= adp1653_get_ctrl
,
208 .s_ctrl
= adp1653_set_ctrl
,
211 static int adp1653_init_controls(struct adp1653_flash
*flash
)
213 struct v4l2_ctrl
*fault
;
215 v4l2_ctrl_handler_init(&flash
->ctrls
, 9);
218 v4l2_ctrl_new_std_menu(&flash
->ctrls
, &adp1653_ctrl_ops
,
219 V4L2_CID_FLASH_LED_MODE
,
220 V4L2_FLASH_LED_MODE_TORCH
, ~0x7, 0);
221 v4l2_ctrl_new_std_menu(&flash
->ctrls
, &adp1653_ctrl_ops
,
222 V4L2_CID_FLASH_STROBE_SOURCE
,
223 V4L2_FLASH_STROBE_SOURCE_SOFTWARE
, ~0x1, 0);
224 v4l2_ctrl_new_std(&flash
->ctrls
, &adp1653_ctrl_ops
,
225 V4L2_CID_FLASH_STROBE
, 0, 0, 0, 0);
226 v4l2_ctrl_new_std(&flash
->ctrls
, &adp1653_ctrl_ops
,
227 V4L2_CID_FLASH_STROBE_STOP
, 0, 0, 0, 0);
228 flash
->flash_timeout
=
229 v4l2_ctrl_new_std(&flash
->ctrls
, &adp1653_ctrl_ops
,
230 V4L2_CID_FLASH_TIMEOUT
, TIMEOUT_MIN
,
231 flash
->platform_data
->max_flash_timeout
,
233 flash
->platform_data
->max_flash_timeout
);
234 flash
->flash_intensity
=
235 v4l2_ctrl_new_std(&flash
->ctrls
, &adp1653_ctrl_ops
,
236 V4L2_CID_FLASH_INTENSITY
,
237 ADP1653_FLASH_INTENSITY_MIN
,
238 flash
->platform_data
->max_flash_intensity
,
239 1, flash
->platform_data
->max_flash_intensity
);
240 flash
->torch_intensity
=
241 v4l2_ctrl_new_std(&flash
->ctrls
, &adp1653_ctrl_ops
,
242 V4L2_CID_FLASH_TORCH_INTENSITY
,
243 ADP1653_TORCH_INTENSITY_MIN
,
244 flash
->platform_data
->max_torch_intensity
,
245 ADP1653_FLASH_INTENSITY_STEP
,
246 flash
->platform_data
->max_torch_intensity
);
247 flash
->indicator_intensity
=
248 v4l2_ctrl_new_std(&flash
->ctrls
, &adp1653_ctrl_ops
,
249 V4L2_CID_FLASH_INDICATOR_INTENSITY
,
250 ADP1653_INDICATOR_INTENSITY_MIN
,
251 flash
->platform_data
->max_indicator_intensity
,
252 ADP1653_INDICATOR_INTENSITY_STEP
,
253 ADP1653_INDICATOR_INTENSITY_MIN
);
254 fault
= v4l2_ctrl_new_std(&flash
->ctrls
, &adp1653_ctrl_ops
,
255 V4L2_CID_FLASH_FAULT
, 0,
256 V4L2_FLASH_FAULT_OVER_VOLTAGE
257 | V4L2_FLASH_FAULT_OVER_TEMPERATURE
258 | V4L2_FLASH_FAULT_SHORT_CIRCUIT
, 0, 0);
260 if (flash
->ctrls
.error
)
261 return flash
->ctrls
.error
;
263 fault
->flags
|= V4L2_CTRL_FLAG_VOLATILE
;
265 flash
->subdev
.ctrl_handler
= &flash
->ctrls
;
269 /* --------------------------------------------------------------------------
270 * V4L2 subdev operations
274 adp1653_init_device(struct adp1653_flash
*flash
)
276 struct i2c_client
*client
= v4l2_get_subdevdata(&flash
->subdev
);
279 /* Clear FAULT register by writing zero to OUT_SEL */
280 rval
= i2c_smbus_write_byte_data(client
, ADP1653_REG_OUT_SEL
, 0);
282 dev_err(&client
->dev
, "failed writing fault register\n");
286 mutex_lock(&flash
->ctrls
.lock
);
287 /* Reset faults before reading new ones. */
289 rval
= adp1653_get_fault(flash
);
290 mutex_unlock(&flash
->ctrls
.lock
);
292 dev_err(&client
->dev
, "faults detected: 0x%1.1x\n", rval
);
296 mutex_lock(&flash
->ctrls
.lock
);
297 rval
= adp1653_update_hw(flash
);
298 mutex_unlock(&flash
->ctrls
.lock
);
300 dev_err(&client
->dev
,
301 "adp1653_update_hw failed at %s\n", __func__
);
309 __adp1653_set_power(struct adp1653_flash
*flash
, int on
)
313 ret
= flash
->platform_data
->power(&flash
->subdev
, on
);
320 ret
= adp1653_init_device(flash
);
322 flash
->platform_data
->power(&flash
->subdev
, 0);
328 adp1653_set_power(struct v4l2_subdev
*subdev
, int on
)
330 struct adp1653_flash
*flash
= to_adp1653_flash(subdev
);
333 mutex_lock(&flash
->power_lock
);
335 /* If the power count is modified from 0 to != 0 or from != 0 to 0,
336 * update the power state.
338 if (flash
->power_count
== !on
) {
339 ret
= __adp1653_set_power(flash
, !!on
);
344 /* Update the power count. */
345 flash
->power_count
+= on
? 1 : -1;
346 WARN_ON(flash
->power_count
< 0);
349 mutex_unlock(&flash
->power_lock
);
353 static int adp1653_open(struct v4l2_subdev
*sd
, struct v4l2_subdev_fh
*fh
)
355 return adp1653_set_power(sd
, 1);
358 static int adp1653_close(struct v4l2_subdev
*sd
, struct v4l2_subdev_fh
*fh
)
360 return adp1653_set_power(sd
, 0);
363 static const struct v4l2_subdev_core_ops adp1653_core_ops
= {
364 .s_power
= adp1653_set_power
,
367 static const struct v4l2_subdev_ops adp1653_ops
= {
368 .core
= &adp1653_core_ops
,
371 static const struct v4l2_subdev_internal_ops adp1653_internal_ops
= {
372 .open
= adp1653_open
,
373 .close
= adp1653_close
,
376 /* --------------------------------------------------------------------------
381 static int adp1653_suspend(struct device
*dev
)
383 struct i2c_client
*client
= to_i2c_client(dev
);
384 struct v4l2_subdev
*subdev
= i2c_get_clientdata(client
);
385 struct adp1653_flash
*flash
= to_adp1653_flash(subdev
);
387 if (!flash
->power_count
)
390 return __adp1653_set_power(flash
, 0);
393 static int adp1653_resume(struct device
*dev
)
395 struct i2c_client
*client
= to_i2c_client(dev
);
396 struct v4l2_subdev
*subdev
= i2c_get_clientdata(client
);
397 struct adp1653_flash
*flash
= to_adp1653_flash(subdev
);
399 if (!flash
->power_count
)
402 return __adp1653_set_power(flash
, 1);
407 #define adp1653_suspend NULL
408 #define adp1653_resume NULL
410 #endif /* CONFIG_PM */
412 static int adp1653_probe(struct i2c_client
*client
,
413 const struct i2c_device_id
*devid
)
415 struct adp1653_flash
*flash
;
418 /* we couldn't work without platform data */
419 if (client
->dev
.platform_data
== NULL
)
422 flash
= kzalloc(sizeof(*flash
), GFP_KERNEL
);
426 flash
->platform_data
= client
->dev
.platform_data
;
428 mutex_init(&flash
->power_lock
);
430 v4l2_i2c_subdev_init(&flash
->subdev
, client
, &adp1653_ops
);
431 flash
->subdev
.internal_ops
= &adp1653_internal_ops
;
432 flash
->subdev
.flags
|= V4L2_SUBDEV_FL_HAS_DEVNODE
;
434 ret
= adp1653_init_controls(flash
);
438 ret
= media_entity_init(&flash
->subdev
.entity
, 0, NULL
, 0);
442 flash
->subdev
.entity
.type
= MEDIA_ENT_T_V4L2_SUBDEV_FLASH
;
447 v4l2_ctrl_handler_free(&flash
->ctrls
);
452 static int __exit
adp1653_remove(struct i2c_client
*client
)
454 struct v4l2_subdev
*subdev
= i2c_get_clientdata(client
);
455 struct adp1653_flash
*flash
= to_adp1653_flash(subdev
);
457 v4l2_device_unregister_subdev(&flash
->subdev
);
458 v4l2_ctrl_handler_free(&flash
->ctrls
);
459 media_entity_cleanup(&flash
->subdev
.entity
);
464 static const struct i2c_device_id adp1653_id_table
[] = {
468 MODULE_DEVICE_TABLE(i2c
, adp1653_id_table
);
470 static struct dev_pm_ops adp1653_pm_ops
= {
471 .suspend
= adp1653_suspend
,
472 .resume
= adp1653_resume
,
475 static struct i2c_driver adp1653_i2c_driver
= {
477 .name
= ADP1653_NAME
,
478 .pm
= &adp1653_pm_ops
,
480 .probe
= adp1653_probe
,
481 .remove
= __exit_p(adp1653_remove
),
482 .id_table
= adp1653_id_table
,
485 static int __init
adp1653_init(void)
489 rval
= i2c_add_driver(&adp1653_i2c_driver
);
491 printk(KERN_ALERT
"%s: failed at i2c_add_driver\n", __func__
);
496 static void __exit
adp1653_exit(void)
498 i2c_del_driver(&adp1653_i2c_driver
);
501 module_init(adp1653_init
);
502 module_exit(adp1653_exit
);
504 MODULE_AUTHOR("Sakari Ailus <sakari.ailus@nokia.com>");
505 MODULE_DESCRIPTION("Analog Devices ADP1653 LED flash driver");
506 MODULE_LICENSE("GPL");