ALSA: oxygen: simplify model-specific MCLK handling
authorClemens Ladisch <clemens@ladisch.de>
Mon, 10 Jan 2011 15:14:52 +0000 (16:14 +0100)
committerTakashi Iwai <tiwai@suse.de>
Mon, 10 Jan 2011 15:46:31 +0000 (16:46 +0100)
Replace the get_i2s_mclk callback with tables of MCLK values.  This
simplifies the MCLK-handling code in both the framework and the model-
specific drivers.

Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
sound/pci/oxygen/oxygen.c
sound/pci/oxygen/oxygen.h
sound/pci/oxygen/oxygen_lib.c
sound/pci/oxygen/oxygen_pcm.c
sound/pci/oxygen/oxygen_regs.h
sound/pci/oxygen/xonar_cs43xx.c
sound/pci/oxygen/xonar_pcm179x.c
sound/pci/oxygen/xonar_wm87x6.c

index fe7ed4fc9f4627a23597f3e6da64c04eaab6f0a3..784d500c700fb59c334bc2b843fdea7cc7c43e1b 100644 (file)
@@ -568,7 +568,6 @@ static const struct oxygen_model model_generic = {
        .mixer_init = generic_wm8785_mixer_init,
        .cleanup = generic_cleanup,
        .resume = generic_resume,
-       .get_i2s_mclk = oxygen_default_i2s_mclk,
        .set_dac_params = set_ak4396_params,
        .set_adc_params = set_wm8785_params,
        .update_dac_volume = update_ak4396_volume,
@@ -589,6 +588,8 @@ static const struct oxygen_model model_generic = {
        .dac_volume_max = 255,
        .function_flags = OXYGEN_FUNCTION_SPI |
                          OXYGEN_FUNCTION_ENABLE_SPI_4_5,
+       .dac_mclks = OXYGEN_MCLKS(256, 256, 128),
+       .adc_mclks = OXYGEN_MCLKS(256, 256, 128),
        .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
        .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
 };
index 70eff3747158e6480fd5e93b4f5afcfd9b844dbc..2c5fb9edcb115f6adcbbfdcb3119a40071dc5b2a 100644 (file)
 #define PCM_AC97       5
 #define PCM_COUNT      6
 
+#define OXYGEN_MCLKS(f_single, f_double, f_quad) ((MCLK_##f_single << 0) | \
+                                                 (MCLK_##f_double << 2) | \
+                                                 (MCLK_##f_quad   << 4))
+
 #define OXYGEN_IO_SIZE 0x100
 
 #define OXYGEN_EEPROM_ID       0x434d  /* "CM" */
@@ -81,8 +85,6 @@ struct oxygen_model {
        void (*resume)(struct oxygen *chip);
        void (*pcm_hardware_filter)(unsigned int channel,
                                    struct snd_pcm_hardware *hardware);
-       unsigned int (*get_i2s_mclk)(struct oxygen *chip, unsigned int channel,
-                                    struct snd_pcm_hw_params *hw_params);
        void (*set_dac_params)(struct oxygen *chip,
                               struct snd_pcm_hw_params *params);
        void (*set_adc_params)(struct oxygen *chip,
@@ -105,6 +107,8 @@ struct oxygen_model {
        u8 dac_volume_max;
        u8 misc_flags;
        u8 function_flags;
+       u8 dac_mclks;
+       u8 adc_mclks;
        u16 dac_i2s_format;
        u16 adc_i2s_format;
 };
@@ -171,8 +175,6 @@ void oxygen_update_spdif_source(struct oxygen *chip);
 /* oxygen_pcm.c */
 
 int oxygen_pcm_init(struct oxygen *chip);
-unsigned int oxygen_default_i2s_mclk(struct oxygen *chip, unsigned int channel,
-                                    struct snd_pcm_hw_params *hw_params);
 
 /* oxygen_io.c */
 
index c44c91e6fb1883106be61d740f48e0a6dcf5e69b..77e1f0805633fee8a81a9204220a7516cc83bdea 100644 (file)
@@ -414,28 +414,40 @@ static void oxygen_init(struct oxygen *chip)
                      (OXYGEN_FORMAT_16 << OXYGEN_MULTICH_FORMAT_SHIFT));
        oxygen_write8(chip, OXYGEN_REC_CHANNELS, OXYGEN_REC_CHANNELS_2_2_2);
        oxygen_write16(chip, OXYGEN_I2S_MULTICH_FORMAT,
-                      OXYGEN_RATE_48000 | chip->model.dac_i2s_format |
-                      OXYGEN_I2S_MCLK_256 | OXYGEN_I2S_BITS_16 |
-                      OXYGEN_I2S_MASTER | OXYGEN_I2S_BCLK_64);
+                      OXYGEN_RATE_48000 |
+                      chip->model.dac_i2s_format |
+                      OXYGEN_I2S_MCLK(chip->model.dac_mclks) |
+                      OXYGEN_I2S_BITS_16 |
+                      OXYGEN_I2S_MASTER |
+                      OXYGEN_I2S_BCLK_64);
        if (chip->model.device_config & CAPTURE_0_FROM_I2S_1)
                oxygen_write16(chip, OXYGEN_I2S_A_FORMAT,
-                              OXYGEN_RATE_48000 | chip->model.adc_i2s_format |
-                              OXYGEN_I2S_MCLK_256 | OXYGEN_I2S_BITS_16 |
-                              OXYGEN_I2S_MASTER | OXYGEN_I2S_BCLK_64);
+                              OXYGEN_RATE_48000 |
+                              chip->model.adc_i2s_format |
+                              OXYGEN_I2S_MCLK(chip->model.adc_mclks) |
+                              OXYGEN_I2S_BITS_16 |
+                              OXYGEN_I2S_MASTER |
+                              OXYGEN_I2S_BCLK_64);
        else
                oxygen_write16(chip, OXYGEN_I2S_A_FORMAT,
-                              OXYGEN_I2S_MASTER | OXYGEN_I2S_MUTE_MCLK);
+                              OXYGEN_I2S_MASTER |
+                              OXYGEN_I2S_MUTE_MCLK);
        if (chip->model.device_config & (CAPTURE_0_FROM_I2S_2 |
                                         CAPTURE_2_FROM_I2S_2))
                oxygen_write16(chip, OXYGEN_I2S_B_FORMAT,
-                              OXYGEN_RATE_48000 | chip->model.adc_i2s_format |
-                              OXYGEN_I2S_MCLK_256 | OXYGEN_I2S_BITS_16 |
-                              OXYGEN_I2S_MASTER | OXYGEN_I2S_BCLK_64);
+                              OXYGEN_RATE_48000 |
+                              chip->model.adc_i2s_format |
+                              OXYGEN_I2S_MCLK(chip->model.adc_mclks) |
+                              OXYGEN_I2S_BITS_16 |
+                              OXYGEN_I2S_MASTER |
+                              OXYGEN_I2S_BCLK_64);
        else
                oxygen_write16(chip, OXYGEN_I2S_B_FORMAT,
-                              OXYGEN_I2S_MASTER | OXYGEN_I2S_MUTE_MCLK);
+                              OXYGEN_I2S_MASTER |
+                              OXYGEN_I2S_MUTE_MCLK);
        oxygen_write16(chip, OXYGEN_I2S_C_FORMAT,
-                      OXYGEN_I2S_MASTER | OXYGEN_I2S_MUTE_MCLK);
+                      OXYGEN_I2S_MASTER |
+                      OXYGEN_I2S_MUTE_MCLK);
        oxygen_clear_bits32(chip, OXYGEN_SPDIF_CONTROL,
                            OXYGEN_SPDIF_OUT_ENABLE |
                            OXYGEN_SPDIF_LOOPBACK);
