aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHerton Ronaldo Krzesinski <herton@mandriva.com.br>2009-02-04 11:34:22 -0500
committerTakashi Iwai <tiwai@suse.de>2009-02-05 01:54:34 -0500
commit6df703aefc81252447c69d24d2863007de2338e9 (patch)
tree6388730e38bcebba158c906a4abb10efa47b0964
parent616f89e74cd954e04ae4f8bad6a3dc8730a4a47a (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.c99
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
4947static struct hda_input_mux stac92hd71bxx_dmux = { 4947static 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
4956static 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
4966static 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
4986static 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
4957static int patch_stac92hd71bxx(struct hda_codec *codec) 5011static 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) {