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

Configure Feed

Select the types of activity you want to include in your feed.

ASoC: rt712-sdca: Add RT712 SDCA driver for Jack and Amp topology

This is the initial codec driver for rt712 SDCA (Jack+Amp topology).
The host should connect with rt712 SdW1 interface.

Signed-off-by: Shuming Fan <shumingf@realtek.com>
Link: https://lore.kernel.org/r/20230207090946.20659-1-shumingf@realtek.com
Signed-off-by: Mark Brown <broonie@kernel.org>

authored by

Shuming Fan and committed by
Mark Brown
6c39710d 9f138bb2

+2150
+7
sound/soc/codecs/Kconfig
··· 198 198 imply SND_SOC_RT700_SDW 199 199 imply SND_SOC_RT711_SDW 200 200 imply SND_SOC_RT711_SDCA_SDW 201 + imply SND_SOC_RT712_SDCA_SDW 201 202 imply SND_SOC_RT715_SDW 202 203 imply SND_SOC_RT715_SDCA_SDW 203 204 imply SND_SOC_RT1308_SDW ··· 1459 1458 1460 1459 config SND_SOC_RT711_SDCA_SDW 1461 1460 tristate "Realtek RT711 SDCA Codec - SDW" 1461 + depends on SOUNDWIRE 1462 + select REGMAP_SOUNDWIRE 1463 + select REGMAP_SOUNDWIRE_MBQ 1464 + 1465 + config SND_SOC_RT712_SDCA_SDW 1466 + tristate "Realtek RT712 SDCA Codec - SDW" 1462 1467 depends on SOUNDWIRE 1463 1468 select REGMAP_SOUNDWIRE 1464 1469 select REGMAP_SOUNDWIRE_MBQ
+2
sound/soc/codecs/Makefile
··· 227 227 snd-soc-rt700-objs := rt700.o rt700-sdw.o 228 228 snd-soc-rt711-objs := rt711.o rt711-sdw.o 229 229 snd-soc-rt711-sdca-objs := rt711-sdca.o rt711-sdca-sdw.o 230 + snd-soc-rt712-sdca-objs := rt712-sdca.o rt712-sdca-sdw.o 230 231 snd-soc-rt715-objs := rt715.o rt715-sdw.o 231 232 snd-soc-rt715-sdca-objs := rt715-sdca.o rt715-sdca-sdw.o 232 233 snd-soc-rt9120-objs := rt9120.o ··· 590 589 obj-$(CONFIG_SND_SOC_RT700) += snd-soc-rt700.o 591 590 obj-$(CONFIG_SND_SOC_RT711) += snd-soc-rt711.o 592 591 obj-$(CONFIG_SND_SOC_RT711_SDCA_SDW) += snd-soc-rt711-sdca.o 592 + obj-$(CONFIG_SND_SOC_RT712_SDCA_SDW) += snd-soc-rt712-sdca.o 593 593 obj-$(CONFIG_SND_SOC_RT715) += snd-soc-rt715.o 594 594 obj-$(CONFIG_SND_SOC_RT715_SDCA_SDW) += snd-soc-rt715-sdca.o 595 595 obj-$(CONFIG_SND_SOC_RT9120) += snd-soc-rt9120.o
+485
sound/soc/codecs/rt712-sdca-sdw.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + // 3 + // rt712-sdca-sdw.c -- rt712 SDCA ALSA SoC audio driver 4 + // 5 + // Copyright(c) 2023 Realtek Semiconductor Corp. 6 + // 7 + // 8 + 9 + #include <linux/delay.h> 10 + #include <linux/device.h> 11 + #include <linux/mod_devicetable.h> 12 + #include <linux/module.h> 13 + #include <linux/pm_runtime.h> 14 + #include <linux/soundwire/sdw_registers.h> 15 + #include "rt712-sdca.h" 16 + #include "rt712-sdca-sdw.h" 17 + 18 + static bool rt712_sdca_readable_register(struct device *dev, unsigned int reg) 19 + { 20 + switch (reg) { 21 + case 0x201a ... 0x201f: 22 + case 0x2029 ... 0x202a: 23 + case 0x202d ... 0x2034: 24 + case 0x2230 ... 0x2232: 25 + case 0x2f01 ... 0x2f0a: 26 + case 0x2f35 ... 0x2f36: 27 + case 0x2f50: 28 + case 0x2f54: 29 + case 0x2f58 ... 0x2f5d: 30 + case 0x3201: 31 + case 0x320c: 32 + case 0x3301 ... 0x3303: 33 + case SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT712_SDCA_ENT_GE49, RT712_SDCA_CTL_SELECTED_MODE, 0): 34 + case SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT712_SDCA_ENT_GE49, RT712_SDCA_CTL_DETECTED_MODE, 0): 35 + case SDW_SDCA_CTL(FUNC_NUM_HID, RT712_SDCA_ENT_HID01, RT712_SDCA_CTL_HIDTX_CURRENT_OWNER, 0) ... 36 + SDW_SDCA_CTL(FUNC_NUM_HID, RT712_SDCA_ENT_HID01, RT712_SDCA_CTL_HIDTX_MESSAGE_LENGTH, 0): 37 + case RT712_BUF_ADDR_HID1 ... RT712_BUF_ADDR_HID2: 38 + return true; 39 + default: 40 + return false; 41 + } 42 + } 43 + 44 + static bool rt712_sdca_volatile_register(struct device *dev, unsigned int reg) 45 + { 46 + switch (reg) { 47 + case 0x201b: 48 + case 0x201c: 49 + case 0x201d: 50 + case 0x201f: 51 + case 0x202d ... 0x202f: 52 + case 0x2230: 53 + case 0x2f01: 54 + case 0x2f35: 55 + case 0x320c: 56 + case SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT712_SDCA_ENT_GE49, RT712_SDCA_CTL_DETECTED_MODE, 0): 57 + case SDW_SDCA_CTL(FUNC_NUM_HID, RT712_SDCA_ENT_HID01, RT712_SDCA_CTL_HIDTX_CURRENT_OWNER, 0) ... 58 + SDW_SDCA_CTL(FUNC_NUM_HID, RT712_SDCA_ENT_HID01, RT712_SDCA_CTL_HIDTX_MESSAGE_LENGTH, 0): 59 + case RT712_BUF_ADDR_HID1 ... RT712_BUF_ADDR_HID2: 60 + return true; 61 + default: 62 + return false; 63 + } 64 + } 65 + 66 + static bool rt712_sdca_mbq_readable_register(struct device *dev, unsigned int reg) 67 + { 68 + switch (reg) { 69 + case 0x2000000 ... 0x200008e: 70 + case 0x5300000 ... 0x530000e: 71 + case 0x5400000 ... 0x540000e: 72 + case 0x5600000 ... 0x5600008: 73 + case 0x5700000 ... 0x570000d: 74 + case 0x5800000 ... 0x5800021: 75 + case 0x5900000 ... 0x5900028: 76 + case 0x5a00000 ... 0x5a00009: 77 + case 0x5b00000 ... 0x5b00051: 78 + case 0x5c00000 ... 0x5c0009a: 79 + case 0x5d00000 ... 0x5d00009: 80 + case 0x5f00000 ... 0x5f00030: 81 + case 0x6100000 ... 0x6100068: 82 + case SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT712_SDCA_ENT_USER_FU05, RT712_SDCA_CTL_FU_VOLUME, CH_L): 83 + case SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT712_SDCA_ENT_USER_FU05, RT712_SDCA_CTL_FU_VOLUME, CH_R): 84 + case SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT712_SDCA_ENT_USER_FU0F, RT712_SDCA_CTL_FU_VOLUME, CH_L): 85 + case SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT712_SDCA_ENT_USER_FU0F, RT712_SDCA_CTL_FU_VOLUME, CH_R): 86 + case SDW_SDCA_CTL(FUNC_NUM_AMP, RT712_SDCA_ENT_USER_FU06, RT712_SDCA_CTL_FU_VOLUME, CH_L): 87 + case SDW_SDCA_CTL(FUNC_NUM_AMP, RT712_SDCA_ENT_USER_FU06, RT712_SDCA_CTL_FU_VOLUME, CH_R): 88 + return true; 89 + default: 90 + return false; 91 + } 92 + } 93 + 94 + static bool rt712_sdca_mbq_volatile_register(struct device *dev, unsigned int reg) 95 + { 96 + switch (reg) { 97 + case 0x2000000: 98 + case 0x200001a: 99 + case 0x2000024: 100 + case 0x2000046: 101 + case 0x200008a: 102 + case 0x5800000: 103 + case 0x5800001: 104 + case 0x6100008: 105 + return true; 106 + default: 107 + return false; 108 + } 109 + } 110 + 111 + static const struct regmap_config rt712_sdca_regmap = { 112 + .reg_bits = 32, 113 + .val_bits = 8, 114 + .readable_reg = rt712_sdca_readable_register, 115 + .volatile_reg = rt712_sdca_volatile_register, 116 + .max_register = 0x44ffffff, 117 + .reg_defaults = rt712_sdca_reg_defaults, 118 + .num_reg_defaults = ARRAY_SIZE(rt712_sdca_reg_defaults), 119 + .cache_type = REGCACHE_RBTREE, 120 + .use_single_read = true, 121 + .use_single_write = true, 122 + }; 123 + 124 + static const struct regmap_config rt712_sdca_mbq_regmap = { 125 + .name = "sdw-mbq", 126 + .reg_bits = 32, 127 + .val_bits = 16, 128 + .readable_reg = rt712_sdca_mbq_readable_register, 129 + .volatile_reg = rt712_sdca_mbq_volatile_register, 130 + .max_register = 0x41000312, 131 + .reg_defaults = rt712_sdca_mbq_defaults, 132 + .num_reg_defaults = ARRAY_SIZE(rt712_sdca_mbq_defaults), 133 + .cache_type = REGCACHE_RBTREE, 134 + .use_single_read = true, 135 + .use_single_write = true, 136 + }; 137 + 138 + static int rt712_sdca_update_status(struct sdw_slave *slave, 139 + enum sdw_slave_status status) 140 + { 141 + struct rt712_sdca_priv *rt712 = dev_get_drvdata(&slave->dev); 142 + 143 + /* Update the status */ 144 + rt712->status = status; 145 + 146 + if (status == SDW_SLAVE_UNATTACHED) 147 + rt712->hw_init = false; 148 + 149 + if (status == SDW_SLAVE_ATTACHED) { 150 + if (rt712->hs_jack) { 151 + /* 152 + * Due to the SCP_SDCA_INTMASK will be cleared by any reset, and then 153 + * if the device attached again, we will need to set the setting back. 154 + * It could avoid losing the jack detection interrupt. 155 + * This also could sync with the cache value as the rt712_sdca_jack_init set. 156 + */ 157 + sdw_write_no_pm(rt712->slave, SDW_SCP_SDCA_INTMASK1, 158 + SDW_SCP_SDCA_INTMASK_SDCA_0); 159 + sdw_write_no_pm(rt712->slave, SDW_SCP_SDCA_INTMASK2, 160 + SDW_SCP_SDCA_INTMASK_SDCA_8); 161 + } 162 + } 163 + 164 + /* 165 + * Perform initialization only if slave status is present and 166 + * hw_init flag is false 167 + */ 168 + if (rt712->hw_init || rt712->status != SDW_SLAVE_ATTACHED) 169 + return 0; 170 + 171 + /* perform I/O transfers required for Slave initialization */ 172 + return rt712_sdca_io_init(&slave->dev, slave); 173 + } 174 + 175 + static int rt712_sdca_read_prop(struct sdw_slave *slave) 176 + { 177 + struct sdw_slave_prop *prop = &slave->prop; 178 + int nval; 179 + int i, j; 180 + u32 bit; 181 + unsigned long addr; 182 + struct sdw_dpn_prop *dpn; 183 + 184 + prop->scp_int1_mask = SDW_SCP_INT1_BUS_CLASH | SDW_SCP_INT1_PARITY; 185 + prop->quirks = SDW_SLAVE_QUIRKS_INVALID_INITIAL_PARITY; 186 + 187 + prop->paging_support = true; 188 + 189 + /* first we need to allocate memory for set bits in port lists */ 190 + prop->source_ports = BIT(4); /* BITMAP: 00010000 */ 191 + prop->sink_ports = BIT(3) | BIT(1); /* BITMAP: 00001010 */ 192 + 193 + nval = hweight32(prop->source_ports); 194 + prop->src_dpn_prop = devm_kcalloc(&slave->dev, nval, 195 + sizeof(*prop->src_dpn_prop), GFP_KERNEL); 196 + if (!prop->src_dpn_prop) 197 + return -ENOMEM; 198 + 199 + i = 0; 200 + dpn = prop->src_dpn_prop; 201 + addr = prop->source_ports; 202 + for_each_set_bit(bit, &addr, 32) { 203 + dpn[i].num = bit; 204 + dpn[i].type = SDW_DPN_FULL; 205 + dpn[i].simple_ch_prep_sm = true; 206 + dpn[i].ch_prep_timeout = 10; 207 + i++; 208 + } 209 + 210 + /* do this again for sink now */ 211 + nval = hweight32(prop->sink_ports); 212 + prop->sink_dpn_prop = devm_kcalloc(&slave->dev, nval, 213 + sizeof(*prop->sink_dpn_prop), GFP_KERNEL); 214 + if (!prop->sink_dpn_prop) 215 + return -ENOMEM; 216 + 217 + j = 0; 218 + dpn = prop->sink_dpn_prop; 219 + addr = prop->sink_ports; 220 + for_each_set_bit(bit, &addr, 32) { 221 + dpn[j].num = bit; 222 + dpn[j].type = SDW_DPN_FULL; 223 + dpn[j].simple_ch_prep_sm = true; 224 + dpn[j].ch_prep_timeout = 10; 225 + j++; 226 + } 227 + 228 + /* set the timeout values */ 229 + prop->clk_stop_timeout = 1380; 230 + 231 + /* wake-up event */ 232 + prop->wake_capable = 1; 233 + 234 + return 0; 235 + } 236 + 237 + static int rt712_sdca_interrupt_callback(struct sdw_slave *slave, 238 + struct sdw_slave_intr_status *status) 239 + { 240 + struct rt712_sdca_priv *rt712 = dev_get_drvdata(&slave->dev); 241 + int ret, stat; 242 + int count = 0, retry = 3; 243 + unsigned int sdca_cascade, scp_sdca_stat1, scp_sdca_stat2 = 0; 244 + 245 + dev_dbg(&slave->dev, 246 + "%s control_port_stat=%x, sdca_cascade=%x", __func__, 247 + status->control_port, status->sdca_cascade); 248 + 249 + if (cancel_delayed_work_sync(&rt712->jack_detect_work)) { 250 + dev_warn(&slave->dev, "%s the pending delayed_work was cancelled", __func__); 251 + /* avoid the HID owner doesn't change to device */ 252 + if (rt712->scp_sdca_stat2) 253 + scp_sdca_stat2 = rt712->scp_sdca_stat2; 254 + } 255 + 256 + /* 257 + * The critical section below intentionally protects a rather large piece of code. 258 + * We don't want to allow the system suspend to disable an interrupt while we are 259 + * processing it, which could be problematic given the quirky SoundWire interrupt 260 + * scheme. We do want however to prevent new workqueues from being scheduled if 261 + * the disable_irq flag was set during system suspend. 262 + */ 263 + mutex_lock(&rt712->disable_irq_lock); 264 + 265 + ret = sdw_read_no_pm(rt712->slave, SDW_SCP_SDCA_INT1); 266 + if (ret < 0) 267 + goto io_error; 268 + rt712->scp_sdca_stat1 = ret; 269 + ret = sdw_read_no_pm(rt712->slave, SDW_SCP_SDCA_INT2); 270 + if (ret < 0) 271 + goto io_error; 272 + rt712->scp_sdca_stat2 = ret; 273 + if (scp_sdca_stat2) 274 + rt712->scp_sdca_stat2 |= scp_sdca_stat2; 275 + 276 + do { 277 + /* clear flag */ 278 + ret = sdw_read_no_pm(rt712->slave, SDW_SCP_SDCA_INT1); 279 + if (ret < 0) 280 + goto io_error; 281 + if (ret & SDW_SCP_SDCA_INTMASK_SDCA_0) { 282 + ret = sdw_write_no_pm(rt712->slave, SDW_SCP_SDCA_INT1, 283 + SDW_SCP_SDCA_INTMASK_SDCA_0); 284 + if (ret < 0) 285 + goto io_error; 286 + } 287 + ret = sdw_read_no_pm(rt712->slave, SDW_SCP_SDCA_INT2); 288 + if (ret < 0) 289 + goto io_error; 290 + if (ret & SDW_SCP_SDCA_INTMASK_SDCA_8) { 291 + ret = sdw_write_no_pm(rt712->slave, SDW_SCP_SDCA_INT2, 292 + SDW_SCP_SDCA_INTMASK_SDCA_8); 293 + if (ret < 0) 294 + goto io_error; 295 + } 296 + 297 + /* check if flag clear or not */ 298 + ret = sdw_read_no_pm(rt712->slave, SDW_DP0_INT); 299 + if (ret < 0) 300 + goto io_error; 301 + sdca_cascade = ret & SDW_DP0_SDCA_CASCADE; 302 + 303 + ret = sdw_read_no_pm(rt712->slave, SDW_SCP_SDCA_INT1); 304 + if (ret < 0) 305 + goto io_error; 306 + scp_sdca_stat1 = ret & SDW_SCP_SDCA_INTMASK_SDCA_0; 307 + 308 + ret = sdw_read_no_pm(rt712->slave, SDW_SCP_SDCA_INT2); 309 + if (ret < 0) 310 + goto io_error; 311 + scp_sdca_stat2 = ret & SDW_SCP_SDCA_INTMASK_SDCA_8; 312 + 313 + stat = scp_sdca_stat1 || scp_sdca_stat2 || sdca_cascade; 314 + 315 + count++; 316 + } while (stat != 0 && count < retry); 317 + 318 + if (stat) 319 + dev_warn(&slave->dev, 320 + "%s scp_sdca_stat1=0x%x, scp_sdca_stat2=0x%x\n", __func__, 321 + rt712->scp_sdca_stat1, rt712->scp_sdca_stat2); 322 + 323 + if (status->sdca_cascade && !rt712->disable_irq) 324 + mod_delayed_work(system_power_efficient_wq, 325 + &rt712->jack_detect_work, msecs_to_jiffies(30)); 326 + 327 + mutex_unlock(&rt712->disable_irq_lock); 328 + 329 + return 0; 330 + 331 + io_error: 332 + mutex_unlock(&rt712->disable_irq_lock); 333 + pr_err_ratelimited("IO error in %s, ret %d\n", __func__, ret); 334 + return ret; 335 + } 336 + 337 + static struct sdw_slave_ops rt712_sdca_slave_ops = { 338 + .read_prop = rt712_sdca_read_prop, 339 + .interrupt_callback = rt712_sdca_interrupt_callback, 340 + .update_status = rt712_sdca_update_status, 341 + }; 342 + 343 + static int rt712_sdca_sdw_probe(struct sdw_slave *slave, 344 + const struct sdw_device_id *id) 345 + { 346 + struct regmap *regmap, *mbq_regmap; 347 + 348 + /* Regmap Initialization */ 349 + mbq_regmap = devm_regmap_init_sdw_mbq(slave, &rt712_sdca_mbq_regmap); 350 + if (IS_ERR(mbq_regmap)) 351 + return PTR_ERR(mbq_regmap); 352 + 353 + regmap = devm_regmap_init_sdw(slave, &rt712_sdca_regmap); 354 + if (IS_ERR(regmap)) 355 + return PTR_ERR(regmap); 356 + 357 + return rt712_sdca_init(&slave->dev, regmap, mbq_regmap, slave); 358 + } 359 + 360 + static int rt712_sdca_sdw_remove(struct sdw_slave *slave) 361 + { 362 + struct rt712_sdca_priv *rt712 = dev_get_drvdata(&slave->dev); 363 + 364 + if (rt712->hw_init) { 365 + cancel_delayed_work_sync(&rt712->jack_detect_work); 366 + cancel_delayed_work_sync(&rt712->jack_btn_check_work); 367 + } 368 + 369 + if (rt712->first_hw_init) 370 + pm_runtime_disable(&slave->dev); 371 + 372 + mutex_destroy(&rt712->calibrate_mutex); 373 + mutex_destroy(&rt712->disable_irq_lock); 374 + 375 + return 0; 376 + } 377 + 378 + static const struct sdw_device_id rt712_sdca_id[] = { 379 + SDW_SLAVE_ENTRY_EXT(0x025d, 0x712, 0x3, 0x1, 0), 380 + SDW_SLAVE_ENTRY_EXT(0x025d, 0x713, 0x3, 0x1, 0), 381 + SDW_SLAVE_ENTRY_EXT(0x025d, 0x716, 0x3, 0x1, 0), 382 + SDW_SLAVE_ENTRY_EXT(0x025d, 0x717, 0x3, 0x1, 0), 383 + {}, 384 + }; 385 + MODULE_DEVICE_TABLE(sdw, rt712_sdca_id); 386 + 387 + static int __maybe_unused rt712_sdca_dev_suspend(struct device *dev) 388 + { 389 + struct rt712_sdca_priv *rt712 = dev_get_drvdata(dev); 390 + 391 + if (!rt712->hw_init) 392 + return 0; 393 + 394 + cancel_delayed_work_sync(&rt712->jack_detect_work); 395 + cancel_delayed_work_sync(&rt712->jack_btn_check_work); 396 + 397 + regcache_cache_only(rt712->regmap, true); 398 + regcache_cache_only(rt712->mbq_regmap, true); 399 + 400 + return 0; 401 + } 402 + 403 + static int __maybe_unused rt712_sdca_dev_system_suspend(struct device *dev) 404 + { 405 + struct rt712_sdca_priv *rt712_sdca = dev_get_drvdata(dev); 406 + struct sdw_slave *slave = dev_to_sdw_dev(dev); 407 + int ret1, ret2; 408 + 409 + if (!rt712_sdca->hw_init) 410 + return 0; 411 + 412 + /* 413 + * prevent new interrupts from being handled after the 414 + * deferred work completes and before the parent disables 415 + * interrupts on the link 416 + */ 417 + mutex_lock(&rt712_sdca->disable_irq_lock); 418 + rt712_sdca->disable_irq = true; 419 + ret1 = sdw_update_no_pm(slave, SDW_SCP_SDCA_INTMASK1, 420 + SDW_SCP_SDCA_INTMASK_SDCA_0, 0); 421 + ret2 = sdw_update_no_pm(slave, SDW_SCP_SDCA_INTMASK2, 422 + SDW_SCP_SDCA_INTMASK_SDCA_8, 0); 423 + mutex_unlock(&rt712_sdca->disable_irq_lock); 424 + 425 + if (ret1 < 0 || ret2 < 0) { 426 + /* log but don't prevent suspend from happening */ 427 + dev_dbg(&slave->dev, "%s: could not disable SDCA interrupts\n:", __func__); 428 + } 429 + 430 + return rt712_sdca_dev_suspend(dev); 431 + } 432 + 433 + #define RT712_PROBE_TIMEOUT 5000 434 + 435 + static int __maybe_unused rt712_sdca_dev_resume(struct device *dev) 436 + { 437 + struct sdw_slave *slave = dev_to_sdw_dev(dev); 438 + struct rt712_sdca_priv *rt712 = dev_get_drvdata(dev); 439 + unsigned long time; 440 + 441 + if (!rt712->first_hw_init) 442 + return 0; 443 + 444 + if (!slave->unattach_request) 445 + goto regmap_sync; 446 + 447 + time = wait_for_completion_timeout(&slave->initialization_complete, 448 + msecs_to_jiffies(RT712_PROBE_TIMEOUT)); 449 + if (!time) { 450 + dev_err(&slave->dev, "Initialization not complete, timed out\n"); 451 + sdw_show_ping_status(slave->bus, true); 452 + 453 + return -ETIMEDOUT; 454 + } 455 + 456 + regmap_sync: 457 + slave->unattach_request = 0; 458 + regcache_cache_only(rt712->regmap, false); 459 + regcache_sync(rt712->regmap); 460 + regcache_cache_only(rt712->mbq_regmap, false); 461 + regcache_sync(rt712->mbq_regmap); 462 + return 0; 463 + } 464 + 465 + static const struct dev_pm_ops rt712_sdca_pm = { 466 + SET_SYSTEM_SLEEP_PM_OPS(rt712_sdca_dev_system_suspend, rt712_sdca_dev_resume) 467 + SET_RUNTIME_PM_OPS(rt712_sdca_dev_suspend, rt712_sdca_dev_resume, NULL) 468 + }; 469 + 470 + static struct sdw_driver rt712_sdca_sdw_driver = { 471 + .driver = { 472 + .name = "rt712-sdca", 473 + .owner = THIS_MODULE, 474 + .pm = &rt712_sdca_pm, 475 + }, 476 + .probe = rt712_sdca_sdw_probe, 477 + .remove = rt712_sdca_sdw_remove, 478 + .ops = &rt712_sdca_slave_ops, 479 + .id_table = rt712_sdca_id, 480 + }; 481 + module_sdw_driver(rt712_sdca_sdw_driver); 482 + 483 + MODULE_DESCRIPTION("ASoC RT712 SDCA SDW driver"); 484 + MODULE_AUTHOR("Shuming Fan <shumingf@realtek.com>"); 485 + MODULE_LICENSE("GPL");
+108
sound/soc/codecs/rt712-sdca-sdw.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-only */ 2 + /* 3 + * rt712-sdca-sdw.h -- RT712 SDCA ALSA SoC audio driver header 4 + * 5 + * Copyright(c) 2023 Realtek Semiconductor Corp. 6 + */ 7 + 8 + #ifndef __RT712_SDW_H__ 9 + #define __RT712_SDW_H__ 10 + 11 + #include <linux/regmap.h> 12 + #include <linux/soundwire/sdw_registers.h> 13 + 14 + static const struct reg_default rt712_sdca_reg_defaults[] = { 15 + { 0x201a, 0x00 }, 16 + { 0x201b, 0x00 }, 17 + { 0x201c, 0x00 }, 18 + { 0x201d, 0x00 }, 19 + { 0x201e, 0x00 }, 20 + { 0x201f, 0x00 }, 21 + { 0x2029, 0x00 }, 22 + { 0x202a, 0x00 }, 23 + { 0x202d, 0x00 }, 24 + { 0x202e, 0x00 }, 25 + { 0x202f, 0x00 }, 26 + { 0x2030, 0x00 }, 27 + { 0x2031, 0x00 }, 28 + { 0x2032, 0x00 }, 29 + { 0x2033, 0x00 }, 30 + { 0x2034, 0x00 }, 31 + { 0x2230, 0x00 }, 32 + { 0x2231, 0x2f }, 33 + { 0x2232, 0x80 }, 34 + { 0x2f01, 0x00 }, 35 + { 0x2f02, 0x09 }, 36 + { 0x2f03, 0x00 }, 37 + { 0x2f04, 0x00 }, 38 + { 0x2f05, 0x0b }, 39 + { 0x2f06, 0x01 }, 40 + { 0x2f08, 0x00 }, 41 + { 0x2f09, 0x00 }, 42 + { 0x2f0a, 0x01 }, 43 + { 0x2f35, 0x01 }, 44 + { 0x2f36, 0xcf }, 45 + { 0x2f50, 0x0f }, 46 + { 0x2f54, 0x01 }, 47 + { 0x2f58, 0x07 }, 48 + { 0x2f59, 0x09 }, 49 + { 0x2f5a, 0x01 }, 50 + { 0x2f5b, 0x07 }, 51 + { 0x2f5c, 0x05 }, 52 + { 0x2f5d, 0x05 }, 53 + { 0x3201, 0x01 }, 54 + { 0x320c, 0x00 }, 55 + { 0x3301, 0x01 }, 56 + { 0x3302, 0x00 }, 57 + { 0x3303, 0x1f }, 58 + { SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT712_SDCA_ENT_CS01, RT712_SDCA_CTL_SAMPLE_FREQ_INDEX, 0), 0x09 }, 59 + { SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT712_SDCA_ENT_CS11, RT712_SDCA_CTL_SAMPLE_FREQ_INDEX, 0), 0x09 }, 60 + { SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT712_SDCA_ENT_USER_FU05, RT712_SDCA_CTL_FU_MUTE, CH_L), 0x01 }, 61 + { SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT712_SDCA_ENT_USER_FU05, RT712_SDCA_CTL_FU_MUTE, CH_R), 0x01 }, 62 + { SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT712_SDCA_ENT_USER_FU0F, RT712_SDCA_CTL_FU_MUTE, CH_L), 0x01 }, 63 + { SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT712_SDCA_ENT_USER_FU0F, RT712_SDCA_CTL_FU_MUTE, CH_R), 0x01 }, 64 + { SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT712_SDCA_ENT_PDE40, RT712_SDCA_CTL_REQ_POWER_STATE, 0), 0x03 }, 65 + { SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT712_SDCA_ENT_PDE12, RT712_SDCA_CTL_REQ_POWER_STATE, 0), 0x03 }, 66 + { SDW_SDCA_CTL(FUNC_NUM_AMP, RT712_SDCA_ENT_CS31, RT712_SDCA_CTL_SAMPLE_FREQ_INDEX, 0), 0x09 }, 67 + { SDW_SDCA_CTL(FUNC_NUM_AMP, RT712_SDCA_ENT_PDE23, RT712_SDCA_CTL_REQ_POWER_STATE, 0), 0x03 }, 68 + { SDW_SDCA_CTL(FUNC_NUM_AMP, RT712_SDCA_ENT_USER_FU06, RT712_SDCA_CTL_FU_MUTE, CH_L), 0x01 }, 69 + { SDW_SDCA_CTL(FUNC_NUM_AMP, RT712_SDCA_ENT_USER_FU06, RT712_SDCA_CTL_FU_MUTE, CH_R), 0x01 }, 70 + { SDW_SDCA_CTL(FUNC_NUM_AMP, RT712_SDCA_ENT_OT23, RT712_SDCA_CTL_VENDOR_DEF, 0), 0x00 }, 71 + }; 72 + 73 + static const struct reg_default rt712_sdca_mbq_defaults[] = { 74 + { 0x2000004, 0xaa01 }, 75 + { 0x200000e, 0x21e0 }, 76 + { 0x2000024, 0x01ba }, 77 + { 0x200004a, 0x8830 }, 78 + { 0x2000067, 0xf100 }, 79 + { 0x5800000, 0x1893 }, 80 + { 0x5b00000, 0x0407 }, 81 + { 0x5b00005, 0x0000 }, 82 + { 0x5b00029, 0x3fff }, 83 + { 0x5b0002a, 0xf000 }, 84 + { 0x5f00008, 0x7000 }, 85 + { 0x610000e, 0x0007 }, 86 + { 0x6100022, 0x2828 }, 87 + { 0x6100023, 0x2929 }, 88 + { 0x6100026, 0x2c29 }, 89 + { 0x610002c, 0x4150 }, 90 + { 0x6100045, 0x0860 }, 91 + { 0x6100046, 0x0029 }, 92 + { 0x6100053, 0x3fff }, 93 + { 0x6100055, 0x0000 }, 94 + { 0x6100060, 0x0000 }, 95 + { 0x6100064, 0x8000 }, 96 + { 0x6100065, 0x0000 }, 97 + { 0x6100067, 0xff12 }, 98 + { SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT712_SDCA_ENT_USER_FU05, RT712_SDCA_CTL_FU_VOLUME, CH_L), 0x0000 }, 99 + { SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT712_SDCA_ENT_USER_FU05, RT712_SDCA_CTL_FU_VOLUME, CH_R), 0x0000 }, 100 + { SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT712_SDCA_ENT_USER_FU0F, RT712_SDCA_CTL_FU_VOLUME, CH_L), 0x0000 }, 101 + { SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT712_SDCA_ENT_USER_FU0F, RT712_SDCA_CTL_FU_VOLUME, CH_R), 0x0000 }, 102 + { SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT712_SDCA_ENT_PLATFORM_FU44, RT712_SDCA_CTL_FU_CH_GAIN, CH_L), 0x0000 }, 103 + { SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT712_SDCA_ENT_PLATFORM_FU44, RT712_SDCA_CTL_FU_CH_GAIN, CH_R), 0x0000 }, 104 + { SDW_SDCA_CTL(FUNC_NUM_AMP, RT712_SDCA_ENT_USER_FU06, RT712_SDCA_CTL_FU_VOLUME, CH_L), 0x0000 }, 105 + { SDW_SDCA_CTL(FUNC_NUM_AMP, RT712_SDCA_ENT_USER_FU06, RT712_SDCA_CTL_FU_VOLUME, CH_R), 0x0000 }, 106 + }; 107 + 108 + #endif /* __RT712_SDW_H__ */
+1328
sound/soc/codecs/rt712-sdca.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + // 3 + // rt712-sdca.c -- rt712 SDCA ALSA SoC audio driver 4 + // 5 + // Copyright(c) 2023 Realtek Semiconductor Corp. 6 + // 7 + // 8 + 9 + #include <linux/bitops.h> 10 + #include <sound/core.h> 11 + #include <linux/delay.h> 12 + #include <linux/init.h> 13 + #include <sound/initval.h> 14 + #include <sound/jack.h> 15 + #include <linux/kernel.h> 16 + #include <linux/module.h> 17 + #include <linux/moduleparam.h> 18 + #include <linux/pm_runtime.h> 19 + #include <sound/pcm.h> 20 + #include <sound/pcm_params.h> 21 + #include <linux/soundwire/sdw_registers.h> 22 + #include <linux/slab.h> 23 + #include <sound/soc-dapm.h> 24 + #include <sound/tlv.h> 25 + #include "rt712-sdca.h" 26 + 27 + static int rt712_sdca_index_write(struct rt712_sdca_priv *rt712, 28 + unsigned int nid, unsigned int reg, unsigned int value) 29 + { 30 + int ret; 31 + struct regmap *regmap = rt712->mbq_regmap; 32 + unsigned int addr = (nid << 20) | reg; 33 + 34 + ret = regmap_write(regmap, addr, value); 35 + if (ret < 0) 36 + dev_err(&rt712->slave->dev, 37 + "Failed to set private value: %06x <= %04x ret=%d\n", 38 + addr, value, ret); 39 + 40 + return ret; 41 + } 42 + 43 + static int rt712_sdca_index_read(struct rt712_sdca_priv *rt712, 44 + unsigned int nid, unsigned int reg, unsigned int *value) 45 + { 46 + int ret; 47 + struct regmap *regmap = rt712->mbq_regmap; 48 + unsigned int addr = (nid << 20) | reg; 49 + 50 + ret = regmap_read(regmap, addr, value); 51 + if (ret < 0) 52 + dev_err(&rt712->slave->dev, 53 + "Failed to get private value: %06x => %04x ret=%d\n", 54 + addr, *value, ret); 55 + 56 + return ret; 57 + } 58 + 59 + static int rt712_sdca_index_update_bits(struct rt712_sdca_priv *rt712, 60 + unsigned int nid, unsigned int reg, unsigned int mask, unsigned int val) 61 + { 62 + unsigned int tmp; 63 + int ret; 64 + 65 + ret = rt712_sdca_index_read(rt712, nid, reg, &tmp); 66 + if (ret < 0) 67 + return ret; 68 + 69 + set_mask_bits(&tmp, mask, val); 70 + return rt712_sdca_index_write(rt712, nid, reg, tmp); 71 + } 72 + 73 + static int rt712_sdca_calibration(struct rt712_sdca_priv *rt712) 74 + { 75 + unsigned int val, loop_rc = 0, loop_dc = 0; 76 + struct device *dev; 77 + struct regmap *regmap = rt712->regmap; 78 + int chk_cnt = 100; 79 + int ret = 0; 80 + 81 + mutex_lock(&rt712->calibrate_mutex); 82 + dev = regmap_get_device(regmap); 83 + 84 + /* Set HP-JD source from JD1 */ 85 + rt712_sdca_index_write(rt712, RT712_VENDOR_REG, RT712_CC_DET1, 0x043a); 86 + 87 + /* FSM switch to calibration manual mode */ 88 + rt712_sdca_index_write(rt712, RT712_VENDOR_REG, RT712_FSM_CTL, 0x4100); 89 + 90 + /* Calibration setting */ 91 + rt712_sdca_index_write(rt712, RT712_VENDOR_CALI, RT712_DAC_DC_CALI_CTL1, 0x7883); 92 + 93 + /* W1C Trigger DC calibration (HP & Class-D) */ 94 + rt712_sdca_index_write(rt712, RT712_VENDOR_CALI, RT712_DAC_DC_CALI_CTL1, 0xf893); 95 + 96 + /* wait for calibration process */ 97 + rt712_sdca_index_read(rt712, RT712_VENDOR_CALI, 98 + RT712_DAC_DC_CALI_CTL1, &val); 99 + 100 + for (loop_dc = 0; loop_dc < chk_cnt && 101 + (val & RT712_DAC_DC_CALI_TRIGGER); loop_dc++) { 102 + usleep_range(10000, 11000); 103 + ret = rt712_sdca_index_read(rt712, RT712_VENDOR_CALI, 104 + RT712_DAC_DC_CALI_CTL1, &val); 105 + if (ret < 0) 106 + goto _cali_fail_; 107 + } 108 + if (loop_dc == chk_cnt) 109 + dev_err(dev, "%s, calibration time-out!\n", __func__); 110 + 111 + if (loop_dc == chk_cnt || loop_rc == chk_cnt) 112 + ret = -ETIMEDOUT; 113 + 114 + _cali_fail_: 115 + /* Enable Rldet in FSM */ 116 + rt712_sdca_index_write(rt712, RT712_VENDOR_REG, RT712_FSM_CTL, 0x4500); 117 + 118 + /* Sensing Lch+Rch */ 119 + rt712_sdca_index_write(rt712, RT712_VENDOR_IMS_DRE, RT712_IMS_DIGITAL_CTL1, 0x040f); 120 + 121 + /* Sine gen path control */ 122 + rt712_sdca_index_write(rt712, RT712_VENDOR_IMS_DRE, RT712_IMS_DIGITAL_CTL5, 0x0000); 123 + 124 + /* Release HP-JD, EN_CBJ_TIE_GL/R open, en_osw gating auto done bit */ 125 + rt712_sdca_index_write(rt712, RT712_VENDOR_REG, RT712_DIGITAL_MISC_CTRL4, 0x0010); 126 + 127 + mutex_unlock(&rt712->calibrate_mutex); 128 + dev_dbg(dev, "%s calibration complete, ret=%d\n", __func__, ret); 129 + return ret; 130 + } 131 + 132 + static unsigned int rt712_sdca_button_detect(struct rt712_sdca_priv *rt712) 133 + { 134 + unsigned int btn_type = 0, offset, idx, val, owner; 135 + int ret; 136 + unsigned char buf[3]; 137 + 138 + /* get current UMP message owner */ 139 + ret = regmap_read(rt712->regmap, 140 + SDW_SDCA_CTL(FUNC_NUM_HID, RT712_SDCA_ENT_HID01, RT712_SDCA_CTL_HIDTX_CURRENT_OWNER, 0), 141 + &owner); 142 + if (ret < 0) 143 + return 0; 144 + 145 + /* if owner is device then there is no button event from device */ 146 + if (owner == 1) 147 + return 0; 148 + 149 + /* read UMP message offset */ 150 + ret = regmap_read(rt712->regmap, 151 + SDW_SDCA_CTL(FUNC_NUM_HID, RT712_SDCA_ENT_HID01, RT712_SDCA_CTL_HIDTX_MESSAGE_OFFSET, 0), 152 + &offset); 153 + if (ret < 0) 154 + goto _end_btn_det_; 155 + 156 + for (idx = 0; idx < sizeof(buf); idx++) { 157 + ret = regmap_read(rt712->regmap, 158 + RT712_BUF_ADDR_HID1 + offset + idx, &val); 159 + if (ret < 0) 160 + goto _end_btn_det_; 161 + buf[idx] = val & 0xff; 162 + } 163 + 164 + if (buf[0] == 0x11) { 165 + switch (buf[1] & 0xf0) { 166 + case 0x10: 167 + btn_type |= SND_JACK_BTN_2; 168 + break; 169 + case 0x20: 170 + btn_type |= SND_JACK_BTN_3; 171 + break; 172 + case 0x40: 173 + btn_type |= SND_JACK_BTN_0; 174 + break; 175 + case 0x80: 176 + btn_type |= SND_JACK_BTN_1; 177 + break; 178 + } 179 + switch (buf[2]) { 180 + case 0x01: 181 + case 0x10: 182 + btn_type |= SND_JACK_BTN_2; 183 + break; 184 + case 0x02: 185 + case 0x20: 186 + btn_type |= SND_JACK_BTN_3; 187 + break; 188 + case 0x04: 189 + case 0x40: 190 + btn_type |= SND_JACK_BTN_0; 191 + break; 192 + case 0x08: 193 + case 0x80: 194 + btn_type |= SND_JACK_BTN_1; 195 + break; 196 + } 197 + } 198 + 199 + _end_btn_det_: 200 + /* Host is owner, so set back to device */ 201 + if (owner == 0) 202 + /* set owner to device */ 203 + regmap_write(rt712->regmap, 204 + SDW_SDCA_CTL(FUNC_NUM_HID, RT712_SDCA_ENT_HID01, 205 + RT712_SDCA_CTL_HIDTX_SET_OWNER_TO_DEVICE, 0), 0x01); 206 + 207 + return btn_type; 208 + } 209 + 210 + static int rt712_sdca_headset_detect(struct rt712_sdca_priv *rt712) 211 + { 212 + unsigned int det_mode; 213 + int ret; 214 + 215 + /* get detected_mode */ 216 + ret = regmap_read(rt712->regmap, 217 + SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT712_SDCA_ENT_GE49, RT712_SDCA_CTL_DETECTED_MODE, 0), 218 + &det_mode); 219 + if (ret < 0) 220 + goto io_error; 221 + 222 + switch (det_mode) { 223 + case 0x00: 224 + rt712->jack_type = 0; 225 + break; 226 + case 0x03: 227 + rt712->jack_type = SND_JACK_HEADPHONE; 228 + break; 229 + case 0x05: 230 + rt712->jack_type = SND_JACK_HEADSET; 231 + break; 232 + } 233 + 234 + /* write selected_mode */ 235 + if (det_mode) { 236 + ret = regmap_write(rt712->regmap, 237 + SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT712_SDCA_ENT_GE49, RT712_SDCA_CTL_SELECTED_MODE, 0), 238 + det_mode); 239 + if (ret < 0) 240 + goto io_error; 241 + } 242 + 243 + dev_dbg(&rt712->slave->dev, 244 + "%s, detected_mode=0x%x\n", __func__, det_mode); 245 + 246 + return 0; 247 + 248 + io_error: 249 + pr_err_ratelimited("IO error in %s, ret %d\n", __func__, ret); 250 + return ret; 251 + } 252 + 253 + static void rt712_sdca_jack_detect_handler(struct work_struct *work) 254 + { 255 + struct rt712_sdca_priv *rt712 = 256 + container_of(work, struct rt712_sdca_priv, jack_detect_work.work); 257 + int btn_type = 0, ret; 258 + 259 + if (!rt712->hs_jack) 260 + return; 261 + 262 + if (!rt712->component->card || !rt712->component->card->instantiated) 263 + return; 264 + 265 + /* SDW_SCP_SDCA_INT_SDCA_0 is used for jack detection */ 266 + if (rt712->scp_sdca_stat1 & SDW_SCP_SDCA_INT_SDCA_0) { 267 + ret = rt712_sdca_headset_detect(rt712); 268 + if (ret < 0) 269 + return; 270 + } 271 + 272 + /* SDW_SCP_SDCA_INT_SDCA_8 is used for button detection */ 273 + if (rt712->scp_sdca_stat2 & SDW_SCP_SDCA_INT_SDCA_8) 274 + btn_type = rt712_sdca_button_detect(rt712); 275 + 276 + if (rt712->jack_type == 0) 277 + btn_type = 0; 278 + 279 + dev_dbg(&rt712->slave->dev, 280 + "in %s, jack_type=0x%x\n", __func__, rt712->jack_type); 281 + dev_dbg(&rt712->slave->dev, 282 + "in %s, btn_type=0x%x\n", __func__, btn_type); 283 + dev_dbg(&rt712->slave->dev, 284 + "in %s, scp_sdca_stat1=0x%x, scp_sdca_stat2=0x%x\n", __func__, 285 + rt712->scp_sdca_stat1, rt712->scp_sdca_stat2); 286 + 287 + snd_soc_jack_report(rt712->hs_jack, rt712->jack_type | btn_type, 288 + SND_JACK_HEADSET | 289 + SND_JACK_BTN_0 | SND_JACK_BTN_1 | 290 + SND_JACK_BTN_2 | SND_JACK_BTN_3); 291 + 292 + if (btn_type) { 293 + /* button released */ 294 + snd_soc_jack_report(rt712->hs_jack, rt712->jack_type, 295 + SND_JACK_HEADSET | 296 + SND_JACK_BTN_0 | SND_JACK_BTN_1 | 297 + SND_JACK_BTN_2 | SND_JACK_BTN_3); 298 + 299 + mod_delayed_work(system_power_efficient_wq, 300 + &rt712->jack_btn_check_work, msecs_to_jiffies(200)); 301 + } 302 + } 303 + 304 + static void rt712_sdca_btn_check_handler(struct work_struct *work) 305 + { 306 + struct rt712_sdca_priv *rt712 = 307 + container_of(work, struct rt712_sdca_priv, jack_btn_check_work.work); 308 + int btn_type = 0, ret, idx; 309 + unsigned int det_mode, offset, val; 310 + unsigned char buf[3]; 311 + 312 + ret = regmap_read(rt712->regmap, 313 + SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT712_SDCA_ENT_GE49, RT712_SDCA_CTL_DETECTED_MODE, 0), 314 + &det_mode); 315 + if (ret < 0) 316 + goto io_error; 317 + 318 + /* pin attached */ 319 + if (det_mode) { 320 + /* read UMP message offset */ 321 + ret = regmap_read(rt712->regmap, 322 + SDW_SDCA_CTL(FUNC_NUM_HID, RT712_SDCA_ENT_HID01, RT712_SDCA_CTL_HIDTX_MESSAGE_OFFSET, 0), 323 + &offset); 324 + if (ret < 0) 325 + goto io_error; 326 + 327 + for (idx = 0; idx < sizeof(buf); idx++) { 328 + ret = regmap_read(rt712->regmap, 329 + RT712_BUF_ADDR_HID1 + offset + idx, &val); 330 + if (ret < 0) 331 + goto io_error; 332 + buf[idx] = val & 0xff; 333 + } 334 + 335 + if (buf[0] == 0x11) { 336 + switch (buf[1] & 0xf0) { 337 + case 0x10: 338 + btn_type |= SND_JACK_BTN_2; 339 + break; 340 + case 0x20: 341 + btn_type |= SND_JACK_BTN_3; 342 + break; 343 + case 0x40: 344 + btn_type |= SND_JACK_BTN_0; 345 + break; 346 + case 0x80: 347 + btn_type |= SND_JACK_BTN_1; 348 + break; 349 + } 350 + switch (buf[2]) { 351 + case 0x01: 352 + case 0x10: 353 + btn_type |= SND_JACK_BTN_2; 354 + break; 355 + case 0x02: 356 + case 0x20: 357 + btn_type |= SND_JACK_BTN_3; 358 + break; 359 + case 0x04: 360 + case 0x40: 361 + btn_type |= SND_JACK_BTN_0; 362 + break; 363 + case 0x08: 364 + case 0x80: 365 + btn_type |= SND_JACK_BTN_1; 366 + break; 367 + } 368 + } 369 + } else 370 + rt712->jack_type = 0; 371 + 372 + dev_dbg(&rt712->slave->dev, "%s, btn_type=0x%x\n", __func__, btn_type); 373 + snd_soc_jack_report(rt712->hs_jack, rt712->jack_type | btn_type, 374 + SND_JACK_HEADSET | 375 + SND_JACK_BTN_0 | SND_JACK_BTN_1 | 376 + SND_JACK_BTN_2 | SND_JACK_BTN_3); 377 + 378 + if (btn_type) { 379 + /* button released */ 380 + snd_soc_jack_report(rt712->hs_jack, rt712->jack_type, 381 + SND_JACK_HEADSET | 382 + SND_JACK_BTN_0 | SND_JACK_BTN_1 | 383 + SND_JACK_BTN_2 | SND_JACK_BTN_3); 384 + 385 + mod_delayed_work(system_power_efficient_wq, 386 + &rt712->jack_btn_check_work, msecs_to_jiffies(200)); 387 + } 388 + 389 + return; 390 + 391 + io_error: 392 + pr_err_ratelimited("IO error in %s, ret %d\n", __func__, ret); 393 + } 394 + 395 + static void rt712_sdca_jack_init(struct rt712_sdca_priv *rt712) 396 + { 397 + mutex_lock(&rt712->calibrate_mutex); 398 + 399 + if (rt712->hs_jack) { 400 + /* Enable HID1 event & set button RTC mode */ 401 + rt712_sdca_index_write(rt712, RT712_VENDOR_HDA_CTL, 402 + RT712_UMP_HID_CTL5, 0xfff0); 403 + rt712_sdca_index_update_bits(rt712, RT712_VENDOR_HDA_CTL, 404 + RT712_UMP_HID_CTL0, 0x1100, 0x1100); 405 + rt712_sdca_index_update_bits(rt712, RT712_VENDOR_HDA_CTL, 406 + RT712_UMP_HID_CTL7, 0xf000, 0x0000); 407 + 408 + /* detected_mode_change_event_en & hid1_push_button_event_en */ 409 + rt712_sdca_index_update_bits(rt712, RT712_VENDOR_HDA_CTL, 410 + RT712_GE_RELATED_CTL1, 0x0c00, 0x0c00); 411 + /* ge_inbox_en */ 412 + rt712_sdca_index_update_bits(rt712, RT712_VENDOR_HDA_CTL, 413 + RT712_GE_RELATED_CTL2, 0x0020, 0x0000); 414 + 415 + switch (rt712->jd_src) { 416 + case RT712_JD1: 417 + /* Set HP-JD source from JD1 */ 418 + rt712_sdca_index_write(rt712, RT712_VENDOR_REG, RT712_CC_DET1, 0x043a); 419 + break; 420 + default: 421 + dev_warn(rt712->component->dev, "Wrong JD source\n"); 422 + break; 423 + } 424 + 425 + /* set SCP_SDCA_IntMask1[0]=1 */ 426 + sdw_write_no_pm(rt712->slave, SDW_SCP_SDCA_INTMASK1, SDW_SCP_SDCA_INTMASK_SDCA_0); 427 + /* set SCP_SDCA_IntMask2[0]=1 */ 428 + sdw_write_no_pm(rt712->slave, SDW_SCP_SDCA_INTMASK2, SDW_SCP_SDCA_INTMASK_SDCA_8); 429 + dev_dbg(&rt712->slave->dev, "in %s enable\n", __func__); 430 + 431 + /* trigger GE interrupt */ 432 + rt712_sdca_index_update_bits(rt712, RT712_VENDOR_HDA_CTL, 433 + RT712_GE_RELATED_CTL1, 0x0080, 0x0080); 434 + rt712_sdca_index_update_bits(rt712, RT712_VENDOR_HDA_CTL, 435 + RT712_GE_RELATED_CTL1, 0x0080, 0x0000); 436 + } else { 437 + /* disable HID1 & detected_mode_change event */ 438 + rt712_sdca_index_update_bits(rt712, RT712_VENDOR_HDA_CTL, 439 + RT712_GE_RELATED_CTL1, 0x0c00, 0x0000); 440 + 441 + dev_dbg(&rt712->slave->dev, "in %s disable\n", __func__); 442 + } 443 + 444 + mutex_unlock(&rt712->calibrate_mutex); 445 + } 446 + 447 + static int rt712_sdca_set_jack_detect(struct snd_soc_component *component, 448 + struct snd_soc_jack *hs_jack, void *data) 449 + { 450 + struct rt712_sdca_priv *rt712 = snd_soc_component_get_drvdata(component); 451 + int ret; 452 + 453 + rt712->hs_jack = hs_jack; 454 + 455 + ret = pm_runtime_resume_and_get(component->dev); 456 + if (ret < 0) { 457 + if (ret != -EACCES) { 458 + dev_err(component->dev, "%s: failed to resume %d\n", __func__, ret); 459 + return ret; 460 + } 461 + 462 + /* pm_runtime not enabled yet */ 463 + dev_dbg(component->dev, "%s: skipping jack init for now\n", __func__); 464 + return 0; 465 + } 466 + 467 + rt712_sdca_jack_init(rt712); 468 + 469 + pm_runtime_mark_last_busy(component->dev); 470 + pm_runtime_put_autosuspend(component->dev); 471 + 472 + return 0; 473 + } 474 + 475 + /* For SDCA control DAC/ADC Gain */ 476 + static int rt712_sdca_set_gain_put(struct snd_kcontrol *kcontrol, 477 + struct snd_ctl_elem_value *ucontrol) 478 + { 479 + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); 480 + struct soc_mixer_control *mc = 481 + (struct soc_mixer_control *)kcontrol->private_value; 482 + struct rt712_sdca_priv *rt712 = snd_soc_component_get_drvdata(component); 483 + unsigned int read_l, read_r, gain_l_val, gain_r_val; 484 + unsigned int adc_vol_flag = 0; 485 + unsigned int lvalue, rvalue; 486 + const unsigned int interval_offset = 0xc0; 487 + const unsigned int tendB = 0xa00; 488 + 489 + if (strstr(ucontrol->id.name, "FU0F Capture Volume")) 490 + adc_vol_flag = 1; 491 + 492 + regmap_read(rt712->mbq_regmap, mc->reg, &lvalue); 493 + regmap_read(rt712->mbq_regmap, mc->rreg, &rvalue); 494 + 495 + /* L Channel */ 496 + gain_l_val = ucontrol->value.integer.value[0]; 497 + if (gain_l_val > mc->max) 498 + gain_l_val = mc->max; 499 + 500 + if (mc->shift == 8) /* boost gain */ 501 + gain_l_val = gain_l_val * tendB; 502 + else { 503 + /* ADC/DAC gain */ 504 + if (adc_vol_flag) 505 + gain_l_val = 0x1e00 - ((mc->max - gain_l_val) * interval_offset); 506 + else 507 + gain_l_val = 0 - ((mc->max - gain_l_val) * interval_offset); 508 + gain_l_val &= 0xffff; 509 + } 510 + 511 + /* R Channel */ 512 + gain_r_val = ucontrol->value.integer.value[1]; 513 + if (gain_r_val > mc->max) 514 + gain_r_val = mc->max; 515 + 516 + if (mc->shift == 8) /* boost gain */ 517 + gain_r_val = gain_r_val * tendB; 518 + else { 519 + /* ADC/DAC gain */ 520 + if (adc_vol_flag) 521 + gain_r_val = 0x1e00 - ((mc->max - gain_r_val) * interval_offset); 522 + else 523 + gain_r_val = 0 - ((mc->max - gain_r_val) * interval_offset); 524 + gain_r_val &= 0xffff; 525 + } 526 + 527 + if (lvalue == gain_l_val && rvalue == gain_r_val) 528 + return 0; 529 + 530 + /* Lch*/ 531 + regmap_write(rt712->mbq_regmap, mc->reg, gain_l_val); 532 + /* Rch */ 533 + regmap_write(rt712->mbq_regmap, mc->rreg, gain_r_val); 534 + 535 + regmap_read(rt712->mbq_regmap, mc->reg, &read_l); 536 + regmap_read(rt712->mbq_regmap, mc->rreg, &read_r); 537 + if (read_r == gain_r_val && read_l == gain_l_val) 538 + return 1; 539 + 540 + return -EIO; 541 + } 542 + 543 + static int rt712_sdca_set_gain_get(struct snd_kcontrol *kcontrol, 544 + struct snd_ctl_elem_value *ucontrol) 545 + { 546 + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); 547 + struct rt712_sdca_priv *rt712 = snd_soc_component_get_drvdata(component); 548 + struct soc_mixer_control *mc = 549 + (struct soc_mixer_control *)kcontrol->private_value; 550 + unsigned int read_l, read_r, ctl_l = 0, ctl_r = 0; 551 + unsigned int adc_vol_flag = 0; 552 + const unsigned int interval_offset = 0xc0; 553 + const unsigned int tendB = 0xa00; 554 + 555 + if (strstr(ucontrol->id.name, "FU0F Capture Volume")) 556 + adc_vol_flag = 1; 557 + 558 + regmap_read(rt712->mbq_regmap, mc->reg, &read_l); 559 + regmap_read(rt712->mbq_regmap, mc->rreg, &read_r); 560 + 561 + if (mc->shift == 8) /* boost gain */ 562 + ctl_l = read_l / tendB; 563 + else { 564 + if (adc_vol_flag) 565 + ctl_l = mc->max - (((0x1e00 - read_l) & 0xffff) / interval_offset); 566 + else 567 + ctl_l = mc->max - (((0 - read_l) & 0xffff) / interval_offset); 568 + } 569 + 570 + if (read_l != read_r) { 571 + if (mc->shift == 8) /* boost gain */ 572 + ctl_r = read_r / tendB; 573 + else { /* ADC/DAC gain */ 574 + if (adc_vol_flag) 575 + ctl_r = mc->max - (((0x1e00 - read_r) & 0xffff) / interval_offset); 576 + else 577 + ctl_r = mc->max - (((0 - read_r) & 0xffff) / interval_offset); 578 + } 579 + } else 580 + ctl_r = ctl_l; 581 + 582 + ucontrol->value.integer.value[0] = ctl_l; 583 + ucontrol->value.integer.value[1] = ctl_r; 584 + 585 + return 0; 586 + } 587 + 588 + static int rt712_sdca_set_fu0f_capture_ctl(struct rt712_sdca_priv *rt712) 589 + { 590 + int err; 591 + unsigned int ch_l, ch_r; 592 + 593 + ch_l = (rt712->fu0f_dapm_mute || rt712->fu0f_mixer_l_mute) ? 0x01 : 0x00; 594 + ch_r = (rt712->fu0f_dapm_mute || rt712->fu0f_mixer_r_mute) ? 0x01 : 0x00; 595 + 596 + err = regmap_write(rt712->regmap, 597 + SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT712_SDCA_ENT_USER_FU0F, 598 + RT712_SDCA_CTL_FU_MUTE, CH_L), ch_l); 599 + if (err < 0) 600 + return err; 601 + 602 + err = regmap_write(rt712->regmap, 603 + SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT712_SDCA_ENT_USER_FU0F, 604 + RT712_SDCA_CTL_FU_MUTE, CH_R), ch_r); 605 + if (err < 0) 606 + return err; 607 + 608 + return 0; 609 + } 610 + 611 + static int rt712_sdca_fu0f_capture_get(struct snd_kcontrol *kcontrol, 612 + struct snd_ctl_elem_value *ucontrol) 613 + { 614 + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); 615 + struct rt712_sdca_priv *rt712 = snd_soc_component_get_drvdata(component); 616 + 617 + ucontrol->value.integer.value[0] = !rt712->fu0f_mixer_l_mute; 618 + ucontrol->value.integer.value[1] = !rt712->fu0f_mixer_r_mute; 619 + return 0; 620 + } 621 + 622 + static int rt712_sdca_fu0f_capture_put(struct snd_kcontrol *kcontrol, 623 + struct snd_ctl_elem_value *ucontrol) 624 + { 625 + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); 626 + struct rt712_sdca_priv *rt712 = snd_soc_component_get_drvdata(component); 627 + int err; 628 + 629 + if (rt712->fu0f_mixer_l_mute == !ucontrol->value.integer.value[0] && 630 + rt712->fu0f_mixer_r_mute == !ucontrol->value.integer.value[1]) 631 + return 0; 632 + 633 + rt712->fu0f_mixer_l_mute = !ucontrol->value.integer.value[0]; 634 + rt712->fu0f_mixer_r_mute = !ucontrol->value.integer.value[1]; 635 + err = rt712_sdca_set_fu0f_capture_ctl(rt712); 636 + if (err < 0) 637 + return err; 638 + 639 + return 1; 640 + } 641 + 642 + static const DECLARE_TLV_DB_SCALE(out_vol_tlv, -6525, 75, 0); 643 + static const DECLARE_TLV_DB_SCALE(mic_vol_tlv, -1725, 75, 0); 644 + static const DECLARE_TLV_DB_SCALE(boost_vol_tlv, 0, 1000, 0); 645 + 646 + static const struct snd_kcontrol_new rt712_sdca_controls[] = { 647 + SOC_DOUBLE_R_EXT_TLV("FU05 Playback Volume", 648 + SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT712_SDCA_ENT_USER_FU05, RT712_SDCA_CTL_FU_VOLUME, CH_L), 649 + SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT712_SDCA_ENT_USER_FU05, RT712_SDCA_CTL_FU_VOLUME, CH_R), 650 + 0, 0x57, 0, 651 + rt712_sdca_set_gain_get, rt712_sdca_set_gain_put, out_vol_tlv), 652 + SOC_DOUBLE_EXT("FU0F Capture Switch", SND_SOC_NOPM, 0, 1, 1, 0, 653 + rt712_sdca_fu0f_capture_get, rt712_sdca_fu0f_capture_put), 654 + SOC_DOUBLE_R_EXT_TLV("FU0F Capture Volume", 655 + SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT712_SDCA_ENT_USER_FU0F, RT712_SDCA_CTL_FU_VOLUME, CH_L), 656 + SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT712_SDCA_ENT_USER_FU0F, RT712_SDCA_CTL_FU_VOLUME, CH_R), 657 + 0, 0x3f, 0, 658 + rt712_sdca_set_gain_get, rt712_sdca_set_gain_put, mic_vol_tlv), 659 + SOC_DOUBLE_R_EXT_TLV("FU44 Boost Volume", 660 + SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT712_SDCA_ENT_PLATFORM_FU44, RT712_SDCA_CTL_FU_CH_GAIN, CH_L), 661 + SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT712_SDCA_ENT_PLATFORM_FU44, RT712_SDCA_CTL_FU_CH_GAIN, CH_R), 662 + 8, 3, 0, 663 + rt712_sdca_set_gain_get, rt712_sdca_set_gain_put, boost_vol_tlv), 664 + }; 665 + 666 + static const struct snd_kcontrol_new rt712_sdca_spk_controls[] = { 667 + SOC_DOUBLE_R_EXT_TLV("FU06 Playback Volume", 668 + SDW_SDCA_CTL(FUNC_NUM_AMP, RT712_SDCA_ENT_USER_FU06, RT712_SDCA_CTL_FU_VOLUME, CH_L), 669 + SDW_SDCA_CTL(FUNC_NUM_AMP, RT712_SDCA_ENT_USER_FU06, RT712_SDCA_CTL_FU_VOLUME, CH_R), 670 + 0, 0x57, 0, 671 + rt712_sdca_set_gain_get, rt712_sdca_set_gain_put, out_vol_tlv), 672 + }; 673 + 674 + static int rt712_sdca_mux_get(struct snd_kcontrol *kcontrol, 675 + struct snd_ctl_elem_value *ucontrol) 676 + { 677 + struct snd_soc_component *component = 678 + snd_soc_dapm_kcontrol_component(kcontrol); 679 + struct rt712_sdca_priv *rt712 = snd_soc_component_get_drvdata(component); 680 + unsigned int val = 0, mask = 0x3300; 681 + 682 + rt712_sdca_index_read(rt712, RT712_VENDOR_HDA_CTL, RT712_MIXER_CTL1, &val); 683 + 684 + val = val & mask; 685 + switch (val) { 686 + case 0x3000: 687 + val = 1; 688 + break; 689 + case 0x0300: 690 + val = 0; 691 + break; 692 + } 693 + 694 + ucontrol->value.enumerated.item[0] = val; 695 + 696 + return 0; 697 + } 698 + 699 + static int rt712_sdca_mux_put(struct snd_kcontrol *kcontrol, 700 + struct snd_ctl_elem_value *ucontrol) 701 + { 702 + struct snd_soc_component *component = 703 + snd_soc_dapm_kcontrol_component(kcontrol); 704 + struct snd_soc_dapm_context *dapm = 705 + snd_soc_dapm_kcontrol_dapm(kcontrol); 706 + struct rt712_sdca_priv *rt712 = snd_soc_component_get_drvdata(component); 707 + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 708 + unsigned int *item = ucontrol->value.enumerated.item; 709 + unsigned int mask_sft; 710 + 711 + if (item[0] >= e->items) 712 + return -EINVAL; 713 + 714 + if (ucontrol->value.enumerated.item[0] == 0) 715 + mask_sft = 12; 716 + else if (ucontrol->value.enumerated.item[0] == 1) 717 + mask_sft = 8; 718 + else 719 + return -EINVAL; 720 + 721 + rt712_sdca_index_write(rt712, RT712_VENDOR_HDA_CTL, 722 + RT712_MIXER_CTL1, 0x3fff); 723 + rt712_sdca_index_update_bits(rt712, RT712_VENDOR_HDA_CTL, 724 + RT712_MIXER_CTL1, 0x3 << mask_sft, 0); 725 + 726 + snd_soc_dapm_mux_update_power(dapm, kcontrol, 727 + item[0], e, NULL); 728 + 729 + return 1; 730 + } 731 + 732 + static const char * const adc_mux_text[] = { 733 + "MIC2", 734 + "LINE2", 735 + }; 736 + 737 + static SOC_ENUM_SINGLE_DECL( 738 + rt712_adc23_enum, SND_SOC_NOPM, 0, adc_mux_text); 739 + 740 + static const struct snd_kcontrol_new rt712_sdca_adc23_mux = 741 + SOC_DAPM_ENUM_EXT("ADC 23 Mux", rt712_adc23_enum, 742 + rt712_sdca_mux_get, rt712_sdca_mux_put); 743 + 744 + static int rt712_sdca_fu05_event(struct snd_soc_dapm_widget *w, 745 + struct snd_kcontrol *kcontrol, int event) 746 + { 747 + struct snd_soc_component *component = 748 + snd_soc_dapm_to_component(w->dapm); 749 + struct rt712_sdca_priv *rt712 = snd_soc_component_get_drvdata(component); 750 + unsigned char unmute = 0x0, mute = 0x1; 751 + 752 + switch (event) { 753 + case SND_SOC_DAPM_POST_PMU: 754 + regmap_write(rt712->regmap, 755 + SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT712_SDCA_ENT_USER_FU05, 756 + RT712_SDCA_CTL_FU_MUTE, CH_L), 757 + unmute); 758 + regmap_write(rt712->regmap, 759 + SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT712_SDCA_ENT_USER_FU05, 760 + RT712_SDCA_CTL_FU_MUTE, CH_R), 761 + unmute); 762 + break; 763 + case SND_SOC_DAPM_PRE_PMD: 764 + regmap_write(rt712->regmap, 765 + SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT712_SDCA_ENT_USER_FU05, 766 + RT712_SDCA_CTL_FU_MUTE, CH_L), 767 + mute); 768 + regmap_write(rt712->regmap, 769 + SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT712_SDCA_ENT_USER_FU05, 770 + RT712_SDCA_CTL_FU_MUTE, CH_R), 771 + mute); 772 + break; 773 + } 774 + return 0; 775 + } 776 + 777 + static int rt712_sdca_fu0f_event(struct snd_soc_dapm_widget *w, 778 + struct snd_kcontrol *kcontrol, int event) 779 + { 780 + struct snd_soc_component *component = 781 + snd_soc_dapm_to_component(w->dapm); 782 + struct rt712_sdca_priv *rt712 = snd_soc_component_get_drvdata(component); 783 + 784 + switch (event) { 785 + case SND_SOC_DAPM_POST_PMU: 786 + rt712->fu0f_dapm_mute = false; 787 + rt712_sdca_set_fu0f_capture_ctl(rt712); 788 + break; 789 + case SND_SOC_DAPM_PRE_PMD: 790 + rt712->fu0f_dapm_mute = true; 791 + rt712_sdca_set_fu0f_capture_ctl(rt712); 792 + break; 793 + } 794 + return 0; 795 + } 796 + 797 + static int rt712_sdca_pde40_event(struct snd_soc_dapm_widget *w, 798 + struct snd_kcontrol *kcontrol, int event) 799 + { 800 + struct snd_soc_component *component = 801 + snd_soc_dapm_to_component(w->dapm); 802 + struct rt712_sdca_priv *rt712 = snd_soc_component_get_drvdata(component); 803 + unsigned char ps0 = 0x0, ps3 = 0x3; 804 + 805 + switch (event) { 806 + case SND_SOC_DAPM_POST_PMU: 807 + regmap_write(rt712->regmap, 808 + SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT712_SDCA_ENT_PDE40, 809 + RT712_SDCA_CTL_REQ_POWER_STATE, 0), 810 + ps0); 811 + break; 812 + case SND_SOC_DAPM_PRE_PMD: 813 + regmap_write(rt712->regmap, 814 + SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT712_SDCA_ENT_PDE40, 815 + RT712_SDCA_CTL_REQ_POWER_STATE, 0), 816 + ps3); 817 + break; 818 + } 819 + return 0; 820 + } 821 + 822 + static int rt712_sdca_pde12_event(struct snd_soc_dapm_widget *w, 823 + struct snd_kcontrol *kcontrol, int event) 824 + { 825 + struct snd_soc_component *component = 826 + snd_soc_dapm_to_component(w->dapm); 827 + struct rt712_sdca_priv *rt712 = snd_soc_component_get_drvdata(component); 828 + unsigned char ps0 = 0x0, ps3 = 0x3; 829 + 830 + switch (event) { 831 + case SND_SOC_DAPM_POST_PMU: 832 + regmap_write(rt712->regmap, 833 + SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT712_SDCA_ENT_PDE12, 834 + RT712_SDCA_CTL_REQ_POWER_STATE, 0), 835 + ps0); 836 + break; 837 + case SND_SOC_DAPM_PRE_PMD: 838 + regmap_write(rt712->regmap, 839 + SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT712_SDCA_ENT_PDE12, 840 + RT712_SDCA_CTL_REQ_POWER_STATE, 0), 841 + ps3); 842 + break; 843 + } 844 + return 0; 845 + } 846 + 847 + static int rt712_sdca_classd_event(struct snd_soc_dapm_widget *w, 848 + struct snd_kcontrol *kcontrol, int event) 849 + { 850 + struct snd_soc_component *component = 851 + snd_soc_dapm_to_component(w->dapm); 852 + struct rt712_sdca_priv *rt712 = snd_soc_component_get_drvdata(component); 853 + unsigned char ps0 = 0x0, ps3 = 0x3; 854 + 855 + switch (event) { 856 + case SND_SOC_DAPM_POST_PMU: 857 + regmap_write(rt712->regmap, 858 + SDW_SDCA_CTL(FUNC_NUM_AMP, RT712_SDCA_ENT_PDE23, 859 + RT712_SDCA_CTL_REQ_POWER_STATE, 0), 860 + ps0); 861 + break; 862 + case SND_SOC_DAPM_PRE_PMD: 863 + regmap_write(rt712->regmap, 864 + SDW_SDCA_CTL(FUNC_NUM_AMP, RT712_SDCA_ENT_PDE23, 865 + RT712_SDCA_CTL_REQ_POWER_STATE, 0), 866 + ps3); 867 + break; 868 + 869 + default: 870 + break; 871 + } 872 + 873 + return 0; 874 + } 875 + 876 + static const struct snd_kcontrol_new rt712_spk_sto_dac = 877 + SOC_DAPM_DOUBLE_R("Switch", 878 + SDW_SDCA_CTL(FUNC_NUM_AMP, RT712_SDCA_ENT_USER_FU06, RT712_SDCA_CTL_FU_MUTE, CH_L), 879 + SDW_SDCA_CTL(FUNC_NUM_AMP, RT712_SDCA_ENT_USER_FU06, RT712_SDCA_CTL_FU_MUTE, CH_R), 880 + 0, 1, 1); 881 + 882 + static const struct snd_soc_dapm_widget rt712_sdca_dapm_widgets[] = { 883 + SND_SOC_DAPM_OUTPUT("HP"), 884 + SND_SOC_DAPM_INPUT("MIC2"), 885 + SND_SOC_DAPM_INPUT("LINE2"), 886 + 887 + SND_SOC_DAPM_SUPPLY("PDE 40", SND_SOC_NOPM, 0, 0, 888 + rt712_sdca_pde40_event, 889 + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), 890 + SND_SOC_DAPM_SUPPLY("PDE 12", SND_SOC_NOPM, 0, 0, 891 + rt712_sdca_pde12_event, 892 + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), 893 + 894 + SND_SOC_DAPM_DAC_E("FU 05", NULL, SND_SOC_NOPM, 0, 0, 895 + rt712_sdca_fu05_event, 896 + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), 897 + SND_SOC_DAPM_ADC_E("FU 0F", NULL, SND_SOC_NOPM, 0, 0, 898 + rt712_sdca_fu0f_event, 899 + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), 900 + SND_SOC_DAPM_MUX("ADC 23 Mux", SND_SOC_NOPM, 0, 0, 901 + &rt712_sdca_adc23_mux), 902 + 903 + SND_SOC_DAPM_AIF_IN("DP1RX", "DP1 Playback", 0, SND_SOC_NOPM, 0, 0), 904 + SND_SOC_DAPM_AIF_OUT("DP4TX", "DP4 Capture", 0, SND_SOC_NOPM, 0, 0), 905 + }; 906 + 907 + static const struct snd_soc_dapm_route rt712_sdca_audio_map[] = { 908 + { "FU 05", NULL, "DP1RX" }, 909 + { "DP4TX", NULL, "FU 0F" }, 910 + 911 + { "FU 0F", NULL, "PDE 12" }, 912 + { "FU 0F", NULL, "ADC 23 Mux" }, 913 + { "ADC 23 Mux", "LINE2", "LINE2" }, 914 + { "ADC 23 Mux", "MIC2", "MIC2" }, 915 + 916 + { "HP", NULL, "PDE 40" }, 917 + { "HP", NULL, "FU 05" }, 918 + }; 919 + 920 + static const struct snd_soc_dapm_widget rt712_sdca_spk_dapm_widgets[] = { 921 + SND_SOC_DAPM_AIF_IN("DP3RX", "DP3 Playback", 0, SND_SOC_NOPM, 0, 0), 922 + 923 + /* Digital Interface */ 924 + SND_SOC_DAPM_SWITCH("FU06", SND_SOC_NOPM, 0, 0, &rt712_spk_sto_dac), 925 + 926 + /* Output */ 927 + SND_SOC_DAPM_PGA_E("CLASS D", SND_SOC_NOPM, 0, 0, NULL, 0, 928 + rt712_sdca_classd_event, SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), 929 + SND_SOC_DAPM_OUTPUT("SPOL"), 930 + SND_SOC_DAPM_OUTPUT("SPOR"), 931 + }; 932 + 933 + static const struct snd_soc_dapm_route rt712_sdca_spk_dapm_routes[] = { 934 + { "FU06", "Switch", "DP3RX" }, 935 + { "CLASS D", NULL, "FU06" }, 936 + { "SPOL", NULL, "CLASS D" }, 937 + { "SPOR", NULL, "CLASS D" }, 938 + }; 939 + 940 + static int rt712_sdca_parse_dt(struct rt712_sdca_priv *rt712, struct device *dev) 941 + { 942 + device_property_read_u32(dev, "realtek,jd-src", &rt712->jd_src); 943 + 944 + return 0; 945 + } 946 + 947 + static int rt712_sdca_probe(struct snd_soc_component *component) 948 + { 949 + struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); 950 + struct rt712_sdca_priv *rt712 = snd_soc_component_get_drvdata(component); 951 + int ret; 952 + 953 + rt712_sdca_parse_dt(rt712, &rt712->slave->dev); 954 + rt712->component = component; 955 + 956 + ret = pm_runtime_resume(component->dev); 957 + if (ret < 0 && ret != -EACCES) 958 + return ret; 959 + 960 + /* add SPK route */ 961 + if (rt712->hw_id != RT712_DEV_ID_713) { 962 + snd_soc_add_component_controls(component, 963 + rt712_sdca_spk_controls, ARRAY_SIZE(rt712_sdca_spk_controls)); 964 + snd_soc_dapm_new_controls(dapm, 965 + rt712_sdca_spk_dapm_widgets, ARRAY_SIZE(rt712_sdca_spk_dapm_widgets)); 966 + snd_soc_dapm_add_routes(dapm, 967 + rt712_sdca_spk_dapm_routes, ARRAY_SIZE(rt712_sdca_spk_dapm_routes)); 968 + } 969 + 970 + return 0; 971 + } 972 + 973 + static const struct snd_soc_component_driver soc_sdca_dev_rt712 = { 974 + .probe = rt712_sdca_probe, 975 + .controls = rt712_sdca_controls, 976 + .num_controls = ARRAY_SIZE(rt712_sdca_controls), 977 + .dapm_widgets = rt712_sdca_dapm_widgets, 978 + .num_dapm_widgets = ARRAY_SIZE(rt712_sdca_dapm_widgets), 979 + .dapm_routes = rt712_sdca_audio_map, 980 + .num_dapm_routes = ARRAY_SIZE(rt712_sdca_audio_map), 981 + .set_jack = rt712_sdca_set_jack_detect, 982 + .endianness = 1, 983 + }; 984 + 985 + static int rt712_sdca_set_sdw_stream(struct snd_soc_dai *dai, void *sdw_stream, 986 + int direction) 987 + { 988 + struct sdw_stream_data *stream; 989 + 990 + if (!sdw_stream) 991 + return 0; 992 + 993 + stream = kzalloc(sizeof(*stream), GFP_KERNEL); 994 + if (!stream) 995 + return -ENOMEM; 996 + 997 + stream->sdw_stream = sdw_stream; 998 + 999 + /* Use tx_mask or rx_mask to configure stream tag and set dma_data */ 1000 + snd_soc_dai_dma_data_set(dai, direction, stream); 1001 + 1002 + return 0; 1003 + } 1004 + 1005 + static void rt712_sdca_shutdown(struct snd_pcm_substream *substream, 1006 + struct snd_soc_dai *dai) 1007 + { 1008 + struct sdw_stream_data *stream; 1009 + 1010 + stream = snd_soc_dai_get_dma_data(dai, substream); 1011 + snd_soc_dai_set_dma_data(dai, substream, NULL); 1012 + kfree(stream); 1013 + } 1014 + 1015 + static int rt712_sdca_pcm_hw_params(struct snd_pcm_substream *substream, 1016 + struct snd_pcm_hw_params *params, 1017 + struct snd_soc_dai *dai) 1018 + { 1019 + struct snd_soc_component *component = dai->component; 1020 + struct rt712_sdca_priv *rt712 = snd_soc_component_get_drvdata(component); 1021 + struct sdw_stream_config stream_config; 1022 + struct sdw_port_config port_config; 1023 + enum sdw_data_direction direction; 1024 + struct sdw_stream_data *stream; 1025 + int retval, port, num_channels; 1026 + unsigned int sampling_rate; 1027 + 1028 + dev_dbg(dai->dev, "%s %s", __func__, dai->name); 1029 + stream = snd_soc_dai_get_dma_data(dai, substream); 1030 + 1031 + if (!stream) 1032 + return -EINVAL; 1033 + 1034 + if (!rt712->slave) 1035 + return -EINVAL; 1036 + 1037 + /* SoundWire specific configuration */ 1038 + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 1039 + direction = SDW_DATA_DIR_RX; 1040 + if (dai->id == RT712_AIF1) 1041 + port = 1; 1042 + else if (dai->id == RT712_AIF2) 1043 + port = 3; 1044 + else 1045 + return -EINVAL; 1046 + } else { 1047 + direction = SDW_DATA_DIR_TX; 1048 + if (dai->id == RT712_AIF1) 1049 + port = 4; 1050 + else 1051 + return -EINVAL; 1052 + } 1053 + 1054 + stream_config.frame_rate = params_rate(params); 1055 + stream_config.ch_count = params_channels(params); 1056 + stream_config.bps = snd_pcm_format_width(params_format(params)); 1057 + stream_config.direction = direction; 1058 + 1059 + num_channels = params_channels(params); 1060 + port_config.ch_mask = GENMASK(num_channels - 1, 0); 1061 + port_config.num = port; 1062 + 1063 + retval = sdw_stream_add_slave(rt712->slave, &stream_config, 1064 + &port_config, 1, stream->sdw_stream); 1065 + if (retval) { 1066 + dev_err(dai->dev, "Unable to configure port\n"); 1067 + return retval; 1068 + } 1069 + 1070 + if (params_channels(params) > 16) { 1071 + dev_err(component->dev, "Unsupported channels %d\n", 1072 + params_channels(params)); 1073 + return -EINVAL; 1074 + } 1075 + 1076 + /* sampling rate configuration */ 1077 + switch (params_rate(params)) { 1078 + case 44100: 1079 + sampling_rate = RT712_SDCA_RATE_44100HZ; 1080 + break; 1081 + case 48000: 1082 + sampling_rate = RT712_SDCA_RATE_48000HZ; 1083 + break; 1084 + case 96000: 1085 + sampling_rate = RT712_SDCA_RATE_96000HZ; 1086 + break; 1087 + case 192000: 1088 + sampling_rate = RT712_SDCA_RATE_192000HZ; 1089 + break; 1090 + default: 1091 + dev_err(component->dev, "Rate %d is not supported\n", 1092 + params_rate(params)); 1093 + return -EINVAL; 1094 + } 1095 + 1096 + /* set sampling frequency */ 1097 + if (dai->id == RT712_AIF1) { 1098 + regmap_write(rt712->regmap, 1099 + SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT712_SDCA_ENT_CS01, RT712_SDCA_CTL_SAMPLE_FREQ_INDEX, 0), 1100 + sampling_rate); 1101 + regmap_write(rt712->regmap, 1102 + SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT712_SDCA_ENT_CS11, RT712_SDCA_CTL_SAMPLE_FREQ_INDEX, 0), 1103 + sampling_rate); 1104 + } 1105 + 1106 + if (dai->id == RT712_AIF2) 1107 + regmap_write(rt712->regmap, 1108 + SDW_SDCA_CTL(FUNC_NUM_AMP, RT712_SDCA_ENT_CS31, RT712_SDCA_CTL_SAMPLE_FREQ_INDEX, 0), 1109 + sampling_rate); 1110 + 1111 + return 0; 1112 + } 1113 + 1114 + static int rt712_sdca_pcm_hw_free(struct snd_pcm_substream *substream, 1115 + struct snd_soc_dai *dai) 1116 + { 1117 + struct snd_soc_component *component = dai->component; 1118 + struct rt712_sdca_priv *rt712 = snd_soc_component_get_drvdata(component); 1119 + struct sdw_stream_data *stream = 1120 + snd_soc_dai_get_dma_data(dai, substream); 1121 + 1122 + if (!rt712->slave) 1123 + return -EINVAL; 1124 + 1125 + sdw_stream_remove_slave(rt712->slave, stream->sdw_stream); 1126 + return 0; 1127 + } 1128 + 1129 + #define RT712_STEREO_RATES (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 | \ 1130 + SNDRV_PCM_RATE_192000) 1131 + #define RT712_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \ 1132 + SNDRV_PCM_FMTBIT_S24_LE) 1133 + 1134 + static const struct snd_soc_dai_ops rt712_sdca_ops = { 1135 + .hw_params = rt712_sdca_pcm_hw_params, 1136 + .hw_free = rt712_sdca_pcm_hw_free, 1137 + .set_stream = rt712_sdca_set_sdw_stream, 1138 + .shutdown = rt712_sdca_shutdown, 1139 + }; 1140 + 1141 + static struct snd_soc_dai_driver rt712_sdca_dai[] = { 1142 + { 1143 + .name = "rt712-sdca-aif1", 1144 + .id = RT712_AIF1, 1145 + .playback = { 1146 + .stream_name = "DP1 Playback", 1147 + .channels_min = 1, 1148 + .channels_max = 2, 1149 + .rates = RT712_STEREO_RATES, 1150 + .formats = RT712_FORMATS, 1151 + }, 1152 + .capture = { 1153 + .stream_name = "DP4 Capture", 1154 + .channels_min = 1, 1155 + .channels_max = 2, 1156 + .rates = RT712_STEREO_RATES, 1157 + .formats = RT712_FORMATS, 1158 + }, 1159 + .ops = &rt712_sdca_ops, 1160 + }, 1161 + { 1162 + .name = "rt712-sdca-aif2", 1163 + .id = RT712_AIF2, 1164 + .playback = { 1165 + .stream_name = "DP3 Playback", 1166 + .channels_min = 1, 1167 + .channels_max = 2, 1168 + .rates = RT712_STEREO_RATES, 1169 + .formats = RT712_FORMATS, 1170 + }, 1171 + .ops = &rt712_sdca_ops, 1172 + } 1173 + }; 1174 + 1175 + int rt712_sdca_init(struct device *dev, struct regmap *regmap, 1176 + struct regmap *mbq_regmap, struct sdw_slave *slave) 1177 + { 1178 + struct rt712_sdca_priv *rt712; 1179 + int ret; 1180 + 1181 + rt712 = devm_kzalloc(dev, sizeof(*rt712), GFP_KERNEL); 1182 + if (!rt712) 1183 + return -ENOMEM; 1184 + 1185 + dev_set_drvdata(dev, rt712); 1186 + rt712->slave = slave; 1187 + rt712->regmap = regmap; 1188 + rt712->mbq_regmap = mbq_regmap; 1189 + 1190 + mutex_init(&rt712->calibrate_mutex); 1191 + mutex_init(&rt712->disable_irq_lock); 1192 + 1193 + INIT_DELAYED_WORK(&rt712->jack_detect_work, rt712_sdca_jack_detect_handler); 1194 + INIT_DELAYED_WORK(&rt712->jack_btn_check_work, rt712_sdca_btn_check_handler); 1195 + 1196 + /* 1197 + * Mark hw_init to false 1198 + * HW init will be performed when device reports present 1199 + */ 1200 + rt712->hw_init = false; 1201 + rt712->first_hw_init = false; 1202 + rt712->fu0f_dapm_mute = true; 1203 + rt712->fu0f_mixer_l_mute = rt712->fu0f_mixer_r_mute = true; 1204 + 1205 + /* JD source uses JD1 in default */ 1206 + rt712->jd_src = RT712_JD1; 1207 + 1208 + if (slave->id.part_id != RT712_PART_ID_713) 1209 + ret = devm_snd_soc_register_component(dev, 1210 + &soc_sdca_dev_rt712, rt712_sdca_dai, ARRAY_SIZE(rt712_sdca_dai)); 1211 + else 1212 + ret = devm_snd_soc_register_component(dev, 1213 + &soc_sdca_dev_rt712, rt712_sdca_dai, 1); 1214 + 1215 + dev_dbg(&slave->dev, "%s\n", __func__); 1216 + 1217 + return ret; 1218 + } 1219 + 1220 + int rt712_sdca_io_init(struct device *dev, struct sdw_slave *slave) 1221 + { 1222 + struct rt712_sdca_priv *rt712 = dev_get_drvdata(dev); 1223 + int ret = 0; 1224 + unsigned int val, hibernation_flag; 1225 + 1226 + rt712->disable_irq = false; 1227 + 1228 + if (rt712->hw_init) 1229 + return 0; 1230 + 1231 + if (rt712->first_hw_init) { 1232 + regcache_cache_only(rt712->regmap, false); 1233 + regcache_cache_bypass(rt712->regmap, true); 1234 + regcache_cache_only(rt712->mbq_regmap, false); 1235 + regcache_cache_bypass(rt712->mbq_regmap, true); 1236 + } else { 1237 + /* 1238 + * PM runtime is only enabled when a Slave reports as Attached 1239 + */ 1240 + 1241 + /* set autosuspend parameters */ 1242 + pm_runtime_set_autosuspend_delay(&slave->dev, 3000); 1243 + pm_runtime_use_autosuspend(&slave->dev); 1244 + 1245 + /* update count of parent 'active' children */ 1246 + pm_runtime_set_active(&slave->dev); 1247 + 1248 + /* make sure the device does not suspend immediately */ 1249 + pm_runtime_mark_last_busy(&slave->dev); 1250 + 1251 + pm_runtime_enable(&slave->dev); 1252 + } 1253 + 1254 + pm_runtime_get_noresume(&slave->dev); 1255 + 1256 + rt712_sdca_index_read(rt712, RT712_VENDOR_REG, RT712_JD_PRODUCT_NUM, &val); 1257 + rt712->hw_id = (val & 0xf000) >> 12; 1258 + 1259 + rt712_sdca_index_write(rt712, RT712_VENDOR_REG, RT712_ANALOG_BIAS_CTL3, 0xaa81); 1260 + rt712_sdca_index_write(rt712, RT712_VENDOR_REG, RT712_LDO2_3_CTL1, 0xa1e0); 1261 + rt712_sdca_index_write(rt712, RT712_VENDOR_IMS_DRE, RT712_HP_DETECT_RLDET_CTL1, 0x0000); 1262 + rt712_sdca_index_write(rt712, RT712_VENDOR_IMS_DRE, RT712_HP_DETECT_RLDET_CTL2, 0x0000); 1263 + rt712_sdca_index_write(rt712, RT712_VENDOR_ANALOG_CTL, RT712_MISC_POWER_CTL7, 0x0000); 1264 + regmap_write(rt712->regmap, RT712_RC_CAL, 0x23); 1265 + 1266 + /* calibration */ 1267 + rt712_sdca_index_read(rt712, RT712_VENDOR_REG, RT712_SW_CONFIG1, &hibernation_flag); 1268 + if (!hibernation_flag) { 1269 + ret = rt712_sdca_calibration(rt712); 1270 + if (ret < 0) 1271 + dev_err(dev, "%s, calibration failed!\n", __func__); 1272 + } 1273 + 1274 + rt712_sdca_index_update_bits(rt712, RT712_VENDOR_HDA_CTL, 1275 + RT712_MIXER_CTL1, 0x3000, 0x0000); 1276 + rt712_sdca_index_write(rt712, RT712_VENDOR_HDA_CTL, 1277 + RT712_ADC0A_08_PDE_FLOAT_CTL, 0x1112); 1278 + rt712_sdca_index_write(rt712, RT712_VENDOR_HDA_CTL, 1279 + RT712_MIC2_LINE2_PDE_FLOAT_CTL, 0x3412); 1280 + rt712_sdca_index_write(rt712, RT712_VENDOR_HDA_CTL, 1281 + RT712_DAC03_HP_PDE_FLOAT_CTL, 0x4040); 1282 + 1283 + rt712_sdca_index_update_bits(rt712, RT712_VENDOR_HDA_CTL, 1284 + RT712_HDA_LEGACY_GPIO_WAKE_EN_CTL, 0x0001, 0x0000); 1285 + regmap_write(rt712->regmap, 0x2f50, 0x00); 1286 + regmap_write(rt712->regmap, 0x2f54, 0x00); 1287 + regmap_write(rt712->regmap, 1288 + SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT712_SDCA_ENT_IT09, RT712_SDCA_CTL_VENDOR_DEF, 0), 0x01); 1289 + 1290 + /* add SPK settings */ 1291 + if (rt712->hw_id != RT712_DEV_ID_713) { 1292 + rt712_sdca_index_write(rt712, RT712_VENDOR_HDA_CTL, RT712_AMP_PDE_FLOAT_CTL, 0x2323); 1293 + rt712_sdca_index_write(rt712, RT712_VENDOR_HDA_CTL, RT712_EAPD_CTL, 0x0002); 1294 + regmap_write(rt712->regmap, 1295 + SDW_SDCA_CTL(FUNC_NUM_AMP, RT712_SDCA_ENT_OT23, RT712_SDCA_CTL_VENDOR_DEF, 0), 0x04); 1296 + } 1297 + 1298 + /* 1299 + * if set_jack callback occurred early than io_init, 1300 + * we set up the jack detection function now 1301 + */ 1302 + if (rt712->hs_jack) 1303 + rt712_sdca_jack_init(rt712); 1304 + 1305 + if (!hibernation_flag) 1306 + rt712_sdca_index_write(rt712, RT712_VENDOR_REG, RT712_SW_CONFIG1, 0x0001); 1307 + 1308 + if (rt712->first_hw_init) { 1309 + regcache_cache_bypass(rt712->regmap, false); 1310 + regcache_mark_dirty(rt712->regmap); 1311 + regcache_cache_bypass(rt712->mbq_regmap, false); 1312 + regcache_mark_dirty(rt712->mbq_regmap); 1313 + } else 1314 + rt712->first_hw_init = true; 1315 + 1316 + /* Mark Slave initialization complete */ 1317 + rt712->hw_init = true; 1318 + 1319 + pm_runtime_mark_last_busy(&slave->dev); 1320 + pm_runtime_put_autosuspend(&slave->dev); 1321 + 1322 + dev_dbg(&slave->dev, "%s hw_init complete\n", __func__); 1323 + return 0; 1324 + } 1325 + 1326 + MODULE_DESCRIPTION("ASoC RT712 SDCA SDW driver"); 1327 + MODULE_AUTHOR("Shuming Fan <shumingf@realtek.com>"); 1328 + MODULE_LICENSE("GPL");
+220
sound/soc/codecs/rt712-sdca.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-only */ 2 + /* 3 + * rt712-sdca.h -- RT712 SDCA ALSA SoC audio driver header 4 + * 5 + * Copyright(c) 2023 Realtek Semiconductor Corp. 6 + */ 7 + 8 + #ifndef __RT712_H__ 9 + #define __RT712_H__ 10 + 11 + #include <linux/pm.h> 12 + #include <linux/regmap.h> 13 + #include <linux/soundwire/sdw.h> 14 + #include <linux/soundwire/sdw_type.h> 15 + #include <sound/soc.h> 16 + #include <linux/workqueue.h> 17 + 18 + struct rt712_sdca_priv { 19 + struct regmap *regmap; 20 + struct regmap *mbq_regmap; 21 + struct snd_soc_component *component; 22 + struct sdw_slave *slave; 23 + enum sdw_slave_status status; 24 + struct sdw_bus_params params; 25 + bool hw_init; 26 + bool first_hw_init; 27 + struct snd_soc_jack *hs_jack; 28 + struct delayed_work jack_detect_work; 29 + struct delayed_work jack_btn_check_work; 30 + struct mutex calibrate_mutex; /* for headset calibration */ 31 + struct mutex disable_irq_lock; /* SDCA irq lock protection */ 32 + bool disable_irq; 33 + int jack_type; 34 + int jd_src; 35 + unsigned int scp_sdca_stat1; 36 + unsigned int scp_sdca_stat2; 37 + unsigned int hw_id; 38 + bool fu0f_dapm_mute; 39 + bool fu0f_mixer_l_mute; 40 + bool fu0f_mixer_r_mute; 41 + }; 42 + 43 + struct sdw_stream_data { 44 + struct sdw_stream_runtime *sdw_stream; 45 + }; 46 + 47 + /* NID */ 48 + #define RT712_VENDOR_REG 0x20 49 + #define RT712_VENDOR_CALI 0x58 50 + #define RT712_ULTRA_SOUND_DET 0x59 51 + #define RT712_VENDOR_IMS_DRE 0x5b 52 + #define RT712_VENDOR_ANALOG_CTL 0x5f 53 + #define RT712_VENDOR_HDA_CTL 0x61 54 + 55 + /* Index (NID:20h) */ 56 + #define RT712_JD_PRODUCT_NUM 0x00 57 + #define RT712_ANALOG_BIAS_CTL3 0x04 58 + #define RT712_LDO2_3_CTL1 0x0e 59 + #define RT712_PARA_VERB_CTL 0x1a 60 + #define RT712_CC_DET1 0x24 61 + #define RT712_COMBO_JACK_AUTO_CTL1 0x45 62 + #define RT712_COMBO_JACK_AUTO_CTL2 0x46 63 + #define RT712_COMBO_JACK_AUTO_CTL3 0x47 64 + #define RT712_DIGITAL_MISC_CTRL4 0x4a 65 + #define RT712_FSM_CTL 0x67 66 + #define RT712_SW_CONFIG1 0x8a 67 + #define RT712_SW_CONFIG2 0x8b 68 + 69 + /* Index (NID:58h) */ 70 + #define RT712_DAC_DC_CALI_CTL1 0x00 71 + #define RT712_DAC_DC_CALI_CTL2 0x01 72 + 73 + /* Index (NID:59h) */ 74 + #define RT712_ULTRA_SOUND_DETECTOR6 0x1e 75 + 76 + /* Index (NID:5bh) */ 77 + #define RT712_IMS_DIGITAL_CTL1 0x00 78 + #define RT712_IMS_DIGITAL_CTL5 0x05 79 + #define RT712_HP_DETECT_RLDET_CTL1 0x29 80 + #define RT712_HP_DETECT_RLDET_CTL2 0x2a 81 + 82 + /* Index (NID:5fh) */ 83 + #define RT712_MISC_POWER_CTL0 0x00 84 + #define RT712_MISC_POWER_CTL7 0x08 85 + 86 + /* Index (NID:61h) */ 87 + #define RT712_HDA_LEGACY_MUX_CTL0 0x00 88 + #define RT712_HDA_LEGACY_CONFIG_CTL0 0x06 89 + #define RT712_HDA_LEGACY_RESET_CTL 0x08 90 + #define RT712_HDA_LEGACY_GPIO_WAKE_EN_CTL 0x0e 91 + #define RT712_DMIC_ENT_FLOAT_CTL 0x10 92 + #define RT712_DMIC_GAIN_ENT_FLOAT_CTL0 0x11 93 + #define RT712_DMIC_GAIN_ENT_FLOAT_CTL2 0x13 94 + #define RT712_ADC_ENT_FLOAT_CTL 0x15 95 + #define RT712_ADC_VOL_CH_FLOAT_CTL2 0x18 96 + #define RT712_DAC03_HP_PDE_FLOAT_CTL 0x22 97 + #define RT712_MIC2_LINE2_PDE_FLOAT_CTL 0x23 98 + #define RT712_ADC0A_08_PDE_FLOAT_CTL 0x26 99 + #define RT712_ADC0B_11_PDE_FLOAT_CTL 0x27 100 + #define RT712_DMIC1_2_PDE_FLOAT_CTL 0x2b 101 + #define RT712_AMP_PDE_FLOAT_CTL 0x2c 102 + #define RT712_I2S_IN_OUT_PDE_FLOAT_CTL 0x2f 103 + #define RT712_GE_RELATED_CTL1 0x45 104 + #define RT712_GE_RELATED_CTL2 0x46 105 + #define RT712_MIXER_CTL0 0x52 106 + #define RT712_MIXER_CTL1 0x53 107 + #define RT712_EAPD_CTL 0x55 108 + #define RT712_UMP_HID_CTL0 0x60 109 + #define RT712_UMP_HID_CTL1 0x61 110 + #define RT712_UMP_HID_CTL2 0x62 111 + #define RT712_UMP_HID_CTL3 0x63 112 + #define RT712_UMP_HID_CTL4 0x64 113 + #define RT712_UMP_HID_CTL5 0x65 114 + #define RT712_UMP_HID_CTL6 0x66 115 + #define RT712_UMP_HID_CTL7 0x67 116 + #define RT712_UMP_HID_CTL8 0x68 117 + 118 + /* Parameter & Verb control 01 (0x1a)(NID:20h) */ 119 + #define RT712_HIDDEN_REG_SW_RESET (0x1 << 14) 120 + 121 + /* combo jack auto switch control 2 (0x46)(NID:20h) */ 122 + #define RT712_COMBOJACK_AUTO_DET_STATUS (0x1 << 11) 123 + #define RT712_COMBOJACK_AUTO_DET_TRS (0x1 << 10) 124 + #define RT712_COMBOJACK_AUTO_DET_CTIA (0x1 << 9) 125 + #define RT712_COMBOJACK_AUTO_DET_OMTP (0x1 << 8) 126 + 127 + /* DAC DC offset calibration control-1 (0x00)(NID:58h) */ 128 + #define RT712_DAC_DC_CALI_TRIGGER (0x1 << 15) 129 + 130 + #define RT712_EAPD_HIGH 0x2 131 + #define RT712_EAPD_LOW 0x0 132 + 133 + /* RC Calibration register */ 134 + #define RT712_RC_CAL 0x3201 135 + 136 + /* Buffer address for HID */ 137 + #define RT712_BUF_ADDR_HID1 0x44030000 138 + #define RT712_BUF_ADDR_HID2 0x44030020 139 + 140 + /* RT712 SDCA Control - function number */ 141 + #define FUNC_NUM_JACK_CODEC 0x01 142 + #define FUNC_NUM_MIC_ARRAY 0x02 143 + #define FUNC_NUM_HID 0x03 144 + #define FUNC_NUM_AMP 0x04 145 + 146 + /* RT712 SDCA entity */ 147 + #define RT712_SDCA_ENT_HID01 0x01 148 + #define RT712_SDCA_ENT_GE49 0x49 149 + #define RT712_SDCA_ENT_USER_FU05 0x05 150 + #define RT712_SDCA_ENT_USER_FU06 0x06 151 + #define RT712_SDCA_ENT_USER_FU0F 0x0f 152 + #define RT712_SDCA_ENT_USER_FU10 0x19 153 + #define RT712_SDCA_ENT_USER_FU1E 0x1e 154 + #define RT712_SDCA_ENT_FU15 0x15 155 + #define RT712_SDCA_ENT_PDE23 0x23 156 + #define RT712_SDCA_ENT_PDE40 0x40 157 + #define RT712_SDCA_ENT_PDE11 0x11 158 + #define RT712_SDCA_ENT_PDE12 0x12 159 + #define RT712_SDCA_ENT_CS01 0x01 160 + #define RT712_SDCA_ENT_CS11 0x11 161 + #define RT712_SDCA_ENT_CS1F 0x1f 162 + #define RT712_SDCA_ENT_CS1C 0x1c 163 + #define RT712_SDCA_ENT_CS31 0x31 164 + #define RT712_SDCA_ENT_OT23 0x42 165 + #define RT712_SDCA_ENT_IT26 0x26 166 + #define RT712_SDCA_ENT_IT09 0x09 167 + #define RT712_SDCA_ENT_PLATFORM_FU15 0x15 168 + #define RT712_SDCA_ENT_PLATFORM_FU44 0x44 169 + 170 + /* RT712 SDCA control */ 171 + #define RT712_SDCA_CTL_SAMPLE_FREQ_INDEX 0x10 172 + #define RT712_SDCA_CTL_FU_MUTE 0x01 173 + #define RT712_SDCA_CTL_FU_VOLUME 0x02 174 + #define RT712_SDCA_CTL_HIDTX_CURRENT_OWNER 0x10 175 + #define RT712_SDCA_CTL_HIDTX_SET_OWNER_TO_DEVICE 0x11 176 + #define RT712_SDCA_CTL_HIDTX_MESSAGE_OFFSET 0x12 177 + #define RT712_SDCA_CTL_HIDTX_MESSAGE_LENGTH 0x13 178 + #define RT712_SDCA_CTL_SELECTED_MODE 0x01 179 + #define RT712_SDCA_CTL_DETECTED_MODE 0x02 180 + #define RT712_SDCA_CTL_REQ_POWER_STATE 0x01 181 + #define RT712_SDCA_CTL_VENDOR_DEF 0x30 182 + #define RT712_SDCA_CTL_FU_CH_GAIN 0x0b 183 + 184 + /* RT712 SDCA channel */ 185 + #define CH_L 0x01 186 + #define CH_R 0x02 187 + 188 + /* sample frequency index */ 189 + #define RT712_SDCA_RATE_16000HZ 0x04 190 + #define RT712_SDCA_RATE_32000HZ 0x07 191 + #define RT712_SDCA_RATE_44100HZ 0x08 192 + #define RT712_SDCA_RATE_48000HZ 0x09 193 + #define RT712_SDCA_RATE_96000HZ 0x0b 194 + #define RT712_SDCA_RATE_192000HZ 0x0d 195 + 196 + enum { 197 + RT712_AIF1, 198 + RT712_AIF2, 199 + }; 200 + 201 + enum rt712_sdca_jd_src { 202 + RT712_JD_NULL, 203 + RT712_JD1, 204 + }; 205 + 206 + enum rt712_sdca_hw_id { 207 + RT712_DEV_ID_712 = 0x7, 208 + RT712_DEV_ID_713 = 0x6, 209 + RT712_DEV_ID_716 = 0x5, 210 + RT712_DEV_ID_717 = 0x4, 211 + }; 212 + 213 + #define RT712_PART_ID_713 0x713 214 + 215 + int rt712_sdca_io_init(struct device *dev, struct sdw_slave *slave); 216 + int rt712_sdca_init(struct device *dev, struct regmap *regmap, 217 + struct regmap *mbq_regmap, struct sdw_slave *slave); 218 + 219 + int rt712_sdca_jack_detect(struct rt712_sdca_priv *rt712, bool *hp, bool *mic); 220 + #endif /* __RT712_H__ */