1dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown/* 2dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown * wm9713.c -- Codec touch driver for Wolfson WM9713 AC97 Codec. 3dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown * 4dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown * Copyright 2003, 2004, 2005, 2006, 2007, 2008 Wolfson Microelectronics PLC. 5b8d055a878ee0f997ded40649701089d2486f850Liam Girdwood * Author: Liam Girdwood <lrg@slimlogic.co.uk> 6dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown * Parts Copyright : Ian Molton <spyro@f2s.com> 7dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown * Andrew Zabolotny <zap@homelink.ru> 8dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown * Russell King <rmk@arm.linux.org.uk> 9dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown * 10dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown * This program is free software; you can redistribute it and/or modify it 11dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown * under the terms of the GNU General Public License as published by the 12dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown * Free Software Foundation; either version 2 of the License, or (at your 13dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown * option) any later version. 14dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown * 15dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown */ 16dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown 17dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown#include <linux/module.h> 18dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown#include <linux/moduleparam.h> 19dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown#include <linux/kernel.h> 20dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown#include <linux/input.h> 21dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown#include <linux/delay.h> 22dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown#include <linux/bitops.h> 23dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown#include <linux/wm97xx.h> 24dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown 25dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown#define TS_NAME "wm97xx" 26dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown#define WM9713_VERSION "1.00" 27dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown#define DEFAULT_PRESSURE 0xb0c0 28dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown 29dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown/* 30dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown * Module parameters 31dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown */ 32dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown 33dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown/* 34dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown * Set internal pull up for pen detect. 35dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown * 36dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown * Pull up is in the range 1.02k (least sensitive) to 64k (most sensitive) 37dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown * i.e. pull up resistance = 64k Ohms / rpu. 38dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown * 39dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown * Adjust this value if you are having problems with pen detect not 40dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown * detecting any down event. 41dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown */ 42dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brownstatic int rpu = 8; 43dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brownmodule_param(rpu, int, 0); 44dca98e91fb83a43fc430893f349fd8248fa0ba38Mark BrownMODULE_PARM_DESC(rpu, "Set internal pull up resitor for pen detect."); 45dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown 46dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown/* 47dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown * Set current used for pressure measurement. 48dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown * 49dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown * Set pil = 2 to use 400uA 50dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown * pil = 1 to use 200uA and 51dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown * pil = 0 to disable pressure measurement. 52dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown * 53dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown * This is used to increase the range of values returned by the adc 54dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown * when measureing touchpanel pressure. 55dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown */ 56dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brownstatic int pil; 57dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brownmodule_param(pil, int, 0); 58dca98e91fb83a43fc430893f349fd8248fa0ba38Mark BrownMODULE_PARM_DESC(pil, "Set current used for pressure measurement."); 59dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown 60dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown/* 61dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown * Set threshold for pressure measurement. 62dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown * 63dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown * Pen down pressure below threshold is ignored. 64dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown */ 65dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brownstatic int pressure = DEFAULT_PRESSURE & 0xfff; 66dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brownmodule_param(pressure, int, 0); 67dca98e91fb83a43fc430893f349fd8248fa0ba38Mark BrownMODULE_PARM_DESC(pressure, "Set threshold for pressure measurement."); 68dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown 69dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown/* 70dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown * Set adc sample delay. 71dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown * 72dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown * For accurate touchpanel measurements, some settling time may be 73dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown * required between the switch matrix applying a voltage across the 74dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown * touchpanel plate and the ADC sampling the signal. 75dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown * 76dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown * This delay can be set by setting delay = n, where n is the array 77dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown * position of the delay in the array delay_table below. 78dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown * Long delays > 1ms are supported for completeness, but are not 79dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown * recommended. 80dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown */ 81dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brownstatic int delay = 4; 82dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brownmodule_param(delay, int, 0); 83dca98e91fb83a43fc430893f349fd8248fa0ba38Mark BrownMODULE_PARM_DESC(delay, "Set adc sample delay."); 84dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown 85dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown/* 8643f83a8f9963a11a9c3f41beecc363da21ae3602Mark Brown * Set five_wire = 1 to use a 5 wire touchscreen. 8743f83a8f9963a11a9c3f41beecc363da21ae3602Mark Brown * 8843f83a8f9963a11a9c3f41beecc363da21ae3602Mark Brown * NOTE: Five wire mode does not allow for readback of pressure. 8943f83a8f9963a11a9c3f41beecc363da21ae3602Mark Brown */ 9043f83a8f9963a11a9c3f41beecc363da21ae3602Mark Brownstatic int five_wire; 9143f83a8f9963a11a9c3f41beecc363da21ae3602Mark Brownmodule_param(five_wire, int, 0); 9243f83a8f9963a11a9c3f41beecc363da21ae3602Mark BrownMODULE_PARM_DESC(five_wire, "Set to '1' to use 5-wire touchscreen."); 9343f83a8f9963a11a9c3f41beecc363da21ae3602Mark Brown 9443f83a8f9963a11a9c3f41beecc363da21ae3602Mark Brown/* 95dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown * Set adc mask function. 96dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown * 97dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown * Sources of glitch noise, such as signals driving an LCD display, may feed 98dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown * through to the touch screen plates and affect measurement accuracy. In 99dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown * order to minimise this, a signal may be applied to the MASK pin to delay or 100dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown * synchronise the sampling. 101dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown * 102dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown * 0 = No delay or sync 103dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown * 1 = High on pin stops conversions 104dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown * 2 = Edge triggered, edge on pin delays conversion by delay param (above) 105dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown * 3 = Edge triggered, edge on pin starts conversion after delay param 106dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown */ 107dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brownstatic int mask; 108dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brownmodule_param(mask, int, 0); 109dca98e91fb83a43fc430893f349fd8248fa0ba38Mark BrownMODULE_PARM_DESC(mask, "Set adc mask function."); 110dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown 111dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown/* 112dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown * Coordinate Polling Enable. 113dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown * 114dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown * Set to 1 to enable coordinate polling. e.g. x,y[,p] is sampled together 115dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown * for every poll. 116dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown */ 117dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brownstatic int coord; 118dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brownmodule_param(coord, int, 0); 119dca98e91fb83a43fc430893f349fd8248fa0ba38Mark BrownMODULE_PARM_DESC(coord, "Polling coordinate mode"); 120dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown 121dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown/* 122dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown * ADC sample delay times in uS 123dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown */ 124dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brownstatic const int delay_table[] = { 125dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown 21, /* 1 AC97 Link frames */ 126dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown 42, /* 2 */ 127dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown 84, /* 4 */ 128dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown 167, /* 8 */ 129dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown 333, /* 16 */ 130dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown 667, /* 32 */ 131dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown 1000, /* 48 */ 132dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown 1333, /* 64 */ 133dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown 2000, /* 96 */ 134dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown 2667, /* 128 */ 135dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown 3333, /* 160 */ 136dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown 4000, /* 192 */ 137dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown 4667, /* 224 */ 138dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown 5333, /* 256 */ 139dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown 6000, /* 288 */ 140dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown 0 /* No delay, switch matrix always on */ 141dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown}; 142dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown 143dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown/* 144dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown * Delay after issuing a POLL command. 145dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown * 146dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown * The delay is 3 AC97 link frames + the touchpanel settling delay 147dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown */ 148dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brownstatic inline void poll_delay(int d) 149dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown{ 150dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown udelay(3 * AC97_LINK_FRAME + delay_table[d]); 151dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown} 152dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown 153dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown/* 154dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown * set up the physical settings of the WM9713 155dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown */ 156dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brownstatic void wm9713_phy_init(struct wm97xx *wm) 157dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown{ 158dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown u16 dig1 = 0, dig2, dig3; 159dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown 160dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown /* default values */ 161dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown dig2 = WM97XX_DELAY(4) | WM97XX_SLT(5); 162dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown dig3 = WM9712_RPU(1); 163dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown 164dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown /* rpu */ 165dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown if (rpu) { 166dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown dig3 &= 0xffc0; 167dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown dig3 |= WM9712_RPU(rpu); 168dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown dev_info(wm->dev, "setting pen detect pull-up to %d Ohms\n", 169dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown 64000 / rpu); 170dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown } 171dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown 17243f83a8f9963a11a9c3f41beecc363da21ae3602Mark Brown /* Five wire panel? */ 17343f83a8f9963a11a9c3f41beecc363da21ae3602Mark Brown if (five_wire) { 17443f83a8f9963a11a9c3f41beecc363da21ae3602Mark Brown dig3 |= WM9713_45W; 17543f83a8f9963a11a9c3f41beecc363da21ae3602Mark Brown dev_info(wm->dev, "setting 5-wire touchscreen mode."); 17643f83a8f9963a11a9c3f41beecc363da21ae3602Mark Brown 17743f83a8f9963a11a9c3f41beecc363da21ae3602Mark Brown if (pil) { 17843f83a8f9963a11a9c3f41beecc363da21ae3602Mark Brown dev_warn(wm->dev, 17943f83a8f9963a11a9c3f41beecc363da21ae3602Mark Brown "Pressure measurement not supported in 5 " 18043f83a8f9963a11a9c3f41beecc363da21ae3602Mark Brown "wire mode, disabling\n"); 18143f83a8f9963a11a9c3f41beecc363da21ae3602Mark Brown pil = 0; 18243f83a8f9963a11a9c3f41beecc363da21ae3602Mark Brown } 18343f83a8f9963a11a9c3f41beecc363da21ae3602Mark Brown } 18443f83a8f9963a11a9c3f41beecc363da21ae3602Mark Brown 185dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown /* touchpanel pressure */ 186dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown if (pil == 2) { 187dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown dig3 |= WM9712_PIL; 188dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown dev_info(wm->dev, 189dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown "setting pressure measurement current to 400uA."); 190dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown } else if (pil) 191dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown dev_info(wm->dev, 192dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown "setting pressure measurement current to 200uA."); 193dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown if (!pil) 194dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown pressure = 0; 195dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown 196dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown /* sample settling delay */ 197dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown if (delay < 0 || delay > 15) { 198dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown dev_info(wm->dev, "supplied delay out of range."); 199dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown delay = 4; 200dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown dev_info(wm->dev, "setting adc sample delay to %d u Secs.", 201dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown delay_table[delay]); 202dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown } 203dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown dig2 &= 0xff0f; 204dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown dig2 |= WM97XX_DELAY(delay); 205dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown 206dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown /* mask */ 207dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown dig3 |= ((mask & 0x3) << 4); 208dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown if (coord) 209dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown dig3 |= WM9713_WAIT; 210dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown 211dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown wm->misc = wm97xx_reg_read(wm, 0x5a); 212dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown 213dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown wm97xx_reg_write(wm, AC97_WM9713_DIG1, dig1); 214dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown wm97xx_reg_write(wm, AC97_WM9713_DIG2, dig2); 215dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown wm97xx_reg_write(wm, AC97_WM9713_DIG3, dig3); 216dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown wm97xx_reg_write(wm, AC97_GPIO_STICKY, 0x0); 217dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown} 218dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown 219dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brownstatic void wm9713_dig_enable(struct wm97xx *wm, int enable) 220dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown{ 221dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown u16 val; 222dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown 223dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown if (enable) { 224dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown val = wm97xx_reg_read(wm, AC97_EXTENDED_MID); 225dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown wm97xx_reg_write(wm, AC97_EXTENDED_MID, val & 0x7fff); 226dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown wm97xx_reg_write(wm, AC97_WM9713_DIG3, wm->dig[2] | 227dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown WM97XX_PRP_DET_DIG); 228dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD); /* dummy read */ 229dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown } else { 230dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown wm97xx_reg_write(wm, AC97_WM9713_DIG3, wm->dig[2] & 231dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown ~WM97XX_PRP_DET_DIG); 232dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown val = wm97xx_reg_read(wm, AC97_EXTENDED_MID); 233dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown wm97xx_reg_write(wm, AC97_EXTENDED_MID, val | 0x8000); 234dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown } 235dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown} 236dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown 237dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brownstatic void wm9713_dig_restore(struct wm97xx *wm) 238dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown{ 239dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown wm97xx_reg_write(wm, AC97_WM9713_DIG1, wm->dig_save[0]); 240dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown wm97xx_reg_write(wm, AC97_WM9713_DIG2, wm->dig_save[1]); 241dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown wm97xx_reg_write(wm, AC97_WM9713_DIG3, wm->dig_save[2]); 242dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown} 243dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown 244dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brownstatic void wm9713_aux_prepare(struct wm97xx *wm) 245dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown{ 246dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown memcpy(wm->dig_save, wm->dig, sizeof(wm->dig)); 247dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown wm97xx_reg_write(wm, AC97_WM9713_DIG1, 0); 248dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown wm97xx_reg_write(wm, AC97_WM9713_DIG2, 0); 249dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown wm97xx_reg_write(wm, AC97_WM9713_DIG3, WM97XX_PRP_DET_DIG); 250dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown} 251dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown 252dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brownstatic inline int is_pden(struct wm97xx *wm) 253dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown{ 254dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown return wm->dig[2] & WM9713_PDEN; 255dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown} 256dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown 257dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown/* 258dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown * Read a sample from the WM9713 adc in polling mode. 259dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown */ 260dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brownstatic int wm9713_poll_sample(struct wm97xx *wm, int adcsel, int *sample) 261dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown{ 262dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown u16 dig1; 263dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown int timeout = 5 * delay; 26477da38387e1c6f473744afccd83795805f506498Wolfram Sang bool wants_pen = adcsel & WM97XX_PEN_DOWN; 265dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown 26677da38387e1c6f473744afccd83795805f506498Wolfram Sang if (wants_pen && !wm->pen_probably_down) { 267dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown u16 data = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD); 268dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown if (!(data & WM97XX_PEN_DOWN)) 269dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown return RC_PENUP; 270dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown wm->pen_probably_down = 1; 271dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown } 272dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown 273dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown /* set up digitiser */ 274dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown dig1 = wm97xx_reg_read(wm, AC97_WM9713_DIG1); 275dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown dig1 &= ~WM9713_ADCSEL_MASK; 276c8f205258bc8942e79cd37ebc1c8ec4652a1a501Wolfram Sang /* WM97XX_ADCSEL_* channels need to be converted to WM9713 format */ 277c8f205258bc8942e79cd37ebc1c8ec4652a1a501Wolfram Sang dig1 |= 1 << ((adcsel & WM97XX_ADCSEL_MASK) >> 12); 278dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown 279dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown if (wm->mach_ops && wm->mach_ops->pre_sample) 280dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown wm->mach_ops->pre_sample(adcsel); 281c8f205258bc8942e79cd37ebc1c8ec4652a1a501Wolfram Sang wm97xx_reg_write(wm, AC97_WM9713_DIG1, dig1 | WM9713_POLL); 282dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown 283dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown /* wait 3 AC97 time slots + delay for conversion */ 284dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown poll_delay(delay); 285dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown 286dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown /* wait for POLL to go low */ 287dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown while ((wm97xx_reg_read(wm, AC97_WM9713_DIG1) & WM9713_POLL) && 288dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown timeout) { 289dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown udelay(AC97_LINK_FRAME); 290dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown timeout--; 291dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown } 292dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown 293dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown if (timeout <= 0) { 294dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown /* If PDEN is set, we can get a timeout when pen goes up */ 295dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown if (is_pden(wm)) 296dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown wm->pen_probably_down = 0; 297dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown else 298dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown dev_dbg(wm->dev, "adc sample timeout"); 299dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown return RC_PENUP; 300dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown } 301dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown 302dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown *sample = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD); 303dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown if (wm->mach_ops && wm->mach_ops->post_sample) 304dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown wm->mach_ops->post_sample(adcsel); 305dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown 306dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown /* check we have correct sample */ 307c8f205258bc8942e79cd37ebc1c8ec4652a1a501Wolfram Sang if ((*sample ^ adcsel) & WM97XX_ADCSEL_MASK) { 308c8f205258bc8942e79cd37ebc1c8ec4652a1a501Wolfram Sang dev_dbg(wm->dev, "adc wrong sample, wanted %x got %x", 309c8f205258bc8942e79cd37ebc1c8ec4652a1a501Wolfram Sang adcsel & WM97XX_ADCSEL_MASK, 3102456689b3b11ddecc091cd5f00b9adea6a9854cfWolfram Sang *sample & WM97XX_ADCSEL_MASK); 311dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown return RC_PENUP; 312dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown } 313dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown 31477da38387e1c6f473744afccd83795805f506498Wolfram Sang if (wants_pen && !(*sample & WM97XX_PEN_DOWN)) { 315dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown wm->pen_probably_down = 0; 316dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown return RC_PENUP; 317dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown } 318dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown 319dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown return RC_VALID; 320dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown} 321dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown 322dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown/* 323dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown * Read a coordinate from the WM9713 adc in polling mode. 324dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown */ 325dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brownstatic int wm9713_poll_coord(struct wm97xx *wm, struct wm97xx_data *data) 326dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown{ 327dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown u16 dig1; 328dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown int timeout = 5 * delay; 329dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown 330dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown if (!wm->pen_probably_down) { 331dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown u16 val = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD); 332dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown if (!(val & WM97XX_PEN_DOWN)) 333dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown return RC_PENUP; 334dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown wm->pen_probably_down = 1; 335dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown } 336dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown 337dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown /* set up digitiser */ 338dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown dig1 = wm97xx_reg_read(wm, AC97_WM9713_DIG1); 339dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown dig1 &= ~WM9713_ADCSEL_MASK; 340dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown if (pil) 341dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown dig1 |= WM9713_ADCSEL_PRES; 342dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown 343dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown if (wm->mach_ops && wm->mach_ops->pre_sample) 344dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown wm->mach_ops->pre_sample(WM97XX_ADCSEL_X | WM97XX_ADCSEL_Y); 345dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown wm97xx_reg_write(wm, AC97_WM9713_DIG1, 346dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown dig1 | WM9713_POLL | WM9713_COO); 347dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown 348dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown /* wait 3 AC97 time slots + delay for conversion */ 349dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown poll_delay(delay); 350dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown data->x = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD); 351dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown /* wait for POLL to go low */ 352dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown while ((wm97xx_reg_read(wm, AC97_WM9713_DIG1) & WM9713_POLL) 353dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown && timeout) { 354dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown udelay(AC97_LINK_FRAME); 355dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown timeout--; 356dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown } 357dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown 358dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown if (timeout <= 0) { 359dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown /* If PDEN is set, we can get a timeout when pen goes up */ 360dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown if (is_pden(wm)) 361dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown wm->pen_probably_down = 0; 362dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown else 363dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown dev_dbg(wm->dev, "adc sample timeout"); 364dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown return RC_PENUP; 365dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown } 366dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown 367dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown /* read back data */ 368dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown data->y = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD); 369dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown if (pil) 370dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown data->p = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD); 371dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown else 372dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown data->p = DEFAULT_PRESSURE; 373dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown 374dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown if (wm->mach_ops && wm->mach_ops->post_sample) 375dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown wm->mach_ops->post_sample(WM97XX_ADCSEL_X | WM97XX_ADCSEL_Y); 376dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown 377dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown /* check we have correct sample */ 378dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown if (!(data->x & WM97XX_ADCSEL_X) || !(data->y & WM97XX_ADCSEL_Y)) 379dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown goto err; 380dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown if (pil && !(data->p & WM97XX_ADCSEL_PRES)) 381dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown goto err; 382dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown 383dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown if (!(data->x & WM97XX_PEN_DOWN) || !(data->y & WM97XX_PEN_DOWN)) { 384dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown wm->pen_probably_down = 0; 385dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown return RC_PENUP; 386dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown } 387dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown return RC_VALID; 388dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brownerr: 389dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown return 0; 390dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown} 391dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown 392dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown/* 393dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown * Sample the WM9713 touchscreen in polling mode 394dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown */ 395dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brownstatic int wm9713_poll_touch(struct wm97xx *wm, struct wm97xx_data *data) 396dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown{ 397dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown int rc; 398dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown 399dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown if (coord) { 400dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown rc = wm9713_poll_coord(wm, data); 401dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown if (rc != RC_VALID) 402dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown return rc; 403dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown } else { 40477da38387e1c6f473744afccd83795805f506498Wolfram Sang rc = wm9713_poll_sample(wm, WM97XX_ADCSEL_X | WM97XX_PEN_DOWN, &data->x); 405dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown if (rc != RC_VALID) 406dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown return rc; 40777da38387e1c6f473744afccd83795805f506498Wolfram Sang rc = wm9713_poll_sample(wm, WM97XX_ADCSEL_Y | WM97XX_PEN_DOWN, &data->y); 408dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown if (rc != RC_VALID) 409dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown return rc; 410dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown if (pil) { 41177da38387e1c6f473744afccd83795805f506498Wolfram Sang rc = wm9713_poll_sample(wm, WM97XX_ADCSEL_PRES | WM97XX_PEN_DOWN, 412dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown &data->p); 413dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown if (rc != RC_VALID) 414dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown return rc; 415dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown } else 416dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown data->p = DEFAULT_PRESSURE; 417dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown } 418dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown return RC_VALID; 419dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown} 420dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown 421dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown/* 422dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown * Enable WM9713 continuous mode, i.e. touch data is streamed across 423dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown * an AC97 slot 424dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown */ 425dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brownstatic int wm9713_acc_enable(struct wm97xx *wm, int enable) 426dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown{ 427dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown u16 dig1, dig2, dig3; 428dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown int ret = 0; 429dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown 430dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown dig1 = wm->dig[0]; 431dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown dig2 = wm->dig[1]; 432dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown dig3 = wm->dig[2]; 433dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown 434dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown if (enable) { 43525985edcedea6396277003854657b5f3cb31a628Lucas De Marchi /* continuous mode */ 436dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown if (wm->mach_ops->acc_startup && 437dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown (ret = wm->mach_ops->acc_startup(wm)) < 0) 438dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown return ret; 439dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown 440dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown dig1 &= ~WM9713_ADCSEL_MASK; 441dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown dig1 |= WM9713_CTC | WM9713_COO | WM9713_ADCSEL_X | 442dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown WM9713_ADCSEL_Y; 443dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown if (pil) 444dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown dig1 |= WM9713_ADCSEL_PRES; 445dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown dig2 &= ~(WM97XX_DELAY_MASK | WM97XX_SLT_MASK | 446dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown WM97XX_CM_RATE_MASK); 447dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown dig2 |= WM97XX_SLEN | WM97XX_DELAY(delay) | 448dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown WM97XX_SLT(wm->acc_slot) | WM97XX_RATE(wm->acc_rate); 449dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown dig3 |= WM9713_PDEN; 450dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown } else { 451dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown dig1 &= ~(WM9713_CTC | WM9713_COO); 452dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown dig2 &= ~WM97XX_SLEN; 453dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown dig3 &= ~WM9713_PDEN; 454dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown if (wm->mach_ops->acc_shutdown) 455dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown wm->mach_ops->acc_shutdown(wm); 456dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown } 457dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown 458dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown wm97xx_reg_write(wm, AC97_WM9713_DIG1, dig1); 459dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown wm97xx_reg_write(wm, AC97_WM9713_DIG2, dig2); 460dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown wm97xx_reg_write(wm, AC97_WM9713_DIG3, dig3); 461dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown 462dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown return ret; 463dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown} 464dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown 465dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brownstruct wm97xx_codec_drv wm9713_codec = { 466dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown .id = WM9713_ID2, 467dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown .name = "wm9713", 468dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown .poll_sample = wm9713_poll_sample, 469dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown .poll_touch = wm9713_poll_touch, 470dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown .acc_enable = wm9713_acc_enable, 471dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown .phy_init = wm9713_phy_init, 472dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown .dig_enable = wm9713_dig_enable, 473dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown .dig_restore = wm9713_dig_restore, 474dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown .aux_prepare = wm9713_aux_prepare, 475dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown}; 476dca98e91fb83a43fc430893f349fd8248fa0ba38Mark BrownEXPORT_SYMBOL_GPL(wm9713_codec); 477dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown 478dca98e91fb83a43fc430893f349fd8248fa0ba38Mark Brown/* Module information */ 479b8d055a878ee0f997ded40649701089d2486f850Liam GirdwoodMODULE_AUTHOR("Liam Girdwood <lrg@slimlogic.co.uk>"); 480dca98e91fb83a43fc430893f349fd8248fa0ba38Mark BrownMODULE_DESCRIPTION("WM9713 Touch Screen Driver"); 481dca98e91fb83a43fc430893f349fd8248fa0ba38Mark BrownMODULE_LICENSE("GPL"); 482