[ALSA] oxygen: make the I2S format configurable

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>
This commit is contained in:
Clemens Ladisch 2008-01-17 09:05:09 +01:00 committed by Jaroslav Kysela
parent b8c5b53e1f
commit 05855ba3f4
5 changed files with 44 additions and 30 deletions

View File

@ -285,6 +285,8 @@ static const struct oxygen_model model_generic = {
OXYGEN_CHANNEL_MULTICH | OXYGEN_CHANNEL_MULTICH |
OXYGEN_CHANNEL_AC97, OXYGEN_CHANNEL_AC97,
.function_flags = OXYGEN_FUNCTION_ENABLE_SPI_4_5, .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 = { static const struct oxygen_model model_meridian = {
.shortname = "C-Media CMI8788", .shortname = "C-Media CMI8788",
@ -304,6 +306,8 @@ static const struct oxygen_model model_meridian = {
OXYGEN_CHANNEL_MULTICH | OXYGEN_CHANNEL_MULTICH |
OXYGEN_CHANNEL_AC97, OXYGEN_CHANNEL_AC97,
.function_flags = OXYGEN_FUNCTION_ENABLE_SPI_4_5, .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, static int __devinit generic_oxygen_probe(struct pci_dev *pci,

View File

@ -86,6 +86,8 @@ struct oxygen_model {
void (*update_dac_mute)(struct oxygen *chip); void (*update_dac_mute)(struct oxygen *chip);
u8 used_channels; u8 used_channels;
u8 function_flags; u8 function_flags;
u16 dac_i2s_format;
u16 adc_i2s_format;
}; };
/* oxygen_lib.c */ /* oxygen_lib.c */

View 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; 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) if (params_format(hw_params) == SNDRV_PCM_FORMAT_S32_LE)
return OXYGEN_I2S_FORMAT_24; return OXYGEN_I2S_BITS_24;
else else
return OXYGEN_I2S_FORMAT_16; return OXYGEN_I2S_BITS_16;
} }
static unsigned int oxygen_play_channels(struct snd_pcm_hw_params *hw_params) 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_write8_masked(chip, OXYGEN_REC_FORMAT,
oxygen_format(hw_params) << OXYGEN_REC_FORMAT_A_SHIFT, oxygen_format(hw_params) << OXYGEN_REC_FORMAT_A_SHIFT,
OXYGEN_REC_FORMAT_A_MASK); OXYGEN_REC_FORMAT_A_MASK);
oxygen_write8_masked(chip, OXYGEN_I2S_A_FORMAT, oxygen_write16_masked(chip, OXYGEN_I2S_A_FORMAT,
oxygen_rate(hw_params) | oxygen_rate(hw_params) |
oxygen_i2s_magic2(hw_params) | oxygen_i2s_magic2(hw_params) |
oxygen_i2s_format(hw_params), chip->model->adc_i2s_format |
OXYGEN_I2S_RATE_MASK | oxygen_i2s_bits(hw_params),
OXYGEN_I2S_MAGIC2_MASK | OXYGEN_I2S_RATE_MASK |
OXYGEN_I2S_FORMAT_MASK); OXYGEN_I2S_FORMAT_MASK |
OXYGEN_I2S_MAGIC2_MASK |
OXYGEN_I2S_BITS_MASK);
oxygen_clear_bits8(chip, OXYGEN_REC_ROUTING, 0x08); oxygen_clear_bits8(chip, OXYGEN_REC_ROUTING, 0x08);
spin_unlock_irq(&chip->reg_lock); 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_write8_masked(chip, OXYGEN_REC_FORMAT,
oxygen_format(hw_params) << OXYGEN_REC_FORMAT_B_SHIFT, oxygen_format(hw_params) << OXYGEN_REC_FORMAT_B_SHIFT,
OXYGEN_REC_FORMAT_B_MASK); OXYGEN_REC_FORMAT_B_MASK);
oxygen_write8_masked(chip, OXYGEN_I2S_B_FORMAT, oxygen_write16_masked(chip, OXYGEN_I2S_B_FORMAT,
oxygen_rate(hw_params) | oxygen_rate(hw_params) |
oxygen_i2s_magic2(hw_params) | oxygen_i2s_magic2(hw_params) |
oxygen_i2s_format(hw_params), chip->model->adc_i2s_format |
OXYGEN_I2S_RATE_MASK | oxygen_i2s_bits(hw_params),
OXYGEN_I2S_MAGIC2_MASK | OXYGEN_I2S_RATE_MASK |
OXYGEN_I2S_FORMAT_MASK); OXYGEN_I2S_FORMAT_MASK |
OXYGEN_I2S_MAGIC2_MASK |
OXYGEN_I2S_BITS_MASK);
oxygen_clear_bits8(chip, OXYGEN_REC_ROUTING, 0x10); oxygen_clear_bits8(chip, OXYGEN_REC_ROUTING, 0x10);
spin_unlock_irq(&chip->reg_lock); 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_format(hw_params) << OXYGEN_MULTICH_FORMAT_SHIFT,
OXYGEN_MULTICH_FORMAT_MASK); OXYGEN_MULTICH_FORMAT_MASK);
oxygen_write16_masked(chip, OXYGEN_I2S_MULTICH_FORMAT, oxygen_write16_masked(chip, OXYGEN_I2S_MULTICH_FORMAT,
oxygen_rate(hw_params) | oxygen_i2s_format(hw_params), oxygen_rate(hw_params) |
OXYGEN_I2S_RATE_MASK | OXYGEN_I2S_FORMAT_MASK); 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_clear_bits16(chip, OXYGEN_PLAY_ROUTING, 0x001f);
oxygen_update_dac_routing(chip); oxygen_update_dac_routing(chip);
oxygen_update_spdif_source(chip); oxygen_update_spdif_source(chip);

View File

@ -105,18 +105,20 @@
#define OXYGEN_RATE_96000 0x0005 #define OXYGEN_RATE_96000 0x0005
#define OXYGEN_RATE_176400 0x0006 #define OXYGEN_RATE_176400 0x0006
#define OXYGEN_RATE_192000 0x0007 #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_MAGIC2_MASK 0x0030
#define OXYGEN_I2S_FORMAT_MASK 0x00c0 #define OXYGEN_I2S_BITS_MASK 0x00c0
#define OXYGEN_I2S_FORMAT_16 0x0000 #define OXYGEN_I2S_BITS_16 0x0000
#define OXYGEN_I2S_FORMAT_20 0x0040 #define OXYGEN_I2S_BITS_20 0x0040
#define OXYGEN_I2S_FORMAT_24 0x0080 #define OXYGEN_I2S_BITS_24 0x0080
#define OXYGEN_I2S_FORMAT_32 0x00c0 #define OXYGEN_I2S_BITS_32 0x00c0
#define OXYGEN_I2S_A_FORMAT 0x62 #define OXYGEN_I2S_A_FORMAT 0x62
#define OXYGEN_I2S_B_FORMAT 0x64 #define OXYGEN_I2S_B_FORMAT 0x64
#define OXYGEN_I2S_C_FORMAT 0x66 #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_CONTROL 0x70
#define OXYGEN_SPDIF_OUT_ENABLE 0x00000002 #define OXYGEN_SPDIF_OUT_ENABLE 0x00000002

View File

@ -102,10 +102,6 @@ static void xonar_init(struct oxygen *chip)
oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, 0x8c); oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, 0x8c);
oxygen_write16_masked(chip, OXYGEN_GPIO_DATA, 0x00, 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); oxygen_ac97_set_bits(chip, 0, 0x62, 0x0080);
msleep(300); msleep(300);
oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, 0x100); oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, 0x100);
@ -253,6 +249,8 @@ static const struct oxygen_model model_xonar = {
OXYGEN_CHANNEL_SPDIF | OXYGEN_CHANNEL_SPDIF |
OXYGEN_CHANNEL_MULTICH, OXYGEN_CHANNEL_MULTICH,
.function_flags = OXYGEN_FUNCTION_ENABLE_SPI_4_5, .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, static int __devinit xonar_probe(struct pci_dev *pci,