[PATCH V1 1/3] Basic split of mpc5200 DMA code out from mpc5200_psc_i2s

2009-04-26 Thread Jon Smirl
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

2009-04-26 Thread Grant Likely
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);
 +