Lines Matching +full:max +full:- +full:brightness

1 // SPDX-License-Identifier: GPL-2.0-only
8 #include <linux/led-class-flash.h>
9 #include <linux/led-class-multicolor.h>
15 #include <media/v4l2-flash-led-class.h>
29 #define MT6360_ISNK_ENMASK(_led_no) BIT(7 - (_led_no))
39 #define MT6360_REG_FLEDBASE(_id) (0x372 + 4 * (_id - MT6360_LED_FLASH1))
49 #define MT6360_FLCSEN_MASK(_id) BIT(MT6360_LED_FLASH2 - _id)
102 struct mt6360_priv *priv = led->priv; in mt6360_mc_brightness_set()
106 mutex_lock(&priv->lock); in mt6360_mc_brightness_set()
110 for (i = 0; i < mccdev->num_colors; i++) { in mt6360_mc_brightness_set()
111 struct mc_subled *subled = mccdev->subled_info + i; in mt6360_mc_brightness_set()
113 real_bright = min(lcdev->max_brightness, subled->brightness); in mt6360_mc_brightness_set()
114 ret = regmap_update_bits(priv->regmap, MT6360_REG_ISNK(i), in mt6360_mc_brightness_set()
119 enable_mask |= MT6360_ISNK_ENMASK(subled->channel); in mt6360_mc_brightness_set()
121 enable |= MT6360_ISNK_ENMASK(subled->channel); in mt6360_mc_brightness_set()
124 ret = regmap_update_bits(priv->regmap, MT6360_REG_RGBEN, enable_mask, in mt6360_mc_brightness_set()
128 mutex_unlock(&priv->lock); in mt6360_mc_brightness_set()
136 struct mt6360_priv *priv = led->priv; in mt6360_isnk_brightness_set()
137 u32 enable_mask = MT6360_ISNK_ENMASK(led->led_no); in mt6360_isnk_brightness_set()
138 u32 val = level ? MT6360_ISNK_ENMASK(led->led_no) : 0; in mt6360_isnk_brightness_set()
141 mutex_lock(&priv->lock); in mt6360_isnk_brightness_set()
143 ret = regmap_update_bits(priv->regmap, MT6360_REG_ISNK(led->led_no), in mt6360_isnk_brightness_set()
148 ret = regmap_update_bits(priv->regmap, MT6360_REG_RGBEN, enable_mask, in mt6360_isnk_brightness_set()
152 mutex_unlock(&priv->lock); in mt6360_isnk_brightness_set()
161 struct mt6360_priv *priv = led->priv; in mt6360_torch_brightness_set()
162 u32 enable_mask = MT6360_TORCHEN_MASK | MT6360_FLCSEN_MASK(led->led_no); in mt6360_torch_brightness_set()
163 u32 val = level ? MT6360_FLCSEN_MASK(led->led_no) : 0; in mt6360_torch_brightness_set()
164 u32 prev = priv->fled_torch_used, curr; in mt6360_torch_brightness_set()
167 mutex_lock(&priv->lock); in mt6360_torch_brightness_set()
173 if (priv->fled_strobe_used) { in mt6360_torch_brightness_set()
174 dev_warn(lcdev->dev, "Please disable strobe first [%d]\n", in mt6360_torch_brightness_set()
175 priv->fled_strobe_used); in mt6360_torch_brightness_set()
176 ret = -EBUSY; in mt6360_torch_brightness_set()
181 curr = prev | BIT(led->led_no); in mt6360_torch_brightness_set()
183 curr = prev & ~BIT(led->led_no); in mt6360_torch_brightness_set()
189 ret = regmap_update_bits(priv->regmap, in mt6360_torch_brightness_set()
190 MT6360_REG_FLEDITOR(led->led_no), in mt6360_torch_brightness_set()
191 MT6360_ITORCH_MASK, level - 1); in mt6360_torch_brightness_set()
196 ret = regmap_update_bits(priv->regmap, MT6360_REG_FLEDEN, enable_mask, in mt6360_torch_brightness_set()
201 priv->fled_torch_used = curr; in mt6360_torch_brightness_set()
204 mutex_unlock(&priv->lock); in mt6360_torch_brightness_set()
209 u32 brightness) in mt6360_flash_brightness_set() argument
212 * Due to the current spike when turning on flash, let brightness to be in mt6360_flash_brightness_set()
221 u32 brightness) in _mt6360_flash_brightness_set() argument
225 struct mt6360_priv *priv = led->priv; in _mt6360_flash_brightness_set()
226 struct led_flash_setting *s = &fl_cdev->brightness; in _mt6360_flash_brightness_set()
227 u32 val = (brightness - s->min) / s->step; in _mt6360_flash_brightness_set()
229 return regmap_update_bits(priv->regmap, in _mt6360_flash_brightness_set()
230 MT6360_REG_FLEDISTRB(led->led_no), in _mt6360_flash_brightness_set()
238 struct mt6360_priv *priv = led->priv; in mt6360_strobe_set()
239 struct led_classdev *lcdev = &fl_cdev->led_cdev; in mt6360_strobe_set()
240 struct led_flash_setting *s = &fl_cdev->brightness; in mt6360_strobe_set()
241 u32 enable_mask = MT6360_STROBEN_MASK | MT6360_FLCSEN_MASK(led->led_no); in mt6360_strobe_set()
242 u32 val = state ? MT6360_FLCSEN_MASK(led->led_no) : 0; in mt6360_strobe_set()
243 u32 prev = priv->fled_strobe_used, curr; in mt6360_strobe_set()
246 mutex_lock(&priv->lock); in mt6360_strobe_set()
252 if (priv->fled_torch_used) { in mt6360_strobe_set()
253 dev_warn(lcdev->dev, "Please disable torch first [0x%x]\n", in mt6360_strobe_set()
254 priv->fled_torch_used); in mt6360_strobe_set()
255 ret = -EBUSY; in mt6360_strobe_set()
260 curr = prev | BIT(led->led_no); in mt6360_strobe_set()
262 curr = prev & ~BIT(led->led_no); in mt6360_strobe_set()
267 ret = regmap_update_bits(priv->regmap, MT6360_REG_FLEDEN, enable_mask, in mt6360_strobe_set()
270 dev_err(lcdev->dev, "[%d] control current source %d fail\n", in mt6360_strobe_set()
271 led->led_no, state); in mt6360_strobe_set()
280 ret = _mt6360_flash_brightness_set(fl_cdev, state ? s->val : s->min); in mt6360_strobe_set()
293 priv->fled_strobe_used = curr; in mt6360_strobe_set()
296 mutex_unlock(&priv->lock); in mt6360_strobe_set()
304 struct mt6360_priv *priv = led->priv; in mt6360_strobe_get()
306 mutex_lock(&priv->lock); in mt6360_strobe_get()
307 *state = !!(priv->fled_strobe_used & BIT(led->led_no)); in mt6360_strobe_get()
308 mutex_unlock(&priv->lock); in mt6360_strobe_get()
317 struct mt6360_priv *priv = led->priv; in mt6360_timeout_set()
318 struct led_flash_setting *s = &fl_cdev->timeout; in mt6360_timeout_set()
319 u32 val = (timeout - s->min) / s->step; in mt6360_timeout_set()
322 mutex_lock(&priv->lock); in mt6360_timeout_set()
323 ret = regmap_update_bits(priv->regmap, MT6360_REG_STRBTO, in mt6360_timeout_set()
325 mutex_unlock(&priv->lock); in mt6360_timeout_set()
334 struct mt6360_priv *priv = led->priv; in mt6360_fault_get()
340 mutex_lock(&priv->lock); in mt6360_fault_get()
341 ret = regmap_read(priv->regmap, MT6360_REG_CHGSTAT2, &chg_stat); in mt6360_fault_get()
345 ret = regmap_raw_read(priv->regmap, MT6360_REG_FLEDSTAT1, &fled_stat, in mt6360_fault_get()
350 if (led->led_no == MT6360_LED_FLASH1) { in mt6360_fault_get()
372 mutex_unlock(&priv->lock); in mt6360_fault_get()
386 struct mt6360_priv *priv = led->priv; in mt6360_isnk_init_default_state()
391 ret = regmap_read(priv->regmap, MT6360_REG_ISNK(led->led_no), &regval); in mt6360_isnk_init_default_state()
396 ret = regmap_read(priv->regmap, MT6360_REG_RGBEN, &regval); in mt6360_isnk_init_default_state()
400 if (!(regval & MT6360_ISNK_ENMASK(led->led_no))) in mt6360_isnk_init_default_state()
403 switch (led->default_state) { in mt6360_isnk_init_default_state()
405 led->isnk.brightness = led->isnk.max_brightness; in mt6360_isnk_init_default_state()
408 led->isnk.brightness = min(level, led->isnk.max_brightness); in mt6360_isnk_init_default_state()
411 led->isnk.brightness = LED_OFF; in mt6360_isnk_init_default_state()
414 return mt6360_isnk_brightness_set(&led->isnk, led->isnk.brightness); in mt6360_isnk_init_default_state()
419 struct led_classdev_flash *flash = &led->flash; in mt6360_flash_init_default_state()
420 struct mt6360_priv *priv = led->priv; in mt6360_flash_init_default_state()
421 u32 enable_mask = MT6360_TORCHEN_MASK | MT6360_FLCSEN_MASK(led->led_no); in mt6360_flash_init_default_state()
426 ret = regmap_read(priv->regmap, MT6360_REG_FLEDITOR(led->led_no), in mt6360_flash_init_default_state()
432 ret = regmap_read(priv->regmap, MT6360_REG_FLEDEN, &regval); in mt6360_flash_init_default_state()
441 switch (led->default_state) { in mt6360_flash_init_default_state()
443 flash->led_cdev.brightness = flash->led_cdev.max_brightness; in mt6360_flash_init_default_state()
446 flash->led_cdev.brightness = in mt6360_flash_init_default_state()
447 min(level, flash->led_cdev.max_brightness); in mt6360_flash_init_default_state()
450 flash->led_cdev.brightness = LED_OFF; in mt6360_flash_init_default_state()
453 return mt6360_torch_brightness_set(&flash->led_cdev, in mt6360_flash_init_default_state()
454 flash->led_cdev.brightness); in mt6360_flash_init_default_state()
461 struct led_classdev_flash *flash = v4l2_flash->fled_cdev; in mt6360_flash_external_strobe_set()
463 struct mt6360_priv *priv = led->priv; in mt6360_flash_external_strobe_set()
464 u32 mask = MT6360_FLCSEN_MASK(led->led_no); in mt6360_flash_external_strobe_set()
468 mutex_lock(&priv->lock); in mt6360_flash_external_strobe_set()
470 ret = regmap_update_bits(priv->regmap, MT6360_REG_FLEDEN, mask, val); in mt6360_flash_external_strobe_set()
475 priv->fled_strobe_used |= BIT(led->led_no); in mt6360_flash_external_strobe_set()
477 priv->fled_strobe_used &= ~BIT(led->led_no); in mt6360_flash_external_strobe_set()
480 mutex_unlock(&priv->lock); in mt6360_flash_external_strobe_set()
492 struct led_flash_setting *s = &config->intensity; in mt6360_init_v4l2_flash_config()
494 lcdev = &led->flash.led_cdev; in mt6360_init_v4l2_flash_config()
496 s->min = MT6360_ITORCH_MINUA; in mt6360_init_v4l2_flash_config()
497 s->step = MT6360_ITORCH_STEPUA; in mt6360_init_v4l2_flash_config()
498 s->val = s->max = s->min + (lcdev->max_brightness - 1) * s->step; in mt6360_init_v4l2_flash_config()
500 config->has_external_strobe = 1; in mt6360_init_v4l2_flash_config()
501 strscpy(config->dev_name, lcdev->dev->kobj.name, in mt6360_init_v4l2_flash_config()
502 sizeof(config->dev_name)); in mt6360_init_v4l2_flash_config()
504 config->flash_faults = LED_FAULT_SHORT_CIRCUIT | LED_FAULT_TIMEOUT | in mt6360_init_v4l2_flash_config()
519 struct mt6360_priv *priv = led->priv; in mt6360_led_register()
523 if ((led->led_no == MT6360_LED_ISNK1 || in mt6360_led_register()
524 led->led_no == MT6360_VIRTUAL_MULTICOLOR) && in mt6360_led_register()
525 (priv->leds_active & BIT(MT6360_LED_ISNK1))) { in mt6360_led_register()
530 ret = regmap_update_bits(priv->regmap, MT6360_REG_RGBEN, in mt6360_led_register()
539 switch (led->led_no) { in mt6360_led_register()
541 ret = mt6360_mc_brightness_set(&led->mc.led_cdev, LED_OFF); in mt6360_led_register()
544 "Failed to init multicolor brightness\n"); in mt6360_led_register()
549 &led->mc, init_data); in mt6360_led_register()
559 led->led_no); in mt6360_led_register()
563 ret = devm_led_classdev_register_ext(parent, &led->isnk, in mt6360_led_register()
567 led->led_no); in mt6360_led_register()
575 led->led_no); in mt6360_led_register()
579 ret = devm_led_classdev_flash_register_ext(parent, &led->flash, in mt6360_led_register()
583 led->led_no); in mt6360_led_register()
588 led->v4l2_flash = v4l2_flash_init(parent, init_data->fwnode, in mt6360_led_register()
589 &led->flash, in mt6360_led_register()
592 if (IS_ERR(led->v4l2_flash)) { in mt6360_led_register()
594 led->led_no); in mt6360_led_register()
595 return PTR_ERR(led->v4l2_flash); in mt6360_led_register()
602 static u32 clamp_align(u32 val, u32 min, u32 max, u32 step) in clamp_align() argument
606 retval = clamp_val(val, min, max); in clamp_align()
608 retval = rounddown(retval - min, step) + min; in clamp_align()
617 struct mt6360_priv *priv = led->priv; in mt6360_init_isnk_properties()
623 if (led->led_no == MT6360_VIRTUAL_MULTICOLOR) { in mt6360_init_isnk_properties()
626 sub_led = devm_kzalloc(priv->dev, in mt6360_init_isnk_properties()
629 return -ENOMEM; in mt6360_init_isnk_properties()
631 fwnode_for_each_child_node(init_data->fwnode, child) { in mt6360_init_isnk_properties()
636 priv->leds_active & BIT(reg)) in mt6360_init_isnk_properties()
637 return -EINVAL; in mt6360_init_isnk_properties()
641 dev_err(priv->dev, in mt6360_init_isnk_properties()
643 led->led_no); in mt6360_init_isnk_properties()
647 priv->leds_active |= BIT(reg); in mt6360_init_isnk_properties()
654 dev_err(priv->dev, in mt6360_init_isnk_properties()
656 return -EINVAL; in mt6360_init_isnk_properties()
659 led->mc.num_colors = num_color; in mt6360_init_isnk_properties()
660 led->mc.subled_info = sub_led; in mt6360_init_isnk_properties()
662 lcdev = &led->mc.led_cdev; in mt6360_init_isnk_properties()
663 lcdev->brightness_set_blocking = mt6360_mc_brightness_set; in mt6360_init_isnk_properties()
665 if (led->led_no == MT6360_LED_ISNKML) { in mt6360_init_isnk_properties()
670 lcdev = &led->isnk; in mt6360_init_isnk_properties()
671 lcdev->brightness_set_blocking = mt6360_isnk_brightness_set; in mt6360_init_isnk_properties()
674 ret = fwnode_property_read_u32(init_data->fwnode, "led-max-microamp", in mt6360_init_isnk_properties()
677 dev_warn(priv->dev, in mt6360_init_isnk_properties()
678 "Not specified led-max-microamp, config to the minimum\n"); in mt6360_init_isnk_properties()
683 lcdev->max_brightness = val / step_uA; in mt6360_init_isnk_properties()
685 fwnode_property_read_string(init_data->fwnode, "linux,default-trigger", in mt6360_init_isnk_properties()
686 &lcdev->default_trigger); in mt6360_init_isnk_properties()
694 struct led_classdev_flash *flash = &led->flash; in mt6360_init_flash_properties()
695 struct led_classdev *lcdev = &flash->led_cdev; in mt6360_init_flash_properties()
696 struct mt6360_priv *priv = led->priv; in mt6360_init_flash_properties()
701 ret = fwnode_property_read_u32(init_data->fwnode, "led-max-microamp", in mt6360_init_flash_properties()
704 dev_warn(priv->dev, in mt6360_init_flash_properties()
705 "Not specified led-max-microamp, config to the minimum\n"); in mt6360_init_flash_properties()
711 lcdev->max_brightness = in mt6360_init_flash_properties()
712 (val - MT6360_ITORCH_MINUA) / MT6360_ITORCH_STEPUA + 1; in mt6360_init_flash_properties()
713 lcdev->brightness_set_blocking = mt6360_torch_brightness_set; in mt6360_init_flash_properties()
714 lcdev->flags |= LED_DEV_CAP_FLASH; in mt6360_init_flash_properties()
716 ret = fwnode_property_read_u32(init_data->fwnode, "flash-max-microamp", in mt6360_init_flash_properties()
719 dev_warn(priv->dev, in mt6360_init_flash_properties()
720 "Not specified flash-max-microamp, config to the minimum\n"); in mt6360_init_flash_properties()
726 s = &flash->brightness; in mt6360_init_flash_properties()
727 s->min = MT6360_ISTRB_MINUA; in mt6360_init_flash_properties()
728 s->step = MT6360_ISTRB_STEPUA; in mt6360_init_flash_properties()
729 s->val = s->max = val; in mt6360_init_flash_properties()
735 ret = _mt6360_flash_brightness_set(flash, s->min); in mt6360_init_flash_properties()
739 ret = fwnode_property_read_u32(init_data->fwnode, in mt6360_init_flash_properties()
740 "flash-max-timeout-us", &val); in mt6360_init_flash_properties()
742 dev_warn(priv->dev, in mt6360_init_flash_properties()
743 "Not specified flash-max-timeout-us, config to the minimum\n"); in mt6360_init_flash_properties()
749 s = &flash->timeout; in mt6360_init_flash_properties()
750 s->min = MT6360_STRBTO_MINUS; in mt6360_init_flash_properties()
751 s->step = MT6360_STRBTO_STEPUS; in mt6360_init_flash_properties()
752 s->val = s->max = val; in mt6360_init_flash_properties()
754 flash->ops = &mt6360_flash_ops; in mt6360_init_flash_properties()
763 for (i = 0; i < priv->leds_count; i++) { in mt6360_v4l2_flash_release()
764 struct mt6360_led *led = priv->leds + i; in mt6360_v4l2_flash_release()
766 if (led->v4l2_flash) in mt6360_v4l2_flash_release()
767 v4l2_flash_release(led->v4l2_flash); in mt6360_v4l2_flash_release()
778 count = device_get_child_node_count(&pdev->dev); in mt6360_led_probe()
780 dev_err(&pdev->dev, in mt6360_led_probe()
781 "No child node or node count over max led number %zu\n", in mt6360_led_probe()
783 return -EINVAL; in mt6360_led_probe()
786 priv = devm_kzalloc(&pdev->dev, in mt6360_led_probe()
789 return -ENOMEM; in mt6360_led_probe()
791 priv->leds_count = count; in mt6360_led_probe()
792 priv->dev = &pdev->dev; in mt6360_led_probe()
793 mutex_init(&priv->lock); in mt6360_led_probe()
795 priv->regmap = dev_get_regmap(pdev->dev.parent, NULL); in mt6360_led_probe()
796 if (!priv->regmap) { in mt6360_led_probe()
797 dev_err(&pdev->dev, "Failed to get parent regmap\n"); in mt6360_led_probe()
798 return -ENODEV; in mt6360_led_probe()
801 device_for_each_child_node(&pdev->dev, child) { in mt6360_led_probe()
802 struct mt6360_led *led = priv->leds + i; in mt6360_led_probe()
819 ret = -EINVAL; in mt6360_led_probe()
824 if (priv->leds_active & BIT(reg)) { in mt6360_led_probe()
825 ret = -EINVAL; in mt6360_led_probe()
828 priv->leds_active |= BIT(reg); in mt6360_led_probe()
830 led->led_no = reg; in mt6360_led_probe()
831 led->priv = priv; in mt6360_led_probe()
832 led->default_state = led_init_default_state_get(child); in mt6360_led_probe()
843 ret = mt6360_led_register(&pdev->dev, led, &init_data); in mt6360_led_probe()
866 { .compatible = "mediatek,mt6360-led", },
873 .name = "mt6360-led",