diff options
-rw-r--r-- | include/sound/soc.h | 1 | ||||
-rw-r--r-- | sound/soc/au1x/psc-ac97.c | 129 | ||||
-rw-r--r-- | sound/soc/au1x/psc.h | 1 | ||||
-rw-r--r-- | sound/soc/blackfin/bf5xx-ac97.c | 8 | ||||
-rw-r--r-- | sound/soc/blackfin/bf5xx-ac97.h | 2 | ||||
-rw-r--r-- | sound/soc/blackfin/bf5xx-i2s.c | 22 | ||||
-rw-r--r-- | sound/soc/blackfin/bf5xx-i2s.h | 2 | ||||
-rw-r--r-- | sound/soc/blackfin/bf5xx-sport.c | 2 | ||||
-rw-r--r-- | sound/soc/codecs/ad1836.c | 1 | ||||
-rw-r--r-- | sound/soc/codecs/ad1938.c | 1 | ||||
-rw-r--r-- | sound/soc/codecs/wm8350.c | 2 | ||||
-rw-r--r-- | sound/soc/codecs/wm8974.c | 1 | ||||
-rw-r--r-- | sound/soc/davinci/davinci-mcasp.c | 24 | ||||
-rw-r--r-- | sound/soc/fsl/mpc5200_dma.c | 33 | ||||
-rw-r--r-- | sound/soc/s3c24xx/s3c-i2s-v2.c | 16 | ||||
-rw-r--r-- | sound/soc/soc-dapm.c | 7 |
16 files changed, 174 insertions, 78 deletions
diff --git a/include/sound/soc.h b/include/sound/soc.h index 0758a1b3ca44..475cb7ed6bec 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h | |||
@@ -205,7 +205,6 @@ struct snd_soc_jack_gpio; | |||
205 | #endif | 205 | #endif |
206 | 206 | ||
207 | typedef int (*hw_write_t)(void *,const char* ,int); | 207 | typedef int (*hw_write_t)(void *,const char* ,int); |
208 | typedef int (*hw_read_t)(void *,char* ,int); | ||
209 | 208 | ||
210 | extern struct snd_ac97_bus_ops soc_ac97_ops; | 209 | extern struct snd_ac97_bus_ops soc_ac97_ops; |
211 | 210 | ||
diff --git a/sound/soc/au1x/psc-ac97.c b/sound/soc/au1x/psc-ac97.c index 479d7bdf1865..a521aa90ddee 100644 --- a/sound/soc/au1x/psc-ac97.c +++ b/sound/soc/au1x/psc-ac97.c | |||
@@ -1,8 +1,8 @@ | |||
1 | /* | 1 | /* |
2 | * Au12x0/Au1550 PSC ALSA ASoC audio support. | 2 | * Au12x0/Au1550 PSC ALSA ASoC audio support. |
3 | * | 3 | * |
4 | * (c) 2007-2008 MSC Vertriebsges.m.b.H., | 4 | * (c) 2007-2009 MSC Vertriebsges.m.b.H., |
5 | * Manuel Lauss <mano@roarinelk.homelinux.net> | 5 | * Manuel Lauss <manuel.lauss@gmail.com> |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
8 | * it under the terms of the GNU General Public License version 2 as | 8 | * it under the terms of the GNU General Public License version 2 as |
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/module.h> | 19 | #include <linux/module.h> |
20 | #include <linux/device.h> | 20 | #include <linux/device.h> |
21 | #include <linux/delay.h> | 21 | #include <linux/delay.h> |
22 | #include <linux/mutex.h> | ||
22 | #include <linux/suspend.h> | 23 | #include <linux/suspend.h> |
23 | #include <sound/core.h> | 24 | #include <sound/core.h> |
24 | #include <sound/pcm.h> | 25 | #include <sound/pcm.h> |
@@ -29,6 +30,9 @@ | |||
29 | 30 | ||
30 | #include "psc.h" | 31 | #include "psc.h" |
31 | 32 | ||
33 | /* how often to retry failed codec register reads/writes */ | ||
34 | #define AC97_RW_RETRIES 5 | ||
35 | |||
32 | #define AC97_DIR \ | 36 | #define AC97_DIR \ |
33 | (SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE) | 37 | (SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE) |
34 | 38 | ||
@@ -45,6 +49,9 @@ | |||
45 | #define AC97PCR_CLRFIFO(stype) \ | 49 | #define AC97PCR_CLRFIFO(stype) \ |
46 | ((stype) == PCM_TX ? PSC_AC97PCR_TC : PSC_AC97PCR_RC) | 50 | ((stype) == PCM_TX ? PSC_AC97PCR_TC : PSC_AC97PCR_RC) |
47 | 51 | ||
52 | #define AC97STAT_BUSY(stype) \ | ||
53 | ((stype) == PCM_TX ? PSC_AC97STAT_TB : PSC_AC97STAT_RB) | ||
54 | |||
48 | /* instance data. There can be only one, MacLeod!!!! */ | 55 | /* instance data. There can be only one, MacLeod!!!! */ |
49 | static struct au1xpsc_audio_data *au1xpsc_ac97_workdata; | 56 | static struct au1xpsc_audio_data *au1xpsc_ac97_workdata; |
50 | 57 | ||
@@ -54,24 +61,33 @@ static unsigned short au1xpsc_ac97_read(struct snd_ac97 *ac97, | |||
54 | { | 61 | { |
55 | /* FIXME */ | 62 | /* FIXME */ |
56 | struct au1xpsc_audio_data *pscdata = au1xpsc_ac97_workdata; | 63 | struct au1xpsc_audio_data *pscdata = au1xpsc_ac97_workdata; |
57 | unsigned short data, tmo; | 64 | unsigned short data, retry, tmo; |
58 | 65 | ||
59 | au_writel(PSC_AC97CDC_RD | PSC_AC97CDC_INDX(reg), AC97_CDC(pscdata)); | 66 | au_writel(PSC_AC97EVNT_CD, AC97_EVNT(pscdata)); |
60 | au_sync(); | 67 | au_sync(); |
61 | 68 | ||
62 | tmo = 1000; | 69 | retry = AC97_RW_RETRIES; |
63 | while ((!(au_readl(AC97_EVNT(pscdata)) & PSC_AC97EVNT_CD)) && --tmo) | 70 | do { |
64 | udelay(2); | 71 | mutex_lock(&pscdata->lock); |
72 | |||
73 | au_writel(PSC_AC97CDC_RD | PSC_AC97CDC_INDX(reg), | ||
74 | AC97_CDC(pscdata)); | ||
75 | au_sync(); | ||
76 | |||
77 | tmo = 2000; | ||
78 | while ((!(au_readl(AC97_EVNT(pscdata)) & PSC_AC97EVNT_CD)) | ||
79 | && --tmo) | ||
80 | udelay(2); | ||
65 | 81 | ||
66 | if (!tmo) | ||
67 | data = 0xffff; | ||
68 | else | ||
69 | data = au_readl(AC97_CDC(pscdata)) & 0xffff; | 82 | data = au_readl(AC97_CDC(pscdata)) & 0xffff; |
70 | 83 | ||
71 | au_writel(PSC_AC97EVNT_CD, AC97_EVNT(pscdata)); | 84 | au_writel(PSC_AC97EVNT_CD, AC97_EVNT(pscdata)); |
72 | au_sync(); | 85 | au_sync(); |
86 | |||
87 | mutex_unlock(&pscdata->lock); | ||
88 | } while (--retry && !tmo); | ||
73 | 89 | ||
74 | return data; | 90 | return retry ? data : 0xffff; |
75 | } | 91 | } |
76 | 92 | ||
77 | /* AC97 controller writes to codec register */ | 93 | /* AC97 controller writes to codec register */ |
@@ -80,16 +96,29 @@ static void au1xpsc_ac97_write(struct snd_ac97 *ac97, unsigned short reg, | |||
80 | { | 96 | { |
81 | /* FIXME */ | 97 | /* FIXME */ |
82 | struct au1xpsc_audio_data *pscdata = au1xpsc_ac97_workdata; | 98 | struct au1xpsc_audio_data *pscdata = au1xpsc_ac97_workdata; |
83 | unsigned int tmo; | 99 | unsigned int tmo, retry; |
84 | 100 | ||
85 | au_writel(PSC_AC97CDC_INDX(reg) | (val & 0xffff), AC97_CDC(pscdata)); | 101 | au_writel(PSC_AC97EVNT_CD, AC97_EVNT(pscdata)); |
86 | au_sync(); | 102 | au_sync(); |
87 | tmo = 1000; | 103 | |
88 | while ((!(au_readl(AC97_EVNT(pscdata)) & PSC_AC97EVNT_CD)) && --tmo) | 104 | retry = AC97_RW_RETRIES; |
105 | do { | ||
106 | mutex_lock(&pscdata->lock); | ||
107 | |||
108 | au_writel(PSC_AC97CDC_INDX(reg) | (val & 0xffff), | ||
109 | AC97_CDC(pscdata)); | ||
89 | au_sync(); | 110 | au_sync(); |
90 | 111 | ||
91 | au_writel(PSC_AC97EVNT_CD, AC97_EVNT(pscdata)); | 112 | tmo = 2000; |
92 | au_sync(); | 113 | while ((!(au_readl(AC97_EVNT(pscdata)) & PSC_AC97EVNT_CD)) |
114 | && --tmo) | ||
115 | udelay(2); | ||
116 | |||
117 | au_writel(PSC_AC97EVNT_CD, AC97_EVNT(pscdata)); | ||
118 | au_sync(); | ||
119 | |||
120 | mutex_unlock(&pscdata->lock); | ||
121 | } while (--retry && !tmo); | ||
93 | } | 122 | } |
94 | 123 | ||
95 | /* AC97 controller asserts a warm reset */ | 124 | /* AC97 controller asserts a warm reset */ |
@@ -129,9 +158,9 @@ static void au1xpsc_ac97_cold_reset(struct snd_ac97 *ac97) | |||
129 | au_sync(); | 158 | au_sync(); |
130 | 159 | ||
131 | /* wait for PSC to indicate it's ready */ | 160 | /* wait for PSC to indicate it's ready */ |
132 | i = 100000; | 161 | i = 1000; |
133 | while (!((au_readl(AC97_STAT(pscdata)) & PSC_AC97STAT_SR)) && (--i)) | 162 | while (!((au_readl(AC97_STAT(pscdata)) & PSC_AC97STAT_SR)) && (--i)) |
134 | au_sync(); | 163 | msleep(1); |
135 | 164 | ||
136 | if (i == 0) { | 165 | if (i == 0) { |
137 | printk(KERN_ERR "au1xpsc-ac97: PSC not ready!\n"); | 166 | printk(KERN_ERR "au1xpsc-ac97: PSC not ready!\n"); |
@@ -143,9 +172,9 @@ static void au1xpsc_ac97_cold_reset(struct snd_ac97 *ac97) | |||
143 | au_sync(); | 172 | au_sync(); |
144 | 173 | ||
145 | /* wait for AC97 core to become ready */ | 174 | /* wait for AC97 core to become ready */ |
146 | i = 100000; | 175 | i = 1000; |
147 | while (!((au_readl(AC97_STAT(pscdata)) & PSC_AC97STAT_DR)) && (--i)) | 176 | while (!((au_readl(AC97_STAT(pscdata)) & PSC_AC97STAT_DR)) && (--i)) |
148 | au_sync(); | 177 | msleep(1); |
149 | if (i == 0) | 178 | if (i == 0) |
150 | printk(KERN_ERR "au1xpsc-ac97: AC97 ctrl not ready\n"); | 179 | printk(KERN_ERR "au1xpsc-ac97: AC97 ctrl not ready\n"); |
151 | } | 180 | } |
@@ -165,12 +194,12 @@ static int au1xpsc_ac97_hw_params(struct snd_pcm_substream *substream, | |||
165 | { | 194 | { |
166 | /* FIXME */ | 195 | /* FIXME */ |
167 | struct au1xpsc_audio_data *pscdata = au1xpsc_ac97_workdata; | 196 | struct au1xpsc_audio_data *pscdata = au1xpsc_ac97_workdata; |
168 | unsigned long r, stat; | 197 | unsigned long r, ro, stat; |
169 | int chans, stype = SUBSTREAM_TYPE(substream); | 198 | int chans, stype = SUBSTREAM_TYPE(substream); |
170 | 199 | ||
171 | chans = params_channels(params); | 200 | chans = params_channels(params); |
172 | 201 | ||
173 | r = au_readl(AC97_CFG(pscdata)); | 202 | r = ro = au_readl(AC97_CFG(pscdata)); |
174 | stat = au_readl(AC97_STAT(pscdata)); | 203 | stat = au_readl(AC97_STAT(pscdata)); |
175 | 204 | ||
176 | /* already active? */ | 205 | /* already active? */ |
@@ -180,9 +209,6 @@ static int au1xpsc_ac97_hw_params(struct snd_pcm_substream *substream, | |||
180 | (pscdata->rate != params_rate(params))) | 209 | (pscdata->rate != params_rate(params))) |
181 | return -EINVAL; | 210 | return -EINVAL; |
182 | } else { | 211 | } else { |
183 | /* disable AC97 device controller first */ | ||
184 | au_writel(r & ~PSC_AC97CFG_DE_ENABLE, AC97_CFG(pscdata)); | ||
185 | au_sync(); | ||
186 | 212 | ||
187 | /* set sample bitdepth: REG[24:21]=(BITS-2)/2 */ | 213 | /* set sample bitdepth: REG[24:21]=(BITS-2)/2 */ |
188 | r &= ~PSC_AC97CFG_LEN_MASK; | 214 | r &= ~PSC_AC97CFG_LEN_MASK; |
@@ -199,14 +225,40 @@ static int au1xpsc_ac97_hw_params(struct snd_pcm_substream *substream, | |||
199 | r |= PSC_AC97CFG_RXSLOT_ENA(4); | 225 | r |= PSC_AC97CFG_RXSLOT_ENA(4); |
200 | } | 226 | } |
201 | 227 | ||
202 | /* finally enable the AC97 controller again */ | 228 | /* do we need to poke the hardware? */ |
229 | if (!(r ^ ro)) | ||
230 | goto out; | ||
231 | |||
232 | /* ac97 engine is about to be disabled */ | ||
233 | mutex_lock(&pscdata->lock); | ||
234 | |||
235 | /* disable AC97 device controller first... */ | ||
236 | au_writel(r & ~PSC_AC97CFG_DE_ENABLE, AC97_CFG(pscdata)); | ||
237 | au_sync(); | ||
238 | |||
239 | /* ...wait for it... */ | ||
240 | while (au_readl(AC97_STAT(pscdata)) & PSC_AC97STAT_DR) | ||
241 | asm volatile ("nop"); | ||
242 | |||
243 | /* ...write config... */ | ||
244 | au_writel(r, AC97_CFG(pscdata)); | ||
245 | au_sync(); | ||
246 | |||
247 | /* ...enable the AC97 controller again... */ | ||
203 | au_writel(r | PSC_AC97CFG_DE_ENABLE, AC97_CFG(pscdata)); | 248 | au_writel(r | PSC_AC97CFG_DE_ENABLE, AC97_CFG(pscdata)); |
204 | au_sync(); | 249 | au_sync(); |
205 | 250 | ||
251 | /* ...and wait for ready bit */ | ||
252 | while (!(au_readl(AC97_STAT(pscdata)) & PSC_AC97STAT_DR)) | ||
253 | asm volatile ("nop"); | ||
254 | |||
255 | mutex_unlock(&pscdata->lock); | ||
256 | |||
206 | pscdata->cfg = r; | 257 | pscdata->cfg = r; |
207 | pscdata->rate = params_rate(params); | 258 | pscdata->rate = params_rate(params); |
208 | } | 259 | } |
209 | 260 | ||
261 | out: | ||
210 | return 0; | 262 | return 0; |
211 | } | 263 | } |
212 | 264 | ||
@@ -222,6 +274,8 @@ static int au1xpsc_ac97_trigger(struct snd_pcm_substream *substream, | |||
222 | switch (cmd) { | 274 | switch (cmd) { |
223 | case SNDRV_PCM_TRIGGER_START: | 275 | case SNDRV_PCM_TRIGGER_START: |
224 | case SNDRV_PCM_TRIGGER_RESUME: | 276 | case SNDRV_PCM_TRIGGER_RESUME: |
277 | au_writel(AC97PCR_CLRFIFO(stype), AC97_PCR(pscdata)); | ||
278 | au_sync(); | ||
225 | au_writel(AC97PCR_START(stype), AC97_PCR(pscdata)); | 279 | au_writel(AC97PCR_START(stype), AC97_PCR(pscdata)); |
226 | au_sync(); | 280 | au_sync(); |
227 | break; | 281 | break; |
@@ -229,6 +283,13 @@ static int au1xpsc_ac97_trigger(struct snd_pcm_substream *substream, | |||
229 | case SNDRV_PCM_TRIGGER_SUSPEND: | 283 | case SNDRV_PCM_TRIGGER_SUSPEND: |
230 | au_writel(AC97PCR_STOP(stype), AC97_PCR(pscdata)); | 284 | au_writel(AC97PCR_STOP(stype), AC97_PCR(pscdata)); |
231 | au_sync(); | 285 | au_sync(); |
286 | |||
287 | while (au_readl(AC97_STAT(pscdata)) & AC97STAT_BUSY(stype)) | ||
288 | asm volatile ("nop"); | ||
289 | |||
290 | au_writel(AC97PCR_CLRFIFO(stype), AC97_PCR(pscdata)); | ||
291 | au_sync(); | ||
292 | |||
232 | break; | 293 | break; |
233 | default: | 294 | default: |
234 | ret = -EINVAL; | 295 | ret = -EINVAL; |
@@ -251,6 +312,8 @@ static int au1xpsc_ac97_probe(struct platform_device *pdev, | |||
251 | if (!au1xpsc_ac97_workdata) | 312 | if (!au1xpsc_ac97_workdata) |
252 | return -ENOMEM; | 313 | return -ENOMEM; |
253 | 314 | ||
315 | mutex_init(&au1xpsc_ac97_workdata->lock); | ||
316 | |||
254 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 317 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
255 | if (!r) { | 318 | if (!r) { |
256 | ret = -ENODEV; | 319 | ret = -ENODEV; |
@@ -269,9 +332,9 @@ static int au1xpsc_ac97_probe(struct platform_device *pdev, | |||
269 | goto out1; | 332 | goto out1; |
270 | 333 | ||
271 | /* configuration: max dma trigger threshold, enable ac97 */ | 334 | /* configuration: max dma trigger threshold, enable ac97 */ |
272 | au1xpsc_ac97_workdata->cfg = PSC_AC97CFG_RT_FIFO8 | | 335 | au1xpsc_ac97_workdata->cfg = PSC_AC97CFG_RT_FIFO8 | |
273 | PSC_AC97CFG_TT_FIFO8 | | 336 | PSC_AC97CFG_TT_FIFO8 | |
274 | PSC_AC97CFG_DE_ENABLE; | 337 | PSC_AC97CFG_DE_ENABLE; |
275 | 338 | ||
276 | /* preserve PSC clock source set up by platform (dev.platform_data | 339 | /* preserve PSC clock source set up by platform (dev.platform_data |
277 | * is already occupied by soc layer) | 340 | * is already occupied by soc layer) |
@@ -386,4 +449,4 @@ module_exit(au1xpsc_ac97_exit); | |||
386 | 449 | ||
387 | MODULE_LICENSE("GPL"); | 450 | MODULE_LICENSE("GPL"); |
388 | MODULE_DESCRIPTION("Au12x0/Au1550 PSC AC97 ALSA ASoC audio driver"); | 451 | MODULE_DESCRIPTION("Au12x0/Au1550 PSC AC97 ALSA ASoC audio driver"); |
389 | MODULE_AUTHOR("Manuel Lauss <mano@roarinelk.homelinux.net>"); | 452 | MODULE_AUTHOR("Manuel Lauss <manuel.lauss@gmail.com>"); |
diff --git a/sound/soc/au1x/psc.h b/sound/soc/au1x/psc.h index 8fdb1a04a07b..3f474e8ed4f6 100644 --- a/sound/soc/au1x/psc.h +++ b/sound/soc/au1x/psc.h | |||
@@ -29,6 +29,7 @@ struct au1xpsc_audio_data { | |||
29 | 29 | ||
30 | unsigned long pm[2]; | 30 | unsigned long pm[2]; |
31 | struct resource *ioarea; | 31 | struct resource *ioarea; |
32 | struct mutex lock; | ||
32 | }; | 33 | }; |
33 | 34 | ||
34 | #define PCM_TX 0 | 35 | #define PCM_TX 0 |
diff --git a/sound/soc/blackfin/bf5xx-ac97.c b/sound/soc/blackfin/bf5xx-ac97.c index 2758b9017a7f..e69322978739 100644 --- a/sound/soc/blackfin/bf5xx-ac97.c +++ b/sound/soc/blackfin/bf5xx-ac97.c | |||
@@ -277,7 +277,11 @@ static int bf5xx_ac97_resume(struct snd_soc_dai *dai) | |||
277 | if (!dai->active) | 277 | if (!dai->active) |
278 | return 0; | 278 | return 0; |
279 | 279 | ||
280 | #if defined(CONFIG_SND_BF5XX_MULTICHAN_SUPPORT) | ||
281 | ret = sport_set_multichannel(sport, 16, 0x3FF, 1); | ||
282 | #else | ||
280 | ret = sport_set_multichannel(sport, 16, 0x1F, 1); | 283 | ret = sport_set_multichannel(sport, 16, 0x1F, 1); |
284 | #endif | ||
281 | if (ret) { | 285 | if (ret) { |
282 | pr_err("SPORT is busy!\n"); | 286 | pr_err("SPORT is busy!\n"); |
283 | return -EBUSY; | 287 | return -EBUSY; |
@@ -334,7 +338,11 @@ static int bf5xx_ac97_probe(struct platform_device *pdev, | |||
334 | goto sport_err; | 338 | goto sport_err; |
335 | } | 339 | } |
336 | /*SPORT works in TDM mode to simulate AC97 transfers*/ | 340 | /*SPORT works in TDM mode to simulate AC97 transfers*/ |
341 | #if defined(CONFIG_SND_BF5XX_MULTICHAN_SUPPORT) | ||
342 | ret = sport_set_multichannel(sport_handle, 16, 0x3FF, 1); | ||
343 | #else | ||
337 | ret = sport_set_multichannel(sport_handle, 16, 0x1F, 1); | 344 | ret = sport_set_multichannel(sport_handle, 16, 0x1F, 1); |
345 | #endif | ||
338 | if (ret) { | 346 | if (ret) { |
339 | pr_err("SPORT is busy!\n"); | 347 | pr_err("SPORT is busy!\n"); |
340 | ret = -EBUSY; | 348 | ret = -EBUSY; |
diff --git a/sound/soc/blackfin/bf5xx-ac97.h b/sound/soc/blackfin/bf5xx-ac97.h index 3f2a911fe0cb..a1f97dd809d6 100644 --- a/sound/soc/blackfin/bf5xx-ac97.h +++ b/sound/soc/blackfin/bf5xx-ac97.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * linux/sound/arm/bf5xx-ac97.h | 2 | * sound/soc/blackfin/bf5xx-ac97.h |
3 | * | 3 | * |
4 | * This program is free software; you can redistribute it and/or modify | 4 | * This program is free software; you can redistribute it and/or modify |
5 | * it under the terms of the GNU General Public License version 2 as | 5 | * it under the terms of the GNU General Public License version 2 as |
diff --git a/sound/soc/blackfin/bf5xx-i2s.c b/sound/soc/blackfin/bf5xx-i2s.c index 876abade27e1..1e9d161c76c4 100644 --- a/sound/soc/blackfin/bf5xx-i2s.c +++ b/sound/soc/blackfin/bf5xx-i2s.c | |||
@@ -227,7 +227,8 @@ static int bf5xx_i2s_probe(struct platform_device *pdev, | |||
227 | return 0; | 227 | return 0; |
228 | } | 228 | } |
229 | 229 | ||
230 | static void bf5xx_i2s_remove(struct snd_soc_dai *dai) | 230 | static void bf5xx_i2s_remove(struct platform_device *pdev, |
231 | struct snd_soc_dai *dai) | ||
231 | { | 232 | { |
232 | pr_debug("%s enter\n", __func__); | 233 | pr_debug("%s enter\n", __func__); |
233 | peripheral_free_list(&sport_req[sport_num][0]); | 234 | peripheral_free_list(&sport_req[sport_num][0]); |
@@ -236,36 +237,31 @@ static void bf5xx_i2s_remove(struct snd_soc_dai *dai) | |||
236 | #ifdef CONFIG_PM | 237 | #ifdef CONFIG_PM |
237 | static int bf5xx_i2s_suspend(struct snd_soc_dai *dai) | 238 | static int bf5xx_i2s_suspend(struct snd_soc_dai *dai) |
238 | { | 239 | { |
239 | struct sport_device *sport = | ||
240 | (struct sport_device *)dai->private_data; | ||
241 | 240 | ||
242 | pr_debug("%s : sport %d\n", __func__, dai->id); | 241 | pr_debug("%s : sport %d\n", __func__, dai->id); |
243 | if (!dai->active) | 242 | |
244 | return 0; | ||
245 | if (dai->capture.active) | 243 | if (dai->capture.active) |
246 | sport_rx_stop(sport); | 244 | sport_rx_stop(sport_handle); |
247 | if (dai->playback.active) | 245 | if (dai->playback.active) |
248 | sport_tx_stop(sport); | 246 | sport_tx_stop(sport_handle); |
249 | return 0; | 247 | return 0; |
250 | } | 248 | } |
251 | 249 | ||
252 | static int bf5xx_i2s_resume(struct snd_soc_dai *dai) | 250 | static int bf5xx_i2s_resume(struct snd_soc_dai *dai) |
253 | { | 251 | { |
254 | int ret; | 252 | int ret; |
255 | struct sport_device *sport = | ||
256 | (struct sport_device *)dai->private_data; | ||
257 | 253 | ||
258 | pr_debug("%s : sport %d\n", __func__, dai->id); | 254 | pr_debug("%s : sport %d\n", __func__, dai->id); |
259 | if (!dai->active) | ||
260 | return 0; | ||
261 | 255 | ||
262 | ret = sport_config_rx(sport, RFSR | RCKFE, RSFSE|0x1f, 0, 0); | 256 | ret = sport_config_rx(sport_handle, bf5xx_i2s.rcr1, |
257 | bf5xx_i2s.rcr2, 0, 0); | ||
263 | if (ret) { | 258 | if (ret) { |
264 | pr_err("SPORT is busy!\n"); | 259 | pr_err("SPORT is busy!\n"); |
265 | return -EBUSY; | 260 | return -EBUSY; |
266 | } | 261 | } |
267 | 262 | ||
268 | ret = sport_config_tx(sport, TFSR | TCKFE, TSFSE|0x1f, 0, 0); | 263 | ret = sport_config_tx(sport_handle, bf5xx_i2s.tcr1, |
264 | bf5xx_i2s.tcr2, 0, 0); | ||
269 | if (ret) { | 265 | if (ret) { |
270 | pr_err("SPORT is busy!\n"); | 266 | pr_err("SPORT is busy!\n"); |
271 | return -EBUSY; | 267 | return -EBUSY; |
diff --git a/sound/soc/blackfin/bf5xx-i2s.h b/sound/soc/blackfin/bf5xx-i2s.h index 7107d1a0b06b..264ecdcba35a 100644 --- a/sound/soc/blackfin/bf5xx-i2s.h +++ b/sound/soc/blackfin/bf5xx-i2s.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * linux/sound/arm/bf5xx-i2s.h | 2 | * sound/soc/blackfin/bf5xx-i2s.h |
3 | * | 3 | * |
4 | * This program is free software; you can redistribute it and/or modify | 4 | * This program is free software; you can redistribute it and/or modify |
5 | * it under the terms of the GNU General Public License version 2 as | 5 | * it under the terms of the GNU General Public License version 2 as |
diff --git a/sound/soc/blackfin/bf5xx-sport.c b/sound/soc/blackfin/bf5xx-sport.c index 469ce7fab20c..99051ff0954e 100644 --- a/sound/soc/blackfin/bf5xx-sport.c +++ b/sound/soc/blackfin/bf5xx-sport.c | |||
@@ -326,7 +326,7 @@ static inline int sport_hook_tx_dummy(struct sport_device *sport) | |||
326 | 326 | ||
327 | int sport_tx_start(struct sport_device *sport) | 327 | int sport_tx_start(struct sport_device *sport) |
328 | { | 328 | { |
329 | unsigned flags; | 329 | unsigned long flags; |
330 | pr_debug("%s: tx_run:%d, rx_run:%d\n", __func__, | 330 | pr_debug("%s: tx_run:%d, rx_run:%d\n", __func__, |
331 | sport->tx_run, sport->rx_run); | 331 | sport->tx_run, sport->rx_run); |
332 | if (sport->tx_run) | 332 | if (sport->tx_run) |
diff --git a/sound/soc/codecs/ad1836.c b/sound/soc/codecs/ad1836.c index 3612bb92df90..01343dc984fd 100644 --- a/sound/soc/codecs/ad1836.c +++ b/sound/soc/codecs/ad1836.c | |||
@@ -18,7 +18,6 @@ | |||
18 | 18 | ||
19 | #include <linux/init.h> | 19 | #include <linux/init.h> |
20 | #include <linux/module.h> | 20 | #include <linux/module.h> |
21 | #include <linux/version.h> | ||
22 | #include <linux/kernel.h> | 21 | #include <linux/kernel.h> |
23 | #include <linux/device.h> | 22 | #include <linux/device.h> |
24 | #include <sound/core.h> | 23 | #include <sound/core.h> |
diff --git a/sound/soc/codecs/ad1938.c b/sound/soc/codecs/ad1938.c index e62b27701a49..9a049a1995a3 100644 --- a/sound/soc/codecs/ad1938.c +++ b/sound/soc/codecs/ad1938.c | |||
@@ -28,7 +28,6 @@ | |||
28 | 28 | ||
29 | #include <linux/init.h> | 29 | #include <linux/init.h> |
30 | #include <linux/module.h> | 30 | #include <linux/module.h> |
31 | #include <linux/version.h> | ||
32 | #include <linux/kernel.h> | 31 | #include <linux/kernel.h> |
33 | #include <linux/device.h> | 32 | #include <linux/device.h> |
34 | #include <sound/core.h> | 33 | #include <sound/core.h> |
diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c index 0ebd99b7493e..3f7e8a8b387e 100644 --- a/sound/soc/codecs/wm8350.c +++ b/sound/soc/codecs/wm8350.c | |||
@@ -612,7 +612,7 @@ SOC_DAPM_SINGLE("Switch", WM8350_BEEP_VOLUME, 15, 1, 1); | |||
612 | 612 | ||
613 | /* Out4 Capture Mux */ | 613 | /* Out4 Capture Mux */ |
614 | static const struct snd_kcontrol_new wm8350_out4_capture_controls = | 614 | static const struct snd_kcontrol_new wm8350_out4_capture_controls = |
615 | SOC_DAPM_ENUM("Route", wm8350_enum[8]); | 615 | SOC_DAPM_ENUM("Route", wm8350_enum[7]); |
616 | 616 | ||
617 | static const struct snd_soc_dapm_widget wm8350_dapm_widgets[] = { | 617 | static const struct snd_soc_dapm_widget wm8350_dapm_widgets[] = { |
618 | 618 | ||
diff --git a/sound/soc/codecs/wm8974.c b/sound/soc/codecs/wm8974.c index fa4d85bd048b..93d66e30f109 100644 --- a/sound/soc/codecs/wm8974.c +++ b/sound/soc/codecs/wm8974.c | |||
@@ -12,7 +12,6 @@ | |||
12 | 12 | ||
13 | #include <linux/module.h> | 13 | #include <linux/module.h> |
14 | #include <linux/moduleparam.h> | 14 | #include <linux/moduleparam.h> |
15 | #include <linux/version.h> | ||
16 | #include <linux/kernel.h> | 15 | #include <linux/kernel.h> |
17 | #include <linux/init.h> | 16 | #include <linux/init.h> |
18 | #include <linux/delay.h> | 17 | #include <linux/delay.h> |
diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c index eca22d7829d2..7a06c0a86665 100644 --- a/sound/soc/davinci/davinci-mcasp.c +++ b/sound/soc/davinci/davinci-mcasp.c | |||
@@ -512,34 +512,49 @@ static int davinci_config_channel_size(struct davinci_audio_dev *dev, | |||
512 | int channel_size) | 512 | int channel_size) |
513 | { | 513 | { |
514 | u32 fmt = 0; | 514 | u32 fmt = 0; |
515 | u32 mask, rotate; | ||
515 | 516 | ||
516 | switch (channel_size) { | 517 | switch (channel_size) { |
517 | case DAVINCI_AUDIO_WORD_8: | 518 | case DAVINCI_AUDIO_WORD_8: |
518 | fmt = 0x03; | 519 | fmt = 0x03; |
520 | rotate = 6; | ||
521 | mask = 0x000000ff; | ||
519 | break; | 522 | break; |
520 | 523 | ||
521 | case DAVINCI_AUDIO_WORD_12: | 524 | case DAVINCI_AUDIO_WORD_12: |
522 | fmt = 0x05; | 525 | fmt = 0x05; |
526 | rotate = 5; | ||
527 | mask = 0x00000fff; | ||
523 | break; | 528 | break; |
524 | 529 | ||
525 | case DAVINCI_AUDIO_WORD_16: | 530 | case DAVINCI_AUDIO_WORD_16: |
526 | fmt = 0x07; | 531 | fmt = 0x07; |
532 | rotate = 4; | ||
533 | mask = 0x0000ffff; | ||
527 | break; | 534 | break; |
528 | 535 | ||
529 | case DAVINCI_AUDIO_WORD_20: | 536 | case DAVINCI_AUDIO_WORD_20: |
530 | fmt = 0x09; | 537 | fmt = 0x09; |
538 | rotate = 3; | ||
539 | mask = 0x000fffff; | ||
531 | break; | 540 | break; |
532 | 541 | ||
533 | case DAVINCI_AUDIO_WORD_24: | 542 | case DAVINCI_AUDIO_WORD_24: |
534 | fmt = 0x0B; | 543 | fmt = 0x0B; |
544 | rotate = 2; | ||
545 | mask = 0x00ffffff; | ||
535 | break; | 546 | break; |
536 | 547 | ||
537 | case DAVINCI_AUDIO_WORD_28: | 548 | case DAVINCI_AUDIO_WORD_28: |
538 | fmt = 0x0D; | 549 | fmt = 0x0D; |
550 | rotate = 1; | ||
551 | mask = 0x0fffffff; | ||
539 | break; | 552 | break; |
540 | 553 | ||
541 | case DAVINCI_AUDIO_WORD_32: | 554 | case DAVINCI_AUDIO_WORD_32: |
542 | fmt = 0x0F; | 555 | fmt = 0x0F; |
556 | rotate = 0; | ||
557 | mask = 0xffffffff; | ||
543 | break; | 558 | break; |
544 | 559 | ||
545 | default: | 560 | default: |
@@ -550,6 +565,13 @@ static int davinci_config_channel_size(struct davinci_audio_dev *dev, | |||
550 | RXSSZ(fmt), RXSSZ(0x0F)); | 565 | RXSSZ(fmt), RXSSZ(0x0F)); |
551 | mcasp_mod_bits(dev->base + DAVINCI_MCASP_TXFMT_REG, | 566 | mcasp_mod_bits(dev->base + DAVINCI_MCASP_TXFMT_REG, |
552 | TXSSZ(fmt), TXSSZ(0x0F)); | 567 | TXSSZ(fmt), TXSSZ(0x0F)); |
568 | mcasp_mod_bits(dev->base + DAVINCI_MCASP_TXFMT_REG, TXROT(rotate), | ||
569 | TXROT(7)); | ||
570 | mcasp_mod_bits(dev->base + DAVINCI_MCASP_RXFMT_REG, RXROT(rotate), | ||
571 | RXROT(7)); | ||
572 | mcasp_set_reg(dev->base + DAVINCI_MCASP_TXMASK_REG, mask); | ||
573 | mcasp_set_reg(dev->base + DAVINCI_MCASP_RXMASK_REG, mask); | ||
574 | |||
553 | return 0; | 575 | return 0; |
554 | } | 576 | } |
555 | 577 | ||
@@ -638,7 +660,6 @@ static void davinci_hw_param(struct davinci_audio_dev *dev, int stream) | |||
638 | printk(KERN_ERR "playback tdm slot %d not supported\n", | 660 | printk(KERN_ERR "playback tdm slot %d not supported\n", |
639 | dev->tdm_slots); | 661 | dev->tdm_slots); |
640 | 662 | ||
641 | mcasp_set_reg(dev->base + DAVINCI_MCASP_TXMASK_REG, 0xFFFFFFFF); | ||
642 | mcasp_clr_bits(dev->base + DAVINCI_MCASP_TXFMCTL_REG, FSXDUR); | 663 | mcasp_clr_bits(dev->base + DAVINCI_MCASP_TXFMCTL_REG, FSXDUR); |
643 | } else { | 664 | } else { |
644 | /* bit stream is MSB first with no delay */ | 665 | /* bit stream is MSB first with no delay */ |
@@ -655,7 +676,6 @@ static void davinci_hw_param(struct davinci_audio_dev *dev, int stream) | |||
655 | printk(KERN_ERR "capture tdm slot %d not supported\n", | 676 | printk(KERN_ERR "capture tdm slot %d not supported\n", |
656 | dev->tdm_slots); | 677 | dev->tdm_slots); |
657 | 678 | ||
658 | mcasp_set_reg(dev->base + DAVINCI_MCASP_RXMASK_REG, 0xFFFFFFFF); | ||
659 | mcasp_clr_bits(dev->base + DAVINCI_MCASP_RXFMCTL_REG, FSRDUR); | 679 | mcasp_clr_bits(dev->base + DAVINCI_MCASP_RXFMCTL_REG, FSRDUR); |
660 | } | 680 | } |
661 | } | 681 | } |
diff --git a/sound/soc/fsl/mpc5200_dma.c b/sound/soc/fsl/mpc5200_dma.c index 9ff62e3a9b1d..6096d22283e6 100644 --- a/sound/soc/fsl/mpc5200_dma.c +++ b/sound/soc/fsl/mpc5200_dma.c | |||
@@ -447,6 +447,7 @@ int mpc5200_audio_dma_create(struct of_device *op) | |||
447 | int size, irq, rc; | 447 | int size, irq, rc; |
448 | const __be32 *prop; | 448 | const __be32 *prop; |
449 | void __iomem *regs; | 449 | void __iomem *regs; |
450 | int ret; | ||
450 | 451 | ||
451 | /* Fetch the registers and IRQ of the PSC */ | 452 | /* Fetch the registers and IRQ of the PSC */ |
452 | irq = irq_of_parse_and_map(op->node, 0); | 453 | irq = irq_of_parse_and_map(op->node, 0); |
@@ -463,14 +464,16 @@ int mpc5200_audio_dma_create(struct of_device *op) | |||
463 | /* Allocate and initialize the driver private data */ | 464 | /* Allocate and initialize the driver private data */ |
464 | psc_dma = kzalloc(sizeof *psc_dma, GFP_KERNEL); | 465 | psc_dma = kzalloc(sizeof *psc_dma, GFP_KERNEL); |
465 | if (!psc_dma) { | 466 | if (!psc_dma) { |
466 | iounmap(regs); | 467 | ret = -ENOMEM; |
467 | return -ENOMEM; | 468 | goto out_unmap; |
468 | } | 469 | } |
469 | 470 | ||
470 | /* Get the PSC ID */ | 471 | /* Get the PSC ID */ |
471 | prop = of_get_property(op->node, "cell-index", &size); | 472 | prop = of_get_property(op->node, "cell-index", &size); |
472 | if (!prop || size < sizeof *prop) | 473 | if (!prop || size < sizeof *prop) { |
473 | return -ENODEV; | 474 | ret = -ENODEV; |
475 | goto out_free; | ||
476 | } | ||
474 | 477 | ||
475 | spin_lock_init(&psc_dma->lock); | 478 | spin_lock_init(&psc_dma->lock); |
476 | mutex_init(&psc_dma->mutex); | 479 | mutex_init(&psc_dma->mutex); |
@@ -493,9 +496,8 @@ int mpc5200_audio_dma_create(struct of_device *op) | |||
493 | if (!psc_dma->capture.bcom_task || | 496 | if (!psc_dma->capture.bcom_task || |
494 | !psc_dma->playback.bcom_task) { | 497 | !psc_dma->playback.bcom_task) { |
495 | dev_err(&op->dev, "Could not allocate bestcomm tasks\n"); | 498 | dev_err(&op->dev, "Could not allocate bestcomm tasks\n"); |
496 | iounmap(regs); | 499 | ret = -ENODEV; |
497 | kfree(psc_dma); | 500 | goto out_free; |
498 | return -ENODEV; | ||
499 | } | 501 | } |
500 | 502 | ||
501 | /* Disable all interrupts and reset the PSC */ | 503 | /* Disable all interrupts and reset the PSC */ |
@@ -537,12 +539,8 @@ int mpc5200_audio_dma_create(struct of_device *op) | |||
537 | &psc_dma_bcom_irq_tx, IRQF_SHARED, | 539 | &psc_dma_bcom_irq_tx, IRQF_SHARED, |
538 | "psc-dma-playback", &psc_dma->playback); | 540 | "psc-dma-playback", &psc_dma->playback); |
539 | if (rc) { | 541 | if (rc) { |
540 | free_irq(psc_dma->irq, psc_dma); | 542 | ret = -ENODEV; |
541 | free_irq(psc_dma->capture.irq, | 543 | goto out_irq; |
542 | &psc_dma->capture); | ||
543 | free_irq(psc_dma->playback.irq, | ||
544 | &psc_dma->playback); | ||
545 | return -ENODEV; | ||
546 | } | 544 | } |
547 | 545 | ||
548 | /* Save what we've done so it can be found again later */ | 546 | /* Save what we've done so it can be found again later */ |
@@ -550,6 +548,15 @@ int mpc5200_audio_dma_create(struct of_device *op) | |||
550 | 548 | ||
551 | /* Tell the ASoC OF helpers about it */ | 549 | /* Tell the ASoC OF helpers about it */ |
552 | return snd_soc_register_platform(&mpc5200_audio_dma_platform); | 550 | return snd_soc_register_platform(&mpc5200_audio_dma_platform); |
551 | out_irq: | ||
552 | free_irq(psc_dma->irq, psc_dma); | ||
553 | free_irq(psc_dma->capture.irq, &psc_dma->capture); | ||
554 | free_irq(psc_dma->playback.irq, &psc_dma->playback); | ||
555 | out_free: | ||
556 | kfree(psc_dma); | ||
557 | out_unmap: | ||
558 | iounmap(regs); | ||
559 | return ret; | ||
553 | } | 560 | } |
554 | EXPORT_SYMBOL_GPL(mpc5200_audio_dma_create); | 561 | EXPORT_SYMBOL_GPL(mpc5200_audio_dma_create); |
555 | 562 | ||
diff --git a/sound/soc/s3c24xx/s3c-i2s-v2.c b/sound/soc/s3c24xx/s3c-i2s-v2.c index 819c3c086d69..11c45a37c631 100644 --- a/sound/soc/s3c24xx/s3c-i2s-v2.c +++ b/sound/soc/s3c24xx/s3c-i2s-v2.c | |||
@@ -230,6 +230,8 @@ static void s3c2412_snd_rxctrl(struct s3c_i2sv2_info *i2s, int on) | |||
230 | pr_debug("%s: IIS: CON=%x MOD=%x FIC=%x\n", __func__, con, mod, fic); | 230 | pr_debug("%s: IIS: CON=%x MOD=%x FIC=%x\n", __func__, con, mod, fic); |
231 | } | 231 | } |
232 | 232 | ||
233 | #define msecs_to_loops(t) (loops_per_jiffy / 1000 * HZ * t) | ||
234 | |||
233 | /* | 235 | /* |
234 | * Wait for the LR signal to allow synchronisation to the L/R clock | 236 | * Wait for the LR signal to allow synchronisation to the L/R clock |
235 | * from the codec. May only be needed for slave mode. | 237 | * from the codec. May only be needed for slave mode. |
@@ -237,19 +239,21 @@ static void s3c2412_snd_rxctrl(struct s3c_i2sv2_info *i2s, int on) | |||
237 | static int s3c2412_snd_lrsync(struct s3c_i2sv2_info *i2s) | 239 | static int s3c2412_snd_lrsync(struct s3c_i2sv2_info *i2s) |
238 | { | 240 | { |
239 | u32 iiscon; | 241 | u32 iiscon; |
240 | unsigned long timeout = jiffies + msecs_to_jiffies(5); | 242 | unsigned long loops = msecs_to_loops(5); |
241 | 243 | ||
242 | pr_debug("Entered %s\n", __func__); | 244 | pr_debug("Entered %s\n", __func__); |
243 | 245 | ||
244 | while (1) { | 246 | while (--loops) { |
245 | iiscon = readl(i2s->regs + S3C2412_IISCON); | 247 | iiscon = readl(i2s->regs + S3C2412_IISCON); |
246 | if (iiscon & S3C2412_IISCON_LRINDEX) | 248 | if (iiscon & S3C2412_IISCON_LRINDEX) |
247 | break; | 249 | break; |
248 | 250 | ||
249 | if (timeout < jiffies) { | 251 | cpu_relax(); |
250 | printk(KERN_ERR "%s: timeout\n", __func__); | 252 | } |
251 | return -ETIMEDOUT; | 253 | |
252 | } | 254 | if (!loops) { |
255 | printk(KERN_ERR "%s: timeout\n", __func__); | ||
256 | return -ETIMEDOUT; | ||
253 | } | 257 | } |
254 | 258 | ||
255 | return 0; | 259 | return 0; |
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 37f7adeae323..9babda559c92 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c | |||
@@ -1135,9 +1135,10 @@ static ssize_t dapm_widget_power_read_file(struct file *file, | |||
1135 | ret = snprintf(buf, PAGE_SIZE, "%s: %s in %d out %d\n", | 1135 | ret = snprintf(buf, PAGE_SIZE, "%s: %s in %d out %d\n", |
1136 | w->name, w->power ? "On" : "Off", in, out); | 1136 | w->name, w->power ? "On" : "Off", in, out); |
1137 | 1137 | ||
1138 | if (w->active && w->sname) | 1138 | if (w->sname) |
1139 | ret += snprintf(buf, PAGE_SIZE - ret, " stream %s active\n", | 1139 | ret += snprintf(buf + ret, PAGE_SIZE - ret, " stream %s %s\n", |
1140 | w->sname); | 1140 | w->sname, |
1141 | w->active ? "active" : "inactive"); | ||
1141 | 1142 | ||
1142 | list_for_each_entry(p, &w->sources, list_sink) { | 1143 | list_for_each_entry(p, &w->sources, list_sink) { |
1143 | if (p->connected && !p->connected(w, p->sink)) | 1144 | if (p->connected && !p->connected(w, p->sink)) |