adding patches for 4.18.x

This commit is contained in:
Jake Day 2018-09-09 13:54:26 -04:00
parent ceee60032e
commit 83a5a5b425
8 changed files with 11012 additions and 0 deletions

1324
patches/4.18/acpi.patch Normal file

File diff suppressed because it is too large Load diff

298
patches/4.18/buttons.patch Normal file
View file

@ -0,0 +1,298 @@
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
index 2025f56446a0..97e612baa892 100644
--- a/drivers/platform/x86/Kconfig
+++ b/drivers/platform/x86/Kconfig
@@ -1158,6 +1158,11 @@ config SURFACE_3_BUTTON
---help---
This driver handles the power/home/volume buttons on the Microsoft Surface 3 tablet.
+config SURFACEBOOK2_BUTTON
+ tristate "Power/home/volume buttons driver for Microsoft Surface Book 2/ Surface Pro (2017) tablet"
+ ---help---
+ This driver handles the power and volume buttons on the Microsoft Surface Book 2/ Surface Pro (2017) tablet.
+
config ACPI_SURFACE
tristate "Microsoft Surface Extras"
depends on ACPI
diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile
index 8fd5b93bb20d..28c4cede2d91 100644
--- a/drivers/platform/x86/Makefile
+++ b/drivers/platform/x86/Makefile
@@ -81,6 +81,7 @@ obj-$(CONFIG_INTEL_PMC_IPC) += intel_pmc_ipc.o
obj-$(CONFIG_SILEAD_DMI) += silead_dmi.o
obj-$(CONFIG_SURFACE_PRO3_BUTTON) += surfacepro3_button.o
obj-$(CONFIG_SURFACE_3_BUTTON) += surface3_button.o
+obj-$(CONFIG_SURFACEBOOK2_BUTTON) += surfacebook2_button.o
obj-$(CONFIG_ACPI_SURFACE) += surface_acpi.o
obj-$(CONFIG_ACPI_SURFACE) += surface_i2c.o
obj-$(CONFIG_ACPI_SURFACE) += surface_platform.o
diff --git a/drivers/platform/x86/surfacebook2_button.c b/drivers/platform/x86/surfacebook2_button.c
new file mode 100644
index 000000000000..a6b7de595090
--- /dev/null
+++ b/drivers/platform/x86/surfacebook2_button.c
@@ -0,0 +1,242 @@
+/*
+ * Supports for Surface Book 2 and Surface Pro (2017) power and volume
+ * buttons.
+ *
+ * Based on soc_button_array.c:
+ *
+ * (C) Copyright 2014 Intel Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; version 2
+ * of the License.
+ */
+
+#include <linux/module.h>
+#include <linux/input.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/acpi.h>
+#include <linux/gpio/consumer.h>
+#include <linux/gpio_keys.h>
+#include <linux/gpio.h>
+#include <linux/platform_device.h>
+
+struct soc_button_info {
+ const char *name;
+ int acpi_index;
+ unsigned int event_type;
+ unsigned int event_code;
+ bool autorepeat;
+ bool wakeup;
+};
+
+/*
+ * Some of the buttons like volume up/down are auto repeat, while others
+ * are not. To support both, we register two platform devices, and put
+ * buttons into them based on whether the key should be auto repeat.
+ */
+#define BUTTON_TYPES 2
+#define SURFACE_METHOD_DSM "_DSM"
+
+struct soc_button_data {
+ struct platform_device *children[BUTTON_TYPES];
+};
+
+/*
+ * Get the Nth GPIO number from the ACPI object.
+ */
+static int soc_button_lookup_gpio(struct device *dev, int acpi_index)
+{
+ struct gpio_desc *desc;
+ int gpio;
+
+ desc = gpiod_get_index(dev, NULL, acpi_index, GPIOD_ASIS);
+ if (IS_ERR(desc))
+ return PTR_ERR(desc);
+
+ gpio = desc_to_gpio(desc);
+
+ gpiod_put(desc);
+
+ return gpio;
+}
+
+static struct platform_device *
+soc_button_device_create(struct platform_device *pdev,
+ const struct soc_button_info *button_info,
+ bool autorepeat)
+{
+ const struct soc_button_info *info;
+ struct platform_device *pd;
+ struct gpio_keys_button *gpio_keys;
+ struct gpio_keys_platform_data *gpio_keys_pdata;
+ int n_buttons = 0;
+ int gpio;
+ int error;
+
+ for (info = button_info; info->name; info++)
+ if (info->autorepeat == autorepeat)
+ n_buttons++;
+
+ gpio_keys_pdata = devm_kzalloc(&pdev->dev,
+ sizeof(*gpio_keys_pdata) +
+ sizeof(*gpio_keys) * n_buttons,
+ GFP_KERNEL);
+ if (!gpio_keys_pdata)
+ return ERR_PTR(-ENOMEM);
+
+ gpio_keys = (void *)(gpio_keys_pdata + 1);
+ n_buttons = 0;
+
+ for (info = button_info; info->name; info++) {
+ if (info->autorepeat != autorepeat)
+ continue;
+
+ gpio = soc_button_lookup_gpio(&pdev->dev, info->acpi_index);
+ if (!gpio_is_valid(gpio))
+ continue;
+
+ gpio_keys[n_buttons].type = info->event_type;
+ gpio_keys[n_buttons].code = info->event_code;
+ gpio_keys[n_buttons].gpio = gpio;
+ gpio_keys[n_buttons].active_low = 1;
+ gpio_keys[n_buttons].desc = info->name;
+ gpio_keys[n_buttons].wakeup = info->wakeup;
+ /* These devices often use cheap buttons, use 50 ms debounce */
+ gpio_keys[n_buttons].debounce_interval = 50;
+ n_buttons++;
+ }
+
+ if (n_buttons == 0) {
+ error = -ENODEV;
+ goto err_free_mem;
+ }
+
+ gpio_keys_pdata->buttons = gpio_keys;
+ gpio_keys_pdata->nbuttons = n_buttons;
+ gpio_keys_pdata->rep = autorepeat;
+
+ pd = platform_device_alloc("gpio-keys", PLATFORM_DEVID_AUTO);
+ if (!pd) {
+ error = -ENOMEM;
+ goto err_free_mem;
+ }
+
+ error = platform_device_add_data(pd, gpio_keys_pdata,
+ sizeof(*gpio_keys_pdata));
+ if (error)
+ goto err_free_pdev;
+
+ error = platform_device_add(pd);
+ if (error)
+ goto err_free_pdev;
+
+ return pd;
+
+err_free_pdev:
+ platform_device_put(pd);
+err_free_mem:
+ devm_kfree(&pdev->dev, gpio_keys_pdata);
+ return ERR_PTR(error);
+}
+
+static int soc_button_remove(struct platform_device *pdev)
+{
+ struct soc_button_data *priv = platform_get_drvdata(pdev);
+
+ int i;
+
+ for (i = 0; i < BUTTON_TYPES; i++)
+ if (priv->children[i])
+ platform_device_unregister(priv->children[i]);
+
+ return 0;
+}
+
+static int soc_button_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ const struct acpi_device_id *id;
+ struct soc_button_info *button_info;
+ struct soc_button_data *priv;
+ struct platform_device *pd;
+ int i;
+ int error;
+
+ id = acpi_match_device(dev->driver->acpi_match_table, dev);
+ if (!id)
+ return -ENODEV;
+
+ if (!acpi_has_method(ACPI_HANDLE(dev), SURFACE_METHOD_DSM))
+ return -ENODEV;
+
+ button_info = (struct soc_button_info *)id->driver_data;
+
+ error = gpiod_count(dev, NULL);
+ if (error < 0) {
+ dev_dbg(dev, "no GPIO attached, ignoring...\n");
+ return -ENODEV;
+ }
+
+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ platform_set_drvdata(pdev, priv);
+
+ for (i = 0; i < BUTTON_TYPES; i++) {
+ pd = soc_button_device_create(pdev, button_info, i == 0);
+ if (IS_ERR(pd)) {
+ error = PTR_ERR(pd);
+ if (error != -ENODEV) {
+ soc_button_remove(pdev);
+ return error;
+ }
+ continue;
+ }
+
+ priv->children[i] = pd;
+ }
+
+ if (!priv->children[0] && !priv->children[1])
+ return -ENODEV;
+
+ if (!id->driver_data)
+ devm_kfree(dev, button_info);
+
+ return 0;
+}
+
+/*
+ * Definition of buttons on the tablet. The ACPI index of each button
+ * is defined in section 2.8.7.2 of "Windows ACPI Design Guide for SoC
+ * Platforms"
+ */
+static struct soc_button_info soc_button_MSHW0040[] = {
+ { "power", 0, EV_KEY, KEY_POWER, false, true },
+ { "volume_up", 2, EV_KEY, KEY_VOLUMEUP, true, false },
+ { "volume_down", 4, EV_KEY, KEY_VOLUMEDOWN, true, false },
+ { }
+};
+
+static const struct acpi_device_id soc_button_acpi_match[] = {
+ { "MSHW0040", (unsigned long)soc_button_MSHW0040 },
+ { }
+};
+
+MODULE_DEVICE_TABLE(acpi, soc_button_acpi_match);
+
+static struct platform_driver soc_button_driver_sb2 = {
+ .probe = soc_button_probe,
+ .remove = soc_button_remove,
+ .driver = {
+ .name = "surfacebook2_button",
+ .acpi_match_table = ACPI_PTR(soc_button_acpi_match),
+ },
+};
+module_platform_driver(soc_button_driver_sb2);
+
+MODULE_AUTHOR("Maximilian Luz");
+MODULE_DESCRIPTION("Surface Book 2/Surface Pro (2017) Button Driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/platform/x86/surfacepro3_button.c b/drivers/platform/x86/surfacepro3_button.c
index 1b491690ce07..9385262b65be 100644
--- a/drivers/platform/x86/surfacepro3_button.c
+++ b/drivers/platform/x86/surfacepro3_button.c
@@ -22,6 +22,7 @@
#define SURFACE_PRO3_BUTTON_HID "MSHW0028"
#define SURFACE_PRO4_BUTTON_HID "MSHW0040"
#define SURFACE_BUTTON_OBJ_NAME "VGBI"
+#define SURFACE_METHOD_DSM "_DSM"
#define SURFACE_BUTTON_DEVICE_NAME "Surface Pro 3/4 Buttons"
#define SURFACE_BUTTON_NOTIFY_TABLET_MODE 0xc8
@@ -158,6 +159,9 @@ static int surface_button_add(struct acpi_device *device)
strlen(SURFACE_BUTTON_OBJ_NAME)))
return -ENODEV;
+ if (acpi_has_method(device->handle, SURFACE_METHOD_DSM))
+ return -ENODEV;
+
button = kzalloc(sizeof(struct surface_button), GFP_KERNEL);
if (!button)
return -ENOMEM;

