All of lore.kernel.org
 help / color / mirror / Atom feed
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


  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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.