diff options
author | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2010-04-16 21:45:54 -0400 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2010-04-16 21:45:54 -0400 |
commit | 890c681275ab02623de1187f2d97fc355d76f372 (patch) | |
tree | 9098c63135cfa468a787a9ae25fba0d4b15f4f91 | |
parent | d21e0f4cd16656f71207683ee27465600ad21625 (diff) | |
parent | 8392609969b3b37a4da5cff08161661f7a8c16af (diff) |
Merge branch 'for-2.6.34' into for-2.6.35
-rw-r--r-- | sound/soc/codecs/wm2000.c | 1 | ||||
-rw-r--r-- | sound/soc/imx/imx-pcm-dma-mx2.c | 15 | ||||
-rw-r--r-- | sound/soc/imx/imx-pcm-fiq.c | 55 | ||||
-rw-r--r-- | sound/soc/imx/imx-ssi.c | 3 |
4 files changed, 45 insertions, 29 deletions
diff --git a/sound/soc/codecs/wm2000.c b/sound/soc/codecs/wm2000.c index 217b02680597..8de866618bf4 100644 --- a/sound/soc/codecs/wm2000.c +++ b/sound/soc/codecs/wm2000.c | |||
@@ -23,7 +23,6 @@ | |||
23 | 23 | ||
24 | #include <linux/module.h> | 24 | #include <linux/module.h> |
25 | #include <linux/moduleparam.h> | 25 | #include <linux/moduleparam.h> |
26 | #include <linux/version.h> | ||
27 | #include <linux/kernel.h> | 26 | #include <linux/kernel.h> |
28 | #include <linux/init.h> | 27 | #include <linux/init.h> |
29 | #include <linux/firmware.h> | 28 | #include <linux/firmware.h> |
diff --git a/sound/soc/imx/imx-pcm-dma-mx2.c b/sound/soc/imx/imx-pcm-dma-mx2.c index c78c000e2afe..93272966b848 100644 --- a/sound/soc/imx/imx-pcm-dma-mx2.c +++ b/sound/soc/imx/imx-pcm-dma-mx2.c | |||
@@ -70,7 +70,12 @@ static void imx_ssi_dma_callback(int channel, void *data) | |||
70 | 70 | ||
71 | static void snd_imx_dma_err_callback(int channel, void *data, int err) | 71 | static void snd_imx_dma_err_callback(int channel, void *data, int err) |
72 | { | 72 | { |
73 | pr_err("DMA error callback called\n"); | 73 | struct snd_pcm_substream *substream = data; |
74 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
75 | struct imx_pcm_dma_params *dma_params = rtd->dai->cpu_dai->dma_data; | ||
76 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
77 | struct imx_pcm_runtime_data *iprtd = runtime->private_data; | ||
78 | int ret; | ||
74 | 79 | ||
75 | pr_err("DMA timeout on channel %d -%s%s%s%s\n", | 80 | pr_err("DMA timeout on channel %d -%s%s%s%s\n", |
76 | channel, | 81 | channel, |
@@ -78,6 +83,14 @@ static void snd_imx_dma_err_callback(int channel, void *data, int err) | |||
78 | err & IMX_DMA_ERR_REQUEST ? " request" : "", | 83 | err & IMX_DMA_ERR_REQUEST ? " request" : "", |
79 | err & IMX_DMA_ERR_TRANSFER ? " transfer" : "", | 84 | err & IMX_DMA_ERR_TRANSFER ? " transfer" : "", |
80 | err & IMX_DMA_ERR_BUFFER ? " buffer" : ""); | 85 | err & IMX_DMA_ERR_BUFFER ? " buffer" : ""); |
86 | |||
87 | imx_dma_disable(iprtd->dma); | ||
88 | ret = imx_dma_setup_sg(iprtd->dma, iprtd->sg_list, iprtd->sg_count, | ||
89 | IMX_DMA_LENGTH_LOOP, dma_params->dma_addr, | ||
90 | substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? | ||
91 | DMA_MODE_WRITE : DMA_MODE_READ); | ||
92 | if (!ret) | ||
93 | imx_dma_enable(iprtd->dma); | ||
81 | } | 94 | } |
82 | 95 | ||
83 | static int imx_ssi_dma_alloc(struct snd_pcm_substream *substream) | 96 | static int imx_ssi_dma_alloc(struct snd_pcm_substream *substream) |
diff --git a/sound/soc/imx/imx-pcm-fiq.c b/sound/soc/imx/imx-pcm-fiq.c index d9cb9849b033..ecec332121f2 100644 --- a/sound/soc/imx/imx-pcm-fiq.c +++ b/sound/soc/imx/imx-pcm-fiq.c | |||
@@ -38,23 +38,24 @@ struct imx_pcm_runtime_data { | |||
38 | unsigned long offset; | 38 | unsigned long offset; |
39 | unsigned long last_offset; | 39 | unsigned long last_offset; |
40 | unsigned long size; | 40 | unsigned long size; |
41 | struct timer_list timer; | 41 | struct hrtimer hrt; |
42 | int poll_time; | 42 | int poll_time_ns; |
43 | struct snd_pcm_substream *substream; | ||
44 | atomic_t running; | ||
43 | }; | 45 | }; |
44 | 46 | ||
45 | static inline void imx_ssi_set_next_poll(struct imx_pcm_runtime_data *iprtd) | 47 | static enum hrtimer_restart snd_hrtimer_callback(struct hrtimer *hrt) |
46 | { | 48 | { |
47 | iprtd->timer.expires = jiffies + iprtd->poll_time; | 49 | struct imx_pcm_runtime_data *iprtd = |
48 | } | 50 | container_of(hrt, struct imx_pcm_runtime_data, hrt); |
49 | 51 | struct snd_pcm_substream *substream = iprtd->substream; | |
50 | static void imx_ssi_timer_callback(unsigned long data) | ||
51 | { | ||
52 | struct snd_pcm_substream *substream = (void *)data; | ||
53 | struct snd_pcm_runtime *runtime = substream->runtime; | 52 | struct snd_pcm_runtime *runtime = substream->runtime; |
54 | struct imx_pcm_runtime_data *iprtd = runtime->private_data; | ||
55 | struct pt_regs regs; | 53 | struct pt_regs regs; |
56 | unsigned long delta; | 54 | unsigned long delta; |
57 | 55 | ||
56 | if (!atomic_read(&iprtd->running)) | ||
57 | return HRTIMER_NORESTART; | ||
58 | |||
58 | get_fiq_regs(®s); | 59 | get_fiq_regs(®s); |
59 | 60 | ||
60 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | 61 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) |
@@ -71,16 +72,14 @@ static void imx_ssi_timer_callback(unsigned long data) | |||
71 | 72 | ||
72 | /* If we've transferred at least a period then report it and | 73 | /* If we've transferred at least a period then report it and |
73 | * reset our poll time */ | 74 | * reset our poll time */ |
74 | if (delta >= runtime->period_size) { | 75 | if (delta >= iprtd->period) { |
75 | snd_pcm_period_elapsed(substream); | 76 | snd_pcm_period_elapsed(substream); |
76 | iprtd->last_offset = iprtd->offset; | 77 | iprtd->last_offset = iprtd->offset; |
77 | |||
78 | imx_ssi_set_next_poll(iprtd); | ||
79 | } | 78 | } |
80 | 79 | ||
81 | /* Restart the timer; if we didn't report we'll run on the next tick */ | 80 | hrtimer_forward_now(hrt, ns_to_ktime(iprtd->poll_time_ns)); |
82 | add_timer(&iprtd->timer); | ||
83 | 81 | ||
82 | return HRTIMER_RESTART; | ||
84 | } | 83 | } |
85 | 84 | ||
86 | static struct fiq_handler fh = { | 85 | static struct fiq_handler fh = { |
@@ -98,8 +97,8 @@ static int snd_imx_pcm_hw_params(struct snd_pcm_substream *substream, | |||
98 | iprtd->period = params_period_bytes(params) ; | 97 | iprtd->period = params_period_bytes(params) ; |
99 | iprtd->offset = 0; | 98 | iprtd->offset = 0; |
100 | iprtd->last_offset = 0; | 99 | iprtd->last_offset = 0; |
101 | iprtd->poll_time = HZ / (params_rate(params) / params_period_size(params)); | 100 | iprtd->poll_time_ns = 1000000000 / params_rate(params) * |
102 | 101 | params_period_size(params); | |
103 | snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); | 102 | snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); |
104 | 103 | ||
105 | return 0; | 104 | return 0; |
@@ -134,8 +133,9 @@ static int snd_imx_pcm_trigger(struct snd_pcm_substream *substream, int cmd) | |||
134 | case SNDRV_PCM_TRIGGER_START: | 133 | case SNDRV_PCM_TRIGGER_START: |
135 | case SNDRV_PCM_TRIGGER_RESUME: | 134 | case SNDRV_PCM_TRIGGER_RESUME: |
136 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: | 135 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: |
137 | imx_ssi_set_next_poll(iprtd); | 136 | atomic_set(&iprtd->running, 1); |
138 | add_timer(&iprtd->timer); | 137 | hrtimer_start(&iprtd->hrt, ns_to_ktime(iprtd->poll_time_ns), |
138 | HRTIMER_MODE_REL); | ||
139 | if (++fiq_enable == 1) | 139 | if (++fiq_enable == 1) |
140 | enable_fiq(imx_pcm_fiq); | 140 | enable_fiq(imx_pcm_fiq); |
141 | 141 | ||
@@ -144,11 +144,11 @@ static int snd_imx_pcm_trigger(struct snd_pcm_substream *substream, int cmd) | |||
144 | case SNDRV_PCM_TRIGGER_STOP: | 144 | case SNDRV_PCM_TRIGGER_STOP: |
145 | case SNDRV_PCM_TRIGGER_SUSPEND: | 145 | case SNDRV_PCM_TRIGGER_SUSPEND: |
146 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: | 146 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: |
147 | del_timer(&iprtd->timer); | 147 | atomic_set(&iprtd->running, 0); |
148 | |||
148 | if (--fiq_enable == 0) | 149 | if (--fiq_enable == 0) |
149 | disable_fiq(imx_pcm_fiq); | 150 | disable_fiq(imx_pcm_fiq); |
150 | 151 | ||
151 | |||
152 | break; | 152 | break; |
153 | default: | 153 | default: |
154 | return -EINVAL; | 154 | return -EINVAL; |
@@ -179,7 +179,7 @@ static struct snd_pcm_hardware snd_imx_hardware = { | |||
179 | .buffer_bytes_max = IMX_SSI_DMABUF_SIZE, | 179 | .buffer_bytes_max = IMX_SSI_DMABUF_SIZE, |
180 | .period_bytes_min = 128, | 180 | .period_bytes_min = 128, |
181 | .period_bytes_max = 16 * 1024, | 181 | .period_bytes_max = 16 * 1024, |
182 | .periods_min = 2, | 182 | .periods_min = 4, |
183 | .periods_max = 255, | 183 | .periods_max = 255, |
184 | .fifo_size = 0, | 184 | .fifo_size = 0, |
185 | }; | 185 | }; |
@@ -193,9 +193,11 @@ static int snd_imx_open(struct snd_pcm_substream *substream) | |||
193 | iprtd = kzalloc(sizeof(*iprtd), GFP_KERNEL); | 193 | iprtd = kzalloc(sizeof(*iprtd), GFP_KERNEL); |
194 | runtime->private_data = iprtd; | 194 | runtime->private_data = iprtd; |
195 | 195 | ||
196 | init_timer(&iprtd->timer); | 196 | iprtd->substream = substream; |
197 | iprtd->timer.data = (unsigned long)substream; | 197 | |
198 | iprtd->timer.function = imx_ssi_timer_callback; | 198 | atomic_set(&iprtd->running, 0); |
199 | hrtimer_init(&iprtd->hrt, CLOCK_MONOTONIC, HRTIMER_MODE_REL); | ||
200 | iprtd->hrt.function = snd_hrtimer_callback; | ||
199 | 201 | ||
200 | ret = snd_pcm_hw_constraint_integer(substream->runtime, | 202 | ret = snd_pcm_hw_constraint_integer(substream->runtime, |
201 | SNDRV_PCM_HW_PARAM_PERIODS); | 203 | SNDRV_PCM_HW_PARAM_PERIODS); |
@@ -211,7 +213,8 @@ static int snd_imx_close(struct snd_pcm_substream *substream) | |||
211 | struct snd_pcm_runtime *runtime = substream->runtime; | 213 | struct snd_pcm_runtime *runtime = substream->runtime; |
212 | struct imx_pcm_runtime_data *iprtd = runtime->private_data; | 214 | struct imx_pcm_runtime_data *iprtd = runtime->private_data; |
213 | 215 | ||
214 | del_timer_sync(&iprtd->timer); | 216 | hrtimer_cancel(&iprtd->hrt); |
217 | |||
215 | kfree(iprtd); | 218 | kfree(iprtd); |
216 | 219 | ||
217 | return 0; | 220 | return 0; |
diff --git a/sound/soc/imx/imx-ssi.c b/sound/soc/imx/imx-ssi.c index 28e55c7b14b4..1bf9dc88babf 100644 --- a/sound/soc/imx/imx-ssi.c +++ b/sound/soc/imx/imx-ssi.c | |||
@@ -655,7 +655,8 @@ static int imx_ssi_probe(struct platform_device *pdev) | |||
655 | dai->private_data = ssi; | 655 | dai->private_data = ssi; |
656 | 656 | ||
657 | if ((cpu_is_mx27() || cpu_is_mx21()) && | 657 | if ((cpu_is_mx27() || cpu_is_mx21()) && |
658 | !(ssi->flags & IMX_SSI_USE_AC97)) { | 658 | !(ssi->flags & IMX_SSI_USE_AC97) && |
659 | (ssi->flags & IMX_SSI_DMA)) { | ||
659 | ssi->flags |= IMX_SSI_DMA; | 660 | ssi->flags |= IMX_SSI_DMA; |
660 | platform = imx_ssi_dma_mx2_init(pdev, ssi); | 661 | platform = imx_ssi_dma_mx2_init(pdev, ssi); |
661 | } else | 662 | } else |