drivers/ioexpander: add an optional pin PWM operation

Add an ioe_setpwm operation (guarded by CONFIG_IOEXPANDER_PWM) for
expanders that can modulate their outputs, e.g. through a LED driver
engine.

Assisted-by: Claude Code
Signed-off-by: raiden00pl <raiden00@railab.me>
This commit is contained in:
raiden00pl 2026-09-23 11:58:19 +02:00 • committed by Xiang Xiao
parent 9eb6969843
commit c31b87ee1e
3 changed files with 46 additions and 0 deletions

View file

@ -273,6 +273,18 @@ driver operations table (``struct ioexpander_ops_s``):
- ``IOEXP_READBUF`` reads the buffered/register value cached by the
expander.
Pin PWM control
---------------
``CONFIG_IOEXPANDER_PWM`` enables the optional ``ioe_setpwm`` operation.
.. c:macro:: IOEXP_SETPWM(dev, pin, duty)
Set a physical pin's duty cycle: ``duty`` is a ``uint16_t`` value from
``0`` (off) to ``0xffff`` (fully on). Returns 0 on success or a negative
errno on failure. The caller must ensure ``dev->ops->ioe_setpwm`` is
non-NULL; the macro does not check it. Frequency control is not provided.
Multi-pin operations
--------------------

View file

@ -618,6 +618,14 @@ config IOEXPANDER_MULTIPIN
This settings enable the definition of routines for
optimized simultaneous access to multiple pins.
config IOEXPANDER_PWM
bool "Support pin PWM control"
default n
---help---
This setting enables an operation to control the PWM duty cycle
of I/O expander pins, for expanders that can modulate their
outputs (e.g. through a LED driver engine).
endif # IOEXPANDER
config DEV_GPIO

View file

@ -253,6 +253,28 @@
#endif /* CONFIG_IOEXPANDER_MULTIPIN */
#ifdef CONFIG_IOEXPANDER_PWM
/****************************************************************************
* Name: IOEXP_SETPWM
*
* Description:
* Set the pin PWM duty cycle. Optional.
*
* Input Parameters:
* dev - Device-specific state data
* pin - The index of the pin to alter in this call
* duty - The duty cycle, where 0 is off and 0xffff is fully on
*
* Returned Value:
* 0 on success, else a negative error code
*
****************************************************************************/
#define IOEXP_SETPWM(dev,pin,duty) ((dev)->ops->ioe_setpwm(dev,pin,duty))
#endif /* CONFIG_IOEXPANDER_PWM */
/****************************************************************************
* Name: IOEP_ATTACH
*
@ -358,6 +380,10 @@ struct ioexpander_ops_s
ioe_callback_t callback, FAR void *arg);
CODE int (*ioe_detach)(FAR struct ioexpander_dev_s *dev, FAR void *handle);
#endif
#ifdef CONFIG_IOEXPANDER_PWM
CODE int (*ioe_setpwm)(FAR struct ioexpander_dev_s *dev, uint8_t pin,
uint16_t duty);
#endif
};
struct ioexpander_dev_s