~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/sound/soc/meson/axg-pdm.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

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

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php