<&clkgen JH7110_I2SRX_3CH_BCLK_MST>,
<&clkgen JH7110_I2SRX_3CH_LRCK_MST>,
<&clkgen JH7110_I2SRX0_3CH_BCLK>,
- <&clkgen JH7110_I2SRX0_3CH_LRCK>;
+ <&clkgen JH7110_I2SRX0_3CH_LRCK>,
+ <&clkgen JH7110_MCLK>,
+ <&mclk_ext>;
clock-names = "apb0", "i2srx_apb",
"i2srx_bclk_mst", "i2srx_lrck_mst",
- "i2srx_bclk", "i2srx_lrck";
+ "i2srx_bclk", "i2srx_lrck",
+ "mclk", "mclk_ext";
resets = <&rstgen RSTN_U0_I2SRX_3CH_APB>,
<&rstgen RSTN_U0_I2SRX_3CH_BCLK>;
reset-names = "rst_apb_rx", "rst_bclk_rx";
<&clkgen JH7110_I2SRX0_3CH_BCLK>,
<&clkgen JH7110_I2SRX0_3CH_LRCK>,
<&clkgen JH7110_MCLK>,
+ <&mclk_ext>,
<&i2srx_bclk_ext>,
<&i2srx_lrck_ext>;
clock-names = "apb0", "3ch-apb",
"audioroot", "mclk-inner",
"bclk_mst", "3ch-lrck",
"rx-bclk", "rx-lrck",
- "mclk", "bclk-ext",
- "lrck-ext";
+ "mclk", "mclk_ext",
+ "bclk-ext", "lrck-ext";
resets = <&rstgen RSTN_U0_I2SRX_3CH_APB>,
<&rstgen RSTN_U0_I2SRX_3CH_BCLK>;
dmas = <&dma 24 1>;
return ret;
}
+ if (dw_dev->rst_i2s_apb) {
+ ret = reset_control_deassert(dw_dev->rst_i2s_apb);
+ if (ret)
+ return ret;
+ }
+ if (dw_dev->rst_i2s_bclk) {
+ ret = reset_control_deassert(dw_dev->rst_i2s_bclk);
+ if (ret)
+ return ret;
+ }
+
return 0;
}
int stream;
int ret;
+ if (!dev->is_master) {
+ ret = clk_set_parent(dev->clk_i2s_bclk, dev->clk_i2s_bclk_mst);
+ if (ret) {
+ dev_err(dev->dev, "%s: failed to set clk_i2s_bclk parent to bclk_mst.\n",
+ __func__);
+ goto exit;
+ }
+
+ ret = clk_set_parent(dev->clk_i2s_lrck, dev->clk_i2s_lrck_mst);
+ if (ret) {
+ dev_err(dev->dev, "%s: failed to set clk_i2s_lrck parent to lrck_mst.\n",
+ __func__);
+ goto exit;
+ }
+ }
+
ret = pm_runtime_force_resume(component->dev);
if (ret)
return ret;
+ if (dev->syscon_base) {
+ if (dev->is_master) {
+ /* config i2s data source: PDM */
+ regmap_update_bits(dev->syscon_base, dev->syscon_offset_34,
+ AUDIO_SDIN_MUX_MASK, I2SRX_DATA_SRC_PDM);
+
+ regmap_update_bits(dev->syscon_base, dev->syscon_offset_18,
+ I2SRX_3CH_ADC_MASK, I2SRX_3CH_ADC_EN);
+ } else {
+ /*i2srx_3ch_adc_enable*/
+ regmap_update_bits(dev->syscon_base, dev->syscon_offset_18,
+ 0x1 << 1, 0x1 << 1);
+
+ /*set i2sdin_sel*/
+ regmap_update_bits(dev->syscon_base, dev->syscon_offset_34,
+ (0x1 << 10) | (0x1 << 14) | (0x1<<17), (0x0<<10) | (0x0<<14) | (0x0<<17));
+ }
+ }
+
for_each_component_dais(component, dai) {
for_each_pcm_streams(stream)
if (snd_soc_dai_stream_active(dai, stream))
dw_i2s_config(dev, stream);
}
+ i2s_write_reg(dev->i2s_base, CCR, dev->ccr);
+
+ if (!dev->is_master) {
+ ret = clk_set_parent(dev->clk_mclk, dev->clk_mclk_ext);
+ if (ret) {
+ dev_err(dev->dev, "failed to set mclk parent to mclk_ext\n");
+ goto exit;
+ }
+
+ ret = clk_set_parent(dev->clk_i2s_bclk, dev->clk_bclk_ext);
+ if (ret) {
+ dev_err(dev->dev, "%s: failed to set clk_i2s_bclk parent to bclk_ext.\n",
+ __func__);
+ goto exit;
+ }
+
+ ret = clk_set_parent(dev->clk_i2s_lrck, dev->clk_lrck_ext);
+ if (ret) {
+ dev_err(dev->dev, "%s: failed to set clk_i2s_lrck parent to lrck_ext.\n",
+ __func__);
+ goto exit;
+ }
+ }
+
return 0;
+
+exit:
+ return ret;
}
#else
{ .id = "i2srx_lrck_mst" },
{ .id = "i2srx_bclk" },
{ .id = "i2srx_lrck" },
+ { .id = "mclk" },
+ { .id = "mclk_ext" },
};
ret = devm_clk_bulk_get(&pdev->dev, ARRAY_SIZE(clks), clks);
dev->clk_i2s_lrck_mst = clks[2].clk;
dev->clk_i2s_bclk = clks[3].clk;
dev->clk_i2s_lrck = clks[4].clk;
+ dev->clk_mclk = clks[5].clk;
+ dev->clk_mclk_ext = clks[6].clk;
dev->rst_i2s_apb = devm_reset_control_get_exclusive(&pdev->dev, "rst_apb_rx");
if (IS_ERR(dev->rst_i2s_apb)) {
goto exit;
}
- reset_control_assert(dev->rst_i2s_apb);
- reset_control_assert(dev->rst_i2s_bclk);
-
ret = clk_prepare_enable(dev->clk_i2s_apb);
if (ret) {
dev_err(&pdev->dev, "failed to prepare enable clk_i2srx_apb\n");
goto exit;
}
+ ret = clk_set_parent(dev->clk_i2s_bclk, dev->clk_i2s_bclk_mst);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to set parent clk_i2s_bclk\n");
+ goto err_dis_bclk_mst;
+ }
+
+ ret = clk_set_parent(dev->clk_i2s_lrck, dev->clk_i2s_lrck_mst);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to set parent clk_i2s_lrck\n");
+ goto err_dis_bclk_mst;
+ }
+
+ ret = clk_set_parent(dev->clk_mclk, dev->clk_mclk_ext);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to set mclk parent to mclk_ext\n");
+ goto err_dis_bclk_mst;
+ }
+
ret = clk_prepare_enable(dev->clk_i2s_bclk_mst);
if (ret) {
dev_err(&pdev->dev, "failed to prepare enable clk_i2srx_3ch_bclk_mst\n");
regmap_update_bits(dev->syscon_base, dev->syscon_offset_18,
I2SRX_3CH_ADC_MASK, I2SRX_3CH_ADC_EN);
+
return 0;
err_dis_bclk_mst:
{ .id = "rx-lrck" },
{ .id = "bclk-ext" },
{ .id = "lrck-ext" },
+ { .id = "mclk" },
+ { .id = "mclk_ext" },
};
ret = devm_clk_bulk_get(&pdev->dev, ARRAY_SIZE(clks), clks);
dev->clk_i2s_lrck = clks[4].clk;
dev->clk_bclk_ext = clks[5].clk;
dev->clk_lrck_ext = clks[6].clk;
+ dev->clk_mclk = clks[7].clk;
+ dev->clk_mclk_ext = clks[8].clk;
+
+ ret = clk_set_parent(dev->clk_i2s_bclk, dev->clk_i2s_bclk_mst);
+ if (ret) {
+ dev_err(&pdev->dev, "%s: failed to set clk_i2s_bclk parent to bclk_mst.\n",
+ __func__);
+ goto exit;
+ }
+
+ ret = clk_set_parent(dev->clk_i2s_lrck, dev->clk_i2s_lrck_mst);
+ if (ret) {
+ dev_err(&pdev->dev, "%s: failed to set clk_i2s_lrck parent to lrck_mst.\n",
+ __func__);
+ goto exit;
+ }
ret = clk_prepare_enable(dev->clk_i2s_apb);
if (ret) {
regmap_update_bits(dev->syscon_base, dev->syscon_offset_34,
(0x1 << 10) | (0x1 << 14) | (0x1<<17), (0x0<<10) | (0x0<<14) | (0x0<<17));
+
+ ret = clk_set_parent(dev->clk_mclk, dev->clk_mclk_ext);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to set mclk parent to mclk_ext\n");
+ goto disable_parent;
+ }
+
ret = clk_set_parent(dev->clk_i2s_bclk, dev->clk_bclk_ext);
if (ret) {
dev_err(&pdev->dev, "%s: failed to set clk_i2s_bclk parent to bclk_ext.\n",
disable_bclk:
clk_disable_unprepare(dev->clk_i2s_apb);
disable_apb_clk:
+exit:
return ret;
}
dev->clk_bclk_ext = clks[7].clk;
dev->clk_lrck_ext = clks[8].clk;
+ ret = clk_set_parent(dev->clk_i2s_bclk, dev->clk_i2s_bclk_mst);
+ if (ret) {
+ dev_err(&pdev->dev, "%s: failed to set clk_i2s_bclk parent to bclk_mst.\n",
+ __func__);
+ goto exit;
+ }
+
+ ret = clk_set_parent(dev->clk_i2s_lrck, dev->clk_i2s_lrck_mst);
+ if (ret) {
+ dev_err(&pdev->dev, "%s: failed to set clk_i2s_lrck parent to lrck_mst.\n",
+ __func__);
+ goto exit;
+ }
+
ret = clk_prepare_enable(dev->clk_i2s_apb);
if (ret) {
dev_err(&pdev->dev, "%s: failed to enable clk_i2s_apb\n", __func__);
dev_err(&pdev->dev, "%s: failed to reset control assert rsts\n", __func__);
goto disable_rst;
}
-
+ udelay(5);
ret = reset_control_deassert(dev->rst_i2s_apb);
if (ret) {
dev_err(&pdev->dev, "%s: failed to reset control deassert rsts\n", __func__);
goto disable_rst;
}
+ ret = clk_set_parent(dev->clk_mclk, dev->clk_mclk_ext);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to set mclk parent to mclk_ext\n");
+ goto exit;
+ }
+
ret = clk_set_parent(dev->clk_i2s_bclk, dev->clk_bclk_ext);
if (ret) {
dev_err(&pdev->dev, "%s: failed to set clk_i2s_bclk parent to bclk_ext.\n",
static int dw_i2s_remove(struct platform_device *pdev)
{
+#ifndef CONFIG_PM
struct dw_i2s_dev *dev = dev_get_drvdata(&pdev->dev);
clk_disable_unprepare(dev->clk_i2s_bclk_mst);
clk_disable_unprepare(dev->clk_i2s_apb);
+#endif
pm_runtime_disable(&pdev->dev);
return 0;