Lines Matching +full:default +full:- +full:brightness +full:- +full:level

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 enum led_brightness level) in mt6360_mc_brightness_set() argument
106 struct mt6360_priv *priv = led->priv; in mt6360_mc_brightness_set()
110 mutex_lock(&priv->lock); in mt6360_mc_brightness_set()
112 led_mc_calc_color_components(mccdev, level); in mt6360_mc_brightness_set()
114 for (i = 0; i < mccdev->num_colors; i++) { in mt6360_mc_brightness_set()
115 struct mc_subled *subled = mccdev->subled_info + i; in mt6360_mc_brightness_set()
117 real_bright = min(lcdev->max_brightness, subled->brightness); in mt6360_mc_brightness_set()
118 ret = regmap_update_bits(priv->regmap, MT6360_REG_ISNK(i), in mt6360_mc_brightness_set()
123 enable_mask |= MT6360_ISNK_ENMASK(subled->channel); in mt6360_mc_brightness_set()
125 enable |= MT6360_ISNK_ENMASK(subled->channel); in mt6360_mc_brightness_set()
128 ret = regmap_update_bits(priv->regmap, MT6360_REG_RGBEN, enable_mask, in mt6360_mc_brightness_set()
132 mutex_unlock(&priv->lock); in mt6360_mc_brightness_set()
137 enum led_brightness level) in mt6360_isnk_brightness_set() argument
140 struct mt6360_priv *priv = led->priv; in mt6360_isnk_brightness_set()
141 u32 enable_mask = MT6360_ISNK_ENMASK(led->led_no); in mt6360_isnk_brightness_set()
142 u32 val = level ? MT6360_ISNK_ENMASK(led->led_no) : 0; in mt6360_isnk_brightness_set()
145 mutex_lock(&priv->lock); in mt6360_isnk_brightness_set()
147 ret = regmap_update_bits(priv->regmap, MT6360_REG_ISNK(led->led_no), in mt6360_isnk_brightness_set()
148 MT6360_ISNK_MASK, level); in mt6360_isnk_brightness_set()
152 ret = regmap_update_bits(priv->regmap, MT6360_REG_RGBEN, enable_mask, in mt6360_isnk_brightness_set()
156 mutex_unlock(&priv->lock); in mt6360_isnk_brightness_set()
161 enum led_brightness level) in mt6360_torch_brightness_set() argument
165 struct mt6360_priv *priv = led->priv; in mt6360_torch_brightness_set()
166 u32 enable_mask = MT6360_TORCHEN_MASK | MT6360_FLCSEN_MASK(led->led_no); in mt6360_torch_brightness_set()
167 u32 val = level ? MT6360_FLCSEN_MASK(led->led_no) : 0; in mt6360_torch_brightness_set()
168 u32 prev = priv->fled_torch_used, curr; in mt6360_torch_brightness_set()
171 mutex_lock(&priv->lock); in mt6360_torch_brightness_set()
177 if (priv->fled_strobe_used) { in mt6360_torch_brightness_set()
178 dev_warn(lcdev->dev, "Please disable strobe first [%d]\n", in mt6360_torch_brightness_set()
179 priv->fled_strobe_used); in mt6360_torch_brightness_set()
180 ret = -EBUSY; in mt6360_torch_brightness_set()
184 if (level) in mt6360_torch_brightness_set()
185 curr = prev | BIT(led->led_no); in mt6360_torch_brightness_set()
187 curr = prev & ~BIT(led->led_no); in mt6360_torch_brightness_set()
192 if (level) { in mt6360_torch_brightness_set()
193 ret = regmap_update_bits(priv->regmap, in mt6360_torch_brightness_set()
194 MT6360_REG_FLEDITOR(led->led_no), in mt6360_torch_brightness_set()
195 MT6360_ITORCH_MASK, level - 1); in mt6360_torch_brightness_set()
200 ret = regmap_update_bits(priv->regmap, MT6360_REG_FLEDEN, enable_mask, in mt6360_torch_brightness_set()
205 priv->fled_torch_used = curr; in mt6360_torch_brightness_set()
208 mutex_unlock(&priv->lock); in mt6360_torch_brightness_set()
213 u32 brightness) in mt6360_flash_brightness_set() argument
216 * Due to the current spike when turning on flash, let brightness to be in mt6360_flash_brightness_set()
225 u32 brightness) in _mt6360_flash_brightness_set() argument
229 struct mt6360_priv *priv = led->priv; in _mt6360_flash_brightness_set()
230 struct led_flash_setting *s = &fl_cdev->brightness; in _mt6360_flash_brightness_set()
231 u32 val = (brightness - s->min) / s->step; in _mt6360_flash_brightness_set()
233 return regmap_update_bits(priv->regmap, in _mt6360_flash_brightness_set()
234 MT6360_REG_FLEDISTRB(led->led_no), in _mt6360_flash_brightness_set()
242 struct mt6360_priv *priv = led->priv; in mt6360_strobe_set()
243 struct led_classdev *lcdev = &fl_cdev->led_cdev; in mt6360_strobe_set()
244 struct led_flash_setting *s = &fl_cdev->brightness; in mt6360_strobe_set()
245 u32 enable_mask = MT6360_STROBEN_MASK | MT6360_FLCSEN_MASK(led->led_no); in mt6360_strobe_set()
246 u32 val = state ? MT6360_FLCSEN_MASK(led->led_no) : 0; in mt6360_strobe_set()
247 u32 prev = priv->fled_strobe_used, curr; in mt6360_strobe_set()
250 mutex_lock(&priv->lock); in mt6360_strobe_set()
256 if (priv->fled_torch_used) { in mt6360_strobe_set()
257 dev_warn(lcdev->dev, "Please disable torch first [0x%x]\n", in mt6360_strobe_set()
258 priv->fled_torch_used); in mt6360_strobe_set()
259 ret = -EBUSY; in mt6360_strobe_set()
264 curr = prev | BIT(led->led_no); in mt6360_strobe_set()
266 curr = prev & ~BIT(led->led_no); in mt6360_strobe_set()
271 ret = regmap_update_bits(priv->regmap, MT6360_REG_FLEDEN, enable_mask, in mt6360_strobe_set()
274 dev_err(lcdev->dev, "[%d] control current source %d fail\n", in mt6360_strobe_set()
275 led->led_no, state); in mt6360_strobe_set()
284 ret = _mt6360_flash_brightness_set(fl_cdev, state ? s->val : s->min); in mt6360_strobe_set()
297 priv->fled_strobe_used = curr; in mt6360_strobe_set()
300 mutex_unlock(&priv->lock); in mt6360_strobe_set()
308 struct mt6360_priv *priv = led->priv; in mt6360_strobe_get()
310 mutex_lock(&priv->lock); in mt6360_strobe_get()
311 *state = !!(priv->fled_strobe_used & BIT(led->led_no)); in mt6360_strobe_get()
312 mutex_unlock(&priv->lock); in mt6360_strobe_get()
321 struct mt6360_priv *priv = led->priv; in mt6360_timeout_set()
322 struct led_flash_setting *s = &fl_cdev->timeout; in mt6360_timeout_set()
323 u32 val = (timeout - s->min) / s->step; in mt6360_timeout_set()
326 mutex_lock(&priv->lock); in mt6360_timeout_set()
327 ret = regmap_update_bits(priv->regmap, MT6360_REG_STRBTO, in mt6360_timeout_set()
329 mutex_unlock(&priv->lock); in mt6360_timeout_set()
338 struct mt6360_priv *priv = led->priv; in mt6360_fault_get()
344 mutex_lock(&priv->lock); in mt6360_fault_get()
345 ret = regmap_read(priv->regmap, MT6360_REG_CHGSTAT2, &chg_stat); in mt6360_fault_get()
349 ret = regmap_raw_read(priv->regmap, MT6360_REG_FLEDSTAT1, &fled_stat, in mt6360_fault_get()
354 if (led->led_no == MT6360_LED_FLASH1) { in mt6360_fault_get()
376 mutex_unlock(&priv->lock); in mt6360_fault_get()
390 struct mt6360_priv *priv = led->priv; in mt6360_isnk_init_default_state()
392 u32 level; in mt6360_isnk_init_default_state() local
395 ret = regmap_read(priv->regmap, MT6360_REG_ISNK(led->led_no), &regval); in mt6360_isnk_init_default_state()
398 level = regval & MT6360_ISNK_MASK; in mt6360_isnk_init_default_state()
400 ret = regmap_read(priv->regmap, MT6360_REG_RGBEN, &regval); in mt6360_isnk_init_default_state()
404 if (!(regval & MT6360_ISNK_ENMASK(led->led_no))) in mt6360_isnk_init_default_state()
405 level = LED_OFF; in mt6360_isnk_init_default_state()
407 switch (led->default_state) { in mt6360_isnk_init_default_state()
409 led->isnk.brightness = led->isnk.max_brightness; in mt6360_isnk_init_default_state()
412 led->isnk.brightness = min(level, led->isnk.max_brightness); in mt6360_isnk_init_default_state()
414 default: in mt6360_isnk_init_default_state()
415 led->isnk.brightness = LED_OFF; in mt6360_isnk_init_default_state()
418 return mt6360_isnk_brightness_set(&led->isnk, led->isnk.brightness); in mt6360_isnk_init_default_state()
423 struct led_classdev_flash *flash = &led->flash; in mt6360_flash_init_default_state()
424 struct mt6360_priv *priv = led->priv; in mt6360_flash_init_default_state()
425 u32 enable_mask = MT6360_TORCHEN_MASK | MT6360_FLCSEN_MASK(led->led_no); in mt6360_flash_init_default_state()
426 u32 level; in mt6360_flash_init_default_state() local
430 ret = regmap_read(priv->regmap, MT6360_REG_FLEDITOR(led->led_no), in mt6360_flash_init_default_state()
434 level = regval & MT6360_ITORCH_MASK; in mt6360_flash_init_default_state()
436 ret = regmap_read(priv->regmap, MT6360_REG_FLEDEN, &regval); in mt6360_flash_init_default_state()
441 level += 1; in mt6360_flash_init_default_state()
443 level = LED_OFF; in mt6360_flash_init_default_state()
445 switch (led->default_state) { in mt6360_flash_init_default_state()
447 flash->led_cdev.brightness = flash->led_cdev.max_brightness; in mt6360_flash_init_default_state()
450 flash->led_cdev.brightness = in mt6360_flash_init_default_state()
451 min(level, flash->led_cdev.max_brightness); in mt6360_flash_init_default_state()
453 default: in mt6360_flash_init_default_state()
454 flash->led_cdev.brightness = LED_OFF; in mt6360_flash_init_default_state()
457 return mt6360_torch_brightness_set(&flash->led_cdev, in mt6360_flash_init_default_state()
458 flash->led_cdev.brightness); in mt6360_flash_init_default_state()
465 struct led_classdev_flash *flash = v4l2_flash->fled_cdev; in mt6360_flash_external_strobe_set()
467 struct mt6360_priv *priv = led->priv; in mt6360_flash_external_strobe_set()
468 u32 mask = MT6360_FLCSEN_MASK(led->led_no); in mt6360_flash_external_strobe_set()
472 mutex_lock(&priv->lock); in mt6360_flash_external_strobe_set()
474 ret = regmap_update_bits(priv->regmap, MT6360_REG_FLEDEN, mask, val); in mt6360_flash_external_strobe_set()
479 priv->fled_strobe_used |= BIT(led->led_no); in mt6360_flash_external_strobe_set()
481 priv->fled_strobe_used &= ~BIT(led->led_no); in mt6360_flash_external_strobe_set()
484 mutex_unlock(&priv->lock); in mt6360_flash_external_strobe_set()
496 struct led_flash_setting *s = &config->intensity; in mt6360_init_v4l2_flash_config()
498 lcdev = &led->flash.led_cdev; in mt6360_init_v4l2_flash_config()
500 s->min = MT6360_ITORCH_MINUA; in mt6360_init_v4l2_flash_config()
501 s->step = MT6360_ITORCH_STEPUA; in mt6360_init_v4l2_flash_config()
502 s->val = s->max = s->min + (lcdev->max_brightness - 1) * s->step; in mt6360_init_v4l2_flash_config()
504 config->has_external_strobe = 1; in mt6360_init_v4l2_flash_config()
505 strscpy(config->dev_name, lcdev->dev->kobj.name, in mt6360_init_v4l2_flash_config()
506 sizeof(config->dev_name)); in mt6360_init_v4l2_flash_config()
508 config->flash_faults = LED_FAULT_SHORT_CIRCUIT | LED_FAULT_TIMEOUT | in mt6360_init_v4l2_flash_config()
523 struct mt6360_priv *priv = led->priv; in mt6360_led_register()
527 if ((led->led_no == MT6360_LED_ISNK1 || in mt6360_led_register()
528 led->led_no == MT6360_VIRTUAL_MULTICOLOR) && in mt6360_led_register()
529 (priv->leds_active & BIT(MT6360_LED_ISNK1))) { in mt6360_led_register()
534 ret = regmap_update_bits(priv->regmap, MT6360_REG_RGBEN, in mt6360_led_register()
543 switch (led->led_no) { in mt6360_led_register()
545 ret = mt6360_mc_brightness_set(&led->mc.led_cdev, LED_OFF); in mt6360_led_register()
548 "Failed to init multicolor brightness\n"); in mt6360_led_register()
553 &led->mc, init_data); in mt6360_led_register()
563 led->led_no); in mt6360_led_register()
567 ret = devm_led_classdev_register_ext(parent, &led->isnk, in mt6360_led_register()
571 led->led_no); in mt6360_led_register()
575 default: in mt6360_led_register()
579 led->led_no); in mt6360_led_register()
583 ret = devm_led_classdev_flash_register_ext(parent, &led->flash, in mt6360_led_register()
587 led->led_no); in mt6360_led_register()
592 led->v4l2_flash = v4l2_flash_init(parent, init_data->fwnode, in mt6360_led_register()
593 &led->flash, in mt6360_led_register()
596 if (IS_ERR(led->v4l2_flash)) { in mt6360_led_register()
598 led->led_no); in mt6360_led_register()
599 return PTR_ERR(led->v4l2_flash); in mt6360_led_register()
612 retval = rounddown(retval - min, step) + min; in clamp_align()
621 struct mt6360_priv *priv = led->priv; in mt6360_init_isnk_properties()
627 if (led->led_no == MT6360_VIRTUAL_MULTICOLOR) { in mt6360_init_isnk_properties()
630 sub_led = devm_kzalloc(priv->dev, in mt6360_init_isnk_properties()
633 return -ENOMEM; in mt6360_init_isnk_properties()
635 fwnode_for_each_child_node(init_data->fwnode, child) { in mt6360_init_isnk_properties()
640 priv->leds_active & BIT(reg)) in mt6360_init_isnk_properties()
641 return -EINVAL; in mt6360_init_isnk_properties()
645 dev_err(priv->dev, in mt6360_init_isnk_properties()
647 led->led_no); in mt6360_init_isnk_properties()
651 priv->leds_active |= BIT(reg); in mt6360_init_isnk_properties()
658 dev_err(priv->dev, in mt6360_init_isnk_properties()
660 return -EINVAL; in mt6360_init_isnk_properties()
663 led->mc.num_colors = num_color; in mt6360_init_isnk_properties()
664 led->mc.subled_info = sub_led; in mt6360_init_isnk_properties()
666 lcdev = &led->mc.led_cdev; in mt6360_init_isnk_properties()
667 lcdev->brightness_set_blocking = mt6360_mc_brightness_set; in mt6360_init_isnk_properties()
669 if (led->led_no == MT6360_LED_ISNKML) { in mt6360_init_isnk_properties()
674 lcdev = &led->isnk; in mt6360_init_isnk_properties()
675 lcdev->brightness_set_blocking = mt6360_isnk_brightness_set; in mt6360_init_isnk_properties()
678 ret = fwnode_property_read_u32(init_data->fwnode, "led-max-microamp", in mt6360_init_isnk_properties()
681 dev_warn(priv->dev, in mt6360_init_isnk_properties()
682 "Not specified led-max-microamp, config to the minimum\n"); in mt6360_init_isnk_properties()
687 lcdev->max_brightness = val / step_uA; in mt6360_init_isnk_properties()
689 fwnode_property_read_string(init_data->fwnode, "linux,default-trigger", in mt6360_init_isnk_properties()
690 &lcdev->default_trigger); in mt6360_init_isnk_properties()
698 struct led_classdev_flash *flash = &led->flash; in mt6360_init_flash_properties()
699 struct led_classdev *lcdev = &flash->led_cdev; in mt6360_init_flash_properties()
700 struct mt6360_priv *priv = led->priv; in mt6360_init_flash_properties()
705 ret = fwnode_property_read_u32(init_data->fwnode, "led-max-microamp", in mt6360_init_flash_properties()
708 dev_warn(priv->dev, in mt6360_init_flash_properties()
709 "Not specified led-max-microamp, config to the minimum\n"); in mt6360_init_flash_properties()
715 lcdev->max_brightness = in mt6360_init_flash_properties()
716 (val - MT6360_ITORCH_MINUA) / MT6360_ITORCH_STEPUA + 1; in mt6360_init_flash_properties()
717 lcdev->brightness_set_blocking = mt6360_torch_brightness_set; in mt6360_init_flash_properties()
718 lcdev->flags |= LED_DEV_CAP_FLASH; in mt6360_init_flash_properties()
720 ret = fwnode_property_read_u32(init_data->fwnode, "flash-max-microamp", in mt6360_init_flash_properties()
723 dev_warn(priv->dev, in mt6360_init_flash_properties()
724 "Not specified flash-max-microamp, config to the minimum\n"); in mt6360_init_flash_properties()
730 s = &flash->brightness; in mt6360_init_flash_properties()
731 s->min = MT6360_ISTRB_MINUA; in mt6360_init_flash_properties()
732 s->step = MT6360_ISTRB_STEPUA; in mt6360_init_flash_properties()
733 s->val = s->max = val; in mt6360_init_flash_properties()
736 * Always configure as min level when off to prevent flash current in mt6360_init_flash_properties()
739 ret = _mt6360_flash_brightness_set(flash, s->min); in mt6360_init_flash_properties()
743 ret = fwnode_property_read_u32(init_data->fwnode, in mt6360_init_flash_properties()
744 "flash-max-timeout-us", &val); in mt6360_init_flash_properties()
746 dev_warn(priv->dev, in mt6360_init_flash_properties()
747 "Not specified flash-max-timeout-us, config to the minimum\n"); in mt6360_init_flash_properties()
753 s = &flash->timeout; in mt6360_init_flash_properties()
754 s->min = MT6360_STRBTO_MINUS; in mt6360_init_flash_properties()
755 s->step = MT6360_STRBTO_STEPUS; in mt6360_init_flash_properties()
756 s->val = s->max = val; in mt6360_init_flash_properties()
758 flash->ops = &mt6360_flash_ops; in mt6360_init_flash_properties()
770 if (!fwnode_property_read_string(init_data->fwnode, in mt6360_init_common_properties()
771 "default-state", &str)) { in mt6360_init_common_properties()
776 led->default_state = ret; in mt6360_init_common_properties()
786 for (i = 0; i < priv->leds_count; i++) { in mt6360_v4l2_flash_release()
787 struct mt6360_led *led = priv->leds + i; in mt6360_v4l2_flash_release()
789 if (led->v4l2_flash) in mt6360_v4l2_flash_release()
790 v4l2_flash_release(led->v4l2_flash); in mt6360_v4l2_flash_release()
801 count = device_get_child_node_count(&pdev->dev); in mt6360_led_probe()
803 dev_err(&pdev->dev, in mt6360_led_probe()
806 return -EINVAL; in mt6360_led_probe()
809 priv = devm_kzalloc(&pdev->dev, in mt6360_led_probe()
812 return -ENOMEM; in mt6360_led_probe()
814 priv->leds_count = count; in mt6360_led_probe()
815 priv->dev = &pdev->dev; in mt6360_led_probe()
816 mutex_init(&priv->lock); in mt6360_led_probe()
818 priv->regmap = dev_get_regmap(pdev->dev.parent, NULL); in mt6360_led_probe()
819 if (!priv->regmap) { in mt6360_led_probe()
820 dev_err(&pdev->dev, "Failed to get parent regmap\n"); in mt6360_led_probe()
821 return -ENODEV; in mt6360_led_probe()
824 device_for_each_child_node(&pdev->dev, child) { in mt6360_led_probe()
825 struct mt6360_led *led = priv->leds + i; in mt6360_led_probe()
842 ret = -EINVAL; in mt6360_led_probe()
847 if (priv->leds_active & BIT(reg)) { in mt6360_led_probe()
848 ret = -EINVAL; in mt6360_led_probe()
851 priv->leds_active |= BIT(reg); in mt6360_led_probe()
853 led->led_no = reg; in mt6360_led_probe()
854 led->priv = priv; in mt6360_led_probe()
869 ret = mt6360_led_register(&pdev->dev, led, &init_data); in mt6360_led_probe()
893 { .compatible = "mediatek,mt6360-led", },
900 .name = "mt6360-led",