* [PATCH v8 0/2] Add support for LTC3208 multi-display driver
@ 2026-07-29 23:14 Jan Carlo Roleda
2026-07-29 23:14 ` [PATCH v8 1/2] dt-bindings: leds: Document LTC3208 Multidisplay LED Driver Jan Carlo Roleda
2026-07-29 23:14 ` [PATCH v8 2/2] leds: ltc3208: Add driver for " Jan Carlo Roleda
0 siblings, 2 replies; 5+ messages in thread
From: Jan Carlo Roleda @ 2026-07-29 23:14 UTC (permalink / raw)
To: Lee Jones, Pavel Machek, Rob Herring, Krzysztof Kozlowski,
Conor Dooley
Cc: linux-kernel, linux-leds, devicetree, Uwe Kleine-König,
Jan Carlo Roleda, Krzysztof Kozlowski
The LTC3208 is a multi-display LED driver, using a high-efficiency, low
noise charge pump to provide power to 5 channels (MAIN, SUB, RGB, CAM,
AUX). Current for each LED is controlled by the I2C serial interface.
Four AUX current sources can be independently assigned via the I2C port
to the CAM, SUB, MAIN, or AUX DAC controlled displays
Signed-off-by: Jan Carlo Roleda <jancarlo.roleda@analog.com>
---
Changes in v8:
- Adjusted register define comments and formatting
- Adjusted aux channel string declaration formatting.
- Removed I2C client from ltc3208_led.
- Replaced struct ltc3208 with a bitmap to validate unique channel
registration in probe.
- Replaced ltc3208 kzalloc with individual ltc3208_led kzalloc in probe.
- Added spacing to each bracketed item.
- Adjusted formatting of reg_field declaration.
- Replaced reg_val with dev_options name in probe.
- Adjusted error messages to be more descriptive.
- Removed newlines from error messages.
- Refactored AUX channel configuration to be more readable.
- Removed id_table from i2c_driver initialization.
- Link to v7: https://lore.kernel.org/r/20260708-upstream-ltc3208-v7-0-aed7f7bd461c@analog.com
Changes in v7:
- added reg_defaults to regmap_config
- removed i2c_client and regmap from ltc3208 struct data
- fixed typo comment in driver commit description
- fixed string formatting of u32 chan data in probe
- added explicit CPO set to 0 in probe
- Link to v6: https://lore.kernel.org/r/20260623-upstream-ltc3208-v6-0-fc6bd9749166@analog.com
Changes in v6:
- Fixed code conventions (spaces in brackets, awkward line breaks)
- Removed unused `i2c_set_clientdata` from probe function
- Added guard for potential errors in AUX channel configurations
- Added guards to prevent duplicate LED registrations to the same ID
- Corrected `dev_err_probe` return values
- Link to v5: https://lore.kernel.org/r/20260619-upstream-ltc3208-v5-0-075d18060606@analog.com
Changes in v5:
- Fixed MAINTAINERS commit ordering
- removed i2c_client from ltc3208_dev
- renamed ltc3208_dev struct to ltc3208
- refactored brightness_set function to use regmap_field
- updated leds attribute to use constant size array
- updated regmap_config to use REGCACHE_FLAT_S cache type
- added max_register to regmap_config
- renamed variables in probe function
- renamed map to regmap for regmap instances
- moved AUX channel configuration inline to probe
- Link to v4: https://lore.kernel.org/r/20260416-upstream-ltc3208-v4-0-3884ed3e49f5@analog.com
Changes in v4:
- Reordered commit order to match dependency order
- Updated Kconfig to be more descriptive of device
- Added led@0-7 with more complete example properties (function and
color)
- Driver changes:
-- Removed unnecessary include headers
-- Formatted macros
-- Created helper `write_current_level` functions for LED current
configuration, using `regmap_update_bits()`
-- Adjusted awkward tabbing issues
-- Updated variable names in probe to be more descriptive
-- Updated inline comment capitalization
-- Initialized `i` within the for loop in AUX configuration in probe
-- Refactored `update_aux_dac` function to use array pointer
-- Fixed error messages in probe
- Link to v3: https://lore.kernel.org/r/20260406-upstream-ltc3208-v3-0-7f0b1d20ee7a@analog.com
Changes in v3:
- Edited device bindings descriptions
-- removed full stop in title
-- replaced quotes with double quotes for consistency
-- removed <dt-bindings/gpio/gpio.h> from example
-- removed led1-7 in example for brevity
- squashed maintainers commit to driver commit
- Link to v2: https://lore.kernel.org/r/20260326-upstream-ltc3208-v2-0-3dbc992b6098@analog.com
Changes in v2:
- Addressed DTSchema bot warnings and errors
-- removed extra blank lines
-- fixed $id to match current naming
- Addressed Kernel test warnings
-- fixed bounds for aux channel configurations
- Link to v0: https://lore.kernel.org/r/20260318-upstream-ltc3208-v1-0-015f1f1e9065@analog.com
---
Jan Carlo Roleda (2):
dt-bindings: leds: Document LTC3208 Multidisplay LED Driver
leds: ltc3208: Add driver for LTC3208 Multidisplay LED Driver
.../devicetree/bindings/leds/adi,ltc3208.yaml | 181 +++++++++++++++++
MAINTAINERS | 8 +
drivers/leds/Kconfig | 12 ++
drivers/leds/Makefile | 1 +
drivers/leds/leds-ltc3208.c | 226 +++++++++++++++++++++
5 files changed, 428 insertions(+)
---
base-commit: d43f1d792902ba0a53fd311bff2cf96095c7606d
change-id: 20260318-upstream-ltc3208-7cc8968bf69e
Best regards,
--
Jan Carlo Roleda <jancarlo.roleda@analog.com>
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v8 1/2] dt-bindings: leds: Document LTC3208 Multidisplay LED Driver
2026-07-29 23:14 [PATCH v8 0/2] Add support for LTC3208 multi-display driver Jan Carlo Roleda
@ 2026-07-29 23:14 ` Jan Carlo Roleda
2026-07-29 23:20 ` sashiko-bot
2026-07-29 23:14 ` [PATCH v8 2/2] leds: ltc3208: Add driver for " Jan Carlo Roleda
1 sibling, 1 reply; 5+ messages in thread
From: Jan Carlo Roleda @ 2026-07-29 23:14 UTC (permalink / raw)
To: Lee Jones, Pavel Machek, Rob Herring, Krzysztof Kozlowski,
Conor Dooley
Cc: linux-kernel, linux-leds, devicetree, Uwe Kleine-König,
Jan Carlo Roleda, Krzysztof Kozlowski
Add Devicetree Documentation for LTC3208 Multidisplay LED Driver.
Signed-off-by: Jan Carlo Roleda <jancarlo.roleda@analog.com>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
---
.../devicetree/bindings/leds/adi,ltc3208.yaml | 181 +++++++++++++++++++++
MAINTAINERS | 7 +
2 files changed, 188 insertions(+)
diff --git a/Documentation/devicetree/bindings/leds/adi,ltc3208.yaml b/Documentation/devicetree/bindings/leds/adi,ltc3208.yaml
new file mode 100644
index 000000000000..0a01e07e0ab7
--- /dev/null
+++ b/Documentation/devicetree/bindings/leds/adi,ltc3208.yaml
@@ -0,0 +1,181 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+# Copyright (c) 2026 Analog Devices, Inc.
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/leds/adi,ltc3208.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: LTC3208 Multidisplay LED Controller from Linear Technologies (Now Analog Devices)
+
+maintainers:
+ - Jan Carlo Roleda <jancarlo.roleda@analog.com>
+
+description:
+ The LTC3208 is a multidisplay LED controller that can support up to 1A to all
+ connected LEDs.
+
+ The datasheet for this device can be found in
+ https://www.analog.com/en/products/ltc3208.html
+
+properties:
+ compatible:
+ const: adi,ltc3208
+
+ reg:
+ maxItems: 1
+
+ "#address-cells":
+ const: 1
+
+ "#size-cells":
+ const: 0
+
+ adi,disable-camhl-pin:
+ type: boolean
+ description:
+ Configures whether the external CAMHL pin is disabled.
+ If disabled then the output pins associated with CAM will always select
+ the CAM register's high half-byte brightness.
+
+ adi,cfg-enrgbs-pin:
+ type: boolean
+ description:
+ Configures which channel the ENRGBS pin toggles when it receives a signal.
+ ENRGBS pin controls the SUB channel's output pins if this is set,
+ or RGB channel's output pins if this is unset.
+
+ adi,disable-rgb-aux4-dropout:
+ type: boolean
+ description:
+ Configures the RGB and AUX4 dropout signals to be disabled.
+
+ adi,aux1-channel:
+ $ref: /schemas/types.yaml#/definitions/string
+ description:
+ LED Channel that the AUX1 output pin mirrors its brightness level from.
+ enum: [aux, main, sub, cam]
+ default: aux
+
+ adi,aux2-channel:
+ $ref: /schemas/types.yaml#/definitions/string
+ description:
+ LED Channel that the AUX2 output pin mirrors its brightness level from.
+ enum: [aux, main, sub, cam]
+ default: aux
+
+ adi,aux3-channel:
+ $ref: /schemas/types.yaml#/definitions/string
+ description:
+ LED Channel that the AUX3 output pin mirrors its brightness level from.
+ enum: [aux, main, sub, cam]
+ default: aux
+
+ adi,aux4-channel:
+ $ref: /schemas/types.yaml#/definitions/string
+ description:
+ LED Channel that the AUX4 output pin mirrors its brightness level from.
+ enum: [aux, main, sub, cam]
+ default: aux
+
+patternProperties:
+ "^led@[0-7]$":
+ type: object
+ $ref: /schemas/leds/common.yaml#
+ unevaluatedProperties: false
+ properties:
+ reg:
+ description:
+ LED Channel Number. each channel maps to a specific channel group used
+ to configure the brightness level of the output pins corresponding to
+ the channel.
+ enum:
+ - 0 # Main Channel (8-bit brightness)
+ - 1 # Sub Channel (8-bit brightness)
+ - 2 # AUX Channel (4-bit brightness)
+ - 3 # Camera Channel, Low-side byte (4-bit brightness)
+ - 4 # Camera Channel, High-side byte (4-bit brightness)
+ - 5 # Red Channel (4-bit brightness)
+ - 6 # Blue Channel (4-bit brightness)
+ - 7 # Green Channel (4-bit brightness)
+ required:
+ - reg
+
+required:
+ - compatible
+ - reg
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/leds/common.h>
+ i2c {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ led-controller@1b {
+ compatible = "adi,ltc3208";
+ reg = <0x1b>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ adi,disable-camhl-pin;
+ adi,cfg-enrgbs-pin;
+ adi,disable-rgb-aux4-dropout;
+
+ /* MAIN */
+ led@0 {
+ reg = <0>;
+ function = LED_FUNCTION_ACTIVITY;
+ color = <LED_COLOR_ID_WHITE>;
+ };
+
+ /* SUB */
+ led@1 {
+ reg = <1>;
+ function = LED_FUNCTION_ACTIVITY;
+ color = <LED_COLOR_ID_WHITE>;
+ };
+
+ /* AUX */
+ led@2 {
+ reg = <2>;
+ function = LED_FUNCTION_ACTIVITY;
+ color = <LED_COLOR_ID_WHITE>;
+ };
+
+ /* CAMLO */
+ led@3 {
+ reg = <3>;
+ function = LED_FUNCTION_FLASH;
+ color = <LED_COLOR_ID_WHITE>;
+ };
+
+ /* CAMHI */
+ led@4 {
+ reg = <4>;
+ function = LED_FUNCTION_FLASH;
+ color = <LED_COLOR_ID_WHITE>;
+ };
+
+ /* RED */
+ led@5 {
+ reg = <5>;
+ function = LED_FUNCTION_INDICATOR;
+ color = <LED_COLOR_ID_RED>;
+ };
+
+ /* BLUE */
+ led@6 {
+ reg = <6>;
+ function = LED_FUNCTION_INDICATOR;
+ color = <LED_COLOR_ID_BLUE>;
+ };
+
+ /* GREEN */
+ led@7 {
+ reg = <7>;
+ function = LED_FUNCTION_INDICATOR;
+ color = <LED_COLOR_ID_GREEN>;
+ };
+ };
+ };
diff --git a/MAINTAINERS b/MAINTAINERS
index 2fb1c75afd16..2fd6ffdaaf04 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -15223,6 +15223,13 @@ W: https://ez.analog.com/linux-software-drivers
F: Documentation/devicetree/bindings/iio/temperature/adi,ltc2983.yaml
F: drivers/iio/temperature/ltc2983.c
+LTC3208 LED DRIVER
+M: Jan Carlo Roleda <jancarlo.roleda@analog.com>
+L: linux-leds@vger.kernel.org
+S: Maintained
+W: https://ez.analog.com/linux-software-drivers
+F: Documentation/devicetree/bindings/leds/adi,ltc3208.yaml
+
LTC4282 HARDWARE MONITOR DRIVER
M: Nuno Sa <nuno.sa@analog.com>
L: linux-hwmon@vger.kernel.org
--
2.43.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH v8 2/2] leds: ltc3208: Add driver for LTC3208 Multidisplay LED Driver
2026-07-29 23:14 [PATCH v8 0/2] Add support for LTC3208 multi-display driver Jan Carlo Roleda
2026-07-29 23:14 ` [PATCH v8 1/2] dt-bindings: leds: Document LTC3208 Multidisplay LED Driver Jan Carlo Roleda
@ 2026-07-29 23:14 ` Jan Carlo Roleda
2026-07-29 23:22 ` sashiko-bot
1 sibling, 1 reply; 5+ messages in thread
From: Jan Carlo Roleda @ 2026-07-29 23:14 UTC (permalink / raw)
To: Lee Jones, Pavel Machek, Rob Herring, Krzysztof Kozlowski,
Conor Dooley
Cc: linux-kernel, linux-leds, devicetree, Uwe Kleine-König,
Jan Carlo Roleda
Kernel driver implementation for LTC3208 Multidisplay LED Driver.
The LTC3208 is a Multi-display LED driver, designed to control up to
7 distinct LED channels (MAIN, SUB, AUX, CAMHI, CAMLO, RED, GREEN, BLUE),
each configurable with its own current level that is equally set to its
respective output current source pins for external LEDs.
It is programmed via the I2C serial interface.
MAIN and SUB support 8-bit current level resolution,
while AUX, CAMHI/LO, RED, GREEN, and BLUE support 4-bit levels.
The AUX LED channel can be configured to mirror the CAM, SUB, and MAIN
channel current levels, or as its own independent AUX channel.
The CAM LED channel is configured as 2 separate CAMHI and CAMLO register
sub-channels, which current is selected via the CAMHL pin, or set to
CAMHI register only via setting the S_CAMHILO bit high in register G (0x7).
Signed-off-by: Jan Carlo Roleda <jancarlo.roleda@analog.com>
---
MAINTAINERS | 1 +
drivers/leds/Kconfig | 12 +++
drivers/leds/Makefile | 1 +
drivers/leds/leds-ltc3208.c | 226 ++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 240 insertions(+)
diff --git a/MAINTAINERS b/MAINTAINERS
index 2fd6ffdaaf04..e3b59485ecb3 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -15229,6 +15229,7 @@ L: linux-leds@vger.kernel.org
S: Maintained
W: https://ez.analog.com/linux-software-drivers
F: Documentation/devicetree/bindings/leds/adi,ltc3208.yaml
+F: drivers/leds/leds-ltc3208.c
LTC4282 HARDWARE MONITOR DRIVER
M: Nuno Sa <nuno.sa@analog.com>
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
index f4a0a3c8c870..d917ce3b72f4 100644
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -1028,6 +1028,18 @@ config LEDS_ACER_A500
This option enables support for the Power Button LED of
Acer Iconia Tab A500.
+config LEDS_LTC3208
+ tristate "LED Driver for Analog Devices LTC3208"
+ depends on LEDS_CLASS && I2C
+ select REGMAP_I2C
+ help
+ Say Y to enable the LTC3208 LED driver.
+ This enables the LED device LTC3208, a 7-channel, 17-current source
+ multidisplay high-current LED driver, configured via I2C.
+
+ To compile this driver as a module, choose M here: the module will
+ be called ltc3208.
+
source "drivers/leds/blink/Kconfig"
comment "Flash and Torch LED drivers"
diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile
index 7db3768912ca..0148b87e16ba 100644
--- a/drivers/leds/Makefile
+++ b/drivers/leds/Makefile
@@ -61,6 +61,7 @@ obj-$(CONFIG_LEDS_LP8788) += leds-lp8788.o
obj-$(CONFIG_LEDS_LP8860) += leds-lp8860.o
obj-$(CONFIG_LEDS_LP8864) += leds-lp8864.o
obj-$(CONFIG_LEDS_LT3593) += leds-lt3593.o
+obj-$(CONFIG_LEDS_LTC3208) += leds-ltc3208.o
obj-$(CONFIG_LEDS_MAX5970) += leds-max5970.o
obj-$(CONFIG_LEDS_MAX77650) += leds-max77650.o
obj-$(CONFIG_LEDS_MAX77705) += leds-max77705.o
diff --git a/drivers/leds/leds-ltc3208.c b/drivers/leds/leds-ltc3208.c
new file mode 100644
index 000000000000..45f867a753a1
--- /dev/null
+++ b/drivers/leds/leds-ltc3208.c
@@ -0,0 +1,226 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * LED driver for Analog Devices LTC3208 Multi-Display Driver
+ *
+ * Copyright 2026 Analog Devices Inc.
+ *
+ * Author: Jan Carlo Roleda <jancarlo.roleda@analog.com>
+ *
+ */
+
+#include <linux/bitfield.h>
+#include <linux/bitmap.h>
+#include <linux/errno.h>
+#include <linux/i2c.h>
+#include <linux/leds.h>
+#include <linux/module.h>
+#include <linux/property.h>
+#include <linux/regmap.h>
+#include <linux/types.h>
+
+/* Registers */
+#define LTC3208_REG_A_GRNRED 0x1 /* Green and Red current DAC */
+#define LTC3208_REG_B_AUXBLU 0x2 /* AUX and Blue current DAC */
+#define LTC3208_REG_C_MAIN 0x3 /* Main current DAC */
+#define LTC3208_REG_D_SUB 0x4 /* Sub current DAC */
+#define LTC3208_REG_E_AUX_SELECT 0x5 /* AUX DAC Select */
+#define LTC3208_AUX1_MASK GENMASK(1, 0)
+#define LTC3208_AUX2_MASK GENMASK(3, 2)
+#define LTC3208_AUX3_MASK GENMASK(5, 4)
+#define LTC3208_AUX4_MASK GENMASK(7, 6)
+#define LTC3208_REG_F_CAM 0x6 /* CAM (High and Low) current DAC */
+#define LTC3208_REG_G_OPT 0x7 /* Device Options */
+#define LTC3208_OPT_CPO_MASK GENMASK(7, 6)
+#define LTC3208_OPT_DIS_RGBDROP BIT(3)
+#define LTC3208_OPT_DIS_CAMHILO BIT(2)
+#define LTC3208_OPT_EN_RGBS BIT(1)
+
+#define LTC3208_MAX_BRIGHTNESS_4BIT 0xF
+#define LTC3208_MAX_BRIGHTNESS_8BIT 0xFF
+
+#define LTC3208_NUM_AUX_LEDS 4 /* Number of configurable aux channels */
+
+enum ltc3208_aux_channel {
+ LTC3208_AUX_CHAN_AUX = 0,
+ LTC3208_AUX_CHAN_MAIN,
+ LTC3208_AUX_CHAN_SUB,
+ LTC3208_AUX_CHAN_CAM
+};
+
+enum ltc3208_channel {
+ LTC3208_CHAN_MAIN = 0,
+ LTC3208_CHAN_SUB,
+ LTC3208_CHAN_AUX,
+ LTC3208_CHAN_CAML,
+ LTC3208_CHAN_CAMH,
+ LTC3208_CHAN_RED,
+ LTC3208_CHAN_BLUE,
+ LTC3208_CHAN_GREEN,
+ LTC3208_CHAN_N_COUNT,
+};
+
+static const char *const ltc3208_dt_aux_channels[] = {
+ "adi,aux1-channel",
+ "adi,aux2-channel",
+ "adi,aux3-channel",
+ "adi,aux4-channel"
+};
+
+static const char *const ltc3208_aux_opt[] = { "aux", "main", "sub", "cam" };
+
+struct ltc3208_led {
+ struct led_classdev cdev;
+ struct regmap_field *rfield;
+};
+
+static const struct reg_default ltc3208_reg_defaults[LTC3208_REG_G_OPT] = {
+ { LTC3208_REG_A_GRNRED, 0 },
+ { LTC3208_REG_B_AUXBLU, 0 },
+ { LTC3208_REG_C_MAIN, 0 },
+ { LTC3208_REG_D_SUB, 0 },
+ { LTC3208_REG_E_AUX_SELECT, 0 },
+ { LTC3208_REG_F_CAM, 0 },
+ { LTC3208_REG_G_OPT, 0 }
+};
+
+static const struct regmap_config ltc3208_regmap_cfg = {
+ .reg_bits = 8,
+ .val_bits = 8,
+ .max_register = LTC3208_REG_G_OPT,
+ .cache_type = REGCACHE_FLAT_S,
+ .reg_defaults = ltc3208_reg_defaults,
+ .num_reg_defaults = LTC3208_REG_G_OPT,
+};
+
+static const struct reg_field ltc3208_led_reg_field[LTC3208_CHAN_N_COUNT] = {
+ [LTC3208_CHAN_MAIN] = REG_FIELD(LTC3208_REG_C_MAIN, 0, 7),
+ [LTC3208_CHAN_SUB] = REG_FIELD(LTC3208_REG_D_SUB, 0, 7),
+ [LTC3208_CHAN_BLUE] = REG_FIELD(LTC3208_REG_B_AUXBLU, 0, 3),
+ [LTC3208_CHAN_AUX] = REG_FIELD(LTC3208_REG_B_AUXBLU, 4, 7),
+ [LTC3208_CHAN_CAML] = REG_FIELD(LTC3208_REG_F_CAM, 0, 3),
+ [LTC3208_CHAN_CAMH] = REG_FIELD(LTC3208_REG_F_CAM, 4, 7),
+ [LTC3208_CHAN_RED] = REG_FIELD(LTC3208_REG_A_GRNRED, 0, 3),
+ [LTC3208_CHAN_GREEN] = REG_FIELD(LTC3208_REG_A_GRNRED, 4, 7),
+};
+
+static int ltc3208_led_set_brightness(struct led_classdev *led_cdev, enum led_brightness brightness)
+{
+ struct ltc3208_led *led = container_of(led_cdev, struct ltc3208_led, cdev);
+ u8 current_level = brightness;
+
+ return regmap_field_write(led->rfield, current_level);
+}
+
+static int ltc3208_probe(struct i2c_client *client)
+{
+ enum ltc3208_aux_channel aux_channels[LTC3208_NUM_AUX_LEDS];
+ DECLARE_BITMAP(registered_chans, LTC3208_CHAN_N_COUNT) = { };
+ struct regmap *regmap;
+ bool disable_rgb_aux4_dropout_signal;
+ bool disable_camhl_pin;
+ bool set_sub_control_pin;
+ int ret;
+ u8 dev_options;
+
+ regmap = devm_regmap_init_i2c(client, <c3208_regmap_cfg);
+ if (IS_ERR(regmap))
+ return dev_err_probe(&client->dev, PTR_ERR(regmap), "Failed to initialize regmap.");
+
+ disable_camhl_pin = device_property_read_bool(&client->dev, "adi,disable-camhl-pin");
+ set_sub_control_pin = device_property_read_bool(&client->dev, "adi,cfg-enrgbs-pin");
+ disable_rgb_aux4_dropout_signal =
+ device_property_read_bool(&client->dev, "adi,disable-rgb-aux4-dropout");
+
+ dev_options = FIELD_PREP(LTC3208_OPT_EN_RGBS, set_sub_control_pin) |
+ FIELD_PREP(LTC3208_OPT_DIS_CAMHILO, disable_camhl_pin) |
+ FIELD_PREP(LTC3208_OPT_CPO_MASK, 0) |
+ FIELD_PREP(LTC3208_OPT_DIS_RGBDROP, disable_rgb_aux4_dropout_signal);
+
+ ret = regmap_write(regmap, LTC3208_REG_G_OPT, dev_options);
+ if (ret)
+ return dev_err_probe(&client->dev, ret, "failed to set device options register.");
+
+ /* Initialize aux channel configurations */
+ for (int i = 0; i < LTC3208_NUM_AUX_LEDS; i++) {
+ /* default value (AUX) if property is not present in dt */
+ if (!device_property_present(&client->dev, ltc3208_dt_aux_channels[i])) {
+ aux_channels[i] = LTC3208_AUX_CHAN_AUX;
+ continue;
+ }
+
+ ret = device_property_match_property_string(&client->dev,
+ ltc3208_dt_aux_channels[i],
+ ltc3208_aux_opt, LTC3208_NUM_AUX_LEDS);
+ if (ret < 0)
+ return dev_err_probe(&client->dev, ret, "Error reading AUX Channel %d", i);
+
+ aux_channels[i] = ret;
+ }
+
+ dev_options = FIELD_PREP(LTC3208_AUX1_MASK, aux_channels[0]) |
+ FIELD_PREP(LTC3208_AUX2_MASK, aux_channels[1]) |
+ FIELD_PREP(LTC3208_AUX3_MASK, aux_channels[2]) |
+ FIELD_PREP(LTC3208_AUX4_MASK, aux_channels[3]);
+
+ ret = regmap_write(regmap, LTC3208_REG_E_AUX_SELECT, dev_options);
+ if (ret)
+ return dev_err_probe(&client->dev, ret, "error writing to aux channel register.");
+
+ device_for_each_child_node_scoped(&client->dev, child) {
+ struct ltc3208_led *led;
+ struct led_init_data init_data = { };
+ u32 chan;
+
+ ret = fwnode_property_read_u32(child, "reg", &chan);
+ if (ret)
+ return dev_err_probe(&client->dev, ret, "Failed to get reg value of LED.");
+ if (chan >= LTC3208_CHAN_N_COUNT)
+ return dev_err_probe(&client->dev, -EINVAL, "%u is an invalid LED ID.",
+ chan);
+ if (test_and_set_bit(chan, registered_chans))
+ return dev_err_probe(&client->dev, -EINVAL, "%u is already registered.",
+ chan);
+
+ led = devm_kzalloc(&client->dev, sizeof(*led), GFP_KERNEL);
+ if (!led)
+ return -ENOMEM;
+
+ led->rfield = devm_regmap_field_alloc(&client->dev, regmap,
+ ltc3208_led_reg_field[chan]);
+ if (IS_ERR(led->rfield))
+ return dev_err_probe(&client->dev, PTR_ERR(led->rfield),
+ "cannot allocate regmap field.");
+ led->cdev.brightness_set_blocking = ltc3208_led_set_brightness;
+ led->cdev.max_brightness = LTC3208_MAX_BRIGHTNESS_4BIT;
+
+ if (chan == LTC3208_CHAN_MAIN || chan == LTC3208_CHAN_SUB)
+ led->cdev.max_brightness = LTC3208_MAX_BRIGHTNESS_8BIT;
+
+ init_data.fwnode = child;
+
+ ret = devm_led_classdev_register_ext(&client->dev, &led->cdev, &init_data);
+ if (ret)
+ return dev_err_probe(&client->dev, ret, "LED %u Register failed.", chan);
+ }
+
+ return 0;
+}
+
+static const struct of_device_id ltc3208_match_table[] = {
+ { .compatible = "adi,ltc3208" },
+ { }
+};
+MODULE_DEVICE_TABLE(of, ltc3208_match_table);
+
+static struct i2c_driver ltc3208_driver = {
+ .driver = {
+ .name = "ltc3208",
+ .of_match_table = ltc3208_match_table,
+ },
+ .probe = ltc3208_probe,
+};
+module_i2c_driver(ltc3208_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Jan Carlo Roleda <jancarlo.roleda@analog.com>");
+MODULE_DESCRIPTION("LTC3208 LED Driver");
--
2.43.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH v8 1/2] dt-bindings: leds: Document LTC3208 Multidisplay LED Driver
2026-07-29 23:14 ` [PATCH v8 1/2] dt-bindings: leds: Document LTC3208 Multidisplay LED Driver Jan Carlo Roleda
@ 2026-07-29 23:20 ` sashiko-bot
0 siblings, 0 replies; 5+ messages in thread
From: sashiko-bot @ 2026-07-29 23:20 UTC (permalink / raw)
To: Jan Carlo Roleda; +Cc: lee, linux-leds, robh, conor+dt, devicetree
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Low] The schema omits `#address-cells` and `#size-cells` from the top-level `required` list, which allows structurally incomplete device tree nodes to silently pass validation.
--
--- Patch [1]: [PATCH v8 1/2] dt-bindings: leds: Document LTC3208 Multidisplay LED Driver ---
commit 40f57e6c55c9069959e21c4ed832c353a3472f0a
Author: Jan Carlo Roleda <jancarlo.roleda@analog.com>
dt-bindings: leds: Document LTC3208 Multidisplay LED Driver
This commit adds Devicetree Documentation for the LTC3208 Multidisplay LED
Driver.
> diff --git a/Documentation/devicetree/bindings/leds/adi,ltc3208.yaml b/Documentation/devicetree/bindings/leds/adi,ltc3208.yaml
> new file mode 100644
> index 0000000000000..0a01e07e0ab70
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/leds/adi,ltc3208.yaml
[ ... ]
> +patternProperties:
> + "^led@[0-7]$":
> + type: object
> + $ref: /schemas/leds/common.yaml#
> + unevaluatedProperties: false
> + properties:
> + reg:
> + description:
> + LED Channel Number. each channel maps to a specific channel group used
> + to configure the brightness level of the output pins corresponding to
> + the channel.
> + enum:
> + - 0 # Main Channel (8-bit brightness)
> + - 1 # Sub Channel (8-bit brightness)
> + - 2 # AUX Channel (4-bit brightness)
> + - 3 # Camera Channel, Low-side byte (4-bit brightness)
> + - 4 # Camera Channel, High-side byte (4-bit brightness)
> + - 5 # Red Channel (4-bit brightness)
> + - 6 # Blue Channel (4-bit brightness)
> + - 7 # Green Channel (4-bit brightness)
> + required:
> + - reg
> +
> +required:
> + - compatible
> + - reg
[Severity: Low]
Should #address-cells and #size-cells be included in this top-level required
list?
The schema defines child LED nodes in patternProperties that strictly
require a reg property. This means the parent controller node must establish
an address space for them.
If #address-cells and #size-cells are omitted from the required list, a
device tree author could configure the node with led@X child nodes but forget
to set the addressing cells, and the structurally incomplete device tree
nodes could silently pass schema validation.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260730-upstream-ltc3208-v8-0-6bdcc35e65d7@analog.com?part=1
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH v8 2/2] leds: ltc3208: Add driver for LTC3208 Multidisplay LED Driver
2026-07-29 23:14 ` [PATCH v8 2/2] leds: ltc3208: Add driver for " Jan Carlo Roleda
@ 2026-07-29 23:22 ` sashiko-bot
0 siblings, 0 replies; 5+ messages in thread
From: sashiko-bot @ 2026-07-29 23:22 UTC (permalink / raw)
To: Jan Carlo Roleda; +Cc: linux-leds, robh, conor+dt, lee, devicetree
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] Regcache desynchronization leads to inability to turn off LEDs left on by bootloader
--
--- Patch [2]: [PATCH v8 2/2] leds: ltc3208: Add driver for LTC3208 Multidisplay LED Driver ---
commit 438e39dda8c60e73fe40abad6d35331fd8bb4b80
Author: Jan Carlo Roleda <jancarlo.roleda@analog.com>
leds: ltc3208: Add driver for LTC3208 Multidisplay LED Driver
This commit adds support for the Analog Devices LTC3208 Multidisplay LED
driver. It supports 7 distinct LED channels and uses I2C for configuration,
utilizing regmap for register access and caching.
> diff --git a/drivers/leds/leds-ltc3208.c b/drivers/leds/leds-ltc3208.c
> new file mode 100644
> --- /dev/null
> +++ b/drivers/leds/leds-ltc3208.c
[ ... ]
> +static int ltc3208_probe(struct i2c_client *client)
> +{
[ ... ]
> + regmap = devm_regmap_init_i2c(client, <c3208_regmap_cfg);
> + if (IS_ERR(regmap))
> + return dev_err_probe(&client->dev, PTR_ERR(regmap), "Failed to initialize regmap.");
[Severity: Medium]
Does this code need to synchronize the register cache with the hardware
during initialization, for instance by calling regcache_sync() or explicitly
clearing the LED DAC registers?
If the bootloader or firmware leaves any LEDs physically turned on,
the regmap cache is still initialized with a default value of 0 for the
LED DAC registers (via ltc3208_reg_defaults), but the hardware itself
is not reset to 0.
If userspace later tries to turn off the LED by setting a brightness of 0,
will regmap_field_write() see that the requested value matches the
cached value (0) and optimize away the I2C transaction? This would leave
the LED physically on while the kernel and sysfs report it as off,
requiring the user to first set a non-zero brightness to force a hardware
update before they can successfully turn it off.
> +
> + disable_camhl_pin = device_property_read_bool(&client->dev, "adi,disable-camhl-pin");
[ ... ]
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260730-upstream-ltc3208-v8-0-6bdcc35e65d7@analog.com?part=2
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-07-30 0:17 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-29 23:14 [PATCH v8 0/2] Add support for LTC3208 multi-display driver Jan Carlo Roleda
2026-07-29 23:14 ` [PATCH v8 1/2] dt-bindings: leds: Document LTC3208 Multidisplay LED Driver Jan Carlo Roleda
2026-07-29 23:20 ` sashiko-bot
2026-07-29 23:14 ` [PATCH v8 2/2] leds: ltc3208: Add driver for " Jan Carlo Roleda
2026-07-29 23:22 ` sashiko-bot
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox