Message ID | 20250610174319.183375-1-trannamatk@gmail.com |
---|---|
Headers | show |
Series | leds: add new LED driver for TI LP5812 | expand |
Please disregard the mistakenly sent patch named "[PATCH v5] test" — it was sent in error and is not part of this series. Apologies for the noise. -- Nam Tran
On 6/10/25 10:43 AM, Nam Tran wrote: > diff --git a/drivers/leds/rgb/Kconfig b/drivers/leds/rgb/Kconfig > index 222d943d826a..becee5c1d21c 100644 > --- a/drivers/leds/rgb/Kconfig > +++ b/drivers/leds/rgb/Kconfig > @@ -26,6 +26,19 @@ config LEDS_KTD202X > To compile this driver as a module, choose M here: the module > will be called leds-ktd202x. > > +config LEDS_LP5812 > + tristate "LED support for Texas Instruments LP5812" > + depends on I2C > + help > + If you say Y here you get support for TI LP5812 LED driver. > + The LP5812 is a 4 × 3 matrix RGB LED driver with autonomous The '×' character does not display well (not at all) in menuconfig or nconfig. The graphical configs (gconfig, xconfig) can display it. I would change it to 4x3 (letter 'x') but it's up to you. > + animation engine control. > + > + To compile this driver as a module, choose M here: the > + module will be called leds-lp5812. > + > + If unsure, say N.
Le 10/06/2025 à 19:43, Nam Tran a écrit : > The LP5812 is a 4×3 matrix RGB LED driver with an autonomous animation > engine and time-cross-multiplexing (TCM) support for up to 12 LEDs or > 4 RGB LEDs. Each LED can be configured through the related registers > to realize vivid and fancy lighting effects. Hi, ... > +static struct lp5812_data *lp5812_of_populate_pdata(struct device *dev, > + struct device_node *np, > + struct lp5812_chip *chip) > +{ > + struct device_node *child; > + struct lp5812_data *pdata; > + struct lp5812_led_config *cfg; > + int num_channels, i = 0, ret; > + > + pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); > + if (!pdata) > + return ERR_PTR(-ENOMEM); > + > + num_channels = of_get_available_child_count(np); > + if (num_channels == 0) { > + dev_err(dev, "no LED channels\n"); > + return ERR_PTR(-EINVAL); > + } > + > + cfg = devm_kcalloc(dev, num_channels, sizeof(*cfg), GFP_KERNEL); > + if (!cfg) > + return ERR_PTR(-ENOMEM); > + > + pdata->led_config = &cfg[0]; > + pdata->num_channels = num_channels; > + > + for_each_available_child_of_node(np, child) { Maybe for_each_available_child_of_node_scoped() to slihtly simplify the code? > + ret = lp5812_parse_logical_led(child, cfg, i); > + if (ret) { > + of_node_put(child); > + return ERR_PTR(-EINVAL); > + } > + i++; > + } > + > + of_property_read_string(np, "label", &pdata->label); > + > + return pdata; > +} ... > +static ssize_t lp5812_aeu_slope_time(struct device *dev, > + struct device_attribute *attr, > + enum slope_time_num slope_chan, > + const char *buf, size_t len) > +{ > + struct lp5812_led *led; > + struct lp5812_chip *chip; > + struct lp5812_led_config *led_cfg; > + const char *name = dev->platform_data; > + int val[LED_COLOR_ID_MAX]; > + u8 chan_nr = 0; > + char *sub_str, *str = (char *)buf; > + int i, ret, aeu; > + union slope_time slope_time_val; > + u16 reg; > + > + if (strcmp(name, LP5812_SC_LED) == 0) > + led = dev_to_lp5812_led(dev); > + else > + led = dev_to_lp5812_led_mc(dev); > + > + chan_nr = led->chan_nr; > + chip = led->chip; > + led_cfg = &chip->pdata->led_config[chan_nr]; > + > + sub_str = strsep(&str, ":"); > + if (!sub_str) > + return -EINVAL; > + if (kstrtoint(&sub_str[3], 0, &aeu)) > + return -EINVAL; > + > + pr_info("AEU = %d", aeu); > + > + guard(mutex)(&chip->lock); > + for (i = 0; i < led_cfg->num_colors; i++) { > + sub_str = strsep(&str, " "); > + if (!sub_str) > + return -EINVAL; > + if (kstrtoint(sub_str, 0, &val[i])) > + return -EINVAL; > + if (val[i] < 0 || val[i] > 15) > + return -EINVAL; > + > + reg = LP5812_AEU_SLOPE_TIME_ADDR(led_cfg->led_id[i], aeu, slope_chan); > + > + /* get original value of slope time */ > + ret = lp5812_read(chip, reg, &slope_time_val.time_val); > + if (ret) > + return ret; > + > + /* Update new value for slope time*/ > + if (slope_chan == LP5812_SLOPE_TIME_T1 || slope_chan == LP5812_SLOPE_TIME_T3) > + slope_time_val.s_time.first = val[i]; > + if (slope_chan == LP5812_SLOPE_TIME_T2 || slope_chan == LP5812_SLOPE_TIME_T4) > + slope_time_val.s_time.second = val[i]; > + > + /* Save updated value to hardware */ > + ret = lp5812_write(chip, reg, slope_time_val.time_val); Should we do something if ret != 0? > + } > + > + return len; > +} ... > +static struct attribute *lp5812_led_attrs[] = { > + &dev_attr_led_current.attr, > + &dev_attr_max_current.attr, > + &dev_attr_mode.attr, > + &dev_attr_activate.attr, > + &dev_attr_pwm_dimming_scale.attr, > + &dev_attr_pwm_phase_align.attr, > + &dev_attr_auto_time_pause_at_start.attr, > + &dev_attr_auto_time_pause_at_stop.attr, > + &dev_attr_auto_playback_eau_number.attr, > + &dev_attr_auto_playback_time.attr, > + &dev_attr_aeu_playback_time.attr, > + &dev_attr_aeu_pwm1.attr, > + &dev_attr_aeu_pwm2.attr, > + &dev_attr_aeu_pwm3.attr, > + &dev_attr_aeu_pwm4.attr, > + &dev_attr_aeu_pwm5.attr, > + &dev_attr_aeu_slop_time_t1.attr, > + &dev_attr_aeu_slop_time_t2.attr, > + &dev_attr_aeu_slop_time_t3.attr, > + &dev_attr_aeu_slop_time_t4.attr, > + &dev_attr_lod_lsd.attr, > + NULL, Unneeded trailing comma after a terminator. > +}; > +ATTRIBUTE_GROUPS(lp5812_led); ... > +static int lp5812_init_led(struct lp5812_led *led, struct lp5812_chip *chip, int chan) > +{ > + struct lp5812_data *pdata = chip->pdata; > + struct device *dev = &chip->i2c_cl->dev; > + struct mc_subled *mc_led_info; > + struct led_classdev *led_cdev; > + char name[32]; > + int i, ret = 0; > + > + if (pdata->led_config[chan].name) { > + led->cdev.name = pdata->led_config[chan].name; > + } else { > + snprintf(name, sizeof(name), "%s:channel%d", > + pdata->label ? : chip->i2c_cl->name, chan); > + led->cdev.name = name; Is it fine below when 'name' is defined on the stack and is used... > + } > + > + if (pdata->led_config[chan].is_sc_led == 0) { > + mc_led_info = devm_kcalloc(dev, > + pdata->led_config[chan].num_colors, > + sizeof(*mc_led_info), GFP_KERNEL); > + if (!mc_led_info) > + return -ENOMEM; > + > + led_cdev = &led->mc_cdev.led_cdev; > + led_cdev->name = led->cdev.name; ...here? > + led_cdev->brightness_set_blocking = lp5812_set_mc_brightness; > + led->mc_cdev.num_colors = pdata->led_config[chan].num_colors; > + for (i = 0; i < led->mc_cdev.num_colors; i++) { > + mc_led_info[i].color_index = > + pdata->led_config[chan].color_id[i]; > + mc_led_info[i].channel = > + pdata->led_config[chan].led_id[i]; > + } > + > + led->mc_cdev.subled_info = mc_led_info; > + } else { > + led->cdev.brightness_set_blocking = lp5812_set_brightness; > + } > + > + led->cdev.groups = lp5812_led_groups; > + led->chan_nr = chan; > + > + if (pdata->led_config[chan].is_sc_led) { > + ret = devm_led_classdev_register(dev, &led->cdev); > + if (ret == 0) { > + led->cdev.dev->platform_data = devm_kstrdup(dev, LP5812_SC_LED, GFP_KERNEL); > + if (!led->cdev.dev->platform_data) > + return -ENOMEM; > + } > + } else { > + ret = devm_led_classdev_multicolor_register(dev, &led->mc_cdev); > + if (ret == 0) { > + led->mc_cdev.led_cdev.dev->platform_data = > + devm_kstrdup(dev, LP5812_MC_LED, GFP_KERNEL); > + if (!led->mc_cdev.led_cdev.dev->platform_data) > + return -ENOMEM; > + > + ret = sysfs_create_groups(&led->mc_cdev.led_cdev.dev->kobj, > + lp5812_led_groups); > + if (ret) > + dev_err(dev, "sysfs_create_groups failed\n"); > + } > + } > + > + if (ret) { > + dev_err(dev, "led register err: %d\n", ret); > + return ret; > + } > + > + return 0; > +} ... CJ
On 10/06/2025 19:43, Nam Tran wrote: > This patch series adds support for the TI/National Semiconductor LP5812 > 4x3 matrix RGB LED driver. The driver supports features such as autonomous > animation and time-cross-multiplexing (TCM) for dynamic LED effects. > > Following feedback from both the LED and auxdisplay subsystem maintainers, > the driver has been moved back to the LED subsystem, under drivers/leds/rgb/. > This version integrates with the existing multicolor LED APIs, avoiding custom > sysfs where standard LED interfaces are sufficient. > > Signed-off-by: Nam Tran <trannamatk@gmail.com> > --- > Changes in v9: > - Move driver back to drivers/leds/rgb/ > - Integrate with LED multicolor framework > - Refactor and simplify custom sysfs handling > - Extend Device Tree binding to support multi-led@ nodes using leds-class-multicolor.yaml You need to provide reason why you dropped reviews. Best regards, Krzysztof
On Wed, Jun 11, 2025 at 12:43:15AM GMT, Nam Tran wrote: > +patternProperties: > + "^led@[0-3]$": > + type: object > + $ref: common.yaml# > + unevaluatedProperties: false > + > + properties: > + led-cur: > + $ref: /schemas/types.yaml#/definitions/uint8 > + description: | > + LED current in 0.1 mA steps (e.g., 150 = 15.0 mA; 0 if not connected) > + minimum: 0 > + maximum: 255 > + > + max-cur: > + $ref: /schemas/types.yaml#/definitions/uint8 > + description: Maximum allowed current in 0.1 mA steps > + > + reg: > + minimum: 0 > + maximum: 3 Place properties according to DTS coding style. > + > + '^multi-led@[4-7]$': > + type: object > + $ref: leds-class-multicolor.yaml# > + unevaluatedProperties: false > + > + properties: > + reg: > + minimum: 4 > + maximum: 7 > + > + '#address-cells': Don't mix quotes. Either ' or " > + const: 1 > + > + '#size-cells': > + const: 0 > + > + patternProperties: > + "^led@[4-9a-f]$": > + type: object > + $ref: common.yaml# > + unevaluatedProperties: false > + > + properties: > + led-cur: > + $ref: /schemas/types.yaml#/definitions/uint8 No, use existing led common properties. Also observe the units - this is not uint8 but a defined type for microamp, see property-units in dtschema. > + description: | > + LED current in 0.1 mA steps (e.g., 150 = 15.0 mA; 0 if not connected) > + minimum: 0 > + maximum: 255 > + > + max-cur: > + $ref: /schemas/types.yaml#/definitions/uint8 No, use existing led common properties. Same everywhere. > + description: Maximum allowed current in 0.1 mA steps > + > + reg: > + minimum: 4 > + maximum: 15 > + > + required: > + - reg > + > +required: > + - compatible > + - reg > + > +additionalProperties: false > + > +examples: > + - | > + #include <dt-bindings/leds/common.h> > + > + i2c { > + #address-cells = <1>; > + #size-cells = <0>; > + > + led-controller@1b { > + #address-cells = <1>; > + #size-cells = <0>; > + compatible = "ti,lp5812"; > + reg = <0x1b>; > + vcc-supply = <&vdd_3v3_reg>; > + > + led@0 { > + reg = <0x0>; Messed/mixed indentation. BTW, such significant binding change at v9, invalidting reviews and rewriting the binding completely, is surprising. Best regards, Krzysztof
On Wed, 11 Jun 2025, Krzysztof Kozlowski wrote: > On 10/06/2025 19:43, Nam Tran wrote: > > This patch series adds support for the TI/National Semiconductor LP5812 > > 4x3 matrix RGB LED driver. The driver supports features such as autonomous > > animation and time-cross-multiplexing (TCM) for dynamic LED effects. > > > > Following feedback from both the LED and auxdisplay subsystem maintainers, > > the driver has been moved back to the LED subsystem, under drivers/leds/rgb/. > > This version integrates with the existing multicolor LED APIs, avoiding custom > > sysfs where standard LED interfaces are sufficient. > > > > Signed-off-by: Nam Tran <trannamatk@gmail.com> > > --- > > Changes in v9: > > - Move driver back to drivers/leds/rgb/ > > - Integrate with LED multicolor framework > > - Refactor and simplify custom sysfs handling > > - Extend Device Tree binding to support multi-led@ nodes using leds-class-multicolor.yaml > > You need to provide reason why you dropped reviews. In v9, the Device Tree binding was restructured to integrate with the standard leds-class-multicolor.yaml schema and support multi-led@ nodes with nested led@ subnodes. This change introduced a new patternProperties hierarchy and removed the previous flat led@ layout used in the earlier versions. Due to this substantial structural change — even though the intent and top-level properties remained similar — I decided to drop the Reviewed-by tag to avoid misrepresenting prior review coverage. I will include this explanation in the changelog of the next version (v10). Best regards, Nam Tran
On Wed, 11 Jun 2025, Krzysztof Kozlowski wrote: > > +patternProperties: > > + "^led@[0-3]$": > > + type: object > > + $ref: common.yaml# > > + unevaluatedProperties: false > > + > > + properties: > > + led-cur: > > + $ref: /schemas/types.yaml#/definitions/uint8 > > + description: | > > + LED current in 0.1 mA steps (e.g., 150 = 15.0 mA; 0 if not connected) > > + minimum: 0 > > + maximum: 255 > > + > > + max-cur: > > + $ref: /schemas/types.yaml#/definitions/uint8 > > + description: Maximum allowed current in 0.1 mA steps > > + > > + reg: > > + minimum: 0 > > + maximum: 3 > > Place properties according to DTS coding style. Got it! I'll update the property order accordingly. > > + '^multi-led@[4-7]$': > > + type: object > > + $ref: leds-class-multicolor.yaml# > > + unevaluatedProperties: false > > + > > + properties: > > + reg: > > + minimum: 4 > > + maximum: 7 > > + > > + '#address-cells': > > Don't mix quotes. Either ' or " I'll use consistent ". > > + const: 1 > > + > > + '#size-cells': > > + const: 0 > > + > > + patternProperties: > > + "^led@[4-9a-f]$": > > + type: object > > + $ref: common.yaml# > > + unevaluatedProperties: false > > + > > + properties: > > + led-cur: > > + $ref: /schemas/types.yaml#/definitions/uint8 > > No, use existing led common properties. Also observe the units - this is > not uint8 but a defined type for microamp, see property-units in > dtschema. > > > + description: | > > + LED current in 0.1 mA steps (e.g., 150 = 15.0 mA; 0 if not connected) > > + minimum: 0 > > + maximum: 255 > > + > > + max-cur: > > + $ref: /schemas/types.yaml#/definitions/uint8 > > No, use existing led common properties. Same everywhere. I'll replace max-cur with the standard led-max-microamp. I'll remove led-cur as there's no equivalent LED common property to represent it. The LED current can be configured runtime via the led_current sysfs. > > +examples: > > + - | > > + #include <dt-bindings/leds/common.h> > > + > > + i2c { > > + #address-cells = <1>; > > + #size-cells = <0>; > > + > > + led-controller@1b { > > + #address-cells = <1>; > > + #size-cells = <0>; > > + compatible = "ti,lp5812"; > > + reg = <0x1b>; > > + vcc-supply = <&vdd_3v3_reg>; > > + > > + led@0 { > > + reg = <0x0>; > > > Messed/mixed indentation. I'll fix it. > BTW, such significant binding change at v9, invalidting reviews and > rewriting the binding completely, is surprising. Understood. I restructured the binding in v9 to align with leds-class-multicolor.yaml and better represent the LP5812 hierarchy. I'll make sure to highlight such major changes more clearly in future revisions. Appreciate your time and feedback. Best regards, Nam Tran
On Tue, 10 Jun 2025, Christophe JAILLET wrote: > > +static struct lp5812_data *lp5812_of_populate_pdata(struct device *dev, > > + struct device_node *np, > > + struct lp5812_chip *chip) > > +{ > > + struct device_node *child; > > + struct lp5812_data *pdata; > > + struct lp5812_led_config *cfg; > > + int num_channels, i = 0, ret; > > + > > + pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); > > + if (!pdata) > > + return ERR_PTR(-ENOMEM); > > + > > + num_channels = of_get_available_child_count(np); > > + if (num_channels == 0) { > > + dev_err(dev, "no LED channels\n"); > > + return ERR_PTR(-EINVAL); > > + } > > + > > + cfg = devm_kcalloc(dev, num_channels, sizeof(*cfg), GFP_KERNEL); > > + if (!cfg) > > + return ERR_PTR(-ENOMEM); > > + > > + pdata->led_config = &cfg[0]; > > + pdata->num_channels = num_channels; > > + > > + for_each_available_child_of_node(np, child) { > > Maybe for_each_available_child_of_node_scoped() to slihtly simplify the > code? Thanks, I'll switch to for_each_available_child_of_node_scoped(). > > +static ssize_t lp5812_aeu_slope_time(struct device *dev, > > + struct device_attribute *attr, > > + enum slope_time_num slope_chan, > > + const char *buf, size_t len) > > +{ > > + struct lp5812_led *led; > > + struct lp5812_chip *chip; > > + struct lp5812_led_config *led_cfg; > > + const char *name = dev->platform_data; > > + int val[LED_COLOR_ID_MAX]; > > + u8 chan_nr = 0; > > + char *sub_str, *str = (char *)buf; > > + int i, ret, aeu; > > + union slope_time slope_time_val; > > + u16 reg; > > + > > + if (strcmp(name, LP5812_SC_LED) == 0) > > + led = dev_to_lp5812_led(dev); > > + else > > + led = dev_to_lp5812_led_mc(dev); > > + > > + chan_nr = led->chan_nr; > > + chip = led->chip; > > + led_cfg = &chip->pdata->led_config[chan_nr]; > > + > > + sub_str = strsep(&str, ":"); > > + if (!sub_str) > > + return -EINVAL; > > + if (kstrtoint(&sub_str[3], 0, &aeu)) > > + return -EINVAL; > > + > > + pr_info("AEU = %d", aeu); > > + > > + guard(mutex)(&chip->lock); > > + for (i = 0; i < led_cfg->num_colors; i++) { > > + sub_str = strsep(&str, " "); > > + if (!sub_str) > > + return -EINVAL; > > + if (kstrtoint(sub_str, 0, &val[i])) > > + return -EINVAL; > > + if (val[i] < 0 || val[i] > 15) > > + return -EINVAL; > > + > > + reg = LP5812_AEU_SLOPE_TIME_ADDR(led_cfg->led_id[i], aeu, slope_chan); > > + > > + /* get original value of slope time */ > > + ret = lp5812_read(chip, reg, &slope_time_val.time_val); > > + if (ret) > > + return ret; > > + > > + /* Update new value for slope time*/ > > + if (slope_chan == LP5812_SLOPE_TIME_T1 || slope_chan == LP5812_SLOPE_TIME_T3) > > + slope_time_val.s_time.first = val[i]; > > + if (slope_chan == LP5812_SLOPE_TIME_T2 || slope_chan == LP5812_SLOPE_TIME_T4) > > + slope_time_val.s_time.second = val[i]; > > + > > + /* Save updated value to hardware */ > > + ret = lp5812_write(chip, reg, slope_time_val.time_val); > > Should we do something if ret != 0? Yes. I'll add a return check to handle possible write errors. > > +static struct attribute *lp5812_led_attrs[] = { > > + &dev_attr_led_current.attr, > > + &dev_attr_max_current.attr, > > + &dev_attr_mode.attr, > > + &dev_attr_activate.attr, > > + &dev_attr_pwm_dimming_scale.attr, > > + &dev_attr_pwm_phase_align.attr, > > + &dev_attr_auto_time_pause_at_start.attr, > > + &dev_attr_auto_time_pause_at_stop.attr, > > + &dev_attr_auto_playback_eau_number.attr, > > + &dev_attr_auto_playback_time.attr, > > + &dev_attr_aeu_playback_time.attr, > > + &dev_attr_aeu_pwm1.attr, > > + &dev_attr_aeu_pwm2.attr, > > + &dev_attr_aeu_pwm3.attr, > > + &dev_attr_aeu_pwm4.attr, > > + &dev_attr_aeu_pwm5.attr, > > + &dev_attr_aeu_slop_time_t1.attr, > > + &dev_attr_aeu_slop_time_t2.attr, > > + &dev_attr_aeu_slop_time_t3.attr, > > + &dev_attr_aeu_slop_time_t4.attr, > > + &dev_attr_lod_lsd.attr, > > + NULL, > > Unneeded trailing comma after a terminator. I'll remove it. > > +static int lp5812_init_led(struct lp5812_led *led, struct lp5812_chip *chip, int chan) > > +{ > > + struct lp5812_data *pdata = chip->pdata; > > + struct device *dev = &chip->i2c_cl->dev; > > + struct mc_subled *mc_led_info; > > + struct led_classdev *led_cdev; > > + char name[32]; > > + int i, ret = 0; > > + > > + if (pdata->led_config[chan].name) { > > + led->cdev.name = pdata->led_config[chan].name; > > + } else { > > + snprintf(name, sizeof(name), "%s:channel%d", > > + pdata->label ? : chip->i2c_cl->name, chan); > > + led->cdev.name = name; > > Is it fine below when 'name' is defined on the stack and is used... > > > + } > > + > > + if (pdata->led_config[chan].is_sc_led == 0) { > > + mc_led_info = devm_kcalloc(dev, > > + pdata->led_config[chan].num_colors, > > + sizeof(*mc_led_info), GFP_KERNEL); > > + if (!mc_led_info) > > + return -ENOMEM; > > + > > + led_cdev = &led->mc_cdev.led_cdev; > > + led_cdev->name = led->cdev.name; > > ...here? You're right, name was stack-allocated and unsafe to use after the function returns. I'll replace it with a devm_kasprintf() allocation. Appreciate your time and feedback. Best regards, Nam Tran
This patch series adds support for the TI/National Semiconductor LP5812 4x3 matrix RGB LED driver. The driver supports features such as autonomous animation and time-cross-multiplexing (TCM) for dynamic LED effects. Following feedback from both the LED and auxdisplay subsystem maintainers, the driver has been moved back to the LED subsystem, under drivers/leds/rgb/. This version integrates with the existing multicolor LED APIs, avoiding custom sysfs where standard LED interfaces are sufficient. Signed-off-by: Nam Tran <trannamatk@gmail.com> --- Changes in v9: - Move driver back to drivers/leds/rgb/ - Integrate with LED multicolor framework - Refactor and simplify custom sysfs handling - Extend Device Tree binding to support multi-led@ nodes using leds-class-multicolor.yaml - Update documentation to reflect the updated sysfs - Link to v8: https://lore.kernel.org/lkml/20250427082447.138359-1-trannamatk@gmail.com/ Changes in v8: - Move driver to drivers/auxdisplay/ instead of drivers/leds/. - Rename files from leds-lp5812.c/.h to lp5812.c/.h. - Move ti,lp5812.yaml binding to auxdisplay/ directory, and update the title and $id to match new path. - No functional changes to the binding itself (keep Reviewed-by). - Update commit messages and patch titles to reflect the move. - Link to v7: https://lore.kernel.org/linux-leds/20250422190121.46839-1-trannamatk@gmail.com/ Changes in v7: - Mark `chip_leds_map` as const. - Use consistent `ret` initialization. - Simplify the function `set_mix_sel_led()`. - Refactor `dev_config_show()` and `led_auto_animation_show()` to avoid temp buffer, malloc/free. - Simplify the code and ensure consistent use of mutex lock/unlock in show/store functions. - Remove `total_leds` and `total_aeu`. - Link to v6: https://lore.kernel.org/linux-leds/20250419184333.56617-1-trannamatk@gmail.com/ Changes in v6: - Add `vcc-supply` property to describe the LP5812 power supply. - Remove `chan-name` property and entire LED subnodes, as they are not needed. - Update LP5812 LED driver node to Raspberry Pi 4 B Device Tree, based on updated binding. - Link to v5: https://lore.kernel.org/linux-leds/20250414145742.35713-1-trannamatk@gmail.com/ Changes in v5: - Rebase on v6.15-rc2 - Removed unused functions (lp5812_dump_regs, lp5812_update_bit). - Address Krzysztof's review comments - Link to v4: https://lore.kernel.org/linux-leds/20250405183246.198568-1-trannamatk@gmail.com/ --- Nam Tran (4): dt-bindings: leds: add TI/National Semiconductor LP5812 LED Driver leds: add TI/National Semiconductor LP5812 LED Driver docs: ABI: Document LP5812 LED sysfs interfaces docs: leds: Document TI LP5812 LED driver .../ABI/testing/sysfs-bus-i2c-devices-lp5812 | 40 + .../ABI/testing/sysfs-class-led-lp5812 | 120 + .../devicetree/bindings/leds/ti,lp5812.yaml | 264 +++ Documentation/leds/index.rst | 1 + Documentation/leds/leds-lp5812.rst | 84 + MAINTAINERS | 13 + drivers/leds/rgb/Kconfig | 13 + drivers/leds/rgb/Makefile | 1 + drivers/leds/rgb/leds-lp5812.c | 1946 +++++++++++++++++ drivers/leds/rgb/leds-lp5812.h | 228 ++ 10 files changed, 2710 insertions(+) create mode 100644 Documentation/ABI/testing/sysfs-bus-i2c-devices-lp5812 create mode 100644 Documentation/ABI/testing/sysfs-class-led-lp5812 create mode 100644 Documentation/devicetree/bindings/leds/ti,lp5812.yaml create mode 100644 Documentation/leds/leds-lp5812.rst create mode 100644 drivers/leds/rgb/leds-lp5812.c create mode 100644 drivers/leds/rgb/leds-lp5812.h base-commit: f09079bd04a924c72d555cd97942d5f8d7eca98c