aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/pxa
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/pxa')
-rw-r--r--sound/soc/pxa/Kconfig3
-rw-r--r--sound/soc/pxa/corgi.c1
-rw-r--r--sound/soc/pxa/poodle.c1
-rw-r--r--sound/soc/pxa/pxa2xx-ac97.c272
-rw-r--r--sound/soc/pxa/pxa2xx-i2s.c20
-rw-r--r--sound/soc/pxa/pxa2xx-pcm.c265
-rw-r--r--sound/soc/pxa/pxa2xx-pcm.h15
-rw-r--r--sound/soc/pxa/spitz.c1
8 files changed, 39 insertions, 539 deletions
diff --git a/sound/soc/pxa/Kconfig b/sound/soc/pxa/Kconfig
index 9212c37a33b8..f8c1cdd940ac 100644
--- a/sound/soc/pxa/Kconfig
+++ b/sound/soc/pxa/Kconfig
@@ -1,6 +1,7 @@
1config SND_PXA2XX_SOC 1config SND_PXA2XX_SOC
2 tristate "SoC Audio for the Intel PXA2xx chip" 2 tristate "SoC Audio for the Intel PXA2xx chip"
3 depends on ARCH_PXA 3 depends on ARCH_PXA
4 select SND_PXA2XX_LIB
4 help 5 help
5 Say Y or M if you want to add support for codecs attached to 6 Say Y or M if you want to add support for codecs attached to
6 the PXA2xx AC97, I2S or SSP interface. You will also need 7 the PXA2xx AC97, I2S or SSP interface. You will also need
@@ -13,6 +14,8 @@ config SND_PXA2XX_AC97
13config SND_PXA2XX_SOC_AC97 14config SND_PXA2XX_SOC_AC97
14 tristate 15 tristate
15 select AC97_BUS 16 select AC97_BUS
17 select SND_ARM
18 select SND_PXA2XX_LIB_AC97
16 select SND_SOC_AC97_BUS 19 select SND_SOC_AC97_BUS
17 20
18config SND_PXA2XX_SOC_I2S 21config SND_PXA2XX_SOC_I2S
diff --git a/sound/soc/pxa/corgi.c b/sound/soc/pxa/corgi.c
index 0a53f72077fd..72b7a5140bf8 100644
--- a/sound/soc/pxa/corgi.c
+++ b/sound/soc/pxa/corgi.c
@@ -330,6 +330,7 @@ static struct snd_soc_machine snd_soc_machine_corgi = {
330 330
331/* corgi audio private data */ 331/* corgi audio private data */
332static struct wm8731_setup_data corgi_wm8731_setup = { 332static struct wm8731_setup_data corgi_wm8731_setup = {
333 .i2c_bus = 0,
333 .i2c_address = 0x1b, 334 .i2c_address = 0x1b,
334}; 335};
335 336
diff --git a/sound/soc/pxa/poodle.c b/sound/soc/pxa/poodle.c
index a4697f7e2921..f84f7d8db09a 100644
--- a/sound/soc/pxa/poodle.c
+++ b/sound/soc/pxa/poodle.c
@@ -284,6 +284,7 @@ static struct snd_soc_machine snd_soc_machine_poodle = {
284 284
285/* poodle audio private data */ 285/* poodle audio private data */
286static struct wm8731_setup_data poodle_wm8731_setup = { 286static struct wm8731_setup_data poodle_wm8731_setup = {
287 .i2c_bus = 0,
287 .i2c_address = 0x1b, 288 .i2c_address = 0x1b,
288}; 289};
289 290
diff --git a/sound/soc/pxa/pxa2xx-ac97.c b/sound/soc/pxa/pxa2xx-ac97.c
index d94a495bd6bd..a80ae074b090 100644
--- a/sound/soc/pxa/pxa2xx-ac97.c
+++ b/sound/soc/pxa/pxa2xx-ac97.c
@@ -13,225 +13,30 @@
13#include <linux/init.h> 13#include <linux/init.h>
14#include <linux/module.h> 14#include <linux/module.h>
15#include <linux/platform_device.h> 15#include <linux/platform_device.h>
16#include <linux/interrupt.h>
17#include <linux/wait.h>
18#include <linux/clk.h>
19#include <linux/delay.h>
20 16
21#include <sound/core.h> 17#include <sound/core.h>
22#include <sound/pcm.h>
23#include <sound/ac97_codec.h> 18#include <sound/ac97_codec.h>
24#include <sound/initval.h>
25#include <sound/soc.h> 19#include <sound/soc.h>
20#include <sound/pxa2xx-lib.h>
26 21
27#include <asm/irq.h>
28#include <linux/mutex.h>
29#include <mach/hardware.h> 22#include <mach/hardware.h>
30#include <mach/pxa-regs.h> 23#include <mach/pxa-regs.h>
31#include <mach/pxa2xx-gpio.h>
32#include <mach/audio.h>
33 24
34#include "pxa2xx-pcm.h" 25#include "pxa2xx-pcm.h"
35#include "pxa2xx-ac97.h" 26#include "pxa2xx-ac97.h"
36 27
37static DEFINE_MUTEX(car_mutex);
38static DECLARE_WAIT_QUEUE_HEAD(gsr_wq);
39static volatile long gsr_bits;
40static struct clk *ac97_clk;
41#ifdef CONFIG_PXA27x
42static struct clk *ac97conf_clk;
43#endif
44
45/*
46 * Beware PXA27x bugs:
47 *
48 * o Slot 12 read from modem space will hang controller.
49 * o CDONE, SDONE interrupt fails after any slot 12 IO.
50 *
51 * We therefore have an hybrid approach for waiting on SDONE (interrupt or
52 * 1 jiffy timeout if interrupt never comes).
53 */
54
55static unsigned short pxa2xx_ac97_read(struct snd_ac97 *ac97,
56 unsigned short reg)
57{
58 unsigned short val = -1;
59 volatile u32 *reg_addr;
60
61 mutex_lock(&car_mutex);
62
63 /* set up primary or secondary codec/modem space */
64#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)
65 reg_addr = ac97->num ? &SAC_REG_BASE : &PAC_REG_BASE;
66#else
67 if (reg == AC97_GPIO_STATUS)
68 reg_addr = ac97->num ? &SMC_REG_BASE : &PMC_REG_BASE;
69 else
70 reg_addr = ac97->num ? &SAC_REG_BASE : &PAC_REG_BASE;
71#endif
72 reg_addr += (reg >> 1);
73
74#ifndef CONFIG_PXA27x
75 if (reg == AC97_GPIO_STATUS) {
76 /* read from controller cache */
77 val = *reg_addr;
78 goto out;
79 }
80#endif
81
82 /* start read access across the ac97 link */
83 GSR = GSR_CDONE | GSR_SDONE;
84 gsr_bits = 0;
85 val = *reg_addr;
86
87 wait_event_timeout(gsr_wq, (GSR | gsr_bits) & GSR_SDONE, 1);
88 if (!((GSR | gsr_bits) & GSR_SDONE)) {
89 printk(KERN_ERR "%s: read error (ac97_reg=%x GSR=%#lx)\n",
90 __func__, reg, GSR | gsr_bits);
91 val = -1;
92 goto out;
93 }
94
95 /* valid data now */
96 GSR = GSR_CDONE | GSR_SDONE;
97 gsr_bits = 0;
98 val = *reg_addr;
99 /* but we've just started another cycle... */
100 wait_event_timeout(gsr_wq, (GSR | gsr_bits) & GSR_SDONE, 1);
101
102out: mutex_unlock(&car_mutex);
103 return val;
104}
105
106static void pxa2xx_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
107 unsigned short val)
108{
109 volatile u32 *reg_addr;
110
111 mutex_lock(&car_mutex);
112
113 /* set up primary or secondary codec/modem space */
114#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)
115 reg_addr = ac97->num ? &SAC_REG_BASE : &PAC_REG_BASE;
116#else
117 if (reg == AC97_GPIO_STATUS)
118 reg_addr = ac97->num ? &SMC_REG_BASE : &PMC_REG_BASE;
119 else
120 reg_addr = ac97->num ? &SAC_REG_BASE : &PAC_REG_BASE;
121#endif
122 reg_addr += (reg >> 1);
123
124 GSR = GSR_CDONE | GSR_SDONE;
125 gsr_bits = 0;
126 *reg_addr = val;
127 wait_event_timeout(gsr_wq, (GSR | gsr_bits) & GSR_CDONE, 1);
128 if (!((GSR | gsr_bits) & GSR_CDONE))
129 printk(KERN_ERR "%s: write error (ac97_reg=%x GSR=%#lx)\n",
130 __func__, reg, GSR | gsr_bits);
131
132 mutex_unlock(&car_mutex);
133}
134
135static void pxa2xx_ac97_warm_reset(struct snd_ac97 *ac97) 28static void pxa2xx_ac97_warm_reset(struct snd_ac97 *ac97)
136{ 29{
137#ifdef CONFIG_PXA3xx 30 pxa2xx_ac97_try_warm_reset(ac97);
138 int timeout = 100;
139#endif
140 gsr_bits = 0;
141
142#ifdef CONFIG_PXA27x
143 /* warm reset broken on Bulverde,
144 so manually keep AC97 reset high */
145 pxa_gpio_mode(113 | GPIO_OUT | GPIO_DFLT_HIGH);
146 udelay(10);
147 GCR |= GCR_WARM_RST;
148 pxa_gpio_mode(113 | GPIO_ALT_FN_2_OUT);
149 udelay(500);
150#elif defined(CONFIG_PXA3xx)
151 /* Can't use interrupts */
152 GCR |= GCR_WARM_RST;
153 while (!((GSR | gsr_bits) & (GSR_PCR | GSR_SCR)) && timeout--)
154 mdelay(1);
155#else
156 GCR |= GCR_WARM_RST | GCR_PRIRDY_IEN | GCR_SECRDY_IEN;
157 wait_event_timeout(gsr_wq, gsr_bits & (GSR_PCR | GSR_SCR), 1);
158#endif
159
160 if (!((GSR | gsr_bits) & (GSR_PCR | GSR_SCR)))
161 printk(KERN_INFO "%s: warm reset timeout (GSR=%#lx)\n",
162 __func__, gsr_bits);
163 31
164 GCR &= ~(GCR_PRIRDY_IEN|GCR_SECRDY_IEN); 32 pxa2xx_ac97_finish_reset(ac97);
165 GCR |= GCR_SDONE_IE|GCR_CDONE_IE;
166} 33}
167 34
168static void pxa2xx_ac97_cold_reset(struct snd_ac97 *ac97) 35static void pxa2xx_ac97_cold_reset(struct snd_ac97 *ac97)
169{ 36{
170#ifdef CONFIG_PXA3xx 37 pxa2xx_ac97_try_cold_reset(ac97);
171 int timeout = 1000;
172
173 /* Hold CLKBPB for 100us */
174 GCR = 0;
175 GCR = GCR_CLKBPB;
176 udelay(100);
177 GCR = 0;
178#endif
179 38
180 GCR &= GCR_COLD_RST; /* clear everything but nCRST */ 39 pxa2xx_ac97_finish_reset(ac97);
181 GCR &= ~GCR_COLD_RST; /* then assert nCRST */
182
183 gsr_bits = 0;
184#ifdef CONFIG_PXA27x
185 /* PXA27x Developers Manual section 13.5.2.2.1 */
186 clk_enable(ac97conf_clk);
187 udelay(5);
188 clk_disable(ac97conf_clk);
189 GCR = GCR_COLD_RST;
190 udelay(50);
191#elif defined(CONFIG_PXA3xx)
192 /* Can't use interrupts on PXA3xx */
193 GCR &= ~(GCR_PRIRDY_IEN|GCR_SECRDY_IEN);
194
195 GCR = GCR_WARM_RST | GCR_COLD_RST;
196 while (!(GSR & (GSR_PCR | GSR_SCR)) && timeout--)
197 mdelay(10);
198#else
199 GCR = GCR_COLD_RST;
200 GCR |= GCR_CDONE_IE|GCR_SDONE_IE;
201 wait_event_timeout(gsr_wq, gsr_bits & (GSR_PCR | GSR_SCR), 1);
202#endif
203
204 if (!((GSR | gsr_bits) & (GSR_PCR | GSR_SCR)))
205 printk(KERN_INFO "%s: cold reset timeout (GSR=%#lx)\n",
206 __func__, gsr_bits);
207
208 GCR &= ~(GCR_PRIRDY_IEN|GCR_SECRDY_IEN);
209 GCR |= GCR_SDONE_IE|GCR_CDONE_IE;
210}
211
212static irqreturn_t pxa2xx_ac97_irq(int irq, void *dev_id)
213{
214 long status;
215
216 status = GSR;
217 if (status) {
218 GSR = status;
219 gsr_bits |= status;
220 wake_up(&gsr_wq);
221
222#ifdef CONFIG_PXA27x
223 /* Although we don't use those we still need to clear them
224 since they tend to spuriously trigger when MMC is used
225 (hardware bug? go figure)... */
226 MISR = MISR_EOC;
227 PISR = PISR_EOC;
228 MCSR = MCSR_EOC;
229#endif
230
231 return IRQ_HANDLED;
232 }
233
234 return IRQ_NONE;
235} 40}
236 41
237struct snd_ac97_bus_ops soc_ac97_ops = { 42struct snd_ac97_bus_ops soc_ac97_ops = {
@@ -285,24 +90,13 @@ static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_mic_mono_in = {
285static int pxa2xx_ac97_suspend(struct platform_device *pdev, 90static int pxa2xx_ac97_suspend(struct platform_device *pdev,
286 struct snd_soc_dai *dai) 91 struct snd_soc_dai *dai)
287{ 92{
288 GCR |= GCR_ACLINK_OFF; 93 return pxa2xx_ac97_hw_suspend();
289 clk_disable(ac97_clk);
290 return 0;
291} 94}
292 95
293static int pxa2xx_ac97_resume(struct platform_device *pdev, 96static int pxa2xx_ac97_resume(struct platform_device *pdev,
294 struct snd_soc_dai *dai) 97 struct snd_soc_dai *dai)
295{ 98{
296 pxa_gpio_mode(GPIO31_SYNC_AC97_MD); 99 return pxa2xx_ac97_hw_resume();
297 pxa_gpio_mode(GPIO30_SDATA_OUT_AC97_MD);
298 pxa_gpio_mode(GPIO28_BITCLK_AC97_MD);
299 pxa_gpio_mode(GPIO29_SDATA_IN_AC97_MD);
300#ifdef CONFIG_PXA27x
301 /* Use GPIO 113 as AC97 Reset on Bulverde */
302 pxa_gpio_mode(113 | GPIO_ALT_FN_2_OUT);
303#endif
304 clk_enable(ac97_clk);
305 return 0;
306} 100}
307 101
308#else 102#else
@@ -313,61 +107,13 @@ static int pxa2xx_ac97_resume(struct platform_device *pdev,
313static int pxa2xx_ac97_probe(struct platform_device *pdev, 107static int pxa2xx_ac97_probe(struct platform_device *pdev,
314 struct snd_soc_dai *dai) 108 struct snd_soc_dai *dai)
315{ 109{
316 int ret; 110 return pxa2xx_ac97_hw_probe(pdev);
317
318 ret = request_irq(IRQ_AC97, pxa2xx_ac97_irq, IRQF_DISABLED, "AC97", NULL);
319 if (ret < 0)
320 goto err;
321
322 pxa_gpio_mode(GPIO31_SYNC_AC97_MD);
323 pxa_gpio_mode(GPIO30_SDATA_OUT_AC97_MD);
324 pxa_gpio_mode(GPIO28_BITCLK_AC97_MD);
325 pxa_gpio_mode(GPIO29_SDATA_IN_AC97_MD);
326#ifdef CONFIG_PXA27x
327 /* Use GPIO 113 as AC97 Reset on Bulverde */
328 pxa_gpio_mode(113 | GPIO_ALT_FN_2_OUT);
329
330 ac97conf_clk = clk_get(&pdev->dev, "AC97CONFCLK");
331 if (IS_ERR(ac97conf_clk)) {
332 ret = PTR_ERR(ac97conf_clk);
333 ac97conf_clk = NULL;
334 goto err_irq;
335 }
336#endif
337 ac97_clk = clk_get(&pdev->dev, "AC97CLK");
338 if (IS_ERR(ac97_clk)) {
339 ret = PTR_ERR(ac97_clk);
340 ac97_clk = NULL;
341 goto err_irq;
342 }
343 clk_enable(ac97_clk);
344 return 0;
345
346 err_irq:
347 GCR |= GCR_ACLINK_OFF;
348#ifdef CONFIG_PXA27x
349 if (ac97conf_clk) {
350 clk_put(ac97conf_clk);
351 ac97conf_clk = NULL;
352 }
353#endif
354 free_irq(IRQ_AC97, NULL);
355 err:
356 return ret;
357} 111}
358 112
359static void pxa2xx_ac97_remove(struct platform_device *pdev, 113static void pxa2xx_ac97_remove(struct platform_device *pdev,
360 struct snd_soc_dai *dai) 114 struct snd_soc_dai *dai)
361{ 115{
362 GCR |= GCR_ACLINK_OFF; 116 pxa2xx_ac97_hw_remove(pdev);
363 free_irq(IRQ_AC97, NULL);
364#ifdef CONFIG_PXA27x
365 clk_put(ac97conf_clk);
366 ac97conf_clk = NULL;
367#endif
368 clk_disable(ac97_clk);
369 clk_put(ac97_clk);
370 ac97_clk = NULL;
371} 117}
372 118
373static int pxa2xx_ac97_hw_params(struct snd_pcm_substream *substream, 119static int pxa2xx_ac97_hw_params(struct snd_pcm_substream *substream,
diff --git a/sound/soc/pxa/pxa2xx-i2s.c b/sound/soc/pxa/pxa2xx-i2s.c
index c796b1882776..39d19212f6d3 100644
--- a/sound/soc/pxa/pxa2xx-i2s.c
+++ b/sound/soc/pxa/pxa2xx-i2s.c
@@ -21,6 +21,7 @@
21#include <sound/pcm.h> 21#include <sound/pcm.h>
22#include <sound/initval.h> 22#include <sound/initval.h>
23#include <sound/soc.h> 23#include <sound/soc.h>
24#include <sound/pxa2xx-lib.h>
24 25
25#include <mach/hardware.h> 26#include <mach/hardware.h>
26#include <mach/pxa-regs.h> 27#include <mach/pxa-regs.h>
@@ -30,6 +31,15 @@
30#include "pxa2xx-pcm.h" 31#include "pxa2xx-pcm.h"
31#include "pxa2xx-i2s.h" 32#include "pxa2xx-i2s.h"
32 33
34struct pxa2xx_gpio {
35 u32 sys;
36 u32 rx;
37 u32 tx;
38 u32 clk;
39 u32 frm;
40};
41
42
33struct pxa_i2s_port { 43struct pxa_i2s_port {
34 u32 sadiv; 44 u32 sadiv;
35 u32 sacr0; 45 u32 sacr0;
@@ -65,11 +75,6 @@ static struct pxa2xx_gpio gpio_bus[] = {
65 .frm = GPIO31_SYNC_I2S_MD, 75 .frm = GPIO31_SYNC_I2S_MD,
66 }, 76 },
67 { /* I2S SoC Master */ 77 { /* I2S SoC Master */
68#ifdef CONFIG_PXA27x
69 .sys = GPIO113_I2S_SYSCLK_MD,
70#else
71 .sys = GPIO32_SYSCLK_I2S_MD,
72#endif
73 .rx = GPIO29_SDATA_IN_I2S_MD, 78 .rx = GPIO29_SDATA_IN_I2S_MD,
74 .tx = GPIO30_SDATA_OUT_I2S_MD, 79 .tx = GPIO30_SDATA_OUT_I2S_MD,
75 .clk = GPIO28_BITCLK_OUT_I2S_MD, 80 .clk = GPIO28_BITCLK_OUT_I2S_MD,
@@ -343,6 +348,11 @@ static struct platform_driver pxa2xx_i2s_driver = {
343 348
344static int __init pxa2xx_i2s_init(void) 349static int __init pxa2xx_i2s_init(void)
345{ 350{
351 if (cpu_is_pxa27x())
352 gpio_bus[1].sys = GPIO113_I2S_SYSCLK_MD;
353 else
354 gpio_bus[1].sys = GPIO32_SYSCLK_I2S_MD;
355
346 clk_i2s = ERR_PTR(-ENOENT); 356 clk_i2s = ERR_PTR(-ENOENT);
347 return platform_driver_register(&pxa2xx_i2s_driver); 357 return platform_driver_register(&pxa2xx_i2s_driver);
348} 358}
diff --git a/sound/soc/pxa/pxa2xx-pcm.c b/sound/soc/pxa/pxa2xx-pcm.c
index 4345f387fe41..afcd892cd2fa 100644
--- a/sound/soc/pxa/pxa2xx-pcm.c
+++ b/sound/soc/pxa/pxa2xx-pcm.c
@@ -10,64 +10,14 @@
10 * published by the Free Software Foundation. 10 * published by the Free Software Foundation.
11 */ 11 */
12 12
13#include <linux/module.h>
14#include <linux/init.h>
15#include <linux/platform_device.h>
16#include <linux/slab.h>
17#include <linux/dma-mapping.h> 13#include <linux/dma-mapping.h>
18 14
19#include <sound/core.h> 15#include <sound/core.h>
20#include <sound/pcm.h>
21#include <sound/pcm_params.h>
22#include <sound/soc.h> 16#include <sound/soc.h>
23 17#include <sound/pxa2xx-lib.h>
24#include <asm/dma.h>
25#include <mach/hardware.h>
26#include <mach/pxa-regs.h>
27#include <mach/audio.h>
28 18
29#include "pxa2xx-pcm.h" 19#include "pxa2xx-pcm.h"
30 20#include "../../arm/pxa2xx-pcm.h"
31static const struct snd_pcm_hardware pxa2xx_pcm_hardware = {
32 .info = SNDRV_PCM_INFO_MMAP |
33 SNDRV_PCM_INFO_MMAP_VALID |
34 SNDRV_PCM_INFO_INTERLEAVED |
35 SNDRV_PCM_INFO_PAUSE |
36 SNDRV_PCM_INFO_RESUME,
37 .formats = SNDRV_PCM_FMTBIT_S16_LE |
38 SNDRV_PCM_FMTBIT_S24_LE |
39 SNDRV_PCM_FMTBIT_S32_LE,
40 .period_bytes_min = 32,
41 .period_bytes_max = 8192 - 32,
42 .periods_min = 1,
43 .periods_max = PAGE_SIZE/sizeof(pxa_dma_desc),
44 .buffer_bytes_max = 128 * 1024,
45 .fifo_size = 32,
46};
47
48struct pxa2xx_runtime_data {
49 int dma_ch;
50 struct pxa2xx_pcm_dma_params *params;
51 pxa_dma_desc *dma_desc_array;
52 dma_addr_t dma_desc_array_phys;
53};
54
55static void pxa2xx_pcm_dma_irq(int dma_ch, void *dev_id)
56{
57 struct snd_pcm_substream *substream = dev_id;
58 struct pxa2xx_runtime_data *prtd = substream->runtime->private_data;
59 int dcsr;
60
61 dcsr = DCSR(dma_ch);
62 DCSR(dma_ch) = dcsr & ~DCSR_STOPIRQEN;
63
64 if (dcsr & DCSR_ENDINTR) {
65 snd_pcm_period_elapsed(substream);
66 } else {
67 printk(KERN_ERR "%s: DMA error on channel %d (DCSR=%#x)\n",
68 prtd->params->name, dma_ch, dcsr);
69 }
70}
71 21
72static int pxa2xx_pcm_hw_params(struct snd_pcm_substream *substream, 22static int pxa2xx_pcm_hw_params(struct snd_pcm_substream *substream,
73 struct snd_pcm_hw_params *params) 23 struct snd_pcm_hw_params *params)
@@ -76,10 +26,6 @@ static int pxa2xx_pcm_hw_params(struct snd_pcm_substream *substream,
76 struct pxa2xx_runtime_data *prtd = runtime->private_data; 26 struct pxa2xx_runtime_data *prtd = runtime->private_data;
77 struct snd_soc_pcm_runtime *rtd = substream->private_data; 27 struct snd_soc_pcm_runtime *rtd = substream->private_data;
78 struct pxa2xx_pcm_dma_params *dma = rtd->dai->cpu_dai->dma_data; 28 struct pxa2xx_pcm_dma_params *dma = rtd->dai->cpu_dai->dma_data;
79 size_t totsize = params_buffer_bytes(params);
80 size_t period = params_period_bytes(params);
81 pxa_dma_desc *dma_desc;
82 dma_addr_t dma_buff_phys, next_desc_phys;
83 int ret; 29 int ret;
84 30
85 /* return if this is a bufferless transfer e.g. 31 /* return if this is a bufferless transfer e.g.
@@ -106,42 +52,16 @@ static int pxa2xx_pcm_hw_params(struct snd_pcm_substream *substream,
106 prtd->dma_ch = ret; 52 prtd->dma_ch = ret;
107 } 53 }
108 54
109 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); 55 return __pxa2xx_pcm_hw_params(substream, params);
110 runtime->dma_bytes = totsize;
111
112 dma_desc = prtd->dma_desc_array;
113 next_desc_phys = prtd->dma_desc_array_phys;
114 dma_buff_phys = runtime->dma_addr;
115 do {
116 next_desc_phys += sizeof(pxa_dma_desc);
117 dma_desc->ddadr = next_desc_phys;
118 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
119 dma_desc->dsadr = dma_buff_phys;
120 dma_desc->dtadr = prtd->params->dev_addr;
121 } else {
122 dma_desc->dsadr = prtd->params->dev_addr;
123 dma_desc->dtadr = dma_buff_phys;
124 }
125 if (period > totsize)
126 period = totsize;
127 dma_desc->dcmd = prtd->params->dcmd | period | DCMD_ENDIRQEN;
128 dma_desc++;
129 dma_buff_phys += period;
130 } while (totsize -= period);
131 dma_desc[-1].ddadr = prtd->dma_desc_array_phys;
132
133 return 0;
134} 56}
135 57
136static int pxa2xx_pcm_hw_free(struct snd_pcm_substream *substream) 58static int pxa2xx_pcm_hw_free(struct snd_pcm_substream *substream)
137{ 59{
138 struct pxa2xx_runtime_data *prtd = substream->runtime->private_data; 60 struct pxa2xx_runtime_data *prtd = substream->runtime->private_data;
139 61
140 if (prtd && prtd->params) 62 __pxa2xx_pcm_hw_free(substream);
141 *prtd->params->drcmr = 0;
142 63
143 if (prtd->dma_ch) { 64 if (prtd->dma_ch) {
144 snd_pcm_set_runtime_buffer(substream, NULL);
145 pxa_free_dma(prtd->dma_ch); 65 pxa_free_dma(prtd->dma_ch);
146 prtd->dma_ch = 0; 66 prtd->dma_ch = 0;
147 } 67 }
@@ -149,188 +69,21 @@ static int pxa2xx_pcm_hw_free(struct snd_pcm_substream *substream)
149 return 0; 69 return 0;
150} 70}
151 71
152static int pxa2xx_pcm_prepare(struct snd_pcm_substream *substream)
153{
154 struct pxa2xx_runtime_data *prtd = substream->runtime->private_data;
155
156 DCSR(prtd->dma_ch) &= ~DCSR_RUN;
157 DCSR(prtd->dma_ch) = 0;
158 DCMD(prtd->dma_ch) = 0;
159 *prtd->params->drcmr = prtd->dma_ch | DRCMR_MAPVLD;
160
161 return 0;
162}
163
164static int pxa2xx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
165{
166 struct pxa2xx_runtime_data *prtd = substream->runtime->private_data;
167 int ret = 0;
168
169 switch (cmd) {
170 case SNDRV_PCM_TRIGGER_START:
171 DDADR(prtd->dma_ch) = prtd->dma_desc_array_phys;
172 DCSR(prtd->dma_ch) = DCSR_RUN;
173 break;
174
175 case SNDRV_PCM_TRIGGER_STOP:
176 case SNDRV_PCM_TRIGGER_SUSPEND:
177 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
178 DCSR(prtd->dma_ch) &= ~DCSR_RUN;
179 break;
180
181 case SNDRV_PCM_TRIGGER_RESUME:
182 DCSR(prtd->dma_ch) |= DCSR_RUN;
183 break;
184 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
185 DDADR(prtd->dma_ch) = prtd->dma_desc_array_phys;
186 DCSR(prtd->dma_ch) |= DCSR_RUN;
187 break;
188
189 default:
190 ret = -EINVAL;
191 }
192
193 return ret;
194}
195
196static snd_pcm_uframes_t
197pxa2xx_pcm_pointer(struct snd_pcm_substream *substream)
198{
199 struct snd_pcm_runtime *runtime = substream->runtime;
200 struct pxa2xx_runtime_data *prtd = runtime->private_data;
201
202 dma_addr_t ptr = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
203 DSADR(prtd->dma_ch) : DTADR(prtd->dma_ch);
204 snd_pcm_uframes_t x = bytes_to_frames(runtime, ptr - runtime->dma_addr);
205
206 if (x == runtime->buffer_size)
207 x = 0;
208 return x;
209}
210
211static int pxa2xx_pcm_open(struct snd_pcm_substream *substream)
212{
213 struct snd_pcm_runtime *runtime = substream->runtime;
214 struct pxa2xx_runtime_data *prtd;
215 int ret;
216
217 snd_soc_set_runtime_hwparams(substream, &pxa2xx_pcm_hardware);
218
219 /*
220 * For mysterious reasons (and despite what the manual says)
221 * playback samples are lost if the DMA count is not a multiple
222 * of the DMA burst size. Let's add a rule to enforce that.
223 */
224 ret = snd_pcm_hw_constraint_step(runtime, 0,
225 SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 32);
226 if (ret)
227 goto out;
228
229 ret = snd_pcm_hw_constraint_step(runtime, 0,
230 SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 32);
231 if (ret)
232 goto out;
233
234 ret = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
235 if (ret < 0)
236 goto out;
237
238 prtd = kzalloc(sizeof(struct pxa2xx_runtime_data), GFP_KERNEL);
239 if (prtd == NULL) {
240 ret = -ENOMEM;
241 goto out;
242 }
243
244 prtd->dma_desc_array =
245 dma_alloc_writecombine(substream->pcm->card->dev, PAGE_SIZE,
246 &prtd->dma_desc_array_phys, GFP_KERNEL);
247 if (!prtd->dma_desc_array) {
248 ret = -ENOMEM;
249 goto err1;
250 }
251
252 runtime->private_data = prtd;
253 return 0;
254
255 err1:
256 kfree(prtd);
257 out:
258 return ret;
259}
260
261static int pxa2xx_pcm_close(struct snd_pcm_substream *substream)
262{
263 struct snd_pcm_runtime *runtime = substream->runtime;
264 struct pxa2xx_runtime_data *prtd = runtime->private_data;
265
266 dma_free_writecombine(substream->pcm->card->dev, PAGE_SIZE,
267 prtd->dma_desc_array, prtd->dma_desc_array_phys);
268 kfree(prtd);
269 return 0;
270}
271
272static int pxa2xx_pcm_mmap(struct snd_pcm_substream *substream,
273 struct vm_area_struct *vma)
274{
275 struct snd_pcm_runtime *runtime = substream->runtime;
276 return dma_mmap_writecombine(substream->pcm->card->dev, vma,
277 runtime->dma_area,
278 runtime->dma_addr,
279 runtime->dma_bytes);
280}
281
282struct snd_pcm_ops pxa2xx_pcm_ops = { 72struct snd_pcm_ops pxa2xx_pcm_ops = {
283 .open = pxa2xx_pcm_open, 73 .open = __pxa2xx_pcm_open,
284 .close = pxa2xx_pcm_close, 74 .close = __pxa2xx_pcm_close,
285 .ioctl = snd_pcm_lib_ioctl, 75 .ioctl = snd_pcm_lib_ioctl,
286 .hw_params = pxa2xx_pcm_hw_params, 76 .hw_params = pxa2xx_pcm_hw_params,
287 .hw_free = pxa2xx_pcm_hw_free, 77 .hw_free = pxa2xx_pcm_hw_free,
288 .prepare = pxa2xx_pcm_prepare, 78 .prepare = __pxa2xx_pcm_prepare,
289 .trigger = pxa2xx_pcm_trigger, 79 .trigger = pxa2xx_pcm_trigger,
290 .pointer = pxa2xx_pcm_pointer, 80 .pointer = pxa2xx_pcm_pointer,
291 .mmap = pxa2xx_pcm_mmap, 81 .mmap = pxa2xx_pcm_mmap,
292}; 82};
293 83
294static int pxa2xx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
295{
296 struct snd_pcm_substream *substream = pcm->streams[stream].substream;
297 struct snd_dma_buffer *buf = &substream->dma_buffer;
298 size_t size = pxa2xx_pcm_hardware.buffer_bytes_max;
299 buf->dev.type = SNDRV_DMA_TYPE_DEV;
300 buf->dev.dev = pcm->card->dev;
301 buf->private_data = NULL;
302 buf->area = dma_alloc_writecombine(pcm->card->dev, size,
303 &buf->addr, GFP_KERNEL);
304 if (!buf->area)
305 return -ENOMEM;
306 buf->bytes = size;
307 return 0;
308}
309
310static void pxa2xx_pcm_free_dma_buffers(struct snd_pcm *pcm)
311{
312 struct snd_pcm_substream *substream;
313 struct snd_dma_buffer *buf;
314 int stream;
315
316 for (stream = 0; stream < 2; stream++) {
317 substream = pcm->streams[stream].substream;
318 if (!substream)
319 continue;
320
321 buf = &substream->dma_buffer;
322 if (!buf->area)
323 continue;
324
325 dma_free_writecombine(pcm->card->dev, buf->bytes,
326 buf->area, buf->addr);
327 buf->area = NULL;
328 }
329}
330
331static u64 pxa2xx_pcm_dmamask = DMA_32BIT_MASK; 84static u64 pxa2xx_pcm_dmamask = DMA_32BIT_MASK;
332 85
333int pxa2xx_pcm_new(struct snd_card *card, struct snd_soc_dai *dai, 86static int pxa2xx_soc_pcm_new(struct snd_card *card, struct snd_soc_dai *dai,
334 struct snd_pcm *pcm) 87 struct snd_pcm *pcm)
335{ 88{
336 int ret = 0; 89 int ret = 0;
@@ -360,7 +113,7 @@ int pxa2xx_pcm_new(struct snd_card *card, struct snd_soc_dai *dai,
360struct snd_soc_platform pxa2xx_soc_platform = { 113struct snd_soc_platform pxa2xx_soc_platform = {
361 .name = "pxa2xx-audio", 114 .name = "pxa2xx-audio",
362 .pcm_ops = &pxa2xx_pcm_ops, 115 .pcm_ops = &pxa2xx_pcm_ops,
363 .pcm_new = pxa2xx_pcm_new, 116 .pcm_new = pxa2xx_soc_pcm_new,
364 .pcm_free = pxa2xx_pcm_free_dma_buffers, 117 .pcm_free = pxa2xx_pcm_free_dma_buffers,
365}; 118};
366EXPORT_SYMBOL_GPL(pxa2xx_soc_platform); 119EXPORT_SYMBOL_GPL(pxa2xx_soc_platform);
diff --git a/sound/soc/pxa/pxa2xx-pcm.h b/sound/soc/pxa/pxa2xx-pcm.h
index 54c9c755e508..60c3b20aeeb4 100644
--- a/sound/soc/pxa/pxa2xx-pcm.h
+++ b/sound/soc/pxa/pxa2xx-pcm.h
@@ -13,21 +13,6 @@
13#ifndef _PXA2XX_PCM_H 13#ifndef _PXA2XX_PCM_H
14#define _PXA2XX_PCM_H 14#define _PXA2XX_PCM_H
15 15
16struct pxa2xx_pcm_dma_params {
17 char *name; /* stream identifier */
18 u32 dcmd; /* DMA descriptor dcmd field */
19 volatile u32 *drcmr; /* the DMA request channel to use */
20 u32 dev_addr; /* device physical address for DMA */
21};
22
23struct pxa2xx_gpio {
24 u32 sys;
25 u32 rx;
26 u32 tx;
27 u32 clk;
28 u32 frm;
29};
30
31/* platform data */ 16/* platform data */
32extern struct snd_soc_platform pxa2xx_soc_platform; 17extern struct snd_soc_platform pxa2xx_soc_platform;
33 18
diff --git a/sound/soc/pxa/spitz.c b/sound/soc/pxa/spitz.c
index 37cb768fc933..3d4738c06e7e 100644
--- a/sound/soc/pxa/spitz.c
+++ b/sound/soc/pxa/spitz.c
@@ -337,6 +337,7 @@ static struct snd_soc_machine snd_soc_machine_spitz = {
337 337
338/* spitz audio private data */ 338/* spitz audio private data */
339static struct wm8750_setup_data spitz_wm8750_setup = { 339static struct wm8750_setup_data spitz_wm8750_setup = {
340 .i2c_bus = 0,
340 .i2c_address = 0x1b, 341 .i2c_address = 0x1b,
341}; 342};
342 343