22
22
/* Touchscreen commands */
23
23
#define REG_TOUCHDATA 0x10
24
24
#define REG_PANEL_INFO 0x20
25
+ #define REG_FIRMWARE_VERSION 0x40
26
+ #define REG_PROTOCOL_VERSION 0x42
27
+ #define REG_KERNEL_VERSION 0x61
28
+ #define REG_GET_MODE 0xc0
29
+ #define REG_GET_MODE_AP 0x5a
30
+ #define REG_GET_MODE_BL 0x55
25
31
#define REG_CALIBRATE 0xcc
26
32
27
33
struct ili2xxx_chip {
@@ -45,6 +51,10 @@ struct ili210x {
45
51
struct gpio_desc * reset_gpio ;
46
52
struct touchscreen_properties prop ;
47
53
const struct ili2xxx_chip * chip ;
54
+ u8 version_firmware [8 ];
55
+ u8 version_kernel [5 ];
56
+ u8 version_proto [2 ];
57
+ u8 ic_mode [2 ];
48
58
bool stop ;
49
59
};
50
60
@@ -353,6 +363,69 @@ static int ili251x_firmware_update_resolution(struct device *dev)
353
363
return 0 ;
354
364
}
355
365
366
+ static ssize_t ili251x_firmware_update_firmware_version (struct device * dev )
367
+ {
368
+ struct i2c_client * client = to_i2c_client (dev );
369
+ struct ili210x * priv = i2c_get_clientdata (client );
370
+ int error ;
371
+ u8 fw [8 ];
372
+
373
+ /* Get firmware version */
374
+ error = priv -> chip -> read_reg (client , REG_FIRMWARE_VERSION ,
375
+ & fw , sizeof (fw ));
376
+ if (!error )
377
+ memcpy (priv -> version_firmware , fw , sizeof (fw ));
378
+
379
+ return error ;
380
+ }
381
+
382
+ static ssize_t ili251x_firmware_update_kernel_version (struct device * dev )
383
+ {
384
+ struct i2c_client * client = to_i2c_client (dev );
385
+ struct ili210x * priv = i2c_get_clientdata (client );
386
+ int error ;
387
+ u8 kv [5 ];
388
+
389
+ /* Get kernel version */
390
+ error = priv -> chip -> read_reg (client , REG_KERNEL_VERSION ,
391
+ & kv , sizeof (kv ));
392
+ if (!error )
393
+ memcpy (priv -> version_kernel , kv , sizeof (kv ));
394
+
395
+ return error ;
396
+ }
397
+
398
+ static ssize_t ili251x_firmware_update_protocol_version (struct device * dev )
399
+ {
400
+ struct i2c_client * client = to_i2c_client (dev );
401
+ struct ili210x * priv = i2c_get_clientdata (client );
402
+ int error ;
403
+ u8 pv [2 ];
404
+
405
+ /* Get protocol version */
406
+ error = priv -> chip -> read_reg (client , REG_PROTOCOL_VERSION ,
407
+ & pv , sizeof (pv ));
408
+ if (!error )
409
+ memcpy (priv -> version_proto , pv , sizeof (pv ));
410
+
411
+ return error ;
412
+ }
413
+
414
+ static ssize_t ili251x_firmware_update_ic_mode (struct device * dev )
415
+ {
416
+ struct i2c_client * client = to_i2c_client (dev );
417
+ struct ili210x * priv = i2c_get_clientdata (client );
418
+ int error ;
419
+ u8 md [2 ];
420
+
421
+ /* Get chip boot mode */
422
+ error = priv -> chip -> read_reg (client , REG_GET_MODE , & md , sizeof (md ));
423
+ if (!error )
424
+ memcpy (priv -> ic_mode , md , sizeof (md ));
425
+
426
+ return error ;
427
+ }
428
+
356
429
static int ili251x_firmware_update_cached_state (struct device * dev )
357
430
{
358
431
struct i2c_client * client = to_i2c_client (dev );
@@ -370,9 +443,83 @@ static int ili251x_firmware_update_cached_state(struct device *dev)
370
443
if (error )
371
444
return error ;
372
445
446
+ error = ili251x_firmware_update_firmware_version (dev );
447
+ if (error )
448
+ return error ;
449
+
450
+ error = ili251x_firmware_update_kernel_version (dev );
451
+ if (error )
452
+ return error ;
453
+
454
+ error = ili251x_firmware_update_protocol_version (dev );
455
+ if (error )
456
+ return error ;
457
+
458
+ error = ili251x_firmware_update_ic_mode (dev );
459
+ if (error )
460
+ return error ;
461
+
373
462
return 0 ;
374
463
}
375
464
465
+ static ssize_t ili251x_firmware_version_show (struct device * dev ,
466
+ struct device_attribute * attr ,
467
+ char * buf )
468
+ {
469
+ struct i2c_client * client = to_i2c_client (dev );
470
+ struct ili210x * priv = i2c_get_clientdata (client );
471
+ u8 * fw = priv -> version_firmware ;
472
+
473
+ return sysfs_emit (buf , "%02x%02x.%02x%02x.%02x%02x.%02x%02x\n" ,
474
+ fw [0 ], fw [1 ], fw [2 ], fw [3 ],
475
+ fw [4 ], fw [5 ], fw [6 ], fw [7 ]);
476
+ }
477
+ static DEVICE_ATTR (firmware_version , 0444 , ili251x_firmware_version_show , NULL) ;
478
+
479
+ static ssize_t ili251x_kernel_version_show (struct device * dev ,
480
+ struct device_attribute * attr ,
481
+ char * buf )
482
+ {
483
+ struct i2c_client * client = to_i2c_client (dev );
484
+ struct ili210x * priv = i2c_get_clientdata (client );
485
+ u8 * kv = priv -> version_kernel ;
486
+
487
+ return sysfs_emit (buf , "%02x.%02x.%02x.%02x.%02x\n" ,
488
+ kv [0 ], kv [1 ], kv [2 ], kv [3 ], kv [4 ]);
489
+ }
490
+ static DEVICE_ATTR (kernel_version , 0444 , ili251x_kernel_version_show , NULL) ;
491
+
492
+ static ssize_t ili251x_protocol_version_show (struct device * dev ,
493
+ struct device_attribute * attr ,
494
+ char * buf )
495
+ {
496
+ struct i2c_client * client = to_i2c_client (dev );
497
+ struct ili210x * priv = i2c_get_clientdata (client );
498
+ u8 * pv = priv -> version_proto ;
499
+
500
+ return sysfs_emit (buf , "%02x.%02x\n" , pv [0 ], pv [1 ]);
501
+ }
502
+ static DEVICE_ATTR (protocol_version , 0444 , ili251x_protocol_version_show , NULL) ;
503
+
504
+ static ssize_t ili251x_mode_show (struct device * dev ,
505
+ struct device_attribute * attr , char * buf )
506
+ {
507
+ struct i2c_client * client = to_i2c_client (dev );
508
+ struct ili210x * priv = i2c_get_clientdata (client );
509
+ u8 * md = priv -> ic_mode ;
510
+ char * mode = "AP" ;
511
+
512
+ if (md [0 ] == REG_GET_MODE_AP ) /* Application Mode */
513
+ mode = "AP" ;
514
+ else if (md [0 ] == REG_GET_MODE_BL ) /* BootLoader Mode */
515
+ mode = "BL" ;
516
+ else /* Unknown Mode */
517
+ mode = "??" ;
518
+
519
+ return sysfs_emit (buf , "%02x.%02x:%s\n" , md [0 ], md [1 ], mode );
520
+ }
521
+ static DEVICE_ATTR (mode , 0444 , ili251x_mode_show , NULL) ;
522
+
376
523
static ssize_t ili210x_calibrate (struct device * dev ,
377
524
struct device_attribute * attr ,
378
525
const char * buf , size_t count )
@@ -401,22 +548,34 @@ static DEVICE_ATTR(calibrate, S_IWUSR, NULL, ili210x_calibrate);
401
548
402
549
static struct attribute * ili210x_attributes [] = {
403
550
& dev_attr_calibrate .attr ,
551
+ & dev_attr_firmware_version .attr ,
552
+ & dev_attr_kernel_version .attr ,
553
+ & dev_attr_protocol_version .attr ,
554
+ & dev_attr_mode .attr ,
404
555
NULL ,
405
556
};
406
557
407
- static umode_t ili210x_calibrate_visible (struct kobject * kobj ,
558
+ static umode_t ili210x_attributes_visible (struct kobject * kobj ,
408
559
struct attribute * attr , int index )
409
560
{
410
561
struct device * dev = kobj_to_dev (kobj );
411
562
struct i2c_client * client = to_i2c_client (dev );
412
563
struct ili210x * priv = i2c_get_clientdata (client );
413
564
414
- return priv -> chip -> has_calibrate_reg ? attr -> mode : 0 ;
565
+ /* Calibrate is present on all ILI2xxx which have calibrate register */
566
+ if (attr == & dev_attr_calibrate .attr )
567
+ return priv -> chip -> has_calibrate_reg ? attr -> mode : 0 ;
568
+
569
+ /* Firmware/Kernel/Protocol/BootMode is implememted only for ILI251x */
570
+ if (!priv -> chip -> has_firmware_proto )
571
+ return 0 ;
572
+
573
+ return attr -> mode ;
415
574
}
416
575
417
576
static const struct attribute_group ili210x_attr_group = {
418
577
.attrs = ili210x_attributes ,
419
- .is_visible = ili210x_calibrate_visible ,
578
+ .is_visible = ili210x_attributes_visible ,
420
579
};
421
580
422
581
static void ili210x_power_down (void * data )
0 commit comments