예제 #1
0
static int rockchip_i2s_probe(struct platform_device *pdev)
{
	struct device_node *node = pdev->dev.of_node;
	struct rk30_i2s_info *i2s;
	struct resource *mem, *memregion;
	u32 regs_base;
	int ret;

	I2S_DBG("%s()\n", __FUNCTION__);

	ret = of_property_read_u32(node, "i2s-id", &pdev->id);
	if (ret < 0) {
		dev_err(&pdev->dev, "%s() Can not read property: id\n", __FUNCTION__);
		ret = -ENOMEM;
		goto err;
	}

	if(pdev->id >= MAX_I2S) {
		dev_err(&pdev->dev, "id %d out of range\n", pdev->id);
		ret = -ENOMEM;
		goto err;
	}

	i2s = devm_kzalloc(&pdev->dev, sizeof(struct rk30_i2s_info), GFP_KERNEL);
	if (!i2s) {
		dev_err(&pdev->dev, "Can't allocate i2s info\n");
		ret = -ENOMEM;
		goto err;
	}

	rk30_i2s = i2s;

	i2s->i2s_hclk = clk_get(&pdev->dev, "i2s_hclk");
	if(IS_ERR(i2s->i2s_hclk) ) {
                dev_err(&pdev->dev, "get i2s_hclk failed.\n");
        } else{
		clk_prepare_enable(i2s->i2s_hclk);
	}

	i2s->i2s_clk= clk_get(&pdev->dev, "i2s_clk");
	if (IS_ERR(i2s->i2s_clk)) {
		dev_err(&pdev->dev, "Can't retrieve i2s clock\n");
		ret = PTR_ERR(i2s->i2s_clk);
		goto err;
	}
#ifdef CLK_SET_lATER
	INIT_DELAYED_WORK(&i2s->clk_delayed_work, set_clk_later_work);
	schedule_delayed_work(&i2s->clk_delayed_work, msecs_to_jiffies(10));
#else
	clk_set_rate(i2s->iis_clk, 11289600);
#endif	
	clk_prepare_enable(i2s->i2s_clk);

	i2s->i2s_mclk= clk_get(&pdev->dev, "i2s_mclk");
	if(IS_ERR(i2s->i2s_mclk) ) {
		printk("This platfrom have not i2s_mclk,no need to set i2s_mclk.\n");
	}else{
	#ifdef CLK_SET_lATER
		
	#else
		clk_set_rate(i2s->i2s_mclk, 11289600);
	#endif
		clk_prepare_enable(i2s->i2s_mclk);
	}

	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!mem) {
		dev_err(&pdev->dev, "No memory resource\n");
		ret = -ENODEV;
		goto err_clk_put;
	}

	memregion = devm_request_mem_region(&pdev->dev, mem->start,
					    resource_size(mem), "rockchip-i2s");
	if (!memregion) {
		dev_err(&pdev->dev, "Memory region already claimed\n");
		ret = -EBUSY;
		goto err_clk_put;
	}

	i2s->regs = devm_ioremap(&pdev->dev, mem->start, resource_size(mem));
	if (!i2s->regs) {
		dev_err(&pdev->dev, "ioremap failed\n");
		ret = -ENOMEM;
		goto err_clk_put;
	}

	regs_base = mem->start;

	i2s->playback_dma_data.addr = regs_base + I2S_TXR_BUFF;
	i2s->playback_dma_data.addr_width = 4;
	i2s->playback_dma_data.maxburst = 1;

	i2s->capture_dma_data.addr = regs_base + I2S_RXR_BUFF;
	i2s->capture_dma_data.addr_width = 4;
	i2s->capture_dma_data.maxburst = 1;

	i2s->i2s_tx_status = false;
	i2s->i2s_rx_status = false;

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

	//set dev name to driver->name.id for sound card register
	dev_set_name(&pdev->dev, "%s.%d", pdev->dev.driver->name, pdev->id);

	ret = snd_soc_register_component(&pdev->dev, &rockchip_i2s_component,
		&rockchip_i2s_dai[pdev->id], 1);

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

	ret = rockchip_pcm_platform_register(&pdev->dev);
	if (ret) {
		dev_err(&pdev->dev, "Could not register PCM: %d\n", ret);
		goto err_unregister_component;
	}

	/* Mark ourselves as in TXRX mode so we can run through our cleanup
	 * process without warnings. */
	rockchip_snd_txctrl(i2s, 0);
	rockchip_snd_rxctrl(i2s, 0);

	dev_set_drvdata(&pdev->dev, i2s);
	return 0;

