mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-10-30 08:02:30 +00:00
ALSA: hda/ca0132 - Clean up ca0132_alt_out_select.
Remove the output structures that were in use before and instead set the DSP commands line by line. Now that the commands use is known, it makes the functionality more clear this way. Signed-off-by: Connor McAdams <conmanx360@gmail.com> Link: https://lore.kernel.org/r/20200825201040.30339-8-conmanx360@gmail.com Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
parent
ed8156c86f
commit
8e00dc7ced
1 changed files with 57 additions and 85 deletions
|
@ -83,6 +83,7 @@ MODULE_FIRMWARE(R3DI_EFX_FILE);
|
|||
static const char *const dirstr[2] = { "Playback", "Capture" };
|
||||
|
||||
#define NUM_OF_OUTPUTS 2
|
||||
static const char *const out_type_str[2] = { "Speakers", "Headphone" };
|
||||
enum {
|
||||
SPEAKER_OUT,
|
||||
HEADPHONE_OUT,
|
||||
|
@ -667,39 +668,6 @@ enum speaker_tuning_reqs {
|
|||
SPEAKER_TUNING_MUTE = 0x3a,
|
||||
};
|
||||
|
||||
/* DSP command sequences for ca0132_alt_select_out */
|
||||
#define ALT_OUT_SET_MAX_COMMANDS 9 /* Max number of commands in sequence */
|
||||
struct ca0132_alt_out_set {
|
||||
char *name; /*preset name*/
|
||||
unsigned char commands;
|
||||
unsigned int mids[ALT_OUT_SET_MAX_COMMANDS];
|
||||
unsigned int reqs[ALT_OUT_SET_MAX_COMMANDS];
|
||||
unsigned int vals[ALT_OUT_SET_MAX_COMMANDS];
|
||||
};
|
||||
|
||||
static const struct ca0132_alt_out_set alt_out_presets[] = {
|
||||
{ .name = "Line Out",
|
||||
.commands = 7,
|
||||
.mids = { 0x96, 0x96, 0x96, 0x8F,
|
||||
0x96, 0x96, 0x96 },
|
||||
.reqs = { 0x19, 0x17, 0x18, 0x01,
|
||||
0x1F, 0x15, 0x3A },
|
||||
.vals = { 0x3F000000, 0x42A00000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000 }
|
||||
},
|
||||
{ .name = "Headphone",
|
||||
.commands = 7,
|
||||
.mids = { 0x96, 0x96, 0x96, 0x8F,
|
||||
0x96, 0x96, 0x96 },
|
||||
.reqs = { 0x19, 0x17, 0x18, 0x01,
|
||||
0x1F, 0x15, 0x3A },
|
||||
.vals = { 0x3F000000, 0x42A00000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000 }
|
||||
},
|
||||
};
|
||||
|
||||
/* Surround output channel count configuration structures. */
|
||||
#define SPEAKER_CHANNEL_CFG_COUNT 5
|
||||
enum {
|
||||
|
@ -4428,21 +4396,31 @@ static void ca0132_alt_select_out_quirk_handler(struct hda_codec *codec)
|
|||
}
|
||||
}
|
||||
|
||||
static void ca0132_set_out_node_pincfg(struct hda_codec *codec, hda_nid_t nid,
|
||||
bool out_enable, bool hp_enable)
|
||||
{
|
||||
unsigned int pin_ctl;
|
||||
|
||||
pin_ctl = snd_hda_codec_read(codec, nid, 0,
|
||||
AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
|
||||
|
||||
pin_ctl = hp_enable ? pin_ctl | PIN_HP_AMP : pin_ctl & ~PIN_HP_AMP;
|
||||
pin_ctl = out_enable ? pin_ctl | PIN_OUT : pin_ctl & ~PIN_OUT;
|
||||
snd_hda_set_pin_ctl(codec, nid, pin_ctl);
|
||||
}
|
||||
|
||||
/*
|
||||
* This function behaves similarly to the ca0132_select_out funciton above,
|
||||
* except with a few differences. It adds the ability to select the current
|
||||
* output with an enumerated control "output source" if the auto detect
|
||||
* mute switch is set to off. If the auto detect mute switch is enabled, it
|
||||
* will detect either headphone or lineout(SPEAKER_OUT) from jack detection.
|
||||
* It also adds the ability to auto-detect the front headphone port. The only
|
||||
* way to select surround is to disable auto detect, and set Surround with the
|
||||
* enumerated control.
|
||||
* It also adds the ability to auto-detect the front headphone port.
|
||||
*/
|
||||
static int ca0132_alt_select_out(struct hda_codec *codec)
|
||||
{
|
||||
struct ca0132_spec *spec = codec->spec;
|
||||
unsigned int tmp, outfx_set, i;
|
||||
unsigned int pin_ctl;
|
||||
unsigned int tmp, outfx_set;
|
||||
int jack_present;
|
||||
int auto_jack;
|
||||
int err;
|
||||
|
@ -4473,9 +4451,8 @@ static int ca0132_alt_select_out(struct hda_codec *codec)
|
|||
|
||||
outfx_set = spec->effects_switch[PLAY_ENHANCEMENT - EFFECT_START_NID];
|
||||
|
||||
/* Begin DSP output switch */
|
||||
tmp = FLOAT_ONE;
|
||||
err = dspio_set_uint_param(codec, 0x96, 0x3A, tmp);
|
||||
/* Begin DSP output switch, mute DSP volume. */
|
||||
err = dspio_set_uint_param(codec, 0x96, SPEAKER_TUNING_MUTE, FLOAT_ONE);
|
||||
if (err < 0)
|
||||
goto exit;
|
||||
|
||||
|
@ -4485,31 +4462,18 @@ static int ca0132_alt_select_out(struct hda_codec *codec)
|
|||
case SPEAKER_OUT:
|
||||
codec_dbg(codec, "%s speaker\n", __func__);
|
||||
|
||||
/* disable headphone node */
|
||||
|
||||
pin_ctl = snd_hda_codec_read(codec, spec->out_pins[1], 0,
|
||||
AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
|
||||
snd_hda_set_pin_ctl(codec, spec->out_pins[1],
|
||||
pin_ctl & ~PIN_HP);
|
||||
/* enable line-out node */
|
||||
pin_ctl = snd_hda_codec_read(codec, spec->out_pins[0], 0,
|
||||
AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
|
||||
snd_hda_set_pin_ctl(codec, spec->out_pins[0],
|
||||
pin_ctl | PIN_OUT);
|
||||
/* Enable EAPD */
|
||||
snd_hda_codec_write(codec, spec->out_pins[0], 0,
|
||||
AC_VERB_SET_EAPD_BTLENABLE, 0x01);
|
||||
|
||||
/* enable center/lfe out node */
|
||||
pin_ctl = snd_hda_codec_read(codec, spec->out_pins[2], 0,
|
||||
AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
|
||||
snd_hda_set_pin_ctl(codec, spec->out_pins[2],
|
||||
pin_ctl | PIN_OUT);
|
||||
/* Now set rear surround node as out. */
|
||||
pin_ctl = snd_hda_codec_read(codec, spec->out_pins[3], 0,
|
||||
AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
|
||||
snd_hda_set_pin_ctl(codec, spec->out_pins[3],
|
||||
pin_ctl | PIN_OUT);
|
||||
/* Disable headphone node. */
|
||||
ca0132_set_out_node_pincfg(codec, spec->out_pins[1], 0, 0);
|
||||
/* Set front L-R to output. */
|
||||
ca0132_set_out_node_pincfg(codec, spec->out_pins[0], 1, 0);
|
||||
/* Set Center/LFE to output. */
|
||||
ca0132_set_out_node_pincfg(codec, spec->out_pins[2], 1, 0);
|
||||
/* Set rear surround to output. */
|
||||
ca0132_set_out_node_pincfg(codec, spec->out_pins[3], 1, 0);
|
||||
|
||||
/*
|
||||
* Without PlayEnhancement being enabled, if we've got a 2.0
|
||||
|
@ -4531,11 +4495,10 @@ static int ca0132_alt_select_out(struct hda_codec *codec)
|
|||
snd_hda_codec_write(codec, spec->out_pins[0], 0,
|
||||
AC_VERB_SET_EAPD_BTLENABLE, 0x00);
|
||||
|
||||
/* disable speaker*/
|
||||
pin_ctl = snd_hda_codec_read(codec, spec->out_pins[0], 0,
|
||||
AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
|
||||
snd_hda_set_pin_ctl(codec, spec->out_pins[0],
|
||||
pin_ctl & ~PIN_HP);
|
||||
/* Disable all speaker nodes. */
|
||||
ca0132_set_out_node_pincfg(codec, spec->out_pins[0], 0, 0);
|
||||
ca0132_set_out_node_pincfg(codec, spec->out_pins[2], 0, 0);
|
||||
ca0132_set_out_node_pincfg(codec, spec->out_pins[3], 0, 0);
|
||||
|
||||
/* enable headphone, either front or rear */
|
||||
if (snd_hda_jack_detect(codec, spec->unsol_tag_front_hp))
|
||||
|
@ -4543,15 +4506,15 @@ static int ca0132_alt_select_out(struct hda_codec *codec)
|
|||
else if (snd_hda_jack_detect(codec, spec->unsol_tag_hp))
|
||||
headphone_nid = spec->out_pins[1];
|
||||
|
||||
pin_ctl = snd_hda_codec_read(codec, headphone_nid, 0,
|
||||
AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
|
||||
snd_hda_set_pin_ctl(codec, headphone_nid,
|
||||
pin_ctl | PIN_HP);
|
||||
ca0132_set_out_node_pincfg(codec, headphone_nid, 1, 1);
|
||||
|
||||
if (outfx_set)
|
||||
dspio_set_uint_param(codec, 0x80, 0x04, FLOAT_ONE);
|
||||
err = dspio_set_uint_param(codec, 0x80, 0x04, FLOAT_ONE);
|
||||
else
|
||||
dspio_set_uint_param(codec, 0x80, 0x04, FLOAT_ZERO);
|
||||
err = dspio_set_uint_param(codec, 0x80, 0x04, FLOAT_ZERO);
|
||||
|
||||
if (err < 0)
|
||||
goto exit;
|
||||
break;
|
||||
}
|
||||
/*
|
||||
|
@ -4563,29 +4526,38 @@ static int ca0132_alt_select_out(struct hda_codec *codec)
|
|||
ca0132_effects_set(codec, X_BASS,
|
||||
spec->effects_switch[X_BASS - EFFECT_START_NID]);
|
||||
|
||||
/* Set speaker EQ bypass attenuation to 0. */
|
||||
err = dspio_set_uint_param(codec, 0x8f, 0x01, FLOAT_ZERO);
|
||||
if (err < 0)
|
||||
goto exit;
|
||||
|
||||
/*
|
||||
* Although unused on all cards but the AE series, this is always set
|
||||
* to zero when setting the output.
|
||||
*/
|
||||
err = dspio_set_uint_param(codec, 0x96,
|
||||
SPEAKER_TUNING_USE_SPEAKER_EQ, FLOAT_ZERO);
|
||||
if (err < 0)
|
||||
goto exit;
|
||||
|
||||
if (spec->cur_out_type == SPEAKER_OUT)
|
||||
err = ca0132_alt_surround_set_bass_redirection(codec,
|
||||
spec->bass_redirection_val);
|
||||
else
|
||||
err = ca0132_alt_surround_set_bass_redirection(codec, 0);
|
||||
|
||||
/* Unmute DSP now that we're done with output selection. */
|
||||
err = dspio_set_uint_param(codec, 0x96,
|
||||
SPEAKER_TUNING_MUTE, FLOAT_ZERO);
|
||||
if (err < 0)
|
||||
goto exit;
|
||||
|
||||
/* run through the output dsp commands for the selected output. */
|
||||
for (i = 0; i < alt_out_presets[spec->cur_out_type].commands; i++) {
|
||||
err = dspio_set_uint_param(codec,
|
||||
alt_out_presets[spec->cur_out_type].mids[i],
|
||||
alt_out_presets[spec->cur_out_type].reqs[i],
|
||||
alt_out_presets[spec->cur_out_type].vals[i]);
|
||||
|
||||
if (spec->cur_out_type == SPEAKER_OUT) {
|
||||
err = ca0132_alt_set_full_range_speaker(codec);
|
||||
if (err < 0)
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (spec->cur_out_type == SPEAKER_OUT)
|
||||
err = ca0132_alt_set_full_range_speaker(codec);
|
||||
|
||||
exit:
|
||||
snd_hda_power_down_pm(codec);
|
||||
|
||||
|
@ -5659,7 +5631,7 @@ static int ca0132_alt_output_select_get_info(struct snd_kcontrol *kcontrol,
|
|||
if (uinfo->value.enumerated.item >= NUM_OF_OUTPUTS)
|
||||
uinfo->value.enumerated.item = NUM_OF_OUTPUTS - 1;
|
||||
strcpy(uinfo->value.enumerated.name,
|
||||
alt_out_presets[uinfo->value.enumerated.item].name);
|
||||
out_type_str[uinfo->value.enumerated.item]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -5686,7 +5658,7 @@ static int ca0132_alt_output_select_put(struct snd_kcontrol *kcontrol,
|
|||
return 0;
|
||||
|
||||
codec_dbg(codec, "ca0132_alt_output_select: sel=%d, preset=%s\n",
|
||||
sel, alt_out_presets[sel].name);
|
||||
sel, out_type_str[sel]);
|
||||
|
||||
spec->out_enum_val = sel;
|
||||
|
||||
|
|
Loading…
Reference in a new issue