1 #include <linux/module.h>
3 #include <linux/interrupt.h>
4 #include <linux/slab.h>
5 #include <linux/input.h>
6 #include <linux/input/mt.h>
7 #include <linux/delay.h>
8 #include <linux/workqueue.h>
9 #include <linux/input/ili210x.h>
12 #define DEFAULT_POLL_PERIOD 20
14 /* Touchscreen commands */
15 #define REG_TOUCHDATA 0x10
16 #define REG_PANEL_INFO 0x20
17 #define REG_FIRMWARE_VERSION 0x40
18 #define REG_CALIBRATE 0xcc
29 struct finger finger
[MAX_TOUCHES
];
33 struct finger finger_max
;
38 struct firmware_version
{
45 struct i2c_client
*client
;
46 struct input_dev
*input
;
47 bool (*get_pendown_state
)(void);
48 unsigned int poll_period
;
49 struct delayed_work dwork
;
52 static int ili210x_read_reg(struct i2c_client
*client
, u8 reg
, void *buf
,
55 struct i2c_msg msg
[2] = {
70 if (i2c_transfer(client
->adapter
, msg
, 2) != 2) {
71 dev_err(&client
->dev
, "i2c transfer failed\n");
78 static void ili210x_report_events(struct input_dev
*input
,
79 const struct touchdata
*touchdata
)
84 const struct finger
*finger
;
86 for (i
= 0; i
< MAX_TOUCHES
; i
++) {
87 input_mt_slot(input
, i
);
89 finger
= &touchdata
->finger
[i
];
91 touch
= touchdata
->status
& (1 << i
);
92 input_mt_report_slot_state(input
, MT_TOOL_FINGER
, touch
);
94 x
= finger
->x_low
| (finger
->x_high
<< 8);
95 y
= finger
->y_low
| (finger
->y_high
<< 8);
97 input_report_abs(input
, ABS_MT_POSITION_X
, x
);
98 input_report_abs(input
, ABS_MT_POSITION_Y
, y
);
102 input_mt_report_pointer_emulation(input
, false);
106 static bool get_pendown_state(const struct ili210x
*priv
)
110 if (priv
->get_pendown_state
)
111 state
= priv
->get_pendown_state();
116 static void ili210x_work(struct work_struct
*work
)
118 struct ili210x
*priv
= container_of(work
, struct ili210x
,
120 struct i2c_client
*client
= priv
->client
;
121 struct touchdata touchdata
;
124 error
= ili210x_read_reg(client
, REG_TOUCHDATA
,
125 &touchdata
, sizeof(touchdata
));
127 dev_err(&client
->dev
,
128 "Unable to get touchdata, err = %d\n", error
);
132 ili210x_report_events(priv
->input
, &touchdata
);
134 if ((touchdata
.status
& 0xf3) || get_pendown_state(priv
))
135 schedule_delayed_work(&priv
->dwork
,
136 msecs_to_jiffies(priv
->poll_period
));
139 static irqreturn_t
ili210x_irq(int irq
, void *irq_data
)
141 struct ili210x
*priv
= irq_data
;
143 schedule_delayed_work(&priv
->dwork
, 0);
148 static ssize_t
ili210x_calibrate(struct device
*dev
,
149 struct device_attribute
*attr
,
150 const char *buf
, size_t count
)
152 struct i2c_client
*client
= to_i2c_client(dev
);
153 struct ili210x
*priv
= i2c_get_clientdata(client
);
154 unsigned long calibrate
;
156 u8 cmd
= REG_CALIBRATE
;
158 if (kstrtoul(buf
, 10, &calibrate
))
165 rc
= i2c_master_send(priv
->client
, &cmd
, sizeof(cmd
));
166 if (rc
!= sizeof(cmd
))
172 static DEVICE_ATTR(calibrate
, S_IWUSR
, NULL
, ili210x_calibrate
);
174 static struct attribute
*ili210x_attributes
[] = {
175 &dev_attr_calibrate
.attr
,
179 static const struct attribute_group ili210x_attr_group
= {
180 .attrs
= ili210x_attributes
,
183 static int ili210x_i2c_probe(struct i2c_client
*client
,
184 const struct i2c_device_id
*id
)
186 struct device
*dev
= &client
->dev
;
187 const struct ili210x_platform_data
*pdata
= dev_get_platdata(dev
);
188 struct ili210x
*priv
;
189 struct input_dev
*input
;
190 struct panel_info panel
;
191 struct firmware_version firmware
;
195 dev_dbg(dev
, "Probing for ILI210X I2C Touschreen driver");
198 dev_err(dev
, "No platform data!\n");
202 if (client
->irq
<= 0) {
203 dev_err(dev
, "No IRQ!\n");
207 /* Get firmware version */
208 error
= ili210x_read_reg(client
, REG_FIRMWARE_VERSION
,
209 &firmware
, sizeof(firmware
));
211 dev_err(dev
, "Failed to get firmware version, err: %d\n",
217 error
= ili210x_read_reg(client
, REG_PANEL_INFO
, &panel
, sizeof(panel
));
219 dev_err(dev
, "Failed to get panel information, err: %d\n",
224 xmax
= panel
.finger_max
.x_low
| (panel
.finger_max
.x_high
<< 8);
225 ymax
= panel
.finger_max
.y_low
| (panel
.finger_max
.y_high
<< 8);
227 priv
= kzalloc(sizeof(*priv
), GFP_KERNEL
);
228 input
= input_allocate_device();
229 if (!priv
|| !input
) {
234 priv
->client
= client
;
236 priv
->get_pendown_state
= pdata
->get_pendown_state
;
237 priv
->poll_period
= pdata
->poll_period
? : DEFAULT_POLL_PERIOD
;
238 INIT_DELAYED_WORK(&priv
->dwork
, ili210x_work
);
240 /* Setup input device */
241 input
->name
= "ILI210x Touchscreen";
242 input
->id
.bustype
= BUS_I2C
;
243 input
->dev
.parent
= dev
;
245 __set_bit(EV_SYN
, input
->evbit
);
246 __set_bit(EV_KEY
, input
->evbit
);
247 __set_bit(EV_ABS
, input
->evbit
);
248 __set_bit(BTN_TOUCH
, input
->keybit
);
251 input_set_abs_params(input
, ABS_X
, 0, xmax
, 0, 0);
252 input_set_abs_params(input
, ABS_Y
, 0, ymax
, 0, 0);
255 input_mt_init_slots(input
, MAX_TOUCHES
, 0);
256 input_set_abs_params(input
, ABS_MT_POSITION_X
, 0, xmax
, 0, 0);
257 input_set_abs_params(input
, ABS_MT_POSITION_Y
, 0, ymax
, 0, 0);
259 i2c_set_clientdata(client
, priv
);
261 error
= request_irq(client
->irq
, ili210x_irq
, pdata
->irq_flags
,
264 dev_err(dev
, "Unable to request touchscreen IRQ, err: %d\n",
269 error
= sysfs_create_group(&dev
->kobj
, &ili210x_attr_group
);
271 dev_err(dev
, "Unable to create sysfs attributes, err: %d\n",
276 error
= input_register_device(priv
->input
);
278 dev_err(dev
, "Cannot register input device, err: %d\n", error
);
279 goto err_remove_sysfs
;
282 device_init_wakeup(dev
, 1);
285 "ILI210x initialized (IRQ: %d), firmware version %d.%d.%d",
286 client
->irq
, firmware
.id
, firmware
.major
, firmware
.minor
);
291 sysfs_remove_group(&dev
->kobj
, &ili210x_attr_group
);
293 free_irq(client
->irq
, priv
);
295 input_free_device(input
);
300 static int ili210x_i2c_remove(struct i2c_client
*client
)
302 struct ili210x
*priv
= i2c_get_clientdata(client
);
304 sysfs_remove_group(&client
->dev
.kobj
, &ili210x_attr_group
);
305 free_irq(priv
->client
->irq
, priv
);
306 cancel_delayed_work_sync(&priv
->dwork
);
307 input_unregister_device(priv
->input
);
313 static int __maybe_unused
ili210x_i2c_suspend(struct device
*dev
)
315 struct i2c_client
*client
= to_i2c_client(dev
);
317 if (device_may_wakeup(&client
->dev
))
318 enable_irq_wake(client
->irq
);
323 static int __maybe_unused
ili210x_i2c_resume(struct device
*dev
)
325 struct i2c_client
*client
= to_i2c_client(dev
);
327 if (device_may_wakeup(&client
->dev
))
328 disable_irq_wake(client
->irq
);
333 static SIMPLE_DEV_PM_OPS(ili210x_i2c_pm
,
334 ili210x_i2c_suspend
, ili210x_i2c_resume
);
336 static const struct i2c_device_id ili210x_i2c_id
[] = {
340 MODULE_DEVICE_TABLE(i2c
, ili210x_i2c_id
);
342 static struct i2c_driver ili210x_ts_driver
= {
344 .name
= "ili210x_i2c",
345 .pm
= &ili210x_i2c_pm
,
347 .id_table
= ili210x_i2c_id
,
348 .probe
= ili210x_i2c_probe
,
349 .remove
= ili210x_i2c_remove
,
352 module_i2c_driver(ili210x_ts_driver
);
354 MODULE_AUTHOR("Olivier Sobrie <olivier@sobrie.be>");
355 MODULE_DESCRIPTION("ILI210X I2C Touchscreen Driver");
356 MODULE_LICENSE("GPL");