diff options
| -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"); | ||
