Skip to content

Commit

Permalink
leds: add function to configure hardware controlled LED
Browse files Browse the repository at this point in the history
Add hw_control_configure helper to configure how the LED should work in
hardware mode. The function require to support the particular trigger and
will use the passed flag to elaborate the data and apply the
correct configuration. This function will then be used by the trigger to
request and update hardware configuration.

Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
  • Loading branch information
Ansuel authored and lunn committed Mar 2, 2023
1 parent a1d4d16 commit d4ee8e7
Show file tree
Hide file tree
Showing 2 changed files with 103 additions and 0 deletions.
60 changes: 60 additions & 0 deletions Documentation/leds/leds-class.rst
Expand Up @@ -200,10 +200,70 @@ The LED must implement 3 main API:
It's advised to the driver to put the LED in the old state
but this is not enforcerd and putting the LED off is also accepted.

- hw_control_configure():
This will be used to configure the various blink modes LED support
in hardware mode.

With LED_BLINK_HW_CONTROLLED blink_mode hw_control_status/start/stop is optional
and any software only trigger will reject activation as the LED supports only
hardware mode.

Where a trigger has support for hardware controlled blink modes,
hw_control_configure() will be used to check whether a particular blink mode
is supported and configure the blink mode using various specific command.

hw_control_configure() takes 3 arguments:

- struct led_classdev *led_cdev
- unsigned long flag:
This can be used for multiple purpose based on passed command
in the 3rd argument of this function.
It may be NULL if the 3rd argument doesn't require them.

The unsigned long flag is specific to the trigger and its meaning
change across different triggers.
For this exact reason LED driver needs to declare explicit support
for the trigger supporting hardware blink mode.
The driver should return -EOPNOTSUPP if asked to enter in hardware
blink mode with an unsupported trigger.

The LED driver may also report -EOPNOTSUPP if the requested flag
are rejected and can't be handled in hw blink mode by the LED.

Flag can both be a single blink mode or a set of multiple blink
mode. LED driver must be able to handle both cases.

- enum led_blink_hw_cmd cmd:
This is used to request to the LED driver various operation.

They may return -EOPNOTSUPP or -EINVAL based on the provided flags.

hw_control_configure() supports the following cmd:

- LED_BLINK_HW_ENABLE:
enable the blink mode requested in flag. Returns 0 or a negative
error.

- LED_BLINK_HW_DISABLE:
disable the blink mode requested in flag. Returns 0 or a negative
error.

- LED_BLINK_HW_STATUS:
read the status of the blink mode requested in flag. Return a mask
of the enabled blink mode requested in flag or a negative error.

- LED_BLINK_HW_SUPPORTED:
ask the LED driver if the blink mode requested in flag is supported.
Return 1 if supported or a negative error in any other case.

- LED_BLINK_HW_RESET:
reset any blink mode currently active. Value in flag are ignored.
Return 0 or a negative error.

LED driver can set the blink mode to a default state or keep everything
disabled.

Known Issues
============

Expand Down
43 changes: 43 additions & 0 deletions include/linux/leds.h
Expand Up @@ -94,6 +94,14 @@ enum led_blink_modes {
LED_BLINK_SWHW_CONTROLLED,
};

enum led_blink_hw_cmd {
LED_BLINK_HW_ENABLE, /* Enable the hardware blink mode */
LED_BLINK_HW_DISABLE, /* Disable the hardware blink mode */
LED_BLINK_HW_STATUS, /* Read the status of the hardware blink mode */
LED_BLINK_HW_SUPPORTED, /* Ask the driver if the hardware blink mode is supported */
LED_BLINK_HW_RESET, /* Reset any hardware blink active */
};

struct led_classdev {
const char *name;
unsigned int brightness;
Expand Down Expand Up @@ -199,6 +207,17 @@ struct led_classdev {
* the old status but that is not mandatory and also putting it off is accepted.
*/
int (*hw_control_stop)(struct led_classdev *led_cdev);
/* This will be used to configure the various blink modes LED support in hardware
* mode.
* The LED driver require to support the active trigger and will elaborate the
* unsigned long flag and do the operation based on the provided cmd.
* Current operation are enable,disable,supported and status.
* A trigger will use this to enable or disable the asked blink mode, check the
* status of the blink mode or ask if the blink mode can run in hardware mode.
*/
int (*hw_control_configure)(struct led_classdev *led_cdev,
unsigned long flag,
enum led_blink_hw_cmd cmd);
#endif

#ifdef CONFIG_LEDS_BRIGHTNESS_HW_CHANGED
Expand Down Expand Up @@ -473,6 +492,30 @@ static inline void *led_get_trigger_data(struct led_classdev *led_cdev)
return led_cdev->trigger_data;
}

#ifdef CONFIG_LEDS_HARDWARE_CONTROL
static inline bool led_trigger_blink_mode_is_supported(struct led_classdev *led_cdev,
unsigned long flag)
{
int ret;

/* Sanity check: make sure led support hw mode */
if (led_cdev->blink_mode == LED_BLINK_SW_CONTROLLED)
return false;

ret = led_cdev->hw_control_configure(led_cdev, flag, LED_BLINK_HW_SUPPORTED);
if (ret > 0)
return true;

return false;
}
#else
static inline bool led_trigger_blink_mode_is_supported(struct led_classdev *led_cdev,
unsigned long flag)
{
return false;
}
#endif

/**
* led_trigger_rename_static - rename a trigger
* @name: the new trigger name
Expand Down

0 comments on commit d4ee8e7

Please sign in to comment.