Re: [PATCH v3 1/2] platform/x86: Add new Dell UART backlight driver

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

On 5/13/24 5:07 PM, Ilpo Järvinen wrote:
> On Mon, 13 May 2024, Hans de Goede wrote:
> 
>> Dell All In One (AIO) models released after 2017 use a backlight controller
>> board connected to an UART.
>>
>> In DSDT this uart port will be defined as:
>>
>>    Name (_HID, "DELL0501")
>>    Name (_CID, EisaId ("PNP0501")
>>
>> Instead of having a separate ACPI device with an UartSerialBusV2() resource
>> to model the backlight-controller, which would be the standard way to do
>> this.
>>
>> The acpi_quirk_skip_serdev_enumeration() has special handling for this
>> and it will make the serial port code create a serdev controller device
>> for the UART instead of a /dev/ttyS0 char-dev. It will also create
>> a dell-uart-backlight driver platform device for this driver to bind too.
>>
>> This new kernel module contains 2 drivers for this:
>>
>> 1. A simple platform driver which creates the actual serdev device
>>    (with the serdev controller device as parent)
>>
>> 2. A serdev driver for the created serdev device which exports
>>    the backlight functionality uses a standard backlight class device.
>>
>> Reported-by: Roman Bogoyev <roman@xxxxxxxxxxxxxxxxxxxx>
>> Tested-by: Roman Bogoyev <roman@xxxxxxxxxxxxxxxxxxxx>
>> Tested-by: Kai-Heng Feng <kai.heng.feng@xxxxxxxxxxxxx>
>> Co-developed-by: AceLan Kao <acelan.kao@xxxxxxxxxxxxx>
>> Signed-off-by: AceLan Kao <acelan.kao@xxxxxxxxxxxxx>
>> Signed-off-by: Hans de Goede <hdegoede@xxxxxxxxxx>
>> ---
>> Changes in v3:
>> - Rework dell_uart_bl_receive() loop (based on suggestions from Ilpo)
>> - s/SOF/DELL_SOF/ to avoid future namespace conflicts
>>
>> Changes in v2:
>> - Address various review remarks from Ilpo and Andy
>> ---
>>  drivers/platform/x86/dell/Kconfig             |  15 +
>>  drivers/platform/x86/dell/Makefile            |   1 +
>>  .../platform/x86/dell/dell-uart-backlight.c   | 398 ++++++++++++++++++
>>  3 files changed, 414 insertions(+)
>>  create mode 100644 drivers/platform/x86/dell/dell-uart-backlight.c
>>
>> diff --git a/drivers/platform/x86/dell/Kconfig b/drivers/platform/x86/dell/Kconfig
>> index bd9f445974cc..195a8bf532cc 100644
>> --- a/drivers/platform/x86/dell/Kconfig
>> +++ b/drivers/platform/x86/dell/Kconfig
>> @@ -145,6 +145,21 @@ config DELL_SMO8800
>>  	  To compile this driver as a module, choose M here: the module will
>>  	  be called dell-smo8800.
>>  
>> +config DELL_UART_BACKLIGHT
>> +	tristate "Dell AIO UART Backlight driver"
>> +	depends on ACPI
>> +	depends on BACKLIGHT_CLASS_DEVICE
>> +	depends on SERIAL_DEV_BUS
>> +	help
>> +	  Say Y here if you want to support Dell AIO UART backlight interface.
>> +	  The Dell AIO machines released after 2017 come with a UART interface
>> +	  to communicate with the backlight scalar board. This driver creates
>> +	  a standard backlight interface and talks to the scalar board through
>> +	  UART to adjust the AIO screen brightness.
>> +
>> +	  To compile this driver as a module, choose M here: the module will
>> +	  be called dell_uart_backlight.
>> +
>>  config DELL_WMI
>>  	tristate "Dell WMI notifications"
>>  	default m
>> diff --git a/drivers/platform/x86/dell/Makefile b/drivers/platform/x86/dell/Makefile
>> index 1b8942426622..8176a257d9c3 100644
>> --- a/drivers/platform/x86/dell/Makefile
>> +++ b/drivers/platform/x86/dell/Makefile
>> @@ -14,6 +14,7 @@ dell-smbios-objs			:= dell-smbios-base.o
>>  dell-smbios-$(CONFIG_DELL_SMBIOS_WMI)	+= dell-smbios-wmi.o
>>  dell-smbios-$(CONFIG_DELL_SMBIOS_SMM)	+= dell-smbios-smm.o
>>  obj-$(CONFIG_DELL_SMO8800)		+= dell-smo8800.o
>> +obj-$(CONFIG_DELL_UART_BACKLIGHT)	+= dell-uart-backlight.o
>>  obj-$(CONFIG_DELL_WMI)			+= dell-wmi.o
>>  dell-wmi-objs				:= dell-wmi-base.o
>>  dell-wmi-$(CONFIG_DELL_WMI_PRIVACY)	+= dell-wmi-privacy.o
>> diff --git a/drivers/platform/x86/dell/dell-uart-backlight.c b/drivers/platform/x86/dell/dell-uart-backlight.c
>> new file mode 100644
>> index 000000000000..4e73fa035aca
>> --- /dev/null
>> +++ b/drivers/platform/x86/dell/dell-uart-backlight.c
>> @@ -0,0 +1,398 @@
>> +// SPDX-License-Identifier: GPL-2.0-or-later
>> +/*
>> + * Dell AIO Serial Backlight Driver
>> + *
>> + * Copyright (C) 2024 Hans de Goede <hansg@xxxxxxxxxx>
>> + * Copyright (C) 2017 AceLan Kao <acelan.kao@xxxxxxxxxxxxx>
>> + */
>> +
>> +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
>> +
>> +#include <linux/acpi.h>
>> +#include <linux/backlight.h>
>> +#include <linux/delay.h>
>> +#include <linux/device.h>
>> +#include <linux/err.h>
>> +#include <linux/module.h>
>> +#include <linux/mutex.h>
>> +#include <linux/platform_device.h>
>> +#include <linux/serdev.h>
>> +#include <linux/string.h>
>> +#include <linux/types.h>
>> +#include <linux/wait.h>
>> +#include "../serdev_helpers.h"
>> +
>> +/* The backlight controller must respond within 1 second */
>> +#define DELL_BL_TIMEOUT		msecs_to_jiffies(1000)
>> +#define DELL_BL_MAX_BRIGHTNESS	100
>> +
>> +/* Defines for the commands send to the controller */
>> +
>> +/* 1st byte Start Of Frame 3 MSB bits: cmd-len + 01010 SOF marker */
>> +#define DELL_SOF(len)			(((len) << 5) | 0x0a)
>> +#define GET_CMD_LEN			3
>> +#define SET_CMD_LEN			4
>> +
>> +/* 2nd byte command */
>> +#define CMD_GET_VERSION			0x06
>> +#define CMD_SET_BRIGHTNESS		0x0b
>> +#define CMD_GET_BRIGHTNESS		0x0c
>> +#define CMD_SET_BL_POWER		0x0e
>> +
>> +/* Indexes and other defines for response received from the controller */
>> +#define RESP_LEN			0
>> +#define RESP_CMD			1 /* Echo of CMD byte from command */
>> +#define RESP_DATA			2 /* Start of received data */
>> +
>> +#define SET_RESP_LEN			3
>> +#define GET_RESP_LEN			4
>> +#define MIN_RESP_LEN			3
>> +#define MAX_RESP_LEN			80
>> +
>> +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);
>> +		ret = (ret < 0) ? ret : -EIO;
> 
> This does nothing because you return dell_bl->status.

Ugh, thank you for catching that.  This is fallout from changing the initial
status value from 0 to -EBUSY.

Ive squashed the following fix into my review-hans branch to fix this:

diff --git a/drivers/platform/x86/dell/dell-uart-backlight.c b/drivers/platform/x86/dell/dell-uart-backlight.c
index 4e73fa035aca..87d2a20b4cb3 100644
--- a/drivers/platform/x86/dell/dell-uart-backlight.c
+++ b/drivers/platform/x86/dell/dell-uart-backlight.c
@@ -95,7 +95,7 @@ static int dell_uart_bl_command(struct dell_uart_backlight *dell_bl,
 	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);
-		ret = (ret < 0) ? ret : -EIO;
+		dell_bl->status = (ret < 0) ? ret : -EIO;
 		goto out;
 	}
 

Regards,

Hans





[Index of Archives]     [Linux Kernel Development]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux