diff options
| -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 217b0268059..8de866618bf 100644 --- a/sound/soc/codecs/wm2000.c +++ b/sound/soc/codecs/wm2000.c @@ -23,7 +23,6 @@  #include <linux/module.h>  #include <linux/moduleparam.h> -#include <linux/version.h>  #include <linux/kernel.h>  #include <linux/init.h>  #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 c78c000e2af..93272966b84 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)  static void snd_imx_dma_err_callback(int channel, void *data, int err)  { -	pr_err("DMA error callback called\n"); +	struct snd_pcm_substream *substream = data; +	struct snd_soc_pcm_runtime *rtd = substream->private_data; +	struct imx_pcm_dma_params *dma_params = rtd->dai->cpu_dai->dma_data; +	struct snd_pcm_runtime *runtime = substream->runtime; +	struct imx_pcm_runtime_data *iprtd = runtime->private_data; +	int ret;  	pr_err("DMA timeout on channel %d -%s%s%s%s\n",  		 channel, @@ -78,6 +83,14 @@ static void snd_imx_dma_err_callback(int channel, void *data, int err)  		 err & IMX_DMA_ERR_REQUEST ?  " request" : "",  		 err & IMX_DMA_ERR_TRANSFER ? " transfer" : "",  		 err & IMX_DMA_ERR_BUFFER ?   " buffer" : ""); + +	imx_dma_disable(iprtd->dma); +	ret = imx_dma_setup_sg(iprtd->dma, iprtd->sg_list, iprtd->sg_count, +			IMX_DMA_LENGTH_LOOP, dma_params->dma_addr, +			substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? +			DMA_MODE_WRITE : DMA_MODE_READ); +	if (!ret) +		imx_dma_enable(iprtd->dma);  }  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 d9cb9849b03..ecec332121f 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 {  	unsigned long offset;  	unsigned long last_offset;  	unsigned long size; -	struct timer_list timer; -	int poll_time; +	struct hrtimer hrt; +	int poll_time_ns; +	struct snd_pcm_substream *substream; +	atomic_t running;  }; -static inline void imx_ssi_set_next_poll(struct imx_pcm_runtime_data *iprtd) +static enum hrtimer_restart snd_hrtimer_callback(struct hrtimer *hrt)  { -	iprtd->timer.expires = jiffies + iprtd->poll_time; -} - -static void imx_ssi_timer_callback(unsigned long data) -{ -	struct snd_pcm_substream *substream = (void *)data; +	struct imx_pcm_runtime_data *iprtd = +		container_of(hrt, struct imx_pcm_runtime_data, hrt); +	struct snd_pcm_substream *substream = iprtd->substream;  	struct snd_pcm_runtime *runtime = substream->runtime; -	struct imx_pcm_runtime_data *iprtd = runtime->private_data;  	struct pt_regs regs;  	unsigned long delta; +	if (!atomic_read(&iprtd->running)) +		return HRTIMER_NORESTART; +  	get_fiq_regs(®s);  	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) @@ -71,16 +72,14 @@ static void imx_ssi_timer_callback(unsigned long data)  	/* If we've transferred at least a period then report it and  	 * reset our poll time */ -	if (delta >= runtime->period_size) { +	if (delta >= iprtd->period) {  		snd_pcm_period_elapsed(substream);  		iprtd->last_offset = iprtd->offset; - -		imx_ssi_set_next_poll(iprtd);  	} -	/* Restart the timer; if we didn't report we'll run on the next tick */ -	add_timer(&iprtd->timer); +	hrtimer_forward_now(hrt, ns_to_ktime(iprtd->poll_time_ns)); +	return HRTIMER_RESTART;  }  static struct fiq_handler fh = { @@ -98,8 +97,8 @@ static int snd_imx_pcm_hw_params(struct snd_pcm_substream *substream,  	iprtd->period = params_period_bytes(params) ;  	iprtd->offset = 0;  	iprtd->last_offset = 0; -	iprtd->poll_time = HZ / (params_rate(params) / params_period_size(params)); - +	iprtd->poll_time_ns = 1000000000 / params_rate(params) * +				params_period_size(params);  	snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);  	return 0; @@ -134,8 +133,9 @@ static int snd_imx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)  	case SNDRV_PCM_TRIGGER_START:  	case SNDRV_PCM_TRIGGER_RESUME:  	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: -		imx_ssi_set_next_poll(iprtd); -		add_timer(&iprtd->timer); +		atomic_set(&iprtd->running, 1); +		hrtimer_start(&iprtd->hrt, ns_to_ktime(iprtd->poll_time_ns), +		      HRTIMER_MODE_REL);  		if (++fiq_enable == 1)  			enable_fiq(imx_pcm_fiq); @@ -144,11 +144,11 @@ static int snd_imx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)  	case SNDRV_PCM_TRIGGER_STOP:  	case SNDRV_PCM_TRIGGER_SUSPEND:  	case SNDRV_PCM_TRIGGER_PAUSE_PUSH: -		del_timer(&iprtd->timer); +		atomic_set(&iprtd->running, 0); +  		if (--fiq_enable == 0)  			disable_fiq(imx_pcm_fiq); -  		break;  	default:  		return -EINVAL; @@ -179,7 +179,7 @@ static struct snd_pcm_hardware snd_imx_hardware = {  	.buffer_bytes_max = IMX_SSI_DMABUF_SIZE,  	.period_bytes_min = 128,  	.period_bytes_max = 16 * 1024, -	.periods_min = 2, +	.periods_min = 4,  	.periods_max = 255,  	.fifo_size = 0,  }; @@ -193,9 +193,11 @@ static int snd_imx_open(struct snd_pcm_substream *substream)  	iprtd = kzalloc(sizeof(*iprtd), GFP_KERNEL);  	runtime->private_data = iprtd; -	init_timer(&iprtd->timer); -	iprtd->timer.data = (unsigned long)substream; -	iprtd->timer.function = imx_ssi_timer_callback; +	iprtd->substream = substream; + +	atomic_set(&iprtd->running, 0); +	hrtimer_init(&iprtd->hrt, CLOCK_MONOTONIC, HRTIMER_MODE_REL); +	iprtd->hrt.function = snd_hrtimer_callback;  	ret = snd_pcm_hw_constraint_integer(substream->runtime,  			SNDRV_PCM_HW_PARAM_PERIODS); @@ -211,7 +213,8 @@ static int snd_imx_close(struct snd_pcm_substream *substream)  	struct snd_pcm_runtime *runtime = substream->runtime;  	struct imx_pcm_runtime_data *iprtd = runtime->private_data; -	del_timer_sync(&iprtd->timer); +	hrtimer_cancel(&iprtd->hrt); +  	kfree(iprtd);  	return 0; diff --git a/sound/soc/imx/imx-ssi.c b/sound/soc/imx/imx-ssi.c index 28e55c7b14b..1bf9dc88bab 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)  	dai->private_data = ssi;  	if ((cpu_is_mx27() || cpu_is_mx21()) && -			!(ssi->flags & IMX_SSI_USE_AC97)) { +			!(ssi->flags & IMX_SSI_USE_AC97) && +			(ssi->flags & IMX_SSI_DMA)) {  		ssi->flags |= IMX_SSI_DMA;  		platform = imx_ssi_dma_mx2_init(pdev, ssi);  	} else  |