diff options
-rw-r--r-- | sound/pci/oxygen/cm9780.h | 63 | ||||
-rw-r--r-- | sound/pci/oxygen/oxygen.c | 138 | ||||
-rw-r--r-- | sound/pci/oxygen/oxygen.h | 2 | ||||
-rw-r--r-- | sound/pci/oxygen/oxygen_lib.c | 16 | ||||
-rw-r--r-- | sound/pci/oxygen/oxygen_mixer.c | 9 | ||||
-rw-r--r-- | sound/pci/oxygen/virtuoso.c | 123 |
6 files changed, 281 insertions, 70 deletions
diff --git a/sound/pci/oxygen/cm9780.h b/sound/pci/oxygen/cm9780.h new file mode 100644 index 000000000000..144596799676 --- /dev/null +++ b/sound/pci/oxygen/cm9780.h | |||
@@ -0,0 +1,63 @@ | |||
1 | #ifndef CM9780_H_INCLUDED | ||
2 | #define CM9780_H_INCLUDED | ||
3 | |||
4 | #define CM9780_JACK 0x62 | ||
5 | #define CM9780_MIXER 0x64 | ||
6 | #define CM9780_GPIO_SETUP 0x70 | ||
7 | #define CM9780_GPIO_STATUS 0x72 | ||
8 | |||
9 | /* jack control */ | ||
10 | #define CM9780_RSOE 0x0001 | ||
11 | #define CM9780_CBOE 0x0002 | ||
12 | #define CM9780_SSOE 0x0004 | ||
13 | #define CM9780_FROE 0x0008 | ||
14 | #define CM9780_HP2FMICOE 0x0010 | ||
15 | #define CM9780_CB2MICOE 0x0020 | ||
16 | #define CM9780_FMIC2LI 0x0040 | ||
17 | #define CM9780_FMIC2MIC 0x0080 | ||
18 | #define CM9780_HP2LI 0x0100 | ||
19 | #define CM9780_HP2MIC 0x0200 | ||
20 | #define CM9780_MIC2LI 0x0400 | ||
21 | #define CM9780_MIC2MIC 0x0800 | ||
22 | #define CM9780_LI2LI 0x1000 | ||
23 | #define CM9780_LI2MIC 0x2000 | ||
24 | #define CM9780_LO2LI 0x4000 | ||
25 | #define CM9780_LO2MIC 0x8000 | ||
26 | |||
27 | /* mixer control */ | ||
28 | #define CM9780_BSTSEL 0x0001 | ||
29 | #define CM9780_STRO_MIC 0x0002 | ||
30 | #define CM9780_SPDI_FREX 0x0004 | ||
31 | #define CM9780_SPDI_SSEX 0x0008 | ||
32 | #define CM9780_SPDI_CBEX 0x0010 | ||
33 | #define CM9780_SPDI_RSEX 0x0020 | ||
34 | #define CM9780_MIX2FR 0x0040 | ||
35 | #define CM9780_MIX2SS 0x0080 | ||
36 | #define CM9780_MIX2CB 0x0100 | ||
37 | #define CM9780_MIX2RS 0x0200 | ||
38 | #define CM9780_MIX2FR_EX 0x0400 | ||
39 | #define CM9780_MIX2SS_EX 0x0800 | ||
40 | #define CM9780_MIX2CB_EX 0x1000 | ||
41 | #define CM9780_MIX2RS_EX 0x2000 | ||
42 | #define CM9780_P47_IO 0x4000 | ||
43 | #define CM9780_PCBSW 0x8000 | ||
44 | |||
45 | /* GPIO setup */ | ||
46 | #define CM9780_GPI0EN 0x0001 | ||
47 | #define CM9780_GPI1EN 0x0002 | ||
48 | #define CM9780_SENSE_P 0x0004 | ||
49 | #define CM9780_LOCK_P 0x0008 | ||
50 | #define CM9780_GPIO0P 0x0010 | ||
51 | #define CM9780_GPIO1P 0x0020 | ||
52 | #define CM9780_GPIO0IO 0x0100 | ||
53 | #define CM9780_GPIO1IO 0x0200 | ||
54 | |||
55 | /* GPIO status */ | ||
56 | #define CM9780_GPO0 0x0001 | ||
57 | #define CM9780_GPO1 0x0002 | ||
58 | #define CM9780_GPIO0S 0x0010 | ||
59 | #define CM9780_GPIO1S 0x0020 | ||
60 | #define CM9780_GPII0S 0x0100 | ||
61 | #define CM9780_GPII1S 0x0200 | ||
62 | |||
63 | #endif | ||
diff --git a/sound/pci/oxygen/oxygen.c b/sound/pci/oxygen/oxygen.c index b11341f01c1d..78aa96917626 100644 --- a/sound/pci/oxygen/oxygen.c +++ b/sound/pci/oxygen/oxygen.c | |||
@@ -70,30 +70,92 @@ static struct pci_device_id oxygen_ids[] __devinitdata = { | |||
70 | }; | 70 | }; |
71 | MODULE_DEVICE_TABLE(pci, oxygen_ids); | 71 | MODULE_DEVICE_TABLE(pci, oxygen_ids); |
72 | 72 | ||
73 | |||
74 | #define GPIO_AK5385_DFS_MASK 0x0003 | ||
75 | #define GPIO_AK5385_DFS_NORMAL 0x0000 | ||
76 | #define GPIO_AK5385_DFS_DOUBLE 0x0001 | ||
77 | #define GPIO_AK5385_DFS_QUAD 0x0002 | ||
78 | |||
73 | #define AK4396_WRITE 0x2000 | 79 | #define AK4396_WRITE 0x2000 |
74 | 80 | ||
75 | /* register 0 */ | 81 | #define AK4396_CONTROL_1 0 |
82 | #define AK4396_CONTROL_2 1 | ||
83 | #define AK4396_CONTROL_3 2 | ||
84 | #define AK4396_LCH_ATT 3 | ||
85 | #define AK4396_RCH_ATT 4 | ||
86 | |||
87 | /* control 1 */ | ||
76 | #define AK4396_RSTN 0x01 | 88 | #define AK4396_RSTN 0x01 |
89 | #define AK4396_DIF_MASK 0x0e | ||
90 | #define AK4396_DIF_16_LSB 0x00 | ||
91 | #define AK4396_DIF_20_LSB 0x02 | ||
77 | #define AK4396_DIF_24_MSB 0x04 | 92 | #define AK4396_DIF_24_MSB 0x04 |
78 | /* register 1 */ | 93 | #define AK4396_DIF_24_I2S 0x06 |
94 | #define AK4396_DIF_24_LSB 0x08 | ||
95 | #define AK4396_ACKS 0x80 | ||
96 | /* control 2 */ | ||
79 | #define AK4396_SMUTE 0x01 | 97 | #define AK4396_SMUTE 0x01 |
98 | #define AK4396_DEM_MASK 0x06 | ||
99 | #define AK4396_DEM_441 0x00 | ||
80 | #define AK4396_DEM_OFF 0x02 | 100 | #define AK4396_DEM_OFF 0x02 |
101 | #define AK4396_DEM_48 0x04 | ||
102 | #define AK4396_DEM_32 0x06 | ||
81 | #define AK4396_DFS_MASK 0x18 | 103 | #define AK4396_DFS_MASK 0x18 |
82 | #define AK4396_DFS_NORMAL 0x00 | 104 | #define AK4396_DFS_NORMAL 0x00 |
83 | #define AK4396_DFS_DOUBLE 0x08 | 105 | #define AK4396_DFS_DOUBLE 0x08 |
84 | #define AK4396_DFS_QUAD 0x10 | 106 | #define AK4396_DFS_QUAD 0x10 |
85 | 107 | #define AK4396_SLOW 0x20 | |
86 | /* register 0 */ | 108 | #define AK4396_DZFM 0x40 |
109 | #define AK4396_DZFE 0x80 | ||
110 | /* control 3 */ | ||
111 | #define AK4396_DZFB 0x04 | ||
112 | #define AK4396_DCKB 0x10 | ||
113 | #define AK4396_DCKS 0x20 | ||
114 | #define AK4396_DSDM 0x40 | ||
115 | #define AK4396_D_P_MASK 0x80 | ||
116 | #define AK4396_PCM 0x00 | ||
117 | #define AK4396_DSD 0x80 | ||
118 | |||
119 | #define WM8785_R0 0 | ||
120 | #define WM8785_R1 1 | ||
121 | #define WM8785_R2 2 | ||
122 | #define WM8785_R7 7 | ||
123 | |||
124 | /* R0 */ | ||
125 | #define WM8785_MCR_MASK 0x007 | ||
126 | #define WM8785_MCR_SLAVE 0x000 | ||
127 | #define WM8785_MCR_MASTER_128 0x001 | ||
128 | #define WM8785_MCR_MASTER_192 0x002 | ||
129 | #define WM8785_MCR_MASTER_256 0x003 | ||
130 | #define WM8785_MCR_MASTER_384 0x004 | ||
131 | #define WM8785_MCR_MASTER_512 0x005 | ||
132 | #define WM8785_MCR_MASTER_768 0x006 | ||
133 | #define WM8785_OSR_MASK 0x018 | ||
87 | #define WM8785_OSR_SINGLE 0x000 | 134 | #define WM8785_OSR_SINGLE 0x000 |
88 | #define WM8785_OSR_DOUBLE 0x008 | 135 | #define WM8785_OSR_DOUBLE 0x008 |
89 | #define WM8785_OSR_QUAD 0x010 | 136 | #define WM8785_OSR_QUAD 0x010 |
137 | #define WM8785_FORMAT_MASK 0x060 | ||
138 | #define WM8785_FORMAT_RJUST 0x000 | ||
90 | #define WM8785_FORMAT_LJUST 0x020 | 139 | #define WM8785_FORMAT_LJUST 0x020 |
91 | #define WM8785_FORMAT_I2S 0x040 | 140 | #define WM8785_FORMAT_I2S 0x040 |
92 | /* register 1 */ | 141 | #define WM8785_FORMAT_DSP 0x060 |
142 | /* R1 */ | ||
143 | #define WM8785_WL_MASK 0x003 | ||
93 | #define WM8785_WL_16 0x000 | 144 | #define WM8785_WL_16 0x000 |
94 | #define WM8785_WL_20 0x001 | 145 | #define WM8785_WL_20 0x001 |
95 | #define WM8785_WL_24 0x002 | 146 | #define WM8785_WL_24 0x002 |
96 | #define WM8785_WL_32 0x003 | 147 | #define WM8785_WL_32 0x003 |
148 | #define WM8785_LRP 0x004 | ||
149 | #define WM8785_BCLKINV 0x008 | ||
150 | #define WM8785_LRSWAP 0x010 | ||
151 | #define WM8785_DEVNO_MASK 0x0e0 | ||
152 | /* R2 */ | ||
153 | #define WM8785_HPFR 0x001 | ||
154 | #define WM8785_HPFL 0x002 | ||
155 | #define WM8785_SDODIS 0x004 | ||
156 | #define WM8785_PWRDNR 0x008 | ||
157 | #define WM8785_PWRDNL 0x010 | ||
158 | #define WM8785_TDM_MASK 0x1c0 | ||
97 | 159 | ||
98 | static void ak4396_write(struct oxygen *chip, unsigned int codec, | 160 | static void ak4396_write(struct oxygen *chip, unsigned int codec, |
99 | u8 reg, u8 value) | 161 | u8 reg, u8 value) |
@@ -124,29 +186,33 @@ static void ak4396_init(struct oxygen *chip) | |||
124 | { | 186 | { |
125 | unsigned int i; | 187 | unsigned int i; |
126 | 188 | ||
127 | chip->ak4396_reg1 = AK4396_DEM_OFF | AK4396_DFS_NORMAL; | 189 | chip->ak4396_ctl2 = AK4396_DEM_OFF | AK4396_DFS_NORMAL; |
128 | for (i = 0; i < 4; ++i) { | 190 | for (i = 0; i < 4; ++i) { |
129 | ak4396_write(chip, i, 0, AK4396_DIF_24_MSB | AK4396_RSTN); | 191 | ak4396_write(chip, i, |
130 | ak4396_write(chip, i, 1, chip->ak4396_reg1); | 192 | AK4396_CONTROL_1, AK4396_DIF_24_MSB | AK4396_RSTN); |
131 | ak4396_write(chip, i, 2, 0); | 193 | ak4396_write(chip, i, |
132 | ak4396_write(chip, i, 3, 0xff); | 194 | AK4396_CONTROL_2, chip->ak4396_ctl2); |
133 | ak4396_write(chip, i, 4, 0xff); | 195 | ak4396_write(chip, i, |
196 | AK4396_CONTROL_3, AK4396_PCM); | ||
197 | ak4396_write(chip, i, AK4396_LCH_ATT, 0xff); | ||
198 | ak4396_write(chip, i, AK4396_RCH_ATT, 0xff); | ||
134 | } | 199 | } |
135 | snd_component_add(chip->card, "AK4396"); | 200 | snd_component_add(chip->card, "AK4396"); |
136 | } | 201 | } |
137 | 202 | ||
138 | static void ak5385_init(struct oxygen *chip) | 203 | static void ak5385_init(struct oxygen *chip) |
139 | { | 204 | { |
140 | oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, 0x0003); | 205 | oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, GPIO_AK5385_DFS_MASK); |
141 | oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, 0x0003); | 206 | oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, GPIO_AK5385_DFS_MASK); |
142 | snd_component_add(chip->card, "AK5385"); | 207 | snd_component_add(chip->card, "AK5385"); |
143 | } | 208 | } |
144 | 209 | ||
145 | static void wm8785_init(struct oxygen *chip) | 210 | static void wm8785_init(struct oxygen *chip) |
146 | { | 211 | { |
147 | wm8785_write(chip, 7, 0); | 212 | wm8785_write(chip, WM8785_R7, 0); |
148 | wm8785_write(chip, 0, WM8785_FORMAT_LJUST | WM8785_OSR_SINGLE); | 213 | wm8785_write(chip, WM8785_R0, WM8785_MCR_SLAVE | |
149 | wm8785_write(chip, 1, WM8785_WL_24); | 214 | WM8785_OSR_SINGLE | WM8785_FORMAT_LJUST); |
215 | wm8785_write(chip, WM8785_R1, WM8785_WL_24); | ||
150 | snd_component_add(chip->card, "WM8785"); | 216 | snd_component_add(chip->card, "WM8785"); |
151 | } | 217 | } |
152 | 218 | ||
@@ -184,18 +250,21 @@ static void set_ak4396_params(struct oxygen *chip, | |||
184 | unsigned int i; | 250 | unsigned int i; |
185 | u8 value; | 251 | u8 value; |
186 | 252 | ||
187 | value = chip->ak4396_reg1 & ~AK4396_DFS_MASK; | 253 | value = chip->ak4396_ctl2 & ~AK4396_DFS_MASK; |
188 | if (params_rate(params) <= 54000) | 254 | if (params_rate(params) <= 54000) |
189 | value |= AK4396_DFS_NORMAL; | 255 | value |= AK4396_DFS_NORMAL; |
190 | else if (params_rate(params) < 120000) | 256 | else if (params_rate(params) < 120000) |
191 | value |= AK4396_DFS_DOUBLE; | 257 | value |= AK4396_DFS_DOUBLE; |
192 | else | 258 | else |
193 | value |= AK4396_DFS_QUAD; | 259 | value |= AK4396_DFS_QUAD; |
194 | chip->ak4396_reg1 = value; | 260 | chip->ak4396_ctl2 = value; |
195 | for (i = 0; i < 4; ++i) { | 261 | for (i = 0; i < 4; ++i) { |
196 | ak4396_write(chip, i, 0, AK4396_DIF_24_MSB); | 262 | ak4396_write(chip, i, |
197 | ak4396_write(chip, i, 1, value); | 263 | AK4396_CONTROL_1, AK4396_DIF_24_MSB); |
198 | ak4396_write(chip, i, 0, AK4396_DIF_24_MSB | AK4396_RSTN); | 264 | ak4396_write(chip, i, |
265 | AK4396_CONTROL_2, value); | ||
266 | ak4396_write(chip, i, | ||
267 | AK4396_CONTROL_1, AK4396_DIF_24_MSB | AK4396_RSTN); | ||
199 | } | 268 | } |
200 | } | 269 | } |
201 | 270 | ||
@@ -204,8 +273,10 @@ static void update_ak4396_volume(struct oxygen *chip) | |||
204 | unsigned int i; | 273 | unsigned int i; |
205 | 274 | ||
206 | for (i = 0; i < 4; ++i) { | 275 | for (i = 0; i < 4; ++i) { |
207 | ak4396_write(chip, i, 3, chip->dac_volume[i * 2]); | 276 | ak4396_write(chip, i, |
208 | ak4396_write(chip, i, 4, chip->dac_volume[i * 2 + 1]); | 277 | AK4396_LCH_ATT, chip->dac_volume[i * 2]); |
278 | ak4396_write(chip, i, | ||
279 | AK4396_RCH_ATT, chip->dac_volume[i * 2 + 1]); | ||
209 | } | 280 | } |
210 | } | 281 | } |
211 | 282 | ||
@@ -214,11 +285,11 @@ static void update_ak4396_mute(struct oxygen *chip) | |||
214 | unsigned int i; | 285 | unsigned int i; |
215 | u8 value; | 286 | u8 value; |
216 | 287 | ||
217 | value = chip->ak4396_reg1 & ~AK4396_SMUTE; | 288 | value = chip->ak4396_ctl2 & ~AK4396_SMUTE; |
218 | if (chip->dac_mute) | 289 | if (chip->dac_mute) |
219 | value |= AK4396_SMUTE; | 290 | value |= AK4396_SMUTE; |
220 | for (i = 0; i < 4; ++i) | 291 | for (i = 0; i < 4; ++i) |
221 | ak4396_write(chip, i, 1, value); | 292 | ak4396_write(chip, i, AK4396_CONTROL_2, value); |
222 | } | 293 | } |
223 | 294 | ||
224 | static void set_wm8785_params(struct oxygen *chip, | 295 | static void set_wm8785_params(struct oxygen *chip, |
@@ -226,22 +297,22 @@ static void set_wm8785_params(struct oxygen *chip, | |||
226 | { | 297 | { |
227 | unsigned int value; | 298 | unsigned int value; |
228 | 299 | ||
229 | wm8785_write(chip, 7, 0); | 300 | wm8785_write(chip, WM8785_R7, 0); |
230 | 301 | ||
231 | value = WM8785_FORMAT_LJUST; | 302 | value = WM8785_MCR_SLAVE | WM8785_FORMAT_LJUST; |
232 | if (params_rate(params) == 96000) | 303 | if (params_rate(params) == 96000) |
233 | value |= WM8785_OSR_DOUBLE; | 304 | value |= WM8785_OSR_DOUBLE; |
234 | else if (params_rate(params) == 192000) | 305 | else if (params_rate(params) == 192000) |
235 | value |= WM8785_OSR_QUAD; | 306 | value |= WM8785_OSR_QUAD; |
236 | else | 307 | else |
237 | value |= WM8785_OSR_SINGLE; | 308 | value |= WM8785_OSR_SINGLE; |
238 | wm8785_write(chip, 0, value); | 309 | wm8785_write(chip, WM8785_R0, value); |
239 | 310 | ||
240 | if (snd_pcm_format_width(params_format(params)) <= 16) | 311 | if (snd_pcm_format_width(params_format(params)) <= 16) |
241 | value = WM8785_WL_16; | 312 | value = WM8785_WL_16; |
242 | else | 313 | else |
243 | value = WM8785_WL_24; | 314 | value = WM8785_WL_24; |
244 | wm8785_write(chip, 1, value); | 315 | wm8785_write(chip, WM8785_R1, value); |
245 | } | 316 | } |
246 | 317 | ||
247 | static void set_ak5385_params(struct oxygen *chip, | 318 | static void set_ak5385_params(struct oxygen *chip, |
@@ -250,12 +321,13 @@ static void set_ak5385_params(struct oxygen *chip, | |||
250 | unsigned int value; | 321 | unsigned int value; |
251 | 322 | ||
252 | if (params_rate(params) <= 54000) | 323 | if (params_rate(params) <= 54000) |
253 | value = 0; | 324 | value = GPIO_AK5385_DFS_NORMAL; |
254 | else if (params_rate(params) <= 108000) | 325 | else if (params_rate(params) <= 108000) |
255 | value = 1; | 326 | value = GPIO_AK5385_DFS_DOUBLE; |
256 | else | 327 | else |
257 | value = 2; | 328 | value = GPIO_AK5385_DFS_QUAD; |
258 | oxygen_write16_masked(chip, OXYGEN_GPIO_DATA, value, 0x0003); | 329 | oxygen_write16_masked(chip, OXYGEN_GPIO_DATA, |
330 | value, GPIO_AK5385_DFS_MASK); | ||
259 | } | 331 | } |
260 | 332 | ||
261 | static const DECLARE_TLV_DB_LINEAR(ak4396_db_scale, TLV_DB_GAIN_MUTE, 0); | 333 | static const DECLARE_TLV_DB_LINEAR(ak4396_db_scale, TLV_DB_GAIN_MUTE, 0); |
diff --git a/sound/pci/oxygen/oxygen.h b/sound/pci/oxygen/oxygen.h index 1c402cbc1c37..4f4a56a95ca2 100644 --- a/sound/pci/oxygen/oxygen.h +++ b/sound/pci/oxygen/oxygen.h | |||
@@ -56,7 +56,7 @@ struct oxygen { | |||
56 | u8 pcm_running; | 56 | u8 pcm_running; |
57 | u8 dac_routing; | 57 | u8 dac_routing; |
58 | u8 spdif_playback_enable; | 58 | u8 spdif_playback_enable; |
59 | u8 ak4396_reg1; | 59 | u8 ak4396_ctl2; |
60 | u8 revision; | 60 | u8 revision; |
61 | u8 has_ac97_0; | 61 | u8 has_ac97_0; |
62 | u8 has_ac97_1; | 62 | u8 has_ac97_1; |
diff --git a/sound/pci/oxygen/oxygen_lib.c b/sound/pci/oxygen/oxygen_lib.c index b7079adc3d92..aceb1f9e0f35 100644 --- a/sound/pci/oxygen/oxygen_lib.c +++ b/sound/pci/oxygen/oxygen_lib.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <sound/mpu401.h> | 28 | #include <sound/mpu401.h> |
29 | #include <sound/pcm.h> | 29 | #include <sound/pcm.h> |
30 | #include "oxygen.h" | 30 | #include "oxygen.h" |
31 | #include "cm9780.h" | ||
31 | 32 | ||
32 | MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>"); | 33 | MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>"); |
33 | MODULE_DESCRIPTION("C-Media CMI8788 helper library"); | 34 | MODULE_DESCRIPTION("C-Media CMI8788 helper library"); |
@@ -262,9 +263,15 @@ static void __devinit oxygen_init(struct oxygen *chip) | |||
262 | OXYGEN_AC97_CODEC0_LINER); | 263 | OXYGEN_AC97_CODEC0_LINER); |
263 | oxygen_write_ac97(chip, 0, AC97_RESET, 0); | 264 | oxygen_write_ac97(chip, 0, AC97_RESET, 0); |
264 | msleep(1); | 265 | msleep(1); |
265 | oxygen_ac97_set_bits(chip, 0, 0x70, 0x0300); | 266 | oxygen_ac97_set_bits(chip, 0, CM9780_GPIO_SETUP, |
266 | oxygen_ac97_set_bits(chip, 0, 0x64, 0x8043); | 267 | CM9780_GPIO0IO | CM9780_GPIO1IO); |
267 | oxygen_ac97_set_bits(chip, 0, 0x62, 0x180f); | 268 | oxygen_ac97_set_bits(chip, 0, CM9780_MIXER, |
269 | CM9780_BSTSEL | CM9780_STRO_MIC | | ||
270 | CM9780_MIX2FR | CM9780_PCBSW); | ||
271 | oxygen_ac97_set_bits(chip, 0, CM9780_JACK, | ||
272 | CM9780_RSOE | CM9780_CBOE | | ||
273 | CM9780_SSOE | CM9780_FROE | | ||
274 | CM9780_MIC2MIC | CM9780_LI2LI); | ||
268 | oxygen_write_ac97(chip, 0, AC97_MASTER, 0x0000); | 275 | oxygen_write_ac97(chip, 0, AC97_MASTER, 0x0000); |
269 | oxygen_write_ac97(chip, 0, AC97_PC_BEEP, 0x8000); | 276 | oxygen_write_ac97(chip, 0, AC97_PC_BEEP, 0x8000); |
270 | oxygen_write_ac97(chip, 0, AC97_MIC, 0x8808); | 277 | oxygen_write_ac97(chip, 0, AC97_MIC, 0x8808); |
@@ -275,7 +282,8 @@ static void __devinit oxygen_init(struct oxygen *chip) | |||
275 | oxygen_write_ac97(chip, 0, AC97_REC_GAIN, 0x8000); | 282 | oxygen_write_ac97(chip, 0, AC97_REC_GAIN, 0x8000); |
276 | oxygen_write_ac97(chip, 0, AC97_CENTER_LFE_MASTER, 0x8080); | 283 | oxygen_write_ac97(chip, 0, AC97_CENTER_LFE_MASTER, 0x8080); |
277 | oxygen_write_ac97(chip, 0, AC97_SURROUND_MASTER, 0x8080); | 284 | oxygen_write_ac97(chip, 0, AC97_SURROUND_MASTER, 0x8080); |
278 | oxygen_ac97_clear_bits(chip, 0, 0x72, 0x0001); | 285 | oxygen_ac97_clear_bits(chip, 0, |
286 | CM9780_GPIO_STATUS, CM9780_GPO0); | ||
279 | /* power down unused ADCs and DACs */ | 287 | /* power down unused ADCs and DACs */ |
280 | oxygen_ac97_set_bits(chip, 0, AC97_POWERDOWN, | 288 | oxygen_ac97_set_bits(chip, 0, AC97_POWERDOWN, |
281 | AC97_PD_PR0 | AC97_PD_PR1); | 289 | AC97_PD_PR0 | AC97_PD_PR1); |
diff --git a/sound/pci/oxygen/oxygen_mixer.c b/sound/pci/oxygen/oxygen_mixer.c index d23d18aed25c..11114cedc05d 100644 --- a/sound/pci/oxygen/oxygen_mixer.c +++ b/sound/pci/oxygen/oxygen_mixer.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <sound/control.h> | 23 | #include <sound/control.h> |
24 | #include <sound/tlv.h> | 24 | #include <sound/tlv.h> |
25 | #include "oxygen.h" | 25 | #include "oxygen.h" |
26 | #include "cm9780.h" | ||
26 | 27 | ||
27 | static int dac_volume_info(struct snd_kcontrol *ctl, | 28 | static int dac_volume_info(struct snd_kcontrol *ctl, |
28 | struct snd_ctl_elem_info *info) | 29 | struct snd_ctl_elem_info *info) |
@@ -460,8 +461,9 @@ static int ac97_switch_put(struct snd_kcontrol *ctl, | |||
460 | if (change) { | 461 | if (change) { |
461 | oxygen_write_ac97(chip, 0, index, newreg); | 462 | oxygen_write_ac97(chip, 0, index, newreg); |
462 | if (index == AC97_LINE) { | 463 | if (index == AC97_LINE) { |
463 | oxygen_write_ac97_masked(chip, 0, 0x72, | 464 | oxygen_write_ac97_masked(chip, 0, CM9780_GPIO_STATUS, |
464 | !!(newreg & 0x8000), 0x0001); | 465 | newreg & 0x8000 ? |
466 | CM9780_GPO0 : 0, CM9780_GPO0); | ||
465 | if (!(newreg & 0x8000)) { | 467 | if (!(newreg & 0x8000)) { |
466 | ac97_mute_ctl(chip, CONTROL_MIC_CAPTURE_SWITCH); | 468 | ac97_mute_ctl(chip, CONTROL_MIC_CAPTURE_SWITCH); |
467 | ac97_mute_ctl(chip, CONTROL_CD_CAPTURE_SWITCH); | 469 | ac97_mute_ctl(chip, CONTROL_CD_CAPTURE_SWITCH); |
@@ -471,7 +473,8 @@ static int ac97_switch_put(struct snd_kcontrol *ctl, | |||
471 | index == AC97_VIDEO || index == AC97_AUX) && | 473 | index == AC97_VIDEO || index == AC97_AUX) && |
472 | bitnr == 15 && !(newreg & 0x8000)) { | 474 | bitnr == 15 && !(newreg & 0x8000)) { |
473 | ac97_mute_ctl(chip, CONTROL_LINE_CAPTURE_SWITCH); | 475 | ac97_mute_ctl(chip, CONTROL_LINE_CAPTURE_SWITCH); |
474 | oxygen_write_ac97_masked(chip, 0, 0x72, 0x0001, 0x0001); | 476 | oxygen_write_ac97_masked(chip, 0, CM9780_GPIO_STATUS, |
477 | CM9780_GPO0, CM9780_GPO0); | ||
475 | } | 478 | } |
476 | } | 479 | } |
477 | mutex_unlock(&chip->mutex); | 480 | mutex_unlock(&chip->mutex); |
diff --git a/sound/pci/oxygen/virtuoso.c b/sound/pci/oxygen/virtuoso.c index 73975711c074..7b240c778759 100644 --- a/sound/pci/oxygen/virtuoso.c +++ b/sound/pci/oxygen/virtuoso.c | |||
@@ -18,6 +18,8 @@ | |||
18 | */ | 18 | */ |
19 | 19 | ||
20 | /* | 20 | /* |
21 | * CMI8788: | ||
22 | * | ||
21 | * SPI 0 -> 1st PCM1796 (front) | 23 | * SPI 0 -> 1st PCM1796 (front) |
22 | * SPI 1 -> 2nd PCM1796 (surround) | 24 | * SPI 1 -> 2nd PCM1796 (surround) |
23 | * SPI 2 -> 3rd PCM1796 (center/LFE) | 25 | * SPI 2 -> 3rd PCM1796 (center/LFE) |
@@ -25,9 +27,13 @@ | |||
25 | * | 27 | * |
26 | * GPIO 2 -> M0 of CS5381 | 28 | * GPIO 2 -> M0 of CS5381 |
27 | * GPIO 3 -> M1 of CS5381 | 29 | * GPIO 3 -> M1 of CS5381 |
28 | * GPIO 5 <- ? (D2X only) | 30 | * GPIO 5 <- external power present (D2X only) |
29 | * GPIO 7 -> ALT | 31 | * GPIO 7 -> ALT |
30 | * GPIO 8 -> ? (amps enable?) | 32 | * GPIO 8 -> enable output to speakers |
33 | * | ||
34 | * CM9780: | ||
35 | * | ||
36 | * GPIO 0 -> enable AC'97 bypass (line in -> ADC) | ||
31 | */ | 37 | */ |
32 | 38 | ||
33 | #include <linux/pci.h> | 39 | #include <linux/pci.h> |
@@ -40,6 +46,7 @@ | |||
40 | #include <sound/pcm.h> | 46 | #include <sound/pcm.h> |
41 | #include <sound/tlv.h> | 47 | #include <sound/tlv.h> |
42 | #include "oxygen.h" | 48 | #include "oxygen.h" |
49 | #include "cm9780.h" | ||
43 | 50 | ||
44 | MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>"); | 51 | MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>"); |
45 | MODULE_DESCRIPTION("Asus AV200 driver"); | 52 | MODULE_DESCRIPTION("Asus AV200 driver"); |
@@ -64,14 +71,68 @@ static struct pci_device_id xonar_ids[] __devinitdata = { | |||
64 | }; | 71 | }; |
65 | MODULE_DEVICE_TABLE(pci, xonar_ids); | 72 | MODULE_DEVICE_TABLE(pci, xonar_ids); |
66 | 73 | ||
67 | /* register 0x12 */ | 74 | |
75 | #define GPIO_CS5381_M_MASK 0x000c | ||
76 | #define GPIO_CS5381_M_SINGLE 0x0000 | ||
77 | #define GPIO_CS5381_M_DOUBLE 0x0004 | ||
78 | #define GPIO_CS5381_M_QUAD 0x0008 | ||
79 | #define GPIO_EXT_POWER 0x0020 | ||
80 | #define GPIO_ALT 0x0080 | ||
81 | #define GPIO_OUTPUT_ENABLE 0x0100 | ||
82 | |||
83 | /* register 16 */ | ||
84 | #define PCM1796_ATL_MASK 0xff | ||
85 | /* register 17 */ | ||
86 | #define PCM1796_ATR_MASK 0xff | ||
87 | /* register 18 */ | ||
68 | #define PCM1796_MUTE 0x01 | 88 | #define PCM1796_MUTE 0x01 |
69 | #define PCM1796_FMT_24_MSB 0x30 | 89 | #define PCM1796_DME 0x02 |
90 | #define PCM1796_DMF_MASK 0x0c | ||
91 | #define PCM1796_DMF_DISABLED 0x00 | ||
92 | #define PCM1796_DMF_48 0x04 | ||
93 | #define PCM1796_DMF_441 0x08 | ||
94 | #define PCM1796_DMF_32 0x0c | ||
95 | #define PCM1796_FMT_MASK 0x70 | ||
96 | #define PCM1796_FMT_16_RJUST 0x00 | ||
97 | #define PCM1796_FMT_20_RJUST 0x10 | ||
98 | #define PCM1796_FMT_24_RJUST 0x20 | ||
99 | #define PCM1796_FMT_24_LJUST 0x30 | ||
100 | #define PCM1796_FMT_16_I2S 0x40 | ||
101 | #define PCM1796_FMT_24_I2S 0x50 | ||
70 | #define PCM1796_ATLD 0x80 | 102 | #define PCM1796_ATLD 0x80 |
71 | /* register 0x14 */ | 103 | /* register 19 */ |
104 | #define PCM1796_INZD 0x01 | ||
105 | #define PCM1796_FLT_MASK 0x02 | ||
106 | #define PCM1796_FLT_SHARP 0x00 | ||
107 | #define PCM1796_FLT_SLOW 0x02 | ||
108 | #define PCM1796_DFMS 0x04 | ||
109 | #define PCM1796_OPE 0x10 | ||
110 | #define PCM1796_ATS_MASK 0x60 | ||
111 | #define PCM1796_ATS_1 0x00 | ||
112 | #define PCM1796_ATS_2 0x20 | ||
113 | #define PCM1796_ATS_4 0x40 | ||
114 | #define PCM1796_ATS_8 0x60 | ||
115 | #define PCM1796_REV 0x80 | ||
116 | /* register 20 */ | ||
117 | #define PCM1796_OS_MASK 0x03 | ||
72 | #define PCM1796_OS_64 0x00 | 118 | #define PCM1796_OS_64 0x00 |
73 | #define PCM1796_OS_32 0x01 | 119 | #define PCM1796_OS_32 0x01 |
74 | #define PCM1796_OS_128 0x02 | 120 | #define PCM1796_OS_128 0x02 |
121 | #define PCM1796_CHSL_MASK 0x04 | ||
122 | #define PCM1796_CHSL_LEFT 0x00 | ||
123 | #define PCM1796_CHSL_RIGHT 0x04 | ||
124 | #define PCM1796_MONO 0x08 | ||
125 | #define PCM1796_DFTH 0x10 | ||
126 | #define PCM1796_DSD 0x20 | ||
127 | #define PCM1796_SRST 0x40 | ||
128 | /* register 21 */ | ||
129 | #define PCM1796_PCMZ 0x01 | ||
130 | #define PCM1796_DZ_MASK 0x06 | ||
131 | /* register 22 */ | ||
132 | #define PCM1796_ZFGL 0x01 | ||
133 | #define PCM1796_ZFGR 0x02 | ||
134 | /* register 23 */ | ||
135 | #define PCM1796_ID_MASK 0x1f | ||
75 | 136 | ||
76 | static void pcm1796_write(struct oxygen *chip, unsigned int codec, | 137 | static void pcm1796_write(struct oxygen *chip, unsigned int codec, |
77 | u8 reg, u8 value) | 138 | u8 reg, u8 value) |
@@ -93,20 +154,23 @@ static void xonar_init(struct oxygen *chip) | |||
93 | unsigned int i; | 154 | unsigned int i; |
94 | 155 | ||
95 | for (i = 0; i < 4; ++i) { | 156 | for (i = 0; i < 4; ++i) { |
96 | pcm1796_write(chip, i, 0x12, PCM1796_FMT_24_MSB | PCM1796_ATLD); | 157 | pcm1796_write(chip, i, 18, PCM1796_FMT_24_LJUST | PCM1796_ATLD); |
97 | pcm1796_write(chip, i, 0x13, 0); | 158 | pcm1796_write(chip, i, 19, PCM1796_FLT_SHARP | PCM1796_ATS_1); |
98 | pcm1796_write(chip, i, 0x14, PCM1796_OS_64); | 159 | pcm1796_write(chip, i, 20, PCM1796_OS_64); |
99 | pcm1796_write(chip, i, 0x15, 0); | 160 | pcm1796_write(chip, i, 21, 0); |
100 | pcm1796_write(chip, i, 0x10, 0xff); | 161 | pcm1796_write(chip, i, 16, 0xff); /* set ATL/ATR after ATLD */ |
101 | pcm1796_write(chip, i, 0x11, 0xff); | 162 | pcm1796_write(chip, i, 17, 0xff); |
102 | } | 163 | } |
103 | 164 | ||
104 | oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, 0x8c); | 165 | oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, |
105 | oxygen_write16_masked(chip, OXYGEN_GPIO_DATA, 0x00, 0x8c); | 166 | GPIO_CS5381_M_MASK | GPIO_ALT); |
106 | oxygen_ac97_set_bits(chip, 0, 0x62, 0x0080); | 167 | oxygen_write16_masked(chip, OXYGEN_GPIO_DATA, |
168 | GPIO_CS5381_M_SINGLE, | ||
169 | GPIO_CS5381_M_MASK | GPIO_ALT); | ||
170 | oxygen_ac97_set_bits(chip, 0, CM9780_JACK, CM9780_FMIC2MIC); | ||
107 | msleep(300); | 171 | msleep(300); |
108 | oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, 0x100); | 172 | oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, GPIO_OUTPUT_ENABLE); |
109 | oxygen_set_bits16(chip, OXYGEN_GPIO_DATA, 0x100); | 173 | oxygen_set_bits16(chip, OXYGEN_GPIO_DATA, GPIO_OUTPUT_ENABLE); |
110 | 174 | ||
111 | snd_component_add(chip->card, "PCM1796"); | 175 | snd_component_add(chip->card, "PCM1796"); |
112 | snd_component_add(chip->card, "CS5381"); | 176 | snd_component_add(chip->card, "CS5381"); |
@@ -114,7 +178,7 @@ static void xonar_init(struct oxygen *chip) | |||
114 | 178 | ||
115 | static void xonar_cleanup(struct oxygen *chip) | 179 | static void xonar_cleanup(struct oxygen *chip) |
116 | { | 180 | { |
117 | oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, 0x100); | 181 | oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, GPIO_OUTPUT_ENABLE); |
118 | } | 182 | } |
119 | 183 | ||
120 | static void set_pcm1796_params(struct oxygen *chip, | 184 | static void set_pcm1796_params(struct oxygen *chip, |
@@ -126,7 +190,7 @@ static void set_pcm1796_params(struct oxygen *chip, | |||
126 | 190 | ||
127 | value = params_rate(params) >= 96000 ? PCM1796_OS_32 : PCM1796_OS_64; | 191 | value = params_rate(params) >= 96000 ? PCM1796_OS_32 : PCM1796_OS_64; |
128 | for (i = 0; i < 4; ++i) | 192 | for (i = 0; i < 4; ++i) |
129 | pcm1796_write(chip, i, 0x14, value); | 193 | pcm1796_write(chip, i, 20, value); |
130 | #endif | 194 | #endif |
131 | } | 195 | } |
132 | 196 | ||
@@ -135,8 +199,8 @@ static void update_pcm1796_volume(struct oxygen *chip) | |||
135 | unsigned int i; | 199 | unsigned int i; |
136 | 200 | ||
137 | for (i = 0; i < 4; ++i) { | 201 | for (i = 0; i < 4; ++i) { |
138 | pcm1796_write(chip, i, 0x10, chip->dac_volume[i * 2]); | 202 | pcm1796_write(chip, i, 16, chip->dac_volume[i * 2]); |
139 | pcm1796_write(chip, i, 0x11, chip->dac_volume[i * 2 + 1]); | 203 | pcm1796_write(chip, i, 17, chip->dac_volume[i * 2 + 1]); |
140 | } | 204 | } |
141 | } | 205 | } |
142 | 206 | ||
@@ -145,11 +209,11 @@ static void update_pcm1796_mute(struct oxygen *chip) | |||
145 | unsigned int i; | 209 | unsigned int i; |
146 | u8 value; | 210 | u8 value; |
147 | 211 | ||
148 | value = PCM1796_FMT_24_MSB | PCM1796_ATLD; | 212 | value = PCM1796_FMT_24_LJUST | PCM1796_ATLD; |
149 | if (chip->dac_mute) | 213 | if (chip->dac_mute) |
150 | value |= PCM1796_MUTE; | 214 | value |= PCM1796_MUTE; |
151 | for (i = 0; i < 4; ++i) | 215 | for (i = 0; i < 4; ++i) |
152 | pcm1796_write(chip, i, 0x12, value); | 216 | pcm1796_write(chip, i, 18, value); |
153 | } | 217 | } |
154 | 218 | ||
155 | static void set_cs5381_params(struct oxygen *chip, | 219 | static void set_cs5381_params(struct oxygen *chip, |
@@ -158,12 +222,13 @@ static void set_cs5381_params(struct oxygen *chip, | |||
158 | unsigned int value; | 222 | unsigned int value; |
159 | 223 | ||
160 | if (params_rate(params) <= 54000) | 224 | if (params_rate(params) <= 54000) |
161 | value = 0; | 225 | value = GPIO_CS5381_M_SINGLE; |
162 | else if (params_rate(params) <= 108000) | 226 | else if (params_rate(params) <= 108000) |
163 | value = 4; | 227 | value = GPIO_CS5381_M_DOUBLE; |
164 | else | 228 | else |
165 | value = 8; | 229 | value = GPIO_CS5381_M_QUAD; |
166 | oxygen_write16_masked(chip, OXYGEN_GPIO_DATA, value, 0x000c); | 230 | oxygen_write16_masked(chip, OXYGEN_GPIO_DATA, |
231 | value, GPIO_CS5381_M_MASK); | ||
167 | } | 232 | } |
168 | 233 | ||
169 | static int pcm1796_volume_info(struct snd_kcontrol *ctl, | 234 | static int pcm1796_volume_info(struct snd_kcontrol *ctl, |
@@ -182,7 +247,7 @@ static int alt_switch_get(struct snd_kcontrol *ctl, | |||
182 | struct oxygen *chip = ctl->private_data; | 247 | struct oxygen *chip = ctl->private_data; |
183 | 248 | ||
184 | value->value.integer.value[0] = | 249 | value->value.integer.value[0] = |
185 | !!(oxygen_read16(chip, OXYGEN_GPIO_DATA) & 0x80); | 250 | !!(oxygen_read16(chip, OXYGEN_GPIO_DATA) & GPIO_ALT); |
186 | return 0; | 251 | return 0; |
187 | } | 252 | } |
188 | 253 | ||
@@ -196,9 +261,9 @@ static int alt_switch_put(struct snd_kcontrol *ctl, | |||
196 | spin_lock_irq(&chip->reg_lock); | 261 | spin_lock_irq(&chip->reg_lock); |
197 | old_bits = oxygen_read16(chip, OXYGEN_GPIO_DATA); | 262 | old_bits = oxygen_read16(chip, OXYGEN_GPIO_DATA); |
198 | if (value->value.integer.value[0]) | 263 | if (value->value.integer.value[0]) |
199 | new_bits = old_bits | 0x80; | 264 | new_bits = old_bits | GPIO_ALT; |
200 | else | 265 | else |
201 | new_bits = old_bits & ~0x80; | 266 | new_bits = old_bits & ~GPIO_ALT; |
202 | changed = new_bits != old_bits; | 267 | changed = new_bits != old_bits; |
203 | if (changed) | 268 | if (changed) |
204 | oxygen_write16(chip, OXYGEN_GPIO_DATA, new_bits); | 269 | oxygen_write16(chip, OXYGEN_GPIO_DATA, new_bits); |