From ab9c608c8f4e41a4115bc5d90ae11b837be9ac5b Mon Sep 17 00:00:00 2001 From: "walker.chen" Date: Wed, 1 Jun 2022 02:24:19 -0400 Subject: [PATCH] Add PDM driver for JH7110 SoC Signed-off-by: Walker Chen --- arch/riscv/boot/dts/starfive/jh7110-common.dtsi | 2 +- arch/riscv/boot/dts/starfive/jh7110.dtsi | 44 ++- arch/riscv/boot/dts/starfive/jh7110_pinctrl.dtsi | 18 +- arch/riscv/configs/starfive_jh7110_defconfig | 3 + sound/soc/dwc/Kconfig | 0 sound/soc/dwc/dwc-i2s.c | 351 ++++++++--------------- sound/soc/dwc/local.h | 47 ++- sound/soc/starfive/starfive_pdm.c | 313 +++++++++----------- sound/soc/starfive/starfive_pdm.h | 38 ++- 9 files changed, 319 insertions(+), 497 deletions(-) mode change 100755 => 100644 sound/soc/dwc/Kconfig mode change 100755 => 100644 sound/soc/dwc/dwc-i2s.c mode change 100755 => 100644 sound/soc/dwc/local.h diff --git a/arch/riscv/boot/dts/starfive/jh7110-common.dtsi b/arch/riscv/boot/dts/starfive/jh7110-common.dtsi index 0298016..32d2e29 100755 --- a/arch/riscv/boot/dts/starfive/jh7110-common.dtsi +++ b/arch/riscv/boot/dts/starfive/jh7110-common.dtsi @@ -448,7 +448,7 @@ &i2srx_3ch { pinctrl-names = "default"; - pinctrl-0 = <&i2srx_pins>; + pinctrl-0 = <&i2s_clk_pins>; status = "okay"; }; diff --git a/arch/riscv/boot/dts/starfive/jh7110.dtsi b/arch/riscv/boot/dts/starfive/jh7110.dtsi index f75a110..5227d60 100755 --- a/arch/riscv/boot/dts/starfive/jh7110.dtsi +++ b/arch/riscv/boot/dts/starfive/jh7110.dtsi @@ -1090,15 +1090,12 @@ clocks = <&clkgen JH7110_PDM_CLK_DMIC>, <&clkgen JH7110_APB0>, <&clkgen JH7110_PDM_CLK_APB>, - <&clkgen JH7110_PDM_CLK_DMIC0_BCLK_SLV>, - <&clkgen JH7110_PDM_CLK_DMIC0_LRCK_SLV>, - <&clkgen JH7110_PDM_CLK_DMIC1_BCLK_SLV>, - <&clkgen JH7110_PDM_CLK_DMIC1_LRCK_SLV>, - <&clkgen JH7110_I2SRX0_3CH_BCLK>; - clock-names = "pdm_dmic", "clk_apb0", "pdm_apb", - "pdm_dmic0_bclk", "pdm_dmic0_lrck", - "pdm_dmic1_bclk", "pdm_dmic1_lrck", - "u0_i2srx_3ch_bclk"; + <&clkgen JH7110_MCLK_INNER>, + <&clkgen JH7110_MCLK>, + <&clkgen JH7110_MCLK_OUT>; + clock-names = "pdm_mclk", "clk_apb0", + "pdm_apb", "mclk_inner", + "clk_mclk", "mclk_out"; resets = <&rstgen RSTN_U0_PDM_4MIC_DMIC>, <&rstgen RSTN_U0_PDM_4MIC_APB>; reset-names = "pdm_dmic", "pdm_apb"; @@ -1110,16 +1107,19 @@ reg = <0x0 0x100e0000 0x0 0x1000>; clocks = <&clkgen JH7110_APB0>, <&clkgen JH7110_I2SRX0_3CH_CLK_APB>, - <&clkgen JH7110_I2SRX_3CH_BCLK_MST>; - clock-names = "apb0", "3ch-apb", - "3ch-bclk"; + <&clkgen JH7110_I2SRX_3CH_BCLK_MST>, + <&clkgen JH7110_I2SRX_3CH_LRCK_MST>, + <&clkgen JH7110_I2SRX0_3CH_BCLK>, + <&clkgen JH7110_I2SRX0_3CH_LRCK>; + clock-names = "apb0", "i2srx_apb", + "i2srx_bclk_mst", "i2srx_lrck_mst", + "i2srx_bclk", "i2srx_lrck"; resets = <&rstgen RSTN_U0_I2SRX_3CH_APB>, <&rstgen RSTN_U0_I2SRX_3CH_BCLK>; reset-names = "rst_apb_rx", "rst_bclk_rx"; - interrupts = <42>; - interrupt-names = "rx"; dmas = <&dma 24 1>; dma-names = "rx"; + starfive,sys-syscon = <&sys_syscon 0x18 0x34>; #sound-dai-cells = <0>; status = "disabled"; }; @@ -1583,6 +1583,22 @@ sound-dai = <&pwmdac_codec>; }; }; + + simple-audio-card,dai-link@1 { + reg = <0>; + status = "okay"; + format = "i2s"; + bitclock-master = <&dailink_master>; + frame-master = <&dailink_master>; + + dailink_master:cpu { + sound-dai = <&i2srx_3ch>; + }; + + dailink_slave:codec { + sound-dai = <&pdm>; + }; + }; }; co_process: e24@0 { diff --git a/arch/riscv/boot/dts/starfive/jh7110_pinctrl.dtsi b/arch/riscv/boot/dts/starfive/jh7110_pinctrl.dtsi index 5bba503..711aa30 100755 --- a/arch/riscv/boot/dts/starfive/jh7110_pinctrl.dtsi +++ b/arch/riscv/boot/dts/starfive/jh7110_pinctrl.dtsi @@ -361,22 +361,6 @@ sf,pin-gpio-dout = ; sf,pin-gpio-doen = ; }; - - i2s-clk0_bclk { - sf,pins = ; - sf,pinmux = ; - sf,pin-ioconfig = ; - sf,pin-gpio-dout = ; - sf,pin-gpio-doen = ; - }; - - i2s-clk0_lrclk { - sf,pins = ; - sf,pinmux = ; - sf,pin-ioconfig = ; - sf,pin-gpio-dout = ; - sf,pin-gpio-doen = ; - }; }; i2stx_pins: i2stx-pins { @@ -837,11 +821,13 @@ sf,pinmux = ; sf,pin-ioconfig = ; }; +/* rgb-6-pins { sf,pins = ; sf,pinmux = ; sf,pin-ioconfig = ; }; +*/ rgb-7-pins { sf,pins = ; sf,pinmux = ; diff --git a/arch/riscv/configs/starfive_jh7110_defconfig b/arch/riscv/configs/starfive_jh7110_defconfig index d53c691..505c0d6 100644 --- a/arch/riscv/configs/starfive_jh7110_defconfig +++ b/arch/riscv/configs/starfive_jh7110_defconfig @@ -189,7 +189,10 @@ CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_SOUND=y CONFIG_SND=y CONFIG_SND_SOC=y +CONFIG_SND_DESIGNWARE_I2S=y +CONFIG_SND_DESIGNWARE_I2S_STARFIVE_JH7110=y CONFIG_SND_STARFIVE_PWMDAC=y +CONFIG_SND_STARFIVE_PDM=y CONFIG_SND_SIMPLE_CARD=y CONFIG_USB=y CONFIG_USB_XHCI_HCD=y diff --git a/sound/soc/dwc/Kconfig b/sound/soc/dwc/Kconfig old mode 100755 new mode 100644 diff --git a/sound/soc/dwc/dwc-i2s.c b/sound/soc/dwc/dwc-i2s.c old mode 100755 new mode 100644 index 30b2e4c..76ff62d --- a/sound/soc/dwc/dwc-i2s.c +++ b/sound/soc/dwc/dwc-i2s.c @@ -24,18 +24,11 @@ #include #include #include +#include +#include #include #include "local.h" -static const char * const rst_name[RST_AUDIO_NUM] = { - [RST_APB0_BUS] = "rst_apb0", - [RST_BCLK_0] = "rst_bclk0", - [RST_APB1_BUS] = "rst_apb1", - [RST_BCLK_1] = "rst_bclk1", - [RST_APB_RX] = "rst_apb_rx", - [RST_BCLK_RX] = "rst_bclk_rx", -}; - static inline void i2s_write_reg(void __iomem *io_base, int reg, u32 val) { writel(val, io_base + reg); @@ -173,6 +166,7 @@ static void i2s_start(struct dw_i2s_dev *dev, i2s_write_reg(dev->i2s_base, IRER, 1); i2s_write_reg(dev->i2s_base, CER, 1); + } static void i2s_stop(struct dw_i2s_dev *dev, @@ -252,6 +246,7 @@ static int dw_i2s_hw_params(struct snd_pcm_substream *substream, struct dw_i2s_dev *dev = snd_soc_dai_get_drvdata(dai); struct i2s_clk_config_data *config = &dev->config; int ret; + unsigned int bclk_rate; switch (params_format(params)) { case SNDRV_PCM_FORMAT_S16_LE: @@ -277,6 +272,19 @@ static int dw_i2s_hw_params(struct snd_pcm_substream *substream, return -EINVAL; } + switch (params_rate(params)) { + case 8000: + bclk_rate = 512000; + break; + case 16000: + bclk_rate = 1024000; + break; + default: + dev_err(dai->dev, "%d rate not supported\n", + params_rate(params)); + return -EINVAL; + } + config->chan_nr = params_channels(params); switch (config->chan_nr) { @@ -296,6 +304,7 @@ static int dw_i2s_hw_params(struct snd_pcm_substream *substream, config->sample_rate = params_rate(params); + if (dev->capability & DW_I2S_MASTER) { if (dev->i2s_clk_cfg) { ret = dev->i2s_clk_cfg(config); @@ -304,13 +313,9 @@ static int dw_i2s_hw_params(struct snd_pcm_substream *substream, return ret; } } else { - u32 bitclk = config->sample_rate * - config->data_width * 2; - - ret = clk_set_rate(dev->clk, bitclk); + ret = clk_set_rate(dev->clk_i2srx_bclk_mst, bclk_rate); if (ret) { - dev_err(dev->dev, "Can't set I2S clock rate: %d\n", - ret); + dev_err(dev->dev, "Can't set i2s bclk: %d\n", ret); return ret; } } @@ -467,230 +472,98 @@ static int dw_i2srx_clk_init(struct platform_device *pdev, struct dw_i2s_dev *de int ret = 0; static struct clk_bulk_data clks[] = { - { .id = "apb0" }, //clock-names in dts file - { .id = "3ch-apb" }, - { .id = "3ch-bclk" }, + { .id = "apb0" }, + { .id = "i2srx_apb" }, + { .id = "i2srx_bclk_mst" }, + { .id = "i2srx_lrck_mst" }, + { .id = "i2srx_bclk" }, + { .id = "i2srx_lrck" }, }; 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_err(&pdev->dev, "%s: failed to get i2srx clocks\n", __func__); + goto exit; } - 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->clk_apb0 = clks[0].clk; + dev->clk_i2srx_apb = clks[1].clk; + dev->clk_i2srx_bclk_mst = clks[2].clk; + dev->clk_i2srx_lrck_mst = clks[3].clk; + dev->clk_i2srx_bclk = clks[4].clk; + dev->clk_i2srx_lrck = clks[5].clk; - 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->rst_i2srx_apb = devm_reset_control_get_exclusive(&pdev->dev, "rst_apb_rx"); + if (IS_ERR(dev->rst_i2srx_apb)) { + dev_err(&pdev->dev, "failed to get apb_i2srx reset control\n"); + ret = PTR_ERR(dev->rst_i2srx_apb); + goto exit; } - 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]); + dev->rst_i2srx_bclk = devm_reset_control_get_exclusive(&pdev->dev, "rst_bclk_rx"); + if (IS_ERR(dev->rst_i2srx_bclk)) { + dev_err(&pdev->dev, "failed to get i2s bclk rx reset control\n"); + ret = PTR_ERR(dev->rst_i2srx_bclk); + goto exit; } - reset_control_deassert(dev->rstc[RST_APB_RX]); - reset_control_deassert(dev->rstc[RST_BCLK_RX]); - - - return 0; + reset_control_assert(dev->rst_i2srx_apb); + reset_control_assert(dev->rst_i2srx_bclk); -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); + ret = clk_prepare_enable(dev->clk_apb0); 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; + dev_err(&pdev->dev, "failed to prepare enable clk_apb0\n"); + goto exit; } - ret = clk_prepare_enable(dev->clks[CLK_DAC_BCLK_MST]); + ret = clk_prepare_enable(dev->clk_i2srx_apb); if (ret) { - dev_err(&pdev->dev, "%s: failed to enable CLK_DAC_BCLK_MST\n", __func__); - goto err_clk_i2s; + dev_err(&pdev->dev, "failed to prepare enable clk_i2srx_apb\n"); + goto err_dis_i2srx_apb; } - ret = clk_prepare_enable(dev->clks[CLK_DAC_LRCLK_MST]); + ret = clk_prepare_enable(dev->clk_i2srx_bclk_mst); if (ret) { - dev_err(&pdev->dev, "%s: failed to enable CLK_DAC_LRCLK_MST\n", __func__); - goto err_clk_i2s; + dev_err(&pdev->dev, "failed to prepare enable clk_i2srx_3ch_bclk_mst\n"); + goto err_dis_bclk_mst; } - ret = clk_prepare_enable(dev->clks[CLK_MCLK]); + ret = clk_prepare_enable(dev->clk_i2srx_lrck_mst); if (ret) { - dev_err(&pdev->dev, "%s: failed to enable CLK_MCLK\n", __func__); - goto err_clk_i2s; + dev_err(&pdev->dev, "failed to prepare enable clk_i2srx_3ch_lrck_mst\n"); + goto err_dis_lrck_mst; } - ret = clk_prepare_enable(dev->clks[CLK_DAC_BCLK0]); + ret = clk_prepare_enable(dev->clk_i2srx_bclk); if (ret) { - dev_err(&pdev->dev, "%s: failed to enable CLK_DAC_BCLK0\n", __func__); - goto err_clk_i2s; + dev_err(&pdev->dev, "failed to prepare enable clk_i2srx_3ch_bclk\n"); + goto err_dis_bclk; } - ret = clk_prepare_enable(dev->clks[CLK_DAC_LRCLK0]); + ret = clk_prepare_enable(dev->clk_i2srx_lrck); 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]); + dev_err(&pdev->dev, "failed to prepare enable clk_i2srx_3ch_lrck\n"); + goto err_dis_lrck; } - 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; + reset_control_deassert(dev->rst_i2srx_apb); + reset_control_deassert(dev->rst_i2srx_bclk); - 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]); + regmap_update_bits(dev->syscon_base, dev->syscon_offset_18, + I2SRX_3CH_ADC_MASK, I2SRX_3CH_ADC_EN); + return 0; -err_clk_i2s: +err_dis_i2srx_apb: + clk_disable_unprepare(dev->clk_apb0); +err_dis_bclk_mst: + clk_disable_unprepare(dev->clk_i2srx_apb); +err_dis_lrck_mst: + clk_disable_unprepare(dev->clk_i2srx_bclk_mst); +err_dis_bclk: + clk_disable_unprepare(dev->clk_i2srx_lrck_mst); +err_dis_lrck: + clk_disable_unprepare(dev->clk_i2srx_bclk); +exit: return ret; } @@ -772,18 +645,12 @@ static int dw_configure_dai(struct dw_i2s_dev *dev, dw_i2s_dai->capture.channels_min = MIN_CHANNEL_NUM; dw_i2s_dai->capture.channels_max = 1 << (COMP1_RX_CHANNELS(comp1) + 1); - dw_i2s_dai->capture.formats = formats[idx]; + dw_i2s_dai->capture.formats = SNDRV_PCM_FMTBIT_S16_LE; dw_i2s_dai->capture.rates = rates; } - if (COMP1_MODE_EN(comp1)) { - dev_dbg(dev->dev, "designware: i2s master mode supported\n"); - dev->capability |= DW_I2S_MASTER; - } else { - dev_dbg(dev->dev, "designware: i2s slave mode supported\n"); - dev->capability |= DW_I2S_SLAVE; - } - + dev_dbg(dev->dev, "designware: i2s master mode supported\n"); + dev->capability |= DW_I2S_MASTER; dev->fifo_th = fifo_depth / 2; return 0; } @@ -852,6 +719,9 @@ static int dw_configure_dai_by_dt(struct dw_i2s_dev *dev, if (COMP1_RX_ENABLED(comp1)) { idx2 = COMP2_RX_WORDSIZE_0(comp2); + /* force change to 1 */ + idx = 1; + idx2 = 1; dev->capability |= DWC_I2S_RECORD; dev->capture_dma_data.dt.addr = res->start + I2S_RXDMA; dev->capture_dma_data.dt.addr_width = bus_widths[idx]; @@ -878,6 +748,7 @@ static int dw_i2s_probe(struct platform_device *pdev) { const struct i2s_platform_data *pdata = pdev->dev.platform_data; struct device_node *np = pdev->dev.of_node; + struct of_phandle_args args; struct dw_i2s_dev *dev; struct resource *res; int ret, irq; @@ -892,6 +763,7 @@ static int dw_i2s_probe(struct platform_device *pdev) if (!dw_i2s_dai) return -ENOMEM; + dw_i2s_dai->ops = &dw_i2s_dai_ops; #ifdef CONFIG_SND_DESIGNWARE_I2S_STARFIVE_JH7110 dw_i2s_dai->probe = dw_i2s_dai_probe; @@ -903,6 +775,21 @@ static int dw_i2s_probe(struct platform_device *pdev) dev->dev = &pdev->dev; + ret = of_parse_phandle_with_fixed_args(dev->dev->of_node, + "starfive,sys-syscon", 2, 0, &args); + if (ret) { + dev_err(dev->dev, "Failed to parse starfive,sys-syscon\n"); + return -EINVAL; + } + + dev->syscon_base = syscon_node_to_regmap(args.np); + of_node_put(args.np); + if (IS_ERR(dev->syscon_base)) + return PTR_ERR(dev->syscon_base); + + dev->syscon_offset_18 = args.args[0]; + dev->syscon_offset_34 = args.args[1]; + irq = platform_get_irq_optional(pdev, 0); if (irq >= 0) { ret = devm_request_irq(&pdev->dev, irq, i2s_irq_handler, 0, @@ -913,18 +800,14 @@ static int dw_i2s_probe(struct platform_device *pdev) } } - if (of_device_is_compatible(np, "snps,designware-i2srx")) { //record + if (of_device_is_compatible(np, "snps,designware-i2srx")) { + /* config i2s data source: PDM */ + regmap_update_bits(dev->syscon_base, dev->syscon_offset_34, + AUDIO_SDIN_MUX_MASK, I2SRX_DATA_SRC_PDM); + ret = dw_i2srx_clk_init(pdev, dev); if (ret < 0) goto err_clk_disable; - } else if (of_device_is_compatible(np, "snps,designware-i2stx-4ch0")) { //playback - ret = dw_i2stx_4ch0_clk_init(pdev, dev); - if (ret < 0) - goto err_clk_disable; - } else if (of_device_is_compatible(np, "snps,designware-i2stx-4ch1")) { //playback - ret = dw_i2stx_4ch1_clk_init(pdev, dev); - if (ret < 0) - goto err_clk_disable; } dev->i2s_reg_comp1 = I2S_COMP_PARAM_1; @@ -939,7 +822,7 @@ static int dw_i2s_probe(struct platform_device *pdev) } ret = dw_configure_dai_by_pd(dev, dw_i2s_dai, res, pdata); } else { - clk_id = "i2sclk"; + clk_id = "i2srx_bclk"; ret = dw_configure_dai_by_dt(dev, dw_i2s_dai, res); } if (ret < 0) @@ -953,14 +836,6 @@ static int dw_i2s_probe(struct platform_device *pdev) return -ENODEV; } } - dev->clk = devm_clk_get(&pdev->dev, clk_id); - - if (IS_ERR(dev->clk)) - return PTR_ERR(dev->clk); - - ret = clk_prepare_enable(dev->clk); - if (ret < 0) - return ret; } dev_set_drvdata(&pdev->dev, dev); @@ -993,7 +868,7 @@ static int dw_i2s_probe(struct platform_device *pdev) err_clk_disable: if (dev->capability & DW_I2S_MASTER) - clk_disable_unprepare(dev->clk); + clk_disable_unprepare(dev->clk_i2srx_bclk_mst); return ret; } @@ -1002,7 +877,7 @@ static int dw_i2s_remove(struct platform_device *pdev) struct dw_i2s_dev *dev = dev_get_drvdata(&pdev->dev); if (dev->capability & DW_I2S_MASTER) - clk_disable_unprepare(dev->clk); + clk_disable_unprepare(dev->clk_i2srx_bclk_mst); pm_runtime_disable(&pdev->dev); return 0; @@ -1010,9 +885,7 @@ static int dw_i2s_remove(struct platform_device *pdev) #ifdef CONFIG_OF static const struct of_device_id dw_i2s_of_match[] = { - { .compatible = "snps,designware-i2srx", }, - { .compatible = "snps,designware-i2stx-4ch0", }, - { .compatible = "snps,designware-i2stx-4ch1", }, + { .compatible = "snps,designware-i2srx", }, {}, }; diff --git a/sound/soc/dwc/local.h b/sound/soc/dwc/local.h old mode 100755 new mode 100644 index baf4062..a0b9adc --- a/sound/soc/dwc/local.h +++ b/sound/soc/dwc/local.h @@ -81,32 +81,11 @@ #define MAX_CHANNEL_NUM 8 #define MIN_CHANNEL_NUM 2 -enum { - CLK_DAC_INNER = 0, - CLK_DAC_BCLK_MST, - CLK_DAC_LRCLK_MST, - CLK_MCLK, - CLK_DAC_BCLK0, - CLK_DAC_LRCLK0, - CLK_DAC_BCLK_MST_1, - CLK_DAC_LRCLK_MST_1, - CLK_DAC_BCLK_1, - CLK_DAC_LRCLK_1, - CLK_ADC_APB0, - CLK_ADC_APB, - CLK_ADC_LRCLK, - CLK_AUDIO_NUM, -}; - -enum { - RST_APB0_BUS = 0, - RST_BCLK_0, - RST_APB1_BUS, - RST_BCLK_1, - RST_APB_RX, - RST_BCLK_RX, - RST_AUDIO_NUM, -}; +/* SYSCON Registers */ +#define I2SRX_3CH_ADC_MASK 0x2 +#define I2SRX_3CH_ADC_EN BIT(1) +#define AUDIO_SDIN_MUX_MASK 0x3FC00 +#define I2SRX_DATA_SRC_PDM (0x91 << 10) union dw_i2s_snd_dma_data { struct i2s_dma_data pd; @@ -115,7 +94,7 @@ union dw_i2s_snd_dma_data { struct dw_i2s_dev { void __iomem *i2s_base; - struct clk *clk; + struct regmap *syscon_base; int active; unsigned int capability; unsigned int quirks; @@ -125,9 +104,17 @@ struct dw_i2s_dev { u32 ccr; u32 xfer_resolution; u32 fifo_th; - - struct clk *clks[CLK_AUDIO_NUM]; - struct reset_control *rstc[RST_AUDIO_NUM]; + u32 syscon_offset_18; + u32 syscon_offset_34; + + struct clk *clk_apb0; + struct clk *clk_i2srx_apb; + struct clk *clk_i2srx_bclk_mst; + struct clk *clk_i2srx_lrck_mst; + struct clk *clk_i2srx_bclk; + struct clk *clk_i2srx_lrck; + struct reset_control *rst_i2srx_apb; + struct reset_control *rst_i2srx_bclk; /* data related to DMA transfers b/w i2s and DMAC */ union dw_i2s_snd_dma_data play_dma_data; diff --git a/sound/soc/starfive/starfive_pdm.c b/sound/soc/starfive/starfive_pdm.c index f7d985f..a68e4b9 100644 --- a/sound/soc/starfive/starfive_pdm.c +++ b/sound/soc/starfive/starfive_pdm.c @@ -18,19 +18,15 @@ #include #include "starfive_pdm.h" -#define AUDIOC_CLK 12288000 -#define PDM_MUL 128 - struct sf_pdm { struct regmap *pdm_map; + struct device *dev; struct clk *clk_pdm_apb; - struct clk *clk_pdm_dmic; - struct clk *clk_dmic0_bclk; - struct clk *clk_dmic0_lrck; - struct clk *clk_dmic1_bclk; - struct clk *clk_dmic1_lrck; + struct clk *clk_pdm_mclk; struct clk *clk_apb0; - struct clk *clk_i2srx_3ch_bclk; + struct clk *clk_mclk_inner; + struct clk *clk_mclk; + struct clk *clk_mclk_out; struct reset_control *rst_pdm_dmic; struct reset_control *rst_pdm_apb; }; @@ -48,77 +44,16 @@ static const struct snd_kcontrol_new sf_pdm_snd_controls[] = { SOC_SINGLE("DC offset", PDM_DC_SCALE0, 8, 0xFFFFF, 0), }; -static int sf_pdm_set_mclk(struct sf_pdm *priv, unsigned int clk, - unsigned int width) -{ - /* - audio source clk:12288000, mclk_div:4, mclk:3M - support 8K/16K/32K/48K sample rate - support 16/24/32 bit width - bit width 32 - mclk bclk lrclk - 3M 1.5M 48K - 3M 1M 32K - 3M 0.5M 16K - 3M 0.25M 8K - - bit width 24, set lrclk_div as 32 - mclk bclk lrclk - 3M 1.5M 48K - 3M 1M 32K - 3M 0.5M 16K - 3M 0.25M 8K - - bit width 16 - mclk bclk lrclk - 3M 0.75M 48K - 3M 0.5M 32K - 3M 0.25M 16K - 3M 0.125M 8K - */ - - switch (clk) { - case 8000: - case 16000: - case 32000: - case 48000: - break; - default: - pr_err("PDM: not support sample rate:%d\n", clk); - return -EINVAL; - } - - switch (width) { - case 16: - case 24: - case 32: - break; - default: - pr_err("PDM: not support bit width %d\n", width); - return -EINVAL; - } - - if (width == 24) - width = 32; - - /* PDM MCLK = 128 * LRCLK */ - clk_set_rate(priv->clk_dmic0_bclk, clk*width); - clk_set_rate(priv->clk_dmic0_lrck, clk); - /* MCLK */ - clk_set_rate(priv->clk_pdm_dmic, PDM_MUL * clk); - - return 0; -} - static void sf_pdm_enable(struct regmap *map) { - /* Enable PDM */ + /* Left and Right Channel Volume Control Enable */ regmap_update_bits(map, PDM_DMIC_CTRL0, PDM_DMIC_RVOL_MASK, 0); regmap_update_bits(map, PDM_DMIC_CTRL0, PDM_DMIC_LVOL_MASK, 0); } static void sf_pdm_disable(struct regmap *map) { + /* Left and Right Channel Volume Control Disable */ regmap_update_bits(map, PDM_DMIC_CTRL0, PDM_DMIC_RVOL_MASK, PDM_DMIC_RVOL_MASK); regmap_update_bits(map, PDM_DMIC_CTRL0, @@ -153,28 +88,54 @@ static int sf_pdm_hw_params(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { struct sf_pdm *priv = snd_soc_dai_get_drvdata(dai); - unsigned int rate = params_rate(params); - unsigned int width; + unsigned int sample_rate; + unsigned int data_width; int ret; + unsigned int mclk_rate; + const int pdm_mul = 128; if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) return 0; - width = params_width(params); - switch (width) { + sample_rate = params_rate(params); + switch (sample_rate) { + case 8000: + mclk_rate = 12288000; + break; + case 16000: + mclk_rate = 24576000; + break; + default: + pr_err("PDM: not support sample rate:%d\n", sample_rate); + return -EINVAL; + } + + data_width = params_width(params); + switch (data_width) { case 16: case 24: case 32: break; default: - dev_err(dai->dev, "unsupported sample width\n"); + pr_err("PDM: not support bit width %d\n", data_width); return -EINVAL; } - ret = sf_pdm_set_mclk(priv, rate, width); - if (ret < 0) { - dev_err(dai->dev, "unsupported sample rate\n"); - return -EINVAL; + if (data_width == 24) + data_width = 32; + + /* set clk_mclk */ + ret = clk_set_rate(priv->clk_mclk_inner, mclk_rate); + if (ret) { + dev_info(priv->dev, "Can't set clk_mclk: %d\n", ret); + return ret; + } + + /* set pdm_mclk, PDM MCLK = 128 * LRCLK */ + ret = clk_set_rate(priv->clk_pdm_mclk, pdm_mul * sample_rate); + if (ret) { + dev_info(priv->dev, "Can't set pdm_mclk: %d\n", ret); + return ret; } return 0; @@ -191,20 +152,20 @@ static int sf_pdm_dai_probe(struct snd_soc_dai *dai) /* Reset */ regmap_update_bits(priv->pdm_map, PDM_DMIC_CTRL0, - PDM_DMIC_SW_RSTN_MASK, 0x00); + PDM_SW_RST_MASK, 0x00); regmap_update_bits(priv->pdm_map, PDM_DMIC_CTRL0, - PDM_DMIC_SW_RSTN_MASK, PDM_DMIC_SW_RSTN_MASK); + PDM_SW_RST_MASK, PDM_SW_RST_RELEASE); /* Make sure the device is initially disabled */ sf_pdm_disable(priv->pdm_map); /* MUTE */ regmap_update_bits(priv->pdm_map, PDM_DMIC_CTRL0, - PDM_DMIC_VOL_MASK, PDM_DMIC_VOL_MASK); + PDM_DMIC_VOL_MASK, PDM_VOL_DB_MUTE); /* UNMUTE */ regmap_update_bits(priv->pdm_map, PDM_DMIC_CTRL0, - PDM_DMIC_VOL_MASK, 0); + PDM_DMIC_VOL_MASK, PDM_VOL_DB_MAX); /* enable high pass filter */ regmap_update_bits(priv->pdm_map, PDM_DMIC_CTRL0, @@ -218,21 +179,27 @@ static int sf_pdm_dai_probe(struct snd_soc_dai *dai) regmap_update_bits(priv->pdm_map, PDM_DMIC_CTRL0, PDM_DMIC_FASTMODE_MASK, 0); - /* enable dc bypass mode */ - regmap_update_bits(priv->pdm_map, PDM_DMIC_CTRL0, - PDM_DMIC_DC_BYPASS_MASK, 0); - /* dmic msb shift 0 */ regmap_update_bits(priv->pdm_map, PDM_DMIC_CTRL0, PDM_DMIC_MSB_MASK, 0); - /* scale:0 */ + /* scale: 0x8 */ regmap_update_bits(priv->pdm_map, PDM_DC_SCALE0, - PDM_DC_SCALE0_MASK, 0x08); + DMIC_SCALE_MASK, DMIC_SCALE_DEF_VAL); - /* DC offset:0 */ regmap_update_bits(priv->pdm_map, PDM_DC_SCALE0, - PDM_DMIC_DCOFF1_MASK, PDM_DMIC_DCOFF1_EN); + DMIC_DCOFF1_MASK, DMIC_DCOFF1_VAL); + + regmap_update_bits(priv->pdm_map, PDM_DC_SCALE0, + DMIC_DCOFF3_MASK, DMIC_DCOFF3_VAL); + + /* scale: 0x3f */ + regmap_update_bits(priv->pdm_map, PDM_DC_SCALE0, + DMIC_SCALE_MASK, DMIC_SCALE_MASK); + + /* dmic msb shift 2 */ + regmap_update_bits(priv->pdm_map, PDM_DMIC_CTRL0, + PDM_DMIC_MSB_MASK, PDM_MSB_SHIFT_4); return 0; } @@ -250,8 +217,7 @@ static int sf_pdm_dai_remove(struct snd_soc_dai *dai) #define SF_PCM_RATE (SNDRV_PCM_RATE_8000 | \ SNDRV_PCM_RATE_16000 | \ - SNDRV_PCM_RATE_32000 | \ - SNDRV_PCM_RATE_48000) + SNDRV_PCM_RATE_32000) static struct snd_soc_dai_driver sf_pdm_dai_drv = { .name = "PDM", @@ -294,123 +260,87 @@ static const struct regmap_config sf_pdm_regmap_cfg = { .max_register = 0x20, }; -static const struct regmap_config sf_audio_clk_regmap_cfg = { - .reg_bits = 32, - .val_bits = 32, - .reg_stride = 4, - .max_register = 0x100, -}; - static int sf_pdm_clock_init(struct platform_device *pdev, struct sf_pdm *priv) { int ret; + static struct clk_bulk_data clks[] = { + { .id = "pdm_mclk" }, + { .id = "clk_apb0" }, + { .id = "pdm_apb" }, + { .id = "mclk_inner" }, + { .id = "clk_mclk" }, + { .id = "mclk_out" }, + }; + + ret = devm_clk_bulk_get(&pdev->dev, ARRAY_SIZE(clks), clks); + if (ret) { + dev_err(&pdev->dev, "failed to get pdm clocks\n"); + goto exit; + } + + priv->clk_pdm_mclk = clks[0].clk; + priv->clk_apb0 = clks[1].clk; + priv->clk_pdm_apb = clks[2].clk; + priv->clk_mclk_inner = clks[3].clk; + priv->clk_mclk = clks[4].clk; + priv->clk_mclk_out = clks[5].clk; + priv->rst_pdm_dmic = devm_reset_control_get_exclusive(&pdev->dev, "pdm_dmic"); if (IS_ERR(priv->rst_pdm_dmic)) { dev_err(&pdev->dev, "failed to get pdm_dmic reset control\n"); - return PTR_ERR(priv->rst_pdm_dmic); + ret = PTR_ERR(priv->rst_pdm_dmic); + goto exit; } priv->rst_pdm_apb = devm_reset_control_get_exclusive(&pdev->dev, "pdm_apb"); if (IS_ERR(priv->rst_pdm_apb)) { dev_err(&pdev->dev, "failed to get pdm_apb reset control\n"); - return PTR_ERR(priv->rst_pdm_apb); - } - - priv->clk_apb0 = devm_clk_get(&pdev->dev, "clk_apb0"); - if (IS_ERR(priv->clk_apb0)) { - dev_err(&pdev->dev, "failed to get clk_apb0\n"); - return PTR_ERR(priv->clk_apb0); - } - - priv->clk_pdm_apb = devm_clk_get(&pdev->dev, "pdm_apb"); - if (IS_ERR(priv->clk_pdm_apb)) { - dev_err(&pdev->dev, "failed to get clk_pdm_apb\n"); - return PTR_ERR(priv->clk_pdm_apb); - } - - priv->clk_pdm_dmic = devm_clk_get(&pdev->dev, "pdm_dmic"); - if (IS_ERR(priv->clk_pdm_dmic)) { - dev_err(&pdev->dev, "failed to get clk_pdm_dmic\n"); - return PTR_ERR(priv->clk_pdm_dmic); - } - - priv->clk_dmic0_bclk = devm_clk_get(&pdev->dev, "pdm_dmic0_bclk"); - if (IS_ERR(priv->clk_dmic0_bclk)) { - dev_err(&pdev->dev, "failed to get clk_dmic0_bclk\n"); - return PTR_ERR(priv->clk_dmic0_bclk); - } - - priv->clk_dmic0_lrck = devm_clk_get(&pdev->dev, "pdm_dmic0_lrck"); - if (IS_ERR(priv->clk_dmic0_lrck)) { - dev_err(&pdev->dev, "failed to get clk_dmic0_bclk\n"); - return PTR_ERR(priv->clk_dmic0_lrck); - } - - priv->clk_dmic1_bclk = devm_clk_get(&pdev->dev, "pdm_dmic1_bclk"); - if (IS_ERR(priv->clk_dmic1_bclk)) { - dev_err(&pdev->dev, "failed to get clk_dmic1_bclk\n"); - return PTR_ERR(priv->clk_dmic1_bclk); - } - - priv->clk_dmic1_lrck = devm_clk_get(&pdev->dev, "pdm_dmic1_lrck"); - if (IS_ERR(priv->clk_dmic1_lrck)) { - dev_err(&pdev->dev, "failed to get clk_dmic1_bclk\n"); - return PTR_ERR(priv->clk_dmic1_lrck); - } - - priv->clk_i2srx_3ch_bclk = devm_clk_get(&pdev->dev, "u0_i2srx_3ch_bclk"); - if (IS_ERR(priv->clk_i2srx_3ch_bclk)) { - dev_err(&pdev->dev, "failed to get clk_i2srx_3ch_bclk\n"); - return PTR_ERR(priv->clk_i2srx_3ch_bclk); + ret = PTR_ERR(priv->rst_pdm_apb); + goto exit; } - ret = clk_prepare_enable(priv->clk_pdm_dmic); + /* Enable PDM Clock */ + ret = reset_control_assert(priv->rst_pdm_apb); if (ret) { - dev_err(&pdev->dev, "failed to prepare enable clk_pdm_dmic\n"); - goto err_clk_disable; + dev_err(&pdev->dev, "failed to assert rst_pdm_apb\n"); + goto exit; } - ret = clk_prepare_enable(priv->clk_apb0); + ret = clk_prepare_enable(priv->clk_mclk_inner); if (ret) { - dev_err(&pdev->dev, "failed to prepare enable clk_apb0\n"); - goto err_clk_disable; + dev_err(&pdev->dev, "failed to prepare enable clk_mclk_inner\n"); + goto exit; } - ret = clk_prepare_enable(priv->clk_pdm_apb); + ret = clk_prepare_enable(priv->clk_mclk); if (ret) { - dev_err(&pdev->dev, "failed to prepare enable clk_pdm_apb\n"); - goto err_clk_disable; + dev_err(&pdev->dev, "failed to prepare enable clk_mclk\n"); + goto err_dis_mclk; } - ret = clk_prepare_enable(priv->clk_i2srx_3ch_bclk); + ret = clk_prepare_enable(priv->clk_mclk_out); if (ret) { - dev_err(&pdev->dev, "failed to prepare enable clk_i2srx_3ch_bclk\n"); - goto err_clk_disable; + dev_err(&pdev->dev, "failed to prepare enable clk_mclk_out\n"); + goto err_dis_mclk_out; } - ret = clk_prepare_enable(priv->clk_dmic0_bclk); + ret = clk_prepare_enable(priv->clk_pdm_mclk); if (ret) { - dev_err(&pdev->dev, "failed to prepare enable clk_dmic0_bclk\n"); - goto err_clk_disable; + dev_err(&pdev->dev, "failed to prepare enable clk_pdm_mclk\n"); + goto err_dis_pdm_mclk; } - ret = clk_prepare_enable(priv->clk_dmic0_lrck); - if (ret) { - dev_err(&pdev->dev, "failed to prepare enable clk_dmic0_lrck\n"); - goto err_clk_disable; - } - - ret = clk_prepare_enable(priv->clk_dmic1_bclk); + ret = clk_prepare_enable(priv->clk_apb0); if (ret) { - dev_err(&pdev->dev, "failed to prepare enable clk_dmic1_bclk\n"); - goto err_clk_disable; + dev_err(&pdev->dev, "failed to prepare enable clk_apb0\n"); + goto err_dis_apb0; } - ret = clk_prepare_enable(priv->clk_dmic1_lrck); + ret = clk_prepare_enable(priv->clk_pdm_apb); if (ret) { - dev_err(&pdev->dev, "failed to prepare enable clk_dmic1_lrck\n"); - goto err_clk_disable; + dev_err(&pdev->dev, "failed to prepare enable clk_pdm_apb\n"); + goto err_dis_pdm_apb; } ret = reset_control_deassert(priv->rst_pdm_dmic); @@ -428,18 +358,29 @@ static int sf_pdm_clock_init(struct platform_device *pdev, struct sf_pdm *priv) return 0; err_clk_disable: + clk_disable_unprepare(priv->clk_pdm_apb); +err_dis_pdm_apb: + clk_disable_unprepare(priv->clk_apb0); +err_dis_apb0: + clk_disable_unprepare(priv->clk_pdm_mclk); +err_dis_pdm_mclk: + clk_disable_unprepare(priv->clk_mclk_out); +err_dis_mclk_out: + clk_disable_unprepare(priv->clk_mclk); +err_dis_mclk: + clk_disable_unprepare(priv->clk_mclk_inner); +exit: return ret; } static int sf_pdm_probe(struct platform_device *pdev) { - struct device *dev = &pdev->dev; struct sf_pdm *priv; struct resource *res; void __iomem *regs; int ret; - priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; platform_set_drvdata(pdev, priv); @@ -449,20 +390,22 @@ static int sf_pdm_probe(struct platform_device *pdev) if (IS_ERR(regs)) return PTR_ERR(regs); - priv->pdm_map = devm_regmap_init_mmio(dev, regs, &sf_pdm_regmap_cfg); + priv->pdm_map = devm_regmap_init_mmio(&pdev->dev, regs, &sf_pdm_regmap_cfg); if (IS_ERR(priv->pdm_map)) { - dev_err(dev, "failed to init regmap: %ld\n", - PTR_ERR(priv->pdm_map)); + dev_err(&pdev->dev, "failed to init regmap: %ld\n", + PTR_ERR(priv->pdm_map)); return PTR_ERR(priv->pdm_map); } + priv->dev = &pdev->dev; + ret = sf_pdm_clock_init(pdev, priv); if (ret) { dev_err(&pdev->dev, "failed to enable audio-pdm clock\n"); return ret; } - return devm_snd_soc_register_component(dev, &sf_pdm_component_drv, + return devm_snd_soc_register_component(&pdev->dev, &sf_pdm_component_drv, &sf_pdm_dai_drv, 1); } diff --git a/sound/soc/starfive/starfive_pdm.h b/sound/soc/starfive/starfive_pdm.h index e9b9b79..4f514a0 100644 --- a/sound/soc/starfive/starfive_pdm.h +++ b/sound/soc/starfive/starfive_pdm.h @@ -25,25 +25,39 @@ #define PDM_DMIC_MSB_MASK (0x7 << PDM_DMIC_MSB_SHIFT) #define PDM_DMIC_VOL_SHIFT 16 #define PDM_DMIC_VOL_MASK (0x3f << PDM_DMIC_VOL_SHIFT) +#define PDM_VOL_DB_MUTE (0x3f << PDM_DMIC_VOL_SHIFT) +#define PDM_VOL_DB_MAX 0 + #define PDM_DMIC_RVOL_MASK BIT(22) #define PDM_DMIC_LVOL_MASK BIT(23) #define PDM_DMIC_I2S_SLAVE BIT(24) #define PDM_DMIC_HPF_EN BIT(28) #define PDM_DMIC_FASTMODE_MASK BIT(29) #define PDM_DMIC_DC_BYPASS_MASK BIT(30) -#define PDM_DMIC_SW_RSTN_MASK BIT(31) +#define PDM_SW_RST_MASK BIT(31) +#define PDM_SW_RST_RELEASE BIT(31) /* PDM SCALE OFFSET */ -#define PDM_DMIC_DCOFF3_SHIFT 24 -#define PDM_DMIC_DCOFF2_SHIFT 16 -#define PDM_DMIC_DCOFF1_SHIFT 8 -#define PDM_DMIC_DCOFF1_MASK (0xfffff << PDM_DMIC_DCOFF1_SHIFT) -#define PDM_DMIC_DCOFF1_EN (0xc0005 << PDM_DMIC_DCOFF1_SHIFT) -#define PDM_DC_SCALE0_MASK 0x3f - -#define AUDIO_CLK_ADC_MCLK 0x0 -#define AUDIO_CLK_I2SADC_BCLK 0xC -#define AUDIO_CLK_ADC_LRCLK 0x14 -#define AUDIO_CLK_PDM_CLK 0x1C +#define DMIC_DCOFF3_SHIFT 24 +#define DMIC_DCOFF2_SHIFT 16 +#define DMIC_DCOFF1_SHIFT 8 + +#define DMIC_DCOFF3_MASK (0xf << DMIC_DCOFF3_SHIFT) +#define DMIC_DCOFF3_VAL (0xc << DMIC_DCOFF3_SHIFT) +#define DMIC_DCOFF1_MASK (0xff << DMIC_DCOFF1_SHIFT) +#define DMIC_DCOFF1_VAL (0x5 << DMIC_DCOFF1_SHIFT) +#define DMIC_SCALE_MASK 0x3f +#define DMIC_SCALE_DEF_VAL 0x8 + +enum PDM_MSB_SHIFT { + PDM_MSB_SHIFT_NONE = 0, + PDM_MSB_SHIFT_1, + PDM_MSB_SHIFT_2, + PDM_MSB_SHIFT_3, + PDM_MSB_SHIFT_4, + PDM_MSB_SHIFT_5, + PDM_MSB_SHIFT_6, + PDM_MSB_SHIFT_7, +}; #endif /* __SND_SOC_STARFIVE_PDM_H__ */ -- 2.7.4