linux/drivers/platform/chrome/cros_kbd_led_backlight.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2// Keyboard backlight LED driver for ChromeOS
   3//
   4// Copyright (C) 2012 Google, Inc.
   5
   6#include <linux/acpi.h>
   7#include <linux/leds.h>
   8#include <linux/delay.h>
   9#include <linux/err.h>
  10#include <linux/module.h>
  11#include <linux/init.h>
  12#include <linux/kernel.h>
  13#include <linux/platform_device.h>
  14#include <linux/slab.h>
  15
  16/* Keyboard LED ACPI Device must be defined in firmware */
  17#define ACPI_KEYBOARD_BACKLIGHT_DEVICE  "\\_SB.KBLT"
  18#define ACPI_KEYBOARD_BACKLIGHT_READ    ACPI_KEYBOARD_BACKLIGHT_DEVICE ".KBQC"
  19#define ACPI_KEYBOARD_BACKLIGHT_WRITE   ACPI_KEYBOARD_BACKLIGHT_DEVICE ".KBCM"
  20
  21#define ACPI_KEYBOARD_BACKLIGHT_MAX             100
  22
  23static void keyboard_led_set_brightness(struct led_classdev *cdev,
  24                                        enum led_brightness brightness)
  25{
  26        union acpi_object param;
  27        struct acpi_object_list input;
  28        acpi_status status;
  29
  30        param.type = ACPI_TYPE_INTEGER;
  31        param.integer.value = brightness;
  32        input.count = 1;
  33        input.pointer = &param;
  34
  35        status = acpi_evaluate_object(NULL, ACPI_KEYBOARD_BACKLIGHT_WRITE,
  36                                      &input, NULL);
  37        if (ACPI_FAILURE(status))
  38                dev_err(cdev->dev, "Error setting keyboard LED value: %d\n",
  39                        status);
  40}
  41
  42static enum led_brightness
  43keyboard_led_get_brightness(struct led_classdev *cdev)
  44{
  45        unsigned long long brightness;
  46        acpi_status status;
  47
  48        status = acpi_evaluate_integer(NULL, ACPI_KEYBOARD_BACKLIGHT_READ,
  49                                       NULL, &brightness);
  50        if (ACPI_FAILURE(status)) {
  51                dev_err(cdev->dev, "Error getting keyboard LED value: %d\n",
  52                        status);
  53                return -EIO;
  54        }
  55
  56        return brightness;
  57}
  58
  59static int keyboard_led_probe(struct platform_device *pdev)
  60{
  61        struct led_classdev *cdev;
  62        acpi_handle handle;
  63        acpi_status status;
  64        int error;
  65
  66        /* Look for the keyboard LED ACPI Device */
  67        status = acpi_get_handle(ACPI_ROOT_OBJECT,
  68                                 ACPI_KEYBOARD_BACKLIGHT_DEVICE,
  69                                 &handle);
  70        if (ACPI_FAILURE(status)) {
  71                dev_err(&pdev->dev, "Unable to find ACPI device %s: %d\n",
  72                        ACPI_KEYBOARD_BACKLIGHT_DEVICE, status);
  73                return -ENXIO;
  74        }
  75
  76        cdev = devm_kzalloc(&pdev->dev, sizeof(*cdev), GFP_KERNEL);
  77        if (!cdev)
  78                return -ENOMEM;
  79
  80        cdev->name = "chromeos::kbd_backlight";
  81        cdev->max_brightness = ACPI_KEYBOARD_BACKLIGHT_MAX;
  82        cdev->flags |= LED_CORE_SUSPENDRESUME;
  83        cdev->brightness_set = keyboard_led_set_brightness;
  84        cdev->brightness_get = keyboard_led_get_brightness;
  85
  86        error = devm_led_classdev_register(&pdev->dev, cdev);
  87        if (error)
  88                return error;
  89
  90        return 0;
  91}
  92
  93static const struct acpi_device_id keyboard_led_id[] = {
  94        { "GOOG0002", 0 },
  95        { }
  96};
  97MODULE_DEVICE_TABLE(acpi, keyboard_led_id);
  98
  99static struct platform_driver keyboard_led_driver = {
 100        .driver         = {
 101                .name   = "chromeos-keyboard-leds",
 102                .acpi_match_table = ACPI_PTR(keyboard_led_id),
 103        },
 104        .probe          = keyboard_led_probe,
 105};
 106module_platform_driver(keyboard_led_driver);
 107
 108MODULE_AUTHOR("Simon Que <sque@chromium.org>");
 109MODULE_DESCRIPTION("ChromeOS Keyboard backlight LED Driver");
 110MODULE_LICENSE("GPL");
 111MODULE_ALIAS("platform:chromeos-keyboard-leds");
 112