aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2011-12-07 11:33:09 -0500
committerTakashi Iwai <tiwai@suse.de>2011-12-07 11:33:09 -0500
commitffe7e4063987678c00589717d7871f837c6e7300 (patch)
tree1aeee46780d9f7601909a4baa5f0c766c555e2e2 /sound/pci
parent9eb6e9b16f86ef94f05427bd7fc84d521aa57169 (diff)
parent0a34b42b6245ccc710be6759cded5b7fe41ea1f9 (diff)
Merge branch 'fix/hda' into topic/hda
Conflicts: sound/pci/hda/patch_realtek.c
Diffstat (limited to 'sound/pci')
-rw-r--r--sound/pci/hda/patch_realtek.c65
-rw-r--r--sound/pci/hda/patch_sigmatel.c47
-rw-r--r--sound/pci/sis7019.c64
3 files changed, 127 insertions, 49 deletions
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 63186d7d18a9..8a74c1e8eedb 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -300,6 +300,8 @@ static int alc_mux_select(struct hda_codec *codec, unsigned int adc_idx,
300 imux = &spec->input_mux[mux_idx]; 300 imux = &spec->input_mux[mux_idx];
301 if (!imux->num_items && mux_idx > 0) 301 if (!imux->num_items && mux_idx > 0)
302 imux = &spec->input_mux[0]; 302 imux = &spec->input_mux[0];
303 if (!imux->num_items)
304 return 0;
303 305
304 if (idx >= imux->num_items) 306 if (idx >= imux->num_items)
305 idx = imux->num_items - 1; 307 idx = imux->num_items - 1;
@@ -2663,6 +2665,8 @@ static const char *alc_get_line_out_pfx(struct alc_spec *spec, int ch,
2663 case AUTO_PIN_SPEAKER_OUT: 2665 case AUTO_PIN_SPEAKER_OUT:
2664 if (cfg->line_outs == 1) 2666 if (cfg->line_outs == 1)
2665 return "Speaker"; 2667 return "Speaker";
2668 if (cfg->line_outs == 2)
2669 return ch ? "Bass Speaker" : "Speaker";
2666 break; 2670 break;
2667 case AUTO_PIN_HP_OUT: 2671 case AUTO_PIN_HP_OUT:
2668 /* for multi-io case, only the primary out */ 2672 /* for multi-io case, only the primary out */
@@ -2974,7 +2978,7 @@ static hda_nid_t alc_auto_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
2974 if (!nid) 2978 if (!nid)
2975 continue; 2979 continue;
2976 if (found_in_nid_list(nid, spec->multiout.dac_nids, 2980 if (found_in_nid_list(nid, spec->multiout.dac_nids,
2977 spec->multiout.num_dacs)) 2981 ARRAY_SIZE(spec->private_dac_nids)))
2978 continue; 2982 continue;
2979 if (found_in_nid_list(nid, spec->multiout.hp_out_nid, 2983 if (found_in_nid_list(nid, spec->multiout.hp_out_nid,
2980 ARRAY_SIZE(spec->multiout.hp_out_nid))) 2984 ARRAY_SIZE(spec->multiout.hp_out_nid)))
@@ -3012,6 +3016,7 @@ static hda_nid_t get_dac_if_single(struct hda_codec *codec, hda_nid_t pin)
3012 return 0; 3016 return 0;
3013} 3017}
3014 3018
3019/* return 0 if no possible DAC is found, 1 if one or more found */
3015static int alc_auto_fill_extra_dacs(struct hda_codec *codec, int num_outs, 3020static int alc_auto_fill_extra_dacs(struct hda_codec *codec, int num_outs,
3016 const hda_nid_t *pins, hda_nid_t *dacs) 3021 const hda_nid_t *pins, hda_nid_t *dacs)
3017{ 3022{
@@ -3029,7 +3034,7 @@ static int alc_auto_fill_extra_dacs(struct hda_codec *codec, int num_outs,
3029 if (!dacs[i]) 3034 if (!dacs[i])
3030 dacs[i] = alc_auto_look_for_dac(codec, pins[i]); 3035 dacs[i] = alc_auto_look_for_dac(codec, pins[i]);
3031 } 3036 }
3032 return 0; 3037 return 1;
3033} 3038}
3034 3039
3035static int alc_auto_fill_multi_ios(struct hda_codec *codec, 3040static int alc_auto_fill_multi_ios(struct hda_codec *codec,
@@ -3039,7 +3044,7 @@ static int alc_auto_fill_multi_ios(struct hda_codec *codec,
3039static int alc_auto_fill_dac_nids(struct hda_codec *codec) 3044static int alc_auto_fill_dac_nids(struct hda_codec *codec)
3040{ 3045{
3041 struct alc_spec *spec = codec->spec; 3046 struct alc_spec *spec = codec->spec;
3042 const struct auto_pin_cfg *cfg = &spec->autocfg; 3047 struct auto_pin_cfg *cfg = &spec->autocfg;
3043 unsigned int location, defcfg; 3048 unsigned int location, defcfg;
3044 int num_pins; 3049 int num_pins;
3045 bool redone = false; 3050 bool redone = false;
@@ -3052,6 +3057,7 @@ static int alc_auto_fill_dac_nids(struct hda_codec *codec)
3052 spec->multiout.extra_out_nid[0] = 0; 3057 spec->multiout.extra_out_nid[0] = 0;
3053 memset(spec->private_dac_nids, 0, sizeof(spec->private_dac_nids)); 3058 memset(spec->private_dac_nids, 0, sizeof(spec->private_dac_nids));
3054 spec->multiout.dac_nids = spec->private_dac_nids; 3059 spec->multiout.dac_nids = spec->private_dac_nids;
3060 spec->multi_ios = 0;
3055 3061
3056 /* fill hard-wired DACs first */ 3062 /* fill hard-wired DACs first */
3057 if (!redone) { 3063 if (!redone) {
@@ -3085,10 +3091,12 @@ static int alc_auto_fill_dac_nids(struct hda_codec *codec)
3085 for (i = 0; i < cfg->line_outs; i++) { 3091 for (i = 0; i < cfg->line_outs; i++) {
3086 if (spec->private_dac_nids[i]) 3092 if (spec->private_dac_nids[i])
3087 spec->multiout.num_dacs++; 3093 spec->multiout.num_dacs++;
3088 else 3094 else {
3089 memmove(spec->private_dac_nids + i, 3095 memmove(spec->private_dac_nids + i,
3090 spec->private_dac_nids + i + 1, 3096 spec->private_dac_nids + i + 1,
3091 sizeof(hda_nid_t) * (cfg->line_outs - i - 1)); 3097 sizeof(hda_nid_t) * (cfg->line_outs - i - 1));
3098 spec->private_dac_nids[cfg->line_outs - 1] = 0;
3099 }
3092 } 3100 }
3093 3101
3094 if (cfg->line_outs == 1 && cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) { 3102 if (cfg->line_outs == 1 && cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
@@ -3107,9 +3115,28 @@ static int alc_auto_fill_dac_nids(struct hda_codec *codec)
3107 if (cfg->line_out_type != AUTO_PIN_HP_OUT) 3115 if (cfg->line_out_type != AUTO_PIN_HP_OUT)
3108 alc_auto_fill_extra_dacs(codec, cfg->hp_outs, cfg->hp_pins, 3116 alc_auto_fill_extra_dacs(codec, cfg->hp_outs, cfg->hp_pins,
3109 spec->multiout.hp_out_nid); 3117 spec->multiout.hp_out_nid);
3110 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) 3118 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
3111 alc_auto_fill_extra_dacs(codec, cfg->speaker_outs, cfg->speaker_pins, 3119 int err = alc_auto_fill_extra_dacs(codec, cfg->speaker_outs,
3112 spec->multiout.extra_out_nid); 3120 cfg->speaker_pins,
3121 spec->multiout.extra_out_nid);
3122 /* if no speaker volume is assigned, try again as the primary
3123 * output
3124 */
3125 if (!err && cfg->speaker_outs > 0 &&
3126 cfg->line_out_type == AUTO_PIN_HP_OUT) {
3127 cfg->hp_outs = cfg->line_outs;
3128 memcpy(cfg->hp_pins, cfg->line_out_pins,
3129 sizeof(cfg->hp_pins));
3130 cfg->line_outs = cfg->speaker_outs;
3131 memcpy(cfg->line_out_pins, cfg->speaker_pins,
3132 sizeof(cfg->speaker_pins));
3133 cfg->speaker_outs = 0;
3134 memset(cfg->speaker_pins, 0, sizeof(cfg->speaker_pins));
3135 cfg->line_out_type = AUTO_PIN_SPEAKER_OUT;
3136 redone = false;
3137 goto again;
3138 }
3139 }
3113 3140
3114 if (!spec->multi_ios && 3141 if (!spec->multi_ios &&
3115 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT && 3142 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT &&
@@ -3287,7 +3314,8 @@ static int alc_auto_create_multi_out_ctls(struct hda_codec *codec,
3287} 3314}
3288 3315
3289static int alc_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin, 3316static int alc_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
3290 hda_nid_t dac, const char *pfx) 3317 hda_nid_t dac, const char *pfx,
3318 int cidx)
3291{ 3319{
3292 struct alc_spec *spec = codec->spec; 3320 struct alc_spec *spec = codec->spec;
3293 hda_nid_t sw, vol; 3321 hda_nid_t sw, vol;
@@ -3303,15 +3331,15 @@ static int alc_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
3303 if (is_ctl_used(spec->sw_ctls, val)) 3331 if (is_ctl_used(spec->sw_ctls, val))
3304 return 0; /* already created */ 3332 return 0; /* already created */
3305 mark_ctl_usage(spec->sw_ctls, val); 3333 mark_ctl_usage(spec->sw_ctls, val);
3306 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, val); 3334 return __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, cidx, val);
3307 } 3335 }
3308 3336
3309 sw = alc_look_for_out_mute_nid(codec, pin, dac); 3337 sw = alc_look_for_out_mute_nid(codec, pin, dac);
3310 vol = alc_look_for_out_vol_nid(codec, pin, dac); 3338 vol = alc_look_for_out_vol_nid(codec, pin, dac);
3311 err = alc_auto_add_stereo_vol(codec, pfx, 0, vol); 3339 err = alc_auto_add_stereo_vol(codec, pfx, cidx, vol);
3312 if (err < 0) 3340 if (err < 0)
3313 return err; 3341 return err;
3314 err = alc_auto_add_stereo_sw(codec, pfx, 0, sw); 3342 err = alc_auto_add_stereo_sw(codec, pfx, cidx, sw);
3315 if (err < 0) 3343 if (err < 0)
3316 return err; 3344 return err;
3317 return 0; 3345 return 0;
@@ -3352,16 +3380,21 @@ static int alc_auto_create_extra_outs(struct hda_codec *codec, int num_pins,
3352 hda_nid_t dac = *dacs; 3380 hda_nid_t dac = *dacs;
3353 if (!dac) 3381 if (!dac)
3354 dac = spec->multiout.dac_nids[0]; 3382 dac = spec->multiout.dac_nids[0];
3355 return alc_auto_create_extra_out(codec, *pins, dac, pfx); 3383 return alc_auto_create_extra_out(codec, *pins, dac, pfx, 0);
3356 } 3384 }
3357 3385
3358 if (dacs[num_pins - 1]) { 3386 if (dacs[num_pins - 1]) {
3359 /* OK, we have a multi-output system with individual volumes */ 3387 /* OK, we have a multi-output system with individual volumes */
3360 for (i = 0; i < num_pins; i++) { 3388 for (i = 0; i < num_pins; i++) {
3361 snprintf(name, sizeof(name), "%s %s", 3389 if (num_pins >= 3) {
3362 pfx, channel_name[i]); 3390 snprintf(name, sizeof(name), "%s %s",
3363 err = alc_auto_create_extra_out(codec, pins[i], dacs[i], 3391 pfx, channel_name[i]);
3364 name); 3392 err = alc_auto_create_extra_out(codec, pins[i], dacs[i],
3393 name, 0);
3394 } else {
3395 err = alc_auto_create_extra_out(codec, pins[i], dacs[i],
3396 pfx, i);
3397 }
3365 if (err < 0) 3398 if (err < 0)
3366 return err; 3399 return err;
3367 } 3400 }
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index d8d2f9dccd9b..eeb25d529e30 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -215,6 +215,7 @@ struct sigmatel_spec {
215 unsigned int gpio_mute; 215 unsigned int gpio_mute;
216 unsigned int gpio_led; 216 unsigned int gpio_led;
217 unsigned int gpio_led_polarity; 217 unsigned int gpio_led_polarity;
218 unsigned int vref_mute_led_nid; /* pin NID for mute-LED vref control */
218 unsigned int vref_led; 219 unsigned int vref_led;
219 220
220 /* stream */ 221 /* stream */
@@ -4318,12 +4319,10 @@ static void stac_store_hints(struct hda_codec *codec)
4318 spec->eapd_switch = val; 4319 spec->eapd_switch = val;
4319 get_int_hint(codec, "gpio_led_polarity", &spec->gpio_led_polarity); 4320 get_int_hint(codec, "gpio_led_polarity", &spec->gpio_led_polarity);
4320 if (get_int_hint(codec, "gpio_led", &spec->gpio_led)) { 4321 if (get_int_hint(codec, "gpio_led", &spec->gpio_led)) {
4321 if (spec->gpio_led <= 8) { 4322 spec->gpio_mask |= spec->gpio_led;
4322 spec->gpio_mask |= spec->gpio_led; 4323 spec->gpio_dir |= spec->gpio_led;
4323 spec->gpio_dir |= spec->gpio_led; 4324 if (spec->gpio_led_polarity)
4324 if (spec->gpio_led_polarity) 4325 spec->gpio_data |= spec->gpio_led;
4325 spec->gpio_data |= spec->gpio_led;
4326 }
4327 } 4326 }
4328} 4327}
4329 4328
@@ -4443,7 +4442,7 @@ static int stac92xx_init(struct hda_codec *codec)
4443 /* power on when no jack detection is available */ 4442 /* power on when no jack detection is available */
4444 /* or when the VREF is used for controlling LED */ 4443 /* or when the VREF is used for controlling LED */
4445 if (!spec->hp_detect || 4444 if (!spec->hp_detect ||
4446 (spec->gpio_led > 8 && spec->gpio_led == nid)) { 4445 spec->vref_mute_led_nid == nid) {
4447 stac_toggle_power_map(codec, nid, 1); 4446 stac_toggle_power_map(codec, nid, 1);
4448 continue; 4447 continue;
4449 } 4448 }
@@ -4915,8 +4914,14 @@ static int find_mute_led_gpio(struct hda_codec *codec, int default_polarity)
4915 if (sscanf(dev->name, "HP_Mute_LED_%d_%x", 4914 if (sscanf(dev->name, "HP_Mute_LED_%d_%x",
4916 &spec->gpio_led_polarity, 4915 &spec->gpio_led_polarity,
4917 &spec->gpio_led) == 2) { 4916 &spec->gpio_led) == 2) {
4918 if (spec->gpio_led < 4) 4917 unsigned int max_gpio;
4918 max_gpio = snd_hda_param_read(codec, codec->afg,
4919 AC_PAR_GPIO_CAP);
4920 max_gpio &= AC_GPIO_IO_COUNT;
4921 if (spec->gpio_led < max_gpio)
4919 spec->gpio_led = 1 << spec->gpio_led; 4922 spec->gpio_led = 1 << spec->gpio_led;
4923 else
4924 spec->vref_mute_led_nid = spec->gpio_led;
4920 return 1; 4925 return 1;
4921 } 4926 }
4922 if (sscanf(dev->name, "HP_Mute_LED_%d", 4927 if (sscanf(dev->name, "HP_Mute_LED_%d",
@@ -5045,15 +5050,12 @@ static int stac92xx_pre_resume(struct hda_codec *codec)
5045 struct sigmatel_spec *spec = codec->spec; 5050 struct sigmatel_spec *spec = codec->spec;
5046 5051
5047 /* sync mute LED */ 5052 /* sync mute LED */
5048 if (spec->gpio_led) { 5053 if (spec->vref_mute_led_nid)
5049 if (spec->gpio_led <= 8) { 5054 stac_vrefout_set(codec, spec->vref_mute_led_nid,
5050 stac_gpio_set(codec, spec->gpio_mask, 5055 spec->vref_led);
5051 spec->gpio_dir, spec->gpio_data); 5056 else if (spec->gpio_led)
5052 } else { 5057 stac_gpio_set(codec, spec->gpio_mask,
5053 stac_vrefout_set(codec, 5058 spec->gpio_dir, spec->gpio_data);
5054 spec->gpio_led, spec->vref_led);
5055 }
5056 }
5057 return 0; 5059 return 0;
5058} 5060}
5059 5061
@@ -5064,7 +5066,7 @@ static void stac92xx_set_power_state(struct hda_codec *codec, hda_nid_t fg,
5064 struct sigmatel_spec *spec = codec->spec; 5066 struct sigmatel_spec *spec = codec->spec;
5065 5067
5066 if (power_state == AC_PWRST_D3) { 5068 if (power_state == AC_PWRST_D3) {
5067 if (spec->gpio_led > 8) { 5069 if (spec->vref_mute_led_nid) {
5068 /* with vref-out pin used for mute led control 5070 /* with vref-out pin used for mute led control
5069 * codec AFG is prevented from D3 state 5071 * codec AFG is prevented from D3 state
5070 */ 5072 */
@@ -5117,7 +5119,7 @@ static int stac92xx_update_led_status(struct hda_codec *codec)
5117 } 5119 }
5118 } 5120 }
5119 /*polarity defines *not* muted state level*/ 5121 /*polarity defines *not* muted state level*/
5120 if (spec->gpio_led <= 8) { 5122 if (!spec->vref_mute_led_nid) {
5121 if (muted) 5123 if (muted)
5122 spec->gpio_data &= ~spec->gpio_led; /* orange */ 5124 spec->gpio_data &= ~spec->gpio_led; /* orange */
5123 else 5125 else
@@ -5135,7 +5137,8 @@ static int stac92xx_update_led_status(struct hda_codec *codec)
5135 muted_lvl = spec->gpio_led_polarity ? 5137 muted_lvl = spec->gpio_led_polarity ?
5136 AC_PINCTL_VREF_GRD : AC_PINCTL_VREF_HIZ; 5138 AC_PINCTL_VREF_GRD : AC_PINCTL_VREF_HIZ;
5137 spec->vref_led = muted ? muted_lvl : notmtd_lvl; 5139 spec->vref_led = muted ? muted_lvl : notmtd_lvl;
5138 stac_vrefout_set(codec, spec->gpio_led, spec->vref_led); 5140 stac_vrefout_set(codec, spec->vref_mute_led_nid,
5141 spec->vref_led);
5139 } 5142 }
5140 return 0; 5143 return 0;
5141} 5144}
@@ -5649,7 +5652,7 @@ again:
5649 5652
5650#ifdef CONFIG_SND_HDA_POWER_SAVE 5653#ifdef CONFIG_SND_HDA_POWER_SAVE
5651 if (spec->gpio_led) { 5654 if (spec->gpio_led) {
5652 if (spec->gpio_led <= 8) { 5655 if (!spec->vref_mute_led_nid) {
5653 spec->gpio_mask |= spec->gpio_led; 5656 spec->gpio_mask |= spec->gpio_led;
5654 spec->gpio_dir |= spec->gpio_led; 5657 spec->gpio_dir |= spec->gpio_led;
5655 spec->gpio_data |= spec->gpio_led; 5658 spec->gpio_data |= spec->gpio_led;
@@ -5962,7 +5965,7 @@ again:
5962 5965
5963#ifdef CONFIG_SND_HDA_POWER_SAVE 5966#ifdef CONFIG_SND_HDA_POWER_SAVE
5964 if (spec->gpio_led) { 5967 if (spec->gpio_led) {
5965 if (spec->gpio_led <= 8) { 5968 if (!spec->vref_mute_led_nid) {
5966 spec->gpio_mask |= spec->gpio_led; 5969 spec->gpio_mask |= spec->gpio_led;
5967 spec->gpio_dir |= spec->gpio_led; 5970 spec->gpio_dir |= spec->gpio_led;
5968 spec->gpio_data |= spec->gpio_led; 5971 spec->gpio_data |= spec->gpio_led;
diff --git a/sound/pci/sis7019.c b/sound/pci/sis7019.c
index a391e622a192..28dfafb56dd1 100644
--- a/sound/pci/sis7019.c
+++ b/sound/pci/sis7019.c
@@ -41,6 +41,7 @@ MODULE_SUPPORTED_DEVICE("{{SiS,SiS7019 Audio Accelerator}}");
41static int index = SNDRV_DEFAULT_IDX1; /* Index 0-MAX */ 41static int index = SNDRV_DEFAULT_IDX1; /* Index 0-MAX */
42static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */ 42static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */
43static int enable = 1; 43static int enable = 1;
44static int codecs = 1;
44 45
45module_param(index, int, 0444); 46module_param(index, int, 0444);
46MODULE_PARM_DESC(index, "Index value for SiS7019 Audio Accelerator."); 47MODULE_PARM_DESC(index, "Index value for SiS7019 Audio Accelerator.");
@@ -48,6 +49,8 @@ module_param(id, charp, 0444);
48MODULE_PARM_DESC(id, "ID string for SiS7019 Audio Accelerator."); 49MODULE_PARM_DESC(id, "ID string for SiS7019 Audio Accelerator.");
49module_param(enable, bool, 0444); 50module_param(enable, bool, 0444);
50MODULE_PARM_DESC(enable, "Enable SiS7019 Audio Accelerator."); 51MODULE_PARM_DESC(enable, "Enable SiS7019 Audio Accelerator.");
52module_param(codecs, int, 0444);
53MODULE_PARM_DESC(codecs, "Set bit to indicate that codec number is expected to be present (default 1)");
51 54
52static DEFINE_PCI_DEVICE_TABLE(snd_sis7019_ids) = { 55static DEFINE_PCI_DEVICE_TABLE(snd_sis7019_ids) = {
53 { PCI_DEVICE(PCI_VENDOR_ID_SI, 0x7019) }, 56 { PCI_DEVICE(PCI_VENDOR_ID_SI, 0x7019) },
@@ -140,6 +143,9 @@ struct sis7019 {
140 dma_addr_t silence_dma_addr; 143 dma_addr_t silence_dma_addr;
141}; 144};
142 145
146/* These values are also used by the module param 'codecs' to indicate
147 * which codecs should be present.
148 */
143#define SIS_PRIMARY_CODEC_PRESENT 0x0001 149#define SIS_PRIMARY_CODEC_PRESENT 0x0001
144#define SIS_SECONDARY_CODEC_PRESENT 0x0002 150#define SIS_SECONDARY_CODEC_PRESENT 0x0002
145#define SIS_TERTIARY_CODEC_PRESENT 0x0004 151#define SIS_TERTIARY_CODEC_PRESENT 0x0004
@@ -1078,6 +1084,7 @@ static int sis_chip_init(struct sis7019 *sis)
1078{ 1084{
1079 unsigned long io = sis->ioport; 1085 unsigned long io = sis->ioport;
1080 void __iomem *ioaddr = sis->ioaddr; 1086 void __iomem *ioaddr = sis->ioaddr;
1087 unsigned long timeout;
1081 u16 status; 1088 u16 status;
1082 int count; 1089 int count;
1083 int i; 1090 int i;
@@ -1104,21 +1111,45 @@ static int sis_chip_init(struct sis7019 *sis)
1104 while ((inw(io + SIS_AC97_STATUS) & SIS_AC97_STATUS_BUSY) && --count) 1111 while ((inw(io + SIS_AC97_STATUS) & SIS_AC97_STATUS_BUSY) && --count)
1105 udelay(1); 1112 udelay(1);
1106 1113
1114 /* Command complete, we can let go of the semaphore now.
1115 */
1116 outl(SIS_AC97_SEMA_RELEASE, io + SIS_AC97_SEMA);
1117 if (!count)
1118 return -EIO;
1119
1107 /* Now that we've finished the reset, find out what's attached. 1120 /* Now that we've finished the reset, find out what's attached.
1121 * There are some codec/board combinations that take an extremely
1122 * long time to come up. 350+ ms has been observed in the field,
1123 * so we'll give them up to 500ms.
1108 */ 1124 */
1109 status = inl(io + SIS_AC97_STATUS); 1125 sis->codecs_present = 0;
1110 if (status & SIS_AC97_STATUS_CODEC_READY) 1126 timeout = msecs_to_jiffies(500) + jiffies;
1111 sis->codecs_present |= SIS_PRIMARY_CODEC_PRESENT; 1127 while (time_before_eq(jiffies, timeout)) {
1112 if (status & SIS_AC97_STATUS_CODEC2_READY) 1128 status = inl(io + SIS_AC97_STATUS);
1113 sis->codecs_present |= SIS_SECONDARY_CODEC_PRESENT; 1129 if (status & SIS_AC97_STATUS_CODEC_READY)
1114 if (status & SIS_AC97_STATUS_CODEC3_READY) 1130 sis->codecs_present |= SIS_PRIMARY_CODEC_PRESENT;
1115 sis->codecs_present |= SIS_TERTIARY_CODEC_PRESENT; 1131 if (status & SIS_AC97_STATUS_CODEC2_READY)
1116 1132 sis->codecs_present |= SIS_SECONDARY_CODEC_PRESENT;
1117 /* All done, let go of the semaphore, and check for errors 1133 if (status & SIS_AC97_STATUS_CODEC3_READY)
1134 sis->codecs_present |= SIS_TERTIARY_CODEC_PRESENT;
1135
1136 if (sis->codecs_present == codecs)
1137 break;
1138
1139 msleep(1);
1140 }
1141
1142 /* All done, check for errors.
1118 */ 1143 */
1119 outl(SIS_AC97_SEMA_RELEASE, io + SIS_AC97_SEMA); 1144 if (!sis->codecs_present) {
1120 if (!sis->codecs_present || !count) 1145 printk(KERN_ERR "sis7019: could not find any codecs\n");
1121 return -EIO; 1146 return -EIO;
1147 }
1148
1149 if (sis->codecs_present != codecs) {
1150 printk(KERN_WARNING "sis7019: missing codecs, found %0x, expected %0x\n",
1151 sis->codecs_present, codecs);
1152 }
1122 1153
1123 /* Let the hardware know that the audio driver is alive, 1154 /* Let the hardware know that the audio driver is alive,
1124 * and enable PCM slots on the AC-link for L/R playback (3 & 4) and 1155 * and enable PCM slots on the AC-link for L/R playback (3 & 4) and
@@ -1390,6 +1421,17 @@ static int __devinit snd_sis7019_probe(struct pci_dev *pci,
1390 if (!enable) 1421 if (!enable)
1391 goto error_out; 1422 goto error_out;
1392 1423
1424 /* The user can specify which codecs should be present so that we
1425 * can wait for them to show up if they are slow to recover from
1426 * the AC97 cold reset. We default to a single codec, the primary.
1427 *
1428 * We assume that SIS_PRIMARY_*_PRESENT matches bits 0-2.
1429 */
1430 codecs &= SIS_PRIMARY_CODEC_PRESENT | SIS_SECONDARY_CODEC_PRESENT |
1431 SIS_TERTIARY_CODEC_PRESENT;
1432 if (!codecs)
1433 codecs = SIS_PRIMARY_CODEC_PRESENT;
1434
1393 rc = snd_card_create(index, id, THIS_MODULE, sizeof(*sis), &card); 1435 rc = snd_card_create(index, id, THIS_MODULE, sizeof(*sis), &card);
1394 if (rc < 0) 1436 if (rc < 0)
1395 goto error_out; 1437 goto error_out;