Diff markup
1 /* 1 /*
2 * wm9712.c -- ALSA Soc WM9712 codec support 2 * wm9712.c -- ALSA Soc WM9712 codec support
3 * 3 *
4 * Copyright 2006 Wolfson Microelectronics PLC 4 * Copyright 2006 Wolfson Microelectronics PLC.
5 * Author: Liam Girdwood !! 5 * Author: Liam Girdwood <lrg@slimlogic.co.uk>
6 * liam.girdwood@wolfsonmicro.com or l <<
7 * 6 *
8 * This program is free software; you can red 7 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Publ 8 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 9 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version. 10 * option) any later version.
12 * <<
13 * Revision history <<
14 * 4th Feb 2006 Initial version. <<
15 */ 11 */
16 12
17 #include <linux/init.h> 13 #include <linux/init.h>
18 #include <linux/module.h> 14 #include <linux/module.h>
19 #include <linux/version.h> <<
20 #include <linux/kernel.h> 15 #include <linux/kernel.h>
21 #include <linux/device.h> 16 #include <linux/device.h>
22 #include <sound/core.h> 17 #include <sound/core.h>
23 #include <sound/pcm.h> 18 #include <sound/pcm.h>
24 #include <sound/ac97_codec.h> 19 #include <sound/ac97_codec.h>
25 #include <sound/initval.h> 20 #include <sound/initval.h>
26 #include <sound/soc.h> 21 #include <sound/soc.h>
27 #include <sound/soc-dapm.h> 22 #include <sound/soc-dapm.h>
>> 23 #include "wm9712.h"
28 24
29 #define WM9712_VERSION "0.4" 25 #define WM9712_VERSION "0.4"
30 26
31 static unsigned int ac97_read(struct snd_soc_c 27 static unsigned int ac97_read(struct snd_soc_codec *codec,
32 unsigned int reg); 28 unsigned int reg);
33 static int ac97_write(struct snd_soc_codec *co 29 static int ac97_write(struct snd_soc_codec *codec,
34 unsigned int reg, unsigned int val); 30 unsigned int reg, unsigned int val);
35 31
36 /* 32 /*
37 * WM9712 register cache 33 * WM9712 register cache
38 */ 34 */
39 static const u16 wm9712_reg[] = { 35 static const u16 wm9712_reg[] = {
40 0x6174, 0x8000, 0x8000, 0x8000, // 6 !! 36 0x6174, 0x8000, 0x8000, 0x8000, /* 6 */
41 0x0f0f, 0xaaa0, 0xc008, 0x6808, // e !! 37 0x0f0f, 0xaaa0, 0xc008, 0x6808, /* e */
42 0xe808, 0xaaa0, 0xad00, 0x8000, // 16 !! 38 0xe808, 0xaaa0, 0xad00, 0x8000, /* 16 */
43 0xe808, 0x3000, 0x8000, 0x0000, // 1e !! 39 0xe808, 0x3000, 0x8000, 0x0000, /* 1e */
44 0x0000, 0x0000, 0x0000, 0x000f, // 26 !! 40 0x0000, 0x0000, 0x0000, 0x000f, /* 26 */
45 0x0405, 0x0410, 0xbb80, 0xbb80, // 2e !! 41 0x0405, 0x0410, 0xbb80, 0xbb80, /* 2e */
46 0x0000, 0xbb80, 0x0000, 0x0000, // 36 !! 42 0x0000, 0xbb80, 0x0000, 0x0000, /* 36 */
47 0x0000, 0x2000, 0x0000, 0x0000, // 3e !! 43 0x0000, 0x2000, 0x0000, 0x0000, /* 3e */
48 0x0000, 0x0000, 0x0000, 0x0000, // 46 !! 44 0x0000, 0x0000, 0x0000, 0x0000, /* 46 */
49 0x0000, 0x0000, 0xf83e, 0xffff, // 4e !! 45 0x0000, 0x0000, 0xf83e, 0xffff, /* 4e */
50 0x0000, 0x0000, 0x0000, 0xf83e, // 56 !! 46 0x0000, 0x0000, 0x0000, 0xf83e, /* 56 */
51 0x0008, 0x0000, 0x0000, 0x0000, // 5e !! 47 0x0008, 0x0000, 0x0000, 0x0000, /* 5e */
52 0xb032, 0x3e00, 0x0000, 0x0000, // 66 !! 48 0xb032, 0x3e00, 0x0000, 0x0000, /* 66 */
53 0x0000, 0x0000, 0x0000, 0x0000, // 6e !! 49 0x0000, 0x0000, 0x0000, 0x0000, /* 6e */
54 0x0000, 0x0000, 0x0000, 0x0006, // 76 !! 50 0x0000, 0x0000, 0x0000, 0x0006, /* 76 */
55 0x0001, 0x0000, 0x574d, 0x4c12, // 7e !! 51 0x0001, 0x0000, 0x574d, 0x4c12, /* 7e */
56 0x0000, 0x0000 // virtual hp mixers !! 52 0x0000, 0x0000 /* virtual hp mixers */
57 }; 53 };
58 54
59 /* virtual HP mixers regs */ 55 /* virtual HP mixers regs */
60 #define HPL_MIXER 0x80 56 #define HPL_MIXER 0x80
61 #define HPR_MIXER 0x82 57 #define HPR_MIXER 0x82
62 58
63 static const char *wm9712_alc_select[] = {"Non 59 static const char *wm9712_alc_select[] = {"None", "Left", "Right", "Stereo"};
64 static const char *wm9712_alc_mux[] = {"Stereo 60 static const char *wm9712_alc_mux[] = {"Stereo", "Left", "Right", "None"};
65 static const char *wm9712_out3_src[] = {"Left" 61 static const char *wm9712_out3_src[] = {"Left", "VREF", "Left + Right",
66 "Mono"}; 62 "Mono"};
67 static const char *wm9712_spk_src[] = {"Speake 63 static const char *wm9712_spk_src[] = {"Speaker Mix", "Headphone Mix"};
68 static const char *wm9712_rec_adc[] = {"Stereo 64 static const char *wm9712_rec_adc[] = {"Stereo", "Left", "Right", "Mute"};
69 static const char *wm9712_base[] = {"Linear Co 65 static const char *wm9712_base[] = {"Linear Control", "Adaptive Boost"};
70 static const char *wm9712_rec_gain[] = {"+1.5d 66 static const char *wm9712_rec_gain[] = {"+1.5dB Steps", "+0.75dB Steps"};
71 static const char *wm9712_mic[] = {"Mic 1", "D 67 static const char *wm9712_mic[] = {"Mic 1", "Differential", "Mic 2",
72 "Stereo"}; 68 "Stereo"};
73 static const char *wm9712_rec_sel[] = {"Mic", 69 static const char *wm9712_rec_sel[] = {"Mic", "NC", "NC", "Speaker Mixer",
74 "Line", "Headphone Mixer", "Phone Mixe 70 "Line", "Headphone Mixer", "Phone Mixer", "Phone"};
75 static const char *wm9712_ng_type[] = {"Consta 71 static const char *wm9712_ng_type[] = {"Constant Gain", "Mute"};
76 static const char *wm9712_diff_sel[] = {"Mic", 72 static const char *wm9712_diff_sel[] = {"Mic", "Line"};
77 73
78 static const struct soc_enum wm9712_enum[] = { 74 static const struct soc_enum wm9712_enum[] = {
79 SOC_ENUM_SINGLE(AC97_PCI_SVID, 14, 4, wm9712_a 75 SOC_ENUM_SINGLE(AC97_PCI_SVID, 14, 4, wm9712_alc_select),
80 SOC_ENUM_SINGLE(AC97_VIDEO, 12, 4, wm9712_alc_ 76 SOC_ENUM_SINGLE(AC97_VIDEO, 12, 4, wm9712_alc_mux),
81 SOC_ENUM_SINGLE(AC97_AUX, 9, 4, wm9712_out3_sr 77 SOC_ENUM_SINGLE(AC97_AUX, 9, 4, wm9712_out3_src),
82 SOC_ENUM_SINGLE(AC97_AUX, 8, 2, wm9712_spk_src 78 SOC_ENUM_SINGLE(AC97_AUX, 8, 2, wm9712_spk_src),
83 SOC_ENUM_SINGLE(AC97_REC_SEL, 12, 4, wm9712_re 79 SOC_ENUM_SINGLE(AC97_REC_SEL, 12, 4, wm9712_rec_adc),
84 SOC_ENUM_SINGLE(AC97_MASTER_TONE, 15, 2, wm971 80 SOC_ENUM_SINGLE(AC97_MASTER_TONE, 15, 2, wm9712_base),
85 SOC_ENUM_DOUBLE(AC97_REC_GAIN, 14, 6, 2, wm971 81 SOC_ENUM_DOUBLE(AC97_REC_GAIN, 14, 6, 2, wm9712_rec_gain),
86 SOC_ENUM_SINGLE(AC97_MIC, 5, 4, wm9712_mic), 82 SOC_ENUM_SINGLE(AC97_MIC, 5, 4, wm9712_mic),
87 SOC_ENUM_SINGLE(AC97_REC_SEL, 8, 8, wm9712_rec 83 SOC_ENUM_SINGLE(AC97_REC_SEL, 8, 8, wm9712_rec_sel),
88 SOC_ENUM_SINGLE(AC97_REC_SEL, 0, 8, wm9712_rec 84 SOC_ENUM_SINGLE(AC97_REC_SEL, 0, 8, wm9712_rec_sel),
89 SOC_ENUM_SINGLE(AC97_PCI_SVID, 5, 2, wm9712_ng 85 SOC_ENUM_SINGLE(AC97_PCI_SVID, 5, 2, wm9712_ng_type),
90 SOC_ENUM_SINGLE(0x5c, 8, 2, wm9712_diff_sel), 86 SOC_ENUM_SINGLE(0x5c, 8, 2, wm9712_diff_sel),
91 }; 87 };
92 88
93 static const struct snd_kcontrol_new wm9712_sn 89 static const struct snd_kcontrol_new wm9712_snd_ac97_controls[] = {
94 SOC_DOUBLE("Speaker Playback Volume", AC97_MAS 90 SOC_DOUBLE("Speaker Playback Volume", AC97_MASTER, 8, 0, 31, 1),
95 SOC_SINGLE("Speaker Playback Switch", AC97_MAS 91 SOC_SINGLE("Speaker Playback Switch", AC97_MASTER, 15, 1, 1),
96 SOC_DOUBLE("Headphone Playback Volume", AC97_H 92 SOC_DOUBLE("Headphone Playback Volume", AC97_HEADPHONE, 8, 0, 31, 1),
97 SOC_SINGLE("Headphone Playback Switch", AC97_H !! 93 SOC_SINGLE("Headphone Playback Switch", AC97_HEADPHONE, 15, 1, 1),
98 SOC_DOUBLE("PCM Playback Volume", AC97_PCM, 8, 94 SOC_DOUBLE("PCM Playback Volume", AC97_PCM, 8, 0, 31, 1),
99 95
100 SOC_SINGLE("Speaker Playback ZC Switch", AC97_ 96 SOC_SINGLE("Speaker Playback ZC Switch", AC97_MASTER, 7, 1, 0),
101 SOC_SINGLE("Speaker Playback Invert Switch", A 97 SOC_SINGLE("Speaker Playback Invert Switch", AC97_MASTER, 6, 1, 0),
102 SOC_SINGLE("Headphone Playback ZC Switch", AC9 98 SOC_SINGLE("Headphone Playback ZC Switch", AC97_HEADPHONE, 7, 1, 0),
103 SOC_SINGLE("Mono Playback ZC Switch", AC97_MAS 99 SOC_SINGLE("Mono Playback ZC Switch", AC97_MASTER_MONO, 7, 1, 0),
104 SOC_SINGLE("Mono Playback Volume", AC97_MASTER 100 SOC_SINGLE("Mono Playback Volume", AC97_MASTER_MONO, 0, 31, 1),
105 SOC_SINGLE("Mono Playback Switch", AC97_MASTER 101 SOC_SINGLE("Mono Playback Switch", AC97_MASTER_MONO, 15, 1, 1),
106 102
107 SOC_SINGLE("ALC Target Volume", AC97_CODEC_CLA 103 SOC_SINGLE("ALC Target Volume", AC97_CODEC_CLASS_REV, 12, 15, 0),
108 SOC_SINGLE("ALC Hold Time", AC97_CODEC_CLASS_R 104 SOC_SINGLE("ALC Hold Time", AC97_CODEC_CLASS_REV, 8, 15, 0),
109 SOC_SINGLE("ALC Decay Time", AC97_CODEC_CLASS_ 105 SOC_SINGLE("ALC Decay Time", AC97_CODEC_CLASS_REV, 4, 15, 0),
110 SOC_SINGLE("ALC Attack Time", AC97_CODEC_CLASS 106 SOC_SINGLE("ALC Attack Time", AC97_CODEC_CLASS_REV, 0, 15, 0),
111 SOC_ENUM("ALC Function", wm9712_enum[0]), 107 SOC_ENUM("ALC Function", wm9712_enum[0]),
112 SOC_SINGLE("ALC Max Volume", AC97_PCI_SVID, 11 108 SOC_SINGLE("ALC Max Volume", AC97_PCI_SVID, 11, 7, 0),
113 SOC_SINGLE("ALC ZC Timeout", AC97_PCI_SVID, 9, 109 SOC_SINGLE("ALC ZC Timeout", AC97_PCI_SVID, 9, 3, 1),
114 SOC_SINGLE("ALC ZC Switch", AC97_PCI_SVID, 8, 110 SOC_SINGLE("ALC ZC Switch", AC97_PCI_SVID, 8, 1, 0),
115 SOC_SINGLE("ALC NG Switch", AC97_PCI_SVID, 7, 111 SOC_SINGLE("ALC NG Switch", AC97_PCI_SVID, 7, 1, 0),
116 SOC_ENUM("ALC NG Type", wm9712_enum[10]), 112 SOC_ENUM("ALC NG Type", wm9712_enum[10]),
117 SOC_SINGLE("ALC NG Threshold", AC97_PCI_SVID, 113 SOC_SINGLE("ALC NG Threshold", AC97_PCI_SVID, 0, 31, 1),
118 114
119 SOC_SINGLE("Mic Headphone Volume", AC97_VIDEO 115 SOC_SINGLE("Mic Headphone Volume", AC97_VIDEO, 12, 7, 1),
120 SOC_SINGLE("ALC Headphone Volume", AC97_VIDEO, 116 SOC_SINGLE("ALC Headphone Volume", AC97_VIDEO, 7, 7, 1),
121 117
122 SOC_SINGLE("Out3 Switch", AC97_AUX, 15, 1, 1), 118 SOC_SINGLE("Out3 Switch", AC97_AUX, 15, 1, 1),
123 SOC_SINGLE("Out3 ZC Switch", AC97_AUX, 7, 1, 1 119 SOC_SINGLE("Out3 ZC Switch", AC97_AUX, 7, 1, 1),
124 SOC_SINGLE("Out3 Volume", AC97_AUX, 0, 31, 1), 120 SOC_SINGLE("Out3 Volume", AC97_AUX, 0, 31, 1),
125 121
126 SOC_SINGLE("PCBeep Bypass Headphone Volume", A 122 SOC_SINGLE("PCBeep Bypass Headphone Volume", AC97_PC_BEEP, 12, 7, 1),
127 SOC_SINGLE("PCBeep Bypass Speaker Volume", AC9 123 SOC_SINGLE("PCBeep Bypass Speaker Volume", AC97_PC_BEEP, 8, 7, 1),
128 SOC_SINGLE("PCBeep Bypass Phone Volume", AC97_ 124 SOC_SINGLE("PCBeep Bypass Phone Volume", AC97_PC_BEEP, 4, 7, 1),
129 125
130 SOC_SINGLE("Aux Playback Headphone Volume", AC 126 SOC_SINGLE("Aux Playback Headphone Volume", AC97_CD, 12, 7, 1),
131 SOC_SINGLE("Aux Playback Speaker Volume", AC97 127 SOC_SINGLE("Aux Playback Speaker Volume", AC97_CD, 8, 7, 1),
132 SOC_SINGLE("Aux Playback Phone Volume", AC97_C 128 SOC_SINGLE("Aux Playback Phone Volume", AC97_CD, 4, 7, 1),
133 129
134 SOC_SINGLE("Phone Volume", AC97_PHONE, 0, 15, 130 SOC_SINGLE("Phone Volume", AC97_PHONE, 0, 15, 1),
135 SOC_DOUBLE("Line Capture Volume", AC97_LINE, 8 131 SOC_DOUBLE("Line Capture Volume", AC97_LINE, 8, 0, 31, 1),
136 132
137 SOC_SINGLE("Capture 20dB Boost Switch", AC97_R 133 SOC_SINGLE("Capture 20dB Boost Switch", AC97_REC_SEL, 14, 1, 0),
138 SOC_SINGLE("Capture to Phone 20dB Boost Switch 134 SOC_SINGLE("Capture to Phone 20dB Boost Switch", AC97_REC_SEL, 11, 1, 1),
139 135
140 SOC_SINGLE("3D Upper Cut-off Switch", AC97_3D_ 136 SOC_SINGLE("3D Upper Cut-off Switch", AC97_3D_CONTROL, 5, 1, 1),
141 SOC_SINGLE("3D Lower Cut-off Switch", AC97_3D_ 137 SOC_SINGLE("3D Lower Cut-off Switch", AC97_3D_CONTROL, 4, 1, 1),
142 SOC_SINGLE("3D Playback Volume", AC97_3D_CONTR 138 SOC_SINGLE("3D Playback Volume", AC97_3D_CONTROL, 0, 15, 0),
143 139
144 SOC_ENUM("Bass Control", wm9712_enum[5]), 140 SOC_ENUM("Bass Control", wm9712_enum[5]),
145 SOC_SINGLE("Bass Cut-off Switch", AC97_MASTER_ 141 SOC_SINGLE("Bass Cut-off Switch", AC97_MASTER_TONE, 12, 1, 1),
146 SOC_SINGLE("Tone Cut-off Switch", AC97_MASTER_ 142 SOC_SINGLE("Tone Cut-off Switch", AC97_MASTER_TONE, 4, 1, 1),
147 SOC_SINGLE("Playback Attenuate (-6dB) Switch", 143 SOC_SINGLE("Playback Attenuate (-6dB) Switch", AC97_MASTER_TONE, 6, 1, 0),
148 SOC_SINGLE("Bass Volume", AC97_MASTER_TONE, 8, 144 SOC_SINGLE("Bass Volume", AC97_MASTER_TONE, 8, 15, 1),
149 SOC_SINGLE("Treble Volume", AC97_MASTER_TONE, 145 SOC_SINGLE("Treble Volume", AC97_MASTER_TONE, 0, 15, 1),
150 146
151 SOC_SINGLE("Capture ADC Switch", AC97_REC_GAIN 147 SOC_SINGLE("Capture ADC Switch", AC97_REC_GAIN, 15, 1, 1),
152 SOC_ENUM("Capture Volume Steps", wm9712_enum[6 148 SOC_ENUM("Capture Volume Steps", wm9712_enum[6]),
153 SOC_DOUBLE("Capture Volume", AC97_REC_GAIN, 8, 149 SOC_DOUBLE("Capture Volume", AC97_REC_GAIN, 8, 0, 63, 1),
154 SOC_SINGLE("Capture ZC Switch", AC97_REC_GAIN, 150 SOC_SINGLE("Capture ZC Switch", AC97_REC_GAIN, 7, 1, 0),
155 151
156 SOC_SINGLE("Mic 1 Volume", AC97_MIC, 8, 31, 1) 152 SOC_SINGLE("Mic 1 Volume", AC97_MIC, 8, 31, 1),
157 SOC_SINGLE("Mic 2 Volume", AC97_MIC, 0, 31, 1) 153 SOC_SINGLE("Mic 2 Volume", AC97_MIC, 0, 31, 1),
158 SOC_SINGLE("Mic 20dB Boost Switch", AC97_MIC, 154 SOC_SINGLE("Mic 20dB Boost Switch", AC97_MIC, 7, 1, 0),
159 }; 155 };
160 156
161 /* add non dapm controls */ <<
162 static int wm9712_add_controls(struct snd_soc_ <<
163 { <<
164 int err, i; <<
165 <<
166 for (i = 0; i < ARRAY_SIZE(wm9712_snd_ <<
167 err = snd_ctl_add(codec->card, <<
168 snd_soc_cnew(& <<
169 if (err < 0) <<
170 return err; <<
171 } <<
172 return 0; <<
173 } <<
174 <<
175 /* We have to create a fake left and right HP 157 /* We have to create a fake left and right HP mixers because
176 * the codec only has a single control that is 158 * the codec only has a single control that is shared by both channels.
177 * This makes it impossible to determine the a 159 * This makes it impossible to determine the audio path.
178 */ 160 */
179 static int mixer_event(struct snd_soc_dapm_wid 161 static int mixer_event(struct snd_soc_dapm_widget *w,
180 struct snd_kcontrol *k, int event) 162 struct snd_kcontrol *k, int event)
181 { 163 {
182 u16 l, r, beep, line, phone, mic, pcm, 164 u16 l, r, beep, line, phone, mic, pcm, aux;
183 165
184 l = ac97_read(w->codec, HPL_MIXER); 166 l = ac97_read(w->codec, HPL_MIXER);
185 r = ac97_read(w->codec, HPR_MIXER); 167 r = ac97_read(w->codec, HPR_MIXER);
186 beep = ac97_read(w->codec, AC97_PC_BEE 168 beep = ac97_read(w->codec, AC97_PC_BEEP);
187 mic = ac97_read(w->codec, AC97_VIDEO); 169 mic = ac97_read(w->codec, AC97_VIDEO);
188 phone = ac97_read(w->codec, AC97_PHONE 170 phone = ac97_read(w->codec, AC97_PHONE);
189 line = ac97_read(w->codec, AC97_LINE); 171 line = ac97_read(w->codec, AC97_LINE);
190 pcm = ac97_read(w->codec, AC97_PCM); 172 pcm = ac97_read(w->codec, AC97_PCM);
191 aux = ac97_read(w->codec, AC97_CD); 173 aux = ac97_read(w->codec, AC97_CD);
192 174
193 if (l & 0x1 || r & 0x1) 175 if (l & 0x1 || r & 0x1)
194 ac97_write(w->codec, AC97_VIDE 176 ac97_write(w->codec, AC97_VIDEO, mic & 0x7fff);
195 else 177 else
196 ac97_write(w->codec, AC97_VIDE 178 ac97_write(w->codec, AC97_VIDEO, mic | 0x8000);
197 179
198 if (l & 0x2 || r & 0x2) 180 if (l & 0x2 || r & 0x2)
199 ac97_write(w->codec, AC97_PCM, 181 ac97_write(w->codec, AC97_PCM, pcm & 0x7fff);
200 else 182 else
201 ac97_write(w->codec, AC97_PCM, 183 ac97_write(w->codec, AC97_PCM, pcm | 0x8000);
202 184
203 if (l & 0x4 || r & 0x4) 185 if (l & 0x4 || r & 0x4)
204 ac97_write(w->codec, AC97_LINE 186 ac97_write(w->codec, AC97_LINE, line & 0x7fff);
205 else 187 else
206 ac97_write(w->codec, AC97_LINE 188 ac97_write(w->codec, AC97_LINE, line | 0x8000);
207 189
208 if (l & 0x8 || r & 0x8) 190 if (l & 0x8 || r & 0x8)
209 ac97_write(w->codec, AC97_PHON 191 ac97_write(w->codec, AC97_PHONE, phone & 0x7fff);
210 else 192 else
211 ac97_write(w->codec, AC97_PHON 193 ac97_write(w->codec, AC97_PHONE, phone | 0x8000);
212 194
213 if (l & 0x10 || r & 0x10) 195 if (l & 0x10 || r & 0x10)
214 ac97_write(w->codec, AC97_CD, 196 ac97_write(w->codec, AC97_CD, aux & 0x7fff);
215 else 197 else
216 ac97_write(w->codec, AC97_CD, 198 ac97_write(w->codec, AC97_CD, aux | 0x8000);
217 199
218 if (l & 0x20 || r & 0x20) 200 if (l & 0x20 || r & 0x20)
219 ac97_write(w->codec, AC97_PC_B 201 ac97_write(w->codec, AC97_PC_BEEP, beep & 0x7fff);
220 else 202 else
221 ac97_write(w->codec, AC97_PC_B 203 ac97_write(w->codec, AC97_PC_BEEP, beep | 0x8000);
222 204
223 return 0; 205 return 0;
224 } 206 }
225 207
226 /* Left Headphone Mixers */ 208 /* Left Headphone Mixers */
227 static const struct snd_kcontrol_new wm9712_hp 209 static const struct snd_kcontrol_new wm9712_hpl_mixer_controls[] = {
228 SOC_DAPM_SINGLE("PCBeep Bypass Switch" 210 SOC_DAPM_SINGLE("PCBeep Bypass Switch", HPL_MIXER, 5, 1, 0),
229 SOC_DAPM_SINGLE("Aux Playback Switch", 211 SOC_DAPM_SINGLE("Aux Playback Switch", HPL_MIXER, 4, 1, 0),
230 SOC_DAPM_SINGLE("Phone Bypass Switch", 212 SOC_DAPM_SINGLE("Phone Bypass Switch", HPL_MIXER, 3, 1, 0),
231 SOC_DAPM_SINGLE("Line Bypass Switch", 213 SOC_DAPM_SINGLE("Line Bypass Switch", HPL_MIXER, 2, 1, 0),
232 SOC_DAPM_SINGLE("PCM Playback Switch", 214 SOC_DAPM_SINGLE("PCM Playback Switch", HPL_MIXER, 1, 1, 0),
233 SOC_DAPM_SINGLE("Mic Sidetone Switch", 215 SOC_DAPM_SINGLE("Mic Sidetone Switch", HPL_MIXER, 0, 1, 0),
234 }; 216 };
235 217
236 /* Right Headphone Mixers */ 218 /* Right Headphone Mixers */
237 static const struct snd_kcontrol_new wm9712_hp 219 static const struct snd_kcontrol_new wm9712_hpr_mixer_controls[] = {
238 SOC_DAPM_SINGLE("PCBeep Bypass Switch" 220 SOC_DAPM_SINGLE("PCBeep Bypass Switch", HPR_MIXER, 5, 1, 0),
239 SOC_DAPM_SINGLE("Aux Playback Switch", 221 SOC_DAPM_SINGLE("Aux Playback Switch", HPR_MIXER, 4, 1, 0),
240 SOC_DAPM_SINGLE("Phone Bypass Switch", 222 SOC_DAPM_SINGLE("Phone Bypass Switch", HPR_MIXER, 3, 1, 0),
241 SOC_DAPM_SINGLE("Line Bypass Switch", 223 SOC_DAPM_SINGLE("Line Bypass Switch", HPR_MIXER, 2, 1, 0),
242 SOC_DAPM_SINGLE("PCM Playback Switch", 224 SOC_DAPM_SINGLE("PCM Playback Switch", HPR_MIXER, 1, 1, 0),
243 SOC_DAPM_SINGLE("Mic Sidetone Switch", 225 SOC_DAPM_SINGLE("Mic Sidetone Switch", HPR_MIXER, 0, 1, 0),
244 }; 226 };
245 227
246 /* Speaker Mixer */ 228 /* Speaker Mixer */
247 static const struct snd_kcontrol_new wm9712_sp 229 static const struct snd_kcontrol_new wm9712_speaker_mixer_controls[] = {
248 SOC_DAPM_SINGLE("PCBeep Bypass Switch" 230 SOC_DAPM_SINGLE("PCBeep Bypass Switch", AC97_PC_BEEP, 11, 1, 1),
249 SOC_DAPM_SINGLE("Aux Playback Switch", 231 SOC_DAPM_SINGLE("Aux Playback Switch", AC97_CD, 11, 1, 1),
250 SOC_DAPM_SINGLE("Phone Bypass Switch", 232 SOC_DAPM_SINGLE("Phone Bypass Switch", AC97_PHONE, 14, 1, 1),
251 SOC_DAPM_SINGLE("Line Bypass Switch", 233 SOC_DAPM_SINGLE("Line Bypass Switch", AC97_LINE, 14, 1, 1),
252 SOC_DAPM_SINGLE("PCM Playback Switch", 234 SOC_DAPM_SINGLE("PCM Playback Switch", AC97_PCM, 14, 1, 1),
253 }; 235 };
254 236
255 /* Phone Mixer */ 237 /* Phone Mixer */
256 static const struct snd_kcontrol_new wm9712_ph 238 static const struct snd_kcontrol_new wm9712_phone_mixer_controls[] = {
257 SOC_DAPM_SINGLE("PCBeep Bypass Switch" 239 SOC_DAPM_SINGLE("PCBeep Bypass Switch", AC97_PC_BEEP, 7, 1, 1),
258 SOC_DAPM_SINGLE("Aux Playback Switch", 240 SOC_DAPM_SINGLE("Aux Playback Switch", AC97_CD, 7, 1, 1),
259 SOC_DAPM_SINGLE("Line Bypass Switch", 241 SOC_DAPM_SINGLE("Line Bypass Switch", AC97_LINE, 13, 1, 1),
260 SOC_DAPM_SINGLE("PCM Playback Switch", 242 SOC_DAPM_SINGLE("PCM Playback Switch", AC97_PCM, 13, 1, 1),
261 SOC_DAPM_SINGLE("Mic 1 Sidetone Switch 243 SOC_DAPM_SINGLE("Mic 1 Sidetone Switch", AC97_MIC, 14, 1, 1),
262 SOC_DAPM_SINGLE("Mic 2 Sidetone Switch 244 SOC_DAPM_SINGLE("Mic 2 Sidetone Switch", AC97_MIC, 13, 1, 1),
263 }; 245 };
264 246
265 /* ALC headphone mux */ 247 /* ALC headphone mux */
266 static const struct snd_kcontrol_new wm9712_al 248 static const struct snd_kcontrol_new wm9712_alc_mux_controls =
267 SOC_DAPM_ENUM("Route", wm9712_enum[1]); 249 SOC_DAPM_ENUM("Route", wm9712_enum[1]);
268 250
269 /* out 3 mux */ 251 /* out 3 mux */
270 static const struct snd_kcontrol_new wm9712_ou 252 static const struct snd_kcontrol_new wm9712_out3_mux_controls =
271 SOC_DAPM_ENUM("Route", wm9712_enum[2]); 253 SOC_DAPM_ENUM("Route", wm9712_enum[2]);
272 254
273 /* spk mux */ 255 /* spk mux */
274 static const struct snd_kcontrol_new wm9712_sp 256 static const struct snd_kcontrol_new wm9712_spk_mux_controls =
275 SOC_DAPM_ENUM("Route", wm9712_enum[3]); 257 SOC_DAPM_ENUM("Route", wm9712_enum[3]);
276 258
277 /* Capture to Phone mux */ 259 /* Capture to Phone mux */
278 static const struct snd_kcontrol_new wm9712_ca 260 static const struct snd_kcontrol_new wm9712_capture_phone_mux_controls =
279 SOC_DAPM_ENUM("Route", wm9712_enum[4]); 261 SOC_DAPM_ENUM("Route", wm9712_enum[4]);
280 262
281 /* Capture left select */ 263 /* Capture left select */
282 static const struct snd_kcontrol_new wm9712_ca 264 static const struct snd_kcontrol_new wm9712_capture_selectl_controls =
283 SOC_DAPM_ENUM("Route", wm9712_enum[8]); 265 SOC_DAPM_ENUM("Route", wm9712_enum[8]);
284 266
285 /* Capture right select */ 267 /* Capture right select */
286 static const struct snd_kcontrol_new wm9712_ca 268 static const struct snd_kcontrol_new wm9712_capture_selectr_controls =
287 SOC_DAPM_ENUM("Route", wm9712_enum[9]); 269 SOC_DAPM_ENUM("Route", wm9712_enum[9]);
288 270
289 /* Mic select */ 271 /* Mic select */
290 static const struct snd_kcontrol_new wm9712_mi 272 static const struct snd_kcontrol_new wm9712_mic_src_controls =
291 SOC_DAPM_ENUM("Route", wm9712_enum[7]); 273 SOC_DAPM_ENUM("Route", wm9712_enum[7]);
292 274
293 /* diff select */ 275 /* diff select */
294 static const struct snd_kcontrol_new wm9712_di 276 static const struct snd_kcontrol_new wm9712_diff_sel_controls =
295 SOC_DAPM_ENUM("Route", wm9712_enum[11]); 277 SOC_DAPM_ENUM("Route", wm9712_enum[11]);
296 278
297 static const struct snd_soc_dapm_widget wm9712 279 static const struct snd_soc_dapm_widget wm9712_dapm_widgets[] = {
298 SND_SOC_DAPM_MUX("ALC Sidetone Mux", SND_SOC_N 280 SND_SOC_DAPM_MUX("ALC Sidetone Mux", SND_SOC_NOPM, 0, 0,
299 &wm9712_alc_mux_controls), 281 &wm9712_alc_mux_controls),
300 SND_SOC_DAPM_MUX("Out3 Mux", SND_SOC_NOPM, 0, 282 SND_SOC_DAPM_MUX("Out3 Mux", SND_SOC_NOPM, 0, 0,
301 &wm9712_out3_mux_controls), 283 &wm9712_out3_mux_controls),
302 SND_SOC_DAPM_MUX("Speaker Mux", SND_SOC_NOPM, 284 SND_SOC_DAPM_MUX("Speaker Mux", SND_SOC_NOPM, 0, 0,
303 &wm9712_spk_mux_controls), 285 &wm9712_spk_mux_controls),
304 SND_SOC_DAPM_MUX("Capture Phone Mux", SND_SOC_ 286 SND_SOC_DAPM_MUX("Capture Phone Mux", SND_SOC_NOPM, 0, 0,
305 &wm9712_capture_phone_mux_controls), 287 &wm9712_capture_phone_mux_controls),
306 SND_SOC_DAPM_MUX("Left Capture Select", SND_SO 288 SND_SOC_DAPM_MUX("Left Capture Select", SND_SOC_NOPM, 0, 0,
307 &wm9712_capture_selectl_controls), 289 &wm9712_capture_selectl_controls),
308 SND_SOC_DAPM_MUX("Right Capture Select", SND_S 290 SND_SOC_DAPM_MUX("Right Capture Select", SND_SOC_NOPM, 0, 0,
309 &wm9712_capture_selectr_controls), 291 &wm9712_capture_selectr_controls),
310 SND_SOC_DAPM_MUX("Mic Select Source", SND_SOC_ 292 SND_SOC_DAPM_MUX("Mic Select Source", SND_SOC_NOPM, 0, 0,
311 &wm9712_mic_src_controls), 293 &wm9712_mic_src_controls),
312 SND_SOC_DAPM_MUX("Differential Source", SND_SO 294 SND_SOC_DAPM_MUX("Differential Source", SND_SOC_NOPM, 0, 0,
313 &wm9712_diff_sel_controls), 295 &wm9712_diff_sel_controls),
314 SND_SOC_DAPM_MIXER("AC97 Mixer", SND_SOC_NOPM, 296 SND_SOC_DAPM_MIXER("AC97 Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
315 SND_SOC_DAPM_MIXER_E("Left HP Mixer", AC97_INT 297 SND_SOC_DAPM_MIXER_E("Left HP Mixer", AC97_INT_PAGING, 9, 1,
316 &wm9712_hpl_mixer_controls[0], ARRAY_S 298 &wm9712_hpl_mixer_controls[0], ARRAY_SIZE(wm9712_hpl_mixer_controls),
317 mixer_event, SND_SOC_DAPM_POST_REG), 299 mixer_event, SND_SOC_DAPM_POST_REG),
318 SND_SOC_DAPM_MIXER_E("Right HP Mixer", AC97_IN 300 SND_SOC_DAPM_MIXER_E("Right HP Mixer", AC97_INT_PAGING, 8, 1,
319 &wm9712_hpr_mixer_controls[0], ARRAY_S 301 &wm9712_hpr_mixer_controls[0], ARRAY_SIZE(wm9712_hpr_mixer_controls),
320 mixer_event, SND_SOC_DAPM_POST_REG), 302 mixer_event, SND_SOC_DAPM_POST_REG),
321 SND_SOC_DAPM_MIXER("Phone Mixer", AC97_INT_PAG 303 SND_SOC_DAPM_MIXER("Phone Mixer", AC97_INT_PAGING, 6, 1,
322 &wm9712_phone_mixer_controls[0], ARRAY 304 &wm9712_phone_mixer_controls[0], ARRAY_SIZE(wm9712_phone_mixer_controls)),
323 SND_SOC_DAPM_MIXER("Speaker Mixer", AC97_INT_P 305 SND_SOC_DAPM_MIXER("Speaker Mixer", AC97_INT_PAGING, 7, 1,
324 &wm9712_speaker_mixer_controls[0], 306 &wm9712_speaker_mixer_controls[0],
325 ARRAY_SIZE(wm9712_speaker_mixer_contro 307 ARRAY_SIZE(wm9712_speaker_mixer_controls)),
326 SND_SOC_DAPM_MIXER("Mono Mixer", SND_SOC_NOPM, 308 SND_SOC_DAPM_MIXER("Mono Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
327 SND_SOC_DAPM_DAC("Left DAC", "Left HiFi Playba 309 SND_SOC_DAPM_DAC("Left DAC", "Left HiFi Playback", AC97_INT_PAGING, 14, 1),
328 SND_SOC_DAPM_DAC("Right DAC", "Right HiFi Play 310 SND_SOC_DAPM_DAC("Right DAC", "Right HiFi Playback", AC97_INT_PAGING, 13, 1),
329 SND_SOC_DAPM_DAC("Aux DAC", "Aux Playback", SN 311 SND_SOC_DAPM_DAC("Aux DAC", "Aux Playback", SND_SOC_NOPM, 0, 0),
330 SND_SOC_DAPM_ADC("Left ADC", "Left HiFi Captur 312 SND_SOC_DAPM_ADC("Left ADC", "Left HiFi Capture", AC97_INT_PAGING, 12, 1),
331 SND_SOC_DAPM_ADC("Right ADC", "Right HiFi Capt 313 SND_SOC_DAPM_ADC("Right ADC", "Right HiFi Capture", AC97_INT_PAGING, 11, 1),
332 SND_SOC_DAPM_PGA("Headphone PGA", AC97_INT_PAG 314 SND_SOC_DAPM_PGA("Headphone PGA", AC97_INT_PAGING, 4, 1, NULL, 0),
333 SND_SOC_DAPM_PGA("Speaker PGA", AC97_INT_PAGIN 315 SND_SOC_DAPM_PGA("Speaker PGA", AC97_INT_PAGING, 3, 1, NULL, 0),
334 SND_SOC_DAPM_PGA("Out 3 PGA", AC97_INT_PAGING, 316 SND_SOC_DAPM_PGA("Out 3 PGA", AC97_INT_PAGING, 5, 1, NULL, 0),
335 SND_SOC_DAPM_PGA("Line PGA", AC97_INT_PAGING, 317 SND_SOC_DAPM_PGA("Line PGA", AC97_INT_PAGING, 2, 1, NULL, 0),
336 SND_SOC_DAPM_PGA("Phone PGA", AC97_INT_PAGING, 318 SND_SOC_DAPM_PGA("Phone PGA", AC97_INT_PAGING, 1, 1, NULL, 0),
337 SND_SOC_DAPM_PGA("Mic PGA", AC97_INT_PAGING, 0 319 SND_SOC_DAPM_PGA("Mic PGA", AC97_INT_PAGING, 0, 1, NULL, 0),
338 SND_SOC_DAPM_MICBIAS("Mic Bias", AC97_INT_PAGI 320 SND_SOC_DAPM_MICBIAS("Mic Bias", AC97_INT_PAGING, 10, 1),
339 SND_SOC_DAPM_OUTPUT("MONOOUT"), 321 SND_SOC_DAPM_OUTPUT("MONOOUT"),
340 SND_SOC_DAPM_OUTPUT("HPOUTL"), 322 SND_SOC_DAPM_OUTPUT("HPOUTL"),
341 SND_SOC_DAPM_OUTPUT("HPOUTR"), 323 SND_SOC_DAPM_OUTPUT("HPOUTR"),
342 SND_SOC_DAPM_OUTPUT("LOUT2"), 324 SND_SOC_DAPM_OUTPUT("LOUT2"),
343 SND_SOC_DAPM_OUTPUT("ROUT2"), 325 SND_SOC_DAPM_OUTPUT("ROUT2"),
344 SND_SOC_DAPM_OUTPUT("OUT3"), 326 SND_SOC_DAPM_OUTPUT("OUT3"),
345 SND_SOC_DAPM_INPUT("LINEINL"), 327 SND_SOC_DAPM_INPUT("LINEINL"),
346 SND_SOC_DAPM_INPUT("LINEINR"), 328 SND_SOC_DAPM_INPUT("LINEINR"),
347 SND_SOC_DAPM_INPUT("PHONE"), 329 SND_SOC_DAPM_INPUT("PHONE"),
348 SND_SOC_DAPM_INPUT("PCBEEP"), 330 SND_SOC_DAPM_INPUT("PCBEEP"),
349 SND_SOC_DAPM_INPUT("MIC1"), 331 SND_SOC_DAPM_INPUT("MIC1"),
350 SND_SOC_DAPM_INPUT("MIC2"), 332 SND_SOC_DAPM_INPUT("MIC2"),
351 }; 333 };
352 334
353 static const char *audio_map[][3] = { !! 335 static const struct snd_soc_dapm_route audio_map[] = {
354 /* virtual mixer - mixes left & right 336 /* virtual mixer - mixes left & right channels for spk and mono */
355 {"AC97 Mixer", NULL, "Left DAC"}, 337 {"AC97 Mixer", NULL, "Left DAC"},
356 {"AC97 Mixer", NULL, "Right DAC"}, 338 {"AC97 Mixer", NULL, "Right DAC"},
357 339
358 /* Left HP mixer */ 340 /* Left HP mixer */
359 {"Left HP Mixer", "PCBeep Bypass Switc 341 {"Left HP Mixer", "PCBeep Bypass Switch", "PCBEEP"},
360 {"Left HP Mixer", "Aux Playback Switch 342 {"Left HP Mixer", "Aux Playback Switch", "Aux DAC"},
361 {"Left HP Mixer", "Phone Bypass Switch 343 {"Left HP Mixer", "Phone Bypass Switch", "Phone PGA"},
362 {"Left HP Mixer", "Line Bypass Switch" 344 {"Left HP Mixer", "Line Bypass Switch", "Line PGA"},
363 {"Left HP Mixer", "PCM Playback Switch 345 {"Left HP Mixer", "PCM Playback Switch", "Left DAC"},
364 {"Left HP Mixer", "Mic Sidetone Switch 346 {"Left HP Mixer", "Mic Sidetone Switch", "Mic PGA"},
365 {"Left HP Mixer", NULL, "ALC Sidetone 347 {"Left HP Mixer", NULL, "ALC Sidetone Mux"},
366 //{"Right HP Mixer", NULL, "HP Mixer"} <<
367 348
368 /* Right HP mixer */ 349 /* Right HP mixer */
369 {"Right HP Mixer", "PCBeep Bypass Swit 350 {"Right HP Mixer", "PCBeep Bypass Switch", "PCBEEP"},
370 {"Right HP Mixer", "Aux Playback Switc 351 {"Right HP Mixer", "Aux Playback Switch", "Aux DAC"},
371 {"Right HP Mixer", "Phone Bypass Switc 352 {"Right HP Mixer", "Phone Bypass Switch", "Phone PGA"},
372 {"Right HP Mixer", "Line Bypass Switch 353 {"Right HP Mixer", "Line Bypass Switch", "Line PGA"},
373 {"Right HP Mixer", "PCM Playback Switc 354 {"Right HP Mixer", "PCM Playback Switch", "Right DAC"},
374 {"Right HP Mixer", "Mic Sidetone Switc 355 {"Right HP Mixer", "Mic Sidetone Switch", "Mic PGA"},
375 {"Right HP Mixer", NULL, "ALC Sideton 356 {"Right HP Mixer", NULL, "ALC Sidetone Mux"},
376 357
377 /* speaker mixer */ 358 /* speaker mixer */
378 {"Speaker Mixer", "PCBeep Bypass Switc 359 {"Speaker Mixer", "PCBeep Bypass Switch", "PCBEEP"},
379 {"Speaker Mixer", "Line Bypass Switch" 360 {"Speaker Mixer", "Line Bypass Switch", "Line PGA"},
380 {"Speaker Mixer", "PCM Playback Switch 361 {"Speaker Mixer", "PCM Playback Switch", "AC97 Mixer"},
381 {"Speaker Mixer", "Phone Bypass Switch 362 {"Speaker Mixer", "Phone Bypass Switch", "Phone PGA"},
382 {"Speaker Mixer", "Aux Playback Switch 363 {"Speaker Mixer", "Aux Playback Switch", "Aux DAC"},
383 364
384 /* Phone mixer */ 365 /* Phone mixer */
385 {"Phone Mixer", "PCBeep Bypass Switch" 366 {"Phone Mixer", "PCBeep Bypass Switch", "PCBEEP"},
386 {"Phone Mixer", "Line Bypass Switch", 367 {"Phone Mixer", "Line Bypass Switch", "Line PGA"},
387 {"Phone Mixer", "Aux Playback Switch", 368 {"Phone Mixer", "Aux Playback Switch", "Aux DAC"},
388 {"Phone Mixer", "PCM Playback Switch", 369 {"Phone Mixer", "PCM Playback Switch", "AC97 Mixer"},
389 {"Phone Mixer", "Mic 1 Sidetone Switch 370 {"Phone Mixer", "Mic 1 Sidetone Switch", "Mic PGA"},
390 {"Phone Mixer", "Mic 2 Sidetone Switch 371 {"Phone Mixer", "Mic 2 Sidetone Switch", "Mic PGA"},
391 372
392 /* inputs */ 373 /* inputs */
393 {"Line PGA", NULL, "LINEINL"}, 374 {"Line PGA", NULL, "LINEINL"},
394 {"Line PGA", NULL, "LINEINR"}, 375 {"Line PGA", NULL, "LINEINR"},
395 {"Phone PGA", NULL, "PHONE"}, 376 {"Phone PGA", NULL, "PHONE"},
396 {"Mic PGA", NULL, "MIC1"}, 377 {"Mic PGA", NULL, "MIC1"},
397 {"Mic PGA", NULL, "MIC2"}, 378 {"Mic PGA", NULL, "MIC2"},
398 379
399 /* left capture selector */ 380 /* left capture selector */
400 {"Left Capture Select", "Mic", "MIC1"} 381 {"Left Capture Select", "Mic", "MIC1"},
401 {"Left Capture Select", "Speaker Mixer 382 {"Left Capture Select", "Speaker Mixer", "Speaker Mixer"},
402 {"Left Capture Select", "Line", "LINEI 383 {"Left Capture Select", "Line", "LINEINL"},
403 {"Left Capture Select", "Headphone Mix 384 {"Left Capture Select", "Headphone Mixer", "Left HP Mixer"},
404 {"Left Capture Select", "Phone Mixer", 385 {"Left Capture Select", "Phone Mixer", "Phone Mixer"},
405 {"Left Capture Select", "Phone", "PHON 386 {"Left Capture Select", "Phone", "PHONE"},
406 387
407 /* right capture selector */ 388 /* right capture selector */
408 {"Right Capture Select", "Mic", "MIC2" 389 {"Right Capture Select", "Mic", "MIC2"},
409 {"Right Capture Select", "Speaker Mixe 390 {"Right Capture Select", "Speaker Mixer", "Speaker Mixer"},
410 {"Right Capture Select", "Line", "LINE 391 {"Right Capture Select", "Line", "LINEINR"},
411 {"Right Capture Select", "Headphone Mi 392 {"Right Capture Select", "Headphone Mixer", "Right HP Mixer"},
412 {"Right Capture Select", "Phone Mixer" 393 {"Right Capture Select", "Phone Mixer", "Phone Mixer"},
413 {"Right Capture Select", "Phone", "PHO 394 {"Right Capture Select", "Phone", "PHONE"},
414 395
415 /* ALC Sidetone */ 396 /* ALC Sidetone */
416 {"ALC Sidetone Mux", "Stereo", "Left C 397 {"ALC Sidetone Mux", "Stereo", "Left Capture Select"},
417 {"ALC Sidetone Mux", "Stereo", "Right 398 {"ALC Sidetone Mux", "Stereo", "Right Capture Select"},
418 {"ALC Sidetone Mux", "Left", "Left Cap 399 {"ALC Sidetone Mux", "Left", "Left Capture Select"},
419 {"ALC Sidetone Mux", "Right", "Right C 400 {"ALC Sidetone Mux", "Right", "Right Capture Select"},
420 401
421 /* ADC's */ 402 /* ADC's */
422 {"Left ADC", NULL, "Left Capture Selec 403 {"Left ADC", NULL, "Left Capture Select"},
423 {"Right ADC", NULL, "Right Capture Sel 404 {"Right ADC", NULL, "Right Capture Select"},
424 405
425 /* outputs */ 406 /* outputs */
426 {"MONOOUT", NULL, "Phone Mixer"}, 407 {"MONOOUT", NULL, "Phone Mixer"},
427 {"HPOUTL", NULL, "Headphone PGA"}, 408 {"HPOUTL", NULL, "Headphone PGA"},
428 {"Headphone PGA", NULL, "Left HP Mixer 409 {"Headphone PGA", NULL, "Left HP Mixer"},
429 {"HPOUTR", NULL, "Headphone PGA"}, 410 {"HPOUTR", NULL, "Headphone PGA"},
430 {"Headphone PGA", NULL, "Right HP Mixe 411 {"Headphone PGA", NULL, "Right HP Mixer"},
431 412
432 /* mono hp mixer */ !! 413 /* mono mixer */
433 {"Mono HP Mixer", NULL, "Left HP Mixer !! 414 {"Mono Mixer", NULL, "Left HP Mixer"},
434 {"Mono HP Mixer", NULL, "Right HP Mixe !! 415 {"Mono Mixer", NULL, "Right HP Mixer"},
435 416
436 /* Out3 Mux */ 417 /* Out3 Mux */
437 {"Out3 Mux", "Left", "Left HP Mixer"}, 418 {"Out3 Mux", "Left", "Left HP Mixer"},
438 {"Out3 Mux", "Mono", "Phone Mixer"}, 419 {"Out3 Mux", "Mono", "Phone Mixer"},
439 {"Out3 Mux", "Left + Right", "Mono HP !! 420 {"Out3 Mux", "Left + Right", "Mono Mixer"},
440 {"Out 3 PGA", NULL, "Out3 Mux"}, 421 {"Out 3 PGA", NULL, "Out3 Mux"},
441 {"OUT3", NULL, "Out 3 PGA"}, 422 {"OUT3", NULL, "Out 3 PGA"},
442 423
443 /* speaker Mux */ 424 /* speaker Mux */
444 {"Speaker Mux", "Speaker Mix", "Speake 425 {"Speaker Mux", "Speaker Mix", "Speaker Mixer"},
445 {"Speaker Mux", "Headphone Mix", "Mono !! 426 {"Speaker Mux", "Headphone Mix", "Mono Mixer"},
446 {"Speaker PGA", NULL, "Speaker Mux"}, 427 {"Speaker PGA", NULL, "Speaker Mux"},
447 {"LOUT2", NULL, "Speaker PGA"}, 428 {"LOUT2", NULL, "Speaker PGA"},
448 {"ROUT2", NULL, "Speaker PGA"}, 429 {"ROUT2", NULL, "Speaker PGA"},
449 <<
450 {NULL, NULL, NULL}, <<
451 }; 430 };
452 431
453 static int wm9712_add_widgets(struct snd_soc_c 432 static int wm9712_add_widgets(struct snd_soc_codec *codec)
454 { 433 {
455 int i; !! 434 snd_soc_dapm_new_controls(codec, wm9712_dapm_widgets,
456 !! 435 ARRAY_SIZE(wm9712_dapm_widgets));
457 for(i = 0; i < ARRAY_SIZE(wm9712_dapm_ <<
458 snd_soc_dapm_new_control(codec <<
459 } <<
460 436
461 /* set up audio path audio_mapnects */ !! 437 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
462 for(i = 0; audio_map[i][0] != NULL; i+ <<
463 snd_soc_dapm_connect_input(cod <<
464 audio_map[i][1], audio <<
465 } <<
466 438
467 snd_soc_dapm_new_widgets(codec); 439 snd_soc_dapm_new_widgets(codec);
468 return 0; 440 return 0;
469 } 441 }
470 442
471 static unsigned int ac97_read(struct snd_soc_c 443 static unsigned int ac97_read(struct snd_soc_codec *codec,
472 unsigned int reg) 444 unsigned int reg)
473 { 445 {
474 u16 *cache = codec->reg_cache; 446 u16 *cache = codec->reg_cache;
475 447
476 if (reg == AC97_RESET || reg == AC97_G 448 if (reg == AC97_RESET || reg == AC97_GPIO_STATUS ||
477 reg == AC97_VENDOR_ID1 || reg 449 reg == AC97_VENDOR_ID1 || reg == AC97_VENDOR_ID2 ||
478 reg == AC97_REC_GAIN) 450 reg == AC97_REC_GAIN)
479 return soc_ac97_ops.read(codec 451 return soc_ac97_ops.read(codec->ac97, reg);
480 else { 452 else {
481 reg = reg >> 1; 453 reg = reg >> 1;
482 454
483 if (reg > (ARRAY_SIZE(wm9712_r !! 455 if (reg >= (ARRAY_SIZE(wm9712_reg)))
484 return -EIO; 456 return -EIO;
485 457
486 return cache[reg]; 458 return cache[reg];
487 } 459 }
488 } 460 }
489 461
490 static int ac97_write(struct snd_soc_codec *co 462 static int ac97_write(struct snd_soc_codec *codec, unsigned int reg,
491 unsigned int val) 463 unsigned int val)
492 { 464 {
493 u16 *cache = codec->reg_cache; 465 u16 *cache = codec->reg_cache;
494 466
495 soc_ac97_ops.write(codec->ac97, reg, v !! 467 if (reg < 0x7c)
>> 468 soc_ac97_ops.write(codec->ac97, reg, val);
496 reg = reg >> 1; 469 reg = reg >> 1;
497 if (reg <= (ARRAY_SIZE(wm9712_reg))) !! 470 if (reg < (ARRAY_SIZE(wm9712_reg)))
498 cache[reg] = val; 471 cache[reg] = val;
499 472
500 return 0; 473 return 0;
501 } 474 }
502 475
503 static int ac97_prepare(struct snd_pcm_substre !! 476 static int ac97_prepare(struct snd_pcm_substream *substream,
>> 477 struct snd_soc_dai *dai)
504 { 478 {
505 struct snd_pcm_runtime *runtime = subs 479 struct snd_pcm_runtime *runtime = substream->runtime;
506 struct snd_soc_pcm_runtime *rtd = subs 480 struct snd_soc_pcm_runtime *rtd = substream->private_data;
507 struct snd_soc_device *socdev = rtd->s 481 struct snd_soc_device *socdev = rtd->socdev;
508 struct snd_soc_codec *codec = socdev-> !! 482 struct snd_soc_codec *codec = socdev->card->codec;
509 int reg; 483 int reg;
510 u16 vra; 484 u16 vra;
511 485
512 vra = ac97_read(codec, AC97_EXTENDED_S 486 vra = ac97_read(codec, AC97_EXTENDED_STATUS);
513 ac97_write(codec, AC97_EXTENDED_STATUS 487 ac97_write(codec, AC97_EXTENDED_STATUS, vra | 0x1);
514 488
515 if (substream->stream == SNDRV_PCM_STR 489 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
516 reg = AC97_PCM_FRONT_DAC_RATE; 490 reg = AC97_PCM_FRONT_DAC_RATE;
517 else 491 else
518 reg = AC97_PCM_LR_ADC_RATE; 492 reg = AC97_PCM_LR_ADC_RATE;
519 493
520 return ac97_write(codec, reg, runtime- 494 return ac97_write(codec, reg, runtime->rate);
521 } 495 }
522 496
523 static int ac97_aux_prepare(struct snd_pcm_sub !! 497 static int ac97_aux_prepare(struct snd_pcm_substream *substream,
>> 498 struct snd_soc_dai *dai)
524 { 499 {
525 struct snd_pcm_runtime *runtime = subs 500 struct snd_pcm_runtime *runtime = substream->runtime;
526 struct snd_soc_pcm_runtime *rtd = subs 501 struct snd_soc_pcm_runtime *rtd = substream->private_data;
527 struct snd_soc_device *socdev = rtd->s 502 struct snd_soc_device *socdev = rtd->socdev;
528 struct snd_soc_codec *codec = socdev-> !! 503 struct snd_soc_codec *codec = socdev->card->codec;
529 u16 vra, xsle; 504 u16 vra, xsle;
530 505
531 vra = ac97_read(codec, AC97_EXTENDED_S 506 vra = ac97_read(codec, AC97_EXTENDED_STATUS);
532 ac97_write(codec, AC97_EXTENDED_STATUS 507 ac97_write(codec, AC97_EXTENDED_STATUS, vra | 0x1);
533 xsle = ac97_read(codec, AC97_PCI_SID); 508 xsle = ac97_read(codec, AC97_PCI_SID);
534 ac97_write(codec, AC97_PCI_SID, xsle | 509 ac97_write(codec, AC97_PCI_SID, xsle | 0x8000);
535 510
536 if (substream->stream != SNDRV_PCM_STR 511 if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK)
537 return -ENODEV; 512 return -ENODEV;
538 513
539 return ac97_write(codec, AC97_PCM_SURR 514 return ac97_write(codec, AC97_PCM_SURR_DAC_RATE, runtime->rate);
540 } 515 }
541 516
542 #define WM9712_AC97_RATES (SNDRV_PCM_RATE_8000 517 #define WM9712_AC97_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
543 SNDRV_PCM_RATE_22050 | SNDRV_P !! 518 SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_44100 |\
>> 519 SNDRV_PCM_RATE_48000)
>> 520
>> 521 static struct snd_soc_dai_ops wm9712_dai_ops_hifi = {
>> 522 .prepare = ac97_prepare,
>> 523 };
>> 524
>> 525 static struct snd_soc_dai_ops wm9712_dai_ops_aux = {
>> 526 .prepare = ac97_aux_prepare,
>> 527 };
544 528
545 struct snd_soc_codec_dai wm9712_dai[] = { !! 529 struct snd_soc_dai wm9712_dai[] = {
546 { 530 {
547 .name = "AC97 HiFi", 531 .name = "AC97 HiFi",
548 .type = SND_SOC_DAI_AC97_BUS, !! 532 .ac97_control = 1,
549 .playback = { 533 .playback = {
550 .stream_name = "HiFi Playback" 534 .stream_name = "HiFi Playback",
551 .channels_min = 1, 535 .channels_min = 1,
552 .channels_max = 2, 536 .channels_max = 2,
553 .rates = WM9712_AC97_RATES, 537 .rates = WM9712_AC97_RATES,
554 .formats = SNDRV_PCM_FMTBIT_S1 !! 538 .formats = SND_SOC_STD_AC97_FMTS,},
555 .capture = { 539 .capture = {
556 .stream_name = "HiFi Capture", 540 .stream_name = "HiFi Capture",
557 .channels_min = 1, 541 .channels_min = 1,
558 .channels_max = 2, 542 .channels_max = 2,
559 .rates = WM9712_AC97_RATES, 543 .rates = WM9712_AC97_RATES,
560 .formats = SNDRV_PCM_FMTBIT_S1 !! 544 .formats = SND_SOC_STD_AC97_FMTS,},
561 .ops = { !! 545 .ops = &wm9712_dai_ops_hifi,
562 .prepare = ac97_prepare,}, <<
563 }, 546 },
564 { 547 {
565 .name = "AC97 Aux", 548 .name = "AC97 Aux",
566 .playback = { 549 .playback = {
567 .stream_name = "Aux Playback", 550 .stream_name = "Aux Playback",
568 .channels_min = 1, 551 .channels_min = 1,
569 .channels_max = 1, 552 .channels_max = 1,
570 .rates = WM9712_AC97_RATES, 553 .rates = WM9712_AC97_RATES,
571 .formats = SNDRV_PCM_FMTBIT_S1 !! 554 .formats = SND_SOC_STD_AC97_FMTS,},
572 .ops = { !! 555 .ops = &wm9712_dai_ops_aux,
573 .prepare = ac97_aux_prepare,}, <<
574 } 556 }
575 }; 557 };
576 EXPORT_SYMBOL_GPL(wm9712_dai); 558 EXPORT_SYMBOL_GPL(wm9712_dai);
577 559
578 static int wm9712_dapm_event(struct snd_soc_co !! 560 static int wm9712_set_bias_level(struct snd_soc_codec *codec,
>> 561 enum snd_soc_bias_level level)
579 { 562 {
580 u16 reg; !! 563 switch (level) {
581 !! 564 case SND_SOC_BIAS_ON:
582 switch (event) { !! 565 case SND_SOC_BIAS_PREPARE:
583 case SNDRV_CTL_POWER_D0: /* full On */ <<
584 /* liam - maybe enable thermal <<
585 reg = ac97_read(codec, AC97_EX <<
586 ac97_write(codec, AC97_EXTENDE <<
587 break; <<
588 case SNDRV_CTL_POWER_D1: /* partial On <<
589 case SNDRV_CTL_POWER_D2: /* partial On <<
590 break; 566 break;
591 case SNDRV_CTL_POWER_D3hot: /* Off, wi !! 567 case SND_SOC_BIAS_STANDBY:
592 /* enable master bias and vmid <<
593 reg = ac97_read(codec, AC97_EX <<
594 ac97_write(codec, AC97_EXTENDE <<
595 ac97_write(codec, AC97_POWERDO 568 ac97_write(codec, AC97_POWERDOWN, 0x0000);
596 break; 569 break;
597 case SNDRV_CTL_POWER_D3cold: /* Off, w !! 570 case SND_SOC_BIAS_OFF:
598 /* disable everything includin 571 /* disable everything including AC link */
599 ac97_write(codec, AC97_EXTENDE <<
600 ac97_write(codec, AC97_EXTENDE 572 ac97_write(codec, AC97_EXTENDED_MSTATUS, 0xffff);
601 ac97_write(codec, AC97_POWERDO 573 ac97_write(codec, AC97_POWERDOWN, 0xffff);
602 break; 574 break;
603 } 575 }
604 codec->dapm_state = event; !! 576 codec->bias_level = level;
605 return 0; 577 return 0;
606 } 578 }
607 579
608 static int wm9712_reset(struct snd_soc_codec * 580 static int wm9712_reset(struct snd_soc_codec *codec, int try_warm)
609 { 581 {
610 if (try_warm && soc_ac97_ops.warm_rese 582 if (try_warm && soc_ac97_ops.warm_reset) {
611 soc_ac97_ops.warm_reset(codec- 583 soc_ac97_ops.warm_reset(codec->ac97);
612 if (!(ac97_read(codec, 0) & 0x !! 584 if (ac97_read(codec, 0) == wm9712_reg[0])
613 return 1; 585 return 1;
614 } 586 }
615 587
616 soc_ac97_ops.reset(codec->ac97); 588 soc_ac97_ops.reset(codec->ac97);
617 if (ac97_read(codec, 0) & 0x8000) !! 589 if (soc_ac97_ops.warm_reset)
>> 590 soc_ac97_ops.warm_reset(codec->ac97);
>> 591 if (ac97_read(codec, 0) != wm9712_reg[0])
618 goto err; 592 goto err;
619 return 0; 593 return 0;
620 594
621 err: 595 err:
622 printk(KERN_ERR "WM9712 AC97 reset fai 596 printk(KERN_ERR "WM9712 AC97 reset failed\n");
623 return -EIO; 597 return -EIO;
624 } 598 }
625 599
626 static int wm9712_soc_suspend(struct platform_ 600 static int wm9712_soc_suspend(struct platform_device *pdev,
627 pm_message_t state) 601 pm_message_t state)
628 { 602 {
629 struct snd_soc_device *socdev = platfo 603 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
630 struct snd_soc_codec *codec = socdev-> !! 604 struct snd_soc_codec *codec = socdev->card->codec;
631 605
632 wm9712_dapm_event(codec, SNDRV_CTL_POW !! 606 wm9712_set_bias_level(codec, SND_SOC_BIAS_OFF);
633 return 0; 607 return 0;
634 } 608 }
635 609
636 static int wm9712_soc_resume(struct platform_d 610 static int wm9712_soc_resume(struct platform_device *pdev)
637 { 611 {
638 struct snd_soc_device *socdev = platfo 612 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
639 struct snd_soc_codec *codec = socdev-> !! 613 struct snd_soc_codec *codec = socdev->card->codec;
640 int i, ret; 614 int i, ret;
641 u16 *cache = codec->reg_cache; 615 u16 *cache = codec->reg_cache;
642 616
643 ret = wm9712_reset(codec, 1); 617 ret = wm9712_reset(codec, 1);
644 if (ret < 0){ !! 618 if (ret < 0) {
645 printk(KERN_ERR "could not res 619 printk(KERN_ERR "could not reset AC97 codec\n");
646 return ret; 620 return ret;
647 } 621 }
648 622
649 wm9712_dapm_event(codec, SNDRV_CTL_POW !! 623 wm9712_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
650 624
651 if (ret == 0) { 625 if (ret == 0) {
652 /* Sync reg_cache with the har 626 /* Sync reg_cache with the hardware after cold reset */
653 for (i = 2; i < ARRAY_SIZE(wm9 !! 627 for (i = 2; i < ARRAY_SIZE(wm9712_reg) << 1; i += 2) {
654 if (i == AC97_INT_PAGI 628 if (i == AC97_INT_PAGING || i == AC97_POWERDOWN ||
655 (i > 0x58 && i !! 629 (i > 0x58 && i != 0x5c))
656 continue; 630 continue;
657 soc_ac97_ops.write(cod 631 soc_ac97_ops.write(codec->ac97, i, cache[i>>1]);
658 } 632 }
659 } 633 }
660 634
661 if (codec->suspend_dapm_state == SNDRV !! 635 if (codec->suspend_bias_level == SND_SOC_BIAS_ON)
662 wm9712_dapm_event(codec, SNDRV !! 636 wm9712_set_bias_level(codec, SND_SOC_BIAS_ON);
663 637
664 return ret; 638 return ret;
665 } 639 }
666 640
667 static int wm9712_soc_probe(struct platform_de 641 static int wm9712_soc_probe(struct platform_device *pdev)
668 { 642 {
669 struct snd_soc_device *socdev = platfo 643 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
670 struct snd_soc_codec *codec; 644 struct snd_soc_codec *codec;
671 int ret = 0; 645 int ret = 0;
672 646
673 printk(KERN_INFO "WM9711/WM9712 SoC Au 647 printk(KERN_INFO "WM9711/WM9712 SoC Audio Codec %s\n", WM9712_VERSION);
674 648
675 socdev->codec = kzalloc(sizeof(struct !! 649 socdev->card->codec = kzalloc(sizeof(struct snd_soc_codec),
676 if (socdev->codec == NULL) !! 650 GFP_KERNEL);
>> 651 if (socdev->card->codec == NULL)
677 return -ENOMEM; 652 return -ENOMEM;
678 codec = socdev->codec; !! 653 codec = socdev->card->codec;
679 mutex_init(&codec->mutex); 654 mutex_init(&codec->mutex);
680 655
681 codec->reg_cache = kmemdup(wm9712_reg, 656 codec->reg_cache = kmemdup(wm9712_reg, sizeof(wm9712_reg), GFP_KERNEL);
682 657
683 if (codec->reg_cache == NULL) { 658 if (codec->reg_cache == NULL) {
684 ret = -ENOMEM; 659 ret = -ENOMEM;
685 goto cache_err; 660 goto cache_err;
686 } 661 }
687 codec->reg_cache_size = sizeof(wm9712_ 662 codec->reg_cache_size = sizeof(wm9712_reg);
688 codec->reg_cache_step = 2; 663 codec->reg_cache_step = 2;
689 664
690 codec->name = "WM9712"; 665 codec->name = "WM9712";
691 codec->owner = THIS_MODULE; 666 codec->owner = THIS_MODULE;
692 codec->dai = wm9712_dai; 667 codec->dai = wm9712_dai;
693 codec->num_dai = ARRAY_SIZE(wm9712_dai 668 codec->num_dai = ARRAY_SIZE(wm9712_dai);
694 codec->write = ac97_write; 669 codec->write = ac97_write;
695 codec->read = ac97_read; 670 codec->read = ac97_read;
696 codec->dapm_event = wm9712_dapm_event; !! 671 codec->set_bias_level = wm9712_set_bias_level;
697 INIT_LIST_HEAD(&codec->dapm_widgets); 672 INIT_LIST_HEAD(&codec->dapm_widgets);
698 INIT_LIST_HEAD(&codec->dapm_paths); 673 INIT_LIST_HEAD(&codec->dapm_paths);
699 674
700 ret = snd_soc_new_ac97_codec(codec, &s 675 ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0);
701 if (ret < 0) { 676 if (ret < 0) {
702 printk(KERN_ERR "wm9712: faile 677 printk(KERN_ERR "wm9712: failed to register AC97 codec\n");
703 goto codec_err; 678 goto codec_err;
704 } 679 }
705 680
706 /* register pcms */ 681 /* register pcms */
707 ret = snd_soc_new_pcms(socdev, SNDRV_D 682 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
708 if (ret < 0) 683 if (ret < 0)
709 goto pcm_err; 684 goto pcm_err;
710 685
711 ret = wm9712_reset(codec, 0); 686 ret = wm9712_reset(codec, 0);
712 if (ret < 0) { 687 if (ret < 0) {
713 printk(KERN_ERR "AC97 link err !! 688 printk(KERN_ERR "Failed to reset WM9712: AC97 link error\n");
714 goto reset_err; 689 goto reset_err;
715 } 690 }
716 691
717 /* set alc mux to none */ 692 /* set alc mux to none */
718 ac97_write(codec, AC97_VIDEO, ac97_rea 693 ac97_write(codec, AC97_VIDEO, ac97_read(codec, AC97_VIDEO) | 0x3000);
719 694
720 wm9712_dapm_event(codec, SNDRV_CTL_POW !! 695 wm9712_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
721 wm9712_add_controls(codec); !! 696 snd_soc_add_controls(codec, wm9712_snd_ac97_controls,
>> 697 ARRAY_SIZE(wm9712_snd_ac97_controls));
722 wm9712_add_widgets(codec); 698 wm9712_add_widgets(codec);
723 ret = snd_soc_register_card(socdev); !! 699 ret = snd_soc_init_card(socdev);
724 if (ret < 0) { 700 if (ret < 0) {
725 printk(KERN_ERR "wm9712: faile 701 printk(KERN_ERR "wm9712: failed to register card\n");
726 goto reset_err; 702 goto reset_err;
727 } 703 }
728 704
729 return 0; 705 return 0;
730 706
731 reset_err: 707 reset_err:
732 snd_soc_free_pcms(socdev); 708 snd_soc_free_pcms(socdev);
733 709
734 pcm_err: 710 pcm_err:
735 snd_soc_free_ac97_codec(codec); 711 snd_soc_free_ac97_codec(codec);
736 712
737 codec_err: 713 codec_err:
738 kfree(codec->reg_cache); 714 kfree(codec->reg_cache);
739 715
740 cache_err: 716 cache_err:
741 kfree(socdev->codec); !! 717 kfree(socdev->card->codec);
742 socdev->codec = NULL; !! 718 socdev->card->codec = NULL;
743 return ret; 719 return ret;
744 } 720 }
745 721
746 static int wm9712_soc_remove(struct platform_d 722 static int wm9712_soc_remove(struct platform_device *pdev)
747 { 723 {
748 struct snd_soc_device *socdev = platfo 724 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
749 struct snd_soc_codec *codec = socdev-> !! 725 struct snd_soc_codec *codec = socdev->card->codec;
750 726
751 if (codec == NULL) 727 if (codec == NULL)
752 return 0; 728 return 0;
753 729
754 snd_soc_dapm_free(socdev); 730 snd_soc_dapm_free(socdev);
755 snd_soc_free_pcms(socdev); 731 snd_soc_free_pcms(socdev);
756 snd_soc_free_ac97_codec(codec); 732 snd_soc_free_ac97_codec(codec);
757 kfree(codec->reg_cache); 733 kfree(codec->reg_cache);
758 kfree(codec); 734 kfree(codec);
759 return 0; 735 return 0;
760 } 736 }
761 737
762 struct snd_soc_codec_device soc_codec_dev_wm97 738 struct snd_soc_codec_device soc_codec_dev_wm9712 = {
763 .probe = wm9712_soc_probe, 739 .probe = wm9712_soc_probe,
764 .remove = wm9712_soc_remove, 740 .remove = wm9712_soc_remove,
765 .suspend = wm9712_soc_suspend, 741 .suspend = wm9712_soc_suspend,
766 .resume = wm9712_soc_resume, 742 .resume = wm9712_soc_resume,
767 }; 743 };
768 <<
769 EXPORT_SYMBOL_GPL(soc_codec_dev_wm9712); 744 EXPORT_SYMBOL_GPL(soc_codec_dev_wm9712);
770 745
771 MODULE_DESCRIPTION("ASoC WM9711/WM9712 driver" 746 MODULE_DESCRIPTION("ASoC WM9711/WM9712 driver");
772 MODULE_AUTHOR("Liam Girdwood"); 747 MODULE_AUTHOR("Liam Girdwood");
773 MODULE_LICENSE("GPL"); 748 MODULE_LICENSE("GPL");
774 749
|
This page was automatically generated by the
LXR engine.
|