drivers/platform/chrome/cros_kbd_led_backlight.c

Source file repositories/reference/linux-study-clean/drivers/platform/chrome/cros_kbd_led_backlight.c

File Facts

System
Linux kernel
Corpus path
drivers/platform/chrome/cros_kbd_led_backlight.c
Extension
.c
Size
7044 bytes
Lines
242
Domain
Driver Families
Bucket
drivers/platform
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct keyboard_led {
	struct led_classdev cdev;
	struct cros_ec_device *ec;
};

/**
 * struct keyboard_led_drvdata - keyboard LED driver data.
 * @init:			Init function.
 * @brightness_get:		Get LED brightness level.
 * @brightness_set:		Set LED brightness level.  Must not sleep.
 * @brightness_set_blocking:	Set LED brightness level.  It can block the
 *				caller for the time required for accessing a
 *				LED device register
 *
 * See struct led_classdev in include/linux/leds.h for more details.
 */
struct keyboard_led_drvdata {
	int (*init)(struct platform_device *pdev, struct keyboard_led *keyboard_led);

	enum led_brightness (*brightness_get)(struct led_classdev *led_cdev);

	void (*brightness_set)(struct led_classdev *led_cdev,
			       enum led_brightness brightness);
	int (*brightness_set_blocking)(struct led_classdev *led_cdev,
				       enum led_brightness brightness);
};

#ifdef CONFIG_ACPI

/* Keyboard LED ACPI Device must be defined in firmware */
#define ACPI_KEYBOARD_BACKLIGHT_DEVICE	"\\_SB.KBLT"
#define ACPI_KEYBOARD_BACKLIGHT_READ	ACPI_KEYBOARD_BACKLIGHT_DEVICE ".KBQC"
#define ACPI_KEYBOARD_BACKLIGHT_WRITE	ACPI_KEYBOARD_BACKLIGHT_DEVICE ".KBCM"

static void keyboard_led_set_brightness_acpi(struct led_classdev *cdev,
					     enum led_brightness brightness)
{
	union acpi_object param;
	struct acpi_object_list input;
	acpi_status status;

	param.type = ACPI_TYPE_INTEGER;
	param.integer.value = brightness;
	input.count = 1;
	input.pointer = &param;

	status = acpi_evaluate_object(NULL, ACPI_KEYBOARD_BACKLIGHT_WRITE,
				      &input, NULL);
	if (ACPI_FAILURE(status))
		dev_err(cdev->dev, "Error setting keyboard LED value: %d\n",
			status);
}

static enum led_brightness
keyboard_led_get_brightness_acpi(struct led_classdev *cdev)
{
	unsigned long long brightness;
	acpi_status status;

	status = acpi_evaluate_integer(NULL, ACPI_KEYBOARD_BACKLIGHT_READ,
				       NULL, &brightness);
	if (ACPI_FAILURE(status)) {
		dev_err(cdev->dev, "Error getting keyboard LED value: %d\n",
			status);
		return -EIO;
	}

	return brightness;
}

static int keyboard_led_init_acpi(struct platform_device *pdev,
				  struct keyboard_led *keyboard_led)
{
	acpi_handle handle;
	acpi_status status;

	/* Look for the keyboard LED ACPI Device */
	status = acpi_get_handle(ACPI_ROOT_OBJECT,
				 ACPI_KEYBOARD_BACKLIGHT_DEVICE,
				 &handle);
	if (ACPI_FAILURE(status)) {
		dev_err(&pdev->dev, "Unable to find ACPI device %s: %d\n",
			ACPI_KEYBOARD_BACKLIGHT_DEVICE, status);
		return -ENXIO;
	}

	return 0;
}

static const struct keyboard_led_drvdata keyboard_led_drvdata_acpi = {

Annotation

Implementation Notes