1ffa458c1SDavid Brownell /* 2ffa458c1SDavid Brownell * ADS7846 based touchscreen and sensor driver 3ffa458c1SDavid Brownell * 4ffa458c1SDavid Brownell * Copyright (c) 2005 David Brownell 57de90a8cSImre Deak * Copyright (c) 2006 Nokia Corporation 67de90a8cSImre Deak * Various changes: Imre Deak <imre.deak@nokia.com> 7ffa458c1SDavid Brownell * 8ffa458c1SDavid Brownell * Using code from: 9ffa458c1SDavid Brownell * - corgi_ts.c 10ffa458c1SDavid Brownell * Copyright (C) 2004-2005 Richard Purdie 11ffa458c1SDavid Brownell * - omap_ts.[hc], ads7846.h, ts_osk.c 12ffa458c1SDavid Brownell * Copyright (C) 2002 MontaVista Software 13ffa458c1SDavid Brownell * Copyright (C) 2004 Texas Instruments 14ffa458c1SDavid Brownell * Copyright (C) 2005 Dirk Behme 15ffa458c1SDavid Brownell * 16ffa458c1SDavid Brownell * This program is free software; you can redistribute it and/or modify 17ffa458c1SDavid Brownell * it under the terms of the GNU General Public License version 2 as 18ffa458c1SDavid Brownell * published by the Free Software Foundation. 19ffa458c1SDavid Brownell */ 20ffa458c1SDavid Brownell #include <linux/device.h> 21ffa458c1SDavid Brownell #include <linux/init.h> 22ffa458c1SDavid Brownell #include <linux/delay.h> 23ffa458c1SDavid Brownell #include <linux/input.h> 24ffa458c1SDavid Brownell #include <linux/interrupt.h> 25ffa458c1SDavid Brownell #include <linux/slab.h> 26ffa458c1SDavid Brownell #include <linux/spi/spi.h> 27ffa458c1SDavid Brownell #include <linux/spi/ads7846.h> 283ac8bf07SAndrew Morton #include <asm/irq.h> 29ffa458c1SDavid Brownell 30ffa458c1SDavid Brownell #ifdef CONFIG_ARM 31ffa458c1SDavid Brownell #include <asm/mach-types.h> 32ffa458c1SDavid Brownell #ifdef CONFIG_ARCH_OMAP 33ffa458c1SDavid Brownell #include <asm/arch/gpio.h> 34ffa458c1SDavid Brownell #endif 35ffa458c1SDavid Brownell #endif 36ffa458c1SDavid Brownell 37ffa458c1SDavid Brownell 38ffa458c1SDavid Brownell /* 399084533eSDavid Brownell * This code has been heavily tested on a Nokia 770, and lightly 409084533eSDavid Brownell * tested on other ads7846 devices (OSK/Mistral, Lubbock). 41ffa458c1SDavid Brownell * Support for ads7843 and ads7845 has only been stubbed in. 42ffa458c1SDavid Brownell * 437de90a8cSImre Deak * IRQ handling needs a workaround because of a shortcoming in handling 447de90a8cSImre Deak * edge triggered IRQs on some platforms like the OMAP1/2. These 457de90a8cSImre Deak * platforms don't handle the ARM lazy IRQ disabling properly, thus we 467de90a8cSImre Deak * have to maintain our own SW IRQ disabled status. This should be 477de90a8cSImre Deak * removed as soon as the affected platform's IRQ handling is fixed. 487de90a8cSImre Deak * 49ffa458c1SDavid Brownell * app note sbaa036 talks in more detail about accurate sampling... 50ffa458c1SDavid Brownell * that ought to help in situations like LCDs inducing noise (which 51ffa458c1SDavid Brownell * can also be helped by using synch signals) and more generally. 527de90a8cSImre Deak * This driver tries to utilize the measures described in the app 537de90a8cSImre Deak * note. The strength of filtering can be set in the board-* specific 547de90a8cSImre Deak * files. 55ffa458c1SDavid Brownell */ 56ffa458c1SDavid Brownell 57ffa458c1SDavid Brownell #define TS_POLL_PERIOD msecs_to_jiffies(10) 58ffa458c1SDavid Brownell 59d93f70b2SDavid Brownell /* this driver doesn't aim at the peak continuous sample rate */ 60d93f70b2SDavid Brownell #define SAMPLE_BITS (8 /*cmd*/ + 16 /*sample*/ + 2 /* before, after */) 61d93f70b2SDavid Brownell 62ffa458c1SDavid Brownell struct ts_event { 63ffa458c1SDavid Brownell /* For portability, we can't read 12 bit values using SPI (which 64ffa458c1SDavid Brownell * would make the controller deliver them as native byteorder u16 65d93f70b2SDavid Brownell * with msbs zeroed). Instead, we read them as two 8-bit values, 66ffa458c1SDavid Brownell * which need byteswapping then range adjustment. 67ffa458c1SDavid Brownell */ 68ffa458c1SDavid Brownell __be16 x; 69ffa458c1SDavid Brownell __be16 y; 70ffa458c1SDavid Brownell __be16 z1, z2; 71d5b415c9SImre Deak int ignore; 72ffa458c1SDavid Brownell }; 73ffa458c1SDavid Brownell 74ffa458c1SDavid Brownell struct ads7846 { 75a90f7e98SDmitry Torokhov struct input_dev *input; 76ffa458c1SDavid Brownell char phys[32]; 77ffa458c1SDavid Brownell 78ffa458c1SDavid Brownell struct spi_device *spi; 79ffa458c1SDavid Brownell u16 model; 80ffa458c1SDavid Brownell u16 vref_delay_usecs; 81ffa458c1SDavid Brownell u16 x_plate_ohms; 82d5b415c9SImre Deak u16 pressure_max; 83ffa458c1SDavid Brownell 8453a0ef89SImre Deak u8 read_x, read_y, read_z1, read_z2, pwrdown; 8553a0ef89SImre Deak u16 dummy; /* for the pwrdown read */ 86ffa458c1SDavid Brownell struct ts_event tc; 87ffa458c1SDavid Brownell 8853a0ef89SImre Deak struct spi_transfer xfer[10]; 890b7018aaSImre Deak struct spi_message msg[5]; 90d5b415c9SImre Deak struct spi_message *last_msg; 910b7018aaSImre Deak int msg_idx; 920b7018aaSImre Deak int read_cnt; 93d5b415c9SImre Deak int read_rep; 940b7018aaSImre Deak int last_read; 950b7018aaSImre Deak 960b7018aaSImre Deak u16 debounce_max; 970b7018aaSImre Deak u16 debounce_tol; 98d5b415c9SImre Deak u16 debounce_rep; 99ffa458c1SDavid Brownell 100ffa458c1SDavid Brownell spinlock_t lock; 101ffa458c1SDavid Brownell struct timer_list timer; /* P: lock */ 102ffa458c1SDavid Brownell unsigned pendown:1; /* P: lock */ 103ffa458c1SDavid Brownell unsigned pending:1; /* P: lock */ 104ffa458c1SDavid Brownell // FIXME remove "irq_disabled" 105ffa458c1SDavid Brownell unsigned irq_disabled:1; /* P: lock */ 1067de90a8cSImre Deak unsigned disabled:1; 107c9e617a5SImre Deak 108c9e617a5SImre Deak int (*get_pendown_state)(void); 109ffa458c1SDavid Brownell }; 110ffa458c1SDavid Brownell 111ffa458c1SDavid Brownell /* leave chip selected when we're done, for quicker re-select? */ 112ffa458c1SDavid Brownell #if 0 113ffa458c1SDavid Brownell #define CS_CHANGE(xfer) ((xfer).cs_change = 1) 114ffa458c1SDavid Brownell #else 115ffa458c1SDavid Brownell #define CS_CHANGE(xfer) ((xfer).cs_change = 0) 116ffa458c1SDavid Brownell #endif 117ffa458c1SDavid Brownell 118ffa458c1SDavid Brownell /*--------------------------------------------------------------------------*/ 119ffa458c1SDavid Brownell 120ffa458c1SDavid Brownell /* The ADS7846 has touchscreen and other sensors. 121ffa458c1SDavid Brownell * Earlier ads784x chips are somewhat compatible. 122ffa458c1SDavid Brownell */ 123ffa458c1SDavid Brownell #define ADS_START (1 << 7) 124ffa458c1SDavid Brownell #define ADS_A2A1A0_d_y (1 << 4) /* differential */ 125ffa458c1SDavid Brownell #define ADS_A2A1A0_d_z1 (3 << 4) /* differential */ 126ffa458c1SDavid Brownell #define ADS_A2A1A0_d_z2 (4 << 4) /* differential */ 127ffa458c1SDavid Brownell #define ADS_A2A1A0_d_x (5 << 4) /* differential */ 128ffa458c1SDavid Brownell #define ADS_A2A1A0_temp0 (0 << 4) /* non-differential */ 129ffa458c1SDavid Brownell #define ADS_A2A1A0_vbatt (2 << 4) /* non-differential */ 130ffa458c1SDavid Brownell #define ADS_A2A1A0_vaux (6 << 4) /* non-differential */ 131ffa458c1SDavid Brownell #define ADS_A2A1A0_temp1 (7 << 4) /* non-differential */ 132ffa458c1SDavid Brownell #define ADS_8_BIT (1 << 3) 133ffa458c1SDavid Brownell #define ADS_12_BIT (0 << 3) 134ffa458c1SDavid Brownell #define ADS_SER (1 << 2) /* non-differential */ 135ffa458c1SDavid Brownell #define ADS_DFR (0 << 2) /* differential */ 136ffa458c1SDavid Brownell #define ADS_PD10_PDOWN (0 << 0) /* lowpower mode + penirq */ 137ffa458c1SDavid Brownell #define ADS_PD10_ADC_ON (1 << 0) /* ADC on */ 138ffa458c1SDavid Brownell #define ADS_PD10_REF_ON (2 << 0) /* vREF on + penirq */ 139ffa458c1SDavid Brownell #define ADS_PD10_ALL_ON (3 << 0) /* ADC + vREF on */ 140ffa458c1SDavid Brownell 141ffa458c1SDavid Brownell #define MAX_12BIT ((1<<12)-1) 142ffa458c1SDavid Brownell 143ffa458c1SDavid Brownell /* leave ADC powered up (disables penirq) between differential samples */ 144ffa458c1SDavid Brownell #define READ_12BIT_DFR(x) (ADS_START | ADS_A2A1A0_d_ ## x \ 145ffa458c1SDavid Brownell | ADS_12_BIT | ADS_DFR) 146ffa458c1SDavid Brownell 147d93f70b2SDavid Brownell #define READ_Y (READ_12BIT_DFR(y) | ADS_PD10_ADC_ON) 148d93f70b2SDavid Brownell #define READ_Z1 (READ_12BIT_DFR(z1) | ADS_PD10_ADC_ON) 149d93f70b2SDavid Brownell #define READ_Z2 (READ_12BIT_DFR(z2) | ADS_PD10_ADC_ON) 15053a0ef89SImre Deak 15153a0ef89SImre Deak #define READ_X (READ_12BIT_DFR(x) | ADS_PD10_ADC_ON) 15253a0ef89SImre Deak #define PWRDOWN (READ_12BIT_DFR(y) | ADS_PD10_PDOWN) /* LAST */ 153ffa458c1SDavid Brownell 154ffa458c1SDavid Brownell /* single-ended samples need to first power up reference voltage; 155ffa458c1SDavid Brownell * we leave both ADC and VREF powered 156ffa458c1SDavid Brownell */ 157ffa458c1SDavid Brownell #define READ_12BIT_SER(x) (ADS_START | ADS_A2A1A0_ ## x \ 158ffa458c1SDavid Brownell | ADS_12_BIT | ADS_SER) 159ffa458c1SDavid Brownell 160d93f70b2SDavid Brownell #define REF_ON (READ_12BIT_DFR(x) | ADS_PD10_ALL_ON) 161d93f70b2SDavid Brownell #define REF_OFF (READ_12BIT_DFR(y) | ADS_PD10_PDOWN) 162ffa458c1SDavid Brownell 163ffa458c1SDavid Brownell /*--------------------------------------------------------------------------*/ 164ffa458c1SDavid Brownell 165ffa458c1SDavid Brownell /* 166ffa458c1SDavid Brownell * Non-touchscreen sensors only use single-ended conversions. 167ffa458c1SDavid Brownell */ 168ffa458c1SDavid Brownell 169ffa458c1SDavid Brownell struct ser_req { 170d93f70b2SDavid Brownell u8 ref_on; 171ffa458c1SDavid Brownell u8 command; 172d93f70b2SDavid Brownell u8 ref_off; 173ffa458c1SDavid Brownell u16 scratch; 174ffa458c1SDavid Brownell __be16 sample; 175ffa458c1SDavid Brownell struct spi_message msg; 176ffa458c1SDavid Brownell struct spi_transfer xfer[6]; 177ffa458c1SDavid Brownell }; 178ffa458c1SDavid Brownell 1797de90a8cSImre Deak static void ads7846_enable(struct ads7846 *ts); 1807de90a8cSImre Deak static void ads7846_disable(struct ads7846 *ts); 1817de90a8cSImre Deak 182c9e617a5SImre Deak static int device_suspended(struct device *dev) 183c9e617a5SImre Deak { 184c9e617a5SImre Deak struct ads7846 *ts = dev_get_drvdata(dev); 185c9e617a5SImre Deak return dev->power.power_state.event != PM_EVENT_ON || ts->disabled; 186c9e617a5SImre Deak } 187c9e617a5SImre Deak 188ffa458c1SDavid Brownell static int ads7846_read12_ser(struct device *dev, unsigned command) 189ffa458c1SDavid Brownell { 190ffa458c1SDavid Brownell struct spi_device *spi = to_spi_device(dev); 191ffa458c1SDavid Brownell struct ads7846 *ts = dev_get_drvdata(dev); 192ffa458c1SDavid Brownell struct ser_req *req = kzalloc(sizeof *req, SLAB_KERNEL); 193ffa458c1SDavid Brownell int status; 194ffa458c1SDavid Brownell int sample; 1958275c642SVitaly Wool int i; 196ffa458c1SDavid Brownell 197ffa458c1SDavid Brownell if (!req) 198ffa458c1SDavid Brownell return -ENOMEM; 199ffa458c1SDavid Brownell 2000b7018aaSImre Deak spi_message_init(&req->msg); 2018275c642SVitaly Wool 202ffa458c1SDavid Brownell /* activate reference, so it has time to settle; */ 203d93f70b2SDavid Brownell req->ref_on = REF_ON; 204d93f70b2SDavid Brownell req->xfer[0].tx_buf = &req->ref_on; 205ffa458c1SDavid Brownell req->xfer[0].len = 1; 206ffa458c1SDavid Brownell req->xfer[1].rx_buf = &req->scratch; 207ffa458c1SDavid Brownell req->xfer[1].len = 2; 208ffa458c1SDavid Brownell 209ffa458c1SDavid Brownell /* 210ffa458c1SDavid Brownell * for external VREF, 0 usec (and assume it's always on); 211ffa458c1SDavid Brownell * for 1uF, use 800 usec; 212ffa458c1SDavid Brownell * no cap, 100 usec. 213ffa458c1SDavid Brownell */ 214ffa458c1SDavid Brownell req->xfer[1].delay_usecs = ts->vref_delay_usecs; 215ffa458c1SDavid Brownell 216ffa458c1SDavid Brownell /* take sample */ 217ffa458c1SDavid Brownell req->command = (u8) command; 218ffa458c1SDavid Brownell req->xfer[2].tx_buf = &req->command; 219ffa458c1SDavid Brownell req->xfer[2].len = 1; 220ffa458c1SDavid Brownell req->xfer[3].rx_buf = &req->sample; 221ffa458c1SDavid Brownell req->xfer[3].len = 2; 222ffa458c1SDavid Brownell 223ffa458c1SDavid Brownell /* REVISIT: take a few more samples, and compare ... */ 224ffa458c1SDavid Brownell 225ffa458c1SDavid Brownell /* turn off reference */ 226d93f70b2SDavid Brownell req->ref_off = REF_OFF; 227d93f70b2SDavid Brownell req->xfer[4].tx_buf = &req->ref_off; 228ffa458c1SDavid Brownell req->xfer[4].len = 1; 229ffa458c1SDavid Brownell req->xfer[5].rx_buf = &req->scratch; 230ffa458c1SDavid Brownell req->xfer[5].len = 2; 231ffa458c1SDavid Brownell 232ffa458c1SDavid Brownell CS_CHANGE(req->xfer[5]); 233ffa458c1SDavid Brownell 234ffa458c1SDavid Brownell /* group all the transfers together, so we can't interfere with 235ffa458c1SDavid Brownell * reading touchscreen state; disable penirq while sampling 236ffa458c1SDavid Brownell */ 2378275c642SVitaly Wool for (i = 0; i < 6; i++) 2388275c642SVitaly Wool spi_message_add_tail(&req->xfer[i], &req->msg); 239ffa458c1SDavid Brownell 240c9e617a5SImre Deak ts->irq_disabled = 1; 241ffa458c1SDavid Brownell disable_irq(spi->irq); 242ffa458c1SDavid Brownell status = spi_sync(spi, &req->msg); 243c9e617a5SImre Deak ts->irq_disabled = 0; 244ffa458c1SDavid Brownell enable_irq(spi->irq); 245ffa458c1SDavid Brownell 246ffa458c1SDavid Brownell if (req->msg.status) 247ffa458c1SDavid Brownell status = req->msg.status; 248ffa458c1SDavid Brownell 2499084533eSDavid Brownell /* on-wire is a must-ignore bit, a BE12 value, then padding */ 2509084533eSDavid Brownell sample = be16_to_cpu(req->sample); 2519084533eSDavid Brownell sample = sample >> 3; 2529084533eSDavid Brownell sample &= 0x0fff; 2539084533eSDavid Brownell 2549084533eSDavid Brownell kfree(req); 255ffa458c1SDavid Brownell return status ? status : sample; 256ffa458c1SDavid Brownell } 257ffa458c1SDavid Brownell 258ffa458c1SDavid Brownell #define SHOW(name) static ssize_t \ 259ffa458c1SDavid Brownell name ## _show(struct device *dev, struct device_attribute *attr, char *buf) \ 260ffa458c1SDavid Brownell { \ 261ffa458c1SDavid Brownell ssize_t v = ads7846_read12_ser(dev, \ 262ffa458c1SDavid Brownell READ_12BIT_SER(name) | ADS_PD10_ALL_ON); \ 263ffa458c1SDavid Brownell if (v < 0) \ 264ffa458c1SDavid Brownell return v; \ 265ffa458c1SDavid Brownell return sprintf(buf, "%u\n", (unsigned) v); \ 266ffa458c1SDavid Brownell } \ 267ffa458c1SDavid Brownell static DEVICE_ATTR(name, S_IRUGO, name ## _show, NULL); 268ffa458c1SDavid Brownell 269ffa458c1SDavid Brownell SHOW(temp0) 270ffa458c1SDavid Brownell SHOW(temp1) 271ffa458c1SDavid Brownell SHOW(vaux) 272ffa458c1SDavid Brownell SHOW(vbatt) 273ffa458c1SDavid Brownell 274438f2a74SImre Deak static int is_pen_down(struct device *dev) 275438f2a74SImre Deak { 276438f2a74SImre Deak struct ads7846 *ts = dev_get_drvdata(dev); 277438f2a74SImre Deak 278438f2a74SImre Deak return ts->pendown; 279438f2a74SImre Deak } 280438f2a74SImre Deak 281438f2a74SImre Deak static ssize_t ads7846_pen_down_show(struct device *dev, 282438f2a74SImre Deak struct device_attribute *attr, char *buf) 283438f2a74SImre Deak { 284438f2a74SImre Deak return sprintf(buf, "%u\n", is_pen_down(dev)); 285438f2a74SImre Deak } 286438f2a74SImre Deak 287438f2a74SImre Deak static DEVICE_ATTR(pen_down, S_IRUGO, ads7846_pen_down_show, NULL); 288438f2a74SImre Deak 2897de90a8cSImre Deak static ssize_t ads7846_disable_show(struct device *dev, 2907de90a8cSImre Deak struct device_attribute *attr, char *buf) 2917de90a8cSImre Deak { 2927de90a8cSImre Deak struct ads7846 *ts = dev_get_drvdata(dev); 2937de90a8cSImre Deak 2947de90a8cSImre Deak return sprintf(buf, "%u\n", ts->disabled); 2957de90a8cSImre Deak } 2967de90a8cSImre Deak 2977de90a8cSImre Deak static ssize_t ads7846_disable_store(struct device *dev, 2987de90a8cSImre Deak struct device_attribute *attr, 2997de90a8cSImre Deak const char *buf, size_t count) 3007de90a8cSImre Deak { 3017de90a8cSImre Deak struct ads7846 *ts = dev_get_drvdata(dev); 3027de90a8cSImre Deak char *endp; 3037de90a8cSImre Deak int i; 3047de90a8cSImre Deak 3057de90a8cSImre Deak i = simple_strtoul(buf, &endp, 10); 3067de90a8cSImre Deak spin_lock_irq(&ts->lock); 3077de90a8cSImre Deak 3087de90a8cSImre Deak if (i) 3097de90a8cSImre Deak ads7846_disable(ts); 3107de90a8cSImre Deak else 3117de90a8cSImre Deak ads7846_enable(ts); 3127de90a8cSImre Deak 3137de90a8cSImre Deak spin_unlock_irq(&ts->lock); 3147de90a8cSImre Deak 3157de90a8cSImre Deak return count; 3167de90a8cSImre Deak } 3177de90a8cSImre Deak 3187de90a8cSImre Deak static DEVICE_ATTR(disable, 0664, ads7846_disable_show, ads7846_disable_store); 3197de90a8cSImre Deak 320ffa458c1SDavid Brownell /*--------------------------------------------------------------------------*/ 321ffa458c1SDavid Brownell 322ffa458c1SDavid Brownell /* 323ffa458c1SDavid Brownell * PENIRQ only kicks the timer. The timer only reissues the SPI transfer, 324ffa458c1SDavid Brownell * to retrieve touchscreen status. 325ffa458c1SDavid Brownell * 326ffa458c1SDavid Brownell * The SPI transfer completion callback does the real work. It reports 327ffa458c1SDavid Brownell * touchscreen events and reactivates the timer (or IRQ) as appropriate. 328ffa458c1SDavid Brownell */ 329ffa458c1SDavid Brownell 330ffa458c1SDavid Brownell static void ads7846_rx(void *ads) 331ffa458c1SDavid Brownell { 332ffa458c1SDavid Brownell struct ads7846 *ts = ads; 333a90f7e98SDmitry Torokhov struct input_dev *input_dev = ts->input; 334ffa458c1SDavid Brownell unsigned Rt; 335ffa458c1SDavid Brownell unsigned sync = 0; 336ffa458c1SDavid Brownell u16 x, y, z1, z2; 337ffa458c1SDavid Brownell unsigned long flags; 338ffa458c1SDavid Brownell 3399084533eSDavid Brownell /* adjust: on-wire is a must-ignore bit, a BE12 value, then padding; 3409084533eSDavid Brownell * built from two 8 bit values written msb-first. 341ffa458c1SDavid Brownell */ 3429084533eSDavid Brownell x = (be16_to_cpu(ts->tc.x) >> 3) & 0x0fff; 3439084533eSDavid Brownell y = (be16_to_cpu(ts->tc.y) >> 3) & 0x0fff; 3449084533eSDavid Brownell z1 = (be16_to_cpu(ts->tc.z1) >> 3) & 0x0fff; 3459084533eSDavid Brownell z2 = (be16_to_cpu(ts->tc.z2) >> 3) & 0x0fff; 346ffa458c1SDavid Brownell 347ffa458c1SDavid Brownell /* range filtering */ 348ffa458c1SDavid Brownell if (x == MAX_12BIT) 349ffa458c1SDavid Brownell x = 0; 350ffa458c1SDavid Brownell 351c9e617a5SImre Deak if (likely(x && z1 && !device_suspended(&ts->spi->dev))) { 352ffa458c1SDavid Brownell /* compute touch pressure resistance using equation #2 */ 353ffa458c1SDavid Brownell Rt = z2; 354ffa458c1SDavid Brownell Rt -= z1; 355ffa458c1SDavid Brownell Rt *= x; 356ffa458c1SDavid Brownell Rt *= ts->x_plate_ohms; 357ffa458c1SDavid Brownell Rt /= z1; 358ffa458c1SDavid Brownell Rt = (Rt + 2047) >> 12; 359ffa458c1SDavid Brownell } else 360ffa458c1SDavid Brownell Rt = 0; 361ffa458c1SDavid Brownell 362d5b415c9SImre Deak /* Sample found inconsistent by debouncing or pressure is beyond 363d5b415c9SImre Deak * the maximum. Don't report it to user space, repeat at least 364d5b415c9SImre Deak * once more the measurement */ 365d5b415c9SImre Deak if (ts->tc.ignore || Rt > ts->pressure_max) { 366d5b415c9SImre Deak mod_timer(&ts->timer, jiffies + TS_POLL_PERIOD); 367d5b415c9SImre Deak return; 368d5b415c9SImre Deak } 369d5b415c9SImre Deak 370ffa458c1SDavid Brownell /* NOTE: "pendown" is inferred from pressure; we don't rely on 371ffa458c1SDavid Brownell * being able to check nPENIRQ status, or "friendly" trigger modes 372ffa458c1SDavid Brownell * (both-edges is much better than just-falling or low-level). 373ffa458c1SDavid Brownell * 374ffa458c1SDavid Brownell * REVISIT: some boards may require reading nPENIRQ; it's 375ffa458c1SDavid Brownell * needed on 7843. and 7845 reads pressure differently... 376ffa458c1SDavid Brownell * 377ffa458c1SDavid Brownell * REVISIT: the touchscreen might not be connected; this code 378ffa458c1SDavid Brownell * won't notice that, even if nPENIRQ never fires ... 379ffa458c1SDavid Brownell */ 380ffa458c1SDavid Brownell if (!ts->pendown && Rt != 0) { 381a90f7e98SDmitry Torokhov input_report_key(input_dev, BTN_TOUCH, 1); 382ffa458c1SDavid Brownell sync = 1; 383ffa458c1SDavid Brownell } else if (ts->pendown && Rt == 0) { 384a90f7e98SDmitry Torokhov input_report_key(input_dev, BTN_TOUCH, 0); 385ffa458c1SDavid Brownell sync = 1; 386ffa458c1SDavid Brownell } 387ffa458c1SDavid Brownell 388ffa458c1SDavid Brownell if (Rt) { 389a90f7e98SDmitry Torokhov input_report_abs(input_dev, ABS_X, x); 390a90f7e98SDmitry Torokhov input_report_abs(input_dev, ABS_Y, y); 391ffa458c1SDavid Brownell sync = 1; 392ffa458c1SDavid Brownell } 393ae82d5abSImre Deak 394ae82d5abSImre Deak if (sync) { 395ae82d5abSImre Deak input_report_abs(input_dev, ABS_PRESSURE, Rt); 396a90f7e98SDmitry Torokhov input_sync(input_dev); 397ae82d5abSImre Deak } 398ffa458c1SDavid Brownell 399ffa458c1SDavid Brownell #ifdef VERBOSE 400ffa458c1SDavid Brownell if (Rt || ts->pendown) 401ffa458c1SDavid Brownell pr_debug("%s: %d/%d/%d%s\n", ts->spi->dev.bus_id, 402ffa458c1SDavid Brownell x, y, Rt, Rt ? "" : " UP"); 403ffa458c1SDavid Brownell #endif 404ffa458c1SDavid Brownell 405ffa458c1SDavid Brownell spin_lock_irqsave(&ts->lock, flags); 406ffa458c1SDavid Brownell 407ffa458c1SDavid Brownell ts->pendown = (Rt != 0); 408ffa458c1SDavid Brownell mod_timer(&ts->timer, jiffies + TS_POLL_PERIOD); 409ffa458c1SDavid Brownell 410ffa458c1SDavid Brownell spin_unlock_irqrestore(&ts->lock, flags); 411ffa458c1SDavid Brownell } 412ffa458c1SDavid Brownell 4130b7018aaSImre Deak static void ads7846_debounce(void *ads) 414ffa458c1SDavid Brownell { 4150b7018aaSImre Deak struct ads7846 *ts = ads; 4160b7018aaSImre Deak struct spi_message *m; 4170b7018aaSImre Deak struct spi_transfer *t; 418d5b415c9SImre Deak int val; 4190b7018aaSImre Deak int status; 420ffa458c1SDavid Brownell 4210b7018aaSImre Deak m = &ts->msg[ts->msg_idx]; 4220b7018aaSImre Deak t = list_entry(m->transfers.prev, struct spi_transfer, transfer_list); 4239084533eSDavid Brownell val = (be16_to_cpu(*(__be16 *)t->rx_buf) >> 3) & 0x0fff; 424d5b415c9SImre Deak if (!ts->read_cnt || (abs(ts->last_read - val) > ts->debounce_tol)) { 425d5b415c9SImre Deak /* Repeat it, if this was the first read or the read 426d5b415c9SImre Deak * wasn't consistent enough. */ 427d5b415c9SImre Deak if (ts->read_cnt < ts->debounce_max) { 4280b7018aaSImre Deak ts->last_read = val; 429d5b415c9SImre Deak ts->read_cnt++; 4300b7018aaSImre Deak } else { 431d5b415c9SImre Deak /* Maximum number of debouncing reached and still 432d5b415c9SImre Deak * not enough number of consistent readings. Abort 433d5b415c9SImre Deak * the whole sample, repeat it in the next sampling 434d5b415c9SImre Deak * period. 435d5b415c9SImre Deak */ 436d5b415c9SImre Deak ts->tc.ignore = 1; 437d5b415c9SImre Deak ts->read_cnt = 0; 438d5b415c9SImre Deak /* Last message will contain ads7846_rx() as the 439d5b415c9SImre Deak * completion function. 440d5b415c9SImre Deak */ 441d5b415c9SImre Deak m = ts->last_msg; 442d5b415c9SImre Deak } 443d5b415c9SImre Deak /* Start over collecting consistent readings. */ 444d5b415c9SImre Deak ts->read_rep = 0; 445d5b415c9SImre Deak } else { 446d5b415c9SImre Deak if (++ts->read_rep > ts->debounce_rep) { 447d5b415c9SImre Deak /* Got a good reading for this coordinate, 448d5b415c9SImre Deak * go for the next one. */ 449d5b415c9SImre Deak ts->tc.ignore = 0; 4500b7018aaSImre Deak ts->msg_idx++; 4510b7018aaSImre Deak ts->read_cnt = 0; 452d5b415c9SImre Deak ts->read_rep = 0; 4530b7018aaSImre Deak m++; 454d5b415c9SImre Deak } else 455d5b415c9SImre Deak /* Read more values that are consistent. */ 456d5b415c9SImre Deak ts->read_cnt++; 457ffa458c1SDavid Brownell } 4580b7018aaSImre Deak status = spi_async(ts->spi, m); 459ffa458c1SDavid Brownell if (status) 460ffa458c1SDavid Brownell dev_err(&ts->spi->dev, "spi_async --> %d\n", 461ffa458c1SDavid Brownell status); 462ffa458c1SDavid Brownell } 4630b7018aaSImre Deak 4640b7018aaSImre Deak static void ads7846_timer(unsigned long handle) 4650b7018aaSImre Deak { 4660b7018aaSImre Deak struct ads7846 *ts = (void *)handle; 4670b7018aaSImre Deak int status = 0; 4680b7018aaSImre Deak 469c9e617a5SImre Deak spin_lock_irq(&ts->lock); 470c9e617a5SImre Deak 471c9e617a5SImre Deak if (unlikely(ts->msg_idx && !ts->pendown)) { 4729084533eSDavid Brownell /* measurement cycle ended */ 473c9e617a5SImre Deak if (!device_suspended(&ts->spi->dev)) { 474c9e617a5SImre Deak ts->irq_disabled = 0; 475c9e617a5SImre Deak enable_irq(ts->spi->irq); 476c9e617a5SImre Deak } 477c9e617a5SImre Deak ts->pending = 0; 478c9e617a5SImre Deak ts->msg_idx = 0; 479c9e617a5SImre Deak } else { 480c9e617a5SImre Deak /* pen is still down, continue with the measurement */ 4810b7018aaSImre Deak ts->msg_idx = 0; 4820b7018aaSImre Deak status = spi_async(ts->spi, &ts->msg[0]); 4830b7018aaSImre Deak if (status) 4840b7018aaSImre Deak dev_err(&ts->spi->dev, "spi_async --> %d\n", status); 485ffa458c1SDavid Brownell } 486ffa458c1SDavid Brownell 487c9e617a5SImre Deak spin_unlock_irq(&ts->lock); 488c9e617a5SImre Deak } 489c9e617a5SImre Deak 490*7d12e780SDavid Howells static irqreturn_t ads7846_irq(int irq, void *handle) 491ffa458c1SDavid Brownell { 4920b7018aaSImre Deak struct ads7846 *ts = handle; 4930b7018aaSImre Deak unsigned long flags; 4940b7018aaSImre Deak 4950b7018aaSImre Deak spin_lock_irqsave(&ts->lock, flags); 496c9e617a5SImre Deak if (likely(ts->get_pendown_state())) { 4970b7018aaSImre Deak if (!ts->irq_disabled) { 4989084533eSDavid Brownell /* The ARM do_simple_IRQ() dispatcher doesn't act 4999084533eSDavid Brownell * like the other dispatchers: it will report IRQs 5009084533eSDavid Brownell * even after they've been disabled. We work around 5019084533eSDavid Brownell * that here. (The "generic irq" framework may help...) 5020b7018aaSImre Deak */ 5030b7018aaSImre Deak ts->irq_disabled = 1; 5040b7018aaSImre Deak disable_irq(ts->spi->irq); 5050b7018aaSImre Deak ts->pending = 1; 5060b7018aaSImre Deak mod_timer(&ts->timer, jiffies); 5070b7018aaSImre Deak } 5080b7018aaSImre Deak } 5090b7018aaSImre Deak spin_unlock_irqrestore(&ts->lock, flags); 5107de90a8cSImre Deak 5117de90a8cSImre Deak return IRQ_HANDLED; 512ffa458c1SDavid Brownell } 513ffa458c1SDavid Brownell 514ffa458c1SDavid Brownell /*--------------------------------------------------------------------------*/ 515ffa458c1SDavid Brownell 5167de90a8cSImre Deak /* Must be called with ts->lock held */ 5177de90a8cSImre Deak static void ads7846_disable(struct ads7846 *ts) 518ffa458c1SDavid Brownell { 5197de90a8cSImre Deak if (ts->disabled) 5207de90a8cSImre Deak return; 521ffa458c1SDavid Brownell 522c9e617a5SImre Deak ts->disabled = 1; 523c9e617a5SImre Deak 524ffa458c1SDavid Brownell /* are we waiting for IRQ, or polling? */ 525c9e617a5SImre Deak if (!ts->pending) { 526ffa458c1SDavid Brownell ts->irq_disabled = 1; 527ffa458c1SDavid Brownell disable_irq(ts->spi->irq); 528ffa458c1SDavid Brownell } else { 529c9e617a5SImre Deak /* the timer will run at least once more, and 530c9e617a5SImre Deak * leave everything in a clean state, IRQ disabled 531ffa458c1SDavid Brownell */ 532c9e617a5SImre Deak while (ts->pending) { 5337de90a8cSImre Deak spin_unlock_irq(&ts->lock); 534c4febb94SJuha Yrjola msleep(1); 5357de90a8cSImre Deak spin_lock_irq(&ts->lock); 536ffa458c1SDavid Brownell } 537ffa458c1SDavid Brownell } 538ffa458c1SDavid Brownell 539ffa458c1SDavid Brownell /* we know the chip's in lowpower mode since we always 540ffa458c1SDavid Brownell * leave it that way after every request 541ffa458c1SDavid Brownell */ 542ffa458c1SDavid Brownell 5437de90a8cSImre Deak } 5447de90a8cSImre Deak 5457de90a8cSImre Deak /* Must be called with ts->lock held */ 5467de90a8cSImre Deak static void ads7846_enable(struct ads7846 *ts) 5477de90a8cSImre Deak { 5487de90a8cSImre Deak if (!ts->disabled) 5497de90a8cSImre Deak return; 5507de90a8cSImre Deak 5517de90a8cSImre Deak ts->disabled = 0; 5527de90a8cSImre Deak ts->irq_disabled = 0; 5537de90a8cSImre Deak enable_irq(ts->spi->irq); 5547de90a8cSImre Deak } 5557de90a8cSImre Deak 5567de90a8cSImre Deak static int ads7846_suspend(struct spi_device *spi, pm_message_t message) 5577de90a8cSImre Deak { 5587de90a8cSImre Deak struct ads7846 *ts = dev_get_drvdata(&spi->dev); 5597de90a8cSImre Deak 5607de90a8cSImre Deak spin_lock_irq(&ts->lock); 5617de90a8cSImre Deak 5627de90a8cSImre Deak spi->dev.power.power_state = message; 5637de90a8cSImre Deak ads7846_disable(ts); 5647de90a8cSImre Deak 5657de90a8cSImre Deak spin_unlock_irq(&ts->lock); 5667de90a8cSImre Deak 567ffa458c1SDavid Brownell return 0; 5687de90a8cSImre Deak 569ffa458c1SDavid Brownell } 570ffa458c1SDavid Brownell 5712e5a7bd9SDavid Brownell static int ads7846_resume(struct spi_device *spi) 572ffa458c1SDavid Brownell { 5732e5a7bd9SDavid Brownell struct ads7846 *ts = dev_get_drvdata(&spi->dev); 574ffa458c1SDavid Brownell 5757de90a8cSImre Deak spin_lock_irq(&ts->lock); 5767de90a8cSImre Deak 5772e5a7bd9SDavid Brownell spi->dev.power.power_state = PMSG_ON; 5787de90a8cSImre Deak ads7846_enable(ts); 5797de90a8cSImre Deak 5807de90a8cSImre Deak spin_unlock_irq(&ts->lock); 5817de90a8cSImre Deak 582ffa458c1SDavid Brownell return 0; 583ffa458c1SDavid Brownell } 584ffa458c1SDavid Brownell 5852e5a7bd9SDavid Brownell static int __devinit ads7846_probe(struct spi_device *spi) 586ffa458c1SDavid Brownell { 587ffa458c1SDavid Brownell struct ads7846 *ts; 588a90f7e98SDmitry Torokhov struct input_dev *input_dev; 5892e5a7bd9SDavid Brownell struct ads7846_platform_data *pdata = spi->dev.platform_data; 5900b7018aaSImre Deak struct spi_message *m; 591ffa458c1SDavid Brownell struct spi_transfer *x; 592a90f7e98SDmitry Torokhov int err; 593ffa458c1SDavid Brownell 594ffa458c1SDavid Brownell if (!spi->irq) { 5952e5a7bd9SDavid Brownell dev_dbg(&spi->dev, "no IRQ?\n"); 596ffa458c1SDavid Brownell return -ENODEV; 597ffa458c1SDavid Brownell } 598ffa458c1SDavid Brownell 599ffa458c1SDavid Brownell if (!pdata) { 6002e5a7bd9SDavid Brownell dev_dbg(&spi->dev, "no platform data?\n"); 601ffa458c1SDavid Brownell return -ENODEV; 602ffa458c1SDavid Brownell } 603ffa458c1SDavid Brownell 604ffa458c1SDavid Brownell /* don't exceed max specified sample rate */ 605d93f70b2SDavid Brownell if (spi->max_speed_hz > (125000 * SAMPLE_BITS)) { 6062e5a7bd9SDavid Brownell dev_dbg(&spi->dev, "f(sample) %d KHz?\n", 607d93f70b2SDavid Brownell (spi->max_speed_hz/SAMPLE_BITS)/1000); 608ffa458c1SDavid Brownell return -EINVAL; 609ffa458c1SDavid Brownell } 610ffa458c1SDavid Brownell 6119084533eSDavid Brownell /* REVISIT when the irq can be triggered active-low, or if for some 6129084533eSDavid Brownell * reason the touchscreen isn't hooked up, we don't need to access 6139084533eSDavid Brownell * the pendown state. 6149084533eSDavid Brownell */ 615c9e617a5SImre Deak if (pdata->get_pendown_state == NULL) { 616c9e617a5SImre Deak dev_dbg(&spi->dev, "no get_pendown_state function?\n"); 617c9e617a5SImre Deak return -EINVAL; 618c9e617a5SImre Deak } 619c9e617a5SImre Deak 6209084533eSDavid Brownell /* We'd set TX wordsize 8 bits and RX wordsize to 13 bits ... except 6219084533eSDavid Brownell * that even if the hardware can do that, the SPI controller driver 6229084533eSDavid Brownell * may not. So we stick to very-portable 8 bit words, both RX and TX. 623ffa458c1SDavid Brownell */ 6249084533eSDavid Brownell spi->bits_per_word = 8; 625ffa458c1SDavid Brownell 626a90f7e98SDmitry Torokhov ts = kzalloc(sizeof(struct ads7846), GFP_KERNEL); 627a90f7e98SDmitry Torokhov input_dev = input_allocate_device(); 628a90f7e98SDmitry Torokhov if (!ts || !input_dev) { 629a90f7e98SDmitry Torokhov err = -ENOMEM; 630a90f7e98SDmitry Torokhov goto err_free_mem; 631a90f7e98SDmitry Torokhov } 632ffa458c1SDavid Brownell 6332e5a7bd9SDavid Brownell dev_set_drvdata(&spi->dev, ts); 634a90f7e98SDmitry Torokhov spi->dev.power.power_state = PMSG_ON; 635ffa458c1SDavid Brownell 636ffa458c1SDavid Brownell ts->spi = spi; 637a90f7e98SDmitry Torokhov ts->input = input_dev; 638ffa458c1SDavid Brownell 639ffa458c1SDavid Brownell init_timer(&ts->timer); 640ffa458c1SDavid Brownell ts->timer.data = (unsigned long) ts; 641ffa458c1SDavid Brownell ts->timer.function = ads7846_timer; 642ffa458c1SDavid Brownell 6437de90a8cSImre Deak spin_lock_init(&ts->lock); 6447de90a8cSImre Deak 645ffa458c1SDavid Brownell ts->model = pdata->model ? : 7846; 646ffa458c1SDavid Brownell ts->vref_delay_usecs = pdata->vref_delay_usecs ? : 100; 647ffa458c1SDavid Brownell ts->x_plate_ohms = pdata->x_plate_ohms ? : 400; 648d5b415c9SImre Deak ts->pressure_max = pdata->pressure_max ? : ~0; 649d5b415c9SImre Deak if (pdata->debounce_max) { 650d5b415c9SImre Deak ts->debounce_max = pdata->debounce_max; 651d5b415c9SImre Deak ts->debounce_tol = pdata->debounce_tol; 652d5b415c9SImre Deak ts->debounce_rep = pdata->debounce_rep; 653d5b415c9SImre Deak if (ts->debounce_rep > ts->debounce_max + 1) 654d5b415c9SImre Deak ts->debounce_rep = ts->debounce_max - 1; 655d5b415c9SImre Deak } else 656d5b415c9SImre Deak ts->debounce_tol = ~0; 657c9e617a5SImre Deak ts->get_pendown_state = pdata->get_pendown_state; 658ffa458c1SDavid Brownell 659a90f7e98SDmitry Torokhov snprintf(ts->phys, sizeof(ts->phys), "%s/input0", spi->dev.bus_id); 660ffa458c1SDavid Brownell 661a90f7e98SDmitry Torokhov input_dev->name = "ADS784x Touchscreen"; 662a90f7e98SDmitry Torokhov input_dev->phys = ts->phys; 663a90f7e98SDmitry Torokhov input_dev->cdev.dev = &spi->dev; 664ffa458c1SDavid Brownell 665a90f7e98SDmitry Torokhov input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); 666a90f7e98SDmitry Torokhov input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); 667a90f7e98SDmitry Torokhov input_set_abs_params(input_dev, ABS_X, 668ffa458c1SDavid Brownell pdata->x_min ? : 0, 669ffa458c1SDavid Brownell pdata->x_max ? : MAX_12BIT, 670ffa458c1SDavid Brownell 0, 0); 671a90f7e98SDmitry Torokhov input_set_abs_params(input_dev, ABS_Y, 672ffa458c1SDavid Brownell pdata->y_min ? : 0, 673ffa458c1SDavid Brownell pdata->y_max ? : MAX_12BIT, 674ffa458c1SDavid Brownell 0, 0); 675a90f7e98SDmitry Torokhov input_set_abs_params(input_dev, ABS_PRESSURE, 676ffa458c1SDavid Brownell pdata->pressure_min, pdata->pressure_max, 0, 0); 677ffa458c1SDavid Brownell 678ffa458c1SDavid Brownell /* set up the transfers to read touchscreen state; this assumes we 679ffa458c1SDavid Brownell * use formula #2 for pressure, not #3. 680ffa458c1SDavid Brownell */ 6810b7018aaSImre Deak m = &ts->msg[0]; 682ffa458c1SDavid Brownell x = ts->xfer; 683ffa458c1SDavid Brownell 6840b7018aaSImre Deak spi_message_init(m); 6850b7018aaSImre Deak 686ffa458c1SDavid Brownell /* y- still on; turn on only y+ (and ADC) */ 687d93f70b2SDavid Brownell ts->read_y = READ_Y; 688d93f70b2SDavid Brownell x->tx_buf = &ts->read_y; 689ffa458c1SDavid Brownell x->len = 1; 6900b7018aaSImre Deak spi_message_add_tail(x, m); 691d93f70b2SDavid Brownell 692ffa458c1SDavid Brownell x++; 693ffa458c1SDavid Brownell x->rx_buf = &ts->tc.y; 694ffa458c1SDavid Brownell x->len = 2; 6950b7018aaSImre Deak spi_message_add_tail(x, m); 696ffa458c1SDavid Brownell 6970b7018aaSImre Deak m->complete = ads7846_debounce; 6980b7018aaSImre Deak m->context = ts; 699d93f70b2SDavid Brownell 7000b7018aaSImre Deak m++; 7010b7018aaSImre Deak spi_message_init(m); 702ffa458c1SDavid Brownell 703ffa458c1SDavid Brownell /* turn y- off, x+ on, then leave in lowpower */ 704d93f70b2SDavid Brownell x++; 705d93f70b2SDavid Brownell ts->read_x = READ_X; 706d93f70b2SDavid Brownell x->tx_buf = &ts->read_x; 707ffa458c1SDavid Brownell x->len = 1; 7080b7018aaSImre Deak spi_message_add_tail(x, m); 709d93f70b2SDavid Brownell 710ffa458c1SDavid Brownell x++; 711ffa458c1SDavid Brownell x->rx_buf = &ts->tc.x; 712ffa458c1SDavid Brownell x->len = 2; 7130b7018aaSImre Deak spi_message_add_tail(x, m); 7140b7018aaSImre Deak 7150b7018aaSImre Deak m->complete = ads7846_debounce; 7160b7018aaSImre Deak m->context = ts; 7170b7018aaSImre Deak 7180b7018aaSImre Deak /* turn y+ off, x- on; we'll use formula #2 */ 7190b7018aaSImre Deak if (ts->model == 7846) { 7200b7018aaSImre Deak m++; 7210b7018aaSImre Deak spi_message_init(m); 7220b7018aaSImre Deak 7230b7018aaSImre Deak x++; 7240b7018aaSImre Deak ts->read_z1 = READ_Z1; 7250b7018aaSImre Deak x->tx_buf = &ts->read_z1; 7260b7018aaSImre Deak x->len = 1; 7270b7018aaSImre Deak spi_message_add_tail(x, m); 7280b7018aaSImre Deak 7290b7018aaSImre Deak x++; 7300b7018aaSImre Deak x->rx_buf = &ts->tc.z1; 7310b7018aaSImre Deak x->len = 2; 7320b7018aaSImre Deak spi_message_add_tail(x, m); 7330b7018aaSImre Deak 7340b7018aaSImre Deak m->complete = ads7846_debounce; 7350b7018aaSImre Deak m->context = ts; 7360b7018aaSImre Deak 7370b7018aaSImre Deak m++; 7380b7018aaSImre Deak spi_message_init(m); 7390b7018aaSImre Deak 7400b7018aaSImre Deak x++; 7410b7018aaSImre Deak ts->read_z2 = READ_Z2; 7420b7018aaSImre Deak x->tx_buf = &ts->read_z2; 7430b7018aaSImre Deak x->len = 1; 7440b7018aaSImre Deak spi_message_add_tail(x, m); 7450b7018aaSImre Deak 7460b7018aaSImre Deak x++; 7470b7018aaSImre Deak x->rx_buf = &ts->tc.z2; 7480b7018aaSImre Deak x->len = 2; 7490b7018aaSImre Deak spi_message_add_tail(x, m); 7500b7018aaSImre Deak 7510b7018aaSImre Deak m->complete = ads7846_debounce; 7520b7018aaSImre Deak m->context = ts; 7530b7018aaSImre Deak } 75453a0ef89SImre Deak 75553a0ef89SImre Deak /* power down */ 7560b7018aaSImre Deak m++; 7570b7018aaSImre Deak spi_message_init(m); 7580b7018aaSImre Deak 75953a0ef89SImre Deak x++; 76053a0ef89SImre Deak ts->pwrdown = PWRDOWN; 76153a0ef89SImre Deak x->tx_buf = &ts->pwrdown; 76253a0ef89SImre Deak x->len = 1; 7630b7018aaSImre Deak spi_message_add_tail(x, m); 76453a0ef89SImre Deak 76553a0ef89SImre Deak x++; 76653a0ef89SImre Deak x->rx_buf = &ts->dummy; 76753a0ef89SImre Deak x->len = 2; 768d93f70b2SDavid Brownell CS_CHANGE(*x); 7690b7018aaSImre Deak spi_message_add_tail(x, m); 770ffa458c1SDavid Brownell 7710b7018aaSImre Deak m->complete = ads7846_rx; 7720b7018aaSImre Deak m->context = ts; 773ffa458c1SDavid Brownell 774d5b415c9SImre Deak ts->last_msg = m; 775d5b415c9SImre Deak 776dace1453SThomas Gleixner if (request_irq(spi->irq, ads7846_irq, IRQF_TRIGGER_FALLING, 7779084533eSDavid Brownell spi->dev.driver->name, ts)) { 7782e5a7bd9SDavid Brownell dev_dbg(&spi->dev, "irq %d busy?\n", spi->irq); 779a90f7e98SDmitry Torokhov err = -EBUSY; 780a90f7e98SDmitry Torokhov goto err_free_mem; 781ffa458c1SDavid Brownell } 782ffa458c1SDavid Brownell 7832e5a7bd9SDavid Brownell dev_info(&spi->dev, "touchscreen, irq %d\n", spi->irq); 784ffa458c1SDavid Brownell 785ffa458c1SDavid Brownell /* take a first sample, leaving nPENIRQ active; avoid 786ffa458c1SDavid Brownell * the touchscreen, in case it's not connected. 787ffa458c1SDavid Brownell */ 7882e5a7bd9SDavid Brownell (void) ads7846_read12_ser(&spi->dev, 789ffa458c1SDavid Brownell READ_12BIT_SER(vaux) | ADS_PD10_ALL_ON); 790ffa458c1SDavid Brownell 791ffa458c1SDavid Brownell /* ads7843/7845 don't have temperature sensors, and 792ffa458c1SDavid Brownell * use the other sensors a bit differently too 793ffa458c1SDavid Brownell */ 794ffa458c1SDavid Brownell if (ts->model == 7846) { 7952e5a7bd9SDavid Brownell device_create_file(&spi->dev, &dev_attr_temp0); 7962e5a7bd9SDavid Brownell device_create_file(&spi->dev, &dev_attr_temp1); 797ffa458c1SDavid Brownell } 798ffa458c1SDavid Brownell if (ts->model != 7845) 7992e5a7bd9SDavid Brownell device_create_file(&spi->dev, &dev_attr_vbatt); 8002e5a7bd9SDavid Brownell device_create_file(&spi->dev, &dev_attr_vaux); 801ffa458c1SDavid Brownell 802438f2a74SImre Deak device_create_file(&spi->dev, &dev_attr_pen_down); 803438f2a74SImre Deak 8047de90a8cSImre Deak device_create_file(&spi->dev, &dev_attr_disable); 8057de90a8cSImre Deak 806a90f7e98SDmitry Torokhov err = input_register_device(input_dev); 807a90f7e98SDmitry Torokhov if (err) 8087de90a8cSImre Deak goto err_remove_attr; 809a90f7e98SDmitry Torokhov 810ffa458c1SDavid Brownell return 0; 811a90f7e98SDmitry Torokhov 8127de90a8cSImre Deak err_remove_attr: 8137de90a8cSImre Deak device_remove_file(&spi->dev, &dev_attr_disable); 8147de90a8cSImre Deak device_remove_file(&spi->dev, &dev_attr_pen_down); 8157de90a8cSImre Deak if (ts->model == 7846) { 8167de90a8cSImre Deak device_remove_file(&spi->dev, &dev_attr_temp1); 8177de90a8cSImre Deak device_remove_file(&spi->dev, &dev_attr_temp0); 8187de90a8cSImre Deak } 8197de90a8cSImre Deak if (ts->model != 7845) 8207de90a8cSImre Deak device_remove_file(&spi->dev, &dev_attr_vbatt); 8217de90a8cSImre Deak device_remove_file(&spi->dev, &dev_attr_vaux); 8227de90a8cSImre Deak 823a90f7e98SDmitry Torokhov free_irq(spi->irq, ts); 824a90f7e98SDmitry Torokhov err_free_mem: 825a90f7e98SDmitry Torokhov input_free_device(input_dev); 826a90f7e98SDmitry Torokhov kfree(ts); 827a90f7e98SDmitry Torokhov return err; 828ffa458c1SDavid Brownell } 829ffa458c1SDavid Brownell 8302e5a7bd9SDavid Brownell static int __devexit ads7846_remove(struct spi_device *spi) 831ffa458c1SDavid Brownell { 8322e5a7bd9SDavid Brownell struct ads7846 *ts = dev_get_drvdata(&spi->dev); 833ffa458c1SDavid Brownell 8347de90a8cSImre Deak input_unregister_device(ts->input); 8357de90a8cSImre Deak 8362e5a7bd9SDavid Brownell ads7846_suspend(spi, PMSG_SUSPEND); 837ffa458c1SDavid Brownell 8387de90a8cSImre Deak device_remove_file(&spi->dev, &dev_attr_disable); 839438f2a74SImre Deak device_remove_file(&spi->dev, &dev_attr_pen_down); 840ffa458c1SDavid Brownell if (ts->model == 7846) { 8412e5a7bd9SDavid Brownell device_remove_file(&spi->dev, &dev_attr_temp1); 8427de90a8cSImre Deak device_remove_file(&spi->dev, &dev_attr_temp0); 843ffa458c1SDavid Brownell } 844ffa458c1SDavid Brownell if (ts->model != 7845) 8452e5a7bd9SDavid Brownell device_remove_file(&spi->dev, &dev_attr_vbatt); 8462e5a7bd9SDavid Brownell device_remove_file(&spi->dev, &dev_attr_vaux); 847ffa458c1SDavid Brownell 8487de90a8cSImre Deak free_irq(ts->spi->irq, ts); 849c9e617a5SImre Deak /* suspend left the IRQ disabled */ 8507de90a8cSImre Deak enable_irq(ts->spi->irq); 8517de90a8cSImre Deak 852ffa458c1SDavid Brownell kfree(ts); 853ffa458c1SDavid Brownell 8542e5a7bd9SDavid Brownell dev_dbg(&spi->dev, "unregistered touchscreen\n"); 855ffa458c1SDavid Brownell return 0; 856ffa458c1SDavid Brownell } 857ffa458c1SDavid Brownell 8582e5a7bd9SDavid Brownell static struct spi_driver ads7846_driver = { 8592e5a7bd9SDavid Brownell .driver = { 860ffa458c1SDavid Brownell .name = "ads7846", 861ffa458c1SDavid Brownell .bus = &spi_bus_type, 8622e5a7bd9SDavid Brownell .owner = THIS_MODULE, 8632e5a7bd9SDavid Brownell }, 864ffa458c1SDavid Brownell .probe = ads7846_probe, 8652e5a7bd9SDavid Brownell .remove = __devexit_p(ads7846_remove), 866ffa458c1SDavid Brownell .suspend = ads7846_suspend, 867ffa458c1SDavid Brownell .resume = ads7846_resume, 868ffa458c1SDavid Brownell }; 869ffa458c1SDavid Brownell 870ffa458c1SDavid Brownell static int __init ads7846_init(void) 871ffa458c1SDavid Brownell { 872ffa458c1SDavid Brownell /* grr, board-specific init should stay out of drivers!! */ 873ffa458c1SDavid Brownell 874ffa458c1SDavid Brownell #ifdef CONFIG_ARCH_OMAP 875ffa458c1SDavid Brownell if (machine_is_omap_osk()) { 876ffa458c1SDavid Brownell /* GPIO4 = PENIRQ; GPIO6 = BUSY */ 877ffa458c1SDavid Brownell omap_request_gpio(4); 878ffa458c1SDavid Brownell omap_set_gpio_direction(4, 1); 879ffa458c1SDavid Brownell omap_request_gpio(6); 880ffa458c1SDavid Brownell omap_set_gpio_direction(6, 1); 881ffa458c1SDavid Brownell } 882ffa458c1SDavid Brownell // also TI 1510 Innovator, bitbanging through FPGA 883ffa458c1SDavid Brownell // also Nokia 770 884ffa458c1SDavid Brownell // also Palm Tungsten T2 885ffa458c1SDavid Brownell #endif 886ffa458c1SDavid Brownell 887ffa458c1SDavid Brownell // PXA: 888ffa458c1SDavid Brownell // also Dell Axim X50 889ffa458c1SDavid Brownell // also HP iPaq H191x/H192x/H415x/H435x 8902e5a7bd9SDavid Brownell // also Intel Lubbock (additional to UCB1400; as temperature sensor) 891ffa458c1SDavid Brownell // also Sharp Zaurus C7xx, C8xx (corgi/sheperd/husky) 892ffa458c1SDavid Brownell 8932e5a7bd9SDavid Brownell // Atmel at91sam9261-EK uses ads7843 8942e5a7bd9SDavid Brownell 895ffa458c1SDavid Brownell // also various AMD Au1x00 devel boards 896ffa458c1SDavid Brownell 8972e5a7bd9SDavid Brownell return spi_register_driver(&ads7846_driver); 898ffa458c1SDavid Brownell } 899ffa458c1SDavid Brownell module_init(ads7846_init); 900ffa458c1SDavid Brownell 901ffa458c1SDavid Brownell static void __exit ads7846_exit(void) 902ffa458c1SDavid Brownell { 9032e5a7bd9SDavid Brownell spi_unregister_driver(&ads7846_driver); 904ffa458c1SDavid Brownell 905ffa458c1SDavid Brownell #ifdef CONFIG_ARCH_OMAP 906ffa458c1SDavid Brownell if (machine_is_omap_osk()) { 907ffa458c1SDavid Brownell omap_free_gpio(4); 908ffa458c1SDavid Brownell omap_free_gpio(6); 909ffa458c1SDavid Brownell } 910ffa458c1SDavid Brownell #endif 911ffa458c1SDavid Brownell 912ffa458c1SDavid Brownell } 913ffa458c1SDavid Brownell module_exit(ads7846_exit); 914ffa458c1SDavid Brownell 915ffa458c1SDavid Brownell MODULE_DESCRIPTION("ADS7846 TouchScreen Driver"); 916ffa458c1SDavid Brownell MODULE_LICENSE("GPL"); 917