1// SPDX-License-Identifier: GPL-2.0-only
2//
3// tegra210_mbdrc.c - Tegra210 MBDRC driver
4//
5// Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved.
6
7#include <linux/device.h>
8#include <linux/io.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>
16
17#include "tegra210_mbdrc.h"
18#include "tegra210_ope.h"
19
20#define MBDRC_FILTER_REG(reg, id) \
21 ((reg) + ((id) * TEGRA210_MBDRC_FILTER_PARAM_STRIDE))
22
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}
41
42static 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},
46
47 MBDRC_FILTER_REG_DEFAULTS(0),
48 MBDRC_FILTER_REG_DEFAULTS(1),
49 MBDRC_FILTER_REG_DEFAULTS(2),
50};
51
52/* Default MBDRC parameters */
53static const struct tegra210_mbdrc_config mbdrc_init_config = {
54 .mode = 0, /* Bypass */
55 .rms_off = 48,
56 .peak_rms_mode = 1, /* PEAK */
57 .filter_structure = 0, /* All-pass tree */
58 .shift_ctrl = 30,
59 .frame_size = 32,
60 .channel_mask = 0x3,
61 .fa_factor = 2048,
62 .fr_factor = 14747,
63
64 .band_params[MBDRC_LOW_BAND] = {
65 .band = MBDRC_LOW_BAND,
66 .iir_stages = 5,
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},
73 .makeup_gain = 4,
74 .gain_init = 419430,
75 .gain_attack_tc = 14268942,
76 .gain_release_tc = 1440547090,
77 .fast_release_tc = 2147480170,
78
79 .biquad_params = {
80 /*
81 * Gains:
82 *
83 * b0, b1, a0,
84 * a1, a2,
85 */
86
87 /* Band-0 */
88 961046798, -2030431983, 1073741824,
89 2030431983, -961046798,
90 /* Band-1 */
91 1030244425, -2099481453, 1073741824,
92 2099481453, -1030244425,
93 /* Band-2 */
94 1067169294, -2136327263, 1073741824,
95 2136327263, -1067169294,
96 /* Band-3 */
97 434951949, -1306567134, 1073741824,
98 1306567134, -434951949,
99 /* Band-4 */
100 780656019, -1605955641, 1073741824,
101 1605955641, -780656019,
102 /* Band-5 */
103 1024497031, -1817128152, 1073741824,
104 1817128152, -1024497031,
105 /* Band-6 */
106 1073741824, 0, 0,
107 0, 0,
108 /* Band-7 */
109 1073741824, 0, 0,
110 0, 0,
111 }
112 },
113
114 .band_params[MBDRC_MID_BAND] = {
115 .band = MBDRC_MID_BAND,
116 .iir_stages = 5,
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},
123 .makeup_gain = 6,
124 .gain_init = 419430,
125 .gain_attack_tc = 4766887,
126 .gain_release_tc = 1044928780,
127 .fast_release_tc = 2147480170,
128
129 .biquad_params = {
130 /*
131 * Gains:
132 *
133 * b0, b1, a0,
134 * a1, a2,
135 */
136
137 /* Band-0 */
138 -1005668963, 1073741824, 0,
139 1005668963, 0,
140 /* Band-1 */
141 998437058, -2067742187, 1073741824,
142 2067742187, -998437058,
143 /* Band-2 */
144 1051963422, -2121153948, 1073741824,
145 2121153948, -1051963422,
146 /* Band-3 */
147 434951949, -1306567134, 1073741824,
148 1306567134, -434951949,
149 /* Band-4 */
150 780656019, -1605955641, 1073741824,
151 1605955641, -780656019,
152 /* Band-5 */
153 1024497031, -1817128152, 1073741824,
154 1817128152, -1024497031,
155 /* Band-6 */
156 1073741824, 0, 0,
157 0, 0,
158 /* Band-7 */
159 1073741824, 0, 0,
160 0, 0,
161 }
162 },
163
164 .band_params[MBDRC_HIGH_BAND] = {
165 .band = MBDRC_HIGH_BAND,
166 .iir_stages = 5,
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},
173 .makeup_gain = 6,
174 .gain_init = 419430,
175 .gain_attack_tc = 4766887,
176 .gain_release_tc = 1044928780,
177 .fast_release_tc = 2147480170,
178
179 .biquad_params = {
180 /*
181 * Gains:
182 *
183 * b0, b1, a0,
184 * a1, a2,
185 */
186
187 /* Band-0 */
188 1073741824, 0, 0,
189 0, 0,
190 /* Band-1 */
191 1073741824, 0, 0,
192 0, 0,
193 /* Band-2 */
194 1073741824, 0, 0,
195 0, 0,
196 /* Band-3 */
197 -619925131, 1073741824, 0,
198 619925131, 0,
199 /* Band-4 */
200 606839335, -1455425976, 1073741824,
201 1455425976, -606839335,
202 /* Band-5 */
203 917759617, -1724690840, 1073741824,
204 1724690840, -917759617,
205 /* Band-6 */
206 1073741824, 0, 0,
207 0, 0,
208 /* Band-7 */
209 1073741824, 0, 0,
210 0, 0,
211 }
212 }
213};
214
215static 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)
218{
219 unsigned int val;
220 unsigned int i;
221
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;
226
227 regmap_write(map: regmap, reg: reg_ctrl, val);
228
229 for (i = 0; i < size; i++)
230 regmap_write(map: regmap, reg: reg_data, val: data[i]);
231}
232
233static int tegra210_mbdrc_get(struct snd_kcontrol *kcontrol,
234 struct snd_ctl_elem_value *ucontrol)
235{
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(c: cmpnt);
240 unsigned int val;
241
242 regmap_read(map: ope->mbdrc_regmap, reg: mc->reg, val: &val);
243
244 ucontrol->value.integer.value[0] = (val >> mc->shift) & mc->max;
245
246 return 0;
247}
248
249static int tegra210_mbdrc_put(struct snd_kcontrol *kcontrol,
250 struct snd_ctl_elem_value *ucontrol)
251{
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(c: cmpnt);
256 unsigned int val = ucontrol->value.integer.value[0];
257 bool change = false;
258
259 val = val << mc->shift;
260
261 regmap_update_bits_check(map: ope->mbdrc_regmap, reg: mc->reg,
262 mask: (mc->max << mc->shift), val, change: &change);
263
264 return change ? 1 : 0;
265}
266
267static int tegra210_mbdrc_get_enum(struct snd_kcontrol *kcontrol,
268 struct snd_ctl_elem_value *ucontrol)
269{
270 struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
271 struct tegra210_ope *ope = snd_soc_component_get_drvdata(c: cmpnt);
272 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
273 unsigned int val;
274
275 regmap_read(map: ope->mbdrc_regmap, reg: e->reg, val: &val);
276
277 ucontrol->value.enumerated.item[0] = (val >> e->shift_l) & e->mask;
278
279 return 0;
280}
281
282static int tegra210_mbdrc_put_enum(struct snd_kcontrol *kcontrol,
283 struct snd_ctl_elem_value *ucontrol)
284{
285 struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
286 struct tegra210_ope *ope = snd_soc_component_get_drvdata(c: cmpnt);
287 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
288 bool change = false;
289 unsigned int val;
290 unsigned int mask;
291
292 if (ucontrol->value.enumerated.item[0] > e->items - 1)
293 return -EINVAL;
294
295 val = ucontrol->value.enumerated.item[0] << e->shift_l;
296 mask = e->mask << e->shift_l;
297
298 regmap_update_bits_check(map: ope->mbdrc_regmap, reg: e->reg, mask, val,
299 change: &change);
300
301 return change ? 1 : 0;
302}
303
304static int tegra210_mbdrc_band_params_get(struct snd_kcontrol *kcontrol,
305 struct snd_ctl_elem_value *ucontrol)
306{
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(c: 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;
314 unsigned int i;
315
316 for (i = 0; i < params->soc.num_regs; i++, regs += cmpnt->val_bytes) {
317 regmap_read(map: ope->mbdrc_regmap, reg: regs, val: &data[i]);
318
319 data[i] = ((data[i] & mask) >> shift);
320 }
321
322 return 0;
323}
324
325static int tegra210_mbdrc_band_params_put(struct snd_kcontrol *kcontrol,
326 struct snd_ctl_elem_value *ucontrol)
327{
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(c: 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;
335 bool change = false;
336 unsigned int i;
337
338 for (i = 0; i < params->soc.num_regs; i++, regs += cmpnt->val_bytes) {
339 bool update = false;
340
341 regmap_update_bits_check(map: ope->mbdrc_regmap, reg: regs, mask,
342 val: data[i] << shift, change: &update);
343
344 change |= update;
345 }
346
347 return change ? 1 : 0;
348}
349
350static int tegra210_mbdrc_threshold_get(struct snd_kcontrol *kcontrol,
351 struct snd_ctl_elem_value *ucontrol)
352{
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(c: cmpnt);
356 u32 *data = (u32 *)ucontrol->value.bytes.data;
357 u32 regs = params->soc.base;
358 u32 num_regs = params->soc.num_regs;
359 u32 val;
360 unsigned int i;
361
362 for (i = 0; i < num_regs; i += 4, regs += cmpnt->val_bytes) {
363 regmap_read(map: ope->mbdrc_regmap, reg: regs, val: &val);
364
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;
373 }
374
375 return 0;
376}
377
378static int tegra210_mbdrc_threshold_put(struct snd_kcontrol *kcontrol,
379 struct snd_ctl_elem_value *ucontrol)
380{
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(c: cmpnt);
384 u32 *data = (u32 *)ucontrol->value.bytes.data;
385 u32 regs = params->soc.base;
386 u32 num_regs = params->soc.num_regs;
387 bool change = false;
388 unsigned int i;
389
390 for (i = 0; i < num_regs; i += 4, regs += cmpnt->val_bytes) {
391 bool update = false;
392
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));
401
402 regmap_update_bits_check(map: ope->mbdrc_regmap, reg: regs, mask: 0xffffffff,
403 val: data[i], change: &update);
404
405 change |= update;
406 }
407
408 return change ? 1 : 0;
409}
410
411static int tegra210_mbdrc_biquad_coeffs_get(struct snd_kcontrol *kcontrol,
412 struct snd_ctl_elem_value *ucontrol)
413{
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;
417
418 memset(data, 0, params->soc.num_regs * cmpnt->val_bytes);
419
420 return 0;
421}
422
423static int tegra210_mbdrc_biquad_coeffs_put(struct snd_kcontrol *kcontrol,
424 struct snd_ctl_elem_value *ucontrol)
425{
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(c: 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;
432
433 tegra210_mbdrc_write_ram(regmap: ope->mbdrc_regmap, reg_ctrl, reg_data,
434 ram_offset: params->shift, data, size: params->soc.num_regs);
435
436 return 1;
437}
438
439static int tegra210_mbdrc_param_info(struct snd_kcontrol *kcontrol,
440 struct snd_ctl_elem_info *uinfo)
441{
442 struct soc_bytes *params = (void *)kcontrol->private_value;
443
444 uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
445 uinfo->count = params->num_regs * sizeof(u32);
446
447 return 0;
448}
449
450static int tegra210_mbdrc_vol_get(struct snd_kcontrol *kcontrol,
451 struct snd_ctl_elem_value *ucontrol)
452{
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(c: cmpnt);
457 int val;
458
459 regmap_read(map: ope->mbdrc_regmap, reg: mc->reg, val: &val);
460
461 ucontrol->value.integer.value[0] =
462 ((val >> mc->shift) - TEGRA210_MBDRC_MASTER_VOL_MIN);
463
464 return 0;
465}
466
467static int tegra210_mbdrc_vol_put(struct snd_kcontrol *kcontrol,
468 struct snd_ctl_elem_value *ucontrol)
469{
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(c: cmpnt);
474 int val = ucontrol->value.integer.value[0];
475 bool change = false;
476
477 val += TEGRA210_MBDRC_MASTER_VOL_MIN;
478
479 regmap_update_bits_check(map: ope->mbdrc_regmap, reg: mc->reg,
480 mask: mc->max << mc->shift, val: val << mc->shift,
481 change: &change);
482
483 regmap_read(map: ope->mbdrc_regmap, reg: mc->reg, val: &val);
484
485 return change ? 1 : 0;
486}
487
488static const char * const tegra210_mbdrc_mode_text[] = {
489 "Bypass", "Fullband", "Dualband", "Multiband"
490};
491
492static 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);
495
496static const char * const tegra210_mbdrc_peak_rms_text[] = {
497 "Peak", "RMS"
498};
499
500static 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);
503
504static const char * const tegra210_mbdrc_filter_structure_text[] = {
505 "All-pass-tree", "Flexible"
506};
507
508static 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);
512
513static const char * const tegra210_mbdrc_frame_size_text[] = {
514 "N1", "N2", "N4", "N8", "N16", "N32", "N64"
515};
516
517static 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);
520
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)
526
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)
530
531static const DECLARE_TLV_DB_MINMAX(mdbrc_vol_tlv, -25600, 25500);
532
533static 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),
536
537 SOC_ENUM_EXT("MBDRC Filter Structure",
538 tegra210_mbdrc_filter_structure_enum,
539 tegra210_mbdrc_get_enum, tegra210_mbdrc_put_enum),
540
541 SOC_ENUM_EXT("MBDRC Frame Size", tegra210_mbdrc_frame_size_enum,
542 tegra210_mbdrc_get_enum, tegra210_mbdrc_put_enum),
543
544 SOC_ENUM_EXT("MBDRC Mode", tegra210_mbdrc_mode_enum,
545 tegra210_mbdrc_get_enum, tegra210_mbdrc_put_enum),
546
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),
550
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),
554
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),
558
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),
562
563 SOC_SINGLE_RANGE_EXT_TLV("MBDRC Master Volume",
564 TEGRA210_MBDRC_MASTER_VOL,
565 TEGRA210_MBDRC_MASTER_VOL_SHIFT,
566 0, 0x1ff, 0,
567 tegra210_mbdrc_vol_get, tegra210_mbdrc_vol_put,
568 mdbrc_vol_tlv),
569
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),
577
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),
585
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),
593
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),
601
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),
607
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),
613
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),
620
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),
628
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),
636
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),
644
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),
652
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),
661
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),
668
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),
676
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),
684};
685
686static bool tegra210_mbdrc_wr_reg(struct device *dev, unsigned int reg)
687{
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));
692
693 switch (reg) {
694 case TEGRA210_MBDRC_SOFT_RESET:
695 case TEGRA210_MBDRC_CG:
696 case TEGRA210_MBDRC_CFG ... TEGRA210_MBDRC_CFG_RAM_DATA:
697 return true;
698 default:
699 return false;
700 }
701}
702
703static bool tegra210_mbdrc_rd_reg(struct device *dev, unsigned int reg)
704{
705 if (tegra210_mbdrc_wr_reg(dev, reg))
706 return true;
707
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));
712
713 switch (reg) {
714 case TEGRA210_MBDRC_STATUS:
715 return true;
716 default:
717 return false;
718 }
719}
720
721static bool tegra210_mbdrc_volatile_reg(struct device *dev, unsigned int reg)
722{
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));
727
728 switch (reg) {
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:
733 return true;
734 default:
735 return false;
736 }
737}
738
739static bool tegra210_mbdrc_precious_reg(struct device *dev, unsigned int reg)
740{
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));
745
746 switch (reg) {
747 case TEGRA210_MBDRC_CFG_RAM_DATA:
748 return true;
749 default:
750 return false;
751 }
752}
753
754static const struct regmap_config tegra210_mbdrc_regmap_cfg = {
755 .name = "mbdrc",
756 .reg_bits = 32,
757 .reg_stride = 4,
758 .val_bits = 32,
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,
767};
768
769int tegra210_mbdrc_hw_params(struct snd_soc_component *cmpnt)
770{
771 struct tegra210_ope *ope = snd_soc_component_get_drvdata(c: cmpnt);
772 const struct tegra210_mbdrc_config *conf = &mbdrc_init_config;
773 u32 val = 0;
774 unsigned int i;
775
776 regmap_read(map: ope->mbdrc_regmap, TEGRA210_MBDRC_CFG, val: &val);
777
778 val &= TEGRA210_MBDRC_CFG_MBDRC_MODE_MASK;
779
780 if (val == TEGRA210_MBDRC_CFG_MBDRC_MODE_BYPASS)
781 return 0;
782
783 for (i = 0; i < MBDRC_NUM_BAND; i++) {
784 const struct tegra210_mbdrc_band_params *params =
785 &conf->band_params[i];
786
787 u32 reg_off = i * TEGRA210_MBDRC_FILTER_PARAM_STRIDE;
788
789 tegra210_mbdrc_write_ram(regmap: ope->mbdrc_regmap,
790 reg_ctrl: reg_off + TEGRA210_MBDRC_CFG_RAM_CTRL,
791 reg_data: reg_off + TEGRA210_MBDRC_CFG_RAM_DATA,
792 ram_offset: 0, data: (u32 *)&params->biquad_params[0],
793 TEGRA210_MBDRC_MAX_BIQUAD_STAGES * 5);
794 }
795 return 0;
796}
797
798int tegra210_mbdrc_component_init(struct snd_soc_component *cmpnt)
799{
800 struct tegra210_ope *ope = snd_soc_component_get_drvdata(c: cmpnt);
801 const struct tegra210_mbdrc_config *conf = &mbdrc_init_config;
802 unsigned int i;
803 u32 val;
804
805 pm_runtime_get_sync(dev: cmpnt->dev);
806
807 /* Initialize MBDRC registers and AHUB RAM with default params */
808 regmap_update_bits(map: ope->mbdrc_regmap, TEGRA210_MBDRC_CFG,
809 TEGRA210_MBDRC_CFG_MBDRC_MODE_MASK,
810 val: conf->mode << TEGRA210_MBDRC_CFG_MBDRC_MODE_SHIFT);
811
812 regmap_update_bits(map: ope->mbdrc_regmap, TEGRA210_MBDRC_CFG,
813 TEGRA210_MBDRC_CFG_RMS_OFFSET_MASK,
814 val: conf->rms_off << TEGRA210_MBDRC_CFG_RMS_OFFSET_SHIFT);
815
816 regmap_update_bits(map: ope->mbdrc_regmap, TEGRA210_MBDRC_CFG,
817 TEGRA210_MBDRC_CFG_PEAK_RMS_MASK,
818 val: conf->peak_rms_mode << TEGRA210_MBDRC_CFG_PEAK_RMS_SHIFT);
819
820 regmap_update_bits(map: ope->mbdrc_regmap, TEGRA210_MBDRC_CFG,
821 TEGRA210_MBDRC_CFG_FILTER_STRUCTURE_MASK,
822 val: conf->filter_structure <<
823 TEGRA210_MBDRC_CFG_FILTER_STRUCTURE_SHIFT);
824
825 regmap_update_bits(map: ope->mbdrc_regmap, TEGRA210_MBDRC_CFG,
826 TEGRA210_MBDRC_CFG_SHIFT_CTRL_MASK,
827 val: conf->shift_ctrl << TEGRA210_MBDRC_CFG_SHIFT_CTRL_SHIFT);
828
829 regmap_update_bits(map: 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);
833
834 regmap_update_bits(map: ope->mbdrc_regmap, TEGRA210_MBDRC_CHANNEL_MASK,
835 TEGRA210_MBDRC_CHANNEL_MASK_MASK,
836 val: conf->channel_mask << TEGRA210_MBDRC_CHANNEL_MASK_SHIFT);
837
838 regmap_update_bits(map: ope->mbdrc_regmap, TEGRA210_MBDRC_FAST_FACTOR,
839 TEGRA210_MBDRC_FAST_FACTOR_ATTACK_MASK,
840 val: conf->fa_factor << TEGRA210_MBDRC_FAST_FACTOR_ATTACK_SHIFT);
841
842 regmap_update_bits(map: ope->mbdrc_regmap, TEGRA210_MBDRC_FAST_FACTOR,
843 TEGRA210_MBDRC_FAST_FACTOR_ATTACK_MASK,
844 val: conf->fr_factor << TEGRA210_MBDRC_FAST_FACTOR_ATTACK_SHIFT);
845
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;
850
851 regmap_update_bits(map: ope->mbdrc_regmap,
852 reg: reg_off + TEGRA210_MBDRC_IIR_CFG,
853 TEGRA210_MBDRC_IIR_CFG_NUM_STAGES_MASK,
854 val: params->iir_stages <<
855 TEGRA210_MBDRC_IIR_CFG_NUM_STAGES_SHIFT);
856
857 regmap_update_bits(map: ope->mbdrc_regmap,
858 reg: reg_off + TEGRA210_MBDRC_IN_ATTACK,
859 TEGRA210_MBDRC_IN_ATTACK_TC_MASK,
860 val: params->in_attack_tc <<
861 TEGRA210_MBDRC_IN_ATTACK_TC_SHIFT);
862
863 regmap_update_bits(map: ope->mbdrc_regmap,
864 reg: reg_off + TEGRA210_MBDRC_IN_RELEASE,
865 TEGRA210_MBDRC_IN_RELEASE_TC_MASK,
866 val: params->in_release_tc <<
867 TEGRA210_MBDRC_IN_RELEASE_TC_SHIFT);
868
869 regmap_update_bits(map: ope->mbdrc_regmap,
870 reg: reg_off + TEGRA210_MBDRC_FAST_ATTACK,
871 TEGRA210_MBDRC_FAST_ATTACK_TC_MASK,
872 val: params->fast_attack_tc <<
873 TEGRA210_MBDRC_FAST_ATTACK_TC_SHIFT);
874
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));
887
888 regmap_update_bits(map: ope->mbdrc_regmap,
889 reg: reg_off + TEGRA210_MBDRC_IN_THRESHOLD,
890 mask: 0xffffffff, val);
891
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));
904
905 regmap_update_bits(map: ope->mbdrc_regmap,
906 reg: reg_off + TEGRA210_MBDRC_OUT_THRESHOLD,
907 mask: 0xffffffff, val);
908
909 regmap_update_bits(map: ope->mbdrc_regmap,
910 reg: reg_off + TEGRA210_MBDRC_RATIO_1ST,
911 TEGRA210_MBDRC_RATIO_1ST_MASK,
912 val: params->ratio[0] << TEGRA210_MBDRC_RATIO_1ST_SHIFT);
913
914 regmap_update_bits(map: ope->mbdrc_regmap,
915 reg: reg_off + TEGRA210_MBDRC_RATIO_2ND,
916 TEGRA210_MBDRC_RATIO_2ND_MASK,
917 val: params->ratio[1] << TEGRA210_MBDRC_RATIO_2ND_SHIFT);
918
919 regmap_update_bits(map: ope->mbdrc_regmap,
920 reg: reg_off + TEGRA210_MBDRC_RATIO_3RD,
921 TEGRA210_MBDRC_RATIO_3RD_MASK,
922 val: params->ratio[2] << TEGRA210_MBDRC_RATIO_3RD_SHIFT);
923
924 regmap_update_bits(map: ope->mbdrc_regmap,
925 reg: reg_off + TEGRA210_MBDRC_RATIO_4TH,
926 TEGRA210_MBDRC_RATIO_4TH_MASK,
927 val: params->ratio[3] << TEGRA210_MBDRC_RATIO_4TH_SHIFT);
928
929 regmap_update_bits(map: ope->mbdrc_regmap,
930 reg: reg_off + TEGRA210_MBDRC_RATIO_5TH,
931 TEGRA210_MBDRC_RATIO_5TH_MASK,
932 val: params->ratio[4] << TEGRA210_MBDRC_RATIO_5TH_SHIFT);
933
934 regmap_update_bits(map: ope->mbdrc_regmap,
935 reg: reg_off + TEGRA210_MBDRC_MAKEUP_GAIN,
936 TEGRA210_MBDRC_MAKEUP_GAIN_MASK,
937 val: params->makeup_gain <<
938 TEGRA210_MBDRC_MAKEUP_GAIN_SHIFT);
939
940 regmap_update_bits(map: ope->mbdrc_regmap,
941 reg: reg_off + TEGRA210_MBDRC_INIT_GAIN,
942 TEGRA210_MBDRC_INIT_GAIN_MASK,
943 val: params->gain_init <<
944 TEGRA210_MBDRC_INIT_GAIN_SHIFT);
945
946 regmap_update_bits(map: ope->mbdrc_regmap,
947 reg: reg_off + TEGRA210_MBDRC_GAIN_ATTACK,
948 TEGRA210_MBDRC_GAIN_ATTACK_MASK,
949 val: params->gain_attack_tc <<
950 TEGRA210_MBDRC_GAIN_ATTACK_SHIFT);
951
952 regmap_update_bits(map: ope->mbdrc_regmap,
953 reg: reg_off + TEGRA210_MBDRC_GAIN_RELEASE,
954 TEGRA210_MBDRC_GAIN_RELEASE_MASK,
955 val: params->gain_release_tc <<
956 TEGRA210_MBDRC_GAIN_RELEASE_SHIFT);
957
958 regmap_update_bits(map: ope->mbdrc_regmap,
959 reg: reg_off + TEGRA210_MBDRC_FAST_RELEASE,
960 TEGRA210_MBDRC_FAST_RELEASE_MASK,
961 val: params->fast_release_tc <<
962 TEGRA210_MBDRC_FAST_RELEASE_SHIFT);
963
964 tegra210_mbdrc_write_ram(regmap: ope->mbdrc_regmap,
965 reg_ctrl: reg_off + TEGRA210_MBDRC_CFG_RAM_CTRL,
966 reg_data: reg_off + TEGRA210_MBDRC_CFG_RAM_DATA, ram_offset: 0,
967 data: (u32 *)&params->biquad_params[0],
968 TEGRA210_MBDRC_MAX_BIQUAD_STAGES * 5);
969 }
970
971 pm_runtime_put_sync(dev: cmpnt->dev);
972
973 snd_soc_add_component_controls(component: cmpnt, controls: tegra210_mbdrc_controls,
974 ARRAY_SIZE(tegra210_mbdrc_controls));
975
976 return 0;
977}
978
979int tegra210_mbdrc_regmap_init(struct platform_device *pdev)
980{
981 struct device *dev = &pdev->dev;
982 struct tegra210_ope *ope = dev_get_drvdata(dev);
983 struct device_node *child;
984 struct resource mem;
985 void __iomem *regs;
986 int err;
987
988 child = of_get_child_by_name(node: dev->of_node, name: "dynamic-range-compressor");
989 if (!child)
990 return -ENODEV;
991
992 err = of_address_to_resource(dev: child, index: 0, r: &mem);
993 of_node_put(node: child);
994 if (err < 0) {
995 dev_err(dev, "fail to get MBDRC resource\n");
996 return err;
997 }
998
999 mem.flags = IORESOURCE_MEM;
1000 regs = devm_ioremap_resource(dev, res: &mem);
1001 if (IS_ERR(ptr: regs))
1002 return PTR_ERR(ptr: regs);
1003
1004 ope->mbdrc_regmap = devm_regmap_init_mmio(dev, regs,
1005 &tegra210_mbdrc_regmap_cfg);
1006 if (IS_ERR(ptr: ope->mbdrc_regmap)) {
1007 dev_err(dev, "regmap init failed\n");
1008 return PTR_ERR(ptr: ope->mbdrc_regmap);
1009 }
1010
1011 regcache_cache_only(map: ope->mbdrc_regmap, enable: true);
1012
1013 return 0;
1014}
1015

source code of linux/sound/soc/tegra/tegra210_mbdrc.c