2 * card driver for the Xonar DG
4 * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
7 * This driver is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License, version 2.
10 * This driver is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this driver; if not, see <http://www.gnu.org/licenses/>.
28 * I²S 2 -> CS4361 (center/LFE)
29 * I²S 3 -> CS4361 (surround)
30 * I²S 4 -> CS4361 (front)
33 * GPIO 4 <- headphone detect
34 * GPIO 5 -> route input jack to line-in (0) or mic-in (1)
35 * GPIO 6 -> route input jack to line-in (0) or mic-in (1)
36 * GPIO 7 -> enable rear headphone amp
37 * GPIO 8 -> enable output to speakers
42 * input 2 <- front mic
44 * DAC out -> headphones
45 * aux out -> front panel headphones
48 #include <linux/pci.h>
49 #include <linux/delay.h>
50 #include <sound/control.h>
51 #include <sound/core.h>
52 #include <sound/info.h>
53 #include <sound/pcm.h>
54 #include <sound/tlv.h>
59 #define GPIO_MAGIC 0x0008
60 #define GPIO_HP_DETECT 0x0010
61 #define GPIO_INPUT_ROUTE 0x0060
62 #define GPIO_HP_REAR 0x0080
63 #define GPIO_OUTPUT_ENABLE 0x0100
66 unsigned int output_sel
;
68 unsigned int input_sel
;
73 static void cs4245_write(struct oxygen
*chip
, unsigned int reg
, u8 value
)
75 struct dg
*data
= chip
->model_data
;
77 oxygen_write_spi(chip
, OXYGEN_SPI_TRIGGER
|
78 OXYGEN_SPI_DATA_LENGTH_3
|
79 OXYGEN_SPI_CLOCK_1280
|
80 (0 << OXYGEN_SPI_CODEC_SHIFT
) |
81 OXYGEN_SPI_CEN_LATCH_CLOCK_HI
,
85 data
->cs4245_regs
[reg
] = value
;
88 static void cs4245_write_cached(struct oxygen
*chip
, unsigned int reg
, u8 value
)
90 struct dg
*data
= chip
->model_data
;
92 if (value
!= data
->cs4245_regs
[reg
])
93 cs4245_write(chip
, reg
, value
);
96 static void cs4245_registers_init(struct oxygen
*chip
)
98 struct dg
*data
= chip
->model_data
;
100 cs4245_write(chip
, CS4245_POWER_CTRL
, CS4245_PDN
);
101 cs4245_write(chip
, CS4245_DAC_CTRL_1
,
102 data
->cs4245_regs
[CS4245_DAC_CTRL_1
]);
103 cs4245_write(chip
, CS4245_ADC_CTRL
,
104 data
->cs4245_regs
[CS4245_ADC_CTRL
]);
105 cs4245_write(chip
, CS4245_SIGNAL_SEL
,
106 data
->cs4245_regs
[CS4245_SIGNAL_SEL
]);
107 cs4245_write(chip
, CS4245_PGA_B_CTRL
,
108 data
->cs4245_regs
[CS4245_PGA_B_CTRL
]);
109 cs4245_write(chip
, CS4245_PGA_A_CTRL
,
110 data
->cs4245_regs
[CS4245_PGA_A_CTRL
]);
111 cs4245_write(chip
, CS4245_ANALOG_IN
,
112 data
->cs4245_regs
[CS4245_ANALOG_IN
]);
113 cs4245_write(chip
, CS4245_DAC_A_CTRL
,
114 data
->cs4245_regs
[CS4245_DAC_A_CTRL
]);
115 cs4245_write(chip
, CS4245_DAC_B_CTRL
,
116 data
->cs4245_regs
[CS4245_DAC_B_CTRL
]);
117 cs4245_write(chip
, CS4245_DAC_CTRL_2
,
118 CS4245_DAC_SOFT
| CS4245_DAC_ZERO
| CS4245_INVERT_DAC
);
119 cs4245_write(chip
, CS4245_INT_MASK
, 0);
120 cs4245_write(chip
, CS4245_POWER_CTRL
, 0);
123 static void cs4245_init(struct oxygen
*chip
)
125 struct dg
*data
= chip
->model_data
;
127 data
->cs4245_regs
[CS4245_DAC_CTRL_1
] =
128 CS4245_DAC_FM_SINGLE
| CS4245_DAC_DIF_LJUST
;
129 data
->cs4245_regs
[CS4245_ADC_CTRL
] =
130 CS4245_ADC_FM_SINGLE
| CS4245_ADC_DIF_LJUST
;
131 data
->cs4245_regs
[CS4245_SIGNAL_SEL
] =
132 CS4245_A_OUT_SEL_HIZ
| CS4245_ASYNCH
;
133 data
->cs4245_regs
[CS4245_PGA_B_CTRL
] = 0;
134 data
->cs4245_regs
[CS4245_PGA_A_CTRL
] = 0;
135 data
->cs4245_regs
[CS4245_ANALOG_IN
] =
136 CS4245_PGA_SOFT
| CS4245_PGA_ZERO
| CS4245_SEL_INPUT_4
;
137 data
->cs4245_regs
[CS4245_DAC_A_CTRL
] = 0;
138 data
->cs4245_regs
[CS4245_DAC_B_CTRL
] = 0;
139 cs4245_registers_init(chip
);
140 snd_component_add(chip
->card
, "CS4245");
143 static void dg_output_enable(struct oxygen
*chip
)
146 oxygen_set_bits16(chip
, OXYGEN_GPIO_DATA
, GPIO_OUTPUT_ENABLE
);
149 static void dg_init(struct oxygen
*chip
)
151 struct dg
*data
= chip
->model_data
;
153 data
->output_sel
= 0;
155 data
->hp_vol_att
= 2 * 16;
159 oxygen_clear_bits16(chip
, OXYGEN_GPIO_CONTROL
,
160 GPIO_MAGIC
| GPIO_HP_DETECT
);
161 oxygen_set_bits16(chip
, OXYGEN_GPIO_CONTROL
,
162 GPIO_INPUT_ROUTE
| GPIO_HP_REAR
| GPIO_OUTPUT_ENABLE
);
163 oxygen_clear_bits16(chip
, OXYGEN_GPIO_DATA
,
164 GPIO_INPUT_ROUTE
| GPIO_HP_REAR
);
165 dg_output_enable(chip
);
168 static void dg_cleanup(struct oxygen
*chip
)
170 oxygen_clear_bits16(chip
, OXYGEN_GPIO_DATA
, GPIO_OUTPUT_ENABLE
);
173 static void dg_suspend(struct oxygen
*chip
)
178 static void dg_resume(struct oxygen
*chip
)
180 cs4245_registers_init(chip
);
181 dg_output_enable(chip
);
184 static void set_cs4245_dac_params(struct oxygen
*chip
,
185 struct snd_pcm_hw_params
*params
)
187 struct dg
*data
= chip
->model_data
;
190 value
= data
->cs4245_regs
[CS4245_DAC_CTRL_1
] & ~CS4245_DAC_FM_MASK
;
191 if (params_rate(params
) <= 50000)
192 value
|= CS4245_DAC_FM_SINGLE
;
193 else if (params_rate(params
) <= 100000)
194 value
|= CS4245_DAC_FM_DOUBLE
;
196 value
|= CS4245_DAC_FM_QUAD
;
197 cs4245_write_cached(chip
, CS4245_DAC_CTRL_1
, value
);
200 static void set_cs4245_adc_params(struct oxygen
*chip
,
201 struct snd_pcm_hw_params
*params
)
203 struct dg
*data
= chip
->model_data
;
206 value
= data
->cs4245_regs
[CS4245_ADC_CTRL
] & ~CS4245_ADC_FM_MASK
;
207 if (params_rate(params
) <= 50000)
208 value
|= CS4245_ADC_FM_SINGLE
;
209 else if (params_rate(params
) <= 100000)
210 value
|= CS4245_ADC_FM_DOUBLE
;
212 value
|= CS4245_ADC_FM_QUAD
;
213 cs4245_write_cached(chip
, CS4245_ADC_CTRL
, value
);
216 static inline unsigned int shift_bits(unsigned int value
,
217 unsigned int shift_from
,
218 unsigned int shift_to
,
221 if (shift_from
< shift_to
)
222 return (value
<< (shift_to
- shift_from
)) & mask
;
224 return (value
>> (shift_from
- shift_to
)) & mask
;
227 static unsigned int adjust_dg_dac_routing(struct oxygen
*chip
,
228 unsigned int play_routing
)
230 return (play_routing
& OXYGEN_PLAY_DAC0_SOURCE_MASK
) |
231 shift_bits(play_routing
,
232 OXYGEN_PLAY_DAC2_SOURCE_SHIFT
,
233 OXYGEN_PLAY_DAC1_SOURCE_SHIFT
,
234 OXYGEN_PLAY_DAC1_SOURCE_MASK
) |
235 shift_bits(play_routing
,
236 OXYGEN_PLAY_DAC1_SOURCE_SHIFT
,
237 OXYGEN_PLAY_DAC2_SOURCE_SHIFT
,
238 OXYGEN_PLAY_DAC2_SOURCE_MASK
) |
239 shift_bits(play_routing
,
240 OXYGEN_PLAY_DAC0_SOURCE_SHIFT
,
241 OXYGEN_PLAY_DAC3_SOURCE_SHIFT
,
242 OXYGEN_PLAY_DAC3_SOURCE_MASK
);
245 static int output_switch_info(struct snd_kcontrol
*ctl
,
246 struct snd_ctl_elem_info
*info
)
248 static const char *const names
[3] = {
249 "Speakers", "Headphones", "FP Headphones"
252 return snd_ctl_enum_info(info
, 1, 3, names
);
255 static int output_switch_get(struct snd_kcontrol
*ctl
,
256 struct snd_ctl_elem_value
*value
)
258 struct oxygen
*chip
= ctl
->private_data
;
259 struct dg
*data
= chip
->model_data
;
261 mutex_lock(&chip
->mutex
);
262 value
->value
.enumerated
.item
[0] = data
->output_sel
;
263 mutex_unlock(&chip
->mutex
);
267 static int output_switch_put(struct snd_kcontrol
*ctl
,
268 struct snd_ctl_elem_value
*value
)
270 struct oxygen
*chip
= ctl
->private_data
;
271 struct dg
*data
= chip
->model_data
;
275 if (value
->value
.enumerated
.item
[0] > 2)
278 mutex_lock(&chip
->mutex
);
279 changed
= value
->value
.enumerated
.item
[0] != data
->output_sel
;
281 data
->output_sel
= value
->value
.enumerated
.item
[0];
283 reg
= data
->cs4245_regs
[CS4245_SIGNAL_SEL
] &
284 ~CS4245_A_OUT_SEL_MASK
;
285 reg
|= data
->output_sel
== 2 ?
286 CS4245_A_OUT_SEL_DAC
: CS4245_A_OUT_SEL_HIZ
;
287 cs4245_write_cached(chip
, CS4245_SIGNAL_SEL
, reg
);
289 cs4245_write_cached(chip
, CS4245_DAC_A_CTRL
,
290 data
->output_sel
? data
->hp_vol_att
: 0);
291 cs4245_write_cached(chip
, CS4245_DAC_B_CTRL
,
292 data
->output_sel
? data
->hp_vol_att
: 0);
294 oxygen_write16_masked(chip
, OXYGEN_GPIO_DATA
,
295 data
->output_sel
== 1 ? GPIO_HP_REAR
: 0,
298 mutex_unlock(&chip
->mutex
);
302 static int hp_volume_offset_info(struct snd_kcontrol
*ctl
,
303 struct snd_ctl_elem_info
*info
)
305 static const char *const names
[3] = {
306 "< 64 ohms", "64-150 ohms", "150-300 ohms"
309 return snd_ctl_enum_info(info
, 1, 3, names
);
312 static int hp_volume_offset_get(struct snd_kcontrol
*ctl
,
313 struct snd_ctl_elem_value
*value
)
315 struct oxygen
*chip
= ctl
->private_data
;
316 struct dg
*data
= chip
->model_data
;
318 mutex_lock(&chip
->mutex
);
319 if (data
->hp_vol_att
> 2 * 7)
320 value
->value
.enumerated
.item
[0] = 0;
321 else if (data
->hp_vol_att
> 0)
322 value
->value
.enumerated
.item
[0] = 1;
324 value
->value
.enumerated
.item
[0] = 2;
325 mutex_unlock(&chip
->mutex
);
329 static int hp_volume_offset_put(struct snd_kcontrol
*ctl
,
330 struct snd_ctl_elem_value
*value
)
332 static const s8 atts
[3] = { 2 * 16, 2 * 7, 0 };
333 struct oxygen
*chip
= ctl
->private_data
;
334 struct dg
*data
= chip
->model_data
;
338 if (value
->value
.enumerated
.item
[0] > 2)
340 att
= atts
[value
->value
.enumerated
.item
[0]];
341 mutex_lock(&chip
->mutex
);
342 changed
= att
!= data
->hp_vol_att
;
344 data
->hp_vol_att
= att
;
345 if (data
->output_sel
) {
346 cs4245_write_cached(chip
, CS4245_DAC_A_CTRL
, att
);
347 cs4245_write_cached(chip
, CS4245_DAC_B_CTRL
, att
);
350 mutex_unlock(&chip
->mutex
);
354 static int input_vol_info(struct snd_kcontrol
*ctl
,
355 struct snd_ctl_elem_info
*info
)
357 info
->type
= SNDRV_CTL_ELEM_TYPE_INTEGER
;
359 info
->value
.integer
.min
= 2 * -12;
360 info
->value
.integer
.max
= 2 * 12;
364 static int input_vol_get(struct snd_kcontrol
*ctl
,
365 struct snd_ctl_elem_value
*value
)
367 struct oxygen
*chip
= ctl
->private_data
;
368 struct dg
*data
= chip
->model_data
;
369 unsigned int idx
= ctl
->private_value
;
371 mutex_lock(&chip
->mutex
);
372 value
->value
.integer
.value
[0] = data
->input_vol
[idx
][0];
373 value
->value
.integer
.value
[1] = data
->input_vol
[idx
][1];
374 mutex_unlock(&chip
->mutex
);
378 static int input_vol_put(struct snd_kcontrol
*ctl
,
379 struct snd_ctl_elem_value
*value
)
381 struct oxygen
*chip
= ctl
->private_data
;
382 struct dg
*data
= chip
->model_data
;
383 unsigned int idx
= ctl
->private_value
;
386 if (value
->value
.integer
.value
[0] < 2 * -12 ||
387 value
->value
.integer
.value
[0] > 2 * 12 ||
388 value
->value
.integer
.value
[1] < 2 * -12 ||
389 value
->value
.integer
.value
[1] > 2 * 12)
391 mutex_lock(&chip
->mutex
);
392 changed
= data
->input_vol
[idx
][0] != value
->value
.integer
.value
[0] ||
393 data
->input_vol
[idx
][1] != value
->value
.integer
.value
[1];
395 data
->input_vol
[idx
][0] = value
->value
.integer
.value
[0];
396 data
->input_vol
[idx
][1] = value
->value
.integer
.value
[1];
397 if (idx
== data
->input_sel
) {
398 cs4245_write_cached(chip
, CS4245_PGA_A_CTRL
,
399 data
->input_vol
[idx
][0]);
400 cs4245_write_cached(chip
, CS4245_PGA_B_CTRL
,
401 data
->input_vol
[idx
][1]);
404 mutex_unlock(&chip
->mutex
);
408 static DECLARE_TLV_DB_SCALE(cs4245_pga_db_scale
, -1200, 50, 0);
410 static int input_sel_info(struct snd_kcontrol
*ctl
,
411 struct snd_ctl_elem_info
*info
)
413 static const char *const names
[4] = {
414 "Mic", "Aux", "Front Mic", "Line"
417 return snd_ctl_enum_info(info
, 1, 4, names
);
420 static int input_sel_get(struct snd_kcontrol
*ctl
,
421 struct snd_ctl_elem_value
*value
)
423 struct oxygen
*chip
= ctl
->private_data
;
424 struct dg
*data
= chip
->model_data
;
426 mutex_lock(&chip
->mutex
);
427 value
->value
.enumerated
.item
[0] = data
->input_sel
;
428 mutex_unlock(&chip
->mutex
);
432 static int input_sel_put(struct snd_kcontrol
*ctl
,
433 struct snd_ctl_elem_value
*value
)
435 static const u8 sel_values
[4] = {
441 struct oxygen
*chip
= ctl
->private_data
;
442 struct dg
*data
= chip
->model_data
;
445 if (value
->value
.enumerated
.item
[0] > 3)
448 mutex_lock(&chip
->mutex
);
449 changed
= value
->value
.enumerated
.item
[0] != data
->input_sel
;
451 data
->input_sel
= value
->value
.enumerated
.item
[0];
453 cs4245_write(chip
, CS4245_ANALOG_IN
,
454 (data
->cs4245_regs
[CS4245_ANALOG_IN
] &
456 sel_values
[data
->input_sel
]);
458 cs4245_write_cached(chip
, CS4245_PGA_A_CTRL
,
459 data
->input_vol
[data
->input_sel
][0]);
460 cs4245_write_cached(chip
, CS4245_PGA_B_CTRL
,
461 data
->input_vol
[data
->input_sel
][1]);
463 oxygen_write16_masked(chip
, OXYGEN_GPIO_DATA
,
464 data
->input_sel
? 0 : GPIO_INPUT_ROUTE
,
467 mutex_unlock(&chip
->mutex
);
471 static int hpf_info(struct snd_kcontrol
*ctl
, struct snd_ctl_elem_info
*info
)
473 static const char *const names
[2] = { "Active", "Frozen" };
475 return snd_ctl_enum_info(info
, 1, 2, names
);
478 static int hpf_get(struct snd_kcontrol
*ctl
, struct snd_ctl_elem_value
*value
)
480 struct oxygen
*chip
= ctl
->private_data
;
481 struct dg
*data
= chip
->model_data
;
483 value
->value
.enumerated
.item
[0] =
484 !!(data
->cs4245_regs
[CS4245_ADC_CTRL
] & CS4245_HPF_FREEZE
);
488 static int hpf_put(struct snd_kcontrol
*ctl
, struct snd_ctl_elem_value
*value
)
490 struct oxygen
*chip
= ctl
->private_data
;
491 struct dg
*data
= chip
->model_data
;
495 mutex_lock(&chip
->mutex
);
496 reg
= data
->cs4245_regs
[CS4245_ADC_CTRL
] & ~CS4245_HPF_FREEZE
;
497 if (value
->value
.enumerated
.item
[0])
498 reg
|= CS4245_HPF_FREEZE
;
499 changed
= reg
!= data
->cs4245_regs
[CS4245_ADC_CTRL
];
501 cs4245_write(chip
, CS4245_ADC_CTRL
, reg
);
502 mutex_unlock(&chip
->mutex
);
506 #define INPUT_VOLUME(xname, index) { \
507 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
509 .info = input_vol_info, \
510 .get = input_vol_get, \
511 .put = input_vol_put, \
512 .tlv = { .p = cs4245_pga_db_scale }, \
513 .private_value = index, \
515 static const struct snd_kcontrol_new dg_controls
[] = {
517 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
518 .name
= "Analog Output Playback Enum",
519 .info
= output_switch_info
,
520 .get
= output_switch_get
,
521 .put
= output_switch_put
,
524 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
525 .name
= "Headphones Impedance Playback Enum",
526 .info
= hp_volume_offset_info
,
527 .get
= hp_volume_offset_get
,
528 .put
= hp_volume_offset_put
,
530 INPUT_VOLUME("Mic Capture Volume", 0),
531 INPUT_VOLUME("Aux Capture Volume", 1),
532 INPUT_VOLUME("Front Mic Capture Volume", 2),
533 INPUT_VOLUME("Line Capture Volume", 3),
535 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
536 .name
= "Capture Source",
537 .info
= input_sel_info
,
538 .get
= input_sel_get
,
539 .put
= input_sel_put
,
542 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
543 .name
= "ADC High-pass Filter Capture Enum",
550 static int dg_control_filter(struct snd_kcontrol_new
*template)
552 if (!strncmp(template->name
, "Master Playback ", 16))
557 static int dg_mixer_init(struct oxygen
*chip
)
562 for (i
= 0; i
< ARRAY_SIZE(dg_controls
); ++i
) {
563 err
= snd_ctl_add(chip
->card
,
564 snd_ctl_new1(&dg_controls
[i
], chip
));
571 static void dump_cs4245_registers(struct oxygen
*chip
,
572 struct snd_info_buffer
*buffer
)
574 struct dg
*data
= chip
->model_data
;
577 snd_iprintf(buffer
, "\nCS4245:");
578 for (i
= 1; i
<= 0x10; ++i
)
579 snd_iprintf(buffer
, " %02x", data
->cs4245_regs
[i
]);
580 snd_iprintf(buffer
, "\n");
583 struct oxygen_model model_xonar_dg
= {
584 .shortname
= "Xonar DG",
585 .longname
= "C-Media Oxygen HD Audio",
588 .control_filter
= dg_control_filter
,
589 .mixer_init
= dg_mixer_init
,
590 .cleanup
= dg_cleanup
,
591 .suspend
= dg_suspend
,
593 .set_dac_params
= set_cs4245_dac_params
,
594 .set_adc_params
= set_cs4245_adc_params
,
595 .adjust_dac_routing
= adjust_dg_dac_routing
,
596 .dump_registers
= dump_cs4245_registers
,
597 .model_data_size
= sizeof(struct dg
),
598 .device_config
= PLAYBACK_0_TO_I2S
|
599 PLAYBACK_1_TO_SPDIF
|
600 CAPTURE_0_FROM_I2S_2
,
601 .dac_channels_pcm
= 6,
602 .dac_channels_mixer
= 0,
603 .function_flags
= OXYGEN_FUNCTION_SPI
,
604 .dac_mclks
= OXYGEN_MCLKS(256, 128, 128),
605 .adc_mclks
= OXYGEN_MCLKS(256, 128, 128),
606 .dac_i2s_format
= OXYGEN_I2S_FORMAT_LJUST
,
607 .adc_i2s_format
= OXYGEN_I2S_FORMAT_LJUST
,