]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blame - src/patches/suse-2.6.27.25/patches.drivers/alsa-post-ga-hda-sync-verbs
Reenabled linux-xen and xen-image build
[people/pmueller/ipfire-2.x.git] / src / patches / suse-2.6.27.25 / patches.drivers / alsa-post-ga-hda-sync-verbs
CommitLineData
00e5a55c
BS
1From: Takashi Iwai <tiwai@suse.de>
2Subject: ALSA: hda - Support sync after writing a verb
3Patch-mainline:
4References: bnc#502903
5
6This patch adds a debug mode to make the codec communication
7synchronous. Define SND_HDA_SUPPORT_SYNC_WRITE in hda_codec.c,
8and the call of snd_hda_codec_write*() will become synchronous,
9i.e. wait for the reply from the codec at each time issuing a verb.
10
11Signed-off-by: Takashi Iwai <tiwai@suse.de>
12
13---
14 sound/pci/hda/hda_codec.c | 87 +++++++++++++++++++++++++---------------------
15 1 file changed, 49 insertions(+), 38 deletions(-)
16
17--- a/sound/pci/hda/hda_codec.c
18+++ b/sound/pci/hda/hda_codec.c
19@@ -176,6 +176,27 @@
20 >> AC_DEFCFG_DEVICE_SHIFT];
21 }
22
23+/*
24+ * Send and receive a verb
25+ */
26+static int codec_exec_verb(struct hda_codec *codec, unsigned int cmd,
27+ unsigned int *res)
28+{
29+ struct hda_bus *bus = codec->bus;
30+ int err;
31+
32+ if (res)
33+ *res = -1;
34+ snd_hda_power_up(codec);
35+ mutex_lock(&bus->cmd_mutex);
36+ err = bus->ops.command(bus, cmd);
37+ if (!err && res)
38+ *res = bus->ops.get_response(bus);
39+ mutex_unlock(&bus->cmd_mutex);
40+ snd_hda_power_down(codec);
41+ return err;
42+}
43+
44 /**
45 * snd_hda_codec_read - send a command and get the response
46 * @codec: the HDA codec
47@@ -192,21 +213,17 @@
48 int direct,
49 unsigned int verb, unsigned int parm)
50 {
51- struct hda_bus *bus = codec->bus;
52+ unsigned cmd = make_codec_cmd(codec, nid, direct, verb, parm);
53 unsigned int res;
54-
55- res = make_codec_cmd(codec, nid, direct, verb, parm);
56- snd_hda_power_up(codec);
57- mutex_lock(&bus->cmd_mutex);
58- if (!bus->ops.command(bus, res))
59- res = bus->ops.get_response(bus);
60- else
61- res = (unsigned int)-1;
62- mutex_unlock(&bus->cmd_mutex);
63- snd_hda_power_down(codec);
64+ codec_exec_verb(codec, cmd, &res);
65 return res;
66 }
67
68+/* Define the below to send and receive verbs synchronously.
69+ * If you often get any codec communication errors, this is worth to try.
70+ */
71+#define SND_HDA_SUPPORT_SYNC_WRITE
72+
73 /**
74 * snd_hda_codec_write - send a single command without waiting for response
75 * @codec: the HDA codec
76@@ -222,17 +239,13 @@
77 int snd_hda_codec_write(struct hda_codec *codec, hda_nid_t nid, int direct,
78 unsigned int verb, unsigned int parm)
79 {
80- struct hda_bus *bus = codec->bus;
81+ unsigned int cmd = make_codec_cmd(codec, nid, direct, verb, parm);
82+#ifdef SND_HDA_SUPPORT_SYNC_WRITE
83 unsigned int res;
84- int err;
85-
86- res = make_codec_cmd(codec, nid, direct, verb, parm);
87- snd_hda_power_up(codec);
88- mutex_lock(&bus->cmd_mutex);
89- err = bus->ops.command(bus, res);
90- mutex_unlock(&bus->cmd_mutex);
91- snd_hda_power_down(codec);
92- return err;
93+ return codec_exec_verb(codec, cmd, &res);
94+#else
95+ return codec_exec_verb(codec, cmd, NULL);
96+#endif
97 }
98
99 /**
100@@ -1876,24 +1889,22 @@
101 int snd_hda_codec_write_cache(struct hda_codec *codec, hda_nid_t nid,
102 int direct, unsigned int verb, unsigned int parm)
103 {
104- struct hda_bus *bus = codec->bus;
105- unsigned int res;
106- int err;
107+ int err = snd_hda_codec_write(codec, nid, direct, verb, parm);
108+ struct hda_cache_head *c;
109+ u32 key;
110
111- res = make_codec_cmd(codec, nid, direct, verb, parm);
112- snd_hda_power_up(codec);
113- mutex_lock(&bus->cmd_mutex);
114- err = bus->ops.command(bus, res);
115- if (!err) {
116- struct hda_cache_head *c;
117- u32 key = build_cmd_cache_key(nid, verb);
118- c = get_alloc_hash(&codec->cmd_cache, key);
119- if (c)
120- c->val = parm;
121- }
122- mutex_unlock(&bus->cmd_mutex);
123- snd_hda_power_down(codec);
124- return err;
125+ if (err < 0)
126+ return err;
127+ /* parm may contain the verb stuff for get/set amp */
128+ verb = verb | (parm >> 8);
129+ parm &= 0xff;
130+ key = build_cmd_cache_key(nid, verb);
131+ mutex_lock(&codec->bus->cmd_mutex);
132+ c = get_alloc_hash(&codec->cmd_cache, key);
133+ if (c)
134+ c->val = parm;
135+ mutex_unlock(&codec->bus->cmd_mutex);
136+ return 0;
137 }
138
139 /* resume the all commands from the cache */