Linux Audio

Check our new training course

Loading...
Note: File does not exist in v4.10.11.
   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}