diff options
Diffstat (limited to 'sound/soc/txx9')
| -rw-r--r-- | sound/soc/txx9/txx9aclc-ac97.c | 107 | ||||
| -rw-r--r-- | sound/soc/txx9/txx9aclc-generic.c | 28 | ||||
| -rw-r--r-- | sound/soc/txx9/txx9aclc.c | 163 | ||||
| -rw-r--r-- | sound/soc/txx9/txx9aclc.h | 13 |
4 files changed, 143 insertions, 168 deletions
diff --git a/sound/soc/txx9/txx9aclc-ac97.c b/sound/soc/txx9/txx9aclc-ac97.c index 0f83bdb9b16..9edd68db9f4 100644 --- a/sound/soc/txx9/txx9aclc-ac97.c +++ b/sound/soc/txx9/txx9aclc-ac97.c @@ -16,6 +16,7 @@ #include <linux/delay.h> #include <linux/interrupt.h> #include <linux/io.h> +#include <linux/gfp.h> #include <sound/core.h> #include <sound/pcm.h> #include <sound/soc.h> @@ -35,13 +36,11 @@ static DECLARE_WAIT_QUEUE_HEAD(ac97_waitq); -/* REVISIT: How to find txx9aclc_soc_device from snd_ac97? */ -static struct txx9aclc_soc_device *txx9aclc_soc_dev; +/* REVISIT: How to find txx9aclc_drvdata from snd_ac97? */ +static struct txx9aclc_plat_drvdata *txx9aclc_drvdata; -static int txx9aclc_regready(struct txx9aclc_soc_device *dev) +static int txx9aclc_regready(struct txx9aclc_plat_drvdata *drvdata) { - struct txx9aclc_plat_drvdata *drvdata = txx9aclc_get_plat_drvdata(dev); - return __raw_readl(drvdata->base + ACINTSTS) & ACINT_REGACCRDY; } @@ -49,8 +48,7 @@ static int txx9aclc_regready(struct txx9aclc_soc_device *dev) static unsigned short txx9aclc_ac97_read(struct snd_ac97 *ac97, unsigned short reg) { - struct txx9aclc_soc_device *dev = txx9aclc_soc_dev; - struct txx9aclc_plat_drvdata *drvdata = txx9aclc_get_plat_drvdata(dev); + struct txx9aclc_plat_drvdata *drvdata = txx9aclc_drvdata; void __iomem *base = drvdata->base; u32 dat; @@ -60,15 +58,15 @@ static unsigned short txx9aclc_ac97_read(struct snd_ac97 *ac97, dat = (reg << ACREGACC_REG_SHIFT) | ACREGACC_READ; __raw_writel(dat, base + ACREGACC); __raw_writel(ACINT_REGACCRDY, base + ACINTEN); - if (!wait_event_timeout(ac97_waitq, txx9aclc_regready(dev), HZ)) { + if (!wait_event_timeout(ac97_waitq, txx9aclc_regready(txx9aclc_drvdata), HZ)) { __raw_writel(ACINT_REGACCRDY, base + ACINTDIS); - dev_err(dev->soc_dev.dev, "ac97 read timeout (reg %#x)\n", reg); + printk(KERN_ERR "ac97 read timeout (reg %#x)\n", reg); dat = 0xffff; goto done; } dat = __raw_readl(base + ACREGACC); if (((dat >> ACREGACC_REG_SHIFT) & 0xff) != reg) { - dev_err(dev->soc_dev.dev, "reg mismatch %x with %x\n", + printk(KERN_ERR "reg mismatch %x with %x\n", dat, reg); dat = 0xffff; goto done; @@ -83,16 +81,15 @@ done: static void txx9aclc_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigned short val) { - struct txx9aclc_soc_device *dev = txx9aclc_soc_dev; - struct txx9aclc_plat_drvdata *drvdata = txx9aclc_get_plat_drvdata(dev); + struct txx9aclc_plat_drvdata *drvdata = txx9aclc_drvdata; void __iomem *base = drvdata->base; __raw_writel(((reg | (ac97->num << 7)) << ACREGACC_REG_SHIFT) | (val << ACREGACC_DAT_SHIFT), base + ACREGACC); __raw_writel(ACINT_REGACCRDY, base + ACINTEN); - if (!wait_event_timeout(ac97_waitq, txx9aclc_regready(dev), HZ)) { - dev_err(dev->soc_dev.dev, + if (!wait_event_timeout(ac97_waitq, txx9aclc_regready(txx9aclc_drvdata), HZ)) { + printk(KERN_ERR "ac97 write timeout (reg %#x)\n", reg); } __raw_writel(ACINT_REGACCRDY, base + ACINTDIS); @@ -100,8 +97,7 @@ static void txx9aclc_ac97_write(struct snd_ac97 *ac97, unsigned short reg, static void txx9aclc_ac97_cold_reset(struct snd_ac97 *ac97) { - struct txx9aclc_soc_device *dev = txx9aclc_soc_dev; - struct txx9aclc_plat_drvdata *drvdata = txx9aclc_get_plat_drvdata(dev); + struct txx9aclc_plat_drvdata *drvdata = txx9aclc_drvdata; void __iomem *base = drvdata->base; u32 ready = ACINT_CODECRDY(ac97->num) | ACINT_REGACCRDY; @@ -123,12 +119,11 @@ static void txx9aclc_ac97_cold_reset(struct snd_ac97 *ac97) } /* AC97 controller operations */ -struct snd_ac97_bus_ops soc_ac97_ops = { +static struct snd_ac97_bus_ops txx9aclc_ac97_ops = { .read = txx9aclc_ac97_read, .write = txx9aclc_ac97_write, .reset = txx9aclc_ac97_cold_reset, }; -EXPORT_SYMBOL_GPL(soc_ac97_ops); static irqreturn_t txx9aclc_ac97_irq(int irq, void *dev_id) { @@ -140,31 +135,23 @@ static irqreturn_t txx9aclc_ac97_irq(int irq, void *dev_id) return IRQ_HANDLED; } -static int txx9aclc_ac97_probe(struct platform_device *pdev, - struct snd_soc_dai *dai) +static int txx9aclc_ac97_probe(struct snd_soc_dai *dai) { - struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct txx9aclc_soc_device *dev = - container_of(socdev, struct txx9aclc_soc_device, soc_dev); - - dev->aclc_pdev = to_platform_device(dai->dev); - txx9aclc_soc_dev = dev; + txx9aclc_drvdata = snd_soc_dai_get_drvdata(dai); return 0; } -static void txx9aclc_ac97_remove(struct platform_device *pdev, - struct snd_soc_dai *dai) +static int txx9aclc_ac97_remove(struct snd_soc_dai *dai) { - struct platform_device *aclc_pdev = to_platform_device(dai->dev); - struct txx9aclc_plat_drvdata *drvdata = platform_get_drvdata(aclc_pdev); + struct txx9aclc_plat_drvdata *drvdata = snd_soc_dai_get_drvdata(dai); /* disable AC-link */ __raw_writel(ACCTL_ENLINK, drvdata->base + ACCTLDIS); - txx9aclc_soc_dev = NULL; + txx9aclc_drvdata = NULL; + return 0; } -struct snd_soc_dai txx9aclc_ac97_dai = { - .name = "txx9aclc_ac97", +static struct snd_soc_dai_driver txx9aclc_ac97_dai = { .ac97_control = 1, .probe = txx9aclc_ac97_probe, .remove = txx9aclc_ac97_remove, @@ -181,9 +168,12 @@ struct snd_soc_dai txx9aclc_ac97_dai = { .channels_max = 2, }, }; -EXPORT_SYMBOL_GPL(txx9aclc_ac97_dai); -static int __devinit txx9aclc_ac97_dev_probe(struct platform_device *pdev) +static const struct snd_soc_component_driver txx9aclc_ac97_component = { + .name = "txx9aclc-ac97", +}; + +static int txx9aclc_ac97_dev_probe(struct platform_device *pdev) { struct txx9aclc_plat_drvdata *drvdata; struct resource *r; @@ -193,63 +183,54 @@ static int __devinit txx9aclc_ac97_dev_probe(struct platform_device *pdev) irq = platform_get_irq(pdev, 0); if (irq < 0) return irq; - r = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!r) - return -EBUSY; - - if (!devm_request_mem_region(&pdev->dev, r->start, resource_size(r), - dev_name(&pdev->dev))) - return -EBUSY; drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL); if (!drvdata) return -ENOMEM; + + r = platform_get_resource(pdev, IORESOURCE_MEM, 0); + drvdata->base = devm_ioremap_resource(&pdev->dev, r); + if (IS_ERR(drvdata->base)) + return PTR_ERR(drvdata->base); + platform_set_drvdata(pdev, drvdata); drvdata->physbase = r->start; if (sizeof(drvdata->physbase) > sizeof(r->start) && r->start >= TXX9_DIRECTMAP_BASE && r->start < TXX9_DIRECTMAP_BASE + 0x400000) drvdata->physbase |= 0xf00000000ull; - drvdata->base = devm_ioremap(&pdev->dev, r->start, resource_size(r)); - if (!drvdata->base) - return -EBUSY; err = devm_request_irq(&pdev->dev, irq, txx9aclc_ac97_irq, - IRQF_DISABLED, dev_name(&pdev->dev), drvdata); + 0, dev_name(&pdev->dev), drvdata); if (err < 0) return err; - txx9aclc_ac97_dai.dev = &pdev->dev; - return snd_soc_register_dai(&txx9aclc_ac97_dai); + err = snd_soc_set_ac97_ops(&txx9aclc_ac97_ops); + if (err < 0) + return err; + + return snd_soc_register_component(&pdev->dev, &txx9aclc_ac97_component, + &txx9aclc_ac97_dai, 1); } -static int __devexit txx9aclc_ac97_dev_remove(struct platform_device *pdev) +static int txx9aclc_ac97_dev_remove(struct platform_device *pdev) { - snd_soc_unregister_dai(&txx9aclc_ac97_dai); + snd_soc_unregister_component(&pdev->dev); + snd_soc_set_ac97_ops(NULL); return 0; } static struct platform_driver txx9aclc_ac97_driver = { .probe = txx9aclc_ac97_dev_probe, - .remove = __devexit_p(txx9aclc_ac97_dev_remove), + .remove = txx9aclc_ac97_dev_remove, .driver = { .name = "txx9aclc-ac97", .owner = THIS_MODULE, }, }; -static int __init txx9aclc_ac97_init(void) -{ - return platform_driver_register(&txx9aclc_ac97_driver); -} - -static void __exit txx9aclc_ac97_exit(void) -{ - platform_driver_unregister(&txx9aclc_ac97_driver); -} - -module_init(txx9aclc_ac97_init); -module_exit(txx9aclc_ac97_exit); +module_platform_driver(txx9aclc_ac97_driver); MODULE_AUTHOR("Atsushi Nemoto <anemo@mba.ocn.ne.jp>"); MODULE_DESCRIPTION("TXx9 ACLC AC97 driver"); MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:txx9aclc-ac97"); diff --git a/sound/soc/txx9/txx9aclc-generic.c b/sound/soc/txx9/txx9aclc-generic.c index 3175de9a92c..b056a1431ed 100644 --- a/sound/soc/txx9/txx9aclc-generic.c +++ b/sound/soc/txx9/txx9aclc-generic.c @@ -19,60 +19,51 @@ #include <sound/core.h> #include <sound/pcm.h> #include <sound/soc.h> -#include "../codecs/ac97.h" #include "txx9aclc.h" static struct snd_soc_dai_link txx9aclc_generic_dai = { .name = "AC97", .stream_name = "AC97 HiFi", - .cpu_dai = &txx9aclc_ac97_dai, - .codec_dai = &ac97_dai, + .cpu_dai_name = "txx9aclc-ac97", + .codec_dai_name = "ac97-hifi", + .platform_name = "txx9aclc-pcm-audio", + .codec_name = "ac97-codec", }; static struct snd_soc_card txx9aclc_generic_card = { .name = "Generic TXx9 ACLC Audio", - .platform = &txx9aclc_soc_platform, + .owner = THIS_MODULE, .dai_link = &txx9aclc_generic_dai, .num_links = 1, }; -static struct txx9aclc_soc_device txx9aclc_generic_soc_device = { - .soc_dev = { - .card = &txx9aclc_generic_card, - .codec_dev = &soc_codec_dev_ac97, - }, -}; +static struct platform_device *soc_pdev; static int __init txx9aclc_generic_probe(struct platform_device *pdev) { - struct txx9aclc_soc_device *dev = &txx9aclc_generic_soc_device; - struct platform_device *soc_pdev; int ret; soc_pdev = platform_device_alloc("soc-audio", -1); if (!soc_pdev) return -ENOMEM; - platform_set_drvdata(soc_pdev, &dev->soc_dev); - dev->soc_dev.dev = &soc_pdev->dev; + platform_set_drvdata(soc_pdev, &txx9aclc_generic_card); ret = platform_device_add(soc_pdev); if (ret) { platform_device_put(soc_pdev); return ret; } - platform_set_drvdata(pdev, soc_pdev); + return 0; } static int __exit txx9aclc_generic_remove(struct platform_device *pdev) { - struct platform_device *soc_pdev = platform_get_drvdata(pdev); - platform_device_unregister(soc_pdev); return 0; } static struct platform_driver txx9aclc_generic_driver = { - .remove = txx9aclc_generic_remove, + .remove = __exit_p(txx9aclc_generic_remove), .driver = { .name = "txx9aclc-generic", .owner = THIS_MODULE, @@ -96,3 +87,4 @@ module_exit(txx9aclc_generic_exit); MODULE_AUTHOR("Atsushi Nemoto <anemo@mba.ocn.ne.jp>"); MODULE_DESCRIPTION("Generic TXx9 ACLC ALSA SoC audio driver"); MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:txx9aclc-generic"); diff --git a/sound/soc/txx9/txx9aclc.c b/sound/soc/txx9/txx9aclc.c index efed64b8b02..f0829de2870 100644 --- a/sound/soc/txx9/txx9aclc.c +++ b/sound/soc/txx9/txx9aclc.c @@ -15,12 +15,23 @@ #include <linux/init.h> #include <linux/platform_device.h> #include <linux/scatterlist.h> +#include <linux/slab.h> #include <sound/core.h> #include <sound/pcm.h> #include <sound/pcm_params.h> #include <sound/soc.h> #include "txx9aclc.h" +static struct txx9aclc_soc_device { + struct txx9aclc_dmadata dmadata[2]; +} txx9aclc_soc_device; + +/* REVISIT: How to find txx9aclc_drvdata from snd_ac97? */ +static struct txx9aclc_plat_drvdata *txx9aclc_drvdata; + +static int txx9aclc_dma_init(struct txx9aclc_soc_device *dev, + struct txx9aclc_dmadata *dmadata); + static const struct snd_pcm_hardware txx9aclc_pcm_hardware = { /* * REVISIT: SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID @@ -29,11 +40,6 @@ static const struct snd_pcm_hardware txx9aclc_pcm_hardware = { .info = SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BATCH | SNDRV_PCM_INFO_PAUSE, -#ifdef __BIG_ENDIAN - .formats = SNDRV_PCM_FMTBIT_S16_BE, -#else - .formats = SNDRV_PCM_FMTBIT_S16_LE, -#endif .period_bytes_min = 1024, .period_bytes_max = 8 * 1024, .periods_min = 2, @@ -45,7 +51,6 @@ static int txx9aclc_pcm_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream); - struct snd_soc_device *socdev = rtd->socdev; struct snd_pcm_runtime *runtime = substream->runtime; struct txx9aclc_dmadata *dmadata = runtime->private_data; int ret; @@ -54,13 +59,13 @@ static int txx9aclc_pcm_hw_params(struct snd_pcm_substream *substream, if (ret < 0) return ret; - dev_dbg(socdev->dev, + dev_dbg(rtd->platform->dev, "runtime->dma_area = %#lx dma_addr = %#lx dma_bytes = %zd " "runtime->min_align %ld\n", (unsigned long)runtime->dma_area, (unsigned long)runtime->dma_addr, runtime->dma_bytes, runtime->min_align); - dev_dbg(socdev->dev, + dev_dbg(rtd->platform->dev, "periods %d period_bytes %d stream %d\n", params_periods(params), params_period_bytes(params), substream->stream); @@ -105,8 +110,8 @@ static void txx9aclc_dma_complete(void *arg) spin_lock_irqsave(&dmadata->dma_lock, flags); if (dmadata->frag_count >= 0) { dmadata->dmacount--; - BUG_ON(dmadata->dmacount < 0); - tasklet_schedule(&dmadata->tasklet); + if (!WARN_ON(dmadata->dmacount < 0)) + tasklet_schedule(&dmadata->tasklet); } spin_unlock_irqrestore(&dmadata->dma_lock, flags); } @@ -122,9 +127,9 @@ txx9aclc_dma_submit(struct txx9aclc_dmadata *dmadata, dma_addr_t buf_dma_addr) sg_set_page(&sg, pfn_to_page(PFN_DOWN(buf_dma_addr)), dmadata->frag_bytes, buf_dma_addr & (PAGE_SIZE - 1)); sg_dma_address(&sg) = buf_dma_addr; - desc = chan->device->device_prep_slave_sg(chan, &sg, 1, + desc = dmaengine_prep_slave_sg(chan, &sg, 1, dmadata->substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? - DMA_TO_DEVICE : DMA_FROM_DEVICE, + DMA_MEM_TO_DEV : DMA_DEV_TO_MEM, DMA_PREP_INTERRUPT | DMA_CTRL_ACK); if (!desc) { dev_err(&chan->dev->device, "cannot prepare slave dma\n"); @@ -151,15 +156,11 @@ static void txx9aclc_dma_tasklet(unsigned long data) spin_lock_irqsave(&dmadata->dma_lock, flags); if (dmadata->frag_count < 0) { - struct txx9aclc_soc_device *dev = - container_of(dmadata, struct txx9aclc_soc_device, - dmadata[substream->stream]); - struct txx9aclc_plat_drvdata *drvdata = - txx9aclc_get_plat_drvdata(dev); + struct txx9aclc_plat_drvdata *drvdata = txx9aclc_drvdata; void __iomem *base = drvdata->base; spin_unlock_irqrestore(&dmadata->dma_lock, flags); - chan->device->device_terminate_all(chan); + chan->device->device_control(chan, DMA_TERMINATE_ALL, 0); /* first time */ for (i = 0; i < NR_DMA_CHAIN; i++) { desc = txx9aclc_dma_submit(dmadata, @@ -175,7 +176,10 @@ static void txx9aclc_dma_tasklet(unsigned long data) spin_unlock_irqrestore(&dmadata->dma_lock, flags); return; } - BUG_ON(dmadata->dmacount >= NR_DMA_CHAIN); + if (WARN_ON(dmadata->dmacount >= NR_DMA_CHAIN)) { + spin_unlock_irqrestore(&dmadata->dma_lock, flags); + return; + } while (dmadata->dmacount < NR_DMA_CHAIN) { dmadata->dmacount++; spin_unlock_irqrestore(&dmadata->dma_lock, flags); @@ -201,10 +205,7 @@ static void txx9aclc_dma_tasklet(unsigned long data) static int txx9aclc_pcm_trigger(struct snd_pcm_substream *substream, int cmd) { struct txx9aclc_dmadata *dmadata = substream->runtime->private_data; - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct txx9aclc_soc_device *dev = - container_of(rtd->socdev, struct txx9aclc_soc_device, soc_dev); - struct txx9aclc_plat_drvdata *drvdata = txx9aclc_get_plat_drvdata(dev); + struct txx9aclc_plat_drvdata *drvdata =txx9aclc_drvdata; void __iomem *base = drvdata->base; unsigned long flags; int ret = 0; @@ -243,9 +244,7 @@ txx9aclc_pcm_pointer(struct snd_pcm_substream *substream) static int txx9aclc_pcm_open(struct snd_pcm_substream *substream) { - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct txx9aclc_soc_device *dev = - container_of(rtd->socdev, struct txx9aclc_soc_device, soc_dev); + struct txx9aclc_soc_device *dev = &txx9aclc_soc_device; struct txx9aclc_dmadata *dmadata = &dev->dmadata[substream->stream]; int ret; @@ -267,7 +266,7 @@ static int txx9aclc_pcm_close(struct snd_pcm_substream *substream) struct dma_chan *chan = dmadata->dma_chan; dmadata->frag_count = -1; - chan->device->device_terminate_all(chan); + chan->device->device_control(chan, DMA_TERMINATE_ALL, 0); return 0; } @@ -287,11 +286,43 @@ static void txx9aclc_pcm_free_dma_buffers(struct snd_pcm *pcm) snd_pcm_lib_preallocate_free_for_all(pcm); } -static int txx9aclc_pcm_new(struct snd_card *card, struct snd_soc_dai *dai, - struct snd_pcm *pcm) +static int txx9aclc_pcm_new(struct snd_soc_pcm_runtime *rtd) { + struct snd_card *card = rtd->card->snd_card; + struct snd_soc_dai *dai = rtd->cpu_dai; + struct snd_pcm *pcm = rtd->pcm; + struct platform_device *pdev = to_platform_device(dai->platform->dev); + struct txx9aclc_soc_device *dev; + struct resource *r; + int i; + int ret; + + /* at this point onwards the AC97 component has probed and this will be valid */ + dev = snd_soc_dai_get_drvdata(dai); + + dev->dmadata[0].stream = SNDRV_PCM_STREAM_PLAYBACK; + dev->dmadata[1].stream = SNDRV_PCM_STREAM_CAPTURE; + for (i = 0; i < 2; i++) { + r = platform_get_resource(pdev, IORESOURCE_DMA, i); + if (!r) { + ret = -EBUSY; + goto exit; + } + dev->dmadata[i].dma_res = r; + ret = txx9aclc_dma_init(dev, &dev->dmadata[i]); + if (ret) + goto exit; + } return snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, card->dev, 64 * 1024, 4 * 1024 * 1024); + +exit: + for (i = 0; i < 2; i++) { + if (dev->dmadata[i].dma_chan) + dma_release_channel(dev->dmadata[i].dma_chan); + dev->dmadata[i].dma_chan = NULL; + } + return ret; } static bool filter(struct dma_chan *chan, void *param) @@ -313,7 +344,7 @@ static bool filter(struct dma_chan *chan, void *param) static int txx9aclc_dma_init(struct txx9aclc_soc_device *dev, struct txx9aclc_dmadata *dmadata) { - struct txx9aclc_plat_drvdata *drvdata = txx9aclc_get_plat_drvdata(dev); + struct txx9aclc_plat_drvdata *drvdata =txx9aclc_drvdata; struct txx9dmac_slave *ds = &dmadata->dma_slave; dma_cap_mask_t mask; @@ -333,7 +364,7 @@ static int txx9aclc_dma_init(struct txx9aclc_soc_device *dev, dma_cap_set(DMA_SLAVE, mask); dmadata->dma_chan = dma_request_channel(mask, filter, dmadata); if (!dmadata->dma_chan) { - dev_err(dev->soc_dev.dev, + printk(KERN_ERR "DMA channel for %s is not available\n", dmadata->stream == SNDRV_PCM_STREAM_PLAYBACK ? "playback" : "capture"); @@ -344,45 +375,16 @@ static int txx9aclc_dma_init(struct txx9aclc_soc_device *dev, return 0; } -static int txx9aclc_pcm_probe(struct platform_device *pdev) +static int txx9aclc_pcm_probe(struct snd_soc_platform *platform) { - struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct txx9aclc_soc_device *dev = - container_of(socdev, struct txx9aclc_soc_device, soc_dev); - struct resource *r; - int i; - int ret; - - dev->dmadata[0].stream = SNDRV_PCM_STREAM_PLAYBACK; - dev->dmadata[1].stream = SNDRV_PCM_STREAM_CAPTURE; - for (i = 0; i < 2; i++) { - r = platform_get_resource(dev->aclc_pdev, IORESOURCE_DMA, i); - if (!r) { - ret = -EBUSY; - goto exit; - } - dev->dmadata[i].dma_res = r; - ret = txx9aclc_dma_init(dev, &dev->dmadata[i]); - if (ret) - goto exit; - } + snd_soc_platform_set_drvdata(platform, &txx9aclc_soc_device); return 0; - -exit: - for (i = 0; i < 2; i++) { - if (dev->dmadata[i].dma_chan) - dma_release_channel(dev->dmadata[i].dma_chan); - dev->dmadata[i].dma_chan = NULL; - } - return ret; } -static int txx9aclc_pcm_remove(struct platform_device *pdev) +static int txx9aclc_pcm_remove(struct snd_soc_platform *platform) { - struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct txx9aclc_soc_device *dev = - container_of(socdev, struct txx9aclc_soc_device, soc_dev); - struct txx9aclc_plat_drvdata *drvdata = txx9aclc_get_plat_drvdata(dev); + struct txx9aclc_soc_device *dev = snd_soc_platform_get_drvdata(platform); + struct txx9aclc_plat_drvdata *drvdata = txx9aclc_drvdata; void __iomem *base = drvdata->base; int i; @@ -396,7 +398,8 @@ static int txx9aclc_pcm_remove(struct platform_device *pdev) struct dma_chan *chan = dmadata->dma_chan; if (chan) { dmadata->frag_count = -1; - chan->device->device_terminate_all(chan); + chan->device->device_control(chan, + DMA_TERMINATE_ALL, 0); dma_release_channel(chan); } dev->dmadata[i].dma_chan = NULL; @@ -404,28 +407,36 @@ static int txx9aclc_pcm_remove(struct platform_device *pdev) return 0; } -struct snd_soc_platform txx9aclc_soc_platform = { - .name = "txx9aclc-audio", +static struct snd_soc_platform_driver txx9aclc_soc_platform = { .probe = txx9aclc_pcm_probe, .remove = txx9aclc_pcm_remove, - .pcm_ops = &txx9aclc_pcm_ops, + .ops = &txx9aclc_pcm_ops, .pcm_new = txx9aclc_pcm_new, .pcm_free = txx9aclc_pcm_free_dma_buffers, }; -EXPORT_SYMBOL_GPL(txx9aclc_soc_platform); -static int __init txx9aclc_soc_platform_init(void) +static int txx9aclc_soc_platform_probe(struct platform_device *pdev) { - return snd_soc_register_platform(&txx9aclc_soc_platform); + return snd_soc_register_platform(&pdev->dev, &txx9aclc_soc_platform); } -static void __exit txx9aclc_soc_platform_exit(void) +static int txx9aclc_soc_platform_remove(struct platform_device *pdev) { - snd_soc_unregister_platform(&txx9aclc_soc_platform); + snd_soc_unregister_platform(&pdev->dev); + return 0; } -module_init(txx9aclc_soc_platform_init); -module_exit(txx9aclc_soc_platform_exit); +static struct platform_driver txx9aclc_pcm_driver = { + .driver = { + .name = "txx9aclc-pcm-audio", + .owner = THIS_MODULE, + }, + + .probe = txx9aclc_soc_platform_probe, + .remove = txx9aclc_soc_platform_remove, +}; + +module_platform_driver(txx9aclc_pcm_driver); MODULE_AUTHOR("Atsushi Nemoto <anemo@mba.ocn.ne.jp>"); MODULE_DESCRIPTION("TXx9 ACLC Audio DMA driver"); diff --git a/sound/soc/txx9/txx9aclc.h b/sound/soc/txx9/txx9aclc.h index 6769aab41b3..9c2de84fec3 100644 --- a/sound/soc/txx9/txx9aclc.h +++ b/sound/soc/txx9/txx9aclc.h @@ -65,19 +65,10 @@ struct txx9aclc_plat_drvdata { u64 physbase; }; -struct txx9aclc_soc_device { - struct snd_soc_device soc_dev; - struct platform_device *aclc_pdev; /* for ioresources, drvdata */ - struct txx9aclc_dmadata dmadata[2]; -}; - static inline struct txx9aclc_plat_drvdata *txx9aclc_get_plat_drvdata( - struct txx9aclc_soc_device *sdev) + struct snd_soc_dai *dai) { - return platform_get_drvdata(sdev->aclc_pdev); + return dev_get_drvdata(dai->dev); } -extern struct snd_soc_platform txx9aclc_soc_platform; -extern struct snd_soc_dai txx9aclc_ac97_dai; - #endif /* __TXX9ACLC_H */ |
