diff options
author | Simon Que <sque@chromium.org> | 2016-03-08 14:12:46 -0500 |
---|---|---|
committer | Olof Johansson <olof@lixom.net> | 2016-05-11 14:55:47 -0400 |
commit | 492ef7829d2d09428803bffb187d5781bbc12ca5 (patch) | |
tree | d6f242596a5864505e3664d0f1a5e6861e0cff2f | |
parent | 48b9b6d4699e23cda45756b6a1fe5d481ba45914 (diff) |
platform/chrome: Add Chrome OS keyboard backlight LEDs support
This is a driver for ACPI-based keyboard backlight LEDs found on
Chromebooks. The driver locates \\_SB.KBLT ACPI device and exports
backlight as "chromeos::kbd_backlight" LED class device in sysfs.
Signed-off-by: Simon Que <sque@chromium.org>
Signed-off-by: Duncan Laurie <dlaurie@chromium.org>
Tested-by: Evan McClain <aeroevan@gmail.com>
Signed-off-by: Dmitry Torokhov <dtor@chromium.org>
Signed-off-by: Olof Johansson <olof@lixom.net>
-rw-r--r-- | drivers/platform/chrome/Kconfig | 10 | ||||
-rw-r--r-- | drivers/platform/chrome/Makefile | 15 | ||||
-rw-r--r-- | drivers/platform/chrome/cros_kbd_led_backlight.c | 122 |
3 files changed, 140 insertions, 7 deletions
diff --git a/drivers/platform/chrome/Kconfig b/drivers/platform/chrome/Kconfig index d03df4a60d05..76bdae1a93bb 100644 --- a/drivers/platform/chrome/Kconfig +++ b/drivers/platform/chrome/Kconfig | |||
@@ -64,4 +64,14 @@ config CROS_EC_PROTO | |||
64 | help | 64 | help |
65 | ChromeOS EC communication protocol helpers. | 65 | ChromeOS EC communication protocol helpers. |
66 | 66 | ||
67 | config CROS_KBD_LED_BACKLIGHT | ||
68 | tristate "Backlight LED support for Chrome OS keyboards" | ||
69 | depends on LEDS_CLASS && ACPI | ||
70 | help | ||
71 | This option enables support for the keyboard backlight LEDs on | ||
72 | select Chrome OS systems. | ||
73 | |||
74 | To compile this driver as a module, choose M here: the | ||
75 | module will be called cros_kbd_led_backlight. | ||
76 | |||
67 | endif # CHROMEOS_PLATFORMS | 77 | endif # CHROMEOS_PLATFORMS |
diff --git a/drivers/platform/chrome/Makefile b/drivers/platform/chrome/Makefile index bc498bda8211..4f3462783a3c 100644 --- a/drivers/platform/chrome/Makefile +++ b/drivers/platform/chrome/Makefile | |||
@@ -1,8 +1,9 @@ | |||
1 | 1 | ||
2 | obj-$(CONFIG_CHROMEOS_LAPTOP) += chromeos_laptop.o | 2 | obj-$(CONFIG_CHROMEOS_LAPTOP) += chromeos_laptop.o |
3 | obj-$(CONFIG_CHROMEOS_PSTORE) += chromeos_pstore.o | 3 | obj-$(CONFIG_CHROMEOS_PSTORE) += chromeos_pstore.o |
4 | cros_ec_devs-objs := cros_ec_dev.o cros_ec_sysfs.o \ | 4 | cros_ec_devs-objs := cros_ec_dev.o cros_ec_sysfs.o \ |
5 | cros_ec_lightbar.o cros_ec_vbc.o | 5 | cros_ec_lightbar.o cros_ec_vbc.o |
6 | obj-$(CONFIG_CROS_EC_CHARDEV) += cros_ec_devs.o | 6 | obj-$(CONFIG_CROS_EC_CHARDEV) += cros_ec_devs.o |
7 | obj-$(CONFIG_CROS_EC_LPC) += cros_ec_lpc.o | 7 | obj-$(CONFIG_CROS_EC_LPC) += cros_ec_lpc.o |
8 | obj-$(CONFIG_CROS_EC_PROTO) += cros_ec_proto.o | 8 | obj-$(CONFIG_CROS_EC_PROTO) += cros_ec_proto.o |
9 | obj-$(CONFIG_CROS_KBD_LED_BACKLIGHT) += cros_kbd_led_backlight.o | ||
diff --git a/drivers/platform/chrome/cros_kbd_led_backlight.c b/drivers/platform/chrome/cros_kbd_led_backlight.c new file mode 100644 index 000000000000..ca3e4da852b4 --- /dev/null +++ b/drivers/platform/chrome/cros_kbd_led_backlight.c | |||
@@ -0,0 +1,122 @@ | |||
1 | /* | ||
2 | * Keyboard backlight LED driver for Chrome OS. | ||
3 | * | ||
4 | * Copyright (C) 2012 Google, Inc. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | */ | ||
16 | |||
17 | #include <linux/acpi.h> | ||
18 | #include <linux/leds.h> | ||
19 | #include <linux/delay.h> | ||
20 | #include <linux/err.h> | ||
21 | #include <linux/module.h> | ||
22 | #include <linux/init.h> | ||
23 | #include <linux/kernel.h> | ||
24 | #include <linux/platform_device.h> | ||
25 | #include <linux/slab.h> | ||
26 | |||
27 | /* Keyboard LED ACPI Device must be defined in firmware */ | ||
28 | #define ACPI_KEYBOARD_BACKLIGHT_DEVICE "\\_SB.KBLT" | ||
29 | #define ACPI_KEYBOARD_BACKLIGHT_READ ACPI_KEYBOARD_BACKLIGHT_DEVICE ".KBQC" | ||
30 | #define ACPI_KEYBOARD_BACKLIGHT_WRITE ACPI_KEYBOARD_BACKLIGHT_DEVICE ".KBCM" | ||
31 | |||
32 | #define ACPI_KEYBOARD_BACKLIGHT_MAX 100 | ||
33 | |||
34 | static void keyboard_led_set_brightness(struct led_classdev *cdev, | ||
35 | enum led_brightness brightness) | ||
36 | { | ||
37 | union acpi_object param; | ||
38 | struct acpi_object_list input; | ||
39 | acpi_status status; | ||
40 | |||
41 | param.type = ACPI_TYPE_INTEGER; | ||
42 | param.integer.value = brightness; | ||
43 | input.count = 1; | ||
44 | input.pointer = ¶m; | ||
45 | |||
46 | status = acpi_evaluate_object(NULL, ACPI_KEYBOARD_BACKLIGHT_WRITE, | ||
47 | &input, NULL); | ||
48 | if (ACPI_FAILURE(status)) | ||
49 | dev_err(cdev->dev, "Error setting keyboard LED value: %d\n", | ||
50 | status); | ||
51 | } | ||
52 | |||
53 | static enum led_brightness | ||
54 | keyboard_led_get_brightness(struct led_classdev *cdev) | ||
55 | { | ||
56 | unsigned long long brightness; | ||
57 | acpi_status status; | ||
58 | |||
59 | status = acpi_evaluate_integer(NULL, ACPI_KEYBOARD_BACKLIGHT_READ, | ||
60 | NULL, &brightness); | ||
61 | if (ACPI_FAILURE(status)) { | ||
62 | dev_err(cdev->dev, "Error getting keyboard LED value: %d\n", | ||
63 | status); | ||
64 | return -EIO; | ||
65 | } | ||
66 | |||
67 | return brightness; | ||
68 | } | ||
69 | |||
70 | static int keyboard_led_probe(struct platform_device *pdev) | ||
71 | { | ||
72 | struct led_classdev *cdev; | ||
73 | acpi_handle handle; | ||
74 | acpi_status status; | ||
75 | int error; | ||
76 | |||
77 | /* Look for the keyboard LED ACPI Device */ | ||
78 | status = acpi_get_handle(ACPI_ROOT_OBJECT, | ||
79 | ACPI_KEYBOARD_BACKLIGHT_DEVICE, | ||
80 | &handle); | ||
81 | if (ACPI_FAILURE(status)) { | ||
82 | dev_err(&pdev->dev, "Unable to find ACPI device %s: %d\n", | ||
83 | ACPI_KEYBOARD_BACKLIGHT_DEVICE, status); | ||
84 | return -ENXIO; | ||
85 | } | ||
86 | |||
87 | cdev = devm_kzalloc(&pdev->dev, sizeof(*cdev), GFP_KERNEL); | ||
88 | if (!cdev) | ||
89 | return -ENOMEM; | ||
90 | |||
91 | cdev->name = "chromeos::kbd_backlight"; | ||
92 | cdev->max_brightness = ACPI_KEYBOARD_BACKLIGHT_MAX; | ||
93 | cdev->flags |= LED_CORE_SUSPENDRESUME; | ||
94 | cdev->brightness_set = keyboard_led_set_brightness; | ||
95 | cdev->brightness_get = keyboard_led_get_brightness; | ||
96 | |||
97 | error = devm_led_classdev_register(&pdev->dev, cdev); | ||
98 | if (error) | ||
99 | return error; | ||
100 | |||
101 | return 0; | ||
102 | } | ||
103 | |||
104 | static const struct acpi_device_id keyboard_led_id[] = { | ||
105 | { "GOOG0002", 0 }, | ||
106 | { } | ||
107 | }; | ||
108 | MODULE_DEVICE_TABLE(acpi, keyboard_led_id); | ||
109 | |||
110 | static struct platform_driver keyboard_led_driver = { | ||
111 | .driver = { | ||
112 | .name = "chromeos-keyboard-leds", | ||
113 | .acpi_match_table = ACPI_PTR(keyboard_led_id), | ||
114 | }, | ||
115 | .probe = keyboard_led_probe, | ||
116 | }; | ||
117 | module_platform_driver(keyboard_led_driver); | ||
118 | |||
119 | MODULE_AUTHOR("Simon Que <sque@chromium.org>"); | ||
120 | MODULE_DESCRIPTION("ChromeOS Keyboard backlight LED Driver"); | ||
121 | MODULE_LICENSE("GPL"); | ||
122 | MODULE_ALIAS("platform:chromeos-keyboard-leds"); | ||