Lines Matching +full:flash +full:- +full:max +full:- +full:timeout +full:- +full:us

1 // SPDX-License-Identifier: GPL-2.0-only
3 * drivers/leds/leds-as3645a.c - AS3645A and LM3555 flash controllers driver
5 * Copyright (C) 2008-2011 Nokia Corporation
16 #include <linux/led-class-flash.h>
23 #include <media/v4l2-flash-led-class.h>
25 #define AS_TIMER_US_TO_CODE(t) (((t) / 1000 - 100) / 50)
30 /* Read-only Design info register: Reset state: xxxx 0001 */
35 /* Read-only Version control register: Reset state: 0000 0000
86 #define AS_FLASH_TIMEOUT_MIN 100000 /* us */
105 ((min_t(u32, AS_PEAK_mA_MAX, a) - 1250) / 250)
144 unsigned int timeout; member
156 static int as3645a_write(struct as3645a *flash, u8 addr, u8 val) in as3645a_write() argument
158 struct i2c_client *client = flash->client; in as3645a_write()
163 dev_dbg(&client->dev, "Write Addr:%02X Val:%02X %s\n", addr, val, in as3645a_write()
170 static int as3645a_read(struct as3645a *flash, u8 addr) in as3645a_read() argument
172 struct i2c_client *client = flash->client; in as3645a_read()
177 dev_dbg(&client->dev, "Read Addr:%02X Val:%02X %s\n", addr, rval, in as3645a_read()
183 /* -----------------------------------------------------------------------------
188 * as3645a_set_current - Set flash configuration registers
189 * @flash: The flash
191 * Configure the hardware with flash, assist and indicator currents, as well as
192 * flash timeout.
197 static int as3645a_set_current(struct as3645a *flash) in as3645a_set_current() argument
201 val = (flash->flash_current << AS_CURRENT_FLASH_CURRENT_SHIFT) in as3645a_set_current()
202 | (flash->assist_current << AS_CURRENT_ASSIST_LIGHT_SHIFT) in as3645a_set_current()
205 return as3645a_write(flash, AS_CURRENT_SET_REG, val); in as3645a_set_current()
208 static int as3645a_set_timeout(struct as3645a *flash) in as3645a_set_timeout() argument
212 val = flash->timeout << AS_INDICATOR_AND_TIMER_TIMEOUT_SHIFT; in as3645a_set_timeout()
214 val |= (flash->cfg.voltage_reference in as3645a_set_timeout()
216 | ((flash->indicator_current ? flash->indicator_current - 1 : 0) in as3645a_set_timeout()
219 return as3645a_write(flash, AS_INDICATOR_AND_TIMER_REG, val); in as3645a_set_timeout()
223 * as3645a_set_control - Set flash control register
224 * @flash: The flash
234 as3645a_set_control(struct as3645a *flash, enum as_mode mode, bool on) in as3645a_set_control() argument
239 reg = (flash->cfg.peak << AS_CONTROL_COIL_PEAK_SHIFT) in as3645a_set_control()
244 flash->strobe_source == V4L2_FLASH_STROBE_SOURCE_EXTERNAL) in as3645a_set_control()
248 return as3645a_write(flash, AS_CONTROL_REG, reg); in as3645a_set_control()
253 struct as3645a *flash = fled_to_as3645a(fled); in as3645a_get_fault() local
257 rval = as3645a_read(flash, AS_FAULT_INFO_REG); in as3645a_get_fault()
267 dev_dbg(&flash->client->dev, "%u connected LEDs\n", in as3645a_get_fault()
285 static unsigned int __as3645a_current_to_reg(unsigned int min, unsigned int max, in __as3645a_current_to_reg() argument
292 if (val > max) in __as3645a_current_to_reg()
293 val = max; in __as3645a_current_to_reg()
295 return (val - min) / step; in __as3645a_current_to_reg()
298 static unsigned int as3645a_current_to_reg(struct as3645a *flash, bool is_flash, in as3645a_current_to_reg() argument
303 flash->cfg.assist_max_ua, in as3645a_current_to_reg()
307 flash->cfg.flash_max_ua, in as3645a_current_to_reg()
314 struct as3645a *flash = iled_cdev_to_as3645a(iled_cdev); in as3645a_set_indicator_brightness() local
317 flash->indicator_current = brightness; in as3645a_set_indicator_brightness()
319 rval = as3645a_set_timeout(flash); in as3645a_set_indicator_brightness()
323 return as3645a_set_control(flash, AS_MODE_INDICATOR, brightness); in as3645a_set_indicator_brightness()
330 struct as3645a *flash = fled_to_as3645a(fled); in as3645a_set_assist_brightness() local
335 flash->assist_current = brightness - 1; in as3645a_set_assist_brightness()
337 rval = as3645a_set_current(flash); in as3645a_set_assist_brightness()
342 return as3645a_set_control(flash, AS_MODE_ASSIST, brightness); in as3645a_set_assist_brightness()
348 struct as3645a *flash = fled_to_as3645a(fled); in as3645a_set_flash_brightness() local
350 flash->flash_current = as3645a_current_to_reg(flash, true, in as3645a_set_flash_brightness()
353 return as3645a_set_current(flash); in as3645a_set_flash_brightness()
359 struct as3645a *flash = fled_to_as3645a(fled); in as3645a_set_flash_timeout() local
361 flash->timeout = AS_TIMER_US_TO_CODE(timeout_us); in as3645a_set_flash_timeout()
363 return as3645a_set_timeout(flash); in as3645a_set_flash_timeout()
368 struct as3645a *flash = fled_to_as3645a(fled); in as3645a_set_strobe() local
370 return as3645a_set_control(flash, AS_MODE_FLASH, state); in as3645a_set_strobe()
380 static int as3645a_setup(struct as3645a *flash) in as3645a_setup() argument
382 struct device *dev = &flash->client->dev; in as3645a_setup()
387 rval = as3645a_read(flash, AS_FAULT_INFO_REG); in as3645a_setup()
393 rval = as3645a_set_current(flash); in as3645a_setup()
397 rval = as3645a_set_timeout(flash); in as3645a_setup()
401 rval = as3645a_set_control(flash, AS_MODE_INDICATOR, false); in as3645a_setup()
406 rval = as3645a_get_fault(&flash->fled, &fault); in as3645a_setup()
411 as3645a_read(flash, AS_INDICATOR_AND_TIMER_REG)); in as3645a_setup()
413 as3645a_read(flash, AS_CURRENT_SET_REG)); in as3645a_setup()
415 as3645a_read(flash, AS_CONTROL_REG)); in as3645a_setup()
417 return rval & ~AS_FAULT_INFO_LED_AMOUNT ? -EIO : 0; in as3645a_setup()
420 static int as3645a_detect(struct as3645a *flash) in as3645a_detect() argument
422 struct device *dev = &flash->client->dev; in as3645a_detect()
426 rval = as3645a_read(flash, AS_DESIGN_INFO_REG); in as3645a_detect()
435 rval = as3645a_read(flash, AS_VERSION_CONTROL_REG); in as3645a_detect()
448 return -ENODEV; in as3645a_detect()
474 rval = as3645a_write(flash, AS_PASSWORD_REG, AS_PASSWORD_UNLOCK_VALUE); in as3645a_detect()
478 return as3645a_write(flash, AS_BOOST_REG, AS_BOOST_CURRENT_DISABLE); in as3645a_detect()
481 static int as3645a_parse_node(struct device *dev, struct as3645a *flash) in as3645a_parse_node() argument
483 struct as3645a_config *cfg = &flash->cfg; in as3645a_parse_node()
493 flash->flash_node = child; in as3645a_parse_node()
497 flash->indicator_node = child; in as3645a_parse_node()
501 dev_warn(&flash->client->dev, in as3645a_parse_node()
507 if (!flash->flash_node) { in as3645a_parse_node()
508 dev_err(&flash->client->dev, "can't find flash node\n"); in as3645a_parse_node()
509 return -ENODEV; in as3645a_parse_node()
512 rval = fwnode_property_read_u32(flash->flash_node, "flash-timeout-us", in as3645a_parse_node()
513 &cfg->flash_timeout_us); in as3645a_parse_node()
515 dev_err(&flash->client->dev, in as3645a_parse_node()
516 "can't read flash-timeout-us property for flash\n"); in as3645a_parse_node()
520 rval = fwnode_property_read_u32(flash->flash_node, "flash-max-microamp", in as3645a_parse_node()
521 &cfg->flash_max_ua); in as3645a_parse_node()
523 dev_err(&flash->client->dev, in as3645a_parse_node()
524 "can't read flash-max-microamp property for flash\n"); in as3645a_parse_node()
528 rval = fwnode_property_read_u32(flash->flash_node, "led-max-microamp", in as3645a_parse_node()
529 &cfg->assist_max_ua); in as3645a_parse_node()
531 dev_err(&flash->client->dev, in as3645a_parse_node()
532 "can't read led-max-microamp property for flash\n"); in as3645a_parse_node()
536 fwnode_property_read_u32(flash->flash_node, "voltage-reference", in as3645a_parse_node()
537 &cfg->voltage_reference); in as3645a_parse_node()
539 fwnode_property_read_u32(flash->flash_node, "ams,input-max-microamp", in as3645a_parse_node()
540 &cfg->peak); in as3645a_parse_node()
541 cfg->peak = AS_PEAK_mA_TO_REG(cfg->peak); in as3645a_parse_node()
543 if (!flash->indicator_node) { in as3645a_parse_node()
544 dev_warn(&flash->client->dev, in as3645a_parse_node()
546 rval = -ENODEV; in as3645a_parse_node()
551 rval = fwnode_property_read_u32(flash->indicator_node, in as3645a_parse_node()
552 "led-max-microamp", in as3645a_parse_node()
553 &cfg->indicator_max_ua); in as3645a_parse_node()
555 dev_err(&flash->client->dev, in as3645a_parse_node()
556 "can't read led-max-microamp property for indicator\n"); in as3645a_parse_node()
563 fwnode_handle_put(flash->flash_node); in as3645a_parse_node()
564 fwnode_handle_put(flash->indicator_node); in as3645a_parse_node()
569 static int as3645a_led_class_setup(struct as3645a *flash) in as3645a_led_class_setup() argument
571 struct led_classdev *fled_cdev = &flash->fled.led_cdev; in as3645a_led_class_setup()
572 struct led_classdev *iled_cdev = &flash->iled_cdev; in as3645a_led_class_setup()
577 iled_cdev->brightness_set_blocking = as3645a_set_indicator_brightness; in as3645a_led_class_setup()
578 iled_cdev->max_brightness = in as3645a_led_class_setup()
579 flash->cfg.indicator_max_ua / AS_INDICATOR_INTENSITY_STEP; in as3645a_led_class_setup()
580 iled_cdev->flags = LED_CORE_SUSPENDRESUME; in as3645a_led_class_setup()
582 init_data.fwnode = flash->indicator_node; in as3645a_led_class_setup()
586 rval = led_classdev_register_ext(&flash->client->dev, iled_cdev, in as3645a_led_class_setup()
591 cfg = &flash->fled.brightness; in as3645a_led_class_setup()
592 cfg->min = AS_FLASH_INTENSITY_MIN; in as3645a_led_class_setup()
593 cfg->max = flash->cfg.flash_max_ua; in as3645a_led_class_setup()
594 cfg->step = AS_FLASH_INTENSITY_STEP; in as3645a_led_class_setup()
595 cfg->val = flash->cfg.flash_max_ua; in as3645a_led_class_setup()
597 cfg = &flash->fled.timeout; in as3645a_led_class_setup()
598 cfg->min = AS_FLASH_TIMEOUT_MIN; in as3645a_led_class_setup()
599 cfg->max = flash->cfg.flash_timeout_us; in as3645a_led_class_setup()
600 cfg->step = AS_FLASH_TIMEOUT_STEP; in as3645a_led_class_setup()
601 cfg->val = flash->cfg.flash_timeout_us; in as3645a_led_class_setup()
603 flash->fled.ops = &as3645a_led_flash_ops; in as3645a_led_class_setup()
605 fled_cdev->brightness_set_blocking = as3645a_set_assist_brightness; in as3645a_led_class_setup()
607 fled_cdev->max_brightness = in as3645a_led_class_setup()
608 as3645a_current_to_reg(flash, false, in as3645a_led_class_setup()
609 flash->cfg.assist_max_ua) + 1; in as3645a_led_class_setup()
610 fled_cdev->flags = LED_DEV_CAP_FLASH | LED_CORE_SUSPENDRESUME; in as3645a_led_class_setup()
612 init_data.fwnode = flash->flash_node; in as3645a_led_class_setup()
614 init_data.default_label = "flash"; in as3645a_led_class_setup()
616 rval = led_classdev_flash_register_ext(&flash->client->dev, in as3645a_led_class_setup()
617 &flash->fled, &init_data); in as3645a_led_class_setup()
625 dev_err(&flash->client->dev, in as3645a_led_class_setup()
631 static int as3645a_v4l2_setup(struct as3645a *flash) in as3645a_v4l2_setup() argument
633 struct led_classdev_flash *fled = &flash->fled; in as3645a_v4l2_setup()
634 struct led_classdev *led = &fled->led_cdev; in as3645a_v4l2_setup()
638 .max = flash->cfg.assist_max_ua, in as3645a_v4l2_setup()
640 .val = flash->cfg.assist_max_ua, in as3645a_v4l2_setup()
646 .max = flash->cfg.indicator_max_ua, in as3645a_v4l2_setup()
648 .val = flash->cfg.indicator_max_ua, in as3645a_v4l2_setup()
652 strscpy(cfg.dev_name, led->dev->kobj.name, sizeof(cfg.dev_name)); in as3645a_v4l2_setup()
653 strscpy(cfgind.dev_name, flash->iled_cdev.dev->kobj.name, in as3645a_v4l2_setup()
656 flash->vf = v4l2_flash_init( in as3645a_v4l2_setup()
657 &flash->client->dev, flash->flash_node, &flash->fled, NULL, in as3645a_v4l2_setup()
659 if (IS_ERR(flash->vf)) in as3645a_v4l2_setup()
660 return PTR_ERR(flash->vf); in as3645a_v4l2_setup()
662 flash->vfind = v4l2_flash_indicator_init( in as3645a_v4l2_setup()
663 &flash->client->dev, flash->indicator_node, &flash->iled_cdev, in as3645a_v4l2_setup()
665 if (IS_ERR(flash->vfind)) { in as3645a_v4l2_setup()
666 v4l2_flash_release(flash->vf); in as3645a_v4l2_setup()
667 return PTR_ERR(flash->vfind); in as3645a_v4l2_setup()
675 struct as3645a *flash; in as3645a_probe() local
678 if (!dev_fwnode(&client->dev)) in as3645a_probe()
679 return -ENODEV; in as3645a_probe()
681 flash = devm_kzalloc(&client->dev, sizeof(*flash), GFP_KERNEL); in as3645a_probe()
682 if (flash == NULL) in as3645a_probe()
683 return -ENOMEM; in as3645a_probe()
685 flash->client = client; in as3645a_probe()
687 rval = as3645a_parse_node(&client->dev, flash); in as3645a_probe()
691 rval = as3645a_detect(flash); in as3645a_probe()
695 mutex_init(&flash->mutex); in as3645a_probe()
696 i2c_set_clientdata(client, flash); in as3645a_probe()
698 rval = as3645a_setup(flash); in as3645a_probe()
702 rval = as3645a_led_class_setup(flash); in as3645a_probe()
706 rval = as3645a_v4l2_setup(flash); in as3645a_probe()
713 led_classdev_flash_unregister(&flash->fled); in as3645a_probe()
716 mutex_destroy(&flash->mutex); in as3645a_probe()
719 fwnode_handle_put(flash->flash_node); in as3645a_probe()
720 fwnode_handle_put(flash->indicator_node); in as3645a_probe()
727 struct as3645a *flash = i2c_get_clientdata(client); in as3645a_remove() local
729 as3645a_set_control(flash, AS_MODE_EXT_TORCH, false); in as3645a_remove()
731 v4l2_flash_release(flash->vf); in as3645a_remove()
732 v4l2_flash_release(flash->vfind); in as3645a_remove()
734 led_classdev_flash_unregister(&flash->fled); in as3645a_remove()
735 led_classdev_unregister(&flash->iled_cdev); in as3645a_remove()
737 mutex_destroy(&flash->mutex); in as3645a_remove()
739 fwnode_handle_put(flash->flash_node); in as3645a_remove()
740 fwnode_handle_put(flash->indicator_node); in as3645a_remove()
769 MODULE_DESCRIPTION("LED flash driver for AS3645A, LM3555 and their clones");