diff options
author | Takashi Iwai <tiwai@suse.de> | 2009-06-01 19:20:22 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2009-06-01 19:21:30 -0400 |
commit | b20f3b834673be9ead83a3c6f07fa3881d1a990f (patch) | |
tree | 719597407012fca08c66ef5f4565193765a042ed /sound | |
parent | 8dd783304e6d0f7c2830365d63f75f08aa343e10 (diff) |
ALSA: hda - Limit codec-verb retry to limited hardwares
The reset of a BUS controller during operations is somehow risky and
shouldn't be done inevitably for devices that have apparently no such
codec-communication problems.
This patch adds the check of the hardware and limits the bus-reset
capability.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound')
-rw-r--r-- | sound/pci/hda/hda_codec.c | 12 | ||||
-rw-r--r-- | sound/pci/hda/hda_codec.h | 3 | ||||
-rw-r--r-- | sound/pci/hda/hda_intel.c | 2 | ||||
-rw-r--r-- | sound/pci/hda/patch_sigmatel.c | 9 |
4 files changed, 15 insertions, 11 deletions
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index aa0e1c18b606..562403a23488 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c | |||
@@ -214,11 +214,6 @@ unsigned int snd_hda_codec_read(struct hda_codec *codec, hda_nid_t nid, | |||
214 | } | 214 | } |
215 | EXPORT_SYMBOL_HDA(snd_hda_codec_read); | 215 | EXPORT_SYMBOL_HDA(snd_hda_codec_read); |
216 | 216 | ||
217 | /* Define the below to send and receive verbs synchronously. | ||
218 | * If you often get any codec communication errors, this is worth to try. | ||
219 | */ | ||
220 | /* #define SND_HDA_SUPPORT_SYNC_WRITE */ | ||
221 | |||
222 | /** | 217 | /** |
223 | * snd_hda_codec_write - send a single command without waiting for response | 218 | * snd_hda_codec_write - send a single command without waiting for response |
224 | * @codec: the HDA codec | 219 | * @codec: the HDA codec |
@@ -235,12 +230,9 @@ int snd_hda_codec_write(struct hda_codec *codec, hda_nid_t nid, int direct, | |||
235 | unsigned int verb, unsigned int parm) | 230 | unsigned int verb, unsigned int parm) |
236 | { | 231 | { |
237 | unsigned int cmd = make_codec_cmd(codec, nid, direct, verb, parm); | 232 | unsigned int cmd = make_codec_cmd(codec, nid, direct, verb, parm); |
238 | #ifdef SND_HDA_SUPPORT_SYNC_WRITE | ||
239 | unsigned int res; | 233 | unsigned int res; |
240 | return codec_exec_verb(codec, cmd, &res); | 234 | return codec_exec_verb(codec, cmd, |
241 | #else | 235 | codec->bus->sync_write ? &res : NULL); |
242 | return codec_exec_verb(codec, cmd, NULL); | ||
243 | #endif | ||
244 | } | 236 | } |
245 | EXPORT_SYMBOL_HDA(snd_hda_codec_write); | 237 | EXPORT_SYMBOL_HDA(snd_hda_codec_write); |
246 | 238 | ||
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h index f5fa5d1f223c..cad79efaabc9 100644 --- a/sound/pci/hda/hda_codec.h +++ b/sound/pci/hda/hda_codec.h | |||
@@ -624,6 +624,9 @@ struct hda_bus { | |||
624 | 624 | ||
625 | /* misc op flags */ | 625 | /* misc op flags */ |
626 | unsigned int needs_damn_long_delay :1; | 626 | unsigned int needs_damn_long_delay :1; |
627 | unsigned int allow_bus_reset:1; /* allow bus reset at fatal error */ | ||
628 | unsigned int sync_write:1; /* sync after verb write */ | ||
629 | /* status for codec/controller */ | ||
627 | unsigned int shutdown :1; /* being unloaded */ | 630 | unsigned int shutdown :1; /* being unloaded */ |
628 | unsigned int rirb_error:1; /* error in codec communication */ | 631 | unsigned int rirb_error:1; /* error in codec communication */ |
629 | unsigned int response_reset:1; /* controller was reset */ | 632 | unsigned int response_reset:1; /* controller was reset */ |
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 44f9a0aa20c5..9f44645a1d04 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c | |||
@@ -665,7 +665,7 @@ static unsigned int azx_rirb_get_response(struct hda_bus *bus) | |||
665 | * to the single_cmd mode | 665 | * to the single_cmd mode |
666 | */ | 666 | */ |
667 | bus->rirb_error = 1; | 667 | bus->rirb_error = 1; |
668 | if (!bus->response_reset && !bus->in_reset) { | 668 | if (bus->allow_bus_reset && !bus->response_reset && !bus->in_reset) { |
669 | bus->response_reset = 1; | 669 | bus->response_reset = 1; |
670 | return -1; /* give a chance to retry */ | 670 | return -1; /* give a chance to retry */ |
671 | } | 671 | } |
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 48f4a36c4813..42f944bb641d 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c | |||
@@ -5375,6 +5375,15 @@ again: | |||
5375 | if (get_wcaps(codec, 0xa) & AC_WCAP_IN_AMP) | 5375 | if (get_wcaps(codec, 0xa) & AC_WCAP_IN_AMP) |
5376 | snd_hda_sequence_write_cache(codec, unmute_init); | 5376 | snd_hda_sequence_write_cache(codec, unmute_init); |
5377 | 5377 | ||
5378 | /* Some HP machines seem to have unstable codec communications | ||
5379 | * especially with ATI fglrx driver. For recovering from the | ||
5380 | * CORB/RIRB stall, allow the BUS reset and keep always sync | ||
5381 | */ | ||
5382 | if (spec->board_config == STAC_HP_DV5) { | ||
5383 | codec->bus->sync_write = 1; | ||
5384 | codec->bus->allow_bus_reset = 1; | ||
5385 | } | ||
5386 | |||
5378 | spec->aloopback_ctl = stac92hd71bxx_loopback; | 5387 | spec->aloopback_ctl = stac92hd71bxx_loopback; |
5379 | spec->aloopback_mask = 0x50; | 5388 | spec->aloopback_mask = 0x50; |
5380 | spec->aloopback_shift = 0; | 5389 | spec->aloopback_shift = 0; |