Lines Matching +full:current +full:- +full:limit +full:- +full:microamp

1 // SPDX-License-Identifier: GPL-2.0-or-later
10 #include <linux/led-class-flash.h>
14 #include <media/v4l2-flash-led-class.h>
217 diff = abs(tps6131x_timer_configs[i].time_us - timeout_us); in tps6131x_find_closest_timer_config()
233 if (tps6131x->reset_gpio) { in tps6131x_reset_chip()
234 gpiod_set_value_cansleep(tps6131x->reset_gpio, 1); in tps6131x_reset_chip()
236 gpiod_set_value_cansleep(tps6131x->reset_gpio, 0); in tps6131x_reset_chip()
239 ret = regmap_update_bits(tps6131x->regmap, TPS6131X_REG_0, TPS6131X_REG_0_RESET, in tps6131x_reset_chip()
246 ret = regmap_update_bits(tps6131x->regmap, TPS6131X_REG_0, TPS6131X_REG_0_RESET, 0); in tps6131x_reset_chip()
259 val = tps6131x->valley_current_limit ? TPS6131X_REG_4_ILIM : 0; in tps6131x_init_chip()
261 ret = regmap_write(tps6131x->regmap, TPS6131X_REG_4, val); in tps6131x_init_chip()
267 if (tps6131x->chan1_en) in tps6131x_init_chip()
270 if (tps6131x->chan2_en) in tps6131x_init_chip()
273 if (tps6131x->chan3_en) in tps6131x_init_chip()
276 ret = regmap_write(tps6131x->regmap, TPS6131X_REG_5, val); in tps6131x_init_chip()
282 ret = regmap_write(tps6131x->regmap, TPS6131X_REG_6, val); in tps6131x_init_chip()
293 return regmap_update_bits_base(tps6131x->regmap, TPS6131X_REG_1, TPS6131X_REG_1_MODE, val, in tps6131x_set_mode()
302 guard(mutex)(&tps6131x->lock); in tps6131x_torch_refresh_handler()
306 dev_err(tps6131x->dev, "Failed to refresh torch watchdog timer\n"); in tps6131x_torch_refresh_handler()
310 schedule_delayed_work(&tps6131x->torch_refresh_work, in tps6131x_torch_refresh_handler()
322 cancel_delayed_work_sync(&tps6131x->torch_refresh_work); in tps6131x_brightness_set()
325 * The brightness parameter uses the number of current steps as the unit (not the current in tps6131x_brightness_set()
329 steps_remaining = (brightness * tps6131x->step_torch_current_ma) / TPS6131X_TORCH_STEP_I_MA; in tps6131x_brightness_set()
331 num_chans = tps6131x->chan1_en + tps6131x->chan2_en + tps6131x->chan3_en; in tps6131x_brightness_set()
335 * Since channels 1 and 3 share the same register setting, they always use the same current in tps6131x_brightness_set()
341 if (tps6131x->chan1_en) in tps6131x_brightness_set()
342 steps_remaining -= steps_chan13; in tps6131x_brightness_set()
343 if (tps6131x->chan3_en) in tps6131x_brightness_set()
344 steps_remaining -= steps_chan13; in tps6131x_brightness_set()
349 guard(mutex)(&tps6131x->lock); in tps6131x_brightness_set()
353 ret = regmap_update_bits(tps6131x->regmap, TPS6131X_REG_0, in tps6131x_brightness_set()
370 schedule_delayed_work(&tps6131x->torch_refresh_work, in tps6131x_brightness_set()
381 guard(mutex)(&tps6131x->lock); in tps6131x_strobe_set()
389 ret = regmap_update_bits_base(tps6131x->regmap, TPS6131X_REG_3, TPS6131X_REG_3_SFT, in tps6131x_strobe_set()
395 ret = regmap_update_bits_base(tps6131x->regmap, TPS6131X_REG_3, TPS6131X_REG_3_SFT, 0, NULL, in tps6131x_strobe_set()
412 num_chans = tps6131x->chan1_en + tps6131x->chan2_en + tps6131x->chan3_en; in tps6131x_flash_brightness_set()
415 if (tps6131x->chan1_en) in tps6131x_flash_brightness_set()
416 steps_remaining -= steps_chan13; in tps6131x_flash_brightness_set()
417 if (tps6131x->chan3_en) in tps6131x_flash_brightness_set()
418 steps_remaining -= steps_chan13; in tps6131x_flash_brightness_set()
422 guard(mutex)(&tps6131x->lock); in tps6131x_flash_brightness_set()
424 ret = regmap_update_bits(tps6131x->regmap, TPS6131X_REG_2, TPS6131X_REG_2_FC13, in tps6131x_flash_brightness_set()
429 ret = regmap_update_bits(tps6131x->regmap, TPS6131X_REG_1, TPS6131X_REG_1_FC2, in tps6131x_flash_brightness_set()
434 fled_cdev->brightness.val = brightness; in tps6131x_flash_brightness_set()
446 guard(mutex)(&tps6131x->lock); in tps6131x_flash_timeout_set()
450 reg3 = timer_config->val << TPS6131X_REG_3_STIM_SHIFT; in tps6131x_flash_timeout_set()
451 if (timer_config->range) in tps6131x_flash_timeout_set()
454 ret = regmap_update_bits(tps6131x->regmap, TPS6131X_REG_3, in tps6131x_flash_timeout_set()
459 fled_cdev->timeout.val = timer_config->time_us; in tps6131x_flash_timeout_set()
470 ret = regmap_read_bypassed(tps6131x->regmap, TPS6131X_REG_3, &reg3); in tps6131x_strobe_get()
487 ret = regmap_read_bypassed(tps6131x->regmap, TPS6131X_REG_3, &reg3); in tps6131x_flash_fault_get()
491 ret = regmap_read_bypassed(tps6131x->regmap, TPS6131X_REG_4, &reg4); in tps6131x_flash_fault_get()
495 ret = regmap_read_bypassed(tps6131x->regmap, TPS6131X_REG_6, &reg6); in tps6131x_flash_fault_get()
515 ret = regmap_update_bits_base(tps6131x->regmap, TPS6131X_REG_6, in tps6131x_flash_fault_get()
535 struct device *dev = tps6131x->dev; in tps6131x_parse_node()
545 tps6131x->valley_current_limit = device_property_read_bool(dev, "ti,valley-current-limit"); in tps6131x_parse_node()
547 tps6131x->led_node = fwnode_get_next_available_child_node(dev->fwnode, NULL); in tps6131x_parse_node()
548 if (!tps6131x->led_node) { in tps6131x_parse_node()
550 return -EINVAL; in tps6131x_parse_node()
553 num_channels = fwnode_property_count_u32(tps6131x->led_node, "led-sources"); in tps6131x_parse_node()
555 dev_err(dev, "Failed to read led-sources property\n"); in tps6131x_parse_node()
556 return -EINVAL; in tps6131x_parse_node()
560 dev_err(dev, "led-sources count %u exceeds maximum channel count %u\n", in tps6131x_parse_node()
562 return -EINVAL; in tps6131x_parse_node()
565 ret = fwnode_property_read_u32_array(tps6131x->led_node, "led-sources", channels, in tps6131x_parse_node()
568 dev_err(dev, "Failed to read led-sources property\n"); in tps6131x_parse_node()
577 tps6131x->chan1_en = true; in tps6131x_parse_node()
582 tps6131x->chan2_en = true; in tps6131x_parse_node()
587 tps6131x->chan3_en = true; in tps6131x_parse_node()
592 dev_err(dev, "led-source out of range [1-3]\n"); in tps6131x_parse_node()
593 return -EINVAL; in tps6131x_parse_node()
599 * share the same current control register. in tps6131x_parse_node()
602 (tps6131x->chan1_en && tps6131x->chan3_en && !tps6131x->chan2_en) ? 2 : 1; in tps6131x_parse_node()
603 tps6131x->step_flash_current_ma = current_step_multiplier * TPS6131X_FLASH_STEP_I_MA; in tps6131x_parse_node()
604 tps6131x->step_torch_current_ma = current_step_multiplier * TPS6131X_TORCH_STEP_I_MA; in tps6131x_parse_node()
606 ret = fwnode_property_read_u32(tps6131x->led_node, "led-max-microamp", &current_ua); in tps6131x_parse_node()
608 dev_err(dev, "Failed to read led-max-microamp property\n"); in tps6131x_parse_node()
612 tps6131x->max_torch_current_ma = UA_TO_MA(current_ua); in tps6131x_parse_node()
614 if (!tps6131x->max_torch_current_ma || in tps6131x_parse_node()
615 tps6131x->max_torch_current_ma > max_current_torch_ma || in tps6131x_parse_node()
616 (tps6131x->max_torch_current_ma % tps6131x->step_torch_current_ma)) { in tps6131x_parse_node()
617 dev_err(dev, "led-max-microamp out of range or not a multiple of %u\n", in tps6131x_parse_node()
618 tps6131x->step_torch_current_ma); in tps6131x_parse_node()
619 return -EINVAL; in tps6131x_parse_node()
622 ret = fwnode_property_read_u32(tps6131x->led_node, "flash-max-microamp", &current_ua); in tps6131x_parse_node()
624 dev_err(dev, "Failed to read flash-max-microamp property\n"); in tps6131x_parse_node()
628 tps6131x->max_flash_current_ma = UA_TO_MA(current_ua); in tps6131x_parse_node()
630 if (!tps6131x->max_flash_current_ma || in tps6131x_parse_node()
631 tps6131x->max_flash_current_ma > max_current_flash_ma || in tps6131x_parse_node()
632 (tps6131x->max_flash_current_ma % tps6131x->step_flash_current_ma)) { in tps6131x_parse_node()
633 dev_err(dev, "flash-max-microamp out of range or not a multiple of %u\n", in tps6131x_parse_node()
634 tps6131x->step_flash_current_ma); in tps6131x_parse_node()
635 return -EINVAL; in tps6131x_parse_node()
638 ret = fwnode_property_read_u32(tps6131x->led_node, "flash-max-timeout-us", &timeout_us); in tps6131x_parse_node()
640 dev_err(dev, "Failed to read flash-max-timeout-us property\n"); in tps6131x_parse_node()
645 tps6131x->max_timeout_us = timer_config->time_us; in tps6131x_parse_node()
647 if (tps6131x->max_timeout_us != timeout_us) in tps6131x_parse_node()
648 dev_warn(dev, "flash-max-timeout-us %u not supported (using %u)\n", timeout_us, in tps6131x_parse_node()
649 tps6131x->max_timeout_us); in tps6131x_parse_node()
662 tps6131x->fled_cdev.ops = &flash_ops; in tps6131x_led_class_setup()
664 setting = &tps6131x->fled_cdev.timeout; in tps6131x_led_class_setup()
666 setting->min = timer_config->time_us; in tps6131x_led_class_setup()
667 setting->max = tps6131x->max_timeout_us; in tps6131x_led_class_setup()
668 setting->step = 1; /* Only some specific time periods are supported. No fixed step size. */ in tps6131x_led_class_setup()
669 setting->val = setting->min; in tps6131x_led_class_setup()
671 setting = &tps6131x->fled_cdev.brightness; in tps6131x_led_class_setup()
672 setting->min = tps6131x->step_flash_current_ma; in tps6131x_led_class_setup()
673 setting->max = tps6131x->max_flash_current_ma; in tps6131x_led_class_setup()
674 setting->step = tps6131x->step_flash_current_ma; in tps6131x_led_class_setup()
675 setting->val = setting->min; in tps6131x_led_class_setup()
677 led_cdev = &tps6131x->fled_cdev.led_cdev; in tps6131x_led_class_setup()
678 led_cdev->brightness_set_blocking = tps6131x_brightness_set; in tps6131x_led_class_setup()
679 led_cdev->max_brightness = tps6131x->max_torch_current_ma; in tps6131x_led_class_setup()
680 led_cdev->flags |= LED_DEV_CAP_FLASH; in tps6131x_led_class_setup()
682 init_data.fwnode = tps6131x->led_node; in tps6131x_led_class_setup()
687 ret = devm_led_classdev_flash_register_ext(tps6131x->dev, &tps6131x->fled_cdev, in tps6131x_led_class_setup()
697 struct led_classdev_flash *fled_cdev = v4l2_flash->fled_cdev; in tps6131x_flash_external_strobe_set()
700 guard(mutex)(&tps6131x->lock); in tps6131x_flash_external_strobe_set()
715 intensity->min = tps6131x->step_torch_current_ma; in tps6131x_v4l2_setup()
716 intensity->max = tps6131x->max_torch_current_ma; in tps6131x_v4l2_setup()
717 intensity->step = tps6131x->step_torch_current_ma; in tps6131x_v4l2_setup()
718 intensity->val = intensity->min; in tps6131x_v4l2_setup()
720 strscpy(v4l2_cfg.dev_name, tps6131x->fled_cdev.led_cdev.dev->kobj.name, in tps6131x_v4l2_setup()
728 tps6131x->v4l2_flash = v4l2_flash_init(tps6131x->dev, tps6131x->led_node, in tps6131x_v4l2_setup()
729 &tps6131x->fled_cdev, &tps6131x_v4l2_flash_ops, in tps6131x_v4l2_setup()
731 if (IS_ERR(tps6131x->v4l2_flash)) { in tps6131x_v4l2_setup()
732 dev_err(tps6131x->dev, "Failed to initialize v4l2 flash LED\n"); in tps6131x_v4l2_setup()
733 return PTR_ERR(tps6131x->v4l2_flash); in tps6131x_v4l2_setup()
744 tps6131x = devm_kzalloc(&client->dev, sizeof(*tps6131x), GFP_KERNEL); in tps6131x_probe()
746 return -ENOMEM; in tps6131x_probe()
748 tps6131x->dev = &client->dev; in tps6131x_probe()
750 mutex_init(&tps6131x->lock); in tps6131x_probe()
751 INIT_DELAYED_WORK(&tps6131x->torch_refresh_work, tps6131x_torch_refresh_handler); in tps6131x_probe()
757 tps6131x->regmap = devm_regmap_init_i2c(client, &tps6131x_regmap); in tps6131x_probe()
758 if (IS_ERR(tps6131x->regmap)) { in tps6131x_probe()
759 ret = PTR_ERR(tps6131x->regmap); in tps6131x_probe()
760 return dev_err_probe(&client->dev, ret, "Failed to allocate register map\n"); in tps6131x_probe()
763 tps6131x->reset_gpio = devm_gpiod_get_optional(&client->dev, "reset", GPIOD_OUT_HIGH); in tps6131x_probe()
764 if (IS_ERR(tps6131x->reset_gpio)) { in tps6131x_probe()
765 ret = PTR_ERR(tps6131x->reset_gpio); in tps6131x_probe()
766 return dev_err_probe(&client->dev, ret, "Failed to get reset GPIO\n"); in tps6131x_probe()
771 return dev_err_probe(&client->dev, ret, "Failed to reset LED controller\n"); in tps6131x_probe()
775 return dev_err_probe(&client->dev, ret, "Failed to initialize LED controller\n"); in tps6131x_probe()
779 return dev_err_probe(&client->dev, ret, "Failed to setup LED class\n"); in tps6131x_probe()
783 return dev_err_probe(&client->dev, ret, "Failed to setup v4l2 flash\n"); in tps6131x_probe()
792 v4l2_flash_release(tps6131x->v4l2_flash); in tps6131x_remove()
794 cancel_delayed_work_sync(&tps6131x->torch_refresh_work); in tps6131x_remove()