cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

cros_kbd_led_backlight.c (2961B)


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