err_unregister_component:
	snd_soc_unregister_component(&pdev->dev);
err_suspend:
	if (!pm_runtime_status_suspended(&pdev->dev))
		rockchip_i2s_suspend_noirq(&pdev->dev);
err_pm_disable:
	pm_runtime_disable(&pdev->dev);
err_clk_put:
	clk_put(i2s->i2s_clk);
err:
	return ret;

}
static int spdif_probe(struct platform_device *pdev)
{
	/*struct device_node *spdif_np = pdev->dev.of_node;*/
	struct resource *memregion;
	struct resource *mem_res;
	struct rockchip_spdif_info *spdif;
	int ret;

	RK_SPDIF_DBG("Entered %s\n", __func__);

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

	spin_lock_init(&spdif->lock);

	/* get spdif register regoin. */
	mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!mem_res) {
		dev_err(&pdev->dev, "No memory resource\n");
		ret = -ENOENT;
		goto err_;
	}
	memregion = devm_request_mem_region(&pdev->
			dev, mem_res->start,
			resource_size(mem_res), "rockchip-spdif");
	if (!memregion) {
		dev_err(&pdev->dev, "Memory region already claimed\n");
		ret = -EBUSY;
		goto err_;
	}
	spdif->regs = devm_ioremap(&pdev->dev, memregion->
			start, resource_size(memregion));
	if (!spdif->regs) {
		dev_err(&pdev->dev, "ioremap failed\n");
		ret = -ENOMEM;
		goto err_;
	}

	/* get spdif clock and init. */
	spdif->hclk = devm_clk_get(&pdev->dev, "spdif_hclk");
	if (IS_ERR(spdif->hclk)) {
		dev_err(&pdev->dev, "Can't retrieve spdif hclock\n");
		spdif->hclk = NULL;
	}
	clk_prepare_enable(spdif->hclk);

	/* get spdif clock and init. */
	spdif->clk = devm_clk_get(&pdev->dev, "spdif_mclk");
	if (IS_ERR(spdif->clk)) {
		dev_err(&pdev->dev, "Can't retrieve spdif clock\n");
		ret = -ENOMEM;
		goto err_;
	}
	clk_set_rate(spdif->clk, 12288000);
	clk_set_rate(spdif->clk, 11289600);
	clk_prepare_enable(spdif->clk);

	spdif->dma_playback.addr = mem_res->start + DATA_OUTBUF;
	spdif->dma_playback.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
	spdif->dma_playback.maxburst = 4;

	/* set dev name to driver->name for sound card register */
	dev_set_name(&pdev->dev, "%s", pdev->dev.driver->name);

	ret = snd_soc_register_component(&pdev->
		dev, &rockchip_spdif_component,	&rockchip_spdif_dai, 1);
	if (ret) {
		dev_err(&pdev->dev, "Could not register DAI: %d\n", ret);
		ret = -ENOMEM;
		goto err_;
	}

	ret = rockchip_pcm_platform_register(&pdev->dev);
	if (ret) {
		dev_err(&pdev->dev, "Could not register PCM: %d\n", ret);
		goto err_;
	}

	RK_SPDIF_DBG("spdif:spdif probe ok!\n");

	return 0;

err_:
	platform_set_drvdata(pdev, NULL);

	return ret;
}