Commit c8f20525 authored by Wolfram Sang's avatar Wolfram Sang Committed by Dmitry Torokhov

Input: wm97xx - refactor channel selection in poll_sample()

The current implementation of poll_sample() has the problem that one of
its arguments, the channel to be selected, differs from wm9713 to other
variants. This parameter gets passed to the (currently unused)
mach-specific functions pre_sample() and post_sample() which thus have
to deal with codec-specific differences. Refactor the routine so that
the argument to poll_sample() is generic for all codecs and do necessary
conversions only in the codec-specific driver. The outcome even uses
less code and removes the non-standard use of the PEN_DOWN bit to mark
the AUX-channels.
Signed-off-by: default avatarWolfram Sang <w.sang@pengutronix.de>
Acked-by: default avatarMark Brown <broonie@opensource.wolfsonmicro.com>
Signed-off-by: default avatarDmitry Torokhov <dtor@mail.ru>
parent 2456689b
...@@ -224,13 +224,10 @@ static int wm9705_poll_sample(struct wm97xx *wm, int adcsel, int *sample) ...@@ -224,13 +224,10 @@ static int wm9705_poll_sample(struct wm97xx *wm, int adcsel, int *sample)
} }
/* set up digitiser */ /* set up digitiser */
if (adcsel & 0x8000)
adcsel = ((adcsel & 0x7fff) + 3) << 12;
if (wm->mach_ops && wm->mach_ops->pre_sample) if (wm->mach_ops && wm->mach_ops->pre_sample)
wm->mach_ops->pre_sample(adcsel); wm->mach_ops->pre_sample(adcsel);
wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1, wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1, (adcsel & WM97XX_ADCSEL_MASK)
adcsel | WM97XX_POLL | WM97XX_DELAY(delay)); | WM97XX_POLL | WM97XX_DELAY(delay));
/* wait 3 AC97 time slots + delay for conversion */ /* wait 3 AC97 time slots + delay for conversion */
poll_delay(delay); poll_delay(delay);
...@@ -256,9 +253,10 @@ static int wm9705_poll_sample(struct wm97xx *wm, int adcsel, int *sample) ...@@ -256,9 +253,10 @@ static int wm9705_poll_sample(struct wm97xx *wm, int adcsel, int *sample)
wm->mach_ops->post_sample(adcsel); wm->mach_ops->post_sample(adcsel);
/* check we have correct sample */ /* check we have correct sample */
if ((*sample & WM97XX_ADCSEL_MASK) != adcsel) { if ((*sample ^ adcsel) & WM97XX_ADCSEL_MASK) {
dev_dbg(wm->dev, "adc wrong sample, read %x got %x", adcsel, dev_dbg(wm->dev, "adc wrong sample, wanted %x got %x",
*sample & WM97XX_ADCSEL_MASK); adcsel & WM97XX_ADCSEL_MASK,
*sample & WM97XX_ADCSEL_MASK);
return RC_PENUP; return RC_PENUP;
} }
......
...@@ -264,13 +264,10 @@ static int wm9712_poll_sample(struct wm97xx *wm, int adcsel, int *sample) ...@@ -264,13 +264,10 @@ static int wm9712_poll_sample(struct wm97xx *wm, int adcsel, int *sample)
} }
/* set up digitiser */ /* set up digitiser */
if (adcsel & 0x8000)
adcsel = ((adcsel & 0x7fff) + 3) << 12;
if (wm->mach_ops && wm->mach_ops->pre_sample) if (wm->mach_ops && wm->mach_ops->pre_sample)
wm->mach_ops->pre_sample(adcsel); wm->mach_ops->pre_sample(adcsel);
wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1, wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1, (adcsel & WM97XX_ADCSEL_MASK)
adcsel | WM97XX_POLL | WM97XX_DELAY(delay)); | WM97XX_POLL | WM97XX_DELAY(delay));
/* wait 3 AC97 time slots + delay for conversion */ /* wait 3 AC97 time slots + delay for conversion */
poll_delay(delay); poll_delay(delay);
...@@ -296,9 +293,10 @@ static int wm9712_poll_sample(struct wm97xx *wm, int adcsel, int *sample) ...@@ -296,9 +293,10 @@ static int wm9712_poll_sample(struct wm97xx *wm, int adcsel, int *sample)
wm->mach_ops->post_sample(adcsel); wm->mach_ops->post_sample(adcsel);
/* check we have correct sample */ /* check we have correct sample */
if ((*sample & WM97XX_ADCSEL_MASK) != adcsel) { if ((*sample ^ adcsel) & WM97XX_ADCSEL_MASK) {
dev_dbg(wm->dev, "adc wrong sample, read %x got %x", adcsel, dev_dbg(wm->dev, "adc wrong sample, wanted %x got %x",
*sample & WM97XX_ADCSEL_MASK); adcsel & WM97XX_ADCSEL_MASK,
*sample & WM97XX_ADCSEL_MASK);
return RC_PENUP; return RC_PENUP;
} }
......
...@@ -270,15 +270,14 @@ static int wm9713_poll_sample(struct wm97xx *wm, int adcsel, int *sample) ...@@ -270,15 +270,14 @@ static int wm9713_poll_sample(struct wm97xx *wm, int adcsel, int *sample)
} }
/* set up digitiser */ /* set up digitiser */
if (adcsel & 0x8000)
adcsel = 1 << ((adcsel & 0x7fff) + 3);
dig1 = wm97xx_reg_read(wm, AC97_WM9713_DIG1); dig1 = wm97xx_reg_read(wm, AC97_WM9713_DIG1);
dig1 &= ~WM9713_ADCSEL_MASK; dig1 &= ~WM9713_ADCSEL_MASK;
/* WM97XX_ADCSEL_* channels need to be converted to WM9713 format */
dig1 |= 1 << ((adcsel & WM97XX_ADCSEL_MASK) >> 12);
if (wm->mach_ops && wm->mach_ops->pre_sample) if (wm->mach_ops && wm->mach_ops->pre_sample)
wm->mach_ops->pre_sample(adcsel); wm->mach_ops->pre_sample(adcsel);
wm97xx_reg_write(wm, AC97_WM9713_DIG1, dig1 | adcsel | WM9713_POLL); wm97xx_reg_write(wm, AC97_WM9713_DIG1, dig1 | WM9713_POLL);
/* wait 3 AC97 time slots + delay for conversion */ /* wait 3 AC97 time slots + delay for conversion */
poll_delay(delay); poll_delay(delay);
...@@ -304,8 +303,9 @@ static int wm9713_poll_sample(struct wm97xx *wm, int adcsel, int *sample) ...@@ -304,8 +303,9 @@ static int wm9713_poll_sample(struct wm97xx *wm, int adcsel, int *sample)
wm->mach_ops->post_sample(adcsel); wm->mach_ops->post_sample(adcsel);
/* check we have correct sample */ /* check we have correct sample */
if ((*sample & WM97XX_ADCSEL_MASK) != ffs(adcsel >> 1) << 12) { if ((*sample ^ adcsel) & WM97XX_ADCSEL_MASK) {
dev_dbg(wm->dev, "adc wrong sample, read %x got %x", adcsel, dev_dbg(wm->dev, "adc wrong sample, wanted %x got %x",
adcsel & WM97XX_ADCSEL_MASK,
*sample & WM97XX_ADCSEL_MASK); *sample & WM97XX_ADCSEL_MASK);
return RC_PENUP; return RC_PENUP;
} }
...@@ -400,14 +400,14 @@ static int wm9713_poll_touch(struct wm97xx *wm, struct wm97xx_data *data) ...@@ -400,14 +400,14 @@ static int wm9713_poll_touch(struct wm97xx *wm, struct wm97xx_data *data)
if (rc != RC_VALID) if (rc != RC_VALID)
return rc; return rc;
} else { } else {
rc = wm9713_poll_sample(wm, WM9713_ADCSEL_X, &data->x); rc = wm9713_poll_sample(wm, WM97XX_ADCSEL_X, &data->x);
if (rc != RC_VALID) if (rc != RC_VALID)
return rc; return rc;
rc = wm9713_poll_sample(wm, WM9713_ADCSEL_Y, &data->y); rc = wm9713_poll_sample(wm, WM97XX_ADCSEL_Y, &data->y);
if (rc != RC_VALID) if (rc != RC_VALID)
return rc; return rc;
if (pil) { if (pil) {
rc = wm9713_poll_sample(wm, WM9713_ADCSEL_PRES, rc = wm9713_poll_sample(wm, WM97XX_ADCSEL_PRES,
&data->p); &data->p);
if (rc != RC_VALID) if (rc != RC_VALID)
return rc; return rc;
......
...@@ -38,6 +38,10 @@ ...@@ -38,6 +38,10 @@
#define WM97XX_ADCSEL_X 0x1000 /* x coord measurement */ #define WM97XX_ADCSEL_X 0x1000 /* x coord measurement */
#define WM97XX_ADCSEL_Y 0x2000 /* y coord measurement */ #define WM97XX_ADCSEL_Y 0x2000 /* y coord measurement */
#define WM97XX_ADCSEL_PRES 0x3000 /* pressure measurement */ #define WM97XX_ADCSEL_PRES 0x3000 /* pressure measurement */
#define WM97XX_AUX_ID1 0x4000
#define WM97XX_AUX_ID2 0x5000
#define WM97XX_AUX_ID3 0x6000
#define WM97XX_AUX_ID4 0x7000
#define WM97XX_ADCSEL_MASK 0x7000 /* ADC selection mask */ #define WM97XX_ADCSEL_MASK 0x7000 /* ADC selection mask */
#define WM97XX_COO 0x0800 /* enable coordinate mode */ #define WM97XX_COO 0x0800 /* enable coordinate mode */
#define WM97XX_CTC 0x0400 /* enable continuous mode */ #define WM97XX_CTC 0x0400 /* enable continuous mode */
...@@ -62,12 +66,6 @@ ...@@ -62,12 +66,6 @@
#define WM97XX_RPR 0x2000 /* wake up on pen down */ #define WM97XX_RPR 0x2000 /* wake up on pen down */
#define WM97XX_PEN_DOWN 0x8000 /* pen is down */ #define WM97XX_PEN_DOWN 0x8000 /* pen is down */
#define WM97XX_AUX_ID1 0x8001
#define WM97XX_AUX_ID2 0x8002
#define WM97XX_AUX_ID3 0x8003
#define WM97XX_AUX_ID4 0x8004
/* WM9712 Bits */ /* WM9712 Bits */
#define WM9712_45W 0x1000 /* set for 5-wire touchscreen */ #define WM9712_45W 0x1000 /* set for 5-wire touchscreen */
#define WM9712_PDEN 0x0800 /* measure only when pen down */ #define WM9712_PDEN 0x0800 /* measure only when pen down */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment