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>
This commit is contained in:
@@ -214,11 +214,6 @@ unsigned int snd_hda_codec_read(struct hda_codec *codec, hda_nid_t nid,
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL_HDA(snd_hda_codec_read);
|
EXPORT_SYMBOL_HDA(snd_hda_codec_read);
|
||||||
|
|
||||||
/* Define the below to send and receive verbs synchronously.
|
|
||||||
* If you often get any codec communication errors, this is worth to try.
|
|
||||||
*/
|
|
||||||
/* #define SND_HDA_SUPPORT_SYNC_WRITE */
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* snd_hda_codec_write - send a single command without waiting for response
|
* snd_hda_codec_write - send a single command without waiting for response
|
||||||
* @codec: the HDA codec
|
* @codec: the HDA codec
|
||||||
@@ -235,12 +230,9 @@ int snd_hda_codec_write(struct hda_codec *codec, hda_nid_t nid, int direct,
|
|||||||
unsigned int verb, unsigned int parm)
|
unsigned int verb, unsigned int parm)
|
||||||
{
|
{
|
||||||
unsigned int cmd = make_codec_cmd(codec, nid, direct, verb, parm);
|
unsigned int cmd = make_codec_cmd(codec, nid, direct, verb, parm);
|
||||||
#ifdef SND_HDA_SUPPORT_SYNC_WRITE
|
|
||||||
unsigned int res;
|
unsigned int res;
|
||||||
return codec_exec_verb(codec, cmd, &res);
|
return codec_exec_verb(codec, cmd,
|
||||||
#else
|
codec->bus->sync_write ? &res : NULL);
|
||||||
return codec_exec_verb(codec, cmd, NULL);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_HDA(snd_hda_codec_write);
|
EXPORT_SYMBOL_HDA(snd_hda_codec_write);
|
||||||
|
|
||||||
|
@@ -624,6 +624,9 @@ struct hda_bus {
|
|||||||
|
|
||||||
/* misc op flags */
|
/* misc op flags */
|
||||||
unsigned int needs_damn_long_delay :1;
|
unsigned int needs_damn_long_delay :1;
|
||||||
|
unsigned int allow_bus_reset:1; /* allow bus reset at fatal error */
|
||||||
|
unsigned int sync_write:1; /* sync after verb write */
|
||||||
|
/* status for codec/controller */
|
||||||
unsigned int shutdown :1; /* being unloaded */
|
unsigned int shutdown :1; /* being unloaded */
|
||||||
unsigned int rirb_error:1; /* error in codec communication */
|
unsigned int rirb_error:1; /* error in codec communication */
|
||||||
unsigned int response_reset:1; /* controller was reset */
|
unsigned int response_reset:1; /* controller was reset */
|
||||||
|
@@ -665,7 +665,7 @@ static unsigned int azx_rirb_get_response(struct hda_bus *bus)
|
|||||||
* to the single_cmd mode
|
* to the single_cmd mode
|
||||||
*/
|
*/
|
||||||
bus->rirb_error = 1;
|
bus->rirb_error = 1;
|
||||||
if (!bus->response_reset && !bus->in_reset) {
|
if (bus->allow_bus_reset && !bus->response_reset && !bus->in_reset) {
|
||||||
bus->response_reset = 1;
|
bus->response_reset = 1;
|
||||||
return -1; /* give a chance to retry */
|
return -1; /* give a chance to retry */
|
||||||
}
|
}
|
||||||
|
@@ -5375,6 +5375,15 @@ again:
|
|||||||
if (get_wcaps(codec, 0xa) & AC_WCAP_IN_AMP)
|
if (get_wcaps(codec, 0xa) & AC_WCAP_IN_AMP)
|
||||||
snd_hda_sequence_write_cache(codec, unmute_init);
|
snd_hda_sequence_write_cache(codec, unmute_init);
|
||||||
|
|
||||||
|
/* Some HP machines seem to have unstable codec communications
|
||||||
|
* especially with ATI fglrx driver. For recovering from the
|
||||||
|
* CORB/RIRB stall, allow the BUS reset and keep always sync
|
||||||
|
*/
|
||||||
|
if (spec->board_config == STAC_HP_DV5) {
|
||||||
|
codec->bus->sync_write = 1;
|
||||||
|
codec->bus->allow_bus_reset = 1;
|
||||||
|
}
|
||||||
|
|
||||||
spec->aloopback_ctl = stac92hd71bxx_loopback;
|
spec->aloopback_ctl = stac92hd71bxx_loopback;
|
||||||
spec->aloopback_mask = 0x50;
|
spec->aloopback_mask = 0x50;
|
||||||
spec->aloopback_shift = 0;
|
spec->aloopback_shift = 0;
|
||||||
|
Reference in New Issue
Block a user