linux/drivers/input/touchscreen/atmel_tsadcc.c
<<
>>
Prefs
   1/*
   2 *  Atmel Touch Screen Driver
   3 *
   4 *  Copyright (c) 2008 ATMEL
   5 *  Copyright (c) 2008 Dan Liang
   6 *  Copyright (c) 2008 TimeSys Corporation
   7 *  Copyright (c) 2008 Justin Waters
   8 *
   9 *  Based on touchscreen code from Atmel Corporation.
  10 *
  11 *  This program is free software; you can redistribute it and/or modify
  12 *  it under the terms of the GNU General Public License version 2 as
  13 *  published by the Free Software Foundation.
  14 */
  15#include <linux/init.h>
  16#include <linux/err.h>
  17#include <linux/kernel.h>
  18#include <linux/module.h>
  19#include <linux/input.h>
  20#include <linux/slab.h>
  21#include <linux/interrupt.h>
  22#include <linux/clk.h>
  23#include <linux/platform_device.h>
  24#include <linux/io.h>
  25#include <linux/platform_data/atmel.h>
  26#include <mach/cpu.h>
  27
  28/* Register definitions based on AT91SAM9RL64 preliminary draft datasheet */
  29
  30#define ATMEL_TSADCC_CR         0x00    /* Control register */
  31#define   ATMEL_TSADCC_SWRST    (1 << 0)        /* Software Reset*/
  32#define   ATMEL_TSADCC_START    (1 << 1)        /* Start conversion */
  33
  34#define ATMEL_TSADCC_MR         0x04    /* Mode register */
  35#define   ATMEL_TSADCC_TSAMOD   (3    <<  0)    /* ADC mode */
  36#define     ATMEL_TSADCC_TSAMOD_ADC_ONLY_MODE   (0x0)   /* ADC Mode */
  37#define     ATMEL_TSADCC_TSAMOD_TS_ONLY_MODE    (0x1)   /* Touch Screen Only Mode */
  38#define   ATMEL_TSADCC_LOWRES   (1    <<  4)    /* Resolution selection */
  39#define   ATMEL_TSADCC_SLEEP    (1    <<  5)    /* Sleep mode */
  40#define   ATMEL_TSADCC_PENDET   (1    <<  6)    /* Pen Detect selection */
  41#define   ATMEL_TSADCC_PRES     (1    <<  7)    /* Pressure Measurement Selection */
  42#define   ATMEL_TSADCC_PRESCAL  (0x3f <<  8)    /* Prescalar Rate Selection */
  43#define   ATMEL_TSADCC_EPRESCAL (0xff <<  8)    /* Prescalar Rate Selection (Extended) */
  44#define   ATMEL_TSADCC_STARTUP  (0x7f << 16)    /* Start Up time */
  45#define   ATMEL_TSADCC_SHTIM    (0xf  << 24)    /* Sample & Hold time */
  46#define   ATMEL_TSADCC_PENDBC   (0xf  << 28)    /* Pen Detect debouncing time */
  47
  48#define ATMEL_TSADCC_TRGR       0x08    /* Trigger register */
  49#define   ATMEL_TSADCC_TRGMOD   (7      <<  0)  /* Trigger mode */
  50#define     ATMEL_TSADCC_TRGMOD_NONE            (0 << 0)
  51#define     ATMEL_TSADCC_TRGMOD_EXT_RISING      (1 << 0)
  52#define     ATMEL_TSADCC_TRGMOD_EXT_FALLING     (2 << 0)
  53#define     ATMEL_TSADCC_TRGMOD_EXT_ANY         (3 << 0)
  54#define     ATMEL_TSADCC_TRGMOD_PENDET          (4 << 0)
  55#define     ATMEL_TSADCC_TRGMOD_PERIOD          (5 << 0)
  56#define     ATMEL_TSADCC_TRGMOD_CONTINUOUS      (6 << 0)
  57#define   ATMEL_TSADCC_TRGPER   (0xffff << 16)  /* Trigger period */
  58
  59#define ATMEL_TSADCC_TSR        0x0C    /* Touch Screen register */
  60#define   ATMEL_TSADCC_TSFREQ   (0xf <<  0)     /* TS Frequency in Interleaved mode */
  61#define   ATMEL_TSADCC_TSSHTIM  (0xf << 24)     /* Sample & Hold time */
  62
  63#define ATMEL_TSADCC_CHER       0x10    /* Channel Enable register */
  64#define ATMEL_TSADCC_CHDR       0x14    /* Channel Disable register */
  65#define ATMEL_TSADCC_CHSR       0x18    /* Channel Status register */
  66#define   ATMEL_TSADCC_CH(n)    (1 << (n))      /* Channel number */
  67
  68#define ATMEL_TSADCC_SR         0x1C    /* Status register */
  69#define   ATMEL_TSADCC_EOC(n)   (1 << ((n)+0))  /* End of conversion for channel N */
  70#define   ATMEL_TSADCC_OVRE(n)  (1 << ((n)+8))  /* Overrun error for channel N */
  71#define   ATMEL_TSADCC_DRDY     (1 << 16)       /* Data Ready */
  72#define   ATMEL_TSADCC_GOVRE    (1 << 17)       /* General Overrun Error */
  73#define   ATMEL_TSADCC_ENDRX    (1 << 18)       /* End of RX Buffer */
  74#define   ATMEL_TSADCC_RXBUFF   (1 << 19)       /* TX Buffer full */
  75#define   ATMEL_TSADCC_PENCNT   (1 << 20)       /* Pen contact */
  76#define   ATMEL_TSADCC_NOCNT    (1 << 21)       /* No contact */
  77
  78#define ATMEL_TSADCC_LCDR       0x20    /* Last Converted Data register */
  79#define   ATMEL_TSADCC_DATA     (0x3ff << 0)    /* Channel data */
  80
  81#define ATMEL_TSADCC_IER        0x24    /* Interrupt Enable register */
  82#define ATMEL_TSADCC_IDR        0x28    /* Interrupt Disable register */
  83#define ATMEL_TSADCC_IMR        0x2C    /* Interrupt Mask register */
  84#define ATMEL_TSADCC_CDR0       0x30    /* Channel Data 0 */
  85#define ATMEL_TSADCC_CDR1       0x34    /* Channel Data 1 */
  86#define ATMEL_TSADCC_CDR2       0x38    /* Channel Data 2 */
  87#define ATMEL_TSADCC_CDR3       0x3C    /* Channel Data 3 */
  88#define ATMEL_TSADCC_CDR4       0x40    /* Channel Data 4 */
  89#define ATMEL_TSADCC_CDR5       0x44    /* Channel Data 5 */
  90
  91#define ATMEL_TSADCC_XPOS       0x50
  92#define ATMEL_TSADCC_Z1DAT      0x54
  93#define ATMEL_TSADCC_Z2DAT      0x58
  94
  95#define PRESCALER_VAL(x)        ((x) >> 8)
  96
  97#define ADC_DEFAULT_CLOCK       100000
  98
  99struct atmel_tsadcc {
 100        struct input_dev        *input;
 101        char                    phys[32];
 102        struct clk              *clk;
 103        int                     irq;
 104        unsigned int            prev_absx;
 105        unsigned int            prev_absy;
 106        unsigned char           bufferedmeasure;
 107};
 108
 109static void __iomem             *tsc_base;
 110
 111#define atmel_tsadcc_read(reg)          __raw_readl(tsc_base + (reg))
 112#define atmel_tsadcc_write(reg, val)    __raw_writel((val), tsc_base + (reg))
 113
 114static irqreturn_t atmel_tsadcc_interrupt(int irq, void *dev)
 115{
 116        struct atmel_tsadcc     *ts_dev = (struct atmel_tsadcc *)dev;
 117        struct input_dev        *input_dev = ts_dev->input;
 118
 119        unsigned int status;
 120        unsigned int reg;
 121
 122        status = atmel_tsadcc_read(ATMEL_TSADCC_SR);
 123        status &= atmel_tsadcc_read(ATMEL_TSADCC_IMR);
 124
 125        if (status & ATMEL_TSADCC_NOCNT) {
 126                /* Contact lost */
 127                reg = atmel_tsadcc_read(ATMEL_TSADCC_MR) | ATMEL_TSADCC_PENDBC;
 128
 129                atmel_tsadcc_write(ATMEL_TSADCC_MR, reg);
 130                atmel_tsadcc_write(ATMEL_TSADCC_TRGR, ATMEL_TSADCC_TRGMOD_NONE);
 131                atmel_tsadcc_write(ATMEL_TSADCC_IDR,
 132                                   ATMEL_TSADCC_EOC(3) | ATMEL_TSADCC_NOCNT);
 133                atmel_tsadcc_write(ATMEL_TSADCC_IER, ATMEL_TSADCC_PENCNT);
 134
 135                input_report_key(input_dev, BTN_TOUCH, 0);
 136                ts_dev->bufferedmeasure = 0;
 137                input_sync(input_dev);
 138
 139        } else if (status & ATMEL_TSADCC_PENCNT) {
 140                /* Pen detected */
 141                reg = atmel_tsadcc_read(ATMEL_TSADCC_MR);
 142                reg &= ~ATMEL_TSADCC_PENDBC;
 143
 144                atmel_tsadcc_write(ATMEL_TSADCC_IDR, ATMEL_TSADCC_PENCNT);
 145                atmel_tsadcc_write(ATMEL_TSADCC_MR, reg);
 146                atmel_tsadcc_write(ATMEL_TSADCC_IER,
 147                                   ATMEL_TSADCC_EOC(3) | ATMEL_TSADCC_NOCNT);
 148                atmel_tsadcc_write(ATMEL_TSADCC_TRGR,
 149                                   ATMEL_TSADCC_TRGMOD_PERIOD | (0x0FFF << 16));
 150
 151        } else if (status & ATMEL_TSADCC_EOC(3)) {
 152                /* Conversion finished */
 153
 154                if (ts_dev->bufferedmeasure) {
 155                        /* Last measurement is always discarded, since it can
 156                         * be erroneous.
 157                         * Always report previous measurement */
 158                        input_report_abs(input_dev, ABS_X, ts_dev->prev_absx);
 159                        input_report_abs(input_dev, ABS_Y, ts_dev->prev_absy);
 160                        input_report_key(input_dev, BTN_TOUCH, 1);
 161                        input_sync(input_dev);
 162                } else
 163                        ts_dev->bufferedmeasure = 1;
 164
 165                /* Now make new measurement */
 166                ts_dev->prev_absx = atmel_tsadcc_read(ATMEL_TSADCC_CDR3) << 10;
 167                ts_dev->prev_absx /= atmel_tsadcc_read(ATMEL_TSADCC_CDR2);
 168
 169                ts_dev->prev_absy = atmel_tsadcc_read(ATMEL_TSADCC_CDR1) << 10;
 170                ts_dev->prev_absy /= atmel_tsadcc_read(ATMEL_TSADCC_CDR0);
 171        }
 172
 173        return IRQ_HANDLED;
 174}
 175
 176/*
 177 * The functions for inserting/removing us as a module.
 178 */
 179
 180static int atmel_tsadcc_probe(struct platform_device *pdev)
 181{
 182        struct atmel_tsadcc     *ts_dev;
 183        struct input_dev        *input_dev;
 184        struct resource         *res;
 185        struct at91_tsadcc_data *pdata = pdev->dev.platform_data;
 186        int             err;
 187        unsigned int    prsc;
 188        unsigned int    reg;
 189
 190        if (!pdata)
 191                return -EINVAL;
 192
 193        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 194        if (!res) {
 195                dev_err(&pdev->dev, "no mmio resource defined.\n");
 196                return -ENXIO;
 197        }
 198
 199        /* Allocate memory for device */
 200        ts_dev = kzalloc(sizeof(struct atmel_tsadcc), GFP_KERNEL);
 201        if (!ts_dev) {
 202                dev_err(&pdev->dev, "failed to allocate memory.\n");
 203                return -ENOMEM;
 204        }
 205        platform_set_drvdata(pdev, ts_dev);
 206
 207        input_dev = input_allocate_device();
 208        if (!input_dev) {
 209                dev_err(&pdev->dev, "failed to allocate input device.\n");
 210                err = -EBUSY;
 211                goto err_free_mem;
 212        }
 213
 214        ts_dev->irq = platform_get_irq(pdev, 0);
 215        if (ts_dev->irq < 0) {
 216                dev_err(&pdev->dev, "no irq ID is designated.\n");
 217                err = -ENODEV;
 218                goto err_free_dev;
 219        }
 220
 221        if (!request_mem_region(res->start, resource_size(res),
 222                                "atmel tsadcc regs")) {
 223                dev_err(&pdev->dev, "resources is unavailable.\n");
 224                err = -EBUSY;
 225                goto err_free_dev;
 226        }
 227
 228        tsc_base = ioremap(res->start, resource_size(res));
 229        if (!tsc_base) {
 230                dev_err(&pdev->dev, "failed to map registers.\n");
 231                err = -ENOMEM;
 232                goto err_release_mem;
 233        }
 234
 235        err = request_irq(ts_dev->irq, atmel_tsadcc_interrupt, 0,
 236                        pdev->dev.driver->name, ts_dev);
 237        if (err) {
 238                dev_err(&pdev->dev, "failed to allocate irq.\n");
 239                goto err_unmap_regs;
 240        }
 241
 242        ts_dev->clk = clk_get(&pdev->dev, "tsc_clk");
 243        if (IS_ERR(ts_dev->clk)) {
 244                dev_err(&pdev->dev, "failed to get ts_clk\n");
 245                err = PTR_ERR(ts_dev->clk);
 246                goto err_free_irq;
 247        }
 248
 249        ts_dev->input = input_dev;
 250        ts_dev->bufferedmeasure = 0;
 251
 252        snprintf(ts_dev->phys, sizeof(ts_dev->phys),
 253                 "%s/input0", dev_name(&pdev->dev));
 254
 255        input_dev->name = "atmel touch screen controller";
 256        input_dev->phys = ts_dev->phys;
 257        input_dev->dev.parent = &pdev->dev;
 258
 259        __set_bit(EV_ABS, input_dev->evbit);
 260        input_set_abs_params(input_dev, ABS_X, 0, 0x3FF, 0, 0);
 261        input_set_abs_params(input_dev, ABS_Y, 0, 0x3FF, 0, 0);
 262
 263        input_set_capability(input_dev, EV_KEY, BTN_TOUCH);
 264
 265        /* clk_enable() always returns 0, no need to check it */
 266        clk_enable(ts_dev->clk);
 267
 268        prsc = clk_get_rate(ts_dev->clk);
 269        dev_info(&pdev->dev, "Master clock is set at: %d Hz\n", prsc);
 270
 271        if (!pdata->adc_clock)
 272                pdata->adc_clock = ADC_DEFAULT_CLOCK;
 273
 274        prsc = (prsc / (2 * pdata->adc_clock)) - 1;
 275
 276        /* saturate if this value is too high */
 277        if (cpu_is_at91sam9rl()) {
 278                if (prsc > PRESCALER_VAL(ATMEL_TSADCC_PRESCAL))
 279                        prsc = PRESCALER_VAL(ATMEL_TSADCC_PRESCAL);
 280        } else {
 281                if (prsc > PRESCALER_VAL(ATMEL_TSADCC_EPRESCAL))
 282                        prsc = PRESCALER_VAL(ATMEL_TSADCC_EPRESCAL);
 283        }
 284
 285        dev_info(&pdev->dev, "Prescaler is set at: %d\n", prsc);
 286
 287        reg = ATMEL_TSADCC_TSAMOD_TS_ONLY_MODE          |
 288                ((0x00 << 5) & ATMEL_TSADCC_SLEEP)      |       /* Normal Mode */
 289                ((0x01 << 6) & ATMEL_TSADCC_PENDET)     |       /* Enable Pen Detect */
 290                (prsc << 8)                             |
 291                ((0x26 << 16) & ATMEL_TSADCC_STARTUP)   |
 292                ((pdata->pendet_debounce << 28) & ATMEL_TSADCC_PENDBC);
 293
 294        atmel_tsadcc_write(ATMEL_TSADCC_CR, ATMEL_TSADCC_SWRST);
 295        atmel_tsadcc_write(ATMEL_TSADCC_MR, reg);
 296        atmel_tsadcc_write(ATMEL_TSADCC_TRGR, ATMEL_TSADCC_TRGMOD_NONE);
 297        atmel_tsadcc_write(ATMEL_TSADCC_TSR,
 298                (pdata->ts_sample_hold_time << 24) & ATMEL_TSADCC_TSSHTIM);
 299
 300        atmel_tsadcc_read(ATMEL_TSADCC_SR);
 301        atmel_tsadcc_write(ATMEL_TSADCC_IER, ATMEL_TSADCC_PENCNT);
 302
 303        /* All went ok, so register to the input system */
 304        err = input_register_device(input_dev);
 305        if (err)
 306                goto err_fail;
 307
 308        return 0;
 309
 310err_fail:
 311        clk_disable(ts_dev->clk);
 312        clk_put(ts_dev->clk);
 313err_free_irq:
 314        free_irq(ts_dev->irq, ts_dev);
 315err_unmap_regs:
 316        iounmap(tsc_base);
 317err_release_mem:
 318        release_mem_region(res->start, resource_size(res));
 319err_free_dev:
 320        input_free_device(input_dev);
 321err_free_mem:
 322        kfree(ts_dev);
 323        return err;
 324}
 325
 326static int atmel_tsadcc_remove(struct platform_device *pdev)
 327{
 328        struct atmel_tsadcc *ts_dev = platform_get_drvdata(pdev);
 329        struct resource *res;
 330
 331        free_irq(ts_dev->irq, ts_dev);
 332
 333        input_unregister_device(ts_dev->input);
 334
 335        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 336        iounmap(tsc_base);
 337        release_mem_region(res->start, resource_size(res));
 338
 339        clk_disable(ts_dev->clk);
 340        clk_put(ts_dev->clk);
 341
 342        kfree(ts_dev);
 343
 344        return 0;
 345}
 346
 347static struct platform_driver atmel_tsadcc_driver = {
 348        .probe          = atmel_tsadcc_probe,
 349        .remove         = atmel_tsadcc_remove,
 350        .driver         = {
 351                .name   = "atmel_tsadcc",
 352        },
 353};
 354module_platform_driver(atmel_tsadcc_driver);
 355
 356MODULE_LICENSE("GPL");
 357MODULE_DESCRIPTION("Atmel TouchScreen Driver");
 358MODULE_AUTHOR("Dan Liang <dan.liang@atmel.com>");
 359
 360