ALSA: oxygen: Xonar DG(X): modify DAC/ADC parameters function
authorRoman Volkov <v1ron@mail.ru>
Fri, 24 Jan 2014 12:18:10 +0000 (16:18 +0400)
committerClemens Ladisch <clemens@ladisch.de>
Wed, 29 Jan 2014 19:45:47 +0000 (20:45 +0100)
When selecting the audio sample rate for CS4245,
the MCLK divider should also be changed.

Signed-off-by: Roman Volkov <v1ron@mail.ru>
Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
sound/pci/oxygen/xonar_dg.c

index 4177fb131086eb32e4197aa43cc46a0ab7194e2c..81c004c78766fc8768ac4ea6042a8faa58ab70e2 100644 (file)
@@ -216,32 +216,50 @@ static void set_cs4245_dac_params(struct oxygen *chip,
                                  struct snd_pcm_hw_params *params)
 {
        struct dg *data = chip->model_data;
-       u8 value;
-
-       value = data->cs4245_shadow[CS4245_DAC_CTRL_1] & ~CS4245_DAC_FM_MASK;
-       if (params_rate(params) <= 50000)
-               value |= CS4245_DAC_FM_SINGLE;
-       else if (params_rate(params) <= 100000)
-               value |= CS4245_DAC_FM_DOUBLE;
-       else
-               value |= CS4245_DAC_FM_QUAD;
-       cs4245_write_cached(chip, CS4245_DAC_CTRL_1, value);
+       unsigned char dac_ctrl;
+       unsigned char mclk_freq;
+
+       dac_ctrl = data->cs4245_shadow[CS4245_DAC_CTRL_1] & ~CS4245_DAC_FM_MASK;
+       mclk_freq = data->cs4245_shadow[CS4245_MCLK_FREQ] & ~CS4245_MCLK1_MASK;
+       if (params_rate(params) <= 50000) {
+               dac_ctrl |= CS4245_DAC_FM_SINGLE;
+               mclk_freq |= CS4245_MCLK_1 << CS4245_MCLK1_SHIFT;
+       } else if (params_rate(params) <= 100000) {
+               dac_ctrl |= CS4245_DAC_FM_DOUBLE;
+               mclk_freq |= CS4245_MCLK_1 << CS4245_MCLK1_SHIFT;
+       } else {
+               dac_ctrl |= CS4245_DAC_FM_QUAD;
+               mclk_freq |= CS4245_MCLK_2 << CS4245_MCLK1_SHIFT;
+       }
+       data->cs4245_shadow[CS4245_DAC_CTRL_1] = dac_ctrl;
+       data->cs4245_shadow[CS4245_MCLK_FREQ] = mclk_freq;
+       cs4245_write_spi(chip, CS4245_DAC_CTRL_1);
+       cs4245_write_spi(chip, CS4245_MCLK_FREQ);
 }
 
 static void set_cs4245_adc_params(struct oxygen *chip,
                                  struct snd_pcm_hw_params *params)
 {
        struct dg *data = chip->model_data;
-       u8 value;
-
-       value = data->cs4245_shadow[CS4245_ADC_CTRL] & ~CS4245_ADC_FM_MASK;
-       if (params_rate(params) <= 50000)
-               value |= CS4245_ADC_FM_SINGLE;
-       else if (params_rate(params) <= 100000)
-               value |= CS4245_ADC_FM_DOUBLE;
-       else
-               value |= CS4245_ADC_FM_QUAD;
-       cs4245_write_cached(chip, CS4245_ADC_CTRL, value);
+       unsigned char adc_ctrl;
+       unsigned char mclk_freq;
+
+       adc_ctrl = data->cs4245_shadow[CS4245_ADC_CTRL] & ~CS4245_ADC_FM_MASK;
+       mclk_freq = data->cs4245_shadow[CS4245_MCLK_FREQ] & ~CS4245_MCLK2_MASK;
+       if (params_rate(params) <= 50000) {
+               adc_ctrl |= CS4245_ADC_FM_SINGLE;
+               mclk_freq |= CS4245_MCLK_1 << CS4245_MCLK2_SHIFT;
+       } else if (params_rate(params) <= 100000) {
+               adc_ctrl |= CS4245_ADC_FM_DOUBLE;
+               mclk_freq |= CS4245_MCLK_1 << CS4245_MCLK2_SHIFT;
+       } else {
+               adc_ctrl |= CS4245_ADC_FM_QUAD;
+               mclk_freq |= CS4245_MCLK_2 << CS4245_MCLK2_SHIFT;
+       }
+       data->cs4245_shadow[CS4245_ADC_CTRL] = adc_ctrl;
+       data->cs4245_shadow[CS4245_MCLK_FREQ] = mclk_freq;
+       cs4245_write_spi(chip, CS4245_ADC_CTRL);
+       cs4245_write_spi(chip, CS4245_MCLK_FREQ);
 }
 
 static inline unsigned int shift_bits(unsigned int value,