mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-29 07:04:10 +08:00
platform/surface: Add DTX driver
The Microsoft Surface Book series devices consist of a so-called clipboard part (containing the CPU, touchscreen, and primary battery) and a base part (containing keyboard, secondary battery, and optional discrete GPU). These parts can be separated, i.e. the clipboard can be detached and used as tablet. This detachment process is initiated by pressing a button. On the Surface Book 2 and 3 (targeted with this commit), the Surface Aggregator Module (i.e. the embedded controller on those devices) attempts to send a notification to any listening client driver and waits for further instructions (i.e. whether the detachment process should continue or be aborted). If it does not receive a response in a certain time-frame, the detachment process (by default) continues and the clipboard can be physically separated. In other words, (by default and) without a driver, the detachment process takes about 10 seconds to complete. This commit introduces a driver for this detachment system (called DTX). This driver allows a user-space daemon to control and influence the detachment behavior. Specifically, it forwards any detachment requests to user-space, allows user-space to make such requests itself, and allows handling of those requests. Requests can be handled by either aborting, continuing/allowing, or delaying (i.e. resetting the timeout via a heartbeat commend). The user-space API is implemented via the /dev/surface/dtx miscdevice. In addition, user-space can change the default behavior on timeout from allowing detachment to disallowing it, which is useful if the (optional) discrete GPU is in use. Furthermore, this driver allows user-space to receive notifications about the state of the base, specifically when it is physically removed (as opposed to detachment requested), in what manner it is connected (i.e. in reverse-/tent-/studio- or laptop-mode), and what type of base is connected. Based on this information, the driver also provides a simple tablet-mode switch (aliasing all modes without keyboard access, i.e. tablet-mode and studio-mode to its reported tablet-mode). An implementation of such a user-space daemon, allowing configuration of detachment behavior via scripts (e.g. safely unmounting USB devices connected to the base before continuing) can be found at [1]. [1]: https://github.com/linux-surface/surface-dtx-daemon Signed-off-by: Maximilian Luz <luzmaximilian@gmail.com> Link: https://lore.kernel.org/r/20210308184819.437438-2-luzmaximilian@gmail.com Signed-off-by: Hans de Goede <hdegoede@redhat.com>
This commit is contained in:
parent
87eaede453
commit
1d60999283
@ -327,6 +327,8 @@ Code Seq# Include File Comments
|
||||
0xA4 00-1F uapi/asm/sgx.h <mailto:linux-sgx@vger.kernel.org>
|
||||
0xA5 01 linux/surface_aggregator/cdev.h Microsoft Surface Platform System Aggregator
|
||||
<mailto:luzmaximilian@gmail.com>
|
||||
0xA5 20-2F linux/surface_aggregator/dtx.h Microsoft Surface DTX driver
|
||||
<mailto:luzmaximilian@gmail.com>
|
||||
0xAA 00-3F linux/uapi/linux/userfaultfd.h
|
||||
0xAB 00-1F linux/nbd.h
|
||||
0xAC 00-1F linux/raw.h
|
||||
|
@ -11861,6 +11861,13 @@ F: drivers/scsi/smartpqi/smartpqi*.[ch]
|
||||
F: include/linux/cciss*.h
|
||||
F: include/uapi/linux/cciss*.h
|
||||
|
||||
MICROSOFT SURFACE DTX DRIVER
|
||||
M: Maximilian Luz <luzmaximilian@gmail.com>
|
||||
L: platform-driver-x86@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/platform/surface/surface_dtx.c
|
||||
F: include/uapi/linux/surface_aggregator/dtx.h
|
||||
|
||||
MICROSOFT SURFACE GPE LID SUPPORT DRIVER
|
||||
M: Maximilian Luz <luzmaximilian@gmail.com>
|
||||
L: platform-driver-x86@vger.kernel.org
|
||||
|
@ -104,6 +104,22 @@ config SURFACE_AGGREGATOR_REGISTRY
|
||||
the respective client devices. Drivers for these devices still need to
|
||||
be selected via the other options.
|
||||
|
||||
config SURFACE_DTX
|
||||
tristate "Surface DTX (Detachment System) Driver"
|
||||
depends on SURFACE_AGGREGATOR
|
||||
depends on INPUT
|
||||
help
|
||||
Driver for the Surface Book clipboard detachment system (DTX).
|
||||
|
||||
On the Surface Book series devices, the display part containing the
|
||||
CPU (called the clipboard) can be detached from the base (containing a
|
||||
battery, the keyboard, and, optionally, a discrete GPU) by (if
|
||||
necessary) unlocking and opening the latch connecting both parts.
|
||||
|
||||
This driver provides a user-space interface that can influence the
|
||||
behavior of this process, which includes the option to abort it in
|
||||
case the base is still in use or speed it up in case it is not.
|
||||
|
||||
config SURFACE_GPE
|
||||
tristate "Surface GPE/Lid Support Driver"
|
||||
depends on DMI
|
||||
|
@ -11,6 +11,7 @@ obj-$(CONFIG_SURFACE_ACPI_NOTIFY) += surface_acpi_notify.o
|
||||
obj-$(CONFIG_SURFACE_AGGREGATOR) += aggregator/
|
||||
obj-$(CONFIG_SURFACE_AGGREGATOR_CDEV) += surface_aggregator_cdev.o
|
||||
obj-$(CONFIG_SURFACE_AGGREGATOR_REGISTRY) += surface_aggregator_registry.o
|
||||
obj-$(CONFIG_SURFACE_DTX) += surface_dtx.o
|
||||
obj-$(CONFIG_SURFACE_GPE) += surface_gpe.o
|
||||
obj-$(CONFIG_SURFACE_HOTPLUG) += surface_hotplug.o
|
||||
obj-$(CONFIG_SURFACE_PLATFORM_PROFILE) += surface_platform_profile.o
|
||||
|
1201
drivers/platform/surface/surface_dtx.c
Normal file
1201
drivers/platform/surface/surface_dtx.c
Normal file
File diff suppressed because it is too large
Load Diff
146
include/uapi/linux/surface_aggregator/dtx.h
Normal file
146
include/uapi/linux/surface_aggregator/dtx.h
Normal file
@ -0,0 +1,146 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */
|
||||
/*
|
||||
* Surface DTX (clipboard detachment system driver) user-space interface.
|
||||
*
|
||||
* Definitions, structs, and IOCTLs for the /dev/surface/dtx misc device. This
|
||||
* device allows user-space to control the clipboard detachment process on
|
||||
* Surface Book series devices.
|
||||
*
|
||||
* Copyright (C) 2020-2021 Maximilian Luz <luzmaximilian@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef _UAPI_LINUX_SURFACE_AGGREGATOR_DTX_H
|
||||
#define _UAPI_LINUX_SURFACE_AGGREGATOR_DTX_H
|
||||
|
||||
#include <linux/ioctl.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
/* Status/error categories */
|
||||
#define SDTX_CATEGORY_STATUS 0x0000
|
||||
#define SDTX_CATEGORY_RUNTIME_ERROR 0x1000
|
||||
#define SDTX_CATEGORY_HARDWARE_ERROR 0x2000
|
||||
#define SDTX_CATEGORY_UNKNOWN 0xf000
|
||||
|
||||
#define SDTX_CATEGORY_MASK 0xf000
|
||||
#define SDTX_CATEGORY(value) ((value) & SDTX_CATEGORY_MASK)
|
||||
|
||||
#define SDTX_STATUS(code) ((code) | SDTX_CATEGORY_STATUS)
|
||||
#define SDTX_ERR_RT(code) ((code) | SDTX_CATEGORY_RUNTIME_ERROR)
|
||||
#define SDTX_ERR_HW(code) ((code) | SDTX_CATEGORY_HARDWARE_ERROR)
|
||||
#define SDTX_UNKNOWN(code) ((code) | SDTX_CATEGORY_UNKNOWN)
|
||||
|
||||
#define SDTX_SUCCESS(value) (SDTX_CATEGORY(value) == SDTX_CATEGORY_STATUS)
|
||||
|
||||
/* Latch status values */
|
||||
#define SDTX_LATCH_CLOSED SDTX_STATUS(0x00)
|
||||
#define SDTX_LATCH_OPENED SDTX_STATUS(0x01)
|
||||
|
||||
/* Base state values */
|
||||
#define SDTX_BASE_DETACHED SDTX_STATUS(0x00)
|
||||
#define SDTX_BASE_ATTACHED SDTX_STATUS(0x01)
|
||||
|
||||
/* Runtime errors (non-critical) */
|
||||
#define SDTX_DETACH_NOT_FEASIBLE SDTX_ERR_RT(0x01)
|
||||
#define SDTX_DETACH_TIMEDOUT SDTX_ERR_RT(0x02)
|
||||
|
||||
/* Hardware errors (critical) */
|
||||
#define SDTX_ERR_FAILED_TO_OPEN SDTX_ERR_HW(0x01)
|
||||
#define SDTX_ERR_FAILED_TO_REMAIN_OPEN SDTX_ERR_HW(0x02)
|
||||
#define SDTX_ERR_FAILED_TO_CLOSE SDTX_ERR_HW(0x03)
|
||||
|
||||
/* Base types */
|
||||
#define SDTX_DEVICE_TYPE_HID 0x0100
|
||||
#define SDTX_DEVICE_TYPE_SSH 0x0200
|
||||
|
||||
#define SDTX_DEVICE_TYPE_MASK 0x0f00
|
||||
#define SDTX_DEVICE_TYPE(value) ((value) & SDTX_DEVICE_TYPE_MASK)
|
||||
|
||||
#define SDTX_BASE_TYPE_HID(id) ((id) | SDTX_DEVICE_TYPE_HID)
|
||||
#define SDTX_BASE_TYPE_SSH(id) ((id) | SDTX_DEVICE_TYPE_SSH)
|
||||
|
||||
/**
|
||||
* enum sdtx_device_mode - Mode describing how (and if) the clipboard is
|
||||
* attached to the base of the device.
|
||||
* @SDTX_DEVICE_MODE_TABLET: The clipboard is detached from the base and the
|
||||
* device operates as tablet.
|
||||
* @SDTX_DEVICE_MODE_LAPTOP: The clipboard is attached normally to the base
|
||||
* and the device operates as laptop.
|
||||
* @SDTX_DEVICE_MODE_STUDIO: The clipboard is attached to the base in reverse.
|
||||
* The device operates as tablet with keyboard and
|
||||
* touchpad deactivated, however, the base battery
|
||||
* and, if present in the specific device model, dGPU
|
||||
* are available to the system.
|
||||
*/
|
||||
enum sdtx_device_mode {
|
||||
SDTX_DEVICE_MODE_TABLET = 0x00,
|
||||
SDTX_DEVICE_MODE_LAPTOP = 0x01,
|
||||
SDTX_DEVICE_MODE_STUDIO = 0x02,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct sdtx_event - Event provided by reading from the DTX device file.
|
||||
* @length: Length of the event payload, in bytes.
|
||||
* @code: Event code, detailing what type of event this is.
|
||||
* @data: Payload of the event, containing @length bytes.
|
||||
*
|
||||
* See &enum sdtx_event_code for currently valid event codes.
|
||||
*/
|
||||
struct sdtx_event {
|
||||
__u16 length;
|
||||
__u16 code;
|
||||
__u8 data[];
|
||||
} __attribute__((__packed__));
|
||||
|
||||
/**
|
||||
* enum sdtx_event_code - Code describing the type of an event.
|
||||
* @SDTX_EVENT_REQUEST: Detachment request event type.
|
||||
* @SDTX_EVENT_CANCEL: Cancel detachment process event type.
|
||||
* @SDTX_EVENT_BASE_CONNECTION: Base/clipboard connection change event type.
|
||||
* @SDTX_EVENT_LATCH_STATUS: Latch status change event type.
|
||||
* @SDTX_EVENT_DEVICE_MODE: Device mode change event type.
|
||||
*
|
||||
* Used in &struct sdtx_event to describe the type of the event. Further event
|
||||
* codes are reserved for future use. Any event parser should be able to
|
||||
* gracefully handle unknown events, i.e. by simply skipping them.
|
||||
*
|
||||
* Consult the DTX user-space interface documentation for details regarding
|
||||
* the individual event types.
|
||||
*/
|
||||
enum sdtx_event_code {
|
||||
SDTX_EVENT_REQUEST = 1,
|
||||
SDTX_EVENT_CANCEL = 2,
|
||||
SDTX_EVENT_BASE_CONNECTION = 3,
|
||||
SDTX_EVENT_LATCH_STATUS = 4,
|
||||
SDTX_EVENT_DEVICE_MODE = 5,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct sdtx_base_info - Describes if and what type of base is connected.
|
||||
* @state: The state of the connection. Valid values are %SDTX_BASE_DETACHED,
|
||||
* %SDTX_BASE_ATTACHED, and %SDTX_DETACH_NOT_FEASIBLE (in case a base
|
||||
* is attached but low clipboard battery prevents detachment). Other
|
||||
* values are currently reserved.
|
||||
* @base_id: The type of base connected. Zero if no base is connected.
|
||||
*/
|
||||
struct sdtx_base_info {
|
||||
__u16 state;
|
||||
__u16 base_id;
|
||||
} __attribute__((__packed__));
|
||||
|
||||
/* IOCTLs */
|
||||
#define SDTX_IOCTL_EVENTS_ENABLE _IO(0xa5, 0x21)
|
||||
#define SDTX_IOCTL_EVENTS_DISABLE _IO(0xa5, 0x22)
|
||||
|
||||
#define SDTX_IOCTL_LATCH_LOCK _IO(0xa5, 0x23)
|
||||
#define SDTX_IOCTL_LATCH_UNLOCK _IO(0xa5, 0x24)
|
||||
|
||||
#define SDTX_IOCTL_LATCH_REQUEST _IO(0xa5, 0x25)
|
||||
#define SDTX_IOCTL_LATCH_CONFIRM _IO(0xa5, 0x26)
|
||||
#define SDTX_IOCTL_LATCH_HEARTBEAT _IO(0xa5, 0x27)
|
||||
#define SDTX_IOCTL_LATCH_CANCEL _IO(0xa5, 0x28)
|
||||
|
||||
#define SDTX_IOCTL_GET_BASE_INFO _IOR(0xa5, 0x29, struct sdtx_base_info)
|
||||
#define SDTX_IOCTL_GET_DEVICE_MODE _IOR(0xa5, 0x2a, __u16)
|
||||
#define SDTX_IOCTL_GET_LATCH_STATUS _IOR(0xa5, 0x2b, __u16)
|
||||
|
||||
#endif /* _UAPI_LINUX_SURFACE_AGGREGATOR_DTX_H */
|
Loading…
Reference in New Issue
Block a user