Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b20f3b83 authored by Takashi Iwai's avatar Takashi Iwai
Browse files

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: default avatarTakashi Iwai <tiwai@suse.de>
parent 8dd78330
Loading
Loading
Loading
Loading
+2 −10
Original line number Diff line number Diff line
@@ -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);

/* 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
 * @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 cmd = make_codec_cmd(codec, nid, direct, verb, parm);
#ifdef SND_HDA_SUPPORT_SYNC_WRITE
	unsigned int res;
	return codec_exec_verb(codec, cmd, &res);
#else
	return codec_exec_verb(codec, cmd, NULL);
#endif
	return codec_exec_verb(codec, cmd,
			       codec->bus->sync_write ? &res : NULL);
}
EXPORT_SYMBOL_HDA(snd_hda_codec_write);

+3 −0
Original line number Diff line number Diff line
@@ -624,6 +624,9 @@ struct hda_bus {

	/* misc op flags */
	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 rirb_error:1;	/* error in codec communication */
	unsigned int response_reset:1;	/* controller was reset */
+1 −1
Original line number Diff line number Diff line
@@ -665,7 +665,7 @@ static unsigned int azx_rirb_get_response(struct hda_bus *bus)
	 * to the single_cmd mode
	 */
	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;
		return -1; /* give a chance to retry */
	}
+9 −0
Original line number Diff line number Diff line
@@ -5375,6 +5375,15 @@ again:
	if (get_wcaps(codec, 0xa) & AC_WCAP_IN_AMP)
		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_mask = 0x50;
	spec->aloopback_shift = 0;