Lines Matching +full:flash +full:- +full:max +full:- +full:microamp

1 // SPDX-License-Identifier: GPL-2.0
6 #include <media/v4l2-ctrls.h>
7 #include <media/v4l2-subdev.h>
10 #include <linux/led-class-flash.h>
17 #include <linux/rk-camera-module.h>
18 #include <linux/rk-led-flash.h>
40 /* maximum LED current in flash mode */
42 /* maximum flash timeout */
49 /* assures led-triggers compatibility */
79 mutex_lock(&led->lock); in rgb13h_set_output()
80 if (!IS_ERR(led->gpio_en)) in rgb13h_set_output()
81 gpiod_direction_output(led->gpio_en, on); in rgb13h_set_output()
82 if (!IS_ERR(led->pwm)) { in rgb13h_set_output()
83 if (led->led_mode == V4L2_FLASH_LED_MODE_TORCH) in rgb13h_set_output()
84 led->pwm_state.duty_cycle = in rgb13h_set_output()
85 div_u64(led->intensity_torch * led->pwm_state.period, led->max_mm_current); in rgb13h_set_output()
87 led->pwm_state.duty_cycle = in rgb13h_set_output()
88 div_u64(led->intensity * led->pwm_state.period, led->max_flash_current); in rgb13h_set_output()
90 led->pwm_state.enabled = true; in rgb13h_set_output()
91 pwm_apply_state(led->pwm, &led->pwm_state); in rgb13h_set_output()
92 dev_dbg(&led->pdev->dev, "led pwm duty=%llu, period=%llu, polarity=%d\n", in rgb13h_set_output()
93 led->pwm_state.duty_cycle, led->pwm_state.period, led->pwm_state.polarity); in rgb13h_set_output()
95 led->pwm_state.enabled = false; in rgb13h_set_output()
96 pwm_apply_state(led->pwm, &led->pwm_state); in rgb13h_set_output()
100 led->strobe_state = false; in rgb13h_set_output()
101 if (led->waiting) { in rgb13h_set_output()
102 led->waiting = false; in rgb13h_set_output()
103 wake_up(&led->done); in rgb13h_set_output()
106 led->timestamp = ns_to_kernel_old_timeval(ktime_get_ns()); in rgb13h_set_output()
108 mutex_unlock(&led->lock); in rgb13h_set_output()
117 wait_event_timeout(led->done, !led->waiting, in rgb13h_timeout_work()
118 usecs_to_jiffies(led->timeout)); in rgb13h_timeout_work()
119 if (led->waiting) { in rgb13h_timeout_work()
120 led->waiting = false; in rgb13h_timeout_work()
121 led->strobe_state = false; in rgb13h_timeout_work()
131 rgb13h_set_output(led, !!led->torch_brightness); in rgb13h_brightness_set_work()
140 led->torch_brightness = brightness; in rgb13h_led_brightness_set()
141 schedule_work(&led->work_brightness_set); in rgb13h_led_brightness_set()
160 mutex_lock(&led->lock); in rgb13h_led_flash_strobe_set()
161 led->strobe_state = state; in rgb13h_led_flash_strobe_set()
163 led->waiting = true; in rgb13h_led_flash_strobe_set()
164 schedule_work(&led->work_timeout); in rgb13h_led_flash_strobe_set()
166 mutex_unlock(&led->lock); in rgb13h_led_flash_strobe_set()
176 mutex_lock(&led->lock); in rgb13h_led_flash_strobe_get()
177 *state = led->strobe_state; in rgb13h_led_flash_strobe_get()
178 mutex_unlock(&led->lock); in rgb13h_led_flash_strobe_get()
187 mutex_lock(&led->lock); in rgb13h_led_flash_timeout_set()
188 led->timeout = timeout; in rgb13h_led_flash_timeout_set()
189 mutex_unlock(&led->lock); in rgb13h_led_flash_timeout_set()
196 struct led_classdev *led_cdev = &led->fled_cdev.led_cdev; in rgb13h_led_parse_dt()
197 struct device *dev = &led->pdev->dev; in rgb13h_led_parse_dt()
198 struct device_node *child_node = dev->of_node; in rgb13h_led_parse_dt()
203 &led->module_index); in rgb13h_led_parse_dt()
206 &led->module_facing); in rgb13h_led_parse_dt()
209 return -EINVAL; in rgb13h_led_parse_dt()
212 led->gpio_en = devm_gpiod_get(dev, "enable", GPIOD_ASIS); in rgb13h_led_parse_dt()
213 if (IS_ERR(led->gpio_en)) { in rgb13h_led_parse_dt()
214 ret = PTR_ERR(led->gpio_en); in rgb13h_led_parse_dt()
215 dev_info(dev, "Unable to claim enable-gpio\n"); in rgb13h_led_parse_dt()
217 led->pwm = devm_pwm_get(dev, NULL); in rgb13h_led_parse_dt()
218 if (IS_ERR(led->pwm)) { in rgb13h_led_parse_dt()
219 ret = PTR_ERR(led->pwm); in rgb13h_led_parse_dt()
222 led->pwm_state.period = led->pwm->args.period; in rgb13h_led_parse_dt()
223 led->pwm_state.polarity = led->pwm->args.polarity; in rgb13h_led_parse_dt()
225 led->pwm_state.period, led->pwm_state.polarity); in rgb13h_led_parse_dt()
227 if (IS_ERR(led->gpio_en) && IS_ERR(led->pwm)) { in rgb13h_led_parse_dt()
228 dev_err(dev, "Neither enable-gpio nor pwm can be get,return error\n"); in rgb13h_led_parse_dt()
232 led_cdev->name = of_get_property(child_node, "label", NULL) ? : in rgb13h_led_parse_dt()
233 child_node->name; in rgb13h_led_parse_dt()
235 ret = of_property_read_u32(child_node, "led-max-microamp", in rgb13h_led_parse_dt()
236 &led->max_mm_current); in rgb13h_led_parse_dt()
239 "led-max-microamp DT property missing\n"); in rgb13h_led_parse_dt()
240 if (led->max_mm_current <= 0) { in rgb13h_led_parse_dt()
241 led->max_mm_current = 20000; in rgb13h_led_parse_dt()
243 "get led-max-microamp error value, used default value 20000\n"); in rgb13h_led_parse_dt()
246 ret = of_property_read_u32(child_node, "flash-max-microamp", in rgb13h_led_parse_dt()
247 &led->max_flash_current); in rgb13h_led_parse_dt()
250 "flash-max-microamp DT property missing\n"); in rgb13h_led_parse_dt()
253 if (led->max_flash_current <= 0) { in rgb13h_led_parse_dt()
254 led->max_flash_current = 20000; in rgb13h_led_parse_dt()
256 "get flash-max-microamp error value, used default value 20000\n"); in rgb13h_led_parse_dt()
259 ret = of_property_read_u32(child_node, "flash-max-timeout-us", in rgb13h_led_parse_dt()
260 &led->max_flash_tm); in rgb13h_led_parse_dt()
263 "flash-max-timeout-us DT property missing\n"); in rgb13h_led_parse_dt()
266 if (led->max_flash_tm <= 0) { in rgb13h_led_parse_dt()
267 led->max_flash_tm = 1000000; in rgb13h_led_parse_dt()
269 "get flash-max-timeout-us error value, used default value 1s\n"); in rgb13h_led_parse_dt()
290 struct led_classdev_flash *fled_cdev = &led->fled_cdev; in rgb13h_init_flash_timeout()
293 /* Init flash timeout setting */ in rgb13h_init_flash_timeout()
294 setting = &fled_cdev->timeout; in rgb13h_init_flash_timeout()
295 setting->min = FLASH_TIMEOUT_MIN; in rgb13h_init_flash_timeout()
296 setting->max = led->max_flash_tm; in rgb13h_init_flash_timeout()
297 setting->step = FLASH_TIMEOUT_STEP; in rgb13h_init_flash_timeout()
298 setting->val = setting->max; in rgb13h_init_flash_timeout()
304 container_of(ctrl->handler, struct rgb13h_led, ctrls); in rgb13h_get_ctrl()
306 switch (ctrl->id) { in rgb13h_get_ctrl()
308 ctrl->val = 0; in rgb13h_get_ctrl()
311 if (led->led_mode != V4L2_FLASH_LED_MODE_FLASH) { in rgb13h_get_ctrl()
312 ctrl->val = 0; in rgb13h_get_ctrl()
315 ctrl->val = led->strobe_state; in rgb13h_get_ctrl()
318 ctrl->val = led->intensity; in rgb13h_get_ctrl()
321 ctrl->val = led->intensity_torch; in rgb13h_get_ctrl()
324 ctrl->val = led->led_mode; in rgb13h_get_ctrl()
327 dev_err(&led->pdev->dev, in rgb13h_get_ctrl()
328 "ctrl 0x%x not supported\n", ctrl->id); in rgb13h_get_ctrl()
329 return -EINVAL; in rgb13h_get_ctrl()
338 container_of(ctrl->handler, struct rgb13h_led, ctrls); in rgb13h_set_ctrl()
340 switch (ctrl->id) { in rgb13h_set_ctrl()
342 led->led_mode = ctrl->val; in rgb13h_set_ctrl()
344 if (led->led_mode == V4L2_FLASH_LED_MODE_TORCH) in rgb13h_set_ctrl()
349 if (ctrl->val == V4L2_FLASH_STROBE_SOURCE_EXTERNAL) in rgb13h_set_ctrl()
350 return -EBUSY; in rgb13h_set_ctrl()
353 if (led->led_mode != V4L2_FLASH_LED_MODE_FLASH) in rgb13h_set_ctrl()
354 return -EBUSY; in rgb13h_set_ctrl()
355 return rgb13h_led_flash_strobe_set(&led->fled_cdev, true); in rgb13h_set_ctrl()
357 if (led->led_mode != V4L2_FLASH_LED_MODE_FLASH) in rgb13h_set_ctrl()
358 return -EBUSY; in rgb13h_set_ctrl()
359 return rgb13h_led_flash_strobe_set(&led->fled_cdev, false); in rgb13h_set_ctrl()
361 return rgb13h_led_flash_timeout_set(&led->fled_cdev, ctrl->val); in rgb13h_set_ctrl()
363 led->intensity = ctrl->val; in rgb13h_set_ctrl()
366 led->intensity_torch = ctrl->val; in rgb13h_set_ctrl()
367 if (led->led_mode != V4L2_FLASH_LED_MODE_TORCH) in rgb13h_set_ctrl()
371 dev_err(&led->pdev->dev, in rgb13h_set_ctrl()
372 "ctrl 0x%x not supported\n", ctrl->id); in rgb13h_set_ctrl()
373 return -EINVAL; in rgb13h_set_ctrl()
387 v4l2_ctrl_handler_init(&led->ctrls, 10); in rgb13h_init_controls()
389 v4l2_ctrl_new_std_menu(&led->ctrls, &rgb13h_ctrl_ops, in rgb13h_init_controls()
392 led->led_mode = V4L2_FLASH_LED_MODE_NONE; in rgb13h_init_controls()
394 v4l2_ctrl_new_std_menu(&led->ctrls, &rgb13h_ctrl_ops, in rgb13h_init_controls()
398 v4l2_ctrl_new_std(&led->ctrls, &rgb13h_ctrl_ops, in rgb13h_init_controls()
401 v4l2_ctrl_new_std(&led->ctrls, &rgb13h_ctrl_ops, in rgb13h_init_controls()
404 ctrl = v4l2_ctrl_new_std(&led->ctrls, &rgb13h_ctrl_ops, in rgb13h_init_controls()
407 led->strobe_state = false; in rgb13h_init_controls()
409 ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE; in rgb13h_init_controls()
411 v4l2_ctrl_new_std(&led->ctrls, &rgb13h_ctrl_ops, in rgb13h_init_controls()
413 led->max_flash_tm, FLASH_TIMEOUT_STEP, in rgb13h_init_controls()
414 led->max_flash_tm); in rgb13h_init_controls()
415 led->timeout = led->max_flash_tm; in rgb13h_init_controls()
417 ctrl = v4l2_ctrl_new_std(&led->ctrls, &rgb13h_ctrl_ops, in rgb13h_init_controls()
419 led->max_flash_current, in rgb13h_init_controls()
421 led->max_flash_current); in rgb13h_init_controls()
422 if (ctrl && IS_ERR(led->pwm)) in rgb13h_init_controls()
423 ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY; in rgb13h_init_controls()
424 led->intensity = led->max_flash_current; in rgb13h_init_controls()
426 ctrl = v4l2_ctrl_new_std(&led->ctrls, &rgb13h_ctrl_ops, in rgb13h_init_controls()
428 led->max_mm_current, in rgb13h_init_controls()
430 led->max_mm_current); in rgb13h_init_controls()
431 if (ctrl && IS_ERR(led->pwm)) in rgb13h_init_controls()
432 ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY; in rgb13h_init_controls()
433 led->intensity_torch = led->max_mm_current; in rgb13h_init_controls()
436 ctrl = v4l2_ctrl_new_std(&led->ctrls, &rgb13h_ctrl_ops, in rgb13h_init_controls()
443 ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE; in rgb13h_init_controls()
444 led->sd.ctrl_handler = &led->ctrls; in rgb13h_init_controls()
445 return led->ctrls.error; in rgb13h_init_controls()
456 t->tv_sec = led->timestamp.tv_sec; in rgb13h_ioctl()
457 t->tv_usec = led->timestamp.tv_usec; in rgb13h_ioctl()
459 return -EINVAL; in rgb13h_ioctl()
479 put_user(compat_t.tv_sec, &p32->tv_sec); in rgb13h_compat_ioctl32()
480 put_user(compat_t.tv_usec, &p32->tv_usec); in rgb13h_compat_ioctl32()
482 return -EINVAL; in rgb13h_compat_ioctl32()
508 struct device *dev = &pdev->dev; in rgb13h_led_probe()
524 return -ENOMEM; in rgb13h_led_probe()
526 led->pdev = pdev; in rgb13h_led_probe()
529 fled_cdev = &led->fled_cdev; in rgb13h_led_probe()
530 fled_cdev->ops = &flash_ops; in rgb13h_led_probe()
531 led_cdev = &fled_cdev->led_cdev; in rgb13h_led_probe()
537 mutex_init(&led->lock); in rgb13h_led_probe()
539 /* Initialize LED Flash class device */ in rgb13h_led_probe()
540 led_cdev->brightness_set = rgb13h_led_brightness_set; in rgb13h_led_probe()
541 led_cdev->brightness_set_blocking = rgb13h_led_brightness_set_sync; in rgb13h_led_probe()
542 led_cdev->max_brightness = LED_FULL; in rgb13h_led_probe()
543 led_cdev->flags |= LED_DEV_CAP_FLASH; in rgb13h_led_probe()
544 INIT_WORK(&led->work_brightness_set, rgb13h_brightness_set_work); in rgb13h_led_probe()
547 led->waiting = false; in rgb13h_led_probe()
548 init_waitqueue_head(&led->done); in rgb13h_led_probe()
549 INIT_WORK(&led->work_timeout, rgb13h_timeout_work); in rgb13h_led_probe()
553 /* Register LED Flash class device */ in rgb13h_led_probe()
554 ret = led_classdev_flash_register(&pdev->dev, fled_cdev); in rgb13h_led_probe()
558 sd = &led->sd; in rgb13h_led_probe()
559 sd->dev = dev; in rgb13h_led_probe()
561 sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; in rgb13h_led_probe()
563 if (strcmp(led->module_facing, "back") == 0) in rgb13h_led_probe()
567 snprintf(sd->name, sizeof(sd->name), "m%02d_%s_%s", in rgb13h_led_probe()
568 led->module_index, facing, in rgb13h_led_probe()
569 led_cdev->name); in rgb13h_led_probe()
570 ret = media_entity_pads_init(&sd->entity, 0, NULL); in rgb13h_led_probe()
574 sd->entity.function = MEDIA_ENT_F_FLASH; in rgb13h_led_probe()
586 v4l2_ctrl_handler_free(sd->ctrl_handler); in rgb13h_led_probe()
588 media_entity_cleanup(&sd->entity); in rgb13h_led_probe()
592 mutex_destroy(&led->lock); in rgb13h_led_probe()
601 v4l2_async_unregister_subdev(&led->sd); in rgb13h_led_remove()
602 v4l2_ctrl_handler_free(led->sd.ctrl_handler); in rgb13h_led_remove()
603 media_entity_cleanup(&led->sd.entity); in rgb13h_led_remove()
604 led_classdev_flash_unregister(&led->fled_cdev); in rgb13h_led_remove()
606 mutex_destroy(&led->lock); in rgb13h_led_remove()
621 .name = "rgb13h-flash",
628 MODULE_DESCRIPTION("GPIO LEDS Flash driver");