1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * wm8958-dsp2.c -- WM8958 DSP2 support 4 * 5 * Copyright 2011 Wolfson Microelectronics plc 6 * 7 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> 8 */ 9 10 #include <linux/cleanup.h> 11 #include <linux/module.h> 12 #include <linux/moduleparam.h> 13 #include <linux/init.h> 14 #include <linux/delay.h> 15 #include <linux/pm.h> 16 #include <linux/i2c.h> 17 #include <linux/platform_device.h> 18 #include <linux/slab.h> 19 #include <sound/soc.h> 20 #include <sound/initval.h> 21 #include <sound/tlv.h> 22 #include <trace/events/asoc.h> 23 24 #include <linux/mfd/wm8994/core.h> 25 #include <linux/mfd/wm8994/registers.h> 26 #include <linux/mfd/wm8994/pdata.h> 27 #include <linux/mfd/wm8994/gpio.h> 28 29 #include <linux/unaligned.h> 30 31 #include "wm8994.h" 32 33 #define WM_FW_BLOCK_INFO 0xff 34 #define WM_FW_BLOCK_PM 0x00 35 #define WM_FW_BLOCK_X 0x01 36 #define WM_FW_BLOCK_Y 0x02 37 #define WM_FW_BLOCK_Z 0x03 38 #define WM_FW_BLOCK_I 0x06 39 #define WM_FW_BLOCK_A 0x08 40 #define WM_FW_BLOCK_C 0x0c 41 42 static int wm8958_dsp2_fw(struct snd_soc_component *component, const char *name, 43 const struct firmware *fw, bool check) 44 { 45 struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component); 46 u64 data64; 47 u32 data32; 48 const u8 *data; 49 char *str; 50 size_t block_len, len; 51 int ret = 0; 52 53 /* Suppress unneeded downloads */ 54 if (wm8994->cur_fw == fw) 55 return 0; 56 57 if (fw->size < 32) { 58 dev_err(component->dev, "%s: firmware too short (%zd bytes)\n", 59 name, fw->size); 60 goto err; 61 } 62 63 if (memcmp(fw->data, "WMFW", 4) != 0) { 64 data32 = get_unaligned_be32(fw->data); 65 dev_err(component->dev, "%s: firmware has bad file magic %08x\n", 66 name, data32); 67 goto err; 68 } 69 70 len = get_unaligned_be32(fw->data + 4); 71 data32 = get_unaligned_be32(fw->data + 8); 72 73 if ((data32 >> 24) & 0xff) { 74 dev_err(component->dev, "%s: unsupported firmware version %d\n", 75 name, (data32 >> 24) & 0xff); 76 goto err; 77 } 78 if ((data32 & 0xffff) != 8958) { 79 dev_err(component->dev, "%s: unsupported target device %d\n", 80 name, data32 & 0xffff); 81 goto err; 82 } 83 if (((data32 >> 16) & 0xff) != 0xc) { 84 dev_err(component->dev, "%s: unsupported target core %d\n", 85 name, (data32 >> 16) & 0xff); 86 goto err; 87 } 88 89 if (check) { 90 data64 = get_unaligned_be64(fw->data + 24); 91 dev_info(component->dev, "%s timestamp %llx\n", name, data64); 92 } else { 93 snd_soc_component_write(component, 0x102, 0x2); 94 snd_soc_component_write(component, 0x900, 0x2); 95 } 96 97 data = fw->data + len; 98 len = fw->size - len; 99 while (len) { 100 if (len < 12) { 101 dev_err(component->dev, "%s short data block of %zd\n", 102 name, len); 103 goto err; 104 } 105 106 block_len = get_unaligned_be32(data + 4); 107 if (block_len + 8 > len) { 108 dev_err(component->dev, "%zd byte block longer than file\n", 109 block_len); 110 goto err; 111 } 112 if (block_len == 0) { 113 dev_err(component->dev, "Zero length block\n"); 114 goto err; 115 } 116 117 data32 = get_unaligned_be32(data); 118 119 switch ((data32 >> 24) & 0xff) { 120 case WM_FW_BLOCK_INFO: 121 /* Informational text */ 122 if (!check) 123 break; 124 125 str = kzalloc(block_len + 1, GFP_KERNEL); 126 if (str) { 127 memcpy(str, data + 8, block_len); 128 dev_info(component->dev, "%s: %s\n", name, str); 129 kfree(str); 130 } else { 131 dev_err(component->dev, "Out of memory\n"); 132 } 133 break; 134 case WM_FW_BLOCK_PM: 135 case WM_FW_BLOCK_X: 136 case WM_FW_BLOCK_Y: 137 case WM_FW_BLOCK_Z: 138 case WM_FW_BLOCK_I: 139 case WM_FW_BLOCK_A: 140 case WM_FW_BLOCK_C: 141 dev_dbg(component->dev, "%s: %zd bytes of %x@%x\n", name, 142 block_len, (data32 >> 24) & 0xff, 143 data32 & 0xffffff); 144 145 if (check) 146 break; 147 148 data32 &= 0xffffff; 149 150 wm8994_bulk_write(wm8994->wm8994, 151 data32 & 0xffffff, 152 block_len / 2, 153 (void *)(data + 8)); 154 155 break; 156 default: 157 dev_warn(component->dev, "%s: unknown block type %d\n", 158 name, (data32 >> 24) & 0xff); 159 break; 160 } 161 162 /* Round up to the next 32 bit word */ 163 block_len += block_len % 4; 164 165 data += block_len + 8; 166 len -= block_len + 8; 167 } 168 169 if (!check) { 170 dev_dbg(component->dev, "%s: download done\n", name); 171 wm8994->cur_fw = fw; 172 } else { 173 dev_info(component->dev, "%s: got firmware\n", name); 174 } 175 176 goto ok; 177 178 err: 179 ret = -EINVAL; 180 ok: 181 if (!check) { 182 snd_soc_component_write(component, 0x900, 0x0); 183 snd_soc_component_write(component, 0x102, 0x0); 184 } 185 186 return ret; 187 } 188 189 static void wm8958_dsp_start_mbc(struct snd_soc_component *component, int path) 190 { 191 struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component); 192 struct wm8994 *control = wm8994->wm8994; 193 int i; 194 195 /* If the DSP is already running then noop */ 196 if (snd_soc_component_read(component, WM8958_DSP2_PROGRAM) & WM8958_DSP2_ENA) 197 return; 198 199 /* If we have MBC firmware download it */ 200 if (wm8994->mbc) 201 wm8958_dsp2_fw(component, "MBC", wm8994->mbc, false); 202 203 snd_soc_component_update_bits(component, WM8958_DSP2_PROGRAM, 204 WM8958_DSP2_ENA, WM8958_DSP2_ENA); 205 206 /* If we've got user supplied MBC settings use them */ 207 if (control->pdata.num_mbc_cfgs) { 208 struct wm8958_mbc_cfg *cfg 209 = &control->pdata.mbc_cfgs[wm8994->mbc_cfg]; 210 211 for (i = 0; i < ARRAY_SIZE(cfg->coeff_regs); i++) 212 snd_soc_component_write(component, i + WM8958_MBC_BAND_1_K_1, 213 cfg->coeff_regs[i]); 214 215 for (i = 0; i < ARRAY_SIZE(cfg->cutoff_regs); i++) 216 snd_soc_component_write(component, 217 i + WM8958_MBC_BAND_2_LOWER_CUTOFF_C1_1, 218 cfg->cutoff_regs[i]); 219 } 220 221 /* Run the DSP */ 222 snd_soc_component_write(component, WM8958_DSP2_EXECCONTROL, 223 WM8958_DSP2_RUNR); 224 225 /* And we're off! */ 226 snd_soc_component_update_bits(component, WM8958_DSP2_CONFIG, 227 WM8958_MBC_ENA | 228 WM8958_MBC_SEL_MASK, 229 path << WM8958_MBC_SEL_SHIFT | 230 WM8958_MBC_ENA); 231 } 232 233 static void wm8958_dsp_start_vss(struct snd_soc_component *component, int path) 234 { 235 struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component); 236 struct wm8994 *control = wm8994->wm8994; 237 int i, ena; 238 239 if (wm8994->mbc_vss) 240 wm8958_dsp2_fw(component, "MBC+VSS", wm8994->mbc_vss, false); 241 242 snd_soc_component_update_bits(component, WM8958_DSP2_PROGRAM, 243 WM8958_DSP2_ENA, WM8958_DSP2_ENA); 244 245 /* If we've got user supplied settings use them */ 246 if (control->pdata.num_mbc_cfgs) { 247 struct wm8958_mbc_cfg *cfg 248 = &control->pdata.mbc_cfgs[wm8994->mbc_cfg]; 249 250 for (i = 0; i < ARRAY_SIZE(cfg->combined_regs); i++) 251 snd_soc_component_write(component, i + 0x2800, 252 cfg->combined_regs[i]); 253 } 254 255 if (control->pdata.num_vss_cfgs) { 256 struct wm8958_vss_cfg *cfg 257 = &control->pdata.vss_cfgs[wm8994->vss_cfg]; 258 259 for (i = 0; i < ARRAY_SIZE(cfg->regs); i++) 260 snd_soc_component_write(component, i + 0x2600, cfg->regs[i]); 261 } 262 263 if (control->pdata.num_vss_hpf_cfgs) { 264 struct wm8958_vss_hpf_cfg *cfg 265 = &control->pdata.vss_hpf_cfgs[wm8994->vss_hpf_cfg]; 266 267 for (i = 0; i < ARRAY_SIZE(cfg->regs); i++) 268 snd_soc_component_write(component, i + 0x2400, cfg->regs[i]); 269 } 270 271 /* Run the DSP */ 272 snd_soc_component_write(component, WM8958_DSP2_EXECCONTROL, 273 WM8958_DSP2_RUNR); 274 275 /* Enable the algorithms we've selected */ 276 ena = 0; 277 if (wm8994->mbc_ena[path]) 278 ena |= 0x8; 279 if (wm8994->hpf2_ena[path]) 280 ena |= 0x4; 281 if (wm8994->hpf1_ena[path]) 282 ena |= 0x2; 283 if (wm8994->vss_ena[path]) 284 ena |= 0x1; 285 286 snd_soc_component_write(component, 0x2201, ena); 287 288 /* Switch the DSP into the data path */ 289 snd_soc_component_update_bits(component, WM8958_DSP2_CONFIG, 290 WM8958_MBC_SEL_MASK | WM8958_MBC_ENA, 291 path << WM8958_MBC_SEL_SHIFT | WM8958_MBC_ENA); 292 } 293 294 static void wm8958_dsp_start_enh_eq(struct snd_soc_component *component, int path) 295 { 296 struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component); 297 struct wm8994 *control = wm8994->wm8994; 298 int i; 299 300 wm8958_dsp2_fw(component, "ENH_EQ", wm8994->enh_eq, false); 301 302 snd_soc_component_update_bits(component, WM8958_DSP2_PROGRAM, 303 WM8958_DSP2_ENA, WM8958_DSP2_ENA); 304 305 /* If we've got user supplied settings use them */ 306 if (control->pdata.num_enh_eq_cfgs) { 307 struct wm8958_enh_eq_cfg *cfg 308 = &control->pdata.enh_eq_cfgs[wm8994->enh_eq_cfg]; 309 310 for (i = 0; i < ARRAY_SIZE(cfg->regs); i++) 311 snd_soc_component_write(component, i + 0x2200, 312 cfg->regs[i]); 313 } 314 315 /* Run the DSP */ 316 snd_soc_component_write(component, WM8958_DSP2_EXECCONTROL, 317 WM8958_DSP2_RUNR); 318 319 /* Switch the DSP into the data path */ 320 snd_soc_component_update_bits(component, WM8958_DSP2_CONFIG, 321 WM8958_MBC_SEL_MASK | WM8958_MBC_ENA, 322 path << WM8958_MBC_SEL_SHIFT | WM8958_MBC_ENA); 323 } 324 325 static void wm8958_dsp_apply(struct snd_soc_component *component, int path, int start) 326 { 327 struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component); 328 int pwr_reg = snd_soc_component_read(component, WM8994_POWER_MANAGEMENT_5); 329 int ena, reg, aif; 330 331 switch (path) { 332 case 0: 333 pwr_reg &= (WM8994_AIF1DAC1L_ENA | WM8994_AIF1DAC1R_ENA); 334 aif = 0; 335 break; 336 case 1: 337 pwr_reg &= (WM8994_AIF1DAC2L_ENA | WM8994_AIF1DAC2R_ENA); 338 aif = 0; 339 break; 340 case 2: 341 pwr_reg &= (WM8994_AIF2DACL_ENA | WM8994_AIF2DACR_ENA); 342 aif = 1; 343 break; 344 default: 345 WARN(1, "Invalid path %d\n", path); 346 return; 347 } 348 349 /* Do we have both an active AIF and an active algorithm? */ 350 ena = wm8994->mbc_ena[path] || wm8994->vss_ena[path] || 351 wm8994->hpf1_ena[path] || wm8994->hpf2_ena[path] || 352 wm8994->enh_eq_ena[path]; 353 if (!pwr_reg) 354 ena = 0; 355 356 reg = snd_soc_component_read(component, WM8958_DSP2_PROGRAM); 357 358 dev_dbg(component->dev, "DSP path %d %d startup: %d, power: %x, DSP: %x\n", 359 path, wm8994->dsp_active, start, pwr_reg, reg); 360 361 if (start && ena) { 362 /* If the DSP is already running then noop */ 363 if (reg & WM8958_DSP2_ENA) 364 return; 365 366 /* If either AIFnCLK is not yet enabled postpone */ 367 if (!(snd_soc_component_read(component, WM8994_AIF1_CLOCKING_1) 368 & WM8994_AIF1CLK_ENA_MASK) && 369 !(snd_soc_component_read(component, WM8994_AIF2_CLOCKING_1) 370 & WM8994_AIF2CLK_ENA_MASK)) 371 return; 372 373 /* Switch the clock over to the appropriate AIF */ 374 snd_soc_component_update_bits(component, WM8994_CLOCKING_1, 375 WM8958_DSP2CLK_SRC | WM8958_DSP2CLK_ENA, 376 aif << WM8958_DSP2CLK_SRC_SHIFT | 377 WM8958_DSP2CLK_ENA); 378 379 if (wm8994->enh_eq_ena[path]) 380 wm8958_dsp_start_enh_eq(component, path); 381 else if (wm8994->vss_ena[path] || wm8994->hpf1_ena[path] || 382 wm8994->hpf2_ena[path]) 383 wm8958_dsp_start_vss(component, path); 384 else if (wm8994->mbc_ena[path]) 385 wm8958_dsp_start_mbc(component, path); 386 387 wm8994->dsp_active = path; 388 389 dev_dbg(component->dev, "DSP running in path %d\n", path); 390 } 391 392 if (!start && wm8994->dsp_active == path) { 393 /* If the DSP is already stopped then noop */ 394 if (!(reg & WM8958_DSP2_ENA)) 395 return; 396 397 snd_soc_component_update_bits(component, WM8958_DSP2_CONFIG, 398 WM8958_MBC_ENA, 0); 399 snd_soc_component_write(component, WM8958_DSP2_EXECCONTROL, 400 WM8958_DSP2_STOP); 401 snd_soc_component_update_bits(component, WM8958_DSP2_PROGRAM, 402 WM8958_DSP2_ENA, 0); 403 snd_soc_component_update_bits(component, WM8994_CLOCKING_1, 404 WM8958_DSP2CLK_ENA, 0); 405 406 wm8994->dsp_active = -1; 407 408 dev_dbg(component->dev, "DSP stopped\n"); 409 } 410 } 411 412 int wm8958_aif_ev(struct snd_soc_dapm_widget *w, 413 struct snd_kcontrol *kcontrol, int event) 414 { 415 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); 416 struct wm8994 *control = dev_get_drvdata(component->dev->parent); 417 int i; 418 419 if (control->type != WM8958) 420 return 0; 421 422 switch (event) { 423 case SND_SOC_DAPM_POST_PMU: 424 case SND_SOC_DAPM_PRE_PMU: 425 for (i = 0; i < 3; i++) 426 wm8958_dsp_apply(component, i, 1); 427 break; 428 case SND_SOC_DAPM_POST_PMD: 429 case SND_SOC_DAPM_PRE_PMD: 430 for (i = 0; i < 3; i++) 431 wm8958_dsp_apply(component, i, 0); 432 break; 433 } 434 435 return 0; 436 } 437 438 /* Check if DSP2 is in use on another AIF */ 439 static int wm8958_dsp2_busy(struct wm8994_priv *wm8994, int aif) 440 { 441 int i; 442 443 for (i = 0; i < ARRAY_SIZE(wm8994->mbc_ena); i++) { 444 if (i == aif) 445 continue; 446 if (wm8994->mbc_ena[i] || wm8994->vss_ena[i] || 447 wm8994->hpf1_ena[i] || wm8994->hpf2_ena[i]) 448 return 1; 449 } 450 451 return 0; 452 } 453 454 static int wm8958_put_mbc_enum(struct snd_kcontrol *kcontrol, 455 struct snd_ctl_elem_value *ucontrol) 456 { 457 struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); 458 struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component); 459 struct wm8994 *control = wm8994->wm8994; 460 int value = ucontrol->value.enumerated.item[0]; 461 int reg; 462 463 /* Don't allow on the fly reconfiguration */ 464 reg = snd_soc_component_read(component, WM8994_CLOCKING_1); 465 if (reg < 0 || reg & WM8958_DSP2CLK_ENA) 466 return -EBUSY; 467 468 if (value >= control->pdata.num_mbc_cfgs) 469 return -EINVAL; 470 471 wm8994->mbc_cfg = value; 472 473 return 0; 474 } 475 476 static int wm8958_get_mbc_enum(struct snd_kcontrol *kcontrol, 477 struct snd_ctl_elem_value *ucontrol) 478 { 479 struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); 480 struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component); 481 482 ucontrol->value.enumerated.item[0] = wm8994->mbc_cfg; 483 484 return 0; 485 } 486 487 static int wm8958_mbc_info(struct snd_kcontrol *kcontrol, 488 struct snd_ctl_elem_info *uinfo) 489 { 490 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; 491 uinfo->count = 1; 492 uinfo->value.integer.min = 0; 493 uinfo->value.integer.max = 1; 494 return 0; 495 } 496 497 static int wm8958_mbc_get(struct snd_kcontrol *kcontrol, 498 struct snd_ctl_elem_value *ucontrol) 499 { 500 int mbc = kcontrol->private_value; 501 struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); 502 struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component); 503 504 ucontrol->value.integer.value[0] = wm8994->mbc_ena[mbc]; 505 506 return 0; 507 } 508 509 static int wm8958_mbc_put(struct snd_kcontrol *kcontrol, 510 struct snd_ctl_elem_value *ucontrol) 511 { 512 int mbc = kcontrol->private_value; 513 struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); 514 struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component); 515 516 if (wm8994->mbc_ena[mbc] == ucontrol->value.integer.value[0]) 517 return 0; 518 519 if (ucontrol->value.integer.value[0] > 1) 520 return -EINVAL; 521 522 if (wm8958_dsp2_busy(wm8994, mbc)) { 523 dev_dbg(component->dev, "DSP2 active on %d already\n", mbc); 524 return -EBUSY; 525 } 526 527 if (wm8994->enh_eq_ena[mbc]) 528 return -EBUSY; 529 530 wm8994->mbc_ena[mbc] = ucontrol->value.integer.value[0]; 531 532 wm8958_dsp_apply(component, mbc, wm8994->mbc_ena[mbc]); 533 534 return 1; 535 } 536 537 #define WM8958_MBC_SWITCH(xname, xval) {\ 538 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \ 539 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,\ 540 .info = wm8958_mbc_info, \ 541 .get = wm8958_mbc_get, .put = wm8958_mbc_put, \ 542 .private_value = xval } 543 544 static int wm8958_put_vss_enum(struct snd_kcontrol *kcontrol, 545 struct snd_ctl_elem_value *ucontrol) 546 { 547 struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); 548 struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component); 549 struct wm8994 *control = wm8994->wm8994; 550 int value = ucontrol->value.enumerated.item[0]; 551 int reg; 552 553 /* Don't allow on the fly reconfiguration */ 554 reg = snd_soc_component_read(component, WM8994_CLOCKING_1); 555 if (reg < 0 || reg & WM8958_DSP2CLK_ENA) 556 return -EBUSY; 557 558 if (value >= control->pdata.num_vss_cfgs) 559 return -EINVAL; 560 561 wm8994->vss_cfg = value; 562 563 return 0; 564 } 565 566 static int wm8958_get_vss_enum(struct snd_kcontrol *kcontrol, 567 struct snd_ctl_elem_value *ucontrol) 568 { 569 struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); 570 struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component); 571 572 ucontrol->value.enumerated.item[0] = wm8994->vss_cfg; 573 574 return 0; 575 } 576 577 static int wm8958_put_vss_hpf_enum(struct snd_kcontrol *kcontrol, 578 struct snd_ctl_elem_value *ucontrol) 579 { 580 struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); 581 struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component); 582 struct wm8994 *control = wm8994->wm8994; 583 int value = ucontrol->value.enumerated.item[0]; 584 int reg; 585 586 /* Don't allow on the fly reconfiguration */ 587 reg = snd_soc_component_read(component, WM8994_CLOCKING_1); 588 if (reg < 0 || reg & WM8958_DSP2CLK_ENA) 589 return -EBUSY; 590 591 if (value >= control->pdata.num_vss_hpf_cfgs) 592 return -EINVAL; 593 594 wm8994->vss_hpf_cfg = value; 595 596 return 0; 597 } 598 599 static int wm8958_get_vss_hpf_enum(struct snd_kcontrol *kcontrol, 600 struct snd_ctl_elem_value *ucontrol) 601 { 602 struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); 603 struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component); 604 605 ucontrol->value.enumerated.item[0] = wm8994->vss_hpf_cfg; 606 607 return 0; 608 } 609 610 static int wm8958_vss_info(struct snd_kcontrol *kcontrol, 611 struct snd_ctl_elem_info *uinfo) 612 { 613 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; 614 uinfo->count = 1; 615 uinfo->value.integer.min = 0; 616 uinfo->value.integer.max = 1; 617 return 0; 618 } 619 620 static int wm8958_vss_get(struct snd_kcontrol *kcontrol, 621 struct snd_ctl_elem_value *ucontrol) 622 { 623 int vss = kcontrol->private_value; 624 struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); 625 struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component); 626 627 ucontrol->value.integer.value[0] = wm8994->vss_ena[vss]; 628 629 return 0; 630 } 631 632 static int wm8958_vss_put(struct snd_kcontrol *kcontrol, 633 struct snd_ctl_elem_value *ucontrol) 634 { 635 int vss = kcontrol->private_value; 636 struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); 637 struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component); 638 639 if (wm8994->vss_ena[vss] == ucontrol->value.integer.value[0]) 640 return 0; 641 642 if (ucontrol->value.integer.value[0] > 1) 643 return -EINVAL; 644 645 if (!wm8994->mbc_vss) 646 return -ENODEV; 647 648 if (wm8958_dsp2_busy(wm8994, vss)) { 649 dev_dbg(component->dev, "DSP2 active on %d already\n", vss); 650 return -EBUSY; 651 } 652 653 if (wm8994->enh_eq_ena[vss]) 654 return -EBUSY; 655 656 wm8994->vss_ena[vss] = ucontrol->value.integer.value[0]; 657 658 wm8958_dsp_apply(component, vss, wm8994->vss_ena[vss]); 659 660 return 1; 661 } 662 663 664 #define WM8958_VSS_SWITCH(xname, xval) {\ 665 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \ 666 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,\ 667 .info = wm8958_vss_info, \ 668 .get = wm8958_vss_get, .put = wm8958_vss_put, \ 669 .private_value = xval } 670 671 static int wm8958_hpf_info(struct snd_kcontrol *kcontrol, 672 struct snd_ctl_elem_info *uinfo) 673 { 674 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; 675 uinfo->count = 1; 676 uinfo->value.integer.min = 0; 677 uinfo->value.integer.max = 1; 678 return 0; 679 } 680 681 static int wm8958_hpf_get(struct snd_kcontrol *kcontrol, 682 struct snd_ctl_elem_value *ucontrol) 683 { 684 int hpf = kcontrol->private_value; 685 struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); 686 struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component); 687 688 if (hpf < 3) 689 ucontrol->value.integer.value[0] = wm8994->hpf1_ena[hpf % 3]; 690 else 691 ucontrol->value.integer.value[0] = wm8994->hpf2_ena[hpf % 3]; 692 693 return 0; 694 } 695 696 static int wm8958_hpf_put(struct snd_kcontrol *kcontrol, 697 struct snd_ctl_elem_value *ucontrol) 698 { 699 int hpf = kcontrol->private_value; 700 struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); 701 struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component); 702 703 if (hpf < 3) { 704 if (wm8994->hpf1_ena[hpf % 3] == 705 ucontrol->value.integer.value[0]) 706 return 0; 707 } else { 708 if (wm8994->hpf2_ena[hpf % 3] == 709 ucontrol->value.integer.value[0]) 710 return 0; 711 } 712 713 if (ucontrol->value.integer.value[0] > 1) 714 return -EINVAL; 715 716 if (!wm8994->mbc_vss) 717 return -ENODEV; 718 719 if (wm8958_dsp2_busy(wm8994, hpf % 3)) { 720 dev_dbg(component->dev, "DSP2 active on %d already\n", hpf); 721 return -EBUSY; 722 } 723 724 if (wm8994->enh_eq_ena[hpf % 3]) 725 return -EBUSY; 726 727 if (hpf < 3) 728 wm8994->hpf1_ena[hpf % 3] = ucontrol->value.integer.value[0]; 729 else 730 wm8994->hpf2_ena[hpf % 3] = ucontrol->value.integer.value[0]; 731 732 wm8958_dsp_apply(component, hpf % 3, ucontrol->value.integer.value[0]); 733 734 return 1; 735 } 736 737 #define WM8958_HPF_SWITCH(xname, xval) {\ 738 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \ 739 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,\ 740 .info = wm8958_hpf_info, \ 741 .get = wm8958_hpf_get, .put = wm8958_hpf_put, \ 742 .private_value = xval } 743 744 static int wm8958_put_enh_eq_enum(struct snd_kcontrol *kcontrol, 745 struct snd_ctl_elem_value *ucontrol) 746 { 747 struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); 748 struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component); 749 struct wm8994 *control = wm8994->wm8994; 750 int value = ucontrol->value.enumerated.item[0]; 751 int reg; 752 753 /* Don't allow on the fly reconfiguration */ 754 reg = snd_soc_component_read(component, WM8994_CLOCKING_1); 755 if (reg < 0 || reg & WM8958_DSP2CLK_ENA) 756 return -EBUSY; 757 758 if (value >= control->pdata.num_enh_eq_cfgs) 759 return -EINVAL; 760 761 wm8994->enh_eq_cfg = value; 762 763 return 0; 764 } 765 766 static int wm8958_get_enh_eq_enum(struct snd_kcontrol *kcontrol, 767 struct snd_ctl_elem_value *ucontrol) 768 { 769 struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); 770 struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component); 771 772 ucontrol->value.enumerated.item[0] = wm8994->enh_eq_cfg; 773 774 return 0; 775 } 776 777 static int wm8958_enh_eq_info(struct snd_kcontrol *kcontrol, 778 struct snd_ctl_elem_info *uinfo) 779 { 780 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; 781 uinfo->count = 1; 782 uinfo->value.integer.min = 0; 783 uinfo->value.integer.max = 1; 784 return 0; 785 } 786 787 static int wm8958_enh_eq_get(struct snd_kcontrol *kcontrol, 788 struct snd_ctl_elem_value *ucontrol) 789 { 790 int eq = kcontrol->private_value; 791 struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); 792 struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component); 793 794 ucontrol->value.integer.value[0] = wm8994->enh_eq_ena[eq]; 795 796 return 0; 797 } 798 799 static int wm8958_enh_eq_put(struct snd_kcontrol *kcontrol, 800 struct snd_ctl_elem_value *ucontrol) 801 { 802 int eq = kcontrol->private_value; 803 struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); 804 struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component); 805 806 if (wm8994->enh_eq_ena[eq] == ucontrol->value.integer.value[0]) 807 return 0; 808 809 if (ucontrol->value.integer.value[0] > 1) 810 return -EINVAL; 811 812 if (!wm8994->enh_eq) 813 return -ENODEV; 814 815 if (wm8958_dsp2_busy(wm8994, eq)) { 816 dev_dbg(component->dev, "DSP2 active on %d already\n", eq); 817 return -EBUSY; 818 } 819 820 if (wm8994->mbc_ena[eq] || wm8994->vss_ena[eq] || 821 wm8994->hpf1_ena[eq] || wm8994->hpf2_ena[eq]) 822 return -EBUSY; 823 824 wm8994->enh_eq_ena[eq] = ucontrol->value.integer.value[0]; 825 826 wm8958_dsp_apply(component, eq, ucontrol->value.integer.value[0]); 827 828 return 1; 829 } 830 831 #define WM8958_ENH_EQ_SWITCH(xname, xval) {\ 832 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \ 833 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,\ 834 .info = wm8958_enh_eq_info, \ 835 .get = wm8958_enh_eq_get, .put = wm8958_enh_eq_put, \ 836 .private_value = xval } 837 838 static const struct snd_kcontrol_new wm8958_mbc_snd_controls[] = { 839 WM8958_MBC_SWITCH("AIF1DAC1 MBC Switch", 0), 840 WM8958_MBC_SWITCH("AIF1DAC2 MBC Switch", 1), 841 WM8958_MBC_SWITCH("AIF2DAC MBC Switch", 2), 842 }; 843 844 static const struct snd_kcontrol_new wm8958_vss_snd_controls[] = { 845 WM8958_VSS_SWITCH("AIF1DAC1 VSS Switch", 0), 846 WM8958_VSS_SWITCH("AIF1DAC2 VSS Switch", 1), 847 WM8958_VSS_SWITCH("AIF2DAC VSS Switch", 2), 848 WM8958_HPF_SWITCH("AIF1DAC1 HPF1 Switch", 0), 849 WM8958_HPF_SWITCH("AIF1DAC2 HPF1 Switch", 1), 850 WM8958_HPF_SWITCH("AIF2DAC HPF1 Switch", 2), 851 WM8958_HPF_SWITCH("AIF1DAC1 HPF2 Switch", 3), 852 WM8958_HPF_SWITCH("AIF1DAC2 HPF2 Switch", 4), 853 WM8958_HPF_SWITCH("AIF2DAC HPF2 Switch", 5), 854 }; 855 856 static const struct snd_kcontrol_new wm8958_enh_eq_snd_controls[] = { 857 WM8958_ENH_EQ_SWITCH("AIF1DAC1 Enhanced EQ Switch", 0), 858 WM8958_ENH_EQ_SWITCH("AIF1DAC2 Enhanced EQ Switch", 1), 859 WM8958_ENH_EQ_SWITCH("AIF2DAC Enhanced EQ Switch", 2), 860 }; 861 862 static void wm8958_enh_eq_loaded(const struct firmware *fw, void *context) 863 { 864 struct snd_soc_component *component = context; 865 struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component); 866 867 if (fw && (wm8958_dsp2_fw(component, "ENH_EQ", fw, true) == 0)) { 868 guard(mutex)(&wm8994->fw_lock); 869 wm8994->enh_eq = fw; 870 } 871 } 872 873 static void wm8958_mbc_vss_loaded(const struct firmware *fw, void *context) 874 { 875 struct snd_soc_component *component = context; 876 struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component); 877 878 if (fw && (wm8958_dsp2_fw(component, "MBC+VSS", fw, true) == 0)) { 879 guard(mutex)(&wm8994->fw_lock); 880 wm8994->mbc_vss = fw; 881 } 882 } 883 884 static void wm8958_mbc_loaded(const struct firmware *fw, void *context) 885 { 886 struct snd_soc_component *component = context; 887 struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component); 888 889 if (fw && (wm8958_dsp2_fw(component, "MBC", fw, true) == 0)) { 890 guard(mutex)(&wm8994->fw_lock); 891 wm8994->mbc = fw; 892 } 893 } 894 895 void wm8958_dsp2_init(struct snd_soc_component *component) 896 { 897 struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component); 898 struct wm8994 *control = wm8994->wm8994; 899 struct wm8994_pdata *pdata = &control->pdata; 900 int ret, i; 901 902 wm8994->dsp_active = -1; 903 904 snd_soc_add_component_controls(component, wm8958_mbc_snd_controls, 905 ARRAY_SIZE(wm8958_mbc_snd_controls)); 906 snd_soc_add_component_controls(component, wm8958_vss_snd_controls, 907 ARRAY_SIZE(wm8958_vss_snd_controls)); 908 snd_soc_add_component_controls(component, wm8958_enh_eq_snd_controls, 909 ARRAY_SIZE(wm8958_enh_eq_snd_controls)); 910 911 912 /* We don't *require* firmware and don't want to delay boot */ 913 request_firmware_nowait(THIS_MODULE, FW_ACTION_UEVENT, 914 "wm8958_mbc.wfw", component->dev, GFP_KERNEL, 915 component, wm8958_mbc_loaded); 916 request_firmware_nowait(THIS_MODULE, FW_ACTION_UEVENT, 917 "wm8958_mbc_vss.wfw", component->dev, GFP_KERNEL, 918 component, wm8958_mbc_vss_loaded); 919 request_firmware_nowait(THIS_MODULE, FW_ACTION_UEVENT, 920 "wm8958_enh_eq.wfw", component->dev, GFP_KERNEL, 921 component, wm8958_enh_eq_loaded); 922 923 if (pdata->num_mbc_cfgs) { 924 struct snd_kcontrol_new mbc_control[] = { 925 SOC_ENUM_EXT("MBC Mode", wm8994->mbc_enum, 926 wm8958_get_mbc_enum, wm8958_put_mbc_enum), 927 }; 928 929 /* We need an array of texts for the enum API */ 930 wm8994->mbc_texts = kmalloc_array(pdata->num_mbc_cfgs, 931 sizeof(char *), 932 GFP_KERNEL); 933 if (!wm8994->mbc_texts) 934 return; 935 936 for (i = 0; i < pdata->num_mbc_cfgs; i++) 937 wm8994->mbc_texts[i] = pdata->mbc_cfgs[i].name; 938 939 wm8994->mbc_enum.items = pdata->num_mbc_cfgs; 940 wm8994->mbc_enum.texts = wm8994->mbc_texts; 941 942 ret = snd_soc_add_component_controls(wm8994->hubs.component, 943 mbc_control, 1); 944 if (ret != 0) 945 dev_err(wm8994->hubs.component->dev, 946 "Failed to add MBC mode controls: %d\n", ret); 947 } 948 949 if (pdata->num_vss_cfgs) { 950 struct snd_kcontrol_new vss_control[] = { 951 SOC_ENUM_EXT("VSS Mode", wm8994->vss_enum, 952 wm8958_get_vss_enum, wm8958_put_vss_enum), 953 }; 954 955 /* We need an array of texts for the enum API */ 956 wm8994->vss_texts = kmalloc_array(pdata->num_vss_cfgs, 957 sizeof(char *), 958 GFP_KERNEL); 959 if (!wm8994->vss_texts) 960 return; 961 962 for (i = 0; i < pdata->num_vss_cfgs; i++) 963 wm8994->vss_texts[i] = pdata->vss_cfgs[i].name; 964 965 wm8994->vss_enum.items = pdata->num_vss_cfgs; 966 wm8994->vss_enum.texts = wm8994->vss_texts; 967 968 ret = snd_soc_add_component_controls(wm8994->hubs.component, 969 vss_control, 1); 970 if (ret != 0) 971 dev_err(wm8994->hubs.component->dev, 972 "Failed to add VSS mode controls: %d\n", ret); 973 } 974 975 if (pdata->num_vss_hpf_cfgs) { 976 struct snd_kcontrol_new hpf_control[] = { 977 SOC_ENUM_EXT("VSS HPF Mode", wm8994->vss_hpf_enum, 978 wm8958_get_vss_hpf_enum, 979 wm8958_put_vss_hpf_enum), 980 }; 981 982 /* We need an array of texts for the enum API */ 983 wm8994->vss_hpf_texts = kmalloc_array(pdata->num_vss_hpf_cfgs, 984 sizeof(char *), 985 GFP_KERNEL); 986 if (!wm8994->vss_hpf_texts) 987 return; 988 989 for (i = 0; i < pdata->num_vss_hpf_cfgs; i++) 990 wm8994->vss_hpf_texts[i] = pdata->vss_hpf_cfgs[i].name; 991 992 wm8994->vss_hpf_enum.items = pdata->num_vss_hpf_cfgs; 993 wm8994->vss_hpf_enum.texts = wm8994->vss_hpf_texts; 994 995 ret = snd_soc_add_component_controls(wm8994->hubs.component, 996 hpf_control, 1); 997 if (ret != 0) 998 dev_err(wm8994->hubs.component->dev, 999 "Failed to add VSS HPFmode controls: %d\n", 1000 ret); 1001 } 1002 1003 if (pdata->num_enh_eq_cfgs) { 1004 struct snd_kcontrol_new eq_control[] = { 1005 SOC_ENUM_EXT("Enhanced EQ Mode", wm8994->enh_eq_enum, 1006 wm8958_get_enh_eq_enum, 1007 wm8958_put_enh_eq_enum), 1008 }; 1009 1010 /* We need an array of texts for the enum API */ 1011 wm8994->enh_eq_texts = kmalloc_array(pdata->num_enh_eq_cfgs, 1012 sizeof(char *), 1013 GFP_KERNEL); 1014 if (!wm8994->enh_eq_texts) 1015 return; 1016 1017 for (i = 0; i < pdata->num_enh_eq_cfgs; i++) 1018 wm8994->enh_eq_texts[i] = pdata->enh_eq_cfgs[i].name; 1019 1020 wm8994->enh_eq_enum.items = pdata->num_enh_eq_cfgs; 1021 wm8994->enh_eq_enum.texts = wm8994->enh_eq_texts; 1022 1023 ret = snd_soc_add_component_controls(wm8994->hubs.component, 1024 eq_control, 1); 1025 if (ret != 0) 1026 dev_err(wm8994->hubs.component->dev, 1027 "Failed to add enhanced EQ controls: %d\n", 1028 ret); 1029 } 1030 } 1031