diff options
author | Eric Millbrandt <emillbrandt@dekaresearch.com> | 2010-09-03 13:31:05 -0400 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2010-09-05 15:14:36 -0400 |
commit | eb54ddd4d78e62647b7096e4ada7389dbdf2cea7 (patch) | |
tree | cef6a031b465523fac6e0f5c1b1466e1aa986b02 | |
parent | d3622e6f05b2134deb5ba8ca2f6bcce5391e7e6d (diff) |
Input: wm97xx-core - add retries to wm97xx_read_aux_adc
Add logic to wm97xx_read_aux_adc() to retry reading the adc if the
sample failed. This could occur if the previous sample was still in
the return register or the sample timed-out. Also avoid a pathologic
failure mode by disabling the digitizer and returning -EBUSY after 5
retries.
Signed-off-by: Eric Millbrandt <emillbrandt@dekaresearch.com>
Acked-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
-rw-r--r-- | drivers/input/touchscreen/wm97xx-core.c | 15 |
1 files changed, 13 insertions, 2 deletions
diff --git a/drivers/input/touchscreen/wm97xx-core.c b/drivers/input/touchscreen/wm97xx-core.c index 770537c14628..6b75c9f660ae 100644 --- a/drivers/input/touchscreen/wm97xx-core.c +++ b/drivers/input/touchscreen/wm97xx-core.c | |||
@@ -125,6 +125,8 @@ int wm97xx_read_aux_adc(struct wm97xx *wm, u16 adcsel) | |||
125 | { | 125 | { |
126 | int power_adc = 0, auxval; | 126 | int power_adc = 0, auxval; |
127 | u16 power = 0; | 127 | u16 power = 0; |
128 | int rc = 0; | ||
129 | int timeout = 0; | ||
128 | 130 | ||
129 | /* get codec */ | 131 | /* get codec */ |
130 | mutex_lock(&wm->codec_mutex); | 132 | mutex_lock(&wm->codec_mutex); |
@@ -143,7 +145,9 @@ int wm97xx_read_aux_adc(struct wm97xx *wm, u16 adcsel) | |||
143 | 145 | ||
144 | /* Turn polling mode on to read AUX ADC */ | 146 | /* Turn polling mode on to read AUX ADC */ |
145 | wm->pen_probably_down = 1; | 147 | wm->pen_probably_down = 1; |
146 | wm->codec->poll_sample(wm, adcsel, &auxval); | 148 | |
149 | while (rc != RC_VALID && timeout++ < 5) | ||
150 | rc = wm->codec->poll_sample(wm, adcsel, &auxval); | ||
147 | 151 | ||
148 | if (power_adc) | 152 | if (power_adc) |
149 | wm97xx_reg_write(wm, AC97_EXTENDED_MID, power | 0x8000); | 153 | wm97xx_reg_write(wm, AC97_EXTENDED_MID, power | 0x8000); |
@@ -152,8 +156,15 @@ int wm97xx_read_aux_adc(struct wm97xx *wm, u16 adcsel) | |||
152 | 156 | ||
153 | wm->pen_probably_down = 0; | 157 | wm->pen_probably_down = 0; |
154 | 158 | ||
159 | if (timeout >= 5) { | ||
160 | dev_err(wm->dev, | ||
161 | "timeout reading auxadc %d, disabling digitiser\n", | ||
162 | adcsel); | ||
163 | wm->codec->dig_enable(wm, false); | ||
164 | } | ||
165 | |||
155 | mutex_unlock(&wm->codec_mutex); | 166 | mutex_unlock(&wm->codec_mutex); |
156 | return auxval & 0xfff; | 167 | return (rc == RC_VALID ? auxval & 0xfff : -EBUSY); |
157 | } | 168 | } |
158 | EXPORT_SYMBOL_GPL(wm97xx_read_aux_adc); | 169 | EXPORT_SYMBOL_GPL(wm97xx_read_aux_adc); |
159 | 170 | ||