2727#define EXC3000_LEN_FRAME 66
2828#define EXC3000_LEN_POINT 10
2929
30+ #define EXC3000_LEN_MODEL_NAME 16
31+ #define EXC3000_LEN_FW_VERSION 16
32+
3033#define EXC3000_MT1_EVENT 0x06
3134#define EXC3000_MT2_EVENT 0x18
3235
@@ -71,6 +74,11 @@ struct exc3000_data {
7174 struct gpio_desc * reset ;
7275 struct timer_list timer ;
7376 u8 buf [2 * EXC3000_LEN_FRAME ];
77+ struct completion wait_event ;
78+ struct mutex query_lock ;
79+ int query_result ;
80+ char model [EXC3000_LEN_MODEL_NAME ];
81+ char fw_version [EXC3000_LEN_FW_VERSION ];
7482};
7583
7684static void exc3000_report_slots (struct input_dev * input ,
@@ -156,6 +164,28 @@ static int exc3000_read_data(struct exc3000_data *data,
156164 return 0 ;
157165}
158166
167+ static int exc3000_query_interrupt (struct exc3000_data * data )
168+ {
169+ u8 * buf = data -> buf ;
170+ int error ;
171+
172+ error = i2c_master_recv (data -> client , buf , EXC3000_LEN_FRAME );
173+ if (error < 0 )
174+ return error ;
175+
176+ if (buf [0 ] != 'B' )
177+ return - EPROTO ;
178+
179+ if (buf [4 ] == 'E' )
180+ strlcpy (data -> model , buf + 5 , sizeof (data -> model ));
181+ else if (buf [4 ] == 'D' )
182+ strlcpy (data -> fw_version , buf + 5 , sizeof (data -> fw_version ));
183+ else
184+ return - EPROTO ;
185+
186+ return 0 ;
187+ }
188+
159189static irqreturn_t exc3000_interrupt (int irq , void * dev_id )
160190{
161191 struct exc3000_data * data = dev_id ;
@@ -164,6 +194,12 @@ static irqreturn_t exc3000_interrupt(int irq, void *dev_id)
164194 int slots , total_slots ;
165195 int error ;
166196
197+ if (mutex_is_locked (& data -> query_lock )) {
198+ data -> query_result = exc3000_query_interrupt (data );
199+ complete (& data -> wait_event );
200+ goto out ;
201+ }
202+
167203 error = exc3000_read_data (data , buf , & total_slots );
168204 if (error ) {
169205 /* Schedule a timer to release "stuck" contacts */
@@ -191,11 +227,91 @@ static irqreturn_t exc3000_interrupt(int irq, void *dev_id)
191227 return IRQ_HANDLED ;
192228}
193229
230+ static ssize_t fw_version_show (struct device * dev ,
231+ struct device_attribute * attr , char * buf )
232+ {
233+ struct i2c_client * client = to_i2c_client (dev );
234+ struct exc3000_data * data = i2c_get_clientdata (client );
235+ static const u8 request [68 ] = {
236+ 0x67 , 0x00 , 0x42 , 0x00 , 0x03 , 0x01 , 'D' , 0x00
237+ };
238+ int error ;
239+
240+ mutex_lock (& data -> query_lock );
241+
242+ data -> query_result = - ETIMEDOUT ;
243+ reinit_completion (& data -> wait_event );
244+
245+ error = i2c_master_send (client , request , sizeof (request ));
246+ if (error < 0 ) {
247+ mutex_unlock (& data -> query_lock );
248+ return error ;
249+ }
250+
251+ wait_for_completion_interruptible_timeout (& data -> wait_event , 1 * HZ );
252+ mutex_unlock (& data -> query_lock );
253+
254+ if (data -> query_result < 0 )
255+ return data -> query_result ;
256+
257+ return sprintf (buf , "%s\n" , data -> fw_version );
258+ }
259+ static DEVICE_ATTR_RO (fw_version );
260+
261+ static ssize_t exc3000_get_model (struct exc3000_data * data )
262+ {
263+ static const u8 request [68 ] = {
264+ 0x67 , 0x00 , 0x42 , 0x00 , 0x03 , 0x01 , 'E' , 0x00
265+ };
266+ struct i2c_client * client = data -> client ;
267+ int error ;
268+
269+ mutex_lock (& data -> query_lock );
270+ data -> query_result = - ETIMEDOUT ;
271+ reinit_completion (& data -> wait_event );
272+
273+ error = i2c_master_send (client , request , sizeof (request ));
274+ if (error < 0 ) {
275+ mutex_unlock (& data -> query_lock );
276+ return error ;
277+ }
278+
279+ wait_for_completion_interruptible_timeout (& data -> wait_event , 1 * HZ );
280+ mutex_unlock (& data -> query_lock );
281+
282+ return data -> query_result ;
283+ }
284+
285+ static ssize_t model_show (struct device * dev ,
286+ struct device_attribute * attr , char * buf )
287+ {
288+ struct i2c_client * client = to_i2c_client (dev );
289+ struct exc3000_data * data = i2c_get_clientdata (client );
290+ int error ;
291+
292+ error = exc3000_get_model (data );
293+ if (error < 0 )
294+ return error ;
295+
296+ return sprintf (buf , "%s\n" , data -> model );
297+ }
298+ static DEVICE_ATTR_RO (model );
299+
300+ static struct attribute * sysfs_attrs [] = {
301+ & dev_attr_fw_version .attr ,
302+ & dev_attr_model .attr ,
303+ NULL
304+ };
305+
306+ static struct attribute_group exc3000_attribute_group = {
307+ .attrs = sysfs_attrs
308+ };
309+
194310static int exc3000_probe (struct i2c_client * client )
195311{
196312 struct exc3000_data * data ;
197313 struct input_dev * input ;
198- int error , max_xy ;
314+ int error , max_xy , retry ;
199315
200316 data = devm_kzalloc (& client -> dev , sizeof (* data ), GFP_KERNEL );
201317 if (!data )
@@ -209,6 +325,8 @@ static int exc3000_probe(struct i2c_client *client)
209325 data -> info = & exc3000_info [eeti_dev_id ];
210326 }
211327 timer_setup (& data -> timer , exc3000_timer , 0 );
328+ init_completion (& data -> wait_event );
329+ mutex_init (& data -> query_lock );
212330
213331 data -> reset = devm_gpiod_get_optional (& client -> dev , "reset" ,
214332 GPIOD_OUT_HIGH );
@@ -226,6 +344,7 @@ static int exc3000_probe(struct i2c_client *client)
226344 return - ENOMEM ;
227345
228346 data -> input = input ;
347+ input_set_drvdata (input , data );
229348
230349 input -> name = data -> info -> name ;
231350 input -> id .bustype = BUS_I2C ;
@@ -251,6 +370,33 @@ static int exc3000_probe(struct i2c_client *client)
251370 if (error )
252371 return error ;
253372
373+ /*
374+ * I²C does not have built-in recovery, so retry on failure. This
375+ * ensures, that the device probe will not fail for temporary issues
376+ * on the bus. This is not needed for the sysfs calls (userspace
377+ * will receive the error code and can start another query) and
378+ * cannot be done for touch events (but that only means loosing one
379+ * or two touch events anyways).
380+ */
381+ for (retry = 0 ; retry < 3 ; retry ++ ) {
382+ error = exc3000_get_model (data );
383+ if (!error )
384+ break ;
385+ dev_warn (& client -> dev , "Retry %d get EETI EXC3000 model: %d\n" ,
386+ retry + 1 , error );
387+ }
388+
389+ if (error )
390+ return error ;
391+
392+ dev_dbg (& client -> dev , "TS Model: %s" , data -> model );
393+
394+ i2c_set_clientdata (client , data );
395+
396+ error = devm_device_add_group (& client -> dev , & exc3000_attribute_group );
397+ if (error )
398+ return error ;
399+
254400 return 0 ;
255401}
256402
0 commit comments