uefi-x86-6.19: copy patches from 6.18

This commit is contained in:
EvilOlaf
2025-12-16 05:36:16 +00:00
committed by Werner
parent e0f38cb9be
commit 32ef352ad9
19 changed files with 14660 additions and 0 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,77 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Redecorating <69827514+Redecorating@users.noreply.github.com>
Date: Mon, 7 Nov 2022 14:56:34 +0530
Subject: Put apple-bce in drivers/staging
- rpardini: 6.12: in drivers/staging/Makefile do it at the top to avoid
conflicts with Armbian's (wifi?) patching.
Signed-off-by: Ricardo Pardini <ricardo@pardini.net>
---
drivers/staging/Kconfig | 2 ++
drivers/staging/Makefile | 1 +
drivers/staging/apple-bce/Kconfig | 18 ++++++++++
drivers/staging/apple-bce/Makefile | 2 +-
4 files changed, 22 insertions(+), 1 deletion(-)
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig
index 111111111111..222222222222 100644
--- a/drivers/staging/Kconfig
+++ b/drivers/staging/Kconfig
@@ -52,4 +52,6 @@ source "drivers/staging/gpib/Kconfig"
source "drivers/staging/rtl8723cs/Kconfig"
+source "drivers/staging/apple-bce/Kconfig"
+
endif # STAGING
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile
index 111111111111..222222222222 100644
--- a/drivers/staging/Makefile
+++ b/drivers/staging/Makefile
@@ -2,6 +2,7 @@
# Makefile for staging directory
obj-y += media/
+obj-$(CONFIG_APPLE_BCE) += apple-bce/
obj-$(CONFIG_RTL8723BS) += rtl8723bs/
obj-$(CONFIG_OCTEON_ETHERNET) += octeon/
obj-$(CONFIG_VME_BUS) += vme_user/
diff --git a/drivers/staging/apple-bce/Kconfig b/drivers/staging/apple-bce/Kconfig
new file mode 100644
index 000000000000..111111111111
--- /dev/null
+++ b/drivers/staging/apple-bce/Kconfig
@@ -0,0 +1,18 @@
+config APPLE_BCE
+ tristate "Apple BCE driver (VHCI and Audio support)"
+ default m
+ depends on X86
+ select SOUND
+ select SND
+ select SND_PCM
+ select SND_JACK
+ help
+ VHCI and audio support on Apple MacBooks with the T2 Chip.
+ This driver is divided in three components:
+ - BCE (Buffer Copy Engine): which establishes a basic communication
+ channel with the T2 chip. This component is required by the other two:
+ - VHCI (Virtual Host Controller Interface): Access to keyboard, mouse
+ and other system devices depend on this virtual USB host controller
+ - Audio: a driver for the T2 audio interface.
+
+ If "M" is selected, the module will be called apple-bce.'
diff --git a/drivers/staging/apple-bce/Makefile b/drivers/staging/apple-bce/Makefile
index 111111111111..222222222222 100644
--- a/drivers/staging/apple-bce/Makefile
+++ b/drivers/staging/apple-bce/Makefile
@@ -1,5 +1,5 @@
modname := apple-bce
-obj-m += $(modname).o
+obj-$(CONFIG_APPLE_BCE) += $(modname).o
apple-bce-objs := apple_bce.o mailbox.o queue.o queue_dma.o vhci/vhci.o vhci/queue.o vhci/transfer.o audio/audio.o audio/protocol.o audio/protocol_bce.o audio/pcm.o
--
Armbian

View File

