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

ASoC: rt721-sdca: Add RT721 SDCA driver

This is the initial codec driver for rt721-sdca.
It's a three functions (jack,mic,amp) soundwire driver.

Signed-off-by: Jack Yu <jack.yu@realtek.com>

v2: Fix typo in mbq default registers.
v3: Include soundwire common functions for Realtek.
Link: https://patch.msgid.link/d18b35f8b6934fc6a2be6c4458a63fe5@realtek.com
Signed-off-by: Mark Brown <broonie@kernel.org>

authored by

Jack Yu and committed by
Mark Brown
86ce355c bbca8e70

+2525
+7
sound/soc/codecs/Kconfig
··· 222 222 imply SND_SOC_RT712_SDCA_DMIC_SDW 223 223 imply SND_SOC_RT715_SDW 224 224 imply SND_SOC_RT715_SDCA_SDW 225 + imply SND_SOC_RT721_SDCA_SDW 225 226 imply SND_SOC_RT722_SDCA_SDW 226 227 imply SND_SOC_RT1308_SDW 227 228 imply SND_SOC_RT1316_SDW ··· 1745 1744 1746 1745 config SND_SOC_RT712_SDCA_DMIC_SDW 1747 1746 tristate "Realtek RT712 SDCA DMIC Codec - SDW" 1747 + depends on SOUNDWIRE 1748 + select REGMAP_SOUNDWIRE 1749 + select REGMAP_SOUNDWIRE_MBQ 1750 + 1751 + config SND_SOC_RT721_SDCA_SDW 1752 + tristate "Realtek RT721 SDCA Codec - SDW" 1748 1753 depends on SOUNDWIRE 1749 1754 select REGMAP_SOUNDWIRE 1750 1755 select REGMAP_SOUNDWIRE_MBQ
+2
sound/soc/codecs/Makefile
··· 263 263 snd-soc-rt712-sdca-dmic-y := rt712-sdca-dmic.o 264 264 snd-soc-rt715-y := rt715.o rt715-sdw.o 265 265 snd-soc-rt715-sdca-y := rt715-sdca.o rt715-sdca-sdw.o 266 + snd-soc-rt721-sdca-y := rt721-sdca.o rt721-sdca-sdw.o 266 267 snd-soc-rt722-sdca-y := rt722-sdca.o rt722-sdca-sdw.o 267 268 snd-soc-rt9120-y := rt9120.o 268 269 snd-soc-rtq9128-y := rtq9128.o ··· 671 670 obj-$(CONFIG_SND_SOC_RT712_SDCA_DMIC_SDW) += snd-soc-rt712-sdca-dmic.o 672 671 obj-$(CONFIG_SND_SOC_RT715) += snd-soc-rt715.o 673 672 obj-$(CONFIG_SND_SOC_RT715_SDCA_SDW) += snd-soc-rt715-sdca.o 673 + obj-$(CONFIG_SND_SOC_RT721_SDCA_SDW) += snd-soc-rt721-sdca.o 674 674 obj-$(CONFIG_SND_SOC_RT722_SDCA_SDW) += snd-soc-rt722-sdca.o 675 675 obj-$(CONFIG_SND_SOC_RT9120) += snd-soc-rt9120.o 676 676 obj-$(CONFIG_SND_SOC_RTQ9128) += snd-soc-rtq9128.o
+551
sound/soc/codecs/rt721-sdca-sdw.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + // 3 + // rt721-sdca-sdw.c -- rt721 SDCA ALSA SoC audio driver 4 + // 5 + // Copyright(c) 2024 Realtek Semiconductor Corp. 6 + // 7 + // 8 + 9 + #include <linux/delay.h> 10 + #include <linux/device.h> 11 + #include <linux/module.h> 12 + #include <linux/mod_devicetable.h> 13 + #include <linux/pm_runtime.h> 14 + #include <linux/soundwire/sdw_registers.h> 15 + 16 + #include "rt721-sdca.h" 17 + #include "rt721-sdca-sdw.h" 18 + #include "rt-sdw-common.h" 19 + 20 + static bool rt721_sdca_readable_register(struct device *dev, unsigned int reg) 21 + { 22 + switch (reg) { 23 + case 0x2f01 ... 0x2f0a: 24 + case 0x2f35: 25 + case 0x2f50: 26 + case 0x2f51: 27 + case 0x2f58 ... 0x2f5d: 28 + case SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT721_SDCA_ENT_XUV, 29 + RT721_SDCA_CTL_XUV, 0): 30 + case SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT721_SDCA_ENT_GE49, 31 + RT721_SDCA_CTL_SELECTED_MODE, 0): 32 + case SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT721_SDCA_ENT_GE49, 33 + RT721_SDCA_CTL_DETECTED_MODE, 0): 34 + case SDW_SDCA_CTL(FUNC_NUM_HID, RT721_SDCA_ENT_HID01, 35 + RT721_SDCA_CTL_HIDTX_CURRENT_OWNER, 0) ... SDW_SDCA_CTL(FUNC_NUM_HID, 36 + RT721_SDCA_ENT_HID01, RT721_SDCA_CTL_HIDTX_MESSAGE_LENGTH, 0): 37 + case RT721_BUF_ADDR_HID1 ... RT721_BUF_ADDR_HID2: 38 + return true; 39 + default: 40 + return false; 41 + } 42 + } 43 + 44 + static bool rt721_sdca_volatile_register(struct device *dev, unsigned int reg) 45 + { 46 + switch (reg) { 47 + case 0x2f01: 48 + case 0x2f51: 49 + case SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT721_SDCA_ENT_GE49, 50 + RT721_SDCA_CTL_DETECTED_MODE, 0): 51 + case SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT721_SDCA_ENT_XUV, 52 + RT721_SDCA_CTL_XUV, 0): 53 + case SDW_SDCA_CTL(FUNC_NUM_HID, RT721_SDCA_ENT_HID01, 54 + RT721_SDCA_CTL_HIDTX_CURRENT_OWNER, 0) ... SDW_SDCA_CTL(FUNC_NUM_HID, 55 + RT721_SDCA_ENT_HID01, RT721_SDCA_CTL_HIDTX_MESSAGE_LENGTH, 0): 56 + case RT721_BUF_ADDR_HID1 ... RT721_BUF_ADDR_HID2: 57 + return true; 58 + default: 59 + return false; 60 + } 61 + } 62 + 63 + static bool rt721_sdca_mbq_readable_register(struct device *dev, unsigned int reg) 64 + { 65 + switch (reg) { 66 + case 0x0900007: 67 + case 0x0a00005: 68 + case 0x0c00005: 69 + case 0x0d00014: 70 + case 0x0310100: 71 + case 0x2000001: 72 + case 0x2000002: 73 + case 0x2000003: 74 + case 0x2000013: 75 + case 0x200003c: 76 + case 0x2000046: 77 + case 0x5810000: 78 + case 0x5810036: 79 + case 0x5810037: 80 + case 0x5810038: 81 + case 0x5810039: 82 + case 0x5b10018: 83 + case 0x5b10019: 84 + case 0x5f00045: 85 + case 0x5f00048: 86 + case 0x6100000: 87 + case 0x6100005: 88 + case 0x6100006: 89 + case 0x610000d: 90 + case 0x6100010: 91 + case 0x6100011: 92 + case 0x6100013: 93 + case 0x6100015: 94 + case 0x6100017: 95 + case 0x6100025: 96 + case 0x6100029: 97 + case 0x610002c ... 0x610002f: 98 + case 0x6100053 ... 0x6100055: 99 + case 0x6100057: 100 + case 0x610005a: 101 + case 0x610005b: 102 + case 0x610006a: 103 + case 0x610006d: 104 + case 0x6100092: 105 + case SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT721_SDCA_ENT_USER_FU05, RT721_SDCA_CTL_FU_VOLUME, 106 + CH_L): 107 + case SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT721_SDCA_ENT_USER_FU05, RT721_SDCA_CTL_FU_VOLUME, 108 + CH_R): 109 + case SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT721_SDCA_ENT_USER_FU0F, RT721_SDCA_CTL_FU_VOLUME, 110 + CH_L): 111 + case SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT721_SDCA_ENT_USER_FU0F, RT721_SDCA_CTL_FU_VOLUME, 112 + CH_R): 113 + case SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT721_SDCA_ENT_PLATFORM_FU44, 114 + RT721_SDCA_CTL_FU_CH_GAIN, CH_L): 115 + case SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT721_SDCA_ENT_PLATFORM_FU44, 116 + RT721_SDCA_CTL_FU_CH_GAIN, CH_R): 117 + case SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT721_SDCA_ENT_USER_FU1E, RT721_SDCA_CTL_FU_VOLUME, 118 + CH_01): 119 + case SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT721_SDCA_ENT_USER_FU1E, RT721_SDCA_CTL_FU_VOLUME, 120 + CH_02): 121 + case SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT721_SDCA_ENT_USER_FU1E, RT721_SDCA_CTL_FU_VOLUME, 122 + CH_03): 123 + case SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT721_SDCA_ENT_USER_FU1E, RT721_SDCA_CTL_FU_VOLUME, 124 + CH_04): 125 + case SDW_SDCA_CTL(FUNC_NUM_AMP, RT721_SDCA_ENT_USER_FU06, RT721_SDCA_CTL_FU_VOLUME, CH_L): 126 + case SDW_SDCA_CTL(FUNC_NUM_AMP, RT721_SDCA_ENT_USER_FU06, RT721_SDCA_CTL_FU_VOLUME, CH_R): 127 + return true; 128 + default: 129 + return false; 130 + } 131 + } 132 + 133 + static bool rt721_sdca_mbq_volatile_register(struct device *dev, unsigned int reg) 134 + { 135 + switch (reg) { 136 + case 0x0310100: 137 + case 0x0a00005: 138 + case 0x0c00005: 139 + case 0x0d00014: 140 + case 0x2000000: 141 + case 0x200000d: 142 + case 0x2000019: 143 + case 0x2000020: 144 + case 0x2000030: 145 + case 0x2000046: 146 + case 0x2000067: 147 + case 0x2000084: 148 + case 0x2000086: 149 + case 0x5810000: 150 + case 0x5810036: 151 + case 0x5810037: 152 + case 0x5810038: 153 + case 0x5810039: 154 + case 0x5b10018: 155 + case 0x5b10019: 156 + return true; 157 + default: 158 + return false; 159 + } 160 + } 161 + 162 + static const struct regmap_config rt721_sdca_regmap = { 163 + .reg_bits = 32, 164 + .val_bits = 8, 165 + .readable_reg = rt721_sdca_readable_register, 166 + .volatile_reg = rt721_sdca_volatile_register, 167 + .max_register = 0x44ffffff, 168 + .reg_defaults = rt721_sdca_reg_defaults, 169 + .num_reg_defaults = ARRAY_SIZE(rt721_sdca_reg_defaults), 170 + .cache_type = REGCACHE_MAPLE, 171 + .use_single_read = true, 172 + .use_single_write = true, 173 + }; 174 + 175 + static const struct regmap_config rt721_sdca_mbq_regmap = { 176 + .name = "sdw-mbq", 177 + .reg_bits = 32, 178 + .val_bits = 16, 179 + .readable_reg = rt721_sdca_mbq_readable_register, 180 + .volatile_reg = rt721_sdca_mbq_volatile_register, 181 + .max_register = 0x41000312, 182 + .reg_defaults = rt721_sdca_mbq_defaults, 183 + .num_reg_defaults = ARRAY_SIZE(rt721_sdca_mbq_defaults), 184 + .cache_type = REGCACHE_MAPLE, 185 + .use_single_read = true, 186 + .use_single_write = true, 187 + }; 188 + 189 + static int rt721_sdca_update_status(struct sdw_slave *slave, 190 + enum sdw_slave_status status) 191 + { 192 + struct rt721_sdca_priv *rt721 = dev_get_drvdata(&slave->dev); 193 + 194 + if (status == SDW_SLAVE_UNATTACHED) 195 + rt721->hw_init = false; 196 + 197 + if (status == SDW_SLAVE_ATTACHED) { 198 + if (rt721->hs_jack) { 199 + /* 200 + * Due to the SCP_SDCA_INTMASK will be cleared by any reset, and then 201 + * if the device attached again, we will need to set the setting back. 202 + * It could avoid losing the jack detection interrupt. 203 + * This also could sync with the cache value as the rt721_sdca_jack_init set. 204 + */ 205 + sdw_write_no_pm(rt721->slave, SDW_SCP_SDCA_INTMASK1, 206 + SDW_SCP_SDCA_INTMASK_SDCA_6); 207 + sdw_write_no_pm(rt721->slave, SDW_SCP_SDCA_INTMASK2, 208 + SDW_SCP_SDCA_INTMASK_SDCA_8); 209 + } 210 + } 211 + 212 + /* 213 + * Perform initialization only if slave status is present and 214 + * hw_init flag is false 215 + */ 216 + if (rt721->hw_init || status != SDW_SLAVE_ATTACHED) 217 + return 0; 218 + 219 + /* perform I/O transfers required for Slave initialization */ 220 + return rt721_sdca_io_init(&slave->dev, slave); 221 + } 222 + 223 + static int rt721_sdca_read_prop(struct sdw_slave *slave) 224 + { 225 + struct sdw_slave_prop *prop = &slave->prop; 226 + int nval; 227 + int i, j; 228 + u32 bit; 229 + unsigned long addr; 230 + struct sdw_dpn_prop *dpn; 231 + 232 + sdw_slave_read_prop(slave); 233 + prop->scp_int1_mask = SDW_SCP_INT1_BUS_CLASH | SDW_SCP_INT1_PARITY; 234 + prop->quirks = SDW_SLAVE_QUIRKS_INVALID_INITIAL_PARITY; 235 + 236 + prop->paging_support = true; 237 + 238 + /* 239 + * port = 1 for headphone playback 240 + * port = 2 for headset-mic capture 241 + * port = 3 for speaker playback 242 + * port = 6 for digital-mic capture 243 + */ 244 + prop->source_ports = BIT(6) | BIT(2); /* BITMAP: 01000100 */ 245 + prop->sink_ports = BIT(3) | BIT(1); /* BITMAP: 00001010 */ 246 + 247 + nval = hweight32(prop->source_ports); 248 + prop->src_dpn_prop = devm_kcalloc(&slave->dev, nval, 249 + sizeof(*prop->src_dpn_prop), GFP_KERNEL); 250 + if (!prop->src_dpn_prop) 251 + return -ENOMEM; 252 + 253 + i = 0; 254 + dpn = prop->src_dpn_prop; 255 + addr = prop->source_ports; 256 + for_each_set_bit(bit, &addr, 32) { 257 + dpn[i].num = bit; 258 + dpn[i].type = SDW_DPN_FULL; 259 + dpn[i].simple_ch_prep_sm = true; 260 + dpn[i].ch_prep_timeout = 10; 261 + i++; 262 + } 263 + 264 + /* do this again for sink now */ 265 + nval = hweight32(prop->sink_ports); 266 + prop->sink_dpn_prop = devm_kcalloc(&slave->dev, nval, 267 + sizeof(*prop->sink_dpn_prop), GFP_KERNEL); 268 + if (!prop->sink_dpn_prop) 269 + return -ENOMEM; 270 + 271 + j = 0; 272 + dpn = prop->sink_dpn_prop; 273 + addr = prop->sink_ports; 274 + for_each_set_bit(bit, &addr, 32) { 275 + dpn[j].num = bit; 276 + dpn[j].type = SDW_DPN_FULL; 277 + dpn[j].simple_ch_prep_sm = true; 278 + dpn[j].ch_prep_timeout = 10; 279 + j++; 280 + } 281 + 282 + /* set the timeout values */ 283 + prop->clk_stop_timeout = 900; 284 + 285 + /* wake-up event */ 286 + prop->wake_capable = 1; 287 + 288 + /* Three data lanes are supported by rt721-sdca codec */ 289 + prop->lane_control_support = true; 290 + 291 + return 0; 292 + } 293 + 294 + static int rt721_sdca_interrupt_callback(struct sdw_slave *slave, 295 + struct sdw_slave_intr_status *status) 296 + { 297 + struct rt721_sdca_priv *rt721 = dev_get_drvdata(&slave->dev); 298 + int ret, stat; 299 + int count = 0, retry = 3; 300 + unsigned int sdca_cascade, scp_sdca_stat1, scp_sdca_stat2 = 0; 301 + 302 + if (cancel_delayed_work_sync(&rt721->jack_detect_work)) { 303 + dev_warn(&slave->dev, "%s the pending delayed_work was cancelled", __func__); 304 + /* avoid the HID owner doesn't change to device */ 305 + if (rt721->scp_sdca_stat2) 306 + scp_sdca_stat2 = rt721->scp_sdca_stat2; 307 + } 308 + 309 + /* 310 + * The critical section below intentionally protects a rather large piece of code. 311 + * We don't want to allow the system suspend to disable an interrupt while we are 312 + * processing it, which could be problematic given the quirky SoundWire interrupt 313 + * scheme. We do want however to prevent new workqueues from being scheduled if 314 + * the disable_irq flag was set during system suspend. 315 + */ 316 + mutex_lock(&rt721->disable_irq_lock); 317 + 318 + ret = sdw_read_no_pm(rt721->slave, SDW_SCP_SDCA_INT1); 319 + if (ret < 0) 320 + goto io_error; 321 + 322 + rt721->scp_sdca_stat1 = ret; 323 + ret = sdw_read_no_pm(rt721->slave, SDW_SCP_SDCA_INT2); 324 + if (ret < 0) 325 + goto io_error; 326 + 327 + rt721->scp_sdca_stat2 = ret; 328 + if (scp_sdca_stat2) 329 + rt721->scp_sdca_stat2 |= scp_sdca_stat2; 330 + do { 331 + /* clear flag */ 332 + ret = sdw_read_no_pm(rt721->slave, SDW_SCP_SDCA_INT1); 333 + if (ret < 0) 334 + goto io_error; 335 + if (ret & SDW_SCP_SDCA_INTMASK_SDCA_0) { 336 + ret = sdw_update_no_pm(rt721->slave, SDW_SCP_SDCA_INT1, 337 + SDW_SCP_SDCA_INT_SDCA_0, SDW_SCP_SDCA_INT_SDCA_0); 338 + if (ret < 0) 339 + goto io_error; 340 + } else if (ret & SDW_SCP_SDCA_INTMASK_SDCA_6) { 341 + ret = sdw_update_no_pm(rt721->slave, SDW_SCP_SDCA_INT1, 342 + SDW_SCP_SDCA_INT_SDCA_6, SDW_SCP_SDCA_INT_SDCA_6); 343 + if (ret < 0) 344 + goto io_error; 345 + } 346 + ret = sdw_read_no_pm(rt721->slave, SDW_SCP_SDCA_INT2); 347 + if (ret < 0) 348 + goto io_error; 349 + if (ret & SDW_SCP_SDCA_INTMASK_SDCA_8) { 350 + ret = sdw_write_no_pm(rt721->slave, SDW_SCP_SDCA_INT2, 351 + SDW_SCP_SDCA_INTMASK_SDCA_8); 352 + if (ret < 0) 353 + goto io_error; 354 + } 355 + 356 + /* check if flag clear or not */ 357 + ret = sdw_read_no_pm(rt721->slave, SDW_DP0_INT); 358 + if (ret < 0) 359 + goto io_error; 360 + sdca_cascade = ret & SDW_DP0_SDCA_CASCADE; 361 + 362 + ret = sdw_read_no_pm(rt721->slave, SDW_SCP_SDCA_INT1); 363 + if (ret < 0) 364 + goto io_error; 365 + scp_sdca_stat1 = ret & SDW_SCP_SDCA_INTMASK_SDCA_0; 366 + 367 + ret = sdw_read_no_pm(rt721->slave, SDW_SCP_SDCA_INT2); 368 + if (ret < 0) 369 + goto io_error; 370 + scp_sdca_stat2 = ret & SDW_SCP_SDCA_INTMASK_SDCA_8; 371 + 372 + stat = scp_sdca_stat1 || scp_sdca_stat2 || sdca_cascade; 373 + 374 + count++; 375 + } while (stat != 0 && count < retry); 376 + 377 + if (stat) 378 + dev_warn(&slave->dev, 379 + "%s scp_sdca_stat1=0x%x, scp_sdca_stat2=0x%x\n", __func__, 380 + rt721->scp_sdca_stat1, rt721->scp_sdca_stat2); 381 + ret = sdw_read_no_pm(rt721->slave, SDW_SCP_SDCA_INT1); 382 + ret = sdw_read_no_pm(rt721->slave, SDW_SCP_SDCA_INT2); 383 + 384 + if (status->sdca_cascade && !rt721->disable_irq) 385 + mod_delayed_work(system_power_efficient_wq, 386 + &rt721->jack_detect_work, msecs_to_jiffies(280)); 387 + 388 + mutex_unlock(&rt721->disable_irq_lock); 389 + 390 + return 0; 391 + 392 + io_error: 393 + mutex_unlock(&rt721->disable_irq_lock); 394 + pr_err_ratelimited("IO error in %s, ret %d\n", __func__, ret); 395 + return ret; 396 + } 397 + 398 + static const struct sdw_slave_ops rt721_sdca_slave_ops = { 399 + .read_prop = rt721_sdca_read_prop, 400 + .interrupt_callback = rt721_sdca_interrupt_callback, 401 + .update_status = rt721_sdca_update_status, 402 + }; 403 + 404 + static int rt721_sdca_sdw_probe(struct sdw_slave *slave, 405 + const struct sdw_device_id *id) 406 + { 407 + struct regmap *regmap, *mbq_regmap; 408 + 409 + /* Regmap Initialization */ 410 + mbq_regmap = devm_regmap_init_sdw_mbq(slave, &rt721_sdca_mbq_regmap); 411 + if (IS_ERR(mbq_regmap)) 412 + return PTR_ERR(mbq_regmap); 413 + 414 + regmap = devm_regmap_init_sdw(slave, &rt721_sdca_regmap); 415 + if (IS_ERR(regmap)) 416 + return PTR_ERR(regmap); 417 + 418 + return rt721_sdca_init(&slave->dev, regmap, mbq_regmap, slave); 419 + } 420 + 421 + static int rt721_sdca_sdw_remove(struct sdw_slave *slave) 422 + { 423 + struct rt721_sdca_priv *rt721 = dev_get_drvdata(&slave->dev); 424 + 425 + if (rt721->hw_init) { 426 + cancel_delayed_work_sync(&rt721->jack_detect_work); 427 + cancel_delayed_work_sync(&rt721->jack_btn_check_work); 428 + } 429 + 430 + if (rt721->first_hw_init) 431 + pm_runtime_disable(&slave->dev); 432 + 433 + mutex_destroy(&rt721->calibrate_mutex); 434 + mutex_destroy(&rt721->disable_irq_lock); 435 + 436 + return 0; 437 + } 438 + 439 + static const struct sdw_device_id rt721_sdca_id[] = { 440 + SDW_SLAVE_ENTRY_EXT(0x025d, 0x721, 0x3, 0x1, 0), 441 + {}, 442 + }; 443 + MODULE_DEVICE_TABLE(sdw, rt721_sdca_id); 444 + 445 + static int __maybe_unused rt721_sdca_dev_suspend(struct device *dev) 446 + { 447 + struct rt721_sdca_priv *rt721 = dev_get_drvdata(dev); 448 + 449 + if (!rt721->hw_init) 450 + return 0; 451 + 452 + cancel_delayed_work_sync(&rt721->jack_detect_work); 453 + cancel_delayed_work_sync(&rt721->jack_btn_check_work); 454 + 455 + regcache_cache_only(rt721->regmap, true); 456 + regcache_cache_only(rt721->mbq_regmap, true); 457 + 458 + return 0; 459 + } 460 + 461 + static int __maybe_unused rt721_sdca_dev_system_suspend(struct device *dev) 462 + { 463 + struct rt721_sdca_priv *rt721_sdca = dev_get_drvdata(dev); 464 + struct sdw_slave *slave = dev_to_sdw_dev(dev); 465 + int ret1, ret2; 466 + 467 + if (!rt721_sdca->hw_init) 468 + return 0; 469 + 470 + /* 471 + * prevent new interrupts from being handled after the 472 + * deferred work completes and before the parent disables 473 + * interrupts on the link 474 + */ 475 + mutex_lock(&rt721_sdca->disable_irq_lock); 476 + rt721_sdca->disable_irq = true; 477 + ret1 = sdw_update_no_pm(slave, SDW_SCP_SDCA_INTMASK1, 478 + SDW_SCP_SDCA_INTMASK_SDCA_0 | SDW_SCP_SDCA_INTMASK_SDCA_6, 0); 479 + ret2 = sdw_update_no_pm(slave, SDW_SCP_SDCA_INTMASK2, 480 + SDW_SCP_SDCA_INTMASK_SDCA_8, 0); 481 + mutex_unlock(&rt721_sdca->disable_irq_lock); 482 + 483 + if (ret1 < 0 || ret2 < 0) { 484 + /* log but don't prevent suspend from happening */ 485 + dev_dbg(&slave->dev, "%s: could not disable SDCA interrupts\n:", __func__); 486 + } 487 + 488 + return rt721_sdca_dev_suspend(dev); 489 + } 490 + 491 + #define RT721_PROBE_TIMEOUT 5000 492 + 493 + static int __maybe_unused rt721_sdca_dev_resume(struct device *dev) 494 + { 495 + struct sdw_slave *slave = dev_to_sdw_dev(dev); 496 + struct rt721_sdca_priv *rt721 = dev_get_drvdata(dev); 497 + unsigned long time; 498 + 499 + if (!rt721->first_hw_init) 500 + return 0; 501 + 502 + if (!slave->unattach_request) { 503 + mutex_lock(&rt721->disable_irq_lock); 504 + if (rt721->disable_irq == true) { 505 + sdw_write_no_pm(slave, SDW_SCP_SDCA_INTMASK1, SDW_SCP_SDCA_INTMASK_SDCA_6); 506 + sdw_write_no_pm(slave, SDW_SCP_SDCA_INTMASK2, SDW_SCP_SDCA_INTMASK_SDCA_8); 507 + rt721->disable_irq = false; 508 + } 509 + mutex_unlock(&rt721->disable_irq_lock); 510 + goto regmap_sync; 511 + } 512 + 513 + time = wait_for_completion_timeout(&slave->initialization_complete, 514 + msecs_to_jiffies(RT721_PROBE_TIMEOUT)); 515 + if (!time) { 516 + dev_err(&slave->dev, "Initialization not complete, timed out\n"); 517 + sdw_show_ping_status(slave->bus, true); 518 + 519 + return -ETIMEDOUT; 520 + } 521 + 522 + regmap_sync: 523 + slave->unattach_request = 0; 524 + regcache_cache_only(rt721->regmap, false); 525 + regcache_sync(rt721->regmap); 526 + regcache_cache_only(rt721->mbq_regmap, false); 527 + regcache_sync(rt721->mbq_regmap); 528 + return 0; 529 + } 530 + 531 + static const struct dev_pm_ops rt721_sdca_pm = { 532 + SET_SYSTEM_SLEEP_PM_OPS(rt721_sdca_dev_system_suspend, rt721_sdca_dev_resume) 533 + SET_RUNTIME_PM_OPS(rt721_sdca_dev_suspend, rt721_sdca_dev_resume, NULL) 534 + }; 535 + 536 + static struct sdw_driver rt721_sdca_sdw_driver = { 537 + .driver = { 538 + .name = "rt721-sdca", 539 + .owner = THIS_MODULE, 540 + .pm = &rt721_sdca_pm, 541 + }, 542 + .probe = rt721_sdca_sdw_probe, 543 + .remove = rt721_sdca_sdw_remove, 544 + .ops = &rt721_sdca_slave_ops, 545 + .id_table = rt721_sdca_id, 546 + }; 547 + module_sdw_driver(rt721_sdca_sdw_driver); 548 + 549 + MODULE_DESCRIPTION("ASoC RT721 SDCA SDW driver"); 550 + MODULE_AUTHOR("Jack Yu <jack.yu@realtek.com>"); 551 + MODULE_LICENSE("GPL");
+150
sound/soc/codecs/rt721-sdca-sdw.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-only */ 2 + /* 3 + * rt721-sdca-sdw.h -- RT721 SDCA ALSA SoC audio driver header 4 + * 5 + * Copyright(c) 2024 Realtek Semiconductor Corp. 6 + */ 7 + 8 + #ifndef __RT721_SDW_H__ 9 + #define __RT721_SDW_H__ 10 + 11 + #include <linux/regmap.h> 12 + #include <linux/soundwire/sdw_registers.h> 13 + 14 + static const struct reg_default rt721_sdca_reg_defaults[] = { 15 + { 0x202d, 0x00 }, 16 + { 0x2f01, 0x00 }, 17 + { 0x2f02, 0x09 }, 18 + { 0x2f03, 0x08 }, 19 + { 0x2f04, 0x00 }, 20 + { 0x2f05, 0x0e }, 21 + { 0x2f06, 0x01 }, 22 + { 0x2f09, 0x00 }, 23 + { 0x2f0a, 0x00 }, 24 + { 0x2f35, 0x00 }, 25 + { 0x2f50, 0xf0 }, 26 + { 0x2f58, 0x07 }, 27 + { 0x2f59, 0x07 }, 28 + { 0x2f5a, 0x00 }, 29 + { 0x2f5b, 0x07 }, 30 + { 0x2f5c, 0x27 }, 31 + { 0x2f5d, 0x07 }, 32 + { SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT721_SDCA_ENT_CS01, 33 + RT721_SDCA_CTL_SAMPLE_FREQ_INDEX, 0), 0x09 }, 34 + { SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT721_SDCA_ENT_CS11, 35 + RT721_SDCA_CTL_SAMPLE_FREQ_INDEX, 0), 0x09 }, 36 + { SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT721_SDCA_ENT_PDE12, 37 + RT721_SDCA_CTL_REQ_POWER_STATE, 0), 0x03 }, 38 + { SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT721_SDCA_ENT_PDE40, 39 + RT721_SDCA_CTL_REQ_POWER_STATE, 0), 0x03 }, 40 + { SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT721_SDCA_ENT_USER_FU05, 41 + RT721_SDCA_CTL_FU_MUTE, CH_L), 0x01 }, 42 + { SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT721_SDCA_ENT_USER_FU05, 43 + RT721_SDCA_CTL_FU_MUTE, CH_R), 0x01 }, 44 + { SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT721_SDCA_ENT_USER_FU0F, 45 + RT721_SDCA_CTL_FU_MUTE, CH_L), 0x01 }, 46 + { SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT721_SDCA_ENT_USER_FU0F, 47 + RT721_SDCA_CTL_FU_MUTE, CH_R), 0x01 }, 48 + { SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT721_SDCA_ENT_USER_FU1E, 49 + RT721_SDCA_CTL_FU_MUTE, CH_01), 0x01 }, 50 + { SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT721_SDCA_ENT_USER_FU1E, 51 + RT721_SDCA_CTL_FU_MUTE, CH_02), 0x01 }, 52 + { SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT721_SDCA_ENT_USER_FU1E, 53 + RT721_SDCA_CTL_FU_MUTE, CH_03), 0x01 }, 54 + { SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT721_SDCA_ENT_USER_FU1E, 55 + RT721_SDCA_CTL_FU_MUTE, CH_04), 0x01 }, 56 + { SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT721_SDCA_ENT_CS1F, 57 + RT721_SDCA_CTL_SAMPLE_FREQ_INDEX, 0), 0x09 }, 58 + { SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT721_SDCA_ENT_IT26, 59 + RT721_SDCA_CTL_VENDOR_DEF, 0), 0x00 }, 60 + { SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT721_SDCA_ENT_PDE2A, 61 + RT721_SDCA_CTL_REQ_POWER_STATE, 0), 0x03 }, 62 + { SDW_SDCA_CTL(FUNC_NUM_AMP, RT721_SDCA_ENT_CS31, 63 + RT721_SDCA_CTL_SAMPLE_FREQ_INDEX, 0), 0x09 }, 64 + { SDW_SDCA_CTL(FUNC_NUM_AMP, RT721_SDCA_ENT_USER_FU06, 65 + RT721_SDCA_CTL_FU_MUTE, CH_L), 0x01 }, 66 + { SDW_SDCA_CTL(FUNC_NUM_AMP, RT721_SDCA_ENT_USER_FU06, 67 + RT721_SDCA_CTL_FU_MUTE, CH_R), 0x01 }, 68 + { SDW_SDCA_CTL(FUNC_NUM_AMP, RT721_SDCA_ENT_PDE23, 69 + RT721_SDCA_CTL_REQ_POWER_STATE, 0), 0x03 }, 70 + { SDW_SDCA_CTL(FUNC_NUM_AMP, RT721_SDCA_ENT_OT23, 71 + RT721_SDCA_CTL_VENDOR_DEF, 0), 0x00 }, 72 + { SDW_SDCA_CTL(FUNC_NUM_AMP, RT721_SDCA_ENT_PDE23, 73 + RT721_SDCA_CTL_FU_MUTE, CH_01), 0x01 }, 74 + { SDW_SDCA_CTL(FUNC_NUM_AMP, RT721_SDCA_ENT_PDE23, 75 + RT721_SDCA_CTL_FU_MUTE, CH_02), 0x01 }, 76 + { SDW_SDCA_CTL(FUNC_NUM_AMP, RT721_SDCA_ENT_FU55, 77 + RT721_SDCA_CTL_FU_MUTE, CH_01), 0x01 }, 78 + { SDW_SDCA_CTL(FUNC_NUM_AMP, RT721_SDCA_ENT_FU55, 79 + RT721_SDCA_CTL_FU_MUTE, CH_02), 0x01 }, 80 + }; 81 + 82 + static const struct reg_default rt721_sdca_mbq_defaults[] = { 83 + { 0x0900007, 0xc004 }, 84 + { 0x2000001, 0x0000 }, 85 + { 0x2000002, 0x0000 }, 86 + { 0x2000003, 0x0000 }, 87 + { 0x2000013, 0x8001 }, 88 + { 0x200003c, 0x0000 }, 89 + { 0x2000046, 0x3400 }, 90 + { 0x5f00044, 0x6040 }, 91 + { 0x5f00045, 0x3333 }, 92 + { 0x5f00048, 0x0000 }, 93 + { 0x6100005, 0x0005 }, 94 + { 0x6100006, 0x0000 }, 95 + { 0x610000d, 0x0051 }, 96 + { 0x6100010, 0x0180 }, 97 + { 0x6100011, 0x0000 }, 98 + { 0x6100013, 0x0000 }, 99 + { 0x6100015, 0x0000 }, 100 + { 0x6100017, 0x8049 }, 101 + { 0x6100025, 0x1000 }, 102 + { 0x6100029, 0x0809 }, 103 + { 0x610002c, 0x2828 }, 104 + { 0x610002d, 0x2929 }, 105 + { 0x610002e, 0x3529 }, 106 + { 0x610002f, 0x2901 }, 107 + { 0x6100053, 0x2630 }, 108 + { 0x6100054, 0x2a2a }, 109 + { 0x6100055, 0x152f }, 110 + { 0x6100057, 0x2200 }, 111 + { 0x610005a, 0x2a4b }, 112 + { 0x610005b, 0x2a00 }, 113 + { 0x610006a, 0x0102 }, 114 + { 0x610006d, 0x0102 }, 115 + { 0x6100092, 0x4f61 }, 116 + { SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT721_SDCA_ENT_USER_FU05, RT721_SDCA_CTL_FU_VOLUME, 117 + CH_L), 0x0000 }, 118 + { SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT721_SDCA_ENT_USER_FU05, RT721_SDCA_CTL_FU_VOLUME, 119 + CH_R), 0x0000 }, 120 + { SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT721_SDCA_ENT_USER_FU0F, RT721_SDCA_CTL_FU_VOLUME, 121 + CH_L), 0x0000 }, 122 + { SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT721_SDCA_ENT_USER_FU0F, RT721_SDCA_CTL_FU_VOLUME, 123 + CH_R), 0x0000 }, 124 + { SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT721_SDCA_ENT_PLATFORM_FU44, RT721_SDCA_CTL_FU_CH_GAIN, 125 + CH_L), 0xfe00 }, 126 + { SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT721_SDCA_ENT_PLATFORM_FU44, RT721_SDCA_CTL_FU_CH_GAIN, 127 + CH_R), 0xfe00 }, 128 + { SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT721_SDCA_ENT_FU15, RT721_SDCA_CTL_FU_CH_GAIN, CH_01), 129 + 0x0000 }, 130 + { SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT721_SDCA_ENT_FU15, RT721_SDCA_CTL_FU_CH_GAIN, CH_02), 131 + 0x0000 }, 132 + { SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT721_SDCA_ENT_FU15, RT721_SDCA_CTL_FU_CH_GAIN, CH_03), 133 + 0x0000 }, 134 + { SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT721_SDCA_ENT_FU15, RT721_SDCA_CTL_FU_CH_GAIN, CH_04), 135 + 0x0000 }, 136 + { SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT721_SDCA_ENT_USER_FU1E, RT721_SDCA_CTL_FU_VOLUME, 137 + CH_01), 0x0000 }, 138 + { SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT721_SDCA_ENT_USER_FU1E, RT721_SDCA_CTL_FU_VOLUME, 139 + CH_02), 0x0000 }, 140 + { SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT721_SDCA_ENT_USER_FU1E, RT721_SDCA_CTL_FU_VOLUME, 141 + CH_03), 0x0000 }, 142 + { SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT721_SDCA_ENT_USER_FU1E, RT721_SDCA_CTL_FU_VOLUME, 143 + CH_04), 0x0000 }, 144 + { SDW_SDCA_CTL(FUNC_NUM_AMP, RT721_SDCA_ENT_USER_FU06, RT721_SDCA_CTL_FU_VOLUME, CH_L), 145 + 0x0000 }, 146 + { SDW_SDCA_CTL(FUNC_NUM_AMP, RT721_SDCA_ENT_USER_FU06, RT721_SDCA_CTL_FU_VOLUME, CH_R), 147 + 0x0000 }, 148 + }; 149 + 150 + #endif /* __RT721_SDW_H__ */
+1547
sound/soc/codecs/rt721-sdca.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + // 3 + // rt721-sdca.c -- rt721 SDCA ALSA SoC audio driver 4 + // 5 + // Copyright(c) 2024 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 <sound/pcm.h> 19 + #include <linux/pm_runtime.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 + 26 + #include "rt721-sdca.h" 27 + #include "rt-sdw-common.h" 28 + 29 + static void rt721_sdca_jack_detect_handler(struct work_struct *work) 30 + { 31 + struct rt721_sdca_priv *rt721 = 32 + container_of(work, struct rt721_sdca_priv, jack_detect_work.work); 33 + int btn_type = 0, ret; 34 + 35 + if (!rt721->hs_jack) 36 + return; 37 + 38 + if (!rt721->component->card || !rt721->component->card->instantiated) 39 + return; 40 + 41 + /* SDW_SCP_SDCA_INT_SDCA_6 is used for jack detection */ 42 + if (rt721->scp_sdca_stat1 & SDW_SCP_SDCA_INT_SDCA_6) { 43 + rt721->jack_type = rt_sdca_headset_detect(rt721->regmap, 44 + RT721_SDCA_ENT_GE49); 45 + if (ret < 0) 46 + return; 47 + } 48 + 49 + /* SDW_SCP_SDCA_INT_SDCA_8 is used for button detection */ 50 + if (rt721->scp_sdca_stat2 & SDW_SCP_SDCA_INT_SDCA_8) 51 + btn_type = rt_sdca_button_detect(rt721->regmap, 52 + RT721_SDCA_ENT_HID01, RT721_BUF_ADDR_HID1, 53 + RT721_SDCA_HID_ID); 54 + 55 + if (rt721->jack_type == 0) 56 + btn_type = 0; 57 + 58 + dev_dbg(&rt721->slave->dev, 59 + "in %s, jack_type=%d\n", __func__, rt721->jack_type); 60 + dev_dbg(&rt721->slave->dev, 61 + "in %s, btn_type=0x%x\n", __func__, btn_type); 62 + dev_dbg(&rt721->slave->dev, 63 + "in %s, scp_sdca_stat1=0x%x, scp_sdca_stat2=0x%x\n", __func__, 64 + rt721->scp_sdca_stat1, rt721->scp_sdca_stat2); 65 + 66 + snd_soc_jack_report(rt721->hs_jack, rt721->jack_type | btn_type, 67 + SND_JACK_HEADSET | 68 + SND_JACK_BTN_0 | SND_JACK_BTN_1 | 69 + SND_JACK_BTN_2 | SND_JACK_BTN_3); 70 + 71 + if (btn_type) { 72 + /* button released */ 73 + snd_soc_jack_report(rt721->hs_jack, rt721->jack_type, 74 + SND_JACK_HEADSET | 75 + SND_JACK_BTN_0 | SND_JACK_BTN_1 | 76 + SND_JACK_BTN_2 | SND_JACK_BTN_3); 77 + 78 + mod_delayed_work(system_power_efficient_wq, 79 + &rt721->jack_btn_check_work, msecs_to_jiffies(200)); 80 + } 81 + } 82 + 83 + static void rt721_sdca_btn_check_handler(struct work_struct *work) 84 + { 85 + struct rt721_sdca_priv *rt721 = 86 + container_of(work, struct rt721_sdca_priv, jack_btn_check_work.work); 87 + int btn_type = 0, ret, idx; 88 + unsigned int det_mode, offset, val; 89 + unsigned char buf[3]; 90 + 91 + ret = regmap_read(rt721->regmap, 92 + SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT721_SDCA_ENT_GE49, 93 + RT721_SDCA_CTL_DETECTED_MODE, 0), &det_mode); 94 + if (ret < 0) 95 + goto io_error; 96 + 97 + /* pin attached */ 98 + if (det_mode) { 99 + /* read UMP message offset */ 100 + ret = regmap_read(rt721->regmap, 101 + SDW_SDCA_CTL(FUNC_NUM_HID, RT721_SDCA_ENT_HID01, 102 + RT721_SDCA_CTL_HIDTX_MESSAGE_OFFSET, 0), &offset); 103 + if (ret < 0) 104 + goto io_error; 105 + 106 + for (idx = 0; idx < sizeof(buf); idx++) { 107 + ret = regmap_read(rt721->regmap, 108 + RT721_BUF_ADDR_HID1 + offset + idx, &val); 109 + if (ret < 0) 110 + goto io_error; 111 + buf[idx] = val & 0xff; 112 + } 113 + /* Report ID for HID1 */ 114 + if (buf[0] == 0x11) 115 + btn_type = rt_sdca_btn_type(&buf[1]); 116 + } else 117 + rt721->jack_type = 0; 118 + 119 + dev_dbg(&rt721->slave->dev, "%s, btn_type=0x%x\n", __func__, btn_type); 120 + snd_soc_jack_report(rt721->hs_jack, rt721->jack_type | btn_type, 121 + SND_JACK_HEADSET | 122 + SND_JACK_BTN_0 | SND_JACK_BTN_1 | 123 + SND_JACK_BTN_2 | SND_JACK_BTN_3); 124 + 125 + if (btn_type) { 126 + /* button released */ 127 + snd_soc_jack_report(rt721->hs_jack, rt721->jack_type, 128 + SND_JACK_HEADSET | 129 + SND_JACK_BTN_0 | SND_JACK_BTN_1 | 130 + SND_JACK_BTN_2 | SND_JACK_BTN_3); 131 + 132 + mod_delayed_work(system_power_efficient_wq, 133 + &rt721->jack_btn_check_work, msecs_to_jiffies(200)); 134 + } 135 + 136 + return; 137 + 138 + io_error: 139 + pr_err_ratelimited("IO error in %s, ret %d\n", __func__, ret); 140 + } 141 + 142 + static void rt721_sdca_dmic_preset(struct rt721_sdca_priv *rt721) 143 + { 144 + rt_sdca_index_write(rt721->mbq_regmap, RT721_VENDOR_ANA_CTL, 145 + RT721_MISC_POWER_CTL31, 0x8000); 146 + rt_sdca_index_write(rt721->mbq_regmap, RT721_ANA_POW_PART, 147 + RT721_VREF1_HV_CTRL1, 0xe000); 148 + rt_sdca_index_write(rt721->mbq_regmap, RT721_VENDOR_ANA_CTL, 149 + RT721_MISC_POWER_CTL31, 0x8007); 150 + rt_sdca_index_write(rt721->mbq_regmap, RT721_HDA_SDCA_FLOAT, 151 + RT721_ENT_FLOAT_CTL9, 0x2a2a); 152 + rt_sdca_index_write(rt721->mbq_regmap, RT721_HDA_SDCA_FLOAT, 153 + RT721_ENT_FLOAT_CTL10, 0x2a00); 154 + rt_sdca_index_write(rt721->mbq_regmap, RT721_HDA_SDCA_FLOAT, 155 + RT721_ENT_FLOAT_CTL6, 0x2a2a); 156 + rt_sdca_index_write(rt721->mbq_regmap, RT721_HDA_SDCA_FLOAT, 157 + RT721_ENT_FLOAT_CTL5, 0x2626); 158 + rt_sdca_index_write(rt721->mbq_regmap, RT721_HDA_SDCA_FLOAT, 159 + RT721_ENT_FLOAT_CTL8, 0x1e00); 160 + rt_sdca_index_write(rt721->mbq_regmap, RT721_HDA_SDCA_FLOAT, 161 + RT721_ENT_FLOAT_CTL7, 0x1515); 162 + rt_sdca_index_write(rt721->mbq_regmap, RT721_HDA_SDCA_FLOAT, 163 + RT721_CH_FLOAT_CTL3, 0x0304); 164 + rt_sdca_index_write(rt721->mbq_regmap, RT721_HDA_SDCA_FLOAT, 165 + RT721_CH_FLOAT_CTL4, 0x0304); 166 + rt_sdca_index_write(rt721->mbq_regmap, RT721_HDA_SDCA_FLOAT, 167 + RT721_HDA_LEGACY_CTL1, 0x0000); 168 + regmap_write(rt721->regmap, 169 + SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT721_SDCA_ENT_IT26, 170 + RT721_SDCA_CTL_VENDOR_DEF, 0), 0x01); 171 + regmap_write(rt721->mbq_regmap, 0x5910009, 0x2e01); 172 + rt_sdca_index_write(rt721->mbq_regmap, RT721_RC_CALIB_CTRL, 173 + RT721_RC_CALIB_CTRL0, 0x0b00); 174 + rt_sdca_index_write(rt721->mbq_regmap, RT721_RC_CALIB_CTRL, 175 + RT721_RC_CALIB_CTRL0, 0x0b40); 176 + regmap_write(rt721->regmap, 0x2f5c, 0x25); 177 + } 178 + 179 + static void rt721_sdca_amp_preset(struct rt721_sdca_priv *rt721) 180 + { 181 + rt_sdca_index_write(rt721->mbq_regmap, RT721_VENDOR_ANA_CTL, 182 + RT721_MISC_POWER_CTL31, 0x8000); 183 + rt_sdca_index_write(rt721->mbq_regmap, RT721_ANA_POW_PART, 184 + RT721_VREF1_HV_CTRL1, 0xe000); 185 + rt_sdca_index_write(rt721->mbq_regmap, RT721_VENDOR_ANA_CTL, 186 + RT721_MISC_POWER_CTL31, 0x8007); 187 + regmap_write(rt721->mbq_regmap, 0x5810000, 0x6420); 188 + regmap_write(rt721->mbq_regmap, 0x5810000, 0x6421); 189 + regmap_write(rt721->mbq_regmap, 0x5810000, 0xe421); 190 + rt_sdca_index_write(rt721->mbq_regmap, RT721_HDA_SDCA_FLOAT, 191 + RT721_CH_FLOAT_CTL6, 0x5561); 192 + rt_sdca_index_write(rt721->mbq_regmap, RT721_VENDOR_REG, 193 + RT721_GPIO_PAD_CTRL5, 0x8003); 194 + regmap_write(rt721->regmap, 195 + SDW_SDCA_CTL(FUNC_NUM_AMP, RT721_SDCA_ENT_OT23, 196 + RT721_SDCA_CTL_VENDOR_DEF, 0), 0x04); 197 + regmap_write(rt721->regmap, 198 + SDW_SDCA_CTL(FUNC_NUM_AMP, RT721_SDCA_ENT_PDE23, 199 + RT721_SDCA_CTL_FU_MUTE, CH_01), 0x00); 200 + regmap_write(rt721->regmap, 201 + SDW_SDCA_CTL(FUNC_NUM_AMP, RT721_SDCA_ENT_PDE23, 202 + RT721_SDCA_CTL_FU_MUTE, CH_02), 0x00); 203 + regmap_write(rt721->regmap, 204 + SDW_SDCA_CTL(FUNC_NUM_AMP, RT721_SDCA_ENT_FU55, 205 + RT721_SDCA_CTL_FU_MUTE, CH_01), 0x00); 206 + regmap_write(rt721->regmap, 207 + SDW_SDCA_CTL(FUNC_NUM_AMP, RT721_SDCA_ENT_FU55, 208 + RT721_SDCA_CTL_FU_MUTE, CH_02), 0x00); 209 + } 210 + 211 + static void rt721_sdca_jack_preset(struct rt721_sdca_priv *rt721) 212 + { 213 + rt_sdca_index_write(rt721->mbq_regmap, RT721_VENDOR_ANA_CTL, 214 + RT721_MISC_POWER_CTL31, 0x8000); 215 + rt_sdca_index_write(rt721->mbq_regmap, RT721_ANA_POW_PART, 216 + RT721_VREF1_HV_CTRL1, 0xe000); 217 + rt_sdca_index_write(rt721->mbq_regmap, RT721_VENDOR_ANA_CTL, 218 + RT721_MISC_POWER_CTL31, 0x8007); 219 + rt_sdca_index_write(rt721->mbq_regmap, RT721_HDA_SDCA_FLOAT, 220 + RT721_GE_REL_CTRL1, 0x8011); 221 + rt_sdca_index_write(rt721->mbq_regmap, RT721_HDA_SDCA_FLOAT, 222 + RT721_UMP_HID_CTRL3, 0xcf00); 223 + rt_sdca_index_write(rt721->mbq_regmap, RT721_HDA_SDCA_FLOAT, 224 + RT721_UMP_HID_CTRL4, 0x000f); 225 + rt_sdca_index_write(rt721->mbq_regmap, RT721_HDA_SDCA_FLOAT, 226 + RT721_UMP_HID_CTRL1, 0x1100); 227 + rt_sdca_index_write(rt721->mbq_regmap, RT721_HDA_SDCA_FLOAT, 228 + RT721_UMP_HID_CTRL5, 0x0c12); 229 + rt_sdca_index_write(rt721->mbq_regmap, RT721_JD_CTRL, 230 + RT721_JD_1PIN_GAT_CTRL2, 0xc002); 231 + rt_sdca_index_write(rt721->mbq_regmap, RT721_RC_CALIB_CTRL, 232 + RT721_RC_CALIB_CTRL0, 0x0b00); 233 + rt_sdca_index_write(rt721->mbq_regmap, RT721_RC_CALIB_CTRL, 234 + RT721_RC_CALIB_CTRL0, 0x0b40); 235 + rt_sdca_index_write(rt721->mbq_regmap, RT721_VENDOR_ANA_CTL, 236 + RT721_UAJ_TOP_TCON14, 0x3333); 237 + regmap_write(rt721->mbq_regmap, 0x5810035, 0x0036); 238 + regmap_write(rt721->mbq_regmap, 0x5810030, 0xee00); 239 + rt_sdca_index_write(rt721->mbq_regmap, RT721_CAP_PORT_CTRL, 240 + RT721_HP_AMP_2CH_CAL1, 0x0140); 241 + regmap_write(rt721->mbq_regmap, 0x5810000, 0x0021); 242 + regmap_write(rt721->mbq_regmap, 0x5810000, 0x8021); 243 + rt_sdca_index_write(rt721->mbq_regmap, RT721_CAP_PORT_CTRL, 244 + RT721_HP_AMP_2CH_CAL18, 0x5522); 245 + regmap_write(rt721->mbq_regmap, 0x5b10007, 0x2000); 246 + regmap_write(rt721->mbq_regmap, 0x5B10017, 0x1b0f); 247 + rt_sdca_index_write(rt721->mbq_regmap, RT721_CBJ_CTRL, 248 + RT721_CBJ_A0_GAT_CTRL1, 0x2a02); 249 + rt_sdca_index_write(rt721->mbq_regmap, RT721_CAP_PORT_CTRL, 250 + RT721_HP_AMP_2CH_CAL4, 0xa105); 251 + rt_sdca_index_write(rt721->mbq_regmap, RT721_VENDOR_ANA_CTL, 252 + RT721_UAJ_TOP_TCON14, 0x3b33); 253 + regmap_write(rt721->mbq_regmap, 0x310400, 0x3023); 254 + rt_sdca_index_write(rt721->mbq_regmap, RT721_VENDOR_ANA_CTL, 255 + RT721_UAJ_TOP_TCON14, 0x3f33); 256 + rt_sdca_index_write(rt721->mbq_regmap, RT721_VENDOR_ANA_CTL, 257 + RT721_UAJ_TOP_TCON13, 0x6048); 258 + regmap_write(rt721->mbq_regmap, 0x310401, 0x3000); 259 + regmap_write(rt721->mbq_regmap, 0x310402, 0x1b00); 260 + regmap_write(rt721->mbq_regmap, 0x310300, 0x000f); 261 + regmap_write(rt721->mbq_regmap, 0x310301, 0x3000); 262 + regmap_write(rt721->mbq_regmap, 0x310302, 0x1b00); 263 + rt_sdca_index_write(rt721->mbq_regmap, RT721_VENDOR_ANA_CTL, 264 + RT721_UAJ_TOP_TCON17, 0x0008); 265 + rt_sdca_index_write(rt721->mbq_regmap, RT721_DAC_CTRL, 266 + RT721_DAC_2CH_CTRL3, 0x55ff); 267 + rt_sdca_index_write(rt721->mbq_regmap, RT721_DAC_CTRL, 268 + RT721_DAC_2CH_CTRL4, 0xcc00); 269 + rt_sdca_index_write(rt721->mbq_regmap, RT721_ANA_POW_PART, 270 + RT721_MBIAS_LV_CTRL2, 0x6677); 271 + rt_sdca_index_write(rt721->mbq_regmap, RT721_ANA_POW_PART, 272 + RT721_VREF2_LV_CTRL1, 0x7600); 273 + rt_sdca_index_write(rt721->mbq_regmap, RT721_HDA_SDCA_FLOAT, 274 + RT721_ENT_FLOAT_CTL2, 0x1234); 275 + rt_sdca_index_write(rt721->mbq_regmap, RT721_HDA_SDCA_FLOAT, 276 + RT721_ENT_FLOAT_CTL3, 0x3512); 277 + rt_sdca_index_write(rt721->mbq_regmap, RT721_HDA_SDCA_FLOAT, 278 + RT721_ENT_FLOAT_CTL1, 0x4040); 279 + rt_sdca_index_write(rt721->mbq_regmap, RT721_HDA_SDCA_FLOAT, 280 + RT721_ENT_FLOAT_CTL4, 0x1201); 281 + regmap_write(rt721->regmap, 0x2f58, 0x07); 282 + } 283 + 284 + static void rt721_sdca_jack_init(struct rt721_sdca_priv *rt721) 285 + { 286 + mutex_lock(&rt721->calibrate_mutex); 287 + if (rt721->hs_jack) { 288 + sdw_write_no_pm(rt721->slave, SDW_SCP_SDCA_INTMASK1, 289 + SDW_SCP_SDCA_INTMASK_SDCA_0 | SDW_SCP_SDCA_INTMASK_SDCA_6); 290 + sdw_write_no_pm(rt721->slave, SDW_SCP_SDCA_INTMASK2, 291 + SDW_SCP_SDCA_INTMASK_SDCA_8); 292 + dev_dbg(&rt721->slave->dev, "in %s enable\n", __func__); 293 + rt_sdca_index_write(rt721->mbq_regmap, RT721_HDA_SDCA_FLOAT, 294 + RT721_HDA_LEGACY_UAJ_CTL, 0x036E); 295 + regmap_write(rt721->regmap, 296 + SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT721_SDCA_ENT_XU03, 297 + RT721_SDCA_CTL_SELECTED_MODE, 0), 0); 298 + regmap_write(rt721->regmap, 299 + SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT721_SDCA_ENT_XU0D, 300 + RT721_SDCA_CTL_SELECTED_MODE, 0), 0); 301 + rt_sdca_index_update_bits(rt721->mbq_regmap, RT721_HDA_SDCA_FLOAT, 302 + RT721_GE_REL_CTRL1, 0x4000, 0x4000); 303 + } 304 + mutex_unlock(&rt721->calibrate_mutex); 305 + } 306 + 307 + static int rt721_sdca_set_jack_detect(struct snd_soc_component *component, 308 + struct snd_soc_jack *hs_jack, void *data) 309 + { 310 + struct rt721_sdca_priv *rt721 = snd_soc_component_get_drvdata(component); 311 + int ret; 312 + 313 + rt721->hs_jack = hs_jack; 314 + 315 + ret = pm_runtime_resume_and_get(component->dev); 316 + if (ret < 0) { 317 + if (ret != -EACCES) { 318 + dev_err(component->dev, "%s: failed to resume %d\n", __func__, ret); 319 + return ret; 320 + } 321 + /* pm_runtime not enabled yet */ 322 + dev_dbg(component->dev, "%s: skipping jack init for now\n", __func__); 323 + return 0; 324 + } 325 + 326 + rt721_sdca_jack_init(rt721); 327 + 328 + pm_runtime_mark_last_busy(component->dev); 329 + pm_runtime_put_autosuspend(component->dev); 330 + 331 + return 0; 332 + } 333 + 334 + /* For SDCA control DAC/ADC Gain */ 335 + static int rt721_sdca_set_gain_put(struct snd_kcontrol *kcontrol, 336 + struct snd_ctl_elem_value *ucontrol) 337 + { 338 + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); 339 + struct soc_mixer_control *mc = 340 + (struct soc_mixer_control *)kcontrol->private_value; 341 + struct rt721_sdca_priv *rt721 = snd_soc_component_get_drvdata(component); 342 + unsigned int read_l, read_r, gain_l_val, gain_r_val; 343 + unsigned int adc_vol_flag = 0, changed = 0; 344 + unsigned int lvalue, rvalue; 345 + const unsigned int interval_offset = 0xc0; 346 + const unsigned int tendA = 0x200; 347 + const unsigned int tendB = 0xa00; 348 + 349 + if (strstr(ucontrol->id.name, "FU1E Capture Volume") || 350 + strstr(ucontrol->id.name, "FU0F Capture Volume")) 351 + adc_vol_flag = 1; 352 + 353 + regmap_read(rt721->mbq_regmap, mc->reg, &lvalue); 354 + regmap_read(rt721->mbq_regmap, mc->rreg, &rvalue); 355 + 356 + /* L Channel */ 357 + gain_l_val = ucontrol->value.integer.value[0]; 358 + if (gain_l_val > mc->max) 359 + gain_l_val = mc->max; 360 + 361 + if (mc->shift == 8) { 362 + /* boost gain */ 363 + gain_l_val = gain_l_val * tendB; 364 + } else if (mc->shift == 1) { 365 + /* FU33 boost gain */ 366 + if (gain_l_val == 0) 367 + gain_l_val = 0x8000; 368 + else 369 + gain_l_val = (gain_l_val - 1) * tendA; 370 + } else { 371 + /* ADC/DAC gain */ 372 + if (adc_vol_flag) 373 + gain_l_val = 0x1e00 - ((mc->max - gain_l_val) * interval_offset); 374 + else 375 + gain_l_val = 0 - ((mc->max - gain_l_val) * interval_offset); 376 + gain_l_val &= 0xffff; 377 + } 378 + 379 + /* R Channel */ 380 + gain_r_val = ucontrol->value.integer.value[1]; 381 + if (gain_r_val > mc->max) 382 + gain_r_val = mc->max; 383 + 384 + if (mc->shift == 8) { 385 + /* boost gain */ 386 + gain_r_val = gain_r_val * tendB; 387 + } else if (mc->shift == 1) { 388 + /* FU33 boost gain */ 389 + if (gain_r_val == 0) 390 + gain_r_val = 0x8000; 391 + else 392 + gain_r_val = (gain_r_val - 1) * tendA; 393 + } else { 394 + /* ADC/DAC gain */ 395 + if (adc_vol_flag) 396 + gain_r_val = 0x1e00 - ((mc->max - gain_r_val) * interval_offset); 397 + else 398 + gain_r_val = 0 - ((mc->max - gain_r_val) * interval_offset); 399 + gain_r_val &= 0xffff; 400 + } 401 + 402 + if (lvalue != gain_l_val || rvalue != gain_r_val) 403 + changed = 1; 404 + else 405 + return 0; 406 + 407 + /* Lch*/ 408 + regmap_write(rt721->mbq_regmap, mc->reg, gain_l_val); 409 + 410 + /* Rch */ 411 + regmap_write(rt721->mbq_regmap, mc->rreg, gain_r_val); 412 + 413 + regmap_read(rt721->mbq_regmap, mc->reg, &read_l); 414 + regmap_read(rt721->mbq_regmap, mc->rreg, &read_r); 415 + if (read_r == gain_r_val && read_l == gain_l_val) 416 + return changed; 417 + 418 + return -EIO; 419 + } 420 + 421 + static int rt721_sdca_set_gain_get(struct snd_kcontrol *kcontrol, 422 + struct snd_ctl_elem_value *ucontrol) 423 + { 424 + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); 425 + struct rt721_sdca_priv *rt721 = snd_soc_component_get_drvdata(component); 426 + struct soc_mixer_control *mc = 427 + (struct soc_mixer_control *)kcontrol->private_value; 428 + unsigned int read_l, read_r, ctl_l = 0, ctl_r = 0; 429 + unsigned int adc_vol_flag = 0; 430 + const unsigned int interval_offset = 0xc0; 431 + const unsigned int tendB = 0xa00; 432 + 433 + if (strstr(ucontrol->id.name, "FU1E Capture Volume") || 434 + strstr(ucontrol->id.name, "FU0F Capture Volume")) 435 + adc_vol_flag = 1; 436 + 437 + regmap_read(rt721->mbq_regmap, mc->reg, &read_l); 438 + regmap_read(rt721->mbq_regmap, mc->rreg, &read_r); 439 + 440 + if (mc->shift == 8) /* boost gain */ 441 + ctl_l = read_l / tendB; 442 + else { 443 + if (adc_vol_flag) 444 + ctl_l = mc->max - (((0x1e00 - read_l) & 0xffff) / interval_offset); 445 + else 446 + ctl_l = mc->max - (((0 - read_l) & 0xffff) / interval_offset); 447 + } 448 + 449 + if (read_l != read_r) { 450 + if (mc->shift == 8) /* boost gain */ 451 + ctl_r = read_r / tendB; 452 + else { /* ADC/DAC gain */ 453 + if (adc_vol_flag) 454 + ctl_r = mc->max - (((0x1e00 - read_r) & 0xffff) / interval_offset); 455 + else 456 + ctl_r = mc->max - (((0 - read_r) & 0xffff) / interval_offset); 457 + } 458 + } else { 459 + ctl_r = ctl_l; 460 + } 461 + 462 + ucontrol->value.integer.value[0] = ctl_l; 463 + ucontrol->value.integer.value[1] = ctl_r; 464 + 465 + return 0; 466 + } 467 + 468 + static int rt721_sdca_set_fu1e_capture_ctl(struct rt721_sdca_priv *rt721) 469 + { 470 + int err, i; 471 + unsigned int ch_mute; 472 + 473 + for (i = 0; i < ARRAY_SIZE(rt721->fu1e_mixer_mute); i++) { 474 + ch_mute = rt721->fu1e_dapm_mute || rt721->fu1e_mixer_mute[i]; 475 + err = regmap_write(rt721->regmap, 476 + SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT721_SDCA_ENT_USER_FU1E, 477 + RT721_SDCA_CTL_FU_MUTE, CH_01) + i, ch_mute); 478 + if (err < 0) 479 + return err; 480 + } 481 + 482 + return 0; 483 + } 484 + 485 + static int rt721_sdca_fu1e_capture_get(struct snd_kcontrol *kcontrol, 486 + struct snd_ctl_elem_value *ucontrol) 487 + { 488 + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); 489 + struct rt721_sdca_priv *rt721 = snd_soc_component_get_drvdata(component); 490 + struct rt721_sdca_dmic_kctrl_priv *p = 491 + (struct rt721_sdca_dmic_kctrl_priv *)kcontrol->private_value; 492 + unsigned int i; 493 + 494 + for (i = 0; i < p->count; i++) 495 + ucontrol->value.integer.value[i] = !rt721->fu1e_mixer_mute[i]; 496 + 497 + return 0; 498 + } 499 + 500 + static int rt721_sdca_fu1e_capture_put(struct snd_kcontrol *kcontrol, 501 + struct snd_ctl_elem_value *ucontrol) 502 + { 503 + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); 504 + struct rt721_sdca_priv *rt721 = snd_soc_component_get_drvdata(component); 505 + struct rt721_sdca_dmic_kctrl_priv *p = 506 + (struct rt721_sdca_dmic_kctrl_priv *)kcontrol->private_value; 507 + int err, changed = 0, i; 508 + 509 + for (i = 0; i < p->count; i++) { 510 + if (rt721->fu1e_mixer_mute[i] != !ucontrol->value.integer.value[i]) 511 + changed = 1; 512 + rt721->fu1e_mixer_mute[i] = !ucontrol->value.integer.value[i]; 513 + } 514 + 515 + err = rt721_sdca_set_fu1e_capture_ctl(rt721); 516 + if (err < 0) 517 + return err; 518 + 519 + return changed; 520 + } 521 + 522 + static int rt721_sdca_set_fu0f_capture_ctl(struct rt721_sdca_priv *rt721) 523 + { 524 + int err; 525 + unsigned int ch_l, ch_r; 526 + 527 + ch_l = (rt721->fu0f_dapm_mute || rt721->fu0f_mixer_l_mute) ? 0x01 : 0x00; 528 + ch_r = (rt721->fu0f_dapm_mute || rt721->fu0f_mixer_r_mute) ? 0x01 : 0x00; 529 + 530 + err = regmap_write(rt721->regmap, 531 + SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT721_SDCA_ENT_USER_FU0F, 532 + RT721_SDCA_CTL_FU_MUTE, CH_L), ch_l); 533 + if (err < 0) 534 + return err; 535 + 536 + err = regmap_write(rt721->regmap, 537 + SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT721_SDCA_ENT_USER_FU0F, 538 + RT721_SDCA_CTL_FU_MUTE, CH_R), ch_r); 539 + if (err < 0) 540 + return err; 541 + 542 + return 0; 543 + } 544 + 545 + static int rt721_sdca_fu0f_capture_get(struct snd_kcontrol *kcontrol, 546 + struct snd_ctl_elem_value *ucontrol) 547 + { 548 + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); 549 + struct rt721_sdca_priv *rt721 = snd_soc_component_get_drvdata(component); 550 + 551 + ucontrol->value.integer.value[0] = !rt721->fu0f_mixer_l_mute; 552 + ucontrol->value.integer.value[1] = !rt721->fu0f_mixer_r_mute; 553 + return 0; 554 + } 555 + 556 + static int rt721_sdca_fu0f_capture_put(struct snd_kcontrol *kcontrol, 557 + struct snd_ctl_elem_value *ucontrol) 558 + { 559 + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); 560 + struct rt721_sdca_priv *rt721 = snd_soc_component_get_drvdata(component); 561 + int err, changed = 0; 562 + 563 + if (rt721->fu0f_mixer_l_mute != !ucontrol->value.integer.value[0] || 564 + rt721->fu0f_mixer_r_mute != !ucontrol->value.integer.value[1]) 565 + changed = 1; 566 + 567 + rt721->fu0f_mixer_l_mute = !ucontrol->value.integer.value[0]; 568 + rt721->fu0f_mixer_r_mute = !ucontrol->value.integer.value[1]; 569 + err = rt721_sdca_set_fu0f_capture_ctl(rt721); 570 + if (err < 0) 571 + return err; 572 + 573 + return changed; 574 + } 575 + 576 + static int rt721_sdca_fu_info(struct snd_kcontrol *kcontrol, 577 + struct snd_ctl_elem_info *uinfo) 578 + { 579 + struct rt721_sdca_dmic_kctrl_priv *p = 580 + (struct rt721_sdca_dmic_kctrl_priv *)kcontrol->private_value; 581 + 582 + if (p->max == 1) 583 + uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; 584 + else 585 + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 586 + uinfo->count = p->count; 587 + uinfo->value.integer.min = 0; 588 + uinfo->value.integer.max = p->max; 589 + return 0; 590 + } 591 + 592 + static int rt721_sdca_dmic_set_gain_get(struct snd_kcontrol *kcontrol, 593 + struct snd_ctl_elem_value *ucontrol) 594 + { 595 + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); 596 + struct rt721_sdca_priv *rt721 = snd_soc_component_get_drvdata(component); 597 + struct rt721_sdca_dmic_kctrl_priv *p = 598 + (struct rt721_sdca_dmic_kctrl_priv *)kcontrol->private_value; 599 + unsigned int boost_step = 0x0a00; 600 + unsigned int vol_max = 0x1e00; 601 + unsigned int regvalue, ctl, i; 602 + unsigned int adc_vol_flag = 0; 603 + const unsigned int interval_offset = 0xc0; 604 + 605 + if (strstr(ucontrol->id.name, "FU1E Capture Volume")) 606 + adc_vol_flag = 1; 607 + 608 + /* check all channels */ 609 + for (i = 0; i < p->count; i++) { 610 + regmap_read(rt721->mbq_regmap, p->reg_base + i, &regvalue); 611 + 612 + if (!adc_vol_flag) /* boost gain */ 613 + ctl = regvalue / boost_step; 614 + else { /* ADC gain */ 615 + if (adc_vol_flag) 616 + ctl = p->max - (((vol_max - regvalue) & 0xffff) / interval_offset); 617 + else 618 + ctl = p->max - (((0 - regvalue) & 0xffff) / interval_offset); 619 + } 620 + 621 + ucontrol->value.integer.value[i] = ctl; 622 + } 623 + 624 + return 0; 625 + } 626 + 627 + static int rt721_sdca_dmic_set_gain_put(struct snd_kcontrol *kcontrol, 628 + struct snd_ctl_elem_value *ucontrol) 629 + { 630 + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); 631 + struct rt721_sdca_dmic_kctrl_priv *p = 632 + (struct rt721_sdca_dmic_kctrl_priv *)kcontrol->private_value; 633 + struct rt721_sdca_priv *rt721 = snd_soc_component_get_drvdata(component); 634 + unsigned int boost_step = 0x0a00; 635 + unsigned int vol_max = 0x1e00; 636 + unsigned int gain_val[4]; 637 + unsigned int i, adc_vol_flag = 0, changed = 0; 638 + unsigned int regvalue[4]; 639 + const unsigned int interval_offset = 0xc0; 640 + int err; 641 + 642 + if (strstr(ucontrol->id.name, "FU1E Capture Volume")) 643 + adc_vol_flag = 1; 644 + 645 + /* check all channels */ 646 + for (i = 0; i < p->count; i++) { 647 + regmap_read(rt721->mbq_regmap, p->reg_base + i, &regvalue[i]); 648 + 649 + gain_val[i] = ucontrol->value.integer.value[i]; 650 + if (gain_val[i] > p->max) 651 + gain_val[i] = p->max; 652 + 653 + if (!adc_vol_flag) /* boost gain */ 654 + gain_val[i] = gain_val[i] * boost_step; 655 + else { /* ADC gain */ 656 + gain_val[i] = vol_max - ((p->max - gain_val[i]) * interval_offset); 657 + gain_val[i] &= 0xffff; 658 + } 659 + 660 + if (regvalue[i] != gain_val[i]) 661 + changed = 1; 662 + } 663 + 664 + if (!changed) 665 + return 0; 666 + 667 + for (i = 0; i < p->count; i++) { 668 + err = regmap_write(rt721->mbq_regmap, p->reg_base + i, gain_val[i]); 669 + if (err < 0) 670 + dev_err(&rt721->slave->dev, "%#08x can't be set\n", p->reg_base + i); 671 + } 672 + 673 + return changed; 674 + } 675 + 676 + static const DECLARE_TLV_DB_SCALE(out_vol_tlv, -6525, 75, 0); 677 + static const DECLARE_TLV_DB_SCALE(mic_vol_tlv, -1725, 75, 0); 678 + static const DECLARE_TLV_DB_SCALE(boost_vol_tlv, 0, 1000, 0); 679 + static const DECLARE_TLV_DB_SCALE(mic2_boost_vol_tlv, -200, 200, 0); 680 + 681 + static const struct snd_kcontrol_new rt721_sdca_controls[] = { 682 + /* Headphone playback settings */ 683 + SOC_DOUBLE_R_EXT_TLV("FU05 Playback Volume", 684 + SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT721_SDCA_ENT_USER_FU05, 685 + RT721_SDCA_CTL_FU_VOLUME, CH_L), 686 + SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT721_SDCA_ENT_USER_FU05, 687 + RT721_SDCA_CTL_FU_VOLUME, CH_R), 0, 0x57, 0, 688 + rt721_sdca_set_gain_get, rt721_sdca_set_gain_put, out_vol_tlv), 689 + /* Headset mic capture settings */ 690 + SOC_DOUBLE_EXT("FU0F Capture Switch", SND_SOC_NOPM, 0, 1, 1, 0, 691 + rt721_sdca_fu0f_capture_get, rt721_sdca_fu0f_capture_put), 692 + SOC_DOUBLE_R_EXT_TLV("FU0F Capture Volume", 693 + SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT721_SDCA_ENT_USER_FU0F, 694 + RT721_SDCA_CTL_FU_VOLUME, CH_L), 695 + SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT721_SDCA_ENT_USER_FU0F, 696 + RT721_SDCA_CTL_FU_VOLUME, CH_R), 0, 0x3f, 0, 697 + rt721_sdca_set_gain_get, rt721_sdca_set_gain_put, mic_vol_tlv), 698 + SOC_DOUBLE_R_EXT_TLV("FU33 Boost Volume", 699 + SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT721_SDCA_ENT_PLATFORM_FU44, 700 + RT721_SDCA_CTL_FU_CH_GAIN, CH_L), 701 + SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT721_SDCA_ENT_PLATFORM_FU44, 702 + RT721_SDCA_CTL_FU_CH_GAIN, CH_R), 1, 0x15, 0, 703 + rt721_sdca_set_gain_get, rt721_sdca_set_gain_put, mic2_boost_vol_tlv), 704 + /* AMP playback settings */ 705 + SOC_DOUBLE_R_EXT_TLV("FU06 Playback Volume", 706 + SDW_SDCA_CTL(FUNC_NUM_AMP, RT721_SDCA_ENT_USER_FU06, 707 + RT721_SDCA_CTL_FU_VOLUME, CH_L), 708 + SDW_SDCA_CTL(FUNC_NUM_AMP, RT721_SDCA_ENT_USER_FU06, 709 + RT721_SDCA_CTL_FU_VOLUME, CH_R), 0, 0x57, 0, 710 + rt721_sdca_set_gain_get, rt721_sdca_set_gain_put, out_vol_tlv), 711 + /* DMIC capture settings */ 712 + RT_SDCA_FU_CTRL("FU1E Capture Switch", 713 + SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT721_SDCA_ENT_USER_FU1E, 714 + RT721_SDCA_CTL_FU_MUTE, CH_01), 1, 1, 4, rt721_sdca_fu_info, 715 + rt721_sdca_fu1e_capture_get, rt721_sdca_fu1e_capture_put), 716 + RT_SDCA_EXT_TLV("FU1E Capture Volume", 717 + SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT721_SDCA_ENT_USER_FU1E, 718 + RT721_SDCA_CTL_FU_VOLUME, CH_01), 719 + rt721_sdca_dmic_set_gain_get, rt721_sdca_dmic_set_gain_put, 720 + 4, 0x3f, mic_vol_tlv, rt721_sdca_fu_info), 721 + RT_SDCA_EXT_TLV("FU15 Boost Volume", 722 + SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT721_SDCA_ENT_FU15, 723 + RT721_SDCA_CTL_FU_CH_GAIN, CH_01), 724 + rt721_sdca_dmic_set_gain_get, rt721_sdca_dmic_set_gain_put, 725 + 4, 3, boost_vol_tlv, rt721_sdca_fu_info), 726 + }; 727 + 728 + static int rt721_sdca_adc_mux_get(struct snd_kcontrol *kcontrol, 729 + struct snd_ctl_elem_value *ucontrol) 730 + { 731 + struct snd_soc_component *component = 732 + snd_soc_dapm_kcontrol_component(kcontrol); 733 + struct rt721_sdca_priv *rt721 = snd_soc_component_get_drvdata(component); 734 + unsigned int val = 0, mask_sft, mask; 735 + 736 + if (strstr(ucontrol->id.name, "ADC 09 Mux")) { 737 + mask_sft = 12; 738 + mask = 0x7; 739 + } else if (strstr(ucontrol->id.name, "ADC 08 R Mux")) { 740 + mask_sft = 10; 741 + mask = 0x3; 742 + } else if (strstr(ucontrol->id.name, "ADC 08 L Mux")) { 743 + mask_sft = 8; 744 + mask = 0x3; 745 + } else if (strstr(ucontrol->id.name, "ADC 10 R Mux")) { 746 + mask_sft = 6; 747 + mask = 0x3; 748 + } else if (strstr(ucontrol->id.name, "ADC 10 L Mux")) { 749 + mask_sft = 4; 750 + mask = 0x3; 751 + } else if (strstr(ucontrol->id.name, "ADC 07 R Mux")) { 752 + mask_sft = 2; 753 + mask = 0x3; 754 + } else if (strstr(ucontrol->id.name, "ADC 07 L Mux")) { 755 + mask_sft = 0; 756 + mask = 0x3; 757 + } else 758 + return -EINVAL; 759 + 760 + rt_sdca_index_read(rt721->mbq_regmap, RT721_HDA_SDCA_FLOAT, 761 + RT721_HDA_LEGACY_MUX_CTL0, &val); 762 + 763 + ucontrol->value.enumerated.item[0] = (val >> mask_sft) & mask; 764 + 765 + return 0; 766 + } 767 + 768 + static int rt721_sdca_adc_mux_put(struct snd_kcontrol *kcontrol, 769 + struct snd_ctl_elem_value *ucontrol) 770 + { 771 + struct snd_soc_component *component = 772 + snd_soc_dapm_kcontrol_component(kcontrol); 773 + struct snd_soc_dapm_context *dapm = 774 + snd_soc_dapm_kcontrol_dapm(kcontrol); 775 + struct rt721_sdca_priv *rt721 = snd_soc_component_get_drvdata(component); 776 + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 777 + unsigned int *item = ucontrol->value.enumerated.item; 778 + unsigned int val, val2 = 0, change, mask_sft, mask; 779 + unsigned int check; 780 + 781 + if (item[0] >= e->items) 782 + return -EINVAL; 783 + 784 + if (strstr(ucontrol->id.name, "ADC 09 Mux")) { 785 + mask_sft = 12; 786 + mask = 0x7; 787 + } else if (strstr(ucontrol->id.name, "ADC 08 R Mux")) { 788 + mask_sft = 10; 789 + mask = 0x3; 790 + } else if (strstr(ucontrol->id.name, "ADC 08 L Mux")) { 791 + mask_sft = 8; 792 + mask = 0x3; 793 + } else if (strstr(ucontrol->id.name, "ADC 10 R Mux")) { 794 + mask_sft = 6; 795 + mask = 0x3; 796 + } else if (strstr(ucontrol->id.name, "ADC 10 L Mux")) { 797 + mask_sft = 4; 798 + mask = 0x3; 799 + } else if (strstr(ucontrol->id.name, "ADC 07 R Mux")) { 800 + mask_sft = 2; 801 + mask = 0x3; 802 + } else if (strstr(ucontrol->id.name, "ADC 07 L Mux")) { 803 + mask_sft = 0; 804 + mask = 0x3; 805 + } else 806 + return -EINVAL; 807 + 808 + val = snd_soc_enum_item_to_val(e, item[0]) << e->shift_l; 809 + rt_sdca_index_read(rt721->mbq_regmap, RT721_HDA_SDCA_FLOAT, 810 + RT721_HDA_LEGACY_MUX_CTL0, &val2); 811 + 812 + if (strstr(ucontrol->id.name, "ADC 09 Mux")) 813 + val2 = (val2 >> mask_sft) & 0x7; 814 + else 815 + val2 = (val2 >> mask_sft) & 0x3; 816 + 817 + if (val == val2) 818 + change = 0; 819 + else 820 + change = 1; 821 + 822 + if (change) { 823 + rt_sdca_index_read(rt721->mbq_regmap, RT721_HDA_SDCA_FLOAT, 824 + RT721_HDA_LEGACY_MUX_CTL0, &check); 825 + rt_sdca_index_update_bits(rt721->mbq_regmap, RT721_HDA_SDCA_FLOAT, 826 + RT721_HDA_LEGACY_MUX_CTL0, mask << mask_sft, 827 + val << mask_sft); 828 + } 829 + 830 + snd_soc_dapm_mux_update_power(dapm, kcontrol, 831 + item[0], e, NULL); 832 + 833 + return change; 834 + } 835 + 836 + static const char * const adc09_mux_text[] = { 837 + "MIC2", 838 + "LINE1", 839 + "LINE2", 840 + }; 841 + static const char * const adc07_10_mux_text[] = { 842 + "DMIC1 RE", 843 + "DMIC1 FE", 844 + "DMIC2 RE", 845 + "DMIC2 FE", 846 + }; 847 + 848 + static SOC_ENUM_SINGLE_DECL( 849 + rt721_adc09_enum, SND_SOC_NOPM, 0, adc09_mux_text); 850 + static SOC_ENUM_SINGLE_DECL( 851 + rt721_dmic_enum, SND_SOC_NOPM, 0, adc07_10_mux_text); 852 + 853 + static const struct snd_kcontrol_new rt721_sdca_adc09_mux = 854 + SOC_DAPM_ENUM_EXT("ADC 09 Mux", rt721_adc09_enum, 855 + rt721_sdca_adc_mux_get, rt721_sdca_adc_mux_put); 856 + static const struct snd_kcontrol_new rt721_sdca_adc08_r_mux = 857 + SOC_DAPM_ENUM_EXT("ADC 08 R Mux", rt721_dmic_enum, 858 + rt721_sdca_adc_mux_get, rt721_sdca_adc_mux_put); 859 + static const struct snd_kcontrol_new rt721_sdca_adc08_l_mux = 860 + SOC_DAPM_ENUM_EXT("ADC 08 L Mux", rt721_dmic_enum, 861 + rt721_sdca_adc_mux_get, rt721_sdca_adc_mux_put); 862 + static const struct snd_kcontrol_new rt721_sdca_adc10_r_mux = 863 + SOC_DAPM_ENUM_EXT("ADC 10 R Mux", rt721_dmic_enum, 864 + rt721_sdca_adc_mux_get, rt721_sdca_adc_mux_put); 865 + static const struct snd_kcontrol_new rt721_sdca_adc10_l_mux = 866 + SOC_DAPM_ENUM_EXT("ADC 10 L Mux", rt721_dmic_enum, 867 + rt721_sdca_adc_mux_get, rt721_sdca_adc_mux_put); 868 + static const struct snd_kcontrol_new rt721_sdca_adc07_r_mux = 869 + SOC_DAPM_ENUM_EXT("ADC 07 R Mux", rt721_dmic_enum, 870 + rt721_sdca_adc_mux_get, rt721_sdca_adc_mux_put); 871 + static const struct snd_kcontrol_new rt721_sdca_adc07_l_mux = 872 + SOC_DAPM_ENUM_EXT("ADC 07 L Mux", rt721_dmic_enum, 873 + rt721_sdca_adc_mux_get, rt721_sdca_adc_mux_put); 874 + 875 + 876 + static int rt721_sdca_fu42_event(struct snd_soc_dapm_widget *w, 877 + struct snd_kcontrol *kcontrol, int event) 878 + { 879 + struct snd_soc_component *component = 880 + snd_soc_dapm_to_component(w->dapm); 881 + struct rt721_sdca_priv *rt721 = snd_soc_component_get_drvdata(component); 882 + unsigned char unmute = 0x0, mute = 0x1; 883 + 884 + switch (event) { 885 + case SND_SOC_DAPM_POST_PMU: 886 + msleep(100); 887 + regmap_write(rt721->regmap, 888 + SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT721_SDCA_ENT_USER_FU05, 889 + RT721_SDCA_CTL_FU_MUTE, CH_L), unmute); 890 + regmap_write(rt721->regmap, 891 + SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT721_SDCA_ENT_USER_FU05, 892 + RT721_SDCA_CTL_FU_MUTE, CH_R), unmute); 893 + break; 894 + case SND_SOC_DAPM_PRE_PMD: 895 + regmap_write(rt721->regmap, 896 + SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT721_SDCA_ENT_USER_FU05, 897 + RT721_SDCA_CTL_FU_MUTE, CH_L), mute); 898 + regmap_write(rt721->regmap, 899 + SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT721_SDCA_ENT_USER_FU05, 900 + RT721_SDCA_CTL_FU_MUTE, CH_R), mute); 901 + break; 902 + } 903 + return 0; 904 + } 905 + 906 + static int rt721_sdca_fu21_event(struct snd_soc_dapm_widget *w, 907 + struct snd_kcontrol *kcontrol, int event) 908 + { 909 + struct snd_soc_component *component = 910 + snd_soc_dapm_to_component(w->dapm); 911 + struct rt721_sdca_priv *rt721 = snd_soc_component_get_drvdata(component); 912 + unsigned char unmute = 0x0, mute = 0x1; 913 + 914 + switch (event) { 915 + case SND_SOC_DAPM_POST_PMU: 916 + regmap_write(rt721->regmap, 917 + SDW_SDCA_CTL(FUNC_NUM_AMP, RT721_SDCA_ENT_USER_FU06, 918 + RT721_SDCA_CTL_FU_MUTE, CH_L), unmute); 919 + regmap_write(rt721->regmap, 920 + SDW_SDCA_CTL(FUNC_NUM_AMP, RT721_SDCA_ENT_USER_FU06, 921 + RT721_SDCA_CTL_FU_MUTE, CH_R), unmute); 922 + break; 923 + case SND_SOC_DAPM_PRE_PMD: 924 + regmap_write(rt721->regmap, 925 + SDW_SDCA_CTL(FUNC_NUM_AMP, RT721_SDCA_ENT_USER_FU06, 926 + RT721_SDCA_CTL_FU_MUTE, CH_L), mute); 927 + regmap_write(rt721->regmap, 928 + SDW_SDCA_CTL(FUNC_NUM_AMP, RT721_SDCA_ENT_USER_FU06, 929 + RT721_SDCA_CTL_FU_MUTE, CH_R), mute); 930 + break; 931 + } 932 + return 0; 933 + } 934 + 935 + static int rt721_sdca_fu23_event(struct snd_soc_dapm_widget *w, 936 + struct snd_kcontrol *kcontrol, int event) 937 + { 938 + struct snd_soc_component *component = 939 + snd_soc_dapm_to_component(w->dapm); 940 + struct rt721_sdca_priv *rt721 = snd_soc_component_get_drvdata(component); 941 + unsigned char unmute = 0x0, mute = 0x1; 942 + 943 + switch (event) { 944 + case SND_SOC_DAPM_POST_PMU: 945 + regmap_write(rt721->regmap, 946 + SDW_SDCA_CTL(FUNC_NUM_AMP, RT721_SDCA_ENT_PDE23, 947 + RT721_SDCA_CTL_FU_MUTE, CH_L), unmute); 948 + regmap_write(rt721->regmap, 949 + SDW_SDCA_CTL(FUNC_NUM_AMP, RT721_SDCA_ENT_PDE23, 950 + RT721_SDCA_CTL_FU_MUTE, CH_R), unmute); 951 + break; 952 + case SND_SOC_DAPM_PRE_PMD: 953 + regmap_write(rt721->regmap, 954 + SDW_SDCA_CTL(FUNC_NUM_AMP, RT721_SDCA_ENT_PDE23, 955 + RT721_SDCA_CTL_FU_MUTE, CH_L), mute); 956 + regmap_write(rt721->regmap, 957 + SDW_SDCA_CTL(FUNC_NUM_AMP, RT721_SDCA_ENT_PDE23, 958 + RT721_SDCA_CTL_FU_MUTE, CH_R), mute); 959 + break; 960 + } 961 + return 0; 962 + } 963 + 964 + static int rt721_sdca_fu113_event(struct snd_soc_dapm_widget *w, 965 + struct snd_kcontrol *kcontrol, int event) 966 + { 967 + struct snd_soc_component *component = 968 + snd_soc_dapm_to_component(w->dapm); 969 + struct rt721_sdca_priv *rt721 = snd_soc_component_get_drvdata(component); 970 + 971 + switch (event) { 972 + case SND_SOC_DAPM_POST_PMU: 973 + rt721->fu1e_dapm_mute = false; 974 + rt721_sdca_set_fu1e_capture_ctl(rt721); 975 + break; 976 + case SND_SOC_DAPM_PRE_PMD: 977 + rt721->fu1e_dapm_mute = true; 978 + rt721_sdca_set_fu1e_capture_ctl(rt721); 979 + break; 980 + } 981 + return 0; 982 + } 983 + 984 + static int rt721_sdca_fu36_event(struct snd_soc_dapm_widget *w, 985 + struct snd_kcontrol *kcontrol, int event) 986 + { 987 + struct snd_soc_component *component = 988 + snd_soc_dapm_to_component(w->dapm); 989 + struct rt721_sdca_priv *rt721 = snd_soc_component_get_drvdata(component); 990 + 991 + switch (event) { 992 + case SND_SOC_DAPM_POST_PMU: 993 + rt721->fu0f_dapm_mute = false; 994 + rt721_sdca_set_fu0f_capture_ctl(rt721); 995 + break; 996 + case SND_SOC_DAPM_PRE_PMD: 997 + rt721->fu0f_dapm_mute = true; 998 + rt721_sdca_set_fu0f_capture_ctl(rt721); 999 + break; 1000 + } 1001 + return 0; 1002 + } 1003 + 1004 + static int rt721_sdca_pde47_event(struct snd_soc_dapm_widget *w, 1005 + struct snd_kcontrol *kcontrol, int event) 1006 + { 1007 + struct snd_soc_component *component = 1008 + snd_soc_dapm_to_component(w->dapm); 1009 + struct rt721_sdca_priv *rt721 = snd_soc_component_get_drvdata(component); 1010 + unsigned char ps0 = 0x0, ps3 = 0x3; 1011 + 1012 + switch (event) { 1013 + case SND_SOC_DAPM_POST_PMU: 1014 + regmap_write(rt721->regmap, 1015 + SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT721_SDCA_ENT_PDE40, 1016 + RT721_SDCA_CTL_REQ_POWER_STATE, 0), ps0); 1017 + break; 1018 + case SND_SOC_DAPM_PRE_PMD: 1019 + regmap_write(rt721->regmap, 1020 + SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT721_SDCA_ENT_PDE40, 1021 + RT721_SDCA_CTL_REQ_POWER_STATE, 0), ps3); 1022 + break; 1023 + } 1024 + return 0; 1025 + } 1026 + 1027 + static int rt721_sdca_pde41_event(struct snd_soc_dapm_widget *w, 1028 + struct snd_kcontrol *kcontrol, int event) 1029 + { 1030 + struct snd_soc_component *component = 1031 + snd_soc_dapm_to_component(w->dapm); 1032 + struct rt721_sdca_priv *rt721 = snd_soc_component_get_drvdata(component); 1033 + unsigned char ps0 = 0x0, ps3 = 0x3; 1034 + 1035 + switch (event) { 1036 + case SND_SOC_DAPM_POST_PMU: 1037 + regmap_write(rt721->regmap, 1038 + SDW_SDCA_CTL(FUNC_NUM_AMP, RT721_SDCA_ENT_PDE41, 1039 + RT721_SDCA_CTL_REQ_POWER_STATE, 0), ps0); 1040 + break; 1041 + case SND_SOC_DAPM_PRE_PMD: 1042 + regmap_write(rt721->regmap, 1043 + SDW_SDCA_CTL(FUNC_NUM_AMP, RT721_SDCA_ENT_PDE41, 1044 + RT721_SDCA_CTL_REQ_POWER_STATE, 0), ps3); 1045 + break; 1046 + } 1047 + return 0; 1048 + } 1049 + 1050 + static int rt721_sdca_pde11_event(struct snd_soc_dapm_widget *w, 1051 + struct snd_kcontrol *kcontrol, int event) 1052 + { 1053 + struct snd_soc_component *component = 1054 + snd_soc_dapm_to_component(w->dapm); 1055 + struct rt721_sdca_priv *rt721 = snd_soc_component_get_drvdata(component); 1056 + unsigned char ps0 = 0x0, ps3 = 0x3; 1057 + 1058 + switch (event) { 1059 + case SND_SOC_DAPM_POST_PMU: 1060 + regmap_write(rt721->regmap, 1061 + SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT721_SDCA_ENT_PDE2A, 1062 + RT721_SDCA_CTL_REQ_POWER_STATE, 0), ps0); 1063 + break; 1064 + case SND_SOC_DAPM_PRE_PMD: 1065 + regmap_write(rt721->regmap, 1066 + SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT721_SDCA_ENT_PDE2A, 1067 + RT721_SDCA_CTL_REQ_POWER_STATE, 0), ps3); 1068 + break; 1069 + } 1070 + return 0; 1071 + } 1072 + 1073 + static int rt721_sdca_pde34_event(struct snd_soc_dapm_widget *w, 1074 + struct snd_kcontrol *kcontrol, int event) 1075 + { 1076 + struct snd_soc_component *component = 1077 + snd_soc_dapm_to_component(w->dapm); 1078 + struct rt721_sdca_priv *rt721 = snd_soc_component_get_drvdata(component); 1079 + unsigned char ps0 = 0x0, ps3 = 0x3; 1080 + 1081 + switch (event) { 1082 + case SND_SOC_DAPM_POST_PMU: 1083 + regmap_write(rt721->regmap, 1084 + SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT721_SDCA_ENT_PDE12, 1085 + RT721_SDCA_CTL_REQ_POWER_STATE, 0), ps0); 1086 + break; 1087 + case SND_SOC_DAPM_PRE_PMD: 1088 + regmap_write(rt721->regmap, 1089 + SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT721_SDCA_ENT_PDE12, 1090 + RT721_SDCA_CTL_REQ_POWER_STATE, 0), ps3); 1091 + break; 1092 + } 1093 + return 0; 1094 + } 1095 + 1096 + static const struct snd_soc_dapm_widget rt721_sdca_dapm_widgets[] = { 1097 + SND_SOC_DAPM_OUTPUT("HP"), 1098 + SND_SOC_DAPM_OUTPUT("SPK"), 1099 + SND_SOC_DAPM_INPUT("MIC2"), 1100 + SND_SOC_DAPM_INPUT("LINE1"), 1101 + SND_SOC_DAPM_INPUT("LINE2"), 1102 + SND_SOC_DAPM_INPUT("DMIC1_2"), 1103 + SND_SOC_DAPM_INPUT("DMIC3_4"), 1104 + 1105 + SND_SOC_DAPM_SUPPLY("PDE 41", SND_SOC_NOPM, 0, 0, 1106 + rt721_sdca_pde41_event, 1107 + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), 1108 + SND_SOC_DAPM_SUPPLY("PDE 47", SND_SOC_NOPM, 0, 0, 1109 + rt721_sdca_pde47_event, 1110 + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), 1111 + SND_SOC_DAPM_SUPPLY("PDE 11", SND_SOC_NOPM, 0, 0, 1112 + rt721_sdca_pde11_event, 1113 + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), 1114 + SND_SOC_DAPM_SUPPLY("PDE 34", SND_SOC_NOPM, 0, 0, 1115 + rt721_sdca_pde34_event, 1116 + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), 1117 + 1118 + SND_SOC_DAPM_DAC_E("FU 21", NULL, SND_SOC_NOPM, 0, 0, 1119 + rt721_sdca_fu21_event, 1120 + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), 1121 + SND_SOC_DAPM_DAC_E("FU 23", NULL, SND_SOC_NOPM, 0, 0, 1122 + rt721_sdca_fu23_event, 1123 + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), 1124 + SND_SOC_DAPM_DAC_E("FU 42", NULL, SND_SOC_NOPM, 0, 0, 1125 + rt721_sdca_fu42_event, 1126 + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), 1127 + SND_SOC_DAPM_ADC_E("FU 36", NULL, SND_SOC_NOPM, 0, 0, 1128 + rt721_sdca_fu36_event, 1129 + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), 1130 + SND_SOC_DAPM_ADC_E("FU 113", NULL, SND_SOC_NOPM, 0, 0, 1131 + rt721_sdca_fu113_event, 1132 + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), 1133 + SND_SOC_DAPM_MUX("ADC 09 Mux", SND_SOC_NOPM, 0, 0, 1134 + &rt721_sdca_adc09_mux), 1135 + SND_SOC_DAPM_MUX("ADC 08 R Mux", SND_SOC_NOPM, 0, 0, 1136 + &rt721_sdca_adc08_r_mux), 1137 + SND_SOC_DAPM_MUX("ADC 08 L Mux", SND_SOC_NOPM, 0, 0, 1138 + &rt721_sdca_adc08_l_mux), 1139 + SND_SOC_DAPM_MUX("ADC 10 R Mux", SND_SOC_NOPM, 0, 0, 1140 + &rt721_sdca_adc10_r_mux), 1141 + SND_SOC_DAPM_MUX("ADC 10 L Mux", SND_SOC_NOPM, 0, 0, 1142 + &rt721_sdca_adc10_l_mux), 1143 + SND_SOC_DAPM_MUX("ADC 07 R Mux", SND_SOC_NOPM, 0, 0, 1144 + &rt721_sdca_adc07_r_mux), 1145 + SND_SOC_DAPM_MUX("ADC 07 L Mux", SND_SOC_NOPM, 0, 0, 1146 + &rt721_sdca_adc07_l_mux), 1147 + 1148 + SND_SOC_DAPM_AIF_IN("DP1RX", "DP1 Headphone Playback", 0, SND_SOC_NOPM, 0, 0), 1149 + SND_SOC_DAPM_AIF_OUT("DP2TX", "DP2 Headset Capture", 0, SND_SOC_NOPM, 0, 0), 1150 + SND_SOC_DAPM_AIF_IN("DP3RX", "DP3 Speaker Playback", 0, SND_SOC_NOPM, 0, 0), 1151 + SND_SOC_DAPM_AIF_OUT("DP6TX", "DP6 DMic Capture", 0, SND_SOC_NOPM, 0, 0), 1152 + }; 1153 + 1154 + static const struct snd_soc_dapm_route rt721_sdca_audio_map[] = { 1155 + {"FU 42", NULL, "DP1RX"}, 1156 + {"FU 21", NULL, "DP3RX"}, 1157 + {"FU 23", NULL, "DP3RX"}, 1158 + 1159 + {"ADC 09 Mux", "MIC2", "MIC2"}, 1160 + {"ADC 09 Mux", "LINE1", "LINE1"}, 1161 + {"ADC 09 Mux", "LINE2", "LINE2"}, 1162 + {"ADC 07 R Mux", "DMIC1 RE", "DMIC1_2"}, 1163 + {"ADC 07 R Mux", "DMIC1 FE", "DMIC1_2"}, 1164 + {"ADC 07 R Mux", "DMIC2 RE", "DMIC3_4"}, 1165 + {"ADC 07 R Mux", "DMIC2 FE", "DMIC3_4"}, 1166 + {"ADC 07 L Mux", "DMIC1 RE", "DMIC1_2"}, 1167 + {"ADC 07 L Mux", "DMIC1 FE", "DMIC1_2"}, 1168 + {"ADC 07 L Mux", "DMIC2 RE", "DMIC3_4"}, 1169 + {"ADC 07 L Mux", "DMIC2 FE", "DMIC3_4"}, 1170 + {"ADC 08 R Mux", "DMIC1 RE", "DMIC1_2"}, 1171 + {"ADC 08 R Mux", "DMIC1 FE", "DMIC1_2"}, 1172 + {"ADC 08 R Mux", "DMIC2 RE", "DMIC3_4"}, 1173 + {"ADC 08 R Mux", "DMIC2 FE", "DMIC3_4"}, 1174 + {"ADC 08 L Mux", "DMIC1 RE", "DMIC1_2"}, 1175 + {"ADC 08 L Mux", "DMIC1 FE", "DMIC1_2"}, 1176 + {"ADC 08 L Mux", "DMIC2 RE", "DMIC3_4"}, 1177 + {"ADC 08 L Mux", "DMIC2 FE", "DMIC3_4"}, 1178 + {"ADC 10 R Mux", "DMIC1 RE", "DMIC1_2"}, 1179 + {"ADC 10 R Mux", "DMIC1 FE", "DMIC1_2"}, 1180 + {"ADC 10 R Mux", "DMIC2 RE", "DMIC3_4"}, 1181 + {"ADC 10 R Mux", "DMIC2 FE", "DMIC3_4"}, 1182 + {"ADC 10 L Mux", "DMIC1 RE", "DMIC1_2"}, 1183 + {"ADC 10 L Mux", "DMIC1 FE", "DMIC1_2"}, 1184 + {"ADC 10 L Mux", "DMIC2 RE", "DMIC3_4"}, 1185 + {"ADC 10 L Mux", "DMIC2 FE", "DMIC3_4"}, 1186 + {"FU 36", NULL, "PDE 34"}, 1187 + {"FU 36", NULL, "ADC 09 Mux"}, 1188 + {"FU 113", NULL, "PDE 11"}, 1189 + {"FU 113", NULL, "ADC 07 R Mux"}, 1190 + {"FU 113", NULL, "ADC 07 L Mux"}, 1191 + {"FU 113", NULL, "ADC 10 R Mux"}, 1192 + {"FU 113", NULL, "ADC 10 L Mux"}, 1193 + {"DP2TX", NULL, "FU 36"}, 1194 + {"DP6TX", NULL, "FU 113"}, 1195 + 1196 + {"HP", NULL, "PDE 47"}, 1197 + {"HP", NULL, "FU 42"}, 1198 + {"SPK", NULL, "PDE 41"}, 1199 + {"SPK", NULL, "FU 21"}, 1200 + {"SPK", NULL, "FU 23"}, 1201 + }; 1202 + 1203 + static int rt721_sdca_parse_dt(struct rt721_sdca_priv *rt721, struct device *dev) 1204 + { 1205 + device_property_read_u32(dev, "realtek,jd-src", &rt721->jd_src); 1206 + 1207 + return 0; 1208 + } 1209 + 1210 + static int rt721_sdca_probe(struct snd_soc_component *component) 1211 + { 1212 + struct rt721_sdca_priv *rt721 = snd_soc_component_get_drvdata(component); 1213 + int ret; 1214 + 1215 + rt721_sdca_parse_dt(rt721, &rt721->slave->dev); 1216 + rt721->component = component; 1217 + 1218 + ret = pm_runtime_resume(component->dev); 1219 + if (ret < 0 && ret != -EACCES) 1220 + return ret; 1221 + 1222 + return 0; 1223 + } 1224 + 1225 + static const struct snd_soc_component_driver soc_sdca_dev_rt721 = { 1226 + .probe = rt721_sdca_probe, 1227 + .controls = rt721_sdca_controls, 1228 + .num_controls = ARRAY_SIZE(rt721_sdca_controls), 1229 + .dapm_widgets = rt721_sdca_dapm_widgets, 1230 + .num_dapm_widgets = ARRAY_SIZE(rt721_sdca_dapm_widgets), 1231 + .dapm_routes = rt721_sdca_audio_map, 1232 + .num_dapm_routes = ARRAY_SIZE(rt721_sdca_audio_map), 1233 + .set_jack = rt721_sdca_set_jack_detect, 1234 + .endianness = 1, 1235 + }; 1236 + 1237 + static int rt721_sdca_set_sdw_stream(struct snd_soc_dai *dai, void *sdw_stream, 1238 + int direction) 1239 + { 1240 + snd_soc_dai_dma_data_set(dai, direction, sdw_stream); 1241 + 1242 + return 0; 1243 + } 1244 + 1245 + static void rt721_sdca_shutdown(struct snd_pcm_substream *substream, 1246 + struct snd_soc_dai *dai) 1247 + { 1248 + snd_soc_dai_set_dma_data(dai, substream, NULL); 1249 + } 1250 + 1251 + static int rt721_sdca_pcm_hw_params(struct snd_pcm_substream *substream, 1252 + struct snd_pcm_hw_params *params, 1253 + struct snd_soc_dai *dai) 1254 + { 1255 + struct snd_soc_component *component = dai->component; 1256 + struct rt721_sdca_priv *rt721 = snd_soc_component_get_drvdata(component); 1257 + struct sdw_stream_config stream_config; 1258 + struct sdw_port_config port_config; 1259 + enum sdw_data_direction direction; 1260 + struct sdw_stream_runtime *sdw_stream; 1261 + int retval, port, num_channels; 1262 + unsigned int sampling_rate; 1263 + 1264 + dev_dbg(dai->dev, "%s %s", __func__, dai->name); 1265 + sdw_stream = snd_soc_dai_get_dma_data(dai, substream); 1266 + 1267 + if (!sdw_stream) 1268 + return -EINVAL; 1269 + 1270 + if (!rt721->slave) 1271 + return -EINVAL; 1272 + 1273 + /* 1274 + * RT721_AIF1 with port = 1 for headphone playback 1275 + * RT721_AIF1 with port = 2 for headset-mic capture 1276 + * RT721_AIF2 with port = 3 for speaker playback 1277 + * RT721_AIF3 with port = 6 for digital-mic capture 1278 + */ 1279 + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 1280 + direction = SDW_DATA_DIR_RX; 1281 + if (dai->id == RT721_AIF1) 1282 + port = 1; 1283 + else if (dai->id == RT721_AIF2) 1284 + port = 3; 1285 + else 1286 + return -EINVAL; 1287 + } else { 1288 + direction = SDW_DATA_DIR_TX; 1289 + if (dai->id == RT721_AIF1) 1290 + port = 2; 1291 + else if (dai->id == RT721_AIF3) 1292 + port = 6; 1293 + else 1294 + return -EINVAL; 1295 + } 1296 + stream_config.frame_rate = params_rate(params); 1297 + stream_config.ch_count = params_channels(params); 1298 + stream_config.bps = snd_pcm_format_width(params_format(params)); 1299 + stream_config.direction = direction; 1300 + 1301 + num_channels = params_channels(params); 1302 + port_config.ch_mask = GENMASK(num_channels - 1, 0); 1303 + port_config.num = port; 1304 + 1305 + retval = sdw_stream_add_slave(rt721->slave, &stream_config, 1306 + &port_config, 1, sdw_stream); 1307 + if (retval) { 1308 + dev_err(dai->dev, "Unable to configure port\n"); 1309 + return retval; 1310 + } 1311 + 1312 + if (params_channels(params) > 16) { 1313 + dev_err(component->dev, "Unsupported channels %d\n", 1314 + params_channels(params)); 1315 + return -EINVAL; 1316 + } 1317 + 1318 + /* sampling rate configuration */ 1319 + switch (params_rate(params)) { 1320 + case 8000: 1321 + sampling_rate = RT721_SDCA_RATE_8000HZ; 1322 + break; 1323 + case 16000: 1324 + sampling_rate = RT721_SDCA_RATE_16000HZ; 1325 + break; 1326 + case 24000: 1327 + sampling_rate = RT721_SDCA_RATE_24000HZ; 1328 + break; 1329 + case 32000: 1330 + sampling_rate = RT721_SDCA_RATE_32000HZ; 1331 + break; 1332 + case 44100: 1333 + sampling_rate = RT721_SDCA_RATE_44100HZ; 1334 + break; 1335 + case 48000: 1336 + sampling_rate = RT721_SDCA_RATE_48000HZ; 1337 + break; 1338 + case 96000: 1339 + sampling_rate = RT721_SDCA_RATE_96000HZ; 1340 + break; 1341 + case 192000: 1342 + sampling_rate = RT721_SDCA_RATE_192000HZ; 1343 + break; 1344 + case 384000: 1345 + sampling_rate = RT721_SDCA_RATE_384000HZ; 1346 + break; 1347 + case 768000: 1348 + sampling_rate = RT721_SDCA_RATE_768000HZ; 1349 + break; 1350 + default: 1351 + dev_err(component->dev, "Rate %d is not supported\n", 1352 + params_rate(params)); 1353 + return -EINVAL; 1354 + } 1355 + 1356 + /* set sampling frequency */ 1357 + if (dai->id == RT721_AIF1) { 1358 + regmap_write(rt721->regmap, 1359 + SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT721_SDCA_ENT_CS01, 1360 + RT721_SDCA_CTL_SAMPLE_FREQ_INDEX, 0), sampling_rate); 1361 + regmap_write(rt721->regmap, 1362 + SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT721_SDCA_ENT_CS11, 1363 + RT721_SDCA_CTL_SAMPLE_FREQ_INDEX, 0), sampling_rate); 1364 + } 1365 + 1366 + if (dai->id == RT721_AIF2) 1367 + regmap_write(rt721->regmap, 1368 + SDW_SDCA_CTL(FUNC_NUM_AMP, RT721_SDCA_ENT_CS31, 1369 + RT721_SDCA_CTL_SAMPLE_FREQ_INDEX, 0), sampling_rate); 1370 + 1371 + if (dai->id == RT721_AIF3) 1372 + regmap_write(rt721->regmap, 1373 + SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT721_SDCA_ENT_CS1F, 1374 + RT721_SDCA_CTL_SAMPLE_FREQ_INDEX, 0), sampling_rate); 1375 + 1376 + return 0; 1377 + } 1378 + 1379 + static int rt721_sdca_pcm_hw_free(struct snd_pcm_substream *substream, 1380 + struct snd_soc_dai *dai) 1381 + { 1382 + struct snd_soc_component *component = dai->component; 1383 + struct rt721_sdca_priv *rt721 = snd_soc_component_get_drvdata(component); 1384 + struct sdw_stream_runtime *sdw_stream = 1385 + snd_soc_dai_get_dma_data(dai, substream); 1386 + 1387 + if (!rt721->slave) 1388 + return -EINVAL; 1389 + 1390 + sdw_stream_remove_slave(rt721->slave, sdw_stream); 1391 + return 0; 1392 + } 1393 + 1394 + #define RT721_STEREO_RATES (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | \ 1395 + SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000) 1396 + #define RT721_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \ 1397 + SNDRV_PCM_FMTBIT_S24_LE) 1398 + 1399 + static const struct snd_soc_dai_ops rt721_sdca_ops = { 1400 + .hw_params = rt721_sdca_pcm_hw_params, 1401 + .hw_free = rt721_sdca_pcm_hw_free, 1402 + .set_stream = rt721_sdca_set_sdw_stream, 1403 + .shutdown = rt721_sdca_shutdown, 1404 + }; 1405 + 1406 + static struct snd_soc_dai_driver rt721_sdca_dai[] = { 1407 + { 1408 + .name = "rt721-sdca-aif1", 1409 + .id = RT721_AIF1, 1410 + .playback = { 1411 + .stream_name = "DP1 Headphone Playback", 1412 + .channels_min = 1, 1413 + .channels_max = 2, 1414 + .rates = RT721_STEREO_RATES, 1415 + .formats = RT721_FORMATS, 1416 + }, 1417 + .capture = { 1418 + .stream_name = "DP2 Headset Capture", 1419 + .channels_min = 1, 1420 + .channels_max = 2, 1421 + .rates = RT721_STEREO_RATES, 1422 + .formats = RT721_FORMATS, 1423 + }, 1424 + .ops = &rt721_sdca_ops, 1425 + }, 1426 + { 1427 + .name = "rt721-sdca-aif2", 1428 + .id = RT721_AIF2, 1429 + .playback = { 1430 + .stream_name = "DP3 Speaker Playback", 1431 + .channels_min = 1, 1432 + .channels_max = 2, 1433 + .rates = RT721_STEREO_RATES, 1434 + .formats = RT721_FORMATS, 1435 + }, 1436 + .ops = &rt721_sdca_ops, 1437 + }, 1438 + { 1439 + .name = "rt721-sdca-aif3", 1440 + .id = RT721_AIF3, 1441 + .capture = { 1442 + .stream_name = "DP6 DMic Capture", 1443 + .channels_min = 1, 1444 + .channels_max = 4, 1445 + .rates = RT721_STEREO_RATES, 1446 + .formats = RT721_FORMATS, 1447 + }, 1448 + .ops = &rt721_sdca_ops, 1449 + } 1450 + }; 1451 + 1452 + int rt721_sdca_init(struct device *dev, struct regmap *regmap, 1453 + struct regmap *mbq_regmap, struct sdw_slave *slave) 1454 + { 1455 + struct rt721_sdca_priv *rt721; 1456 + 1457 + rt721 = devm_kzalloc(dev, sizeof(*rt721), GFP_KERNEL); 1458 + if (!rt721) 1459 + return -ENOMEM; 1460 + 1461 + dev_set_drvdata(dev, rt721); 1462 + rt721->slave = slave; 1463 + rt721->regmap = regmap; 1464 + rt721->mbq_regmap = mbq_regmap; 1465 + 1466 + regcache_cache_only(rt721->regmap, true); 1467 + regcache_cache_only(rt721->mbq_regmap, true); 1468 + 1469 + mutex_init(&rt721->calibrate_mutex); 1470 + mutex_init(&rt721->disable_irq_lock); 1471 + 1472 + INIT_DELAYED_WORK(&rt721->jack_detect_work, rt721_sdca_jack_detect_handler); 1473 + INIT_DELAYED_WORK(&rt721->jack_btn_check_work, rt721_sdca_btn_check_handler); 1474 + 1475 + /* 1476 + * Mark hw_init to false 1477 + * HW init will be performed when device reports present 1478 + */ 1479 + rt721->hw_init = false; 1480 + rt721->first_hw_init = false; 1481 + rt721->fu1e_dapm_mute = true; 1482 + rt721->fu0f_dapm_mute = true; 1483 + rt721->fu0f_mixer_l_mute = rt721->fu0f_mixer_r_mute = true; 1484 + rt721->fu1e_mixer_mute[0] = rt721->fu1e_mixer_mute[1] = 1485 + rt721->fu1e_mixer_mute[2] = rt721->fu1e_mixer_mute[3] = true; 1486 + 1487 + return devm_snd_soc_register_component(dev, 1488 + &soc_sdca_dev_rt721, rt721_sdca_dai, ARRAY_SIZE(rt721_sdca_dai)); 1489 + } 1490 + 1491 + int rt721_sdca_io_init(struct device *dev, struct sdw_slave *slave) 1492 + { 1493 + struct rt721_sdca_priv *rt721 = dev_get_drvdata(dev); 1494 + 1495 + rt721->disable_irq = false; 1496 + 1497 + if (rt721->hw_init) 1498 + return 0; 1499 + 1500 + regcache_cache_only(rt721->regmap, false); 1501 + regcache_cache_only(rt721->mbq_regmap, false); 1502 + if (rt721->first_hw_init) { 1503 + regcache_cache_bypass(rt721->regmap, true); 1504 + regcache_cache_bypass(rt721->mbq_regmap, true); 1505 + } else { 1506 + /* 1507 + * PM runtime is only enabled when a Slave reports as Attached 1508 + */ 1509 + 1510 + /* set autosuspend parameters */ 1511 + pm_runtime_set_autosuspend_delay(&slave->dev, 3000); 1512 + pm_runtime_use_autosuspend(&slave->dev); 1513 + 1514 + /* update count of parent 'active' children */ 1515 + pm_runtime_set_active(&slave->dev); 1516 + 1517 + /* make sure the device does not suspend immediately */ 1518 + pm_runtime_mark_last_busy(&slave->dev); 1519 + 1520 + pm_runtime_enable(&slave->dev); 1521 + } 1522 + 1523 + pm_runtime_get_noresume(&slave->dev); 1524 + rt721_sdca_dmic_preset(rt721); 1525 + rt721_sdca_amp_preset(rt721); 1526 + rt721_sdca_jack_preset(rt721); 1527 + if (rt721->first_hw_init) { 1528 + regcache_cache_bypass(rt721->regmap, false); 1529 + regcache_mark_dirty(rt721->regmap); 1530 + regcache_cache_bypass(rt721->mbq_regmap, false); 1531 + regcache_mark_dirty(rt721->mbq_regmap); 1532 + } else 1533 + rt721->first_hw_init = true; 1534 + 1535 + /* Mark Slave initialization complete */ 1536 + rt721->hw_init = true; 1537 + 1538 + pm_runtime_mark_last_busy(&slave->dev); 1539 + pm_runtime_put_autosuspend(&slave->dev); 1540 + 1541 + dev_dbg(&slave->dev, "%s hw_init complete\n", __func__); 1542 + return 0; 1543 + } 1544 + 1545 + MODULE_DESCRIPTION("ASoC RT721 SDCA SDW driver"); 1546 + MODULE_AUTHOR("Jack Yu <jack.yu@realtek.com>"); 1547 + MODULE_LICENSE("GPL");
+268
sound/soc/codecs/rt721-sdca.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-only */ 2 + /* 3 + * rt721-sdca.h -- RT721 SDCA ALSA SoC audio driver header 4 + * 5 + * Copyright(c) 2024 Realtek Semiconductor Corp. 6 + */ 7 + 8 + #ifndef __RT721_H__ 9 + #define __RT721_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 rt721_sdca_priv { 19 + struct regmap *regmap; 20 + struct regmap *mbq_regmap; 21 + struct snd_soc_component *component; 22 + struct sdw_slave *slave; 23 + struct sdw_bus_params params; 24 + bool hw_init; 25 + bool first_hw_init; 26 + struct mutex calibrate_mutex; 27 + struct mutex disable_irq_lock; 28 + bool disable_irq; 29 + /* For Headset jack & Headphone */ 30 + unsigned int scp_sdca_stat1; 31 + unsigned int scp_sdca_stat2; 32 + struct snd_soc_jack *hs_jack; 33 + struct delayed_work jack_detect_work; 34 + struct delayed_work jack_btn_check_work; 35 + int jack_type; 36 + int jd_src; 37 + bool fu0f_dapm_mute; 38 + bool fu0f_mixer_l_mute; 39 + bool fu0f_mixer_r_mute; 40 + /* For DMIC */ 41 + bool fu1e_dapm_mute; 42 + bool fu1e_mixer_mute[4]; 43 + }; 44 + 45 + struct rt721_sdca_dmic_kctrl_priv { 46 + unsigned int reg_base; 47 + unsigned int count; 48 + unsigned int max; 49 + unsigned int invert; 50 + }; 51 + 52 + /* NID */ 53 + #define RT721_ANA_POW_PART 0x01 54 + #define RT721_DAC_CTRL 0x04 55 + #define RT721_JD_CTRL 0x09 56 + #define RT721_CBJ_CTRL 0x0a 57 + #define RT721_CAP_PORT_CTRL 0x0c 58 + #define RT721_CLASD_AMP_CTRL 0x0d 59 + #define RT721_VENDOR_REG 0x20 60 + #define RT721_RC_CALIB_CTRL 0x40 61 + #define RT721_VENDOR_EQ_L 0x53 62 + #define RT721_VENDOR_EQ_R 0x54 63 + #define RT721_VENDOR_HP_CALI 0x56 64 + #define RT721_VENDOR_CHARGE_PUMP 0x57 65 + #define RT721_VENDOR_CLASD_CALI 0x58 66 + #define RT721_VENDOR_IMS_DRE 0x5b 67 + #define RT721_VENDOR_SPK_EFUSE 0x5c 68 + #define RT721_VENDOR_LEVEL_CTRL 0x5d 69 + #define RT721_VENDOR_ANA_CTL 0x5f 70 + #define RT721_HDA_SDCA_FLOAT 0x61 71 + 72 + /* Index (NID:01h) */ 73 + #define RT721_MBIAS_LV_CTRL2 0x07 74 + #define RT721_VREF1_HV_CTRL1 0x0a 75 + #define RT721_VREF2_LV_CTRL1 0x0b 76 + 77 + /* Index (NID:04h) */ 78 + #define RT721_DAC_2CH_CTRL3 0x02 79 + #define RT721_DAC_2CH_CTRL4 0x03 80 + 81 + /* Index (NID:09h) */ 82 + #define RT721_JD_1PIN_GAT_CTRL2 0x07 83 + 84 + /* Index (NID:0ah) */ 85 + #define RT721_CBJ_A0_GAT_CTRL1 0x04 86 + #define RT721_CBJ_A0_GAT_CTRL2 0x05 87 + 88 + /* Index (NID:0Ch) */ 89 + #define RT721_HP_AMP_2CH_CAL1 0x05 90 + #define RT721_HP_AMP_2CH_CAL4 0x08 91 + #define RT721_HP_AMP_2CH_CAL18 0x1b 92 + 93 + /* Index (NID:0dh) */ 94 + #define RT721_CLASD_AMP_2CH_CAL 0x14 95 + 96 + /* Index (NID:20h) */ 97 + #define RT721_JD_PRODUCT_NUM 0x00 98 + #define RT721_ANALOG_BIAS_CTL3 0x04 99 + #define RT721_JD_CTRL1 0x09 100 + #define RT721_LDO2_3_CTL1 0x0e 101 + #define RT721_GPIO_PAD_CTRL5 0x13 102 + #define RT721_LDO1_CTL 0x1a 103 + #define RT721_HP_JD_CTRL 0x24 104 + #define RT721_VD_HIDDEN_CTRL 0x26 105 + #define RT721_CLSD_CTRL6 0x3c 106 + #define RT721_COMBO_JACK_AUTO_CTL1 0x45 107 + #define RT721_COMBO_JACK_AUTO_CTL2 0x46 108 + #define RT721_COMBO_JACK_AUTO_CTL3 0x47 109 + #define RT721_DIGITAL_MISC_CTRL4 0x4a 110 + #define RT721_VREFO_GAT 0x63 111 + #define RT721_FSM_CTL 0x67 112 + #define RT721_SDCA_INTR_REC 0x82 113 + #define RT721_SW_CONFIG1 0x8a 114 + #define RT721_SW_CONFIG2 0x8b 115 + 116 + /* Index (NID:40h) */ 117 + #define RT721_RC_CALIB_CTRL0 0x00 118 + 119 + /* Index (NID:58h) */ 120 + #define RT721_DAC_DC_CALI_CTL1 0x01 121 + #define RT721_DAC_DC_CALI_CTL2 0x02 122 + #define RT721_DAC_DC_CALI_CTL3 0x03 123 + 124 + /* Index (NID:5fh) */ 125 + #define RT721_MISC_POWER_CTL0 0x00 126 + #define RT721_MISC_POWER_CTL31 0x31 127 + #define RT721_UAJ_TOP_TCON13 0x44 128 + #define RT721_UAJ_TOP_TCON14 0x45 129 + #define RT721_UAJ_TOP_TCON17 0x48 130 + 131 + /* Index (NID:61h) */ 132 + #define RT721_HDA_LEGACY_MUX_CTL0 0x00 133 + #define RT721_HDA_LEGACY_UAJ_CTL 0x02 134 + #define RT721_HDA_LEGACY_CTL1 0x05 135 + #define RT721_HDA_LEGACY_RESET_CTL 0x06 136 + #define RT721_GE_REL_CTRL1 0x0d 137 + #define RT721_HDA_LEGACY_GPIO_WAKE_EN_CTL 0x0e 138 + #define RT721_GE_SDCA_RST_CTRL 0x10 139 + #define RT721_INT_RST_EN_CTRL 0x11 140 + #define RT721_XU_EVENT_EN 0x13 141 + #define RT721_INLINE_CTL2 0x17 142 + #define RT721_UMP_HID_CTRL1 0x18 143 + #define RT721_UMP_HID_CTRL2 0x19 144 + #define RT721_UMP_HID_CTRL3 0x1a 145 + #define RT721_UMP_HID_CTRL4 0x1b 146 + #define RT721_UMP_HID_CTRL5 0x1c 147 + #define RT721_FUNC_FLOAT_CTL0 0x22 148 + #define RT721_FUNC_FLOAT_CTL1 0x23 149 + #define RT721_FUNC_FLOAT_CTL2 0x24 150 + #define RT721_FUNC_FLOAT_CTL3 0x25 151 + #define RT721_ENT_FLOAT_CTL0 0x29 152 + #define RT721_ENT_FLOAT_CTL1 0x2c 153 + #define RT721_ENT_FLOAT_CTL2 0x2d 154 + #define RT721_ENT_FLOAT_CTL3 0x2e 155 + #define RT721_ENT_FLOAT_CTL4 0x2f 156 + #define RT721_CH_FLOAT_CTL1 0x45 157 + #define RT721_CH_FLOAT_CTL2 0x46 158 + #define RT721_ENT_FLOAT_CTL5 0x53 159 + #define RT721_ENT_FLOAT_CTL6 0x54 160 + #define RT721_ENT_FLOAT_CTL7 0x55 161 + #define RT721_ENT_FLOAT_CTL8 0x57 162 + #define RT721_ENT_FLOAT_CTL9 0x5a 163 + #define RT721_ENT_FLOAT_CTL10 0x5b 164 + #define RT721_CH_FLOAT_CTL3 0x6a 165 + #define RT721_CH_FLOAT_CTL4 0x6d 166 + #define RT721_CH_FLOAT_CTL5 0x70 167 + #define RT721_CH_FLOAT_CTL6 0x92 168 + 169 + /* Parameter & Verb control 01 (0x26)(NID:20h) */ 170 + #define RT721_HIDDEN_REG_SW_RESET (0x1 << 14) 171 + 172 + /* Buffer address for HID */ 173 + #define RT721_BUF_ADDR_HID1 0x44030000 174 + #define RT721_BUF_ADDR_HID2 0x44030020 175 + 176 + /* RT721 SDCA Control - function number */ 177 + #define FUNC_NUM_JACK_CODEC 0x01 178 + #define FUNC_NUM_MIC_ARRAY 0x02 179 + #define FUNC_NUM_HID 0x03 180 + #define FUNC_NUM_AMP 0x04 181 + 182 + /* RT721 SDCA entity */ 183 + #define RT721_SDCA_ENT_HID01 0x01 184 + #define RT721_SDCA_ENT_XUV 0x03 185 + #define RT721_SDCA_ENT_GE49 0x49 186 + #define RT721_SDCA_ENT_USER_FU05 0x05 187 + #define RT721_SDCA_ENT_USER_FU06 0x06 188 + #define RT721_SDCA_ENT_USER_FU0F 0x0f 189 + #define RT721_SDCA_ENT_USER_FU10 0x19 190 + #define RT721_SDCA_ENT_USER_FU1E 0x1e 191 + #define RT721_SDCA_ENT_FU15 0x15 192 + #define RT721_SDCA_ENT_PDE23 0x23 193 + #define RT721_SDCA_ENT_PDE40 0x40 194 + #define RT721_SDCA_ENT_PDE41 0x41 195 + #define RT721_SDCA_ENT_PDE11 0x11 196 + #define RT721_SDCA_ENT_PDE12 0x12 197 + #define RT721_SDCA_ENT_PDE2A 0x2a 198 + #define RT721_SDCA_ENT_CS01 0x01 199 + #define RT721_SDCA_ENT_CS11 0x11 200 + #define RT721_SDCA_ENT_CS1F 0x1f 201 + #define RT721_SDCA_ENT_CS1C 0x1c 202 + #define RT721_SDCA_ENT_CS31 0x31 203 + #define RT721_SDCA_ENT_OT23 0x42 204 + #define RT721_SDCA_ENT_IT26 0x26 205 + #define RT721_SDCA_ENT_IT09 0x09 206 + #define RT721_SDCA_ENT_PLATFORM_FU15 0x15 207 + #define RT721_SDCA_ENT_PLATFORM_FU44 0x44 208 + #define RT721_SDCA_ENT_XU03 0x03 209 + #define RT721_SDCA_ENT_XU0D 0x0d 210 + #define RT721_SDCA_ENT_FU55 0x55 211 + 212 + /* RT721 SDCA control */ 213 + #define RT721_SDCA_CTL_SAMPLE_FREQ_INDEX 0x10 214 + #define RT721_SDCA_CTL_FU_MUTE 0x01 215 + #define RT721_SDCA_CTL_FU_VOLUME 0x02 216 + #define RT721_SDCA_CTL_HIDTX_CURRENT_OWNER 0x10 217 + #define RT721_SDCA_CTL_HIDTX_SET_OWNER_TO_DEVICE 0x11 218 + #define RT721_SDCA_CTL_HIDTX_MESSAGE_OFFSET 0x12 219 + #define RT721_SDCA_CTL_HIDTX_MESSAGE_LENGTH 0x13 220 + #define RT721_SDCA_CTL_SELECTED_MODE 0x01 221 + #define RT721_SDCA_CTL_DETECTED_MODE 0x02 222 + #define RT721_SDCA_CTL_REQ_POWER_STATE 0x01 223 + #define RT721_SDCA_CTL_VENDOR_DEF 0x30 224 + #define RT721_SDCA_CTL_XUV 0x34 225 + #define RT721_SDCA_CTL_FU_CH_GAIN 0x0b 226 + 227 + /* RT721 SDCA channel */ 228 + #define CH_L 0x01 229 + #define CH_R 0x02 230 + #define CH_01 0x01 231 + #define CH_02 0x02 232 + #define CH_03 0x03 233 + #define CH_04 0x04 234 + #define CH_08 0x08 235 + #define CH_09 0x09 236 + #define CH_0A 0x0a 237 + 238 + /* sample frequency index */ 239 + #define RT721_SDCA_RATE_8000HZ 0x01 240 + #define RT721_SDCA_RATE_11025HZ 0x02 241 + #define RT721_SDCA_RATE_12000HZ 0x03 242 + #define RT721_SDCA_RATE_16000HZ 0x04 243 + #define RT721_SDCA_RATE_22050HZ 0x05 244 + #define RT721_SDCA_RATE_24000HZ 0x06 245 + #define RT721_SDCA_RATE_32000HZ 0x07 246 + #define RT721_SDCA_RATE_44100HZ 0x08 247 + #define RT721_SDCA_RATE_48000HZ 0x09 248 + #define RT721_SDCA_RATE_88200HZ 0x0a 249 + #define RT721_SDCA_RATE_96000HZ 0x0b 250 + #define RT721_SDCA_RATE_176400HZ 0x0c 251 + #define RT721_SDCA_RATE_192000HZ 0x0d 252 + #define RT721_SDCA_RATE_384000HZ 0x0e 253 + #define RT721_SDCA_RATE_768000HZ 0x0f 254 + 255 + /* RT721 HID ID */ 256 + #define RT721_SDCA_HID_ID 0x11 257 + 258 + enum { 259 + RT721_AIF1, /* For headset mic and headphone */ 260 + RT721_AIF2, /* For speaker */ 261 + RT721_AIF3, /* For dmic */ 262 + RT721_AIFS, 263 + }; 264 + 265 + int rt721_sdca_io_init(struct device *dev, struct sdw_slave *slave); 266 + int rt721_sdca_init(struct device *dev, struct regmap *regmap, 267 + struct regmap *mbq_regmap, struct sdw_slave *slave); 268 + #endif /* __RT721_H__ */