]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blob - src/patches/suse-2.6.27.25/patches.drivers/alsa-post-ga-hda-intel-cleanup
Updated xen patches taken from suse.
[people/pmueller/ipfire-2.x.git] / src / patches / suse-2.6.27.25 / patches.drivers / alsa-post-ga-hda-intel-cleanup
1 From: Takashi Iwai <tiwai@suse.de>
2 Subject: ALSA: hda - clean up hda_intel.c
3 Patch-mainline: 2.6.30-rc1
4 References: bnc#502733
5
6 Clean up hda_intel.c for error path.
7 Also clean up / optimization for stream setups.
8
9 Signed-off-by: Takashi Iwai <tiwai@suse.de>
10
11 ---
12 sound/pci/hda/hda_intel.c | 112 +++++++++++++++++++++++++++-------------------
13 1 file changed, 67 insertions(+), 45 deletions(-)
14
15 --- a/sound/pci/hda/hda_intel.c
16 +++ b/sound/pci/hda/hda_intel.c
17 @@ -848,13 +848,18 @@ static void azx_stream_start(struct azx
18 SD_CTL_DMA_START | SD_INT_MASK);
19 }
20
21 -/* stop a stream */
22 -static void azx_stream_stop(struct azx *chip, struct azx_dev *azx_dev)
23 +/* stop DMA */
24 +static void azx_stream_clear(struct azx *chip, struct azx_dev *azx_dev)
25 {
26 - /* stop DMA */
27 azx_sd_writeb(azx_dev, SD_CTL, azx_sd_readb(azx_dev, SD_CTL) &
28 ~(SD_CTL_DMA_START | SD_INT_MASK));
29 azx_sd_writeb(azx_dev, SD_STS, SD_INT_MASK); /* to be sure */
30 +}
31 +
32 +/* stop a stream */
33 +static void azx_stream_stop(struct azx *chip, struct azx_dev *azx_dev)
34 +{
35 + azx_stream_clear(chip, azx_dev);
36 /* disable SIE */
37 azx_writeb(chip, INTCTL,
38 azx_readb(chip, INTCTL) & ~(1 << azx_dev->index));
39 @@ -1067,8 +1072,7 @@ static int azx_setup_periods(struct azx
40 azx_sd_writel(azx_dev, SD_BDLPL, 0);
41 azx_sd_writel(azx_dev, SD_BDLPU, 0);
42
43 - period_bytes = snd_pcm_lib_period_bytes(substream);
44 - azx_dev->period_bytes = period_bytes;
45 + period_bytes = azx_dev->period_bytes;
46 periods = azx_dev->bufsize / period_bytes;
47
48 /* program the initial BDL entries */
49 @@ -1115,24 +1119,17 @@ static int azx_setup_periods(struct azx
50 error:
51 snd_printk(KERN_ERR "Too many BDL entries: buffer=%d, period=%d\n",
52 azx_dev->bufsize, period_bytes);
53 - /* reset */
54 - azx_sd_writel(azx_dev, SD_BDLPL, 0);
55 - azx_sd_writel(azx_dev, SD_BDLPU, 0);
56 return -EINVAL;
57 }
58
59 -/*
60 - * set up the SD for streaming
61 - */
62 -static int azx_setup_controller(struct azx *chip, struct azx_dev *azx_dev)
63 +/* reset stream */
64 +static void azx_stream_reset(struct azx *chip, struct azx_dev *azx_dev)
65 {
66 unsigned char val;
67 int timeout;
68
69 - /* make sure the run bit is zero for SD */
70 - azx_sd_writeb(azx_dev, SD_CTL, azx_sd_readb(azx_dev, SD_CTL) &
71 - ~SD_CTL_DMA_START);
72 - /* reset stream */
73 + azx_stream_clear(chip, azx_dev);
74 +
75 azx_sd_writeb(azx_dev, SD_CTL, azx_sd_readb(azx_dev, SD_CTL) |
76 SD_CTL_STREAM_RESET);
77 udelay(3);
78 @@ -1149,7 +1146,15 @@ static int azx_setup_controller(struct a
79 while (((val = azx_sd_readb(azx_dev, SD_CTL)) & SD_CTL_STREAM_RESET) &&
80 --timeout)
81 ;
82 +}
83
84 +/*
85 + * set up the SD for streaming
86 + */
87 +static int azx_setup_controller(struct azx *chip, struct azx_dev *azx_dev)
88 +{
89 + /* make sure the run bit is zero for SD */
90 + azx_stream_clear(chip, azx_dev);
91 /* program the stream_tag */
92 azx_sd_writel(azx_dev, SD_CTL,
93 (azx_sd_readl(azx_dev, SD_CTL) & ~SD_CTL_STREAM_TAG_MASK)|
94 @@ -1390,6 +1395,8 @@ static int azx_pcm_open(struct snd_pcm_s
95 runtime->private_data = azx_dev;
96 snd_pcm_set_sync(substream);
97 mutex_unlock(&chip->open_mutex);
98 +
99 + azx_stream_reset(chip, azx_dev);
100 return 0;
101 }
102
103 @@ -1416,6 +1423,11 @@ static int azx_pcm_close(struct snd_pcm_
104 static int azx_pcm_hw_params(struct snd_pcm_substream *substream,
105 struct snd_pcm_hw_params *hw_params)
106 {
107 + struct azx_dev *azx_dev = get_azx_dev(substream);
108 +
109 + azx_dev->bufsize = 0;
110 + azx_dev->period_bytes = 0;
111 + azx_dev->format_val = 0;
112 return snd_pcm_lib_malloc_pages(substream,
113 params_buffer_bytes(hw_params));
114 }
115 @@ -1430,6 +1442,9 @@ static int azx_pcm_hw_free(struct snd_pc
116 azx_sd_writel(azx_dev, SD_BDLPL, 0);
117 azx_sd_writel(azx_dev, SD_BDLPU, 0);
118 azx_sd_writel(azx_dev, SD_CTL, 0);
119 + azx_dev->bufsize = 0;
120 + azx_dev->period_bytes = 0;
121 + azx_dev->format_val = 0;
122
123 hinfo->ops.cleanup(hinfo, apcm->codec, substream);
124
125 @@ -1443,23 +1458,37 @@ static int azx_pcm_prepare(struct snd_pc
126 struct azx_dev *azx_dev = get_azx_dev(substream);
127 struct hda_pcm_stream *hinfo = apcm->hinfo[substream->stream];
128 struct snd_pcm_runtime *runtime = substream->runtime;
129 + unsigned int bufsize, period_bytes, format_val;
130 + int err;
131
132 - azx_dev->bufsize = snd_pcm_lib_buffer_bytes(substream);
133 - azx_dev->format_val = snd_hda_calc_stream_format(runtime->rate,
134 - runtime->channels,
135 - runtime->format,
136 - hinfo->maxbps);
137 - if (!azx_dev->format_val) {
138 + format_val = snd_hda_calc_stream_format(runtime->rate,
139 + runtime->channels,
140 + runtime->format,
141 + hinfo->maxbps);
142 + if (!format_val) {
143 snd_printk(KERN_ERR SFX
144 "invalid format_val, rate=%d, ch=%d, format=%d\n",
145 runtime->rate, runtime->channels, runtime->format);
146 return -EINVAL;
147 }
148
149 + bufsize = snd_pcm_lib_buffer_bytes(substream);
150 + period_bytes = snd_pcm_lib_period_bytes(substream);
151 +
152 snd_printdd("azx_pcm_prepare: bufsize=0x%x, format=0x%x\n",
153 - azx_dev->bufsize, azx_dev->format_val);
154 - if (azx_setup_periods(chip, substream, azx_dev) < 0)
155 - return -EINVAL;
156 + bufsize, format_val);
157 +
158 + if (bufsize != azx_dev->bufsize ||
159 + period_bytes != azx_dev->period_bytes ||
160 + format_val != azx_dev->format_val) {
161 + azx_dev->bufsize = bufsize;
162 + azx_dev->period_bytes = period_bytes;
163 + azx_dev->format_val = format_val;
164 + err = azx_setup_periods(chip, substream, azx_dev);
165 + if (err < 0)
166 + return err;
167 + }
168 +
169 azx_setup_controller(chip, azx_dev);
170 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
171 azx_dev->fifo_size = azx_sd_readw(azx_dev, SD_FIFOSIZE) + 1;
172 @@ -2373,40 +2402,30 @@ static int __devinit azx_probe(struct pc
173 }
174
175 err = azx_create(card, pci, dev, pci_id->driver_data, &chip);
176 - if (err < 0) {
177 - snd_card_free(card);
178 - return err;
179 - }
180 + if (err < 0)
181 + goto out_free;
182 card->private_data = chip;
183
184 /* create codec instances */
185 err = azx_codec_create(chip, model[dev], probe_mask[dev]);
186 - if (err < 0) {
187 - snd_card_free(card);
188 - return err;
189 - }
190 + if (err < 0)
191 + goto out_free;
192
193 /* create PCM streams */
194 err = azx_pcm_create(chip);
195 - if (err < 0) {
196 - snd_card_free(card);
197 - return err;
198 - }
199 + if (err < 0)
200 + goto out_free;
201
202 /* create mixer controls */
203 err = azx_mixer_create(chip);
204 - if (err < 0) {
205 - snd_card_free(card);
206 - return err;
207 - }
208 + if (err < 0)
209 + goto out_free;
210
211 snd_card_set_dev(card, &pci->dev);
212
213 err = snd_card_register(card);
214 - if (err < 0) {
215 - snd_card_free(card);
216 - return err;
217 - }
218 + if (err < 0)
219 + goto out_free;
220
221 pci_set_drvdata(pci, card);
222 chip->running = 1;
223 @@ -2415,6 +2434,9 @@ static int __devinit azx_probe(struct pc
224
225 dev++;
226 return err;
227 +out_free:
228 + snd_card_free(card);
229 + return err;
230 }
231
232 static void __devexit azx_remove(struct pci_dev *pci)