1 // SPDX-License-Identifier: GPL-2.0-only 2 // 3 // tegra210_peq.c - Tegra210 PEQ driver 4 // 5 // Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. 6 7 #include <linux/clk.h> 8 #include <linux/device.h> 9 #include <linux/io.h> 10 #include <linux/module.h> 11 #include <linux/of.h> 12 #include <linux/of_address.h> 13 #include <linux/platform_device.h> 14 #include <linux/pm_runtime.h> 15 #include <linux/regmap.h> 16 #include <sound/core.h> 17 #include <sound/pcm.h> 18 #include <sound/pcm_params.h> 19 #include <sound/soc.h> 20 21 #include "tegra210_ope.h" 22 #include "tegra210_peq.h" 23 24 static const struct reg_default tegra210_peq_reg_defaults[] = { 25 { TEGRA210_PEQ_CFG, 0x00000013}, 26 { TEGRA210_PEQ_CFG_RAM_CTRL, 0x00004000}, 27 { TEGRA210_PEQ_CFG_RAM_SHIFT_CTRL, 0x00004000}, 28 }; 29 30 static const u32 biquad_init_gains[TEGRA210_PEQ_GAIN_PARAM_SIZE_PER_CH] = { 31 1495012349, /* Pre-gain */ 32 33 /* Gains : b0, b1, a0, a1, a2 */ 34 536870912, -1073741824, 536870912, 2143508246, -1069773768, /* Band-0 */ 35 134217728, -265414508, 131766272, 2140402222, -1071252997, /* Band-1 */ 36 268435456, -233515765, -33935948, 1839817267, -773826124, /* Band-2 */ 37 536870912, -672537913, 139851540, 1886437554, -824433167, /* Band-3 */ 38 268435456, -114439279, 173723964, 205743566, 278809729, /* Band-4 */ 39 1, 0, 0, 0, 0, /* Band-5 */ 40 1, 0, 0, 0, 0, /* Band-6 */ 41 1, 0, 0, 0, 0, /* Band-7 */ 42 1, 0, 0, 0, 0, /* Band-8 */ 43 1, 0, 0, 0, 0, /* Band-9 */ 44 1, 0, 0, 0, 0, /* Band-10 */ 45 1, 0, 0, 0, 0, /* Band-11 */ 46 47 963423114, /* Post-gain */ 48 }; 49 50 static const u32 biquad_init_shifts[TEGRA210_PEQ_SHIFT_PARAM_SIZE_PER_CH] = { 51 23, /* Pre-shift */ 52 30, 30, 30, 30, 30, 0, 0, 0, 0, 0, 0, 0, /* Shift for bands */ 53 28, /* Post-shift */ 54 }; 55 56 static s32 biquad_coeff_buffer[TEGRA210_PEQ_GAIN_PARAM_SIZE_PER_CH]; 57 58 static void tegra210_peq_read_ram(struct regmap *regmap, unsigned int reg_ctrl, 59 unsigned int reg_data, unsigned int ram_offset, 60 unsigned int *data, size_t size) 61 { 62 unsigned int val; 63 unsigned int i; 64 65 val = ram_offset & TEGRA210_PEQ_RAM_CTRL_RAM_ADDR_MASK; 66 val |= TEGRA210_PEQ_RAM_CTRL_ADDR_INIT_EN; 67 val |= TEGRA210_PEQ_RAM_CTRL_SEQ_ACCESS_EN; 68 val |= TEGRA210_PEQ_RAM_CTRL_RW_READ; 69 70 regmap_write(regmap, reg_ctrl, val); 71 72 /* 73 * Since all ahub non-io modules work under same ahub clock it is not 74 * necessary to check ahub read busy bit after every read. 75 */ 76 for (i = 0; i < size; i++) 77 regmap_read(regmap, reg_data, &data[i]); 78 } 79 80 static void tegra210_peq_write_ram(struct regmap *regmap, unsigned int reg_ctrl, 81 unsigned int reg_data, unsigned int ram_offset, 82 unsigned int *data, size_t size) 83 { 84 unsigned int val; 85 unsigned int i; 86 87 val = ram_offset & TEGRA210_PEQ_RAM_CTRL_RAM_ADDR_MASK; 88 val |= TEGRA210_PEQ_RAM_CTRL_ADDR_INIT_EN; 89 val |= TEGRA210_PEQ_RAM_CTRL_SEQ_ACCESS_EN; 90 val |= TEGRA210_PEQ_RAM_CTRL_RW_WRITE; 91 92 regmap_write(regmap, reg_ctrl, val); 93 94 for (i = 0; i < size; i++) 95 regmap_write(regmap, reg_data, data[i]); 96 } 97 98 static int tegra210_peq_get(struct snd_kcontrol *kcontrol, 99 struct snd_ctl_elem_value *ucontrol) 100 { 101 struct soc_mixer_control *mc = 102 (struct soc_mixer_control *)kcontrol->private_value; 103 struct snd_soc_component *cmpnt = snd_kcontrol_chip(kcontrol); 104 struct tegra210_ope *ope = snd_soc_component_get_drvdata(cmpnt); 105 unsigned int mask = (1 << fls(mc->max)) - 1; 106 unsigned int val; 107 108 regmap_read(ope->peq_regmap, mc->reg, &val); 109 110 ucontrol->value.integer.value[0] = (val >> mc->shift) & mask; 111 112 if (!mc->invert) 113 return 0; 114 115 ucontrol->value.integer.value[0] = 116 mc->max - ucontrol->value.integer.value[0]; 117 118 return 0; 119 } 120 121 static int tegra210_peq_put(struct snd_kcontrol *kcontrol, 122 struct snd_ctl_elem_value *ucontrol) 123 { 124 struct soc_mixer_control *mc = 125 (struct soc_mixer_control *)kcontrol->private_value; 126 struct snd_soc_component *cmpnt = snd_kcontrol_chip(kcontrol); 127 struct tegra210_ope *ope = snd_soc_component_get_drvdata(cmpnt); 128 unsigned int mask = (1 << fls(mc->max)) - 1; 129 bool change = false; 130 unsigned int val; 131 132 val = (ucontrol->value.integer.value[0] & mask); 133 134 if (mc->invert) 135 val = mc->max - val; 136 137 val = val << mc->shift; 138 139 regmap_update_bits_check(ope->peq_regmap, mc->reg, (mask << mc->shift), 140 val, &change); 141 142 return change ? 1 : 0; 143 } 144 145 static int tegra210_peq_ram_get(struct snd_kcontrol *kcontrol, 146 struct snd_ctl_elem_value *ucontrol) 147 { 148 struct tegra_soc_bytes *params = (void *)kcontrol->private_value; 149 struct snd_soc_component *cmpnt = snd_kcontrol_chip(kcontrol); 150 struct tegra210_ope *ope = snd_soc_component_get_drvdata(cmpnt); 151 int val_bytes = snd_soc_component_regmap_val_bytes(cmpnt); 152 u32 i, reg_ctrl = params->soc.base; 153 u32 reg_data = reg_ctrl + val_bytes; 154 s32 *data = (s32 *)biquad_coeff_buffer; 155 156 pm_runtime_get_sync(cmpnt->dev); 157 158 tegra210_peq_read_ram(ope->peq_regmap, reg_ctrl, reg_data, 159 params->shift, data, params->soc.num_regs); 160 161 pm_runtime_put_sync(cmpnt->dev); 162 163 for (i = 0; i < params->soc.num_regs; i++) 164 ucontrol->value.integer.value[i] = (long)data[i]; 165 166 return 0; 167 } 168 169 static int tegra210_peq_ram_put(struct snd_kcontrol *kcontrol, 170 struct snd_ctl_elem_value *ucontrol) 171 { 172 struct tegra_soc_bytes *params = (void *)kcontrol->private_value; 173 struct snd_soc_component *cmpnt = snd_kcontrol_chip(kcontrol); 174 struct tegra210_ope *ope = snd_soc_component_get_drvdata(cmpnt); 175 int val_bytes = snd_soc_component_regmap_val_bytes(cmpnt); 176 u32 i, reg_ctrl = params->soc.base; 177 u32 reg_data = reg_ctrl + val_bytes; 178 s32 *data = (s32 *)biquad_coeff_buffer; 179 180 for (i = 0; i < params->soc.num_regs; i++) 181 data[i] = (s32)ucontrol->value.integer.value[i]; 182 183 pm_runtime_get_sync(cmpnt->dev); 184 185 tegra210_peq_write_ram(ope->peq_regmap, reg_ctrl, reg_data, 186 params->shift, data, params->soc.num_regs); 187 188 pm_runtime_put_sync(cmpnt->dev); 189 190 return 1; 191 } 192 193 static int tegra210_peq_param_info(struct snd_kcontrol *kcontrol, 194 struct snd_ctl_elem_info *uinfo) 195 { 196 struct soc_bytes *params = (void *)kcontrol->private_value; 197 198 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 199 uinfo->value.integer.min = INT_MIN; 200 uinfo->value.integer.max = INT_MAX; 201 uinfo->count = params->num_regs; 202 203 return 0; 204 } 205 206 #define TEGRA210_PEQ_GAIN_PARAMS_CTRL(chan) \ 207 TEGRA_SOC_BYTES_EXT("PEQ Channel-" #chan " Biquad Gain Params", \ 208 TEGRA210_PEQ_CFG_RAM_CTRL, \ 209 TEGRA210_PEQ_GAIN_PARAM_SIZE_PER_CH, \ 210 (TEGRA210_PEQ_GAIN_PARAM_SIZE_PER_CH * chan), 0xffffffff, \ 211 tegra210_peq_ram_get, tegra210_peq_ram_put, \ 212 tegra210_peq_param_info) 213 214 #define TEGRA210_PEQ_SHIFT_PARAMS_CTRL(chan) \ 215 TEGRA_SOC_BYTES_EXT("PEQ Channel-" #chan " Biquad Shift Params", \ 216 TEGRA210_PEQ_CFG_RAM_SHIFT_CTRL, \ 217 TEGRA210_PEQ_SHIFT_PARAM_SIZE_PER_CH, \ 218 (TEGRA210_PEQ_SHIFT_PARAM_SIZE_PER_CH * chan), 0x1f, \ 219 tegra210_peq_ram_get, tegra210_peq_ram_put, \ 220 tegra210_peq_param_info) 221 222 static const struct snd_kcontrol_new tegra210_peq_controls[] = { 223 SOC_SINGLE_EXT("PEQ Active", TEGRA210_PEQ_CFG, 224 TEGRA210_PEQ_CFG_MODE_SHIFT, 1, 0, 225 tegra210_peq_get, tegra210_peq_put), 226 227 SOC_SINGLE_EXT("PEQ Biquad Stages", TEGRA210_PEQ_CFG, 228 TEGRA210_PEQ_CFG_BIQUAD_STAGES_SHIFT, 229 TEGRA210_PEQ_MAX_BIQUAD_STAGES - 1, 0, 230 tegra210_peq_get, tegra210_peq_put), 231 232 TEGRA210_PEQ_GAIN_PARAMS_CTRL(0), 233 TEGRA210_PEQ_GAIN_PARAMS_CTRL(1), 234 TEGRA210_PEQ_GAIN_PARAMS_CTRL(2), 235 TEGRA210_PEQ_GAIN_PARAMS_CTRL(3), 236 TEGRA210_PEQ_GAIN_PARAMS_CTRL(4), 237 TEGRA210_PEQ_GAIN_PARAMS_CTRL(5), 238 TEGRA210_PEQ_GAIN_PARAMS_CTRL(6), 239 TEGRA210_PEQ_GAIN_PARAMS_CTRL(7), 240 241 TEGRA210_PEQ_SHIFT_PARAMS_CTRL(0), 242 TEGRA210_PEQ_SHIFT_PARAMS_CTRL(1), 243 TEGRA210_PEQ_SHIFT_PARAMS_CTRL(2), 244 TEGRA210_PEQ_SHIFT_PARAMS_CTRL(3), 245 TEGRA210_PEQ_SHIFT_PARAMS_CTRL(4), 246 TEGRA210_PEQ_SHIFT_PARAMS_CTRL(5), 247 TEGRA210_PEQ_SHIFT_PARAMS_CTRL(6), 248 TEGRA210_PEQ_SHIFT_PARAMS_CTRL(7), 249 }; 250 251 static bool tegra210_peq_wr_reg(struct device *dev, unsigned int reg) 252 { 253 switch (reg) { 254 case TEGRA210_PEQ_SOFT_RESET: 255 case TEGRA210_PEQ_CG: 256 case TEGRA210_PEQ_CFG ... TEGRA210_PEQ_CFG_RAM_SHIFT_DATA: 257 return true; 258 default: 259 return false; 260 } 261 } 262 263 static bool tegra210_peq_rd_reg(struct device *dev, unsigned int reg) 264 { 265 if (tegra210_peq_wr_reg(dev, reg)) 266 return true; 267 268 switch (reg) { 269 case TEGRA210_PEQ_STATUS: 270 return true; 271 default: 272 return false; 273 } 274 } 275 276 static bool tegra210_peq_volatile_reg(struct device *dev, unsigned int reg) 277 { 278 switch (reg) { 279 case TEGRA210_PEQ_SOFT_RESET: 280 case TEGRA210_PEQ_STATUS: 281 case TEGRA210_PEQ_CFG_RAM_CTRL ... TEGRA210_PEQ_CFG_RAM_SHIFT_DATA: 282 return true; 283 default: 284 return false; 285 } 286 } 287 288 static bool tegra210_peq_precious_reg(struct device *dev, unsigned int reg) 289 { 290 switch (reg) { 291 case TEGRA210_PEQ_CFG_RAM_DATA: 292 case TEGRA210_PEQ_CFG_RAM_SHIFT_DATA: 293 return true; 294 default: 295 return false; 296 } 297 } 298 299 static const struct regmap_config tegra210_peq_regmap_config = { 300 .name = "peq", 301 .reg_bits = 32, 302 .reg_stride = 4, 303 .val_bits = 32, 304 .max_register = TEGRA210_PEQ_CFG_RAM_SHIFT_DATA, 305 .writeable_reg = tegra210_peq_wr_reg, 306 .readable_reg = tegra210_peq_rd_reg, 307 .volatile_reg = tegra210_peq_volatile_reg, 308 .precious_reg = tegra210_peq_precious_reg, 309 .reg_defaults = tegra210_peq_reg_defaults, 310 .num_reg_defaults = ARRAY_SIZE(tegra210_peq_reg_defaults), 311 .reg_default_cb = regmap_default_zero_cb, 312 .cache_type = REGCACHE_FLAT, 313 }; 314 315 void tegra210_peq_restore(struct regmap *regmap, u32 *biquad_gains, 316 u32 *biquad_shifts) 317 { 318 unsigned int i; 319 320 for (i = 0; i < TEGRA210_PEQ_MAX_CHANNELS; i++) { 321 tegra210_peq_write_ram(regmap, TEGRA210_PEQ_CFG_RAM_CTRL, 322 TEGRA210_PEQ_CFG_RAM_DATA, 323 (i * TEGRA210_PEQ_GAIN_PARAM_SIZE_PER_CH), 324 biquad_gains, 325 TEGRA210_PEQ_GAIN_PARAM_SIZE_PER_CH); 326 327 tegra210_peq_write_ram(regmap, 328 TEGRA210_PEQ_CFG_RAM_SHIFT_CTRL, 329 TEGRA210_PEQ_CFG_RAM_SHIFT_DATA, 330 (i * TEGRA210_PEQ_SHIFT_PARAM_SIZE_PER_CH), 331 biquad_shifts, 332 TEGRA210_PEQ_SHIFT_PARAM_SIZE_PER_CH); 333 334 } 335 } 336 337 void tegra210_peq_save(struct regmap *regmap, u32 *biquad_gains, 338 u32 *biquad_shifts) 339 { 340 unsigned int i; 341 342 for (i = 0; i < TEGRA210_PEQ_MAX_CHANNELS; i++) { 343 tegra210_peq_read_ram(regmap, 344 TEGRA210_PEQ_CFG_RAM_CTRL, 345 TEGRA210_PEQ_CFG_RAM_DATA, 346 (i * TEGRA210_PEQ_GAIN_PARAM_SIZE_PER_CH), 347 biquad_gains, 348 TEGRA210_PEQ_GAIN_PARAM_SIZE_PER_CH); 349 350 tegra210_peq_read_ram(regmap, 351 TEGRA210_PEQ_CFG_RAM_SHIFT_CTRL, 352 TEGRA210_PEQ_CFG_RAM_SHIFT_DATA, 353 (i * TEGRA210_PEQ_SHIFT_PARAM_SIZE_PER_CH), 354 biquad_shifts, 355 TEGRA210_PEQ_SHIFT_PARAM_SIZE_PER_CH); 356 } 357 } 358 359 int tegra210_peq_component_init(struct snd_soc_component *cmpnt) 360 { 361 struct tegra210_ope *ope = snd_soc_component_get_drvdata(cmpnt); 362 unsigned int i; 363 364 pm_runtime_get_sync(cmpnt->dev); 365 regmap_update_bits(ope->peq_regmap, TEGRA210_PEQ_CFG, 366 TEGRA210_PEQ_CFG_MODE_MASK, 367 0 << TEGRA210_PEQ_CFG_MODE_SHIFT); 368 regmap_update_bits(ope->peq_regmap, TEGRA210_PEQ_CFG, 369 TEGRA210_PEQ_CFG_BIQUAD_STAGES_MASK, 370 (TEGRA210_PEQ_BIQUAD_INIT_STAGE - 1) << 371 TEGRA210_PEQ_CFG_BIQUAD_STAGES_SHIFT); 372 373 /* Initialize PEQ AHUB RAM with default params */ 374 for (i = 0; i < TEGRA210_PEQ_MAX_CHANNELS; i++) { 375 376 /* Set default gain params */ 377 tegra210_peq_write_ram(ope->peq_regmap, 378 TEGRA210_PEQ_CFG_RAM_CTRL, 379 TEGRA210_PEQ_CFG_RAM_DATA, 380 (i * TEGRA210_PEQ_GAIN_PARAM_SIZE_PER_CH), 381 (u32 *)&biquad_init_gains, 382 TEGRA210_PEQ_GAIN_PARAM_SIZE_PER_CH); 383 384 /* Set default shift params */ 385 tegra210_peq_write_ram(ope->peq_regmap, 386 TEGRA210_PEQ_CFG_RAM_SHIFT_CTRL, 387 TEGRA210_PEQ_CFG_RAM_SHIFT_DATA, 388 (i * TEGRA210_PEQ_SHIFT_PARAM_SIZE_PER_CH), 389 (u32 *)&biquad_init_shifts, 390 TEGRA210_PEQ_SHIFT_PARAM_SIZE_PER_CH); 391 392 } 393 394 pm_runtime_put_sync(cmpnt->dev); 395 396 snd_soc_add_component_controls(cmpnt, tegra210_peq_controls, 397 ARRAY_SIZE(tegra210_peq_controls)); 398 399 return 0; 400 } 401 402 int tegra210_peq_regmap_init(struct platform_device *pdev) 403 { 404 struct device *dev = &pdev->dev; 405 struct tegra210_ope *ope = dev_get_drvdata(dev); 406 struct device_node *child; 407 struct resource mem; 408 void __iomem *regs; 409 int err; 410 411 child = of_get_child_by_name(dev->of_node, "equalizer"); 412 if (!child) 413 return dev_err_probe(dev, -ENODEV, 414 "missing 'equalizer' DT child node\n"); 415 416 err = of_address_to_resource(child, 0, &mem); 417 of_node_put(child); 418 if (err < 0) 419 return dev_err_probe(dev, err, 420 "failed to get PEQ resource\n"); 421 422 mem.flags = IORESOURCE_MEM; 423 regs = devm_ioremap_resource(dev, &mem); 424 if (IS_ERR(regs)) 425 return PTR_ERR(regs); 426 ope->peq_regmap = devm_regmap_init_mmio(dev, regs, 427 &tegra210_peq_regmap_config); 428 if (IS_ERR(ope->peq_regmap)) 429 return dev_err_probe(dev, PTR_ERR(ope->peq_regmap), 430 "PEQ regmap init failed\n"); 431 432 regcache_cache_only(ope->peq_regmap, true); 433 434 return 0; 435 } 436