blob: 5d6f90da27d326bcf792b70e18131550be1cec4d [file] [log] [blame]
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001/* drivers/input/touchscreen/msm_ts.c
2 *
3 * Copyright (C) 2008 Google, Inc.
Duy Truong790f06d2013-02-13 16:38:12 -08004 * Copyright (c) 2010-2012, The Linux Foundation. All rights reserved.
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07005 *
6 * This software is licensed under the terms of the GNU General Public
7 * License version 2, as published by the Free Software Foundation, and
8 * may be copied, distributed, and modified under those terms.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * TODO:
16 * - Add a timer to simulate a pen_up in case there's a timeout.
17 */
18
19#include <linux/delay.h>
20#include <linux/device.h>
21#include <linux/init.h>
22#include <linux/input.h>
23#include <linux/interrupt.h>
24#include <linux/io.h>
25#include <linux/module.h>
26#include <linux/platform_device.h>
27#include <linux/mfd/marimba-tsadc.h>
28#include <linux/pm.h>
29#include <linux/slab.h>
30
31#if defined(CONFIG_HAS_EARLYSUSPEND)
32#include <linux/earlysuspend.h>
33#endif
34
35#include <linux/input/msm_ts.h>
36
37#define TSSC_CTL 0x100
38#define TSSC_CTL_PENUP_IRQ (1 << 12)
39#define TSSC_CTL_DATA_FLAG (1 << 11)
40#define TSSC_CTL_DEBOUNCE_EN (1 << 6)
41#define TSSC_CTL_EN_AVERAGE (1 << 5)
42#define TSSC_CTL_MODE_MASTER (3 << 3)
43#define TSSC_CTL_SW_RESET (1 << 2)
44#define TSSC_CTL_ENABLE (1 << 0)
45#define TSSC_OPN 0x104
46#define TSSC_OPN_NOOP 0x00
47#define TSSC_OPN_4WIRE_X 0x01
48#define TSSC_OPN_4WIRE_Y 0x02
49#define TSSC_OPN_4WIRE_Z1 0x03
50#define TSSC_OPN_4WIRE_Z2 0x04
51#define TSSC_SAMPLING_INT 0x108
52#define TSSC_STATUS 0x10c
53#define TSSC_AVG_12 0x110
54#define TSSC_AVG_34 0x114
55#define TSSC_SAMPLE(op,samp) ((0x118 + ((op & 0x3) * 0x20)) + \
56 ((samp & 0x7) * 0x4))
57#define TSSC_TEST_1 0x198
58 #define TSSC_TEST_1_EN_GATE_DEBOUNCE (1 << 2)
59#define TSSC_TEST_2 0x19c
60
61struct msm_ts {
62 struct msm_ts_platform_data *pdata;
63 struct input_dev *input_dev;
64 void __iomem *tssc_base;
65 uint32_t ts_down:1;
66 struct ts_virt_key *vkey_down;
67 struct marimba_tsadc_client *ts_client;
68
69 unsigned int sample_irq;
70 unsigned int pen_up_irq;
71
72#if defined(CONFIG_HAS_EARLYSUSPEND)
73 struct early_suspend early_suspend;
74#endif
75 struct device *dev;
76};
77
78static uint32_t msm_tsdebug;
79module_param_named(tsdebug, msm_tsdebug, uint, 0664);
80
81#define tssc_readl(t, a) (readl_relaxed(((t)->tssc_base) + (a)))
82#define tssc_writel(t, v, a) do {writel_relaxed(v, \
83 ((t)->tssc_base) + (a)); } \
84 while (0)
85
86static void setup_next_sample(struct msm_ts *ts)
87{
88 uint32_t tmp;
89
90 /* 1.2ms debounce time */
91 tmp = ((2 << 7) | TSSC_CTL_DEBOUNCE_EN | TSSC_CTL_EN_AVERAGE |
92 TSSC_CTL_MODE_MASTER | TSSC_CTL_ENABLE);
93 tssc_writel(ts, tmp, TSSC_CTL);
94 /* barrier: Make sure the write completes before the next sample */
95 mb();
96}
97
98static struct ts_virt_key *find_virt_key(struct msm_ts *ts,
99 struct msm_ts_virtual_keys *vkeys,
100 uint32_t val)
101{
102 int i;
103
104 if (!vkeys)
105 return NULL;
106
107 for (i = 0; i < vkeys->num_keys; ++i)
108 if ((val >= vkeys->keys[i].min) && (val <= vkeys->keys[i].max))
109 return &vkeys->keys[i];
110 return NULL;
111}
112
113
114static irqreturn_t msm_ts_irq(int irq, void *dev_id)
115{
116 struct msm_ts *ts = dev_id;
117 struct msm_ts_platform_data *pdata = ts->pdata;
118
119 uint32_t tssc_avg12, tssc_avg34, tssc_status, tssc_ctl;
120 int x, y, z1, z2;
121 int was_down;
122 int down;
123
124 tssc_ctl = tssc_readl(ts, TSSC_CTL);
125 tssc_status = tssc_readl(ts, TSSC_STATUS);
126 tssc_avg12 = tssc_readl(ts, TSSC_AVG_12);
127 tssc_avg34 = tssc_readl(ts, TSSC_AVG_34);
128
129 setup_next_sample(ts);
130
131 x = tssc_avg12 & 0xffff;
132 y = tssc_avg12 >> 16;
133 z1 = tssc_avg34 & 0xffff;
134 z2 = tssc_avg34 >> 16;
135
136 /* invert the inputs if necessary */
137 if (pdata->inv_x) x = pdata->inv_x - x;
138 if (pdata->inv_y) y = pdata->inv_y - y;
139 if (x < 0) x = 0;
140 if (y < 0) y = 0;
141
142 down = !(tssc_ctl & TSSC_CTL_PENUP_IRQ);
143 was_down = ts->ts_down;
144 ts->ts_down = down;
145
146 /* no valid data */
147 if (down && !(tssc_ctl & TSSC_CTL_DATA_FLAG))
148 return IRQ_HANDLED;
149
150 if (msm_tsdebug & 2)
151 printk("%s: down=%d, x=%d, y=%d, z1=%d, z2=%d, status %x\n",
152 __func__, down, x, y, z1, z2, tssc_status);
153
154 if (!was_down && down) {
155 struct ts_virt_key *vkey = NULL;
156
157 if (pdata->vkeys_y && (y > pdata->virt_y_start))
158 vkey = find_virt_key(ts, pdata->vkeys_y, x);
159 if (!vkey && ts->pdata->vkeys_x && (x > pdata->virt_x_start))
160 vkey = find_virt_key(ts, pdata->vkeys_x, y);
161
162 if (vkey) {
163 WARN_ON(ts->vkey_down != NULL);
164 if(msm_tsdebug)
165 printk("%s: virtual key down %d\n", __func__,
166 vkey->key);
167 ts->vkey_down = vkey;
168 input_report_key(ts->input_dev, vkey->key, 1);
169 input_sync(ts->input_dev);
170 return IRQ_HANDLED;
171 }
172 } else if (ts->vkey_down != NULL) {
173 if (!down) {
174 if(msm_tsdebug)
175 printk("%s: virtual key up %d\n", __func__,
176 ts->vkey_down->key);
177 input_report_key(ts->input_dev, ts->vkey_down->key, 0);
178 input_sync(ts->input_dev);
179 ts->vkey_down = NULL;
180 }
181 return IRQ_HANDLED;
182 }
183
184 if (down) {
185 input_report_abs(ts->input_dev, ABS_X, x);
186 input_report_abs(ts->input_dev, ABS_Y, y);
187 input_report_abs(ts->input_dev, ABS_PRESSURE, z1);
188 }
189 input_report_key(ts->input_dev, BTN_TOUCH, down);
190 input_sync(ts->input_dev);
191
192 return IRQ_HANDLED;
193}
194
195static void dump_tssc_regs(struct msm_ts *ts)
196{
197#define __dump_tssc_reg(r) \
198 do { printk(#r " %x\n", tssc_readl(ts, (r))); } while(0)
199
200 __dump_tssc_reg(TSSC_CTL);
201 __dump_tssc_reg(TSSC_OPN);
202 __dump_tssc_reg(TSSC_SAMPLING_INT);
203 __dump_tssc_reg(TSSC_STATUS);
204 __dump_tssc_reg(TSSC_AVG_12);
205 __dump_tssc_reg(TSSC_AVG_34);
206 __dump_tssc_reg(TSSC_TEST_1);
207#undef __dump_tssc_reg
208}
209
Stephen Boyd93d0d192012-04-25 11:50:07 -0700210static int msm_ts_hw_init(struct msm_ts *ts)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700211{
212 uint32_t tmp;
213
214 /* Enable the register clock to tssc so we can configure it. */
215 tssc_writel(ts, TSSC_CTL_ENABLE, TSSC_CTL);
216 /* Enable software reset*/
217 tssc_writel(ts, TSSC_CTL_SW_RESET, TSSC_CTL);
218
219 /* op1 - measure X, 1 sample, 12bit resolution */
220 tmp = (TSSC_OPN_4WIRE_X << 16) | (2 << 8) | (2 << 0);
221 /* op2 - measure Y, 1 sample, 12bit resolution */
222 tmp |= (TSSC_OPN_4WIRE_Y << 20) | (2 << 10) | (2 << 2);
223 /* op3 - measure Z1, 1 sample, 8bit resolution */
224 tmp |= (TSSC_OPN_4WIRE_Z1 << 24) | (2 << 12) | (0 << 4);
225
226 /* XXX: we don't actually need to measure Z2 (thus 0 samples) when
227 * doing voltage-driven measurement */
228 /* op4 - measure Z2, 0 samples, 8bit resolution */
229 tmp |= (TSSC_OPN_4WIRE_Z2 << 28) | (0 << 14) | (0 << 6);
230 tssc_writel(ts, tmp, TSSC_OPN);
231
232 /* 16ms sampling interval */
233 tssc_writel(ts, 16, TSSC_SAMPLING_INT);
234 /* Enable gating logic to fix the timing delays caused because of
235 * enabling debounce logic */
236 tssc_writel(ts, TSSC_TEST_1_EN_GATE_DEBOUNCE, TSSC_TEST_1);
237
238 setup_next_sample(ts);
239
240 return 0;
241}
242
243static void msm_ts_enable(struct msm_ts *ts, bool enable)
244{
245 uint32_t val;
246
247 if (enable == true)
248 msm_ts_hw_init(ts);
249 else {
250 val = tssc_readl(ts, TSSC_CTL);
251 val &= ~TSSC_CTL_ENABLE;
252 tssc_writel(ts, val, TSSC_CTL);
253 }
254}
255
256#ifdef CONFIG_PM
257static int
258msm_ts_suspend(struct device *dev)
259{
260 struct msm_ts *ts = dev_get_drvdata(dev);
261
262 if (device_may_wakeup(dev) &&
263 device_may_wakeup(dev->parent))
264 enable_irq_wake(ts->sample_irq);
265 else {
266 disable_irq(ts->sample_irq);
267 disable_irq(ts->pen_up_irq);
268 msm_ts_enable(ts, false);
269 }
270
271 return 0;
272}
273
274static int
275msm_ts_resume(struct device *dev)
276{
277 struct msm_ts *ts = dev_get_drvdata(dev);
278
279 if (device_may_wakeup(dev) &&
280 device_may_wakeup(dev->parent))
281 disable_irq_wake(ts->sample_irq);
282 else {
283 msm_ts_enable(ts, true);
284 enable_irq(ts->sample_irq);
285 enable_irq(ts->pen_up_irq);
286 }
287
288 return 0;
289}
290
291static struct dev_pm_ops msm_touchscreen_pm_ops = {
292#ifndef CONFIG_HAS_EARLYSUSPEND
293 .suspend = msm_ts_suspend,
294 .resume = msm_ts_resume,
295#endif
296};
297#endif
298
299#ifdef CONFIG_HAS_EARLYSUSPEND
300static void msm_ts_early_suspend(struct early_suspend *h)
301{
302 struct msm_ts *ts = container_of(h, struct msm_ts, early_suspend);
303
304 msm_ts_suspend(ts->dev);
305}
306
307static void msm_ts_late_resume(struct early_suspend *h)
308{
309 struct msm_ts *ts = container_of(h, struct msm_ts, early_suspend);
310
311 msm_ts_resume(ts->dev);
312}
313#endif
314
315
316static int __devinit msm_ts_probe(struct platform_device *pdev)
317{
318 struct msm_ts_platform_data *pdata = pdev->dev.platform_data;
319 struct msm_ts *ts;
320 struct resource *tssc_res;
321 struct resource *irq1_res;
322 struct resource *irq2_res;
323 int err = 0;
324 int i;
325 struct marimba_tsadc_client *ts_client;
326
327 printk("%s\n", __func__);
328
329 tssc_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "tssc");
330 irq1_res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "tssc1");
331 irq2_res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "tssc2");
332
333 if (!tssc_res || !irq1_res || !irq2_res) {
334 pr_err("%s: required resources not defined\n", __func__);
335 return -ENODEV;
336 }
337
338 if (pdata == NULL) {
339 pr_err("%s: missing platform_data\n", __func__);
340 return -ENODEV;
341 }
342
343 ts = kzalloc(sizeof(struct msm_ts), GFP_KERNEL);
344 if (ts == NULL) {
345 pr_err("%s: No memory for struct msm_ts\n", __func__);
346 return -ENOMEM;
347 }
348 ts->pdata = pdata;
349 ts->dev = &pdev->dev;
350
351 ts->sample_irq = irq1_res->start;
352 ts->pen_up_irq = irq2_res->start;
353
354 ts->tssc_base = ioremap(tssc_res->start, resource_size(tssc_res));
355 if (ts->tssc_base == NULL) {
356 pr_err("%s: Can't ioremap region (0x%08x - 0x%08x)\n", __func__,
357 (uint32_t)tssc_res->start, (uint32_t)tssc_res->end);
358 err = -ENOMEM;
359 goto err_ioremap_tssc;
360 }
361
362 ts_client = marimba_tsadc_register(pdev, 1);
363 if (IS_ERR(ts_client)) {
364 pr_err("%s: Unable to register with TSADC\n", __func__);
365 err = -ENOMEM;
366 goto err_tsadc_register;
367 }
368 ts->ts_client = ts_client;
369
370 err = marimba_tsadc_start(ts_client);
371 if (err) {
372 pr_err("%s: Unable to start TSADC\n", __func__);
373 err = -EINVAL;
374 goto err_start_tsadc;
375 }
376
377 ts->input_dev = input_allocate_device();
378 if (ts->input_dev == NULL) {
379 pr_err("failed to allocate touchscreen input device\n");
380 err = -ENOMEM;
381 goto err_alloc_input_dev;
382 }
383 ts->input_dev->name = "msm-touchscreen";
384 ts->input_dev->dev.parent = &pdev->dev;
385
386 input_set_drvdata(ts->input_dev, ts);
387
388 input_set_capability(ts->input_dev, EV_KEY, BTN_TOUCH);
389 set_bit(EV_ABS, ts->input_dev->evbit);
Anirudh Ghayal3aaf03e2012-07-26 13:25:17 +0530390 set_bit(INPUT_PROP_DIRECT, ts->input_dev->propbit);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700391
392 input_set_abs_params(ts->input_dev, ABS_X, pdata->min_x, pdata->max_x,
393 0, 0);
394 input_set_abs_params(ts->input_dev, ABS_Y, pdata->min_y, pdata->max_y,
395 0, 0);
396 input_set_abs_params(ts->input_dev, ABS_PRESSURE, pdata->min_press,
397 pdata->max_press, 0, 0);
398
399 for (i = 0; pdata->vkeys_x && (i < pdata->vkeys_x->num_keys); ++i)
400 input_set_capability(ts->input_dev, EV_KEY,
401 pdata->vkeys_x->keys[i].key);
402 for (i = 0; pdata->vkeys_y && (i < pdata->vkeys_y->num_keys); ++i)
403 input_set_capability(ts->input_dev, EV_KEY,
404 pdata->vkeys_y->keys[i].key);
405
406 err = input_register_device(ts->input_dev);
407 if (err != 0) {
408 pr_err("%s: failed to register input device\n", __func__);
409 goto err_input_dev_reg;
410 }
411
412 msm_ts_hw_init(ts);
413
414 err = request_irq(ts->sample_irq, msm_ts_irq,
415 (irq1_res->flags & ~IORESOURCE_IRQ) | IRQF_DISABLED,
416 "msm_touchscreen", ts);
417 if (err != 0) {
418 pr_err("%s: Cannot register irq1 (%d)\n", __func__, err);
419 goto err_request_irq1;
420 }
421
422 err = request_irq(ts->pen_up_irq, msm_ts_irq,
423 (irq2_res->flags & ~IORESOURCE_IRQ) | IRQF_DISABLED,
424 "msm_touchscreen", ts);
425 if (err != 0) {
426 pr_err("%s: Cannot register irq2 (%d)\n", __func__, err);
427 goto err_request_irq2;
428 }
429
430 platform_set_drvdata(pdev, ts);
431
432#ifdef CONFIG_HAS_EARLYSUSPEND
433 ts->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN +
434 TSSC_SUSPEND_LEVEL;
435 ts->early_suspend.suspend = msm_ts_early_suspend;
436 ts->early_suspend.resume = msm_ts_late_resume;
437 register_early_suspend(&ts->early_suspend);
438#endif
439
440 device_init_wakeup(&pdev->dev, pdata->can_wakeup);
441 pr_info("%s: tssc_base=%p irq1=%d irq2=%d\n", __func__,
442 ts->tssc_base, (int)ts->sample_irq, (int)ts->pen_up_irq);
443 dump_tssc_regs(ts);
444 return 0;
445
446err_request_irq2:
447 free_irq(ts->sample_irq, ts);
448
449err_request_irq1:
450 /* disable the tssc */
451 tssc_writel(ts, TSSC_CTL_ENABLE, TSSC_CTL);
452
453err_input_dev_reg:
454 input_set_drvdata(ts->input_dev, NULL);
455 input_free_device(ts->input_dev);
456
457err_alloc_input_dev:
458err_start_tsadc:
459 marimba_tsadc_unregister(ts->ts_client);
460
461err_tsadc_register:
462 iounmap(ts->tssc_base);
463
464err_ioremap_tssc:
465 kfree(ts);
466 return err;
467}
468
469static int __devexit msm_ts_remove(struct platform_device *pdev)
470{
471 struct msm_ts *ts = platform_get_drvdata(pdev);
472
473 device_init_wakeup(&pdev->dev, 0);
474 marimba_tsadc_unregister(ts->ts_client);
475 free_irq(ts->sample_irq, ts);
476 free_irq(ts->pen_up_irq, ts);
477 input_unregister_device(ts->input_dev);
478 iounmap(ts->tssc_base);
479#ifdef CONFIG_HAS_EARLYSUSPEND
480 unregister_early_suspend(&ts->early_suspend);
481#endif
482 platform_set_drvdata(pdev, NULL);
483 kfree(ts);
484
485 return 0;
486}
487
488static struct platform_driver msm_touchscreen_driver = {
489 .driver = {
490 .name = "msm_touchscreen",
491 .owner = THIS_MODULE,
492#ifdef CONFIG_PM
493 .pm = &msm_touchscreen_pm_ops,
494#endif
495 },
496 .probe = msm_ts_probe,
497 .remove = __devexit_p(msm_ts_remove),
498};
499
500static int __init msm_ts_init(void)
501{
502 return platform_driver_register(&msm_touchscreen_driver);
503}
504
505static void __exit msm_ts_exit(void)
506{
507 platform_driver_unregister(&msm_touchscreen_driver);
508}
509
510module_init(msm_ts_init);
511module_exit(msm_ts_exit);
512MODULE_DESCRIPTION("Qualcomm MSM/QSD Touchscreen controller driver");
513MODULE_LICENSE("GPL");
514MODULE_ALIAS("platform:msm_touchscreen");