diff options
Diffstat (limited to 'sound/pci/oxygen/oxygen.c')
-rw-r--r-- | sound/pci/oxygen/oxygen.c | 129 |
1 files changed, 28 insertions, 101 deletions
diff --git a/sound/pci/oxygen/oxygen.c b/sound/pci/oxygen/oxygen.c index 9a9941bb0460..63f185c1ed1e 100644 --- a/sound/pci/oxygen/oxygen.c +++ b/sound/pci/oxygen/oxygen.c | |||
@@ -39,7 +39,7 @@ | |||
39 | #include <sound/tlv.h> | 39 | #include <sound/tlv.h> |
40 | #include "oxygen.h" | 40 | #include "oxygen.h" |
41 | #include "ak4396.h" | 41 | #include "ak4396.h" |
42 | #include "cm9780.h" | 42 | #include "wm8785.h" |
43 | 43 | ||
44 | MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>"); | 44 | MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>"); |
45 | MODULE_DESCRIPTION("C-Media CMI8788 driver"); | 45 | MODULE_DESCRIPTION("C-Media CMI8788 driver"); |
@@ -78,49 +78,6 @@ MODULE_DEVICE_TABLE(pci, oxygen_ids); | |||
78 | #define GPIO_AK5385_DFS_DOUBLE 0x0001 | 78 | #define GPIO_AK5385_DFS_DOUBLE 0x0001 |
79 | #define GPIO_AK5385_DFS_QUAD 0x0002 | 79 | #define GPIO_AK5385_DFS_QUAD 0x0002 |
80 | 80 | ||
81 | #define GPIO_LINE_MUTE CM9780_GPO0 | ||
82 | |||
83 | #define WM8785_R0 0 | ||
84 | #define WM8785_R1 1 | ||
85 | #define WM8785_R2 2 | ||
86 | #define WM8785_R7 7 | ||
87 | |||
88 | /* R0 */ | ||
89 | #define WM8785_MCR_MASK 0x007 | ||
90 | #define WM8785_MCR_SLAVE 0x000 | ||
91 | #define WM8785_MCR_MASTER_128 0x001 | ||
92 | #define WM8785_MCR_MASTER_192 0x002 | ||
93 | #define WM8785_MCR_MASTER_256 0x003 | ||
94 | #define WM8785_MCR_MASTER_384 0x004 | ||
95 | #define WM8785_MCR_MASTER_512 0x005 | ||
96 | #define WM8785_MCR_MASTER_768 0x006 | ||
97 | #define WM8785_OSR_MASK 0x018 | ||
98 | #define WM8785_OSR_SINGLE 0x000 | ||
99 | #define WM8785_OSR_DOUBLE 0x008 | ||
100 | #define WM8785_OSR_QUAD 0x010 | ||
101 | #define WM8785_FORMAT_MASK 0x060 | ||
102 | #define WM8785_FORMAT_RJUST 0x000 | ||
103 | #define WM8785_FORMAT_LJUST 0x020 | ||
104 | #define WM8785_FORMAT_I2S 0x040 | ||
105 | #define WM8785_FORMAT_DSP 0x060 | ||
106 | /* R1 */ | ||
107 | #define WM8785_WL_MASK 0x003 | ||
108 | #define WM8785_WL_16 0x000 | ||
109 | #define WM8785_WL_20 0x001 | ||
110 | #define WM8785_WL_24 0x002 | ||
111 | #define WM8785_WL_32 0x003 | ||
112 | #define WM8785_LRP 0x004 | ||
113 | #define WM8785_BCLKINV 0x008 | ||
114 | #define WM8785_LRSWAP 0x010 | ||
115 | #define WM8785_DEVNO_MASK 0x0e0 | ||
116 | /* R2 */ | ||
117 | #define WM8785_HPFR 0x001 | ||
118 | #define WM8785_HPFL 0x002 | ||
119 | #define WM8785_SDODIS 0x004 | ||
120 | #define WM8785_PWRDNR 0x008 | ||
121 | #define WM8785_PWRDNL 0x010 | ||
122 | #define WM8785_TDM_MASK 0x1c0 | ||
123 | |||
124 | struct generic_data { | 81 | struct generic_data { |
125 | u8 ak4396_ctl2; | 82 | u8 ak4396_ctl2; |
126 | }; | 83 | }; |
@@ -155,7 +112,7 @@ static void ak4396_init(struct oxygen *chip) | |||
155 | struct generic_data *data = chip->model_data; | 112 | struct generic_data *data = chip->model_data; |
156 | unsigned int i; | 113 | unsigned int i; |
157 | 114 | ||
158 | data->ak4396_ctl2 = AK4396_DEM_OFF | AK4396_DFS_NORMAL; | 115 | data->ak4396_ctl2 = AK4396_SMUTE | AK4396_DEM_OFF | AK4396_DFS_NORMAL; |
159 | for (i = 0; i < 4; ++i) { | 116 | for (i = 0; i < 4; ++i) { |
160 | ak4396_write(chip, i, | 117 | ak4396_write(chip, i, |
161 | AK4396_CONTROL_1, AK4396_DIF_24_MSB | AK4396_RSTN); | 118 | AK4396_CONTROL_1, AK4396_DIF_24_MSB | AK4396_RSTN); |
@@ -163,8 +120,8 @@ static void ak4396_init(struct oxygen *chip) | |||
163 | AK4396_CONTROL_2, data->ak4396_ctl2); | 120 | AK4396_CONTROL_2, data->ak4396_ctl2); |
164 | ak4396_write(chip, i, | 121 | ak4396_write(chip, i, |
165 | AK4396_CONTROL_3, AK4396_PCM); | 122 | AK4396_CONTROL_3, AK4396_PCM); |
166 | ak4396_write(chip, i, AK4396_LCH_ATT, 0xff); | 123 | ak4396_write(chip, i, AK4396_LCH_ATT, 0); |
167 | ak4396_write(chip, i, AK4396_RCH_ATT, 0xff); | 124 | ak4396_write(chip, i, AK4396_RCH_ATT, 0); |
168 | } | 125 | } |
169 | snd_component_add(chip->card, "AK4396"); | 126 | snd_component_add(chip->card, "AK4396"); |
170 | } | 127 | } |
@@ -185,23 +142,16 @@ static void wm8785_init(struct oxygen *chip) | |||
185 | snd_component_add(chip->card, "WM8785"); | 142 | snd_component_add(chip->card, "WM8785"); |
186 | } | 143 | } |
187 | 144 | ||
188 | static void cmi9780_init(struct oxygen *chip) | ||
189 | { | ||
190 | oxygen_ac97_clear_bits(chip, 0, CM9780_GPIO_STATUS, GPIO_LINE_MUTE); | ||
191 | } | ||
192 | |||
193 | static void generic_init(struct oxygen *chip) | 145 | static void generic_init(struct oxygen *chip) |
194 | { | 146 | { |
195 | ak4396_init(chip); | 147 | ak4396_init(chip); |
196 | wm8785_init(chip); | 148 | wm8785_init(chip); |
197 | cmi9780_init(chip); | ||
198 | } | 149 | } |
199 | 150 | ||
200 | static void meridian_init(struct oxygen *chip) | 151 | static void meridian_init(struct oxygen *chip) |
201 | { | 152 | { |
202 | ak4396_init(chip); | 153 | ak4396_init(chip); |
203 | ak5385_init(chip); | 154 | ak5385_init(chip); |
204 | cmi9780_init(chip); | ||
205 | } | 155 | } |
206 | 156 | ||
207 | static void generic_cleanup(struct oxygen *chip) | 157 | static void generic_cleanup(struct oxygen *chip) |
@@ -297,59 +247,32 @@ static void set_ak5385_params(struct oxygen *chip, | |||
297 | value, GPIO_AK5385_DFS_MASK); | 247 | value, GPIO_AK5385_DFS_MASK); |
298 | } | 248 | } |
299 | 249 | ||
300 | static void cmi9780_switch_hook(struct oxygen *chip, unsigned int codec, | ||
301 | unsigned int reg, int mute) | ||
302 | { | ||
303 | if (codec != 0) | ||
304 | return; | ||
305 | switch (reg) { | ||
306 | case AC97_LINE: | ||
307 | oxygen_write_ac97_masked(chip, 0, CM9780_GPIO_STATUS, | ||
308 | mute ? GPIO_LINE_MUTE : 0, | ||
309 | GPIO_LINE_MUTE); | ||
310 | break; | ||
311 | case AC97_MIC: | ||
312 | case AC97_CD: | ||
313 | case AC97_AUX: | ||
314 | if (!mute) | ||
315 | oxygen_ac97_set_bits(chip, 0, CM9780_GPIO_STATUS, | ||
316 | GPIO_LINE_MUTE); | ||
317 | break; | ||
318 | } | ||
319 | } | ||
320 | |||
321 | static const DECLARE_TLV_DB_LINEAR(ak4396_db_scale, TLV_DB_GAIN_MUTE, 0); | 250 | static const DECLARE_TLV_DB_LINEAR(ak4396_db_scale, TLV_DB_GAIN_MUTE, 0); |
322 | 251 | ||
323 | static int ak4396_control_filter(struct snd_kcontrol_new *template) | ||
324 | { | ||
325 | if (!strcmp(template->name, "Master Playback Volume")) { | ||
326 | template->access |= SNDRV_CTL_ELEM_ACCESS_TLV_READ; | ||
327 | template->tlv.p = ak4396_db_scale; | ||
328 | } | ||
329 | return 0; | ||
330 | } | ||
331 | |||
332 | static const struct oxygen_model model_generic = { | 252 | static const struct oxygen_model model_generic = { |
333 | .shortname = "C-Media CMI8788", | 253 | .shortname = "C-Media CMI8788", |
334 | .longname = "C-Media Oxygen HD Audio", | 254 | .longname = "C-Media Oxygen HD Audio", |
335 | .chip = "CMI8788", | 255 | .chip = "CMI8788", |
336 | .owner = THIS_MODULE, | 256 | .owner = THIS_MODULE, |
337 | .init = generic_init, | 257 | .init = generic_init, |
338 | .control_filter = ak4396_control_filter, | ||
339 | .cleanup = generic_cleanup, | 258 | .cleanup = generic_cleanup, |
340 | .set_dac_params = set_ak4396_params, | 259 | .set_dac_params = set_ak4396_params, |
341 | .set_adc_params = set_wm8785_params, | 260 | .set_adc_params = set_wm8785_params, |
342 | .update_dac_volume = update_ak4396_volume, | 261 | .update_dac_volume = update_ak4396_volume, |
343 | .update_dac_mute = update_ak4396_mute, | 262 | .update_dac_mute = update_ak4396_mute, |
344 | .ac97_switch_hook = cmi9780_switch_hook, | 263 | .dac_tlv = ak4396_db_scale, |
345 | .model_data_size = sizeof(struct generic_data), | 264 | .model_data_size = sizeof(struct generic_data), |
265 | .pcm_dev_cfg = PLAYBACK_0_TO_I2S | | ||
266 | PLAYBACK_1_TO_SPDIF | | ||
267 | PLAYBACK_2_TO_AC97_1 | | ||
268 | CAPTURE_0_FROM_I2S_1 | | ||
269 | CAPTURE_1_FROM_SPDIF | | ||
270 | CAPTURE_2_FROM_AC97_1, | ||
346 | .dac_channels = 8, | 271 | .dac_channels = 8, |
347 | .used_channels = OXYGEN_CHANNEL_A | | 272 | .dac_volume_min = 0, |
348 | OXYGEN_CHANNEL_C | | 273 | .dac_volume_max = 255, |
349 | OXYGEN_CHANNEL_SPDIF | | 274 | .function_flags = OXYGEN_FUNCTION_SPI | |
350 | OXYGEN_CHANNEL_MULTICH | | 275 | OXYGEN_FUNCTION_ENABLE_SPI_4_5, |
351 | OXYGEN_CHANNEL_AC97, | ||
352 | .function_flags = OXYGEN_FUNCTION_ENABLE_SPI_4_5, | ||
353 | .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST, | 276 | .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST, |
354 | .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST, | 277 | .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST, |
355 | }; | 278 | }; |
@@ -359,21 +282,25 @@ static const struct oxygen_model model_meridian = { | |||
359 | .chip = "CMI8788", | 282 | .chip = "CMI8788", |
360 | .owner = THIS_MODULE, | 283 | .owner = THIS_MODULE, |
361 | .init = meridian_init, | 284 | .init = meridian_init, |
362 | .control_filter = ak4396_control_filter, | ||
363 | .cleanup = generic_cleanup, | 285 | .cleanup = generic_cleanup, |
364 | .set_dac_params = set_ak4396_params, | 286 | .set_dac_params = set_ak4396_params, |
365 | .set_adc_params = set_ak5385_params, | 287 | .set_adc_params = set_ak5385_params, |
366 | .update_dac_volume = update_ak4396_volume, | 288 | .update_dac_volume = update_ak4396_volume, |
367 | .update_dac_mute = update_ak4396_mute, | 289 | .update_dac_mute = update_ak4396_mute, |
368 | .ac97_switch_hook = cmi9780_switch_hook, | 290 | .dac_tlv = ak4396_db_scale, |
369 | .model_data_size = sizeof(struct generic_data), | 291 | .model_data_size = sizeof(struct generic_data), |
292 | .pcm_dev_cfg = PLAYBACK_0_TO_I2S | | ||
293 | PLAYBACK_1_TO_SPDIF | | ||
294 | PLAYBACK_2_TO_AC97_1 | | ||
295 | CAPTURE_0_FROM_I2S_2 | | ||
296 | CAPTURE_1_FROM_SPDIF | | ||
297 | CAPTURE_2_FROM_AC97_1, | ||
370 | .dac_channels = 8, | 298 | .dac_channels = 8, |
371 | .used_channels = OXYGEN_CHANNEL_B | | 299 | .dac_volume_min = 0, |
372 | OXYGEN_CHANNEL_C | | 300 | .dac_volume_max = 255, |
373 | OXYGEN_CHANNEL_SPDIF | | 301 | .misc_flags = OXYGEN_MISC_MIDI, |
374 | OXYGEN_CHANNEL_MULTICH | | 302 | .function_flags = OXYGEN_FUNCTION_SPI | |
375 | OXYGEN_CHANNEL_AC97, | 303 | OXYGEN_FUNCTION_ENABLE_SPI_4_5, |
376 | .function_flags = OXYGEN_FUNCTION_ENABLE_SPI_4_5, | ||
377 | .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST, | 304 | .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST, |
378 | .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST, | 305 | .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST, |
379 | }; | 306 | }; |
@@ -392,7 +319,7 @@ static int __devinit generic_oxygen_probe(struct pci_dev *pci, | |||
392 | return -ENOENT; | 319 | return -ENOENT; |
393 | } | 320 | } |
394 | is_meridian = pci_id->driver_data; | 321 | is_meridian = pci_id->driver_data; |
395 | err = oxygen_pci_probe(pci, index[dev], id[dev], is_meridian, | 322 | err = oxygen_pci_probe(pci, index[dev], id[dev], |
396 | is_meridian ? &model_meridian : &model_generic); | 323 | is_meridian ? &model_meridian : &model_generic); |
397 | if (err >= 0) | 324 | if (err >= 0) |
398 | ++dev; | 325 | ++dev; |