.../devicetree/bindings/leds/ams,as3668.yaml | 74 +++++++ MAINTAINERS | 7 + drivers/leds/Kconfig | 13 ++ drivers/leds/Makefile | 1 + drivers/leds/leds-as3668.c | 202 ++++++++++++++++++ 5 files changed, 297 insertions(+) create mode 100644 Documentation/devicetree/bindings/leds/ams,as3668.yaml create mode 100644 drivers/leds/leds-as3668.c
This patch adds basic support for the as3668 driver IC via I2C interface. The IC is capable of driving four individual LEDs up to 25.5mA per channel. Hardware blinking would be theoretically possible, but this chip only supports a few set on/off-delays which makes using that feature unfeasable, therefore my driver doesn't offer that capability. It's intended applications is in mobile devices such as phones, tablets and cameras. This driver was tested and is working on a google-manta which is running postmarketOS with a near mainline kernel. Also there is a patch in the linux mailing list for that device: https://lore.kernel.org/all/20251120201958.1970828-1-linux@timmermann.space/ The register names and values are taken from the official datasheet which can be found here: https://www.mouser.com/datasheet/2/588/AS3668_DS000196_1-00-1512816.pdf Please note: This is my first suggested patch to the kernel. I've read the docs in regards to the led subsystem, coding style and submission of patches, but I'm still a bit unsure about the general workflow. I will try my best. Changes in v13: - Fixed a syntax error in ..channel_mode_set(). - Improved error handling in ..channel_mode_set(). - Link to v12: https://lore.kernel.org/all/20251128175827.649481-1-linux@timmermann.space/ Changes in v12: - Fixed error handling in ..channel_mode_set(). (@Lee) - Link to v11: https://lore.kernel.org/all/20251125114015.355487-1-linux@timmermann.space/ Changes in v11: - Adding mask and register to struct instead of led_id. (@Lee) - Renaming reg variables to be more clear. (@Lee) - Simplified calling of ..channel_mode_set(). (@Lee) - Removed unnecessary pointer dereferencing. (@Lee) - Changed error type in ..probe() to -EINVAL. (@Lee) - Reworded some error messages to be more clear. (@Lee) - Removed error message when removing module. (@Lee) - Link to v10: https://lore.kernel.org/all/20251117020008.316648-1-linux@timmermann.space/ Changes in v10: - Reworded some error messages to be more clear. (@Lee) - Removed newline. (@Lee) - Added enabling and disabling of channels during brightness set. (@Lee) - Rearranged and renamed constants. - Link to v9: https://lore.kernel.org/all/20251014152604.852487-1-linux@timmermann.space/ Changes in v9: - Tabbed out values. (@Lee) - Removed newlines. (@Lee) - Renamed chip id constant and variables to be more clear. (@Lee) - Removed unnecessary comments. (@Lee) - Removed unnecessary debug message. (@Lee) - Separate declaration and assignment of err variable. (@Lee) - Link to v8: https://lore.kernel.org/all/20250808213143.146732-1-linux@timmermann.space/ Changes in v8: - Rearranged constants. - Removed more newlines. - Changed error messages to be more clear. - Renamed variables. - Removed revision check. - Removed extra i2c read&write functions. - Made initalisation code more readable with bitmasks. - The code now wraps around before 100 chars instead of 80. - Link to v7: https://lore.kernel.org/all/20250708141114.134950-1-linux@timmermann.space/ Changes in v7: - Simplified multiple error messages. They now use dev_err_probe(). - Removed some newlines. - Link to v6: https://lore.kernel.org/all/20250611083151.22150-1-linux@timmermann.space/ Changes in v6: - Fixed missing error handling during init - Fixed missing newline in error messages - Fixed size calculation for memory allocation - Fixed error handling for memory allocation - Link to v5: https://lore.kernel.org/lkml/20250608231854.75668-1-linux@timmermann.space/ Changes in v5: - Fixed debug and error messages using wrong format specifiers. - Fixed missing include bitwise.h. - Changed commit message for dt file to fit expected style. - Link to v4: https://lore.kernel.org/lkml/20250607215049.29259-1-linux@timmermann.space/ Changes in v4: - Fixed some mistakes made in the dt file pointed out in v3. - Swapped dt and driver in patch series. DT now comes first. - Fixed errors in Kconfig due to last minute changes. - Added dt file into MAINTAINERS file. - Link to v3: https://lore.kernel.org/lkml/20250604225838.102910-2-linux@timmermann.space/ Changes in v3: - Fixed an extra whitespace in the dt bindings documentation. - Sent patch to all related lists and maintainers. - Link to v2: https://lore.kernel.org/lkml/20250531120715.302870-4-linux@timmermann.space/ Changes in v2: - Fixed reading led subnodes in dt incorrectly, which caused wrong numbering and a segfault when removing the driver module - Fixed calling of_property_read_u8 with an int, causing a compiler error - Added more error checking during writes to the i2c bus - Link to v1: https://lore.kernel.org/linux-leds/20250530184219.78085-3-linux@timmermann.space/ Signed-off-by: Lukas Timmermann <linux@timmermann.space> Lukas Timmermann (2): dt-bindings: leds: Add new as3668 support leds: as3668: Driver for the ams Osram 4-channel i2c LED driver .../devicetree/bindings/leds/ams,as3668.yaml | 74 +++++++ MAINTAINERS | 7 + drivers/leds/Kconfig | 13 ++ drivers/leds/Makefile | 1 + drivers/leds/leds-as3668.c | 202 ++++++++++++++++++ 5 files changed, 297 insertions(+) create mode 100644 Documentation/devicetree/bindings/leds/ams,as3668.yaml create mode 100644 drivers/leds/leds-as3668.c -- 2.52.0
On Tue, 02 Dec 2025 00:05:59 +0100, Lukas Timmermann wrote:
> This patch adds basic support for the as3668 driver IC via I2C interface.
> The IC is capable of driving four individual LEDs up to 25.5mA per
> channel. Hardware blinking would be theoretically possible, but this chip
> only supports a few set on/off-delays which makes using that feature
> unfeasable, therefore my driver doesn't offer that capability.
> It's intended applications is in mobile devices such as phones,
> tablets and cameras. This driver was tested and is working on
> a google-manta which is running postmarketOS with a near mainline kernel.
> Also there is a patch in the linux mailing list for that device:
> https://lore.kernel.org/all/20251120201958.1970828-1-linux@timmermann.space/
> The register names and values are taken from the official datasheet which
> can be found here:
> https://www.mouser.com/datasheet/2/588/AS3668_DS000196_1-00-1512816.pdf
>
> [...]
Applied, thanks!
[1/2] dt-bindings: leds: Add new as3668 support
commit: 1e31ecb73163385b7ca764a97fb350b395bcff3c
[2/2] leds: as3668: Driver for the ams Osram 4-channel i2c LED driver
commit: 68d2a846952f81cd01331fffdec9a67299b22319
--
Lee Jones [李琼斯]
On Tue, 02 Dec 2025, Lukas Timmermann wrote:
Running through checkpatch.pl
total: 0 errors, 0 warnings, 86 lines checked
"[PATCH v13 1/2] dt-bindings: leds: Add new as3668 support" has no obvious style problems and is ready for submission.
ERROR: Macros with complex values should be enclosed in parentheses
#115: FILE: drivers/leds/leds-as3668.c:35:
+#define AS3668_CURR_MODE_PACK(mode) ((mode) << 0) | \
+ ((mode) << 2) | \
+ ((mode) << 4) | \
+ ((mode) << 6)
BUT SEE:
do {} while (0) advice is over-stated in a few situations:
The more obvious case is macros, like MODULE_PARM_DESC, invoked at
file-scope, where C disallows code (it must be in functions). See
$exceptions if you have one to add by name.
More troublesome is declarative macros used at top of new scope,
like DECLARE_PER_CPU. These might just compile with a do-while-0
wrapper, but would be incorrect. Most of these are handled by
detecting struct,union,etc declaration primitives in $exceptions.
Theres also macros called inside an if (block), which "return" an
expression. These cannot do-while, and need a ({}) wrapper.
Enjoy this qualification while we work to improve our heuristics.
WARNING: please, no spaces at the start of a line
#135: FILE: drivers/leds/leds-as3668.c:55:
+ int ret;$
WARNING: please, no spaces at the start of a line
#136: FILE: drivers/leds/leds-as3668.c:56:
+ u8 channel_modes;$
WARNING: please, no spaces at the start of a line
#138: FILE: drivers/leds/leds-as3668.c:58:
+ ret = i2c_smbus_read_byte_data(led->chip->client, AS3668_CURR_MODE_REG);$
WARNING: please, no spaces at the start of a line
#139: FILE: drivers/leds/leds-as3668.c:59:
+ if (ret < 0) {$
ERROR: code indent should use tabs where possible
#140: FILE: drivers/leds/leds-as3668.c:60:
+ dev_err(led->cdev.dev, "failed to read channel modes\n");$
WARNING: please, no spaces at the start of a line
#140: FILE: drivers/leds/leds-as3668.c:60:
+ dev_err(led->cdev.dev, "failed to read channel modes\n");$
ERROR: code indent should use tabs where possible
#141: FILE: drivers/leds/leds-as3668.c:61:
+ return ret;$
WARNING: please, no spaces at the start of a line
#141: FILE: drivers/leds/leds-as3668.c:61:
+ return ret;$
WARNING: please, no spaces at the start of a line
#142: FILE: drivers/leds/leds-as3668.c:62:
+ }$
WARNING: please, no spaces at the start of a line
#143: FILE: drivers/leds/leds-as3668.c:63:
+ channel_modes = (u8)ret;$
WARNING: please, no spaces at the start of a line
#145: FILE: drivers/leds/leds-as3668.c:65:
+ channel_modes &= ~led->mode_mask;$
WARNING: please, no spaces at the start of a line
#146: FILE: drivers/leds/leds-as3668.c:66:
+ channel_modes |= led->mode_mask & (AS3668_CURR_MODE_PACK(mode));$
WARNING: please, no spaces at the start of a line
#148: FILE: drivers/leds/leds-as3668.c:68:
+ return i2c_smbus_write_byte_data(led->chip->client, AS3668_CURR_MODE_REG, channel_modes);$
WARNING: line length of 104 exceeds 100 columns
#247: FILE: drivers/leds/leds-as3668.c:167:
+ return dev_err_probe(&client->dev, -EIO, "failed to set zero initial current levels\n");
WARNING: DT compatible string "ams,as3668" appears un-documented -- check ./Documentation/devicetree/bindings/
#264: FILE: drivers/leds/leds-as3668.c:184:
+ { .compatible = "ams,as3668" },
total: 3 errors, 13 warnings, 235 lines checked
NOTE: For some of the reported defects, checkpatch may be able to
mechanically convert to the typical style using --fix or --fix-inplace.
NOTE: Whitespace errors detected.
You may wish to use scripts/cleanpatch or scripts/cleanfile
"[PATCH v13 2/2] leds: as3668: Driver for the ams Osram 4-channel" has style problems, please review.
NOTE: If any of the errors are false positives, please report
them to the maintainer, see CHECKPATCH in MAINTAINERS.
--
Lee Jones [李琼斯]
On Thu, Jan 08, 2026 at 10:41:30AM +0000, Lee Jones wrote:
> On Tue, 02 Dec 2025, Lukas Timmermann wrote:
>
> Running through checkpatch.pl
> total: 0 errors, 0 warnings, 86 lines checked
>
> "[PATCH v13 1/2] dt-bindings: leds: Add new as3668 support" has no obvious style problems and is ready for submission.
> ERROR: Macros with complex values should be enclosed in parentheses
> #115: FILE: drivers/leds/leds-as3668.c:35:
> +#define AS3668_CURR_MODE_PACK(mode) ((mode) << 0) | \
> + ((mode) << 2) | \
> + ((mode) << 4) | \
> + ((mode) << 6)
>
> BUT SEE:
>
> do {} while (0) advice is over-stated in a few situations:
>
> The more obvious case is macros, like MODULE_PARM_DESC, invoked at
> file-scope, where C disallows code (it must be in functions). See
> $exceptions if you have one to add by name.
>
> More troublesome is declarative macros used at top of new scope,
> like DECLARE_PER_CPU. These might just compile with a do-while-0
> wrapper, but would be incorrect. Most of these are handled by
> detecting struct,union,etc declaration primitives in $exceptions.
>
> Theres also macros called inside an if (block), which "return" an
> expression. These cannot do-while, and need a ({}) wrapper.
>
> Enjoy this qualification while we work to improve our heuristics.
>
> WARNING: please, no spaces at the start of a line
> #135: FILE: drivers/leds/leds-as3668.c:55:
> + int ret;$
>
> WARNING: please, no spaces at the start of a line
> #136: FILE: drivers/leds/leds-as3668.c:56:
> + u8 channel_modes;$
>
> WARNING: please, no spaces at the start of a line
> #138: FILE: drivers/leds/leds-as3668.c:58:
> + ret = i2c_smbus_read_byte_data(led->chip->client, AS3668_CURR_MODE_REG);$
>
> WARNING: please, no spaces at the start of a line
> #139: FILE: drivers/leds/leds-as3668.c:59:
> + if (ret < 0) {$
>
> ERROR: code indent should use tabs where possible
> #140: FILE: drivers/leds/leds-as3668.c:60:
> + dev_err(led->cdev.dev, "failed to read channel modes\n");$
>
> WARNING: please, no spaces at the start of a line
> #140: FILE: drivers/leds/leds-as3668.c:60:
> + dev_err(led->cdev.dev, "failed to read channel modes\n");$
>
> ERROR: code indent should use tabs where possible
> #141: FILE: drivers/leds/leds-as3668.c:61:
> + return ret;$
>
> WARNING: please, no spaces at the start of a line
> #141: FILE: drivers/leds/leds-as3668.c:61:
> + return ret;$
>
> WARNING: please, no spaces at the start of a line
> #142: FILE: drivers/leds/leds-as3668.c:62:
> + }$
>
> WARNING: please, no spaces at the start of a line
> #143: FILE: drivers/leds/leds-as3668.c:63:
> + channel_modes = (u8)ret;$
>
> WARNING: please, no spaces at the start of a line
> #145: FILE: drivers/leds/leds-as3668.c:65:
> + channel_modes &= ~led->mode_mask;$
>
> WARNING: please, no spaces at the start of a line
> #146: FILE: drivers/leds/leds-as3668.c:66:
> + channel_modes |= led->mode_mask & (AS3668_CURR_MODE_PACK(mode));$
>
> WARNING: please, no spaces at the start of a line
> #148: FILE: drivers/leds/leds-as3668.c:68:
> + return i2c_smbus_write_byte_data(led->chip->client, AS3668_CURR_MODE_REG, channel_modes);$
>
> WARNING: line length of 104 exceeds 100 columns
> #247: FILE: drivers/leds/leds-as3668.c:167:
> + return dev_err_probe(&client->dev, -EIO, "failed to set zero initial current levels\n");
>
> WARNING: DT compatible string "ams,as3668" appears un-documented -- check ./Documentation/devicetree/bindings/
> #264: FILE: drivers/leds/leds-as3668.c:184:
> + { .compatible = "ams,as3668" },
>
> total: 3 errors, 13 warnings, 235 lines checked
>
> NOTE: For some of the reported defects, checkpatch may be able to
> mechanically convert to the typical style using --fix or --fix-inplace.
>
> NOTE: Whitespace errors detected.
> You may wish to use scripts/cleanpatch or scripts/cleanfile
>
> "[PATCH v13 2/2] leds: as3668: Driver for the ams Osram 4-channel" has style problems, please review.
>
> NOTE: If any of the errors are false positives, please report
> them to the maintainer, see CHECKPATCH in MAINTAINERS.
>
> --
> Lee Jones [李琼斯]
>
Acknowledged. That shouldn't have happened. I apologize.
I had no time to fix this issue since. I will try to make that happen in
the next days.
Best regards,
Lukas Timmermann
© 2016 - 2026 Red Hat, Inc.