2730
patches/4.18/cameras.patch Normal file

File diff suppressed because it is too large Load diff

6058
patches/4.18/ipts.patch Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,555 @@
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index c7981ddd8776..914a19b4290a 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -793,11 +793,21 @@
#define USB_DEVICE_ID_MS_DIGITAL_MEDIA_3KV1 0x0732
#define USB_DEVICE_ID_MS_DIGITAL_MEDIA_600 0x0750
#define USB_DEVICE_ID_MS_COMFORT_MOUSE_4500 0x076c
-#define USB_DEVICE_ID_MS_COMFORT_KEYBOARD 0x00e3
-#define USB_DEVICE_ID_MS_SURFACE_PRO_2 0x0799
-#define USB_DEVICE_ID_MS_TOUCH_COVER_2 0x07a7
-#define USB_DEVICE_ID_MS_TYPE_COVER_2 0x07a9
-#define USB_DEVICE_ID_MS_POWER_COVER 0x07da
+#define USB_DEVICE_ID_MS_COMFORT_KEYBOARD 0x00e3
+#define USB_DEVICE_ID_MS_SURFACE_PRO_2 0x0799
+#define USB_DEVICE_ID_MS_TOUCH_COVER_2 0x07a7
+#define USB_DEVICE_ID_MS_TYPE_COVER_2 0x07a9
+#define USB_DEVICE_ID_MS_TYPE_COVER_3 0x07de
+#define USB_DEVICE_ID_MS_TYPE_COVER_PRO_3 0x07dc
+#define USB_DEVICE_ID_MS_TYPE_COVER_PRO_3_1 0x07de
+#define USB_DEVICE_ID_MS_TYPE_COVER_PRO_3_2 0x07e2
+#define USB_DEVICE_ID_MS_TYPE_COVER_PRO_3_JP 0x07dd
+#define USB_DEVICE_ID_MS_TYPE_COVER_PRO_4 0x07e8
+#define USB_DEVICE_ID_MS_TYPE_COVER_PRO_4_1 0x07e4
+#define USB_DEVICE_ID_MS_SURFACE_BOOK 0x07cd
+#define USB_DEVICE_ID_MS_SURFACE_BOOK_2 0x0922
+#define USB_DEVICE_ID_MS_SURFACE_LAPTOP 0xf001
+#define USB_DEVICE_ID_MS_POWER_COVER 0x07da
#define USB_VENDOR_ID_MOJO 0x8282
#define USB_DEVICE_ID_RETRO_ADAPTER 0x3201
diff --git a/drivers/hid/hid-microsoft.c b/drivers/hid/hid-microsoft.c
index 96e7d3231d2f..e55097221eec 100644
--- a/drivers/hid/hid-microsoft.c
+++ b/drivers/hid/hid-microsoft.c
@@ -278,7 +278,8 @@ static const struct hid_device_id ms_devices[] = {
.driver_data = MS_HIDINPUT },
{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_COMFORT_KEYBOARD),
.driver_data = MS_ERGONOMY},
-
+ { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_SURFACE_LAPTOP),
+ .driver_data = MS_HIDINPUT},
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_BT),
.driver_data = MS_PRESENTER },
{ }
diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
index a0e053c4dc1c..5298793b1eaf 100644
--- a/drivers/hid/hid-multitouch.c
+++ b/drivers/hid/hid-multitouch.c
@@ -1754,6 +1754,58 @@ static const struct hid_device_id mt_devices[] = {
HID_USB_DEVICE(USB_VENDOR_ID_LG,
USB_DEVICE_ID_LG_MELFAS_MT) },
+ /* Microsoft Touch Cover */
+ { .driver_data = MT_CLS_EXPORT_ALL_INPUTS,
+ MT_USB_DEVICE(USB_VENDOR_ID_MICROSOFT,
+ USB_DEVICE_ID_MS_TOUCH_COVER_2) },
+
+ /* Microsoft Type Cover */
+ { .driver_data = MT_CLS_EXPORT_ALL_INPUTS,
+ MT_USB_DEVICE(USB_VENDOR_ID_MICROSOFT,
+ USB_DEVICE_ID_MS_TYPE_COVER_2) },
+ { .driver_data = MT_CLS_EXPORT_ALL_INPUTS,
+ MT_USB_DEVICE(USB_VENDOR_ID_MICROSOFT,
+ USB_DEVICE_ID_MS_TYPE_COVER_3) },
+ { .driver_data = MT_CLS_EXPORT_ALL_INPUTS,
+ MT_USB_DEVICE(USB_VENDOR_ID_MICROSOFT,
+ USB_DEVICE_ID_MS_TYPE_COVER_PRO_3) },
+ { .driver_data = MT_CLS_EXPORT_ALL_INPUTS,
+ MT_USB_DEVICE(USB_VENDOR_ID_MICROSOFT,
+ USB_DEVICE_ID_MS_TYPE_COVER_PRO_3_1) },
+ { .driver_data = MT_CLS_EXPORT_ALL_INPUTS,
+ MT_USB_DEVICE(USB_VENDOR_ID_MICROSOFT,
+ USB_DEVICE_ID_MS_TYPE_COVER_PRO_3_2) },
+ { .driver_data = MT_CLS_EXPORT_ALL_INPUTS,
+ MT_USB_DEVICE(USB_VENDOR_ID_MICROSOFT,
+ USB_DEVICE_ID_MS_TYPE_COVER_PRO_3_JP) },
+ { .driver_data = MT_CLS_EXPORT_ALL_INPUTS,
+ MT_USB_DEVICE(USB_VENDOR_ID_MICROSOFT,
+ USB_DEVICE_ID_MS_TYPE_COVER_PRO_4) },
+ { .driver_data = MT_CLS_EXPORT_ALL_INPUTS,
+ MT_USB_DEVICE(USB_VENDOR_ID_MICROSOFT,
+ USB_DEVICE_ID_MS_TYPE_COVER_PRO_4_1) },
+
+ /* Microsoft Surface Book */
+ { .driver_data = MT_CLS_EXPORT_ALL_INPUTS,
+ MT_USB_DEVICE(USB_VENDOR_ID_MICROSOFT,
+ USB_DEVICE_ID_MS_SURFACE_BOOK) },
+
+ /* Microsoft Surface Book 2 */
+ { .driver_data = MT_CLS_EXPORT_ALL_INPUTS,
+ MT_USB_DEVICE(USB_VENDOR_ID_MICROSOFT,
+ USB_DEVICE_ID_MS_SURFACE_BOOK_2) },
+
+ /* Microsoft Surface Laptop */
+ { .driver_data = MT_CLS_EXPORT_ALL_INPUTS,
+ HID_DEVICE(HID_BUS_ANY, HID_GROUP_ANY,
+ USB_VENDOR_ID_MICROSOFT,
+ USB_DEVICE_ID_MS_SURFACE_LAPTOP) },
+
+ /* Microsoft Power Cover */
+ { .driver_data = MT_CLS_EXPORT_ALL_INPUTS,
+ MT_USB_DEVICE(USB_VENDOR_ID_MICROSOFT,
+ USB_DEVICE_ID_MS_POWER_COVER) },
+
/* MosArt panels */
{ .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE,
MT_USB_DEVICE(USB_VENDOR_ID_ASUS,
diff --git a/drivers/hid/hid-quirks.c b/drivers/hid/hid-quirks.c
index 249d49b6b16c..28fa76011df3 100644
--- a/drivers/hid/hid-quirks.c
+++ b/drivers/hid/hid-quirks.c
@@ -111,6 +111,16 @@ static const struct hid_device_id hid_quirks[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_SURFACE_PRO_2), HID_QUIRK_NO_INIT_REPORTS },
{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TOUCH_COVER_2), HID_QUIRK_NO_INIT_REPORTS },
{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_2), HID_QUIRK_NO_INIT_REPORTS },
+ { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_3), HID_QUIRK_NO_INIT_REPORTS },
+ { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_PRO_3), HID_QUIRK_NO_INIT_REPORTS },
+ { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_PRO_3_1), HID_QUIRK_NO_INIT_REPORTS },
+ { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_PRO_3_2), HID_QUIRK_NO_INIT_REPORTS },
+ { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_PRO_3_JP), HID_QUIRK_NO_INIT_REPORTS },
+ { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_PRO_4), HID_QUIRK_NO_INIT_REPORTS },
+ { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_PRO_4_1), HID_QUIRK_NO_INIT_REPORTS },
+ { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_SURFACE_BOOK), HID_QUIRK_NO_INIT_REPORTS },
+ { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_SURFACE_BOOK_2), HID_QUIRK_NO_INIT_REPORTS },
+ { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_SURFACE_LAPTOP), HID_QUIRK_ALWAYS_POLL },
{ HID_USB_DEVICE(USB_VENDOR_ID_MOJO, USB_DEVICE_ID_RETRO_ADAPTER), HID_QUIRK_MULTI_INPUT },
{ HID_USB_DEVICE(USB_VENDOR_ID_MSI, USB_DEVICE_ID_MSI_GT683R_LED_PANEL), HID_QUIRK_NO_INIT_REPORTS },
{ HID_USB_DEVICE(USB_VENDOR_ID_MULTIPLE_1781, USB_DEVICE_ID_RAPHNET_4NES4SNES_OLD), HID_QUIRK_MULTI_INPUT },
diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile
index 28c4cede2d91..4afa91fdb4da 100644
--- a/drivers/platform/x86/Makefile
+++ b/drivers/platform/x86/Makefile
@@ -85,6 +85,8 @@ obj-$(CONFIG_SURFACEBOOK2_BUTTON) += surfacebook2_button.o
obj-$(CONFIG_ACPI_SURFACE) += surface_acpi.o
obj-$(CONFIG_ACPI_SURFACE) += surface_i2c.o
obj-$(CONFIG_ACPI_SURFACE) += surface_platform.o
+obj-$(CONFIG_ACPI_SURFACE) += surface_vhf.o
+obj-$(CONFIG_ACPI_SURFACE) += surface_vhf_keyboard.o
obj-$(CONFIG_INTEL_PUNIT_IPC) += intel_punit_ipc.o
obj-$(CONFIG_INTEL_BXTWC_PMIC_TMU) += intel_bxtwc_tmu.o
obj-$(CONFIG_INTEL_TELEMETRY) += intel_telemetry_core.o \
diff --git a/drivers/platform/x86/surface_vhf.c b/drivers/platform/x86/surface_vhf.c
new file mode 100644
index 000000000000..2e9f2a670455
--- /dev/null
+++ b/drivers/platform/x86/surface_vhf.c
@@ -0,0 +1,328 @@
+/*
+ * surface_vhf.c - Microsoft Surface Virtual HID Framework Driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * The full GNU General Public License is included in the distribution in
+ * the file called "COPYING".
+ */
+
+#include <linux/acpi.h>
+#include <linux/dmi.h>
+#include <linux/device.h>
+#include <linux/hid.h>
+#include <linux/input.h>
+#include <linux/input/sparse-keymap.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/hid-sensor-hub.h>
+#include <linux/suspend.h>
+#include <linux/clk.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/pm_wakeup.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Jake Day");
+
+#define STATUS_REG 0x0C
+#define DATA_REG 0x10
+#define DATA_AVAIL 0x2
+
+static const struct acpi_device_id surface_vhf_ids[] = {
+ {"MSHW0096", 0},
+ {"", 0},
+};
+
+struct surface_kbd {
+ struct input_dev *input;
+ struct resource *res;
+ void __iomem *io_base;
+ struct clk *clk;
+ unsigned short keycodes[256];
+};
+
+struct kbd_platform_data {
+ const struct matrix_keymap_data *keymap;
+ bool rep;
+};
+
+static const struct key_entry surface_vhf_keymap[] = {
+ { KE_KEY, 1, { KEY_ESC } },
+ { KE_KEY, 2, { KEY_F1 } },
+ { KE_KEY, 3, { KEY_F2 } },
+ { KE_KEY, 4, { KEY_F3 } },
+ { KE_KEY, 5, { KEY_F4 } },
+ { KE_KEY, 6, { KEY_F5 } },
+ { KE_KEY, 7, { KEY_F6 } },
+ { KE_KEY, 8, { KEY_F7 } },
+ { KE_KEY, 9, { KEY_F8 } },
+ { KE_KEY, 10, { KEY_F9 } },
+ { KE_KEY, 11, { KEY_F10 } },
+ { KE_KEY, 12, { KEY_F11 } },
+ { KE_KEY, 13, { KEY_F12 } },
+ { KE_KEY, 14, { KEY_POWER } },
+ { KE_KEY, 15, { KEY_DELETE } },
+ { KE_KEY, 16, { KEY_GRAVE } },
+ { KE_KEY, 17, { KEY_1 } },
+ { KE_KEY, 18, { KEY_2 } },
+ { KE_KEY, 19, { KEY_3 } },
+ { KE_KEY, 20, { KEY_4 } },
+ { KE_KEY, 21, { KEY_5 } },
+ { KE_KEY, 23, { KEY_6 } },
+ { KE_KEY, 23, { KEY_7 } },
+ { KE_KEY, 24, { KEY_8 } },
+ { KE_KEY, 25, { KEY_9 } },
+ { KE_KEY, 26, { KEY_0 } },
+ { KE_KEY, 27, { KEY_MINUS } },
+ { KE_KEY, 28, { KEY_EQUAL } },
+ { KE_KEY, 29, { KEY_BACKSPACE } },
+ { KE_KEY, 30, { KEY_TAB } },
+ { KE_KEY, 31, { KEY_Q } },
+ { KE_KEY, 32, { KEY_W } },
+ { KE_KEY, 33, { KEY_E } },
+ { KE_KEY, 34, { KEY_R } },
+ { KE_KEY, 35, { KEY_T } },
+ { KE_KEY, 36, { KEY_Y } },
+ { KE_KEY, 37, { KEY_U } },
+ { KE_KEY, 38, { KEY_I } },
+ { KE_KEY, 39, { KEY_O } },
+ { KE_KEY, 40, { KEY_P } },
+ { KE_KEY, 41, { KEY_LEFTBRACE } },
+ { KE_KEY, 42, { KEY_RIGHTBRACE } },
+ { KE_KEY, 43, { KEY_BACKSLASH } },
+ { KE_KEY, 44, { KEY_CAPSLOCK } },
+ { KE_KEY, 45, { KEY_A } },
+ { KE_KEY, 46, { KEY_S } },
+ { KE_KEY, 47, { KEY_D } },
+ { KE_KEY, 48, { KEY_F } },
+ { KE_KEY, 49, { KEY_G } },
+ { KE_KEY, 50, { KEY_H } },
+ { KE_KEY, 51, { KEY_J } },
+ { KE_KEY, 52, { KEY_K } },
+ { KE_KEY, 53, { KEY_L } },
+ { KE_KEY, 54, { KEY_SEMICOLON } },
+ { KE_KEY, 55, { KEY_APOSTROPHE } },
+ { KE_KEY, 56, { KEY_ENTER } },
+ { KE_KEY, 57, { KEY_LEFTSHIFT } },
+ { KE_KEY, 58, { KEY_Z } },
+ { KE_KEY, 59, { KEY_X } },
+ { KE_KEY, 60, { KEY_C } },
+ { KE_KEY, 61, { KEY_V } },
+ { KE_KEY, 62, { KEY_B } },
+ { KE_KEY, 63, { KEY_N } },
+ { KE_KEY, 64, { KEY_M } },
+ { KE_KEY, 65, { KEY_COMMA } },
+ { KE_KEY, 66, { KEY_DOT } },
+ { KE_KEY, 67, { KEY_SLASH } },
+ { KE_KEY, 68, { KEY_RIGHTSHIFT } },
+ { KE_KEY, 69, { KEY_LEFTCTRL } },
+ { KE_KEY, 70, { KEY_FN } },
+ { KE_KEY, 71, { KEY_KPASTERISK } },
+ { KE_KEY, 72, { KEY_LEFTALT } },
+ { KE_KEY, 73, { KEY_SPACE } },
+ { KE_KEY, 74, { KEY_RIGHTALT } },
+ { KE_KEY, 75, { KEY_MENU } },
+ { KE_KEY, 76, { KEY_LEFT } },
+ { KE_KEY, 77, { KEY_UP } },
+ { KE_KEY, 78, { KEY_DOWN } },
+ { KE_KEY, 79, { KEY_RIGHT } },
+ { KE_END },
+};
+
+
+static irqreturn_t surface_kbd_interrupt(int irq, void *dev_id)
+{
+ struct surface_kbd *kbd = dev_id;
+ struct input_dev *input = kbd->input;
+ unsigned int key;
+ u8 sts, val;
+
+ sts = readb(kbd->io_base + STATUS_REG);
+ if (!(sts & DATA_AVAIL))
+ return IRQ_NONE;
+
+ val = readb(kbd->io_base + DATA_REG);
+ key = kbd->keycodes[val];
+
+ input_event(input, EV_MSC, MSC_SCAN, val);
+ input_report_key(input, key, 1);
+ input_sync(input);
+
+ writeb(0, kbd->io_base + STATUS_REG);
+
+ return IRQ_HANDLED;
+}
+
+static int surface_vhf_probe(struct platform_device *pdev)
+{
+ struct resource *res;
+ struct surface_kbd *kbd;
+ struct input_dev *input_dev;
+ int error;
+ int ret;
+ int irq;
+
+ pr_info("Surface VHF found\n");
+
+ pr_info("Surface VHF resources: %u\n", pdev->num_resources);
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(&pdev->dev, "Surface VHF: No keyboard resource defined\n");
+ return -EBUSY;
+ }
+
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0) {
+ dev_err(&pdev->dev, "not able to get irq for the device\n");
+ return irq;
+ }
+
+ kbd = kzalloc(sizeof(*kbd), GFP_KERNEL);
+ input_dev = input_allocate_device();
+ if (!kbd || !input_dev) {
+ dev_err(&pdev->dev, "Surface VHF: Out of memory\n");
+ error = -ENOMEM;
+ goto err_free_mem;
+ }
+
+ kbd->input = input_dev;
+
+ /*kbd->res = request_mem_region(res->start, resource_size(res),
+ pdev->name);
+ if (!kbd->res) {
+ dev_err(&pdev->dev, "keyboard region already claimed\n");
+ error = -EBUSY;
+ goto err_free_mem;
+ }*/
+
+ kbd->io_base = ioremap(res->start, resource_size(res));
+ if (!kbd->io_base) {
+ dev_err(&pdev->dev, "Surface VHF: ioremap failed for kbd region\n");
+ error = -ENOMEM;
+ goto err_release_mem_region;
+ }
+
+ kbd->clk = clk_get(&pdev->dev, NULL);
+ if (IS_ERR(kbd->clk)) {
+ error = PTR_ERR(kbd->clk);
+ goto err_iounmap;
+ }
+
+ input_dev->name = "Surface Laptop Keyboard";
+ input_dev->phys = "keyboard/input0";
+ input_dev->dev.parent = &pdev->dev;
+ input_dev->id.bustype = BUS_HOST;
+ input_dev->id.vendor = 0x045e;
+ input_dev->id.product = 0xf001;
+ input_dev->id.version = 0x0001;
+
+ __set_bit(EV_KEY, input_dev->evbit);
+ input_set_capability(input_dev, EV_MSC, MSC_SCAN);
+
+ input_dev->keycode = kbd->keycodes;
+ input_dev->keycodesize = sizeof(kbd->keycodes[0]);
+ input_dev->keycodemax = ARRAY_SIZE(kbd->keycodes);
+
+ input_set_drvdata(input_dev, kbd);
+
+ ret = sparse_keymap_setup(input_dev, surface_vhf_keymap, NULL);
+ if (ret)
+ return ret;
+
+ error = request_irq(irq, surface_kbd_interrupt, 0, "keyboard", kbd);
+ if (error) {
+ dev_err(&pdev->dev, "Surface VHF: Request_irq fail\n");
+ goto err_put_clk;
+ }
+
+ error = input_register_device(input_dev);
+ if (error) {
+ dev_err(&pdev->dev, "Surface VHF: Unable to register keyboard device\n");
+ return 0;
+ }
+
+ device_init_wakeup(&pdev->dev, 1);
+ platform_set_drvdata(pdev, kbd);
+
+ return 0;
+
+/*err_free_irq:
+ free_irq(kbd->irq, kbd);*/
+err_put_clk:
+ clk_put(kbd->clk);
+err_iounmap:
+ iounmap(kbd->io_base);
+err_release_mem_region:
+ release_mem_region(res->start, resource_size(res));
+err_free_mem:
+ input_free_device(input_dev);
+ kfree(kbd);
+
+ return error;
+}
+
+static int surface_vhf_remove(struct platform_device *pdev)
+{
+ device_init_wakeup(&pdev->dev, false);
+
+ return 0;
+}
+
+static struct platform_driver surface_vhf_driver = {
+ .driver = {
+ .name = "surface_vhf",
+ .acpi_match_table = surface_vhf_ids,
+ },
+ .probe = surface_vhf_probe,
+ .remove = surface_vhf_remove,
+};
+MODULE_DEVICE_TABLE(acpi, surface_vhf_ids);
+
+static acpi_status __init
+check_acpi_dev(acpi_handle handle, u32 lvl, void *context, void **rv)
+{
+ const struct acpi_device_id *ids = context;
+ struct acpi_device *dev;
+
+ if (acpi_bus_get_device(handle, &dev) != 0)
+ return AE_OK;
+
+ if (acpi_match_device_ids(dev, ids) == 0)
+ if (acpi_create_platform_device(dev, NULL))
+ dev_info(&dev->dev,
+ "Surface VHF: Created platform device\n");
+
+ return AE_OK;
+}
+
+static int __init surface_vhf_init(void)
+{
+ acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
+ ACPI_UINT32_MAX, check_acpi_dev, NULL,
+ (void *)surface_vhf_ids, NULL);
+
+ return platform_driver_register(&surface_vhf_driver);
+}
+module_init(surface_vhf_init);
+
+static void __exit surface_vhf_exit(void)
+{
+ platform_driver_unregister(&surface_vhf_driver);
+}
+module_exit(surface_vhf_exit);
diff --git a/drivers/platform/x86/surface_vhf_keyboard.c b/drivers/platform/x86/surface_vhf_keyboard.c
new file mode 100644
index 000000000000..c619d599e4ea
--- /dev/null
+++ b/drivers/platform/x86/surface_vhf_keyboard.c
@@ -0,0 +1,73 @@
+/*
+ * surface_vhf_keyboard.c - Microsoft Surface Virtual HID Framework Keyboard Device
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * The full GNU General Public License is included in the distribution in
+ * the file called "COPYING".
+ */
+
+#include <linux/acpi.h>
+#include <linux/dmi.h>
+#include <linux/device.h>
+#include <linux/hid.h>
+#include <linux/input.h>
+#include <linux/input/sparse-keymap.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/hid-sensor-hub.h>
+#include <linux/suspend.h>
+#include <linux/clk.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/pm_wakeup.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Jake Day");
+
+static struct resource surface_vhf_keyboard_resources[] = {
+ {
+ .start = 0x1a7bbaf9,
+ .end = 0x2d356b9e,
+ .flags = IORESOURCE_MEM,
+ .name = "io-memory"
+ },
+ {
+ .start = 21,
+ .end = 21,
+ .flags = IORESOURCE_IRQ,
+ .name = "irq",
+ }
+};
+
+static struct platform_device surface_vhf_keyboard = {
+ .name = "surface_vhf",
+ .resource = surface_vhf_keyboard_resources,
+ .num_resources = ARRAY_SIZE(surface_vhf_keyboard_resources),
+};
+
+static int __init surface_hid_init(void)
+{
+ return platform_device_register(&surface_vhf_keyboard);
+}
+module_init(surface_hid_init);
+
+static void __exit surface_hid_exit(void)
+{
+ platform_device_unregister(&surface_vhf_keyboard);
+}
+module_exit(surface_hid_exit);

