1 /* 2 * Driver model for leds and led triggers 3 * 4 * Copyright (C) 2005 John Lenz <[email protected]> 5 * Copyright (C) 2005 Richard Purdie <[email protected]> 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License version 2 as 9 * published by the Free Software Foundation. 10 * 11 */ 12 #ifndef __LINUX_LEDS_H_INCLUDED 13 #define __LINUX_LEDS_H_INCLUDED 14 15 #include <linux/device.h> 16 #include <linux/kernfs.h> 17 #include <linux/list.h> 18 #include <linux/mutex.h> 19 #include <linux/rwsem.h> 20 #include <linux/spinlock.h> 21 #include <linux/timer.h> 22 #include <linux/workqueue.h> 23 24 struct device; 25 /* 26 * LED Core 27 */ 28 29 enum led_brightness { 30 LED_OFF = 0, 31 LED_ON = 1, 32 LED_HALF = 127, 33 LED_FULL = 255, 34 }; 35 36 struct led_classdev { 37 const char *name; 38 enum led_brightness brightness; 39 enum led_brightness max_brightness; 40 int flags; 41 42 /* Lower 16 bits reflect status */ 43 #define LED_SUSPENDED (1 << 0) 44 #define LED_UNREGISTERING (1 << 1) 45 /* Upper 16 bits reflect control information */ 46 #define LED_CORE_SUSPENDRESUME (1 << 16) 47 #define LED_SYSFS_DISABLE (1 << 17) 48 #define LED_DEV_CAP_FLASH (1 << 18) 49 #define LED_HW_PLUGGABLE (1 << 19) 50 #define LED_PANIC_INDICATOR (1 << 20) 51 #define LED_BRIGHT_HW_CHANGED (1 << 21) 52 53 /* set_brightness_work / blink_timer flags, atomic, private. */ 54 unsigned long work_flags; 55 56 #define LED_BLINK_SW 0 57 #define LED_BLINK_ONESHOT 1 58 #define LED_BLINK_ONESHOT_STOP 2 59 #define LED_BLINK_INVERT 3 60 #define LED_BLINK_BRIGHTNESS_CHANGE 4 61 #define LED_BLINK_DISABLE 5 62 63 /* Set LED brightness level 64 * Must not sleep. Use brightness_set_blocking for drivers 65 * that can sleep while setting brightness. 66 */ 67 void (*brightness_set)(struct led_classdev *led_cdev, 68 enum led_brightness brightness); 69 /* 70 * Set LED brightness level immediately - it can block the caller for 71 * the time required for accessing a LED device register. 72 */ 73 int (*brightness_set_blocking)(struct led_classdev *led_cdev, 74 enum led_brightness brightness); 75 /* Get LED brightness level */ 76 enum led_brightness (*brightness_get)(struct led_classdev *led_cdev); 77 78 /* 79 * Activate hardware accelerated blink, delays are in milliseconds 80 * and if both are zero then a sensible default should be chosen. 81 * The call should adjust the timings in that case and if it can't 82 * match the values specified exactly. 83 * Deactivate blinking again when the brightness is set to LED_OFF 84 * via the brightness_set() callback. 85 */ 86 int (*blink_set)(struct led_classdev *led_cdev, 87 unsigned long *delay_on, 88 unsigned long *delay_off); 89 90 struct device *dev; 91 const struct attribute_group **groups; 92 93 struct list_head node; /* LED Device list */ 94 const char *default_trigger; /* Trigger to use */ 95 96 unsigned long blink_delay_on, blink_delay_off; 97 struct timer_list blink_timer; 98 int blink_brightness; 99 int new_blink_brightness; 100 void (*flash_resume)(struct led_classdev *led_cdev); 101 102 struct work_struct set_brightness_work; 103 int delayed_set_value; 104 105 #ifdef CONFIG_LEDS_TRIGGERS 106 /* Protects the trigger data below */ 107 struct rw_semaphore trigger_lock; 108 109 struct led_trigger *trigger; 110 struct list_head trig_list; 111 void *trigger_data; 112 /* true if activated - deactivate routine uses it to do cleanup */ 113 bool activated; 114 #endif 115 116 #ifdef CONFIG_LEDS_BRIGHTNESS_HW_CHANGED 117 int brightness_hw_changed; 118 struct kernfs_node *brightness_hw_changed_kn; 119 #endif 120 121 /* Ensures consistent access to the LED Flash Class device */ 122 struct mutex led_access; 123 }; 124 125 extern int of_led_classdev_register(struct device *parent, 126 struct device_node *np, 127 struct led_classdev *led_cdev); 128 #define led_classdev_register(parent, led_cdev) \ 129 of_led_classdev_register(parent, NULL, led_cdev) 130 extern int devm_of_led_classdev_register(struct device *parent, 131 struct device_node *np, 132 struct led_classdev *led_cdev); 133 #define devm_led_classdev_register(parent, led_cdev) \ 134 devm_of_led_classdev_register(parent, NULL, led_cdev) 135 extern void led_classdev_unregister(struct led_classdev *led_cdev); 136 extern void devm_led_classdev_unregister(struct device *parent, 137 struct led_classdev *led_cdev); 138 extern void led_classdev_suspend(struct led_classdev *led_cdev); 139 extern void led_classdev_resume(struct led_classdev *led_cdev); 140 141 /** 142 * led_blink_set - set blinking with software fallback 143 * @led_cdev: the LED to start blinking 144 * @delay_on: the time it should be on (in ms) 145 * @delay_off: the time it should ble off (in ms) 146 * 147 * This function makes the LED blink, attempting to use the 148 * hardware acceleration if possible, but falling back to 149 * software blinking if there is no hardware blinking or if 150 * the LED refuses the passed values. 151 * 152 * Note that if software blinking is active, simply calling 153 * led_cdev->brightness_set() will not stop the blinking, 154 * use led_classdev_brightness_set() instead. 155 */ 156 extern void led_blink_set(struct led_classdev *led_cdev, 157 unsigned long *delay_on, 158 unsigned long *delay_off); 159 /** 160 * led_blink_set_oneshot - do a oneshot software blink 161 * @led_cdev: the LED to start blinking 162 * @delay_on: the time it should be on (in ms) 163 * @delay_off: the time it should ble off (in ms) 164 * @invert: blink off, then on, leaving the led on 165 * 166 * This function makes the LED blink one time for delay_on + 167 * delay_off time, ignoring the request if another one-shot 168 * blink is already in progress. 169 * 170 * If invert is set, led blinks for delay_off first, then for 171 * delay_on and leave the led on after the on-off cycle. 172 */ 173 extern void led_blink_set_oneshot(struct led_classdev *led_cdev, 174 unsigned long *delay_on, 175 unsigned long *delay_off, 176 int invert); 177 /** 178 * led_set_brightness - set LED brightness 179 * @led_cdev: the LED to set 180 * @brightness: the brightness to set it to 181 * 182 * Set an LED's brightness, and, if necessary, cancel the 183 * software blink timer that implements blinking when the 184 * hardware doesn't. This function is guaranteed not to sleep. 185 */ 186 extern void led_set_brightness(struct led_classdev *led_cdev, 187 enum led_brightness brightness); 188 189 /** 190 * led_set_brightness_sync - set LED brightness synchronously 191 * @led_cdev: the LED to set 192 * @brightness: the brightness to set it to 193 * 194 * Set an LED's brightness immediately. This function will block 195 * the caller for the time required for accessing device registers, 196 * and it can sleep. 197 * 198 * Returns: 0 on success or negative error value on failure 199 */ 200 extern int led_set_brightness_sync(struct led_classdev *led_cdev, 201 enum led_brightness value); 202 203 /** 204 * led_update_brightness - update LED brightness 205 * @led_cdev: the LED to query 206 * 207 * Get an LED's current brightness and update led_cdev->brightness 208 * member with the obtained value. 209 * 210 * Returns: 0 on success or negative error value on failure 211 */ 212 extern int led_update_brightness(struct led_classdev *led_cdev); 213 214 /** 215 * led_sysfs_disable - disable LED sysfs interface 216 * @led_cdev: the LED to set 217 * 218 * Disable the led_cdev's sysfs interface. 219 */ 220 extern void led_sysfs_disable(struct led_classdev *led_cdev); 221 222 /** 223 * led_sysfs_enable - enable LED sysfs interface 224 * @led_cdev: the LED to set 225 * 226 * Enable the led_cdev's sysfs interface. 227 */ 228 extern void led_sysfs_enable(struct led_classdev *led_cdev); 229 230 /** 231 * led_sysfs_is_disabled - check if LED sysfs interface is disabled 232 * @led_cdev: the LED to query 233 * 234 * Returns: true if the led_cdev's sysfs interface is disabled. 235 */ 236 static inline bool led_sysfs_is_disabled(struct led_classdev *led_cdev) 237 { 238 return led_cdev->flags & LED_SYSFS_DISABLE; 239 } 240 241 /* 242 * LED Triggers 243 */ 244 /* Registration functions for simple triggers */ 245 #define DEFINE_LED_TRIGGER(x) static struct led_trigger *x; 246 #define DEFINE_LED_TRIGGER_GLOBAL(x) struct led_trigger *x; 247 248 #ifdef CONFIG_LEDS_TRIGGERS 249 250 #define TRIG_NAME_MAX 50 251 252 struct led_trigger { 253 /* Trigger Properties */ 254 const char *name; 255 void (*activate)(struct led_classdev *led_cdev); 256 void (*deactivate)(struct led_classdev *led_cdev); 257 258 /* LEDs under control by this trigger (for simple triggers) */ 259 rwlock_t leddev_list_lock; 260 struct list_head led_cdevs; 261 262 /* Link to next registered trigger */ 263 struct list_head next_trig; 264 }; 265 266 ssize_t led_trigger_store(struct device *dev, struct device_attribute *attr, 267 const char *buf, size_t count); 268 ssize_t led_trigger_show(struct device *dev, struct device_attribute *attr, 269 char *buf); 270 271 /* Registration functions for complex triggers */ 272 extern int led_trigger_register(struct led_trigger *trigger); 273 extern void led_trigger_unregister(struct led_trigger *trigger); 274 extern int devm_led_trigger_register(struct device *dev, 275 struct led_trigger *trigger); 276 277 extern void led_trigger_register_simple(const char *name, 278 struct led_trigger **trigger); 279 extern void led_trigger_unregister_simple(struct led_trigger *trigger); 280 extern void led_trigger_event(struct led_trigger *trigger, 281 enum led_brightness event); 282 extern void led_trigger_blink(struct led_trigger *trigger, 283 unsigned long *delay_on, 284 unsigned long *delay_off); 285 extern void led_trigger_blink_oneshot(struct led_trigger *trigger, 286 unsigned long *delay_on, 287 unsigned long *delay_off, 288 int invert); 289 extern void led_trigger_set_default(struct led_classdev *led_cdev); 290 extern void led_trigger_set(struct led_classdev *led_cdev, 291 struct led_trigger *trigger); 292 extern void led_trigger_remove(struct led_classdev *led_cdev); 293 294 static inline void *led_get_trigger_data(struct led_classdev *led_cdev) 295 { 296 return led_cdev->trigger_data; 297 } 298 299 /** 300 * led_trigger_rename_static - rename a trigger 301 * @name: the new trigger name 302 * @trig: the LED trigger to rename 303 * 304 * Change a LED trigger name by copying the string passed in 305 * name into current trigger name, which MUST be large 306 * enough for the new string. 307 * 308 * Note that name must NOT point to the same string used 309 * during LED registration, as that could lead to races. 310 * 311 * This is meant to be used on triggers with statically 312 * allocated name. 313 */ 314 extern void led_trigger_rename_static(const char *name, 315 struct led_trigger *trig); 316 317 #else 318 319 /* Trigger has no members */ 320 struct led_trigger {}; 321 322 /* Trigger inline empty functions */ 323 static inline void led_trigger_register_simple(const char *name, 324 struct led_trigger **trigger) {} 325 static inline void led_trigger_unregister_simple(struct led_trigger *trigger) {} 326 static inline void led_trigger_event(struct led_trigger *trigger, 327 enum led_brightness event) {} 328 static inline void led_trigger_blink(struct led_trigger *trigger, 329 unsigned long *delay_on, 330 unsigned long *delay_off) {} 331 static inline void led_trigger_blink_oneshot(struct led_trigger *trigger, 332 unsigned long *delay_on, 333 unsigned long *delay_off, 334 int invert) {} 335 static inline void led_trigger_set_default(struct led_classdev *led_cdev) {} 336 static inline void led_trigger_set(struct led_classdev *led_cdev, 337 struct led_trigger *trigger) {} 338 static inline void led_trigger_remove(struct led_classdev *led_cdev) {} 339 static inline void *led_get_trigger_data(struct led_classdev *led_cdev) 340 { 341 return NULL; 342 } 343 344 #endif /* CONFIG_LEDS_TRIGGERS */ 345 346 /* Trigger specific functions */ 347 #ifdef CONFIG_LEDS_TRIGGER_DISK 348 extern void ledtrig_disk_activity(void); 349 #else 350 static inline void ledtrig_disk_activity(void) {} 351 #endif 352 353 #ifdef CONFIG_LEDS_TRIGGER_MTD 354 extern void ledtrig_mtd_activity(void); 355 #else 356 static inline void ledtrig_mtd_activity(void) {} 357 #endif 358 359 #if defined(CONFIG_LEDS_TRIGGER_CAMERA) || defined(CONFIG_LEDS_TRIGGER_CAMERA_MODULE) 360 extern void ledtrig_flash_ctrl(bool on); 361 extern void ledtrig_torch_ctrl(bool on); 362 #else 363 static inline void ledtrig_flash_ctrl(bool on) {} 364 static inline void ledtrig_torch_ctrl(bool on) {} 365 #endif 366 367 /* 368 * Generic LED platform data for describing LED names and default triggers. 369 */ 370 struct led_info { 371 const char *name; 372 const char *default_trigger; 373 int flags; 374 }; 375 376 struct led_platform_data { 377 int num_leds; 378 struct led_info *leds; 379 }; 380 381 struct gpio_desc; 382 typedef int (*gpio_blink_set_t)(struct gpio_desc *desc, int state, 383 unsigned long *delay_on, 384 unsigned long *delay_off); 385 386 /* For the leds-gpio driver */ 387 struct gpio_led { 388 const char *name; 389 const char *default_trigger; 390 unsigned gpio; 391 unsigned active_low : 1; 392 unsigned retain_state_suspended : 1; 393 unsigned panic_indicator : 1; 394 unsigned default_state : 2; 395 /* default_state should be one of LEDS_GPIO_DEFSTATE_(ON|OFF|KEEP) */ 396 struct gpio_desc *gpiod; 397 }; 398 #define LEDS_GPIO_DEFSTATE_OFF 0 399 #define LEDS_GPIO_DEFSTATE_ON 1 400 #define LEDS_GPIO_DEFSTATE_KEEP 2 401 402 struct gpio_led_platform_data { 403 int num_leds; 404 const struct gpio_led *leds; 405 406 #define GPIO_LED_NO_BLINK_LOW 0 /* No blink GPIO state low */ 407 #define GPIO_LED_NO_BLINK_HIGH 1 /* No blink GPIO state high */ 408 #define GPIO_LED_BLINK 2 /* Please, blink */ 409 gpio_blink_set_t gpio_blink_set; 410 }; 411 412 #ifdef CONFIG_NEW_LEDS 413 struct platform_device *gpio_led_register_device( 414 int id, const struct gpio_led_platform_data *pdata); 415 #else 416 static inline struct platform_device *gpio_led_register_device( 417 int id, const struct gpio_led_platform_data *pdata) 418 { 419 return 0; 420 } 421 #endif 422 423 enum cpu_led_event { 424 CPU_LED_IDLE_START, /* CPU enters idle */ 425 CPU_LED_IDLE_END, /* CPU idle ends */ 426 CPU_LED_START, /* Machine starts, especially resume */ 427 CPU_LED_STOP, /* Machine stops, especially suspend */ 428 CPU_LED_HALTED, /* Machine shutdown */ 429 }; 430 #ifdef CONFIG_LEDS_TRIGGER_CPU 431 extern void ledtrig_cpu(enum cpu_led_event evt); 432 #else 433 static inline void ledtrig_cpu(enum cpu_led_event evt) 434 { 435 return; 436 } 437 #endif 438 439 #ifdef CONFIG_LEDS_BRIGHTNESS_HW_CHANGED 440 extern void led_classdev_notify_brightness_hw_changed( 441 struct led_classdev *led_cdev, enum led_brightness brightness); 442 #else 443 static inline void led_classdev_notify_brightness_hw_changed( 444 struct led_classdev *led_cdev, enum led_brightness brightness) { } 445 #endif 446 447 #endif /* __LINUX_LEDS_H_INCLUDED */ 448