Lines Matching +full:led +full:- +full:8

1 // SPDX-License-Identifier: GPL-2.0
2 // TI LP50XX LED chip family driver
3 // Copyright (C) 2018-20 Texas Instruments Incorporated - https://www.ti.com/
17 #include <linux/led-class-multicolor.h>
54 /* There are 3 LED outputs per bank */
60 #define LP5024_MAX_LED_MODULES 8
132 .reg_bits = 8,
133 .val_bits = 8,
142 .reg_bits = 8,
143 .val_bits = 8,
152 .reg_bits = 8,
153 .val_bits = 8,
171 * struct lp50xx_chip_info -
173 * @model_id: LED device model
174 * @max_modules: total number of supported LED modules
175 * @num_leds: number of LED outputs available on the device
271 * struct lp50xx -
273 * @regulator: LED supply regulator pointer
279 * @leds: array of LED strings
303 struct lp50xx_led *led = mcled_cdev_to_led(mc_dev); in lp50xx_brightness_set() local
304 const struct lp50xx_chip_info *led_chip = led->priv->chip_info; in lp50xx_brightness_set()
309 mutex_lock(&led->priv->lock); in lp50xx_brightness_set()
310 if (led->ctrl_bank_enabled) in lp50xx_brightness_set()
311 reg_val = led_chip->bank_brt_reg; in lp50xx_brightness_set()
313 reg_val = led_chip->led_brightness0_reg + in lp50xx_brightness_set()
314 led->led_number; in lp50xx_brightness_set()
316 ret = regmap_write(led->priv->regmap, reg_val, brightness); in lp50xx_brightness_set()
318 dev_err(led->priv->dev, in lp50xx_brightness_set()
323 for (i = 0; i < led->mc_cdev.num_colors; i++) { in lp50xx_brightness_set()
324 if (led->ctrl_bank_enabled) { in lp50xx_brightness_set()
325 reg_val = led_chip->bank_mix_reg + i; in lp50xx_brightness_set()
327 led_offset = (led->led_number * 3) + i; in lp50xx_brightness_set()
328 reg_val = led_chip->mix_out0_reg + led_offset; in lp50xx_brightness_set()
331 ret = regmap_write(led->priv->regmap, reg_val, in lp50xx_brightness_set()
332 mc_dev->subled_info[i].intensity); in lp50xx_brightness_set()
334 dev_err(led->priv->dev, in lp50xx_brightness_set()
340 mutex_unlock(&led->priv->lock); in lp50xx_brightness_set()
351 for (i = 0; i < priv->chip_info->max_modules; i++) { in lp50xx_set_banks()
357 led_config_hi = bank_enable_mask >> 8; in lp50xx_set_banks()
359 ret = regmap_write(priv->regmap, LP50XX_LED_CFG0, led_config_lo); in lp50xx_set_banks()
363 if (priv->chip_info->model_id >= LP5030) in lp50xx_set_banks()
364 ret = regmap_write(priv->regmap, LP5036_LED_CFG1, led_config_hi); in lp50xx_set_banks()
371 return regmap_write(priv->regmap, priv->chip_info->reset_reg, LP50XX_SW_RESET); in lp50xx_reset()
378 ret = gpiod_direction_output(priv->enable_gpio, enable_disable); in lp50xx_enable_disable()
383 return regmap_write(priv->regmap, LP50XX_DEV_CFG0, LP50XX_CHIP_EN); in lp50xx_enable_disable()
385 return regmap_write(priv->regmap, LP50XX_DEV_CFG0, 0); in lp50xx_enable_disable()
390 struct lp50xx_led *led, int num_leds) in lp50xx_probe_leds() argument
397 if (num_leds > priv->chip_info->max_modules) { in lp50xx_probe_leds()
398 dev_err(priv->dev, "reg property is invalid\n"); in lp50xx_probe_leds()
399 return -EINVAL; in lp50xx_probe_leds()
404 dev_err(priv->dev, "reg property is missing\n"); in lp50xx_probe_leds()
410 dev_err(priv->dev, "Cannot setup banked LEDs\n"); in lp50xx_probe_leds()
414 led->ctrl_bank_enabled = 1; in lp50xx_probe_leds()
418 dev_err(priv->dev, "led reg property missing\n"); in lp50xx_probe_leds()
422 if (led_number > priv->chip_info->num_leds) { in lp50xx_probe_leds()
423 dev_err(priv->dev, "led-sources property is invalid\n"); in lp50xx_probe_leds()
424 return -EINVAL; in lp50xx_probe_leds()
427 led->led_number = led_number; in lp50xx_probe_leds()
439 struct lp50xx_led *led; in lp50xx_probe_dt() local
440 int ret = -EINVAL; in lp50xx_probe_dt()
445 priv->enable_gpio = devm_gpiod_get_optional(priv->dev, "enable", GPIOD_OUT_LOW); in lp50xx_probe_dt()
446 if (IS_ERR(priv->enable_gpio)) in lp50xx_probe_dt()
447 return dev_err_probe(priv->dev, PTR_ERR(priv->enable_gpio), in lp50xx_probe_dt()
450 priv->regulator = devm_regulator_get(priv->dev, "vled"); in lp50xx_probe_dt()
451 if (IS_ERR(priv->regulator)) in lp50xx_probe_dt()
452 priv->regulator = NULL; in lp50xx_probe_dt()
454 device_for_each_child_node_scoped(priv->dev, child) { in lp50xx_probe_dt()
455 led = &priv->leds[i]; in lp50xx_probe_dt()
458 dev_err(priv->dev, "reg property is invalid\n"); in lp50xx_probe_dt()
462 ret = lp50xx_probe_leds(child, priv, led, ret); in lp50xx_probe_dt()
473 mc_led_info = devm_kcalloc(priv->dev, LP50XX_LEDS_PER_MODULE, in lp50xx_probe_dt()
476 return -ENOMEM; in lp50xx_probe_dt()
483 dev_err(priv->dev, "Cannot read color\n"); in lp50xx_probe_dt()
491 led->priv = priv; in lp50xx_probe_dt()
492 led->mc_cdev.num_colors = num_colors; in lp50xx_probe_dt()
493 led->mc_cdev.subled_info = mc_led_info; in lp50xx_probe_dt()
494 led_cdev = &led->mc_cdev.led_cdev; in lp50xx_probe_dt()
495 led_cdev->brightness_set_blocking = lp50xx_brightness_set; in lp50xx_probe_dt()
497 ret = devm_led_classdev_multicolor_register_ext(priv->dev, in lp50xx_probe_dt()
498 &led->mc_cdev, in lp50xx_probe_dt()
501 dev_err(priv->dev, "led register err: %d\n", ret); in lp50xx_probe_dt()
512 struct lp50xx *led; in lp50xx_probe() local
516 count = device_get_child_node_count(&client->dev); in lp50xx_probe()
518 dev_err(&client->dev, "LEDs are not defined in device tree!"); in lp50xx_probe()
519 return -ENODEV; in lp50xx_probe()
522 led = devm_kzalloc(&client->dev, struct_size(led, leds, count), in lp50xx_probe()
524 if (!led) in lp50xx_probe()
525 return -ENOMEM; in lp50xx_probe()
527 mutex_init(&led->lock); in lp50xx_probe()
528 led->client = client; in lp50xx_probe()
529 led->dev = &client->dev; in lp50xx_probe()
530 led->chip_info = device_get_match_data(&client->dev); in lp50xx_probe()
531 i2c_set_clientdata(client, led); in lp50xx_probe()
532 led->regmap = devm_regmap_init_i2c(client, in lp50xx_probe()
533 led->chip_info->lp50xx_regmap_config); in lp50xx_probe()
534 if (IS_ERR(led->regmap)) { in lp50xx_probe()
535 ret = PTR_ERR(led->regmap); in lp50xx_probe()
536 dev_err(&client->dev, "Failed to allocate register map: %d\n", in lp50xx_probe()
541 ret = lp50xx_reset(led); in lp50xx_probe()
545 ret = lp50xx_enable_disable(led, 1); in lp50xx_probe()
549 return lp50xx_probe_dt(led); in lp50xx_probe()
554 struct lp50xx *led = i2c_get_clientdata(client); in lp50xx_remove() local
557 ret = lp50xx_enable_disable(led, 0); in lp50xx_remove()
559 dev_err(led->dev, "Failed to disable chip\n"); in lp50xx_remove()
561 if (led->regulator) { in lp50xx_remove()
562 ret = regulator_disable(led->regulator); in lp50xx_remove()
564 dev_err(led->dev, "Failed to disable regulator\n"); in lp50xx_remove()
567 mutex_destroy(&led->lock); in lp50xx_remove()
603 MODULE_DESCRIPTION("Texas Instruments LP50XX LED driver");