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/
18 #include <linux/led-class-multicolor.h>
57 /* There are 3 LED outputs per bank */
63 #define LP5024_MAX_LED_MODULES 8
135 .reg_bits = 8,
136 .val_bits = 8,
145 .reg_bits = 8,
146 .val_bits = 8,
155 .reg_bits = 8,
156 .val_bits = 8,
174 * struct lp50xx_chip_info -
176 * @model_id: LED device model
177 * @max_modules: total number of supported LED modules
178 * @num_leds: number of LED outputs available on the device
276 * struct lp50xx -
278 * @regulator: LED supply regulator pointer
285 * @leds: array of LED strings
310 struct lp50xx_led *led = mcled_cdev_to_led(mc_dev); in lp50xx_brightness_set() local
311 const struct lp50xx_chip_info *led_chip = led->priv->chip_info; in lp50xx_brightness_set()
316 mutex_lock(&led->priv->lock); in lp50xx_brightness_set()
317 if (led->ctrl_bank_enabled) in lp50xx_brightness_set()
318 reg_val = led_chip->bank_brt_reg; in lp50xx_brightness_set()
320 reg_val = led_chip->led_brightness0_reg + in lp50xx_brightness_set()
321 led->led_number; in lp50xx_brightness_set()
323 ret = regmap_write(led->priv->regmap, reg_val, brightness); in lp50xx_brightness_set()
325 dev_err(&led->priv->client->dev, in lp50xx_brightness_set()
330 for (i = 0; i < led->mc_cdev.num_colors; i++) { in lp50xx_brightness_set()
331 if (led->ctrl_bank_enabled) { in lp50xx_brightness_set()
332 reg_val = led_chip->bank_mix_reg + i; in lp50xx_brightness_set()
334 led_offset = (led->led_number * 3) + i; in lp50xx_brightness_set()
335 reg_val = led_chip->mix_out0_reg + led_offset; in lp50xx_brightness_set()
338 ret = regmap_write(led->priv->regmap, reg_val, in lp50xx_brightness_set()
339 mc_dev->subled_info[i].intensity); in lp50xx_brightness_set()
341 dev_err(&led->priv->client->dev, in lp50xx_brightness_set()
347 mutex_unlock(&led->priv->lock); in lp50xx_brightness_set()
358 for (i = 0; i < priv->chip_info->max_modules; i++) { in lp50xx_set_banks()
364 led_config_hi = (u8)(bank_enable_mask >> 8) & 0xff; in lp50xx_set_banks()
366 ret = regmap_write(priv->regmap, LP50XX_LED_CFG0, led_config_lo); in lp50xx_set_banks()
370 if (priv->chip_info->model_id >= LP5030) in lp50xx_set_banks()
371 ret = regmap_write(priv->regmap, LP5036_LED_CFG1, led_config_hi); in lp50xx_set_banks()
378 return regmap_write(priv->regmap, priv->chip_info->reset_reg, LP50XX_SW_RESET); in lp50xx_reset()
385 if (priv->enable_gpio) { in lp50xx_enable_disable()
386 ret = gpiod_direction_output(priv->enable_gpio, enable_disable); in lp50xx_enable_disable()
392 return regmap_write(priv->regmap, LP50XX_DEV_CFG0, LP50XX_CHIP_EN); in lp50xx_enable_disable()
394 return regmap_write(priv->regmap, LP50XX_DEV_CFG0, 0); in lp50xx_enable_disable()
399 struct lp50xx_led *led, int num_leds) in lp50xx_probe_leds() argument
406 if (num_leds > priv->chip_info->max_modules) { in lp50xx_probe_leds()
407 dev_err(&priv->client->dev, "reg property is invalid\n"); in lp50xx_probe_leds()
408 return -EINVAL; in lp50xx_probe_leds()
411 priv->num_of_banked_leds = num_leds; in lp50xx_probe_leds()
415 dev_err(&priv->client->dev, "reg property is missing\n"); in lp50xx_probe_leds()
421 dev_err(&priv->client->dev, "Cannot setup banked LEDs\n"); in lp50xx_probe_leds()
425 led->ctrl_bank_enabled = 1; in lp50xx_probe_leds()
429 dev_err(&priv->client->dev, "led reg property missing\n"); in lp50xx_probe_leds()
433 if (led_number > priv->chip_info->num_leds) { in lp50xx_probe_leds()
434 dev_err(&priv->client->dev, "led-sources property is invalid\n"); in lp50xx_probe_leds()
435 return -EINVAL; in lp50xx_probe_leds()
438 led->led_number = led_number; in lp50xx_probe_leds()
451 struct lp50xx_led *led; in lp50xx_probe_dt() local
452 int ret = -EINVAL; in lp50xx_probe_dt()
457 priv->enable_gpio = devm_gpiod_get_optional(priv->dev, "enable", GPIOD_OUT_LOW); in lp50xx_probe_dt()
458 if (IS_ERR(priv->enable_gpio)) { in lp50xx_probe_dt()
459 ret = PTR_ERR(priv->enable_gpio); in lp50xx_probe_dt()
460 dev_err(&priv->client->dev, "Failed to get enable gpio: %d\n", in lp50xx_probe_dt()
465 priv->regulator = devm_regulator_get(priv->dev, "vled"); in lp50xx_probe_dt()
466 if (IS_ERR(priv->regulator)) in lp50xx_probe_dt()
467 priv->regulator = NULL; in lp50xx_probe_dt()
469 device_for_each_child_node(priv->dev, child) { in lp50xx_probe_dt()
470 led = &priv->leds[i]; in lp50xx_probe_dt()
473 dev_err(&priv->client->dev, "reg property is invalid\n"); in lp50xx_probe_dt()
477 ret = lp50xx_probe_leds(child, priv, led, ret); in lp50xx_probe_dt()
488 mc_led_info = devm_kcalloc(priv->dev, LP50XX_LEDS_PER_MODULE, in lp50xx_probe_dt()
491 return -ENOMEM; in lp50xx_probe_dt()
497 dev_err(priv->dev, "Cannot read color\n"); in lp50xx_probe_dt()
505 led->priv = priv; in lp50xx_probe_dt()
506 led->mc_cdev.num_colors = num_colors; in lp50xx_probe_dt()
507 led->mc_cdev.subled_info = mc_led_info; in lp50xx_probe_dt()
508 led_cdev = &led->mc_cdev.led_cdev; in lp50xx_probe_dt()
509 led_cdev->brightness_set_blocking = lp50xx_brightness_set; in lp50xx_probe_dt()
511 ret = devm_led_classdev_multicolor_register_ext(&priv->client->dev, in lp50xx_probe_dt()
512 &led->mc_cdev, in lp50xx_probe_dt()
515 dev_err(&priv->client->dev, "led register err: %d\n", in lp50xx_probe_dt()
533 struct lp50xx *led; in lp50xx_probe() local
537 count = device_get_child_node_count(&client->dev); in lp50xx_probe()
539 dev_err(&client->dev, "LEDs are not defined in device tree!"); in lp50xx_probe()
540 return -ENODEV; in lp50xx_probe()
543 led = devm_kzalloc(&client->dev, struct_size(led, leds, count), in lp50xx_probe()
545 if (!led) in lp50xx_probe()
546 return -ENOMEM; in lp50xx_probe()
548 mutex_init(&led->lock); in lp50xx_probe()
549 led->client = client; in lp50xx_probe()
550 led->dev = &client->dev; in lp50xx_probe()
551 led->chip_info = &lp50xx_chip_info_tbl[id->driver_data]; in lp50xx_probe()
552 i2c_set_clientdata(client, led); in lp50xx_probe()
553 led->regmap = devm_regmap_init_i2c(client, in lp50xx_probe()
554 led->chip_info->lp50xx_regmap_config); in lp50xx_probe()
555 if (IS_ERR(led->regmap)) { in lp50xx_probe()
556 ret = PTR_ERR(led->regmap); in lp50xx_probe()
557 dev_err(&client->dev, "Failed to allocate register map: %d\n", in lp50xx_probe()
562 ret = lp50xx_reset(led); in lp50xx_probe()
566 ret = lp50xx_enable_disable(led, 1); in lp50xx_probe()
570 return lp50xx_probe_dt(led); in lp50xx_probe()
575 struct lp50xx *led = i2c_get_clientdata(client); in lp50xx_remove() local
578 ret = lp50xx_enable_disable(led, 0); in lp50xx_remove()
580 dev_err(&led->client->dev, "Failed to disable chip\n"); in lp50xx_remove()
584 if (led->regulator) { in lp50xx_remove()
585 ret = regulator_disable(led->regulator); in lp50xx_remove()
587 dev_err(&led->client->dev, in lp50xx_remove()
591 mutex_destroy(&led->lock); in lp50xx_remove()
629 MODULE_DESCRIPTION("Texas Instruments LP50XX LED driver");