]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/input/touchscreen/ads7846.c
Merge current mainline tree into linux-omap tree
[linux-2.6-omap-h63xx.git] / drivers / input / touchscreen / ads7846.c
index cc1db125a14a5d0d6f0e9cb568ee43ebab9bd328..7a1ac271785a0ee6ffee92c6e095565399170cbe 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/input.h>
 #include <linux/interrupt.h>
 #include <linux/slab.h>
+#include <linux/gpio.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/ads7846.h>
 #include <asm/irq.h>
@@ -68,6 +69,17 @@ struct ts_event {
        int     ignore;
 };
 
+/*
+ * We allocate this separately to avoid cache line sharing issues when
+ * driver is used with DMA-based SPI controllers (like atmel_spi) on
+ * systems where main memory is not DMA-coherent (most non-x86 boards).
+ */
+struct ads7846_packet {
+       u8                      read_x, read_y, read_z1, read_z2, pwrdown;
+       u16                     dummy;          /* for the pwrdown read */
+       struct ts_event         tc;
+};
+
 struct ads7846 {
        struct input_dev        *input;
        char                    phys[32];
@@ -85,9 +97,7 @@ struct ads7846 {
        u16                     x_plate_ohms;
        u16                     pressure_max;
 
-       u8                      read_x, read_y, read_z1, read_z2, pwrdown;
-       u16                     dummy;          /* for the pwrdown read */
-       struct ts_event         tc;
+       struct ads7846_packet   *packet;
 
        struct spi_transfer     xfer[18];
        struct spi_message      msg[5];
@@ -116,6 +126,7 @@ struct ads7846 {
        void                    *filter_data;
        void                    (*filter_cleanup)(void *data);
        int                     (*get_pendown_state)(void);
+       int                     gpio_pendown;
 };
 
 /* leave chip selected when we're done, for quicker re-select? */
@@ -461,10 +472,11 @@ static ssize_t ads7846_disable_store(struct device *dev,
                                     const char *buf, size_t count)
 {
        struct ads7846 *ts = dev_get_drvdata(dev);
-       char *endp;
-       int i;
+       long i;
+
+       if (strict_strtoul(buf, 10, &i))
+               return -EINVAL;
 
-       i = simple_strtoul(buf, &endp, 10);
        spin_lock_irq(&ts->lock);
 
        if (i)
@@ -491,6 +503,14 @@ static struct attribute_group ads784x_attr_group = {
 
 /*--------------------------------------------------------------------------*/
 
+static int get_pendown_state(struct ads7846 *ts)
+{
+       if (ts->get_pendown_state)
+               return ts->get_pendown_state();
+
+       return !gpio_get_value(ts->gpio_pendown);
+}
+
 /*
  * PENIRQ only kicks the timer.  The timer only reissues the SPI transfer,
  * to retrieve touchscreen status.
@@ -502,16 +522,17 @@ static struct attribute_group ads784x_attr_group = {
 static void ads7846_rx(void *ads)
 {
        struct ads7846          *ts = ads;
+       struct ads7846_packet   *packet = ts->packet;
        unsigned                Rt;
        u16                     x, y, z1, z2;
 
        /* ads7846_rx_val() did in-place conversion (including byteswap) from
         * on-the-wire format as part of debouncing to get stable readings.
         */
-       x = ts->tc.x;
-       y = ts->tc.y;
-       z1 = ts->tc.z1;
-       z2 = ts->tc.z2;
+       x = packet->tc.x;
+       y = packet->tc.y;
+       z1 = packet->tc.z1;
+       z2 = packet->tc.z2;
 
        /* range filtering */
        if (x == MAX_12BIT)
@@ -535,10 +556,10 @@ static void ads7846_rx(void *ads)
         * the maximum. Don't report it to user space, repeat at least
         * once more the measurement
         */
-       if (ts->tc.ignore || Rt > ts->pressure_max) {
+       if (packet->tc.ignore || Rt > ts->pressure_max) {
 #ifdef VERBOSE
                pr_debug("%s: ignored %d pressure %d\n",
-                       ts->spi->dev.bus_id, ts->tc.ignore, Rt);
+                       ts->spi->dev.bus_id, packet->tc.ignore, Rt);
 #endif
                hrtimer_start(&ts->timer, ktime_set(0, TS_POLL_PERIOD),
                              HRTIMER_MODE_REL);
@@ -550,7 +571,7 @@ static void ads7846_rx(void *ads)
         */
        if (ts->penirq_recheck_delay_usecs) {
                udelay(ts->penirq_recheck_delay_usecs);
-               if (!ts->get_pendown_state())
+               if (!get_pendown_state(ts))
                        Rt = 0;
        }
 
@@ -631,6 +652,7 @@ static int ads7846_no_filter(void *ads, int data_idx, int *val)
 static void ads7846_rx_val(void *ads)
 {
        struct ads7846 *ts = ads;
+       struct ads7846_packet *packet = ts->packet;
        struct spi_message *m;
        struct spi_transfer *t;
        int val;
@@ -650,7 +672,7 @@ static void ads7846_rx_val(void *ads)
        case ADS7846_FILTER_REPEAT:
                break;
        case ADS7846_FILTER_IGNORE:
-               ts->tc.ignore = 1;
+               packet->tc.ignore = 1;
                /* Last message will contain ads7846_rx() as the
                 * completion function.
                 */
@@ -658,7 +680,7 @@ static void ads7846_rx_val(void *ads)
                break;
        case ADS7846_FILTER_OK:
                *(u16 *)t->rx_buf = val;
-               ts->tc.ignore = 0;
+               packet->tc.ignore = 0;
                m = &ts->msg[++ts->msg_idx];
                break;
        default:
@@ -677,7 +699,7 @@ static enum hrtimer_restart ads7846_timer(struct hrtimer *handle)
 
        spin_lock_irq(&ts->lock);
 
-       if (unlikely(!ts->get_pendown_state() ||
+       if (unlikely(!get_pendown_state(ts) ||
                     device_suspended(&ts->spi->dev))) {
                if (ts->pendown) {
                        struct input_dev *input = ts->input;
@@ -716,7 +738,7 @@ static irqreturn_t ads7846_irq(int irq, void *handle)
        unsigned long flags;
 
        spin_lock_irqsave(&ts->lock, flags);
-       if (likely(ts->get_pendown_state())) {
+       if (likely(get_pendown_state(ts))) {
                if (!ts->irq_disabled) {
                        /* The ARM do_simple_IRQ() dispatcher doesn't act
                         * like the other dispatchers:  it will report IRQs
@@ -763,7 +785,6 @@ static void ads7846_disable(struct ads7846 *ts)
        /* we know the chip's in lowpower mode since we always
         * leave it that way after every request
         */
-
 }
 
 /* Must be called with ts->lock held */
@@ -806,9 +827,40 @@ static int ads7846_resume(struct spi_device *spi)
        return 0;
 }
 
+static int __devinit setup_pendown(struct spi_device *spi, struct ads7846 *ts)
+{
+       struct ads7846_platform_data *pdata = spi->dev.platform_data;
+       int err;
+
+       /* REVISIT when the irq can be triggered active-low, or if for some
+        * reason the touchscreen isn't hooked up, we don't need to access
+        * the pendown state.
+        */
+       if (!pdata->get_pendown_state && !gpio_is_valid(pdata->gpio_pendown)) {
+               dev_err(&spi->dev, "no get_pendown_state nor gpio_pendown?\n");
+               return -EINVAL;
+       }
+
+       if (pdata->get_pendown_state) {
+               ts->get_pendown_state = pdata->get_pendown_state;
+               return 0;
+       }
+
+       err = gpio_request(pdata->gpio_pendown, "ads7846_pendown");
+       if (err) {
+               dev_err(&spi->dev, "failed to request pendown GPIO%d\n",
+                               pdata->gpio_pendown);
+               return err;
+       }
+
+       ts->gpio_pendown = pdata->gpio_pendown;
+       return 0;
+}
+
 static int __devinit ads7846_probe(struct spi_device *spi)
 {
        struct ads7846                  *ts;
+       struct ads7846_packet           *packet;
        struct input_dev                *input_dev;
        struct ads7846_platform_data    *pdata = spi->dev.platform_data;
        struct spi_message              *m;
@@ -842,15 +894,6 @@ static int __devinit ads7846_probe(struct spi_device *spi)
                return -EINVAL;
        }
 
-       /* REVISIT when the irq can be triggered active-low, or if for some
-        * reason the touchscreen isn't hooked up, we don't need to access
-        * the pendown state.
-        */
-       if (pdata->get_pendown_state == NULL) {
-               dev_dbg(&spi->dev, "no get_pendown_state function?\n");
-               return -EINVAL;
-       }
-
        /* We'd set TX wordsize 8 bits and RX wordsize to 13 bits ... except
         * that even if the hardware can do that, the SPI controller driver
         * may not.  So we stick to very-portable 8 bit words, both RX and TX.
@@ -862,14 +905,16 @@ static int __devinit ads7846_probe(struct spi_device *spi)
                return err;
 
        ts = kzalloc(sizeof(struct ads7846), GFP_KERNEL);
+       packet = kzalloc(sizeof(struct ads7846_packet), GFP_KERNEL);
        input_dev = input_allocate_device();
-       if (!ts || !input_dev) {
+       if (!ts || !packet || !input_dev) {
                err = -ENOMEM;
                goto err_free_mem;
        }
 
        dev_set_drvdata(&spi->dev, ts);
 
+       ts->packet = packet;
        ts->spi = spi;
        ts->input = input_dev;
        ts->vref_mv = pdata->vref_mv;
@@ -902,7 +947,10 @@ static int __devinit ads7846_probe(struct spi_device *spi)
                ts->filter_data = ts;
        } else
                ts->filter = ads7846_no_filter;
-       ts->get_pendown_state = pdata->get_pendown_state;
+
+       err = setup_pendown(spi, ts);
+       if (err)
+               goto err_cleanup_filter;
 
        if (pdata->penirq_recheck_delay_usecs)
                ts->penirq_recheck_delay_usecs =
@@ -938,13 +986,13 @@ static int __devinit ads7846_probe(struct spi_device *spi)
        spi_message_init(m);
 
        /* y- still on; turn on only y+ (and ADC) */
-       ts->read_y = READ_Y(vref);
-       x->tx_buf = &ts->read_y;
+       packet->read_y = READ_Y(vref);
+       x->tx_buf = &packet->read_y;
        x->len = 1;
        spi_message_add_tail(x, m);
 
        x++;
-       x->rx_buf = &ts->tc.y;
+       x->rx_buf = &packet->tc.y;
        x->len = 2;
        spi_message_add_tail(x, m);
 
@@ -956,12 +1004,12 @@ static int __devinit ads7846_probe(struct spi_device *spi)
                x->delay_usecs = pdata->settle_delay_usecs;
 
                x++;
-               x->tx_buf = &ts->read_y;
+               x->tx_buf = &packet->read_y;
                x->len = 1;
                spi_message_add_tail(x, m);
 
                x++;
-               x->rx_buf = &ts->tc.y;
+               x->rx_buf = &packet->tc.y;
                x->len = 2;
                spi_message_add_tail(x, m);
        }
@@ -974,13 +1022,13 @@ static int __devinit ads7846_probe(struct spi_device *spi)
 
        /* turn y- off, x+ on, then leave in lowpower */
        x++;
-       ts->read_x = READ_X(vref);
-       x->tx_buf = &ts->read_x;
+       packet->read_x = READ_X(vref);
+       x->tx_buf = &packet->read_x;
        x->len = 1;
        spi_message_add_tail(x, m);
 
        x++;
-       x->rx_buf = &ts->tc.x;
+       x->rx_buf = &packet->tc.x;
        x->len = 2;
        spi_message_add_tail(x, m);
 
@@ -989,12 +1037,12 @@ static int __devinit ads7846_probe(struct spi_device *spi)
                x->delay_usecs = pdata->settle_delay_usecs;
 
                x++;
-               x->tx_buf = &ts->read_x;
+               x->tx_buf = &packet->read_x;
                x->len = 1;
                spi_message_add_tail(x, m);
 
                x++;
-               x->rx_buf = &ts->tc.x;
+               x->rx_buf = &packet->tc.x;
                x->len = 2;
                spi_message_add_tail(x, m);
        }
@@ -1008,13 +1056,13 @@ static int __devinit ads7846_probe(struct spi_device *spi)
                spi_message_init(m);
 
                x++;
-               ts->read_z1 = READ_Z1(vref);
-               x->tx_buf = &ts->read_z1;
+               packet->read_z1 = READ_Z1(vref);
+               x->tx_buf = &packet->read_z1;
                x->len = 1;
                spi_message_add_tail(x, m);
 
                x++;
-               x->rx_buf = &ts->tc.z1;
+               x->rx_buf = &packet->tc.z1;
                x->len = 2;
                spi_message_add_tail(x, m);
 
@@ -1023,12 +1071,12 @@ static int __devinit ads7846_probe(struct spi_device *spi)
                        x->delay_usecs = pdata->settle_delay_usecs;
 
                        x++;
-                       x->tx_buf = &ts->read_z1;
+                       x->tx_buf = &packet->read_z1;
                        x->len = 1;
                        spi_message_add_tail(x, m);
 
                        x++;
-                       x->rx_buf = &ts->tc.z1;
+                       x->rx_buf = &packet->tc.z1;
                        x->len = 2;
                        spi_message_add_tail(x, m);
                }
@@ -1040,13 +1088,13 @@ static int __devinit ads7846_probe(struct spi_device *spi)
                spi_message_init(m);
 
                x++;
-               ts->read_z2 = READ_Z2(vref);
-               x->tx_buf = &ts->read_z2;
+               packet->read_z2 = READ_Z2(vref);
+               x->tx_buf = &packet->read_z2;
                x->len = 1;
                spi_message_add_tail(x, m);
 
                x++;
-               x->rx_buf = &ts->tc.z2;
+               x->rx_buf = &packet->tc.z2;
                x->len = 2;
                spi_message_add_tail(x, m);
 
@@ -1055,12 +1103,12 @@ static int __devinit ads7846_probe(struct spi_device *spi)
                        x->delay_usecs = pdata->settle_delay_usecs;
 
                        x++;
-                       x->tx_buf = &ts->read_z2;
+                       x->tx_buf = &packet->read_z2;
                        x->len = 1;
                        spi_message_add_tail(x, m);
 
                        x++;
-                       x->rx_buf = &ts->tc.z2;
+                       x->rx_buf = &packet->tc.z2;
                        x->len = 2;
                        spi_message_add_tail(x, m);
                }
@@ -1074,13 +1122,13 @@ static int __devinit ads7846_probe(struct spi_device *spi)
        spi_message_init(m);
 
        x++;
-       ts->pwrdown = PWRDOWN;
-       x->tx_buf = &ts->pwrdown;
+       packet->pwrdown = PWRDOWN;
+       x->tx_buf = &packet->pwrdown;
        x->len = 1;
        spi_message_add_tail(x, m);
 
        x++;
-       x->rx_buf = &ts->dummy;
+       x->rx_buf = &packet->dummy;
        x->len = 2;
        CS_CHANGE(*x);
        spi_message_add_tail(x, m);
@@ -1094,7 +1142,7 @@ static int __devinit ads7846_probe(struct spi_device *spi)
                        spi->dev.driver->name, ts)) {
                dev_dbg(&spi->dev, "irq %d busy?\n", spi->irq);
                err = -EBUSY;
-               goto err_cleanup_filter;
+               goto err_free_gpio;
        }
 
        err = ads784x_hwmon_register(spi, ts);
@@ -1125,11 +1173,15 @@ static int __devinit ads7846_probe(struct spi_device *spi)
        ads784x_hwmon_unregister(spi, ts);
  err_free_irq:
        free_irq(spi->irq, ts);
+ err_free_gpio:
+       if (ts->gpio_pendown != -1)
+               gpio_free(ts->gpio_pendown);
  err_cleanup_filter:
        if (ts->filter_cleanup)
                ts->filter_cleanup(ts->filter_data);
  err_free_mem:
        input_free_device(input_dev);
+       kfree(packet);
        kfree(ts);
        return err;
 }
@@ -1149,9 +1201,13 @@ static int __devexit ads7846_remove(struct spi_device *spi)
        /* suspend left the IRQ disabled */
        enable_irq(ts->spi->irq);
 
+       if (ts->gpio_pendown != -1)
+               gpio_free(ts->gpio_pendown);
+
        if (ts->filter_cleanup)
                ts->filter_cleanup(ts->filter_data);
 
+       kfree(ts->packet);
        kfree(ts);
 
        dev_dbg(&spi->dev, "unregistered touchscreen\n");