提交 976cd627 编写于 作者: C Clemens Ladisch 提交者: Jaroslav Kysela

[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: NClemens Ladisch <clemens@ladisch.de>
Signed-off-by: NJaroslav Kysela <perex@perex.cz>
上级 09189ac7
...@@ -350,6 +350,7 @@ static const struct oxygen_model model_generic = { ...@@ -350,6 +350,7 @@ static const struct oxygen_model model_generic = {
.update_dac_volume = update_ak4396_volume, .update_dac_volume = update_ak4396_volume,
.update_dac_mute = update_ak4396_mute, .update_dac_mute = update_ak4396_mute,
.model_data_size = sizeof(struct generic_data), .model_data_size = sizeof(struct generic_data),
.dac_channels = 8,
.used_channels = OXYGEN_CHANNEL_A | .used_channels = OXYGEN_CHANNEL_A |
OXYGEN_CHANNEL_C | OXYGEN_CHANNEL_C |
OXYGEN_CHANNEL_SPDIF | OXYGEN_CHANNEL_SPDIF |
...@@ -372,6 +373,7 @@ static const struct oxygen_model model_meridian = { ...@@ -372,6 +373,7 @@ static const struct oxygen_model model_meridian = {
.update_dac_volume = update_ak4396_volume, .update_dac_volume = update_ak4396_volume,
.update_dac_mute = update_ak4396_mute, .update_dac_mute = update_ak4396_mute,
.model_data_size = sizeof(struct generic_data), .model_data_size = sizeof(struct generic_data),
.dac_channels = 8,
.used_channels = OXYGEN_CHANNEL_B | .used_channels = OXYGEN_CHANNEL_B |
OXYGEN_CHANNEL_C | OXYGEN_CHANNEL_C |
OXYGEN_CHANNEL_SPDIF | OXYGEN_CHANNEL_SPDIF |
......
...@@ -85,6 +85,7 @@ struct oxygen_model { ...@@ -85,6 +85,7 @@ struct oxygen_model {
void (*update_dac_volume)(struct oxygen *chip); void (*update_dac_volume)(struct oxygen *chip);
void (*update_dac_mute)(struct oxygen *chip); void (*update_dac_mute)(struct oxygen *chip);
size_t model_data_size; size_t model_data_size;
u8 dac_channels;
u8 used_channels; u8 used_channels;
u8 function_flags; u8 function_flags;
u16 dac_i2s_format; u16 dac_i2s_format;
......
...@@ -28,8 +28,10 @@ ...@@ -28,8 +28,10 @@
static int dac_volume_info(struct snd_kcontrol *ctl, static int dac_volume_info(struct snd_kcontrol *ctl,
struct snd_ctl_elem_info *info) struct snd_ctl_elem_info *info)
{ {
struct oxygen *chip = ctl->private_data;
info->type = SNDRV_CTL_ELEM_TYPE_INTEGER; info->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
info->count = 8; info->count = chip->model->dac_channels;
info->value.integer.min = 0; info->value.integer.min = 0;
info->value.integer.max = 0xff; info->value.integer.max = 0xff;
return 0; return 0;
...@@ -42,7 +44,7 @@ static int dac_volume_get(struct snd_kcontrol *ctl, ...@@ -42,7 +44,7 @@ static int dac_volume_get(struct snd_kcontrol *ctl,
unsigned int i; unsigned int i;
mutex_lock(&chip->mutex); 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]; value->value.integer.value[i] = chip->dac_volume[i];
mutex_unlock(&chip->mutex); mutex_unlock(&chip->mutex);
return 0; return 0;
...@@ -57,7 +59,7 @@ static int dac_volume_put(struct snd_kcontrol *ctl, ...@@ -57,7 +59,7 @@ static int dac_volume_put(struct snd_kcontrol *ctl,
changed = 0; changed = 0;
mutex_lock(&chip->mutex); 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]) { if (value->value.integer.value[i] != chip->dac_volume[i]) {
chip->dac_volume[i] = value->value.integer.value[i]; chip->dac_volume[i] = value->value.integer.value[i];
changed = 1; changed = 1;
...@@ -100,11 +102,14 @@ static int upmix_info(struct snd_kcontrol *ctl, struct snd_ctl_elem_info *info) ...@@ -100,11 +102,14 @@ static int upmix_info(struct snd_kcontrol *ctl, struct snd_ctl_elem_info *info)
static const char *const names[3] = { static const char *const names[3] = {
"Front", "Front+Surround", "Front+Surround+Back" "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->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
info->count = 1; info->count = 1;
info->value.enumerated.items = 3; info->value.enumerated.items = count;
if (info->value.enumerated.item > 2) if (info->value.enumerated.item >= count)
info->value.enumerated.item = 2; info->value.enumerated.item = count - 1;
strcpy(info->value.enumerated.name, names[info->value.enumerated.item]); strcpy(info->value.enumerated.name, names[info->value.enumerated.item]);
return 0; return 0;
} }
...@@ -167,12 +172,14 @@ void oxygen_update_dac_routing(struct oxygen *chip) ...@@ -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) static int upmix_put(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value)
{ {
struct oxygen *chip = ctl->private_data; struct oxygen *chip = ctl->private_data;
unsigned int count = 2 + (chip->model->dac_channels == 8);
int changed; int changed;
mutex_lock(&chip->mutex); mutex_lock(&chip->mutex);
changed = value->value.enumerated.item[0] != chip->dac_routing; changed = value->value.enumerated.item[0] != chip->dac_routing;
if (changed) { 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); spin_lock_irq(&chip->reg_lock);
oxygen_update_dac_routing(chip); oxygen_update_dac_routing(chip);
spin_unlock_irq(&chip->reg_lock); spin_unlock_irq(&chip->reg_lock);
......
...@@ -119,10 +119,15 @@ static int oxygen_open(struct snd_pcm_substream *substream, ...@@ -119,10 +119,15 @@ static int oxygen_open(struct snd_pcm_substream *substream,
runtime->private_data = (void *)(uintptr_t)channel; runtime->private_data = (void *)(uintptr_t)channel;
runtime->hw = *oxygen_hardware[channel]; runtime->hw = *oxygen_hardware[channel];
if (channel == PCM_C) { switch (channel) {
case PCM_C:
runtime->hw.rates &= ~(SNDRV_PCM_RATE_32000 | runtime->hw.rates &= ~(SNDRV_PCM_RATE_32000 |
SNDRV_PCM_RATE_64000); SNDRV_PCM_RATE_64000);
runtime->hw.rate_min = 44100; runtime->hw.rate_min = 44100;
break;
case PCM_MULTICH:
runtime->hw.channels_max = chip->model->dac_channels;
break;
} }
if (chip->model->pcm_hardware_filter) if (chip->model->pcm_hardware_filter)
chip->model->pcm_hardware_filter(channel, &runtime->hw); chip->model->pcm_hardware_filter(channel, &runtime->hw);
......
...@@ -310,6 +310,7 @@ static const struct oxygen_model model_xonar = { ...@@ -310,6 +310,7 @@ static const struct oxygen_model model_xonar = {
.set_adc_params = set_cs5381_params, .set_adc_params = set_cs5381_params,
.update_dac_volume = update_pcm1796_volume, .update_dac_volume = update_pcm1796_volume,
.update_dac_mute = update_pcm1796_mute, .update_dac_mute = update_pcm1796_mute,
.dac_channels = 8,
.used_channels = OXYGEN_CHANNEL_B | .used_channels = OXYGEN_CHANNEL_B |
OXYGEN_CHANNEL_C | OXYGEN_CHANNEL_C |
OXYGEN_CHANNEL_SPDIF | OXYGEN_CHANNEL_SPDIF |
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册