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_PARAM_REG_DEFAULTS(reg, val) \
24 { MBDRC_FILTER_REG(reg, 0), val}, \
25 { MBDRC_FILTER_REG(reg, 1), val}, \
26 { MBDRC_FILTER_REG(reg, 2), val}
27
28 static const struct reg_default tegra210_mbdrc_reg_defaults[] = {
29 { TEGRA210_MBDRC_CFG, 0x0030de51},
30 { TEGRA210_MBDRC_CHANNEL_MASK, 0x00000003},
31 { TEGRA210_MBDRC_FAST_FACTOR, 0x30000800},
32
33 MBDRC_FILTER_PARAM_REG_DEFAULTS(TEGRA210_MBDRC_IIR_CFG, 0x00000005),
34 MBDRC_FILTER_PARAM_REG_DEFAULTS(TEGRA210_MBDRC_IN_ATTACK, 0x3e48590c),
35 MBDRC_FILTER_PARAM_REG_DEFAULTS(TEGRA210_MBDRC_IN_RELEASE, 0x08414e9f),
36 MBDRC_FILTER_PARAM_REG_DEFAULTS(TEGRA210_MBDRC_FAST_ATTACK, 0x7fffffff),
37 MBDRC_FILTER_PARAM_REG_DEFAULTS(TEGRA210_MBDRC_IN_THRESHOLD, 0x06145082),
38 MBDRC_FILTER_PARAM_REG_DEFAULTS(TEGRA210_MBDRC_OUT_THRESHOLD, 0x060d379b),
39 MBDRC_FILTER_PARAM_REG_DEFAULTS(TEGRA210_MBDRC_RATIO_1ST, 0x0000a000),
40 MBDRC_FILTER_PARAM_REG_DEFAULTS(TEGRA210_MBDRC_RATIO_2ND, 0x00002000),
41 MBDRC_FILTER_PARAM_REG_DEFAULTS(TEGRA210_MBDRC_RATIO_3RD, 0x00000b33),
42 MBDRC_FILTER_PARAM_REG_DEFAULTS(TEGRA210_MBDRC_RATIO_4TH, 0x00000800),
43 MBDRC_FILTER_PARAM_REG_DEFAULTS(TEGRA210_MBDRC_RATIO_5TH, 0x0000019a),
44 MBDRC_FILTER_PARAM_REG_DEFAULTS(TEGRA210_MBDRC_MAKEUP_GAIN, 0x00000002),
45 MBDRC_FILTER_PARAM_REG_DEFAULTS(TEGRA210_MBDRC_INIT_GAIN, 0x00066666),
46 MBDRC_FILTER_PARAM_REG_DEFAULTS(TEGRA210_MBDRC_GAIN_ATTACK, 0x00d9ba0e),
47 MBDRC_FILTER_PARAM_REG_DEFAULTS(TEGRA210_MBDRC_GAIN_RELEASE, 0x3e48590c),
48 MBDRC_FILTER_PARAM_REG_DEFAULTS(TEGRA210_MBDRC_FAST_RELEASE, 0x7ffff26a),
49 MBDRC_FILTER_PARAM_REG_DEFAULTS(TEGRA210_MBDRC_CFG_RAM_CTRL, 0x4000),
50 };
51
52 /* Default MBDRC parameters */
53 static 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
tegra210_mbdrc_write_ram(struct regmap * regmap,unsigned int reg_ctrl,unsigned int reg_data,unsigned int ram_offset,unsigned int * data,size_t size)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)
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(regmap, reg_ctrl, val);
228
229 for (i = 0; i < size; i++)
230 regmap_write(regmap, reg_data, data[i]);
231 }
232
tegra210_mbdrc_get(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)233 static 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_kcontrol_chip(kcontrol);
239 struct tegra210_ope *ope = snd_soc_component_get_drvdata(cmpnt);
240 unsigned int val;
241
242 regmap_read(ope->mbdrc_regmap, mc->reg, &val);
243
244 ucontrol->value.integer.value[0] = (val >> mc->shift) & mc->max;
245
246 return 0;
247 }
248
tegra210_mbdrc_put(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)249 static 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_kcontrol_chip(kcontrol);
255 struct tegra210_ope *ope = snd_soc_component_get_drvdata(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(ope->mbdrc_regmap, mc->reg,
262 (mc->max << mc->shift), val, &change);
263
264 return change ? 1 : 0;
265 }
266
tegra210_mbdrc_get_enum(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)267 static int tegra210_mbdrc_get_enum(struct snd_kcontrol *kcontrol,
268 struct snd_ctl_elem_value *ucontrol)
269 {
270 struct snd_soc_component *cmpnt = snd_kcontrol_chip(kcontrol);
271 struct tegra210_ope *ope = snd_soc_component_get_drvdata(cmpnt);
272 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
273 unsigned int val;
274
275 regmap_read(ope->mbdrc_regmap, e->reg, &val);
276
277 ucontrol->value.enumerated.item[0] = (val >> e->shift_l) & e->mask;
278
279 return 0;
280 }
281
tegra210_mbdrc_put_enum(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)282 static int tegra210_mbdrc_put_enum(struct snd_kcontrol *kcontrol,
283 struct snd_ctl_elem_value *ucontrol)
284 {
285 struct snd_soc_component *cmpnt = snd_kcontrol_chip(kcontrol);
286 struct tegra210_ope *ope = snd_soc_component_get_drvdata(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(ope->mbdrc_regmap, e->reg, mask, val,
299 &change);
300
301 return change ? 1 : 0;
302 }
303
tegra210_mbdrc_band_params_get(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)304 static 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_kcontrol_chip(kcontrol);
309 struct tegra210_ope *ope = snd_soc_component_get_drvdata(cmpnt);
310 int val_bytes = snd_soc_component_regmap_val_bytes(cmpnt);
311 u32 *data = (u32 *)ucontrol->value.bytes.data;
312 u32 regs = params->soc.base;
313 u32 mask = params->soc.mask;
314 u32 shift = params->shift;
315 unsigned int i;
316
317 for (i = 0; i < params->soc.num_regs; i++, regs += val_bytes) {
318 regmap_read(ope->mbdrc_regmap, regs, &data[i]);
319
320 data[i] = ((data[i] & mask) >> shift);
321 }
322
323 return 0;
324 }
325
tegra210_mbdrc_band_params_put(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)326 static int tegra210_mbdrc_band_params_put(struct snd_kcontrol *kcontrol,
327 struct snd_ctl_elem_value *ucontrol)
328 {
329 struct tegra_soc_bytes *params = (void *)kcontrol->private_value;
330 struct snd_soc_component *cmpnt = snd_kcontrol_chip(kcontrol);
331 struct tegra210_ope *ope = snd_soc_component_get_drvdata(cmpnt);
332 int val_bytes = snd_soc_component_regmap_val_bytes(cmpnt);
333 u32 *data = (u32 *)ucontrol->value.bytes.data;
334 u32 regs = params->soc.base;
335 u32 mask = params->soc.mask;
336 u32 shift = params->shift;
337 bool change = false;
338 unsigned int i;
339
340 for (i = 0; i < params->soc.num_regs; i++, regs += val_bytes) {
341 bool update = false;
342
343 regmap_update_bits_check(ope->mbdrc_regmap, regs, mask,
344 data[i] << shift, &update);
345
346 change |= update;
347 }
348
349 return change ? 1 : 0;
350 }
351
tegra210_mbdrc_threshold_get(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)352 static int tegra210_mbdrc_threshold_get(struct snd_kcontrol *kcontrol,
353 struct snd_ctl_elem_value *ucontrol)
354 {
355 struct tegra_soc_bytes *params = (void *)kcontrol->private_value;
356 struct snd_soc_component *cmpnt = snd_kcontrol_chip(kcontrol);
357 struct tegra210_ope *ope = snd_soc_component_get_drvdata(cmpnt);
358 int val_bytes = snd_soc_component_regmap_val_bytes(cmpnt);
359 u32 *data = (u32 *)ucontrol->value.bytes.data;
360 u32 regs = params->soc.base;
361 u32 num_regs = params->soc.num_regs;
362 u32 val;
363 unsigned int i;
364
365 for (i = 0; i < num_regs; i += 4, regs += val_bytes) {
366 regmap_read(ope->mbdrc_regmap, regs, &val);
367
368 data[i] = (val & TEGRA210_MBDRC_THRESH_1ST_MASK) >>
369 TEGRA210_MBDRC_THRESH_1ST_SHIFT;
370 data[i + 1] = (val & TEGRA210_MBDRC_THRESH_2ND_MASK) >>
371 TEGRA210_MBDRC_THRESH_2ND_SHIFT;
372 data[i + 2] = (val & TEGRA210_MBDRC_THRESH_3RD_MASK) >>
373 TEGRA210_MBDRC_THRESH_3RD_SHIFT;
374 data[i + 3] = (val & TEGRA210_MBDRC_THRESH_4TH_MASK) >>
375 TEGRA210_MBDRC_THRESH_4TH_SHIFT;
376 }
377
378 return 0;
379 }
380
tegra210_mbdrc_threshold_put(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)381 static int tegra210_mbdrc_threshold_put(struct snd_kcontrol *kcontrol,
382 struct snd_ctl_elem_value *ucontrol)
383 {
384 struct tegra_soc_bytes *params = (void *)kcontrol->private_value;
385 struct snd_soc_component *cmpnt = snd_kcontrol_chip(kcontrol);
386 struct tegra210_ope *ope = snd_soc_component_get_drvdata(cmpnt);
387 int val_bytes = snd_soc_component_regmap_val_bytes(cmpnt);
388 u32 *data = (u32 *)ucontrol->value.bytes.data;
389 u32 regs = params->soc.base;
390 u32 num_regs = params->soc.num_regs;
391 bool change = false;
392 unsigned int i;
393
394 for (i = 0; i < num_regs; i += 4, regs += val_bytes) {
395 bool update = false;
396
397 data[i] = (((data[i] >> TEGRA210_MBDRC_THRESH_1ST_SHIFT) &
398 TEGRA210_MBDRC_THRESH_1ST_MASK) |
399 ((data[i + 1] >> TEGRA210_MBDRC_THRESH_2ND_SHIFT) &
400 TEGRA210_MBDRC_THRESH_2ND_MASK) |
401 ((data[i + 2] >> TEGRA210_MBDRC_THRESH_3RD_SHIFT) &
402 TEGRA210_MBDRC_THRESH_3RD_MASK) |
403 ((data[i + 3] >> TEGRA210_MBDRC_THRESH_4TH_SHIFT) &
404 TEGRA210_MBDRC_THRESH_4TH_MASK));
405
406 regmap_update_bits_check(ope->mbdrc_regmap, regs, 0xffffffff,
407 data[i], &update);
408
409 change |= update;
410 }
411
412 return change ? 1 : 0;
413 }
414
tegra210_mbdrc_biquad_coeffs_get(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)415 static int tegra210_mbdrc_biquad_coeffs_get(struct snd_kcontrol *kcontrol,
416 struct snd_ctl_elem_value *ucontrol)
417 {
418 struct tegra_soc_bytes *params = (void *)kcontrol->private_value;
419 struct snd_soc_component *cmpnt = snd_kcontrol_chip(kcontrol);
420 int val_bytes = snd_soc_component_regmap_val_bytes(cmpnt);
421 u32 *data = (u32 *)ucontrol->value.bytes.data;
422
423 memset(data, 0, params->soc.num_regs * val_bytes);
424
425 return 0;
426 }
427
tegra210_mbdrc_biquad_coeffs_put(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)428 static int tegra210_mbdrc_biquad_coeffs_put(struct snd_kcontrol *kcontrol,
429 struct snd_ctl_elem_value *ucontrol)
430 {
431 struct tegra_soc_bytes *params = (void *)kcontrol->private_value;
432 struct snd_soc_component *cmpnt = snd_kcontrol_chip(kcontrol);
433 struct tegra210_ope *ope = snd_soc_component_get_drvdata(cmpnt);
434 int val_bytes = snd_soc_component_regmap_val_bytes(cmpnt);
435 u32 reg_ctrl = params->soc.base;
436 u32 reg_data = reg_ctrl + val_bytes;
437 u32 *data = (u32 *)ucontrol->value.bytes.data;
438
439 tegra210_mbdrc_write_ram(ope->mbdrc_regmap, reg_ctrl, reg_data,
440 params->shift, data, params->soc.num_regs);
441
442 return 1;
443 }
444
tegra210_mbdrc_param_info(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_info * uinfo)445 static int tegra210_mbdrc_param_info(struct snd_kcontrol *kcontrol,
446 struct snd_ctl_elem_info *uinfo)
447 {
448 struct soc_bytes *params = (void *)kcontrol->private_value;
449
450 uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
451 uinfo->count = params->num_regs * sizeof(u32);
452
453 return 0;
454 }
455
tegra210_mbdrc_vol_get(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)456 static int tegra210_mbdrc_vol_get(struct snd_kcontrol *kcontrol,
457 struct snd_ctl_elem_value *ucontrol)
458 {
459 struct soc_mixer_control *mc =
460 (struct soc_mixer_control *)kcontrol->private_value;
461 struct snd_soc_component *cmpnt = snd_kcontrol_chip(kcontrol);
462 struct tegra210_ope *ope = snd_soc_component_get_drvdata(cmpnt);
463 int val;
464
465 regmap_read(ope->mbdrc_regmap, mc->reg, &val);
466
467 ucontrol->value.integer.value[0] =
468 ((val >> mc->shift) - TEGRA210_MBDRC_MASTER_VOL_MIN);
469
470 return 0;
471 }
472
tegra210_mbdrc_vol_put(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)473 static int tegra210_mbdrc_vol_put(struct snd_kcontrol *kcontrol,
474 struct snd_ctl_elem_value *ucontrol)
475 {
476 struct soc_mixer_control *mc =
477 (struct soc_mixer_control *)kcontrol->private_value;
478 struct snd_soc_component *cmpnt = snd_kcontrol_chip(kcontrol);
479 struct tegra210_ope *ope = snd_soc_component_get_drvdata(cmpnt);
480 int val = ucontrol->value.integer.value[0];
481 bool change = false;
482
483 val += TEGRA210_MBDRC_MASTER_VOL_MIN;
484
485 regmap_update_bits_check(ope->mbdrc_regmap, mc->reg,
486 mc->max << mc->shift, val << mc->shift,
487 &change);
488
489 regmap_read(ope->mbdrc_regmap, mc->reg, &val);
490
491 return change ? 1 : 0;
492 }
493
494 static const char * const tegra210_mbdrc_mode_text[] = {
495 "Bypass", "Fullband", "Dualband", "Multiband"
496 };
497
498 static const struct soc_enum tegra210_mbdrc_mode_enum =
499 SOC_ENUM_SINGLE(TEGRA210_MBDRC_CFG, TEGRA210_MBDRC_CFG_MBDRC_MODE_SHIFT,
500 4, tegra210_mbdrc_mode_text);
501
502 static const char * const tegra210_mbdrc_peak_rms_text[] = {
503 "Peak", "RMS"
504 };
505
506 static const struct soc_enum tegra210_mbdrc_peak_rms_enum =
507 SOC_ENUM_SINGLE(TEGRA210_MBDRC_CFG, TEGRA210_MBDRC_CFG_PEAK_RMS_SHIFT,
508 2, tegra210_mbdrc_peak_rms_text);
509
510 static const char * const tegra210_mbdrc_filter_structure_text[] = {
511 "All-pass-tree", "Flexible"
512 };
513
514 static const struct soc_enum tegra210_mbdrc_filter_structure_enum =
515 SOC_ENUM_SINGLE(TEGRA210_MBDRC_CFG,
516 TEGRA210_MBDRC_CFG_FILTER_STRUCTURE_SHIFT, 2,
517 tegra210_mbdrc_filter_structure_text);
518
519 static const char * const tegra210_mbdrc_frame_size_text[] = {
520 "N1", "N2", "N4", "N8", "N16", "N32", "N64"
521 };
522
523 static const struct soc_enum tegra210_mbdrc_frame_size_enum =
524 SOC_ENUM_SINGLE(TEGRA210_MBDRC_CFG, TEGRA210_MBDRC_CFG_FRAME_SIZE_SHIFT,
525 7, tegra210_mbdrc_frame_size_text);
526
527 #define TEGRA_MBDRC_BYTES_EXT(xname, xbase, xregs, xshift, xmask, xinfo) \
528 TEGRA_SOC_BYTES_EXT(xname, xbase, xregs, xshift, xmask, \
529 tegra210_mbdrc_band_params_get, \
530 tegra210_mbdrc_band_params_put, \
531 tegra210_mbdrc_param_info)
532
533 #define TEGRA_MBDRC_BAND_BYTES_EXT(xname, xbase, xshift, xmask, xinfo) \
534 TEGRA_MBDRC_BYTES_EXT(xname, xbase, TEGRA210_MBDRC_FILTER_COUNT, \
535 xshift, xmask, xinfo)
536
537 static const DECLARE_TLV_DB_MINMAX(mdbrc_vol_tlv, -25600, 25500);
538
539 static const struct snd_kcontrol_new tegra210_mbdrc_controls[] = {
540 SOC_ENUM_EXT("MBDRC Peak RMS Mode", tegra210_mbdrc_peak_rms_enum,
541 tegra210_mbdrc_get_enum, tegra210_mbdrc_put_enum),
542
543 SOC_ENUM_EXT("MBDRC Filter Structure",
544 tegra210_mbdrc_filter_structure_enum,
545 tegra210_mbdrc_get_enum, tegra210_mbdrc_put_enum),
546
547 SOC_ENUM_EXT("MBDRC Frame Size", tegra210_mbdrc_frame_size_enum,
548 tegra210_mbdrc_get_enum, tegra210_mbdrc_put_enum),
549
550 SOC_ENUM_EXT("MBDRC Mode", tegra210_mbdrc_mode_enum,
551 tegra210_mbdrc_get_enum, tegra210_mbdrc_put_enum),
552
553 SOC_SINGLE_EXT("MBDRC RMS Offset", TEGRA210_MBDRC_CFG,
554 TEGRA210_MBDRC_CFG_RMS_OFFSET_SHIFT, 0x1ff, 0,
555 tegra210_mbdrc_get, tegra210_mbdrc_put),
556
557 SOC_SINGLE_EXT("MBDRC Shift Control", TEGRA210_MBDRC_CFG,
558 TEGRA210_MBDRC_CFG_SHIFT_CTRL_SHIFT, 0x1f, 0,
559 tegra210_mbdrc_get, tegra210_mbdrc_put),
560
561 SOC_SINGLE_EXT("MBDRC Fast Attack Factor", TEGRA210_MBDRC_FAST_FACTOR,
562 TEGRA210_MBDRC_FAST_FACTOR_ATTACK_SHIFT, 0xffff, 0,
563 tegra210_mbdrc_get, tegra210_mbdrc_put),
564
565 SOC_SINGLE_EXT("MBDRC Fast Release Factor", TEGRA210_MBDRC_FAST_FACTOR,
566 TEGRA210_MBDRC_FAST_FACTOR_RELEASE_SHIFT, 0xffff, 0,
567 tegra210_mbdrc_get, tegra210_mbdrc_put),
568
569 SOC_SINGLE_RANGE_EXT_TLV("MBDRC Master Volume",
570 TEGRA210_MBDRC_MASTER_VOL,
571 TEGRA210_MBDRC_MASTER_VOL_SHIFT,
572 0, 0x1ff, 0,
573 tegra210_mbdrc_vol_get, tegra210_mbdrc_vol_put,
574 mdbrc_vol_tlv),
575
576 TEGRA_SOC_BYTES_EXT("MBDRC IIR Stages", TEGRA210_MBDRC_IIR_CFG,
577 TEGRA210_MBDRC_FILTER_COUNT,
578 TEGRA210_MBDRC_IIR_CFG_NUM_STAGES_SHIFT,
579 TEGRA210_MBDRC_IIR_CFG_NUM_STAGES_MASK,
580 tegra210_mbdrc_band_params_get,
581 tegra210_mbdrc_band_params_put,
582 tegra210_mbdrc_param_info),
583
584 TEGRA_SOC_BYTES_EXT("MBDRC In Attack Time Const", TEGRA210_MBDRC_IN_ATTACK,
585 TEGRA210_MBDRC_FILTER_COUNT,
586 TEGRA210_MBDRC_IN_ATTACK_TC_SHIFT,
587 TEGRA210_MBDRC_IN_ATTACK_TC_MASK,
588 tegra210_mbdrc_band_params_get,
589 tegra210_mbdrc_band_params_put,
590 tegra210_mbdrc_param_info),
591
592 TEGRA_SOC_BYTES_EXT("MBDRC In Release Time Const", TEGRA210_MBDRC_IN_RELEASE,
593 TEGRA210_MBDRC_FILTER_COUNT,
594 TEGRA210_MBDRC_IN_RELEASE_TC_SHIFT,
595 TEGRA210_MBDRC_IN_RELEASE_TC_MASK,
596 tegra210_mbdrc_band_params_get,
597 tegra210_mbdrc_band_params_put,
598 tegra210_mbdrc_param_info),
599
600 TEGRA_SOC_BYTES_EXT("MBDRC Fast Attack Time Const", TEGRA210_MBDRC_FAST_ATTACK,
601 TEGRA210_MBDRC_FILTER_COUNT,
602 TEGRA210_MBDRC_FAST_ATTACK_TC_SHIFT,
603 TEGRA210_MBDRC_FAST_ATTACK_TC_MASK,
604 tegra210_mbdrc_band_params_get,
605 tegra210_mbdrc_band_params_put,
606 tegra210_mbdrc_param_info),
607
608 TEGRA_SOC_BYTES_EXT("MBDRC In Threshold", TEGRA210_MBDRC_IN_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 Out Threshold", TEGRA210_MBDRC_OUT_THRESHOLD,
615 TEGRA210_MBDRC_FILTER_COUNT * 4, 0, 0xffffffff,
616 tegra210_mbdrc_threshold_get,
617 tegra210_mbdrc_threshold_put,
618 tegra210_mbdrc_param_info),
619
620 TEGRA_SOC_BYTES_EXT("MBDRC Ratio", TEGRA210_MBDRC_RATIO_1ST,
621 TEGRA210_MBDRC_FILTER_COUNT * 5,
622 TEGRA210_MBDRC_RATIO_1ST_SHIFT, TEGRA210_MBDRC_RATIO_1ST_MASK,
623 tegra210_mbdrc_band_params_get,
624 tegra210_mbdrc_band_params_put,
625 tegra210_mbdrc_param_info),
626
627 TEGRA_SOC_BYTES_EXT("MBDRC Makeup Gain", TEGRA210_MBDRC_MAKEUP_GAIN,
628 TEGRA210_MBDRC_FILTER_COUNT,
629 TEGRA210_MBDRC_MAKEUP_GAIN_SHIFT,
630 TEGRA210_MBDRC_MAKEUP_GAIN_MASK,
631 tegra210_mbdrc_band_params_get,
632 tegra210_mbdrc_band_params_put,
633 tegra210_mbdrc_param_info),
634
635 TEGRA_SOC_BYTES_EXT("MBDRC Init Gain", TEGRA210_MBDRC_INIT_GAIN,
636 TEGRA210_MBDRC_FILTER_COUNT,
637 TEGRA210_MBDRC_INIT_GAIN_SHIFT,
638 TEGRA210_MBDRC_INIT_GAIN_MASK,
639 tegra210_mbdrc_band_params_get,
640 tegra210_mbdrc_band_params_put,
641 tegra210_mbdrc_param_info),
642
643 TEGRA_SOC_BYTES_EXT("MBDRC Attack Gain", TEGRA210_MBDRC_GAIN_ATTACK,
644 TEGRA210_MBDRC_FILTER_COUNT,
645 TEGRA210_MBDRC_GAIN_ATTACK_SHIFT,
646 TEGRA210_MBDRC_GAIN_ATTACK_MASK,
647 tegra210_mbdrc_band_params_get,
648 tegra210_mbdrc_band_params_put,
649 tegra210_mbdrc_param_info),
650
651 TEGRA_SOC_BYTES_EXT("MBDRC Release Gain", TEGRA210_MBDRC_GAIN_RELEASE,
652 TEGRA210_MBDRC_FILTER_COUNT,
653 TEGRA210_MBDRC_GAIN_RELEASE_SHIFT,
654 TEGRA210_MBDRC_GAIN_RELEASE_MASK,
655 tegra210_mbdrc_band_params_get,
656 tegra210_mbdrc_band_params_put,
657 tegra210_mbdrc_param_info),
658
659 TEGRA_SOC_BYTES_EXT("MBDRC Fast Release Gain",
660 TEGRA210_MBDRC_FAST_RELEASE,
661 TEGRA210_MBDRC_FILTER_COUNT,
662 TEGRA210_MBDRC_FAST_RELEASE_SHIFT,
663 TEGRA210_MBDRC_FAST_RELEASE_MASK,
664 tegra210_mbdrc_band_params_get,
665 tegra210_mbdrc_band_params_put,
666 tegra210_mbdrc_param_info),
667
668 TEGRA_SOC_BYTES_EXT("MBDRC Low Band Biquad Coeffs",
669 TEGRA210_MBDRC_CFG_RAM_CTRL,
670 TEGRA210_MBDRC_MAX_BIQUAD_STAGES * 5, 0, 0xffffffff,
671 tegra210_mbdrc_biquad_coeffs_get,
672 tegra210_mbdrc_biquad_coeffs_put,
673 tegra210_mbdrc_param_info),
674
675 TEGRA_SOC_BYTES_EXT("MBDRC Mid Band Biquad Coeffs",
676 TEGRA210_MBDRC_CFG_RAM_CTRL +
677 TEGRA210_MBDRC_FILTER_PARAM_STRIDE,
678 TEGRA210_MBDRC_MAX_BIQUAD_STAGES * 5, 0, 0xffffffff,
679 tegra210_mbdrc_biquad_coeffs_get,
680 tegra210_mbdrc_biquad_coeffs_put,
681 tegra210_mbdrc_param_info),
682
683 TEGRA_SOC_BYTES_EXT("MBDRC High Band Biquad Coeffs",
684 TEGRA210_MBDRC_CFG_RAM_CTRL +
685 (TEGRA210_MBDRC_FILTER_PARAM_STRIDE * 2),
686 TEGRA210_MBDRC_MAX_BIQUAD_STAGES * 5, 0, 0xffffffff,
687 tegra210_mbdrc_biquad_coeffs_get,
688 tegra210_mbdrc_biquad_coeffs_put,
689 tegra210_mbdrc_param_info),
690 };
691
tegra210_mbdrc_wr_reg(struct device * dev,unsigned int reg)692 static bool tegra210_mbdrc_wr_reg(struct device *dev, unsigned int reg)
693 {
694 if (reg >= TEGRA210_MBDRC_IIR_CFG)
695 reg -= ((reg - TEGRA210_MBDRC_IIR_CFG) %
696 (TEGRA210_MBDRC_FILTER_PARAM_STRIDE *
697 TEGRA210_MBDRC_FILTER_COUNT));
698
699 switch (reg) {
700 case TEGRA210_MBDRC_SOFT_RESET:
701 case TEGRA210_MBDRC_CG:
702 case TEGRA210_MBDRC_CFG ... TEGRA210_MBDRC_CFG_RAM_DATA:
703 return true;
704 default:
705 return false;
706 }
707 }
708
tegra210_mbdrc_rd_reg(struct device * dev,unsigned int reg)709 static bool tegra210_mbdrc_rd_reg(struct device *dev, unsigned int reg)
710 {
711 if (tegra210_mbdrc_wr_reg(dev, reg))
712 return true;
713
714 if (reg >= TEGRA210_MBDRC_IIR_CFG)
715 reg -= ((reg - TEGRA210_MBDRC_IIR_CFG) %
716 (TEGRA210_MBDRC_FILTER_PARAM_STRIDE *
717 TEGRA210_MBDRC_FILTER_COUNT));
718
719 switch (reg) {
720 case TEGRA210_MBDRC_STATUS:
721 return true;
722 default:
723 return false;
724 }
725 }
726
tegra210_mbdrc_volatile_reg(struct device * dev,unsigned int reg)727 static bool tegra210_mbdrc_volatile_reg(struct device *dev, unsigned int reg)
728 {
729 if (reg >= TEGRA210_MBDRC_IIR_CFG)
730 reg -= ((reg - TEGRA210_MBDRC_IIR_CFG) %
731 (TEGRA210_MBDRC_FILTER_PARAM_STRIDE *
732 TEGRA210_MBDRC_FILTER_COUNT));
733
734 switch (reg) {
735 case TEGRA210_MBDRC_SOFT_RESET:
736 case TEGRA210_MBDRC_STATUS:
737 case TEGRA210_MBDRC_CFG_RAM_CTRL:
738 case TEGRA210_MBDRC_CFG_RAM_DATA:
739 return true;
740 default:
741 return false;
742 }
743 }
744
tegra210_mbdrc_precious_reg(struct device * dev,unsigned int reg)745 static bool tegra210_mbdrc_precious_reg(struct device *dev, unsigned int reg)
746 {
747 if (reg >= TEGRA210_MBDRC_IIR_CFG)
748 reg -= ((reg - TEGRA210_MBDRC_IIR_CFG) %
749 (TEGRA210_MBDRC_FILTER_PARAM_STRIDE *
750 TEGRA210_MBDRC_FILTER_COUNT));
751
752 switch (reg) {
753 case TEGRA210_MBDRC_CFG_RAM_DATA:
754 return true;
755 default:
756 return false;
757 }
758 }
759
760 static const struct regmap_config tegra210_mbdrc_regmap_cfg = {
761 .name = "mbdrc",
762 .reg_bits = 32,
763 .reg_stride = 4,
764 .val_bits = 32,
765 .max_register = TEGRA210_MBDRC_MAX_REG,
766 .writeable_reg = tegra210_mbdrc_wr_reg,
767 .readable_reg = tegra210_mbdrc_rd_reg,
768 .volatile_reg = tegra210_mbdrc_volatile_reg,
769 .precious_reg = tegra210_mbdrc_precious_reg,
770 .reg_defaults = tegra210_mbdrc_reg_defaults,
771 .num_reg_defaults = ARRAY_SIZE(tegra210_mbdrc_reg_defaults),
772 .reg_default_cb = regmap_default_zero_cb,
773 .cache_type = REGCACHE_FLAT,
774 };
775
tegra210_mbdrc_hw_params(struct snd_soc_component * cmpnt)776 int tegra210_mbdrc_hw_params(struct snd_soc_component *cmpnt)
777 {
778 struct tegra210_ope *ope = snd_soc_component_get_drvdata(cmpnt);
779 const struct tegra210_mbdrc_config *conf = &mbdrc_init_config;
780 u32 val = 0;
781 unsigned int i;
782
783 regmap_read(ope->mbdrc_regmap, TEGRA210_MBDRC_CFG, &val);
784
785 val &= TEGRA210_MBDRC_CFG_MBDRC_MODE_MASK;
786
787 if (val == TEGRA210_MBDRC_CFG_MBDRC_MODE_BYPASS)
788 return 0;
789
790 for (i = 0; i < MBDRC_NUM_BAND; i++) {
791 const struct tegra210_mbdrc_band_params *params =
792 &conf->band_params[i];
793
794 u32 reg_off = i * TEGRA210_MBDRC_FILTER_PARAM_STRIDE;
795
796 tegra210_mbdrc_write_ram(ope->mbdrc_regmap,
797 reg_off + TEGRA210_MBDRC_CFG_RAM_CTRL,
798 reg_off + TEGRA210_MBDRC_CFG_RAM_DATA,
799 0, (u32 *)¶ms->biquad_params[0],
800 TEGRA210_MBDRC_MAX_BIQUAD_STAGES * 5);
801 }
802 return 0;
803 }
804
tegra210_mbdrc_component_init(struct snd_soc_component * cmpnt)805 int tegra210_mbdrc_component_init(struct snd_soc_component *cmpnt)
806 {
807 struct tegra210_ope *ope = snd_soc_component_get_drvdata(cmpnt);
808 const struct tegra210_mbdrc_config *conf = &mbdrc_init_config;
809 unsigned int i;
810 u32 val;
811
812 pm_runtime_get_sync(cmpnt->dev);
813
814 /* Initialize MBDRC registers and AHUB RAM with default params */
815 regmap_update_bits(ope->mbdrc_regmap, TEGRA210_MBDRC_CFG,
816 TEGRA210_MBDRC_CFG_MBDRC_MODE_MASK,
817 conf->mode << TEGRA210_MBDRC_CFG_MBDRC_MODE_SHIFT);
818
819 regmap_update_bits(ope->mbdrc_regmap, TEGRA210_MBDRC_CFG,
820 TEGRA210_MBDRC_CFG_RMS_OFFSET_MASK,
821 conf->rms_off << TEGRA210_MBDRC_CFG_RMS_OFFSET_SHIFT);
822
823 regmap_update_bits(ope->mbdrc_regmap, TEGRA210_MBDRC_CFG,
824 TEGRA210_MBDRC_CFG_PEAK_RMS_MASK,
825 conf->peak_rms_mode << TEGRA210_MBDRC_CFG_PEAK_RMS_SHIFT);
826
827 regmap_update_bits(ope->mbdrc_regmap, TEGRA210_MBDRC_CFG,
828 TEGRA210_MBDRC_CFG_FILTER_STRUCTURE_MASK,
829 conf->filter_structure <<
830 TEGRA210_MBDRC_CFG_FILTER_STRUCTURE_SHIFT);
831
832 regmap_update_bits(ope->mbdrc_regmap, TEGRA210_MBDRC_CFG,
833 TEGRA210_MBDRC_CFG_SHIFT_CTRL_MASK,
834 conf->shift_ctrl << TEGRA210_MBDRC_CFG_SHIFT_CTRL_SHIFT);
835
836 regmap_update_bits(ope->mbdrc_regmap, TEGRA210_MBDRC_CFG,
837 TEGRA210_MBDRC_CFG_FRAME_SIZE_MASK,
838 __ffs(conf->frame_size) <<
839 TEGRA210_MBDRC_CFG_FRAME_SIZE_SHIFT);
840
841 regmap_update_bits(ope->mbdrc_regmap, TEGRA210_MBDRC_CHANNEL_MASK,
842 TEGRA210_MBDRC_CHANNEL_MASK_MASK,
843 conf->channel_mask << TEGRA210_MBDRC_CHANNEL_MASK_SHIFT);
844
845 regmap_update_bits(ope->mbdrc_regmap, TEGRA210_MBDRC_FAST_FACTOR,
846 TEGRA210_MBDRC_FAST_FACTOR_ATTACK_MASK,
847 conf->fa_factor << TEGRA210_MBDRC_FAST_FACTOR_ATTACK_SHIFT);
848
849 regmap_update_bits(ope->mbdrc_regmap, TEGRA210_MBDRC_FAST_FACTOR,
850 TEGRA210_MBDRC_FAST_FACTOR_ATTACK_MASK,
851 conf->fr_factor << TEGRA210_MBDRC_FAST_FACTOR_ATTACK_SHIFT);
852
853 for (i = 0; i < MBDRC_NUM_BAND; i++) {
854 const struct tegra210_mbdrc_band_params *params =
855 &conf->band_params[i];
856 u32 reg_off = i * TEGRA210_MBDRC_FILTER_PARAM_STRIDE;
857
858 regmap_update_bits(ope->mbdrc_regmap,
859 reg_off + TEGRA210_MBDRC_IIR_CFG,
860 TEGRA210_MBDRC_IIR_CFG_NUM_STAGES_MASK,
861 params->iir_stages <<
862 TEGRA210_MBDRC_IIR_CFG_NUM_STAGES_SHIFT);
863
864 regmap_update_bits(ope->mbdrc_regmap,
865 reg_off + TEGRA210_MBDRC_IN_ATTACK,
866 TEGRA210_MBDRC_IN_ATTACK_TC_MASK,
867 params->in_attack_tc <<
868 TEGRA210_MBDRC_IN_ATTACK_TC_SHIFT);
869
870 regmap_update_bits(ope->mbdrc_regmap,
871 reg_off + TEGRA210_MBDRC_IN_RELEASE,
872 TEGRA210_MBDRC_IN_RELEASE_TC_MASK,
873 params->in_release_tc <<
874 TEGRA210_MBDRC_IN_RELEASE_TC_SHIFT);
875
876 regmap_update_bits(ope->mbdrc_regmap,
877 reg_off + TEGRA210_MBDRC_FAST_ATTACK,
878 TEGRA210_MBDRC_FAST_ATTACK_TC_MASK,
879 params->fast_attack_tc <<
880 TEGRA210_MBDRC_FAST_ATTACK_TC_SHIFT);
881
882 val = (((params->in_threshold[0] >>
883 TEGRA210_MBDRC_THRESH_1ST_SHIFT) &
884 TEGRA210_MBDRC_THRESH_1ST_MASK) |
885 ((params->in_threshold[1] >>
886 TEGRA210_MBDRC_THRESH_2ND_SHIFT) &
887 TEGRA210_MBDRC_THRESH_2ND_MASK) |
888 ((params->in_threshold[2] >>
889 TEGRA210_MBDRC_THRESH_3RD_SHIFT) &
890 TEGRA210_MBDRC_THRESH_3RD_MASK) |
891 ((params->in_threshold[3] >>
892 TEGRA210_MBDRC_THRESH_4TH_SHIFT) &
893 TEGRA210_MBDRC_THRESH_4TH_MASK));
894
895 regmap_update_bits(ope->mbdrc_regmap,
896 reg_off + TEGRA210_MBDRC_IN_THRESHOLD,
897 0xffffffff, val);
898
899 val = (((params->out_threshold[0] >>
900 TEGRA210_MBDRC_THRESH_1ST_SHIFT) &
901 TEGRA210_MBDRC_THRESH_1ST_MASK) |
902 ((params->out_threshold[1] >>
903 TEGRA210_MBDRC_THRESH_2ND_SHIFT) &
904 TEGRA210_MBDRC_THRESH_2ND_MASK) |
905 ((params->out_threshold[2] >>
906 TEGRA210_MBDRC_THRESH_3RD_SHIFT) &
907 TEGRA210_MBDRC_THRESH_3RD_MASK) |
908 ((params->out_threshold[3] >>
909 TEGRA210_MBDRC_THRESH_4TH_SHIFT) &
910 TEGRA210_MBDRC_THRESH_4TH_MASK));
911
912 regmap_update_bits(ope->mbdrc_regmap,
913 reg_off + TEGRA210_MBDRC_OUT_THRESHOLD,
914 0xffffffff, val);
915
916 regmap_update_bits(ope->mbdrc_regmap,
917 reg_off + TEGRA210_MBDRC_RATIO_1ST,
918 TEGRA210_MBDRC_RATIO_1ST_MASK,
919 params->ratio[0] << TEGRA210_MBDRC_RATIO_1ST_SHIFT);
920
921 regmap_update_bits(ope->mbdrc_regmap,
922 reg_off + TEGRA210_MBDRC_RATIO_2ND,
923 TEGRA210_MBDRC_RATIO_2ND_MASK,
924 params->ratio[1] << TEGRA210_MBDRC_RATIO_2ND_SHIFT);
925
926 regmap_update_bits(ope->mbdrc_regmap,
927 reg_off + TEGRA210_MBDRC_RATIO_3RD,
928 TEGRA210_MBDRC_RATIO_3RD_MASK,
929 params->ratio[2] << TEGRA210_MBDRC_RATIO_3RD_SHIFT);
930
931 regmap_update_bits(ope->mbdrc_regmap,
932 reg_off + TEGRA210_MBDRC_RATIO_4TH,
933 TEGRA210_MBDRC_RATIO_4TH_MASK,
934 params->ratio[3] << TEGRA210_MBDRC_RATIO_4TH_SHIFT);
935
936 regmap_update_bits(ope->mbdrc_regmap,
937 reg_off + TEGRA210_MBDRC_RATIO_5TH,
938 TEGRA210_MBDRC_RATIO_5TH_MASK,
939 params->ratio[4] << TEGRA210_MBDRC_RATIO_5TH_SHIFT);
940
941 regmap_update_bits(ope->mbdrc_regmap,
942 reg_off + TEGRA210_MBDRC_MAKEUP_GAIN,
943 TEGRA210_MBDRC_MAKEUP_GAIN_MASK,
944 params->makeup_gain <<
945 TEGRA210_MBDRC_MAKEUP_GAIN_SHIFT);
946
947 regmap_update_bits(ope->mbdrc_regmap,
948 reg_off + TEGRA210_MBDRC_INIT_GAIN,
949 TEGRA210_MBDRC_INIT_GAIN_MASK,
950 params->gain_init <<
951 TEGRA210_MBDRC_INIT_GAIN_SHIFT);
952
953 regmap_update_bits(ope->mbdrc_regmap,
954 reg_off + TEGRA210_MBDRC_GAIN_ATTACK,
955 TEGRA210_MBDRC_GAIN_ATTACK_MASK,
956 params->gain_attack_tc <<
957 TEGRA210_MBDRC_GAIN_ATTACK_SHIFT);
958
959 regmap_update_bits(ope->mbdrc_regmap,
960 reg_off + TEGRA210_MBDRC_GAIN_RELEASE,
961 TEGRA210_MBDRC_GAIN_RELEASE_MASK,
962 params->gain_release_tc <<
963 TEGRA210_MBDRC_GAIN_RELEASE_SHIFT);
964
965 regmap_update_bits(ope->mbdrc_regmap,
966 reg_off + TEGRA210_MBDRC_FAST_RELEASE,
967 TEGRA210_MBDRC_FAST_RELEASE_MASK,
968 params->fast_release_tc <<
969 TEGRA210_MBDRC_FAST_RELEASE_SHIFT);
970
971 tegra210_mbdrc_write_ram(ope->mbdrc_regmap,
972 reg_off + TEGRA210_MBDRC_CFG_RAM_CTRL,
973 reg_off + TEGRA210_MBDRC_CFG_RAM_DATA, 0,
974 (u32 *)¶ms->biquad_params[0],
975 TEGRA210_MBDRC_MAX_BIQUAD_STAGES * 5);
976 }
977
978 pm_runtime_put_sync(cmpnt->dev);
979
980 snd_soc_add_component_controls(cmpnt, tegra210_mbdrc_controls,
981 ARRAY_SIZE(tegra210_mbdrc_controls));
982
983 return 0;
984 }
985
tegra210_mbdrc_regmap_init(struct platform_device * pdev)986 int tegra210_mbdrc_regmap_init(struct platform_device *pdev)
987 {
988 struct device *dev = &pdev->dev;
989 struct tegra210_ope *ope = dev_get_drvdata(dev);
990 struct device_node *child;
991 struct resource mem;
992 void __iomem *regs;
993 int err;
994
995 child = of_get_child_by_name(dev->of_node, "dynamic-range-compressor");
996 if (!child)
997 return dev_err_probe(dev, -ENODEV,
998 "missing 'dynamic-range-compressor' DT child node\n");
999
1000 err = of_address_to_resource(child, 0, &mem);
1001 of_node_put(child);
1002 if (err < 0)
1003 return dev_err_probe(dev, err,
1004 "failed to get MBDRC resource\n");
1005
1006 mem.flags = IORESOURCE_MEM;
1007 regs = devm_ioremap_resource(dev, &mem);
1008 if (IS_ERR(regs))
1009 return PTR_ERR(regs);
1010
1011 ope->mbdrc_regmap = devm_regmap_init_mmio(dev, regs,
1012 &tegra210_mbdrc_regmap_cfg);
1013 if (IS_ERR(ope->mbdrc_regmap))
1014 return dev_err_probe(dev, PTR_ERR(ope->mbdrc_regmap),
1015 "MBDRC regmap init failed\n");
1016
1017 regcache_cache_only(ope->mbdrc_regmap, true);
1018
1019 return 0;
1020 }
1021