mirror of
https://github.com/armbian/build.git
synced 2026-01-06 09:58:46 -08:00
uefi: x86: current (6.12) and edge (6.18): add Apple T2 patches
- from linux-t2 project: https://github.com/t2linux/linux-t2-patches - https://t2linux.org/ - x86: add .config hook `custom_kernel_config__applet2()` - original patches from t2linux for 6.18 and 6.12 - rewrite patches against v6.18-rc4 and v6.12.57 - `7001-drm-i915-fbdev-Discard-BIOS-framebuffers-exceeding-h.patch` needed special attention for correct patch attribution (missing From) - `1002-Put-apple-bce-in-drivers-staging` needs reordering to the top to avoid conflicts with EXTRAWIFI sed-based "patching"
This commit is contained in:
@@ -12,4 +12,58 @@ declare -g LINUXFAMILY="x86"
|
||||
declare -g ARCH="amd64"
|
||||
# shellcheck source=config/sources/families/include/uefi_common.inc
|
||||
source "${BASH_SOURCE%/*}/include/uefi_common.inc"
|
||||
|
||||
case "${BRANCH}" in
|
||||
|
||||
current | edge)
|
||||
display_alert "extra .config for Apple T2-based x86 machines" "x86: BRANCH=${BRANCH}" "info"
|
||||
|
||||
# Extra .config stuff for the Applet T2 stuff in this kernel
|
||||
function custom_kernel_config__applet2() {
|
||||
# From https://github.com/t2linux/linux-t2-patches/blob/6.18/extra_config ignore DRM_KUNIT_TEST
|
||||
opts_y+=(
|
||||
BT_HCIUART_BCM
|
||||
STAGING
|
||||
)
|
||||
opts_m+=(
|
||||
APPLE_BCE
|
||||
APPLE_GMUX
|
||||
BRCMFMAC
|
||||
BT_BCM
|
||||
BT_HCIBCM4377
|
||||
BT_HCIUART
|
||||
HID_APPLETB_BL
|
||||
HID_APPLETB_KBD
|
||||
HID_APPLE
|
||||
HID_MAGICMOUSE
|
||||
DRM_APPLETBDRM
|
||||
HID_SENSOR_ALS
|
||||
SENSORS_APPLESMC
|
||||
SND_PCM
|
||||
APFS_FS
|
||||
)
|
||||
}
|
||||
|
||||
# Auto-grab patches from t2linux github if not already present
|
||||
if [[ ! -d "${SRC}/patch/kernel/${KERNELPATCHDIR}" ]]; then
|
||||
# Grab from github .tar.gz and extract there; patches are in the root of the archive
|
||||
GH_URL="https://github.com/t2linux/linux-t2-patches/archive/refs/heads/${KERNEL_MAJOR_MINOR}.tar.gz"
|
||||
display_alert "Fetching Apple T2 patches from" "GH_URL=${GH_URL}" "info"
|
||||
mkdir -pv "${SRC}/patch/kernel/${KERNELPATCHDIR}"
|
||||
curl -L "${GH_URL}" | tar -xz --strip-components=1 -C "${SRC}/patch/kernel/${KERNELPATCHDIR}"
|
||||
tree "${SRC}/patch/kernel/${KERNELPATCHDIR}"
|
||||
# remove any non-patch files and directories
|
||||
# remove .github and .gitignore
|
||||
rm -rf "${SRC}/patch/kernel/${KERNELPATCHDIR}/.github" "${SRC}/patch/kernel/${KERNELPATCHDIR}/.gitignore"
|
||||
find "${SRC}/patch/kernel/${KERNELPATCHDIR}" -type f ! -name "*.patch" -delete
|
||||
display_alert "Apple T2 patches downloaded to" "DIR=${SRC}/patch/kernel/${KERNELPATCHDIR}; go run rewrite-kernel-patches" "info"
|
||||
exit 0
|
||||
else
|
||||
display_alert "Apple T2 patches already present in" "DIR=${SRC}/patch/kernel/${KERNELPATCHDIR}" "info"
|
||||
fi
|
||||
|
||||
;;
|
||||
|
||||
esac
|
||||
|
||||
enable_extension "grub"
|
||||
|
||||
5830
patch/kernel/archive/uefi-x86-6.12/1001-Add-apple-bce-driver.patch
Normal file
5830
patch/kernel/archive/uefi-x86-6.12/1001-Add-apple-bce-driver.patch
Normal file
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
@@ -66,4 +66,6 @@ source "drivers/staging/vme_user/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_FB_OLPC_DCON) += olpc_dcon/
|
||||
obj-$(CONFIG_RTL8192E) += rtl8192e/
|
||||
obj-$(CONFIG_RTL8723BS) += rtl8723bs/
|
||||
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
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aditya Garg <gargaditya08@live.com>
|
||||
Date: Sun, 13 Apr 2025 11:43:53 +0530
|
||||
Subject: Fix sparse errors
|
||||
|
||||
apple_bce.h was using #pragma once, which is not acceptable by sparse
|
||||
---
|
||||
drivers/staging/apple-bce/apple_bce.h | 7 +++++--
|
||||
1 file changed, 5 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/drivers/staging/apple-bce/apple_bce.h b/drivers/staging/apple-bce/apple_bce.h
|
||||
index 111111111111..222222222222 100644
|
||||
--- a/drivers/staging/apple-bce/apple_bce.h
|
||||
+++ b/drivers/staging/apple-bce/apple_bce.h
|
||||
@@ -1,4 +1,5 @@
|
||||
-#pragma once
|
||||
+#ifndef APPLE_BCE_H
|
||||
+#define APPLE_BCE_H
|
||||
|
||||
#include <linux/pci.h>
|
||||
#include <linux/spinlock.h>
|
||||
@@ -35,4 +36,6 @@ struct apple_bce_device {
|
||||
struct bce_vhci vhci;
|
||||
};
|
||||
|
||||
-extern struct apple_bce_device *global_bce;
|
||||
\ No newline at end of file
|
||||
+extern struct apple_bce_device *global_bce;
|
||||
+
|
||||
+#endif //APPLE_BCE_H
|
||||
--
|
||||
Armbian
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -0,0 +1,289 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Kerem Karabay <kekrby@gmail.com>
|
||||
Date: Sun, 5 Mar 2023 18:52:43 +0300
|
||||
Subject: HID: hid-appletb-bl: add driver for the backlight of Apple Touch Bars
|
||||
|
||||
This commit adds a driver for the backlight of Apple Touch Bars on x86
|
||||
Macs. Note that currently only T2 Macs are supported.
|
||||
|
||||
This driver is based on previous work done by Ronald Tschalar
|
||||
<ronald@innovation.ch>.
|
||||
|
||||
Signed-off-by: Kerem Karabay <kekrby@gmail.com>
|
||||
Co-developed-by: Aditya Garg <gargaditya08@live.com>
|
||||
Signed-off-by: Aditya Garg <gargaditya08@live.com>
|
||||
---
|
||||
drivers/hid/Kconfig | 10 +
|
||||
drivers/hid/Makefile | 1 +
|
||||
drivers/hid/hid-appletb-bl.c | 204 ++++++++++
|
||||
drivers/hid/hid-quirks.c | 4 +-
|
||||
4 files changed, 218 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
|
||||
index 111111111111..222222222222 100644
|
||||
--- a/drivers/hid/Kconfig
|
||||
+++ b/drivers/hid/Kconfig
|
||||
@@ -148,6 +148,16 @@ config HID_APPLEIR
|
||||
|
||||
Say Y here if you want support for Apple infrared remote control.
|
||||
|
||||
+config HID_APPLETB_BL
|
||||
+ tristate "Apple Touch Bar Backlight"
|
||||
+ depends on BACKLIGHT_CLASS_DEVICE
|
||||
+ help
|
||||
+ Say Y here if you want support for the backlight of Touch Bars on x86
|
||||
+ MacBook Pros.
|
||||
+
|
||||
+ To compile this driver as a module, choose M here: the
|
||||
+ module will be called hid-appletb-bl.
|
||||
+
|
||||
config HID_ASUS
|
||||
tristate "Asus"
|
||||
depends on USB_HID
|
||||
diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile
|
||||
index 111111111111..222222222222 100644
|
||||
--- a/drivers/hid/Makefile
|
||||
+++ b/drivers/hid/Makefile
|
||||
@@ -29,6 +29,7 @@ obj-$(CONFIG_HID_ALPS) += hid-alps.o
|
||||
obj-$(CONFIG_HID_ACRUX) += hid-axff.o
|
||||
obj-$(CONFIG_HID_APPLE) += hid-apple.o
|
||||
obj-$(CONFIG_HID_APPLEIR) += hid-appleir.o
|
||||
+obj-$(CONFIG_HID_APPLETB_BL) += hid-appletb-bl.o
|
||||
obj-$(CONFIG_HID_CREATIVE_SB0540) += hid-creative-sb0540.o
|
||||
obj-$(CONFIG_HID_ASUS) += hid-asus.o
|
||||
obj-$(CONFIG_HID_AUREAL) += hid-aureal.o
|
||||
diff --git a/drivers/hid/hid-appletb-bl.c b/drivers/hid/hid-appletb-bl.c
|
||||
new file mode 100644
|
||||
index 000000000000..111111111111
|
||||
--- /dev/null
|
||||
+++ b/drivers/hid/hid-appletb-bl.c
|
||||
@@ -0,0 +1,204 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0
|
||||
+/*
|
||||
+ * Apple Touch Bar Backlight Driver
|
||||
+ *
|
||||
+ * Copyright (c) 2017-2018 Ronald Tschalär
|
||||
+ * Copyright (c) 2022-2023 Kerem Karabay <kekrby@gmail.com>
|
||||
+ */
|
||||
+
|
||||
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||
+
|
||||
+#include <linux/hid.h>
|
||||
+#include <linux/backlight.h>
|
||||
+#include <linux/device.h>
|
||||
+
|
||||
+#include "hid-ids.h"
|
||||
+
|
||||
+#define APPLETB_BL_ON 1
|
||||
+#define APPLETB_BL_DIM 3
|
||||
+#define APPLETB_BL_OFF 4
|
||||
+
|
||||
+#define HID_UP_APPLEVENDOR_TB_BL 0xff120000
|
||||
+
|
||||
+#define HID_VD_APPLE_TB_BRIGHTNESS 0xff120001
|
||||
+#define HID_USAGE_AUX1 0xff120020
|
||||
+#define HID_USAGE_BRIGHTNESS 0xff120021
|
||||
+
|
||||
+static int appletb_bl_def_brightness = 2;
|
||||
+module_param_named(brightness, appletb_bl_def_brightness, int, 0444);
|
||||
+MODULE_PARM_DESC(brightness, "Default brightness:\n"
|
||||
+ " 0 - Touchbar is off\n"
|
||||
+ " 1 - Dim brightness\n"
|
||||
+ " [2] - Full brightness");
|
||||
+
|
||||
+struct appletb_bl {
|
||||
+ struct hid_field *aux1_field, *brightness_field;
|
||||
+ struct backlight_device *bdev;
|
||||
+
|
||||
+ bool full_on;
|
||||
+};
|
||||
+
|
||||
+static const u8 appletb_bl_brightness_map[] = {
|
||||
+ APPLETB_BL_OFF,
|
||||
+ APPLETB_BL_DIM,
|
||||
+ APPLETB_BL_ON,
|
||||
+};
|
||||
+
|
||||
+static int appletb_bl_set_brightness(struct appletb_bl *bl, u8 brightness)
|
||||
+{
|
||||
+ struct hid_report *report = bl->brightness_field->report;
|
||||
+ struct hid_device *hdev = report->device;
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = hid_set_field(bl->aux1_field, 0, 1);
|
||||
+ if (ret) {
|
||||
+ hid_err(hdev, "Failed to set auxiliary field (%pe)\n", ERR_PTR(ret));
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ ret = hid_set_field(bl->brightness_field, 0, brightness);
|
||||
+ if (ret) {
|
||||
+ hid_err(hdev, "Failed to set brightness field (%pe)\n", ERR_PTR(ret));
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ if (!bl->full_on) {
|
||||
+ ret = hid_hw_power(hdev, PM_HINT_FULLON);
|
||||
+ if (ret < 0) {
|
||||
+ hid_err(hdev, "Device didn't power on (%pe)\n", ERR_PTR(ret));
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ bl->full_on = true;
|
||||
+ }
|
||||
+
|
||||
+ hid_hw_request(hdev, report, HID_REQ_SET_REPORT);
|
||||
+
|
||||
+ if (brightness == APPLETB_BL_OFF) {
|
||||
+ hid_hw_power(hdev, PM_HINT_NORMAL);
|
||||
+ bl->full_on = false;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int appletb_bl_update_status(struct backlight_device *bdev)
|
||||
+{
|
||||
+ struct appletb_bl *bl = bl_get_data(bdev);
|
||||
+ u8 brightness;
|
||||
+
|
||||
+ if (backlight_is_blank(bdev))
|
||||
+ brightness = APPLETB_BL_OFF;
|
||||
+ else
|
||||
+ brightness = appletb_bl_brightness_map[backlight_get_brightness(bdev)];
|
||||
+
|
||||
+ return appletb_bl_set_brightness(bl, brightness);
|
||||
+}
|
||||
+
|
||||
+static const struct backlight_ops appletb_bl_backlight_ops = {
|
||||
+ .options = BL_CORE_SUSPENDRESUME,
|
||||
+ .update_status = appletb_bl_update_status,
|
||||
+};
|
||||
+
|
||||
+static int appletb_bl_probe(struct hid_device *hdev, const struct hid_device_id *id)
|
||||
+{
|
||||
+ struct hid_field *aux1_field, *brightness_field;
|
||||
+ struct backlight_properties bl_props = { 0 };
|
||||
+ struct device *dev = &hdev->dev;
|
||||
+ struct appletb_bl *bl;
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = hid_parse(hdev);
|
||||
+ if (ret)
|
||||
+ return dev_err_probe(dev, ret, "HID parse failed\n");
|
||||
+
|
||||
+ aux1_field = hid_find_field(hdev, HID_FEATURE_REPORT,
|
||||
+ HID_VD_APPLE_TB_BRIGHTNESS, HID_USAGE_AUX1);
|
||||
+
|
||||
+ brightness_field = hid_find_field(hdev, HID_FEATURE_REPORT,
|
||||
+ HID_VD_APPLE_TB_BRIGHTNESS, HID_USAGE_BRIGHTNESS);
|
||||
+
|
||||
+ if (!aux1_field || !brightness_field)
|
||||
+ return -ENODEV;
|
||||
+
|
||||
+ if (aux1_field->report != brightness_field->report)
|
||||
+ return dev_err_probe(dev, -ENODEV, "Encountered unexpected report structure\n");
|
||||
+
|
||||
+ bl = devm_kzalloc(dev, sizeof(*bl), GFP_KERNEL);
|
||||
+ if (!bl)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ ret = hid_hw_start(hdev, HID_CONNECT_DRIVER);
|
||||
+ if (ret)
|
||||
+ return dev_err_probe(dev, ret, "HID hardware start failed\n");
|
||||
+
|
||||
+ ret = hid_hw_open(hdev);
|
||||
+ if (ret) {
|
||||
+ dev_err_probe(dev, ret, "HID hardware open failed\n");
|
||||
+ goto stop_hw;
|
||||
+ }
|
||||
+
|
||||
+ bl->aux1_field = aux1_field;
|
||||
+ bl->brightness_field = brightness_field;
|
||||
+
|
||||
+ ret = appletb_bl_set_brightness(bl,
|
||||
+ appletb_bl_brightness_map[(appletb_bl_def_brightness > 2) ? 2 : appletb_bl_def_brightness]);
|
||||
+
|
||||
+ if (ret) {
|
||||
+ dev_err_probe(dev, ret, "Failed to set default touch bar brightness to %d\n",
|
||||
+ appletb_bl_def_brightness);
|
||||
+ goto close_hw;
|
||||
+ }
|
||||
+
|
||||
+ bl_props.type = BACKLIGHT_RAW;
|
||||
+ bl_props.max_brightness = ARRAY_SIZE(appletb_bl_brightness_map) - 1;
|
||||
+
|
||||
+ bl->bdev = devm_backlight_device_register(dev, "appletb_backlight", dev, bl,
|
||||
+ &appletb_bl_backlight_ops, &bl_props);
|
||||
+ if (IS_ERR(bl->bdev)) {
|
||||
+ ret = PTR_ERR(bl->bdev);
|
||||
+ dev_err_probe(dev, ret, "Failed to register backlight device\n");
|
||||
+ goto close_hw;
|
||||
+ }
|
||||
+
|
||||
+ hid_set_drvdata(hdev, bl);
|
||||
+
|
||||
+ return 0;
|
||||
+
|
||||
+close_hw:
|
||||
+ hid_hw_close(hdev);
|
||||
+stop_hw:
|
||||
+ hid_hw_stop(hdev);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static void appletb_bl_remove(struct hid_device *hdev)
|
||||
+{
|
||||
+ struct appletb_bl *bl = hid_get_drvdata(hdev);
|
||||
+
|
||||
+ appletb_bl_set_brightness(bl, APPLETB_BL_OFF);
|
||||
+
|
||||
+ hid_hw_close(hdev);
|
||||
+ hid_hw_stop(hdev);
|
||||
+}
|
||||
+
|
||||
+static const struct hid_device_id appletb_bl_hid_ids[] = {
|
||||
+ /* MacBook Pro's 2018, 2019, with T2 chip: iBridge DFR Brightness */
|
||||
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_TOUCHBAR_BACKLIGHT) },
|
||||
+ { }
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(hid, appletb_bl_hid_ids);
|
||||
+
|
||||
+static struct hid_driver appletb_bl_hid_driver = {
|
||||
+ .name = "hid-appletb-bl",
|
||||
+ .id_table = appletb_bl_hid_ids,
|
||||
+ .probe = appletb_bl_probe,
|
||||
+ .remove = appletb_bl_remove,
|
||||
+};
|
||||
+module_hid_driver(appletb_bl_hid_driver);
|
||||
+
|
||||
+MODULE_AUTHOR("Ronald Tschalär");
|
||||
+MODULE_AUTHOR("Kerem Karabay <kekrby@gmail.com>");
|
||||
+MODULE_DESCRIPTION("MacBook Pro Touch Bar Backlight driver");
|
||||
+MODULE_LICENSE("GPL");
|
||||
diff --git a/drivers/hid/hid-quirks.c b/drivers/hid/hid-quirks.c
|
||||
index 111111111111..222222222222 100644
|
||||
--- a/drivers/hid/hid-quirks.c
|
||||
+++ b/drivers/hid/hid-quirks.c
|
||||
@@ -332,7 +332,6 @@ static const struct hid_device_id hid_have_special_driver[] = {
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2021) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_FINGERPRINT_2021) },
|
||||
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_TOUCHBAR_BACKLIGHT) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_TOUCHBAR_DISPLAY) },
|
||||
#endif
|
||||
#if IS_ENABLED(CONFIG_HID_APPLEIR)
|
||||
@@ -342,6 +341,9 @@ static const struct hid_device_id hid_have_special_driver[] = {
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL4) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL5) },
|
||||
#endif
|
||||
+#if IS_ENABLED(CONFIG_HID_APPLETB_BL)
|
||||
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_TOUCHBAR_BACKLIGHT) },
|
||||
+#endif
|
||||
#if IS_ENABLED(CONFIG_HID_ASUS)
|
||||
{ HID_I2C_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_I2C_KEYBOARD) },
|
||||
{ HID_I2C_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_I2C_TOUCHPAD) },
|
||||
--
|
||||
Armbian
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,69 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Kerem Karabay <kekrby@gmail.com>
|
||||
Date: Tue, 27 May 2025 22:13:13 +0530
|
||||
Subject: HID: multitouch: Get the contact ID from HID_DG_TRANSDUCER_INDEX
|
||||
fields in case of Apple Touch Bar
|
||||
|
||||
In Apple Touch Bar, the contact ID is contained in fields with the
|
||||
HID_DG_TRANSDUCER_INDEX usage rather than HID_DG_CONTACTID, thus differing
|
||||
from the HID spec. Add a quirk for the same.
|
||||
|
||||
Acked-by: Benjamin Tissoires <bentiss@kernel.org>
|
||||
Signed-off-by: Kerem Karabay <kekrby@gmail.com>
|
||||
Co-developed-by: Aditya Garg <gargaditya08@live.com>
|
||||
Signed-off-by: Aditya Garg <gargaditya08@live.com>
|
||||
---
|
||||
drivers/hid/hid-multitouch.c | 16 +++++++++-
|
||||
1 file changed, 15 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
|
||||
index 111111111111..222222222222 100644
|
||||
--- a/drivers/hid/hid-multitouch.c
|
||||
+++ b/drivers/hid/hid-multitouch.c
|
||||
@@ -72,6 +72,7 @@ MODULE_LICENSE("GPL");
|
||||
#define MT_QUIRK_FORCE_MULTI_INPUT BIT(20)
|
||||
#define MT_QUIRK_DISABLE_WAKEUP BIT(21)
|
||||
#define MT_QUIRK_ORIENTATION_INVERT BIT(22)
|
||||
+#define MT_QUIRK_APPLE_TOUCHBAR BIT(23)
|
||||
|
||||
#define MT_INPUTMODE_TOUCHSCREEN 0x02
|
||||
#define MT_INPUTMODE_TOUCHPAD 0x03
|
||||
@@ -620,6 +621,7 @@ static struct mt_application *mt_find_application(struct mt_device *td,
|
||||
static struct mt_report_data *mt_allocate_report_data(struct mt_device *td,
|
||||
struct hid_report *report)
|
||||
{
|
||||
+ struct mt_class *cls = &td->mtclass;
|
||||
struct mt_report_data *rdata;
|
||||
struct hid_field *field;
|
||||
int r, n;
|
||||
@@ -644,7 +646,11 @@ static struct mt_report_data *mt_allocate_report_data(struct mt_device *td,
|
||||
|
||||
if (field->logical == HID_DG_FINGER || td->hdev->group != HID_GROUP_MULTITOUCH_WIN_8) {
|
||||
for (n = 0; n < field->report_count; n++) {
|
||||
- if (field->usage[n].hid == HID_DG_CONTACTID) {
|
||||
+ unsigned int hid = field->usage[n].hid;
|
||||
+
|
||||
+ if (hid == HID_DG_CONTACTID ||
|
||||
+ (cls->quirks & MT_QUIRK_APPLE_TOUCHBAR &&
|
||||
+ hid == HID_DG_TRANSDUCER_INDEX)) {
|
||||
rdata->is_mt_collection = true;
|
||||
break;
|
||||
}
|
||||
@@ -822,6 +828,14 @@ static int mt_touch_input_mapping(struct hid_device *hdev, struct hid_input *hi,
|
||||
EV_KEY, BTN_TOUCH);
|
||||
MT_STORE_FIELD(tip_state);
|
||||
return 1;
|
||||
+ case HID_DG_TRANSDUCER_INDEX:
|
||||
+ /*
|
||||
+ * Contact ID in case of Apple Touch Bars is contained
|
||||
+ * in fields with HID_DG_TRANSDUCER_INDEX usage.
|
||||
+ */
|
||||
+ if (!(cls->quirks & MT_QUIRK_APPLE_TOUCHBAR))
|
||||
+ return 0;
|
||||
+ fallthrough;
|
||||
case HID_DG_CONTACTID:
|
||||
MT_STORE_FIELD(contactid);
|
||||
app->touches_by_report++;
|
||||
--
|
||||
Armbian
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Kerem Karabay <kekrby@gmail.com>
|
||||
Date: Tue, 27 May 2025 22:13:14 +0530
|
||||
Subject: HID: multitouch: support getting the tip state from HID_DG_TOUCH
|
||||
fields in Apple Touch Bar
|
||||
|
||||
In Apple Touch Bar, the tip state is contained in fields with the
|
||||
HID_DG_TOUCH usage. This feature is gated by a quirk in order to
|
||||
prevent breaking other devices, see commit c2ef8f21ea8f
|
||||
("HID: multitouch: add support for trackpads").
|
||||
|
||||
Acked-by: Benjamin Tissoires <bentiss@kernel.org>
|
||||
Signed-off-by: Kerem Karabay <kekrby@gmail.com>
|
||||
Co-developed-by: Aditya Garg <gargaditya08@live.com>
|
||||
Signed-off-by: Aditya Garg <gargaditya08@live.com>
|
||||
---
|
||||
drivers/hid/hid-multitouch.c | 15 +++++++---
|
||||
1 file changed, 11 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
|
||||
index 111111111111..222222222222 100644
|
||||
--- a/drivers/hid/hid-multitouch.c
|
||||
+++ b/drivers/hid/hid-multitouch.c
|
||||
@@ -822,6 +822,17 @@ static int mt_touch_input_mapping(struct hid_device *hdev, struct hid_input *hi,
|
||||
|
||||
MT_STORE_FIELD(confidence_state);
|
||||
return 1;
|
||||
+ case HID_DG_TOUCH:
|
||||
+ /*
|
||||
+ * Legacy devices use TIPSWITCH and not TOUCH.
|
||||
+ * One special case here is of the Apple Touch Bars.
|
||||
+ * In these devices, the tip state is contained in
|
||||
+ * fields with the HID_DG_TOUCH usage.
|
||||
+ * Let's just ignore this field for other devices.
|
||||
+ */
|
||||
+ if (!(cls->quirks & MT_QUIRK_APPLE_TOUCHBAR))
|
||||
+ return -1;
|
||||
+ fallthrough;
|
||||
case HID_DG_TIPSWITCH:
|
||||
if (field->application != HID_GD_SYSTEM_MULTIAXIS)
|
||||
input_set_capability(hi->input,
|
||||
@@ -892,10 +903,6 @@ static int mt_touch_input_mapping(struct hid_device *hdev, struct hid_input *hi,
|
||||
case HID_DG_CONTACTMAX:
|
||||
/* contact max are global to the report */
|
||||
return -1;
|
||||
- case HID_DG_TOUCH:
|
||||
- /* Legacy devices use TIPSWITCH and not TOUCH.
|
||||
- * Let's just ignore this field. */
|
||||
- return -1;
|
||||
}
|
||||
/* let hid-input decide for the others */
|
||||
return 0;
|
||||
--
|
||||
Armbian
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Kerem Karabay <kekrby@gmail.com>
|
||||
Date: Tue, 27 May 2025 22:13:15 +0530
|
||||
Subject: HID: multitouch: take cls->maxcontacts into account for Apple Touch
|
||||
Bar even without a HID_DG_CONTACTMAX field
|
||||
|
||||
In Apple Touch Bar, the HID_DG_CONTACTMAX is not present, but the maximum
|
||||
contact count is still greater than the default. Add quirks for the same.
|
||||
|
||||
Acked-by: Benjamin Tissoires <bentiss@kernel.org>
|
||||
Signed-off-by: Kerem Karabay <kekrby@gmail.com>
|
||||
Co-developed-by: Aditya Garg <gargaditya08@live.com>
|
||||
Signed-off-by: Aditya Garg <gargaditya08@live.com>
|
||||
---
|
||||
drivers/hid/hid-multitouch.c | 7 +++++++
|
||||
1 file changed, 7 insertions(+)
|
||||
|
||||
diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
|
||||
index 111111111111..222222222222 100644
|
||||
--- a/drivers/hid/hid-multitouch.c
|
||||
+++ b/drivers/hid/hid-multitouch.c
|
||||
@@ -1327,6 +1327,13 @@ static int mt_touch_input_configured(struct hid_device *hdev,
|
||||
struct input_dev *input = hi->input;
|
||||
int ret;
|
||||
|
||||
+ /*
|
||||
+ * HID_DG_CONTACTMAX field is not present on Apple Touch Bars,
|
||||
+ * but the maximum contact count is greater than the default.
|
||||
+ */
|
||||
+ if (cls->quirks & MT_QUIRK_APPLE_TOUCHBAR && cls->maxcontacts)
|
||||
+ td->maxcontacts = cls->maxcontacts;
|
||||
+
|
||||
if (!td->maxcontacts)
|
||||
td->maxcontacts = MT_DEFAULT_MAXCONTACT;
|
||||
|
||||
--
|
||||
Armbian
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Kerem Karabay <kekrby@gmail.com>
|
||||
Date: Tue, 27 May 2025 22:13:16 +0530
|
||||
Subject: HID: multitouch: specify that Apple Touch Bar is direct
|
||||
|
||||
Currently the driver determines the device type based on the
|
||||
application, but this value is not reliable on Apple Touch Bar, where
|
||||
the application is HID_DG_TOUCHPAD even though this device is direct,
|
||||
so add a quirk for the same.
|
||||
|
||||
Acked-by: Benjamin Tissoires <bentiss@kernel.org>
|
||||
Signed-off-by: Kerem Karabay <kekrby@gmail.com>
|
||||
Co-developed-by: Aditya Garg <gargaditya08@live.com>
|
||||
Signed-off-by: Aditya Garg <gargaditya08@live.com>
|
||||
---
|
||||
drivers/hid/hid-multitouch.c | 7 +++++++
|
||||
1 file changed, 7 insertions(+)
|
||||
|
||||
diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
|
||||
index 111111111111..222222222222 100644
|
||||
--- a/drivers/hid/hid-multitouch.c
|
||||
+++ b/drivers/hid/hid-multitouch.c
|
||||
@@ -1341,6 +1341,13 @@ static int mt_touch_input_configured(struct hid_device *hdev,
|
||||
if (td->serial_maybe)
|
||||
mt_post_parse_default_settings(td, app);
|
||||
|
||||
+ /*
|
||||
+ * The application for Apple Touch Bars is HID_DG_TOUCHPAD,
|
||||
+ * but these devices are direct.
|
||||
+ */
|
||||
+ if (cls->quirks & MT_QUIRK_APPLE_TOUCHBAR)
|
||||
+ app->mt_flags |= INPUT_MT_DIRECT;
|
||||
+
|
||||
if (cls->is_indirect)
|
||||
app->mt_flags |= INPUT_MT_POINTER;
|
||||
|
||||
--
|
||||
Armbian
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Kerem Karabay <kekrby@gmail.com>
|
||||
Date: Tue, 27 May 2025 22:13:17 +0530
|
||||
Subject: HID: multitouch: add device ID for Apple Touch Bar
|
||||
|
||||
This patch adds the device ID of Apple Touch Bar found on x86 MacBook Pros
|
||||
to the hid-multitouch driver.
|
||||
|
||||
Note that this is device ID is for T2 Macs. Testing on T1 Macs would be
|
||||
appreciated.
|
||||
|
||||
Signed-off-by: Kerem Karabay <kekrby@gmail.com>
|
||||
Co-developed-by: Aditya Garg <gargaditya08@live.com>
|
||||
Signed-off-by: Aditya Garg <gargaditya08@live.com>
|
||||
---
|
||||
drivers/hid/Kconfig | 1 +
|
||||
drivers/hid/hid-multitouch.c | 17 ++++++++++
|
||||
2 files changed, 18 insertions(+)
|
||||
|
||||
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
|
||||
index 111111111111..222222222222 100644
|
||||
--- a/drivers/hid/Kconfig
|
||||
+++ b/drivers/hid/Kconfig
|
||||
@@ -754,6 +754,7 @@ config HID_MULTITOUCH
|
||||
Say Y here if you have one of the following devices:
|
||||
- 3M PCT touch screens
|
||||
- ActionStar dual touch panels
|
||||
+ - Apple Touch Bar on x86 MacBook Pros
|
||||
- Atmel panels
|
||||
- Cando dual touch panels
|
||||
- Chunghwa panels
|
||||
diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
|
||||
index 111111111111..222222222222 100644
|
||||
--- a/drivers/hid/hid-multitouch.c
|
||||
+++ b/drivers/hid/hid-multitouch.c
|
||||
@@ -216,6 +216,7 @@ static void mt_post_parse(struct mt_device *td, struct mt_application *app);
|
||||
#define MT_CLS_GOOGLE 0x0111
|
||||
#define MT_CLS_RAZER_BLADE_STEALTH 0x0112
|
||||
#define MT_CLS_SMART_TECH 0x0113
|
||||
+#define MT_CLS_APPLE_TOUCHBAR 0x0114
|
||||
#define MT_CLS_SIS 0x0457
|
||||
|
||||
#define MT_DEFAULT_MAXCONTACT 10
|
||||
@@ -401,6 +402,12 @@ static const struct mt_class mt_classes[] = {
|
||||
MT_QUIRK_CONTACT_CNT_ACCURATE |
|
||||
MT_QUIRK_SEPARATE_APP_REPORT,
|
||||
},
|
||||
+ { .name = MT_CLS_APPLE_TOUCHBAR,
|
||||
+ .quirks = MT_QUIRK_HOVERING |
|
||||
+ MT_QUIRK_SLOT_IS_CONTACTID_MINUS_ONE |
|
||||
+ MT_QUIRK_APPLE_TOUCHBAR,
|
||||
+ .maxcontacts = 11,
|
||||
+ },
|
||||
{ .name = MT_CLS_SIS,
|
||||
.quirks = MT_QUIRK_NOT_SEEN_MEANS_UP |
|
||||
MT_QUIRK_ALWAYS_VALID |
|
||||
@@ -1862,6 +1869,11 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
+ if (mtclass->name == MT_CLS_APPLE_TOUCHBAR &&
|
||||
+ !hid_find_field(hdev, HID_INPUT_REPORT,
|
||||
+ HID_DG_TOUCHPAD, HID_DG_TRANSDUCER_INDEX))
|
||||
+ return -ENODEV;
|
||||
+
|
||||
if (mtclass->quirks & MT_QUIRK_FIX_CONST_CONTACT_ID)
|
||||
mt_fix_const_fields(hdev, HID_DG_CONTACTID);
|
||||
|
||||
@@ -2349,6 +2361,11 @@ static const struct hid_device_id mt_devices[] = {
|
||||
MT_USB_DEVICE(USB_VENDOR_ID_XIROKU,
|
||||
USB_DEVICE_ID_XIROKU_CSR2) },
|
||||
|
||||
+ /* Apple Touch Bar */
|
||||
+ { .driver_data = MT_CLS_APPLE_TOUCHBAR,
|
||||
+ HID_USB_DEVICE(USB_VENDOR_ID_APPLE,
|
||||
+ USB_DEVICE_ID_APPLE_TOUCHBAR_DISPLAY) },
|
||||
+
|
||||
/* Google MT devices */
|
||||
{ .driver_data = MT_CLS_GOOGLE,
|
||||
HID_DEVICE(HID_BUS_ANY, HID_GROUP_ANY, USB_VENDOR_ID_GOOGLE,
|
||||
--
|
||||
Armbian
|
||||
|
||||
@@ -0,0 +1,167 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Hector Martin <marcan@marcan.st>
|
||||
Date: Tue, 8 Apr 2025 12:17:57 +0530
|
||||
Subject: lib/vsprintf: Add support for generic FourCCs by extending %p4cc
|
||||
|
||||
%p4cc is designed for DRM/V4L2 FourCCs with their specific quirks, but
|
||||
it's useful to be able to print generic 4-character codes formatted as
|
||||
an integer. Extend it to add format specifiers for printing generic
|
||||
32-bit FourCCs with various endian semantics:
|
||||
|
||||
%p4ch Host byte order
|
||||
%p4cn Network byte order
|
||||
%p4cl Little-endian
|
||||
%p4cb Big-endian
|
||||
|
||||
The endianness determines how bytes are interpreted as a u32, and the
|
||||
FourCC is then always printed MSByte-first (this is the opposite of
|
||||
V4L/DRM FourCCs). This covers most practical cases, e.g. %p4cn would
|
||||
allow printing LSByte-first FourCCs stored in host endian order
|
||||
(other than the hex form being in character order, not the integer
|
||||
value).
|
||||
|
||||
Acked-by: Rasmus Villemoes <linux@rasmusvillemoes.dk>
|
||||
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
|
||||
Reviewed-by: Petr Mladek <pmladek@suse.com>
|
||||
Tested-by: Petr Mladek <pmladek@suse.com>
|
||||
Signed-off-by: Hector Martin <marcan@marcan.st>
|
||||
Signed-off-by: Aditya Garg <gargaditya08@live.com>
|
||||
Reviewed-by: Kees Cook <kees@kernel.org>
|
||||
---
|
||||
Documentation/core-api/printk-formats.rst | 32 ++++++++
|
||||
lib/vsprintf.c | 40 ++++++++--
|
||||
scripts/checkpatch.pl | 2 +-
|
||||
3 files changed, 67 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/Documentation/core-api/printk-formats.rst b/Documentation/core-api/printk-formats.rst
|
||||
index 111111111111..222222222222 100644
|
||||
--- a/Documentation/core-api/printk-formats.rst
|
||||
+++ b/Documentation/core-api/printk-formats.rst
|
||||
@@ -630,6 +630,38 @@ Examples::
|
||||
%p4cc Y10 little-endian (0x20303159)
|
||||
%p4cc NV12 big-endian (0xb231564e)
|
||||
|
||||
+Generic FourCC code
|
||||
+-------------------
|
||||
+
|
||||
+::
|
||||
+ %p4c[h[R]lb] gP00 (0x67503030)
|
||||
+
|
||||
+Print a generic FourCC code, as both ASCII characters and its numerical
|
||||
+value as hexadecimal.
|
||||
+
|
||||
+The generic FourCC code is always printed in the big-endian format,
|
||||
+the most significant byte first. This is the opposite of V4L/DRM FourCCs.
|
||||
+
|
||||
+The additional ``h``, ``hR``, ``l``, and ``b`` specifiers define what
|
||||
+endianness is used to load the stored bytes. The data might be interpreted
|
||||
+using the host, reversed host byte order, little-endian, or big-endian.
|
||||
+
|
||||
+Passed by reference.
|
||||
+
|
||||
+Examples for a little-endian machine, given &(u32)0x67503030::
|
||||
+
|
||||
+ %p4ch gP00 (0x67503030)
|
||||
+ %p4chR 00Pg (0x30305067)
|
||||
+ %p4cl gP00 (0x67503030)
|
||||
+ %p4cb 00Pg (0x30305067)
|
||||
+
|
||||
+Examples for a big-endian machine, given &(u32)0x67503030::
|
||||
+
|
||||
+ %p4ch gP00 (0x67503030)
|
||||
+ %p4chR 00Pg (0x30305067)
|
||||
+ %p4cl 00Pg (0x30305067)
|
||||
+ %p4cb gP00 (0x67503030)
|
||||
+
|
||||
Rust
|
||||
----
|
||||
|
||||
diff --git a/lib/vsprintf.c b/lib/vsprintf.c
|
||||
index 111111111111..222222222222 100644
|
||||
--- a/lib/vsprintf.c
|
||||
+++ b/lib/vsprintf.c
|
||||
@@ -1760,27 +1760,49 @@ char *fourcc_string(char *buf, char *end, const u32 *fourcc,
|
||||
char output[sizeof("0123 little-endian (0x01234567)")];
|
||||
char *p = output;
|
||||
unsigned int i;
|
||||
+ bool pixel_fmt = false;
|
||||
u32 orig, val;
|
||||
|
||||
- if (fmt[1] != 'c' || fmt[2] != 'c')
|
||||
+ if (fmt[1] != 'c')
|
||||
return error_string(buf, end, "(%p4?)", spec);
|
||||
|
||||
if (check_pointer(&buf, end, fourcc, spec))
|
||||
return buf;
|
||||
|
||||
orig = get_unaligned(fourcc);
|
||||
- val = orig & ~BIT(31);
|
||||
+ switch (fmt[2]) {
|
||||
+ case 'h':
|
||||
+ if (fmt[3] == 'R')
|
||||
+ orig = swab32(orig);
|
||||
+ break;
|
||||
+ case 'l':
|
||||
+ orig = (__force u32)cpu_to_le32(orig);
|
||||
+ break;
|
||||
+ case 'b':
|
||||
+ orig = (__force u32)cpu_to_be32(orig);
|
||||
+ break;
|
||||
+ case 'c':
|
||||
+ /* Pixel formats are printed LSB-first */
|
||||
+ pixel_fmt = true;
|
||||
+ break;
|
||||
+ default:
|
||||
+ return error_string(buf, end, "(%p4?)", spec);
|
||||
+ }
|
||||
+
|
||||
+ val = pixel_fmt ? swab32(orig & ~BIT(31)) : orig;
|
||||
|
||||
for (i = 0; i < sizeof(u32); i++) {
|
||||
- unsigned char c = val >> (i * 8);
|
||||
+ unsigned char c = val >> ((3 - i) * 8);
|
||||
|
||||
/* Print non-control ASCII characters as-is, dot otherwise */
|
||||
*p++ = isascii(c) && isprint(c) ? c : '.';
|
||||
}
|
||||
|
||||
- *p++ = ' ';
|
||||
- strcpy(p, orig & BIT(31) ? "big-endian" : "little-endian");
|
||||
- p += strlen(p);
|
||||
+ if (pixel_fmt) {
|
||||
+ *p++ = ' ';
|
||||
+ strcpy(p, orig & BIT(31) ? "big-endian" : "little-endian");
|
||||
+ p += strlen(p);
|
||||
+ }
|
||||
|
||||
*p++ = ' ';
|
||||
*p++ = '(';
|
||||
@@ -2334,6 +2356,12 @@ char *rust_fmt_argument(char *buf, char *end, const void *ptr);
|
||||
* read the documentation (path below) first.
|
||||
* - 'NF' For a netdev_features_t
|
||||
* - '4cc' V4L2 or DRM FourCC code, with endianness and raw numerical value.
|
||||
+ * - '4c[h[R]lb]' For generic FourCC code with raw numerical value. Both are
|
||||
+ * displayed in the big-endian format. This is the opposite of V4L2 or
|
||||
+ * DRM FourCCs.
|
||||
+ * The additional specifiers define what endianness is used to load
|
||||
+ * the stored bytes. The data might be interpreted using the host,
|
||||
+ * reversed host byte order, little-endian, or big-endian.
|
||||
* - 'h[CDN]' For a variable-length buffer, it prints it as a hex string with
|
||||
* a certain separator (' ' by default):
|
||||
* C colon
|
||||
diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
|
||||
index 111111111111..222222222222 100755
|
||||
--- a/scripts/checkpatch.pl
|
||||
+++ b/scripts/checkpatch.pl
|
||||
@@ -6912,7 +6912,7 @@ sub process {
|
||||
($extension eq "f" &&
|
||||
defined $qualifier && $qualifier !~ /^w/) ||
|
||||
($extension eq "4" &&
|
||||
- defined $qualifier && $qualifier !~ /^cc/)) {
|
||||
+ defined $qualifier && $qualifier !~ /^c[hnlbc]/)) {
|
||||
$bad_specifier = $specifier;
|
||||
last;
|
||||
}
|
||||
--
|
||||
Armbian
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,84 @@
|
||||
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 | 4 +++
|
||||
drivers/gpu/drm/i915/display/intel_quirks.c | 15 ++++++++++
|
||||
drivers/gpu/drm/i915/display/intel_quirks.h | 1 +
|
||||
3 files changed, 20 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
|
||||
@@ -4648,6 +4648,7 @@ static int intel_ddi_init_hdmi_connector(struct intel_digital_port *dig_port)
|
||||
|
||||
static bool intel_ddi_a_force_4_lanes(struct intel_digital_port *dig_port)
|
||||
{
|
||||
+ struct intel_display *display = to_intel_display(dig_port);
|
||||
struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev);
|
||||
|
||||
if (dig_port->base.port != PORT_A)
|
||||
@@ -4656,6 +4657,9 @@ static bool intel_ddi_a_force_4_lanes(struct intel_digital_port *dig_port)
|
||||
if (dig_port->saved_port_bits & 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
|
||||
@@ -64,6 +64,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);
|
||||
@@ -229,6 +241,9 @@ static struct intel_quirk intel_quirks[] = {
|
||||
{ 0x3184, 0x1019, 0xa94d, quirk_increase_ddi_disabled_time },
|
||||
/* HP Notebook - 14-r206nv */
|
||||
{ 0x0f31, 0x103c, 0x220f, quirk_invert_brightness },
|
||||
+
|
||||
+ /* Apple MacBookPro15,1 */
|
||||
+ { 0x3e9b, 0x106b, 0x0176, quirk_ddi_a_force_4_lanes },
|
||||
};
|
||||
|
||||
static 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
|
||||
@@ -20,6 +20,7 @@ enum intel_quirk_id {
|
||||
QUIRK_LVDS_SSC_DISABLE,
|
||||
QUIRK_NO_PPS_BACKLIGHT_POWER_HOOK,
|
||||
QUIRK_FW_SYNC_LEN,
|
||||
+ QUIRK_DDI_A_FORCE_4_LANES,
|
||||
};
|
||||
|
||||
void intel_init_quirks(struct intel_display *display);
|
||||
--
|
||||
Armbian
|
||||
|
||||
@@ -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
|
||||
@@ -2262,6 +2262,9 @@ static int amdgpu_pci_probe(struct pci_dev *pdev,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
+ if (vga_switcheroo_client_probe_defer(pdev))
|
||||
+ return -EPROBE_DEFER;
|
||||
+
|
||||
/* skip devices which are owned by radeon */
|
||||
for (i = 0; i < ARRAY_SIZE(amdgpu_unsupported_pciidlist); i++) {
|
||||
if (amdgpu_unsupported_pciidlist[i] == pdev->device)
|
||||
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 ((pdev->class >> 16) == PCI_BASE_CLASS_DISPLAY) {
|
||||
- /*
|
||||
- * 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
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user