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(regmap, reg_ctrl, val);
228
229	for (i = 0; i < size; i++)
230		regmap_write(regmap, reg_data, 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(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
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(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
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(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
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(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
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(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
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(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
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(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
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(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
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(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
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(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
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(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
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(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
798int 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
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(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