[alsa-devel] [PATCH 2/2] snd-oxygen: Fixes for the Xonar DG card
Clemens Ladisch
clemens at ladisch.de
Tue Nov 19 23:23:54 CET 2013
Roman Volkov wrote:
> Fixes for the Xonar DG model of the Oxygen driver:
Each of the following sentences describes a separate logical change.
> +++ linux-3.12-my/sound/pci/oxygen/xonar_dg.c 2013-11-19 01:01:07.000000000 +0400
> + * DGX card: not tested.
> + * Suspend/resume: not tested
This does not belong in the source code; if some tests succeeds, we do
not want to update the driver.
> + * SPDIF: not tested
SPDIF is handled completely by the CMI8788 itself.
> + * 128kHz doesn't work for CS4361 (multichannel playback)
Why do you expect 128 kHz to work?
> + * CS4245 Auxiliary Output is connected to the front panel headphones jack
> + * through amplifier.
The comment below already says this.
> - * GPIO 3 <- ?
> + * GPIO 3 <- unused (?)
Why this change?
> - * GPIO 5 -> route input jack to line-in (0) or mic-in (1)
> - * GPIO 6 -> route input jack to line-in (0) or mic-in (1)
> + * GPIO 5 -> ADC analog circuit power supply control for left channel (?)
> + * GPIO 6 -> ADC analog circuit power supply control for right channel (?)
The Xonar cards often use mechanical relays for these routing things;
you should be able to hear them when switching.
> - * GPIO 7 -> enable rear headphone amp
> + * GPIO 7 -> switches green rear output jack between CS4245 / CS4361 first
> + * channel
0 or 1?
> - * GPIO 8 -> enable output to speakers
> + * GPIO 8 -> DAC analog circuit power supply control (?)
This relay is intended to prevent popping when powering on.
> +static int cs4245_dump_regs(struct oxygen *chip, bool bRead)
Why "dump" for writing? This should be two functions.
> + for (address = 0; address <= 0x10; address++) {
> + return bRead ? cs4245_read_spi(chip, address) :
> + cs4245_write_spi(chip, address);
> + }
Why return from the loop?
> +static void dg_init(struct oxygen *chip)
> + * Recommended sequence from the datasheet: reset the codec and then
> + * initialize it.
> + oxygen_write8_masked(chip, OXYGEN_FUNCTION, 0,
> + OXYGEN_FUNCTION_RESET_CODEC);
This is what the _set/clear_bits functions are for.
Is the reset pin actually connected? Does the Windows driver do this?
> + mdelay(1);
Use mdelay() only when sleeping is not possible; use msleep() instead.
> + msleep_interruptible(1000);
When you use _interruptible, you should also check for the interrupt.
> static void set_cs4245_dac_params(struct oxygen *chip,
> struct snd_pcm_hw_params *params)
> + unsigned char tmp;
> + unsigned char tmp2;
These variable names are not very descriptive.
> + case PLAYBACK_DST_20_CH:
> + case PLAYBACK_DST_40_CH:
> + case PLAYBACK_DST_51_CH:
Why is it necessary to differentiate between those? There should be no
mixer control; the driver can automatically detect what format is used.
And this should not make any difference because the unused channels will
be silent anyway.
> +/* Put the codec into low power mode, disable audio output, save registers */
Does the Windows driver implement this?
> +static void dg_suspend(struct oxygen *chip)
> {
> struct dg *data = chip->model_data;
> + data->cs4245_shadow[CS4245_POWER_CTRL] = CS4245_PDN_MIC |
> + CS4245_PDN_ADC | CS4245_PDN_DAC | CS4245_PDN;
> + cs4245_write_spi(chip, CS4245_POWER_CTRL);
> + cs4245_dump_regs(chip, true);
Why reading the registers? The cs4245_shadow values should already be
valid.
> - .function_flags = OXYGEN_FUNCTION_SPI,
> + .function_flags = OXYGEN_FUNCTION_SPI | OXYGEN_FUNCTION_ENABLE_SPI_4_5,
Why?
> +++ linux-3.12-my/sound/pci/oxygen/xonar_dg.h 2013-11-19 01:06:12.000000000 +0400
This file was intended as the interface between xonar_dg.c and the
generic oxygen.c driver.
That you have to add so much stuff indicates that xonar_dg.c and
xonar_dg_mixer.c are not very independent and maybe should have stayed
a single file.
> + /* Independend capture volumes */
> + char mic_vol_l;
> + char mic_vol_r;
> + bool mic_m;
> + char line_vol_l;
> + char line_vol_r;
> + bool line_m;
> + char aux_vol_l;
> + char aux_vol_r;
> + bool aux_m;
The old driver had a separate volume for front mic.
> + * It is not good that we do not have software volume control
> + * as the Windows driver does. CS4361 cannot attenuate the volume.
> + * When we are switching from headphones to the speakers,
> + * which are controlled by the simple DAC CS4361, our headphones
> + * in the rear jack can stun us.
This is why I did not implement a volume control in the first place.
> +static int xonar_dg_pcm_route_apply(struct oxygen *chip)
> + oxygen_write8_masked(chip, OXYGEN_GPIO_DATA, 0x00, 0x80);
Use _set_bits and the GPIO_ symbol.
> +static int xonar_dg_pga_volume_get(struct snd_kcontrol *ctl,
> + struct snd_ctl_elem_value *val)
> + switch (ctl->private_value) {
> + case CAPTURE_SRC_MIC:
> + case CAPTURE_SRC_LINE:
> + case CAPTURE_SRC_AUX:
And FP_MIC? (Also elsewhere.)
Regards,
Clemens
More information about the Alsa-devel
mailing list