diff options
author | Clemens Ladisch <clemens@ladisch.de> | 2008-01-28 08:35:47 +0100 |
---|---|---|
committer | Jaroslav Kysela <perex@perex.cz> | 2008-01-31 17:30:17 +0100 |
commit | 5f7b9b457751efc9f3ad120d0ebdb19fe753e9d0 (patch) | |
tree | e63cb022688a2f345d7ea489beded5b2964b6406 | |
parent | a3601560496d7b46d2d1187169824d11570ff63a (diff) | |
download | linux-5f7b9b457751efc9f3ad120d0ebdb19fe753e9d0.tar.bz2 |
[ALSA] oxygen: add front panel capture
When a second AC97 codec is present, add a PCM device for capturing from
the front panel.
Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
-rw-r--r-- | sound/pci/oxygen/oxygen_pcm.c | 52 |
1 files changed, 34 insertions, 18 deletions
diff --git a/sound/pci/oxygen/oxygen_pcm.c b/sound/pci/oxygen/oxygen_pcm.c index 5b89c727601e..dfad3db35c82 100644 --- a/sound/pci/oxygen/oxygen_pcm.c +++ b/sound/pci/oxygen/oxygen_pcm.c @@ -118,7 +118,11 @@ static int oxygen_open(struct snd_pcm_substream *substream, int err; runtime->private_data = (void *)(uintptr_t)channel; - runtime->hw = *oxygen_hardware[channel]; + if (channel == PCM_B && chip->has_ac97_1 && + (chip->model->used_channels & OXYGEN_CHANNEL_AC97)) + runtime->hw = oxygen_ac97_hardware; + else + runtime->hw = *oxygen_hardware[channel]; switch (channel) { case PCM_C: runtime->hw.rates &= ~(SNDRV_PCM_RATE_32000 | @@ -353,30 +357,37 @@ static int oxygen_rec_b_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *hw_params) { struct oxygen *chip = snd_pcm_substream_chip(substream); + int is_ac97; int err; err = oxygen_hw_params(substream, hw_params); if (err < 0) return err; + is_ac97 = chip->has_ac97_1 && + (chip->model->used_channels & OXYGEN_CHANNEL_AC97); + spin_lock_irq(&chip->reg_lock); oxygen_write8_masked(chip, OXYGEN_REC_FORMAT, oxygen_format(hw_params) << OXYGEN_REC_FORMAT_B_SHIFT, OXYGEN_REC_FORMAT_B_MASK); - oxygen_write16_masked(chip, OXYGEN_I2S_B_FORMAT, - oxygen_rate(hw_params) | - oxygen_i2s_mclk(hw_params) | - chip->model->adc_i2s_format | - oxygen_i2s_bits(hw_params), - OXYGEN_I2S_RATE_MASK | - OXYGEN_I2S_FORMAT_MASK | - OXYGEN_I2S_MCLK_MASK | - OXYGEN_I2S_BITS_MASK); + if (!is_ac97) + oxygen_write16_masked(chip, OXYGEN_I2S_B_FORMAT, + oxygen_rate(hw_params) | + oxygen_i2s_mclk(hw_params) | + chip->model->adc_i2s_format | + oxygen_i2s_bits(hw_params), + OXYGEN_I2S_RATE_MASK | + OXYGEN_I2S_FORMAT_MASK | + OXYGEN_I2S_MCLK_MASK | + OXYGEN_I2S_BITS_MASK); spin_unlock_irq(&chip->reg_lock); - mutex_lock(&chip->mutex); - chip->model->set_adc_params(chip, hw_params); - mutex_unlock(&chip->mutex); + if (!is_ac97) { + mutex_lock(&chip->mutex); + chip->model->set_adc_params(chip, hw_params); + mutex_unlock(&chip->mutex); + } return 0; } @@ -677,23 +688,28 @@ int __devinit oxygen_pcm_init(struct oxygen *chip) outs = chip->has_ac97_1 && (chip->model->used_channels & OXYGEN_CHANNEL_AC97); - ins = (chip->model->used_channels & (OXYGEN_CHANNEL_A | - OXYGEN_CHANNEL_B)) + ins = outs || + (chip->model->used_channels & (OXYGEN_CHANNEL_A | + OXYGEN_CHANNEL_B)) == (OXYGEN_CHANNEL_A | OXYGEN_CHANNEL_B); if (outs | ins) { - err = snd_pcm_new(chip->card, ins ? "Analog2" : "AC97", + err = snd_pcm_new(chip->card, outs ? "AC97" : "Analog2", 2, outs, ins, &pcm); if (err < 0) return err; - if (outs) + if (outs) { snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &oxygen_ac97_ops); + oxygen_write8_masked(chip, OXYGEN_REC_ROUTING, + OXYGEN_REC_B_ROUTE_AC97_1, + OXYGEN_REC_B_ROUTE_MASK); + } if (ins) snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &oxygen_rec_b_ops); pcm->private_data = chip; pcm->private_free = oxygen_pcm_free; - strcpy(pcm->name, ins ? "Analog 2" : "Front Panel"); + strcpy(pcm->name, outs ? "Front Panel" : "Analog 2"); snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci), 128 * 1024, 256 * 1024); |