+++ /dev/null
-From: Takashi Iwai <tiwai@suse.de>
-Subject: ALSA: hda - Support sync after writing a verb
-Patch-mainline:
-References: bnc#502903
-
-This patch adds a debug mode to make the codec communication
-synchronous. Define SND_HDA_SUPPORT_SYNC_WRITE in hda_codec.c,
-and the call of snd_hda_codec_write*() will become synchronous,
-i.e. wait for the reply from the codec at each time issuing a verb.
-
-Signed-off-by: Takashi Iwai <tiwai@suse.de>
-
----
- sound/pci/hda/hda_codec.c | 87 +++++++++++++++++++++++++---------------------
- 1 file changed, 49 insertions(+), 38 deletions(-)
-
---- a/sound/pci/hda/hda_codec.c
-+++ b/sound/pci/hda/hda_codec.c
-@@ -176,6 +176,27 @@
- >> AC_DEFCFG_DEVICE_SHIFT];
- }
-
-+/*
-+ * Send and receive a verb
-+ */
-+static int codec_exec_verb(struct hda_codec *codec, unsigned int cmd,
-+ unsigned int *res)
-+{
-+ struct hda_bus *bus = codec->bus;
-+ int err;
-+
-+ if (res)
-+ *res = -1;
-+ snd_hda_power_up(codec);
-+ mutex_lock(&bus->cmd_mutex);
-+ err = bus->ops.command(bus, cmd);
-+ if (!err && res)
-+ *res = bus->ops.get_response(bus);
-+ mutex_unlock(&bus->cmd_mutex);
-+ snd_hda_power_down(codec);
-+ return err;
-+}
-+
- /**
- * snd_hda_codec_read - send a command and get the response
- * @codec: the HDA codec
-@@ -192,21 +213,17 @@
- int direct,
- unsigned int verb, unsigned int parm)
- {
-- struct hda_bus *bus = codec->bus;
-+ unsigned cmd = make_codec_cmd(codec, nid, direct, verb, parm);
- unsigned int res;
--
-- res = make_codec_cmd(codec, nid, direct, verb, parm);
-- snd_hda_power_up(codec);
-- mutex_lock(&bus->cmd_mutex);
-- if (!bus->ops.command(bus, res))
-- res = bus->ops.get_response(bus);
-- else
-- res = (unsigned int)-1;
-- mutex_unlock(&bus->cmd_mutex);
-- snd_hda_power_down(codec);
-+ codec_exec_verb(codec, cmd, &res);
- return res;
- }
-
-+/* 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
-@@ -222,17 +239,13 @@
- int snd_hda_codec_write(struct hda_codec *codec, hda_nid_t nid, int direct,
- unsigned int verb, unsigned int parm)
- {
-- struct hda_bus *bus = codec->bus;
-+ unsigned int cmd = make_codec_cmd(codec, nid, direct, verb, parm);
-+#ifdef SND_HDA_SUPPORT_SYNC_WRITE
- unsigned int res;
-- int err;
--
-- res = make_codec_cmd(codec, nid, direct, verb, parm);
-- snd_hda_power_up(codec);
-- mutex_lock(&bus->cmd_mutex);
-- err = bus->ops.command(bus, res);
-- mutex_unlock(&bus->cmd_mutex);
-- snd_hda_power_down(codec);
-- return err;
-+ return codec_exec_verb(codec, cmd, &res);
-+#else
-+ return codec_exec_verb(codec, cmd, NULL);
-+#endif
- }
-
- /**
-@@ -1876,24 +1889,22 @@
- int snd_hda_codec_write_cache(struct hda_codec *codec, hda_nid_t nid,
- int direct, unsigned int verb, unsigned int parm)
- {
-- struct hda_bus *bus = codec->bus;
-- unsigned int res;
-- int err;
-+ int err = snd_hda_codec_write(codec, nid, direct, verb, parm);
-+ struct hda_cache_head *c;
-+ u32 key;
-
-- res = make_codec_cmd(codec, nid, direct, verb, parm);
-- snd_hda_power_up(codec);
-- mutex_lock(&bus->cmd_mutex);
-- err = bus->ops.command(bus, res);
-- if (!err) {
-- struct hda_cache_head *c;
-- u32 key = build_cmd_cache_key(nid, verb);
-- c = get_alloc_hash(&codec->cmd_cache, key);
-- if (c)
-- c->val = parm;
-- }
-- mutex_unlock(&bus->cmd_mutex);
-- snd_hda_power_down(codec);
-- return err;
-+ if (err < 0)
-+ return err;
-+ /* parm may contain the verb stuff for get/set amp */
-+ verb = verb | (parm >> 8);
-+ parm &= 0xff;
-+ key = build_cmd_cache_key(nid, verb);
-+ mutex_lock(&codec->bus->cmd_mutex);
-+ c = get_alloc_hash(&codec->cmd_cache, key);
-+ if (c)
-+ c->val = parm;
-+ mutex_unlock(&codec->bus->cmd_mutex);
-+ return 0;
- }
-
- /* resume the all commands from the cache */