^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * wm9712.c -- Codec driver for Wolfson WM9712 AC97 Codecs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright 2003, 2004, 2005, 2006, 2007 Wolfson Microelectronics PLC.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Author: Liam Girdwood <lrg@slimlogic.co.uk>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Parts Copyright : Ian Molton <spyro@f2s.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Andrew Zabolotny <zap@homelink.ru>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Russell King <rmk@arm.linux.org.uk>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/moduleparam.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/input.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/bitops.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/wm97xx.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #define TS_NAME "wm97xx"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #define WM9712_VERSION "1.00"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #define DEFAULT_PRESSURE 0xb0c0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * Module parameters
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * Set internal pull up for pen detect.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * Pull up is in the range 1.02k (least sensitive) to 64k (most sensitive)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) * i.e. pull up resistance = 64k Ohms / rpu.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * Adjust this value if you are having problems with pen detect not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) * detecting any down event.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) static int rpu = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) module_param(rpu, int, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) MODULE_PARM_DESC(rpu, "Set internal pull up resistor for pen detect.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) * Set current used for pressure measurement.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) * Set pil = 2 to use 400uA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) * pil = 1 to use 200uA and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) * pil = 0 to disable pressure measurement.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) * This is used to increase the range of values returned by the adc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) * when measureing touchpanel pressure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) static int pil;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) module_param(pil, int, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) MODULE_PARM_DESC(pil, "Set current used for pressure measurement.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) * Set threshold for pressure measurement.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) * Pen down pressure below threshold is ignored.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) static int pressure = DEFAULT_PRESSURE & 0xfff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) module_param(pressure, int, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) MODULE_PARM_DESC(pressure, "Set threshold for pressure measurement.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) * Set adc sample delay.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) * For accurate touchpanel measurements, some settling time may be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) * required between the switch matrix applying a voltage across the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) * touchpanel plate and the ADC sampling the signal.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) * This delay can be set by setting delay = n, where n is the array
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) * position of the delay in the array delay_table below.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) * Long delays > 1ms are supported for completeness, but are not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) * recommended.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) static int delay = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) module_param(delay, int, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) MODULE_PARM_DESC(delay, "Set adc sample delay.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) * Set five_wire = 1 to use a 5 wire touchscreen.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) * NOTE: Five wire mode does not allow for readback of pressure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) static int five_wire;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) module_param(five_wire, int, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) MODULE_PARM_DESC(five_wire, "Set to '1' to use 5-wire touchscreen.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) * Set adc mask function.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) * Sources of glitch noise, such as signals driving an LCD display, may feed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) * through to the touch screen plates and affect measurement accuracy. In
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) * order to minimise this, a signal may be applied to the MASK pin to delay or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) * synchronise the sampling.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) * 0 = No delay or sync
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) * 1 = High on pin stops conversions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) * 2 = Edge triggered, edge on pin delays conversion by delay param (above)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) * 3 = Edge triggered, edge on pin starts conversion after delay param
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) static int mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) module_param(mask, int, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) MODULE_PARM_DESC(mask, "Set adc mask function.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) * Coordinate Polling Enable.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) * Set to 1 to enable coordinate polling. e.g. x,y[,p] is sampled together
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) * for every poll.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) static int coord;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) module_param(coord, int, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) MODULE_PARM_DESC(coord, "Polling coordinate mode");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) * ADC sample delay times in uS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) static const int delay_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 21, /* 1 AC97 Link frames */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 42, /* 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 84, /* 4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 167, /* 8 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 333, /* 16 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 667, /* 32 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 1000, /* 48 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 1333, /* 64 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 2000, /* 96 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 2667, /* 128 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 3333, /* 160 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 4000, /* 192 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 4667, /* 224 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 5333, /* 256 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 6000, /* 288 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 0 /* No delay, switch matrix always on */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) * Delay after issuing a POLL command.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) * The delay is 3 AC97 link frames + the touchpanel settling delay
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) static inline void poll_delay(int d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) udelay(3 * AC97_LINK_FRAME + delay_table[d]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) * set up the physical settings of the WM9712
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) static void wm9712_phy_init(struct wm97xx *wm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) u16 dig1 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) u16 dig2 = WM97XX_RPR | WM9712_RPU(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) /* WM9712 rpu */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) if (rpu) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) dig2 &= 0xffc0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) dig2 |= WM9712_RPU(rpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) dev_dbg(wm->dev, "setting pen detect pull-up to %d Ohms\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 64000 / rpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) /* WM9712 five wire */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) if (five_wire) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) dig2 |= WM9712_45W;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) dev_dbg(wm->dev, "setting 5-wire touchscreen mode.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) if (pil) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) dev_warn(wm->dev, "pressure measurement is not "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) "supported in 5-wire mode\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) pil = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) /* touchpanel pressure current*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) if (pil == 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) dig2 |= WM9712_PIL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) dev_dbg(wm->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) "setting pressure measurement current to 400uA.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) } else if (pil)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) dev_dbg(wm->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) "setting pressure measurement current to 200uA.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) if (!pil)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) pressure = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) /* polling mode sample settling delay */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) if (delay < 0 || delay > 15) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) dev_dbg(wm->dev, "supplied delay out of range.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) delay = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) dig1 &= 0xff0f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) dig1 |= WM97XX_DELAY(delay);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) dev_dbg(wm->dev, "setting adc sample delay to %d u Secs.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) delay_table[delay]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) /* mask */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) dig2 |= ((mask & 0x3) << 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) if (mask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) u16 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) /* Set GPIO4 as Mask Pin*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) reg = wm97xx_reg_read(wm, AC97_MISC_AFE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) wm97xx_reg_write(wm, AC97_MISC_AFE, reg | WM97XX_GPIO_4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) reg = wm97xx_reg_read(wm, AC97_GPIO_CFG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) wm97xx_reg_write(wm, AC97_GPIO_CFG, reg | WM97XX_GPIO_4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) /* wait - coord mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) if (coord)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) dig2 |= WM9712_WAIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1, dig1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2, dig2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) static void wm9712_dig_enable(struct wm97xx *wm, int enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) u16 dig2 = wm->dig[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) if (enable) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) dig2 | WM97XX_PRP_DET_DIG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD); /* dummy read */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) dig2 & ~WM97XX_PRP_DET_DIG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) static void wm9712_aux_prepare(struct wm97xx *wm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) memcpy(wm->dig_save, wm->dig, sizeof(wm->dig));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2, WM97XX_PRP_DET_DIG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) static void wm9712_dig_restore(struct wm97xx *wm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1, wm->dig_save[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2, wm->dig_save[2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) static inline int is_pden(struct wm97xx *wm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) return wm->dig[2] & WM9712_PDEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) * Read a sample from the WM9712 adc in polling mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) static int wm9712_poll_sample(struct wm97xx *wm, int adcsel, int *sample)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) int timeout = 5 * delay;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) bool wants_pen = adcsel & WM97XX_PEN_DOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) if (wants_pen && !wm->pen_probably_down) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) u16 data = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) if (!(data & WM97XX_PEN_DOWN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) return RC_PENUP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) wm->pen_probably_down = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) /* set up digitiser */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) if (wm->mach_ops && wm->mach_ops->pre_sample)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) wm->mach_ops->pre_sample(adcsel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1, (adcsel & WM97XX_ADCSEL_MASK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) | WM97XX_POLL | WM97XX_DELAY(delay));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) /* wait 3 AC97 time slots + delay for conversion */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) poll_delay(delay);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) /* wait for POLL to go low */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) while ((wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER1) & WM97XX_POLL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) && timeout) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) udelay(AC97_LINK_FRAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) timeout--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) if (timeout <= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) /* If PDEN is set, we can get a timeout when pen goes up */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) if (is_pden(wm))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) wm->pen_probably_down = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) dev_dbg(wm->dev, "adc sample timeout\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) return RC_PENUP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) *sample = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) if (wm->mach_ops && wm->mach_ops->post_sample)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) wm->mach_ops->post_sample(adcsel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) /* check we have correct sample */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) if ((*sample ^ adcsel) & WM97XX_ADCSEL_MASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) dev_dbg(wm->dev, "adc wrong sample, wanted %x got %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) adcsel & WM97XX_ADCSEL_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) *sample & WM97XX_ADCSEL_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) return RC_AGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) if (wants_pen && !(*sample & WM97XX_PEN_DOWN)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) /* Sometimes it reads a wrong value the first time. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) *sample = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) if (!(*sample & WM97XX_PEN_DOWN)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) wm->pen_probably_down = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) return RC_PENUP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) return RC_VALID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) * Read a coord from the WM9712 adc in polling mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) static int wm9712_poll_coord(struct wm97xx *wm, struct wm97xx_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) int timeout = 5 * delay;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) if (!wm->pen_probably_down) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) u16 data_rd = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) if (!(data_rd & WM97XX_PEN_DOWN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) return RC_PENUP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) wm->pen_probably_down = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) /* set up digitiser */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) if (wm->mach_ops && wm->mach_ops->pre_sample)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) wm->mach_ops->pre_sample(WM97XX_ADCSEL_X | WM97XX_ADCSEL_Y);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) WM97XX_COO | WM97XX_POLL | WM97XX_DELAY(delay));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) /* wait 3 AC97 time slots + delay for conversion and read x */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) poll_delay(delay);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) data->x = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) /* wait for POLL to go low */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) while ((wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER1) & WM97XX_POLL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) && timeout) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) udelay(AC97_LINK_FRAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) timeout--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) if (timeout <= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) /* If PDEN is set, we can get a timeout when pen goes up */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) if (is_pden(wm))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) wm->pen_probably_down = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) dev_dbg(wm->dev, "adc sample timeout\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) return RC_PENUP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) /* read back y data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) data->y = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) if (pil)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) data->p = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) data->p = DEFAULT_PRESSURE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) if (wm->mach_ops && wm->mach_ops->post_sample)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) wm->mach_ops->post_sample(WM97XX_ADCSEL_X | WM97XX_ADCSEL_Y);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) /* check we have correct sample */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) if (!(data->x & WM97XX_ADCSEL_X) || !(data->y & WM97XX_ADCSEL_Y))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) if (pil && !(data->p & WM97XX_ADCSEL_PRES))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) if (!(data->x & WM97XX_PEN_DOWN) || !(data->y & WM97XX_PEN_DOWN)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) wm->pen_probably_down = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) return RC_PENUP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) return RC_VALID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) * Sample the WM9712 touchscreen in polling mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) static int wm9712_poll_touch(struct wm97xx *wm, struct wm97xx_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) if (coord) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) rc = wm9712_poll_coord(wm, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) if (rc != RC_VALID)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) rc = wm9712_poll_sample(wm, WM97XX_ADCSEL_X | WM97XX_PEN_DOWN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) &data->x);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) if (rc != RC_VALID)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) rc = wm9712_poll_sample(wm, WM97XX_ADCSEL_Y | WM97XX_PEN_DOWN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) &data->y);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) if (rc != RC_VALID)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) if (pil && !five_wire) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) rc = wm9712_poll_sample(wm, WM97XX_ADCSEL_PRES | WM97XX_PEN_DOWN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) &data->p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) if (rc != RC_VALID)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) data->p = DEFAULT_PRESSURE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) return RC_VALID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) * Enable WM9712 continuous mode, i.e. touch data is streamed across
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) * an AC97 slot
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) static int wm9712_acc_enable(struct wm97xx *wm, int enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) u16 dig1, dig2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) dig1 = wm->dig[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) dig2 = wm->dig[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) if (enable) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) /* continuous mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) if (wm->mach_ops->acc_startup) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) ret = wm->mach_ops->acc_startup(wm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) dig1 &= ~(WM97XX_CM_RATE_MASK | WM97XX_ADCSEL_MASK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) WM97XX_DELAY_MASK | WM97XX_SLT_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) dig1 |= WM97XX_CTC | WM97XX_COO | WM97XX_SLEN |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) WM97XX_DELAY(delay) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) WM97XX_SLT(wm->acc_slot) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) WM97XX_RATE(wm->acc_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) if (pil)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) dig1 |= WM97XX_ADCSEL_PRES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) dig2 |= WM9712_PDEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) dig1 &= ~(WM97XX_CTC | WM97XX_COO | WM97XX_SLEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) dig2 &= ~WM9712_PDEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) if (wm->mach_ops->acc_shutdown)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) wm->mach_ops->acc_shutdown(wm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1, dig1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2, dig2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) struct wm97xx_codec_drv wm9712_codec = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) .id = WM9712_ID2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) .name = "wm9712",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) .poll_sample = wm9712_poll_sample,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) .poll_touch = wm9712_poll_touch,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) .acc_enable = wm9712_acc_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) .phy_init = wm9712_phy_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) .dig_enable = wm9712_dig_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) .dig_restore = wm9712_dig_restore,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) .aux_prepare = wm9712_aux_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) EXPORT_SYMBOL_GPL(wm9712_codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) /* Module information */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) MODULE_AUTHOR("Liam Girdwood <lrg@slimlogic.co.uk>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) MODULE_DESCRIPTION("WM9712 Touch Screen Driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) MODULE_LICENSE("GPL");