Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit be681a82 authored by Bo Shen's avatar Bo Shen Committed by Mark Brown
Browse files

ASoC: atmel-ssc-dai: register dai and pcm directly



change the method for register dai and pcm
  - let the atmel-ssc-dai no longer as a standalone platform device
  - remap ssc and then register dai directly
  - register pcm from dai directly
  - modify the code which related with this change

Signed-off-by: default avatarBo Shen <voice.shen@atmel.com>
Signed-off-by: default avatarMark Brown <broonie@opensource.wolfsonmicro.com>
parent 099343c6
Loading
Loading
Loading
Loading
+6 −17
Original line number Diff line number Diff line
@@ -473,28 +473,17 @@ static struct snd_soc_platform_driver atmel_soc_platform = {
	.resume		= atmel_pcm_resume,
};

static int __devinit atmel_soc_platform_probe(struct platform_device *pdev)
int atmel_pcm_platform_register(struct device *dev)
{
	return snd_soc_register_platform(&pdev->dev, &atmel_soc_platform);
	return snd_soc_register_platform(dev, &atmel_soc_platform);
}
EXPORT_SYMBOL(atmel_pcm_platform_register);

static int __devexit atmel_soc_platform_remove(struct platform_device *pdev)
void atmel_pcm_platform_unregister(struct device *dev)
{
	snd_soc_unregister_platform(&pdev->dev);
	return 0;
	snd_soc_unregister_platform(dev);
}

static struct platform_driver atmel_pcm_driver = {
	.driver = {
			.name = "atmel-pcm-audio",
			.owner = THIS_MODULE,
	},

	.probe = atmel_soc_platform_probe,
	.remove = __devexit_p(atmel_soc_platform_remove),
};

module_platform_driver(atmel_pcm_driver);
EXPORT_SYMBOL(atmel_pcm_platform_unregister);

MODULE_AUTHOR("Sedji Gaouaou <sedji.gaouaou@atmel.com>");
MODULE_DESCRIPTION("Atmel PCM module");
+3 −0
Original line number Diff line number Diff line
@@ -80,4 +80,7 @@ struct atmel_pcm_dma_params {
#define ssc_readx(base, reg)            (__raw_readl((base) + (reg)))
#define ssc_writex(base, reg, value)    __raw_writel((value), (base) + (reg))

int atmel_pcm_platform_register(struct device *dev);
void atmel_pcm_platform_unregister(struct device *dev);

#endif /* _ATMEL_PCM_H */
+39 −118
Original line number Diff line number Diff line
@@ -48,11 +48,7 @@
#include "atmel_ssc_dai.h"


#if defined(CONFIG_ARCH_AT91SAM9260) || defined(CONFIG_ARCH_AT91SAM9G20)
#define NUM_SSC_DEVICES		1
#else
#define NUM_SSC_DEVICES		3
#endif

/*
 * SSC PDC registers required by the PCM DMA engine.
@@ -107,7 +103,6 @@ static struct atmel_pcm_dma_params ssc_dma_params[NUM_SSC_DEVICES][2] = {
	.pdc		= &pdc_rx_reg,
	.mask		= &ssc_rx_mask,
	} },
#if NUM_SSC_DEVICES == 3
	{{
	.name		= "SSC1 PCM out",
	.pdc		= &pdc_tx_reg,
@@ -128,7 +123,6 @@ static struct atmel_pcm_dma_params ssc_dma_params[NUM_SSC_DEVICES][2] = {
	.pdc		= &pdc_rx_reg,
	.mask		= &ssc_rx_mask,
	} },
#endif
};


@@ -139,7 +133,6 @@ static struct atmel_ssc_info ssc_info[NUM_SSC_DEVICES] = {
	.dir_mask	= SSC_DIR_MASK_UNUSED,
	.initialized	= 0,
	},
#if NUM_SSC_DEVICES == 3
	{
	.name		= "ssc1",
	.lock		= __SPIN_LOCK_UNLOCKED(ssc_info[1].lock),
@@ -152,7 +145,6 @@ static struct atmel_ssc_info ssc_info[NUM_SSC_DEVICES] = {
	.dir_mask	= SSC_DIR_MASK_UNUSED,
	.initialized	= 0,
	},
#endif
};


@@ -690,27 +682,9 @@ static int atmel_ssc_resume(struct snd_soc_dai *cpu_dai)
static int atmel_ssc_probe(struct snd_soc_dai *dai)
{
	struct atmel_ssc_info *ssc_p = &ssc_info[dai->id];
	int ret = 0;

	snd_soc_dai_set_drvdata(dai, ssc_p);

	/*
	 * Request SSC device
	 */
	ssc_p->ssc = ssc_request(dai->id);
	if (IS_ERR(ssc_p->ssc)) {
		printk(KERN_ERR "ASoC: Failed to request SSC %d\n", dai->id);
		ret = PTR_ERR(ssc_p->ssc);
	}

	return ret;
}