index dc3c68f76df495ec2421afa9822433ca36268314..d5533e34ece923faa90364cc9ce0d51cf22e9678 100644 (file)
@@ -274,17 +274,6 @@ static unsigned int oxygen_rate(struct snd_pcm_hw_params *hw_params)
        }
 }
 
-unsigned int oxygen_default_i2s_mclk(struct oxygen *chip,
-                                    unsigned int channel,
-                                    struct snd_pcm_hw_params *hw_params)
-{
-       if (params_rate(hw_params) <= 96000)
-               return OXYGEN_I2S_MCLK_256;
-       else
-               return OXYGEN_I2S_MCLK_128;
-}
-EXPORT_SYMBOL(oxygen_default_i2s_mclk);
-
 static unsigned int oxygen_i2s_bits(struct snd_pcm_hw_params *hw_params)
 {
        if (params_format(hw_params) == SNDRV_PCM_FORMAT_S32_LE)
@@ -344,6 +333,26 @@ static int oxygen_hw_params(struct snd_pcm_substream *substream,
        return 0;
 }
 
+static u16 get_mclk(struct oxygen *chip, unsigned int channel,
+                   struct snd_pcm_hw_params *params)
+{
+       unsigned int mclks, shift;
+
+       if (channel == PCM_MULTICH)
+               mclks = chip->model.dac_mclks;
+       else
+               mclks = chip->model.adc_mclks;
+
+       if (params_rate(params) <= 48000)
+               shift = 0;
+       else if (params_rate(params) <= 96000)
+               shift = 2;
+       else
+               shift = 4;
+
+       return OXYGEN_I2S_MCLK(mclks >> shift);
+}
+
 static int oxygen_rec_a_hw_params(struct snd_pcm_substream *substream,
                                  struct snd_pcm_hw_params *hw_params)
 {
@@ -360,8 +369,8 @@ static int oxygen_rec_a_hw_params(struct snd_pcm_substream *substream,
                             OXYGEN_REC_FORMAT_A_MASK);
        oxygen_write16_masked(chip, OXYGEN_I2S_A_FORMAT,
                              oxygen_rate(hw_params) |
-                             chip->model.get_i2s_mclk(chip, PCM_A, hw_params) |
                              chip->model.adc_i2s_format |
+                             get_mclk(chip, PCM_A, hw_params) |
                              oxygen_i2s_bits(hw_params),
                              OXYGEN_I2S_RATE_MASK |
                              OXYGEN_I2S_FORMAT_MASK |
@@ -396,9 +405,8 @@ static int oxygen_rec_b_hw_params(struct snd_pcm_substream *substream,
        if (!is_ac97)
                oxygen_write16_masked(chip, OXYGEN_I2S_B_FORMAT,
                                      oxygen_rate(hw_params) |
-                                     chip->model.get_i2s_mclk(chip, PCM_B,
-                                                              hw_params) |
                                      chip->model.adc_i2s_format |
+                                     get_mclk(chip, PCM_B, hw_params) |
                                      oxygen_i2s_bits(hw_params),
                                      OXYGEN_I2S_RATE_MASK |
                                      OXYGEN_I2S_FORMAT_MASK |
@@ -479,8 +487,7 @@ static int oxygen_multich_hw_params(struct snd_pcm_substream *substream,
        oxygen_write16_masked(chip, OXYGEN_I2S_MULTICH_FORMAT,
                              oxygen_rate(hw_params) |
                              chip->model.dac_i2s_format |
-                             chip->model.get_i2s_mclk(chip, PCM_MULTICH,
-                                                      hw_params) |
+                             get_mclk(chip, PCM_MULTICH, hw_params) |
                              oxygen_i2s_bits(hw_params),
                              OXYGEN_I2S_RATE_MASK |
                              OXYGEN_I2S_FORMAT_MASK |
index 331d3d96fa2148db33398288e7e3b23002d3a04b..63dc7a0ab55592b9b3a82aea7ccbeb18bea46799 100644 (file)
 #define  OXYGEN_I2S_FORMAT_I2S         0x0000
 #define  OXYGEN_I2S_FORMAT_LJUST       0x0008
 #define  OXYGEN_I2S_MCLK_MASK          0x0030  /* MCLK/LRCK */
-#define  OXYGEN_I2S_MCLK_128           0x0000
-#define  OXYGEN_I2S_MCLK_256           0x0010
-#define  OXYGEN_I2S_MCLK_512           0x0020
+#define  OXYGEN_I2S_MCLK_SHIFT         4
+#define  MCLK_128                      0
+#define  MCLK_256                      1
+#define  MCLK_512                      2
+#define  OXYGEN_I2S_MCLK(f)            (((f) & 3) << OXYGEN_I2S_MCLK_SHIFT)
 #define  OXYGEN_I2S_BITS_MASK          0x00c0
 #define  OXYGEN_I2S_BITS_16            0x0000
 #define  OXYGEN_I2S_BITS_20            0x0040
index a25197ca39a15b05413d9b09c533239728093560..b651938f3248226ac7a0c8c723ea8bcea1fb0138 100644 (file)
@@ -412,7 +412,6 @@ static const struct oxygen_model model_xonar_d1 = {
        .cleanup = xonar_d1_cleanup,
        .suspend = xonar_d1_suspend,
        .resume = xonar_d1_resume,
-       .get_i2s_mclk = oxygen_default_i2s_mclk,
        .set_dac_params = set_cs43xx_params,
        .set_adc_params = xonar_set_cs53x1_params,
        .update_dac_volume = update_cs43xx_volume,
@@ -431,6 +430,8 @@ static const struct oxygen_model model_xonar_d1 = {
        .dac_volume_min = 127 - 60,
        .dac_volume_max = 127,
        .function_flags = OXYGEN_FUNCTION_2WIRE,
+       .dac_mclks = OXYGEN_MCLKS(256, 256, 128),
+       .adc_mclks = OXYGEN_MCLKS(256, 256, 128),
        .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
        .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
 };
index e15ecee2ccf72e18d9f4f72469f6af288072d21d..9787193f6ed35d453645040ae7b8df2dac2e6179 100644 (file)
@@ -335,10 +335,6 @@ static void pcm1796_init(struct oxygen *chip)
                data->h6 ? PCM1796_OS_64 : PCM1796_OS_128;
        pcm1796_registers_init(chip);
        data->current_rate = 48000;
-       if (!data->h6)
-               oxygen_write16_masked(chip, OXYGEN_I2S_MULTICH_FORMAT,
-                                     OXYGEN_I2S_MCLK_512,
-                                     OXYGEN_I2S_MCLK_MASK);
 }
 
 static void xonar_d2_init(struct oxygen *chip)
@@ -476,7 +472,7 @@ static void xonar_st_init(struct oxygen *chip)
        oxygen_write16(chip, OXYGEN_I2S_A_FORMAT,
                       OXYGEN_RATE_48000 |
                       OXYGEN_I2S_FORMAT_I2S |
-                      (data->h6 ? OXYGEN_I2S_MCLK_256 : OXYGEN_I2S_MCLK_512) |
+                      OXYGEN_I2S_MCLK(data->h6 ? MCLK_256 : MCLK_512) |
                       OXYGEN_I2S_BITS_16 |
                       OXYGEN_I2S_MASTER |
                       OXYGEN_I2S_BCLK_64);
@@ -560,26 +556,6 @@ static void xonar_st_resume(struct oxygen *chip)
        xonar_stx_resume(chip);
 }
 
-static unsigned int mclk_from_rate(struct oxygen *chip, unsigned int rate)
-{
-       struct xonar_pcm179x *data = chip->model_data;
-
-       if (rate <= 48000)
-               return data->h6 ? OXYGEN_I2S_MCLK_256 : OXYGEN_I2S_MCLK_512;
-       else
-               return OXYGEN_I2S_MCLK_128;
-}
-
-static unsigned int get_pcm1796_i2s_mclk(struct oxygen *chip,
-                                        unsigned int channel,
-                                        struct snd_pcm_hw_params *params)
-{
-       if (channel == PCM_MULTICH)
-               return mclk_from_rate(chip, params_rate(params));
-       else
-               return oxygen_default_i2s_mclk(chip, channel, params);
-}
-
 static void update_pcm1796_oversampling(struct oxygen *chip)
 {
        struct xonar_pcm179x *data = chip->model_data;
@@ -640,45 +616,32 @@ static void update_cs2000_rate(struct oxygen *chip, unsigned int rate)
 
        switch (rate) {
        case 32000:
-               if (data->h6)
-                       rate_mclk = OXYGEN_RATE_32000 | OXYGEN_I2S_MCLK_256;
-               else
-                       rate_mclk = OXYGEN_RATE_32000 | OXYGEN_I2S_MCLK_512;
-               break;
-       case 44100:
-               if (data->h6)
-                       rate_mclk = OXYGEN_RATE_44100 | OXYGEN_I2S_MCLK_256;
-               else
-                       rate_mclk = OXYGEN_RATE_44100 | OXYGEN_I2S_MCLK_512;
-               break;
-       default: /* 48000 */
-               if (data->h6)
-                       rate_mclk = OXYGEN_RATE_48000 | OXYGEN_I2S_MCLK_256;
-               else
-                       rate_mclk = OXYGEN_RATE_48000 | OXYGEN_I2S_MCLK_512;
-               break;
        case 64000:
-               rate_mclk = OXYGEN_RATE_32000 | OXYGEN_I2S_MCLK_256;
+               rate_mclk = OXYGEN_RATE_32000;
                break;
+       case 44100:
        case 88200:
-               rate_mclk = OXYGEN_RATE_44100 | OXYGEN_I2S_MCLK_256;
-               break;
-       case 96000:
-               rate_mclk = OXYGEN_RATE_48000 | OXYGEN_I2S_MCLK_256;
-               break;
        case 176400:
-               rate_mclk = OXYGEN_RATE_44100 | OXYGEN_I2S_MCLK_512;
+               rate_mclk = OXYGEN_RATE_44100;
                break;
+       default:
+       case 48000:
+       case 96000:
        case 192000:
-               rate_mclk = OXYGEN_RATE_48000 | OXYGEN_I2S_MCLK_512;
+               rate_mclk = OXYGEN_RATE_48000;
                break;
        }
-       oxygen_write16_masked(chip, OXYGEN_I2S_A_FORMAT, rate_mclk,
-                             OXYGEN_I2S_RATE_MASK | OXYGEN_I2S_MCLK_MASK);
-       if ((rate_mclk & OXYGEN_I2S_MCLK_MASK) <= OXYGEN_I2S_MCLK_256)
+
+       if (rate <= 96000 && (rate > 48000 || data->h6)) {
+               rate_mclk |= OXYGEN_I2S_MCLK(MCLK_256);
                reg = CS2000_REF_CLK_DIV_1;
-       else
+       } else {
+               rate_mclk |= OXYGEN_I2S_MCLK(MCLK_512);
                reg = CS2000_REF_CLK_DIV_2;
+       }
+
+       oxygen_write16_masked(chip, OXYGEN_I2S_A_FORMAT, rate_mclk,
+                             OXYGEN_I2S_RATE_MASK | OXYGEN_I2S_MCLK_MASK);
        cs2000_write_cached(chip, CS2000_FUN_CFG_1, reg);
        msleep(3); /* PLL lock delay */
 }
@@ -1047,7 +1010,6 @@ static const struct oxygen_model model_xonar_d2 = {
        .cleanup = xonar_d2_cleanup,
        .suspend = xonar_d2_suspend,
        .resume = xonar_d2_resume,
-       .get_i2s_mclk = get_pcm1796_i2s_mclk,
        .set_dac_params = set_pcm1796_params,
        .set_adc_params = xonar_set_cs53x1_params,
        .update_dac_volume = update_pcm1796_volume,
@@ -1069,6 +1031,8 @@ static const struct oxygen_model model_xonar_d2 = {
        .misc_flags = OXYGEN_MISC_MIDI,
        .function_flags = OXYGEN_FUNCTION_SPI |
                          OXYGEN_FUNCTION_ENABLE_SPI_4_5,
+       .dac_mclks = OXYGEN_MCLKS(512, 128, 128),
+       .adc_mclks = OXYGEN_MCLKS(256, 256, 128),
        .dac_i2s_format = OXYGEN_I2S_FORMAT_I2S,
        .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
 };
@@ -1082,7 +1046,6 @@ static const struct oxygen_model model_xonar_hdav = {
        .suspend = xonar_hdav_suspend,
        .resume = xonar_hdav_resume,
        .pcm_hardware_filter = xonar_hdmi_pcm_hardware_filter,
-       .get_i2s_mclk = get_pcm1796_i2s_mclk,
        .set_dac_params = set_hdav_params,
        .set_adc_params = xonar_set_cs53x1_params,
        .update_dac_volume = update_pcm1796_volume,
@@ -1102,6 +1065,8 @@ static const struct oxygen_model model_xonar_hdav = {
        .dac_volume_max = 255,
        .misc_flags = OXYGEN_MISC_MIDI,
        .function_flags = OXYGEN_FUNCTION_2WIRE,
+       .dac_mclks = OXYGEN_MCLKS(512, 128, 128),
+       .adc_mclks = OXYGEN_MCLKS(256, 256, 128),
        .dac_i2s_format = OXYGEN_I2S_FORMAT_I2S,
        .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
 };
@@ -1114,7 +1079,6 @@ static const struct oxygen_model model_xonar_st = {
        .cleanup = xonar_st_cleanup,
        .suspend = xonar_st_suspend,
        .resume = xonar_st_resume,
-       .get_i2s_mclk = get_pcm1796_i2s_mclk,
        .set_dac_params = set_st_params,
        .set_adc_params = xonar_set_cs53x1_params,
        .update_dac_volume = update_pcm1796_volume,
@@ -1132,6 +1096,8 @@ static const struct oxygen_model model_xonar_st = {
        .dac_volume_min = 255 - 2*60,
        .dac_volume_max = 255,
        .function_flags = OXYGEN_FUNCTION_2WIRE,
+       .dac_mclks = OXYGEN_MCLKS(512, 128, 128),
+       .adc_mclks = OXYGEN_MCLKS(256, 256, 128),
        .dac_i2s_format = OXYGEN_I2S_FORMAT_I2S,
        .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
 };
@@ -1159,6 +1125,7 @@ int __devinit get_xonar_pcm179x_model(struct oxygen *chip,
                case GPIO_DB_H6:
                        chip->model.shortname = "Xonar HDAV1.3+H6";
                        chip->model.dac_channels_mixer = 8;
+                       chip->model.dac_mclks = OXYGEN_MCLKS(256, 128, 128);
                        break;
                }
                break;
@@ -1174,6 +1141,7 @@ int __devinit get_xonar_pcm179x_model(struct oxygen *chip,
                        chip->model.control_filter = xonar_st_h6_control_filter;
                        chip->model.dac_channels_pcm = 8;
                        chip->model.dac_channels_mixer = 8;
+                       chip->model.dac_mclks = OXYGEN_MCLKS(256, 128, 128);
                        break;
                }
                break;
index da92cc24eed2525de0d0c7c064cfe63cfc80a4e2..4f9657084603897c868802b268a32c57dcb6c7b1 100644 (file)
@@ -1122,7 +1122,6 @@ static const struct oxygen_model model_xonar_ds = {
        .suspend = xonar_ds_suspend,
        .resume = xonar_ds_resume,
        .pcm_hardware_filter = wm8776_adc_hardware_filter,
-       .get_i2s_mclk = oxygen_default_i2s_mclk,
        .set_dac_params = set_wm87x6_dac_params,
        .set_adc_params = set_wm8776_adc_params,
        .update_dac_volume = update_wm87x6_volume,
@@ -1140,6 +1139,8 @@ static const struct oxygen_model model_xonar_ds = {
        .dac_volume_min = 255 - 2*60,
        .dac_volume_max = 255,
        .function_flags = OXYGEN_FUNCTION_SPI,
+       .dac_mclks = OXYGEN_MCLKS(256, 256, 128),
+       .adc_mclks = OXYGEN_MCLKS(256, 256, 128),
        .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
        .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
 };