2013-03-02 01:21:16

by Benson Leung

[permalink] [raw]
Subject: [PATCH 0/2] Add platform data and touchpad functionality for Pixel

Add support for an "atmel_mxt_tp" variant in the atmel_mxt_ts.c driver.
Then, add platform data for the 224s trackpad and the 1664s touchscreen
in chromeos_laptop so that the existing version of the driver will
probe these devices correctly.

[PATCH 1/2] Input: atmel_mxt_ts - add device id for touchpad variant
[PATCH 2/2] Platform: x86: chromeos_laptop : Add basic platform data


2013-03-02 01:21:21

by Benson Leung

[permalink] [raw]
Subject: [PATCH 2/2] Platform: x86: chromeos_laptop : Add basic platform data for atmel devices

Add basic platform data to get the current upstream driver working
with the 224s touchpad and 1664s touchscreen.
We will be using NULL config so we will use the settings from the
devices' NVRAMs.

Signed-off-by: Benson Leung <[email protected]>

Change-Id: I712bf4726fb4b194fbde44ad200c54d13dc3bdb9
---
drivers/platform/x86/chromeos_laptop.c | 34 ++++++++++++++++++++++++++++++++--
1 file changed, 32 insertions(+), 2 deletions(-)

diff --git a/drivers/platform/x86/chromeos_laptop.c b/drivers/platform/x86/chromeos_laptop.c
index 80b8d32..47d665b 100644
--- a/drivers/platform/x86/chromeos_laptop.c
+++ b/drivers/platform/x86/chromeos_laptop.c
@@ -23,6 +23,8 @@

#include <linux/dmi.h>
#include <linux/i2c.h>
+#include <linux/i2c/atmel_mxt_ts.h>
+#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/platform_device.h>

@@ -68,15 +70,43 @@ static struct i2c_board_info __initdata tsl2563_als_device = {
I2C_BOARD_INFO("tsl2563", TAOS_ALS_I2C_ADDR),
};

+static struct mxt_platform_data atmel_224s_tp_platform_data = {
+ .x_line = 18,
+ .y_line = 12,
+ .x_size = 102*20,
+ .y_size = 68*20,
+ .blen = 0x80, /* Gain setting is in upper 4 bits */
+ .threshold = 0x32,
+ .voltage = 0, /* 3.3V */
+ .orient = MXT_VERTICAL_FLIP,
+ .irqflags = IRQF_TRIGGER_FALLING,
+ .config = NULL,
+ .config_length = 0,
+};
+
static struct i2c_board_info __initdata atmel_224s_tp_device = {
I2C_BOARD_INFO("atmel_mxt_tp", ATMEL_TP_I2C_ADDR),
- .platform_data = NULL,
+ .platform_data = &atmel_224s_tp_platform_data,
.flags = I2C_CLIENT_WAKE,
};

+static struct mxt_platform_data atmel_1664s_platform_data = {
+ .x_line = 32,
+ .y_line = 50,
+ .x_size = 1700,
+ .y_size = 2560,
+ .blen = 0x89, /* Gain setting is in upper 4 bits */
+ .threshold = 0x28,
+ .voltage = 0, /* 3.3V */
+ .orient = MXT_ROTATED_90_COUNTER,
+ .irqflags = IRQF_TRIGGER_FALLING,
+ .config = NULL,
+ .config_length = 0,
+};
+
static struct i2c_board_info __initdata atmel_1664s_device = {
I2C_BOARD_INFO("atmel_mxt_ts", ATMEL_TS_I2C_ADDR),
- .platform_data = NULL,
+ .platform_data = &atmel_1664s_platform_data,
.flags = I2C_CLIENT_WAKE,
};

--
1.8.1.3

2013-03-02 01:21:36

by Benson Leung

[permalink] [raw]
Subject: [PATCH 1/2] Input: atmel_mxt_ts - add device id for touchpad variant

From: Daniel Kurtz <[email protected]>

This same driver can be used by atmel based touchscreens and touchpads
(buttonpads) by instantiating the i2c device as a "atmel_mxt_tp".

This will cause the driver to perform some touchpad specific
initializations, such as:
* register input device name "Atmel maXTouch Touchpad" instead of
Touchscreen.
* register BTN_LEFT & BTN_TOOL_* event types.
* register axis resolution (as a fixed constant, for now)
* register BUTTONPAD property
* process GPIO buttons using reportid T19

For now, the left mouse button is mapped to GPIO3. Going forward,
platform data should specify the configuration of the buttons.
They can be configured via a future platform data change to
specify optional middle and right buttons, as well as other possible
uses for the GPIO object T19.

Signed-off-by: Daniel Kurtz <[email protected]>
Signed-off-by: Benson Leung <[email protected]>

Change-Id: Ia82e75d85111c94f6c3fb423181df0fa4b964fc4
---
drivers/input/touchscreen/atmel_mxt_ts.c | 55 +++++++++++++++++++++++++++++++-
1 file changed, 54 insertions(+), 1 deletion(-)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
index d04f810..66745b9 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -181,6 +181,12 @@

#define MXT_FWRESET_TIME 175 /* msec */

+/* MXT_SPT_GPIOPWM_T19 field */
+#define MXT_GPIO0_MASK 0x04
+#define MXT_GPIO1_MASK 0x08
+#define MXT_GPIO2_MASK 0x10
+#define MXT_GPIO3_MASK 0x20
+
/* Command to unlock bootloader */
#define MXT_UNLOCK_CMD_MSB 0xaa
#define MXT_UNLOCK_CMD_LSB 0xdc
@@ -212,6 +218,8 @@
/* Touchscreen absolute values */
#define MXT_MAX_AREA 0xff

