From 28f06e76b0bc0fd385b82a189a616d74a978ffdb Mon Sep 17 00:00:00 2001 From: Sasha Finkelstein Date: Mon, 25 May 2026 14:11:16 +0200 Subject: [PATCH 01/33] Bluetooth: Add Broadcom channel priority commands Certain Broadcom bluetooth chips (bcm4377/bcm4378/bcm438) need ACL streams carrying audio to be set as "high priority" using a vendor specific command to prevent 10-ish second-long dropouts whenever something does a device scan. This patch sends the command when the socket priority is set to TC_PRIO_INTERACTIVE, as BlueZ does for audio. From experimenting with the hardware - this command is not suitable for per-skb priority switching, as prioritization is done on the handle level, with this command reconfiguring certain radio timings, and dropping to low priority in order to send a low packet on the same handle as an audio stream is being played on causes the same kind of dropout it is supposed to avoid. In addition, the hardware is rather picky about when this command can be sent, as sending it during connection open results in a timeout. The vendor stacks solve it by having high-level visibility into what a connection is used for and sending it from userspace when it is known that an audio stream is about to start. As we can't have that visibility without introducing a new ioctl, the socket priority is used as proxy. Reviewed-by: Neal Gompa Signed-off-by: Sasha Finkelstein --- MAINTAINERS | 2 ++ drivers/bluetooth/hci_bcm4377.c | 2 ++ include/net/bluetooth/hci_core.h | 15 +++++++++++++ net/bluetooth/Kconfig | 7 ++++++ net/bluetooth/Makefile | 1 + net/bluetooth/brcm.c | 38 ++++++++++++++++++++++++++++++++ net/bluetooth/brcm.h | 19 ++++++++++++++++ net/bluetooth/hci_core.c | 4 ++++ 8 files changed, 88 insertions(+) create mode 100644 net/bluetooth/brcm.c create mode 100644 net/bluetooth/brcm.h diff --git a/MAINTAINERS b/MAINTAINERS index f16f609d68c187..eefdd8a1579ac1 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2575,6 +2575,8 @@ F: include/dt-bindings/pinctrl/apple.h F: include/linux/mfd/macsmc.h F: include/linux/soc/apple/* F: include/uapi/drm/asahi_drm.h +F: net/bluetooth/brcm.c +F: net/bluetooth/brcm.h ARM/ARTPEC MACHINE SUPPORT M: Jesper Nilsson diff --git a/drivers/bluetooth/hci_bcm4377.c b/drivers/bluetooth/hci_bcm4377.c index 925d0a6359453e..5f79920c030681 100644 --- a/drivers/bluetooth/hci_bcm4377.c +++ b/drivers/bluetooth/hci_bcm4377.c @@ -2397,6 +2397,8 @@ static int bcm4377_probe(struct pci_dev *pdev, const struct pci_device_id *id) if (bcm4377->hw->broken_le_ext_adv_report_phy) hci_set_quirk(hdev, HCI_QUIRK_FIXUP_LE_EXT_ADV_REPORT_PHY); + hci_set_brcm_capable(hdev); + pci_set_drvdata(pdev, bcm4377); hci_set_drvdata(hdev, bcm4377); SET_HCIDEV_DEV(hdev, &pdev->dev); diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index a7bffb908c1ec9..65064aff82241d 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -642,6 +642,10 @@ struct hci_dev { bool aosp_quality_report; #endif +#if IS_ENABLED(CONFIG_BT_BRCMEXT) + bool brcm_capable; +#endif + int (*open)(struct hci_dev *hdev); int (*close)(struct hci_dev *hdev); int (*flush)(struct hci_dev *hdev); @@ -756,6 +760,10 @@ struct hci_conn { unsigned int sent; +#if IS_ENABLED(CONFIG_BT_BRCMEXT) + bool brcm_high_prio; +#endif + struct sk_buff_head data_q; struct list_head chan_list; @@ -1791,6 +1799,13 @@ static inline void hci_set_aosp_capable(struct hci_dev *hdev) #endif } +static inline void hci_set_brcm_capable(struct hci_dev *hdev) +{ +#if IS_ENABLED(CONFIG_BT_BRCMEXT) + hdev->brcm_capable = true; +#endif +} + static inline void hci_devcd_setup(struct hci_dev *hdev) { #ifdef CONFIG_DEV_COREDUMP diff --git a/net/bluetooth/Kconfig b/net/bluetooth/Kconfig index 6b2b65a667008b..0f2a5fbcafc563 100644 --- a/net/bluetooth/Kconfig +++ b/net/bluetooth/Kconfig @@ -110,6 +110,13 @@ config BT_AOSPEXT This options enables support for the Android Open Source Project defined HCI vendor extensions. +config BT_BRCMEXT + bool "Enable Broadcom extensions" + depends on BT + help + This option enables support for the Broadcom defined HCI + vendor extensions. + config BT_DEBUGFS bool "Export Bluetooth internals in debugfs" depends on BT && DEBUG_FS diff --git a/net/bluetooth/Makefile b/net/bluetooth/Makefile index a7eede7616d856..b4c9013a46cec2 100644 --- a/net/bluetooth/Makefile +++ b/net/bluetooth/Makefile @@ -24,5 +24,6 @@ bluetooth-$(CONFIG_BT_LE) += iso.o bluetooth-$(CONFIG_BT_LEDS) += leds.o bluetooth-$(CONFIG_BT_MSFTEXT) += msft.o bluetooth-$(CONFIG_BT_AOSPEXT) += aosp.o +bluetooth-$(CONFIG_BT_BRCMEXT) += brcm.o bluetooth-$(CONFIG_BT_DEBUGFS) += hci_debugfs.o bluetooth-$(CONFIG_BT_SELFTEST) += selftest.o diff --git a/net/bluetooth/brcm.c b/net/bluetooth/brcm.c new file mode 100644 index 00000000000000..299d83d465c3a5 --- /dev/null +++ b/net/bluetooth/brcm.c @@ -0,0 +1,38 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2026 The Asahi Linux Contributors + */ + +#include +#include + +#include "brcm.h" + +struct brcm_prio_cmd { + __le16 handle; + u8 enable; +} __packed; + +int brcm_set_high_priority(struct hci_dev *hdev, struct hci_conn *conn, + bool enable) +{ + struct sk_buff *skb; + struct brcm_prio_cmd cmd; + + if (!hdev->brcm_capable) + return 0; + + if (conn->brcm_high_prio == enable) + return 0; + + cmd.handle = cpu_to_le16(conn->handle); + cmd.enable = !!enable; + + skb = hci_cmd_sync(hdev, 0xfc57, sizeof(cmd), &cmd, HCI_CMD_TIMEOUT); + if (IS_ERR(skb)) + return PTR_ERR(skb); + + conn->brcm_high_prio = enable; + kfree_skb(skb); + return 0; +} diff --git a/net/bluetooth/brcm.h b/net/bluetooth/brcm.h new file mode 100644 index 00000000000000..2290fc6cf798b8 --- /dev/null +++ b/net/bluetooth/brcm.h @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2026 The Asahi Linux Contributors + */ + +#if IS_ENABLED(CONFIG_BT_BRCMEXT) + +int brcm_set_high_priority(struct hci_dev *hdev, struct hci_conn *conn, + bool enable); + +#else + +static inline int brcm_set_high_priority(struct hci_dev *hdev, + struct hci_conn *conn, bool enable) +{ + return 0; +} + +#endif diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 01f8ceeb1c0c84..5216efc295edee 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -46,6 +46,7 @@ #include "msft.h" #include "aosp.h" #include "hci_codec.h" +#include "brcm.h" static void hci_rx_work(struct work_struct *work); static void hci_cmd_work(struct work_struct *work); @@ -3696,6 +3697,9 @@ static void hci_sched_acl_pkt(struct hci_dev *hdev) skb = skb_dequeue(&chan->data_q); + if (skb->priority == TC_PRIO_INTERACTIVE) + brcm_set_high_priority(hdev, chan->conn, true); + hci_conn_enter_active_mode(chan->conn, bt_cb(skb)->force_active); From f20419ae8cc84945bca06bdf489573128bf389db Mon Sep 17 00:00:00 2001 From: Janne Grunau Date: Wed, 3 Jun 2026 23:55:55 +0200 Subject: [PATCH 02/33] Revert "Bluetooth: Add Broadcom channel priority commands" This reverts commit 30fcc498ff7c66669b7065a5ff350df7a37f4424. --- MAINTAINERS | 2 -- drivers/bluetooth/hci_bcm4377.c | 2 -- include/net/bluetooth/hci_core.h | 15 ------------- net/bluetooth/Kconfig | 7 ------ net/bluetooth/Makefile | 1 - net/bluetooth/brcm.c | 38 -------------------------------- net/bluetooth/brcm.h | 19 ---------------- net/bluetooth/hci_core.c | 4 ---- 8 files changed, 88 deletions(-) delete mode 100644 net/bluetooth/brcm.c delete mode 100644 net/bluetooth/brcm.h diff --git a/MAINTAINERS b/MAINTAINERS index eefdd8a1579ac1..f16f609d68c187 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2575,8 +2575,6 @@ F: include/dt-bindings/pinctrl/apple.h F: include/linux/mfd/macsmc.h F: include/linux/soc/apple/* F: include/uapi/drm/asahi_drm.h -F: net/bluetooth/brcm.c -F: net/bluetooth/brcm.h ARM/ARTPEC MACHINE SUPPORT M: Jesper Nilsson diff --git a/drivers/bluetooth/hci_bcm4377.c b/drivers/bluetooth/hci_bcm4377.c index 5f79920c030681..925d0a6359453e 100644 --- a/drivers/bluetooth/hci_bcm4377.c +++ b/drivers/bluetooth/hci_bcm4377.c @@ -2397,8 +2397,6 @@ static int bcm4377_probe(struct pci_dev *pdev, const struct pci_device_id *id) if (bcm4377->hw->broken_le_ext_adv_report_phy) hci_set_quirk(hdev, HCI_QUIRK_FIXUP_LE_EXT_ADV_REPORT_PHY); - hci_set_brcm_capable(hdev); - pci_set_drvdata(pdev, bcm4377); hci_set_drvdata(hdev, bcm4377); SET_HCIDEV_DEV(hdev, &pdev->dev); diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 65064aff82241d..a7bffb908c1ec9 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -642,10 +642,6 @@ struct hci_dev { bool aosp_quality_report; #endif -#if IS_ENABLED(CONFIG_BT_BRCMEXT) - bool brcm_capable; -#endif - int (*open)(struct hci_dev *hdev); int (*close)(struct hci_dev *hdev); int (*flush)(struct hci_dev *hdev); @@ -760,10 +756,6 @@ struct hci_conn { unsigned int sent; -#if IS_ENABLED(CONFIG_BT_BRCMEXT) - bool brcm_high_prio; -#endif - struct sk_buff_head data_q; struct list_head chan_list; @@ -1799,13 +1791,6 @@ static inline void hci_set_aosp_capable(struct hci_dev *hdev) #endif } -static inline void hci_set_brcm_capable(struct hci_dev *hdev) -{ -#if IS_ENABLED(CONFIG_BT_BRCMEXT) - hdev->brcm_capable = true; -#endif -} - static inline void hci_devcd_setup(struct hci_dev *hdev) { #ifdef CONFIG_DEV_COREDUMP diff --git a/net/bluetooth/Kconfig b/net/bluetooth/Kconfig index 0f2a5fbcafc563..6b2b65a667008b 100644 --- a/net/bluetooth/Kconfig +++ b/net/bluetooth/Kconfig @@ -110,13 +110,6 @@ config BT_AOSPEXT This options enables support for the Android Open Source Project defined HCI vendor extensions. -config BT_BRCMEXT - bool "Enable Broadcom extensions" - depends on BT - help - This option enables support for the Broadcom defined HCI - vendor extensions. - config BT_DEBUGFS bool "Export Bluetooth internals in debugfs" depends on BT && DEBUG_FS diff --git a/net/bluetooth/Makefile b/net/bluetooth/Makefile index b4c9013a46cec2..a7eede7616d856 100644 --- a/net/bluetooth/Makefile +++ b/net/bluetooth/Makefile @@ -24,6 +24,5 @@ bluetooth-$(CONFIG_BT_LE) += iso.o bluetooth-$(CONFIG_BT_LEDS) += leds.o bluetooth-$(CONFIG_BT_MSFTEXT) += msft.o bluetooth-$(CONFIG_BT_AOSPEXT) += aosp.o -bluetooth-$(CONFIG_BT_BRCMEXT) += brcm.o bluetooth-$(CONFIG_BT_DEBUGFS) += hci_debugfs.o bluetooth-$(CONFIG_BT_SELFTEST) += selftest.o diff --git a/net/bluetooth/brcm.c b/net/bluetooth/brcm.c deleted file mode 100644 index 299d83d465c3a5..00000000000000 --- a/net/bluetooth/brcm.c +++ /dev/null @@ -1,38 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (C) 2026 The Asahi Linux Contributors - */ - -#include -#include - -#include "brcm.h" - -struct brcm_prio_cmd { - __le16 handle; - u8 enable; -} __packed; - -int brcm_set_high_priority(struct hci_dev *hdev, struct hci_conn *conn, - bool enable) -{ - struct sk_buff *skb; - struct brcm_prio_cmd cmd; - - if (!hdev->brcm_capable) - return 0; - - if (conn->brcm_high_prio == enable) - return 0; - - cmd.handle = cpu_to_le16(conn->handle); - cmd.enable = !!enable; - - skb = hci_cmd_sync(hdev, 0xfc57, sizeof(cmd), &cmd, HCI_CMD_TIMEOUT); - if (IS_ERR(skb)) - return PTR_ERR(skb); - - conn->brcm_high_prio = enable; - kfree_skb(skb); - return 0; -} diff --git a/net/bluetooth/brcm.h b/net/bluetooth/brcm.h deleted file mode 100644 index 2290fc6cf798b8..00000000000000 --- a/net/bluetooth/brcm.h +++ /dev/null @@ -1,19 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Copyright (C) 2026 The Asahi Linux Contributors - */ - -#if IS_ENABLED(CONFIG_BT_BRCMEXT) - -int brcm_set_high_priority(struct hci_dev *hdev, struct hci_conn *conn, - bool enable); - -#else - -static inline int brcm_set_high_priority(struct hci_dev *hdev, - struct hci_conn *conn, bool enable) -{ - return 0; -} - -#endif diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 5216efc295edee..01f8ceeb1c0c84 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -46,7 +46,6 @@ #include "msft.h" #include "aosp.h" #include "hci_codec.h" -#include "brcm.h" static void hci_rx_work(struct work_struct *work); static void hci_cmd_work(struct work_struct *work); @@ -3697,9 +3696,6 @@ static void hci_sched_acl_pkt(struct hci_dev *hdev) skb = skb_dequeue(&chan->data_q); - if (skb->priority == TC_PRIO_INTERACTIVE) - brcm_set_high_priority(hdev, chan->conn, true); - hci_conn_enter_active_mode(chan->conn, bt_cb(skb)->force_active); From cfbfd7d5392730a9499974c5e0eee126bd77603b Mon Sep 17 00:00:00 2001 From: Sasha Finkelstein Date: Tue, 7 Apr 2026 13:33:46 +0200 Subject: [PATCH 03/33] Bluetooth: Add Broadcom channel priority commands Certain Broadcom bluetooth chips (bcm4377/bcm4378/bcm438) need ACL streams carrying audio to be set as "high priority" using a vendor specific command to prevent 10-ish second-long dropouts whenever something does a device scan. This patch sends the command when the socket priority is set to TC_PRIO_INTERACTIVE, as BlueZ does for audio. Signed-off-by: Sasha Finkelstein --- MAINTAINERS | 2 ++ drivers/bluetooth/hci_bcm4377.c | 2 ++ include/net/bluetooth/bluetooth.h | 4 ++++ include/net/bluetooth/hci_core.h | 11 +++++++++++ net/bluetooth/Kconfig | 7 +++++++ net/bluetooth/Makefile | 1 + net/bluetooth/brcm.c | 29 +++++++++++++++++++++++++++++ net/bluetooth/brcm.h | 17 +++++++++++++++++ net/bluetooth/hci_conn.c | 27 +++++++++++++++++++++++++++ net/bluetooth/l2cap_sock.c | 13 +++++++++++++ 10 files changed, 113 insertions(+) create mode 100644 net/bluetooth/brcm.c create mode 100644 net/bluetooth/brcm.h diff --git a/MAINTAINERS b/MAINTAINERS index f16f609d68c187..eefdd8a1579ac1 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2575,6 +2575,8 @@ F: include/dt-bindings/pinctrl/apple.h F: include/linux/mfd/macsmc.h F: include/linux/soc/apple/* F: include/uapi/drm/asahi_drm.h +F: net/bluetooth/brcm.c +F: net/bluetooth/brcm.h ARM/ARTPEC MACHINE SUPPORT M: Jesper Nilsson diff --git a/drivers/bluetooth/hci_bcm4377.c b/drivers/bluetooth/hci_bcm4377.c index 925d0a6359453e..5f79920c030681 100644 --- a/drivers/bluetooth/hci_bcm4377.c +++ b/drivers/bluetooth/hci_bcm4377.c @@ -2397,6 +2397,8 @@ static int bcm4377_probe(struct pci_dev *pdev, const struct pci_device_id *id) if (bcm4377->hw->broken_le_ext_adv_report_phy) hci_set_quirk(hdev, HCI_QUIRK_FIXUP_LE_EXT_ADV_REPORT_PHY); + hci_set_brcm_capable(hdev); + pci_set_drvdata(pdev, bcm4377); hci_set_drvdata(hdev, bcm4377); SET_HCIDEV_DEV(hdev, &pdev->dev); diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h index 3faea66b19799a..5d82944370e427 100644 --- a/include/net/bluetooth/bluetooth.h +++ b/include/net/bluetooth/bluetooth.h @@ -458,6 +458,7 @@ struct l2cap_ctrl { }; struct hci_dev; +struct hci_conn; typedef void (*hci_req_complete_t)(struct hci_dev *hdev, u8 status, u16 opcode); typedef void (*hci_req_complete_skb_t)(struct hci_dev *hdev, u8 status, @@ -470,6 +471,9 @@ void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status, int hci_ethtool_ts_info(unsigned int index, int sk_proto, struct kernel_ethtool_ts_info *ts_info); +int hci_conn_setsockopt(struct hci_conn *conn, struct sock *sk, int level, + int optname, sockptr_t optval, unsigned int optlen); + #define HCI_REQ_START BIT(0) #define HCI_REQ_SKB BIT(1) diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index a7bffb908c1ec9..947e7c2b08dd81 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -642,6 +642,10 @@ struct hci_dev { bool aosp_quality_report; #endif +#if IS_ENABLED(CONFIG_BT_BRCMEXT) + bool brcm_capable; +#endif + int (*open)(struct hci_dev *hdev); int (*close)(struct hci_dev *hdev); int (*flush)(struct hci_dev *hdev); @@ -1791,6 +1795,13 @@ static inline void hci_set_aosp_capable(struct hci_dev *hdev) #endif } +static inline void hci_set_brcm_capable(struct hci_dev *hdev) +{ +#if IS_ENABLED(CONFIG_BT_BRCMEXT) + hdev->brcm_capable = true; +#endif +} + static inline void hci_devcd_setup(struct hci_dev *hdev) { #ifdef CONFIG_DEV_COREDUMP diff --git a/net/bluetooth/Kconfig b/net/bluetooth/Kconfig index 6b2b65a667008b..0f2a5fbcafc563 100644 --- a/net/bluetooth/Kconfig +++ b/net/bluetooth/Kconfig @@ -110,6 +110,13 @@ config BT_AOSPEXT This options enables support for the Android Open Source Project defined HCI vendor extensions. +config BT_BRCMEXT + bool "Enable Broadcom extensions" + depends on BT + help + This option enables support for the Broadcom defined HCI + vendor extensions. + config BT_DEBUGFS bool "Export Bluetooth internals in debugfs" depends on BT && DEBUG_FS diff --git a/net/bluetooth/Makefile b/net/bluetooth/Makefile index a7eede7616d856..b4c9013a46cec2 100644 --- a/net/bluetooth/Makefile +++ b/net/bluetooth/Makefile @@ -24,5 +24,6 @@ bluetooth-$(CONFIG_BT_LE) += iso.o bluetooth-$(CONFIG_BT_LEDS) += leds.o bluetooth-$(CONFIG_BT_MSFTEXT) += msft.o bluetooth-$(CONFIG_BT_AOSPEXT) += aosp.o +bluetooth-$(CONFIG_BT_BRCMEXT) += brcm.o bluetooth-$(CONFIG_BT_DEBUGFS) += hci_debugfs.o bluetooth-$(CONFIG_BT_SELFTEST) += selftest.o diff --git a/net/bluetooth/brcm.c b/net/bluetooth/brcm.c new file mode 100644 index 00000000000000..9aa0a265ab3d6b --- /dev/null +++ b/net/bluetooth/brcm.c @@ -0,0 +1,29 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2026 The Asahi Linux Contributors + */ + +#include +#include + +#include "brcm.h" + +int brcm_set_high_priority(struct hci_dev *hdev, u16 handle, bool enable) +{ + struct sk_buff *skb; + u8 cmd[3]; + + if (!hdev->brcm_capable) + return 0; + + cmd[0] = handle; + cmd[1] = handle >> 8; + cmd[2] = !!enable; + + skb = hci_cmd_sync(hdev, 0xfc57, sizeof(cmd), cmd, HCI_CMD_TIMEOUT); + if (IS_ERR(skb)) + return PTR_ERR(skb); + + kfree_skb(skb); + return 0; +} diff --git a/net/bluetooth/brcm.h b/net/bluetooth/brcm.h new file mode 100644 index 00000000000000..fdaee63bd1d23c --- /dev/null +++ b/net/bluetooth/brcm.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2026 The Asahi Linux Contributors + */ + +#if IS_ENABLED(CONFIG_BT_BRCMEXT) + +int brcm_set_high_priority(struct hci_dev *hdev, u16 handle, bool enable); + +#else + +static inline int brcm_set_high_priority(struct hci_dev *hdev, u16 handle, bool enable) +{ + return 0; +} + +#endif diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index 36e80fbfe358e0..d0b559463ebe49 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c @@ -35,6 +35,7 @@ #include #include +#include "brcm.h" #include "smp.h" #include "eir.h" @@ -3089,6 +3090,32 @@ int hci_conn_set_phy(struct hci_conn *conn, u32 phys) } } +int hci_conn_setsockopt(struct hci_conn *conn, struct sock *sk, int level, + int optname, sockptr_t optval, unsigned int optlen) { + int val; + bool old_high, new_high, changed; + + if (level != SOL_SOCKET) + return 0; + + if (optname != SO_PRIORITY) + return 0; + + if (optlen < sizeof(int)) + return -EINVAL; + + if (copy_from_sockptr(&val, optval, sizeof(val))) + return -EFAULT; + + old_high = sk->sk_priority >= TC_PRIO_INTERACTIVE; + new_high = val >= TC_PRIO_INTERACTIVE; + changed = old_high != new_high; + if (!changed) + return 0; + + return brcm_set_high_priority(conn->hdev, conn->handle, new_high); +} + static int abort_conn_sync(struct hci_dev *hdev, void *data) { struct hci_conn *conn = data; diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index c138aa4ae26690..fb197cafa0eaca 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c @@ -896,6 +896,16 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, BT_DBG("sk %p", sk); + if (level == SOL_SOCKET) { + conn = chan->conn; + if (conn) + err = hci_conn_setsockopt(conn->hcon, sock->sk, level, + optname, optval, optlen); + if (err) + return err; + return sock_setsockopt(sock, level, optname, optval, optlen); + } + if (level == SOL_L2CAP) return l2cap_sock_setsockopt_old(sock, optname, optval, optlen); @@ -1979,6 +1989,9 @@ static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, INIT_LIST_HEAD(&l2cap_pi(sk)->rx_busy); + if (sock) + set_bit(SOCK_CUSTOM_SOCKOPT, &sock->flags); + chan = l2cap_chan_create(); if (!chan) { sk_free(sk); From 4222e682e604d2e53628faf5272c7ed25565a65d Mon Sep 17 00:00:00 2001 From: Sasha Finkelstein Date: Thu, 21 May 2026 10:30:50 +0200 Subject: [PATCH 04/33] Fail the build on RUST=y and RUST_IS_AVAILABLE=n The current approach of silently disabling all rust drivers if the toolchain is missing results in users that try to compile their own kernels getting a "successful" build and then being confused about where did their drivers go. In comparison, missing openssl results in a build failure, not a disappearance of everything that depends on it. This also means that allyesconfig will depend on rust, but since the rust experiment concluded with "rust is here to stay", i believe that allyesconfig should be building rust drivers too. Signed-off-by: Sasha Finkelstein --- Documentation/rust/quick-start.rst | 6 +++--- init/Kconfig | 1 - 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/Documentation/rust/quick-start.rst b/Documentation/rust/quick-start.rst index 152289f0bed2fa..2b7e91bd9d3d36 100644 --- a/Documentation/rust/quick-start.rst +++ b/Documentation/rust/quick-start.rst @@ -324,9 +324,9 @@ Configuration ------------- ``Rust support`` (``CONFIG_RUST``) needs to be enabled in the ``General setup`` -menu. The option is only shown if a suitable Rust toolchain is found (see -above), as long as the other requirements are met. In turn, this will make -visible the rest of options that depend on Rust. +menu. In turn, this will make visible the rest of options that depend on Rust. +You can check the value of ``RUST_IS_AVAILABLE`` to determine if your toolchain +is configured correctly. Afterwards, go to:: diff --git a/init/Kconfig b/init/Kconfig index 7484cd703bc1ab..8ef220ca61bff8 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -2170,7 +2170,6 @@ config PROFILING config RUST bool "Rust support" depends on HAVE_RUST - depends on RUST_IS_AVAILABLE select EXTENDED_MODVERSIONS if MODVERSIONS depends on !MODVERSIONS || GENDWARFKSYMS depends on !GCC_PLUGIN_RANDSTRUCT From ad49e3a1ee0853bdf8ff71026e6ea848fd6c4270 Mon Sep 17 00:00:00 2001 From: Janne Grunau Date: Sat, 9 May 2026 11:58:52 +0200 Subject: [PATCH 05/33] driver-core: Add error message to device_links_missing_supplier WARN() Signed-off-by: Janne Grunau --- drivers/base/core.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/base/core.c b/drivers/base/core.c index a1a83b5626b886..d213908c34f726 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -1003,6 +1003,7 @@ static void device_links_missing_supplier(struct device *dev) if (link->supplier->links.status == DL_DEV_DRIVER_BOUND) { WRITE_ONCE(link->status, DL_STATE_AVAILABLE); } else { + dev_err(dev, "devices misses supplier %s\n", dev_name(link->supplier)); WARN_ON(!device_link_test(link, DL_FLAG_SYNC_STATE_ONLY)); WRITE_ONCE(link->status, DL_STATE_DORMANT); } From 83cd1b14072296f3b4328b27ba8a8ed430a63426 Mon Sep 17 00:00:00 2001 From: Janne Grunau Date: Sat, 30 May 2026 12:16:44 +0200 Subject: [PATCH 06/33] dt-bindings: gpio: apple,smc: Add compatible for 'gp00' keys Apple M3 Pro and Max devices are using 'gp00' keys for GPIO in addition to 'gP00' keys. Add a second compatible to handle this keys with an additional macsmc-gpio instance. Signed-off-by: Janne Grunau --- Documentation/devicetree/bindings/gpio/apple,smc-gpio.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/gpio/apple,smc-gpio.yaml b/Documentation/devicetree/bindings/gpio/apple,smc-gpio.yaml index 42b1bc0a10c97a..b4063a9dd1248c 100644 --- a/Documentation/devicetree/bindings/gpio/apple,smc-gpio.yaml +++ b/Documentation/devicetree/bindings/gpio/apple,smc-gpio.yaml @@ -14,7 +14,9 @@ description: properties: compatible: - const: apple,smc-gpio + enum: + - apple,smc-gpio + - apple,smc-low-gpio gpio-controller: true From 2aab90c60dedbae9e8024d64ec433fd12cf88906 Mon Sep 17 00:00:00 2001 From: Janne Grunau Date: Fri, 29 May 2026 20:54:16 +0200 Subject: [PATCH 07/33] gpio: gpio-macsmc: Support 'gp00' GPIO keys Add support for SMC GPIO keys with a lower letter 'p' via the "apple,smc-low-gpio" compatible. This adds support for a second macsmc-gpio controller using 'gp00' keys. These keys are used on Apple M3 Pro and Max MacBooks in the controller for keyboard and trackpad and for the built-in DisplayPort to HDMI converter. Signed-off-by: Janne Grunau --- drivers/gpio/gpio-macsmc.c | 45 +++++++++++++++++++++++++++++--------- 1 file changed, 35 insertions(+), 10 deletions(-) diff --git a/drivers/gpio/gpio-macsmc.c b/drivers/gpio/gpio-macsmc.c index b0952d066a9dd0..c3ca445a85ac9d 100644 --- a/drivers/gpio/gpio-macsmc.c +++ b/drivers/gpio/gpio-macsmc.c @@ -75,6 +75,7 @@ struct macsmc_gpio { struct gpio_chip gc; int first_index; + smc_key base_key; }; static int macsmc_gpio_nr(smc_key key) @@ -88,15 +89,15 @@ static int macsmc_gpio_nr(smc_key key) return low | (high << 4); } -static int macsmc_gpio_key(unsigned int offset) +static int macsmc_gpio_key(smc_key base_key, unsigned int offset) { - return _SMC_KEY("gP\0\0") | hex_asc_hi(offset) << 8 | hex_asc_lo(offset); + return base_key | hex_asc_hi(offset) << 8 | hex_asc_lo(offset); } static int macsmc_gpio_find_first_gpio_index(struct macsmc_gpio *smcgp) { struct apple_smc *smc = smcgp->smc; - smc_key key = macsmc_gpio_key(0); + smc_key key = macsmc_gpio_key(smcgp->base_key, 0); smc_key first_key, last_key; int start, count, ret; @@ -143,7 +144,7 @@ static int macsmc_gpio_find_first_gpio_index(struct macsmc_gpio *smcgp) static int macsmc_gpio_get_direction(struct gpio_chip *gc, unsigned int offset) { struct macsmc_gpio *smcgp = gpiochip_get_data(gc); - smc_key key = macsmc_gpio_key(offset); + smc_key key = macsmc_gpio_key(smcgp->base_key, offset); u32 val; int ret; @@ -163,7 +164,7 @@ static int macsmc_gpio_get_direction(struct gpio_chip *gc, unsigned int offset) static int macsmc_gpio_get(struct gpio_chip *gc, unsigned int offset) { struct macsmc_gpio *smcgp = gpiochip_get_data(gc); - smc_key key = macsmc_gpio_key(offset); + smc_key key = macsmc_gpio_key(smcgp->base_key, offset); u32 cmd, val; int ret; @@ -186,7 +187,7 @@ static int macsmc_gpio_get(struct gpio_chip *gc, unsigned int offset) static int macsmc_gpio_set(struct gpio_chip *gc, unsigned int offset, int value) { struct macsmc_gpio *smcgp = gpiochip_get_data(gc); - smc_key key = macsmc_gpio_key(offset); + smc_key key = macsmc_gpio_key(smcgp->base_key, offset); int ret; value |= CMD_OUTPUT; @@ -217,7 +218,7 @@ static int macsmc_gpio_init_valid_mask(struct gpio_chip *gc, if (ret < 0) return ret; - if (key > SMC_KEY(gPff)) + if (key > macsmc_gpio_key(smcgp->base_key, MAX_GPIO - 1)) break; gpio_nr = macsmc_gpio_nr(key); @@ -232,10 +233,15 @@ static int macsmc_gpio_init_valid_mask(struct gpio_chip *gc, return 0; } +struct macsmc_gpio_of_match_data { + smc_key base_key; +}; + static int macsmc_gpio_probe(struct platform_device *pdev) { struct macsmc_gpio *smcgp; struct apple_smc *smc = dev_get_drvdata(pdev->dev.parent); + const struct macsmc_gpio_of_match_data *data = of_device_get_match_data(&pdev->dev); smc_key key; int ret; @@ -245,6 +251,7 @@ static int macsmc_gpio_probe(struct platform_device *pdev) smcgp->dev = &pdev->dev; smcgp->smc = smc; + smcgp->base_key = data ? data->base_key : _SMC_KEY("gP\0\0"); smcgp->first_index = macsmc_gpio_find_first_gpio_index(smcgp); if (smcgp->first_index < 0) @@ -254,12 +261,15 @@ static int macsmc_gpio_probe(struct platform_device *pdev) if (ret < 0) return ret; - if (key > macsmc_gpio_key(MAX_GPIO - 1)) + if (key > macsmc_gpio_key(smcgp->base_key, MAX_GPIO - 1)) return -ENODEV; dev_info(smcgp->dev, "First GPIO key: %p4ch\n", &key); - smcgp->gc.label = "macsmc-pmu-gpio"; + if (device_is_compatible(&pdev->dev, "apple,smc-low-gpio")) + smcgp->gc.label = "macsmc-pmu-low-gpio"; + else + smcgp->gc.label = "macsmc-pmu-gpio"; smcgp->gc.owner = THIS_MODULE; smcgp->gc.get = macsmc_gpio_get; smcgp->gc.set = macsmc_gpio_set; @@ -273,8 +283,23 @@ static int macsmc_gpio_probe(struct platform_device *pdev) return devm_gpiochip_add_data(&pdev->dev, &smcgp->gc, smcgp); } +static const struct macsmc_gpio_of_match_data macsmc_gpio_up_data = { + .base_key = _SMC_KEY("gP\0\0"), +}; + +static const struct macsmc_gpio_of_match_data macsmc_gpio_low_data = { + .base_key = _SMC_KEY("gp\0\0"), +}; + static const struct of_device_id macsmc_gpio_of_table[] = { - { .compatible = "apple,smc-gpio", }, + { + .compatible = "apple,smc-gpio", + .data = &macsmc_gpio_up_data, + }, + { + .compatible = "apple,smc-low-gpio", + .data = &macsmc_gpio_low_data, + }, {} }; MODULE_DEVICE_TABLE(of, macsmc_gpio_of_table); From 8f8b535b47690c0043daa48adc374f08e7b7ee24 Mon Sep 17 00:00:00 2001 From: Janne Grunau Date: Sat, 30 May 2026 12:20:39 +0200 Subject: [PATCH 08/33] mfd: macsmc: Add second gpio subdevice for 'gp00' keys Apple M3 Pro and Max devices are using 'gp00' keys for GPIO in addition to 'gP00' keys. These keys are handled by an additional macsmc-gpio instance using the "apple,smc-low-gpio" compatible. Signed-off-by: Janne Grunau --- drivers/mfd/macsmc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/mfd/macsmc.c b/drivers/mfd/macsmc.c index 358feec2d088fc..fd34dae70452ae 100644 --- a/drivers/mfd/macsmc.c +++ b/drivers/mfd/macsmc.c @@ -48,6 +48,7 @@ static const struct mfd_cell apple_smc_devs[] = { MFD_CELL_NAME("macsmc-input"), MFD_CELL_NAME("macsmc-power"), MFD_CELL_OF("macsmc-gpio", NULL, NULL, 0, 0, "apple,smc-gpio"), + MFD_CELL_OF("macsmc-low-gpio", NULL, NULL, 0, 0, "apple,smc-low-gpio"), MFD_CELL_OF("macsmc-hwmon", NULL, NULL, 0, 0, "apple,smc-hwmon"), MFD_CELL_OF("macsmc-reboot", NULL, NULL, 0, 0, "apple,smc-reboot"), MFD_CELL_OF("macsmc-rtc", NULL, NULL, 0, 0, "apple,smc-rtc"), From 7d85d500f02647ba325fab3476dea1c5ef411cfb Mon Sep 17 00:00:00 2001 From: Janne Grunau Date: Fri, 3 Apr 2026 12:36:06 +0200 Subject: [PATCH 09/33] arm64: dts: apple: t8122: Add PCI power enable GPIOs - WLAN/BT (SMC PMU GPIO #13) (all devices) - ASM3142 (SMC PMU GPIO #14) (j434, iMac with 4 USB-C ports) - SD card reader (SMC PMU GPIO #23) (j504, 14-inch MacBook Pro) Signed-off-by: Janne Grunau --- arch/arm64/boot/dts/apple/t8122-j434.dts | 1 + arch/arm64/boot/dts/apple/t8122-j504.dts | 1 + arch/arm64/boot/dts/apple/t8122-jxxx.dtsi | 1 + 3 files changed, 3 insertions(+) diff --git a/arch/arm64/boot/dts/apple/t8122-j434.dts b/arch/arm64/boot/dts/apple/t8122-j434.dts index ecfd9e9b9ccfe1..32a9d7c3df8c90 100644 --- a/arch/arm64/boot/dts/apple/t8122-j434.dts +++ b/arch/arm64/boot/dts/apple/t8122-j434.dts @@ -38,6 +38,7 @@ &port02 { bus-range = <3 3>; + pwren-gpios = <&smc_gpio 14 GPIO_ACTIVE_HIGH>; status = "okay"; }; diff --git a/arch/arm64/boot/dts/apple/t8122-j504.dts b/arch/arm64/boot/dts/apple/t8122-j504.dts index d83b7e5b32e682..d285ae37f30af8 100644 --- a/arch/arm64/boot/dts/apple/t8122-j504.dts +++ b/arch/arm64/boot/dts/apple/t8122-j504.dts @@ -42,6 +42,7 @@ &port01 { /* SD card reader */ bus-range = <2 2>; + pwren-gpios = <&smc_gpio 23 GPIO_ACTIVE_HIGH>; status = "okay"; sdhci0: mmc@0,0 { diff --git a/arch/arm64/boot/dts/apple/t8122-jxxx.dtsi b/arch/arm64/boot/dts/apple/t8122-jxxx.dtsi index 786adeeb7620c9..064b72f2075ec8 100644 --- a/arch/arm64/boot/dts/apple/t8122-jxxx.dtsi +++ b/arch/arm64/boot/dts/apple/t8122-jxxx.dtsi @@ -56,6 +56,7 @@ */ &port00 { bus-range = <1 1>; + pwren-gpios = <&smc_gpio 13 GPIO_ACTIVE_HIGH>; wifi0: wifi@0,0 { compatible = "pci14e4,4434"; From 6c9fc7d7336296bfda9b201a01217582d85486c4 Mon Sep 17 00:00:00 2001 From: Yureka Date: Sat, 30 May 2026 14:31:07 +0200 Subject: [PATCH 10/33] arm64: dts: t603x-j514-j516: Add PCI power enable GPIOs Signed-off-by: Yureka --- arch/arm64/boot/dts/apple/t603x-j514-j516.dtsi | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm64/boot/dts/apple/t603x-j514-j516.dtsi b/arch/arm64/boot/dts/apple/t603x-j514-j516.dtsi index b8919946dc1579..f29d00b091c05c 100644 --- a/arch/arm64/boot/dts/apple/t603x-j514-j516.dtsi +++ b/arch/arm64/boot/dts/apple/t603x-j514-j516.dtsi @@ -82,6 +82,7 @@ &port00 { /* WLAN */ bus-range = <1 1>; + pwren-gpios = <&smc_gpio 19 GPIO_ACTIVE_HIGH>; wifi0: wifi@0,0 { compatible = "pci14e4,4433"; reg = <0x10000 0x0 0x0 0x0 0x0>; @@ -101,6 +102,7 @@ &port01 { /* SD card reader */ bus-range = <2 2>; + pwren-gpios = <&smc_gpio 25 GPIO_ACTIVE_HIGH>; status = "okay"; sdhci0: mmc@0,0 { compatible = "pci17a0,9755"; From c9d1b5d33c5a62fab28f07b2a872584e42ff05ff Mon Sep 17 00:00:00 2001 From: Michael Reeves Date: Fri, 30 Jan 2026 21:43:14 +1100 Subject: [PATCH 11/33] arm64: dts: apple: Add MTP DockChannel to M3 device tree The internal keyboard and trackpad HID on MacBook variants of the Apple M3 (t8122) SoC are connected through a Apple -developed protocol called DockChannel and mediated by a coprocessor known as the Multi-Touch Processor (MTP). This commit adds the nessecary device tree nodes to the M3's device tree for internal HID to work. It is disabled by default, to be enabled only in MacBook board files where it is tested and confirmed to work. Co-developed-by: Alyssa Milburn Signed-off-by: Alyssa Milburn Signed-off-by: Michael Reeves --- arch/arm64/boot/dts/apple/t8122.dtsi | 77 ++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) diff --git a/arch/arm64/boot/dts/apple/t8122.dtsi b/arch/arm64/boot/dts/apple/t8122.dtsi index 4ac9eb045f68b4..1115ff080b3eb9 100644 --- a/arch/arm64/boot/dts/apple/t8122.dtsi +++ b/arch/arm64/boot/dts/apple/t8122.dtsi @@ -826,6 +826,83 @@ ; }; + mtp: mtp@2fa400000 { + compatible = "apple,t8122-mtp", "apple,t8122-rtk-helper-asc4", "apple,mtp", "apple,rtk-helper-asc4"; + reg = <0x2 0xfa400000 0x0 0x4000>, + <0x2 0xfac00000 0x0 0x100000>; + reg-names = "asc", "sram"; + + mboxes = <&mtp_mbox>; + iommus = <&mtp_dart 1>; + #helper-cells = <0>; + + status = "disabled"; + }; + + mtp_mbox: mbox@2fa408000 { + compatible = "apple,t8122-asc-mailbox", "apple,asc-mailbox-v4"; + reg = <0x2 0xfa408000 0x0 0x4000>; + + interrupt-parent = <&aic>; + interrupts = , + , + , + ; + interrupt-names = "send-empty", "send-not-empty", + "recv-empty", "recv-not-empty"; + #mbox-cells = <0>; + status = "disabled"; + }; + + mtp_dart: iommu@2fa808000 { + compatible = "apple,t8122-dart", "apple,t8110-dart"; + reg = <0x2 0xfa808000 0x0 0x4000>; + + interrupt-parent = <&aic>; + interrupts = ; + + #iommu-cells = <1>; + + status = "disabled"; + }; + + mtp_dockchannel: fifo@2fab30000 { + compatible = "apple,t8122-dockchannel", "apple,dockchannel"; + reg = <0x2 0xfab14000 0x0 0x4000>; + reg-names = "irq"; + interrupt-parent = <&aic>; + interrupts = ; + + ranges = <0 0x2 0xfab28000 0x20000>; + nonposted-mmio; + #address-cells = <1>; + #size-cells = <1>; + + interrupt-controller; + #interrupt-cells = <2>; + + status = "disabled"; + + mtp_hid: input@0 { + compatible = "apple,dockchannel-hid"; + reg = <0x0000 0x1000>, + <0x4000 0x1000>, + <0x8000 0x1000>, + <0xc000 0x1000>; + reg-names = "rmt-config", "rmt-data", "config", "data"; + + iommus = <&mtp_dart 1>; + + interrupt-parent = <&mtp_dockchannel>; + interrupts = <2 IRQ_TYPE_LEVEL_HIGH>, + <3 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "tx", "rx"; + + apple,fifo-size = <0x800>; + apple,helper-cpu = <&mtp>; + }; + }; + ans_mbox: mbox@309408000 { compatible = "apple,t8122-asc-mailbox", "apple,asc-mailbox-v4"; reg = <0x3 0x09408000 0x0 0x4000>; From 3e82863eccd27e3da7c891e7fcb96dd003a79897 Mon Sep 17 00:00:00 2001 From: Michael Reeves Date: Fri, 30 Jan 2026 22:06:07 +1100 Subject: [PATCH 12/33] arm64: dts: apple: t8122: Add MTP device nodes to Macbook board files Add mtp device nodes for t8122 (M3) based MacBooks. Signed-off-by: Michael Reeves --- arch/arm64/boot/dts/apple/t8122-j504.dts | 39 ++++++++++++++++++++++++ arch/arm64/boot/dts/apple/t8122-j613.dts | 39 ++++++++++++++++++++++++ arch/arm64/boot/dts/apple/t8122-j615.dts | 39 ++++++++++++++++++++++++ 3 files changed, 117 insertions(+) diff --git a/arch/arm64/boot/dts/apple/t8122-j504.dts b/arch/arm64/boot/dts/apple/t8122-j504.dts index d285ae37f30af8..54950a66f89e9e 100644 --- a/arch/arm64/boot/dts/apple/t8122-j504.dts +++ b/arch/arm64/boot/dts/apple/t8122-j504.dts @@ -62,5 +62,44 @@ status = "okay"; }; +&mtp { + status = "okay"; +}; + +&mtp_mbox { + status = "okay"; +}; + +&mtp_dart { + status = "okay"; +}; + +&mtp_dockchannel { + status = "okay"; +}; + +&mtp_hid { + apple,afe-reset-gpios = <&smc_gpio 8 GPIO_ACTIVE_LOW>; + apple,stm-reset-gpios = <&smc_gpio 24 GPIO_ACTIVE_LOW>; + + multi-touch { + firmware-name = "apple/tpmtfw-j504.bin"; + }; + + keyboard: keyboard { + hid-country-code = <0>; + apple,keyboard-layout-id = <0>; + }; + + stm { + }; + + actuator { + }; + + tp_accel { + }; +}; + #include "hwmon-fan-dual.dtsi" #include "hwmon-laptop.dtsi" diff --git a/arch/arm64/boot/dts/apple/t8122-j613.dts b/arch/arm64/boot/dts/apple/t8122-j613.dts index 222fa847724981..7f5e0be62da267 100644 --- a/arch/arm64/boot/dts/apple/t8122-j613.dts +++ b/arch/arm64/boot/dts/apple/t8122-j613.dts @@ -42,4 +42,43 @@ status = "okay"; }; +&mtp { + status = "okay"; +}; + +&mtp_mbox { + status = "okay"; +}; + +&mtp_dart { + status = "okay"; +}; + +&mtp_dockchannel { + status = "okay"; +}; + +&mtp_hid { + apple,afe-reset-gpios = <&smc_gpio 8 GPIO_ACTIVE_LOW>; + apple,stm-reset-gpios = <&smc_gpio 24 GPIO_ACTIVE_LOW>; + + multi-touch { + firmware-name = "apple/tpmtfw-j613.bin"; + }; + + keyboard: keyboard { + hid-country-code = <0>; + apple,keyboard-layout-id = <0>; + }; + + stm { + }; + + actuator { + }; + + tp_accel { + }; +}; + #include "hwmon-laptop.dtsi" diff --git a/arch/arm64/boot/dts/apple/t8122-j615.dts b/arch/arm64/boot/dts/apple/t8122-j615.dts index 3366d92c0228b9..13e1a3158c2cad 100644 --- a/arch/arm64/boot/dts/apple/t8122-j615.dts +++ b/arch/arm64/boot/dts/apple/t8122-j615.dts @@ -42,4 +42,43 @@ status = "okay"; }; +&mtp { + status = "okay"; +}; + +&mtp_mbox { + status = "okay"; +}; + +&mtp_dart { + status = "okay"; +}; + +&mtp_dockchannel { + status = "okay"; +}; + +&mtp_hid { + apple,afe-reset-gpios = <&smc_gpio 8 GPIO_ACTIVE_LOW>; + apple,stm-reset-gpios = <&smc_gpio 24 GPIO_ACTIVE_LOW>; + + multi-touch { + firmware-name = "apple/tpmtfw-j615.bin"; + }; + + keyboard: keyboard { + hid-country-code = <0>; + apple,keyboard-layout-id = <0>; + }; + + stm { + }; + + actuator { + }; + + tp_accel { + }; +}; + #include "hwmon-laptop.dtsi" From a1fb974ab395d1970c6f9aca68793b74e39a4fab Mon Sep 17 00:00:00 2001 From: Janne Grunau Date: Thu, 21 May 2026 23:31:32 +0200 Subject: [PATCH 13/33] arm64: dts: apple: t6030: Add MTP device nodes Signed-off-by: Janne Grunau --- arch/arm64/boot/dts/apple/t6030.dtsi | 77 ++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) diff --git a/arch/arm64/boot/dts/apple/t6030.dtsi b/arch/arm64/boot/dts/apple/t6030.dtsi index 7f3f401bbfe438..6918f022faab8a 100644 --- a/arch/arm64/boot/dts/apple/t6030.dtsi +++ b/arch/arm64/boot/dts/apple/t6030.dtsi @@ -930,6 +930,83 @@ #interrupt-cells = <2>; }; + mtp: mtp@37a400000 { + compatible = "apple,t6030-mtp", "apple,t6030-rtk-helper-asc4", "apple,mtp", "apple,rtk-helper-asc4"; + reg = <0x3 0x7a400000 0x0 0x4000>, + <0x3 0x7ac00000 0x0 0x100000>; + reg-names = "asc", "sram"; + + mboxes = <&mtp_mbox>; + iommus = <&mtp_dart 1>; + #helper-cells = <0>; + + status = "disabled"; + }; + + mtp_mbox: mbox@37a408000 { + compatible = "apple,t6030-asc-mailbox", "apple,asc-mailbox-v4"; + reg = <0x3 0x7a408000 0x0 0x4000>; + + interrupt-parent = <&aic>; + interrupts = , + , + , + ; + interrupt-names = "send-empty", "send-not-empty", + "recv-empty", "recv-not-empty"; + #mbox-cells = <0>; + status = "disabled"; + }; + + mtp_dart: iommu@37a808000 { + compatible = "apple,t6030-dart", "apple,t8110-dart"; + reg = <0x3 0x7a808000 0x0 0x4000>; + + interrupt-parent = <&aic>; + interrupts = ; + + #iommu-cells = <1>; + + status = "disabled"; + }; + + mtp_dockchannel: fifo@37ab30000 { + compatible = "apple,t6030-dockchannel", "apple,dockchannel"; + reg = <0x3 0x7ab14000 0x0 0x4000>; + reg-names = "irq"; + interrupt-parent = <&aic>; + interrupts = ; + + ranges = <0 0x3 0x7ab28000 0x20000>; + nonposted-mmio; + #address-cells = <1>; + #size-cells = <1>; + + interrupt-controller; + #interrupt-cells = <2>; + + status = "disabled"; + + mtp_hid: input@0 { + compatible = "apple,dockchannel-hid"; + reg = <0x0000 0x4000>, + <0x4000 0x4000>, + <0x8000 0x4000>, + <0xc000 0x4000>; + reg-names = "rmt-config", "rmt-data", "config", "data"; + + iommus = <&mtp_dart 1>; + + interrupt-parent = <&mtp_dockchannel>; + interrupts = <2 IRQ_TYPE_LEVEL_HIGH>, + <3 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "tx", "rx"; + + apple,fifo-size = <0x800>; + apple,helper-cpu = <&mtp>; + }; + }; + ans_mbox: mbox@389408000 { compatible = "apple,t6030-asc-mailbox", "apple,asc-mailbox-v4"; reg = <0x3 0x89408000 0x0 0x4000>; From c6b8915bafac6ddd48794b841a2d19a4db869626 Mon Sep 17 00:00:00 2001 From: Janne Grunau Date: Thu, 21 May 2026 23:32:52 +0200 Subject: [PATCH 14/33] arm64: dts: apple: t6031: Add MTP device nodes Signed-off-by: Janne Grunau --- arch/arm64/boot/dts/apple/t6031-die0.dtsi | 77 +++++++++++++++++++++++ 1 file changed, 77 insertions(+) diff --git a/arch/arm64/boot/dts/apple/t6031-die0.dtsi b/arch/arm64/boot/dts/apple/t6031-die0.dtsi index 5f81a1900c8fd7..e0d1c50c23d2ea 100644 --- a/arch/arm64/boot/dts/apple/t6031-die0.dtsi +++ b/arch/arm64/boot/dts/apple/t6031-die0.dtsi @@ -161,6 +161,83 @@ ; }; + mtp: mtp@2ac400000 { + compatible = "apple,t6031-mtp", "apple,t8122-rtk-helper-asc4", "apple,mtp", "apple,rtk-helper-asc4"; + reg = <0x2 0xac400000 0x0 0x4000>, + <0x2 0xacc00000 0x0 0x100000>; + reg-names = "asc", "sram"; + + mboxes = <&mtp_mbox>; + iommus = <&mtp_dart 1>; + #helper-cells = <0>; + + status = "disabled"; + }; + + mtp_mbox: mbox@2ac408000 { + compatible = "apple,t6031-asc-mailbox", "apple,asc-mailbox-v4"; + reg = <0x2 0xac408000 0x0 0x4000>; + + interrupt-parent = <&aic>; + interrupts = , + , + , + ; + interrupt-names = "send-empty", "send-not-empty", + "recv-empty", "recv-not-empty"; + #mbox-cells = <0>; + status = "disabled"; + }; + + mtp_dart: iommu@2ac808000 { + compatible = "apple,t6031-dart", "apple,t8110-dart"; + reg = <0x2 0xac808000 0x0 0x4000>; + + interrupt-parent = <&aic>; + interrupts = ; + + #iommu-cells = <1>; + + status = "disabled"; + }; + + mtp_dockchannel: fifo@2acb14000 { + compatible = "apple,t6031-dockchannel", "apple,dockchannel"; + reg = <0x2 0xacb14000 0x0 0x4000>; + reg-names = "irq"; + interrupt-parent = <&aic>; + interrupts = ; + + ranges = <0 0x2 0xacb28000 0x20000>; + nonposted-mmio; + #address-cells = <1>; + #size-cells = <1>; + + interrupt-controller; + #interrupt-cells = <2>; + + status = "disabled"; + + mtp_hid: input@0 { + compatible = "apple,dockchannel-hid"; + reg = <0x0000 0x4000>, + <0x4000 0x4000>, + <0x8000 0x4000>, + <0xc000 0x4000>; + reg-names = "rmt-config", "rmt-data", "config", "data"; + + iommus = <&mtp_dart 1>; + + interrupt-parent = <&mtp_dockchannel>; + interrupts = <2 IRQ_TYPE_LEVEL_HIGH>, + <3 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "tx", "rx"; + + apple,fifo-size = <0x800>; + apple,helper-cpu = <&mtp>; + }; + }; + i2c0: i2c@391010000 { compatible = "apple,t6031-i2c", "apple,t8103-i2c"; reg = <0x3 0x91010000 0x0 0x4000>; From 7a32fe9634136354fdcca9153f9d8d3abc45a738 Mon Sep 17 00:00:00 2001 From: Janne Grunau Date: Thu, 21 May 2026 23:33:18 +0200 Subject: [PATCH 15/33] arm64: dts: apple: t603x-g514-j516: Active MTP based input List trackpad firmware files and activate MTP devices nodes on all t6030, t6031 and t6034 based MacBooks. Signed-off-by: Janne Grunau --- arch/arm64/boot/dts/apple/t6030-j514s.dts | 4 ++ arch/arm64/boot/dts/apple/t6030-j516s.dts | 4 ++ arch/arm64/boot/dts/apple/t6031-j514c.dts | 4 ++ arch/arm64/boot/dts/apple/t6031-j516c.dts | 4 ++ arch/arm64/boot/dts/apple/t6034-j514m.dts | 4 ++ arch/arm64/boot/dts/apple/t6034-j516m.dts | 4 ++ .../arm64/boot/dts/apple/t603x-j514-j516.dtsi | 38 +++++++++++++++++++ 7 files changed, 62 insertions(+) diff --git a/arch/arm64/boot/dts/apple/t6030-j514s.dts b/arch/arm64/boot/dts/apple/t6030-j514s.dts index 1a77d748e3f3f3..a1e34dbb512dac 100644 --- a/arch/arm64/boot/dts/apple/t6030-j514s.dts +++ b/arch/arm64/boot/dts/apple/t6030-j514s.dts @@ -17,6 +17,10 @@ model = "Apple MacBook Pro (14-inch, M3 Pro, Nov 2023)"; }; +&mtp_mt { + firmware-name = "apple/tpmtfw-j514s.bin"; +}; + &wifi0 { brcm,board-type = "apple,texa"; }; diff --git a/arch/arm64/boot/dts/apple/t6030-j516s.dts b/arch/arm64/boot/dts/apple/t6030-j516s.dts index 0c08e6ba8edb6d..cb4023c39f5379 100644 --- a/arch/arm64/boot/dts/apple/t6030-j516s.dts +++ b/arch/arm64/boot/dts/apple/t6030-j516s.dts @@ -17,6 +17,10 @@ model = "Apple MacBook Pro (16-inch, M3 Pro, Nov 2023)"; }; +&mtp_mt { + firmware-name = "apple/tpmtfw-j516s.bin"; +}; + &wifi0 { brcm,board-type = "apple,jura"; }; diff --git a/arch/arm64/boot/dts/apple/t6031-j514c.dts b/arch/arm64/boot/dts/apple/t6031-j514c.dts index 8cc2224ee0fd6a..ad9250eac9ad86 100644 --- a/arch/arm64/boot/dts/apple/t6031-j514c.dts +++ b/arch/arm64/boot/dts/apple/t6031-j514c.dts @@ -17,6 +17,10 @@ model = "Apple MacBook Pro (14-inch, M3 Max, 16 CPU cores, Nov 2023)"; }; +&mtp_mt { + firmware-name = "apple/tpmtfw-j514c.bin"; +}; + &wifi0 { brcm,board-type = "apple,texa"; }; diff --git a/arch/arm64/boot/dts/apple/t6031-j516c.dts b/arch/arm64/boot/dts/apple/t6031-j516c.dts index 5dfe886d47a9c5..23d928a61f345c 100644 --- a/arch/arm64/boot/dts/apple/t6031-j516c.dts +++ b/arch/arm64/boot/dts/apple/t6031-j516c.dts @@ -17,6 +17,10 @@ model = "Apple MacBook Pro (16-inch, M3 Max, 16 CPU cores, Nov 2023)"; }; +&mtp_mt { + firmware-name = "apple/tpmtfw-j516c.bin"; +}; + &wifi0 { brcm,board-type = "apple,jura"; }; diff --git a/arch/arm64/boot/dts/apple/t6034-j514m.dts b/arch/arm64/boot/dts/apple/t6034-j514m.dts index 82c23284d729b3..8f288af439fba2 100644 --- a/arch/arm64/boot/dts/apple/t6034-j514m.dts +++ b/arch/arm64/boot/dts/apple/t6034-j514m.dts @@ -17,6 +17,10 @@ model = "Apple MacBook Pro (14-inch, M3 Max, 14 CPU cores, Nov 2023)"; }; +&mtp_mt { + firmware-name = "apple/tpmtfw-j514m.bin"; +}; + &wifi0 { brcm,board-type = "apple,texa"; }; diff --git a/arch/arm64/boot/dts/apple/t6034-j516m.dts b/arch/arm64/boot/dts/apple/t6034-j516m.dts index faffdc8c9aff1e..dd363738db97f2 100644 --- a/arch/arm64/boot/dts/apple/t6034-j516m.dts +++ b/arch/arm64/boot/dts/apple/t6034-j516m.dts @@ -17,6 +17,10 @@ model = "Apple MacBook Pro (16-inch, M3 Max, 14 CPU cores, Nov 2023)"; }; +&mtp_mt { + firmware-name = "apple/tpmtfw-j516m.bin"; +}; + &wifi0 { brcm,board-type = "apple,jura"; }; diff --git a/arch/arm64/boot/dts/apple/t603x-j514-j516.dtsi b/arch/arm64/boot/dts/apple/t603x-j514-j516.dtsi index f29d00b091c05c..23bbaf4294bbbd 100644 --- a/arch/arm64/boot/dts/apple/t603x-j514-j516.dtsi +++ b/arch/arm64/boot/dts/apple/t603x-j514-j516.dtsi @@ -72,6 +72,44 @@ clock-frequency = <900000000>; }; +&mtp { + status = "okay"; +}; + +&mtp_mbox { + status = "okay"; +}; + +&mtp_dart { + status = "okay"; +}; + +&mtp_dockchannel { + status = "okay"; +}; + +&mtp_hid { + apple,afe-reset-gpios = <&smc_gpio_low 25 GPIO_ACTIVE_LOW>; + apple,stm-reset-gpios = <&smc_gpio_low 26 GPIO_ACTIVE_LOW>; + + mtp_mt: multi-touch { + }; + + keyboard: keyboard { + hid-country-code = <0>; + apple,keyboard-layout-id = <0>; + }; + + stm { + }; + + actuator { + }; + + tp_accel { + }; +}; + /* PCIe devices */ /* From 16696083e89257ef35f81915cb3abe89b9faeda2 Mon Sep 17 00:00:00 2001 From: Sasha Finkelstein Date: Thu, 4 Jun 2026 15:08:51 +0200 Subject: [PATCH 16/33] dts: apple: t[603x,8122]: Add speaker/jack nodes Signed-off-by: Sasha Finkelstein --- arch/arm64/boot/dts/apple/t6030-j514s.dts | 5 + arch/arm64/boot/dts/apple/t6030-j516s.dts | 5 + arch/arm64/boot/dts/apple/t6031-j514c.dts | 5 + arch/arm64/boot/dts/apple/t6031-j516c.dts | 5 + arch/arm64/boot/dts/apple/t6032-j575d.dts | 56 +++++++ arch/arm64/boot/dts/apple/t6034-j514m.dts | 5 + arch/arm64/boot/dts/apple/t6034-j516m.dts | 5 + .../arm64/boot/dts/apple/t603x-j514-j516.dtsi | 141 +++++++++++++++++- arch/arm64/boot/dts/apple/t8122-j433.dts | 31 ++++ arch/arm64/boot/dts/apple/t8122-j434.dts | 31 ++++ arch/arm64/boot/dts/apple/t8122-j504.dts | 129 ++++++++++++++++ arch/arm64/boot/dts/apple/t8122-j613.dts | 100 +++++++++++++ arch/arm64/boot/dts/apple/t8122-j615.dts | 100 +++++++++++++ arch/arm64/boot/dts/apple/t8122-jxxx.dtsi | 12 ++ 14 files changed, 626 insertions(+), 4 deletions(-) diff --git a/arch/arm64/boot/dts/apple/t6030-j514s.dts b/arch/arm64/boot/dts/apple/t6030-j514s.dts index a1e34dbb512dac..987bd419afe6fe 100644 --- a/arch/arm64/boot/dts/apple/t6030-j514s.dts +++ b/arch/arm64/boot/dts/apple/t6030-j514s.dts @@ -28,3 +28,8 @@ &bluetooth0 { brcm,board-type = "apple,texa"; }; + +&sound { + compatible = "apple,j514-macaudio", "apple,j314-macaudio", "apple,macaudio"; + model = "MacBook Pro J514"; +}; diff --git a/arch/arm64/boot/dts/apple/t6030-j516s.dts b/arch/arm64/boot/dts/apple/t6030-j516s.dts index cb4023c39f5379..673a4bbf5f4fac 100644 --- a/arch/arm64/boot/dts/apple/t6030-j516s.dts +++ b/arch/arm64/boot/dts/apple/t6030-j516s.dts @@ -28,3 +28,8 @@ &bluetooth0 { brcm,board-type = "apple,jura"; }; + +&sound { + compatible = "apple,j516-macaudio", "apple,j316-macaudio", "apple,macaudio"; + model = "MacBook Pro J516"; +}; diff --git a/arch/arm64/boot/dts/apple/t6031-j514c.dts b/arch/arm64/boot/dts/apple/t6031-j514c.dts index ad9250eac9ad86..1bfb9f2c63923a 100644 --- a/arch/arm64/boot/dts/apple/t6031-j514c.dts +++ b/arch/arm64/boot/dts/apple/t6031-j514c.dts @@ -28,3 +28,8 @@ &bluetooth0 { brcm,board-type = "apple,texa"; }; + +&sound { + compatible = "apple,j514-macaudio", "apple,j314-macaudio", "apple,macaudio"; + model = "MacBook Pro J514"; +}; diff --git a/arch/arm64/boot/dts/apple/t6031-j516c.dts b/arch/arm64/boot/dts/apple/t6031-j516c.dts index 23d928a61f345c..a199b0b11814f2 100644 --- a/arch/arm64/boot/dts/apple/t6031-j516c.dts +++ b/arch/arm64/boot/dts/apple/t6031-j516c.dts @@ -28,3 +28,8 @@ &bluetooth0 { brcm,board-type = "apple,jura"; }; + +&sound { + compatible = "apple,j516-macaudio", "apple,j316-macaudio", "apple,macaudio"; + model = "MacBook Pro J516"; +}; diff --git a/arch/arm64/boot/dts/apple/t6032-j575d.dts b/arch/arm64/boot/dts/apple/t6032-j575d.dts index 9448c7a84b6ad8..1bf14006807e8f 100644 --- a/arch/arm64/boot/dts/apple/t6032-j575d.dts +++ b/arch/arm64/boot/dts/apple/t6032-j575d.dts @@ -45,11 +45,67 @@ status = "okay"; }; +/* Audio */ +&i2c1 { + status = "okay"; + + speaker: codec@38 { + compatible = "ti,sn012776", "ti,tas2764"; + reg = <0x38>; + shutdown-gpios = <&pinctrl_ap 28 GPIO_ACTIVE_HIGH>; + #sound-dai-cells = <0>; + interrupts-extended = <&pinctrl_ap 29 IRQ_TYPE_LEVEL_LOW>; + ti,imon-slot-no = <0>; + ti,vmon-slot-no = <2>; + }; +}; + +&i2c2 { + status = "okay"; + + jack_codec: codec@4b { + compatible = "cirrus,cs42l84"; + reg = <0x4b>; + reset-gpios = <&pinctrl_nub 58 GPIO_ACTIVE_HIGH>; + #sound-dai-cells = <0>; + interrupts-extended = <&pinctrl_ap 30 IRQ_TYPE_LEVEL_LOW>; + sound-name-prefix = "Jack"; + }; +}; &nco_clkref { clock-frequency = <900000000>; }; +/ { + sound: sound { + compatible = "apple,j575-macaudio", "apple,j375-macaudio", "apple,macaudio"; + model = "Mac Studio J575"; + + dai-link@0 { + link-name = "Speaker"; + + cpu { + sound-dai = <&mca 0>; + }; + codec { + sound-dai = <&speaker>; + }; + }; + + dai-link@1 { + link-name = "Headphone Jack"; + + cpu { + sound-dai = <&mca 2>; + }; + codec { + sound-dai = <&jack_codec>; + }; + }; + }; +}; + #include "spi1-nvram.dtsi" #include "hwmon-common.dtsi" #include "hwmon-fan-dual.dtsi" diff --git a/arch/arm64/boot/dts/apple/t6034-j514m.dts b/arch/arm64/boot/dts/apple/t6034-j514m.dts index 8f288af439fba2..a0625efda68529 100644 --- a/arch/arm64/boot/dts/apple/t6034-j514m.dts +++ b/arch/arm64/boot/dts/apple/t6034-j514m.dts @@ -28,3 +28,8 @@ &bluetooth0 { brcm,board-type = "apple,texa"; }; + +&sound { + compatible = "apple,j514-macaudio", "apple,j314-macaudio", "apple,macaudio"; + model = "MacBook Pro J514"; +}; diff --git a/arch/arm64/boot/dts/apple/t6034-j516m.dts b/arch/arm64/boot/dts/apple/t6034-j516m.dts index dd363738db97f2..6ce5fddf8255fa 100644 --- a/arch/arm64/boot/dts/apple/t6034-j516m.dts +++ b/arch/arm64/boot/dts/apple/t6034-j516m.dts @@ -28,3 +28,8 @@ &bluetooth0 { brcm,board-type = "apple,jura"; }; + +&sound { + compatible = "apple,j516-macaudio", "apple,j316-macaudio", "apple,macaudio"; + model = "MacBook Pro J516"; +}; diff --git a/arch/arm64/boot/dts/apple/t603x-j514-j516.dtsi b/arch/arm64/boot/dts/apple/t603x-j514-j516.dtsi index 23bbaf4294bbbd..d1bd37d9fe5aea 100644 --- a/arch/arm64/boot/dts/apple/t603x-j514-j516.dtsi +++ b/arch/arm64/boot/dts/apple/t603x-j514-j516.dtsi @@ -68,10 +68,6 @@ status = "okay"; }; -&nco_clkref { - clock-frequency = <900000000>; -}; - &mtp { status = "okay"; }; @@ -110,6 +106,110 @@ }; }; +/ { + speaker_sdz: fixed-regulator-sn012776-sdz { + compatible = "regulator-fixed"; + regulator-name = "sn012776-sdz"; + startup-delay-us = <5000>; + gpios = <&pinctrl_ap 28 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; +}; + +&i2c1 { + status = "okay"; + + speaker_left_tweet: codec@3a { + compatible = "ti,sn012776", "ti,tas2764"; + reg = <0x3a>; + SDZ-supply = <&speaker_sdz>; + #sound-dai-cells = <0>; + sound-name-prefix = "Left Tweeter"; + interrupts-extended = <&pinctrl_ap 29 IRQ_TYPE_LEVEL_LOW>; + ti,imon-slot-no = <8>; + ti,vmon-slot-no = <10>; + }; + + speaker_left_woof1: codec@38 { + compatible = "ti,sn012776", "ti,tas2764"; + reg = <0x38>; + SDZ-supply = <&speaker_sdz>; + #sound-dai-cells = <0>; + sound-name-prefix = "Left Woofer 1"; + interrupts-extended = <&pinctrl_ap 29 IRQ_TYPE_LEVEL_LOW>; + ti,imon-slot-no = <0>; + ti,vmon-slot-no = <2>; + ti,sdout-force-zero-mask = <0xf0f0f0>; + }; + + speaker_left_woof2: codec@39 { + compatible = "ti,sn012776", "ti,tas2764"; + reg = <0x39>; + SDZ-supply = <&speaker_sdz>; + #sound-dai-cells = <0>; + sound-name-prefix = "Left Woofer 2"; + interrupts-extended = <&pinctrl_ap 29 IRQ_TYPE_LEVEL_LOW>; + ti,imon-slot-no = <16>; + ti,vmon-slot-no = <18>; + }; +}; + +&i2c2 { + status = "okay"; + + jack_codec: codec@4b { + compatible = "cirrus,cs42l84"; + reg = <0x4b>; + reset-gpios = <&pinctrl_nub 58 GPIO_ACTIVE_HIGH>; + #sound-dai-cells = <0>; + interrupts-extended = <&pinctrl_ap 30 IRQ_TYPE_LEVEL_LOW>; + sound-name-prefix = "Jack"; + }; +}; + +&i2c3 { + status = "okay"; + + speaker_right_tweet: codec@3d { + compatible = "ti,sn012776", "ti,tas2764"; + reg = <0x3d>; + SDZ-supply = <&speaker_sdz>; + #sound-dai-cells = <0>; + sound-name-prefix = "Right Tweeter"; + interrupts-extended = <&pinctrl_ap 29 IRQ_TYPE_LEVEL_LOW>; + ti,imon-slot-no = <12>; + ti,vmon-slot-no = <14>; + }; + + speaker_right_woof1: codec@3b { + compatible = "ti,sn012776", "ti,tas2764"; + reg = <0x3b>; + SDZ-supply = <&speaker_sdz>; + #sound-dai-cells = <0>; + sound-name-prefix = "Right Woofer 1"; + interrupts-extended = <&pinctrl_ap 29 IRQ_TYPE_LEVEL_LOW>; + ti,imon-slot-no = <4>; + ti,vmon-slot-no = <6>; + ti,sdout-force-zero-mask = <0x0f0f0f>; + }; + + speaker_right_woof2: codec@3c { + compatible = "ti,sn012776", "ti,tas2764"; + reg = <0x3c>; + SDZ-supply = <&speaker_sdz>; + #sound-dai-cells = <0>; + sound-name-prefix = "Right Woofer 2"; + interrupts-extended = <&pinctrl_ap 29 IRQ_TYPE_LEVEL_LOW>; + ti,imon-slot-no = <20>; + ti,vmon-slot-no = <22>; + }; +}; + +&nco_clkref { + clock-frequency = <900000000>; +}; + + /* PCIe devices */ /* @@ -154,6 +254,39 @@ status = "okay"; }; +/ { + sound: sound { + /* compatible is set per machine */ + + dai-link@0 { + link-name = "Speakers"; + + cpu { + sound-dai = <&mca 0>, <&mca 1>; + }; + codec { + sound-dai = <&speaker_left_woof1>, + <&speaker_left_tweet>, + <&speaker_left_woof2>, + <&speaker_right_woof1>, + <&speaker_right_tweet>, + <&speaker_right_woof2>; + }; + }; + + dai-link@1 { + link-name = "Headphone Jack"; + + cpu { + sound-dai = <&mca 2>; + }; + codec { + sound-dai = <&jack_codec>; + }; + }; + }; +}; + #include "spi1-nvram.dtsi" #include "hwmon-common.dtsi" #include "hwmon-fan-dual.dtsi" diff --git a/arch/arm64/boot/dts/apple/t8122-j433.dts b/arch/arm64/boot/dts/apple/t8122-j433.dts index 3cd4a899856d0b..e8d5f096456449 100644 --- a/arch/arm64/boot/dts/apple/t8122-j433.dts +++ b/arch/arm64/boot/dts/apple/t8122-j433.dts @@ -44,4 +44,35 @@ status = "okay"; }; +&i2c1 { + jack_codec: codec@4b { + compatible = "cirrus,cs42l84"; + reg = <0x4b>; + reset-gpios = <&pinctrl_nub 17 GPIO_ACTIVE_HIGH>; + interrupt-parent = <&pinctrl_ap>; + interrupts = <173 IRQ_TYPE_LEVEL_LOW>; + #sound-dai-cells = <0>; + cirrus,ts-inv = <1>; + sound-name-prefix = "Jack"; + }; +}; + +/ { + sound { + compatible = "apple,j433-macaudio", "apple,macaudio"; + model = "iMac J433"; + + dai-link@1 { + link-name = "Headphone Jack"; + + cpu { + sound-dai = <&mca 2>; + }; + codec { + sound-dai = <&jack_codec>; + }; + }; + }; +}; + #include "hwmon-fan-dual.dtsi" diff --git a/arch/arm64/boot/dts/apple/t8122-j434.dts b/arch/arm64/boot/dts/apple/t8122-j434.dts index 32a9d7c3df8c90..a374c16f794e3b 100644 --- a/arch/arm64/boot/dts/apple/t8122-j434.dts +++ b/arch/arm64/boot/dts/apple/t8122-j434.dts @@ -50,4 +50,35 @@ status = "okay"; }; +&i2c1 { + jack_codec: codec@4b { + compatible = "cirrus,cs42l84"; + reg = <0x4b>; + reset-gpios = <&pinctrl_nub 17 GPIO_ACTIVE_HIGH>; + interrupt-parent = <&pinctrl_ap>; + interrupts = <173 IRQ_TYPE_LEVEL_LOW>; + #sound-dai-cells = <0>; + cirrus,ts-inv = <1>; + sound-name-prefix = "Jack"; + }; +}; + +/ { + sound { + compatible = "apple,j434-macaudio", "apple,macaudio"; + model = "iMac J434"; + + dai-link@1 { + link-name = "Headphone Jack"; + + cpu { + sound-dai = <&mca 2>; + }; + codec { + sound-dai = <&jack_codec>; + }; + }; + }; +}; + #include "hwmon-fan-dual.dtsi" diff --git a/arch/arm64/boot/dts/apple/t8122-j504.dts b/arch/arm64/boot/dts/apple/t8122-j504.dts index 54950a66f89e9e..f85f7a55a99a3e 100644 --- a/arch/arm64/boot/dts/apple/t8122-j504.dts +++ b/arch/arm64/boot/dts/apple/t8122-j504.dts @@ -101,5 +101,134 @@ }; }; +/ { + speaker_sdz: fixed-regulator-sn012776-sdz { + compatible = "regulator-fixed"; + regulator-name = "sn012776-sdz"; + startup-delay-us = <5000>; + gpios = <&pinctrl_ap 13 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; +}; + +&i2c1 { + status = "okay"; + + speaker_left_tweet: codec@3a { + compatible = "ti,sn012776", "ti,tas2764"; + reg = <0x3a>; + SDZ-supply = <&speaker_sdz>; + #sound-dai-cells = <0>; + sound-name-prefix = "Left Tweeter"; + interrupts-extended = <&pinctrl_ap 12 IRQ_TYPE_LEVEL_LOW>; + ti,imon-slot-no = <8>; + ti,vmon-slot-no = <10>; + }; + + speaker_left_woof1: codec@38 { + compatible = "ti,sn012776", "ti,tas2764"; + reg = <0x38>; + SDZ-supply = <&speaker_sdz>; + #sound-dai-cells = <0>; + sound-name-prefix = "Left Woofer 1"; + interrupts-extended = <&pinctrl_ap 12 IRQ_TYPE_LEVEL_LOW>; + ti,imon-slot-no = <0>; + ti,vmon-slot-no = <2>; + ti,sdout-force-zero-mask = <0xf0f0f0>; + }; + + speaker_left_woof2: codec@39 { + compatible = "ti,sn012776", "ti,tas2764"; + reg = <0x39>; + SDZ-supply = <&speaker_sdz>; + #sound-dai-cells = <0>; + sound-name-prefix = "Left Woofer 2"; + interrupts-extended = <&pinctrl_ap 12 IRQ_TYPE_LEVEL_LOW>; + ti,imon-slot-no = <16>; + ti,vmon-slot-no = <18>; + }; + + jack_codec: codec@4b { + compatible = "cirrus,cs42l84"; + reg = <0x4b>; + reset-gpios = <&pinctrl_nub 17 GPIO_ACTIVE_HIGH>; + #sound-dai-cells = <0>; + interrupts-extended = <&pinctrl_ap 173 IRQ_TYPE_LEVEL_LOW>; + sound-name-prefix = "Jack"; + }; +}; + +&i2c3 { + status = "okay"; + + speaker_right_tweet: codec@3d { + compatible = "ti,sn012776", "ti,tas2764"; + reg = <0x3d>; + SDZ-supply = <&speaker_sdz>; + #sound-dai-cells = <0>; + sound-name-prefix = "Right Tweeter"; + interrupts-extended = <&pinctrl_ap 12 IRQ_TYPE_LEVEL_LOW>; + ti,imon-slot-no = <12>; + ti,vmon-slot-no = <14>; + }; + + speaker_right_woof1: codec@3b { + compatible = "ti,sn012776", "ti,tas2764"; + reg = <0x3b>; + SDZ-supply = <&speaker_sdz>; + #sound-dai-cells = <0>; + sound-name-prefix = "Right Woofer 1"; + interrupts-extended = <&pinctrl_ap 12 IRQ_TYPE_LEVEL_LOW>; + ti,imon-slot-no = <4>; + ti,vmon-slot-no = <6>; + ti,sdout-force-zero-mask = <0x0f0f0f>; + }; + + speaker_right_woof2: codec@3c { + compatible = "ti,sn012776", "ti,tas2764"; + reg = <0x3c>; + SDZ-supply = <&speaker_sdz>; + #sound-dai-cells = <0>; + sound-name-prefix = "Right Woofer 2"; + interrupts-extended = <&pinctrl_ap 12 IRQ_TYPE_LEVEL_LOW>; + ti,imon-slot-no = <20>; + ti,vmon-slot-no = <22>; + }; +}; + +/ { + sound: sound { + compatible = "apple,j504-macaudio", "apple,macaudio"; + model = "MacBook Pro J504"; + + dai-link@0 { + link-name = "Speakers"; + + cpu { + sound-dai = <&mca 0>, <&mca 1>; + }; + codec { + sound-dai = <&speaker_left_woof1>, + <&speaker_left_tweet>, + <&speaker_left_woof2>, + <&speaker_right_woof1>, + <&speaker_right_tweet>, + <&speaker_right_woof2>; + }; + }; + + dai-link@1 { + link-name = "Headphone Jack"; + + cpu { + sound-dai = <&mca 2>; + }; + codec { + sound-dai = <&jack_codec>; + }; + }; + }; +}; + #include "hwmon-fan-dual.dtsi" #include "hwmon-laptop.dtsi" diff --git a/arch/arm64/boot/dts/apple/t8122-j613.dts b/arch/arm64/boot/dts/apple/t8122-j613.dts index 7f5e0be62da267..fcf9ea0ae79237 100644 --- a/arch/arm64/boot/dts/apple/t8122-j613.dts +++ b/arch/arm64/boot/dts/apple/t8122-j613.dts @@ -38,6 +38,106 @@ brcm,board-type = "apple,dnieper"; }; +/* Virtual regulator representing the shared shutdown GPIO */ +/ { + speaker_sdz: fixed-regulator-sn012776-sdz { + compatible = "regulator-fixed"; + regulator-name = "sn012776-sdz"; + startup-delay-us = <5000>; + gpios = <&pinctrl_ap 13 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; +}; + +&i2c1 { + speaker_left_woof: codec@38 { + compatible = "ti,sn012776", "ti,tas2764"; + reg = <0x38>; + SDZ-supply = <&speaker_sdz>; + #sound-dai-cells = <0>; + sound-name-prefix = "Left Woofer"; + interrupts-extended = <&pinctrl_ap 12 IRQ_TYPE_LEVEL_LOW>; + ti,imon-slot-no = <0>; + ti,vmon-slot-no = <2>; + ti,sdout-force-zero-mask = <0xf0f0>; + }; + + speaker_left_tweet: codec@39 { + compatible = "ti,sn012776", "ti,tas2764"; + reg = <0x39>; + SDZ-supply = <&speaker_sdz>; + #sound-dai-cells = <0>; + sound-name-prefix = "Left Tweeter"; + interrupts-extended = <&pinctrl_ap 12 IRQ_TYPE_LEVEL_LOW>; + ti,imon-slot-no = <8>; + ti,vmon-slot-no = <10>; + }; +}; + +&i2c3 { + speaker_right_woof: codec@3b { + compatible = "ti,sn012776", "ti,tas2764"; + reg = <0x3b>; + SDZ-supply = <&speaker_sdz>; + #sound-dai-cells = <0>; + sound-name-prefix = "Right Woofer"; + interrupts-extended = <&pinctrl_ap 12 IRQ_TYPE_LEVEL_LOW>; + ti,imon-slot-no = <4>; + ti,vmon-slot-no = <6>; + ti,sdout-force-zero-mask = <0x0f0f>; + }; + + speaker_right_tweet: codec@3c { + compatible = "ti,sn012776", "ti,tas2764"; + reg = <0x3c>; + SDZ-supply = <&speaker_sdz>; + #sound-dai-cells = <0>; + sound-name-prefix = "Right Tweeter"; + interrupts-extended = <&pinctrl_ap 12 IRQ_TYPE_LEVEL_LOW>; + ti,imon-slot-no = <12>; + ti,vmon-slot-no = <14>; + }; + + jack_codec: codec@4b { + compatible = "cirrus,cs42l84"; + reg = <0x4b>; + reset-gpios = <&pinctrl_nub 17 GPIO_ACTIVE_HIGH>; + #sound-dai-cells = <0>; + interrupts-extended = <&pinctrl_ap 173 IRQ_TYPE_LEVEL_LOW>; + sound-name-prefix = "Jack"; + }; +}; + +/ { + sound { + compatible = "apple,j613-macaudio", "apple,j413-macaudio", "apple,macaudio"; + model = "MacBook Air J613"; + + dai-link@0 { + link-name = "Speakers"; + + cpu { + sound-dai = <&mca 0>, <&mca 1>; + }; + codec { + sound-dai = <&speaker_left_woof>, <&speaker_left_tweet>, + <&speaker_right_woof>, <&speaker_right_tweet>; + }; + }; + + dai-link@1 { + link-name = "Headphone Jack"; + + cpu { + sound-dai = <&mca 2>; + }; + codec { + sound-dai = <&jack_codec>; + }; + }; + }; +}; + &fpwm1 { status = "okay"; }; diff --git a/arch/arm64/boot/dts/apple/t8122-j615.dts b/arch/arm64/boot/dts/apple/t8122-j615.dts index 13e1a3158c2cad..990f799e391120 100644 --- a/arch/arm64/boot/dts/apple/t8122-j615.dts +++ b/arch/arm64/boot/dts/apple/t8122-j615.dts @@ -38,6 +38,106 @@ brcm,board-type = "apple,tuzla"; }; +/* Virtual regulator representing the shared shutdown GPIO */ +/ { + speaker_sdz: fixed-regulator-sn012776-sdz { + compatible = "regulator-fixed"; + regulator-name = "sn012776-sdz"; + startup-delay-us = <5000>; + gpios = <&pinctrl_ap 13 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; +}; + +&i2c1 { + speaker_left_woof: codec@38 { + compatible = "ti,sn012776", "ti,tas2764"; + reg = <0x38>; + SDZ-supply = <&speaker_sdz>; + #sound-dai-cells = <0>; + sound-name-prefix = "Left Woofer"; + interrupts-extended = <&pinctrl_ap 12 IRQ_TYPE_LEVEL_LOW>; + ti,imon-slot-no = <0>; + ti,vmon-slot-no = <2>; + ti,sdout-force-zero-mask = <0xf0f0>; + }; + + speaker_left_tweet: codec@39 { + compatible = "ti,sn012776", "ti,tas2764"; + reg = <0x39>; + SDZ-supply = <&speaker_sdz>; + #sound-dai-cells = <0>; + sound-name-prefix = "Left Tweeter"; + interrupts-extended = <&pinctrl_ap 12 IRQ_TYPE_LEVEL_LOW>; + ti,imon-slot-no = <8>; + ti,vmon-slot-no = <10>; + }; +}; + +&i2c3 { + speaker_right_woof: codec@3b { + compatible = "ti,sn012776", "ti,tas2764"; + reg = <0x3b>; + SDZ-supply = <&speaker_sdz>; + #sound-dai-cells = <0>; + sound-name-prefix = "Right Woofer"; + interrupts-extended = <&pinctrl_ap 12 IRQ_TYPE_LEVEL_LOW>; + ti,imon-slot-no = <4>; + ti,vmon-slot-no = <6>; + ti,sdout-force-zero-mask = <0x0f0f>; + }; + + speaker_right_tweet: codec@3c { + compatible = "ti,sn012776", "ti,tas2764"; + reg = <0x3c>; + SDZ-supply = <&speaker_sdz>; + #sound-dai-cells = <0>; + sound-name-prefix = "Right Tweeter"; + interrupts-extended = <&pinctrl_ap 12 IRQ_TYPE_LEVEL_LOW>; + ti,imon-slot-no = <12>; + ti,vmon-slot-no = <14>; + }; + + jack_codec: codec@4b { + compatible = "cirrus,cs42l84"; + reg = <0x4b>; + reset-gpios = <&pinctrl_nub 17 GPIO_ACTIVE_HIGH>; + #sound-dai-cells = <0>; + interrupts-extended = <&pinctrl_ap 173 IRQ_TYPE_LEVEL_LOW>; + sound-name-prefix = "Jack"; + }; +}; + +/ { + sound { + compatible = "apple,j615-macaudio", "apple,j415-macaudio", "apple,macaudio"; + model = "MacBook Air J615"; + + dai-link@0 { + link-name = "Speakers"; + + cpu { + sound-dai = <&mca 0>, <&mca 1>; + }; + codec { + sound-dai = <&speaker_left_woof>, <&speaker_left_tweet>, + <&speaker_right_woof>, <&speaker_right_tweet>; + }; + }; + + dai-link@1 { + link-name = "Headphone Jack"; + + cpu { + sound-dai = <&mca 2>; + }; + codec { + sound-dai = <&jack_codec>; + }; + }; + }; +}; + &fpwm1 { status = "okay"; }; diff --git a/arch/arm64/boot/dts/apple/t8122-jxxx.dtsi b/arch/arm64/boot/dts/apple/t8122-jxxx.dtsi index 064b72f2075ec8..e5de3e68052378 100644 --- a/arch/arm64/boot/dts/apple/t8122-jxxx.dtsi +++ b/arch/arm64/boot/dts/apple/t8122-jxxx.dtsi @@ -74,6 +74,18 @@ }; }; +&i2c1 { + status = "okay"; +}; + +&i2c2 { + status = "okay"; +}; + +&i2c3 { + status = "okay"; +}; + &nco_clkref { clock-frequency = <900000000>; }; From 8a26bd626c9497157b1dd50ee62be755c4472801 Mon Sep 17 00:00:00 2001 From: Janne Grunau Date: Sun, 14 Jun 2026 22:32:48 +0200 Subject: [PATCH 17/33] HACK: drm/apple: depend on BACKLIGHT_CLASS_DEVICE to break x86 Kconfig cycles Signed-off-by: Janne Grunau --- drivers/gpu/drm/apple/Kconfig | 2 +- drivers/platform/x86/Kconfig | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/apple/Kconfig b/drivers/gpu/drm/apple/Kconfig index a1d4498c5d788e..ecf7afd76cedaf 100644 --- a/drivers/gpu/drm/apple/Kconfig +++ b/drivers/gpu/drm/apple/Kconfig @@ -11,7 +11,7 @@ config DRM_APPLE select DRM_KMS_DMA_HELPER select DRM_GEM_DMA_HELPER select VIDEOMODE_HELPERS - select BACKLIGHT_CLASS_DEVICE + depends on BACKLIGHT_CLASS_DEVICE select MULTIPLEXER help Say Y if you have an Apple Silicon chipset. diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig index 4cb7d97a9fcc8e..4a43488202e34e 100644 --- a/drivers/platform/x86/Kconfig +++ b/drivers/platform/x86/Kconfig @@ -345,7 +345,7 @@ config EEEPC_LAPTOP depends on ACPI_VIDEO || ACPI_VIDEO = n depends on HOTPLUG_PCI depends on BACKLIGHT_CLASS_DEVICE - select HWMON + depends on HWMON select LEDS_CLASS select NEW_LEDS select INPUT_SPARSEKMAP From 984ea8438efb60a78fecf2809e07acc06b0126bc Mon Sep 17 00:00:00 2001 From: Janne Grunau Date: Sun, 14 Jun 2026 22:34:12 +0200 Subject: [PATCH 18/33] phy: apple: atc: Handle dummy pipehandler transisions Signed-off-by: Janne Grunau --- drivers/phy/apple/atc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/phy/apple/atc.c b/drivers/phy/apple/atc.c index 4f0585818fa7ac..1cf4ea19ffe80b 100644 --- a/drivers/phy/apple/atc.c +++ b/drivers/phy/apple/atc.c @@ -1133,6 +1133,8 @@ static int atcphy_configure_pipehandler(struct apple_atcphy *atcphy, bool host) case ATCPHY_PIPEHANDLER_STATE_USB4: dev_warn(atcphy->dev, "ATCPHY_PIPEHANDLER_STATE_USB4 not implemented; falling back to USB2\n"); + fallthrough; + case ATCPHY_PIPEHANDLER_STATE_DUMMY: ret = atcphy_configure_pipehandler_dummy(atcphy); atcphy->pipehandler_up = false; break; From dfba559f2e11a726a7d3075dc4b1f3aeaecc124b Mon Sep 17 00:00:00 2001 From: Janne Grunau Date: Thu, 4 Jun 2026 20:37:46 +0200 Subject: [PATCH 19/33] fixup! dts: apple: t[603x,8122]: Add MCA and supporting nodes Signed-off-by: Janne Grunau --- arch/arm64/boot/dts/apple/t8122.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm64/boot/dts/apple/t8122.dtsi b/arch/arm64/boot/dts/apple/t8122.dtsi index 1115ff080b3eb9..09f0087e922e71 100644 --- a/arch/arm64/boot/dts/apple/t8122.dtsi +++ b/arch/arm64/boot/dts/apple/t8122.dtsi @@ -545,9 +545,9 @@ #sound-dai-cells = <1>; }; - nco: clock-controller@2c0044000 { + nco: clock-controller@2d0044000 { compatible = "apple,t8122-nco", "apple,t8103-nco"; - reg = <0x2 0xc0044000 0x0 0x14000>; + reg = <0x2 0xd0044000 0x0 0x14000>; clocks = <&nco_clkref>; #clock-cells = <1>; }; From d2dc26f1532f07e3d0c8382d5b43fef46a76e808 Mon Sep 17 00:00:00 2001 From: Janne Grunau Date: Thu, 11 Sep 2025 00:01:39 +0200 Subject: [PATCH 20/33] usb: typec: tipd: Track data_status changes for CD321x HDP status for DisplayPort alt-mode is signaled data_status. Track changes to have a debounced HPD to forward to the DRM KMS driver. Signed-off-by: Janne Grunau --- drivers/usb/typec/tipd/core.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/usb/typec/tipd/core.c b/drivers/usb/typec/tipd/core.c index d0b769333bd998..403c5a54087552 100644 --- a/drivers/usb/typec/tipd/core.c +++ b/drivers/usb/typec/tipd/core.c @@ -194,6 +194,7 @@ struct cd321x_status { u32 pwr_status; u32 data_status; u32 status_changed; + u32 data_status_changed; struct usb_pd_identity partner_identity; struct tps6598x_dp_sid_status_reg dp_sid_status; struct tps6598x_intel_vid_status_reg intel_vid_status; @@ -745,6 +746,7 @@ static void cd321x_update_work(struct work_struct *work) st = cd321x->update_status; cd321x->update_status.status_changed = 0; + cd321x->update_status.data_status_changed = 0; bool old_connected = !!tps->partner; bool new_connected = st.status & TPS_STATUS_PLUG_PRESENT; @@ -843,6 +845,7 @@ static void cd321x_update_work(struct work_struct *work) static void cd321x_queue_status(struct cd321x *cd321x) { cd321x->update_status.status_changed |= cd321x->update_status.status ^ cd321x->tps.status; + cd321x->update_status.data_status_changed |= cd321x->update_status.data_status ^ cd321x->tps.data_status; cd321x->update_status.status = cd321x->tps.status; cd321x->update_status.pwr_status = cd321x->tps.pwr_status; From 808c7daad7cc3262f096839cda749500f110941a Mon Sep 17 00:00:00 2001 From: Janne Grunau Date: Mon, 22 Dec 2025 22:08:35 +0100 Subject: [PATCH 21/33] usb: typec: tipd: HACK: Use drm oob hotplug event This is not how dp-altmode support should be implemented but it works for new. Requires a "displayport" property in the connector node with a phandle of the connector. Signed-off-by: Janne Grunau --- drivers/usb/typec/tipd/core.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/drivers/usb/typec/tipd/core.c b/drivers/usb/typec/tipd/core.c index 403c5a54087552..abc41773285592 100644 --- a/drivers/usb/typec/tipd/core.c +++ b/drivers/usb/typec/tipd/core.c @@ -6,6 +6,8 @@ * Author: Heikki Krogerus */ +#include + #include #include #include @@ -217,6 +219,8 @@ struct cd321x { struct cd321x_status update_status; struct delayed_work update_work; struct usb_pd_identity cur_partner_identity; + + struct fwnode_handle *connector_fwnode; }; static enum power_supply_property tps6598x_psy_props[] = { @@ -755,6 +759,9 @@ static void cd321x_update_work(struct work_struct *work) bool usb_connection = st.data_status & (TPS_DATA_STATUS_USB2_CONNECTION | TPS_DATA_STATUS_USB3_CONNECTION); + bool dp_hpd = st.data_status & CD321X_DATA_STATUS_HPD_LEVEL; + bool dp_hpd_changed = st.data_status_changed & CD321X_DATA_STATUS_HPD_LEVEL; + enum usb_role old_role = usb_role_switch_get_role(tps->role_sw); enum usb_role new_role = USB_ROLE_NONE; enum typec_pwr_opmode pwr_opmode = TYPEC_PWR_MODE_USB; @@ -783,6 +790,10 @@ static void cd321x_update_work(struct work_struct *work) if (old_role != USB_ROLE_NONE && (new_role != old_role || was_disconnected)) usb_role_switch_set_role(tps->role_sw, USB_ROLE_NONE); + if (cd321x->connector_fwnode && (!dp_hpd || dp_hpd_changed)) { + drm_connector_oob_hotplug_event(cd321x->connector_fwnode, connector_status_disconnected); + } + /* Process partner disconnection or change */ if (!new_connected || partner_changed) { if (!IS_ERR(tps->partner)) @@ -839,6 +850,9 @@ static void cd321x_update_work(struct work_struct *work) /* Launch the USB role switch */ usb_role_switch_set_role(tps->role_sw, new_role); + if (cd321x->connector_fwnode && dp_hpd) + drm_connector_oob_hotplug_event(cd321x->connector_fwnode, connector_status_connected); + power_supply_changed(tps->psy); } @@ -1273,6 +1287,7 @@ static int cd321x_register_port(struct tps6598x *tps, struct fwnode_handle *fwnode) { struct cd321x *cd321x = container_of(tps, struct cd321x, tps); + struct fwnode_handle *connector_fwnode = NULL; int ret; INIT_DELAYED_WORK(&cd321x->update_work, cd321x_update_work); @@ -1291,6 +1306,11 @@ cd321x_register_port(struct tps6598x *tps, struct fwnode_handle *fwnode) goto err_unregister_altmodes; } + if (fwnode_property_present(fwnode, "displayport")) + connector_fwnode = fwnode_find_reference(fwnode, "displayport", 0); + if (!IS_ERR_OR_NULL(connector_fwnode)) + cd321x->connector_fwnode = connector_fwnode; + cd321x->state.alt = NULL; cd321x->state.mode = TYPEC_STATE_SAFE; cd321x->state.data = NULL; From d8d35f748dbe27b3708b95f407e55022c9141ef4 Mon Sep 17 00:00:00 2001 From: Janne Grunau Date: Sat, 3 Dec 2022 21:26:42 +0100 Subject: [PATCH 22/33] arm64: dts: apple: t8103: Add dp-altmode dts hacks Enable DP alt mode for all M1 devices: - Mac Mini (M1): USB-C port next to the HDMI port - Macbook Pro (M1, 13-inch): front left USB-C port - Macbook Air (M1, 13-inch): front left USB-C port - iMac (M1, 2 USB-C ports): back left USB-C port - iMac (M1, 4 USB-C ports): back right middle USB-C port Signed-off-by: Janne Grunau --- arch/arm64/boot/dts/apple/t8103-jxxx.dtsi | 45 +++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/arch/arm64/boot/dts/apple/t8103-jxxx.dtsi b/arch/arm64/boot/dts/apple/t8103-jxxx.dtsi index 67a57fc507df92..0d4ff6fd093387 100644 --- a/arch/arm64/boot/dts/apple/t8103-jxxx.dtsi +++ b/arch/arm64/boot/dts/apple/t8103-jxxx.dtsi @@ -9,10 +9,15 @@ * Copyright The Asahi Linux Contributors */ +#define ENABLE_DCPEXT_TYPEC + / { aliases { bluetooth0 = &bluetooth0; dcp = &dcp; +#ifdef ENABLE_DCPEXT_TYPEC + dcpext = &dcpext; +#endif disp0 = &display; disp0_piodma = &disp0_piodma; serial0 = &serial0; @@ -103,6 +108,11 @@ power-role = "dual"; data-role = "dual"; +#ifdef ENABLE_DCPEXT_TYPEC + /* hacks */ + displayport = <&dcpext>; +#endif + ports { #address-cells = <1>; #size-cells = <0>; @@ -123,6 +133,41 @@ }; }; +#ifdef ENABLE_DCPEXT_TYPEC +&display { + iommus = <&disp0_dart 0>, <&dispext0_dart 0>; +}; + +&dispext0_dart { + status = "okay"; +}; + +&dcpext_dart { + status = "okay"; +}; + +&dcpext_mbox { + status = "okay"; +}; + +&dcpext { + status = "okay"; + apple,connector-type = "DP"; + + /* hacks */ + apple,dptx-phy = <1>; + phys = <&atcphy1 PHY_TYPE_DP>; + phy-names = "dp-phy"; + mux-controls = <&atcphy1_xbar 0>; + mux-control-names = "dp-xbar"; + mux-index = <0>; +}; + +&dpaudio1 { + status = "okay"; +}; +#endif + /* USB controllers */ &dwc3_0 { ports { From 47201fabb3220dcffe74a7697b4f27f3761e89d7 Mon Sep 17 00:00:00 2001 From: Janne Grunau Date: Thu, 25 Dec 2025 18:49:55 +0100 Subject: [PATCH 23/33] HACK: arm64: dts: apple: t8103: Mark ps_atc1_common as always on Works around missing suspend/resume handling in ATC phy for DP-altmode. Signed-off-by: Janne Grunau --- arch/arm64/boot/dts/apple/t8103-jxxx.dtsi | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/arm64/boot/dts/apple/t8103-jxxx.dtsi b/arch/arm64/boot/dts/apple/t8103-jxxx.dtsi index 0d4ff6fd093387..bf92d3e2c7753e 100644 --- a/arch/arm64/boot/dts/apple/t8103-jxxx.dtsi +++ b/arch/arm64/boot/dts/apple/t8103-jxxx.dtsi @@ -166,6 +166,10 @@ &dpaudio1 { status = "okay"; }; + +&ps_atc1_common { + apple,always-on; /* Needs to stay on for DP-alt suspend/resume */ +}; #endif /* USB controllers */ From 1c72f35b3da41781329fb1b7bb6a01c4247b0f44 Mon Sep 17 00:00:00 2001 From: Janne Grunau Date: Sat, 3 Dec 2022 22:19:44 +0100 Subject: [PATCH 24/33] arm64: dts: apple: t8112: Add dp-altmode dts hacks Enable DP alt mode for the front left USB-C port of Macbook Air 13 (M2, 13/15-inch) and Macbook Pro (M2, 13-inch). Can't easily enabled on on the M2 Mac Mini since dcpext is used for the HDMI port and dcp bringup is troublesome. Signed-off-by: Janne Grunau --- arch/arm64/boot/dts/apple/t8112-j413.dts | 2 + arch/arm64/boot/dts/apple/t8112-j415.dts | 2 + arch/arm64/boot/dts/apple/t8112-j493.dts | 2 + arch/arm64/boot/dts/apple/t8112-jxxx.dtsi | 46 +++++++++++++++++++++++ 4 files changed, 52 insertions(+) diff --git a/arch/arm64/boot/dts/apple/t8112-j413.dts b/arch/arm64/boot/dts/apple/t8112-j413.dts index f36d40cb7fe611..312a54cb7f2155 100644 --- a/arch/arm64/boot/dts/apple/t8112-j413.dts +++ b/arch/arm64/boot/dts/apple/t8112-j413.dts @@ -9,6 +9,8 @@ /dts-v1/; +#define ENABLE_DCPEXT_TYPEC + #include "t8112.dtsi" #include "t8112-jxxx.dtsi" #include diff --git a/arch/arm64/boot/dts/apple/t8112-j415.dts b/arch/arm64/boot/dts/apple/t8112-j415.dts index 7f63969ede2ab9..5fe5b2ba5dabd2 100644 --- a/arch/arm64/boot/dts/apple/t8112-j415.dts +++ b/arch/arm64/boot/dts/apple/t8112-j415.dts @@ -9,6 +9,8 @@ /dts-v1/; +#define ENABLE_DCPEXT_TYPEC + #include "t8112.dtsi" #include "t8112-jxxx.dtsi" #include diff --git a/arch/arm64/boot/dts/apple/t8112-j493.dts b/arch/arm64/boot/dts/apple/t8112-j493.dts index 61bbb7a3c6f486..9859375f8fa120 100644 --- a/arch/arm64/boot/dts/apple/t8112-j493.dts +++ b/arch/arm64/boot/dts/apple/t8112-j493.dts @@ -9,6 +9,8 @@ /dts-v1/; +#define ENABLE_DCPEXT_TYPEC + #include "t8112.dtsi" #include "t8112-jxxx.dtsi" #include diff --git a/arch/arm64/boot/dts/apple/t8112-jxxx.dtsi b/arch/arm64/boot/dts/apple/t8112-jxxx.dtsi index fb957f785d82c5..344042877adb22 100644 --- a/arch/arm64/boot/dts/apple/t8112-jxxx.dtsi +++ b/arch/arm64/boot/dts/apple/t8112-jxxx.dtsi @@ -96,6 +96,11 @@ power-role = "dual"; data-role = "dual"; +#ifdef ENABLE_DCPEXT_TYPEC + /* hacks */ + displayport = <&dcpext>; +#endif + ports { #address-cells = <1>; #size-cells = <0>; @@ -116,6 +121,47 @@ }; }; +#ifdef ENABLE_DCPEXT_TYPEC +/ { + aliases { + dcpext = &dcpext; + }; +}; + +&display { + iommus = <&disp0_dart 0>, <&dispext0_dart 0>; +}; + +&dispext0_dart { + status = "okay"; +}; + +&dcpext_dart { + status = "okay"; +}; + +&dcpext_mbox { + status = "okay"; +}; + +&dcpext { + status = "okay"; + apple,connector-type = "DP"; + + /* hacks */ + apple,dptx-phy = <1>; + phys = <&atcphy1 PHY_TYPE_DP>; + phy-names = "dp-phy"; + mux-controls = <&atcphy1_xbar 0>; + mux-control-names = "dp-xbar"; + mux-index = <2>; +}; + +&dpaudio1 { + status = "okay"; +}; +#endif + /* USB controllers */ &dwc3_0 { ports { From e1b74a993169de015cd39a5774909ff044b9c50b Mon Sep 17 00:00:00 2001 From: Janne Grunau Date: Thu, 25 Dec 2025 18:49:55 +0100 Subject: [PATCH 25/33] HACK: arm64: dts: apple: t8112: Mark ps_atc1_common as always on Works around missing suspend/resume handling in ATC phy for DP-altmode. Signed-off-by: Janne Grunau --- arch/arm64/boot/dts/apple/t8112-jxxx.dtsi | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/arm64/boot/dts/apple/t8112-jxxx.dtsi b/arch/arm64/boot/dts/apple/t8112-jxxx.dtsi index 344042877adb22..62fa3bc8f99ff0 100644 --- a/arch/arm64/boot/dts/apple/t8112-jxxx.dtsi +++ b/arch/arm64/boot/dts/apple/t8112-jxxx.dtsi @@ -160,6 +160,10 @@ &dpaudio1 { status = "okay"; }; + +&ps_atc1_common { + apple,always-on; /* Needs to stay on for DP-alt suspend/resume */ +}; #endif /* USB controllers */ From 0d23eb59b53f327fdd9ed759158a925fc3229b37 Mon Sep 17 00:00:00 2001 From: Janne Grunau Date: Sun, 4 Aug 2024 18:42:36 +0200 Subject: [PATCH 26/33] arm64: apple: t8112-j473: Add DP-altmode on typec1 Needs more testing, maybe a little unstable and somehow limits the HDMI out to 1280x720 (to be verified). Using dcp as display coproc since dcpext is used for the HDMI port. Signed-off-by: Janne Grunau --- arch/arm64/boot/dts/apple/t8112-j473.dts | 43 ++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/arch/arm64/boot/dts/apple/t8112-j473.dts b/arch/arm64/boot/dts/apple/t8112-j473.dts index 4fc96779806ea3..53f4ab554b1845 100644 --- a/arch/arm64/boot/dts/apple/t8112-j473.dts +++ b/arch/arm64/boot/dts/apple/t8112-j473.dts @@ -9,6 +9,8 @@ /dts-v1/; +#define ENABLE_DCPEXT_TYPEC + #include "t8112.dtsi" #include "t8112-jxxx.dtsi" @@ -66,6 +68,47 @@ apple,dptx-phy = <5>; }; +#ifdef ENABLE_DCPEXT_TYPEC +/ { + aliases { + dcp = &dcp; + }; +}; + +&display { + /* dispext0_dart needs to be first for m1n1's */ + iommus = <&dispext0_dart 0>, <&disp0_dart 0>; +}; + +&disp0_dart { + status = "okay"; +}; + +&dcp { + status = "okay"; + apple,connector-type = "DP"; + + /* hacks */ + apple,dptx-phy = <1>; + phys = <&atcphy1 PHY_TYPE_DP>; + phy-names = "dp-phy"; + mux-controls = <&atcphy1_xbar 0>; + mux-control-names = "dp-xbar"; + mux-index = <0>; +}; + +&dcpext { + /delete-property/ mux-controls; + /delete-property/ mux-control-names; + /delete-property/ mux-index; +}; + +&typec1 { + /* hacks */ + displayport = <&dcp>; +}; +#endif + /* remove once m1n1 enables sio nodes after setup */ &sio { status = "okay"; From 82e16857ad5ffc048d4fedc19075e69531f4318d Mon Sep 17 00:00:00 2001 From: Janne Grunau Date: Thu, 25 Dec 2025 18:49:55 +0100 Subject: [PATCH 27/33] HACK: arm64: apple: t8112-j473: Mark ps_atc1_common as always on Works around missing suspend/resume handling in ATC phy for DP-altmode. Signed-off-by: Janne Grunau --- arch/arm64/boot/dts/apple/t8112-j473.dts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/arm64/boot/dts/apple/t8112-j473.dts b/arch/arm64/boot/dts/apple/t8112-j473.dts index 53f4ab554b1845..dea9ef1eb7340a 100644 --- a/arch/arm64/boot/dts/apple/t8112-j473.dts +++ b/arch/arm64/boot/dts/apple/t8112-j473.dts @@ -107,6 +107,10 @@ /* hacks */ displayport = <&dcp>; }; + +&ps_atc1_common { + apple,always-on; /* Needs to stay on for DP-alt suspend/resume */ +}; #endif /* remove once m1n1 enables sio nodes after setup */ From 1ca5c771ccaa2ab97f35291f960b6c79f2f1bb11 Mon Sep 17 00:00:00 2001 From: Janne Grunau Date: Sat, 5 Nov 2022 21:22:50 +0100 Subject: [PATCH 28/33] arm64: dts: apple: t60xx: j[34]1[46]: Add dp-altmode hacks Blessed dp-altmode port is front left port on j314/j316/j414/j416. Signed-off-by: Janne Grunau --- .../arm64/boot/dts/apple/t600x-j314-j316.dtsi | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/arch/arm64/boot/dts/apple/t600x-j314-j316.dtsi b/arch/arm64/boot/dts/apple/t600x-j314-j316.dtsi index 38808916e29948..34b407e571e224 100644 --- a/arch/arm64/boot/dts/apple/t600x-j314-j316.dtsi +++ b/arch/arm64/boot/dts/apple/t600x-j314-j316.dtsi @@ -9,6 +9,8 @@ * Copyright The Asahi Linux Contributors */ +#define ENABLE_DCPEXT_TYPEC + #include / { @@ -22,6 +24,9 @@ bluetooth0 = &bluetooth0; dcp = &dcp; dcpext0 = &dcpext0; +#ifdef ENABLE_DCPEXT_TYPEC + dcpext1 = &dcpext1; +#endif disp0 = &display; disp0_piodma = &disp0_piodma; serial0 = &serial0; @@ -186,6 +191,11 @@ power-role = "dual"; data-role = "dual"; +#ifdef ENABLE_DCPEXT_TYPEC + /* hacks */ + displayport = <&dcpext1>; +#endif + ports { #address-cells = <1>; #size-cells = <0>; @@ -247,6 +257,46 @@ }; }; +#ifdef ENABLE_DCPEXT_TYPEC + +&display { + iommus = <&disp0_dart 0>, <&dispext0_dart 0>, <&dispext1_dart 0>; +}; + +&dispext1_dart { + status = "okay"; +}; + +&dcpext1_dart { + status = "okay"; +}; + +&dcpext1_mbox { + status = "okay"; +}; + +&dcpext1 { + status = "okay"; + apple,connector-type = "DP"; + + /* hacks */ + apple,dptx-phy = <1>; + phys = <&atcphy1 PHY_TYPE_DP>; + phy-names = "dp-phy"; + mux-controls = <&atcphy1_xbar 0>; + mux-control-names = "dp-xbar"; + mux-index = <2>; +}; + +&dpaudio2 { + status = "okay"; +}; + +&atcphy1_xbar { + status = "okay"; +}; +#endif + /* Virtual regulator representing the shared shutdown GPIO */ / { speaker_sdz: fixed-regulator-sn012776-sdz { From 8ad6a6eec0891e2dbd0b9af7508b7fb5f59b79ea Mon Sep 17 00:00:00 2001 From: Janne Grunau Date: Thu, 25 Dec 2025 18:50:32 +0100 Subject: [PATCH 29/33] HACK: arm64: dts: apple: t60xx: j[34]1[46]: Mark ps_atc1_common as always on Works around missing suspend/resume handling in ATC phy for DP-altmode. Signed-off-by: Janne Grunau --- arch/arm64/boot/dts/apple/t600x-j314-j316.dtsi | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/arm64/boot/dts/apple/t600x-j314-j316.dtsi b/arch/arm64/boot/dts/apple/t600x-j314-j316.dtsi index 34b407e571e224..70e7d0bc09376f 100644 --- a/arch/arm64/boot/dts/apple/t600x-j314-j316.dtsi +++ b/arch/arm64/boot/dts/apple/t600x-j314-j316.dtsi @@ -295,6 +295,10 @@ &atcphy1_xbar { status = "okay"; }; + +&ps_atc1_common { + apple,always-on; /* Needs to stay on for DP-alt suspend/resume */ +}; #endif /* Virtual regulator representing the shared shutdown GPIO */ From 80655bbed09870c88d23b123cede6c650d10d46b Mon Sep 17 00:00:00 2001 From: Janne Grunau Date: Sun, 9 Jun 2024 23:35:29 +0200 Subject: [PATCH 30/33] arm64: dts: apple: t60xx: j[34]75: Add dp-altmode hacks DP alt mode for Mac Studio, the blessed port is the back left middle port (second closest USB-C port to the power connector). Signed-off-by: Janne Grunau --- arch/arm64/boot/dts/apple/t6001-j375c.dts | 2 + arch/arm64/boot/dts/apple/t6002-j375d.dts | 2 + arch/arm64/boot/dts/apple/t600x-j375.dtsi | 47 ++++++++++++++++++++++ arch/arm64/boot/dts/apple/t6021-j475c.dts | 6 +++ arch/arm64/boot/dts/apple/t6022-j475d.dts | 2 + arch/arm64/boot/dts/apple/t6022-jxxxd.dtsi | 4 ++ 6 files changed, 63 insertions(+) diff --git a/arch/arm64/boot/dts/apple/t6001-j375c.dts b/arch/arm64/boot/dts/apple/t6001-j375c.dts index f3f98f03800908..844bee0c4fdf39 100644 --- a/arch/arm64/boot/dts/apple/t6001-j375c.dts +++ b/arch/arm64/boot/dts/apple/t6001-j375c.dts @@ -9,6 +9,8 @@ /dts-v1/; +#define ENABLE_DCPEXT_TYPEC + #include "t6001.dtsi" #include "t600x-j375.dtsi" diff --git a/arch/arm64/boot/dts/apple/t6002-j375d.dts b/arch/arm64/boot/dts/apple/t6002-j375d.dts index 5cf30cd162b679..1eedbfecfc38fe 100644 --- a/arch/arm64/boot/dts/apple/t6002-j375d.dts +++ b/arch/arm64/boot/dts/apple/t6002-j375d.dts @@ -9,6 +9,8 @@ /dts-v1/; +#define ENABLE_DCPEXT_TYPEC + #include "t6002.dtsi" #include "t600x-j375.dtsi" diff --git a/arch/arm64/boot/dts/apple/t600x-j375.dtsi b/arch/arm64/boot/dts/apple/t600x-j375.dtsi index ce339c0855bc98..16730697493974 100644 --- a/arch/arm64/boot/dts/apple/t600x-j375.dtsi +++ b/arch/arm64/boot/dts/apple/t600x-j375.dtsi @@ -23,6 +23,9 @@ disp0 = &display; disp0_piodma = &disp0_piodma; #endif +#ifdef ENABLE_DCPEXT_TYPEC + dcpext1 = &dcpext1; +#endif ethernet0 = ðernet0; serial0 = &serial0; sio = &sio; @@ -111,6 +114,11 @@ power-role = "dual"; data-role = "dual"; +#ifdef ENABLE_DCPEXT_TYPEC + /* hacks */ + displayport = <&dcpext1>; +#endif + ports { #address-cells = <1>; #size-cells = <0>; @@ -195,6 +203,45 @@ }; }; +#ifdef ENABLE_DCPEXT_TYPEC +&display { + iommus = <&disp0_dart 0>, <&dispext1_dart 0>; +}; + +&dispext1_dart { + status = "okay"; +}; + +&dcpext1_dart { + status = "okay"; +}; + +&dcpext1_mbox { + status = "okay"; +}; + +&dcpext1 { + status = "okay"; + apple,connector-type = "DP"; + + /* hacks */ + apple,dptx-phy = <1>; + phys = <&atcphy1 PHY_TYPE_DP>; + phy-names = "dp-phy"; + mux-controls = <&atcphy1_xbar 0>; + mux-control-names = "dp-xbar"; + mux-index = <2>; +}; + +&dpaudio2 { + status = "okay"; +}; + +&atcphy1_xbar { + status = "okay"; +}; +#endif + /* USB controllers */ &dwc3_0 { ports { diff --git a/arch/arm64/boot/dts/apple/t6021-j475c.dts b/arch/arm64/boot/dts/apple/t6021-j475c.dts index e4321cfc556838..ce08d5a42761b9 100644 --- a/arch/arm64/boot/dts/apple/t6021-j475c.dts +++ b/arch/arm64/boot/dts/apple/t6021-j475c.dts @@ -9,6 +9,8 @@ /dts-v1/; +#define ENABLE_DCPEXT_TYPEC + #include "t6021.dtsi" #include "t602x-j474-j475.dtsi" @@ -81,7 +83,11 @@ status = "disabled"; }; &display { +#ifdef ENABLE_DCPEXT_TYPEC + iommus = <&dispext0_dart 0>, <&dispext1_dart 0>; +#else iommus = <&dispext0_dart 0>; +#endif }; &dispext0_dart { status = "okay"; diff --git a/arch/arm64/boot/dts/apple/t6022-j475d.dts b/arch/arm64/boot/dts/apple/t6022-j475d.dts index cdfc78a1703c7a..1ab639556cb0b2 100644 --- a/arch/arm64/boot/dts/apple/t6022-j475d.dts +++ b/arch/arm64/boot/dts/apple/t6022-j475d.dts @@ -9,6 +9,8 @@ /dts-v1/; +#define ENABLE_DCPEXT_TYPEC + #define NO_DCP #include "t6022.dtsi" diff --git a/arch/arm64/boot/dts/apple/t6022-jxxxd.dtsi b/arch/arm64/boot/dts/apple/t6022-jxxxd.dtsi index fa0183441d791b..eee0c83f7f7d45 100644 --- a/arch/arm64/boot/dts/apple/t6022-jxxxd.dtsi +++ b/arch/arm64/boot/dts/apple/t6022-jxxxd.dtsi @@ -22,7 +22,11 @@ }; &display { +#ifdef ENABLE_DCPEXT_TYPEC + iommus = <&dispext0_dart_die1 0>, <&dispext1_dart 0>; +#else iommus = <&dispext0_dart_die1 0>; +#endif }; &dispext0_dart_die1 { From 45b2f78eb60a08f5f935e06d80a5d76171b3f719 Mon Sep 17 00:00:00 2001 From: Janne Grunau Date: Thu, 25 Dec 2025 18:49:55 +0100 Subject: [PATCH 31/33] HACK: arm64: dts: apple: t60xx: j[34]75: Mark ps_atc1_common as always on Works around missing suspend/resume handling in ATC phy for DP-altmode. Signed-off-by: Janne Grunau --- arch/arm64/boot/dts/apple/t600x-j375.dtsi | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/arm64/boot/dts/apple/t600x-j375.dtsi b/arch/arm64/boot/dts/apple/t600x-j375.dtsi index 16730697493974..03b335d0cc53b2 100644 --- a/arch/arm64/boot/dts/apple/t600x-j375.dtsi +++ b/arch/arm64/boot/dts/apple/t600x-j375.dtsi @@ -240,6 +240,10 @@ &atcphy1_xbar { status = "okay"; }; + +&ps_atc1_common { + apple,always-on; /* Needs to stay on for DP-alt suspend/resume */ +}; #endif /* USB controllers */ From b94beb589e9b3b423afc459e70f5c73cd3602a82 Mon Sep 17 00:00:00 2001 From: Janne Grunau Date: Sat, 5 Nov 2022 21:22:50 +0100 Subject: [PATCH 32/33] arm64: dts: apple: t6020-j474s: Add dp-altmode hacks DP alt mode for Mac Mini M2 Pro, the blessed port is the back right middle port (second closest USB-C port to the power connector). Signed-off-by: Janne Grunau --- arch/arm64/boot/dts/apple/t6020-j474s.dts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/arch/arm64/boot/dts/apple/t6020-j474s.dts b/arch/arm64/boot/dts/apple/t6020-j474s.dts index 12dfe9693502ad..cfe7f8ac730641 100644 --- a/arch/arm64/boot/dts/apple/t6020-j474s.dts +++ b/arch/arm64/boot/dts/apple/t6020-j474s.dts @@ -9,6 +9,8 @@ /dts-v1/; +#define ENABLE_DCPEXT_TYPEC + #include "t6020.dtsi" /* @@ -85,7 +87,11 @@ status = "disabled"; }; &display { +#ifdef ENABLE_DCPEXT_TYPEC + iommus = <&dispext0_dart 0>, <&dispext1_dart 0>; +#else iommus = <&dispext0_dart 0>; +#endif }; &dispext0_dart { status = "okay"; From 7b924fd6fa7446be0dd169fca419dfaafa6401ab Mon Sep 17 00:00:00 2001 From: areofyl Date: Sat, 6 Jun 2026 16:29:43 -0700 Subject: [PATCH 33/33] macsmc-input: poll MSLD for lid state, fix spurious s2idle wake SMC lid events (0x7203) show up in the SMC firmware syslog but never get delivered to Linux via RTKit notifications, so lid open/close is invisible to userspace. Switch to polling the MSLD key every second with a delayed_work and reporting SW_LID when it changes. 2-poll debounce because MSLD bounces during DP disconnect events. Also fixes spurious wake: the SMC fires a fake BTN_TOUCHID press+release within ~1ms of entering s2idle. Skip the first 2 button events after pm_prepare, real presses after that go through normally. Other fixes: - Add remove callback (old driver had none, leaked notifier + work) - pm_complete cancels and reschedules lid_work so polling survives suspend/resume cycles - Expose MSLD as sysfs attribute (msld_state) for debugging - Init pending_lid_state from MSLD at probe Tested on M1 MacBook Air (J313), fairydust 6.18.10. Signed-off-by: areofyl --- drivers/input/misc/macsmc-input.c | 116 ++++++++++++++++++++++++++++-- 1 file changed, 109 insertions(+), 7 deletions(-) diff --git a/drivers/input/misc/macsmc-input.c b/drivers/input/misc/macsmc-input.c index 2cead3b7f45fed..8992ef52f32ced 100644 --- a/drivers/input/misc/macsmc-input.c +++ b/drivers/input/misc/macsmc-input.c @@ -28,6 +28,12 @@ struct macsmc_input { struct input_dev *input; struct notifier_block nb; bool wakeup_mode; + int ignore_btn_count; + struct delayed_work lid_work; + u8 pending_lid_state; + u8 debounce_lid_state; + int debounce_count; + bool have_lid; }; #define SMC_EV_BTN 0x7201 @@ -46,11 +52,21 @@ static void macsmc_input_event_button(struct macsmc_input *smcin, unsigned long switch (button) { case BTN_POWER: case BTN_TOUCHID: + /* + * The SMC fires a spurious BTN_TOUCHID press+release ~1ms + * after entering s2idle. Skip those first 2 events, then + * let real presses through normally. + */ + if (smcin->wakeup_mode && smcin->ignore_btn_count > 0) { + smcin->ignore_btn_count--; + return; + } + pm_wakeup_dev_event(smcin->dev, 0, (smcin->wakeup_mode && state)); /* * Suppress KEY_POWER reports when suspended to avoid powering down * immediately after waking from s2idle. - * */ + */ if (smcin->wakeup_mode) return; @@ -79,14 +95,75 @@ static void macsmc_input_event_button(struct macsmc_input *smcin, unsigned long } } +static void macsmc_input_lid_work(struct work_struct *work) +{ + struct macsmc_input *smcin = container_of(work, struct macsmc_input, lid_work.work); + u8 val; + int ret; + + ret = apple_smc_read_u8(smcin->smc, SMC_KEY(MSLD), &val); + if (ret) { + dev_warn_once(smcin->dev, "MSLD read failed: %d\n", ret); + goto resched; + } + + /* + * Debounce: DP disconnect can cause MSLD to bounce briefly. + * Require 2 consecutive polls with the same changed value + * before reporting a lid state change. + */ + if (val != smcin->debounce_lid_state) { + smcin->debounce_lid_state = val; + smcin->debounce_count = 1; + } else { + smcin->debounce_count++; + } + + if (smcin->debounce_lid_state != smcin->pending_lid_state && + smcin->debounce_count >= 2) { + dev_info(smcin->dev, "lid state changed: %d -> %d\n", + smcin->pending_lid_state, smcin->debounce_lid_state); + smcin->pending_lid_state = smcin->debounce_lid_state; + input_report_switch(smcin->input, SW_LID, smcin->pending_lid_state); + input_sync(smcin->input); + } + +resched: + schedule_delayed_work(&smcin->lid_work, msecs_to_jiffies(1000)); +} + static void macsmc_input_event_lid(struct macsmc_input *smcin, unsigned long event) { - u8 lid_state = !!((event >> 8) & 0xff); + /* + * SMC lid events (0x7203) are not reliably delivered via RTKit + * notifications on all machines. Lid state is polled via the + * MSLD key in lid_work instead. + */ +} + +static ssize_t msld_state_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct macsmc_input *smcin = dev_get_drvdata(dev); + u8 val; + int ret; - pm_wakeup_dev_event(smcin->dev, 0, (smcin->wakeup_mode && !lid_state)); - input_report_switch(smcin->input, SW_LID, lid_state); - input_sync(smcin->input); + if (!smcin->have_lid) + return sysfs_emit(buf, "unsupported\n"); + + ret = apple_smc_read_u8(smcin->smc, SMC_KEY(MSLD), &val); + if (ret) + return sysfs_emit(buf, "error %d\n", ret); + + return sysfs_emit(buf, "%d\n", val); } +static DEVICE_ATTR_RO(msld_state); + +static struct attribute *macsmc_input_attrs[] = { + &dev_attr_msld_state.attr, + NULL, +}; +ATTRIBUTE_GROUPS(macsmc_input); static int macsmc_input_event(struct notifier_block *nb, unsigned long event, void *data) { @@ -125,7 +202,9 @@ static int macsmc_input_probe(struct platform_device *pdev) smcin->dev = &pdev->dev; smcin->smc = smc; + smcin->have_lid = have_lid; platform_set_drvdata(pdev, smcin); + INIT_DELAYED_WORK(&smcin->lid_work, macsmc_input_lid_work); smcin->input = devm_input_allocate_device(&pdev->dev); if (!smcin->input) @@ -143,10 +222,14 @@ static int macsmc_input_probe(struct platform_device *pdev) u8 val; error = apple_smc_read_u8(smc, SMC_KEY(MSLD), &val); - if (error < 0) + if (error < 0) { dev_warn(&pdev->dev, "Failed to read initial lid state\n"); - else + } else { + smcin->pending_lid_state = val; + smcin->debounce_lid_state = val; + smcin->debounce_count = 2; input_report_switch(smcin->input, SW_LID, val); + } } if (have_power) { @@ -172,14 +255,27 @@ static int macsmc_input_probe(struct platform_device *pdev) device_init_wakeup(&pdev->dev, true); + if (have_lid) + schedule_delayed_work(&smcin->lid_work, msecs_to_jiffies(1000)); + return 0; } +static void macsmc_input_remove(struct platform_device *pdev) +{ + struct macsmc_input *smcin = platform_get_drvdata(pdev); + struct apple_smc *smc = smcin->smc; + + cancel_delayed_work_sync(&smcin->lid_work); + blocking_notifier_chain_unregister(&smc->event_handlers, &smcin->nb); +} + static int macsmc_input_pm_prepare(struct device *dev) { struct macsmc_input *smcin = dev_get_drvdata(dev); smcin->wakeup_mode = true; + smcin->ignore_btn_count = 2; return 0; } @@ -187,7 +283,11 @@ static void macsmc_input_pm_complete(struct device *dev) { struct macsmc_input *smcin = dev_get_drvdata(dev); + cancel_delayed_work_sync(&smcin->lid_work); smcin->wakeup_mode = false; + smcin->ignore_btn_count = 0; + if (smcin->have_lid) + schedule_delayed_work(&smcin->lid_work, msecs_to_jiffies(1000)); } static const struct dev_pm_ops macsmc_input_pm_ops = { @@ -199,8 +299,10 @@ static struct platform_driver macsmc_input_driver = { .driver = { .name = "macsmc-input", .pm = &macsmc_input_pm_ops, + .dev_groups = macsmc_input_groups, }, .probe = macsmc_input_probe, + .remove = macsmc_input_remove, }; module_platform_driver(macsmc_input_driver);