Linux-libre 3.0.32-gnu1
[librecmc/linux-libre.git] / drivers / input / touchscreen / tps6507x-ts.c
1 /*
2  * drivers/input/touchscreen/tps6507x_ts.c
3  *
4  * Touchscreen driver for the tps6507x chip.
5  *
6  * Copyright (c) 2009 RidgeRun (todd.fischer@ridgerun.com)
7  *
8  * Credits:
9  *
10  *    Using code from tsc2007, MtekVision Co., Ltd.
11  *
12  * For licencing details see kernel-base/COPYING
13  *
14  * TPS65070, TPS65073, TPS650731, and TPS650732 support
15  * 10 bit touch screen interface.
16  */
17
18 #include <linux/module.h>
19 #include <linux/workqueue.h>
20 #include <linux/slab.h>
21 #include <linux/input.h>
22 #include <linux/platform_device.h>
23 #include <linux/mfd/tps6507x.h>
24 #include <linux/input/tps6507x-ts.h>
25 #include <linux/delay.h>
26
27 #define TSC_DEFAULT_POLL_PERIOD 30 /* ms */
28 #define TPS_DEFAULT_MIN_PRESSURE 0x30
29 #define MAX_10BIT ((1 << 10) - 1)
30
31 #define TPS6507X_ADCONFIG_CONVERT_TS (TPS6507X_ADCONFIG_AD_ENABLE | \
32                                          TPS6507X_ADCONFIG_START_CONVERSION | \
33                                          TPS6507X_ADCONFIG_INPUT_REAL_TSC)
34 #define TPS6507X_ADCONFIG_POWER_DOWN_TS (TPS6507X_ADCONFIG_INPUT_REAL_TSC)
35
36 struct ts_event {
37         u16     x;
38         u16     y;
39         u16     pressure;
40 };
41
42 struct tps6507x_ts {
43         struct input_dev        *input_dev;
44         struct device           *dev;
45         char                    phys[32];
46         struct delayed_work     work;
47         unsigned                polling;        /* polling is active */
48         struct ts_event         tc;
49         struct tps6507x_dev     *mfd;
50         u16                     model;
51         unsigned                pendown;
52         int                     irq;
53         void                    (*clear_penirq)(void);
54         unsigned long           poll_period;    /* ms */
55         u16                     min_pressure;
56         int                     vref;           /* non-zero to leave vref on */
57 };
58
59 static int tps6507x_read_u8(struct tps6507x_ts *tsc, u8 reg, u8 *data)
60 {
61         int err;
62
63         err = tsc->mfd->read_dev(tsc->mfd, reg, 1, data);
64
65         if (err)
66                 return err;
67
68         return 0;
69 }
70
71 static int tps6507x_write_u8(struct tps6507x_ts *tsc, u8 reg, u8 data)
72 {
73         return tsc->mfd->write_dev(tsc->mfd, reg, 1, &data);
74 }
75
76 static s32 tps6507x_adc_conversion(struct tps6507x_ts *tsc,
77                                    u8 tsc_mode, u16 *value)
78 {
79         s32 ret;
80         u8 adc_status;
81         u8 result;
82
83         /* Route input signal to A/D converter */
84
85         ret = tps6507x_write_u8(tsc, TPS6507X_REG_TSCMODE, tsc_mode);
86         if (ret) {
87                 dev_err(tsc->dev, "TSC mode read failed\n");
88                 goto err;
89         }
90
91         /* Start A/D conversion */
92
93         ret = tps6507x_write_u8(tsc, TPS6507X_REG_ADCONFIG,
94                                 TPS6507X_ADCONFIG_CONVERT_TS);
95         if (ret) {
96                 dev_err(tsc->dev, "ADC config write failed\n");
97                 return ret;
98         }
99
100         do {
101                 ret = tps6507x_read_u8(tsc, TPS6507X_REG_ADCONFIG,
102                                        &adc_status);
103                 if (ret) {
104                         dev_err(tsc->dev, "ADC config read failed\n");
105                         goto err;
106                 }
107         } while (adc_status & TPS6507X_ADCONFIG_START_CONVERSION);
108
109         ret = tps6507x_read_u8(tsc, TPS6507X_REG_ADRESULT_2, &result);
110         if (ret) {
111                 dev_err(tsc->dev, "ADC result 2 read failed\n");
112                 goto err;
113         }
114
115         *value = (result & TPS6507X_REG_ADRESULT_2_MASK) << 8;
116
117         ret = tps6507x_read_u8(tsc, TPS6507X_REG_ADRESULT_1, &result);
118         if (ret) {
119                 dev_err(tsc->dev, "ADC result 1 read failed\n");
120                 goto err;
121         }
122
123         *value |= result;
124
125         dev_dbg(tsc->dev, "TSC channel %d = 0x%X\n", tsc_mode, *value);
126
127 err:
128         return ret;
129 }
130
131 /* Need to call tps6507x_adc_standby() after using A/D converter for the
132  * touch screen interrupt to work properly.
133  */
134
135 static s32 tps6507x_adc_standby(struct tps6507x_ts *tsc)
136 {
137         s32 ret;
138         s32 loops = 0;
139         u8 val;
140
141         ret = tps6507x_write_u8(tsc,  TPS6507X_REG_ADCONFIG,
142                                 TPS6507X_ADCONFIG_INPUT_TSC);
143         if (ret)
144                 return ret;
145
146         ret = tps6507x_write_u8(tsc, TPS6507X_REG_TSCMODE,
147                                 TPS6507X_TSCMODE_STANDBY);
148         if (ret)
149                 return ret;
150
151         ret = tps6507x_read_u8(tsc, TPS6507X_REG_INT, &val);
152         if (ret)
153                 return ret;
154
155         while (val & TPS6507X_REG_TSC_INT) {
156                 mdelay(10);
157                 ret = tps6507x_read_u8(tsc, TPS6507X_REG_INT, &val);
158                 if (ret)
159                         return ret;
160                 loops++;
161         }
162
163         return ret;
164 }
165
166 static void tps6507x_ts_handler(struct work_struct *work)
167 {
168         struct tps6507x_ts *tsc =  container_of(work,
169                                 struct tps6507x_ts, work.work);
170         struct input_dev *input_dev = tsc->input_dev;
171         int pendown;
172         int schd;
173         int poll = 0;
174         s32 ret;
175
176         ret =  tps6507x_adc_conversion(tsc, TPS6507X_TSCMODE_PRESSURE,
177                                        &tsc->tc.pressure);
178         if (ret)
179                 goto done;
180
181         pendown = tsc->tc.pressure > tsc->min_pressure;
182
183         if (unlikely(!pendown && tsc->pendown)) {
184                 dev_dbg(tsc->dev, "UP\n");
185                 input_report_key(input_dev, BTN_TOUCH, 0);
186                 input_report_abs(input_dev, ABS_PRESSURE, 0);
187                 input_sync(input_dev);
188                 tsc->pendown = 0;
189         }
190
191         if (pendown) {
192
193                 if (!tsc->pendown) {
194                         dev_dbg(tsc->dev, "DOWN\n");
195                         input_report_key(input_dev, BTN_TOUCH, 1);
196                 } else
197                         dev_dbg(tsc->dev, "still down\n");
198
199                 ret =  tps6507x_adc_conversion(tsc, TPS6507X_TSCMODE_X_POSITION,
200                                                &tsc->tc.x);
201                 if (ret)
202                         goto done;
203
204                 ret =  tps6507x_adc_conversion(tsc, TPS6507X_TSCMODE_Y_POSITION,
205                                                &tsc->tc.y);
206                 if (ret)
207                         goto done;
208
209                 input_report_abs(input_dev, ABS_X, tsc->tc.x);
210                 input_report_abs(input_dev, ABS_Y, tsc->tc.y);
211                 input_report_abs(input_dev, ABS_PRESSURE, tsc->tc.pressure);
212                 input_sync(input_dev);
213                 tsc->pendown = 1;
214                 poll = 1;
215         }
216
217 done:
218         /* always poll if not using interrupts */
219         poll = 1;
220
221         if (poll) {
222                 schd = schedule_delayed_work(&tsc->work,
223                                         msecs_to_jiffies(tsc->poll_period));
224                 if (schd)
225                         tsc->polling = 1;
226                 else {
227                         tsc->polling = 0;
228                         dev_err(tsc->dev, "re-schedule failed");
229                 }
230         } else
231                 tsc->polling = 0;
232
233         ret = tps6507x_adc_standby(tsc);
234 }
235
236 static int tps6507x_ts_probe(struct platform_device *pdev)
237 {
238         int error;
239         struct tps6507x_ts *tsc;
240         struct tps6507x_dev *tps6507x_dev = dev_get_drvdata(pdev->dev.parent);
241         struct touchscreen_init_data *init_data;
242         struct input_dev *input_dev;
243         struct tps6507x_board *tps_board;
244         int schd;
245
246         /**
247          * tps_board points to pmic related constants
248          * coming from the board-evm file.
249          */
250
251         tps_board = (struct tps6507x_board *)tps6507x_dev->dev->platform_data;
252
253         if (!tps_board) {
254                 dev_err(tps6507x_dev->dev,
255                         "Could not find tps6507x platform data\n");
256                 return -EIO;
257         }
258
259         /**
260          * init_data points to array of regulator_init structures
261          * coming from the board-evm file.
262          */
263
264         init_data = tps_board->tps6507x_ts_init_data;
265
266         tsc = kzalloc(sizeof(struct tps6507x_ts), GFP_KERNEL);
267         if (!tsc) {
268                 dev_err(tps6507x_dev->dev, "failed to allocate driver data\n");
269                 error = -ENOMEM;
270                 goto err0;
271         }
272
273         tps6507x_dev->ts = tsc;
274         tsc->mfd = tps6507x_dev;
275         tsc->dev = tps6507x_dev->dev;
276         input_dev = input_allocate_device();
277         if (!input_dev) {
278                 dev_err(tsc->dev, "Failed to allocate input device.\n");
279                 error = -ENOMEM;
280                 goto err1;
281         }
282
283         input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
284         input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
285
286         input_set_abs_params(input_dev, ABS_X, 0, MAX_10BIT, 0, 0);
287         input_set_abs_params(input_dev, ABS_Y, 0, MAX_10BIT, 0, 0);
288         input_set_abs_params(input_dev, ABS_PRESSURE, 0, MAX_10BIT, 0, 0);
289
290         input_dev->name = "TPS6507x Touchscreen";
291         input_dev->id.bustype = BUS_I2C;
292         input_dev->dev.parent = tsc->dev;
293
294         snprintf(tsc->phys, sizeof(tsc->phys),
295                  "%s/input0", dev_name(tsc->dev));
296         input_dev->phys = tsc->phys;
297
298         dev_dbg(tsc->dev, "device: %s\n", input_dev->phys);
299
300         input_set_drvdata(input_dev, tsc);
301
302         tsc->input_dev = input_dev;
303
304         INIT_DELAYED_WORK(&tsc->work, tps6507x_ts_handler);
305
306         if (init_data) {
307                 tsc->poll_period = init_data->poll_period;
308                 tsc->vref = init_data->vref;
309                 tsc->min_pressure = init_data->min_pressure;
310                 input_dev->id.vendor = init_data->vendor;
311                 input_dev->id.product = init_data->product;
312                 input_dev->id.version = init_data->version;
313         } else {
314                 tsc->poll_period = TSC_DEFAULT_POLL_PERIOD;
315                 tsc->min_pressure = TPS_DEFAULT_MIN_PRESSURE;
316         }
317
318         error = tps6507x_adc_standby(tsc);
319         if (error)
320                 goto err2;
321
322         error = input_register_device(input_dev);
323         if (error)
324                 goto err2;
325
326         schd = schedule_delayed_work(&tsc->work,
327                                      msecs_to_jiffies(tsc->poll_period));
328
329         if (schd)
330                 tsc->polling = 1;
331         else {
332                 tsc->polling = 0;
333                 dev_err(tsc->dev, "schedule failed");
334                 goto err2;
335          }
336         platform_set_drvdata(pdev, tps6507x_dev);
337
338         return 0;
339
340 err2:
341         cancel_delayed_work_sync(&tsc->work);
342         input_free_device(input_dev);
343 err1:
344         kfree(tsc);
345         tps6507x_dev->ts = NULL;
346 err0:
347         return error;
348 }
349
350 static int __devexit tps6507x_ts_remove(struct platform_device *pdev)
351 {
352         struct tps6507x_dev *tps6507x_dev = platform_get_drvdata(pdev);
353         struct tps6507x_ts *tsc = tps6507x_dev->ts;
354         struct input_dev *input_dev = tsc->input_dev;
355
356         cancel_delayed_work_sync(&tsc->work);
357
358         input_unregister_device(input_dev);
359
360         tps6507x_dev->ts = NULL;
361         kfree(tsc);
362
363         return 0;
364 }
365
366 static struct platform_driver tps6507x_ts_driver = {
367         .driver = {
368                 .name = "tps6507x-ts",
369                 .owner = THIS_MODULE,
370         },
371         .probe = tps6507x_ts_probe,
372         .remove = __devexit_p(tps6507x_ts_remove),
373 };
374
375 static int __init tps6507x_ts_init(void)
376 {
377         return platform_driver_register(&tps6507x_ts_driver);
378 }
379 module_init(tps6507x_ts_init);
380
381 static void __exit tps6507x_ts_exit(void)
382 {
383         platform_driver_unregister(&tps6507x_ts_driver);
384 }
385 module_exit(tps6507x_ts_exit);
386
387 MODULE_AUTHOR("Todd Fischer <todd.fischer@ridgerun.com>");
388 MODULE_DESCRIPTION("TPS6507x - TouchScreen driver");
389 MODULE_LICENSE("GPL v2");
390 MODULE_ALIAS("platform:tps6507x-tsc");