diff options
-rw-r--r-- | include/sound/pxa2xx-lib.h | 15 | ||||
-rw-r--r-- | sound/arm/pxa2xx-ac97-lib.c | 71 | ||||
-rw-r--r-- | sound/soc/codecs/twl4030.c | 12 | ||||
-rw-r--r-- | sound/soc/pxa/pxa2xx-ac97.c | 16 | ||||
-rw-r--r-- | sound/soc/s3c24xx/s3c64xx-i2s.c | 8 | ||||
-rw-r--r-- | sound/soc/sh/hac.c | 12 | ||||
-rw-r--r-- | sound/soc/soc-core.c | 3 |
7 files changed, 113 insertions, 24 deletions
diff --git a/include/sound/pxa2xx-lib.h b/include/sound/pxa2xx-lib.h index 2fd3d251d9a5..2c894b600e5b 100644 --- a/include/sound/pxa2xx-lib.h +++ b/include/sound/pxa2xx-lib.h | |||
@@ -42,4 +42,19 @@ extern int pxa2xx_ac97_hw_resume(void); | |||
42 | extern int pxa2xx_ac97_hw_probe(struct platform_device *dev); | 42 | extern int pxa2xx_ac97_hw_probe(struct platform_device *dev); |
43 | extern void pxa2xx_ac97_hw_remove(struct platform_device *dev); | 43 | extern void pxa2xx_ac97_hw_remove(struct platform_device *dev); |
44 | 44 | ||
45 | /* AC97 platform_data */ | ||
46 | /** | ||
47 | * struct pxa2xx_ac97_platform_data - pxa ac97 platform data | ||
48 | * @reset_gpio: AC97 reset gpio (normally gpio113 or gpio95) | ||
49 | * a -1 value means no gpio will be used for reset | ||
50 | * | ||
51 | * Platform data should only be specified for pxa27x CPUs where a silicon bug | ||
52 | * prevents correct operation of the reset line. If not specified, the default | ||
53 | * behaviour is to consider gpio 113 as the AC97 reset line, which is the | ||
54 | * default on most boards. | ||
55 | */ | ||
56 | struct pxa2xx_ac97_platform_data { | ||
57 | int reset_gpio; | ||
58 | }; | ||
59 | |||
45 | #endif | 60 | #endif |
diff --git a/sound/arm/pxa2xx-ac97-lib.c b/sound/arm/pxa2xx-ac97-lib.c index 35afd0c33be5..d721ea7cae8f 100644 --- a/sound/arm/pxa2xx-ac97-lib.c +++ b/sound/arm/pxa2xx-ac97-lib.c | |||
@@ -31,6 +31,7 @@ static DECLARE_WAIT_QUEUE_HEAD(gsr_wq); | |||
31 | static volatile long gsr_bits; | 31 | static volatile long gsr_bits; |
32 | static struct clk *ac97_clk; | 32 | static struct clk *ac97_clk; |
33 | static struct clk *ac97conf_clk; | 33 | static struct clk *ac97conf_clk; |
34 | static int reset_gpio; | ||
34 | 35 | ||
35 | /* | 36 | /* |
36 | * Beware PXA27x bugs: | 37 | * Beware PXA27x bugs: |
@@ -42,6 +43,45 @@ static struct clk *ac97conf_clk; | |||
42 | * 1 jiffy timeout if interrupt never comes). | 43 | * 1 jiffy timeout if interrupt never comes). |
43 | */ | 44 | */ |
44 | 45 | ||
46 | enum { | ||
47 | RESETGPIO_FORCE_HIGH, | ||
48 | RESETGPIO_FORCE_LOW, | ||
49 | RESETGPIO_NORMAL_ALTFUNC | ||
50 | }; | ||
51 | |||
52 | /** | ||
53 | * set_resetgpio_mode - computes and sets the AC97_RESET gpio mode on PXA | ||
54 | * @mode: chosen action | ||
55 | * | ||
56 | * As the PXA27x CPUs suffer from a AC97 bug, a manual control of the reset line | ||
57 | * must be done to insure proper work of AC97 reset line. This function | ||
58 | * computes the correct gpio_mode for further use by reset functions, and | ||
59 | * applied the change through pxa_gpio_mode. | ||
60 | */ | ||
61 | static void set_resetgpio_mode(int resetgpio_action) | ||
62 | { | ||
63 | int mode = 0; | ||
64 | |||
65 | if (reset_gpio) | ||
66 | switch (resetgpio_action) { | ||
67 | case RESETGPIO_NORMAL_ALTFUNC: | ||
68 | if (reset_gpio == 113) | ||
69 | mode = 113 | GPIO_OUT | GPIO_DFLT_LOW; | ||
70 | if (reset_gpio == 95) | ||
71 | mode = 95 | GPIO_ALT_FN_1_OUT; | ||
72 | break; | ||
73 | case RESETGPIO_FORCE_LOW: | ||
74 | mode = reset_gpio | GPIO_OUT | GPIO_DFLT_LOW; | ||
75 | break; | ||
76 | case RESETGPIO_FORCE_HIGH: | ||
77 | mode = reset_gpio | GPIO_OUT | GPIO_DFLT_HIGH; | ||
78 | break; | ||
79 | }; | ||
80 | |||
81 | if (mode) | ||
82 | pxa_gpio_mode(mode); | ||
83 | } | ||
84 | |||
45 | unsigned short pxa2xx_ac97_read(struct snd_ac97 *ac97, unsigned short reg) | 85 | unsigned short pxa2xx_ac97_read(struct snd_ac97 *ac97, unsigned short reg) |
46 | { | 86 | { |
47 | unsigned short val = -1; | 87 | unsigned short val = -1; |
@@ -137,10 +177,10 @@ static inline void pxa_ac97_warm_pxa27x(void) | |||
137 | 177 | ||
138 | /* warm reset broken on Bulverde, | 178 | /* warm reset broken on Bulverde, |
139 | so manually keep AC97 reset high */ | 179 | so manually keep AC97 reset high */ |
140 | pxa_gpio_mode(113 | GPIO_OUT | GPIO_DFLT_HIGH); | 180 | set_resetgpio_mode(RESETGPIO_FORCE_HIGH); |
141 | udelay(10); | 181 | udelay(10); |
142 | GCR |= GCR_WARM_RST; | 182 | GCR |= GCR_WARM_RST; |
143 | pxa_gpio_mode(113 | GPIO_ALT_FN_2_OUT); | 183 | set_resetgpio_mode(RESETGPIO_NORMAL_ALTFUNC); |
144 | udelay(500); | 184 | udelay(500); |
145 | } | 185 | } |
146 | 186 | ||
@@ -308,8 +348,8 @@ int pxa2xx_ac97_hw_resume(void) | |||
308 | pxa_gpio_mode(GPIO29_SDATA_IN_AC97_MD); | 348 | pxa_gpio_mode(GPIO29_SDATA_IN_AC97_MD); |
309 | } | 349 | } |
310 | if (cpu_is_pxa27x()) { | 350 | if (cpu_is_pxa27x()) { |
311 | /* Use GPIO 113 as AC97 Reset on Bulverde */ | 351 | /* Use GPIO 113 or 95 as AC97 Reset on Bulverde */ |
312 | pxa_gpio_mode(113 | GPIO_ALT_FN_2_OUT); | 352 | set_resetgpio_mode(RESETGPIO_NORMAL_ALTFUNC); |
313 | } | 353 | } |
314 | clk_enable(ac97_clk); | 354 | clk_enable(ac97_clk); |
315 | return 0; | 355 | return 0; |
@@ -320,6 +360,27 @@ EXPORT_SYMBOL_GPL(pxa2xx_ac97_hw_resume); | |||
320 | int __devinit pxa2xx_ac97_hw_probe(struct platform_device *dev) | 360 | int __devinit pxa2xx_ac97_hw_probe(struct platform_device *dev) |
321 | { | 361 | { |
322 | int ret; | 362 | int ret; |
363 | struct pxa2xx_ac97_platform_data *pdata = dev->dev.platform_data; | ||
364 | |||
365 | if (pdata) { | ||
366 | switch (pdata->reset_gpio) { | ||
367 | case 95: | ||
368 | case 113: | ||
369 | reset_gpio = pdata->reset_gpio; | ||
370 | break; | ||
371 | case 0: | ||
372 | reset_gpio = 113; | ||
373 | break; | ||
374 | case -1: | ||
375 | break; | ||
376 | default: | ||
377 | dev_err(dev, "Invalid reset GPIO %d\n", | ||
378 | pdata->reset_gpio); | ||
379 | } | ||
380 | } else { | ||
381 | if (cpu_is_pxa27x()) | ||
382 | reset_gpio = 113; | ||
383 | } | ||
323 | 384 | ||
324 | if (cpu_is_pxa25x() || cpu_is_pxa27x()) { | 385 | if (cpu_is_pxa25x() || cpu_is_pxa27x()) { |
325 | pxa_gpio_mode(GPIO31_SYNC_AC97_MD); | 386 | pxa_gpio_mode(GPIO31_SYNC_AC97_MD); |
@@ -330,7 +391,7 @@ int __devinit pxa2xx_ac97_hw_probe(struct platform_device *dev) | |||
330 | 391 | ||
331 | if (cpu_is_pxa27x()) { | 392 | if (cpu_is_pxa27x()) { |
332 | /* Use GPIO 113 as AC97 Reset on Bulverde */ | 393 | /* Use GPIO 113 as AC97 Reset on Bulverde */ |
333 | pxa_gpio_mode(113 | GPIO_ALT_FN_2_OUT); | 394 | set_resetgpio_mode(RESETGPIO_NORMAL_ALTFUNC); |
334 | ac97conf_clk = clk_get(&dev->dev, "AC97CONFCLK"); | 395 | ac97conf_clk = clk_get(&dev->dev, "AC97CONFCLK"); |
335 | if (IS_ERR(ac97conf_clk)) { | 396 | if (IS_ERR(ac97conf_clk)) { |
336 | ret = PTR_ERR(ac97conf_clk); | 397 | ret = PTR_ERR(ac97conf_clk); |
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c index 86bb15cc82ce..97738e2ece04 100644 --- a/sound/soc/codecs/twl4030.c +++ b/sound/soc/codecs/twl4030.c | |||
@@ -1383,6 +1383,12 @@ static int twl4030_set_dai_fmt(struct snd_soc_dai *codec_dai, | |||
1383 | #define TWL4030_RATES (SNDRV_PCM_RATE_8000_48000) | 1383 | #define TWL4030_RATES (SNDRV_PCM_RATE_8000_48000) |
1384 | #define TWL4030_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FORMAT_S24_LE) | 1384 | #define TWL4030_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FORMAT_S24_LE) |
1385 | 1385 | ||
1386 | static struct snd_soc_dai_ops twl4030_dai_ops = { | ||
1387 | .hw_params = twl4030_hw_params, | ||
1388 | .set_sysclk = twl4030_set_dai_sysclk, | ||
1389 | .set_fmt = twl4030_set_dai_fmt, | ||
1390 | }; | ||
1391 | |||
1386 | struct snd_soc_dai twl4030_dai = { | 1392 | struct snd_soc_dai twl4030_dai = { |
1387 | .name = "twl4030", | 1393 | .name = "twl4030", |
1388 | .playback = { | 1394 | .playback = { |
@@ -1397,11 +1403,7 @@ struct snd_soc_dai twl4030_dai = { | |||
1397 | .channels_max = 2, | 1403 | .channels_max = 2, |
1398 | .rates = TWL4030_RATES, | 1404 | .rates = TWL4030_RATES, |
1399 | .formats = TWL4030_FORMATS,}, | 1405 | .formats = TWL4030_FORMATS,}, |
1400 | .ops = { | 1406 | .ops = &twl4030_dai_ops, |
1401 | .hw_params = twl4030_hw_params, | ||
1402 | .set_sysclk = twl4030_set_dai_sysclk, | ||
1403 | .set_fmt = twl4030_set_dai_fmt, | ||
1404 | } | ||
1405 | }; | 1407 | }; |
1406 | EXPORT_SYMBOL_GPL(twl4030_dai); | 1408 | EXPORT_SYMBOL_GPL(twl4030_dai); |
1407 | 1409 | ||
diff --git a/sound/soc/pxa/pxa2xx-ac97.c b/sound/soc/pxa/pxa2xx-ac97.c index cf809049272a..01c21c6cdbbc 100644 --- a/sound/soc/pxa/pxa2xx-ac97.c +++ b/sound/soc/pxa/pxa2xx-ac97.c | |||
@@ -164,10 +164,18 @@ static int pxa2xx_ac97_hw_mic_params(struct snd_pcm_substream *substream, | |||
164 | SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_44100 | \ | 164 | SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_44100 | \ |
165 | SNDRV_PCM_RATE_48000) | 165 | SNDRV_PCM_RATE_48000) |
166 | 166 | ||
167 | static struct snd_soc_dai_ops pxa_ac97_dai_ops = { | 167 | static struct snd_soc_dai_ops pxa_ac97_hifi_dai_ops = { |
168 | .hw_params = pxa2xx_ac97_hw_params, | 168 | .hw_params = pxa2xx_ac97_hw_params, |
169 | }; | 169 | }; |
170 | 170 | ||
171 | static struct snd_soc_dai_ops pxa_ac97_aux_dai_ops = { | ||
172 | .hw_params = pxa2xx_ac97_hw_aux_params, | ||
173 | }; | ||
174 | |||
175 | static struct snd_soc_dai_ops pxa_ac97_mic_dai_ops = { | ||
176 | .hw_params = pxa2xx_ac97_hw_mic_params, | ||
177 | }; | ||
178 | |||
171 | /* | 179 | /* |
172 | * There is only 1 physical AC97 interface for pxa2xx, but it | 180 | * There is only 1 physical AC97 interface for pxa2xx, but it |
173 | * has extra fifo's that can be used for aux DACs and ADCs. | 181 | * has extra fifo's that can be used for aux DACs and ADCs. |
@@ -193,7 +201,7 @@ struct snd_soc_dai pxa_ac97_dai[] = { | |||
193 | .channels_max = 2, | 201 | .channels_max = 2, |
194 | .rates = PXA2XX_AC97_RATES, | 202 | .rates = PXA2XX_AC97_RATES, |
195 | .formats = SNDRV_PCM_FMTBIT_S16_LE,}, | 203 | .formats = SNDRV_PCM_FMTBIT_S16_LE,}, |
196 | .ops = &pxa_ac97_dai_ops, | 204 | .ops = &pxa_ac97_hifi_dai_ops, |
197 | }, | 205 | }, |
198 | { | 206 | { |
199 | .name = "pxa2xx-ac97-aux", | 207 | .name = "pxa2xx-ac97-aux", |
@@ -211,7 +219,7 @@ struct snd_soc_dai pxa_ac97_dai[] = { | |||
211 | .channels_max = 1, | 219 | .channels_max = 1, |
212 | .rates = PXA2XX_AC97_RATES, | 220 | .rates = PXA2XX_AC97_RATES, |
213 | .formats = SNDRV_PCM_FMTBIT_S16_LE,}, | 221 | .formats = SNDRV_PCM_FMTBIT_S16_LE,}, |
214 | .ops = &pxa_ac97_dai_ops, | 222 | .ops = &pxa_ac97_aux_dai_ops, |
215 | }, | 223 | }, |
216 | { | 224 | { |
217 | .name = "pxa2xx-ac97-mic", | 225 | .name = "pxa2xx-ac97-mic", |
@@ -223,7 +231,7 @@ struct snd_soc_dai pxa_ac97_dai[] = { | |||
223 | .channels_max = 1, | 231 | .channels_max = 1, |
224 | .rates = PXA2XX_AC97_RATES, | 232 | .rates = PXA2XX_AC97_RATES, |
225 | .formats = SNDRV_PCM_FMTBIT_S16_LE,}, | 233 | .formats = SNDRV_PCM_FMTBIT_S16_LE,}, |
226 | .ops = &pxa_ac97_dai_ops, | 234 | .ops = &pxa_ac97_mic_dai_ops, |
227 | }, | 235 | }, |
228 | }; | 236 | }; |
229 | 237 | ||
diff --git a/sound/soc/s3c24xx/s3c64xx-i2s.c b/sound/soc/s3c24xx/s3c64xx-i2s.c index 6e1e85dc1ff2..33c5de7e255f 100644 --- a/sound/soc/s3c24xx/s3c64xx-i2s.c +++ b/sound/soc/s3c24xx/s3c64xx-i2s.c | |||
@@ -177,6 +177,10 @@ static int s3c64xx_i2s_probe(struct platform_device *pdev, | |||
177 | #define S3C64XX_I2S_FMTS \ | 177 | #define S3C64XX_I2S_FMTS \ |
178 | (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE) | 178 | (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE) |
179 | 179 | ||
180 | static struct snd_soc_dai_ops s3c64xx_i2s_dai_ops = { | ||
181 | .set_sysclk = s3c64xx_i2s_set_sysclk, | ||
182 | }; | ||
183 | |||
180 | struct snd_soc_dai s3c64xx_i2s_dai = { | 184 | struct snd_soc_dai s3c64xx_i2s_dai = { |
181 | .name = "s3c64xx-i2s", | 185 | .name = "s3c64xx-i2s", |
182 | .id = 0, | 186 | .id = 0, |
@@ -193,9 +197,7 @@ struct snd_soc_dai s3c64xx_i2s_dai = { | |||
193 | .rates = S3C64XX_I2S_RATES, | 197 | .rates = S3C64XX_I2S_RATES, |
194 | .formats = S3C64XX_I2S_FMTS, | 198 | .formats = S3C64XX_I2S_FMTS, |
195 | }, | 199 | }, |
196 | .ops = { | 200 | .ops = &s3c64xx_i2s_dai_ops, |
197 | .set_sysclk = s3c64xx_i2s_set_sysclk, | ||
198 | }, | ||
199 | }; | 201 | }; |
200 | EXPORT_SYMBOL_GPL(s3c64xx_i2s_dai); | 202 | EXPORT_SYMBOL_GPL(s3c64xx_i2s_dai); |
201 | 203 | ||
diff --git a/sound/soc/sh/hac.c b/sound/soc/sh/hac.c index eab31838badf..41db75af3c69 100644 --- a/sound/soc/sh/hac.c +++ b/sound/soc/sh/hac.c | |||
@@ -267,6 +267,10 @@ static int hac_hw_params(struct snd_pcm_substream *substream, | |||
267 | #define AC97_FMTS \ | 267 | #define AC97_FMTS \ |
268 | SNDRV_PCM_FMTBIT_S16_LE | 268 | SNDRV_PCM_FMTBIT_S16_LE |
269 | 269 | ||
270 | static struct snd_soc_dai_ops hac_dai_ops = { | ||
271 | .hw_params = hac_hw_params, | ||
272 | }; | ||
273 | |||
270 | struct snd_soc_dai sh4_hac_dai[] = { | 274 | struct snd_soc_dai sh4_hac_dai[] = { |
271 | { | 275 | { |
272 | .name = "HAC0", | 276 | .name = "HAC0", |
@@ -284,9 +288,7 @@ struct snd_soc_dai sh4_hac_dai[] = { | |||
284 | .channels_min = 2, | 288 | .channels_min = 2, |
285 | .channels_max = 2, | 289 | .channels_max = 2, |
286 | }, | 290 | }, |
287 | .ops = { | 291 | .ops = &hac_dai_ops, |
288 | .hw_params = hac_hw_params, | ||
289 | }, | ||
290 | }, | 292 | }, |
291 | #ifdef CONFIG_CPU_SUBTYPE_SH7760 | 293 | #ifdef CONFIG_CPU_SUBTYPE_SH7760 |
292 | { | 294 | { |
@@ -305,9 +307,7 @@ struct snd_soc_dai sh4_hac_dai[] = { | |||
305 | .channels_min = 2, | 307 | .channels_min = 2, |
306 | .channels_max = 2, | 308 | .channels_max = 2, |
307 | }, | 309 | }, |
308 | .ops = { | 310 | .ops = &hac_dai_ops, |
309 | .hw_params = hac_hw_params, | ||
310 | }, | ||
311 | 311 | ||
312 | }, | 312 | }, |
313 | #endif | 313 | #endif |
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 16518329f6b2..6e710f705a74 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c | |||
@@ -1432,7 +1432,8 @@ void snd_soc_free_pcms(struct snd_soc_device *socdev) | |||
1432 | #ifdef CONFIG_SND_SOC_AC97_BUS | 1432 | #ifdef CONFIG_SND_SOC_AC97_BUS |
1433 | for (i = 0; i < codec->num_dai; i++) { | 1433 | for (i = 0; i < codec->num_dai; i++) { |
1434 | codec_dai = &codec->dai[i]; | 1434 | codec_dai = &codec->dai[i]; |
1435 | if (codec_dai->ac97_control && codec->ac97) { | 1435 | if (codec_dai->ac97_control && codec->ac97 && |
1436 | strcmp(codec->name, "AC97") != 0) { | ||
1436 | soc_ac97_dev_unregister(codec); | 1437 | soc_ac97_dev_unregister(codec); |
1437 | goto free_card; | 1438 | goto free_card; |
1438 | } | 1439 | } |