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