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