aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHans de Goede <hdegoede@redhat.com>2017-01-23 12:35:30 -0500
committerAndy Shevchenko <andriy.shevchenko@linux.intel.com>2017-02-13 17:39:48 -0500
commitcef9dd85acd79449d1a5a65543d10f18cb68e56c (patch)
treed7f847f184b2055412645b3693f661584ef85799
parent1cfd3ba0c146a165951cedf293929a4983a45ae3 (diff)
platform/x86: add support for devices with Silead touchscreens
On ACPI based tablets, the ACPI touchscreen node only contains info on the gpio and the irq, and is missing any info on the axis. This info is expected to be built into the tablet model specific version of the driver shipped with the os-image for the device. Add support for getting the missing info from a table built into the driver, using dmi data to identify which entry of the table to use and add info for the CUBE iwork8 Air and Jumper EZpad mini3 tablets on which this code was tested / developed. BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=187531 Signed-off-by: Hans de Goede <hdegoede@redhat.com> [dmitry.torokhov@gmail.com: Move to platform/x86] Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com> Acked-by: Andy Shevchenko <andy.shevchenko@gmail.com> [andy: fixed merge conflict] Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
-rw-r--r--MAINTAINERS8
-rw-r--r--drivers/platform/x86/Kconfig11
-rw-r--r--drivers/platform/x86/Makefile1
-rw-r--r--drivers/platform/x86/silead_dmi.c136
4 files changed, 156 insertions, 0 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index 5f10c28b2e15..88cbc17d71c8 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -11271,6 +11271,14 @@ F: drivers/media/usb/siano/
11271F: drivers/media/usb/siano/ 11271F: drivers/media/usb/siano/
11272F: drivers/media/mmc/siano/ 11272F: drivers/media/mmc/siano/
11273 11273
11274SILEAD TOUCHSCREEN DRIVER
11275M: Hans de Goede <hdegoede@redhat.com>
11276L: linux-input@vger.kernel.org
11277L: platform-driver-x86@vger.kernel.org
11278S: Maintained
11279F: drivers/input/touchscreen/silead.c
11280F: drivers/platform/x86/silead_dmi.c
11281
11274SIMPLEFB FB DRIVER 11282SIMPLEFB FB DRIVER
11275M: Hans de Goede <hdegoede@redhat.com> 11283M: Hans de Goede <hdegoede@redhat.com>
11276L: linux-fbdev@vger.kernel.org 11284L: linux-fbdev@vger.kernel.org
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
index d9748a881798..cfa842daa270 100644
--- a/drivers/platform/x86/Kconfig
+++ b/drivers/platform/x86/Kconfig
@@ -1084,4 +1084,15 @@ config INTEL_TURBO_MAX_3
1084 This driver is only required when the system is not using Hardware 1084 This driver is only required when the system is not using Hardware
1085 P-States (HWP). In HWP mode, priority can be read from ACPI tables. 1085 P-States (HWP). In HWP mode, priority can be read from ACPI tables.
1086 1086
1087config SILEAD_DMI
1088 bool "Tablets with Silead touchscreens"
1089 depends on ACPI && DMI && I2C && INPUT
1090 ---help---
1091 Certain ACPI based tablets with Silead touchscreens do not have
1092 enough data in ACPI tables for the touchscreen driver to handle
1093 the touchscreen properly, as OEMs expected the data to be baked
1094 into the tablet model specific version of the driver shipped
1095 with the OS-image for the device. This option supplies the missing
1096 information. Enable this for x86 tablets with Silead touchscreens.
1097
1087endif # X86_PLATFORM_DEVICES 1098endif # X86_PLATFORM_DEVICES
diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile
index cde7b4fdf5d6..b689be13ade0 100644
--- a/drivers/platform/x86/Makefile
+++ b/drivers/platform/x86/Makefile
@@ -66,6 +66,7 @@ obj-$(CONFIG_INTEL_SMARTCONNECT) += intel-smartconnect.o
66obj-$(CONFIG_PVPANIC) += pvpanic.o 66obj-$(CONFIG_PVPANIC) += pvpanic.o
67obj-$(CONFIG_ALIENWARE_WMI) += alienware-wmi.o 67obj-$(CONFIG_ALIENWARE_WMI) += alienware-wmi.o
68obj-$(CONFIG_INTEL_PMC_IPC) += intel_pmc_ipc.o 68obj-$(CONFIG_INTEL_PMC_IPC) += intel_pmc_ipc.o
69obj-$(CONFIG_SILEAD_DMI) += silead_dmi.o
69obj-$(CONFIG_SURFACE_PRO3_BUTTON) += surfacepro3_button.o 70obj-$(CONFIG_SURFACE_PRO3_BUTTON) += surfacepro3_button.o
70obj-$(CONFIG_SURFACE_3_BUTTON) += surface3_button.o 71obj-$(CONFIG_SURFACE_3_BUTTON) += surface3_button.o
71obj-$(CONFIG_INTEL_PUNIT_IPC) += intel_punit_ipc.o 72obj-$(CONFIG_INTEL_PUNIT_IPC) += intel_punit_ipc.o
diff --git a/drivers/platform/x86/silead_dmi.c b/drivers/platform/x86/silead_dmi.c
new file mode 100644
index 000000000000..02e11fdbf375
--- /dev/null
+++ b/drivers/platform/x86/silead_dmi.c
@@ -0,0 +1,136 @@
1/*
2 * Silead touchscreen driver DMI based configuration code
3 *
4 * Copyright (c) 2017 Red Hat Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * Red Hat authors:
12 * Hans de Goede <hdegoede@redhat.com>
13 */
14
15#include <linux/acpi.h>
16#include <linux/device.h>
17#include <linux/dmi.h>
18#include <linux/i2c.h>
19#include <linux/notifier.h>
20#include <linux/property.h>
21#include <linux/string.h>
22
23struct silead_ts_dmi_data {
24 const char *acpi_name;
25 struct property_entry *properties;
26};
27
28static struct property_entry cube_iwork8_air_props[] = {
29 PROPERTY_ENTRY_U32("touchscreen-size-x", 1660),
30 PROPERTY_ENTRY_U32("touchscreen-size-y", 900),
31 PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
32 PROPERTY_ENTRY_STRING("firmware-name", "gsl3670-cube-iwork8-air.fw"),
33 PROPERTY_ENTRY_U32("silead,max-fingers", 10),
34 { }
35};
36
37static const struct silead_ts_dmi_data cube_iwork8_air_data = {
38 .acpi_name = "MSSL1680:00",
39 .properties = cube_iwork8_air_props,
40};
41
42static struct property_entry jumper_ezpad_mini3_props[] = {
43 PROPERTY_ENTRY_U32("touchscreen-size-x", 1700),
44 PROPERTY_ENTRY_U32("touchscreen-size-y", 1150),
45 PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
46 PROPERTY_ENTRY_STRING("firmware-name", "gsl3676-jumper-ezpad-mini3.fw"),
47 PROPERTY_ENTRY_U32("silead,max-fingers", 10),
48 { }
49};
50
51static const struct silead_ts_dmi_data jumper_ezpad_mini3_data = {
52 .acpi_name = "MSSL1680:00",
53 .properties = jumper_ezpad_mini3_props,
54};
55
56static const struct dmi_system_id silead_ts_dmi_table[] = {
57 {
58 /* CUBE iwork8 Air */
59 .driver_data = (void *)&cube_iwork8_air_data,
60 .matches = {
61 DMI_MATCH(DMI_SYS_VENDOR, "cube"),
62 DMI_MATCH(DMI_PRODUCT_NAME, "i1-TF"),
63 DMI_MATCH(DMI_BOARD_NAME, "Cherry Trail CR"),
64 },
65 },
66 {
67 /* Jumper EZpad mini3 */
68 .driver_data = (void *)&jumper_ezpad_mini3_data,
69 .matches = {
70 DMI_MATCH(DMI_SYS_VENDOR, "Insyde"),
71 /* jumperx.T87.KFBNEEA02 with the version-nr dropped */
72 DMI_MATCH(DMI_BIOS_VERSION, "jumperx.T87.KFBNEEA"),
73 },
74 },
75 { },
76};
77
78static void silead_ts_dmi_add_props(struct device *dev)
79{
80 struct i2c_client *client = to_i2c_client(dev);
81 const struct dmi_system_id *dmi_id;
82 const struct silead_ts_dmi_data *ts_data;
83 int error;
84
85 dmi_id = dmi_first_match(silead_ts_dmi_table);
86 if (!dmi_id)
87 return;
88
89 ts_data = dmi_id->driver_data;
90 if (has_acpi_companion(dev) &&
91 !strncmp(ts_data->acpi_name, client->name, I2C_NAME_SIZE)) {
92 error = device_add_properties(dev, ts_data->properties);
93 if (error)
94 dev_err(dev, "failed to add properties: %d\n", error);
95 }
96}
97
98static int silead_ts_dmi_notifier_call(struct notifier_block *nb,
99 unsigned long action, void *data)
100{
101 struct device *dev = data;
102
103 switch (action) {
104 case BUS_NOTIFY_ADD_DEVICE:
105 silead_ts_dmi_add_props(dev);
106 break;
107
108 default:
109 break;
110 }
111
112 return 0;
113}
114
115static struct notifier_block silead_ts_dmi_notifier = {
116 .notifier_call = silead_ts_dmi_notifier_call,
117};
118
119static int __init silead_ts_dmi_init(void)
120{
121 int error;
122
123 error = bus_register_notifier(&i2c_bus_type, &silead_ts_dmi_notifier);
124 if (error)
125 pr_err("%s: failed to register i2c bus notifier: %d\n",
126 __func__, error);
127
128 return error;
129}
130
131/*
132 * We are registering out notifier after i2c core is initialized and i2c bus
133 * itself is ready (which happens at postcore initcall level), but before
134 * ACPI starts enumerating devices (at subsys initcall level).
135 */
136arch_initcall(silead_ts_dmi_init);