root/drivers/input/touchscreen/mainstone-wm97xx.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. wm97xx_acc_pen_up
  2. wm97xx_acc_pen_up
  3. wm97xx_acc_pen_down
  4. wm97xx_acc_startup
  5. wm97xx_acc_shutdown
  6. wm97xx_irq_enable
  7. mainstone_wm97xx_probe
  8. mainstone_wm97xx_remove

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  * mainstone-wm97xx.c  --  Mainstone Continuous Touch screen driver for
   4  *                         Wolfson WM97xx AC97 Codecs.
   5  *
   6  * Copyright 2004, 2007 Wolfson Microelectronics PLC.
   7  * Author: Liam Girdwood <lrg@slimlogic.co.uk>
   8  * Parts Copyright : Ian Molton <spyro@f2s.com>
   9  *                   Andrew Zabolotny <zap@homelink.ru>
  10  *
  11  * Notes:
  12  *     This is a wm97xx extended touch driver to capture touch
  13  *     data in a continuous manner on the Intel XScale architecture
  14  *
  15  *  Features:
  16  *       - codecs supported:- WM9705, WM9712, WM9713
  17  *       - processors supported:- Intel XScale PXA25x, PXA26x, PXA27x
  18  */
  19 
  20 #include <linux/module.h>
  21 #include <linux/moduleparam.h>
  22 #include <linux/kernel.h>
  23 #include <linux/delay.h>
  24 #include <linux/irq.h>
  25 #include <linux/interrupt.h>
  26 #include <linux/wm97xx.h>
  27 #include <linux/io.h>
  28 #include <linux/gpio.h>
  29 
  30 #include <mach/regs-ac97.h>
  31 
  32 #include <asm/mach-types.h>
  33 
  34 struct continuous {
  35         u16 id;    /* codec id */
  36         u8 code;   /* continuous code */
  37         u8 reads;  /* number of coord reads per read cycle */
  38         u32 speed; /* number of coords per second */
  39 };
  40 
  41 #define WM_READS(sp) ((sp / HZ) + 1)
  42 
  43 static const struct continuous cinfo[] = {
  44         {WM9705_ID2, 0, WM_READS(94), 94},
  45         {WM9705_ID2, 1, WM_READS(188), 188},
  46         {WM9705_ID2, 2, WM_READS(375), 375},
  47         {WM9705_ID2, 3, WM_READS(750), 750},
  48         {WM9712_ID2, 0, WM_READS(94), 94},
  49         {WM9712_ID2, 1, WM_READS(188), 188},
  50         {WM9712_ID2, 2, WM_READS(375), 375},
  51         {WM9712_ID2, 3, WM_READS(750), 750},
  52         {WM9713_ID2, 0, WM_READS(94), 94},
  53         {WM9713_ID2, 1, WM_READS(120), 120},
  54         {WM9713_ID2, 2, WM_READS(154), 154},
  55         {WM9713_ID2, 3, WM_READS(188), 188},
  56 };
  57 
  58 /* continuous speed index */
  59 static int sp_idx;
  60 static u16 last, tries;
  61 static int irq;
  62 
  63 /*
  64  * Pen sampling frequency (Hz) in continuous mode.
  65  */
  66 static int cont_rate = 200;
  67 module_param(cont_rate, int, 0);
  68 MODULE_PARM_DESC(cont_rate, "Sampling rate in continuous mode (Hz)");
  69 
  70 /*
  71  * Pen down detection.
  72  *
  73  * This driver can either poll or use an interrupt to indicate a pen down
  74  * event. If the irq request fails then it will fall back to polling mode.
  75  */
  76 static int pen_int;
  77 module_param(pen_int, int, 0);
  78 MODULE_PARM_DESC(pen_int, "Pen down detection (1 = interrupt, 0 = polling)");
  79 
  80 /*
  81  * Pressure readback.
  82  *
  83  * Set to 1 to read back pen down pressure
  84  */
  85 static int pressure;
  86 module_param(pressure, int, 0);
  87 MODULE_PARM_DESC(pressure, "Pressure readback (1 = pressure, 0 = no pressure)");
  88 
  89 /*
  90  * AC97 touch data slot.
  91  *
  92  * Touch screen readback data ac97 slot
  93  */
  94 static int ac97_touch_slot = 5;
  95 module_param(ac97_touch_slot, int, 0);
  96 MODULE_PARM_DESC(ac97_touch_slot, "Touch screen data slot AC97 number");
  97 
  98 
  99 /* flush AC97 slot 5 FIFO on pxa machines */
 100 #ifdef CONFIG_PXA27x
 101 static void wm97xx_acc_pen_up(struct wm97xx *wm)
 102 {
 103         schedule_timeout_uninterruptible(1);
 104 
 105         while (MISR & (1 << 2))
 106                 MODR;
 107 }
 108 #else
 109 static void wm97xx_acc_pen_up(struct wm97xx *wm)
 110 {
 111         unsigned int count;
 112 
 113         schedule_timeout_uninterruptible(1);
 114 
 115         for (count = 0; count < 16; count++)
 116                 MODR;
 117 }
 118 #endif
 119 
 120 static int wm97xx_acc_pen_down(struct wm97xx *wm)
 121 {
 122         u16 x, y, p = 0x100 | WM97XX_ADCSEL_PRES;
 123         int reads = 0;
 124 
 125         /* When the AC97 queue has been drained we need to allow time
 126          * to buffer up samples otherwise we end up spinning polling
 127          * for samples.  The controller can't have a suitably low
 128          * threshold set to use the notifications it gives.
 129          */
 130         schedule_timeout_uninterruptible(1);
 131 
 132         if (tries > 5) {
 133                 tries = 0;
 134                 return RC_PENUP;
 135         }
 136 
 137         x = MODR;
 138         if (x == last) {
 139                 tries++;
 140                 return RC_AGAIN;
 141         }
 142         last = x;
 143         do {
 144                 if (reads)
 145                         x = MODR;
 146                 y = MODR;
 147                 if (pressure)
 148                         p = MODR;
 149 
 150                 dev_dbg(wm->dev, "Raw coordinates: x=%x, y=%x, p=%x\n",
 151                         x, y, p);
 152 
 153                 /* are samples valid */
 154                 if ((x & WM97XX_ADCSEL_MASK) != WM97XX_ADCSEL_X ||
 155                     (y & WM97XX_ADCSEL_MASK) != WM97XX_ADCSEL_Y ||
 156                     (p & WM97XX_ADCSEL_MASK) != WM97XX_ADCSEL_PRES)
 157                         goto up;
 158 
 159                 /* coordinate is good */
 160                 tries = 0;
 161                 input_report_abs(wm->input_dev, ABS_X, x & 0xfff);
 162                 input_report_abs(wm->input_dev, ABS_Y, y & 0xfff);
 163                 input_report_abs(wm->input_dev, ABS_PRESSURE, p & 0xfff);
 164                 input_report_key(wm->input_dev, BTN_TOUCH, (p != 0));
 165                 input_sync(wm->input_dev);
 166                 reads++;
 167         } while (reads < cinfo[sp_idx].reads);
 168 up:
 169         return RC_PENDOWN | RC_AGAIN;
 170 }
 171 
 172 static int wm97xx_acc_startup(struct wm97xx *wm)
 173 {
 174         int idx = 0, ret = 0;
 175 
 176         /* check we have a codec */
 177         if (wm->ac97 == NULL)
 178                 return -ENODEV;
 179 
 180         /* Go you big red fire engine */
 181         for (idx = 0; idx < ARRAY_SIZE(cinfo); idx++) {
 182                 if (wm->id != cinfo[idx].id)
 183                         continue;
 184                 sp_idx = idx;
 185                 if (cont_rate <= cinfo[idx].speed)
 186                         break;
 187         }
 188         wm->acc_rate = cinfo[sp_idx].code;
 189         wm->acc_slot = ac97_touch_slot;
 190         dev_info(wm->dev,
 191                  "mainstone accelerated touchscreen driver, %d samples/sec\n",
 192                  cinfo[sp_idx].speed);
 193 
 194         /* IRQ driven touchscreen is used on Palm hardware */
 195         if (machine_is_palmt5() || machine_is_palmtx() || machine_is_palmld()) {
 196                 pen_int = 1;
 197                 irq = 27;
 198                 /* There is some obscure mutant of WM9712 interbred with WM9713
 199                  * used on Palm HW */
 200                 wm->variant = WM97xx_WM1613;
 201         } else if (machine_is_mainstone() && pen_int)
 202                 irq = 4;
 203 
 204         if (irq) {
 205                 ret = gpio_request(irq, "Touchscreen IRQ");
 206                 if (ret)
 207                         goto out;
 208 
 209                 ret = gpio_direction_input(irq);
 210                 if (ret) {
 211                         gpio_free(irq);
 212                         goto out;
 213                 }
 214 
 215                 wm->pen_irq = gpio_to_irq(irq);
 216                 irq_set_irq_type(wm->pen_irq, IRQ_TYPE_EDGE_BOTH);
 217         } else /* pen irq not supported */
 218                 pen_int = 0;
 219 
 220         /* codec specific irq config */
 221         if (pen_int) {
 222                 switch (wm->id) {
 223                 case WM9705_ID2:
 224                         break;
 225                 case WM9712_ID2:
 226                 case WM9713_ID2:
 227                         /* use PEN_DOWN GPIO 13 to assert IRQ on GPIO line 2 */
 228                         wm97xx_config_gpio(wm, WM97XX_GPIO_13, WM97XX_GPIO_IN,
 229                                            WM97XX_GPIO_POL_HIGH,
 230                                            WM97XX_GPIO_STICKY,
 231                                            WM97XX_GPIO_WAKE);
 232                         wm97xx_config_gpio(wm, WM97XX_GPIO_2, WM97XX_GPIO_OUT,
 233                                            WM97XX_GPIO_POL_HIGH,
 234                                            WM97XX_GPIO_NOTSTICKY,
 235                                            WM97XX_GPIO_NOWAKE);
 236                         break;
 237                 default:
 238                         dev_err(wm->dev,
 239                                 "pen down irq not supported on this device\n");
 240                         pen_int = 0;
 241                         break;
 242                 }
 243         }
 244 
 245 out:
 246         return ret;
 247 }
 248 
 249 static void wm97xx_acc_shutdown(struct wm97xx *wm)
 250 {
 251         /* codec specific deconfig */
 252         if (pen_int) {
 253                 if (irq)
 254                         gpio_free(irq);
 255                 wm->pen_irq = 0;
 256         }
 257 }
 258 
 259 static void wm97xx_irq_enable(struct wm97xx *wm, int enable)
 260 {
 261         if (enable)
 262                 enable_irq(wm->pen_irq);
 263         else
 264                 disable_irq_nosync(wm->pen_irq);
 265 }
 266 
 267 static struct wm97xx_mach_ops mainstone_mach_ops = {
 268         .acc_enabled = 1,
 269         .acc_pen_up = wm97xx_acc_pen_up,
 270         .acc_pen_down = wm97xx_acc_pen_down,
 271         .acc_startup = wm97xx_acc_startup,
 272         .acc_shutdown = wm97xx_acc_shutdown,
 273         .irq_enable = wm97xx_irq_enable,
 274         .irq_gpio = WM97XX_GPIO_2,
 275 };
 276 
 277 static int mainstone_wm97xx_probe(struct platform_device *pdev)
 278 {
 279         struct wm97xx *wm = platform_get_drvdata(pdev);
 280 
 281         return wm97xx_register_mach_ops(wm, &mainstone_mach_ops);
 282 }
 283 
 284 static int mainstone_wm97xx_remove(struct platform_device *pdev)
 285 {
 286         struct wm97xx *wm = platform_get_drvdata(pdev);
 287 
 288         wm97xx_unregister_mach_ops(wm);
 289         return 0;
 290 }
 291 
 292 static struct platform_driver mainstone_wm97xx_driver = {
 293         .probe = mainstone_wm97xx_probe,
 294         .remove = mainstone_wm97xx_remove,
 295         .driver = {
 296                 .name = "wm97xx-touch",
 297         },
 298 };
 299 module_platform_driver(mainstone_wm97xx_driver);
 300 
 301 /* Module information */
 302 MODULE_AUTHOR("Liam Girdwood <lrg@slimlogic.co.uk>");
 303 MODULE_DESCRIPTION("wm97xx continuous touch driver for mainstone");
 304 MODULE_LICENSE("GPL");

/* [<][>][^][v][top][bottom][index][help] */