1 /* 2 * TI Touch Screen driver 3 * 4 * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License as 8 * published by the Free Software Foundation version 2. 9 * 10 * This program is distributed "as is" WITHOUT ANY WARRANTY of any 11 * kind, whether express or implied; without even the implied warranty 12 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 */ 15 16 17 #include <linux/init.h> 18 #include <linux/kernel.h> 19 #include <linux/err.h> 20 #include <linux/module.h> 21 #include <linux/input.h> 22 #include <linux/slab.h> 23 #include <linux/interrupt.h> 24 #include <linux/clk.h> 25 #include <linux/platform_device.h> 26 #include <linux/io.h> 27 #include <linux/input/ti_am335x_tsc.h> 28 #include <linux/delay.h> 29 30 #include <linux/mfd/ti_am335x_tscadc.h> 31 32 #define ADCFSM_STEPID 0x10 33 #define SEQ_SETTLE 275 34 #define MAX_12BIT ((1 << 12) - 1) 35 36 struct titsc { 37 struct input_dev *input; 38 struct ti_tscadc_dev *mfd_tscadc; 39 unsigned int irq; 40 unsigned int wires; 41 unsigned int x_plate_resistance; 42 bool pen_down; 43 int steps_to_configure; 44 }; 45 46 static unsigned int titsc_readl(struct titsc *ts, unsigned int reg) 47 { 48 return readl(ts->mfd_tscadc->tscadc_base + reg); 49 } 50 51 static void titsc_writel(struct titsc *tsc, unsigned int reg, 52 unsigned int val) 53 { 54 writel(val, tsc->mfd_tscadc->tscadc_base + reg); 55 } 56 57 static void titsc_step_config(struct titsc *ts_dev) 58 { 59 unsigned int config; 60 int i, total_steps; 61 62 /* Configure the Step registers */ 63 total_steps = 2 * ts_dev->steps_to_configure; 64 65 config = STEPCONFIG_MODE_HWSYNC | 66 STEPCONFIG_AVG_16 | STEPCONFIG_XPP; 67 switch (ts_dev->wires) { 68 case 4: 69 config |= STEPCONFIG_INP_AN2 | STEPCONFIG_XNN; 70 break; 71 case 5: 72 config |= STEPCONFIG_YNN | 73 STEPCONFIG_INP_AN4 | STEPCONFIG_XNN | 74 STEPCONFIG_YPP; 75 break; 76 case 8: 77 config |= STEPCONFIG_INP_AN2 | STEPCONFIG_XNN; 78 break; 79 } 80 81 for (i = 1; i <= ts_dev->steps_to_configure; i++) { 82 titsc_writel(ts_dev, REG_STEPCONFIG(i), config); 83 titsc_writel(ts_dev, REG_STEPDELAY(i), STEPCONFIG_OPENDLY); 84 } 85 86 config = 0; 87 config = STEPCONFIG_MODE_HWSYNC | 88 STEPCONFIG_AVG_16 | STEPCONFIG_YNN | 89 STEPCONFIG_INM_ADCREFM | STEPCONFIG_FIFO1; 90 switch (ts_dev->wires) { 91 case 4: 92 config |= STEPCONFIG_YPP; 93 break; 94 case 5: 95 config |= STEPCONFIG_XPP | STEPCONFIG_INP_AN4 | 96 STEPCONFIG_XNP | STEPCONFIG_YPN; 97 break; 98 case 8: 99 config |= STEPCONFIG_YPP; 100 break; 101 } 102 103 for (i = (ts_dev->steps_to_configure + 1); i <= total_steps; i++) { 104 titsc_writel(ts_dev, REG_STEPCONFIG(i), config); 105 titsc_writel(ts_dev, REG_STEPDELAY(i), STEPCONFIG_OPENDLY); 106 } 107 108 config = 0; 109 /* Charge step configuration */ 110 config = STEPCONFIG_XPP | STEPCONFIG_YNN | 111 STEPCHARGE_RFP_XPUL | STEPCHARGE_RFM_XNUR | 112 STEPCHARGE_INM_AN1 | STEPCHARGE_INP_AN1; 113 114 titsc_writel(ts_dev, REG_CHARGECONFIG, config); 115 titsc_writel(ts_dev, REG_CHARGEDELAY, CHARGEDLY_OPENDLY); 116 117 config = 0; 118 /* Configure to calculate pressure */ 119 config = STEPCONFIG_MODE_HWSYNC | 120 STEPCONFIG_AVG_16 | STEPCONFIG_YPP | 121 STEPCONFIG_XNN | STEPCONFIG_INM_ADCREFM; 122 titsc_writel(ts_dev, REG_STEPCONFIG(total_steps + 1), config); 123 titsc_writel(ts_dev, REG_STEPDELAY(total_steps + 1), 124 STEPCONFIG_OPENDLY); 125 126 config |= STEPCONFIG_INP_AN3 | STEPCONFIG_FIFO1; 127 titsc_writel(ts_dev, REG_STEPCONFIG(total_steps + 2), config); 128 titsc_writel(ts_dev, REG_STEPDELAY(total_steps + 2), 129 STEPCONFIG_OPENDLY); 130 131 titsc_writel(ts_dev, REG_SE, STPENB_STEPENB_TC); 132 } 133 134 static void titsc_read_coordinates(struct titsc *ts_dev, 135 unsigned int *x, unsigned int *y) 136 { 137 unsigned int fifocount = titsc_readl(ts_dev, REG_FIFO0CNT); 138 unsigned int prev_val_x = ~0, prev_val_y = ~0; 139 unsigned int prev_diff_x = ~0, prev_diff_y = ~0; 140 unsigned int read, diff; 141 unsigned int i, channel; 142 143 /* 144 * Delta filter is used to remove large variations in sampled 145 * values from ADC. The filter tries to predict where the next 146 * coordinate could be. This is done by taking a previous 147 * coordinate and subtracting it form current one. Further the 148 * algorithm compares the difference with that of a present value, 149 * if true the value is reported to the sub system. 150 */ 151 for (i = 0; i < fifocount - 1; i++) { 152 read = titsc_readl(ts_dev, REG_FIFO0); 153 channel = read & 0xf0000; 154 channel = channel >> 0x10; 155 if ((channel >= 0) && (channel < ts_dev->steps_to_configure)) { 156 read &= 0xfff; 157 diff = abs(read - prev_val_x); 158 if (diff < prev_diff_x) { 159 prev_diff_x = diff; 160 *x = read; 161 } 162 prev_val_x = read; 163 } 164 165 read = titsc_readl(ts_dev, REG_FIFO1); 166 channel = read & 0xf0000; 167 channel = channel >> 0x10; 168 if ((channel >= ts_dev->steps_to_configure) && 169 (channel < (2 * ts_dev->steps_to_configure - 1))) { 170 read &= 0xfff; 171 diff = abs(read - prev_val_y); 172 if (diff < prev_diff_y) { 173 prev_diff_y = diff; 174 *y = read; 175 } 176 prev_val_y = read; 177 } 178 } 179 } 180 181 static irqreturn_t titsc_irq(int irq, void *dev) 182 { 183 struct titsc *ts_dev = dev; 184 struct input_dev *input_dev = ts_dev->input; 185 unsigned int status, irqclr = 0; 186 unsigned int x = 0, y = 0; 187 unsigned int z1, z2, z; 188 unsigned int fsm; 189 unsigned int fifo1count, fifo0count; 190 int i; 191 192 status = titsc_readl(ts_dev, REG_IRQSTATUS); 193 if (status & IRQENB_FIFO0THRES) { 194 titsc_read_coordinates(ts_dev, &x, &y); 195 196 z1 = titsc_readl(ts_dev, REG_FIFO0) & 0xfff; 197 z2 = titsc_readl(ts_dev, REG_FIFO1) & 0xfff; 198 199 fifo1count = titsc_readl(ts_dev, REG_FIFO1CNT); 200 for (i = 0; i < fifo1count; i++) 201 titsc_readl(ts_dev, REG_FIFO1); 202 203 fifo0count = titsc_readl(ts_dev, REG_FIFO0CNT); 204 for (i = 0; i < fifo0count; i++) 205 titsc_readl(ts_dev, REG_FIFO0); 206 207 if (ts_dev->pen_down && z1 != 0 && z2 != 0) { 208 /* 209 * Calculate pressure using formula 210 * Resistance(touch) = x plate resistance * 211 * x postion/4096 * ((z2 / z1) - 1) 212 */ 213 z = z2 - z1; 214 z *= x; 215 z *= ts_dev->x_plate_resistance; 216 z /= z1; 217 z = (z + 2047) >> 12; 218 219 if (z <= MAX_12BIT) { 220 input_report_abs(input_dev, ABS_X, x); 221 input_report_abs(input_dev, ABS_Y, y); 222 input_report_abs(input_dev, ABS_PRESSURE, z); 223 input_report_key(input_dev, BTN_TOUCH, 1); 224 input_sync(input_dev); 225 } 226 } 227 irqclr |= IRQENB_FIFO0THRES; 228 } 229 230 /* 231 * Time for sequencer to settle, to read 232 * correct state of the sequencer. 233 */ 234 udelay(SEQ_SETTLE); 235 236 status = titsc_readl(ts_dev, REG_RAWIRQSTATUS); 237 if (status & IRQENB_PENUP) { 238 /* Pen up event */ 239 fsm = titsc_readl(ts_dev, REG_ADCFSM); 240 if (fsm == ADCFSM_STEPID) { 241 ts_dev->pen_down = false; 242 input_report_key(input_dev, BTN_TOUCH, 0); 243 input_report_abs(input_dev, ABS_PRESSURE, 0); 244 input_sync(input_dev); 245 } else { 246 ts_dev->pen_down = true; 247 } 248 irqclr |= IRQENB_PENUP; 249 } 250 251 titsc_writel(ts_dev, REG_IRQSTATUS, irqclr); 252 253 titsc_writel(ts_dev, REG_SE, STPENB_STEPENB_TC); 254 return IRQ_HANDLED; 255 } 256 257 /* 258 * The functions for inserting/removing driver as a module. 259 */ 260 261 static int titsc_probe(struct platform_device *pdev) 262 { 263 struct titsc *ts_dev; 264 struct input_dev *input_dev; 265 struct ti_tscadc_dev *tscadc_dev = pdev->dev.platform_data; 266 struct mfd_tscadc_board *pdata; 267 int err; 268 269 pdata = tscadc_dev->dev->platform_data; 270 271 if (!pdata) { 272 dev_err(&pdev->dev, "Could not find platform data\n"); 273 return -EINVAL; 274 } 275 276 /* Allocate memory for device */ 277 ts_dev = kzalloc(sizeof(struct titsc), GFP_KERNEL); 278 input_dev = input_allocate_device(); 279 if (!ts_dev || !input_dev) { 280 dev_err(&pdev->dev, "failed to allocate memory.\n"); 281 err = -ENOMEM; 282 goto err_free_mem; 283 } 284 285 tscadc_dev->tsc = ts_dev; 286 ts_dev->mfd_tscadc = tscadc_dev; 287 ts_dev->input = input_dev; 288 ts_dev->irq = tscadc_dev->irq; 289 ts_dev->wires = pdata->tsc_init->wires; 290 ts_dev->x_plate_resistance = pdata->tsc_init->x_plate_resistance; 291 ts_dev->steps_to_configure = pdata->tsc_init->steps_to_configure; 292 293 err = request_irq(ts_dev->irq, titsc_irq, 294 0, pdev->dev.driver->name, ts_dev); 295 if (err) { 296 dev_err(&pdev->dev, "failed to allocate irq.\n"); 297 goto err_free_mem; 298 } 299 300 titsc_writel(ts_dev, REG_IRQENABLE, IRQENB_FIFO0THRES); 301 titsc_step_config(ts_dev); 302 titsc_writel(ts_dev, REG_FIFO0THR, ts_dev->steps_to_configure); 303 304 input_dev->name = "ti-tsc"; 305 input_dev->dev.parent = &pdev->dev; 306 307 input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); 308 input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); 309 310 input_set_abs_params(input_dev, ABS_X, 0, MAX_12BIT, 0, 0); 311 input_set_abs_params(input_dev, ABS_Y, 0, MAX_12BIT, 0, 0); 312 input_set_abs_params(input_dev, ABS_PRESSURE, 0, MAX_12BIT, 0, 0); 313 314 /* register to the input system */ 315 err = input_register_device(input_dev); 316 if (err) 317 goto err_free_irq; 318 319 platform_set_drvdata(pdev, ts_dev); 320 return 0; 321 322 err_free_irq: 323 free_irq(ts_dev->irq, ts_dev); 324 err_free_mem: 325 input_free_device(input_dev); 326 kfree(ts_dev); 327 return err; 328 } 329 330 static int titsc_remove(struct platform_device *pdev) 331 { 332 struct ti_tscadc_dev *tscadc_dev = pdev->dev.platform_data; 333 struct titsc *ts_dev = tscadc_dev->tsc; 334 335 free_irq(ts_dev->irq, ts_dev); 336 337 input_unregister_device(ts_dev->input); 338 339 platform_set_drvdata(pdev, NULL); 340 kfree(ts_dev); 341 return 0; 342 } 343 344 #ifdef CONFIG_PM 345 static int titsc_suspend(struct device *dev) 346 { 347 struct ti_tscadc_dev *tscadc_dev = dev->platform_data; 348 struct titsc *ts_dev = tscadc_dev->tsc; 349 unsigned int idle; 350 351 if (device_may_wakeup(tscadc_dev->dev)) { 352 idle = titsc_readl(ts_dev, REG_IRQENABLE); 353 titsc_writel(ts_dev, REG_IRQENABLE, 354 (idle | IRQENB_HW_PEN)); 355 titsc_writel(ts_dev, REG_IRQWAKEUP, IRQWKUP_ENB); 356 } 357 return 0; 358 } 359 360 static int titsc_resume(struct device *dev) 361 { 362 struct ti_tscadc_dev *tscadc_dev = dev->platform_data; 363 struct titsc *ts_dev = tscadc_dev->tsc; 364 365 if (device_may_wakeup(tscadc_dev->dev)) { 366 titsc_writel(ts_dev, REG_IRQWAKEUP, 367 0x00); 368 titsc_writel(ts_dev, REG_IRQCLR, IRQENB_HW_PEN); 369 } 370 titsc_step_config(ts_dev); 371 titsc_writel(ts_dev, REG_FIFO0THR, 372 ts_dev->steps_to_configure); 373 return 0; 374 } 375 376 static const struct dev_pm_ops titsc_pm_ops = { 377 .suspend = titsc_suspend, 378 .resume = titsc_resume, 379 }; 380 #define TITSC_PM_OPS (&titsc_pm_ops) 381 #else 382 #define TITSC_PM_OPS NULL 383 #endif 384 385 static struct platform_driver ti_tsc_driver = { 386 .probe = titsc_probe, 387 .remove = titsc_remove, 388 .driver = { 389 .name = "tsc", 390 .owner = THIS_MODULE, 391 .pm = TITSC_PM_OPS, 392 }, 393 }; 394 module_platform_driver(ti_tsc_driver); 395 396 MODULE_DESCRIPTION("TI touchscreen controller driver"); 397 MODULE_AUTHOR("Rachna Patil <rachna@ti.com>"); 398 MODULE_LICENSE("GPL"); 399