123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014 |
- // SPDX-License-Identifier: GPL-2.0-only
- //
- // tegra210_mbdrc.c - Tegra210 MBDRC driver
- //
- // Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved.
- #include <linux/device.h>
- #include <linux/io.h>
- #include <linux/module.h>
- #include <linux/of_address.h>
- #include <linux/pm_runtime.h>
- #include <linux/regmap.h>
- #include <sound/core.h>
- #include <sound/soc.h>
- #include <sound/tlv.h>
- #include "tegra210_mbdrc.h"
- #include "tegra210_ope.h"
- #define MBDRC_FILTER_REG(reg, id) \
- ((reg) + ((id) * TEGRA210_MBDRC_FILTER_PARAM_STRIDE))
- #define MBDRC_FILTER_REG_DEFAULTS(id) \
- { MBDRC_FILTER_REG(TEGRA210_MBDRC_IIR_CFG, id), 0x00000005}, \
- { MBDRC_FILTER_REG(TEGRA210_MBDRC_IN_ATTACK, id), 0x3e48590c}, \
- { MBDRC_FILTER_REG(TEGRA210_MBDRC_IN_RELEASE, id), 0x08414e9f}, \
- { MBDRC_FILTER_REG(TEGRA210_MBDRC_FAST_ATTACK, id), 0x7fffffff}, \
- { MBDRC_FILTER_REG(TEGRA210_MBDRC_IN_THRESHOLD, id), 0x06145082}, \
- { MBDRC_FILTER_REG(TEGRA210_MBDRC_OUT_THRESHOLD, id), 0x060d379b}, \
- { MBDRC_FILTER_REG(TEGRA210_MBDRC_RATIO_1ST, id), 0x0000a000}, \
- { MBDRC_FILTER_REG(TEGRA210_MBDRC_RATIO_2ND, id), 0x00002000}, \
- { MBDRC_FILTER_REG(TEGRA210_MBDRC_RATIO_3RD, id), 0x00000b33}, \
- { MBDRC_FILTER_REG(TEGRA210_MBDRC_RATIO_4TH, id), 0x00000800}, \
- { MBDRC_FILTER_REG(TEGRA210_MBDRC_RATIO_5TH, id), 0x0000019a}, \
- { MBDRC_FILTER_REG(TEGRA210_MBDRC_MAKEUP_GAIN, id), 0x00000002}, \
- { MBDRC_FILTER_REG(TEGRA210_MBDRC_INIT_GAIN, id), 0x00066666}, \
- { MBDRC_FILTER_REG(TEGRA210_MBDRC_GAIN_ATTACK, id), 0x00d9ba0e}, \
- { MBDRC_FILTER_REG(TEGRA210_MBDRC_GAIN_RELEASE, id), 0x3e48590c}, \
- { MBDRC_FILTER_REG(TEGRA210_MBDRC_FAST_RELEASE, id), 0x7ffff26a}, \
- { MBDRC_FILTER_REG(TEGRA210_MBDRC_CFG_RAM_CTRL, id), 0x4000}
- static const struct reg_default tegra210_mbdrc_reg_defaults[] = {
- { TEGRA210_MBDRC_CFG, 0x0030de51},
- { TEGRA210_MBDRC_CHANNEL_MASK, 0x00000003},
- { TEGRA210_MBDRC_FAST_FACTOR, 0x30000800},
- MBDRC_FILTER_REG_DEFAULTS(0),
- MBDRC_FILTER_REG_DEFAULTS(1),
- MBDRC_FILTER_REG_DEFAULTS(2),
- };
- /* Default MBDRC parameters */
- static const struct tegra210_mbdrc_config mbdrc_init_config = {
- .mode = 0, /* Bypass */
- .rms_off = 48,
- .peak_rms_mode = 1, /* PEAK */
- .fliter_structure = 0, /* All-pass tree */
- .shift_ctrl = 30,
- .frame_size = 32,
- .channel_mask = 0x3,
- .fa_factor = 2048,
- .fr_factor = 14747,
- .band_params[MBDRC_LOW_BAND] = {
- .band = MBDRC_LOW_BAND,
- .iir_stages = 5,
- .in_attack_tc = 1044928780,
- .in_release_tc = 138497695,
- .fast_attack_tc = 2147483647,
- .in_threshold = {130, 80, 20, 6},
- .out_threshold = {155, 55, 13, 6},
- .ratio = {40960, 8192, 2867, 2048, 410},
- .makeup_gain = 4,
- .gain_init = 419430,
- .gain_attack_tc = 14268942,
- .gain_release_tc = 1440547090,
- .fast_release_tc = 2147480170,
- .biquad_params = {
- /*
- * Gains:
- *
- * b0, b1, a0,
- * a1, a2,
- */
- /* Band-0 */
- 961046798, -2030431983, 1073741824,
- 2030431983, -961046798,
- /* Band-1 */
- 1030244425, -2099481453, 1073741824,
- 2099481453, -1030244425,
- /* Band-2 */
- 1067169294, -2136327263, 1073741824,
- 2136327263, -1067169294,
- /* Band-3 */
- 434951949, -1306567134, 1073741824,
- 1306567134, -434951949,
- /* Band-4 */
- 780656019, -1605955641, 1073741824,
- 1605955641, -780656019,
- /* Band-5 */
- 1024497031, -1817128152, 1073741824,
- 1817128152, -1024497031,
- /* Band-6 */
- 1073741824, 0, 0,
- 0, 0,
- /* Band-7 */
- 1073741824, 0, 0,
- 0, 0,
- }
- },
- .band_params[MBDRC_MID_BAND] = {
- .band = MBDRC_MID_BAND,
- .iir_stages = 5,
- .in_attack_tc = 1581413104,
- .in_release_tc = 35494783,
- .fast_attack_tc = 2147483647,
- .in_threshold = {130, 50, 30, 6},
- .out_threshold = {106, 50, 30, 13},
- .ratio = {40960, 2867, 4096, 2867, 410},
- .makeup_gain = 6,
- .gain_init = 419430,
- .gain_attack_tc = 4766887,
- .gain_release_tc = 1044928780,
- .fast_release_tc = 2147480170,
- .biquad_params = {
- /*
- * Gains:
- *
- * b0, b1, a0,
- * a1, a2,
- */
- /* Band-0 */
- -1005668963, 1073741824, 0,
- 1005668963, 0,
- /* Band-1 */
- 998437058, -2067742187, 1073741824,
- 2067742187, -998437058,
- /* Band-2 */
- 1051963422, -2121153948, 1073741824,
- 2121153948, -1051963422,
- /* Band-3 */
- 434951949, -1306567134, 1073741824,
- 1306567134, -434951949,
- /* Band-4 */
- 780656019, -1605955641, 1073741824,
- 1605955641, -780656019,
- /* Band-5 */
- 1024497031, -1817128152, 1073741824,
- 1817128152, -1024497031,
- /* Band-6 */
- 1073741824, 0, 0,
- 0, 0,
- /* Band-7 */
- 1073741824, 0, 0,
- 0, 0,
- }
- },
- .band_params[MBDRC_HIGH_BAND] = {
- .band = MBDRC_HIGH_BAND,
- .iir_stages = 5,
- .in_attack_tc = 2144750688,
- .in_release_tc = 70402888,
- .fast_attack_tc = 2147483647,
- .in_threshold = {130, 50, 30, 6},
- .out_threshold = {106, 50, 30, 13},
- .ratio = {40960, 2867, 4096, 2867, 410},
- .makeup_gain = 6,
- .gain_init = 419430,
- .gain_attack_tc = 4766887,
- .gain_release_tc = 1044928780,
- .fast_release_tc = 2147480170,
- .biquad_params = {
- /*
- * Gains:
- *
- * b0, b1, a0,
- * a1, a2,
- */
- /* Band-0 */
- 1073741824, 0, 0,
- 0, 0,
- /* Band-1 */
- 1073741824, 0, 0,
- 0, 0,
- /* Band-2 */
- 1073741824, 0, 0,
- 0, 0,
- /* Band-3 */
- -619925131, 1073741824, 0,
- 619925131, 0,
- /* Band-4 */
- 606839335, -1455425976, 1073741824,
- 1455425976, -606839335,
- /* Band-5 */
- 917759617, -1724690840, 1073741824,
- 1724690840, -917759617,
- /* Band-6 */
- 1073741824, 0, 0,
- 0, 0,
- /* Band-7 */
- 1073741824, 0, 0,
- 0, 0,
- }
- }
- };
- static void tegra210_mbdrc_write_ram(struct regmap *regmap, unsigned int reg_ctrl,
- unsigned int reg_data, unsigned int ram_offset,
- unsigned int *data, size_t size)
- {
- unsigned int val;
- unsigned int i;
- val = ram_offset & TEGRA210_MBDRC_RAM_CTRL_RAM_ADDR_MASK;
- val |= TEGRA210_MBDRC_RAM_CTRL_ADDR_INIT_EN;
- val |= TEGRA210_MBDRC_RAM_CTRL_SEQ_ACCESS_EN;
- val |= TEGRA210_MBDRC_RAM_CTRL_RW_WRITE;
- regmap_write(regmap, reg_ctrl, val);
- for (i = 0; i < size; i++)
- regmap_write(regmap, reg_data, data[i]);
- }
- static int tegra210_mbdrc_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
- {
- struct soc_mixer_control *mc =
- (struct soc_mixer_control *)kcontrol->private_value;
- struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
- struct tegra210_ope *ope = snd_soc_component_get_drvdata(cmpnt);
- unsigned int val;
- regmap_read(ope->mbdrc_regmap, mc->reg, &val);
- ucontrol->value.integer.value[0] = (val >> mc->shift) & mc->max;
- return 0;
- }
- static int tegra210_mbdrc_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
- {
- struct soc_mixer_control *mc =
- (struct soc_mixer_control *)kcontrol->private_value;
- struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
- struct tegra210_ope *ope = snd_soc_component_get_drvdata(cmpnt);
- unsigned int val = ucontrol->value.integer.value[0];
- bool change = false;
- val = val << mc->shift;
- regmap_update_bits_check(ope->mbdrc_regmap, mc->reg,
- (mc->max << mc->shift), val, &change);
- return change ? 1 : 0;
- }
- static int tegra210_mbdrc_get_enum(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
- {
- struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
- struct tegra210_ope *ope = snd_soc_component_get_drvdata(cmpnt);
- struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
- unsigned int val;
- regmap_read(ope->mbdrc_regmap, e->reg, &val);
- ucontrol->value.enumerated.item[0] = (val >> e->shift_l) & e->mask;
- return 0;
- }
- static int tegra210_mbdrc_put_enum(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
- {
- struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
- struct tegra210_ope *ope = snd_soc_component_get_drvdata(cmpnt);
- struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
- bool change = false;
- unsigned int val;
- unsigned int mask;
- if (ucontrol->value.enumerated.item[0] > e->items - 1)
- return -EINVAL;
- val = ucontrol->value.enumerated.item[0] << e->shift_l;
- mask = e->mask << e->shift_l;
- regmap_update_bits_check(ope->mbdrc_regmap, e->reg, mask, val,
- &change);
- return change ? 1 : 0;
- }
- static int tegra210_mbdrc_band_params_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
- {
- struct tegra_soc_bytes *params = (void *)kcontrol->private_value;
- struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
- struct tegra210_ope *ope = snd_soc_component_get_drvdata(cmpnt);
- u32 *data = (u32 *)ucontrol->value.bytes.data;
- u32 regs = params->soc.base;
- u32 mask = params->soc.mask;
- u32 shift = params->shift;
- unsigned int i;
- for (i = 0; i < params->soc.num_regs; i++, regs += cmpnt->val_bytes) {
- regmap_read(ope->mbdrc_regmap, regs, &data[i]);
- data[i] = ((data[i] & mask) >> shift);
- }
- return 0;
- }
- static int tegra210_mbdrc_band_params_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
- {
- struct tegra_soc_bytes *params = (void *)kcontrol->private_value;
- struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
- struct tegra210_ope *ope = snd_soc_component_get_drvdata(cmpnt);
- u32 *data = (u32 *)ucontrol->value.bytes.data;
- u32 regs = params->soc.base;
- u32 mask = params->soc.mask;
- u32 shift = params->shift;
- bool change = false;
- unsigned int i;
- for (i = 0; i < params->soc.num_regs; i++, regs += cmpnt->val_bytes) {
- bool update = false;
- regmap_update_bits_check(ope->mbdrc_regmap, regs, mask,
- data[i] << shift, &update);
- change |= update;
- }
- return change ? 1 : 0;
- }
- static int tegra210_mbdrc_threshold_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
- {
- struct tegra_soc_bytes *params = (void *)kcontrol->private_value;
- struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
- struct tegra210_ope *ope = snd_soc_component_get_drvdata(cmpnt);
- u32 *data = (u32 *)ucontrol->value.bytes.data;
- u32 regs = params->soc.base;
- u32 num_regs = params->soc.num_regs;
- u32 val;
- unsigned int i;
- for (i = 0; i < num_regs; i += 4, regs += cmpnt->val_bytes) {
- regmap_read(ope->mbdrc_regmap, regs, &val);
- data[i] = (val & TEGRA210_MBDRC_THRESH_1ST_MASK) >>
- TEGRA210_MBDRC_THRESH_1ST_SHIFT;
- data[i + 1] = (val & TEGRA210_MBDRC_THRESH_2ND_MASK) >>
- TEGRA210_MBDRC_THRESH_2ND_SHIFT;
- data[i + 2] = (val & TEGRA210_MBDRC_THRESH_3RD_MASK) >>
- TEGRA210_MBDRC_THRESH_3RD_SHIFT;
- data[i + 3] = (val & TEGRA210_MBDRC_THRESH_4TH_MASK) >>
- TEGRA210_MBDRC_THRESH_4TH_SHIFT;
- }
- return 0;
- }
- static int tegra210_mbdrc_threshold_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
- {
- struct tegra_soc_bytes *params = (void *)kcontrol->private_value;
- struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
- struct tegra210_ope *ope = snd_soc_component_get_drvdata(cmpnt);
- u32 *data = (u32 *)ucontrol->value.bytes.data;
- u32 regs = params->soc.base;
- u32 num_regs = params->soc.num_regs;
- bool change = false;
- unsigned int i;
- for (i = 0; i < num_regs; i += 4, regs += cmpnt->val_bytes) {
- bool update = false;
- data[i] = (((data[i] >> TEGRA210_MBDRC_THRESH_1ST_SHIFT) &
- TEGRA210_MBDRC_THRESH_1ST_MASK) |
- ((data[i + 1] >> TEGRA210_MBDRC_THRESH_2ND_SHIFT) &
- TEGRA210_MBDRC_THRESH_2ND_MASK) |
- ((data[i + 2] >> TEGRA210_MBDRC_THRESH_3RD_SHIFT) &
- TEGRA210_MBDRC_THRESH_3RD_MASK) |
- ((data[i + 3] >> TEGRA210_MBDRC_THRESH_4TH_SHIFT) &
- TEGRA210_MBDRC_THRESH_4TH_MASK));
- regmap_update_bits_check(ope->mbdrc_regmap, regs, 0xffffffff,
- data[i], &update);
- change |= update;
- }
- return change ? 1 : 0;
- }
- static int tegra210_mbdrc_biquad_coeffs_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
- {
- struct tegra_soc_bytes *params = (void *)kcontrol->private_value;
- struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
- u32 *data = (u32 *)ucontrol->value.bytes.data;
- memset(data, 0, params->soc.num_regs * cmpnt->val_bytes);
- return 0;
- }
- static int tegra210_mbdrc_biquad_coeffs_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
- {
- struct tegra_soc_bytes *params = (void *)kcontrol->private_value;
- struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
- struct tegra210_ope *ope = snd_soc_component_get_drvdata(cmpnt);
- u32 reg_ctrl = params->soc.base;
- u32 reg_data = reg_ctrl + cmpnt->val_bytes;
- u32 *data = (u32 *)ucontrol->value.bytes.data;
- tegra210_mbdrc_write_ram(ope->mbdrc_regmap, reg_ctrl, reg_data,
- params->shift, data, params->soc.num_regs);
- return 1;
- }
- static int tegra210_mbdrc_param_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
- {
- struct soc_bytes *params = (void *)kcontrol->private_value;
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
- uinfo->count = params->num_regs * sizeof(u32);
- return 0;
- }
- static int tegra210_mbdrc_vol_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
- {
- struct soc_mixer_control *mc =
- (struct soc_mixer_control *)kcontrol->private_value;
- struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
- struct tegra210_ope *ope = snd_soc_component_get_drvdata(cmpnt);
- int val;
- regmap_read(ope->mbdrc_regmap, mc->reg, &val);
- ucontrol->value.integer.value[0] =
- ((val >> mc->shift) - TEGRA210_MBDRC_MASTER_VOL_MIN);
- return 0;
- }
- static int tegra210_mbdrc_vol_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
- {
- struct soc_mixer_control *mc =
- (struct soc_mixer_control *)kcontrol->private_value;
- struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
- struct tegra210_ope *ope = snd_soc_component_get_drvdata(cmpnt);
- int val = ucontrol->value.integer.value[0];
- bool change = false;
- val += TEGRA210_MBDRC_MASTER_VOL_MIN;
- regmap_update_bits_check(ope->mbdrc_regmap, mc->reg,
- mc->max << mc->shift, val << mc->shift,
- &change);
- regmap_read(ope->mbdrc_regmap, mc->reg, &val);
- return change ? 1 : 0;
- }
- static const char * const tegra210_mbdrc_mode_text[] = {
- "Bypass", "Fullband", "Dualband", "Multiband"
- };
- static const struct soc_enum tegra210_mbdrc_mode_enum =
- SOC_ENUM_SINGLE(TEGRA210_MBDRC_CFG, TEGRA210_MBDRC_CFG_MBDRC_MODE_SHIFT,
- 4, tegra210_mbdrc_mode_text);
- static const char * const tegra210_mbdrc_peak_rms_text[] = {
- "Peak", "RMS"
- };
- static const struct soc_enum tegra210_mbdrc_peak_rms_enum =
- SOC_ENUM_SINGLE(TEGRA210_MBDRC_CFG, TEGRA210_MBDRC_CFG_PEAK_RMS_SHIFT,
- 2, tegra210_mbdrc_peak_rms_text);
- static const char * const tegra210_mbdrc_filter_structure_text[] = {
- "All-pass-tree", "Flexible"
- };
- static const struct soc_enum tegra210_mbdrc_filter_structure_enum =
- SOC_ENUM_SINGLE(TEGRA210_MBDRC_CFG,
- TEGRA210_MBDRC_CFG_FILTER_STRUCTURE_SHIFT, 2,
- tegra210_mbdrc_filter_structure_text);
- static const char * const tegra210_mbdrc_frame_size_text[] = {
- "N1", "N2", "N4", "N8", "N16", "N32", "N64"
- };
- static const struct soc_enum tegra210_mbdrc_frame_size_enum =
- SOC_ENUM_SINGLE(TEGRA210_MBDRC_CFG, TEGRA210_MBDRC_CFG_FRAME_SIZE_SHIFT,
- 7, tegra210_mbdrc_frame_size_text);
- #define TEGRA_MBDRC_BYTES_EXT(xname, xbase, xregs, xshift, xmask, xinfo) \
- TEGRA_SOC_BYTES_EXT(xname, xbase, xregs, xshift, xmask, \
- tegra210_mbdrc_band_params_get, \
- tegra210_mbdrc_band_params_put, \
- tegra210_mbdrc_param_info)
- #define TEGRA_MBDRC_BAND_BYTES_EXT(xname, xbase, xshift, xmask, xinfo) \
- TEGRA_MBDRC_BYTES_EXT(xname, xbase, TEGRA210_MBDRC_FILTER_COUNT, \
- xshift, xmask, xinfo)
- static const DECLARE_TLV_DB_MINMAX(mdbrc_vol_tlv, -25600, 25500);
- static const struct snd_kcontrol_new tegra210_mbdrc_controls[] = {
- SOC_ENUM_EXT("MBDRC Peak RMS Mode", tegra210_mbdrc_peak_rms_enum,
- tegra210_mbdrc_get_enum, tegra210_mbdrc_put_enum),
- SOC_ENUM_EXT("MBDRC Filter Structure",
- tegra210_mbdrc_filter_structure_enum,
- tegra210_mbdrc_get_enum, tegra210_mbdrc_put_enum),
- SOC_ENUM_EXT("MBDRC Frame Size", tegra210_mbdrc_frame_size_enum,
- tegra210_mbdrc_get_enum, tegra210_mbdrc_put_enum),
- SOC_ENUM_EXT("MBDRC Mode", tegra210_mbdrc_mode_enum,
- tegra210_mbdrc_get_enum, tegra210_mbdrc_put_enum),
- SOC_SINGLE_EXT("MBDRC RMS Offset", TEGRA210_MBDRC_CFG,
- TEGRA210_MBDRC_CFG_RMS_OFFSET_SHIFT, 0x1ff, 0,
- tegra210_mbdrc_get, tegra210_mbdrc_put),
- SOC_SINGLE_EXT("MBDRC Shift Control", TEGRA210_MBDRC_CFG,
- TEGRA210_MBDRC_CFG_SHIFT_CTRL_SHIFT, 0x1f, 0,
- tegra210_mbdrc_get, tegra210_mbdrc_put),
- SOC_SINGLE_EXT("MBDRC Fast Attack Factor", TEGRA210_MBDRC_FAST_FACTOR,
- TEGRA210_MBDRC_FAST_FACTOR_ATTACK_SHIFT, 0xffff, 0,
- tegra210_mbdrc_get, tegra210_mbdrc_put),
- SOC_SINGLE_EXT("MBDRC Fast Release Factor", TEGRA210_MBDRC_FAST_FACTOR,
- TEGRA210_MBDRC_FAST_FACTOR_RELEASE_SHIFT, 0xffff, 0,
- tegra210_mbdrc_get, tegra210_mbdrc_put),
- SOC_SINGLE_RANGE_EXT_TLV("MBDRC Master Volume",
- TEGRA210_MBDRC_MASTER_VOL,
- TEGRA210_MBDRC_MASTER_VOL_SHIFT,
- 0, 0x1ff, 0,
- tegra210_mbdrc_vol_get, tegra210_mbdrc_vol_put,
- mdbrc_vol_tlv),
- TEGRA_SOC_BYTES_EXT("MBDRC IIR Stages", TEGRA210_MBDRC_IIR_CFG,
- TEGRA210_MBDRC_FILTER_COUNT,
- TEGRA210_MBDRC_IIR_CFG_NUM_STAGES_SHIFT,
- TEGRA210_MBDRC_IIR_CFG_NUM_STAGES_MASK,
- tegra210_mbdrc_band_params_get,
- tegra210_mbdrc_band_params_put,
- tegra210_mbdrc_param_info),
- TEGRA_SOC_BYTES_EXT("MBDRC In Attack Time Const", TEGRA210_MBDRC_IN_ATTACK,
- TEGRA210_MBDRC_FILTER_COUNT,
- TEGRA210_MBDRC_IN_ATTACK_TC_SHIFT,
- TEGRA210_MBDRC_IN_ATTACK_TC_MASK,
- tegra210_mbdrc_band_params_get,
- tegra210_mbdrc_band_params_put,
- tegra210_mbdrc_param_info),
- TEGRA_SOC_BYTES_EXT("MBDRC In Release Time Const", TEGRA210_MBDRC_IN_RELEASE,
- TEGRA210_MBDRC_FILTER_COUNT,
- TEGRA210_MBDRC_IN_RELEASE_TC_SHIFT,
- TEGRA210_MBDRC_IN_RELEASE_TC_MASK,
- tegra210_mbdrc_band_params_get,
- tegra210_mbdrc_band_params_put,
- tegra210_mbdrc_param_info),
- TEGRA_SOC_BYTES_EXT("MBDRC Fast Attack Time Const", TEGRA210_MBDRC_FAST_ATTACK,
- TEGRA210_MBDRC_FILTER_COUNT,
- TEGRA210_MBDRC_FAST_ATTACK_TC_SHIFT,
- TEGRA210_MBDRC_FAST_ATTACK_TC_MASK,
- tegra210_mbdrc_band_params_get,
- tegra210_mbdrc_band_params_put,
- tegra210_mbdrc_param_info),
- TEGRA_SOC_BYTES_EXT("MBDRC In Threshold", TEGRA210_MBDRC_IN_THRESHOLD,
- TEGRA210_MBDRC_FILTER_COUNT * 4, 0, 0xffffffff,
- tegra210_mbdrc_threshold_get,
- tegra210_mbdrc_threshold_put,
- tegra210_mbdrc_param_info),
- TEGRA_SOC_BYTES_EXT("MBDRC Out Threshold", TEGRA210_MBDRC_OUT_THRESHOLD,
- TEGRA210_MBDRC_FILTER_COUNT * 4, 0, 0xffffffff,
- tegra210_mbdrc_threshold_get,
- tegra210_mbdrc_threshold_put,
- tegra210_mbdrc_param_info),
- TEGRA_SOC_BYTES_EXT("MBDRC Ratio", TEGRA210_MBDRC_RATIO_1ST,
- TEGRA210_MBDRC_FILTER_COUNT * 5,
- TEGRA210_MBDRC_RATIO_1ST_SHIFT, TEGRA210_MBDRC_RATIO_1ST_MASK,
- tegra210_mbdrc_band_params_get,
- tegra210_mbdrc_band_params_put,
- tegra210_mbdrc_param_info),
- TEGRA_SOC_BYTES_EXT("MBDRC Makeup Gain", TEGRA210_MBDRC_MAKEUP_GAIN,
- TEGRA210_MBDRC_FILTER_COUNT,
- TEGRA210_MBDRC_MAKEUP_GAIN_SHIFT,
- TEGRA210_MBDRC_MAKEUP_GAIN_MASK,
- tegra210_mbdrc_band_params_get,
- tegra210_mbdrc_band_params_put,
- tegra210_mbdrc_param_info),
- TEGRA_SOC_BYTES_EXT("MBDRC Init Gain", TEGRA210_MBDRC_INIT_GAIN,
- TEGRA210_MBDRC_FILTER_COUNT,
- TEGRA210_MBDRC_INIT_GAIN_SHIFT,
- TEGRA210_MBDRC_INIT_GAIN_MASK,
- tegra210_mbdrc_band_params_get,
- tegra210_mbdrc_band_params_put,
- tegra210_mbdrc_param_info),
- TEGRA_SOC_BYTES_EXT("MBDRC Attack Gain", TEGRA210_MBDRC_GAIN_ATTACK,
- TEGRA210_MBDRC_FILTER_COUNT,
- TEGRA210_MBDRC_GAIN_ATTACK_SHIFT,
- TEGRA210_MBDRC_GAIN_ATTACK_MASK,
- tegra210_mbdrc_band_params_get,
- tegra210_mbdrc_band_params_put,
- tegra210_mbdrc_param_info),
- TEGRA_SOC_BYTES_EXT("MBDRC Release Gain", TEGRA210_MBDRC_GAIN_RELEASE,
- TEGRA210_MBDRC_FILTER_COUNT,
- TEGRA210_MBDRC_GAIN_RELEASE_SHIFT,
- TEGRA210_MBDRC_GAIN_RELEASE_MASK,
- tegra210_mbdrc_band_params_get,
- tegra210_mbdrc_band_params_put,
- tegra210_mbdrc_param_info),
- TEGRA_SOC_BYTES_EXT("MBDRC Fast Release Gain",
- TEGRA210_MBDRC_FAST_RELEASE,
- TEGRA210_MBDRC_FILTER_COUNT,
- TEGRA210_MBDRC_FAST_RELEASE_SHIFT,
- TEGRA210_MBDRC_FAST_RELEASE_MASK,
- tegra210_mbdrc_band_params_get,
- tegra210_mbdrc_band_params_put,
- tegra210_mbdrc_param_info),
- TEGRA_SOC_BYTES_EXT("MBDRC Low Band Biquad Coeffs",
- TEGRA210_MBDRC_CFG_RAM_CTRL,
- TEGRA210_MBDRC_MAX_BIQUAD_STAGES * 5, 0, 0xffffffff,
- tegra210_mbdrc_biquad_coeffs_get,
- tegra210_mbdrc_biquad_coeffs_put,
- tegra210_mbdrc_param_info),
- TEGRA_SOC_BYTES_EXT("MBDRC Mid Band Biquad Coeffs",
- TEGRA210_MBDRC_CFG_RAM_CTRL +
- TEGRA210_MBDRC_FILTER_PARAM_STRIDE,
- TEGRA210_MBDRC_MAX_BIQUAD_STAGES * 5, 0, 0xffffffff,
- tegra210_mbdrc_biquad_coeffs_get,
- tegra210_mbdrc_biquad_coeffs_put,
- tegra210_mbdrc_param_info),
- TEGRA_SOC_BYTES_EXT("MBDRC High Band Biquad Coeffs",
- TEGRA210_MBDRC_CFG_RAM_CTRL +
- (TEGRA210_MBDRC_FILTER_PARAM_STRIDE * 2),
- TEGRA210_MBDRC_MAX_BIQUAD_STAGES * 5, 0, 0xffffffff,
- tegra210_mbdrc_biquad_coeffs_get,
- tegra210_mbdrc_biquad_coeffs_put,
- tegra210_mbdrc_param_info),
- };
- static bool tegra210_mbdrc_wr_reg(struct device *dev, unsigned int reg)
- {
- if (reg >= TEGRA210_MBDRC_IIR_CFG)
- reg -= ((reg - TEGRA210_MBDRC_IIR_CFG) %
- (TEGRA210_MBDRC_FILTER_PARAM_STRIDE *
- TEGRA210_MBDRC_FILTER_COUNT));
- switch (reg) {
- case TEGRA210_MBDRC_SOFT_RESET:
- case TEGRA210_MBDRC_CG:
- case TEGRA210_MBDRC_CFG ... TEGRA210_MBDRC_CFG_RAM_DATA:
- return true;
- default:
- return false;
- }
- }
- static bool tegra210_mbdrc_rd_reg(struct device *dev, unsigned int reg)
- {
- if (tegra210_mbdrc_wr_reg(dev, reg))
- return true;
- if (reg >= TEGRA210_MBDRC_IIR_CFG)
- reg -= ((reg - TEGRA210_MBDRC_IIR_CFG) %
- (TEGRA210_MBDRC_FILTER_PARAM_STRIDE *
- TEGRA210_MBDRC_FILTER_COUNT));
- switch (reg) {
- case TEGRA210_MBDRC_STATUS:
- return true;
- default:
- return false;
- }
- }
- static bool tegra210_mbdrc_volatile_reg(struct device *dev, unsigned int reg)
- {
- if (reg >= TEGRA210_MBDRC_IIR_CFG)
- reg -= ((reg - TEGRA210_MBDRC_IIR_CFG) %
- (TEGRA210_MBDRC_FILTER_PARAM_STRIDE *
- TEGRA210_MBDRC_FILTER_COUNT));
- switch (reg) {
- case TEGRA210_MBDRC_SOFT_RESET:
- case TEGRA210_MBDRC_STATUS:
- case TEGRA210_MBDRC_CFG_RAM_CTRL:
- case TEGRA210_MBDRC_CFG_RAM_DATA:
- return true;
- default:
- return false;
- }
- }
- static bool tegra210_mbdrc_precious_reg(struct device *dev, unsigned int reg)
- {
- if (reg >= TEGRA210_MBDRC_IIR_CFG)
- reg -= ((reg - TEGRA210_MBDRC_IIR_CFG) %
- (TEGRA210_MBDRC_FILTER_PARAM_STRIDE *
- TEGRA210_MBDRC_FILTER_COUNT));
- switch (reg) {
- case TEGRA210_MBDRC_CFG_RAM_DATA:
- return true;
- default:
- return false;
- }
- }
- static const struct regmap_config tegra210_mbdrc_regmap_cfg = {
- .name = "mbdrc",
- .reg_bits = 32,
- .reg_stride = 4,
- .val_bits = 32,
- .max_register = TEGRA210_MBDRC_MAX_REG,
- .writeable_reg = tegra210_mbdrc_wr_reg,
- .readable_reg = tegra210_mbdrc_rd_reg,
- .volatile_reg = tegra210_mbdrc_volatile_reg,
- .precious_reg = tegra210_mbdrc_precious_reg,
- .reg_defaults = tegra210_mbdrc_reg_defaults,
- .num_reg_defaults = ARRAY_SIZE(tegra210_mbdrc_reg_defaults),
- .cache_type = REGCACHE_FLAT,
- };
- int tegra210_mbdrc_hw_params(struct snd_soc_component *cmpnt)
- {
- struct tegra210_ope *ope = snd_soc_component_get_drvdata(cmpnt);
- const struct tegra210_mbdrc_config *conf = &mbdrc_init_config;
- u32 val = 0;
- unsigned int i;
- regmap_read(ope->mbdrc_regmap, TEGRA210_MBDRC_CFG, &val);
- val &= TEGRA210_MBDRC_CFG_MBDRC_MODE_MASK;
- if (val == TEGRA210_MBDRC_CFG_MBDRC_MODE_BYPASS)
- return 0;
- for (i = 0; i < MBDRC_NUM_BAND; i++) {
- const struct tegra210_mbdrc_band_params *params =
- &conf->band_params[i];
- u32 reg_off = i * TEGRA210_MBDRC_FILTER_PARAM_STRIDE;
- tegra210_mbdrc_write_ram(ope->mbdrc_regmap,
- reg_off + TEGRA210_MBDRC_CFG_RAM_CTRL,
- reg_off + TEGRA210_MBDRC_CFG_RAM_DATA,
- 0, (u32 *)¶ms->biquad_params[0],
- TEGRA210_MBDRC_MAX_BIQUAD_STAGES * 5);
- }
- return 0;
- }
- int tegra210_mbdrc_component_init(struct snd_soc_component *cmpnt)
- {
- struct tegra210_ope *ope = snd_soc_component_get_drvdata(cmpnt);
- const struct tegra210_mbdrc_config *conf = &mbdrc_init_config;
- unsigned int i;
- u32 val;
- pm_runtime_get_sync(cmpnt->dev);
- /* Initialize MBDRC registers and AHUB RAM with default params */
- regmap_update_bits(ope->mbdrc_regmap, TEGRA210_MBDRC_CFG,
- TEGRA210_MBDRC_CFG_MBDRC_MODE_MASK,
- conf->mode << TEGRA210_MBDRC_CFG_MBDRC_MODE_SHIFT);
- regmap_update_bits(ope->mbdrc_regmap, TEGRA210_MBDRC_CFG,
- TEGRA210_MBDRC_CFG_RMS_OFFSET_MASK,
- conf->rms_off << TEGRA210_MBDRC_CFG_RMS_OFFSET_SHIFT);
- regmap_update_bits(ope->mbdrc_regmap, TEGRA210_MBDRC_CFG,
- TEGRA210_MBDRC_CFG_PEAK_RMS_MASK,
- conf->peak_rms_mode << TEGRA210_MBDRC_CFG_PEAK_RMS_SHIFT);
- regmap_update_bits(ope->mbdrc_regmap, TEGRA210_MBDRC_CFG,
- TEGRA210_MBDRC_CFG_FILTER_STRUCTURE_MASK,
- conf->fliter_structure <<
- TEGRA210_MBDRC_CFG_FILTER_STRUCTURE_SHIFT);
- regmap_update_bits(ope->mbdrc_regmap, TEGRA210_MBDRC_CFG,
- TEGRA210_MBDRC_CFG_SHIFT_CTRL_MASK,
- conf->shift_ctrl << TEGRA210_MBDRC_CFG_SHIFT_CTRL_SHIFT);
- regmap_update_bits(ope->mbdrc_regmap, TEGRA210_MBDRC_CFG,
- TEGRA210_MBDRC_CFG_FRAME_SIZE_MASK,
- __ffs(conf->frame_size) <<
- TEGRA210_MBDRC_CFG_FRAME_SIZE_SHIFT);
- regmap_update_bits(ope->mbdrc_regmap, TEGRA210_MBDRC_CHANNEL_MASK,
- TEGRA210_MBDRC_CHANNEL_MASK_MASK,
- conf->channel_mask << TEGRA210_MBDRC_CHANNEL_MASK_SHIFT);
- regmap_update_bits(ope->mbdrc_regmap, TEGRA210_MBDRC_FAST_FACTOR,
- TEGRA210_MBDRC_FAST_FACTOR_ATTACK_MASK,
- conf->fa_factor << TEGRA210_MBDRC_FAST_FACTOR_ATTACK_SHIFT);
- regmap_update_bits(ope->mbdrc_regmap, TEGRA210_MBDRC_FAST_FACTOR,
- TEGRA210_MBDRC_FAST_FACTOR_ATTACK_MASK,
- conf->fr_factor << TEGRA210_MBDRC_FAST_FACTOR_ATTACK_SHIFT);
- for (i = 0; i < MBDRC_NUM_BAND; i++) {
- const struct tegra210_mbdrc_band_params *params =
- &conf->band_params[i];
- u32 reg_off = i * TEGRA210_MBDRC_FILTER_PARAM_STRIDE;
- regmap_update_bits(ope->mbdrc_regmap,
- reg_off + TEGRA210_MBDRC_IIR_CFG,
- TEGRA210_MBDRC_IIR_CFG_NUM_STAGES_MASK,
- params->iir_stages <<
- TEGRA210_MBDRC_IIR_CFG_NUM_STAGES_SHIFT);
- regmap_update_bits(ope->mbdrc_regmap,
- reg_off + TEGRA210_MBDRC_IN_ATTACK,
- TEGRA210_MBDRC_IN_ATTACK_TC_MASK,
- params->in_attack_tc <<
- TEGRA210_MBDRC_IN_ATTACK_TC_SHIFT);
- regmap_update_bits(ope->mbdrc_regmap,
- reg_off + TEGRA210_MBDRC_IN_RELEASE,
- TEGRA210_MBDRC_IN_RELEASE_TC_MASK,
- params->in_release_tc <<
- TEGRA210_MBDRC_IN_RELEASE_TC_SHIFT);
- regmap_update_bits(ope->mbdrc_regmap,
- reg_off + TEGRA210_MBDRC_FAST_ATTACK,
- TEGRA210_MBDRC_FAST_ATTACK_TC_MASK,
- params->fast_attack_tc <<
- TEGRA210_MBDRC_FAST_ATTACK_TC_SHIFT);
- val = (((params->in_threshold[0] >>
- TEGRA210_MBDRC_THRESH_1ST_SHIFT) &
- TEGRA210_MBDRC_THRESH_1ST_MASK) |
- ((params->in_threshold[1] >>
- TEGRA210_MBDRC_THRESH_2ND_SHIFT) &
- TEGRA210_MBDRC_THRESH_2ND_MASK) |
- ((params->in_threshold[2] >>
- TEGRA210_MBDRC_THRESH_3RD_SHIFT) &
- TEGRA210_MBDRC_THRESH_3RD_MASK) |
- ((params->in_threshold[3] >>
- TEGRA210_MBDRC_THRESH_4TH_SHIFT) &
- TEGRA210_MBDRC_THRESH_4TH_MASK));
- regmap_update_bits(ope->mbdrc_regmap,
- reg_off + TEGRA210_MBDRC_IN_THRESHOLD,
- 0xffffffff, val);
- val = (((params->out_threshold[0] >>
- TEGRA210_MBDRC_THRESH_1ST_SHIFT) &
- TEGRA210_MBDRC_THRESH_1ST_MASK) |
- ((params->out_threshold[1] >>
- TEGRA210_MBDRC_THRESH_2ND_SHIFT) &
- TEGRA210_MBDRC_THRESH_2ND_MASK) |
- ((params->out_threshold[2] >>
- TEGRA210_MBDRC_THRESH_3RD_SHIFT) &
- TEGRA210_MBDRC_THRESH_3RD_MASK) |
- ((params->out_threshold[3] >>
- TEGRA210_MBDRC_THRESH_4TH_SHIFT) &
- TEGRA210_MBDRC_THRESH_4TH_MASK));
- regmap_update_bits(ope->mbdrc_regmap,
- reg_off + TEGRA210_MBDRC_OUT_THRESHOLD,
- 0xffffffff, val);
- regmap_update_bits(ope->mbdrc_regmap,
- reg_off + TEGRA210_MBDRC_RATIO_1ST,
- TEGRA210_MBDRC_RATIO_1ST_MASK,
- params->ratio[0] << TEGRA210_MBDRC_RATIO_1ST_SHIFT);
- regmap_update_bits(ope->mbdrc_regmap,
- reg_off + TEGRA210_MBDRC_RATIO_2ND,
- TEGRA210_MBDRC_RATIO_2ND_MASK,
- params->ratio[1] << TEGRA210_MBDRC_RATIO_2ND_SHIFT);
- regmap_update_bits(ope->mbdrc_regmap,
- reg_off + TEGRA210_MBDRC_RATIO_3RD,
- TEGRA210_MBDRC_RATIO_3RD_MASK,
- params->ratio[2] << TEGRA210_MBDRC_RATIO_3RD_SHIFT);
- regmap_update_bits(ope->mbdrc_regmap,
- reg_off + TEGRA210_MBDRC_RATIO_4TH,
- TEGRA210_MBDRC_RATIO_4TH_MASK,
- params->ratio[3] << TEGRA210_MBDRC_RATIO_4TH_SHIFT);
- regmap_update_bits(ope->mbdrc_regmap,
- reg_off + TEGRA210_MBDRC_RATIO_5TH,
- TEGRA210_MBDRC_RATIO_5TH_MASK,
- params->ratio[4] << TEGRA210_MBDRC_RATIO_5TH_SHIFT);
- regmap_update_bits(ope->mbdrc_regmap,
- reg_off + TEGRA210_MBDRC_MAKEUP_GAIN,
- TEGRA210_MBDRC_MAKEUP_GAIN_MASK,
- params->makeup_gain <<
- TEGRA210_MBDRC_MAKEUP_GAIN_SHIFT);
- regmap_update_bits(ope->mbdrc_regmap,
- reg_off + TEGRA210_MBDRC_INIT_GAIN,
- TEGRA210_MBDRC_INIT_GAIN_MASK,
- params->gain_init <<
- TEGRA210_MBDRC_INIT_GAIN_SHIFT);
- regmap_update_bits(ope->mbdrc_regmap,
- reg_off + TEGRA210_MBDRC_GAIN_ATTACK,
- TEGRA210_MBDRC_GAIN_ATTACK_MASK,
- params->gain_attack_tc <<
- TEGRA210_MBDRC_GAIN_ATTACK_SHIFT);
- regmap_update_bits(ope->mbdrc_regmap,
- reg_off + TEGRA210_MBDRC_GAIN_RELEASE,
- TEGRA210_MBDRC_GAIN_RELEASE_MASK,
- params->gain_release_tc <<
- TEGRA210_MBDRC_GAIN_RELEASE_SHIFT);
- regmap_update_bits(ope->mbdrc_regmap,
- reg_off + TEGRA210_MBDRC_FAST_RELEASE,
- TEGRA210_MBDRC_FAST_RELEASE_MASK,
- params->fast_release_tc <<
- TEGRA210_MBDRC_FAST_RELEASE_SHIFT);
- tegra210_mbdrc_write_ram(ope->mbdrc_regmap,
- reg_off + TEGRA210_MBDRC_CFG_RAM_CTRL,
- reg_off + TEGRA210_MBDRC_CFG_RAM_DATA, 0,
- (u32 *)¶ms->biquad_params[0],
- TEGRA210_MBDRC_MAX_BIQUAD_STAGES * 5);
- }
- pm_runtime_put_sync(cmpnt->dev);
- snd_soc_add_component_controls(cmpnt, tegra210_mbdrc_controls,
- ARRAY_SIZE(tegra210_mbdrc_controls));
- return 0;
- }
- int tegra210_mbdrc_regmap_init(struct platform_device *pdev)
- {
- struct device *dev = &pdev->dev;
- struct tegra210_ope *ope = dev_get_drvdata(dev);
- struct device_node *child;
- struct resource mem;
- void __iomem *regs;
- int err;
- child = of_get_child_by_name(dev->of_node, "dynamic-range-compressor");
- if (!child)
- return -ENODEV;
- err = of_address_to_resource(child, 0, &mem);
- of_node_put(child);
- if (err < 0) {
- dev_err(dev, "fail to get MBDRC resource\n");
- return err;
- }
- mem.flags = IORESOURCE_MEM;
- regs = devm_ioremap_resource(dev, &mem);
- if (IS_ERR(regs))
- return PTR_ERR(regs);
- ope->mbdrc_regmap = devm_regmap_init_mmio(dev, regs,
- &tegra210_mbdrc_regmap_cfg);
- if (IS_ERR(ope->mbdrc_regmap)) {
- dev_err(dev, "regmap init failed\n");
- return PTR_ERR(ope->mbdrc_regmap);
- }
- regcache_cache_only(ope->mbdrc_regmap, true);
- return 0;
- }
|