1111#include <linux/property.h>
1212#include <linux/regulator/consumer.h>
1313
14+ #define IST3038B_REG_STATUS 0x20
15+ #define IST3038B_REG_CHIPID 0x30
16+ #define IST3038B_WHOAMI 0x30380b
17+
1418#define IST3038C_HIB_ACCESS (0x800B << 16)
1519#define IST3038C_DIRECT_ACCESS BIT(31)
16- #define IST3038C_REG_CHIPID 0x40001000
20+ #define IST3038C_REG_CHIPID ( 0x40001000 | IST3038C_DIRECT_ACCESS)
1721#define IST3038C_REG_HIB_BASE 0x30000100
1822#define IST3038C_REG_TOUCH_STATUS (IST3038C_REG_HIB_BASE | IST3038C_HIB_ACCESS)
1923#define IST3038C_REG_TOUCH_COORD (IST3038C_REG_HIB_BASE | IST3038C_HIB_ACCESS | 0x8)
3135#define IST3038C_FINGER_COUNT_SHIFT 12
3236#define IST3038C_FINGER_STATUS_MASK GENMASK(9, 0)
3337
38+ struct imagis_properties {
39+ unsigned int interrupt_msg_cmd ;
40+ unsigned int touch_coord_cmd ;
41+ unsigned int whoami_cmd ;
42+ unsigned int whoami_val ;
43+ bool protocol_b ;
44+ };
45+
3446struct imagis_ts {
3547 struct i2c_client * client ;
48+ const struct imagis_properties * tdata ;
3649 struct input_dev * input_dev ;
3750 struct touchscreen_properties prop ;
3851 struct regulator_bulk_data supplies [2 ];
@@ -84,8 +97,7 @@ static irqreturn_t imagis_interrupt(int irq, void *dev_id)
8497 int i ;
8598 int error ;
8699
87- error = imagis_i2c_read_reg (ts , IST3038C_REG_INTR_MESSAGE ,
88- & intr_message );
100+ error = imagis_i2c_read_reg (ts , ts -> tdata -> interrupt_msg_cmd , & intr_message );
89101 if (error ) {
90102 dev_err (& ts -> client -> dev ,
91103 "failed to read the interrupt message: %d\n" , error );
@@ -104,9 +116,13 @@ static irqreturn_t imagis_interrupt(int irq, void *dev_id)
104116 finger_pressed = intr_message & IST3038C_FINGER_STATUS_MASK ;
105117
106118 for (i = 0 ; i < finger_count ; i ++ ) {
107- error = imagis_i2c_read_reg (ts ,
108- IST3038C_REG_TOUCH_COORD + (i * 4 ),
109- & finger_status );
119+ if (ts -> tdata -> protocol_b )
120+ error = imagis_i2c_read_reg (ts ,
121+ ts -> tdata -> touch_coord_cmd , & finger_status );
122+ else
123+ error = imagis_i2c_read_reg (ts ,
124+ ts -> tdata -> touch_coord_cmd + (i * 4 ),
125+ & finger_status );
110126 if (error ) {
111127 dev_err (& ts -> client -> dev ,
112128 "failed to read coordinates for finger %d: %d\n" ,
@@ -261,6 +277,12 @@ static int imagis_probe(struct i2c_client *i2c)
261277
262278 ts -> client = i2c ;
263279
280+ ts -> tdata = device_get_match_data (dev );
281+ if (!ts -> tdata ) {
282+ dev_err (dev , "missing chip data\n" );
283+ return - EINVAL ;
284+ }
285+
264286 error = imagis_init_regulators (ts );
265287 if (error ) {
266288 dev_err (dev , "regulator init error: %d\n" , error );
@@ -279,15 +301,13 @@ static int imagis_probe(struct i2c_client *i2c)
279301 return error ;
280302 }
281303
282- error = imagis_i2c_read_reg (ts ,
283- IST3038C_REG_CHIPID | IST3038C_DIRECT_ACCESS ,
284- & chip_id );
304+ error = imagis_i2c_read_reg (ts , ts -> tdata -> whoami_cmd , & chip_id );
285305 if (error ) {
286306 dev_err (dev , "chip ID read failure: %d\n" , error );
287307 return error ;
288308 }
289309
290- if (chip_id != IST3038C_WHOAMI ) {
310+ if (chip_id != ts -> tdata -> whoami_val ) {
291311 dev_err (dev , "unknown chip ID: 0x%x\n" , chip_id );
292312 return - EINVAL ;
293313 }
@@ -343,9 +363,25 @@ static int imagis_resume(struct device *dev)
343363
344364static DEFINE_SIMPLE_DEV_PM_OPS (imagis_pm_ops , imagis_suspend , imagis_resume ) ;
345365
366+ static const struct imagis_properties imagis_3038b_data = {
367+ .interrupt_msg_cmd = IST3038B_REG_STATUS ,
368+ .touch_coord_cmd = IST3038B_REG_STATUS ,
369+ .whoami_cmd = IST3038B_REG_CHIPID ,
370+ .whoami_val = IST3038B_WHOAMI ,
371+ .protocol_b = true,
372+ };
373+
374+ static const struct imagis_properties imagis_3038c_data = {
375+ .interrupt_msg_cmd = IST3038C_REG_INTR_MESSAGE ,
376+ .touch_coord_cmd = IST3038C_REG_TOUCH_COORD ,
377+ .whoami_cmd = IST3038C_REG_CHIPID ,
378+ .whoami_val = IST3038C_WHOAMI ,
379+ };
380+
346381#ifdef CONFIG_OF
347382static const struct of_device_id imagis_of_match [] = {
348- { .compatible = "imagis,ist3038c" , },
383+ { .compatible = "imagis,ist3038b" , .data = & imagis_3038b_data },
384+ { .compatible = "imagis,ist3038c" , .data = & imagis_3038c_data },
349385 { },
350386};
351387MODULE_DEVICE_TABLE (of , imagis_of_match );
0 commit comments