Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 | /* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (c) 2015 Google, Inc * Written by Simon Glass <sjg@chromium.org> */ #ifndef __LED_H #define __LED_H #include <stdbool.h> #include <cyclic.h> #include <dm/ofnode.h> /** * DOC: Overview * * Generic LED API provided when a supported compatible is defined in DeviceTree. * * To enable support for LEDs, enable the `CONFIG_LED` Kconfig option. * * The most common implementation is for GPIO-connected LEDs. If using GPIO-connected LEDs, * enable the `LED_GPIO` Kconfig option. * * `LED_BLINK` support requires LED driver support and is therefore optional. If LED blink * functionality is needed, enable the `LED_BLINK` Kconfig option. If LED driver doesn't * support HW Blink, SW Blink can be used with the Cyclic framework by enabling the * CONFIG_LED_SW_BLINK. * * Boot and Activity LEDs are also supported. These LEDs can signal various system operations * during runtime, such as boot initialization, file transfers, and flash write/erase operations. * * To enable a Boot LED, enable `CONFIG_LED_BOOT` and define in `/options/u-boot` root node the * property `boot-led`. This will enable the specified LED to blink and turn ON when * the bootloader initializes correctly. * * To enable an Activity LED, enable `CONFIG_LED_ACTIVITY` and define in `/options/u-boot` root * node the property `activity-led`. * This will enable the specified LED to blink and turn ON during file transfers or flash * write/erase operations. * * Both Boot and Activity LEDs provide a simple API to turn the LED ON or OFF: * `led_boot_on()`, `led_boot_off()`, `led_activity_on()`, and `led_activity_off()`. * * Both configurations can optionally define a `boot/activity-led-period` property * if `CONFIG_LED_BLINK` or `CONFIG_LED_SW_BLINK` is enabled for LED blink operations, which * is usually used by the Activity LED. If not defined the default value of 250 (ms) is used. * * When `CONFIG_LED_BLINK` or `CONFIG_LED_SW_BLINK` is enabled, additional APIs are exposed: * `led_boot_blink()` and `led_activity_blink()`. Note that if `CONFIG_LED_BLINK` or * `CONFIG_LED_SW_BLINK` is disabled, these APIs will behave like the `led_boot_on()` and * `led_activity_on()` APIs, respectively. */ struct udevice; /* * value imported from linux:include/linux/uapi/linux/uleds.h */ #define LED_MAX_NAME_SIZE 64 enum led_state_t { LEDST_OFF = 0, LEDST_ON = 1, LEDST_TOGGLE, LEDST_BLINK, LEDST_COUNT, }; enum led_sw_blink_state_t { LED_SW_BLINK_ST_DISABLED, LED_SW_BLINK_ST_NOT_READY, LED_SW_BLINK_ST_OFF, LED_SW_BLINK_ST_ON, }; struct led_sw_blink { enum led_sw_blink_state_t state; struct udevice *dev; struct cyclic_info cyclic; const char cyclic_name[0]; }; /** * struct led_uc_plat - Platform data the uclass stores about each device * * @label: LED label * @default_state: LED default state * @name: LED name, derived from function, color or function-enumerator * property. * @sw_blink: LED software blink struct */ struct led_uc_plat { const char *label; enum led_state_t default_state; char name[LED_MAX_NAME_SIZE]; #ifdef CONFIG_LED_SW_BLINK struct led_sw_blink *sw_blink; #endif }; /** * struct led_uc_priv - Private data the uclass stores about each device * * @boot_led_label: Boot LED label * @activity_led_label: Activity LED label * @boot_led_dev: Boot LED dev * @activity_led_dev: Activity LED dev * @boot_led_period: Boot LED blink period * @activity_led_period: Activity LED blink period */ struct led_uc_priv { #ifdef CONFIG_LED_BOOT const char *boot_led_label; int boot_led_period; #endif #ifdef CONFIG_LED_ACTIVITY const char *activity_led_label; int activity_led_period; #endif }; struct led_ops { /** * set_state() - set the state of an LED * * @dev: LED device to change * @state: LED state to set * @return 0 if OK, -ve on error */ int (*set_state)(struct udevice *dev, enum led_state_t state); /** * led_get_state() - get the state of an LED * * @dev: LED device to change * @return LED state led_state_t, or -ve on error */ enum led_state_t (*get_state)(struct udevice *dev); #ifdef CONFIG_LED_BLINK /** * led_set_period() - set the blink period of an LED * * Thie records the period if supported, or returns -ENOSYS if not. * To start the LED blinking, use set_state(). * * @dev: LED device to change * @period_ms: LED blink period in milliseconds * @return 0 if OK, -ve on error */ int (*set_period)(struct udevice *dev, int period_ms); #endif }; #define led_get_ops(dev) ((struct led_ops *)(dev)->driver->ops) /** * led_get_by_label() - Find an LED device by label * * @label: LED label to look up * @devp: Returns the associated device, if found * Return: 0 if found, -ENODEV if not found, other -ve on error */ int led_get_by_label(const char *label, struct udevice **devp); /** * led_set_state() - set the state of an LED * * @dev: LED device to change * @state: LED state to set * Return: 0 if OK, -ve on error */ int led_set_state(struct udevice *dev, enum led_state_t state); /** * led_get_state() - get the state of an LED * * @dev: LED device to change * Return: LED state led_state_t, or -ve on error */ enum led_state_t led_get_state(struct udevice *dev); /** * led_set_period() - set the blink period of an LED * * @dev: LED device to change * @period_ms: LED blink period in milliseconds * Return: 0 if OK, -ve on error */ int led_set_period(struct udevice *dev, int period_ms); /** * led_bind_generic() - bind children of parent to given driver * * @parent: Top-level LED device * @driver_name: Driver for handling individual child nodes */ int led_bind_generic(struct udevice *parent, const char *driver_name); /* Internal functions for software blinking. Do not use them in your code */ int led_sw_set_period(struct udevice *dev, int period_ms); bool led_sw_is_blinking(struct udevice *dev); bool led_sw_on_state_change(struct udevice *dev, enum led_state_t state); #ifdef CONFIG_LED_BOOT /** * led_boot_on() - turn ON the designated LED for booting * * Return: 0 if OK, -ve on error */ int led_boot_on(void); /** * led_boot_off() - turn OFF the designated LED for booting * * Return: 0 if OK, -ve on error */ int led_boot_off(void); #if defined(CONFIG_LED_BLINK) || defined(CONFIG_LED_SW_BLINK) /** * led_boot_blink() - turn ON the designated LED for booting * * Return: 0 if OK, -ve on error */ int led_boot_blink(void); #else /* If LED BLINK is not supported/enabled, fallback to LED ON */ #define led_boot_blink led_boot_on #endif #else static inline int led_boot_on(void) { return -ENOSYS; } static inline int led_boot_off(void) { return -ENOSYS; } static inline int led_boot_blink(void) { return -ENOSYS; } #endif #ifdef CONFIG_LED_ACTIVITY /** * led_activity_on() - turn ON the designated LED for activity * * Return: 0 if OK, -ve on error */ int led_activity_on(void); /** * led_activity_off() - turn OFF the designated LED for activity * * Return: 0 if OK, -ve on error */ int led_activity_off(void); #if defined(CONFIG_LED_BLINK) || defined(CONFIG_LED_SW_BLINK) /** * led_activity_blink() - turn ON the designated LED for activity * * Return: 0 if OK, -ve on error */ int led_activity_blink(void); #else /* If LED BLINK is not supported/enabled, fallback to LED ON */ #define led_activity_blink led_activity_on #endif #else static inline int led_activity_on(void) { return -ENOSYS; } static inline int led_activity_off(void) { return -ENOSYS; } static inline int led_activity_blink(void) { return -ENOSYS; } #endif #endif |