[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 <clemens@ladisch.de> Signed-off-by: Jaroslav Kysela <perex@perex.cz>
This commit is contained in:
committed by
Jaroslav Kysela
parent
09189ac793
commit
976cd62700
@ -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 = {
|
|||||||
.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 {
|
|||||||
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 @@
|
|||||||
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,
|
|||||||
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,
|
|||||||
|
|
||||||
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)
|
|||||||
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)
|
|||||||
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,
|
|||||||
|
|
||||||
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 = {
|
|||||||
.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 |
|
||||||
|
Reference in New Issue
Block a user