blob: e191e295c95116e311fc226f64dc850b6a4ba196 [file] [log] [blame]
Sakari Ailus13abada2011-05-05 15:39:25 -03001/*
Mauro Carvalho Chehabcb7a01a2012-08-14 16:23:43 -03002 * drivers/media/i2c/adp1653.c
Sakari Ailus13abada2011-05-05 15:39:25 -03003 *
4 * Copyright (C) 2008--2011 Nokia Corporation
5 *
Sakari Ailus8c5dff92012-10-28 06:44:17 -03006 * Contact: Sakari Ailus <sakari.ailus@iki.fi>
Sakari Ailus13abada2011-05-05 15:39:25 -03007 *
8 * Contributors:
Sakari Ailus8c5dff92012-10-28 06:44:17 -03009 * Sakari Ailus <sakari.ailus@iki.fi>
Sakari Ailus13abada2011-05-05 15:39:25 -030010 * Tuukka Toivonen <tuukkat76@gmail.com>
Pavel Machek074c57a2015-04-09 04:42:38 -030011 * Pavel Machek <pavel@ucw.cz>
Sakari Ailus13abada2011-05-05 15:39:25 -030012 *
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * version 2 as published by the Free Software Foundation.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
25 * 02110-1301 USA
26 *
27 * TODO:
28 * - fault interrupt handling
29 * - hardware strobe
30 * - power doesn't need to be ON if all lights are off
31 *
32 */
33
34#include <linux/delay.h>
Paul Gortmaker7a707b82011-07-03 14:03:12 -040035#include <linux/module.h>
Sakari Ailus13abada2011-05-05 15:39:25 -030036#include <linux/i2c.h>
37#include <linux/slab.h>
Pavel Machek074c57a2015-04-09 04:42:38 -030038#include <linux/of.h>
39#include <linux/gpio/consumer.h>
Mauro Carvalho Chehabb5dcee22015-11-10 12:01:44 -020040#include <media/i2c/adp1653.h>
Sakari Ailus13abada2011-05-05 15:39:25 -030041#include <media/v4l2-device.h>
42
43#define TIMEOUT_MAX 820000
44#define TIMEOUT_STEP 54600
45#define TIMEOUT_MIN (TIMEOUT_MAX - ADP1653_REG_CONFIG_TMR_SET_MAX \
46 * TIMEOUT_STEP)
47#define TIMEOUT_US_TO_CODE(t) ((TIMEOUT_MAX + (TIMEOUT_STEP / 2) - (t)) \
48 / TIMEOUT_STEP)
49#define TIMEOUT_CODE_TO_US(c) (TIMEOUT_MAX - (c) * TIMEOUT_STEP)
50
51/* Write values into ADP1653 registers. */
52static int adp1653_update_hw(struct adp1653_flash *flash)
53{
54 struct i2c_client *client = v4l2_get_subdevdata(&flash->subdev);
55 u8 out_sel;
56 u8 config = 0;
57 int rval;
58
59 out_sel = ADP1653_INDICATOR_INTENSITY_uA_TO_REG(
60 flash->indicator_intensity->val)
61 << ADP1653_REG_OUT_SEL_ILED_SHIFT;
62
63 switch (flash->led_mode->val) {
64 case V4L2_FLASH_LED_MODE_NONE:
65 break;
66 case V4L2_FLASH_LED_MODE_FLASH:
67 /* Flash mode, light on with strobe, duration from timer */
68 config = ADP1653_REG_CONFIG_TMR_CFG;
69 config |= TIMEOUT_US_TO_CODE(flash->flash_timeout->val)
70 << ADP1653_REG_CONFIG_TMR_SET_SHIFT;
71 break;
72 case V4L2_FLASH_LED_MODE_TORCH:
73 /* Torch mode, light immediately on, duration indefinite */
74 out_sel |= ADP1653_FLASH_INTENSITY_mA_TO_REG(
75 flash->torch_intensity->val)
76 << ADP1653_REG_OUT_SEL_HPLED_SHIFT;
77 break;
78 }
79
80 rval = i2c_smbus_write_byte_data(client, ADP1653_REG_OUT_SEL, out_sel);
81 if (rval < 0)
82 return rval;
83
84 rval = i2c_smbus_write_byte_data(client, ADP1653_REG_CONFIG, config);
85 if (rval < 0)
86 return rval;
87
88 return 0;
89}
90
91static int adp1653_get_fault(struct adp1653_flash *flash)
92{
93 struct i2c_client *client = v4l2_get_subdevdata(&flash->subdev);
94 int fault;
95 int rval;
96
97 fault = i2c_smbus_read_byte_data(client, ADP1653_REG_FAULT);
Arnd Bergmann287980e2016-05-27 23:23:25 +020098 if (fault < 0)
Sakari Ailus13abada2011-05-05 15:39:25 -030099 return fault;
100
101 flash->fault |= fault;
102
103 if (!flash->fault)
104 return 0;
105
106 /* Clear faults. */
107 rval = i2c_smbus_write_byte_data(client, ADP1653_REG_OUT_SEL, 0);
Arnd Bergmann287980e2016-05-27 23:23:25 +0200108 if (rval < 0)
Sakari Ailus13abada2011-05-05 15:39:25 -0300109 return rval;
110
111 flash->led_mode->val = V4L2_FLASH_LED_MODE_NONE;
112
113 rval = adp1653_update_hw(flash);
Arnd Bergmann287980e2016-05-27 23:23:25 +0200114 if (rval)
Sakari Ailus13abada2011-05-05 15:39:25 -0300115 return rval;
116
117 return flash->fault;
118}
119
120static int adp1653_strobe(struct adp1653_flash *flash, int enable)
121{
122 struct i2c_client *client = v4l2_get_subdevdata(&flash->subdev);
123 u8 out_sel = ADP1653_INDICATOR_INTENSITY_uA_TO_REG(
124 flash->indicator_intensity->val)
125 << ADP1653_REG_OUT_SEL_ILED_SHIFT;
126 int rval;
127
128 if (flash->led_mode->val != V4L2_FLASH_LED_MODE_FLASH)
129 return -EBUSY;
130
131 if (!enable)
132 return i2c_smbus_write_byte_data(client, ADP1653_REG_OUT_SEL,
133 out_sel);
134
135 out_sel |= ADP1653_FLASH_INTENSITY_mA_TO_REG(
136 flash->flash_intensity->val)
137 << ADP1653_REG_OUT_SEL_HPLED_SHIFT;
138 rval = i2c_smbus_write_byte_data(client, ADP1653_REG_OUT_SEL, out_sel);
139 if (rval)
140 return rval;
141
142 /* Software strobe using i2c */
143 rval = i2c_smbus_write_byte_data(client, ADP1653_REG_SW_STROBE,
144 ADP1653_REG_SW_STROBE_SW_STROBE);
145 if (rval)
146 return rval;
147 return i2c_smbus_write_byte_data(client, ADP1653_REG_SW_STROBE, 0);
148}
149
150/* --------------------------------------------------------------------------
151 * V4L2 controls
152 */
153
154static int adp1653_get_ctrl(struct v4l2_ctrl *ctrl)
155{
156 struct adp1653_flash *flash =
157 container_of(ctrl->handler, struct adp1653_flash, ctrls);
158 int rval;
159
160 rval = adp1653_get_fault(flash);
Arnd Bergmann287980e2016-05-27 23:23:25 +0200161 if (rval)
Sakari Ailus13abada2011-05-05 15:39:25 -0300162 return rval;
163
164 ctrl->cur.val = 0;
165
166 if (flash->fault & ADP1653_REG_FAULT_FLT_SCP)
167 ctrl->cur.val |= V4L2_FLASH_FAULT_SHORT_CIRCUIT;
168 if (flash->fault & ADP1653_REG_FAULT_FLT_OT)
169 ctrl->cur.val |= V4L2_FLASH_FAULT_OVER_TEMPERATURE;
170 if (flash->fault & ADP1653_REG_FAULT_FLT_TMR)
171 ctrl->cur.val |= V4L2_FLASH_FAULT_TIMEOUT;
172 if (flash->fault & ADP1653_REG_FAULT_FLT_OV)
173 ctrl->cur.val |= V4L2_FLASH_FAULT_OVER_VOLTAGE;
174
175 flash->fault = 0;
176
177 return 0;
178}
179
180static int adp1653_set_ctrl(struct v4l2_ctrl *ctrl)
181{
182 struct adp1653_flash *flash =
183 container_of(ctrl->handler, struct adp1653_flash, ctrls);
184 int rval;
185
186 rval = adp1653_get_fault(flash);
Arnd Bergmann287980e2016-05-27 23:23:25 +0200187 if (rval)
Sakari Ailus13abada2011-05-05 15:39:25 -0300188 return rval;
189 if ((rval & (ADP1653_REG_FAULT_FLT_SCP |
190 ADP1653_REG_FAULT_FLT_OT |
191 ADP1653_REG_FAULT_FLT_OV)) &&
192 (ctrl->id == V4L2_CID_FLASH_STROBE ||
193 ctrl->id == V4L2_CID_FLASH_TORCH_INTENSITY ||
194 ctrl->id == V4L2_CID_FLASH_LED_MODE))
195 return -EBUSY;
196
197 switch (ctrl->id) {
198 case V4L2_CID_FLASH_STROBE:
199 return adp1653_strobe(flash, 1);
200 case V4L2_CID_FLASH_STROBE_STOP:
201 return adp1653_strobe(flash, 0);
202 }
203
204 return adp1653_update_hw(flash);
205}
206
207static const struct v4l2_ctrl_ops adp1653_ctrl_ops = {
208 .g_volatile_ctrl = adp1653_get_ctrl,
209 .s_ctrl = adp1653_set_ctrl,
210};
211
212static int adp1653_init_controls(struct adp1653_flash *flash)
213{
214 struct v4l2_ctrl *fault;
215
216 v4l2_ctrl_handler_init(&flash->ctrls, 9);
217
218 flash->led_mode =
219 v4l2_ctrl_new_std_menu(&flash->ctrls, &adp1653_ctrl_ops,
220 V4L2_CID_FLASH_LED_MODE,
221 V4L2_FLASH_LED_MODE_TORCH, ~0x7, 0);
222 v4l2_ctrl_new_std_menu(&flash->ctrls, &adp1653_ctrl_ops,
223 V4L2_CID_FLASH_STROBE_SOURCE,
224 V4L2_FLASH_STROBE_SOURCE_SOFTWARE, ~0x1, 0);
225 v4l2_ctrl_new_std(&flash->ctrls, &adp1653_ctrl_ops,
226 V4L2_CID_FLASH_STROBE, 0, 0, 0, 0);
227 v4l2_ctrl_new_std(&flash->ctrls, &adp1653_ctrl_ops,
228 V4L2_CID_FLASH_STROBE_STOP, 0, 0, 0, 0);
229 flash->flash_timeout =
230 v4l2_ctrl_new_std(&flash->ctrls, &adp1653_ctrl_ops,
231 V4L2_CID_FLASH_TIMEOUT, TIMEOUT_MIN,
232 flash->platform_data->max_flash_timeout,
233 TIMEOUT_STEP,
234 flash->platform_data->max_flash_timeout);
235 flash->flash_intensity =
236 v4l2_ctrl_new_std(&flash->ctrls, &adp1653_ctrl_ops,
237 V4L2_CID_FLASH_INTENSITY,
238 ADP1653_FLASH_INTENSITY_MIN,
239 flash->platform_data->max_flash_intensity,
240 1, flash->platform_data->max_flash_intensity);
241 flash->torch_intensity =
242 v4l2_ctrl_new_std(&flash->ctrls, &adp1653_ctrl_ops,
243 V4L2_CID_FLASH_TORCH_INTENSITY,
244 ADP1653_TORCH_INTENSITY_MIN,
245 flash->platform_data->max_torch_intensity,
246 ADP1653_FLASH_INTENSITY_STEP,
247 flash->platform_data->max_torch_intensity);
248 flash->indicator_intensity =
249 v4l2_ctrl_new_std(&flash->ctrls, &adp1653_ctrl_ops,
250 V4L2_CID_FLASH_INDICATOR_INTENSITY,
251 ADP1653_INDICATOR_INTENSITY_MIN,
252 flash->platform_data->max_indicator_intensity,
253 ADP1653_INDICATOR_INTENSITY_STEP,
254 ADP1653_INDICATOR_INTENSITY_MIN);
255 fault = v4l2_ctrl_new_std(&flash->ctrls, &adp1653_ctrl_ops,
256 V4L2_CID_FLASH_FAULT, 0,
257 V4L2_FLASH_FAULT_OVER_VOLTAGE
258 | V4L2_FLASH_FAULT_OVER_TEMPERATURE
259 | V4L2_FLASH_FAULT_SHORT_CIRCUIT, 0, 0);
260
261 if (flash->ctrls.error)
262 return flash->ctrls.error;
263
Hans Verkuil88365102011-08-26 07:35:14 -0300264 fault->flags |= V4L2_CTRL_FLAG_VOLATILE;
Sakari Ailus13abada2011-05-05 15:39:25 -0300265
266 flash->subdev.ctrl_handler = &flash->ctrls;
267 return 0;
268}
269
270/* --------------------------------------------------------------------------
271 * V4L2 subdev operations
272 */
273
274static int
275adp1653_init_device(struct adp1653_flash *flash)
276{
277 struct i2c_client *client = v4l2_get_subdevdata(&flash->subdev);
278 int rval;
279
280 /* Clear FAULT register by writing zero to OUT_SEL */
281 rval = i2c_smbus_write_byte_data(client, ADP1653_REG_OUT_SEL, 0);
282 if (rval < 0) {
283 dev_err(&client->dev, "failed writing fault register\n");
284 return -EIO;
285 }
286
Sakari Ailus77e7c4e2012-01-24 21:05:34 -0300287 mutex_lock(flash->ctrls.lock);
Sakari Ailus13abada2011-05-05 15:39:25 -0300288 /* Reset faults before reading new ones. */
289 flash->fault = 0;
290 rval = adp1653_get_fault(flash);
Sakari Ailus77e7c4e2012-01-24 21:05:34 -0300291 mutex_unlock(flash->ctrls.lock);
Sakari Ailus13abada2011-05-05 15:39:25 -0300292 if (rval > 0) {
293 dev_err(&client->dev, "faults detected: 0x%1.1x\n", rval);
294 return -EIO;
295 }
296
Sakari Ailus77e7c4e2012-01-24 21:05:34 -0300297 mutex_lock(flash->ctrls.lock);
Sakari Ailus13abada2011-05-05 15:39:25 -0300298 rval = adp1653_update_hw(flash);
Sakari Ailus77e7c4e2012-01-24 21:05:34 -0300299 mutex_unlock(flash->ctrls.lock);
Sakari Ailus13abada2011-05-05 15:39:25 -0300300 if (rval) {
301 dev_err(&client->dev,
302 "adp1653_update_hw failed at %s\n", __func__);
303 return -EIO;
304 }
305
306 return 0;
307}
308
309static int
310__adp1653_set_power(struct adp1653_flash *flash, int on)
311{
Mauro Carvalho Chehabbe8e58d2015-04-09 07:33:45 -0300312 int ret;
Sakari Ailus13abada2011-05-05 15:39:25 -0300313
Pavel Machek074c57a2015-04-09 04:42:38 -0300314 if (flash->platform_data->power) {
315 ret = flash->platform_data->power(&flash->subdev, on);
316 if (ret < 0)
317 return ret;
318 } else {
319 gpiod_set_value(flash->platform_data->enable_gpio, on);
320 if (on)
321 /* Some delay is apparently required. */
322 udelay(20);
323 }
Sakari Ailus13abada2011-05-05 15:39:25 -0300324
325 if (!on)
326 return 0;
327
328 ret = adp1653_init_device(flash);
Pavel Machek074c57a2015-04-09 04:42:38 -0300329 if (ret >= 0)
330 return ret;
331
332 if (flash->platform_data->power)
Sakari Ailus13abada2011-05-05 15:39:25 -0300333 flash->platform_data->power(&flash->subdev, 0);
Pavel Machek074c57a2015-04-09 04:42:38 -0300334 else
335 gpiod_set_value(flash->platform_data->enable_gpio, 0);
Sakari Ailus13abada2011-05-05 15:39:25 -0300336
337 return ret;
338}
339
340static int
341adp1653_set_power(struct v4l2_subdev *subdev, int on)
342{
343 struct adp1653_flash *flash = to_adp1653_flash(subdev);
344 int ret = 0;
345
346 mutex_lock(&flash->power_lock);
347
348 /* If the power count is modified from 0 to != 0 or from != 0 to 0,
349 * update the power state.
350 */
351 if (flash->power_count == !on) {
352 ret = __adp1653_set_power(flash, !!on);
353 if (ret < 0)
354 goto done;
355 }
356
357 /* Update the power count. */
358 flash->power_count += on ? 1 : -1;
359 WARN_ON(flash->power_count < 0);
360
361done:
362 mutex_unlock(&flash->power_lock);
363 return ret;
364}
365
366static int adp1653_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
367{
368 return adp1653_set_power(sd, 1);
369}
370
371static int adp1653_close(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
372{
373 return adp1653_set_power(sd, 0);
374}
375
376static const struct v4l2_subdev_core_ops adp1653_core_ops = {
377 .s_power = adp1653_set_power,
378};
379
380static const struct v4l2_subdev_ops adp1653_ops = {
381 .core = &adp1653_core_ops,
382};
383
384static const struct v4l2_subdev_internal_ops adp1653_internal_ops = {
385 .open = adp1653_open,
386 .close = adp1653_close,
387};
388
389/* --------------------------------------------------------------------------
390 * I2C driver
391 */
392#ifdef CONFIG_PM
393
394static int adp1653_suspend(struct device *dev)
395{
396 struct i2c_client *client = to_i2c_client(dev);
397 struct v4l2_subdev *subdev = i2c_get_clientdata(client);
398 struct adp1653_flash *flash = to_adp1653_flash(subdev);
399
400 if (!flash->power_count)
401 return 0;
402
403 return __adp1653_set_power(flash, 0);
404}
405
406static int adp1653_resume(struct device *dev)
407{
408 struct i2c_client *client = to_i2c_client(dev);
409 struct v4l2_subdev *subdev = i2c_get_clientdata(client);
410 struct adp1653_flash *flash = to_adp1653_flash(subdev);
411
412 if (!flash->power_count)
413 return 0;
414
415 return __adp1653_set_power(flash, 1);
416}
417
418#else
419
420#define adp1653_suspend NULL
421#define adp1653_resume NULL
422
423#endif /* CONFIG_PM */
424
Pavel Machek074c57a2015-04-09 04:42:38 -0300425static int adp1653_of_init(struct i2c_client *client,
426 struct adp1653_flash *flash,
427 struct device_node *node)
428{
429 struct adp1653_platform_data *pd;
430 struct device_node *child;
431
432 pd = devm_kzalloc(&client->dev, sizeof(*pd), GFP_KERNEL);
433 if (!pd)
434 return -ENOMEM;
435 flash->platform_data = pd;
436
437 child = of_get_child_by_name(node, "flash");
438 if (!child)
439 return -EINVAL;
440
441 if (of_property_read_u32(child, "flash-timeout-us",
442 &pd->max_flash_timeout))
443 goto err;
444
445 if (of_property_read_u32(child, "flash-max-microamp",
446 &pd->max_flash_intensity))
447 goto err;
448
449 pd->max_flash_intensity /= 1000;
450
451 if (of_property_read_u32(child, "led-max-microamp",
452 &pd->max_torch_intensity))
453 goto err;
454
455 pd->max_torch_intensity /= 1000;
456 of_node_put(child);
457
458 child = of_get_child_by_name(node, "indicator");
459 if (!child)
460 return -EINVAL;
461
462 if (of_property_read_u32(child, "led-max-microamp",
463 &pd->max_indicator_intensity))
464 goto err;
465
466 of_node_put(child);
467
Uwe Kleine-Königa33c3802015-06-12 09:04:55 +0200468 pd->enable_gpio = devm_gpiod_get(&client->dev, "enable", GPIOD_OUT_LOW);
Vladimir Zapolskiy806f8ff2016-03-07 15:39:32 -0300469 if (IS_ERR(pd->enable_gpio)) {
Pavel Machek074c57a2015-04-09 04:42:38 -0300470 dev_err(&client->dev, "Error getting GPIO\n");
Vladimir Zapolskiy806f8ff2016-03-07 15:39:32 -0300471 return PTR_ERR(pd->enable_gpio);
Pavel Machek074c57a2015-04-09 04:42:38 -0300472 }
473
474 return 0;
475err:
476 dev_err(&client->dev, "Required property not found\n");
477 of_node_put(child);
478 return -EINVAL;
479}
480
481
Sakari Ailus13abada2011-05-05 15:39:25 -0300482static int adp1653_probe(struct i2c_client *client,
483 const struct i2c_device_id *devid)
484{
485 struct adp1653_flash *flash;
486 int ret;
487
Laurent Pinchartc02b2112013-05-02 08:29:43 -0300488 flash = devm_kzalloc(&client->dev, sizeof(*flash), GFP_KERNEL);
Sakari Ailus13abada2011-05-05 15:39:25 -0300489 if (flash == NULL)
490 return -ENOMEM;
491
Pavel Machek074c57a2015-04-09 04:42:38 -0300492 if (client->dev.of_node) {
493 ret = adp1653_of_init(client, flash, client->dev.of_node);
494 if (ret)
495 return ret;
496 } else {
497 if (!client->dev.platform_data) {
498 dev_err(&client->dev,
499 "Neither DT not platform data provided\n");
Anton Protopopovb888d232016-02-07 02:27:32 -0200500 return -EINVAL;
Pavel Machek074c57a2015-04-09 04:42:38 -0300501 }
502 flash->platform_data = client->dev.platform_data;
503 }
Sakari Ailus13abada2011-05-05 15:39:25 -0300504
505 mutex_init(&flash->power_lock);
506
507 v4l2_i2c_subdev_init(&flash->subdev, client, &adp1653_ops);
508 flash->subdev.internal_ops = &adp1653_internal_ops;
509 flash->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
510
Andy Shevchenko31ee95e2011-07-28 04:59:38 -0300511 ret = adp1653_init_controls(flash);
512 if (ret)
513 goto free_and_quit;
Sakari Ailus13abada2011-05-05 15:39:25 -0300514
Mauro Carvalho Chehabab22e772015-12-11 07:44:40 -0200515 ret = media_entity_pads_init(&flash->subdev.entity, 0, NULL);
Sakari Ailus13abada2011-05-05 15:39:25 -0300516 if (ret < 0)
Andy Shevchenko31ee95e2011-07-28 04:59:38 -0300517 goto free_and_quit;
Sakari Ailus13abada2011-05-05 15:39:25 -0300518
Mauro Carvalho Chehab4ca72ef2015-12-10 17:25:41 -0200519 flash->subdev.entity.function = MEDIA_ENT_F_FLASH;
Mauro Carvalho Chehabbe8e58d2015-04-09 07:33:45 -0300520
Andy Shevchenko31ee95e2011-07-28 04:59:38 -0300521 return 0;
522
523free_and_quit:
Pavel Machek074c57a2015-04-09 04:42:38 -0300524 dev_err(&client->dev, "adp1653: failed to register device\n");
Andy Shevchenko31ee95e2011-07-28 04:59:38 -0300525 v4l2_ctrl_handler_free(&flash->ctrls);
Sakari Ailus13abada2011-05-05 15:39:25 -0300526 return ret;
527}
528
Dmitry Torokhovbf306902013-02-26 03:17:27 -0300529static int adp1653_remove(struct i2c_client *client)
Sakari Ailus13abada2011-05-05 15:39:25 -0300530{
531 struct v4l2_subdev *subdev = i2c_get_clientdata(client);
532 struct adp1653_flash *flash = to_adp1653_flash(subdev);
533
534 v4l2_device_unregister_subdev(&flash->subdev);
535 v4l2_ctrl_handler_free(&flash->ctrls);
536 media_entity_cleanup(&flash->subdev.entity);
Laurent Pinchartc02b2112013-05-02 08:29:43 -0300537
Sakari Ailus13abada2011-05-05 15:39:25 -0300538 return 0;
539}
540
541static const struct i2c_device_id adp1653_id_table[] = {
542 { ADP1653_NAME, 0 },
543 { }
544};
545MODULE_DEVICE_TABLE(i2c, adp1653_id_table);
546
Pavel Machek074c57a2015-04-09 04:42:38 -0300547static const struct dev_pm_ops adp1653_pm_ops = {
Sakari Ailus13abada2011-05-05 15:39:25 -0300548 .suspend = adp1653_suspend,
549 .resume = adp1653_resume,
550};
551
552static struct i2c_driver adp1653_i2c_driver = {
553 .driver = {
554 .name = ADP1653_NAME,
555 .pm = &adp1653_pm_ops,
556 },
557 .probe = adp1653_probe,
Dmitry Torokhovbf306902013-02-26 03:17:27 -0300558 .remove = adp1653_remove,
Sakari Ailus13abada2011-05-05 15:39:25 -0300559 .id_table = adp1653_id_table,
560};
561
Axel Linc6e8d862012-02-12 06:56:32 -0300562module_i2c_driver(adp1653_i2c_driver);
Sakari Ailus13abada2011-05-05 15:39:25 -0300563
564MODULE_AUTHOR("Sakari Ailus <sakari.ailus@nokia.com>");
565MODULE_DESCRIPTION("Analog Devices ADP1653 LED flash driver");
566MODULE_LICENSE("GPL");