[ALSA] oxygen: make the I2S format configurable
Clemens Ladisch [Thu, 17 Jan 2008 08:05:09 +0000 (09:05 +0100)]
Add proper register bit symbols for the I2S format field, and allow card
models to configure the I2S format to be used for the DACs and ADCs.

Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>

sound/pci/oxygen/oxygen.c
sound/pci/oxygen/oxygen.h
sound/pci/oxygen/oxygen_pcm.c
sound/pci/oxygen/oxygen_regs.h
sound/pci/oxygen/virtuoso.c

index f8e3fd3..e618cde 100644 (file)
@@ -285,6 +285,8 @@ static const struct oxygen_model model_generic = {
                         OXYGEN_CHANNEL_MULTICH |
                         OXYGEN_CHANNEL_AC97,
        .function_flags = OXYGEN_FUNCTION_ENABLE_SPI_4_5,
+       .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
+       .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
 };
 static const struct oxygen_model model_meridian = {
        .shortname = "C-Media CMI8788",
@@ -304,6 +306,8 @@ static const struct oxygen_model model_meridian = {
                         OXYGEN_CHANNEL_MULTICH |
                         OXYGEN_CHANNEL_AC97,
        .function_flags = OXYGEN_FUNCTION_ENABLE_SPI_4_5,
+       .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
+       .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
 };
 
 static int __devinit generic_oxygen_probe(struct pci_dev *pci,
index 602105c..98cccc6 100644 (file)
@@ -86,6 +86,8 @@ struct oxygen_model {
        void (*update_dac_mute)(struct oxygen *chip);
        u8 used_channels;
        u8 function_flags;
+       u16 dac_i2s_format;
+       u16 adc_i2s_format;
 };
 
 /* oxygen_lib.c */
index 5515c75..f24659a 100644 (file)
@@ -313,12 +313,12 @@ static unsigned int oxygen_i2s_magic2(struct snd_pcm_hw_params *hw_params)
        return params_rate(hw_params) <= 96000 ? 0x10 : 0x00;
 }
 
-static unsigned int oxygen_i2s_format(struct snd_pcm_hw_params *hw_params)
+static unsigned int oxygen_i2s_bits(struct snd_pcm_hw_params *hw_params)
 {
        if (params_format(hw_params) == SNDRV_PCM_FORMAT_S32_LE)
-               return OXYGEN_I2S_FORMAT_24;
+               return OXYGEN_I2S_BITS_24;
        else
-               return OXYGEN_I2S_FORMAT_16;
+               return OXYGEN_I2S_BITS_16;
 }
 
 static unsigned int oxygen_play_channels(struct snd_pcm_hw_params *hw_params)
@@ -386,13 +386,15 @@ static int oxygen_rec_a_hw_params(struct snd_pcm_substream *substream,
        oxygen_write8_masked(chip, OXYGEN_REC_FORMAT,
                             oxygen_format(hw_params) << OXYGEN_REC_FORMAT_A_SHIFT,
                             OXYGEN_REC_FORMAT_A_MASK);
-       oxygen_write8_masked(chip, OXYGEN_I2S_A_FORMAT,
-                            oxygen_rate(hw_params) |
-                            oxygen_i2s_magic2(hw_params) |
-                            oxygen_i2s_format(hw_params),
-                            OXYGEN_I2S_RATE_MASK |
-                            OXYGEN_I2S_MAGIC2_MASK |
-                            OXYGEN_I2S_FORMAT_MASK);
+       oxygen_write16_masked(chip, OXYGEN_I2S_A_FORMAT,
+                             oxygen_rate(hw_params) |
+                             oxygen_i2s_magic2(hw_params) |
+                             chip->model->adc_i2s_format |
+                             oxygen_i2s_bits(hw_params),
+                             OXYGEN_I2S_RATE_MASK |
+                             OXYGEN_I2S_FORMAT_MASK |
+                             OXYGEN_I2S_MAGIC2_MASK |
+                             OXYGEN_I2S_BITS_MASK);
        oxygen_clear_bits8(chip, OXYGEN_REC_ROUTING, 0x08);
        spin_unlock_irq(&chip->reg_lock);
 
@@ -416,13 +418,15 @@ static int oxygen_rec_b_hw_params(struct snd_pcm_substream *substream,
        oxygen_write8_masked(chip, OXYGEN_REC_FORMAT,
                             oxygen_format(hw_params) << OXYGEN_REC_FORMAT_B_SHIFT,
                             OXYGEN_REC_FORMAT_B_MASK);
-       oxygen_write8_masked(chip, OXYGEN_I2S_B_FORMAT,
-                            oxygen_rate(hw_params) |
-                            oxygen_i2s_magic2(hw_params) |
-                            oxygen_i2s_format(hw_params),
-                            OXYGEN_I2S_RATE_MASK |
-                            OXYGEN_I2S_MAGIC2_MASK |
-                            OXYGEN_I2S_FORMAT_MASK);
+       oxygen_write16_masked(chip, OXYGEN_I2S_B_FORMAT,
+                             oxygen_rate(hw_params) |
+                             oxygen_i2s_magic2(hw_params) |
+                             chip->model->adc_i2s_format |
+                             oxygen_i2s_bits(hw_params),
+                             OXYGEN_I2S_RATE_MASK |
+                             OXYGEN_I2S_FORMAT_MASK |
+                             OXYGEN_I2S_MAGIC2_MASK |
+                             OXYGEN_I2S_BITS_MASK);
        oxygen_clear_bits8(chip, OXYGEN_REC_ROUTING, 0x10);
        spin_unlock_irq(&chip->reg_lock);
 
@@ -493,8 +497,12 @@ static int oxygen_multich_hw_params(struct snd_pcm_substream *substream,
                             oxygen_format(hw_params) << OXYGEN_MULTICH_FORMAT_SHIFT,
                             OXYGEN_MULTICH_FORMAT_MASK);
        oxygen_write16_masked(chip, OXYGEN_I2S_MULTICH_FORMAT,
-                             oxygen_rate(hw_params) | oxygen_i2s_format(hw_params),
-                             OXYGEN_I2S_RATE_MASK | OXYGEN_I2S_FORMAT_MASK);
+                             oxygen_rate(hw_params) |
+                             chip->model->dac_i2s_format |
+                             oxygen_i2s_bits(hw_params),
+                             OXYGEN_I2S_RATE_MASK |
+                             OXYGEN_I2S_FORMAT_MASK |
+                             OXYGEN_I2S_BITS_MASK);
        oxygen_clear_bits16(chip, OXYGEN_PLAY_ROUTING, 0x001f);
        oxygen_update_dac_routing(chip);
        oxygen_update_spdif_source(chip);
index 7a4726d..b3491f7 100644 (file)
 #define  OXYGEN_RATE_96000             0x0005
 #define  OXYGEN_RATE_176400            0x0006
 #define  OXYGEN_RATE_192000            0x0007
-#define  OXYGEN_I2S_MAGIC1_MASK                0x0008
+#define  OXYGEN_I2S_FORMAT_MASK                0x0008
+#define  OXYGEN_I2S_FORMAT_I2S         0x0000
+#define  OXYGEN_I2S_FORMAT_LJUST       0x0008
 #define  OXYGEN_I2S_MAGIC2_MASK                0x0030
-#define  OXYGEN_I2S_FORMAT_MASK                0x00c0
-#define  OXYGEN_I2S_FORMAT_16          0x0000
-#define  OXYGEN_I2S_FORMAT_20          0x0040
-#define  OXYGEN_I2S_FORMAT_24          0x0080
-#define  OXYGEN_I2S_FORMAT_32          0x00c0
+#define  OXYGEN_I2S_BITS_MASK          0x00c0
+#define  OXYGEN_I2S_BITS_16            0x0000
+#define  OXYGEN_I2S_BITS_20            0x0040
+#define  OXYGEN_I2S_BITS_24            0x0080
+#define  OXYGEN_I2S_BITS_32            0x00c0
 
 #define OXYGEN_I2S_A_FORMAT            0x62
 #define OXYGEN_I2S_B_FORMAT            0x64
 #define OXYGEN_I2S_C_FORMAT            0x66
-/* OXYGEN_I2S_RATE_* and OXYGEN_I2S_FORMAT_* */
+/* like OXYGEN_I2S_MULTICH_FORMAT */
 
 #define OXYGEN_SPDIF_CONTROL           0x70
 #define  OXYGEN_SPDIF_OUT_ENABLE       0x00000002
index bea34f1..83c2c43 100644 (file)
@@ -102,10 +102,6 @@ static void xonar_init(struct oxygen *chip)
 
        oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, 0x8c);
        oxygen_write16_masked(chip, OXYGEN_GPIO_DATA, 0x00, 0x8c);
-#if 0
-       oxygen_clear_bits16(chip, OXYGEN_I2S_MULTICH_FORMAT,
-                           OXYGEN_I2S_MAGIC1_MASK);
-#endif
        oxygen_ac97_set_bits(chip, 0, 0x62, 0x0080);
        msleep(300);
        oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, 0x100);
@@ -253,6 +249,8 @@ static const struct oxygen_model model_xonar = {
                         OXYGEN_CHANNEL_SPDIF |
                         OXYGEN_CHANNEL_MULTICH,
        .function_flags = OXYGEN_FUNCTION_ENABLE_SPI_4_5,
+       .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
+       .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
 };
 
 static int __devinit xonar_probe(struct pci_dev *pci,