From: Maximilian Luz <luzmaximilian@gmail.com>
To: Hans de Goede <hdegoede@redhat.com>,
Jiri Kosina <jikos@kernel.org>,
Sebastian Reichel <sre@kernel.org>
Cc: Mark Gross <markgross@kernel.org>,
Benjamin Tissoires <benjamin.tissoires@redhat.com>,
Jonathan Corbet <corbet@lwn.net>,
platform-driver-x86@vger.kernel.org, linux-input@vger.kernel.org,
linux-pm@vger.kernel.org, linux-doc@vger.kernel.org,
Maximilian Luz <luzmaximilian@gmail.com>
Subject: [PATCH v2 11/12] platform/surface: aggregator_registry: Add KIP device hub
Date: Fri, 27 May 2022 04:34:46 +0200 [thread overview]
Message-ID: <20220527023447.2460025-12-luzmaximilian@gmail.com> (raw)
In-Reply-To: <20220527023447.2460025-1-luzmaximilian@gmail.com>
Add a Surface System Aggregator Module (SSAM) client device hub for
hot-removable devices managed via the KIP subsystem.
The KIP subsystem (full name unknown, abbreviation has been obtained
through reverse engineering) is a subsystem that manages hot-removable
SSAM client devices. Specifically, it manages HID input devices
contained in the detachable keyboard cover of the Surface Pro 8 and
Surface Pro X.
The KIP subsystem handles a single group of devices (e.g. all devices
contained in the keyboard cover) and cannot handle devices individually.
Thus we model it as a client device hub, which (hot-)removes all devices
contained under it once removal of the hub (e.g. keyboard cover) has
been detected and (re-)adds all devices once the physical hub device has
been (re-)attached. To do this, use the previously generified SSAM
subsystem hub framework.
Signed-off-by: Maximilian Luz <luzmaximilian@gmail.com>
---
Changes in v2:
- Change KIP hub device UID to improve consistency.
---
.../surface/surface_aggregator_registry.c | 103 +++++++++++++++++-
1 file changed, 101 insertions(+), 2 deletions(-)
diff --git a/drivers/platform/surface/surface_aggregator_registry.c b/drivers/platform/surface/surface_aggregator_registry.c
index b11ce87c7184..f15cef60630f 100644
--- a/drivers/platform/surface/surface_aggregator_registry.c
+++ b/drivers/platform/surface/surface_aggregator_registry.c
@@ -551,6 +551,93 @@ static struct ssam_device_driver ssam_base_hub_driver = {
};
+/* -- 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,
+ },
+};
+
+
/* -- SSAM platform/meta-hub driver. ---------------------------------------- */
static const struct acpi_device_id ssam_platform_hub_match[] = {
@@ -673,18 +760,30 @@ static int __init ssam_device_hub_init(void)
status = platform_driver_register(&ssam_platform_hub_driver);
if (status)
- return status;
+ goto err_platform;
status = ssam_device_driver_register(&ssam_base_hub_driver);
if (status)
- platform_driver_unregister(&ssam_platform_hub_driver);
+ goto err_base;
+
+ status = ssam_device_driver_register(&ssam_kip_hub_driver);
+ if (status)
+ goto err_kip;
+ return 0;
+
+err_kip:
+ ssam_device_driver_unregister(&ssam_base_hub_driver);
+err_base:
+ platform_driver_unregister(&ssam_platform_hub_driver);
+err_platform:
return status;
}
module_init(ssam_device_hub_init);
static void __exit ssam_device_hub_exit(void)
{
+ ssam_device_driver_unregister(&ssam_kip_hub_driver);
ssam_device_driver_unregister(&ssam_base_hub_driver);
platform_driver_unregister(&ssam_platform_hub_driver);
}
--
2.36.1
next prev parent reply other threads:[~2022-05-27 2:35 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-05-27 2:34 [PATCH v2 00/12] platform/surface: aggregator: Add support for client hot-removal Maximilian Luz
2022-05-27 2:34 ` [PATCH v2 01/12] platform/surface: aggregator: Allow is_ssam_device() to be used when CONFIG_SURFACE_AGGREGATOR_BUS is disabled Maximilian Luz
2022-05-27 2:34 ` [PATCH v2 02/12] platform/surface: aggregator: Allow devices to be marked as hot-removed Maximilian Luz
2022-05-27 2:34 ` [PATCH v2 03/12] platform/surface: aggregator: Allow notifiers to avoid communication on unregistering Maximilian Luz
2022-05-27 2:34 ` [PATCH v2 04/12] platform/surface: aggregator_registry: Use client device wrappers for notifier registration Maximilian Luz
2022-05-27 2:34 ` [PATCH v2 05/12] power/supply: surface_charger: " Maximilian Luz
2022-06-09 18:01 ` Sebastian Reichel
2022-05-27 2:34 ` [PATCH v2 06/12] power/supply: surface_battery: " Maximilian Luz
2022-06-09 18:01 ` Sebastian Reichel
2022-05-27 2:34 ` [PATCH v2 07/12] HID: surface-hid: Add support for hot-removal Maximilian Luz
2022-05-27 2:34 ` [PATCH v2 08/12] platform/surface: aggregator: Add comment for KIP subsystem category Maximilian Luz
2022-05-27 2:34 ` [PATCH v2 09/12] platform/surface: aggregator_registry: Generify subsystem hub functionality Maximilian Luz
2022-05-27 2:34 ` [PATCH v2 10/12] platform/surface: aggregator_registry: Change device ID for base hub Maximilian Luz
2022-05-27 2:34 ` Maximilian Luz [this message]
2022-05-27 2:34 ` [PATCH v2 12/12] platform/surface: aggregator_registry: Add support for keyboard cover on Surface Pro 8 Maximilian Luz
2022-06-13 15:27 ` [PATCH v2 00/12] platform/surface: aggregator: Add support for client hot-removal Hans de Goede
2022-06-14 7:48 ` Benjamin Tissoires
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20220527023447.2460025-12-luzmaximilian@gmail.com \
--to=luzmaximilian@gmail.com \
--cc=benjamin.tissoires@redhat.com \
--cc=corbet@lwn.net \
--cc=hdegoede@redhat.com \
--cc=jikos@kernel.org \
--cc=linux-doc@vger.kernel.org \
--cc=linux-input@vger.kernel.org \
--cc=linux-pm@vger.kernel.org \
--cc=markgross@kernel.org \
--cc=platform-driver-x86@vger.kernel.org \
--cc=sre@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).