1 // SPDX-License-Identifier: GPL-2.0-only 2 // 3 // tegra210_mbdrc.c - Tegra210 MBDRC driver 4 // 5 // Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. 6 7 #include <linux/device.h> 8 #include <linux/io.h> 9 #include <linux/module.h> 10 #include <linux/of_address.h> 11 #include <linux/pm_runtime.h> 12 #include <linux/regmap.h> 13 #include <sound/core.h> 14 #include <sound/soc.h> 15 #include <sound/tlv.h> 16 17 #include "tegra210_mbdrc.h" 18 #include "tegra210_ope.h" 19 20 #define MBDRC_FILTER_REG(reg, id) \ 21 ((reg) + ((id) * TEGRA210_MBDRC_FILTER_PARAM_STRIDE)) 22 23 #define MBDRC_FILTER_REG_DEFAULTS(id) \ 24 { MBDRC_FILTER_REG(TEGRA210_MBDRC_IIR_CFG, id), 0x00000005}, \ 25 { MBDRC_FILTER_REG(TEGRA210_MBDRC_IN_ATTACK, id), 0x3e48590c}, \ 26 { MBDRC_FILTER_REG(TEGRA210_MBDRC_IN_RELEASE, id), 0x08414e9f}, \ 27 { MBDRC_FILTER_REG(TEGRA210_MBDRC_FAST_ATTACK, id), 0x7fffffff}, \ 28 { MBDRC_FILTER_REG(TEGRA210_MBDRC_IN_THRESHOLD, id), 0x06145082}, \ 29 { MBDRC_FILTER_REG(TEGRA210_MBDRC_OUT_THRESHOLD, id), 0x060d379b}, \ 30 { MBDRC_FILTER_REG(TEGRA210_MBDRC_RATIO_1ST, id), 0x0000a000}, \ 31 { MBDRC_FILTER_REG(TEGRA210_MBDRC_RATIO_2ND, id), 0x00002000}, \ 32 { MBDRC_FILTER_REG(TEGRA210_MBDRC_RATIO_3RD, id), 0x00000b33}, \ 33 { MBDRC_FILTER_REG(TEGRA210_MBDRC_RATIO_4TH, id), 0x00000800}, \ 34 { MBDRC_FILTER_REG(TEGRA210_MBDRC_RATIO_5TH, id), 0x0000019a}, \ 35 { MBDRC_FILTER_REG(TEGRA210_MBDRC_MAKEUP_GAIN, id), 0x00000002}, \ 36 { MBDRC_FILTER_REG(TEGRA210_MBDRC_INIT_GAIN, id), 0x00066666}, \ 37 { MBDRC_FILTER_REG(TEGRA210_MBDRC_GAIN_ATTACK, id), 0x00d9ba0e}, \ 38 { MBDRC_FILTER_REG(TEGRA210_MBDRC_GAIN_RELEASE, id), 0x3e48590c}, \ 39 { MBDRC_FILTER_REG(TEGRA210_MBDRC_FAST_RELEASE, id), 0x7ffff26a}, \ 40 { MBDRC_FILTER_REG(TEGRA210_MBDRC_CFG_RAM_CTRL, id), 0x4000} 41 42 static 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 */ 53 static 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 215 static 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 233 static 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 249 static 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 267 static 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 282 static 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 304 static 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 325 static 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 350 static 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 378 static 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 411 static 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 423 static 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 439 static 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 450 static 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 467 static 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 488 static const char * const tegra210_mbdrc_mode_text[] = { 489 "Bypass", "Fullband", "Dualband", "Multiband" 490 }; 491 492 static 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 496 static const char * const tegra210_mbdrc_peak_rms_text[] = { 497 "Peak", "RMS" 498 }; 499 500 static 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 504 static const char * const tegra210_mbdrc_filter_structure_text[] = { 505 "All-pass-tree", "Flexible" 506 }; 507 508 static 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 513 static const char * const tegra210_mbdrc_frame_size_text[] = { 514 "N1", "N2", "N4", "N8", "N16", "N32", "N64" 515 }; 516 517 static 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 531 static const DECLARE_TLV_DB_MINMAX(mdbrc_vol_tlv, -25600, 25500); 532 533 static 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 686 static 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 703 static 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 721 static 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 739 static 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 754 static 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 769 int 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 *)¶ms->biquad_params[0], 793 TEGRA210_MBDRC_MAX_BIQUAD_STAGES * 5); 794 } 795 return 0; 796 } 797 798 int 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 *)¶ms->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 979 int 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
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.