diff options
author | Clemens Ladisch <clemens@ladisch.de> | 2009-09-28 05:21:21 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2009-09-28 05:55:00 -0400 |
commit | 4852ad02476ab2bbc874f6f8fda9e677e0f09c87 (patch) | |
tree | 0edcea50bffb7a643e3a72e29bcc920dd7ab71dc /sound/pci/oxygen/xonar_cs43xx.c | |
parent | 973dca93a3d46cca7e4743300f8a510b779906af (diff) |
sound: oxygen: add digital filter control
Add a control to select between sharp and slow roll-of filter responses
of the DACs.
Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/oxygen/xonar_cs43xx.c')
-rw-r--r-- | sound/pci/oxygen/xonar_cs43xx.c | 82 |
1 files changed, 77 insertions, 5 deletions
diff --git a/sound/pci/oxygen/xonar_cs43xx.c b/sound/pci/oxygen/xonar_cs43xx.c index a83f827feb34..16c226bfcd2b 100644 --- a/sound/pci/oxygen/xonar_cs43xx.c +++ b/sound/pci/oxygen/xonar_cs43xx.c | |||
@@ -69,7 +69,7 @@ | |||
69 | 69 | ||
70 | struct xonar_cs43xx { | 70 | struct xonar_cs43xx { |
71 | struct xonar_generic generic; | 71 | struct xonar_generic generic; |
72 | u8 cs4398_regs[7]; | 72 | u8 cs4398_regs[8]; |
73 | u8 cs4362a_regs[15]; | 73 | u8 cs4362a_regs[15]; |
74 | }; | 74 | }; |
75 | 75 | ||
@@ -121,12 +121,11 @@ static void cs43xx_registers_init(struct oxygen *chip) | |||
121 | cs4398_write(chip, 4, data->cs4398_regs[4]); | 121 | cs4398_write(chip, 4, data->cs4398_regs[4]); |
122 | cs4398_write(chip, 5, data->cs4398_regs[5]); | 122 | cs4398_write(chip, 5, data->cs4398_regs[5]); |
123 | cs4398_write(chip, 6, data->cs4398_regs[6]); | 123 | cs4398_write(chip, 6, data->cs4398_regs[6]); |
124 | cs4398_write(chip, 7, CS4398_RMP_DN | CS4398_RMP_UP | | 124 | cs4398_write(chip, 7, data->cs4398_regs[7]); |
125 | CS4398_ZERO_CROSS | CS4398_SOFT_RAMP); | ||
126 | cs4362a_write(chip, 0x02, CS4362A_DIF_LJUST); | 125 | cs4362a_write(chip, 0x02, CS4362A_DIF_LJUST); |
127 | cs4362a_write(chip, 0x03, CS4362A_MUTEC_6 | CS4362A_AMUTE | | 126 | cs4362a_write(chip, 0x03, CS4362A_MUTEC_6 | CS4362A_AMUTE | |
128 | CS4362A_RMP_UP | CS4362A_ZERO_CROSS | CS4362A_SOFT_RAMP); | 127 | CS4362A_RMP_UP | CS4362A_ZERO_CROSS | CS4362A_SOFT_RAMP); |
129 | cs4362a_write(chip, 0x04, CS4362A_RMP_DN | CS4362A_DEM_NONE); | 128 | cs4362a_write(chip, 0x04, data->cs4362a_regs[0x04]); |
130 | cs4362a_write(chip, 0x05, 0); | 129 | cs4362a_write(chip, 0x05, 0); |
131 | for (i = 6; i <= 14; ++i) | 130 | for (i = 6; i <= 14; ++i) |
132 | cs4362a_write(chip, i, data->cs4362a_regs[i]); | 131 | cs4362a_write(chip, i, data->cs4362a_regs[i]); |
@@ -147,6 +146,9 @@ static void xonar_d1_init(struct oxygen *chip) | |||
147 | CS4398_MUTE_B | CS4398_MUTE_A | CS4398_PAMUTE; | 146 | CS4398_MUTE_B | CS4398_MUTE_A | CS4398_PAMUTE; |
148 | data->cs4398_regs[5] = 60 * 2; | 147 | data->cs4398_regs[5] = 60 * 2; |
149 | data->cs4398_regs[6] = 60 * 2; | 148 | data->cs4398_regs[6] = 60 * 2; |
149 | data->cs4398_regs[7] = CS4398_RMP_DN | CS4398_RMP_UP | | ||
150 | CS4398_ZERO_CROSS | CS4398_SOFT_RAMP; | ||
151 | data->cs4362a_regs[4] = CS4362A_RMP_DN | CS4362A_DEM_NONE; | ||
150 | data->cs4362a_regs[6] = CS4362A_FM_SINGLE | | 152 | data->cs4362a_regs[6] = CS4362A_FM_SINGLE | |
151 | CS4362A_ATAPI_B_R | CS4362A_ATAPI_A_L; | 153 | CS4362A_ATAPI_B_R | CS4362A_ATAPI_A_L; |
152 | data->cs4362a_regs[7] = 60 | CS4362A_MUTE; | 154 | data->cs4362a_regs[7] = 60 | CS4362A_MUTE; |
@@ -286,6 +288,68 @@ static const struct snd_kcontrol_new front_panel_switch = { | |||
286 | .private_value = GPIO_D1_FRONT_PANEL, | 288 | .private_value = GPIO_D1_FRONT_PANEL, |
287 | }; | 289 | }; |
288 | 290 | ||
291 | static int rolloff_info(struct snd_kcontrol *ctl, | ||
292 | struct snd_ctl_elem_info *info) | ||
293 | { | ||
294 | static const char *const names[2] = { | ||
295 | "Fast Roll-off", "Slow Roll-off" | ||
296 | }; | ||
297 | |||
298 | info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | ||
299 | info->count = 1; | ||
300 | info->value.enumerated.items = 2; | ||
301 | if (info->value.enumerated.item >= 2) | ||
302 | info->value.enumerated.item = 1; | ||
303 | strcpy(info->value.enumerated.name, names[info->value.enumerated.item]); | ||
304 | return 0; | ||
305 | } | ||
306 | |||
307 | static int rolloff_get(struct snd_kcontrol *ctl, | ||
308 | struct snd_ctl_elem_value *value) | ||
309 | { | ||
310 | struct oxygen *chip = ctl->private_data; | ||
311 | struct xonar_cs43xx *data = chip->model_data; | ||
312 | |||
313 | value->value.enumerated.item[0] = | ||
314 | (data->cs4398_regs[7] & CS4398_FILT_SEL) != 0; | ||
315 | return 0; | ||
316 | } | ||
317 | |||
318 | static int rolloff_put(struct snd_kcontrol *ctl, | ||
319 | struct snd_ctl_elem_value *value) | ||
320 | { | ||
321 | struct oxygen *chip = ctl->private_data; | ||
322 | struct xonar_cs43xx *data = chip->model_data; | ||
323 | int changed; | ||
324 | u8 reg; | ||
325 | |||
326 | mutex_lock(&chip->mutex); | ||
327 | reg = data->cs4398_regs[7]; | ||
328 | if (value->value.enumerated.item[0]) | ||
329 | reg |= CS4398_FILT_SEL; | ||
330 | else | ||
331 | reg &= ~CS4398_FILT_SEL; | ||
332 | changed = reg != data->cs4398_regs[7]; | ||
333 | if (changed) { | ||
334 | cs4398_write(chip, 7, reg); | ||
335 | if (reg & CS4398_FILT_SEL) | ||
336 | reg = data->cs4362a_regs[0x04] | CS4362A_FILT_SEL; | ||
337 | else | ||
338 | reg = data->cs4362a_regs[0x04] & ~CS4362A_FILT_SEL; | ||
339 | cs4362a_write(chip, 0x04, reg); | ||
340 | } | ||
341 | mutex_unlock(&chip->mutex); | ||
342 | return changed; | ||
343 | } | ||
344 | |||
345 | static const struct snd_kcontrol_new rolloff_control = { | ||
346 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
347 | .name = "DAC Filter Playback Enum", | ||
348 | .info = rolloff_info, | ||
349 | .get = rolloff_get, | ||
350 | .put = rolloff_put, | ||
351 | }; | ||
352 | |||
289 | static void xonar_d1_line_mic_ac97_switch(struct oxygen *chip, | 353 | static void xonar_d1_line_mic_ac97_switch(struct oxygen *chip, |
290 | unsigned int reg, unsigned int mute) | 354 | unsigned int reg, unsigned int mute) |
291 | { | 355 | { |
@@ -309,7 +373,15 @@ static int xonar_d1_control_filter(struct snd_kcontrol_new *template) | |||
309 | 373 | ||
310 | static int xonar_d1_mixer_init(struct oxygen *chip) | 374 | static int xonar_d1_mixer_init(struct oxygen *chip) |
311 | { | 375 | { |
312 | return snd_ctl_add(chip->card, snd_ctl_new1(&front_panel_switch, chip)); | 376 | int err; |
377 | |||
378 | err = snd_ctl_add(chip->card, snd_ctl_new1(&front_panel_switch, chip)); | ||
379 | if (err < 0) | ||
380 | return err; | ||
381 | err = snd_ctl_add(chip->card, snd_ctl_new1(&rolloff_control, chip)); | ||
382 | if (err < 0) | ||
383 | return err; | ||
384 | return 0; | ||
313 | } | 385 | } |
314 | 386 | ||
315 | static const struct oxygen_model model_xonar_d1 = { | 387 | static const struct oxygen_model model_xonar_d1 = { |