aboutsummaryrefslogtreecommitdiff
path: root/sound/atmel/abdac.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/atmel/abdac.c')
-rw-r--r--sound/atmel/abdac.c77
1 files changed, 42 insertions, 35 deletions
diff --git a/sound/atmel/abdac.c b/sound/atmel/abdac.c
index f2f41c85422..edf2ca72d51 100644
--- a/sound/atmel/abdac.c
+++ b/sound/atmel/abdac.c
@@ -16,6 +16,7 @@
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/platform_device.h>
+#include <linux/types.h>
#include <linux/io.h>
#include <sound/core.h>
@@ -133,7 +134,7 @@ static int atmel_abdac_prepare_dma(struct atmel_abdac *dac,
period_len = frames_to_bytes(runtime, runtime->period_size);
cdesc = dw_dma_cyclic_prep(chan, runtime->dma_addr, buffer_len,
- period_len, DMA_TO_DEVICE);
+ period_len, DMA_MEM_TO_DEV);
if (IS_ERR(cdesc)) {
dev_dbg(&dac->pdev->dev, "could not prepare cyclic DMA\n");
return PTR_ERR(cdesc);
@@ -308,7 +309,7 @@ static struct snd_pcm_ops atmel_abdac_ops = {
.pointer = atmel_abdac_pointer,
};
-static int __devinit atmel_abdac_pcm_new(struct atmel_abdac *dac)
+static int atmel_abdac_pcm_new(struct atmel_abdac *dac)
{
struct snd_pcm_hardware hw = atmel_abdac_hw;
struct snd_pcm *pcm;
@@ -353,10 +354,11 @@ static int set_sample_rates(struct atmel_abdac *dac)
/* we start at 192 kHz and work our way down to 5112 Hz */
while (new_rate >= RATE_MIN && index < (MAX_NUM_RATES + 1)) {
new_rate = clk_round_rate(dac->sample_clk, 256 * new_rate);
- if (new_rate < 0)
+ if (new_rate <= 0)
break;
/* make sure we are below the ABDAC clock */
- if (new_rate <= clk_get_rate(dac->pclk)) {
+ if (index < MAX_NUM_RATES &&
+ new_rate <= clk_get_rate(dac->pclk)) {
dac->rates[index] = new_rate / 256;
index++;
}
@@ -385,7 +387,7 @@ static int set_sample_rates(struct atmel_abdac *dac)
return retval;
}
-static int __devinit atmel_abdac_probe(struct platform_device *pdev)
+static int atmel_abdac_probe(struct platform_device *pdev)
{
struct snd_card *card;
struct atmel_abdac *dac;
@@ -420,15 +422,16 @@ static int __devinit atmel_abdac_probe(struct platform_device *pdev)
return PTR_ERR(pclk);
}
sample_clk = clk_get(&pdev->dev, "sample_clk");
- if (IS_ERR(pclk)) {
+ if (IS_ERR(sample_clk)) {
dev_dbg(&pdev->dev, "no sample clock\n");
- retval = PTR_ERR(pclk);
+ retval = PTR_ERR(sample_clk);
goto out_put_pclk;
}
clk_enable(pclk);
- retval = snd_card_create(SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1,
- THIS_MODULE, sizeof(struct atmel_abdac), &card);
+ retval = snd_card_new(&pdev->dev, SNDRV_DEFAULT_IDX1,
+ SNDRV_DEFAULT_STR1, THIS_MODULE,
+ sizeof(struct atmel_abdac), &card);
if (retval) {
dev_dbg(&pdev->dev, "could not create sound card device\n");
goto out_put_sample_clk;
@@ -448,9 +451,10 @@ static int __devinit atmel_abdac_probe(struct platform_device *pdev)
goto out_free_card;
}
- dac->regs = ioremap(regs->start, regs->end - regs->start + 1);
+ dac->regs = ioremap(regs->start, resource_size(regs));
if (!dac->regs) {
dev_dbg(&pdev->dev, "could not remap register memory\n");
+ retval = -ENOMEM;
goto out_free_card;
}
@@ -464,23 +468,30 @@ static int __devinit atmel_abdac_probe(struct platform_device *pdev)
goto out_unmap_regs;
}
- snd_card_set_dev(card, &pdev->dev);
-
if (pdata->dws.dma_dev) {
- struct dw_dma_slave *dws = &pdata->dws;
dma_cap_mask_t mask;
- dws->tx_reg = regs->start + DAC_DATA;
-
dma_cap_zero(mask);
dma_cap_set(DMA_SLAVE, mask);
- dac->dma.chan = dma_request_channel(mask, filter, dws);
+ dac->dma.chan = dma_request_channel(mask, filter, &pdata->dws);
+ if (dac->dma.chan) {
+ struct dma_slave_config dma_conf = {
+ .dst_addr = regs->start + DAC_DATA,
+ .dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES,
+ .src_maxburst = 1,
+ .dst_maxburst = 1,
+ .direction = DMA_MEM_TO_DEV,
+ .device_fc = false,
+ };
+
+ dmaengine_slave_config(dac->dma.chan, &dma_conf);
+ }
}
if (!pdata->dws.dma_dev || !dac->dma.chan) {
dev_dbg(&pdev->dev, "DMA not available\n");
retval = -ENODEV;
- goto out_unset_card_dev;
+ goto out_unmap_regs;
}
strcpy(card->driver, "Atmel ABDAC");
@@ -509,9 +520,6 @@ static int __devinit atmel_abdac_probe(struct platform_device *pdev)
out_release_dma:
dma_release_channel(dac->dma.chan);
dac->dma.chan = NULL;
-out_unset_card_dev:
- snd_card_set_dev(card, NULL);
- free_irq(irq, dac);
out_unmap_regs:
iounmap(dac->regs);
out_free_card:
@@ -524,10 +532,10 @@ out_put_pclk:
return retval;
}
-#ifdef CONFIG_PM
-static int atmel_abdac_suspend(struct platform_device *pdev, pm_message_t msg)
+#ifdef CONFIG_PM_SLEEP
+static int atmel_abdac_suspend(struct device *pdev)
{
- struct snd_card *card = platform_get_drvdata(pdev);
+ struct snd_card *card = dev_get_drvdata(pdev);
struct atmel_abdac *dac = card->private_data;
dw_dma_cyclic_stop(dac->dma.chan);
@@ -537,9 +545,9 @@ static int atmel_abdac_suspend(struct platform_device *pdev, pm_message_t msg)
return 0;
}
-static int atmel_abdac_resume(struct platform_device *pdev)
+static int atmel_abdac_resume(struct device *pdev)
{
- struct snd_card *card = platform_get_drvdata(pdev);
+ struct snd_card *card = dev_get_drvdata(pdev);
struct atmel_abdac *dac = card->private_data;
clk_enable(dac->pclk);
@@ -549,12 +557,14 @@ static int atmel_abdac_resume(struct platform_device *pdev)
return 0;
}
+
+static SIMPLE_DEV_PM_OPS(atmel_abdac_pm, atmel_abdac_suspend, atmel_abdac_resume);
+#define ATMEL_ABDAC_PM_OPS &atmel_abdac_pm
#else
-#define atmel_abdac_suspend NULL
-#define atmel_abdac_resume NULL
+#define ATMEL_ABDAC_PM_OPS NULL
#endif
-static int __devexit atmel_abdac_remove(struct platform_device *pdev)
+static int atmel_abdac_remove(struct platform_device *pdev)
{
struct snd_card *card = platform_get_drvdata(pdev);
struct atmel_abdac *dac = get_dac(card);
@@ -565,23 +575,20 @@ static int __devexit atmel_abdac_remove(struct platform_device *pdev)
dma_release_channel(dac->dma.chan);
dac->dma.chan = NULL;
- snd_card_set_dev(card, NULL);
iounmap(dac->regs);
free_irq(dac->irq, dac);
snd_card_free(card);
- platform_set_drvdata(pdev, NULL);
-
return 0;
}
static struct platform_driver atmel_abdac_driver = {
- .remove = __devexit_p(atmel_abdac_remove),
+ .remove = atmel_abdac_remove,
.driver = {
.name = "atmel_abdac",
+ .owner = THIS_MODULE,
+ .pm = ATMEL_ABDAC_PM_OPS,
},
- .suspend = atmel_abdac_suspend,
- .resume = atmel_abdac_resume,
};
static int __init atmel_abdac_init(void)
@@ -599,4 +606,4 @@ module_exit(atmel_abdac_exit);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Driver for Atmel Audio Bitstream DAC (ABDAC)");
-MODULE_AUTHOR("Hans-Christian Egtvedt <hans-christian.egtvedt@atmel.com>");
+MODULE_AUTHOR("Hans-Christian Egtvedt <egtvedt@samfundet.no>");