From 251e103172002bb5af5b359c281fc75e4b9e66db Mon Sep 17 00:00:00 2001 From: James Lambert Date: Sat, 20 Feb 2021 08:39:12 +0000 Subject: [PATCH] Initial Commit --- ...nd-CONFIG-to-disallow-unprivileged-C.patch | 154 + ...pple-Magic-Trackpad-2-to-hid_have_sp.patch | 36 + ...wifi-provide-gso_type-to-GSO-packets.patch | 52 + ...Force-link_rate-as-LINK_RATE_RBR2-fo.patch | 60 + ...convert-static-structures-to-drvdata.patch | 1218 ++ ...lesmc-make-io-port-base-addr-dynamic.patch | 312 + ...-switch-to-acpi_device-from-platform.patch | 267 + 3004-applesmc-key-interface-wrappers.patch | 298 + ...-basic-mmio-interface-implementation.patch | 343 + 3006-applesmc-fan-support-on-T2-Macs.patch | 227 + ...pport-for-keyboard-backlight-on-supp.patch | 195 + ...pport-for-MacbookAir8-1-keyboard-tra.patch | 112 + ...pport-for-MacBookPro15-2-keyboard-tr.patch | 110 + ...pport-for-MacBookPro15-1-keyboard-tr.patch | 110 + ...pport-for-MacBookPro15-4-keyboard-tr.patch | 110 + ...pport-for-MacBookPro16-2-keyboard-tr.patch | 111 + ...pport-for-MacBookAir9-1-keyboard-tra.patch | 110 + ...pport-for-MacBookPro16-1-keyboard-tr.patch | 110 + ...-brcmf_mp_device-into-its-own-header.patch | 120 + ...lity-to-manually-specify-FW-rambase-.patch | 224 + ...dd-support-for-Apple-T2-attached-iSi.patch | 38 + ...iscard-BIOS-framebuffers-exceeding-h.patch | 40 + ...Add-initial-support-for-the-BRCM4355.patch | 79 + ...Add-initial-support-for-the-BRCM4377.patch | 80 + PKGBUILD | 265 + README.md | 6 + config | 10180 ++++++++++++++++ linux-5.10.12.tar.sign | 19 + wifi-bigsur.patch | 790 ++ 29 files changed, 15776 insertions(+) create mode 100644 0001-ZEN-Add-sysctl-and-CONFIG-to-disallow-unprivileged-C.patch create mode 100644 0002-HID-quirks-Add-Apple-Magic-Trackpad-2-to-hid_have_sp.patch create mode 100644 0003-iwlwifi-provide-gso_type-to-GSO-packets.patch create mode 100644 2001-drm-amd-display-Force-link_rate-as-LINK_RATE_RBR2-fo.patch create mode 100644 3001-applesmc-convert-static-structures-to-drvdata.patch create mode 100644 3002-applesmc-make-io-port-base-addr-dynamic.patch create mode 100644 3003-applesmc-switch-to-acpi_device-from-platform.patch create mode 100644 3004-applesmc-key-interface-wrappers.patch create mode 100644 3005-applesmc-basic-mmio-interface-implementation.patch create mode 100644 3006-applesmc-fan-support-on-T2-Macs.patch create mode 100644 4001-HID-apple-Add-support-for-keyboard-backlight-on-supp.patch create mode 100644 4002-HID-apple-Add-support-for-MacbookAir8-1-keyboard-tra.patch create mode 100644 4003-HID-apple-Add-support-for-MacBookPro15-2-keyboard-tr.patch create mode 100644 4004-HID-apple-Add-support-for-MacBookPro15-1-keyboard-tr.patch create mode 100644 4005-HID-apple-Add-support-for-MacBookPro15-4-keyboard-tr.patch create mode 100644 4006-HID-apple-Add-support-for-MacBookPro16-2-keyboard-tr.patch create mode 100644 4007-HID-apple-Add-support-for-MacBookAir9-1-keyboard-tra.patch create mode 100644 4008-HID-apple-Add-support-for-MacBookPro16-1-keyboard-tr.patch create mode 100644 5001-brcmfmac-move-brcmf_mp_device-into-its-own-header.patch create mode 100644 5002-brcmfmac-Add-ability-to-manually-specify-FW-rambase-.patch create mode 100644 6001-media-uvcvideo-Add-support-for-Apple-T2-attached-iSi.patch create mode 100644 7001-drm-i915-fbdev-Discard-BIOS-framebuffers-exceeding-h.patch create mode 100644 8001-brcmfmac-Add-initial-support-for-the-BRCM4355.patch create mode 100644 8002-brcmfmac-Add-initial-support-for-the-BRCM4377.patch create mode 100644 PKGBUILD create mode 100644 README.md create mode 100644 config create mode 100644 linux-5.10.12.tar.sign create mode 100644 wifi-bigsur.patch diff --git a/0001-ZEN-Add-sysctl-and-CONFIG-to-disallow-unprivileged-C.patch b/0001-ZEN-Add-sysctl-and-CONFIG-to-disallow-unprivileged-C.patch new file mode 100644 index 0000000..3a7d755 --- /dev/null +++ b/0001-ZEN-Add-sysctl-and-CONFIG-to-disallow-unprivileged-C.patch @@ -0,0 +1,154 @@ +From 51b77e4f052b0717eaa69cfd9b62978da58d9d02 Mon Sep 17 00:00:00 2001 +From: "Jan Alexander Steffens (heftig)" +Date: Mon, 16 Sep 2019 04:53:20 +0200 +Subject: [PATCH 1/3] ZEN: Add sysctl and CONFIG to disallow unprivileged + CLONE_NEWUSER + +Our default behavior continues to match the vanilla kernel. +--- + include/linux/user_namespace.h | 4 ++++ + init/Kconfig | 16 ++++++++++++++++ + kernel/fork.c | 14 ++++++++++++++ + kernel/sysctl.c | 12 ++++++++++++ + kernel/user_namespace.c | 7 +++++++ + 5 files changed, 53 insertions(+) + +diff --git a/include/linux/user_namespace.h b/include/linux/user_namespace.h +index 6ef1c7109fc4..2140091b0b8d 100644 +--- a/include/linux/user_namespace.h ++++ b/include/linux/user_namespace.h +@@ -106,6 +106,8 @@ void dec_ucount(struct ucounts *ucounts, enum ucount_type type); + + #ifdef CONFIG_USER_NS + ++extern int unprivileged_userns_clone; ++ + static inline struct user_namespace *get_user_ns(struct user_namespace *ns) + { + if (ns) +@@ -139,6 +141,8 @@ extern bool current_in_userns(const struct user_namespace *target_ns); + struct ns_common *ns_get_owner(struct ns_common *ns); + #else + ++#define unprivileged_userns_clone 0 ++ + static inline struct user_namespace *get_user_ns(struct user_namespace *ns) + { + return &init_user_ns; +diff --git a/init/Kconfig b/init/Kconfig +index 0872a5a2e759..a40d8afeb1bb 100644 +--- a/init/Kconfig ++++ b/init/Kconfig +@@ -1173,6 +1173,22 @@ config USER_NS + + If unsure, say N. + ++config USER_NS_UNPRIVILEGED ++ bool "Allow unprivileged users to create namespaces" ++ default y ++ depends on USER_NS ++ help ++ When disabled, unprivileged users will not be able to create ++ new namespaces. Allowing users to create their own namespaces ++ has been part of several recent local privilege escalation ++ exploits, so if you need user namespaces but are ++ paranoid^Wsecurity-conscious you want to disable this. ++ ++ This setting can be overridden at runtime via the ++ kernel.unprivileged_userns_clone sysctl. ++ ++ If unsure, say Y. ++ + config PID_NS + bool "PID Namespaces" + default y +diff --git a/kernel/fork.c b/kernel/fork.c +index c675fdbd3dce..9266039e28e4 100644 +--- a/kernel/fork.c ++++ b/kernel/fork.c +@@ -97,6 +97,10 @@ + #include + #include + ++#ifdef CONFIG_USER_NS ++#include ++#endif ++ + #include + #include + #include +@@ -1863,6 +1867,10 @@ static __latent_entropy struct task_struct *copy_process( + if ((clone_flags & (CLONE_NEWUSER|CLONE_FS)) == (CLONE_NEWUSER|CLONE_FS)) + return ERR_PTR(-EINVAL); + ++ if ((clone_flags & CLONE_NEWUSER) && !unprivileged_userns_clone) ++ if (!capable(CAP_SYS_ADMIN)) ++ return ERR_PTR(-EPERM); ++ + /* + * Thread groups must share signals as well, and detached threads + * can only be started up within the thread group. +@@ -2928,6 +2936,12 @@ int ksys_unshare(unsigned long unshare_flags) + if (unshare_flags & CLONE_NEWNS) + unshare_flags |= CLONE_FS; + ++ if ((unshare_flags & CLONE_NEWUSER) && !unprivileged_userns_clone) { ++ err = -EPERM; ++ if (!capable(CAP_SYS_ADMIN)) ++ goto bad_unshare_out; ++ } ++ + err = check_unshare_flags(unshare_flags); + if (err) + goto bad_unshare_out; +diff --git a/kernel/sysctl.c b/kernel/sysctl.c +index afad085960b8..a94828fb31c2 100644 +--- a/kernel/sysctl.c ++++ b/kernel/sysctl.c +@@ -103,6 +103,9 @@ + #ifdef CONFIG_LOCKUP_DETECTOR + #include + #endif ++#ifdef CONFIG_USER_NS ++#include ++#endif + + #if defined(CONFIG_SYSCTL) + +@@ -1902,6 +1905,15 @@ static struct ctl_table kern_table[] = { + .proc_handler = proc_dointvec, + }, + #endif ++#ifdef CONFIG_USER_NS ++ { ++ .procname = "unprivileged_userns_clone", ++ .data = &unprivileged_userns_clone, ++ .maxlen = sizeof(int), ++ .mode = 0644, ++ .proc_handler = proc_dointvec, ++ }, ++#endif + #ifdef CONFIG_PROC_SYSCTL + { + .procname = "tainted", +diff --git a/kernel/user_namespace.c b/kernel/user_namespace.c +index e703d5d9cbe8..5758274feaee 100644 +--- a/kernel/user_namespace.c ++++ b/kernel/user_namespace.c +@@ -21,6 +21,13 @@ + #include + #include + ++/* sysctl */ ++#ifdef CONFIG_USER_NS_UNPRIVILEGED ++int unprivileged_userns_clone = 1; ++#else ++int unprivileged_userns_clone; ++#endif ++ + static struct kmem_cache *user_ns_cachep __read_mostly; + static DEFINE_MUTEX(userns_state_mutex); + +-- +2.30.0 + diff --git a/0002-HID-quirks-Add-Apple-Magic-Trackpad-2-to-hid_have_sp.patch b/0002-HID-quirks-Add-Apple-Magic-Trackpad-2-to-hid_have_sp.patch new file mode 100644 index 0000000..317def3 --- /dev/null +++ b/0002-HID-quirks-Add-Apple-Magic-Trackpad-2-to-hid_have_sp.patch @@ -0,0 +1,36 @@ +From af5906764eea0c609d9d0dfc2c9834c6b72c88e6 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Felix=20H=C3=A4dicke?= +Date: Thu, 19 Nov 2020 09:22:32 +0100 +Subject: [PATCH 2/3] HID: quirks: Add Apple Magic Trackpad 2 to + hid_have_special_driver list +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The Apple Magic Trackpad 2 is handled by the magicmouse driver. And +there were severe stability issues when both drivers (hid-generic and +hid-magicmouse) were loaded for this device. + +Fixes: https://bugzilla.kernel.org/show_bug.cgi?id=210241 + +Signed-off-by: Felix Hädicke +--- + drivers/hid/hid-quirks.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/hid/hid-quirks.c b/drivers/hid/hid-quirks.c +index bf7ecab5d9e5..142e9dae2837 100644 +--- a/drivers/hid/hid-quirks.c ++++ b/drivers/hid/hid-quirks.c +@@ -478,6 +478,8 @@ static const struct hid_device_id hid_have_special_driver[] = { + #if IS_ENABLED(CONFIG_HID_MAGICMOUSE) + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGICMOUSE) }, + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGICTRACKPAD) }, ++ { HID_BLUETOOTH_DEVICE(BT_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGICTRACKPAD2) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGICTRACKPAD2) }, + #endif + #if IS_ENABLED(CONFIG_HID_MAYFLASH) + { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_PS3) }, +-- +2.30.0 + diff --git a/0003-iwlwifi-provide-gso_type-to-GSO-packets.patch b/0003-iwlwifi-provide-gso_type-to-GSO-packets.patch new file mode 100644 index 0000000..50c20c3 --- /dev/null +++ b/0003-iwlwifi-provide-gso_type-to-GSO-packets.patch @@ -0,0 +1,52 @@ +From 545d6504ef3c786b8294ca2129111227a7bb6515 Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Mon, 25 Jan 2021 07:09:49 -0800 +Subject: [PATCH 3/3] iwlwifi: provide gso_type to GSO packets + +commit 81a86e1bd8e7060ebba1718b284d54f1238e9bf9 upstream. + +net/core/tso.c got recent support for USO, and this broke iwlfifi +because the driver implemented a limited form of GSO. + +Providing ->gso_type allows for skb_is_gso_tcp() to provide +a correct result. + +Fixes: 3d5b459ba0e3 ("net: tso: add UDP segmentation support") +Signed-off-by: Eric Dumazet +Reported-by: Ben Greear +Tested-by: Ben Greear +Cc: Luca Coelho +Cc: Johannes Berg +Link: https://bugzilla.kernel.org/show_bug.cgi?id=209913 +Link: https://lore.kernel.org/r/20210125150949.619309-1-eric.dumazet@gmail.com +Signed-off-by: Jakub Kicinski +Cc: Robert Hancock +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/wireless/intel/iwlwifi/mvm/tx.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c +index fe1c538cd718..7626117c01fa 100644 +--- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c ++++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c +@@ -833,6 +833,7 @@ iwl_mvm_tx_tso_segment(struct sk_buff *skb, unsigned int num_subframes, + + next = skb_gso_segment(skb, netdev_flags); + skb_shinfo(skb)->gso_size = mss; ++ skb_shinfo(skb)->gso_type = ipv4 ? SKB_GSO_TCPV4 : SKB_GSO_TCPV6; + if (WARN_ON_ONCE(IS_ERR(next))) + return -EINVAL; + else if (next) +@@ -855,6 +856,8 @@ iwl_mvm_tx_tso_segment(struct sk_buff *skb, unsigned int num_subframes, + + if (tcp_payload_len > mss) { + skb_shinfo(tmp)->gso_size = mss; ++ skb_shinfo(tmp)->gso_type = ipv4 ? SKB_GSO_TCPV4 : ++ SKB_GSO_TCPV6; + } else { + if (qos) { + u8 *qc; +-- +2.30.0 + diff --git a/2001-drm-amd-display-Force-link_rate-as-LINK_RATE_RBR2-fo.patch b/2001-drm-amd-display-Force-link_rate-as-LINK_RATE_RBR2-fo.patch new file mode 100644 index 0000000..2e802d8 --- /dev/null +++ b/2001-drm-amd-display-Force-link_rate-as-LINK_RATE_RBR2-fo.patch @@ -0,0 +1,60 @@ +From b6740001d1adbfe84768b859bee038ceeccdc50c Mon Sep 17 00:00:00 2001 +From: Aun-Ali Zaidi +Date: Wed, 29 Jul 2020 08:04:54 -0500 +Subject: [PATCH] drm/amd/display: Force link_rate as LINK_RATE_RBR2 for 2018 + 15" Apple Retina panels + +The eDP link rate reported by the DP_MAX_LINK_RATE dpcd register (0xa) is +contradictory to the highest rate supported reported by +EDID (0xc = LINK_RATE_RBR2). The effects of this compounded with commit +'4a8ca46bae8a ("drm/amd/display: Default max bpc to 16 for eDP")' results +in no display modes being found and a dark panel. + +For now, simply force the maximum supported link rate for the eDP attached +2018 15" Apple Retina panels. + +Additionally, we must also check the firmware revision since the device ID +reported by the DPCD is identical to that of the more capable 16,1, +incorrectly quirking it. We also use said firmware check to quirk the +refreshed 15,1 models with Vega graphics as they use a slightly newer +firmware version. + +Tested-by: Aun-Ali Zaidi +Signed-off-by: Aun-Ali Zaidi +--- + .../gpu/drm/amd/display/dc/core/dc_link_dp.c | 19 +++++++++++++++++++ + 1 file changed, 19 insertions(+) + +diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c +index fbcd979438e2..8f78f9928df6 100644 +--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c ++++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c +@@ -3465,6 +3465,25 @@ static bool retrieve_link_cap(struct dc_link *link) + dp_hw_fw_revision.ieee_fw_rev, + sizeof(dp_hw_fw_revision.ieee_fw_rev)); + ++ /* Quirk for Apple MBP 2018 15" Retina panels: wrong DP_MAX_LINK_RATE */ ++ { ++ uint8_t str_mbp_2018[] = { 101, 68, 21, 103, 98, 97 }; ++ uint8_t fwrev_mbp_2018[] = { 7, 4 }; ++ uint8_t fwrev_mbp_2018_vega[] = { 8, 4 }; ++ ++ // We also check for the firmware revision as 16,1 models have an ++ // identical device id and are incorrectly quirked otherwise. ++ if ((link->dpcd_caps.sink_dev_id == 0x0010fa) && ++ !memcmp(link->dpcd_caps.sink_dev_id_str, str_mbp_2018, ++ sizeof(str_mbp_2018)) && ++ (!memcmp(link->dpcd_caps.sink_fw_revision, fwrev_mbp_2018, ++ sizeof(fwrev_mbp_2018)) || ++ !memcmp(link->dpcd_caps.sink_fw_revision, fwrev_mbp_2018_vega, ++ sizeof(fwrev_mbp_2018_vega)))) { ++ link->reported_link_cap.link_rate = LINK_RATE_RBR2; ++ } ++ } ++ + memset(&link->dpcd_caps.dsc_caps, '\0', + sizeof(link->dpcd_caps.dsc_caps)); + memset(&link->dpcd_caps.fec_cap, '\0', sizeof(link->dpcd_caps.fec_cap)); +-- +2.28.0 + diff --git a/3001-applesmc-convert-static-structures-to-drvdata.patch b/3001-applesmc-convert-static-structures-to-drvdata.patch new file mode 100644 index 0000000..ab0376f --- /dev/null +++ b/3001-applesmc-convert-static-structures-to-drvdata.patch @@ -0,0 +1,1218 @@ +From 09dd6c563cd73d72e917de07e8d59358c41e051d Mon Sep 17 00:00:00 2001 +From: Paul Pawlowski +Date: Sun, 17 Nov 2019 23:12:55 +0100 +Subject: [PATCH 1/6] applesmc: convert static structures to drvdata + +All static data structures have been moved to an applesmc_device struct, +which is then associated with the platform device. +This change is intended to ease the migration to an acpi_device, where +static data would preferably be avoided. + +Signed-off-by: Aun-Ali Zaidi +--- + drivers/hwmon/applesmc.c | 540 +++++++++++++++++++++++---------------- + 1 file changed, 319 insertions(+), 221 deletions(-) + +diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c +index 79b498f816fe..62211b590a61 100644 +--- a/drivers/hwmon/applesmc.c ++++ b/drivers/hwmon/applesmc.c +@@ -6,6 +6,7 @@ + * + * Copyright (C) 2007 Nicolas Boichat + * Copyright (C) 2010 Henrik Rydberg ++ * Copyright (C) 2019 Paul Pawlowski + * + * Based on hdaps.c driver: + * Copyright (C) 2005 Robert Love +@@ -119,7 +120,7 @@ struct applesmc_entry { + }; + + /* Register lookup and registers common to all SMCs */ +-static struct applesmc_registers { ++struct applesmc_registers { + struct mutex mutex; /* register read/write mutex */ + unsigned int key_count; /* number of SMC registers */ + unsigned int fan_count; /* number of fans */ +@@ -133,26 +134,32 @@ static struct applesmc_registers { + bool init_complete; /* true when fully initialized */ + struct applesmc_entry *cache; /* cached key entries */ + const char **index; /* temperature key index */ +-} smcreg = { +- .mutex = __MUTEX_INITIALIZER(smcreg.mutex), + }; + +-static const int debug; +-static struct platform_device *pdev; +-static s16 rest_x; +-static s16 rest_y; +-static u8 backlight_state[2]; ++struct applesmc_device { ++ struct platform_device *dev; ++ struct applesmc_registers reg; + +-static struct device *hwmon_dev; +-static struct input_dev *applesmc_idev; ++ s16 rest_x; ++ s16 rest_y; + +-/* +- * Last index written to key_at_index sysfs file, and value to use for all other +- * key_at_index_* sysfs files. +- */ +-static unsigned int key_at_index; ++ u8 backlight_state[2]; ++ ++ struct device *hwmon_dev; ++ struct input_dev *idev; ++ ++ /* ++ * Last index written to key_at_index sysfs file, and value to use for all other ++ * key_at_index_* sysfs files. ++ */ ++ unsigned int key_at_index; ++ ++ struct workqueue_struct *backlight_wq; ++ struct work_struct backlight_work; ++ struct led_classdev backlight_dev; ++}; + +-static struct workqueue_struct *applesmc_led_wq; ++static const int debug; + + /* + * Wait for specific status bits with a mask on the SMC. +@@ -338,36 +345,37 @@ static int read_register_count(unsigned int *count) + * All functions below are concurrency safe - callers should NOT hold lock. + */ + +-static int applesmc_read_entry(const struct applesmc_entry *entry, +- u8 *buf, u8 len) ++static int applesmc_read_entry(struct applesmc_device *smc, ++ const struct applesmc_entry *entry, u8 *buf, u8 len) + { + int ret; + + if (entry->len != len) + return -EINVAL; +- mutex_lock(&smcreg.mutex); ++ mutex_lock(&smc->reg.mutex); + ret = read_smc(APPLESMC_READ_CMD, entry->key, buf, len); +- mutex_unlock(&smcreg.mutex); ++ mutex_unlock(&smc->reg.mutex); + + return ret; + } + +-static int applesmc_write_entry(const struct applesmc_entry *entry, +- const u8 *buf, u8 len) ++static int applesmc_write_entry(struct applesmc_device *smc, ++ const struct applesmc_entry *entry, const u8 *buf, u8 len) + { + int ret; + + if (entry->len != len) + return -EINVAL; +- mutex_lock(&smcreg.mutex); ++ mutex_lock(&smc->reg.mutex); + ret = write_smc(APPLESMC_WRITE_CMD, entry->key, buf, len); +- mutex_unlock(&smcreg.mutex); ++ mutex_unlock(&smc->reg.mutex); + return ret; + } + +-static const struct applesmc_entry *applesmc_get_entry_by_index(int index) ++static const struct applesmc_entry *applesmc_get_entry_by_index( ++ struct applesmc_device *smc, int index) + { +- struct applesmc_entry *cache = &smcreg.cache[index]; ++ struct applesmc_entry *cache = &smc->reg.cache[index]; + u8 key[4], info[6]; + __be32 be; + int ret = 0; +@@ -375,7 +383,7 @@ static const struct applesmc_entry *applesmc_get_entry_by_index(int index) + if (cache->valid) + return cache; + +- mutex_lock(&smcreg.mutex); ++ mutex_lock(&smc->reg.mutex); + + if (cache->valid) + goto out; +@@ -394,20 +402,21 @@ static const struct applesmc_entry *applesmc_get_entry_by_index(int index) + cache->valid = 1; + + out: +- mutex_unlock(&smcreg.mutex); ++ mutex_unlock(&smc->reg.mutex); + if (ret) + return ERR_PTR(ret); + return cache; + } + +-static int applesmc_get_lower_bound(unsigned int *lo, const char *key) ++static int applesmc_get_lower_bound(struct applesmc_device *smc, ++ unsigned int *lo, const char *key) + { +- int begin = 0, end = smcreg.key_count; ++ int begin = 0, end = smc->reg.key_count; + const struct applesmc_entry *entry; + + while (begin != end) { + int middle = begin + (end - begin) / 2; +- entry = applesmc_get_entry_by_index(middle); ++ entry = applesmc_get_entry_by_index(smc, middle); + if (IS_ERR(entry)) { + *lo = 0; + return PTR_ERR(entry); +@@ -422,16 +431,17 @@ static int applesmc_get_lower_bound(unsigned int *lo, const char *key) + return 0; + } + +-static int applesmc_get_upper_bound(unsigned int *hi, const char *key) ++static int applesmc_get_upper_bound(struct applesmc_device *smc, ++ unsigned int *hi, const char *key) + { +- int begin = 0, end = smcreg.key_count; ++ int begin = 0, end = smc->reg.key_count; + const struct applesmc_entry *entry; + + while (begin != end) { + int middle = begin + (end - begin) / 2; +- entry = applesmc_get_entry_by_index(middle); ++ entry = applesmc_get_entry_by_index(smc, middle); + if (IS_ERR(entry)) { +- *hi = smcreg.key_count; ++ *hi = smc->reg.key_count; + return PTR_ERR(entry); + } + if (strcmp(key, entry->key) < 0) +@@ -444,50 +454,54 @@ static int applesmc_get_upper_bound(unsigned int *hi, const char *key) + return 0; + } + +-static const struct applesmc_entry *applesmc_get_entry_by_key(const char *key) ++static const struct applesmc_entry *applesmc_get_entry_by_key( ++ struct applesmc_device *smc, const char *key) + { + int begin, end; + int ret; + +- ret = applesmc_get_lower_bound(&begin, key); ++ ret = applesmc_get_lower_bound(smc, &begin, key); + if (ret) + return ERR_PTR(ret); +- ret = applesmc_get_upper_bound(&end, key); ++ ret = applesmc_get_upper_bound(smc, &end, key); + if (ret) + return ERR_PTR(ret); + if (end - begin != 1) + return ERR_PTR(-EINVAL); + +- return applesmc_get_entry_by_index(begin); ++ return applesmc_get_entry_by_index(smc, begin); + } + +-static int applesmc_read_key(const char *key, u8 *buffer, u8 len) ++static int applesmc_read_key(struct applesmc_device *smc, ++ const char *key, u8 *buffer, u8 len) + { + const struct applesmc_entry *entry; + +- entry = applesmc_get_entry_by_key(key); ++ entry = applesmc_get_entry_by_key(smc, key); + if (IS_ERR(entry)) + return PTR_ERR(entry); + +- return applesmc_read_entry(entry, buffer, len); ++ return applesmc_read_entry(smc, entry, buffer, len); + } + +-static int applesmc_write_key(const char *key, const u8 *buffer, u8 len) ++static int applesmc_write_key(struct applesmc_device *smc, ++ const char *key, const u8 *buffer, u8 len) + { + const struct applesmc_entry *entry; + +- entry = applesmc_get_entry_by_key(key); ++ entry = applesmc_get_entry_by_key(smc, key); + if (IS_ERR(entry)) + return PTR_ERR(entry); + +- return applesmc_write_entry(entry, buffer, len); ++ return applesmc_write_entry(smc, entry, buffer, len); + } + +-static int applesmc_has_key(const char *key, bool *value) ++static int applesmc_has_key(struct applesmc_device *smc, ++ const char *key, bool *value) + { + const struct applesmc_entry *entry; + +- entry = applesmc_get_entry_by_key(key); ++ entry = applesmc_get_entry_by_key(smc, key); + if (IS_ERR(entry) && PTR_ERR(entry) != -EINVAL) + return PTR_ERR(entry); + +@@ -498,12 +512,13 @@ static int applesmc_has_key(const char *key, bool *value) + /* + * applesmc_read_s16 - Read 16-bit signed big endian register + */ +-static int applesmc_read_s16(const char *key, s16 *value) ++static int applesmc_read_s16(struct applesmc_device *smc, ++ const char *key, s16 *value) + { + u8 buffer[2]; + int ret; + +- ret = applesmc_read_key(key, buffer, 2); ++ ret = applesmc_read_key(smc, key, buffer, 2); + if (ret) + return ret; + +@@ -514,28 +529,29 @@ static int applesmc_read_s16(const char *key, s16 *value) + /* + * applesmc_device_init - initialize the accelerometer. Can sleep. + */ +-static void applesmc_device_init(void) ++static void applesmc_device_init(struct applesmc_device *smc) + { + int total; + u8 buffer[2]; + +- if (!smcreg.has_accelerometer) ++ if (!smc->reg.has_accelerometer) + return; + + for (total = INIT_TIMEOUT_MSECS; total > 0; total -= INIT_WAIT_MSECS) { +- if (!applesmc_read_key(MOTION_SENSOR_KEY, buffer, 2) && ++ if (!applesmc_read_key(smc, MOTION_SENSOR_KEY, buffer, 2) && + (buffer[0] != 0x00 || buffer[1] != 0x00)) + return; + buffer[0] = 0xe0; + buffer[1] = 0x00; +- applesmc_write_key(MOTION_SENSOR_KEY, buffer, 2); ++ applesmc_write_key(smc, MOTION_SENSOR_KEY, buffer, 2); + msleep(INIT_WAIT_MSECS); + } + + pr_warn("failed to init the device\n"); + } + +-static int applesmc_init_index(struct applesmc_registers *s) ++static int applesmc_init_index(struct applesmc_device *smc, ++ struct applesmc_registers *s) + { + const struct applesmc_entry *entry; + unsigned int i; +@@ -548,7 +564,7 @@ static int applesmc_init_index(struct applesmc_registers *s) + return -ENOMEM; + + for (i = s->temp_begin; i < s->temp_end; i++) { +- entry = applesmc_get_entry_by_index(i); ++ entry = applesmc_get_entry_by_index(smc, i); + if (IS_ERR(entry)) + continue; + if (strcmp(entry->type, TEMP_SENSOR_TYPE)) +@@ -562,9 +578,9 @@ static int applesmc_init_index(struct applesmc_registers *s) + /* + * applesmc_init_smcreg_try - Try to initialize register cache. Idempotent. + */ +-static int applesmc_init_smcreg_try(void) ++static int applesmc_init_smcreg_try(struct applesmc_device *smc) + { +- struct applesmc_registers *s = &smcreg; ++ struct applesmc_registers *s = &smc->reg; + bool left_light_sensor = 0, right_light_sensor = 0; + unsigned int count; + u8 tmp[1]; +@@ -590,35 +606,35 @@ static int applesmc_init_smcreg_try(void) + if (!s->cache) + return -ENOMEM; + +- ret = applesmc_read_key(FANS_COUNT, tmp, 1); ++ ret = applesmc_read_key(smc, FANS_COUNT, tmp, 1); + if (ret) + return ret; + s->fan_count = tmp[0]; + if (s->fan_count > 10) + s->fan_count = 10; + +- ret = applesmc_get_lower_bound(&s->temp_begin, "T"); ++ ret = applesmc_get_lower_bound(smc, &s->temp_begin, "T"); + if (ret) + return ret; +- ret = applesmc_get_lower_bound(&s->temp_end, "U"); ++ ret = applesmc_get_lower_bound(smc, &s->temp_end, "U"); + if (ret) + return ret; + s->temp_count = s->temp_end - s->temp_begin; + +- ret = applesmc_init_index(s); ++ ret = applesmc_init_index(smc, s); + if (ret) + return ret; + +- ret = applesmc_has_key(LIGHT_SENSOR_LEFT_KEY, &left_light_sensor); ++ ret = applesmc_has_key(smc, LIGHT_SENSOR_LEFT_KEY, &left_light_sensor); + if (ret) + return ret; +- ret = applesmc_has_key(LIGHT_SENSOR_RIGHT_KEY, &right_light_sensor); ++ ret = applesmc_has_key(smc, LIGHT_SENSOR_RIGHT_KEY, &right_light_sensor); + if (ret) + return ret; +- ret = applesmc_has_key(MOTION_SENSOR_KEY, &s->has_accelerometer); ++ ret = applesmc_has_key(smc, MOTION_SENSOR_KEY, &s->has_accelerometer); + if (ret) + return ret; +- ret = applesmc_has_key(BACKLIGHT_KEY, &s->has_key_backlight); ++ ret = applesmc_has_key(smc, BACKLIGHT_KEY, &s->has_key_backlight); + if (ret) + return ret; + +@@ -634,13 +650,13 @@ static int applesmc_init_smcreg_try(void) + return 0; + } + +-static void applesmc_destroy_smcreg(void) ++static void applesmc_destroy_smcreg(struct applesmc_device *smc) + { +- kfree(smcreg.index); +- smcreg.index = NULL; +- kfree(smcreg.cache); +- smcreg.cache = NULL; +- smcreg.init_complete = false; ++ kfree(smc->reg.index); ++ smc->reg.index = NULL; ++ kfree(smc->reg.cache); ++ smc->reg.cache = NULL; ++ smc->reg.init_complete = false; + } + + /* +@@ -649,12 +665,12 @@ static void applesmc_destroy_smcreg(void) + * Retries until initialization is successful, or the operation times out. + * + */ +-static int applesmc_init_smcreg(void) ++static int applesmc_init_smcreg(struct applesmc_device *smc) + { + int ms, ret; + + for (ms = 0; ms < INIT_TIMEOUT_MSECS; ms += INIT_WAIT_MSECS) { +- ret = applesmc_init_smcreg_try(); ++ ret = applesmc_init_smcreg_try(smc); + if (!ret) { + if (ms) + pr_info("init_smcreg() took %d ms\n", ms); +@@ -663,21 +679,58 @@ static int applesmc_init_smcreg(void) + msleep(INIT_WAIT_MSECS); + } + +- applesmc_destroy_smcreg(); ++ applesmc_destroy_smcreg(smc); + + return ret; + } + + /* Device model stuff */ ++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) + { ++ struct applesmc_device *smc; + int ret; + +- ret = applesmc_init_smcreg(); ++ smc = kzalloc(sizeof(struct applesmc_device), GFP_KERNEL); ++ if (!smc) ++ return -ENOMEM; ++ smc->dev = dev; ++ mutex_init(&smc->reg.mutex); ++ ++ platform_set_drvdata(dev, smc); ++ ++ ret = applesmc_init_smcreg(smc); + if (ret) +- return ret; ++ goto out_mem; ++ ++ applesmc_device_init(smc); ++ ++ ret = applesmc_create_modules(smc); ++ if (ret) ++ goto out_reg; ++ ++ return 0; ++ ++out_reg: ++ applesmc_destroy_smcreg(smc); ++out_mem: ++ platform_set_drvdata(dev, NULL); ++ mutex_destroy(&smc->reg.mutex); ++ kfree(smc); + +- applesmc_device_init(); ++ return ret; ++} ++ ++static int applesmc_remove(struct platform_device *dev) ++{ ++ struct applesmc_device *smc = platform_get_drvdata(dev); ++ ++ applesmc_destroy_modules(smc); ++ applesmc_destroy_smcreg(smc); ++ ++ mutex_destroy(&smc->reg.mutex); ++ kfree(smc); + + return 0; + } +@@ -685,15 +738,21 @@ static int applesmc_probe(struct platform_device *dev) + /* Synchronize device with memorized backlight state */ + static int applesmc_pm_resume(struct device *dev) + { +- if (smcreg.has_key_backlight) +- applesmc_write_key(BACKLIGHT_KEY, backlight_state, 2); ++ struct applesmc_device *smc = dev_get_drvdata(dev); ++ ++ if (smc->reg.has_key_backlight) ++ applesmc_write_key(smc, BACKLIGHT_KEY, smc->backlight_state, 2); ++ + return 0; + } + + /* Reinitialize device on resume from hibernation */ + static int applesmc_pm_restore(struct device *dev) + { +- applesmc_device_init(); ++ struct applesmc_device *smc = dev_get_drvdata(dev); ++ ++ applesmc_device_init(smc); ++ + return applesmc_pm_resume(dev); + } + +@@ -704,6 +763,7 @@ static const struct dev_pm_ops applesmc_pm_ops = { + + static struct platform_driver applesmc_driver = { + .probe = applesmc_probe, ++ .remove = applesmc_remove, + .driver = { + .name = "applesmc", + .pm = &applesmc_pm_ops, +@@ -714,25 +774,26 @@ static struct platform_driver applesmc_driver = { + * applesmc_calibrate - Set our "resting" values. Callers must + * hold applesmc_lock. + */ +-static void applesmc_calibrate(void) ++static void applesmc_calibrate(struct applesmc_device *smc) + { +- applesmc_read_s16(MOTION_SENSOR_X_KEY, &rest_x); +- applesmc_read_s16(MOTION_SENSOR_Y_KEY, &rest_y); +- rest_x = -rest_x; ++ applesmc_read_s16(smc, MOTION_SENSOR_X_KEY, &smc->rest_x); ++ applesmc_read_s16(smc, MOTION_SENSOR_Y_KEY, &smc->rest_y); ++ smc->rest_x = -smc->rest_x; + } + + static void applesmc_idev_poll(struct input_dev *idev) + { ++ struct applesmc_device *smc = dev_get_drvdata(&idev->dev); + s16 x, y; + +- if (applesmc_read_s16(MOTION_SENSOR_X_KEY, &x)) ++ if (applesmc_read_s16(smc, MOTION_SENSOR_X_KEY, &x)) + return; +- if (applesmc_read_s16(MOTION_SENSOR_Y_KEY, &y)) ++ if (applesmc_read_s16(smc, MOTION_SENSOR_Y_KEY, &y)) + return; + + x = -x; +- input_report_abs(idev, ABS_X, x - rest_x); +- input_report_abs(idev, ABS_Y, y - rest_y); ++ input_report_abs(idev, ABS_X, x - smc->rest_x); ++ input_report_abs(idev, ABS_Y, y - smc->rest_y); + input_sync(idev); + } + +@@ -747,16 +808,17 @@ static ssize_t applesmc_name_show(struct device *dev, + static ssize_t applesmc_position_show(struct device *dev, + struct device_attribute *attr, char *buf) + { ++ struct applesmc_device *smc = dev_get_drvdata(dev); + int ret; + s16 x, y, z; + +- ret = applesmc_read_s16(MOTION_SENSOR_X_KEY, &x); ++ ret = applesmc_read_s16(smc, MOTION_SENSOR_X_KEY, &x); + if (ret) + goto out; +- ret = applesmc_read_s16(MOTION_SENSOR_Y_KEY, &y); ++ ret = applesmc_read_s16(smc, MOTION_SENSOR_Y_KEY, &y); + if (ret) + goto out; +- ret = applesmc_read_s16(MOTION_SENSOR_Z_KEY, &z); ++ ret = applesmc_read_s16(smc, MOTION_SENSOR_Z_KEY, &z); + if (ret) + goto out; + +@@ -770,6 +832,7 @@ static ssize_t applesmc_position_show(struct device *dev, + static ssize_t applesmc_light_show(struct device *dev, + struct device_attribute *attr, char *sysfsbuf) + { ++ struct applesmc_device *smc = dev_get_drvdata(dev); + const struct applesmc_entry *entry; + static int data_length; + int ret; +@@ -777,7 +840,7 @@ static ssize_t applesmc_light_show(struct device *dev, + u8 buffer[10]; + + if (!data_length) { +- entry = applesmc_get_entry_by_key(LIGHT_SENSOR_LEFT_KEY); ++ entry = applesmc_get_entry_by_key(smc, LIGHT_SENSOR_LEFT_KEY); + if (IS_ERR(entry)) + return PTR_ERR(entry); + if (entry->len > 10) +@@ -786,7 +849,7 @@ static ssize_t applesmc_light_show(struct device *dev, + pr_info("light sensor data length set to %d\n", data_length); + } + +- ret = applesmc_read_key(LIGHT_SENSOR_LEFT_KEY, buffer, data_length); ++ ret = applesmc_read_key(smc, LIGHT_SENSOR_LEFT_KEY, buffer, data_length); + if (ret) + goto out; + /* newer macbooks report a single 10-bit bigendian value */ +@@ -796,7 +859,7 @@ static ssize_t applesmc_light_show(struct device *dev, + } + left = buffer[2]; + +- ret = applesmc_read_key(LIGHT_SENSOR_RIGHT_KEY, buffer, data_length); ++ ret = applesmc_read_key(smc, LIGHT_SENSOR_RIGHT_KEY, buffer, data_length); + if (ret) + goto out; + right = buffer[2]; +@@ -812,7 +875,8 @@ static ssize_t applesmc_light_show(struct device *dev, + static ssize_t applesmc_show_sensor_label(struct device *dev, + struct device_attribute *devattr, char *sysfsbuf) + { +- const char *key = smcreg.index[to_index(devattr)]; ++ struct applesmc_device *smc = dev_get_drvdata(dev); ++ const char *key = smc->reg.index[to_index(devattr)]; + + return snprintf(sysfsbuf, PAGE_SIZE, "%s\n", key); + } +@@ -821,12 +885,13 @@ static ssize_t applesmc_show_sensor_label(struct device *dev, + static ssize_t applesmc_show_temperature(struct device *dev, + struct device_attribute *devattr, char *sysfsbuf) + { +- const char *key = smcreg.index[to_index(devattr)]; ++ struct applesmc_device *smc = dev_get_drvdata(dev); ++ const char *key = smc->reg.index[to_index(devattr)]; + int ret; + s16 value; + int temp; + +- ret = applesmc_read_s16(key, &value); ++ ret = applesmc_read_s16(smc, key, &value); + if (ret) + return ret; + +@@ -838,6 +903,7 @@ static ssize_t applesmc_show_temperature(struct device *dev, + static ssize_t applesmc_show_fan_speed(struct device *dev, + struct device_attribute *attr, char *sysfsbuf) + { ++ struct applesmc_device *smc = dev_get_drvdata(dev); + int ret; + unsigned int speed = 0; + char newkey[5]; +@@ -846,7 +912,7 @@ static ssize_t applesmc_show_fan_speed(struct device *dev, + scnprintf(newkey, sizeof(newkey), fan_speed_fmt[to_option(attr)], + to_index(attr)); + +- ret = applesmc_read_key(newkey, buffer, 2); ++ ret = applesmc_read_key(smc, newkey, buffer, 2); + if (ret) + return ret; + +@@ -858,6 +924,7 @@ static ssize_t applesmc_store_fan_speed(struct device *dev, + struct device_attribute *attr, + const char *sysfsbuf, size_t count) + { ++ struct applesmc_device *smc = dev_get_drvdata(dev); + int ret; + unsigned long speed; + char newkey[5]; +@@ -871,7 +938,7 @@ static ssize_t applesmc_store_fan_speed(struct device *dev, + + buffer[0] = (speed >> 6) & 0xff; + buffer[1] = (speed << 2) & 0xff; +- ret = applesmc_write_key(newkey, buffer, 2); ++ ret = applesmc_write_key(smc, newkey, buffer, 2); + + if (ret) + return ret; +@@ -882,11 +949,12 @@ static ssize_t applesmc_store_fan_speed(struct device *dev, + static ssize_t applesmc_show_fan_manual(struct device *dev, + struct device_attribute *attr, char *sysfsbuf) + { ++ struct applesmc_device *smc = dev_get_drvdata(dev); + int ret; + u16 manual = 0; + u8 buffer[2]; + +- ret = applesmc_read_key(FANS_MANUAL, buffer, 2); ++ ret = applesmc_read_key(smc, FANS_MANUAL, buffer, 2); + if (ret) + return ret; + +@@ -898,6 +966,7 @@ static ssize_t applesmc_store_fan_manual(struct device *dev, + struct device_attribute *attr, + const char *sysfsbuf, size_t count) + { ++ struct applesmc_device *smc = dev_get_drvdata(dev); + int ret; + u8 buffer[2]; + unsigned long input; +@@ -906,7 +975,7 @@ static ssize_t applesmc_store_fan_manual(struct device *dev, + if (kstrtoul(sysfsbuf, 10, &input) < 0) + return -EINVAL; + +- ret = applesmc_read_key(FANS_MANUAL, buffer, 2); ++ ret = applesmc_read_key(smc, FANS_MANUAL, buffer, 2); + if (ret) + goto out; + +@@ -920,7 +989,7 @@ static ssize_t applesmc_store_fan_manual(struct device *dev, + buffer[0] = (val >> 8) & 0xFF; + buffer[1] = val & 0xFF; + +- ret = applesmc_write_key(FANS_MANUAL, buffer, 2); ++ ret = applesmc_write_key(smc, FANS_MANUAL, buffer, 2); + + out: + if (ret) +@@ -932,13 +1001,14 @@ static ssize_t applesmc_store_fan_manual(struct device *dev, + static ssize_t applesmc_show_fan_position(struct device *dev, + struct device_attribute *attr, char *sysfsbuf) + { ++ struct applesmc_device *smc = dev_get_drvdata(dev); + int ret; + char newkey[5]; + u8 buffer[17]; + + scnprintf(newkey, sizeof(newkey), FAN_ID_FMT, to_index(attr)); + +- ret = applesmc_read_key(newkey, buffer, 16); ++ ret = applesmc_read_key(smc, newkey, buffer, 16); + buffer[16] = 0; + + if (ret) +@@ -950,30 +1020,36 @@ static ssize_t applesmc_show_fan_position(struct device *dev, + static ssize_t applesmc_calibrate_show(struct device *dev, + struct device_attribute *attr, char *sysfsbuf) + { +- return snprintf(sysfsbuf, PAGE_SIZE, "(%d,%d)\n", rest_x, rest_y); ++ struct applesmc_device *smc = dev_get_drvdata(dev); ++ ++ return snprintf(sysfsbuf, PAGE_SIZE, "(%d,%d)\n", smc->rest_x, smc->rest_y); + } + + static ssize_t applesmc_calibrate_store(struct device *dev, + struct device_attribute *attr, const char *sysfsbuf, size_t count) + { +- applesmc_calibrate(); ++ struct applesmc_device *smc = dev_get_drvdata(dev); ++ ++ applesmc_calibrate(smc); + + return count; + } + + static void applesmc_backlight_set(struct work_struct *work) + { +- applesmc_write_key(BACKLIGHT_KEY, backlight_state, 2); ++ struct applesmc_device *smc = container_of(work, struct applesmc_device, backlight_work); ++ ++ applesmc_write_key(smc, BACKLIGHT_KEY, smc->backlight_state, 2); + } +-static DECLARE_WORK(backlight_work, &applesmc_backlight_set); + + static void applesmc_brightness_set(struct led_classdev *led_cdev, + enum led_brightness value) + { ++ struct applesmc_device *smc = dev_get_drvdata(led_cdev->dev); + int ret; + +- backlight_state[0] = value; +- ret = queue_work(applesmc_led_wq, &backlight_work); ++ smc->backlight_state[0] = value; ++ ret = queue_work(smc->backlight_wq, &smc->backlight_work); + + if (debug && (!ret)) + dev_dbg(led_cdev->dev, "work was already on the queue.\n"); +@@ -982,11 +1058,12 @@ static void applesmc_brightness_set(struct led_classdev *led_cdev, + static ssize_t applesmc_key_count_show(struct device *dev, + struct device_attribute *attr, char *sysfsbuf) + { ++ struct applesmc_device *smc = dev_get_drvdata(dev); + int ret; + u8 buffer[4]; + u32 count; + +- ret = applesmc_read_key(KEY_COUNT_KEY, buffer, 4); ++ ret = applesmc_read_key(smc, KEY_COUNT_KEY, buffer, 4); + if (ret) + return ret; + +@@ -998,13 +1075,14 @@ static ssize_t applesmc_key_count_show(struct device *dev, + static ssize_t applesmc_key_at_index_read_show(struct device *dev, + struct device_attribute *attr, char *sysfsbuf) + { ++ struct applesmc_device *smc = dev_get_drvdata(dev); + const struct applesmc_entry *entry; + int ret; + +- entry = applesmc_get_entry_by_index(key_at_index); ++ entry = applesmc_get_entry_by_index(smc, smc->key_at_index); + if (IS_ERR(entry)) + return PTR_ERR(entry); +- ret = applesmc_read_entry(entry, sysfsbuf, entry->len); ++ ret = applesmc_read_entry(smc, entry, sysfsbuf, entry->len); + if (ret) + return ret; + +@@ -1014,9 +1092,10 @@ static ssize_t applesmc_key_at_index_read_show(struct device *dev, + static ssize_t applesmc_key_at_index_data_length_show(struct device *dev, + struct device_attribute *attr, char *sysfsbuf) + { ++ struct applesmc_device *smc = dev_get_drvdata(dev); + const struct applesmc_entry *entry; + +- entry = applesmc_get_entry_by_index(key_at_index); ++ entry = applesmc_get_entry_by_index(smc, smc->key_at_index); + if (IS_ERR(entry)) + return PTR_ERR(entry); + +@@ -1026,9 +1105,10 @@ static ssize_t applesmc_key_at_index_data_length_show(struct device *dev, + static ssize_t applesmc_key_at_index_type_show(struct device *dev, + struct device_attribute *attr, char *sysfsbuf) + { ++ struct applesmc_device *smc = dev_get_drvdata(dev); + const struct applesmc_entry *entry; + +- entry = applesmc_get_entry_by_index(key_at_index); ++ entry = applesmc_get_entry_by_index(smc, smc->key_at_index); + if (IS_ERR(entry)) + return PTR_ERR(entry); + +@@ -1038,9 +1118,10 @@ static ssize_t applesmc_key_at_index_type_show(struct device *dev, + static ssize_t applesmc_key_at_index_name_show(struct device *dev, + struct device_attribute *attr, char *sysfsbuf) + { ++ struct applesmc_device *smc = dev_get_drvdata(dev); + const struct applesmc_entry *entry; + +- entry = applesmc_get_entry_by_index(key_at_index); ++ entry = applesmc_get_entry_by_index(smc, smc->key_at_index); + if (IS_ERR(entry)) + return PTR_ERR(entry); + +@@ -1050,28 +1131,25 @@ static ssize_t applesmc_key_at_index_name_show(struct device *dev, + static ssize_t applesmc_key_at_index_show(struct device *dev, + struct device_attribute *attr, char *sysfsbuf) + { +- return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", key_at_index); ++ struct applesmc_device *smc = dev_get_drvdata(dev); ++ ++ return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", smc->key_at_index); + } + + static ssize_t applesmc_key_at_index_store(struct device *dev, + struct device_attribute *attr, const char *sysfsbuf, size_t count) + { ++ struct applesmc_device *smc = dev_get_drvdata(dev); + unsigned long newkey; + + if (kstrtoul(sysfsbuf, 10, &newkey) < 0 +- || newkey >= smcreg.key_count) ++ || newkey >= smc->reg.key_count) + return -EINVAL; + +- key_at_index = newkey; ++ smc->key_at_index = newkey; + return count; + } + +-static struct led_classdev applesmc_backlight = { +- .name = "smc::kbd_backlight", +- .default_trigger = "nand-disk", +- .brightness_set = applesmc_brightness_set, +-}; +- + static struct applesmc_node_group info_group[] = { + { "name", applesmc_name_show }, + { "key_count", applesmc_key_count_show }, +@@ -1116,14 +1194,15 @@ static struct applesmc_node_group temp_group[] = { + /* + * applesmc_destroy_nodes - remove files and free associated memory + */ +-static void applesmc_destroy_nodes(struct applesmc_node_group *groups) ++static void applesmc_destroy_nodes(struct applesmc_device *smc, ++ struct applesmc_node_group *groups) + { + struct applesmc_node_group *grp; + struct applesmc_dev_attr *node; + + for (grp = groups; grp->nodes; grp++) { + for (node = grp->nodes; node->sda.dev_attr.attr.name; node++) +- sysfs_remove_file(&pdev->dev.kobj, ++ sysfs_remove_file(&smc->dev->dev.kobj, + &node->sda.dev_attr.attr); + kfree(grp->nodes); + grp->nodes = NULL; +@@ -1133,7 +1212,8 @@ static void applesmc_destroy_nodes(struct applesmc_node_group *groups) + /* + * applesmc_create_nodes - create a two-dimensional group of sysfs files + */ +-static int applesmc_create_nodes(struct applesmc_node_group *groups, int num) ++static int applesmc_create_nodes(struct applesmc_device *smc, ++ struct applesmc_node_group *groups, int num) + { + struct applesmc_node_group *grp; + struct applesmc_dev_attr *node; +@@ -1157,7 +1237,7 @@ static int applesmc_create_nodes(struct applesmc_node_group *groups, int num) + sysfs_attr_init(attr); + attr->name = node->name; + attr->mode = 0444 | (grp->store ? 0200 : 0); +- ret = sysfs_create_file(&pdev->dev.kobj, attr); ++ ret = sysfs_create_file(&smc->dev->dev.kobj, attr); + if (ret) { + attr->name = NULL; + goto out; +@@ -1167,57 +1247,57 @@ static int applesmc_create_nodes(struct applesmc_node_group *groups, int num) + + return 0; + out: +- applesmc_destroy_nodes(groups); ++ applesmc_destroy_nodes(smc, groups); + return ret; + } + + /* Create accelerometer resources */ +-static int applesmc_create_accelerometer(void) ++static int applesmc_create_accelerometer(struct applesmc_device *smc) + { + int ret; + +- if (!smcreg.has_accelerometer) ++ if (!smc->reg.has_accelerometer) + return 0; + +- ret = applesmc_create_nodes(accelerometer_group, 1); ++ ret = applesmc_create_nodes(smc, accelerometer_group, 1); + if (ret) + goto out; + +- applesmc_idev = input_allocate_device(); +- if (!applesmc_idev) { ++ smc->idev = input_allocate_device(); ++ if (!smc->idev) { + ret = -ENOMEM; + goto out_sysfs; + } + + /* initial calibrate for the input device */ +- applesmc_calibrate(); ++ applesmc_calibrate(smc); + + /* initialize the input device */ +- applesmc_idev->name = "applesmc"; +- applesmc_idev->id.bustype = BUS_HOST; +- applesmc_idev->dev.parent = &pdev->dev; +- input_set_abs_params(applesmc_idev, ABS_X, ++ smc->idev->name = "applesmc"; ++ smc->idev->id.bustype = BUS_HOST; ++ smc->idev->dev.parent = &smc->dev->dev; ++ input_set_abs_params(smc->idev, ABS_X, + -256, 256, APPLESMC_INPUT_FUZZ, APPLESMC_INPUT_FLAT); +- input_set_abs_params(applesmc_idev, ABS_Y, ++ input_set_abs_params(smc->idev, ABS_Y, + -256, 256, APPLESMC_INPUT_FUZZ, APPLESMC_INPUT_FLAT); + +- ret = input_setup_polling(applesmc_idev, applesmc_idev_poll); ++ ret = input_setup_polling(smc->idev, applesmc_idev_poll); + if (ret) + goto out_idev; + +- input_set_poll_interval(applesmc_idev, APPLESMC_POLL_INTERVAL); ++ input_set_poll_interval(smc->idev, APPLESMC_POLL_INTERVAL); + +- ret = input_register_device(applesmc_idev); ++ ret = input_register_device(smc->idev); + if (ret) + goto out_idev; + + return 0; + + out_idev: +- input_free_device(applesmc_idev); ++ input_free_device(smc->idev); + + out_sysfs: +- applesmc_destroy_nodes(accelerometer_group); ++ applesmc_destroy_nodes(smc, accelerometer_group); + + out: + pr_warn("driver init failed (ret=%d)!\n", ret); +@@ -1225,44 +1305,55 @@ static int applesmc_create_accelerometer(void) + } + + /* Release all resources used by the accelerometer */ +-static void applesmc_release_accelerometer(void) ++static void applesmc_release_accelerometer(struct applesmc_device *smc) + { +- if (!smcreg.has_accelerometer) ++ if (!smc->reg.has_accelerometer) + return; +- input_unregister_device(applesmc_idev); +- applesmc_destroy_nodes(accelerometer_group); ++ input_unregister_device(smc->idev); ++ applesmc_destroy_nodes(smc, accelerometer_group); + } + +-static int applesmc_create_light_sensor(void) ++static int applesmc_create_light_sensor(struct applesmc_device *smc) + { +- if (!smcreg.num_light_sensors) ++ if (!smc->reg.num_light_sensors) + return 0; +- return applesmc_create_nodes(light_sensor_group, 1); ++ return applesmc_create_nodes(smc, light_sensor_group, 1); + } + +-static void applesmc_release_light_sensor(void) ++static void applesmc_release_light_sensor(struct applesmc_device *smc) + { +- if (!smcreg.num_light_sensors) ++ if (!smc->reg.num_light_sensors) + return; +- applesmc_destroy_nodes(light_sensor_group); ++ applesmc_destroy_nodes(smc, light_sensor_group); + } + +-static int applesmc_create_key_backlight(void) ++static int applesmc_create_key_backlight(struct applesmc_device *smc) + { +- if (!smcreg.has_key_backlight) ++ int ret; ++ ++ if (!smc->reg.has_key_backlight) + return 0; +- applesmc_led_wq = create_singlethread_workqueue("applesmc-led"); +- if (!applesmc_led_wq) ++ smc->backlight_wq = create_singlethread_workqueue("applesmc-led"); ++ if (!smc->backlight_wq) + return -ENOMEM; +- return led_classdev_register(&pdev->dev, &applesmc_backlight); ++ ++ INIT_WORK(&smc->backlight_work, applesmc_backlight_set); ++ smc->backlight_dev.name = "smc::kbd_backlight"; ++ smc->backlight_dev.default_trigger = "nand-disk"; ++ smc->backlight_dev.brightness_set = applesmc_brightness_set; ++ ret = led_classdev_register(&smc->dev->dev, &smc->backlight_dev); ++ if (ret) ++ destroy_workqueue(smc->backlight_wq); ++ ++ return ret; + } + +-static void applesmc_release_key_backlight(void) ++static void applesmc_release_key_backlight(struct applesmc_device *smc) + { +- if (!smcreg.has_key_backlight) ++ if (!smc->reg.has_key_backlight) + return; +- led_classdev_unregister(&applesmc_backlight); +- destroy_workqueue(applesmc_led_wq); ++ led_classdev_unregister(&smc->backlight_dev); ++ destroy_workqueue(smc->backlight_wq); + } + + static int applesmc_dmi_match(const struct dmi_system_id *id) +@@ -1302,86 +1393,100 @@ static const struct dmi_system_id applesmc_whitelist[] __initconst = { + { .ident = NULL } + }; + +-static int __init applesmc_init(void) ++static int applesmc_create_modules(struct applesmc_device *smc) + { + int ret; + +- if (!dmi_check_system(applesmc_whitelist)) { +- pr_warn("supported laptop not found!\n"); +- ret = -ENODEV; +- goto out; +- } +- +- if (!request_region(APPLESMC_DATA_PORT, APPLESMC_NR_PORTS, +- "applesmc")) { +- ret = -ENXIO; +- goto out; +- } +- +- ret = platform_driver_register(&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; +- } +- +- /* create register cache */ +- ret = applesmc_init_smcreg(); +- if (ret) +- goto out_device; +- +- ret = applesmc_create_nodes(info_group, 1); ++ ret = applesmc_create_nodes(smc, info_group, 1); + if (ret) +- goto out_smcreg; ++ goto out; + +- ret = applesmc_create_nodes(fan_group, smcreg.fan_count); ++ ret = applesmc_create_nodes(smc, fan_group, smc->reg.fan_count); + if (ret) + goto out_info; + +- ret = applesmc_create_nodes(temp_group, smcreg.index_count); ++ ret = applesmc_create_nodes(smc, temp_group, smc->reg.index_count); + if (ret) + goto out_fans; + +- ret = applesmc_create_accelerometer(); ++ ret = applesmc_create_accelerometer(smc); + if (ret) + goto out_temperature; + +- ret = applesmc_create_light_sensor(); ++ ret = applesmc_create_light_sensor(smc); + if (ret) + goto out_accelerometer; + +- ret = applesmc_create_key_backlight(); ++ ret = applesmc_create_key_backlight(smc); + if (ret) + goto out_light_sysfs; + +- hwmon_dev = hwmon_device_register(&pdev->dev); +- if (IS_ERR(hwmon_dev)) { +- ret = PTR_ERR(hwmon_dev); ++ smc->hwmon_dev = hwmon_device_register(&smc->dev->dev); ++ if (IS_ERR(smc->hwmon_dev)) { ++ ret = PTR_ERR(smc->hwmon_dev); + goto out_light_ledclass; + } + + return 0; + + out_light_ledclass: +- applesmc_release_key_backlight(); ++ applesmc_release_key_backlight(smc); + out_light_sysfs: +- applesmc_release_light_sensor(); ++ applesmc_release_light_sensor(smc); + out_accelerometer: +- applesmc_release_accelerometer(); ++ applesmc_release_accelerometer(smc); + out_temperature: +- applesmc_destroy_nodes(temp_group); ++ applesmc_destroy_nodes(smc, temp_group); + out_fans: +- applesmc_destroy_nodes(fan_group); ++ applesmc_destroy_nodes(smc, fan_group); + out_info: +- applesmc_destroy_nodes(info_group); +-out_smcreg: +- applesmc_destroy_smcreg(); +-out_device: +- platform_device_unregister(pdev); ++ applesmc_destroy_nodes(smc, info_group); ++out: ++ return ret; ++} ++ ++static void applesmc_destroy_modules(struct applesmc_device *smc) ++{ ++ hwmon_device_unregister(smc->hwmon_dev); ++ applesmc_release_key_backlight(smc); ++ applesmc_release_light_sensor(smc); ++ applesmc_release_accelerometer(smc); ++ applesmc_destroy_nodes(smc, temp_group); ++ applesmc_destroy_nodes(smc, fan_group); ++ applesmc_destroy_nodes(smc, info_group); ++} ++ ++static struct platform_device *pdev; ++ ++static int __init applesmc_init(void) ++{ ++ int ret; ++ ++ if (!dmi_check_system(applesmc_whitelist)) { ++ pr_warn("supported laptop not found!\n"); ++ ret = -ENODEV; ++ goto out; ++ } ++ ++ if (!request_region(APPLESMC_DATA_PORT, APPLESMC_NR_PORTS, ++ "applesmc")) { ++ ret = -ENXIO; ++ goto out; ++ } ++ ++ ret = platform_driver_register(&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; ++ } ++ ++ return 0; ++ + out_driver: + platform_driver_unregister(&applesmc_driver); + out_region: +@@ -1393,14 +1498,6 @@ static int __init applesmc_init(void) + + static void __exit applesmc_exit(void) + { +- hwmon_device_unregister(hwmon_dev); +- applesmc_release_key_backlight(); +- applesmc_release_light_sensor(); +- applesmc_release_accelerometer(); +- applesmc_destroy_nodes(temp_group); +- applesmc_destroy_nodes(fan_group); +- applesmc_destroy_nodes(info_group); +- applesmc_destroy_smcreg(); + platform_device_unregister(pdev); + platform_driver_unregister(&applesmc_driver); + release_region(APPLESMC_DATA_PORT, APPLESMC_NR_PORTS); +@@ -1410,6 +1507,7 @@ module_init(applesmc_init); + module_exit(applesmc_exit); + + MODULE_AUTHOR("Nicolas Boichat"); ++MODULE_AUTHOR("Paul Pawlowski"); + MODULE_DESCRIPTION("Apple SMC"); + MODULE_LICENSE("GPL v2"); + MODULE_DEVICE_TABLE(dmi, applesmc_whitelist); +-- +2.30.0 + diff --git a/3002-applesmc-make-io-port-base-addr-dynamic.patch b/3002-applesmc-make-io-port-base-addr-dynamic.patch new file mode 100644 index 0000000..cc332c7 --- /dev/null +++ b/3002-applesmc-make-io-port-base-addr-dynamic.patch @@ -0,0 +1,312 @@ +From 713e78b8dbb8adb92d4ee09ea11e726b05577689 Mon Sep 17 00:00:00 2001 +From: Paul Pawlowski +Date: Sun, 17 Nov 2019 23:11:56 +0100 +Subject: [PATCH 2/6] 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 +--- + 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 62211b590a61..39ed0bb21365 100644 +--- a/drivers/hwmon/applesmc.c ++++ b/drivers/hwmon/applesmc.c +@@ -35,10 +35,11 @@ + #include + #include + ++#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; + +@@ -1468,7 +1475,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; +@@ -1490,7 +1497,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; +@@ -1500,7 +1507,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); +-- +2.30.0 + diff --git a/3003-applesmc-switch-to-acpi_device-from-platform.patch b/3003-applesmc-switch-to-acpi_device-from-platform.patch new file mode 100644 index 0000000..f8f7f82 --- /dev/null +++ b/3003-applesmc-switch-to-acpi_device-from-platform.patch @@ -0,0 +1,267 @@ +From ee3d4bf4a01bc94553bde2ae3e806a63a13faa12 Mon Sep 17 00:00:00 2001 +From: Paul Pawlowski +Date: Sun, 17 Nov 2019 23:12:08 +0100 +Subject: [PATCH 3/6] 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 +--- + drivers/hwmon/applesmc.c | 125 ++++++++++++++++++++++++++------------- + 1 file changed, 85 insertions(+), 40 deletions(-) + +diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c +index 39ed0bb21365..bdaaf696f7b6 100644 +--- a/drivers/hwmon/applesmc.c ++++ b/drivers/hwmon/applesmc.c +@@ -19,7 +19,7 @@ + #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + + #include +-#include ++#include + #include + #include + #include +@@ -35,7 +35,6 @@ + #include + #include + +-#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,18 +820,28 @@ 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 ++ }, ++ .owner = THIS_MODULE + }; + + /* +@@ -1262,7 +1329,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; + +@@ -1463,8 +1529,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; +@@ -1475,29 +1539,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; +@@ -1505,9 +1552,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); +-- +2.30.0 + diff --git a/3004-applesmc-key-interface-wrappers.patch b/3004-applesmc-key-interface-wrappers.patch new file mode 100644 index 0000000..057a77d --- /dev/null +++ b/3004-applesmc-key-interface-wrappers.patch @@ -0,0 +1,298 @@ +From 43df89a1377782788760808d8ea4bcf0730effbb Mon Sep 17 00:00:00 2001 +From: Paul Pawlowski +Date: Sun, 17 Nov 2019 23:12:14 +0100 +Subject: [PATCH 4/6] 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 +--- + 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 bdaaf696f7b6..3017d8ca2c79 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 = 1; + + out: +-- +2.30.0 + diff --git a/3005-applesmc-basic-mmio-interface-implementation.patch b/3005-applesmc-basic-mmio-interface-implementation.patch new file mode 100644 index 0000000..c370d05 --- /dev/null +++ b/3005-applesmc-basic-mmio-interface-implementation.patch @@ -0,0 +1,343 @@ +From 799e7a54c62a36007f7874c58d7dac87c9651759 Mon Sep 17 00:00:00 2001 +From: Aun-Ali Zaidi +Date: Sun, 17 Nov 2019 23:12:16 +0100 +Subject: [PATCH 5/6] applesmc: basic mmio interface implementation + +This change introduces a basic MMIO-based +interface implementation required to communicate +with the SMC on T2 Macs. The MMIO interface is +enabled only when it's supported on the running +system. + +The MMIO interface replaces legacy port-based SMC +key reads, writes and metadata requests (getting +key by index and getting key info). + +(Based on patch by @mcmrarm) + +Signed-off-by: Aun-Ali Zaidi +--- + drivers/hwmon/applesmc.c | 237 ++++++++++++++++++++++++++++++++++++++- + 1 file changed, 231 insertions(+), 6 deletions(-) + +diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c +index 3017d8ca2c79..2d23bb9ad9dd 100644 +--- a/drivers/hwmon/applesmc.c ++++ b/drivers/hwmon/applesmc.c +@@ -42,6 +42,18 @@ + + #define APPLESMC_NR_PORTS 32 /* 0x300-0x31f */ + ++#define APPLESMC_IOMEM_KEY_DATA 0 ++#define APPLESMC_IOMEM_KEY_STATUS 0x4005 ++#define APPLESMC_IOMEM_KEY_NAME 0x78 ++#define APPLESMC_IOMEM_KEY_DATA_LEN 0x7D ++#define APPLESMC_IOMEM_KEY_SMC_ID 0x7E ++#define APPLESMC_IOMEM_KEY_CMD 0x7F ++#define APPLESMC_IOMEM_MIN_SIZE 0x4006 ++ ++#define APPLESMC_IOMEM_KEY_TYPE_CODE 0 ++#define APPLESMC_IOMEM_KEY_TYPE_DATA_LEN 5 ++#define APPLESMC_IOMEM_KEY_TYPE_FLAGS 6 ++ + #define APPLESMC_MAX_DATA_LENGTH 32 + + /* Apple SMC status bits */ +@@ -138,10 +150,13 @@ struct applesmc_registers { + + struct applesmc_device { + struct acpi_device *dev; ++ struct device *ldev; + struct applesmc_registers reg; + +- bool port_base_set; ++ bool port_base_set, iomem_base_set; + u16 port_base; ++ u8 *__iomem iomem_base; ++ u32 iomem_base_addr, iomem_base_size; + + s16 rest_x; + s16 rest_y; +@@ -347,16 +362,156 @@ static int port_get_smc_key_info(struct applesmc_device *smc, + return 0; + } + ++ ++/* ++ * MMIO based communication. ++ * TODO: Use updated mechanism for cmd timeout/retry ++ */ ++ ++static void iomem_clear_status(struct applesmc_device *smc) ++{ ++ if (ioread8(smc->iomem_base + APPLESMC_IOMEM_KEY_STATUS)) ++ iowrite8(0, smc->iomem_base + APPLESMC_IOMEM_KEY_STATUS); ++} ++ ++static int iomem_wait_read(struct applesmc_device *smc) ++{ ++ u8 status; ++ int us; ++ int i; ++ ++ us = APPLESMC_MIN_WAIT; ++ for (i = 0; i < 24 ; i++) { ++ status = ioread8(smc->iomem_base + APPLESMC_IOMEM_KEY_STATUS); ++ if (status & 0x20) ++ return 0; ++ usleep_range(us, us * 2); ++ if (i > 9) ++ us <<= 1; ++ } ++ ++ dev_warn(smc->ldev, "%s... timeout\n", __func__); ++ return -EIO; ++} ++ ++static int iomem_read_smc(struct applesmc_device *smc, u8 cmd, const char *key, ++ u8 *buffer, u8 len) ++{ ++ u8 err, remote_len; ++ u32 key_int = *((u32 *) key); ++ ++ iomem_clear_status(smc); ++ iowrite32(key_int, smc->iomem_base + APPLESMC_IOMEM_KEY_NAME); ++ iowrite32(0, smc->iomem_base + APPLESMC_IOMEM_KEY_SMC_ID); ++ iowrite32(cmd, smc->iomem_base + APPLESMC_IOMEM_KEY_CMD); ++ ++ if (iomem_wait_read(smc)) ++ return -EIO; ++ ++ err = ioread8(smc->iomem_base + APPLESMC_IOMEM_KEY_CMD); ++ if (err != 0) { ++ dev_warn(smc->ldev, "read_smc_mmio(%x %8x/%.4s) failed: %u\n", ++ cmd, key_int, key, err); ++ return -EIO; ++ } ++ ++ if (cmd == APPLESMC_READ_CMD) { ++ remote_len = ioread8(smc->iomem_base + APPLESMC_IOMEM_KEY_DATA_LEN); ++ if (remote_len != len) { ++ dev_warn(smc->ldev, ++ "read_smc_mmio(%x %8x/%.4s) failed: buffer length mismatch (remote = %u, requested = %u)\n", ++ cmd, key_int, key, remote_len, len); ++ return -EINVAL; ++ } ++ } else { ++ remote_len = len; ++ } ++ ++ memcpy_fromio(buffer, smc->iomem_base + APPLESMC_IOMEM_KEY_DATA, ++ remote_len); ++ ++ dev_dbg(smc->ldev, "read_smc_mmio(%x %8x/%.4s): buflen=%u reslen=%u\n", ++ cmd, key_int, key, len, remote_len); ++ print_hex_dump_bytes("read_smc_mmio(): ", DUMP_PREFIX_NONE, buffer, remote_len); ++ return 0; ++} ++ ++static int iomem_get_smc_key_type(struct applesmc_device *smc, const char *key, ++ struct applesmc_entry *e) ++{ ++ u8 err; ++ u8 cmd = APPLESMC_GET_KEY_TYPE_CMD; ++ u32 key_int = *((u32 *) key); ++ ++ iomem_clear_status(smc); ++ iowrite32(key_int, smc->iomem_base + APPLESMC_IOMEM_KEY_NAME); ++ iowrite32(0, smc->iomem_base + APPLESMC_IOMEM_KEY_SMC_ID); ++ iowrite32(cmd, smc->iomem_base + APPLESMC_IOMEM_KEY_CMD); ++ ++ if (iomem_wait_read(smc)) ++ return -EIO; ++ ++ err = ioread8(smc->iomem_base + APPLESMC_IOMEM_KEY_CMD); ++ if (err != 0) { ++ dev_warn(smc->ldev, "get_smc_key_type_mmio(%.4s) failed: %u\n", key, err); ++ return -EIO; ++ } ++ ++ e->len = ioread8(smc->iomem_base + APPLESMC_IOMEM_KEY_TYPE_DATA_LEN); ++ *((uint32_t *) e->type) = ioread32( ++ smc->iomem_base + APPLESMC_IOMEM_KEY_TYPE_CODE); ++ e->flags = ioread8(smc->iomem_base + APPLESMC_IOMEM_KEY_TYPE_FLAGS); ++ ++ dev_dbg(smc->ldev, "get_smc_key_type_mmio(%.4s): len=%u type=%.4s flags=%x\n", ++ key, e->len, e->type, e->flags); ++ return 0; ++} ++ ++static int iomem_write_smc(struct applesmc_device *smc, u8 cmd, const char *key, ++ const u8 *buffer, u8 len) ++{ ++ u8 err; ++ u32 key_int = *((u32 *) key); ++ ++ iomem_clear_status(smc); ++ iowrite32(key_int, smc->iomem_base + APPLESMC_IOMEM_KEY_NAME); ++ memcpy_toio(smc->iomem_base + APPLESMC_IOMEM_KEY_DATA, buffer, len); ++ iowrite32(len, smc->iomem_base + APPLESMC_IOMEM_KEY_DATA_LEN); ++ iowrite32(0, smc->iomem_base + APPLESMC_IOMEM_KEY_SMC_ID); ++ iowrite32(cmd, smc->iomem_base + APPLESMC_IOMEM_KEY_CMD); ++ ++ if (iomem_wait_read(smc)) ++ return -EIO; ++ ++ err = ioread8(smc->iomem_base + APPLESMC_IOMEM_KEY_CMD); ++ if (err != 0) { ++ dev_warn(smc->ldev, "write_smc_mmio(%x %.4s) failed: %u\n", cmd, key, err); ++ print_hex_dump_bytes("write_smc_mmio(): ", DUMP_PREFIX_NONE, buffer, len); ++ return -EIO; ++ } ++ ++ dev_dbg(smc->ldev, "write_smc_mmio(%x %.4s): buflen=%u\n", cmd, key, len); ++ print_hex_dump_bytes("write_smc_mmio(): ", DUMP_PREFIX_NONE, buffer, len); ++ return 0; ++} ++ ++ + static int read_smc(struct applesmc_device *smc, const char *key, + u8 *buffer, u8 len) + { +- return port_read_smc(smc, APPLESMC_READ_CMD, key, buffer, len); ++ if (smc->iomem_base_set) ++ return iomem_read_smc(smc, APPLESMC_READ_CMD, key, buffer, len); ++ else ++ return port_read_smc(smc, APPLESMC_READ_CMD, key, buffer, len); + } + + static int write_smc(struct applesmc_device *smc, const char *key, + const u8 *buffer, u8 len) + { +- return port_write_smc(smc, APPLESMC_WRITE_CMD, key, buffer, len); ++ if (smc->iomem_base_set) ++ return iomem_write_smc(smc, APPLESMC_WRITE_CMD, key, buffer, len); ++ else ++ return port_write_smc(smc, APPLESMC_WRITE_CMD, key, buffer, len); + } + + static int get_smc_key_by_index(struct applesmc_device *smc, +@@ -365,14 +520,21 @@ static int get_smc_key_by_index(struct applesmc_device *smc, + __be32 be; + + be = cpu_to_be32(index); +- return port_read_smc(smc, APPLESMC_GET_KEY_BY_INDEX_CMD, +- (const char *) &be, (u8 *) key, 4); ++ if (smc->iomem_base_set) ++ return iomem_read_smc(smc, APPLESMC_GET_KEY_BY_INDEX_CMD, ++ (const char *) &be, (u8 *) key, 4); ++ else ++ return port_read_smc(smc, APPLESMC_GET_KEY_BY_INDEX_CMD, ++ (const char *) &be, (u8 *) key, 4); + } + + static int get_smc_key_info(struct applesmc_device *smc, const char *key, + struct applesmc_entry *info) + { +- return port_get_smc_key_info(smc, key, info); ++ if (smc->iomem_base_set) ++ return iomem_get_smc_key_type(smc, key, info); ++ else ++ return port_get_smc_key_info(smc, key, info); + } + + static int read_register_count(struct applesmc_device *smc, +@@ -746,6 +908,7 @@ static int applesmc_add(struct acpi_device *dev) + if (!smc) + return -ENOMEM; + smc->dev = dev; ++ smc->ldev = &dev->dev; + mutex_init(&smc->reg.mutex); + + dev_set_drvdata(&dev->dev, smc); +@@ -807,6 +970,20 @@ static acpi_status applesmc_walk_resources(struct acpi_resource *res, + } + return AE_OK; + ++ case ACPI_RESOURCE_TYPE_FIXED_MEMORY32: ++ if (!smc->iomem_base_set) { ++ if (res->data.fixed_memory32.address_length < ++ APPLESMC_IOMEM_MIN_SIZE) { ++ dev_warn(smc->ldev, "found iomem but it's too small: %u\n", ++ res->data.fixed_memory32.address_length); ++ return AE_OK; ++ } ++ smc->iomem_base_addr = res->data.fixed_memory32.address; ++ smc->iomem_base_size = res->data.fixed_memory32.address_length; ++ smc->iomem_base_set = true; ++ } ++ return AE_OK; ++ + case ACPI_RESOURCE_TYPE_END_TAG: + if (smc->port_base_set) + return AE_OK; +@@ -818,6 +995,8 @@ static acpi_status applesmc_walk_resources(struct acpi_resource *res, + } + } + ++static int applesmc_try_enable_iomem(struct applesmc_device *smc); ++ + static int applesmc_init_resources(struct applesmc_device *smc) + { + int ret; +@@ -830,11 +1009,57 @@ static int applesmc_init_resources(struct applesmc_device *smc) + if (!request_region(smc->port_base, APPLESMC_NR_PORTS, "applesmc")) + return -ENXIO; + ++ if (smc->iomem_base_set) { ++ if (applesmc_try_enable_iomem(smc)) ++ smc->iomem_base_set = false; ++ } ++ + return 0; + } + ++static int applesmc_try_enable_iomem(struct applesmc_device *smc) ++{ ++ u8 test_val, ldkn_version; ++ ++ dev_dbg(smc->ldev, "Trying to enable iomem based communication\n"); ++ smc->iomem_base = ioremap(smc->iomem_base_addr, smc->iomem_base_size); ++ if (!smc->iomem_base) ++ goto out; ++ ++ /* Apple's driver does this check for some reason */ ++ test_val = ioread8(smc->iomem_base + APPLESMC_IOMEM_KEY_STATUS); ++ if (test_val == 0xff) { ++ dev_warn(smc->ldev, ++ "iomem enable failed: initial status is 0xff (is %x)\n", ++ test_val); ++ goto out_iomem; ++ } ++ ++ if (read_smc(smc, "LDKN", &ldkn_version, 1)) { ++ dev_warn(smc->ldev, "iomem enable failed: ldkn read failed\n"); ++ goto out_iomem; ++ } ++ ++ if (ldkn_version < 2) { ++ dev_warn(smc->ldev, ++ "iomem enable failed: ldkn version %u is less than minimum (2)\n", ++ ldkn_version); ++ goto out_iomem; ++ } ++ ++ return 0; ++ ++out_iomem: ++ iounmap(smc->iomem_base); ++ ++out: ++ return -ENXIO; ++} ++ + static void applesmc_free_resources(struct applesmc_device *smc) + { ++ if (smc->iomem_base_set) ++ iounmap(smc->iomem_base); + release_region(smc->port_base, APPLESMC_NR_PORTS); + } + +-- +2.30.0 + diff --git a/3006-applesmc-fan-support-on-T2-Macs.patch b/3006-applesmc-fan-support-on-T2-Macs.patch new file mode 100644 index 0000000..2f9c26b --- /dev/null +++ b/3006-applesmc-fan-support-on-T2-Macs.patch @@ -0,0 +1,227 @@ +From 4e63e9b77422aae8e7411ddc7a8458c2585c86df Mon Sep 17 00:00:00 2001 +From: Paul Pawlowski +Date: Sun, 17 Nov 2019 23:12:18 +0100 +Subject: [PATCH 6/6] applesmc: fan support on T2 Macs + +T2 Macs changed the fan values from shorts to +floats, and changed the fan manual override +setting from a bitmask to a per-fan boolean +named F0Md (thanks to @kleuter for mentioning +it). + +A minimal soft-float implementation has been +written for convert floats to integers (and vice +versa). + +Signed-off-by: Aun-Ali Zaidi +--- + drivers/hwmon/applesmc.c | 119 +++++++++++++++++++++++++++++++++------ + 1 file changed, 102 insertions(+), 17 deletions(-) + +diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c +index 2d23bb9ad9dd..0938227be612 100644 +--- a/drivers/hwmon/applesmc.c ++++ b/drivers/hwmon/applesmc.c +@@ -87,6 +87,7 @@ + #define FAN_ID_FMT "F%dID" /* r-o char[16] */ + + #define TEMP_SENSOR_TYPE "sp78" ++#define FLOAT_TYPE "flt " + + /* List of keys used to read/write fan speeds */ + static const char *const fan_speed_fmt[] = { +@@ -96,6 +97,7 @@ static const char *const fan_speed_fmt[] = { + "F%dSf", /* safe speed - not all models */ + "F%dTg", /* target speed (manual: rw) */ + }; ++#define FAN_MANUAL_FMT "F%dMd" + + #define INIT_TIMEOUT_MSECS 5000 /* wait up to 5s for device init ... */ + #define INIT_WAIT_MSECS 50 /* ... in 50ms increments */ +@@ -734,6 +736,42 @@ static int applesmc_read_s16(struct applesmc_device *smc, + return 0; + } + ++/** ++ * applesmc_float_to_u32 - Retrieve the integral part of a float. ++ * This is needed because Apple made fans use float values in the T2. ++ * The fractional point is not significantly useful though, and the integral ++ * part can be easily extracted. ++ */ ++static inline u32 applesmc_float_to_u32(u32 d) ++{ ++ u8 sign = (u8) ((d >> 31) & 1); ++ s32 exp = (s32) ((d >> 23) & 0xff) - 0x7f; ++ u32 fr = d & ((1u << 23) - 1); ++ ++ if (sign || exp < 0) ++ return 0; ++ ++ return (u32) ((1u << exp) + (fr >> (23 - exp))); ++} ++ ++/** ++ * applesmc_u32_to_float - Convert an u32 into a float. ++ * See applesmc_float_to_u32 for a rationale. ++ */ ++static inline u32 applesmc_u32_to_float(u32 d) ++{ ++ u32 dc = d, bc = 0, exp; ++ ++ if (!d) ++ return 0; ++ ++ while (dc >>= 1) ++ ++bc; ++ exp = 0x7f + bc; ++ ++ return (u32) ((exp << 23) | ++ ((d << (23 - (exp - 0x7f))) & ((1u << 23) - 1))); ++} + /* + * applesmc_device_init - initialize the accelerometer. Can sleep. + */ +@@ -1242,6 +1280,7 @@ static ssize_t applesmc_show_fan_speed(struct device *dev, + struct device_attribute *attr, char *sysfsbuf) + { + struct applesmc_device *smc = dev_get_drvdata(dev); ++ const struct applesmc_entry *entry; + int ret; + unsigned int speed = 0; + char newkey[5]; +@@ -1250,11 +1289,21 @@ static ssize_t applesmc_show_fan_speed(struct device *dev, + scnprintf(newkey, sizeof(newkey), fan_speed_fmt[to_option(attr)], + to_index(attr)); + +- ret = applesmc_read_key(smc, newkey, buffer, 2); ++ entry = applesmc_get_entry_by_key(smc, newkey); ++ if (IS_ERR(entry)) ++ return PTR_ERR(entry); ++ ++ if (!strcmp(entry->type, FLOAT_TYPE)) { ++ ret = applesmc_read_entry(smc, entry, (u8 *) &speed, 4); ++ speed = applesmc_float_to_u32(speed); ++ } else { ++ ret = applesmc_read_entry(smc, entry, buffer, 2); ++ speed = ((buffer[0] << 8 | buffer[1]) >> 2); ++ } ++ + if (ret) + return ret; + +- speed = ((buffer[0] << 8 | buffer[1]) >> 2); + return snprintf(sysfsbuf, PAGE_SIZE, "%u\n", speed); + } + +@@ -1263,6 +1312,7 @@ static ssize_t applesmc_store_fan_speed(struct device *dev, + const char *sysfsbuf, size_t count) + { + struct applesmc_device *smc = dev_get_drvdata(dev); ++ const struct applesmc_entry *entry; + int ret; + unsigned long speed; + char newkey[5]; +@@ -1274,9 +1324,18 @@ static ssize_t applesmc_store_fan_speed(struct device *dev, + scnprintf(newkey, sizeof(newkey), fan_speed_fmt[to_option(attr)], + to_index(attr)); + +- buffer[0] = (speed >> 6) & 0xff; +- buffer[1] = (speed << 2) & 0xff; +- ret = applesmc_write_key(smc, newkey, buffer, 2); ++ entry = applesmc_get_entry_by_key(smc, newkey); ++ if (IS_ERR(entry)) ++ return PTR_ERR(entry); ++ ++ if (!strcmp(entry->type, FLOAT_TYPE)) { ++ speed = applesmc_u32_to_float(speed); ++ ret = applesmc_write_entry(smc, entry, (u8 *) &speed, 4); ++ } else { ++ buffer[0] = (speed >> 6) & 0xff; ++ buffer[1] = (speed << 2) & 0xff; ++ ret = applesmc_write_key(smc, newkey, buffer, 2); ++ } + + if (ret) + return ret; +@@ -1291,12 +1350,26 @@ static ssize_t applesmc_show_fan_manual(struct device *dev, + int ret; + u16 manual = 0; + u8 buffer[2]; ++ char newkey[5]; ++ bool has_newkey = false; ++ ++ scnprintf(newkey, sizeof(newkey), FAN_MANUAL_FMT, to_index(attr)); ++ ++ ret = applesmc_has_key(smc, newkey, &has_newkey); ++ if (ret) ++ return ret; ++ ++ if (has_newkey) { ++ ret = applesmc_read_key(smc, newkey, buffer, 1); ++ manual = buffer[0]; ++ } else { ++ ret = applesmc_read_key(smc, FANS_MANUAL, buffer, 2); ++ manual = ((buffer[0] << 8 | buffer[1]) >> to_index(attr)) & 0x01; ++ } + +- ret = applesmc_read_key(smc, FANS_MANUAL, buffer, 2); + if (ret) + return ret; + +- manual = ((buffer[0] << 8 | buffer[1]) >> to_index(attr)) & 0x01; + return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", manual); + } + +@@ -1307,27 +1380,39 @@ static ssize_t applesmc_store_fan_manual(struct device *dev, + struct applesmc_device *smc = dev_get_drvdata(dev); + int ret; + u8 buffer[2]; ++ char newkey[5]; ++ bool has_newkey = false; + unsigned long input; + u16 val; + + if (kstrtoul(sysfsbuf, 10, &input) < 0) + return -EINVAL; + +- ret = applesmc_read_key(smc, FANS_MANUAL, buffer, 2); ++ scnprintf(newkey, sizeof(newkey), FAN_MANUAL_FMT, to_index(attr)); ++ ++ ret = applesmc_has_key(smc, newkey, &has_newkey); + if (ret) +- goto out; ++ return ret; + +- val = (buffer[0] << 8 | buffer[1]); ++ if (has_newkey) { ++ buffer[0] = input & 1; ++ ret = applesmc_write_key(smc, newkey, buffer, 1); ++ } else { ++ ret = applesmc_read_key(smc, FANS_MANUAL, buffer, 2); ++ val = (buffer[0] << 8 | buffer[1]); ++ if (ret) ++ goto out; + +- if (input) +- val = val | (0x01 << to_index(attr)); +- else +- val = val & ~(0x01 << to_index(attr)); ++ if (input) ++ val = val | (0x01 << to_index(attr)); ++ else ++ val = val & ~(0x01 << to_index(attr)); + +- buffer[0] = (val >> 8) & 0xFF; +- buffer[1] = val & 0xFF; ++ buffer[0] = (val >> 8) & 0xFF; ++ buffer[1] = val & 0xFF; + +- ret = applesmc_write_key(smc, FANS_MANUAL, buffer, 2); ++ ret = applesmc_write_key(smc, FANS_MANUAL, buffer, 2); ++ } + + out: + if (ret) +-- +2.30.0 + diff --git a/4001-HID-apple-Add-support-for-keyboard-backlight-on-supp.patch b/4001-HID-apple-Add-support-for-keyboard-backlight-on-supp.patch new file mode 100644 index 0000000..51b0c16 --- /dev/null +++ b/4001-HID-apple-Add-support-for-keyboard-backlight-on-supp.patch @@ -0,0 +1,195 @@ +From dea63f5efd772740758cc78cde6c94a3df2ebde8 Mon Sep 17 00:00:00 2001 +From: Paul Pawlowski +Date: Sat, 30 Jan 2021 23:42:14 -0600 +Subject: [PATCH 1/8] HID: apple: Add support for keyboard backlight on + supported models + +This commit introduces the requisite plumbing for supporting keyboard +backlight on T2-attached, USB exposed models. The quirk mechanism was +used to reuse the existing hid-apple driver. + +Devices that support this feature will be added in subsequent patches. + +Signed-off-by: Aun-Ali Zaidi +--- + drivers/hid/hid-apple.c | 124 ++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 124 insertions(+) + +diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c +index e82f604d33e9..bcebd6ecb2f2 100644 +--- a/drivers/hid/hid-apple.c ++++ b/drivers/hid/hid-apple.c +@@ -7,6 +7,7 @@ + * Copyright (c) 2005 Michael Haboustak for Concept2, Inc + * Copyright (c) 2006-2007 Jiri Kosina + * Copyright (c) 2008 Jiri Slaby ++ * Copyright (c) 2019 Paul Pawlowski + */ + + /* +@@ -30,6 +31,7 @@ + #define APPLE_INVERT_HWHEEL 0x0040 + #define APPLE_IGNORE_HIDINPUT 0x0080 + #define APPLE_NUMLOCK_EMULATION 0x0100 ++#define APPLE_BACKLIGHT_CTL 0x0200 + + #define APPLE_FLAG_FKEY 0x01 + +@@ -57,11 +59,18 @@ MODULE_PARM_DESC(swap_fn_leftctrl, "Swap the Fn and left Control keys. " + "(For people who want to keep PC keyboard muscle memory. " + "[0] = as-is, Mac layout, 1 = swapped, PC layout)"); + ++struct apple_sc_backlight { ++ struct led_classdev cdev; ++ struct hid_device *hdev; ++ unsigned short backlight_off, backlight_on_min, backlight_on_max; ++}; ++ + struct apple_sc { + unsigned long quirks; + unsigned int fn_on; + unsigned int fn_found; + DECLARE_BITMAP(pressed_numlock, KEY_CNT); ++ struct apple_sc_backlight *backlight + }; + + struct apple_key_translation { +@@ -70,6 +79,19 @@ struct apple_key_translation { + u8 flags; + }; + ++struct apple_backlight_config_report { ++ u8 report_id; ++ u8 version; ++ u16 backlight_off, backlight_on_min, backlight_on_max; ++}; ++ ++struct apple_backlight_set_report { ++ u8 report_id; ++ u8 version; ++ u16 backlight; ++ u16 rate; ++}; ++ + static const struct apple_key_translation macbookair_fn_keys[] = { + { KEY_BACKSPACE, KEY_DELETE }, + { KEY_ENTER, KEY_INSERT }, +@@ -414,6 +436,105 @@ static int apple_input_configured(struct hid_device *hdev, + return 0; + } + ++static bool apple_backlight_check_support(struct hid_device *hdev) ++{ ++ int i; ++ unsigned int hid; ++ struct hid_report *report; ++ ++ list_for_each_entry(report, &hdev->report_enum[HID_INPUT_REPORT].report_list, list) { ++ for (i = 0; i < report->maxfield; i++) { ++ hid = report->field[i]->usage->hid; ++ if ((hid & HID_USAGE_PAGE) == HID_UP_MSVENDOR && (hid & HID_USAGE) == 0xf) ++ return true; ++ } ++ } ++ ++ return false; ++} ++ ++static int apple_backlight_set(struct hid_device *hdev, u16 value, u16 rate) ++{ ++ int ret = 0; ++ struct apple_backlight_set_report *rep; ++ ++ rep = kmalloc(sizeof(*rep), GFP_KERNEL); ++ if (rep == NULL) ++ return -ENOMEM; ++ ++ rep->report_id = 0xB0; ++ rep->version = 1; ++ rep->backlight = value; ++ rep->rate = rate; ++ ++ ret = hid_hw_raw_request(hdev, 0xB0u, (u8 *) rep, sizeof(*rep), ++ HID_OUTPUT_REPORT, HID_REQ_SET_REPORT); ++ ++ kfree(rep); ++ return ret; ++} ++ ++static int apple_backlight_led_set(struct led_classdev *led_cdev, ++ enum led_brightness brightness) ++{ ++ struct apple_sc_backlight *backlight = container_of(led_cdev, ++ struct apple_sc_backlight, cdev); ++ ++ return apple_backlight_set(backlight->hdev, brightness, 0); ++} ++ ++static int apple_backlight_init(struct hid_device *hdev) ++{ ++ int ret; ++ struct apple_sc *asc = hid_get_drvdata(hdev); ++ struct apple_backlight_config_report *rep; ++ ++ if (!apple_backlight_check_support(hdev)) ++ return -EINVAL; ++ ++ rep = kmalloc(0x200, GFP_KERNEL); ++ if (rep == NULL) ++ return -ENOMEM; ++ ++ ret = hid_hw_raw_request(hdev, 0xBFu, (u8 *) rep, sizeof(*rep), ++ HID_FEATURE_REPORT, HID_REQ_GET_REPORT); ++ if (ret < 0) { ++ hid_err(hdev, "backlight request failed: %d\n", ret); ++ goto cleanup_and_exit; ++ } ++ if (ret < 8 || rep->version != 1) { ++ hid_err(hdev, "backlight config struct: bad version %i\n", rep->version); ++ ret = -EINVAL; ++ goto cleanup_and_exit; ++ } ++ ++ hid_dbg(hdev, "backlight config: off=%u, on_min=%u, on_max=%u\n", ++ rep->backlight_off, rep->backlight_on_min, rep->backlight_on_max); ++ ++ asc->backlight = devm_kzalloc(&hdev->dev, sizeof(*asc->backlight), GFP_KERNEL); ++ if (!asc->backlight) { ++ ret = -ENOMEM; ++ goto cleanup_and_exit; ++ } ++ ++ asc->backlight->hdev = hdev; ++ asc->backlight->cdev.name = "apple::kbd_backlight"; ++ asc->backlight->cdev.max_brightness = rep->backlight_on_max; ++ asc->backlight->cdev.brightness_set_blocking = apple_backlight_led_set; ++ ++ ret = apple_backlight_set(hdev, 0, 0); ++ if (ret < 0) { ++ hid_err(hdev, "backlight set request failed: %d\n", ret); ++ goto cleanup_and_exit; ++ } ++ ++ ret = devm_led_classdev_register(&hdev->dev, &asc->backlight->cdev); ++ ++cleanup_and_exit: ++ kfree(rep); ++ return ret; ++} ++ + static int apple_probe(struct hid_device *hdev, + const struct hid_device_id *id) + { +@@ -449,6 +570,9 @@ static int apple_probe(struct hid_device *hdev, + return ret; + } + ++ if (quirks & APPLE_BACKLIGHT_CTL) ++ apple_backlight_init(hdev); ++ + return 0; + } + +-- +2.30.0 + diff --git a/4002-HID-apple-Add-support-for-MacbookAir8-1-keyboard-tra.patch b/4002-HID-apple-Add-support-for-MacbookAir8-1-keyboard-tra.patch new file mode 100644 index 0000000..467d7d3 --- /dev/null +++ b/4002-HID-apple-Add-support-for-MacbookAir8-1-keyboard-tra.patch @@ -0,0 +1,112 @@ +From 66b51e1a4c6730ebd926ead0163f7240ef23ec95 Mon Sep 17 00:00:00 2001 +From: Aun-Ali Zaidi +Date: Sun, 31 Jan 2021 00:39:07 -0600 +Subject: [PATCH 2/8] HID: apple: Add support for MacbookAir8,1 + keyboard/trackpad + +This commit adds the necessary IDs and configuration for the MacBook Air +(Retina, 13-inch, 2018) [MacBookAir8,1 J140K iBridge2,8]. + +This model uses the APPLE_BACKLIGHT_CTL quirk to expose keyboard +backlight controls. + +Signed-off-by: Aun-Ali Zaidi +--- + drivers/hid/hid-apple.c | 2 ++ + drivers/hid/hid-ids.h | 1 + + drivers/hid/hid-quirks.c | 2 ++ + drivers/input/mouse/bcm5974.c | 19 +++++++++++++++++++ + 4 files changed, 24 insertions(+) + +diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c +index bcebd6ecb2f2..e0b7b2f2a899 100644 +--- a/drivers/hid/hid-apple.c ++++ b/drivers/hid/hid-apple.c +@@ -729,6 +729,8 @@ static const struct hid_device_id apple_devices[] = { + .driver_data = APPLE_HAS_FN }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING9_JIS), + .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J140K), ++ .driver_data = APPLE_HAS_FN | APPLE_BACKLIGHT_CTL }, + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI), + .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO), +diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h +index a6d63a759043..aedecbb1624c 100644 +--- a/drivers/hid/hid-ids.h ++++ b/drivers/hid/hid-ids.h +@@ -165,6 +165,7 @@ + #define USB_DEVICE_ID_APPLE_WELLSPRING9_ANSI 0x0272 + #define USB_DEVICE_ID_APPLE_WELLSPRING9_ISO 0x0273 + #define USB_DEVICE_ID_APPLE_WELLSPRING9_JIS 0x0274 ++#define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J140K 0x027a + #define USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY 0x030a + #define USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY 0x030b + #define USB_DEVICE_ID_APPLE_IRCONTROL 0x8240 +diff --git a/drivers/hid/hid-quirks.c b/drivers/hid/hid-quirks.c +index 142e9dae2837..fdd0b212cfcb 100644 +--- a/drivers/hid/hid-quirks.c ++++ b/drivers/hid/hid-quirks.c +@@ -289,6 +289,7 @@ static const struct hid_device_id hid_have_special_driver[] = { + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING9_ANSI) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING9_ISO) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING9_JIS) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J140K) }, + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI) }, + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO) }, + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS) }, +@@ -923,6 +924,7 @@ static const struct hid_device_id hid_mouse_ignore_list[] = { + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING9_ANSI) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING9_ISO) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING9_JIS) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J140K) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) }, + { } +diff --git a/drivers/input/mouse/bcm5974.c b/drivers/input/mouse/bcm5974.c +index 59a14505b9cd..bf610d2d8c69 100644 +--- a/drivers/input/mouse/bcm5974.c ++++ b/drivers/input/mouse/bcm5974.c +@@ -83,6 +83,10 @@ + #define USB_DEVICE_ID_APPLE_WELLSPRING9_ISO 0x0273 + #define USB_DEVICE_ID_APPLE_WELLSPRING9_JIS 0x0274 + ++/* T2-Attached Devices */ ++/* MacbookAir8,1 (2018) */ ++#define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J140K 0x027a ++ + #define BCM5974_DEVICE(prod) { \ + .match_flags = (USB_DEVICE_ID_MATCH_DEVICE | \ + USB_DEVICE_ID_MATCH_INT_CLASS | \ +@@ -147,6 +151,8 @@ static const struct usb_device_id bcm5974_table[] = { + BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING9_ANSI), + BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING9_ISO), + BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING9_JIS), ++ /* MacbookAir8,1 */ ++ BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRINGT2_J140K), + /* Terminating entry */ + {} + }; +@@ -483,6 +489,19 @@ static const struct bcm5974_config bcm5974_config_table[] = { + { SN_COORD, -203, 6803 }, + { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION } + }, ++ { ++ USB_DEVICE_ID_APPLE_WELLSPRINGT2_J140K, ++ 0, ++ 0, ++ HAS_INTEGRATED_BUTTON, ++ 0, sizeof(struct bt_data), ++ 0x83, DATAFORMAT(TYPE4), ++ { SN_PRESSURE, 0, 300 }, ++ { SN_WIDTH, 0, 2048 }, ++ { SN_COORD, -6243, 6749 }, ++ { SN_COORD, -170, 7685 }, ++ { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION } ++ }, + {} + }; + +-- +2.30.0 + diff --git a/4003-HID-apple-Add-support-for-MacBookPro15-2-keyboard-tr.patch b/4003-HID-apple-Add-support-for-MacBookPro15-2-keyboard-tr.patch new file mode 100644 index 0000000..71c8b8e --- /dev/null +++ b/4003-HID-apple-Add-support-for-MacBookPro15-2-keyboard-tr.patch @@ -0,0 +1,110 @@ +From cca73561d936d960f17f4861e98844441e610d05 Mon Sep 17 00:00:00 2001 +From: Aun-Ali Zaidi +Date: Sun, 31 Jan 2021 01:04:22 -0600 +Subject: [PATCH 3/8] HID: apple: Add support for MacBookPro15,2 + keyboard/trackpad + +This commit adds the necessary IDs and configuration for the MacBook Pro +(13-inch, 2019, Four Thunderbolt 3 ports) [MacBookPro15,2 J132 iBridge2,4] + +This model uses the APPLE_BACKLIGHT_CTL quirk to expose keyboard +backlight controls. + +Signed-off-by: Aun-Ali Zaidi +--- + drivers/hid/hid-apple.c | 2 ++ + drivers/hid/hid-ids.h | 1 + + drivers/hid/hid-quirks.c | 2 ++ + drivers/input/mouse/bcm5974.c | 17 +++++++++++++++++ + 4 files changed, 22 insertions(+) + +diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c +index e0b7b2f2a899..9c4903b3a1c1 100644 +--- a/drivers/hid/hid-apple.c ++++ b/drivers/hid/hid-apple.c +@@ -731,6 +731,8 @@ static const struct hid_device_id apple_devices[] = { + .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J140K), + .driver_data = APPLE_HAS_FN | APPLE_BACKLIGHT_CTL }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J132), ++ .driver_data = APPLE_HAS_FN | APPLE_BACKLIGHT_CTL }, + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI), + .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO), +diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h +index aedecbb1624c..b0574939b59f 100644 +--- a/drivers/hid/hid-ids.h ++++ b/drivers/hid/hid-ids.h +@@ -166,6 +166,7 @@ + #define USB_DEVICE_ID_APPLE_WELLSPRING9_ISO 0x0273 + #define USB_DEVICE_ID_APPLE_WELLSPRING9_JIS 0x0274 + #define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J140K 0x027a ++#define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J132 0x027b + #define USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY 0x030a + #define USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY 0x030b + #define USB_DEVICE_ID_APPLE_IRCONTROL 0x8240 +diff --git a/drivers/hid/hid-quirks.c b/drivers/hid/hid-quirks.c +index fdd0b212cfcb..7df65c99e984 100644 +--- a/drivers/hid/hid-quirks.c ++++ b/drivers/hid/hid-quirks.c +@@ -290,6 +290,7 @@ static const struct hid_device_id hid_have_special_driver[] = { + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING9_ISO) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING9_JIS) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J140K) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J132) }, + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI) }, + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO) }, + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS) }, +@@ -925,6 +926,7 @@ static const struct hid_device_id hid_mouse_ignore_list[] = { + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING9_ISO) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING9_JIS) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J140K) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J132) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) }, + { } +diff --git a/drivers/input/mouse/bcm5974.c b/drivers/input/mouse/bcm5974.c +index bf610d2d8c69..81c1dac1da81 100644 +--- a/drivers/input/mouse/bcm5974.c ++++ b/drivers/input/mouse/bcm5974.c +@@ -86,6 +86,8 @@ + /* T2-Attached Devices */ + /* MacbookAir8,1 (2018) */ + #define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J140K 0x027a ++/* MacbookPro15,2 (2018) */ ++#define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J132 0x027b + + #define BCM5974_DEVICE(prod) { \ + .match_flags = (USB_DEVICE_ID_MATCH_DEVICE | \ +@@ -153,6 +155,8 @@ static const struct usb_device_id bcm5974_table[] = { + BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING9_JIS), + /* MacbookAir8,1 */ + BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRINGT2_J140K), ++ /* MacbookPro15,2 */ ++ BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRINGT2_J132), + /* Terminating entry */ + {} + }; +@@ -502,6 +506,19 @@ static const struct bcm5974_config bcm5974_config_table[] = { + { SN_COORD, -170, 7685 }, + { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION } + }, ++ { ++ USB_DEVICE_ID_APPLE_WELLSPRINGT2_J132, ++ 0, ++ 0, ++ HAS_INTEGRATED_BUTTON, ++ 0, sizeof(struct bt_data), ++ 0x83, DATAFORMAT(TYPE4), ++ { SN_PRESSURE, 0, 300 }, ++ { SN_WIDTH, 0, 2048 }, ++ { SN_COORD, -6243, 6749 }, ++ { SN_COORD, -170, 7685 }, ++ { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION } ++ }, + {} + }; + +-- +2.30.0 + diff --git a/4004-HID-apple-Add-support-for-MacBookPro15-1-keyboard-tr.patch b/4004-HID-apple-Add-support-for-MacBookPro15-1-keyboard-tr.patch new file mode 100644 index 0000000..d110e8b --- /dev/null +++ b/4004-HID-apple-Add-support-for-MacBookPro15-1-keyboard-tr.patch @@ -0,0 +1,110 @@ +From 257aca65118f370840d6206d821ff4233cae6816 Mon Sep 17 00:00:00 2001 +From: Aun-Ali Zaidi +Date: Sun, 31 Jan 2021 01:16:37 -0600 +Subject: [PATCH 4/8] HID: apple: Add support for MacBookPro15,1 + keyboard/trackpad + +This commit adds the necessary IDs and configuration for the MacBook Pro +(15-inch, 2018) [MacBookPro15,1 J680 iBridge2,3] + +This model uses the APPLE_BACKLIGHT_CTL quirk to expose keyboard +backlight controls. + +Signed-off-by: Aun-Ali Zaidi +--- + drivers/hid/hid-apple.c | 2 ++ + drivers/hid/hid-ids.h | 1 + + drivers/hid/hid-quirks.c | 2 ++ + drivers/input/mouse/bcm5974.c | 17 +++++++++++++++++ + 4 files changed, 22 insertions(+) + +diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c +index 9c4903b3a1c1..bf8dfca762a7 100644 +--- a/drivers/hid/hid-apple.c ++++ b/drivers/hid/hid-apple.c +@@ -733,6 +733,8 @@ static const struct hid_device_id apple_devices[] = { + .driver_data = APPLE_HAS_FN | APPLE_BACKLIGHT_CTL }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J132), + .driver_data = APPLE_HAS_FN | APPLE_BACKLIGHT_CTL }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680), ++ .driver_data = APPLE_HAS_FN | APPLE_BACKLIGHT_CTL }, + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI), + .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO), +diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h +index b0574939b59f..c5340b03a56a 100644 +--- a/drivers/hid/hid-ids.h ++++ b/drivers/hid/hid-ids.h +@@ -167,6 +167,7 @@ + #define USB_DEVICE_ID_APPLE_WELLSPRING9_JIS 0x0274 + #define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J140K 0x027a + #define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J132 0x027b ++#define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680 0x027c + #define USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY 0x030a + #define USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY 0x030b + #define USB_DEVICE_ID_APPLE_IRCONTROL 0x8240 +diff --git a/drivers/hid/hid-quirks.c b/drivers/hid/hid-quirks.c +index 7df65c99e984..32419a34a64d 100644 +--- a/drivers/hid/hid-quirks.c ++++ b/drivers/hid/hid-quirks.c +@@ -291,6 +291,7 @@ static const struct hid_device_id hid_have_special_driver[] = { + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING9_JIS) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J140K) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J132) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680) }, + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI) }, + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO) }, + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS) }, +@@ -927,6 +928,7 @@ static const struct hid_device_id hid_mouse_ignore_list[] = { + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING9_JIS) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J140K) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J132) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) }, + { } +diff --git a/drivers/input/mouse/bcm5974.c b/drivers/input/mouse/bcm5974.c +index 81c1dac1da81..e7280b3c1a08 100644 +--- a/drivers/input/mouse/bcm5974.c ++++ b/drivers/input/mouse/bcm5974.c +@@ -88,6 +88,8 @@ + #define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J140K 0x027a + /* MacbookPro15,2 (2018) */ + #define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J132 0x027b ++/* MacbookPro15,1 (2018) */ ++#define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680 0x027c + + #define BCM5974_DEVICE(prod) { \ + .match_flags = (USB_DEVICE_ID_MATCH_DEVICE | \ +@@ -157,6 +159,8 @@ static const struct usb_device_id bcm5974_table[] = { + BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRINGT2_J140K), + /* MacbookPro15,2 */ + BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRINGT2_J132), ++ /* MacbookPro15,1 */ ++ BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680), + /* Terminating entry */ + {} + }; +@@ -519,6 +523,19 @@ static const struct bcm5974_config bcm5974_config_table[] = { + { SN_COORD, -170, 7685 }, + { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION } + }, ++ { ++ USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680, ++ 0, ++ 0, ++ HAS_INTEGRATED_BUTTON, ++ 0, sizeof(struct bt_data), ++ 0x83, DATAFORMAT(TYPE4), ++ { SN_PRESSURE, 0, 300 }, ++ { SN_WIDTH, 0, 2048 }, ++ { SN_COORD, -7456, 7976 }, ++ { SN_COORD, -1768, 7685 }, ++ { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION } ++ }, + {} + }; + +-- +2.30.0 + diff --git a/4005-HID-apple-Add-support-for-MacBookPro15-4-keyboard-tr.patch b/4005-HID-apple-Add-support-for-MacBookPro15-4-keyboard-tr.patch new file mode 100644 index 0000000..0230306 --- /dev/null +++ b/4005-HID-apple-Add-support-for-MacBookPro15-4-keyboard-tr.patch @@ -0,0 +1,110 @@ +From 3c0c9c386f44263d0003e0cc148cff10a61f5a37 Mon Sep 17 00:00:00 2001 +From: Aun-Ali Zaidi +Date: Sun, 31 Jan 2021 01:56:59 -0600 +Subject: [PATCH 5/8] HID: apple: Add support for MacBookPro15,4 + keyboard/trackpad + +This commit adds the necessary IDs and configuration for the MacBook Pro +(13-inch, 2019, Two Thunderbolt 3 ports) [MacBookPro15,4 J213 iBridge2,10] + +This model uses the APPLE_BACKLIGHT_CTL quirk to expose keyboard +backlight controls. + +Signed-off-by: Aun-Ali Zaidi +--- + drivers/hid/hid-apple.c | 2 ++ + drivers/hid/hid-ids.h | 1 + + drivers/hid/hid-quirks.c | 2 ++ + drivers/input/mouse/bcm5974.c | 17 +++++++++++++++++ + 4 files changed, 22 insertions(+) + +diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c +index bf8dfca762a7..11bfc6b16778 100644 +--- a/drivers/hid/hid-apple.c ++++ b/drivers/hid/hid-apple.c +@@ -735,6 +735,8 @@ static const struct hid_device_id apple_devices[] = { + .driver_data = APPLE_HAS_FN | APPLE_BACKLIGHT_CTL }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680), + .driver_data = APPLE_HAS_FN | APPLE_BACKLIGHT_CTL }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J213), ++ .driver_data = APPLE_HAS_FN | APPLE_BACKLIGHT_CTL }, + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI), + .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO), +diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h +index c5340b03a56a..1e28f1f54de8 100644 +--- a/drivers/hid/hid-ids.h ++++ b/drivers/hid/hid-ids.h +@@ -168,6 +168,7 @@ + #define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J140K 0x027a + #define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J132 0x027b + #define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680 0x027c ++#define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J213 0x027d + #define USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY 0x030a + #define USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY 0x030b + #define USB_DEVICE_ID_APPLE_IRCONTROL 0x8240 +diff --git a/drivers/hid/hid-quirks.c b/drivers/hid/hid-quirks.c +index 32419a34a64d..ee698d275427 100644 +--- a/drivers/hid/hid-quirks.c ++++ b/drivers/hid/hid-quirks.c +@@ -292,6 +292,7 @@ static const struct hid_device_id hid_have_special_driver[] = { + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J140K) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J132) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J213) }, + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI) }, + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO) }, + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS) }, +@@ -929,6 +930,7 @@ static const struct hid_device_id hid_mouse_ignore_list[] = { + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J140K) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J132) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J213) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) }, + { } +diff --git a/drivers/input/mouse/bcm5974.c b/drivers/input/mouse/bcm5974.c +index e7280b3c1a08..3964f58fb870 100644 +--- a/drivers/input/mouse/bcm5974.c ++++ b/drivers/input/mouse/bcm5974.c +@@ -90,6 +90,8 @@ + #define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J132 0x027b + /* MacbookPro15,1 (2018) */ + #define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680 0x027c ++/* MacbookPro15,4 (2019) */ ++#define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J213 0x027d + + #define BCM5974_DEVICE(prod) { \ + .match_flags = (USB_DEVICE_ID_MATCH_DEVICE | \ +@@ -161,6 +163,8 @@ static const struct usb_device_id bcm5974_table[] = { + BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRINGT2_J132), + /* MacbookPro15,1 */ + BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680), ++ /* MacbookPro15,4 */ ++ BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRINGT2_J213), + /* Terminating entry */ + {} + }; +@@ -536,6 +540,19 @@ static const struct bcm5974_config bcm5974_config_table[] = { + { SN_COORD, -1768, 7685 }, + { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION } + }, ++ { ++ USB_DEVICE_ID_APPLE_WELLSPRINGT2_J213, ++ 0, ++ 0, ++ HAS_INTEGRATED_BUTTON, ++ 0, sizeof(struct bt_data), ++ 0x83, DATAFORMAT(TYPE4), ++ { SN_PRESSURE, 0, 300 }, ++ { SN_WIDTH, 0, 2048 }, ++ { SN_COORD, -6243, 6749 }, ++ { SN_COORD, -170, 7685 }, ++ { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION } ++ }, + {} + }; + +-- +2.30.0 + diff --git a/4006-HID-apple-Add-support-for-MacBookPro16-2-keyboard-tr.patch b/4006-HID-apple-Add-support-for-MacBookPro16-2-keyboard-tr.patch new file mode 100644 index 0000000..ad6da05 --- /dev/null +++ b/4006-HID-apple-Add-support-for-MacBookPro16-2-keyboard-tr.patch @@ -0,0 +1,111 @@ +From 30592af9908905aaa13579e31c85c6fc9ff5e8d1 Mon Sep 17 00:00:00 2001 +From: Aun-Ali Zaidi +Date: Sun, 31 Jan 2021 02:00:14 -0600 +Subject: [PATCH 6/8] HID: apple: Add support for MacBookPro16,2 + keyboard/trackpad + +This commit adds the necessary IDs and configuration for the MacBook Pro +(13-inch, 2020, Four Thunderbolt 3 ports) [MacBookPro16,2 J214K +iBridge2,16] + +This model uses the APPLE_BACKLIGHT_CTL quirk to expose keyboard +backlight controls. + +Signed-off-by: Aun-Ali Zaidi +--- + drivers/hid/hid-apple.c | 2 ++ + drivers/hid/hid-ids.h | 1 + + drivers/hid/hid-quirks.c | 2 ++ + drivers/input/mouse/bcm5974.c | 17 +++++++++++++++++ + 4 files changed, 22 insertions(+) + +diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c +index 11bfc6b16778..f4df537c2141 100644 +--- a/drivers/hid/hid-apple.c ++++ b/drivers/hid/hid-apple.c +@@ -737,6 +737,8 @@ static const struct hid_device_id apple_devices[] = { + .driver_data = APPLE_HAS_FN | APPLE_BACKLIGHT_CTL }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J213), + .driver_data = APPLE_HAS_FN | APPLE_BACKLIGHT_CTL }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J214K), ++ .driver_data = APPLE_HAS_FN | APPLE_BACKLIGHT_CTL }, + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI), + .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO), +diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h +index 1e28f1f54de8..3f9ebb04858e 100644 +--- a/drivers/hid/hid-ids.h ++++ b/drivers/hid/hid-ids.h +@@ -169,6 +169,7 @@ + #define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J132 0x027b + #define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680 0x027c + #define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J213 0x027d ++#define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J214K 0x027e + #define USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY 0x030a + #define USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY 0x030b + #define USB_DEVICE_ID_APPLE_IRCONTROL 0x8240 +diff --git a/drivers/hid/hid-quirks.c b/drivers/hid/hid-quirks.c +index ee698d275427..d15b6fe0c8c2 100644 +--- a/drivers/hid/hid-quirks.c ++++ b/drivers/hid/hid-quirks.c +@@ -293,6 +293,7 @@ static const struct hid_device_id hid_have_special_driver[] = { + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J132) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J213) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J214K) }, + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI) }, + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO) }, + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS) }, +@@ -931,6 +932,7 @@ static const struct hid_device_id hid_mouse_ignore_list[] = { + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J132) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J213) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J214K) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) }, + { } +diff --git a/drivers/input/mouse/bcm5974.c b/drivers/input/mouse/bcm5974.c +index 3964f58fb870..00116c57d6cd 100644 +--- a/drivers/input/mouse/bcm5974.c ++++ b/drivers/input/mouse/bcm5974.c +@@ -92,6 +92,8 @@ + #define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680 0x027c + /* MacbookPro15,4 (2019) */ + #define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J213 0x027d ++/* MacbookPro16,2 (2020) */ ++#define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J214K 0x027e + + #define BCM5974_DEVICE(prod) { \ + .match_flags = (USB_DEVICE_ID_MATCH_DEVICE | \ +@@ -165,6 +167,8 @@ static const struct usb_device_id bcm5974_table[] = { + BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680), + /* MacbookPro15,4 */ + BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRINGT2_J213), ++ /* MacbookPro16,2 */ ++ BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRINGT2_J214K), + /* Terminating entry */ + {} + }; +@@ -553,6 +557,19 @@ static const struct bcm5974_config bcm5974_config_table[] = { + { SN_COORD, -170, 7685 }, + { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION } + }, ++ { ++ USB_DEVICE_ID_APPLE_WELLSPRINGT2_J214K, ++ 0, ++ 0, ++ HAS_INTEGRATED_BUTTON, ++ 0, sizeof(struct bt_data), ++ 0x83, DATAFORMAT(TYPE4), ++ { SN_PRESSURE, 0, 300 }, ++ { SN_WIDTH, 0, 2048 }, ++ { SN_COORD, -6243, 6749 }, ++ { SN_COORD, -170, 7685 }, ++ { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION } ++ }, + {} + }; + +-- +2.30.0 + diff --git a/4007-HID-apple-Add-support-for-MacBookAir9-1-keyboard-tra.patch b/4007-HID-apple-Add-support-for-MacBookAir9-1-keyboard-tra.patch new file mode 100644 index 0000000..8a304c2 --- /dev/null +++ b/4007-HID-apple-Add-support-for-MacBookAir9-1-keyboard-tra.patch @@ -0,0 +1,110 @@ +From 7d0a89b5be341ef58bf5a509c3c1f5abae6b72d6 Mon Sep 17 00:00:00 2001 +From: Aun-Ali Zaidi +Date: Sun, 31 Jan 2021 02:16:15 -0600 +Subject: [PATCH 7/8] HID: apple: Add support for MacBookAir9,1 + keyboard/trackpad + +This commit adds the necessary IDs and configuration for the MacBook Air +(Retina, 13-inch, 2020) [MacBookAir9,1 J230K iBridge2,15] + +This model uses the APPLE_BACKLIGHT_CTL quirk to expose keyboard +backlight controls. + +Signed-off-by: Aun-Ali Zaidi +--- + drivers/hid/hid-apple.c | 2 ++ + drivers/hid/hid-ids.h | 1 + + drivers/hid/hid-quirks.c | 2 ++ + drivers/input/mouse/bcm5974.c | 17 +++++++++++++++++ + 4 files changed, 22 insertions(+) + +diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c +index f4df537c2141..bb21fa2cc3cd 100644 +--- a/drivers/hid/hid-apple.c ++++ b/drivers/hid/hid-apple.c +@@ -739,6 +739,8 @@ static const struct hid_device_id apple_devices[] = { + .driver_data = APPLE_HAS_FN | APPLE_BACKLIGHT_CTL }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J214K), + .driver_data = APPLE_HAS_FN | APPLE_BACKLIGHT_CTL }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J230K), ++ .driver_data = APPLE_HAS_FN | APPLE_BACKLIGHT_CTL }, + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI), + .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO), +diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h +index 3f9ebb04858e..604bbeca64c7 100644 +--- a/drivers/hid/hid-ids.h ++++ b/drivers/hid/hid-ids.h +@@ -170,6 +170,7 @@ + #define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680 0x027c + #define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J213 0x027d + #define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J214K 0x027e ++#define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J230K 0x0280 + #define USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY 0x030a + #define USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY 0x030b + #define USB_DEVICE_ID_APPLE_IRCONTROL 0x8240 +diff --git a/drivers/hid/hid-quirks.c b/drivers/hid/hid-quirks.c +index d15b6fe0c8c2..c9b5eab5118c 100644 +--- a/drivers/hid/hid-quirks.c ++++ b/drivers/hid/hid-quirks.c +@@ -294,6 +294,7 @@ static const struct hid_device_id hid_have_special_driver[] = { + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J213) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J214K) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J230K) }, + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI) }, + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO) }, + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS) }, +@@ -933,6 +934,7 @@ static const struct hid_device_id hid_mouse_ignore_list[] = { + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J213) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J214K) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J230K) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) }, + { } +diff --git a/drivers/input/mouse/bcm5974.c b/drivers/input/mouse/bcm5974.c +index 00116c57d6cd..5214b9cb6709 100644 +--- a/drivers/input/mouse/bcm5974.c ++++ b/drivers/input/mouse/bcm5974.c +@@ -94,6 +94,8 @@ + #define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J213 0x027d + /* MacbookPro16,2 (2020) */ + #define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J214K 0x027e ++/* MacbookAir9,1 (2020) */ ++#define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J230K 0x0280 + + #define BCM5974_DEVICE(prod) { \ + .match_flags = (USB_DEVICE_ID_MATCH_DEVICE | \ +@@ -169,6 +171,8 @@ static const struct usb_device_id bcm5974_table[] = { + BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRINGT2_J213), + /* MacbookPro16,2 */ + BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRINGT2_J214K), ++ /* MacbookAir9,1 */ ++ BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRINGT2_J230K), + /* Terminating entry */ + {} + }; +@@ -570,6 +574,19 @@ static const struct bcm5974_config bcm5974_config_table[] = { + { SN_COORD, -170, 7685 }, + { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION } + }, ++ { ++ USB_DEVICE_ID_APPLE_WELLSPRINGT2_J230K, ++ 0, ++ 0, ++ HAS_INTEGRATED_BUTTON, ++ 0, sizeof(struct bt_data), ++ 0x83, DATAFORMAT(TYPE4), ++ { SN_PRESSURE, 0, 300 }, ++ { SN_WIDTH, 0, 2048 }, ++ { SN_COORD, -6243, 6749 }, ++ { SN_COORD, -170, 7685 }, ++ { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION } ++ }, + {} + }; + +-- +2.30.0 + diff --git a/4008-HID-apple-Add-support-for-MacBookPro16-1-keyboard-tr.patch b/4008-HID-apple-Add-support-for-MacBookPro16-1-keyboard-tr.patch new file mode 100644 index 0000000..0f729d8 --- /dev/null +++ b/4008-HID-apple-Add-support-for-MacBookPro16-1-keyboard-tr.patch @@ -0,0 +1,110 @@ +From b0ca7f7f2b8e714f68021b705ac21edf45ae8959 Mon Sep 17 00:00:00 2001 +From: Aun-Ali Zaidi +Date: Sun, 31 Jan 2021 02:26:18 -0600 +Subject: [PATCH 8/8] HID: apple: Add support for MacBookPro16,1 + keyboard/trackpad + +This commit adds the necessary IDs and configuration for the MacBook Pro +(16-inch, 2019) [MacBookPro16,1 J152F iBridge2,14] + +This model uses the APPLE_BACKLIGHT_CTL quirk to expose keyboard +backlight controls. + +Signed-off-by: Aun-Ali Zaidi +--- + drivers/hid/hid-apple.c | 2 ++ + drivers/hid/hid-ids.h | 1 + + drivers/hid/hid-quirks.c | 2 ++ + drivers/input/mouse/bcm5974.c | 17 +++++++++++++++++ + 4 files changed, 22 insertions(+) + +diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c +index bb21fa2cc3cd..471268af21d6 100644 +--- a/drivers/hid/hid-apple.c ++++ b/drivers/hid/hid-apple.c +@@ -741,6 +741,8 @@ static const struct hid_device_id apple_devices[] = { + .driver_data = APPLE_HAS_FN | APPLE_BACKLIGHT_CTL }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J230K), + .driver_data = APPLE_HAS_FN | APPLE_BACKLIGHT_CTL }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J152F), ++ .driver_data = APPLE_HAS_FN | APPLE_BACKLIGHT_CTL }, + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI), + .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO), +diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h +index 604bbeca64c7..3e87df966ab7 100644 +--- a/drivers/hid/hid-ids.h ++++ b/drivers/hid/hid-ids.h +@@ -171,6 +171,7 @@ + #define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J213 0x027d + #define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J214K 0x027e + #define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J230K 0x0280 ++#define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J152F 0x0340 + #define USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY 0x030a + #define USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY 0x030b + #define USB_DEVICE_ID_APPLE_IRCONTROL 0x8240 +diff --git a/drivers/hid/hid-quirks.c b/drivers/hid/hid-quirks.c +index c9b5eab5118c..79aa08364eec 100644 +--- a/drivers/hid/hid-quirks.c ++++ b/drivers/hid/hid-quirks.c +@@ -295,6 +295,7 @@ static const struct hid_device_id hid_have_special_driver[] = { + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J213) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J214K) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J230K) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J152F) }, + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI) }, + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO) }, + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS) }, +@@ -935,6 +936,7 @@ static const struct hid_device_id hid_mouse_ignore_list[] = { + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J213) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J214K) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J230K) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J152F) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) }, + { } +diff --git a/drivers/input/mouse/bcm5974.c b/drivers/input/mouse/bcm5974.c +index 5214b9cb6709..bc332d092859 100644 +--- a/drivers/input/mouse/bcm5974.c ++++ b/drivers/input/mouse/bcm5974.c +@@ -96,6 +96,8 @@ + #define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J214K 0x027e + /* MacbookAir9,1 (2020) */ + #define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J230K 0x0280 ++/* MacbookPro16,1 (2019)*/ ++#define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J152F 0x0340 + + #define BCM5974_DEVICE(prod) { \ + .match_flags = (USB_DEVICE_ID_MATCH_DEVICE | \ +@@ -173,6 +175,8 @@ static const struct usb_device_id bcm5974_table[] = { + BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRINGT2_J214K), + /* MacbookAir9,1 */ + BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRINGT2_J230K), ++ /* MacbookPro16,1 */ ++ BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRINGT2_J152F), + /* Terminating entry */ + {} + }; +@@ -587,6 +591,19 @@ static const struct bcm5974_config bcm5974_config_table[] = { + { SN_COORD, -170, 7685 }, + { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION } + }, ++ { ++ USB_DEVICE_ID_APPLE_WELLSPRINGT2_J152F, ++ 0, ++ 0, ++ HAS_INTEGRATED_BUTTON, ++ 0, sizeof(struct bt_data), ++ 0x83, DATAFORMAT(TYPE4), ++ { SN_PRESSURE, 0, 300 }, ++ { SN_WIDTH, 0, 2048 }, ++ { SN_COORD, -7456, 7976 }, ++ { SN_COORD, -1768, 7685 }, ++ { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION } ++ }, + {} + }; + +-- +2.30.0 + diff --git a/5001-brcmfmac-move-brcmf_mp_device-into-its-own-header.patch b/5001-brcmfmac-move-brcmf_mp_device-into-its-own-header.patch new file mode 100644 index 0000000..b47da92 --- /dev/null +++ b/5001-brcmfmac-move-brcmf_mp_device-into-its-own-header.patch @@ -0,0 +1,120 @@ +From ca775a3e16ac138ff47fcc3eccacd154ee35e9c2 Mon Sep 17 00:00:00 2001 +From: Aun-Ali Zaidi +Date: Fri, 10 Jan 2020 12:47:25 -0600 +Subject: [PATCH 1/2] brcmfmac: move brcmf_mp_device into its own header + +This commit relocates the brcmf_mp_device struct into its own header. This +aids in utilizing the struct without the redefinition of the existing +included headers found in common.h, such as fwil_types.h. + +Tested-by: Aun-Ali Zaidi +Signed-off-by: Aun-Ali Zaidi +--- + .../broadcom/brcm80211/brcmfmac/common.h | 36 +++--------------- + .../broadcom/brcm80211/brcmfmac/settings.h | 37 +++++++++++++++++++ + 2 files changed, 42 insertions(+), 31 deletions(-) + create mode 100644 drivers/net/wireless/broadcom/brcm80211/brcmfmac/settings.h + +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h +index 8b5f49997c8b..6cde5ee13e7a 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h +@@ -8,15 +8,14 @@ + #include + #include + #include "fwil_types.h" ++#include "settings.h" + + #define BRCMF_FW_ALTPATH_LEN 256 + +-/* Definitions for the module global and device specific settings are defined +- * here. Two structs are used for them. brcmf_mp_global_t and brcmf_mp_device. +- * The mp_global is instantiated once in a global struct and gets initialized +- * by the common_attach function which should be called before any other +- * (module) initiliazation takes place. The device specific settings is part +- * of the drvr struct and should be initialized on every brcmf_attach. ++/* Definition for the module global settings are defined here. One struct is ++ * used called brcmf_mp_global_t. The mp_global is instantiated once in a ++ * global struct and gets initialized by the common_attach function which ++ * should be called before any other (module) initiliazation takes place. + */ + + /** +@@ -30,31 +29,6 @@ struct brcmf_mp_global_t { + + extern struct brcmf_mp_global_t brcmf_mp_global; + +-/** +- * struct brcmf_mp_device - Device module paramaters. +- * +- * @p2p_enable: Legacy P2P0 enable (old wpa_supplicant). +- * @feature_disable: Feature_disable bitmask. +- * @fcmode: FWS flow control. +- * @roamoff: Firmware roaming off? +- * @ignore_probe_fail: Ignore probe failure. +- * @country_codes: If available, pointer to struct for translating country codes +- * @bus: Bus specific platform data. Only SDIO at the mmoment. +- */ +-struct brcmf_mp_device { +- bool p2p_enable; +- unsigned int feature_disable; +- int fcmode; +- bool roamoff; +- bool iapp; +- bool ignore_probe_fail; +- struct brcmfmac_pd_cc *country_codes; +- const char *board_type; +- union { +- struct brcmfmac_sdio_pd sdio; +- } bus; +-}; +- + void brcmf_c_set_joinpref_default(struct brcmf_if *ifp); + + struct brcmf_mp_device *brcmf_get_module_param(struct device *dev, +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/settings.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/settings.h +new file mode 100644 +index 000000000000..7bab0d362cdd +--- /dev/null ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/settings.h +@@ -0,0 +1,37 @@ ++/* SPDX-License-Identifier: ISC */ ++/* Copyright (c) 2014 Broadcom Corporation */ ++ ++#ifndef BRCMFMAC_SETTINGS_H ++#define BRCMFMAC_SETTINGS_H ++ ++/* Definition for the device specific settings are defined here. One struct ++ * is used called brcmf_mp_device. The device specific settings is part of ++ * the drvr struct and should be initialized on every brcmf_attach. ++ */ ++ ++/** ++ * struct brcmf_mp_device - Device module parameters. ++ * ++ * @p2p_enable: Legacy P2P0 enable (old wpa_supplicant). ++ * @feature_disable: Feature_disable bitmask. ++ * @fcmode: FWS flow control. ++ * @roamoff: Firmware roaming off? ++ * @ignore_probe_fail: Ignore probe failure. ++ * @country_codes: If available, pointer to struct for translating country codes ++ * @bus: Bus specific platform data. Only SDIO at the mmoment. ++ */ ++struct brcmf_mp_device { ++ bool p2p_enable; ++ unsigned int feature_disable; ++ int fcmode; ++ bool roamoff; ++ bool iapp; ++ bool ignore_probe_fail; ++ struct brcmfmac_pd_cc *country_codes; ++ const char *board_type; ++ union { ++ struct brcmfmac_sdio_pd sdio; ++ } bus; ++}; ++ ++#endif /* BRCMFMAC_SETTINGS_H */ +-- +2.30.0 + diff --git a/5002-brcmfmac-Add-ability-to-manually-specify-FW-rambase-.patch b/5002-brcmfmac-Add-ability-to-manually-specify-FW-rambase-.patch new file mode 100644 index 0000000..752c249 --- /dev/null +++ b/5002-brcmfmac-Add-ability-to-manually-specify-FW-rambase-.patch @@ -0,0 +1,224 @@ +From 26c44d268ac1d328ef4cbd35a2a1a3d703346903 Mon Sep 17 00:00:00 2001 +From: Aun-Ali Zaidi +Date: Fri, 10 Jan 2020 19:41:21 -0600 +Subject: [PATCH 2/2] brcmfmac: Add ability to manually specify FW rambase + address + +This commit introduces the ability to manually pass the rambase address +for the brcmfmac chip as a kernel module option. The existing +brcmf_chip_tcm_rambase() function is bypassed when this option is +supplied. This is very useful when debugging support for newer chipsets +that are not provided by the aforementioned function. + +Tested-by: Aun-Ali Zaidi +Signed-off-by: Aun-Ali Zaidi +--- + .../broadcom/brcm80211/brcmfmac/chip.c | 19 ++++++++++++------- + .../broadcom/brcm80211/brcmfmac/chip.h | 7 +++++-- + .../broadcom/brcm80211/brcmfmac/common.c | 5 +++++ + .../broadcom/brcm80211/brcmfmac/common.h | 1 - + .../broadcom/brcm80211/brcmfmac/pcie.c | 4 ++-- + .../broadcom/brcm80211/brcmfmac/sdio.c | 2 +- + .../broadcom/brcm80211/brcmfmac/settings.h | 4 ++++ + 7 files changed, 29 insertions(+), 13 deletions(-) + +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c +index a3a257089696..039dcf7853a6 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c +@@ -733,7 +733,7 @@ static u32 brcmf_chip_tcm_rambase(struct brcmf_chip_priv *ci) + return 0; + } + +-int brcmf_chip_get_raminfo(struct brcmf_chip *pub) ++int brcmf_chip_get_raminfo(struct brcmf_chip *pub, struct brcmf_mp_device *settings) + { + struct brcmf_chip_priv *ci = container_of(pub, struct brcmf_chip_priv, + pub); +@@ -744,7 +744,9 @@ int brcmf_chip_get_raminfo(struct brcmf_chip *pub) + if (mem) { + mem_core = container_of(mem, struct brcmf_core_priv, pub); + ci->pub.ramsize = brcmf_chip_tcm_ramsize(mem_core); +- ci->pub.rambase = brcmf_chip_tcm_rambase(ci); ++ ci->pub.rambase = (settings && ++ settings->rambase_addr > 0) ? settings->rambase_addr ++ : brcmf_chip_tcm_rambase(ci); + if (!ci->pub.rambase) { + brcmf_err("RAM base not provided with ARM CR4 core\n"); + return -EINVAL; +@@ -755,7 +757,9 @@ int brcmf_chip_get_raminfo(struct brcmf_chip *pub) + mem_core = container_of(mem, struct brcmf_core_priv, + pub); + ci->pub.ramsize = brcmf_chip_sysmem_ramsize(mem_core); +- ci->pub.rambase = brcmf_chip_tcm_rambase(ci); ++ ci->pub.rambase = (settings && ++ settings->rambase_addr > 0) ? settings->rambase_addr ++ : brcmf_chip_tcm_rambase(ci); + if (!ci->pub.rambase) { + brcmf_err("RAM base not provided with ARM CA7 core\n"); + return -EINVAL; +@@ -941,7 +945,7 @@ int brcmf_chip_dmp_erom_scan(struct brcmf_chip_priv *ci) + return 0; + } + +-static int brcmf_chip_recognition(struct brcmf_chip_priv *ci) ++static int brcmf_chip_recognition(struct brcmf_chip_priv *ci, struct brcmf_mp_device *settings) + { + struct brcmf_core *core; + u32 regdata; +@@ -1014,7 +1018,7 @@ static int brcmf_chip_recognition(struct brcmf_chip_priv *ci) + brcmf_chip_set_passive(&ci->pub); + } + +- return brcmf_chip_get_raminfo(&ci->pub); ++ return brcmf_chip_get_raminfo(&ci->pub, settings); + } + + static void brcmf_chip_disable_arm(struct brcmf_chip_priv *chip, u16 id) +@@ -1088,7 +1092,8 @@ static int brcmf_chip_setup(struct brcmf_chip_priv *chip) + } + + struct brcmf_chip *brcmf_chip_attach(void *ctx, +- const struct brcmf_buscore_ops *ops) ++ const struct brcmf_buscore_ops *ops, ++ struct brcmf_mp_device *settings) + { + struct brcmf_chip_priv *chip; + int err = 0; +@@ -1117,7 +1122,7 @@ struct brcmf_chip *brcmf_chip_attach(void *ctx, + if (err < 0) + goto fail; + +- err = brcmf_chip_recognition(chip); ++ err = brcmf_chip_recognition(chip, settings); + if (err < 0) + goto fail; + +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.h +index 8fa38658e727..7da0ef3129a0 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.h +@@ -7,6 +7,8 @@ + + #include + ++#include "settings.h" ++ + #define CORE_CC_REG(base, field) \ + (base + offsetof(struct chipcregs, field)) + +@@ -69,9 +71,10 @@ struct brcmf_buscore_ops { + void (*activate)(void *ctx, struct brcmf_chip *chip, u32 rstvec); + }; + +-int brcmf_chip_get_raminfo(struct brcmf_chip *pub); ++int brcmf_chip_get_raminfo(struct brcmf_chip *pub, struct brcmf_mp_device *settings); + struct brcmf_chip *brcmf_chip_attach(void *ctx, +- const struct brcmf_buscore_ops *ops); ++ const struct brcmf_buscore_ops *ops, ++ struct brcmf_mp_device *settings); + void brcmf_chip_detach(struct brcmf_chip *chip); + struct brcmf_core *brcmf_chip_get_core(struct brcmf_chip *chip, u16 coreid); + struct brcmf_core *brcmf_chip_get_d11core(struct brcmf_chip *pub, u8 unit); +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c +index e3758bd86acf..46a525278848 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c +@@ -67,6 +67,10 @@ static int brcmf_iapp_enable; + module_param_named(iapp, brcmf_iapp_enable, int, 0); + MODULE_PARM_DESC(iapp, "Enable partial support for the obsoleted Inter-Access Point Protocol"); + ++static uint brcmf_rambase_addr; ++module_param_named(rambase_addr, brcmf_rambase_addr, uint, 0); ++MODULE_PARM_DESC(rambase_addr, "Manually specify FW shared rambase address"); ++ + #ifdef DEBUG + /* always succeed brcmf_bus_started() */ + static int brcmf_ignore_probe_fail; +@@ -416,6 +420,7 @@ struct brcmf_mp_device *brcmf_get_module_param(struct device *dev, + #ifdef DEBUG + settings->ignore_probe_fail = !!brcmf_ignore_probe_fail; + #endif ++ settings->rambase_addr = brcmf_rambase_addr; + + if (bus_type == BRCMF_BUSTYPE_SDIO) + settings->bus.sdio.txglomsz = brcmf_sdiod_txglomsz; +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h +index 6cde5ee13e7a..0da7eeeb7768 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h +@@ -6,7 +6,6 @@ + #define BRCMFMAC_COMMON_H + + #include +-#include + #include "fwil_types.h" + #include "settings.h" + +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c +index 39381cbde89e..a9575ae8add1 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c +@@ -1772,7 +1772,7 @@ static void brcmf_pcie_setup(struct device *dev, int ret, + nvram_len = fwreq->items[BRCMF_PCIE_FW_NVRAM].nv_data.len; + kfree(fwreq); + +- ret = brcmf_chip_get_raminfo(devinfo->ci); ++ ret = brcmf_chip_get_raminfo(devinfo->ci, devinfo->settings); + if (ret) { + brcmf_err(bus, "Failed to get RAM info\n"); + goto fail; +@@ -1884,7 +1884,7 @@ brcmf_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id) + + devinfo->pdev = pdev; + pcie_bus_dev = NULL; +- devinfo->ci = brcmf_chip_attach(devinfo, &brcmf_pcie_buscore_ops); ++ devinfo->ci = brcmf_chip_attach(devinfo, &brcmf_pcie_buscore_ops, devinfo->settings); + if (IS_ERR(devinfo->ci)) { + ret = PTR_ERR(devinfo->ci); + devinfo->ci = NULL; +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +index ac3ee93a2378..d4bf1c7e3c81 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +@@ -3962,7 +3962,7 @@ brcmf_sdio_probe_attach(struct brcmf_sdio *bus) + goto fail; + } + +- bus->ci = brcmf_chip_attach(sdiodev, &brcmf_sdio_buscore_ops); ++ bus->ci = brcmf_chip_attach(sdiodev, &brcmf_sdio_buscore_ops, sdiodev->settings); + if (IS_ERR(bus->ci)) { + brcmf_err("brcmf_chip_attach failed!\n"); + bus->ci = NULL; +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/settings.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/settings.h +index 7bab0d362cdd..160e32f32bd8 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/settings.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/settings.h +@@ -4,6 +4,8 @@ + #ifndef BRCMFMAC_SETTINGS_H + #define BRCMFMAC_SETTINGS_H + ++#include ++ + /* Definition for the device specific settings are defined here. One struct + * is used called brcmf_mp_device. The device specific settings is part of + * the drvr struct and should be initialized on every brcmf_attach. +@@ -19,6 +21,7 @@ + * @ignore_probe_fail: Ignore probe failure. + * @country_codes: If available, pointer to struct for translating country codes + * @bus: Bus specific platform data. Only SDIO at the mmoment. ++ * @rambase_addr: Manually specified FW shared rambase address. + */ + struct brcmf_mp_device { + bool p2p_enable; +@@ -32,6 +35,7 @@ struct brcmf_mp_device { + union { + struct brcmfmac_sdio_pd sdio; + } bus; ++ u32 rambase_addr; + }; + + #endif /* BRCMFMAC_SETTINGS_H */ +-- +2.30.0 + diff --git a/6001-media-uvcvideo-Add-support-for-Apple-T2-attached-iSi.patch b/6001-media-uvcvideo-Add-support-for-Apple-T2-attached-iSi.patch new file mode 100644 index 0000000..7914894 --- /dev/null +++ b/6001-media-uvcvideo-Add-support-for-Apple-T2-attached-iSi.patch @@ -0,0 +1,38 @@ +From 4b7d515dcd6b4faf84a05b8ef555d75875314407 Mon Sep 17 00:00:00 2001 +From: Paul Pawlowski +Date: Tue, 18 Aug 2020 06:55:07 -0500 +Subject: [PATCH] media: uvcvideo: Add support for Apple T2-attached iSight + Camera + +Adds the requisite device id to support detection of the Apple iSight +webcam exposed over the T2 BCE VHCI interface. + +Tested-by: Aun-Ali Zaidi +Signed-off-by: Aun-Ali Zaidi +--- + drivers/media/usb/uvc/uvc_driver.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c +index 431d86e1c94b..1183b6372a14 100644 +--- a/drivers/media/usb/uvc/uvc_driver.c ++++ b/drivers/media/usb/uvc/uvc_driver.c +@@ -2908,6 +2908,15 @@ static const struct usb_device_id uvc_ids[] = { + .bInterfaceSubClass = 1, + .bInterfaceProtocol = 0, + .driver_info = UVC_INFO_META(V4L2_META_FMT_D4XX) }, ++ /* Apple Built-In iSight via iBridge */ ++ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE ++ | USB_DEVICE_ID_MATCH_INT_INFO, ++ .idVendor = 0x05ac, ++ .idProduct = 0x8514, ++ .bInterfaceClass = USB_CLASS_VIDEO, ++ .bInterfaceSubClass = 1, ++ .bInterfaceProtocol = 0, ++ .driver_info = (kernel_ulong_t)&uvc_quirk_probe_def }, + /* Generic USB Video Class */ + { USB_INTERFACE_INFO(USB_CLASS_VIDEO, 1, UVC_PC_PROTOCOL_UNDEFINED) }, + { USB_INTERFACE_INFO(USB_CLASS_VIDEO, 1, UVC_PC_PROTOCOL_15) }, +-- +2.28.0 + diff --git a/7001-drm-i915-fbdev-Discard-BIOS-framebuffers-exceeding-h.patch b/7001-drm-i915-fbdev-Discard-BIOS-framebuffers-exceeding-h.patch new file mode 100644 index 0000000..be2c366 --- /dev/null +++ b/7001-drm-i915-fbdev-Discard-BIOS-framebuffers-exceeding-h.patch @@ -0,0 +1,40 @@ +From 155bb242ee7f4e177386fbdec565db6d4a173d5e Mon Sep 17 00:00:00 2001 +From: Aun-Ali Zaidi +Date: Wed, 16 Sep 2020 18:31:10 -0500 +Subject: [PATCH] drm/i915/fbdev: Discard BIOS framebuffers exceeding hardware + supported size + +On certain devices with high-DPI panels, the BIOS supplied framebuffer is larger +than what is physically supported by the panel, resulting in overscan. A previous +check introduced with edd586fe ("drm/i915: Discard BIOS framebuffers too small to +accommodate chosen mode"), handles the lower bound case. We extend that check +to include the upper bound case. + +Signed-off-by: Aun-Ali Zaidi +--- + drivers/gpu/drm/i915/display/intel_fbdev.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/i915/display/intel_fbdev.c b/drivers/gpu/drm/i915/display/intel_fbdev.c +index bd39eb6a21b8..1949526cbe20 100644 +--- a/drivers/gpu/drm/i915/display/intel_fbdev.c ++++ b/drivers/gpu/drm/i915/display/intel_fbdev.c +@@ -181,10 +181,12 @@ static int intelfb_create(struct drm_fb_helper *helper, + int ret; + + if (intel_fb && +- (sizes->fb_width > intel_fb->base.width || +- sizes->fb_height > intel_fb->base.height)) { ++ ((sizes->fb_width > intel_fb->base.width || ++ sizes->fb_height > intel_fb->base.height) || ++ (sizes->fb_width < intel_fb->base.width || ++ sizes->fb_height < intel_fb->base.height))) { + drm_dbg_kms(&dev_priv->drm, +- "BIOS fb too small (%dx%d), we require (%dx%d)," ++ "BIOS fb invalid size (%dx%d), we require (%dx%d)," + " releasing it\n", + intel_fb->base.width, intel_fb->base.height, + sizes->fb_width, sizes->fb_height); +-- +2.28.0 + diff --git a/8001-brcmfmac-Add-initial-support-for-the-BRCM4355.patch b/8001-brcmfmac-Add-initial-support-for-the-BRCM4355.patch new file mode 100644 index 0000000..3b6bd7b --- /dev/null +++ b/8001-brcmfmac-Add-initial-support-for-the-BRCM4355.patch @@ -0,0 +1,79 @@ +From f4d7309ca1ecfa5c48a0d9429e0c56ff100a43a9 Mon Sep 17 00:00:00 2001 +From: Aun-Ali Zaidi +Date: Sun, 1 Nov 2020 01:26:38 -0400 +Subject: [PATCH 1/2] brcmfmac: Add initial support for the BRCM4355 + +This commit adds the necessary device IDs and rambase address +for the BRCM4355 Wifi/BT combo chip. + +Tested-by: Aun-Ali Zaidi +Signed-off-by: Aun-Ali Zaidi +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c | 1 + + drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c | 3 +++ + drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h | 2 ++ + 3 files changed, 6 insertions(+) + +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c +index a3a257089696..6c39415a69d6 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c +@@ -723,6 +723,7 @@ static u32 brcmf_chip_tcm_rambase(struct brcmf_chip_priv *ci) + return 0x200000; + case BRCM_CC_4359_CHIP_ID: + return (ci->pub.chiprev < 9) ? 0x180000 : 0x160000; ++ case BRCM_CC_4355_CHIP_ID: + case BRCM_CC_4364_CHIP_ID: + case CY_CC_4373_CHIP_ID: + return 0x160000; +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c +index 39381cbde89e..60e3b0ce4fd7 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c +@@ -48,6 +48,7 @@ enum brcmf_pcie_state { + BRCMF_FW_DEF(43602, "brcmfmac43602-pcie"); + BRCMF_FW_DEF(4350, "brcmfmac4350-pcie"); + BRCMF_FW_DEF(4350C, "brcmfmac4350c2-pcie"); ++BRCMF_FW_DEF(4355, "brcmfmac4355-pcie"); + BRCMF_FW_DEF(4356, "brcmfmac4356-pcie"); + BRCMF_FW_DEF(43570, "brcmfmac43570-pcie"); + BRCMF_FW_DEF(4358, "brcmfmac4358-pcie"); +@@ -65,6 +66,7 @@ static const struct brcmf_firmware_mapping brcmf_pcie_fwnames[] = { + BRCMF_FW_ENTRY(BRCM_CC_4350_CHIP_ID, 0x000000FF, 4350C), + BRCMF_FW_ENTRY(BRCM_CC_4350_CHIP_ID, 0xFFFFFF00, 4350), + BRCMF_FW_ENTRY(BRCM_CC_43525_CHIP_ID, 0xFFFFFFF0, 4365C), ++ BRCMF_FW_ENTRY(BRCM_CC_4355_CHIP_ID, 0xFFFFFFFF, 4355), + BRCMF_FW_ENTRY(BRCM_CC_4356_CHIP_ID, 0xFFFFFFFF, 4356), + BRCMF_FW_ENTRY(BRCM_CC_43567_CHIP_ID, 0xFFFFFFFF, 43570), + BRCMF_FW_ENTRY(BRCM_CC_43569_CHIP_ID, 0xFFFFFFFF, 43570), +@@ -2098,6 +2100,7 @@ static const struct pci_device_id brcmf_pcie_devid_table[] = { + BRCMF_PCIE_DEVICE(BRCM_PCIE_4350_DEVICE_ID), + BRCMF_PCIE_DEVICE_SUB(0x4355, BRCM_PCIE_VENDOR_ID_BROADCOM, 0x4355), + BRCMF_PCIE_DEVICE(BRCM_PCIE_4354_RAW_DEVICE_ID), ++ BRCMF_PCIE_DEVICE(BRCM_PCIE_4355_DEVICE_ID), + BRCMF_PCIE_DEVICE(BRCM_PCIE_4356_DEVICE_ID), + BRCMF_PCIE_DEVICE(BRCM_PCIE_43567_DEVICE_ID), + BRCMF_PCIE_DEVICE(BRCM_PCIE_43570_DEVICE_ID), +diff --git a/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h b/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h +index c6c4be05159d..777ffdbce230 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h ++++ b/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h +@@ -36,6 +36,7 @@ + #define BRCM_CC_4350_CHIP_ID 0x4350 + #define BRCM_CC_43525_CHIP_ID 43525 + #define BRCM_CC_4354_CHIP_ID 0x4354 ++#define BRCM_CC_4355_CHIP_ID 0x4355 + #define BRCM_CC_4356_CHIP_ID 0x4356 + #define BRCM_CC_43566_CHIP_ID 43566 + #define BRCM_CC_43567_CHIP_ID 43567 +@@ -66,6 +67,7 @@ + #define BRCM_PCIE_4350_DEVICE_ID 0x43a3 + #define BRCM_PCIE_4354_DEVICE_ID 0x43df + #define BRCM_PCIE_4354_RAW_DEVICE_ID 0x4354 ++#define BRCM_PCIE_4355_DEVICE_ID 0x43dc + #define BRCM_PCIE_4356_DEVICE_ID 0x43ec + #define BRCM_PCIE_43567_DEVICE_ID 0x43d3 + #define BRCM_PCIE_43570_DEVICE_ID 0x43d9 +-- +2.29.1 + diff --git a/8002-brcmfmac-Add-initial-support-for-the-BRCM4377.patch b/8002-brcmfmac-Add-initial-support-for-the-BRCM4377.patch new file mode 100644 index 0000000..825f7ee --- /dev/null +++ b/8002-brcmfmac-Add-initial-support-for-the-BRCM4377.patch @@ -0,0 +1,80 @@ +From ef2dddd7ecd61ffa5b055e1dabeba806f2de0a69 Mon Sep 17 00:00:00 2001 +From: Aun-Ali Zaidi +Date: Sun, 1 Nov 2020 01:39:09 -0400 +Subject: [PATCH 2/2] brcmfmac: Add initial support for the BRCM4377 + +This commit adds the required device IDs and rambase address +for the BRCM4377 Wifi/BT combo chip. Additional changes are +required to fully support this chip. + +Signed-off-by: Aun-Ali Zaidi +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c | 2 ++ + drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c | 3 +++ + drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h | 2 ++ + 3 files changed, 7 insertions(+) + +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c +index 6c39415a69d6..d2392a8fdbbb 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c +@@ -727,6 +727,8 @@ static u32 brcmf_chip_tcm_rambase(struct brcmf_chip_priv *ci) + case BRCM_CC_4364_CHIP_ID: + case CY_CC_4373_CHIP_ID: + return 0x160000; ++ case BRCM_CC_4377_CHIP_ID: ++ return 0x170000; + default: + brcmf_err("unknown chip: %s\n", ci->pub.name); + break; +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c +index 60e3b0ce4fd7..a262e2eb36af 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c +@@ -59,6 +59,7 @@ BRCMF_FW_DEF(4365C, "brcmfmac4365c-pcie"); + BRCMF_FW_DEF(4366B, "brcmfmac4366b-pcie"); + BRCMF_FW_DEF(4366C, "brcmfmac4366c-pcie"); + BRCMF_FW_DEF(4371, "brcmfmac4371-pcie"); ++BRCMF_FW_DEF(4377, "brcmfmac4377-pcie"); + + static const struct brcmf_firmware_mapping brcmf_pcie_fwnames[] = { + BRCMF_FW_ENTRY(BRCM_CC_43602_CHIP_ID, 0xFFFFFFFF, 43602), +@@ -80,6 +81,7 @@ static const struct brcmf_firmware_mapping brcmf_pcie_fwnames[] = { + BRCMF_FW_ENTRY(BRCM_CC_4366_CHIP_ID, 0xFFFFFFF0, 4366C), + BRCMF_FW_ENTRY(BRCM_CC_43664_CHIP_ID, 0xFFFFFFF0, 4366C), + BRCMF_FW_ENTRY(BRCM_CC_4371_CHIP_ID, 0xFFFFFFFF, 4371), ++ BRCMF_FW_ENTRY(BRCM_CC_4377_CHIP_ID, 0xFFFFFFFF, 4377), + }; + + #define BRCMF_PCIE_FW_UP_TIMEOUT 5000 /* msec */ +@@ -2119,6 +2121,7 @@ static const struct pci_device_id brcmf_pcie_devid_table[] = { + BRCMF_PCIE_DEVICE(BRCM_PCIE_4366_2G_DEVICE_ID), + BRCMF_PCIE_DEVICE(BRCM_PCIE_4366_5G_DEVICE_ID), + BRCMF_PCIE_DEVICE(BRCM_PCIE_4371_DEVICE_ID), ++ BRCMF_PCIE_DEVICE(BRCM_PCIE_4377_DEVICE_ID), + { /* end: all zeroes */ } + }; + +diff --git a/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h b/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h +index 777ffdbce230..7b50e2edf6e2 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h ++++ b/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h +@@ -50,6 +50,7 @@ + #define BRCM_CC_4366_CHIP_ID 0x4366 + #define BRCM_CC_43664_CHIP_ID 43664 + #define BRCM_CC_4371_CHIP_ID 0x4371 ++#define BRCM_CC_4377_CHIP_ID 0x4377 + #define CY_CC_4373_CHIP_ID 0x4373 + #define CY_CC_43012_CHIP_ID 43012 + +@@ -85,6 +86,7 @@ + #define BRCM_PCIE_4366_2G_DEVICE_ID 0x43c4 + #define BRCM_PCIE_4366_5G_DEVICE_ID 0x43c5 + #define BRCM_PCIE_4371_DEVICE_ID 0x440d ++#define BRCM_PCIE_4377_DEVICE_ID 0x4488 + + + /* brcmsmac IDs */ +-- +2.29.1 + diff --git a/PKGBUILD b/PKGBUILD new file mode 100644 index 0000000..9a91a41 --- /dev/null +++ b/PKGBUILD @@ -0,0 +1,265 @@ +# Maintainer: Aun-Ali Zaidi +# Contributor: Jan Alexander Steffens (heftig) + +pkgbase=linux-mbp +pkgver=5.10.12 +_srcname=linux-${pkgver} +pkgrel=1 +pkgdesc='Linux for MBP' +_srctag=v${pkgver%.*}-${pkgver##*.} +url="https://git.archlinux.org/linux.git/log/?h=v$_srctag" +arch=(x86_64) +license=(GPL2) +makedepends=( + bc kmod libelf pahole cpio perl tar xz + xmlto python-sphinx python-sphinx_rtd_theme graphviz imagemagick + git +) +options=('!strip') + +source=( + https://www.kernel.org/pub/linux/kernel/v${pkgver//.*}.x/linux-${pkgver}.tar.xz + https://www.kernel.org/pub/linux/kernel/v${pkgver//.*}.x/linux-${pkgver}.tar.sign + config # the main kernel config file + + # Arch Linux patches + 0001-ZEN-Add-sysctl-and-CONFIG-to-disallow-unprivileged-C.patch + 0002-HID-quirks-Add-Apple-Magic-Trackpad-2-to-hid_have_sp.patch + 0003-iwlwifi-provide-gso_type-to-GSO-packets.patch + + # Hack for AMD DC eDP link rate bug + 2001-drm-amd-display-Force-link_rate-as-LINK_RATE_RBR2-fo.patch + + # Apple SMC ACPI support + 3001-applesmc-convert-static-structures-to-drvdata.patch + 3002-applesmc-make-io-port-base-addr-dynamic.patch + 3003-applesmc-switch-to-acpi_device-from-platform.patch + 3004-applesmc-key-interface-wrappers.patch + 3005-applesmc-basic-mmio-interface-implementation.patch + 3006-applesmc-fan-support-on-T2-Macs.patch + + # T2 USB Keyboard/Touchpad support + 4001-HID-apple-Add-support-for-keyboard-backlight-on-supp.patch + 4002-HID-apple-Add-support-for-MacbookAir8-1-keyboard-tra.patch + 4003-HID-apple-Add-support-for-MacBookPro15-2-keyboard-tr.patch + 4004-HID-apple-Add-support-for-MacBookPro15-1-keyboard-tr.patch + 4005-HID-apple-Add-support-for-MacBookPro15-4-keyboard-tr.patch + 4006-HID-apple-Add-support-for-MacBookPro16-2-keyboard-tr.patch + 4007-HID-apple-Add-support-for-MacBookAir9-1-keyboard-tra.patch + 4008-HID-apple-Add-support-for-MacBookPro16-1-keyboard-tr.patch + + # Broadcom Wifi rambase debugging additions + #5001-brcmfmac-move-brcmf_mp_device-into-its-own-header.patch + #5002-brcmfmac-Add-ability-to-manually-specify-FW-rambase-.patch + + # MBP Peripheral support + 6001-media-uvcvideo-Add-support-for-Apple-T2-attached-iSi.patch # UVC Camera support + + # Hack for i915 overscan issues + 7001-drm-i915-fbdev-Discard-BIOS-framebuffers-exceeding-h.patch + + # Broadcom WIFI/BT device support + #8001-brcmfmac-Add-initial-support-for-the-BRCM4355.patch + #8002-brcmfmac-Add-initial-support-for-the-BRCM4377.patch + wifi-bigsur.patch +) + +validpgpkeys=( + 'ABAF11C65A2970B130ABE3C479BE3E4300411886' # Linus Torvalds + '647F28654894E3BD457199BE38DBBDC86092693E' # Greg Kroah-Hartman +) + +export KBUILD_BUILD_HOST=archlinux +export KBUILD_BUILD_USER=$pkgbase +export KBUILD_BUILD_TIMESTAMP="$(date -Ru${SOURCE_DATE_EPOCH:+d @$SOURCE_DATE_EPOCH})" + +prepare() { + cd $_srcname + + echo "Setting version..." + scripts/setlocalversion --save-scmversion + echo "-$pkgrel" > localversion.10-pkgrel + echo "${pkgbase#linux}" > localversion.20-pkgname + + local src + for src in "${source[@]}"; do + src="${src%%::*}" + src="${src##*/}" + [[ $src = *.patch ]] || continue + echo "Applying patch $src..." + patch -Np1 < "../$src" + done + + echo "Setting config..." + cp ../config .config + make olddefconfig + + make -s kernelrelease > version + echo "Prepared $pkgbase version $( +Date: Sat, 30 Jan 2021 18:23:20 -0500 +Subject: [PATCH] brcmfmac: Add support for BCM4378 on Apple hardware (with + their special OTP). + +Signed-off-by: Stan Skowronek +--- + .../broadcom/brcm80211/brcmfmac/cfg80211.c | 7 +- + .../broadcom/brcm80211/brcmfmac/chip.c | 4 + + .../broadcom/brcm80211/brcmfmac/common.c | 37 +-- + .../broadcom/brcm80211/brcmfmac/common.h | 23 +- + .../broadcom/brcm80211/brcmfmac/firmware.c | 38 ++- + .../broadcom/brcm80211/brcmfmac/p2p.c | 14 +- + .../broadcom/brcm80211/brcmfmac/pcie.c | 286 ++++++++++++++++-- + .../broadcom/brcm80211/include/brcm_hw_ids.h | 2 + + 8 files changed, 344 insertions(+), 67 deletions(-) + +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +index 0ee421f30aa24..8f7db434de111 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -5136,8 +5136,13 @@ brcmf_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, + ie_offset = DOT11_MGMT_HDR_LEN + + DOT11_BCN_PRB_FIXED_LEN; + ie_len = len - ie_offset; +- if (vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif) ++ if (vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif) { + vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif; ++ if (vif == NULL) { ++ bphy_err(drvr, "No p2p device available for probe response\n"); ++ return -ENODEV; ++ } ++ } + err = brcmf_vif_set_mgmt_ie(vif, + BRCMF_VNDR_IE_PRBRSP_FLAG, + &buf[ie_offset], +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c +index 5bf11e46fc49a..4058edddbdc23 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c +@@ -726,6 +726,8 @@ static u32 brcmf_chip_tcm_rambase(struct brcmf_chip_priv *ci) + case BRCM_CC_4364_CHIP_ID: + case CY_CC_4373_CHIP_ID: + return 0x160000; ++ case BRCM_CC_4378_CHIP_ID: ++ return 0x352000; + default: + brcmf_err("unknown chip: %s\n", ci->pub.name); + break; +@@ -1425,5 +1427,7 @@ bool brcmf_chip_sr_capable(struct brcmf_chip *pub) + reg = chip->ops->read32(chip->ctx, addr); + return (reg & (PMU_RCTL_MACPHY_DISABLE_MASK | + PMU_RCTL_LOGIC_DISABLE_MASK)) == 0; ++ case BRCM_CC_4378_CHIP_ID: ++ return false; + } + } +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c +index e3758bd86acf0..4b91a04afdc34 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c +@@ -50,11 +50,24 @@ static int brcmf_feature_disable; + module_param_named(feature_disable, brcmf_feature_disable, int, 0); + MODULE_PARM_DESC(feature_disable, "Disable features"); + +-static char brcmf_firmware_path[BRCMF_FW_ALTPATH_LEN]; ++char brcmf_firmware_path[BRCMF_FW_ALTPATH_LEN]; + module_param_string(alternative_fw_path, brcmf_firmware_path, +- BRCMF_FW_ALTPATH_LEN, 0400); ++ BRCMF_FW_ALTPATH_LEN, 0600); + MODULE_PARM_DESC(alternative_fw_path, "Alternative firmware path"); + ++char brcmf_mac_addr[18]; ++module_param_string(nvram_mac_addr, brcmf_mac_addr, ++ 18, 0600); ++MODULE_PARM_DESC(nvram_mac_addr, "Set MAC address in NVRAM"); ++ ++char brcmf_otp_chip_id[BRCMF_OTP_VERSION_MAX]; ++module_param_string(otp_chip_id, brcmf_otp_chip_id, BRCMF_OTP_VERSION_MAX, 0400); ++MODULE_PARM_DESC(otp_chip_id, "Chip ID and revision from OTP"); ++ ++char brcmf_otp_nvram_id[BRCMF_OTP_VERSION_MAX]; ++module_param_string(otp_nvram_id, brcmf_otp_nvram_id, BRCMF_OTP_VERSION_MAX, 0400); ++MODULE_PARM_DESC(otp_chip_id, "NVRAM variant from OTP"); ++ + static int brcmf_fcmode; + module_param_named(fcmode, brcmf_fcmode, int, 0); + MODULE_PARM_DESC(fcmode, "Mode of firmware signalled flow control"); +@@ -75,7 +88,6 @@ MODULE_PARM_DESC(ignore_probe_fail, "always succeed probe for debugging"); + #endif + + static struct brcmfmac_platform_data *brcmfmac_pdata; +-struct brcmf_mp_global_t brcmf_mp_global; + + void brcmf_c_set_joinpref_default(struct brcmf_if *ifp) + { +@@ -376,22 +388,6 @@ void __brcmf_dbg(u32 level, const char *func, const char *fmt, ...) + } + #endif + +-static void brcmf_mp_attach(void) +-{ +- /* If module param firmware path is set then this will always be used, +- * if not set then if available use the platform data version. To make +- * sure it gets initialized at all, always copy the module param version +- */ +- strlcpy(brcmf_mp_global.firmware_path, brcmf_firmware_path, +- BRCMF_FW_ALTPATH_LEN); +- if ((brcmfmac_pdata) && (brcmfmac_pdata->fw_alternative_path) && +- (brcmf_mp_global.firmware_path[0] == '\0')) { +- strlcpy(brcmf_mp_global.firmware_path, +- brcmfmac_pdata->fw_alternative_path, +- BRCMF_FW_ALTPATH_LEN); +- } +-} +- + struct brcmf_mp_device *brcmf_get_module_param(struct device *dev, + enum brcmf_bus_type bus_type, + u32 chip, u32 chiprev) +@@ -492,9 +488,6 @@ static int __init brcmfmac_module_init(void) + if (err == -ENODEV) + brcmf_dbg(INFO, "No platform data available.\n"); + +- /* Initialize global module paramaters */ +- brcmf_mp_attach(); +- + /* Continue the initialization by registering the different busses */ + err = brcmf_core_init(); + if (err) { +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h +index 8b5f49997c8b5..3b6ba43af4d51 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h +@@ -10,25 +10,12 @@ + #include "fwil_types.h" + + #define BRCMF_FW_ALTPATH_LEN 256 ++#define BRCMF_OTP_VERSION_MAX 64 + +-/* Definitions for the module global and device specific settings are defined +- * here. Two structs are used for them. brcmf_mp_global_t and brcmf_mp_device. +- * The mp_global is instantiated once in a global struct and gets initialized +- * by the common_attach function which should be called before any other +- * (module) initiliazation takes place. The device specific settings is part +- * of the drvr struct and should be initialized on every brcmf_attach. +- */ +- +-/** +- * struct brcmf_mp_global_t - Global module paramaters. +- * +- * @firmware_path: Alternative firmware path. +- */ +-struct brcmf_mp_global_t { +- char firmware_path[BRCMF_FW_ALTPATH_LEN]; +-}; +- +-extern struct brcmf_mp_global_t brcmf_mp_global; ++extern char brcmf_firmware_path[BRCMF_FW_ALTPATH_LEN]; ++extern char brcmf_mac_addr[18]; ++extern char brcmf_otp_chip_id[BRCMF_OTP_VERSION_MAX]; ++extern char brcmf_otp_nvram_id[BRCMF_OTP_VERSION_MAX]; + + /** + * struct brcmf_mp_device - Device module paramaters. +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c +index d821a4758f8cf..c3a05e254c851 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c +@@ -368,6 +368,35 @@ static void brcmf_fw_add_defaults(struct nvram_parser *nvp) + nvp->nvram_len++; + } + ++static void brcmf_fw_set_macaddr(struct nvram_parser *nvp, const char *mac_addr) ++{ ++ uint8_t mac[6] = { 0 }; ++ size_t len = strlen("macaddr=") + 17 + 1; /* 17 = "aa:bb:cc:dd:ee:ff" */ ++ unsigned i = 0; ++ unsigned long res = 0; ++ char tmp[3]; ++ ++ while(mac_addr[0] && mac_addr[1] && i < 6) { ++ tmp[0] = mac_addr[0]; ++ tmp[1] = mac_addr[1]; ++ tmp[2] = 0; ++ if(kstrtoul(tmp, 16, &res)) ++ break; ++ mac[i] = res; ++ mac_addr += 2; ++ i ++; ++ while(*mac_addr == ':' || *mac_addr == ' ' || *mac_addr == '-') ++ mac_addr ++; ++ } ++ if(i < 6) ++ pr_warn("invalid MAC address supplied for brcmfmac!\n"); ++ ++ memmove(&nvp->nvram[len], &nvp->nvram[0], nvp->nvram_len); ++ nvp->nvram_len += len; ++ sprintf(&nvp->nvram[0], "macaddr=%02x:%02x:%02x:%02x:%02x:%02x", ++ mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); ++} ++ + /* brcmf_nvram_strip :Takes a buffer of "=\n" lines read from a fil + * and ending in a NUL. Removes carriage returns, empty lines, comment lines, + * and converts newlines to NULs. Shortens buffer as needed and pads with NULs. +@@ -404,8 +433,11 @@ static void *brcmf_fw_nvram_strip(const u8 *data, size_t data_len, + + brcmf_fw_add_defaults(&nvp); + ++ if(brcmf_mac_addr[0]) ++ brcmf_fw_set_macaddr(&nvp, brcmf_mac_addr); ++ + pad = nvp.nvram_len; +- *new_length = roundup(nvp.nvram_len + 1, 4); ++ *new_length = roundup(nvp.nvram_len + 1, 8) + 4; + while (pad != *new_length) { + nvp.nvram[pad] = 0; + pad++; +@@ -721,7 +753,7 @@ brcmf_fw_alloc_request(u32 chip, u32 chiprev, + brcmf_info("using %s for chip %s\n", + mapping_table[i].fw_base, chipname); + +- mp_path = brcmf_mp_global.firmware_path; ++ mp_path = brcmf_firmware_path; + mp_path_len = strnlen(mp_path, BRCMF_FW_ALTPATH_LEN); + if (mp_path_len) + end = mp_path[mp_path_len - 1]; +@@ -732,7 +764,7 @@ brcmf_fw_alloc_request(u32 chip, u32 chiprev, + fwreq->items[j].path = fwnames[j].path; + fwnames[j].path[0] = '\0'; + /* check if firmware path is provided by module parameter */ +- if (brcmf_mp_global.firmware_path[0] != '\0') { ++ if (brcmf_firmware_path[0] != '\0') { + strlcpy(fwnames[j].path, mp_path, + BRCMF_FW_NAME_LEN); + +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c +index ec6fc7a150a6a..1c1d5131c3f36 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c +@@ -565,7 +565,8 @@ static s32 brcmf_p2p_deinit_discovery(struct brcmf_p2p_info *p2p) + + /* Set the discovery state to SCAN */ + vif = p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif; +- (void)brcmf_p2p_set_discover_state(vif->ifp, WL_P2P_DISC_ST_SCAN, 0, 0); ++ if (vif != NULL) ++ (void)brcmf_p2p_set_discover_state(vif->ifp, WL_P2P_DISC_ST_SCAN, 0, 0); + + /* Disable P2P discovery in the firmware */ + vif = p2p->bss_idx[P2PAPI_BSSCFG_PRIMARY].vif; +@@ -1351,6 +1352,8 @@ brcmf_p2p_gon_req_collision(struct brcmf_p2p_info *p2p, u8 *mac) + * if not (sa addr > da addr), + * this device will process gon request and drop gon req of peer. + */ ++ if(p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif == NULL) ++ return false; + ifp = p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif->ifp; + if (memcmp(mac, ifp->mac_addr, ETH_ALEN) < 0) { + brcmf_dbg(INFO, "Block transmit gon req !!!\n"); +@@ -1559,6 +1562,10 @@ static s32 brcmf_p2p_tx_action_frame(struct brcmf_p2p_info *p2p, + else + vif = p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif; + ++ if (vif == NULL) { ++ bphy_err(drvr, " no P2P interface available\n"); ++ goto exit; ++ } + err = brcmf_fil_bsscfg_data_set(vif->ifp, "actframe", af_params, + sizeof(*af_params)); + if (err) { +@@ -1734,8 +1741,11 @@ bool brcmf_p2p_send_action_frame(struct brcmf_cfg80211_info *cfg, + uint delta_ms; + unsigned long dwell_jiffies = 0; + bool dwell_overflow = false; +- + u32 requested_dwell = le32_to_cpu(af_params->dwell_time); ++ ++ if(p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif == NULL) ++ goto exit; ++ + action_frame = &af_params->action_frame; + action_frame_len = le16_to_cpu(action_frame->len); + +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c +index 45bc502fcb341..2890b24a34d1d 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c +@@ -4,6 +4,7 @@ + */ + + #include ++#include + #include + #include + #include +@@ -58,6 +59,7 @@ BRCMF_FW_DEF(4365C, "brcmfmac4365c-pcie"); + BRCMF_FW_DEF(4366B, "brcmfmac4366b-pcie"); + BRCMF_FW_DEF(4366C, "brcmfmac4366c-pcie"); + BRCMF_FW_DEF(4371, "brcmfmac4371-pcie"); ++BRCMF_FW_DEF(4378, "brcmfmac4378-pcie"); + + static const struct brcmf_firmware_mapping brcmf_pcie_fwnames[] = { + BRCMF_FW_ENTRY(BRCM_CC_43602_CHIP_ID, 0xFFFFFFFF, 43602), +@@ -78,6 +80,7 @@ static const struct brcmf_firmware_mapping brcmf_pcie_fwnames[] = { + BRCMF_FW_ENTRY(BRCM_CC_4366_CHIP_ID, 0xFFFFFFF0, 4366C), + BRCMF_FW_ENTRY(BRCM_CC_43664_CHIP_ID, 0xFFFFFFF0, 4366C), + BRCMF_FW_ENTRY(BRCM_CC_4371_CHIP_ID, 0xFFFFFFFF, 4371), ++ BRCMF_FW_ENTRY(BRCM_CC_4378_CHIP_ID, 0xFFFFFFFF, 4378), + }; + + #define BRCMF_PCIE_FW_UP_TIMEOUT 5000 /* msec */ +@@ -109,6 +112,12 @@ static const struct brcmf_firmware_mapping brcmf_pcie_fwnames[] = { + #define BRCMF_PCIE_PCIE2REG_H2D_MAILBOX_0 0x140 + #define BRCMF_PCIE_PCIE2REG_H2D_MAILBOX_1 0x144 + ++#define BRCMF_PCIE_64_PCIE2REG_INTMASK 0xC14 ++#define BRCMF_PCIE_64_PCIE2REG_MAILBOXINT 0xC30 ++#define BRCMF_PCIE_64_PCIE2REG_MAILBOXMASK 0xC34 ++#define BRCMF_PCIE_64_PCIE2REG_H2D_MAILBOX_0 0xA20 ++#define BRCMF_PCIE_64_PCIE2REG_H2D_MAILBOX_1 0xA24 ++ + #define BRCMF_PCIE2_INTA 0x01 + #define BRCMF_PCIE2_INTB 0x02 + +@@ -137,6 +146,40 @@ static const struct brcmf_firmware_mapping brcmf_pcie_fwnames[] = { + BRCMF_PCIE_MB_INT_D2H3_DB0 | \ + BRCMF_PCIE_MB_INT_D2H3_DB1) + ++#define BRCMF_PCIE_64_MB_INT_D2H0_DB0 1 ++#define BRCMF_PCIE_64_MB_INT_D2H0_DB1 2 ++#define BRCMF_PCIE_64_MB_INT_D2H1_DB0 4 ++#define BRCMF_PCIE_64_MB_INT_D2H1_DB1 8 ++#define BRCMF_PCIE_64_MB_INT_D2H2_DB0 0x10 ++#define BRCMF_PCIE_64_MB_INT_D2H2_DB1 0x20 ++#define BRCMF_PCIE_64_MB_INT_D2H3_DB0 0x40 ++#define BRCMF_PCIE_64_MB_INT_D2H3_DB1 0x80 ++#define BRCMF_PCIE_64_MB_INT_D2H4_DB0 0x100 ++#define BRCMF_PCIE_64_MB_INT_D2H4_DB1 0x200 ++#define BRCMF_PCIE_64_MB_INT_D2H5_DB0 0x400 ++#define BRCMF_PCIE_64_MB_INT_D2H5_DB1 0x800 ++#define BRCMF_PCIE_64_MB_INT_D2H6_DB0 0x1000 ++#define BRCMF_PCIE_64_MB_INT_D2H6_DB1 0x2000 ++#define BRCMF_PCIE_64_MB_INT_D2H7_DB0 0x4000 ++#define BRCMF_PCIE_64_MB_INT_D2H7_DB1 0x8000 ++ ++#define BRCMF_PCIE_64_MB_INT_D2H_DB (BRCMF_PCIE_64_MB_INT_D2H0_DB0 | \ ++ BRCMF_PCIE_64_MB_INT_D2H0_DB1 | \ ++ BRCMF_PCIE_64_MB_INT_D2H1_DB0 | \ ++ BRCMF_PCIE_64_MB_INT_D2H1_DB1 | \ ++ BRCMF_PCIE_64_MB_INT_D2H2_DB0 | \ ++ BRCMF_PCIE_64_MB_INT_D2H2_DB1 | \ ++ BRCMF_PCIE_64_MB_INT_D2H3_DB0 | \ ++ BRCMF_PCIE_64_MB_INT_D2H3_DB1 | \ ++ BRCMF_PCIE_64_MB_INT_D2H4_DB0 | \ ++ BRCMF_PCIE_64_MB_INT_D2H4_DB1 | \ ++ BRCMF_PCIE_64_MB_INT_D2H5_DB0 | \ ++ BRCMF_PCIE_64_MB_INT_D2H5_DB1 | \ ++ BRCMF_PCIE_64_MB_INT_D2H6_DB0 | \ ++ BRCMF_PCIE_64_MB_INT_D2H6_DB1 | \ ++ BRCMF_PCIE_64_MB_INT_D2H7_DB0 | \ ++ BRCMF_PCIE_64_MB_INT_D2H7_DB1) ++ + #define BRCMF_PCIE_SHARED_VERSION_7 7 + #define BRCMF_PCIE_MIN_SHARED_VERSION 5 + #define BRCMF_PCIE_MAX_SHARED_VERSION BRCMF_PCIE_SHARED_VERSION_7 +@@ -351,6 +394,15 @@ brcmf_pcie_read_reg32(struct brcmf_pciedev_info *devinfo, u32 reg_offset) + } + + ++static u16 ++brcmf_pcie_read_reg16(struct brcmf_pciedev_info *devinfo, u32 reg_offset) ++{ ++ void __iomem *address = devinfo->regs + reg_offset; ++ ++ return (ioread16(address)); ++} ++ ++ + static void + brcmf_pcie_write_reg32(struct brcmf_pciedev_info *devinfo, u32 reg_offset, + u32 value) +@@ -528,6 +580,37 @@ brcmf_pcie_copy_dev_tomem(struct brcmf_pciedev_info *devinfo, u32 mem_offset, + } + + ++static u32 ++brcmf_pcie_reg_map(struct brcmf_pciedev_info *devinfo, u32 reg) ++{ ++ switch(reg) { ++ case BRCMF_PCIE_PCIE2REG_INTMASK: ++ if(devinfo->ci->chip == BRCM_CC_4378_CHIP_ID) ++ return BRCMF_PCIE_64_PCIE2REG_INTMASK; ++ return reg; ++ case BRCMF_PCIE_PCIE2REG_MAILBOXINT: ++ if(devinfo->ci->chip == BRCM_CC_4378_CHIP_ID) ++ return BRCMF_PCIE_64_PCIE2REG_MAILBOXINT; ++ return reg; ++ case BRCMF_PCIE_PCIE2REG_MAILBOXMASK: ++ if(devinfo->ci->chip == BRCM_CC_4378_CHIP_ID) ++ return BRCMF_PCIE_64_PCIE2REG_MAILBOXMASK; ++ return reg; ++ case BRCMF_PCIE_PCIE2REG_H2D_MAILBOX_0: ++ if(devinfo->ci->chip == BRCM_CC_4378_CHIP_ID) ++ return BRCMF_PCIE_64_PCIE2REG_H2D_MAILBOX_0; ++ return reg; ++ case BRCMF_PCIE_PCIE2REG_H2D_MAILBOX_1: ++ if(devinfo->ci->chip == BRCM_CC_4378_CHIP_ID) ++ return BRCMF_PCIE_64_PCIE2REG_H2D_MAILBOX_1; ++ return reg; ++ default: ++ return reg; ++ } ++} ++ ++ ++ + #define WRITECC32(devinfo, reg, value) brcmf_pcie_write_reg32(devinfo, \ + CHIPCREGOFFS(reg), value) + +@@ -543,6 +626,7 @@ brcmf_pcie_select_core(struct brcmf_pciedev_info *devinfo, u16 coreid) + core = brcmf_chip_get_core(devinfo->ci, coreid); + if (core) { + bar0_win = core->base; ++ + pci_write_config_dword(pdev, BRCMF_PCIE_BAR0_WINDOW, bar0_win); + if (pci_read_config_dword(pdev, BRCMF_PCIE_BAR0_WINDOW, + &bar0_win) == 0) { +@@ -615,11 +699,129 @@ static void brcmf_pcie_reset_device(struct brcmf_pciedev_info *devinfo) + } + } + ++#define OTP_SIZE 64 ++#define OTP_CORE_ID BCMA_CORE_GCI ++#define OTP_CC_ADDR_4378 0x1120 ++ ++static void brcmf_pcie_process_otp_tuple(struct brcmf_pciedev_info *devinfo, u8 type, u8 size, u8 *data) ++{ ++ char tmp[OTP_SIZE], t_chiprev[8] = "", t_module[8] = "", t_modrev[8] = "", t_vendor[8] = "", t_chip[8] = ""; ++ unsigned i, len; ++ ++ switch(type) { ++ case 0x15: /* system vendor OTP */ ++ if(size < 4) ++ return; ++ if(*(u32 *)data != 8) ++ dev_warn(&devinfo->pdev->dev, "system vendor OTP header unexpected: %d\n", *(u32 *)data); ++ size -= 4; ++ data += 4; ++ while(size) { ++ if(data[0] == 0xFF) ++ break; ++ for(len=0; lenci->chip > 40000) ? "%05d" : "%04x", devinfo->ci->chip); ++ dev_info(&devinfo->pdev->dev, "module revision data: chip %s, chip rev %s, module %s, module rev %s, vendor %s\n", t_chip, t_chiprev, t_module, t_modrev, t_vendor); ++ ++ if(t_chiprev[0]) ++ sprintf(brcmf_otp_chip_id, "C-%s__s-%s", t_chip, t_chiprev); ++ else ++ sprintf(brcmf_otp_chip_id, "C-%s", t_chip); ++ sprintf(brcmf_otp_nvram_id, "M-%s_V-%s__m-%s", t_module, t_vendor, t_modrev); ++ ++ break; ++ case 0x80: /* Broadcom CIS */ ++ if(size < 1) ++ return; ++ switch(data[0]) { ++ case 0x83: /* serial number */ ++ for(i=0; i<16 && ipdev->dev, "module serial number: %s\n", tmp); ++ break; ++ } ++ break; ++ } ++} ++ ++static u32 brcmf_pcie_buscore_prep_addr(const struct pci_dev *pdev, u32 addr); ++ ++static void brcmf_pcie_read_otp(struct brcmf_pciedev_info *devinfo) ++{ ++ u8 otp[OTP_SIZE], type, size; ++ unsigned i; ++ struct brcmf_core *core; ++ u32 base; ++ ++ if (devinfo->ci->chip == BRCM_CC_4378_CHIP_ID) { ++ /* for whatever reason, reading OTP works only once after reset */ ++ if(brcmf_otp_chip_id[0]) ++ return; ++ ++ core = brcmf_chip_get_core(devinfo->ci, OTP_CORE_ID); ++ if(!core) { ++ dev_err(&devinfo->pdev->dev, "can't find core for OTP\n"); ++ return; ++ } ++ base = brcmf_pcie_buscore_prep_addr(devinfo->pdev, core->base + OTP_CC_ADDR_4378); ++ ++ for(i=0; ici->chip == BRCM_CC_4378_CHIP_ID) ++ brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_64_PCIE2REG_MAILBOXMASK, ++ BRCMF_PCIE_64_MB_INT_D2H_DB); ++ else ++ brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXMASK, ++ BRCMF_PCIE_MB_INT_D2H_DB | ++ BRCMF_PCIE_MB_INT_FN0_0 | ++ BRCMF_PCIE_MB_INT_FN0_1); + } + + static void brcmf_pcie_hostready(struct brcmf_pciedev_info *devinfo) + { + if (devinfo->shared.flags & BRCMF_PCIE_SHARED_HOSTRDY_DB1) + brcmf_pcie_write_reg32(devinfo, +- BRCMF_PCIE_PCIE2REG_H2D_MAILBOX_1, 1); ++ brcmf_pcie_reg_map(devinfo, BRCMF_PCIE_PCIE2REG_H2D_MAILBOX_1), 1); + } + + static irqreturn_t brcmf_pcie_quick_check_isr(int irq, void *arg) + { + struct brcmf_pciedev_info *devinfo = (struct brcmf_pciedev_info *)arg; + +- if (brcmf_pcie_read_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXINT)) { ++ if (brcmf_pcie_read_reg32(devinfo, brcmf_pcie_reg_map(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXINT))) { + brcmf_pcie_intr_disable(devinfo); + brcmf_dbg(PCIE, "Enter\n"); + return IRQ_WAKE_THREAD; +@@ -844,18 +1050,23 @@ static irqreturn_t brcmf_pcie_quick_check_isr(int irq, void *arg) + static irqreturn_t brcmf_pcie_isr_thread(int irq, void *arg) + { + struct brcmf_pciedev_info *devinfo = (struct brcmf_pciedev_info *)arg; +- u32 status; ++ u32 status, mask; ++ ++ if(devinfo->ci->chip == BRCM_CC_4378_CHIP_ID) ++ mask = BRCMF_PCIE_64_MB_INT_D2H_DB; ++ else ++ mask = BRCMF_PCIE_MB_INT_D2H_DB; + + devinfo->in_irq = true; +- status = brcmf_pcie_read_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXINT); ++ status = brcmf_pcie_read_reg32(devinfo, brcmf_pcie_reg_map(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXINT)); + brcmf_dbg(PCIE, "Enter %x\n", status); + if (status) { +- brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXINT, ++ brcmf_pcie_write_reg32(devinfo, brcmf_pcie_reg_map(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXINT), + status); + if (status & (BRCMF_PCIE_MB_INT_FN0_0 | + BRCMF_PCIE_MB_INT_FN0_1)) + brcmf_pcie_handle_mb_data(devinfo); +- if (status & BRCMF_PCIE_MB_INT_D2H_DB) { ++ if (status & mask) { + if (devinfo->state == BRCMFMAC_PCIE_STATE_UP) + brcmf_proto_msgbuf_rx_trigger( + &devinfo->pdev->dev); +@@ -914,8 +1125,8 @@ static void brcmf_pcie_release_irq(struct brcmf_pciedev_info *devinfo) + if (devinfo->in_irq) + brcmf_err(bus, "Still in IRQ (processing) !!!\n"); + +- status = brcmf_pcie_read_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXINT); +- brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXINT, status); ++ status = brcmf_pcie_read_reg32(devinfo, brcmf_pcie_reg_map(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXINT)); ++ brcmf_pcie_write_reg32(devinfo, brcmf_pcie_reg_map(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXINT), status); + + devinfo->irq_allocated = false; + } +@@ -967,7 +1178,7 @@ static int brcmf_pcie_ring_mb_ring_bell(void *ctx) + + brcmf_dbg(PCIE, "RING !\n"); + /* Any arbitrary value will do, lets use 1 */ +- brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_H2D_MAILBOX_0, 1); ++ brcmf_pcie_write_reg32(devinfo, brcmf_pcie_reg_map(devinfo, BRCMF_PCIE_PCIE2REG_H2D_MAILBOX_0), 1); + + return 0; + } +@@ -1543,6 +1754,8 @@ brcmf_pcie_init_share_ram_info(struct brcmf_pciedev_info *devinfo, + return 0; + } + ++#define RANDOMBYTES_SIZE 264 ++#define CLEAR_SIZE 256 + + static int brcmf_pcie_download_fw_nvram(struct brcmf_pciedev_info *devinfo, + const struct firmware *fw, void *nvram, +@@ -1553,15 +1766,16 @@ static int brcmf_pcie_download_fw_nvram(struct brcmf_pciedev_info *devinfo, + u32 sharedram_addr_written; + u32 loop_counter; + int err; +- u32 address; ++ u32 address, clraddr; + u32 resetintr; ++ uint8_t randb[RANDOMBYTES_SIZE]; + + brcmf_dbg(PCIE, "Halt ARM.\n"); + err = brcmf_pcie_enter_download_state(devinfo); + if (err) + return err; + +- brcmf_dbg(PCIE, "Download FW %s\n", devinfo->fw_name); ++ brcmf_dbg(PCIE, "Download FW %s 0x%x 0x%x\n", devinfo->fw_name, (unsigned)devinfo->ci->rambase, (unsigned)fw->size); + brcmf_pcie_copy_mem_todev(devinfo, devinfo->ci->rambase, + (void *)fw->data, fw->size); + +@@ -1574,20 +1788,38 @@ static int brcmf_pcie_download_fw_nvram(struct brcmf_pciedev_info *devinfo, + brcmf_pcie_write_ram32(devinfo, devinfo->ci->ramsize - 4, 0); + + if (nvram) { +- brcmf_dbg(PCIE, "Download NVRAM %s\n", devinfo->nvram_name); + address = devinfo->ci->rambase + devinfo->ci->ramsize - + nvram_len; ++ brcmf_dbg(PCIE, "Download NVRAM %s 0x%x 0x%x\n", devinfo->nvram_name, address, nvram_len); + brcmf_pcie_copy_mem_todev(devinfo, address, nvram, nvram_len); + brcmf_fw_nvram_free(nvram); ++ ++ address -= RANDOMBYTES_SIZE; ++ get_random_bytes(randb, RANDOMBYTES_SIZE - 8); ++ memcpy(randb + RANDOMBYTES_SIZE - 8, "\x00\x01\x00\x00\xde\xc0\xed\xfe", 8); ++ brcmf_pcie_copy_mem_todev(devinfo, address, randb, RANDOMBYTES_SIZE); + } else { + brcmf_dbg(PCIE, "No matching NVRAM file found %s\n", + devinfo->nvram_name); ++ address = devinfo->ci->rambase + devinfo->ci->ramsize; ++ } ++ ++ memset(randb, 0, CLEAR_SIZE); ++ clraddr = devinfo->ci->rambase + fw->size; ++ while(clraddr < address) { ++ u32 block = address - clraddr; ++ if(block > CLEAR_SIZE) ++ block = CLEAR_SIZE; ++ if(((clraddr + block - 1) ^ clraddr) & -CLEAR_SIZE) ++ block = (CLEAR_SIZE - clraddr) & (CLEAR_SIZE - 1); ++ brcmf_pcie_copy_mem_todev(devinfo, clraddr, randb, block); ++ clraddr += block; + } + + sharedram_addr_written = brcmf_pcie_read_ram32(devinfo, + devinfo->ci->ramsize - + 4); +- brcmf_dbg(PCIE, "Bring ARM in running state\n"); ++ brcmf_dbg(PCIE, "Bring ARM in running state (RAM sign: 0x%08x)\n", sharedram_addr_written); + err = brcmf_pcie_exit_download_state(devinfo, resetintr); + if (err) + return err; +@@ -1719,9 +1951,9 @@ static int brcmf_pcie_buscore_reset(void *ctx, struct brcmf_chip *chip) + devinfo->ci = chip; + brcmf_pcie_reset_device(devinfo); + +- val = brcmf_pcie_read_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXINT); ++ val = brcmf_pcie_read_reg32(devinfo, brcmf_pcie_reg_map(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXINT)); + if (val != 0xffffffff) +- brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXINT, ++ brcmf_pcie_write_reg32(devinfo, brcmf_pcie_reg_map(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXINT), + val); + + return 0; +@@ -1892,6 +2124,16 @@ brcmf_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id) + goto fail; + } + ++ if(devinfo->ci->chip == BRCM_CC_4378_CHIP_ID) { ++ brcmf_pcie_read_otp(devinfo); ++ ++ if(!brcmf_mac_addr[0]) { ++ dev_info(&pdev->dev, "hardware discovery complete, not starting driver\n"); ++ ret = -ENODEV; ++ goto exit; ++ } ++ } ++ + pcie_bus_dev = kzalloc(sizeof(*pcie_bus_dev), GFP_KERNEL); + if (pcie_bus_dev == NULL) { + ret = -ENOMEM; +@@ -1954,6 +2196,7 @@ brcmf_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id) + kfree(bus); + fail: + brcmf_err(NULL, "failed %x:%x\n", pdev->vendor, pdev->device); ++exit: + brcmf_pcie_release_resource(devinfo); + if (devinfo->ci) + brcmf_chip_detach(devinfo->ci); +@@ -2053,7 +2296,7 @@ static int brcmf_pcie_pm_leave_D3(struct device *dev) + brcmf_dbg(PCIE, "Enter, dev=%p, bus=%p\n", dev, bus); + + /* Check if device is still up and running, if so we are ready */ +- if (brcmf_pcie_read_reg32(devinfo, BRCMF_PCIE_PCIE2REG_INTMASK) != 0) { ++ if (brcmf_pcie_read_reg32(devinfo, brcmf_pcie_reg_map(devinfo, BRCMF_PCIE_PCIE2REG_INTMASK)) != 0) { + brcmf_dbg(PCIE, "Try to wakeup device....\n"); + if (brcmf_pcie_send_mb_data(devinfo, BRCMF_H2D_HOST_D0_INFORM)) + goto cleanup; +@@ -2119,6 +2362,7 @@ static const struct pci_device_id brcmf_pcie_devid_table[] = { + BRCMF_PCIE_DEVICE(BRCM_PCIE_4366_2G_DEVICE_ID), + BRCMF_PCIE_DEVICE(BRCM_PCIE_4366_5G_DEVICE_ID), + BRCMF_PCIE_DEVICE(BRCM_PCIE_4371_DEVICE_ID), ++ BRCMF_PCIE_DEVICE(BRCM_PCIE_4378_DEVICE_ID), + { /* end: all zeroes */ } + }; + +diff --git a/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h b/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h +index c6c4be05159d4..083cc6927417e 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h ++++ b/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h +@@ -49,6 +49,7 @@ + #define BRCM_CC_4366_CHIP_ID 0x4366 + #define BRCM_CC_43664_CHIP_ID 43664 + #define BRCM_CC_4371_CHIP_ID 0x4371 ++#define BRCM_CC_4378_CHIP_ID 0x4378 + #define CY_CC_4373_CHIP_ID 0x4373 + #define CY_CC_43012_CHIP_ID 43012 + +@@ -83,6 +84,7 @@ + #define BRCM_PCIE_4366_2G_DEVICE_ID 0x43c4 + #define BRCM_PCIE_4366_5G_DEVICE_ID 0x43c5 + #define BRCM_PCIE_4371_DEVICE_ID 0x440d ++#define BRCM_PCIE_4378_DEVICE_ID 0x4425 + + + /* brcmsmac IDs */