1875 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2//3// rt712-sdca.c -- rt712 SDCA ALSA SoC audio driver4//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 27static 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 "%s: Failed to set private value: %06x <= %04x ret=%d\n",38 __func__, addr, value, ret);39 40 return ret;41}42 43static 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 "%s: Failed to get private value: %06x => %04x ret=%d\n",54 __func__, addr, *value, ret);55 56 return ret;57}58 59static 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 73static 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 if (rt712->version_id == RT712_VA)86 rt712_sdca_index_write(rt712, RT712_VENDOR_REG, RT712_CC_DET1, 0x043a);87 88 /* FSM switch to calibration manual mode */89 rt712_sdca_index_write(rt712, RT712_VENDOR_REG, RT712_FSM_CTL, 0x4100);90 91 /* Calibration setting */92 rt712_sdca_index_write(rt712, RT712_VENDOR_CALI, RT712_DAC_DC_CALI_CTL1, 0x7883);93 94 /* W1C Trigger DC calibration (HP & Class-D) */95 rt712_sdca_index_write(rt712, RT712_VENDOR_CALI, RT712_DAC_DC_CALI_CTL1, 0xf893);96 97 /* wait for calibration process */98 rt712_sdca_index_read(rt712, RT712_VENDOR_CALI,99 RT712_DAC_DC_CALI_CTL1, &val);100 101 for (loop_dc = 0; loop_dc < chk_cnt &&102 (val & RT712_DAC_DC_CALI_TRIGGER); loop_dc++) {103 usleep_range(10000, 11000);104 ret = rt712_sdca_index_read(rt712, RT712_VENDOR_CALI,105 RT712_DAC_DC_CALI_CTL1, &val);106 if (ret < 0)107 goto _cali_fail_;108 }109 if (loop_dc == chk_cnt)110 dev_err(dev, "%s, calibration time-out!\n", __func__);111 112 if (loop_dc == chk_cnt || loop_rc == chk_cnt)113 ret = -ETIMEDOUT;114 115_cali_fail_:116 /* Enable Rldet in FSM */117 rt712_sdca_index_write(rt712, RT712_VENDOR_REG, RT712_FSM_CTL, 0x4500);118 119 /* Sensing Lch+Rch */120 rt712_sdca_index_write(rt712, RT712_VENDOR_IMS_DRE, RT712_IMS_DIGITAL_CTL1, 0x040f);121 122 /* Sine gen path control */123 rt712_sdca_index_write(rt712, RT712_VENDOR_IMS_DRE, RT712_IMS_DIGITAL_CTL5, 0x0000);124 125 /* Release HP-JD, EN_CBJ_TIE_GL/R open, en_osw gating auto done bit */126 rt712_sdca_index_write(rt712, RT712_VENDOR_REG, RT712_DIGITAL_MISC_CTRL4, 0x0010);127 128 mutex_unlock(&rt712->calibrate_mutex);129 dev_dbg(dev, "%s calibration complete, ret=%d\n", __func__, ret);130 return ret;131}132 133static unsigned int rt712_sdca_button_detect(struct rt712_sdca_priv *rt712)134{135 unsigned int btn_type = 0, offset, idx, val, owner;136 int ret;137 unsigned char buf[3];138 139 /* get current UMP message owner */140 ret = regmap_read(rt712->regmap,141 SDW_SDCA_CTL(FUNC_NUM_HID, RT712_SDCA_ENT_HID01, RT712_SDCA_CTL_HIDTX_CURRENT_OWNER, 0),142 &owner);143 if (ret < 0)144 return 0;145 146 /* if owner is device then there is no button event from device */147 if (owner == 1)148 return 0;149 150 /* read UMP message offset */151 ret = regmap_read(rt712->regmap,152 SDW_SDCA_CTL(FUNC_NUM_HID, RT712_SDCA_ENT_HID01, RT712_SDCA_CTL_HIDTX_MESSAGE_OFFSET, 0),153 &offset);154 if (ret < 0)155 goto _end_btn_det_;156 157 for (idx = 0; idx < sizeof(buf); idx++) {158 ret = regmap_read(rt712->regmap,159 RT712_BUF_ADDR_HID1 + offset + idx, &val);160 if (ret < 0)161 goto _end_btn_det_;162 buf[idx] = val & 0xff;163 }164 165 if (buf[0] == 0x11) {166 switch (buf[1] & 0xf0) {167 case 0x10:168 btn_type |= SND_JACK_BTN_2;169 break;170 case 0x20:171 btn_type |= SND_JACK_BTN_3;172 break;173 case 0x40:174 btn_type |= SND_JACK_BTN_0;175 break;176 case 0x80:177 btn_type |= SND_JACK_BTN_1;178 break;179 }180 switch (buf[2]) {181 case 0x01:182 case 0x10:183 btn_type |= SND_JACK_BTN_2;184 break;185 case 0x02:186 case 0x20:187 btn_type |= SND_JACK_BTN_3;188 break;189 case 0x04:190 case 0x40:191 btn_type |= SND_JACK_BTN_0;192 break;193 case 0x08:194 case 0x80:195 btn_type |= SND_JACK_BTN_1;196 break;197 }198 }199 200_end_btn_det_:201 /* Host is owner, so set back to device */202 if (owner == 0) {203 /* set owner to device */204 if (rt712->version_id == RT712_VA)205 regmap_write(rt712->regmap,206 SDW_SDCA_CTL(FUNC_NUM_HID, RT712_SDCA_ENT_HID01,207 RT712_SDCA_CTL_HIDTX_SET_OWNER_TO_DEVICE, 0), 0x01);208 else209 regmap_write(rt712->regmap,210 SDW_SDCA_CTL(FUNC_NUM_HID, RT712_SDCA_ENT_HID01,211 RT712_SDCA_CTL_HIDTX_CURRENT_OWNER, 0), 0x01);212 }213 214 return btn_type;215}216 217static int rt712_sdca_headset_detect(struct rt712_sdca_priv *rt712)218{219 unsigned int det_mode;220 int ret;221 222 /* get detected_mode */223 ret = regmap_read(rt712->regmap,224 SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT712_SDCA_ENT_GE49, RT712_SDCA_CTL_DETECTED_MODE, 0),225 &det_mode);226 if (ret < 0)227 goto io_error;228 229 switch (det_mode) {230 case 0x00:231 rt712->jack_type = 0;232 break;233 case 0x03:234 rt712->jack_type = SND_JACK_HEADPHONE;235 break;236 case 0x05:237 rt712->jack_type = SND_JACK_HEADSET;238 break;239 }240 241 /* write selected_mode */242 if (det_mode) {243 ret = regmap_write(rt712->regmap,244 SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT712_SDCA_ENT_GE49, RT712_SDCA_CTL_SELECTED_MODE, 0),245 det_mode);246 if (ret < 0)247 goto io_error;248 }249 250 dev_dbg(&rt712->slave->dev,251 "%s, detected_mode=0x%x\n", __func__, det_mode);252 253 return 0;254 255io_error:256 pr_err_ratelimited("IO error in %s, ret %d\n", __func__, ret);257 return ret;258}259 260static void rt712_sdca_jack_detect_handler(struct work_struct *work)261{262 struct rt712_sdca_priv *rt712 =263 container_of(work, struct rt712_sdca_priv, jack_detect_work.work);264 int btn_type = 0, ret;265 266 if (!rt712->hs_jack)267 return;268 269 if (!rt712->component->card || !rt712->component->card->instantiated)270 return;271 272 /* SDW_SCP_SDCA_INT_SDCA_0 is used for jack detection */273 if (rt712->scp_sdca_stat1 & SDW_SCP_SDCA_INT_SDCA_0) {274 ret = rt712_sdca_headset_detect(rt712);275 if (ret < 0)276 return;277 }278 279 /* SDW_SCP_SDCA_INT_SDCA_8 is used for button detection */280 if (rt712->scp_sdca_stat2 & SDW_SCP_SDCA_INT_SDCA_8)281 btn_type = rt712_sdca_button_detect(rt712);282 283 if (rt712->jack_type == 0)284 btn_type = 0;285 286 dev_dbg(&rt712->slave->dev,287 "in %s, jack_type=0x%x\n", __func__, rt712->jack_type);288 dev_dbg(&rt712->slave->dev,289 "in %s, btn_type=0x%x\n", __func__, btn_type);290 dev_dbg(&rt712->slave->dev,291 "in %s, scp_sdca_stat1=0x%x, scp_sdca_stat2=0x%x\n", __func__,292 rt712->scp_sdca_stat1, rt712->scp_sdca_stat2);293 294 snd_soc_jack_report(rt712->hs_jack, rt712->jack_type | btn_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 if (btn_type) {300 /* button released */301 snd_soc_jack_report(rt712->hs_jack, rt712->jack_type,302 SND_JACK_HEADSET |303 SND_JACK_BTN_0 | SND_JACK_BTN_1 |304 SND_JACK_BTN_2 | SND_JACK_BTN_3);305 306 mod_delayed_work(system_power_efficient_wq,307 &rt712->jack_btn_check_work, msecs_to_jiffies(200));308 }309}310 311static void rt712_sdca_btn_check_handler(struct work_struct *work)312{313 struct rt712_sdca_priv *rt712 =314 container_of(work, struct rt712_sdca_priv, jack_btn_check_work.work);315 int btn_type = 0, ret, idx;316 unsigned int det_mode, offset, val;317 unsigned char buf[3];318 319 ret = regmap_read(rt712->regmap,320 SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT712_SDCA_ENT_GE49, RT712_SDCA_CTL_DETECTED_MODE, 0),321 &det_mode);322 if (ret < 0)323 goto io_error;324 325 /* pin attached */326 if (det_mode) {327 /* read UMP message offset */328 ret = regmap_read(rt712->regmap,329 SDW_SDCA_CTL(FUNC_NUM_HID, RT712_SDCA_ENT_HID01, RT712_SDCA_CTL_HIDTX_MESSAGE_OFFSET, 0),330 &offset);331 if (ret < 0)332 goto io_error;333 334 for (idx = 0; idx < sizeof(buf); idx++) {335 ret = regmap_read(rt712->regmap,336 RT712_BUF_ADDR_HID1 + offset + idx, &val);337 if (ret < 0)338 goto io_error;339 buf[idx] = val & 0xff;340 }341 342 if (buf[0] == 0x11) {343 switch (buf[1] & 0xf0) {344 case 0x10:345 btn_type |= SND_JACK_BTN_2;346 break;347 case 0x20:348 btn_type |= SND_JACK_BTN_3;349 break;350 case 0x40:351 btn_type |= SND_JACK_BTN_0;352 break;353 case 0x80:354 btn_type |= SND_JACK_BTN_1;355 break;356 }357 switch (buf[2]) {358 case 0x01:359 case 0x10:360 btn_type |= SND_JACK_BTN_2;361 break;362 case 0x02:363 case 0x20:364 btn_type |= SND_JACK_BTN_3;365 break;366 case 0x04:367 case 0x40:368 btn_type |= SND_JACK_BTN_0;369 break;370 case 0x08:371 case 0x80:372 btn_type |= SND_JACK_BTN_1;373 break;374 }375 }376 } else {377 rt712->jack_type = 0;378 }379 380 dev_dbg(&rt712->slave->dev, "%s, btn_type=0x%x\n", __func__, btn_type);381 snd_soc_jack_report(rt712->hs_jack, rt712->jack_type | btn_type,382 SND_JACK_HEADSET |383 SND_JACK_BTN_0 | SND_JACK_BTN_1 |384 SND_JACK_BTN_2 | SND_JACK_BTN_3);385 386 if (btn_type) {387 /* button released */388 snd_soc_jack_report(rt712->hs_jack, rt712->jack_type,389 SND_JACK_HEADSET |390 SND_JACK_BTN_0 | SND_JACK_BTN_1 |391 SND_JACK_BTN_2 | SND_JACK_BTN_3);392 393 mod_delayed_work(system_power_efficient_wq,394 &rt712->jack_btn_check_work, msecs_to_jiffies(200));395 }396 397 return;398 399io_error:400 pr_err_ratelimited("IO error in %s, ret %d\n", __func__, ret);401}402 403static void rt712_sdca_jack_init(struct rt712_sdca_priv *rt712)404{405 mutex_lock(&rt712->calibrate_mutex);406 407 if (rt712->hs_jack) {408 /* Enable HID1 event & set button RTC mode */409 rt712_sdca_index_write(rt712, RT712_VENDOR_HDA_CTL,410 RT712_UMP_HID_CTL5, 0xfff0);411 rt712_sdca_index_update_bits(rt712, RT712_VENDOR_HDA_CTL,412 RT712_UMP_HID_CTL0, 0x1100, 0x1100);413 rt712_sdca_index_update_bits(rt712, RT712_VENDOR_HDA_CTL,414 RT712_UMP_HID_CTL7, 0xf000, 0x0000);415 416 /* detected_mode_change_event_en & hid1_push_button_event_en */417 rt712_sdca_index_update_bits(rt712, RT712_VENDOR_HDA_CTL,418 RT712_GE_RELATED_CTL1, 0x0c00, 0x0c00);419 /* ge_inbox_en */420 rt712_sdca_index_update_bits(rt712, RT712_VENDOR_HDA_CTL,421 RT712_GE_RELATED_CTL2, 0x0020, 0x0000);422 423 switch (rt712->jd_src) {424 case RT712_JD1:425 /* Set HP-JD source from JD1, VB uses JD1 in default */426 if (rt712->version_id == RT712_VA)427 rt712_sdca_index_write(rt712, RT712_VENDOR_REG, RT712_CC_DET1, 0x043a);428 break;429 default:430 dev_warn(rt712->component->dev, "Wrong JD source\n");431 break;432 }433 434 /* set SCP_SDCA_IntMask1[0]=1 */435 sdw_write_no_pm(rt712->slave, SDW_SCP_SDCA_INTMASK1, SDW_SCP_SDCA_INTMASK_SDCA_0);436 /* set SCP_SDCA_IntMask2[0]=1 */437 sdw_write_no_pm(rt712->slave, SDW_SCP_SDCA_INTMASK2, SDW_SCP_SDCA_INTMASK_SDCA_8);438 dev_dbg(&rt712->slave->dev, "in %s enable\n", __func__);439 440 /* trigger GE interrupt */441 rt712_sdca_index_update_bits(rt712, RT712_VENDOR_HDA_CTL,442 RT712_GE_RELATED_CTL1, 0x0080, 0x0080);443 rt712_sdca_index_update_bits(rt712, RT712_VENDOR_HDA_CTL,444 RT712_GE_RELATED_CTL1, 0x0080, 0x0000);445 } else {446 /* disable HID1 & detected_mode_change event */447 rt712_sdca_index_update_bits(rt712, RT712_VENDOR_HDA_CTL,448 RT712_GE_RELATED_CTL1, 0x0c00, 0x0000);449 450 dev_dbg(&rt712->slave->dev, "in %s disable\n", __func__);451 }452 453 mutex_unlock(&rt712->calibrate_mutex);454}455 456static int rt712_sdca_set_jack_detect(struct snd_soc_component *component,457 struct snd_soc_jack *hs_jack, void *data)458{459 struct rt712_sdca_priv *rt712 = snd_soc_component_get_drvdata(component);460 int ret;461 462 rt712->hs_jack = hs_jack;463 464 if (!rt712->first_hw_init)465 return 0;466 467 ret = pm_runtime_resume_and_get(component->dev);468 if (ret < 0) {469 if (ret != -EACCES) {470 dev_err(component->dev, "%s: failed to resume %d\n", __func__, ret);471 return ret;472 }473 474 /* pm_runtime not enabled yet */475 dev_dbg(component->dev, "%s: skipping jack init for now\n", __func__);476 return 0;477 }478 479 rt712_sdca_jack_init(rt712);480 481 pm_runtime_mark_last_busy(component->dev);482 pm_runtime_put_autosuspend(component->dev);483 484 return 0;485}486 487/* For SDCA control DAC/ADC Gain */488static int rt712_sdca_set_gain_put(struct snd_kcontrol *kcontrol,489 struct snd_ctl_elem_value *ucontrol)490{491 struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);492 struct soc_mixer_control *mc =493 (struct soc_mixer_control *)kcontrol->private_value;494 struct rt712_sdca_priv *rt712 = snd_soc_component_get_drvdata(component);495 unsigned int read_l, read_r, gain_l_val, gain_r_val;496 unsigned int adc_vol_flag = 0;497 unsigned int lvalue, rvalue;498 const unsigned int interval_offset = 0xc0;499 const unsigned int tendB = 0xa00;500 501 if (strstr(ucontrol->id.name, "FU0F Capture Volume"))502 adc_vol_flag = 1;503 504 regmap_read(rt712->mbq_regmap, mc->reg, &lvalue);505 regmap_read(rt712->mbq_regmap, mc->rreg, &rvalue);506 507 /* L Channel */508 gain_l_val = ucontrol->value.integer.value[0];509 if (gain_l_val > mc->max)510 gain_l_val = mc->max;511 512 if (mc->shift == 8) /* boost gain */513 gain_l_val = gain_l_val * tendB;514 else {515 /* ADC/DAC gain */516 if (adc_vol_flag)517 gain_l_val = 0x1e00 - ((mc->max - gain_l_val) * interval_offset);518 else519 gain_l_val = 0 - ((mc->max - gain_l_val) * interval_offset);520 gain_l_val &= 0xffff;521 }522 523 /* R Channel */524 gain_r_val = ucontrol->value.integer.value[1];525 if (gain_r_val > mc->max)526 gain_r_val = mc->max;527 528 if (mc->shift == 8) /* boost gain */529 gain_r_val = gain_r_val * tendB;530 else {531 /* ADC/DAC gain */532 if (adc_vol_flag)533 gain_r_val = 0x1e00 - ((mc->max - gain_r_val) * interval_offset);534 else535 gain_r_val = 0 - ((mc->max - gain_r_val) * interval_offset);536 gain_r_val &= 0xffff;537 }538 539 if (lvalue == gain_l_val && rvalue == gain_r_val)540 return 0;541 542 /* Lch*/543 regmap_write(rt712->mbq_regmap, mc->reg, gain_l_val);544 /* Rch */545 regmap_write(rt712->mbq_regmap, mc->rreg, gain_r_val);546 547 regmap_read(rt712->mbq_regmap, mc->reg, &read_l);548 regmap_read(rt712->mbq_regmap, mc->rreg, &read_r);549 if (read_r == gain_r_val && read_l == gain_l_val)550 return 1;551 552 return -EIO;553}554 555static int rt712_sdca_set_gain_get(struct snd_kcontrol *kcontrol,556 struct snd_ctl_elem_value *ucontrol)557{558 struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);559 struct rt712_sdca_priv *rt712 = snd_soc_component_get_drvdata(component);560 struct soc_mixer_control *mc =561 (struct soc_mixer_control *)kcontrol->private_value;562 unsigned int read_l, read_r, ctl_l = 0, ctl_r = 0;563 unsigned int adc_vol_flag = 0;564 const unsigned int interval_offset = 0xc0;565 const unsigned int tendB = 0xa00;566 567 if (strstr(ucontrol->id.name, "FU0F Capture Volume"))568 adc_vol_flag = 1;569 570 regmap_read(rt712->mbq_regmap, mc->reg, &read_l);571 regmap_read(rt712->mbq_regmap, mc->rreg, &read_r);572 573 if (mc->shift == 8) /* boost gain */574 ctl_l = read_l / tendB;575 else {576 if (adc_vol_flag)577 ctl_l = mc->max - (((0x1e00 - read_l) & 0xffff) / interval_offset);578 else579 ctl_l = mc->max - (((0 - read_l) & 0xffff) / interval_offset);580 }581 582 if (read_l != read_r) {583 if (mc->shift == 8) /* boost gain */584 ctl_r = read_r / tendB;585 else { /* ADC/DAC gain */586 if (adc_vol_flag)587 ctl_r = mc->max - (((0x1e00 - read_r) & 0xffff) / interval_offset);588 else589 ctl_r = mc->max - (((0 - read_r) & 0xffff) / interval_offset);590 }591 } else592 ctl_r = ctl_l;593 594 ucontrol->value.integer.value[0] = ctl_l;595 ucontrol->value.integer.value[1] = ctl_r;596 597 return 0;598}599 600static int rt712_sdca_set_fu0f_capture_ctl(struct rt712_sdca_priv *rt712)601{602 int err;603 unsigned int ch_01, ch_02;604 605 ch_01 = (rt712->fu0f_dapm_mute || rt712->fu0f_mixer_l_mute) ? 0x01 : 0x00;606 ch_02 = (rt712->fu0f_dapm_mute || rt712->fu0f_mixer_r_mute) ? 0x01 : 0x00;607 608 err = regmap_write(rt712->regmap,609 SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT712_SDCA_ENT_USER_FU0F,610 RT712_SDCA_CTL_FU_MUTE, CH_01), ch_01);611 if (err < 0)612 return err;613 614 err = regmap_write(rt712->regmap,615 SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT712_SDCA_ENT_USER_FU0F,616 RT712_SDCA_CTL_FU_MUTE, CH_02), ch_02);617 if (err < 0)618 return err;619 620 return 0;621}622 623static int rt712_sdca_fu0f_capture_get(struct snd_kcontrol *kcontrol,624 struct snd_ctl_elem_value *ucontrol)625{626 struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);627 struct rt712_sdca_priv *rt712 = snd_soc_component_get_drvdata(component);628 629 ucontrol->value.integer.value[0] = !rt712->fu0f_mixer_l_mute;630 ucontrol->value.integer.value[1] = !rt712->fu0f_mixer_r_mute;631 return 0;632}633 634static int rt712_sdca_fu0f_capture_put(struct snd_kcontrol *kcontrol,635 struct snd_ctl_elem_value *ucontrol)636{637 struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);638 struct rt712_sdca_priv *rt712 = snd_soc_component_get_drvdata(component);639 int err;640 641 if (rt712->fu0f_mixer_l_mute == !ucontrol->value.integer.value[0] &&642 rt712->fu0f_mixer_r_mute == !ucontrol->value.integer.value[1])643 return 0;644 645 rt712->fu0f_mixer_l_mute = !ucontrol->value.integer.value[0];646 rt712->fu0f_mixer_r_mute = !ucontrol->value.integer.value[1];647 err = rt712_sdca_set_fu0f_capture_ctl(rt712);648 if (err < 0)649 return err;650 651 return 1;652}653 654static const DECLARE_TLV_DB_SCALE(out_vol_tlv, -6525, 75, 0);655static const DECLARE_TLV_DB_SCALE(mic_vol_tlv, -1725, 75, 0);656static const DECLARE_TLV_DB_SCALE(boost_vol_tlv, 0, 1000, 0);657 658static const struct snd_kcontrol_new rt712_sdca_controls[] = {659 SOC_DOUBLE_R_EXT_TLV("FU05 Playback Volume",660 SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT712_SDCA_ENT_USER_FU05, RT712_SDCA_CTL_FU_VOLUME, CH_01),661 SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT712_SDCA_ENT_USER_FU05, RT712_SDCA_CTL_FU_VOLUME, CH_02),662 0, 0x57, 0,663 rt712_sdca_set_gain_get, rt712_sdca_set_gain_put, out_vol_tlv),664 SOC_DOUBLE_EXT("FU0F Capture Switch", SND_SOC_NOPM, 0, 1, 1, 0,665 rt712_sdca_fu0f_capture_get, rt712_sdca_fu0f_capture_put),666 SOC_DOUBLE_R_EXT_TLV("FU0F Capture Volume",667 SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT712_SDCA_ENT_USER_FU0F, RT712_SDCA_CTL_FU_VOLUME, CH_01),668 SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT712_SDCA_ENT_USER_FU0F, RT712_SDCA_CTL_FU_VOLUME, CH_02),669 0, 0x3f, 0,670 rt712_sdca_set_gain_get, rt712_sdca_set_gain_put, mic_vol_tlv),671 SOC_DOUBLE_R_EXT_TLV("FU44 Boost Volume",672 SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT712_SDCA_ENT_PLATFORM_FU44, RT712_SDCA_CTL_FU_CH_GAIN, CH_01),673 SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT712_SDCA_ENT_PLATFORM_FU44, RT712_SDCA_CTL_FU_CH_GAIN, CH_02),674 8, 3, 0,675 rt712_sdca_set_gain_get, rt712_sdca_set_gain_put, boost_vol_tlv),676};677 678static const struct snd_kcontrol_new rt712_sdca_spk_controls[] = {679 SOC_DOUBLE_R_EXT_TLV("FU06 Playback Volume",680 SDW_SDCA_CTL(FUNC_NUM_AMP, RT712_SDCA_ENT_USER_FU06, RT712_SDCA_CTL_FU_VOLUME, CH_01),681 SDW_SDCA_CTL(FUNC_NUM_AMP, RT712_SDCA_ENT_USER_FU06, RT712_SDCA_CTL_FU_VOLUME, CH_02),682 0, 0x57, 0,683 rt712_sdca_set_gain_get, rt712_sdca_set_gain_put, out_vol_tlv),684};685 686static int rt712_sdca_mux_get(struct snd_kcontrol *kcontrol,687 struct snd_ctl_elem_value *ucontrol)688{689 struct snd_soc_component *component =690 snd_soc_dapm_kcontrol_component(kcontrol);691 struct rt712_sdca_priv *rt712 = snd_soc_component_get_drvdata(component);692 unsigned int val = 0, mask = 0x3300;693 694 rt712_sdca_index_read(rt712, RT712_VENDOR_HDA_CTL, RT712_MIXER_CTL1, &val);695 696 val = val & mask;697 switch (val) {698 case 0x3000:699 val = 1;700 break;701 case 0x0300:702 val = 0;703 break;704 }705 706 ucontrol->value.enumerated.item[0] = val;707 708 return 0;709}710 711static int rt712_sdca_mux_put(struct snd_kcontrol *kcontrol,712 struct snd_ctl_elem_value *ucontrol)713{714 struct snd_soc_component *component =715 snd_soc_dapm_kcontrol_component(kcontrol);716 struct snd_soc_dapm_context *dapm =717 snd_soc_dapm_kcontrol_dapm(kcontrol);718 struct rt712_sdca_priv *rt712 = snd_soc_component_get_drvdata(component);719 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;720 unsigned int *item = ucontrol->value.enumerated.item;721 unsigned int mask_sft;722 unsigned int val;723 724 if (item[0] >= e->items)725 return -EINVAL;726 727 if (ucontrol->value.enumerated.item[0] == 0)728 mask_sft = 12;729 else if (ucontrol->value.enumerated.item[0] == 1)730 mask_sft = 8;731 else732 return -EINVAL;733 734 rt712_sdca_index_read(rt712, RT712_VENDOR_HDA_CTL, RT712_MIXER_CTL1, &val);735 val = (val >> mask_sft) & 0x3;736 if (!val)737 return 0;738 739 rt712_sdca_index_write(rt712, RT712_VENDOR_HDA_CTL,740 RT712_MIXER_CTL1, 0x3fff);741 rt712_sdca_index_update_bits(rt712, RT712_VENDOR_HDA_CTL,742 RT712_MIXER_CTL1, 0x3 << mask_sft, 0);743 744 snd_soc_dapm_mux_update_power(dapm, kcontrol,745 item[0], e, NULL);746 747 return 1;748}749 750static const char * const adc_mux_text[] = {751 "MIC2",752 "LINE2",753};754 755static SOC_ENUM_SINGLE_DECL(756 rt712_adc23_enum, SND_SOC_NOPM, 0, adc_mux_text);757 758static const struct snd_kcontrol_new rt712_sdca_adc23_mux =759 SOC_DAPM_ENUM_EXT("ADC 23 Mux", rt712_adc23_enum,760 rt712_sdca_mux_get, rt712_sdca_mux_put);761 762static int rt712_sdca_fu05_event(struct snd_soc_dapm_widget *w,763 struct snd_kcontrol *kcontrol, int event)764{765 struct snd_soc_component *component =766 snd_soc_dapm_to_component(w->dapm);767 struct rt712_sdca_priv *rt712 = snd_soc_component_get_drvdata(component);768 unsigned char unmute = 0x0, mute = 0x1;769 770 switch (event) {771 case SND_SOC_DAPM_POST_PMU:772 regmap_write(rt712->regmap,773 SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT712_SDCA_ENT_USER_FU05,774 RT712_SDCA_CTL_FU_MUTE, CH_01),775 unmute);776 regmap_write(rt712->regmap,777 SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT712_SDCA_ENT_USER_FU05,778 RT712_SDCA_CTL_FU_MUTE, CH_02),779 unmute);780 break;781 case SND_SOC_DAPM_PRE_PMD:782 regmap_write(rt712->regmap,783 SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT712_SDCA_ENT_USER_FU05,784 RT712_SDCA_CTL_FU_MUTE, CH_01),785 mute);786 regmap_write(rt712->regmap,787 SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT712_SDCA_ENT_USER_FU05,788 RT712_SDCA_CTL_FU_MUTE, CH_02),789 mute);790 break;791 }792 return 0;793}794 795static int rt712_sdca_fu0f_event(struct snd_soc_dapm_widget *w,796 struct snd_kcontrol *kcontrol, int event)797{798 struct snd_soc_component *component =799 snd_soc_dapm_to_component(w->dapm);800 struct rt712_sdca_priv *rt712 = snd_soc_component_get_drvdata(component);801 802 switch (event) {803 case SND_SOC_DAPM_POST_PMU:804 rt712->fu0f_dapm_mute = false;805 rt712_sdca_set_fu0f_capture_ctl(rt712);806 break;807 case SND_SOC_DAPM_PRE_PMD:808 rt712->fu0f_dapm_mute = true;809 rt712_sdca_set_fu0f_capture_ctl(rt712);810 break;811 }812 return 0;813}814 815static int rt712_sdca_pde40_event(struct snd_soc_dapm_widget *w,816 struct snd_kcontrol *kcontrol, int event)817{818 struct snd_soc_component *component =819 snd_soc_dapm_to_component(w->dapm);820 struct rt712_sdca_priv *rt712 = snd_soc_component_get_drvdata(component);821 unsigned char ps0 = 0x0, ps3 = 0x3;822 823 switch (event) {824 case SND_SOC_DAPM_POST_PMU:825 regmap_write(rt712->regmap,826 SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT712_SDCA_ENT_PDE40,827 RT712_SDCA_CTL_REQ_POWER_STATE, 0),828 ps0);829 break;830 case SND_SOC_DAPM_PRE_PMD:831 regmap_write(rt712->regmap,832 SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT712_SDCA_ENT_PDE40,833 RT712_SDCA_CTL_REQ_POWER_STATE, 0),834 ps3);835 break;836 }837 return 0;838}839 840static int rt712_sdca_pde12_event(struct snd_soc_dapm_widget *w,841 struct snd_kcontrol *kcontrol, int event)842{843 struct snd_soc_component *component =844 snd_soc_dapm_to_component(w->dapm);845 struct rt712_sdca_priv *rt712 = snd_soc_component_get_drvdata(component);846 unsigned char ps0 = 0x0, ps3 = 0x3;847 848 switch (event) {849 case SND_SOC_DAPM_POST_PMU:850 regmap_write(rt712->regmap,851 SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT712_SDCA_ENT_PDE12,852 RT712_SDCA_CTL_REQ_POWER_STATE, 0),853 ps0);854 break;855 case SND_SOC_DAPM_PRE_PMD:856 regmap_write(rt712->regmap,857 SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT712_SDCA_ENT_PDE12,858 RT712_SDCA_CTL_REQ_POWER_STATE, 0),859 ps3);860 break;861 }862 return 0;863}864 865static int rt712_sdca_pde23_event(struct snd_soc_dapm_widget *w,866 struct snd_kcontrol *kcontrol, int event)867{868 struct snd_soc_component *component =869 snd_soc_dapm_to_component(w->dapm);870 struct rt712_sdca_priv *rt712 = snd_soc_component_get_drvdata(component);871 unsigned char ps0 = 0x0, ps3 = 0x3;872 873 switch (event) {874 case SND_SOC_DAPM_POST_PMU:875 regmap_write(rt712->regmap,876 SDW_SDCA_CTL(FUNC_NUM_AMP, RT712_SDCA_ENT_PDE23,877 RT712_SDCA_CTL_REQ_POWER_STATE, 0),878 ps0);879 break;880 case SND_SOC_DAPM_PRE_PMD:881 regmap_write(rt712->regmap,882 SDW_SDCA_CTL(FUNC_NUM_AMP, RT712_SDCA_ENT_PDE23,883 RT712_SDCA_CTL_REQ_POWER_STATE, 0),884 ps3);885 break;886 887 default:888 break;889 }890 891 return 0;892}893 894static const struct snd_kcontrol_new rt712_spk_l_dac =895 SOC_DAPM_SINGLE_AUTODISABLE("Switch",896 SDW_SDCA_CTL(FUNC_NUM_AMP, RT712_SDCA_ENT_USER_FU06, RT712_SDCA_CTL_FU_MUTE, CH_01),897 0, 1, 1);898static const struct snd_kcontrol_new rt712_spk_r_dac =899 SOC_DAPM_SINGLE_AUTODISABLE("Switch",900 SDW_SDCA_CTL(FUNC_NUM_AMP, RT712_SDCA_ENT_USER_FU06, RT712_SDCA_CTL_FU_MUTE, CH_02),901 0, 1, 1);902 903static const struct snd_soc_dapm_widget rt712_sdca_dapm_widgets[] = {904 SND_SOC_DAPM_OUTPUT("HP"),905 SND_SOC_DAPM_INPUT("MIC2"),906 SND_SOC_DAPM_INPUT("LINE2"),907 908 SND_SOC_DAPM_SUPPLY("PDE 40", SND_SOC_NOPM, 0, 0,909 rt712_sdca_pde40_event,910 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),911 SND_SOC_DAPM_SUPPLY("PDE 12", SND_SOC_NOPM, 0, 0,912 rt712_sdca_pde12_event,913 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),914 915 SND_SOC_DAPM_DAC_E("FU 05", NULL, SND_SOC_NOPM, 0, 0,916 rt712_sdca_fu05_event,917 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),918 SND_SOC_DAPM_ADC_E("FU 0F", NULL, SND_SOC_NOPM, 0, 0,919 rt712_sdca_fu0f_event,920 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),921 SND_SOC_DAPM_MUX("ADC 23 Mux", SND_SOC_NOPM, 0, 0,922 &rt712_sdca_adc23_mux),923 924 SND_SOC_DAPM_AIF_IN("DP1RX", "DP1 Playback", 0, SND_SOC_NOPM, 0, 0),925 SND_SOC_DAPM_AIF_OUT("DP4TX", "DP4 Capture", 0, SND_SOC_NOPM, 0, 0),926};927 928static const struct snd_soc_dapm_route rt712_sdca_audio_map[] = {929 { "FU 05", NULL, "DP1RX" },930 { "DP4TX", NULL, "FU 0F" },931 932 { "FU 0F", NULL, "PDE 12" },933 { "FU 0F", NULL, "ADC 23 Mux" },934 { "ADC 23 Mux", "LINE2", "LINE2" },935 { "ADC 23 Mux", "MIC2", "MIC2" },936 937 { "HP", NULL, "PDE 40" },938 { "HP", NULL, "FU 05" },939};940 941static const struct snd_soc_dapm_widget rt712_sdca_spk_dapm_widgets[] = {942 SND_SOC_DAPM_AIF_IN("DP3RX", "DP3 Playback", 0, SND_SOC_NOPM, 0, 0),943 944 /* Digital Interface */945 SND_SOC_DAPM_PGA("FU06", SND_SOC_NOPM, 0, 0, NULL, 0),946 947 SND_SOC_DAPM_SUPPLY("PDE 23", SND_SOC_NOPM, 0, 0,948 rt712_sdca_pde23_event,949 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),950 951 /* Output */952 SND_SOC_DAPM_SWITCH("OT23 L", SND_SOC_NOPM, 0, 0, &rt712_spk_l_dac),953 SND_SOC_DAPM_SWITCH("OT23 R", SND_SOC_NOPM, 0, 0, &rt712_spk_r_dac),954 SND_SOC_DAPM_OUTPUT("SPOL"),955 SND_SOC_DAPM_OUTPUT("SPOR"),956};957 958static const struct snd_soc_dapm_route rt712_sdca_spk_dapm_routes[] = {959 { "FU06", NULL, "DP3RX" },960 { "FU06", NULL, "PDE 23" },961 { "OT23 L", "Switch", "FU06" },962 { "OT23 R", "Switch", "FU06" },963 { "SPOL", NULL, "OT23 L" },964 { "SPOR", NULL, "OT23 R" },965};966 967static int rt712_sdca_parse_dt(struct rt712_sdca_priv *rt712, struct device *dev)968{969 device_property_read_u32(dev, "realtek,jd-src", &rt712->jd_src);970 971 return 0;972}973 974static int rt712_sdca_probe(struct snd_soc_component *component)975{976 struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);977 struct rt712_sdca_priv *rt712 = snd_soc_component_get_drvdata(component);978 int ret;979 980 rt712_sdca_parse_dt(rt712, &rt712->slave->dev);981 rt712->component = component;982 983 /* add SPK route */984 if (rt712->hw_id != RT712_DEV_ID_713) {985 snd_soc_add_component_controls(component,986 rt712_sdca_spk_controls, ARRAY_SIZE(rt712_sdca_spk_controls));987 snd_soc_dapm_new_controls(dapm,988 rt712_sdca_spk_dapm_widgets, ARRAY_SIZE(rt712_sdca_spk_dapm_widgets));989 snd_soc_dapm_add_routes(dapm,990 rt712_sdca_spk_dapm_routes, ARRAY_SIZE(rt712_sdca_spk_dapm_routes));991 }992 993 if (!rt712->first_hw_init)994 return 0;995 996 ret = pm_runtime_resume(component->dev);997 if (ret < 0 && ret != -EACCES)998 return ret;999 1000 return 0;1001}1002 1003static int rt712_sdca_dmic_set_gain_get(struct snd_kcontrol *kcontrol,1004 struct snd_ctl_elem_value *ucontrol)1005{1006 struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);1007 struct rt712_sdca_priv *rt712 = snd_soc_component_get_drvdata(component);1008 struct rt712_dmic_kctrl_priv *p =1009 (struct rt712_dmic_kctrl_priv *)kcontrol->private_value;1010 unsigned int regvalue, ctl, i;1011 unsigned int adc_vol_flag = 0;1012 const unsigned int interval_offset = 0xc0;1013 1014 if (strstr(ucontrol->id.name, "FU1E Capture Volume"))1015 adc_vol_flag = 1;1016 1017 /* check all channels */1018 for (i = 0; i < p->count; i++) {1019 regmap_read(rt712->mbq_regmap, p->reg_base + i, ®value);1020 1021 if (!adc_vol_flag) /* boost gain */1022 ctl = regvalue / 0x0a00;1023 else { /* ADC gain */1024 if (adc_vol_flag)1025 ctl = p->max - (((0x1e00 - regvalue) & 0xffff) / interval_offset);1026 else1027 ctl = p->max - (((0 - regvalue) & 0xffff) / interval_offset);1028 }1029 1030 ucontrol->value.integer.value[i] = ctl;1031 }1032 1033 return 0;1034}1035 1036static int rt712_sdca_dmic_set_gain_put(struct snd_kcontrol *kcontrol,1037 struct snd_ctl_elem_value *ucontrol)1038{1039 struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);1040 struct rt712_dmic_kctrl_priv *p =1041 (struct rt712_dmic_kctrl_priv *)kcontrol->private_value;1042 struct rt712_sdca_priv *rt712 = snd_soc_component_get_drvdata(component);1043 unsigned int gain_val[4];1044 unsigned int i, adc_vol_flag = 0, changed = 0;1045 unsigned int regvalue[4];1046 const unsigned int interval_offset = 0xc0;1047 int err;1048 1049 if (strstr(ucontrol->id.name, "FU1E Capture Volume"))1050 adc_vol_flag = 1;1051 1052 /* check all channels */1053 for (i = 0; i < p->count; i++) {1054 regmap_read(rt712->mbq_regmap, p->reg_base + i, ®value[i]);1055 1056 gain_val[i] = ucontrol->value.integer.value[i];1057 if (gain_val[i] > p->max)1058 gain_val[i] = p->max;1059 1060 if (!adc_vol_flag) /* boost gain */1061 gain_val[i] = gain_val[i] * 0x0a00;1062 else { /* ADC gain */1063 gain_val[i] = 0x1e00 - ((p->max - gain_val[i]) * interval_offset);1064 gain_val[i] &= 0xffff;1065 }1066 1067 if (regvalue[i] != gain_val[i])1068 changed = 1;1069 }1070 1071 if (!changed)1072 return 0;1073 1074 for (i = 0; i < p->count; i++) {1075 err = regmap_write(rt712->mbq_regmap, p->reg_base + i, gain_val[i]);1076 if (err < 0)1077 dev_err(&rt712->slave->dev, "0x%08x can't be set\n", p->reg_base + i);1078 }1079 1080 return changed;1081}1082 1083static int rt712_sdca_set_fu1e_capture_ctl(struct rt712_sdca_priv *rt712)1084{1085 int err, i;1086 unsigned int ch_mute;1087 1088 for (i = 0; i < ARRAY_SIZE(rt712->fu1e_mixer_mute); i++) {1089 ch_mute = (rt712->fu1e_dapm_mute || rt712->fu1e_mixer_mute[i]) ? 0x01 : 0x00;1090 err = regmap_write(rt712->regmap,1091 SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT712_SDCA_ENT_USER_FU1E,1092 RT712_SDCA_CTL_FU_MUTE, CH_01) + i, ch_mute);1093 if (err < 0)1094 return err;1095 }1096 1097 return 0;1098}1099 1100static int rt712_sdca_dmic_fu1e_capture_get(struct snd_kcontrol *kcontrol,1101 struct snd_ctl_elem_value *ucontrol)1102{1103 struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);1104 struct rt712_sdca_priv *rt712 = snd_soc_component_get_drvdata(component);1105 struct rt712_dmic_kctrl_priv *p =1106 (struct rt712_dmic_kctrl_priv *)kcontrol->private_value;1107 unsigned int i;1108 1109 for (i = 0; i < p->count; i++)1110 ucontrol->value.integer.value[i] = !rt712->fu1e_mixer_mute[i];1111 1112 return 0;1113}1114 1115static int rt712_sdca_dmic_fu1e_capture_put(struct snd_kcontrol *kcontrol,1116 struct snd_ctl_elem_value *ucontrol)1117{1118 struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);1119 struct rt712_sdca_priv *rt712 = snd_soc_component_get_drvdata(component);1120 struct rt712_dmic_kctrl_priv *p =1121 (struct rt712_dmic_kctrl_priv *)kcontrol->private_value;1122 int err, changed = 0, i;1123 1124 for (i = 0; i < p->count; i++) {1125 if (rt712->fu1e_mixer_mute[i] != !ucontrol->value.integer.value[i])1126 changed = 1;1127 rt712->fu1e_mixer_mute[i] = !ucontrol->value.integer.value[i];1128 }1129 1130 err = rt712_sdca_set_fu1e_capture_ctl(rt712);1131 if (err < 0)1132 return err;1133 1134 return changed;1135}1136 1137static int rt712_sdca_fu_info(struct snd_kcontrol *kcontrol,1138 struct snd_ctl_elem_info *uinfo)1139{1140 struct rt712_dmic_kctrl_priv *p =1141 (struct rt712_dmic_kctrl_priv *)kcontrol->private_value;1142 1143 if (p->max == 1)1144 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;1145 else1146 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;1147 uinfo->count = p->count;1148 uinfo->value.integer.min = 0;1149 uinfo->value.integer.max = p->max;1150 return 0;1151}1152 1153#define RT712_SDCA_PR_VALUE(xreg_base, xcount, xmax, xinvert) \1154 ((unsigned long)&(struct rt712_dmic_kctrl_priv) \1155 {.reg_base = xreg_base, .count = xcount, .max = xmax, \1156 .invert = xinvert})1157 1158#define RT712_SDCA_FU_CTRL(xname, reg_base, xmax, xinvert, xcount) \1159{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \1160 .info = rt712_sdca_fu_info, \1161 .get = rt712_sdca_dmic_fu1e_capture_get, \1162 .put = rt712_sdca_dmic_fu1e_capture_put, \1163 .private_value = RT712_SDCA_PR_VALUE(reg_base, xcount, xmax, xinvert)}1164 1165#define RT712_SDCA_EXT_TLV(xname, reg_base, xhandler_get,\1166 xhandler_put, xcount, xmax, tlv_array) \1167{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \1168 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \1169 SNDRV_CTL_ELEM_ACCESS_READWRITE, \1170 .tlv.p = (tlv_array), \1171 .info = rt712_sdca_fu_info, \1172 .get = xhandler_get, .put = xhandler_put, \1173 .private_value = RT712_SDCA_PR_VALUE(reg_base, xcount, xmax, 0) }1174 1175static const DECLARE_TLV_DB_SCALE(in_vol_tlv, -1725, 75, 0);1176static const DECLARE_TLV_DB_SCALE(dmic_vol_tlv, 0, 1000, 0);1177 1178static const struct snd_kcontrol_new rt712_sdca_dmic_snd_controls[] = {1179 RT712_SDCA_FU_CTRL("FU1E Capture Switch",1180 SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT712_SDCA_ENT_USER_FU1E, RT712_SDCA_CTL_FU_MUTE, CH_01),1181 1, 1, 4),1182 RT712_SDCA_EXT_TLV("FU1E Capture Volume",1183 SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT712_SDCA_ENT_USER_FU1E, RT712_SDCA_CTL_FU_VOLUME, CH_01),1184 rt712_sdca_dmic_set_gain_get, rt712_sdca_dmic_set_gain_put, 4, 0x3f, in_vol_tlv),1185 RT712_SDCA_EXT_TLV("FU15 Boost Volume",1186 SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT712_SDCA_ENT_PLATFORM_FU15, RT712_SDCA_CTL_FU_CH_GAIN, CH_01),1187 rt712_sdca_dmic_set_gain_get, rt712_sdca_dmic_set_gain_put, 4, 3, dmic_vol_tlv),1188};1189 1190static int rt712_sdca_dmic_mux_get(struct snd_kcontrol *kcontrol,1191 struct snd_ctl_elem_value *ucontrol)1192{1193 struct snd_soc_component *component =1194 snd_soc_dapm_kcontrol_component(kcontrol);1195 struct rt712_sdca_priv *rt712 = snd_soc_component_get_drvdata(component);1196 unsigned int val = 0, mask_sft;1197 1198 if (strstr(ucontrol->id.name, "ADC 0A Mux"))1199 mask_sft = 0;1200 else if (strstr(ucontrol->id.name, "ADC 0B Mux"))1201 mask_sft = 4;1202 else1203 return -EINVAL;1204 1205 rt712_sdca_index_read(rt712, RT712_VENDOR_HDA_CTL,1206 RT712_HDA_LEGACY_MUX_CTL0, &val);1207 1208 ucontrol->value.enumerated.item[0] = (((val >> mask_sft) & 0xf) == 0x4) ? 0 : 1;1209 1210 return 0;1211}1212 1213static int rt712_sdca_dmic_mux_put(struct snd_kcontrol *kcontrol,1214 struct snd_ctl_elem_value *ucontrol)1215{1216 struct snd_soc_component *component =1217 snd_soc_dapm_kcontrol_component(kcontrol);1218 struct snd_soc_dapm_context *dapm =1219 snd_soc_dapm_kcontrol_dapm(kcontrol);1220 struct rt712_sdca_priv *rt712 = snd_soc_component_get_drvdata(component);1221 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;1222 unsigned int *item = ucontrol->value.enumerated.item;1223 unsigned int val, val2 = 0, change, mask_sft;1224 1225 if (item[0] >= e->items)1226 return -EINVAL;1227 1228 if (strstr(ucontrol->id.name, "ADC 0A Mux"))1229 mask_sft = 0;1230 else if (strstr(ucontrol->id.name, "ADC 0B Mux"))1231 mask_sft = 4;1232 else1233 return -EINVAL;1234 1235 val = snd_soc_enum_item_to_val(e, item[0]) << e->shift_l;1236 1237 rt712_sdca_index_read(rt712, RT712_VENDOR_HDA_CTL,1238 RT712_HDA_LEGACY_MUX_CTL0, &val2);1239 val2 = ((0xf << mask_sft) & val2) >> mask_sft;1240 1241 if (val == 0)1242 val = 0x4;1243 else if (val >= 1)1244 val = 0xe;1245 1246 if (val == val2)1247 change = 0;1248 else1249 change = 1;1250 1251 if (change)1252 rt712_sdca_index_update_bits(rt712, RT712_VENDOR_HDA_CTL,1253 RT712_HDA_LEGACY_MUX_CTL0, 0xf << mask_sft,1254 val << mask_sft);1255 1256 snd_soc_dapm_mux_update_power(dapm, kcontrol, item[0], e, NULL);1257 1258 return change;1259}1260 1261static const char * const adc_dmic_mux_text[] = {1262 "DMIC1",1263 "DMIC2",1264};1265 1266static SOC_ENUM_SINGLE_DECL(1267 rt712_adc0a_enum, SND_SOC_NOPM, 0, adc_dmic_mux_text);1268 1269static SOC_ENUM_SINGLE_DECL(1270 rt712_adc0b_enum, SND_SOC_NOPM, 0, adc_dmic_mux_text);1271 1272static const struct snd_kcontrol_new rt712_sdca_dmic_adc0a_mux =1273 SOC_DAPM_ENUM_EXT("ADC 0A Mux", rt712_adc0a_enum,1274 rt712_sdca_dmic_mux_get, rt712_sdca_dmic_mux_put);1275 1276static const struct snd_kcontrol_new rt712_sdca_dmic_adc0b_mux =1277 SOC_DAPM_ENUM_EXT("ADC 0B Mux", rt712_adc0b_enum,1278 rt712_sdca_dmic_mux_get, rt712_sdca_dmic_mux_put);1279 1280static int rt712_sdca_dmic_fu1e_event(struct snd_soc_dapm_widget *w,1281 struct snd_kcontrol *kcontrol, int event)1282{1283 struct snd_soc_component *component =1284 snd_soc_dapm_to_component(w->dapm);1285 struct rt712_sdca_priv *rt712 = snd_soc_component_get_drvdata(component);1286 1287 switch (event) {1288 case SND_SOC_DAPM_POST_PMU:1289 rt712->fu1e_dapm_mute = false;1290 rt712_sdca_set_fu1e_capture_ctl(rt712);1291 break;1292 case SND_SOC_DAPM_PRE_PMD:1293 rt712->fu1e_dapm_mute = true;1294 rt712_sdca_set_fu1e_capture_ctl(rt712);1295 break;1296 }1297 return 0;1298}1299 1300static int rt712_sdca_dmic_pde11_event(struct snd_soc_dapm_widget *w,1301 struct snd_kcontrol *kcontrol, int event)1302{1303 struct snd_soc_component *component =1304 snd_soc_dapm_to_component(w->dapm);1305 struct rt712_sdca_priv *rt712 = snd_soc_component_get_drvdata(component);1306 unsigned char ps0 = 0x0, ps3 = 0x3;1307 1308 switch (event) {1309 case SND_SOC_DAPM_POST_PMU:1310 regmap_write(rt712->regmap,1311 SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT712_SDCA_ENT_PDE11,1312 RT712_SDCA_CTL_REQ_POWER_STATE, 0),1313 ps0);1314 break;1315 case SND_SOC_DAPM_PRE_PMD:1316 regmap_write(rt712->regmap,1317 SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT712_SDCA_ENT_PDE11,1318 RT712_SDCA_CTL_REQ_POWER_STATE, 0),1319 ps3);1320 break;1321 }1322 return 0;1323}1324 1325static const struct snd_soc_dapm_widget rt712_sdca_dmic_dapm_widgets[] = {1326 SND_SOC_DAPM_INPUT("DMIC1"),1327 SND_SOC_DAPM_INPUT("DMIC2"),1328 1329 SND_SOC_DAPM_SUPPLY("PDE 11", SND_SOC_NOPM, 0, 0,1330 rt712_sdca_dmic_pde11_event,1331 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),1332 1333 SND_SOC_DAPM_ADC_E("FU 1E", NULL, SND_SOC_NOPM, 0, 0,1334 rt712_sdca_dmic_fu1e_event,1335 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),1336 SND_SOC_DAPM_MUX("ADC 0A Mux", SND_SOC_NOPM, 0, 0,1337 &rt712_sdca_dmic_adc0a_mux),1338 SND_SOC_DAPM_MUX("ADC 0B Mux", SND_SOC_NOPM, 0, 0,1339 &rt712_sdca_dmic_adc0b_mux),1340 1341 SND_SOC_DAPM_AIF_OUT("DP8TX", "DP8 Capture", 0, SND_SOC_NOPM, 0, 0),1342};1343 1344static const struct snd_soc_dapm_route rt712_sdca_dmic_audio_map[] = {1345 {"DP8TX", NULL, "FU 1E"},1346 1347 {"FU 1E", NULL, "PDE 11"},1348 {"FU 1E", NULL, "ADC 0A Mux"},1349 {"FU 1E", NULL, "ADC 0B Mux"},1350 {"ADC 0A Mux", "DMIC1", "DMIC1"},1351 {"ADC 0A Mux", "DMIC2", "DMIC2"},1352 {"ADC 0B Mux", "DMIC1", "DMIC1"},1353 {"ADC 0B Mux", "DMIC2", "DMIC2"},1354};1355 1356static int rt712_sdca_dmic_probe(struct snd_soc_component *component)1357{1358 struct rt712_sdca_priv *rt712 = snd_soc_component_get_drvdata(component);1359 int ret;1360 1361 rt712->dmic_component = component;1362 1363 if (!rt712->first_hw_init)1364 return 0;1365 1366 ret = pm_runtime_resume(component->dev);1367 if (ret < 0 && ret != -EACCES)1368 return ret;1369 1370 return 0;1371}1372 1373static const struct snd_soc_component_driver soc_sdca_dev_rt712 = {1374 .probe = rt712_sdca_probe,1375 .controls = rt712_sdca_controls,1376 .num_controls = ARRAY_SIZE(rt712_sdca_controls),1377 .dapm_widgets = rt712_sdca_dapm_widgets,1378 .num_dapm_widgets = ARRAY_SIZE(rt712_sdca_dapm_widgets),1379 .dapm_routes = rt712_sdca_audio_map,1380 .num_dapm_routes = ARRAY_SIZE(rt712_sdca_audio_map),1381 .set_jack = rt712_sdca_set_jack_detect,1382 .endianness = 1,1383};1384 1385static const struct snd_soc_component_driver soc_sdca_dev_rt712_dmic = {1386 .probe = rt712_sdca_dmic_probe,1387 .controls = rt712_sdca_dmic_snd_controls,1388 .num_controls = ARRAY_SIZE(rt712_sdca_dmic_snd_controls),1389 .dapm_widgets = rt712_sdca_dmic_dapm_widgets,1390 .num_dapm_widgets = ARRAY_SIZE(rt712_sdca_dmic_dapm_widgets),1391 .dapm_routes = rt712_sdca_dmic_audio_map,1392 .num_dapm_routes = ARRAY_SIZE(rt712_sdca_dmic_audio_map),1393 .endianness = 1,1394#ifdef CONFIG_DEBUG_FS1395 .debugfs_prefix = "dmic",1396#endif1397};1398 1399static int rt712_sdca_set_sdw_stream(struct snd_soc_dai *dai, void *sdw_stream,1400 int direction)1401{1402 snd_soc_dai_dma_data_set(dai, direction, sdw_stream);1403 1404 return 0;1405}1406 1407static void rt712_sdca_shutdown(struct snd_pcm_substream *substream,1408 struct snd_soc_dai *dai)1409{1410 snd_soc_dai_set_dma_data(dai, substream, NULL);1411}1412 1413static int rt712_sdca_pcm_hw_params(struct snd_pcm_substream *substream,1414 struct snd_pcm_hw_params *params,1415 struct snd_soc_dai *dai)1416{1417 struct snd_soc_component *component = dai->component;1418 struct rt712_sdca_priv *rt712 = snd_soc_component_get_drvdata(component);1419 struct sdw_stream_config stream_config;1420 struct sdw_port_config port_config;1421 enum sdw_data_direction direction;1422 struct sdw_stream_runtime *sdw_stream;1423 int retval, port, num_channels;1424 unsigned int sampling_rate;1425 1426 dev_dbg(dai->dev, "%s %s id %d", __func__, dai->name, dai->id);1427 sdw_stream = snd_soc_dai_get_dma_data(dai, substream);1428 1429 if (!sdw_stream)1430 return -EINVAL;1431 1432 if (!rt712->slave)1433 return -EINVAL;1434 1435 /* VA doesn't support AIF3 */1436 if (dai->id == RT712_AIF3 && rt712->version_id == RT712_VA)1437 return -EINVAL;1438 1439 /* SoundWire specific configuration */1440 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {1441 direction = SDW_DATA_DIR_RX;1442 if (dai->id == RT712_AIF1)1443 port = 1;1444 else if (dai->id == RT712_AIF2)1445 port = 3;1446 else1447 return -EINVAL;1448 } else {1449 direction = SDW_DATA_DIR_TX;1450 if (dai->id == RT712_AIF1)1451 port = 4;1452 else if (dai->id == RT712_AIF3)1453 port = 8;1454 else1455 return -EINVAL;1456 }1457 1458 stream_config.frame_rate = params_rate(params);1459 stream_config.ch_count = params_channels(params);1460 stream_config.bps = snd_pcm_format_width(params_format(params));1461 stream_config.direction = direction;1462 1463 num_channels = params_channels(params);1464 port_config.ch_mask = GENMASK(num_channels - 1, 0);1465 port_config.num = port;1466 1467 retval = sdw_stream_add_slave(rt712->slave, &stream_config,1468 &port_config, 1, sdw_stream);1469 if (retval) {1470 dev_err(dai->dev, "%s: Unable to configure port\n", __func__);1471 return retval;1472 }1473 1474 if (params_channels(params) > 16) {1475 dev_err(component->dev, "%s: Unsupported channels %d\n",1476 __func__, params_channels(params));1477 return -EINVAL;1478 }1479 1480 /* sampling rate configuration */1481 switch (params_rate(params)) {1482 case 44100:1483 sampling_rate = RT712_SDCA_RATE_44100HZ;1484 break;1485 case 48000:1486 sampling_rate = RT712_SDCA_RATE_48000HZ;1487 break;1488 case 96000:1489 sampling_rate = RT712_SDCA_RATE_96000HZ;1490 break;1491 case 192000:1492 sampling_rate = RT712_SDCA_RATE_192000HZ;1493 break;1494 default:1495 dev_err(component->dev, "%s: Rate %d is not supported\n",1496 __func__, params_rate(params));1497 return -EINVAL;1498 }1499 1500 /* set sampling frequency */1501 switch (dai->id) {1502 case RT712_AIF1:1503 regmap_write(rt712->regmap,1504 SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT712_SDCA_ENT_CS01, RT712_SDCA_CTL_SAMPLE_FREQ_INDEX, 0),1505 sampling_rate);1506 regmap_write(rt712->regmap,1507 SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT712_SDCA_ENT_CS11, RT712_SDCA_CTL_SAMPLE_FREQ_INDEX, 0),1508 sampling_rate);1509 break;1510 case RT712_AIF2:1511 regmap_write(rt712->regmap,1512 SDW_SDCA_CTL(FUNC_NUM_AMP, RT712_SDCA_ENT_CS31, RT712_SDCA_CTL_SAMPLE_FREQ_INDEX, 0),1513 sampling_rate);1514 break;1515 case RT712_AIF3:1516 regmap_write(rt712->regmap,1517 SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT712_SDCA_ENT_CS1F, RT712_SDCA_CTL_SAMPLE_FREQ_INDEX, 0),1518 sampling_rate);1519 regmap_write(rt712->regmap,1520 SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT712_SDCA_ENT_CS1C, RT712_SDCA_CTL_SAMPLE_FREQ_INDEX, 0),1521 sampling_rate);1522 break;1523 default:1524 dev_err(component->dev, "%s: Wrong DAI id\n", __func__);1525 return -EINVAL;1526 }1527 1528 return 0;1529}1530 1531static int rt712_sdca_pcm_hw_free(struct snd_pcm_substream *substream,1532 struct snd_soc_dai *dai)1533{1534 struct snd_soc_component *component = dai->component;1535 struct rt712_sdca_priv *rt712 = snd_soc_component_get_drvdata(component);1536 struct sdw_stream_runtime *sdw_stream =1537 snd_soc_dai_get_dma_data(dai, substream);1538 1539 if (!rt712->slave)1540 return -EINVAL;1541 1542 sdw_stream_remove_slave(rt712->slave, sdw_stream);1543 return 0;1544}1545 1546#define RT712_STEREO_RATES (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 | \1547 SNDRV_PCM_RATE_192000)1548#define RT712_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \1549 SNDRV_PCM_FMTBIT_S24_LE)1550 1551static const struct snd_soc_dai_ops rt712_sdca_ops = {1552 .hw_params = rt712_sdca_pcm_hw_params,1553 .hw_free = rt712_sdca_pcm_hw_free,1554 .set_stream = rt712_sdca_set_sdw_stream,1555 .shutdown = rt712_sdca_shutdown,1556};1557 1558static struct snd_soc_dai_driver rt712_sdca_dai[] = {1559 {1560 .name = "rt712-sdca-aif1",1561 .id = RT712_AIF1,1562 .playback = {1563 .stream_name = "DP1 Playback",1564 .channels_min = 1,1565 .channels_max = 2,1566 .rates = RT712_STEREO_RATES,1567 .formats = RT712_FORMATS,1568 },1569 .capture = {1570 .stream_name = "DP4 Capture",1571 .channels_min = 1,1572 .channels_max = 2,1573 .rates = RT712_STEREO_RATES,1574 .formats = RT712_FORMATS,1575 },1576 .ops = &rt712_sdca_ops,1577 },1578 {1579 .name = "rt712-sdca-aif2",1580 .id = RT712_AIF2,1581 .playback = {1582 .stream_name = "DP3 Playback",1583 .channels_min = 1,1584 .channels_max = 2,1585 .rates = RT712_STEREO_RATES,1586 .formats = RT712_FORMATS,1587 },1588 .ops = &rt712_sdca_ops,1589 }1590};1591 1592static struct snd_soc_dai_driver rt712_sdca_dmic_dai[] = {1593 {1594 .name = "rt712-sdca-aif3",1595 .id = RT712_AIF3,1596 .capture = {1597 .stream_name = "DP8 Capture",1598 .channels_min = 1,1599 .channels_max = 4,1600 .rates = RT712_STEREO_RATES,1601 .formats = RT712_FORMATS,1602 },1603 .ops = &rt712_sdca_ops,1604 }1605};1606 1607int rt712_sdca_init(struct device *dev, struct regmap *regmap,1608 struct regmap *mbq_regmap, struct sdw_slave *slave)1609{1610 struct rt712_sdca_priv *rt712;1611 int ret;1612 1613 rt712 = devm_kzalloc(dev, sizeof(*rt712), GFP_KERNEL);1614 if (!rt712)1615 return -ENOMEM;1616 1617 dev_set_drvdata(dev, rt712);1618 rt712->slave = slave;1619 rt712->regmap = regmap;1620 rt712->mbq_regmap = mbq_regmap;1621 1622 regcache_cache_only(rt712->regmap, true);1623 regcache_cache_only(rt712->mbq_regmap, true);1624 1625 mutex_init(&rt712->calibrate_mutex);1626 mutex_init(&rt712->disable_irq_lock);1627 1628 INIT_DELAYED_WORK(&rt712->jack_detect_work, rt712_sdca_jack_detect_handler);1629 INIT_DELAYED_WORK(&rt712->jack_btn_check_work, rt712_sdca_btn_check_handler);1630 1631 /*1632 * Mark hw_init to false1633 * HW init will be performed when device reports present1634 */1635 rt712->hw_init = false;1636 rt712->first_hw_init = false;1637 rt712->fu0f_dapm_mute = true;1638 rt712->fu0f_mixer_l_mute = rt712->fu0f_mixer_r_mute = true;1639 rt712->fu1e_dapm_mute = true;1640 rt712->fu1e_mixer_mute[0] = rt712->fu1e_mixer_mute[1] =1641 rt712->fu1e_mixer_mute[2] = rt712->fu1e_mixer_mute[3] = true;1642 1643 /* JD source uses JD1 in default */1644 rt712->jd_src = RT712_JD1;1645 1646 if (slave->id.part_id != RT712_PART_ID_713)1647 ret = devm_snd_soc_register_component(dev,1648 &soc_sdca_dev_rt712, rt712_sdca_dai, ARRAY_SIZE(rt712_sdca_dai));1649 else1650 ret = devm_snd_soc_register_component(dev,1651 &soc_sdca_dev_rt712, rt712_sdca_dai, 1);1652 if (ret < 0)1653 return ret;1654 1655 /* set autosuspend parameters */1656 pm_runtime_set_autosuspend_delay(dev, 3000);1657 pm_runtime_use_autosuspend(dev);1658 1659 /* make sure the device does not suspend immediately */1660 pm_runtime_mark_last_busy(dev);1661 1662 pm_runtime_enable(dev);1663 1664 /* important note: the device is NOT tagged as 'active' and will remain1665 * 'suspended' until the hardware is enumerated/initialized. This is required1666 * to make sure the ASoC framework use of pm_runtime_get_sync() does not silently1667 * fail with -EACCESS because of race conditions between card creation and enumeration1668 */1669 1670 dev_dbg(dev, "%s\n", __func__);1671 1672 return 0;1673}1674 1675static void rt712_sdca_va_io_init(struct rt712_sdca_priv *rt712)1676{1677 int ret = 0;1678 unsigned int hibernation_flag;1679 struct device *dev = &rt712->slave->dev;1680 1681 rt712_sdca_index_write(rt712, RT712_VENDOR_REG, RT712_ANALOG_BIAS_CTL3, 0xaa81);1682 rt712_sdca_index_write(rt712, RT712_VENDOR_REG, RT712_LDO2_3_CTL1, 0xa1e0);1683 rt712_sdca_index_write(rt712, RT712_VENDOR_IMS_DRE, RT712_HP_DETECT_RLDET_CTL1, 0x0000);1684 rt712_sdca_index_write(rt712, RT712_VENDOR_IMS_DRE, RT712_HP_DETECT_RLDET_CTL2, 0x0000);1685 rt712_sdca_index_write(rt712, RT712_VENDOR_ANALOG_CTL, RT712_MISC_POWER_CTL7, 0x0000);1686 regmap_write(rt712->regmap, RT712_RC_CAL, 0x23);1687 1688 /* calibration */1689 rt712_sdca_index_read(rt712, RT712_VENDOR_REG, RT712_SW_CONFIG1, &hibernation_flag);1690 if (!hibernation_flag) {1691 ret = rt712_sdca_calibration(rt712);1692 if (ret < 0)1693 dev_err(dev, "%s, calibration failed!\n", __func__);1694 }1695 1696 rt712_sdca_index_update_bits(rt712, RT712_VENDOR_HDA_CTL,1697 RT712_MIXER_CTL1, 0x3000, 0x0000);1698 rt712_sdca_index_write(rt712, RT712_VENDOR_HDA_CTL,1699 RT712_ADC0A_08_PDE_FLOAT_CTL, 0x1112);1700 rt712_sdca_index_write(rt712, RT712_VENDOR_HDA_CTL,1701 RT712_MIC2_LINE2_PDE_FLOAT_CTL, 0x3412);1702 rt712_sdca_index_write(rt712, RT712_VENDOR_HDA_CTL,1703 RT712_DAC03_HP_PDE_FLOAT_CTL, 0x4040);1704 1705 rt712_sdca_index_update_bits(rt712, RT712_VENDOR_HDA_CTL,1706 RT712_HDA_LEGACY_GPIO_WAKE_EN_CTL, 0x0001, 0x0000);1707 regmap_write(rt712->regmap, 0x2f50, 0x00);1708 regmap_write(rt712->regmap, 0x2f54, 0x00);1709 regmap_write(rt712->regmap,1710 SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT712_SDCA_ENT_IT09, RT712_SDCA_CTL_VENDOR_DEF, 0), 0x01);1711 1712 /* add SPK settings */1713 if (rt712->hw_id != RT712_DEV_ID_713) {1714 rt712_sdca_index_write(rt712, RT712_VENDOR_HDA_CTL, RT712_AMP_PDE_FLOAT_CTL, 0x2323);1715 rt712_sdca_index_write(rt712, RT712_VENDOR_HDA_CTL, RT712_EAPD_CTL, 0x0002);1716 regmap_write(rt712->regmap,1717 SDW_SDCA_CTL(FUNC_NUM_AMP, RT712_SDCA_ENT_OT23, RT712_SDCA_CTL_VENDOR_DEF, 0), 0x04);1718 }1719}1720 1721static void rt712_sdca_vb_io_init(struct rt712_sdca_priv *rt712)1722{1723 int ret = 0;1724 unsigned int jack_func_status, mic_func_status, amp_func_status;1725 struct device *dev = &rt712->slave->dev;1726 1727 regmap_read(rt712->regmap,1728 SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT712_SDCA_ENT0, RT712_SDCA_CTL_FUNC_STATUS, 0), &jack_func_status);1729 regmap_read(rt712->regmap,1730 SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT712_SDCA_ENT0, RT712_SDCA_CTL_FUNC_STATUS, 0), &mic_func_status);1731 regmap_read(rt712->regmap,1732 SDW_SDCA_CTL(FUNC_NUM_AMP, RT712_SDCA_ENT0, RT712_SDCA_CTL_FUNC_STATUS, 0), &_func_status);1733 dev_dbg(dev, "%s jack/mic/amp func_status=0x%x, 0x%x, 0x%x\n",1734 __func__, jack_func_status, mic_func_status, amp_func_status);1735 1736 /* DMIC */1737 if ((mic_func_status & FUNCTION_NEEDS_INITIALIZATION) || (!rt712->first_hw_init)) {1738 rt712_sdca_index_write(rt712, RT712_VENDOR_HDA_CTL, RT712_DMIC2_FU_IT_FLOAT_CTL, 0x1526);1739 rt712_sdca_index_write(rt712, RT712_VENDOR_HDA_CTL, RT712_DMIC2_FU_CH12_FLOAT_CTL, 0x0304);1740 rt712_sdca_index_write(rt712, RT712_VENDOR_HDA_CTL, RT712_ADC0A_CS_ADC0B_FU_FLOAT_CTL, 0x1f1e);1741 rt712_sdca_index_write(rt712, RT712_VENDOR_HDA_CTL, RT712_ADC0B_FU_CH12_FLOAT_CTL, 0x0304);1742 rt712_sdca_index_write(rt712, RT712_VENDOR_HDA_CTL, RT712_HDA_LEGACY_CONFIG_CTL0, 0x8010);1743 regmap_write(rt712->regmap,1744 SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT712_SDCA_ENT_IT11, RT712_SDCA_CTL_VENDOR_DEF, 0), 0x01);1745 rt712_sdca_index_write(rt712, RT712_ULTRA_SOUND_DET, RT712_ULTRA_SOUND_DETECTOR6, 0x3200);1746 regmap_write(rt712->regmap, RT712_RC_CAL, 0x23);1747 1748 /* clear flag */1749 regmap_write(rt712->regmap,1750 SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT712_SDCA_ENT0, RT712_SDCA_CTL_FUNC_STATUS, 0),1751 FUNCTION_NEEDS_INITIALIZATION);1752 }1753 1754 /* Jack */1755 if ((jack_func_status & FUNCTION_NEEDS_INITIALIZATION) || (!rt712->first_hw_init)) {1756 rt712_sdca_index_write(rt712, RT712_VENDOR_IMS_DRE, RT712_SEL_VEE2_HP_CTL1, 0x042a);1757 rt712_sdca_index_write(rt712, RT712_CHARGE_PUMP, RT712_HP_DET_CTL3, 0x1fff);1758 rt712_sdca_index_write(rt712, RT712_VENDOR_REG, RT712_IO_CTL, 0xec67);1759 rt712_sdca_index_write(rt712, RT712_VENDOR_REG, RT712_ANALOG_BIAS_CTL3, 0xaa81);1760 rt712_sdca_index_write(rt712, RT712_VENDOR_REG, RT712_LDO2_3_CTL1, 0xa1e0);1761 rt712_sdca_index_write(rt712, RT712_VENDOR_IMS_DRE, RT712_HP_DETECT_RLDET_CTL1, 0x0000);1762 rt712_sdca_index_write(rt712, RT712_VENDOR_IMS_DRE, RT712_HP_DETECT_RLDET_CTL2, 0x0000);1763 regmap_write(rt712->regmap, RT712_RC_CAL, 0x23);1764 rt712_sdca_index_write(rt712, RT712_VENDOR_REG, RT712_JD_CTL1, 0x2802);1765 rt712_sdca_index_write(rt712, RT712_VENDOR_REG, RT712_CLASSD_AMP_CTL6, 0xf215);1766 1767 /* calibration */1768 ret = rt712_sdca_calibration(rt712);1769 if (ret < 0)1770 dev_err(dev, "%s, calibration failed!\n", __func__);1771 1772 rt712_sdca_index_update_bits(rt712, RT712_VENDOR_HDA_CTL, RT712_MIXER_CTL1, 0x3000, 0x0000);1773 regmap_write(rt712->regmap,1774 SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT712_SDCA_ENT_IT09, RT712_SDCA_CTL_VENDOR_DEF, 0), 0x01);1775 rt712_sdca_index_write(rt712, RT712_VENDOR_HDA_CTL, RT712_MISC_CTL_FOR_UAJ, 0x0003);1776 1777 /* clear flag */1778 regmap_write(rt712->regmap,1779 SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT712_SDCA_ENT0, RT712_SDCA_CTL_FUNC_STATUS, 0),1780 FUNCTION_NEEDS_INITIALIZATION);1781 }1782 1783 /* SPK */1784 if ((amp_func_status & FUNCTION_NEEDS_INITIALIZATION) || (!rt712->first_hw_init)) {1785 if (rt712->hw_id != RT712_DEV_ID_713) {1786 rt712_sdca_index_write(rt712, RT712_VENDOR_REG, RT712_IO_CTL, 0xec63);1787 rt712_sdca_index_write(rt712, RT712_VENDOR_REG, RT712_CLASSD_AMP_CTL1, 0xfff5);1788 rt712_sdca_index_write(rt712, RT712_VENDOR_HDA_CTL, RT712_EAPD_CTL, 0x0002);1789 regmap_write(rt712->regmap,1790 SDW_SDCA_CTL(FUNC_NUM_AMP, RT712_SDCA_ENT_OT23, RT712_SDCA_CTL_VENDOR_DEF, 0), 0x04);1791 }1792 /* clear flag */1793 regmap_write(rt712->regmap,1794 SDW_SDCA_CTL(FUNC_NUM_AMP, RT712_SDCA_ENT0, RT712_SDCA_CTL_FUNC_STATUS, 0),1795 FUNCTION_NEEDS_INITIALIZATION);1796 }1797}1798 1799int rt712_sdca_io_init(struct device *dev, struct sdw_slave *slave)1800{1801 struct rt712_sdca_priv *rt712 = dev_get_drvdata(dev);1802 int ret = 0;1803 unsigned int val;1804 struct sdw_slave_prop *prop = &slave->prop;1805 1806 rt712->disable_irq = false;1807 1808 if (rt712->hw_init)1809 return 0;1810 1811 regcache_cache_only(rt712->regmap, false);1812 regcache_cache_only(rt712->mbq_regmap, false);1813 if (rt712->first_hw_init) {1814 regcache_cache_bypass(rt712->regmap, true);1815 regcache_cache_bypass(rt712->mbq_regmap, true);1816 } else {1817 /*1818 * PM runtime status is marked as 'active' only when a Slave reports as Attached1819 */1820 1821 /* update count of parent 'active' children */1822 pm_runtime_set_active(&slave->dev);1823 }1824 1825 pm_runtime_get_noresume(&slave->dev);1826 1827 rt712_sdca_index_read(rt712, RT712_VENDOR_REG, RT712_JD_PRODUCT_NUM, &val);1828 rt712->hw_id = (val & 0xf000) >> 12;1829 rt712->version_id = (val & 0x0f00) >> 8;1830 dev_dbg(&slave->dev, "%s hw_id=0x%x, version_id=0x%x\n", __func__, rt712->hw_id, rt712->version_id);1831 1832 if (rt712->version_id == RT712_VA)1833 rt712_sdca_va_io_init(rt712);1834 else {1835 /* multilanes and DMIC are supported by rt712vb */1836 ret = devm_snd_soc_register_component(dev,1837 &soc_sdca_dev_rt712_dmic, rt712_sdca_dmic_dai, ARRAY_SIZE(rt712_sdca_dmic_dai));1838 if (ret < 0)1839 return ret;1840 1841 prop->lane_control_support = true;1842 rt712_sdca_vb_io_init(rt712);1843 }1844 1845 /*1846 * if set_jack callback occurred early than io_init,1847 * we set up the jack detection function now1848 */1849 if (rt712->hs_jack)1850 rt712_sdca_jack_init(rt712);1851 1852 rt712_sdca_index_write(rt712, RT712_VENDOR_REG, RT712_SW_CONFIG1, 0x0001);1853 1854 if (rt712->first_hw_init) {1855 regcache_cache_bypass(rt712->regmap, false);1856 regcache_mark_dirty(rt712->regmap);1857 regcache_cache_bypass(rt712->mbq_regmap, false);1858 regcache_mark_dirty(rt712->mbq_regmap);1859 } else1860 rt712->first_hw_init = true;1861 1862 /* Mark Slave initialization complete */1863 rt712->hw_init = true;1864 1865 pm_runtime_mark_last_busy(&slave->dev);1866 pm_runtime_put_autosuspend(&slave->dev);1867 1868 dev_dbg(&slave->dev, "%s hw_init complete\n", __func__);1869 return 0;1870}1871 1872MODULE_DESCRIPTION("ASoC RT712 SDCA SDW driver");1873MODULE_AUTHOR("Shuming Fan <shumingf@realtek.com>");1874MODULE_LICENSE("GPL");1875