Input: ads7846 - add possibility to use external vref on ads7846
authorAlexander Stein <alexander.stein@systec-electronic.com>
Wed, 11 May 2011 23:24:08 +0000 (16:24 -0700)
committerDmitry Torokhov <dmitry.torokhov@gmail.com>
Thu, 12 May 2011 15:28:56 +0000 (08:28 -0700)
Just set vref_mv in your platform config to use external vref. Otherwise
the internal one is used.

Signed-off-by: Alexander Stein <alexander.stein@systec-electronic.com>
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
drivers/input/touchscreen/ads7846.c
include/linux/spi/ads7846.h

index c24946f512564e35925d0e6c090b7fd4a6c4eccd..e4ee43e159d2d0b761e0ec61038281cd4043a540 100644 (file)
@@ -109,6 +109,7 @@ struct ads7846 {
        u16                     pressure_max;
 
        bool                    swap_xy;
+       bool                    use_internal;
 
        struct ads7846_packet   *packet;
 
@@ -300,7 +301,6 @@ static int ads7846_read12_ser(struct device *dev, unsigned command)
        struct ads7846 *ts = dev_get_drvdata(dev);
        struct ser_req *req;
        int status;
-       int use_internal;
 
        req = kzalloc(sizeof *req, GFP_KERNEL);
        if (!req)
@@ -308,11 +308,8 @@ static int ads7846_read12_ser(struct device *dev, unsigned command)
 
        spi_message_init(&req->msg);
 
-       /* FIXME boards with ads7846 might use external vref instead ... */
-       use_internal = (ts->model == 7846);
-
        /* maybe turn on internal vREF, and let it settle */
-       if (use_internal) {
+       if (ts->use_internal) {
                req->ref_on = REF_ON;
                req->xfer[0].tx_buf = &req->ref_on;
                req->xfer[0].len = 1;
@@ -324,8 +321,14 @@ static int ads7846_read12_ser(struct device *dev, unsigned command)
                /* for 1uF, settle for 800 usec; no cap, 100 usec.  */
                req->xfer[1].delay_usecs = ts->vref_delay_usecs;
                spi_message_add_tail(&req->xfer[1], &req->msg);
+
+               /* Enable reference voltage */
+               command |= ADS_PD10_REF_ON;
        }
 
+       /* Enable ADC in every case */
+       command |= ADS_PD10_ADC_ON;
+
        /* take sample */
        req->command = (u8) command;
        req->xfer[2].tx_buf = &req->command;
@@ -409,7 +412,7 @@ name ## _show(struct device *dev, struct device_attribute *attr, char *buf) \
 { \
        struct ads7846 *ts = dev_get_drvdata(dev); \
        ssize_t v = ads7846_read12_ser(dev, \
-                       READ_12BIT_SER(var) | ADS_PD10_ALL_ON); \
+                       READ_12BIT_SER(var)); \
        if (v < 0) \
                return v; \
        return sprintf(buf, "%u\n", adjust(ts, v)); \
@@ -502,6 +505,7 @@ static int ads784x_hwmon_register(struct spi_device *spi, struct ads7846 *ts)
                if (!ts->vref_mv) {
                        dev_dbg(&spi->dev, "assuming 2.5V internal vREF\n");
                        ts->vref_mv = 2500;
+                       ts->use_internal = true;
                }
                break;
        case 7845:
@@ -1333,8 +1337,7 @@ static int __devinit ads7846_probe(struct spi_device *spi)
        if (ts->model == 7845)
                ads7845_read12_ser(&spi->dev, PWRDOWN);
        else
-               (void) ads7846_read12_ser(&spi->dev,
-                               READ_12BIT_SER(vaux) | ADS_PD10_ALL_ON);
+               (void) ads7846_read12_ser(&spi->dev, READ_12BIT_SER(vaux));
 
        err = sysfs_create_group(&spi->dev.kobj, &ads784x_attr_group);
        if (err)
index 92bd0839d5b49a414f8cd23fef827403ed965bab..c64de9dd7631bb44232eeca7d8080c62521c5b1e 100644 (file)
@@ -14,7 +14,8 @@ enum ads7846_filter {
 struct ads7846_platform_data {
        u16     model;                  /* 7843, 7845, 7846, 7873. */
        u16     vref_delay_usecs;       /* 0 for external vref; etc */
-       u16     vref_mv;                /* external vref value, milliVolts */
+       u16     vref_mv;                /* external vref value, milliVolts
+                                        * ads7846: if 0, use internal vref */
        bool    keep_vref_on;           /* set to keep vref on for differential
                                         * measurements as well */
        bool    swap_xy;                /* swap x and y axes */