static int atmel_ssc_remove(struct snd_soc_dai *dai)
{
	struct atmel_ssc_info *ssc_p = snd_soc_dai_get_drvdata(dai);

	ssc_free(ssc_p->ssc);
	return 0;
}

@@ -728,11 +702,8 @@ static const struct snd_soc_dai_ops atmel_ssc_dai_ops = {
	.set_clkdiv	= atmel_ssc_set_dai_clkdiv,
};

static struct snd_soc_dai_driver atmel_ssc_dai[NUM_SSC_DEVICES] = {
	{
		.name = "atmel-ssc-dai.0",
static struct snd_soc_dai_driver atmel_ssc_dai = {
		.probe = atmel_ssc_probe,
		.remove = atmel_ssc_remove,
		.suspend = atmel_ssc_suspend,
		.resume = atmel_ssc_resume,
		.playback = {
@@ -746,69 +717,37 @@ static struct snd_soc_dai_driver atmel_ssc_dai[NUM_SSC_DEVICES] = {
			.rates = ATMEL_SSC_RATES,
			.formats = ATMEL_SSC_FORMATS,},
		.ops = &atmel_ssc_dai_ops,
	},
#if NUM_SSC_DEVICES == 3
	{
		.name = "atmel-ssc-dai.1",
		.probe = atmel_ssc_probe,
		.remove = atmel_ssc_remove,
		.suspend = atmel_ssc_suspend,
		.resume = atmel_ssc_resume,
		.playback = {
			.channels_min = 1,
			.channels_max = 2,
			.rates = ATMEL_SSC_RATES,
			.formats = ATMEL_SSC_FORMATS,},
		.capture = {
			.channels_min = 1,
			.channels_max = 2,
			.rates = ATMEL_SSC_RATES,
			.formats = ATMEL_SSC_FORMATS,},
		.ops = &atmel_ssc_dai_ops,
	},
	{
		.name = "atmel-ssc-dai.2",
		.probe = atmel_ssc_probe,
		.remove = atmel_ssc_remove,
		.suspend = atmel_ssc_suspend,
		.resume = atmel_ssc_resume,
		.playback = {
			.channels_min = 1,
			.channels_max = 2,
			.rates = ATMEL_SSC_RATES,
			.formats = ATMEL_SSC_FORMATS,},
		.capture = {
			.channels_min = 1,
			.channels_max = 2,
			.rates = ATMEL_SSC_RATES,
			.formats = ATMEL_SSC_FORMATS,},
		.ops = &atmel_ssc_dai_ops,
	},
#endif
};

static __devinit int asoc_ssc_probe(struct platform_device *pdev)
static int asoc_ssc_init(struct device *dev)
{
	BUG_ON(pdev->id < 0);
	BUG_ON(pdev->id >= ARRAY_SIZE(atmel_ssc_dai));
	return snd_soc_register_dai(&pdev->dev, &atmel_ssc_dai[pdev->id]);
	int ret;

	ret = snd_soc_register_dai(dev, &atmel_ssc_dai);
	if (ret) {
		dev_err(dev, "Could not register DAI: %d\n", ret);
		goto err;
	}

static int __devexit asoc_ssc_remove(struct platform_device *pdev)
{
	snd_soc_unregister_dai(&pdev->dev);
	ret = atmel_pcm_platform_register(dev);
	if (ret) {
		dev_err(dev, "Could not register PCM: %d\n", ret);
		goto err_unregister_dai;
	};

	return 0;
}

static struct platform_driver asoc_ssc_driver = {
	.driver = {
			.name = "atmel-ssc-dai",
			.owner = THIS_MODULE,
	},
err_unregister_dai:
	snd_soc_unregister_dai(dev);
err:
	return ret;
}

	.probe = asoc_ssc_probe,
	.remove = __devexit_p(asoc_ssc_remove),
};
static void asoc_ssc_exit(struct device *dev)
{
	atmel_pcm_platform_unregister(dev);
	snd_soc_unregister_dai(dev);
}

/**
 * atmel_ssc_set_audio - Allocate the specified SSC for audio use.
@@ -816,50 +755,32 @@ static struct platform_driver asoc_ssc_driver = {
int atmel_ssc_set_audio(int ssc_id)
{
	struct ssc_device *ssc;
	static struct platform_device *dma_pdev;
	struct platform_device *ssc_pdev;
	int ret;

	if (ssc_id < 0 || ssc_id >= ARRAY_SIZE(atmel_ssc_dai))
		return -EINVAL;

	/* Allocate a dummy device for DMA if we don't have one already */
	if (!dma_pdev) {
		dma_pdev = platform_device_alloc("atmel-pcm-audio", -1);
		if (!dma_pdev)
			return -ENOMEM;

		ret = platform_device_add(dma_pdev);
		if (ret < 0) {
			platform_device_put(dma_pdev);
			dma_pdev = NULL;
			return ret;
		}
	}

