Linux Audio

Check our new training course

Loading...
Note: File does not exist in v4.6.
  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");