at v4.12 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 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) 130extern 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) 135extern void led_classdev_unregister(struct led_classdev *led_cdev); 136extern void devm_led_classdev_unregister(struct device *parent, 137 struct led_classdev *led_cdev); 138extern void led_classdev_suspend(struct led_classdev *led_cdev); 139extern 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 */ 156extern 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 */ 173extern 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 */ 186extern 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 */ 200extern 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 */ 212extern 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 */ 220extern 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 */ 228extern 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 */ 236static 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 252struct 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 266ssize_t led_trigger_store(struct device *dev, struct device_attribute *attr, 267 const char *buf, size_t count); 268ssize_t led_trigger_show(struct device *dev, struct device_attribute *attr, 269 char *buf); 270 271/* Registration functions for complex triggers */ 272extern int led_trigger_register(struct led_trigger *trigger); 273extern void led_trigger_unregister(struct led_trigger *trigger); 274extern int devm_led_trigger_register(struct device *dev, 275 struct led_trigger *trigger); 276 277extern void led_trigger_register_simple(const char *name, 278 struct led_trigger **trigger); 279extern void led_trigger_unregister_simple(struct led_trigger *trigger); 280extern void led_trigger_event(struct led_trigger *trigger, 281 enum led_brightness event); 282extern void led_trigger_blink(struct led_trigger *trigger, 283 unsigned long *delay_on, 284 unsigned long *delay_off); 285extern void led_trigger_blink_oneshot(struct led_trigger *trigger, 286 unsigned long *delay_on, 287 unsigned long *delay_off, 288 int invert); 289extern void led_trigger_set_default(struct led_classdev *led_cdev); 290extern void led_trigger_set(struct led_classdev *led_cdev, 291 struct led_trigger *trigger); 292extern void led_trigger_remove(struct led_classdev *led_cdev); 293 294static 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 */ 314extern void led_trigger_rename_static(const char *name, 315 struct led_trigger *trig); 316 317#else 318 319/* Trigger has no members */ 320struct led_trigger {}; 321 322/* Trigger inline empty functions */ 323static inline void led_trigger_register_simple(const char *name, 324 struct led_trigger **trigger) {} 325static inline void led_trigger_unregister_simple(struct led_trigger *trigger) {} 326static inline void led_trigger_event(struct led_trigger *trigger, 327 enum led_brightness event) {} 328static inline void led_trigger_blink(struct led_trigger *trigger, 329 unsigned long *delay_on, 330 unsigned long *delay_off) {} 331static inline void led_trigger_blink_oneshot(struct led_trigger *trigger, 332 unsigned long *delay_on, 333 unsigned long *delay_off, 334 int invert) {} 335static inline void led_trigger_set_default(struct led_classdev *led_cdev) {} 336static inline void led_trigger_set(struct led_classdev *led_cdev, 337 struct led_trigger *trigger) {} 338static inline void led_trigger_remove(struct led_classdev *led_cdev) {} 339static 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 348extern void ledtrig_disk_activity(void); 349#else 350static inline void ledtrig_disk_activity(void) {} 351#endif 352 353#ifdef CONFIG_LEDS_TRIGGER_MTD 354extern void ledtrig_mtd_activity(void); 355#else 356static inline void ledtrig_mtd_activity(void) {} 357#endif 358 359#if defined(CONFIG_LEDS_TRIGGER_CAMERA) || defined(CONFIG_LEDS_TRIGGER_CAMERA_MODULE) 360extern void ledtrig_flash_ctrl(bool on); 361extern void ledtrig_torch_ctrl(bool on); 362#else 363static inline void ledtrig_flash_ctrl(bool on) {} 364static inline void ledtrig_torch_ctrl(bool on) {} 365#endif 366 367/* 368 * Generic LED platform data for describing LED names and default triggers. 369 */ 370struct led_info { 371 const char *name; 372 const char *default_trigger; 373 int flags; 374}; 375 376struct led_platform_data { 377 int num_leds; 378 struct led_info *leds; 379}; 380 381struct gpio_desc; 382typedef 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 */ 387struct 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 402struct 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 413struct platform_device *gpio_led_register_device( 414 int id, const struct gpio_led_platform_data *pdata); 415#else 416static 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 423enum 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 431extern void ledtrig_cpu(enum cpu_led_event evt); 432#else 433static inline void ledtrig_cpu(enum cpu_led_event evt) 434{ 435 return; 436} 437#endif 438 439#ifdef CONFIG_LEDS_BRIGHTNESS_HW_CHANGED 440extern void led_classdev_notify_brightness_hw_changed( 441 struct led_classdev *led_cdev, enum led_brightness brightness); 442#else 443static 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 */