diff options
Diffstat (limited to 'sound/soc/codecs/wm8961.c')
-rw-r--r-- | sound/soc/codecs/wm8961.c | 231 |
1 files changed, 85 insertions, 146 deletions
diff --git a/sound/soc/codecs/wm8961.c b/sound/soc/codecs/wm8961.c index bd1af92a122f..503032085899 100644 --- a/sound/soc/codecs/wm8961.c +++ b/sound/soc/codecs/wm8961.c | |||
@@ -292,9 +292,10 @@ struct wm8961_priv { | |||
292 | u16 reg_cache[WM8961_MAX_REGISTER]; | 292 | u16 reg_cache[WM8961_MAX_REGISTER]; |
293 | }; | 293 | }; |
294 | 294 | ||
295 | static int wm8961_reg_is_volatile(int reg) | 295 | static int wm8961_volatile_register(unsigned int reg) |
296 | { | 296 | { |
297 | switch (reg) { | 297 | switch (reg) { |
298 | case WM8961_SOFTWARE_RESET: | ||
298 | case WM8961_WRITE_SEQUENCER_7: | 299 | case WM8961_WRITE_SEQUENCER_7: |
299 | case WM8961_DC_SERVO_1: | 300 | case WM8961_DC_SERVO_1: |
300 | return 1; | 301 | return 1; |
@@ -304,76 +305,9 @@ static int wm8961_reg_is_volatile(int reg) | |||
304 | } | 305 | } |
305 | } | 306 | } |
306 | 307 | ||
307 | static unsigned int wm8961_read_reg_cache(struct snd_soc_codec *codec, | ||
308 | unsigned int reg) | ||
309 | { | ||
310 | u16 *cache = codec->reg_cache; | ||
311 | BUG_ON(reg > WM8961_MAX_REGISTER); | ||
312 | return cache[reg]; | ||
313 | } | ||
314 | |||
315 | static unsigned int wm8961_read_hw(struct snd_soc_codec *codec, u8 reg) | ||
316 | { | ||
317 | struct i2c_msg xfer[2]; | ||
318 | u16 data; | ||
319 | int ret; | ||
320 | struct i2c_client *client = codec->control_data; | ||
321 | |||
322 | BUG_ON(reg > WM8961_MAX_REGISTER); | ||
323 | |||
324 | /* Write register */ | ||
325 | xfer[0].addr = client->addr; | ||
326 | xfer[0].flags = 0; | ||
327 | xfer[0].len = 1; | ||
328 | xfer[0].buf = ® | ||
329 | |||
330 | /* Read data */ | ||
331 | xfer[1].addr = client->addr; | ||
332 | xfer[1].flags = I2C_M_RD; | ||
333 | xfer[1].len = 2; | ||
334 | xfer[1].buf = (u8 *)&data; | ||
335 | |||
336 | ret = i2c_transfer(client->adapter, xfer, 2); | ||
337 | if (ret != 2) { | ||
338 | dev_err(&client->dev, "i2c_transfer() returned %d\n", ret); | ||
339 | return 0; | ||
340 | } | ||
341 | |||
342 | return (data >> 8) | ((data & 0xff) << 8); | ||
343 | } | ||
344 | |||
345 | static unsigned int wm8961_read(struct snd_soc_codec *codec, unsigned int reg) | ||
346 | { | ||
347 | if (wm8961_reg_is_volatile(reg)) | ||
348 | return wm8961_read_hw(codec, reg); | ||
349 | else | ||
350 | return wm8961_read_reg_cache(codec, reg); | ||
351 | } | ||
352 | |||
353 | static int wm8961_write(struct snd_soc_codec *codec, unsigned int reg, | ||
354 | unsigned int value) | ||
355 | { | ||
356 | u16 *cache = codec->reg_cache; | ||
357 | u8 data[3]; | ||
358 | |||
359 | BUG_ON(reg > WM8961_MAX_REGISTER); | ||
360 | |||
361 | if (!wm8961_reg_is_volatile(reg)) | ||
362 | cache[reg] = value; | ||
363 | |||
364 | data[0] = reg; | ||
365 | data[1] = value >> 8; | ||
366 | data[2] = value & 0x00ff; | ||
367 | |||
368 | if (codec->hw_write(codec->control_data, data, 3) == 3) | ||
369 | return 0; | ||
370 | else | ||
371 | return -EIO; | ||
372 | } | ||
373 | |||
374 | static int wm8961_reset(struct snd_soc_codec *codec) | 308 | static int wm8961_reset(struct snd_soc_codec *codec) |
375 | { | 309 | { |
376 | return wm8961_write(codec, WM8961_SOFTWARE_RESET, 0); | 310 | return snd_soc_write(codec, WM8961_SOFTWARE_RESET, 0); |
377 | } | 311 | } |
378 | 312 | ||
379 | /* | 313 | /* |
@@ -384,33 +318,33 @@ static int wm8961_hp_event(struct snd_soc_dapm_widget *w, | |||
384 | struct snd_kcontrol *kcontrol, int event) | 318 | struct snd_kcontrol *kcontrol, int event) |
385 | { | 319 | { |
386 | struct snd_soc_codec *codec = w->codec; | 320 | struct snd_soc_codec *codec = w->codec; |
387 | u16 hp_reg = wm8961_read(codec, WM8961_ANALOGUE_HP_0); | 321 | u16 hp_reg = snd_soc_read(codec, WM8961_ANALOGUE_HP_0); |
388 | u16 cp_reg = wm8961_read(codec, WM8961_CHARGE_PUMP_1); | 322 | u16 cp_reg = snd_soc_read(codec, WM8961_CHARGE_PUMP_1); |
389 | u16 pwr_reg = wm8961_read(codec, WM8961_PWR_MGMT_2); | 323 | u16 pwr_reg = snd_soc_read(codec, WM8961_PWR_MGMT_2); |
390 | u16 dcs_reg = wm8961_read(codec, WM8961_DC_SERVO_1); | 324 | u16 dcs_reg = snd_soc_read(codec, WM8961_DC_SERVO_1); |
391 | int timeout = 500; | 325 | int timeout = 500; |
392 | 326 | ||
393 | if (event & SND_SOC_DAPM_POST_PMU) { | 327 | if (event & SND_SOC_DAPM_POST_PMU) { |
394 | /* Make sure the output is shorted */ | 328 | /* Make sure the output is shorted */ |
395 | hp_reg &= ~(WM8961_HPR_RMV_SHORT | WM8961_HPL_RMV_SHORT); | 329 | hp_reg &= ~(WM8961_HPR_RMV_SHORT | WM8961_HPL_RMV_SHORT); |
396 | wm8961_write(codec, WM8961_ANALOGUE_HP_0, hp_reg); | 330 | snd_soc_write(codec, WM8961_ANALOGUE_HP_0, hp_reg); |
397 | 331 | ||
398 | /* Enable the charge pump */ | 332 | /* Enable the charge pump */ |
399 | cp_reg |= WM8961_CP_ENA; | 333 | cp_reg |= WM8961_CP_ENA; |
400 | wm8961_write(codec, WM8961_CHARGE_PUMP_1, cp_reg); | 334 | snd_soc_write(codec, WM8961_CHARGE_PUMP_1, cp_reg); |
401 | mdelay(5); | 335 | mdelay(5); |
402 | 336 | ||
403 | /* Enable the PGA */ | 337 | /* Enable the PGA */ |
404 | pwr_reg |= WM8961_LOUT1_PGA | WM8961_ROUT1_PGA; | 338 | pwr_reg |= WM8961_LOUT1_PGA | WM8961_ROUT1_PGA; |
405 | wm8961_write(codec, WM8961_PWR_MGMT_2, pwr_reg); | 339 | snd_soc_write(codec, WM8961_PWR_MGMT_2, pwr_reg); |
406 | 340 | ||
407 | /* Enable the amplifier */ | 341 | /* Enable the amplifier */ |
408 | hp_reg |= WM8961_HPR_ENA | WM8961_HPL_ENA; | 342 | hp_reg |= WM8961_HPR_ENA | WM8961_HPL_ENA; |
409 | wm8961_write(codec, WM8961_ANALOGUE_HP_0, hp_reg); | 343 | snd_soc_write(codec, WM8961_ANALOGUE_HP_0, hp_reg); |
410 | 344 | ||
411 | /* Second stage enable */ | 345 | /* Second stage enable */ |
412 | hp_reg |= WM8961_HPR_ENA_DLY | WM8961_HPL_ENA_DLY; | 346 | hp_reg |= WM8961_HPR_ENA_DLY | WM8961_HPL_ENA_DLY; |
413 | wm8961_write(codec, WM8961_ANALOGUE_HP_0, hp_reg); | 347 | snd_soc_write(codec, WM8961_ANALOGUE_HP_0, hp_reg); |
414 | 348 | ||
415 | /* Enable the DC servo & trigger startup */ | 349 | /* Enable the DC servo & trigger startup */ |
416 | dcs_reg |= | 350 | dcs_reg |= |
@@ -418,10 +352,10 @@ static int wm8961_hp_event(struct snd_soc_dapm_widget *w, | |||
418 | WM8961_DCS_ENA_CHAN_HPL | WM8961_DCS_TRIG_STARTUP_HPL; | 352 | WM8961_DCS_ENA_CHAN_HPL | WM8961_DCS_TRIG_STARTUP_HPL; |
419 | dev_dbg(codec->dev, "Enabling DC servo\n"); | 353 | dev_dbg(codec->dev, "Enabling DC servo\n"); |
420 | 354 | ||
421 | wm8961_write(codec, WM8961_DC_SERVO_1, dcs_reg); | 355 | snd_soc_write(codec, WM8961_DC_SERVO_1, dcs_reg); |
422 | do { | 356 | do { |
423 | msleep(1); | 357 | msleep(1); |
424 | dcs_reg = wm8961_read(codec, WM8961_DC_SERVO_1); | 358 | dcs_reg = snd_soc_read(codec, WM8961_DC_SERVO_1); |
425 | } while (--timeout && | 359 | } while (--timeout && |
426 | dcs_reg & (WM8961_DCS_TRIG_STARTUP_HPR | | 360 | dcs_reg & (WM8961_DCS_TRIG_STARTUP_HPR | |
427 | WM8961_DCS_TRIG_STARTUP_HPL)); | 361 | WM8961_DCS_TRIG_STARTUP_HPL)); |
@@ -433,39 +367,39 @@ static int wm8961_hp_event(struct snd_soc_dapm_widget *w, | |||
433 | 367 | ||
434 | /* Enable the output stage */ | 368 | /* Enable the output stage */ |
435 | hp_reg |= WM8961_HPR_ENA_OUTP | WM8961_HPL_ENA_OUTP; | 369 | hp_reg |= WM8961_HPR_ENA_OUTP | WM8961_HPL_ENA_OUTP; |
436 | wm8961_write(codec, WM8961_ANALOGUE_HP_0, hp_reg); | 370 | snd_soc_write(codec, WM8961_ANALOGUE_HP_0, hp_reg); |
437 | 371 | ||
438 | /* Remove the short on the output stage */ | 372 | /* Remove the short on the output stage */ |
439 | hp_reg |= WM8961_HPR_RMV_SHORT | WM8961_HPL_RMV_SHORT; | 373 | hp_reg |= WM8961_HPR_RMV_SHORT | WM8961_HPL_RMV_SHORT; |
440 | wm8961_write(codec, WM8961_ANALOGUE_HP_0, hp_reg); | 374 | snd_soc_write(codec, WM8961_ANALOGUE_HP_0, hp_reg); |
441 | } | 375 | } |
442 | 376 | ||
443 | if (event & SND_SOC_DAPM_PRE_PMD) { | 377 | if (event & SND_SOC_DAPM_PRE_PMD) { |
444 | /* Short the output */ | 378 | /* Short the output */ |
445 | hp_reg &= ~(WM8961_HPR_RMV_SHORT | WM8961_HPL_RMV_SHORT); | 379 | hp_reg &= ~(WM8961_HPR_RMV_SHORT | WM8961_HPL_RMV_SHORT); |
446 | wm8961_write(codec, WM8961_ANALOGUE_HP_0, hp_reg); | 380 | snd_soc_write(codec, WM8961_ANALOGUE_HP_0, hp_reg); |
447 | 381 | ||
448 | /* Disable the output stage */ | 382 | /* Disable the output stage */ |
449 | hp_reg &= ~(WM8961_HPR_ENA_OUTP | WM8961_HPL_ENA_OUTP); | 383 | hp_reg &= ~(WM8961_HPR_ENA_OUTP | WM8961_HPL_ENA_OUTP); |
450 | wm8961_write(codec, WM8961_ANALOGUE_HP_0, hp_reg); | 384 | snd_soc_write(codec, WM8961_ANALOGUE_HP_0, hp_reg); |
451 | 385 | ||
452 | /* Disable DC offset cancellation */ | 386 | /* Disable DC offset cancellation */ |
453 | dcs_reg &= ~(WM8961_DCS_ENA_CHAN_HPR | | 387 | dcs_reg &= ~(WM8961_DCS_ENA_CHAN_HPR | |
454 | WM8961_DCS_ENA_CHAN_HPL); | 388 | WM8961_DCS_ENA_CHAN_HPL); |
455 | wm8961_write(codec, WM8961_DC_SERVO_1, dcs_reg); | 389 | snd_soc_write(codec, WM8961_DC_SERVO_1, dcs_reg); |
456 | 390 | ||
457 | /* Finish up */ | 391 | /* Finish up */ |
458 | hp_reg &= ~(WM8961_HPR_ENA_DLY | WM8961_HPR_ENA | | 392 | hp_reg &= ~(WM8961_HPR_ENA_DLY | WM8961_HPR_ENA | |
459 | WM8961_HPL_ENA_DLY | WM8961_HPL_ENA); | 393 | WM8961_HPL_ENA_DLY | WM8961_HPL_ENA); |
460 | wm8961_write(codec, WM8961_ANALOGUE_HP_0, hp_reg); | 394 | snd_soc_write(codec, WM8961_ANALOGUE_HP_0, hp_reg); |
461 | 395 | ||
462 | /* Disable the PGA */ | 396 | /* Disable the PGA */ |
463 | pwr_reg &= ~(WM8961_LOUT1_PGA | WM8961_ROUT1_PGA); | 397 | pwr_reg &= ~(WM8961_LOUT1_PGA | WM8961_ROUT1_PGA); |
464 | wm8961_write(codec, WM8961_PWR_MGMT_2, pwr_reg); | 398 | snd_soc_write(codec, WM8961_PWR_MGMT_2, pwr_reg); |
465 | 399 | ||
466 | /* Disable the charge pump */ | 400 | /* Disable the charge pump */ |
467 | dev_dbg(codec->dev, "Disabling charge pump\n"); | 401 | dev_dbg(codec->dev, "Disabling charge pump\n"); |
468 | wm8961_write(codec, WM8961_CHARGE_PUMP_1, | 402 | snd_soc_write(codec, WM8961_CHARGE_PUMP_1, |
469 | cp_reg & ~WM8961_CP_ENA); | 403 | cp_reg & ~WM8961_CP_ENA); |
470 | } | 404 | } |
471 | 405 | ||
@@ -476,27 +410,27 @@ static int wm8961_spk_event(struct snd_soc_dapm_widget *w, | |||
476 | struct snd_kcontrol *kcontrol, int event) | 410 | struct snd_kcontrol *kcontrol, int event) |
477 | { | 411 | { |
478 | struct snd_soc_codec *codec = w->codec; | 412 | struct snd_soc_codec *codec = w->codec; |
479 | u16 pwr_reg = wm8961_read(codec, WM8961_PWR_MGMT_2); | 413 | u16 pwr_reg = snd_soc_read(codec, WM8961_PWR_MGMT_2); |
480 | u16 spk_reg = wm8961_read(codec, WM8961_CLASS_D_CONTROL_1); | 414 | u16 spk_reg = snd_soc_read(codec, WM8961_CLASS_D_CONTROL_1); |
481 | 415 | ||
482 | if (event & SND_SOC_DAPM_POST_PMU) { | 416 | if (event & SND_SOC_DAPM_POST_PMU) { |
483 | /* Enable the PGA */ | 417 | /* Enable the PGA */ |
484 | pwr_reg |= WM8961_SPKL_PGA | WM8961_SPKR_PGA; | 418 | pwr_reg |= WM8961_SPKL_PGA | WM8961_SPKR_PGA; |
485 | wm8961_write(codec, WM8961_PWR_MGMT_2, pwr_reg); | 419 | snd_soc_write(codec, WM8961_PWR_MGMT_2, pwr_reg); |
486 | 420 | ||
487 | /* Enable the amplifier */ | 421 | /* Enable the amplifier */ |
488 | spk_reg |= WM8961_SPKL_ENA | WM8961_SPKR_ENA; | 422 | spk_reg |= WM8961_SPKL_ENA | WM8961_SPKR_ENA; |
489 | wm8961_write(codec, WM8961_CLASS_D_CONTROL_1, spk_reg); | 423 | snd_soc_write(codec, WM8961_CLASS_D_CONTROL_1, spk_reg); |
490 | } | 424 | } |
491 | 425 | ||
492 | if (event & SND_SOC_DAPM_PRE_PMD) { | 426 | if (event & SND_SOC_DAPM_PRE_PMD) { |
493 | /* Enable the amplifier */ | 427 | /* Enable the amplifier */ |
494 | spk_reg &= ~(WM8961_SPKL_ENA | WM8961_SPKR_ENA); | 428 | spk_reg &= ~(WM8961_SPKL_ENA | WM8961_SPKR_ENA); |
495 | wm8961_write(codec, WM8961_CLASS_D_CONTROL_1, spk_reg); | 429 | snd_soc_write(codec, WM8961_CLASS_D_CONTROL_1, spk_reg); |
496 | 430 | ||
497 | /* Enable the PGA */ | 431 | /* Enable the PGA */ |
498 | pwr_reg &= ~(WM8961_SPKL_PGA | WM8961_SPKR_PGA); | 432 | pwr_reg &= ~(WM8961_SPKL_PGA | WM8961_SPKR_PGA); |
499 | wm8961_write(codec, WM8961_PWR_MGMT_2, pwr_reg); | 433 | snd_soc_write(codec, WM8961_PWR_MGMT_2, pwr_reg); |
500 | } | 434 | } |
501 | 435 | ||
502 | return 0; | 436 | return 0; |
@@ -714,10 +648,10 @@ static int wm8961_hw_params(struct snd_pcm_substream *substream, | |||
714 | abs(wm8961_srate[best].rate - fs)) | 648 | abs(wm8961_srate[best].rate - fs)) |
715 | best = i; | 649 | best = i; |
716 | } | 650 | } |
717 | reg = wm8961_read(codec, WM8961_ADDITIONAL_CONTROL_3); | 651 | reg = snd_soc_read(codec, WM8961_ADDITIONAL_CONTROL_3); |
718 | reg &= ~WM8961_SAMPLE_RATE_MASK; | 652 | reg &= ~WM8961_SAMPLE_RATE_MASK; |
719 | reg |= wm8961_srate[best].val; | 653 | reg |= wm8961_srate[best].val; |
720 | wm8961_write(codec, WM8961_ADDITIONAL_CONTROL_3, reg); | 654 | snd_soc_write(codec, WM8961_ADDITIONAL_CONTROL_3, reg); |
721 | dev_dbg(codec->dev, "Selected SRATE %dHz for %dHz\n", | 655 | dev_dbg(codec->dev, "Selected SRATE %dHz for %dHz\n", |
722 | wm8961_srate[best].rate, fs); | 656 | wm8961_srate[best].rate, fs); |
723 | 657 | ||
@@ -747,12 +681,12 @@ static int wm8961_hw_params(struct snd_pcm_substream *substream, | |||
747 | wm8961_clk_sys_ratio[i].ratio, wm8961->sysclk, fs, | 681 | wm8961_clk_sys_ratio[i].ratio, wm8961->sysclk, fs, |
748 | wm8961->sysclk / fs); | 682 | wm8961->sysclk / fs); |
749 | 683 | ||
750 | reg = wm8961_read(codec, WM8961_CLOCKING_4); | 684 | reg = snd_soc_read(codec, WM8961_CLOCKING_4); |
751 | reg &= ~WM8961_CLK_SYS_RATE_MASK; | 685 | reg &= ~WM8961_CLK_SYS_RATE_MASK; |
752 | reg |= wm8961_clk_sys_ratio[i].val << WM8961_CLK_SYS_RATE_SHIFT; | 686 | reg |= wm8961_clk_sys_ratio[i].val << WM8961_CLK_SYS_RATE_SHIFT; |
753 | wm8961_write(codec, WM8961_CLOCKING_4, reg); | 687 | snd_soc_write(codec, WM8961_CLOCKING_4, reg); |
754 | 688 | ||
755 | reg = wm8961_read(codec, WM8961_AUDIO_INTERFACE_0); | 689 | reg = snd_soc_read(codec, WM8961_AUDIO_INTERFACE_0); |
756 | reg &= ~WM8961_WL_MASK; | 690 | reg &= ~WM8961_WL_MASK; |
757 | switch (params_format(params)) { | 691 | switch (params_format(params)) { |
758 | case SNDRV_PCM_FORMAT_S16_LE: | 692 | case SNDRV_PCM_FORMAT_S16_LE: |
@@ -769,15 +703,15 @@ static int wm8961_hw_params(struct snd_pcm_substream *substream, | |||
769 | default: | 703 | default: |
770 | return -EINVAL; | 704 | return -EINVAL; |
771 | } | 705 | } |
772 | wm8961_write(codec, WM8961_AUDIO_INTERFACE_0, reg); | 706 | snd_soc_write(codec, WM8961_AUDIO_INTERFACE_0, reg); |
773 | 707 | ||
774 | /* Sloping stop-band filter is recommended for <= 24kHz */ | 708 | /* Sloping stop-band filter is recommended for <= 24kHz */ |
775 | reg = wm8961_read(codec, WM8961_ADC_DAC_CONTROL_2); | 709 | reg = snd_soc_read(codec, WM8961_ADC_DAC_CONTROL_2); |
776 | if (fs <= 24000) | 710 | if (fs <= 24000) |
777 | reg |= WM8961_DACSLOPE; | 711 | reg |= WM8961_DACSLOPE; |
778 | else | 712 | else |
779 | reg &= WM8961_DACSLOPE; | 713 | reg &= WM8961_DACSLOPE; |
780 | wm8961_write(codec, WM8961_ADC_DAC_CONTROL_2, reg); | 714 | snd_soc_write(codec, WM8961_ADC_DAC_CONTROL_2, reg); |
781 | 715 | ||
782 | return 0; | 716 | return 0; |
783 | } | 717 | } |
@@ -788,7 +722,7 @@ static int wm8961_set_sysclk(struct snd_soc_dai *dai, int clk_id, | |||
788 | { | 722 | { |
789 | struct snd_soc_codec *codec = dai->codec; | 723 | struct snd_soc_codec *codec = dai->codec; |
790 | struct wm8961_priv *wm8961 = codec->private_data; | 724 | struct wm8961_priv *wm8961 = codec->private_data; |
791 | u16 reg = wm8961_read(codec, WM8961_CLOCKING1); | 725 | u16 reg = snd_soc_read(codec, WM8961_CLOCKING1); |
792 | 726 | ||
793 | if (freq > 33000000) { | 727 | if (freq > 33000000) { |
794 | dev_err(codec->dev, "MCLK must be <33MHz\n"); | 728 | dev_err(codec->dev, "MCLK must be <33MHz\n"); |
@@ -804,7 +738,7 @@ static int wm8961_set_sysclk(struct snd_soc_dai *dai, int clk_id, | |||
804 | reg &= WM8961_MCLKDIV; | 738 | reg &= WM8961_MCLKDIV; |
805 | } | 739 | } |
806 | 740 | ||
807 | wm8961_write(codec, WM8961_CLOCKING1, reg); | 741 | snd_soc_write(codec, WM8961_CLOCKING1, reg); |
808 | 742 | ||
809 | wm8961->sysclk = freq; | 743 | wm8961->sysclk = freq; |
810 | 744 | ||
@@ -814,7 +748,7 @@ static int wm8961_set_sysclk(struct snd_soc_dai *dai, int clk_id, | |||
814 | static int wm8961_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) | 748 | static int wm8961_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) |
815 | { | 749 | { |
816 | struct snd_soc_codec *codec = dai->codec; | 750 | struct snd_soc_codec *codec = dai->codec; |
817 | u16 aif = wm8961_read(codec, WM8961_AUDIO_INTERFACE_0); | 751 | u16 aif = snd_soc_read(codec, WM8961_AUDIO_INTERFACE_0); |
818 | 752 | ||
819 | aif &= ~(WM8961_BCLKINV | WM8961_LRP | | 753 | aif &= ~(WM8961_BCLKINV | WM8961_LRP | |
820 | WM8961_MS | WM8961_FORMAT_MASK); | 754 | WM8961_MS | WM8961_FORMAT_MASK); |
@@ -874,26 +808,26 @@ static int wm8961_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) | |||
874 | return -EINVAL; | 808 | return -EINVAL; |
875 | } | 809 | } |
876 | 810 | ||
877 | return wm8961_write(codec, WM8961_AUDIO_INTERFACE_0, aif); | 811 | return snd_soc_write(codec, WM8961_AUDIO_INTERFACE_0, aif); |
878 | } | 812 | } |
879 | 813 | ||
880 | static int wm8961_set_tristate(struct snd_soc_dai *dai, int tristate) | 814 | static int wm8961_set_tristate(struct snd_soc_dai *dai, int tristate) |
881 | { | 815 | { |
882 | struct snd_soc_codec *codec = dai->codec; | 816 | struct snd_soc_codec *codec = dai->codec; |
883 | u16 reg = wm8961_read(codec, WM8961_ADDITIONAL_CONTROL_2); | 817 | u16 reg = snd_soc_read(codec, WM8961_ADDITIONAL_CONTROL_2); |
884 | 818 | ||
885 | if (tristate) | 819 | if (tristate) |
886 | reg |= WM8961_TRIS; | 820 | reg |= WM8961_TRIS; |
887 | else | 821 | else |
888 | reg &= ~WM8961_TRIS; | 822 | reg &= ~WM8961_TRIS; |
889 | 823 | ||
890 | return wm8961_write(codec, WM8961_ADDITIONAL_CONTROL_2, reg); | 824 | return snd_soc_write(codec, WM8961_ADDITIONAL_CONTROL_2, reg); |
891 | } | 825 | } |
892 | 826 | ||
893 | static int wm8961_digital_mute(struct snd_soc_dai *dai, int mute) | 827 | static int wm8961_digital_mute(struct snd_soc_dai *dai, int mute) |
894 | { | 828 | { |
895 | struct snd_soc_codec *codec = dai->codec; | 829 | struct snd_soc_codec *codec = dai->codec; |
896 | u16 reg = wm8961_read(codec, WM8961_ADC_DAC_CONTROL_1); | 830 | u16 reg = snd_soc_read(codec, WM8961_ADC_DAC_CONTROL_1); |
897 | 831 | ||
898 | if (mute) | 832 | if (mute) |
899 | reg |= WM8961_DACMU; | 833 | reg |= WM8961_DACMU; |
@@ -902,7 +836,7 @@ static int wm8961_digital_mute(struct snd_soc_dai *dai, int mute) | |||
902 | 836 | ||
903 | msleep(17); | 837 | msleep(17); |
904 | 838 | ||
905 | return wm8961_write(codec, WM8961_ADC_DAC_CONTROL_1, reg); | 839 | return snd_soc_write(codec, WM8961_ADC_DAC_CONTROL_1, reg); |
906 | } | 840 | } |
907 | 841 | ||
908 | static int wm8961_set_clkdiv(struct snd_soc_dai *dai, int div_id, int div) | 842 | static int wm8961_set_clkdiv(struct snd_soc_dai *dai, int div_id, int div) |
@@ -912,17 +846,17 @@ static int wm8961_set_clkdiv(struct snd_soc_dai *dai, int div_id, int div) | |||
912 | 846 | ||
913 | switch (div_id) { | 847 | switch (div_id) { |
914 | case WM8961_BCLK: | 848 | case WM8961_BCLK: |
915 | reg = wm8961_read(codec, WM8961_CLOCKING2); | 849 | reg = snd_soc_read(codec, WM8961_CLOCKING2); |
916 | reg &= ~WM8961_BCLKDIV_MASK; | 850 | reg &= ~WM8961_BCLKDIV_MASK; |
917 | reg |= div; | 851 | reg |= div; |
918 | wm8961_write(codec, WM8961_CLOCKING2, reg); | 852 | snd_soc_write(codec, WM8961_CLOCKING2, reg); |
919 | break; | 853 | break; |
920 | 854 | ||
921 | case WM8961_LRCLK: | 855 | case WM8961_LRCLK: |
922 | reg = wm8961_read(codec, WM8961_AUDIO_INTERFACE_2); | 856 | reg = snd_soc_read(codec, WM8961_AUDIO_INTERFACE_2); |
923 | reg &= ~WM8961_LRCLK_RATE_MASK; | 857 | reg &= ~WM8961_LRCLK_RATE_MASK; |
924 | reg |= div; | 858 | reg |= div; |
925 | wm8961_write(codec, WM8961_AUDIO_INTERFACE_2, reg); | 859 | snd_soc_write(codec, WM8961_AUDIO_INTERFACE_2, reg); |
926 | break; | 860 | break; |
927 | 861 | ||
928 | default: | 862 | default: |
@@ -949,34 +883,34 @@ static int wm8961_set_bias_level(struct snd_soc_codec *codec, | |||
949 | case SND_SOC_BIAS_PREPARE: | 883 | case SND_SOC_BIAS_PREPARE: |
950 | if (codec->bias_level == SND_SOC_BIAS_STANDBY) { | 884 | if (codec->bias_level == SND_SOC_BIAS_STANDBY) { |
951 | /* Enable bias generation */ | 885 | /* Enable bias generation */ |
952 | reg = wm8961_read(codec, WM8961_ANTI_POP); | 886 | reg = snd_soc_read(codec, WM8961_ANTI_POP); |
953 | reg |= WM8961_BUFIOEN | WM8961_BUFDCOPEN; | 887 | reg |= WM8961_BUFIOEN | WM8961_BUFDCOPEN; |
954 | wm8961_write(codec, WM8961_ANTI_POP, reg); | 888 | snd_soc_write(codec, WM8961_ANTI_POP, reg); |
955 | 889 | ||
956 | /* VMID=2*50k, VREF */ | 890 | /* VMID=2*50k, VREF */ |
957 | reg = wm8961_read(codec, WM8961_PWR_MGMT_1); | 891 | reg = snd_soc_read(codec, WM8961_PWR_MGMT_1); |
958 | reg &= ~WM8961_VMIDSEL_MASK; | 892 | reg &= ~WM8961_VMIDSEL_MASK; |
959 | reg |= (1 << WM8961_VMIDSEL_SHIFT) | WM8961_VREF; | 893 | reg |= (1 << WM8961_VMIDSEL_SHIFT) | WM8961_VREF; |
960 | wm8961_write(codec, WM8961_PWR_MGMT_1, reg); | 894 | snd_soc_write(codec, WM8961_PWR_MGMT_1, reg); |
961 | } | 895 | } |
962 | break; | 896 | break; |
963 | 897 | ||
964 | case SND_SOC_BIAS_STANDBY: | 898 | case SND_SOC_BIAS_STANDBY: |
965 | if (codec->bias_level == SND_SOC_BIAS_PREPARE) { | 899 | if (codec->bias_level == SND_SOC_BIAS_PREPARE) { |
966 | /* VREF off */ | 900 | /* VREF off */ |
967 | reg = wm8961_read(codec, WM8961_PWR_MGMT_1); | 901 | reg = snd_soc_read(codec, WM8961_PWR_MGMT_1); |
968 | reg &= ~WM8961_VREF; | 902 | reg &= ~WM8961_VREF; |
969 | wm8961_write(codec, WM8961_PWR_MGMT_1, reg); | 903 | snd_soc_write(codec, WM8961_PWR_MGMT_1, reg); |
970 | 904 | ||
971 | /* Bias generation off */ | 905 | /* Bias generation off */ |
972 | reg = wm8961_read(codec, WM8961_ANTI_POP); | 906 | reg = snd_soc_read(codec, WM8961_ANTI_POP); |
973 | reg &= ~(WM8961_BUFIOEN | WM8961_BUFDCOPEN); | 907 | reg &= ~(WM8961_BUFIOEN | WM8961_BUFDCOPEN); |
974 | wm8961_write(codec, WM8961_ANTI_POP, reg); | 908 | snd_soc_write(codec, WM8961_ANTI_POP, reg); |
975 | 909 | ||
976 | /* VMID off */ | 910 | /* VMID off */ |
977 | reg = wm8961_read(codec, WM8961_PWR_MGMT_1); | 911 | reg = snd_soc_read(codec, WM8961_PWR_MGMT_1); |
978 | reg &= ~WM8961_VMIDSEL_MASK; | 912 | reg &= ~WM8961_VMIDSEL_MASK; |
979 | wm8961_write(codec, WM8961_PWR_MGMT_1, reg); | 913 | snd_soc_write(codec, WM8961_PWR_MGMT_1, reg); |
980 | } | 914 | } |
981 | break; | 915 | break; |
982 | 916 | ||
@@ -1101,7 +1035,7 @@ static int wm8961_resume(struct platform_device *pdev) | |||
1101 | if (i == WM8961_SOFTWARE_RESET) | 1035 | if (i == WM8961_SOFTWARE_RESET) |
1102 | continue; | 1036 | continue; |
1103 | 1037 | ||
1104 | wm8961_write(codec, i, reg_cache[i]); | 1038 | snd_soc_write(codec, i, reg_cache[i]); |
1105 | } | 1039 | } |
1106 | 1040 | ||
1107 | wm8961_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 1041 | wm8961_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
@@ -1140,26 +1074,32 @@ static int wm8961_register(struct wm8961_priv *wm8961) | |||
1140 | codec->private_data = wm8961; | 1074 | codec->private_data = wm8961; |
1141 | codec->name = "WM8961"; | 1075 | codec->name = "WM8961"; |
1142 | codec->owner = THIS_MODULE; | 1076 | codec->owner = THIS_MODULE; |
1143 | codec->read = wm8961_read; | ||
1144 | codec->write = wm8961_write; | ||
1145 | codec->dai = &wm8961_dai; | 1077 | codec->dai = &wm8961_dai; |
1146 | codec->num_dai = 1; | 1078 | codec->num_dai = 1; |
1147 | codec->reg_cache_size = ARRAY_SIZE(wm8961->reg_cache); | 1079 | codec->reg_cache_size = ARRAY_SIZE(wm8961->reg_cache); |
1148 | codec->reg_cache = &wm8961->reg_cache; | 1080 | codec->reg_cache = &wm8961->reg_cache; |
1149 | codec->bias_level = SND_SOC_BIAS_OFF; | 1081 | codec->bias_level = SND_SOC_BIAS_OFF; |
1150 | codec->set_bias_level = wm8961_set_bias_level; | 1082 | codec->set_bias_level = wm8961_set_bias_level; |
1083 | codec->volatile_register = wm8961_volatile_register; | ||
1151 | 1084 | ||
1152 | memcpy(codec->reg_cache, wm8961_reg_defaults, | 1085 | memcpy(codec->reg_cache, wm8961_reg_defaults, |
1153 | sizeof(wm8961_reg_defaults)); | 1086 | sizeof(wm8961_reg_defaults)); |
1154 | 1087 | ||
1155 | reg = wm8961_read_hw(codec, WM8961_SOFTWARE_RESET); | 1088 | ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C); |
1089 | if (ret != 0) { | ||
1090 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | ||
1091 | goto err; | ||
1092 | } | ||
1093 | |||
1094 | reg = snd_soc_read(codec, WM8961_SOFTWARE_RESET); | ||
1156 | if (reg != 0x1801) { | 1095 | if (reg != 0x1801) { |
1157 | dev_err(codec->dev, "Device is not a WM8961: ID=0x%x\n", reg); | 1096 | dev_err(codec->dev, "Device is not a WM8961: ID=0x%x\n", reg); |
1158 | ret = -EINVAL; | 1097 | ret = -EINVAL; |
1159 | goto err; | 1098 | goto err; |
1160 | } | 1099 | } |
1161 | 1100 | ||
1162 | reg = wm8961_read_hw(codec, WM8961_RIGHT_INPUT_VOLUME); | 1101 | /* This isn't volatile - readback doesn't correspond to write */ |
1102 | reg = codec->hw_read(codec, WM8961_RIGHT_INPUT_VOLUME); | ||
1163 | dev_info(codec->dev, "WM8961 family %d revision %c\n", | 1103 | dev_info(codec->dev, "WM8961 family %d revision %c\n", |
1164 | (reg & WM8961_DEVICE_ID_MASK) >> WM8961_DEVICE_ID_SHIFT, | 1104 | (reg & WM8961_DEVICE_ID_MASK) >> WM8961_DEVICE_ID_SHIFT, |
1165 | ((reg & WM8961_CHIP_REV_MASK) >> WM8961_CHIP_REV_SHIFT) | 1105 | ((reg & WM8961_CHIP_REV_MASK) >> WM8961_CHIP_REV_SHIFT) |
@@ -1172,37 +1112,37 @@ static int wm8961_register(struct wm8961_priv *wm8961) | |||
1172 | } | 1112 | } |
1173 | 1113 | ||
1174 | /* Enable class W */ | 1114 | /* Enable class W */ |
1175 | reg = wm8961_read(codec, WM8961_CHARGE_PUMP_B); | 1115 | reg = snd_soc_read(codec, WM8961_CHARGE_PUMP_B); |
1176 | reg |= WM8961_CP_DYN_PWR_MASK; | 1116 | reg |= WM8961_CP_DYN_PWR_MASK; |
1177 | wm8961_write(codec, WM8961_CHARGE_PUMP_B, reg); | 1117 | snd_soc_write(codec, WM8961_CHARGE_PUMP_B, reg); |
1178 | 1118 | ||
1179 | /* Latch volume update bits (right channel only, we always | 1119 | /* Latch volume update bits (right channel only, we always |
1180 | * write both out) and default ZC on. */ | 1120 | * write both out) and default ZC on. */ |
1181 | reg = wm8961_read(codec, WM8961_ROUT1_VOLUME); | 1121 | reg = snd_soc_read(codec, WM8961_ROUT1_VOLUME); |
1182 | wm8961_write(codec, WM8961_ROUT1_VOLUME, | 1122 | snd_soc_write(codec, WM8961_ROUT1_VOLUME, |
1183 | reg | WM8961_LO1ZC | WM8961_OUT1VU); | 1123 | reg | WM8961_LO1ZC | WM8961_OUT1VU); |
1184 | wm8961_write(codec, WM8961_LOUT1_VOLUME, reg | WM8961_LO1ZC); | 1124 | snd_soc_write(codec, WM8961_LOUT1_VOLUME, reg | WM8961_LO1ZC); |
1185 | reg = wm8961_read(codec, WM8961_ROUT2_VOLUME); | 1125 | reg = snd_soc_read(codec, WM8961_ROUT2_VOLUME); |
1186 | wm8961_write(codec, WM8961_ROUT2_VOLUME, | 1126 | snd_soc_write(codec, WM8961_ROUT2_VOLUME, |
1187 | reg | WM8961_SPKRZC | WM8961_SPKVU); | 1127 | reg | WM8961_SPKRZC | WM8961_SPKVU); |
1188 | wm8961_write(codec, WM8961_LOUT2_VOLUME, reg | WM8961_SPKLZC); | 1128 | snd_soc_write(codec, WM8961_LOUT2_VOLUME, reg | WM8961_SPKLZC); |
1189 | 1129 | ||
1190 | reg = wm8961_read(codec, WM8961_RIGHT_ADC_VOLUME); | 1130 | reg = snd_soc_read(codec, WM8961_RIGHT_ADC_VOLUME); |
1191 | wm8961_write(codec, WM8961_RIGHT_ADC_VOLUME, reg | WM8961_ADCVU); | 1131 | snd_soc_write(codec, WM8961_RIGHT_ADC_VOLUME, reg | WM8961_ADCVU); |
1192 | reg = wm8961_read(codec, WM8961_RIGHT_INPUT_VOLUME); | 1132 | reg = snd_soc_read(codec, WM8961_RIGHT_INPUT_VOLUME); |
1193 | wm8961_write(codec, WM8961_RIGHT_INPUT_VOLUME, reg | WM8961_IPVU); | 1133 | snd_soc_write(codec, WM8961_RIGHT_INPUT_VOLUME, reg | WM8961_IPVU); |
1194 | 1134 | ||
1195 | /* Use soft mute by default */ | 1135 | /* Use soft mute by default */ |
1196 | reg = wm8961_read(codec, WM8961_ADC_DAC_CONTROL_2); | 1136 | reg = snd_soc_read(codec, WM8961_ADC_DAC_CONTROL_2); |
1197 | reg |= WM8961_DACSMM; | 1137 | reg |= WM8961_DACSMM; |
1198 | wm8961_write(codec, WM8961_ADC_DAC_CONTROL_2, reg); | 1138 | snd_soc_write(codec, WM8961_ADC_DAC_CONTROL_2, reg); |
1199 | 1139 | ||
1200 | /* Use automatic clocking mode by default; for now this is all | 1140 | /* Use automatic clocking mode by default; for now this is all |
1201 | * we support. | 1141 | * we support. |
1202 | */ | 1142 | */ |
1203 | reg = wm8961_read(codec, WM8961_CLOCKING_3); | 1143 | reg = snd_soc_read(codec, WM8961_CLOCKING_3); |
1204 | reg &= ~WM8961_MANUAL_MODE; | 1144 | reg &= ~WM8961_MANUAL_MODE; |
1205 | wm8961_write(codec, WM8961_CLOCKING_3, reg); | 1145 | snd_soc_write(codec, WM8961_CLOCKING_3, reg); |
1206 | 1146 | ||
1207 | wm8961_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 1147 | wm8961_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
1208 | 1148 | ||
@@ -1250,7 +1190,6 @@ static __devinit int wm8961_i2c_probe(struct i2c_client *i2c, | |||
1250 | return -ENOMEM; | 1190 | return -ENOMEM; |
1251 | 1191 | ||
1252 | codec = &wm8961->codec; | 1192 | codec = &wm8961->codec; |
1253 | codec->hw_write = (hw_write_t)i2c_master_send; | ||
1254 | 1193 | ||
1255 | i2c_set_clientdata(i2c, wm8961); | 1194 | i2c_set_clientdata(i2c, wm8961); |
1256 | codec->control_data = i2c; | 1195 | codec->control_data = i2c; |