+#define MXT_PIXELS_PER_MM 20
+
struct mxt_info {
u8 family_id;
u8 variant_id;
@@ -243,6 +251,8 @@ struct mxt_data {
const struct mxt_platform_data *pdata;
struct mxt_object *object_table;
struct mxt_info info;
+ bool is_tp;
+
unsigned int irq;
unsigned int max_x;
unsigned int max_y;
@@ -251,6 +261,7 @@ struct mxt_data {
u8 T6_reportid;
u8 T9_reportid_min;
u8 T9_reportid_max;
+ u8 T19_reportid;
};

static bool mxt_object_readable(unsigned int type)
@@ -502,6 +513,18 @@ static int mxt_write_object(struct mxt_data *data,
return mxt_write_reg(data->client, reg + offset, val);
}

+static void mxt_input_button(struct mxt_data *data, struct mxt_message *message)
+{
+ struct device *dev = &data->client->dev;
+ struct input_dev *input = data->input_dev;
+ bool button;
+
+ /* Active-low switch */
+ button = !(message->message[0] & MXT_GPIO3_MASK);
+ input_report_key(input, BTN_LEFT, button);
+ dev_dbg(dev, "Button state: %d\n", button);
+}
+
static void mxt_input_touchevent(struct mxt_data *data,
struct mxt_message *message, int id)
{
@@ -585,6 +608,9 @@ static irqreturn_t mxt_interrupt(int irq, void *dev_id)
int id = reportid - data->T9_reportid_min;
mxt_input_touchevent(data, &message, id);
update_input = true;
+ } else if (message.reportid == data->T19_reportid) {
+ mxt_input_button(data, &message);
+ update_input = true;
} else {
mxt_dump_message(dev, &message);
}
@@ -764,6 +790,9 @@ static int mxt_get_object_table(struct mxt_data *data)
data->T9_reportid_min = min_id;
data->T9_reportid_max = max_id;
break;
+ case MXT_SPT_GPIOPWM_T19:
+ data->T19_reportid = min_id;
+ break;
}
}

@@ -1115,9 +1144,13 @@ static int mxt_probe(struct i2c_client *client,
goto err_free_mem;
}

- input_dev->name = "Atmel maXTouch Touchscreen";
+ data->is_tp = !strcmp(id->name, "atmel_mxt_tp");
+
+ input_dev->name = (data->is_tp) ? "Atmel maXTouch Touchpad" :
+ "Atmel maXTouch Touchscreen";
snprintf(data->phys, sizeof(data->phys), "i2c-%u-%04x/input0",
client->adapter->nr, client->addr);
+
input_dev->phys = data->phys;

input_dev->id.bustype = BUS_I2C;
@@ -1140,6 +1173,25 @@ static int mxt_probe(struct i2c_client *client,
__set_bit(EV_KEY, input_dev->evbit);
__set_bit(BTN_TOUCH, input_dev->keybit);

+ if (data->is_tp) {
+ __set_bit(INPUT_PROP_POINTER, input_dev->propbit);
+ __set_bit(INPUT_PROP_BUTTONPAD, input_dev->propbit);
+
+ __set_bit(BTN_LEFT, input_dev->keybit);
+ __set_bit(BTN_TOOL_FINGER, input_dev->keybit);
+ __set_bit(BTN_TOOL_DOUBLETAP, input_dev->keybit);
+ __set_bit(BTN_TOOL_TRIPLETAP, input_dev->keybit);
+ __set_bit(BTN_TOOL_QUADTAP, input_dev->keybit);
+ __set_bit(BTN_TOOL_QUINTTAP, input_dev->keybit);
+
+ 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 single touch */
input_set_abs_params(input_dev, ABS_X,
0, data->max_x, 0, 0);
@@ -1258,6 +1310,7 @@ static SIMPLE_DEV_PM_OPS(mxt_pm_ops, mxt_suspend, mxt_resume);
static const struct i2c_device_id mxt_id[] = {
{ "qt602240_ts", 0 },
{ "atmel_mxt_ts", 0 },
+ { "atmel_mxt_tp", 0 },
{ "mXT224", 0 },
{ }
};
--
1.8.1.3

2013-03-02 03:57:38

by Olof Johansson

[permalink] [raw]
Subject: Re: [PATCH 1/2] Input: atmel_mxt_ts - add device id for touchpad variant

(sorry for duplicate post to some of you, my mail client defaulted to
HTML email for some reason).


2013/3/1 Benson Leung <[email protected]>
>
> From: Daniel Kurtz <[email protected]>
>
> This same driver can be used by atmel based touchscreens and touchpads
> (buttonpads) by instantiating the i2c device as a "atmel_mxt_tp".
>
> This will cause the driver to perform some touchpad specific
> initializations, such as:
> * register input device name "Atmel maXTouch Touchpad" instead of
> Touchscreen.
> * register BTN_LEFT & BTN_TOOL_* event types.
> * register axis resolution (as a fixed constant, for now)
> * register BUTTONPAD property
> * process GPIO buttons using reportid T19
>
> For now, the left mouse button is mapped to GPIO3. Going forward,
> platform data should specify the configuration of the buttons.
> They can be configured via a future platform data change to
> specify optional middle and right buttons, as well as other possible
> uses for the GPIO object T19.
>
> Signed-off-by: Daniel Kurtz <[email protected]>
> Signed-off-by: Benson Leung <[email protected]>
>
> Change-Id: Ia82e75d85111c94f6c3fb423181df0fa4b964fc4

Please remember to remove Change-Id on future patch postings.

Tested with native Linux Mint +mainline kernel earlier today, so:

Tested-by: Olof Johansson <[email protected]>

2013-03-02 04:00:13

by Olof Johansson

[permalink] [raw]
Subject: Re: [PATCH 2/2] Platform: x86: chromeos_laptop : Add basic platform data for atmel devices

2013/3/1 Benson Leung <[email protected]>:
> Add basic platform data to get the current upstream driver working
> with the 224s touchpad and 1664s touchscreen.
> We will be using NULL config so we will use the settings from the
> devices' NVRAMs.
>
> Signed-off-by: Benson Leung <[email protected]>
>
> Change-Id: I712bf4726fb4b194fbde44ad200c54d13dc3bdb9

Same thing, please remove Change-Id.

I've tested this patch, and had issues getting touchscreen to work.
Seems to be a driver-side issue, so this patch is still valid.

There was also some flakiness with the touchpad device going
unresponsive after some time that needs to be debugged. Again, driver
side.

With those caveats:

Tested-by: Olof Johansson <[email protected]>


-Olof

2013-03-06 07:42:00

by Benson Leung

[permalink] [raw]
Subject: [PATCH v2 0/2] Add platform data and touchpad functionality for Pixel

Add support for an "atmel_mxt_tp" variant in the atmel_mxt_ts.c driver.
Then, add platform data for the 224s trackpad and the 1664s touchscreen
in chromeos_laptop so that the existing version of the driver will
probe these devices correctly.

v2 : Minor bugfix in patch 1. Cleanup client_id from commit message.
Make sure chromeos_laptop patch applies cleanly to v3.9-rc1

[PATCH v2 1/2] Input: atmel_mxt_ts - add device id for touchpad variant
[PATCH v2 2/2] Platform: x86: chromeos_laptop : Add basic platform data

2013-03-06 07:42:11

by Benson Leung

[permalink] [raw]
Subject: [PATCH v2 1/2] Input: atmel_mxt_ts - add device id for touchpad variant

From: Daniel Kurtz <[email protected]>

This same driver can be used by atmel based touchscreens and touchpads
(buttonpads) by instantiating the i2c device as a "atmel_mxt_tp".

This will cause the driver to perform some touchpad specific
initializations, such as:
* register input device name "Atmel maXTouch Touchpad" instead of
Touchscreen.
* register BTN_LEFT & BTN_TOOL_* event types.
* register axis resolution (as a fixed constant, for now)
* register BUTTONPAD property
* process GPIO buttons using reportid T19

For now, the left mouse button is mapped to GPIO3. Going forward,
platform data should specify the configuration of the buttons.
They can be configured via a future platform data change to
specify optional middle and right buttons, as well as other possible
uses for the GPIO object T19.

Signed-off-by: Daniel Kurtz <[email protected]>
Signed-off-by: Benson Leung <[email protected]>
Signed-off-by: Nick Dyer <[email protected]>
Tested-by: Olof Johansson <[email protected]>
---
v2: zero reportid in mxt_object_table_free(), Thanks [email protected]
v1: Initial
---
drivers/input/touchscreen/atmel_mxt_ts.c | 57 ++++++++++++++++++++++++++++++--
1 file changed, 55 insertions(+), 2 deletions(-)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
index d04f810..3611a26 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -181,6 +181,12 @@

#define MXT_FWRESET_TIME 175 /* msec */

+/* MXT_SPT_GPIOPWM_T19 field */
+#define MXT_GPIO0_MASK 0x04
+#define MXT_GPIO1_MASK 0x08
+#define MXT_GPIO2_MASK 0x10
+#define MXT_GPIO3_MASK 0x20
+
/* Command to unlock bootloader */
#define MXT_UNLOCK_CMD_MSB 0xaa
#define MXT_UNLOCK_CMD_LSB 0xdc
@@ -212,6 +218,8 @@
/* Touchscreen absolute values */
#define MXT_MAX_AREA 0xff

+#define MXT_PIXELS_PER_MM 20
+
struct mxt_info {
u8 family_id;
u8 variant_id;
@@ -243,6 +251,8 @@ struct mxt_data {
const struct mxt_platform_data *pdata;
struct mxt_object *object_table;
struct mxt_info info;
+ bool is_tp;
+
unsigned int irq;
unsigned int max_x;
unsigned int max_y;
@@ -251,6 +261,7 @@ struct mxt_data {
u8 T6_reportid;
u8 T9_reportid_min;
u8 T9_reportid_max;
+ u8 T19_reportid;
};

static bool mxt_object_readable(unsigned int type)
@@ -502,6 +513,18 @@ static int mxt_write_object(struct mxt_data *data,
return mxt_write_reg(data->client, reg + offset, val);
}

+static void mxt_input_button(struct mxt_data *data, struct mxt_message *message)
+{
+ struct device *dev = &data->client->dev;
+ struct input_dev *input = data->input_dev;
+ bool button;
+
+ /* Active-low switch */
+ button = !(message->message[0] & MXT_GPIO3_MASK);
+ input_report_key(input, BTN_LEFT, button);
+ dev_dbg(dev, "Button state: %d\n", button);
+}
+
static void mxt_input_touchevent(struct mxt_data *data,
struct mxt_message *message, int id)
{
@@ -585,6 +608,9 @@ static irqreturn_t mxt_interrupt(int irq, void *dev_id)
int id = reportid - data->T9_reportid_min;
mxt_input_touchevent(data, &message, id);
update_input = true;
+ } else if (message.reportid == data->T19_reportid) {
+ mxt_input_button(data, &message);
+ update_input = true;
} else {
mxt_dump_message(dev, &message);
}
@@ -764,6 +790,9 @@ static int mxt_get_object_table(struct mxt_data *data)
data->T9_reportid_min = min_id;
data->T9_reportid_max = max_id;
break;
+ case MXT_SPT_GPIOPWM_T19:
+ data->T19_reportid = min_id;
+ break;
}
}

@@ -777,7 +806,7 @@ static void mxt_free_object_table(struct mxt_data *data)
data->T6_reportid = 0;
data->T9_reportid_min = 0;
data->T9_reportid_max = 0;
-
+ data->T19_reportid = 0;
}

static int mxt_initialize(struct mxt_data *data)
@@ -1115,9 +1144,13 @@ static int mxt_probe(struct i2c_client *client,
goto err_free_mem;
}

- input_dev->name = "Atmel maXTouch Touchscreen";
+ data->is_tp = !strcmp(id->name, "atmel_mxt_tp");
+
+ input_dev->name = (data->is_tp) ? "Atmel maXTouch Touchpad" :
+ "Atmel maXTouch Touchscreen";
snprintf(data->phys, sizeof(data->phys), "i2c-%u-%04x/input0",
client->adapter->nr, client->addr);
+
input_dev->phys = data->phys;

input_dev->id.bustype = BUS_I2C;
@@ -1140,6 +1173,25 @@ static int mxt_probe(struct i2c_client *client,
__set_bit(EV_KEY, input_dev->evbit);
__set_bit(BTN_TOUCH, input_dev->keybit);

+ if (data->is_tp) {
+ __set_bit(INPUT_PROP_POINTER, input_dev->propbit);
+ __set_bit(INPUT_PROP_BUTTONPAD, input_dev->propbit);
+
+ __set_bit(BTN_LEFT, input_dev->keybit);
+ __set_bit(BTN_TOOL_FINGER, input_dev->keybit);
+ __set_bit(BTN_TOOL_DOUBLETAP, input_dev->keybit);
+ __set_bit(BTN_TOOL_TRIPLETAP, input_dev->keybit);
+ __set_bit(BTN_TOOL_QUADTAP, input_dev->keybit);
+ __set_bit(BTN_TOOL_QUINTTAP, input_dev->keybit);
+
+ 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 single touch */
input_set_abs_params(input_dev, ABS_X,
0, data->max_x, 0, 0);
@@ -1258,6 +1310,7 @@ static SIMPLE_DEV_PM_OPS(mxt_pm_ops, mxt_suspend, mxt_resume);
static const struct i2c_device_id mxt_id[] = {
{ "qt602240_ts", 0 },
{ "atmel_mxt_ts", 0 },
+ { "atmel_mxt_tp", 0 },
{ "mXT224", 0 },
{ }
};
--
1.8.1.3

2013-03-06 07:42:13

by Benson Leung

[permalink] [raw]
Subject: [PATCH v2 2/2] Platform: x86: chromeos_laptop : Add basic platform data for atmel devices

Add basic platform data to get the current upstream driver working
with the 224s touchpad and 1664s touchscreen.
We will be using NULL config so we will use the settings from the
devices' NVRAMs.

Signed-off-by: Benson Leung <[email protected]>
Tested-by: Olof Johansson <[email protected]>
---
v2: Patches cleanly with v3.9-rc1
v1: Initial
---
drivers/platform/x86/chromeos_laptop.c | 34 ++++++++++++++++++++++++++++++++--
1 file changed, 32 insertions(+), 2 deletions(-)

diff --git a/drivers/platform/x86/chromeos_laptop.c b/drivers/platform/x86/chromeos_laptop.c
index 93d6680..c10ff84 100644
--- a/drivers/platform/x86/chromeos_laptop.c
+++ b/drivers/platform/x86/chromeos_laptop.c
@@ -23,6 +23,8 @@

#include <linux/dmi.h>
#include <linux/i2c.h>
+#include <linux/i2c/atmel_mxt_ts.h>
+#include <linux/interrupt.h>
#include <linux/module.h>

#define ATMEL_TP_I2C_ADDR 0x4b
@@ -67,15 +69,43 @@ static struct i2c_board_info __initdata tsl2563_als_device = {
I2C_BOARD_INFO("tsl2563", TAOS_ALS_I2C_ADDR),
};

+static struct mxt_platform_data atmel_224s_tp_platform_data = {
+ .x_line = 18,
+ .y_line = 12,
+ .x_size = 102*20,
+ .y_size = 68*20,
+ .blen = 0x80, /* Gain setting is in upper 4 bits */
+ .threshold = 0x32,
+ .voltage = 0, /* 3.3V */
+ .orient = MXT_VERTICAL_FLIP,
+ .irqflags = IRQF_TRIGGER_FALLING,
+ .config = NULL,
+ .config_length = 0,
+};
+
static struct i2c_board_info __initdata atmel_224s_tp_device = {
I2C_BOARD_INFO("atmel_mxt_tp", ATMEL_TP_I2C_ADDR),
- .platform_data = NULL,
+ .platform_data = &atmel_224s_tp_platform_data,
.flags = I2C_CLIENT_WAKE,
};

+static struct mxt_platform_data atmel_1664s_platform_data = {
+ .x_line = 32,
+ .y_line = 50,
+ .x_size = 1700,
+ .y_size = 2560,
+ .blen = 0x89, /* Gain setting is in upper 4 bits */
+ .threshold = 0x28,
+ .voltage = 0, /* 3.3V */
+ .orient = MXT_ROTATED_90_COUNTER,
+ .irqflags = IRQF_TRIGGER_FALLING,
+ .config = NULL,
+ .config_length = 0,
+};
+
static struct i2c_board_info __initdata atmel_1664s_device = {
I2C_BOARD_INFO("atmel_mxt_ts", ATMEL_TS_I2C_ADDR),
- .platform_data = NULL,
+ .platform_data = &atmel_1664s_platform_data,
.flags = I2C_CLIENT_WAKE,
};

--
1.8.1.3

2013-03-06 08:44:30

by Joonyoung Shim

[permalink] [raw]
Subject: Re: [PATCH v2 1/2] Input: atmel_mxt_ts - add device id for touchpad variant

Hi Benson,

On 03/06/2013 04:41 PM, Benson Leung wrote:
> From: Daniel Kurtz <[email protected]>
>
> This same driver can be used by atmel based touchscreens and touchpads
> (buttonpads) by instantiating the i2c device as a "atmel_mxt_tp".
>
> This will cause the driver to perform some touchpad specific
> initializations, such as:
> * register input device name "Atmel maXTouch Touchpad" instead of
> Touchscreen.
> * register BTN_LEFT & BTN_TOOL_* event types.
> * register axis resolution (as a fixed constant, for now)
> * register BUTTONPAD property
> * process GPIO buttons using reportid T19
>
> For now, the left mouse button is mapped to GPIO3. Going forward,
> platform data should specify the configuration of the buttons.
> They can be configured via a future platform data change to
> specify optional middle and right buttons, as well as other possible
> uses for the GPIO object T19.

It's better to implement this now.

> Signed-off-by: Daniel Kurtz <[email protected]>
> Signed-off-by: Benson Leung <[email protected]>
> Signed-off-by: Nick Dyer <[email protected]>
> Tested-by: Olof Johansson <[email protected]>
> ---
> v2: zero reportid in mxt_object_table_free(), Thanks [email protected]
> v1: Initial
> ---
> drivers/input/touchscreen/atmel_mxt_ts.c | 57 ++++++++++++++++++++++++++++++--
> 1 file changed, 55 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
> index d04f810..3611a26 100644
> --- a/drivers/input/touchscreen/atmel_mxt_ts.c
> +++ b/drivers/input/touchscreen/atmel_mxt_ts.c
> @@ -181,6 +181,12 @@
>
> #define MXT_FWRESET_TIME 175 /* msec */
>
> +/* MXT_SPT_GPIOPWM_T19 field */
> +#define MXT_GPIO0_MASK 0x04
> +#define MXT_GPIO1_MASK 0x08
> +#define MXT_GPIO2_MASK 0x10
> +#define MXT_GPIO3_MASK 0x20
> +
> /* Command to unlock bootloader */
> #define MXT_UNLOCK_CMD_MSB 0xaa
> #define MXT_UNLOCK_CMD_LSB 0xdc
> @@ -212,6 +218,8 @@
> /* Touchscreen absolute values */
> #define MXT_MAX_AREA 0xff
>
> +#define MXT_PIXELS_PER_MM 20
> +
> struct mxt_info {
> u8 family_id;
> u8 variant_id;
> @@ -243,6 +251,8 @@ struct mxt_data {
> const struct mxt_platform_data *pdata;
> struct mxt_object *object_table;
> struct mxt_info info;
> + bool is_tp;
> +
> unsigned int irq;
> unsigned int max_x;
> unsigned int max_y;
> @@ -251,6 +261,7 @@ struct mxt_data {
> u8 T6_reportid;
> u8 T9_reportid_min;
> u8 T9_reportid_max;
> + u8 T19_reportid;
> };
>
> static bool mxt_object_readable(unsigned int type)
> @@ -502,6 +513,18 @@ static int mxt_write_object(struct mxt_data *data,
> return mxt_write_reg(data->client, reg + offset, val);
> }
>
> +static void mxt_input_button(struct mxt_data *data, struct mxt_message *message)
> +{
> + struct device *dev = &data->client->dev;
> + struct input_dev *input = data->input_dev;
> + bool button;
> +
> + /* Active-low switch */
> + button = !(message->message[0] & MXT_GPIO3_MASK);
> + input_report_key(input, BTN_LEFT, button);
> + dev_dbg(dev, "Button state: %d\n", button);
> +}
> +
> static void mxt_input_touchevent(struct mxt_data *data,
> struct mxt_message *message, int id)
> {
> @@ -585,6 +608,9 @@ static irqreturn_t mxt_interrupt(int irq, void *dev_id)
> int id = reportid - data->T9_reportid_min;
> mxt_input_touchevent(data, &message, id);
> update_input = true;
> + } else if (message.reportid == data->T19_reportid) {
> + mxt_input_button(data, &message);
> + update_input = true;
> } else {
> mxt_dump_message(dev, &message);
> }
> @@ -764,6 +790,9 @@ static int mxt_get_object_table(struct mxt_data *data)
> data->T9_reportid_min = min_id;
> data->T9_reportid_max = max_id;
> break;
> + case MXT_SPT_GPIOPWM_T19:
> + data->T19_reportid = min_id;
> + break;
> }
> }
>
> @@ -777,7 +806,7 @@ static void mxt_free_object_table(struct mxt_data *data)
> data->T6_reportid = 0;
> data->T9_reportid_min = 0;
> data->T9_reportid_max = 0;
> -
> + data->T19_reportid = 0;
> }
>
> static int mxt_initialize(struct mxt_data *data)
> @@ -1115,9 +1144,13 @@ static int mxt_probe(struct i2c_client *client,
> goto err_free_mem;
> }
>
> - input_dev->name = "Atmel maXTouch Touchscreen";
> + data->is_tp = !strcmp(id->name, "atmel_mxt_tp");
> +
> + input_dev->name = (data->is_tp) ? "Atmel maXTouch Touchpad" :
> + "Atmel maXTouch Touchscreen";
> snprintf(data->phys, sizeof(data->phys), "i2c-%u-%04x/input0",
> client->adapter->nr, client->addr);
> +
> input_dev->phys = data->phys;
>
> input_dev->id.bustype = BUS_I2C;
> @@ -1140,6 +1173,25 @@ static int mxt_probe(struct i2c_client *client,
> __set_bit(EV_KEY, input_dev->evbit);
> __set_bit(BTN_TOUCH, input_dev->keybit);
>
> + if (data->is_tp) {
> + __set_bit(INPUT_PROP_POINTER, input_dev->propbit);
> + __set_bit(INPUT_PROP_BUTTONPAD, input_dev->propbit);
> +
> + __set_bit(BTN_LEFT, input_dev->keybit);
> + __set_bit(BTN_TOOL_FINGER, input_dev->keybit);
> + __set_bit(BTN_TOOL_DOUBLETAP, input_dev->keybit);
> + __set_bit(BTN_TOOL_TRIPLETAP, input_dev->keybit);
> + __set_bit(BTN_TOOL_QUADTAP, input_dev->keybit);
> + __set_bit(BTN_TOOL_QUINTTAP, input_dev->keybit);
> +
> + 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 single touch */
> input_set_abs_params(input_dev, ABS_X,
> 0, data->max_x, 0, 0);
> @@ -1258,6 +1310,7 @@ static SIMPLE_DEV_PM_OPS(mxt_pm_ops, mxt_suspend, mxt_resume);
> static const struct i2c_device_id mxt_id[] = {
> { "qt602240_ts", 0 },
> { "atmel_mxt_ts", 0 },
> + { "atmel_mxt_tp", 0 },

How about driver_data to distinguish touchscreen and touchpad?

> { "mXT224", 0 },
> { }
> };

2013-03-08 03:43:45

by Benson Leung

[permalink] [raw]
Subject: [PATCH v3 0/2] Add platform data and touchpad functionality for Pixel

Add support for a touchpad variant in the atmel_mxt_ts driver.
Then, add platform data for the 224s trackpad and the 1664s touchscreen
in chromeos_laptop so that the existing version of the driver will
probe these devices correctly.

v3 : Add platform data for is_tp and key_map. Remove dependence on
device name for tp behavior.
v2 : Minor bugfix in patch 1. Cleanup client_id from commit message.
Make sure chromeos_laptop patch applies cleanly to v3.9-rc1

[PATCH v3 1/2] Input: atmel_mxt_ts - Support for touchpad variant
[PATCH v3 2/2] Platform: x86: chromeos_laptop : Add basic platform data

2013-03-08 03:43:56

by Benson Leung

[permalink] [raw]
Subject: [PATCH v3 1/2] Input: atmel_mxt_ts - Support for touchpad variant

From: Daniel Kurtz <[email protected]>

This same driver can be used by atmel based touchscreens and touchpads
(buttonpads). Platform data may specify a device is a touchpad
using the is_tp flag.

This will cause the driver to perform some touchpad specific
initializations, such as:
* register input device name "Atmel maXTouch Touchpad" instead of
Touchscreen.
* register BTN_LEFT & BTN_TOOL_* event types.
* register axis resolution (as a fixed constant, for now)
* register BUTTONPAD property
* process GPIO buttons using reportid T19

Input event GPIO mapping is done by the platform data key_map array.

key_map[x] should contain the KEY or BTN code to send when processing
GPIOx from T19. To specify a GPIO as not an input source, populate
with KEY_RESERVED, or 0.

Signed-off-by: Daniel Kurtz <[email protected]>
Signed-off-by: Benson Leung <[email protected]>
Signed-off-by: Nick Dyer <[email protected]>
Tested-by: Olof Johansson <[email protected]>
---
v3: Add key_map array to map gpios to keys or buttons. Configure is_tp from
pdata.
v2: zero reportid in mxt_object_table_free(), Thanks [email protected]
v1: Initial
---
drivers/input/touchscreen/atmel_mxt_ts.c | 65 +++++++++++++++++++++++++++++++-
include/linux/i2c/atmel_mxt_ts.h | 5 +++
2 files changed, 68 insertions(+), 2 deletions(-)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
index d04f810..feafbb8 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -181,6 +181,12 @@

#define MXT_FWRESET_TIME 175 /* msec */

+/* MXT_SPT_GPIOPWM_T19 field */
+#define MXT_GPIO0_MASK 0x04
+#define MXT_GPIO1_MASK 0x08
+#define MXT_GPIO2_MASK 0x10
+#define MXT_GPIO3_MASK 0x20
+
/* Command to unlock bootloader */
#define MXT_UNLOCK_CMD_MSB 0xaa
#define MXT_UNLOCK_CMD_LSB 0xdc
@@ -212,6 +218,8 @@
/* Touchscreen absolute values */
#define MXT_MAX_AREA 0xff

+#define MXT_PIXELS_PER_MM 20
+
struct mxt_info {
u8 family_id;
u8 variant_id;
@@ -243,6 +251,8 @@ struct mxt_data {
const struct mxt_platform_data *pdata;
struct mxt_object *object_table;
struct mxt_info info;
+ bool is_tp;
+
unsigned int irq;
unsigned int max_x;
unsigned int max_y;
@@ -251,6 +261,7 @@ struct mxt_data {
u8 T6_reportid;
u8 T9_reportid_min;
u8 T9_reportid_max;
+ u8 T19_reportid;
};

static bool mxt_object_readable(unsigned int type)
@@ -502,6 +513,22 @@ static int mxt_write_object(struct mxt_data *data,
return mxt_write_reg(data->client, reg + offset, val);
}

+static void mxt_input_button(struct mxt_data *data, struct mxt_message *message)
+{
+ struct device *dev = &data->client->dev;
+ struct input_dev *input = data->input_dev;
+ bool button;
+ int i;
+
+ /* Active-low switch */
+ for (i = 0; i < MXT_NUM_GPIO; i++) {
+ if (data->pdata->key_map[i] == KEY_RESERVED)
+ continue;
+ button = !(message->message[0] & MXT_GPIO0_MASK << i);
+ input_report_key(input, data->pdata->key_map[i], button);
+ }
+}
+
static void mxt_input_touchevent(struct mxt_data *data,
struct mxt_message *message, int id)
{
@@ -585,6 +612,9 @@ static irqreturn_t mxt_interrupt(int irq, void *dev_id)
int id = reportid - data->T9_reportid_min;
mxt_input_touchevent(data, &message, id);
update_input = true;
+ } else if (message.reportid == data->T19_reportid) {
+ mxt_input_button(data, &message);
+ update_input = true;
} else {
mxt_dump_message(dev, &message);
}
@@ -764,6 +794,9 @@ static int mxt_get_object_table(struct mxt_data *data)
data->T9_reportid_min = min_id;
data->T9_reportid_max = max_id;
break;
+ case MXT_SPT_GPIOPWM_T19:
+ data->T19_reportid = min_id;
+ break;
}
}

@@ -777,7 +810,7 @@ static void mxt_free_object_table(struct mxt_data *data)
data->T6_reportid = 0;
data->T9_reportid_min = 0;
data->T9_reportid_max = 0;
-
+ data->T19_reportid = 0;
}

static int mxt_initialize(struct mxt_data *data)
@@ -1115,9 +1148,13 @@ static int mxt_probe(struct i2c_client *client,
goto err_free_mem;
}

- input_dev->name = "Atmel maXTouch Touchscreen";
+ data->is_tp = pdata && pdata->is_tp;
+
+ input_dev->name = (data->is_tp) ? "Atmel maXTouch Touchpad" :
+ "Atmel maXTouch Touchscreen";
snprintf(data->phys, sizeof(data->phys), "i2c-%u-%04x/input0",
client->adapter->nr, client->addr);
+
input_dev->phys = data->phys;

input_dev->id.bustype = BUS_I2C;
@@ -1140,6 +1177,29 @@ static int mxt_probe(struct i2c_client *client,
__set_bit(EV_KEY, input_dev->evbit);
__set_bit(BTN_TOUCH, input_dev->keybit);

+ if (data->is_tp) {
+ int i;
+ __set_bit(INPUT_PROP_POINTER, input_dev->propbit);
+ __set_bit(INPUT_PROP_BUTTONPAD, input_dev->propbit);
+
+ for (i = 0; i < MXT_NUM_GPIO; i++)
+ if (pdata->key_map[i] != KEY_RESERVED)
+ __set_bit(pdata->key_map[i], input_dev->keybit);
+
+ __set_bit(BTN_TOOL_FINGER, input_dev->keybit);
+ __set_bit(BTN_TOOL_DOUBLETAP, input_dev->keybit);
+ __set_bit(BTN_TOOL_TRIPLETAP, input_dev->keybit);
+ __set_bit(BTN_TOOL_QUADTAP, input_dev->keybit);
+ __set_bit(BTN_TOOL_QUINTTAP, input_dev->keybit);
+
+ 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 single touch */
input_set_abs_params(input_dev, ABS_X,
0, data->max_x, 0, 0);
@@ -1258,6 +1318,7 @@ static SIMPLE_DEV_PM_OPS(mxt_pm_ops, mxt_suspend, mxt_resume);
static const struct i2c_device_id mxt_id[] = {
{ "qt602240_ts", 0 },
{ "atmel_mxt_ts", 0 },
+ { "atmel_mxt_tp", 0 },
{ "mXT224", 0 },
{ }
};
diff --git a/include/linux/i2c/atmel_mxt_ts.h b/include/linux/i2c/atmel_mxt_ts.h
index f027f7a..99e379b 100644
--- a/include/linux/i2c/atmel_mxt_ts.h
+++ b/include/linux/i2c/atmel_mxt_ts.h
@@ -15,6 +15,9 @@

#include <linux/types.h>

+/* For key_map array */
+#define MXT_NUM_GPIO 4
+
/* Orient */
#define MXT_NORMAL 0x0
#define MXT_DIAGONAL 0x1
@@ -39,6 +42,8 @@ struct mxt_platform_data {
unsigned int voltage;
unsigned char orient;
unsigned long irqflags;
+ bool is_tp;
+ const unsigned int key_map[MXT_NUM_GPIO];
};

#endif /* __LINUX_ATMEL_MXT_TS_H */
--
1.8.1.3

2013-03-08 03:44:10

by Benson Leung

[permalink] [raw]
Subject: [PATCH v3 2/2] Platform: x86: chromeos_laptop : Add basic platform data for atmel devices

Add basic platform data to get the current upstream driver working
with the 224s touchpad and 1664s touchscreen.
We will be using NULL config so we will use the settings from the
devices' NVRAMs.

Signed-off-by: Benson Leung <[email protected]>
Tested-by: Olof Johansson <[email protected]>
---
v3: Add key map for the mXT224SL used on Chromebook Pixel, assigning BTN_LEFT
to GPIO3. Set .is_tp to true for mXT224SL.
v2: Patches cleanly with v3.9-rc1
v1: Initial
---
drivers/platform/x86/chromeos_laptop.c | 41 ++++++++++++++++++++++++++++++++--
1 file changed, 39 insertions(+), 2 deletions(-)

diff --git a/drivers/platform/x86/chromeos_laptop.c b/drivers/platform/x86/chromeos_laptop.c
index 93d6680..3e5b4497 100644
--- a/drivers/platform/x86/chromeos_laptop.c
+++ b/drivers/platform/x86/chromeos_laptop.c
@@ -23,6 +23,9 @@

#include <linux/dmi.h>
#include <linux/i2c.h>
+#include <linux/i2c/atmel_mxt_ts.h>
+#include <linux/input.h>
+#include <linux/interrupt.h>
#include <linux/module.h>

#define ATMEL_TP_I2C_ADDR 0x4b
@@ -67,15 +70,49 @@ static struct i2c_board_info __initdata tsl2563_als_device = {
I2C_BOARD_INFO("tsl2563", TAOS_ALS_I2C_ADDR),
};

+static struct mxt_platform_data atmel_224s_tp_platform_data = {
+ .x_line = 18,
+ .y_line = 12,
+ .x_size = 102*20,
+ .y_size = 68*20,
+ .blen = 0x80, /* Gain setting is in upper 4 bits */
+ .threshold = 0x32,
+ .voltage = 0, /* 3.3V */
+ .orient = MXT_VERTICAL_FLIP,
+ .irqflags = IRQF_TRIGGER_FALLING,
+ .is_tp = true,
+ .key_map = { KEY_RESERVED,
+ KEY_RESERVED,
+ KEY_RESERVED,
+ BTN_LEFT },
+ .config = NULL,
+ .config_length = 0,
+};
+
static struct i2c_board_info __initdata atmel_224s_tp_device = {
I2C_BOARD_INFO("atmel_mxt_tp", ATMEL_TP_I2C_ADDR),
- .platform_data = NULL,
+ .platform_data = &atmel_224s_tp_platform_data,
.flags = I2C_CLIENT_WAKE,
};

+static struct mxt_platform_data atmel_1664s_platform_data = {
+ .x_line = 32,
+ .y_line = 50,
+ .x_size = 1700,
+ .y_size = 2560,
+ .blen = 0x89, /* Gain setting is in upper 4 bits */
+ .threshold = 0x28,
+ .voltage = 0, /* 3.3V */
+ .orient = MXT_ROTATED_90_COUNTER,
+ .irqflags = IRQF_TRIGGER_FALLING,
+ .is_tp = false,
+ .config = NULL,
+ .config_length = 0,
+};
+
static struct i2c_board_info __initdata atmel_1664s_device = {
I2C_BOARD_INFO("atmel_mxt_ts", ATMEL_TS_I2C_ADDR),
- .platform_data = NULL,
+ .platform_data = &atmel_1664s_platform_data,
.flags = I2C_CLIENT_WAKE,
};

--
1.8.1.3

2013-03-08 06:57:23

by Benson Leung

[permalink] [raw]
Subject: Re: [PATCH v3 1/2] Input: atmel_mxt_ts - Support for touchpad variant

On Thu, Mar 7, 2013 at 7:43 PM, Benson Leung <[email protected]> wrote:
> +static void mxt_input_button(struct mxt_data *data, struct mxt_message *message)
> +{
> + struct device *dev = &data->client->dev;
Oops. I missed a warning: unused variable 'dev' here.

> + struct input_dev *input = data->input_dev;
> + bool button;
> + int i;
> +
> + /* Active-low switch */
> + for (i = 0; i < MXT_NUM_GPIO; i++) {
> + if (data->pdata->key_map[i] == KEY_RESERVED)
> + continue;
> + button = !(message->message[0] & MXT_GPIO0_MASK << i);
> + input_report_key(input, data->pdata->key_map[i], button);
> + }
> +}
> +




--
Benson Leung
Software Engineer, Chrom* OS
[email protected]

2013-03-10 09:10:22

by Henrik Rydberg

[permalink] [raw]
Subject: Re: [PATCH v3 1/2] Input: atmel_mxt_ts - Support for touchpad variant

Hi Benson,

> From: Daniel Kurtz <[email protected]>
>
> This same driver can be used by atmel based touchscreens and touchpads
> (buttonpads). Platform data may specify a device is a touchpad
> using the is_tp flag.
>
> This will cause the driver to perform some touchpad specific
> initializations, such as:
> * register input device name "Atmel maXTouch Touchpad" instead of
> Touchscreen.
> * register BTN_LEFT & BTN_TOOL_* event types.
> * register axis resolution (as a fixed constant, for now)
> * register BUTTONPAD property
> * process GPIO buttons using reportid T19
>
> Input event GPIO mapping is done by the platform data key_map array.
>
> key_map[x] should contain the KEY or BTN code to send when processing
> GPIOx from T19. To specify a GPIO as not an input source, populate
> with KEY_RESERVED, or 0.
>
> Signed-off-by: Daniel Kurtz <[email protected]>
> Signed-off-by: Benson Leung <[email protected]>
> Signed-off-by: Nick Dyer <[email protected]>
> Tested-by: Olof Johansson <[email protected]>
> ---
> v3: Add key_map array to map gpios to keys or buttons. Configure is_tp from
> pdata.
> v2: zero reportid in mxt_object_table_free(), Thanks [email protected]
> v1: Initial
> ---
> drivers/input/touchscreen/atmel_mxt_ts.c | 65 +++++++++++++++++++++++++++++++-
> include/linux/i2c/atmel_mxt_ts.h | 5 +++
> 2 files changed, 68 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
> index d04f810..feafbb8 100644
> --- a/drivers/input/touchscreen/atmel_mxt_ts.c
> +++ b/drivers/input/touchscreen/atmel_mxt_ts.c
> @@ -181,6 +181,12 @@
>
> #define MXT_FWRESET_TIME 175 /* msec */
>
> +/* MXT_SPT_GPIOPWM_T19 field */
> +#define MXT_GPIO0_MASK 0x04
> +#define MXT_GPIO1_MASK 0x08
> +#define MXT_GPIO2_MASK 0x10
> +#define MXT_GPIO3_MASK 0x20

Since these are not used individually, but treated as a bit field in
the code, a single bit index would suffice.

> +
> /* Command to unlock bootloader */
> #define MXT_UNLOCK_CMD_MSB 0xaa
> #define MXT_UNLOCK_CMD_LSB 0xdc
> @@ -212,6 +218,8 @@
> /* Touchscreen absolute values */
> #define MXT_MAX_AREA 0xff
>
> +#define MXT_PIXELS_PER_MM 20
> +
> struct mxt_info {
> u8 family_id;
> u8 variant_id;
> @@ -243,6 +251,8 @@ struct mxt_data {
> const struct mxt_platform_data *pdata;
> struct mxt_object *object_table;
> struct mxt_info info;
> + bool is_tp;
> +
> unsigned int irq;
> unsigned int max_x;
> unsigned int max_y;
> @@ -251,6 +261,7 @@ struct mxt_data {
> u8 T6_reportid;
> u8 T9_reportid_min;
> u8 T9_reportid_max;
> + u8 T19_reportid;
> };
>
> static bool mxt_object_readable(unsigned int type)
> @@ -502,6 +513,22 @@ static int mxt_write_object(struct mxt_data *data,
> return mxt_write_reg(data->client, reg + offset, val);
> }
>
> +static void mxt_input_button(struct mxt_data *data, struct mxt_message *message)
> +{
> + struct device *dev = &data->client->dev;
> + struct input_dev *input = data->input_dev;
> + bool button;
> + int i;
> +
> + /* Active-low switch */
> + for (i = 0; i < MXT_NUM_GPIO; i++) {
> + if (data->pdata->key_map[i] == KEY_RESERVED)
> + continue;
> + button = !(message->message[0] & MXT_GPIO0_MASK << i);

This looks unintended.

> + input_report_key(input, data->pdata->key_map[i], button);
> + }
> +}
> +
> static void mxt_input_touchevent(struct mxt_data *data,
> struct mxt_message *message, int id)
> {
> @@ -585,6 +612,9 @@ static irqreturn_t mxt_interrupt(int irq, void *dev_id)
> int id = reportid - data->T9_reportid_min;
> mxt_input_touchevent(data, &message, id);
> update_input = true;
> + } else if (message.reportid == data->T19_reportid) {
> + mxt_input_button(data, &message);
> + update_input = true;
> } else {
> mxt_dump_message(dev, &message);
> }
> @@ -764,6 +794,9 @@ static int mxt_get_object_table(struct mxt_data *data)
> data->T9_reportid_min = min_id;
> data->T9_reportid_max = max_id;
> break;
> + case MXT_SPT_GPIOPWM_T19:
> + data->T19_reportid = min_id;
> + break;
> }
> }
>
> @@ -777,7 +810,7 @@ static void mxt_free_object_table(struct mxt_data *data)
> data->T6_reportid = 0;
> data->T9_reportid_min = 0;
> data->T9_reportid_max = 0;
> -
> + data->T19_reportid = 0;
> }
>
> static int mxt_initialize(struct mxt_data *data)
> @@ -1115,9 +1148,13 @@ static int mxt_probe(struct i2c_client *client,
> goto err_free_mem;
> }
>
> - input_dev->name = "Atmel maXTouch Touchscreen";
> + data->is_tp = pdata && pdata->is_tp;
> +
> + input_dev->name = (data->is_tp) ? "Atmel maXTouch Touchpad" :
> + "Atmel maXTouch Touchscreen";
> snprintf(data->phys, sizeof(data->phys), "i2c-%u-%04x/input0",
> client->adapter->nr, client->addr);
> +
> input_dev->phys = data->phys;
>
> input_dev->id.bustype = BUS_I2C;
> @@ -1140,6 +1177,29 @@ static int mxt_probe(struct i2c_client *client,
> __set_bit(EV_KEY, input_dev->evbit);
> __set_bit(BTN_TOUCH, input_dev->keybit);
>
> + if (data->is_tp) {
> + int i;
> + __set_bit(INPUT_PROP_POINTER, input_dev->propbit);
> + __set_bit(INPUT_PROP_BUTTONPAD, input_dev->propbit);
> +
> + for (i = 0; i < MXT_NUM_GPIO; i++)
> + if (pdata->key_map[i] != KEY_RESERVED)
> + __set_bit(pdata->key_map[i], input_dev->keybit);
> +
> + __set_bit(BTN_TOOL_FINGER, input_dev->keybit);
> + __set_bit(BTN_TOOL_DOUBLETAP, input_dev->keybit);
> + __set_bit(BTN_TOOL_TRIPLETAP, input_dev->keybit);
> + __set_bit(BTN_TOOL_QUADTAP, input_dev->keybit);
> + __set_bit(BTN_TOOL_QUINTTAP, input_dev->keybit);
> +

It would be much preferred to have all these handled by input
_mt_init_slots() instead. For instance by adding the INPUT_MT_POINTER
flag. Also, the driver does not seem to handle touchpads properly, as
I cannot see the finger count sent anywhere.

> + 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 single touch */
> input_set_abs_params(input_dev, ABS_X,
> 0, data->max_x, 0, 0);
> @@ -1258,6 +1318,7 @@ static SIMPLE_DEV_PM_OPS(mxt_pm_ops, mxt_suspend, mxt_resume);
> static const struct i2c_device_id mxt_id[] = {
> { "qt602240_ts", 0 },
> { "atmel_mxt_ts", 0 },
> + { "atmel_mxt_tp", 0 },
> { "mXT224", 0 },
> { }
> };
> diff --git a/include/linux/i2c/atmel_mxt_ts.h b/include/linux/i2c/atmel_mxt_ts.h
> index f027f7a..99e379b 100644
> --- a/include/linux/i2c/atmel_mxt_ts.h
> +++ b/include/linux/i2c/atmel_mxt_ts.h
> @@ -15,6 +15,9 @@
>
> #include <linux/types.h>
>
> +/* For key_map array */
> +#define MXT_NUM_GPIO 4
> +
> /* Orient */
> #define MXT_NORMAL 0x0
> #define MXT_DIAGONAL 0x1
> @@ -39,6 +42,8 @@ struct mxt_platform_data {
> unsigned int voltage;
> unsigned char orient;
> unsigned long irqflags;
> + bool is_tp;
> + const unsigned int key_map[MXT_NUM_GPIO];
> };
>
> #endif /* __LINUX_ATMEL_MXT_TS_H */
> --
> 1.8.1.3
>

Thanks,
Henrik