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 wrote: > Basic split of mpc5200 DMA code out from i2s into a standalone file. > > Signed-off-by: Jon Smirl Acked-by: Grant Likely 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 > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include > +#include > +#include > + > +#include "mpc5200_dma.h" > + > +MODULE_AUTHOR("Grant Likely "); > +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(®s->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(®s->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; > +
[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 --- 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 +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "mpc5200_dma.h" + +MODULE_AUTHOR("Grant Likely "); +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(®s->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(®s->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 middle layer +* of the period finished event. */ + if (s->active) + snd_pcm_period_elapsed(s->stream); + + return IRQ_HANDLED; +} + +/** + * psc_i2s_startup: create a new substream + * + * This is the first function called when a stream is open