[PATCH V1 1/3] Basic split of mpc5200 DMA code out from mpc5200_psc_i2s
Basic split of mpc5200 DMA code out from i2s into a standalone file. Signed-off-by: Jon Smirl jonsm...@gmail.com --- sound/soc/fsl/Kconfig |4 sound/soc/fsl/Makefile |2 sound/soc/fsl/mpc5200_dma.c | 457 + sound/soc/fsl/mpc5200_dma.h | 81 +++ sound/soc/fsl/mpc5200_psc_i2s.c | 484 --- 5 files changed, 546 insertions(+), 482 deletions(-) create mode 100644 sound/soc/fsl/mpc5200_dma.c create mode 100644 sound/soc/fsl/mpc5200_dma.h diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig index 9fc9082..dc79bdf 100644 --- a/sound/soc/fsl/Kconfig +++ b/sound/soc/fsl/Kconfig @@ -1,5 +1,8 @@ config SND_SOC_OF_SIMPLE tristate + +config SND_MPC52xx_DMA + tristate # ASoC platform support for the Freescale MPC8610 SOC. This compiles drivers # for the SSI and the Elo DMA controller. You will still need to select @@ -23,6 +26,7 @@ config SND_SOC_MPC5200_I2S tristate Freescale MPC5200 PSC in I2S mode driver depends on PPC_MPC52xx PPC_BESTCOMM select SND_SOC_OF_SIMPLE + select SND_MPC52xx_DMA select PPC_BESTCOMM_GEN_BD help Say Y here to support the MPC5200 PSCs in I2S mode. diff --git a/sound/soc/fsl/Makefile b/sound/soc/fsl/Makefile index f85134c..7731ef2 100644 --- a/sound/soc/fsl/Makefile +++ b/sound/soc/fsl/Makefile @@ -10,5 +10,7 @@ snd-soc-fsl-ssi-objs := fsl_ssi.o snd-soc-fsl-dma-objs := fsl_dma.o obj-$(CONFIG_SND_SOC_MPC8610) += snd-soc-fsl-ssi.o snd-soc-fsl-dma.o +# MPC5200 Platform Support +obj-$(CONFIG_SND_MPC52xx_DMA) += mpc5200_dma.o obj-$(CONFIG_SND_SOC_MPC5200_I2S) += mpc5200_psc_i2s.o diff --git a/sound/soc/fsl/mpc5200_dma.c b/sound/soc/fsl/mpc5200_dma.c new file mode 100644 index 000..cccaff4 --- /dev/null +++ b/sound/soc/fsl/mpc5200_dma.c @@ -0,0 +1,457 @@ +/* + * Freescale MPC5200 PSC DMA + * ALSA SoC Platform driver + * + * Copyright (C) 2008 Secret Lab Technologies Ltd. + */ + +#include linux/init.h +#include linux/module.h +#include linux/interrupt.h +#include linux/device.h +#include linux/delay.h +#include linux/of_device.h +#include linux/of_platform.h +#include linux/dma-mapping.h + +#include sound/core.h +#include sound/pcm.h +#include sound/pcm_params.h +#include sound/initval.h +#include sound/soc.h +#include sound/soc-of-simple.h + +#include sysdev/bestcomm/bestcomm.h +#include sysdev/bestcomm/gen_bd.h +#include asm/mpc52xx_psc.h + +#include mpc5200_dma.h + +MODULE_AUTHOR(Grant Likely grant.lik...@secretlab.ca); +MODULE_DESCRIPTION(Freescale MPC5200 PSC in DMA mode ASoC Driver); +MODULE_LICENSE(GPL); + +/* + * Interrupt handlers + */ +static irqreturn_t psc_i2s_status_irq(int irq, void *_psc_i2s) +{ + struct psc_i2s *psc_i2s = _psc_i2s; + struct mpc52xx_psc __iomem *regs = psc_i2s-psc_regs; + u16 isr; + + isr = in_be16(regs-mpc52xx_psc_isr); + + /* Playback underrun error */ + if (psc_i2s-playback.active (isr MPC52xx_PSC_IMR_TXEMP)) + psc_i2s-stats.underrun_count++; + + /* Capture overrun error */ + if (psc_i2s-capture.active (isr MPC52xx_PSC_IMR_ORERR)) + psc_i2s-stats.overrun_count++; + + out_8(regs-command, 4 4); /* reset the error status */ + + return IRQ_HANDLED; +} + +/** + * psc_i2s_bcom_enqueue_next_buffer - Enqueue another audio buffer + * @s: pointer to stream private data structure + * + * Enqueues another audio period buffer into the bestcomm queue. + * + * Note: The routine must only be called when there is space available in + * the queue. Otherwise the enqueue will fail and the audio ring buffer + * will get out of sync + */ +static void psc_i2s_bcom_enqueue_next_buffer(struct psc_i2s_stream *s) +{ + struct bcom_bd *bd; + + /* Prepare and enqueue the next buffer descriptor */ + bd = bcom_prepare_next_buffer(s-bcom_task); + bd-status = s-period_bytes; + bd-data[0] = s-period_next_pt; + bcom_submit_next_buffer(s-bcom_task, NULL); + + /* Update for next period */ + s-period_next_pt += s-period_bytes; + if (s-period_next_pt = s-period_end) + s-period_next_pt = s-period_start; +} + +/* Bestcomm DMA irq handler */ +static irqreturn_t psc_i2s_bcom_irq(int irq, void *_psc_i2s_stream) +{ + struct psc_i2s_stream *s = _psc_i2s_stream; + + /* For each finished period, dequeue the completed period buffer +* and enqueue a new one in it's place. */ + while (bcom_buffer_done(s-bcom_task)) { + bcom_retrieve_buffer(s-bcom_task, NULL, NULL); + s-period_current_pt += s-period_bytes; + if (s-period_current_pt = s-period_end) + s-period_current_pt = s-period_start; + psc_i2s_bcom_enqueue_next_buffer(s); + bcom_enable(s-bcom_task); + } + + /* If the stream is active, then also inform the PCM
Re: [PATCH V1 1/3] Basic split of mpc5200 DMA code out from mpc5200_psc_i2s
On Sun, Apr 26, 2009 at 1:53 PM, Jon Smirl jonsm...@gmail.com wrote: Basic split of mpc5200 DMA code out from i2s into a standalone file. Signed-off-by: Jon Smirl jonsm...@gmail.com Acked-by: Grant Likely grant.lik...@secretlab.ca But you should really also send this to the ALSA list. I cannot merge this patch. g. --- sound/soc/fsl/Kconfig | 4 sound/soc/fsl/Makefile | 2 sound/soc/fsl/mpc5200_dma.c | 457 + sound/soc/fsl/mpc5200_dma.h | 81 +++ sound/soc/fsl/mpc5200_psc_i2s.c | 484 --- 5 files changed, 546 insertions(+), 482 deletions(-) create mode 100644 sound/soc/fsl/mpc5200_dma.c create mode 100644 sound/soc/fsl/mpc5200_dma.h diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig index 9fc9082..dc79bdf 100644 --- a/sound/soc/fsl/Kconfig +++ b/sound/soc/fsl/Kconfig @@ -1,5 +1,8 @@ config SND_SOC_OF_SIMPLE tristate + +config SND_MPC52xx_DMA + tristate # ASoC platform support for the Freescale MPC8610 SOC. This compiles drivers # for the SSI and the Elo DMA controller. You will still need to select @@ -23,6 +26,7 @@ config SND_SOC_MPC5200_I2S tristate Freescale MPC5200 PSC in I2S mode driver depends on PPC_MPC52xx PPC_BESTCOMM select SND_SOC_OF_SIMPLE + select SND_MPC52xx_DMA select PPC_BESTCOMM_GEN_BD help Say Y here to support the MPC5200 PSCs in I2S mode. diff --git a/sound/soc/fsl/Makefile b/sound/soc/fsl/Makefile index f85134c..7731ef2 100644 --- a/sound/soc/fsl/Makefile +++ b/sound/soc/fsl/Makefile @@ -10,5 +10,7 @@ snd-soc-fsl-ssi-objs := fsl_ssi.o snd-soc-fsl-dma-objs := fsl_dma.o obj-$(CONFIG_SND_SOC_MPC8610) += snd-soc-fsl-ssi.o snd-soc-fsl-dma.o +# MPC5200 Platform Support +obj-$(CONFIG_SND_MPC52xx_DMA) += mpc5200_dma.o obj-$(CONFIG_SND_SOC_MPC5200_I2S) += mpc5200_psc_i2s.o diff --git a/sound/soc/fsl/mpc5200_dma.c b/sound/soc/fsl/mpc5200_dma.c new file mode 100644 index 000..cccaff4 --- /dev/null +++ b/sound/soc/fsl/mpc5200_dma.c @@ -0,0 +1,457 @@ +/* + * Freescale MPC5200 PSC DMA + * ALSA SoC Platform driver + * + * Copyright (C) 2008 Secret Lab Technologies Ltd. + */ + +#include linux/init.h +#include linux/module.h +#include linux/interrupt.h +#include linux/device.h +#include linux/delay.h +#include linux/of_device.h +#include linux/of_platform.h +#include linux/dma-mapping.h + +#include sound/core.h +#include sound/pcm.h +#include sound/pcm_params.h +#include sound/initval.h +#include sound/soc.h +#include sound/soc-of-simple.h + +#include sysdev/bestcomm/bestcomm.h +#include sysdev/bestcomm/gen_bd.h +#include asm/mpc52xx_psc.h + +#include mpc5200_dma.h + +MODULE_AUTHOR(Grant Likely grant.lik...@secretlab.ca); +MODULE_DESCRIPTION(Freescale MPC5200 PSC in DMA mode ASoC Driver); +MODULE_LICENSE(GPL); + +/* + * Interrupt handlers + */ +static irqreturn_t psc_i2s_status_irq(int irq, void *_psc_i2s) +{ + struct psc_i2s *psc_i2s = _psc_i2s; + struct mpc52xx_psc __iomem *regs = psc_i2s-psc_regs; + u16 isr; + + isr = in_be16(regs-mpc52xx_psc_isr); + + /* Playback underrun error */ + if (psc_i2s-playback.active (isr MPC52xx_PSC_IMR_TXEMP)) + psc_i2s-stats.underrun_count++; + + /* Capture overrun error */ + if (psc_i2s-capture.active (isr MPC52xx_PSC_IMR_ORERR)) + psc_i2s-stats.overrun_count++; + + out_8(regs-command, 4 4); /* reset the error status */ + + return IRQ_HANDLED; +} + +/** + * psc_i2s_bcom_enqueue_next_buffer - Enqueue another audio buffer + * @s: pointer to stream private data structure + * + * Enqueues another audio period buffer into the bestcomm queue. + * + * Note: The routine must only be called when there is space available in + * the queue. Otherwise the enqueue will fail and the audio ring buffer + * will get out of sync + */ +static void psc_i2s_bcom_enqueue_next_buffer(struct psc_i2s_stream *s) +{ + struct bcom_bd *bd; + + /* Prepare and enqueue the next buffer descriptor */ + bd = bcom_prepare_next_buffer(s-bcom_task); + bd-status = s-period_bytes; + bd-data[0] = s-period_next_pt; + bcom_submit_next_buffer(s-bcom_task, NULL); + + /* Update for next period */ + s-period_next_pt += s-period_bytes; + if (s-period_next_pt = s-period_end) + s-period_next_pt = s-period_start; +} + +/* Bestcomm DMA irq handler */ +static irqreturn_t psc_i2s_bcom_irq(int irq, void *_psc_i2s_stream) +{ + struct psc_i2s_stream *s = _psc_i2s_stream; + + /* For each finished period, dequeue the completed period buffer + * and enqueue a new one in it's place. */ + while (bcom_buffer_done(s-bcom_task)) { + bcom_retrieve_buffer(s-bcom_task, NULL, NULL); +