Skip to content

Commit

Permalink
ALSA: oxygen: Xonar DG(X): modify playback output select
Browse files Browse the repository at this point in the history
Change the order of elements in the output select control. This will
reduce the number of relay switches. Change 'put' function to call the
oxygen_update_dac_routing() function. Otherwise multichannel playback
does not work. Also there is a new function to apply settings, this
prevents from duplicating the code.

Signed-off-by: Roman Volkov <v1ron@mail.ru>
Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
  • Loading branch information
Roman Volkov authored and Clemens Ladisch committed Jan 29, 2014
1 parent 3dd7765 commit 2809cb8
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 33 deletions.
2 changes: 1 addition & 1 deletion sound/pci/oxygen/xonar_dg.c
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,7 @@ unsigned int adjust_dg_dac_routing(struct oxygen *chip,
struct dg *data = chip->model_data;
unsigned int routing = 0;

switch (data->pcm_output) {
switch (data->output_sel) {
case PLAYBACK_DST_HP:
case PLAYBACK_DST_HP_FP:
oxygen_write8_masked(chip, OXYGEN_PLAY_ROUTING,
Expand Down
3 changes: 1 addition & 2 deletions sound/pci/oxygen/xonar_dg.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,7 @@ struct dg {
/* shadow copy of the CS4245 register space */
unsigned char cs4245_shadow[17];
/* output select: headphone/speakers */
unsigned char pcm_output;
unsigned int output_sel;
unsigned char output_sel;
s8 input_vol[4][2];
unsigned int input_sel;
u8 hp_vol_att;
Expand Down
75 changes: 45 additions & 30 deletions sound/pci/oxygen/xonar_dg_mixer.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 +27,46 @@
#include "xonar_dg.h"
#include "cs4245.h"

static int output_switch_info(struct snd_kcontrol *ctl,
/* analog output select */

static int output_select_apply(struct oxygen *chip)
{
struct dg *data = chip->model_data;

data->cs4245_shadow[CS4245_SIGNAL_SEL] &= ~CS4245_A_OUT_SEL_MASK;
if (data->output_sel == PLAYBACK_DST_HP) {
/* mute FP (aux output) amplifier, switch rear jack to CS4245 */
oxygen_set_bits8(chip, OXYGEN_GPIO_DATA, GPIO_HP_REAR);
} else if (data->output_sel == PLAYBACK_DST_HP_FP) {
/*
* Unmute FP amplifier, switch rear jack to CS4361;
* I2S channels 2,3,4 should be inactive.
*/
oxygen_clear_bits8(chip, OXYGEN_GPIO_DATA, GPIO_HP_REAR);
data->cs4245_shadow[CS4245_SIGNAL_SEL] |= CS4245_A_OUT_SEL_DAC;
} else {
/*
* 2.0, 4.0, 5.1: switch to CS4361, mute FP amp.,
* and change playback routing.
*/
oxygen_clear_bits8(chip, OXYGEN_GPIO_DATA, GPIO_HP_REAR);
}
return cs4245_write_spi(chip, CS4245_SIGNAL_SEL);
}

static int output_select_info(struct snd_kcontrol *ctl,
struct snd_ctl_elem_info *info)
{
static const char *const names[3] = {
"Speakers", "Headphones", "FP Headphones"
"Stereo Headphones",
"Stereo Headphones FP",
"Multichannel",
};

return snd_ctl_enum_info(info, 1, 3, names);
}

static int output_switch_get(struct snd_kcontrol *ctl,
static int output_select_get(struct snd_kcontrol *ctl,
struct snd_ctl_elem_value *value)
{
struct oxygen *chip = ctl->private_data;
Expand All @@ -49,38 +78,24 @@ static int output_switch_get(struct snd_kcontrol *ctl,
return 0;
}

static int output_switch_put(struct snd_kcontrol *ctl,
static int output_select_put(struct snd_kcontrol *ctl,
struct snd_ctl_elem_value *value)
{
struct oxygen *chip = ctl->private_data;
struct dg *data = chip->model_data;
u8 reg;
int changed;

if (value->value.enumerated.item[0] > 2)
return -EINVAL;
unsigned int new = value->value.enumerated.item[0];
int changed = 0;
int ret;

mutex_lock(&chip->mutex);
changed = value->value.enumerated.item[0] != data->output_sel;
if (changed) {
data->output_sel = value->value.enumerated.item[0];

reg = data->cs4245_shadow[CS4245_SIGNAL_SEL] &
~CS4245_A_OUT_SEL_MASK;
reg |= data->output_sel == 2 ?
CS4245_A_OUT_SEL_DAC : CS4245_A_OUT_SEL_HIZ;
cs4245_write_cached(chip, CS4245_SIGNAL_SEL, reg);

cs4245_write_cached(chip, CS4245_DAC_A_CTRL,
data->output_sel ? data->hp_vol_att : 0);
cs4245_write_cached(chip, CS4245_DAC_B_CTRL,
data->output_sel ? data->hp_vol_att : 0);

oxygen_write16_masked(chip, OXYGEN_GPIO_DATA,
data->output_sel == 1 ? GPIO_HP_REAR : 0,
GPIO_HP_REAR);
if (data->output_sel != new) {
data->output_sel = new;
ret = output_select_apply(chip);
changed = ret >= 0 ? 1 : ret;
oxygen_update_dac_routing(chip);
}
mutex_unlock(&chip->mutex);

return changed;
}

Expand Down Expand Up @@ -301,9 +316,9 @@ static const struct snd_kcontrol_new dg_controls[] = {
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "Analog Output Playback Enum",
.info = output_switch_info,
.get = output_switch_get,
.put = output_switch_put,
.info = output_select_info,
.get = output_select_get,
.put = output_select_put,
},
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
Expand Down

0 comments on commit 2809cb8

Please sign in to comment.