]> git.ipfire.org Git - people/teissler/ipfire-2.x.git/blob - src/patches/suse-2.6.27.31/patches.drivers/alsa-post-ga-hda-sync-verbs
Reenabled linux-xen, added patches for Xen Kernel Version 2.6.27.31,
[people/teissler/ipfire-2.x.git] / src / patches / suse-2.6.27.31 / patches.drivers / alsa-post-ga-hda-sync-verbs
1 From: Takashi Iwai <tiwai@suse.de>
2 Subject: ALSA: hda - Support sync after writing a verb
3 Patch-mainline:
4 References: bnc#502903
5
6 This patch adds a debug mode to make the codec communication
7 synchronous. Define SND_HDA_SUPPORT_SYNC_WRITE in hda_codec.c,
8 and the call of snd_hda_codec_write*() will become synchronous,
9 i.e. wait for the reply from the codec at each time issuing a verb.
10
11 Signed-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 */