mirror of https://gitee.com/openkylin/linux.git
ALSA: hda - Use new inputs[] field to parse input-pins for VIA codecs
Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
parent
eea7dc932b
commit
7b315bb498
|
@ -444,8 +444,8 @@ static hda_nid_t vt1812_adc_nids[2] = {
|
||||||
|
|
||||||
|
|
||||||
/* add dynamic controls */
|
/* add dynamic controls */
|
||||||
static int via_add_control(struct via_spec *spec, int type, const char *name,
|
static int __via_add_control(struct via_spec *spec, int type, const char *name,
|
||||||
unsigned long val)
|
int idx, unsigned long val)
|
||||||
{
|
{
|
||||||
struct snd_kcontrol_new *knew;
|
struct snd_kcontrol_new *knew;
|
||||||
|
|
||||||
|
@ -463,6 +463,9 @@ static int via_add_control(struct via_spec *spec, int type, const char *name,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define via_add_control(spec, type, name, val) \
|
||||||
|
__via_add_control(spec, type, name, 0, val)
|
||||||
|
|
||||||
static struct snd_kcontrol_new *via_clone_control(struct via_spec *spec,
|
static struct snd_kcontrol_new *via_clone_control(struct via_spec *spec,
|
||||||
struct snd_kcontrol_new *tmpl)
|
struct snd_kcontrol_new *tmpl)
|
||||||
{
|
{
|
||||||
|
@ -494,18 +497,18 @@ static void via_free_kctls(struct hda_codec *codec)
|
||||||
|
|
||||||
/* create input playback/capture controls for the given pin */
|
/* create input playback/capture controls for the given pin */
|
||||||
static int via_new_analog_input(struct via_spec *spec, const char *ctlname,
|
static int via_new_analog_input(struct via_spec *spec, const char *ctlname,
|
||||||
int idx, int mix_nid)
|
int type_idx, int idx, int mix_nid)
|
||||||
{
|
{
|
||||||
char name[32];
|
char name[32];
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
sprintf(name, "%s Playback Volume", ctlname);
|
sprintf(name, "%s Playback Volume", ctlname);
|
||||||
err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
|
err = __via_add_control(spec, VIA_CTL_WIDGET_VOL, name, type_idx,
|
||||||
HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
|
HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
return err;
|
||||||
sprintf(name, "%s Playback Switch", ctlname);
|
sprintf(name, "%s Playback Switch", ctlname);
|
||||||
err = via_add_control(spec, VIA_CTL_WIDGET_ANALOG_MUTE, name,
|
err = __via_add_control(spec, VIA_CTL_WIDGET_ANALOG_MUTE, name, type_idx,
|
||||||
HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
|
HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
return err;
|
||||||
|
@ -557,14 +560,12 @@ static int is_smart51_pins(struct via_spec *spec, hda_nid_t pin);
|
||||||
static void via_auto_init_analog_input(struct hda_codec *codec)
|
static void via_auto_init_analog_input(struct hda_codec *codec)
|
||||||
{
|
{
|
||||||
struct via_spec *spec = codec->spec;
|
struct via_spec *spec = codec->spec;
|
||||||
|
const struct auto_pin_cfg *cfg = &spec->autocfg;
|
||||||
unsigned int ctl;
|
unsigned int ctl;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < AUTO_PIN_LAST; i++) {
|
for (i = 0; i < cfg->num_inputs; i++) {
|
||||||
hda_nid_t nid = spec->autocfg.input_pins[i];
|
hda_nid_t nid = cfg->inputs[i].pin;
|
||||||
if (!nid)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (spec->smart51_enabled && is_smart51_pins(spec, nid))
|
if (spec->smart51_enabled && is_smart51_pins(spec, nid))
|
||||||
ctl = PIN_OUT;
|
ctl = PIN_OUT;
|
||||||
else if (i <= AUTO_PIN_FRONT_MIC)
|
else if (i <= AUTO_PIN_FRONT_MIC)
|
||||||
|
@ -1322,15 +1323,14 @@ static void mute_aa_path(struct hda_codec *codec, int mute)
|
||||||
}
|
}
|
||||||
static int is_smart51_pins(struct via_spec *spec, hda_nid_t pin)
|
static int is_smart51_pins(struct via_spec *spec, hda_nid_t pin)
|
||||||
{
|
{
|
||||||
int res = 0;
|
const struct auto_pin_cfg *cfg = &spec->autocfg;
|
||||||
int index;
|
int i;
|
||||||
for (index = AUTO_PIN_MIC; index < AUTO_PIN_FRONT_LINE; index++) {
|
|
||||||
if (pin == spec->autocfg.input_pins[index]) {
|
for (i = 0; i < cfg->num_inputs; i++) {
|
||||||
res = 1;
|
if (pin == cfg->inputs[i].pin)
|
||||||
break;
|
return cfg->inputs[i].type < AUTO_PIN_FRONT_LINE;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return res;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int via_smart51_info(struct snd_kcontrol *kcontrol,
|
static int via_smart51_info(struct snd_kcontrol *kcontrol,
|
||||||
|
@ -1348,25 +1348,21 @@ static int via_smart51_get(struct snd_kcontrol *kcontrol,
|
||||||
{
|
{
|
||||||
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
|
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
|
||||||
struct via_spec *spec = codec->spec;
|
struct via_spec *spec = codec->spec;
|
||||||
int index[] = { AUTO_PIN_MIC, AUTO_PIN_FRONT_MIC, AUTO_PIN_LINE };
|
const struct auto_pin_cfg *cfg = &spec->autocfg;
|
||||||
int on = 1;
|
int on = 1;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(index); i++) {
|
for (i = 0; i < cfg->num_inputs; i++) {
|
||||||
hda_nid_t nid = spec->autocfg.input_pins[index[i]];
|
hda_nid_t nid = cfg->inputs[i].pin;
|
||||||
if (nid) {
|
int ctl = snd_hda_codec_read(codec, nid, 0,
|
||||||
int ctl =
|
AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
|
||||||
snd_hda_codec_read(codec, nid, 0,
|
if (cfg->inputs[i].type >= AUTO_PIN_FRONT_LINE)
|
||||||
AC_VERB_GET_PIN_WIDGET_CONTROL,
|
continue;
|
||||||
0);
|
if (cfg->inputs[i].type == AUTO_PIN_FRONT_MIC &&
|
||||||
if (i == AUTO_PIN_FRONT_MIC
|
spec->hp_independent_mode && spec->codec_type != VT1718S)
|
||||||
&& spec->hp_independent_mode
|
continue; /* ignore FMic for independent HP */
|
||||||
&& spec->codec_type != VT1718S)
|
if ((ctl & AC_PINCTL_IN_EN) && !(ctl & AC_PINCTL_OUT_EN))
|
||||||
continue; /* ignore FMic for independent HP */
|
on = 0;
|
||||||
if (ctl & AC_PINCTL_IN_EN
|
|
||||||
&& !(ctl & AC_PINCTL_OUT_EN))
|
|
||||||
on = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
*ucontrol->value.integer.value = on;
|
*ucontrol->value.integer.value = on;
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1377,36 +1373,38 @@ static int via_smart51_put(struct snd_kcontrol *kcontrol,
|
||||||
{
|
{
|
||||||
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
|
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
|
||||||
struct via_spec *spec = codec->spec;
|
struct via_spec *spec = codec->spec;
|
||||||
|
const struct auto_pin_cfg *cfg = &spec->autocfg;
|
||||||
int out_in = *ucontrol->value.integer.value
|
int out_in = *ucontrol->value.integer.value
|
||||||
? AC_PINCTL_OUT_EN : AC_PINCTL_IN_EN;
|
? AC_PINCTL_OUT_EN : AC_PINCTL_IN_EN;
|
||||||
int index[] = { AUTO_PIN_MIC, AUTO_PIN_FRONT_MIC, AUTO_PIN_LINE };
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(index); i++) {
|
for (i = 0; i < cfg->num_inputs; i++) {
|
||||||
hda_nid_t nid = spec->autocfg.input_pins[index[i]];
|
hda_nid_t nid = cfg->inputs[i].pin;
|
||||||
if (i == AUTO_PIN_FRONT_MIC
|
unsigned int parm;
|
||||||
&& spec->hp_independent_mode
|
|
||||||
&& spec->codec_type != VT1718S)
|
if (cfg->inputs[i].type >= AUTO_PIN_FRONT_LINE)
|
||||||
|
continue;
|
||||||
|
if (cfg->inputs[i].type == AUTO_PIN_FRONT_MIC &&
|
||||||
|
spec->hp_independent_mode && spec->codec_type != VT1718S)
|
||||||
continue; /* don't retask FMic for independent HP */
|
continue; /* don't retask FMic for independent HP */
|
||||||
if (nid) {
|
|
||||||
unsigned int parm = snd_hda_codec_read(
|
parm = snd_hda_codec_read(codec, nid, 0,
|
||||||
codec, nid, 0,
|
AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
|
||||||
AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
|
parm &= ~(AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN);
|
||||||
parm &= ~(AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN);
|
parm |= out_in;
|
||||||
parm |= out_in;
|
snd_hda_codec_write(codec, nid, 0,
|
||||||
snd_hda_codec_write(codec, nid, 0,
|
AC_VERB_SET_PIN_WIDGET_CONTROL,
|
||||||
AC_VERB_SET_PIN_WIDGET_CONTROL,
|
parm);
|
||||||
parm);
|
if (out_in == AC_PINCTL_OUT_EN) {
|
||||||
if (out_in == AC_PINCTL_OUT_EN) {
|
mute_aa_path(codec, 1);
|
||||||
mute_aa_path(codec, 1);
|
notify_aa_path_ctls(codec);
|
||||||
notify_aa_path_ctls(codec);
|
}
|
||||||
}
|
if (spec->codec_type == VT1718S) {
|
||||||
if (spec->codec_type == VT1718S)
|
snd_hda_codec_amp_stereo(
|
||||||
snd_hda_codec_amp_stereo(
|
|
||||||
codec, nid, HDA_OUTPUT, 0, HDA_AMP_MUTE,
|
codec, nid, HDA_OUTPUT, 0, HDA_AMP_MUTE,
|
||||||
HDA_AMP_UNMUTE);
|
HDA_AMP_UNMUTE);
|
||||||
}
|
}
|
||||||
if (i == AUTO_PIN_FRONT_MIC) {
|
if (cfg->inputs[i].type == AUTO_PIN_FRONT_MIC) {
|
||||||
if (spec->codec_type == VT1708S
|
if (spec->codec_type == VT1708S
|
||||||
|| spec->codec_type == VT1716S) {
|
|| spec->codec_type == VT1716S) {
|
||||||
/* input = index 1 (AOW3) */
|
/* input = index 1 (AOW3) */
|
||||||
|
@ -1442,7 +1440,7 @@ static struct snd_kcontrol_new via_smart51_mixer[2] = {
|
||||||
static int via_smart51_build(struct via_spec *spec)
|
static int via_smart51_build(struct via_spec *spec)
|
||||||
{
|
{
|
||||||
struct snd_kcontrol_new *knew;
|
struct snd_kcontrol_new *knew;
|
||||||
int index[] = { AUTO_PIN_MIC, AUTO_PIN_FRONT_MIC, AUTO_PIN_LINE };
|
const struct auto_pin_cfg *cfg = &spec->autocfg;
|
||||||
hda_nid_t nid;
|
hda_nid_t nid;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
@ -1450,13 +1448,14 @@ static int via_smart51_build(struct via_spec *spec)
|
||||||
if (knew == NULL)
|
if (knew == NULL)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(index); i++) {
|
for (i = 0; i < cfg->num_inputs; i++) {
|
||||||
nid = spec->autocfg.input_pins[index[i]];
|
nid = cfg->inputs[i].pin;
|
||||||
if (nid) {
|
if (cfg->inputs[i].type < AUTO_PIN_FRONT_LINE) {
|
||||||
knew = via_clone_control(spec, &via_smart51_mixer[1]);
|
knew = via_clone_control(spec, &via_smart51_mixer[1]);
|
||||||
if (knew == NULL)
|
if (knew == NULL)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
knew->subdevice = nid;
|
knew->subdevice = nid;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2419,7 +2418,7 @@ static int vt_auto_create_analog_input_ctls(struct via_spec *spec,
|
||||||
hda_nid_t pin_idxs[], int num_idxs)
|
hda_nid_t pin_idxs[], int num_idxs)
|
||||||
{
|
{
|
||||||
struct hda_input_mux *imux = &spec->private_imux[0];
|
struct hda_input_mux *imux = &spec->private_imux[0];
|
||||||
int i, err, idx;
|
int i, err, idx, type, type_idx = 0;
|
||||||
|
|
||||||
/* for internal loopback recording select */
|
/* for internal loopback recording select */
|
||||||
for (idx = 0; idx < num_idxs; idx++) {
|
for (idx = 0; idx < num_idxs; idx++) {
|
||||||
|
@ -2431,20 +2430,23 @@ static int vt_auto_create_analog_input_ctls(struct via_spec *spec,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < AUTO_PIN_LAST; i++) {
|
for (i = 0; i < cfg->num_inputs; i++) {
|
||||||
if (!cfg->input_pins[i])
|
type = cfg->inputs[i].type;
|
||||||
continue;
|
|
||||||
|
|
||||||
for (idx = 0; idx < num_idxs; idx++)
|
for (idx = 0; idx < num_idxs; idx++)
|
||||||
if (pin_idxs[idx] == cfg->input_pins[i])
|
if (pin_idxs[idx] == cfg->inputs[i].pin)
|
||||||
break;
|
break;
|
||||||
if (idx >= num_idxs)
|
if (idx >= num_idxs)
|
||||||
continue;
|
continue;
|
||||||
err = via_new_analog_input(spec, auto_pin_cfg_labels[i],
|
if (i > 0 && type == cfg->inputs[i - 1].type)
|
||||||
idx, cap_nid);
|
type_idx++;
|
||||||
|
else
|
||||||
|
type_idx = 0;
|
||||||
|
err = via_new_analog_input(spec, auto_pin_cfg_labels[type],
|
||||||
|
type_idx, idx, cap_nid);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
return err;
|
||||||
imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
|
imux->items[imux->num_items].label =
|
||||||
|
snd_hda_get_input_pin_label(cfg, i);
|
||||||
imux->items[imux->num_items].index = idx;
|
imux->items[imux->num_items].index = idx;
|
||||||
imux->num_items++;
|
imux->num_items++;
|
||||||
}
|
}
|
||||||
|
@ -5513,7 +5515,7 @@ static int vt2002P_auto_create_analog_input_ctls(struct via_spec *spec,
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
return err;
|
||||||
/* build volume/mute control of loopback */
|
/* build volume/mute control of loopback */
|
||||||
err = via_new_analog_input(spec, "Stereo Mixer", 3, 0x21);
|
err = via_new_analog_input(spec, "Stereo Mixer", 0, 3, 0x21);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
|
@ -5836,7 +5838,7 @@ static int vt1812_auto_create_analog_input_ctls(struct via_spec *spec,
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
/* build volume/mute control of loopback */
|
/* build volume/mute control of loopback */
|
||||||
err = via_new_analog_input(spec, "Stereo Mixer", 5, 0x21);
|
err = via_new_analog_input(spec, "Stereo Mixer", 0, 5, 0x21);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue