jwboyer pushed to kernel (f22). "Add support for touchpad on Google Pixel 2 (rhbz 1209088)"
notifications at fedoraproject.org
notifications at fedoraproject.org
Fri Apr 17 15:24:44 UTC 2015
>From 6bb1eb088b9e8bca356b55be99dbb4ec62c3865d Mon Sep 17 00:00:00 2001
From: Josh Boyer <jwboyer at fedoraproject.org>
Date: Fri, 17 Apr 2015 11:24:24 -0400
Subject: Add support for touchpad on Google Pixel 2 (rhbz 1209088)
diff --git a/Input-atmel_mxt_ts-add-support-for-Google-Pixel-2.patch b/Input-atmel_mxt_ts-add-support-for-Google-Pixel-2.patch
new file mode 100644
index 0000000..2e8af33
--- /dev/null
+++ b/Input-atmel_mxt_ts-add-support-for-Google-Pixel-2.patch
@@ -0,0 +1,223 @@
+From: Dmitry Torokhov <dmitry.torokhov at gmail.com>
+Date: Tue, 7 Apr 2015 16:30:01 -0700
+Subject: [PATCH] Input: atmel_mxt_ts - add support for Google Pixel 2
+
+This change allows atmel_mxt_ts to bind to ACPI-enumerated devices in
+Google Pixel 2 (2015).
+
+While newer version of ACPI standard allow use of device-tree-like
+properties in device descriptions, the version of ACPI implemented in
+Google BIOS does not support them, and we have to resort to DMI data to
+specify exact characteristics of the devices (touchpad vs. touchscreen,
+GPIO to button mapping, etc).
+
+Pixel 1 continues to use i2c devices and platform data created by
+chromeos-laptop driver, since ACPI does not enumerate them.
+
+Reviewed-by: Javier Martinez Canillas <javier.martinez at collabora.co.uk>
+Tested-by: Javier Martinez Canillas <javier.martinez at collabora.co.uk>
+Signed-off-by: Dmitry Torokhov <dmitry.torokhov at gmail.com>
+---
+ drivers/input/touchscreen/atmel_mxt_ts.c | 141 ++++++++++++++++++++++++++++---
+ 1 file changed, 130 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
+index 2875ddf37289..40b98dda8f38 100644
+--- a/drivers/input/touchscreen/atmel_mxt_ts.c
++++ b/drivers/input/touchscreen/atmel_mxt_ts.c
+@@ -14,6 +14,8 @@
+ *
+ */
+
++#include <linux/acpi.h>
++#include <linux/dmi.h>
+ #include <linux/module.h>
+ #include <linux/init.h>
+ #include <linux/completion.h>
+@@ -2371,7 +2373,7 @@ static void mxt_input_close(struct input_dev *dev)
+ }
+
+ #ifdef CONFIG_OF
+-static struct mxt_platform_data *mxt_parse_dt(struct i2c_client *client)
++static const struct mxt_platform_data *mxt_parse_dt(struct i2c_client *client)
+ {
+ struct mxt_platform_data *pdata;
+ u32 *keymap;
+@@ -2379,7 +2381,7 @@ static struct mxt_platform_data *mxt_parse_dt(struct i2c_client *client)
+ int proplen, i, ret;
+
+ if (!client->dev.of_node)
+- return ERR_PTR(-ENODEV);
++ return ERR_PTR(-ENOENT);
+
+ pdata = devm_kzalloc(&client->dev, sizeof(*pdata), GFP_KERNEL);
+ if (!pdata)
+@@ -2410,25 +2412,132 @@ static struct mxt_platform_data *mxt_parse_dt(struct i2c_client *client)
+ return pdata;
+ }
+ #else
+-static struct mxt_platform_data *mxt_parse_dt(struct i2c_client *client)
++static const struct mxt_platform_data *mxt_parse_dt(struct i2c_client *client)
+ {
+- dev_dbg(&client->dev, "No platform data specified\n");
+- return ERR_PTR(-EINVAL);
++ return ERR_PTR(-ENOENT);
++}
++#endif
++
++#ifdef CONFIG_ACPI
++
++struct mxt_acpi_platform_data {
++ const char *hid;
++ struct mxt_platform_data pdata;
++};
++
++static unsigned int samus_touchpad_buttons[] = {
++ KEY_RESERVED,
++ KEY_RESERVED,
++ KEY_RESERVED,
++ BTN_LEFT
++};
++
++static struct mxt_acpi_platform_data samus_platform_data[] = {
++ {
++ /* Touchpad */
++ .hid = "ATML0000",
++ .pdata = {
++ .t19_num_keys = ARRAY_SIZE(samus_touchpad_buttons),
++ .t19_keymap = samus_touchpad_buttons,
++ },
++ },
++ {
++ /* Touchscreen */
++ .hid = "ATML0001",
++ },
++ { }
++};
++
++static const struct dmi_system_id mxt_dmi_table[] = {
++ {
++ /* 2015 Google Pixel */
++ .ident = "Chromebook Pixel 2",
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "GOOGLE"),
++ DMI_MATCH(DMI_PRODUCT_NAME, "Samus"),
++ },
++ .driver_data = samus_platform_data,
++ },
++ { }
++};
++
++static const struct mxt_platform_data *mxt_parse_acpi(struct i2c_client *client)
++{
++ struct acpi_device *adev;
++ const struct dmi_system_id *system_id;
++ const struct mxt_acpi_platform_data *acpi_pdata;
++
++ /*
++ * Ignore ACPI devices representing bootloader mode.
++ *
++ * This is a bit of a hack: Google Chromebook BIOS creates ACPI
++ * devices for both application and bootloader modes, but we are
++ * interested in application mode only (if device is in bootloader
++ * mode we'll end up switching into application anyway). So far
++ * application mode addresses were all above 0x40, so we'll use it
++ * as a threshold.
++ */
++ if (client->addr < 0x40)
++ return ERR_PTR(-ENXIO);
++
++ adev = ACPI_COMPANION(&client->dev);
++ if (!adev)
++ return ERR_PTR(-ENOENT);
++
++ system_id = dmi_first_match(mxt_dmi_table);
++ if (!system_id)
++ return ERR_PTR(-ENOENT);
++
++ acpi_pdata = system_id->driver_data;
++ if (!acpi_pdata)
++ return ERR_PTR(-ENOENT);
++
++ while (acpi_pdata->hid) {
++ if (!strcmp(acpi_device_hid(adev), acpi_pdata->hid))
++ return &acpi_pdata->pdata;
++
++ acpi_pdata++;
++ }
++
++ return ERR_PTR(-ENOENT);
++}
++#else
++static const struct mxt_platform_data *mxt_parse_acpi(struct i2c_client *client)
++{
++ return ERR_PTR(-ENOENT);
+ }
+ #endif
+
++static const struct mxt_platform_data *
++mxt_get_platform_data(struct i2c_client *client)
++{
++ const struct mxt_platform_data *pdata;
++
++ pdata = dev_get_platdata(&client->dev);
++ if (pdata)
++ return pdata;
++
++ pdata = mxt_parse_dt(client);
++ if (!IS_ERR(pdata) || PTR_ERR(pdata) != -ENOENT)
++ return pdata;
++
++ pdata = mxt_parse_acpi(client);
++ if (!IS_ERR(pdata) || PTR_ERR(pdata) != -ENOENT)
++ return pdata;
++
++ dev_err(&client->dev, "No platform data specified\n");
++ return ERR_PTR(-EINVAL);
++}
++
+ static int mxt_probe(struct i2c_client *client, const struct i2c_device_id *id)
+ {
+ struct mxt_data *data;
+ const struct mxt_platform_data *pdata;
+ int error;
+
+- pdata = dev_get_platdata(&client->dev);
+- if (!pdata) {
+- pdata = mxt_parse_dt(client);
+- if (IS_ERR(pdata))
+- return PTR_ERR(pdata);
+- }
++ pdata = mxt_get_platform_data(client);
++ if (IS_ERR(pdata))
++ return PTR_ERR(pdata);
+
+ data = kzalloc(sizeof(struct mxt_data), GFP_KERNEL);
+ if (!data) {
+@@ -2536,6 +2645,15 @@ static const struct of_device_id mxt_of_match[] = {
+ };
+ MODULE_DEVICE_TABLE(of, mxt_of_match);
+
++#ifdef CONFIG_ACPI
++static const struct acpi_device_id mxt_acpi_id[] = {
++ { "ATML0000", 0 }, /* Touchpad */
++ { "ATML0001", 0 }, /* Touchscreen */
++ { }
++};
++MODULE_DEVICE_TABLE(acpi, mxt_acpi_id);
++#endif
++
+ static const struct i2c_device_id mxt_id[] = {
+ { "qt602240_ts", 0 },
+ { "atmel_mxt_ts", 0 },
+@@ -2550,6 +2668,7 @@ static struct i2c_driver mxt_driver = {
+ .name = "atmel_mxt_ts",
+ .owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(mxt_of_match),
++ .acpi_match_table = ACPI_PTR(mxt_acpi_id),
+ .pm = &mxt_pm_ops,
+ },
+ .probe = mxt_probe,
+--
+2.1.0
+
diff --git a/Input-atmel_mxt_ts-implement-support-for-T100-touch-.patch b/Input-atmel_mxt_ts-implement-support-for-T100-touch-.patch
new file mode 100644
index 0000000..8dbdfb1
--- /dev/null
+++ b/Input-atmel_mxt_ts-implement-support-for-T100-touch-.patch
@@ -0,0 +1,515 @@
+From: Nick Dyer <nick.dyer at itdev.co.uk>
+Date: Mon, 6 Apr 2015 11:25:13 -0700
+Subject: [PATCH] Input: atmel_mxt_ts - implement support for T100 touch object
+
+Add support for the new T100 object which replaces the previous T9
+multitouch touchscreen object in recent maXTouch devices. T100 provides
+improved reporting with selectable auxiliary information, and a type field
+for hover/stylus/glove reporting.
+
+The hovering finger support was based on Chung-Yih's work in the ChromiumOS
+downstream kernel:
+
+https://chromium-review.googlesource.com/#/c/219280/
+
+Signed-off-by: Nick Dyer <nick.dyer at itdev.co.uk>
+Acked-by: Yufeng Shen <miletus at chromium.org>
+[javier: Factor out T9 and T100 init functions and rework hover support]
+Signed-off-by: Javier Martinez Canillas <javier.martinez at collabora.co.uk>
+Signed-off-by: Dmitry Torokhov <dmitry.torokhov at gmail.com>
+---
+ drivers/input/touchscreen/atmel_mxt_ts.c | 345 ++++++++++++++++++++++++++++---
+ 1 file changed, 318 insertions(+), 27 deletions(-)
+
+diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
+index 95ee92a91bd2..1b3b845d92f4 100644
+--- a/drivers/input/touchscreen/atmel_mxt_ts.c
++++ b/drivers/input/touchscreen/atmel_mxt_ts.c
+@@ -25,6 +25,7 @@
+ #include <linux/interrupt.h>
+ #include <linux/of.h>
+ #include <linux/slab.h>
++#include <asm/unaligned.h>
+
+ /* Version */
+ #define MXT_VER_20 20
+@@ -79,6 +80,7 @@
+ #define MXT_SPT_DIGITIZER_T43 43
+ #define MXT_SPT_MESSAGECOUNT_T44 44
+ #define MXT_SPT_CTECONFIG_T46 46
++#define MXT_TOUCH_MULTITOUCHSCREEN_T100 100
+
+ /* MXT_GEN_MESSAGE_T5 object */
+ #define MXT_RPTID_NOMSG 0xff
+@@ -185,6 +187,36 @@ struct t9_range {
+ #define MXT_RESET_VALUE 0x01
+ #define MXT_BACKUP_VALUE 0x55
+
++/* T100 Multiple Touch Touchscreen */
++#define MXT_T100_CTRL 0
++#define MXT_T100_CFG1 1
++#define MXT_T100_TCHAUX 3
++#define MXT_T100_XRANGE 13
++#define MXT_T100_YRANGE 24
++
++#define MXT_T100_CFG_SWITCHXY BIT(5)
++
++#define MXT_T100_TCHAUX_VECT BIT(0)
++#define MXT_T100_TCHAUX_AMPL BIT(1)
++#define MXT_T100_TCHAUX_AREA BIT(2)
++
++#define MXT_T100_DETECT BIT(7)
++#define MXT_T100_TYPE_MASK 0x70
++
++enum t100_type {
++ MXT_T100_TYPE_FINGER = 1,
++ MXT_T100_TYPE_PASSIVE_STYLUS = 2,
++ MXT_T100_TYPE_HOVERING_FINGER = 4,
++ MXT_T100_TYPE_GLOVE = 5,
++ MXT_T100_TYPE_LARGE_TOUCH = 6,
++};
++
++#define MXT_DISTANCE_ACTIVE_TOUCH 0
++#define MXT_DISTANCE_HOVERING 1
++
++#define MXT_TOUCH_MAJOR_DEFAULT 1
++#define MXT_PRESSURE_DEFAULT 1
++
+ /* Delay times */
+ #define MXT_BACKUP_TIME 50 /* msec */
+ #define MXT_RESET_TIME 200 /* msec */
+@@ -244,6 +276,9 @@ struct mxt_data {
+ unsigned int max_y;
+ bool in_bootloader;
+ u16 mem_size;
++ u8 t100_aux_ampl;
++ u8 t100_aux_area;
++ u8 t100_aux_vect;
+ u8 max_reportid;
+ u32 config_crc;
+ u32 info_crc;
+@@ -253,6 +288,7 @@ struct mxt_data {
+ bool update_input;
+ u8 last_message_count;
+ u8 num_touchids;
++ u8 multitouch;
+
+ /* Cached parameters from object table */
+ u16 T5_address;
+@@ -264,6 +300,8 @@ struct mxt_data {
+ u8 T9_reportid_max;
+ u8 T19_reportid;
+ u16 T44_address;
++ u8 T100_reportid_min;
++ u8 T100_reportid_max;
+
+ /* for fw update in bootloader */
+ struct completion bl_completion;
+@@ -771,6 +809,114 @@ static void mxt_proc_t9_message(struct mxt_data *data, u8 *message)
+ data->update_input = true;
+ }
+
++static void mxt_proc_t100_message(struct mxt_data *data, u8 *message)
++{
++ struct device *dev = &data->client->dev;
++ struct input_dev *input_dev = data->input_dev;
++ int id;
++ u8 status;
++ u8 type = 0;
++ u16 x;
++ u16 y;
++ int distance = 0;
++ int tool = 0;
++ u8 major = 0;
++ u8 pressure = 0;
++ u8 orientation = 0;
++
++ id = message[0] - data->T100_reportid_min - 2;
++
++ /* ignore SCRSTATUS events */
++ if (id < 0)
++ return;
++
++ status = message[1];
++ x = get_unaligned_le16(&message[2]);
++ y = get_unaligned_le16(&message[4]);
++
++ if (status & MXT_T100_DETECT) {
++ type = (status & MXT_T100_TYPE_MASK) >> 4;
++
++ switch (type) {
++ case MXT_T100_TYPE_HOVERING_FINGER:
++ tool = MT_TOOL_FINGER;
++ distance = MXT_DISTANCE_HOVERING;
++
++ if (data->t100_aux_vect)
++ orientation = message[data->t100_aux_vect];
++
++ break;
++
++ case MXT_T100_TYPE_FINGER:
++ case MXT_T100_TYPE_GLOVE:
++ tool = MT_TOOL_FINGER;
++ distance = MXT_DISTANCE_ACTIVE_TOUCH;
++
++ if (data->t100_aux_area)
++ major = message[data->t100_aux_area];
++
++ if (data->t100_aux_ampl)
++ pressure = message[data->t100_aux_ampl];
++
++ if (data->t100_aux_vect)
++ orientation = message[data->t100_aux_vect];
++
++ break;
++
++ case MXT_T100_TYPE_PASSIVE_STYLUS:
++ tool = MT_TOOL_PEN;
++
++ /*
++ * Passive stylus is reported with size zero so
++ * hardcode.
++ */
++ major = MXT_TOUCH_MAJOR_DEFAULT;
++
++ if (data->t100_aux_ampl)
++ pressure = message[data->t100_aux_ampl];
++
++ break;
++
++ case MXT_T100_TYPE_LARGE_TOUCH:
++ /* Ignore suppressed touch */
++ break;
++
++ default:
++ dev_dbg(dev, "Unexpected T100 type\n");
++ return;
++ }
++ }
++
++ /*
++ * Values reported should be non-zero if tool is touching the
++ * device
++ */
++ if (!pressure && type != MXT_T100_TYPE_HOVERING_FINGER)
++ pressure = MXT_PRESSURE_DEFAULT;
++
++ input_mt_slot(input_dev, id);
++
++ if (status & MXT_T100_DETECT) {
++ dev_dbg(dev, "[%u] type:%u x:%u y:%u a:%02X p:%02X v:%02X\n",
++ id, type, x, y, major, pressure, orientation);
++
++ input_mt_report_slot_state(input_dev, tool, 1);
++ input_report_abs(input_dev, ABS_MT_POSITION_X, x);
++ input_report_abs(input_dev, ABS_MT_POSITION_Y, y);
++ input_report_abs(input_dev, ABS_MT_TOUCH_MAJOR, major);
++ input_report_abs(input_dev, ABS_MT_PRESSURE, pressure);
++ input_report_abs(input_dev, ABS_MT_DISTANCE, distance);
++ input_report_abs(input_dev, ABS_MT_ORIENTATION, orientation);
++ } else {
++ dev_dbg(dev, "[%u] release\n", id);
++
++ /* close out slot */
++ input_mt_report_slot_state(input_dev, 0, 0);
++ }
++
++ data->update_input = true;
++}
++
+ static int mxt_proc_message(struct mxt_data *data, u8 *message)
+ {
+ u8 report_id = message[0];
+@@ -786,9 +932,12 @@ static int mxt_proc_message(struct mxt_data *data, u8 *message)
+ * is not yet registered.
+ */
+ mxt_dump_message(data, message);
+- } else if (report_id >= data->T9_reportid_min
+- && report_id <= data->T9_reportid_max) {
++ } else if (report_id >= data->T9_reportid_min &&
++ report_id <= data->T9_reportid_max) {
+ mxt_proc_t9_message(data, message);
++ } else if (report_id >= data->T100_reportid_min &&
++ report_id <= data->T100_reportid_max) {
++ mxt_proc_t100_message(data, message);
+ } else if (report_id == data->T19_reportid) {
+ mxt_input_button(data, message);
+ data->update_input = true;
+@@ -1411,6 +1560,8 @@ static void mxt_free_object_table(struct mxt_data *data)
+ data->T9_reportid_max = 0;
+ data->T19_reportid = 0;
+ data->T44_address = 0;
++ data->T100_reportid_min = 0;
++ data->T100_reportid_max = 0;
+ data->max_reportid = 0;
+ }
+
+@@ -1487,6 +1638,7 @@ static int mxt_get_object_table(struct mxt_data *data)
+ data->T7_address = object->start_address;
+ break;
+ case MXT_TOUCH_MULTI_T9:
++ data->multitouch = MXT_TOUCH_MULTI_T9;
+ data->T9_reportid_min = min_id;
+ data->T9_reportid_max = max_id;
+ data->num_touchids = object->num_report_ids
+@@ -1498,6 +1650,13 @@ static int mxt_get_object_table(struct mxt_data *data)
+ case MXT_SPT_GPIOPWM_T19:
+ data->T19_reportid = min_id;
+ break;
++ case MXT_TOUCH_MULTITOUCHSCREEN_T100:
++ data->multitouch = MXT_TOUCH_MULTITOUCHSCREEN_T100;
++ data->T100_reportid_min = min_id;
++ data->T100_reportid_max = max_id;
++ /* first two report IDs reserved */
++ data->num_touchids = object->num_report_ids - 2;
++ break;
+ }
+
+ end_address = object->start_address
+@@ -1582,10 +1741,88 @@ static int mxt_read_t9_resolution(struct mxt_data *data)
+ return 0;
+ }
+
++static int mxt_read_t100_config(struct mxt_data *data)
++{
++ struct i2c_client *client = data->client;
++ int error;
++ struct mxt_object *object;
++ u16 range_x, range_y;
++ u8 cfg, tchaux;
++ u8 aux;
++
++ object = mxt_get_object(data, MXT_TOUCH_MULTITOUCHSCREEN_T100);
++ if (!object)
++ return -EINVAL;
++
++ error = __mxt_read_reg(client,
++ object->start_address + MXT_T100_XRANGE,
++ sizeof(range_x), &range_x);
++ if (error)
++ return error;
++
++ le16_to_cpus(&range_x);
++
++ error = __mxt_read_reg(client,
++ object->start_address + MXT_T100_YRANGE,
++ sizeof(range_y), &range_y);
++ if (error)
++ return error;
++
++ le16_to_cpus(&range_y);
++
++ error = __mxt_read_reg(client,
++ object->start_address + MXT_T100_CFG1,
++ 1, &cfg);
++ if (error)
++ return error;
++
++ error = __mxt_read_reg(client,
++ object->start_address + MXT_T100_TCHAUX,
++ 1, &tchaux);
++ if (error)
++ return error;
++
++ /* Handle default values */
++ if (range_x == 0)
++ range_x = 1023;
++
++ if (range_y == 0)
++ range_y = 1023;
++
++ if (cfg & MXT_T100_CFG_SWITCHXY) {
++ data->max_x = range_y;
++ data->max_y = range_x;
++ } else {
++ data->max_x = range_x;
++ data->max_y = range_y;
++ }
++
++ /* allocate aux bytes */
++ aux = 6;
++
++ if (tchaux & MXT_T100_TCHAUX_VECT)
++ data->t100_aux_vect = aux++;
++
++ if (tchaux & MXT_T100_TCHAUX_AMPL)
++ data->t100_aux_ampl = aux++;
++
++ if (tchaux & MXT_T100_TCHAUX_AREA)
++ data->t100_aux_area = aux++;
++
++ dev_dbg(&client->dev,
++ "T100 aux mappings vect:%u ampl:%u area:%u\n",
++ data->t100_aux_vect, data->t100_aux_ampl, data->t100_aux_area);
++
++ dev_info(&client->dev,
++ "T100 Touchscreen size X%uY%u\n", data->max_x, data->max_y);
++
++ return 0;
++}
++
+ static int mxt_input_open(struct input_dev *dev);
+ static void mxt_input_close(struct input_dev *dev);
+
+-static int mxt_initialize_t9_input_device(struct mxt_data *data)
++static int mxt_initialize_input_device(struct mxt_data *data)
+ {
+ struct device *dev = &data->client->dev;
+ const struct mxt_platform_data *pdata = data->pdata;
+@@ -1595,9 +1832,25 @@ static int mxt_initialize_t9_input_device(struct mxt_data *data)
+ unsigned int mt_flags = 0;
+ int i;
+
+- error = mxt_read_t9_resolution(data);
+- if (error)
+- dev_warn(dev, "Failed to initialize T9 resolution\n");
++ switch (data->multitouch) {
++ case MXT_TOUCH_MULTI_T9:
++ num_mt_slots = data->T9_reportid_max - data->T9_reportid_min + 1;
++ error = mxt_read_t9_resolution(data);
++ if (error)
++ dev_warn(dev, "Failed to initialize T9 resolution\n");
++ break;
++
++ case MXT_TOUCH_MULTITOUCHSCREEN_T100:
++ num_mt_slots = data->num_touchids;
++ error = mxt_read_t100_config(data);
++ if (error)
++ dev_warn(dev, "Failed to read T100 config\n");
++ break;
++
++ default:
++ dev_err(dev, "Invalid multitouch object\n");
++ return -EINVAL;
++ }
+
+ input_dev = input_allocate_device();
+ if (!input_dev) {
+@@ -1612,9 +1865,7 @@ static int mxt_initialize_t9_input_device(struct mxt_data *data)
+ input_dev->open = mxt_input_open;
+ input_dev->close = mxt_input_close;
+
+- __set_bit(EV_ABS, input_dev->evbit);
+- __set_bit(EV_KEY, input_dev->evbit);
+- __set_bit(BTN_TOUCH, input_dev->keybit);
++ input_set_capability(input_dev, EV_KEY, BTN_TOUCH);
+
+ if (pdata->t19_num_keys) {
+ __set_bit(INPUT_PROP_BUTTONPAD, input_dev->propbit);
+@@ -1637,29 +1888,67 @@ static int mxt_initialize_t9_input_device(struct mxt_data *data)
+ }
+
+ /* For single touch */
+- input_set_abs_params(input_dev, ABS_X,
+- 0, data->max_x, 0, 0);
+- input_set_abs_params(input_dev, ABS_Y,
+- 0, data->max_y, 0, 0);
+- input_set_abs_params(input_dev, ABS_PRESSURE,
+- 0, 255, 0, 0);
++ input_set_abs_params(input_dev, ABS_X, 0, data->max_x, 0, 0);
++ input_set_abs_params(input_dev, ABS_Y, 0, data->max_y, 0, 0);
++
++ if (data->multitouch == MXT_TOUCH_MULTI_T9 ||
++ (data->multitouch == MXT_TOUCH_MULTITOUCHSCREEN_T100 &&
++ data->t100_aux_ampl)) {
++ input_set_abs_params(input_dev, ABS_PRESSURE, 0, 255, 0, 0);
++ }
+
+ /* For multi touch */
+- num_mt_slots = data->T9_reportid_max - data->T9_reportid_min + 1;
+ error = input_mt_init_slots(input_dev, num_mt_slots, mt_flags);
+ if (error) {
+ dev_err(dev, "Error %d initialising slots\n", error);
+ goto err_free_mem;
+ }
+
+- input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR,
+- 0, MXT_MAX_AREA, 0, 0);
++ if (data->multitouch == MXT_TOUCH_MULTITOUCHSCREEN_T100) {
++ input_set_abs_params(input_dev, ABS_MT_TOOL_TYPE,
++ 0, MT_TOOL_MAX, 0, 0);
++ input_set_abs_params(input_dev, ABS_MT_DISTANCE,
++ MXT_DISTANCE_ACTIVE_TOUCH,
++ MXT_DISTANCE_HOVERING,
++ 0, 0);
++ }
++
+ input_set_abs_params(input_dev, ABS_MT_POSITION_X,
+ 0, data->max_x, 0, 0);
+ input_set_abs_params(input_dev, ABS_MT_POSITION_Y,
+ 0, data->max_y, 0, 0);
+- input_set_abs_params(input_dev, ABS_MT_PRESSURE,
+- 0, 255, 0, 0);
++
++ if (data->multitouch == MXT_TOUCH_MULTI_T9 ||
++ (data->multitouch == MXT_TOUCH_MULTITOUCHSCREEN_T100 &&
++ data->t100_aux_area)) {
++ input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR,
++ 0, MXT_MAX_AREA, 0, 0);
++ }
++
++ if (data->multitouch == MXT_TOUCH_MULTI_T9 ||
++ (data->multitouch == MXT_TOUCH_MULTITOUCHSCREEN_T100 &&
++ data->t100_aux_ampl)) {
++ input_set_abs_params(input_dev, ABS_MT_PRESSURE,
++ 0, 255, 0, 0);
++ }
++
++ if (data->multitouch == MXT_TOUCH_MULTITOUCHSCREEN_T100 &&
++ data->t100_aux_vect) {
++ input_set_abs_params(input_dev, ABS_MT_ORIENTATION,
++ 0, 255, 0, 0);
++ }
++
++ if (data->multitouch == MXT_TOUCH_MULTITOUCHSCREEN_T100 &&
++ data->t100_aux_ampl) {
++ input_set_abs_params(input_dev, ABS_MT_PRESSURE,
++ 0, 255, 0, 0);
++ }
++
++ if (data->multitouch == MXT_TOUCH_MULTITOUCHSCREEN_T100 &&
++ data->t100_aux_vect) {
++ input_set_abs_params(input_dev, ABS_MT_ORIENTATION,
++ 0, 255, 0, 0);
++ }
+
+ input_set_drvdata(input_dev, data);
+
+@@ -1765,9 +2054,13 @@ static int mxt_configure_objects(struct mxt_data *data,
+ dev_warn(dev, "Error %d updating config\n", error);
+ }
+
+- error = mxt_initialize_t9_input_device(data);
+- if (error)
+- return error;
++ if (data->multitouch) {
++ error = mxt_initialize_input_device(data);
++ if (error)
++ return error;
++ } else {
++ dev_warn(dev, "No touch object detected\n");
++ }
+
+ dev_info(dev,
+ "Family: %u Variant: %u Firmware V%u.%u.%02X Objects: %u\n",
+@@ -2044,15 +2337,13 @@ static const struct attribute_group mxt_attr_group = {
+ static void mxt_start(struct mxt_data *data)
+ {
+ /* Touch enable */
+- mxt_write_object(data,
+- MXT_TOUCH_MULTI_T9, MXT_TOUCH_CTRL, 0x83);
++ mxt_write_object(data, data->multitouch, MXT_TOUCH_CTRL, 0x83);
+ }
+
+ static void mxt_stop(struct mxt_data *data)
+ {
+ /* Touch disable */
+- mxt_write_object(data,
+- MXT_TOUCH_MULTI_T9, MXT_TOUCH_CTRL, 0);
++ mxt_write_object(data, data->multitouch, MXT_TOUCH_CTRL, 0);
+ }
+
+ static int mxt_input_open(struct input_dev *dev)
+--
+2.1.0
+
diff --git a/Input-atmel_mxt_ts-split-out-touchpad-initialisation.patch b/Input-atmel_mxt_ts-split-out-touchpad-initialisation.patch
new file mode 100644
index 0000000..c760061
--- /dev/null
+++ b/Input-atmel_mxt_ts-split-out-touchpad-initialisation.patch
@@ -0,0 +1,103 @@
+From: Sjoerd Simons <sjoerd.simons at collabora.co.uk>
+Date: Mon, 6 Apr 2015 13:10:30 -0700
+Subject: [PATCH] Input: atmel_mxt_ts - split out touchpad initialisation logic
+
+If the "linux,gpio-keymap" DT property is defined, the T19 keys are
+configured and the device is setup as a touchpad rather than a touchscreen.
+The logic is part of the input device initialization routine but it can be
+factored out to its own function to simplify the former.
+
+Signed-off-by: Sjoerd Simons <sjoerd.simons at collabora.co.uk>
+Signed-off-by: Javier Martinez Canillas <javier.martinez at collabora.co.uk>
+Signed-off-by: Dmitry Torokhov <dmitry.torokhov at gmail.com>
+---
+ drivers/input/touchscreen/atmel_mxt_ts.c | 52 ++++++++++++++++++--------------
+ 1 file changed, 30 insertions(+), 22 deletions(-)
+
+diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
+index 1b3b845d92f4..2875ddf37289 100644
+--- a/drivers/input/touchscreen/atmel_mxt_ts.c
++++ b/drivers/input/touchscreen/atmel_mxt_ts.c
+@@ -1822,15 +1822,37 @@ static int mxt_read_t100_config(struct mxt_data *data)
+ static int mxt_input_open(struct input_dev *dev);
+ static void mxt_input_close(struct input_dev *dev);
+
++static void mxt_set_up_as_touchpad(struct input_dev *input_dev,
++ struct mxt_data *data)
++{
++ const struct mxt_platform_data *pdata = data->pdata;
++ int i;
++
++ input_dev->name = "Atmel maXTouch Touchpad";
++
++ __set_bit(INPUT_PROP_BUTTONPAD, input_dev->propbit);
++
++ input_abs_set_res(input_dev, ABS_X, MXT_PIXELS_PER_MM);
++ input_abs_set_res(input_dev, ABS_Y, MXT_PIXELS_PER_MM);
++ input_abs_set_res(input_dev, ABS_MT_POSITION_X,
++ MXT_PIXELS_PER_MM);
++ input_abs_set_res(input_dev, ABS_MT_POSITION_Y,
++ MXT_PIXELS_PER_MM);
++
++ for (i = 0; i < pdata->t19_num_keys; i++)
++ if (pdata->t19_keymap[i] != KEY_RESERVED)
++ input_set_capability(input_dev, EV_KEY,
++ pdata->t19_keymap[i]);
++}
++
+ static int mxt_initialize_input_device(struct mxt_data *data)
+ {
+- struct device *dev = &data->client->dev;
+ const struct mxt_platform_data *pdata = data->pdata;
++ struct device *dev = &data->client->dev;
+ struct input_dev *input_dev;
+ int error;
+ unsigned int num_mt_slots;
+ unsigned int mt_flags = 0;
+- int i;
+
+ switch (data->multitouch) {
+ case MXT_TOUCH_MULTI_T9:
+@@ -1867,26 +1889,6 @@ static int mxt_initialize_input_device(struct mxt_data *data)
+
+ input_set_capability(input_dev, EV_KEY, BTN_TOUCH);
+
+- if (pdata->t19_num_keys) {
+- __set_bit(INPUT_PROP_BUTTONPAD, input_dev->propbit);
+-
+- for (i = 0; i < pdata->t19_num_keys; i++)
+- if (pdata->t19_keymap[i] != KEY_RESERVED)
+- input_set_capability(input_dev, EV_KEY,
+- pdata->t19_keymap[i]);
+-
+- mt_flags |= INPUT_MT_POINTER;
+-
+- input_abs_set_res(input_dev, ABS_X, MXT_PIXELS_PER_MM);
+- input_abs_set_res(input_dev, ABS_Y, MXT_PIXELS_PER_MM);
+- input_abs_set_res(input_dev, ABS_MT_POSITION_X,
+- MXT_PIXELS_PER_MM);
+- input_abs_set_res(input_dev, ABS_MT_POSITION_Y,
+- MXT_PIXELS_PER_MM);
+-
+- input_dev->name = "Atmel maXTouch Touchpad";
+- }
+-
+ /* For single touch */
+ input_set_abs_params(input_dev, ABS_X, 0, data->max_x, 0, 0);
+ input_set_abs_params(input_dev, ABS_Y, 0, data->max_y, 0, 0);
+@@ -1897,6 +1899,12 @@ static int mxt_initialize_input_device(struct mxt_data *data)
+ input_set_abs_params(input_dev, ABS_PRESSURE, 0, 255, 0, 0);
+ }
+
++ /* If device has buttons we assume it is a touchpad */
++ if (pdata->t19_num_keys) {
++ mxt_set_up_as_touchpad(input_dev, data);
++ mt_flags |= INPUT_MT_POINTER;
++ }
++
+ /* For multi touch */
+ error = input_mt_init_slots(input_dev, num_mt_slots, mt_flags);
+ if (error) {
+--
+2.1.0
+
diff --git a/kernel.spec b/kernel.spec
index 1f3cf48..4733d6b 100644
--- a/kernel.spec
+++ b/kernel.spec
@@ -630,6 +630,11 @@ Patch26178: pty-Fix-input-race-when-closing.patch
#rhbz 1210801
Patch26179: HID-logitech-hidpp-add-a-module-parameter-to-keep-fi.patch
+#rhbz 1209088
+Patch26180: Input-atmel_mxt_ts-implement-support-for-T100-touch-.patch
+Patch26181: Input-atmel_mxt_ts-split-out-touchpad-initialisation.patch
+Patch26182: Input-atmel_mxt_ts-add-support-for-Google-Pixel-2.patch
+
# END OF PATCH DEFINITIONS
%endif
@@ -1375,6 +1380,11 @@ ApplyPatch pty-Fix-input-race-when-closing.patch
#rhbz 1210801
ApplyPatch HID-logitech-hidpp-add-a-module-parameter-to-keep-fi.patch
+#rhbz 1209088
+ApplyPatch Input-atmel_mxt_ts-implement-support-for-T100-touch-.patch
+ApplyPatch Input-atmel_mxt_ts-split-out-touchpad-initialisation.patch
+ApplyPatch Input-atmel_mxt_ts-add-support-for-Google-Pixel-2.patch
+
# END OF PATCH APPLICATIONS
%endif
@@ -2226,6 +2236,7 @@ fi
#
%changelog
* Fri Apr 17 2015 Josh Boyer <jwboyer at fedoraproject.org>
+- Add support for touchpad on Google Pixel 2 (rhbz 1209088)
- Allow disabling raw mode in logitech-hidpp (rhbz 1210801)
* Wed Apr 15 2015 Josh Boyer <jwboyer at fedoraproject.org>
--
cgit v0.10.2
http://pkgs.fedoraproject.org/cgit/kernel.git/commit/?h=f22&id=6bb1eb088b9e8bca356b55be99dbb4ec62c3865d
More information about the scm-commits
mailing list