From 976cd62700ae378df330ec82112da3d17e33a0fe Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Fri, 25 Jan 2008 08:37:49 +0100 Subject: [ALSA] oxygen: make the number of analog output configurable Add a field to struct oxygen_model to allow model drivers for cards with less than eight output channels. Signed-off-by: Clemens Ladisch Signed-off-by: Jaroslav Kysela --- sound/pci/oxygen/oxygen.c | 2 ++ sound/pci/oxygen/oxygen.h | 1 + sound/pci/oxygen/oxygen_mixer.c | 21 ++++++++++++++------- sound/pci/oxygen/oxygen_pcm.c | 7 ++++++- sound/pci/oxygen/virtuoso.c | 1 + 5 files changed, 24 insertions(+), 8 deletions(-) (limited to 'sound') diff --git a/sound/pci/oxygen/oxygen.c b/sound/pci/oxygen/oxygen.c index 4f809bdc75e1..60af3a7d9824 100644 --- a/sound/pci/oxygen/oxygen.c +++ b/sound/pci/oxygen/oxygen.c @@ -350,6 +350,7 @@ static const struct oxygen_model model_generic = { .update_dac_volume = update_ak4396_volume, .update_dac_mute = update_ak4396_mute, .model_data_size = sizeof(struct generic_data), + .dac_channels = 8, .used_channels = OXYGEN_CHANNEL_A | OXYGEN_CHANNEL_C | OXYGEN_CHANNEL_SPDIF | @@ -372,6 +373,7 @@ static const struct oxygen_model model_meridian = { .update_dac_volume = update_ak4396_volume, .update_dac_mute = update_ak4396_mute, .model_data_size = sizeof(struct generic_data), + .dac_channels = 8, .used_channels = OXYGEN_CHANNEL_B | OXYGEN_CHANNEL_C | OXYGEN_CHANNEL_SPDIF | diff --git a/sound/pci/oxygen/oxygen.h b/sound/pci/oxygen/oxygen.h index 4894dbd28126..9ec9e6bab7d7 100644 --- a/sound/pci/oxygen/oxygen.h +++ b/sound/pci/oxygen/oxygen.h @@ -85,6 +85,7 @@ struct oxygen_model { void (*update_dac_volume)(struct oxygen *chip); void (*update_dac_mute)(struct oxygen *chip); size_t model_data_size; + u8 dac_channels; u8 used_channels; u8 function_flags; u16 dac_i2s_format; diff --git a/sound/pci/oxygen/oxygen_mixer.c b/sound/pci/oxygen/oxygen_mixer.c index 6b7420fdd026..21b227a94ace 100644 --- a/sound/pci/oxygen/oxygen_mixer.c +++ b/sound/pci/oxygen/oxygen_mixer.c @@ -28,8 +28,10 @@ static int dac_volume_info(struct snd_kcontrol *ctl, struct snd_ctl_elem_info *info) { + struct oxygen *chip = ctl->private_data; + info->type = SNDRV_CTL_ELEM_TYPE_INTEGER; - info->count = 8; + info->count = chip->model->dac_channels; info->value.integer.min = 0; info->value.integer.max = 0xff; return 0; @@ -42,7 +44,7 @@ static int dac_volume_get(struct snd_kcontrol *ctl, unsigned int i; mutex_lock(&chip->mutex); - for (i = 0; i < 8; ++i) + for (i = 0; i < chip->model->dac_channels; ++i) value->value.integer.value[i] = chip->dac_volume[i]; mutex_unlock(&chip->mutex); return 0; @@ -57,7 +59,7 @@ static int dac_volume_put(struct snd_kcontrol *ctl, changed = 0; mutex_lock(&chip->mutex); - for (i = 0; i < 8; ++i) + for (i = 0; i < chip->model->dac_channels; ++i) if (value->value.integer.value[i] != chip->dac_volume[i]) { chip->dac_volume[i] = value->value.integer.value[i]; changed = 1; @@ -100,11 +102,14 @@ static int upmix_info(struct snd_kcontrol *ctl, struct snd_ctl_elem_info *info) static const char *const names[3] = { "Front", "Front+Surround", "Front+Surround+Back" }; + struct oxygen *chip = ctl->private_data; + unsigned int count = 2 + (chip->model->dac_channels == 8); + info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; info->count = 1; - info->value.enumerated.items = 3; - if (info->value.enumerated.item > 2) - info->value.enumerated.item = 2; + info->value.enumerated.items = count; + if (info->value.enumerated.item >= count) + info->value.enumerated.item = count - 1; strcpy(info->value.enumerated.name, names[info->value.enumerated.item]); return 0; } @@ -167,12 +172,14 @@ void oxygen_update_dac_routing(struct oxygen *chip) static int upmix_put(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value) { struct oxygen *chip = ctl->private_data; + unsigned int count = 2 + (chip->model->dac_channels == 8); int changed; mutex_lock(&chip->mutex); changed = value->value.enumerated.item[0] != chip->dac_routing; if (changed) { - chip->dac_routing = min(value->value.enumerated.item[0], 2u); + chip->dac_routing = min(value->value.enumerated.item[0], + count - 1); spin_lock_irq(&chip->reg_lock); oxygen_update_dac_routing(chip); spin_unlock_irq(&chip->reg_lock); diff --git a/sound/pci/oxygen/oxygen_pcm.c b/sound/pci/oxygen/oxygen_pcm.c index 2785660957d0..df1d0cae1dad 100644 --- a/sound/pci/oxygen/oxygen_pcm.c +++ b/sound/pci/oxygen/oxygen_pcm.c @@ -119,10 +119,15 @@ static int oxygen_open(struct snd_pcm_substream *substream, runtime->private_data = (void *)(uintptr_t)channel; runtime->hw = *oxygen_hardware[channel]; - if (channel == PCM_C) { + switch (channel) { + case PCM_C: runtime->hw.rates &= ~(SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_64000); runtime->hw.rate_min = 44100; + break; + case PCM_MULTICH: + runtime->hw.channels_max = chip->model->dac_channels; + break; } if (chip->model->pcm_hardware_filter) chip->model->pcm_hardware_filter(channel, &runtime->hw); diff --git a/sound/pci/oxygen/virtuoso.c b/sound/pci/oxygen/virtuoso.c index 7b240c778759..665115d23627 100644 --- a/sound/pci/oxygen/virtuoso.c +++ b/sound/pci/oxygen/virtuoso.c @@ -310,6 +310,7 @@ static const struct oxygen_model model_xonar = { .set_adc_params = set_cs5381_params, .update_dac_volume = update_pcm1796_volume, .update_dac_mute = update_pcm1796_mute, + .dac_channels = 8, .used_channels = OXYGEN_CHANNEL_B | OXYGEN_CHANNEL_C | OXYGEN_CHANNEL_SPDIF | -- cgit v1.2.3-59-g8ed1b