ALSA: hda - Dynamic detection of dmics/dmuxes/smuxes in stac92hd71bxx
Detect the number of connected ports and number of smuxes dynamically, looking at pin configs, using new introduced functions stac92hd71bxx_connected_ports and stac92hd71bxx_connected_smuxes. Also use proper input mux configuration for 4port and 5port models. Signed-off-by: Herton Ronaldo Krzesinski <herton@mandriva.com.br> Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
Родитель
616f89e74c
Коммит
6df703aefc
|
@ -4944,7 +4944,16 @@ again:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct hda_input_mux stac92hd71bxx_dmux = {
|
static struct hda_input_mux stac92hd71bxx_dmux_nomixer = {
|
||||||
|
.num_items = 3,
|
||||||
|
.items = {
|
||||||
|
{ "Analog Inputs", 0x00 },
|
||||||
|
{ "Digital Mic 1", 0x02 },
|
||||||
|
{ "Digital Mic 2", 0x03 },
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct hda_input_mux stac92hd71bxx_dmux_amixer = {
|
||||||
.num_items = 4,
|
.num_items = 4,
|
||||||
.items = {
|
.items = {
|
||||||
{ "Analog Inputs", 0x00 },
|
{ "Analog Inputs", 0x00 },
|
||||||
|
@ -4954,11 +4963,57 @@ static struct hda_input_mux stac92hd71bxx_dmux = {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static int stac92hd71bxx_connected_ports(struct hda_codec *codec,
|
||||||
|
hda_nid_t *nids, int num_nids)
|
||||||
|
{
|
||||||
|
struct sigmatel_spec *spec = codec->spec;
|
||||||
|
int idx, num;
|
||||||
|
unsigned int def_conf;
|
||||||
|
|
||||||
|
for (num = 0; num < num_nids; num++) {
|
||||||
|
for (idx = 0; idx < spec->num_pins; idx++)
|
||||||
|
if (spec->pin_nids[idx] == nids[num])
|
||||||
|
break;
|
||||||
|
if (idx >= spec->num_pins)
|
||||||
|
break;
|
||||||
|
def_conf = get_defcfg_connect(spec->pin_configs[idx]);
|
||||||
|
if (def_conf == AC_JACK_PORT_NONE)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return num;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int stac92hd71bxx_connected_smuxes(struct hda_codec *codec,
|
||||||
|
hda_nid_t dig0pin)
|
||||||
|
{
|
||||||
|
struct sigmatel_spec *spec = codec->spec;
|
||||||
|
int idx;
|
||||||
|
|
||||||
|
for (idx = 0; idx < spec->num_pins; idx++)
|
||||||
|
if (spec->pin_nids[idx] == dig0pin)
|
||||||
|
break;
|
||||||
|
if ((idx + 2) >= spec->num_pins)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* dig1pin case */
|
||||||
|
if (get_defcfg_connect(spec->pin_configs[idx+1]) != AC_JACK_PORT_NONE)
|
||||||
|
return 2;
|
||||||
|
|
||||||
|
/* dig0pin + dig2pin case */
|
||||||
|
if (get_defcfg_connect(spec->pin_configs[idx+2]) != AC_JACK_PORT_NONE)
|
||||||
|
return 2;
|
||||||
|
if (get_defcfg_connect(spec->pin_configs[idx]) != AC_JACK_PORT_NONE)
|
||||||
|
return 1;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int patch_stac92hd71bxx(struct hda_codec *codec)
|
static int patch_stac92hd71bxx(struct hda_codec *codec)
|
||||||
{
|
{
|
||||||
struct sigmatel_spec *spec;
|
struct sigmatel_spec *spec;
|
||||||
struct hda_verb *unmute_init = stac92hd71bxx_unmute_core_init;
|
struct hda_verb *unmute_init = stac92hd71bxx_unmute_core_init;
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
unsigned int ndmic_nids = 0;
|
||||||
|
|
||||||
spec = kzalloc(sizeof(*spec), GFP_KERNEL);
|
spec = kzalloc(sizeof(*spec), GFP_KERNEL);
|
||||||
if (spec == NULL)
|
if (spec == NULL)
|
||||||
|
@ -4981,8 +5036,6 @@ static int patch_stac92hd71bxx(struct hda_codec *codec)
|
||||||
spec->pin_nids = stac92hd71bxx_pin_nids_6port;
|
spec->pin_nids = stac92hd71bxx_pin_nids_6port;
|
||||||
}
|
}
|
||||||
spec->num_pwrs = ARRAY_SIZE(stac92hd71bxx_pwr_nids);
|
spec->num_pwrs = ARRAY_SIZE(stac92hd71bxx_pwr_nids);
|
||||||
memcpy(&spec->private_dimux, &stac92hd71bxx_dmux,
|
|
||||||
sizeof(stac92hd71bxx_dmux));
|
|
||||||
spec->board_config = snd_hda_check_board_config(codec,
|
spec->board_config = snd_hda_check_board_config(codec,
|
||||||
STAC_92HD71BXX_MODELS,
|
STAC_92HD71BXX_MODELS,
|
||||||
stac92hd71bxx_models,
|
stac92hd71bxx_models,
|
||||||
|
@ -5007,16 +5060,32 @@ again:
|
||||||
spec->gpio_data = 0x01;
|
spec->gpio_data = 0x01;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
spec->dmic_nids = stac92hd71bxx_dmic_nids;
|
||||||
|
spec->dmux_nids = stac92hd71bxx_dmux_nids;
|
||||||
|
|
||||||
switch (codec->vendor_id) {
|
switch (codec->vendor_id) {
|
||||||
case 0x111d76b6: /* 4 Port without Analog Mixer */
|
case 0x111d76b6: /* 4 Port without Analog Mixer */
|
||||||
case 0x111d76b7:
|
case 0x111d76b7:
|
||||||
case 0x111d76b4: /* 6 Port without Analog Mixer */
|
case 0x111d76b4: /* 6 Port without Analog Mixer */
|
||||||
case 0x111d76b5:
|
case 0x111d76b5:
|
||||||
|
memcpy(&spec->private_dimux, &stac92hd71bxx_dmux_nomixer,
|
||||||
|
sizeof(stac92hd71bxx_dmux_nomixer));
|
||||||
spec->mixer = stac92hd71bxx_mixer;
|
spec->mixer = stac92hd71bxx_mixer;
|
||||||
spec->init = stac92hd71bxx_core_init;
|
spec->init = stac92hd71bxx_core_init;
|
||||||
codec->slave_dig_outs = stac92hd71bxx_slave_dig_outs;
|
codec->slave_dig_outs = stac92hd71bxx_slave_dig_outs;
|
||||||
|
spec->num_dmics = stac92hd71bxx_connected_ports(codec,
|
||||||
|
stac92hd71bxx_dmic_nids,
|
||||||
|
STAC92HD71BXX_NUM_DMICS);
|
||||||
|
if (spec->num_dmics) {
|
||||||
|
spec->num_dmuxes = ARRAY_SIZE(stac92hd71bxx_dmux_nids);
|
||||||
|
spec->dinput_mux = &spec->private_dimux;
|
||||||
|
ndmic_nids = ARRAY_SIZE(stac92hd71bxx_dmic_nids) - 1;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 0x111d7608: /* 5 Port with Analog Mixer */
|
case 0x111d7608: /* 5 Port with Analog Mixer */
|
||||||
|
memcpy(&spec->private_dimux, &stac92hd71bxx_dmux_amixer,
|
||||||
|
sizeof(stac92hd71bxx_dmux_amixer));
|
||||||
|
spec->private_dimux.num_items--;
|
||||||
switch (spec->board_config) {
|
switch (spec->board_config) {
|
||||||
case STAC_HP_M4:
|
case STAC_HP_M4:
|
||||||
/* Enable VREF power saving on GPIO1 detect */
|
/* Enable VREF power saving on GPIO1 detect */
|
||||||
|
@ -5046,6 +5115,12 @@ again:
|
||||||
unmute_init++;
|
unmute_init++;
|
||||||
stac_change_pin_config(codec, 0x0f, 0x40f000f0);
|
stac_change_pin_config(codec, 0x0f, 0x40f000f0);
|
||||||
stac_change_pin_config(codec, 0x19, 0x40f000f3);
|
stac_change_pin_config(codec, 0x19, 0x40f000f3);
|
||||||
|
stac92hd71bxx_dmic_nids[STAC92HD71BXX_NUM_DMICS - 1] = 0;
|
||||||
|
spec->num_dmics = stac92hd71bxx_connected_ports(codec,
|
||||||
|
stac92hd71bxx_dmic_nids,
|
||||||
|
STAC92HD71BXX_NUM_DMICS - 1);
|
||||||
|
spec->num_dmuxes = ARRAY_SIZE(stac92hd71bxx_dmux_nids);
|
||||||
|
ndmic_nids = ARRAY_SIZE(stac92hd71bxx_dmic_nids) - 2;
|
||||||
break;
|
break;
|
||||||
case 0x111d7603: /* 6 Port with Analog Mixer */
|
case 0x111d7603: /* 6 Port with Analog Mixer */
|
||||||
if ((codec->revision_id & 0xf) == 1)
|
if ((codec->revision_id & 0xf) == 1)
|
||||||
|
@ -5055,10 +5130,17 @@ again:
|
||||||
spec->num_pwrs = 0;
|
spec->num_pwrs = 0;
|
||||||
/* fallthru */
|
/* fallthru */
|
||||||
default:
|
default:
|
||||||
|
memcpy(&spec->private_dimux, &stac92hd71bxx_dmux_amixer,
|
||||||
|
sizeof(stac92hd71bxx_dmux_amixer));
|
||||||
spec->dinput_mux = &spec->private_dimux;
|
spec->dinput_mux = &spec->private_dimux;
|
||||||
spec->mixer = stac92hd71bxx_analog_mixer;
|
spec->mixer = stac92hd71bxx_analog_mixer;
|
||||||
spec->init = stac92hd71bxx_analog_core_init;
|
spec->init = stac92hd71bxx_analog_core_init;
|
||||||
codec->slave_dig_outs = stac92hd71bxx_slave_dig_outs;
|
codec->slave_dig_outs = stac92hd71bxx_slave_dig_outs;
|
||||||
|
spec->num_dmics = stac92hd71bxx_connected_ports(codec,
|
||||||
|
stac92hd71bxx_dmic_nids,
|
||||||
|
STAC92HD71BXX_NUM_DMICS);
|
||||||
|
spec->num_dmuxes = ARRAY_SIZE(stac92hd71bxx_dmux_nids);
|
||||||
|
ndmic_nids = ARRAY_SIZE(stac92hd71bxx_dmic_nids) - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (get_wcaps(codec, 0xa) & AC_WCAP_IN_AMP)
|
if (get_wcaps(codec, 0xa) & AC_WCAP_IN_AMP)
|
||||||
|
@ -5071,13 +5153,12 @@ again:
|
||||||
spec->digbeep_nid = 0x26;
|
spec->digbeep_nid = 0x26;
|
||||||
spec->mux_nids = stac92hd71bxx_mux_nids;
|
spec->mux_nids = stac92hd71bxx_mux_nids;
|
||||||
spec->adc_nids = stac92hd71bxx_adc_nids;
|
spec->adc_nids = stac92hd71bxx_adc_nids;
|
||||||
spec->dmic_nids = stac92hd71bxx_dmic_nids;
|
|
||||||
spec->dmux_nids = stac92hd71bxx_dmux_nids;
|
|
||||||
spec->smux_nids = stac92hd71bxx_smux_nids;
|
spec->smux_nids = stac92hd71bxx_smux_nids;
|
||||||
spec->pwr_nids = stac92hd71bxx_pwr_nids;
|
spec->pwr_nids = stac92hd71bxx_pwr_nids;
|
||||||
|
|
||||||
spec->num_muxes = ARRAY_SIZE(stac92hd71bxx_mux_nids);
|
spec->num_muxes = ARRAY_SIZE(stac92hd71bxx_mux_nids);
|
||||||
spec->num_adcs = ARRAY_SIZE(stac92hd71bxx_adc_nids);
|
spec->num_adcs = ARRAY_SIZE(stac92hd71bxx_adc_nids);
|
||||||
|
spec->num_smuxes = stac92hd71bxx_connected_smuxes(codec, 0x1e);
|
||||||
|
|
||||||
switch (spec->board_config) {
|
switch (spec->board_config) {
|
||||||
case STAC_HP_M4:
|
case STAC_HP_M4:
|
||||||
|
@ -5097,17 +5178,11 @@ again:
|
||||||
spec->num_smuxes = 0;
|
spec->num_smuxes = 0;
|
||||||
spec->num_dmuxes = 0;
|
spec->num_dmuxes = 0;
|
||||||
break;
|
break;
|
||||||
default:
|
|
||||||
spec->num_dmics = STAC92HD71BXX_NUM_DMICS;
|
|
||||||
spec->num_smuxes = ARRAY_SIZE(stac92hd71bxx_smux_nids);
|
|
||||||
spec->num_dmuxes = ARRAY_SIZE(stac92hd71bxx_dmux_nids);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
spec->multiout.dac_nids = spec->dac_nids;
|
spec->multiout.dac_nids = spec->dac_nids;
|
||||||
if (spec->dinput_mux)
|
if (spec->dinput_mux)
|
||||||
spec->private_dimux.num_items +=
|
spec->private_dimux.num_items += spec->num_dmics - ndmic_nids;
|
||||||
spec->num_dmics -
|
|
||||||
(ARRAY_SIZE(stac92hd71bxx_dmic_nids) - 1);
|
|
||||||
|
|
||||||
err = stac92xx_parse_auto_config(codec, 0x21, 0x23);
|
err = stac92xx_parse_auto_config(codec, 0x21, 0x23);
|
||||||
if (!err) {
|
if (!err) {
|
||||||
|
|
Загрузка…
Ссылка в новой задаче