Skip to content

Commit 3bdd21c

Browse files
sredtor
authored andcommitted
Input: exc3000 - add EXC80H60 and EXC80H84 support
This adds support for EXC80H60 and EXCH84 controllers, which use a different event type id and have two extra bits for the resolution (so the maximum is 16K instead of 4K). Signed-off-by: Sebastian Reichel <[email protected]> Acked-by: Rob Herring <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Dmitry Torokhov <[email protected]>
1 parent 1053653 commit 3bdd21c

File tree

2 files changed

+70
-15
lines changed

2 files changed

+70
-15
lines changed

Documentation/devicetree/bindings/input/touchscreen/eeti,exc3000.yaml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,10 @@ allOf:
1414

1515
properties:
1616
compatible:
17-
const: eeti,exc3000
17+
enum:
18+
- eeti,exc3000
19+
- eeti,exc80h60
20+
- eeti,exc80h84
1821
reg:
1922
const: 0x2a
2023
interrupts:

drivers/input/touchscreen/exc3000.c

Lines changed: 66 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -16,18 +16,51 @@
1616
#include <linux/interrupt.h>
1717
#include <linux/module.h>
1818
#include <linux/of.h>
19+
#include <linux/sizes.h>
1920
#include <linux/timer.h>
2021
#include <asm/unaligned.h>
2122

2223
#define EXC3000_NUM_SLOTS 10
2324
#define EXC3000_SLOTS_PER_FRAME 5
2425
#define EXC3000_LEN_FRAME 66
2526
#define EXC3000_LEN_POINT 10
26-
#define EXC3000_MT_EVENT 6
27+
28+
#define EXC3000_MT1_EVENT 0x06
29+
#define EXC3000_MT2_EVENT 0x18
30+
2731
#define EXC3000_TIMEOUT_MS 100
2832

33+
static const struct i2c_device_id exc3000_id[];
34+
35+
struct eeti_dev_info {
36+
const char *name;
37+
int max_xy;
38+
};
39+
40+
enum eeti_dev_id {
41+
EETI_EXC3000,
42+
EETI_EXC80H60,
43+
EETI_EXC80H84,
44+
};
45+
46+
static struct eeti_dev_info exc3000_info[] = {
47+
[EETI_EXC3000] = {
48+
.name = "EETI EXC3000 Touch Screen",
49+
.max_xy = SZ_4K - 1,
50+
},
51+
[EETI_EXC80H60] = {
52+
.name = "EETI EXC80H60 Touch Screen",
53+
.max_xy = SZ_16K - 1,
54+
},
55+
[EETI_EXC80H84] = {
56+
.name = "EETI EXC80H84 Touch Screen",
57+
.max_xy = SZ_16K - 1,
58+
},
59+
};
60+
2961
struct exc3000_data {
3062
struct i2c_client *client;
63+
const struct eeti_dev_info *info;
3164
struct input_dev *input;
3265
struct touchscreen_properties prop;
3366
struct timer_list timer;
@@ -58,10 +91,15 @@ static void exc3000_timer(struct timer_list *t)
5891
input_sync(data->input);
5992
}
6093

61-
static int exc3000_read_frame(struct i2c_client *client, u8 *buf)
94+
static int exc3000_read_frame(struct exc3000_data *data, u8 *buf)
6295
{
96+
struct i2c_client *client = data->client;
97+
u8 expected_event = EXC3000_MT1_EVENT;
6398
int ret;
6499

100+
if (data->info->max_xy == SZ_16K - 1)
101+
expected_event = EXC3000_MT2_EVENT;
102+
65103
ret = i2c_master_send(client, "'", 2);
66104
if (ret < 0)
67105
return ret;
@@ -76,19 +114,21 @@ static int exc3000_read_frame(struct i2c_client *client, u8 *buf)
76114
if (ret != EXC3000_LEN_FRAME)
77115
return -EIO;
78116

79-
if (get_unaligned_le16(buf) != EXC3000_LEN_FRAME ||
80-
buf[2] != EXC3000_MT_EVENT)
117+
if (get_unaligned_le16(buf) != EXC3000_LEN_FRAME)
118+
return -EINVAL;
119+
120+
if (buf[2] != expected_event)
81121
return -EINVAL;
82122

83123
return 0;
84124
}
85125

86-
static int exc3000_read_data(struct i2c_client *client,
126+
static int exc3000_read_data(struct exc3000_data *data,
87127
u8 *buf, int *n_slots)
88128
{
89129
int error;
90130

91-
error = exc3000_read_frame(client, buf);
131+
error = exc3000_read_frame(data, buf);
92132
if (error)
93133
return error;
94134

@@ -98,7 +138,7 @@ static int exc3000_read_data(struct i2c_client *client,
98138

99139
if (*n_slots > EXC3000_SLOTS_PER_FRAME) {
100140
/* Read 2nd frame to get the rest of the contacts. */
101-
error = exc3000_read_frame(client, buf + EXC3000_LEN_FRAME);
141+
error = exc3000_read_frame(data, buf + EXC3000_LEN_FRAME);
102142
if (error)
103143
return error;
104144

@@ -118,7 +158,7 @@ static irqreturn_t exc3000_interrupt(int irq, void *dev_id)
118158
int slots, total_slots;
119159
int error;
120160

121-
error = exc3000_read_data(data->client, buf, &total_slots);
161+
error = exc3000_read_data(data, buf, &total_slots);
122162
if (error) {
123163
/* Schedule a timer to release "stuck" contacts */
124164
mod_timer(&data->timer,
@@ -149,13 +189,19 @@ static int exc3000_probe(struct i2c_client *client)
149189
{
150190
struct exc3000_data *data;
151191
struct input_dev *input;
152-
int error;
192+
int error, max_xy;
153193

154194
data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL);
155195
if (!data)
156196
return -ENOMEM;
157197

158198
data->client = client;
199+
data->info = device_get_match_data(&client->dev);
200+
if (!data->info) {
201+
enum eeti_dev_id eeti_dev_id =
202+
i2c_match_id(exc3000_id, client)->driver_data;
203+
data->info = &exc3000_info[eeti_dev_id];
204+
}
159205
timer_setup(&data->timer, exc3000_timer, 0);
160206

161207
input = devm_input_allocate_device(&client->dev);
@@ -164,11 +210,13 @@ static int exc3000_probe(struct i2c_client *client)
164210

165211
data->input = input;
166212

167-
input->name = "EETI EXC3000 Touch Screen";
213+
input->name = data->info->name;
168214
input->id.bustype = BUS_I2C;
169215

170-
input_set_abs_params(input, ABS_MT_POSITION_X, 0, 4095, 0, 0);
171-
input_set_abs_params(input, ABS_MT_POSITION_Y, 0, 4095, 0, 0);
216+
max_xy = data->info->max_xy;
217+
input_set_abs_params(input, ABS_MT_POSITION_X, 0, max_xy, 0, 0);
218+
input_set_abs_params(input, ABS_MT_POSITION_Y, 0, max_xy, 0, 0);
219+
172220
touchscreen_parse_properties(input, true, &data->prop);
173221

174222
error = input_mt_init_slots(input, EXC3000_NUM_SLOTS,
@@ -190,14 +238,18 @@ static int exc3000_probe(struct i2c_client *client)
190238
}
191239

192240
static const struct i2c_device_id exc3000_id[] = {
193-
{ "exc3000", 0 },
241+
{ "exc3000", EETI_EXC3000 },
242+
{ "exc80h60", EETI_EXC80H60 },
243+
{ "exc80h84", EETI_EXC80H84 },
194244
{ }
195245
};
196246
MODULE_DEVICE_TABLE(i2c, exc3000_id);
197247

198248
#ifdef CONFIG_OF
199249
static const struct of_device_id exc3000_of_match[] = {
200-
{ .compatible = "eeti,exc3000" },
250+
{ .compatible = "eeti,exc3000", .data = &exc3000_info[EETI_EXC3000] },
251+
{ .compatible = "eeti,exc80h60", .data = &exc3000_info[EETI_EXC80H60] },
252+
{ .compatible = "eeti,exc80h84", .data = &exc3000_info[EETI_EXC80H84] },
201253
{ }
202254
};
203255
MODULE_DEVICE_TABLE(of, exc3000_of_match);

0 commit comments

Comments
 (0)