Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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: Wolfram Sang <w.sang@pengutronix.de>
Acked-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>

authored by

Wolfram Sang and committed by
Dmitry Torokhov
c8f20525 2456689b

+25 -31
+6 -8
drivers/input/touchscreen/wm9705.c
··· 224 224 } 225 225 226 226 /* set up digitiser */ 227 - if (adcsel & 0x8000) 228 - adcsel = ((adcsel & 0x7fff) + 3) << 12; 229 - 230 227 if (wm->mach_ops && wm->mach_ops->pre_sample) 231 228 wm->mach_ops->pre_sample(adcsel); 232 - wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1, 233 - adcsel | WM97XX_POLL | WM97XX_DELAY(delay)); 229 + wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1, (adcsel & WM97XX_ADCSEL_MASK) 230 + | WM97XX_POLL | WM97XX_DELAY(delay)); 234 231 235 232 /* wait 3 AC97 time slots + delay for conversion */ 236 233 poll_delay(delay); ··· 253 256 wm->mach_ops->post_sample(adcsel); 254 257 255 258 /* check we have correct sample */ 256 - if ((*sample & WM97XX_ADCSEL_MASK) != adcsel) { 257 - dev_dbg(wm->dev, "adc wrong sample, read %x got %x", adcsel, 258 - *sample & WM97XX_ADCSEL_MASK); 259 + if ((*sample ^ adcsel) & WM97XX_ADCSEL_MASK) { 260 + dev_dbg(wm->dev, "adc wrong sample, wanted %x got %x", 261 + adcsel & WM97XX_ADCSEL_MASK, 262 + *sample & WM97XX_ADCSEL_MASK); 259 263 return RC_PENUP; 260 264 } 261 265
+6 -8
drivers/input/touchscreen/wm9712.c
··· 264 264 } 265 265 266 266 /* set up digitiser */ 267 - if (adcsel & 0x8000) 268 - adcsel = ((adcsel & 0x7fff) + 3) << 12; 269 - 270 267 if (wm->mach_ops && wm->mach_ops->pre_sample) 271 268 wm->mach_ops->pre_sample(adcsel); 272 - wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1, 273 - adcsel | WM97XX_POLL | WM97XX_DELAY(delay)); 269 + wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1, (adcsel & WM97XX_ADCSEL_MASK) 270 + | WM97XX_POLL | WM97XX_DELAY(delay)); 274 271 275 272 /* wait 3 AC97 time slots + delay for conversion */ 276 273 poll_delay(delay); ··· 293 296 wm->mach_ops->post_sample(adcsel); 294 297 295 298 /* check we have correct sample */ 296 - if ((*sample & WM97XX_ADCSEL_MASK) != adcsel) { 297 - dev_dbg(wm->dev, "adc wrong sample, read %x got %x", adcsel, 298 - *sample & WM97XX_ADCSEL_MASK); 299 + if ((*sample ^ adcsel) & WM97XX_ADCSEL_MASK) { 300 + dev_dbg(wm->dev, "adc wrong sample, wanted %x got %x", 301 + adcsel & WM97XX_ADCSEL_MASK, 302 + *sample & WM97XX_ADCSEL_MASK); 299 303 return RC_PENUP; 300 304 } 301 305
+9 -9
drivers/input/touchscreen/wm9713.c
··· 270 270 } 271 271 272 272 /* set up digitiser */ 273 - if (adcsel & 0x8000) 274 - adcsel = 1 << ((adcsel & 0x7fff) + 3); 275 - 276 273 dig1 = wm97xx_reg_read(wm, AC97_WM9713_DIG1); 277 274 dig1 &= ~WM9713_ADCSEL_MASK; 275 + /* WM97XX_ADCSEL_* channels need to be converted to WM9713 format */ 276 + dig1 |= 1 << ((adcsel & WM97XX_ADCSEL_MASK) >> 12); 278 277 279 278 if (wm->mach_ops && wm->mach_ops->pre_sample) 280 279 wm->mach_ops->pre_sample(adcsel); 281 - wm97xx_reg_write(wm, AC97_WM9713_DIG1, dig1 | adcsel | WM9713_POLL); 280 + wm97xx_reg_write(wm, AC97_WM9713_DIG1, dig1 | WM9713_POLL); 282 281 283 282 /* wait 3 AC97 time slots + delay for conversion */ 284 283 poll_delay(delay); ··· 303 304 wm->mach_ops->post_sample(adcsel); 304 305 305 306 /* check we have correct sample */ 306 - if ((*sample & WM97XX_ADCSEL_MASK) != ffs(adcsel >> 1) << 12) { 307 - dev_dbg(wm->dev, "adc wrong sample, read %x got %x", adcsel, 307 + if ((*sample ^ adcsel) & WM97XX_ADCSEL_MASK) { 308 + dev_dbg(wm->dev, "adc wrong sample, wanted %x got %x", 309 + adcsel & WM97XX_ADCSEL_MASK, 308 310 *sample & WM97XX_ADCSEL_MASK); 309 311 return RC_PENUP; 310 312 } ··· 400 400 if (rc != RC_VALID) 401 401 return rc; 402 402 } else { 403 - rc = wm9713_poll_sample(wm, WM9713_ADCSEL_X, &data->x); 403 + rc = wm9713_poll_sample(wm, WM97XX_ADCSEL_X, &data->x); 404 404 if (rc != RC_VALID) 405 405 return rc; 406 - rc = wm9713_poll_sample(wm, WM9713_ADCSEL_Y, &data->y); 406 + rc = wm9713_poll_sample(wm, WM97XX_ADCSEL_Y, &data->y); 407 407 if (rc != RC_VALID) 408 408 return rc; 409 409 if (pil) { 410 - rc = wm9713_poll_sample(wm, WM9713_ADCSEL_PRES, 410 + rc = wm9713_poll_sample(wm, WM97XX_ADCSEL_PRES, 411 411 &data->p); 412 412 if (rc != RC_VALID) 413 413 return rc;
+4 -6
include/linux/wm97xx.h
··· 38 38 #define WM97XX_ADCSEL_X 0x1000 /* x coord measurement */ 39 39 #define WM97XX_ADCSEL_Y 0x2000 /* y coord measurement */ 40 40 #define WM97XX_ADCSEL_PRES 0x3000 /* pressure measurement */ 41 + #define WM97XX_AUX_ID1 0x4000 42 + #define WM97XX_AUX_ID2 0x5000 43 + #define WM97XX_AUX_ID3 0x6000 44 + #define WM97XX_AUX_ID4 0x7000 41 45 #define WM97XX_ADCSEL_MASK 0x7000 /* ADC selection mask */ 42 46 #define WM97XX_COO 0x0800 /* enable coordinate mode */ 43 47 #define WM97XX_CTC 0x0400 /* enable continuous mode */ ··· 65 61 #define WM97XX_PRP_DET_DIG 0xc000 /* setect on, digitise on */ 66 62 #define WM97XX_RPR 0x2000 /* wake up on pen down */ 67 63 #define WM97XX_PEN_DOWN 0x8000 /* pen is down */ 68 - 69 - #define WM97XX_AUX_ID1 0x8001 70 - #define WM97XX_AUX_ID2 0x8002 71 - #define WM97XX_AUX_ID3 0x8003 72 - #define WM97XX_AUX_ID4 0x8004 73 - 74 64 75 65 /* WM9712 Bits */ 76 66 #define WM9712_45W 0x1000 /* set for 5-wire touchscreen */