diff options
Diffstat (limited to 'sound/soc/codecs/wm8750.c')
-rw-r--r-- | sound/soc/codecs/wm8750.c | 121 |
1 files changed, 43 insertions, 78 deletions
diff --git a/sound/soc/codecs/wm8750.c b/sound/soc/codecs/wm8750.c index b64509b01a49..ed09043181e1 100644 --- a/sound/soc/codecs/wm8750.c +++ b/sound/soc/codecs/wm8750.c | |||
@@ -55,50 +55,7 @@ static const u16 wm8750_reg[] = { | |||
55 | 0x0079, 0x0079, 0x0079, /* 40 */ | 55 | 0x0079, 0x0079, 0x0079, /* 40 */ |
56 | }; | 56 | }; |
57 | 57 | ||
58 | /* | 58 | #define wm8750_reset(c) snd_soc_write(c, WM8750_RESET, 0) |
59 | * read wm8750 register cache | ||
60 | */ | ||
61 | static inline unsigned int wm8750_read_reg_cache(struct snd_soc_codec *codec, | ||
62 | unsigned int reg) | ||
63 | { | ||
64 | u16 *cache = codec->reg_cache; | ||
65 | if (reg > WM8750_CACHE_REGNUM) | ||
66 | return -1; | ||
67 | return cache[reg]; | ||
68 | } | ||
69 | |||
70 | /* | ||
71 | * write wm8750 register cache | ||
72 | */ | ||
73 | static inline void wm8750_write_reg_cache(struct snd_soc_codec *codec, | ||
74 | unsigned int reg, unsigned int value) | ||
75 | { | ||
76 | u16 *cache = codec->reg_cache; | ||
77 | if (reg > WM8750_CACHE_REGNUM) | ||
78 | return; | ||
79 | cache[reg] = value; | ||
80 | } | ||
81 | |||
82 | static int wm8750_write(struct snd_soc_codec *codec, unsigned int reg, | ||
83 | unsigned int value) | ||
84 | { | ||
85 | u8 data[2]; | ||
86 | |||
87 | /* data is | ||
88 | * D15..D9 WM8753 register offset | ||
89 | * D8...D0 register data | ||
90 | */ | ||
91 | data[0] = (reg << 1) | ((value >> 8) & 0x0001); | ||
92 | data[1] = value & 0x00ff; | ||
93 | |||
94 | wm8750_write_reg_cache(codec, reg, value); | ||
95 | if (codec->hw_write(codec->control_data, data, 2) == 2) | ||
96 | return 0; | ||
97 | else | ||
98 | return -EIO; | ||
99 | } | ||
100 | |||
101 | #define wm8750_reset(c) wm8750_write(c, WM8750_RESET, 0) | ||
102 | 59 | ||
103 | /* | 60 | /* |
104 | * WM8750 Controls | 61 | * WM8750 Controls |
@@ -594,7 +551,7 @@ static int wm8750_set_dai_fmt(struct snd_soc_dai *codec_dai, | |||
594 | return -EINVAL; | 551 | return -EINVAL; |
595 | } | 552 | } |
596 | 553 | ||
597 | wm8750_write(codec, WM8750_IFACE, iface); | 554 | snd_soc_write(codec, WM8750_IFACE, iface); |
598 | return 0; | 555 | return 0; |
599 | } | 556 | } |
600 | 557 | ||
@@ -606,8 +563,8 @@ static int wm8750_pcm_hw_params(struct snd_pcm_substream *substream, | |||
606 | struct snd_soc_device *socdev = rtd->socdev; | 563 | struct snd_soc_device *socdev = rtd->socdev; |
607 | struct snd_soc_codec *codec = socdev->card->codec; | 564 | struct snd_soc_codec *codec = socdev->card->codec; |
608 | struct wm8750_priv *wm8750 = codec->private_data; | 565 | struct wm8750_priv *wm8750 = codec->private_data; |
609 | u16 iface = wm8750_read_reg_cache(codec, WM8750_IFACE) & 0x1f3; | 566 | u16 iface = snd_soc_read(codec, WM8750_IFACE) & 0x1f3; |
610 | u16 srate = wm8750_read_reg_cache(codec, WM8750_SRATE) & 0x1c0; | 567 | u16 srate = snd_soc_read(codec, WM8750_SRATE) & 0x1c0; |
611 | int coeff = get_coeff(wm8750->sysclk, params_rate(params)); | 568 | int coeff = get_coeff(wm8750->sysclk, params_rate(params)); |
612 | 569 | ||
613 | /* bit size */ | 570 | /* bit size */ |
@@ -626,9 +583,9 @@ static int wm8750_pcm_hw_params(struct snd_pcm_substream *substream, | |||
626 | } | 583 | } |
627 | 584 | ||
628 | /* set iface & srate */ | 585 | /* set iface & srate */ |
629 | wm8750_write(codec, WM8750_IFACE, iface); | 586 | snd_soc_write(codec, WM8750_IFACE, iface); |
630 | if (coeff >= 0) | 587 | if (coeff >= 0) |
631 | wm8750_write(codec, WM8750_SRATE, srate | | 588 | snd_soc_write(codec, WM8750_SRATE, srate | |
632 | (coeff_div[coeff].sr << 1) | coeff_div[coeff].usb); | 589 | (coeff_div[coeff].sr << 1) | coeff_div[coeff].usb); |
633 | 590 | ||
634 | return 0; | 591 | return 0; |
@@ -637,35 +594,35 @@ static int wm8750_pcm_hw_params(struct snd_pcm_substream *substream, | |||
637 | static int wm8750_mute(struct snd_soc_dai *dai, int mute) | 594 | static int wm8750_mute(struct snd_soc_dai *dai, int mute) |
638 | { | 595 | { |
639 | struct snd_soc_codec *codec = dai->codec; | 596 | struct snd_soc_codec *codec = dai->codec; |
640 | u16 mute_reg = wm8750_read_reg_cache(codec, WM8750_ADCDAC) & 0xfff7; | 597 | u16 mute_reg = snd_soc_read(codec, WM8750_ADCDAC) & 0xfff7; |
641 | 598 | ||
642 | if (mute) | 599 | if (mute) |
643 | wm8750_write(codec, WM8750_ADCDAC, mute_reg | 0x8); | 600 | snd_soc_write(codec, WM8750_ADCDAC, mute_reg | 0x8); |
644 | else | 601 | else |
645 | wm8750_write(codec, WM8750_ADCDAC, mute_reg); | 602 | snd_soc_write(codec, WM8750_ADCDAC, mute_reg); |
646 | return 0; | 603 | return 0; |
647 | } | 604 | } |
648 | 605 | ||
649 | static int wm8750_set_bias_level(struct snd_soc_codec *codec, | 606 | static int wm8750_set_bias_level(struct snd_soc_codec *codec, |
650 | enum snd_soc_bias_level level) | 607 | enum snd_soc_bias_level level) |
651 | { | 608 | { |
652 | u16 pwr_reg = wm8750_read_reg_cache(codec, WM8750_PWR1) & 0xfe3e; | 609 | u16 pwr_reg = snd_soc_read(codec, WM8750_PWR1) & 0xfe3e; |
653 | 610 | ||
654 | switch (level) { | 611 | switch (level) { |
655 | case SND_SOC_BIAS_ON: | 612 | case SND_SOC_BIAS_ON: |
656 | /* set vmid to 50k and unmute dac */ | 613 | /* set vmid to 50k and unmute dac */ |
657 | wm8750_write(codec, WM8750_PWR1, pwr_reg | 0x00c0); | 614 | snd_soc_write(codec, WM8750_PWR1, pwr_reg | 0x00c0); |
658 | break; | 615 | break; |
659 | case SND_SOC_BIAS_PREPARE: | 616 | case SND_SOC_BIAS_PREPARE: |
660 | /* set vmid to 5k for quick power up */ | 617 | /* set vmid to 5k for quick power up */ |
661 | wm8750_write(codec, WM8750_PWR1, pwr_reg | 0x01c1); | 618 | snd_soc_write(codec, WM8750_PWR1, pwr_reg | 0x01c1); |
662 | break; | 619 | break; |
663 | case SND_SOC_BIAS_STANDBY: | 620 | case SND_SOC_BIAS_STANDBY: |
664 | /* mute dac and set vmid to 500k, enable VREF */ | 621 | /* mute dac and set vmid to 500k, enable VREF */ |
665 | wm8750_write(codec, WM8750_PWR1, pwr_reg | 0x0141); | 622 | snd_soc_write(codec, WM8750_PWR1, pwr_reg | 0x0141); |
666 | break; | 623 | break; |
667 | case SND_SOC_BIAS_OFF: | 624 | case SND_SOC_BIAS_OFF: |
668 | wm8750_write(codec, WM8750_PWR1, 0x0001); | 625 | snd_soc_write(codec, WM8750_PWR1, 0x0001); |
669 | break; | 626 | break; |
670 | } | 627 | } |
671 | codec->bias_level = level; | 628 | codec->bias_level = level; |
@@ -761,8 +718,6 @@ static int wm8750_init(struct snd_soc_device *socdev) | |||
761 | 718 | ||
762 | codec->name = "WM8750"; | 719 | codec->name = "WM8750"; |
763 | codec->owner = THIS_MODULE; | 720 | codec->owner = THIS_MODULE; |
764 | codec->read = wm8750_read_reg_cache; | ||
765 | codec->write = wm8750_write; | ||
766 | codec->set_bias_level = wm8750_set_bias_level; | 721 | codec->set_bias_level = wm8750_set_bias_level; |
767 | codec->dai = &wm8750_dai; | 722 | codec->dai = &wm8750_dai; |
768 | codec->num_dai = 1; | 723 | codec->num_dai = 1; |
@@ -771,13 +726,23 @@ static int wm8750_init(struct snd_soc_device *socdev) | |||
771 | if (codec->reg_cache == NULL) | 726 | if (codec->reg_cache == NULL) |
772 | return -ENOMEM; | 727 | return -ENOMEM; |
773 | 728 | ||
774 | wm8750_reset(codec); | 729 | ret = snd_soc_codec_set_cache_io(codec, 7, 9); |
730 | if (ret < 0) { | ||
731 | printk(KERN_ERR "wm8750: failed to set cache I/O: %d\n", ret); | ||
732 | goto err; | ||
733 | } | ||
734 | |||
735 | ret = wm8750_reset(codec); | ||
736 | if (ret < 0) { | ||
737 | printk(KERN_ERR "wm8750: failed to reset: %d\n", ret); | ||
738 | goto err; | ||
739 | } | ||
775 | 740 | ||
776 | /* register pcms */ | 741 | /* register pcms */ |
777 | ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); | 742 | ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); |
778 | if (ret < 0) { | 743 | if (ret < 0) { |
779 | printk(KERN_ERR "wm8750: failed to create pcms\n"); | 744 | printk(KERN_ERR "wm8750: failed to create pcms\n"); |
780 | goto pcm_err; | 745 | goto err; |
781 | } | 746 | } |
782 | 747 | ||
783 | /* charge output caps */ | 748 | /* charge output caps */ |
@@ -786,22 +751,22 @@ static int wm8750_init(struct snd_soc_device *socdev) | |||
786 | schedule_delayed_work(&codec->delayed_work, msecs_to_jiffies(1000)); | 751 | schedule_delayed_work(&codec->delayed_work, msecs_to_jiffies(1000)); |
787 | 752 | ||
788 | /* set the update bits */ | 753 | /* set the update bits */ |
789 | reg = wm8750_read_reg_cache(codec, WM8750_LDAC); | 754 | reg = snd_soc_read(codec, WM8750_LDAC); |
790 | wm8750_write(codec, WM8750_LDAC, reg | 0x0100); | 755 | snd_soc_write(codec, WM8750_LDAC, reg | 0x0100); |
791 | reg = wm8750_read_reg_cache(codec, WM8750_RDAC); | 756 | reg = snd_soc_read(codec, WM8750_RDAC); |
792 | wm8750_write(codec, WM8750_RDAC, reg | 0x0100); | 757 | snd_soc_write(codec, WM8750_RDAC, reg | 0x0100); |
793 | reg = wm8750_read_reg_cache(codec, WM8750_LOUT1V); | 758 | reg = snd_soc_read(codec, WM8750_LOUT1V); |
794 | wm8750_write(codec, WM8750_LOUT1V, reg | 0x0100); | 759 | snd_soc_write(codec, WM8750_LOUT1V, reg | 0x0100); |
795 | reg = wm8750_read_reg_cache(codec, WM8750_ROUT1V); | 760 | reg = snd_soc_read(codec, WM8750_ROUT1V); |
796 | wm8750_write(codec, WM8750_ROUT1V, reg | 0x0100); | 761 | snd_soc_write(codec, WM8750_ROUT1V, reg | 0x0100); |
797 | reg = wm8750_read_reg_cache(codec, WM8750_LOUT2V); | 762 | reg = snd_soc_read(codec, WM8750_LOUT2V); |
798 | wm8750_write(codec, WM8750_LOUT2V, reg | 0x0100); | 763 | snd_soc_write(codec, WM8750_LOUT2V, reg | 0x0100); |
799 | reg = wm8750_read_reg_cache(codec, WM8750_ROUT2V); | 764 | reg = snd_soc_read(codec, WM8750_ROUT2V); |
800 | wm8750_write(codec, WM8750_ROUT2V, reg | 0x0100); | 765 | snd_soc_write(codec, WM8750_ROUT2V, reg | 0x0100); |
801 | reg = wm8750_read_reg_cache(codec, WM8750_LINVOL); | 766 | reg = snd_soc_read(codec, WM8750_LINVOL); |
802 | wm8750_write(codec, WM8750_LINVOL, reg | 0x0100); | 767 | snd_soc_write(codec, WM8750_LINVOL, reg | 0x0100); |
803 | reg = wm8750_read_reg_cache(codec, WM8750_RINVOL); | 768 | reg = snd_soc_read(codec, WM8750_RINVOL); |
804 | wm8750_write(codec, WM8750_RINVOL, reg | 0x0100); | 769 | snd_soc_write(codec, WM8750_RINVOL, reg | 0x0100); |
805 | 770 | ||
806 | snd_soc_add_controls(codec, wm8750_snd_controls, | 771 | snd_soc_add_controls(codec, wm8750_snd_controls, |
807 | ARRAY_SIZE(wm8750_snd_controls)); | 772 | ARRAY_SIZE(wm8750_snd_controls)); |
@@ -816,7 +781,7 @@ static int wm8750_init(struct snd_soc_device *socdev) | |||
816 | card_err: | 781 | card_err: |
817 | snd_soc_free_pcms(socdev); | 782 | snd_soc_free_pcms(socdev); |
818 | snd_soc_dapm_free(socdev); | 783 | snd_soc_dapm_free(socdev); |
819 | pcm_err: | 784 | err: |
820 | kfree(codec->reg_cache); | 785 | kfree(codec->reg_cache); |
821 | return ret; | 786 | return ret; |
822 | } | 787 | } |