Skip to content

Commit eb91ecc

Browse files
Marek Vasutdtor
authored andcommitted
Input: ili210x - add ILI2117 support
Add support for ILI2117 touch controller. This controller is similar to the ILI210x and ILI251x, except for the following differences: - Reading out of touch data must happen at most 300 mS after the interrupt line was asserted. No command must be sent, the data are returned upon pure I2C read of 43 bytes long. - Supports 10 simultaneous touch inputs. - Touch data format is slightly different. Signed-off-by: Marek Vasut <[email protected]> Reviewed-by: Rob Herring <[email protected]> # for DT binding Tested-by: Adam Ford <[email protected]> #imx6q-logicpd Tested-by: Sven Van Asbroeck <[email protected]> # ILI2118A variant Signed-off-by: Dmitry Torokhov <[email protected]>
1 parent 4d856f7 commit eb91ecc

File tree

2 files changed

+47
-2
lines changed

2 files changed

+47
-2
lines changed

Documentation/devicetree/bindings/input/ilitek,ili2xxx.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1-
Ilitek ILI210x/ILI251x touchscreen controller
1+
Ilitek ILI210x/ILI2117/ILI251x touchscreen controller
22

33
Required properties:
44
- compatible:
55
ilitek,ili210x for ILI210x
6+
ilitek,ili2117 for ILI2117
67
ilitek,ili251x for ILI251x
78

89
- reg: The I2C address of the device

drivers/input/touchscreen/ili210x.c

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include <asm/unaligned.h>
1414

1515
#define ILI210X_TOUCHES 2
16+
#define ILI211X_TOUCHES 10
1617
#define ILI251X_TOUCHES 10
1718
#define DEFAULT_POLL_PERIOD 20
1819

@@ -30,6 +31,7 @@ struct firmware_version {
3031

3132
enum ili2xxx_model {
3233
MODEL_ILI210X,
34+
MODEL_ILI211X,
3335
MODEL_ILI251X,
3436
};
3537

@@ -118,6 +120,27 @@ static bool ili210x_touchdata_to_coords(struct ili210x *priv, u8 *touchdata,
118120
return true;
119121
}
120122

123+
static bool ili211x_touchdata_to_coords(struct ili210x *priv, u8 *touchdata,
124+
unsigned int finger,
125+
unsigned int *x, unsigned int *y)
126+
{
127+
u32 data;
128+
129+
if (finger >= ILI211X_TOUCHES)
130+
return false;
131+
132+
data = get_unaligned_be32(touchdata + 1 + (finger * 4) + 0);
133+
if (data == 0xffffffff) /* Finger up */
134+
return false;
135+
136+
*x = ((touchdata[1 + (finger * 4) + 0] & 0xf0) << 4) |
137+
touchdata[1 + (finger * 4) + 1];
138+
*y = ((touchdata[1 + (finger * 4) + 0] & 0x0f) << 8) |
139+
touchdata[1 + (finger * 4) + 2];
140+
141+
return true;
142+
}
143+
121144
static bool ili251x_touchdata_to_coords(struct ili210x *priv, u8 *touchdata,
122145
unsigned int finger,
123146
unsigned int *x, unsigned int *y)
@@ -146,6 +169,9 @@ static bool ili210x_report_events(struct ili210x *priv, u8 *touchdata)
146169
if (priv->model == MODEL_ILI210X) {
147170
touch = ili210x_touchdata_to_coords(priv, touchdata,
148171
i, &x, &y);
172+
} else if (priv->model == MODEL_ILI211X) {
173+
touch = ili211x_touchdata_to_coords(priv, touchdata,
174+
i, &x, &y);
149175
} else if (priv->model == MODEL_ILI251X) {
150176
touch = ili251x_touchdata_to_coords(priv, touchdata,
151177
i, &x, &y);
@@ -176,12 +202,26 @@ static void ili210x_work(struct work_struct *work)
176202
dwork.work);
177203
struct i2c_client *client = priv->client;
178204
u8 touchdata[64] = { 0 };
205+
s16 sum = 0;
179206
bool touch;
180-
int error = -EINVAL;
207+
int i, error = -EINVAL;
181208

182209
if (priv->model == MODEL_ILI210X) {
183210
error = ili210x_read_reg(client, REG_TOUCHDATA,
184211
touchdata, sizeof(touchdata));
212+
} else if (priv->model == MODEL_ILI211X) {
213+
error = ili210x_read(client, touchdata, 43);
214+
if (!error) {
215+
/* This chip uses custom checksum at the end of data */
216+
for (i = 0; i <= 41; i++)
217+
sum = (sum + touchdata[i]) & 0xff;
218+
if ((-sum & 0xff) != touchdata[42]) {
219+
dev_err(&client->dev,
220+
"CRC error (crc=0x%02x expected=0x%02x)\n",
221+
sum, touchdata[42]);
222+
return;
223+
}
224+
}
185225
} else if (priv->model == MODEL_ILI251X) {
186226
error = ili210x_read_reg(client, REG_TOUCHDATA,
187227
touchdata, 31);
@@ -311,6 +351,8 @@ static int ili210x_i2c_probe(struct i2c_client *client,
311351
priv->model = model;
312352
if (model == MODEL_ILI210X)
313353
priv->max_touches = ILI210X_TOUCHES;
354+
if (model == MODEL_ILI211X)
355+
priv->max_touches = ILI211X_TOUCHES;
314356
if (model == MODEL_ILI251X)
315357
priv->max_touches = ILI251X_TOUCHES;
316358

@@ -395,13 +437,15 @@ static SIMPLE_DEV_PM_OPS(ili210x_i2c_pm,
395437

396438
static const struct i2c_device_id ili210x_i2c_id[] = {
397439
{ "ili210x", MODEL_ILI210X },
440+
{ "ili2117", MODEL_ILI211X },
398441
{ "ili251x", MODEL_ILI251X },
399442
{ }
400443
};
401444
MODULE_DEVICE_TABLE(i2c, ili210x_i2c_id);
402445

403446
static const struct of_device_id ili210x_dt_ids[] = {
404447
{ .compatible = "ilitek,ili210x", .data = (void *)MODEL_ILI210X },
448+
{ .compatible = "ilitek,ili2117", .data = (void *)MODEL_ILI211X },
405449
{ .compatible = "ilitek,ili251x", .data = (void *)MODEL_ILI251X },
406450
{ },
407451
};

0 commit comments

Comments
 (0)