]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - drivers/input/touchscreen/atmel_tsadcc.c
Merge branch 'timers-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[mv-sheeva.git] / drivers / input / touchscreen / atmel_tsadcc.c
index 9c7fce4d74d09b3f6ec1927e87ad659a6fc8a910..3d9b5166ebe95d79712b9382d4f22ef666386e7c 100644 (file)
@@ -22,6 +22,8 @@
 #include <linux/clk.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
+#include <mach/board.h>
+#include <mach/cpu.h>
 
 /* Register definitions based on AT91SAM9RL64 preliminary draft datasheet */
 
@@ -36,7 +38,9 @@
 #define          ATMEL_TSADCC_LOWRES   (1    <<  4)    /* Resolution selection */
 #define          ATMEL_TSADCC_SLEEP    (1    <<  5)    /* Sleep mode */
 #define          ATMEL_TSADCC_PENDET   (1    <<  6)    /* Pen Detect selection */
+#define          ATMEL_TSADCC_PRES     (1    <<  7)    /* Pressure Measurement Selection */
 #define          ATMEL_TSADCC_PRESCAL  (0x3f <<  8)    /* Prescalar Rate Selection */
+#define          ATMEL_TSADCC_EPRESCAL (0xff <<  8)    /* Prescalar Rate Selection (Extended) */
 #define          ATMEL_TSADCC_STARTUP  (0x7f << 16)    /* Start Up time */
 #define          ATMEL_TSADCC_SHTIM    (0xf  << 24)    /* Sample & Hold time */
 #define          ATMEL_TSADCC_PENDBC   (0xf  << 28)    /* Pen Detect debouncing time */
 #define ATMEL_TSADCC_CDR4      0x40    /* Channel Data 4 */
 #define ATMEL_TSADCC_CDR5      0x44    /* Channel Data 5 */
 
-#define ADC_CLOCK      1000000
+#define ATMEL_TSADCC_XPOS      0x50
+#define ATMEL_TSADCC_Z1DAT     0x54
+#define ATMEL_TSADCC_Z2DAT     0x58
+
+#define PRESCALER_VAL(x)       ((x) >> 8)
+
+#define ADC_DEFAULT_CLOCK      100000
 
 struct atmel_tsadcc {
        struct input_dev        *input;
@@ -172,6 +182,7 @@ static int __devinit atmel_tsadcc_probe(struct platform_device *pdev)
        struct atmel_tsadcc     *ts_dev;
        struct input_dev        *input_dev;
        struct resource         *res;
+       struct at91_tsadcc_data *pdata = pdev->dev.platform_data;
        int             err = 0;
        unsigned int    prsc;
        unsigned int    reg;
@@ -242,31 +253,49 @@ static int __devinit atmel_tsadcc_probe(struct platform_device *pdev)
        input_dev->phys = ts_dev->phys;
        input_dev->dev.parent = &pdev->dev;
 
-       input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
-       input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
-
+       __set_bit(EV_ABS, input_dev->evbit);
        input_set_abs_params(input_dev, ABS_X, 0, 0x3FF, 0, 0);
        input_set_abs_params(input_dev, ABS_Y, 0, 0x3FF, 0, 0);
 
+       input_set_capability(input_dev, EV_KEY, BTN_TOUCH);
+
        /* clk_enable() always returns 0, no need to check it */
        clk_enable(ts_dev->clk);
 
        prsc = clk_get_rate(ts_dev->clk);
        dev_info(&pdev->dev, "Master clock is set at: %d Hz\n", prsc);
 
-       prsc = prsc / ADC_CLOCK / 2 - 1;
+       if (!pdata)
+               goto err_fail;
+
+       if (!pdata->adc_clock)
+               pdata->adc_clock = ADC_DEFAULT_CLOCK;
+
+       prsc = (prsc / (2 * pdata->adc_clock)) - 1;
+
+       /* saturate if this value is too high */
+       if (cpu_is_at91sam9rl()) {
+               if (prsc > PRESCALER_VAL(ATMEL_TSADCC_PRESCAL))
+                       prsc = PRESCALER_VAL(ATMEL_TSADCC_PRESCAL);
+       } else {
+               if (prsc > PRESCALER_VAL(ATMEL_TSADCC_EPRESCAL))
+                       prsc = PRESCALER_VAL(ATMEL_TSADCC_EPRESCAL);
+       }
+
+       dev_info(&pdev->dev, "Prescaler is set at: %d\n", prsc);
 
        reg = ATMEL_TSADCC_TSAMOD_TS_ONLY_MODE          |
                ((0x00 << 5) & ATMEL_TSADCC_SLEEP)      |       /* Normal Mode */
                ((0x01 << 6) & ATMEL_TSADCC_PENDET)     |       /* Enable Pen Detect */
-               ((prsc << 8) & ATMEL_TSADCC_PRESCAL)    |       /* PRESCAL */
-               ((0x13 << 16) & ATMEL_TSADCC_STARTUP)   |       /* STARTUP */
-               ((0x0F << 28) & ATMEL_TSADCC_PENDBC);           /* PENDBC */
+               (prsc << 8)                             |
+               ((0x26 << 16) & ATMEL_TSADCC_STARTUP)   |
+               ((pdata->pendet_debounce << 28) & ATMEL_TSADCC_PENDBC);
 
        atmel_tsadcc_write(ATMEL_TSADCC_CR, ATMEL_TSADCC_SWRST);
        atmel_tsadcc_write(ATMEL_TSADCC_MR, reg);
        atmel_tsadcc_write(ATMEL_TSADCC_TRGR, ATMEL_TSADCC_TRGMOD_NONE);
-       atmel_tsadcc_write(ATMEL_TSADCC_TSR, (0x3 << 24) & ATMEL_TSADCC_TSSHTIM);
+       atmel_tsadcc_write(ATMEL_TSADCC_TSR,
+               (pdata->ts_sample_hold_time << 24) & ATMEL_TSADCC_TSSHTIM);
 
        atmel_tsadcc_read(ATMEL_TSADCC_SR);
        atmel_tsadcc_write(ATMEL_TSADCC_IER, ATMEL_TSADCC_PENCNT);