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+
2961struct 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
192240static const struct i2c_device_id exc3000_id [] = {
193- { "exc3000" , 0 },
241+ { "exc3000" , EETI_EXC3000 },
242+ { "exc80h60" , EETI_EXC80H60 },
243+ { "exc80h84" , EETI_EXC80H84 },
194244 { }
195245};
196246MODULE_DEVICE_TABLE (i2c , exc3000_id );
197247
198248#ifdef CONFIG_OF
199249static 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};
203255MODULE_DEVICE_TABLE (of , exc3000_of_match );
0 commit comments