1 // SPDX-License-Identifier: GPL-2.0-only
3 // tegra210_mbdrc.c - Tegra210 MBDRC driver
5 // Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved.
7 #include <linux/device.h>
9 #include <linux/module.h>
10 #include <linux/of_address.h>
11 #include <linux/pm_runtime.h>
12 #include <linux/regmap.h>
13 #include <sound/core.h>
14 #include <sound/soc.h>
15 #include <sound/tlv.h>
17 #include "tegra210_mbdrc.h"
18 #include "tegra210_ope.h"
20 #define MBDRC_FILTER_REG(reg, id) \
21 ((reg) + ((id) * TEGRA210_MBDRC_FILTER_PARAM_STRIDE))
23 #define MBDRC_FILTER_REG_DEFAULTS(id) \
24 { MBDRC_FILTER_REG(TEGRA210_MBDRC_IIR_CFG, id), 0x00000005}, \
25 { MBDRC_FILTER_REG(TEGRA210_MBDRC_IN_ATTACK, id), 0x3e48590c}, \
26 { MBDRC_FILTER_REG(TEGRA210_MBDRC_IN_RELEASE, id), 0x08414e9f}, \
27 { MBDRC_FILTER_REG(TEGRA210_MBDRC_FAST_ATTACK, id), 0x7fffffff}, \
28 { MBDRC_FILTER_REG(TEGRA210_MBDRC_IN_THRESHOLD, id), 0x06145082}, \
29 { MBDRC_FILTER_REG(TEGRA210_MBDRC_OUT_THRESHOLD, id), 0x060d379b}, \
30 { MBDRC_FILTER_REG(TEGRA210_MBDRC_RATIO_1ST, id), 0x0000a000}, \
31 { MBDRC_FILTER_REG(TEGRA210_MBDRC_RATIO_2ND, id), 0x00002000}, \
32 { MBDRC_FILTER_REG(TEGRA210_MBDRC_RATIO_3RD, id), 0x00000b33}, \
33 { MBDRC_FILTER_REG(TEGRA210_MBDRC_RATIO_4TH, id), 0x00000800}, \
34 { MBDRC_FILTER_REG(TEGRA210_MBDRC_RATIO_5TH, id), 0x0000019a}, \
35 { MBDRC_FILTER_REG(TEGRA210_MBDRC_MAKEUP_GAIN, id), 0x00000002}, \
36 { MBDRC_FILTER_REG(TEGRA210_MBDRC_INIT_GAIN, id), 0x00066666}, \
37 { MBDRC_FILTER_REG(TEGRA210_MBDRC_GAIN_ATTACK, id), 0x00d9ba0e}, \
38 { MBDRC_FILTER_REG(TEGRA210_MBDRC_GAIN_RELEASE, id), 0x3e48590c}, \
39 { MBDRC_FILTER_REG(TEGRA210_MBDRC_FAST_RELEASE, id), 0x7ffff26a}, \
40 { MBDRC_FILTER_REG(TEGRA210_MBDRC_CFG_RAM_CTRL, id), 0x4000}
42 static const struct reg_default tegra210_mbdrc_reg_defaults
[] = {
43 { TEGRA210_MBDRC_CFG
, 0x0030de51},
44 { TEGRA210_MBDRC_CHANNEL_MASK
, 0x00000003},
45 { TEGRA210_MBDRC_FAST_FACTOR
, 0x30000800},
47 MBDRC_FILTER_REG_DEFAULTS(0),
48 MBDRC_FILTER_REG_DEFAULTS(1),
49 MBDRC_FILTER_REG_DEFAULTS(2),
52 /* Default MBDRC parameters */
53 static const struct tegra210_mbdrc_config mbdrc_init_config
= {
54 .mode
= 0, /* Bypass */
56 .peak_rms_mode
= 1, /* PEAK */
57 .filter_structure
= 0, /* All-pass tree */
64 .band_params
[MBDRC_LOW_BAND
] = {
65 .band
= MBDRC_LOW_BAND
,
67 .in_attack_tc
= 1044928780,
68 .in_release_tc
= 138497695,
69 .fast_attack_tc
= 2147483647,
70 .in_threshold
= {130, 80, 20, 6},
71 .out_threshold
= {155, 55, 13, 6},
72 .ratio
= {40960, 8192, 2867, 2048, 410},
75 .gain_attack_tc
= 14268942,
76 .gain_release_tc
= 1440547090,
77 .fast_release_tc
= 2147480170,
88 961046798, -2030431983, 1073741824,
89 2030431983, -961046798,
91 1030244425, -2099481453, 1073741824,
92 2099481453, -1030244425,
94 1067169294, -2136327263, 1073741824,
95 2136327263, -1067169294,
97 434951949, -1306567134, 1073741824,
98 1306567134, -434951949,
100 780656019, -1605955641, 1073741824,
101 1605955641, -780656019,
103 1024497031, -1817128152, 1073741824,
104 1817128152, -1024497031,
114 .band_params
[MBDRC_MID_BAND
] = {
115 .band
= MBDRC_MID_BAND
,
117 .in_attack_tc
= 1581413104,
118 .in_release_tc
= 35494783,
119 .fast_attack_tc
= 2147483647,
120 .in_threshold
= {130, 50, 30, 6},
121 .out_threshold
= {106, 50, 30, 13},
122 .ratio
= {40960, 2867, 4096, 2867, 410},
125 .gain_attack_tc
= 4766887,
126 .gain_release_tc
= 1044928780,
127 .fast_release_tc
= 2147480170,
138 -1005668963, 1073741824, 0,
141 998437058, -2067742187, 1073741824,
142 2067742187, -998437058,
144 1051963422, -2121153948, 1073741824,
145 2121153948, -1051963422,
147 434951949, -1306567134, 1073741824,
148 1306567134, -434951949,
150 780656019, -1605955641, 1073741824,
151 1605955641, -780656019,
153 1024497031, -1817128152, 1073741824,
154 1817128152, -1024497031,
164 .band_params
[MBDRC_HIGH_BAND
] = {
165 .band
= MBDRC_HIGH_BAND
,
167 .in_attack_tc
= 2144750688,
168 .in_release_tc
= 70402888,
169 .fast_attack_tc
= 2147483647,
170 .in_threshold
= {130, 50, 30, 6},
171 .out_threshold
= {106, 50, 30, 13},
172 .ratio
= {40960, 2867, 4096, 2867, 410},
175 .gain_attack_tc
= 4766887,
176 .gain_release_tc
= 1044928780,
177 .fast_release_tc
= 2147480170,
197 -619925131, 1073741824, 0,
200 606839335, -1455425976, 1073741824,
201 1455425976, -606839335,
203 917759617, -1724690840, 1073741824,
204 1724690840, -917759617,
215 static void tegra210_mbdrc_write_ram(struct regmap
*regmap
, unsigned int reg_ctrl
,
216 unsigned int reg_data
, unsigned int ram_offset
,
217 unsigned int *data
, size_t size
)
222 val
= ram_offset
& TEGRA210_MBDRC_RAM_CTRL_RAM_ADDR_MASK
;
223 val
|= TEGRA210_MBDRC_RAM_CTRL_ADDR_INIT_EN
;
224 val
|= TEGRA210_MBDRC_RAM_CTRL_SEQ_ACCESS_EN
;
225 val
|= TEGRA210_MBDRC_RAM_CTRL_RW_WRITE
;
227 regmap_write(regmap
, reg_ctrl
, val
);
229 for (i
= 0; i
< size
; i
++)
230 regmap_write(regmap
, reg_data
, data
[i
]);
233 static int tegra210_mbdrc_get(struct snd_kcontrol
*kcontrol
,
234 struct snd_ctl_elem_value
*ucontrol
)
236 struct soc_mixer_control
*mc
=
237 (struct soc_mixer_control
*)kcontrol
->private_value
;
238 struct snd_soc_component
*cmpnt
= snd_soc_kcontrol_component(kcontrol
);
239 struct tegra210_ope
*ope
= snd_soc_component_get_drvdata(cmpnt
);
242 regmap_read(ope
->mbdrc_regmap
, mc
->reg
, &val
);
244 ucontrol
->value
.integer
.value
[0] = (val
>> mc
->shift
) & mc
->max
;
249 static int tegra210_mbdrc_put(struct snd_kcontrol
*kcontrol
,
250 struct snd_ctl_elem_value
*ucontrol
)
252 struct soc_mixer_control
*mc
=
253 (struct soc_mixer_control
*)kcontrol
->private_value
;
254 struct snd_soc_component
*cmpnt
= snd_soc_kcontrol_component(kcontrol
);
255 struct tegra210_ope
*ope
= snd_soc_component_get_drvdata(cmpnt
);
256 unsigned int val
= ucontrol
->value
.integer
.value
[0];
259 val
= val
<< mc
->shift
;
261 regmap_update_bits_check(ope
->mbdrc_regmap
, mc
->reg
,
262 (mc
->max
<< mc
->shift
), val
, &change
);
264 return change
? 1 : 0;
267 static int tegra210_mbdrc_get_enum(struct snd_kcontrol
*kcontrol
,
268 struct snd_ctl_elem_value
*ucontrol
)
270 struct snd_soc_component
*cmpnt
= snd_soc_kcontrol_component(kcontrol
);
271 struct tegra210_ope
*ope
= snd_soc_component_get_drvdata(cmpnt
);
272 struct soc_enum
*e
= (struct soc_enum
*)kcontrol
->private_value
;
275 regmap_read(ope
->mbdrc_regmap
, e
->reg
, &val
);
277 ucontrol
->value
.enumerated
.item
[0] = (val
>> e
->shift_l
) & e
->mask
;
282 static int tegra210_mbdrc_put_enum(struct snd_kcontrol
*kcontrol
,
283 struct snd_ctl_elem_value
*ucontrol
)
285 struct snd_soc_component
*cmpnt
= snd_soc_kcontrol_component(kcontrol
);
286 struct tegra210_ope
*ope
= snd_soc_component_get_drvdata(cmpnt
);
287 struct soc_enum
*e
= (struct soc_enum
*)kcontrol
->private_value
;
292 if (ucontrol
->value
.enumerated
.item
[0] > e
->items
- 1)
295 val
= ucontrol
->value
.enumerated
.item
[0] << e
->shift_l
;
296 mask
= e
->mask
<< e
->shift_l
;
298 regmap_update_bits_check(ope
->mbdrc_regmap
, e
->reg
, mask
, val
,
301 return change
? 1 : 0;
304 static int tegra210_mbdrc_band_params_get(struct snd_kcontrol
*kcontrol
,
305 struct snd_ctl_elem_value
*ucontrol
)
307 struct tegra_soc_bytes
*params
= (void *)kcontrol
->private_value
;
308 struct snd_soc_component
*cmpnt
= snd_soc_kcontrol_component(kcontrol
);
309 struct tegra210_ope
*ope
= snd_soc_component_get_drvdata(cmpnt
);
310 u32
*data
= (u32
*)ucontrol
->value
.bytes
.data
;
311 u32 regs
= params
->soc
.base
;
312 u32 mask
= params
->soc
.mask
;
313 u32 shift
= params
->shift
;
316 for (i
= 0; i
< params
->soc
.num_regs
; i
++, regs
+= cmpnt
->val_bytes
) {
317 regmap_read(ope
->mbdrc_regmap
, regs
, &data
[i
]);
319 data
[i
] = ((data
[i
] & mask
) >> shift
);
325 static int tegra210_mbdrc_band_params_put(struct snd_kcontrol
*kcontrol
,
326 struct snd_ctl_elem_value
*ucontrol
)
328 struct tegra_soc_bytes
*params
= (void *)kcontrol
->private_value
;
329 struct snd_soc_component
*cmpnt
= snd_soc_kcontrol_component(kcontrol
);
330 struct tegra210_ope
*ope
= snd_soc_component_get_drvdata(cmpnt
);
331 u32
*data
= (u32
*)ucontrol
->value
.bytes
.data
;
332 u32 regs
= params
->soc
.base
;
333 u32 mask
= params
->soc
.mask
;
334 u32 shift
= params
->shift
;
338 for (i
= 0; i
< params
->soc
.num_regs
; i
++, regs
+= cmpnt
->val_bytes
) {
341 regmap_update_bits_check(ope
->mbdrc_regmap
, regs
, mask
,
342 data
[i
] << shift
, &update
);
347 return change
? 1 : 0;
350 static int tegra210_mbdrc_threshold_get(struct snd_kcontrol
*kcontrol
,
351 struct snd_ctl_elem_value
*ucontrol
)
353 struct tegra_soc_bytes
*params
= (void *)kcontrol
->private_value
;
354 struct snd_soc_component
*cmpnt
= snd_soc_kcontrol_component(kcontrol
);
355 struct tegra210_ope
*ope
= snd_soc_component_get_drvdata(cmpnt
);
356 u32
*data
= (u32
*)ucontrol
->value
.bytes
.data
;
357 u32 regs
= params
->soc
.base
;
358 u32 num_regs
= params
->soc
.num_regs
;
362 for (i
= 0; i
< num_regs
; i
+= 4, regs
+= cmpnt
->val_bytes
) {
363 regmap_read(ope
->mbdrc_regmap
, regs
, &val
);
365 data
[i
] = (val
& TEGRA210_MBDRC_THRESH_1ST_MASK
) >>
366 TEGRA210_MBDRC_THRESH_1ST_SHIFT
;
367 data
[i
+ 1] = (val
& TEGRA210_MBDRC_THRESH_2ND_MASK
) >>
368 TEGRA210_MBDRC_THRESH_2ND_SHIFT
;
369 data
[i
+ 2] = (val
& TEGRA210_MBDRC_THRESH_3RD_MASK
) >>
370 TEGRA210_MBDRC_THRESH_3RD_SHIFT
;
371 data
[i
+ 3] = (val
& TEGRA210_MBDRC_THRESH_4TH_MASK
) >>
372 TEGRA210_MBDRC_THRESH_4TH_SHIFT
;
378 static int tegra210_mbdrc_threshold_put(struct snd_kcontrol
*kcontrol
,
379 struct snd_ctl_elem_value
*ucontrol
)
381 struct tegra_soc_bytes
*params
= (void *)kcontrol
->private_value
;
382 struct snd_soc_component
*cmpnt
= snd_soc_kcontrol_component(kcontrol
);
383 struct tegra210_ope
*ope
= snd_soc_component_get_drvdata(cmpnt
);
384 u32
*data
= (u32
*)ucontrol
->value
.bytes
.data
;
385 u32 regs
= params
->soc
.base
;
386 u32 num_regs
= params
->soc
.num_regs
;
390 for (i
= 0; i
< num_regs
; i
+= 4, regs
+= cmpnt
->val_bytes
) {
393 data
[i
] = (((data
[i
] >> TEGRA210_MBDRC_THRESH_1ST_SHIFT
) &
394 TEGRA210_MBDRC_THRESH_1ST_MASK
) |
395 ((data
[i
+ 1] >> TEGRA210_MBDRC_THRESH_2ND_SHIFT
) &
396 TEGRA210_MBDRC_THRESH_2ND_MASK
) |
397 ((data
[i
+ 2] >> TEGRA210_MBDRC_THRESH_3RD_SHIFT
) &
398 TEGRA210_MBDRC_THRESH_3RD_MASK
) |
399 ((data
[i
+ 3] >> TEGRA210_MBDRC_THRESH_4TH_SHIFT
) &
400 TEGRA210_MBDRC_THRESH_4TH_MASK
));
402 regmap_update_bits_check(ope
->mbdrc_regmap
, regs
, 0xffffffff,
408 return change
? 1 : 0;
411 static int tegra210_mbdrc_biquad_coeffs_get(struct snd_kcontrol
*kcontrol
,
412 struct snd_ctl_elem_value
*ucontrol
)
414 struct tegra_soc_bytes
*params
= (void *)kcontrol
->private_value
;
415 struct snd_soc_component
*cmpnt
= snd_soc_kcontrol_component(kcontrol
);
416 u32
*data
= (u32
*)ucontrol
->value
.bytes
.data
;
418 memset(data
, 0, params
->soc
.num_regs
* cmpnt
->val_bytes
);
423 static int tegra210_mbdrc_biquad_coeffs_put(struct snd_kcontrol
*kcontrol
,
424 struct snd_ctl_elem_value
*ucontrol
)
426 struct tegra_soc_bytes
*params
= (void *)kcontrol
->private_value
;
427 struct snd_soc_component
*cmpnt
= snd_soc_kcontrol_component(kcontrol
);
428 struct tegra210_ope
*ope
= snd_soc_component_get_drvdata(cmpnt
);
429 u32 reg_ctrl
= params
->soc
.base
;
430 u32 reg_data
= reg_ctrl
+ cmpnt
->val_bytes
;
431 u32
*data
= (u32
*)ucontrol
->value
.bytes
.data
;
433 tegra210_mbdrc_write_ram(ope
->mbdrc_regmap
, reg_ctrl
, reg_data
,
434 params
->shift
, data
, params
->soc
.num_regs
);
439 static int tegra210_mbdrc_param_info(struct snd_kcontrol
*kcontrol
,
440 struct snd_ctl_elem_info
*uinfo
)
442 struct soc_bytes
*params
= (void *)kcontrol
->private_value
;
444 uinfo
->type
= SNDRV_CTL_ELEM_TYPE_BYTES
;
445 uinfo
->count
= params
->num_regs
* sizeof(u32
);
450 static int tegra210_mbdrc_vol_get(struct snd_kcontrol
*kcontrol
,
451 struct snd_ctl_elem_value
*ucontrol
)
453 struct soc_mixer_control
*mc
=
454 (struct soc_mixer_control
*)kcontrol
->private_value
;
455 struct snd_soc_component
*cmpnt
= snd_soc_kcontrol_component(kcontrol
);
456 struct tegra210_ope
*ope
= snd_soc_component_get_drvdata(cmpnt
);
459 regmap_read(ope
->mbdrc_regmap
, mc
->reg
, &val
);
461 ucontrol
->value
.integer
.value
[0] =
462 ((val
>> mc
->shift
) - TEGRA210_MBDRC_MASTER_VOL_MIN
);
467 static int tegra210_mbdrc_vol_put(struct snd_kcontrol
*kcontrol
,
468 struct snd_ctl_elem_value
*ucontrol
)
470 struct soc_mixer_control
*mc
=
471 (struct soc_mixer_control
*)kcontrol
->private_value
;
472 struct snd_soc_component
*cmpnt
= snd_soc_kcontrol_component(kcontrol
);
473 struct tegra210_ope
*ope
= snd_soc_component_get_drvdata(cmpnt
);
474 int val
= ucontrol
->value
.integer
.value
[0];
477 val
+= TEGRA210_MBDRC_MASTER_VOL_MIN
;
479 regmap_update_bits_check(ope
->mbdrc_regmap
, mc
->reg
,
480 mc
->max
<< mc
->shift
, val
<< mc
->shift
,
483 regmap_read(ope
->mbdrc_regmap
, mc
->reg
, &val
);
485 return change
? 1 : 0;
488 static const char * const tegra210_mbdrc_mode_text
[] = {
489 "Bypass", "Fullband", "Dualband", "Multiband"
492 static const struct soc_enum tegra210_mbdrc_mode_enum
=
493 SOC_ENUM_SINGLE(TEGRA210_MBDRC_CFG
, TEGRA210_MBDRC_CFG_MBDRC_MODE_SHIFT
,
494 4, tegra210_mbdrc_mode_text
);
496 static const char * const tegra210_mbdrc_peak_rms_text
[] = {
500 static const struct soc_enum tegra210_mbdrc_peak_rms_enum
=
501 SOC_ENUM_SINGLE(TEGRA210_MBDRC_CFG
, TEGRA210_MBDRC_CFG_PEAK_RMS_SHIFT
,
502 2, tegra210_mbdrc_peak_rms_text
);
504 static const char * const tegra210_mbdrc_filter_structure_text
[] = {
505 "All-pass-tree", "Flexible"
508 static const struct soc_enum tegra210_mbdrc_filter_structure_enum
=
509 SOC_ENUM_SINGLE(TEGRA210_MBDRC_CFG
,
510 TEGRA210_MBDRC_CFG_FILTER_STRUCTURE_SHIFT
, 2,
511 tegra210_mbdrc_filter_structure_text
);
513 static const char * const tegra210_mbdrc_frame_size_text
[] = {
514 "N1", "N2", "N4", "N8", "N16", "N32", "N64"
517 static const struct soc_enum tegra210_mbdrc_frame_size_enum
=
518 SOC_ENUM_SINGLE(TEGRA210_MBDRC_CFG
, TEGRA210_MBDRC_CFG_FRAME_SIZE_SHIFT
,
519 7, tegra210_mbdrc_frame_size_text
);
521 #define TEGRA_MBDRC_BYTES_EXT(xname, xbase, xregs, xshift, xmask, xinfo) \
522 TEGRA_SOC_BYTES_EXT(xname, xbase, xregs, xshift, xmask, \
523 tegra210_mbdrc_band_params_get, \
524 tegra210_mbdrc_band_params_put, \
525 tegra210_mbdrc_param_info)
527 #define TEGRA_MBDRC_BAND_BYTES_EXT(xname, xbase, xshift, xmask, xinfo) \
528 TEGRA_MBDRC_BYTES_EXT(xname, xbase, TEGRA210_MBDRC_FILTER_COUNT, \
529 xshift, xmask, xinfo)
531 static const DECLARE_TLV_DB_MINMAX(mdbrc_vol_tlv
, -25600, 25500);
533 static const struct snd_kcontrol_new tegra210_mbdrc_controls
[] = {
534 SOC_ENUM_EXT("MBDRC Peak RMS Mode", tegra210_mbdrc_peak_rms_enum
,
535 tegra210_mbdrc_get_enum
, tegra210_mbdrc_put_enum
),
537 SOC_ENUM_EXT("MBDRC Filter Structure",
538 tegra210_mbdrc_filter_structure_enum
,
539 tegra210_mbdrc_get_enum
, tegra210_mbdrc_put_enum
),
541 SOC_ENUM_EXT("MBDRC Frame Size", tegra210_mbdrc_frame_size_enum
,
542 tegra210_mbdrc_get_enum
, tegra210_mbdrc_put_enum
),
544 SOC_ENUM_EXT("MBDRC Mode", tegra210_mbdrc_mode_enum
,
545 tegra210_mbdrc_get_enum
, tegra210_mbdrc_put_enum
),
547 SOC_SINGLE_EXT("MBDRC RMS Offset", TEGRA210_MBDRC_CFG
,
548 TEGRA210_MBDRC_CFG_RMS_OFFSET_SHIFT
, 0x1ff, 0,
549 tegra210_mbdrc_get
, tegra210_mbdrc_put
),
551 SOC_SINGLE_EXT("MBDRC Shift Control", TEGRA210_MBDRC_CFG
,
552 TEGRA210_MBDRC_CFG_SHIFT_CTRL_SHIFT
, 0x1f, 0,
553 tegra210_mbdrc_get
, tegra210_mbdrc_put
),
555 SOC_SINGLE_EXT("MBDRC Fast Attack Factor", TEGRA210_MBDRC_FAST_FACTOR
,
556 TEGRA210_MBDRC_FAST_FACTOR_ATTACK_SHIFT
, 0xffff, 0,
557 tegra210_mbdrc_get
, tegra210_mbdrc_put
),
559 SOC_SINGLE_EXT("MBDRC Fast Release Factor", TEGRA210_MBDRC_FAST_FACTOR
,
560 TEGRA210_MBDRC_FAST_FACTOR_RELEASE_SHIFT
, 0xffff, 0,
561 tegra210_mbdrc_get
, tegra210_mbdrc_put
),
563 SOC_SINGLE_RANGE_EXT_TLV("MBDRC Master Volume",
564 TEGRA210_MBDRC_MASTER_VOL
,
565 TEGRA210_MBDRC_MASTER_VOL_SHIFT
,
567 tegra210_mbdrc_vol_get
, tegra210_mbdrc_vol_put
,
570 TEGRA_SOC_BYTES_EXT("MBDRC IIR Stages", TEGRA210_MBDRC_IIR_CFG
,
571 TEGRA210_MBDRC_FILTER_COUNT
,
572 TEGRA210_MBDRC_IIR_CFG_NUM_STAGES_SHIFT
,
573 TEGRA210_MBDRC_IIR_CFG_NUM_STAGES_MASK
,
574 tegra210_mbdrc_band_params_get
,
575 tegra210_mbdrc_band_params_put
,
576 tegra210_mbdrc_param_info
),
578 TEGRA_SOC_BYTES_EXT("MBDRC In Attack Time Const", TEGRA210_MBDRC_IN_ATTACK
,
579 TEGRA210_MBDRC_FILTER_COUNT
,
580 TEGRA210_MBDRC_IN_ATTACK_TC_SHIFT
,
581 TEGRA210_MBDRC_IN_ATTACK_TC_MASK
,
582 tegra210_mbdrc_band_params_get
,
583 tegra210_mbdrc_band_params_put
,
584 tegra210_mbdrc_param_info
),
586 TEGRA_SOC_BYTES_EXT("MBDRC In Release Time Const", TEGRA210_MBDRC_IN_RELEASE
,
587 TEGRA210_MBDRC_FILTER_COUNT
,
588 TEGRA210_MBDRC_IN_RELEASE_TC_SHIFT
,
589 TEGRA210_MBDRC_IN_RELEASE_TC_MASK
,
590 tegra210_mbdrc_band_params_get
,
591 tegra210_mbdrc_band_params_put
,
592 tegra210_mbdrc_param_info
),
594 TEGRA_SOC_BYTES_EXT("MBDRC Fast Attack Time Const", TEGRA210_MBDRC_FAST_ATTACK
,
595 TEGRA210_MBDRC_FILTER_COUNT
,
596 TEGRA210_MBDRC_FAST_ATTACK_TC_SHIFT
,
597 TEGRA210_MBDRC_FAST_ATTACK_TC_MASK
,
598 tegra210_mbdrc_band_params_get
,
599 tegra210_mbdrc_band_params_put
,
600 tegra210_mbdrc_param_info
),
602 TEGRA_SOC_BYTES_EXT("MBDRC In Threshold", TEGRA210_MBDRC_IN_THRESHOLD
,
603 TEGRA210_MBDRC_FILTER_COUNT
* 4, 0, 0xffffffff,
604 tegra210_mbdrc_threshold_get
,
605 tegra210_mbdrc_threshold_put
,
606 tegra210_mbdrc_param_info
),
608 TEGRA_SOC_BYTES_EXT("MBDRC Out Threshold", TEGRA210_MBDRC_OUT_THRESHOLD
,
609 TEGRA210_MBDRC_FILTER_COUNT
* 4, 0, 0xffffffff,
610 tegra210_mbdrc_threshold_get
,
611 tegra210_mbdrc_threshold_put
,
612 tegra210_mbdrc_param_info
),
614 TEGRA_SOC_BYTES_EXT("MBDRC Ratio", TEGRA210_MBDRC_RATIO_1ST
,
615 TEGRA210_MBDRC_FILTER_COUNT
* 5,
616 TEGRA210_MBDRC_RATIO_1ST_SHIFT
, TEGRA210_MBDRC_RATIO_1ST_MASK
,
617 tegra210_mbdrc_band_params_get
,
618 tegra210_mbdrc_band_params_put
,
619 tegra210_mbdrc_param_info
),
621 TEGRA_SOC_BYTES_EXT("MBDRC Makeup Gain", TEGRA210_MBDRC_MAKEUP_GAIN
,
622 TEGRA210_MBDRC_FILTER_COUNT
,
623 TEGRA210_MBDRC_MAKEUP_GAIN_SHIFT
,
624 TEGRA210_MBDRC_MAKEUP_GAIN_MASK
,
625 tegra210_mbdrc_band_params_get
,
626 tegra210_mbdrc_band_params_put
,
627 tegra210_mbdrc_param_info
),
629 TEGRA_SOC_BYTES_EXT("MBDRC Init Gain", TEGRA210_MBDRC_INIT_GAIN
,
630 TEGRA210_MBDRC_FILTER_COUNT
,
631 TEGRA210_MBDRC_INIT_GAIN_SHIFT
,
632 TEGRA210_MBDRC_INIT_GAIN_MASK
,
633 tegra210_mbdrc_band_params_get
,
634 tegra210_mbdrc_band_params_put
,
635 tegra210_mbdrc_param_info
),
637 TEGRA_SOC_BYTES_EXT("MBDRC Attack Gain", TEGRA210_MBDRC_GAIN_ATTACK
,
638 TEGRA210_MBDRC_FILTER_COUNT
,
639 TEGRA210_MBDRC_GAIN_ATTACK_SHIFT
,
640 TEGRA210_MBDRC_GAIN_ATTACK_MASK
,
641 tegra210_mbdrc_band_params_get
,
642 tegra210_mbdrc_band_params_put
,
643 tegra210_mbdrc_param_info
),
645 TEGRA_SOC_BYTES_EXT("MBDRC Release Gain", TEGRA210_MBDRC_GAIN_RELEASE
,
646 TEGRA210_MBDRC_FILTER_COUNT
,
647 TEGRA210_MBDRC_GAIN_RELEASE_SHIFT
,
648 TEGRA210_MBDRC_GAIN_RELEASE_MASK
,
649 tegra210_mbdrc_band_params_get
,
650 tegra210_mbdrc_band_params_put
,
651 tegra210_mbdrc_param_info
),
653 TEGRA_SOC_BYTES_EXT("MBDRC Fast Release Gain",
654 TEGRA210_MBDRC_FAST_RELEASE
,
655 TEGRA210_MBDRC_FILTER_COUNT
,
656 TEGRA210_MBDRC_FAST_RELEASE_SHIFT
,
657 TEGRA210_MBDRC_FAST_RELEASE_MASK
,
658 tegra210_mbdrc_band_params_get
,
659 tegra210_mbdrc_band_params_put
,
660 tegra210_mbdrc_param_info
),
662 TEGRA_SOC_BYTES_EXT("MBDRC Low Band Biquad Coeffs",
663 TEGRA210_MBDRC_CFG_RAM_CTRL
,
664 TEGRA210_MBDRC_MAX_BIQUAD_STAGES
* 5, 0, 0xffffffff,
665 tegra210_mbdrc_biquad_coeffs_get
,
666 tegra210_mbdrc_biquad_coeffs_put
,
667 tegra210_mbdrc_param_info
),
669 TEGRA_SOC_BYTES_EXT("MBDRC Mid Band Biquad Coeffs",
670 TEGRA210_MBDRC_CFG_RAM_CTRL
+
671 TEGRA210_MBDRC_FILTER_PARAM_STRIDE
,
672 TEGRA210_MBDRC_MAX_BIQUAD_STAGES
* 5, 0, 0xffffffff,
673 tegra210_mbdrc_biquad_coeffs_get
,
674 tegra210_mbdrc_biquad_coeffs_put
,
675 tegra210_mbdrc_param_info
),
677 TEGRA_SOC_BYTES_EXT("MBDRC High Band Biquad Coeffs",
678 TEGRA210_MBDRC_CFG_RAM_CTRL
+
679 (TEGRA210_MBDRC_FILTER_PARAM_STRIDE
* 2),
680 TEGRA210_MBDRC_MAX_BIQUAD_STAGES
* 5, 0, 0xffffffff,
681 tegra210_mbdrc_biquad_coeffs_get
,
682 tegra210_mbdrc_biquad_coeffs_put
,
683 tegra210_mbdrc_param_info
),
686 static bool tegra210_mbdrc_wr_reg(struct device
*dev
, unsigned int reg
)
688 if (reg
>= TEGRA210_MBDRC_IIR_CFG
)
689 reg
-= ((reg
- TEGRA210_MBDRC_IIR_CFG
) %
690 (TEGRA210_MBDRC_FILTER_PARAM_STRIDE
*
691 TEGRA210_MBDRC_FILTER_COUNT
));
694 case TEGRA210_MBDRC_SOFT_RESET
:
695 case TEGRA210_MBDRC_CG
:
696 case TEGRA210_MBDRC_CFG
... TEGRA210_MBDRC_CFG_RAM_DATA
:
703 static bool tegra210_mbdrc_rd_reg(struct device
*dev
, unsigned int reg
)
705 if (tegra210_mbdrc_wr_reg(dev
, reg
))
708 if (reg
>= TEGRA210_MBDRC_IIR_CFG
)
709 reg
-= ((reg
- TEGRA210_MBDRC_IIR_CFG
) %
710 (TEGRA210_MBDRC_FILTER_PARAM_STRIDE
*
711 TEGRA210_MBDRC_FILTER_COUNT
));
714 case TEGRA210_MBDRC_STATUS
:
721 static bool tegra210_mbdrc_volatile_reg(struct device
*dev
, unsigned int reg
)
723 if (reg
>= TEGRA210_MBDRC_IIR_CFG
)
724 reg
-= ((reg
- TEGRA210_MBDRC_IIR_CFG
) %
725 (TEGRA210_MBDRC_FILTER_PARAM_STRIDE
*
726 TEGRA210_MBDRC_FILTER_COUNT
));
729 case TEGRA210_MBDRC_SOFT_RESET
:
730 case TEGRA210_MBDRC_STATUS
:
731 case TEGRA210_MBDRC_CFG_RAM_CTRL
:
732 case TEGRA210_MBDRC_CFG_RAM_DATA
:
739 static bool tegra210_mbdrc_precious_reg(struct device
*dev
, unsigned int reg
)
741 if (reg
>= TEGRA210_MBDRC_IIR_CFG
)
742 reg
-= ((reg
- TEGRA210_MBDRC_IIR_CFG
) %
743 (TEGRA210_MBDRC_FILTER_PARAM_STRIDE
*
744 TEGRA210_MBDRC_FILTER_COUNT
));
747 case TEGRA210_MBDRC_CFG_RAM_DATA
:
754 static const struct regmap_config tegra210_mbdrc_regmap_cfg
= {
759 .max_register
= TEGRA210_MBDRC_MAX_REG
,
760 .writeable_reg
= tegra210_mbdrc_wr_reg
,
761 .readable_reg
= tegra210_mbdrc_rd_reg
,
762 .volatile_reg
= tegra210_mbdrc_volatile_reg
,
763 .precious_reg
= tegra210_mbdrc_precious_reg
,
764 .reg_defaults
= tegra210_mbdrc_reg_defaults
,
765 .num_reg_defaults
= ARRAY_SIZE(tegra210_mbdrc_reg_defaults
),
766 .cache_type
= REGCACHE_FLAT
,
769 int tegra210_mbdrc_hw_params(struct snd_soc_component
*cmpnt
)
771 struct tegra210_ope
*ope
= snd_soc_component_get_drvdata(cmpnt
);
772 const struct tegra210_mbdrc_config
*conf
= &mbdrc_init_config
;
776 regmap_read(ope
->mbdrc_regmap
, TEGRA210_MBDRC_CFG
, &val
);
778 val
&= TEGRA210_MBDRC_CFG_MBDRC_MODE_MASK
;
780 if (val
== TEGRA210_MBDRC_CFG_MBDRC_MODE_BYPASS
)
783 for (i
= 0; i
< MBDRC_NUM_BAND
; i
++) {
784 const struct tegra210_mbdrc_band_params
*params
=
785 &conf
->band_params
[i
];
787 u32 reg_off
= i
* TEGRA210_MBDRC_FILTER_PARAM_STRIDE
;
789 tegra210_mbdrc_write_ram(ope
->mbdrc_regmap
,
790 reg_off
+ TEGRA210_MBDRC_CFG_RAM_CTRL
,
791 reg_off
+ TEGRA210_MBDRC_CFG_RAM_DATA
,
792 0, (u32
*)¶ms
->biquad_params
[0],
793 TEGRA210_MBDRC_MAX_BIQUAD_STAGES
* 5);
798 int tegra210_mbdrc_component_init(struct snd_soc_component
*cmpnt
)
800 struct tegra210_ope
*ope
= snd_soc_component_get_drvdata(cmpnt
);
801 const struct tegra210_mbdrc_config
*conf
= &mbdrc_init_config
;
805 pm_runtime_get_sync(cmpnt
->dev
);
807 /* Initialize MBDRC registers and AHUB RAM with default params */
808 regmap_update_bits(ope
->mbdrc_regmap
, TEGRA210_MBDRC_CFG
,
809 TEGRA210_MBDRC_CFG_MBDRC_MODE_MASK
,
810 conf
->mode
<< TEGRA210_MBDRC_CFG_MBDRC_MODE_SHIFT
);
812 regmap_update_bits(ope
->mbdrc_regmap
, TEGRA210_MBDRC_CFG
,
813 TEGRA210_MBDRC_CFG_RMS_OFFSET_MASK
,
814 conf
->rms_off
<< TEGRA210_MBDRC_CFG_RMS_OFFSET_SHIFT
);
816 regmap_update_bits(ope
->mbdrc_regmap
, TEGRA210_MBDRC_CFG
,
817 TEGRA210_MBDRC_CFG_PEAK_RMS_MASK
,
818 conf
->peak_rms_mode
<< TEGRA210_MBDRC_CFG_PEAK_RMS_SHIFT
);
820 regmap_update_bits(ope
->mbdrc_regmap
, TEGRA210_MBDRC_CFG
,
821 TEGRA210_MBDRC_CFG_FILTER_STRUCTURE_MASK
,
822 conf
->filter_structure
<<
823 TEGRA210_MBDRC_CFG_FILTER_STRUCTURE_SHIFT
);
825 regmap_update_bits(ope
->mbdrc_regmap
, TEGRA210_MBDRC_CFG
,
826 TEGRA210_MBDRC_CFG_SHIFT_CTRL_MASK
,
827 conf
->shift_ctrl
<< TEGRA210_MBDRC_CFG_SHIFT_CTRL_SHIFT
);
829 regmap_update_bits(ope
->mbdrc_regmap
, TEGRA210_MBDRC_CFG
,
830 TEGRA210_MBDRC_CFG_FRAME_SIZE_MASK
,
831 __ffs(conf
->frame_size
) <<
832 TEGRA210_MBDRC_CFG_FRAME_SIZE_SHIFT
);
834 regmap_update_bits(ope
->mbdrc_regmap
, TEGRA210_MBDRC_CHANNEL_MASK
,
835 TEGRA210_MBDRC_CHANNEL_MASK_MASK
,
836 conf
->channel_mask
<< TEGRA210_MBDRC_CHANNEL_MASK_SHIFT
);
838 regmap_update_bits(ope
->mbdrc_regmap
, TEGRA210_MBDRC_FAST_FACTOR
,
839 TEGRA210_MBDRC_FAST_FACTOR_ATTACK_MASK
,
840 conf
->fa_factor
<< TEGRA210_MBDRC_FAST_FACTOR_ATTACK_SHIFT
);
842 regmap_update_bits(ope
->mbdrc_regmap
, TEGRA210_MBDRC_FAST_FACTOR
,
843 TEGRA210_MBDRC_FAST_FACTOR_ATTACK_MASK
,
844 conf
->fr_factor
<< TEGRA210_MBDRC_FAST_FACTOR_ATTACK_SHIFT
);
846 for (i
= 0; i
< MBDRC_NUM_BAND
; i
++) {
847 const struct tegra210_mbdrc_band_params
*params
=
848 &conf
->band_params
[i
];
849 u32 reg_off
= i
* TEGRA210_MBDRC_FILTER_PARAM_STRIDE
;
851 regmap_update_bits(ope
->mbdrc_regmap
,
852 reg_off
+ TEGRA210_MBDRC_IIR_CFG
,
853 TEGRA210_MBDRC_IIR_CFG_NUM_STAGES_MASK
,
854 params
->iir_stages
<<
855 TEGRA210_MBDRC_IIR_CFG_NUM_STAGES_SHIFT
);
857 regmap_update_bits(ope
->mbdrc_regmap
,
858 reg_off
+ TEGRA210_MBDRC_IN_ATTACK
,
859 TEGRA210_MBDRC_IN_ATTACK_TC_MASK
,
860 params
->in_attack_tc
<<
861 TEGRA210_MBDRC_IN_ATTACK_TC_SHIFT
);
863 regmap_update_bits(ope
->mbdrc_regmap
,
864 reg_off
+ TEGRA210_MBDRC_IN_RELEASE
,
865 TEGRA210_MBDRC_IN_RELEASE_TC_MASK
,
866 params
->in_release_tc
<<
867 TEGRA210_MBDRC_IN_RELEASE_TC_SHIFT
);
869 regmap_update_bits(ope
->mbdrc_regmap
,
870 reg_off
+ TEGRA210_MBDRC_FAST_ATTACK
,
871 TEGRA210_MBDRC_FAST_ATTACK_TC_MASK
,
872 params
->fast_attack_tc
<<
873 TEGRA210_MBDRC_FAST_ATTACK_TC_SHIFT
);
875 val
= (((params
->in_threshold
[0] >>
876 TEGRA210_MBDRC_THRESH_1ST_SHIFT
) &
877 TEGRA210_MBDRC_THRESH_1ST_MASK
) |
878 ((params
->in_threshold
[1] >>
879 TEGRA210_MBDRC_THRESH_2ND_SHIFT
) &
880 TEGRA210_MBDRC_THRESH_2ND_MASK
) |
881 ((params
->in_threshold
[2] >>
882 TEGRA210_MBDRC_THRESH_3RD_SHIFT
) &
883 TEGRA210_MBDRC_THRESH_3RD_MASK
) |
884 ((params
->in_threshold
[3] >>
885 TEGRA210_MBDRC_THRESH_4TH_SHIFT
) &
886 TEGRA210_MBDRC_THRESH_4TH_MASK
));
888 regmap_update_bits(ope
->mbdrc_regmap
,
889 reg_off
+ TEGRA210_MBDRC_IN_THRESHOLD
,
892 val
= (((params
->out_threshold
[0] >>
893 TEGRA210_MBDRC_THRESH_1ST_SHIFT
) &
894 TEGRA210_MBDRC_THRESH_1ST_MASK
) |
895 ((params
->out_threshold
[1] >>
896 TEGRA210_MBDRC_THRESH_2ND_SHIFT
) &
897 TEGRA210_MBDRC_THRESH_2ND_MASK
) |
898 ((params
->out_threshold
[2] >>
899 TEGRA210_MBDRC_THRESH_3RD_SHIFT
) &
900 TEGRA210_MBDRC_THRESH_3RD_MASK
) |
901 ((params
->out_threshold
[3] >>
902 TEGRA210_MBDRC_THRESH_4TH_SHIFT
) &
903 TEGRA210_MBDRC_THRESH_4TH_MASK
));
905 regmap_update_bits(ope
->mbdrc_regmap
,
906 reg_off
+ TEGRA210_MBDRC_OUT_THRESHOLD
,
909 regmap_update_bits(ope
->mbdrc_regmap
,
910 reg_off
+ TEGRA210_MBDRC_RATIO_1ST
,
911 TEGRA210_MBDRC_RATIO_1ST_MASK
,
912 params
->ratio
[0] << TEGRA210_MBDRC_RATIO_1ST_SHIFT
);
914 regmap_update_bits(ope
->mbdrc_regmap
,
915 reg_off
+ TEGRA210_MBDRC_RATIO_2ND
,
916 TEGRA210_MBDRC_RATIO_2ND_MASK
,
917 params
->ratio
[1] << TEGRA210_MBDRC_RATIO_2ND_SHIFT
);
919 regmap_update_bits(ope
->mbdrc_regmap
,
920 reg_off
+ TEGRA210_MBDRC_RATIO_3RD
,
921 TEGRA210_MBDRC_RATIO_3RD_MASK
,
922 params
->ratio
[2] << TEGRA210_MBDRC_RATIO_3RD_SHIFT
);
924 regmap_update_bits(ope
->mbdrc_regmap
,
925 reg_off
+ TEGRA210_MBDRC_RATIO_4TH
,
926 TEGRA210_MBDRC_RATIO_4TH_MASK
,
927 params
->ratio
[3] << TEGRA210_MBDRC_RATIO_4TH_SHIFT
);
929 regmap_update_bits(ope
->mbdrc_regmap
,
930 reg_off
+ TEGRA210_MBDRC_RATIO_5TH
,
931 TEGRA210_MBDRC_RATIO_5TH_MASK
,
932 params
->ratio
[4] << TEGRA210_MBDRC_RATIO_5TH_SHIFT
);
934 regmap_update_bits(ope
->mbdrc_regmap
,
935 reg_off
+ TEGRA210_MBDRC_MAKEUP_GAIN
,
936 TEGRA210_MBDRC_MAKEUP_GAIN_MASK
,
937 params
->makeup_gain
<<
938 TEGRA210_MBDRC_MAKEUP_GAIN_SHIFT
);
940 regmap_update_bits(ope
->mbdrc_regmap
,
941 reg_off
+ TEGRA210_MBDRC_INIT_GAIN
,
942 TEGRA210_MBDRC_INIT_GAIN_MASK
,
944 TEGRA210_MBDRC_INIT_GAIN_SHIFT
);
946 regmap_update_bits(ope
->mbdrc_regmap
,
947 reg_off
+ TEGRA210_MBDRC_GAIN_ATTACK
,
948 TEGRA210_MBDRC_GAIN_ATTACK_MASK
,
949 params
->gain_attack_tc
<<
950 TEGRA210_MBDRC_GAIN_ATTACK_SHIFT
);
952 regmap_update_bits(ope
->mbdrc_regmap
,
953 reg_off
+ TEGRA210_MBDRC_GAIN_RELEASE
,
954 TEGRA210_MBDRC_GAIN_RELEASE_MASK
,
955 params
->gain_release_tc
<<
956 TEGRA210_MBDRC_GAIN_RELEASE_SHIFT
);
958 regmap_update_bits(ope
->mbdrc_regmap
,
959 reg_off
+ TEGRA210_MBDRC_FAST_RELEASE
,
960 TEGRA210_MBDRC_FAST_RELEASE_MASK
,
961 params
->fast_release_tc
<<
962 TEGRA210_MBDRC_FAST_RELEASE_SHIFT
);
964 tegra210_mbdrc_write_ram(ope
->mbdrc_regmap
,
965 reg_off
+ TEGRA210_MBDRC_CFG_RAM_CTRL
,
966 reg_off
+ TEGRA210_MBDRC_CFG_RAM_DATA
, 0,
967 (u32
*)¶ms
->biquad_params
[0],
968 TEGRA210_MBDRC_MAX_BIQUAD_STAGES
* 5);
971 pm_runtime_put_sync(cmpnt
->dev
);
973 snd_soc_add_component_controls(cmpnt
, tegra210_mbdrc_controls
,
974 ARRAY_SIZE(tegra210_mbdrc_controls
));
979 int tegra210_mbdrc_regmap_init(struct platform_device
*pdev
)
981 struct device
*dev
= &pdev
->dev
;
982 struct tegra210_ope
*ope
= dev_get_drvdata(dev
);
983 struct device_node
*child
;
988 child
= of_get_child_by_name(dev
->of_node
, "dynamic-range-compressor");
992 err
= of_address_to_resource(child
, 0, &mem
);
995 dev_err(dev
, "fail to get MBDRC resource\n");
999 mem
.flags
= IORESOURCE_MEM
;
1000 regs
= devm_ioremap_resource(dev
, &mem
);
1002 return PTR_ERR(regs
);
1004 ope
->mbdrc_regmap
= devm_regmap_init_mmio(dev
, regs
,
1005 &tegra210_mbdrc_regmap_cfg
);
1006 if (IS_ERR(ope
->mbdrc_regmap
)) {
1007 dev_err(dev
, "regmap init failed\n");
1008 return PTR_ERR(ope
->mbdrc_regmap
);
1011 regcache_cache_only(ope
->mbdrc_regmap
, true);