Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
adp1653.c
Go to the documentation of this file.
1 /*
2  * drivers/media/i2c/adp1653.c
3  *
4  * Copyright (C) 2008--2011 Nokia Corporation
5  *
6  * Contact: Sakari Ailus <[email protected]>
7  *
8  * Contributors:
9  * Sakari Ailus <[email protected]>
10  * Tuukka Toivonen <[email protected]>
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 
57  flash->indicator_intensity->val)
59 
60  switch (flash->led_mode->val) {
62  break;
64  /* Flash mode, light on with strobe, duration from timer */
66  config |= TIMEOUT_US_TO_CODE(flash->flash_timeout->val)
68  break;
70  /* Torch mode, light immediately on, duration indefinite */
72  flash->torch_intensity->val)
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 
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. */
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);
121  flash->indicator_intensity->val)
123  int rval;
124 
125  if (flash->led_mode->val != V4L2_FLASH_LED_MODE_FLASH)
126  return -EBUSY;
127 
128  if (!enable)
130  out_sel);
131 
133  flash->flash_intensity->val)
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 */
142  if (rval)
143  return rval;
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)
165  if (flash->fault & ADP1653_REG_FAULT_FLT_OT)
167  if (flash->fault & ADP1653_REG_FAULT_FLT_TMR)
169  if (flash->fault & ADP1653_REG_FAULT_FLT_OV)
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 |
189  (ctrl->id == V4L2_CID_FLASH_STROBE ||
191  ctrl->id == V4L2_CID_FLASH_LED_MODE))
192  return -EBUSY;
193 
194  switch (ctrl->id) {
196  return adp1653_strobe(flash, 1);
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,
218  V4L2_FLASH_LED_MODE_TORCH, ~0x7, 0);
219  v4l2_ctrl_new_std_menu(&flash->ctrls, &adp1653_ctrl_ops,
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,
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,
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,
242  flash->platform_data->max_torch_intensity,
244  flash->platform_data->max_torch_intensity);
245  flash->indicator_intensity =
246  v4l2_ctrl_new_std(&flash->ctrls, &adp1653_ctrl_ops,
249  flash->platform_data->max_indicator_intensity,
252  fault = v4l2_ctrl_new_std(&flash->ctrls, &adp1653_ctrl_ops,
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 */
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 = kzalloc(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  kfree(flash);
447  return ret;
448 }
449 
450 static int __exit adp1653_remove(struct i2c_client *client)
451 {
452  struct v4l2_subdev *subdev = i2c_get_clientdata(client);
453  struct adp1653_flash *flash = to_adp1653_flash(subdev);
454 
456  v4l2_ctrl_handler_free(&flash->ctrls);
457  media_entity_cleanup(&flash->subdev.entity);
458  kfree(flash);
459  return 0;
460 }
461 
462 static const struct i2c_device_id adp1653_id_table[] = {
463  { ADP1653_NAME, 0 },
464  { }
465 };
466 MODULE_DEVICE_TABLE(i2c, adp1653_id_table);
467 
468 static struct dev_pm_ops adp1653_pm_ops = {
469  .suspend = adp1653_suspend,
470  .resume = adp1653_resume,
471 };
472 
473 static struct i2c_driver adp1653_i2c_driver = {
474  .driver = {
475  .name = ADP1653_NAME,
476  .pm = &adp1653_pm_ops,
477  },
478  .probe = adp1653_probe,
479  .remove = __exit_p(adp1653_remove),
480  .id_table = adp1653_id_table,
481 };
482 
483 module_i2c_driver(adp1653_i2c_driver);
484 
485 MODULE_AUTHOR("Sakari Ailus <[email protected]>");
486 MODULE_DESCRIPTION("Analog Devices ADP1653 LED flash driver");
487 MODULE_LICENSE("GPL");