1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Backlight Lowlevel Control Abstraction 4 * 5 * Copyright (C) 2003,2004 Hewlett-Packard Company 6 * 7 */ 8 9 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 10 11 #include <linux/module.h> 12 #include <linux/init.h> 13 #include <linux/device.h> 14 #include <linux/backlight.h> 15 #include <linux/notifier.h> 16 #include <linux/ctype.h> 17 #include <linux/err.h> 18 #include <linux/fb.h> 19 #include <linux/slab.h> 20 21 #ifdef CONFIG_PMAC_BACKLIGHT 22 #include <asm/backlight.h> 23 #endif 24 25 static struct list_head backlight_dev_list; 26 static struct mutex backlight_dev_list_mutex; 27 static struct blocking_notifier_head backlight_notifier; 28 29 static const char *const backlight_types[] = { 30 [BACKLIGHT_RAW] = "raw", 31 [BACKLIGHT_PLATFORM] = "platform", 32 [BACKLIGHT_FIRMWARE] = "firmware", 33 }; 34 35 static const char *const backlight_scale_types[] = { 36 [BACKLIGHT_SCALE_UNKNOWN] = "unknown", 37 [BACKLIGHT_SCALE_LINEAR] = "linear", 38 [BACKLIGHT_SCALE_NON_LINEAR] = "non-linear", 39 }; 40 41 #if defined(CONFIG_FB) || (defined(CONFIG_FB_MODULE) && \ 42 defined(CONFIG_BACKLIGHT_CLASS_DEVICE_MODULE)) 43 /* This callback gets called when something important happens inside a 44 * framebuffer driver. We're looking if that important event is blanking, 45 * and if it is and necessary, we're switching backlight power as well ... 46 */ 47 static int fb_notifier_callback(struct notifier_block *self, 48 unsigned long event, void *data) 49 { 50 struct backlight_device *bd; 51 struct fb_event *evdata = data; 52 int node = evdata->info->node; 53 int fb_blank = 0; 54 55 /* If we aren't interested in this event, skip it immediately ... */ 56 if (event != FB_EVENT_BLANK) 57 return 0; 58 59 bd = container_of(self, struct backlight_device, fb_notif); 60 mutex_lock(&bd->ops_lock); 61 if (bd->ops) 62 if (!bd->ops->check_fb || 63 bd->ops->check_fb(bd, evdata->info)) { 64 fb_blank = *(int *)evdata->data; 65 if (fb_blank == FB_BLANK_UNBLANK && 66 !bd->fb_bl_on[node]) { 67 bd->fb_bl_on[node] = true; 68 if (!bd->use_count++) { 69 bd->props.state &= ~BL_CORE_FBBLANK; 70 bd->props.fb_blank = FB_BLANK_UNBLANK; 71 backlight_update_status(bd); 72 } 73 } else if (fb_blank != FB_BLANK_UNBLANK && 74 bd->fb_bl_on[node]) { 75 bd->fb_bl_on[node] = false; 76 if (!(--bd->use_count)) { 77 bd->props.state |= BL_CORE_FBBLANK; 78 bd->props.fb_blank = fb_blank; 79 backlight_update_status(bd); 80 } 81 } 82 } 83 mutex_unlock(&bd->ops_lock); 84 return 0; 85 } 86 87 static int backlight_register_fb(struct backlight_device *bd) 88 { 89 memset(&bd->fb_notif, 0, sizeof(bd->fb_notif)); 90 bd->fb_notif.notifier_call = fb_notifier_callback; 91 92 return fb_register_client(&bd->fb_notif); 93 } 94 95 static void backlight_unregister_fb(struct backlight_device *bd) 96 { 97 fb_unregister_client(&bd->fb_notif); 98 } 99 #else 100 static inline int backlight_register_fb(struct backlight_device *bd) 101 { 102 return 0; 103 } 104 105 static inline void backlight_unregister_fb(struct backlight_device *bd) 106 { 107 } 108 #endif /* CONFIG_FB */ 109 110 static void backlight_generate_event(struct backlight_device *bd, 111 enum backlight_update_reason reason) 112 { 113 char *envp[2]; 114 115 switch (reason) { 116 case BACKLIGHT_UPDATE_SYSFS: 117 envp[0] = "SOURCE=sysfs"; 118 break; 119 case BACKLIGHT_UPDATE_HOTKEY: 120 envp[0] = "SOURCE=hotkey"; 121 break; 122 default: 123 envp[0] = "SOURCE=unknown"; 124 break; 125 } 126 envp[1] = NULL; 127 kobject_uevent_env(&bd->dev.kobj, KOBJ_CHANGE, envp); 128 sysfs_notify(&bd->dev.kobj, NULL, "actual_brightness"); 129 } 130 131 static ssize_t bl_power_show(struct device *dev, struct device_attribute *attr, 132 char *buf) 133 { 134 struct backlight_device *bd = to_backlight_device(dev); 135 136 return sprintf(buf, "%d\n", bd->props.power); 137 } 138 139 static ssize_t bl_power_store(struct device *dev, struct device_attribute *attr, 140 const char *buf, size_t count) 141 { 142 int rc; 143 struct backlight_device *bd = to_backlight_device(dev); 144 unsigned long power, old_power; 145 146 rc = kstrtoul(buf, 0, &power); 147 if (rc) 148 return rc; 149 150 rc = -ENXIO; 151 mutex_lock(&bd->ops_lock); 152 if (bd->ops) { 153 pr_debug("set power to %lu\n", power); 154 if (bd->props.power != power) { 155 old_power = bd->props.power; 156 bd->props.power = power; 157 rc = backlight_update_status(bd); 158 if (rc) 159 bd->props.power = old_power; 160 else 161 rc = count; 162 } else { 163 rc = count; 164 } 165 } 166 mutex_unlock(&bd->ops_lock); 167 168 return rc; 169 } 170 static DEVICE_ATTR_RW(bl_power); 171 172 static ssize_t brightness_show(struct device *dev, 173 struct device_attribute *attr, char *buf) 174 { 175 struct backlight_device *bd = to_backlight_device(dev); 176 177 return sprintf(buf, "%d\n", bd->props.brightness); 178 } 179 180 int backlight_device_set_brightness(struct backlight_device *bd, 181 unsigned long brightness) 182 { 183 int rc = -ENXIO; 184 185 mutex_lock(&bd->ops_lock); 186 if (bd->ops) { 187 if (brightness > bd->props.max_brightness) 188 rc = -EINVAL; 189 else { 190 pr_debug("set brightness to %lu\n", brightness); 191 bd->props.brightness = brightness; 192 rc = backlight_update_status(bd); 193 } 194 } 195 mutex_unlock(&bd->ops_lock); 196 197 backlight_generate_event(bd, BACKLIGHT_UPDATE_SYSFS); 198 199 return rc; 200 } 201 EXPORT_SYMBOL(backlight_device_set_brightness); 202 203 static ssize_t brightness_store(struct device *dev, 204 struct device_attribute *attr, const char *buf, size_t count) 205 { 206 int rc; 207 struct backlight_device *bd = to_backlight_device(dev); 208 unsigned long brightness; 209 210 rc = kstrtoul(buf, 0, &brightness); 211 if (rc) 212 return rc; 213 214 rc = backlight_device_set_brightness(bd, brightness); 215 216 return rc ? rc : count; 217 } 218 static DEVICE_ATTR_RW(brightness); 219 220 static ssize_t type_show(struct device *dev, struct device_attribute *attr, 221 char *buf) 222 { 223 struct backlight_device *bd = to_backlight_device(dev); 224 225 return sprintf(buf, "%s\n", backlight_types[bd->props.type]); 226 } 227 static DEVICE_ATTR_RO(type); 228 229 static ssize_t max_brightness_show(struct device *dev, 230 struct device_attribute *attr, char *buf) 231 { 232 struct backlight_device *bd = to_backlight_device(dev); 233 234 return sprintf(buf, "%d\n", bd->props.max_brightness); 235 } 236 static DEVICE_ATTR_RO(max_brightness); 237 238 static ssize_t actual_brightness_show(struct device *dev, 239 struct device_attribute *attr, char *buf) 240 { 241 int rc = -ENXIO; 242 struct backlight_device *bd = to_backlight_device(dev); 243 244 mutex_lock(&bd->ops_lock); 245 if (bd->ops && bd->ops->get_brightness) 246 rc = sprintf(buf, "%d\n", bd->ops->get_brightness(bd)); 247 else 248 rc = sprintf(buf, "%d\n", bd->props.brightness); 249 mutex_unlock(&bd->ops_lock); 250 251 return rc; 252 } 253 static DEVICE_ATTR_RO(actual_brightness); 254 255 static ssize_t scale_show(struct device *dev, 256 struct device_attribute *attr, char *buf) 257 { 258 struct backlight_device *bd = to_backlight_device(dev); 259 260 if (WARN_ON(bd->props.scale > BACKLIGHT_SCALE_NON_LINEAR)) 261 return sprintf(buf, "unknown\n"); 262 263 return sprintf(buf, "%s\n", backlight_scale_types[bd->props.scale]); 264 } 265 static DEVICE_ATTR_RO(scale); 266 267 static struct class *backlight_class; 268 269 #ifdef CONFIG_PM_SLEEP 270 static int backlight_suspend(struct device *dev) 271 { 272 struct backlight_device *bd = to_backlight_device(dev); 273 274 mutex_lock(&bd->ops_lock); 275 if (bd->ops && bd->ops->options & BL_CORE_SUSPENDRESUME) { 276 bd->props.state |= BL_CORE_SUSPENDED; 277 backlight_update_status(bd); 278 } 279 mutex_unlock(&bd->ops_lock); 280 281 return 0; 282 } 283 284 static int backlight_resume(struct device *dev) 285 { 286 struct backlight_device *bd = to_backlight_device(dev); 287 288 mutex_lock(&bd->ops_lock); 289 if (bd->ops && bd->ops->options & BL_CORE_SUSPENDRESUME) { 290 bd->props.state &= ~BL_CORE_SUSPENDED; 291 backlight_update_status(bd); 292 } 293 mutex_unlock(&bd->ops_lock); 294 295 return 0; 296 } 297 #endif 298 299 static SIMPLE_DEV_PM_OPS(backlight_class_dev_pm_ops, backlight_suspend, 300 backlight_resume); 301 302 static void bl_device_release(struct device *dev) 303 { 304 struct backlight_device *bd = to_backlight_device(dev); 305 kfree(bd); 306 } 307 308 static struct attribute *bl_device_attrs[] = { 309 &dev_attr_bl_power.attr, 310 &dev_attr_brightness.attr, 311 &dev_attr_actual_brightness.attr, 312 &dev_attr_max_brightness.attr, 313 &dev_attr_scale.attr, 314 &dev_attr_type.attr, 315 NULL, 316 }; 317 ATTRIBUTE_GROUPS(bl_device); 318 319 /** 320 * backlight_force_update - tell the backlight subsystem that hardware state 321 * has changed 322 * @bd: the backlight device to update 323 * 324 * Updates the internal state of the backlight in response to a hardware event, 325 * and generate a uevent to notify userspace 326 */ 327 void backlight_force_update(struct backlight_device *bd, 328 enum backlight_update_reason reason) 329 { 330 mutex_lock(&bd->ops_lock); 331 if (bd->ops && bd->ops->get_brightness) 332 bd->props.brightness = bd->ops->get_brightness(bd); 333 mutex_unlock(&bd->ops_lock); 334 backlight_generate_event(bd, reason); 335 } 336 EXPORT_SYMBOL(backlight_force_update); 337 338 /** 339 * backlight_device_register - create and register a new object of 340 * backlight_device class. 341 * @name: the name of the new object(must be the same as the name of the 342 * respective framebuffer device). 343 * @parent: a pointer to the parent device 344 * @devdata: an optional pointer to be stored for private driver use. The 345 * methods may retrieve it by using bl_get_data(bd). 346 * @ops: the backlight operations structure. 347 * 348 * Creates and registers new backlight device. Returns either an 349 * ERR_PTR() or a pointer to the newly allocated device. 350 */ 351 struct backlight_device *backlight_device_register(const char *name, 352 struct device *parent, void *devdata, const struct backlight_ops *ops, 353 const struct backlight_properties *props) 354 { 355 struct backlight_device *new_bd; 356 int rc; 357 358 pr_debug("backlight_device_register: name=%s\n", name); 359 360 new_bd = kzalloc(sizeof(struct backlight_device), GFP_KERNEL); 361 if (!new_bd) 362 return ERR_PTR(-ENOMEM); 363 364 mutex_init(&new_bd->update_lock); 365 mutex_init(&new_bd->ops_lock); 366 367 new_bd->dev.class = backlight_class; 368 new_bd->dev.parent = parent; 369 new_bd->dev.release = bl_device_release; 370 dev_set_name(&new_bd->dev, "%s", name); 371 dev_set_drvdata(&new_bd->dev, devdata); 372 373 /* Set default properties */ 374 if (props) { 375 memcpy(&new_bd->props, props, 376 sizeof(struct backlight_properties)); 377 if (props->type <= 0 || props->type >= BACKLIGHT_TYPE_MAX) { 378 WARN(1, "%s: invalid backlight type", name); 379 new_bd->props.type = BACKLIGHT_RAW; 380 } 381 } else { 382 new_bd->props.type = BACKLIGHT_RAW; 383 } 384 385 rc = device_register(&new_bd->dev); 386 if (rc) { 387 put_device(&new_bd->dev); 388 return ERR_PTR(rc); 389 } 390 391 rc = backlight_register_fb(new_bd); 392 if (rc) { 393 device_unregister(&new_bd->dev); 394 return ERR_PTR(rc); 395 } 396 397 new_bd->ops = ops; 398 399 #ifdef CONFIG_PMAC_BACKLIGHT 400 mutex_lock(&pmac_backlight_mutex); 401 if (!pmac_backlight) 402 pmac_backlight = new_bd; 403 mutex_unlock(&pmac_backlight_mutex); 404 #endif 405 406 mutex_lock(&backlight_dev_list_mutex); 407 list_add(&new_bd->entry, &backlight_dev_list); 408 mutex_unlock(&backlight_dev_list_mutex); 409 410 blocking_notifier_call_chain(&backlight_notifier, 411 BACKLIGHT_REGISTERED, new_bd); 412 413 return new_bd; 414 } 415 EXPORT_SYMBOL(backlight_device_register); 416 417 struct backlight_device *backlight_device_get_by_type(enum backlight_type type) 418 { 419 bool found = false; 420 struct backlight_device *bd; 421 422 mutex_lock(&backlight_dev_list_mutex); 423 list_for_each_entry(bd, &backlight_dev_list, entry) { 424 if (bd->props.type == type) { 425 found = true; 426 break; 427 } 428 } 429 mutex_unlock(&backlight_dev_list_mutex); 430 431 return found ? bd : NULL; 432 } 433 EXPORT_SYMBOL(backlight_device_get_by_type); 434 435 /** 436 * backlight_device_unregister - unregisters a backlight device object. 437 * @bd: the backlight device object to be unregistered and freed. 438 * 439 * Unregisters a previously registered via backlight_device_register object. 440 */ 441 void backlight_device_unregister(struct backlight_device *bd) 442 { 443 if (!bd) 444 return; 445 446 mutex_lock(&backlight_dev_list_mutex); 447 list_del(&bd->entry); 448 mutex_unlock(&backlight_dev_list_mutex); 449 450 #ifdef CONFIG_PMAC_BACKLIGHT 451 mutex_lock(&pmac_backlight_mutex); 452 if (pmac_backlight == bd) 453 pmac_backlight = NULL; 454 mutex_unlock(&pmac_backlight_mutex); 455 #endif 456 457 blocking_notifier_call_chain(&backlight_notifier, 458 BACKLIGHT_UNREGISTERED, bd); 459 460 mutex_lock(&bd->ops_lock); 461 bd->ops = NULL; 462 mutex_unlock(&bd->ops_lock); 463 464 backlight_unregister_fb(bd); 465 device_unregister(&bd->dev); 466 } 467 EXPORT_SYMBOL(backlight_device_unregister); 468 469 static void devm_backlight_device_release(struct device *dev, void *res) 470 { 471 struct backlight_device *backlight = *(struct backlight_device **)res; 472 473 backlight_device_unregister(backlight); 474 } 475 476 static int devm_backlight_device_match(struct device *dev, void *res, 477 void *data) 478 { 479 struct backlight_device **r = res; 480 481 return *r == data; 482 } 483 484 /** 485 * backlight_register_notifier - get notified of backlight (un)registration 486 * @nb: notifier block with the notifier to call on backlight (un)registration 487 * 488 * @return 0 on success, otherwise a negative error code 489 * 490 * Register a notifier to get notified when backlight devices get registered 491 * or unregistered. 492 */ 493 int backlight_register_notifier(struct notifier_block *nb) 494 { 495 return blocking_notifier_chain_register(&backlight_notifier, nb); 496 } 497 EXPORT_SYMBOL(backlight_register_notifier); 498 499 /** 500 * backlight_unregister_notifier - unregister a backlight notifier 501 * @nb: notifier block to unregister 502 * 503 * @return 0 on success, otherwise a negative error code 504 * 505 * Register a notifier to get notified when backlight devices get registered 506 * or unregistered. 507 */ 508 int backlight_unregister_notifier(struct notifier_block *nb) 509 { 510 return blocking_notifier_chain_unregister(&backlight_notifier, nb); 511 } 512 EXPORT_SYMBOL(backlight_unregister_notifier); 513 514 /** 515 * devm_backlight_device_register - resource managed backlight_device_register() 516 * @dev: the device to register 517 * @name: the name of the device 518 * @parent: a pointer to the parent device 519 * @devdata: an optional pointer to be stored for private driver use 520 * @ops: the backlight operations structure 521 * @props: the backlight properties 522 * 523 * @return a struct backlight on success, or an ERR_PTR on error 524 * 525 * Managed backlight_device_register(). The backlight_device returned 526 * from this function are automatically freed on driver detach. 527 * See backlight_device_register() for more information. 528 */ 529 struct backlight_device *devm_backlight_device_register(struct device *dev, 530 const char *name, struct device *parent, void *devdata, 531 const struct backlight_ops *ops, 532 const struct backlight_properties *props) 533 { 534 struct backlight_device **ptr, *backlight; 535 536 ptr = devres_alloc(devm_backlight_device_release, sizeof(*ptr), 537 GFP_KERNEL); 538 if (!ptr) 539 return ERR_PTR(-ENOMEM); 540 541 backlight = backlight_device_register(name, parent, devdata, ops, 542 props); 543 if (!IS_ERR(backlight)) { 544 *ptr = backlight; 545 devres_add(dev, ptr); 546 } else { 547 devres_free(ptr); 548 } 549 550 return backlight; 551 } 552 EXPORT_SYMBOL(devm_backlight_device_register); 553 554 /** 555 * devm_backlight_device_unregister - resource managed backlight_device_unregister() 556 * @dev: the device to unregister 557 * @bd: the backlight device to unregister 558 * 559 * Deallocated a backlight allocated with devm_backlight_device_register(). 560 * Normally this function will not need to be called and the resource management 561 * code will ensure that the resource is freed. 562 */ 563 void devm_backlight_device_unregister(struct device *dev, 564 struct backlight_device *bd) 565 { 566 int rc; 567 568 rc = devres_release(dev, devm_backlight_device_release, 569 devm_backlight_device_match, bd); 570 WARN_ON(rc); 571 } 572 EXPORT_SYMBOL(devm_backlight_device_unregister); 573 574 #ifdef CONFIG_OF 575 static int of_parent_match(struct device *dev, const void *data) 576 { 577 return dev->parent && dev->parent->of_node == data; 578 } 579 580 /** 581 * of_find_backlight_by_node() - find backlight device by device-tree node 582 * @node: device-tree node of the backlight device 583 * 584 * Returns a pointer to the backlight device corresponding to the given DT 585 * node or NULL if no such backlight device exists or if the device hasn't 586 * been probed yet. 587 * 588 * This function obtains a reference on the backlight device and it is the 589 * caller's responsibility to drop the reference by calling put_device() on 590 * the backlight device's .dev field. 591 */ 592 struct backlight_device *of_find_backlight_by_node(struct device_node *node) 593 { 594 struct device *dev; 595 596 dev = class_find_device(backlight_class, NULL, node, of_parent_match); 597 598 return dev ? to_backlight_device(dev) : NULL; 599 } 600 EXPORT_SYMBOL(of_find_backlight_by_node); 601 #endif 602 603 /** 604 * of_find_backlight - Get backlight device 605 * @dev: Device 606 * 607 * This function looks for a property named 'backlight' on the DT node 608 * connected to @dev and looks up the backlight device. 609 * 610 * Call backlight_put() to drop the reference on the backlight device. 611 * 612 * Returns: 613 * A pointer to the backlight device if found. 614 * Error pointer -EPROBE_DEFER if the DT property is set, but no backlight 615 * device is found. 616 * NULL if there's no backlight property. 617 */ 618 struct backlight_device *of_find_backlight(struct device *dev) 619 { 620 struct backlight_device *bd = NULL; 621 struct device_node *np; 622 623 if (!dev) 624 return NULL; 625 626 if (IS_ENABLED(CONFIG_OF) && dev->of_node) { 627 np = of_parse_phandle(dev->of_node, "backlight", 0); 628 if (np) { 629 bd = of_find_backlight_by_node(np); 630 of_node_put(np); 631 if (!bd) 632 return ERR_PTR(-EPROBE_DEFER); 633 /* 634 * Note: gpio_backlight uses brightness as 635 * power state during probe 636 */ 637 if (!bd->props.brightness) 638 bd->props.brightness = bd->props.max_brightness; 639 } 640 } 641 642 return bd; 643 } 644 EXPORT_SYMBOL(of_find_backlight); 645 646 static void devm_backlight_release(void *data) 647 { 648 backlight_put(data); 649 } 650 651 /** 652 * devm_of_find_backlight - Resource-managed of_find_backlight() 653 * @dev: Device 654 * 655 * Device managed version of of_find_backlight(). 656 * The reference on the backlight device is automatically 657 * dropped on driver detach. 658 */ 659 struct backlight_device *devm_of_find_backlight(struct device *dev) 660 { 661 struct backlight_device *bd; 662 int ret; 663 664 bd = of_find_backlight(dev); 665 if (IS_ERR_OR_NULL(bd)) 666 return bd; 667 ret = devm_add_action(dev, devm_backlight_release, bd); 668 if (ret) { 669 backlight_put(bd); 670 return ERR_PTR(ret); 671 } 672 return bd; 673 } 674 EXPORT_SYMBOL(devm_of_find_backlight); 675 676 static void __exit backlight_class_exit(void) 677 { 678 class_destroy(backlight_class); 679 } 680 681 static int __init backlight_class_init(void) 682 { 683 backlight_class = class_create(THIS_MODULE, "backlight"); 684 if (IS_ERR(backlight_class)) { 685 pr_warn("Unable to create backlight class; errno = %ld\n", 686 PTR_ERR(backlight_class)); 687 return PTR_ERR(backlight_class); 688 } 689 690 backlight_class->dev_groups = bl_device_groups; 691 backlight_class->pm = &backlight_class_dev_pm_ops; 692 INIT_LIST_HEAD(&backlight_dev_list); 693 mutex_init(&backlight_dev_list_mutex); 694 BLOCKING_INIT_NOTIFIER_HEAD(&backlight_notifier); 695 696 return 0; 697 } 698 699 /* 700 * if this is compiled into the kernel, we need to ensure that the 701 * class is registered before users of the class try to register lcd's 702 */ 703 postcore_initcall(backlight_class_init); 704 module_exit(backlight_class_exit); 705 706 MODULE_LICENSE("GPL"); 707 MODULE_AUTHOR("Jamey Hicks <jamey.hicks@hp.com>, Andrew Zabolotny <zap@homelink.ru>"); 708 MODULE_DESCRIPTION("Backlight Lowlevel Control Abstraction"); 709