static int rockchip_i2s_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_dai *dai) { struct rk_i2s_dev *i2s = to_info(dai); int ret = 0; switch (cmd) { case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_RESUME: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) rockchip_snd_rxctrl(i2s, 1); else rockchip_snd_txctrl(i2s, 1); break; case SNDRV_PCM_TRIGGER_SUSPEND: case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_PAUSE_PUSH: if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) rockchip_snd_rxctrl(i2s, 0); else rockchip_snd_txctrl(i2s, 0); break; default: ret = -EINVAL; break; } return ret; }
static int rockchip_i2s_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_dai *dai) { struct rk30_i2s_info *i2s = to_info(dai); int ret = 0; I2S_DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__); switch (cmd) { case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_RESUME: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) rockchip_snd_rxctrl(i2s, 1); else { rockchip_snd_txctrl(i2s, 1); #ifdef CONFIG_RK_HDMI //hdmi_audio_mute(0); #endif } break; case SNDRV_PCM_TRIGGER_SUSPEND: case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_PAUSE_PUSH: if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) rockchip_snd_rxctrl(i2s, 0); else { rockchip_snd_txctrl(i2s, 0); #ifdef CONFIG_RK_HDMI //hdmi_audio_mute(1); #endif } break; default: ret = -EINVAL; break; } return ret; }
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; }