ALSA: oxygen: fix output routing on Xonar DG
This card uses separate I2S outputs for the front speakers and headphones, and reverses the order of the three speaker outputs. To work around this, add a model-specific callback to adjust the controller's playback routing. Signed-off-by: Clemens Ladisch <clemens@ladisch.de> Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
Родитель
fdbc5d1b32
Коммит
efbeb07181
|
@ -92,6 +92,8 @@ 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);
|
||||||
void (*update_center_lfe_mix)(struct oxygen *chip, bool mixed);
|
void (*update_center_lfe_mix)(struct oxygen *chip, bool mixed);
|
||||||
|
unsigned int (*adjust_dac_routing)(struct oxygen *chip,
|
||||||
|
unsigned int play_routing);
|
||||||
void (*gpio_changed)(struct oxygen *chip);
|
void (*gpio_changed)(struct oxygen *chip);
|
||||||
void (*uart_input)(struct oxygen *chip);
|
void (*uart_input)(struct oxygen *chip);
|
||||||
void (*ac97_switch)(struct oxygen *chip,
|
void (*ac97_switch)(struct oxygen *chip,
|
||||||
|
|
|
@ -180,6 +180,8 @@ void oxygen_update_dac_routing(struct oxygen *chip)
|
||||||
(1 << OXYGEN_PLAY_DAC1_SOURCE_SHIFT) |
|
(1 << OXYGEN_PLAY_DAC1_SOURCE_SHIFT) |
|
||||||
(2 << OXYGEN_PLAY_DAC2_SOURCE_SHIFT) |
|
(2 << OXYGEN_PLAY_DAC2_SOURCE_SHIFT) |
|
||||||
(3 << OXYGEN_PLAY_DAC3_SOURCE_SHIFT);
|
(3 << OXYGEN_PLAY_DAC3_SOURCE_SHIFT);
|
||||||
|
if (chip->model.adjust_dac_routing)
|
||||||
|
reg_value = chip->model.adjust_dac_routing(chip, reg_value);
|
||||||
oxygen_write16_masked(chip, OXYGEN_PLAY_ROUTING, reg_value,
|
oxygen_write16_masked(chip, OXYGEN_PLAY_ROUTING, reg_value,
|
||||||
OXYGEN_PLAY_DAC0_SOURCE_MASK |
|
OXYGEN_PLAY_DAC0_SOURCE_MASK |
|
||||||
OXYGEN_PLAY_DAC1_SOURCE_MASK |
|
OXYGEN_PLAY_DAC1_SOURCE_MASK |
|
||||||
|
|
|
@ -24,6 +24,11 @@
|
||||||
*
|
*
|
||||||
* SPI 0 -> CS4245
|
* SPI 0 -> CS4245
|
||||||
*
|
*
|
||||||
|
* I²S 1 -> CS4245
|
||||||
|
* I²S 2 -> CS4361 (center/LFE)
|
||||||
|
* I²S 3 -> CS4361 (surround)
|
||||||
|
* I²S 4 -> CS4361 (front)
|
||||||
|
*
|
||||||
* GPIO 3 <- ?
|
* GPIO 3 <- ?
|
||||||
* GPIO 4 <- headphone detect
|
* GPIO 4 <- headphone detect
|
||||||
* GPIO 5 -> route input jack to line-in (0) or mic-in (1)
|
* GPIO 5 -> route input jack to line-in (0) or mic-in (1)
|
||||||
|
@ -36,6 +41,7 @@
|
||||||
* input 1 <- aux
|
* input 1 <- aux
|
||||||
* input 2 <- front mic
|
* input 2 <- front mic
|
||||||
* input 4 <- line/mic
|
* input 4 <- line/mic
|
||||||
|
* DAC out -> headphones
|
||||||
* aux out -> front panel headphones
|
* aux out -> front panel headphones
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -207,6 +213,35 @@ static void set_cs4245_adc_params(struct oxygen *chip,
|
||||||
cs4245_write_cached(chip, CS4245_ADC_CTRL, value);
|
cs4245_write_cached(chip, CS4245_ADC_CTRL, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline unsigned int shift_bits(unsigned int value,
|
||||||
|
unsigned int shift_from,
|
||||||
|
unsigned int shift_to,
|
||||||
|
unsigned int mask)
|
||||||
|
{
|
||||||
|
if (shift_from < shift_to)
|
||||||
|
return (value << (shift_to - shift_from)) & mask;
|
||||||
|
else
|
||||||
|
return (value >> (shift_from - shift_to)) & mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned int adjust_dg_dac_routing(struct oxygen *chip,
|
||||||
|
unsigned int play_routing)
|
||||||
|
{
|
||||||
|
return (play_routing & OXYGEN_PLAY_DAC0_SOURCE_MASK) |
|
||||||
|
shift_bits(play_routing,
|
||||||
|
OXYGEN_PLAY_DAC2_SOURCE_SHIFT,
|
||||||
|
OXYGEN_PLAY_DAC1_SOURCE_SHIFT,
|
||||||
|
OXYGEN_PLAY_DAC1_SOURCE_MASK) |
|
||||||
|
shift_bits(play_routing,
|
||||||
|
OXYGEN_PLAY_DAC1_SOURCE_SHIFT,
|
||||||
|
OXYGEN_PLAY_DAC2_SOURCE_SHIFT,
|
||||||
|
OXYGEN_PLAY_DAC2_SOURCE_MASK) |
|
||||||
|
shift_bits(play_routing,
|
||||||
|
OXYGEN_PLAY_DAC0_SOURCE_SHIFT,
|
||||||
|
OXYGEN_PLAY_DAC3_SOURCE_SHIFT,
|
||||||
|
OXYGEN_PLAY_DAC3_SOURCE_MASK);
|
||||||
|
}
|
||||||
|
|
||||||
static int output_switch_info(struct snd_kcontrol *ctl,
|
static int output_switch_info(struct snd_kcontrol *ctl,
|
||||||
struct snd_ctl_elem_info *info)
|
struct snd_ctl_elem_info *info)
|
||||||
{
|
{
|
||||||
|
@ -557,6 +592,7 @@ struct oxygen_model model_xonar_dg = {
|
||||||
.resume = dg_resume,
|
.resume = dg_resume,
|
||||||
.set_dac_params = set_cs4245_dac_params,
|
.set_dac_params = set_cs4245_dac_params,
|
||||||
.set_adc_params = set_cs4245_adc_params,
|
.set_adc_params = set_cs4245_adc_params,
|
||||||
|
.adjust_dac_routing = adjust_dg_dac_routing,
|
||||||
.dump_registers = dump_cs4245_registers,
|
.dump_registers = dump_cs4245_registers,
|
||||||
.model_data_size = sizeof(struct dg),
|
.model_data_size = sizeof(struct dg),
|
||||||
.device_config = PLAYBACK_0_TO_I2S |
|
.device_config = PLAYBACK_0_TO_I2S |
|
||||||
|
|
Загрузка…
Ссылка в новой задаче