1 // SPDX-License-Identifier: GPL-2.0
2 // Copyright (c) 2019 Fuzhou Rockchip Electronics Co., Ltd.
3 /*
4 * v0.1.1 Fix the bug that when pwm is disabled, the light cannot be turned off
5 */
6 #include <media/v4l2-ctrls.h>
7 #include <media/v4l2-subdev.h>
8 #include <linux/delay.h>
9 #include <linux/gpio/consumer.h>
10 #include <linux/led-class-flash.h>
11 #include <linux/leds.h>
12 #include <linux/module.h>
13 #include <linux/mutex.h>
14 #include <linux/of.h>
15 #include <linux/pinctrl/consumer.h>
16 #include <linux/platform_device.h>
17 #include <linux/rk-camera-module.h>
18 #include <linux/rk-led-flash.h>
19 #include <linux/slab.h>
20 #include <linux/workqueue.h>
21 #include <linux/version.h>
22 #include <linux/pwm.h>
23 #include <linux/compat.h>
24
25 #define DRIVER_VERSION KERNEL_VERSION(0, 0x01, 0x1)
26
27 #define FLASH_TIMEOUT_MIN 1000
28 #define FLASH_TIMEOUT_STEP 1000
29
30 struct rgb13h_led {
31 struct platform_device *pdev;
32 struct led_classdev_flash fled_cdev;
33 struct v4l2_ctrl_handler ctrls;
34 struct v4l2_subdev sd;
35 /* secures access to the device */
36 struct mutex lock;
37 struct gpio_desc *gpio_en;
38 /* maximum LED current in torch mode*/
39 u32 max_mm_current;
40 /* maximum LED current in flash mode */
41 u32 max_flash_current;
42 /* maximum flash timeout */
43 u32 max_flash_tm;
44 u32 intensity;
45 u32 intensity_torch;
46 bool strobe_state;
47 /* brightness cache */
48 u32 torch_brightness;
49 /* assures led-triggers compatibility */
50 struct work_struct work_brightness_set;
51
52 struct __kernel_old_timeval timestamp;
53
54 u32 timeout;
55 bool waiting;
56 wait_queue_head_t done;
57 struct work_struct work_timeout;
58
59 enum v4l2_flash_led_mode led_mode;
60
61 u32 module_index;
62 const char *module_facing;
63 struct pwm_device *pwm;
64 struct pwm_state pwm_state;
65 };
66
fled_cdev_to_led(struct led_classdev_flash * fled_cdev)67 static struct rgb13h_led *fled_cdev_to_led(struct led_classdev_flash *fled_cdev)
68 {
69 return container_of(fled_cdev, struct rgb13h_led, fled_cdev);
70 }
71
sd_to_led(struct v4l2_subdev * subdev)72 static struct rgb13h_led *sd_to_led(struct v4l2_subdev *subdev)
73 {
74 return container_of(subdev, struct rgb13h_led, sd);
75 }
76
rgb13h_set_output(struct rgb13h_led * led,bool on)77 static int rgb13h_set_output(struct rgb13h_led *led, bool on)
78 {
79 mutex_lock(&led->lock);
80 if (!IS_ERR(led->gpio_en))
81 gpiod_direction_output(led->gpio_en, on);
82 if (!IS_ERR(led->pwm)) {
83 if (led->led_mode == V4L2_FLASH_LED_MODE_TORCH)
84 led->pwm_state.duty_cycle =
85 div_u64(led->intensity_torch * led->pwm_state.period, led->max_mm_current);
86 else
87 led->pwm_state.duty_cycle =
88 div_u64(led->intensity * led->pwm_state.period, led->max_flash_current);
89 if (on) {
90 led->pwm_state.enabled = true;
91 pwm_apply_state(led->pwm, &led->pwm_state);
92 dev_dbg(&led->pdev->dev, "led pwm duty=%llu, period=%llu, polarity=%d\n",
93 led->pwm_state.duty_cycle, led->pwm_state.period, led->pwm_state.polarity);
94 } else {
95 led->pwm_state.enabled = false;
96 pwm_apply_state(led->pwm, &led->pwm_state);
97 }
98 }
99 if (!on) {
100 led->strobe_state = false;
101 if (led->waiting) {
102 led->waiting = false;
103 wake_up(&led->done);
104 }
105 } else {
106 led->timestamp = ns_to_kernel_old_timeval(ktime_get_ns());
107 }
108 mutex_unlock(&led->lock);
109 return 0;
110 }
111
rgb13h_timeout_work(struct work_struct * work)112 static void rgb13h_timeout_work(struct work_struct *work)
113 {
114 struct rgb13h_led *led =
115 container_of(work, struct rgb13h_led, work_timeout);
116
117 wait_event_timeout(led->done, !led->waiting,
118 usecs_to_jiffies(led->timeout));
119 if (led->waiting) {
120 led->waiting = false;
121 led->strobe_state = false;
122 rgb13h_set_output(led, false);
123 }
124 }
125
rgb13h_brightness_set_work(struct work_struct * work)126 static void rgb13h_brightness_set_work(struct work_struct *work)
127 {
128 struct rgb13h_led *led =
129 container_of(work, struct rgb13h_led, work_brightness_set);
130
131 rgb13h_set_output(led, !!led->torch_brightness);
132 }
133
rgb13h_led_brightness_set(struct led_classdev * led_cdev,enum led_brightness brightness)134 static void rgb13h_led_brightness_set(struct led_classdev *led_cdev,
135 enum led_brightness brightness)
136 {
137 struct led_classdev_flash *fled_cdev = lcdev_to_flcdev(led_cdev);
138 struct rgb13h_led *led = fled_cdev_to_led(fled_cdev);
139
140 led->torch_brightness = brightness;
141 schedule_work(&led->work_brightness_set);
142 }
143
rgb13h_led_brightness_set_sync(struct led_classdev * led_cdev,enum led_brightness brightness)144 static int rgb13h_led_brightness_set_sync(struct led_classdev *led_cdev,
145 enum led_brightness brightness)
146 {
147 struct led_classdev_flash *fled_cdev = lcdev_to_flcdev(led_cdev);
148 struct rgb13h_led *led = fled_cdev_to_led(fled_cdev);
149
150 rgb13h_set_output(led, !!brightness);
151 return 0;
152 }
153
rgb13h_led_flash_strobe_set(struct led_classdev_flash * fled_cdev,bool state)154 static int rgb13h_led_flash_strobe_set(struct led_classdev_flash *fled_cdev,
155 bool state)
156
157 {
158 struct rgb13h_led *led = fled_cdev_to_led(fled_cdev);
159
160 mutex_lock(&led->lock);
161 led->strobe_state = state;
162 if (state) {
163 led->waiting = true;
164 schedule_work(&led->work_timeout);
165 }
166 mutex_unlock(&led->lock);
167
168 return rgb13h_set_output(led, state);
169 }
170
rgb13h_led_flash_strobe_get(struct led_classdev_flash * fled_cdev,bool * state)171 static int rgb13h_led_flash_strobe_get(struct led_classdev_flash *fled_cdev,
172 bool *state)
173 {
174 struct rgb13h_led *led = fled_cdev_to_led(fled_cdev);
175
176 mutex_lock(&led->lock);
177 *state = led->strobe_state;
178 mutex_unlock(&led->lock);
179 return 0;
180 }
181
rgb13h_led_flash_timeout_set(struct led_classdev_flash * fled_cdev,u32 timeout)182 static int rgb13h_led_flash_timeout_set(struct led_classdev_flash *fled_cdev,
183 u32 timeout)
184 {
185 struct rgb13h_led *led = fled_cdev_to_led(fled_cdev);
186
187 mutex_lock(&led->lock);
188 led->timeout = timeout;
189 mutex_unlock(&led->lock);
190 return 0;
191 }
192
rgb13h_led_parse_dt(struct rgb13h_led * led,struct device_node ** sub_node)193 static int rgb13h_led_parse_dt(struct rgb13h_led *led,
194 struct device_node **sub_node)
195 {
196 struct led_classdev *led_cdev = &led->fled_cdev.led_cdev;
197 struct device *dev = &led->pdev->dev;
198 struct device_node *child_node = dev->of_node;
199 int ret = 0;
200
201 ret = of_property_read_u32(child_node,
202 RKMODULE_CAMERA_MODULE_INDEX,
203 &led->module_index);
204 ret |= of_property_read_string(child_node,
205 RKMODULE_CAMERA_MODULE_FACING,
206 &led->module_facing);
207 if (ret) {
208 dev_err(dev, "could not get module information!\n");
209 return -EINVAL;
210 }
211
212 led->gpio_en = devm_gpiod_get(dev, "enable", GPIOD_ASIS);
213 if (IS_ERR(led->gpio_en)) {
214 ret = PTR_ERR(led->gpio_en);
215 dev_info(dev, "Unable to claim enable-gpio\n");
216 }
217 led->pwm = devm_pwm_get(dev, NULL);
218 if (IS_ERR(led->pwm)) {
219 ret = PTR_ERR(led->pwm);
220 dev_info(dev, "Unable to get pwm device\n");
221 } else {
222 led->pwm_state.period = led->pwm->args.period;
223 led->pwm_state.polarity = led->pwm->args.polarity;
224 dev_dbg(dev, "period %llu, polarity %d\n",
225 led->pwm_state.period, led->pwm_state.polarity);
226 }
227 if (IS_ERR(led->gpio_en) && IS_ERR(led->pwm)) {
228 dev_err(dev, "Neither enable-gpio nor pwm can be get,return error\n");
229 return ret;
230 }
231
232 led_cdev->name = of_get_property(child_node, "label", NULL) ? :
233 child_node->name;
234
235 ret = of_property_read_u32(child_node, "led-max-microamp",
236 &led->max_mm_current);
237 if (ret < 0)
238 dev_warn(dev,
239 "led-max-microamp DT property missing\n");
240 if (led->max_mm_current <= 0) {
241 led->max_mm_current = 20000;
242 dev_warn(dev,
243 "get led-max-microamp error value, used default value 20000\n");
244 }
245
246 ret = of_property_read_u32(child_node, "flash-max-microamp",
247 &led->max_flash_current);
248 if (ret < 0) {
249 dev_err(dev,
250 "flash-max-microamp DT property missing\n");
251 return ret;
252 }
253 if (led->max_flash_current <= 0) {
254 led->max_flash_current = 20000;
255 dev_warn(dev,
256 "get flash-max-microamp error value, used default value 20000\n");
257 }
258
259 ret = of_property_read_u32(child_node, "flash-max-timeout-us",
260 &led->max_flash_tm);
261 if (ret < 0) {
262 dev_err(dev,
263 "flash-max-timeout-us DT property missing\n");
264 return ret;
265 }
266 if (led->max_flash_tm <= 0) {
267 led->max_flash_tm = 1000000;
268 dev_warn(dev,
269 "get flash-max-timeout-us error value, used default value 1s\n");
270 }
271
272 *sub_node = child_node;
273 return ret;
274 }
275
rgb13h_led_get_configuration(struct rgb13h_led * led,struct device_node ** sub_node)276 static int rgb13h_led_get_configuration(struct rgb13h_led *led,
277 struct device_node **sub_node)
278 {
279 int ret;
280
281 ret = rgb13h_led_parse_dt(led, sub_node);
282 if (ret < 0)
283 return ret;
284
285 return 0;
286 }
287
rgb13h_init_flash_timeout(struct rgb13h_led * led)288 static void rgb13h_init_flash_timeout(struct rgb13h_led *led)
289 {
290 struct led_classdev_flash *fled_cdev = &led->fled_cdev;
291 struct led_flash_setting *setting;
292
293 /* Init flash timeout setting */
294 setting = &fled_cdev->timeout;
295 setting->min = FLASH_TIMEOUT_MIN;
296 setting->max = led->max_flash_tm;
297 setting->step = FLASH_TIMEOUT_STEP;
298 setting->val = setting->max;
299 }
300
rgb13h_get_ctrl(struct v4l2_ctrl * ctrl)301 static int rgb13h_get_ctrl(struct v4l2_ctrl *ctrl)
302 {
303 struct rgb13h_led *led =
304 container_of(ctrl->handler, struct rgb13h_led, ctrls);
305
306 switch (ctrl->id) {
307 case V4L2_CID_FLASH_FAULT:
308 ctrl->val = 0;
309 break;
310 case V4L2_CID_FLASH_STROBE_STATUS:
311 if (led->led_mode != V4L2_FLASH_LED_MODE_FLASH) {
312 ctrl->val = 0;
313 break;
314 }
315 ctrl->val = led->strobe_state;
316 break;
317 case V4L2_CID_FLASH_INTENSITY:
318 ctrl->val = led->intensity;
319 break;
320 case V4L2_CID_FLASH_TORCH_INTENSITY:
321 ctrl->val = led->intensity_torch;
322 break;
323 case V4L2_CID_FLASH_LED_MODE:
324 ctrl->val = led->led_mode;
325 break;
326 default:
327 dev_err(&led->pdev->dev,
328 "ctrl 0x%x not supported\n", ctrl->id);
329 return -EINVAL;
330 }
331
332 return 0;
333 }
334
rgb13h_set_ctrl(struct v4l2_ctrl * ctrl)335 static int rgb13h_set_ctrl(struct v4l2_ctrl *ctrl)
336 {
337 struct rgb13h_led *led =
338 container_of(ctrl->handler, struct rgb13h_led, ctrls);
339
340 switch (ctrl->id) {
341 case V4L2_CID_FLASH_LED_MODE:
342 led->led_mode = ctrl->val;
343 rgb13h_set_output(led, LED_OFF);
344 if (led->led_mode == V4L2_FLASH_LED_MODE_TORCH)
345 return rgb13h_set_output(led, LED_ON);
346 break;
347
348 case V4L2_CID_FLASH_STROBE_SOURCE:
349 if (ctrl->val == V4L2_FLASH_STROBE_SOURCE_EXTERNAL)
350 return -EBUSY;
351 break;
352 case V4L2_CID_FLASH_STROBE:
353 if (led->led_mode != V4L2_FLASH_LED_MODE_FLASH)
354 return -EBUSY;
355 return rgb13h_led_flash_strobe_set(&led->fled_cdev, true);
356 case V4L2_CID_FLASH_STROBE_STOP:
357 if (led->led_mode != V4L2_FLASH_LED_MODE_FLASH)
358 return -EBUSY;
359 return rgb13h_led_flash_strobe_set(&led->fled_cdev, false);
360 case V4L2_CID_FLASH_TIMEOUT:
361 return rgb13h_led_flash_timeout_set(&led->fled_cdev, ctrl->val);
362 case V4L2_CID_FLASH_INTENSITY:
363 led->intensity = ctrl->val;
364 break;
365 case V4L2_CID_FLASH_TORCH_INTENSITY:
366 led->intensity_torch = ctrl->val;
367 if (led->led_mode != V4L2_FLASH_LED_MODE_TORCH)
368 break;
369 return rgb13h_set_output(led, LED_ON);
370 default:
371 dev_err(&led->pdev->dev,
372 "ctrl 0x%x not supported\n", ctrl->id);
373 return -EINVAL;
374 }
375 return 0;
376 }
377
378 static const struct v4l2_ctrl_ops rgb13h_ctrl_ops = {
379 .g_volatile_ctrl = rgb13h_get_ctrl,
380 .s_ctrl = rgb13h_set_ctrl,
381 };
382
rgb13h_init_controls(struct rgb13h_led * led)383 static int rgb13h_init_controls(struct rgb13h_led *led)
384 {
385 struct v4l2_ctrl *ctrl = NULL;
386
387 v4l2_ctrl_handler_init(&led->ctrls, 10);
388 /* V4L2_CID_FLASH_LED_MODE */
389 v4l2_ctrl_new_std_menu(&led->ctrls, &rgb13h_ctrl_ops,
390 V4L2_CID_FLASH_LED_MODE, 2, ~7,
391 V4L2_FLASH_LED_MODE_NONE);
392 led->led_mode = V4L2_FLASH_LED_MODE_NONE;
393 /* V4L2_CID_FLASH_STROBE_SOURCE */
394 v4l2_ctrl_new_std_menu(&led->ctrls, &rgb13h_ctrl_ops,
395 V4L2_CID_FLASH_STROBE_SOURCE,
396 0, ~1, V4L2_FLASH_STROBE_SOURCE_SOFTWARE);
397 /* V4L2_CID_FLASH_STROBE */
398 v4l2_ctrl_new_std(&led->ctrls, &rgb13h_ctrl_ops,
399 V4L2_CID_FLASH_STROBE, 0, 0, 0, 0);
400 /* V4L2_CID_FLASH_STROBE_STOP */
401 v4l2_ctrl_new_std(&led->ctrls, &rgb13h_ctrl_ops,
402 V4L2_CID_FLASH_STROBE_STOP, 0, 0, 0, 0);
403 /* V4L2_CID_FLASH_STROBE_STATUS */
404 ctrl = v4l2_ctrl_new_std(&led->ctrls, &rgb13h_ctrl_ops,
405 V4L2_CID_FLASH_STROBE_STATUS,
406 0, 1, 1, 0);
407 led->strobe_state = false;
408 if (ctrl)
409 ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
410 /* V4L2_CID_FLASH_TIMEOUT */
411 v4l2_ctrl_new_std(&led->ctrls, &rgb13h_ctrl_ops,
412 V4L2_CID_FLASH_TIMEOUT, FLASH_TIMEOUT_MIN,
413 led->max_flash_tm, FLASH_TIMEOUT_STEP,
414 led->max_flash_tm);
415 led->timeout = led->max_flash_tm;
416 /* V4L2_CID_FLASH_INTENSITY */
417 ctrl = v4l2_ctrl_new_std(&led->ctrls, &rgb13h_ctrl_ops,
418 V4L2_CID_FLASH_INTENSITY, 0,
419 led->max_flash_current,
420 1,
421 led->max_flash_current);
422 if (ctrl && IS_ERR(led->pwm))
423 ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
424 led->intensity = led->max_flash_current;
425 /* V4L2_CID_FLASH_TORCH_INTENSITY */
426 ctrl = v4l2_ctrl_new_std(&led->ctrls, &rgb13h_ctrl_ops,
427 V4L2_CID_FLASH_TORCH_INTENSITY, 0,
428 led->max_mm_current,
429 1,
430 led->max_mm_current);
431 if (ctrl && IS_ERR(led->pwm))
432 ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
433 led->intensity_torch = led->max_mm_current;
434
435 /* V4L2_CID_FLASH_FAULT */
436 ctrl = v4l2_ctrl_new_std(&led->ctrls, &rgb13h_ctrl_ops,
437 V4L2_CID_FLASH_FAULT, 0,
438 V4L2_FLASH_FAULT_OVER_VOLTAGE |
439 V4L2_FLASH_FAULT_TIMEOUT |
440 V4L2_FLASH_FAULT_OVER_TEMPERATURE |
441 V4L2_FLASH_FAULT_SHORT_CIRCUIT, 0, 0);
442 if (ctrl)
443 ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
444 led->sd.ctrl_handler = &led->ctrls;
445 return led->ctrls.error;
446 }
447
rgb13h_ioctl(struct v4l2_subdev * sd,unsigned int cmd,void * arg)448 static long rgb13h_ioctl(struct v4l2_subdev *sd,
449 unsigned int cmd, void *arg)
450 {
451 struct rgb13h_led *led = sd_to_led(sd);
452 struct __kernel_old_timeval *t;
453
454 if (cmd == RK_VIDIOC_FLASH_TIMEINFO) {
455 t = (struct __kernel_old_timeval *)arg;
456 t->tv_sec = led->timestamp.tv_sec;
457 t->tv_usec = led->timestamp.tv_usec;
458 } else {
459 return -EINVAL;
460 }
461 return 0;
462 }
463
464 #ifdef CONFIG_COMPAT
465 #define RK_VIDIOC_COMPAT_FLASH_TIMEINFO \
466 _IOR('V', BASE_VIDIOC_PRIVATE + 0, struct old_timeval32)
rgb13h_compat_ioctl32(struct v4l2_subdev * sd,unsigned int cmd,unsigned long arg)467 static long rgb13h_compat_ioctl32(struct v4l2_subdev *sd,
468 unsigned int cmd,
469 unsigned long arg)
470 {
471 struct __kernel_old_timeval t;
472 struct old_timeval32 compat_t;
473 struct old_timeval32 __user *p32 = compat_ptr(arg);
474
475 if (cmd == RK_VIDIOC_COMPAT_FLASH_TIMEINFO) {
476 rgb13h_ioctl(sd, RK_VIDIOC_FLASH_TIMEINFO, &t);
477 compat_t.tv_sec = t.tv_sec;
478 compat_t.tv_usec = t.tv_usec;
479 put_user(compat_t.tv_sec, &p32->tv_sec);
480 put_user(compat_t.tv_usec, &p32->tv_usec);
481 } else {
482 return -EINVAL;
483 }
484
485 return 0;
486 }
487 #endif
488
489 static const struct v4l2_subdev_core_ops v4l2_flash_core_ops = {
490 .ioctl = rgb13h_ioctl,
491 #ifdef CONFIG_COMPAT
492 .compat_ioctl32 = rgb13h_compat_ioctl32
493 #endif
494 };
495
496 static const struct v4l2_subdev_ops v4l2_flash_subdev_ops = {
497 .core = &v4l2_flash_core_ops,
498 };
499
500 static const struct led_flash_ops flash_ops = {
501 .strobe_set = rgb13h_led_flash_strobe_set,
502 .strobe_get = rgb13h_led_flash_strobe_get,
503 .timeout_set = rgb13h_led_flash_timeout_set,
504 };
505
rgb13h_led_probe(struct platform_device * pdev)506 static int rgb13h_led_probe(struct platform_device *pdev)
507 {
508 struct device *dev = &pdev->dev;
509 struct device_node *sub_node = NULL;
510 struct rgb13h_led *led;
511 struct led_classdev *led_cdev;
512 struct led_classdev_flash *fled_cdev;
513 struct v4l2_subdev *sd = NULL;
514 char facing[2];
515 int ret;
516
517 dev_info(dev, "driver version: %02x.%02x.%02x",
518 DRIVER_VERSION >> 16,
519 (DRIVER_VERSION & 0xff00) >> 8,
520 DRIVER_VERSION & 0x00ff);
521
522 led = devm_kzalloc(dev, sizeof(*led), GFP_KERNEL);
523 if (!led)
524 return -ENOMEM;
525
526 led->pdev = pdev;
527 platform_set_drvdata(pdev, led);
528
529 fled_cdev = &led->fled_cdev;
530 fled_cdev->ops = &flash_ops;
531 led_cdev = &fled_cdev->led_cdev;
532
533 ret = rgb13h_led_get_configuration(led, &sub_node);
534 if (ret < 0)
535 return ret;
536
537 mutex_init(&led->lock);
538
539 /* Initialize LED Flash class device */
540 led_cdev->brightness_set = rgb13h_led_brightness_set;
541 led_cdev->brightness_set_blocking = rgb13h_led_brightness_set_sync;
542 led_cdev->max_brightness = LED_FULL;
543 led_cdev->flags |= LED_DEV_CAP_FLASH;
544 INIT_WORK(&led->work_brightness_set, rgb13h_brightness_set_work);
545
546 /* Init strobe timeout handle */
547 led->waiting = false;
548 init_waitqueue_head(&led->done);
549 INIT_WORK(&led->work_timeout, rgb13h_timeout_work);
550
551 rgb13h_init_flash_timeout(led);
552
553 /* Register LED Flash class device */
554 ret = led_classdev_flash_register(&pdev->dev, fled_cdev);
555 if (ret < 0)
556 goto err_flash_register;
557
558 sd = &led->sd;
559 sd->dev = dev;
560 v4l2_subdev_init(sd, &v4l2_flash_subdev_ops);
561 sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
562 memset(facing, 0, sizeof(facing));
563 if (strcmp(led->module_facing, "back") == 0)
564 facing[0] = 'b';
565 else
566 facing[0] = 'f';
567 snprintf(sd->name, sizeof(sd->name), "m%02d_%s_%s",
568 led->module_index, facing,
569 led_cdev->name);
570 ret = media_entity_pads_init(&sd->entity, 0, NULL);
571 if (ret < 0)
572 goto error_v4l2_flash_init;
573
574 sd->entity.function = MEDIA_ENT_F_FLASH;
575 ret = rgb13h_init_controls(led);
576 if (ret < 0)
577 goto err_init_controls;
578
579 ret = v4l2_async_register_subdev(sd);
580 if (ret < 0)
581 goto err_async_register_sd;
582
583 return 0;
584
585 err_async_register_sd:
586 v4l2_ctrl_handler_free(sd->ctrl_handler);
587 err_init_controls:
588 media_entity_cleanup(&sd->entity);
589 error_v4l2_flash_init:
590 led_classdev_flash_unregister(fled_cdev);
591 err_flash_register:
592 mutex_destroy(&led->lock);
593
594 return ret;
595 }
596
rgb13h_led_remove(struct platform_device * pdev)597 static int rgb13h_led_remove(struct platform_device *pdev)
598 {
599 struct rgb13h_led *led = platform_get_drvdata(pdev);
600
601 v4l2_async_unregister_subdev(&led->sd);
602 v4l2_ctrl_handler_free(led->sd.ctrl_handler);
603 media_entity_cleanup(&led->sd.entity);
604 led_classdev_flash_unregister(&led->fled_cdev);
605
606 mutex_destroy(&led->lock);
607
608 return 0;
609 }
610
611 static const struct of_device_id rgb13h_led_dt_match[] = {
612 { .compatible = "led,rgb13h" },
613 {},
614 };
615 MODULE_DEVICE_TABLE(of, rgb13h_led_dt_match);
616
617 static struct platform_driver rgb13h_led_driver = {
618 .probe = rgb13h_led_probe,
619 .remove = rgb13h_led_remove,
620 .driver = {
621 .name = "rgb13h-flash",
622 .of_match_table = rgb13h_led_dt_match,
623 },
624 };
625
626 module_platform_driver(rgb13h_led_driver);
627
628 MODULE_DESCRIPTION("GPIO LEDS Flash driver");
629 MODULE_LICENSE("GPL v2");
630