diff options
author | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
---|---|---|
committer | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
commit | ada47b5fe13d89735805b566185f4885f5a3f750 (patch) | |
tree | 644b88f8a71896307d71438e9b3af49126ffb22b /sound/soc/omap/omap-pcm.c | |
parent | 43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff) | |
parent | 3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff) |
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'sound/soc/omap/omap-pcm.c')
-rw-r--r-- | sound/soc/omap/omap-pcm.c | 39 |
1 files changed, 21 insertions, 18 deletions
diff --git a/sound/soc/omap/omap-pcm.c b/sound/soc/omap/omap-pcm.c index 6a829eef2a4f..1e521904ea64 100644 --- a/sound/soc/omap/omap-pcm.c +++ b/sound/soc/omap/omap-pcm.c | |||
@@ -23,12 +23,13 @@ | |||
23 | */ | 23 | */ |
24 | 24 | ||
25 | #include <linux/dma-mapping.h> | 25 | #include <linux/dma-mapping.h> |
26 | #include <linux/slab.h> | ||
26 | #include <sound/core.h> | 27 | #include <sound/core.h> |
27 | #include <sound/pcm.h> | 28 | #include <sound/pcm.h> |
28 | #include <sound/pcm_params.h> | 29 | #include <sound/pcm_params.h> |
29 | #include <sound/soc.h> | 30 | #include <sound/soc.h> |
30 | 31 | ||
31 | #include <mach/dma.h> | 32 | #include <plat/dma.h> |
32 | #include "omap-pcm.h" | 33 | #include "omap-pcm.h" |
33 | 34 | ||
34 | static const struct snd_pcm_hardware omap_pcm_hardware = { | 35 | static const struct snd_pcm_hardware omap_pcm_hardware = { |
@@ -37,7 +38,8 @@ static const struct snd_pcm_hardware omap_pcm_hardware = { | |||
37 | SNDRV_PCM_INFO_INTERLEAVED | | 38 | SNDRV_PCM_INFO_INTERLEAVED | |
38 | SNDRV_PCM_INFO_PAUSE | | 39 | SNDRV_PCM_INFO_PAUSE | |
39 | SNDRV_PCM_INFO_RESUME, | 40 | SNDRV_PCM_INFO_RESUME, |
40 | .formats = SNDRV_PCM_FMTBIT_S16_LE, | 41 | .formats = SNDRV_PCM_FMTBIT_S16_LE | |
42 | SNDRV_PCM_FMTBIT_S32_LE, | ||
41 | .period_bytes_min = 32, | 43 | .period_bytes_min = 32, |
42 | .period_bytes_max = 64 * 1024, | 44 | .period_bytes_max = 64 * 1024, |
43 | .periods_min = 2, | 45 | .periods_min = 2, |
@@ -59,12 +61,11 @@ static void omap_pcm_dma_irq(int ch, u16 stat, void *data) | |||
59 | struct omap_runtime_data *prtd = runtime->private_data; | 61 | struct omap_runtime_data *prtd = runtime->private_data; |
60 | unsigned long flags; | 62 | unsigned long flags; |
61 | 63 | ||
62 | if ((cpu_is_omap1510()) && | 64 | if ((cpu_is_omap1510())) { |
63 | (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)) { | ||
64 | /* | 65 | /* |
65 | * OMAP1510 doesn't fully support DMA progress counter | 66 | * OMAP1510 doesn't fully support DMA progress counter |
66 | * and there is no software emulation implemented yet, | 67 | * and there is no software emulation implemented yet, |
67 | * so have to maintain our own playback progress counter | 68 | * so have to maintain our own progress counters |
68 | * that can be used by omap_pcm_pointer() instead. | 69 | * that can be used by omap_pcm_pointer() instead. |
69 | */ | 70 | */ |
70 | spin_lock_irqsave(&prtd->lock, flags); | 71 | spin_lock_irqsave(&prtd->lock, flags); |
@@ -99,9 +100,11 @@ static int omap_pcm_hw_params(struct snd_pcm_substream *substream, | |||
99 | struct snd_pcm_runtime *runtime = substream->runtime; | 100 | struct snd_pcm_runtime *runtime = substream->runtime; |
100 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 101 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
101 | struct omap_runtime_data *prtd = runtime->private_data; | 102 | struct omap_runtime_data *prtd = runtime->private_data; |
102 | struct omap_pcm_dma_data *dma_data = rtd->dai->cpu_dai->dma_data; | 103 | struct omap_pcm_dma_data *dma_data; |
103 | int err = 0; | 104 | int err = 0; |
104 | 105 | ||
106 | dma_data = snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream); | ||
107 | |||
105 | /* return if this is a bufferless transfer e.g. | 108 | /* return if this is a bufferless transfer e.g. |
106 | * codec <--> BT codec or GSM modem -- lg FIXME */ | 109 | * codec <--> BT codec or GSM modem -- lg FIXME */ |
107 | if (!dma_data) | 110 | if (!dma_data) |
@@ -149,6 +152,7 @@ static int omap_pcm_prepare(struct snd_pcm_substream *substream) | |||
149 | struct omap_runtime_data *prtd = runtime->private_data; | 152 | struct omap_runtime_data *prtd = runtime->private_data; |
150 | struct omap_pcm_dma_data *dma_data = prtd->dma_data; | 153 | struct omap_pcm_dma_data *dma_data = prtd->dma_data; |
151 | struct omap_dma_channel_params dma_params; | 154 | struct omap_dma_channel_params dma_params; |
155 | int bytes; | ||
152 | 156 | ||
153 | /* return if this is a bufferless transfer e.g. | 157 | /* return if this is a bufferless transfer e.g. |
154 | * codec <--> BT codec or GSM modem -- lg FIXME */ | 158 | * codec <--> BT codec or GSM modem -- lg FIXME */ |
@@ -156,11 +160,7 @@ static int omap_pcm_prepare(struct snd_pcm_substream *substream) | |||
156 | return 0; | 160 | return 0; |
157 | 161 | ||
158 | memset(&dma_params, 0, sizeof(dma_params)); | 162 | memset(&dma_params, 0, sizeof(dma_params)); |
159 | /* | 163 | dma_params.data_type = dma_data->data_type; |
160 | * Note: Regardless of interface data formats supported by OMAP McBSP | ||
161 | * or EAC blocks, internal representation is always fixed 16-bit/sample | ||
162 | */ | ||
163 | dma_params.data_type = OMAP_DMA_DATA_TYPE_S16; | ||
164 | dma_params.trigger = dma_data->dma_req; | 164 | dma_params.trigger = dma_data->dma_req; |
165 | dma_params.sync_mode = dma_data->sync_mode; | 165 | dma_params.sync_mode = dma_data->sync_mode; |
166 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { | 166 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { |
@@ -170,6 +170,7 @@ static int omap_pcm_prepare(struct snd_pcm_substream *substream) | |||
170 | dma_params.src_start = runtime->dma_addr; | 170 | dma_params.src_start = runtime->dma_addr; |
171 | dma_params.dst_start = dma_data->port_addr; | 171 | dma_params.dst_start = dma_data->port_addr; |
172 | dma_params.dst_port = OMAP_DMA_PORT_MPUI; | 172 | dma_params.dst_port = OMAP_DMA_PORT_MPUI; |
173 | dma_params.dst_fi = dma_data->packet_size; | ||
173 | } else { | 174 | } else { |
174 | dma_params.src_amode = OMAP_DMA_AMODE_CONSTANT; | 175 | dma_params.src_amode = OMAP_DMA_AMODE_CONSTANT; |
175 | dma_params.dst_amode = OMAP_DMA_AMODE_POST_INC; | 176 | dma_params.dst_amode = OMAP_DMA_AMODE_POST_INC; |
@@ -177,6 +178,7 @@ static int omap_pcm_prepare(struct snd_pcm_substream *substream) | |||
177 | dma_params.src_start = dma_data->port_addr; | 178 | dma_params.src_start = dma_data->port_addr; |
178 | dma_params.dst_start = runtime->dma_addr; | 179 | dma_params.dst_start = runtime->dma_addr; |
179 | dma_params.src_port = OMAP_DMA_PORT_MPUI; | 180 | dma_params.src_port = OMAP_DMA_PORT_MPUI; |
181 | dma_params.src_fi = dma_data->packet_size; | ||
180 | } | 182 | } |
181 | /* | 183 | /* |
182 | * Set DMA transfer frame size equal to ALSA period size and frame | 184 | * Set DMA transfer frame size equal to ALSA period size and frame |
@@ -184,12 +186,12 @@ static int omap_pcm_prepare(struct snd_pcm_substream *substream) | |||
184 | * we can transfer the whole ALSA buffer with single DMA transfer but | 186 | * we can transfer the whole ALSA buffer with single DMA transfer but |
185 | * still can get an interrupt at each period bounary | 187 | * still can get an interrupt at each period bounary |
186 | */ | 188 | */ |
187 | dma_params.elem_count = snd_pcm_lib_period_bytes(substream) / 2; | 189 | bytes = snd_pcm_lib_period_bytes(substream); |
190 | dma_params.elem_count = bytes >> dma_data->data_type; | ||
188 | dma_params.frame_count = runtime->periods; | 191 | dma_params.frame_count = runtime->periods; |
189 | omap_set_dma_params(prtd->dma_ch, &dma_params); | 192 | omap_set_dma_params(prtd->dma_ch, &dma_params); |
190 | 193 | ||
191 | if ((cpu_is_omap1510()) && | 194 | if ((cpu_is_omap1510())) |
192 | (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)) | ||
193 | omap_enable_dma_irq(prtd->dma_ch, OMAP_DMA_FRAME_IRQ | | 195 | omap_enable_dma_irq(prtd->dma_ch, OMAP_DMA_FRAME_IRQ | |
194 | OMAP_DMA_LAST_IRQ | OMAP_DMA_BLOCK_IRQ); | 196 | OMAP_DMA_LAST_IRQ | OMAP_DMA_BLOCK_IRQ); |
195 | else | 197 | else |
@@ -247,14 +249,15 @@ static snd_pcm_uframes_t omap_pcm_pointer(struct snd_pcm_substream *substream) | |||
247 | dma_addr_t ptr; | 249 | dma_addr_t ptr; |
248 | snd_pcm_uframes_t offset; | 250 | snd_pcm_uframes_t offset; |
249 | 251 | ||
250 | if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { | 252 | if (cpu_is_omap1510()) { |
253 | offset = prtd->period_index * runtime->period_size; | ||
254 | } else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { | ||
251 | ptr = omap_get_dma_dst_pos(prtd->dma_ch); | 255 | ptr = omap_get_dma_dst_pos(prtd->dma_ch); |
252 | offset = bytes_to_frames(runtime, ptr - runtime->dma_addr); | 256 | offset = bytes_to_frames(runtime, ptr - runtime->dma_addr); |
253 | } else if (!(cpu_is_omap1510())) { | 257 | } else { |
254 | ptr = omap_get_dma_src_pos(prtd->dma_ch); | 258 | ptr = omap_get_dma_src_pos(prtd->dma_ch); |
255 | offset = bytes_to_frames(runtime, ptr - runtime->dma_addr); | 259 | offset = bytes_to_frames(runtime, ptr - runtime->dma_addr); |
256 | } else | 260 | } |
257 | offset = prtd->period_index * runtime->period_size; | ||
258 | 261 | ||
259 | if (offset >= runtime->buffer_size) | 262 | if (offset >= runtime->buffer_size) |
260 | offset = 0; | 263 | offset = 0; |