drivers/platform/x86/dell/dell-uart-backlight.c

Source file repositories/reference/linux-study-clean/drivers/platform/x86/dell/dell-uart-backlight.c

File Facts

System
Linux kernel
Corpus path
drivers/platform/x86/dell/dell-uart-backlight.c
Extension
.c
Size
11248 bytes
Lines
408
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 dell_uart_backlight {
	struct mutex mutex;
	wait_queue_head_t wait_queue;
	struct device *dev;
	struct backlight_device *bl;
	u8 *resp;
	u8 resp_idx;
	u8 resp_len;
	u8 resp_max_len;
	u8 pending_cmd;
	int status;
	int power;
};

/* Checksum: SUM(Length and Cmd and Data) xor 0xFF */
static u8 dell_uart_checksum(u8 *buf, int len)
{
	u8 val = 0;

	while (len-- > 0)
		val += buf[len];

	return val ^ 0xff;
}

static int dell_uart_bl_command(struct dell_uart_backlight *dell_bl,
				const u8 *cmd, int cmd_len,
				u8 *resp, int resp_max_len)
{
	int ret;

	ret = mutex_lock_killable(&dell_bl->mutex);
	if (ret)
		return ret;

	dell_bl->status = -EBUSY;
	dell_bl->resp = resp;
	dell_bl->resp_idx = 0;
	dell_bl->resp_len = -1; /* Invalid / unset */
	dell_bl->resp_max_len = resp_max_len;
	dell_bl->pending_cmd = cmd[1];

	/* The TTY buffer should be big enough to take the entire cmd in one go */
	ret = serdev_device_write_buf(to_serdev_device(dell_bl->dev), cmd, cmd_len);
	if (ret != cmd_len) {
		dev_err(dell_bl->dev, "Error writing command: %d\n", ret);
		dell_bl->status = (ret < 0) ? ret : -EIO;
		goto out;
	}

	ret = wait_event_timeout(dell_bl->wait_queue, dell_bl->status != -EBUSY,
				 DELL_BL_TIMEOUT);
	if (ret == 0) {
		dev_err(dell_bl->dev, "Timed out waiting for response.\n");
		/* Clear busy status to discard bytes received after this */
		dell_bl->status = -ETIMEDOUT;
	}

out:
	mutex_unlock(&dell_bl->mutex);
	return dell_bl->status;
}

static int dell_uart_set_brightness(struct dell_uart_backlight *dell_bl, int brightness)
{
	u8 set_brightness[SET_CMD_LEN], resp[SET_RESP_LEN];

	set_brightness[0] = DELL_SOF(SET_CMD_LEN);
	set_brightness[1] = CMD_SET_BRIGHTNESS;
	set_brightness[2] = brightness;
	set_brightness[3] = dell_uart_checksum(set_brightness, 3);

	return dell_uart_bl_command(dell_bl, set_brightness, SET_CMD_LEN, resp, SET_RESP_LEN);
}

static int dell_uart_get_brightness(struct dell_uart_backlight *dell_bl)
{
	struct device *dev = dell_bl->dev;
	u8 get_brightness[GET_CMD_LEN], resp[GET_RESP_LEN];
	int ret;

	get_brightness[0] = DELL_SOF(GET_CMD_LEN);
	get_brightness[1] = CMD_GET_BRIGHTNESS;
	get_brightness[2] = dell_uart_checksum(get_brightness, 2);

	ret = dell_uart_bl_command(dell_bl, get_brightness, GET_CMD_LEN, resp, GET_RESP_LEN);
	if (ret)
		return ret;

	if (resp[RESP_LEN] != GET_RESP_LEN) {

Annotation

Implementation Notes