diff options
Diffstat (limited to 'sound/soc/codecs/wm9081.c')
-rw-r--r-- | sound/soc/codecs/wm9081.c | 368 |
1 files changed, 219 insertions, 149 deletions
diff --git a/sound/soc/codecs/wm9081.c b/sound/soc/codecs/wm9081.c index 4a398c3bfe8..a6bab392700 100644 --- a/sound/soc/codecs/wm9081.c +++ b/sound/soc/codecs/wm9081.c | |||
@@ -18,7 +18,7 @@ | |||
18 | #include <linux/device.h> | 18 | #include <linux/device.h> |
19 | #include <linux/pm.h> | 19 | #include <linux/pm.h> |
20 | #include <linux/i2c.h> | 20 | #include <linux/i2c.h> |
21 | #include <linux/platform_device.h> | 21 | #include <linux/regmap.h> |
22 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
23 | #include <sound/core.h> | 23 | #include <sound/core.h> |
24 | #include <sound/pcm.h> | 24 | #include <sound/pcm.h> |
@@ -30,69 +30,60 @@ | |||
30 | #include <sound/wm9081.h> | 30 | #include <sound/wm9081.h> |
31 | #include "wm9081.h" | 31 | #include "wm9081.h" |
32 | 32 | ||
33 | static u16 wm9081_reg_defaults[] = { | 33 | static struct reg_default wm9081_reg[] = { |
34 | 0x0000, /* R0 - Software Reset */ | 34 | { 2, 0x00B9 }, /* R2 - Analogue Lineout */ |
35 | 0x0000, /* R1 */ | 35 | { 3, 0x00B9 }, /* R3 - Analogue Speaker PGA */ |
36 | 0x00B9, /* R2 - Analogue Lineout */ | 36 | { 4, 0x0001 }, /* R4 - VMID Control */ |
37 | 0x00B9, /* R3 - Analogue Speaker PGA */ | 37 | { 5, 0x0068 }, /* R5 - Bias Control 1 */ |
38 | 0x0001, /* R4 - VMID Control */ | 38 | { 7, 0x0000 }, /* R7 - Analogue Mixer */ |
39 | 0x0068, /* R5 - Bias Control 1 */ | 39 | { 8, 0x0000 }, /* R8 - Anti Pop Control */ |
40 | 0x0000, /* R6 */ | 40 | { 9, 0x01DB }, /* R9 - Analogue Speaker 1 */ |
41 | 0x0000, /* R7 - Analogue Mixer */ | 41 | { 10, 0x0018 }, /* R10 - Analogue Speaker 2 */ |
42 | 0x0000, /* R8 - Anti Pop Control */ | 42 | { 11, 0x0180 }, /* R11 - Power Management */ |
43 | 0x01DB, /* R9 - Analogue Speaker 1 */ | 43 | { 12, 0x0000 }, /* R12 - Clock Control 1 */ |
44 | 0x0018, /* R10 - Analogue Speaker 2 */ | 44 | { 13, 0x0038 }, /* R13 - Clock Control 2 */ |
45 | 0x0180, /* R11 - Power Management */ | 45 | { 14, 0x4000 }, /* R14 - Clock Control 3 */ |
46 | 0x0000, /* R12 - Clock Control 1 */ | 46 | { 16, 0x0000 }, /* R16 - FLL Control 1 */ |
47 | 0x0038, /* R13 - Clock Control 2 */ | 47 | { 17, 0x0200 }, /* R17 - FLL Control 2 */ |
48 | 0x4000, /* R14 - Clock Control 3 */ | 48 | { 18, 0x0000 }, /* R18 - FLL Control 3 */ |
49 | 0x0000, /* R15 */ | 49 | { 19, 0x0204 }, /* R19 - FLL Control 4 */ |
50 | 0x0000, /* R16 - FLL Control 1 */ | 50 | { 20, 0x0000 }, /* R20 - FLL Control 5 */ |
51 | 0x0200, /* R17 - FLL Control 2 */ | 51 | { 22, 0x0000 }, /* R22 - Audio Interface 1 */ |
52 | 0x0000, /* R18 - FLL Control 3 */ | 52 | { 23, 0x0002 }, /* R23 - Audio Interface 2 */ |
53 | 0x0204, /* R19 - FLL Control 4 */ | 53 | { 24, 0x0008 }, /* R24 - Audio Interface 3 */ |
54 | 0x0000, /* R20 - FLL Control 5 */ | 54 | { 25, 0x0022 }, /* R25 - Audio Interface 4 */ |
55 | 0x0000, /* R21 */ | 55 | { 27, 0x0006 }, /* R27 - Interrupt Status Mask */ |
56 | 0x0000, /* R22 - Audio Interface 1 */ | 56 | { 28, 0x0000 }, /* R28 - Interrupt Polarity */ |
57 | 0x0002, /* R23 - Audio Interface 2 */ | 57 | { 29, 0x0000 }, /* R29 - Interrupt Control */ |
58 | 0x0008, /* R24 - Audio Interface 3 */ | 58 | { 30, 0x00C0 }, /* R30 - DAC Digital 1 */ |
59 | 0x0022, /* R25 - Audio Interface 4 */ | 59 | { 31, 0x0008 }, /* R31 - DAC Digital 2 */ |
60 | 0x0000, /* R26 - Interrupt Status */ | 60 | { 32, 0x09AF }, /* R32 - DRC 1 */ |
61 | 0x0006, /* R27 - Interrupt Status Mask */ | 61 | { 33, 0x4201 }, /* R33 - DRC 2 */ |
62 | 0x0000, /* R28 - Interrupt Polarity */ | 62 | { 34, 0x0000 }, /* R34 - DRC 3 */ |
63 | 0x0000, /* R29 - Interrupt Control */ | 63 | { 35, 0x0000 }, /* R35 - DRC 4 */ |
64 | 0x00C0, /* R30 - DAC Digital 1 */ | 64 | { 38, 0x0000 }, /* R38 - Write Sequencer 1 */ |
65 | 0x0008, /* R31 - DAC Digital 2 */ | 65 | { 39, 0x0000 }, /* R39 - Write Sequencer 2 */ |
66 | 0x09AF, /* R32 - DRC 1 */ | 66 | { 40, 0x0002 }, /* R40 - MW Slave 1 */ |
67 | 0x4201, /* R33 - DRC 2 */ | 67 | { 42, 0x0000 }, /* R42 - EQ 1 */ |
68 | 0x0000, /* R34 - DRC 3 */ | 68 | { 43, 0x0000 }, /* R43 - EQ 2 */ |
69 | 0x0000, /* R35 - DRC 4 */ | 69 | { 44, 0x0FCA }, /* R44 - EQ 3 */ |
70 | 0x0000, /* R36 */ | 70 | { 45, 0x0400 }, /* R45 - EQ 4 */ |
71 | 0x0000, /* R37 */ | 71 | { 46, 0x00B8 }, /* R46 - EQ 5 */ |
72 | 0x0000, /* R38 - Write Sequencer 1 */ | 72 | { 47, 0x1EB5 }, /* R47 - EQ 6 */ |
73 | 0x0000, /* R39 - Write Sequencer 2 */ | 73 | { 48, 0xF145 }, /* R48 - EQ 7 */ |
74 | 0x0002, /* R40 - MW Slave 1 */ | 74 | { 49, 0x0B75 }, /* R49 - EQ 8 */ |
75 | 0x0000, /* R41 */ | 75 | { 50, 0x01C5 }, /* R50 - EQ 9 */ |
76 | 0x0000, /* R42 - EQ 1 */ | 76 | { 51, 0x169E }, /* R51 - EQ 10 */ |
77 | 0x0000, /* R43 - EQ 2 */ | 77 | { 52, 0xF829 }, /* R52 - EQ 11 */ |
78 | 0x0FCA, /* R44 - EQ 3 */ | 78 | { 53, 0x07AD }, /* R53 - EQ 12 */ |
79 | 0x0400, /* R45 - EQ 4 */ | 79 | { 54, 0x1103 }, /* R54 - EQ 13 */ |
80 | 0x00B8, /* R46 - EQ 5 */ | 80 | { 55, 0x1C58 }, /* R55 - EQ 14 */ |
81 | 0x1EB5, /* R47 - EQ 6 */ | 81 | { 56, 0xF373 }, /* R56 - EQ 15 */ |
82 | 0xF145, /* R48 - EQ 7 */ | 82 | { 57, 0x0A54 }, /* R57 - EQ 16 */ |
83 | 0x0B75, /* R49 - EQ 8 */ | 83 | { 58, 0x0558 }, /* R58 - EQ 17 */ |
84 | 0x01C5, /* R50 - EQ 9 */ | 84 | { 59, 0x0564 }, /* R59 - EQ 18 */ |
85 | 0x169E, /* R51 - EQ 10 */ | 85 | { 60, 0x0559 }, /* R60 - EQ 19 */ |
86 | 0xF829, /* R52 - EQ 11 */ | 86 | { 61, 0x4000 }, /* R61 - EQ 20 */ |
87 | 0x07AD, /* R53 - EQ 12 */ | ||
88 | 0x1103, /* R54 - EQ 13 */ | ||
89 | 0x1C58, /* R55 - EQ 14 */ | ||
90 | 0xF373, /* R56 - EQ 15 */ | ||
91 | 0x0A54, /* R57 - EQ 16 */ | ||
92 | 0x0558, /* R58 - EQ 17 */ | ||
93 | 0x0564, /* R59 - EQ 18 */ | ||
94 | 0x0559, /* R60 - EQ 19 */ | ||
95 | 0x4000, /* R61 - EQ 20 */ | ||
96 | }; | 87 | }; |
97 | 88 | ||
98 | static struct { | 89 | static struct { |
@@ -156,7 +147,7 @@ static struct { | |||
156 | }; | 147 | }; |
157 | 148 | ||
158 | struct wm9081_priv { | 149 | struct wm9081_priv { |
159 | enum snd_soc_control_type control_type; | 150 | struct regmap *regmap; |
160 | int sysclk_source; | 151 | int sysclk_source; |
161 | int mclk_rate; | 152 | int mclk_rate; |
162 | int sysclk_rate; | 153 | int sysclk_rate; |
@@ -169,20 +160,84 @@ struct wm9081_priv { | |||
169 | struct wm9081_pdata pdata; | 160 | struct wm9081_pdata pdata; |
170 | }; | 161 | }; |
171 | 162 | ||
172 | static int wm9081_volatile_register(struct snd_soc_codec *codec, unsigned int reg) | 163 | static bool wm9081_volatile_register(struct device *dev, unsigned int reg) |
173 | { | 164 | { |
174 | switch (reg) { | 165 | switch (reg) { |
175 | case WM9081_SOFTWARE_RESET: | 166 | case WM9081_SOFTWARE_RESET: |
176 | case WM9081_INTERRUPT_STATUS: | 167 | case WM9081_INTERRUPT_STATUS: |
177 | return 1; | 168 | return true; |
178 | default: | 169 | default: |
179 | return 0; | 170 | return false; |
171 | } | ||
172 | } | ||
173 | |||
174 | static bool wm9081_readable_register(struct device *dev, unsigned int reg) | ||
175 | { | ||
176 | switch (reg) { | ||
177 | case WM9081_SOFTWARE_RESET: | ||
178 | case WM9081_ANALOGUE_LINEOUT: | ||
179 | case WM9081_ANALOGUE_SPEAKER_PGA: | ||
180 | case WM9081_VMID_CONTROL: | ||
181 | case WM9081_BIAS_CONTROL_1: | ||
182 | case WM9081_ANALOGUE_MIXER: | ||
183 | case WM9081_ANTI_POP_CONTROL: | ||
184 | case WM9081_ANALOGUE_SPEAKER_1: | ||
185 | case WM9081_ANALOGUE_SPEAKER_2: | ||
186 | case WM9081_POWER_MANAGEMENT: | ||
187 | case WM9081_CLOCK_CONTROL_1: | ||
188 | case WM9081_CLOCK_CONTROL_2: | ||
189 | case WM9081_CLOCK_CONTROL_3: | ||
190 | case WM9081_FLL_CONTROL_1: | ||
191 | case WM9081_FLL_CONTROL_2: | ||
192 | case WM9081_FLL_CONTROL_3: | ||
193 | case WM9081_FLL_CONTROL_4: | ||
194 | case WM9081_FLL_CONTROL_5: | ||
195 | case WM9081_AUDIO_INTERFACE_1: | ||
196 | case WM9081_AUDIO_INTERFACE_2: | ||
197 | case WM9081_AUDIO_INTERFACE_3: | ||
198 | case WM9081_AUDIO_INTERFACE_4: | ||
199 | case WM9081_INTERRUPT_STATUS: | ||
200 | case WM9081_INTERRUPT_STATUS_MASK: | ||
201 | case WM9081_INTERRUPT_POLARITY: | ||
202 | case WM9081_INTERRUPT_CONTROL: | ||
203 | case WM9081_DAC_DIGITAL_1: | ||
204 | case WM9081_DAC_DIGITAL_2: | ||
205 | case WM9081_DRC_1: | ||
206 | case WM9081_DRC_2: | ||
207 | case WM9081_DRC_3: | ||
208 | case WM9081_DRC_4: | ||
209 | case WM9081_WRITE_SEQUENCER_1: | ||
210 | case WM9081_WRITE_SEQUENCER_2: | ||
211 | case WM9081_MW_SLAVE_1: | ||
212 | case WM9081_EQ_1: | ||
213 | case WM9081_EQ_2: | ||
214 | case WM9081_EQ_3: | ||
215 | case WM9081_EQ_4: | ||
216 | case WM9081_EQ_5: | ||
217 | case WM9081_EQ_6: | ||
218 | case WM9081_EQ_7: | ||
219 | case WM9081_EQ_8: | ||
220 | case WM9081_EQ_9: | ||
221 | case WM9081_EQ_10: | ||
222 | case WM9081_EQ_11: | ||
223 | case WM9081_EQ_12: | ||
224 | case WM9081_EQ_13: | ||
225 | case WM9081_EQ_14: | ||
226 | case WM9081_EQ_15: | ||
227 | case WM9081_EQ_16: | ||
228 | case WM9081_EQ_17: | ||
229 | case WM9081_EQ_18: | ||
230 | case WM9081_EQ_19: | ||
231 | case WM9081_EQ_20: | ||
232 | return true; | ||
233 | default: | ||
234 | return false; | ||
180 | } | 235 | } |
181 | } | 236 | } |
182 | 237 | ||
183 | static int wm9081_reset(struct snd_soc_codec *codec) | 238 | static int wm9081_reset(struct regmap *map) |
184 | { | 239 | { |
185 | return snd_soc_write(codec, WM9081_SOFTWARE_RESET, 0); | 240 | return regmap_write(map, WM9081_SOFTWARE_RESET, 0x9081); |
186 | } | 241 | } |
187 | 242 | ||
188 | static const DECLARE_TLV_DB_SCALE(drc_in_tlv, -4500, 75, 0); | 243 | static const DECLARE_TLV_DB_SCALE(drc_in_tlv, -4500, 75, 0); |
@@ -737,6 +792,7 @@ SND_SOC_DAPM_SUPPLY("CLK_SYS", WM9081_CLOCK_CONTROL_3, 0, 0, clk_sys_event, | |||
737 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), | 792 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), |
738 | SND_SOC_DAPM_SUPPLY("CLK_DSP", WM9081_CLOCK_CONTROL_3, 1, 0, NULL, 0), | 793 | SND_SOC_DAPM_SUPPLY("CLK_DSP", WM9081_CLOCK_CONTROL_3, 1, 0, NULL, 0), |
739 | SND_SOC_DAPM_SUPPLY("TOCLK", WM9081_CLOCK_CONTROL_3, 2, 0, NULL, 0), | 794 | SND_SOC_DAPM_SUPPLY("TOCLK", WM9081_CLOCK_CONTROL_3, 2, 0, NULL, 0), |
795 | SND_SOC_DAPM_SUPPLY("TSENSE", WM9081_POWER_MANAGEMENT, 7, 0, NULL, 0), | ||
740 | }; | 796 | }; |
741 | 797 | ||
742 | 798 | ||
@@ -759,6 +815,7 @@ static const struct snd_soc_dapm_route wm9081_audio_paths[] = { | |||
759 | { "Speaker PGA", NULL, "CLK_SYS" }, | 815 | { "Speaker PGA", NULL, "CLK_SYS" }, |
760 | 816 | ||
761 | { "Speaker", NULL, "Speaker PGA" }, | 817 | { "Speaker", NULL, "Speaker PGA" }, |
818 | { "Speaker", NULL, "TSENSE" }, | ||
762 | 819 | ||
763 | { "SPKN", NULL, "Speaker" }, | 820 | { "SPKN", NULL, "Speaker" }, |
764 | { "SPKP", NULL, "Speaker" }, | 821 | { "SPKP", NULL, "Speaker" }, |
@@ -767,84 +824,74 @@ static const struct snd_soc_dapm_route wm9081_audio_paths[] = { | |||
767 | static int wm9081_set_bias_level(struct snd_soc_codec *codec, | 824 | static int wm9081_set_bias_level(struct snd_soc_codec *codec, |
768 | enum snd_soc_bias_level level) | 825 | enum snd_soc_bias_level level) |
769 | { | 826 | { |
770 | u16 reg; | ||
771 | |||
772 | switch (level) { | 827 | switch (level) { |
773 | case SND_SOC_BIAS_ON: | 828 | case SND_SOC_BIAS_ON: |
774 | break; | 829 | break; |
775 | 830 | ||
776 | case SND_SOC_BIAS_PREPARE: | 831 | case SND_SOC_BIAS_PREPARE: |
777 | /* VMID=2*40k */ | 832 | /* VMID=2*40k */ |
778 | reg = snd_soc_read(codec, WM9081_VMID_CONTROL); | 833 | snd_soc_update_bits(codec, WM9081_VMID_CONTROL, |
779 | reg &= ~WM9081_VMID_SEL_MASK; | 834 | WM9081_VMID_SEL_MASK, 0x2); |
780 | reg |= 0x2; | ||
781 | snd_soc_write(codec, WM9081_VMID_CONTROL, reg); | ||
782 | 835 | ||
783 | /* Normal bias current */ | 836 | /* Normal bias current */ |
784 | reg = snd_soc_read(codec, WM9081_BIAS_CONTROL_1); | 837 | snd_soc_update_bits(codec, WM9081_BIAS_CONTROL_1, |
785 | reg &= ~WM9081_STBY_BIAS_ENA; | 838 | WM9081_STBY_BIAS_ENA, 0); |
786 | snd_soc_write(codec, WM9081_BIAS_CONTROL_1, reg); | ||
787 | break; | 839 | break; |
788 | 840 | ||
789 | case SND_SOC_BIAS_STANDBY: | 841 | case SND_SOC_BIAS_STANDBY: |
790 | /* Initial cold start */ | 842 | /* Initial cold start */ |
791 | if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { | 843 | if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { |
792 | /* Disable LINEOUT discharge */ | 844 | /* Disable LINEOUT discharge */ |
793 | reg = snd_soc_read(codec, WM9081_ANTI_POP_CONTROL); | 845 | snd_soc_update_bits(codec, WM9081_ANTI_POP_CONTROL, |
794 | reg &= ~WM9081_LINEOUT_DISCH; | 846 | WM9081_LINEOUT_DISCH, 0); |
795 | snd_soc_write(codec, WM9081_ANTI_POP_CONTROL, reg); | ||
796 | 847 | ||
797 | /* Select startup bias source */ | 848 | /* Select startup bias source */ |
798 | reg = snd_soc_read(codec, WM9081_BIAS_CONTROL_1); | 849 | snd_soc_update_bits(codec, WM9081_BIAS_CONTROL_1, |
799 | reg |= WM9081_BIAS_SRC | WM9081_BIAS_ENA; | 850 | WM9081_BIAS_SRC | WM9081_BIAS_ENA, |
800 | snd_soc_write(codec, WM9081_BIAS_CONTROL_1, reg); | 851 | WM9081_BIAS_SRC | WM9081_BIAS_ENA); |
801 | 852 | ||
802 | /* VMID 2*4k; Soft VMID ramp enable */ | 853 | /* VMID 2*4k; Soft VMID ramp enable */ |
803 | reg = snd_soc_read(codec, WM9081_VMID_CONTROL); | 854 | snd_soc_update_bits(codec, WM9081_VMID_CONTROL, |
804 | reg |= WM9081_VMID_RAMP | 0x6; | 855 | WM9081_VMID_RAMP | |
805 | snd_soc_write(codec, WM9081_VMID_CONTROL, reg); | 856 | WM9081_VMID_SEL_MASK, |
857 | WM9081_VMID_RAMP | 0x6); | ||
806 | 858 | ||
807 | mdelay(100); | 859 | mdelay(100); |
808 | 860 | ||
809 | /* Normal bias enable & soft start off */ | 861 | /* Normal bias enable & soft start off */ |
810 | reg &= ~WM9081_VMID_RAMP; | 862 | snd_soc_update_bits(codec, WM9081_VMID_CONTROL, |
811 | snd_soc_write(codec, WM9081_VMID_CONTROL, reg); | 863 | WM9081_VMID_RAMP, 0); |
812 | 864 | ||
813 | /* Standard bias source */ | 865 | /* Standard bias source */ |
814 | reg = snd_soc_read(codec, WM9081_BIAS_CONTROL_1); | 866 | snd_soc_update_bits(codec, WM9081_BIAS_CONTROL_1, |
815 | reg &= ~WM9081_BIAS_SRC; | 867 | WM9081_BIAS_SRC, 0); |
816 | snd_soc_write(codec, WM9081_BIAS_CONTROL_1, reg); | ||
817 | } | 868 | } |
818 | 869 | ||
819 | /* VMID 2*240k */ | 870 | /* VMID 2*240k */ |
820 | reg = snd_soc_read(codec, WM9081_VMID_CONTROL); | 871 | snd_soc_update_bits(codec, WM9081_VMID_CONTROL, |
821 | reg &= ~WM9081_VMID_SEL_MASK; | 872 | WM9081_VMID_SEL_MASK, 0x04); |
822 | reg |= 0x04; | ||
823 | snd_soc_write(codec, WM9081_VMID_CONTROL, reg); | ||
824 | 873 | ||
825 | /* Standby bias current on */ | 874 | /* Standby bias current on */ |
826 | reg = snd_soc_read(codec, WM9081_BIAS_CONTROL_1); | 875 | snd_soc_update_bits(codec, WM9081_BIAS_CONTROL_1, |
827 | reg |= WM9081_STBY_BIAS_ENA; | 876 | WM9081_STBY_BIAS_ENA, |
828 | snd_soc_write(codec, WM9081_BIAS_CONTROL_1, reg); | 877 | WM9081_STBY_BIAS_ENA); |
829 | break; | 878 | break; |
830 | 879 | ||
831 | case SND_SOC_BIAS_OFF: | 880 | case SND_SOC_BIAS_OFF: |
832 | /* Startup bias source and disable bias */ | 881 | /* Startup bias source and disable bias */ |
833 | reg = snd_soc_read(codec, WM9081_BIAS_CONTROL_1); | 882 | snd_soc_update_bits(codec, WM9081_BIAS_CONTROL_1, |
834 | reg |= WM9081_BIAS_SRC; | 883 | WM9081_BIAS_SRC | WM9081_BIAS_ENA, |
835 | reg &= ~WM9081_BIAS_ENA; | 884 | WM9081_BIAS_SRC); |
836 | snd_soc_write(codec, WM9081_BIAS_CONTROL_1, reg); | ||
837 | 885 | ||
838 | /* Disable VMID with soft ramping */ | 886 | /* Disable VMID with soft ramping */ |
839 | reg = snd_soc_read(codec, WM9081_VMID_CONTROL); | 887 | snd_soc_update_bits(codec, WM9081_VMID_CONTROL, |
840 | reg &= ~WM9081_VMID_SEL_MASK; | 888 | WM9081_VMID_RAMP | WM9081_VMID_SEL_MASK, |
841 | reg |= WM9081_VMID_RAMP; | 889 | WM9081_VMID_RAMP); |
842 | snd_soc_write(codec, WM9081_VMID_CONTROL, reg); | ||
843 | 890 | ||
844 | /* Actively discharge LINEOUT */ | 891 | /* Actively discharge LINEOUT */ |
845 | reg = snd_soc_read(codec, WM9081_ANTI_POP_CONTROL); | 892 | snd_soc_update_bits(codec, WM9081_ANTI_POP_CONTROL, |
846 | reg |= WM9081_LINEOUT_DISCH; | 893 | WM9081_LINEOUT_DISCH, |
847 | snd_soc_write(codec, WM9081_ANTI_POP_CONTROL, reg); | 894 | WM9081_LINEOUT_DISCH); |
848 | break; | 895 | break; |
849 | } | 896 | } |
850 | 897 | ||
@@ -1185,7 +1232,7 @@ static int wm9081_set_tdm_slot(struct snd_soc_dai *dai, | |||
1185 | (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \ | 1232 | (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \ |
1186 | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) | 1233 | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) |
1187 | 1234 | ||
1188 | static struct snd_soc_dai_ops wm9081_dai_ops = { | 1235 | static const struct snd_soc_dai_ops wm9081_dai_ops = { |
1189 | .hw_params = wm9081_hw_params, | 1236 | .hw_params = wm9081_hw_params, |
1190 | .set_fmt = wm9081_set_dai_fmt, | 1237 | .set_fmt = wm9081_set_dai_fmt, |
1191 | .digital_mute = wm9081_digital_mute, | 1238 | .digital_mute = wm9081_digital_mute, |
@@ -1213,25 +1260,14 @@ static int wm9081_probe(struct snd_soc_codec *codec) | |||
1213 | int ret; | 1260 | int ret; |
1214 | u16 reg; | 1261 | u16 reg; |
1215 | 1262 | ||
1216 | ret = snd_soc_codec_set_cache_io(codec, 8, 16, wm9081->control_type); | 1263 | codec->control_data = wm9081->regmap; |
1264 | |||
1265 | ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP); | ||
1217 | if (ret != 0) { | 1266 | if (ret != 0) { |
1218 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | 1267 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); |
1219 | return ret; | 1268 | return ret; |
1220 | } | 1269 | } |
1221 | 1270 | ||
1222 | reg = snd_soc_read(codec, WM9081_SOFTWARE_RESET); | ||
1223 | if (reg != 0x9081) { | ||
1224 | dev_err(codec->dev, "Device is not a WM9081: ID=0x%x\n", reg); | ||
1225 | ret = -EINVAL; | ||
1226 | return ret; | ||
1227 | } | ||
1228 | |||
1229 | ret = wm9081_reset(codec); | ||
1230 | if (ret < 0) { | ||
1231 | dev_err(codec->dev, "Failed to issue reset\n"); | ||
1232 | return ret; | ||
1233 | } | ||
1234 | |||
1235 | reg = 0; | 1271 | reg = 0; |
1236 | if (wm9081->pdata.irq_high) | 1272 | if (wm9081->pdata.irq_high) |
1237 | reg |= WM9081_IRQ_POL; | 1273 | reg |= WM9081_IRQ_POL; |
@@ -1243,11 +1279,10 @@ static int wm9081_probe(struct snd_soc_codec *codec) | |||
1243 | wm9081_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 1279 | wm9081_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
1244 | 1280 | ||
1245 | /* Enable zero cross by default */ | 1281 | /* Enable zero cross by default */ |
1246 | reg = snd_soc_read(codec, WM9081_ANALOGUE_LINEOUT); | 1282 | snd_soc_update_bits(codec, WM9081_ANALOGUE_LINEOUT, |
1247 | snd_soc_write(codec, WM9081_ANALOGUE_LINEOUT, reg | WM9081_LINEOUTZC); | 1283 | WM9081_LINEOUTZC, WM9081_LINEOUTZC); |
1248 | reg = snd_soc_read(codec, WM9081_ANALOGUE_SPEAKER_PGA); | 1284 | snd_soc_update_bits(codec, WM9081_ANALOGUE_SPEAKER_PGA, |
1249 | snd_soc_write(codec, WM9081_ANALOGUE_SPEAKER_PGA, | 1285 | WM9081_SPKPGAZC, WM9081_SPKPGAZC); |
1250 | reg | WM9081_SPKPGAZC); | ||
1251 | 1286 | ||
1252 | if (!wm9081->pdata.num_retune_configs) { | 1287 | if (!wm9081->pdata.num_retune_configs) { |
1253 | dev_dbg(codec->dev, | 1288 | dev_dbg(codec->dev, |
@@ -1266,7 +1301,7 @@ static int wm9081_remove(struct snd_soc_codec *codec) | |||
1266 | } | 1301 | } |
1267 | 1302 | ||
1268 | #ifdef CONFIG_PM | 1303 | #ifdef CONFIG_PM |
1269 | static int wm9081_suspend(struct snd_soc_codec *codec, pm_message_t state) | 1304 | static int wm9081_suspend(struct snd_soc_codec *codec) |
1270 | { | 1305 | { |
1271 | wm9081_set_bias_level(codec, SND_SOC_BIAS_OFF); | 1306 | wm9081_set_bias_level(codec, SND_SOC_BIAS_OFF); |
1272 | 1307 | ||
@@ -1275,15 +1310,9 @@ static int wm9081_suspend(struct snd_soc_codec *codec, pm_message_t state) | |||
1275 | 1310 | ||
1276 | static int wm9081_resume(struct snd_soc_codec *codec) | 1311 | static int wm9081_resume(struct snd_soc_codec *codec) |
1277 | { | 1312 | { |
1278 | u16 *reg_cache = codec->reg_cache; | 1313 | struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec); |
1279 | int i; | ||
1280 | |||
1281 | for (i = 0; i < codec->driver->reg_cache_size; i++) { | ||
1282 | if (i == WM9081_SOFTWARE_RESET) | ||
1283 | continue; | ||
1284 | 1314 | ||
1285 | snd_soc_write(codec, i, reg_cache[i]); | 1315 | regcache_sync(wm9081->regmap); |
1286 | } | ||
1287 | 1316 | ||
1288 | wm9081_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 1317 | wm9081_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
1289 | 1318 | ||
@@ -1303,11 +1332,6 @@ static struct snd_soc_codec_driver soc_codec_dev_wm9081 = { | |||
1303 | .set_sysclk = wm9081_set_sysclk, | 1332 | .set_sysclk = wm9081_set_sysclk, |
1304 | .set_bias_level = wm9081_set_bias_level, | 1333 | .set_bias_level = wm9081_set_bias_level, |
1305 | 1334 | ||
1306 | .reg_cache_size = ARRAY_SIZE(wm9081_reg_defaults), | ||
1307 | .reg_word_size = sizeof(u16), | ||
1308 | .reg_cache_default = wm9081_reg_defaults, | ||
1309 | .volatile_register = wm9081_volatile_register, | ||
1310 | |||
1311 | .controls = wm9081_snd_controls, | 1335 | .controls = wm9081_snd_controls, |
1312 | .num_controls = ARRAY_SIZE(wm9081_snd_controls), | 1336 | .num_controls = ARRAY_SIZE(wm9081_snd_controls), |
1313 | .dapm_widgets = wm9081_dapm_widgets, | 1337 | .dapm_widgets = wm9081_dapm_widgets, |
@@ -1316,19 +1340,56 @@ static struct snd_soc_codec_driver soc_codec_dev_wm9081 = { | |||
1316 | .num_dapm_routes = ARRAY_SIZE(wm9081_audio_paths), | 1340 | .num_dapm_routes = ARRAY_SIZE(wm9081_audio_paths), |
1317 | }; | 1341 | }; |
1318 | 1342 | ||
1343 | static const struct regmap_config wm9081_regmap = { | ||
1344 | .reg_bits = 8, | ||
1345 | .val_bits = 16, | ||
1346 | |||
1347 | .max_register = WM9081_MAX_REGISTER, | ||
1348 | .reg_defaults = wm9081_reg, | ||
1349 | .num_reg_defaults = ARRAY_SIZE(wm9081_reg), | ||
1350 | .volatile_reg = wm9081_volatile_register, | ||
1351 | .readable_reg = wm9081_readable_register, | ||
1352 | .cache_type = REGCACHE_RBTREE, | ||
1353 | }; | ||
1354 | |||
1319 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | 1355 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) |
1320 | static __devinit int wm9081_i2c_probe(struct i2c_client *i2c, | 1356 | static __devinit int wm9081_i2c_probe(struct i2c_client *i2c, |
1321 | const struct i2c_device_id *id) | 1357 | const struct i2c_device_id *id) |
1322 | { | 1358 | { |
1323 | struct wm9081_priv *wm9081; | 1359 | struct wm9081_priv *wm9081; |
1360 | unsigned int reg; | ||
1324 | int ret; | 1361 | int ret; |
1325 | 1362 | ||
1326 | wm9081 = kzalloc(sizeof(struct wm9081_priv), GFP_KERNEL); | 1363 | wm9081 = devm_kzalloc(&i2c->dev, sizeof(struct wm9081_priv), |
1364 | GFP_KERNEL); | ||
1327 | if (wm9081 == NULL) | 1365 | if (wm9081 == NULL) |
1328 | return -ENOMEM; | 1366 | return -ENOMEM; |
1329 | 1367 | ||
1330 | i2c_set_clientdata(i2c, wm9081); | 1368 | i2c_set_clientdata(i2c, wm9081); |
1331 | wm9081->control_type = SND_SOC_I2C; | 1369 | |
1370 | wm9081->regmap = regmap_init_i2c(i2c, &wm9081_regmap); | ||
1371 | if (IS_ERR(wm9081->regmap)) { | ||
1372 | ret = PTR_ERR(wm9081->regmap); | ||
1373 | dev_err(&i2c->dev, "regmap_init() failed: %d\n", ret); | ||
1374 | goto err; | ||
1375 | } | ||
1376 | |||
1377 | ret = regmap_read(wm9081->regmap, WM9081_SOFTWARE_RESET, ®); | ||
1378 | if (ret != 0) { | ||
1379 | dev_err(&i2c->dev, "Failed to read chip ID: %d\n", ret); | ||
1380 | goto err_regmap; | ||
1381 | } | ||
1382 | if (reg != 0x9081) { | ||
1383 | dev_err(&i2c->dev, "Device is not a WM9081: ID=0x%x\n", reg); | ||
1384 | ret = -EINVAL; | ||
1385 | goto err_regmap; | ||
1386 | } | ||
1387 | |||
1388 | ret = wm9081_reset(wm9081->regmap); | ||
1389 | if (ret < 0) { | ||
1390 | dev_err(&i2c->dev, "Failed to issue reset\n"); | ||
1391 | goto err_regmap; | ||
1392 | } | ||
1332 | 1393 | ||
1333 | if (dev_get_platdata(&i2c->dev)) | 1394 | if (dev_get_platdata(&i2c->dev)) |
1334 | memcpy(&wm9081->pdata, dev_get_platdata(&i2c->dev), | 1395 | memcpy(&wm9081->pdata, dev_get_platdata(&i2c->dev), |
@@ -1337,14 +1398,23 @@ static __devinit int wm9081_i2c_probe(struct i2c_client *i2c, | |||
1337 | ret = snd_soc_register_codec(&i2c->dev, | 1398 | ret = snd_soc_register_codec(&i2c->dev, |
1338 | &soc_codec_dev_wm9081, &wm9081_dai, 1); | 1399 | &soc_codec_dev_wm9081, &wm9081_dai, 1); |
1339 | if (ret < 0) | 1400 | if (ret < 0) |
1340 | kfree(wm9081); | 1401 | goto err_regmap; |
1402 | |||
1403 | return 0; | ||
1404 | |||
1405 | err_regmap: | ||
1406 | regmap_exit(wm9081->regmap); | ||
1407 | err: | ||
1408 | |||
1341 | return ret; | 1409 | return ret; |
1342 | } | 1410 | } |
1343 | 1411 | ||
1344 | static __devexit int wm9081_i2c_remove(struct i2c_client *client) | 1412 | static __devexit int wm9081_i2c_remove(struct i2c_client *client) |
1345 | { | 1413 | { |
1414 | struct wm9081_priv *wm9081 = i2c_get_clientdata(client); | ||
1415 | |||
1346 | snd_soc_unregister_codec(&client->dev); | 1416 | snd_soc_unregister_codec(&client->dev); |
1347 | kfree(i2c_get_clientdata(client)); | 1417 | regmap_exit(wm9081->regmap); |
1348 | return 0; | 1418 | return 0; |
1349 | } | 1419 | } |
1350 | 1420 | ||