diff options
Diffstat (limited to 'sound/soc/fsl')
-rw-r--r-- | sound/soc/fsl/Kconfig | 6 | ||||
-rw-r--r-- | sound/soc/fsl/efika-audio-fabric.c | 2 | ||||
-rw-r--r-- | sound/soc/fsl/mpc5200_dma.c | 51 | ||||
-rw-r--r-- | sound/soc/fsl/mpc5200_dma.h | 1 | ||||
-rw-r--r-- | sound/soc/fsl/mpc5200_psc_ac97.c | 20 | ||||
-rw-r--r-- | sound/soc/fsl/pcm030-audio-fabric.c | 2 |
6 files changed, 64 insertions, 18 deletions
diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig index 5dbebf82249c..8cb65ccad35f 100644 --- a/sound/soc/fsl/Kconfig +++ b/sound/soc/fsl/Kconfig @@ -33,7 +33,7 @@ config SND_SOC_MPC5200_I2S config SND_SOC_MPC5200_AC97 tristate "Freescale MPC5200 PSC in AC97 mode driver" depends on PPC_MPC52xx && PPC_BESTCOMM - select AC97_BUS + select SND_SOC_AC97_BUS select SND_MPC52xx_DMA select PPC_BESTCOMM_GEN_BD help @@ -41,7 +41,7 @@ config SND_SOC_MPC5200_AC97 config SND_MPC52xx_SOC_PCM030 tristate "SoC AC97 Audio support for Phytec pcm030 and WM9712" - depends on PPC_MPC5200_SIMPLE && BROKEN + depends on PPC_MPC5200_SIMPLE select SND_SOC_MPC5200_AC97 select SND_SOC_WM9712 help @@ -50,7 +50,7 @@ config SND_MPC52xx_SOC_PCM030 config SND_MPC52xx_SOC_EFIKA tristate "SoC AC97 Audio support for bbplan Efika and STAC9766" - depends on PPC_EFIKA && BROKEN + depends on PPC_EFIKA select SND_SOC_MPC5200_AC97 select SND_SOC_STAC9766 help diff --git a/sound/soc/fsl/efika-audio-fabric.c b/sound/soc/fsl/efika-audio-fabric.c index 85b0e7569504..3326e2a1e863 100644 --- a/sound/soc/fsl/efika-audio-fabric.c +++ b/sound/soc/fsl/efika-audio-fabric.c @@ -30,6 +30,8 @@ #include "mpc5200_psc_ac97.h" #include "../codecs/stac9766.h" +#define DRV_NAME "efika-audio-fabric" + static struct snd_soc_device device; static struct snd_soc_card card; diff --git a/sound/soc/fsl/mpc5200_dma.c b/sound/soc/fsl/mpc5200_dma.c index efec33a1c5bd..6096d22283e6 100644 --- a/sound/soc/fsl/mpc5200_dma.c +++ b/sound/soc/fsl/mpc5200_dma.c @@ -69,6 +69,23 @@ static void psc_dma_bcom_enqueue_next_buffer(struct psc_dma_stream *s) static void psc_dma_bcom_enqueue_tx(struct psc_dma_stream *s) { + if (s->appl_ptr > s->runtime->control->appl_ptr) { + /* + * In this case s->runtime->control->appl_ptr has wrapped around. + * Play the data to the end of the boundary, then wrap our own + * appl_ptr back around. + */ + while (s->appl_ptr < s->runtime->boundary) { + if (bcom_queue_full(s->bcom_task)) + return; + + s->appl_ptr += s->period_size; + + psc_dma_bcom_enqueue_next_buffer(s); + } + s->appl_ptr -= s->runtime->boundary; + } + while (s->appl_ptr < s->runtime->control->appl_ptr) { if (bcom_queue_full(s->bcom_task)) @@ -430,6 +447,7 @@ int mpc5200_audio_dma_create(struct of_device *op) int size, irq, rc; const __be32 *prop; void __iomem *regs; + int ret; /* Fetch the registers and IRQ of the PSC */ irq = irq_of_parse_and_map(op->node, 0); @@ -446,16 +464,19 @@ int mpc5200_audio_dma_create(struct of_device *op) /* Allocate and initialize the driver private data */ psc_dma = kzalloc(sizeof *psc_dma, GFP_KERNEL); if (!psc_dma) { - iounmap(regs); - return -ENOMEM; + ret = -ENOMEM; + goto out_unmap; } /* Get the PSC ID */ prop = of_get_property(op->node, "cell-index", &size); - if (!prop || size < sizeof *prop) - return -ENODEV; + if (!prop || size < sizeof *prop) { + ret = -ENODEV; + goto out_free; + } spin_lock_init(&psc_dma->lock); + mutex_init(&psc_dma->mutex); psc_dma->id = be32_to_cpu(*prop); psc_dma->irq = irq; psc_dma->psc_regs = regs; @@ -475,9 +496,8 @@ int mpc5200_audio_dma_create(struct of_device *op) if (!psc_dma->capture.bcom_task || !psc_dma->playback.bcom_task) { dev_err(&op->dev, "Could not allocate bestcomm tasks\n"); - iounmap(regs); - kfree(psc_dma); - return -ENODEV; + ret = -ENODEV; + goto out_free; } /* Disable all interrupts and reset the PSC */ @@ -519,12 +539,8 @@ int mpc5200_audio_dma_create(struct of_device *op) &psc_dma_bcom_irq_tx, IRQF_SHARED, "psc-dma-playback", &psc_dma->playback); if (rc) { - free_irq(psc_dma->irq, psc_dma); - free_irq(psc_dma->capture.irq, - &psc_dma->capture); - free_irq(psc_dma->playback.irq, - &psc_dma->playback); - return -ENODEV; + ret = -ENODEV; + goto out_irq; } /* Save what we've done so it can be found again later */ @@ -532,6 +548,15 @@ int mpc5200_audio_dma_create(struct of_device *op) /* Tell the ASoC OF helpers about it */ return snd_soc_register_platform(&mpc5200_audio_dma_platform); +out_irq: + free_irq(psc_dma->irq, psc_dma); + free_irq(psc_dma->capture.irq, &psc_dma->capture); + free_irq(psc_dma->playback.irq, &psc_dma->playback); +out_free: + kfree(psc_dma); +out_unmap: + iounmap(regs); + return ret; } EXPORT_SYMBOL_GPL(mpc5200_audio_dma_create); diff --git a/sound/soc/fsl/mpc5200_dma.h b/sound/soc/fsl/mpc5200_dma.h index 2000803f06a7..8d396bb9d9fe 100644 --- a/sound/soc/fsl/mpc5200_dma.h +++ b/sound/soc/fsl/mpc5200_dma.h @@ -55,6 +55,7 @@ struct psc_dma { unsigned int irq; struct device *dev; spinlock_t lock; + struct mutex mutex; u32 sicr; uint sysclk; int imr; diff --git a/sound/soc/fsl/mpc5200_psc_ac97.c b/sound/soc/fsl/mpc5200_psc_ac97.c index 794a247b3eb5..c4ae3e096bb9 100644 --- a/sound/soc/fsl/mpc5200_psc_ac97.c +++ b/sound/soc/fsl/mpc5200_psc_ac97.c @@ -12,6 +12,7 @@ #include <linux/module.h> #include <linux/of_device.h> #include <linux/of_platform.h> +#include <linux/delay.h> #include <sound/pcm.h> #include <sound/pcm_params.h> @@ -34,13 +35,20 @@ static unsigned short psc_ac97_read(struct snd_ac97 *ac97, unsigned short reg) int status; unsigned int val; + mutex_lock(&psc_dma->mutex); + /* Wait for command send status zero = ready */ status = spin_event_timeout(!(in_be16(&psc_dma->psc_regs->sr_csr.status) & MPC52xx_PSC_SR_CMDSEND), 100, 0); if (status == 0) { pr_err("timeout on ac97 bus (rdy)\n"); + mutex_unlock(&psc_dma->mutex); return -ENODEV; } + + /* Force clear the data valid bit */ + in_be32(&psc_dma->psc_regs->ac97_data); + /* Send the read */ out_be32(&psc_dma->psc_regs->ac97_cmd, (1<<31) | ((reg & 0x7f) << 24)); @@ -50,16 +58,19 @@ static unsigned short psc_ac97_read(struct snd_ac97 *ac97, unsigned short reg) if (status == 0) { pr_err("timeout on ac97 read (val) %x\n", in_be16(&psc_dma->psc_regs->sr_csr.status)); + mutex_unlock(&psc_dma->mutex); return -ENODEV; } /* Get the data */ val = in_be32(&psc_dma->psc_regs->ac97_data); if (((val >> 24) & 0x7f) != reg) { pr_err("reg echo error on ac97 read\n"); + mutex_unlock(&psc_dma->mutex); return -ENODEV; } val = (val >> 8) & 0xffff; + mutex_unlock(&psc_dma->mutex); return (unsigned short) val; } @@ -68,16 +79,21 @@ static void psc_ac97_write(struct snd_ac97 *ac97, { int status; + mutex_lock(&psc_dma->mutex); + /* Wait for command status zero = ready */ status = spin_event_timeout(!(in_be16(&psc_dma->psc_regs->sr_csr.status) & MPC52xx_PSC_SR_CMDSEND), 100, 0); if (status == 0) { pr_err("timeout on ac97 bus (write)\n"); - return; + goto out; } /* Write data */ out_be32(&psc_dma->psc_regs->ac97_cmd, ((reg & 0x7f) << 24) | (val << 8)); + + out: + mutex_unlock(&psc_dma->mutex); } static void psc_ac97_warm_reset(struct snd_ac97 *ac97) @@ -97,7 +113,7 @@ static void psc_ac97_cold_reset(struct snd_ac97 *ac97) out_8(®s->op1, MPC52xx_PSC_OP_RES); udelay(10); out_8(®s->op0, MPC52xx_PSC_OP_RES); - udelay(50); + msleep(1); psc_ac97_warm_reset(ac97); } diff --git a/sound/soc/fsl/pcm030-audio-fabric.c b/sound/soc/fsl/pcm030-audio-fabric.c index 8766f7a3893d..b928ef7d28eb 100644 --- a/sound/soc/fsl/pcm030-audio-fabric.c +++ b/sound/soc/fsl/pcm030-audio-fabric.c @@ -30,6 +30,8 @@ #include "mpc5200_psc_ac97.h" #include "../codecs/wm9712.h" +#define DRV_NAME "pcm030-audio-fabric" + static struct snd_soc_device device; static struct snd_soc_card card; |