From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.remote-ip=95.215.58.118 ARC-Seal: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; cv=none; t=1793775964; b=jUzjg0mW8qJwLJ7U2fM8blEBjtSzToeLvwf2euueRrSeJ5ftE+4DjA5BBp3kU+Wzp0n+ vgxL8Zz6wVS/cw9NArSjUx9ZTOdJxoXsZOvZPpAu5XaX5uIR7DoKCQBEsLlpuWdkTuG3U Wxlu2JCG6et21k5xcan8qCBsJbOwCEj0406DD/UCwLlCGmGvQvzgGAWsZ21h5QA92WhDX //U4TFSRNyU8Lfnq0CExMpkIYjOMDEnNO2i6UIDeWWOo8xIo4dX+y/q1sADeufElK9v9S 9rlzkStHULLF8ucqI+P9kxaVvHeUDS3Y8nQJ9Hn242UV3Au7IO7aZBUHs0cUQYeWkSA== ARC-Message-Signature: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; c=relaxed/relaxed; t=1793775964; h=DMARC-Filter:X-Envelope-To:DKIM-Signature:X-Envelope-To:Received: X-Mizu-Trace-ID:X-Migadu-Flow:From:To:Cc:Subject:Date:Message-ID: X-Mailer:In-Reply-To:References:MIME-Version: Content-Transfer-Encoding; bh=O4s+EhwbikmitcBwtvaK2nWWDlS5IjTnGOVxRj5axnA=; b=NoujlWL5RyVCehM/mx9eAWctQ/tvY3oA/qEf72WsvTz7zHMZ6sX6pn0BxMxZ4A1xsMTT EfxQTpySZF9ZvdCP7cJzNg7ldNhzksyW0Hm3y84Dx0PTgRZqPoWIYnMfqehU85p/QLNyA tOupU4jFcPswZBJRVuhTRr8MMmL6wPsw4OgblG6NuS8rzB/PVk4RRJdSPnOLgVLPCF3Gl IaBQPgyQDJmdiBuFW4SkRAAwcw87IarF46R1HD+82qO9wLdLYaBKAf6+r5OL8J9ZesfHn Fy6M0iiLJLv64Wqj68FeDy1WRr3vO986Bo17fTpcw+pOV/sz9mcjZ1MkE5aRcKlbkdA== ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass header.from=packett.cool; spf=pass smtp.mailfrom=packett.cool; dkim=pass header.d=packett.cool header.i=@packett.cool header.a=rsa-sha256 header.s=key1 header.b=hOe5EEux; arc=none smtp.remote-ip=95.215.58.118 Received: from mta1.migadu.com (out-118.mta1.migadu.com [95.215.58.118]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits) key-exchange X25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2BB81606A32D for ; Wed, 4 Nov 2026 07:06:03 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.2 smtp.subspace.kernel.org 2BB81606A32D Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=packett.cool Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=packett.cool Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key, unprotected) header.d=packett.cool header.i=@packett.cool header.a=rsa-sha256 header.s=key1 header.b=hOe5EEux X-Envelope-To: devicetree@vger.kernel.org DKIM-Signature: a=rsa-sha256; bh=CQru9P9q47Kx5STBo5ffycljRxiD1FuZ+bafX8rql98=; c=simple/simple; d=packett.cool; h=from:to:subject:date:message-id:mime-version:content-type; s=key1; t=1793775962; v=1; x=1794380762; b=hOe5EEuxpDGR+sbI8uD0i5VZCQYfjo//oicy4SiJ4iIy7iyWHrU1n3cVUtBQ+ZreHyYMfEiP MrCGpb44d5LsIOOOqPd9/1zI5OPUWWsnX4YgXE5cy7kru+KlNQIOdtixJWHx058oCOrVk/DwRkc OwXy66CWsrL8m/K4Zd8egt0xsGrVocC1Xttzem2e4uzMZja6SyV2eiBsysFPKGf5Kq9ceJspW0p 11ZUM+qlAi1ge5dqq1xsVWkovDaoldevRIoHw8cIwERyiamZ6LxtlPQssV493F7iwliBrKmU6UV 9CEhtLDbtUix6Pl+fAmLabEuv//04iz9C9YrWN4wStv4Q== X-Envelope-To: devicetree@vger.kernel.org Received: by smtp.migadu.com with ESMTPS id 94ca4bed4724cb0d; Wed, 04 Nov 2026 07:06:02 +0000 X-Mizu-Trace-ID: 94ca4bed4724cb0d X-Migadu-Flow: FLOW_OUT From: Val Packett To: Alexandre Belloni , Maximilian Luz , Val Packett Cc: Bjorn Andersson , Konrad Dybcio , Abel Vesa , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Hans de Goede , =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= , linux-arm-msm@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-rtc@vger.kernel.org Subject: [PATCH 4/5] rtc: Add basic support for RTC via Surface System Aggregator Module Date: Wed, 4 Nov 2026 04:04:35 -0300 Message-ID: <20261104070441.74127-5-val@packett.cool> X-Mailer: git-send-email 2.56.0 In-Reply-To: <20261104070441.74127-1-val@packett.cool> References: <20261104070441.74127-1-val@packett.cool> X-Mailing-List: devicetree@vger.kernel.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Transfer-Encoding: 8bit From: Maximilian Luz The Surface Pro X uses an RTC provided by the SSAM. Add a driver for it. Signed-off-by: Maximilian Luz Signed-off-by: Val Packett --- MAINTAINERS | 8 +++ drivers/rtc/Kconfig | 9 +++ drivers/rtc/Makefile | 1 + drivers/rtc/rtc-surface.c | 129 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 147 insertions(+) create mode 100644 drivers/rtc/rtc-surface.c diff --git a/MAINTAINERS b/MAINTAINERS index d23f7d8c4c17..36b3abad50f4 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -18585,6 +18585,14 @@ L: platform-driver-x86@vger.kernel.org S: Supported F: drivers/platform/surface/surfacepro3_button.c +MICROSOFT SURFACE PRO X RTC DRIVER +M: Maximilian Luz +M: Val Packett +L: linux-rtc@vger.kernel.org +L: linux-arm-msm@vger.kernel.org +S: Maintained +F: drivers/rtc/rtc-surface.c + MICROSOFT SURFACE SYSTEM AGGREGATOR HUB DRIVER M: Maximilian Luz L: platform-driver-x86@vger.kernel.org diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 73ec9230edfd..6af1aa18724f 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -1451,6 +1451,15 @@ config RTC_DRV_NTXEC embedded controller found in certain e-book readers designed by the original design manufacturer Netronix. +config RTC_DRV_SURFACE + tristate "Microsoft Surface Aggregator RTC" + depends on SURFACE_AGGREGATOR + depends on SURFACE_AGGREGATOR_BUS + help + Say yes here if you want to support the RTC functionality of the + Surface Aggregator Module (embedded controller) found in the + Microsoft Surface Pro X tablet. + comment "on-CPU RTC drivers" config RTC_DRV_ASM9260 diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index 46f1a0fc2416..f86e827c14e0 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile @@ -186,6 +186,7 @@ obj-$(CONFIG_RTC_DRV_SUN4V) += rtc-sun4v.o obj-$(CONFIG_RTC_DRV_SUN6I) += rtc-sun6i.o obj-$(CONFIG_RTC_DRV_SUNPLUS) += rtc-sunplus.o obj-$(CONFIG_RTC_DRV_SUNXI) += rtc-sunxi.o +obj-$(CONFIG_RTC_DRV_SURFACE) += rtc-surface.o obj-$(CONFIG_RTC_DRV_TEGRA) += rtc-tegra.o obj-$(CONFIG_RTC_DRV_TEST) += rtc-test.o obj-$(CONFIG_RTC_DRV_TI_K3) += rtc-ti-k3.o diff --git a/drivers/rtc/rtc-surface.c b/drivers/rtc/rtc-surface.c new file mode 100644 index 000000000000..f6c17c4e98d5 --- /dev/null +++ b/drivers/rtc/rtc-surface.c @@ -0,0 +1,129 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * AC driver for 7th-generation Microsoft Surface devices via Surface System + * Aggregator Module (SSAM). + * + * Copyright (C) 2019-2021 Maximilian Luz + */ + +#include +#include +#include +#include +#include + +#include + +struct surface_rtc { + struct ssam_device *sdev; + struct rtc_device *rtc; +}; + +SSAM_DEFINE_SYNC_REQUEST_R(__ssam_rtc_get_unix_time, __le32, { + .target_category = SSAM_SSH_TC_SAM, + .target_id = SSAM_SSH_TID_SAM, + .instance_id = 0x00, + .command_id = 0x10, +}); + +SSAM_DEFINE_SYNC_REQUEST_W(__ssam_rtc_set_unix_time, __le32, { + .target_category = SSAM_SSH_TC_SAM, + .target_id = SSAM_SSH_TID_SAM, + .instance_id = 0x00, + .command_id = 0x0f, +}); + +static int ssam_rtc_get_unix_time(struct surface_rtc *srtc, u32 *time) +{ + __le32 time_le; + int status; + + status = __ssam_rtc_get_unix_time(srtc->sdev->ctrl, &time_le); + if (status) + return status; + + *time = le32_to_cpu(time_le); + return 0; +} + +static int ssam_rtc_set_unix_time(struct surface_rtc *srtc, u32 time) +{ + __le32 time_le = cpu_to_le32(time); + + return __ssam_rtc_set_unix_time(srtc->sdev->ctrl, &time_le); +} + +static int surface_rtc_read_time(struct device *dev, struct rtc_time *tm) +{ + struct surface_rtc *srtc = dev_get_drvdata(dev); + int status; + u32 time; + + status = ssam_rtc_get_unix_time(srtc, &time); + if (status) + return status; + + rtc_time64_to_tm(time, tm); + return 0; +} + +static int surface_rtc_set_time(struct device *dev, struct rtc_time *tm) +{ + struct surface_rtc *srtc = dev_get_drvdata(dev); + time64_t time = rtc_tm_to_time64(tm); + + return ssam_rtc_set_unix_time(srtc, (u32)time); +} + +static const struct rtc_class_ops surface_rtc_ops = { + .read_time = surface_rtc_read_time, + .set_time = surface_rtc_set_time, +}; + +static int surface_rtc_probe(struct ssam_device *sdev) +{ + struct surface_rtc *srtc; + + srtc = devm_kzalloc(&sdev->dev, sizeof(*srtc), GFP_KERNEL); + if (!srtc) + return -ENOMEM; + + srtc->sdev = sdev; + + srtc->rtc = devm_rtc_allocate_device(&sdev->dev); + if (IS_ERR(srtc->rtc)) + return PTR_ERR(srtc->rtc); + + srtc->rtc->ops = &surface_rtc_ops; + srtc->rtc->range_max = U32_MAX; + + ssam_device_set_drvdata(sdev, srtc); + + return devm_rtc_register_device(srtc->rtc); +} + +static void surface_rtc_remove(struct ssam_device *sdev) +{ + /* Device-managed allocations take care of everything... */ +} + +static const struct ssam_device_id surface_rtc_match[] = { + { SSAM_SDEV(SAM, SAM, 0x00, 0x00) }, + { }, +}; +MODULE_DEVICE_TABLE(ssam, surface_rtc_match); + +static struct ssam_device_driver surface_rtc_driver = { + .probe = surface_rtc_probe, + .remove = surface_rtc_remove, + .match_table = surface_rtc_match, + .driver = { + .name = "surface_rtc", + .probe_type = PROBE_PREFER_ASYNCHRONOUS, + }, +}; +module_ssam_device_driver(surface_rtc_driver); + +MODULE_AUTHOR("Maximilian Luz "); +MODULE_DESCRIPTION("RTC driver for Surface System Aggregator Module"); +MODULE_LICENSE("GPL"); -- 2.56.0