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 device_node *np, in ktd202x_setup_led_rgb() argument
394 if (!num_channels || num_channels > chip->num_leds) in ktd202x_setup_led_rgb()
395 return -EINVAL; in ktd202x_setup_led_rgb()
397 info = devm_kcalloc(chip->dev, num_channels, sizeof(*info), GFP_KERNEL); in ktd202x_setup_led_rgb()
399 return -ENOMEM; in ktd202x_setup_led_rgb()
407 if (ret != 0 || reg >= chip->num_leds) { in ktd202x_setup_led_rgb()
408 dev_err(chip->dev, "invalid 'reg' of %pOFn\n", child); in ktd202x_setup_led_rgb()
410 return -EINVAL; in ktd202x_setup_led_rgb()
414 if (ret < 0 && ret != -EINVAL) { in ktd202x_setup_led_rgb()
415 dev_err(chip->dev, "failed to parse 'color' of %pOF\n", child); in ktd202x_setup_led_rgb()
426 led->mcdev.subled_info = info; in ktd202x_setup_led_rgb()
427 led->mcdev.num_colors = num_channels; in ktd202x_setup_led_rgb()
429 cdev = &led->mcdev.led_cdev; in ktd202x_setup_led_rgb()
430 cdev->brightness_set_blocking = ktd202x_brightness_mc_set; in ktd202x_setup_led_rgb()
431 cdev->blink_set = ktd202x_blink_mc_set; in ktd202x_setup_led_rgb()
433 return devm_led_classdev_multicolor_register_ext(chip->dev, &led->mcdev, init_data); in ktd202x_setup_led_rgb()
436 static int ktd202x_setup_led_single(struct ktd202x *chip, struct device_node *np, in ktd202x_setup_led_single() argument
444 if (ret != 0 || reg >= chip->num_leds) { in ktd202x_setup_led_single()
445 dev_err(chip->dev, "invalid 'reg' of %pOFn\n", np); in ktd202x_setup_led_single()
446 return -EINVAL; in ktd202x_setup_led_single()
448 led->index = reg; in ktd202x_setup_led_single()
450 cdev = &led->cdev; in ktd202x_setup_led_single()
451 cdev->brightness_set_blocking = ktd202x_brightness_single_set; in ktd202x_setup_led_single()
452 cdev->blink_set = ktd202x_blink_single_set; in ktd202x_setup_led_single()
454 return devm_led_classdev_register_ext(chip->dev, &led->cdev, init_data); in ktd202x_setup_led_single()
457 static int ktd202x_add_led(struct ktd202x *chip, struct device_node *np, unsigned int index) in ktd202x_add_led() argument
459 struct ktd202x_led *led = &chip->leds[index]; in ktd202x_add_led()
467 if (ret < 0 && ret != -EINVAL) { in ktd202x_add_led()
468 dev_err(chip->dev, "failed to parse 'color' of %pOF\n", np); in ktd202x_add_led()
472 led->chip = chip; in ktd202x_add_led()
476 cdev = &led->mcdev.led_cdev; in ktd202x_add_led()
477 ret = ktd202x_setup_led_rgb(chip, np, led, &init_data); in ktd202x_add_led()
479 cdev = &led->cdev; in ktd202x_add_led()
480 ret = ktd202x_setup_led_single(chip, np, led, &init_data); in ktd202x_add_led()
484 dev_err(chip->dev, "unable to register %s\n", cdev->name); in ktd202x_add_led()
488 cdev->max_brightness = KTD202X_MAX_BRIGHTNESS; in ktd202x_add_led()
493 static int ktd202x_probe_dt(struct ktd202x *chip) in ktd202x_probe_dt() argument
495 struct device_node *np = dev_of_node(chip->dev), *child; in ktd202x_probe_dt()
499 chip->num_leds = (int)(unsigned long)of_device_get_match_data(chip->dev); in ktd202x_probe_dt()
502 if (!count || count > chip->num_leds) in ktd202x_probe_dt()
503 return -EINVAL; in ktd202x_probe_dt()
505 regmap_write(chip->regmap, KTD202X_REG_RESET_CONTROL, KTD202X_RSTR_RESET); in ktd202x_probe_dt()
511 int ret = ktd202x_add_led(chip, child, i); in ktd202x_probe_dt()
534 struct device *dev = &client->dev; in ktd202x_probe()
535 struct ktd202x *chip; in ktd202x_probe() local
541 return dev_err_probe(dev, -EINVAL, "Incorrect number of leds (%d)", count); in ktd202x_probe()
543 chip = devm_kzalloc(dev, struct_size(chip, leds, count), GFP_KERNEL); in ktd202x_probe()
544 if (!chip) in ktd202x_probe()
545 return -ENOMEM; in ktd202x_probe()
547 chip->dev = dev; in ktd202x_probe()
548 i2c_set_clientdata(client, chip); in ktd202x_probe()
550 chip->regmap = devm_regmap_init_i2c(client, &ktd202x_regmap_config); in ktd202x_probe()
551 if (IS_ERR(chip->regmap)) { in ktd202x_probe()
552 ret = dev_err_probe(dev, PTR_ERR(chip->regmap), in ktd202x_probe()
557 chip->regulators[0].supply = "vin"; in ktd202x_probe()
558 chip->regulators[1].supply = "vio"; in ktd202x_probe()
559 ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(chip->regulators), chip->regulators); in ktd202x_probe()
565 ret = regulator_bulk_enable(ARRAY_SIZE(chip->regulators), chip->regulators); in ktd202x_probe()
571 ret = ktd202x_probe_dt(chip); in ktd202x_probe()
573 regulator_bulk_disable(ARRAY_SIZE(chip->regulators), chip->regulators); in ktd202x_probe()
577 ret = regulator_bulk_disable(ARRAY_SIZE(chip->regulators), chip->regulators); in ktd202x_probe()
583 mutex_init(&chip->mutex); in ktd202x_probe()
590 struct ktd202x *chip = i2c_get_clientdata(client); in ktd202x_remove() local
592 ktd202x_chip_disable(chip); in ktd202x_remove()
594 mutex_destroy(&chip->mutex); in ktd202x_remove()
599 struct ktd202x *chip = i2c_get_clientdata(client); in ktd202x_shutdown() local
602 regmap_write(chip->regmap, KTD202X_REG_RESET_CONTROL, KTD202X_RSTR_RESET); in ktd202x_shutdown()
614 .name = "leds-ktd202x",