diff options
author | Herton Ronaldo Krzesinski <herton@mandriva.com.br> | 2009-02-04 11:34:22 -0500 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2009-02-05 01:54:34 -0500 |
commit | 6df703aefc81252447c69d24d2863007de2338e9 (patch) | |
tree | 6388730e38bcebba158c906a4abb10efa47b0964 | |
parent | 616f89e74cd954e04ae4f8bad6a3dc8730a4a47a (diff) |
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>
-rw-r--r-- | sound/pci/hda/patch_sigmatel.c | 99 |
1 files changed, 87 insertions, 12 deletions
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 58c9ff9d27f..c36c1c0f957 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c | |||
@@ -4944,7 +4944,16 @@ again: | |||
4944 | return 0; | 4944 | return 0; |
4945 | } | 4945 | } |
4946 | 4946 | ||
4947 | static struct hda_input_mux stac92hd71bxx_dmux = { | 4947 | static struct hda_input_mux stac92hd71bxx_dmux_nomixer = { |
4948 | .num_items = 3, | ||
4949 | .items = { | ||
4950 | { "Analog Inputs", 0x00 }, | ||
4951 | { "Digital Mic 1", 0x02 }, | ||
4952 | { "Digital Mic 2", 0x03 }, | ||
4953 | } | ||
4954 | }; | ||
4955 | |||
4956 | static struct hda_input_mux stac92hd71bxx_dmux_amixer = { | ||
4948 | .num_items = 4, | 4957 | .num_items = 4, |
4949 | .items = { | 4958 | .items = { |
4950 | { "Analog Inputs", 0x00 }, | 4959 | { "Analog Inputs", 0x00 }, |
@@ -4954,11 +4963,57 @@ static struct hda_input_mux stac92hd71bxx_dmux = { | |||
4954 | } | 4963 | } |
4955 | }; | 4964 | }; |
4956 | 4965 | ||
4966 | static int stac92hd71bxx_connected_ports(struct hda_codec *codec, | ||
4967 | hda_nid_t *nids, int num_nids) | ||
4968 | { | ||
4969 | struct sigmatel_spec *spec = codec->spec; | ||
4970 | int idx, num; | ||
4971 | unsigned int def_conf; | ||
4972 | |||
4973 | for (num = 0; num < num_nids; num++) { | ||
4974 | for (idx = 0; idx < spec->num_pins; idx++) | ||
4975 | if (spec->pin_nids[idx] == nids[num]) | ||
4976 | break; | ||
4977 | if (idx >= spec->num_pins) | ||
4978 | break; | ||
4979 | def_conf = get_defcfg_connect(spec->pin_configs[idx]); | ||
4980 | if (def_conf == AC_JACK_PORT_NONE) | ||
4981 | break; | ||
4982 | } | ||
4983 | return num; | ||
4984 | } | ||
4985 | |||
4986 | static int stac92hd71bxx_connected_smuxes(struct hda_codec *codec, | ||
4987 | hda_nid_t dig0pin) | ||
4988 | { | ||
4989 | struct sigmatel_spec *spec = codec->spec; | ||
4990 | int idx; | ||
4991 | |||
4992 | for (idx = 0; idx < spec->num_pins; idx++) | ||
4993 | if (spec->pin_nids[idx] == dig0pin) | ||
4994 | break; | ||
4995 | if ((idx + 2) >= spec->num_pins) | ||
4996 | return 0; | ||
4997 | |||
4998 | /* dig1pin case */ | ||
4999 | if (get_defcfg_connect(spec->pin_configs[idx+1]) != AC_JACK_PORT_NONE) | ||
5000 | return 2; | ||
5001 | |||
5002 | /* dig0pin + dig2pin case */ | ||
5003 | if (get_defcfg_connect(spec->pin_configs[idx+2]) != AC_JACK_PORT_NONE) | ||
5004 | return 2; | ||
5005 | if (get_defcfg_connect(spec->pin_configs[idx]) != AC_JACK_PORT_NONE) | ||
5006 | return 1; | ||
5007 | else | ||
5008 | return 0; | ||
5009 | } | ||
5010 | |||
4957 | static int patch_stac92hd71bxx(struct hda_codec *codec) | 5011 | static int patch_stac92hd71bxx(struct hda_codec *codec) |
4958 | { | 5012 | { |
4959 | struct sigmatel_spec *spec; | 5013 | struct sigmatel_spec *spec; |
4960 | struct hda_verb *unmute_init = stac92hd71bxx_unmute_core_init; | 5014 | struct hda_verb *unmute_init = stac92hd71bxx_unmute_core_init; |
4961 | int err = 0; | 5015 | int err = 0; |
5016 | unsigned int ndmic_nids = 0; | ||
4962 | 5017 | ||
4963 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | 5018 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); |
4964 | if (spec == NULL) | 5019 | if (spec == NULL) |
@@ -4981,8 +5036,6 @@ static int patch_stac92hd71bxx(struct hda_codec *codec) | |||
4981 | spec->pin_nids = stac92hd71bxx_pin_nids_6port; | 5036 | spec->pin_nids = stac92hd71bxx_pin_nids_6port; |
4982 | } | 5037 | } |
4983 | spec->num_pwrs = ARRAY_SIZE(stac92hd71bxx_pwr_nids); | 5038 | spec->num_pwrs = ARRAY_SIZE(stac92hd71bxx_pwr_nids); |
4984 | memcpy(&spec->private_dimux, &stac92hd71bxx_dmux, | ||
4985 | sizeof(stac92hd71bxx_dmux)); | ||
4986 | spec->board_config = snd_hda_check_board_config(codec, | 5039 | spec->board_config = snd_hda_check_board_config(codec, |
4987 | STAC_92HD71BXX_MODELS, | 5040 | STAC_92HD71BXX_MODELS, |
4988 | stac92hd71bxx_models, | 5041 | stac92hd71bxx_models, |
@@ -5007,16 +5060,32 @@ again: | |||
5007 | spec->gpio_data = 0x01; | 5060 | spec->gpio_data = 0x01; |
5008 | } | 5061 | } |
5009 | 5062 | ||
5063 | spec->dmic_nids = stac92hd71bxx_dmic_nids; | ||
5064 | spec->dmux_nids = stac92hd71bxx_dmux_nids; | ||
5065 | |||
5010 | switch (codec->vendor_id) { | 5066 | switch (codec->vendor_id) { |
5011 | case 0x111d76b6: /* 4 Port without Analog Mixer */ | 5067 | case 0x111d76b6: /* 4 Port without Analog Mixer */ |
5012 | case 0x111d76b7: | 5068 | case 0x111d76b7: |
5013 | case 0x111d76b4: /* 6 Port without Analog Mixer */ | 5069 | case 0x111d76b4: /* 6 Port without Analog Mixer */ |
5014 | case 0x111d76b5: | 5070 | case 0x111d76b5: |
5071 | memcpy(&spec->private_dimux, &stac92hd71bxx_dmux_nomixer, | ||
5072 | sizeof(stac92hd71bxx_dmux_nomixer)); | ||
5015 | spec->mixer = stac92hd71bxx_mixer; | 5073 | spec->mixer = stac92hd71bxx_mixer; |
5016 | spec->init = stac92hd71bxx_core_init; | 5074 | spec->init = stac92hd71bxx_core_init; |
5017 | codec->slave_dig_outs = stac92hd71bxx_slave_dig_outs; | 5075 | codec->slave_dig_outs = stac92hd71bxx_slave_dig_outs; |
5076 | spec->num_dmics = stac92hd71bxx_connected_ports(codec, | ||
5077 | stac92hd71bxx_dmic_nids, | ||
5078 | STAC92HD71BXX_NUM_DMICS); | ||
5079 | if (spec->num_dmics) { | ||
5080 | spec->num_dmuxes = ARRAY_SIZE(stac92hd71bxx_dmux_nids); | ||
5081 | spec->dinput_mux = &spec->private_dimux; | ||
5082 | ndmic_nids = ARRAY_SIZE(stac92hd71bxx_dmic_nids) - 1; | ||
5083 | } | ||
5018 | break; | 5084 | break; |
5019 | case 0x111d7608: /* 5 Port with Analog Mixer */ | 5085 | case 0x111d7608: /* 5 Port with Analog Mixer */ |
5086 | memcpy(&spec->private_dimux, &stac92hd71bxx_dmux_amixer, | ||
5087 | sizeof(stac92hd71bxx_dmux_amixer)); | ||
5088 | spec->private_dimux.num_items--; | ||
5020 | switch (spec->board_config) { | 5089 | switch (spec->board_config) { |
5021 | case STAC_HP_M4: | 5090 | case STAC_HP_M4: |
5022 | /* Enable VREF power saving on GPIO1 detect */ | 5091 | /* Enable VREF power saving on GPIO1 detect */ |
@@ -5046,6 +5115,12 @@ again: | |||
5046 | unmute_init++; | 5115 | unmute_init++; |
5047 | stac_change_pin_config(codec, 0x0f, 0x40f000f0); | 5116 | stac_change_pin_config(codec, 0x0f, 0x40f000f0); |
5048 | stac_change_pin_config(codec, 0x19, 0x40f000f3); | 5117 | stac_change_pin_config(codec, 0x19, 0x40f000f3); |
5118 | stac92hd71bxx_dmic_nids[STAC92HD71BXX_NUM_DMICS - 1] = 0; | ||
5119 | spec->num_dmics = stac92hd71bxx_connected_ports(codec, | ||
5120 | stac92hd71bxx_dmic_nids, | ||
5121 | STAC92HD71BXX_NUM_DMICS - 1); | ||
5122 | spec->num_dmuxes = ARRAY_SIZE(stac92hd71bxx_dmux_nids); | ||
5123 | ndmic_nids = ARRAY_SIZE(stac92hd71bxx_dmic_nids) - 2; | ||
5049 | break; | 5124 | break; |
5050 | case 0x111d7603: /* 6 Port with Analog Mixer */ | 5125 | case 0x111d7603: /* 6 Port with Analog Mixer */ |
5051 | if ((codec->revision_id & 0xf) == 1) | 5126 | if ((codec->revision_id & 0xf) == 1) |
@@ -5055,10 +5130,17 @@ again: | |||
5055 | spec->num_pwrs = 0; | 5130 | spec->num_pwrs = 0; |
5056 | /* fallthru */ | 5131 | /* fallthru */ |
5057 | default: | 5132 | default: |
5133 | memcpy(&spec->private_dimux, &stac92hd71bxx_dmux_amixer, | ||
5134 | sizeof(stac92hd71bxx_dmux_amixer)); | ||
5058 | spec->dinput_mux = &spec->private_dimux; | 5135 | spec->dinput_mux = &spec->private_dimux; |
5059 | spec->mixer = stac92hd71bxx_analog_mixer; | 5136 | spec->mixer = stac92hd71bxx_analog_mixer; |
5060 | spec->init = stac92hd71bxx_analog_core_init; | 5137 | spec->init = stac92hd71bxx_analog_core_init; |
5061 | codec->slave_dig_outs = stac92hd71bxx_slave_dig_outs; | 5138 | codec->slave_dig_outs = stac92hd71bxx_slave_dig_outs; |
5139 | spec->num_dmics = stac92hd71bxx_connected_ports(codec, | ||
5140 | stac92hd71bxx_dmic_nids, | ||
5141 | STAC92HD71BXX_NUM_DMICS); | ||
5142 | spec->num_dmuxes = ARRAY_SIZE(stac92hd71bxx_dmux_nids); | ||
5143 | ndmic_nids = ARRAY_SIZE(stac92hd71bxx_dmic_nids) - 1; | ||
5062 | } | 5144 | } |
5063 | 5145 | ||
5064 | if (get_wcaps(codec, 0xa) & AC_WCAP_IN_AMP) | 5146 | if (get_wcaps(codec, 0xa) & AC_WCAP_IN_AMP) |
@@ -5071,13 +5153,12 @@ again: | |||
5071 | spec->digbeep_nid = 0x26; | 5153 | spec->digbeep_nid = 0x26; |
5072 | spec->mux_nids = stac92hd71bxx_mux_nids; | 5154 | spec->mux_nids = stac92hd71bxx_mux_nids; |
5073 | spec->adc_nids = stac92hd71bxx_adc_nids; | 5155 | spec->adc_nids = stac92hd71bxx_adc_nids; |
5074 | spec->dmic_nids = stac92hd71bxx_dmic_nids; | ||
5075 | spec->dmux_nids = stac92hd71bxx_dmux_nids; | ||
5076 | spec->smux_nids = stac92hd71bxx_smux_nids; | 5156 | spec->smux_nids = stac92hd71bxx_smux_nids; |
5077 | spec->pwr_nids = stac92hd71bxx_pwr_nids; | 5157 | spec->pwr_nids = stac92hd71bxx_pwr_nids; |
5078 | 5158 | ||
5079 | spec->num_muxes = ARRAY_SIZE(stac92hd71bxx_mux_nids); | 5159 | spec->num_muxes = ARRAY_SIZE(stac92hd71bxx_mux_nids); |
5080 | spec->num_adcs = ARRAY_SIZE(stac92hd71bxx_adc_nids); | 5160 | spec->num_adcs = ARRAY_SIZE(stac92hd71bxx_adc_nids); |
5161 | spec->num_smuxes = stac92hd71bxx_connected_smuxes(codec, 0x1e); | ||
5081 | 5162 | ||
5082 | switch (spec->board_config) { | 5163 | switch (spec->board_config) { |
5083 | case STAC_HP_M4: | 5164 | case STAC_HP_M4: |
@@ -5097,17 +5178,11 @@ again: | |||
5097 | spec->num_smuxes = 0; | 5178 | spec->num_smuxes = 0; |
5098 | spec->num_dmuxes = 0; | 5179 | spec->num_dmuxes = 0; |
5099 | break; | 5180 | break; |
5100 | default: | ||
5101 | spec->num_dmics = STAC92HD71BXX_NUM_DMICS; | ||
5102 | spec->num_smuxes = ARRAY_SIZE(stac92hd71bxx_smux_nids); | ||
5103 | spec->num_dmuxes = ARRAY_SIZE(stac92hd71bxx_dmux_nids); | ||
5104 | }; | 5181 | }; |
5105 | 5182 | ||
5106 | spec->multiout.dac_nids = spec->dac_nids; | 5183 | spec->multiout.dac_nids = spec->dac_nids; |
5107 | if (spec->dinput_mux) | 5184 | if (spec->dinput_mux) |
5108 | spec->private_dimux.num_items += | 5185 | spec->private_dimux.num_items += spec->num_dmics - ndmic_nids; |
5109 | spec->num_dmics - | ||
5110 | (ARRAY_SIZE(stac92hd71bxx_dmic_nids) - 1); | ||
5111 | 5186 | ||
5112 | err = stac92xx_parse_auto_config(codec, 0x21, 0x23); | 5187 | err = stac92xx_parse_auto_config(codec, 0x21, 0x23); |
5113 | if (!err) { | 5188 | if (!err) { |