diff options
author | Clemens Ladisch <clemens@ladisch.de> | 2008-01-28 02:35:47 -0500 |
---|---|---|
committer | Jaroslav Kysela <perex@perex.cz> | 2008-01-31 11:30:17 -0500 |
commit | 5f7b9b457751efc9f3ad120d0ebdb19fe753e9d0 (patch) | |
tree | e63cb022688a2f345d7ea489beded5b2964b6406 /sound/pci | |
parent | a3601560496d7b46d2d1187169824d11570ff63a (diff) |
[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>
Diffstat (limited to 'sound/pci')
-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, | |||
118 | int err; | 118 | int err; |
119 | 119 | ||
120 | runtime->private_data = (void *)(uintptr_t)channel; | 120 | runtime->private_data = (void *)(uintptr_t)channel; |
121 | runtime->hw = *oxygen_hardware[channel]; | 121 | if (channel == PCM_B && chip->has_ac97_1 && |
122 | (chip->model->used_channels & OXYGEN_CHANNEL_AC97)) | ||
123 | runtime->hw = oxygen_ac97_hardware; | ||
124 | else | ||
125 | runtime->hw = *oxygen_hardware[channel]; | ||
122 | switch (channel) { | 126 | switch (channel) { |
123 | case PCM_C: | 127 | case PCM_C: |
124 | runtime->hw.rates &= ~(SNDRV_PCM_RATE_32000 | | 128 | runtime->hw.rates &= ~(SNDRV_PCM_RATE_32000 | |
@@ -353,30 +357,37 @@ static int oxygen_rec_b_hw_params(struct snd_pcm_substream *substream, | |||
353 | struct snd_pcm_hw_params *hw_params) | 357 | struct snd_pcm_hw_params *hw_params) |
354 | { | 358 | { |
355 | struct oxygen *chip = snd_pcm_substream_chip(substream); | 359 | struct oxygen *chip = snd_pcm_substream_chip(substream); |
360 | int is_ac97; | ||
356 | int err; | 361 | int err; |
357 | 362 | ||
358 | err = oxygen_hw_params(substream, hw_params); | 363 | err = oxygen_hw_params(substream, hw_params); |
359 | if (err < 0) | 364 | if (err < 0) |
360 | return err; | 365 | return err; |
361 | 366 | ||
367 | is_ac97 = chip->has_ac97_1 && | ||
368 | (chip->model->used_channels & OXYGEN_CHANNEL_AC97); | ||
369 | |||
362 | spin_lock_irq(&chip->reg_lock); | 370 | spin_lock_irq(&chip->reg_lock); |
363 | oxygen_write8_masked(chip, OXYGEN_REC_FORMAT, | 371 | oxygen_write8_masked(chip, OXYGEN_REC_FORMAT, |
364 | oxygen_format(hw_params) << OXYGEN_REC_FORMAT_B_SHIFT, | 372 | oxygen_format(hw_params) << OXYGEN_REC_FORMAT_B_SHIFT, |
365 | OXYGEN_REC_FORMAT_B_MASK); | 373 | OXYGEN_REC_FORMAT_B_MASK); |
366 | oxygen_write16_masked(chip, OXYGEN_I2S_B_FORMAT, | 374 | if (!is_ac97) |
367 | oxygen_rate(hw_params) | | 375 | oxygen_write16_masked(chip, OXYGEN_I2S_B_FORMAT, |
368 | oxygen_i2s_mclk(hw_params) | | 376 | oxygen_rate(hw_params) | |
369 | chip->model->adc_i2s_format | | 377 | oxygen_i2s_mclk(hw_params) | |
370 | oxygen_i2s_bits(hw_params), | 378 | chip->model->adc_i2s_format | |
371 | OXYGEN_I2S_RATE_MASK | | 379 | oxygen_i2s_bits(hw_params), |
372 | OXYGEN_I2S_FORMAT_MASK | | 380 | OXYGEN_I2S_RATE_MASK | |
373 | OXYGEN_I2S_MCLK_MASK | | 381 | OXYGEN_I2S_FORMAT_MASK | |
374 | OXYGEN_I2S_BITS_MASK); | 382 | OXYGEN_I2S_MCLK_MASK | |
383 | OXYGEN_I2S_BITS_MASK); | ||
375 | spin_unlock_irq(&chip->reg_lock); | 384 | spin_unlock_irq(&chip->reg_lock); |
376 | 385 | ||
377 | mutex_lock(&chip->mutex); | 386 | if (!is_ac97) { |
378 | chip->model->set_adc_params(chip, hw_params); | 387 | mutex_lock(&chip->mutex); |
379 | mutex_unlock(&chip->mutex); | 388 | chip->model->set_adc_params(chip, hw_params); |
389 | mutex_unlock(&chip->mutex); | ||
390 | } | ||
380 | return 0; | 391 | return 0; |
381 | } | 392 | } |
382 | 393 | ||
@@ -677,23 +688,28 @@ int __devinit oxygen_pcm_init(struct oxygen *chip) | |||
677 | 688 | ||
678 | outs = chip->has_ac97_1 && | 689 | outs = chip->has_ac97_1 && |
679 | (chip->model->used_channels & OXYGEN_CHANNEL_AC97); | 690 | (chip->model->used_channels & OXYGEN_CHANNEL_AC97); |
680 | ins = (chip->model->used_channels & (OXYGEN_CHANNEL_A | | 691 | ins = outs || |
681 | OXYGEN_CHANNEL_B)) | 692 | (chip->model->used_channels & (OXYGEN_CHANNEL_A | |
693 | OXYGEN_CHANNEL_B)) | ||
682 | == (OXYGEN_CHANNEL_A | OXYGEN_CHANNEL_B); | 694 | == (OXYGEN_CHANNEL_A | OXYGEN_CHANNEL_B); |
683 | if (outs | ins) { | 695 | if (outs | ins) { |
684 | err = snd_pcm_new(chip->card, ins ? "Analog2" : "AC97", | 696 | err = snd_pcm_new(chip->card, outs ? "AC97" : "Analog2", |
685 | 2, outs, ins, &pcm); | 697 | 2, outs, ins, &pcm); |
686 | if (err < 0) | 698 | if (err < 0) |
687 | return err; | 699 | return err; |
688 | if (outs) | 700 | if (outs) { |
689 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, | 701 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, |
690 | &oxygen_ac97_ops); | 702 | &oxygen_ac97_ops); |
703 | oxygen_write8_masked(chip, OXYGEN_REC_ROUTING, | ||
704 | OXYGEN_REC_B_ROUTE_AC97_1, | ||
705 | OXYGEN_REC_B_ROUTE_MASK); | ||
706 | } | ||
691 | if (ins) | 707 | if (ins) |
692 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, | 708 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, |
693 | &oxygen_rec_b_ops); | 709 | &oxygen_rec_b_ops); |
694 | pcm->private_data = chip; | 710 | pcm->private_data = chip; |
695 | pcm->private_free = oxygen_pcm_free; | 711 | pcm->private_free = oxygen_pcm_free; |
696 | strcpy(pcm->name, ins ? "Analog 2" : "Front Panel"); | 712 | strcpy(pcm->name, outs ? "Front Panel" : "Analog 2"); |
697 | snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, | 713 | snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, |
698 | snd_dma_pci_data(chip->pci), | 714 | snd_dma_pci_data(chip->pci), |
699 | 128 * 1024, 256 * 1024); | 715 | 128 * 1024, 256 * 1024); |