	ssc_pdev = platform_device_alloc("atmel-ssc-dai", ssc_id);
	if (!ssc_pdev)
		return -ENOMEM;

	/* If we can grab the SSC briefly to parent the DAI device off it */
	ssc = ssc_request(ssc_id);
	if (IS_ERR(ssc))
		pr_warn("Unable to parent ASoC SSC DAI on SSC: %ld\n",
	if (IS_ERR(ssc)) {
		pr_err("Unable to parent ASoC SSC DAI on SSC: %ld\n",
			PTR_ERR(ssc));
	else {
		ssc_pdev->dev.parent = &(ssc->pdev->dev);
		ssc_free(ssc);
		return PTR_ERR(ssc);
	} else {
		ssc_info[ssc_id].ssc = ssc;
	}

	ret = platform_device_add(ssc_pdev);
	if (ret < 0)
		platform_device_put(ssc_pdev);
	ret = asoc_ssc_init(&ssc->pdev->dev);

	return ret;
}
EXPORT_SYMBOL_GPL(atmel_ssc_set_audio);

module_platform_driver(asoc_ssc_driver);
void atmel_ssc_put_audio(int ssc_id)
{
	struct ssc_device *ssc = ssc_info[ssc_id].ssc;

	ssc_free(ssc);
	asoc_ssc_exit(&ssc->pdev->dev);
}
EXPORT_SYMBOL_GPL(atmel_ssc_put_audio);

/* Module information */
MODULE_AUTHOR("Sedji Gaouaou, sedji.gaouaou@atmel.com, www.atmel.com");
+2 −1
Original line number Diff line number Diff line
@@ -117,6 +117,7 @@ struct atmel_ssc_info {
	struct atmel_ssc_state ssc_state;
};

int atmel_ssc_set_audio(int ssc);
int atmel_ssc_set_audio(int ssc_id);
void atmel_ssc_put_audio(int ssc_id);

#endif /* _AT91_SSC_DAI_H */