Add 9,1 backlight

This commit is contained in:
Aditya Garg
2022-11-16 19:19:28 +05:30
parent 42eefd1c03
commit 171e9a8b54
17 changed files with 3941 additions and 3511 deletions
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,70 @@
From dc27d4db5787546ae5eacf3483f3b87f2d4fb1c1 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: [PATCH] Put apple-bce in drivers/staging
---
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(-)
create mode 100644 drivers/staging/apple-bce/Kconfig
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig
index 5cfabd537..3b8e61d26 100644
--- a/drivers/staging/Kconfig
+++ b/drivers/staging/Kconfig
@@ -80,4 +80,6 @@ source "drivers/staging/qlge/Kconfig"
source "drivers/staging/vme_user/Kconfig"
+source "drivers/staging/apple-bce/Kconfig"
+
endif # STAGING
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile
index f8c3aa9c2..1e148d6c3 100644
--- a/drivers/staging/Makefile
+++ b/drivers/staging/Makefile
@@ -29,3 +29,4 @@ obj-$(CONFIG_PI433) += pi433/
obj-$(CONFIG_XIL_AXIS_FIFO) += axis-fifo/
obj-$(CONFIG_FIELDBUS_DEV) += fieldbus/
obj-$(CONFIG_QLGE) += qlge/
+obj-$(CONFIG_APPLE_BCE) += apple-bce/
diff --git a/drivers/staging/apple-bce/Kconfig b/drivers/staging/apple-bce/Kconfig
new file mode 100644
index 000000000..fe92bc441
--- /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 a6a656f06..8cfbd3f64 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
--
2.34.1
@@ -1,111 +0,0 @@
From 153b587ed53135eaf244144f6f8bdd5a0fe6b69e Mon Sep 17 00:00:00 2001
From: Redecorating <69827514+Redecorating@users.noreply.github.com>
Date: Fri, 24 Dec 2021 18:12:25 +1100
Subject: [PATCH 1/1] Put apple-bce and apple-ibridge in drivers/staging
---
drivers/staging/Kconfig | 4 ++++
drivers/staging/Makefile | 2 ++
drivers/staging/apple-bce/Kconfig | 18 ++++++++++++++++++
drivers/staging/apple-bce/Makefile | 2 +-
drivers/staging/apple-ibridge/Kconfig | 15 +++++++++++++++
drivers/staging/apple-ibridge/Makefile | 6 +++---
6 files changed, 43 insertions(+), 4 deletions(-)
create mode 100644 drivers/staging/apple-bce/Kconfig
create mode 100644 drivers/staging/apple-ibridge/Kconfig
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig
index e03627a..fc121d5 100644
--- a/drivers/staging/Kconfig
+++ b/drivers/staging/Kconfig
@@ -102,4 +102,8 @@ source "drivers/staging/qlge/Kconfig"
source "drivers/staging/vme_user/Kconfig"
+source "drivers/staging/apple-bce/Kconfig"
+
+source "drivers/staging/apple-ibridge/Kconfig"
+
endif # STAGING
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile
index c7f8d8d..debad40 100644
--- a/drivers/staging/Makefile
+++ b/drivers/staging/Makefile
@@ -41,3 +41,5 @@ obj-$(CONFIG_XIL_AXIS_FIFO) += axis-fifo/
obj-$(CONFIG_XIL_AXIS_FIFO) += axis-fifo/
obj-$(CONFIG_FIELDBUS_DEV) += fieldbus/
obj-$(CONFIG_QLGE) += qlge/
+obj-$(CONFIG_APPLE_BCE) += apple-bce/
+obj-$(CONFIG_APPLE_IBRIDGE) += apple-ibridge/
diff --git a/drivers/staging/apple-bce/Kconfig b/drivers/staging/apple-bce/Kconfig
new file mode 100644
index 0000000..bbfb89b
--- /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 a6a656f..8cfbd3f 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
diff --git a/drivers/staging/apple-ibridge/Kconfig b/drivers/staging/apple-ibridge/Kconfig
new file mode 100644
index 0000000..0716486
--- /dev/null
+++ b/drivers/staging/apple-ibridge/Kconfig
@@ -0,0 +1,15 @@
+config APPLE_IBRIDGE
+ tristate "Apple iBridge driver (Touchbar and ALS support)"
+ default m
+ depends on X86
+ select HID
+ select IIO
+ select IIO_TRIGGERED_BUFFER
+ select IIO_BUFFER
+ select ACPI_ALS
+ help
+ Driver for the Touchbar and ALS (Ambient Light Sensor) on some
+ Apple computers.
+
+ If "M" is selected, the modules will be called apple-ibridge,
+ apple-ib-tb and apple-ib-als.
diff --git a/drivers/staging/apple-ibridge/Makefile b/drivers/staging/apple-ibridge/Makefile
index ea40afe..ae129bd 100644
--- a/drivers/staging/apple-ibridge/Makefile
+++ b/drivers/staging/apple-ibridge/Makefile
@@ -1,6 +1,6 @@
-obj-m += apple-ibridge.o
-obj-m += apple-ib-tb.o
-obj-m += apple-ib-als.o
+obj-$(CONFIG_APPLE_IBRIDGE) += apple-ibridge.o
+obj-$(CONFIG_APPLE_IBRIDGE) += apple-ib-tb.o
+obj-$(CONFIG_APPLE_IBRIDGE) += apple-ib-als.o
KVERSION := $(KERNELRELEASE)
ifeq ($(origin KERNELRELEASE), undefined)
--
2.34.1
@@ -0,0 +1,64 @@
From 18bed33b3b1180a8af8a52dcf544b67b61786e89 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ronald=20Tschal=C3=A4r?= <ronald@innovation.ch>
Date: Sat, 27 Feb 2021 17:26:39 -0800
Subject: [PATCH 01/13] HID: Recognize sensors with application collections
too.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
According to HUTRR39 logical sensor devices may be nested inside
physical collections or may be specified in multiple top-level
application collections (see page 59, strategies 1 and 2). However,
the current code was only recognizing those with physical collections.
This issue turned up in recent MacBook Pro's which define the ALS in
a top-level application collection.
Signed-off-by: Ronald Tschalär <ronald@innovation.ch>
---
drivers/hid/hid-core.c | 3 ++-
drivers/hid/hid-sensor-hub.c | 6 ++++--
2 files changed, 6 insertions(+), 3 deletions(-)
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index b7f5566e338d..8fcd663b10e2 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -804,7 +804,8 @@ static void hid_scan_collection(struct hid_parser *parser, unsigned type)
int i;
if (((parser->global.usage_page << 16) == HID_UP_SENSOR) &&
- type == HID_COLLECTION_PHYSICAL)
+ (type == HID_COLLECTION_PHYSICAL ||
+ type == HID_COLLECTION_APPLICATION))
hid->group = HID_GROUP_SENSOR_HUB;
if (hid->vendor == USB_VENDOR_ID_MICROSOFT &&
diff --git a/drivers/hid/hid-sensor-hub.c b/drivers/hid/hid-sensor-hub.c
index 6abd3e2a9094..d03dc4ca095f 100644
--- a/drivers/hid/hid-sensor-hub.c
+++ b/drivers/hid/hid-sensor-hub.c
@@ -397,7 +397,8 @@ int sensor_hub_input_get_attribute_info(struct hid_sensor_hub_device *hsdev,
for (i = 0; i < report->maxfield; ++i) {
field = report->field[i];
if (field->maxusage) {
- if (field->physical == usage_id &&
+ if ((field->physical == usage_id ||
+ field->application == usage_id) &&
(field->logical == attr_usage_id ||
field->usage[0].hid ==
attr_usage_id) &&
@@ -506,7 +507,8 @@ static int sensor_hub_raw_event(struct hid_device *hdev,
collection->usage);
callback = sensor_hub_get_callback(hdev,
- report->field[i]->physical,
+ report->field[i]->physical ?:
+ report->field[i]->application,
report->field[i]->usage[0].collection_index,
&hsdev, &priv);
if (!callback) {
--
2.38.1
@@ -0,0 +1,221 @@
From 360637979541fa2f3a64ed54af818f07e4e95a8d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ronald=20Tschal=C3=A4r?= <ronald@innovation.ch>
Date: Sat, 27 Feb 2021 17:26:41 -0800
Subject: [PATCH 02/13] HID: core: Export some report item parsing functions.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
These are useful to drivers that need to scan or parse reports
themselves.
Signed-off-by: Ronald Tschalär <ronald@innovation.ch>
---
drivers/hid/hid-core.c | 54 +++++++++++++++++++++++++-----------------
include/linux/hid.h | 4 ++++
2 files changed, 36 insertions(+), 22 deletions(-)
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 8fcd663b10e2..f0d914238e55 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -343,7 +343,7 @@ static int hid_add_field(struct hid_parser *parser, unsigned report_type, unsign
* Read data value from item.
*/
-static u32 item_udata(struct hid_item *item)
+u32 hid_item_udata(struct hid_item *item)
{
switch (item->size) {
case 1: return item->data.u8;
@@ -352,8 +352,9 @@ static u32 item_udata(struct hid_item *item)
}
return 0;
}
+EXPORT_SYMBOL_GPL(hid_item_udata);
-static s32 item_sdata(struct hid_item *item)
+s32 hid_item_sdata(struct hid_item *item)
{
switch (item->size) {
case 1: return item->data.s8;
@@ -362,6 +363,7 @@ static s32 item_sdata(struct hid_item *item)
}
return 0;
}
+EXPORT_SYMBOL_GPL(hid_item_sdata);
/*
* Process a global item.
@@ -394,29 +396,29 @@ static int hid_parser_global(struct hid_parser *parser, struct hid_item *item)
return 0;
case HID_GLOBAL_ITEM_TAG_USAGE_PAGE:
- parser->global.usage_page = item_udata(item);
+ parser->global.usage_page = hid_item_udata(item);
return 0;
case HID_GLOBAL_ITEM_TAG_LOGICAL_MINIMUM:
- parser->global.logical_minimum = item_sdata(item);
+ parser->global.logical_minimum = hid_item_sdata(item);
return 0;
case HID_GLOBAL_ITEM_TAG_LOGICAL_MAXIMUM:
if (parser->global.logical_minimum < 0)
- parser->global.logical_maximum = item_sdata(item);
+ parser->global.logical_maximum = hid_item_sdata(item);
else
- parser->global.logical_maximum = item_udata(item);
+ parser->global.logical_maximum = hid_item_udata(item);
return 0;
case HID_GLOBAL_ITEM_TAG_PHYSICAL_MINIMUM:
- parser->global.physical_minimum = item_sdata(item);
+ parser->global.physical_minimum = hid_item_sdata(item);
return 0;
case HID_GLOBAL_ITEM_TAG_PHYSICAL_MAXIMUM:
if (parser->global.physical_minimum < 0)
- parser->global.physical_maximum = item_sdata(item);
+ parser->global.physical_maximum = hid_item_sdata(item);
else
- parser->global.physical_maximum = item_udata(item);
+ parser->global.physical_maximum = hid_item_udata(item);
return 0;
case HID_GLOBAL_ITEM_TAG_UNIT_EXPONENT:
@@ -424,7 +426,7 @@ static int hid_parser_global(struct hid_parser *parser, struct hid_item *item)
* nibble due to the common misunderstanding of HID
* specification 1.11, 6.2.2.7 Global Items. Attempt to handle
* both this and the standard encoding. */
- raw_value = item_sdata(item);
+ raw_value = hid_item_sdata(item);
if (!(raw_value & 0xfffffff0))
parser->global.unit_exponent = hid_snto32(raw_value, 4);
else
@@ -432,11 +434,11 @@ static int hid_parser_global(struct hid_parser *parser, struct hid_item *item)
return 0;
case HID_GLOBAL_ITEM_TAG_UNIT:
- parser->global.unit = item_udata(item);
+ parser->global.unit = hid_item_udata(item);
return 0;
case HID_GLOBAL_ITEM_TAG_REPORT_SIZE:
- parser->global.report_size = item_udata(item);
+ parser->global.report_size = hid_item_udata(item);
if (parser->global.report_size > 256) {
hid_err(parser->device, "invalid report_size %d\n",
parser->global.report_size);
@@ -445,7 +447,7 @@ static int hid_parser_global(struct hid_parser *parser, struct hid_item *item)
return 0;
case HID_GLOBAL_ITEM_TAG_REPORT_COUNT:
- parser->global.report_count = item_udata(item);
+ parser->global.report_count = hid_item_udata(item);
if (parser->global.report_count > HID_MAX_USAGES) {
hid_err(parser->device, "invalid report_count %d\n",
parser->global.report_count);
@@ -454,7 +456,7 @@ static int hid_parser_global(struct hid_parser *parser, struct hid_item *item)
return 0;
case HID_GLOBAL_ITEM_TAG_REPORT_ID:
- parser->global.report_id = item_udata(item);
+ parser->global.report_id = hid_item_udata(item);
if (parser->global.report_id == 0 ||
parser->global.report_id >= HID_MAX_IDS) {
hid_err(parser->device, "report_id %u is invalid\n",
@@ -479,7 +481,7 @@ static int hid_parser_local(struct hid_parser *parser, struct hid_item *item)
unsigned n;
__u32 count;
- data = item_udata(item);
+ data = hid_item_udata(item);
switch (item->tag) {
case HID_LOCAL_ITEM_TAG_DELIMITER:
@@ -611,7 +613,7 @@ static int hid_parser_main(struct hid_parser *parser, struct hid_item *item)
hid_concatenate_last_usage_page(parser);
- data = item_udata(item);
+ data = hid_item_udata(item);
switch (item->tag) {
case HID_MAIN_ITEM_TAG_BEGIN_COLLECTION:
@@ -712,12 +714,19 @@ static void hid_device_release(struct device *dev)
kfree(hid);
}
-/*
+/**
+ * hid_fetch_item - fetch an item from a report
+ *
+ * @start: the current position in the report buffer to read the next item from
+ * @end: the end of the report buffer
+ * @item: the item struct to fill in
+ *
* Fetch a report description item from the data stream. We support long
* items, though they are not used yet.
+ *
+ * Return: the position of the next item in the report
*/
-
-static u8 *fetch_item(__u8 *start, __u8 *end, struct hid_item *item)
+u8 *hid_fetch_item(__u8 *start, __u8 *end, struct hid_item *item)
{
u8 b;
@@ -778,6 +787,7 @@ static u8 *fetch_item(__u8 *start, __u8 *end, struct hid_item *item)
return NULL;
}
+EXPORT_SYMBOL_GPL(hid_fetch_item);
static void hid_scan_input_usage(struct hid_parser *parser, u32 usage)
{
@@ -836,7 +846,7 @@ static int hid_scan_main(struct hid_parser *parser, struct hid_item *item)
hid_concatenate_last_usage_page(parser);
- data = item_udata(item);
+ data = hid_item_udata(item);
switch (item->tag) {
case HID_MAIN_ITEM_TAG_BEGIN_COLLECTION:
@@ -896,7 +906,7 @@ static int hid_scan_report(struct hid_device *hid)
* be robust against hid errors. Those errors will be raised by
* hid_open_report() anyway.
*/
- while ((start = fetch_item(start, end, &item)) != NULL)
+ while ((start = hid_fetch_item(start, end, &item)) != NULL)
dispatch_type[item.type](parser, &item);
/*
@@ -1255,7 +1265,7 @@ int hid_open_report(struct hid_device *device)
device->collection_size = HID_DEFAULT_NUM_COLLECTIONS;
ret = -EINVAL;
- while ((next = fetch_item(start, end, &item)) != NULL) {
+ while ((next = hid_fetch_item(start, end, &item)) != NULL) {
start = next;
if (item.format != HID_ITEM_FORMAT_SHORT) {
diff --git a/include/linux/hid.h b/include/linux/hid.h
index 4363a63b9775..b39f97d565e2 100644
--- a/include/linux/hid.h
+++ b/include/linux/hid.h
@@ -941,6 +941,10 @@ struct hid_report *hid_validate_values(struct hid_device *hid,
unsigned int field_index,
unsigned int report_counts);
+u32 hid_item_udata(struct hid_item *item);
+s32 hid_item_sdata(struct hid_item *item);
+u8 *hid_fetch_item(__u8 *start, __u8 *end, struct hid_item *item);
+
void hid_setup_resolution_multiplier(struct hid_device *hid);
int hid_open_report(struct hid_device *device);
int hid_check_keys_pressed(struct hid_device *hid);
--
2.38.1
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,35 @@
From 2ae64be127e2aa426afe3f158f13b8a680509a8e Mon Sep 17 00:00:00 2001
From: Aditya Garg <gargaditya08@live.com>
Date: Mon, 7 Nov 2022 01:17:17 +0530
Subject: [PATCH 05/13] HID: quirks: Use touchbar quirks when touchbar driver
is enabled
Signed-off-by: Aditya Garg <gargaditya08@live.com>
---
drivers/hid/hid-quirks.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/hid/hid-quirks.c b/drivers/hid/hid-quirks.c
index cc862fbf1995..32ff8b7b336f 100644
--- a/drivers/hid/hid-quirks.c
+++ b/drivers/hid/hid-quirks.c
@@ -314,12 +314,14 @@ 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_APPLE_IBRIDGE)
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IBRIDGE) },
#endif
+#if IS_ENABLED(CONFIG_HID_APPLE_TOUCHBAR)
+ { 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)
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL2) },
--
2.38.1
@@ -0,0 +1,210 @@
From 6afbbbbb3c8d576c5c15c593e3fd64b80e9474f0 Mon Sep 17 00:00:00 2001
From: Kerem Karabay <kekrby@gmail.com>
Date: Mon, 7 Nov 2022 21:37:44 +0300
Subject: [PATCH 06/13] HID: apple-ibridge: convert to a platform_driver from
an acpi_driver
This commit addresses the issues raised in
https://lore.kernel.org/lkml/CAHp75Vd13nobdyiUbYoTbeoqG4rGP-Vfswcuuy3oYjXgTXzNSw@mail.gmail.com/.
Signed-off-by: Kerem Karabay <kekrby@gmail.com>
---
drivers/hid/Kconfig | 3 +-
drivers/hid/apple-ibridge.c | 67 +++++++++++++++----------------------
2 files changed, 28 insertions(+), 42 deletions(-)
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
index d5a61773a163..476c1fd50520 100644
--- a/drivers/hid/Kconfig
+++ b/drivers/hid/Kconfig
@@ -140,9 +140,8 @@ config HID_APPLE
config HID_APPLE_IBRIDGE
tristate "Apple iBridge"
- depends on ACPI
depends on USB_HID
- depends on X86 || COMPILE_TEST
+ depends on (X86 && ACPI) || COMPILE_TEST
imply HID_APPLE_TOUCHBAR
imply HID_SENSOR_HUB
imply HID_SENSOR_ALS
diff --git a/drivers/hid/apple-ibridge.c b/drivers/hid/apple-ibridge.c
index 5f2b71c19974..d4d15e54eedf 100644
--- a/drivers/hid/apple-ibridge.c
+++ b/drivers/hid/apple-ibridge.c
@@ -40,6 +40,7 @@
* iBridge when suspending and resuming.
*/
+#include <linux/platform_device.h>
#include <linux/acpi.h>
#include <linux/device.h>
#include <linux/hid.h>
@@ -54,8 +55,6 @@
#define APPLEIB_BASIC_CONFIG 1
-#define LOG_DEV(ib_dev) (&(ib_dev)->acpi_dev->dev)
-
static struct hid_device_id appleib_sub_hid_ids[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_LINUX_FOUNDATION,
USB_DEVICE_ID_IBRIDGE_TB) },
@@ -78,8 +77,7 @@ static struct {
};
struct appleib_device {
- struct acpi_device *acpi_dev;
- acpi_handle asoc_socw;
+ acpi_handle asoc_socw;
};
struct appleib_hid_dev_info {
@@ -561,21 +559,19 @@ static struct hid_driver appleib_hid_driver = {
#endif
};
-static struct appleib_device *appleib_alloc_device(struct acpi_device *acpi_dev)
+static struct appleib_device *appleib_alloc_device(struct platform_device *platform_dev)
{
struct appleib_device *ib_dev;
acpi_status sts;
- ib_dev = devm_kzalloc(&acpi_dev->dev, sizeof(*ib_dev), GFP_KERNEL);
+ ib_dev = devm_kzalloc(&platform_dev->dev, sizeof(*ib_dev), GFP_KERNEL);
if (!ib_dev)
return ERR_PTR(-ENOMEM);
- ib_dev->acpi_dev = acpi_dev;
-
/* get iBridge acpi power control method for suspend/resume */
- sts = acpi_get_handle(acpi_dev->handle, "SOCW", &ib_dev->asoc_socw);
+ sts = acpi_get_handle(ACPI_HANDLE(&platform_dev->dev), "SOCW", &ib_dev->asoc_socw);
if (ACPI_FAILURE(sts)) {
- dev_err(LOG_DEV(ib_dev),
+ dev_err(&platform_dev->dev,
"Error getting handle for ASOC.SOCW method: %s\n",
acpi_format_exception(sts));
return ERR_PTR(-ENXIO);
@@ -584,76 +580,70 @@ static struct appleib_device *appleib_alloc_device(struct acpi_device *acpi_dev)
/* ensure iBridge is powered on */
sts = acpi_execute_simple_method(ib_dev->asoc_socw, NULL, 1);
if (ACPI_FAILURE(sts))
- dev_warn(LOG_DEV(ib_dev), "SOCW(1) failed: %s\n",
+ dev_warn(&platform_dev->dev, "SOCW(1) failed: %s\n",
acpi_format_exception(sts));
return ib_dev;
}
-static int appleib_probe(struct acpi_device *acpi)
+static int appleib_probe(struct platform_device *platform_dev)
{
struct appleib_device *ib_dev;
int ret;
- ib_dev = appleib_alloc_device(acpi);
+ ib_dev = appleib_alloc_device(platform_dev);
if (IS_ERR(ib_dev))
return PTR_ERR(ib_dev);
ret = hid_register_driver(&appleib_hid_driver);
if (ret) {
- dev_err(LOG_DEV(ib_dev), "Error registering hid driver: %d\n",
+ dev_err(&platform_dev->dev, "Error registering hid driver: %d\n",
ret);
return ret;
}
- acpi->driver_data = ib_dev;
+ platform_set_drvdata(platform_dev, ib_dev);
return 0;
}
-static int appleib_remove(struct acpi_device *acpi)
+static int appleib_remove(struct platform_device *platform_dev)
{
hid_unregister_driver(&appleib_hid_driver);
return 0;
}
-static int appleib_suspend(struct device *dev)
+static int appleib_suspend(struct platform_device *platform_dev, pm_message_t message)
{
struct appleib_device *ib_dev;
int rc;
- ib_dev = acpi_driver_data(to_acpi_device(dev));
+ ib_dev = platform_get_drvdata(platform_dev);
rc = acpi_execute_simple_method(ib_dev->asoc_socw, NULL, 0);
if (ACPI_FAILURE(rc))
- dev_warn(dev, "SOCW(0) failed: %s\n",
+ dev_warn(&platform_dev->dev, "SOCW(0) failed: %s\n",
acpi_format_exception(rc));
return 0;
}
-static int appleib_resume(struct device *dev)
+static int appleib_resume(struct platform_device *platform_dev)
{
struct appleib_device *ib_dev;
int rc;
- ib_dev = acpi_driver_data(to_acpi_device(dev));
+ ib_dev = platform_get_drvdata(platform_dev);
rc = acpi_execute_simple_method(ib_dev->asoc_socw, NULL, 1);
if (ACPI_FAILURE(rc))
- dev_warn(dev, "SOCW(1) failed: %s\n",
+ dev_warn(&platform_dev->dev, "SOCW(1) failed: %s\n",
acpi_format_exception(rc));
return 0;
}
-static const struct dev_pm_ops appleib_pm = {
- .suspend = appleib_suspend,
- .resume = appleib_resume,
- .restore = appleib_resume,
-};
-
static const struct acpi_device_id appleib_acpi_match[] = {
{ "APP7777", 0 },
{ },
@@ -661,21 +651,18 @@ static const struct acpi_device_id appleib_acpi_match[] = {
MODULE_DEVICE_TABLE(acpi, appleib_acpi_match);
-static struct acpi_driver appleib_driver = {
- .name = "apple-ibridge",
- .class = "apple_ibridge",
- .owner = THIS_MODULE,
- .ids = appleib_acpi_match,
- .ops = {
- .add = appleib_probe,
- .remove = appleib_remove,
- },
- .drv = {
- .pm = &appleib_pm,
+static struct platform_driver appleib_driver = {
+ .probe = appleib_probe,
+ .remove = appleib_remove,
+ .suspend = appleib_suspend,
+ .resume = appleib_resume,
+ .driver = {
+ .name = "apple-ibridge",
+ .acpi_match_table = appleib_acpi_match,
},
};
-module_acpi_driver(appleib_driver)
+module_platform_driver(appleib_driver);
MODULE_AUTHOR("Ronald Tschalär");
MODULE_DESCRIPTION("Apple iBridge driver");
--
2.38.1
@@ -0,0 +1,45 @@
From be7dd12ddd1a85366a989c6c7bda21adc556013d Mon Sep 17 00:00:00 2001
From: Kerem Karabay <kekrby@gmail.com>
Date: Mon, 7 Nov 2022 22:00:09 +0300
Subject: [PATCH 07/13] HID: apple-ibridge: fix appleib_forward_int_op
This commit fixes an issue mentioned in
https://lore.kernel.org/lkml/20210228150239.00007d34@Huawei.com/.
Signed-off-by: Kerem Karabay <kekrby@gmail.com>
---
drivers/hid/apple-ibridge.c | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)
diff --git a/drivers/hid/apple-ibridge.c b/drivers/hid/apple-ibridge.c
index d4d15e54eedf..4caa7820fcf6 100644
--- a/drivers/hid/apple-ibridge.c
+++ b/drivers/hid/apple-ibridge.c
@@ -161,7 +161,7 @@ static int appleib_forward_int_op(struct hid_device *hdev,
{
struct appleib_hid_dev_info *hdev_info = hid_get_drvdata(hdev);
struct hid_device *sub_hdev;
- int rc = 0;
+ int rc;
int i;
for (i = 0; i < ARRAY_SIZE(hdev_info->sub_hdevs); i++) {
@@ -169,13 +169,11 @@ static int appleib_forward_int_op(struct hid_device *hdev,
if (sub_hdev->driver) {
rc = forward(sub_hdev->driver, sub_hdev, args);
if (rc)
- break;
+ return rc;
}
-
- break;
}
- return rc;
+ return 0;
}
static int appleib_hid_suspend_fwd(struct hid_driver *drv,
--
2.38.1
@@ -0,0 +1,135 @@
From 1076dfa2cb823cf51f3843583957fbcb20c2678c Mon Sep 17 00:00:00 2001
From: Kerem Karabay <kekrby@gmail.com>
Date: Tue, 8 Nov 2022 20:48:46 +0300
Subject: [PATCH 08/13] HID: apple-ibridge: rely on hid-core's parsing
This commit addresses the issues raised in
https://lore.kernel.org/lkml/CAO-hwJLXAHvjYKxu8pyqMPCNgMrN-H8bGWudVqCaRFnWODHPVQ@mail.gmail.com/.
Signed-off-by: Kerem Karabay <kekrby@gmail.com>
---
drivers/hid/apple-ibridge.c | 69 ++++---------------------------------
1 file changed, 6 insertions(+), 63 deletions(-)
diff --git a/drivers/hid/apple-ibridge.c b/drivers/hid/apple-ibridge.c
index 4caa7820fcf6..bc070ab034dd 100644
--- a/drivers/hid/apple-ibridge.c
+++ b/drivers/hid/apple-ibridge.c
@@ -328,43 +328,6 @@ static struct hid_ll_driver appleib_ll_driver = {
.output_report = appleib_ll_output_report,
};
-static __u8 *appleib_find_collection(__u8 *start, __u8 *end,
- unsigned int *usage)
-{
- struct hid_item item;
- int depth = 0;
-
- *usage = 0;
-
- while ((start = hid_fetch_item(start, end, &item)) != NULL) {
- if (item.type == HID_ITEM_TYPE_MAIN) {
- switch (item.tag) {
- case HID_MAIN_ITEM_TAG_BEGIN_COLLECTION:
- depth++;
- break;
-
- case HID_MAIN_ITEM_TAG_END_COLLECTION:
- depth--;
- if (depth <= 0)
- return start;
- break;
- }
- } else if (item.type == HID_ITEM_TYPE_GLOBAL &&
- item.tag == HID_GLOBAL_ITEM_TAG_USAGE_PAGE &&
- depth == 0) {
- *usage = (*usage & 0x0000FFFF) |
- ((hid_item_udata(&item) & 0xFFFF) << 16);
- } else if (item.type == HID_ITEM_TYPE_LOCAL &&
- item.tag == HID_LOCAL_ITEM_TAG_USAGE &&
- depth == 0) {
- *usage = (*usage & 0xFFFF0000) |
- (hid_item_udata(&item) & 0xFFFF);
- }
- }
-
- return end;
-}
-
static struct hid_device_id *appleib_find_dev_id_for_usage(unsigned int usage)
{
int i;
@@ -379,7 +342,7 @@ static struct hid_device_id *appleib_find_dev_id_for_usage(unsigned int usage)
static struct hid_device *
appleib_add_sub_dev(struct appleib_hid_dev_info *hdev_info,
- struct hid_device_id *dev_id, u8 *rdesc, size_t rsize)
+ struct hid_device_id *dev_id)
{
struct hid_device *sub_hdev;
int rc;
@@ -404,12 +367,6 @@ appleib_add_sub_dev(struct appleib_hid_dev_info *hdev_info,
sub_hdev->driver_data = hdev_info;
- rc = hid_parse_report(sub_hdev, rdesc, rsize);
- if (rc) {
- hid_destroy_device(sub_hdev);
- return ERR_PTR(rc);
- }
-
rc = hid_add_device(sub_hdev);
if (rc) {
hid_destroy_device(sub_hdev);
@@ -422,9 +379,6 @@ appleib_add_sub_dev(struct appleib_hid_dev_info *hdev_info,
static struct appleib_hid_dev_info *appleib_add_device(struct hid_device *hdev)
{
struct appleib_hid_dev_info *hdev_info;
- __u8 *start = hdev->dev_rdesc;
- __u8 *end = start + hdev->dev_rsize;
- __u8 *pos;
struct hid_device_id *dev_id;
unsigned int usage;
int i;
@@ -435,33 +389,22 @@ static struct appleib_hid_dev_info *appleib_add_device(struct hid_device *hdev)
hdev_info->hdev = hdev;
- for (i = 0; ; ) {
- pos = appleib_find_collection(start, end, &usage);
-
+ for (i = 0; i < hdev->maxcollection; i++) {
+ usage = hdev->collection[i].usage;
dev_id = appleib_find_dev_id_for_usage(usage);
+
if (!dev_id) {
hid_warn(hdev, "Unknown collection encountered with usage %x\n",
usage);
-
- } else if (i >= ARRAY_SIZE(hdev_info->sub_hdevs)) {
- hid_warn(hdev, "Too many collections encountered - ignoring for usage %x\n",
- usage);
} else {
- hdev_info->sub_hdevs[i] =
- appleib_add_sub_dev(hdev_info, dev_id, start,
- pos - start);
+ hdev_info->sub_hdevs[i] = appleib_add_sub_dev(hdev_info, dev_id);
+
if (IS_ERR(hdev_info->sub_hdevs[i])) {
while (i-- > 0)
hid_destroy_device(hdev_info->sub_hdevs[i]);
return (void *)hdev_info->sub_hdevs[i];
}
-
- i++;
}
-
- start = pos;
- if (start >= end)
- break;
}
return hdev_info;
--
2.38.1
@@ -0,0 +1,219 @@
From dcb2fa1b2c8df683b6b86264eb1514eec496e2a0 Mon Sep 17 00:00:00 2001
From: Kerem Karabay <kekrby@gmail.com>
Date: Tue, 8 Nov 2022 20:52:08 +0300
Subject: [PATCH 09/13] Revert "HID: core: Export some report item parsing
functions."
This reverts commit 360637979541fa2f3a64ed54af818f07e4e95a8d as it is no
longer needed as the driver now relies on hid-core for parsing.
Signed-off-by: Kerem Karabay <kekrby@gmail.com>
---
drivers/hid/hid-core.c | 54 +++++++++++++++++-------------------------
include/linux/hid.h | 4 ----
2 files changed, 22 insertions(+), 36 deletions(-)
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index f0d914238e55..8fcd663b10e2 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -343,7 +343,7 @@ static int hid_add_field(struct hid_parser *parser, unsigned report_type, unsign
* Read data value from item.
*/
-u32 hid_item_udata(struct hid_item *item)
+static u32 item_udata(struct hid_item *item)
{
switch (item->size) {
case 1: return item->data.u8;
@@ -352,9 +352,8 @@ u32 hid_item_udata(struct hid_item *item)
}
return 0;
}
-EXPORT_SYMBOL_GPL(hid_item_udata);
-s32 hid_item_sdata(struct hid_item *item)
+static s32 item_sdata(struct hid_item *item)
{
switch (item->size) {
case 1: return item->data.s8;
@@ -363,7 +362,6 @@ s32 hid_item_sdata(struct hid_item *item)
}
return 0;
}
-EXPORT_SYMBOL_GPL(hid_item_sdata);
/*
* Process a global item.
@@ -396,29 +394,29 @@ static int hid_parser_global(struct hid_parser *parser, struct hid_item *item)
return 0;
case HID_GLOBAL_ITEM_TAG_USAGE_PAGE:
- parser->global.usage_page = hid_item_udata(item);
+ parser->global.usage_page = item_udata(item);
return 0;
case HID_GLOBAL_ITEM_TAG_LOGICAL_MINIMUM:
- parser->global.logical_minimum = hid_item_sdata(item);
+ parser->global.logical_minimum = item_sdata(item);
return 0;
case HID_GLOBAL_ITEM_TAG_LOGICAL_MAXIMUM:
if (parser->global.logical_minimum < 0)
- parser->global.logical_maximum = hid_item_sdata(item);
+ parser->global.logical_maximum = item_sdata(item);
else
- parser->global.logical_maximum = hid_item_udata(item);
+ parser->global.logical_maximum = item_udata(item);
return 0;
case HID_GLOBAL_ITEM_TAG_PHYSICAL_MINIMUM:
- parser->global.physical_minimum = hid_item_sdata(item);
+ parser->global.physical_minimum = item_sdata(item);
return 0;
case HID_GLOBAL_ITEM_TAG_PHYSICAL_MAXIMUM:
if (parser->global.physical_minimum < 0)
- parser->global.physical_maximum = hid_item_sdata(item);
+ parser->global.physical_maximum = item_sdata(item);
else
- parser->global.physical_maximum = hid_item_udata(item);
+ parser->global.physical_maximum = item_udata(item);
return 0;
case HID_GLOBAL_ITEM_TAG_UNIT_EXPONENT:
@@ -426,7 +424,7 @@ static int hid_parser_global(struct hid_parser *parser, struct hid_item *item)
* nibble due to the common misunderstanding of HID
* specification 1.11, 6.2.2.7 Global Items. Attempt to handle
* both this and the standard encoding. */
- raw_value = hid_item_sdata(item);
+ raw_value = item_sdata(item);
if (!(raw_value & 0xfffffff0))
parser->global.unit_exponent = hid_snto32(raw_value, 4);
else
@@ -434,11 +432,11 @@ static int hid_parser_global(struct hid_parser *parser, struct hid_item *item)
return 0;
case HID_GLOBAL_ITEM_TAG_UNIT:
- parser->global.unit = hid_item_udata(item);
+ parser->global.unit = item_udata(item);
return 0;
case HID_GLOBAL_ITEM_TAG_REPORT_SIZE:
- parser->global.report_size = hid_item_udata(item);
+ parser->global.report_size = item_udata(item);
if (parser->global.report_size > 256) {
hid_err(parser->device, "invalid report_size %d\n",
parser->global.report_size);
@@ -447,7 +445,7 @@ static int hid_parser_global(struct hid_parser *parser, struct hid_item *item)
return 0;
case HID_GLOBAL_ITEM_TAG_REPORT_COUNT:
- parser->global.report_count = hid_item_udata(item);
+ parser->global.report_count = item_udata(item);
if (parser->global.report_count > HID_MAX_USAGES) {
hid_err(parser->device, "invalid report_count %d\n",
parser->global.report_count);
@@ -456,7 +454,7 @@ static int hid_parser_global(struct hid_parser *parser, struct hid_item *item)
return 0;
case HID_GLOBAL_ITEM_TAG_REPORT_ID:
- parser->global.report_id = hid_item_udata(item);
+ parser->global.report_id = item_udata(item);
if (parser->global.report_id == 0 ||
parser->global.report_id >= HID_MAX_IDS) {
hid_err(parser->device, "report_id %u is invalid\n",
@@ -481,7 +479,7 @@ static int hid_parser_local(struct hid_parser *parser, struct hid_item *item)
unsigned n;
__u32 count;
- data = hid_item_udata(item);
+ data = item_udata(item);
switch (item->tag) {
case HID_LOCAL_ITEM_TAG_DELIMITER:
@@ -613,7 +611,7 @@ static int hid_parser_main(struct hid_parser *parser, struct hid_item *item)
hid_concatenate_last_usage_page(parser);
- data = hid_item_udata(item);
+ data = item_udata(item);
switch (item->tag) {
case HID_MAIN_ITEM_TAG_BEGIN_COLLECTION:
@@ -714,19 +712,12 @@ static void hid_device_release(struct device *dev)
kfree(hid);
}
-/**
- * hid_fetch_item - fetch an item from a report
- *
- * @start: the current position in the report buffer to read the next item from
- * @end: the end of the report buffer
- * @item: the item struct to fill in
- *
+/*
* Fetch a report description item from the data stream. We support long
* items, though they are not used yet.
- *
- * Return: the position of the next item in the report
*/
-u8 *hid_fetch_item(__u8 *start, __u8 *end, struct hid_item *item)
+
+static u8 *fetch_item(__u8 *start, __u8 *end, struct hid_item *item)
{
u8 b;
@@ -787,7 +778,6 @@ u8 *hid_fetch_item(__u8 *start, __u8 *end, struct hid_item *item)
return NULL;
}
-EXPORT_SYMBOL_GPL(hid_fetch_item);
static void hid_scan_input_usage(struct hid_parser *parser, u32 usage)
{
@@ -846,7 +836,7 @@ static int hid_scan_main(struct hid_parser *parser, struct hid_item *item)
hid_concatenate_last_usage_page(parser);
- data = hid_item_udata(item);
+ data = item_udata(item);
switch (item->tag) {
case HID_MAIN_ITEM_TAG_BEGIN_COLLECTION:
@@ -906,7 +896,7 @@ static int hid_scan_report(struct hid_device *hid)
* be robust against hid errors. Those errors will be raised by
* hid_open_report() anyway.
*/
- while ((start = hid_fetch_item(start, end, &item)) != NULL)
+ while ((start = fetch_item(start, end, &item)) != NULL)
dispatch_type[item.type](parser, &item);
/*
@@ -1265,7 +1255,7 @@ int hid_open_report(struct hid_device *device)
device->collection_size = HID_DEFAULT_NUM_COLLECTIONS;
ret = -EINVAL;
- while ((next = hid_fetch_item(start, end, &item)) != NULL) {
+ while ((next = fetch_item(start, end, &item)) != NULL) {
start = next;
if (item.format != HID_ITEM_FORMAT_SHORT) {
diff --git a/include/linux/hid.h b/include/linux/hid.h
index b39f97d565e2..4363a63b9775 100644
--- a/include/linux/hid.h
+++ b/include/linux/hid.h
@@ -941,10 +941,6 @@ struct hid_report *hid_validate_values(struct hid_device *hid,
unsigned int field_index,
unsigned int report_counts);
-u32 hid_item_udata(struct hid_item *item);
-s32 hid_item_sdata(struct hid_item *item);
-u8 *hid_fetch_item(__u8 *start, __u8 *end, struct hid_item *item);
-
void hid_setup_resolution_multiplier(struct hid_device *hid);
int hid_open_report(struct hid_device *device);
int hid_check_keys_pressed(struct hid_device *hid);
--
2.38.1
@@ -0,0 +1,31 @@
From 4df962ed303d55664fd4a3e92118d8030d5000d2 Mon Sep 17 00:00:00 2001
From: Kerem Karabay <kekrby@gmail.com>
Date: Wed, 9 Nov 2022 18:21:50 +0300
Subject: [PATCH 10/13] HID: apple-touchbar: use product IDs from hid-ids.h
Signed-off-by: Kerem Karabay <kekrby@gmail.com>
---
drivers/hid/apple-touchbar.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/hid/apple-touchbar.c b/drivers/hid/apple-touchbar.c
index 87cb9ebafb61..69e03173db3a 100644
--- a/drivers/hid/apple-touchbar.c
+++ b/drivers/hid/apple-touchbar.c
@@ -1466,9 +1466,11 @@ static const struct hid_device_id appletb_hid_ids[] = {
USB_DEVICE_ID_IBRIDGE_TB),
.driver_data = APPLETB_FEATURE_IS_T1 },
/* MacBook Pro's 2018, 2019, with T2 chip: iBridge DFR brightness */
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, 0x8102) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE,
+ USB_DEVICE_ID_APPLE_TOUCHBAR_BACKLIGHT) },
/* MacBook Pro's 2018, 2019, with T2 chip: iBridge Display */
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, 0x8302) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE,
+ USB_DEVICE_ID_APPLE_TOUCHBAR_DISPLAY) },
{ },
};
--
2.38.1
@@ -0,0 +1,116 @@
From a7d71c39ee7a705b7c26714f82ba14cb6d45b084 Mon Sep 17 00:00:00 2001
From: Kerem Karabay <kekrby@gmail.com>
Date: Wed, 9 Nov 2022 21:54:56 +0300
Subject: [PATCH 11/13] HID: apple-touchbar: make the signature of
appletb_send_usb_ctrl more similar to the signature of hid_hw_raw_request
Signed-off-by: Kerem Karabay <kekrby@gmail.com>
---
drivers/hid/apple-touchbar.c | 53 +++++++++++++++++++++---------------
1 file changed, 31 insertions(+), 22 deletions(-)
diff --git a/drivers/hid/apple-touchbar.c b/drivers/hid/apple-touchbar.c
index 69e03173db3a..5e41e62b1a6c 100644
--- a/drivers/hid/apple-touchbar.c
+++ b/drivers/hid/apple-touchbar.c
@@ -199,20 +199,31 @@ static const struct appletb_key_translation appletb_fn_codes[] = {
static struct appletb_device *appletb_dev;
-static int appletb_send_usb_ctrl(struct appletb_iface_info *iface_info,
- __u8 requesttype, struct hid_report *report,
- void *data, __u16 size)
+static int appletb_hw_raw_request(struct appletb_iface_info *iface_info,
+ unsigned char reportnum, __u8 *buf,
+ size_t len, unsigned char rtype,
+ int reqtype, __u8 usbtype)
{
struct usb_device *dev = interface_to_usbdev(iface_info->usb_iface);
u8 ifnum = iface_info->usb_iface->cur_altsetting->desc.bInterfaceNumber;
+ int direction;
int tries = 0;
+ int pipe;
int rc;
+ if (reqtype == HID_REQ_SET_REPORT) {
+ direction = USB_DIR_OUT;
+ pipe = usb_sndctrlpipe(dev, 0);
+ } else {
+ direction = USB_DIR_IN;
+ pipe = usb_rcvctrlpipe(dev, 0);
+ }
+
do {
- rc = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
- HID_REQ_SET_REPORT, requesttype,
- (report->type + 1) << 8 | report->id,
- ifnum, data, size, 2000);
+ rc = usb_control_msg(dev, pipe, reqtype,
+ direction | USB_RECIP_INTERFACE | usbtype,
+ (rtype + 1) << 8 | reportnum,
+ ifnum, buf, len, 2000);
if (rc != -EPIPE)
break;
@@ -268,15 +279,14 @@ static int appletb_set_tb_mode(struct appletb_device *tb_dev,
autopm_off = appletb_disable_autopm(tb_dev->mode_iface.hdev);
if (tb_dev->is_t1)
- rc = appletb_send_usb_ctrl(&tb_dev->mode_iface,
- USB_DIR_OUT | USB_TYPE_VENDOR |
- USB_RECIP_DEVICE,
- report, buf, 1);
+ rc = appletb_hw_raw_request(&tb_dev->mode_iface, report->id,
+ (__u8 *) buf, 1, report->type,
+ HID_REQ_SET_REPORT, USB_TYPE_VENDOR);
else
- rc = appletb_send_usb_ctrl(&tb_dev->mode_iface,
- USB_DIR_OUT | USB_TYPE_CLASS |
- USB_RECIP_INTERFACE,
- report, buf, 2);
+ rc = appletb_hw_raw_request(&tb_dev->mode_iface, report->id,
+ (__u8 *) buf, 2, report->type,
+ HID_REQ_SET_REPORT, USB_TYPE_CLASS);
+
if (rc < 0)
dev_err(tb_dev->log_dev,
"Failed to set touch bar mode to %u (%d)\n", mode, rc);
@@ -293,10 +303,10 @@ static int appletb_set_tb_mode(struct appletb_device *tb_dev,
* We don't use hid_hw_request() because that doesn't allow us to get the
* returned status from the usb-control request; we also don't use
* hid_hw_raw_request() because would mean duplicating the retry-on-EPIPE
- * in our appletb_send_usb_ctrl().
+ * in our appletb_hw_raw_request().
*/
static int appletb_send_hid_report(struct appletb_iface_info *iface_info,
- struct hid_report *report)
+ struct hid_report *report, int reqtype)
{
unsigned char *buf;
int rc;
@@ -307,10 +317,9 @@ static int appletb_send_hid_report(struct appletb_iface_info *iface_info,
hid_output_report(report, buf);
- rc = appletb_send_usb_ctrl(iface_info,
- USB_DIR_OUT | USB_TYPE_CLASS |
- USB_RECIP_INTERFACE,
- report, buf, hid_report_len(report));
+ rc = appletb_hw_raw_request(iface_info, report->id, (__u8 *) buf,
+ hid_report_len(report), report->type,
+ reqtype, USB_TYPE_CLASS);
kfree(buf);
@@ -350,7 +359,7 @@ static int appletb_set_tb_disp(struct appletb_device *tb_dev,
tb_dev->tb_autopm_off =
appletb_disable_autopm(report->device);
- rc = appletb_send_hid_report(&tb_dev->disp_iface, report);
+ rc = appletb_send_hid_report(&tb_dev->disp_iface, report, HID_REQ_SET_REPORT);
if (rc < 0)
dev_err(tb_dev->log_dev,
"Failed to set touch bar display to %u (%d)\n", disp,
--
2.38.1
@@ -0,0 +1,68 @@
From 19b1e4c8aea89d67d299f885d07846e756c9fe2d Mon Sep 17 00:00:00 2001
From: Kerem Karabay <kekrby@gmail.com>
Date: Sat, 12 Nov 2022 20:44:07 +0300
Subject: [PATCH 12/13] HID: apple-touchbar: simplify appletb_set_tb_mode
Signed-off-by: Kerem Karabay <kekrby@gmail.com>
---
drivers/hid/apple-touchbar.c | 31 +++++++++++++++++--------------
1 file changed, 17 insertions(+), 14 deletions(-)
diff --git a/drivers/hid/apple-touchbar.c b/drivers/hid/apple-touchbar.c
index 5e41e62b1a6c..40c12886e651 100644
--- a/drivers/hid/apple-touchbar.c
+++ b/drivers/hid/apple-touchbar.c
@@ -258,8 +258,11 @@ static int appletb_set_tb_mode(struct appletb_device *tb_dev,
unsigned char mode)
{
struct hid_report *report;
- void *buf;
bool autopm_off = false;
+ __u8 usbtype;
+ char data[2];
+ size_t len;
+ void *buf;
int rc;
if (!tb_dev->mode_iface.hdev)
@@ -268,24 +271,24 @@ static int appletb_set_tb_mode(struct appletb_device *tb_dev,
report = tb_dev->mode_field->report;
if (tb_dev->is_t1) {
- buf = kmemdup(&mode, 1, GFP_KERNEL);
+ len = sizeof(mode);
+ buf = &mode;
+ usbtype = USB_TYPE_VENDOR;
} else {
- char data[] = { report->id, mode };
- buf = kmemdup(data, sizeof(data), GFP_KERNEL);
+ len = sizeof(data);
+ data[0] = report->id;
+ data[1] = mode;
+ buf = data;
+ usbtype = USB_TYPE_CLASS;
}
- if (!buf)
- return -ENOMEM;
+
+ buf = kmemdup(buf, len, GFP_KERNEL);
autopm_off = appletb_disable_autopm(tb_dev->mode_iface.hdev);
- if (tb_dev->is_t1)
- rc = appletb_hw_raw_request(&tb_dev->mode_iface, report->id,
- (__u8 *) buf, 1, report->type,
- HID_REQ_SET_REPORT, USB_TYPE_VENDOR);
- else
- rc = appletb_hw_raw_request(&tb_dev->mode_iface, report->id,
- (__u8 *) buf, 2, report->type,
- HID_REQ_SET_REPORT, USB_TYPE_CLASS);
+ rc = appletb_hw_raw_request(&tb_dev->mode_iface, report->id,
+ buf, len, HID_OUTPUT_REPORT,
+ HID_REQ_SET_REPORT, usbtype);
if (rc < 0)
dev_err(tb_dev->log_dev,
--
2.38.1
+314
View File
@@ -0,0 +1,314 @@
From c8edf1748a3829b99085bd8e2593a3c46e767d9a Mon Sep 17 00:00:00 2001
From: Orlando Chamberlain <redecorating@protonmail.com>
Date: Mon, 14 Nov 2022 17:29:52 +0300
Subject: [PATCH 13/13] HID: apple-magic-backlight: init
This driver is based on the work of Orlando Chamberlain
<redecorating@protonmail.com> at
https://github.com/Redecorating/apple-ib-drv/commit/467df9b11cb55456f0365f40dd11c9e666623bf3.
Co-authored-by: Kerem Karabay <kekrby@gmail.com>
Signed-off-by: Kerem Karabay <kekrby@gmail.com>
NOTE: This commit hasn't been signed off yet by Orlando Chamberlain
---
drivers/hid/Kconfig | 10 ++
drivers/hid/Makefile | 1 +
drivers/hid/apple-magic-backlight.c | 171 ++++++++++++++++++++++++++++
drivers/hid/apple-touchbar.c | 4 +
drivers/hid/apple-touchbar.h | 50 ++++++++
5 files changed, 236 insertions(+)
create mode 100644 drivers/hid/apple-magic-backlight.c
create mode 100644 drivers/hid/apple-touchbar.h
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
index 476c1fd50520..a382578b1dd7 100644
--- a/drivers/hid/Kconfig
+++ b/drivers/hid/Kconfig
@@ -163,6 +163,16 @@ config HID_APPLE_TOUCHBAR
To compile this driver as a module, choose M here: the
module will be called apple-touchbar.
+config HID_APPLE_MAGIC_BACKLIGHT
+ tristate "Apple Touch Bar"
+ help
+ Say Y here if you want support for the keyboard backlight on Macs with
+ the magic keyboard (MacBookPro16,x and MacBookAir9,1). Note that this
+ driver is not for external magic keyboards.
+
+ To compile this driver as a module, choose M here: the
+ module will be called apple-magic-backlight.
+
config HID_APPLEIR
tristate "Apple infrared receiver"
depends on (USB_HID)
diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile
index 3f0706a459ee..dd65c49c9d17 100644
--- a/drivers/hid/Makefile
+++ b/drivers/hid/Makefile
@@ -28,6 +28,7 @@ obj-$(CONFIG_HID_ACRUX) += hid-axff.o
obj-$(CONFIG_HID_APPLE) += hid-apple.o
obj-$(CONFIG_HID_APPLE_IBRIDGE) += apple-ibridge.o
obj-$(CONFIG_HID_APPLE_TOUCHBAR) += apple-touchbar.o
+obj-$(CONFIG_HID_APPLE_MAGIC_BACKLIGHT) += apple-magic-backlight.o
obj-$(CONFIG_HID_APPLEIR) += hid-appleir.o
obj-$(CONFIG_HID_CREATIVE_SB0540) += hid-creative-sb0540.o
obj-$(CONFIG_HID_ASUS) += hid-asus.o
diff --git a/drivers/hid/apple-magic-backlight.c b/drivers/hid/apple-magic-backlight.c
new file mode 100644
index 000000000000..016145cfa39d
--- /dev/null
+++ b/drivers/hid/apple-magic-backlight.c
@@ -0,0 +1,171 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Apple Magic Backlight Driver
+ *
+ * Copyright (c) 2022 Orlando Chamberlain <redecorating@protonmail.com>
+ * Copyright (c) 2022 Kerem Karabay <kekrby@gmail.com>
+ */
+
+#include <linux/module.h>
+#include <linux/hid.h>
+#include <linux/usb.h>
+
+#include "apple-touchbar.h"
+#include "hid-ids.h"
+
+#define APPLE_MAGIC_BL_MAX 60
+
+struct apple_magic_backlight {
+ struct led_classdev cdev;
+ struct hid_device *hdev;
+ bool powered;
+};
+
+struct apple_magic_backlight_brightness_report {
+ u8 id; /* 0x01 */
+ u8 mode; /* If 0x00, brightness can turn off backlight */
+ u8 brightness;
+ u8 override_1; /* If these are non-zero, backlight is overridden to max brightness */
+ u8 override_2;
+ u8 max; /* Lower is brighter, only takes effect when turning backlight
+ * on from off, can be unreliable
+ */
+ u8 rate;
+ u8 magic_1; /* If these are non-zero, we are ignored. */
+ u8 magic_2;
+};
+
+struct apple_magic_backlight_power_report {
+ u8 id; /* 0x03 */
+ u8 power;
+ u8 max; /* Lower is brighter, only takes effect when turning backlight
+ * on from off, can be unreliable
+ */
+ u8 rate;
+ u8 magic_1; /* If these are non-zero, we are ignored. */
+ u8 magic_2;
+};
+
+static int apple_magic_backlight_power_set(struct apple_magic_backlight *backlight,
+ char power, char rate)
+{
+ struct apple_magic_backlight_power_report *rep;
+ int ret;
+
+ rep = kmalloc(sizeof(*rep), GFP_KERNEL);
+ if (rep == NULL)
+ return -ENOMEM;
+
+ backlight->powered = power ? true : false;
+
+ rep->id = 0x03;
+ rep->power = power;
+ rep->max = 0x5e; /* Windows uses 0x5e when turning on, and 0xf4 when
+ * turning off. When it's off it doesn't matter, so
+ * use 0x5e
+ */
+ rep->rate = rate;
+
+ ret = hid_hw_raw_request(backlight->hdev, 0x03, (__u8 *) rep, sizeof(*rep),
+ HID_FEATURE_REPORT, HID_REQ_SET_REPORT);
+ kfree(rep);
+ return ret;
+}
+
+static int apple_magic_backlight_brightness_set(struct apple_magic_backlight *backlight,
+ char brightness, char rate)
+{
+ struct apple_magic_backlight_brightness_report *rep;
+ int ret;
+
+ rep = kmalloc(sizeof(*rep), GFP_KERNEL);
+ if (rep == NULL)
+ return -ENOMEM;
+
+ rep->id = 0x01;
+ rep->mode = brightness;
+ rep->brightness = brightness;
+ rep->max = 0x5e;
+ rep->rate = rate;
+
+ ret = hid_hw_raw_request(backlight->hdev, 0x01, (__u8 *) rep, sizeof(*rep),
+ HID_FEATURE_REPORT, HID_REQ_SET_REPORT);
+
+ return ret;
+}
+
+static int apple_magic_backlight_set(struct apple_magic_backlight *backlight,
+ char brightness, char rate)
+{
+ int ret;
+
+ if (!brightness)
+ return apple_magic_backlight_power_set(backlight, 0, rate);
+
+ ret = apple_magic_backlight_brightness_set(backlight, brightness, rate);
+ if (ret)
+ return ret;
+
+ if (!backlight->powered && brightness)
+ ret = apple_magic_backlight_power_set(backlight, 1, rate);
+
+ return ret;
+}
+
+static int apple_magic_backlight_led_set(struct led_classdev *led_cdev,
+ enum led_brightness brightness)
+{
+ struct apple_magic_backlight *backlight = container_of(led_cdev,
+ struct apple_magic_backlight, cdev);
+
+ return apple_magic_backlight_set(backlight, brightness, 1);
+}
+
+static int apple_magic_backlight_probe(struct hid_device *hdev,
+ const struct hid_device_id *id)
+{
+ struct apple_magic_backlight *backlight;
+ int ret;
+
+ if (!appletb_is_hdev_for_magic_backlight(hdev))
+ return -ENODEV;
+
+ backlight = devm_kzalloc(&hdev->dev, sizeof(*backlight), GFP_KERNEL);
+
+ if (!backlight) {
+ hid_err(hdev, "Failed to allocate backlight structure");
+ return -ENOMEM;
+ }
+
+ backlight->hdev = hdev;
+ backlight->cdev.name = "apple::kbd_backlight";
+ backlight->cdev.max_brightness = APPLE_MAGIC_BL_MAX;
+ backlight->cdev.brightness_set_blocking = apple_magic_backlight_led_set;
+
+ ret = apple_magic_backlight_set(backlight, 0, 0);
+
+ if (ret) {
+ hid_err(hdev, "Failed to initialise Magic Keyboard Backlight (%d)\n", ret);
+ return ret;
+ }
+
+ return devm_led_classdev_register(&hdev->dev, &backlight->cdev);
+}
+
+static const struct hid_device_id apple_magic_backlight_hid_ids[] = {
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_TOUCHBAR_BACKLIGHT) },
+ { }
+};
+
+static struct hid_driver apple_magic_backlight_hid_driver = {
+ .name = "apple-magic-backlight",
+ .id_table = apple_magic_backlight_hid_ids,
+ .probe = apple_magic_backlight_probe,
+};
+
+module_hid_driver(apple_magic_backlight_hid_driver);
+
+MODULE_DESCRIPTION("MacBook Magic Keyboard Backlight");
+MODULE_AUTHOR("Orlando Chamberlain <redecorating@protonmail.com>");
+MODULE_LICENSE("GPL");
+MODULE_DEVICE_TABLE(hid, apple_magic_backlight_hid_ids);
diff --git a/drivers/hid/apple-touchbar.c b/drivers/hid/apple-touchbar.c
index 40c12886e651..89b401944b28 100644
--- a/drivers/hid/apple-touchbar.c
+++ b/drivers/hid/apple-touchbar.c
@@ -42,6 +42,7 @@
#include "hid-ids.h"
#include "apple-ibridge.h"
+#include "apple-touchbar.h"
#define HID_UP_APPLE 0xff120000
#define HID_USAGE_MODE (HID_UP_CUSTOM | 0x0004)
@@ -1222,6 +1223,9 @@ static int appletb_probe(struct hid_device *hdev,
unsigned long flags;
int rc;
+ if (appletb_is_hdev_for_magic_backlight(hdev))
+ return -ENODEV;
+
spin_lock_irqsave(&tb_dev->tb_lock, flags);
if (!tb_dev->log_dev)
diff --git a/drivers/hid/apple-touchbar.h b/drivers/hid/apple-touchbar.h
new file mode 100644
index 000000000000..7383fa06edf2
--- /dev/null
+++ b/drivers/hid/apple-touchbar.h
@@ -0,0 +1,50 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Helpers for apple-touchbar and apple-magic-keyboard
+ *
+ * Copyright (c) 2022 Kerem Karabay <kekrby@gmail.com>
+ */
+#ifndef __HID_APPLE_TOUCHBAR_H
+#define __HID_APPLE_TOUCHBAR_H
+
+#include <linux/usb.h>
+#include <linux/hid.h>
+
+#include "hid-ids.h"
+
+static int __appletb_match_display(struct device *dev, const void *data)
+{
+ struct usb_device_descriptor *desc;
+
+ if (strcmp(dev->type->name, "usb_interface") != 0)
+ return 0;
+
+ desc = &interface_to_usbdev(to_usb_interface(dev))->descriptor;
+
+ return desc->idVendor == USB_VENDOR_ID_APPLE && desc->idProduct == USB_DEVICE_ID_APPLE_TOUCHBAR_DISPLAY;
+}
+
+static inline bool appletb_is_hdev_for_magic_backlight(struct hid_device *hdev) {
+ __u8 bInterfaceNumber;
+ struct device *tb_disp;
+ struct device *parent = hdev->dev.parent;
+ struct usb_interface *iface = to_usb_interface(parent);
+ struct usb_device_descriptor *desc = &interface_to_usbdev(iface)->descriptor;
+
+ if (!(desc->idVendor == USB_VENDOR_ID_APPLE && desc->idProduct == USB_DEVICE_ID_APPLE_TOUCHBAR_BACKLIGHT))
+ return false;
+
+ tb_disp = bus_find_device(parent->bus, NULL, NULL, __appletb_match_display);
+ bInterfaceNumber = iface->cur_altsetting->desc.bInterfaceNumber;
+
+ put_device(tb_disp);
+
+ /*
+ * The backlight of a magic keyboard is managed using the 1st interface
+ * of the "Touch Bar Backlight" device if a touchbar is present. If
+ * not, the 0th interface should be used.
+ */
+ return (tb_disp && bInterfaceNumber == 1) || (!tb_disp && bInterfaceNumber == 0);
+}
+
+#endif // __HID_APPLE_TOUCHBAR_H
--
2.38.1