xref: /linux/sound/soc/tegra/tegra210_mbdrc.c (revision b54a2377ec02d52b7bb5dab381e9a45ba0bc617a)
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 
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},
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 */
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 
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 
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_soc_kcontrol_component(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 
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_soc_kcontrol_component(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 
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_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;
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 
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_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;
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 
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_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;
314 	unsigned int i;
315 
316 	for (i = 0; i < params->soc.num_regs; i++, regs += cmpnt->val_bytes) {
317 		regmap_read(ope->mbdrc_regmap, regs, &data[i]);
318 
319 		data[i] = ((data[i] & mask) >> shift);
320 	}
321 
322 	return 0;
323 }
324 
325 static 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(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(ope->mbdrc_regmap, regs, mask,
342 					 data[i] << shift, &update);
343 
344 		change |= update;
345 	}
346 
347 	return change ? 1 : 0;
348 }
349 
350 static 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(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(ope->mbdrc_regmap, regs, &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 
378 static 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(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(ope->mbdrc_regmap, regs, 0xffffffff,
403 					 data[i], &update);
404 
405 		change |= update;
406 	}
407 
408 	return change ? 1 : 0;
409 }
410 
411 static 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 
423 static 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(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(ope->mbdrc_regmap, reg_ctrl, reg_data,
434 				 params->shift, data, params->soc.num_regs);
435 
436 	return 1;
437 }
438 
439 static 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 
450 static 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(cmpnt);
457 	int val;
458 
459 	regmap_read(ope->mbdrc_regmap, mc->reg, &val);
460 
461 	ucontrol->value.integer.value[0] =
462 		((val >> mc->shift) - TEGRA210_MBDRC_MASTER_VOL_MIN);
463 
464 	return 0;
465 }
466 
467 static 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(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(ope->mbdrc_regmap, mc->reg,
480 				 mc->max << mc->shift, val << mc->shift,
481 				 &change);
482 
483 	regmap_read(ope->mbdrc_regmap, mc->reg, &val);
484 
485 	return change ? 1 : 0;
486 }
487 
488 static const char * const tegra210_mbdrc_mode_text[] = {
489 	"Bypass", "Fullband", "Dualband", "Multiband"
490 };
491 
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);
495 
496 static const char * const tegra210_mbdrc_peak_rms_text[] = {
497 	"Peak", "RMS"
498 };
499 
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);
503 
504 static const char * const tegra210_mbdrc_filter_structure_text[] = {
505 	"All-pass-tree", "Flexible"
506 };
507 
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);
512 
513 static const char * const tegra210_mbdrc_frame_size_text[] = {
514 	"N1", "N2", "N4", "N8", "N16", "N32", "N64"
515 };
516 
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);
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 
531 static const DECLARE_TLV_DB_MINMAX(mdbrc_vol_tlv, -25600, 25500);
532 
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),
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 
686 static 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 
703 static 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 
721 static 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 
739 static 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 
754 static 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 
769 int tegra210_mbdrc_hw_params(struct snd_soc_component *cmpnt)
770 {
771 	struct tegra210_ope *ope = snd_soc_component_get_drvdata(cmpnt);
772 	const struct tegra210_mbdrc_config *conf = &mbdrc_init_config;
773 	u32 val = 0;
774 	unsigned int i;
775 
776 	regmap_read(ope->mbdrc_regmap, TEGRA210_MBDRC_CFG, &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(ope->mbdrc_regmap,
790 					 reg_off + TEGRA210_MBDRC_CFG_RAM_CTRL,
791 					 reg_off + TEGRA210_MBDRC_CFG_RAM_DATA,
792 					 0, (u32 *)&params->biquad_params[0],
793 					 TEGRA210_MBDRC_MAX_BIQUAD_STAGES * 5);
794 	}
795 	return 0;
796 }
797 
798 int tegra210_mbdrc_component_init(struct snd_soc_component *cmpnt)
799 {
800 	struct tegra210_ope *ope = snd_soc_component_get_drvdata(cmpnt);
801 	const struct tegra210_mbdrc_config *conf = &mbdrc_init_config;
802 	unsigned int i;
803 	u32 val;
804 
805 	pm_runtime_get_sync(cmpnt->dev);
806 
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);
811 
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);
815 
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);
819 
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);
824 
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);
828 
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);
833 
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);
837 
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);
841 
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);
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(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);
856 
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);
862 
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);
868 
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);
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(ope->mbdrc_regmap,
889 				   reg_off + TEGRA210_MBDRC_IN_THRESHOLD,
890 				   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(ope->mbdrc_regmap,
906 			reg_off + TEGRA210_MBDRC_OUT_THRESHOLD,
907 			0xffffffff, val);
908 
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);
913 
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);
918 
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);
923 
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);
928 
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);
933 
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);
939 
940 		regmap_update_bits(ope->mbdrc_regmap,
941 			reg_off + TEGRA210_MBDRC_INIT_GAIN,
942 			TEGRA210_MBDRC_INIT_GAIN_MASK,
943 			params->gain_init <<
944 				TEGRA210_MBDRC_INIT_GAIN_SHIFT);
945 
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);
951 
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);
957 
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);
963 
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 *)&params->biquad_params[0],
968 			TEGRA210_MBDRC_MAX_BIQUAD_STAGES * 5);
969 	}
970 
971 	pm_runtime_put_sync(cmpnt->dev);
972 
973 	snd_soc_add_component_controls(cmpnt, tegra210_mbdrc_controls,
974 				       ARRAY_SIZE(tegra210_mbdrc_controls));
975 
976 	return 0;
977 }
978 
979 int 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(dev->of_node, "dynamic-range-compressor");
989 	if (!child)
990 		return -ENODEV;
991 
992 	err = of_address_to_resource(child, 0, &mem);
993 	of_node_put(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, &mem);
1001 	if (IS_ERR(regs))
1002 		return PTR_ERR(regs);
1003 
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);
1009 	}
1010 
1011 	regcache_cache_only(ope->mbdrc_regmap, true);
1012 
1013 	return 0;
1014 }
1015