aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/oxygen/oxygen_pcm.c
diff options
context:
space:
mode:
authorClemens Ladisch <clemens@ladisch.de>2008-01-28 02:35:47 -0500
committerJaroslav Kysela <perex@perex.cz>2008-01-31 11:30:17 -0500
commit5f7b9b457751efc9f3ad120d0ebdb19fe753e9d0 (patch)
treee63cb022688a2f345d7ea489beded5b2964b6406 /sound/pci/oxygen/oxygen_pcm.c
parenta3601560496d7b46d2d1187169824d11570ff63a (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/oxygen/oxygen_pcm.c')
-rw-r--r--sound/pci/oxygen/oxygen_pcm.c52
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);