Message ID | 1630675410-3354-1-git-send-email-sugar.zhang@rock-chips.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | Patches to update for rockchip pdm | expand |
Hi Sugar Zhang, Sorry to dig out this old thread, but I have two questions. Please see below: On 9/3/21 15:23, Sugar Zhang wrote: > This patch adds support for rv1126 pdm controller which > redesign cic filiter for better performance. > > Signed-off-by: Sugar Zhang <sugar.zhang@rock-chips.com> > --- > > Changes in v4: None > Changes in v3: None > Changes in v2: None > > sound/soc/rockchip/rockchip_pdm.c | 76 +++++++++++++++++++++++++++++++++++---- > sound/soc/rockchip/rockchip_pdm.h | 3 ++ > 2 files changed, 73 insertions(+), 6 deletions(-) > > diff --git a/sound/soc/rockchip/rockchip_pdm.c b/sound/soc/rockchip/rockchip_pdm.c > index 38bd603..67634d1 100644 > --- a/sound/soc/rockchip/rockchip_pdm.c > +++ b/sound/soc/rockchip/rockchip_pdm.c > @@ -24,6 +24,7 @@ > enum rk_pdm_version { > RK_PDM_RK3229, > RK_PDM_RK3308, > + RK_PDM_RV1126, > }; > > struct rk_pdm_dev { > @@ -121,6 +122,55 @@ static unsigned int get_pdm_ds_ratio(unsigned int sr) > return ratio; > } > > +static unsigned int get_pdm_cic_ratio(unsigned int clk) > +{ > + switch (clk) { > + case 4096000: > + case 5644800: > + case 6144000: > + return 0; > + case 2048000: > + case 2822400: > + case 3072000: > + return 1; > + case 1024000: > + case 1411200: > + case 1536000: > + return 2; > + default: > + return 1; > + } > +} > + > +static unsigned int samplerate_to_bit(unsigned int samplerate) > +{ > + switch (samplerate) { > + case 8000: > + case 11025: > + case 12000: > + return 0; > + case 16000: > + case 22050: > + case 24000: > + return 1; > + case 32000: > + return 2; > + case 44100: > + case 48000: > + return 3; > + case 64000: > + case 88200: > + case 96000: > + return 4; > + case 128000: > + case 176400: > + case 192000: > + return 5; > + default: > + return 1; > + } > +} > + > static inline struct rk_pdm_dev *to_info(struct snd_soc_dai *dai) > { > return snd_soc_dai_get_drvdata(dai); > @@ -166,7 +216,8 @@ static int rockchip_pdm_hw_params(struct snd_pcm_substream *substream, > if (ret) > return -EINVAL; > > - if (pdm->version == RK_PDM_RK3308) { > + if (pdm->version == RK_PDM_RK3308 || > + pdm->version == RK_PDM_RV1126) { > rational_best_approximation(clk_out, clk_src, > GENMASK(16 - 1, 0), > GENMASK(16 - 1, 0), > @@ -194,8 +245,18 @@ static int rockchip_pdm_hw_params(struct snd_pcm_substream *substream, > PDM_CLK_FD_RATIO_MSK, > val); > } > - val = get_pdm_ds_ratio(samplerate); > - regmap_update_bits(pdm->regmap, PDM_CLK_CTRL, PDM_DS_RATIO_MSK, val); > + > + if (pdm->version == RK_PDM_RV1126) { > + val = get_pdm_cic_ratio(clk_out); > + regmap_update_bits(pdm->regmap, PDM_CLK_CTRL, PDM_CIC_RATIO_MSK, val); > + val = samplerate_to_bit(samplerate); > + regmap_update_bits(pdm->regmap, PDM_CTRL0, > + PDM_SAMPLERATE_MSK, PDM_SAMPLERATE(val)); > + } else { > + val = get_pdm_ds_ratio(samplerate); > + regmap_update_bits(pdm->regmap, PDM_CLK_CTRL, PDM_DS_RATIO_MSK, val); > + } > + > regmap_update_bits(pdm->regmap, PDM_HPF_CTRL, > PDM_HPF_CF_MSK, PDM_HPF_60HZ); > regmap_update_bits(pdm->regmap, PDM_HPF_CTRL, > @@ -441,9 +502,10 @@ static bool rockchip_pdm_precious_reg(struct device *dev, unsigned int reg) > } > > static const struct reg_default rockchip_pdm_reg_defaults[] = { > - {0x04, 0x78000017}, > - {0x08, 0x0bb8ea60}, > - {0x18, 0x0000001f}, > + { PDM_CTRL0, 0x78000017 }, > + { PDM_CTRL1, 0x0bb8ea60 }, > + { PDM_CLK_CTRL, 0x0000e401 }, > + { PDM_DMA_CTRL, 0x0000001f }, > }; > > static const struct regmap_config rockchip_pdm_regmap_config = { > @@ -469,6 +531,8 @@ static const struct of_device_id rockchip_pdm_match[] __maybe_unused = { > .data = (void *)RK_PDM_RK3308 }, > { .compatible = "rockchip,rk3308-pdm", > .data = (void *)RK_PDM_RK3308 }, > + { .compatible = "rockchip,rv1126-pdm", > + .data = (void *)RK_PDM_RV1126 }, > {}, > }; > MODULE_DEVICE_TABLE(of, rockchip_pdm_match); > diff --git a/sound/soc/rockchip/rockchip_pdm.h b/sound/soc/rockchip/rockchip_pdm.h > index 8e5bbaf..13bfbc2 100644 > --- a/sound/soc/rockchip/rockchip_pdm.h > +++ b/sound/soc/rockchip/rockchip_pdm.h > @@ -41,6 +41,8 @@ > #define PDM_PATH1_EN BIT(28) > #define PDM_PATH0_EN BIT(27) > #define PDM_HWT_EN BIT(26) > +#define PDM_SAMPLERATE_MSK GENMASK(7, 5) > +#define PDM_SAMPLERATE(x) ((x) << 5) > #define PDM_VDW_MSK (0x1f << 0) > #define PDM_VDW(X) ((X - 1) << 0) The TRM of RV1126 and RK3568 both state that sample resolutions from 16 up to 24 bits are supported. However, I don't see anything in this patch that restricts the capture formats accordingly. In fact, the driver offers SNDRV_PCM_FMTBIT_S32_LE in my setup and via this PDM_VDW macro 31 is written to PDM_CTRL0, which is undefined behavior according to the TRM. Are 32 bit samples supported by the RK3568/RV1126 PDM block? > @@ -66,6 +68,7 @@ > #define PDM_CLK_1280FS (0x2 << 0) > #define PDM_CLK_2560FS (0x3 << 0) > #define PDM_CLK_5120FS (0x4 << 0) > +#define PDM_CIC_RATIO_MSK (0x3 << 0) > > /* PDM HPF CTRL */ > #define PDM_HPF_LE BIT(3) Also, I noticed that the number of channels must be an even number. Shouldn't it be possible to use a single mono PDM microphone with this PDM block (i.e., having one channel)? Thanks a lot and best regards, Michael
diff --git a/sound/soc/rockchip/rockchip_pdm.c b/sound/soc/rockchip/rockchip_pdm.c index 38bd603..67634d1 100644 --- a/sound/soc/rockchip/rockchip_pdm.c +++ b/sound/soc/rockchip/rockchip_pdm.c @@ -24,6 +24,7 @@ enum rk_pdm_version { RK_PDM_RK3229, RK_PDM_RK3308, + RK_PDM_RV1126, }; struct rk_pdm_dev { @@ -121,6 +122,55 @@ static unsigned int get_pdm_ds_ratio(unsigned int sr) return ratio; } +static unsigned int get_pdm_cic_ratio(unsigned int clk) +{ + switch (clk) { + case 4096000: + case 5644800: + case 6144000: + return 0; + case 2048000: + case 2822400: + case 3072000: + return 1; + case 1024000: + case 1411200: + case 1536000: + return 2; + default: + return 1; + } +} + +static unsigned int samplerate_to_bit(unsigned int samplerate) +{ + switch (samplerate) { + case 8000: + case 11025: + case 12000: + return 0; + case 16000: + case 22050: + case 24000: + return 1; + case 32000: + return 2; + case 44100: + case 48000: + return 3; + case 64000: + case 88200: + case 96000: + return 4; + case 128000: + case 176400: + case 192000: + return 5; + default: + return 1; + } +} + static inline struct rk_pdm_dev *to_info(struct snd_soc_dai *dai) { return snd_soc_dai_get_drvdata(dai); @@ -166,7 +216,8 @@ static int rockchip_pdm_hw_params(struct snd_pcm_substream *substream, if (ret) return -EINVAL; - if (pdm->version == RK_PDM_RK3308) { + if (pdm->version == RK_PDM_RK3308 || + pdm->version == RK_PDM_RV1126) { rational_best_approximation(clk_out, clk_src, GENMASK(16 - 1, 0), GENMASK(16 - 1, 0), @@ -194,8 +245,18 @@ static int rockchip_pdm_hw_params(struct snd_pcm_substream *substream, PDM_CLK_FD_RATIO_MSK, val); } - val = get_pdm_ds_ratio(samplerate); - regmap_update_bits(pdm->regmap, PDM_CLK_CTRL, PDM_DS_RATIO_MSK, val); + + if (pdm->version == RK_PDM_RV1126) { + val = get_pdm_cic_ratio(clk_out); + regmap_update_bits(pdm->regmap, PDM_CLK_CTRL, PDM_CIC_RATIO_MSK, val); + val = samplerate_to_bit(samplerate); + regmap_update_bits(pdm->regmap, PDM_CTRL0, + PDM_SAMPLERATE_MSK, PDM_SAMPLERATE(val)); + } else { + val = get_pdm_ds_ratio(samplerate); + regmap_update_bits(pdm->regmap, PDM_CLK_CTRL, PDM_DS_RATIO_MSK, val); + } + regmap_update_bits(pdm->regmap, PDM_HPF_CTRL, PDM_HPF_CF_MSK, PDM_HPF_60HZ); regmap_update_bits(pdm->regmap, PDM_HPF_CTRL, @@ -441,9 +502,10 @@ static bool rockchip_pdm_precious_reg(struct device *dev, unsigned int reg) } static const struct reg_default rockchip_pdm_reg_defaults[] = { - {0x04, 0x78000017}, - {0x08, 0x0bb8ea60}, - {0x18, 0x0000001f}, + { PDM_CTRL0, 0x78000017 }, + { PDM_CTRL1, 0x0bb8ea60 }, + { PDM_CLK_CTRL, 0x0000e401 }, + { PDM_DMA_CTRL, 0x0000001f }, }; static const struct regmap_config rockchip_pdm_regmap_config = { @@ -469,6 +531,8 @@ static const struct of_device_id rockchip_pdm_match[] __maybe_unused = { .data = (void *)RK_PDM_RK3308 }, { .compatible = "rockchip,rk3308-pdm", .data = (void *)RK_PDM_RK3308 }, + { .compatible = "rockchip,rv1126-pdm", + .data = (void *)RK_PDM_RV1126 }, {}, }; MODULE_DEVICE_TABLE(of, rockchip_pdm_match); diff --git a/sound/soc/rockchip/rockchip_pdm.h b/sound/soc/rockchip/rockchip_pdm.h index 8e5bbaf..13bfbc2 100644 --- a/sound/soc/rockchip/rockchip_pdm.h +++ b/sound/soc/rockchip/rockchip_pdm.h @@ -41,6 +41,8 @@ #define PDM_PATH1_EN BIT(28) #define PDM_PATH0_EN BIT(27) #define PDM_HWT_EN BIT(26) +#define PDM_SAMPLERATE_MSK GENMASK(7, 5) +#define PDM_SAMPLERATE(x) ((x) << 5) #define PDM_VDW_MSK (0x1f << 0) #define PDM_VDW(X) ((X - 1) << 0) @@ -66,6 +68,7 @@ #define PDM_CLK_1280FS (0x2 << 0) #define PDM_CLK_2560FS (0x3 << 0) #define PDM_CLK_5120FS (0x4 << 0) +#define PDM_CIC_RATIO_MSK (0x3 << 0) /* PDM HPF CTRL */ #define PDM_HPF_LE BIT(3)
This patch adds support for rv1126 pdm controller which redesign cic filiter for better performance. Signed-off-by: Sugar Zhang <sugar.zhang@rock-chips.com> --- Changes in v4: None Changes in v3: None Changes in v2: None sound/soc/rockchip/rockchip_pdm.c | 76 +++++++++++++++++++++++++++++++++++---- sound/soc/rockchip/rockchip_pdm.h | 3 ++ 2 files changed, 73 insertions(+), 6 deletions(-)