コード例 #1
0
ファイル: dmaengine.c プロジェクト: 19Dan01/linux
int samsung_asoc_dma_platform_register(struct device *dev)
{
	return devm_snd_dmaengine_pcm_register(dev,
			&samsung_dmaengine_pcm_config,
			SND_DMAENGINE_PCM_FLAG_CUSTOM_CHANNEL_NAME |
			SND_DMAENGINE_PCM_FLAG_COMPAT);
}
コード例 #2
0
ファイル: jz4740-i2s.c プロジェクト: Abioy/kasan
static int jz4740_i2s_dev_probe(struct platform_device *pdev)
{
	struct jz4740_i2s *i2s;
	struct resource *mem;
	int ret;

	i2s = devm_kzalloc(&pdev->dev, sizeof(*i2s), GFP_KERNEL);
	if (!i2s)
		return -ENOMEM;

	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	i2s->base = devm_ioremap_resource(&pdev->dev, mem);
	if (IS_ERR(i2s->base))
		return PTR_ERR(i2s->base);

	i2s->phys_base = mem->start;

	i2s->clk_aic = devm_clk_get(&pdev->dev, "aic");
	if (IS_ERR(i2s->clk_aic))
		return PTR_ERR(i2s->clk_aic);

	i2s->clk_i2s = devm_clk_get(&pdev->dev, "i2s");
	if (IS_ERR(i2s->clk_i2s))
		return PTR_ERR(i2s->clk_i2s);

	platform_set_drvdata(pdev, i2s);

	ret = devm_snd_soc_register_component(&pdev->dev,
		&jz4740_i2s_component, &jz4740_i2s_dai, 1);
	if (ret)
		return ret;

	return devm_snd_dmaengine_pcm_register(&pdev->dev, NULL,
		SND_DMAENGINE_PCM_FLAG_COMPAT);
}
コード例 #3
0
ファイル: stm32_sai_sub.c プロジェクト: asmalldev/linux
static int stm32_sai_sub_probe(struct platform_device *pdev)
{
	struct stm32_sai_sub_data *sai;
	const struct of_device_id *of_id;
	int ret;

	sai = devm_kzalloc(&pdev->dev, sizeof(*sai), GFP_KERNEL);
	if (!sai)
		return -ENOMEM;

	of_id = of_match_device(stm32_sai_sub_ids, &pdev->dev);
	if (!of_id)
		return -EINVAL;
	sai->id = (uintptr_t)of_id->data;

	sai->pdev = pdev;
	platform_set_drvdata(pdev, sai);

	sai->pdata = dev_get_drvdata(pdev->dev.parent);
	if (!sai->pdata) {
		dev_err(&pdev->dev, "Parent device data not available\n");
		return -EINVAL;
	}

	ret = stm32_sai_sub_parse_of(pdev, sai);
	if (ret)
		return ret;

	ret = stm32_sai_sub_dais_init(pdev, sai);
	if (ret)
		return ret;

	ret = devm_request_irq(&pdev->dev, sai->pdata->irq, stm32_sai_isr,
			       IRQF_SHARED, dev_name(&pdev->dev), sai);
	if (ret) {
		dev_err(&pdev->dev, "irq request returned %d\n", ret);
		return ret;
	}

	ret = devm_snd_soc_register_component(&pdev->dev, &stm32_component,
					      sai->cpu_dai_drv, 1);
	if (ret)
		return ret;

	ret = devm_snd_dmaengine_pcm_register(&pdev->dev,
					      &stm32_sai_pcm_config, 0);
	if (ret) {
		dev_err(&pdev->dev, "could not register pcm dma\n");
		return ret;
	}

	return 0;
}
コード例 #4
0
ファイル: hi6210-i2s.c プロジェクト: Lyude/linux
static int hi6210_i2s_probe(struct platform_device *pdev)
{
	struct device_node *node = pdev->dev.of_node;
	struct device *dev = &pdev->dev;
	struct hi6210_i2s *i2s;
	struct resource *res;
	int ret;

	i2s = devm_kzalloc(&pdev->dev, sizeof(*i2s), GFP_KERNEL);
	if (!i2s)
		return -ENOMEM;

	i2s->dev = dev;
	spin_lock_init(&i2s->lock);

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	i2s->base = devm_ioremap_resource(dev, res);
	if (IS_ERR(i2s->base))
		return PTR_ERR(i2s->base);

	i2s->base_phys = (phys_addr_t)res->start;
	i2s->dai = hi6210_i2s_dai_init;

	dev_set_drvdata(&pdev->dev, i2s);

	i2s->sysctrl = syscon_regmap_lookup_by_phandle(node,
						"hisilicon,sysctrl-syscon");
	if (IS_ERR(i2s->sysctrl))
		return PTR_ERR(i2s->sysctrl);

	i2s->clk[CLK_DACODEC] = devm_clk_get(&pdev->dev, "dacodec");
	if (IS_ERR_OR_NULL(i2s->clk[CLK_DACODEC]))
		return PTR_ERR(i2s->clk[CLK_DACODEC]);
	i2s->clocks++;

	i2s->clk[CLK_I2S_BASE] = devm_clk_get(&pdev->dev, "i2s-base");
	if (IS_ERR_OR_NULL(i2s->clk[CLK_I2S_BASE]))
		return PTR_ERR(i2s->clk[CLK_I2S_BASE]);
	i2s->clocks++;

	ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
	if (ret)
		return ret;

	ret = devm_snd_soc_register_component(&pdev->dev, &hi6210_i2s_i2s_comp,
					 &i2s->dai, 1);
	return ret;
}
コード例 #5
0
ファイル: sirf-usp.c プロジェクト: AkyZero/wrapfs-latest
static int sirf_usp_pcm_probe(struct platform_device *pdev)
{
	int ret;
	struct sirf_usp *usp;
	void __iomem *base;
	struct resource *mem_res;

	usp = devm_kzalloc(&pdev->dev, sizeof(struct sirf_usp),
			GFP_KERNEL);
	if (!usp)
		return -ENOMEM;

	platform_set_drvdata(pdev, usp);

	mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	base = devm_ioremap(&pdev->dev, mem_res->start,
		resource_size(mem_res));
	if (base == NULL)
		return -ENOMEM;
	usp->regmap = devm_regmap_init_mmio(&pdev->dev, base,
					    &sirf_usp_regmap_config);
	if (IS_ERR(usp->regmap))
		return PTR_ERR(usp->regmap);

	usp->clk = devm_clk_get(&pdev->dev, NULL);
	if (IS_ERR(usp->clk)) {
		dev_err(&pdev->dev, "Get clock failed.\n");
		return PTR_ERR(usp->clk);
	}

	pm_runtime_enable(&pdev->dev);
	if (!pm_runtime_enabled(&pdev->dev)) {
		ret = sirf_usp_pcm_runtime_resume(&pdev->dev);
		if (ret)
			return ret;
	}

	ret = devm_snd_soc_register_component(&pdev->dev, &sirf_usp_component,
		&sirf_usp_pcm_dai, 1);
	if (ret) {
		dev_err(&pdev->dev, "Register Audio SoC dai failed.\n");
		return ret;
	}
	return devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
}
コード例 #6
0
ファイル: fsl_sai.c プロジェクト: Astralix/mainline-dss11
static int fsl_sai_probe(struct platform_device *pdev)
{
	struct device_node *np = pdev->dev.of_node;
	struct fsl_sai *sai;
	struct resource *res;
	void __iomem *base;
	int ret;

	sai = devm_kzalloc(&pdev->dev, sizeof(*sai), GFP_KERNEL);
	if (!sai)
		return -ENOMEM;

	sai->big_endian_regs = of_property_read_bool(np, "big-endian-regs");
	if (sai->big_endian_regs)
		fsl_sai_regmap_config.val_format_endian = REGMAP_ENDIAN_BIG;

	sai->big_endian_data = of_property_read_bool(np, "big-endian-data");

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	base = devm_ioremap_resource(&pdev->dev, res);
	if (IS_ERR(base))
		return PTR_ERR(base);

	sai->regmap = devm_regmap_init_mmio_clk(&pdev->dev,
			"sai", base, &fsl_sai_regmap_config);
	if (IS_ERR(sai->regmap)) {
		dev_err(&pdev->dev, "regmap init failed\n");
		return PTR_ERR(sai->regmap);
	}

	sai->dma_params_rx.addr = res->start + FSL_SAI_RDR;
	sai->dma_params_tx.addr = res->start + FSL_SAI_TDR;
	sai->dma_params_rx.maxburst = FSL_SAI_MAXBURST_RX;
	sai->dma_params_tx.maxburst = FSL_SAI_MAXBURST_TX;

	platform_set_drvdata(pdev, sai);

	ret = devm_snd_soc_register_component(&pdev->dev, &fsl_component,
			&fsl_sai_dai, 1);
	if (ret)
		return ret;

	return devm_snd_dmaengine_pcm_register(&pdev->dev, NULL,
			SND_DMAENGINE_PCM_FLAG_NO_RESIDUE);
}
コード例 #7
0
ファイル: jz4740-i2s.c プロジェクト: 020gzh/linux
static int jz4740_i2s_dev_probe(struct platform_device *pdev)
{
	struct jz4740_i2s *i2s;
	struct resource *mem;
	int ret;
	const struct of_device_id *match;

	i2s = devm_kzalloc(&pdev->dev, sizeof(*i2s), GFP_KERNEL);
	if (!i2s)
		return -ENOMEM;

	match = of_match_device(jz4740_of_matches, &pdev->dev);
	if (match)
		i2s->version = (enum jz47xx_i2s_version)match->data;

	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	i2s->base = devm_ioremap_resource(&pdev->dev, mem);
	if (IS_ERR(i2s->base))
		return PTR_ERR(i2s->base);

	i2s->phys_base = mem->start;

	i2s->clk_aic = devm_clk_get(&pdev->dev, "aic");
	if (IS_ERR(i2s->clk_aic))
		return PTR_ERR(i2s->clk_aic);

	i2s->clk_i2s = devm_clk_get(&pdev->dev, "i2s");
	if (IS_ERR(i2s->clk_i2s))
		return PTR_ERR(i2s->clk_i2s);

	platform_set_drvdata(pdev, i2s);

	if (i2s->version == JZ_I2S_JZ4780)
		ret = devm_snd_soc_register_component(&pdev->dev,
			&jz4740_i2s_component, &jz4780_i2s_dai, 1);
	else
		ret = devm_snd_soc_register_component(&pdev->dev,
			&jz4740_i2s_component, &jz4740_i2s_dai, 1);

	if (ret)
		return ret;

	return devm_snd_dmaengine_pcm_register(&pdev->dev, NULL,
		SND_DMAENGINE_PCM_FLAG_COMPAT);
}
コード例 #8
0
ファイル: sirf-audio-port.c プロジェクト: AlexShiLucky/linux
static int sirf_audio_port_probe(struct platform_device *pdev)
{
	int ret;
	struct sirf_audio_port *port;

	port = devm_kzalloc(&pdev->dev,
			sizeof(struct sirf_audio_port), GFP_KERNEL);
	if (!port)
		return -ENOMEM;

	ret = devm_snd_soc_register_component(&pdev->dev,
			&sirf_audio_port_component, &sirf_audio_port_dai, 1);
	if (ret)
		return ret;

	platform_set_drvdata(pdev, port);
	return devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
}
コード例 #9
0
ファイル: stm32_i2s.c プロジェクト: lfd/PreemptRT
static int stm32_i2s_probe(struct platform_device *pdev)
{
	struct stm32_i2s_data *i2s;
	int ret;

	i2s = devm_kzalloc(&pdev->dev, sizeof(*i2s), GFP_KERNEL);
	if (!i2s)
		return -ENOMEM;

	ret = stm32_i2s_parse_dt(pdev, i2s);
	if (ret)
		return ret;

	i2s->pdev = pdev;
	i2s->ms_flg = I2S_MS_NOT_SET;
	spin_lock_init(&i2s->lock_fd);
	spin_lock_init(&i2s->irq_lock);
	platform_set_drvdata(pdev, i2s);

	ret = stm32_i2s_dais_init(pdev, i2s);
	if (ret)
		return ret;

	i2s->regmap = devm_regmap_init_mmio_clk(&pdev->dev, "pclk",
						i2s->base, i2s->regmap_conf);
	if (IS_ERR(i2s->regmap)) {
		dev_err(&pdev->dev, "regmap init failed\n");
		return PTR_ERR(i2s->regmap);
	}

	ret = devm_snd_soc_register_component(&pdev->dev, &stm32_i2s_component,
					      i2s->dai_drv, 1);
	if (ret)
		return ret;

	ret = devm_snd_dmaengine_pcm_register(&pdev->dev,
					      &stm32_i2s_pcm_config, 0);
	if (ret)
		return ret;

	/* Set SPI/I2S in i2s mode */
	return regmap_update_bits(i2s->regmap, STM32_I2S_CGFR_REG,
				  I2S_CGFR_I2SMOD, I2S_CGFR_I2SMOD);
}
コード例 #10
0
ファイル: zx-spdif.c プロジェクト: AlexShiLucky/linux
static int zx_spdif_probe(struct platform_device *pdev)
{
	struct resource *res;
	struct zx_spdif_info *zx_spdif;
	int ret;

	zx_spdif = devm_kzalloc(&pdev->dev, sizeof(*zx_spdif), GFP_KERNEL);
	if (!zx_spdif)
		return -ENOMEM;

	zx_spdif->dai_clk = devm_clk_get(&pdev->dev, "tx");
	if (IS_ERR(zx_spdif->dai_clk)) {
		dev_err(&pdev->dev, "Fail to get clk\n");
		return PTR_ERR(zx_spdif->dai_clk);
	}

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	zx_spdif->mapbase = res->start;
	zx_spdif->reg_base = devm_ioremap_resource(&pdev->dev, res);
	if (IS_ERR(zx_spdif->reg_base)) {
		dev_err(&pdev->dev, "ioremap failed!\n");
		return PTR_ERR(zx_spdif->reg_base);
	}

	zx_spdif_dev_init(zx_spdif->reg_base);
	platform_set_drvdata(pdev, zx_spdif);

	ret = devm_snd_soc_register_component(&pdev->dev, &zx_spdif_component,
					 &zx_spdif_dai, 1);
	if (ret) {
		dev_err(&pdev->dev, "Register DAI failed: %d\n", ret);
		return ret;
	}

	ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
	if (ret)
		dev_err(&pdev->dev, "Register platform PCM failed: %d\n", ret);

	return ret;
}
コード例 #11
0
ファイル: bcm2835-i2s.c プロジェクト: 513855417/linux
static int bcm2835_i2s_probe(struct platform_device *pdev)
{
	struct bcm2835_i2s_dev *dev;
	int ret;
	struct resource *mem;
	void __iomem *base;
	const __be32 *addr;
	dma_addr_t dma_base;

	dev = devm_kzalloc(&pdev->dev, sizeof(*dev),
			   GFP_KERNEL);
	if (!dev)
		return -ENOMEM;

	/* get the clock */
	dev->clk_prepared = false;
	dev->clk = devm_clk_get(&pdev->dev, NULL);
	if (IS_ERR(dev->clk)) {
		dev_err(&pdev->dev, "could not get clk: %ld\n",
			PTR_ERR(dev->clk));
		return PTR_ERR(dev->clk);
	}

	/* Request ioarea */
	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	base = devm_ioremap_resource(&pdev->dev, mem);
	if (IS_ERR(base))
		return PTR_ERR(base);

	dev->i2s_regmap = devm_regmap_init_mmio(&pdev->dev, base,
				&bcm2835_regmap_config);
	if (IS_ERR(dev->i2s_regmap))
		return PTR_ERR(dev->i2s_regmap);

	/* Set the DMA address - we have to parse DT ourselves */
	addr = of_get_address(pdev->dev.of_node, 0, NULL, NULL);
	if (!addr) {
		dev_err(&pdev->dev, "could not get DMA-register address\n");
		return -EINVAL;
	}
	dma_base = be32_to_cpup(addr);

	dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK].addr =
		dma_base + BCM2835_I2S_FIFO_A_REG;

	dev->dma_data[SNDRV_PCM_STREAM_CAPTURE].addr =
		dma_base + BCM2835_I2S_FIFO_A_REG;

	/* Set the bus width */
	dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK].addr_width =
		DMA_SLAVE_BUSWIDTH_4_BYTES;
	dev->dma_data[SNDRV_PCM_STREAM_CAPTURE].addr_width =
		DMA_SLAVE_BUSWIDTH_4_BYTES;

	/* Set burst */
	dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK].maxburst = 2;
	dev->dma_data[SNDRV_PCM_STREAM_CAPTURE].maxburst = 2;

	/*
	 * Set the PACK flag to enable S16_LE support (2 S16_LE values
	 * packed into 32-bit transfers).
	 */
	dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK].flags =
		SND_DMAENGINE_PCM_DAI_FLAG_PACK;
	dev->dma_data[SNDRV_PCM_STREAM_CAPTURE].flags =
		SND_DMAENGINE_PCM_DAI_FLAG_PACK;

	/* BCLK ratio - use default */
	dev->bclk_ratio = 0;

	/* Store the pdev */
	dev->dev = &pdev->dev;
	dev_set_drvdata(&pdev->dev, dev);

	ret = devm_snd_soc_register_component(&pdev->dev,
			&bcm2835_i2s_component, &bcm2835_i2s_dai, 1);
	if (ret) {
		dev_err(&pdev->dev, "Could not register DAI: %d\n", ret);
		return ret;
	}

	ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
	if (ret) {
		dev_err(&pdev->dev, "Could not register PCM: %d\n", ret);
		return ret;
	}

	return 0;
}
コード例 #12
0
ファイル: sun4i-codec.c プロジェクト: 020gzh/linux
static int sun4i_codec_probe(struct platform_device *pdev)
{
	struct snd_soc_card *card;
	struct sun4i_codec *scodec;
	struct resource *res;
	void __iomem *base;
	int ret;

	scodec = devm_kzalloc(&pdev->dev, sizeof(*scodec), GFP_KERNEL);
	if (!scodec)
		return -ENOMEM;

	scodec->dev = &pdev->dev;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	base = devm_ioremap_resource(&pdev->dev, res);
	if (IS_ERR(base)) {
		dev_err(&pdev->dev, "Failed to map the registers\n");
		return PTR_ERR(base);
	}

	scodec->regmap = devm_regmap_init_mmio(&pdev->dev, base,
					     &sun4i_codec_regmap_config);
	if (IS_ERR(scodec->regmap)) {
		dev_err(&pdev->dev, "Failed to create our regmap\n");
		return PTR_ERR(scodec->regmap);
	}

	/* Get the clocks from the DT */
	scodec->clk_apb = devm_clk_get(&pdev->dev, "apb");
	if (IS_ERR(scodec->clk_apb)) {
		dev_err(&pdev->dev, "Failed to get the APB clock\n");
		return PTR_ERR(scodec->clk_apb);
	}

	scodec->clk_module = devm_clk_get(&pdev->dev, "codec");
	if (IS_ERR(scodec->clk_module)) {
		dev_err(&pdev->dev, "Failed to get the module clock\n");
		return PTR_ERR(scodec->clk_module);
	}

	/* Enable the bus clock */
	if (clk_prepare_enable(scodec->clk_apb)) {
		dev_err(&pdev->dev, "Failed to enable the APB clock\n");
		return -EINVAL;
	}

	scodec->gpio_pa = devm_gpiod_get_optional(&pdev->dev, "allwinner,pa",
						  GPIOD_OUT_LOW);
	if (IS_ERR(scodec->gpio_pa)) {
		ret = PTR_ERR(scodec->gpio_pa);
		if (ret != -EPROBE_DEFER)
			dev_err(&pdev->dev, "Failed to get pa gpio: %d\n", ret);
		return ret;
	}

	/* DMA configuration for TX FIFO */
	scodec->playback_dma_data.addr = res->start + SUN4I_CODEC_DAC_TXDATA;
	scodec->playback_dma_data.maxburst = 4;
	scodec->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;

	/* DMA configuration for RX FIFO */
	scodec->capture_dma_data.addr = res->start + SUN4I_CODEC_ADC_RXDATA;
	scodec->capture_dma_data.maxburst = 4;
	scodec->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;

	ret = snd_soc_register_codec(&pdev->dev, &sun4i_codec_codec,
				     &sun4i_codec_dai, 1);
	if (ret) {
		dev_err(&pdev->dev, "Failed to register our codec\n");
		goto err_clk_disable;
	}

	ret = devm_snd_soc_register_component(&pdev->dev,
					      &sun4i_codec_component,
					      &dummy_cpu_dai, 1);
	if (ret) {
		dev_err(&pdev->dev, "Failed to register our DAI\n");
		goto err_unregister_codec;
	}

	ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
	if (ret) {
		dev_err(&pdev->dev, "Failed to register against DMAEngine\n");
		goto err_unregister_codec;
	}

	card = sun4i_codec_create_card(&pdev->dev);
	if (!card) {
		dev_err(&pdev->dev, "Failed to create our card\n");
		goto err_unregister_codec;
	}

	platform_set_drvdata(pdev, card);
	snd_soc_card_set_drvdata(card, scodec);

	ret = snd_soc_register_card(card);
	if (ret) {
		dev_err(&pdev->dev, "Failed to register our card\n");
		goto err_unregister_codec;
	}

	return 0;

err_unregister_codec:
	snd_soc_unregister_codec(&pdev->dev);
err_clk_disable:
	clk_disable_unprepare(scodec->clk_apb);
	return ret;
}
コード例 #13
0
ファイル: rockchip_i2s.c プロジェクト: a2hojsjsjs/linux
static int rockchip_i2s_probe(struct platform_device *pdev)
{
	struct device_node *node = pdev->dev.of_node;
	struct rk_i2s_dev *i2s;
	struct snd_soc_dai_driver *soc_dai;
	struct resource *res;
	void __iomem *regs;
	int ret;
	int val;

	i2s = devm_kzalloc(&pdev->dev, sizeof(*i2s), GFP_KERNEL);
	if (!i2s) {
		dev_err(&pdev->dev, "Can't allocate rk_i2s_dev\n");
		return -ENOMEM;
	}

	/* try to prepare related clocks */
	i2s->hclk = devm_clk_get(&pdev->dev, "i2s_hclk");
	if (IS_ERR(i2s->hclk)) {
		dev_err(&pdev->dev, "Can't retrieve i2s bus clock\n");
		return PTR_ERR(i2s->hclk);
	}
	ret = clk_prepare_enable(i2s->hclk);
	if (ret) {
		dev_err(i2s->dev, "hclock enable failed %d\n", ret);
		return ret;
	}

	i2s->mclk = devm_clk_get(&pdev->dev, "i2s_clk");
	if (IS_ERR(i2s->mclk)) {
		dev_err(&pdev->dev, "Can't retrieve i2s master clock\n");
		return PTR_ERR(i2s->mclk);
	}

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	regs = devm_ioremap_resource(&pdev->dev, res);
	if (IS_ERR(regs))
		return PTR_ERR(regs);

	i2s->regmap = devm_regmap_init_mmio(&pdev->dev, regs,
					    &rockchip_i2s_regmap_config);
	if (IS_ERR(i2s->regmap)) {
		dev_err(&pdev->dev,
			"Failed to initialise managed register map\n");
		return PTR_ERR(i2s->regmap);
	}

	i2s->playback_dma_data.addr = res->start + I2S_TXDR;
	i2s->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
	i2s->playback_dma_data.maxburst = 4;

	i2s->capture_dma_data.addr = res->start + I2S_RXDR;
	i2s->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
	i2s->capture_dma_data.maxburst = 4;

	i2s->dev = &pdev->dev;
	dev_set_drvdata(&pdev->dev, i2s);

	pm_runtime_enable(&pdev->dev);
	if (!pm_runtime_enabled(&pdev->dev)) {
		ret = i2s_runtime_resume(&pdev->dev);
		if (ret)
			goto err_pm_disable;
	}

	soc_dai = devm_kzalloc(&pdev->dev,
			       sizeof(*soc_dai), GFP_KERNEL);
	if (!soc_dai)
		return -ENOMEM;

	memcpy(soc_dai, &rockchip_i2s_dai, sizeof(*soc_dai));
	if (!of_property_read_u32(node, "rockchip,playback-channels", &val)) {
		if (val >= 2 && val <= 8)
			soc_dai->playback.channels_max = val;
	}

	if (!of_property_read_u32(node, "rockchip,capture-channels", &val)) {
		if (val >= 2 && val <= 8)
			soc_dai->capture.channels_max = val;
	}

	ret = devm_snd_soc_register_component(&pdev->dev,
					      &rockchip_i2s_component,
					      soc_dai, 1);

	if (ret) {
		dev_err(&pdev->dev, "Could not register DAI\n");
		goto err_suspend;
	}

	ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
	if (ret) {
		dev_err(&pdev->dev, "Could not register PCM\n");
		return ret;
	}

	return 0;

err_suspend:
	if (!pm_runtime_status_suspended(&pdev->dev))
		i2s_runtime_suspend(&pdev->dev);
err_pm_disable:
	pm_runtime_disable(&pdev->dev);

	return ret;
}
コード例 #14
0
ファイル: mxs-pcm.c プロジェクト: 020gzh/linux
int mxs_pcm_platform_register(struct device *dev)
{
	return devm_snd_dmaengine_pcm_register(dev, &mxs_dmaengine_pcm_config,
		SND_DMAENGINE_PCM_FLAG_HALF_DUPLEX);
}
コード例 #15
0
ファイル: img-i2s-out.c プロジェクト: AlexShiLucky/linux
static int img_i2s_out_probe(struct platform_device *pdev)
{
	struct img_i2s_out *i2s;
	struct resource *res;
	void __iomem *base;
	int i, ret;
	unsigned int max_i2s_chan_pow_2;
	u32 reg;
	struct device *dev = &pdev->dev;

	i2s = devm_kzalloc(&pdev->dev, sizeof(*i2s), GFP_KERNEL);
	if (!i2s)
		return -ENOMEM;

	platform_set_drvdata(pdev, i2s);

	i2s->dev = &pdev->dev;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	base = devm_ioremap_resource(&pdev->dev, res);
	if (IS_ERR(base))
		return PTR_ERR(base);

	i2s->base = base;

	if (of_property_read_u32(pdev->dev.of_node, "img,i2s-channels",
			&i2s->max_i2s_chan)) {
		dev_err(&pdev->dev, "No img,i2s-channels property\n");
		return -EINVAL;
	}

	max_i2s_chan_pow_2 = 1 << get_count_order(i2s->max_i2s_chan);

	i2s->channel_base = base + (max_i2s_chan_pow_2 * 0x20);

	i2s->rst = devm_reset_control_get_exclusive(&pdev->dev, "rst");
	if (IS_ERR(i2s->rst)) {
		if (PTR_ERR(i2s->rst) != -EPROBE_DEFER)
			dev_err(&pdev->dev, "No top level reset found\n");
		return PTR_ERR(i2s->rst);
	}

	i2s->clk_sys = devm_clk_get(&pdev->dev, "sys");
	if (IS_ERR(i2s->clk_sys)) {
		if (PTR_ERR(i2s->clk_sys) != -EPROBE_DEFER)
			dev_err(dev, "Failed to acquire clock 'sys'\n");
		return PTR_ERR(i2s->clk_sys);
	}

	i2s->clk_ref = devm_clk_get(&pdev->dev, "ref");
	if (IS_ERR(i2s->clk_ref)) {
		if (PTR_ERR(i2s->clk_ref) != -EPROBE_DEFER)
			dev_err(dev, "Failed to acquire clock 'ref'\n");
		return PTR_ERR(i2s->clk_ref);
	}

	i2s->suspend_ch_ctl = devm_kcalloc(dev,
		i2s->max_i2s_chan, sizeof(*i2s->suspend_ch_ctl), GFP_KERNEL);
	if (!i2s->suspend_ch_ctl)
		return -ENOMEM;

	pm_runtime_enable(&pdev->dev);
	if (!pm_runtime_enabled(&pdev->dev)) {
		ret = img_i2s_out_runtime_resume(&pdev->dev);
		if (ret)
			goto err_pm_disable;
	}
	ret = pm_runtime_get_sync(&pdev->dev);
	if (ret < 0)
		goto err_suspend;

	reg = IMG_I2S_OUT_CTL_FRM_SIZE_MASK;
	img_i2s_out_writel(i2s, reg, IMG_I2S_OUT_CTL);

	reg = IMG_I2S_OUT_CHAN_CTL_JUST_MASK |
		IMG_I2S_OUT_CHAN_CTL_LT_MASK |
		IMG_I2S_OUT_CHAN_CTL_CH_MASK |
		(8 << IMG_I2S_OUT_CHAN_CTL_FMT_SHIFT);

	for (i = 0; i < i2s->max_i2s_chan; i++)
		img_i2s_out_ch_writel(i2s, i, reg, IMG_I2S_OUT_CH_CTL);

	img_i2s_out_reset(i2s);
	pm_runtime_put(&pdev->dev);

	i2s->active_channels = 1;
	i2s->dma_data.addr = res->start + IMG_I2S_OUT_TX_FIFO;
	i2s->dma_data.addr_width = 4;
	i2s->dma_data.maxburst = 4;

	i2s->dai_driver.probe = img_i2s_out_dai_probe;
	i2s->dai_driver.playback.channels_min = 2;
	i2s->dai_driver.playback.channels_max = i2s->max_i2s_chan * 2;
	i2s->dai_driver.playback.rates = SNDRV_PCM_RATE_8000_192000;
	i2s->dai_driver.playback.formats = SNDRV_PCM_FMTBIT_S32_LE;
	i2s->dai_driver.ops = &img_i2s_out_dai_ops;

	ret = devm_snd_soc_register_component(&pdev->dev,
			&img_i2s_out_component, &i2s->dai_driver, 1);
	if (ret)
		goto err_suspend;

	ret = devm_snd_dmaengine_pcm_register(&pdev->dev,
			&img_i2s_out_dma_config, 0);
	if (ret)
		goto err_suspend;

	return 0;

err_suspend:
	if (!pm_runtime_status_suspended(&pdev->dev))
		img_i2s_out_runtime_suspend(&pdev->dev);
err_pm_disable:
	pm_runtime_disable(&pdev->dev);

	return ret;
}
コード例 #16
0
ファイル: axi-i2s.c プロジェクト: 3null/linux
static int axi_i2s_probe(struct platform_device *pdev)
{
	struct resource *res;
	struct axi_i2s *i2s;
	void __iomem *base;
	int ret;

	i2s = devm_kzalloc(&pdev->dev, sizeof(*i2s), GFP_KERNEL);
	if (!i2s)
		return -ENOMEM;

	platform_set_drvdata(pdev, i2s);

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	base = devm_ioremap_resource(&pdev->dev, res);
	if (IS_ERR(base))
		return PTR_ERR(base);

	i2s->regmap = devm_regmap_init_mmio(&pdev->dev, base,
		&axi_i2s_regmap_config);
	if (IS_ERR(i2s->regmap))
		return PTR_ERR(i2s->regmap);

	i2s->clk = devm_clk_get(&pdev->dev, "axi");
	if (IS_ERR(i2s->clk))
		return PTR_ERR(i2s->clk);

	i2s->clk_ref = devm_clk_get(&pdev->dev, "ref");
	if (IS_ERR(i2s->clk_ref))
		return PTR_ERR(i2s->clk_ref);

	ret = clk_prepare_enable(i2s->clk);
	if (ret)
		return ret;

	i2s->playback_dma_data.addr = res->start + AXI_I2S_REG_TX_FIFO;
	i2s->playback_dma_data.addr_width = 4;
	i2s->playback_dma_data.maxburst = 1;

	i2s->capture_dma_data.addr = res->start + AXI_I2S_REG_RX_FIFO;
	i2s->capture_dma_data.addr_width = 4;
	i2s->capture_dma_data.maxburst = 1;

	i2s->ratnum.num = clk_get_rate(i2s->clk_ref) / 2 / AXI_I2S_BITS_PER_FRAME;
	i2s->ratnum.den_step = 1;
	i2s->ratnum.den_min = 1;
	i2s->ratnum.den_max = 64;

	i2s->rate_constraints.rats = &i2s->ratnum;
	i2s->rate_constraints.nrats = 1;

	regmap_write(i2s->regmap, AXI_I2S_REG_RESET, AXI_I2S_RESET_GLOBAL);

	ret = devm_snd_soc_register_component(&pdev->dev, &axi_i2s_component,
					 &axi_i2s_dai, 1);
	if (ret)
		goto err_clk_disable;

	ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
	if (ret)
		goto err_clk_disable;

err_clk_disable:
	clk_disable_unprepare(i2s->clk);
	return ret;
}
コード例 #17
0
ファイル: designware_i2s.c プロジェクト: rochecr/linux
static int dw_i2s_probe(struct platform_device *pdev)
{
	const struct i2s_platform_data *pdata = pdev->dev.platform_data;
	struct dw_i2s_dev *dev;
	struct resource *res;
	int ret;
	struct snd_soc_dai_driver *dw_i2s_dai;

	dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
	if (!dev) {
		dev_warn(&pdev->dev, "kzalloc fail\n");
		return -ENOMEM;
	}

	dw_i2s_dai = devm_kzalloc(&pdev->dev, sizeof(*dw_i2s_dai), GFP_KERNEL);
	if (!dw_i2s_dai)
		return -ENOMEM;

	dw_i2s_dai->ops = &dw_i2s_dai_ops;
	dw_i2s_dai->suspend = dw_i2s_suspend;
	dw_i2s_dai->resume = dw_i2s_resume;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	dev->i2s_base = devm_ioremap_resource(&pdev->dev, res);
	if (IS_ERR(dev->i2s_base))
		return PTR_ERR(dev->i2s_base);

	dev->dev = &pdev->dev;
	if (pdata) {
		ret = dw_configure_dai_by_pd(dev, dw_i2s_dai, res, pdata);
		if (ret < 0)
			return ret;

		dev->capability = pdata->cap;
		dev->i2s_clk_cfg = pdata->i2s_clk_cfg;
		if (!dev->i2s_clk_cfg) {
			dev_err(&pdev->dev, "no clock configure method\n");
			return -ENODEV;
		}

		dev->clk = devm_clk_get(&pdev->dev, NULL);
	} else {
		ret = dw_configure_dai_by_dt(dev, dw_i2s_dai, res);
		if (ret < 0)
			return ret;

		dev->clk = devm_clk_get(&pdev->dev, "i2sclk");
	}
	if (IS_ERR(dev->clk))
		return PTR_ERR(dev->clk);

	ret = clk_prepare_enable(dev->clk);
	if (ret < 0)
		return ret;

	dev_set_drvdata(&pdev->dev, dev);
	ret = devm_snd_soc_register_component(&pdev->dev, &dw_i2s_component,
					 dw_i2s_dai, 1);
	if (ret != 0) {
		dev_err(&pdev->dev, "not able to register dai\n");
		goto err_clk_disable;
	}

	if (!pdata) {
		ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
		if (ret) {
			dev_err(&pdev->dev,
				"Could not register PCM: %d\n", ret);
			goto err_clk_disable;
		}
	}

	return 0;

err_clk_disable:
	clk_disable_unprepare(dev->clk);
	return ret;
}
コード例 #18
0
static int axi_spdif_probe(struct platform_device *pdev)
{
	struct axi_spdif *spdif;
	struct resource *res;
	void __iomem *base;
	int ret;

	spdif = devm_kzalloc(&pdev->dev, sizeof(*spdif), GFP_KERNEL);
	if (!spdif)
		return -ENOMEM;

	platform_set_drvdata(pdev, spdif);

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	base = devm_ioremap_resource(&pdev->dev, res);
	if (IS_ERR(base))
		return PTR_ERR(base);

	spdif->regmap = devm_regmap_init_mmio(&pdev->dev, base,
					    &axi_spdif_regmap_config);
	if (IS_ERR(spdif->regmap))
		return PTR_ERR(spdif->regmap);

	spdif->clk = devm_clk_get(&pdev->dev, "axi");
	if (IS_ERR(spdif->clk))
		return PTR_ERR(spdif->clk);

	spdif->clk_ref = devm_clk_get(&pdev->dev, "ref");
	if (IS_ERR(spdif->clk_ref))
		return PTR_ERR(spdif->clk_ref);

	ret = clk_prepare_enable(spdif->clk);
	if (ret)
		return ret;

	spdif->dma_data.addr = res->start + AXI_SPDIF_REG_TX_FIFO;
	spdif->dma_data.addr_width = 4;
	spdif->dma_data.maxburst = 1;

	spdif->ratnum.num = clk_get_rate(spdif->clk_ref) / 128;
	spdif->ratnum.den_step = 1;
	spdif->ratnum.den_min = 1;
	spdif->ratnum.den_max = 64;

	spdif->rate_constraints.rats = &spdif->ratnum;
	spdif->rate_constraints.nrats = 1;

	ret = devm_snd_soc_register_component(&pdev->dev, &axi_spdif_component,
					 &axi_spdif_dai, 1);
	if (ret)
		goto err_clk_disable;

	ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
	if (ret)
		goto err_clk_disable;

	return 0;

err_clk_disable:
	clk_disable_unprepare(spdif->clk);
	return ret;
}
コード例 #19
0
static int oc_i2s_probe(struct platform_device *pdev)
{
       struct resource *res, *res_clk;
       struct oc_i2s *i2s;
       void __iomem *base;
       int signature;
       int ret;

       i2s = devm_kzalloc(&pdev->dev, sizeof(*i2s), GFP_KERNEL);
       if (!i2s) {
               dev_err(&pdev->dev, "Can't allocate oc_i2s\n");
               return -ENOMEM;
       }
       platform_set_drvdata(pdev, i2s);

       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
       if (!res) {
               dev_err(&pdev->dev, "No memory resource\n");
               return -ENODEV;
       }
       base = devm_ioremap_resource(&pdev->dev, res);
       if (IS_ERR(base)) {
               dev_err(&pdev->dev, "No ioremap resource\n");
               return PTR_ERR(base);
       }
       printk(KERN_ALERT "oc_i2s at %08x\n", (int)base);

       i2s->regmap_data = devm_regmap_init_mmio(&pdev->dev, base,
               &oc_i2s_regmap_data_config);
       if (IS_ERR(i2s->regmap_data)) {
               dev_err(&pdev->dev, "No regmap_data\n");
               return PTR_ERR(i2s->regmap_data);
       }

       res_clk = platform_get_resource(pdev, IORESOURCE_MEM, 1);
       if (!res_clk) {
               dev_err(&pdev->dev, "No memory resource\n");
               return -ENODEV;
       }
       base = devm_ioremap_resource(&pdev->dev, res_clk);
       if (IS_ERR(base)) {
               dev_err(&pdev->dev, "No ioremap resource\n");
               return PTR_ERR(base);
       }

       i2s->regmap_clk = devm_regmap_init_mmio(&pdev->dev, base,
               &oc_i2s_regmap_clk_config);
       if (IS_ERR(i2s->regmap_clk)) {
               dev_err(&pdev->dev, "No regmap_clk\n");
               return PTR_ERR(i2s->regmap_clk);
       }

       i2s->clk48 = devm_clk_get(&pdev->dev, "clk48");
       if (IS_ERR(i2s->clk48)) {
               dev_err(&pdev->dev, "No clk48 clock\n");
               return PTR_ERR(i2s->clk48);
       }

       ret = clk_prepare_enable(i2s->clk48);
       if (ret) {
               dev_err(&pdev->dev, "Cannot enable clock\n");
               return ret;
       }

       i2s->clk44 = devm_clk_get(&pdev->dev, "clk44");
       if (IS_ERR(i2s->clk44)) {
               dev_err(&pdev->dev, "No clk44 clock\n");
               return PTR_ERR(i2s->clk44);
       }

       ret = clk_prepare_enable(i2s->clk44);
       if (ret) {
               dev_err(&pdev->dev, "Cannot enable clock\n");
               return ret;
       }

       i2s->playback_dma_data.addr = res->start + DAC_FIFO_ADDR;
       i2s->playback_dma_data.addr_width = 4;
       i2s->playback_dma_data.maxburst = 1;
       //i2s->playback_dma_data.maxburst = 2;
       dev_dbg(&pdev->dev, "probe playback dma addr : %8x\n",
               i2s->playback_dma_data.addr);

       i2s->capture_dma_data.addr = res->start + ADC_FIFO_ADDR;
       i2s->capture_dma_data.addr_width = 4;
       i2s->capture_dma_data.maxburst = 1;
       //i2s->capture_dma_data.maxburst = 2;

/*
       i2s->ratnum.num = clk_get_rate(i2s->clk_ref) / 2 / BITS_PER_FRAME;
       i2s->ratnum.den_step = 1;
       i2s->ratnum.den_min = 1;
       i2s->ratnum.den_max = 64;

       i2s->rate_constraints.rats = &i2s->ratnum;
       i2s->rate_constraints.nrats = 1;
*/

       regmap_write(i2s->regmap_data, CMD_ADDR, PB_FIFO_CLEAR | CAP_FIFO_CLEAR);
       ret = regmap_read(i2s->regmap_data, STATUS_ADDR, &signature);
       if (ret) {
               dev_err(&pdev->dev, "Cannot read signature\n");
               printk(KERN_ALERT "oc_i2s probe signature : %4x\n", signature);
               goto err_clk_disable;
       }
       dev_dbg(&pdev->dev, "probe signature : %4x\n", signature);

       ret = devm_snd_soc_register_component(&pdev->dev, &oc_i2s_component,
                                        &oc_i2s_dai, 1);
       if (ret) {
               dev_err(&pdev->dev, "Cannot register component\n");
               goto err_clk_disable;
       }

       ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
       if (ret) {
               dev_err(&pdev->dev, "Cannot register dmaengine\n");
               goto err_clk_disable;
       }

       dev_dbg(&pdev->dev, "probe finishing\n");
       return ret;

err_clk_disable:
       clk_disable_unprepare(i2s->clk48);
       clk_disable_unprepare(i2s->clk44);
       return ret;
}
コード例 #20
0
static int bcm2835_i2s_probe(struct platform_device *pdev)
{
	struct bcm2835_i2s_dev *dev;
	int i;
	int ret;
	struct regmap *regmap[2];
	struct resource *mem[2];

	/* Request both ioareas */
	for (i = 0; i <= 1; i++) {
		void __iomem *base;

		mem[i] = platform_get_resource(pdev, IORESOURCE_MEM, i);
		base = devm_ioremap_resource(&pdev->dev, mem[i]);
		if (IS_ERR(base))
			return PTR_ERR(base);

		regmap[i] = devm_regmap_init_mmio(&pdev->dev, base,
					    &bcm2835_regmap_config[i]);
		if (IS_ERR(regmap[i]))
			return PTR_ERR(regmap[i]);
	}

	dev = devm_kzalloc(&pdev->dev, sizeof(*dev),
			   GFP_KERNEL);
	if (!dev)
		return -ENOMEM;

	dev->i2s_regmap = regmap[0];
	dev->clk_regmap = regmap[1];

	/* Set the DMA address */
	dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK].addr =
		(dma_addr_t)mem[0]->start + BCM2835_I2S_FIFO_A_REG
					  + BCM2835_VCMMU_SHIFT;

	dev->dma_data[SNDRV_PCM_STREAM_CAPTURE].addr =
		(dma_addr_t)mem[0]->start + BCM2835_I2S_FIFO_A_REG
					  + BCM2835_VCMMU_SHIFT;

	/* Set the bus width */
	dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK].addr_width =
		DMA_SLAVE_BUSWIDTH_4_BYTES;
	dev->dma_data[SNDRV_PCM_STREAM_CAPTURE].addr_width =
		DMA_SLAVE_BUSWIDTH_4_BYTES;

	/* Set burst */
	dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK].maxburst = 2;
	dev->dma_data[SNDRV_PCM_STREAM_CAPTURE].maxburst = 2;

	/* BCLK ratio - use default */
	dev->bclk_ratio = 0;

	/* Store the pdev */
	dev->dev = &pdev->dev;
	dev_set_drvdata(&pdev->dev, dev);

	ret = devm_snd_soc_register_component(&pdev->dev,
			&bcm2835_i2s_component, &bcm2835_i2s_dai, 1);
	if (ret) {
		dev_err(&pdev->dev, "Could not register DAI: %d\n", ret);
		return ret;
	}

	ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
	if (ret) {
		dev_err(&pdev->dev, "Could not register PCM: %d\n", ret);
		return ret;
	}

	return 0;
}
コード例 #21
0
ファイル: stm32_spdifrx.c プロジェクト: mdamt/linux
static int stm32_spdifrx_probe(struct platform_device *pdev)
{
	struct stm32_spdifrx_data *spdifrx;
	struct reset_control *rst;
	const struct snd_dmaengine_pcm_config *pcm_config = NULL;
	int ret;

	spdifrx = devm_kzalloc(&pdev->dev, sizeof(*spdifrx), GFP_KERNEL);
	if (!spdifrx)
		return -ENOMEM;

	spdifrx->pdev = pdev;
	init_completion(&spdifrx->cs_completion);
	spin_lock_init(&spdifrx->lock);

	platform_set_drvdata(pdev, spdifrx);

	ret = stm_spdifrx_parse_of(pdev, spdifrx);
	if (ret)
		return ret;

	spdifrx->regmap = devm_regmap_init_mmio_clk(&pdev->dev, "kclk",
						    spdifrx->base,
						    spdifrx->regmap_conf);
	if (IS_ERR(spdifrx->regmap)) {
		dev_err(&pdev->dev, "Regmap init failed\n");
		return PTR_ERR(spdifrx->regmap);
	}

	ret = devm_request_irq(&pdev->dev, spdifrx->irq, stm32_spdifrx_isr, 0,
			       dev_name(&pdev->dev), spdifrx);
	if (ret) {
		dev_err(&pdev->dev, "IRQ request returned %d\n", ret);
		return ret;
	}

	rst = devm_reset_control_get(&pdev->dev, NULL);
	if (!IS_ERR(rst)) {
		reset_control_assert(rst);
		udelay(2);
		reset_control_deassert(rst);
	}

	ret = devm_snd_soc_register_component(&pdev->dev,
					      &stm32_spdifrx_component,
					      stm32_spdifrx_dai,
					      ARRAY_SIZE(stm32_spdifrx_dai));
	if (ret)
		return ret;

	ret = stm32_spdifrx_dma_ctrl_register(&pdev->dev, spdifrx);
	if (ret)
		goto error;

	pcm_config = &stm32_spdifrx_pcm_config;
	ret = devm_snd_dmaengine_pcm_register(&pdev->dev, pcm_config, 0);
	if (ret) {
		dev_err(&pdev->dev, "PCM DMA register returned %d\n", ret);
		goto error;
	}

	return 0;

error:
	if (spdifrx->ctrl_chan)
		dma_release_channel(spdifrx->ctrl_chan);
	if (spdifrx->dmab)
		snd_dma_free_pages(spdifrx->dmab);

	return ret;
}
コード例 #22
0
ファイル: rockchip_pcm.c プロジェクト: Lyude/linux
int rockchip_pcm_platform_register(struct device *dev)
{
	return devm_snd_dmaengine_pcm_register(dev, &rk_dmaengine_pcm_config,
		SND_DMAENGINE_PCM_FLAG_COMPAT);
}
コード例 #23
0
ファイル: img-spdif-out.c プロジェクト: mkrufky/linux
static int img_spdif_out_probe(struct platform_device *pdev)
{
	struct img_spdif_out *spdif;
	struct resource *res;
	void __iomem *base;
	int ret;
	struct device *dev = &pdev->dev;

	spdif = devm_kzalloc(&pdev->dev, sizeof(*spdif), GFP_KERNEL);
	if (!spdif)
		return -ENOMEM;

	platform_set_drvdata(pdev, spdif);

	spdif->dev = &pdev->dev;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	base = devm_ioremap_resource(&pdev->dev, res);
	if (IS_ERR(base))
		return PTR_ERR(base);

	spdif->base = base;

	spdif->rst = devm_reset_control_get_exclusive(&pdev->dev, "rst");
	if (IS_ERR(spdif->rst)) {
		if (PTR_ERR(spdif->rst) != -EPROBE_DEFER)
			dev_err(&pdev->dev, "No top level reset found\n");
		return PTR_ERR(spdif->rst);
	}

	spdif->clk_sys = devm_clk_get(&pdev->dev, "sys");
	if (IS_ERR(spdif->clk_sys)) {
		if (PTR_ERR(spdif->clk_sys) != -EPROBE_DEFER)
			dev_err(dev, "Failed to acquire clock 'sys'\n");
		return PTR_ERR(spdif->clk_sys);
	}

	spdif->clk_ref = devm_clk_get(&pdev->dev, "ref");
	if (IS_ERR(spdif->clk_ref)) {
		if (PTR_ERR(spdif->clk_ref) != -EPROBE_DEFER)
			dev_err(dev, "Failed to acquire clock 'ref'\n");
		return PTR_ERR(spdif->clk_ref);
	}

	ret = clk_prepare_enable(spdif->clk_sys);
	if (ret)
		return ret;

	img_spdif_out_writel(spdif, IMG_SPDIF_OUT_CTL_FS_MASK,
				IMG_SPDIF_OUT_CTL);

	img_spdif_out_reset(spdif);

	pm_runtime_enable(&pdev->dev);
	if (!pm_runtime_enabled(&pdev->dev)) {
		ret = img_spdif_out_resume(&pdev->dev);
		if (ret)
			goto err_pm_disable;
	}

	spin_lock_init(&spdif->lock);

	spdif->dma_data.addr = res->start + IMG_SPDIF_OUT_TX_FIFO;
	spdif->dma_data.addr_width = 4;
	spdif->dma_data.maxburst = 4;

	ret = devm_snd_soc_register_component(&pdev->dev,
			&img_spdif_out_component,
			&img_spdif_out_dai, 1);
	if (ret)
		goto err_suspend;

	ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
	if (ret)
		goto err_suspend;

	dev_dbg(&pdev->dev, "Probe successful\n");

	return 0;

err_suspend:
	if (!pm_runtime_status_suspended(&pdev->dev))
		img_spdif_out_suspend(&pdev->dev);
err_pm_disable:
	pm_runtime_disable(&pdev->dev);
	clk_disable_unprepare(spdif->clk_sys);

	return ret;
}
コード例 #24
0
ファイル: zx-tdm.c プロジェクト: ReneNyffenegger/linux
static int zx_tdm_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct of_phandle_args out_args;
	unsigned int dma_reg_offset;
	struct zx_tdm_info *zx_tdm;
	unsigned int dma_mask;
	struct resource *res;
	struct regmap *regmap_sysctrl;
	int ret;

	zx_tdm = devm_kzalloc(&pdev->dev, sizeof(*zx_tdm), GFP_KERNEL);
	if (!zx_tdm)
		return -ENOMEM;

	zx_tdm->dev = dev;

	zx_tdm->dai_wclk = devm_clk_get(&pdev->dev, "wclk");
	if (IS_ERR(zx_tdm->dai_wclk)) {
		dev_err(&pdev->dev, "Fail to get wclk\n");
		return PTR_ERR(zx_tdm->dai_wclk);
	}

	zx_tdm->dai_pclk = devm_clk_get(&pdev->dev, "pclk");
	if (IS_ERR(zx_tdm->dai_pclk)) {
		dev_err(&pdev->dev, "Fail to get pclk\n");
		return PTR_ERR(zx_tdm->dai_pclk);
	}

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	zx_tdm->phy_addr = res->start;
	zx_tdm->regbase = devm_ioremap_resource(&pdev->dev, res);
	if (IS_ERR(zx_tdm->regbase))
		return PTR_ERR(zx_tdm->regbase);

	ret = of_parse_phandle_with_fixed_args(pdev->dev.of_node,
				"zte,tdm-dma-sysctrl", 2, 0, &out_args);
	if (ret) {
		dev_err(&pdev->dev, "Fail to get zte,tdm-dma-sysctrl\n");
		return ret;
	}

	dma_reg_offset = out_args.args[0];
	dma_mask = out_args.args[1];
	regmap_sysctrl = syscon_node_to_regmap(out_args.np);
	if (IS_ERR(regmap_sysctrl)) {
		of_node_put(out_args.np);
		return PTR_ERR(regmap_sysctrl);
	}

	regmap_update_bits(regmap_sysctrl, dma_reg_offset, dma_mask, dma_mask);
	of_node_put(out_args.np);

	zx_tdm_init_state(zx_tdm);
	platform_set_drvdata(pdev, zx_tdm);

	ret = devm_snd_soc_register_component(&pdev->dev, &zx_tdm_component,
						&zx_tdm_dai, 1);
	if (ret) {
		dev_err(&pdev->dev, "Register DAI failed: %d\n", ret);
		return ret;
	}

	ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
	if (ret)
		dev_err(&pdev->dev, "Register platform PCM failed: %d\n", ret);

	return ret;
}
コード例 #25
0
ファイル: dwc-i2s.c プロジェクト: ReneNyffenegger/linux
static int dw_i2s_probe(struct platform_device *pdev)
{
	const struct i2s_platform_data *pdata = pdev->dev.platform_data;
	struct dw_i2s_dev *dev;
	struct resource *res;
	int ret, irq;
	struct snd_soc_dai_driver *dw_i2s_dai;
	const char *clk_id;

	dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
	if (!dev)
		return -ENOMEM;

	dw_i2s_dai = devm_kzalloc(&pdev->dev, sizeof(*dw_i2s_dai), GFP_KERNEL);
	if (!dw_i2s_dai)
		return -ENOMEM;

	dw_i2s_dai->ops = &dw_i2s_dai_ops;
	dw_i2s_dai->suspend = dw_i2s_suspend;
	dw_i2s_dai->resume = dw_i2s_resume;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	dev->i2s_base = devm_ioremap_resource(&pdev->dev, res);
	if (IS_ERR(dev->i2s_base))
		return PTR_ERR(dev->i2s_base);

	dev->dev = &pdev->dev;

	irq = platform_get_irq(pdev, 0);
	if (irq >= 0) {
		ret = devm_request_irq(&pdev->dev, irq, i2s_irq_handler, 0,
				pdev->name, dev);
		if (ret < 0) {
			dev_err(&pdev->dev, "failed to request irq\n");
			return ret;
		}
	}

	dev->i2s_reg_comp1 = I2S_COMP_PARAM_1;
	dev->i2s_reg_comp2 = I2S_COMP_PARAM_2;
	if (pdata) {
		dev->capability = pdata->cap;
		clk_id = NULL;
		dev->quirks = pdata->quirks;
		if (dev->quirks & DW_I2S_QUIRK_COMP_REG_OFFSET) {
			dev->i2s_reg_comp1 = pdata->i2s_reg_comp1;
			dev->i2s_reg_comp2 = pdata->i2s_reg_comp2;
		}
		ret = dw_configure_dai_by_pd(dev, dw_i2s_dai, res, pdata);
	} else {
		clk_id = "i2sclk";
		ret = dw_configure_dai_by_dt(dev, dw_i2s_dai, res);
	}
	if (ret < 0)
		return ret;

	if (dev->capability & DW_I2S_MASTER) {
		if (pdata) {
			dev->i2s_clk_cfg = pdata->i2s_clk_cfg;
			if (!dev->i2s_clk_cfg) {
				dev_err(&pdev->dev, "no clock configure method\n");
				return -ENODEV;
			}
		}
		dev->clk = devm_clk_get(&pdev->dev, clk_id);

		if (IS_ERR(dev->clk))
			return PTR_ERR(dev->clk);

		ret = clk_prepare_enable(dev->clk);
		if (ret < 0)
			return ret;
	}

	dev_set_drvdata(&pdev->dev, dev);
	ret = devm_snd_soc_register_component(&pdev->dev, &dw_i2s_component,
					 dw_i2s_dai, 1);
	if (ret != 0) {
		dev_err(&pdev->dev, "not able to register dai\n");
		goto err_clk_disable;
	}

	if (!pdata) {
		if (irq >= 0) {
			ret = dw_pcm_register(pdev);
			dev->use_pio = true;
		} else {
			ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL,
					0);
			dev->use_pio = false;
		}

		if (ret) {
			dev_err(&pdev->dev, "could not register pcm: %d\n",
					ret);
			goto err_clk_disable;
		}
	}

	pm_runtime_enable(&pdev->dev);
	return 0;

err_clk_disable:
	if (dev->capability & DW_I2S_MASTER)
		clk_disable_unprepare(dev->clk);
	return ret;
}