Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/sound/soc/meson/axg-pdm.c
26436 views
1
// SPDX-License-Identifier: (GPL-2.0 OR MIT)
2
//
3
// Copyright (c) 2018 BayLibre, SAS.
4
// Author: Jerome Brunet <[email protected]>
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 <[email protected]>");
641
MODULE_LICENSE("GPL v2");
642
643