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