forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-09 95099d4622f8cb224d94e314c7a8e0df60b13f87
kernel/drivers/video/backlight/backlight.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Backlight Lowlevel Control Abstraction
34 *
....@@ -21,6 +22,47 @@
2122 #include <asm/backlight.h>
2223 #endif
2324
25
+/**
26
+ * DOC: overview
27
+ *
28
+ * The backlight core supports implementing backlight drivers.
29
+ *
30
+ * A backlight driver registers a driver using
31
+ * devm_backlight_device_register(). The properties of the backlight
32
+ * driver such as type and max_brightness must be specified.
33
+ * When the core detect changes in for example brightness or power state
34
+ * the update_status() operation is called. The backlight driver shall
35
+ * implement this operation and use it to adjust backlight.
36
+ *
37
+ * Several sysfs attributes are provided by the backlight core::
38
+ *
39
+ * - brightness R/W, set the requested brightness level
40
+ * - actual_brightness RO, the brightness level used by the HW
41
+ * - max_brightness RO, the maximum brightness level supported
42
+ *
43
+ * See Documentation/ABI/stable/sysfs-class-backlight for the full list.
44
+ *
45
+ * The backlight can be adjusted using the sysfs interface, and
46
+ * the backlight driver may also support adjusting backlight using
47
+ * a hot-key or some other platform or firmware specific way.
48
+ *
49
+ * The driver must implement the get_brightness() operation if
50
+ * the HW do not support all the levels that can be specified in
51
+ * brightness, thus providing user-space access to the actual level
52
+ * via the actual_brightness attribute.
53
+ *
54
+ * When the backlight changes this is reported to user-space using
55
+ * an uevent connected to the actual_brightness attribute.
56
+ * When brightness is set by platform specific means, for example
57
+ * a hot-key to adjust backlight, the driver must notify the backlight
58
+ * core that brightness has changed using backlight_force_update().
59
+ *
60
+ * The backlight driver core receives notifications from fbdev and
61
+ * if the event is FB_EVENT_BLANK and if the value of blank, from the
62
+ * FBIOBLANK ioctrl, results in a change in the backlight state the
63
+ * update_status() operation is called.
64
+ */
65
+
2466 static struct list_head backlight_dev_list;
2567 static struct mutex backlight_dev_list_mutex;
2668 static struct blocking_notifier_head backlight_notifier;
....@@ -31,11 +73,25 @@
3173 [BACKLIGHT_FIRMWARE] = "firmware",
3274 };
3375
76
+static const char *const backlight_scale_types[] = {
77
+ [BACKLIGHT_SCALE_UNKNOWN] = "unknown",
78
+ [BACKLIGHT_SCALE_LINEAR] = "linear",
79
+ [BACKLIGHT_SCALE_NON_LINEAR] = "non-linear",
80
+};
81
+
3482 #if defined(CONFIG_FB) || (defined(CONFIG_FB_MODULE) && \
3583 defined(CONFIG_BACKLIGHT_CLASS_DEVICE_MODULE))
36
-/* This callback gets called when something important happens inside a
37
- * framebuffer driver. We're looking if that important event is blanking,
38
- * and if it is and necessary, we're switching backlight power as well ...
84
+/*
85
+ * fb_notifier_callback
86
+ *
87
+ * This callback gets called when something important happens inside a
88
+ * framebuffer driver. The backlight core only cares about FB_BLANK_UNBLANK
89
+ * which is reported to the driver using backlight_update_status()
90
+ * as a state change.
91
+ *
92
+ * There may be several fbdev's connected to the backlight device,
93
+ * in which case they are kept track of. A state change is only reported
94
+ * if there is a change in backlight for the specified fbdev.
3995 */
4096 static int fb_notifier_callback(struct notifier_block *self,
4197 unsigned long event, void *data)
....@@ -46,33 +102,34 @@
46102 int fb_blank = 0;
47103
48104 /* If we aren't interested in this event, skip it immediately ... */
49
- if (event != FB_EVENT_BLANK && event != FB_EVENT_CONBLANK)
105
+ if (event != FB_EVENT_BLANK)
50106 return 0;
51107
52108 bd = container_of(self, struct backlight_device, fb_notif);
53109 mutex_lock(&bd->ops_lock);
54
- if (bd->ops)
55
- if (!bd->ops->check_fb ||
56
- bd->ops->check_fb(bd, evdata->info)) {
57
- fb_blank = *(int *)evdata->data;
58
- if (fb_blank == FB_BLANK_UNBLANK &&
59
- !bd->fb_bl_on[node]) {
60
- bd->fb_bl_on[node] = true;
61
- if (!bd->use_count++) {
62
- bd->props.state &= ~BL_CORE_FBBLANK;
63
- bd->props.fb_blank = FB_BLANK_UNBLANK;
64
- backlight_update_status(bd);
65
- }
66
- } else if (fb_blank != FB_BLANK_UNBLANK &&
67
- bd->fb_bl_on[node]) {
68
- bd->fb_bl_on[node] = false;
69
- if (!(--bd->use_count)) {
70
- bd->props.state |= BL_CORE_FBBLANK;
71
- bd->props.fb_blank = fb_blank;
72
- backlight_update_status(bd);
73
- }
74
- }
110
+
111
+ if (!bd->ops)
112
+ goto out;
113
+ if (bd->ops->check_fb && !bd->ops->check_fb(bd, evdata->info))
114
+ goto out;
115
+
116
+ fb_blank = *(int *)evdata->data;
117
+ if (fb_blank == FB_BLANK_UNBLANK && !bd->fb_bl_on[node]) {
118
+ bd->fb_bl_on[node] = true;
119
+ if (!bd->use_count++) {
120
+ bd->props.state &= ~BL_CORE_FBBLANK;
121
+ bd->props.fb_blank = FB_BLANK_UNBLANK;
122
+ backlight_update_status(bd);
75123 }
124
+ } else if (fb_blank != FB_BLANK_UNBLANK && bd->fb_bl_on[node]) {
125
+ bd->fb_bl_on[node] = false;
126
+ if (!(--bd->use_count)) {
127
+ bd->props.state |= BL_CORE_FBBLANK;
128
+ bd->props.fb_blank = fb_blank;
129
+ backlight_update_status(bd);
130
+ }
131
+ }
132
+out:
76133 mutex_unlock(&bd->ops_lock);
77134 return 0;
78135 }
....@@ -245,6 +302,18 @@
245302 }
246303 static DEVICE_ATTR_RO(actual_brightness);
247304
305
+static ssize_t scale_show(struct device *dev,
306
+ struct device_attribute *attr, char *buf)
307
+{
308
+ struct backlight_device *bd = to_backlight_device(dev);
309
+
310
+ if (WARN_ON(bd->props.scale > BACKLIGHT_SCALE_NON_LINEAR))
311
+ return sprintf(buf, "unknown\n");
312
+
313
+ return sprintf(buf, "%s\n", backlight_scale_types[bd->props.scale]);
314
+}
315
+static DEVICE_ATTR_RO(scale);
316
+
248317 static struct class *backlight_class;
249318
250319 #ifdef CONFIG_PM_SLEEP
....@@ -291,6 +360,7 @@
291360 &dev_attr_brightness.attr,
292361 &dev_attr_actual_brightness.attr,
293362 &dev_attr_max_brightness.attr,
363
+ &dev_attr_scale.attr,
294364 &dev_attr_type.attr,
295365 NULL,
296366 };
....@@ -300,9 +370,13 @@
300370 * backlight_force_update - tell the backlight subsystem that hardware state
301371 * has changed
302372 * @bd: the backlight device to update
373
+ * @reason: reason for update
303374 *
304375 * Updates the internal state of the backlight in response to a hardware event,
305
- * and generate a uevent to notify userspace
376
+ * and generates an uevent to notify userspace. A backlight driver shall call
377
+ * backlight_force_update() when the backlight is changed using, for example,
378
+ * a hot-key. The updated brightness is read using get_brightness() and the
379
+ * brightness value is reported using an uevent.
306380 */
307381 void backlight_force_update(struct backlight_device *bd,
308382 enum backlight_update_reason reason)
....@@ -315,19 +389,7 @@
315389 }
316390 EXPORT_SYMBOL(backlight_force_update);
317391
318
-/**
319
- * backlight_device_register - create and register a new object of
320
- * backlight_device class.
321
- * @name: the name of the new object(must be the same as the name of the
322
- * respective framebuffer device).
323
- * @parent: a pointer to the parent device
324
- * @devdata: an optional pointer to be stored for private driver use. The
325
- * methods may retrieve it by using bl_get_data(bd).
326
- * @ops: the backlight operations structure.
327
- *
328
- * Creates and registers new backlight device. Returns either an
329
- * ERR_PTR() or a pointer to the newly allocated device.
330
- */
392
+/* deprecated - use devm_backlight_device_register() */
331393 struct backlight_device *backlight_device_register(const char *name,
332394 struct device *parent, void *devdata, const struct backlight_ops *ops,
333395 const struct backlight_properties *props)
....@@ -394,6 +456,15 @@
394456 }
395457 EXPORT_SYMBOL(backlight_device_register);
396458
459
+/** backlight_device_get_by_type - find first backlight device of a type
460
+ * @type: the type of backlight device
461
+ *
462
+ * Look up the first backlight device of the specified type
463
+ *
464
+ * RETURNS:
465
+ *
466
+ * Pointer to backlight device if any was found. Otherwise NULL.
467
+ */
397468 struct backlight_device *backlight_device_get_by_type(enum backlight_type type)
398469 {
399470 bool found = false;
....@@ -413,11 +484,27 @@
413484 EXPORT_SYMBOL(backlight_device_get_by_type);
414485
415486 /**
416
- * backlight_device_unregister - unregisters a backlight device object.
417
- * @bd: the backlight device object to be unregistered and freed.
487
+ * backlight_device_get_by_name - Get backlight device by name
488
+ * @name: Device name
418489 *
419
- * Unregisters a previously registered via backlight_device_register object.
490
+ * This function looks up a backlight device by its name. It obtains a reference
491
+ * on the backlight device and it is the caller's responsibility to drop the
492
+ * reference by calling backlight_put().
493
+ *
494
+ * Returns:
495
+ * A pointer to the backlight device if found, otherwise NULL.
420496 */
497
+struct backlight_device *backlight_device_get_by_name(const char *name)
498
+{
499
+ struct device *dev;
500
+
501
+ dev = class_find_device_by_name(backlight_class, name);
502
+
503
+ return dev ? to_backlight_device(dev) : NULL;
504
+}
505
+EXPORT_SYMBOL(backlight_device_get_by_name);
506
+
507
+/* deprecated - use devm_backlight_device_unregister() */
421508 void backlight_device_unregister(struct backlight_device *bd)
422509 {
423510 if (!bd)
....@@ -465,10 +552,12 @@
465552 * backlight_register_notifier - get notified of backlight (un)registration
466553 * @nb: notifier block with the notifier to call on backlight (un)registration
467554 *
468
- * @return 0 on success, otherwise a negative error code
469
- *
470555 * Register a notifier to get notified when backlight devices get registered
471556 * or unregistered.
557
+ *
558
+ * RETURNS:
559
+ *
560
+ * 0 on success, otherwise a negative error code
472561 */
473562 int backlight_register_notifier(struct notifier_block *nb)
474563 {
....@@ -480,10 +569,12 @@
480569 * backlight_unregister_notifier - unregister a backlight notifier
481570 * @nb: notifier block to unregister
482571 *
483
- * @return 0 on success, otherwise a negative error code
484
- *
485572 * Register a notifier to get notified when backlight devices get registered
486573 * or unregistered.
574
+ *
575
+ * RETURNS:
576
+ *
577
+ * 0 on success, otherwise a negative error code
487578 */
488579 int backlight_unregister_notifier(struct notifier_block *nb)
489580 {
....@@ -492,19 +583,21 @@
492583 EXPORT_SYMBOL(backlight_unregister_notifier);
493584
494585 /**
495
- * devm_backlight_device_register - resource managed backlight_device_register()
586
+ * devm_backlight_device_register - register a new backlight device
496587 * @dev: the device to register
497588 * @name: the name of the device
498
- * @parent: a pointer to the parent device
589
+ * @parent: a pointer to the parent device (often the same as @dev)
499590 * @devdata: an optional pointer to be stored for private driver use
500591 * @ops: the backlight operations structure
501592 * @props: the backlight properties
502593 *
503
- * @return a struct backlight on success, or an ERR_PTR on error
594
+ * Creates and registers new backlight device. When a backlight device
595
+ * is registered the configuration must be specified in the @props
596
+ * parameter. See description of &backlight_properties.
504597 *
505
- * Managed backlight_device_register(). The backlight_device returned
506
- * from this function are automatically freed on driver detach.
507
- * See backlight_device_register() for more information.
598
+ * RETURNS:
599
+ *
600
+ * struct backlight on success, or an ERR_PTR on error
508601 */
509602 struct backlight_device *devm_backlight_device_register(struct device *dev,
510603 const char *name, struct device *parent, void *devdata,
....@@ -532,13 +625,13 @@
532625 EXPORT_SYMBOL(devm_backlight_device_register);
533626
534627 /**
535
- * devm_backlight_device_unregister - resource managed backlight_device_unregister()
628
+ * devm_backlight_device_unregister - unregister backlight device
536629 * @dev: the device to unregister
537630 * @bd: the backlight device to unregister
538631 *
539
- * Deallocated a backlight allocated with devm_backlight_device_register().
632
+ * Deallocates a backlight allocated with devm_backlight_device_register().
540633 * Normally this function will not need to be called and the resource management
541
- * code will ensure that the resource is freed.
634
+ * code will ensure that the resources are freed.
542635 */
543636 void devm_backlight_device_unregister(struct device *dev,
544637 struct backlight_device *bd)
....@@ -580,22 +673,7 @@
580673 EXPORT_SYMBOL(of_find_backlight_by_node);
581674 #endif
582675
583
-/**
584
- * of_find_backlight - Get backlight device
585
- * @dev: Device
586
- *
587
- * This function looks for a property named 'backlight' on the DT node
588
- * connected to @dev and looks up the backlight device.
589
- *
590
- * Call backlight_put() to drop the reference on the backlight device.
591
- *
592
- * Returns:
593
- * A pointer to the backlight device if found.
594
- * Error pointer -EPROBE_DEFER if the DT property is set, but no backlight
595
- * device is found.
596
- * NULL if there's no backlight property.
597
- */
598
-struct backlight_device *of_find_backlight(struct device *dev)
676
+static struct backlight_device *of_find_backlight(struct device *dev)
599677 {
600678 struct backlight_device *bd = NULL;
601679 struct device_node *np;
....@@ -615,20 +693,29 @@
615693
616694 return bd;
617695 }
618
-EXPORT_SYMBOL(of_find_backlight);
619696
620697 static void devm_backlight_release(void *data)
621698 {
622
- backlight_put(data);
699
+ struct backlight_device *bd = data;
700
+
701
+ if (bd)
702
+ put_device(&bd->dev);
623703 }
624704
625705 /**
626
- * devm_of_find_backlight - Resource-managed of_find_backlight()
627
- * @dev: Device
706
+ * devm_of_find_backlight - find backlight for a device
707
+ * @dev: the device
628708 *
629
- * Device managed version of of_find_backlight().
630
- * The reference on the backlight device is automatically
709
+ * This function looks for a property named 'backlight' on the DT node
710
+ * connected to @dev and looks up the backlight device. The lookup is
711
+ * device managed so the reference to the backlight device is automatically
631712 * dropped on driver detach.
713
+ *
714
+ * RETURNS:
715
+ *
716
+ * A pointer to the backlight device if found.
717
+ * Error pointer -EPROBE_DEFER if the DT property is set, but no backlight
718
+ * device is found. NULL if there's no backlight property.
632719 */
633720 struct backlight_device *devm_of_find_backlight(struct device *dev)
634721 {
....@@ -640,7 +727,7 @@
640727 return bd;
641728 ret = devm_add_action(dev, devm_backlight_release, bd);
642729 if (ret) {
643
- backlight_put(bd);
730
+ put_device(&bd->dev);
644731 return ERR_PTR(ret);
645732 }
646733 return bd;