1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (C) 2023 Richtek Technology Corp.
4  *
5  * Authors:
6  *   Alice Chen <alice_chen@richtek.com>
7  *   ChiYuan Huang <cy_huang@richtek.com>
8  */
9 
10 #include <linux/bitops.h>
11 #include <linux/delay.h>
12 #include <linux/init.h>
13 #include <linux/interrupt.h>
14 #include <linux/kernel.h>
15 #include <linux/led-class-flash.h>
16 #include <linux/module.h>
17 #include <linux/mutex.h>
18 #include <linux/platform_device.h>
19 #include <linux/property.h>
20 #include <linux/regmap.h>
21 
22 #include <media/v4l2-flash-led-class.h>
23 
24 enum {
25 	MT6370_LED_FLASH1 = 0,
26 	MT6370_LED_FLASH2,
27 	MT6370_MAX_LEDS
28 };
29 
30 /* Virtual definition for multicolor */
31 
32 #define MT6370_REG_FLEDEN		0x17E
33 #define MT6370_REG_STRBTO		0x173
34 #define MT6370_REG_CHGSTAT2		0x1D1
35 #define MT6370_REG_FLEDSTAT1		0x1D9
36 #define MT6370_REG_FLEDISTRB(_id)	(0x174 + 4 * (_id))
37 #define MT6370_REG_FLEDITOR(_id)	(0x175 + 4 * (_id))
38 #define MT6370_ITORCH_MASK		GENMASK(4, 0)
39 #define MT6370_ISTROBE_MASK		GENMASK(6, 0)
40 #define MT6370_STRBTO_MASK		GENMASK(6, 0)
41 #define MT6370_TORCHEN_MASK		BIT(3)
42 #define MT6370_STROBEN_MASK		BIT(2)
43 #define MT6370_FLCSEN_MASK(_id)		BIT(MT6370_LED_FLASH2 - (_id))
44 #define MT6370_FLCSEN_MASK_ALL		GENMASK(1, 0)
45 #define MT6370_FLEDCHGVINOVP_MASK	BIT(3)
46 #define MT6370_FLED1STRBTO_MASK		BIT(11)
47 #define MT6370_FLED2STRBTO_MASK		BIT(10)
48 #define MT6370_FLED1STRB_MASK		BIT(9)
49 #define MT6370_FLED2STRB_MASK		BIT(8)
50 #define MT6370_FLED1SHORT_MASK		BIT(7)
51 #define MT6370_FLED2SHORT_MASK		BIT(6)
52 #define MT6370_FLEDLVF_MASK		BIT(3)
53 
54 #define MT6370_LED_JOINT		2
55 #define MT6370_RANGE_FLED_REG		4
56 #define MT6370_ITORCH_MIN_uA		25000
57 #define MT6370_ITORCH_STEP_uA		12500
58 #define MT6370_ITORCH_MAX_uA		400000
59 #define MT6370_ITORCH_DOUBLE_MAX_uA	800000
60 #define MT6370_ISTRB_MIN_uA		50000
61 #define MT6370_ISTRB_STEP_uA		12500
62 #define MT6370_ISTRB_MAX_uA		1500000
63 #define MT6370_ISTRB_DOUBLE_MAX_uA	3000000
64 #define MT6370_STRBTO_MIN_US		64000
65 #define MT6370_STRBTO_STEP_US		32000
66 #define MT6370_STRBTO_MAX_US		2432000
67 
68 #define to_mt6370_led(ptr, member) container_of(ptr, struct mt6370_led, member)
69 
70 struct mt6370_led {
71 	struct led_classdev_flash flash;
72 	struct v4l2_flash *v4l2_flash;
73 	struct mt6370_priv *priv;
74 	u8 led_no;
75 };
76 
77 struct mt6370_priv {
78 	struct regmap *regmap;
79 	struct mutex lock;
80 	unsigned int fled_strobe_used;
81 	unsigned int fled_torch_used;
82 	unsigned int leds_active;
83 	unsigned int leds_count;
84 	struct mt6370_led leds[];
85 };
86 
mt6370_torch_brightness_set(struct led_classdev * lcdev,enum led_brightness level)87 static int mt6370_torch_brightness_set(struct led_classdev *lcdev, enum led_brightness level)
88 {
89 	struct mt6370_led *led = to_mt6370_led(lcdev, flash.led_cdev);
90 	struct mt6370_priv *priv = led->priv;
91 	u32 led_enable_mask = led->led_no == MT6370_LED_JOINT ? MT6370_FLCSEN_MASK_ALL :
92 			      MT6370_FLCSEN_MASK(led->led_no);
93 	u32 enable_mask = MT6370_TORCHEN_MASK | led_enable_mask;
94 	u32 val = level ? led_enable_mask : 0;
95 	u32 curr;
96 	int ret, i;
97 
98 	mutex_lock(&priv->lock);
99 
100 	/*
101 	 * There is only one set of flash control logic, and this flag is used to check if 'strobe'
102 	 * is currently being used.
103 	 */
104 	if (priv->fled_strobe_used) {
105 		dev_warn(lcdev->dev, "Please disable strobe first [%d]\n", priv->fled_strobe_used);
106 		ret = -EBUSY;
107 		goto unlock;
108 	}
109 
110 	if (level)
111 		curr = priv->fled_torch_used | BIT(led->led_no);
112 	else
113 		curr = priv->fled_torch_used & ~BIT(led->led_no);
114 
115 	if (curr)
116 		val |= MT6370_TORCHEN_MASK;
117 
118 	if (level) {
119 		level -= 1;
120 		if (led->led_no == MT6370_LED_JOINT) {
121 			u32 flevel[MT6370_MAX_LEDS];
122 
123 			/*
124 			 * There're two flash channels in MT6370. If joint flash output is used,
125 			 * torch current will be averaged output from both channels.
126 			 */
127 			flevel[0] = level / 2;
128 			flevel[1] = level - flevel[0];
129 			for (i = 0; i < MT6370_MAX_LEDS; i++) {
130 				ret = regmap_update_bits(priv->regmap, MT6370_REG_FLEDITOR(i),
131 							 MT6370_ITORCH_MASK, flevel[i]);
132 				if (ret)
133 					goto unlock;
134 			}
135 		} else {
136 			ret = regmap_update_bits(priv->regmap, MT6370_REG_FLEDITOR(led->led_no),
137 						 MT6370_ITORCH_MASK, level);
138 			if (ret)
139 				goto unlock;
140 		}
141 	}
142 
143 	ret = regmap_update_bits(priv->regmap, MT6370_REG_FLEDEN, enable_mask, val);
144 	if (ret)
145 		goto unlock;
146 
147 	priv->fled_torch_used = curr;
148 
149 unlock:
150 	mutex_unlock(&priv->lock);
151 	return ret;
152 }
153 
mt6370_flash_brightness_set(struct led_classdev_flash * fl_cdev,u32 brightness)154 static int mt6370_flash_brightness_set(struct led_classdev_flash *fl_cdev, u32 brightness)
155 {
156 	/*
157 	 * Because of the current spikes when turning on the flash, the brightness should be kept
158 	 * by the LED framework. This empty function is used to prevent checking failure when
159 	 * led_classdev_flash registers ops.
160 	 */
161 	return 0;
162 }
163 
_mt6370_flash_brightness_set(struct led_classdev_flash * fl_cdev,u32 brightness)164 static int _mt6370_flash_brightness_set(struct led_classdev_flash *fl_cdev, u32 brightness)
165 {
166 	struct mt6370_led *led = to_mt6370_led(fl_cdev, flash);
167 	struct mt6370_priv *priv = led->priv;
168 	struct led_flash_setting *setting = &fl_cdev->brightness;
169 	u32 val = (brightness - setting->min) / setting->step;
170 	int ret, i;
171 
172 	if (led->led_no == MT6370_LED_JOINT) {
173 		u32 flevel[MT6370_MAX_LEDS];
174 
175 		/*
176 		 * There're two flash channels in MT6370. If joint flash output is used, storbe
177 		 * current will be averaged output from both channels.
178 		 */
179 		flevel[0] = val / 2;
180 		flevel[1] = val - flevel[0];
181 		for (i = 0; i < MT6370_MAX_LEDS; i++) {
182 			ret = regmap_update_bits(priv->regmap, MT6370_REG_FLEDISTRB(i),
183 						 MT6370_ISTROBE_MASK, flevel[i]);
184 			if (ret)
185 				break;
186 		}
187 	} else {
188 		ret = regmap_update_bits(priv->regmap, MT6370_REG_FLEDISTRB(led->led_no),
189 					 MT6370_ISTROBE_MASK, val);
190 	}
191 
192 	return ret;
193 }
194 
mt6370_strobe_set(struct led_classdev_flash * fl_cdev,bool state)195 static int mt6370_strobe_set(struct led_classdev_flash *fl_cdev, bool state)
196 {
197 	struct mt6370_led *led = to_mt6370_led(fl_cdev, flash);
198 	struct mt6370_priv *priv = led->priv;
199 	struct led_classdev *lcdev = &fl_cdev->led_cdev;
200 	struct led_flash_setting *s = &fl_cdev->brightness;
201 	u32 led_enable_mask = led->led_no == MT6370_LED_JOINT ? MT6370_FLCSEN_MASK_ALL :
202 			      MT6370_FLCSEN_MASK(led->led_no);
203 	u32 enable_mask = MT6370_STROBEN_MASK | led_enable_mask;
204 	u32 val = state ? led_enable_mask : 0;
205 	u32 curr;
206 	int ret;
207 
208 	mutex_lock(&priv->lock);
209 
210 	/*
211 	 * There is only one set of flash control logic, and this flag is used to check if 'torch'
212 	 * is currently being used.
213 	 */
214 	if (priv->fled_torch_used) {
215 		dev_warn(lcdev->dev, "Please disable torch first [0x%x]\n", priv->fled_torch_used);
216 		ret = -EBUSY;
217 		goto unlock;
218 	}
219 
220 	if (state)
221 		curr = priv->fled_strobe_used | BIT(led->led_no);
222 	else
223 		curr = priv->fled_strobe_used & ~BIT(led->led_no);
224 
225 	if (curr)
226 		val |= MT6370_STROBEN_MASK;
227 
228 	ret = regmap_update_bits(priv->regmap, MT6370_REG_FLEDEN, enable_mask, val);
229 	if (ret) {
230 		dev_err(lcdev->dev, "[%d] control current source %d fail\n", led->led_no, state);
231 		goto unlock;
232 	}
233 
234 	/*
235 	 * If the flash needs to turn on, configure the flash current to ramp up to the setting
236 	 * value. Otherwise, always revert to the minimum one.
237 	 */
238 	ret = _mt6370_flash_brightness_set(fl_cdev, state ? s->val : s->min);
239 	if (ret) {
240 		dev_err(lcdev->dev, "[%d] Failed to set brightness\n", led->led_no);
241 		goto unlock;
242 	}
243 
244 	/*
245 	 * For the flash to turn on/off, we must wait for HW ramping up/down time 5ms/500us to
246 	 * prevent the unexpected problem.
247 	 */
248 	if (!priv->fled_strobe_used && curr)
249 		usleep_range(5000, 6000);
250 	else if (priv->fled_strobe_used && !curr)
251 		usleep_range(500, 600);
252 
253 	priv->fled_strobe_used = curr;
254 
255 unlock:
256 	mutex_unlock(&priv->lock);
257 	return ret;
258 }
259 
mt6370_strobe_get(struct led_classdev_flash * fl_cdev,bool * state)260 static int mt6370_strobe_get(struct led_classdev_flash *fl_cdev, bool *state)
261 {
262 	struct mt6370_led *led = to_mt6370_led(fl_cdev, flash);
263 	struct mt6370_priv *priv = led->priv;
264 
265 	mutex_lock(&priv->lock);
266 	*state = !!(priv->fled_strobe_used & BIT(led->led_no));
267 	mutex_unlock(&priv->lock);
268 
269 	return 0;
270 }
271 
mt6370_timeout_set(struct led_classdev_flash * fl_cdev,u32 timeout)272 static int mt6370_timeout_set(struct led_classdev_flash *fl_cdev, u32 timeout)
273 {
274 	struct mt6370_led *led = to_mt6370_led(fl_cdev, flash);
275 	struct mt6370_priv *priv = led->priv;
276 	struct led_flash_setting *s = &fl_cdev->timeout;
277 	u32 val = (timeout - s->min) / s->step;
278 
279 	return regmap_update_bits(priv->regmap, MT6370_REG_STRBTO, MT6370_STRBTO_MASK, val);
280 }
281 
mt6370_fault_get(struct led_classdev_flash * fl_cdev,u32 * fault)282 static int mt6370_fault_get(struct led_classdev_flash *fl_cdev, u32 *fault)
283 {
284 	struct mt6370_led *led = to_mt6370_led(fl_cdev, flash);
285 	struct mt6370_priv *priv = led->priv;
286 	u16 fled_stat;
287 	unsigned int chg_stat, strobe_timeout_mask, fled_short_mask;
288 	u32 rfault = 0;
289 	int ret;
290 
291 	ret = regmap_read(priv->regmap, MT6370_REG_CHGSTAT2, &chg_stat);
292 	if (ret)
293 		return ret;
294 
295 	ret = regmap_raw_read(priv->regmap, MT6370_REG_FLEDSTAT1, &fled_stat, sizeof(fled_stat));
296 	if (ret)
297 		return ret;
298 
299 	switch (led->led_no) {
300 	case MT6370_LED_FLASH1:
301 		strobe_timeout_mask = MT6370_FLED1STRBTO_MASK;
302 		fled_short_mask = MT6370_FLED1SHORT_MASK;
303 		break;
304 
305 	case MT6370_LED_FLASH2:
306 		strobe_timeout_mask = MT6370_FLED2STRBTO_MASK;
307 		fled_short_mask = MT6370_FLED2SHORT_MASK;
308 		break;
309 
310 	case MT6370_LED_JOINT:
311 		strobe_timeout_mask = MT6370_FLED1STRBTO_MASK | MT6370_FLED2STRBTO_MASK;
312 		fled_short_mask = MT6370_FLED1SHORT_MASK | MT6370_FLED2SHORT_MASK;
313 		break;
314 	default:
315 		return -EINVAL;
316 	}
317 
318 	if (chg_stat & MT6370_FLEDCHGVINOVP_MASK)
319 		rfault |= LED_FAULT_INPUT_VOLTAGE;
320 
321 	if (fled_stat & strobe_timeout_mask)
322 		rfault |= LED_FAULT_TIMEOUT;
323 
324 	if (fled_stat & fled_short_mask)
325 		rfault |= LED_FAULT_SHORT_CIRCUIT;
326 
327 	if (fled_stat & MT6370_FLEDLVF_MASK)
328 		rfault |= LED_FAULT_UNDER_VOLTAGE;
329 
330 	*fault = rfault;
331 	return ret;
332 }
333 
334 static const struct led_flash_ops mt6370_flash_ops = {
335 	.flash_brightness_set = mt6370_flash_brightness_set,
336 	.strobe_set = mt6370_strobe_set,
337 	.strobe_get = mt6370_strobe_get,
338 	.timeout_set = mt6370_timeout_set,
339 	.fault_get = mt6370_fault_get,
340 };
341 
342 #if IS_ENABLED(CONFIG_V4L2_FLASH_LED_CLASS)
mt6370_flash_external_strobe_set(struct v4l2_flash * v4l2_flash,bool enable)343 static int mt6370_flash_external_strobe_set(struct v4l2_flash *v4l2_flash,
344 					    bool enable)
345 {
346 	struct led_classdev_flash *flash = v4l2_flash->fled_cdev;
347 	struct mt6370_led *led = to_mt6370_led(flash, flash);
348 	struct mt6370_priv *priv = led->priv;
349 	u32 mask = led->led_no == MT6370_LED_JOINT ? MT6370_FLCSEN_MASK_ALL :
350 		   MT6370_FLCSEN_MASK(led->led_no);
351 	u32 val = enable ? mask : 0;
352 	int ret;
353 
354 	mutex_lock(&priv->lock);
355 
356 	ret = regmap_update_bits(priv->regmap, MT6370_REG_FLEDEN, mask, val);
357 	if (ret)
358 		goto unlock;
359 
360 	if (enable)
361 		priv->fled_strobe_used |= BIT(led->led_no);
362 	else
363 		priv->fled_strobe_used &= ~BIT(led->led_no);
364 
365 unlock:
366 	mutex_unlock(&priv->lock);
367 	return ret;
368 }
369 
370 static const struct v4l2_flash_ops v4l2_flash_ops = {
371 	.external_strobe_set = mt6370_flash_external_strobe_set,
372 };
373 
mt6370_init_v4l2_flash_config(struct mt6370_led * led,struct v4l2_flash_config * cfg)374 static void mt6370_init_v4l2_flash_config(struct mt6370_led *led, struct v4l2_flash_config *cfg)
375 {
376 	struct led_classdev *lcdev;
377 	struct led_flash_setting *s = &cfg->intensity;
378 
379 	lcdev = &led->flash.led_cdev;
380 
381 	s->min = MT6370_ITORCH_MIN_uA;
382 	s->step = MT6370_ITORCH_STEP_uA;
383 	s->val = s->max = s->min + (lcdev->max_brightness - 1) * s->step;
384 
385 	cfg->has_external_strobe = 1;
386 	strscpy(cfg->dev_name, dev_name(lcdev->dev), sizeof(cfg->dev_name));
387 
388 	cfg->flash_faults = LED_FAULT_SHORT_CIRCUIT | LED_FAULT_TIMEOUT |
389 			    LED_FAULT_INPUT_VOLTAGE | LED_FAULT_UNDER_VOLTAGE;
390 }
391 #else
392 static const struct v4l2_flash_ops v4l2_flash_ops;
mt6370_init_v4l2_flash_config(struct mt6370_led * led,struct v4l2_flash_config * cfg)393 static void mt6370_init_v4l2_flash_config(struct mt6370_led *led, struct v4l2_flash_config *cfg)
394 {
395 }
396 #endif
397 
mt6370_v4l2_flash_release(void * v4l2_flash)398 static void mt6370_v4l2_flash_release(void *v4l2_flash)
399 {
400 	v4l2_flash_release(v4l2_flash);
401 }
402 
mt6370_led_register(struct device * parent,struct mt6370_led * led,struct fwnode_handle * fwnode)403 static int mt6370_led_register(struct device *parent, struct mt6370_led *led,
404 			       struct fwnode_handle *fwnode)
405 {
406 	struct led_init_data init_data = { .fwnode = fwnode };
407 	struct v4l2_flash_config v4l2_config = {};
408 	int ret;
409 
410 	ret = devm_led_classdev_flash_register_ext(parent, &led->flash, &init_data);
411 	if (ret)
412 		return dev_err_probe(parent, ret, "Couldn't register flash %d\n", led->led_no);
413 
414 	mt6370_init_v4l2_flash_config(led, &v4l2_config);
415 	led->v4l2_flash = v4l2_flash_init(parent, fwnode, &led->flash, &v4l2_flash_ops,
416 					  &v4l2_config);
417 	if (IS_ERR(led->v4l2_flash))
418 		return dev_err_probe(parent, PTR_ERR(led->v4l2_flash),
419 				     "Failed to register %d v4l2 sd\n", led->led_no);
420 
421 	return devm_add_action_or_reset(parent, mt6370_v4l2_flash_release, led->v4l2_flash);
422 }
423 
mt6370_clamp(u32 val,u32 min,u32 max,u32 step)424 static u32 mt6370_clamp(u32 val, u32 min, u32 max, u32 step)
425 {
426 	u32 retval;
427 
428 	retval = clamp_val(val, min, max);
429 	if (step > 1)
430 		retval = rounddown(retval - min, step) + min;
431 
432 	return retval;
433 }
434 
mt6370_init_flash_properties(struct device * dev,struct mt6370_led * led,struct fwnode_handle * fwnode)435 static int mt6370_init_flash_properties(struct device *dev, struct mt6370_led *led,
436 					struct fwnode_handle *fwnode)
437 {
438 	struct led_classdev_flash *flash = &led->flash;
439 	struct led_classdev *lcdev = &flash->led_cdev;
440 	struct mt6370_priv *priv = led->priv;
441 	struct led_flash_setting *s;
442 	u32 sources[MT6370_MAX_LEDS];
443 	u32 max_ua, val;
444 	int i, ret, num;
445 
446 	num = fwnode_property_count_u32(fwnode, "led-sources");
447 	if (num < 1)
448 		return dev_err_probe(dev, -EINVAL,
449 				     "Not specified or wrong number of led-sources\n");
450 
451 	ret = fwnode_property_read_u32_array(fwnode, "led-sources", sources, num);
452 	if (ret)
453 		return ret;
454 
455 	for (i = 0; i < num; i++) {
456 		if (sources[i] >= MT6370_MAX_LEDS)
457 			return -EINVAL;
458 		if (priv->leds_active & BIT(sources[i]))
459 			return -EINVAL;
460 		priv->leds_active |= BIT(sources[i]);
461 	}
462 
463 	/* If both channels are specified in 'led-sources', joint flash output mode is used */
464 	led->led_no = num == 2 ? MT6370_LED_JOINT : sources[0];
465 
466 	max_ua = num == 2 ? MT6370_ITORCH_DOUBLE_MAX_uA : MT6370_ITORCH_MAX_uA;
467 	val = MT6370_ITORCH_MIN_uA;
468 	ret = fwnode_property_read_u32(fwnode, "led-max-microamp", &val);
469 	if (!ret)
470 		val = mt6370_clamp(val, MT6370_ITORCH_MIN_uA, max_ua, MT6370_ITORCH_STEP_uA);
471 
472 	lcdev->max_brightness = (val - MT6370_ITORCH_MIN_uA) / MT6370_ITORCH_STEP_uA + 1;
473 	lcdev->brightness_set_blocking = mt6370_torch_brightness_set;
474 	lcdev->flags |= LED_DEV_CAP_FLASH;
475 
476 	max_ua = num == 2 ? MT6370_ISTRB_DOUBLE_MAX_uA : MT6370_ISTRB_MAX_uA;
477 	val = MT6370_ISTRB_MIN_uA;
478 	ret = fwnode_property_read_u32(fwnode, "flash-max-microamp", &val);
479 	if (!ret)
480 		val = mt6370_clamp(val, MT6370_ISTRB_MIN_uA, max_ua, MT6370_ISTRB_STEP_uA);
481 
482 	s = &flash->brightness;
483 	s->min = MT6370_ISTRB_MIN_uA;
484 	s->step = MT6370_ISTRB_STEP_uA;
485 	s->val = s->max = val;
486 
487 	/* Always configure to the minimum level when off to prevent flash current spikes. */
488 	ret = _mt6370_flash_brightness_set(flash, s->min);
489 	if (ret)
490 		return ret;
491 
492 	val = MT6370_STRBTO_MIN_US;
493 	ret = fwnode_property_read_u32(fwnode, "flash-max-timeout-us", &val);
494 	if (!ret)
495 		val = mt6370_clamp(val, MT6370_STRBTO_MIN_US, MT6370_STRBTO_MAX_US,
496 				   MT6370_STRBTO_STEP_US);
497 
498 	s = &flash->timeout;
499 	s->min = MT6370_STRBTO_MIN_US;
500 	s->step = MT6370_STRBTO_STEP_US;
501 	s->val = s->max = val;
502 
503 	flash->ops = &mt6370_flash_ops;
504 
505 	return 0;
506 }
507 
mt6370_led_probe(struct platform_device * pdev)508 static int mt6370_led_probe(struct platform_device *pdev)
509 {
510 	struct device *dev = &pdev->dev;
511 	struct mt6370_priv *priv;
512 	struct fwnode_handle *child;
513 	size_t count;
514 	int i = 0, ret;
515 
516 	count = device_get_child_node_count(dev);
517 	if (!count || count > MT6370_MAX_LEDS)
518 		return dev_err_probe(dev, -EINVAL,
519 		       "No child node or node count over max led number %zu\n", count);
520 
521 	priv = devm_kzalloc(dev, struct_size(priv, leds, count), GFP_KERNEL);
522 	if (!priv)
523 		return -ENOMEM;
524 
525 	priv->leds_count = count;
526 	mutex_init(&priv->lock);
527 
528 	priv->regmap = dev_get_regmap(dev->parent, NULL);
529 	if (!priv->regmap)
530 		return dev_err_probe(dev, -ENODEV, "Failed to get parent regmap\n");
531 
532 	device_for_each_child_node(dev, child) {
533 		struct mt6370_led *led = priv->leds + i;
534 
535 		led->priv = priv;
536 
537 		ret = mt6370_init_flash_properties(dev, led, child);
538 		if (ret) {
539 			fwnode_handle_put(child);
540 			return ret;
541 		}
542 
543 		ret = mt6370_led_register(dev, led, child);
544 		if (ret) {
545 			fwnode_handle_put(child);
546 			return ret;
547 		}
548 
549 		i++;
550 	}
551 
552 	return 0;
553 }
554 
555 static const struct of_device_id mt6370_led_of_id[] = {
556 	{ .compatible = "mediatek,mt6370-flashlight" },
557 	{}
558 };
559 MODULE_DEVICE_TABLE(of, mt6370_led_of_id);
560 
561 static struct platform_driver mt6370_led_driver = {
562 	.driver = {
563 		.name = "mt6370-flashlight",
564 		.of_match_table = mt6370_led_of_id,
565 	},
566 	.probe = mt6370_led_probe,
567 };
568 module_platform_driver(mt6370_led_driver);
569 
570 MODULE_AUTHOR("Alice Chen <alice_chen@richtek.com>");
571 MODULE_AUTHOR("ChiYuan Huang <cy_huang@richtek.com>");
572 MODULE_DESCRIPTION("MT6370 FLASH LED Driver");
573 MODULE_LICENSE("GPL");
574