brintos

brintos / linux-shallow public Read only

0
0
Text · 30.7 KiB · eeacb12 Raw
1015 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2//3// tegra210_mbdrc.c - Tegra210 MBDRC driver4//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