Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ASoC: rt715: add RT715 codec driver

Signed-off-by: Jack Yu <jack.yu@realtek.com>
Link: https://lore.kernel.org/r/20200110021821.17843-1-jack.yu@realtek.com
Signed-off-by: Mark Brown <broonie@kernel.org>

authored by

Jack Yu and committed by
Mark Brown
d1ede064 ec0f6a4c

+2056
+10
sound/soc/codecs/Kconfig
··· 167 167 select SND_SOC_RT5682 if I2C 168 168 select SND_SOC_RT700_SDW if SOUNDWIRE 169 169 select SND_SOC_RT711_SDW if SOUNDWIRE 170 + select SND_SOC_RT715_SDW if SOUNDWIRE 170 171 select SND_SOC_SGTL5000 if I2C 171 172 select SND_SOC_SI476X if MFD_SI476X_CORE 172 173 select SND_SOC_SIMPLE_AMPLIFIER ··· 1078 1077 tristate "Realtek RT711 Codec - SDW" 1079 1078 depends on SOUNDWIRE 1080 1079 select SND_SOC_RT711 1080 + select REGMAP_SOUNDWIRE 1081 + 1082 + config SND_SOC_RT715 1083 + tristate 1084 + 1085 + config SND_SOC_RT715_SDW 1086 + tristate "Realtek RT715 Codec - SDW" 1087 + depends on SOUNDWIRE 1088 + select SND_SOC_RT715 1081 1089 select REGMAP_SOUNDWIRE 1082 1090 1083 1091 #Freescale sgtl5000 codec
+2
sound/soc/codecs/Makefile
··· 175 175 snd-soc-rt5682-objs := rt5682.o 176 176 snd-soc-rt700-objs := rt700.o rt700-sdw.o 177 177 snd-soc-rt711-objs := rt711.o rt711-sdw.o 178 + snd-soc-rt715-objs := rt715.o rt715-sdw.o 178 179 snd-soc-sgtl5000-objs := sgtl5000.o 179 180 snd-soc-alc5623-objs := alc5623.o 180 181 snd-soc-alc5632-objs := alc5632.o ··· 470 469 obj-$(CONFIG_SND_SOC_RT5682) += snd-soc-rt5682.o 471 470 obj-$(CONFIG_SND_SOC_RT700) += snd-soc-rt700.o 472 471 obj-$(CONFIG_SND_SOC_RT711) += snd-soc-rt711.o 472 + obj-$(CONFIG_SND_SOC_RT715) += snd-soc-rt715.o 473 473 obj-$(CONFIG_SND_SOC_SGTL5000) += snd-soc-sgtl5000.o 474 474 obj-$(CONFIG_SND_SOC_SIGMADSP) += snd-soc-sigmadsp.o 475 475 obj-$(CONFIG_SND_SOC_SIGMADSP_I2C) += snd-soc-sigmadsp-i2c.o
+613
sound/soc/codecs/rt715-sdw.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * rt715-sdw.c -- rt715 ALSA SoC audio driver 4 + * 5 + * Copyright(c) 2019 Realtek Semiconductor Corp. 6 + * 7 + * ALC715 ASoC Codec Driver based Intel Dummy SdW codec driver 8 + * 9 + */ 10 + #include <linux/delay.h> 11 + #include <linux/device.h> 12 + #include <linux/mod_devicetable.h> 13 + #include <linux/soundwire/sdw.h> 14 + #include <linux/soundwire/sdw_type.h> 15 + #include <linux/module.h> 16 + #include <linux/of.h> 17 + #include <linux/regmap.h> 18 + #include <sound/soc.h> 19 + #include "rt715.h" 20 + #include "rt715-sdw.h" 21 + 22 + static bool rt715_readable_register(struct device *dev, unsigned int reg) 23 + { 24 + switch (reg) { 25 + case 0x00e0 ... 0x00e5: 26 + case 0x00ee ... 0x00ef: 27 + case 0x00f0 ... 0x00f5: 28 + case 0x00fe ... 0x00ff: 29 + case 0x02e0: 30 + case 0x02f0: 31 + case 0x04e0: 32 + case 0x04f0: 33 + case 0x06e0: 34 + case 0x06f0: 35 + case 0x2000 ... 0x2016: 36 + case 0x201a ... 0x2027: 37 + case 0x2029 ... 0x202a: 38 + case 0x202d ... 0x2034: 39 + case 0x2200 ... 0x2204: 40 + case 0x2206 ... 0x2212: 41 + case 0x2220 ... 0x2223: 42 + case 0x2230 ... 0x2239: 43 + case 0x22f0 ... 0x22f3: 44 + case 0x3122: 45 + case 0x3123: 46 + case 0x3124: 47 + case 0x3125: 48 + case 0x3607: 49 + case 0x3608: 50 + case 0x3609: 51 + case 0x3610: 52 + case 0x3611: 53 + case 0x3627: 54 + case 0x3712: 55 + case 0x3713: 56 + case 0x3718: 57 + case 0x3719: 58 + case 0x371a: 59 + case 0x371b: 60 + case 0x371d: 61 + case 0x3729: 62 + case 0x385e: 63 + case 0x3859: 64 + case 0x4c12: 65 + case 0x4c13: 66 + case 0x4c1d: 67 + case 0x4c29: 68 + case 0x4d12: 69 + case 0x4d13: 70 + case 0x4d1d: 71 + case 0x4d29: 72 + case 0x4e12: 73 + case 0x4e13: 74 + case 0x4e1d: 75 + case 0x4e29: 76 + case 0x4f12: 77 + case 0x4f13: 78 + case 0x4f1d: 79 + case 0x4f29: 80 + case 0x7207: 81 + case 0x7208: 82 + case 0x7209: 83 + case 0x7227: 84 + case 0x7307: 85 + case 0x7308: 86 + case 0x7309: 87 + case 0x7312: 88 + case 0x7313: 89 + case 0x7318: 90 + case 0x7319: 91 + case 0x731a: 92 + case 0x731b: 93 + case 0x731d: 94 + case 0x7327: 95 + case 0x7329: 96 + case 0x8287: 97 + case 0x8288: 98 + case 0x8289: 99 + case 0x82a7: 100 + case 0x8387: 101 + case 0x8388: 102 + case 0x8389: 103 + case 0x8392: 104 + case 0x8393: 105 + case 0x8398: 106 + case 0x8399: 107 + case 0x839a: 108 + case 0x839b: 109 + case 0x839d: 110 + case 0x83a7: 111 + case 0x83a9: 112 + case 0x752039: 113 + return true; 114 + default: 115 + return false; 116 + } 117 + } 118 + 119 + static bool rt715_volatile_register(struct device *dev, unsigned int reg) 120 + { 121 + switch (reg) { 122 + case 0x00e5: 123 + case 0x00f0: 124 + case 0x00f3: 125 + case 0x00f5: 126 + case 0x2009: 127 + case 0x2016: 128 + case 0x201b: 129 + case 0x201c: 130 + case 0x201d: 131 + case 0x201f: 132 + case 0x2023: 133 + case 0x2230: 134 + case 0x200b ... 0x200e: /* i2c read */ 135 + case 0x2012 ... 0x2015: /* HD-A read */ 136 + case 0x202d ... 0x202f: /* BRA */ 137 + case 0x2201 ... 0x2212: /* i2c debug */ 138 + case 0x2220 ... 0x2223: /* decoded HD-A */ 139 + return true; 140 + default: 141 + return false; 142 + } 143 + } 144 + 145 + static int rt715_sdw_read(void *context, unsigned int reg, unsigned int *val) 146 + { 147 + struct device *dev = context; 148 + struct rt715_priv *rt715 = dev_get_drvdata(dev); 149 + unsigned int sdw_data_3, sdw_data_2, sdw_data_1, sdw_data_0; 150 + unsigned int reg2 = 0, reg3 = 0, reg4 = 0, mask, nid, val2; 151 + unsigned int is_hda_reg = 1, is_index_reg = 0; 152 + int ret; 153 + 154 + if (reg > 0xffff) 155 + is_index_reg = 1; 156 + 157 + mask = reg & 0xf000; 158 + 159 + if (is_index_reg) { /* index registers */ 160 + val2 = reg & 0xff; 161 + reg = reg >> 8; 162 + nid = reg & 0xff; 163 + ret = regmap_write(rt715->sdw_regmap, reg, 0); 164 + if (ret < 0) 165 + return ret; 166 + reg2 = reg + 0x1000; 167 + reg2 |= 0x80; 168 + ret = regmap_write(rt715->sdw_regmap, reg2, val2); 169 + if (ret < 0) 170 + return ret; 171 + 172 + reg3 = RT715_PRIV_DATA_R_H | nid; 173 + ret = regmap_write(rt715->sdw_regmap, reg3, 174 + ((*val >> 8) & 0xff)); 175 + if (ret < 0) 176 + return ret; 177 + reg4 = reg3 + 0x1000; 178 + reg4 |= 0x80; 179 + ret = regmap_write(rt715->sdw_regmap, reg4, (*val & 0xff)); 180 + if (ret < 0) 181 + return ret; 182 + } else if (mask == 0x3000) { 183 + reg += 0x8000; 184 + ret = regmap_write(rt715->sdw_regmap, reg, *val); 185 + if (ret < 0) 186 + return ret; 187 + } else if (mask == 0x7000) { 188 + reg += 0x2000; 189 + reg |= 0x800; 190 + ret = regmap_write(rt715->sdw_regmap, reg, 191 + ((*val >> 8) & 0xff)); 192 + if (ret < 0) 193 + return ret; 194 + reg2 = reg + 0x1000; 195 + reg2 |= 0x80; 196 + ret = regmap_write(rt715->sdw_regmap, reg2, (*val & 0xff)); 197 + if (ret < 0) 198 + return ret; 199 + } else if ((reg & 0xff00) == 0x8300) { /* for R channel */ 200 + reg2 = reg - 0x1000; 201 + reg2 &= ~0x80; 202 + ret = regmap_write(rt715->sdw_regmap, reg2, 203 + ((*val >> 8) & 0xff)); 204 + if (ret < 0) 205 + return ret; 206 + ret = regmap_write(rt715->sdw_regmap, reg, (*val & 0xff)); 207 + if (ret < 0) 208 + return ret; 209 + } else if (mask == 0x9000) { 210 + ret = regmap_write(rt715->sdw_regmap, reg, 211 + ((*val >> 8) & 0xff)); 212 + if (ret < 0) 213 + return ret; 214 + reg2 = reg + 0x1000; 215 + reg2 |= 0x80; 216 + ret = regmap_write(rt715->sdw_regmap, reg2, (*val & 0xff)); 217 + if (ret < 0) 218 + return ret; 219 + } else if (mask == 0xb000) { 220 + ret = regmap_write(rt715->sdw_regmap, reg, *val); 221 + if (ret < 0) 222 + return ret; 223 + } else { 224 + ret = regmap_read(rt715->sdw_regmap, reg, val); 225 + if (ret < 0) 226 + return ret; 227 + is_hda_reg = 0; 228 + } 229 + 230 + if (is_hda_reg || is_index_reg) { 231 + sdw_data_3 = 0; 232 + sdw_data_2 = 0; 233 + sdw_data_1 = 0; 234 + sdw_data_0 = 0; 235 + ret = regmap_read(rt715->sdw_regmap, RT715_READ_HDA_3, 236 + &sdw_data_3); 237 + if (ret < 0) 238 + return ret; 239 + ret = regmap_read(rt715->sdw_regmap, RT715_READ_HDA_2, 240 + &sdw_data_2); 241 + if (ret < 0) 242 + return ret; 243 + ret = regmap_read(rt715->sdw_regmap, RT715_READ_HDA_1, 244 + &sdw_data_1); 245 + if (ret < 0) 246 + return ret; 247 + ret = regmap_read(rt715->sdw_regmap, RT715_READ_HDA_0, 248 + &sdw_data_0); 249 + if (ret < 0) 250 + return ret; 251 + *val = ((sdw_data_3 & 0xff) << 24) | 252 + ((sdw_data_2 & 0xff) << 16) | 253 + ((sdw_data_1 & 0xff) << 8) | (sdw_data_0 & 0xff); 254 + } 255 + 256 + if (is_hda_reg == 0) 257 + dev_dbg(dev, "[%s] %04x => %08x\n", __func__, reg, *val); 258 + else if (is_index_reg) 259 + dev_dbg(dev, "[%s] %04x %04x %04x %04x => %08x\n", __func__, 260 + reg, reg2, reg3, reg4, *val); 261 + else 262 + dev_dbg(dev, "[%s] %04x %04x => %08x\n", 263 + __func__, reg, reg2, *val); 264 + 265 + return 0; 266 + } 267 + 268 + static int rt715_sdw_write(void *context, unsigned int reg, unsigned int val) 269 + { 270 + struct device *dev = context; 271 + struct rt715_priv *rt715 = dev_get_drvdata(dev); 272 + unsigned int reg2 = 0, reg3, reg4, nid, mask, val2; 273 + unsigned int is_index_reg = 0; 274 + int ret; 275 + 276 + if (reg > 0xffff) 277 + is_index_reg = 1; 278 + 279 + mask = reg & 0xf000; 280 + 281 + if (is_index_reg) { /* index registers */ 282 + val2 = reg & 0xff; 283 + reg = reg >> 8; 284 + nid = reg & 0xff; 285 + ret = regmap_write(rt715->sdw_regmap, reg, 0); 286 + if (ret < 0) 287 + return ret; 288 + reg2 = reg + 0x1000; 289 + reg2 |= 0x80; 290 + ret = regmap_write(rt715->sdw_regmap, reg2, val2); 291 + if (ret < 0) 292 + return ret; 293 + 294 + reg3 = RT715_PRIV_DATA_W_H | nid; 295 + ret = regmap_write(rt715->sdw_regmap, reg3, 296 + ((val >> 8) & 0xff)); 297 + if (ret < 0) 298 + return ret; 299 + reg4 = reg3 + 0x1000; 300 + reg4 |= 0x80; 301 + ret = regmap_write(rt715->sdw_regmap, reg4, (val & 0xff)); 302 + if (ret < 0) 303 + return ret; 304 + is_index_reg = 1; 305 + } else if (reg < 0x4fff) { 306 + ret = regmap_write(rt715->sdw_regmap, reg, val); 307 + if (ret < 0) 308 + return ret; 309 + } else if (reg == RT715_FUNC_RESET) { 310 + ret = regmap_write(rt715->sdw_regmap, reg, val); 311 + if (ret < 0) 312 + return ret; 313 + } else if (mask == 0x7000) { 314 + ret = regmap_write(rt715->sdw_regmap, reg, 315 + ((val >> 8) & 0xff)); 316 + if (ret < 0) 317 + return ret; 318 + reg2 = reg + 0x1000; 319 + reg2 |= 0x80; 320 + ret = regmap_write(rt715->sdw_regmap, reg2, (val & 0xff)); 321 + if (ret < 0) 322 + return ret; 323 + } else if ((reg & 0xff00) == 0x8300) { /* for R channel */ 324 + reg2 = reg - 0x1000; 325 + reg2 &= ~0x80; 326 + ret = regmap_write(rt715->sdw_regmap, reg2, 327 + ((val >> 8) & 0xff)); 328 + if (ret < 0) 329 + return ret; 330 + ret = regmap_write(rt715->sdw_regmap, reg, (val & 0xff)); 331 + if (ret < 0) 332 + return ret; 333 + } 334 + 335 + if (reg2 == 0) 336 + dev_dbg(dev, "[%s] %04x <= %04x\n", __func__, reg, val); 337 + else if (is_index_reg) 338 + dev_dbg(dev, "[%s] %04x %04x %04x %04x <= %04x %04x\n", 339 + __func__, reg, reg2, reg3, reg4, val2, val); 340 + else 341 + dev_dbg(dev, "[%s] %04x %04x <= %04x\n", 342 + __func__, reg, reg2, val); 343 + 344 + return 0; 345 + } 346 + 347 + static const struct regmap_config rt715_regmap = { 348 + .reg_bits = 24, 349 + .val_bits = 32, 350 + .readable_reg = rt715_readable_register, /* Readable registers */ 351 + .volatile_reg = rt715_volatile_register, /* volatile register */ 352 + .max_register = 0x752039, /* Maximum number of register */ 353 + .reg_defaults = rt715_reg_defaults, /* Defaults */ 354 + .num_reg_defaults = ARRAY_SIZE(rt715_reg_defaults), 355 + .cache_type = REGCACHE_RBTREE, 356 + .use_single_read = true, 357 + .use_single_write = true, 358 + .reg_read = rt715_sdw_read, 359 + .reg_write = rt715_sdw_write, 360 + }; 361 + 362 + static const struct regmap_config rt715_sdw_regmap = { 363 + .name = "sdw", 364 + .reg_bits = 32, /* Total register space for SDW */ 365 + .val_bits = 8, /* Total number of bits in register */ 366 + .max_register = 0xff01, /* Maximum number of register */ 367 + .cache_type = REGCACHE_NONE, 368 + .use_single_read = true, 369 + .use_single_write = true, 370 + }; 371 + 372 + int hda_to_sdw(unsigned int nid, unsigned int verb, unsigned int payload, 373 + unsigned int *sdw_addr_h, unsigned int *sdw_data_h, 374 + unsigned int *sdw_addr_l, unsigned int *sdw_data_l) 375 + { 376 + unsigned int offset_h, offset_l, e_verb; 377 + 378 + if (((verb & 0xff) != 0) || verb == 0xf00) { /* 12 bits command */ 379 + if (verb == 0x7ff) /* special case */ 380 + offset_h = 0; 381 + else 382 + offset_h = 0x3000; 383 + 384 + if (verb & 0x800) /* get command */ 385 + e_verb = (verb - 0xf00) | 0x80; 386 + else /* set command */ 387 + e_verb = (verb - 0x700); 388 + 389 + *sdw_data_h = payload; /* 7 bits payload */ 390 + *sdw_addr_l = *sdw_data_l = 0; 391 + } else { /* 4 bits command */ 392 + if ((verb & 0x800) == 0x800) { /* read */ 393 + offset_h = 0x9000; 394 + offset_l = 0xa000; 395 + } else { /* write */ 396 + offset_h = 0x7000; 397 + offset_l = 0x8000; 398 + } 399 + e_verb = verb >> 8; 400 + *sdw_data_h = (payload >> 8); /* 16 bits payload [15:8] */ 401 + *sdw_addr_l = (e_verb << 8) | nid | 0x80; /* 0x80: valid bit */ 402 + *sdw_addr_l += offset_l; 403 + *sdw_data_l = payload & 0xff; 404 + } 405 + 406 + *sdw_addr_h = (e_verb << 8) | nid; 407 + *sdw_addr_h += offset_h; 408 + 409 + return 0; 410 + } 411 + EXPORT_SYMBOL(hda_to_sdw); 412 + 413 + static int rt715_update_status(struct sdw_slave *slave, 414 + enum sdw_slave_status status) 415 + { 416 + struct rt715_priv *rt715 = dev_get_drvdata(&slave->dev); 417 + 418 + /* Update the status */ 419 + rt715->status = status; 420 + /* 421 + * Perform initialization only if slave status is present and 422 + * hw_init flag is false 423 + */ 424 + if (rt715->hw_init || rt715->status != SDW_SLAVE_ATTACHED) 425 + return 0; 426 + 427 + /* perform I/O transfers required for Slave initialization */ 428 + return rt715_io_init(&slave->dev, slave); 429 + } 430 + 431 + static int rt715_read_prop(struct sdw_slave *slave) 432 + { 433 + struct sdw_slave_prop *prop = &slave->prop; 434 + int nval, i, num_of_ports = 1; 435 + u32 bit; 436 + unsigned long addr; 437 + struct sdw_dpn_prop *dpn; 438 + 439 + prop->paging_support = false; 440 + 441 + /* first we need to allocate memory for set bits in port lists */ 442 + prop->source_ports = 0x50;/* BITMAP: 01010000 */ 443 + prop->sink_ports = 0x0; /* BITMAP: 00000000 */ 444 + 445 + nval = hweight32(prop->source_ports); 446 + num_of_ports += nval; 447 + prop->src_dpn_prop = devm_kcalloc(&slave->dev, nval, 448 + sizeof(*prop->src_dpn_prop), 449 + GFP_KERNEL); 450 + if (!prop->src_dpn_prop) 451 + return -ENOMEM; 452 + 453 + dpn = prop->src_dpn_prop; 454 + i = 0; 455 + addr = prop->source_ports; 456 + for_each_set_bit(bit, &addr, 32) { 457 + dpn[i].num = bit; 458 + dpn[i].simple_ch_prep_sm = true; 459 + dpn[i].ch_prep_timeout = 10; 460 + i++; 461 + } 462 + 463 + /* do this again for sink now */ 464 + nval = hweight32(prop->sink_ports); 465 + num_of_ports += nval; 466 + prop->sink_dpn_prop = devm_kcalloc(&slave->dev, nval, 467 + sizeof(*prop->sink_dpn_prop), 468 + GFP_KERNEL); 469 + if (!prop->sink_dpn_prop) 470 + return -ENOMEM; 471 + 472 + dpn = prop->sink_dpn_prop; 473 + i = 0; 474 + addr = prop->sink_ports; 475 + for_each_set_bit(bit, &addr, 32) { 476 + dpn[i].num = bit; 477 + dpn[i].simple_ch_prep_sm = true; 478 + dpn[i].ch_prep_timeout = 10; 479 + i++; 480 + } 481 + 482 + /* Allocate port_ready based on num_of_ports */ 483 + slave->port_ready = devm_kcalloc(&slave->dev, num_of_ports, 484 + sizeof(*slave->port_ready), 485 + GFP_KERNEL); 486 + if (!slave->port_ready) 487 + return -ENOMEM; 488 + 489 + /* Initialize completion */ 490 + for (i = 0; i < num_of_ports; i++) 491 + init_completion(&slave->port_ready[i]); 492 + 493 + /* set the timeout values */ 494 + prop->clk_stop_timeout = 20; 495 + 496 + /* wake-up event */ 497 + prop->wake_capable = 1; 498 + 499 + return 0; 500 + } 501 + 502 + static int rt715_bus_config(struct sdw_slave *slave, 503 + struct sdw_bus_params *params) 504 + { 505 + struct rt715_priv *rt715 = dev_get_drvdata(&slave->dev); 506 + int ret; 507 + 508 + memcpy(&rt715->params, params, sizeof(*params)); 509 + 510 + ret = rt715_clock_config(&slave->dev); 511 + if (ret < 0) 512 + dev_err(&slave->dev, "Invalid clk config"); 513 + 514 + return 0; 515 + } 516 + 517 + static struct sdw_slave_ops rt715_slave_ops = { 518 + .read_prop = rt715_read_prop, 519 + .update_status = rt715_update_status, 520 + .bus_config = rt715_bus_config, 521 + }; 522 + 523 + static int rt715_sdw_probe(struct sdw_slave *slave, 524 + const struct sdw_device_id *id) 525 + { 526 + struct regmap *sdw_regmap, *regmap; 527 + 528 + /* Assign ops */ 529 + slave->ops = &rt715_slave_ops; 530 + 531 + /* Regmap Initialization */ 532 + sdw_regmap = devm_regmap_init_sdw(slave, &rt715_sdw_regmap); 533 + if (!sdw_regmap) 534 + return -EINVAL; 535 + 536 + regmap = devm_regmap_init(&slave->dev, NULL, &slave->dev, 537 + &rt715_regmap); 538 + if (!regmap) 539 + return -EINVAL; 540 + 541 + rt715_init(&slave->dev, sdw_regmap, regmap, slave); 542 + 543 + return 0; 544 + } 545 + 546 + static const struct sdw_device_id rt715_id[] = { 547 + SDW_SLAVE_ENTRY(0x025d, 0x715, 0), 548 + {}, 549 + }; 550 + MODULE_DEVICE_TABLE(sdw, rt715_id); 551 + 552 + static int rt715_dev_suspend(struct device *dev) 553 + { 554 + struct rt715_priv *rt715 = dev_get_drvdata(dev); 555 + 556 + if (!rt715->hw_init) 557 + return 0; 558 + 559 + regcache_cache_only(rt715->regmap, true); 560 + 561 + return 0; 562 + } 563 + 564 + #define RT715_PROBE_TIMEOUT 2000 565 + 566 + static int rt715_dev_resume(struct device *dev) 567 + { 568 + struct sdw_slave *slave = to_sdw_slave_device(dev); 569 + struct rt715_priv *rt715 = dev_get_drvdata(dev); 570 + unsigned long time; 571 + 572 + if (!rt715->hw_init) 573 + return 0; 574 + 575 + if (!slave->unattach_request) 576 + goto regmap_sync; 577 + 578 + time = wait_for_completion_timeout(&slave->initialization_complete, 579 + msecs_to_jiffies(RT715_PROBE_TIMEOUT)); 580 + if (!time) { 581 + dev_err(&slave->dev, "Initialization not complete, timed out\n"); 582 + return -ETIMEDOUT; 583 + } 584 + 585 + regmap_sync: 586 + slave->unattach_request = 0; 587 + regcache_cache_only(rt715->regmap, false); 588 + regcache_sync_region(rt715->regmap, 0x3000, 0x8fff); 589 + regcache_sync_region(rt715->regmap, 0x752039, 0x752039); 590 + 591 + return 0; 592 + } 593 + 594 + static const struct dev_pm_ops rt715_pm = { 595 + SET_SYSTEM_SLEEP_PM_OPS(rt715_dev_suspend, rt715_dev_resume) 596 + SET_RUNTIME_PM_OPS(rt715_dev_suspend, rt715_dev_resume, NULL) 597 + }; 598 + 599 + static struct sdw_driver rt715_sdw_driver = { 600 + .driver = { 601 + .name = "rt715", 602 + .owner = THIS_MODULE, 603 + .pm = &rt715_pm, 604 + }, 605 + .probe = rt715_sdw_probe, 606 + .ops = &rt715_slave_ops, 607 + .id_table = rt715_id, 608 + }; 609 + module_sdw_driver(rt715_sdw_driver); 610 + 611 + MODULE_DESCRIPTION("ASoC RT715 driver SDW"); 612 + MODULE_AUTHOR("Jack Yu <jack.yu@realtek.com>"); 613 + MODULE_LICENSE("GPL v2");
+337
sound/soc/codecs/rt715-sdw.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + /* 3 + * rt715-sdw.h -- RT715 ALSA SoC audio driver header 4 + * 5 + * Copyright(c) 2019 Realtek Semiconductor Corp. 6 + */ 7 + 8 + #ifndef __RT715_SDW_H__ 9 + #define __RT715_SDW_H__ 10 + 11 + static const struct reg_default rt715_reg_defaults[] = { 12 + { 0x0000, 0x00 }, 13 + { 0x0001, 0x00 }, 14 + { 0x0002, 0x00 }, 15 + { 0x0003, 0x00 }, 16 + { 0x0004, 0x00 }, 17 + { 0x0005, 0x01 }, 18 + { 0x0020, 0x00 }, 19 + { 0x0022, 0x00 }, 20 + { 0x0023, 0x00 }, 21 + { 0x0024, 0x00 }, 22 + { 0x0025, 0x00 }, 23 + { 0x0026, 0x00 }, 24 + { 0x0030, 0x00 }, 25 + { 0x0032, 0x00 }, 26 + { 0x0033, 0x00 }, 27 + { 0x0034, 0x00 }, 28 + { 0x0035, 0x00 }, 29 + { 0x0036, 0x00 }, 30 + { 0x0040, 0x00 }, 31 + { 0x0041, 0x00 }, 32 + { 0x0042, 0x00 }, 33 + { 0x0043, 0x00 }, 34 + { 0x0044, 0x20 }, 35 + { 0x0045, 0x01 }, 36 + { 0x0046, 0x00 }, 37 + { 0x0050, 0x20 }, 38 + { 0x0051, 0x02 }, 39 + { 0x0052, 0x5d }, 40 + { 0x0053, 0x07 }, 41 + { 0x0054, 0x15 }, 42 + { 0x0055, 0x00 }, 43 + { 0x0060, 0x00 }, 44 + { 0x0070, 0x00 }, 45 + { 0x0080, 0x00 }, 46 + { 0x0088, 0x10 }, 47 + { 0x00e0, 0x00 }, 48 + { 0x00e1, 0x00 }, 49 + { 0x00e2, 0x00 }, 50 + { 0x00e3, 0x00 }, 51 + { 0x00e4, 0x00 }, 52 + { 0x00e5, 0x00 }, 53 + { 0x00ee, 0x00 }, 54 + { 0x00ef, 0x00 }, 55 + { 0x00f0, 0x00 }, 56 + { 0x00f1, 0x00 }, 57 + { 0x00f2, 0x00 }, 58 + { 0x00f3, 0x00 }, 59 + { 0x00f4, 0x00 }, 60 + { 0x00f5, 0x00 }, 61 + { 0x00fe, 0x00 }, 62 + { 0x00ff, 0x00 }, 63 + { 0x0200, 0x00 }, 64 + { 0x0201, 0x00 }, 65 + { 0x0202, 0x20 }, 66 + { 0x0203, 0x00 }, 67 + { 0x0204, 0x00 }, 68 + { 0x0205, 0x03 }, 69 + { 0x0220, 0x00 }, 70 + { 0x0221, 0x00 }, 71 + { 0x0222, 0x00 }, 72 + { 0x0223, 0x00 }, 73 + { 0x0224, 0x00 }, 74 + { 0x0225, 0x00 }, 75 + { 0x0226, 0x00 }, 76 + { 0x0227, 0x00 }, 77 + { 0x0230, 0x00 }, 78 + { 0x0231, 0x00 }, 79 + { 0x0232, 0x00 }, 80 + { 0x0233, 0x00 }, 81 + { 0x0234, 0x00 }, 82 + { 0x0235, 0x00 }, 83 + { 0x0236, 0x00 }, 84 + { 0x0237, 0x00 }, 85 + { 0x02e0, 0x00 }, 86 + { 0x02f0, 0x00 }, 87 + { 0x0400, 0x00 }, 88 + { 0x0401, 0x00 }, 89 + { 0x0402, 0x20 }, 90 + { 0x0403, 0x00 }, 91 + { 0x0404, 0x00 }, 92 + { 0x0405, 0x0f }, 93 + { 0x0420, 0x00 }, 94 + { 0x0421, 0x00 }, 95 + { 0x0422, 0x00 }, 96 + { 0x0423, 0x00 }, 97 + { 0x0424, 0x00 }, 98 + { 0x0425, 0x00 }, 99 + { 0x0426, 0x00 }, 100 + { 0x0427, 0x00 }, 101 + { 0x0430, 0x00 }, 102 + { 0x0431, 0x00 }, 103 + { 0x0432, 0x00 }, 104 + { 0x0433, 0x00 }, 105 + { 0x0434, 0x00 }, 106 + { 0x0435, 0x00 }, 107 + { 0x0436, 0x00 }, 108 + { 0x0437, 0x00 }, 109 + { 0x04e0, 0x00 }, 110 + { 0x04f0, 0x00 }, 111 + { 0x0600, 0x00 }, 112 + { 0x0601, 0x00 }, 113 + { 0x0602, 0x20 }, 114 + { 0x0603, 0x00 }, 115 + { 0x0604, 0x00 }, 116 + { 0x0605, 0xff }, 117 + { 0x0620, 0x00 }, 118 + { 0x0621, 0x00 }, 119 + { 0x0622, 0x00 }, 120 + { 0x0623, 0x00 }, 121 + { 0x0624, 0x00 }, 122 + { 0x0625, 0x00 }, 123 + { 0x0626, 0x00 }, 124 + { 0x0627, 0x00 }, 125 + { 0x0630, 0x00 }, 126 + { 0x0631, 0x00 }, 127 + { 0x0632, 0x00 }, 128 + { 0x0633, 0x00 }, 129 + { 0x0634, 0x00 }, 130 + { 0x0635, 0x00 }, 131 + { 0x0636, 0x00 }, 132 + { 0x0637, 0x00 }, 133 + { 0x06e0, 0x00 }, 134 + { 0x06f0, 0x00 }, 135 + { 0x0f00, 0x00 }, 136 + { 0x0f01, 0x00 }, 137 + { 0x0f02, 0x00 }, 138 + { 0x0f03, 0x00 }, 139 + { 0x0f04, 0x00 }, 140 + { 0x0f05, 0xff }, 141 + { 0x0f06, 0x00 }, 142 + { 0x0f07, 0x00 }, 143 + { 0x0f08, 0x00 }, 144 + { 0x0f09, 0x00 }, 145 + { 0x0f0a, 0x00 }, 146 + { 0x0f0b, 0x00 }, 147 + { 0x0f0c, 0x00 }, 148 + { 0x0f0d, 0x00 }, 149 + { 0x0f0e, 0x00 }, 150 + { 0x0f0f, 0x00 }, 151 + { 0x0f10, 0x00 }, 152 + { 0x0f11, 0x00 }, 153 + { 0x0f12, 0x00 }, 154 + { 0x0f13, 0x00 }, 155 + { 0x0f14, 0x00 }, 156 + { 0x0f15, 0x00 }, 157 + { 0x0f16, 0x00 }, 158 + { 0x0f17, 0x00 }, 159 + { 0x0f18, 0x00 }, 160 + { 0x0f19, 0x00 }, 161 + { 0x0f1a, 0x00 }, 162 + { 0x0f1b, 0x00 }, 163 + { 0x0f1c, 0x00 }, 164 + { 0x0f1d, 0x00 }, 165 + { 0x0f1e, 0x00 }, 166 + { 0x0f1f, 0x00 }, 167 + { 0x0f20, 0x00 }, 168 + { 0x0f21, 0x00 }, 169 + { 0x0f22, 0x00 }, 170 + { 0x0f23, 0x00 }, 171 + { 0x0f24, 0x00 }, 172 + { 0x0f25, 0x00 }, 173 + { 0x0f26, 0x00 }, 174 + { 0x0f27, 0x00 }, 175 + { 0x0f30, 0x00 }, 176 + { 0x0f31, 0x00 }, 177 + { 0x0f32, 0x00 }, 178 + { 0x0f33, 0x00 }, 179 + { 0x0f34, 0x00 }, 180 + { 0x0f35, 0x00 }, 181 + { 0x0f36, 0x00 }, 182 + { 0x0f37, 0x00 }, 183 + { 0x2000, 0x00 }, 184 + { 0x2001, 0x00 }, 185 + { 0x2002, 0x00 }, 186 + { 0x2003, 0x00 }, 187 + { 0x2004, 0x00 }, 188 + { 0x2005, 0x00 }, 189 + { 0x2006, 0x00 }, 190 + { 0x2007, 0x00 }, 191 + { 0x2008, 0x00 }, 192 + { 0x2009, 0x03 }, 193 + { 0x200a, 0x00 }, 194 + { 0x200b, 0x00 }, 195 + { 0x200c, 0x00 }, 196 + { 0x200d, 0x00 }, 197 + { 0x200e, 0x00 }, 198 + { 0x200f, 0x10 }, 199 + { 0x2010, 0x00 }, 200 + { 0x2011, 0x00 }, 201 + { 0x2012, 0x00 }, 202 + { 0x2013, 0x00 }, 203 + { 0x2014, 0x00 }, 204 + { 0x2015, 0x00 }, 205 + { 0x2016, 0x00 }, 206 + { 0x201a, 0x00 }, 207 + { 0x201b, 0x00 }, 208 + { 0x201c, 0x00 }, 209 + { 0x201d, 0x00 }, 210 + { 0x201e, 0x00 }, 211 + { 0x201f, 0x00 }, 212 + { 0x2020, 0x00 }, 213 + { 0x2021, 0x00 }, 214 + { 0x2022, 0x00 }, 215 + { 0x2023, 0x00 }, 216 + { 0x2024, 0x00 }, 217 + { 0x2025, 0x01 }, 218 + { 0x2026, 0x00 }, 219 + { 0x2027, 0x00 }, 220 + { 0x2029, 0x00 }, 221 + { 0x202a, 0x00 }, 222 + { 0x202d, 0x00 }, 223 + { 0x202e, 0x00 }, 224 + { 0x202f, 0x00 }, 225 + { 0x2030, 0x00 }, 226 + { 0x2031, 0x00 }, 227 + { 0x2032, 0x00 }, 228 + { 0x2033, 0x00 }, 229 + { 0x2034, 0x00 }, 230 + { 0x2200, 0x00 }, 231 + { 0x2201, 0x00 }, 232 + { 0x2202, 0x00 }, 233 + { 0x2203, 0x00 }, 234 + { 0x2204, 0x00 }, 235 + { 0x2206, 0x00 }, 236 + { 0x2207, 0x00 }, 237 + { 0x2208, 0x00 }, 238 + { 0x2209, 0x00 }, 239 + { 0x220a, 0x00 }, 240 + { 0x220b, 0x00 }, 241 + { 0x220c, 0x00 }, 242 + { 0x220d, 0x00 }, 243 + { 0x220e, 0x00 }, 244 + { 0x220f, 0x00 }, 245 + { 0x2210, 0x00 }, 246 + { 0x2211, 0x00 }, 247 + { 0x2212, 0x00 }, 248 + { 0x2220, 0x00 }, 249 + { 0x2221, 0x00 }, 250 + { 0x2222, 0x00 }, 251 + { 0x2223, 0x00 }, 252 + { 0x2230, 0x00 }, 253 + { 0x2231, 0x0f }, 254 + { 0x2232, 0x00 }, 255 + { 0x2233, 0x00 }, 256 + { 0x2234, 0x00 }, 257 + { 0x2235, 0x00 }, 258 + { 0x2236, 0x00 }, 259 + { 0x2237, 0x00 }, 260 + { 0x2238, 0x00 }, 261 + { 0x2239, 0x00 }, 262 + { 0x22f0, 0x00 }, 263 + { 0x22f1, 0x00 }, 264 + { 0x22f2, 0x00 }, 265 + { 0x22f3, 0x00 }, 266 + { 0x3122, 0x02 }, 267 + { 0x3123, 0x03 }, 268 + { 0x3124, 0x00 }, 269 + { 0x3125, 0x01 }, 270 + { 0x3607, 0x00 }, 271 + { 0x3608, 0x00 }, 272 + { 0x3609, 0x00 }, 273 + { 0x3610, 0x00 }, 274 + { 0x3611, 0x00 }, 275 + { 0x3627, 0x00 }, 276 + { 0x3712, 0x00 }, 277 + { 0x3713, 0x00 }, 278 + { 0x3718, 0x00 }, 279 + { 0x3719, 0x00 }, 280 + { 0x371a, 0x00 }, 281 + { 0x371b, 0x00 }, 282 + { 0x371d, 0x00 }, 283 + { 0x3729, 0x00 }, 284 + { 0x385e, 0x00 }, 285 + { 0x3859, 0x00 }, 286 + { 0x4c12, 0x411111f0 }, 287 + { 0x4c13, 0x411111f0 }, 288 + { 0x4c1d, 0x411111f0 }, 289 + { 0x4c29, 0x411111f0 }, 290 + { 0x4d12, 0x411111f0 }, 291 + { 0x4d13, 0x411111f0 }, 292 + { 0x4d1d, 0x411111f0 }, 293 + { 0x4d29, 0x411111f0 }, 294 + { 0x4e12, 0x411111f0 }, 295 + { 0x4e13, 0x411111f0 }, 296 + { 0x4e1d, 0x411111f0 }, 297 + { 0x4e29, 0x411111f0 }, 298 + { 0x4f12, 0x411111f0 }, 299 + { 0x4f13, 0x411111f0 }, 300 + { 0x4f1d, 0x411111f0 }, 301 + { 0x4f29, 0x411111f0 }, 302 + { 0x7207, 0x00 }, 303 + { 0x8287, 0x00 }, 304 + { 0x7208, 0x00 }, 305 + { 0x8288, 0x00 }, 306 + { 0x7209, 0x00 }, 307 + { 0x8289, 0x00 }, 308 + { 0x7227, 0x00 }, 309 + { 0x82a7, 0x00 }, 310 + { 0x7307, 0x97 }, 311 + { 0x8387, 0x97 }, 312 + { 0x7308, 0x97 }, 313 + { 0x8388, 0x97 }, 314 + { 0x7309, 0x97 }, 315 + { 0x8389, 0x97 }, 316 + { 0x7312, 0x00 }, 317 + { 0x8392, 0x00 }, 318 + { 0x7313, 0x00 }, 319 + { 0x8393, 0x00 }, 320 + { 0x7318, 0x00 }, 321 + { 0x8398, 0x00 }, 322 + { 0x7319, 0x00 }, 323 + { 0x8399, 0x00 }, 324 + { 0x731a, 0x00 }, 325 + { 0x839a, 0x00 }, 326 + { 0x731b, 0x00 }, 327 + { 0x839b, 0x00 }, 328 + { 0x731d, 0x00 }, 329 + { 0x839d, 0x00 }, 330 + { 0x7327, 0x97 }, 331 + { 0x83a7, 0x97 }, 332 + { 0x7329, 0x00 }, 333 + { 0x83a9, 0x00 }, 334 + { 0x752039, 0xa500 }, 335 + }; 336 + 337 + #endif /* __RT715_H__ */
+873
sound/soc/codecs/rt715.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * rt715.c -- rt715 ALSA SoC audio driver 4 + * 5 + * Copyright(c) 2019 Realtek Semiconductor Corp. 6 + * 7 + * ALC715 ASoC Codec Driver based Intel Dummy SdW codec driver 8 + * 9 + */ 10 + 11 + #include <linux/module.h> 12 + #include <linux/moduleparam.h> 13 + #include <linux/version.h> 14 + #include <linux/kernel.h> 15 + #include <linux/init.h> 16 + #include <linux/delay.h> 17 + #include <linux/i2c.h> 18 + #include <linux/pm_runtime.h> 19 + #include <linux/pm.h> 20 + #include <linux/soundwire/sdw.h> 21 + #include <linux/gpio.h> 22 + #include <linux/regmap.h> 23 + #include <linux/slab.h> 24 + #include <linux/platform_device.h> 25 + #include <linux/regulator/consumer.h> 26 + #include <linux/gpio/consumer.h> 27 + #include <linux/of.h> 28 + #include <linux/of_gpio.h> 29 + #include <linux/of_device.h> 30 + #include <sound/core.h> 31 + #include <sound/pcm.h> 32 + #include <sound/pcm_params.h> 33 + #include <sound/soc.h> 34 + #include <sound/soc-dapm.h> 35 + #include <sound/initval.h> 36 + #include <sound/tlv.h> 37 + #include <sound/hda_verbs.h> 38 + 39 + #include "rt715.h" 40 + 41 + static int rt715_index_write(struct regmap *regmap, unsigned int reg, 42 + unsigned int value) 43 + { 44 + int ret; 45 + unsigned int addr = ((RT715_PRIV_INDEX_W_H) << 8) | reg; 46 + 47 + ret = regmap_write(regmap, addr, value); 48 + if (ret < 0) { 49 + pr_err("Failed to set private value: %08x <= %04x %d\n", ret, 50 + addr, value); 51 + } 52 + 53 + return ret; 54 + } 55 + 56 + static void rt715_get_gain(struct rt715_priv *rt715, unsigned int addr_h, 57 + unsigned int addr_l, unsigned int val_h, 58 + unsigned int *r_val, unsigned int *l_val) 59 + { 60 + int ret; 61 + /* R Channel */ 62 + *r_val = (val_h << 8); 63 + ret = regmap_read(rt715->regmap, addr_l, r_val); 64 + if (ret < 0) 65 + pr_err("Failed to get R channel gain.\n"); 66 + 67 + /* L Channel */ 68 + val_h |= 0x20; 69 + *l_val = (val_h << 8); 70 + ret = regmap_read(rt715->regmap, addr_h, l_val); 71 + if (ret < 0) 72 + pr_err("Failed to get L channel gain.\n"); 73 + } 74 + 75 + /* For Verb-Set Amplifier Gain (Verb ID = 3h) */ 76 + static int rt715_set_amp_gain_put(struct snd_kcontrol *kcontrol, 77 + struct snd_ctl_elem_value *ucontrol) 78 + { 79 + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); 80 + struct snd_soc_dapm_context *dapm = 81 + snd_soc_component_get_dapm(component); 82 + struct soc_mixer_control *mc = 83 + (struct soc_mixer_control *)kcontrol->private_value; 84 + struct rt715_priv *rt715 = snd_soc_component_get_drvdata(component); 85 + unsigned int addr_h, addr_l, val_h, val_ll, val_lr; 86 + unsigned int read_ll, read_rl; 87 + int i; 88 + 89 + /* Can't use update bit function, so read the original value first */ 90 + addr_h = mc->reg; 91 + addr_l = mc->rreg; 92 + if (mc->shift == RT715_DIR_OUT_SFT) /* output */ 93 + val_h = 0x80; 94 + else /* input */ 95 + val_h = 0x0; 96 + 97 + rt715_get_gain(rt715, addr_h, addr_l, val_h, &read_rl, &read_ll); 98 + 99 + /* L Channel */ 100 + if (mc->invert) { 101 + /* for mute */ 102 + val_ll = (mc->max - ucontrol->value.integer.value[0]) << 7; 103 + /* keep gain */ 104 + read_ll = read_ll & 0x7f; 105 + val_ll |= read_ll; 106 + } else { 107 + /* for gain */ 108 + val_ll = ((ucontrol->value.integer.value[0]) & 0x7f); 109 + if (val_ll > mc->max) 110 + val_ll = mc->max; 111 + /* keep mute status */ 112 + read_ll = read_ll & 0x80; 113 + val_ll |= read_ll; 114 + } 115 + 116 + /* R Channel */ 117 + if (mc->invert) { 118 + regmap_write(rt715->regmap, 119 + RT715_SET_AUDIO_POWER_STATE, AC_PWRST_D0); 120 + /* for mute */ 121 + val_lr = (mc->max - ucontrol->value.integer.value[1]) << 7; 122 + /* keep gain */ 123 + read_rl = read_rl & 0x7f; 124 + val_lr |= read_rl; 125 + } else { 126 + /* for gain */ 127 + val_lr = ((ucontrol->value.integer.value[1]) & 0x7f); 128 + if (val_lr > mc->max) 129 + val_lr = mc->max; 130 + /* keep mute status */ 131 + read_rl = read_rl & 0x80; 132 + val_lr |= read_rl; 133 + } 134 + 135 + for (i = 0; i < 3; i++) { /* retry 3 times at most */ 136 + 137 + if (val_ll == val_lr) { 138 + /* Set both L/R channels at the same time */ 139 + val_h = (1 << mc->shift) | (3 << 4); 140 + regmap_write(rt715->regmap, addr_h, 141 + (val_h << 8 | val_ll)); 142 + regmap_write(rt715->regmap, addr_l, 143 + (val_h << 8 | val_ll)); 144 + } else { 145 + /* Lch*/ 146 + val_h = (1 << mc->shift) | (1 << 5); 147 + regmap_write(rt715->regmap, addr_h, 148 + (val_h << 8 | val_ll)); 149 + /* Rch */ 150 + val_h = (1 << mc->shift) | (1 << 4); 151 + regmap_write(rt715->regmap, addr_l, 152 + (val_h << 8 | val_lr)); 153 + } 154 + /* check result */ 155 + if (mc->shift == RT715_DIR_OUT_SFT) /* output */ 156 + val_h = 0x80; 157 + else /* input */ 158 + val_h = 0x0; 159 + 160 + rt715_get_gain(rt715, addr_h, addr_l, val_h, 161 + &read_rl, &read_ll); 162 + if (read_rl == val_lr && read_ll == val_ll) 163 + break; 164 + } 165 + /* D0:power on state, D3: power saving mode */ 166 + if (dapm->bias_level <= SND_SOC_BIAS_STANDBY) 167 + regmap_write(rt715->regmap, 168 + RT715_SET_AUDIO_POWER_STATE, AC_PWRST_D3); 169 + return 0; 170 + } 171 + 172 + static int rt715_set_amp_gain_get(struct snd_kcontrol *kcontrol, 173 + struct snd_ctl_elem_value *ucontrol) 174 + { 175 + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); 176 + struct rt715_priv *rt715 = snd_soc_component_get_drvdata(component); 177 + struct soc_mixer_control *mc = 178 + (struct soc_mixer_control *)kcontrol->private_value; 179 + unsigned int addr_h, addr_l, val_h; 180 + unsigned int read_ll, read_rl; 181 + 182 + addr_h = mc->reg; 183 + addr_l = mc->rreg; 184 + if (mc->shift == RT715_DIR_OUT_SFT) /* output */ 185 + val_h = 0x80; 186 + else /* input */ 187 + val_h = 0x0; 188 + 189 + rt715_get_gain(rt715, addr_h, addr_l, val_h, &read_rl, &read_ll); 190 + 191 + if (mc->invert) { 192 + /* for mute status */ 193 + read_ll = !((read_ll & 0x80) >> RT715_MUTE_SFT); 194 + read_rl = !((read_rl & 0x80) >> RT715_MUTE_SFT); 195 + } else { 196 + /* for gain */ 197 + read_ll = read_ll & 0x7f; 198 + read_rl = read_rl & 0x7f; 199 + } 200 + ucontrol->value.integer.value[0] = read_ll; 201 + ucontrol->value.integer.value[1] = read_rl; 202 + 203 + return 0; 204 + } 205 + 206 + static const DECLARE_TLV_DB_SCALE(out_vol_tlv, -6525, 75, 0); 207 + static const DECLARE_TLV_DB_SCALE(in_vol_tlv, -1725, 75, 0); 208 + static const DECLARE_TLV_DB_SCALE(mic_vol_tlv, 0, 1000, 0); 209 + 210 + #define SOC_DOUBLE_R_EXT(xname, reg_left, reg_right, xshift, xmax, xinvert,\ 211 + xhandler_get, xhandler_put) \ 212 + { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \ 213 + .info = snd_soc_info_volsw, \ 214 + .get = xhandler_get, .put = xhandler_put, \ 215 + .private_value = SOC_DOUBLE_R_VALUE(reg_left, reg_right, xshift, \ 216 + xmax, xinvert) } 217 + 218 + static const struct snd_kcontrol_new rt715_snd_controls[] = { 219 + /* Capture switch */ 220 + SOC_DOUBLE_R_EXT("ADC 07 Capture Switch", RT715_SET_GAIN_MIC_ADC_H, 221 + RT715_SET_GAIN_MIC_ADC_L, RT715_DIR_IN_SFT, 1, 1, 222 + rt715_set_amp_gain_get, rt715_set_amp_gain_put), 223 + SOC_DOUBLE_R_EXT("ADC 08 Capture Switch", RT715_SET_GAIN_LINE_ADC_H, 224 + RT715_SET_GAIN_LINE_ADC_L, RT715_DIR_IN_SFT, 1, 1, 225 + rt715_set_amp_gain_get, rt715_set_amp_gain_put), 226 + SOC_DOUBLE_R_EXT("ADC 09 Capture Switch", RT715_SET_GAIN_MIX_ADC_H, 227 + RT715_SET_GAIN_MIX_ADC_L, RT715_DIR_IN_SFT, 1, 1, 228 + rt715_set_amp_gain_get, rt715_set_amp_gain_put), 229 + SOC_DOUBLE_R_EXT("ADC 27 Capture Switch", RT715_SET_GAIN_MIX_ADC2_H, 230 + RT715_SET_GAIN_MIX_ADC2_L, RT715_DIR_IN_SFT, 1, 1, 231 + rt715_set_amp_gain_get, rt715_set_amp_gain_put), 232 + /* Volume Control */ 233 + SOC_DOUBLE_R_EXT_TLV("ADC 07 Capture Volume", RT715_SET_GAIN_MIC_ADC_H, 234 + RT715_SET_GAIN_MIC_ADC_L, RT715_DIR_IN_SFT, 0x3f, 0, 235 + rt715_set_amp_gain_get, rt715_set_amp_gain_put, 236 + in_vol_tlv), 237 + SOC_DOUBLE_R_EXT_TLV("ADC 08 Capture Volume", RT715_SET_GAIN_LINE_ADC_H, 238 + RT715_SET_GAIN_LINE_ADC_L, RT715_DIR_IN_SFT, 0x3f, 0, 239 + rt715_set_amp_gain_get, rt715_set_amp_gain_put, 240 + in_vol_tlv), 241 + SOC_DOUBLE_R_EXT_TLV("ADC 09 Capture Volume", RT715_SET_GAIN_MIX_ADC_H, 242 + RT715_SET_GAIN_MIX_ADC_L, RT715_DIR_IN_SFT, 0x3f, 0, 243 + rt715_set_amp_gain_get, rt715_set_amp_gain_put, 244 + in_vol_tlv), 245 + SOC_DOUBLE_R_EXT_TLV("ADC 27 Capture Volume", RT715_SET_GAIN_MIX_ADC2_H, 246 + RT715_SET_GAIN_MIX_ADC2_L, RT715_DIR_IN_SFT, 0x3f, 0, 247 + rt715_set_amp_gain_get, rt715_set_amp_gain_put, 248 + in_vol_tlv), 249 + /* MIC Boost Control */ 250 + SOC_DOUBLE_R_EXT_TLV("DMIC1 Boost", RT715_SET_GAIN_DMIC1_H, 251 + RT715_SET_GAIN_DMIC1_L, RT715_DIR_IN_SFT, 3, 0, 252 + rt715_set_amp_gain_get, rt715_set_amp_gain_put, 253 + mic_vol_tlv), 254 + SOC_DOUBLE_R_EXT_TLV("DMIC2 Boost", RT715_SET_GAIN_DMIC2_H, 255 + RT715_SET_GAIN_DMIC2_L, RT715_DIR_IN_SFT, 3, 0, 256 + rt715_set_amp_gain_get, rt715_set_amp_gain_put, 257 + mic_vol_tlv), 258 + SOC_DOUBLE_R_EXT_TLV("DMIC3 Boost", RT715_SET_GAIN_DMIC3_H, 259 + RT715_SET_GAIN_DMIC3_L, RT715_DIR_IN_SFT, 3, 0, 260 + rt715_set_amp_gain_get, rt715_set_amp_gain_put, 261 + mic_vol_tlv), 262 + SOC_DOUBLE_R_EXT_TLV("DMIC4 Boost", RT715_SET_GAIN_DMIC4_H, 263 + RT715_SET_GAIN_DMIC4_L, RT715_DIR_IN_SFT, 3, 0, 264 + rt715_set_amp_gain_get, rt715_set_amp_gain_put, 265 + mic_vol_tlv), 266 + SOC_DOUBLE_R_EXT_TLV("MIC1 Boost", RT715_SET_GAIN_MIC1_H, 267 + RT715_SET_GAIN_MIC1_L, RT715_DIR_IN_SFT, 3, 0, 268 + rt715_set_amp_gain_get, rt715_set_amp_gain_put, 269 + mic_vol_tlv), 270 + SOC_DOUBLE_R_EXT_TLV("MIC2 Boost", RT715_SET_GAIN_MIC2_H, 271 + RT715_SET_GAIN_MIC2_L, RT715_DIR_IN_SFT, 3, 0, 272 + rt715_set_amp_gain_get, rt715_set_amp_gain_put, 273 + mic_vol_tlv), 274 + SOC_DOUBLE_R_EXT_TLV("LINE1 Boost", RT715_SET_GAIN_LINE1_H, 275 + RT715_SET_GAIN_LINE1_L, RT715_DIR_IN_SFT, 3, 0, 276 + rt715_set_amp_gain_get, rt715_set_amp_gain_put, 277 + mic_vol_tlv), 278 + SOC_DOUBLE_R_EXT_TLV("LINE2 Boost", RT715_SET_GAIN_LINE2_H, 279 + RT715_SET_GAIN_LINE2_L, RT715_DIR_IN_SFT, 3, 0, 280 + rt715_set_amp_gain_get, rt715_set_amp_gain_put, 281 + mic_vol_tlv), 282 + }; 283 + 284 + static int rt715_mux_get(struct snd_kcontrol *kcontrol, 285 + struct snd_ctl_elem_value *ucontrol) 286 + { 287 + struct snd_soc_component *component = 288 + snd_soc_dapm_kcontrol_component(kcontrol); 289 + struct rt715_priv *rt715 = snd_soc_component_get_drvdata(component); 290 + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 291 + unsigned int reg, val; 292 + int ret; 293 + 294 + /* nid = e->reg, vid = 0xf01 */ 295 + reg = RT715_VERB_SET_CONNECT_SEL | e->reg; 296 + ret = regmap_read(rt715->regmap, reg, &val); 297 + if (ret < 0) { 298 + dev_err(component->dev, "%s: sdw read failed: %d\n", 299 + __func__, ret); 300 + return ret; 301 + } 302 + 303 + /* 304 + * The first two indices of ADC Mux 24/25 are routed to the same 305 + * hardware source. ie, ADC Mux 24 0/1 will both connect to MIC2. 306 + * To have a unique set of inputs, we skip the index1 of the muxes. 307 + */ 308 + if ((e->reg == RT715_MUX_IN3 || e->reg == RT715_MUX_IN4) && (val > 0)) 309 + val -= 1; 310 + ucontrol->value.enumerated.item[0] = val; 311 + 312 + return 0; 313 + } 314 + 315 + static int rt715_mux_put(struct snd_kcontrol *kcontrol, 316 + struct snd_ctl_elem_value *ucontrol) 317 + { 318 + struct snd_soc_component *component = 319 + snd_soc_dapm_kcontrol_component(kcontrol); 320 + struct snd_soc_dapm_context *dapm = 321 + snd_soc_dapm_kcontrol_dapm(kcontrol); 322 + struct rt715_priv *rt715 = snd_soc_component_get_drvdata(component); 323 + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 324 + unsigned int *item = ucontrol->value.enumerated.item; 325 + unsigned int val, val2 = 0, change, reg; 326 + int ret; 327 + 328 + if (item[0] >= e->items) 329 + return -EINVAL; 330 + 331 + /* Verb ID = 0x701h, nid = e->reg */ 332 + val = snd_soc_enum_item_to_val(e, item[0]) << e->shift_l; 333 + 334 + reg = RT715_VERB_SET_CONNECT_SEL | e->reg; 335 + ret = regmap_read(rt715->regmap, reg, &val2); 336 + if (ret < 0) { 337 + dev_err(component->dev, "%s: sdw read failed: %d\n", 338 + __func__, ret); 339 + return ret; 340 + } 341 + 342 + if (val == val2) 343 + change = 0; 344 + else 345 + change = 1; 346 + 347 + if (change) { 348 + reg = RT715_VERB_SET_CONNECT_SEL | e->reg; 349 + regmap_write(rt715->regmap, reg, val); 350 + } 351 + 352 + snd_soc_dapm_mux_update_power(dapm, kcontrol, 353 + item[0], e, NULL); 354 + 355 + return change; 356 + } 357 + 358 + static const char * const adc_22_23_mux_text[] = { 359 + "MIC1", 360 + "MIC2", 361 + "LINE1", 362 + "LINE2", 363 + "DMIC1", 364 + "DMIC2", 365 + "DMIC3", 366 + "DMIC4", 367 + }; 368 + 369 + /** 370 + * Due to mux design for nid 24 (MUX_IN3)/25 (MUX_IN4), connection index 0 and 371 + * 1 will be connected to the same dmic source, therefore we skip index 1 to 372 + * avoid misunderstanding on usage of dapm routing. 373 + */ 374 + static const unsigned int rt715_adc_24_25_values[] = { 375 + 0, 376 + 2, 377 + 3, 378 + 4, 379 + 5, 380 + }; 381 + 382 + static const char * const adc_24_mux_text[] = { 383 + "MIC2", 384 + "DMIC1", 385 + "DMIC2", 386 + "DMIC3", 387 + "DMIC4", 388 + }; 389 + 390 + static const char * const adc_25_mux_text[] = { 391 + "MIC1", 392 + "DMIC1", 393 + "DMIC2", 394 + "DMIC3", 395 + "DMIC4", 396 + }; 397 + 398 + static SOC_ENUM_SINGLE_DECL( 399 + rt715_adc22_enum, RT715_MUX_IN1, 0, adc_22_23_mux_text); 400 + 401 + static SOC_ENUM_SINGLE_DECL( 402 + rt715_adc23_enum, RT715_MUX_IN2, 0, adc_22_23_mux_text); 403 + 404 + static SOC_VALUE_ENUM_SINGLE_DECL(rt715_adc24_enum, 405 + RT715_MUX_IN3, 0, 0xf, 406 + adc_24_mux_text, rt715_adc_24_25_values); 407 + static SOC_VALUE_ENUM_SINGLE_DECL(rt715_adc25_enum, 408 + RT715_MUX_IN4, 0, 0xf, 409 + adc_25_mux_text, rt715_adc_24_25_values); 410 + 411 + static const struct snd_kcontrol_new rt715_adc22_mux = 412 + SOC_DAPM_ENUM_EXT("ADC 22 Mux", rt715_adc22_enum, 413 + rt715_mux_get, rt715_mux_put); 414 + 415 + static const struct snd_kcontrol_new rt715_adc23_mux = 416 + SOC_DAPM_ENUM_EXT("ADC 23 Mux", rt715_adc23_enum, 417 + rt715_mux_get, rt715_mux_put); 418 + 419 + static const struct snd_kcontrol_new rt715_adc24_mux = 420 + SOC_DAPM_ENUM_EXT("ADC 24 Mux", rt715_adc24_enum, 421 + rt715_mux_get, rt715_mux_put); 422 + 423 + static const struct snd_kcontrol_new rt715_adc25_mux = 424 + SOC_DAPM_ENUM_EXT("ADC 25 Mux", rt715_adc25_enum, 425 + rt715_mux_get, rt715_mux_put); 426 + 427 + static const struct snd_soc_dapm_widget rt715_dapm_widgets[] = { 428 + SND_SOC_DAPM_INPUT("DMIC1"), 429 + SND_SOC_DAPM_INPUT("DMIC2"), 430 + SND_SOC_DAPM_INPUT("DMIC3"), 431 + SND_SOC_DAPM_INPUT("DMIC4"), 432 + SND_SOC_DAPM_INPUT("MIC1"), 433 + SND_SOC_DAPM_INPUT("MIC2"), 434 + SND_SOC_DAPM_INPUT("LINE1"), 435 + SND_SOC_DAPM_INPUT("LINE2"), 436 + SND_SOC_DAPM_ADC("ADC 07", NULL, RT715_SET_STREAMID_MIC_ADC, 4, 0), 437 + SND_SOC_DAPM_ADC("ADC 08", NULL, RT715_SET_STREAMID_LINE_ADC, 4, 0), 438 + SND_SOC_DAPM_ADC("ADC 09", NULL, RT715_SET_STREAMID_MIX_ADC, 4, 0), 439 + SND_SOC_DAPM_ADC("ADC 27", NULL, RT715_SET_STREAMID_MIX_ADC2, 4, 0), 440 + SND_SOC_DAPM_MUX("ADC 22 Mux", SND_SOC_NOPM, 0, 0, 441 + &rt715_adc22_mux), 442 + SND_SOC_DAPM_MUX("ADC 23 Mux", SND_SOC_NOPM, 0, 0, 443 + &rt715_adc23_mux), 444 + SND_SOC_DAPM_MUX("ADC 24 Mux", SND_SOC_NOPM, 0, 0, 445 + &rt715_adc24_mux), 446 + SND_SOC_DAPM_MUX("ADC 25 Mux", SND_SOC_NOPM, 0, 0, 447 + &rt715_adc25_mux), 448 + SND_SOC_DAPM_AIF_OUT("DP4TX", "DP4 Capture", 0, SND_SOC_NOPM, 0, 0), 449 + SND_SOC_DAPM_AIF_OUT("DP6TX", "DP6 Capture", 0, SND_SOC_NOPM, 0, 0), 450 + }; 451 + 452 + static const struct snd_soc_dapm_route rt715_audio_map[] = { 453 + {"DP6TX", NULL, "ADC 09"}, 454 + {"DP6TX", NULL, "ADC 08"}, 455 + {"DP4TX", NULL, "ADC 07"}, 456 + {"DP4TX", NULL, "ADC 27"}, 457 + {"ADC 09", NULL, "ADC 22 Mux"}, 458 + {"ADC 08", NULL, "ADC 23 Mux"}, 459 + {"ADC 07", NULL, "ADC 24 Mux"}, 460 + {"ADC 27", NULL, "ADC 25 Mux"}, 461 + {"ADC 22 Mux", "MIC1", "MIC1"}, 462 + {"ADC 22 Mux", "MIC2", "MIC2"}, 463 + {"ADC 22 Mux", "LINE1", "LINE1"}, 464 + {"ADC 22 Mux", "LINE2", "LINE2"}, 465 + {"ADC 22 Mux", "DMIC1", "DMIC1"}, 466 + {"ADC 22 Mux", "DMIC2", "DMIC2"}, 467 + {"ADC 22 Mux", "DMIC3", "DMIC3"}, 468 + {"ADC 22 Mux", "DMIC4", "DMIC4"}, 469 + {"ADC 23 Mux", "MIC1", "MIC1"}, 470 + {"ADC 23 Mux", "MIC2", "MIC2"}, 471 + {"ADC 23 Mux", "LINE1", "LINE1"}, 472 + {"ADC 23 Mux", "LINE2", "LINE2"}, 473 + {"ADC 23 Mux", "DMIC1", "DMIC1"}, 474 + {"ADC 23 Mux", "DMIC2", "DMIC2"}, 475 + {"ADC 23 Mux", "DMIC3", "DMIC3"}, 476 + {"ADC 23 Mux", "DMIC4", "DMIC4"}, 477 + {"ADC 24 Mux", "MIC2", "MIC2"}, 478 + {"ADC 24 Mux", "DMIC1", "DMIC1"}, 479 + {"ADC 24 Mux", "DMIC2", "DMIC2"}, 480 + {"ADC 24 Mux", "DMIC3", "DMIC3"}, 481 + {"ADC 24 Mux", "DMIC4", "DMIC4"}, 482 + {"ADC 25 Mux", "MIC1", "MIC1"}, 483 + {"ADC 25 Mux", "DMIC1", "DMIC1"}, 484 + {"ADC 25 Mux", "DMIC2", "DMIC2"}, 485 + {"ADC 25 Mux", "DMIC3", "DMIC3"}, 486 + {"ADC 25 Mux", "DMIC4", "DMIC4"}, 487 + }; 488 + 489 + static int rt715_set_bias_level(struct snd_soc_component *component, 490 + enum snd_soc_bias_level level) 491 + { 492 + struct snd_soc_dapm_context *dapm = 493 + snd_soc_component_get_dapm(component); 494 + struct rt715_priv *rt715 = snd_soc_component_get_drvdata(component); 495 + 496 + switch (level) { 497 + case SND_SOC_BIAS_PREPARE: 498 + if (dapm->bias_level == SND_SOC_BIAS_STANDBY) { 499 + regmap_write(rt715->regmap, 500 + RT715_SET_AUDIO_POWER_STATE, 501 + AC_PWRST_D0); 502 + } 503 + break; 504 + 505 + case SND_SOC_BIAS_STANDBY: 506 + regmap_write(rt715->regmap, 507 + RT715_SET_AUDIO_POWER_STATE, 508 + AC_PWRST_D3); 509 + break; 510 + 511 + default: 512 + break; 513 + } 514 + dapm->bias_level = level; 515 + return 0; 516 + } 517 + 518 + static const struct snd_soc_component_driver soc_codec_dev_rt715 = { 519 + .set_bias_level = rt715_set_bias_level, 520 + .controls = rt715_snd_controls, 521 + .num_controls = ARRAY_SIZE(rt715_snd_controls), 522 + .dapm_widgets = rt715_dapm_widgets, 523 + .num_dapm_widgets = ARRAY_SIZE(rt715_dapm_widgets), 524 + .dapm_routes = rt715_audio_map, 525 + .num_dapm_routes = ARRAY_SIZE(rt715_audio_map), 526 + }; 527 + 528 + static int rt715_set_sdw_stream(struct snd_soc_dai *dai, void *sdw_stream, 529 + int direction) 530 + { 531 + 532 + struct sdw_stream_data *stream; 533 + 534 + stream = kzalloc(sizeof(*stream), GFP_KERNEL); 535 + if (!stream) 536 + return -ENOMEM; 537 + 538 + stream->sdw_stream = (struct sdw_stream_runtime *)sdw_stream; 539 + 540 + /* Use tx_mask or rx_mask to configure stream tag and set dma_data */ 541 + if (direction == SNDRV_PCM_STREAM_PLAYBACK) 542 + dai->playback_dma_data = stream; 543 + else 544 + dai->capture_dma_data = stream; 545 + 546 + return 0; 547 + } 548 + 549 + static void rt715_shutdown(struct snd_pcm_substream *substream, 550 + struct snd_soc_dai *dai) 551 + 552 + { 553 + struct sdw_stream_data *stream; 554 + 555 + stream = snd_soc_dai_get_dma_data(dai, substream); 556 + snd_soc_dai_set_dma_data(dai, substream, NULL); 557 + kfree(stream); 558 + } 559 + 560 + static int rt715_pcm_hw_params(struct snd_pcm_substream *substream, 561 + struct snd_pcm_hw_params *params, 562 + struct snd_soc_dai *dai) 563 + { 564 + struct snd_soc_component *component = dai->component; 565 + struct rt715_priv *rt715 = snd_soc_component_get_drvdata(component); 566 + struct sdw_stream_config stream_config; 567 + struct sdw_port_config port_config; 568 + enum sdw_data_direction direction; 569 + struct sdw_stream_data *stream; 570 + int retval, port, num_channels; 571 + unsigned int val = 0; 572 + 573 + stream = snd_soc_dai_get_dma_data(dai, substream); 574 + 575 + if (!stream) 576 + return -EINVAL; 577 + 578 + if (!rt715->slave) 579 + return -EINVAL; 580 + 581 + switch (dai->id) { 582 + case RT715_AIF1: 583 + direction = SDW_DATA_DIR_TX; 584 + port = 6; 585 + rt715_index_write(rt715->regmap, RT715_SDW_INPUT_SEL, 0xa500); 586 + break; 587 + case RT715_AIF2: 588 + direction = SDW_DATA_DIR_TX; 589 + port = 4; 590 + rt715_index_write(rt715->regmap, RT715_SDW_INPUT_SEL, 0xa000); 591 + break; 592 + default: 593 + dev_err(component->dev, "Invalid DAI id %d\n", dai->id); 594 + return -EINVAL; 595 + } 596 + 597 + stream_config.frame_rate = params_rate(params); 598 + stream_config.ch_count = params_channels(params); 599 + stream_config.bps = snd_pcm_format_width(params_format(params)); 600 + stream_config.direction = direction; 601 + 602 + num_channels = params_channels(params); 603 + port_config.ch_mask = (1 << (num_channels)) - 1; 604 + port_config.num = port; 605 + 606 + retval = sdw_stream_add_slave(rt715->slave, &stream_config, 607 + &port_config, 1, stream->sdw_stream); 608 + if (retval) { 609 + dev_err(dai->dev, "Unable to configure port\n"); 610 + return retval; 611 + } 612 + 613 + switch (params_rate(params)) { 614 + /* bit 14 0:48K 1:44.1K */ 615 + /* bit 15 Stream Type 0:PCM 1:Non-PCM, should always be PCM */ 616 + case 44100: 617 + val |= 0x40 << 8; 618 + break; 619 + case 48000: 620 + val |= 0x0 << 8; 621 + break; 622 + default: 623 + dev_err(component->dev, "Unsupported sample rate %d\n", 624 + params_rate(params)); 625 + return -EINVAL; 626 + } 627 + 628 + if (params_channels(params) <= 16) { 629 + /* bit 3:0 Number of Channel */ 630 + val |= (params_channels(params) - 1); 631 + } else { 632 + dev_err(component->dev, "Unsupported channels %d\n", 633 + params_channels(params)); 634 + return -EINVAL; 635 + } 636 + 637 + switch (params_width(params)) { 638 + /* bit 6:4 Bits per Sample */ 639 + case 8: 640 + break; 641 + case 16: 642 + val |= (0x1 << 4); 643 + break; 644 + case 20: 645 + val |= (0x2 << 4); 646 + break; 647 + case 24: 648 + val |= (0x3 << 4); 649 + break; 650 + case 32: 651 + val |= (0x4 << 4); 652 + break; 653 + default: 654 + return -EINVAL; 655 + } 656 + 657 + regmap_write(rt715->regmap, RT715_MIC_ADC_FORMAT_H, val); 658 + regmap_write(rt715->regmap, RT715_MIC_LINE_FORMAT_H, val); 659 + regmap_write(rt715->regmap, RT715_MIX_ADC_FORMAT_H, val); 660 + regmap_write(rt715->regmap, RT715_MIX_ADC2_FORMAT_H, val); 661 + 662 + return retval; 663 + } 664 + 665 + static int rt715_pcm_hw_free(struct snd_pcm_substream *substream, 666 + struct snd_soc_dai *dai) 667 + { 668 + struct snd_soc_component *component = dai->component; 669 + struct rt715_priv *rt715 = snd_soc_component_get_drvdata(component); 670 + struct sdw_stream_data *stream = 671 + snd_soc_dai_get_dma_data(dai, substream); 672 + 673 + if (!rt715->slave) 674 + return -EINVAL; 675 + 676 + sdw_stream_remove_slave(rt715->slave, stream->sdw_stream); 677 + return 0; 678 + } 679 + 680 + #define RT715_STEREO_RATES (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000) 681 + #define RT715_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \ 682 + SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S8) 683 + 684 + static struct snd_soc_dai_ops rt715_ops = { 685 + .hw_params = rt715_pcm_hw_params, 686 + .hw_free = rt715_pcm_hw_free, 687 + .set_sdw_stream = rt715_set_sdw_stream, 688 + .shutdown = rt715_shutdown, 689 + }; 690 + 691 + static struct snd_soc_dai_driver rt715_dai[] = { 692 + { 693 + .name = "rt715-aif1", 694 + .id = RT715_AIF1, 695 + .capture = { 696 + .stream_name = "DP6 Capture", 697 + .channels_min = 1, 698 + .channels_max = 2, 699 + .rates = RT715_STEREO_RATES, 700 + .formats = RT715_FORMATS, 701 + }, 702 + .ops = &rt715_ops, 703 + }, 704 + { 705 + .name = "rt715-aif2", 706 + .id = RT715_AIF2, 707 + .capture = { 708 + .stream_name = "DP4 Capture", 709 + .channels_min = 1, 710 + .channels_max = 2, 711 + .rates = RT715_STEREO_RATES, 712 + .formats = RT715_FORMATS, 713 + }, 714 + .ops = &rt715_ops, 715 + }, 716 + }; 717 + 718 + /* Bus clock frequency */ 719 + #define RT715_CLK_FREQ_9600000HZ 9600000 720 + #define RT715_CLK_FREQ_12000000HZ 12000000 721 + #define RT715_CLK_FREQ_6000000HZ 6000000 722 + #define RT715_CLK_FREQ_4800000HZ 4800000 723 + #define RT715_CLK_FREQ_2400000HZ 2400000 724 + #define RT715_CLK_FREQ_12288000HZ 12288000 725 + 726 + int rt715_clock_config(struct device *dev) 727 + { 728 + struct rt715_priv *rt715 = dev_get_drvdata(dev); 729 + unsigned int clk_freq, value; 730 + 731 + clk_freq = (rt715->params.curr_dr_freq >> 1); 732 + 733 + switch (clk_freq) { 734 + case RT715_CLK_FREQ_12000000HZ: 735 + value = 0x0; 736 + break; 737 + case RT715_CLK_FREQ_6000000HZ: 738 + value = 0x1; 739 + break; 740 + case RT715_CLK_FREQ_9600000HZ: 741 + value = 0x2; 742 + break; 743 + case RT715_CLK_FREQ_4800000HZ: 744 + value = 0x3; 745 + break; 746 + case RT715_CLK_FREQ_2400000HZ: 747 + value = 0x4; 748 + break; 749 + case RT715_CLK_FREQ_12288000HZ: 750 + value = 0x5; 751 + break; 752 + default: 753 + return -EINVAL; 754 + } 755 + 756 + regmap_write(rt715->regmap, 0xe0, value); 757 + regmap_write(rt715->regmap, 0xf0, value); 758 + 759 + return 0; 760 + } 761 + 762 + int rt715_init(struct device *dev, struct regmap *sdw_regmap, 763 + struct regmap *regmap, struct sdw_slave *slave) 764 + { 765 + struct rt715_priv *rt715; 766 + int ret; 767 + 768 + rt715 = devm_kzalloc(dev, sizeof(*rt715), GFP_KERNEL); 769 + if (!rt715) 770 + return -ENOMEM; 771 + 772 + dev_set_drvdata(dev, rt715); 773 + rt715->slave = slave; 774 + rt715->regmap = regmap; 775 + rt715->sdw_regmap = sdw_regmap; 776 + 777 + /* 778 + * Mark hw_init to false 779 + * HW init will be performed when device reports present 780 + */ 781 + rt715->hw_init = false; 782 + rt715->first_hw_init = false; 783 + 784 + ret = devm_snd_soc_register_component(dev, 785 + &soc_codec_dev_rt715, 786 + rt715_dai, 787 + ARRAY_SIZE(rt715_dai)); 788 + 789 + return ret; 790 + } 791 + 792 + int rt715_io_init(struct device *dev, struct sdw_slave *slave) 793 + { 794 + struct rt715_priv *rt715 = dev_get_drvdata(dev); 795 + 796 + if (rt715->hw_init) 797 + return 0; 798 + 799 + /* 800 + * PM runtime is only enabled when a Slave reports as Attached 801 + */ 802 + if (!rt715->first_hw_init) { 803 + /* set autosuspend parameters */ 804 + pm_runtime_set_autosuspend_delay(&slave->dev, 3000); 805 + pm_runtime_use_autosuspend(&slave->dev); 806 + 807 + /* update count of parent 'active' children */ 808 + pm_runtime_set_active(&slave->dev); 809 + 810 + /* make sure the device does not suspend immediately */ 811 + pm_runtime_mark_last_busy(&slave->dev); 812 + 813 + pm_runtime_enable(&slave->dev); 814 + } 815 + 816 + pm_runtime_get_noresume(&slave->dev); 817 + 818 + /* Mute nid=08h/09h */ 819 + regmap_write(rt715->regmap, RT715_SET_GAIN_LINE_ADC_H, 0xb080); 820 + regmap_write(rt715->regmap, RT715_SET_GAIN_MIX_ADC_H, 0xb080); 821 + /* Mute nid=07h/27h */ 822 + regmap_write(rt715->regmap, RT715_SET_GAIN_MIC_ADC_H, 0xb080); 823 + regmap_write(rt715->regmap, RT715_SET_GAIN_MIX_ADC2_H, 0xb080); 824 + 825 + /* Set Pin Widget */ 826 + regmap_write(rt715->regmap, RT715_SET_PIN_DMIC1, 0x20); 827 + regmap_write(rt715->regmap, RT715_SET_PIN_DMIC2, 0x20); 828 + regmap_write(rt715->regmap, RT715_SET_PIN_DMIC3, 0x20); 829 + regmap_write(rt715->regmap, RT715_SET_PIN_DMIC4, 0x20); 830 + /* Set Converter Stream */ 831 + regmap_write(rt715->regmap, RT715_SET_STREAMID_LINE_ADC, 0x10); 832 + regmap_write(rt715->regmap, RT715_SET_STREAMID_MIX_ADC, 0x10); 833 + regmap_write(rt715->regmap, RT715_SET_STREAMID_MIC_ADC, 0x10); 834 + regmap_write(rt715->regmap, RT715_SET_STREAMID_MIX_ADC2, 0x10); 835 + /* Set Configuration Default */ 836 + regmap_write(rt715->regmap, RT715_SET_DMIC1_CONFIG_DEFAULT1, 0xd0); 837 + regmap_write(rt715->regmap, RT715_SET_DMIC1_CONFIG_DEFAULT2, 0x11); 838 + regmap_write(rt715->regmap, RT715_SET_DMIC1_CONFIG_DEFAULT3, 0xa1); 839 + regmap_write(rt715->regmap, RT715_SET_DMIC1_CONFIG_DEFAULT4, 0x81); 840 + regmap_write(rt715->regmap, RT715_SET_DMIC2_CONFIG_DEFAULT1, 0xd1); 841 + regmap_write(rt715->regmap, RT715_SET_DMIC2_CONFIG_DEFAULT2, 0x11); 842 + regmap_write(rt715->regmap, RT715_SET_DMIC2_CONFIG_DEFAULT3, 0xa1); 843 + regmap_write(rt715->regmap, RT715_SET_DMIC2_CONFIG_DEFAULT4, 0x81); 844 + regmap_write(rt715->regmap, RT715_SET_DMIC3_CONFIG_DEFAULT1, 0xd0); 845 + regmap_write(rt715->regmap, RT715_SET_DMIC3_CONFIG_DEFAULT2, 0x11); 846 + regmap_write(rt715->regmap, RT715_SET_DMIC3_CONFIG_DEFAULT3, 0xa1); 847 + regmap_write(rt715->regmap, RT715_SET_DMIC3_CONFIG_DEFAULT4, 0x81); 848 + regmap_write(rt715->regmap, RT715_SET_DMIC4_CONFIG_DEFAULT1, 0xd1); 849 + regmap_write(rt715->regmap, RT715_SET_DMIC4_CONFIG_DEFAULT2, 0x11); 850 + regmap_write(rt715->regmap, RT715_SET_DMIC4_CONFIG_DEFAULT3, 0xa1); 851 + regmap_write(rt715->regmap, RT715_SET_DMIC4_CONFIG_DEFAULT4, 0x81); 852 + 853 + /* Finish Initial Settings, set power to D3 */ 854 + regmap_write(rt715->regmap, RT715_SET_AUDIO_POWER_STATE, AC_PWRST_D3); 855 + 856 + if (rt715->first_hw_init) 857 + regcache_mark_dirty(rt715->regmap); 858 + else 859 + rt715->first_hw_init = true; 860 + 861 + /* Mark Slave initialization complete */ 862 + rt715->hw_init = true; 863 + 864 + pm_runtime_mark_last_busy(&slave->dev); 865 + pm_runtime_put_autosuspend(&slave->dev); 866 + 867 + return 0; 868 + } 869 + 870 + MODULE_DESCRIPTION("ASoC rt715 driver"); 871 + MODULE_DESCRIPTION("ASoC rt715 driver SDW"); 872 + MODULE_AUTHOR("Jack Yu <jack.yu@realtek.com>"); 873 + MODULE_LICENSE("GPL v2");
+221
sound/soc/codecs/rt715.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + /* 3 + * rt715.h -- RT715 ALSA SoC audio driver header 4 + * 5 + * Copyright(c) 2019 Realtek Semiconductor Corp. 6 + */ 7 + 8 + #ifndef __RT715_H__ 9 + #define __RT715_H__ 10 + 11 + #include <linux/regulator/consumer.h> 12 + 13 + struct rt715_priv { 14 + struct regmap *regmap; 15 + struct regmap *sdw_regmap; 16 + struct snd_soc_codec *codec; 17 + struct sdw_slave *slave; 18 + int dbg_nid; 19 + int dbg_vid; 20 + int dbg_payload; 21 + enum sdw_slave_status status; 22 + struct sdw_bus_params params; 23 + bool hw_init; 24 + bool first_hw_init; 25 + }; 26 + 27 + struct sdw_stream_data { 28 + struct sdw_stream_runtime *sdw_stream; 29 + }; 30 + 31 + /* NID */ 32 + #define RT715_AUDIO_FUNCTION_GROUP 0x01 33 + #define RT715_MIC_ADC 0x07 34 + #define RT715_LINE_ADC 0x08 35 + #define RT715_MIX_ADC 0x09 36 + #define RT715_DMIC1 0x12 37 + #define RT715_DMIC2 0x13 38 + #define RT715_MIC1 0x18 39 + #define RT715_MIC2 0x19 40 + #define RT715_LINE1 0x1a 41 + #define RT715_LINE2 0x1b 42 + #define RT715_DMIC3 0x1d 43 + #define RT715_DMIC4 0x29 44 + #define RT715_VENDOR_REGISTERS 0x20 45 + #define RT715_MUX_IN1 0x22 46 + #define RT715_MUX_IN2 0x23 47 + #define RT715_MUX_IN3 0x24 48 + #define RT715_MUX_IN4 0x25 49 + #define RT715_MIX_ADC2 0x27 50 + #define RT715_INLINE_CMD 0x55 51 + 52 + /* Index (NID:20h) */ 53 + #define RT715_SDW_INPUT_SEL 0x39 54 + #define RT715_EXT_DMIC_CLK_CTRL2 0x54 55 + 56 + /* Verb */ 57 + #define RT715_VERB_SET_CONNECT_SEL 0x3100 58 + #define RT715_VERB_GET_CONNECT_SEL 0xb100 59 + #define RT715_VERB_SET_EAPD_BTLENABLE 0x3c00 60 + #define RT715_VERB_SET_POWER_STATE 0x3500 61 + #define RT715_VERB_SET_CHANNEL_STREAMID 0x3600 62 + #define RT715_VERB_SET_PIN_WIDGET_CONTROL 0x3700 63 + #define RT715_VERB_SET_CONFIG_DEFAULT1 0x4c00 64 + #define RT715_VERB_SET_CONFIG_DEFAULT2 0x4d00 65 + #define RT715_VERB_SET_CONFIG_DEFAULT3 0x4e00 66 + #define RT715_VERB_SET_CONFIG_DEFAULT4 0x4f00 67 + #define RT715_VERB_SET_UNSOLICITED_ENABLE 0x3800 68 + #define RT715_SET_AMP_GAIN_MUTE_H 0x7300 69 + #define RT715_SET_AMP_GAIN_MUTE_L 0x8380 70 + #define RT715_READ_HDA_3 0x2012 71 + #define RT715_READ_HDA_2 0x2013 72 + #define RT715_READ_HDA_1 0x2014 73 + #define RT715_READ_HDA_0 0x2015 74 + #define RT715_PRIV_INDEX_W_H 0x7520 75 + #define RT715_PRIV_INDEX_W_L 0x85a0 76 + #define RT715_PRIV_DATA_W_H 0x7420 77 + #define RT715_PRIV_DATA_W_L 0x84a0 78 + #define RT715_PRIV_INDEX_R_H 0x9d20 79 + #define RT715_PRIV_INDEX_R_L 0xada0 80 + #define RT715_PRIV_DATA_R_H 0x9c20 81 + #define RT715_PRIV_DATA_R_L 0xaca0 82 + #define RT715_MIC_ADC_FORMAT_H 0x7207 83 + #define RT715_MIC_ADC_FORMAT_L 0x8287 84 + #define RT715_MIC_LINE_FORMAT_H 0x7208 85 + #define RT715_MIC_LINE_FORMAT_L 0x8288 86 + #define RT715_MIX_ADC_FORMAT_H 0x7209 87 + #define RT715_MIX_ADC_FORMAT_L 0x8289 88 + #define RT715_MIX_ADC2_FORMAT_H 0x7227 89 + #define RT715_MIX_ADC2_FORMAT_L 0x82a7 90 + #define RT715_FUNC_RESET 0xff01 91 + 92 + #define RT715_SET_AUDIO_POWER_STATE\ 93 + (RT715_VERB_SET_POWER_STATE | RT715_AUDIO_FUNCTION_GROUP) 94 + #define RT715_SET_PIN_DMIC1\ 95 + (RT715_VERB_SET_PIN_WIDGET_CONTROL | RT715_DMIC1) 96 + #define RT715_SET_PIN_DMIC2\ 97 + (RT715_VERB_SET_PIN_WIDGET_CONTROL | RT715_DMIC2) 98 + #define RT715_SET_PIN_DMIC3\ 99 + (RT715_VERB_SET_PIN_WIDGET_CONTROL | RT715_DMIC3) 100 + #define RT715_SET_PIN_DMIC4\ 101 + (RT715_VERB_SET_PIN_WIDGET_CONTROL | RT715_DMIC4) 102 + #define RT715_SET_PIN_MIC1\ 103 + (RT715_VERB_SET_PIN_WIDGET_CONTROL | RT715_MIC1) 104 + #define RT715_SET_PIN_MIC2\ 105 + (RT715_VERB_SET_PIN_WIDGET_CONTROL | RT715_MIC2) 106 + #define RT715_SET_PIN_LINE1\ 107 + (RT715_VERB_SET_PIN_WIDGET_CONTROL | RT715_LINE1) 108 + #define RT715_SET_PIN_LINE2\ 109 + (RT715_VERB_SET_PIN_WIDGET_CONTROL | RT715_LINE2) 110 + #define RT715_SET_MIC1_UNSOLICITED_ENABLE\ 111 + (RT715_VERB_SET_UNSOLICITED_ENABLE | RT715_MIC1) 112 + #define RT715_SET_MIC2_UNSOLICITED_ENABLE\ 113 + (RT715_VERB_SET_UNSOLICITED_ENABLE | RT715_MIC2) 114 + #define RT715_SET_STREAMID_MIC_ADC\ 115 + (RT715_VERB_SET_CHANNEL_STREAMID | RT715_MIC_ADC) 116 + #define RT715_SET_STREAMID_LINE_ADC\ 117 + (RT715_VERB_SET_CHANNEL_STREAMID | RT715_LINE_ADC) 118 + #define RT715_SET_STREAMID_MIX_ADC\ 119 + (RT715_VERB_SET_CHANNEL_STREAMID | RT715_MIX_ADC) 120 + #define RT715_SET_STREAMID_MIX_ADC2\ 121 + (RT715_VERB_SET_CHANNEL_STREAMID | RT715_MIX_ADC2) 122 + #define RT715_SET_GAIN_MIC_ADC_L\ 123 + (RT715_SET_AMP_GAIN_MUTE_L | RT715_MIC_ADC) 124 + #define RT715_SET_GAIN_MIC_ADC_H\ 125 + (RT715_SET_AMP_GAIN_MUTE_H | RT715_MIC_ADC) 126 + #define RT715_SET_GAIN_LINE_ADC_L\ 127 + (RT715_SET_AMP_GAIN_MUTE_L | RT715_LINE_ADC) 128 + #define RT715_SET_GAIN_LINE_ADC_H\ 129 + (RT715_SET_AMP_GAIN_MUTE_H | RT715_LINE_ADC) 130 + #define RT715_SET_GAIN_MIX_ADC_L\ 131 + (RT715_SET_AMP_GAIN_MUTE_L | RT715_MIX_ADC) 132 + #define RT715_SET_GAIN_MIX_ADC_H\ 133 + (RT715_SET_AMP_GAIN_MUTE_H | RT715_MIX_ADC) 134 + #define RT715_SET_GAIN_MIX_ADC2_L\ 135 + (RT715_SET_AMP_GAIN_MUTE_L | RT715_MIX_ADC2) 136 + #define RT715_SET_GAIN_MIX_ADC2_H\ 137 + (RT715_SET_AMP_GAIN_MUTE_H | RT715_MIX_ADC2) 138 + #define RT715_SET_GAIN_DMIC1_L\ 139 + (RT715_SET_AMP_GAIN_MUTE_L | RT715_DMIC1) 140 + #define RT715_SET_GAIN_DMIC1_H\ 141 + (RT715_SET_AMP_GAIN_MUTE_H | RT715_DMIC1) 142 + #define RT715_SET_GAIN_DMIC2_L\ 143 + (RT715_SET_AMP_GAIN_MUTE_L | RT715_DMIC2) 144 + #define RT715_SET_GAIN_DMIC2_H\ 145 + (RT715_SET_AMP_GAIN_MUTE_H | RT715_DMIC2) 146 + #define RT715_SET_GAIN_DMIC3_L\ 147 + (RT715_SET_AMP_GAIN_MUTE_L | RT715_DMIC3) 148 + #define RT715_SET_GAIN_DMIC3_H\ 149 + (RT715_SET_AMP_GAIN_MUTE_H | RT715_DMIC3) 150 + #define RT715_SET_GAIN_DMIC4_L\ 151 + (RT715_SET_AMP_GAIN_MUTE_L | RT715_DMIC4) 152 + #define RT715_SET_GAIN_DMIC4_H\ 153 + (RT715_SET_AMP_GAIN_MUTE_H | RT715_DMIC4) 154 + #define RT715_SET_GAIN_MIC1_L\ 155 + (RT715_SET_AMP_GAIN_MUTE_L | RT715_MIC1) 156 + #define RT715_SET_GAIN_MIC1_H\ 157 + (RT715_SET_AMP_GAIN_MUTE_H | RT715_MIC1) 158 + #define RT715_SET_GAIN_MIC2_L\ 159 + (RT715_SET_AMP_GAIN_MUTE_L | RT715_MIC2) 160 + #define RT715_SET_GAIN_MIC2_H\ 161 + (RT715_SET_AMP_GAIN_MUTE_H | RT715_MIC2) 162 + #define RT715_SET_GAIN_LINE1_L\ 163 + (RT715_SET_AMP_GAIN_MUTE_L | RT715_LINE1) 164 + #define RT715_SET_GAIN_LINE1_H\ 165 + (RT715_SET_AMP_GAIN_MUTE_H | RT715_LINE1) 166 + #define RT715_SET_GAIN_LINE2_L\ 167 + (RT715_SET_AMP_GAIN_MUTE_L | RT715_LINE2) 168 + #define RT715_SET_GAIN_LINE2_H\ 169 + (RT715_SET_AMP_GAIN_MUTE_H | RT715_LINE2) 170 + #define RT715_SET_DMIC1_CONFIG_DEFAULT1\ 171 + (RT715_VERB_SET_CONFIG_DEFAULT1 | RT715_DMIC1) 172 + #define RT715_SET_DMIC2_CONFIG_DEFAULT1\ 173 + (RT715_VERB_SET_CONFIG_DEFAULT1 | RT715_DMIC2) 174 + #define RT715_SET_DMIC1_CONFIG_DEFAULT2\ 175 + (RT715_VERB_SET_CONFIG_DEFAULT2 | RT715_DMIC1) 176 + #define RT715_SET_DMIC2_CONFIG_DEFAULT2\ 177 + (RT715_VERB_SET_CONFIG_DEFAULT2 | RT715_DMIC2) 178 + #define RT715_SET_DMIC1_CONFIG_DEFAULT3\ 179 + (RT715_VERB_SET_CONFIG_DEFAULT3 | RT715_DMIC1) 180 + #define RT715_SET_DMIC2_CONFIG_DEFAULT3\ 181 + (RT715_VERB_SET_CONFIG_DEFAULT3 | RT715_DMIC2) 182 + #define RT715_SET_DMIC1_CONFIG_DEFAULT4\ 183 + (RT715_VERB_SET_CONFIG_DEFAULT4 | RT715_DMIC1) 184 + #define RT715_SET_DMIC2_CONFIG_DEFAULT4\ 185 + (RT715_VERB_SET_CONFIG_DEFAULT4 | RT715_DMIC2) 186 + #define RT715_SET_DMIC3_CONFIG_DEFAULT1\ 187 + (RT715_VERB_SET_CONFIG_DEFAULT1 | RT715_DMIC3) 188 + #define RT715_SET_DMIC4_CONFIG_DEFAULT1\ 189 + (RT715_VERB_SET_CONFIG_DEFAULT1 | RT715_DMIC4) 190 + #define RT715_SET_DMIC3_CONFIG_DEFAULT2\ 191 + (RT715_VERB_SET_CONFIG_DEFAULT2 | RT715_DMIC3) 192 + #define RT715_SET_DMIC4_CONFIG_DEFAULT2\ 193 + (RT715_VERB_SET_CONFIG_DEFAULT2 | RT715_DMIC4) 194 + #define RT715_SET_DMIC3_CONFIG_DEFAULT3\ 195 + (RT715_VERB_SET_CONFIG_DEFAULT3 | RT715_DMIC3) 196 + #define RT715_SET_DMIC4_CONFIG_DEFAULT3\ 197 + (RT715_VERB_SET_CONFIG_DEFAULT3 | RT715_DMIC4) 198 + #define RT715_SET_DMIC3_CONFIG_DEFAULT4\ 199 + (RT715_VERB_SET_CONFIG_DEFAULT4 | RT715_DMIC3) 200 + #define RT715_SET_DMIC4_CONFIG_DEFAULT4\ 201 + (RT715_VERB_SET_CONFIG_DEFAULT4 | RT715_DMIC4) 202 + 203 + #define RT715_MUTE_SFT 7 204 + #define RT715_DIR_IN_SFT 6 205 + #define RT715_DIR_OUT_SFT 7 206 + 207 + enum { 208 + RT715_AIF1, 209 + RT715_AIF2, 210 + RT715_AIFS, 211 + }; 212 + 213 + int rt715_io_init(struct device *dev, struct sdw_slave *slave); 214 + int rt715_init(struct device *dev, struct regmap *sdw_regmap, 215 + struct regmap *regmap, struct sdw_slave *slave); 216 + 217 + int hda_to_sdw(unsigned int nid, unsigned int verb, unsigned int payload, 218 + unsigned int *sdw_addr_h, unsigned int *sdw_data_h, 219 + unsigned int *sdw_addr_l, unsigned int *sdw_data_l); 220 + int rt715_clock_config(struct device *dev); 221 + #endif /* __RT715_H__ */