From: Clemens Ladisch Date: Wed, 16 Jan 2008 07:30:38 +0000 (+0100) Subject: [ALSA] oxygen: make all DMA channels configurable X-Git-Tag: v2.6.25-rc1~1127^2~101 X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e85e09250ab552fab6925bcde7c77746101b2d40;p=linux-2.6 [ALSA] oxygen: make all DMA channels configurable Allow the card models to specify whether each of the hardware DMA channels is used. Signed-off-by: Clemens Ladisch Signed-off-by: Jaroslav Kysela --- diff --git a/sound/pci/oxygen/oxygen.c b/sound/pci/oxygen/oxygen.c index 83c6fab425..e2dda16d5d 100644 --- a/sound/pci/oxygen/oxygen.c +++ b/sound/pci/oxygen/oxygen.c @@ -256,6 +256,11 @@ static const struct oxygen_model model_generic = { .update_dac_volume = update_ak4396_volume, .update_dac_mute = update_ak4396_mute, .dac_tlv = ak4396_db_scale, + .used_channels = OXYGEN_CHANNEL_A | + OXYGEN_CHANNEL_C | + OXYGEN_CHANNEL_SPDIF | + OXYGEN_CHANNEL_MULTICH | + OXYGEN_CHANNEL_AC97, .function_flags = OXYGEN_FUNCTION_ENABLE_SPI_4_5, }; static const struct oxygen_model model_meridian = { @@ -270,7 +275,11 @@ static const struct oxygen_model model_meridian = { .update_dac_volume = update_ak4396_volume, .update_dac_mute = update_ak4396_mute, .dac_tlv = ak4396_db_scale, - .record_from_dma_b = 1, + .used_channels = OXYGEN_CHANNEL_B | + OXYGEN_CHANNEL_C | + OXYGEN_CHANNEL_SPDIF | + OXYGEN_CHANNEL_MULTICH | + OXYGEN_CHANNEL_AC97, .function_flags = OXYGEN_FUNCTION_ENABLE_SPI_4_5, }; diff --git a/sound/pci/oxygen/oxygen.h b/sound/pci/oxygen/oxygen.h index fb9cb36b87..9b0234d81d 100644 --- a/sound/pci/oxygen/oxygen.h +++ b/sound/pci/oxygen/oxygen.h @@ -80,7 +80,7 @@ struct oxygen_model { void (*update_dac_volume)(struct oxygen *chip); void (*update_dac_mute)(struct oxygen *chip); const unsigned int *dac_tlv; - u8 record_from_dma_b; + u8 used_channels; u8 cd_in_from_video_in; u8 dac_minimum_volume; u8 function_flags; diff --git a/sound/pci/oxygen/oxygen_pcm.c b/sound/pci/oxygen/oxygen_pcm.c index 0f67defc2b..5f15d355a4 100644 --- a/sound/pci/oxygen/oxygen_pcm.c +++ b/sound/pci/oxygen/oxygen_pcm.c @@ -681,15 +681,22 @@ static void oxygen_pcm_free(struct snd_pcm *pcm) int __devinit oxygen_pcm_init(struct oxygen *chip) { struct snd_pcm *pcm; + int outs, ins; int err; - err = snd_pcm_new(chip->card, "Analog", 0, 1, 1, &pcm); + outs = 1; /* OXYGEN_CHANNEL_MULTICH is always used */ + ins = !!(chip->model->used_channels & (OXYGEN_CHANNEL_A | + OXYGEN_CHANNEL_B)); + err = snd_pcm_new(chip->card, "Analog", 0, outs, ins, &pcm); if (err < 0) return err; snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &oxygen_multich_ops); - snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, - chip->model->record_from_dma_b ? - &oxygen_rec_b_ops : &oxygen_rec_a_ops); + if (chip->model->used_channels & OXYGEN_CHANNEL_A) + snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, + &oxygen_rec_a_ops); + else if (chip->model->used_channels & OXYGEN_CHANNEL_B) + 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, "Analog"); @@ -697,32 +704,51 @@ int __devinit oxygen_pcm_init(struct oxygen *chip) SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci), 512 * 1024, 2048 * 1024); - snd_pcm_lib_preallocate_pages(pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream, - SNDRV_DMA_TYPE_DEV, - snd_dma_pci_data(chip->pci), - 128 * 1024, 256 * 1024); - - err = snd_pcm_new(chip->card, "Digital", 1, 1, 1, &pcm); - if (err < 0) - return err; - snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &oxygen_spdif_ops); - snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &oxygen_rec_c_ops); - pcm->private_data = chip; - pcm->private_free = oxygen_pcm_free; - strcpy(pcm->name, "Digital"); - snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, + if (ins) + snd_pcm_lib_preallocate_pages(pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream, + SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci), 128 * 1024, 256 * 1024); - if (chip->has_ac97_1) { - err = snd_pcm_new(chip->card, "AC97", 2, 1, 0, &pcm); + outs = !!(chip->model->used_channels & OXYGEN_CHANNEL_SPDIF); + ins = !!(chip->model->used_channels & OXYGEN_CHANNEL_C); + if (outs | ins) { + err = snd_pcm_new(chip->card, "Digital", 1, outs, ins, &pcm); + if (err < 0) + return err; + if (outs) + snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, + &oxygen_spdif_ops); + if (ins) + snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, + &oxygen_rec_c_ops); + pcm->private_data = chip; + pcm->private_free = oxygen_pcm_free; + strcpy(pcm->name, "Digital"); + snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, + snd_dma_pci_data(chip->pci), + 128 * 1024, 256 * 1024); + } + + outs = chip->has_ac97_1 && + (chip->model->used_channels & OXYGEN_CHANNEL_AC97); + ins = (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", + 2, outs, ins, &pcm); if (err < 0) return err; - snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, - &oxygen_ac97_ops); + if (outs) + snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, + &oxygen_ac97_ops); + 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, "Front Panel"); + strcpy(pcm->name, ins ? "Analog 2" : "Front Panel"); snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci), 128 * 1024, 256 * 1024); diff --git a/sound/pci/oxygen/virtuoso.c b/sound/pci/oxygen/virtuoso.c index 247d5e1ccb..0574fa19dc 100644 --- a/sound/pci/oxygen/virtuoso.c +++ b/sound/pci/oxygen/virtuoso.c @@ -224,7 +224,10 @@ static const struct oxygen_model model_xonar = { .update_dac_volume = update_pcm1796_volume, .update_dac_mute = update_pcm1796_mute, .dac_tlv = pcm1796_db_scale, - .record_from_dma_b = 1, + .used_channels = OXYGEN_CHANNEL_B | + OXYGEN_CHANNEL_C | + OXYGEN_CHANNEL_SPDIF | + OXYGEN_CHANNEL_MULTICH, .cd_in_from_video_in = 1, .dac_minimum_volume = 15, .function_flags = OXYGEN_FUNCTION_ENABLE_SPI_4_5,