^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: (GPL-2.0 OR MIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) //
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) // Copyright (c) 2018 BayLibre, SAS.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) // Author: Jerome Brunet <jbrunet@baylibre.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <linux/clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/of_irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/of_platform.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/regmap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <sound/soc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <sound/soc-dai.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <sound/pcm_params.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #define PDM_CTRL 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #define PDM_CTRL_EN BIT(31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #define PDM_CTRL_OUT_MODE BIT(29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #define PDM_CTRL_BYPASS_MODE BIT(28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #define PDM_CTRL_RST_FIFO BIT(16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #define PDM_CTRL_CHAN_RSTN_MASK GENMASK(15, 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #define PDM_CTRL_CHAN_RSTN(x) ((x) << 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #define PDM_CTRL_CHAN_EN_MASK GENMASK(7, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #define PDM_CTRL_CHAN_EN(x) ((x) << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #define PDM_HCIC_CTRL1 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define PDM_FILTER_EN BIT(31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define PDM_HCIC_CTRL1_GAIN_SFT_MASK GENMASK(29, 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define PDM_HCIC_CTRL1_GAIN_SFT(x) ((x) << 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define PDM_HCIC_CTRL1_GAIN_MULT_MASK GENMASK(23, 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define PDM_HCIC_CTRL1_GAIN_MULT(x) ((x) << 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define PDM_HCIC_CTRL1_DSR_MASK GENMASK(8, 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define PDM_HCIC_CTRL1_DSR(x) ((x) << 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define PDM_HCIC_CTRL1_STAGE_NUM_MASK GENMASK(3, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define PDM_HCIC_CTRL1_STAGE_NUM(x) ((x) << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define PDM_HCIC_CTRL2 0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define PDM_F1_CTRL 0x0c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define PDM_LPF_ROUND_MODE_MASK GENMASK(17, 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define PDM_LPF_ROUND_MODE(x) ((x) << 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define PDM_LPF_DSR_MASK GENMASK(15, 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define PDM_LPF_DSR(x) ((x) << 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define PDM_LPF_STAGE_NUM_MASK GENMASK(8, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define PDM_LPF_STAGE_NUM(x) ((x) << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define PDM_LPF_MAX_STAGE 336
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define PDM_LPF_NUM 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define PDM_F2_CTRL 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define PDM_F3_CTRL 0x14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define PDM_HPF_CTRL 0x18
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define PDM_HPF_SFT_STEPS_MASK GENMASK(20, 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define PDM_HPF_SFT_STEPS(x) ((x) << 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define PDM_HPF_OUT_FACTOR_MASK GENMASK(15, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define PDM_HPF_OUT_FACTOR(x) ((x) << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define PDM_CHAN_CTRL 0x1c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define PDM_CHAN_CTRL_POINTER_WIDTH 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define PDM_CHAN_CTRL_POINTER_MAX ((1 << PDM_CHAN_CTRL_POINTER_WIDTH) - 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define PDM_CHAN_CTRL_NUM 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define PDM_CHAN_CTRL1 0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define PDM_COEFF_ADDR 0x24
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define PDM_COEFF_DATA 0x28
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #define PDM_CLKG_CTRL 0x2c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #define PDM_STS 0x30
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) struct axg_pdm_lpf {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) unsigned int ds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) unsigned int round_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) const unsigned int *tap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) unsigned int tap_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) struct axg_pdm_hcic {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) unsigned int shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) unsigned int mult;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) unsigned int steps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) unsigned int ds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) struct axg_pdm_hpf {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) unsigned int out_factor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) unsigned int steps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) struct axg_pdm_filters {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) struct axg_pdm_hcic hcic;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) struct axg_pdm_hpf hpf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) struct axg_pdm_lpf lpf[PDM_LPF_NUM];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) struct axg_pdm_cfg {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) const struct axg_pdm_filters *filters;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) unsigned int sys_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) struct axg_pdm {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) const struct axg_pdm_cfg *cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) struct regmap *map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) struct clk *dclk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) struct clk *sysclk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) struct clk *pclk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) static void axg_pdm_enable(struct regmap *map)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) /* Reset AFIFO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) regmap_update_bits(map, PDM_CTRL, PDM_CTRL_RST_FIFO, PDM_CTRL_RST_FIFO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) regmap_update_bits(map, PDM_CTRL, PDM_CTRL_RST_FIFO, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) /* Enable PDM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) regmap_update_bits(map, PDM_CTRL, PDM_CTRL_EN, PDM_CTRL_EN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) static void axg_pdm_disable(struct regmap *map)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) regmap_update_bits(map, PDM_CTRL, PDM_CTRL_EN, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) static void axg_pdm_filters_enable(struct regmap *map, bool enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) unsigned int val = enable ? PDM_FILTER_EN : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) regmap_update_bits(map, PDM_HCIC_CTRL1, PDM_FILTER_EN, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) regmap_update_bits(map, PDM_F1_CTRL, PDM_FILTER_EN, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) regmap_update_bits(map, PDM_F2_CTRL, PDM_FILTER_EN, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) regmap_update_bits(map, PDM_F3_CTRL, PDM_FILTER_EN, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) regmap_update_bits(map, PDM_HPF_CTRL, PDM_FILTER_EN, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) static int axg_pdm_trigger(struct snd_pcm_substream *substream, int cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) struct snd_soc_dai *dai)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) struct axg_pdm *priv = snd_soc_dai_get_drvdata(dai);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) case SNDRV_PCM_TRIGGER_START:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) case SNDRV_PCM_TRIGGER_RESUME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) axg_pdm_enable(priv->map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) case SNDRV_PCM_TRIGGER_STOP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) case SNDRV_PCM_TRIGGER_SUSPEND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) axg_pdm_disable(priv->map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) static unsigned int axg_pdm_get_os(struct axg_pdm *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) const struct axg_pdm_filters *filters = priv->cfg->filters;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) unsigned int os = filters->hcic.ds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) * The global oversampling factor is defined by the down sampling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) * factor applied by each filter (HCIC and LPFs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) for (i = 0; i < PDM_LPF_NUM; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) os *= filters->lpf[i].ds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) return os;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) static int axg_pdm_set_sysclk(struct axg_pdm *priv, unsigned int os,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) unsigned int rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) unsigned int sys_rate = os * 2 * rate * PDM_CHAN_CTRL_POINTER_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) * Set the default system clock rate unless it is too fast for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) * for the requested sample rate. In this case, the sample pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) * counter could overflow so set a lower system clock rate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) if (sys_rate < priv->cfg->sys_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) return clk_set_rate(priv->sysclk, sys_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) return clk_set_rate(priv->sysclk, priv->cfg->sys_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) static int axg_pdm_set_sample_pointer(struct axg_pdm *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) unsigned int spmax, sp, val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) /* Max sample counter value per half period of dclk */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) spmax = DIV_ROUND_UP_ULL((u64)clk_get_rate(priv->sysclk),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) clk_get_rate(priv->dclk) * 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) /* Check if sysclk is not too fast - should not happen */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) if (WARN_ON(spmax > PDM_CHAN_CTRL_POINTER_MAX))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) /* Capture the data when we are at 75% of the half period */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) sp = spmax * 3 / 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) for (i = 0, val = 0; i < PDM_CHAN_CTRL_NUM; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) val |= sp << (PDM_CHAN_CTRL_POINTER_WIDTH * i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) regmap_write(priv->map, PDM_CHAN_CTRL, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) regmap_write(priv->map, PDM_CHAN_CTRL1, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) static void axg_pdm_set_channel_mask(struct axg_pdm *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) unsigned int channels)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) unsigned int mask = GENMASK(channels - 1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) /* Put all channel in reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) regmap_update_bits(priv->map, PDM_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) PDM_CTRL_CHAN_RSTN_MASK, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) /* Take the necessary channels out of reset and enable them */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) regmap_update_bits(priv->map, PDM_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) PDM_CTRL_CHAN_RSTN_MASK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) PDM_CTRL_CHAN_EN_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) PDM_CTRL_CHAN_RSTN(mask) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) PDM_CTRL_CHAN_EN(mask));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) static int axg_pdm_hw_params(struct snd_pcm_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) struct snd_pcm_hw_params *params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) struct snd_soc_dai *dai)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) struct axg_pdm *priv = snd_soc_dai_get_drvdata(dai);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) unsigned int os = axg_pdm_get_os(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) unsigned int rate = params_rate(params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) unsigned int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) switch (params_width(params)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) case 24:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) val = PDM_CTRL_OUT_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) case 32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) dev_err(dai->dev, "unsupported sample width\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) regmap_update_bits(priv->map, PDM_CTRL, PDM_CTRL_OUT_MODE, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) ret = axg_pdm_set_sysclk(priv, os, rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) dev_err(dai->dev, "failed to set system clock\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) ret = clk_set_rate(priv->dclk, rate * os);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) dev_err(dai->dev, "failed to set dclk\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) ret = axg_pdm_set_sample_pointer(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) dev_err(dai->dev, "invalid clock setting\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) axg_pdm_set_channel_mask(priv, params_channels(params));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) static int axg_pdm_startup(struct snd_pcm_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) struct snd_soc_dai *dai)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) struct axg_pdm *priv = snd_soc_dai_get_drvdata(dai);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) ret = clk_prepare_enable(priv->dclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) dev_err(dai->dev, "enabling dclk failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) /* Enable the filters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) axg_pdm_filters_enable(priv->map, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) static void axg_pdm_shutdown(struct snd_pcm_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) struct snd_soc_dai *dai)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) struct axg_pdm *priv = snd_soc_dai_get_drvdata(dai);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) axg_pdm_filters_enable(priv->map, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) clk_disable_unprepare(priv->dclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) static const struct snd_soc_dai_ops axg_pdm_dai_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) .trigger = axg_pdm_trigger,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) .hw_params = axg_pdm_hw_params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) .startup = axg_pdm_startup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) .shutdown = axg_pdm_shutdown,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) static void axg_pdm_set_hcic_ctrl(struct axg_pdm *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) const struct axg_pdm_hcic *hcic = &priv->cfg->filters->hcic;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) unsigned int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) val = PDM_HCIC_CTRL1_STAGE_NUM(hcic->steps);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) val |= PDM_HCIC_CTRL1_DSR(hcic->ds);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) val |= PDM_HCIC_CTRL1_GAIN_MULT(hcic->mult);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) val |= PDM_HCIC_CTRL1_GAIN_SFT(hcic->shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) regmap_update_bits(priv->map, PDM_HCIC_CTRL1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) PDM_HCIC_CTRL1_STAGE_NUM_MASK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) PDM_HCIC_CTRL1_DSR_MASK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) PDM_HCIC_CTRL1_GAIN_MULT_MASK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) PDM_HCIC_CTRL1_GAIN_SFT_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) static void axg_pdm_set_lpf_ctrl(struct axg_pdm *priv, unsigned int index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) const struct axg_pdm_lpf *lpf = &priv->cfg->filters->lpf[index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) unsigned int offset = index * regmap_get_reg_stride(priv->map)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) + PDM_F1_CTRL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) unsigned int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) val = PDM_LPF_STAGE_NUM(lpf->tap_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) val |= PDM_LPF_DSR(lpf->ds);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) val |= PDM_LPF_ROUND_MODE(lpf->round_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) regmap_update_bits(priv->map, offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) PDM_LPF_STAGE_NUM_MASK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) PDM_LPF_DSR_MASK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) PDM_LPF_ROUND_MODE_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) static void axg_pdm_set_hpf_ctrl(struct axg_pdm *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) const struct axg_pdm_hpf *hpf = &priv->cfg->filters->hpf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) unsigned int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) val = PDM_HPF_OUT_FACTOR(hpf->out_factor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) val |= PDM_HPF_SFT_STEPS(hpf->steps);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) regmap_update_bits(priv->map, PDM_HPF_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) PDM_HPF_OUT_FACTOR_MASK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) PDM_HPF_SFT_STEPS_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) static int axg_pdm_set_lpf_filters(struct axg_pdm *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) const struct axg_pdm_lpf *lpf = priv->cfg->filters->lpf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) unsigned int count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) int i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) for (i = 0; i < PDM_LPF_NUM; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) count += lpf[i].tap_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) /* Make sure the coeffs fit in the memory */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) if (count >= PDM_LPF_MAX_STAGE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) /* Set the initial APB bus register address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) regmap_write(priv->map, PDM_COEFF_ADDR, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) /* Set the tap filter values of all 3 filters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) for (i = 0; i < PDM_LPF_NUM; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) axg_pdm_set_lpf_ctrl(priv, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) for (j = 0; j < lpf[i].tap_num; j++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) regmap_write(priv->map, PDM_COEFF_DATA, lpf[i].tap[j]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) static int axg_pdm_dai_probe(struct snd_soc_dai *dai)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) struct axg_pdm *priv = snd_soc_dai_get_drvdata(dai);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) ret = clk_prepare_enable(priv->pclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) dev_err(dai->dev, "enabling pclk failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) * sysclk must be set and enabled as well to access the pdm registers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) * Accessing the register w/o it will give a bus error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) ret = clk_set_rate(priv->sysclk, priv->cfg->sys_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) dev_err(dai->dev, "setting sysclk failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) goto err_pclk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) ret = clk_prepare_enable(priv->sysclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) dev_err(dai->dev, "enabling sysclk failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) goto err_pclk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) /* Make sure the device is initially disabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) axg_pdm_disable(priv->map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) /* Make sure filter bypass is disabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) regmap_update_bits(priv->map, PDM_CTRL, PDM_CTRL_BYPASS_MODE, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) /* Load filter settings */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) axg_pdm_set_hcic_ctrl(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) axg_pdm_set_hpf_ctrl(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) ret = axg_pdm_set_lpf_filters(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) dev_err(dai->dev, "invalid filter configuration\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) goto err_sysclk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) err_sysclk:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) clk_disable_unprepare(priv->sysclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) err_pclk:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) clk_disable_unprepare(priv->pclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) static int axg_pdm_dai_remove(struct snd_soc_dai *dai)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) struct axg_pdm *priv = snd_soc_dai_get_drvdata(dai);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) clk_disable_unprepare(priv->sysclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) clk_disable_unprepare(priv->pclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) static struct snd_soc_dai_driver axg_pdm_dai_drv = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) .name = "PDM",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) .capture = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) .stream_name = "Capture",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) .channels_min = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) .channels_max = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) .rates = SNDRV_PCM_RATE_CONTINUOUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) .rate_min = 5512,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) .rate_max = 48000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) .formats = (SNDRV_PCM_FMTBIT_S24_LE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) SNDRV_PCM_FMTBIT_S32_LE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) .ops = &axg_pdm_dai_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) .probe = axg_pdm_dai_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) .remove = axg_pdm_dai_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) static const struct snd_soc_component_driver axg_pdm_component_drv = {};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) static const struct regmap_config axg_pdm_regmap_cfg = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) .reg_bits = 32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) .val_bits = 32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) .reg_stride = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) .max_register = PDM_STS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) static const unsigned int lpf1_default_tap[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 0x000014, 0xffffb2, 0xfffed9, 0xfffdce, 0xfffd45,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 0xfffe32, 0x000147, 0x000645, 0x000b86, 0x000e21,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 0x000ae3, 0x000000, 0xffeece, 0xffdca8, 0xffd212,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 0xffd7d1, 0xfff2a7, 0x001f4c, 0x0050c2, 0x0072aa,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 0x006ff1, 0x003c32, 0xffdc4e, 0xff6a18, 0xff0fef,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 0xfefbaf, 0xff4c40, 0x000000, 0x00ebc8, 0x01c077,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 0x02209e, 0x01c1a4, 0x008e60, 0xfebe52, 0xfcd690,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 0xfb8fa5, 0xfba498, 0xfd9812, 0x0181ce, 0x06f5f3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 0x0d112f, 0x12a958, 0x169686, 0x18000e, 0x169686,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) 0x12a958, 0x0d112f, 0x06f5f3, 0x0181ce, 0xfd9812,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) 0xfba498, 0xfb8fa5, 0xfcd690, 0xfebe52, 0x008e60,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 0x01c1a4, 0x02209e, 0x01c077, 0x00ebc8, 0x000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) 0xff4c40, 0xfefbaf, 0xff0fef, 0xff6a18, 0xffdc4e,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 0x003c32, 0x006ff1, 0x0072aa, 0x0050c2, 0x001f4c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 0xfff2a7, 0xffd7d1, 0xffd212, 0xffdca8, 0xffeece,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) 0x000000, 0x000ae3, 0x000e21, 0x000b86, 0x000645,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 0x000147, 0xfffe32, 0xfffd45, 0xfffdce, 0xfffed9,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) 0xffffb2, 0x000014,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) static const unsigned int lpf2_default_tap[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 0x00050a, 0xfff004, 0x0002c1, 0x003c12, 0xffa818,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 0xffc87d, 0x010aef, 0xff5223, 0xfebd93, 0x028f41,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 0xff5c0e, 0xfc63f8, 0x055f81, 0x000000, 0xf478a0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 0x11c5e3, 0x2ea74d, 0x11c5e3, 0xf478a0, 0x000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 0x055f81, 0xfc63f8, 0xff5c0e, 0x028f41, 0xfebd93,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 0xff5223, 0x010aef, 0xffc87d, 0xffa818, 0x003c12,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) 0x0002c1, 0xfff004, 0x00050a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) static const unsigned int lpf3_default_tap[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) 0x000000, 0x000081, 0x000000, 0xfffedb, 0x000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 0x00022d, 0x000000, 0xfffc46, 0x000000, 0x0005f7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 0x000000, 0xfff6eb, 0x000000, 0x000d4e, 0x000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 0xffed1e, 0x000000, 0x001a1c, 0x000000, 0xffdcb0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 0x000000, 0x002ede, 0x000000, 0xffc2d1, 0x000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 0x004ebe, 0x000000, 0xff9beb, 0x000000, 0x007dd7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 0x000000, 0xff633a, 0x000000, 0x00c1d2, 0x000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 0xff11d5, 0x000000, 0x012368, 0x000000, 0xfe9c45,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 0x000000, 0x01b252, 0x000000, 0xfdebf6, 0x000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 0x0290b8, 0x000000, 0xfcca0d, 0x000000, 0x041d7c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) 0x000000, 0xfa8152, 0x000000, 0x07e9c6, 0x000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) 0xf28fb5, 0x000000, 0x28b216, 0x3fffde, 0x28b216,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) 0x000000, 0xf28fb5, 0x000000, 0x07e9c6, 0x000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) 0xfa8152, 0x000000, 0x041d7c, 0x000000, 0xfcca0d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) 0x000000, 0x0290b8, 0x000000, 0xfdebf6, 0x000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) 0x01b252, 0x000000, 0xfe9c45, 0x000000, 0x012368,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) 0x000000, 0xff11d5, 0x000000, 0x00c1d2, 0x000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) 0xff633a, 0x000000, 0x007dd7, 0x000000, 0xff9beb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) 0x000000, 0x004ebe, 0x000000, 0xffc2d1, 0x000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) 0x002ede, 0x000000, 0xffdcb0, 0x000000, 0x001a1c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) 0x000000, 0xffed1e, 0x000000, 0x000d4e, 0x000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) 0xfff6eb, 0x000000, 0x0005f7, 0x000000, 0xfffc46,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) 0x000000, 0x00022d, 0x000000, 0xfffedb, 0x000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) 0x000081, 0x000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) * These values are sane defaults for the axg platform:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) * - OS = 64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) * - Latency = 38700 (?)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) * TODO: There is a lot of different HCIC, LPFs and HPF configurations possible.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) * the configuration may depend on the dmic used by the platform, the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) * expected tradeoff between latency and quality, etc ... If/When other
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) * settings are required, we should add a fw interface to this driver to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) * load new filter settings.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) static const struct axg_pdm_filters axg_default_filters = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) .hcic = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) .shift = 0x15,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) .mult = 0x80,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) .steps = 7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) .ds = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) .hpf = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) .out_factor = 0x8000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) .steps = 13,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) .lpf = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) [0] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) .ds = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) .round_mode = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) .tap = lpf1_default_tap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) .tap_num = ARRAY_SIZE(lpf1_default_tap),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) [1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) .ds = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) .round_mode = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) .tap = lpf2_default_tap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) .tap_num = ARRAY_SIZE(lpf2_default_tap),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) [2] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) .ds = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) .round_mode = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) .tap = lpf3_default_tap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) .tap_num = ARRAY_SIZE(lpf3_default_tap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) static const struct axg_pdm_cfg axg_pdm_config = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) .filters = &axg_default_filters,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) .sys_rate = 250000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) static const struct of_device_id axg_pdm_of_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) .compatible = "amlogic,axg-pdm",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) .data = &axg_pdm_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) }, {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) MODULE_DEVICE_TABLE(of, axg_pdm_of_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) static int axg_pdm_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) struct device *dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) struct axg_pdm *priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) void __iomem *regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) if (!priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) platform_set_drvdata(pdev, priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) priv->cfg = of_device_get_match_data(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) if (!priv->cfg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) dev_err(dev, "failed to match device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) regs = devm_platform_ioremap_resource(pdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) if (IS_ERR(regs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) return PTR_ERR(regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) priv->map = devm_regmap_init_mmio(dev, regs, &axg_pdm_regmap_cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) if (IS_ERR(priv->map)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) dev_err(dev, "failed to init regmap: %ld\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) PTR_ERR(priv->map));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) return PTR_ERR(priv->map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) priv->pclk = devm_clk_get(dev, "pclk");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) if (IS_ERR(priv->pclk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) ret = PTR_ERR(priv->pclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) if (ret != -EPROBE_DEFER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) dev_err(dev, "failed to get pclk: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) priv->dclk = devm_clk_get(dev, "dclk");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) if (IS_ERR(priv->dclk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) ret = PTR_ERR(priv->dclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) if (ret != -EPROBE_DEFER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) dev_err(dev, "failed to get dclk: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) priv->sysclk = devm_clk_get(dev, "sysclk");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) if (IS_ERR(priv->sysclk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) ret = PTR_ERR(priv->sysclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) if (ret != -EPROBE_DEFER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) dev_err(dev, "failed to get dclk: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) return devm_snd_soc_register_component(dev, &axg_pdm_component_drv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) &axg_pdm_dai_drv, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) static struct platform_driver axg_pdm_pdrv = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) .probe = axg_pdm_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) .name = "axg-pdm",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) .of_match_table = axg_pdm_of_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) module_platform_driver(axg_pdm_pdrv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) MODULE_DESCRIPTION("Amlogic AXG PDM Input driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) MODULE_AUTHOR("Jerome Brunet <jbrunet@baylibre.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) MODULE_LICENSE("GPL v2");