Loading sound/soc/imx/imx-pcm-fiq.c +30 −10 Original line number Original line Diff line number Diff line Loading @@ -35,22 +35,25 @@ struct imx_pcm_runtime_data { struct imx_pcm_runtime_data { int period; int period; int periods; int periods; unsigned long dma_addr; int dma; unsigned long offset; unsigned long offset; unsigned long last_offset; unsigned long size; unsigned long size; unsigned long period_cnt; void *buf; struct timer_list timer; struct timer_list timer; int period_time; int poll_time; }; }; static inline void imx_ssi_set_next_poll(struct imx_pcm_runtime_data *iprtd) { iprtd->timer.expires = jiffies + iprtd->poll_time; } static void imx_ssi_timer_callback(unsigned long data) static void imx_ssi_timer_callback(unsigned long data) { { struct snd_pcm_substream *substream = (void *)data; struct snd_pcm_substream *substream = (void *)data; struct snd_pcm_runtime *runtime = substream->runtime; struct snd_pcm_runtime *runtime = substream->runtime; struct imx_pcm_runtime_data *iprtd = runtime->private_data; struct imx_pcm_runtime_data *iprtd = runtime->private_data; struct pt_regs regs; struct pt_regs regs; unsigned long delta; get_fiq_regs(®s); get_fiq_regs(®s); Loading @@ -59,9 +62,25 @@ static void imx_ssi_timer_callback(unsigned long data) else else iprtd->offset = regs.ARM_r9 & 0xffff; iprtd->offset = regs.ARM_r9 & 0xffff; iprtd->timer.expires = jiffies + iprtd->period_time; /* How much data have we transferred since the last period report? */ add_timer(&iprtd->timer); if (iprtd->offset >= iprtd->last_offset) delta = iprtd->offset - iprtd->last_offset; else delta = runtime->buffer_size + iprtd->offset - iprtd->last_offset; /* If we've transferred at least a period then report it and * reset our poll time */ if (delta >= runtime->period_size) { snd_pcm_period_elapsed(substream); 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); } } static struct fiq_handler fh = { static struct fiq_handler fh = { Loading @@ -78,7 +97,8 @@ static int snd_imx_pcm_hw_params(struct snd_pcm_substream *substream, iprtd->periods = params_periods(params); iprtd->periods = params_periods(params); iprtd->period = params_period_bytes(params) ; iprtd->period = params_period_bytes(params) ; iprtd->offset = 0; iprtd->offset = 0; iprtd->period_time = HZ / (params_rate(params) / params_period_size(params)); iprtd->last_offset = 0; iprtd->poll_time = HZ / (params_rate(params) / params_period_size(params)); snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); Loading Loading @@ -114,7 +134,7 @@ static int snd_imx_pcm_trigger(struct snd_pcm_substream *substream, int cmd) case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_RESUME: case SNDRV_PCM_TRIGGER_RESUME: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: iprtd->timer.expires = jiffies + iprtd->period_time; imx_ssi_set_next_poll(iprtd); add_timer(&iprtd->timer); add_timer(&iprtd->timer); if (++fiq_enable == 1) if (++fiq_enable == 1) enable_fiq(imx_pcm_fiq); enable_fiq(imx_pcm_fiq); Loading Loading
sound/soc/imx/imx-pcm-fiq.c +30 −10 Original line number Original line Diff line number Diff line Loading @@ -35,22 +35,25 @@ struct imx_pcm_runtime_data { struct imx_pcm_runtime_data { int period; int period; int periods; int periods; unsigned long dma_addr; int dma; unsigned long offset; unsigned long offset; unsigned long last_offset; unsigned long size; unsigned long size; unsigned long period_cnt; void *buf; struct timer_list timer; struct timer_list timer; int period_time; int poll_time; }; }; static inline void imx_ssi_set_next_poll(struct imx_pcm_runtime_data *iprtd) { iprtd->timer.expires = jiffies + iprtd->poll_time; } static void imx_ssi_timer_callback(unsigned long data) static void imx_ssi_timer_callback(unsigned long data) { { struct snd_pcm_substream *substream = (void *)data; struct snd_pcm_substream *substream = (void *)data; struct snd_pcm_runtime *runtime = substream->runtime; struct snd_pcm_runtime *runtime = substream->runtime; struct imx_pcm_runtime_data *iprtd = runtime->private_data; struct imx_pcm_runtime_data *iprtd = runtime->private_data; struct pt_regs regs; struct pt_regs regs; unsigned long delta; get_fiq_regs(®s); get_fiq_regs(®s); Loading @@ -59,9 +62,25 @@ static void imx_ssi_timer_callback(unsigned long data) else else iprtd->offset = regs.ARM_r9 & 0xffff; iprtd->offset = regs.ARM_r9 & 0xffff; iprtd->timer.expires = jiffies + iprtd->period_time; /* How much data have we transferred since the last period report? */ add_timer(&iprtd->timer); if (iprtd->offset >= iprtd->last_offset) delta = iprtd->offset - iprtd->last_offset; else delta = runtime->buffer_size + iprtd->offset - iprtd->last_offset; /* If we've transferred at least a period then report it and * reset our poll time */ if (delta >= runtime->period_size) { snd_pcm_period_elapsed(substream); 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); } } static struct fiq_handler fh = { static struct fiq_handler fh = { Loading @@ -78,7 +97,8 @@ static int snd_imx_pcm_hw_params(struct snd_pcm_substream *substream, iprtd->periods = params_periods(params); iprtd->periods = params_periods(params); iprtd->period = params_period_bytes(params) ; iprtd->period = params_period_bytes(params) ; iprtd->offset = 0; iprtd->offset = 0; iprtd->period_time = HZ / (params_rate(params) / params_period_size(params)); iprtd->last_offset = 0; iprtd->poll_time = HZ / (params_rate(params) / params_period_size(params)); snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); Loading Loading @@ -114,7 +134,7 @@ static int snd_imx_pcm_trigger(struct snd_pcm_substream *substream, int cmd) case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_RESUME: case SNDRV_PCM_TRIGGER_RESUME: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: iprtd->timer.expires = jiffies + iprtd->period_time; imx_ssi_set_next_poll(iprtd); add_timer(&iprtd->timer); add_timer(&iprtd->timer); if (++fiq_enable == 1) if (++fiq_enable == 1) enable_fiq(imx_pcm_fiq); enable_fiq(imx_pcm_fiq); Loading