#include <linux/pm_runtime.h>
#include <linux/regmap.h>
#include <linux/slab.h>
-
#include <asm/dma.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
#include <sound/dmaengine_pcm.h>
#include <asm/io.h>
-
#include <linux/spinlock.h>
+#include <linux/workqueue.h>
+
+#define CLK_SET_lATER
#include "rk_pcm.h"
#include "rk_i2s.h"
struct clk *i2s_clk;// i2s clk ,is bclk lrck
struct clk *i2s_mclk;//i2s mclk,rk32xx can different i2s clk.
-
+ struct clk *i2s_hclk;
struct snd_dmaengine_dai_dma_data capture_dma_data;
struct snd_dmaengine_dai_dma_data playback_dma_data;
bool i2s_tx_status;//active = true;
bool i2s_rx_status;
+#ifdef CLK_SET_lATER
+ struct delayed_work clk_delayed_work;
+#endif
};
#define I2S_CLR_ERROR_COUNT 10// check I2S_CLR reg
u32 tx_ctl,rx_ctl;
u32 iis_ckr_value;//clock generation register
unsigned long flags;
+ int ret = 0;
I2S_DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__);
break;
default:
I2S_DBG("unknwon master/slave format\n");
- return -EINVAL;
+ ret = -EINVAL;
+ goto out_;
}
writel(iis_ckr_value, &(pheadi2s->I2S_CKR));
break;
default:
I2S_DBG("Unknown data format\n");
- return -EINVAL;
+ ret = -EINVAL;
+ goto out_;
}
I2S_DBG("Enter::%s----%d, I2S_TXCR=0x%X\n",__FUNCTION__,__LINE__,tx_ctl);
rx_ctl = tx_ctl & 0x00007FFF;
writel(rx_ctl, &(pheadi2s->I2S_RXCR));
+out_:
+
spin_unlock_irqrestore(&lock, flags);
- return 0;
+
+ return ret;
}
static int rockchip_i2s_hw_params(struct snd_pcm_substream *substream,
struct rk30_i2s_info *i2s;
u32 reg;
unsigned long flags;
+ int ret = 0;
i2s = to_info(cpu_dai);
case ROCKCHIP_DIV_PRESCALER:
break;
default:
- return -EINVAL;
+ ret = -EINVAL;
+ goto out_;
}
writel(reg, &(pheadi2s->I2S_CKR));
+
+out_:
spin_unlock_irqrestore(&lock, flags);
- return 0;
+ return ret;
}
static struct snd_soc_dai_ops rockchip_i2s_dai_ops = {
#define rockchip_i2s_resume_noirq NULL
#endif
+#ifdef CLK_SET_lATER
+static void set_clk_later_work(struct work_struct *work)
+{
+ struct rk30_i2s_info *i2s = rk30_i2s;
+ clk_set_rate(i2s->i2s_clk, 11289600);
+ if(!IS_ERR(i2s->i2s_mclk) )
+ clk_set_rate(i2s->i2s_mclk, 11289600);
+}
+#endif
+
static int rockchip_i2s_probe(struct platform_device *pdev)
{
struct device_node *node = pdev->dev.of_node;
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;
}
- clk_set_rate(i2s->i2s_clk, 11289600);
+#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);
}
rockchip_snd_rxctrl(i2s, 0);
dev_set_drvdata(&pdev->dev, i2s);
-
- rk30_i2s = i2s;
return 0;
err_unregister_component: