xref: /openbmc/linux/drivers/leds/flash/leds-as3645a.c (revision 2612e3bbc0386368a850140a6c9b990cd496a5ec)
1  // SPDX-License-Identifier: GPL-2.0-only
2  /*
3   * drivers/leds/leds-as3645a.c - AS3645A and LM3555 flash controllers driver
4   *
5   * Copyright (C) 2008-2011 Nokia Corporation
6   * Copyright (c) 2011, 2017 Intel Corporation.
7   *
8   * Based on drivers/media/i2c/as3645a.c.
9   *
10   * Contact: Sakari Ailus <sakari.ailus@iki.fi>
11   */
12  
13  #include <linux/delay.h>
14  #include <linux/gpio/consumer.h>
15  #include <linux/i2c.h>
16  #include <linux/led-class-flash.h>
17  #include <linux/leds.h>
18  #include <linux/module.h>
19  #include <linux/mutex.h>
20  #include <linux/property.h>
21  #include <linux/slab.h>
22  
23  #include <media/v4l2-flash-led-class.h>
24  
25  #define AS_TIMER_US_TO_CODE(t)			(((t) / 1000 - 100) / 50)
26  #define AS_TIMER_CODE_TO_US(c)			((50 * (c) + 100) * 1000)
27  
28  /* Register definitions */
29  
30  /* Read-only Design info register: Reset state: xxxx 0001 */
31  #define AS_DESIGN_INFO_REG			0x00
32  #define AS_DESIGN_INFO_FACTORY(x)		(((x) >> 4))
33  #define AS_DESIGN_INFO_MODEL(x)			((x) & 0x0f)
34  
35  /* Read-only Version control register: Reset state: 0000 0000
36   * for first engineering samples
37   */
38  #define AS_VERSION_CONTROL_REG			0x01
39  #define AS_VERSION_CONTROL_RFU(x)		(((x) >> 4))
40  #define AS_VERSION_CONTROL_VERSION(x)		((x) & 0x0f)
41  
42  /* Read / Write	(Indicator and timer register): Reset state: 0000 1111 */
43  #define AS_INDICATOR_AND_TIMER_REG		0x02
44  #define AS_INDICATOR_AND_TIMER_TIMEOUT_SHIFT	0
45  #define AS_INDICATOR_AND_TIMER_VREF_SHIFT	4
46  #define AS_INDICATOR_AND_TIMER_INDICATOR_SHIFT	6
47  
48  /* Read / Write	(Current set register): Reset state: 0110 1001 */
49  #define AS_CURRENT_SET_REG			0x03
50  #define AS_CURRENT_ASSIST_LIGHT_SHIFT		0
51  #define AS_CURRENT_LED_DET_ON			(1 << 3)
52  #define AS_CURRENT_FLASH_CURRENT_SHIFT		4
53  
54  /* Read / Write	(Control register): Reset state: 1011 0100 */
55  #define AS_CONTROL_REG				0x04
56  #define AS_CONTROL_MODE_SETTING_SHIFT		0
57  #define AS_CONTROL_STROBE_ON			(1 << 2)
58  #define AS_CONTROL_OUT_ON			(1 << 3)
59  #define AS_CONTROL_EXT_TORCH_ON			(1 << 4)
60  #define AS_CONTROL_STROBE_TYPE_EDGE		(0 << 5)
61  #define AS_CONTROL_STROBE_TYPE_LEVEL		(1 << 5)
62  #define AS_CONTROL_COIL_PEAK_SHIFT		6
63  
64  /* Read only (D3 is read / write) (Fault and info): Reset state: 0000 x000 */
65  #define AS_FAULT_INFO_REG			0x05
66  #define AS_FAULT_INFO_INDUCTOR_PEAK_LIMIT	(1 << 1)
67  #define AS_FAULT_INFO_INDICATOR_LED		(1 << 2)
68  #define AS_FAULT_INFO_LED_AMOUNT		(1 << 3)
69  #define AS_FAULT_INFO_TIMEOUT			(1 << 4)
70  #define AS_FAULT_INFO_OVER_TEMPERATURE		(1 << 5)
71  #define AS_FAULT_INFO_SHORT_CIRCUIT		(1 << 6)
72  #define AS_FAULT_INFO_OVER_VOLTAGE		(1 << 7)
73  
74  /* Boost register */
75  #define AS_BOOST_REG				0x0d
76  #define AS_BOOST_CURRENT_DISABLE		(0 << 0)
77  #define AS_BOOST_CURRENT_ENABLE			(1 << 0)
78  
79  /* Password register is used to unlock boost register writing */
80  #define AS_PASSWORD_REG				0x0f
81  #define AS_PASSWORD_UNLOCK_VALUE		0x55
82  
83  #define AS_NAME					"as3645a"
84  #define AS_I2C_ADDR				(0x60 >> 1) /* W:0x60, R:0x61 */
85  
86  #define AS_FLASH_TIMEOUT_MIN			100000	/* us */
87  #define AS_FLASH_TIMEOUT_MAX			850000
88  #define AS_FLASH_TIMEOUT_STEP			50000
89  
90  #define AS_FLASH_INTENSITY_MIN			200000	/* uA */
91  #define AS_FLASH_INTENSITY_MAX_1LED		500000
92  #define AS_FLASH_INTENSITY_MAX_2LEDS		400000
93  #define AS_FLASH_INTENSITY_STEP			20000
94  
95  #define AS_TORCH_INTENSITY_MIN			20000	/* uA */
96  #define AS_TORCH_INTENSITY_MAX			160000
97  #define AS_TORCH_INTENSITY_STEP			20000
98  
99  #define AS_INDICATOR_INTENSITY_MIN		0	/* uA */
100  #define AS_INDICATOR_INTENSITY_MAX		10000
101  #define AS_INDICATOR_INTENSITY_STEP		2500
102  
103  #define AS_PEAK_mA_MAX				2000
104  #define AS_PEAK_mA_TO_REG(a) \
105  	((min_t(u32, AS_PEAK_mA_MAX, a) - 1250) / 250)
106  
107  /* LED numbers for Devicetree */
108  #define AS_LED_FLASH				0
109  #define AS_LED_INDICATOR			1
110  
111  enum as_mode {
112  	AS_MODE_EXT_TORCH = 0 << AS_CONTROL_MODE_SETTING_SHIFT,
113  	AS_MODE_INDICATOR = 1 << AS_CONTROL_MODE_SETTING_SHIFT,
114  	AS_MODE_ASSIST = 2 << AS_CONTROL_MODE_SETTING_SHIFT,
115  	AS_MODE_FLASH = 3 << AS_CONTROL_MODE_SETTING_SHIFT,
116  };
117  
118  struct as3645a_config {
119  	u32 flash_timeout_us;
120  	u32 flash_max_ua;
121  	u32 assist_max_ua;
122  	u32 indicator_max_ua;
123  	u32 voltage_reference;
124  	u32 peak;
125  };
126  
127  struct as3645a {
128  	struct i2c_client *client;
129  
130  	struct mutex mutex;
131  
132  	struct led_classdev_flash fled;
133  	struct led_classdev iled_cdev;
134  
135  	struct v4l2_flash *vf;
136  	struct v4l2_flash *vfind;
137  
138  	struct fwnode_handle *flash_node;
139  	struct fwnode_handle *indicator_node;
140  
141  	struct as3645a_config cfg;
142  
143  	enum as_mode mode;
144  	unsigned int timeout;
145  	unsigned int flash_current;
146  	unsigned int assist_current;
147  	unsigned int indicator_current;
148  	enum v4l2_flash_strobe_source strobe_source;
149  };
150  
151  #define fled_to_as3645a(__fled) container_of(__fled, struct as3645a, fled)
152  #define iled_cdev_to_as3645a(__iled_cdev) \
153  	container_of(__iled_cdev, struct as3645a, iled_cdev)
154  
155  /* Return negative errno else zero on success */
as3645a_write(struct as3645a * flash,u8 addr,u8 val)156  static int as3645a_write(struct as3645a *flash, u8 addr, u8 val)
157  {
158  	struct i2c_client *client = flash->client;
159  	int rval;
160  
161  	rval = i2c_smbus_write_byte_data(client, addr, val);
162  
163  	dev_dbg(&client->dev, "Write Addr:%02X Val:%02X %s\n", addr, val,
164  		rval < 0 ? "fail" : "ok");
165  
166  	return rval;
167  }
168  
169  /* Return negative errno else a data byte received from the device. */
as3645a_read(struct as3645a * flash,u8 addr)170  static int as3645a_read(struct as3645a *flash, u8 addr)
171  {
172  	struct i2c_client *client = flash->client;
173  	int rval;
174  
175  	rval = i2c_smbus_read_byte_data(client, addr);
176  
177  	dev_dbg(&client->dev, "Read Addr:%02X Val:%02X %s\n", addr, rval,
178  		rval < 0 ? "fail" : "ok");
179  
180  	return rval;
181  }
182  
183  /* -----------------------------------------------------------------------------
184   * Hardware configuration and trigger
185   */
186  
187  /**
188   * as3645a_set_current - Set flash configuration registers
189   * @flash: The flash
190   *
191   * Configure the hardware with flash, assist and indicator currents, as well as
192   * flash timeout.
193   *
194   * Return 0 on success, or a negative error code if an I2C communication error
195   * occurred.
196   */
as3645a_set_current(struct as3645a * flash)197  static int as3645a_set_current(struct as3645a *flash)
198  {
199  	u8 val;
200  
201  	val = (flash->flash_current << AS_CURRENT_FLASH_CURRENT_SHIFT)
202  	    | (flash->assist_current << AS_CURRENT_ASSIST_LIGHT_SHIFT)
203  	    | AS_CURRENT_LED_DET_ON;
204  
205  	return as3645a_write(flash, AS_CURRENT_SET_REG, val);
206  }
207  
as3645a_set_timeout(struct as3645a * flash)208  static int as3645a_set_timeout(struct as3645a *flash)
209  {
210  	u8 val;
211  
212  	val = flash->timeout << AS_INDICATOR_AND_TIMER_TIMEOUT_SHIFT;
213  
214  	val |= (flash->cfg.voltage_reference
215  		<< AS_INDICATOR_AND_TIMER_VREF_SHIFT)
216  	    |  ((flash->indicator_current ? flash->indicator_current - 1 : 0)
217  		 << AS_INDICATOR_AND_TIMER_INDICATOR_SHIFT);
218  
219  	return as3645a_write(flash, AS_INDICATOR_AND_TIMER_REG, val);
220  }
221  
222  /**
223   * as3645a_set_control - Set flash control register
224   * @flash: The flash
225   * @mode: Desired output mode
226   * @on: Desired output state
227   *
228   * Configure the hardware with output mode and state.
229   *
230   * Return 0 on success, or a negative error code if an I2C communication error
231   * occurred.
232   */
233  static int
as3645a_set_control(struct as3645a * flash,enum as_mode mode,bool on)234  as3645a_set_control(struct as3645a *flash, enum as_mode mode, bool on)
235  {
236  	u8 reg;
237  
238  	/* Configure output parameters and operation mode. */
239  	reg = (flash->cfg.peak << AS_CONTROL_COIL_PEAK_SHIFT)
240  	    | (on ? AS_CONTROL_OUT_ON : 0)
241  	    | mode;
242  
243  	if (mode == AS_MODE_FLASH &&
244  	    flash->strobe_source == V4L2_FLASH_STROBE_SOURCE_EXTERNAL)
245  		reg |= AS_CONTROL_STROBE_TYPE_LEVEL
246  		    |  AS_CONTROL_STROBE_ON;
247  
248  	return as3645a_write(flash, AS_CONTROL_REG, reg);
249  }
250  
as3645a_get_fault(struct led_classdev_flash * fled,u32 * fault)251  static int as3645a_get_fault(struct led_classdev_flash *fled, u32 *fault)
252  {
253  	struct as3645a *flash = fled_to_as3645a(fled);
254  	int rval;
255  
256  	/* NOTE: reading register clears fault status */
257  	rval = as3645a_read(flash, AS_FAULT_INFO_REG);
258  	if (rval < 0)
259  		return rval;
260  
261  	if (rval & AS_FAULT_INFO_INDUCTOR_PEAK_LIMIT)
262  		*fault |= LED_FAULT_OVER_CURRENT;
263  
264  	if (rval & AS_FAULT_INFO_INDICATOR_LED)
265  		*fault |= LED_FAULT_INDICATOR;
266  
267  	dev_dbg(&flash->client->dev, "%u connected LEDs\n",
268  		rval & AS_FAULT_INFO_LED_AMOUNT ? 2 : 1);
269  
270  	if (rval & AS_FAULT_INFO_TIMEOUT)
271  		*fault |= LED_FAULT_TIMEOUT;
272  
273  	if (rval & AS_FAULT_INFO_OVER_TEMPERATURE)
274  		*fault |= LED_FAULT_OVER_TEMPERATURE;
275  
276  	if (rval & AS_FAULT_INFO_SHORT_CIRCUIT)
277  		*fault |= LED_FAULT_OVER_CURRENT;
278  
279  	if (rval & AS_FAULT_INFO_OVER_VOLTAGE)
280  		*fault |= LED_FAULT_INPUT_VOLTAGE;
281  
282  	return rval;
283  }
284  
__as3645a_current_to_reg(unsigned int min,unsigned int max,unsigned int step,unsigned int val)285  static unsigned int __as3645a_current_to_reg(unsigned int min, unsigned int max,
286  					     unsigned int step,
287  					     unsigned int val)
288  {
289  	if (val < min)
290  		val = min;
291  
292  	if (val > max)
293  		val = max;
294  
295  	return (val - min) / step;
296  }
297  
as3645a_current_to_reg(struct as3645a * flash,bool is_flash,unsigned int ua)298  static unsigned int as3645a_current_to_reg(struct as3645a *flash, bool is_flash,
299  					   unsigned int ua)
300  {
301  	if (is_flash)
302  		return __as3645a_current_to_reg(AS_TORCH_INTENSITY_MIN,
303  						flash->cfg.assist_max_ua,
304  						AS_TORCH_INTENSITY_STEP, ua);
305  	else
306  		return __as3645a_current_to_reg(AS_FLASH_INTENSITY_MIN,
307  						flash->cfg.flash_max_ua,
308  						AS_FLASH_INTENSITY_STEP, ua);
309  }
310  
as3645a_set_indicator_brightness(struct led_classdev * iled_cdev,enum led_brightness brightness)311  static int as3645a_set_indicator_brightness(struct led_classdev *iled_cdev,
312  					    enum led_brightness brightness)
313  {
314  	struct as3645a *flash = iled_cdev_to_as3645a(iled_cdev);
315  	int rval;
316  
317  	flash->indicator_current = brightness;
318  
319  	rval = as3645a_set_timeout(flash);
320  	if (rval)
321  		return rval;
322  
323  	return as3645a_set_control(flash, AS_MODE_INDICATOR, brightness);
324  }
325  
as3645a_set_assist_brightness(struct led_classdev * fled_cdev,enum led_brightness brightness)326  static int as3645a_set_assist_brightness(struct led_classdev *fled_cdev,
327  					 enum led_brightness brightness)
328  {
329  	struct led_classdev_flash *fled = lcdev_to_flcdev(fled_cdev);
330  	struct as3645a *flash = fled_to_as3645a(fled);
331  	int rval;
332  
333  	if (brightness) {
334  		/* Register value 0 is 20 mA. */
335  		flash->assist_current = brightness - 1;
336  
337  		rval = as3645a_set_current(flash);
338  		if (rval)
339  			return rval;
340  	}
341  
342  	return as3645a_set_control(flash, AS_MODE_ASSIST, brightness);
343  }
344  
as3645a_set_flash_brightness(struct led_classdev_flash * fled,u32 brightness_ua)345  static int as3645a_set_flash_brightness(struct led_classdev_flash *fled,
346  					u32 brightness_ua)
347  {
348  	struct as3645a *flash = fled_to_as3645a(fled);
349  
350  	flash->flash_current = as3645a_current_to_reg(flash, true,
351  						      brightness_ua);
352  
353  	return as3645a_set_current(flash);
354  }
355  
as3645a_set_flash_timeout(struct led_classdev_flash * fled,u32 timeout_us)356  static int as3645a_set_flash_timeout(struct led_classdev_flash *fled,
357  				     u32 timeout_us)
358  {
359  	struct as3645a *flash = fled_to_as3645a(fled);
360  
361  	flash->timeout = AS_TIMER_US_TO_CODE(timeout_us);
362  
363  	return as3645a_set_timeout(flash);
364  }
365  
as3645a_set_strobe(struct led_classdev_flash * fled,bool state)366  static int as3645a_set_strobe(struct led_classdev_flash *fled, bool state)
367  {
368  	struct as3645a *flash = fled_to_as3645a(fled);
369  
370  	return as3645a_set_control(flash, AS_MODE_FLASH, state);
371  }
372  
373  static const struct led_flash_ops as3645a_led_flash_ops = {
374  	.flash_brightness_set = as3645a_set_flash_brightness,
375  	.timeout_set = as3645a_set_flash_timeout,
376  	.strobe_set = as3645a_set_strobe,
377  	.fault_get = as3645a_get_fault,
378  };
379  
as3645a_setup(struct as3645a * flash)380  static int as3645a_setup(struct as3645a *flash)
381  {
382  	struct device *dev = &flash->client->dev;
383  	u32 fault = 0;
384  	int rval;
385  
386  	/* clear errors */
387  	rval = as3645a_read(flash, AS_FAULT_INFO_REG);
388  	if (rval < 0)
389  		return rval;
390  
391  	dev_dbg(dev, "Fault info: %02x\n", rval);
392  
393  	rval = as3645a_set_current(flash);
394  	if (rval < 0)
395  		return rval;
396  
397  	rval = as3645a_set_timeout(flash);
398  	if (rval < 0)
399  		return rval;
400  
401  	rval = as3645a_set_control(flash, AS_MODE_INDICATOR, false);
402  	if (rval < 0)
403  		return rval;
404  
405  	/* read status */
406  	rval = as3645a_get_fault(&flash->fled, &fault);
407  	if (rval < 0)
408  		return rval;
409  
410  	dev_dbg(dev, "AS_INDICATOR_AND_TIMER_REG: %02x\n",
411  		as3645a_read(flash, AS_INDICATOR_AND_TIMER_REG));
412  	dev_dbg(dev, "AS_CURRENT_SET_REG: %02x\n",
413  		as3645a_read(flash, AS_CURRENT_SET_REG));
414  	dev_dbg(dev, "AS_CONTROL_REG: %02x\n",
415  		as3645a_read(flash, AS_CONTROL_REG));
416  
417  	return rval & ~AS_FAULT_INFO_LED_AMOUNT ? -EIO : 0;
418  }
419  
as3645a_detect(struct as3645a * flash)420  static int as3645a_detect(struct as3645a *flash)
421  {
422  	struct device *dev = &flash->client->dev;
423  	int rval, man, model, rfu, version;
424  	const char *vendor;
425  
426  	rval = as3645a_read(flash, AS_DESIGN_INFO_REG);
427  	if (rval < 0) {
428  		dev_err(dev, "can't read design info reg\n");
429  		return rval;
430  	}
431  
432  	man = AS_DESIGN_INFO_FACTORY(rval);
433  	model = AS_DESIGN_INFO_MODEL(rval);
434  
435  	rval = as3645a_read(flash, AS_VERSION_CONTROL_REG);
436  	if (rval < 0) {
437  		dev_err(dev, "can't read version control reg\n");
438  		return rval;
439  	}
440  
441  	rfu = AS_VERSION_CONTROL_RFU(rval);
442  	version = AS_VERSION_CONTROL_VERSION(rval);
443  
444  	/* Verify the chip model and version. */
445  	if (model != 0x01 || rfu != 0x00) {
446  		dev_err(dev, "AS3645A not detected (model %d rfu %d)\n",
447  			model, rfu);
448  		return -ENODEV;
449  	}
450  
451  	switch (man) {
452  	case 1:
453  		vendor = "AMS, Austria Micro Systems";
454  		break;
455  	case 2:
456  		vendor = "ADI, Analog Devices Inc.";
457  		break;
458  	case 3:
459  		vendor = "NSC, National Semiconductor";
460  		break;
461  	case 4:
462  		vendor = "NXP";
463  		break;
464  	case 5:
465  		vendor = "TI, Texas Instrument";
466  		break;
467  	default:
468  		vendor = "Unknown";
469  	}
470  
471  	dev_info(dev, "Chip vendor: %s (%d) Version: %d\n", vendor,
472  		 man, version);
473  
474  	rval = as3645a_write(flash, AS_PASSWORD_REG, AS_PASSWORD_UNLOCK_VALUE);
475  	if (rval < 0)
476  		return rval;
477  
478  	return as3645a_write(flash, AS_BOOST_REG, AS_BOOST_CURRENT_DISABLE);
479  }
480  
as3645a_parse_node(struct as3645a * flash,struct fwnode_handle * fwnode)481  static int as3645a_parse_node(struct as3645a *flash,
482  			      struct fwnode_handle *fwnode)
483  {
484  	struct as3645a_config *cfg = &flash->cfg;
485  	struct fwnode_handle *child;
486  	int rval;
487  
488  	fwnode_for_each_child_node(fwnode, child) {
489  		u32 id = 0;
490  
491  		fwnode_property_read_u32(child, "reg", &id);
492  
493  		switch (id) {
494  		case AS_LED_FLASH:
495  			flash->flash_node = child;
496  			fwnode_handle_get(child);
497  			break;
498  		case AS_LED_INDICATOR:
499  			flash->indicator_node = child;
500  			fwnode_handle_get(child);
501  			break;
502  		default:
503  			dev_warn(&flash->client->dev,
504  				 "unknown LED %u encountered, ignoring\n", id);
505  			break;
506  		}
507  	}
508  
509  	if (!flash->flash_node) {
510  		dev_err(&flash->client->dev, "can't find flash node\n");
511  		return -ENODEV;
512  	}
513  
514  	rval = fwnode_property_read_u32(flash->flash_node, "flash-timeout-us",
515  					&cfg->flash_timeout_us);
516  	if (rval < 0) {
517  		dev_err(&flash->client->dev,
518  			"can't read flash-timeout-us property for flash\n");
519  		goto out_err;
520  	}
521  
522  	rval = fwnode_property_read_u32(flash->flash_node, "flash-max-microamp",
523  					&cfg->flash_max_ua);
524  	if (rval < 0) {
525  		dev_err(&flash->client->dev,
526  			"can't read flash-max-microamp property for flash\n");
527  		goto out_err;
528  	}
529  
530  	rval = fwnode_property_read_u32(flash->flash_node, "led-max-microamp",
531  					&cfg->assist_max_ua);
532  	if (rval < 0) {
533  		dev_err(&flash->client->dev,
534  			"can't read led-max-microamp property for flash\n");
535  		goto out_err;
536  	}
537  
538  	fwnode_property_read_u32(flash->flash_node, "voltage-reference",
539  				 &cfg->voltage_reference);
540  
541  	fwnode_property_read_u32(flash->flash_node, "ams,input-max-microamp",
542  				 &cfg->peak);
543  	cfg->peak = AS_PEAK_mA_TO_REG(cfg->peak);
544  
545  	if (!flash->indicator_node) {
546  		dev_warn(&flash->client->dev,
547  			 "can't find indicator node\n");
548  		rval = -ENODEV;
549  		goto out_err;
550  	}
551  
552  
553  	rval = fwnode_property_read_u32(flash->indicator_node,
554  					"led-max-microamp",
555  					&cfg->indicator_max_ua);
556  	if (rval < 0) {
557  		dev_err(&flash->client->dev,
558  			"can't read led-max-microamp property for indicator\n");
559  		goto out_err;
560  	}
561  
562  	return 0;
563  
564  out_err:
565  	fwnode_handle_put(flash->flash_node);
566  	fwnode_handle_put(flash->indicator_node);
567  
568  	return rval;
569  }
570  
as3645a_led_class_setup(struct as3645a * flash)571  static int as3645a_led_class_setup(struct as3645a *flash)
572  {
573  	struct led_classdev *fled_cdev = &flash->fled.led_cdev;
574  	struct led_classdev *iled_cdev = &flash->iled_cdev;
575  	struct led_init_data init_data = {};
576  	struct led_flash_setting *cfg;
577  	int rval;
578  
579  	iled_cdev->brightness_set_blocking = as3645a_set_indicator_brightness;
580  	iled_cdev->max_brightness =
581  		flash->cfg.indicator_max_ua / AS_INDICATOR_INTENSITY_STEP;
582  	iled_cdev->flags = LED_CORE_SUSPENDRESUME;
583  
584  	init_data.fwnode = flash->indicator_node;
585  	init_data.devicename = AS_NAME;
586  	init_data.default_label = "indicator";
587  
588  	rval = led_classdev_register_ext(&flash->client->dev, iled_cdev,
589  					 &init_data);
590  	if (rval < 0)
591  		return rval;
592  
593  	cfg = &flash->fled.brightness;
594  	cfg->min = AS_FLASH_INTENSITY_MIN;
595  	cfg->max = flash->cfg.flash_max_ua;
596  	cfg->step = AS_FLASH_INTENSITY_STEP;
597  	cfg->val = flash->cfg.flash_max_ua;
598  
599  	cfg = &flash->fled.timeout;
600  	cfg->min = AS_FLASH_TIMEOUT_MIN;
601  	cfg->max = flash->cfg.flash_timeout_us;
602  	cfg->step = AS_FLASH_TIMEOUT_STEP;
603  	cfg->val = flash->cfg.flash_timeout_us;
604  
605  	flash->fled.ops = &as3645a_led_flash_ops;
606  
607  	fled_cdev->brightness_set_blocking = as3645a_set_assist_brightness;
608  	/* Value 0 is off in LED class. */
609  	fled_cdev->max_brightness =
610  		as3645a_current_to_reg(flash, false,
611  				       flash->cfg.assist_max_ua) + 1;
612  	fled_cdev->flags = LED_DEV_CAP_FLASH | LED_CORE_SUSPENDRESUME;
613  
614  	init_data.fwnode = flash->flash_node;
615  	init_data.devicename = AS_NAME;
616  	init_data.default_label = "flash";
617  
618  	rval = led_classdev_flash_register_ext(&flash->client->dev,
619  					       &flash->fled, &init_data);
620  	if (rval)
621  		goto out_err;
622  
623  	return rval;
624  
625  out_err:
626  	led_classdev_unregister(iled_cdev);
627  	dev_err(&flash->client->dev,
628  		"led_classdev_flash_register() failed, error %d\n",
629  		rval);
630  	return rval;
631  }
632  
as3645a_v4l2_setup(struct as3645a * flash)633  static int as3645a_v4l2_setup(struct as3645a *flash)
634  {
635  	struct led_classdev_flash *fled = &flash->fled;
636  	struct led_classdev *led = &fled->led_cdev;
637  	struct v4l2_flash_config cfg = {
638  		.intensity = {
639  			.min = AS_TORCH_INTENSITY_MIN,
640  			.max = flash->cfg.assist_max_ua,
641  			.step = AS_TORCH_INTENSITY_STEP,
642  			.val = flash->cfg.assist_max_ua,
643  		},
644  	};
645  	struct v4l2_flash_config cfgind = {
646  		.intensity = {
647  			.min = AS_INDICATOR_INTENSITY_MIN,
648  			.max = flash->cfg.indicator_max_ua,
649  			.step = AS_INDICATOR_INTENSITY_STEP,
650  			.val = flash->cfg.indicator_max_ua,
651  		},
652  	};
653  
654  	strscpy(cfg.dev_name, led->dev->kobj.name, sizeof(cfg.dev_name));
655  	strscpy(cfgind.dev_name, flash->iled_cdev.dev->kobj.name,
656  		sizeof(cfgind.dev_name));
657  
658  	flash->vf = v4l2_flash_init(
659  		&flash->client->dev, flash->flash_node, &flash->fled, NULL,
660  		&cfg);
661  	if (IS_ERR(flash->vf))
662  		return PTR_ERR(flash->vf);
663  
664  	flash->vfind = v4l2_flash_indicator_init(
665  		&flash->client->dev, flash->indicator_node, &flash->iled_cdev,
666  		&cfgind);
667  	if (IS_ERR(flash->vfind)) {
668  		v4l2_flash_release(flash->vf);
669  		return PTR_ERR(flash->vfind);
670  	}
671  
672  	return 0;
673  }
674  
as3645a_probe(struct i2c_client * client)675  static int as3645a_probe(struct i2c_client *client)
676  {
677  	struct as3645a *flash;
678  	int rval;
679  
680  	if (!dev_fwnode(&client->dev))
681  		return -ENODEV;
682  
683  	flash = devm_kzalloc(&client->dev, sizeof(*flash), GFP_KERNEL);
684  	if (flash == NULL)
685  		return -ENOMEM;
686  
687  	flash->client = client;
688  
689  	rval = as3645a_parse_node(flash, dev_fwnode(&client->dev));
690  	if (rval < 0)
691  		return rval;
692  
693  	rval = as3645a_detect(flash);
694  	if (rval < 0)
695  		goto out_put_nodes;
696  
697  	mutex_init(&flash->mutex);
698  	i2c_set_clientdata(client, flash);
699  
700  	rval = as3645a_setup(flash);
701  	if (rval)
702  		goto out_mutex_destroy;
703  
704  	rval = as3645a_led_class_setup(flash);
705  	if (rval)
706  		goto out_mutex_destroy;
707  
708  	rval = as3645a_v4l2_setup(flash);
709  	if (rval)
710  		goto out_led_classdev_flash_unregister;
711  
712  	return 0;
713  
714  out_led_classdev_flash_unregister:
715  	led_classdev_flash_unregister(&flash->fled);
716  
717  out_mutex_destroy:
718  	mutex_destroy(&flash->mutex);
719  
720  out_put_nodes:
721  	fwnode_handle_put(flash->flash_node);
722  	fwnode_handle_put(flash->indicator_node);
723  
724  	return rval;
725  }
726  
as3645a_remove(struct i2c_client * client)727  static void as3645a_remove(struct i2c_client *client)
728  {
729  	struct as3645a *flash = i2c_get_clientdata(client);
730  
731  	as3645a_set_control(flash, AS_MODE_EXT_TORCH, false);
732  
733  	v4l2_flash_release(flash->vf);
734  	v4l2_flash_release(flash->vfind);
735  
736  	led_classdev_flash_unregister(&flash->fled);
737  	led_classdev_unregister(&flash->iled_cdev);
738  
739  	mutex_destroy(&flash->mutex);
740  
741  	fwnode_handle_put(flash->flash_node);
742  	fwnode_handle_put(flash->indicator_node);
743  }
744  
745  static const struct i2c_device_id as3645a_id_table[] = {
746  	{ AS_NAME, 0 },
747  	{ },
748  };
749  MODULE_DEVICE_TABLE(i2c, as3645a_id_table);
750  
751  static const struct of_device_id as3645a_of_table[] = {
752  	{ .compatible = "ams,as3645a" },
753  	{ },
754  };
755  MODULE_DEVICE_TABLE(of, as3645a_of_table);
756  
757  static struct i2c_driver as3645a_i2c_driver = {
758  	.driver	= {
759  		.of_match_table = as3645a_of_table,
760  		.name = AS_NAME,
761  	},
762  	.probe = as3645a_probe,
763  	.remove	= as3645a_remove,
764  	.id_table = as3645a_id_table,
765  };
766  
767  module_i2c_driver(as3645a_i2c_driver);
768  
769  MODULE_AUTHOR("Laurent Pinchart <laurent.pinchart@ideasonboard.com>");
770  MODULE_AUTHOR("Sakari Ailus <sakari.ailus@iki.fi>");
771  MODULE_DESCRIPTION("LED flash driver for AS3645A, LM3555 and their clones");
772  MODULE_LICENSE("GPL v2");
773