@@ -0,0 +1,72 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: mnural <mehmet.nrl@hotmail.com>
Date: Mon, 14 Apr 2025 14:44:20 +0530
Subject: Fix freezing on turning off camera
Detailed logs and reason behind can be seen here:
https://github.com/t2linux/T2-Debian-and-Ubuntu-Kernel/issues/130#issuecomment-2799130835
---
drivers/staging/apple-bce/vhci/transfer.c | 16 ++++++++--
drivers/staging/apple-bce/vhci/transfer.h | 4 ++-
2 files changed, 17 insertions(+), 3 deletions(-)
diff --git a/drivers/staging/apple-bce/vhci/transfer.c b/drivers/staging/apple-bce/vhci/transfer.c
index 111111111111..222222222222 100644
--- a/drivers/staging/apple-bce/vhci/transfer.c
+++ b/drivers/staging/apple-bce/vhci/transfer.c
@@ -400,6 +400,7 @@ int bce_vhci_urb_request_cancel(struct bce_vhci_transfer_queue *q, struct urb *u
struct bce_vhci_urb *vurb;
unsigned long flags;
int ret;
+ enum bce_vhci_urb_state old_state;
spin_lock_irqsave(&q->urb_lock, flags);
if ((ret = usb_hcd_check_unlink_urb(q->vhci->hcd, urb, status))) {
@@ -408,8 +409,19 @@ int bce_vhci_urb_request_cancel(struct bce_vhci_transfer_queue *q, struct urb *u
}
vurb = urb->hcpriv;
+
+ old_state = vurb->state; /* save old state to use later because we'll set state as cancelled */
+
+ if (old_state == BCE_VHCI_URB_CANCELLED) {
+ spin_unlock_irqrestore(&q->urb_lock, flags);
+ pr_debug("bce-vhci: URB %p is already cancelled, skipping\n", urb);
+ return 0;
+ }
+
+ vurb->state = BCE_VHCI_URB_CANCELLED;
+
/* If the URB wasn't posted to the device yet, we can still remove it on the host without pausing the queue. */
- if (vurb->state != BCE_VHCI_URB_INIT_PENDING) {
+ if (old_state != BCE_VHCI_URB_INIT_PENDING) {
pr_debug("bce-vhci: [%02x] Cancelling URB\n", q->endp_addr);
spin_unlock_irqrestore(&q->urb_lock, flags);
@@ -425,7 +437,7 @@ int bce_vhci_urb_request_cancel(struct bce_vhci_transfer_queue *q, struct urb *u
usb_hcd_giveback_urb(q->vhci->hcd, urb, status);
- if (vurb->state != BCE_VHCI_URB_INIT_PENDING)
+ if (old_state != BCE_VHCI_URB_INIT_PENDING)
bce_vhci_transfer_queue_resume(q, BCE_VHCI_PAUSE_INTERNAL_WQ);
kfree(vurb);
diff --git a/drivers/staging/apple-bce/vhci/transfer.h b/drivers/staging/apple-bce/vhci/transfer.h
index 111111111111..222222222222 100644
--- a/drivers/staging/apple-bce/vhci/transfer.h
+++ b/drivers/staging/apple-bce/vhci/transfer.h
@@ -44,7 +44,9 @@ enum bce_vhci_urb_state {
BCE_VHCI_URB_CONTROL_WAITING_FOR_SETUP_REQUEST,
BCE_VHCI_URB_CONTROL_WAITING_FOR_SETUP_COMPLETION,
- BCE_VHCI_URB_CONTROL_COMPLETE
+ BCE_VHCI_URB_CONTROL_COMPLETE,
+
+ BCE_VHCI_URB_CANCELLED
};
struct bce_vhci_urb {
struct urb *urb;
--
Armbian

View File

@@ -0,0 +1,76 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Orlando Chamberlain <orlandoch.dev@gmail.com>
Date: Fri, 28 Jun 2024 04:43:50 +0000
Subject: i915: 4 lane quirk for mbp15,1
Needed to use iGPU when dGPU was boot GPU
Patch written by Kerem Karabay <kekrby@gmail.com>
---
drivers/gpu/drm/i915/display/intel_ddi.c | 3 ++
drivers/gpu/drm/i915/display/intel_quirks.c | 15 ++++++++++
drivers/gpu/drm/i915/display/intel_quirks.h | 1 +
3 files changed, 19 insertions(+)
diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
index 111111111111..222222222222 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -4868,6 +4868,9 @@ static bool intel_ddi_a_force_4_lanes(struct intel_digital_port *dig_port)
if (dig_port->ddi_a_4_lanes)
return false;
+ if (intel_has_quirk(display, QUIRK_DDI_A_FORCE_4_LANES))
+ return true;
+
/* Broxton/Geminilake: Bspec says that DDI_A_4_LANES is the only
* supported configuration
*/
diff --git a/drivers/gpu/drm/i915/display/intel_quirks.c b/drivers/gpu/drm/i915/display/intel_quirks.c
index 111111111111..222222222222 100644
--- a/drivers/gpu/drm/i915/display/intel_quirks.c
+++ b/drivers/gpu/drm/i915/display/intel_quirks.c
@@ -66,6 +66,18 @@ static void quirk_increase_ddi_disabled_time(struct intel_display *display)
drm_info(display->drm, "Applying Increase DDI Disabled quirk\n");
}
+/*
+ * In some cases, the firmware might not set the lane count to 4 (for example,
+ * when booting in some dual GPU Macs with the dGPU as the default GPU), this
+ * quirk is used to force it as otherwise it might not be possible to compute a
+ * valid link configuration.
+ */
+static void quirk_ddi_a_force_4_lanes(struct intel_display *display)
+{
+ intel_set_quirk(display, QUIRK_DDI_A_FORCE_4_LANES);
+ drm_info(display->drm, "Applying DDI A Forced 4 Lanes quirk\n");
+}
+
static void quirk_no_pps_backlight_power_hook(struct intel_display *display)
{
intel_set_quirk(display, QUIRK_NO_PPS_BACKLIGHT_POWER_HOOK);
@@ -240,6 +252,9 @@ static struct intel_quirk intel_quirks[] = {
/* Dell XPS 13 7390 2-in-1 */
{ 0x8a12, 0x1028, 0x08b0, quirk_edp_limit_rate_hbr2 },
+
+ /* Apple MacBookPro15,1 */
+ { 0x3e9b, 0x106b, 0x0176, quirk_ddi_a_force_4_lanes },
};
static const struct intel_dpcd_quirk intel_dpcd_quirks[] = {
diff --git a/drivers/gpu/drm/i915/display/intel_quirks.h b/drivers/gpu/drm/i915/display/intel_quirks.h
index 111111111111..222222222222 100644
--- a/drivers/gpu/drm/i915/display/intel_quirks.h
+++ b/drivers/gpu/drm/i915/display/intel_quirks.h
@@ -21,6 +21,7 @@ enum intel_quirk_id {
QUIRK_NO_PPS_BACKLIGHT_POWER_HOOK,
QUIRK_FW_SYNC_LEN,
QUIRK_EDP_LIMIT_RATE_HBR2,
+ QUIRK_DDI_A_FORCE_4_LANES,
};
void intel_init_quirks(struct intel_display *display);
--
Armbian

View File

@@ -0,0 +1,109 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Orlando Chamberlain <orlandoch.dev@gmail.com>
Date: Fri, 10 Feb 2023 22:45:00 +1100
Subject: apple-gmux: allow switching to igpu at probe
This means user don't need to set the gpu-power-prefs efivar to use the
igpu while runtime switching isn't working, so macOS will be unaffected.
This isn't really upstreamable, what we want upstream is the ability to
switch at runtime (so both gpus need to be able to probe the eDP panel).
Based off of work by Kerem Karabay <kekrby@gmail.com>
---
drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 3 ++
drivers/gpu/vga/vga_switcheroo.c | 7 +---
drivers/pci/vgaarb.c | 1 +
drivers/platform/x86/apple-gmux.c | 18 ++++++++++
4 files changed, 23 insertions(+), 6 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
index 111111111111..222222222222 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
@@ -2322,6 +2322,9 @@ static int amdgpu_pci_probe(struct pci_dev *pdev,
int ret, retry = 0, i;
bool supports_atomic = false;
+ if (vga_switcheroo_client_probe_defer(pdev))
+ return -EPROBE_DEFER;
+
if ((pdev->class >> 8) == PCI_CLASS_DISPLAY_VGA ||
(pdev->class >> 8) == PCI_CLASS_DISPLAY_OTHER) {
if (drm_firmware_drivers_only() && amdgpu_modeset == -1)
diff --git a/drivers/gpu/vga/vga_switcheroo.c b/drivers/gpu/vga/vga_switcheroo.c
index 111111111111..222222222222 100644
--- a/drivers/gpu/vga/vga_switcheroo.c
+++ b/drivers/gpu/vga/vga_switcheroo.c
@@ -438,12 +438,7 @@ find_active_client(struct list_head *head)
bool vga_switcheroo_client_probe_defer(struct pci_dev *pdev)
{
if (pci_is_display(pdev)) {
- /*
- * apple-gmux is needed on pre-retina MacBook Pro
- * to probe the panel if pdev is the inactive GPU.
- */
- if (apple_gmux_present() && pdev != vga_default_device() &&
- !vgasr_priv.handler_flags)
+ if (apple_gmux_present() && !vgasr_priv.handler_flags)
return true;
}
diff --git a/drivers/pci/vgaarb.c b/drivers/pci/vgaarb.c
index 111111111111..222222222222 100644
--- a/drivers/pci/vgaarb.c
+++ b/drivers/pci/vgaarb.c
@@ -143,6 +143,7 @@ void vga_set_default_device(struct pci_dev *pdev)
pci_dev_put(vga_default);
vga_default = pci_dev_get(pdev);
}
+EXPORT_SYMBOL_GPL(vga_set_default_device);
/**
* vga_remove_vgacon - deactivate VGA console
diff --git a/drivers/platform/x86/apple-gmux.c b/drivers/platform/x86/apple-gmux.c
index 111111111111..222222222222 100644
--- a/drivers/platform/x86/apple-gmux.c
+++ b/drivers/platform/x86/apple-gmux.c
@@ -21,6 +21,7 @@
#include <linux/delay.h>
#include <linux/pci.h>
#include <linux/vga_switcheroo.h>
+#include <linux/vgaarb.h>
#include <linux/debugfs.h>
#include <acpi/video.h>
#include <asm/io.h>
@@ -107,6 +108,10 @@ struct apple_gmux_config {
# define MMIO_GMUX_MAX_BRIGHTNESS 0xffff
+static bool force_igd;
+module_param(force_igd, bool, 0);
+MODULE_PARM_DESC(force_idg, "Switch gpu to igd on module load. Make sure that you have apple-set-os set up and the iGPU is in `lspci -s 00:02.0`. (default: false) (bool)");
+
static u8 gmux_pio_read8(struct apple_gmux_data *gmux_data, int port)
{
return inb(gmux_data->iostart + port);
@@ -945,6 +950,19 @@ static int gmux_probe(struct pnp_dev *pnp, const struct pnp_device_id *id)
gmux_enable_interrupts(gmux_data);
gmux_read_switch_state(gmux_data);
+ if (force_igd) {
+ struct pci_dev *pdev;
+
+ pdev = pci_get_domain_bus_and_slot(0, 0, PCI_DEVFN(2, 0));
+ if (pdev) {
+ pr_info("Switching to IGD");
+ gmux_switchto(VGA_SWITCHEROO_IGD);
+ vga_set_default_device(pdev);
+ } else {
+ pr_err("force_idg is true, but couldn't find iGPU at 00:02.0! Is apple-set-os working?");
+ }
+ }
+
/*
* Retina MacBook Pros cannot switch the panel's AUX separately
* and need eDP pre-calibration. They are distinguishable from
--
Armbian

View File

@@ -0,0 +1,312 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Paul Pawlowski <paul@mrarm.io>
Date: Sun, 17 Nov 2019 23:11:56 +0100
Subject: applesmc: make io port base addr dynamic
This change makes the port base runtime configurable.
The reason why this change is made is so that when we switch to an
acpi_device we can resolve the port base addr from ACPI.
This change is not strictly required for T2 support - the base
address is still 0x300 on T2 Macs.
Signed-off-by: Aun-Ali Zaidi <admin@kodeit.net>
---
drivers/hwmon/applesmc.c | 91 +++++-----
1 file changed, 49 insertions(+), 42 deletions(-)
diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c
index 111111111111..222222222222 100644
--- a/drivers/hwmon/applesmc.c
+++ b/drivers/hwmon/applesmc.c
@@ -35,10 +35,11 @@
#include <linux/err.h>
#include <linux/bits.h>
+#define APPLESMC_PORT_BASE 0x300
/* data port used by Apple SMC */
-#define APPLESMC_DATA_PORT 0x300
+#define APPLESMC_DATA_PORT 0
/* command/status port used by Apple SMC */
-#define APPLESMC_CMD_PORT 0x304
+#define APPLESMC_CMD_PORT 4
#define APPLESMC_NR_PORTS 32 /* 0x300-0x31f */
@@ -140,6 +141,8 @@ struct applesmc_device {
struct platform_device *dev;
struct applesmc_registers reg;
+ u16 port_base;
+
s16 rest_x;
s16 rest_y;
@@ -169,7 +172,7 @@ static const int debug;
* run out past 500ms.
*/
-static int wait_status(u8 val, u8 mask)
+static int wait_status(struct applesmc_device *smc, u8 val, u8 mask)
{
u8 status;
int us;
@@ -177,7 +180,7 @@ static int wait_status(u8 val, u8 mask)
us = APPLESMC_MIN_WAIT;
for (i = 0; i < 24 ; i++) {
- status = inb(APPLESMC_CMD_PORT);
+ status = inb(smc->port_base + APPLESMC_CMD_PORT);
if ((status & mask) == val)
return 0;
usleep_range(us, us * 2);
@@ -189,11 +192,11 @@ static int wait_status(u8 val, u8 mask)
/* send_byte - Write to SMC data port. Callers must hold applesmc_lock. */
-static int send_byte(u8 cmd, u16 port)
+static int send_byte(struct applesmc_device *smc, u8 cmd, u16 port)
{
int status;
- status = wait_status(0, SMC_STATUS_IB_CLOSED);
+ status = wait_status(smc, 0, SMC_STATUS_IB_CLOSED);
if (status)
return status;
/*
@@ -202,24 +205,24 @@ static int send_byte(u8 cmd, u16 port)
* this extra read may not happen if status returns both
* simultaneously and this would appear to be required.
*/
- status = wait_status(SMC_STATUS_BUSY, SMC_STATUS_BUSY);
+ status = wait_status(smc, SMC_STATUS_BUSY, SMC_STATUS_BUSY);
if (status)
return status;
- outb(cmd, port);
+ outb(cmd, smc->port_base + port);
return 0;
}
/* send_command - Write a command to the SMC. Callers must hold applesmc_lock. */
-static int send_command(u8 cmd)
+static int send_command(struct applesmc_device *smc, u8 cmd)
{
int ret;
- ret = wait_status(0, SMC_STATUS_IB_CLOSED);
+ ret = wait_status(smc, 0, SMC_STATUS_IB_CLOSED);
if (ret)
return ret;
- outb(cmd, APPLESMC_CMD_PORT);
+ outb(cmd, smc->port_base + APPLESMC_CMD_PORT);
return 0;
}
@@ -229,108 +232,112 @@ static int send_command(u8 cmd)
* If busy is stuck high after the command then the SMC is jammed.
*/
-static int smc_sane(void)
+static int smc_sane(struct applesmc_device *smc)
{
int ret;
- ret = wait_status(0, SMC_STATUS_BUSY);
+ ret = wait_status(smc, 0, SMC_STATUS_BUSY);
if (!ret)
return ret;
- ret = send_command(APPLESMC_READ_CMD);
+ ret = send_command(smc, APPLESMC_READ_CMD);
if (ret)
return ret;
- return wait_status(0, SMC_STATUS_BUSY);
+ return wait_status(smc, 0, SMC_STATUS_BUSY);
}
-static int send_argument(const char *key)
+static int send_argument(struct applesmc_device *smc, const char *key)
{
int i;
for (i = 0; i < 4; i++)
- if (send_byte(key[i], APPLESMC_DATA_PORT))
+ if (send_byte(smc, key[i], APPLESMC_DATA_PORT))
return -EIO;
return 0;
}
-static int read_smc(u8 cmd, const char *key, u8 *buffer, u8 len)
+static int read_smc(struct applesmc_device *smc, u8 cmd, const char *key,
+ u8 *buffer, u8 len)
{
u8 status, data = 0;
int i;
int ret;
- ret = smc_sane();
+ ret = smc_sane(smc);
if (ret)
return ret;
- if (send_command(cmd) || send_argument(key)) {
+ if (send_command(smc, cmd) || send_argument(smc, key)) {
pr_warn("%.4s: read arg fail\n", key);
return -EIO;
}
/* This has no effect on newer (2012) SMCs */
- if (send_byte(len, APPLESMC_DATA_PORT)) {
+ if (send_byte(smc, len, APPLESMC_DATA_PORT)) {
pr_warn("%.4s: read len fail\n", key);
return -EIO;
}
for (i = 0; i < len; i++) {
- if (wait_status(SMC_STATUS_AWAITING_DATA | SMC_STATUS_BUSY,
+ if (wait_status(smc,
+ SMC_STATUS_AWAITING_DATA | SMC_STATUS_BUSY,
SMC_STATUS_AWAITING_DATA | SMC_STATUS_BUSY)) {
pr_warn("%.4s: read data[%d] fail\n", key, i);
return -EIO;
}
- buffer[i] = inb(APPLESMC_DATA_PORT);
+ buffer[i] = inb(smc->port_base + APPLESMC_DATA_PORT);
}
/* Read the data port until bit0 is cleared */
for (i = 0; i < 16; i++) {
udelay(APPLESMC_MIN_WAIT);
- status = inb(APPLESMC_CMD_PORT);
+ status = inb(smc->port_base + APPLESMC_CMD_PORT);
if (!(status & SMC_STATUS_AWAITING_DATA))
break;
- data = inb(APPLESMC_DATA_PORT);
+ data = inb(smc->port_base + APPLESMC_DATA_PORT);
}
if (i)
pr_warn("flushed %d bytes, last value is: %d\n", i, data);
- return wait_status(0, SMC_STATUS_BUSY);
+ return wait_status(smc, 0, SMC_STATUS_BUSY);
}
-static int write_smc(u8 cmd, const char *key, const u8 *buffer, u8 len)
+static int write_smc(struct applesmc_device *smc, u8 cmd, const char *key,
+ const u8 *buffer, u8 len)
{
int i;
int ret;
- ret = smc_sane();
+ ret = smc_sane(smc);
if (ret)
return ret;
- if (send_command(cmd) || send_argument(key)) {
+ if (send_command(smc, cmd) || send_argument(smc, key)) {
pr_warn("%s: write arg fail\n", key);
return -EIO;
}
- if (send_byte(len, APPLESMC_DATA_PORT)) {
+ if (send_byte(smc, len, APPLESMC_DATA_PORT)) {
pr_warn("%.4s: write len fail\n", key);
return -EIO;
}
for (i = 0; i < len; i++) {
- if (send_byte(buffer[i], APPLESMC_DATA_PORT)) {
+ if (send_byte(smc, buffer[i], APPLESMC_DATA_PORT)) {
pr_warn("%s: write data fail\n", key);
return -EIO;
}
}
- return wait_status(0, SMC_STATUS_BUSY);
+ return wait_status(smc, 0, SMC_STATUS_BUSY);
}
-static int read_register_count(unsigned int *count)
+static int read_register_count(struct applesmc_device *smc,
+ unsigned int *count)
{
__be32 be;
int ret;
- ret = read_smc(APPLESMC_READ_CMD, KEY_COUNT_KEY, (u8 *)&be, 4);
+ ret = read_smc(smc, APPLESMC_READ_CMD, KEY_COUNT_KEY, (u8 *)&be, 4);
if (ret)
return ret;
@@ -353,7 +360,7 @@ static int applesmc_read_entry(struct applesmc_device *smc,
if (entry->len != len)
return -EINVAL;
mutex_lock(&smc->reg.mutex);
- ret = read_smc(APPLESMC_READ_CMD, entry->key, buf, len);
+ ret = read_smc(smc, APPLESMC_READ_CMD, entry->key, buf, len);
mutex_unlock(&smc->reg.mutex);
return ret;
@@ -367,7 +374,7 @@ static int applesmc_write_entry(struct applesmc_device *smc,
if (entry->len != len)
return -EINVAL;
mutex_lock(&smc->reg.mutex);
- ret = write_smc(APPLESMC_WRITE_CMD, entry->key, buf, len);
+ ret = write_smc(smc, APPLESMC_WRITE_CMD, entry->key, buf, len);
mutex_unlock(&smc->reg.mutex);
return ret;
}
@@ -388,10 +395,10 @@ static const struct applesmc_entry *applesmc_get_entry_by_index(
if (cache->valid)
goto out;
be = cpu_to_be32(index);
- ret = read_smc(APPLESMC_GET_KEY_BY_INDEX_CMD, (u8 *)&be, key, 4);
+ ret = read_smc(smc, APPLESMC_GET_KEY_BY_INDEX_CMD, (u8 *)&be, key, 4);
if (ret)
goto out;
- ret = read_smc(APPLESMC_GET_KEY_TYPE_CMD, key, info, 6);
+ ret = read_smc(smc, APPLESMC_GET_KEY_TYPE_CMD, key, info, 6);
if (ret)
goto out;
@@ -589,7 +596,7 @@ static int applesmc_init_smcreg_try(struct applesmc_device *smc)
if (s->init_complete)
return 0;
- ret = read_register_count(&count);
+ ret = read_register_count(smc, &count);
if (ret)
return ret;
@@ -1472,7 +1479,7 @@ static int __init applesmc_init(void)
goto out;
}
- if (!request_region(APPLESMC_DATA_PORT, APPLESMC_NR_PORTS,
+ if (!request_region(APPLESMC_PORT_BASE, APPLESMC_NR_PORTS,
"applesmc")) {
ret = -ENXIO;
goto out;
@@ -1494,7 +1501,7 @@ static int __init applesmc_init(void)
out_driver:
platform_driver_unregister(&applesmc_driver);
out_region:
- release_region(APPLESMC_DATA_PORT, APPLESMC_NR_PORTS);
+ release_region(APPLESMC_PORT_BASE, APPLESMC_NR_PORTS);
out:
pr_warn("driver init failed (ret=%d)!\n", ret);
return ret;
@@ -1504,7 +1511,7 @@ static void __exit applesmc_exit(void)
{
platform_device_unregister(pdev);
platform_driver_unregister(&applesmc_driver);
- release_region(APPLESMC_DATA_PORT, APPLESMC_NR_PORTS);
+ release_region(APPLESMC_PORT_BASE, APPLESMC_NR_PORTS);
}
module_init(applesmc_init);
--
Armbian

View File

@@ -0,0 +1,265 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Paul Pawlowski <paul@mrarm.io>
Date: Sat, 29 Jun 2024 04:49:16 +0000
Subject: applesmc: switch to acpi_device (from platform)
This change makes the change from platform_device
to acpi_device. The rationale for this change is
that on T2 Macs, an additional FixedMemory32
region is needed for device operation, and it can
be easily resolved via ACPI tables (this will be
done in another commit).
Additionally, on older Macs, the OS X driver also
looks for the specified ACPI device to resolve
its memory regions, and therefore this change
should not result in any incompatibilities.
Signed-off-by: Aun-Ali Zaidi <admin@kodeit.net>
---
drivers/hwmon/applesmc.c | 124 +++++++---
1 file changed, 84 insertions(+), 40 deletions(-)
diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c
index 111111111111..222222222222 100644
--- a/drivers/hwmon/applesmc.c
+++ b/drivers/hwmon/applesmc.c
@@ -19,7 +19,7 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/delay.h>
-#include <linux/platform_device.h>
+#include <linux/acpi.h>
#include <linux/input.h>
#include <linux/kernel.h>
#include <linux/slab.h>
@@ -35,7 +35,6 @@
#include <linux/err.h>
#include <linux/bits.h>
-#define APPLESMC_PORT_BASE 0x300
/* data port used by Apple SMC */
#define APPLESMC_DATA_PORT 0
/* command/status port used by Apple SMC */
@@ -138,9 +137,10 @@ struct applesmc_registers {
};
struct applesmc_device {
- struct platform_device *dev;
+ struct acpi_device *dev;
struct applesmc_registers reg;
+ bool port_base_set;
u16 port_base;
s16 rest_x;
@@ -692,9 +692,13 @@ static int applesmc_init_smcreg(struct applesmc_device *smc)
}
/* Device model stuff */
+
+static int applesmc_init_resources(struct applesmc_device *smc);
+static void applesmc_free_resources(struct applesmc_device *smc);
static int applesmc_create_modules(struct applesmc_device *smc);
static void applesmc_destroy_modules(struct applesmc_device *smc);
-static int applesmc_probe(struct platform_device *dev)
+
+static int applesmc_add(struct acpi_device *dev)
{
struct applesmc_device *smc;
int ret;
@@ -705,12 +709,16 @@ static int applesmc_probe(struct platform_device *dev)
smc->dev = dev;
mutex_init(&smc->reg.mutex);
- platform_set_drvdata(dev, smc);
+ dev_set_drvdata(&dev->dev, smc);
- ret = applesmc_init_smcreg(smc);
+ ret = applesmc_init_resources(smc);
if (ret)
goto out_mem;
+ ret = applesmc_init_smcreg(smc);
+ if (ret)
+ goto out_res;
+
applesmc_device_init(smc);
ret = applesmc_create_modules(smc);
@@ -721,20 +729,23 @@ static int applesmc_probe(struct platform_device *dev)
out_reg:
applesmc_destroy_smcreg(smc);
+out_res:
+ applesmc_free_resources(smc);
out_mem:
- platform_set_drvdata(dev, NULL);
+ dev_set_drvdata(&dev->dev, NULL);
mutex_destroy(&smc->reg.mutex);
kfree(smc);
return ret;
}
-static int applesmc_remove(struct platform_device *dev)
+static int applesmc_remove(struct acpi_device *dev)
{
- struct applesmc_device *smc = platform_get_drvdata(dev);
+ struct applesmc_device *smc = dev_get_drvdata(&dev->dev);
applesmc_destroy_modules(smc);
applesmc_destroy_smcreg(smc);
+ applesmc_free_resources(smc);
mutex_destroy(&smc->reg.mutex);
kfree(smc);
@@ -742,6 +753,52 @@ static int applesmc_remove(struct platform_device *dev)
return 0;
}
+static acpi_status applesmc_walk_resources(struct acpi_resource *res,
+ void *data)
+{
+ struct applesmc_device *smc = data;
+
+ switch (res->type) {
+ case ACPI_RESOURCE_TYPE_IO:
+ if (!smc->port_base_set) {
+ if (res->data.io.address_length < APPLESMC_NR_PORTS)
+ return AE_ERROR;
+ smc->port_base = res->data.io.minimum;
+ smc->port_base_set = true;
+ }
+ return AE_OK;
+
+ case ACPI_RESOURCE_TYPE_END_TAG:
+ if (smc->port_base_set)
+ return AE_OK;
+ else
+ return AE_NOT_FOUND;
+
+ default:
+ return AE_OK;
+ }
+}
+
+static int applesmc_init_resources(struct applesmc_device *smc)
+{
+ int ret;
+
+ ret = acpi_walk_resources(smc->dev->handle, METHOD_NAME__CRS,
+ applesmc_walk_resources, smc);
+ if (ACPI_FAILURE(ret))
+ return -ENXIO;
+
+ if (!request_region(smc->port_base, APPLESMC_NR_PORTS, "applesmc"))
+ return -ENXIO;
+
+ return 0;
+}
+
+static void applesmc_free_resources(struct applesmc_device *smc)
+{
+ release_region(smc->port_base, APPLESMC_NR_PORTS);
+}
+
/* Synchronize device with memorized backlight state */
static int applesmc_pm_resume(struct device *dev)
{
@@ -763,17 +820,26 @@ static int applesmc_pm_restore(struct device *dev)
return applesmc_pm_resume(dev);
}
+static const struct acpi_device_id applesmc_ids[] = {
+ {"APP0001", 0},
+ {"", 0},
+};
+
static const struct dev_pm_ops applesmc_pm_ops = {
.resume = applesmc_pm_resume,
.restore = applesmc_pm_restore,
};
-static struct platform_driver applesmc_driver = {
- .probe = applesmc_probe,
- .remove = applesmc_remove,
- .driver = {
- .name = "applesmc",
- .pm = &applesmc_pm_ops,
+static struct acpi_driver applesmc_driver = {
+ .name = "applesmc",
+ .class = "applesmc",
+ .ids = applesmc_ids,
+ .ops = {
+ .add = applesmc_add,
+ .remove = applesmc_remove
+ },
+ .drv = {
+ .pm = &applesmc_pm_ops
},
};
@@ -1262,7 +1328,6 @@ static int applesmc_create_nodes(struct applesmc_device *smc,
static int applesmc_create_accelerometer(struct applesmc_device *smc)
{
int ret;
-
if (!smc->reg.has_accelerometer)
return 0;
@@ -1467,8 +1532,6 @@ static void applesmc_destroy_modules(struct applesmc_device *smc)
applesmc_destroy_nodes(smc, info_group);
}
-static struct platform_device *pdev;
-
static int __init applesmc_init(void)
{
int ret;
@@ -1479,29 +1542,12 @@ static int __init applesmc_init(void)
goto out;
}
- if (!request_region(APPLESMC_PORT_BASE, APPLESMC_NR_PORTS,
- "applesmc")) {
- ret = -ENXIO;
- goto out;
- }
-
- ret = platform_driver_register(&applesmc_driver);
+ ret = acpi_bus_register_driver(&applesmc_driver);
if (ret)
- goto out_region;
-
- pdev = platform_device_register_simple("applesmc", APPLESMC_DATA_PORT,
- NULL, 0);
- if (IS_ERR(pdev)) {
- ret = PTR_ERR(pdev);
- goto out_driver;
- }
+ goto out;
return 0;
-out_driver:
- platform_driver_unregister(&applesmc_driver);
-out_region:
- release_region(APPLESMC_PORT_BASE, APPLESMC_NR_PORTS);
out:
pr_warn("driver init failed (ret=%d)!\n", ret);
return ret;
@@ -1509,9 +1555,7 @@ static int __init applesmc_init(void)
static void __exit applesmc_exit(void)
{
- platform_device_unregister(pdev);
- platform_driver_unregister(&applesmc_driver);
- release_region(APPLESMC_PORT_BASE, APPLESMC_NR_PORTS);
+ acpi_bus_unregister_driver(&applesmc_driver);
}
module_init(applesmc_init);
--
Armbian

View File

@@ -0,0 +1,298 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Paul Pawlowski <paul@mrarm.io>
Date: Sun, 17 Nov 2019 23:12:14 +0100
Subject: applesmc: key interface wrappers
This change replaces the read_smc and write_smc
methods with wrappers, additionally removing the
command id parameter from them (and introducing
get_smc_key_by_index and get_smc_key_info).
This is done as to allow simple implementation
replacement on T2 Macs. The newly introduced
methods mentioned in the previous paragraph need
special handling on T2 and as such had to be
separated.
Signed-off-by: Aun-Ali Zaidi <admin@kodeit.net>
---
drivers/hwmon/applesmc.c | 119 ++++++----
1 file changed, 79 insertions(+), 40 deletions(-)
diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c
index 111111111111..222222222222 100644
--- a/drivers/hwmon/applesmc.c
+++ b/drivers/hwmon/applesmc.c
@@ -172,7 +172,7 @@ static const int debug;
* run out past 500ms.
*/
-static int wait_status(struct applesmc_device *smc, u8 val, u8 mask)
+static int port_wait_status(struct applesmc_device *smc, u8 val, u8 mask)
{
u8 status;
int us;
@@ -190,13 +190,13 @@ static int wait_status(struct applesmc_device *smc, u8 val, u8 mask)
return -EIO;
}
-/* send_byte - Write to SMC data port. Callers must hold applesmc_lock. */
+/* port_send_byte - Write to SMC data port. Callers must hold applesmc_lock. */
-static int send_byte(struct applesmc_device *smc, u8 cmd, u16 port)
+static int port_send_byte(struct applesmc_device *smc, u8 cmd, u16 port)
{
int status;
- status = wait_status(smc, 0, SMC_STATUS_IB_CLOSED);
+ status = port_wait_status(smc, 0, SMC_STATUS_IB_CLOSED);
if (status)
return status;
/*
@@ -205,7 +205,7 @@ static int send_byte(struct applesmc_device *smc, u8 cmd, u16 port)
* this extra read may not happen if status returns both
* simultaneously and this would appear to be required.
*/
- status = wait_status(smc, SMC_STATUS_BUSY, SMC_STATUS_BUSY);
+ status = port_wait_status(smc, SMC_STATUS_BUSY, SMC_STATUS_BUSY);
if (status)
return status;
@@ -213,15 +213,16 @@ static int send_byte(struct applesmc_device *smc, u8 cmd, u16 port)
return 0;
}
-/* send_command - Write a command to the SMC. Callers must hold applesmc_lock. */
+/* port_send_command - Write a command to the SMC. Callers must hold applesmc_lock. */
-static int send_command(struct applesmc_device *smc, u8 cmd)
+static int port_send_command(struct applesmc_device *smc, u8 cmd)
{
int ret;
- ret = wait_status(smc, 0, SMC_STATUS_IB_CLOSED);
+ ret = port_wait_status(smc, 0, SMC_STATUS_IB_CLOSED);
if (ret)
return ret;
+
outb(cmd, smc->port_base + APPLESMC_CMD_PORT);
return 0;
}
@@ -232,53 +233,53 @@ static int send_command(struct applesmc_device *smc, u8 cmd)
* If busy is stuck high after the command then the SMC is jammed.
*/
-static int smc_sane(struct applesmc_device *smc)
+static int port_smc_sane(struct applesmc_device *smc)
{
int ret;
- ret = wait_status(smc, 0, SMC_STATUS_BUSY);
+ ret = port_wait_status(smc, 0, SMC_STATUS_BUSY);
if (!ret)
return ret;
- ret = send_command(smc, APPLESMC_READ_CMD);
+ ret = port_send_command(smc, APPLESMC_READ_CMD);
if (ret)
return ret;
- return wait_status(smc, 0, SMC_STATUS_BUSY);
+ return port_wait_status(smc, 0, SMC_STATUS_BUSY);
}
-static int send_argument(struct applesmc_device *smc, const char *key)
+static int port_send_argument(struct applesmc_device *smc, const char *key)
{
int i;
for (i = 0; i < 4; i++)
- if (send_byte(smc, key[i], APPLESMC_DATA_PORT))
+ if (port_send_byte(smc, key[i], APPLESMC_DATA_PORT))
return -EIO;
return 0;
}
-static int read_smc(struct applesmc_device *smc, u8 cmd, const char *key,
+static int port_read_smc(struct applesmc_device *smc, u8 cmd, const char *key,
u8 *buffer, u8 len)
{
u8 status, data = 0;
int i;
int ret;
- ret = smc_sane(smc);
+ ret = port_smc_sane(smc);
if (ret)
return ret;
- if (send_command(smc, cmd) || send_argument(smc, key)) {
+ if (port_send_command(smc, cmd) || port_send_argument(smc, key)) {
pr_warn("%.4s: read arg fail\n", key);
return -EIO;
}
/* This has no effect on newer (2012) SMCs */
- if (send_byte(smc, len, APPLESMC_DATA_PORT)) {
+ if (port_send_byte(smc, len, APPLESMC_DATA_PORT)) {
pr_warn("%.4s: read len fail\n", key);
return -EIO;
}
for (i = 0; i < len; i++) {
- if (wait_status(smc,
+ if (port_wait_status(smc,
SMC_STATUS_AWAITING_DATA | SMC_STATUS_BUSY,
SMC_STATUS_AWAITING_DATA | SMC_STATUS_BUSY)) {
pr_warn("%.4s: read data[%d] fail\n", key, i);
@@ -298,37 +299,80 @@ static int read_smc(struct applesmc_device *smc, u8 cmd, const char *key,
if (i)
pr_warn("flushed %d bytes, last value is: %d\n", i, data);
- return wait_status(smc, 0, SMC_STATUS_BUSY);
+ return port_wait_status(smc, 0, SMC_STATUS_BUSY);
}
-static int write_smc(struct applesmc_device *smc, u8 cmd, const char *key,
+static int port_write_smc(struct applesmc_device *smc, u8 cmd, const char *key,
const u8 *buffer, u8 len)
{
int i;
int ret;
- ret = smc_sane(smc);
+ ret = port_smc_sane(smc);
if (ret)
return ret;
- if (send_command(smc, cmd) || send_argument(smc, key)) {
+ if (port_send_command(smc, cmd) || port_send_argument(smc, key)) {
pr_warn("%s: write arg fail\n", key);
return -EIO;
}
- if (send_byte(smc, len, APPLESMC_DATA_PORT)) {
+ if (port_send_byte(smc, len, APPLESMC_DATA_PORT)) {
pr_warn("%.4s: write len fail\n", key);
return -EIO;
}
for (i = 0; i < len; i++) {
- if (send_byte(smc, buffer[i], APPLESMC_DATA_PORT)) {
+ if (port_send_byte(smc, buffer[i], APPLESMC_DATA_PORT)) {
pr_warn("%s: write data fail\n", key);
return -EIO;
}
}
- return wait_status(smc, 0, SMC_STATUS_BUSY);
+ return port_wait_status(smc, 0, SMC_STATUS_BUSY);
+}
+
+static int port_get_smc_key_info(struct applesmc_device *smc,
+ const char *key, struct applesmc_entry *info)
+{
+ int ret;
+ u8 raw[6];
+
+ ret = port_read_smc(smc, APPLESMC_GET_KEY_TYPE_CMD, key, raw, 6);
+ if (ret)
+ return ret;
+ info->len = raw[0];
+ memcpy(info->type, &raw[1], 4);
+ info->flags = raw[5];
+ return 0;
+}
+
+static int read_smc(struct applesmc_device *smc, const char *key,
+ u8 *buffer, u8 len)
+{
+ return port_read_smc(smc, APPLESMC_READ_CMD, key, buffer, len);
+}
+
+static int write_smc(struct applesmc_device *smc, const char *key,
+ const u8 *buffer, u8 len)
+{
+ return port_write_smc(smc, APPLESMC_WRITE_CMD, key, buffer, len);
+}
+
+static int get_smc_key_by_index(struct applesmc_device *smc,
+ unsigned int index, char *key)
+{
+ __be32 be;
+
+ be = cpu_to_be32(index);
+ return port_read_smc(smc, APPLESMC_GET_KEY_BY_INDEX_CMD,
+ (const char *) &be, (u8 *) key, 4);
+}
+
+static int get_smc_key_info(struct applesmc_device *smc, const char *key,
+ struct applesmc_entry *info)
+{
+ return port_get_smc_key_info(smc, key, info);
}
static int read_register_count(struct applesmc_device *smc,
@@ -337,8 +381,8 @@ static int read_register_count(struct applesmc_device *smc,
__be32 be;
int ret;
- ret = read_smc(smc, APPLESMC_READ_CMD, KEY_COUNT_KEY, (u8 *)&be, 4);
- if (ret)
+ ret = read_smc(smc, KEY_COUNT_KEY, (u8 *)&be, 4);
+ if (ret < 0)
return ret;
*count = be32_to_cpu(be);
@@ -360,7 +404,7 @@ static int applesmc_read_entry(struct applesmc_device *smc,
if (entry->len != len)
return -EINVAL;
mutex_lock(&smc->reg.mutex);
- ret = read_smc(smc, APPLESMC_READ_CMD, entry->key, buf, len);
+ ret = read_smc(smc, entry->key, buf, len);
mutex_unlock(&smc->reg.mutex);
return ret;
@@ -374,7 +418,7 @@ static int applesmc_write_entry(struct applesmc_device *smc,
if (entry->len != len)
return -EINVAL;
mutex_lock(&smc->reg.mutex);
- ret = write_smc(smc, APPLESMC_WRITE_CMD, entry->key, buf, len);
+ ret = write_smc(smc, entry->key, buf, len);
mutex_unlock(&smc->reg.mutex);
return ret;
}
@@ -383,8 +427,7 @@ static const struct applesmc_entry *applesmc_get_entry_by_index(
struct applesmc_device *smc, int index)
{
struct applesmc_entry *cache = &smc->reg.cache[index];
- u8 key[4], info[6];
- __be32 be;
+ char key[4];
int ret = 0;
if (cache->valid)
@@ -394,18 +437,14 @@ static const struct applesmc_entry *applesmc_get_entry_by_index(
if (cache->valid)
goto out;
- be = cpu_to_be32(index);
- ret = read_smc(smc, APPLESMC_GET_KEY_BY_INDEX_CMD, (u8 *)&be, key, 4);
+ ret = get_smc_key_by_index(smc, index, key);
if (ret)
goto out;
- ret = read_smc(smc, APPLESMC_GET_KEY_TYPE_CMD, key, info, 6);
+ memcpy(cache->key, key, 4);
+
+ ret = get_smc_key_info(smc, key, cache);
if (ret)
goto out;
-
- memcpy(cache->key, key, 4);
- cache->len = info[0];
- memcpy(cache->type, &info[1], 4);
- cache->flags = info[5];
cache->valid = true;
out:
--
Armbian

View File

@@ -0,0 +1,343 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Aun-Ali Zaidi <admin@kodeit.net>
Date: Sun, 17 Nov 2019 23:12:16 +0100
Subject: applesmc: basic mmio interface implementation
This change introduces a basic MMIO-based
interface implementation required to communicate
with the SMC on T2 Macs. The MMIO interface is
enabled only when it's supported on the running
system.
The MMIO interface replaces legacy port-based SMC
key reads, writes and metadata requests (getting
key by index and getting key info).
(Based on patch by @mcmrarm)
Signed-off-by: Aun-Ali Zaidi <admin@kodeit.net>
---
drivers/hwmon/applesmc.c | 237 +++++++++-
1 file changed, 231 insertions(+), 6 deletions(-)
diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c
index 111111111111..222222222222 100644
--- a/drivers/hwmon/applesmc.c
+++ b/drivers/hwmon/applesmc.c
@@ -42,6 +42,18 @@
#define APPLESMC_NR_PORTS 32 /* 0x300-0x31f */
+#define APPLESMC_IOMEM_KEY_DATA 0
+#define APPLESMC_IOMEM_KEY_STATUS 0x4005
+#define APPLESMC_IOMEM_KEY_NAME 0x78
+#define APPLESMC_IOMEM_KEY_DATA_LEN 0x7D
+#define APPLESMC_IOMEM_KEY_SMC_ID 0x7E
+#define APPLESMC_IOMEM_KEY_CMD 0x7F
+#define APPLESMC_IOMEM_MIN_SIZE 0x4006
+
+#define APPLESMC_IOMEM_KEY_TYPE_CODE 0
+#define APPLESMC_IOMEM_KEY_TYPE_DATA_LEN 5
+#define APPLESMC_IOMEM_KEY_TYPE_FLAGS 6
+
#define APPLESMC_MAX_DATA_LENGTH 32
/* Apple SMC status bits */
@@ -138,10 +150,13 @@ struct applesmc_registers {
struct applesmc_device {
struct acpi_device *dev;
+ struct device *ldev;
struct applesmc_registers reg;
- bool port_base_set;
+ bool port_base_set, iomem_base_set;
u16 port_base;
+ u8 *__iomem iomem_base;
+ u32 iomem_base_addr, iomem_base_size;
s16 rest_x;
s16 rest_y;
@@ -347,16 +362,156 @@ static int port_get_smc_key_info(struct applesmc_device *smc,
return 0;
}
+
+/*
+ * MMIO based communication.
+ * TODO: Use updated mechanism for cmd timeout/retry
+ */
+
+static void iomem_clear_status(struct applesmc_device *smc)
+{
+ if (ioread8(smc->iomem_base + APPLESMC_IOMEM_KEY_STATUS))
+ iowrite8(0, smc->iomem_base + APPLESMC_IOMEM_KEY_STATUS);
+}
+
+static int iomem_wait_read(struct applesmc_device *smc)
+{
+ u8 status;
+ int us;
+ int i;
+
+ us = APPLESMC_MIN_WAIT;
+ for (i = 0; i < 24 ; i++) {
+ status = ioread8(smc->iomem_base + APPLESMC_IOMEM_KEY_STATUS);
+ if (status & 0x20)
+ return 0;
+ usleep_range(us, us * 2);
+ if (i > 9)
+ us <<= 1;
+ }
+
+ dev_warn(smc->ldev, "%s... timeout\n", __func__);
+ return -EIO;
+}
+
+static int iomem_read_smc(struct applesmc_device *smc, u8 cmd, const char *key,
+ u8 *buffer, u8 len)
+{
+ u8 err, remote_len;
+ u32 key_int = *((u32 *) key);
+
+ iomem_clear_status(smc);
+ iowrite32(key_int, smc->iomem_base + APPLESMC_IOMEM_KEY_NAME);
+ iowrite32(0, smc->iomem_base + APPLESMC_IOMEM_KEY_SMC_ID);
+ iowrite32(cmd, smc->iomem_base + APPLESMC_IOMEM_KEY_CMD);
+
+ if (iomem_wait_read(smc))
+ return -EIO;
+
+ err = ioread8(smc->iomem_base + APPLESMC_IOMEM_KEY_CMD);
+ if (err != 0) {
+ dev_warn(smc->ldev, "read_smc_mmio(%x %8x/%.4s) failed: %u\n",
+ cmd, key_int, key, err);
+ return -EIO;
+ }
+
+ if (cmd == APPLESMC_READ_CMD) {
+ remote_len = ioread8(smc->iomem_base + APPLESMC_IOMEM_KEY_DATA_LEN);
+ if (remote_len != len) {
+ dev_warn(smc->ldev,
+ "read_smc_mmio(%x %8x/%.4s) failed: buffer length mismatch (remote = %u, requested = %u)\n",
+ cmd, key_int, key, remote_len, len);
+ return -EINVAL;
+ }
+ } else {
+ remote_len = len;
+ }
+
+ memcpy_fromio(buffer, smc->iomem_base + APPLESMC_IOMEM_KEY_DATA,
+ remote_len);
+
+ dev_dbg(smc->ldev, "read_smc_mmio(%x %8x/%.4s): buflen=%u reslen=%u\n",
+ cmd, key_int, key, len, remote_len);
+ print_hex_dump_bytes("read_smc_mmio(): ", DUMP_PREFIX_NONE, buffer, remote_len);
+ return 0;
+}
+
+static int iomem_get_smc_key_type(struct applesmc_device *smc, const char *key,
+ struct applesmc_entry *e)
+{
+ u8 err;
+ u8 cmd = APPLESMC_GET_KEY_TYPE_CMD;
+ u32 key_int = *((u32 *) key);
+
+ iomem_clear_status(smc);
+ iowrite32(key_int, smc->iomem_base + APPLESMC_IOMEM_KEY_NAME);
+ iowrite32(0, smc->iomem_base + APPLESMC_IOMEM_KEY_SMC_ID);
+ iowrite32(cmd, smc->iomem_base + APPLESMC_IOMEM_KEY_CMD);
+
+ if (iomem_wait_read(smc))
+ return -EIO;
+
+ err = ioread8(smc->iomem_base + APPLESMC_IOMEM_KEY_CMD);
+ if (err != 0) {
+ dev_warn(smc->ldev, "get_smc_key_type_mmio(%.4s) failed: %u\n", key, err);
+ return -EIO;
+ }
+
+ e->len = ioread8(smc->iomem_base + APPLESMC_IOMEM_KEY_TYPE_DATA_LEN);
+ *((uint32_t *) e->type) = ioread32(
+ smc->iomem_base + APPLESMC_IOMEM_KEY_TYPE_CODE);
+ e->flags = ioread8(smc->iomem_base + APPLESMC_IOMEM_KEY_TYPE_FLAGS);
+
+ dev_dbg(smc->ldev, "get_smc_key_type_mmio(%.4s): len=%u type=%.4s flags=%x\n",
+ key, e->len, e->type, e->flags);
+ return 0;
+}
+
+static int iomem_write_smc(struct applesmc_device *smc, u8 cmd, const char *key,
+ const u8 *buffer, u8 len)
+{
+ u8 err;
+ u32 key_int = *((u32 *) key);
+
+ iomem_clear_status(smc);
+ iowrite32(key_int, smc->iomem_base + APPLESMC_IOMEM_KEY_NAME);
+ memcpy_toio(smc->iomem_base + APPLESMC_IOMEM_KEY_DATA, buffer, len);
+ iowrite32(len, smc->iomem_base + APPLESMC_IOMEM_KEY_DATA_LEN);
+ iowrite32(0, smc->iomem_base + APPLESMC_IOMEM_KEY_SMC_ID);
+ iowrite32(cmd, smc->iomem_base + APPLESMC_IOMEM_KEY_CMD);
+
+ if (iomem_wait_read(smc))
+ return -EIO;
+
+ err = ioread8(smc->iomem_base + APPLESMC_IOMEM_KEY_CMD);
+ if (err != 0) {
+ dev_warn(smc->ldev, "write_smc_mmio(%x %.4s) failed: %u\n", cmd, key, err);
+ print_hex_dump_bytes("write_smc_mmio(): ", DUMP_PREFIX_NONE, buffer, len);
+ return -EIO;
+ }
+
+ dev_dbg(smc->ldev, "write_smc_mmio(%x %.4s): buflen=%u\n", cmd, key, len);
+ print_hex_dump_bytes("write_smc_mmio(): ", DUMP_PREFIX_NONE, buffer, len);
+ return 0;
+}
+
+
static int read_smc(struct applesmc_device *smc, const char *key,
u8 *buffer, u8 len)
{
- return port_read_smc(smc, APPLESMC_READ_CMD, key, buffer, len);
+ if (smc->iomem_base_set)
+ return iomem_read_smc(smc, APPLESMC_READ_CMD, key, buffer, len);
+ else
+ return port_read_smc(smc, APPLESMC_READ_CMD, key, buffer, len);
}
static int write_smc(struct applesmc_device *smc, const char *key,
const u8 *buffer, u8 len)
{
- return port_write_smc(smc, APPLESMC_WRITE_CMD, key, buffer, len);
+ if (smc->iomem_base_set)
+ return iomem_write_smc(smc, APPLESMC_WRITE_CMD, key, buffer, len);
+ else
+ return port_write_smc(smc, APPLESMC_WRITE_CMD, key, buffer, len);
}
static int get_smc_key_by_index(struct applesmc_device *smc,
@@ -365,14 +520,21 @@ static int get_smc_key_by_index(struct applesmc_device *smc,
__be32 be;
be = cpu_to_be32(index);
- return port_read_smc(smc, APPLESMC_GET_KEY_BY_INDEX_CMD,
- (const char *) &be, (u8 *) key, 4);
+ if (smc->iomem_base_set)
+ return iomem_read_smc(smc, APPLESMC_GET_KEY_BY_INDEX_CMD,
+ (const char *) &be, (u8 *) key, 4);
+ else
+ return port_read_smc(smc, APPLESMC_GET_KEY_BY_INDEX_CMD,
+ (const char *) &be, (u8 *) key, 4);
}
static int get_smc_key_info(struct applesmc_device *smc, const char *key,
struct applesmc_entry *info)
{
- return port_get_smc_key_info(smc, key, info);
+ if (smc->iomem_base_set)
+ return iomem_get_smc_key_type(smc, key, info);
+ else
+ return port_get_smc_key_info(smc, key, info);
}
static int read_register_count(struct applesmc_device *smc,
@@ -746,6 +908,7 @@ static int applesmc_add(struct acpi_device *dev)
if (!smc)
return -ENOMEM;
smc->dev = dev;
+ smc->ldev = &dev->dev;
mutex_init(&smc->reg.mutex);
dev_set_drvdata(&dev->dev, smc);
@@ -807,6 +970,20 @@ static acpi_status applesmc_walk_resources(struct acpi_resource *res,
}
return AE_OK;
+ case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
+ if (!smc->iomem_base_set) {
+ if (res->data.fixed_memory32.address_length <
+ APPLESMC_IOMEM_MIN_SIZE) {
+ dev_warn(smc->ldev, "found iomem but it's too small: %u\n",
+ res->data.fixed_memory32.address_length);
+ return AE_OK;
+ }
+ smc->iomem_base_addr = res->data.fixed_memory32.address;
+ smc->iomem_base_size = res->data.fixed_memory32.address_length;
+ smc->iomem_base_set = true;
+ }
+ return AE_OK;
+
case ACPI_RESOURCE_TYPE_END_TAG:
if (smc->port_base_set)
return AE_OK;
@@ -818,6 +995,8 @@ static acpi_status applesmc_walk_resources(struct acpi_resource *res,
}
}
+static int applesmc_try_enable_iomem(struct applesmc_device *smc);
+
static int applesmc_init_resources(struct applesmc_device *smc)
{
int ret;
@@ -830,11 +1009,57 @@ static int applesmc_init_resources(struct applesmc_device *smc)
if (!request_region(smc->port_base, APPLESMC_NR_PORTS, "applesmc"))
return -ENXIO;
+ if (smc->iomem_base_set) {
+ if (applesmc_try_enable_iomem(smc))
+ smc->iomem_base_set = false;
+ }
+
return 0;
}
+static int applesmc_try_enable_iomem(struct applesmc_device *smc)
+{
+ u8 test_val, ldkn_version;
+
+ dev_dbg(smc->ldev, "Trying to enable iomem based communication\n");
+ smc->iomem_base = ioremap(smc->iomem_base_addr, smc->iomem_base_size);
+ if (!smc->iomem_base)
+ goto out;
+
+ /* Apple's driver does this check for some reason */
+ test_val = ioread8(smc->iomem_base + APPLESMC_IOMEM_KEY_STATUS);
+ if (test_val == 0xff) {
+ dev_warn(smc->ldev,
+ "iomem enable failed: initial status is 0xff (is %x)\n",
+ test_val);
+ goto out_iomem;
+ }
+
+ if (read_smc(smc, "LDKN", &ldkn_version, 1)) {
+ dev_warn(smc->ldev, "iomem enable failed: ldkn read failed\n");
+ goto out_iomem;
+ }
+
+ if (ldkn_version < 2) {
+ dev_warn(smc->ldev,
+ "iomem enable failed: ldkn version %u is less than minimum (2)\n",
+ ldkn_version);
+ goto out_iomem;
+ }
+
+ return 0;
+
+out_iomem:
+ iounmap(smc->iomem_base);
+
+out:
+ return -ENXIO;
+}
+
static void applesmc_free_resources(struct applesmc_device *smc)
{
+ if (smc->iomem_base_set)
+ iounmap(smc->iomem_base);
release_region(smc->port_base, APPLESMC_NR_PORTS);
}
--
Armbian

View File

@@ -0,0 +1,227 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Paul Pawlowski <paul@mrarm.io>
Date: Sun, 17 Nov 2019 23:12:18 +0100
Subject: applesmc: fan support on T2 Macs
T2 Macs changed the fan values from shorts to
floats, and changed the fan manual override
setting from a bitmask to a per-fan boolean
named F0Md (thanks to @kleuter for mentioning
it).
A minimal soft-float implementation has been
written for convert floats to integers (and vice
versa).
Signed-off-by: Aun-Ali Zaidi <admin@kodeit.net>
---
drivers/hwmon/applesmc.c | 119 ++++++++--
1 file changed, 102 insertions(+), 17 deletions(-)
diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c
index 111111111111..222222222222 100644
--- a/drivers/hwmon/applesmc.c
+++ b/drivers/hwmon/applesmc.c
@@ -87,6 +87,7 @@
#define FAN_ID_FMT "F%dID" /* r-o char[16] */
#define TEMP_SENSOR_TYPE "sp78"
+#define FLOAT_TYPE "flt "
/* List of keys used to read/write fan speeds */
static const char *const fan_speed_fmt[] = {
@@ -96,6 +97,7 @@ static const char *const fan_speed_fmt[] = {
"F%dSf", /* safe speed - not all models */
"F%dTg", /* target speed (manual: rw) */
};
+#define FAN_MANUAL_FMT "F%dMd"
#define INIT_TIMEOUT_MSECS 5000 /* wait up to 5s for device init ... */
#define INIT_WAIT_MSECS 50 /* ... in 50ms increments */
@@ -734,6 +736,42 @@ static int applesmc_read_s16(struct applesmc_device *smc,
return 0;
}
+/**
+ * applesmc_float_to_u32 - Retrieve the integral part of a float.
+ * This is needed because Apple made fans use float values in the T2.
+ * The fractional point is not significantly useful though, and the integral
+ * part can be easily extracted.
+ */
+static inline u32 applesmc_float_to_u32(u32 d)
+{
+ u8 sign = (u8) ((d >> 31) & 1);
+ s32 exp = (s32) ((d >> 23) & 0xff) - 0x7f;
+ u32 fr = d & ((1u << 23) - 1);
+
+ if (sign || exp < 0)
+ return 0;
+
+ return (u32) ((1u << exp) + (fr >> (23 - exp)));
+}
+
+/**
+ * applesmc_u32_to_float - Convert an u32 into a float.
+ * See applesmc_float_to_u32 for a rationale.
+ */
+static inline u32 applesmc_u32_to_float(u32 d)
+{
+ u32 dc = d, bc = 0, exp;
+
+ if (!d)
+ return 0;
+
+ while (dc >>= 1)
+ ++bc;
+ exp = 0x7f + bc;
+
+ return (u32) ((exp << 23) |
+ ((d << (23 - (exp - 0x7f))) & ((1u << 23) - 1)));
+}
/*
* applesmc_device_init - initialize the accelerometer. Can sleep.
*/
@@ -1241,6 +1279,7 @@ static ssize_t applesmc_show_fan_speed(struct device *dev,
struct device_attribute *attr, char *sysfsbuf)
{
struct applesmc_device *smc = dev_get_drvdata(dev);
+ const struct applesmc_entry *entry;
int ret;
unsigned int speed = 0;
char newkey[5];
@@ -1249,11 +1288,21 @@ static ssize_t applesmc_show_fan_speed(struct device *dev,
scnprintf(newkey, sizeof(newkey), fan_speed_fmt[to_option(attr)],
to_index(attr));
- ret = applesmc_read_key(smc, newkey, buffer, 2);
+ entry = applesmc_get_entry_by_key(smc, newkey);
+ if (IS_ERR(entry))
+ return PTR_ERR(entry);
+
+ if (!strcmp(entry->type, FLOAT_TYPE)) {
+ ret = applesmc_read_entry(smc, entry, (u8 *) &speed, 4);
+ speed = applesmc_float_to_u32(speed);
+ } else {
+ ret = applesmc_read_entry(smc, entry, buffer, 2);
+ speed = ((buffer[0] << 8 | buffer[1]) >> 2);
+ }
+
if (ret)
return ret;
- speed = ((buffer[0] << 8 | buffer[1]) >> 2);
return sysfs_emit(sysfsbuf, "%u\n", speed);
}
@@ -1262,6 +1311,7 @@ static ssize_t applesmc_store_fan_speed(struct device *dev,
const char *sysfsbuf, size_t count)
{
struct applesmc_device *smc = dev_get_drvdata(dev);
+ const struct applesmc_entry *entry;
int ret;
unsigned long speed;
char newkey[5];
@@ -1273,9 +1323,18 @@ static ssize_t applesmc_store_fan_speed(struct device *dev,
scnprintf(newkey, sizeof(newkey), fan_speed_fmt[to_option(attr)],
to_index(attr));
- buffer[0] = (speed >> 6) & 0xff;
- buffer[1] = (speed << 2) & 0xff;
- ret = applesmc_write_key(smc, newkey, buffer, 2);
+ entry = applesmc_get_entry_by_key(smc, newkey);
+ if (IS_ERR(entry))
+ return PTR_ERR(entry);
+
+ if (!strcmp(entry->type, FLOAT_TYPE)) {
+ speed = applesmc_u32_to_float(speed);
+ ret = applesmc_write_entry(smc, entry, (u8 *) &speed, 4);
+ } else {
+ buffer[0] = (speed >> 6) & 0xff;
+ buffer[1] = (speed << 2) & 0xff;
+ ret = applesmc_write_key(smc, newkey, buffer, 2);
+ }
if (ret)
return ret;
@@ -1290,12 +1349,26 @@ static ssize_t applesmc_show_fan_manual(struct device *dev,
int ret;
u16 manual = 0;
u8 buffer[2];
+ char newkey[5];
+ bool has_newkey = false;
+
+ scnprintf(newkey, sizeof(newkey), FAN_MANUAL_FMT, to_index(attr));
+
+ ret = applesmc_has_key(smc, newkey, &has_newkey);
+ if (ret)
+ return ret;
+
+ if (has_newkey) {
+ ret = applesmc_read_key(smc, newkey, buffer, 1);
+ manual = buffer[0];
+ } else {
+ ret = applesmc_read_key(smc, FANS_MANUAL, buffer, 2);
+ manual = ((buffer[0] << 8 | buffer[1]) >> to_index(attr)) & 0x01;
+ }
- ret = applesmc_read_key(smc, FANS_MANUAL, buffer, 2);
if (ret)
return ret;
- manual = ((buffer[0] << 8 | buffer[1]) >> to_index(attr)) & 0x01;
return sysfs_emit(sysfsbuf, "%d\n", manual);
}
@@ -1306,27 +1379,39 @@ static ssize_t applesmc_store_fan_manual(struct device *dev,
struct applesmc_device *smc = dev_get_drvdata(dev);
int ret;
u8 buffer[2];
+ char newkey[5];
+ bool has_newkey = false;
unsigned long input;
u16 val;
if (kstrtoul(sysfsbuf, 10, &input) < 0)
return -EINVAL;
- ret = applesmc_read_key(smc, FANS_MANUAL, buffer, 2);
+ scnprintf(newkey, sizeof(newkey), FAN_MANUAL_FMT, to_index(attr));
+
+ ret = applesmc_has_key(smc, newkey, &has_newkey);
if (ret)
- goto out;
+ return ret;
- val = (buffer[0] << 8 | buffer[1]);
+ if (has_newkey) {
+ buffer[0] = input & 1;
+ ret = applesmc_write_key(smc, newkey, buffer, 1);
+ } else {
+ ret = applesmc_read_key(smc, FANS_MANUAL, buffer, 2);
+ val = (buffer[0] << 8 | buffer[1]);
+ if (ret)
+ goto out;
- if (input)
- val = val | (0x01 << to_index(attr));
- else
- val = val & ~(0x01 << to_index(attr));
+ if (input)
+ val = val | (0x01 << to_index(attr));
+ else
+ val = val & ~(0x01 << to_index(attr));
- buffer[0] = (val >> 8) & 0xFF;
- buffer[1] = val & 0xFF;
+ buffer[0] = (val >> 8) & 0xFF;
+ buffer[1] = val & 0xFF;
- ret = applesmc_write_key(smc, FANS_MANUAL, buffer, 2);
+ ret = applesmc_write_key(smc, FANS_MANUAL, buffer, 2);
+ }
out:
if (ret)
--
Armbian

View File

@@ -0,0 +1,31 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Orlando Chamberlain <redecorating@protonmail.com>
Date: Sun, 9 Oct 2022 15:59:01 +0530
Subject: applesmc: Add iMacPro to applesmc_whitelist
The iMacPro1,1 is the only iMacPro released before the line was
discontinued. Add it to the applesmc_whitelist.
Signed-off-by: Orlando Chamberlain <redecorating@protonmail.com>
---
drivers/hwmon/applesmc.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c
index 111111111111..222222222222 100644
--- a/drivers/hwmon/applesmc.c
+++ b/drivers/hwmon/applesmc.c
@@ -1803,6 +1803,10 @@ static const struct dmi_system_id applesmc_whitelist[] __initconst = {
DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
DMI_MATCH(DMI_PRODUCT_NAME, "Macmini") },
},
+ { applesmc_dmi_match, "Apple iMacPro", {
+ DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "iMacPro") },
+ },
{ applesmc_dmi_match, "Apple MacPro", {
DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
DMI_MATCH(DMI_PRODUCT_NAME, "MacPro") },
--
Armbian

View File

@@ -0,0 +1,35 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Orlando Chamberlain <orlandoch.dev@gmail.com>
Date: Tue, 24 Jan 2023 15:46:48 +1100
Subject: applesmc: make applesmc_remove void
for linux6.2 compatibility
---
drivers/hwmon/applesmc.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c
index 111111111111..222222222222 100644
--- a/drivers/hwmon/applesmc.c
+++ b/drivers/hwmon/applesmc.c
@@ -979,7 +979,7 @@ static int applesmc_add(struct acpi_device *dev)
return ret;
}
-static int applesmc_remove(struct acpi_device *dev)
+static void applesmc_remove(struct acpi_device *dev)
{
struct applesmc_device *smc = dev_get_drvdata(&dev->dev);
@@ -990,7 +990,7 @@ static int applesmc_remove(struct acpi_device *dev)
mutex_destroy(&smc->reg.mutex);
kfree(smc);
- return 0;
+ return;
}
static acpi_status applesmc_walk_resources(struct acpi_resource *res,
--
Armbian

View File

@@ -0,0 +1,96 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Orlando Chamberlain <orlandoch.dev@gmail.com>
Date: Mon, 30 Jan 2023 18:42:21 +1100
Subject: applesmc: battery charge limiter
---
drivers/hwmon/applesmc.c | 42 +++++++++-
1 file changed, 41 insertions(+), 1 deletion(-)
diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c
index 111111111111..222222222222 100644
--- a/drivers/hwmon/applesmc.c
+++ b/drivers/hwmon/applesmc.c
@@ -1477,6 +1477,35 @@ static void applesmc_brightness_set(struct led_classdev *led_cdev,
dev_dbg(led_cdev->dev, "work was already on the queue.\n");
}
+static ssize_t applesmc_BCLM_store(struct device *dev,
+ struct device_attribute *attr, char *sysfsbuf, size_t count)
+{
+ struct applesmc_device *smc = dev_get_drvdata(dev);
+ u8 val;
+
+ if (kstrtou8(sysfsbuf, 10, &val) < 0)
+ return -EINVAL;
+
+ if (val < 0 || val > 100)
+ return -EINVAL;
+
+ if (applesmc_write_key(smc, "BCLM", &val, 1))
+ return -ENODEV;
+ return count;
+}
+
+static ssize_t applesmc_BCLM_show(struct device *dev,
+ struct device_attribute *attr, char *sysfsbuf)
+{
+ struct applesmc_device *smc = dev_get_drvdata(dev);
+ u8 val;
+
+ if (applesmc_read_key(smc, "BCLM", &val, 1))
+ return -ENODEV;
+
+ return sysfs_emit(sysfsbuf, "%d\n", val);
+}
+
static ssize_t applesmc_key_count_show(struct device *dev,
struct device_attribute *attr, char *sysfsbuf)
{
@@ -1611,6 +1640,11 @@ static struct applesmc_node_group temp_group[] = {
{ }
};
+static struct applesmc_node_group BCLM_group[] = {
+ { "battery_charge_limit", applesmc_BCLM_show, applesmc_BCLM_store },
+ { }
+};
+
/* Module stuff */
/*
@@ -1829,10 +1863,13 @@ static int applesmc_create_modules(struct applesmc_device *smc)
ret = applesmc_create_nodes(smc, info_group, 1);
if (ret)
goto out;
+ ret = applesmc_create_nodes(smc, BCLM_group, 1);
+ if (ret)
+ goto out_info;
ret = applesmc_create_nodes(smc, fan_group, smc->reg.fan_count);
if (ret)
- goto out_info;
+ goto out_bclm;
ret = applesmc_create_nodes(smc, temp_group, smc->reg.index_count);
if (ret)
@@ -1868,6 +1905,8 @@ static int applesmc_create_modules(struct applesmc_device *smc)
applesmc_destroy_nodes(smc, temp_group);
out_fans:
applesmc_destroy_nodes(smc, fan_group);
+out_bclm:
+ applesmc_destroy_nodes(smc, BCLM_group);
out_info:
applesmc_destroy_nodes(smc, info_group);
out:
@@ -1882,6 +1921,7 @@ static void applesmc_destroy_modules(struct applesmc_device *smc)
applesmc_release_accelerometer(smc);
applesmc_destroy_nodes(smc, temp_group);
applesmc_destroy_nodes(smc, fan_group);
+ applesmc_destroy_nodes(smc, BCLM_group);
applesmc_destroy_nodes(smc, info_group);
}
--
Armbian

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,81 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Aditya Garg <gargaditya08@live.com>
Date: Fri, 12 Sep 2025 12:09:01 +0000
Subject: HID: apple: ignore the trackpad on T2 Macs
In order to manage the trackpad on T2 Macs by hid-magicmouse driver
we need to ensure that it is not bound by the hid-apple driver. Use
the existing APPLE_IGNORE_MOUSE quirk for the same.
Signed-off-by: Aditya Garg <gargaditya08@live.com>
---
drivers/hid/hid-apple.c | 27 ++++++----
1 file changed, 17 insertions(+), 10 deletions(-)
diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c
index 111111111111..222222222222 100644
--- a/drivers/hid/hid-apple.c
+++ b/drivers/hid/hid-apple.c
@@ -30,7 +30,7 @@
#include "hid-ids.h"
#define APPLE_RDESC_JIS BIT(0)
-/* BIT(1) reserved, was: APPLE_IGNORE_MOUSE */
+#define APPLE_IGNORE_MOUSE BIT(1)
#define APPLE_HAS_FN BIT(2)
/* BIT(3) reserved, was: APPLE_HIDDEV */
#define APPLE_ISO_TILDE_QUIRK BIT(4)
@@ -951,6 +951,9 @@ static int apple_probe(struct hid_device *hdev,
hdev->type != HID_TYPE_SPI_KEYBOARD)
return -ENODEV;
+ if (quirks & APPLE_IGNORE_MOUSE && hdev->type == HID_TYPE_USBMOUSE)
+ return -ENODEV;
+
asc = devm_kzalloc(&hdev->dev, sizeof(*asc), GFP_KERNEL);
if (asc == NULL) {
hid_err(hdev, "can't alloc apple descriptor\n");
@@ -1173,27 +1176,31 @@ static const struct hid_device_id apple_devices[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING9_JIS),
.driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J140K),
- .driver_data = APPLE_HAS_FN | APPLE_BACKLIGHT_CTL | APPLE_ISO_TILDE_QUIRK },
+ .driver_data = APPLE_HAS_FN | APPLE_BACKLIGHT_CTL | APPLE_ISO_TILDE_QUIRK |
+ APPLE_IGNORE_MOUSE },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J132),
.driver_data = APPLE_HAS_FN | APPLE_BACKLIGHT_CTL | APPLE_ISO_TILDE_QUIRK |
- APPLE_DISABLE_FKEYS },
+ APPLE_DISABLE_FKEYS | APPLE_IGNORE_MOUSE },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680),
.driver_data = APPLE_HAS_FN | APPLE_BACKLIGHT_CTL | APPLE_ISO_TILDE_QUIRK |
- APPLE_DISABLE_FKEYS },
+ APPLE_DISABLE_FKEYS | APPLE_IGNORE_MOUSE },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680_ALT),
.driver_data = APPLE_HAS_FN | APPLE_BACKLIGHT_CTL | APPLE_ISO_TILDE_QUIRK |
- APPLE_DISABLE_FKEYS },
+ APPLE_DISABLE_FKEYS | APPLE_IGNORE_MOUSE },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J213),
.driver_data = APPLE_HAS_FN | APPLE_BACKLIGHT_CTL | APPLE_ISO_TILDE_QUIRK |
- APPLE_DISABLE_FKEYS },
+ APPLE_DISABLE_FKEYS | APPLE_IGNORE_MOUSE },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J214K),
- .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK | APPLE_DISABLE_FKEYS },
+ .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK | APPLE_DISABLE_FKEYS |
+ APPLE_IGNORE_MOUSE },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J223),
- .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK | APPLE_DISABLE_FKEYS },
+ .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK | APPLE_DISABLE_FKEYS |
+ APPLE_IGNORE_MOUSE },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J230K),
- .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
+ .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK | APPLE_IGNORE_MOUSE },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J152F),
- .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK | APPLE_DISABLE_FKEYS },
+ .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK | APPLE_DISABLE_FKEYS |
+ APPLE_IGNORE_MOUSE },
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI),
.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO),
--
Armbian

View File

@@ -0,0 +1,417 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Aditya Garg <gargaditya08@live.com>
Date: Tue, 11 Mar 2025 18:44:06 +0530
Subject: HID: magicmouse: Add support for trackpads found on T2 Macs
This patch adds support for trackpads found on Macs with the T2
Security Chip. The touch report format differs from other trackpads.
It is the same format as type 4 in bcm5974.c
Signed-off-by: Aditya Garg <gargaditya08@live.com>
---
drivers/hid/hid-magicmouse.c | 296 +++++++++-
1 file changed, 275 insertions(+), 21 deletions(-)
diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c
index 111111111111..222222222222 100644
--- a/drivers/hid/hid-magicmouse.c
+++ b/drivers/hid/hid-magicmouse.c
@@ -118,6 +118,105 @@ MODULE_PARM_DESC(report_undeciphered, "Report undeciphered multi-touch state fie
#define TRACKPAD2_RES_Y \
((TRACKPAD2_MAX_Y - TRACKPAD2_MIN_Y) / (TRACKPAD2_DIMENSION_Y / 100))
+#define J140K_TP_DIMENSION_X (float)12100
+#define J140K_TP_MIN_X -5318
+#define J140K_TP_MAX_X 5787
+#define J140K_TP_RES_X \
+ ((J140K_TP_MAX_X - J140K_TP_MIN_X) / (J140K_TP_DIMENSION_X / 100))
+#define J140K_TP_DIMENSION_Y (float)8200
+#define J140K_TP_MIN_Y -157
+#define J140K_TP_MAX_Y 7102
+#define J140K_TP_RES_Y \
+ ((J140K_TP_MAX_Y - J140K_TP_MIN_Y) / (J140K_TP_DIMENSION_Y / 100))
+
+#define J132_TP_DIMENSION_X (float)13500
+#define J132_TP_MIN_X -6243
+#define J132_TP_MAX_X 6749
+#define J132_TP_RES_X \
+ ((J132_TP_MAX_X - J132_TP_MIN_X) / (J132_TP_DIMENSION_X / 100))
+#define J132_TP_DIMENSION_Y (float)8400
+#define J132_TP_MIN_Y -170
+#define J132_TP_MAX_Y 7685
+#define J132_TP_RES_Y \
+ ((J132_TP_MAX_Y - J132_TP_MIN_Y) / (J132_TP_DIMENSION_Y / 100))
+
+#define J680_TP_DIMENSION_X (float)16000
+#define J680_TP_MIN_X -7456
+#define J680_TP_MAX_X 7976
+#define J680_TP_RES_X \
+ ((J680_TP_MAX_X - J680_TP_MIN_X) / (J680_TP_DIMENSION_X / 100))
+#define J680_TP_DIMENSION_Y (float)10000
+#define J680_TP_MIN_Y -163
+#define J680_TP_MAX_Y 9283
+#define J680_TP_RES_Y \
+ ((J680_TP_MAX_Y - J680_TP_MIN_Y) / (J680_TP_DIMENSION_Y / 100))
+
+#define J680_ALT_TP_DIMENSION_X (float)16000
+#define J680_ALT_TP_MIN_X -7456
+#define J680_ALT_TP_MAX_X 7976
+#define J680_ALT_TP_RES_X \
+ ((J680_ALT_TP_MAX_X - J680_ALT_TP_MIN_X) / (J680_ALT_TP_DIMENSION_X / 100))
+#define J680_ALT_TP_DIMENSION_Y (float)10000
+#define J680_ALT_TP_MIN_Y -163
+#define J680_ALT_TP_MAX_Y 9283
+#define J680_ALT_TP_RES_Y \
+ ((J680_ALT_TP_MAX_Y - J680_ALT_TP_MIN_Y) / (J680_ALT_TP_DIMENSION_Y / 100))
+
+#define J213_TP_DIMENSION_X (float)13500
+#define J213_TP_MIN_X -6243
+#define J213_TP_MAX_X 6749
+#define J213_TP_RES_X \
+ ((J213_TP_MAX_X - J213_TP_MIN_X) / (J213_TP_DIMENSION_X / 100))
+#define J213_TP_DIMENSION_Y (float)8400
+#define J213_TP_MIN_Y -170
+#define J213_TP_MAX_Y 7685
+#define J213_TP_RES_Y \
+ ((J213_TP_MAX_Y - J213_TP_MIN_Y) / (J213_TP_DIMENSION_Y / 100))
+
+#define J214K_TP_DIMENSION_X (float)13200
+#define J214K_TP_MIN_X -6046
+#define J214K_TP_MAX_X 6536
+#define J214K_TP_RES_X \
+ ((J214K_TP_MAX_X - J214K_TP_MIN_X) / (J214K_TP_DIMENSION_X / 100))
+#define J214K_TP_DIMENSION_Y (float)8200
+#define J214K_TP_MIN_Y -164
+#define J214K_TP_MAX_Y 7439
+#define J214K_TP_RES_Y \
+ ((J214K_TP_MAX_Y - J214K_TP_MIN_Y) / (J214K_TP_DIMENSION_Y / 100))
+
+#define J223_TP_DIMENSION_X (float)13200
+#define J223_TP_MIN_X -6046
+#define J223_TP_MAX_X 6536
+#define J223_TP_RES_X \
+ ((J223_TP_MAX_X - J223_TP_MIN_X) / (J223_TP_DIMENSION_X / 100))
+#define J223_TP_DIMENSION_Y (float)8200
+#define J223_TP_MIN_Y -164
+#define J223_TP_MAX_Y 7439
+#define J223_TP_RES_Y \
+ ((J223_TP_MAX_Y - J223_TP_MIN_Y) / (J223_TP_DIMENSION_Y / 100))
+
+#define J230K_TP_DIMENSION_X (float)12100
+#define J230K_TP_MIN_X -5318
+#define J230K_TP_MAX_X 5787
+#define J230K_TP_RES_X \
+ ((J230K_TP_MAX_X - J230K_TP_MIN_X) / (J230K_TP_DIMENSION_X / 100))
+#define J230K_TP_DIMENSION_Y (float)8200
+#define J230K_TP_MIN_Y -157
+#define J230K_TP_MAX_Y 7102
+#define J230K_TP_RES_Y \
+ ((J230K_TP_MAX_Y - J230K_TP_MIN_Y) / (J230K_TP_DIMENSION_Y / 100))
+
+#define J152F_TP_DIMENSION_X (float)16000
+#define J152F_TP_MIN_X -7456
+#define J152F_TP_MAX_X 7976
+#define J152F_TP_RES_X \
+ ((J152F_TP_MAX_X - J152F_TP_MIN_X) / (J152F_TP_DIMENSION_X / 100))
+#define J152F_TP_DIMENSION_Y (float)10000
+#define J152F_TP_MIN_Y -163
+#define J152F_TP_MAX_Y 9283
+#define J152F_TP_RES_Y \
+ ((J152F_TP_MAX_Y - J152F_TP_MIN_Y) / (J152F_TP_DIMENSION_Y / 100))
+
/* These are fallback values, since the real values will be queried from the device. */
#define J314_TP_DIMENSION_X (float)13000
#define J314_TP_MIN_X -5900
@@ -130,7 +229,11 @@ MODULE_PARM_DESC(report_undeciphered, "Report undeciphered multi-touch state fie
#define J314_TP_RES_Y \
((J314_TP_MAX_Y - J314_TP_MIN_Y) / (J314_TP_DIMENSION_Y / 100))
-#define J314_TP_MAX_FINGER_ORIENTATION 16384
+#define T2_TOUCHPAD_ENTRY(model) \
+ { USB_DEVICE_ID_APPLE_WELLSPRINGT2_##model, model##_TP_MIN_X, model##_TP_MIN_Y, \
+model##_TP_MAX_X, model##_TP_MAX_Y, model##_TP_RES_X, model##_TP_RES_Y }
+
+#define INTERNAL_TP_MAX_FINGER_ORIENTATION 16384
struct magicmouse_input_ops {
int (*raw_event)(struct hid_device *hdev,
@@ -733,7 +836,7 @@ static void report_finger_data(struct input_dev *input, int slot,
input_report_abs(input, ABS_MT_WIDTH_MINOR,
le16_to_int(f->tool_minor) << 1);
input_report_abs(input, ABS_MT_ORIENTATION,
- J314_TP_MAX_FINGER_ORIENTATION - le16_to_int(f->orientation));
+ INTERNAL_TP_MAX_FINGER_ORIENTATION - le16_to_int(f->orientation));
input_report_abs(input, ABS_MT_PRESSURE, le16_to_int(f->pressure));
input_report_abs(input, ABS_MT_POSITION_X, pos->x);
input_report_abs(input, ABS_MT_POSITION_Y, pos->y);
@@ -821,6 +924,20 @@ static int magicmouse_raw_event_spi(struct hid_device *hdev,
return magicmouse_raw_event_mtp(hdev, report, data + hdr_sz, size - hdr_sz);
}
+static int magicmouse_raw_event_t2(struct hid_device *hdev,
+ struct hid_report *report, u8 *data, int size)
+{
+ const size_t hdr_sz = sizeof(struct tp_mouse_report);
+
+ if (!size)
+ return 0;
+
+ if (data[0] != TRACKPAD2_USB_REPORT_ID || size < hdr_sz)
+ return 0;
+
+ return magicmouse_raw_event_mtp(hdev, report, data + hdr_sz, size - hdr_sz);
+}
+
static int magicmouse_event(struct hid_device *hdev, struct hid_field *field,
struct hid_usage *usage, __s32 value)
{
@@ -1018,8 +1135,32 @@ static int magicmouse_setup_input_usb(struct input_dev *input,
return 0;
}
-static int magicmouse_setup_input_mtp(struct input_dev *input,
- struct hid_device *hdev)
+struct magicmouse_t2_properties {
+ u32 id;
+ int min_x;
+ int min_y;
+ int max_x;
+ int max_y;
+ int res_x;
+ int res_y;
+};
+
+static const struct magicmouse_t2_properties magicmouse_t2_configs[] = {
+ T2_TOUCHPAD_ENTRY(J140K),
+ T2_TOUCHPAD_ENTRY(J132),
+ T2_TOUCHPAD_ENTRY(J680),
+ T2_TOUCHPAD_ENTRY(J680_ALT),
+ T2_TOUCHPAD_ENTRY(J213),
+ T2_TOUCHPAD_ENTRY(J214K),
+ T2_TOUCHPAD_ENTRY(J223),
+ T2_TOUCHPAD_ENTRY(J230K),
+ T2_TOUCHPAD_ENTRY(J152F),
+};
+
+static int magicmouse_setup_input_int_tpd(struct input_dev *input,
+ struct hid_device *hdev, int min_x, int min_y,
+ int max_x, int max_y, int res_x, int res_y,
+ bool query_dimensions)
{
int error;
int mt_flags = 0;
@@ -1060,19 +1201,17 @@ static int magicmouse_setup_input_mtp(struct input_dev *input,
input_abs_set_res(input, ABS_MT_PRESSURE, 1);
/* finger orientation */
- input_set_abs_params(input, ABS_MT_ORIENTATION, -J314_TP_MAX_FINGER_ORIENTATION,
- J314_TP_MAX_FINGER_ORIENTATION, 0, 0);
+ input_set_abs_params(input, ABS_MT_ORIENTATION, -INTERNAL_TP_MAX_FINGER_ORIENTATION,
+ INTERNAL_TP_MAX_FINGER_ORIENTATION, 0, 0);
/* finger position */
- input_set_abs_params(input, ABS_MT_POSITION_X, J314_TP_MIN_X, J314_TP_MAX_X,
- 0, 0);
+ input_set_abs_params(input, ABS_MT_POSITION_X, min_x, max_x, 0, 0);
/* Y axis is inverted */
- input_set_abs_params(input, ABS_MT_POSITION_Y, -J314_TP_MAX_Y, -J314_TP_MIN_Y,
- 0, 0);
+ input_set_abs_params(input, ABS_MT_POSITION_Y, -max_y, -min_y, 0, 0);
/* X/Y resolution */
- input_abs_set_res(input, ABS_MT_POSITION_X, J314_TP_RES_X);
- input_abs_set_res(input, ABS_MT_POSITION_Y, J314_TP_RES_Y);
+ input_abs_set_res(input, ABS_MT_POSITION_X, res_x);
+ input_abs_set_res(input, ABS_MT_POSITION_Y, res_y);
input_set_events_per_packet(input, 60);
@@ -1099,7 +1238,20 @@ static int magicmouse_setup_input_mtp(struct input_dev *input,
*/
input->open = magicmouse_open;
input->close = magicmouse_close;
- msc->query_dimensions = true;
+ msc->query_dimensions = query_dimensions;
+
+ return 0;
+}
+
+static int magicmouse_setup_input_mtp(struct input_dev *input,
+ struct hid_device *hdev)
+{
+ int ret = magicmouse_setup_input_int_tpd(input, hdev, J314_TP_MIN_X,
+ J314_TP_MIN_Y, J314_TP_MAX_X,
+ J314_TP_MAX_Y, J314_TP_RES_X,
+ J314_TP_RES_Y, true);
+ if (ret)
+ return ret;
return 0;
}
@@ -1107,7 +1259,34 @@ static int magicmouse_setup_input_mtp(struct input_dev *input,
static int magicmouse_setup_input_spi(struct input_dev *input,
struct hid_device *hdev)
{
- int ret = magicmouse_setup_input_mtp(input, hdev);
+ int ret = magicmouse_setup_input_int_tpd(input, hdev, J314_TP_MIN_X,
+ J314_TP_MIN_Y, J314_TP_MAX_X,
+ J314_TP_MAX_Y, J314_TP_RES_X,
+ J314_TP_RES_Y, true);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static int magicmouse_setup_input_t2(struct input_dev *input,
+ struct hid_device *hdev)
+{
+ int min_x, min_y, max_x, max_y, res_x, res_y;
+
+ for (size_t i = 0; i < ARRAY_SIZE(magicmouse_t2_configs); i++) {
+ if (magicmouse_t2_configs[i].id == hdev->product) {
+ min_x = magicmouse_t2_configs[i].min_x;
+ min_y = magicmouse_t2_configs[i].min_y;
+ max_x = magicmouse_t2_configs[i].max_x;
+ max_y = magicmouse_t2_configs[i].max_y;
+ res_x = magicmouse_t2_configs[i].res_x;
+ res_y = magicmouse_t2_configs[i].res_y;
+ }
+ }
+
+ int ret = magicmouse_setup_input_int_tpd(input, hdev, min_x, min_y,
+ max_x, max_y, res_x, res_y, false);
if (ret)
return ret;
@@ -1180,6 +1359,18 @@ static int magicmouse_enable_multitouch(struct hid_device *hdev)
feature = feature_mt_trackpad2_usb;
}
break;
+ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J140K:
+ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J132:
+ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680:
+ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680_ALT:
+ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J213:
+ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J214K:
+ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J223:
+ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J230K:
+ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J152F:
+ feature_size = sizeof(feature_mt_trackpad2_usb);
+ feature = feature_mt_trackpad2_usb;
+ break;
case USB_DEVICE_ID_APPLE_MAGICMOUSE2:
case USB_DEVICE_ID_APPLE_MAGICMOUSE2_USBC:
feature_size = sizeof(feature_mt_mouse2);
@@ -1273,8 +1464,23 @@ static int magicmouse_probe(struct hid_device *hdev,
int ret;
if ((id->bus == BUS_SPI || id->bus == BUS_HOST) && id->vendor == SPI_VENDOR_ID_APPLE &&
- hdev->type != HID_TYPE_SPI_MOUSE)
- return -ENODEV;
+ hdev->type != HID_TYPE_SPI_MOUSE)
+ return -ENODEV;
+
+ switch (id->product) {
+ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J140K:
+ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J132:
+ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680:
+ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680_ALT:
+ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J213:
+ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J214K:
+ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J223:
+ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J230K:
+ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J152F:
+ if (hdev->type != HID_TYPE_USBMOUSE)
+ return -ENODEV;
+ break;
+ }
msc = devm_kzalloc(&hdev->dev, sizeof(*msc), GFP_KERNEL);
if (msc == NULL) {
@@ -1284,15 +1490,33 @@ static int magicmouse_probe(struct hid_device *hdev,
// internal trackpad use a data format use input ops to avoid
// conflicts with the report ID.
- if (id->bus == BUS_HOST) {
+ switch (id->bus) {
+ case BUS_HOST:
msc->input_ops.raw_event = magicmouse_raw_event_mtp;
msc->input_ops.setup_input = magicmouse_setup_input_mtp;
- } else if (id->bus == BUS_SPI) {
+ break;
+ case BUS_SPI:
msc->input_ops.raw_event = magicmouse_raw_event_spi;
msc->input_ops.setup_input = magicmouse_setup_input_spi;
- } else {
- msc->input_ops.raw_event = magicmouse_raw_event_usb;
- msc->input_ops.setup_input = magicmouse_setup_input_usb;
+ break;
+ default:
+ switch (id->product) {
+ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J140K:
+ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J132:
+ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680:
+ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680_ALT:
+ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J213:
+ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J214K:
+ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J223:
+ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J230K:
+ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J152F:
+ msc->input_ops.raw_event = magicmouse_raw_event_t2;
+ msc->input_ops.setup_input = magicmouse_setup_input_t2;
+ break;
+ default:
+ msc->input_ops.raw_event = magicmouse_raw_event_usb;
+ msc->input_ops.setup_input = magicmouse_setup_input_usb;
+ }
}
msc->scroll_accel = SCROLL_ACCEL_DEFAULT;
@@ -1353,6 +1577,18 @@ static int magicmouse_probe(struct hid_device *hdev,
TRACKPAD2_USB_REPORT_ID, 0);
}
break;
+ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J140K:
+ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J132:
+ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680:
+ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680_ALT:
+ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J213:
+ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J214K:
+ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J223:
+ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J230K:
+ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J152F:
+ report = hid_register_report(hdev, HID_INPUT_REPORT,
+ TRACKPAD2_USB_REPORT_ID, 0);
+ break;
case HID_ANY_ID:
switch (id->bus) {
case BUS_HOST:
@@ -1464,6 +1700,24 @@ static const struct hid_device_id magic_mice[] = {
USB_DEVICE_ID_APPLE_MAGICTRACKPAD2_USBC), .driver_data = 0 },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE,
USB_DEVICE_ID_APPLE_MAGICTRACKPAD2_USBC), .driver_data = 0 },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE,
+ USB_DEVICE_ID_APPLE_WELLSPRINGT2_J140K), .driver_data = 0 },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE,
+ USB_DEVICE_ID_APPLE_WELLSPRINGT2_J132), .driver_data = 0 },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE,
+ USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680), .driver_data = 0 },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE,
+ USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680_ALT), .driver_data = 0 },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE,
+ USB_DEVICE_ID_APPLE_WELLSPRINGT2_J213), .driver_data = 0 },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE,
+ USB_DEVICE_ID_APPLE_WELLSPRINGT2_J214K), .driver_data = 0 },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE,
+ USB_DEVICE_ID_APPLE_WELLSPRINGT2_J223), .driver_data = 0 },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE,
+ USB_DEVICE_ID_APPLE_WELLSPRINGT2_J230K), .driver_data = 0 },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE,
+ USB_DEVICE_ID_APPLE_WELLSPRINGT2_J152F), .driver_data = 0 },
{ HID_SPI_DEVICE(SPI_VENDOR_ID_APPLE, HID_ANY_ID),
.driver_data = 0 },
{ HID_DEVICE(BUS_HOST, HID_GROUP_ANY, HOST_VENDOR_ID_APPLE,
--
Armbian

View File

@@ -0,0 +1,53 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Aditya Garg <gargaditya08@live.com>
Date: Wed, 8 Oct 2025 01:48:18 +0000
Subject: HID: magicmouse: fix regression breaking support for Magic Trackpad 1
The case HID_ANY_ID and default are technically the same, but the first
one was assigning no report to the Magic Trackpad 1, while the second
one assigns the correct report. Since the first case is matched first,
the Magic Trackpad 1 was not being assigned any report, breaking
support for it.
Signed-off-by: Aditya Garg <gargaditya08@live.com>
---
drivers/hid/hid-magicmouse.c | 15 ++++------
1 file changed, 6 insertions(+), 9 deletions(-)
diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c
index 111111111111..222222222222 100644
--- a/drivers/hid/hid-magicmouse.c
+++ b/drivers/hid/hid-magicmouse.c
@@ -1589,7 +1589,7 @@ static int magicmouse_probe(struct hid_device *hdev,
report = hid_register_report(hdev, HID_INPUT_REPORT,
TRACKPAD2_USB_REPORT_ID, 0);
break;
- case HID_ANY_ID:
+ default:
switch (id->bus) {
case BUS_HOST:
report = hid_register_report(hdev, HID_INPUT_REPORT, MTP_REPORT_ID, 0);
@@ -1597,15 +1597,12 @@ static int magicmouse_probe(struct hid_device *hdev,
case BUS_SPI:
report = hid_register_report(hdev, HID_INPUT_REPORT, SPI_REPORT_ID, 0);
break;
- default:
- break;
+ default: /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */
+ report = hid_register_report(hdev, HID_INPUT_REPORT,
+ TRACKPAD_REPORT_ID, 0);
+ report = hid_register_report(hdev, HID_INPUT_REPORT,
+ DOUBLE_REPORT_ID, 0);
}
- break;
- default: /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */
- report = hid_register_report(hdev, HID_INPUT_REPORT,
- TRACKPAD_REPORT_ID, 0);
- report = hid_register_report(hdev, HID_INPUT_REPORT,
- DOUBLE_REPORT_ID, 0);
}
if (!report) {
--
Armbian

View File

@@ -0,0 +1,34 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Ashish Arora <ashisharora.linux@outlook.com>
Date: Sat, 8 Jan 2022 21:43:18 +1100
Subject: drm/i915: Discard large BIOS framebuffers causing display corruption
On certain 4k panels, the BIOS framebuffer is larger than what panel
requires causing display corruption. Introduce a check for the same.
Signed-off-by: Ashish Arora <ashisharora.linux@outlook.com>
---
drivers/gpu/drm/i915/display/intel_fbdev.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/i915/display/intel_fbdev.c b/drivers/gpu/drm/i915/display/intel_fbdev.c
index 111111111111..222222222222 100644
--- a/drivers/gpu/drm/i915/display/intel_fbdev.c
+++ b/drivers/gpu/drm/i915/display/intel_fbdev.c
@@ -224,10 +224,10 @@ int intel_fbdev_driver_fbdev_probe(struct drm_fb_helper *helper,
ifbdev->fb = NULL;
if (fb &&
- (sizes->fb_width > fb->base.width ||
- sizes->fb_height > fb->base.height)) {
+ (sizes->fb_width != fb->base.width ||
+ sizes->fb_height != fb->base.height)) {
drm_dbg_kms(display->drm,
- "BIOS fb too small (%dx%d), we require (%dx%d),"
+ "BIOS fb not valid (%dx%d), we require (%dx%d),"
" releasing it\n",
fb->base.width, fb->base.height,
sizes->fb_width, sizes->fb_height);
--
Armbian