View file

@ -0,0 +1,14 @@
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 1fb266809966..916a323ca79f 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -4098,7 +4098,8 @@ void usb_enable_lpm(struct usb_device *udev)
if (!udev || !udev->parent ||
udev->speed < USB_SPEED_SUPER ||
!udev->lpm_capable ||
- udev->state < USB_STATE_DEFAULT)
+ udev->state < USB_STATE_DEFAULT ||
+ !udev->bos || !udev->bos->ss_cap)
return;
udev->lpm_disable_count--;

View file

@ -0,0 +1,30 @@
diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c
index 5c42cf81a08b..5eb92c3f3ea3 100644
--- a/drivers/net/usb/cdc_ether.c
+++ b/drivers/net/usb/cdc_ether.c
@@ -807,13 +807,6 @@ static const struct usb_device_id products[] = {
.driver_info = 0,
},
-/* Microsoft Surface 3 dock (based on Realtek RTL8153) */
-{
- USB_DEVICE_AND_INTERFACE_INFO(MICROSOFT_VENDOR_ID, 0x07c6, USB_CLASS_COMM,
- USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE),
- .driver_info = 0,
-},
-
/* TP-LINK UE300 USB 3.0 Ethernet Adapters (based on Realtek RTL8153) */
{
USB_DEVICE_AND_INTERFACE_INFO(TPLINK_VENDOR_ID, 0x0601, USB_CLASS_COMM,
diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index 2a58607a6aea..954220498d53 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -5323,7 +5323,6 @@ static const struct usb_device_id rtl8152_table[] = {
{REALTEK_USB_DEVICE(VENDOR_ID_REALTEK, 0x8152)},
{REALTEK_USB_DEVICE(VENDOR_ID_REALTEK, 0x8153)},
{REALTEK_USB_DEVICE(VENDOR_ID_MICROSOFT, 0x07ab)},
- {REALTEK_USB_DEVICE(VENDOR_ID_MICROSOFT, 0x07c6)},
{REALTEK_USB_DEVICE(VENDOR_ID_SAMSUNG, 0xa101)},
{REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x304f)},
{REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x3062)},

3
patches/4.18/wifi.patch Normal file
View file

@ -0,0 +1,3 @@
diff --git a/scripts/leaking_addresses.pl b/scripts/leaking_addresses.pl
old mode 100755
new mode 100644