at v4.11 14 kB view raw
1/* 2 * Driver model for leds and led triggers 3 * 4 * Copyright (C) 2005 John Lenz <lenz@cs.wisc.edu> 5 * Copyright (C) 2005 Richard Purdie <rpurdie@openedhand.com> 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 24struct device; 25/* 26 * LED Core 27 */ 28 29enum led_brightness { 30 LED_OFF = 0, 31 LED_ON = 1, 32 LED_HALF = 127, 33 LED_FULL = 255, 34}; 35 36struct 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 125extern int led_classdev_register(struct device *parent, 126 struct led_classdev *led_cdev); 127extern int devm_led_classdev_register(struct device *parent, 128 struct led_classdev *led_cdev); 129extern void led_classdev_unregister(struct led_classdev *led_cdev); 130extern void devm_led_classdev_unregister(struct device *parent, 131 struct led_classdev *led_cdev); 132extern void led_classdev_suspend(struct led_classdev *led_cdev); 133extern void led_classdev_resume(struct led_classdev *led_cdev); 134 135/** 136 * led_blink_set - set blinking with software fallback 137 * @led_cdev: the LED to start blinking 138 * @delay_on: the time it should be on (in ms) 139 * @delay_off: the time it should ble off (in ms) 140 * 141 * This function makes the LED blink, attempting to use the 142 * hardware acceleration if possible, but falling back to 143 * software blinking if there is no hardware blinking or if 144 * the LED refuses the passed values. 145 * 146 * Note that if software blinking is active, simply calling 147 * led_cdev->brightness_set() will not stop the blinking, 148 * use led_classdev_brightness_set() instead. 149 */ 150extern void led_blink_set(struct led_classdev *led_cdev, 151 unsigned long *delay_on, 152 unsigned long *delay_off); 153/** 154 * led_blink_set_oneshot - do a oneshot software blink 155 * @led_cdev: the LED to start blinking 156 * @delay_on: the time it should be on (in ms) 157 * @delay_off: the time it should ble off (in ms) 158 * @invert: blink off, then on, leaving the led on 159 * 160 * This function makes the LED blink one time for delay_on + 161 * delay_off time, ignoring the request if another one-shot 162 * blink is already in progress. 163 * 164 * If invert is set, led blinks for delay_off first, then for 165 * delay_on and leave the led on after the on-off cycle. 166 */ 167extern void led_blink_set_oneshot(struct led_classdev *led_cdev, 168 unsigned long *delay_on, 169 unsigned long *delay_off, 170 int invert); 171/** 172 * led_set_brightness - set LED brightness 173 * @led_cdev: the LED to set 174 * @brightness: the brightness to set it to 175 * 176 * Set an LED's brightness, and, if necessary, cancel the 177 * software blink timer that implements blinking when the 178 * hardware doesn't. This function is guaranteed not to sleep. 179 */ 180extern void led_set_brightness(struct led_classdev *led_cdev, 181 enum led_brightness brightness); 182 183/** 184 * led_set_brightness_sync - set LED brightness synchronously 185 * @led_cdev: the LED to set 186 * @brightness: the brightness to set it to 187 * 188 * Set an LED's brightness immediately. This function will block 189 * the caller for the time required for accessing device registers, 190 * and it can sleep. 191 * 192 * Returns: 0 on success or negative error value on failure 193 */ 194extern int led_set_brightness_sync(struct led_classdev *led_cdev, 195 enum led_brightness value); 196 197/** 198 * led_update_brightness - update LED brightness 199 * @led_cdev: the LED to query 200 * 201 * Get an LED's current brightness and update led_cdev->brightness 202 * member with the obtained value. 203 * 204 * Returns: 0 on success or negative error value on failure 205 */ 206extern int led_update_brightness(struct led_classdev *led_cdev); 207 208/** 209 * led_sysfs_disable - disable LED sysfs interface 210 * @led_cdev: the LED to set 211 * 212 * Disable the led_cdev's sysfs interface. 213 */ 214extern void led_sysfs_disable(struct led_classdev *led_cdev); 215 216/** 217 * led_sysfs_enable - enable LED sysfs interface 218 * @led_cdev: the LED to set 219 * 220 * Enable the led_cdev's sysfs interface. 221 */ 222extern void led_sysfs_enable(struct led_classdev *led_cdev); 223 224/** 225 * led_sysfs_is_disabled - check if LED sysfs interface is disabled 226 * @led_cdev: the LED to query 227 * 228 * Returns: true if the led_cdev's sysfs interface is disabled. 229 */ 230static inline bool led_sysfs_is_disabled(struct led_classdev *led_cdev) 231{ 232 return led_cdev->flags & LED_SYSFS_DISABLE; 233} 234 235/* 236 * LED Triggers 237 */ 238/* Registration functions for simple triggers */ 239#define DEFINE_LED_TRIGGER(x) static struct led_trigger *x; 240#define DEFINE_LED_TRIGGER_GLOBAL(x) struct led_trigger *x; 241 242#ifdef CONFIG_LEDS_TRIGGERS 243 244#define TRIG_NAME_MAX 50 245 246struct led_trigger { 247 /* Trigger Properties */ 248 const char *name; 249 void (*activate)(struct led_classdev *led_cdev); 250 void (*deactivate)(struct led_classdev *led_cdev); 251 252 /* LEDs under control by this trigger (for simple triggers) */ 253 rwlock_t leddev_list_lock; 254 struct list_head led_cdevs; 255 256 /* Link to next registered trigger */ 257 struct list_head next_trig; 258}; 259 260ssize_t led_trigger_store(struct device *dev, struct device_attribute *attr, 261 const char *buf, size_t count); 262ssize_t led_trigger_show(struct device *dev, struct device_attribute *attr, 263 char *buf); 264 265/* Registration functions for complex triggers */ 266extern int led_trigger_register(struct led_trigger *trigger); 267extern void led_trigger_unregister(struct led_trigger *trigger); 268extern int devm_led_trigger_register(struct device *dev, 269 struct led_trigger *trigger); 270 271extern void led_trigger_register_simple(const char *name, 272 struct led_trigger **trigger); 273extern void led_trigger_unregister_simple(struct led_trigger *trigger); 274extern void led_trigger_event(struct led_trigger *trigger, 275 enum led_brightness event); 276extern void led_trigger_blink(struct led_trigger *trigger, 277 unsigned long *delay_on, 278 unsigned long *delay_off); 279extern void led_trigger_blink_oneshot(struct led_trigger *trigger, 280 unsigned long *delay_on, 281 unsigned long *delay_off, 282 int invert); 283extern void led_trigger_set_default(struct led_classdev *led_cdev); 284extern void led_trigger_set(struct led_classdev *led_cdev, 285 struct led_trigger *trigger); 286extern void led_trigger_remove(struct led_classdev *led_cdev); 287 288static inline void *led_get_trigger_data(struct led_classdev *led_cdev) 289{ 290 return led_cdev->trigger_data; 291} 292 293/** 294 * led_trigger_rename_static - rename a trigger 295 * @name: the new trigger name 296 * @trig: the LED trigger to rename 297 * 298 * Change a LED trigger name by copying the string passed in 299 * name into current trigger name, which MUST be large 300 * enough for the new string. 301 * 302 * Note that name must NOT point to the same string used 303 * during LED registration, as that could lead to races. 304 * 305 * This is meant to be used on triggers with statically 306 * allocated name. 307 */ 308extern void led_trigger_rename_static(const char *name, 309 struct led_trigger *trig); 310 311#else 312 313/* Trigger has no members */ 314struct led_trigger {}; 315 316/* Trigger inline empty functions */ 317static inline void led_trigger_register_simple(const char *name, 318 struct led_trigger **trigger) {} 319static inline void led_trigger_unregister_simple(struct led_trigger *trigger) {} 320static inline void led_trigger_event(struct led_trigger *trigger, 321 enum led_brightness event) {} 322static inline void led_trigger_blink(struct led_trigger *trigger, 323 unsigned long *delay_on, 324 unsigned long *delay_off) {} 325static inline void led_trigger_blink_oneshot(struct led_trigger *trigger, 326 unsigned long *delay_on, 327 unsigned long *delay_off, 328 int invert) {} 329static inline void led_trigger_set_default(struct led_classdev *led_cdev) {} 330static inline void led_trigger_set(struct led_classdev *led_cdev, 331 struct led_trigger *trigger) {} 332static inline void led_trigger_remove(struct led_classdev *led_cdev) {} 333static inline void *led_get_trigger_data(struct led_classdev *led_cdev) 334{ 335 return NULL; 336} 337 338#endif /* CONFIG_LEDS_TRIGGERS */ 339 340/* Trigger specific functions */ 341#ifdef CONFIG_LEDS_TRIGGER_DISK 342extern void ledtrig_disk_activity(void); 343#else 344static inline void ledtrig_disk_activity(void) {} 345#endif 346 347#ifdef CONFIG_LEDS_TRIGGER_MTD 348extern void ledtrig_mtd_activity(void); 349#else 350static inline void ledtrig_mtd_activity(void) {} 351#endif 352 353#if defined(CONFIG_LEDS_TRIGGER_CAMERA) || defined(CONFIG_LEDS_TRIGGER_CAMERA_MODULE) 354extern void ledtrig_flash_ctrl(bool on); 355extern void ledtrig_torch_ctrl(bool on); 356#else 357static inline void ledtrig_flash_ctrl(bool on) {} 358static inline void ledtrig_torch_ctrl(bool on) {} 359#endif 360 361/* 362 * Generic LED platform data for describing LED names and default triggers. 363 */ 364struct led_info { 365 const char *name; 366 const char *default_trigger; 367 int flags; 368}; 369 370struct led_platform_data { 371 int num_leds; 372 struct led_info *leds; 373}; 374 375struct gpio_desc; 376typedef int (*gpio_blink_set_t)(struct gpio_desc *desc, int state, 377 unsigned long *delay_on, 378 unsigned long *delay_off); 379 380/* For the leds-gpio driver */ 381struct gpio_led { 382 const char *name; 383 const char *default_trigger; 384 unsigned gpio; 385 unsigned active_low : 1; 386 unsigned retain_state_suspended : 1; 387 unsigned panic_indicator : 1; 388 unsigned default_state : 2; 389 /* default_state should be one of LEDS_GPIO_DEFSTATE_(ON|OFF|KEEP) */ 390 struct gpio_desc *gpiod; 391}; 392#define LEDS_GPIO_DEFSTATE_OFF 0 393#define LEDS_GPIO_DEFSTATE_ON 1 394#define LEDS_GPIO_DEFSTATE_KEEP 2 395 396struct gpio_led_platform_data { 397 int num_leds; 398 const struct gpio_led *leds; 399 400#define GPIO_LED_NO_BLINK_LOW 0 /* No blink GPIO state low */ 401#define GPIO_LED_NO_BLINK_HIGH 1 /* No blink GPIO state high */ 402#define GPIO_LED_BLINK 2 /* Please, blink */ 403 gpio_blink_set_t gpio_blink_set; 404}; 405 406#ifdef CONFIG_NEW_LEDS 407struct platform_device *gpio_led_register_device( 408 int id, const struct gpio_led_platform_data *pdata); 409#else 410static inline struct platform_device *gpio_led_register_device( 411 int id, const struct gpio_led_platform_data *pdata) 412{ 413 return 0; 414} 415#endif 416 417enum cpu_led_event { 418 CPU_LED_IDLE_START, /* CPU enters idle */ 419 CPU_LED_IDLE_END, /* CPU idle ends */ 420 CPU_LED_START, /* Machine starts, especially resume */ 421 CPU_LED_STOP, /* Machine stops, especially suspend */ 422 CPU_LED_HALTED, /* Machine shutdown */ 423}; 424#ifdef CONFIG_LEDS_TRIGGER_CPU 425extern void ledtrig_cpu(enum cpu_led_event evt); 426#else 427static inline void ledtrig_cpu(enum cpu_led_event evt) 428{ 429 return; 430} 431#endif 432 433#ifdef CONFIG_LEDS_BRIGHTNESS_HW_CHANGED 434extern void led_classdev_notify_brightness_hw_changed( 435 struct led_classdev *led_cdev, enum led_brightness brightness); 436#else 437static inline void led_classdev_notify_brightness_hw_changed( 438 struct led_classdev *led_cdev, enum led_brightness brightness) { } 439#endif 440 441#endif /* __LINUX_LEDS_H_INCLUDED */