1/* 2 * Atmel AT91 and AVR32 continuous touch screen driver for Wolfson WM97xx AC97 3 * codecs. 4 * 5 * Copyright (C) 2008 - 2009 Atmel Corporation 6 * 7 * This program is free software; you can redistribute it and/or modify it 8 * under the terms of the GNU General Public License version 2 as published by 9 * the Free Software Foundation. 10 */ 11#include <linux/module.h> 12#include <linux/moduleparam.h> 13#include <linux/kernel.h> 14#include <linux/init.h> 15#include <linux/delay.h> 16#include <linux/irq.h> 17#include <linux/interrupt.h> 18#include <linux/wm97xx.h> 19#include <linux/timer.h> 20#include <linux/gpio.h> 21#include <linux/io.h> 22#include <linux/slab.h> 23 24#define AC97C_ICA 0x10 25#define AC97C_CBRHR 0x30 26#define AC97C_CBSR 0x38 27#define AC97C_CBMR 0x3c 28#define AC97C_IER 0x54 29#define AC97C_IDR 0x58 30 31#define AC97C_RXRDY (1 << 4) 32#define AC97C_OVRUN (1 << 5) 33 34#define AC97C_CMR_SIZE_20 (0 << 16) 35#define AC97C_CMR_SIZE_18 (1 << 16) 36#define AC97C_CMR_SIZE_16 (2 << 16) 37#define AC97C_CMR_SIZE_10 (3 << 16) 38#define AC97C_CMR_CEM_LITTLE (1 << 18) 39#define AC97C_CMR_CEM_BIG (0 << 18) 40#define AC97C_CMR_CENA (1 << 21) 41 42#define AC97C_INT_CBEVT (1 << 4) 43 44#define AC97C_SR_CAEVT (1 << 3) 45 46#define AC97C_CH_MASK(slot) \ 47 (0x7 << (3 * (slot - 3))) 48#define AC97C_CH_ASSIGN(slot, channel) \ 49 (AC97C_CHANNEL_##channel << (3 * (slot - 3))) 50#define AC97C_CHANNEL_NONE 0x0 51#define AC97C_CHANNEL_B 0x2 52 53#define ac97c_writel(chip, reg, val) \ 54 __raw_writel((val), (chip)->regs + AC97C_##reg) 55#define ac97c_readl(chip, reg) \ 56 __raw_readl((chip)->regs + AC97C_##reg) 57 58#ifdef CONFIG_CPU_AT32AP700X 59#define ATMEL_WM97XX_AC97C_IOMEM (0xfff02800) 60#define ATMEL_WM97XX_AC97C_IRQ (29) 61#define ATMEL_WM97XX_GPIO_DEFAULT (32+16) /* Pin 16 on port B. */ 62#else 63#error Unknown CPU, this driver only supports AT32AP700X CPUs. 64#endif 65 66struct continuous { 67 u16 id; /* codec id */ 68 u8 code; /* continuous code */ 69 u8 reads; /* number of coord reads per read cycle */ 70 u32 speed; /* number of coords per second */ 71}; 72 73#define WM_READS(sp) ((sp / HZ) + 1) 74 75static const struct continuous cinfo[] = { 76 {WM9705_ID2, 0, WM_READS(94), 94}, 77 {WM9705_ID2, 1, WM_READS(188), 188}, 78 {WM9705_ID2, 2, WM_READS(375), 375}, 79 {WM9705_ID2, 3, WM_READS(750), 750}, 80 {WM9712_ID2, 0, WM_READS(94), 94}, 81 {WM9712_ID2, 1, WM_READS(188), 188}, 82 {WM9712_ID2, 2, WM_READS(375), 375}, 83 {WM9712_ID2, 3, WM_READS(750), 750}, 84 {WM9713_ID2, 0, WM_READS(94), 94}, 85 {WM9713_ID2, 1, WM_READS(120), 120}, 86 {WM9713_ID2, 2, WM_READS(154), 154}, 87 {WM9713_ID2, 3, WM_READS(188), 188}, 88}; 89 90/* Continuous speed index. */ 91static int sp_idx; 92 93/* 94 * Pen sampling frequency (Hz) in continuous mode. 95 */ 96static int cont_rate = 188; 97module_param(cont_rate, int, 0); 98MODULE_PARM_DESC(cont_rate, "Sampling rate in continuous mode (Hz)"); 99 100/* 101 * Pen down detection. 102 * 103 * This driver can either poll or use an interrupt to indicate a pen down 104 * event. If the irq request fails then it will fall back to polling mode. 105 */ 106static int pen_int = 1; 107module_param(pen_int, int, 0); 108MODULE_PARM_DESC(pen_int, "Pen down detection (1 = interrupt, 0 = polling)"); 109 110/* 111 * Pressure readback. 112 * 113 * Set to 1 to read back pen down pressure. 114 */ 115static int pressure; 116module_param(pressure, int, 0); 117MODULE_PARM_DESC(pressure, "Pressure readback (1 = pressure, 0 = no pressure)"); 118 119/* 120 * AC97 touch data slot. 121 * 122 * Touch screen readback data ac97 slot. 123 */ 124static int ac97_touch_slot = 5; 125module_param(ac97_touch_slot, int, 0); 126MODULE_PARM_DESC(ac97_touch_slot, "Touch screen data slot AC97 number"); 127 128/* 129 * GPIO line number. 130 * 131 * Set to GPIO number where the signal from the WM97xx device is hooked up. 132 */ 133static int atmel_gpio_line = ATMEL_WM97XX_GPIO_DEFAULT; 134module_param(atmel_gpio_line, int, 0); 135MODULE_PARM_DESC(atmel_gpio_line, "GPIO line number connected to WM97xx"); 136 137struct atmel_wm97xx { 138 struct wm97xx *wm; 139 struct timer_list pen_timer; 140 void __iomem *regs; 141 unsigned long ac97c_irq; 142 unsigned long gpio_pen; 143 unsigned long gpio_irq; 144 unsigned short x; 145 unsigned short y; 146}; 147 148static irqreturn_t atmel_wm97xx_channel_b_interrupt(int irq, void *dev_id) 149{ 150 struct atmel_wm97xx *atmel_wm97xx = dev_id; 151 struct wm97xx *wm = atmel_wm97xx->wm; 152 int status = ac97c_readl(atmel_wm97xx, CBSR); 153 irqreturn_t retval = IRQ_NONE; 154 155 if (status & AC97C_OVRUN) { 156 dev_dbg(&wm->touch_dev->dev, "AC97C overrun\n"); 157 ac97c_readl(atmel_wm97xx, CBRHR); 158 retval = IRQ_HANDLED; 159 } else if (status & AC97C_RXRDY) { 160 u16 data; 161 u16 value; 162 u16 source; 163 u16 pen_down; 164 165 data = ac97c_readl(atmel_wm97xx, CBRHR); 166 value = data & 0x0fff; 167 source = data & WM97XX_ADCSEL_MASK; 168 pen_down = (data & WM97XX_PEN_DOWN) >> 8; 169 170 if (source == WM97XX_ADCSEL_X) 171 atmel_wm97xx->x = value; 172 if (source == WM97XX_ADCSEL_Y) 173 atmel_wm97xx->y = value; 174 175 if (!pressure && source == WM97XX_ADCSEL_Y) { 176 input_report_abs(wm->input_dev, ABS_X, atmel_wm97xx->x); 177 input_report_abs(wm->input_dev, ABS_Y, atmel_wm97xx->y); 178 input_report_key(wm->input_dev, BTN_TOUCH, pen_down); 179 input_sync(wm->input_dev); 180 } else if (pressure && source == WM97XX_ADCSEL_PRES) { 181 input_report_abs(wm->input_dev, ABS_X, atmel_wm97xx->x); 182 input_report_abs(wm->input_dev, ABS_Y, atmel_wm97xx->y); 183 input_report_abs(wm->input_dev, ABS_PRESSURE, value); 184 input_report_key(wm->input_dev, BTN_TOUCH, value); 185 input_sync(wm->input_dev); 186 } 187 188 retval = IRQ_HANDLED; 189 } 190 191 return retval; 192} 193 194static void atmel_wm97xx_acc_pen_up(struct wm97xx *wm) 195{ 196 struct atmel_wm97xx *atmel_wm97xx = platform_get_drvdata(wm->touch_dev); 197 struct input_dev *input_dev = wm->input_dev; 198 int pen_down = gpio_get_value(atmel_wm97xx->gpio_pen); 199 200 if (pen_down != 0) { 201 mod_timer(&atmel_wm97xx->pen_timer, 202 jiffies + msecs_to_jiffies(1)); 203 } else { 204 if (pressure) 205 input_report_abs(input_dev, ABS_PRESSURE, 0); 206 input_report_key(input_dev, BTN_TOUCH, 0); 207 input_sync(input_dev); 208 } 209} 210 211static void atmel_wm97xx_pen_timer(unsigned long data) 212{ 213 atmel_wm97xx_acc_pen_up((struct wm97xx *)data); 214} 215 216static int atmel_wm97xx_acc_startup(struct wm97xx *wm) 217{ 218 struct atmel_wm97xx *atmel_wm97xx = platform_get_drvdata(wm->touch_dev); 219 int idx = 0; 220 221 if (wm->ac97 == NULL) 222 return -ENODEV; 223 224 for (idx = 0; idx < ARRAY_SIZE(cinfo); idx++) { 225 if (wm->id != cinfo[idx].id) 226 continue; 227 228 sp_idx = idx; 229 230 if (cont_rate <= cinfo[idx].speed) 231 break; 232 } 233 234 wm->acc_rate = cinfo[sp_idx].code; 235 wm->acc_slot = ac97_touch_slot; 236 dev_info(&wm->touch_dev->dev, "atmel accelerated touchscreen driver, " 237 "%d samples/sec\n", cinfo[sp_idx].speed); 238 239 if (pen_int) { 240 unsigned long reg; 241 242 wm->pen_irq = atmel_wm97xx->gpio_irq; 243 244 switch (wm->id) { 245 case WM9712_ID2: /* Fall through. */ 246 case WM9713_ID2: 247 /* 248 * Use GPIO 13 (PEN_DOWN) to assert GPIO line 3 249 * (PENDOWN). 250 */ 251 wm97xx_config_gpio(wm, WM97XX_GPIO_13, WM97XX_GPIO_IN, 252 WM97XX_GPIO_POL_HIGH, 253 WM97XX_GPIO_STICKY, 254 WM97XX_GPIO_WAKE); 255 wm97xx_config_gpio(wm, WM97XX_GPIO_3, WM97XX_GPIO_OUT, 256 WM97XX_GPIO_POL_HIGH, 257 WM97XX_GPIO_NOTSTICKY, 258 WM97XX_GPIO_NOWAKE); 259 case WM9705_ID2: /* Fall through. */ 260 /* 261 * Enable touch data slot in AC97 controller channel B. 262 */ 263 reg = ac97c_readl(atmel_wm97xx, ICA); 264 reg &= ~AC97C_CH_MASK(wm->acc_slot); 265 reg |= AC97C_CH_ASSIGN(wm->acc_slot, B); 266 ac97c_writel(atmel_wm97xx, ICA, reg); 267 268 /* 269 * Enable channel and interrupt for RXRDY and OVERRUN. 270 */ 271 ac97c_writel(atmel_wm97xx, CBMR, AC97C_CMR_CENA 272 | AC97C_CMR_CEM_BIG 273 | AC97C_CMR_SIZE_16 274 | AC97C_OVRUN 275 | AC97C_RXRDY); 276 /* Dummy read to empty RXRHR. */ 277 ac97c_readl(atmel_wm97xx, CBRHR); 278 /* 279 * Enable interrupt for channel B in the AC97 280 * controller. 281 */ 282 ac97c_writel(atmel_wm97xx, IER, AC97C_INT_CBEVT); 283 break; 284 default: 285 dev_err(&wm->touch_dev->dev, "pen down irq not " 286 "supported on this device\n"); 287 pen_int = 0; 288 break; 289 } 290 } 291 292 return 0; 293} 294 295static void atmel_wm97xx_acc_shutdown(struct wm97xx *wm) 296{ 297 if (pen_int) { 298 struct atmel_wm97xx *atmel_wm97xx = 299 platform_get_drvdata(wm->touch_dev); 300 unsigned long ica; 301 302 switch (wm->id & 0xffff) { 303 case WM9705_ID2: /* Fall through. */ 304 case WM9712_ID2: /* Fall through. */ 305 case WM9713_ID2: 306 /* Disable slot and turn off channel B interrupts. */ 307 ica = ac97c_readl(atmel_wm97xx, ICA); 308 ica &= ~AC97C_CH_MASK(wm->acc_slot); 309 ac97c_writel(atmel_wm97xx, ICA, ica); 310 ac97c_writel(atmel_wm97xx, IDR, AC97C_INT_CBEVT); 311 ac97c_writel(atmel_wm97xx, CBMR, 0); 312 wm->pen_irq = 0; 313 break; 314 default: 315 dev_err(&wm->touch_dev->dev, "unknown codec\n"); 316 break; 317 } 318 } 319} 320 321static void atmel_wm97xx_irq_enable(struct wm97xx *wm, int enable) 322{ 323 /* Intentionally left empty. */ 324} 325 326static struct wm97xx_mach_ops atmel_mach_ops = { 327 .acc_enabled = 1, 328 .acc_pen_up = atmel_wm97xx_acc_pen_up, 329 .acc_startup = atmel_wm97xx_acc_startup, 330 .acc_shutdown = atmel_wm97xx_acc_shutdown, 331 .irq_enable = atmel_wm97xx_irq_enable, 332 .irq_gpio = WM97XX_GPIO_3, 333}; 334 335static int __init atmel_wm97xx_probe(struct platform_device *pdev) 336{ 337 struct wm97xx *wm = platform_get_drvdata(pdev); 338 struct atmel_wm97xx *atmel_wm97xx; 339 int ret; 340 341 atmel_wm97xx = kzalloc(sizeof(struct atmel_wm97xx), GFP_KERNEL); 342 if (!atmel_wm97xx) { 343 dev_dbg(&pdev->dev, "out of memory\n"); 344 return -ENOMEM; 345 } 346 347 atmel_wm97xx->wm = wm; 348 atmel_wm97xx->regs = (void *)ATMEL_WM97XX_AC97C_IOMEM; 349 atmel_wm97xx->ac97c_irq = ATMEL_WM97XX_AC97C_IRQ; 350 atmel_wm97xx->gpio_pen = atmel_gpio_line; 351 atmel_wm97xx->gpio_irq = gpio_to_irq(atmel_wm97xx->gpio_pen); 352 353 setup_timer(&atmel_wm97xx->pen_timer, atmel_wm97xx_pen_timer, 354 (unsigned long)wm); 355 356 ret = request_irq(atmel_wm97xx->ac97c_irq, 357 atmel_wm97xx_channel_b_interrupt, 358 IRQF_SHARED, "atmel-wm97xx-ch-b", atmel_wm97xx); 359 if (ret) { 360 dev_dbg(&pdev->dev, "could not request ac97c irq\n"); 361 goto err; 362 } 363 364 platform_set_drvdata(pdev, atmel_wm97xx); 365 366 ret = wm97xx_register_mach_ops(wm, &atmel_mach_ops); 367 if (ret) 368 goto err_irq; 369 370 return ret; 371 372err_irq: 373 free_irq(atmel_wm97xx->ac97c_irq, atmel_wm97xx); 374err: 375 kfree(atmel_wm97xx); 376 return ret; 377} 378 379static int __exit atmel_wm97xx_remove(struct platform_device *pdev) 380{ 381 struct atmel_wm97xx *atmel_wm97xx = platform_get_drvdata(pdev); 382 struct wm97xx *wm = atmel_wm97xx->wm; 383 384 ac97c_writel(atmel_wm97xx, IDR, AC97C_INT_CBEVT); 385 free_irq(atmel_wm97xx->ac97c_irq, atmel_wm97xx); 386 del_timer_sync(&atmel_wm97xx->pen_timer); 387 wm97xx_unregister_mach_ops(wm); 388 kfree(atmel_wm97xx); 389 390 return 0; 391} 392 393#ifdef CONFIG_PM_SLEEP 394static int atmel_wm97xx_suspend(struct device *dev) 395{ 396 struct platform_device *pdev = to_platform_device(dev); 397 struct atmel_wm97xx *atmel_wm97xx = platform_get_drvdata(pdev); 398 399 ac97c_writel(atmel_wm97xx, IDR, AC97C_INT_CBEVT); 400 disable_irq(atmel_wm97xx->gpio_irq); 401 del_timer_sync(&atmel_wm97xx->pen_timer); 402 403 return 0; 404} 405 406static int atmel_wm97xx_resume(struct device *dev) 407{ 408 struct platform_device *pdev = to_platform_device(dev); 409 struct atmel_wm97xx *atmel_wm97xx = platform_get_drvdata(pdev); 410 struct wm97xx *wm = atmel_wm97xx->wm; 411 412 if (wm->input_dev->users) { 413 enable_irq(atmel_wm97xx->gpio_irq); 414 ac97c_writel(atmel_wm97xx, IER, AC97C_INT_CBEVT); 415 } 416 417 return 0; 418} 419#endif 420 421static SIMPLE_DEV_PM_OPS(atmel_wm97xx_pm_ops, 422 atmel_wm97xx_suspend, atmel_wm97xx_resume); 423 424static struct platform_driver atmel_wm97xx_driver = { 425 .remove = __exit_p(atmel_wm97xx_remove), 426 .driver = { 427 .name = "wm97xx-touch", 428 .pm = &atmel_wm97xx_pm_ops, 429 }, 430}; 431 432module_platform_driver_probe(atmel_wm97xx_driver, atmel_wm97xx_probe); 433 434MODULE_AUTHOR("Hans-Christian Egtvedt <egtvedt@samfundet.no>"); 435MODULE_DESCRIPTION("wm97xx continuous touch driver for Atmel AT91 and AVR32"); 436MODULE_LICENSE("GPL"); 437