aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/wm8711.c
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2009-08-18 16:12:30 -0400
committerMark Brown <broonie@opensource.wolfsonmicro.com>2009-08-18 16:12:30 -0400
commitd97d2e35b903b11dc6f7f8fcbe9a82fd8929e234 (patch)
tree149941c91afa80ad8ec6fa34353dc11960060420 /sound/soc/codecs/wm8711.c
parentf72222c74bd642182cc892c99df65cb105c61193 (diff)
ASoC: Factor out WM8711 cache I/O
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound/soc/codecs/wm8711.c')
-rw-r--r--sound/soc/codecs/wm8711.c114
1 files changed, 38 insertions, 76 deletions
diff --git a/sound/soc/codecs/wm8711.c b/sound/soc/codecs/wm8711.c
index 812283e27603..c7b1af89297b 100644
--- a/sound/soc/codecs/wm8711.c
+++ b/sound/soc/codecs/wm8711.c
@@ -48,55 +48,7 @@ static const u16 wm8711_reg[WM8711_CACHEREGNUM] = {
48 0x009f, 0x000a, 0x0000, 0x0000 48 0x009f, 0x000a, 0x0000, 0x0000
49}; 49};
50 50
51/* 51#define wm8711_reset(c) snd_soc_write(c, WM8711_RESET, 0)
52 * read wm8711 register cache
53 */
54static inline unsigned int wm8711_read_reg_cache(struct snd_soc_codec *codec,
55 unsigned int reg)
56{
57 u16 *cache = codec->reg_cache;
58 if (reg == WM8711_RESET)
59 return 0;
60 if (reg >= WM8711_CACHEREGNUM)
61 return -1;
62 return cache[reg];
63}
64
65/*
66 * write wm8711 register cache
67 */
68static inline void wm8711_write_reg_cache(struct snd_soc_codec *codec,
69 u16 reg, unsigned int value)
70{
71 u16 *cache = codec->reg_cache;
72 if (reg >= WM8711_CACHEREGNUM)
73 return;
74 cache[reg] = value;
75}
76
77/*
78 * write to the WM8711 register space
79 */
80static int wm8711_write(struct snd_soc_codec *codec, unsigned int reg,
81 unsigned int value)
82{
83 u8 data[2];
84
85 /* data is
86 * D15..D9 WM8753 register offset
87 * D8...D0 register data
88 */
89 data[0] = (reg << 1) | ((value >> 8) & 0x0001);
90 data[1] = value & 0x00ff;
91
92 wm8711_write_reg_cache(codec, reg, value);
93 if (codec->hw_write(codec->control_data, data, 2) == 2)
94 return 0;
95 else
96 return -EIO;
97}
98
99#define wm8711_reset(c) wm8711_write(c, WM8711_RESET, 0)
100 52
101static const struct snd_kcontrol_new wm8711_snd_controls[] = { 53static const struct snd_kcontrol_new wm8711_snd_controls[] = {
102 54
@@ -224,12 +176,12 @@ static int wm8711_hw_params(struct snd_pcm_substream *substream,
224{ 176{
225 struct snd_soc_codec *codec = dai->codec; 177 struct snd_soc_codec *codec = dai->codec;
226 struct wm8711_priv *wm8711 = codec->private_data; 178 struct wm8711_priv *wm8711 = codec->private_data;
227 u16 iface = wm8711_read_reg_cache(codec, WM8711_IFACE) & 0xfffc; 179 u16 iface = snd_soc_read(codec, WM8711_IFACE) & 0xfffc;
228 int i = get_coeff(wm8711->sysclk, params_rate(params)); 180 int i = get_coeff(wm8711->sysclk, params_rate(params));
229 u16 srate = (coeff_div[i].sr << 2) | 181 u16 srate = (coeff_div[i].sr << 2) |
230 (coeff_div[i].bosr << 1) | coeff_div[i].usb; 182 (coeff_div[i].bosr << 1) | coeff_div[i].usb;
231 183
232 wm8711_write(codec, WM8711_SRATE, srate); 184 snd_soc_write(codec, WM8711_SRATE, srate);
233 185
234 /* bit size */ 186 /* bit size */
235 switch (params_format(params)) { 187 switch (params_format(params)) {
@@ -243,7 +195,7 @@ static int wm8711_hw_params(struct snd_pcm_substream *substream,
243 break; 195 break;
244 } 196 }
245 197
246 wm8711_write(codec, WM8711_IFACE, iface); 198 snd_soc_write(codec, WM8711_IFACE, iface);
247 return 0; 199 return 0;
248} 200}
249 201
@@ -253,7 +205,7 @@ static int wm8711_pcm_prepare(struct snd_pcm_substream *substream,
253 struct snd_soc_codec *codec = dai->codec; 205 struct snd_soc_codec *codec = dai->codec;
254 206
255 /* set active */ 207 /* set active */
256 wm8711_write(codec, WM8711_ACTIVE, 0x0001); 208 snd_soc_write(codec, WM8711_ACTIVE, 0x0001);
257 209
258 return 0; 210 return 0;
259} 211}
@@ -266,19 +218,19 @@ static void wm8711_shutdown(struct snd_pcm_substream *substream,
266 /* deactivate */ 218 /* deactivate */
267 if (!codec->active) { 219 if (!codec->active) {
268 udelay(50); 220 udelay(50);
269 wm8711_write(codec, WM8711_ACTIVE, 0x0); 221 snd_soc_write(codec, WM8711_ACTIVE, 0x0);
270 } 222 }
271} 223}
272 224
273static int wm8711_mute(struct snd_soc_dai *dai, int mute) 225static int wm8711_mute(struct snd_soc_dai *dai, int mute)
274{ 226{
275 struct snd_soc_codec *codec = dai->codec; 227 struct snd_soc_codec *codec = dai->codec;
276 u16 mute_reg = wm8711_read_reg_cache(codec, WM8711_APDIGI) & 0xfff7; 228 u16 mute_reg = snd_soc_read(codec, WM8711_APDIGI) & 0xfff7;
277 229
278 if (mute) 230 if (mute)
279 wm8711_write(codec, WM8711_APDIGI, mute_reg | 0x8); 231 snd_soc_write(codec, WM8711_APDIGI, mute_reg | 0x8);
280 else 232 else
281 wm8711_write(codec, WM8711_APDIGI, mute_reg); 233 snd_soc_write(codec, WM8711_APDIGI, mute_reg);
282 234
283 return 0; 235 return 0;
284} 236}
@@ -356,7 +308,7 @@ static int wm8711_set_dai_fmt(struct snd_soc_dai *codec_dai,
356 } 308 }
357 309
358 /* set iface */ 310 /* set iface */
359 wm8711_write(codec, WM8711_IFACE, iface); 311 snd_soc_write(codec, WM8711_IFACE, iface);
360 return 0; 312 return 0;
361} 313}
362 314
@@ -364,20 +316,20 @@ static int wm8711_set_dai_fmt(struct snd_soc_dai *codec_dai,
364static int wm8711_set_bias_level(struct snd_soc_codec *codec, 316static int wm8711_set_bias_level(struct snd_soc_codec *codec,
365 enum snd_soc_bias_level level) 317 enum snd_soc_bias_level level)
366{ 318{
367 u16 reg = wm8711_read_reg_cache(codec, WM8711_PWR) & 0xff7f; 319 u16 reg = snd_soc_read(codec, WM8711_PWR) & 0xff7f;
368 320
369 switch (level) { 321 switch (level) {
370 case SND_SOC_BIAS_ON: 322 case SND_SOC_BIAS_ON:
371 wm8711_write(codec, WM8711_PWR, reg); 323 snd_soc_write(codec, WM8711_PWR, reg);
372 break; 324 break;
373 case SND_SOC_BIAS_PREPARE: 325 case SND_SOC_BIAS_PREPARE:
374 break; 326 break;
375 case SND_SOC_BIAS_STANDBY: 327 case SND_SOC_BIAS_STANDBY:
376 wm8711_write(codec, WM8711_PWR, reg | 0x0040); 328 snd_soc_write(codec, WM8711_PWR, reg | 0x0040);
377 break; 329 break;
378 case SND_SOC_BIAS_OFF: 330 case SND_SOC_BIAS_OFF:
379 wm8711_write(codec, WM8711_ACTIVE, 0x0); 331 snd_soc_write(codec, WM8711_ACTIVE, 0x0);
380 wm8711_write(codec, WM8711_PWR, 0xffff); 332 snd_soc_write(codec, WM8711_PWR, 0xffff);
381 break; 333 break;
382 } 334 }
383 codec->bias_level = level; 335 codec->bias_level = level;
@@ -419,7 +371,7 @@ static int wm8711_suspend(struct platform_device *pdev, pm_message_t state)
419 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 371 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
420 struct snd_soc_codec *codec = socdev->card->codec; 372 struct snd_soc_codec *codec = socdev->card->codec;
421 373
422 wm8711_write(codec, WM8711_ACTIVE, 0x0); 374 snd_soc_write(codec, WM8711_ACTIVE, 0x0);
423 wm8711_set_bias_level(codec, SND_SOC_BIAS_OFF); 375 wm8711_set_bias_level(codec, SND_SOC_BIAS_OFF);
424 return 0; 376 return 0;
425} 377}
@@ -501,7 +453,8 @@ struct snd_soc_codec_device soc_codec_dev_wm8711 = {
501}; 453};
502EXPORT_SYMBOL_GPL(soc_codec_dev_wm8711); 454EXPORT_SYMBOL_GPL(soc_codec_dev_wm8711);
503 455
504static int wm8711_register(struct wm8711_priv *wm8711) 456static int wm8711_register(struct wm8711_priv *wm8711,
457 enum snd_soc_control_type control)
505{ 458{
506 int ret; 459 int ret;
507 struct snd_soc_codec *codec = &wm8711->codec; 460 struct snd_soc_codec *codec = &wm8711->codec;
@@ -519,8 +472,6 @@ static int wm8711_register(struct wm8711_priv *wm8711)
519 codec->private_data = wm8711; 472 codec->private_data = wm8711;
520 codec->name = "WM8711"; 473 codec->name = "WM8711";
521 codec->owner = THIS_MODULE; 474 codec->owner = THIS_MODULE;
522 codec->read = wm8711_read_reg_cache;
523 codec->write = wm8711_write;
524 codec->bias_level = SND_SOC_BIAS_OFF; 475 codec->bias_level = SND_SOC_BIAS_OFF;
525 codec->set_bias_level = wm8711_set_bias_level; 476 codec->set_bias_level = wm8711_set_bias_level;
526 codec->dai = &wm8711_dai; 477 codec->dai = &wm8711_dai;
@@ -530,10 +481,16 @@ static int wm8711_register(struct wm8711_priv *wm8711)
530 481
531 memcpy(codec->reg_cache, wm8711_reg, sizeof(wm8711_reg)); 482 memcpy(codec->reg_cache, wm8711_reg, sizeof(wm8711_reg));
532 483
484 ret = snd_soc_codec_set_cache_io(codec, 7, 9, control);
485 if (ret < 0) {
486 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
487 goto err;
488 }
489
533 ret = wm8711_reset(codec); 490 ret = wm8711_reset(codec);
534 if (ret < 0) { 491 if (ret < 0) {
535 dev_err(codec->dev, "Failed to issue reset\n"); 492 dev_err(codec->dev, "Failed to issue reset\n");
536 return ret; 493 goto err;
537 } 494 }
538 495
539 wm8711_dai.dev = codec->dev; 496 wm8711_dai.dev = codec->dev;
@@ -541,27 +498,32 @@ static int wm8711_register(struct wm8711_priv *wm8711)
541 wm8711_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 498 wm8711_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
542 499
543 /* Latch the update bits */ 500 /* Latch the update bits */
544 reg = wm8711_read_reg_cache(codec, WM8711_LOUT1V); 501 reg = snd_soc_read(codec, WM8711_LOUT1V);
545 wm8711_write(codec, WM8711_LOUT1V, reg | 0x0100); 502 snd_soc_write(codec, WM8711_LOUT1V, reg | 0x0100);
546 reg = wm8711_read_reg_cache(codec, WM8711_ROUT1V); 503 reg = snd_soc_read(codec, WM8711_ROUT1V);
547 wm8711_write(codec, WM8711_ROUT1V, reg | 0x0100); 504 snd_soc_write(codec, WM8711_ROUT1V, reg | 0x0100);
548 505
549 wm8711_codec = codec; 506 wm8711_codec = codec;
550 507
551 ret = snd_soc_register_codec(codec); 508 ret = snd_soc_register_codec(codec);
552 if (ret != 0) { 509 if (ret != 0) {
553 dev_err(codec->dev, "Failed to register codec: %d\n", ret); 510 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
554 return ret; 511 goto err;
555 } 512 }
556 513
557 ret = snd_soc_register_dai(&wm8711_dai); 514 ret = snd_soc_register_dai(&wm8711_dai);
558 if (ret != 0) { 515 if (ret != 0) {
559 dev_err(codec->dev, "Failed to register DAI: %d\n", ret); 516 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
560 snd_soc_unregister_codec(codec); 517 goto err_codec;
561 return ret;
562 } 518 }
563 519
564 return 0; 520 return 0;
521
522err_codec:
523 snd_soc_unregister_codec(codec);
524err:
525 kfree(wm8711);
526 return ret;
565} 527}
566 528
567static void wm8711_unregister(struct wm8711_priv *wm8711) 529static void wm8711_unregister(struct wm8711_priv *wm8711)
@@ -592,7 +554,7 @@ static __devinit int wm8711_i2c_probe(struct i2c_client *i2c,
592 554
593 codec->dev = &i2c->dev; 555 codec->dev = &i2c->dev;
594 556
595 return wm8711_register(wm8711); 557 return wm8711_register(wm8711, SND_SOC_I2C);
596} 558}
597 559
598static __devexit int wm8711_i2c_remove(struct i2c_client *client) 560static __devexit int wm8711_i2c_remove(struct i2c_client *client)