Skip to content

Conversation

@jcroleda
Copy link

PR Description

  • This PR adds driver support for LTC3208 Multi-Display Driver
  • Datasheet: LTC3208
  • Tested on Raspberry Pi 4B using the following evaluation board: DC824A

PR Type

  • Bug fix (a change that fixes an issue)
  • New feature (a change that adds new functionality)
  • Breaking change (a change that affects other repos or cause CIs to fail)

PR Checklist

  • I have conducted a self-review of my own code changes
  • I have compiled my changes, including the documentation
  • I have tested the changes on the relevant hardware
  • I have updated the documentation outside this repo accordingly
  • I have provided links for the relevant upstream lore

Copy link

@edelweiseescala edelweiseescala left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello, just sharing what I've learned so far

@jcroleda
Copy link
Author

Changelog V2:

  • removed ltc3208_get_brightness
  • fixed indentations
  • replaced device attributes for AUX configurations in favor of devicetree properties
  • cleaned define macros (removed ltc3208_low_byte_data and ltc3208_byte, used field_prep for ltc3208_high_byte_data)
  • updated GPL license on leds-ltc3208.c
  • updated commit message for devicetree bindings

@jcroleda
Copy link
Author

jcroleda commented Dec 1, 2025

Changelog V3:

  • replaced device_property_match_string with device_property_read_string
  • updated LTC3208_NUM_AUX_LEDS to 4

if (ret) {
dev_err(&client->dev, "Error Writing brightness to register %u\n", reg);
return ret;
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, I would just return regmap()

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is exposed to user space by brightness set and is not used in the probe function, if so should I still remove this dev_err?

@jcroleda
Copy link
Author

jcroleda commented Dec 2, 2025

Changelog V4:
leds-ltc3208.yaml

  • Removed common.yaml ref from led patternproperty
  • updated descriptions for leds and AUX channel configurations for clarity

leds-ltc3208.c

  • fixed formatting for multiline function calls
  • Adjusted defines (removed name, updated option count/limits)
  • fixed error message locations to focus within probe()
  • used FIELD_PREP() in update options for consistency
  • replaced device_property_read_string with device_property_match_property_string to shorten aux pin configuration code in probe

@jcroleda jcroleda force-pushed the staging/ltc3208 branch 2 times, most recently from 5d8624c to 6e8165c Compare December 2, 2025 23:48
@jcroleda
Copy link
Author

jcroleda commented Dec 2, 2025

Changelog V4.1:

  • Adjusted tab spacing

Copy link
Contributor

@machschmitt machschmitt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello @jcroleda,

Some additional comments. Take these with a grain of salt (specially the one about led_trigger) as I'm not experienced with the LEDs subsystem.

Besides those, I suggest to drop the "LTC3208:" part of the
"dt-bindings: leds: LTC3208: Document LTC3208 Multidisplay LED Driver"
commit title. LTC3208 has not been added to the kernel yet.

Comment on lines +267 to +339
ret = ltc3208_update_options(data, en_rgbs, dis_camhl,
dropdis_rgb_aux4, cpo_mode);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not familiar with the LED subsystem. Though, I wonder if we can have the ENRGBS pin functionality better supported as a led_trigger. Main idea is, we add/register a struct led_trigger, setting its name, activate/deactivate callbacks, and any other required fields. With the proper configuration, we should be able to get /sys/class/leds/<led>/shot provided to user space (see Documentation/ABI/testing/sysfs-class-led-trigger-oneshot and Documentation/ABI/testing/sysfs-class-led). There could be one trigger for RGB toggle and one for SUB toggle. The trigger activate/deactive handlers would write the proper REGG bit G1, then pulse the connected GPIO (see the comment about the dt property).

Not sure how much of the above actually makes sense so you might look for somebody more experienced with the LED subsystem if things don't fit well.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or, if this gets too complicated or time consuming, it might be reasonable to assume ENRGBS is always high and not mess around with that on the initial support for LTC3208.

Copy link
Author

@jcroleda jcroleda Dec 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think having seperate oneshot triggers for each channel might introduce specific conflicts on the use of the pin (ex. Sub trigger -> RGB trigger before oneshot period is over, will override the Sub trigger as it will switch control of ENRGBS).

However, we could add a general GPIO pin support to provide sysfs access of the pin, and possibly support the same for the CAMHL pin as it serves a similar toggle function.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that can be avoided by locking a mutex on LTC3208 driver, no? Lock a mutex at the beginning of SUB trigger handler (before writing the ENRGBS config), unlock the mutex at the end of the handler. Same logic (and lock) for the RGB trigger handler.

Add Documentation for LTC3208 Multidisplay LED Driver.

Signed-off-by: Jan Carlo Roleda <jancarlo.roleda@analog.com>
Kernel driver implementation for LTC3208 Multidisplay LED Driver

Signed-off-by: Jan Carlo Roleda <jancarlo.roleda@analog.com>
Add entry to Kconfig for LTC3208 driver

Signed-off-by: Jan Carlo Roleda <jancarlo.roleda@analog.com>
@jcroleda
Copy link
Author

Changelog V5:

  • Updated dtbindings name and description for ENRGBS for clarity
  • removed redundant struct in ltc3208_dev
  • removed prints in -ENOMEM returns
  • moved regmap_write to inside switch case of set_brightness and added invalid default
  • added -ENOMEM error check in kcalloc of LED groups
  • added GPIO support for ENRGBS and CAMHL device pins
  • aligned with @edelweiseescala on the naming of adi,force-cpo-level on both ltc3208 and ltc3220 device drivers

Copy link
Contributor

@machschmitt machschmitt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @jcroleda,

Third round of review.

const: 0

enrgbs-gpios:
$ref: /schemas/types.yaml#/definitions/phandle-array
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Usually not needed to reference the phandle-array type. I'd just drop that.
Also, add maxItems: 1

the SUB channel (if adi,cfg-enrgbs-pin is set).

camhl-gpios:
$ref: /schemas/types.yaml#/definitions/phandle-array
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here

ret = gpiod_get_value(data->enrgbs_gpio);
return sysfs_emit(buf, "%d\n", ret);
}
static DEVICE_ATTR_RW(enrgbs);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I still think this can be better supported as some sort of triggerable led. Note this is adding a new interface between the kernel and user space and, if accepted, will very likely need to be documented (e.g. Documentation/ABI/testing/sysfs-class-led-driver-lm3533).

ret = gpiod_get_value(data->camhl_gpio);
return sysfs_emit(buf, "%d\n", ret);
}
static DEVICE_ATTR_RW(camhl);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same for this one

enum ltc3208_aux_channel aux_3, enum ltc3208_aux_channel aux_4)
{
struct regmap *map = dev->map;
u8 val = 0;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no need to initialize val to zero if it is going to be assigned right below

Comment on lines +273 to +280
struct ltc3208_dev *data;
struct regmap *map;
struct ltc3208_led *leds;
enum ltc3208_aux_channel aux_channels[LTC3208_NUM_AUX_LEDS];
enum ltc3208_cpo_mode cpo_mode;
int ret, i;
u32 val;
bool en_rgbs, dis_camhl, dropdis_rgb_aux4;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can the local variable heres follow reverse xmas tree ordering?

Comment on lines +329 to +330
if (!device_property_read_u32(&client->dev,
"adi,force-cpo-level", &val)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is adi,force-cpo-level not a string? Use device_property_match_property_string() 1. See usage examples within the IIO subsystem (e.g. 2 3).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants