16
16
#include <linux/interrupt.h>
17
17
#include <linux/module.h>
18
18
#include <linux/of.h>
19
+ #include <linux/sizes.h>
19
20
#include <linux/timer.h>
20
21
#include <asm/unaligned.h>
21
22
22
23
#define EXC3000_NUM_SLOTS 10
23
24
#define EXC3000_SLOTS_PER_FRAME 5
24
25
#define EXC3000_LEN_FRAME 66
25
26
#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
+
27
31
#define EXC3000_TIMEOUT_MS 100
28
32
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
+
29
61
struct exc3000_data {
30
62
struct i2c_client * client ;
63
+ const struct eeti_dev_info * info ;
31
64
struct input_dev * input ;
32
65
struct touchscreen_properties prop ;
33
66
struct timer_list timer ;
@@ -58,10 +91,15 @@ static void exc3000_timer(struct timer_list *t)
58
91
input_sync (data -> input );
59
92
}
60
93
61
- static int exc3000_read_frame (struct i2c_client * client , u8 * buf )
94
+ static int exc3000_read_frame (struct exc3000_data * data , u8 * buf )
62
95
{
96
+ struct i2c_client * client = data -> client ;
97
+ u8 expected_event = EXC3000_MT1_EVENT ;
63
98
int ret ;
64
99
100
+ if (data -> info -> max_xy == SZ_16K - 1 )
101
+ expected_event = EXC3000_MT2_EVENT ;
102
+
65
103
ret = i2c_master_send (client , "'" , 2 );
66
104
if (ret < 0 )
67
105
return ret ;
@@ -76,19 +114,21 @@ static int exc3000_read_frame(struct i2c_client *client, u8 *buf)
76
114
if (ret != EXC3000_LEN_FRAME )
77
115
return - EIO ;
78
116
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 )
81
121
return - EINVAL ;
82
122
83
123
return 0 ;
84
124
}
85
125
86
- static int exc3000_read_data (struct i2c_client * client ,
126
+ static int exc3000_read_data (struct exc3000_data * data ,
87
127
u8 * buf , int * n_slots )
88
128
{
89
129
int error ;
90
130
91
- error = exc3000_read_frame (client , buf );
131
+ error = exc3000_read_frame (data , buf );
92
132
if (error )
93
133
return error ;
94
134
@@ -98,7 +138,7 @@ static int exc3000_read_data(struct i2c_client *client,
98
138
99
139
if (* n_slots > EXC3000_SLOTS_PER_FRAME ) {
100
140
/* 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 );
102
142
if (error )
103
143
return error ;
104
144
@@ -118,7 +158,7 @@ static irqreturn_t exc3000_interrupt(int irq, void *dev_id)
118
158
int slots , total_slots ;
119
159
int error ;
120
160
121
- error = exc3000_read_data (data -> client , buf , & total_slots );
161
+ error = exc3000_read_data (data , buf , & total_slots );
122
162
if (error ) {
123
163
/* Schedule a timer to release "stuck" contacts */
124
164
mod_timer (& data -> timer ,
@@ -149,13 +189,19 @@ static int exc3000_probe(struct i2c_client *client)
149
189
{
150
190
struct exc3000_data * data ;
151
191
struct input_dev * input ;
152
- int error ;
192
+ int error , max_xy ;
153
193
154
194
data = devm_kzalloc (& client -> dev , sizeof (* data ), GFP_KERNEL );
155
195
if (!data )
156
196
return - ENOMEM ;
157
197
158
198
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
+ }
159
205
timer_setup (& data -> timer , exc3000_timer , 0 );
160
206
161
207
input = devm_input_allocate_device (& client -> dev );
@@ -164,11 +210,13 @@ static int exc3000_probe(struct i2c_client *client)
164
210
165
211
data -> input = input ;
166
212
167
- input -> name = "EETI EXC3000 Touch Screen" ;
213
+ input -> name = data -> info -> name ;
168
214
input -> id .bustype = BUS_I2C ;
169
215
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
+
172
220
touchscreen_parse_properties (input , true, & data -> prop );
173
221
174
222
error = input_mt_init_slots (input , EXC3000_NUM_SLOTS ,
@@ -190,14 +238,18 @@ static int exc3000_probe(struct i2c_client *client)
190
238
}
191
239
192
240
static const struct i2c_device_id exc3000_id [] = {
193
- { "exc3000" , 0 },
241
+ { "exc3000" , EETI_EXC3000 },
242
+ { "exc80h60" , EETI_EXC80H60 },
243
+ { "exc80h84" , EETI_EXC80H84 },
194
244
{ }
195
245
};
196
246
MODULE_DEVICE_TABLE (i2c , exc3000_id );
197
247
198
248
#ifdef CONFIG_OF
199
249
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 ] },
201
253
{ }
202
254
};
203
255
MODULE_DEVICE_TABLE (of , exc3000_of_match );
0 commit comments