blob: 7c297cbc6cdc1841ced9c65974817200d19b2f29 [file] [log] [blame]
/*
* Copyright (c) 2017 Linaro Limited
* Copyright (c) 2024 Jamie McCrae
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
* @brief Public API for controlling linear strips of LEDs.
*
* This library abstracts the chipset drivers for individually
* addressable strips of LEDs.
*/
#ifndef ZEPHYR_INCLUDE_DRIVERS_LED_STRIP_H_
#define ZEPHYR_INCLUDE_DRIVERS_LED_STRIP_H_
/**
* @brief LED Strip Interface
* @defgroup led_strip_interface LED Strip Interface
* @ingroup io_interfaces
* @{
*/
#include <errno.h>
#include <zephyr/types.h>
#include <zephyr/device.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Color value for a single RGB LED.
*
* Individual strip drivers may ignore lower-order bits if their
* resolution in any channel is less than a full byte.
*/
struct led_rgb {
#ifdef CONFIG_LED_STRIP_RGB_SCRATCH
/*
* Pad/scratch space needed by some drivers. Users should
* ignore.
*/
uint8_t scratch;
#endif
/** Red channel */
uint8_t r;
/** Green channel */
uint8_t g;
/** Blue channel */
uint8_t b;
};
/**
* @typedef led_api_update_rgb
* @brief Callback API for updating an RGB LED strip
*
* @see led_strip_update_rgb() for argument descriptions.
*/
typedef int (*led_api_update_rgb)(const struct device *dev,
struct led_rgb *pixels,
size_t num_pixels);
/**
* @typedef led_api_update_channels
* @brief Callback API for updating channels without an RGB interpretation.
*
* @see led_strip_update_channels() for argument descriptions.
*/
typedef int (*led_api_update_channels)(const struct device *dev,
uint8_t *channels,
size_t num_channels);
/**
* @typedef led_api_length
* @brief Callback API for getting length of an LED strip.
*
* @see led_strip_length() for argument descriptions.
*/
typedef size_t (*led_api_length)(const struct device *dev);
/**
* @brief LED strip driver API
*
* This is the mandatory API any LED strip driver needs to expose.
*/
__subsystem struct led_strip_driver_api {
led_api_update_rgb update_rgb;
led_api_update_channels update_channels;
led_api_length length;
};
/**
* @brief Mandatory function to update an LED strip with the given RGB array.
*
* @param dev LED strip device.
* @param pixels Array of pixel data.
* @param num_pixels Length of pixels array.
*
* @retval 0 on success.
* @retval -errno negative errno code on failure.
*
* @warning This routine may overwrite @a pixels.
*/
static inline int led_strip_update_rgb(const struct device *dev,
struct led_rgb *pixels,
size_t num_pixels)
{
const struct led_strip_driver_api *api =
(const struct led_strip_driver_api *)dev->api;
/* Allow for out-of-tree drivers that do not have this function for 2 Zephyr releases
* until making it mandatory, function added after Zephyr 3.6
*/
if (api->length != NULL) {
/* Ensure supplied pixel size is valid for this device */
if (api->length(dev) < num_pixels) {
return -ERANGE;
}
}
return api->update_rgb(dev, pixels, num_pixels);
}
/**
* @brief Optional function to update an LED strip with the given channel array
* (each channel byte corresponding to an individually addressable color
* channel or LED. Channels are updated linearly in strip order.
*
* @param dev LED strip device.
* @param channels Array of per-channel data.
* @param num_channels Length of channels array.
*
* @retval 0 on success.
* @retval -ENOSYS if not implemented.
* @retval -errno negative errno code on other failure.
*
* @warning This routine may overwrite @a channels.
*/
static inline int led_strip_update_channels(const struct device *dev,
uint8_t *channels,
size_t num_channels)
{
const struct led_strip_driver_api *api =
(const struct led_strip_driver_api *)dev->api;
if (api->update_channels == NULL) {
return -ENOSYS;
}
return api->update_channels(dev, channels, num_channels);
}
/**
* @brief Mandatory function to get chain length (in pixels) of an LED strip device.
*
* @param dev LED strip device.
*
* @retval Length of LED strip device.
*/
static inline size_t led_strip_length(const struct device *dev)
{
const struct led_strip_driver_api *api =
(const struct led_strip_driver_api *)dev->api;
return api->length(dev);
}
#ifdef __cplusplus
}
#endif
/**
* @}
*/
#endif /* ZEPHYR_INCLUDE_DRIVERS_LED_STRIP_H_ */