+static int dw_i2srx_clk_init(struct platform_device *pdev, struct dw_i2s_dev *dev)
+{
+ int ret = 0;
+
+ static struct clk_bulk_data clks[] = {
+ { .id = "apb0" }, //clock-names in dts file
+ { .id = "3ch-apb" },
+ { .id = "3ch-bclk" },
+ };
+
+ ret = devm_clk_bulk_get(&pdev->dev, ARRAY_SIZE(clks), clks);
+ if (ret) {
+ dev_err(&pdev->dev,"%s: failed to get audio_subsys clocks\n", __func__);
+ goto err_out_clock;
+ }
+ dev->clks[CLK_ADC_APB0] = clks[0].clk;
+ dev->clks[CLK_ADC_APB] = clks[1].clk;
+ dev->clks[CLK_ADC_LRCLK] = clks[2].clk;
+
+ ret = clk_prepare_enable(dev->clks[CLK_ADC_APB0]);
+ if (ret) {
+ dev_err(&pdev->dev, "%s: failed to enable CLK_ADC_APB0\n", __func__);
+ goto err_out_clock;
+ }
+
+ ret = clk_prepare_enable(dev->clks[CLK_ADC_APB]);
+ if (ret) {
+ dev_err(&pdev->dev, "%s: failed to enable CLK_ADC_APB\n", __func__);
+ goto err_out_clock;
+ }
+
+ ret = clk_prepare_enable(dev->clks[CLK_ADC_LRCLK]);
+ if (ret) {
+ dev_err(&pdev->dev, "%s: failed to enable CLK_ADC_LRCLK\n", __func__);
+ goto err_out_clock;
+ }
+
+ dev->rstc[RST_APB_RX] = devm_reset_control_get_exclusive(&pdev->dev, rst_name[RST_APB_RX]);
+ if (IS_ERR(dev->rstc[RST_APB_RX])) {
+ dev_err(&pdev->dev, "%s: failed to get apb_i2srx reset control,ret = %d\n", __func__);
+ return PTR_ERR(dev->rstc[RST_APB_RX]);
+ }
+
+ dev->rstc[RST_BCLK_RX] = devm_reset_control_get_exclusive(&pdev->dev, rst_name[RST_BCLK_RX]);
+ if (IS_ERR(dev->rstc[RST_BCLK_RX])) {
+ dev_err(&pdev->dev, "%s: failed to get i2s bclk rx reset control,ret = %d\n", __func__);
+ return PTR_ERR(dev->rstc[RST_BCLK_RX]);
+ }
+
+ reset_control_deassert(dev->rstc[RST_APB_RX]);
+ reset_control_deassert(dev->rstc[RST_BCLK_RX]);
+
+
+ return 0;
+
+err_out_clock:
+ return ret;
+}
+
+static int dw_i2stx_4ch0_clk_init(struct platform_device *pdev, struct dw_i2s_dev *dev)
+{
+ static struct clk_bulk_data i2sclk[] = {
+ { .id = "inner" }, //clock-names in dts file
+ { .id = "bclk-mst" },
+ { .id = "lrck-mst" },
+ { .id = "mclk" },
+ { .id = "bclk0" },
+ { .id = "lrck0" },
+ };
+
+ int ret = 0;
+
+ ret = devm_clk_bulk_get(&pdev->dev, ARRAY_SIZE(i2sclk), i2sclk);
+ if (ret) {
+ printk(KERN_INFO "%s: failed to get i2stx 4ch0 clocks\n", __func__);
+ return ret;
+ }
+
+ dev->clks[CLK_DAC_INNER] = i2sclk[0].clk;
+ dev->clks[CLK_DAC_BCLK_MST] = i2sclk[1].clk;
+ dev->clks[CLK_DAC_LRCLK_MST] = i2sclk[2].clk;
+ dev->clks[CLK_MCLK] = i2sclk[3].clk;
+ dev->clks[CLK_DAC_BCLK0] = i2sclk[4].clk;
+ dev->clks[CLK_DAC_LRCLK0] = i2sclk[5].clk;
+
+ ret = clk_prepare_enable(dev->clks[CLK_DAC_INNER]);
+ if (ret) {
+ dev_err(&pdev->dev, "%s: failed to enable CLK_DAC_INNER\n", __func__);
+ goto err_clk_i2s;
+ }
+
+ ret = clk_prepare_enable(dev->clks[CLK_DAC_BCLK_MST]);
+ if (ret) {
+ dev_err(&pdev->dev, "%s: failed to enable CLK_DAC_BCLK_MST\n", __func__);
+ goto err_clk_i2s;
+ }
+
+ ret = clk_prepare_enable(dev->clks[CLK_DAC_LRCLK_MST]);
+ if (ret) {
+ dev_err(&pdev->dev, "%s: failed to enable CLK_DAC_LRCLK_MST\n", __func__);
+ goto err_clk_i2s;
+ }
+
+ ret = clk_prepare_enable(dev->clks[CLK_MCLK]);
+ if (ret) {
+ dev_err(&pdev->dev, "%s: failed to enable CLK_MCLK\n", __func__);
+ goto err_clk_i2s;
+ }
+
+ ret = clk_prepare_enable(dev->clks[CLK_DAC_BCLK0]);
+ if (ret) {
+ dev_err(&pdev->dev, "%s: failed to enable CLK_DAC_BCLK0\n", __func__);
+ goto err_clk_i2s;
+ }
+
+ ret = clk_prepare_enable(dev->clks[CLK_DAC_LRCLK0]);
+ if (ret) {
+ dev_err(&pdev->dev, "%s: failed to enable CLK_DAC_LRCLK0\n", __func__);
+ goto err_clk_i2s;
+ }
+
+ dev->rstc[RST_APB0_BUS] = devm_reset_control_get_exclusive(&pdev->dev, rst_name[RST_APB0_BUS]);
+ if (IS_ERR(dev->rstc[RST_APB0_BUS])) {
+ dev_err(&pdev->dev, "%s: failed to get apb_i2stx reset control, ret = %d\n", __func__);
+ return PTR_ERR(dev->rstc[RST_APB0_BUS]);
+ }
+
+ dev->rstc[RST_BCLK_0] = devm_reset_control_get_exclusive(&pdev->dev, rst_name[RST_BCLK_0]);
+ if (IS_ERR(dev->rstc[RST_BCLK_0])) {
+ dev_err(&pdev->dev, "%s: failed to get i2s bclk0 reset control, ret = %d\n", __func__);
+ return PTR_ERR(dev->rstc[RST_BCLK_0]);
+ }
+
+ reset_control_deassert(dev->rstc[RST_APB0_BUS]);
+ reset_control_deassert(dev->rstc[RST_BCLK_0]);
+
+err_clk_i2s:
+ return ret;
+}
+
+static int dw_i2stx_4ch1_clk_init(struct platform_device *pdev, struct dw_i2s_dev *dev)
+{
+ static struct clk_bulk_data i2sclk[] = {
+ { .id = "inner" }, //clock-names in dts file
+ { .id = "bclk-mst1" },
+ { .id = "lrck-mst1" },
+ { .id = "mclk" },
+ { .id = "bclk1" },
+ { .id = "lrck1" },
+ };
+
+ int ret = 0;
+
+ ret = devm_clk_bulk_get(&pdev->dev, ARRAY_SIZE(i2sclk), i2sclk);
+ if (ret) {
+ dev_err(&pdev->dev, "%s: failed to get i2stx 4ch0 clocks\n", __func__);
+ return ret;
+ }
+
+ dev->clks[CLK_DAC_INNER] = i2sclk[0].clk;
+ dev->clks[CLK_DAC_BCLK_MST_1] = i2sclk[1].clk;
+ dev->clks[CLK_DAC_LRCLK_MST_1] = i2sclk[2].clk;
+ dev->clks[CLK_MCLK] = i2sclk[3].clk;
+ dev->clks[CLK_DAC_BCLK_1] = i2sclk[4].clk;
+ dev->clks[CLK_DAC_LRCLK_1] = i2sclk[5].clk;
+
+ ret = clk_prepare_enable(dev->clks[CLK_DAC_INNER]);
+ if (ret) {
+ dev_err(&pdev->dev, "%s: failed to enable CLK_DAC_INNER\n", __func__);
+ goto err_clk_i2s;
+ }
+
+ ret = clk_prepare_enable(dev->clks[CLK_DAC_BCLK_MST_1]);
+ if (ret) {
+ dev_err(&pdev->dev, "%s: failed to enable CLK_DAC_BCLK_MST_1\n", __func__);
+ goto err_clk_i2s;
+ }
+
+ ret = clk_prepare_enable(dev->clks[CLK_DAC_LRCLK_MST_1]);
+ if (ret) {
+ dev_err(&pdev->dev, "%s: failed to enable CLK_DAC_LRCLK_MST_1\n", __func__);
+ goto err_clk_i2s;
+ }
+
+ ret = clk_prepare_enable(dev->clks[CLK_MCLK]);
+ if (ret) {
+ dev_err(&pdev->dev, "%s: failed to enable CLK_MCLK\n", __func__);
+ goto err_clk_i2s;
+ }
+
+ ret = clk_prepare_enable(dev->clks[CLK_DAC_BCLK_1]);
+ if (ret) {
+ dev_err(&pdev->dev, "%s: failed to enable CLK_DAC_BCLK_1\n", __func__);
+ goto err_clk_i2s;
+ }
+
+ ret = clk_prepare_enable(dev->clks[CLK_DAC_LRCLK_1]);
+ if (ret) {
+ dev_err(&pdev->dev, "%s: failed to enable CLK_DAC_LRCLK_1\n", __func__);
+ goto err_clk_i2s;
+ }
+ dev_dbg(&pdev->dev, "dev->clks[CLK_DAC_INNER] = %lu \n", clk_get_rate(dev->clks[CLK_DAC_INNER]));
+ dev_dbg(&pdev->dev, "dev->clks[CLK_DAC_BCLK_MST_1] = %lu \n", clk_get_rate(dev->clks[CLK_DAC_BCLK_MST_1]));
+ dev_dbg(&pdev->dev, "dev->clks[CLK_DAC_LRCLK_MST_1] = %lu \n", clk_get_rate(dev->clks[CLK_DAC_LRCLK_MST_1]));
+ dev_dbg(&pdev->dev, "dev->clks[CLK_MCLK] = %lu \n", clk_get_rate(dev->clks[CLK_MCLK]));
+ dev_dbg(&pdev->dev, "dev->clks[CLK_DAC_BCLK_1] = %lu \n", clk_get_rate(dev->clks[CLK_DAC_BCLK_1]));
+ dev_dbg(&pdev->dev, "dev->clks[CLK_DAC_LRCLK_1] = %lu \n", clk_get_rate(dev->clks[CLK_DAC_LRCLK_1]));
+
+ dev->rstc[RST_APB1_BUS] = devm_reset_control_get_exclusive(&pdev->dev, rst_name[RST_APB1_BUS]);
+ if (IS_ERR(dev->rstc[RST_APB1_BUS])) {
+ dev_err(&pdev->dev, "%s: failed to get apb_i2stx reset control, ret = %d\n", __func__);
+ return PTR_ERR(dev->rstc[RST_APB1_BUS]);
+ }
+
+ dev->rstc[RST_BCLK_1] = devm_reset_control_get_exclusive(&pdev->dev, rst_name[RST_BCLK_1]);
+ if (IS_ERR(dev->rstc[RST_BCLK_1])) {
+ dev_err(&pdev->dev, "%s: failed to get i2s bclk1 reset control, ret = %d\n", __func__);
+ return PTR_ERR(dev->rstc[RST_BCLK_1]);
+ }
+
+ reset_control_assert(dev->rstc[RST_APB1_BUS]);
+ reset_control_assert(dev->rstc[RST_BCLK_1]);
+
+ udelay(5);
+
+ reset_control_deassert(dev->rstc[RST_APB1_BUS]);
+ reset_control_deassert(dev->rstc[RST_BCLK_1]);
+
+err_clk_i2s:
+ return ret;
+}
+