GNU Linux-libre 4.9.328-gnu1
[releases.git] / drivers / input / touchscreen / ili210x.c
1 #include <linux/module.h>
2 #include <linux/i2c.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>
10
11 #define MAX_TOUCHES             2
12 #define DEFAULT_POLL_PERIOD     20
13
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
19
20 struct finger {
21         u8 x_low;
22         u8 x_high;
23         u8 y_low;
24         u8 y_high;
25 } __packed;
26
27 struct touchdata {
28         u8 status;
29         struct finger finger[MAX_TOUCHES];
30 } __packed;
31
32 struct panel_info {
33         struct finger finger_max;
34         u8 xchannel_num;
35         u8 ychannel_num;
36 } __packed;
37
38 struct firmware_version {
39         u8 id;
40         u8 major;
41         u8 minor;
42 } __packed;
43
44 struct ili210x {
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;
50 };
51
52 static int ili210x_read_reg(struct i2c_client *client, u8 reg, void *buf,
53                             size_t len)
54 {
55         struct i2c_msg msg[2] = {
56                 {
57                         .addr   = client->addr,
58                         .flags  = 0,
59                         .len    = 1,
60                         .buf    = &reg,
61                 },
62                 {
63                         .addr   = client->addr,
64                         .flags  = I2C_M_RD,
65                         .len    = len,
66                         .buf    = buf,
67                 }
68         };
69
70         if (i2c_transfer(client->adapter, msg, 2) != 2) {
71                 dev_err(&client->dev, "i2c transfer failed\n");
72                 return -EIO;
73         }
74
75         return 0;
76 }
77
78 static void ili210x_report_events(struct input_dev *input,
79                                   const struct touchdata *touchdata)
80 {
81         int i;
82         bool touch;
83         unsigned int x, y;
84         const struct finger *finger;
85
86         for (i = 0; i < MAX_TOUCHES; i++) {
87                 input_mt_slot(input, i);
88
89                 finger = &touchdata->finger[i];
90
91                 touch = touchdata->status & (1 << i);
92                 input_mt_report_slot_state(input, MT_TOOL_FINGER, touch);
93                 if (touch) {
94                         x = finger->x_low | (finger->x_high << 8);
95                         y = finger->y_low | (finger->y_high << 8);
96
97                         input_report_abs(input, ABS_MT_POSITION_X, x);
98                         input_report_abs(input, ABS_MT_POSITION_Y, y);
99                 }
100         }
101
102         input_mt_report_pointer_emulation(input, false);
103         input_sync(input);
104 }
105
106 static bool get_pendown_state(const struct ili210x *priv)
107 {
108         bool state = false;
109
110         if (priv->get_pendown_state)
111                 state = priv->get_pendown_state();
112
113         return state;
114 }
115
116 static void ili210x_work(struct work_struct *work)
117 {
118         struct ili210x *priv = container_of(work, struct ili210x,
119                                             dwork.work);
120         struct i2c_client *client = priv->client;
121         struct touchdata touchdata;
122         int error;
123
124         error = ili210x_read_reg(client, REG_TOUCHDATA,
125                                  &touchdata, sizeof(touchdata));
126         if (error) {
127                 dev_err(&client->dev,
128                         "Unable to get touchdata, err = %d\n", error);
129                 return;
130         }
131
132         ili210x_report_events(priv->input, &touchdata);
133
134         if ((touchdata.status & 0xf3) || get_pendown_state(priv))
135                 schedule_delayed_work(&priv->dwork,
136                                       msecs_to_jiffies(priv->poll_period));
137 }
138
139 static irqreturn_t ili210x_irq(int irq, void *irq_data)
140 {
141         struct ili210x *priv = irq_data;
142
143         schedule_delayed_work(&priv->dwork, 0);
144
145         return IRQ_HANDLED;
146 }
147
148 static ssize_t ili210x_calibrate(struct device *dev,
149                                  struct device_attribute *attr,
150                                  const char *buf, size_t count)
151 {
152         struct i2c_client *client = to_i2c_client(dev);
153         struct ili210x *priv = i2c_get_clientdata(client);
154         unsigned long calibrate;
155         int rc;
156         u8 cmd = REG_CALIBRATE;
157
158         if (kstrtoul(buf, 10, &calibrate))
159                 return -EINVAL;
160
161         if (calibrate > 1)
162                 return -EINVAL;
163
164         if (calibrate) {
165                 rc = i2c_master_send(priv->client, &cmd, sizeof(cmd));
166                 if (rc != sizeof(cmd))
167                         return -EIO;
168         }
169
170         return count;
171 }
172 static DEVICE_ATTR(calibrate, S_IWUSR, NULL, ili210x_calibrate);
173
174 static struct attribute *ili210x_attributes[] = {
175         &dev_attr_calibrate.attr,
176         NULL,
177 };
178
179 static const struct attribute_group ili210x_attr_group = {
180         .attrs = ili210x_attributes,
181 };
182
183 static int ili210x_i2c_probe(struct i2c_client *client,
184                                        const struct i2c_device_id *id)
185 {
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;
192         int xmax, ymax;
193         int error;
194
195         dev_dbg(dev, "Probing for ILI210X I2C Touschreen driver");
196
197         if (!pdata) {
198                 dev_err(dev, "No platform data!\n");
199                 return -EINVAL;
200         }
201
202         if (client->irq <= 0) {
203                 dev_err(dev, "No IRQ!\n");
204                 return -EINVAL;
205         }
206
207         /* Get firmware version */
208         error = ili210x_read_reg(client, REG_FIRMWARE_VERSION,
209                                  &firmware, sizeof(firmware));
210         if (error) {
211                 dev_err(dev, "Failed to get firmware version, err: %d\n",
212                         error);
213                 return error;
214         }
215
216         /* get panel info */
217         error = ili210x_read_reg(client, REG_PANEL_INFO, &panel, sizeof(panel));
218         if (error) {
219                 dev_err(dev, "Failed to get panel information, err: %d\n",
220                         error);
221                 return error;
222         }
223
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);
226
227         priv = kzalloc(sizeof(*priv), GFP_KERNEL);
228         input = input_allocate_device();
229         if (!priv || !input) {
230                 error = -ENOMEM;
231                 goto err_free_mem;
232         }
233
234         priv->client = client;
235         priv->input = input;
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);
239
240         /* Setup input device */
241         input->name = "ILI210x Touchscreen";
242         input->id.bustype = BUS_I2C;
243         input->dev.parent = dev;
244
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);
249
250         /* Single touch */
251         input_set_abs_params(input, ABS_X, 0, xmax, 0, 0);
252         input_set_abs_params(input, ABS_Y, 0, ymax, 0, 0);
253
254         /* Multi touch */
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);
258
259         input_set_drvdata(input, priv);
260         i2c_set_clientdata(client, priv);
261
262         error = request_irq(client->irq, ili210x_irq, pdata->irq_flags,
263                             client->name, priv);
264         if (error) {
265                 dev_err(dev, "Unable to request touchscreen IRQ, err: %d\n",
266                         error);
267                 goto err_free_mem;
268         }
269
270         error = sysfs_create_group(&dev->kobj, &ili210x_attr_group);
271         if (error) {
272                 dev_err(dev, "Unable to create sysfs attributes, err: %d\n",
273                         error);
274                 goto err_free_irq;
275         }
276
277         error = input_register_device(priv->input);
278         if (error) {
279                 dev_err(dev, "Cannot register input device, err: %d\n", error);
280                 goto err_remove_sysfs;
281         }
282
283         device_init_wakeup(&client->dev, 1);
284
285         dev_dbg(dev,
286                 "ILI210x initialized (IRQ: %d), firmware version %d.%d.%d",
287                 client->irq, firmware.id, firmware.major, firmware.minor);
288
289         return 0;
290
291 err_remove_sysfs:
292         sysfs_remove_group(&dev->kobj, &ili210x_attr_group);
293 err_free_irq:
294         free_irq(client->irq, priv);
295 err_free_mem:
296         input_free_device(input);
297         kfree(priv);
298         return error;
299 }
300
301 static int ili210x_i2c_remove(struct i2c_client *client)
302 {
303         struct ili210x *priv = i2c_get_clientdata(client);
304
305         sysfs_remove_group(&client->dev.kobj, &ili210x_attr_group);
306         free_irq(priv->client->irq, priv);
307         cancel_delayed_work_sync(&priv->dwork);
308         input_unregister_device(priv->input);
309         kfree(priv);
310
311         return 0;
312 }
313
314 static int __maybe_unused ili210x_i2c_suspend(struct device *dev)
315 {
316         struct i2c_client *client = to_i2c_client(dev);
317
318         if (device_may_wakeup(&client->dev))
319                 enable_irq_wake(client->irq);
320
321         return 0;
322 }
323
324 static int __maybe_unused ili210x_i2c_resume(struct device *dev)
325 {
326         struct i2c_client *client = to_i2c_client(dev);
327
328         if (device_may_wakeup(&client->dev))
329                 disable_irq_wake(client->irq);
330
331         return 0;
332 }
333
334 static SIMPLE_DEV_PM_OPS(ili210x_i2c_pm,
335                          ili210x_i2c_suspend, ili210x_i2c_resume);
336
337 static const struct i2c_device_id ili210x_i2c_id[] = {
338         { "ili210x", 0 },
339         { }
340 };
341 MODULE_DEVICE_TABLE(i2c, ili210x_i2c_id);
342
343 static struct i2c_driver ili210x_ts_driver = {
344         .driver = {
345                 .name = "ili210x_i2c",
346                 .pm = &ili210x_i2c_pm,
347         },
348         .id_table = ili210x_i2c_id,
349         .probe = ili210x_i2c_probe,
350         .remove = ili210x_i2c_remove,
351 };
352
353 module_i2c_driver(ili210x_ts_driver);
354
355 MODULE_AUTHOR("Olivier Sobrie <olivier@sobrie.be>");
356 MODULE_DESCRIPTION("ILI210X I2C Touchscreen Driver");
357 MODULE_LICENSE("GPL");