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

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>

authored by

Simon Que and committed by
Olof Johansson
492ef782 48b9b6d4

+140 -7
+10
drivers/platform/chrome/Kconfig
··· 64 64 help 65 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 77 endif # CHROMEOS_PLATFORMS
+8 -7
drivers/platform/chrome/Makefile
··· 1 1 2 - obj-$(CONFIG_CHROMEOS_LAPTOP) += chromeos_laptop.o 3 - obj-$(CONFIG_CHROMEOS_PSTORE) += chromeos_pstore.o 4 - cros_ec_devs-objs := cros_ec_dev.o cros_ec_sysfs.o \ 5 - cros_ec_lightbar.o cros_ec_vbc.o 6 - obj-$(CONFIG_CROS_EC_CHARDEV) += cros_ec_devs.o 7 - obj-$(CONFIG_CROS_EC_LPC) += cros_ec_lpc.o 8 - obj-$(CONFIG_CROS_EC_PROTO) += cros_ec_proto.o 2 + obj-$(CONFIG_CHROMEOS_LAPTOP) += chromeos_laptop.o 3 + obj-$(CONFIG_CHROMEOS_PSTORE) += chromeos_pstore.o 4 + cros_ec_devs-objs := cros_ec_dev.o cros_ec_sysfs.o \ 5 + cros_ec_lightbar.o cros_ec_vbc.o 6 + obj-$(CONFIG_CROS_EC_CHARDEV) += cros_ec_devs.o 7 + obj-$(CONFIG_CROS_EC_LPC) += cros_ec_lpc.o 8 + obj-$(CONFIG_CROS_EC_PROTO) += cros_ec_proto.o 9 + obj-$(CONFIG_CROS_KBD_LED_BACKLIGHT) += cros_kbd_led_backlight.o
+122
drivers/platform/chrome/cros_kbd_led_backlight.c
··· 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 = &param; 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");