Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/cooloney/linux-leds

Pull LED subsystem update from Bryan Wu:
"The big change of LED subsystem is introducing a new LED class for
Flash type LEDs which will be used for V4L2 subsystem.

Also we got some cleanup and fixes"

* 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/cooloney/linux-leds:
leds: leds-gpio: Pass on error codes unmodified
DT: leds: Add led-sources property
leds: Add LED Flash class extension to the LED subsystem
leds: leds-mc13783: Use of_get_child_by_name() instead of refcount hack
leds: Use setup_timer
leds: Don't allow brightness values greater than max_brightness
DT: leds: Add flash LED devices related properties

+748 -8
+30
Documentation/devicetree/bindings/leds/common.txt
··· 1 1 Common leds properties. 2 2 3 + LED and flash LED devices provide the same basic functionality as current 4 + regulators, but extended with LED and flash LED specific features like 5 + blinking patterns, flash timeout, flash faults and external flash strobe mode. 6 + 7 + Many LED devices expose more than one current output that can be connected 8 + to one or more discrete LED component. Since the arrangement of connections 9 + can influence the way of the LED device initialization, the LED components 10 + have to be tightly coupled with the LED device binding. They are represented 11 + by child nodes of the parent LED device binding. 12 + 3 13 Optional properties for child nodes: 14 + - led-sources : List of device current outputs the LED is connected to. The 15 + outputs are identified by the numbers that must be defined 16 + in the LED device binding documentation. 4 17 - label : The label for this LED. If omitted, the label is 5 18 taken from the node name (excluding the unit address). 6 19 ··· 27 14 "ide-disk" - LED indicates disk activity 28 15 "timer" - LED flashes at a fixed, configurable rate 29 16 17 + - max-microamp : maximum intensity in microamperes of the LED 18 + (torch LED for flash devices) 19 + - flash-max-microamp : maximum intensity in microamperes of the 20 + flash LED; it is mandatory if the LED should 21 + support the flash mode 22 + - flash-timeout-us : timeout in microseconds after which the flash 23 + LED is turned off 24 + 25 + 30 26 Examples: 31 27 32 28 system-status { 33 29 label = "Status"; 34 30 linux,default-trigger = "heartbeat"; 35 31 ... 32 + }; 33 + 34 + camera-flash { 35 + label = "Flash"; 36 + led-sources = <0>, <1>; 37 + max-microamp = <50000>; 38 + flash-max-microamp = <320000>; 39 + flash-timeout-us = <500000>; 36 40 };
+10
drivers/leds/Kconfig
··· 22 22 This option enables the led sysfs class in /sys/class/leds. You'll 23 23 need this to do anything useful with LEDs. If unsure, say N. 24 24 25 + config LEDS_CLASS_FLASH 26 + tristate "LED Flash Class Support" 27 + depends on LEDS_CLASS 28 + help 29 + This option enables the flash led sysfs class in /sys/class/leds. 30 + It wrapps LED Class and adds flash LEDs specific sysfs attributes 31 + and kernel internal API to it. You'll need this to provide support 32 + for the flash related features of a LED device. It can be built 33 + as a module. 34 + 25 35 comment "LED drivers" 26 36 27 37 config LEDS_88PM860X
+1
drivers/leds/Makefile
··· 2 2 # LED Core 3 3 obj-$(CONFIG_NEW_LEDS) += led-core.o 4 4 obj-$(CONFIG_LEDS_CLASS) += led-class.o 5 + obj-$(CONFIG_LEDS_CLASS_FLASH) += led-class-flash.o 5 6 obj-$(CONFIG_LEDS_TRIGGERS) += led-triggers.o 6 7 7 8 # LED Platform Drivers
+486
drivers/leds/led-class-flash.c
··· 1 + /* 2 + * LED Flash class interface 3 + * 4 + * Copyright (C) 2015 Samsung Electronics Co., Ltd. 5 + * Author: Jacek Anaszewski <j.anaszewski@samsung.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 + #include <linux/device.h> 13 + #include <linux/init.h> 14 + #include <linux/led-class-flash.h> 15 + #include <linux/leds.h> 16 + #include <linux/module.h> 17 + #include <linux/slab.h> 18 + #include "leds.h" 19 + 20 + #define has_flash_op(fled_cdev, op) \ 21 + (fled_cdev && fled_cdev->ops->op) 22 + 23 + #define call_flash_op(fled_cdev, op, args...) \ 24 + ((has_flash_op(fled_cdev, op)) ? \ 25 + (fled_cdev->ops->op(fled_cdev, args)) : \ 26 + -EINVAL) 27 + 28 + static const char * const led_flash_fault_names[] = { 29 + "led-over-voltage", 30 + "flash-timeout-exceeded", 31 + "controller-over-temperature", 32 + "controller-short-circuit", 33 + "led-power-supply-over-current", 34 + "indicator-led-fault", 35 + "led-under-voltage", 36 + "controller-under-voltage", 37 + "led-over-temperature", 38 + }; 39 + 40 + static ssize_t flash_brightness_store(struct device *dev, 41 + struct device_attribute *attr, const char *buf, size_t size) 42 + { 43 + struct led_classdev *led_cdev = dev_get_drvdata(dev); 44 + struct led_classdev_flash *fled_cdev = lcdev_to_flcdev(led_cdev); 45 + unsigned long state; 46 + ssize_t ret; 47 + 48 + mutex_lock(&led_cdev->led_access); 49 + 50 + if (led_sysfs_is_disabled(led_cdev)) { 51 + ret = -EBUSY; 52 + goto unlock; 53 + } 54 + 55 + ret = kstrtoul(buf, 10, &state); 56 + if (ret) 57 + goto unlock; 58 + 59 + ret = led_set_flash_brightness(fled_cdev, state); 60 + if (ret < 0) 61 + goto unlock; 62 + 63 + ret = size; 64 + unlock: 65 + mutex_unlock(&led_cdev->led_access); 66 + return ret; 67 + } 68 + 69 + static ssize_t flash_brightness_show(struct device *dev, 70 + struct device_attribute *attr, char *buf) 71 + { 72 + struct led_classdev *led_cdev = dev_get_drvdata(dev); 73 + struct led_classdev_flash *fled_cdev = lcdev_to_flcdev(led_cdev); 74 + 75 + /* no lock needed for this */ 76 + led_update_flash_brightness(fled_cdev); 77 + 78 + return sprintf(buf, "%u\n", fled_cdev->brightness.val); 79 + } 80 + static DEVICE_ATTR_RW(flash_brightness); 81 + 82 + static ssize_t max_flash_brightness_show(struct device *dev, 83 + struct device_attribute *attr, char *buf) 84 + { 85 + struct led_classdev *led_cdev = dev_get_drvdata(dev); 86 + struct led_classdev_flash *fled_cdev = lcdev_to_flcdev(led_cdev); 87 + 88 + return sprintf(buf, "%u\n", fled_cdev->brightness.max); 89 + } 90 + static DEVICE_ATTR_RO(max_flash_brightness); 91 + 92 + static ssize_t flash_strobe_store(struct device *dev, 93 + struct device_attribute *attr, const char *buf, size_t size) 94 + { 95 + struct led_classdev *led_cdev = dev_get_drvdata(dev); 96 + struct led_classdev_flash *fled_cdev = lcdev_to_flcdev(led_cdev); 97 + unsigned long state; 98 + ssize_t ret = -EINVAL; 99 + 100 + mutex_lock(&led_cdev->led_access); 101 + 102 + if (led_sysfs_is_disabled(led_cdev)) { 103 + ret = -EBUSY; 104 + goto unlock; 105 + } 106 + 107 + ret = kstrtoul(buf, 10, &state); 108 + if (ret) 109 + goto unlock; 110 + 111 + if (state < 0 || state > 1) { 112 + ret = -EINVAL; 113 + goto unlock; 114 + } 115 + 116 + ret = led_set_flash_strobe(fled_cdev, state); 117 + if (ret < 0) 118 + goto unlock; 119 + ret = size; 120 + unlock: 121 + mutex_unlock(&led_cdev->led_access); 122 + return ret; 123 + } 124 + 125 + static ssize_t flash_strobe_show(struct device *dev, 126 + struct device_attribute *attr, char *buf) 127 + { 128 + struct led_classdev *led_cdev = dev_get_drvdata(dev); 129 + struct led_classdev_flash *fled_cdev = lcdev_to_flcdev(led_cdev); 130 + bool state; 131 + int ret; 132 + 133 + /* no lock needed for this */ 134 + ret = led_get_flash_strobe(fled_cdev, &state); 135 + if (ret < 0) 136 + return ret; 137 + 138 + return sprintf(buf, "%u\n", state); 139 + } 140 + static DEVICE_ATTR_RW(flash_strobe); 141 + 142 + static ssize_t flash_timeout_store(struct device *dev, 143 + struct device_attribute *attr, const char *buf, size_t size) 144 + { 145 + struct led_classdev *led_cdev = dev_get_drvdata(dev); 146 + struct led_classdev_flash *fled_cdev = lcdev_to_flcdev(led_cdev); 147 + unsigned long flash_timeout; 148 + ssize_t ret; 149 + 150 + mutex_lock(&led_cdev->led_access); 151 + 152 + if (led_sysfs_is_disabled(led_cdev)) { 153 + ret = -EBUSY; 154 + goto unlock; 155 + } 156 + 157 + ret = kstrtoul(buf, 10, &flash_timeout); 158 + if (ret) 159 + goto unlock; 160 + 161 + ret = led_set_flash_timeout(fled_cdev, flash_timeout); 162 + if (ret < 0) 163 + goto unlock; 164 + 165 + ret = size; 166 + unlock: 167 + mutex_unlock(&led_cdev->led_access); 168 + return ret; 169 + } 170 + 171 + static ssize_t flash_timeout_show(struct device *dev, 172 + struct device_attribute *attr, char *buf) 173 + { 174 + struct led_classdev *led_cdev = dev_get_drvdata(dev); 175 + struct led_classdev_flash *fled_cdev = lcdev_to_flcdev(led_cdev); 176 + 177 + return sprintf(buf, "%u\n", fled_cdev->timeout.val); 178 + } 179 + static DEVICE_ATTR_RW(flash_timeout); 180 + 181 + static ssize_t max_flash_timeout_show(struct device *dev, 182 + struct device_attribute *attr, char *buf) 183 + { 184 + struct led_classdev *led_cdev = dev_get_drvdata(dev); 185 + struct led_classdev_flash *fled_cdev = lcdev_to_flcdev(led_cdev); 186 + 187 + return sprintf(buf, "%u\n", fled_cdev->timeout.max); 188 + } 189 + static DEVICE_ATTR_RO(max_flash_timeout); 190 + 191 + static ssize_t flash_fault_show(struct device *dev, 192 + struct device_attribute *attr, char *buf) 193 + { 194 + struct led_classdev *led_cdev = dev_get_drvdata(dev); 195 + struct led_classdev_flash *fled_cdev = lcdev_to_flcdev(led_cdev); 196 + u32 fault, mask = 0x1; 197 + char *pbuf = buf; 198 + int i, ret, buf_len; 199 + 200 + ret = led_get_flash_fault(fled_cdev, &fault); 201 + if (ret < 0) 202 + return -EINVAL; 203 + 204 + *buf = '\0'; 205 + 206 + for (i = 0; i < LED_NUM_FLASH_FAULTS; ++i) { 207 + if (fault & mask) { 208 + buf_len = sprintf(pbuf, "%s ", 209 + led_flash_fault_names[i]); 210 + pbuf += buf_len; 211 + } 212 + mask <<= 1; 213 + } 214 + 215 + return sprintf(buf, "%s\n", buf); 216 + } 217 + static DEVICE_ATTR_RO(flash_fault); 218 + 219 + static ssize_t available_sync_leds_show(struct device *dev, 220 + struct device_attribute *attr, char *buf) 221 + { 222 + struct led_classdev *led_cdev = dev_get_drvdata(dev); 223 + struct led_classdev_flash *fled_cdev = lcdev_to_flcdev(led_cdev); 224 + char *pbuf = buf; 225 + int i, buf_len; 226 + 227 + buf_len = sprintf(pbuf, "[0: none] "); 228 + pbuf += buf_len; 229 + 230 + for (i = 0; i < fled_cdev->num_sync_leds; ++i) { 231 + buf_len = sprintf(pbuf, "[%d: %s] ", i + 1, 232 + fled_cdev->sync_leds[i]->led_cdev.name); 233 + pbuf += buf_len; 234 + } 235 + 236 + return sprintf(buf, "%s\n", buf); 237 + } 238 + static DEVICE_ATTR_RO(available_sync_leds); 239 + 240 + static ssize_t flash_sync_strobe_store(struct device *dev, 241 + struct device_attribute *attr, const char *buf, size_t size) 242 + { 243 + struct led_classdev *led_cdev = dev_get_drvdata(dev); 244 + struct led_classdev_flash *fled_cdev = lcdev_to_flcdev(led_cdev); 245 + unsigned long led_id; 246 + ssize_t ret; 247 + 248 + mutex_lock(&led_cdev->led_access); 249 + 250 + if (led_sysfs_is_disabled(led_cdev)) { 251 + ret = -EBUSY; 252 + goto unlock; 253 + } 254 + 255 + ret = kstrtoul(buf, 10, &led_id); 256 + if (ret) 257 + goto unlock; 258 + 259 + if (led_id > fled_cdev->num_sync_leds) { 260 + ret = -ERANGE; 261 + goto unlock; 262 + } 263 + 264 + fled_cdev->sync_led_id = led_id; 265 + 266 + ret = size; 267 + unlock: 268 + mutex_unlock(&led_cdev->led_access); 269 + return ret; 270 + } 271 + 272 + static ssize_t flash_sync_strobe_show(struct device *dev, 273 + struct device_attribute *attr, char *buf) 274 + { 275 + struct led_classdev *led_cdev = dev_get_drvdata(dev); 276 + struct led_classdev_flash *fled_cdev = lcdev_to_flcdev(led_cdev); 277 + int sled_id = fled_cdev->sync_led_id; 278 + char *sync_led_name = "none"; 279 + 280 + if (fled_cdev->sync_led_id > 0) 281 + sync_led_name = (char *) 282 + fled_cdev->sync_leds[sled_id - 1]->led_cdev.name; 283 + 284 + return sprintf(buf, "[%d: %s]\n", sled_id, sync_led_name); 285 + } 286 + static DEVICE_ATTR_RW(flash_sync_strobe); 287 + 288 + static struct attribute *led_flash_strobe_attrs[] = { 289 + &dev_attr_flash_strobe.attr, 290 + NULL, 291 + }; 292 + 293 + static struct attribute *led_flash_timeout_attrs[] = { 294 + &dev_attr_flash_timeout.attr, 295 + &dev_attr_max_flash_timeout.attr, 296 + NULL, 297 + }; 298 + 299 + static struct attribute *led_flash_brightness_attrs[] = { 300 + &dev_attr_flash_brightness.attr, 301 + &dev_attr_max_flash_brightness.attr, 302 + NULL, 303 + }; 304 + 305 + static struct attribute *led_flash_fault_attrs[] = { 306 + &dev_attr_flash_fault.attr, 307 + NULL, 308 + }; 309 + 310 + static struct attribute *led_flash_sync_strobe_attrs[] = { 311 + &dev_attr_available_sync_leds.attr, 312 + &dev_attr_flash_sync_strobe.attr, 313 + NULL, 314 + }; 315 + 316 + static const struct attribute_group led_flash_strobe_group = { 317 + .attrs = led_flash_strobe_attrs, 318 + }; 319 + 320 + static const struct attribute_group led_flash_timeout_group = { 321 + .attrs = led_flash_timeout_attrs, 322 + }; 323 + 324 + static const struct attribute_group led_flash_brightness_group = { 325 + .attrs = led_flash_brightness_attrs, 326 + }; 327 + 328 + static const struct attribute_group led_flash_fault_group = { 329 + .attrs = led_flash_fault_attrs, 330 + }; 331 + 332 + static const struct attribute_group led_flash_sync_strobe_group = { 333 + .attrs = led_flash_sync_strobe_attrs, 334 + }; 335 + 336 + static void led_flash_resume(struct led_classdev *led_cdev) 337 + { 338 + struct led_classdev_flash *fled_cdev = lcdev_to_flcdev(led_cdev); 339 + 340 + call_flash_op(fled_cdev, flash_brightness_set, 341 + fled_cdev->brightness.val); 342 + call_flash_op(fled_cdev, timeout_set, fled_cdev->timeout.val); 343 + } 344 + 345 + static void led_flash_init_sysfs_groups(struct led_classdev_flash *fled_cdev) 346 + { 347 + struct led_classdev *led_cdev = &fled_cdev->led_cdev; 348 + const struct led_flash_ops *ops = fled_cdev->ops; 349 + const struct attribute_group **flash_groups = fled_cdev->sysfs_groups; 350 + 351 + int num_sysfs_groups = 0; 352 + 353 + flash_groups[num_sysfs_groups++] = &led_flash_strobe_group; 354 + 355 + if (ops->flash_brightness_set) 356 + flash_groups[num_sysfs_groups++] = &led_flash_brightness_group; 357 + 358 + if (ops->timeout_set) 359 + flash_groups[num_sysfs_groups++] = &led_flash_timeout_group; 360 + 361 + if (ops->fault_get) 362 + flash_groups[num_sysfs_groups++] = &led_flash_fault_group; 363 + 364 + if (led_cdev->flags & LED_DEV_CAP_SYNC_STROBE) 365 + flash_groups[num_sysfs_groups++] = &led_flash_sync_strobe_group; 366 + 367 + led_cdev->groups = flash_groups; 368 + } 369 + 370 + int led_classdev_flash_register(struct device *parent, 371 + struct led_classdev_flash *fled_cdev) 372 + { 373 + struct led_classdev *led_cdev; 374 + const struct led_flash_ops *ops; 375 + int ret; 376 + 377 + if (!fled_cdev) 378 + return -EINVAL; 379 + 380 + led_cdev = &fled_cdev->led_cdev; 381 + 382 + if (led_cdev->flags & LED_DEV_CAP_FLASH) { 383 + if (!led_cdev->brightness_set_sync) 384 + return -EINVAL; 385 + 386 + ops = fled_cdev->ops; 387 + if (!ops || !ops->strobe_set) 388 + return -EINVAL; 389 + 390 + led_cdev->flash_resume = led_flash_resume; 391 + 392 + /* Select the sysfs attributes to be created for the device */ 393 + led_flash_init_sysfs_groups(fled_cdev); 394 + } 395 + 396 + /* Register led class device */ 397 + ret = led_classdev_register(parent, led_cdev); 398 + if (ret < 0) 399 + return ret; 400 + 401 + /* Setting a torch brightness needs to have immediate effect */ 402 + led_cdev->flags &= ~SET_BRIGHTNESS_ASYNC; 403 + led_cdev->flags |= SET_BRIGHTNESS_SYNC; 404 + 405 + return 0; 406 + } 407 + EXPORT_SYMBOL_GPL(led_classdev_flash_register); 408 + 409 + void led_classdev_flash_unregister(struct led_classdev_flash *fled_cdev) 410 + { 411 + if (!fled_cdev) 412 + return; 413 + 414 + led_classdev_unregister(&fled_cdev->led_cdev); 415 + } 416 + EXPORT_SYMBOL_GPL(led_classdev_flash_unregister); 417 + 418 + static void led_clamp_align(struct led_flash_setting *s) 419 + { 420 + u32 v, offset; 421 + 422 + v = s->val + s->step / 2; 423 + v = clamp(v, s->min, s->max); 424 + offset = v - s->min; 425 + offset = s->step * (offset / s->step); 426 + s->val = s->min + offset; 427 + } 428 + 429 + int led_set_flash_timeout(struct led_classdev_flash *fled_cdev, u32 timeout) 430 + { 431 + struct led_classdev *led_cdev = &fled_cdev->led_cdev; 432 + struct led_flash_setting *s = &fled_cdev->timeout; 433 + 434 + s->val = timeout; 435 + led_clamp_align(s); 436 + 437 + if (!(led_cdev->flags & LED_SUSPENDED)) 438 + return call_flash_op(fled_cdev, timeout_set, s->val); 439 + 440 + return 0; 441 + } 442 + EXPORT_SYMBOL_GPL(led_set_flash_timeout); 443 + 444 + int led_get_flash_fault(struct led_classdev_flash *fled_cdev, u32 *fault) 445 + { 446 + return call_flash_op(fled_cdev, fault_get, fault); 447 + } 448 + EXPORT_SYMBOL_GPL(led_get_flash_fault); 449 + 450 + int led_set_flash_brightness(struct led_classdev_flash *fled_cdev, 451 + u32 brightness) 452 + { 453 + struct led_classdev *led_cdev = &fled_cdev->led_cdev; 454 + struct led_flash_setting *s = &fled_cdev->brightness; 455 + 456 + s->val = brightness; 457 + led_clamp_align(s); 458 + 459 + if (!(led_cdev->flags & LED_SUSPENDED)) 460 + return call_flash_op(fled_cdev, flash_brightness_set, s->val); 461 + 462 + return 0; 463 + } 464 + EXPORT_SYMBOL_GPL(led_set_flash_brightness); 465 + 466 + int led_update_flash_brightness(struct led_classdev_flash *fled_cdev) 467 + { 468 + struct led_flash_setting *s = &fled_cdev->brightness; 469 + u32 brightness; 470 + 471 + if (has_flash_op(fled_cdev, flash_brightness_get)) { 472 + int ret = call_flash_op(fled_cdev, flash_brightness_get, 473 + &brightness); 474 + if (ret < 0) 475 + return ret; 476 + 477 + s->val = brightness; 478 + } 479 + 480 + return 0; 481 + } 482 + EXPORT_SYMBOL_GPL(led_update_flash_brightness); 483 + 484 + MODULE_AUTHOR("Jacek Anaszewski <j.anaszewski@samsung.com>"); 485 + MODULE_DESCRIPTION("LED Flash class interface"); 486 + MODULE_LICENSE("GPL v2");
+6 -3
drivers/leds/led-class.c
··· 179 179 void led_classdev_resume(struct led_classdev *led_cdev) 180 180 { 181 181 led_cdev->brightness_set(led_cdev, led_cdev->brightness); 182 + 183 + if (led_cdev->flash_resume) 184 + led_cdev->flash_resume(led_cdev); 185 + 182 186 led_cdev->flags &= ~LED_SUSPENDED; 183 187 } 184 188 EXPORT_SYMBOL_GPL(led_classdev_resume); ··· 243 239 244 240 INIT_WORK(&led_cdev->set_brightness_work, set_brightness_delayed); 245 241 246 - init_timer(&led_cdev->blink_timer); 247 - led_cdev->blink_timer.function = led_timer_function; 248 - led_cdev->blink_timer.data = (unsigned long)led_cdev; 242 + setup_timer(&led_cdev->blink_timer, led_timer_function, 243 + (unsigned long)led_cdev); 249 244 250 245 #ifdef CONFIG_LEDS_TRIGGERS 251 246 led_trigger_set_default(led_cdev);
+2 -1
drivers/leds/leds-gpio.c
··· 187 187 led.gpiod = devm_get_gpiod_from_child(dev, child); 188 188 if (IS_ERR(led.gpiod)) { 189 189 fwnode_handle_put(child); 190 + ret = PTR_ERR(led.gpiod); 190 191 goto err; 191 192 } 192 193 ··· 230 229 err: 231 230 for (count = priv->num_leds - 2; count >= 0; count--) 232 231 delete_gpio_led(&priv->leds[count]); 233 - return ERR_PTR(-ENODEV); 232 + return ERR_PTR(ret); 234 233 } 235 234 236 235 static const struct of_device_id of_gpio_leds_match[] = {
+1 -3
drivers/leds/leds-mc13783.c
··· 134 134 if (!pdata) 135 135 return ERR_PTR(-ENOMEM); 136 136 137 - of_node_get(dev->parent->of_node); 138 - 139 - parent = of_find_node_by_name(dev->parent->of_node, "leds"); 137 + parent = of_get_child_by_name(dev->parent->of_node, "leds"); 140 138 if (!parent) 141 139 goto out_node_put; 142 140
+2 -1
drivers/leds/leds.h
··· 20 20 static inline void led_set_brightness_async(struct led_classdev *led_cdev, 21 21 enum led_brightness value) 22 22 { 23 - led_cdev->brightness = min(value, led_cdev->max_brightness); 23 + value = min(value, led_cdev->max_brightness); 24 + led_cdev->brightness = value; 24 25 25 26 if (!(led_cdev->flags & LED_SUSPENDED)) 26 27 led_cdev->brightness_set(led_cdev, value);
+207
include/linux/led-class-flash.h
··· 1 + /* 2 + * LED Flash class interface 3 + * 4 + * Copyright (C) 2015 Samsung Electronics Co., Ltd. 5 + * Author: Jacek Anaszewski <j.anaszewski@samsung.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_FLASH_LEDS_H_INCLUDED 13 + #define __LINUX_FLASH_LEDS_H_INCLUDED 14 + 15 + #include <linux/leds.h> 16 + #include <uapi/linux/v4l2-controls.h> 17 + 18 + struct device_node; 19 + struct led_classdev_flash; 20 + 21 + /* 22 + * Supported led fault bits - must be kept in synch 23 + * with V4L2_FLASH_FAULT bits. 24 + */ 25 + #define LED_FAULT_OVER_VOLTAGE (1 << 0) 26 + #define LED_FAULT_TIMEOUT (1 << 1) 27 + #define LED_FAULT_OVER_TEMPERATURE (1 << 2) 28 + #define LED_FAULT_SHORT_CIRCUIT (1 << 3) 29 + #define LED_FAULT_OVER_CURRENT (1 << 4) 30 + #define LED_FAULT_INDICATOR (1 << 5) 31 + #define LED_FAULT_UNDER_VOLTAGE (1 << 6) 32 + #define LED_FAULT_INPUT_VOLTAGE (1 << 7) 33 + #define LED_FAULT_LED_OVER_TEMPERATURE (1 << 8) 34 + #define LED_NUM_FLASH_FAULTS 9 35 + 36 + #define LED_FLASH_MAX_SYSFS_GROUPS 7 37 + 38 + struct led_flash_ops { 39 + /* set flash brightness */ 40 + int (*flash_brightness_set)(struct led_classdev_flash *fled_cdev, 41 + u32 brightness); 42 + /* get flash brightness */ 43 + int (*flash_brightness_get)(struct led_classdev_flash *fled_cdev, 44 + u32 *brightness); 45 + /* set flash strobe state */ 46 + int (*strobe_set)(struct led_classdev_flash *fled_cdev, bool state); 47 + /* get flash strobe state */ 48 + int (*strobe_get)(struct led_classdev_flash *fled_cdev, bool *state); 49 + /* set flash timeout */ 50 + int (*timeout_set)(struct led_classdev_flash *fled_cdev, u32 timeout); 51 + /* get the flash LED fault */ 52 + int (*fault_get)(struct led_classdev_flash *fled_cdev, u32 *fault); 53 + }; 54 + 55 + /* 56 + * Current value of a flash setting along 57 + * with its constraints. 58 + */ 59 + struct led_flash_setting { 60 + /* maximum allowed value */ 61 + u32 min; 62 + /* maximum allowed value */ 63 + u32 max; 64 + /* step value */ 65 + u32 step; 66 + /* current value */ 67 + u32 val; 68 + }; 69 + 70 + struct led_classdev_flash { 71 + /* led class device */ 72 + struct led_classdev led_cdev; 73 + 74 + /* flash led specific ops */ 75 + const struct led_flash_ops *ops; 76 + 77 + /* flash brightness value in microamperes along with its constraints */ 78 + struct led_flash_setting brightness; 79 + 80 + /* flash timeout value in microseconds along with its constraints */ 81 + struct led_flash_setting timeout; 82 + 83 + /* LED Flash class sysfs groups */ 84 + const struct attribute_group *sysfs_groups[LED_FLASH_MAX_SYSFS_GROUPS]; 85 + 86 + /* LEDs available for flash strobe synchronization */ 87 + struct led_classdev_flash **sync_leds; 88 + 89 + /* Number of LEDs available for flash strobe synchronization */ 90 + int num_sync_leds; 91 + 92 + /* 93 + * The identifier of the sub-led to synchronize the flash strobe with. 94 + * Identifiers start from 1, which reflects the first element from the 95 + * sync_leds array. 0 means that the flash strobe should not be 96 + * synchronized. 97 + */ 98 + u32 sync_led_id; 99 + }; 100 + 101 + static inline struct led_classdev_flash *lcdev_to_flcdev( 102 + struct led_classdev *lcdev) 103 + { 104 + return container_of(lcdev, struct led_classdev_flash, led_cdev); 105 + } 106 + 107 + /** 108 + * led_classdev_flash_register - register a new object of led_classdev class 109 + * with support for flash LEDs 110 + * @parent: the flash LED to register 111 + * @fled_cdev: the led_classdev_flash structure for this device 112 + * 113 + * Returns: 0 on success or negative error value on failure 114 + */ 115 + extern int led_classdev_flash_register(struct device *parent, 116 + struct led_classdev_flash *fled_cdev); 117 + 118 + /** 119 + * led_classdev_flash_unregister - unregisters an object of led_classdev class 120 + * with support for flash LEDs 121 + * @fled_cdev: the flash LED to unregister 122 + * 123 + * Unregister a previously registered via led_classdev_flash_register object 124 + */ 125 + extern void led_classdev_flash_unregister(struct led_classdev_flash *fled_cdev); 126 + 127 + /** 128 + * led_set_flash_strobe - setup flash strobe 129 + * @fled_cdev: the flash LED to set strobe on 130 + * @state: 1 - strobe flash, 0 - stop flash strobe 131 + * 132 + * Strobe the flash LED. 133 + * 134 + * Returns: 0 on success or negative error value on failure 135 + */ 136 + static inline int led_set_flash_strobe(struct led_classdev_flash *fled_cdev, 137 + bool state) 138 + { 139 + return fled_cdev->ops->strobe_set(fled_cdev, state); 140 + } 141 + 142 + /** 143 + * led_get_flash_strobe - get flash strobe status 144 + * @fled_cdev: the flash LED to query 145 + * @state: 1 - flash is strobing, 0 - flash is off 146 + * 147 + * Check whether the flash is strobing at the moment. 148 + * 149 + * Returns: 0 on success or negative error value on failure 150 + */ 151 + static inline int led_get_flash_strobe(struct led_classdev_flash *fled_cdev, 152 + bool *state) 153 + { 154 + if (fled_cdev->ops->strobe_get) 155 + return fled_cdev->ops->strobe_get(fled_cdev, state); 156 + 157 + return -EINVAL; 158 + } 159 + 160 + /** 161 + * led_set_flash_brightness - set flash LED brightness 162 + * @fled_cdev: the flash LED to set 163 + * @brightness: the brightness to set it to 164 + * 165 + * Set a flash LED's brightness. 166 + * 167 + * Returns: 0 on success or negative error value on failure 168 + */ 169 + extern int led_set_flash_brightness(struct led_classdev_flash *fled_cdev, 170 + u32 brightness); 171 + 172 + /** 173 + * led_update_flash_brightness - update flash LED brightness 174 + * @fled_cdev: the flash LED to query 175 + * 176 + * Get a flash LED's current brightness and update led_flash->brightness 177 + * member with the obtained value. 178 + * 179 + * Returns: 0 on success or negative error value on failure 180 + */ 181 + extern int led_update_flash_brightness(struct led_classdev_flash *fled_cdev); 182 + 183 + /** 184 + * led_set_flash_timeout - set flash LED timeout 185 + * @fled_cdev: the flash LED to set 186 + * @timeout: the flash timeout to set it to 187 + * 188 + * Set the flash strobe duration. 189 + * 190 + * Returns: 0 on success or negative error value on failure 191 + */ 192 + extern int led_set_flash_timeout(struct led_classdev_flash *fled_cdev, 193 + u32 timeout); 194 + 195 + /** 196 + * led_get_flash_fault - get the flash LED fault 197 + * @fled_cdev: the flash LED to query 198 + * @fault: bitmask containing flash faults 199 + * 200 + * Get the flash LED fault. 201 + * 202 + * Returns: 0 on success or negative error value on failure 203 + */ 204 + extern int led_get_flash_fault(struct led_classdev_flash *fled_cdev, 205 + u32 *fault); 206 + 207 + #endif /* __LINUX_FLASH_LEDS_H_INCLUDED */
+3
include/linux/leds.h
··· 46 46 #define LED_SYSFS_DISABLE (1 << 20) 47 47 #define SET_BRIGHTNESS_ASYNC (1 << 21) 48 48 #define SET_BRIGHTNESS_SYNC (1 << 22) 49 + #define LED_DEV_CAP_FLASH (1 << 23) 50 + #define LED_DEV_CAP_SYNC_STROBE (1 << 24) 49 51 50 52 /* Set LED brightness level */ 51 53 /* Must not sleep, use a workqueue if needed */ ··· 83 81 unsigned long blink_delay_on, blink_delay_off; 84 82 struct timer_list blink_timer; 85 83 int blink_brightness; 84 + void (*flash_resume)(struct led_classdev *led_cdev); 86 85 87 86 struct work_struct set_brightness_work; 88 87 int delayed_set_value;