platform/surface: Set up Surface Aggregator device registry
The Surface System Aggregator Module (SSAM) subsystem provides various
functionalities, which are separated by spreading them across multiple
devices and corresponding drivers. Parts of that functionality / some of
those devices, however, can (as far as we currently know) not be
auto-detected by conventional means. While older (specifically 5th- and
6th-)generation models do advertise most of their functionality via
standard platform devices in ACPI, newer generations do not.
As we are currently also not aware of any feasible way to query said
functionalities dynamically, this poses a problem. There is, however, a
device in ACPI that seems to be used by Windows for identifying
different Surface models: The Windows Surface Integration Device (WSID).
This device seems to have a HID corresponding to the overall set of
functionalities SSAM provides for the associated model.
This commit introduces a registry providing non-detectable device
information via software nodes. In addition, a SSAM platform hub driver
is introduced, which takes care of creating and managing the SSAM
devices specified in this registry. This approach allows for a
hierarchical setup akin to ACPI and is easily extendable, e.g. via
firmware node properties.
Note that this commit only provides the basis for the platform hub and
registry, and does not add any content to it. The registry will be
expanded in subsequent commits.
Signed-off-by: Maximilian Luz <luzmaximilian@gmail.com>
Link: https://lore.kernel.org/r/20210212115439.1525216-2-luzmaximilian@gmail.com
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
2021-02-12 12:54:34 +01:00
|
|
|
// SPDX-License-Identifier: GPL-2.0+
|
|
|
|
|
/*
|
|
|
|
|
* Surface System Aggregator Module (SSAM) client device registry.
|
|
|
|
|
*
|
|
|
|
|
* Registry for non-platform/non-ACPI SSAM client devices, i.e. devices that
|
|
|
|
|
* cannot be auto-detected. Provides device-hubs and performs instantiation
|
|
|
|
|
* for these devices.
|
|
|
|
|
*
|
|
|
|
|
* Copyright (C) 2020-2021 Maximilian Luz <luzmaximilian@gmail.com>
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include <linux/acpi.h>
|
|
|
|
|
#include <linux/kernel.h>
|
2021-02-12 12:54:35 +01:00
|
|
|
#include <linux/limits.h>
|
platform/surface: Set up Surface Aggregator device registry
The Surface System Aggregator Module (SSAM) subsystem provides various
functionalities, which are separated by spreading them across multiple
devices and corresponding drivers. Parts of that functionality / some of
those devices, however, can (as far as we currently know) not be
auto-detected by conventional means. While older (specifically 5th- and
6th-)generation models do advertise most of their functionality via
standard platform devices in ACPI, newer generations do not.
As we are currently also not aware of any feasible way to query said
functionalities dynamically, this poses a problem. There is, however, a
device in ACPI that seems to be used by Windows for identifying
different Surface models: The Windows Surface Integration Device (WSID).
This device seems to have a HID corresponding to the overall set of
functionalities SSAM provides for the associated model.
This commit introduces a registry providing non-detectable device
information via software nodes. In addition, a SSAM platform hub driver
is introduced, which takes care of creating and managing the SSAM
devices specified in this registry. This approach allows for a
hierarchical setup akin to ACPI and is easily extendable, e.g. via
firmware node properties.
Note that this commit only provides the basis for the platform hub and
registry, and does not add any content to it. The registry will be
expanded in subsequent commits.
Signed-off-by: Maximilian Luz <luzmaximilian@gmail.com>
Link: https://lore.kernel.org/r/20210212115439.1525216-2-luzmaximilian@gmail.com
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
2021-02-12 12:54:34 +01:00
|
|
|
#include <linux/module.h>
|
|
|
|
|
#include <linux/platform_device.h>
|
|
|
|
|
#include <linux/property.h>
|
2021-02-12 12:54:35 +01:00
|
|
|
#include <linux/types.h>
|
2021-04-06 01:12:22 +02:00
|
|
|
#include <linux/workqueue.h>
|
platform/surface: Set up Surface Aggregator device registry
The Surface System Aggregator Module (SSAM) subsystem provides various
functionalities, which are separated by spreading them across multiple
devices and corresponding drivers. Parts of that functionality / some of
those devices, however, can (as far as we currently know) not be
auto-detected by conventional means. While older (specifically 5th- and
6th-)generation models do advertise most of their functionality via
standard platform devices in ACPI, newer generations do not.
As we are currently also not aware of any feasible way to query said
functionalities dynamically, this poses a problem. There is, however, a
device in ACPI that seems to be used by Windows for identifying
different Surface models: The Windows Surface Integration Device (WSID).
This device seems to have a HID corresponding to the overall set of
functionalities SSAM provides for the associated model.
This commit introduces a registry providing non-detectable device
information via software nodes. In addition, a SSAM platform hub driver
is introduced, which takes care of creating and managing the SSAM
devices specified in this registry. This approach allows for a
hierarchical setup akin to ACPI and is easily extendable, e.g. via
firmware node properties.
Note that this commit only provides the basis for the platform hub and
registry, and does not add any content to it. The registry will be
expanded in subsequent commits.
Signed-off-by: Maximilian Luz <luzmaximilian@gmail.com>
Link: https://lore.kernel.org/r/20210212115439.1525216-2-luzmaximilian@gmail.com
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
2021-02-12 12:54:34 +01:00
|
|
|
|
|
|
|
|
#include <linux/surface_aggregator/controller.h>
|
|
|
|
|
#include <linux/surface_aggregator/device.h>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* -- Device registry. ------------------------------------------------------ */
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* SSAM device names follow the SSAM module alias, meaning they are prefixed
|
|
|
|
|
* with 'ssam:', followed by domain, category, target ID, instance ID, and
|
|
|
|
|
* function, each encoded as two-digit hexadecimal, separated by ':'. In other
|
|
|
|
|
* words, it follows the scheme
|
|
|
|
|
*
|
|
|
|
|
* ssam:dd:cc:tt:ii:ff
|
|
|
|
|
*
|
|
|
|
|
* Where, 'dd', 'cc', 'tt', 'ii', and 'ff' are the two-digit hexadecimal
|
|
|
|
|
* values mentioned above, respectively.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/* Root node. */
|
|
|
|
|
static const struct software_node ssam_node_root = {
|
|
|
|
|
.name = "ssam_platform_hub",
|
|
|
|
|
};
|
|
|
|
|
|
2022-05-27 04:34:47 +02:00
|
|
|
/* KIP device hub (connects keyboard cover devices on Surface Pro 8). */
|
|
|
|
|
static const struct software_node ssam_node_hub_kip = {
|
|
|
|
|
.name = "ssam:00:00:01:0e:00",
|
|
|
|
|
.parent = &ssam_node_root,
|
|
|
|
|
};
|
|
|
|
|
|
2021-02-12 12:54:35 +01:00
|
|
|
/* Base device hub (devices attached to Surface Book 3 base). */
|
|
|
|
|
static const struct software_node ssam_node_hub_base = {
|
2022-05-27 04:34:45 +02:00
|
|
|
.name = "ssam:00:00:02:11:00",
|
2021-02-12 12:54:35 +01:00
|
|
|
.parent = &ssam_node_root,
|
|
|
|
|
};
|
|
|
|
|
|
2021-02-12 12:54:36 +01:00
|
|
|
/* AC adapter. */
|
|
|
|
|
static const struct software_node ssam_node_bat_ac = {
|
|
|
|
|
.name = "ssam:01:02:01:01:01",
|
|
|
|
|
.parent = &ssam_node_root,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/* Primary battery. */
|
|
|
|
|
static const struct software_node ssam_node_bat_main = {
|
|
|
|
|
.name = "ssam:01:02:01:01:00",
|
|
|
|
|
.parent = &ssam_node_root,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/* Secondary battery (Surface Book 3). */
|
|
|
|
|
static const struct software_node ssam_node_bat_sb3base = {
|
|
|
|
|
.name = "ssam:01:02:02:01:00",
|
|
|
|
|
.parent = &ssam_node_hub_base,
|
|
|
|
|
};
|
|
|
|
|
|
2021-02-12 12:54:37 +01:00
|
|
|
/* Platform profile / performance-mode device. */
|
|
|
|
|
static const struct software_node ssam_node_tmp_pprof = {
|
|
|
|
|
.name = "ssam:01:03:01:00:01",
|
|
|
|
|
.parent = &ssam_node_root,
|
|
|
|
|
};
|
|
|
|
|
|
2021-02-12 12:54:38 +01:00
|
|
|
/* DTX / detachment-system device (Surface Book 3). */
|
|
|
|
|
static const struct software_node ssam_node_bas_dtx = {
|
|
|
|
|
.name = "ssam:01:11:01:00:00",
|
|
|
|
|
.parent = &ssam_node_root,
|
|
|
|
|
};
|
|
|
|
|
|
2021-10-21 15:09:02 +02:00
|
|
|
/* HID keyboard (TID1). */
|
|
|
|
|
static const struct software_node ssam_node_hid_tid1_keyboard = {
|
|
|
|
|
.name = "ssam:01:15:01:01:00",
|
|
|
|
|
.parent = &ssam_node_root,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/* HID pen stash (TID1; pen taken / stashed away evens). */
|
|
|
|
|
static const struct software_node ssam_node_hid_tid1_penstash = {
|
|
|
|
|
.name = "ssam:01:15:01:02:00",
|
|
|
|
|
.parent = &ssam_node_root,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/* HID touchpad (TID1). */
|
|
|
|
|
static const struct software_node ssam_node_hid_tid1_touchpad = {
|
|
|
|
|
.name = "ssam:01:15:01:03:00",
|
|
|
|
|
.parent = &ssam_node_root,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/* HID device instance 6 (TID1, unknown HID device). */
|
|
|
|
|
static const struct software_node ssam_node_hid_tid1_iid6 = {
|
|
|
|
|
.name = "ssam:01:15:01:06:00",
|
|
|
|
|
.parent = &ssam_node_root,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/* HID device instance 7 (TID1, unknown HID device). */
|
|
|
|
|
static const struct software_node ssam_node_hid_tid1_iid7 = {
|
|
|
|
|
.name = "ssam:01:15:01:07:00",
|
|
|
|
|
.parent = &ssam_node_root,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/* HID system controls (TID1). */
|
|
|
|
|
static const struct software_node ssam_node_hid_tid1_sysctrl = {
|
|
|
|
|
.name = "ssam:01:15:01:08:00",
|
|
|
|
|
.parent = &ssam_node_root,
|
|
|
|
|
};
|
|
|
|
|
|
2021-02-12 12:54:39 +01:00
|
|
|
/* HID keyboard. */
|
|
|
|
|
static const struct software_node ssam_node_hid_main_keyboard = {
|
|
|
|
|
.name = "ssam:01:15:02:01:00",
|
|
|
|
|
.parent = &ssam_node_root,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/* HID touchpad. */
|
|
|
|
|
static const struct software_node ssam_node_hid_main_touchpad = {
|
|
|
|
|
.name = "ssam:01:15:02:03:00",
|
|
|
|
|
.parent = &ssam_node_root,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/* HID device instance 5 (unknown HID device). */
|
|
|
|
|
static const struct software_node ssam_node_hid_main_iid5 = {
|
|
|
|
|
.name = "ssam:01:15:02:05:00",
|
|
|
|
|
.parent = &ssam_node_root,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/* HID keyboard (base hub). */
|
|
|
|
|
static const struct software_node ssam_node_hid_base_keyboard = {
|
|
|
|
|
.name = "ssam:01:15:02:01:00",
|
|
|
|
|
.parent = &ssam_node_hub_base,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/* HID touchpad (base hub). */
|
|
|
|
|
static const struct software_node ssam_node_hid_base_touchpad = {
|
|
|
|
|
.name = "ssam:01:15:02:03:00",
|
|
|
|
|
.parent = &ssam_node_hub_base,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/* HID device instance 5 (unknown HID device, base hub). */
|
|
|
|
|
static const struct software_node ssam_node_hid_base_iid5 = {
|
|
|
|
|
.name = "ssam:01:15:02:05:00",
|
|
|
|
|
.parent = &ssam_node_hub_base,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/* HID device instance 6 (unknown HID device, base hub). */
|
|
|
|
|
static const struct software_node ssam_node_hid_base_iid6 = {
|
|
|
|
|
.name = "ssam:01:15:02:06:00",
|
|
|
|
|
.parent = &ssam_node_hub_base,
|
|
|
|
|
};
|
|
|
|
|
|
2022-05-27 04:34:47 +02:00
|
|
|
/* HID keyboard (KIP hub). */
|
|
|
|
|
static const struct software_node ssam_node_hid_kip_keyboard = {
|
|
|
|
|
.name = "ssam:01:15:02:01:00",
|
|
|
|
|
.parent = &ssam_node_hub_kip,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/* HID pen stash (KIP hub; pen taken / stashed away evens). */
|
|
|
|
|
static const struct software_node ssam_node_hid_kip_penstash = {
|
|
|
|
|
.name = "ssam:01:15:02:02:00",
|
|
|
|
|
.parent = &ssam_node_hub_kip,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/* HID touchpad (KIP hub). */
|
|
|
|
|
static const struct software_node ssam_node_hid_kip_touchpad = {
|
|
|
|
|
.name = "ssam:01:15:02:03:00",
|
|
|
|
|
.parent = &ssam_node_hub_kip,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/* HID device instance 5 (KIP hub, unknown HID device). */
|
|
|
|
|
static const struct software_node ssam_node_hid_kip_iid5 = {
|
|
|
|
|
.name = "ssam:01:15:02:05:00",
|
|
|
|
|
.parent = &ssam_node_hub_kip,
|
|
|
|
|
};
|
|
|
|
|
|
2021-05-23 15:45:28 +02:00
|
|
|
/*
|
|
|
|
|
* Devices for 5th- and 6th-generations models:
|
|
|
|
|
* - Surface Book 2,
|
|
|
|
|
* - Surface Laptop 1 and 2,
|
|
|
|
|
* - Surface Pro 5 and 6.
|
|
|
|
|
*/
|
|
|
|
|
static const struct software_node *ssam_node_group_gen5[] = {
|
platform/surface: Set up Surface Aggregator device registry
The Surface System Aggregator Module (SSAM) subsystem provides various
functionalities, which are separated by spreading them across multiple
devices and corresponding drivers. Parts of that functionality / some of
those devices, however, can (as far as we currently know) not be
auto-detected by conventional means. While older (specifically 5th- and
6th-)generation models do advertise most of their functionality via
standard platform devices in ACPI, newer generations do not.
As we are currently also not aware of any feasible way to query said
functionalities dynamically, this poses a problem. There is, however, a
device in ACPI that seems to be used by Windows for identifying
different Surface models: The Windows Surface Integration Device (WSID).
This device seems to have a HID corresponding to the overall set of
functionalities SSAM provides for the associated model.
This commit introduces a registry providing non-detectable device
information via software nodes. In addition, a SSAM platform hub driver
is introduced, which takes care of creating and managing the SSAM
devices specified in this registry. This approach allows for a
hierarchical setup akin to ACPI and is easily extendable, e.g. via
firmware node properties.
Note that this commit only provides the basis for the platform hub and
registry, and does not add any content to it. The registry will be
expanded in subsequent commits.
Signed-off-by: Maximilian Luz <luzmaximilian@gmail.com>
Link: https://lore.kernel.org/r/20210212115439.1525216-2-luzmaximilian@gmail.com
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
2021-02-12 12:54:34 +01:00
|
|
|
&ssam_node_root,
|
2021-02-12 12:54:37 +01:00
|
|
|
&ssam_node_tmp_pprof,
|
platform/surface: Set up Surface Aggregator device registry
The Surface System Aggregator Module (SSAM) subsystem provides various
functionalities, which are separated by spreading them across multiple
devices and corresponding drivers. Parts of that functionality / some of
those devices, however, can (as far as we currently know) not be
auto-detected by conventional means. While older (specifically 5th- and
6th-)generation models do advertise most of their functionality via
standard platform devices in ACPI, newer generations do not.
As we are currently also not aware of any feasible way to query said
functionalities dynamically, this poses a problem. There is, however, a
device in ACPI that seems to be used by Windows for identifying
different Surface models: The Windows Surface Integration Device (WSID).
This device seems to have a HID corresponding to the overall set of
functionalities SSAM provides for the associated model.
This commit introduces a registry providing non-detectable device
information via software nodes. In addition, a SSAM platform hub driver
is introduced, which takes care of creating and managing the SSAM
devices specified in this registry. This approach allows for a
hierarchical setup akin to ACPI and is easily extendable, e.g. via
firmware node properties.
Note that this commit only provides the basis for the platform hub and
registry, and does not add any content to it. The registry will be
expanded in subsequent commits.
Signed-off-by: Maximilian Luz <luzmaximilian@gmail.com>
Link: https://lore.kernel.org/r/20210212115439.1525216-2-luzmaximilian@gmail.com
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
2021-02-12 12:54:34 +01:00
|
|
|
NULL,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/* Devices for Surface Book 3. */
|
|
|
|
|
static const struct software_node *ssam_node_group_sb3[] = {
|
|
|
|
|
&ssam_node_root,
|
2021-02-12 12:54:35 +01:00
|
|
|
&ssam_node_hub_base,
|
2021-02-12 12:54:36 +01:00
|
|
|
&ssam_node_bat_ac,
|
|
|
|
|
&ssam_node_bat_main,
|
|
|
|
|
&ssam_node_bat_sb3base,
|
2021-02-12 12:54:37 +01:00
|
|
|
&ssam_node_tmp_pprof,
|
2021-02-12 12:54:38 +01:00
|
|
|
&ssam_node_bas_dtx,
|
2021-02-12 12:54:39 +01:00
|
|
|
&ssam_node_hid_base_keyboard,
|
|
|
|
|
&ssam_node_hid_base_touchpad,
|
|
|
|
|
&ssam_node_hid_base_iid5,
|
|
|
|
|
&ssam_node_hid_base_iid6,
|
platform/surface: Set up Surface Aggregator device registry
The Surface System Aggregator Module (SSAM) subsystem provides various
functionalities, which are separated by spreading them across multiple
devices and corresponding drivers. Parts of that functionality / some of
those devices, however, can (as far as we currently know) not be
auto-detected by conventional means. While older (specifically 5th- and
6th-)generation models do advertise most of their functionality via
standard platform devices in ACPI, newer generations do not.
As we are currently also not aware of any feasible way to query said
functionalities dynamically, this poses a problem. There is, however, a
device in ACPI that seems to be used by Windows for identifying
different Surface models: The Windows Surface Integration Device (WSID).
This device seems to have a HID corresponding to the overall set of
functionalities SSAM provides for the associated model.
This commit introduces a registry providing non-detectable device
information via software nodes. In addition, a SSAM platform hub driver
is introduced, which takes care of creating and managing the SSAM
devices specified in this registry. This approach allows for a
hierarchical setup akin to ACPI and is easily extendable, e.g. via
firmware node properties.
Note that this commit only provides the basis for the platform hub and
registry, and does not add any content to it. The registry will be
expanded in subsequent commits.
Signed-off-by: Maximilian Luz <luzmaximilian@gmail.com>
Link: https://lore.kernel.org/r/20210212115439.1525216-2-luzmaximilian@gmail.com
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
2021-02-12 12:54:34 +01:00
|
|
|
NULL,
|
|
|
|
|
};
|
|
|
|
|
|
2021-05-23 15:45:26 +02:00
|
|
|
/* Devices for Surface Laptop 3 and 4. */
|
platform/surface: Set up Surface Aggregator device registry
The Surface System Aggregator Module (SSAM) subsystem provides various
functionalities, which are separated by spreading them across multiple
devices and corresponding drivers. Parts of that functionality / some of
those devices, however, can (as far as we currently know) not be
auto-detected by conventional means. While older (specifically 5th- and
6th-)generation models do advertise most of their functionality via
standard platform devices in ACPI, newer generations do not.
As we are currently also not aware of any feasible way to query said
functionalities dynamically, this poses a problem. There is, however, a
device in ACPI that seems to be used by Windows for identifying
different Surface models: The Windows Surface Integration Device (WSID).
This device seems to have a HID corresponding to the overall set of
functionalities SSAM provides for the associated model.
This commit introduces a registry providing non-detectable device
information via software nodes. In addition, a SSAM platform hub driver
is introduced, which takes care of creating and managing the SSAM
devices specified in this registry. This approach allows for a
hierarchical setup akin to ACPI and is easily extendable, e.g. via
firmware node properties.
Note that this commit only provides the basis for the platform hub and
registry, and does not add any content to it. The registry will be
expanded in subsequent commits.
Signed-off-by: Maximilian Luz <luzmaximilian@gmail.com>
Link: https://lore.kernel.org/r/20210212115439.1525216-2-luzmaximilian@gmail.com
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
2021-02-12 12:54:34 +01:00
|
|
|
static const struct software_node *ssam_node_group_sl3[] = {
|
|
|
|
|
&ssam_node_root,
|
2021-02-12 12:54:36 +01:00
|
|
|
&ssam_node_bat_ac,
|
|
|
|
|
&ssam_node_bat_main,
|
2021-02-12 12:54:37 +01:00
|
|
|
&ssam_node_tmp_pprof,
|
2021-02-12 12:54:39 +01:00
|
|
|
&ssam_node_hid_main_keyboard,
|
|
|
|
|
&ssam_node_hid_main_touchpad,
|
|
|
|
|
&ssam_node_hid_main_iid5,
|
platform/surface: Set up Surface Aggregator device registry
The Surface System Aggregator Module (SSAM) subsystem provides various
functionalities, which are separated by spreading them across multiple
devices and corresponding drivers. Parts of that functionality / some of
those devices, however, can (as far as we currently know) not be
auto-detected by conventional means. While older (specifically 5th- and
6th-)generation models do advertise most of their functionality via
standard platform devices in ACPI, newer generations do not.
As we are currently also not aware of any feasible way to query said
functionalities dynamically, this poses a problem. There is, however, a
device in ACPI that seems to be used by Windows for identifying
different Surface models: The Windows Surface Integration Device (WSID).
This device seems to have a HID corresponding to the overall set of
functionalities SSAM provides for the associated model.
This commit introduces a registry providing non-detectable device
information via software nodes. In addition, a SSAM platform hub driver
is introduced, which takes care of creating and managing the SSAM
devices specified in this registry. This approach allows for a
hierarchical setup akin to ACPI and is easily extendable, e.g. via
firmware node properties.
Note that this commit only provides the basis for the platform hub and
registry, and does not add any content to it. The registry will be
expanded in subsequent commits.
Signed-off-by: Maximilian Luz <luzmaximilian@gmail.com>
Link: https://lore.kernel.org/r/20210212115439.1525216-2-luzmaximilian@gmail.com
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
2021-02-12 12:54:34 +01:00
|
|
|
NULL,
|
|
|
|
|
};
|
|
|
|
|
|
2021-10-21 15:09:02 +02:00
|
|
|
/* Devices for Surface Laptop Studio. */
|
|
|
|
|
static const struct software_node *ssam_node_group_sls[] = {
|
|
|
|
|
&ssam_node_root,
|
|
|
|
|
&ssam_node_bat_ac,
|
|
|
|
|
&ssam_node_bat_main,
|
|
|
|
|
&ssam_node_tmp_pprof,
|
|
|
|
|
&ssam_node_hid_tid1_keyboard,
|
|
|
|
|
&ssam_node_hid_tid1_penstash,
|
|
|
|
|
&ssam_node_hid_tid1_touchpad,
|
|
|
|
|
&ssam_node_hid_tid1_iid6,
|
|
|
|
|
&ssam_node_hid_tid1_iid7,
|
|
|
|
|
&ssam_node_hid_tid1_sysctrl,
|
|
|
|
|
NULL,
|
|
|
|
|
};
|
|
|
|
|
|
platform/surface: Set up Surface Aggregator device registry
The Surface System Aggregator Module (SSAM) subsystem provides various
functionalities, which are separated by spreading them across multiple
devices and corresponding drivers. Parts of that functionality / some of
those devices, however, can (as far as we currently know) not be
auto-detected by conventional means. While older (specifically 5th- and
6th-)generation models do advertise most of their functionality via
standard platform devices in ACPI, newer generations do not.
As we are currently also not aware of any feasible way to query said
functionalities dynamically, this poses a problem. There is, however, a
device in ACPI that seems to be used by Windows for identifying
different Surface models: The Windows Surface Integration Device (WSID).
This device seems to have a HID corresponding to the overall set of
functionalities SSAM provides for the associated model.
This commit introduces a registry providing non-detectable device
information via software nodes. In addition, a SSAM platform hub driver
is introduced, which takes care of creating and managing the SSAM
devices specified in this registry. This approach allows for a
hierarchical setup akin to ACPI and is easily extendable, e.g. via
firmware node properties.
Note that this commit only provides the basis for the platform hub and
registry, and does not add any content to it. The registry will be
expanded in subsequent commits.
Signed-off-by: Maximilian Luz <luzmaximilian@gmail.com>
Link: https://lore.kernel.org/r/20210212115439.1525216-2-luzmaximilian@gmail.com
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
2021-02-12 12:54:34 +01:00
|
|
|
/* Devices for Surface Laptop Go. */
|
|
|
|
|
static const struct software_node *ssam_node_group_slg1[] = {
|
|
|
|
|
&ssam_node_root,
|
2021-02-12 12:54:36 +01:00
|
|
|
&ssam_node_bat_ac,
|
|
|
|
|
&ssam_node_bat_main,
|
2021-02-12 12:54:37 +01:00
|
|
|
&ssam_node_tmp_pprof,
|
platform/surface: Set up Surface Aggregator device registry
The Surface System Aggregator Module (SSAM) subsystem provides various
functionalities, which are separated by spreading them across multiple
devices and corresponding drivers. Parts of that functionality / some of
those devices, however, can (as far as we currently know) not be
auto-detected by conventional means. While older (specifically 5th- and
6th-)generation models do advertise most of their functionality via
standard platform devices in ACPI, newer generations do not.
As we are currently also not aware of any feasible way to query said
functionalities dynamically, this poses a problem. There is, however, a
device in ACPI that seems to be used by Windows for identifying
different Surface models: The Windows Surface Integration Device (WSID).
This device seems to have a HID corresponding to the overall set of
functionalities SSAM provides for the associated model.
This commit introduces a registry providing non-detectable device
information via software nodes. In addition, a SSAM platform hub driver
is introduced, which takes care of creating and managing the SSAM
devices specified in this registry. This approach allows for a
hierarchical setup akin to ACPI and is easily extendable, e.g. via
firmware node properties.
Note that this commit only provides the basis for the platform hub and
registry, and does not add any content to it. The registry will be
expanded in subsequent commits.
Signed-off-by: Maximilian Luz <luzmaximilian@gmail.com>
Link: https://lore.kernel.org/r/20210212115439.1525216-2-luzmaximilian@gmail.com
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
2021-02-12 12:54:34 +01:00
|
|
|
NULL,
|
|
|
|
|
};
|
|
|
|
|
|
2021-03-09 17:25:50 +01:00
|
|
|
/* Devices for Surface Pro 7 and Surface Pro 7+. */
|
platform/surface: Set up Surface Aggregator device registry
The Surface System Aggregator Module (SSAM) subsystem provides various
functionalities, which are separated by spreading them across multiple
devices and corresponding drivers. Parts of that functionality / some of
those devices, however, can (as far as we currently know) not be
auto-detected by conventional means. While older (specifically 5th- and
6th-)generation models do advertise most of their functionality via
standard platform devices in ACPI, newer generations do not.
As we are currently also not aware of any feasible way to query said
functionalities dynamically, this poses a problem. There is, however, a
device in ACPI that seems to be used by Windows for identifying
different Surface models: The Windows Surface Integration Device (WSID).
This device seems to have a HID corresponding to the overall set of
functionalities SSAM provides for the associated model.
This commit introduces a registry providing non-detectable device
information via software nodes. In addition, a SSAM platform hub driver
is introduced, which takes care of creating and managing the SSAM
devices specified in this registry. This approach allows for a
hierarchical setup akin to ACPI and is easily extendable, e.g. via
firmware node properties.
Note that this commit only provides the basis for the platform hub and
registry, and does not add any content to it. The registry will be
expanded in subsequent commits.
Signed-off-by: Maximilian Luz <luzmaximilian@gmail.com>
Link: https://lore.kernel.org/r/20210212115439.1525216-2-luzmaximilian@gmail.com
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
2021-02-12 12:54:34 +01:00
|
|
|
static const struct software_node *ssam_node_group_sp7[] = {
|
|
|
|
|
&ssam_node_root,
|
2021-02-12 12:54:36 +01:00
|
|
|
&ssam_node_bat_ac,
|
|
|
|
|
&ssam_node_bat_main,
|
2021-02-12 12:54:37 +01:00
|
|
|
&ssam_node_tmp_pprof,
|
platform/surface: Set up Surface Aggregator device registry
The Surface System Aggregator Module (SSAM) subsystem provides various
functionalities, which are separated by spreading them across multiple
devices and corresponding drivers. Parts of that functionality / some of
those devices, however, can (as far as we currently know) not be
auto-detected by conventional means. While older (specifically 5th- and
6th-)generation models do advertise most of their functionality via
standard platform devices in ACPI, newer generations do not.
As we are currently also not aware of any feasible way to query said
functionalities dynamically, this poses a problem. There is, however, a
device in ACPI that seems to be used by Windows for identifying
different Surface models: The Windows Surface Integration Device (WSID).
This device seems to have a HID corresponding to the overall set of
functionalities SSAM provides for the associated model.
This commit introduces a registry providing non-detectable device
information via software nodes. In addition, a SSAM platform hub driver
is introduced, which takes care of creating and managing the SSAM
devices specified in this registry. This approach allows for a
hierarchical setup akin to ACPI and is easily extendable, e.g. via
firmware node properties.
Note that this commit only provides the basis for the platform hub and
registry, and does not add any content to it. The registry will be
expanded in subsequent commits.
Signed-off-by: Maximilian Luz <luzmaximilian@gmail.com>
Link: https://lore.kernel.org/r/20210212115439.1525216-2-luzmaximilian@gmail.com
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
2021-02-12 12:54:34 +01:00
|
|
|
NULL,
|
|
|
|
|
};
|
|
|
|
|
|
2021-10-28 03:28:45 +02:00
|
|
|
static const struct software_node *ssam_node_group_sp8[] = {
|
|
|
|
|
&ssam_node_root,
|
2022-05-27 04:34:47 +02:00
|
|
|
&ssam_node_hub_kip,
|
2021-10-28 03:28:45 +02:00
|
|
|
&ssam_node_bat_ac,
|
|
|
|
|
&ssam_node_bat_main,
|
|
|
|
|
&ssam_node_tmp_pprof,
|
2022-05-27 04:34:47 +02:00
|
|
|
&ssam_node_hid_kip_keyboard,
|
|
|
|
|
&ssam_node_hid_kip_penstash,
|
|
|
|
|
&ssam_node_hid_kip_touchpad,
|
|
|
|
|
&ssam_node_hid_kip_iid5,
|
|
|
|
|
/* TODO: Add support for tablet mode switch. */
|
2021-10-28 03:28:45 +02:00
|
|
|
NULL,
|
|
|
|
|
};
|
|
|
|
|
|
platform/surface: Set up Surface Aggregator device registry
The Surface System Aggregator Module (SSAM) subsystem provides various
functionalities, which are separated by spreading them across multiple
devices and corresponding drivers. Parts of that functionality / some of
those devices, however, can (as far as we currently know) not be
auto-detected by conventional means. While older (specifically 5th- and
6th-)generation models do advertise most of their functionality via
standard platform devices in ACPI, newer generations do not.
As we are currently also not aware of any feasible way to query said
functionalities dynamically, this poses a problem. There is, however, a
device in ACPI that seems to be used by Windows for identifying
different Surface models: The Windows Surface Integration Device (WSID).
This device seems to have a HID corresponding to the overall set of
functionalities SSAM provides for the associated model.
This commit introduces a registry providing non-detectable device
information via software nodes. In addition, a SSAM platform hub driver
is introduced, which takes care of creating and managing the SSAM
devices specified in this registry. This approach allows for a
hierarchical setup akin to ACPI and is easily extendable, e.g. via
firmware node properties.
Note that this commit only provides the basis for the platform hub and
registry, and does not add any content to it. The registry will be
expanded in subsequent commits.
Signed-off-by: Maximilian Luz <luzmaximilian@gmail.com>
Link: https://lore.kernel.org/r/20210212115439.1525216-2-luzmaximilian@gmail.com
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
2021-02-12 12:54:34 +01:00
|
|
|
|
|
|
|
|
/* -- Device registry helper functions. ------------------------------------- */
|
|
|
|
|
|
|
|
|
|
static int ssam_uid_from_string(const char *str, struct ssam_device_uid *uid)
|
|
|
|
|
{
|
|
|
|
|
u8 d, tc, tid, iid, fn;
|
|
|
|
|
int n;
|
|
|
|
|
|
|
|
|
|
n = sscanf(str, "ssam:%hhx:%hhx:%hhx:%hhx:%hhx", &d, &tc, &tid, &iid, &fn);
|
|
|
|
|
if (n != 5)
|
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
|
|
uid->domain = d;
|
|
|
|
|
uid->category = tc;
|
|
|
|
|
uid->target = tid;
|
|
|
|
|
uid->instance = iid;
|
|
|
|
|
uid->function = fn;
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int ssam_hub_add_device(struct device *parent, struct ssam_controller *ctrl,
|
|
|
|
|
struct fwnode_handle *node)
|
|
|
|
|
{
|
|
|
|
|
struct ssam_device_uid uid;
|
|
|
|
|
struct ssam_device *sdev;
|
|
|
|
|
int status;
|
|
|
|
|
|
|
|
|
|
status = ssam_uid_from_string(fwnode_get_name(node), &uid);
|
|
|
|
|
if (status)
|
|
|
|
|
return status;
|
|
|
|
|
|
|
|
|
|
sdev = ssam_device_alloc(ctrl, uid);
|
|
|
|
|
if (!sdev)
|
|
|
|
|
return -ENOMEM;
|
|
|
|
|
|
|
|
|
|
sdev->dev.parent = parent;
|
|
|
|
|
sdev->dev.fwnode = node;
|
|
|
|
|
|
|
|
|
|
status = ssam_device_add(sdev);
|
|
|
|
|
if (status)
|
|
|
|
|
ssam_device_put(sdev);
|
|
|
|
|
|
|
|
|
|
return status;
|
|
|
|
|
}
|
|
|
|
|
|
2021-10-28 02:22:43 +02:00
|
|
|
static int ssam_hub_register_clients(struct device *parent, struct ssam_controller *ctrl,
|
|
|
|
|
struct fwnode_handle *node)
|
platform/surface: Set up Surface Aggregator device registry
The Surface System Aggregator Module (SSAM) subsystem provides various
functionalities, which are separated by spreading them across multiple
devices and corresponding drivers. Parts of that functionality / some of
those devices, however, can (as far as we currently know) not be
auto-detected by conventional means. While older (specifically 5th- and
6th-)generation models do advertise most of their functionality via
standard platform devices in ACPI, newer generations do not.
As we are currently also not aware of any feasible way to query said
functionalities dynamically, this poses a problem. There is, however, a
device in ACPI that seems to be used by Windows for identifying
different Surface models: The Windows Surface Integration Device (WSID).
This device seems to have a HID corresponding to the overall set of
functionalities SSAM provides for the associated model.
This commit introduces a registry providing non-detectable device
information via software nodes. In addition, a SSAM platform hub driver
is introduced, which takes care of creating and managing the SSAM
devices specified in this registry. This approach allows for a
hierarchical setup akin to ACPI and is easily extendable, e.g. via
firmware node properties.
Note that this commit only provides the basis for the platform hub and
registry, and does not add any content to it. The registry will be
expanded in subsequent commits.
Signed-off-by: Maximilian Luz <luzmaximilian@gmail.com>
Link: https://lore.kernel.org/r/20210212115439.1525216-2-luzmaximilian@gmail.com
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
2021-02-12 12:54:34 +01:00
|
|
|
{
|
|
|
|
|
struct fwnode_handle *child;
|
|
|
|
|
int status;
|
|
|
|
|
|
|
|
|
|
fwnode_for_each_child_node(node, child) {
|
|
|
|
|
/*
|
|
|
|
|
* Try to add the device specified in the firmware node. If
|
|
|
|
|
* this fails with -EINVAL, the node does not specify any SSAM
|
|
|
|
|
* device, so ignore it and continue with the next one.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
status = ssam_hub_add_device(parent, ctrl, child);
|
|
|
|
|
if (status && status != -EINVAL)
|
|
|
|
|
goto err;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
err:
|
2021-10-28 02:22:42 +02:00
|
|
|
ssam_remove_clients(parent);
|
platform/surface: Set up Surface Aggregator device registry
The Surface System Aggregator Module (SSAM) subsystem provides various
functionalities, which are separated by spreading them across multiple
devices and corresponding drivers. Parts of that functionality / some of
those devices, however, can (as far as we currently know) not be
auto-detected by conventional means. While older (specifically 5th- and
6th-)generation models do advertise most of their functionality via
standard platform devices in ACPI, newer generations do not.
As we are currently also not aware of any feasible way to query said
functionalities dynamically, this poses a problem. There is, however, a
device in ACPI that seems to be used by Windows for identifying
different Surface models: The Windows Surface Integration Device (WSID).
This device seems to have a HID corresponding to the overall set of
functionalities SSAM provides for the associated model.
This commit introduces a registry providing non-detectable device
information via software nodes. In addition, a SSAM platform hub driver
is introduced, which takes care of creating and managing the SSAM
devices specified in this registry. This approach allows for a
hierarchical setup akin to ACPI and is easily extendable, e.g. via
firmware node properties.
Note that this commit only provides the basis for the platform hub and
registry, and does not add any content to it. The registry will be
expanded in subsequent commits.
Signed-off-by: Maximilian Luz <luzmaximilian@gmail.com>
Link: https://lore.kernel.org/r/20210212115439.1525216-2-luzmaximilian@gmail.com
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
2021-02-12 12:54:34 +01:00
|
|
|
return status;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2022-05-27 04:34:44 +02:00
|
|
|
/* -- SSAM generic subsystem hub driver framework. -------------------------- */
|
2021-02-12 12:54:35 +01:00
|
|
|
|
2022-05-27 04:34:44 +02:00
|
|
|
enum ssam_hub_state {
|
|
|
|
|
SSAM_HUB_UNINITIALIZED, /* Only set during initialization. */
|
|
|
|
|
SSAM_HUB_CONNECTED,
|
|
|
|
|
SSAM_HUB_DISCONNECTED,
|
|
|
|
|
};
|
2021-04-06 01:12:22 +02:00
|
|
|
|
2022-05-27 04:34:44 +02:00
|
|
|
enum ssam_hub_flags {
|
|
|
|
|
SSAM_HUB_HOT_REMOVED,
|
2021-02-12 12:54:35 +01:00
|
|
|
};
|
|
|
|
|
|
2022-05-27 04:34:44 +02:00
|
|
|
struct ssam_hub {
|
2021-02-12 12:54:35 +01:00
|
|
|
struct ssam_device *sdev;
|
|
|
|
|
|
2022-05-27 04:34:44 +02:00
|
|
|
enum ssam_hub_state state;
|
|
|
|
|
unsigned long flags;
|
|
|
|
|
|
2021-04-06 01:12:22 +02:00
|
|
|
struct delayed_work update_work;
|
2022-05-27 04:34:44 +02:00
|
|
|
unsigned long connect_delay;
|
2021-02-12 12:54:35 +01:00
|
|
|
|
|
|
|
|
struct ssam_event_notifier notif;
|
2022-05-27 04:34:44 +02:00
|
|
|
|
|
|
|
|
int (*get_state)(struct ssam_hub *hub, enum ssam_hub_state *state);
|
2021-02-12 12:54:35 +01:00
|
|
|
};
|
|
|
|
|
|
2022-05-27 04:34:44 +02:00
|
|
|
static void ssam_hub_update_workfn(struct work_struct *work)
|
|
|
|
|
{
|
|
|
|
|
struct ssam_hub *hub = container_of(work, struct ssam_hub, update_work.work);
|
|
|
|
|
struct fwnode_handle *node = dev_fwnode(&hub->sdev->dev);
|
|
|
|
|
enum ssam_hub_state state;
|
|
|
|
|
int status = 0;
|
|
|
|
|
|
|
|
|
|
status = hub->get_state(hub, &state);
|
|
|
|
|
if (status)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* There is a small possibility that hub devices were hot-removed and
|
|
|
|
|
* re-added before we were able to remove them here. In that case, both
|
|
|
|
|
* the state returned by get_state() and the state of the hub will
|
|
|
|
|
* equal SSAM_HUB_CONNECTED and we would bail early below, which would
|
|
|
|
|
* leave child devices without proper (re-)initialization and the
|
|
|
|
|
* hot-remove flag set.
|
|
|
|
|
*
|
|
|
|
|
* Therefore, we check whether devices have been hot-removed via an
|
|
|
|
|
* additional flag on the hub and, in this case, override the returned
|
|
|
|
|
* hub state. In case of a missed disconnect (i.e. get_state returned
|
|
|
|
|
* "connected"), we further need to re-schedule this work (with the
|
|
|
|
|
* appropriate delay) as the actual connect work submission might have
|
|
|
|
|
* been merged with this one.
|
|
|
|
|
*
|
|
|
|
|
* This then leads to one of two cases: Either we submit an unnecessary
|
|
|
|
|
* work item (which will get ignored via either the queue or the state
|
|
|
|
|
* checks) or, in the unlikely case that the work is actually required,
|
|
|
|
|
* double the normal connect delay.
|
|
|
|
|
*/
|
|
|
|
|
if (test_and_clear_bit(SSAM_HUB_HOT_REMOVED, &hub->flags)) {
|
|
|
|
|
if (state == SSAM_HUB_CONNECTED)
|
|
|
|
|
schedule_delayed_work(&hub->update_work, hub->connect_delay);
|
|
|
|
|
|
|
|
|
|
state = SSAM_HUB_DISCONNECTED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (hub->state == state)
|
|
|
|
|
return;
|
|
|
|
|
hub->state = state;
|
|
|
|
|
|
|
|
|
|
if (hub->state == SSAM_HUB_CONNECTED)
|
|
|
|
|
status = ssam_hub_register_clients(&hub->sdev->dev, hub->sdev->ctrl, node);
|
|
|
|
|
else
|
|
|
|
|
ssam_remove_clients(&hub->sdev->dev);
|
|
|
|
|
|
|
|
|
|
if (status)
|
|
|
|
|
dev_err(&hub->sdev->dev, "failed to update hub child devices: %d\n", status);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int ssam_hub_mark_hot_removed(struct device *dev, void *_data)
|
|
|
|
|
{
|
|
|
|
|
struct ssam_device *sdev = to_ssam_device(dev);
|
|
|
|
|
|
|
|
|
|
if (is_ssam_device(dev))
|
|
|
|
|
ssam_device_mark_hot_removed(sdev);
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void ssam_hub_update(struct ssam_hub *hub, bool connected)
|
|
|
|
|
{
|
|
|
|
|
unsigned long delay;
|
|
|
|
|
|
|
|
|
|
/* Mark devices as hot-removed before we remove any. */
|
|
|
|
|
if (!connected) {
|
|
|
|
|
set_bit(SSAM_HUB_HOT_REMOVED, &hub->flags);
|
|
|
|
|
device_for_each_child_reverse(&hub->sdev->dev, NULL, ssam_hub_mark_hot_removed);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Delay update when the base/keyboard cover is being connected to give
|
|
|
|
|
* devices/EC some time to set up.
|
|
|
|
|
*/
|
|
|
|
|
delay = connected ? hub->connect_delay : 0;
|
|
|
|
|
|
|
|
|
|
schedule_delayed_work(&hub->update_work, delay);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int __maybe_unused ssam_hub_resume(struct device *dev)
|
|
|
|
|
{
|
|
|
|
|
struct ssam_hub *hub = dev_get_drvdata(dev);
|
|
|
|
|
|
|
|
|
|
schedule_delayed_work(&hub->update_work, 0);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
static SIMPLE_DEV_PM_OPS(ssam_hub_pm_ops, NULL, ssam_hub_resume);
|
|
|
|
|
|
|
|
|
|
static int ssam_hub_setup(struct ssam_device *sdev, struct ssam_hub *hub)
|
|
|
|
|
{
|
|
|
|
|
int status;
|
|
|
|
|
|
|
|
|
|
hub->sdev = sdev;
|
|
|
|
|
hub->state = SSAM_HUB_UNINITIALIZED;
|
|
|
|
|
|
|
|
|
|
INIT_DELAYED_WORK(&hub->update_work, ssam_hub_update_workfn);
|
|
|
|
|
|
|
|
|
|
ssam_device_set_drvdata(sdev, hub);
|
|
|
|
|
|
|
|
|
|
status = ssam_device_notifier_register(sdev, &hub->notif);
|
|
|
|
|
if (status)
|
|
|
|
|
return status;
|
|
|
|
|
|
|
|
|
|
schedule_delayed_work(&hub->update_work, 0);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void ssam_hub_remove(struct ssam_device *sdev)
|
|
|
|
|
{
|
|
|
|
|
struct ssam_hub *hub = ssam_device_get_drvdata(sdev);
|
|
|
|
|
|
|
|
|
|
ssam_device_notifier_unregister(sdev, &hub->notif);
|
|
|
|
|
cancel_delayed_work_sync(&hub->update_work);
|
|
|
|
|
ssam_remove_clients(&sdev->dev);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* -- SSAM base-hub driver. ------------------------------------------------- */
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Some devices (especially battery) may need a bit of time to be fully usable
|
|
|
|
|
* after being (re-)connected. This delay has been determined via
|
|
|
|
|
* experimentation.
|
|
|
|
|
*/
|
|
|
|
|
#define SSAM_BASE_UPDATE_CONNECT_DELAY msecs_to_jiffies(2500)
|
|
|
|
|
|
platform/surface: aggregator: Make SSAM_DEFINE_SYNC_REQUEST_x define static functions
The SSAM_DEFINE_SYNC_REQUEST_x() macros are intended to reduce
boiler-plate code for SSAM request definitions by defining a wrapper
function for the specified request. The client device variants of those
macros, i.e. SSAM_DEFINE_SYNC_REQUEST_CL_x() in particular rely on the
multi-device (MD) variants, e.g.:
#define SSAM_DEFINE_SYNC_REQUEST_CL_R(name, rtype, spec...) \
SSAM_DEFINE_SYNC_REQUEST_MD_R(__raw_##name, rtype, spec) \
int name(struct ssam_device *sdev, rtype *ret) \
{ \
return __raw_##name(sdev->ctrl, sdev->uid.target, \
sdev->uid.instance, ret); \
}
This now creates the problem that it is not possible to declare the
generated functions static via
static SSAM_DEFINE_SYNC_REQUEST_CL_R(...)
as this will only apply to the function defined by the multi-device
macro, i.e. SSAM_DEFINE_SYNC_REQUEST_MD_R(). Thus compiling with
`-Wmissing-prototypes' rightfully complains that there is a 'static'
keyword missing.
To solve this, make all SSAM_DEFINE_SYNC_REQUEST_x() macros define
static functions. Non-client-device macros are also changed for
consistency. In general, we expect those functions to be only used
locally in the respective drivers for the corresponding interfaces, so
having to define a wrapper function to be able to export this should be
the odd case out.
Reported-by: kernel test robot <lkp@intel.com>
Fixes: b78b4982d763 ("platform/surface: Add platform profile driver")
Signed-off-by: Maximilian Luz <luzmaximilian@gmail.com>
Link: https://lore.kernel.org/r/20210304190524.1172197-1-luzmaximilian@gmail.com
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
2021-03-04 20:05:24 +01:00
|
|
|
SSAM_DEFINE_SYNC_REQUEST_R(ssam_bas_query_opmode, u8, {
|
2021-02-12 12:54:35 +01:00
|
|
|
.target_category = SSAM_SSH_TC_BAS,
|
|
|
|
|
.target_id = 0x01,
|
|
|
|
|
.command_id = 0x0d,
|
|
|
|
|
.instance_id = 0x00,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
#define SSAM_BAS_OPMODE_TABLET 0x00
|
|
|
|
|
#define SSAM_EVENT_BAS_CID_CONNECTION 0x0c
|
|
|
|
|
|
2022-05-27 04:34:44 +02:00
|
|
|
static int ssam_base_hub_query_state(struct ssam_hub *hub, enum ssam_hub_state *state)
|
2021-02-12 12:54:35 +01:00
|
|
|
{
|
|
|
|
|
u8 opmode;
|
|
|
|
|
int status;
|
|
|
|
|
|
|
|
|
|
status = ssam_retry(ssam_bas_query_opmode, hub->sdev->ctrl, &opmode);
|
|
|
|
|
if (status < 0) {
|
|
|
|
|
dev_err(&hub->sdev->dev, "failed to query base state: %d\n", status);
|
|
|
|
|
return status;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (opmode != SSAM_BAS_OPMODE_TABLET)
|
2022-05-27 04:34:44 +02:00
|
|
|
*state = SSAM_HUB_CONNECTED;
|
2021-02-12 12:54:35 +01:00
|
|
|
else
|
2022-05-27 04:34:44 +02:00
|
|
|
*state = SSAM_HUB_DISCONNECTED;
|
2021-02-12 12:54:35 +01:00
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static u32 ssam_base_hub_notif(struct ssam_event_notifier *nf, const struct ssam_event *event)
|
|
|
|
|
{
|
2022-05-27 04:34:44 +02:00
|
|
|
struct ssam_hub *hub = container_of(nf, struct ssam_hub, notif);
|
2021-02-12 12:54:35 +01:00
|
|
|
|
|
|
|
|
if (event->command_id != SSAM_EVENT_BAS_CID_CONNECTION)
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
if (event->length < 1) {
|
2021-04-06 01:12:22 +02:00
|
|
|
dev_err(&hub->sdev->dev, "unexpected payload size: %u\n", event->length);
|
2021-02-12 12:54:35 +01:00
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-27 04:34:44 +02:00
|
|
|
ssam_hub_update(hub, event->data[0]);
|
2021-02-12 12:54:35 +01:00
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Do not return SSAM_NOTIF_HANDLED: The event should be picked up and
|
|
|
|
|
* consumed by the detachment system driver. We're just a (more or less)
|
|
|
|
|
* silent observer.
|
|
|
|
|
*/
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int ssam_base_hub_probe(struct ssam_device *sdev)
|
|
|
|
|
{
|
2022-05-27 04:34:44 +02:00
|
|
|
struct ssam_hub *hub;
|
2021-02-12 12:54:35 +01:00
|
|
|
|
|
|
|
|
hub = devm_kzalloc(&sdev->dev, sizeof(*hub), GFP_KERNEL);
|
|
|
|
|
if (!hub)
|
|
|
|
|
return -ENOMEM;
|
|
|
|
|
|
|
|
|
|
hub->notif.base.priority = INT_MAX; /* This notifier should run first. */
|
|
|
|
|
hub->notif.base.fn = ssam_base_hub_notif;
|
|
|
|
|
hub->notif.event.reg = SSAM_EVENT_REGISTRY_SAM;
|
|
|
|
|
hub->notif.event.id.target_category = SSAM_SSH_TC_BAS,
|
|
|
|
|
hub->notif.event.id.instance = 0,
|
|
|
|
|
hub->notif.event.mask = SSAM_EVENT_MASK_NONE;
|
|
|
|
|
hub->notif.event.flags = SSAM_EVENT_SEQUENCED;
|
|
|
|
|
|
2022-05-27 04:34:44 +02:00
|
|
|
hub->connect_delay = SSAM_BASE_UPDATE_CONNECT_DELAY;
|
|
|
|
|
hub->get_state = ssam_base_hub_query_state;
|
2021-02-12 12:54:35 +01:00
|
|
|
|
2022-05-27 04:34:44 +02:00
|
|
|
return ssam_hub_setup(sdev, hub);
|
2021-02-12 12:54:35 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static const struct ssam_device_id ssam_base_hub_match[] = {
|
2022-05-27 04:34:45 +02:00
|
|
|
{ SSAM_VDEV(HUB, 0x02, SSAM_SSH_TC_BAS, 0x00) },
|
2021-02-12 12:54:35 +01:00
|
|
|
{ },
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static struct ssam_device_driver ssam_base_hub_driver = {
|
|
|
|
|
.probe = ssam_base_hub_probe,
|
2022-05-27 04:34:44 +02:00
|
|
|
.remove = ssam_hub_remove,
|
2021-02-12 12:54:35 +01:00
|
|
|
.match_table = ssam_base_hub_match,
|
|
|
|
|
.driver = {
|
|
|
|
|
.name = "surface_aggregator_base_hub",
|
|
|
|
|
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
|
2022-05-27 04:34:44 +02:00
|
|
|
.pm = &ssam_hub_pm_ops,
|
2021-02-12 12:54:35 +01:00
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
2022-05-27 04:34:46 +02:00
|
|
|
/* -- SSAM KIP-subsystem hub driver. ---------------------------------------- */
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Some devices may need a bit of time to be fully usable after being
|
|
|
|
|
* (re-)connected. This delay has been determined via experimentation.
|
|
|
|
|
*/
|
|
|
|
|
#define SSAM_KIP_UPDATE_CONNECT_DELAY msecs_to_jiffies(250)
|
|
|
|
|
|
|
|
|
|
#define SSAM_EVENT_KIP_CID_CONNECTION 0x2c
|
|
|
|
|
|
|
|
|
|
SSAM_DEFINE_SYNC_REQUEST_R(__ssam_kip_get_connection_state, u8, {
|
|
|
|
|
.target_category = SSAM_SSH_TC_KIP,
|
|
|
|
|
.target_id = 0x01,
|
|
|
|
|
.command_id = 0x2c,
|
|
|
|
|
.instance_id = 0x00,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
static int ssam_kip_get_connection_state(struct ssam_hub *hub, enum ssam_hub_state *state)
|
|
|
|
|
{
|
|
|
|
|
int status;
|
|
|
|
|
u8 connected;
|
|
|
|
|
|
|
|
|
|
status = ssam_retry(__ssam_kip_get_connection_state, hub->sdev->ctrl, &connected);
|
|
|
|
|
if (status < 0) {
|
|
|
|
|
dev_err(&hub->sdev->dev, "failed to query KIP connection state: %d\n", status);
|
|
|
|
|
return status;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
*state = connected ? SSAM_HUB_CONNECTED : SSAM_HUB_DISCONNECTED;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static u32 ssam_kip_hub_notif(struct ssam_event_notifier *nf, const struct ssam_event *event)
|
|
|
|
|
{
|
|
|
|
|
struct ssam_hub *hub = container_of(nf, struct ssam_hub, notif);
|
|
|
|
|
|
|
|
|
|
if (event->command_id != SSAM_EVENT_KIP_CID_CONNECTION)
|
|
|
|
|
return 0; /* Return "unhandled". */
|
|
|
|
|
|
|
|
|
|
if (event->length < 1) {
|
|
|
|
|
dev_err(&hub->sdev->dev, "unexpected payload size: %u\n", event->length);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ssam_hub_update(hub, event->data[0]);
|
|
|
|
|
return SSAM_NOTIF_HANDLED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int ssam_kip_hub_probe(struct ssam_device *sdev)
|
|
|
|
|
{
|
|
|
|
|
struct ssam_hub *hub;
|
|
|
|
|
|
|
|
|
|
hub = devm_kzalloc(&sdev->dev, sizeof(*hub), GFP_KERNEL);
|
|
|
|
|
if (!hub)
|
|
|
|
|
return -ENOMEM;
|
|
|
|
|
|
|
|
|
|
hub->notif.base.priority = INT_MAX; /* This notifier should run first. */
|
|
|
|
|
hub->notif.base.fn = ssam_kip_hub_notif;
|
|
|
|
|
hub->notif.event.reg = SSAM_EVENT_REGISTRY_SAM;
|
|
|
|
|
hub->notif.event.id.target_category = SSAM_SSH_TC_KIP,
|
|
|
|
|
hub->notif.event.id.instance = 0,
|
|
|
|
|
hub->notif.event.mask = SSAM_EVENT_MASK_TARGET;
|
|
|
|
|
hub->notif.event.flags = SSAM_EVENT_SEQUENCED;
|
|
|
|
|
|
|
|
|
|
hub->connect_delay = SSAM_KIP_UPDATE_CONNECT_DELAY;
|
|
|
|
|
hub->get_state = ssam_kip_get_connection_state;
|
|
|
|
|
|
|
|
|
|
return ssam_hub_setup(sdev, hub);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static const struct ssam_device_id ssam_kip_hub_match[] = {
|
|
|
|
|
{ SSAM_VDEV(HUB, 0x01, SSAM_SSH_TC_KIP, 0x00) },
|
|
|
|
|
{ },
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static struct ssam_device_driver ssam_kip_hub_driver = {
|
|
|
|
|
.probe = ssam_kip_hub_probe,
|
|
|
|
|
.remove = ssam_hub_remove,
|
|
|
|
|
.match_table = ssam_kip_hub_match,
|
|
|
|
|
.driver = {
|
|
|
|
|
.name = "surface_kip_hub",
|
|
|
|
|
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
|
|
|
|
|
.pm = &ssam_hub_pm_ops,
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
platform/surface: Set up Surface Aggregator device registry
The Surface System Aggregator Module (SSAM) subsystem provides various
functionalities, which are separated by spreading them across multiple
devices and corresponding drivers. Parts of that functionality / some of
those devices, however, can (as far as we currently know) not be
auto-detected by conventional means. While older (specifically 5th- and
6th-)generation models do advertise most of their functionality via
standard platform devices in ACPI, newer generations do not.
As we are currently also not aware of any feasible way to query said
functionalities dynamically, this poses a problem. There is, however, a
device in ACPI that seems to be used by Windows for identifying
different Surface models: The Windows Surface Integration Device (WSID).
This device seems to have a HID corresponding to the overall set of
functionalities SSAM provides for the associated model.
This commit introduces a registry providing non-detectable device
information via software nodes. In addition, a SSAM platform hub driver
is introduced, which takes care of creating and managing the SSAM
devices specified in this registry. This approach allows for a
hierarchical setup akin to ACPI and is easily extendable, e.g. via
firmware node properties.
Note that this commit only provides the basis for the platform hub and
registry, and does not add any content to it. The registry will be
expanded in subsequent commits.
Signed-off-by: Maximilian Luz <luzmaximilian@gmail.com>
Link: https://lore.kernel.org/r/20210212115439.1525216-2-luzmaximilian@gmail.com
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
2021-02-12 12:54:34 +01:00
|
|
|
/* -- SSAM platform/meta-hub driver. ---------------------------------------- */
|
|
|
|
|
|
|
|
|
|
static const struct acpi_device_id ssam_platform_hub_match[] = {
|
|
|
|
|
/* Surface Pro 4, 5, and 6 (OMBR < 0x10) */
|
2021-05-23 15:45:28 +02:00
|
|
|
{ "MSHW0081", (unsigned long)ssam_node_group_gen5 },
|
platform/surface: Set up Surface Aggregator device registry
The Surface System Aggregator Module (SSAM) subsystem provides various
functionalities, which are separated by spreading them across multiple
devices and corresponding drivers. Parts of that functionality / some of
those devices, however, can (as far as we currently know) not be
auto-detected by conventional means. While older (specifically 5th- and
6th-)generation models do advertise most of their functionality via
standard platform devices in ACPI, newer generations do not.
As we are currently also not aware of any feasible way to query said
functionalities dynamically, this poses a problem. There is, however, a
device in ACPI that seems to be used by Windows for identifying
different Surface models: The Windows Surface Integration Device (WSID).
This device seems to have a HID corresponding to the overall set of
functionalities SSAM provides for the associated model.
This commit introduces a registry providing non-detectable device
information via software nodes. In addition, a SSAM platform hub driver
is introduced, which takes care of creating and managing the SSAM
devices specified in this registry. This approach allows for a
hierarchical setup akin to ACPI and is easily extendable, e.g. via
firmware node properties.
Note that this commit only provides the basis for the platform hub and
registry, and does not add any content to it. The registry will be
expanded in subsequent commits.
Signed-off-by: Maximilian Luz <luzmaximilian@gmail.com>
Link: https://lore.kernel.org/r/20210212115439.1525216-2-luzmaximilian@gmail.com
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
2021-02-12 12:54:34 +01:00
|
|
|
|
|
|
|
|
/* Surface Pro 6 (OMBR >= 0x10) */
|
2021-05-23 15:45:28 +02:00
|
|
|
{ "MSHW0111", (unsigned long)ssam_node_group_gen5 },
|
platform/surface: Set up Surface Aggregator device registry
The Surface System Aggregator Module (SSAM) subsystem provides various
functionalities, which are separated by spreading them across multiple
devices and corresponding drivers. Parts of that functionality / some of
those devices, however, can (as far as we currently know) not be
auto-detected by conventional means. While older (specifically 5th- and
6th-)generation models do advertise most of their functionality via
standard platform devices in ACPI, newer generations do not.
As we are currently also not aware of any feasible way to query said
functionalities dynamically, this poses a problem. There is, however, a
device in ACPI that seems to be used by Windows for identifying
different Surface models: The Windows Surface Integration Device (WSID).
This device seems to have a HID corresponding to the overall set of
functionalities SSAM provides for the associated model.
This commit introduces a registry providing non-detectable device
information via software nodes. In addition, a SSAM platform hub driver
is introduced, which takes care of creating and managing the SSAM
devices specified in this registry. This approach allows for a
hierarchical setup akin to ACPI and is easily extendable, e.g. via
firmware node properties.
Note that this commit only provides the basis for the platform hub and
registry, and does not add any content to it. The registry will be
expanded in subsequent commits.
Signed-off-by: Maximilian Luz <luzmaximilian@gmail.com>
Link: https://lore.kernel.org/r/20210212115439.1525216-2-luzmaximilian@gmail.com
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
2021-02-12 12:54:34 +01:00
|
|
|
|
|
|
|
|
/* Surface Pro 7 */
|
|
|
|
|
{ "MSHW0116", (unsigned long)ssam_node_group_sp7 },
|
|
|
|
|
|
2021-03-09 17:25:50 +01:00
|
|
|
/* Surface Pro 7+ */
|
|
|
|
|
{ "MSHW0119", (unsigned long)ssam_node_group_sp7 },
|
|
|
|
|
|
2021-10-28 03:28:45 +02:00
|
|
|
/* Surface Pro 8 */
|
|
|
|
|
{ "MSHW0263", (unsigned long)ssam_node_group_sp8 },
|
|
|
|
|
|
platform/surface: Set up Surface Aggregator device registry
The Surface System Aggregator Module (SSAM) subsystem provides various
functionalities, which are separated by spreading them across multiple
devices and corresponding drivers. Parts of that functionality / some of
those devices, however, can (as far as we currently know) not be
auto-detected by conventional means. While older (specifically 5th- and
6th-)generation models do advertise most of their functionality via
standard platform devices in ACPI, newer generations do not.
As we are currently also not aware of any feasible way to query said
functionalities dynamically, this poses a problem. There is, however, a
device in ACPI that seems to be used by Windows for identifying
different Surface models: The Windows Surface Integration Device (WSID).
This device seems to have a HID corresponding to the overall set of
functionalities SSAM provides for the associated model.
This commit introduces a registry providing non-detectable device
information via software nodes. In addition, a SSAM platform hub driver
is introduced, which takes care of creating and managing the SSAM
devices specified in this registry. This approach allows for a
hierarchical setup akin to ACPI and is easily extendable, e.g. via
firmware node properties.
Note that this commit only provides the basis for the platform hub and
registry, and does not add any content to it. The registry will be
expanded in subsequent commits.
Signed-off-by: Maximilian Luz <luzmaximilian@gmail.com>
Link: https://lore.kernel.org/r/20210212115439.1525216-2-luzmaximilian@gmail.com
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
2021-02-12 12:54:34 +01:00
|
|
|
/* Surface Book 2 */
|
2021-05-23 15:45:28 +02:00
|
|
|
{ "MSHW0107", (unsigned long)ssam_node_group_gen5 },
|
platform/surface: Set up Surface Aggregator device registry
The Surface System Aggregator Module (SSAM) subsystem provides various
functionalities, which are separated by spreading them across multiple
devices and corresponding drivers. Parts of that functionality / some of
those devices, however, can (as far as we currently know) not be
auto-detected by conventional means. While older (specifically 5th- and
6th-)generation models do advertise most of their functionality via
standard platform devices in ACPI, newer generations do not.
As we are currently also not aware of any feasible way to query said
functionalities dynamically, this poses a problem. There is, however, a
device in ACPI that seems to be used by Windows for identifying
different Surface models: The Windows Surface Integration Device (WSID).
This device seems to have a HID corresponding to the overall set of
functionalities SSAM provides for the associated model.
This commit introduces a registry providing non-detectable device
information via software nodes. In addition, a SSAM platform hub driver
is introduced, which takes care of creating and managing the SSAM
devices specified in this registry. This approach allows for a
hierarchical setup akin to ACPI and is easily extendable, e.g. via
firmware node properties.
Note that this commit only provides the basis for the platform hub and
registry, and does not add any content to it. The registry will be
expanded in subsequent commits.
Signed-off-by: Maximilian Luz <luzmaximilian@gmail.com>
Link: https://lore.kernel.org/r/20210212115439.1525216-2-luzmaximilian@gmail.com
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
2021-02-12 12:54:34 +01:00
|
|
|
|
|
|
|
|
/* Surface Book 3 */
|
|
|
|
|
{ "MSHW0117", (unsigned long)ssam_node_group_sb3 },
|
|
|
|
|
|
|
|
|
|
/* Surface Laptop 1 */
|
2021-05-23 15:45:28 +02:00
|
|
|
{ "MSHW0086", (unsigned long)ssam_node_group_gen5 },
|
platform/surface: Set up Surface Aggregator device registry
The Surface System Aggregator Module (SSAM) subsystem provides various
functionalities, which are separated by spreading them across multiple
devices and corresponding drivers. Parts of that functionality / some of
those devices, however, can (as far as we currently know) not be
auto-detected by conventional means. While older (specifically 5th- and
6th-)generation models do advertise most of their functionality via
standard platform devices in ACPI, newer generations do not.
As we are currently also not aware of any feasible way to query said
functionalities dynamically, this poses a problem. There is, however, a
device in ACPI that seems to be used by Windows for identifying
different Surface models: The Windows Surface Integration Device (WSID).
This device seems to have a HID corresponding to the overall set of
functionalities SSAM provides for the associated model.
This commit introduces a registry providing non-detectable device
information via software nodes. In addition, a SSAM platform hub driver
is introduced, which takes care of creating and managing the SSAM
devices specified in this registry. This approach allows for a
hierarchical setup akin to ACPI and is easily extendable, e.g. via
firmware node properties.
Note that this commit only provides the basis for the platform hub and
registry, and does not add any content to it. The registry will be
expanded in subsequent commits.
Signed-off-by: Maximilian Luz <luzmaximilian@gmail.com>
Link: https://lore.kernel.org/r/20210212115439.1525216-2-luzmaximilian@gmail.com
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
2021-02-12 12:54:34 +01:00
|
|
|
|
|
|
|
|
/* Surface Laptop 2 */
|
2021-05-23 15:45:28 +02:00
|
|
|
{ "MSHW0112", (unsigned long)ssam_node_group_gen5 },
|
platform/surface: Set up Surface Aggregator device registry
The Surface System Aggregator Module (SSAM) subsystem provides various
functionalities, which are separated by spreading them across multiple
devices and corresponding drivers. Parts of that functionality / some of
those devices, however, can (as far as we currently know) not be
auto-detected by conventional means. While older (specifically 5th- and
6th-)generation models do advertise most of their functionality via
standard platform devices in ACPI, newer generations do not.
As we are currently also not aware of any feasible way to query said
functionalities dynamically, this poses a problem. There is, however, a
device in ACPI that seems to be used by Windows for identifying
different Surface models: The Windows Surface Integration Device (WSID).
This device seems to have a HID corresponding to the overall set of
functionalities SSAM provides for the associated model.
This commit introduces a registry providing non-detectable device
information via software nodes. In addition, a SSAM platform hub driver
is introduced, which takes care of creating and managing the SSAM
devices specified in this registry. This approach allows for a
hierarchical setup akin to ACPI and is easily extendable, e.g. via
firmware node properties.
Note that this commit only provides the basis for the platform hub and
registry, and does not add any content to it. The registry will be
expanded in subsequent commits.
Signed-off-by: Maximilian Luz <luzmaximilian@gmail.com>
Link: https://lore.kernel.org/r/20210212115439.1525216-2-luzmaximilian@gmail.com
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
2021-02-12 12:54:34 +01:00
|
|
|
|
|
|
|
|
/* Surface Laptop 3 (13", Intel) */
|
|
|
|
|
{ "MSHW0114", (unsigned long)ssam_node_group_sl3 },
|
|
|
|
|
|
2021-05-23 15:45:26 +02:00
|
|
|
/* Surface Laptop 3 (15", AMD) and 4 (15", AMD) */
|
platform/surface: Set up Surface Aggregator device registry
The Surface System Aggregator Module (SSAM) subsystem provides various
functionalities, which are separated by spreading them across multiple
devices and corresponding drivers. Parts of that functionality / some of
those devices, however, can (as far as we currently know) not be
auto-detected by conventional means. While older (specifically 5th- and
6th-)generation models do advertise most of their functionality via
standard platform devices in ACPI, newer generations do not.
As we are currently also not aware of any feasible way to query said
functionalities dynamically, this poses a problem. There is, however, a
device in ACPI that seems to be used by Windows for identifying
different Surface models: The Windows Surface Integration Device (WSID).
This device seems to have a HID corresponding to the overall set of
functionalities SSAM provides for the associated model.
This commit introduces a registry providing non-detectable device
information via software nodes. In addition, a SSAM platform hub driver
is introduced, which takes care of creating and managing the SSAM
devices specified in this registry. This approach allows for a
hierarchical setup akin to ACPI and is easily extendable, e.g. via
firmware node properties.
Note that this commit only provides the basis for the platform hub and
registry, and does not add any content to it. The registry will be
expanded in subsequent commits.
Signed-off-by: Maximilian Luz <luzmaximilian@gmail.com>
Link: https://lore.kernel.org/r/20210212115439.1525216-2-luzmaximilian@gmail.com
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
2021-02-12 12:54:34 +01:00
|
|
|
{ "MSHW0110", (unsigned long)ssam_node_group_sl3 },
|
|
|
|
|
|
2021-05-23 15:45:27 +02:00
|
|
|
/* Surface Laptop 4 (13", Intel) */
|
|
|
|
|
{ "MSHW0250", (unsigned long)ssam_node_group_sl3 },
|
|
|
|
|
|
platform/surface: Set up Surface Aggregator device registry
The Surface System Aggregator Module (SSAM) subsystem provides various
functionalities, which are separated by spreading them across multiple
devices and corresponding drivers. Parts of that functionality / some of
those devices, however, can (as far as we currently know) not be
auto-detected by conventional means. While older (specifically 5th- and
6th-)generation models do advertise most of their functionality via
standard platform devices in ACPI, newer generations do not.
As we are currently also not aware of any feasible way to query said
functionalities dynamically, this poses a problem. There is, however, a
device in ACPI that seems to be used by Windows for identifying
different Surface models: The Windows Surface Integration Device (WSID).
This device seems to have a HID corresponding to the overall set of
functionalities SSAM provides for the associated model.
This commit introduces a registry providing non-detectable device
information via software nodes. In addition, a SSAM platform hub driver
is introduced, which takes care of creating and managing the SSAM
devices specified in this registry. This approach allows for a
hierarchical setup akin to ACPI and is easily extendable, e.g. via
firmware node properties.
Note that this commit only provides the basis for the platform hub and
registry, and does not add any content to it. The registry will be
expanded in subsequent commits.
Signed-off-by: Maximilian Luz <luzmaximilian@gmail.com>
Link: https://lore.kernel.org/r/20210212115439.1525216-2-luzmaximilian@gmail.com
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
2021-02-12 12:54:34 +01:00
|
|
|
/* Surface Laptop Go 1 */
|
|
|
|
|
{ "MSHW0118", (unsigned long)ssam_node_group_slg1 },
|
|
|
|
|
|
2021-10-21 15:09:02 +02:00
|
|
|
/* Surface Laptop Studio */
|
|
|
|
|
{ "MSHW0123", (unsigned long)ssam_node_group_sls },
|
|
|
|
|
|
platform/surface: Set up Surface Aggregator device registry
The Surface System Aggregator Module (SSAM) subsystem provides various
functionalities, which are separated by spreading them across multiple
devices and corresponding drivers. Parts of that functionality / some of
those devices, however, can (as far as we currently know) not be
auto-detected by conventional means. While older (specifically 5th- and
6th-)generation models do advertise most of their functionality via
standard platform devices in ACPI, newer generations do not.
As we are currently also not aware of any feasible way to query said
functionalities dynamically, this poses a problem. There is, however, a
device in ACPI that seems to be used by Windows for identifying
different Surface models: The Windows Surface Integration Device (WSID).
This device seems to have a HID corresponding to the overall set of
functionalities SSAM provides for the associated model.
This commit introduces a registry providing non-detectable device
information via software nodes. In addition, a SSAM platform hub driver
is introduced, which takes care of creating and managing the SSAM
devices specified in this registry. This approach allows for a
hierarchical setup akin to ACPI and is easily extendable, e.g. via
firmware node properties.
Note that this commit only provides the basis for the platform hub and
registry, and does not add any content to it. The registry will be
expanded in subsequent commits.
Signed-off-by: Maximilian Luz <luzmaximilian@gmail.com>
Link: https://lore.kernel.org/r/20210212115439.1525216-2-luzmaximilian@gmail.com
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
2021-02-12 12:54:34 +01:00
|
|
|
{ },
|
|
|
|
|
};
|
|
|
|
|
MODULE_DEVICE_TABLE(acpi, ssam_platform_hub_match);
|
|
|
|
|
|
|
|
|
|
static int ssam_platform_hub_probe(struct platform_device *pdev)
|
|
|
|
|
{
|
|
|
|
|
const struct software_node **nodes;
|
|
|
|
|
struct ssam_controller *ctrl;
|
|
|
|
|
struct fwnode_handle *root;
|
|
|
|
|
int status;
|
|
|
|
|
|
|
|
|
|
nodes = (const struct software_node **)acpi_device_get_match_data(&pdev->dev);
|
|
|
|
|
if (!nodes)
|
|
|
|
|
return -ENODEV;
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* As we're adding the SSAM client devices as children under this device
|
|
|
|
|
* and not the SSAM controller, we need to add a device link to the
|
|
|
|
|
* controller to ensure that we remove all of our devices before the
|
|
|
|
|
* controller is removed. This also guarantees proper ordering for
|
|
|
|
|
* suspend/resume of the devices on this hub.
|
|
|
|
|
*/
|
|
|
|
|
ctrl = ssam_client_bind(&pdev->dev);
|
|
|
|
|
if (IS_ERR(ctrl))
|
|
|
|
|
return PTR_ERR(ctrl) == -ENODEV ? -EPROBE_DEFER : PTR_ERR(ctrl);
|
|
|
|
|
|
|
|
|
|
status = software_node_register_node_group(nodes);
|
|
|
|
|
if (status)
|
|
|
|
|
return status;
|
|
|
|
|
|
|
|
|
|
root = software_node_fwnode(&ssam_node_root);
|
|
|
|
|
if (!root) {
|
|
|
|
|
software_node_unregister_node_group(nodes);
|
|
|
|
|
return -ENOENT;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
set_secondary_fwnode(&pdev->dev, root);
|
|
|
|
|
|
2021-10-28 02:22:43 +02:00
|
|
|
status = ssam_hub_register_clients(&pdev->dev, ctrl, root);
|
platform/surface: Set up Surface Aggregator device registry
The Surface System Aggregator Module (SSAM) subsystem provides various
functionalities, which are separated by spreading them across multiple
devices and corresponding drivers. Parts of that functionality / some of
those devices, however, can (as far as we currently know) not be
auto-detected by conventional means. While older (specifically 5th- and
6th-)generation models do advertise most of their functionality via
standard platform devices in ACPI, newer generations do not.
As we are currently also not aware of any feasible way to query said
functionalities dynamically, this poses a problem. There is, however, a
device in ACPI that seems to be used by Windows for identifying
different Surface models: The Windows Surface Integration Device (WSID).
This device seems to have a HID corresponding to the overall set of
functionalities SSAM provides for the associated model.
This commit introduces a registry providing non-detectable device
information via software nodes. In addition, a SSAM platform hub driver
is introduced, which takes care of creating and managing the SSAM
devices specified in this registry. This approach allows for a
hierarchical setup akin to ACPI and is easily extendable, e.g. via
firmware node properties.
Note that this commit only provides the basis for the platform hub and
registry, and does not add any content to it. The registry will be
expanded in subsequent commits.
Signed-off-by: Maximilian Luz <luzmaximilian@gmail.com>
Link: https://lore.kernel.org/r/20210212115439.1525216-2-luzmaximilian@gmail.com
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
2021-02-12 12:54:34 +01:00
|
|
|
if (status) {
|
|
|
|
|
set_secondary_fwnode(&pdev->dev, NULL);
|
|
|
|
|
software_node_unregister_node_group(nodes);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
platform_set_drvdata(pdev, nodes);
|
|
|
|
|
return status;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int ssam_platform_hub_remove(struct platform_device *pdev)
|
|
|
|
|
{
|
|
|
|
|
const struct software_node **nodes = platform_get_drvdata(pdev);
|
|
|
|
|
|
2021-10-28 02:22:42 +02:00
|
|
|
ssam_remove_clients(&pdev->dev);
|
platform/surface: Set up Surface Aggregator device registry
The Surface System Aggregator Module (SSAM) subsystem provides various
functionalities, which are separated by spreading them across multiple
devices and corresponding drivers. Parts of that functionality / some of
those devices, however, can (as far as we currently know) not be
auto-detected by conventional means. While older (specifically 5th- and
6th-)generation models do advertise most of their functionality via
standard platform devices in ACPI, newer generations do not.
As we are currently also not aware of any feasible way to query said
functionalities dynamically, this poses a problem. There is, however, a
device in ACPI that seems to be used by Windows for identifying
different Surface models: The Windows Surface Integration Device (WSID).
This device seems to have a HID corresponding to the overall set of
functionalities SSAM provides for the associated model.
This commit introduces a registry providing non-detectable device
information via software nodes. In addition, a SSAM platform hub driver
is introduced, which takes care of creating and managing the SSAM
devices specified in this registry. This approach allows for a
hierarchical setup akin to ACPI and is easily extendable, e.g. via
firmware node properties.
Note that this commit only provides the basis for the platform hub and
registry, and does not add any content to it. The registry will be
expanded in subsequent commits.
Signed-off-by: Maximilian Luz <luzmaximilian@gmail.com>
Link: https://lore.kernel.org/r/20210212115439.1525216-2-luzmaximilian@gmail.com
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
2021-02-12 12:54:34 +01:00
|
|
|
set_secondary_fwnode(&pdev->dev, NULL);
|
|
|
|
|
software_node_unregister_node_group(nodes);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static struct platform_driver ssam_platform_hub_driver = {
|
|
|
|
|
.probe = ssam_platform_hub_probe,
|
|
|
|
|
.remove = ssam_platform_hub_remove,
|
|
|
|
|
.driver = {
|
|
|
|
|
.name = "surface_aggregator_platform_hub",
|
|
|
|
|
.acpi_match_table = ssam_platform_hub_match,
|
|
|
|
|
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
|
|
|
|
|
},
|
|
|
|
|
};
|
2021-02-12 12:54:35 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
/* -- Module initialization. ------------------------------------------------ */
|
|
|
|
|
|
|
|
|
|
static int __init ssam_device_hub_init(void)
|
|
|
|
|
{
|
|
|
|
|
int status;
|
|
|
|
|
|
|
|
|
|
status = platform_driver_register(&ssam_platform_hub_driver);
|
|
|
|
|
if (status)
|
2022-05-27 04:34:46 +02:00
|
|
|
goto err_platform;
|
2021-02-12 12:54:35 +01:00
|
|
|
|
|
|
|
|
status = ssam_device_driver_register(&ssam_base_hub_driver);
|
|
|
|
|
if (status)
|
2022-05-27 04:34:46 +02:00
|
|
|
goto err_base;
|
|
|
|
|
|
|
|
|
|
status = ssam_device_driver_register(&ssam_kip_hub_driver);
|
|
|
|
|
if (status)
|
|
|
|
|
goto err_kip;
|
2021-02-12 12:54:35 +01:00
|
|
|
|
2022-05-27 04:34:46 +02:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
err_kip:
|
|
|
|
|
ssam_device_driver_unregister(&ssam_base_hub_driver);
|
|
|
|
|
err_base:
|
|
|
|
|
platform_driver_unregister(&ssam_platform_hub_driver);
|
|
|
|
|
err_platform:
|
2021-02-12 12:54:35 +01:00
|
|
|
return status;
|
|
|
|
|
}
|
|
|
|
|
module_init(ssam_device_hub_init);
|
|
|
|
|
|
|
|
|
|
static void __exit ssam_device_hub_exit(void)
|
|
|
|
|
{
|
2022-05-27 04:34:46 +02:00
|
|
|
ssam_device_driver_unregister(&ssam_kip_hub_driver);
|
2021-02-12 12:54:35 +01:00
|
|
|
ssam_device_driver_unregister(&ssam_base_hub_driver);
|
|
|
|
|
platform_driver_unregister(&ssam_platform_hub_driver);
|
|
|
|
|
}
|
|
|
|
|
module_exit(ssam_device_hub_exit);
|
platform/surface: Set up Surface Aggregator device registry
The Surface System Aggregator Module (SSAM) subsystem provides various
functionalities, which are separated by spreading them across multiple
devices and corresponding drivers. Parts of that functionality / some of
those devices, however, can (as far as we currently know) not be
auto-detected by conventional means. While older (specifically 5th- and
6th-)generation models do advertise most of their functionality via
standard platform devices in ACPI, newer generations do not.
As we are currently also not aware of any feasible way to query said
functionalities dynamically, this poses a problem. There is, however, a
device in ACPI that seems to be used by Windows for identifying
different Surface models: The Windows Surface Integration Device (WSID).
This device seems to have a HID corresponding to the overall set of
functionalities SSAM provides for the associated model.
This commit introduces a registry providing non-detectable device
information via software nodes. In addition, a SSAM platform hub driver
is introduced, which takes care of creating and managing the SSAM
devices specified in this registry. This approach allows for a
hierarchical setup akin to ACPI and is easily extendable, e.g. via
firmware node properties.
Note that this commit only provides the basis for the platform hub and
registry, and does not add any content to it. The registry will be
expanded in subsequent commits.
Signed-off-by: Maximilian Luz <luzmaximilian@gmail.com>
Link: https://lore.kernel.org/r/20210212115439.1525216-2-luzmaximilian@gmail.com
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
2021-02-12 12:54:34 +01:00
|
|
|
|
|
|
|
|
MODULE_AUTHOR("Maximilian Luz <luzmaximilian@gmail.com>");
|
|
|
|
|
MODULE_DESCRIPTION("Device-registry for Surface System Aggregator Module");
|
|
|
|
|
MODULE_LICENSE("GPL");
|