diff options
Diffstat (limited to 'sound/atmel/abdac.c')
| -rw-r--r-- | sound/atmel/abdac.c | 77 | 
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>");  | 
