Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 //
0003 // tegra210_mbdrc.c - Tegra210 MBDRC driver
0004 //
0005 // Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved.
0006 
0007 #include <linux/device.h>
0008 #include <linux/io.h>
0009 #include <linux/module.h>
0010 #include <linux/of_address.h>
0011 #include <linux/pm_runtime.h>
0012 #include <linux/regmap.h>
0013 #include <sound/core.h>
0014 #include <sound/soc.h>
0015 #include <sound/tlv.h>
0016 
0017 #include "tegra210_mbdrc.h"
0018 #include "tegra210_ope.h"
0019 
0020 #define MBDRC_FILTER_REG(reg, id)                       \
0021     ((reg) + ((id) * TEGRA210_MBDRC_FILTER_PARAM_STRIDE))
0022 
0023 #define MBDRC_FILTER_REG_DEFAULTS(id)                       \
0024     { MBDRC_FILTER_REG(TEGRA210_MBDRC_IIR_CFG, id), 0x00000005},        \
0025     { MBDRC_FILTER_REG(TEGRA210_MBDRC_IN_ATTACK, id), 0x3e48590c},      \
0026     { MBDRC_FILTER_REG(TEGRA210_MBDRC_IN_RELEASE, id), 0x08414e9f},     \
0027     { MBDRC_FILTER_REG(TEGRA210_MBDRC_FAST_ATTACK, id), 0x7fffffff},    \
0028     { MBDRC_FILTER_REG(TEGRA210_MBDRC_IN_THRESHOLD, id), 0x06145082},   \
0029     { MBDRC_FILTER_REG(TEGRA210_MBDRC_OUT_THRESHOLD, id), 0x060d379b},  \
0030     { MBDRC_FILTER_REG(TEGRA210_MBDRC_RATIO_1ST, id), 0x0000a000},      \
0031     { MBDRC_FILTER_REG(TEGRA210_MBDRC_RATIO_2ND, id), 0x00002000},      \
0032     { MBDRC_FILTER_REG(TEGRA210_MBDRC_RATIO_3RD, id), 0x00000b33},      \
0033     { MBDRC_FILTER_REG(TEGRA210_MBDRC_RATIO_4TH, id), 0x00000800},      \
0034     { MBDRC_FILTER_REG(TEGRA210_MBDRC_RATIO_5TH, id), 0x0000019a},      \
0035     { MBDRC_FILTER_REG(TEGRA210_MBDRC_MAKEUP_GAIN, id), 0x00000002},    \
0036     { MBDRC_FILTER_REG(TEGRA210_MBDRC_INIT_GAIN, id), 0x00066666},      \
0037     { MBDRC_FILTER_REG(TEGRA210_MBDRC_GAIN_ATTACK, id), 0x00d9ba0e},    \
0038     { MBDRC_FILTER_REG(TEGRA210_MBDRC_GAIN_RELEASE, id), 0x3e48590c},   \
0039     { MBDRC_FILTER_REG(TEGRA210_MBDRC_FAST_RELEASE, id), 0x7ffff26a},   \
0040     { MBDRC_FILTER_REG(TEGRA210_MBDRC_CFG_RAM_CTRL, id), 0x4000}
0041 
0042 static const struct reg_default tegra210_mbdrc_reg_defaults[] = {
0043     { TEGRA210_MBDRC_CFG, 0x0030de51},
0044     { TEGRA210_MBDRC_CHANNEL_MASK, 0x00000003},
0045     { TEGRA210_MBDRC_FAST_FACTOR, 0x30000800},
0046 
0047     MBDRC_FILTER_REG_DEFAULTS(0),
0048     MBDRC_FILTER_REG_DEFAULTS(1),
0049     MBDRC_FILTER_REG_DEFAULTS(2),
0050 };
0051 
0052 /* Default MBDRC parameters */
0053 static const struct tegra210_mbdrc_config mbdrc_init_config = {
0054     .mode           = 0, /* Bypass */
0055     .rms_off        = 48,
0056     .peak_rms_mode      = 1, /* PEAK */
0057     .fliter_structure   = 0, /* All-pass tree */
0058     .shift_ctrl     = 30,
0059     .frame_size     = 32,
0060     .channel_mask       = 0x3,
0061     .fa_factor      = 2048,
0062     .fr_factor      = 14747,
0063 
0064     .band_params[MBDRC_LOW_BAND] = {
0065         .band           = MBDRC_LOW_BAND,
0066         .iir_stages     = 5,
0067         .in_attack_tc       = 1044928780,
0068         .in_release_tc      = 138497695,
0069         .fast_attack_tc     = 2147483647,
0070         .in_threshold       = {130, 80, 20, 6},
0071         .out_threshold      = {155, 55, 13, 6},
0072         .ratio          = {40960, 8192, 2867, 2048, 410},
0073         .makeup_gain        = 4,
0074         .gain_init      = 419430,
0075         .gain_attack_tc     = 14268942,
0076         .gain_release_tc    = 1440547090,
0077         .fast_release_tc    = 2147480170,
0078 
0079         .biquad_params  = {
0080             /*
0081              * Gains:
0082              *
0083              * b0, b1, a0,
0084              * a1, a2,
0085              */
0086 
0087             /* Band-0 */
0088             961046798, -2030431983, 1073741824,
0089             2030431983, -961046798,
0090             /* Band-1 */
0091             1030244425, -2099481453, 1073741824,
0092             2099481453, -1030244425,
0093             /* Band-2 */
0094             1067169294, -2136327263, 1073741824,
0095             2136327263, -1067169294,
0096             /* Band-3 */
0097             434951949, -1306567134, 1073741824,
0098             1306567134, -434951949,
0099             /* Band-4 */
0100             780656019, -1605955641, 1073741824,
0101             1605955641, -780656019,
0102             /* Band-5 */
0103             1024497031, -1817128152, 1073741824,
0104             1817128152, -1024497031,
0105             /* Band-6 */
0106             1073741824, 0, 0,
0107             0, 0,
0108             /* Band-7 */
0109             1073741824, 0, 0,
0110             0, 0,
0111         }
0112     },
0113 
0114     .band_params[MBDRC_MID_BAND] = {
0115         .band           = MBDRC_MID_BAND,
0116         .iir_stages     = 5,
0117         .in_attack_tc       = 1581413104,
0118         .in_release_tc      = 35494783,
0119         .fast_attack_tc     = 2147483647,
0120         .in_threshold       = {130, 50, 30, 6},
0121         .out_threshold      = {106, 50, 30, 13},
0122         .ratio          = {40960, 2867, 4096, 2867, 410},
0123         .makeup_gain        = 6,
0124         .gain_init      = 419430,
0125         .gain_attack_tc     = 4766887,
0126         .gain_release_tc    = 1044928780,
0127         .fast_release_tc    = 2147480170,
0128 
0129         .biquad_params = {
0130             /*
0131              * Gains:
0132              *
0133              * b0, b1, a0,
0134              * a1, a2,
0135              */
0136 
0137             /* Band-0 */
0138             -1005668963, 1073741824, 0,
0139             1005668963, 0,
0140             /* Band-1 */
0141             998437058, -2067742187, 1073741824,
0142             2067742187, -998437058,
0143             /* Band-2 */
0144             1051963422, -2121153948, 1073741824,
0145             2121153948, -1051963422,
0146             /* Band-3 */
0147             434951949, -1306567134, 1073741824,
0148             1306567134, -434951949,
0149             /* Band-4 */
0150             780656019, -1605955641, 1073741824,
0151             1605955641, -780656019,
0152             /* Band-5 */
0153             1024497031, -1817128152, 1073741824,
0154             1817128152, -1024497031,
0155             /* Band-6 */
0156             1073741824, 0, 0,
0157             0, 0,
0158             /* Band-7 */
0159             1073741824, 0, 0,
0160             0, 0,
0161         }
0162     },
0163 
0164     .band_params[MBDRC_HIGH_BAND] = {
0165         .band           = MBDRC_HIGH_BAND,
0166         .iir_stages     = 5,
0167         .in_attack_tc       = 2144750688,
0168         .in_release_tc      = 70402888,
0169         .fast_attack_tc     = 2147483647,
0170         .in_threshold       = {130, 50, 30, 6},
0171         .out_threshold      = {106, 50, 30, 13},
0172         .ratio          = {40960, 2867, 4096, 2867, 410},
0173         .makeup_gain        = 6,
0174         .gain_init      = 419430,
0175         .gain_attack_tc     = 4766887,
0176         .gain_release_tc    = 1044928780,
0177         .fast_release_tc    = 2147480170,
0178 
0179         .biquad_params = {
0180             /*
0181              * Gains:
0182              *
0183              * b0, b1, a0,
0184              * a1, a2,
0185              */
0186 
0187             /* Band-0 */
0188             1073741824, 0, 0,
0189             0, 0,
0190             /* Band-1 */
0191             1073741824, 0, 0,
0192             0, 0,
0193             /* Band-2 */
0194             1073741824, 0, 0,
0195             0, 0,
0196             /* Band-3 */
0197             -619925131, 1073741824, 0,
0198             619925131, 0,
0199             /* Band-4 */
0200             606839335, -1455425976, 1073741824,
0201             1455425976, -606839335,
0202             /* Band-5 */
0203             917759617, -1724690840, 1073741824,
0204             1724690840, -917759617,
0205             /* Band-6 */
0206             1073741824, 0, 0,
0207             0, 0,
0208             /* Band-7 */
0209             1073741824, 0, 0,
0210             0, 0,
0211         }
0212     }
0213 };
0214 
0215 static void tegra210_mbdrc_write_ram(struct regmap *regmap, unsigned int reg_ctrl,
0216                      unsigned int reg_data, unsigned int ram_offset,
0217                      unsigned int *data, size_t size)
0218 {
0219     unsigned int val;
0220     unsigned int i;
0221 
0222     val = ram_offset & TEGRA210_MBDRC_RAM_CTRL_RAM_ADDR_MASK;
0223     val |= TEGRA210_MBDRC_RAM_CTRL_ADDR_INIT_EN;
0224     val |= TEGRA210_MBDRC_RAM_CTRL_SEQ_ACCESS_EN;
0225     val |= TEGRA210_MBDRC_RAM_CTRL_RW_WRITE;
0226 
0227     regmap_write(regmap, reg_ctrl, val);
0228 
0229     for (i = 0; i < size; i++)
0230         regmap_write(regmap, reg_data, data[i]);
0231 }
0232 
0233 static int tegra210_mbdrc_get(struct snd_kcontrol *kcontrol,
0234                   struct snd_ctl_elem_value *ucontrol)
0235 {
0236     struct soc_mixer_control *mc =
0237         (struct soc_mixer_control *)kcontrol->private_value;
0238     struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
0239     struct tegra210_ope *ope = snd_soc_component_get_drvdata(cmpnt);
0240     unsigned int val;
0241 
0242     regmap_read(ope->mbdrc_regmap, mc->reg, &val);
0243 
0244     ucontrol->value.integer.value[0] = (val >> mc->shift) & mc->max;
0245 
0246     return 0;
0247 }
0248 
0249 static int tegra210_mbdrc_put(struct snd_kcontrol *kcontrol,
0250                   struct snd_ctl_elem_value *ucontrol)
0251 {
0252     struct soc_mixer_control *mc =
0253         (struct soc_mixer_control *)kcontrol->private_value;
0254     struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
0255     struct tegra210_ope *ope = snd_soc_component_get_drvdata(cmpnt);
0256     unsigned int val = ucontrol->value.integer.value[0];
0257     bool change = false;
0258 
0259     val = val << mc->shift;
0260 
0261     regmap_update_bits_check(ope->mbdrc_regmap, mc->reg,
0262                  (mc->max << mc->shift), val, &change);
0263 
0264     return change ? 1 : 0;
0265 }
0266 
0267 static int tegra210_mbdrc_get_enum(struct snd_kcontrol *kcontrol,
0268                    struct snd_ctl_elem_value *ucontrol)
0269 {
0270     struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
0271     struct tegra210_ope *ope = snd_soc_component_get_drvdata(cmpnt);
0272     struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
0273     unsigned int val;
0274 
0275     regmap_read(ope->mbdrc_regmap, e->reg, &val);
0276 
0277     ucontrol->value.enumerated.item[0] = (val >> e->shift_l) & e->mask;
0278 
0279     return 0;
0280 }
0281 
0282 static int tegra210_mbdrc_put_enum(struct snd_kcontrol *kcontrol,
0283                    struct snd_ctl_elem_value *ucontrol)
0284 {
0285     struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
0286     struct tegra210_ope *ope = snd_soc_component_get_drvdata(cmpnt);
0287     struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
0288     bool change = false;
0289     unsigned int val;
0290     unsigned int mask;
0291 
0292     if (ucontrol->value.enumerated.item[0] > e->items - 1)
0293         return -EINVAL;
0294 
0295     val = ucontrol->value.enumerated.item[0] << e->shift_l;
0296     mask = e->mask << e->shift_l;
0297 
0298     regmap_update_bits_check(ope->mbdrc_regmap, e->reg, mask, val,
0299                  &change);
0300 
0301     return change ? 1 : 0;
0302 }
0303 
0304 static int tegra210_mbdrc_band_params_get(struct snd_kcontrol *kcontrol,
0305                       struct snd_ctl_elem_value *ucontrol)
0306 {
0307     struct tegra_soc_bytes *params = (void *)kcontrol->private_value;
0308     struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
0309     struct tegra210_ope *ope = snd_soc_component_get_drvdata(cmpnt);
0310     u32 *data = (u32 *)ucontrol->value.bytes.data;
0311     u32 regs = params->soc.base;
0312     u32 mask = params->soc.mask;
0313     u32 shift = params->shift;
0314     unsigned int i;
0315 
0316     for (i = 0; i < params->soc.num_regs; i++, regs += cmpnt->val_bytes) {
0317         regmap_read(ope->mbdrc_regmap, regs, &data[i]);
0318 
0319         data[i] = ((data[i] & mask) >> shift);
0320     }
0321 
0322     return 0;
0323 }
0324 
0325 static int tegra210_mbdrc_band_params_put(struct snd_kcontrol *kcontrol,
0326                       struct snd_ctl_elem_value *ucontrol)
0327 {
0328     struct tegra_soc_bytes *params = (void *)kcontrol->private_value;
0329     struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
0330     struct tegra210_ope *ope = snd_soc_component_get_drvdata(cmpnt);
0331     u32 *data = (u32 *)ucontrol->value.bytes.data;
0332     u32 regs = params->soc.base;
0333     u32 mask = params->soc.mask;
0334     u32 shift = params->shift;
0335     bool change = false;
0336     unsigned int i;
0337 
0338     for (i = 0; i < params->soc.num_regs; i++, regs += cmpnt->val_bytes) {
0339         bool update = false;
0340 
0341         regmap_update_bits_check(ope->mbdrc_regmap, regs, mask,
0342                      data[i] << shift, &update);
0343 
0344         change |= update;
0345     }
0346 
0347     return change ? 1 : 0;
0348 }
0349 
0350 static int tegra210_mbdrc_threshold_get(struct snd_kcontrol *kcontrol,
0351                     struct snd_ctl_elem_value *ucontrol)
0352 {
0353     struct tegra_soc_bytes *params = (void *)kcontrol->private_value;
0354     struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
0355     struct tegra210_ope *ope = snd_soc_component_get_drvdata(cmpnt);
0356     u32 *data = (u32 *)ucontrol->value.bytes.data;
0357     u32 regs = params->soc.base;
0358     u32 num_regs = params->soc.num_regs;
0359     u32 val;
0360     unsigned int i;
0361 
0362     for (i = 0; i < num_regs; i += 4, regs += cmpnt->val_bytes) {
0363         regmap_read(ope->mbdrc_regmap, regs, &val);
0364 
0365         data[i] = (val & TEGRA210_MBDRC_THRESH_1ST_MASK) >>
0366               TEGRA210_MBDRC_THRESH_1ST_SHIFT;
0367         data[i + 1] = (val & TEGRA210_MBDRC_THRESH_2ND_MASK) >>
0368                   TEGRA210_MBDRC_THRESH_2ND_SHIFT;
0369         data[i + 2] = (val & TEGRA210_MBDRC_THRESH_3RD_MASK) >>
0370                   TEGRA210_MBDRC_THRESH_3RD_SHIFT;
0371         data[i + 3] = (val & TEGRA210_MBDRC_THRESH_4TH_MASK) >>
0372                   TEGRA210_MBDRC_THRESH_4TH_SHIFT;
0373     }
0374 
0375     return 0;
0376 }
0377 
0378 static int tegra210_mbdrc_threshold_put(struct snd_kcontrol *kcontrol,
0379                     struct snd_ctl_elem_value *ucontrol)
0380 {
0381     struct tegra_soc_bytes *params = (void *)kcontrol->private_value;
0382     struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
0383     struct tegra210_ope *ope = snd_soc_component_get_drvdata(cmpnt);
0384     u32 *data = (u32 *)ucontrol->value.bytes.data;
0385     u32 regs = params->soc.base;
0386     u32 num_regs = params->soc.num_regs;
0387     bool change = false;
0388     unsigned int i;
0389 
0390     for (i = 0; i < num_regs; i += 4, regs += cmpnt->val_bytes) {
0391         bool update = false;
0392 
0393         data[i] = (((data[i] >> TEGRA210_MBDRC_THRESH_1ST_SHIFT) &
0394                 TEGRA210_MBDRC_THRESH_1ST_MASK) |
0395                ((data[i + 1] >> TEGRA210_MBDRC_THRESH_2ND_SHIFT) &
0396                 TEGRA210_MBDRC_THRESH_2ND_MASK) |
0397                ((data[i + 2] >> TEGRA210_MBDRC_THRESH_3RD_SHIFT) &
0398                 TEGRA210_MBDRC_THRESH_3RD_MASK) |
0399                ((data[i + 3] >> TEGRA210_MBDRC_THRESH_4TH_SHIFT) &
0400                 TEGRA210_MBDRC_THRESH_4TH_MASK));
0401 
0402         regmap_update_bits_check(ope->mbdrc_regmap, regs, 0xffffffff,
0403                      data[i], &update);
0404 
0405         change |= update;
0406     }
0407 
0408     return change ? 1 : 0;
0409 }
0410 
0411 static int tegra210_mbdrc_biquad_coeffs_get(struct snd_kcontrol *kcontrol,
0412     struct snd_ctl_elem_value *ucontrol)
0413 {
0414     struct tegra_soc_bytes *params = (void *)kcontrol->private_value;
0415     struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
0416     u32 *data = (u32 *)ucontrol->value.bytes.data;
0417 
0418     memset(data, 0, params->soc.num_regs * cmpnt->val_bytes);
0419 
0420     return 0;
0421 }
0422 
0423 static int tegra210_mbdrc_biquad_coeffs_put(struct snd_kcontrol *kcontrol,
0424                         struct snd_ctl_elem_value *ucontrol)
0425 {
0426     struct tegra_soc_bytes *params = (void *)kcontrol->private_value;
0427     struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
0428     struct tegra210_ope *ope = snd_soc_component_get_drvdata(cmpnt);
0429     u32 reg_ctrl = params->soc.base;
0430     u32 reg_data = reg_ctrl + cmpnt->val_bytes;
0431     u32 *data = (u32 *)ucontrol->value.bytes.data;
0432 
0433     tegra210_mbdrc_write_ram(ope->mbdrc_regmap, reg_ctrl, reg_data,
0434                  params->shift, data, params->soc.num_regs);
0435 
0436     return 1;
0437 }
0438 
0439 static int tegra210_mbdrc_param_info(struct snd_kcontrol *kcontrol,
0440                      struct snd_ctl_elem_info *uinfo)
0441 {
0442     struct soc_bytes *params = (void *)kcontrol->private_value;
0443 
0444     uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
0445     uinfo->count = params->num_regs * sizeof(u32);
0446 
0447     return 0;
0448 }
0449 
0450 static int tegra210_mbdrc_vol_get(struct snd_kcontrol *kcontrol,
0451                   struct snd_ctl_elem_value *ucontrol)
0452 {
0453     struct soc_mixer_control *mc =
0454         (struct soc_mixer_control *)kcontrol->private_value;
0455     struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
0456     struct tegra210_ope *ope = snd_soc_component_get_drvdata(cmpnt);
0457     int val;
0458 
0459     regmap_read(ope->mbdrc_regmap, mc->reg, &val);
0460 
0461     ucontrol->value.integer.value[0] =
0462         ((val >> mc->shift) - TEGRA210_MBDRC_MASTER_VOL_MIN);
0463 
0464     return 0;
0465 }
0466 
0467 static int tegra210_mbdrc_vol_put(struct snd_kcontrol *kcontrol,
0468                   struct snd_ctl_elem_value *ucontrol)
0469 {
0470     struct soc_mixer_control *mc =
0471         (struct soc_mixer_control *)kcontrol->private_value;
0472     struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
0473     struct tegra210_ope *ope = snd_soc_component_get_drvdata(cmpnt);
0474     int val = ucontrol->value.integer.value[0];
0475     bool change = false;
0476 
0477     val += TEGRA210_MBDRC_MASTER_VOL_MIN;
0478 
0479     regmap_update_bits_check(ope->mbdrc_regmap, mc->reg,
0480                  mc->max << mc->shift, val << mc->shift,
0481                  &change);
0482 
0483     regmap_read(ope->mbdrc_regmap, mc->reg, &val);
0484 
0485     return change ? 1 : 0;
0486 }
0487 
0488 static const char * const tegra210_mbdrc_mode_text[] = {
0489     "Bypass", "Fullband", "Dualband", "Multiband"
0490 };
0491 
0492 static const struct soc_enum tegra210_mbdrc_mode_enum =
0493     SOC_ENUM_SINGLE(TEGRA210_MBDRC_CFG, TEGRA210_MBDRC_CFG_MBDRC_MODE_SHIFT,
0494             4, tegra210_mbdrc_mode_text);
0495 
0496 static const char * const tegra210_mbdrc_peak_rms_text[] = {
0497     "Peak", "RMS"
0498 };
0499 
0500 static const struct soc_enum tegra210_mbdrc_peak_rms_enum =
0501     SOC_ENUM_SINGLE(TEGRA210_MBDRC_CFG, TEGRA210_MBDRC_CFG_PEAK_RMS_SHIFT,
0502             2, tegra210_mbdrc_peak_rms_text);
0503 
0504 static const char * const tegra210_mbdrc_filter_structure_text[] = {
0505     "All-pass-tree", "Flexible"
0506 };
0507 
0508 static const struct soc_enum tegra210_mbdrc_filter_structure_enum =
0509     SOC_ENUM_SINGLE(TEGRA210_MBDRC_CFG,
0510             TEGRA210_MBDRC_CFG_FILTER_STRUCTURE_SHIFT, 2,
0511             tegra210_mbdrc_filter_structure_text);
0512 
0513 static const char * const tegra210_mbdrc_frame_size_text[] = {
0514     "N1", "N2", "N4", "N8", "N16", "N32", "N64"
0515 };
0516 
0517 static const struct soc_enum tegra210_mbdrc_frame_size_enum =
0518     SOC_ENUM_SINGLE(TEGRA210_MBDRC_CFG, TEGRA210_MBDRC_CFG_FRAME_SIZE_SHIFT,
0519             7, tegra210_mbdrc_frame_size_text);
0520 
0521 #define TEGRA_MBDRC_BYTES_EXT(xname, xbase, xregs, xshift, xmask, xinfo)    \
0522     TEGRA_SOC_BYTES_EXT(xname, xbase, xregs, xshift, xmask,         \
0523                 tegra210_mbdrc_band_params_get,         \
0524                 tegra210_mbdrc_band_params_put,         \
0525                 tegra210_mbdrc_param_info)
0526 
0527 #define TEGRA_MBDRC_BAND_BYTES_EXT(xname, xbase, xshift, xmask, xinfo)      \
0528     TEGRA_MBDRC_BYTES_EXT(xname, xbase, TEGRA210_MBDRC_FILTER_COUNT,    \
0529                   xshift, xmask, xinfo)
0530 
0531 static const DECLARE_TLV_DB_MINMAX(mdbrc_vol_tlv, -25600, 25500);
0532 
0533 static const struct snd_kcontrol_new tegra210_mbdrc_controls[] = {
0534     SOC_ENUM_EXT("MBDRC Peak RMS Mode", tegra210_mbdrc_peak_rms_enum,
0535              tegra210_mbdrc_get_enum, tegra210_mbdrc_put_enum),
0536 
0537     SOC_ENUM_EXT("MBDRC Filter Structure",
0538              tegra210_mbdrc_filter_structure_enum,
0539              tegra210_mbdrc_get_enum, tegra210_mbdrc_put_enum),
0540 
0541     SOC_ENUM_EXT("MBDRC Frame Size", tegra210_mbdrc_frame_size_enum,
0542              tegra210_mbdrc_get_enum, tegra210_mbdrc_put_enum),
0543 
0544     SOC_ENUM_EXT("MBDRC Mode", tegra210_mbdrc_mode_enum,
0545              tegra210_mbdrc_get_enum, tegra210_mbdrc_put_enum),
0546 
0547     SOC_SINGLE_EXT("MBDRC RMS Offset", TEGRA210_MBDRC_CFG,
0548                TEGRA210_MBDRC_CFG_RMS_OFFSET_SHIFT, 0x1ff, 0,
0549                tegra210_mbdrc_get, tegra210_mbdrc_put),
0550 
0551     SOC_SINGLE_EXT("MBDRC Shift Control", TEGRA210_MBDRC_CFG,
0552                TEGRA210_MBDRC_CFG_SHIFT_CTRL_SHIFT, 0x1f, 0,
0553                tegra210_mbdrc_get, tegra210_mbdrc_put),
0554 
0555     SOC_SINGLE_EXT("MBDRC Fast Attack Factor", TEGRA210_MBDRC_FAST_FACTOR,
0556                TEGRA210_MBDRC_FAST_FACTOR_ATTACK_SHIFT, 0xffff, 0,
0557                tegra210_mbdrc_get, tegra210_mbdrc_put),
0558 
0559     SOC_SINGLE_EXT("MBDRC Fast Release Factor", TEGRA210_MBDRC_FAST_FACTOR,
0560                TEGRA210_MBDRC_FAST_FACTOR_RELEASE_SHIFT, 0xffff, 0,
0561                tegra210_mbdrc_get, tegra210_mbdrc_put),
0562 
0563     SOC_SINGLE_RANGE_EXT_TLV("MBDRC Master Volume",
0564                  TEGRA210_MBDRC_MASTER_VOL,
0565                  TEGRA210_MBDRC_MASTER_VOL_SHIFT,
0566                  0, 0x1ff, 0,
0567                  tegra210_mbdrc_vol_get, tegra210_mbdrc_vol_put,
0568                  mdbrc_vol_tlv),
0569 
0570     TEGRA_SOC_BYTES_EXT("MBDRC IIR Stages", TEGRA210_MBDRC_IIR_CFG,
0571                 TEGRA210_MBDRC_FILTER_COUNT,
0572                 TEGRA210_MBDRC_IIR_CFG_NUM_STAGES_SHIFT,
0573                 TEGRA210_MBDRC_IIR_CFG_NUM_STAGES_MASK,
0574                 tegra210_mbdrc_band_params_get,
0575                 tegra210_mbdrc_band_params_put,
0576                 tegra210_mbdrc_param_info),
0577 
0578     TEGRA_SOC_BYTES_EXT("MBDRC In Attack Time Const", TEGRA210_MBDRC_IN_ATTACK,
0579                 TEGRA210_MBDRC_FILTER_COUNT,
0580                 TEGRA210_MBDRC_IN_ATTACK_TC_SHIFT,
0581                 TEGRA210_MBDRC_IN_ATTACK_TC_MASK,
0582                 tegra210_mbdrc_band_params_get,
0583                 tegra210_mbdrc_band_params_put,
0584                 tegra210_mbdrc_param_info),
0585 
0586     TEGRA_SOC_BYTES_EXT("MBDRC In Release Time Const", TEGRA210_MBDRC_IN_RELEASE,
0587                 TEGRA210_MBDRC_FILTER_COUNT,
0588                 TEGRA210_MBDRC_IN_RELEASE_TC_SHIFT,
0589                 TEGRA210_MBDRC_IN_RELEASE_TC_MASK,
0590                 tegra210_mbdrc_band_params_get,
0591                 tegra210_mbdrc_band_params_put,
0592                 tegra210_mbdrc_param_info),
0593 
0594     TEGRA_SOC_BYTES_EXT("MBDRC Fast Attack Time Const", TEGRA210_MBDRC_FAST_ATTACK,
0595                 TEGRA210_MBDRC_FILTER_COUNT,
0596                 TEGRA210_MBDRC_FAST_ATTACK_TC_SHIFT,
0597                 TEGRA210_MBDRC_FAST_ATTACK_TC_MASK,
0598                 tegra210_mbdrc_band_params_get,
0599                 tegra210_mbdrc_band_params_put,
0600                 tegra210_mbdrc_param_info),
0601 
0602     TEGRA_SOC_BYTES_EXT("MBDRC In Threshold", TEGRA210_MBDRC_IN_THRESHOLD,
0603                 TEGRA210_MBDRC_FILTER_COUNT * 4, 0, 0xffffffff,
0604                 tegra210_mbdrc_threshold_get,
0605                 tegra210_mbdrc_threshold_put,
0606                 tegra210_mbdrc_param_info),
0607 
0608     TEGRA_SOC_BYTES_EXT("MBDRC Out Threshold", TEGRA210_MBDRC_OUT_THRESHOLD,
0609                 TEGRA210_MBDRC_FILTER_COUNT * 4, 0, 0xffffffff,
0610                 tegra210_mbdrc_threshold_get,
0611                 tegra210_mbdrc_threshold_put,
0612                 tegra210_mbdrc_param_info),
0613 
0614     TEGRA_SOC_BYTES_EXT("MBDRC Ratio", TEGRA210_MBDRC_RATIO_1ST,
0615                 TEGRA210_MBDRC_FILTER_COUNT * 5,
0616                 TEGRA210_MBDRC_RATIO_1ST_SHIFT, TEGRA210_MBDRC_RATIO_1ST_MASK,
0617                 tegra210_mbdrc_band_params_get,
0618                 tegra210_mbdrc_band_params_put,
0619                 tegra210_mbdrc_param_info),
0620 
0621     TEGRA_SOC_BYTES_EXT("MBDRC Makeup Gain", TEGRA210_MBDRC_MAKEUP_GAIN,
0622                 TEGRA210_MBDRC_FILTER_COUNT,
0623                 TEGRA210_MBDRC_MAKEUP_GAIN_SHIFT,
0624                 TEGRA210_MBDRC_MAKEUP_GAIN_MASK,
0625                 tegra210_mbdrc_band_params_get,
0626                 tegra210_mbdrc_band_params_put,
0627                 tegra210_mbdrc_param_info),
0628 
0629     TEGRA_SOC_BYTES_EXT("MBDRC Init Gain", TEGRA210_MBDRC_INIT_GAIN,
0630                 TEGRA210_MBDRC_FILTER_COUNT,
0631                 TEGRA210_MBDRC_INIT_GAIN_SHIFT,
0632                 TEGRA210_MBDRC_INIT_GAIN_MASK,
0633                 tegra210_mbdrc_band_params_get,
0634                 tegra210_mbdrc_band_params_put,
0635                 tegra210_mbdrc_param_info),
0636 
0637     TEGRA_SOC_BYTES_EXT("MBDRC Attack Gain", TEGRA210_MBDRC_GAIN_ATTACK,
0638                 TEGRA210_MBDRC_FILTER_COUNT,
0639                 TEGRA210_MBDRC_GAIN_ATTACK_SHIFT,
0640                 TEGRA210_MBDRC_GAIN_ATTACK_MASK,
0641                 tegra210_mbdrc_band_params_get,
0642                 tegra210_mbdrc_band_params_put,
0643                 tegra210_mbdrc_param_info),
0644 
0645     TEGRA_SOC_BYTES_EXT("MBDRC Release Gain", TEGRA210_MBDRC_GAIN_RELEASE,
0646                 TEGRA210_MBDRC_FILTER_COUNT,
0647                 TEGRA210_MBDRC_GAIN_RELEASE_SHIFT,
0648                 TEGRA210_MBDRC_GAIN_RELEASE_MASK,
0649                 tegra210_mbdrc_band_params_get,
0650                 tegra210_mbdrc_band_params_put,
0651                 tegra210_mbdrc_param_info),
0652 
0653     TEGRA_SOC_BYTES_EXT("MBDRC Fast Release Gain",
0654                 TEGRA210_MBDRC_FAST_RELEASE,
0655                 TEGRA210_MBDRC_FILTER_COUNT,
0656                 TEGRA210_MBDRC_FAST_RELEASE_SHIFT,
0657                 TEGRA210_MBDRC_FAST_RELEASE_MASK,
0658                 tegra210_mbdrc_band_params_get,
0659                 tegra210_mbdrc_band_params_put,
0660                 tegra210_mbdrc_param_info),
0661 
0662     TEGRA_SOC_BYTES_EXT("MBDRC Low Band Biquad Coeffs",
0663                 TEGRA210_MBDRC_CFG_RAM_CTRL,
0664                 TEGRA210_MBDRC_MAX_BIQUAD_STAGES * 5, 0, 0xffffffff,
0665                 tegra210_mbdrc_biquad_coeffs_get,
0666                 tegra210_mbdrc_biquad_coeffs_put,
0667                 tegra210_mbdrc_param_info),
0668 
0669     TEGRA_SOC_BYTES_EXT("MBDRC Mid Band Biquad Coeffs",
0670                 TEGRA210_MBDRC_CFG_RAM_CTRL +
0671                 TEGRA210_MBDRC_FILTER_PARAM_STRIDE,
0672                 TEGRA210_MBDRC_MAX_BIQUAD_STAGES * 5, 0, 0xffffffff,
0673                 tegra210_mbdrc_biquad_coeffs_get,
0674                 tegra210_mbdrc_biquad_coeffs_put,
0675                 tegra210_mbdrc_param_info),
0676 
0677     TEGRA_SOC_BYTES_EXT("MBDRC High Band Biquad Coeffs",
0678                 TEGRA210_MBDRC_CFG_RAM_CTRL +
0679                 (TEGRA210_MBDRC_FILTER_PARAM_STRIDE * 2),
0680                 TEGRA210_MBDRC_MAX_BIQUAD_STAGES * 5, 0, 0xffffffff,
0681                 tegra210_mbdrc_biquad_coeffs_get,
0682                 tegra210_mbdrc_biquad_coeffs_put,
0683                 tegra210_mbdrc_param_info),
0684 };
0685 
0686 static bool tegra210_mbdrc_wr_reg(struct device *dev, unsigned int reg)
0687 {
0688     if (reg >= TEGRA210_MBDRC_IIR_CFG)
0689         reg -= ((reg - TEGRA210_MBDRC_IIR_CFG) %
0690             (TEGRA210_MBDRC_FILTER_PARAM_STRIDE *
0691              TEGRA210_MBDRC_FILTER_COUNT));
0692 
0693     switch (reg) {
0694     case TEGRA210_MBDRC_SOFT_RESET:
0695     case TEGRA210_MBDRC_CG:
0696     case TEGRA210_MBDRC_CFG ... TEGRA210_MBDRC_CFG_RAM_DATA:
0697         return true;
0698     default:
0699         return false;
0700     }
0701 }
0702 
0703 static bool tegra210_mbdrc_rd_reg(struct device *dev, unsigned int reg)
0704 {
0705     if (tegra210_mbdrc_wr_reg(dev, reg))
0706         return true;
0707 
0708     if (reg >= TEGRA210_MBDRC_IIR_CFG)
0709         reg -= ((reg - TEGRA210_MBDRC_IIR_CFG) %
0710             (TEGRA210_MBDRC_FILTER_PARAM_STRIDE *
0711              TEGRA210_MBDRC_FILTER_COUNT));
0712 
0713     switch (reg) {
0714     case TEGRA210_MBDRC_STATUS:
0715         return true;
0716     default:
0717         return false;
0718     }
0719 }
0720 
0721 static bool tegra210_mbdrc_volatile_reg(struct device *dev, unsigned int reg)
0722 {
0723     if (reg >= TEGRA210_MBDRC_IIR_CFG)
0724         reg -= ((reg - TEGRA210_MBDRC_IIR_CFG) %
0725             (TEGRA210_MBDRC_FILTER_PARAM_STRIDE *
0726              TEGRA210_MBDRC_FILTER_COUNT));
0727 
0728     switch (reg) {
0729     case TEGRA210_MBDRC_SOFT_RESET:
0730     case TEGRA210_MBDRC_STATUS:
0731     case TEGRA210_MBDRC_CFG_RAM_CTRL:
0732     case TEGRA210_MBDRC_CFG_RAM_DATA:
0733         return true;
0734     default:
0735         return false;
0736     }
0737 }
0738 
0739 static bool tegra210_mbdrc_precious_reg(struct device *dev, unsigned int reg)
0740 {
0741     if (reg >= TEGRA210_MBDRC_IIR_CFG)
0742         reg -= ((reg - TEGRA210_MBDRC_IIR_CFG) %
0743             (TEGRA210_MBDRC_FILTER_PARAM_STRIDE *
0744              TEGRA210_MBDRC_FILTER_COUNT));
0745 
0746     switch (reg) {
0747     case TEGRA210_MBDRC_CFG_RAM_DATA:
0748         return true;
0749     default:
0750         return false;
0751     }
0752 }
0753 
0754 static const struct regmap_config tegra210_mbdrc_regmap_cfg = {
0755     .name           = "mbdrc",
0756     .reg_bits       = 32,
0757     .reg_stride     = 4,
0758     .val_bits       = 32,
0759     .max_register       = TEGRA210_MBDRC_MAX_REG,
0760     .writeable_reg      = tegra210_mbdrc_wr_reg,
0761     .readable_reg       = tegra210_mbdrc_rd_reg,
0762     .volatile_reg       = tegra210_mbdrc_volatile_reg,
0763     .precious_reg       = tegra210_mbdrc_precious_reg,
0764     .reg_defaults       = tegra210_mbdrc_reg_defaults,
0765     .num_reg_defaults   = ARRAY_SIZE(tegra210_mbdrc_reg_defaults),
0766     .cache_type     = REGCACHE_FLAT,
0767 };
0768 
0769 int tegra210_mbdrc_hw_params(struct snd_soc_component *cmpnt)
0770 {
0771     struct tegra210_ope *ope = snd_soc_component_get_drvdata(cmpnt);
0772     const struct tegra210_mbdrc_config *conf = &mbdrc_init_config;
0773     u32 val = 0;
0774     unsigned int i;
0775 
0776     regmap_read(ope->mbdrc_regmap, TEGRA210_MBDRC_CFG, &val);
0777 
0778     val &= TEGRA210_MBDRC_CFG_MBDRC_MODE_MASK;
0779 
0780     if (val == TEGRA210_MBDRC_CFG_MBDRC_MODE_BYPASS)
0781         return 0;
0782 
0783     for (i = 0; i < MBDRC_NUM_BAND; i++) {
0784         const struct tegra210_mbdrc_band_params *params =
0785             &conf->band_params[i];
0786 
0787         u32 reg_off = i * TEGRA210_MBDRC_FILTER_PARAM_STRIDE;
0788 
0789         tegra210_mbdrc_write_ram(ope->mbdrc_regmap,
0790                      reg_off + TEGRA210_MBDRC_CFG_RAM_CTRL,
0791                      reg_off + TEGRA210_MBDRC_CFG_RAM_DATA,
0792                      0, (u32 *)&params->biquad_params[0],
0793                      TEGRA210_MBDRC_MAX_BIQUAD_STAGES * 5);
0794     }
0795     return 0;
0796 }
0797 
0798 int tegra210_mbdrc_component_init(struct snd_soc_component *cmpnt)
0799 {
0800     struct tegra210_ope *ope = snd_soc_component_get_drvdata(cmpnt);
0801     const struct tegra210_mbdrc_config *conf = &mbdrc_init_config;
0802     unsigned int i;
0803     u32 val;
0804 
0805     pm_runtime_get_sync(cmpnt->dev);
0806 
0807     /* Initialize MBDRC registers and AHUB RAM with default params */
0808     regmap_update_bits(ope->mbdrc_regmap, TEGRA210_MBDRC_CFG,
0809         TEGRA210_MBDRC_CFG_MBDRC_MODE_MASK,
0810         conf->mode << TEGRA210_MBDRC_CFG_MBDRC_MODE_SHIFT);
0811 
0812     regmap_update_bits(ope->mbdrc_regmap, TEGRA210_MBDRC_CFG,
0813         TEGRA210_MBDRC_CFG_RMS_OFFSET_MASK,
0814         conf->rms_off << TEGRA210_MBDRC_CFG_RMS_OFFSET_SHIFT);
0815 
0816     regmap_update_bits(ope->mbdrc_regmap, TEGRA210_MBDRC_CFG,
0817         TEGRA210_MBDRC_CFG_PEAK_RMS_MASK,
0818         conf->peak_rms_mode << TEGRA210_MBDRC_CFG_PEAK_RMS_SHIFT);
0819 
0820     regmap_update_bits(ope->mbdrc_regmap, TEGRA210_MBDRC_CFG,
0821         TEGRA210_MBDRC_CFG_FILTER_STRUCTURE_MASK,
0822         conf->fliter_structure <<
0823         TEGRA210_MBDRC_CFG_FILTER_STRUCTURE_SHIFT);
0824 
0825     regmap_update_bits(ope->mbdrc_regmap, TEGRA210_MBDRC_CFG,
0826         TEGRA210_MBDRC_CFG_SHIFT_CTRL_MASK,
0827         conf->shift_ctrl << TEGRA210_MBDRC_CFG_SHIFT_CTRL_SHIFT);
0828 
0829     regmap_update_bits(ope->mbdrc_regmap, TEGRA210_MBDRC_CFG,
0830         TEGRA210_MBDRC_CFG_FRAME_SIZE_MASK,
0831         __ffs(conf->frame_size) <<
0832         TEGRA210_MBDRC_CFG_FRAME_SIZE_SHIFT);
0833 
0834     regmap_update_bits(ope->mbdrc_regmap, TEGRA210_MBDRC_CHANNEL_MASK,
0835         TEGRA210_MBDRC_CHANNEL_MASK_MASK,
0836         conf->channel_mask << TEGRA210_MBDRC_CHANNEL_MASK_SHIFT);
0837 
0838     regmap_update_bits(ope->mbdrc_regmap, TEGRA210_MBDRC_FAST_FACTOR,
0839         TEGRA210_MBDRC_FAST_FACTOR_ATTACK_MASK,
0840         conf->fa_factor << TEGRA210_MBDRC_FAST_FACTOR_ATTACK_SHIFT);
0841 
0842     regmap_update_bits(ope->mbdrc_regmap, TEGRA210_MBDRC_FAST_FACTOR,
0843         TEGRA210_MBDRC_FAST_FACTOR_ATTACK_MASK,
0844         conf->fr_factor << TEGRA210_MBDRC_FAST_FACTOR_ATTACK_SHIFT);
0845 
0846     for (i = 0; i < MBDRC_NUM_BAND; i++) {
0847         const struct tegra210_mbdrc_band_params *params =
0848                         &conf->band_params[i];
0849         u32 reg_off = i * TEGRA210_MBDRC_FILTER_PARAM_STRIDE;
0850 
0851         regmap_update_bits(ope->mbdrc_regmap,
0852             reg_off + TEGRA210_MBDRC_IIR_CFG,
0853             TEGRA210_MBDRC_IIR_CFG_NUM_STAGES_MASK,
0854             params->iir_stages <<
0855                 TEGRA210_MBDRC_IIR_CFG_NUM_STAGES_SHIFT);
0856 
0857         regmap_update_bits(ope->mbdrc_regmap,
0858             reg_off + TEGRA210_MBDRC_IN_ATTACK,
0859             TEGRA210_MBDRC_IN_ATTACK_TC_MASK,
0860             params->in_attack_tc <<
0861                 TEGRA210_MBDRC_IN_ATTACK_TC_SHIFT);
0862 
0863         regmap_update_bits(ope->mbdrc_regmap,
0864             reg_off + TEGRA210_MBDRC_IN_RELEASE,
0865             TEGRA210_MBDRC_IN_RELEASE_TC_MASK,
0866             params->in_release_tc <<
0867                 TEGRA210_MBDRC_IN_RELEASE_TC_SHIFT);
0868 
0869         regmap_update_bits(ope->mbdrc_regmap,
0870             reg_off + TEGRA210_MBDRC_FAST_ATTACK,
0871             TEGRA210_MBDRC_FAST_ATTACK_TC_MASK,
0872             params->fast_attack_tc <<
0873                 TEGRA210_MBDRC_FAST_ATTACK_TC_SHIFT);
0874 
0875         val = (((params->in_threshold[0] >>
0876              TEGRA210_MBDRC_THRESH_1ST_SHIFT) &
0877             TEGRA210_MBDRC_THRESH_1ST_MASK) |
0878             ((params->in_threshold[1] >>
0879               TEGRA210_MBDRC_THRESH_2ND_SHIFT) &
0880              TEGRA210_MBDRC_THRESH_2ND_MASK) |
0881             ((params->in_threshold[2] >>
0882               TEGRA210_MBDRC_THRESH_3RD_SHIFT) &
0883              TEGRA210_MBDRC_THRESH_3RD_MASK) |
0884             ((params->in_threshold[3] >>
0885               TEGRA210_MBDRC_THRESH_4TH_SHIFT) &
0886              TEGRA210_MBDRC_THRESH_4TH_MASK));
0887 
0888         regmap_update_bits(ope->mbdrc_regmap,
0889                    reg_off + TEGRA210_MBDRC_IN_THRESHOLD,
0890                    0xffffffff, val);
0891 
0892         val = (((params->out_threshold[0] >>
0893              TEGRA210_MBDRC_THRESH_1ST_SHIFT) &
0894             TEGRA210_MBDRC_THRESH_1ST_MASK) |
0895             ((params->out_threshold[1] >>
0896               TEGRA210_MBDRC_THRESH_2ND_SHIFT) &
0897              TEGRA210_MBDRC_THRESH_2ND_MASK) |
0898             ((params->out_threshold[2] >>
0899               TEGRA210_MBDRC_THRESH_3RD_SHIFT) &
0900              TEGRA210_MBDRC_THRESH_3RD_MASK) |
0901             ((params->out_threshold[3] >>
0902               TEGRA210_MBDRC_THRESH_4TH_SHIFT) &
0903              TEGRA210_MBDRC_THRESH_4TH_MASK));
0904 
0905         regmap_update_bits(ope->mbdrc_regmap,
0906             reg_off + TEGRA210_MBDRC_OUT_THRESHOLD,
0907             0xffffffff, val);
0908 
0909         regmap_update_bits(ope->mbdrc_regmap,
0910             reg_off + TEGRA210_MBDRC_RATIO_1ST,
0911             TEGRA210_MBDRC_RATIO_1ST_MASK,
0912             params->ratio[0] << TEGRA210_MBDRC_RATIO_1ST_SHIFT);
0913 
0914         regmap_update_bits(ope->mbdrc_regmap,
0915             reg_off + TEGRA210_MBDRC_RATIO_2ND,
0916             TEGRA210_MBDRC_RATIO_2ND_MASK,
0917             params->ratio[1] << TEGRA210_MBDRC_RATIO_2ND_SHIFT);
0918 
0919         regmap_update_bits(ope->mbdrc_regmap,
0920             reg_off + TEGRA210_MBDRC_RATIO_3RD,
0921             TEGRA210_MBDRC_RATIO_3RD_MASK,
0922             params->ratio[2] << TEGRA210_MBDRC_RATIO_3RD_SHIFT);
0923 
0924         regmap_update_bits(ope->mbdrc_regmap,
0925             reg_off + TEGRA210_MBDRC_RATIO_4TH,
0926             TEGRA210_MBDRC_RATIO_4TH_MASK,
0927             params->ratio[3] << TEGRA210_MBDRC_RATIO_4TH_SHIFT);
0928 
0929         regmap_update_bits(ope->mbdrc_regmap,
0930             reg_off + TEGRA210_MBDRC_RATIO_5TH,
0931             TEGRA210_MBDRC_RATIO_5TH_MASK,
0932             params->ratio[4] << TEGRA210_MBDRC_RATIO_5TH_SHIFT);
0933 
0934         regmap_update_bits(ope->mbdrc_regmap,
0935             reg_off + TEGRA210_MBDRC_MAKEUP_GAIN,
0936             TEGRA210_MBDRC_MAKEUP_GAIN_MASK,
0937             params->makeup_gain <<
0938                 TEGRA210_MBDRC_MAKEUP_GAIN_SHIFT);
0939 
0940         regmap_update_bits(ope->mbdrc_regmap,
0941             reg_off + TEGRA210_MBDRC_INIT_GAIN,
0942             TEGRA210_MBDRC_INIT_GAIN_MASK,
0943             params->gain_init <<
0944                 TEGRA210_MBDRC_INIT_GAIN_SHIFT);
0945 
0946         regmap_update_bits(ope->mbdrc_regmap,
0947             reg_off + TEGRA210_MBDRC_GAIN_ATTACK,
0948             TEGRA210_MBDRC_GAIN_ATTACK_MASK,
0949             params->gain_attack_tc <<
0950                 TEGRA210_MBDRC_GAIN_ATTACK_SHIFT);
0951 
0952         regmap_update_bits(ope->mbdrc_regmap,
0953             reg_off + TEGRA210_MBDRC_GAIN_RELEASE,
0954             TEGRA210_MBDRC_GAIN_RELEASE_MASK,
0955             params->gain_release_tc <<
0956                 TEGRA210_MBDRC_GAIN_RELEASE_SHIFT);
0957 
0958         regmap_update_bits(ope->mbdrc_regmap,
0959             reg_off + TEGRA210_MBDRC_FAST_RELEASE,
0960             TEGRA210_MBDRC_FAST_RELEASE_MASK,
0961             params->fast_release_tc <<
0962                 TEGRA210_MBDRC_FAST_RELEASE_SHIFT);
0963 
0964         tegra210_mbdrc_write_ram(ope->mbdrc_regmap,
0965             reg_off + TEGRA210_MBDRC_CFG_RAM_CTRL,
0966             reg_off + TEGRA210_MBDRC_CFG_RAM_DATA, 0,
0967             (u32 *)&params->biquad_params[0],
0968             TEGRA210_MBDRC_MAX_BIQUAD_STAGES * 5);
0969     }
0970 
0971     pm_runtime_put_sync(cmpnt->dev);
0972 
0973     snd_soc_add_component_controls(cmpnt, tegra210_mbdrc_controls,
0974                        ARRAY_SIZE(tegra210_mbdrc_controls));
0975 
0976     return 0;
0977 }
0978 
0979 int tegra210_mbdrc_regmap_init(struct platform_device *pdev)
0980 {
0981     struct device *dev = &pdev->dev;
0982     struct tegra210_ope *ope = dev_get_drvdata(dev);
0983     struct device_node *child;
0984     struct resource mem;
0985     void __iomem *regs;
0986     int err;
0987 
0988     child = of_get_child_by_name(dev->of_node, "dynamic-range-compressor");
0989     if (!child)
0990         return -ENODEV;
0991 
0992     err = of_address_to_resource(child, 0, &mem);
0993     of_node_put(child);
0994     if (err < 0) {
0995         dev_err(dev, "fail to get MBDRC resource\n");
0996         return err;
0997     }
0998 
0999     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 }