aboutsummaryrefslogtreecommitdiff
path: root/sound
diff options
context:
space:
mode:
Diffstat (limited to 'sound')
-rw-r--r--sound/pci/oxygen/oxygen.c11
-rw-r--r--sound/pci/oxygen/oxygen.h2
-rw-r--r--sound/pci/oxygen/oxygen_pcm.c72
-rw-r--r--sound/pci/oxygen/virtuoso.c5
4 files changed, 64 insertions, 26 deletions
diff --git a/sound/pci/oxygen/oxygen.c b/sound/pci/oxygen/oxygen.c
index 83c6fab425f..e2dda16d5dc 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 fb9cb36b87b..9b0234d81d4 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 0f67defc2b2..5f15d355a43 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 247d5e1ccb6..0574fa19dca 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,