Lines Matching +full:on +full:- +full:chip
1 // SPDX-License-Identifier: GPL-2.0-or-later
7 * Datasheet: https://www.kinet-ic.com/uploads/KTD2026-7-04h.pdf
11 #include <linux/led-class-multicolor.h>
50 /* Register 2-3 */
63 /* Register 6-9 */
88 struct ktd202x *chip; member
106 static int ktd202x_chip_disable(struct ktd202x *chip) in ktd202x_chip_disable() argument
110 if (!chip->enabled) in ktd202x_chip_disable()
113 regmap_write(chip->regmap, KTD202X_REG_RESET_CONTROL, KTD202X_ENABLE_CTRL_SLEEP); in ktd202x_chip_disable()
115 ret = regulator_bulk_disable(ARRAY_SIZE(chip->regulators), chip->regulators); in ktd202x_chip_disable()
117 dev_err(chip->dev, "Failed to disable regulators: %d\n", ret); in ktd202x_chip_disable()
121 chip->enabled = false; in ktd202x_chip_disable()
125 static int ktd202x_chip_enable(struct ktd202x *chip) in ktd202x_chip_enable() argument
129 if (chip->enabled) in ktd202x_chip_enable()
132 ret = regulator_bulk_enable(ARRAY_SIZE(chip->regulators), chip->regulators); in ktd202x_chip_enable()
134 dev_err(chip->dev, "Failed to enable regulators: %d\n", ret); in ktd202x_chip_enable()
137 chip->enabled = true; in ktd202x_chip_enable()
139 ret = regmap_write(chip->regmap, KTD202X_REG_RESET_CONTROL, KTD202X_ENABLE_CTRL_WAKE); in ktd202x_chip_enable()
142 dev_err(chip->dev, "Failed to enable the chip: %d\n", ret); in ktd202x_chip_enable()
143 ktd202x_chip_disable(chip); in ktd202x_chip_enable()
149 static bool ktd202x_chip_in_use(struct ktd202x *chip) in ktd202x_chip_in_use() argument
153 for (i = 0; i < chip->num_leds; i++) { in ktd202x_chip_in_use()
154 if (chip->leds[i].cdev.brightness) in ktd202x_chip_in_use()
171 if (ktd202x_chip_in_use(led->chip)) { in ktd202x_brightness_set()
172 ret = ktd202x_chip_enable(led->chip); in ktd202x_brightness_set()
177 ret = regmap_read(led->chip->regmap, KTD202X_REG_CHANNEL_CTRL, &state); in ktd202x_brightness_set()
183 * channel because another channel cannot be in state ON at the same time in ktd202x_brightness_set()
204 /* Register expects brightness between 0 and MAX_BRIGHTNESS - 1 */ in ktd202x_brightness_set()
205 ret = regmap_write(led->chip->regmap, KTD202X_REG_LED_IOUT(channel), in ktd202x_brightness_set()
206 brightness - 1); in ktd202x_brightness_set()
217 ret = regmap_update_bits(led->chip->regmap, KTD202X_REG_CHANNEL_CTRL, in ktd202x_brightness_set()
223 if (!ktd202x_chip_in_use(led->chip)) in ktd202x_brightness_set()
224 return ktd202x_chip_disable(led->chip); in ktd202x_brightness_set()
236 cdev->brightness = value; in ktd202x_brightness_single_set()
238 mutex_lock(&led->chip->mutex); in ktd202x_brightness_single_set()
241 info.channel = led->index; in ktd202x_brightness_single_set()
244 mutex_unlock(&led->chip->mutex); in ktd202x_brightness_single_set()
256 cdev->brightness = value; in ktd202x_brightness_mc_set()
258 mutex_lock(&led->chip->mutex); in ktd202x_brightness_mc_set()
261 ret = ktd202x_brightness_set(led, mc->subled_info, mc->num_colors); in ktd202x_brightness_mc_set()
263 mutex_unlock(&led->chip->mutex); in ktd202x_brightness_mc_set()
273 int ret, num_steps, on; in ktd202x_blink_set() local
279 mutex_lock(&led->chip->mutex); in ktd202x_blink_set()
289 /* Never off - brightness is already set, disable blinking */ in ktd202x_blink_set()
291 ret = regmap_update_bits(led->chip->regmap, KTD202X_REG_CHANNEL_CTRL, in ktd202x_blink_set()
299 num_steps = (*delay_on + *delay_off - KTD202X_FLASH_PERIOD_MIN_MS) / in ktd202x_blink_set()
303 /* Integer representation of percentage of LED ON time */ in ktd202x_blink_set()
304 on = (*delay_on * KTD202X_FLASH_ON_MAX) / (*delay_on + *delay_off); in ktd202x_blink_set()
306 /* Actually used delay_{on,off} values */ in ktd202x_blink_set()
308 *delay_on = (delay_total_ms * on) / KTD202X_FLASH_ON_MAX; in ktd202x_blink_set()
309 *delay_off = delay_total_ms - *delay_on; in ktd202x_blink_set()
312 ret = regmap_write(led->chip->regmap, KTD202X_REG_FLASH_PERIOD, num_steps); in ktd202x_blink_set()
316 ret = regmap_write(led->chip->regmap, KTD202X_REG_PWM1_TIMER, on); in ktd202x_blink_set()
320 ret = regmap_update_bits(led->chip->regmap, KTD202X_REG_CHANNEL_CTRL, in ktd202x_blink_set()
323 mutex_unlock(&led->chip->mutex); in ktd202x_blink_set()
335 if (!cdev->brightness) { in ktd202x_blink_single_set()
347 /* Never on - just set to off */ in ktd202x_blink_single_set()
351 info.channel = led->index; in ktd202x_blink_single_set()
364 if (!cdev->brightness) { in ktd202x_blink_mc_set()
376 /* Never on - just set to off */ in ktd202x_blink_mc_set()
380 return ktd202x_blink_set(led, delay_on, delay_off, mc->subled_info, in ktd202x_blink_mc_set()
381 mc->num_colors); in ktd202x_blink_mc_set()
384 static int ktd202x_setup_led_rgb(struct ktd202x *chip, struct fwnode_handle *fwnode, in ktd202x_setup_led_rgb() argument
397 if (!num_channels || num_channels > chip->num_leds) in ktd202x_setup_led_rgb()
398 return -EINVAL; in ktd202x_setup_led_rgb()
400 info = devm_kcalloc(chip->dev, num_channels, sizeof(*info), GFP_KERNEL); in ktd202x_setup_led_rgb()
402 return -ENOMEM; in ktd202x_setup_led_rgb()
410 if (ret != 0 || reg >= chip->num_leds) { in ktd202x_setup_led_rgb()
411 dev_err(chip->dev, "invalid 'reg' of %pfw\n", child); in ktd202x_setup_led_rgb()
417 if (ret < 0 && ret != -EINVAL) { in ktd202x_setup_led_rgb()
418 dev_err(chip->dev, "failed to parse 'color' of %pfw\n", child); in ktd202x_setup_led_rgb()
429 led->mcdev.subled_info = info; in ktd202x_setup_led_rgb()
430 led->mcdev.num_colors = num_channels; in ktd202x_setup_led_rgb()
432 cdev = &led->mcdev.led_cdev; in ktd202x_setup_led_rgb()
433 cdev->brightness_set_blocking = ktd202x_brightness_mc_set; in ktd202x_setup_led_rgb()
434 cdev->blink_set = ktd202x_blink_mc_set; in ktd202x_setup_led_rgb()
436 return devm_led_classdev_multicolor_register_ext(chip->dev, &led->mcdev, init_data); in ktd202x_setup_led_rgb()
439 static int ktd202x_setup_led_single(struct ktd202x *chip, struct fwnode_handle *fwnode, in ktd202x_setup_led_single() argument
447 if (ret != 0 || reg >= chip->num_leds) { in ktd202x_setup_led_single()
448 dev_err(chip->dev, "invalid 'reg' of %pfw\n", fwnode); in ktd202x_setup_led_single()
449 return -EINVAL; in ktd202x_setup_led_single()
451 led->index = reg; in ktd202x_setup_led_single()
453 cdev = &led->cdev; in ktd202x_setup_led_single()
454 cdev->brightness_set_blocking = ktd202x_brightness_single_set; in ktd202x_setup_led_single()
455 cdev->blink_set = ktd202x_blink_single_set; in ktd202x_setup_led_single()
457 return devm_led_classdev_register_ext(chip->dev, &led->cdev, init_data); in ktd202x_setup_led_single()
460 static int ktd202x_add_led(struct ktd202x *chip, struct fwnode_handle *fwnode, unsigned int index) in ktd202x_add_led() argument
462 struct ktd202x_led *led = &chip->leds[index]; in ktd202x_add_led()
470 if (ret < 0 && ret != -EINVAL) { in ktd202x_add_led()
471 dev_err(chip->dev, "failed to parse 'color' of %pfw\n", fwnode); in ktd202x_add_led()
475 led->chip = chip; in ktd202x_add_led()
479 cdev = &led->mcdev.led_cdev; in ktd202x_add_led()
480 ret = ktd202x_setup_led_rgb(chip, fwnode, led, &init_data); in ktd202x_add_led()
482 cdev = &led->cdev; in ktd202x_add_led()
483 ret = ktd202x_setup_led_single(chip, fwnode, led, &init_data); in ktd202x_add_led()
487 dev_err(chip->dev, "unable to register %s\n", cdev->name); in ktd202x_add_led()
491 cdev->max_brightness = KTD202X_MAX_BRIGHTNESS; in ktd202x_add_led()
496 static int ktd202x_probe_fw(struct ktd202x *chip) in ktd202x_probe_fw() argument
499 struct device *dev = chip->dev; in ktd202x_probe_fw()
504 if (!count || count > chip->num_leds) in ktd202x_probe_fw()
505 return -EINVAL; in ktd202x_probe_fw()
507 regmap_write(chip->regmap, KTD202X_REG_RESET_CONTROL, KTD202X_RSTR_RESET); in ktd202x_probe_fw()
513 int ret = ktd202x_add_led(chip, child, i); in ktd202x_probe_fw()
536 struct device *dev = &client->dev; in ktd202x_probe()
537 struct ktd202x *chip; in ktd202x_probe() local
543 return dev_err_probe(dev, -EINVAL, "Incorrect number of leds (%d)", count); in ktd202x_probe()
545 chip = devm_kzalloc(dev, struct_size(chip, leds, count), GFP_KERNEL); in ktd202x_probe()
546 if (!chip) in ktd202x_probe()
547 return -ENOMEM; in ktd202x_probe()
549 chip->dev = dev; in ktd202x_probe()
550 i2c_set_clientdata(client, chip); in ktd202x_probe()
552 chip->regmap = devm_regmap_init_i2c(client, &ktd202x_regmap_config); in ktd202x_probe()
553 if (IS_ERR(chip->regmap)) { in ktd202x_probe()
554 ret = dev_err_probe(dev, PTR_ERR(chip->regmap), in ktd202x_probe()
559 ret = devm_mutex_init(dev, &chip->mutex); in ktd202x_probe()
563 chip->num_leds = (unsigned long)i2c_get_match_data(client); in ktd202x_probe()
565 chip->regulators[0].supply = "vin"; in ktd202x_probe()
566 chip->regulators[1].supply = "vio"; in ktd202x_probe()
567 ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(chip->regulators), chip->regulators); in ktd202x_probe()
573 ret = regulator_bulk_enable(ARRAY_SIZE(chip->regulators), chip->regulators); in ktd202x_probe()
579 ret = ktd202x_probe_fw(chip); in ktd202x_probe()
581 regulator_bulk_disable(ARRAY_SIZE(chip->regulators), chip->regulators); in ktd202x_probe()
585 ret = regulator_bulk_disable(ARRAY_SIZE(chip->regulators), chip->regulators); in ktd202x_probe()
596 struct ktd202x *chip = i2c_get_clientdata(client); in ktd202x_remove() local
598 ktd202x_chip_disable(chip); in ktd202x_remove()
603 struct ktd202x *chip = i2c_get_clientdata(client); in ktd202x_shutdown() local
606 regmap_write(chip->regmap, KTD202X_REG_RESET_CONTROL, KTD202X_RSTR_RESET); in ktd202x_shutdown()
625 .name = "leds-ktd202x",