aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/oxygen/oxygen.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci/oxygen/oxygen.c')
-rw-r--r--sound/pci/oxygen/oxygen.c129
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
44MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>"); 44MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
45MODULE_DESCRIPTION("C-Media CMI8788 driver"); 45MODULE_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
124struct generic_data { 81struct 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
188static void cmi9780_init(struct oxygen *chip)
189{
190 oxygen_ac97_clear_bits(chip, 0, CM9780_GPIO_STATUS, GPIO_LINE_MUTE);
191}
192
193static void generic_init(struct oxygen *chip) 145static 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
200static void meridian_init(struct oxygen *chip) 151static 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
207static void generic_cleanup(struct oxygen *chip) 157static 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
300static 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
321static const DECLARE_TLV_DB_LINEAR(ak4396_db_scale, TLV_DB_GAIN_MUTE, 0); 250static const DECLARE_TLV_DB_LINEAR(ak4396_db_scale, TLV_DB_GAIN_MUTE, 0);
322 251
323static 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
332static const struct oxygen_model model_generic = { 252static 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;