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 */ 202c8dc071SDavid Brownell #include <linux/hwmon.h> 21ffa458c1SDavid Brownell #include <linux/init.h> 222c8dc071SDavid Brownell #include <linux/err.h> 23ffa458c1SDavid Brownell #include <linux/delay.h> 24ffa458c1SDavid Brownell #include <linux/input.h> 25ffa458c1SDavid Brownell #include <linux/interrupt.h> 26ffa458c1SDavid Brownell #include <linux/slab.h> 274d5975e5SEric Miao #include <linux/gpio.h> 28ffa458c1SDavid Brownell #include <linux/spi/spi.h> 29ffa458c1SDavid Brownell #include <linux/spi/ads7846.h> 303ac8bf07SAndrew Morton #include <asm/irq.h> 31ffa458c1SDavid Brownell 32ffa458c1SDavid Brownell /* 339084533eSDavid Brownell * This code has been heavily tested on a Nokia 770, and lightly 34*52ce4eaaSPavel Machek * tested on other ads7846 devices (OSK/Mistral, Lubbock, Spitz). 35bff0de5fSDavid Brownell * TSC2046 is just newer ads7846 silicon. 36969111e9SNicolas Ferre * Support for ads7843 tested on Atmel at91sam926x-EK. 37969111e9SNicolas Ferre * Support for ads7845 has only been stubbed in. 38ffa458c1SDavid Brownell * 397de90a8cSImre Deak * IRQ handling needs a workaround because of a shortcoming in handling 407de90a8cSImre Deak * edge triggered IRQs on some platforms like the OMAP1/2. These 417de90a8cSImre Deak * platforms don't handle the ARM lazy IRQ disabling properly, thus we 427de90a8cSImre Deak * have to maintain our own SW IRQ disabled status. This should be 437de90a8cSImre Deak * removed as soon as the affected platform's IRQ handling is fixed. 447de90a8cSImre Deak * 45*52ce4eaaSPavel Machek * App note sbaa036 talks in more detail about accurate sampling... 46ffa458c1SDavid Brownell * that ought to help in situations like LCDs inducing noise (which 47ffa458c1SDavid Brownell * can also be helped by using synch signals) and more generally. 487de90a8cSImre Deak * This driver tries to utilize the measures described in the app 497de90a8cSImre Deak * note. The strength of filtering can be set in the board-* specific 507de90a8cSImre Deak * files. 51ffa458c1SDavid Brownell */ 52ffa458c1SDavid Brownell 531936d590SImre Deak #define TS_POLL_DELAY (1 * 1000000) /* ns delay before the first sample */ 541936d590SImre Deak #define TS_POLL_PERIOD (5 * 1000000) /* ns delay between samples */ 55ffa458c1SDavid Brownell 56d93f70b2SDavid Brownell /* this driver doesn't aim at the peak continuous sample rate */ 57d93f70b2SDavid Brownell #define SAMPLE_BITS (8 /*cmd*/ + 16 /*sample*/ + 2 /* before, after */) 58d93f70b2SDavid Brownell 59ffa458c1SDavid Brownell struct ts_event { 60ffa458c1SDavid Brownell /* For portability, we can't read 12 bit values using SPI (which 61ffa458c1SDavid Brownell * would make the controller deliver them as native byteorder u16 62d93f70b2SDavid Brownell * with msbs zeroed). Instead, we read them as two 8-bit values, 63da970e69SImre Deak * *** WHICH NEED BYTESWAPPING *** and range adjustment. 64ffa458c1SDavid Brownell */ 65da970e69SImre Deak u16 x; 66da970e69SImre Deak u16 y; 67da970e69SImre Deak u16 z1, z2; 68d5b415c9SImre Deak int ignore; 69ffa458c1SDavid Brownell }; 70ffa458c1SDavid Brownell 71e8f462d2SDmitry Torokhov /* 72e8f462d2SDmitry Torokhov * We allocate this separately to avoid cache line sharing issues when 73e8f462d2SDmitry Torokhov * driver is used with DMA-based SPI controllers (like atmel_spi) on 74e8f462d2SDmitry Torokhov * systems where main memory is not DMA-coherent (most non-x86 boards). 75e8f462d2SDmitry Torokhov */ 76e8f462d2SDmitry Torokhov struct ads7846_packet { 77e8f462d2SDmitry Torokhov u8 read_x, read_y, read_z1, read_z2, pwrdown; 78e8f462d2SDmitry Torokhov u16 dummy; /* for the pwrdown read */ 79e8f462d2SDmitry Torokhov struct ts_event tc; 80e8f462d2SDmitry Torokhov }; 81e8f462d2SDmitry Torokhov 82ffa458c1SDavid Brownell struct ads7846 { 83a90f7e98SDmitry Torokhov struct input_dev *input; 84ffa458c1SDavid Brownell char phys[32]; 85b58895f8SMichael Roth char name[32]; 86ffa458c1SDavid Brownell 87ffa458c1SDavid Brownell struct spi_device *spi; 882c8dc071SDavid Brownell 892c8dc071SDavid Brownell #if defined(CONFIG_HWMON) || defined(CONFIG_HWMON_MODULE) 908dd51650SDmitry Torokhov struct attribute_group *attr_group; 911beeffe4STony Jones struct device *hwmon; 922c8dc071SDavid Brownell #endif 932c8dc071SDavid Brownell 94ffa458c1SDavid Brownell u16 model; 957c6d0ee1SDavid Brownell u16 vref_mv; 96ffa458c1SDavid Brownell u16 vref_delay_usecs; 97ffa458c1SDavid Brownell u16 x_plate_ohms; 98d5b415c9SImre Deak u16 pressure_max; 99ffa458c1SDavid Brownell 10086579a4cSMichael Roth bool swap_xy; 10186579a4cSMichael Roth 102e8f462d2SDmitry Torokhov struct ads7846_packet *packet; 103ffa458c1SDavid Brownell 104e4f48861SSemih Hazar struct spi_transfer xfer[18]; 1050b7018aaSImre Deak struct spi_message msg[5]; 106d5b415c9SImre Deak struct spi_message *last_msg; 1070b7018aaSImre Deak int msg_idx; 1080b7018aaSImre Deak int read_cnt; 109d5b415c9SImre Deak int read_rep; 1100b7018aaSImre Deak int last_read; 1110b7018aaSImre Deak 1120b7018aaSImre Deak u16 debounce_max; 1130b7018aaSImre Deak u16 debounce_tol; 114d5b415c9SImre Deak u16 debounce_rep; 115ffa458c1SDavid Brownell 1161d25891fSSemih Hazar u16 penirq_recheck_delay_usecs; 1171d25891fSSemih Hazar 118ffa458c1SDavid Brownell spinlock_t lock; 1191936d590SImre Deak struct hrtimer timer; 120ffa458c1SDavid Brownell unsigned pendown:1; /* P: lock */ 121ffa458c1SDavid Brownell unsigned pending:1; /* P: lock */ 122ffa458c1SDavid Brownell // FIXME remove "irq_disabled" 123ffa458c1SDavid Brownell unsigned irq_disabled:1; /* P: lock */ 1247de90a8cSImre Deak unsigned disabled:1; 125fbb38e30SDavid Brownell unsigned is_suspended:1; 126c9e617a5SImre Deak 127da970e69SImre Deak int (*filter)(void *data, int data_idx, int *val); 128da970e69SImre Deak void *filter_data; 129da970e69SImre Deak void (*filter_cleanup)(void *data); 130c9e617a5SImre Deak int (*get_pendown_state)(void); 1314d5975e5SEric Miao int gpio_pendown; 132fd746d54SEric Miao 133fd746d54SEric Miao void (*wait_for_sync)(void); 134ffa458c1SDavid Brownell }; 135ffa458c1SDavid Brownell 136ffa458c1SDavid Brownell /* leave chip selected when we're done, for quicker re-select? */ 137ffa458c1SDavid Brownell #if 0 138ffa458c1SDavid Brownell #define CS_CHANGE(xfer) ((xfer).cs_change = 1) 139ffa458c1SDavid Brownell #else 140ffa458c1SDavid Brownell #define CS_CHANGE(xfer) ((xfer).cs_change = 0) 141ffa458c1SDavid Brownell #endif 142ffa458c1SDavid Brownell 143ffa458c1SDavid Brownell /*--------------------------------------------------------------------------*/ 144ffa458c1SDavid Brownell 145ffa458c1SDavid Brownell /* The ADS7846 has touchscreen and other sensors. 146ffa458c1SDavid Brownell * Earlier ads784x chips are somewhat compatible. 147ffa458c1SDavid Brownell */ 148ffa458c1SDavid Brownell #define ADS_START (1 << 7) 149ffa458c1SDavid Brownell #define ADS_A2A1A0_d_y (1 << 4) /* differential */ 150ffa458c1SDavid Brownell #define ADS_A2A1A0_d_z1 (3 << 4) /* differential */ 151ffa458c1SDavid Brownell #define ADS_A2A1A0_d_z2 (4 << 4) /* differential */ 152ffa458c1SDavid Brownell #define ADS_A2A1A0_d_x (5 << 4) /* differential */ 153ffa458c1SDavid Brownell #define ADS_A2A1A0_temp0 (0 << 4) /* non-differential */ 154ffa458c1SDavid Brownell #define ADS_A2A1A0_vbatt (2 << 4) /* non-differential */ 155ffa458c1SDavid Brownell #define ADS_A2A1A0_vaux (6 << 4) /* non-differential */ 156ffa458c1SDavid Brownell #define ADS_A2A1A0_temp1 (7 << 4) /* non-differential */ 157ffa458c1SDavid Brownell #define ADS_8_BIT (1 << 3) 158ffa458c1SDavid Brownell #define ADS_12_BIT (0 << 3) 159ffa458c1SDavid Brownell #define ADS_SER (1 << 2) /* non-differential */ 160ffa458c1SDavid Brownell #define ADS_DFR (0 << 2) /* differential */ 161ffa458c1SDavid Brownell #define ADS_PD10_PDOWN (0 << 0) /* lowpower mode + penirq */ 162ffa458c1SDavid Brownell #define ADS_PD10_ADC_ON (1 << 0) /* ADC on */ 163ffa458c1SDavid Brownell #define ADS_PD10_REF_ON (2 << 0) /* vREF on + penirq */ 164ffa458c1SDavid Brownell #define ADS_PD10_ALL_ON (3 << 0) /* ADC + vREF on */ 165ffa458c1SDavid Brownell 166ffa458c1SDavid Brownell #define MAX_12BIT ((1<<12)-1) 167ffa458c1SDavid Brownell 168ffa458c1SDavid Brownell /* leave ADC powered up (disables penirq) between differential samples */ 169de2defd9SImre Deak #define READ_12BIT_DFR(x, adc, vref) (ADS_START | ADS_A2A1A0_d_ ## x \ 170de2defd9SImre Deak | ADS_12_BIT | ADS_DFR | \ 171de2defd9SImre Deak (adc ? ADS_PD10_ADC_ON : 0) | (vref ? ADS_PD10_REF_ON : 0)) 172ffa458c1SDavid Brownell 173de2defd9SImre Deak #define READ_Y(vref) (READ_12BIT_DFR(y, 1, vref)) 174de2defd9SImre Deak #define READ_Z1(vref) (READ_12BIT_DFR(z1, 1, vref)) 175de2defd9SImre Deak #define READ_Z2(vref) (READ_12BIT_DFR(z2, 1, vref)) 17653a0ef89SImre Deak 177de2defd9SImre Deak #define READ_X(vref) (READ_12BIT_DFR(x, 1, vref)) 178de2defd9SImre Deak #define PWRDOWN (READ_12BIT_DFR(y, 0, 0)) /* LAST */ 179ffa458c1SDavid Brownell 180ffa458c1SDavid Brownell /* single-ended samples need to first power up reference voltage; 181ffa458c1SDavid Brownell * we leave both ADC and VREF powered 182ffa458c1SDavid Brownell */ 183ffa458c1SDavid Brownell #define READ_12BIT_SER(x) (ADS_START | ADS_A2A1A0_ ## x \ 184ffa458c1SDavid Brownell | ADS_12_BIT | ADS_SER) 185ffa458c1SDavid Brownell 186de2defd9SImre Deak #define REF_ON (READ_12BIT_DFR(x, 1, 1)) 187de2defd9SImre Deak #define REF_OFF (READ_12BIT_DFR(y, 0, 0)) 188ffa458c1SDavid Brownell 189ffa458c1SDavid Brownell /*--------------------------------------------------------------------------*/ 190ffa458c1SDavid Brownell 191ffa458c1SDavid Brownell /* 192ffa458c1SDavid Brownell * Non-touchscreen sensors only use single-ended conversions. 1932c8dc071SDavid Brownell * The range is GND..vREF. The ads7843 and ads7835 must use external vREF; 1942c8dc071SDavid Brownell * ads7846 lets that pin be unconnected, to use internal vREF. 195ffa458c1SDavid Brownell */ 196ffa458c1SDavid Brownell 197ffa458c1SDavid Brownell struct ser_req { 198d93f70b2SDavid Brownell u8 ref_on; 199ffa458c1SDavid Brownell u8 command; 200d93f70b2SDavid Brownell u8 ref_off; 201ffa458c1SDavid Brownell u16 scratch; 202ffa458c1SDavid Brownell __be16 sample; 203ffa458c1SDavid Brownell struct spi_message msg; 204ffa458c1SDavid Brownell struct spi_transfer xfer[6]; 205ffa458c1SDavid Brownell }; 206ffa458c1SDavid Brownell 2077de90a8cSImre Deak static void ads7846_enable(struct ads7846 *ts); 2087de90a8cSImre Deak static void ads7846_disable(struct ads7846 *ts); 2097de90a8cSImre Deak 210c9e617a5SImre Deak static int device_suspended(struct device *dev) 211c9e617a5SImre Deak { 212c9e617a5SImre Deak struct ads7846 *ts = dev_get_drvdata(dev); 213fbb38e30SDavid Brownell return ts->is_suspended || ts->disabled; 214c9e617a5SImre Deak } 215c9e617a5SImre Deak 216ffa458c1SDavid Brownell static int ads7846_read12_ser(struct device *dev, unsigned command) 217ffa458c1SDavid Brownell { 218ffa458c1SDavid Brownell struct spi_device *spi = to_spi_device(dev); 219ffa458c1SDavid Brownell struct ads7846 *ts = dev_get_drvdata(dev); 220e94b1766SChristoph Lameter struct ser_req *req = kzalloc(sizeof *req, GFP_KERNEL); 221ffa458c1SDavid Brownell int status; 2222c8dc071SDavid Brownell int use_internal; 223ffa458c1SDavid Brownell 224ffa458c1SDavid Brownell if (!req) 225ffa458c1SDavid Brownell return -ENOMEM; 226ffa458c1SDavid Brownell 2270b7018aaSImre Deak spi_message_init(&req->msg); 2288275c642SVitaly Wool 2292c8dc071SDavid Brownell /* FIXME boards with ads7846 might use external vref instead ... */ 2302c8dc071SDavid Brownell use_internal = (ts->model == 7846); 2312c8dc071SDavid Brownell 2322c8dc071SDavid Brownell /* maybe turn on internal vREF, and let it settle */ 2332c8dc071SDavid Brownell if (use_internal) { 234d93f70b2SDavid Brownell req->ref_on = REF_ON; 235d93f70b2SDavid Brownell req->xfer[0].tx_buf = &req->ref_on; 236ffa458c1SDavid Brownell req->xfer[0].len = 1; 2372c8dc071SDavid Brownell spi_message_add_tail(&req->xfer[0], &req->msg); 2382c8dc071SDavid Brownell 239ffa458c1SDavid Brownell req->xfer[1].rx_buf = &req->scratch; 240ffa458c1SDavid Brownell req->xfer[1].len = 2; 241ffa458c1SDavid Brownell 2422c8dc071SDavid Brownell /* for 1uF, settle for 800 usec; no cap, 100 usec. */ 243ffa458c1SDavid Brownell req->xfer[1].delay_usecs = ts->vref_delay_usecs; 2442c8dc071SDavid Brownell spi_message_add_tail(&req->xfer[1], &req->msg); 2452c8dc071SDavid Brownell } 246ffa458c1SDavid Brownell 247ffa458c1SDavid Brownell /* take sample */ 248ffa458c1SDavid Brownell req->command = (u8) command; 249ffa458c1SDavid Brownell req->xfer[2].tx_buf = &req->command; 250ffa458c1SDavid Brownell req->xfer[2].len = 1; 2512c8dc071SDavid Brownell spi_message_add_tail(&req->xfer[2], &req->msg); 2522c8dc071SDavid Brownell 253ffa458c1SDavid Brownell req->xfer[3].rx_buf = &req->sample; 254ffa458c1SDavid Brownell req->xfer[3].len = 2; 2552c8dc071SDavid Brownell spi_message_add_tail(&req->xfer[3], &req->msg); 256ffa458c1SDavid Brownell 257ffa458c1SDavid Brownell /* REVISIT: take a few more samples, and compare ... */ 258ffa458c1SDavid Brownell 259969111e9SNicolas Ferre /* converter in low power mode & enable PENIRQ */ 260969111e9SNicolas Ferre req->ref_off = PWRDOWN; 261d93f70b2SDavid Brownell req->xfer[4].tx_buf = &req->ref_off; 262ffa458c1SDavid Brownell req->xfer[4].len = 1; 2632c8dc071SDavid Brownell spi_message_add_tail(&req->xfer[4], &req->msg); 2642c8dc071SDavid Brownell 265ffa458c1SDavid Brownell req->xfer[5].rx_buf = &req->scratch; 266ffa458c1SDavid Brownell req->xfer[5].len = 2; 267ffa458c1SDavid Brownell CS_CHANGE(req->xfer[5]); 2682c8dc071SDavid Brownell spi_message_add_tail(&req->xfer[5], &req->msg); 269ffa458c1SDavid Brownell 270c9e617a5SImre Deak ts->irq_disabled = 1; 271ffa458c1SDavid Brownell disable_irq(spi->irq); 272ffa458c1SDavid Brownell status = spi_sync(spi, &req->msg); 273c9e617a5SImre Deak ts->irq_disabled = 0; 274ffa458c1SDavid Brownell enable_irq(spi->irq); 275ffa458c1SDavid Brownell 276c24b2602SMarc Pignat if (status == 0) { 2779084533eSDavid Brownell /* on-wire is a must-ignore bit, a BE12 value, then padding */ 2787c6d0ee1SDavid Brownell status = be16_to_cpu(req->sample); 2797c6d0ee1SDavid Brownell status = status >> 3; 2807c6d0ee1SDavid Brownell status &= 0x0fff; 281c24b2602SMarc Pignat } 2829084533eSDavid Brownell 2839084533eSDavid Brownell kfree(req); 2847c6d0ee1SDavid Brownell return status; 285ffa458c1SDavid Brownell } 286ffa458c1SDavid Brownell 2872c8dc071SDavid Brownell #if defined(CONFIG_HWMON) || defined(CONFIG_HWMON_MODULE) 2882c8dc071SDavid Brownell 2892c8dc071SDavid Brownell #define SHOW(name, var, adjust) static ssize_t \ 290ffa458c1SDavid Brownell name ## _show(struct device *dev, struct device_attribute *attr, char *buf) \ 291ffa458c1SDavid Brownell { \ 2922c8dc071SDavid Brownell struct ads7846 *ts = dev_get_drvdata(dev); \ 293ffa458c1SDavid Brownell ssize_t v = ads7846_read12_ser(dev, \ 2942c8dc071SDavid Brownell READ_12BIT_SER(var) | ADS_PD10_ALL_ON); \ 295ffa458c1SDavid Brownell if (v < 0) \ 296ffa458c1SDavid Brownell return v; \ 2972c8dc071SDavid Brownell return sprintf(buf, "%u\n", adjust(ts, v)); \ 298ffa458c1SDavid Brownell } \ 299ffa458c1SDavid Brownell static DEVICE_ATTR(name, S_IRUGO, name ## _show, NULL); 300ffa458c1SDavid Brownell 3012c8dc071SDavid Brownell 302b731d7b6SAdam Buchbinder /* Sysfs conventions report temperatures in millidegrees Celsius. 3032c8dc071SDavid Brownell * ADS7846 could use the low-accuracy two-sample scheme, but can't do the high 3042c8dc071SDavid Brownell * accuracy scheme without calibration data. For now we won't try either; 3052c8dc071SDavid Brownell * userspace sees raw sensor values, and must scale/calibrate appropriately. 3062c8dc071SDavid Brownell */ 3072c8dc071SDavid Brownell static inline unsigned null_adjust(struct ads7846 *ts, ssize_t v) 3082c8dc071SDavid Brownell { 3092c8dc071SDavid Brownell return v; 3102c8dc071SDavid Brownell } 3112c8dc071SDavid Brownell 3122c8dc071SDavid Brownell SHOW(temp0, temp0, null_adjust) /* temp1_input */ 3132c8dc071SDavid Brownell SHOW(temp1, temp1, null_adjust) /* temp2_input */ 3142c8dc071SDavid Brownell 3152c8dc071SDavid Brownell 3162c8dc071SDavid Brownell /* sysfs conventions report voltages in millivolts. We can convert voltages 3172c8dc071SDavid Brownell * if we know vREF. userspace may need to scale vAUX to match the board's 3182c8dc071SDavid Brownell * external resistors; we assume that vBATT only uses the internal ones. 3192c8dc071SDavid Brownell */ 3202c8dc071SDavid Brownell static inline unsigned vaux_adjust(struct ads7846 *ts, ssize_t v) 3212c8dc071SDavid Brownell { 3222c8dc071SDavid Brownell unsigned retval = v; 3232c8dc071SDavid Brownell 3242c8dc071SDavid Brownell /* external resistors may scale vAUX into 0..vREF */ 3257c6d0ee1SDavid Brownell retval *= ts->vref_mv; 3262c8dc071SDavid Brownell retval = retval >> 12; 3272c8dc071SDavid Brownell return retval; 3282c8dc071SDavid Brownell } 3292c8dc071SDavid Brownell 3302c8dc071SDavid Brownell static inline unsigned vbatt_adjust(struct ads7846 *ts, ssize_t v) 3312c8dc071SDavid Brownell { 3322c8dc071SDavid Brownell unsigned retval = vaux_adjust(ts, v); 3332c8dc071SDavid Brownell 3342c8dc071SDavid Brownell /* ads7846 has a resistor ladder to scale this signal down */ 3352c8dc071SDavid Brownell if (ts->model == 7846) 3362c8dc071SDavid Brownell retval *= 4; 3372c8dc071SDavid Brownell return retval; 3382c8dc071SDavid Brownell } 3392c8dc071SDavid Brownell 3402c8dc071SDavid Brownell SHOW(in0_input, vaux, vaux_adjust) 3412c8dc071SDavid Brownell SHOW(in1_input, vbatt, vbatt_adjust) 3422c8dc071SDavid Brownell 3432c8dc071SDavid Brownell 3442c8dc071SDavid Brownell static struct attribute *ads7846_attributes[] = { 3452c8dc071SDavid Brownell &dev_attr_temp0.attr, 3462c8dc071SDavid Brownell &dev_attr_temp1.attr, 3472c8dc071SDavid Brownell &dev_attr_in0_input.attr, 3482c8dc071SDavid Brownell &dev_attr_in1_input.attr, 3492c8dc071SDavid Brownell NULL, 3502c8dc071SDavid Brownell }; 3512c8dc071SDavid Brownell 3522c8dc071SDavid Brownell static struct attribute_group ads7846_attr_group = { 3532c8dc071SDavid Brownell .attrs = ads7846_attributes, 3542c8dc071SDavid Brownell }; 3552c8dc071SDavid Brownell 3562c8dc071SDavid Brownell static struct attribute *ads7843_attributes[] = { 3572c8dc071SDavid Brownell &dev_attr_in0_input.attr, 3582c8dc071SDavid Brownell &dev_attr_in1_input.attr, 3592c8dc071SDavid Brownell NULL, 3602c8dc071SDavid Brownell }; 3612c8dc071SDavid Brownell 3622c8dc071SDavid Brownell static struct attribute_group ads7843_attr_group = { 3632c8dc071SDavid Brownell .attrs = ads7843_attributes, 3642c8dc071SDavid Brownell }; 3652c8dc071SDavid Brownell 3662c8dc071SDavid Brownell static struct attribute *ads7845_attributes[] = { 3672c8dc071SDavid Brownell &dev_attr_in0_input.attr, 3682c8dc071SDavid Brownell NULL, 3692c8dc071SDavid Brownell }; 3702c8dc071SDavid Brownell 3712c8dc071SDavid Brownell static struct attribute_group ads7845_attr_group = { 3722c8dc071SDavid Brownell .attrs = ads7845_attributes, 3732c8dc071SDavid Brownell }; 3742c8dc071SDavid Brownell 3752c8dc071SDavid Brownell static int ads784x_hwmon_register(struct spi_device *spi, struct ads7846 *ts) 3762c8dc071SDavid Brownell { 3771beeffe4STony Jones struct device *hwmon; 3782c8dc071SDavid Brownell int err; 3792c8dc071SDavid Brownell 3802c8dc071SDavid Brownell /* hwmon sensors need a reference voltage */ 3812c8dc071SDavid Brownell switch (ts->model) { 3822c8dc071SDavid Brownell case 7846: 3837c6d0ee1SDavid Brownell if (!ts->vref_mv) { 3842c8dc071SDavid Brownell dev_dbg(&spi->dev, "assuming 2.5V internal vREF\n"); 3857c6d0ee1SDavid Brownell ts->vref_mv = 2500; 3862c8dc071SDavid Brownell } 3872c8dc071SDavid Brownell break; 3882c8dc071SDavid Brownell case 7845: 3892c8dc071SDavid Brownell case 7843: 3907c6d0ee1SDavid Brownell if (!ts->vref_mv) { 3912c8dc071SDavid Brownell dev_warn(&spi->dev, 3922c8dc071SDavid Brownell "external vREF for ADS%d not specified\n", 3932c8dc071SDavid Brownell ts->model); 3942c8dc071SDavid Brownell return 0; 3952c8dc071SDavid Brownell } 3962c8dc071SDavid Brownell break; 3972c8dc071SDavid Brownell } 3982c8dc071SDavid Brownell 3992c8dc071SDavid Brownell /* different chips have different sensor groups */ 4002c8dc071SDavid Brownell switch (ts->model) { 4012c8dc071SDavid Brownell case 7846: 4022c8dc071SDavid Brownell ts->attr_group = &ads7846_attr_group; 4032c8dc071SDavid Brownell break; 4042c8dc071SDavid Brownell case 7845: 4052c8dc071SDavid Brownell ts->attr_group = &ads7845_attr_group; 4062c8dc071SDavid Brownell break; 4072c8dc071SDavid Brownell case 7843: 4082c8dc071SDavid Brownell ts->attr_group = &ads7843_attr_group; 4092c8dc071SDavid Brownell break; 4102c8dc071SDavid Brownell default: 4112c8dc071SDavid Brownell dev_dbg(&spi->dev, "ADS%d not recognized\n", ts->model); 4122c8dc071SDavid Brownell return 0; 4132c8dc071SDavid Brownell } 4142c8dc071SDavid Brownell 4152c8dc071SDavid Brownell err = sysfs_create_group(&spi->dev.kobj, ts->attr_group); 4162c8dc071SDavid Brownell if (err) 4172c8dc071SDavid Brownell return err; 4182c8dc071SDavid Brownell 4192c8dc071SDavid Brownell hwmon = hwmon_device_register(&spi->dev); 4202c8dc071SDavid Brownell if (IS_ERR(hwmon)) { 4212c8dc071SDavid Brownell sysfs_remove_group(&spi->dev.kobj, ts->attr_group); 4222c8dc071SDavid Brownell return PTR_ERR(hwmon); 4232c8dc071SDavid Brownell } 4242c8dc071SDavid Brownell 4252c8dc071SDavid Brownell ts->hwmon = hwmon; 4262c8dc071SDavid Brownell return 0; 4272c8dc071SDavid Brownell } 4282c8dc071SDavid Brownell 4292c8dc071SDavid Brownell static void ads784x_hwmon_unregister(struct spi_device *spi, 4302c8dc071SDavid Brownell struct ads7846 *ts) 4312c8dc071SDavid Brownell { 4322c8dc071SDavid Brownell if (ts->hwmon) { 4332c8dc071SDavid Brownell sysfs_remove_group(&spi->dev.kobj, ts->attr_group); 4342c8dc071SDavid Brownell hwmon_device_unregister(ts->hwmon); 4352c8dc071SDavid Brownell } 4362c8dc071SDavid Brownell } 4372c8dc071SDavid Brownell 4382c8dc071SDavid Brownell #else 4392c8dc071SDavid Brownell static inline int ads784x_hwmon_register(struct spi_device *spi, 4402c8dc071SDavid Brownell struct ads7846 *ts) 4412c8dc071SDavid Brownell { 4422c8dc071SDavid Brownell return 0; 4432c8dc071SDavid Brownell } 4442c8dc071SDavid Brownell 4452c8dc071SDavid Brownell static inline void ads784x_hwmon_unregister(struct spi_device *spi, 4462c8dc071SDavid Brownell struct ads7846 *ts) 4472c8dc071SDavid Brownell { 4482c8dc071SDavid Brownell } 4492c8dc071SDavid Brownell #endif 450ffa458c1SDavid Brownell 451438f2a74SImre Deak static int is_pen_down(struct device *dev) 452438f2a74SImre Deak { 453438f2a74SImre Deak struct ads7846 *ts = dev_get_drvdata(dev); 454438f2a74SImre Deak 455438f2a74SImre Deak return ts->pendown; 456438f2a74SImre Deak } 457438f2a74SImre Deak 458438f2a74SImre Deak static ssize_t ads7846_pen_down_show(struct device *dev, 459438f2a74SImre Deak struct device_attribute *attr, char *buf) 460438f2a74SImre Deak { 461438f2a74SImre Deak return sprintf(buf, "%u\n", is_pen_down(dev)); 462438f2a74SImre Deak } 463438f2a74SImre Deak 464438f2a74SImre Deak static DEVICE_ATTR(pen_down, S_IRUGO, ads7846_pen_down_show, NULL); 465438f2a74SImre Deak 4667de90a8cSImre Deak static ssize_t ads7846_disable_show(struct device *dev, 4677de90a8cSImre Deak struct device_attribute *attr, char *buf) 4687de90a8cSImre Deak { 4697de90a8cSImre Deak struct ads7846 *ts = dev_get_drvdata(dev); 4707de90a8cSImre Deak 4717de90a8cSImre Deak return sprintf(buf, "%u\n", ts->disabled); 4727de90a8cSImre Deak } 4737de90a8cSImre Deak 4747de90a8cSImre Deak static ssize_t ads7846_disable_store(struct device *dev, 4757de90a8cSImre Deak struct device_attribute *attr, 4767de90a8cSImre Deak const char *buf, size_t count) 4777de90a8cSImre Deak { 4787de90a8cSImre Deak struct ads7846 *ts = dev_get_drvdata(dev); 4793a0c58ddSHarvey Harrison unsigned long i; 4807de90a8cSImre Deak 481160f1fefSJoe Rouvier if (strict_strtoul(buf, 10, &i)) 482160f1fefSJoe Rouvier return -EINVAL; 483160f1fefSJoe Rouvier 4847de90a8cSImre Deak spin_lock_irq(&ts->lock); 4857de90a8cSImre Deak 4867de90a8cSImre Deak if (i) 4877de90a8cSImre Deak ads7846_disable(ts); 4887de90a8cSImre Deak else 4897de90a8cSImre Deak ads7846_enable(ts); 4907de90a8cSImre Deak 4917de90a8cSImre Deak spin_unlock_irq(&ts->lock); 4927de90a8cSImre Deak 4937de90a8cSImre Deak return count; 4947de90a8cSImre Deak } 4957de90a8cSImre Deak 4967de90a8cSImre Deak static DEVICE_ATTR(disable, 0664, ads7846_disable_show, ads7846_disable_store); 4977de90a8cSImre Deak 4982c8dc071SDavid Brownell static struct attribute *ads784x_attributes[] = { 4998dd51650SDmitry Torokhov &dev_attr_pen_down.attr, 5008dd51650SDmitry Torokhov &dev_attr_disable.attr, 5018dd51650SDmitry Torokhov NULL, 5028dd51650SDmitry Torokhov }; 5038dd51650SDmitry Torokhov 5042c8dc071SDavid Brownell static struct attribute_group ads784x_attr_group = { 5052c8dc071SDavid Brownell .attrs = ads784x_attributes, 5068dd51650SDmitry Torokhov }; 5078dd51650SDmitry Torokhov 508ffa458c1SDavid Brownell /*--------------------------------------------------------------------------*/ 509ffa458c1SDavid Brownell 5104d5975e5SEric Miao static int get_pendown_state(struct ads7846 *ts) 5114d5975e5SEric Miao { 5124d5975e5SEric Miao if (ts->get_pendown_state) 5134d5975e5SEric Miao return ts->get_pendown_state(); 5144d5975e5SEric Miao 5154d5975e5SEric Miao return !gpio_get_value(ts->gpio_pendown); 5164d5975e5SEric Miao } 5174d5975e5SEric Miao 518fd746d54SEric Miao static void null_wait_for_sync(void) 519fd746d54SEric Miao { 520fd746d54SEric Miao } 521fd746d54SEric Miao 522ffa458c1SDavid Brownell /* 523ffa458c1SDavid Brownell * PENIRQ only kicks the timer. The timer only reissues the SPI transfer, 524ffa458c1SDavid Brownell * to retrieve touchscreen status. 525ffa458c1SDavid Brownell * 526ffa458c1SDavid Brownell * The SPI transfer completion callback does the real work. It reports 527ffa458c1SDavid Brownell * touchscreen events and reactivates the timer (or IRQ) as appropriate. 528ffa458c1SDavid Brownell */ 529ffa458c1SDavid Brownell 530ffa458c1SDavid Brownell static void ads7846_rx(void *ads) 531ffa458c1SDavid Brownell { 532ffa458c1SDavid Brownell struct ads7846 *ts = ads; 533e8f462d2SDmitry Torokhov struct ads7846_packet *packet = ts->packet; 534ffa458c1SDavid Brownell unsigned Rt; 535ffa458c1SDavid Brownell u16 x, y, z1, z2; 536ffa458c1SDavid Brownell 537da970e69SImre Deak /* ads7846_rx_val() did in-place conversion (including byteswap) from 538da970e69SImre Deak * on-the-wire format as part of debouncing to get stable readings. 539ffa458c1SDavid Brownell */ 540e8f462d2SDmitry Torokhov x = packet->tc.x; 541e8f462d2SDmitry Torokhov y = packet->tc.y; 542e8f462d2SDmitry Torokhov z1 = packet->tc.z1; 543e8f462d2SDmitry Torokhov z2 = packet->tc.z2; 544ffa458c1SDavid Brownell 545ffa458c1SDavid Brownell /* range filtering */ 546ffa458c1SDavid Brownell if (x == MAX_12BIT) 547ffa458c1SDavid Brownell x = 0; 548ffa458c1SDavid Brownell 5499460b652SHans-Christian Egtvedt if (ts->model == 7843) { 5509460b652SHans-Christian Egtvedt Rt = ts->pressure_max / 2; 5519460b652SHans-Christian Egtvedt } else if (likely(x && z1)) { 552ffa458c1SDavid Brownell /* compute touch pressure resistance using equation #2 */ 553ffa458c1SDavid Brownell Rt = z2; 554ffa458c1SDavid Brownell Rt -= z1; 555ffa458c1SDavid Brownell Rt *= x; 556ffa458c1SDavid Brownell Rt *= ts->x_plate_ohms; 557ffa458c1SDavid Brownell Rt /= z1; 558ffa458c1SDavid Brownell Rt = (Rt + 2047) >> 12; 5599460b652SHans-Christian Egtvedt } else { 560ffa458c1SDavid Brownell Rt = 0; 5619460b652SHans-Christian Egtvedt } 562969111e9SNicolas Ferre 563d5b415c9SImre Deak /* Sample found inconsistent by debouncing or pressure is beyond 564d5b415c9SImre Deak * the maximum. Don't report it to user space, repeat at least 5651936d590SImre Deak * once more the measurement 5661936d590SImre Deak */ 567e8f462d2SDmitry Torokhov if (packet->tc.ignore || Rt > ts->pressure_max) { 568*52ce4eaaSPavel Machek dev_vdbg(&ts->spi->dev, "ignored %d pressure %d\n", 569*52ce4eaaSPavel Machek packet->tc.ignore, Rt); 5701936d590SImre Deak hrtimer_start(&ts->timer, ktime_set(0, TS_POLL_PERIOD), 571c9cb2e3dSThomas Gleixner HRTIMER_MODE_REL); 572d5b415c9SImre Deak return; 573d5b415c9SImre Deak } 574d5b415c9SImre Deak 5751d25891fSSemih Hazar /* Maybe check the pendown state before reporting. This discards 5761d25891fSSemih Hazar * false readings when the pen is lifted. 5771d25891fSSemih Hazar */ 5781d25891fSSemih Hazar if (ts->penirq_recheck_delay_usecs) { 5791d25891fSSemih Hazar udelay(ts->penirq_recheck_delay_usecs); 5804d5975e5SEric Miao if (!get_pendown_state(ts)) 5811d25891fSSemih Hazar Rt = 0; 5821d25891fSSemih Hazar } 5831d25891fSSemih Hazar 58415e3589eSImre Deak /* NOTE: We can't rely on the pressure to determine the pen down 58515e3589eSImre Deak * state, even this controller has a pressure sensor. The pressure 58615e3589eSImre Deak * value can fluctuate for quite a while after lifting the pen and 58715e3589eSImre Deak * in some cases may not even settle at the expected value. 588ffa458c1SDavid Brownell * 58915e3589eSImre Deak * The only safe way to check for the pen up condition is in the 59015e3589eSImre Deak * timer by reading the pen signal state (it's a GPIO _and_ IRQ). 591ffa458c1SDavid Brownell */ 592ffa458c1SDavid Brownell if (Rt) { 59315e3589eSImre Deak struct input_dev *input = ts->input; 594ae82d5abSImre Deak 59515e3589eSImre Deak if (!ts->pendown) { 59615e3589eSImre Deak input_report_key(input, BTN_TOUCH, 1); 59715e3589eSImre Deak ts->pendown = 1; 598*52ce4eaaSPavel Machek dev_vdbg(&ts->spi->dev, "DOWN\n"); 59915e3589eSImre Deak } 60086579a4cSMichael Roth 60186579a4cSMichael Roth if (ts->swap_xy) 60286579a4cSMichael Roth swap(x, y); 60386579a4cSMichael Roth 60415e3589eSImre Deak input_report_abs(input, ABS_X, x); 60515e3589eSImre Deak input_report_abs(input, ABS_Y, y); 60630ad7ba0SPavel Machek input_report_abs(input, ABS_PRESSURE, ts->pressure_max - Rt); 607ffa458c1SDavid Brownell 60815e3589eSImre Deak input_sync(input); 609*52ce4eaaSPavel Machek dev_vdbg(&ts->spi->dev, "%4d/%4d/%4d\n", x, y, Rt); 61015e3589eSImre Deak } 611ffa458c1SDavid Brownell 612c9cb2e3dSThomas Gleixner hrtimer_start(&ts->timer, ktime_set(0, TS_POLL_PERIOD), 613c9cb2e3dSThomas Gleixner HRTIMER_MODE_REL); 614ffa458c1SDavid Brownell } 615ffa458c1SDavid Brownell 616da970e69SImre Deak static int ads7846_debounce(void *ads, int data_idx, int *val) 617ffa458c1SDavid Brownell { 6180b7018aaSImre Deak struct ads7846 *ts = ads; 619ffa458c1SDavid Brownell 620da970e69SImre Deak if (!ts->read_cnt || (abs(ts->last_read - *val) > ts->debounce_tol)) { 621da970e69SImre Deak /* Start over collecting consistent readings. */ 622da970e69SImre Deak ts->read_rep = 0; 623d5b415c9SImre Deak /* Repeat it, if this was the first read or the read 624d5b415c9SImre Deak * wasn't consistent enough. */ 625d5b415c9SImre Deak if (ts->read_cnt < ts->debounce_max) { 626da970e69SImre Deak ts->last_read = *val; 627d5b415c9SImre Deak ts->read_cnt++; 628da970e69SImre Deak return ADS7846_FILTER_REPEAT; 6290b7018aaSImre Deak } else { 630d5b415c9SImre Deak /* Maximum number of debouncing reached and still 631d5b415c9SImre Deak * not enough number of consistent readings. Abort 632d5b415c9SImre Deak * the whole sample, repeat it in the next sampling 633d5b415c9SImre Deak * period. 634d5b415c9SImre Deak */ 635d5b415c9SImre Deak ts->read_cnt = 0; 636da970e69SImre Deak return ADS7846_FILTER_IGNORE; 637d5b415c9SImre Deak } 638d5b415c9SImre Deak } else { 639d5b415c9SImre Deak if (++ts->read_rep > ts->debounce_rep) { 640d5b415c9SImre Deak /* Got a good reading for this coordinate, 641d5b415c9SImre Deak * go for the next one. */ 6420b7018aaSImre Deak ts->read_cnt = 0; 643d5b415c9SImre Deak ts->read_rep = 0; 644da970e69SImre Deak return ADS7846_FILTER_OK; 645da970e69SImre Deak } else { 646d5b415c9SImre Deak /* Read more values that are consistent. */ 647d5b415c9SImre Deak ts->read_cnt++; 648da970e69SImre Deak return ADS7846_FILTER_REPEAT; 649da970e69SImre Deak } 650da970e69SImre Deak } 651da970e69SImre Deak } 652da970e69SImre Deak 653da970e69SImre Deak static int ads7846_no_filter(void *ads, int data_idx, int *val) 654da970e69SImre Deak { 655da970e69SImre Deak return ADS7846_FILTER_OK; 656da970e69SImre Deak } 657da970e69SImre Deak 658da970e69SImre Deak static void ads7846_rx_val(void *ads) 659da970e69SImre Deak { 660da970e69SImre Deak struct ads7846 *ts = ads; 661e8f462d2SDmitry Torokhov struct ads7846_packet *packet = ts->packet; 662da970e69SImre Deak struct spi_message *m; 663da970e69SImre Deak struct spi_transfer *t; 664da970e69SImre Deak int val; 665da970e69SImre Deak int action; 666da970e69SImre Deak int status; 667da970e69SImre Deak 668da970e69SImre Deak m = &ts->msg[ts->msg_idx]; 669da970e69SImre Deak t = list_entry(m->transfers.prev, struct spi_transfer, transfer_list); 670da970e69SImre Deak 671da970e69SImre Deak /* adjust: on-wire is a must-ignore bit, a BE12 value, then padding; 672da970e69SImre Deak * built from two 8 bit values written msb-first. 673da970e69SImre Deak */ 674494f6857SHarvey Harrison val = be16_to_cpup((__be16 *)t->rx_buf) >> 3; 675da970e69SImre Deak 676da970e69SImre Deak action = ts->filter(ts->filter_data, ts->msg_idx, &val); 677da970e69SImre Deak switch (action) { 678da970e69SImre Deak case ADS7846_FILTER_REPEAT: 679da970e69SImre Deak break; 680da970e69SImre Deak case ADS7846_FILTER_IGNORE: 681e8f462d2SDmitry Torokhov packet->tc.ignore = 1; 682da970e69SImre Deak /* Last message will contain ads7846_rx() as the 683da970e69SImre Deak * completion function. 684da970e69SImre Deak */ 685da970e69SImre Deak m = ts->last_msg; 686da970e69SImre Deak break; 687da970e69SImre Deak case ADS7846_FILTER_OK: 688494f6857SHarvey Harrison *(u16 *)t->rx_buf = val; 689e8f462d2SDmitry Torokhov packet->tc.ignore = 0; 690da970e69SImre Deak m = &ts->msg[++ts->msg_idx]; 691da970e69SImre Deak break; 692da970e69SImre Deak default: 693da970e69SImre Deak BUG(); 694ffa458c1SDavid Brownell } 695fd746d54SEric Miao ts->wait_for_sync(); 6960b7018aaSImre Deak status = spi_async(ts->spi, m); 697ffa458c1SDavid Brownell if (status) 698ffa458c1SDavid Brownell dev_err(&ts->spi->dev, "spi_async --> %d\n", 699ffa458c1SDavid Brownell status); 700ffa458c1SDavid Brownell } 7010b7018aaSImre Deak 702c9cb2e3dSThomas Gleixner static enum hrtimer_restart ads7846_timer(struct hrtimer *handle) 7030b7018aaSImre Deak { 7041936d590SImre Deak struct ads7846 *ts = container_of(handle, struct ads7846, timer); 7050b7018aaSImre Deak int status = 0; 7060b7018aaSImre Deak 707ca109491SPeter Zijlstra spin_lock(&ts->lock); 708c9e617a5SImre Deak 7094d5975e5SEric Miao if (unlikely(!get_pendown_state(ts) || 71015e3589eSImre Deak device_suspended(&ts->spi->dev))) { 71115e3589eSImre Deak if (ts->pendown) { 71215e3589eSImre Deak struct input_dev *input = ts->input; 71315e3589eSImre Deak 71415e3589eSImre Deak input_report_key(input, BTN_TOUCH, 0); 71515e3589eSImre Deak input_report_abs(input, ABS_PRESSURE, 0); 71615e3589eSImre Deak input_sync(input); 71715e3589eSImre Deak 71815e3589eSImre Deak ts->pendown = 0; 719*52ce4eaaSPavel Machek dev_vdbg(&ts->spi->dev, "UP\n"); 72015e3589eSImre Deak } 72115e3589eSImre Deak 7229084533eSDavid Brownell /* measurement cycle ended */ 723c9e617a5SImre Deak if (!device_suspended(&ts->spi->dev)) { 724c9e617a5SImre Deak ts->irq_disabled = 0; 725c9e617a5SImre Deak enable_irq(ts->spi->irq); 726c9e617a5SImre Deak } 727c9e617a5SImre Deak ts->pending = 0; 728c9e617a5SImre Deak } else { 729c9e617a5SImre Deak /* pen is still down, continue with the measurement */ 7300b7018aaSImre Deak ts->msg_idx = 0; 731fd746d54SEric Miao ts->wait_for_sync(); 7320b7018aaSImre Deak status = spi_async(ts->spi, &ts->msg[0]); 7330b7018aaSImre Deak if (status) 7340b7018aaSImre Deak dev_err(&ts->spi->dev, "spi_async --> %d\n", status); 735ffa458c1SDavid Brownell } 736ffa458c1SDavid Brownell 737ca109491SPeter Zijlstra spin_unlock(&ts->lock); 7381936d590SImre Deak return HRTIMER_NORESTART; 739c9e617a5SImre Deak } 740c9e617a5SImre Deak 7417d12e780SDavid Howells static irqreturn_t ads7846_irq(int irq, void *handle) 742ffa458c1SDavid Brownell { 7430b7018aaSImre Deak struct ads7846 *ts = handle; 7440b7018aaSImre Deak unsigned long flags; 7450b7018aaSImre Deak 7460b7018aaSImre Deak spin_lock_irqsave(&ts->lock, flags); 7474d5975e5SEric Miao if (likely(get_pendown_state(ts))) { 7480b7018aaSImre Deak if (!ts->irq_disabled) { 7499084533eSDavid Brownell /* The ARM do_simple_IRQ() dispatcher doesn't act 7509084533eSDavid Brownell * like the other dispatchers: it will report IRQs 7519084533eSDavid Brownell * even after they've been disabled. We work around 7529084533eSDavid Brownell * that here. (The "generic irq" framework may help...) 7530b7018aaSImre Deak */ 7540b7018aaSImre Deak ts->irq_disabled = 1; 7553f3e7c6eSBen Nizette disable_irq_nosync(ts->spi->irq); 7560b7018aaSImre Deak ts->pending = 1; 7571936d590SImre Deak hrtimer_start(&ts->timer, ktime_set(0, TS_POLL_DELAY), 758c9cb2e3dSThomas Gleixner HRTIMER_MODE_REL); 7590b7018aaSImre Deak } 7600b7018aaSImre Deak } 7610b7018aaSImre Deak spin_unlock_irqrestore(&ts->lock, flags); 7627de90a8cSImre Deak 7637de90a8cSImre Deak return IRQ_HANDLED; 764ffa458c1SDavid Brownell } 765ffa458c1SDavid Brownell 766ffa458c1SDavid Brownell /*--------------------------------------------------------------------------*/ 767ffa458c1SDavid Brownell 7687de90a8cSImre Deak /* Must be called with ts->lock held */ 7697de90a8cSImre Deak static void ads7846_disable(struct ads7846 *ts) 770ffa458c1SDavid Brownell { 7717de90a8cSImre Deak if (ts->disabled) 7727de90a8cSImre Deak return; 773ffa458c1SDavid Brownell 774c9e617a5SImre Deak ts->disabled = 1; 775c9e617a5SImre Deak 776ffa458c1SDavid Brownell /* are we waiting for IRQ, or polling? */ 777c9e617a5SImre Deak if (!ts->pending) { 778ffa458c1SDavid Brownell ts->irq_disabled = 1; 779ffa458c1SDavid Brownell disable_irq(ts->spi->irq); 780ffa458c1SDavid Brownell } else { 781c9e617a5SImre Deak /* the timer will run at least once more, and 782c9e617a5SImre Deak * leave everything in a clean state, IRQ disabled 783ffa458c1SDavid Brownell */ 784c9e617a5SImre Deak while (ts->pending) { 7857de90a8cSImre Deak spin_unlock_irq(&ts->lock); 786c4febb94SJuha Yrjola msleep(1); 7877de90a8cSImre Deak spin_lock_irq(&ts->lock); 788ffa458c1SDavid Brownell } 789ffa458c1SDavid Brownell } 790ffa458c1SDavid Brownell 791ffa458c1SDavid Brownell /* we know the chip's in lowpower mode since we always 792ffa458c1SDavid Brownell * leave it that way after every request 793ffa458c1SDavid Brownell */ 7947de90a8cSImre Deak } 7957de90a8cSImre Deak 7967de90a8cSImre Deak /* Must be called with ts->lock held */ 7977de90a8cSImre Deak static void ads7846_enable(struct ads7846 *ts) 7987de90a8cSImre Deak { 7997de90a8cSImre Deak if (!ts->disabled) 8007de90a8cSImre Deak return; 8017de90a8cSImre Deak 8027de90a8cSImre Deak ts->disabled = 0; 8037de90a8cSImre Deak ts->irq_disabled = 0; 8047de90a8cSImre Deak enable_irq(ts->spi->irq); 8057de90a8cSImre Deak } 8067de90a8cSImre Deak 8077de90a8cSImre Deak static int ads7846_suspend(struct spi_device *spi, pm_message_t message) 8087de90a8cSImre Deak { 8097de90a8cSImre Deak struct ads7846 *ts = dev_get_drvdata(&spi->dev); 8107de90a8cSImre Deak 8117de90a8cSImre Deak spin_lock_irq(&ts->lock); 8127de90a8cSImre Deak 813fbb38e30SDavid Brownell ts->is_suspended = 1; 8147de90a8cSImre Deak ads7846_disable(ts); 8157de90a8cSImre Deak 8167de90a8cSImre Deak spin_unlock_irq(&ts->lock); 8177de90a8cSImre Deak 818ffa458c1SDavid Brownell return 0; 8197de90a8cSImre Deak 820ffa458c1SDavid Brownell } 821ffa458c1SDavid Brownell 8222e5a7bd9SDavid Brownell static int ads7846_resume(struct spi_device *spi) 823ffa458c1SDavid Brownell { 8242e5a7bd9SDavid Brownell struct ads7846 *ts = dev_get_drvdata(&spi->dev); 825ffa458c1SDavid Brownell 8267de90a8cSImre Deak spin_lock_irq(&ts->lock); 8277de90a8cSImre Deak 828fbb38e30SDavid Brownell ts->is_suspended = 0; 8297de90a8cSImre Deak ads7846_enable(ts); 8307de90a8cSImre Deak 8317de90a8cSImre Deak spin_unlock_irq(&ts->lock); 8327de90a8cSImre Deak 833ffa458c1SDavid Brownell return 0; 834ffa458c1SDavid Brownell } 835ffa458c1SDavid Brownell 8364d5975e5SEric Miao static int __devinit setup_pendown(struct spi_device *spi, struct ads7846 *ts) 8374d5975e5SEric Miao { 8384d5975e5SEric Miao struct ads7846_platform_data *pdata = spi->dev.platform_data; 8394d5975e5SEric Miao int err; 8404d5975e5SEric Miao 8414d5975e5SEric Miao /* REVISIT when the irq can be triggered active-low, or if for some 8424d5975e5SEric Miao * reason the touchscreen isn't hooked up, we don't need to access 8434d5975e5SEric Miao * the pendown state. 8444d5975e5SEric Miao */ 8454d5975e5SEric Miao if (!pdata->get_pendown_state && !gpio_is_valid(pdata->gpio_pendown)) { 8464d5975e5SEric Miao dev_err(&spi->dev, "no get_pendown_state nor gpio_pendown?\n"); 8474d5975e5SEric Miao return -EINVAL; 8484d5975e5SEric Miao } 8494d5975e5SEric Miao 8504d5975e5SEric Miao if (pdata->get_pendown_state) { 8514d5975e5SEric Miao ts->get_pendown_state = pdata->get_pendown_state; 8524d5975e5SEric Miao return 0; 8534d5975e5SEric Miao } 8544d5975e5SEric Miao 8554d5975e5SEric Miao err = gpio_request(pdata->gpio_pendown, "ads7846_pendown"); 8564d5975e5SEric Miao if (err) { 8574d5975e5SEric Miao dev_err(&spi->dev, "failed to request pendown GPIO%d\n", 8584d5975e5SEric Miao pdata->gpio_pendown); 8594d5975e5SEric Miao return err; 8604d5975e5SEric Miao } 8614d5975e5SEric Miao 8624d5975e5SEric Miao ts->gpio_pendown = pdata->gpio_pendown; 8634d5975e5SEric Miao return 0; 8644d5975e5SEric Miao } 8654d5975e5SEric Miao 8662e5a7bd9SDavid Brownell static int __devinit ads7846_probe(struct spi_device *spi) 867ffa458c1SDavid Brownell { 868ffa458c1SDavid Brownell struct ads7846 *ts; 869e8f462d2SDmitry Torokhov struct ads7846_packet *packet; 870a90f7e98SDmitry Torokhov struct input_dev *input_dev; 8712e5a7bd9SDavid Brownell struct ads7846_platform_data *pdata = spi->dev.platform_data; 8720b7018aaSImre Deak struct spi_message *m; 873ffa458c1SDavid Brownell struct spi_transfer *x; 874de2defd9SImre Deak int vref; 875a90f7e98SDmitry Torokhov int err; 876ffa458c1SDavid Brownell 877ffa458c1SDavid Brownell if (!spi->irq) { 8782e5a7bd9SDavid Brownell dev_dbg(&spi->dev, "no IRQ?\n"); 879ffa458c1SDavid Brownell return -ENODEV; 880ffa458c1SDavid Brownell } 881ffa458c1SDavid Brownell 882ffa458c1SDavid Brownell if (!pdata) { 8832e5a7bd9SDavid Brownell dev_dbg(&spi->dev, "no platform data?\n"); 884ffa458c1SDavid Brownell return -ENODEV; 885ffa458c1SDavid Brownell } 886ffa458c1SDavid Brownell 887ffa458c1SDavid Brownell /* don't exceed max specified sample rate */ 888d93f70b2SDavid Brownell if (spi->max_speed_hz > (125000 * SAMPLE_BITS)) { 8892e5a7bd9SDavid Brownell dev_dbg(&spi->dev, "f(sample) %d KHz?\n", 890d93f70b2SDavid Brownell (spi->max_speed_hz/SAMPLE_BITS)/1000); 891ffa458c1SDavid Brownell return -EINVAL; 892ffa458c1SDavid Brownell } 893ffa458c1SDavid Brownell 8949084533eSDavid Brownell /* We'd set TX wordsize 8 bits and RX wordsize to 13 bits ... except 8959084533eSDavid Brownell * that even if the hardware can do that, the SPI controller driver 8969084533eSDavid Brownell * may not. So we stick to very-portable 8 bit words, both RX and TX. 897ffa458c1SDavid Brownell */ 8989084533eSDavid Brownell spi->bits_per_word = 8; 899230ffc8eSSemih Hazar spi->mode = SPI_MODE_0; 9007937e86aSImre Deak err = spi_setup(spi); 9017937e86aSImre Deak if (err < 0) 9027937e86aSImre Deak return err; 903ffa458c1SDavid Brownell 904a90f7e98SDmitry Torokhov ts = kzalloc(sizeof(struct ads7846), GFP_KERNEL); 905e8f462d2SDmitry Torokhov packet = kzalloc(sizeof(struct ads7846_packet), GFP_KERNEL); 906a90f7e98SDmitry Torokhov input_dev = input_allocate_device(); 907e8f462d2SDmitry Torokhov if (!ts || !packet || !input_dev) { 908a90f7e98SDmitry Torokhov err = -ENOMEM; 909a90f7e98SDmitry Torokhov goto err_free_mem; 910a90f7e98SDmitry Torokhov } 911ffa458c1SDavid Brownell 9122e5a7bd9SDavid Brownell dev_set_drvdata(&spi->dev, ts); 913ffa458c1SDavid Brownell 914e8f462d2SDmitry Torokhov ts->packet = packet; 915ffa458c1SDavid Brownell ts->spi = spi; 916a90f7e98SDmitry Torokhov ts->input = input_dev; 9177c6d0ee1SDavid Brownell ts->vref_mv = pdata->vref_mv; 91886579a4cSMichael Roth ts->swap_xy = pdata->swap_xy; 919ffa458c1SDavid Brownell 920c9cb2e3dSThomas Gleixner hrtimer_init(&ts->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); 921ffa458c1SDavid Brownell ts->timer.function = ads7846_timer; 922ffa458c1SDavid Brownell 9237de90a8cSImre Deak spin_lock_init(&ts->lock); 9247de90a8cSImre Deak 925ffa458c1SDavid Brownell ts->model = pdata->model ? : 7846; 926ffa458c1SDavid Brownell ts->vref_delay_usecs = pdata->vref_delay_usecs ? : 100; 927ffa458c1SDavid Brownell ts->x_plate_ohms = pdata->x_plate_ohms ? : 400; 928d5b415c9SImre Deak ts->pressure_max = pdata->pressure_max ? : ~0; 929da970e69SImre Deak 930da970e69SImre Deak if (pdata->filter != NULL) { 931da970e69SImre Deak if (pdata->filter_init != NULL) { 932da970e69SImre Deak err = pdata->filter_init(pdata, &ts->filter_data); 933da970e69SImre Deak if (err < 0) 934da970e69SImre Deak goto err_free_mem; 935da970e69SImre Deak } 936da970e69SImre Deak ts->filter = pdata->filter; 937da970e69SImre Deak ts->filter_cleanup = pdata->filter_cleanup; 938da970e69SImre Deak } else if (pdata->debounce_max) { 939d5b415c9SImre Deak ts->debounce_max = pdata->debounce_max; 940da970e69SImre Deak if (ts->debounce_max < 2) 941da970e69SImre Deak ts->debounce_max = 2; 942d5b415c9SImre Deak ts->debounce_tol = pdata->debounce_tol; 943d5b415c9SImre Deak ts->debounce_rep = pdata->debounce_rep; 944da970e69SImre Deak ts->filter = ads7846_debounce; 945da970e69SImre Deak ts->filter_data = ts; 946d5b415c9SImre Deak } else 947da970e69SImre Deak ts->filter = ads7846_no_filter; 9484d5975e5SEric Miao 9494d5975e5SEric Miao err = setup_pendown(spi, ts); 9504d5975e5SEric Miao if (err) 9514d5975e5SEric Miao goto err_cleanup_filter; 952ffa458c1SDavid Brownell 9531d25891fSSemih Hazar if (pdata->penirq_recheck_delay_usecs) 9541d25891fSSemih Hazar ts->penirq_recheck_delay_usecs = 9551d25891fSSemih Hazar pdata->penirq_recheck_delay_usecs; 9561d25891fSSemih Hazar 957fd746d54SEric Miao ts->wait_for_sync = pdata->wait_for_sync ? : null_wait_for_sync; 958fd746d54SEric Miao 959a6c2490fSKay Sievers snprintf(ts->phys, sizeof(ts->phys), "%s/input0", dev_name(&spi->dev)); 960b58895f8SMichael Roth snprintf(ts->name, sizeof(ts->name), "ADS%d Touchscreen", ts->model); 961ffa458c1SDavid Brownell 962b58895f8SMichael Roth input_dev->name = ts->name; 963a90f7e98SDmitry Torokhov input_dev->phys = ts->phys; 964a5394fb0SDmitry Torokhov input_dev->dev.parent = &spi->dev; 965ffa458c1SDavid Brownell 9667b19ada2SJiri Slaby input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); 9677b19ada2SJiri Slaby input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); 968a90f7e98SDmitry Torokhov input_set_abs_params(input_dev, ABS_X, 969ffa458c1SDavid Brownell pdata->x_min ? : 0, 970ffa458c1SDavid Brownell pdata->x_max ? : MAX_12BIT, 971ffa458c1SDavid Brownell 0, 0); 972a90f7e98SDmitry Torokhov input_set_abs_params(input_dev, ABS_Y, 973ffa458c1SDavid Brownell pdata->y_min ? : 0, 974ffa458c1SDavid Brownell pdata->y_max ? : MAX_12BIT, 975ffa458c1SDavid Brownell 0, 0); 976a90f7e98SDmitry Torokhov input_set_abs_params(input_dev, ABS_PRESSURE, 977ffa458c1SDavid Brownell pdata->pressure_min, pdata->pressure_max, 0, 0); 978ffa458c1SDavid Brownell 979de2defd9SImre Deak vref = pdata->keep_vref_on; 980de2defd9SImre Deak 981ffa458c1SDavid Brownell /* set up the transfers to read touchscreen state; this assumes we 982ffa458c1SDavid Brownell * use formula #2 for pressure, not #3. 983ffa458c1SDavid Brownell */ 9840b7018aaSImre Deak m = &ts->msg[0]; 985ffa458c1SDavid Brownell x = ts->xfer; 986ffa458c1SDavid Brownell 9870b7018aaSImre Deak spi_message_init(m); 9880b7018aaSImre Deak 989ffa458c1SDavid Brownell /* y- still on; turn on only y+ (and ADC) */ 990e8f462d2SDmitry Torokhov packet->read_y = READ_Y(vref); 991e8f462d2SDmitry Torokhov x->tx_buf = &packet->read_y; 992ffa458c1SDavid Brownell x->len = 1; 9930b7018aaSImre Deak spi_message_add_tail(x, m); 994d93f70b2SDavid Brownell 995ffa458c1SDavid Brownell x++; 996e8f462d2SDmitry Torokhov x->rx_buf = &packet->tc.y; 997ffa458c1SDavid Brownell x->len = 2; 9980b7018aaSImre Deak spi_message_add_tail(x, m); 999ffa458c1SDavid Brownell 1000e4f48861SSemih Hazar /* the first sample after switching drivers can be low quality; 1001e4f48861SSemih Hazar * optionally discard it, using a second one after the signals 1002e4f48861SSemih Hazar * have had enough time to stabilize. 1003e4f48861SSemih Hazar */ 1004e4f48861SSemih Hazar if (pdata->settle_delay_usecs) { 1005e4f48861SSemih Hazar x->delay_usecs = pdata->settle_delay_usecs; 1006e4f48861SSemih Hazar 1007e4f48861SSemih Hazar x++; 1008e8f462d2SDmitry Torokhov x->tx_buf = &packet->read_y; 1009e4f48861SSemih Hazar x->len = 1; 1010e4f48861SSemih Hazar spi_message_add_tail(x, m); 1011e4f48861SSemih Hazar 1012e4f48861SSemih Hazar x++; 1013e8f462d2SDmitry Torokhov x->rx_buf = &packet->tc.y; 1014e4f48861SSemih Hazar x->len = 2; 1015e4f48861SSemih Hazar spi_message_add_tail(x, m); 1016e4f48861SSemih Hazar } 1017e4f48861SSemih Hazar 1018da970e69SImre Deak m->complete = ads7846_rx_val; 10190b7018aaSImre Deak m->context = ts; 1020d93f70b2SDavid Brownell 10210b7018aaSImre Deak m++; 10220b7018aaSImre Deak spi_message_init(m); 1023ffa458c1SDavid Brownell 1024ffa458c1SDavid Brownell /* turn y- off, x+ on, then leave in lowpower */ 1025d93f70b2SDavid Brownell x++; 1026e8f462d2SDmitry Torokhov packet->read_x = READ_X(vref); 1027e8f462d2SDmitry Torokhov x->tx_buf = &packet->read_x; 1028ffa458c1SDavid Brownell x->len = 1; 10290b7018aaSImre Deak spi_message_add_tail(x, m); 1030d93f70b2SDavid Brownell 1031ffa458c1SDavid Brownell x++; 1032e8f462d2SDmitry Torokhov x->rx_buf = &packet->tc.x; 1033ffa458c1SDavid Brownell x->len = 2; 10340b7018aaSImre Deak spi_message_add_tail(x, m); 10350b7018aaSImre Deak 1036e4f48861SSemih Hazar /* ... maybe discard first sample ... */ 1037e4f48861SSemih Hazar if (pdata->settle_delay_usecs) { 1038e4f48861SSemih Hazar x->delay_usecs = pdata->settle_delay_usecs; 1039e4f48861SSemih Hazar 1040e4f48861SSemih Hazar x++; 1041e8f462d2SDmitry Torokhov x->tx_buf = &packet->read_x; 1042e4f48861SSemih Hazar x->len = 1; 1043e4f48861SSemih Hazar spi_message_add_tail(x, m); 1044e4f48861SSemih Hazar 1045e4f48861SSemih Hazar x++; 1046e8f462d2SDmitry Torokhov x->rx_buf = &packet->tc.x; 1047e4f48861SSemih Hazar x->len = 2; 1048e4f48861SSemih Hazar spi_message_add_tail(x, m); 1049e4f48861SSemih Hazar } 1050e4f48861SSemih Hazar 1051da970e69SImre Deak m->complete = ads7846_rx_val; 10520b7018aaSImre Deak m->context = ts; 10530b7018aaSImre Deak 10540b7018aaSImre Deak /* turn y+ off, x- on; we'll use formula #2 */ 10550b7018aaSImre Deak if (ts->model == 7846) { 10560b7018aaSImre Deak m++; 10570b7018aaSImre Deak spi_message_init(m); 10580b7018aaSImre Deak 10590b7018aaSImre Deak x++; 1060e8f462d2SDmitry Torokhov packet->read_z1 = READ_Z1(vref); 1061e8f462d2SDmitry Torokhov x->tx_buf = &packet->read_z1; 10620b7018aaSImre Deak x->len = 1; 10630b7018aaSImre Deak spi_message_add_tail(x, m); 10640b7018aaSImre Deak 10650b7018aaSImre Deak x++; 1066e8f462d2SDmitry Torokhov x->rx_buf = &packet->tc.z1; 10670b7018aaSImre Deak x->len = 2; 10680b7018aaSImre Deak spi_message_add_tail(x, m); 10690b7018aaSImre Deak 1070e4f48861SSemih Hazar /* ... maybe discard first sample ... */ 1071e4f48861SSemih Hazar if (pdata->settle_delay_usecs) { 1072e4f48861SSemih Hazar x->delay_usecs = pdata->settle_delay_usecs; 1073e4f48861SSemih Hazar 1074e4f48861SSemih Hazar x++; 1075e8f462d2SDmitry Torokhov x->tx_buf = &packet->read_z1; 1076e4f48861SSemih Hazar x->len = 1; 1077e4f48861SSemih Hazar spi_message_add_tail(x, m); 1078e4f48861SSemih Hazar 1079e4f48861SSemih Hazar x++; 1080e8f462d2SDmitry Torokhov x->rx_buf = &packet->tc.z1; 1081e4f48861SSemih Hazar x->len = 2; 1082e4f48861SSemih Hazar spi_message_add_tail(x, m); 1083e4f48861SSemih Hazar } 1084e4f48861SSemih Hazar 1085da970e69SImre Deak m->complete = ads7846_rx_val; 10860b7018aaSImre Deak m->context = ts; 10870b7018aaSImre Deak 10880b7018aaSImre Deak m++; 10890b7018aaSImre Deak spi_message_init(m); 10900b7018aaSImre Deak 10910b7018aaSImre Deak x++; 1092e8f462d2SDmitry Torokhov packet->read_z2 = READ_Z2(vref); 1093e8f462d2SDmitry Torokhov x->tx_buf = &packet->read_z2; 10940b7018aaSImre Deak x->len = 1; 10950b7018aaSImre Deak spi_message_add_tail(x, m); 10960b7018aaSImre Deak 10970b7018aaSImre Deak x++; 1098e8f462d2SDmitry Torokhov x->rx_buf = &packet->tc.z2; 10990b7018aaSImre Deak x->len = 2; 11000b7018aaSImre Deak spi_message_add_tail(x, m); 11010b7018aaSImre Deak 1102e4f48861SSemih Hazar /* ... maybe discard first sample ... */ 1103e4f48861SSemih Hazar if (pdata->settle_delay_usecs) { 1104e4f48861SSemih Hazar x->delay_usecs = pdata->settle_delay_usecs; 1105e4f48861SSemih Hazar 1106e4f48861SSemih Hazar x++; 1107e8f462d2SDmitry Torokhov x->tx_buf = &packet->read_z2; 1108e4f48861SSemih Hazar x->len = 1; 1109e4f48861SSemih Hazar spi_message_add_tail(x, m); 1110e4f48861SSemih Hazar 1111e4f48861SSemih Hazar x++; 1112e8f462d2SDmitry Torokhov x->rx_buf = &packet->tc.z2; 1113e4f48861SSemih Hazar x->len = 2; 1114e4f48861SSemih Hazar spi_message_add_tail(x, m); 1115e4f48861SSemih Hazar } 1116e4f48861SSemih Hazar 1117da970e69SImre Deak m->complete = ads7846_rx_val; 11180b7018aaSImre Deak m->context = ts; 11190b7018aaSImre Deak } 112053a0ef89SImre Deak 112153a0ef89SImre Deak /* power down */ 11220b7018aaSImre Deak m++; 11230b7018aaSImre Deak spi_message_init(m); 11240b7018aaSImre Deak 112553a0ef89SImre Deak x++; 1126e8f462d2SDmitry Torokhov packet->pwrdown = PWRDOWN; 1127e8f462d2SDmitry Torokhov x->tx_buf = &packet->pwrdown; 112853a0ef89SImre Deak x->len = 1; 11290b7018aaSImre Deak spi_message_add_tail(x, m); 113053a0ef89SImre Deak 113153a0ef89SImre Deak x++; 1132e8f462d2SDmitry Torokhov x->rx_buf = &packet->dummy; 113353a0ef89SImre Deak x->len = 2; 1134d93f70b2SDavid Brownell CS_CHANGE(*x); 11350b7018aaSImre Deak spi_message_add_tail(x, m); 1136ffa458c1SDavid Brownell 11370b7018aaSImre Deak m->complete = ads7846_rx; 11380b7018aaSImre Deak m->context = ts; 1139ffa458c1SDavid Brownell 1140d5b415c9SImre Deak ts->last_msg = m; 1141d5b415c9SImre Deak 1142dace1453SThomas Gleixner if (request_irq(spi->irq, ads7846_irq, IRQF_TRIGGER_FALLING, 11439084533eSDavid Brownell spi->dev.driver->name, ts)) { 1144c57c0a2aSMichael Roth dev_info(&spi->dev, 1145c57c0a2aSMichael Roth "trying pin change workaround on irq %d\n", spi->irq); 1146c57c0a2aSMichael Roth err = request_irq(spi->irq, ads7846_irq, 1147c57c0a2aSMichael Roth IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, 1148c57c0a2aSMichael Roth spi->dev.driver->name, ts); 1149c57c0a2aSMichael Roth if (err) { 11502e5a7bd9SDavid Brownell dev_dbg(&spi->dev, "irq %d busy?\n", spi->irq); 11514d5975e5SEric Miao goto err_free_gpio; 1152ffa458c1SDavid Brownell } 1153c57c0a2aSMichael Roth } 1154ffa458c1SDavid Brownell 11552c8dc071SDavid Brownell err = ads784x_hwmon_register(spi, ts); 11562c8dc071SDavid Brownell if (err) 11572c8dc071SDavid Brownell goto err_free_irq; 11582c8dc071SDavid Brownell 11592e5a7bd9SDavid Brownell dev_info(&spi->dev, "touchscreen, irq %d\n", spi->irq); 1160ffa458c1SDavid Brownell 11612c8dc071SDavid Brownell /* take a first sample, leaving nPENIRQ active and vREF off; avoid 1162ffa458c1SDavid Brownell * the touchscreen, in case it's not connected. 1163ffa458c1SDavid Brownell */ 11642e5a7bd9SDavid Brownell (void) ads7846_read12_ser(&spi->dev, 1165ffa458c1SDavid Brownell READ_12BIT_SER(vaux) | ADS_PD10_ALL_ON); 1166ffa458c1SDavid Brownell 11672c8dc071SDavid Brownell err = sysfs_create_group(&spi->dev.kobj, &ads784x_attr_group); 11688dd51650SDmitry Torokhov if (err) 11692c8dc071SDavid Brownell goto err_remove_hwmon; 11707de90a8cSImre Deak 1171a90f7e98SDmitry Torokhov err = input_register_device(input_dev); 1172a90f7e98SDmitry Torokhov if (err) 11738dd51650SDmitry Torokhov goto err_remove_attr_group; 1174a90f7e98SDmitry Torokhov 1175ffa458c1SDavid Brownell return 0; 1176a90f7e98SDmitry Torokhov 11778dd51650SDmitry Torokhov err_remove_attr_group: 11782c8dc071SDavid Brownell sysfs_remove_group(&spi->dev.kobj, &ads784x_attr_group); 11792c8dc071SDavid Brownell err_remove_hwmon: 11802c8dc071SDavid Brownell ads784x_hwmon_unregister(spi, ts); 11818dd51650SDmitry Torokhov err_free_irq: 1182a90f7e98SDmitry Torokhov free_irq(spi->irq, ts); 11834d5975e5SEric Miao err_free_gpio: 11844d5975e5SEric Miao if (ts->gpio_pendown != -1) 11854d5975e5SEric Miao gpio_free(ts->gpio_pendown); 1186da970e69SImre Deak err_cleanup_filter: 1187da970e69SImre Deak if (ts->filter_cleanup) 1188da970e69SImre Deak ts->filter_cleanup(ts->filter_data); 1189a90f7e98SDmitry Torokhov err_free_mem: 1190a90f7e98SDmitry Torokhov input_free_device(input_dev); 1191e8f462d2SDmitry Torokhov kfree(packet); 1192a90f7e98SDmitry Torokhov kfree(ts); 1193a90f7e98SDmitry Torokhov return err; 1194ffa458c1SDavid Brownell } 1195ffa458c1SDavid Brownell 11962e5a7bd9SDavid Brownell static int __devexit ads7846_remove(struct spi_device *spi) 1197ffa458c1SDavid Brownell { 11982e5a7bd9SDavid Brownell struct ads7846 *ts = dev_get_drvdata(&spi->dev); 1199ffa458c1SDavid Brownell 12002c8dc071SDavid Brownell ads784x_hwmon_unregister(spi, ts); 12017de90a8cSImre Deak input_unregister_device(ts->input); 12027de90a8cSImre Deak 12032e5a7bd9SDavid Brownell ads7846_suspend(spi, PMSG_SUSPEND); 1204ffa458c1SDavid Brownell 12052c8dc071SDavid Brownell sysfs_remove_group(&spi->dev.kobj, &ads784x_attr_group); 1206ffa458c1SDavid Brownell 12077de90a8cSImre Deak free_irq(ts->spi->irq, ts); 1208c9e617a5SImre Deak /* suspend left the IRQ disabled */ 12097de90a8cSImre Deak enable_irq(ts->spi->irq); 12107de90a8cSImre Deak 12114d5975e5SEric Miao if (ts->gpio_pendown != -1) 12124d5975e5SEric Miao gpio_free(ts->gpio_pendown); 12134d5975e5SEric Miao 1214da970e69SImre Deak if (ts->filter_cleanup) 1215da970e69SImre Deak ts->filter_cleanup(ts->filter_data); 1216da970e69SImre Deak 1217e8f462d2SDmitry Torokhov kfree(ts->packet); 1218ffa458c1SDavid Brownell kfree(ts); 1219ffa458c1SDavid Brownell 12202e5a7bd9SDavid Brownell dev_dbg(&spi->dev, "unregistered touchscreen\n"); 1221ffa458c1SDavid Brownell return 0; 1222ffa458c1SDavid Brownell } 1223ffa458c1SDavid Brownell 12242e5a7bd9SDavid Brownell static struct spi_driver ads7846_driver = { 12252e5a7bd9SDavid Brownell .driver = { 1226ffa458c1SDavid Brownell .name = "ads7846", 1227ffa458c1SDavid Brownell .bus = &spi_bus_type, 12282e5a7bd9SDavid Brownell .owner = THIS_MODULE, 12292e5a7bd9SDavid Brownell }, 1230ffa458c1SDavid Brownell .probe = ads7846_probe, 12312e5a7bd9SDavid Brownell .remove = __devexit_p(ads7846_remove), 1232ffa458c1SDavid Brownell .suspend = ads7846_suspend, 1233ffa458c1SDavid Brownell .resume = ads7846_resume, 1234ffa458c1SDavid Brownell }; 1235ffa458c1SDavid Brownell 1236ffa458c1SDavid Brownell static int __init ads7846_init(void) 1237ffa458c1SDavid Brownell { 12382e5a7bd9SDavid Brownell return spi_register_driver(&ads7846_driver); 1239ffa458c1SDavid Brownell } 1240ffa458c1SDavid Brownell module_init(ads7846_init); 1241ffa458c1SDavid Brownell 1242ffa458c1SDavid Brownell static void __exit ads7846_exit(void) 1243ffa458c1SDavid Brownell { 12442e5a7bd9SDavid Brownell spi_unregister_driver(&ads7846_driver); 1245ffa458c1SDavid Brownell } 1246ffa458c1SDavid Brownell module_exit(ads7846_exit); 1247ffa458c1SDavid Brownell 1248ffa458c1SDavid Brownell MODULE_DESCRIPTION("ADS7846 TouchScreen Driver"); 1249ffa458c1SDavid Brownell MODULE_LICENSE("GPL"); 1250e0626e38SAnton Vorontsov MODULE_ALIAS("spi:ads7846"); 1251