1569 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2//3// rt722-sdca.c -- rt722 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 <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 "rt722-sdca.h"27 28int rt722_sdca_index_write(struct rt722_sdca_priv *rt722,29 unsigned int nid, unsigned int reg, unsigned int value)30{31 struct regmap *regmap = rt722->mbq_regmap;32 unsigned int addr = (nid << 20) | reg;33 int ret;34 35 ret = regmap_write(regmap, addr, value);36 if (ret < 0)37 dev_err(&rt722->slave->dev,38 "%s: Failed to set private value: %06x <= %04x ret=%d\n",39 __func__, addr, value, ret);40 41 return ret;42}43 44int rt722_sdca_index_read(struct rt722_sdca_priv *rt722,45 unsigned int nid, unsigned int reg, unsigned int *value)46{47 int ret;48 struct regmap *regmap = rt722->mbq_regmap;49 unsigned int addr = (nid << 20) | reg;50 51 ret = regmap_read(regmap, addr, value);52 if (ret < 0)53 dev_err(&rt722->slave->dev,54 "%s: Failed to get private value: %06x => %04x ret=%d\n",55 __func__, addr, *value, ret);56 57 return ret;58}59 60static int rt722_sdca_index_update_bits(struct rt722_sdca_priv *rt722,61 unsigned int nid, unsigned int reg, unsigned int mask, unsigned int val)62{63 unsigned int tmp;64 int ret;65 66 ret = rt722_sdca_index_read(rt722, nid, reg, &tmp);67 if (ret < 0)68 return ret;69 70 set_mask_bits(&tmp, mask, val);71 return rt722_sdca_index_write(rt722, nid, reg, tmp);72}73 74static int rt722_sdca_btn_type(unsigned char *buffer)75{76 if ((*buffer & 0xf0) == 0x10 || (*buffer & 0x0f) == 0x01 || (*(buffer + 1) == 0x01) ||77 (*(buffer + 1) == 0x10))78 return SND_JACK_BTN_2;79 else if ((*buffer & 0xf0) == 0x20 || (*buffer & 0x0f) == 0x02 || (*(buffer + 1) == 0x02) ||80 (*(buffer + 1) == 0x20))81 return SND_JACK_BTN_3;82 else if ((*buffer & 0xf0) == 0x40 || (*buffer & 0x0f) == 0x04 || (*(buffer + 1) == 0x04) ||83 (*(buffer + 1) == 0x40))84 return SND_JACK_BTN_0;85 else if ((*buffer & 0xf0) == 0x80 || (*buffer & 0x0f) == 0x08 || (*(buffer + 1) == 0x08) ||86 (*(buffer + 1) == 0x80))87 return SND_JACK_BTN_1;88 89 return 0;90}91 92static unsigned int rt722_sdca_button_detect(struct rt722_sdca_priv *rt722)93{94 unsigned int btn_type = 0, offset, idx, val, owner;95 int ret;96 unsigned char buf[3];97 98 /* get current UMP message owner */99 ret = regmap_read(rt722->regmap,100 SDW_SDCA_CTL(FUNC_NUM_HID, RT722_SDCA_ENT_HID01,101 RT722_SDCA_CTL_HIDTX_CURRENT_OWNER, 0), &owner);102 if (ret < 0)103 return 0;104 105 /* if owner is device then there is no button event from device */106 if (owner == 1)107 return 0;108 109 /* read UMP message offset */110 ret = regmap_read(rt722->regmap,111 SDW_SDCA_CTL(FUNC_NUM_HID, RT722_SDCA_ENT_HID01,112 RT722_SDCA_CTL_HIDTX_MESSAGE_OFFSET, 0), &offset);113 if (ret < 0)114 goto _end_btn_det_;115 116 for (idx = 0; idx < sizeof(buf); idx++) {117 ret = regmap_read(rt722->regmap,118 RT722_BUF_ADDR_HID1 + offset + idx, &val);119 if (ret < 0)120 goto _end_btn_det_;121 buf[idx] = val & 0xff;122 }123 124 if (buf[0] == 0x11)125 btn_type = rt722_sdca_btn_type(&buf[1]);126 127_end_btn_det_:128 /* Host is owner, so set back to device */129 if (owner == 0)130 /* set owner to device */131 regmap_write(rt722->regmap,132 SDW_SDCA_CTL(FUNC_NUM_HID, RT722_SDCA_ENT_HID01,133 RT722_SDCA_CTL_HIDTX_CURRENT_OWNER, 0), 0x01);134 135 return btn_type;136}137 138static int rt722_sdca_headset_detect(struct rt722_sdca_priv *rt722)139{140 unsigned int det_mode;141 int ret;142 143 /* get detected_mode */144 ret = regmap_read(rt722->regmap,145 SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT722_SDCA_ENT_GE49,146 RT722_SDCA_CTL_DETECTED_MODE, 0), &det_mode);147 if (ret < 0)148 goto io_error;149 150 switch (det_mode) {151 case 0x00:152 rt722->jack_type = 0;153 break;154 case 0x03:155 rt722->jack_type = SND_JACK_HEADPHONE;156 break;157 case 0x05:158 rt722->jack_type = SND_JACK_HEADSET;159 break;160 }161 162 /* write selected_mode */163 if (det_mode) {164 ret = regmap_write(rt722->regmap,165 SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT722_SDCA_ENT_GE49,166 RT722_SDCA_CTL_SELECTED_MODE, 0), det_mode);167 if (ret < 0)168 goto io_error;169 }170 171 dev_dbg(&rt722->slave->dev,172 "%s, detected_mode=0x%x\n", __func__, det_mode);173 174 return 0;175 176io_error:177 pr_err_ratelimited("IO error in %s, ret %d\n", __func__, ret);178 return ret;179}180 181static void rt722_sdca_jack_detect_handler(struct work_struct *work)182{183 struct rt722_sdca_priv *rt722 =184 container_of(work, struct rt722_sdca_priv, jack_detect_work.work);185 int btn_type = 0, ret;186 187 if (!rt722->hs_jack)188 return;189 190 if (!rt722->component->card || !rt722->component->card->instantiated)191 return;192 193 /* SDW_SCP_SDCA_INT_SDCA_6 is used for jack detection */194 if (rt722->scp_sdca_stat1 & SDW_SCP_SDCA_INT_SDCA_6) {195 ret = rt722_sdca_headset_detect(rt722);196 if (ret < 0)197 return;198 }199 200 /* SDW_SCP_SDCA_INT_SDCA_8 is used for button detection */201 if (rt722->scp_sdca_stat2 & SDW_SCP_SDCA_INT_SDCA_8)202 btn_type = rt722_sdca_button_detect(rt722);203 204 if (rt722->jack_type == 0)205 btn_type = 0;206 207 dev_dbg(&rt722->slave->dev,208 "in %s, jack_type=%d\n", __func__, rt722->jack_type);209 dev_dbg(&rt722->slave->dev,210 "in %s, btn_type=0x%x\n", __func__, btn_type);211 dev_dbg(&rt722->slave->dev,212 "in %s, scp_sdca_stat1=0x%x, scp_sdca_stat2=0x%x\n", __func__,213 rt722->scp_sdca_stat1, rt722->scp_sdca_stat2);214 215 snd_soc_jack_report(rt722->hs_jack, rt722->jack_type | btn_type,216 SND_JACK_HEADSET |217 SND_JACK_BTN_0 | SND_JACK_BTN_1 |218 SND_JACK_BTN_2 | SND_JACK_BTN_3);219 220 if (btn_type) {221 /* button released */222 snd_soc_jack_report(rt722->hs_jack, rt722->jack_type,223 SND_JACK_HEADSET |224 SND_JACK_BTN_0 | SND_JACK_BTN_1 |225 SND_JACK_BTN_2 | SND_JACK_BTN_3);226 227 mod_delayed_work(system_power_efficient_wq,228 &rt722->jack_btn_check_work, msecs_to_jiffies(200));229 }230}231 232static void rt722_sdca_btn_check_handler(struct work_struct *work)233{234 struct rt722_sdca_priv *rt722 =235 container_of(work, struct rt722_sdca_priv, jack_btn_check_work.work);236 int btn_type = 0, ret, idx;237 unsigned int det_mode, offset, val;238 unsigned char buf[3];239 240 ret = regmap_read(rt722->regmap,241 SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT722_SDCA_ENT_GE49,242 RT722_SDCA_CTL_DETECTED_MODE, 0), &det_mode);243 if (ret < 0)244 goto io_error;245 246 /* pin attached */247 if (det_mode) {248 /* read UMP message offset */249 ret = regmap_read(rt722->regmap,250 SDW_SDCA_CTL(FUNC_NUM_HID, RT722_SDCA_ENT_HID01,251 RT722_SDCA_CTL_HIDTX_MESSAGE_OFFSET, 0), &offset);252 if (ret < 0)253 goto io_error;254 255 for (idx = 0; idx < sizeof(buf); idx++) {256 ret = regmap_read(rt722->regmap,257 RT722_BUF_ADDR_HID1 + offset + idx, &val);258 if (ret < 0)259 goto io_error;260 buf[idx] = val & 0xff;261 }262 263 if (buf[0] == 0x11)264 btn_type = rt722_sdca_btn_type(&buf[1]);265 } else266 rt722->jack_type = 0;267 268 dev_dbg(&rt722->slave->dev, "%s, btn_type=0x%x\n", __func__, btn_type);269 snd_soc_jack_report(rt722->hs_jack, rt722->jack_type | btn_type,270 SND_JACK_HEADSET |271 SND_JACK_BTN_0 | SND_JACK_BTN_1 |272 SND_JACK_BTN_2 | SND_JACK_BTN_3);273 274 if (btn_type) {275 /* button released */276 snd_soc_jack_report(rt722->hs_jack, rt722->jack_type,277 SND_JACK_HEADSET |278 SND_JACK_BTN_0 | SND_JACK_BTN_1 |279 SND_JACK_BTN_2 | SND_JACK_BTN_3);280 281 mod_delayed_work(system_power_efficient_wq,282 &rt722->jack_btn_check_work, msecs_to_jiffies(200));283 }284 285 return;286 287io_error:288 pr_err_ratelimited("IO error in %s, ret %d\n", __func__, ret);289}290 291static void rt722_sdca_jack_init(struct rt722_sdca_priv *rt722)292{293 mutex_lock(&rt722->calibrate_mutex);294 if (rt722->hs_jack) {295 /* set SCP_SDCA_IntMask1[0]=1 */296 sdw_write_no_pm(rt722->slave, SDW_SCP_SDCA_INTMASK1,297 SDW_SCP_SDCA_INTMASK_SDCA_0 | SDW_SCP_SDCA_INTMASK_SDCA_6);298 /* set SCP_SDCA_IntMask2[0]=1 */299 sdw_write_no_pm(rt722->slave, SDW_SCP_SDCA_INTMASK2,300 SDW_SCP_SDCA_INTMASK_SDCA_8);301 dev_dbg(&rt722->slave->dev, "in %s enable\n", __func__);302 rt722_sdca_index_write(rt722, RT722_VENDOR_HDA_CTL,303 RT722_HDA_LEGACY_UNSOL_CTL, 0x016E);304 /* set XU(et03h) & XU(et0Dh) to Not bypassed */305 regmap_write(rt722->regmap,306 SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT722_SDCA_ENT_XU03,307 RT722_SDCA_CTL_SELECTED_MODE, 0), 0);308 regmap_write(rt722->regmap,309 SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT722_SDCA_ENT_XU0D,310 RT722_SDCA_CTL_SELECTED_MODE, 0), 0);311 /* trigger GE interrupt */312 rt722_sdca_index_update_bits(rt722, RT722_VENDOR_HDA_CTL,313 RT722_GE_RELATED_CTL2, 0x4000, 0x4000);314 }315 mutex_unlock(&rt722->calibrate_mutex);316}317 318static int rt722_sdca_set_jack_detect(struct snd_soc_component *component,319 struct snd_soc_jack *hs_jack, void *data)320{321 struct rt722_sdca_priv *rt722 = snd_soc_component_get_drvdata(component);322 int ret;323 324 rt722->hs_jack = hs_jack;325 326 ret = pm_runtime_resume_and_get(component->dev);327 if (ret < 0) {328 if (ret != -EACCES) {329 dev_err(component->dev, "%s: failed to resume %d\n", __func__, ret);330 return ret;331 }332 /* pm_runtime not enabled yet */333 dev_dbg(component->dev, "%s: skipping jack init for now\n", __func__);334 return 0;335 }336 337 rt722_sdca_jack_init(rt722);338 339 pm_runtime_mark_last_busy(component->dev);340 pm_runtime_put_autosuspend(component->dev);341 342 return 0;343}344 345/* For SDCA control DAC/ADC Gain */346static int rt722_sdca_set_gain_put(struct snd_kcontrol *kcontrol,347 struct snd_ctl_elem_value *ucontrol)348{349 struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);350 struct soc_mixer_control *mc =351 (struct soc_mixer_control *)kcontrol->private_value;352 struct rt722_sdca_priv *rt722 = snd_soc_component_get_drvdata(component);353 unsigned int read_l, read_r, gain_l_val, gain_r_val;354 unsigned int adc_vol_flag = 0, changed = 0;355 unsigned int lvalue, rvalue;356 const unsigned int interval_offset = 0xc0;357 const unsigned int tendB = 0xa00;358 359 if (strstr(ucontrol->id.name, "FU1E Capture Volume") ||360 strstr(ucontrol->id.name, "FU0F Capture Volume"))361 adc_vol_flag = 1;362 363 regmap_read(rt722->mbq_regmap, mc->reg, &lvalue);364 regmap_read(rt722->mbq_regmap, mc->rreg, &rvalue);365 366 /* L Channel */367 gain_l_val = ucontrol->value.integer.value[0];368 if (gain_l_val > mc->max)369 gain_l_val = mc->max;370 371 if (mc->shift == 8) /* boost gain */372 gain_l_val = gain_l_val * tendB;373 else {374 /* ADC/DAC gain */375 if (adc_vol_flag)376 gain_l_val = 0x1e00 - ((mc->max - gain_l_val) * interval_offset);377 else378 gain_l_val = 0 - ((mc->max - gain_l_val) * interval_offset);379 gain_l_val &= 0xffff;380 }381 382 /* R Channel */383 gain_r_val = ucontrol->value.integer.value[1];384 if (gain_r_val > mc->max)385 gain_r_val = mc->max;386 387 if (mc->shift == 8) /* boost gain */388 gain_r_val = gain_r_val * tendB;389 else {390 /* ADC/DAC gain */391 if (adc_vol_flag)392 gain_r_val = 0x1e00 - ((mc->max - gain_r_val) * interval_offset);393 else394 gain_r_val = 0 - ((mc->max - gain_r_val) * interval_offset);395 gain_r_val &= 0xffff;396 }397 398 if (lvalue != gain_l_val || rvalue != gain_r_val)399 changed = 1;400 else401 return 0;402 403 /* Lch*/404 regmap_write(rt722->mbq_regmap, mc->reg, gain_l_val);405 406 /* Rch */407 regmap_write(rt722->mbq_regmap, mc->rreg, gain_r_val);408 409 regmap_read(rt722->mbq_regmap, mc->reg, &read_l);410 regmap_read(rt722->mbq_regmap, mc->rreg, &read_r);411 if (read_r == gain_r_val && read_l == gain_l_val)412 return changed;413 414 return -EIO;415}416 417static int rt722_sdca_set_gain_get(struct snd_kcontrol *kcontrol,418 struct snd_ctl_elem_value *ucontrol)419{420 struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);421 struct rt722_sdca_priv *rt722 = snd_soc_component_get_drvdata(component);422 struct soc_mixer_control *mc =423 (struct soc_mixer_control *)kcontrol->private_value;424 unsigned int read_l, read_r, ctl_l = 0, ctl_r = 0;425 unsigned int adc_vol_flag = 0;426 const unsigned int interval_offset = 0xc0;427 const unsigned int tendB = 0xa00;428 429 if (strstr(ucontrol->id.name, "FU1E Capture Volume") ||430 strstr(ucontrol->id.name, "FU0F Capture Volume"))431 adc_vol_flag = 1;432 433 regmap_read(rt722->mbq_regmap, mc->reg, &read_l);434 regmap_read(rt722->mbq_regmap, mc->rreg, &read_r);435 436 if (mc->shift == 8) /* boost gain */437 ctl_l = read_l / tendB;438 else {439 if (adc_vol_flag)440 ctl_l = mc->max - (((0x1e00 - read_l) & 0xffff) / interval_offset);441 else442 ctl_l = mc->max - (((0 - read_l) & 0xffff) / interval_offset);443 }444 445 if (read_l != read_r) {446 if (mc->shift == 8) /* boost gain */447 ctl_r = read_r / tendB;448 else { /* ADC/DAC gain */449 if (adc_vol_flag)450 ctl_r = mc->max - (((0x1e00 - read_r) & 0xffff) / interval_offset);451 else452 ctl_r = mc->max - (((0 - read_r) & 0xffff) / interval_offset);453 }454 } else {455 ctl_r = ctl_l;456 }457 458 ucontrol->value.integer.value[0] = ctl_l;459 ucontrol->value.integer.value[1] = ctl_r;460 461 return 0;462}463 464static int rt722_sdca_set_fu1e_capture_ctl(struct rt722_sdca_priv *rt722)465{466 int err, i;467 unsigned int ch_mute;468 469 for (i = 0; i < ARRAY_SIZE(rt722->fu1e_mixer_mute); i++) {470 ch_mute = rt722->fu1e_dapm_mute || rt722->fu1e_mixer_mute[i];471 err = regmap_write(rt722->regmap,472 SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT722_SDCA_ENT_USER_FU1E,473 RT722_SDCA_CTL_FU_MUTE, CH_01) + i, ch_mute);474 if (err < 0)475 return err;476 }477 478 return 0;479}480 481static int rt722_sdca_fu1e_capture_get(struct snd_kcontrol *kcontrol,482 struct snd_ctl_elem_value *ucontrol)483{484 struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);485 struct rt722_sdca_priv *rt722 = snd_soc_component_get_drvdata(component);486 struct rt722_sdca_dmic_kctrl_priv *p =487 (struct rt722_sdca_dmic_kctrl_priv *)kcontrol->private_value;488 unsigned int i;489 490 for (i = 0; i < p->count; i++)491 ucontrol->value.integer.value[i] = !rt722->fu1e_mixer_mute[i];492 493 return 0;494}495 496static int rt722_sdca_fu1e_capture_put(struct snd_kcontrol *kcontrol,497 struct snd_ctl_elem_value *ucontrol)498{499 struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);500 struct rt722_sdca_priv *rt722 = snd_soc_component_get_drvdata(component);501 struct rt722_sdca_dmic_kctrl_priv *p =502 (struct rt722_sdca_dmic_kctrl_priv *)kcontrol->private_value;503 int err, changed = 0, i;504 505 for (i = 0; i < p->count; i++) {506 if (rt722->fu1e_mixer_mute[i] != !ucontrol->value.integer.value[i])507 changed = 1;508 rt722->fu1e_mixer_mute[i] = !ucontrol->value.integer.value[i];509 }510 511 err = rt722_sdca_set_fu1e_capture_ctl(rt722);512 if (err < 0)513 return err;514 515 return changed;516}517 518static int rt722_sdca_set_fu0f_capture_ctl(struct rt722_sdca_priv *rt722)519{520 int err;521 unsigned int ch_l, ch_r;522 523 ch_l = (rt722->fu0f_dapm_mute || rt722->fu0f_mixer_l_mute) ? 0x01 : 0x00;524 ch_r = (rt722->fu0f_dapm_mute || rt722->fu0f_mixer_r_mute) ? 0x01 : 0x00;525 526 err = regmap_write(rt722->regmap,527 SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT722_SDCA_ENT_USER_FU0F,528 RT722_SDCA_CTL_FU_MUTE, CH_L), ch_l);529 if (err < 0)530 return err;531 532 err = regmap_write(rt722->regmap,533 SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT722_SDCA_ENT_USER_FU0F,534 RT722_SDCA_CTL_FU_MUTE, CH_R), ch_r);535 if (err < 0)536 return err;537 538 return 0;539}540 541static int rt722_sdca_fu0f_capture_get(struct snd_kcontrol *kcontrol,542 struct snd_ctl_elem_value *ucontrol)543{544 struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);545 struct rt722_sdca_priv *rt722 = snd_soc_component_get_drvdata(component);546 547 ucontrol->value.integer.value[0] = !rt722->fu0f_mixer_l_mute;548 ucontrol->value.integer.value[1] = !rt722->fu0f_mixer_r_mute;549 return 0;550}551 552static int rt722_sdca_fu0f_capture_put(struct snd_kcontrol *kcontrol,553 struct snd_ctl_elem_value *ucontrol)554{555 struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);556 struct rt722_sdca_priv *rt722 = snd_soc_component_get_drvdata(component);557 int err, changed = 0;558 559 if (rt722->fu0f_mixer_l_mute != !ucontrol->value.integer.value[0] ||560 rt722->fu0f_mixer_r_mute != !ucontrol->value.integer.value[1])561 changed = 1;562 563 rt722->fu0f_mixer_l_mute = !ucontrol->value.integer.value[0];564 rt722->fu0f_mixer_r_mute = !ucontrol->value.integer.value[1];565 err = rt722_sdca_set_fu0f_capture_ctl(rt722);566 if (err < 0)567 return err;568 569 return changed;570}571 572static int rt722_sdca_fu_info(struct snd_kcontrol *kcontrol,573 struct snd_ctl_elem_info *uinfo)574{575 struct rt722_sdca_dmic_kctrl_priv *p =576 (struct rt722_sdca_dmic_kctrl_priv *)kcontrol->private_value;577 578 if (p->max == 1)579 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;580 else581 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;582 uinfo->count = p->count;583 uinfo->value.integer.min = 0;584 uinfo->value.integer.max = p->max;585 return 0;586}587 588static int rt722_sdca_dmic_set_gain_get(struct snd_kcontrol *kcontrol,589 struct snd_ctl_elem_value *ucontrol)590{591 struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);592 struct rt722_sdca_priv *rt722 = snd_soc_component_get_drvdata(component);593 struct rt722_sdca_dmic_kctrl_priv *p =594 (struct rt722_sdca_dmic_kctrl_priv *)kcontrol->private_value;595 unsigned int boost_step = 0x0a00;596 unsigned int vol_max = 0x1e00;597 unsigned int regvalue, ctl, i;598 unsigned int adc_vol_flag = 0;599 const unsigned int interval_offset = 0xc0;600 601 if (strstr(ucontrol->id.name, "FU1E Capture Volume"))602 adc_vol_flag = 1;603 604 /* check all channels */605 for (i = 0; i < p->count; i++) {606 regmap_read(rt722->mbq_regmap, p->reg_base + i, ®value);607 608 if (!adc_vol_flag) /* boost gain */609 ctl = regvalue / boost_step;610 else { /* ADC gain */611 if (adc_vol_flag)612 ctl = p->max - (((vol_max - regvalue) & 0xffff) / interval_offset);613 else614 ctl = p->max - (((0 - regvalue) & 0xffff) / interval_offset);615 }616 617 ucontrol->value.integer.value[i] = ctl;618 }619 620 return 0;621}622 623static int rt722_sdca_dmic_set_gain_put(struct snd_kcontrol *kcontrol,624 struct snd_ctl_elem_value *ucontrol)625{626 struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);627 struct rt722_sdca_dmic_kctrl_priv *p =628 (struct rt722_sdca_dmic_kctrl_priv *)kcontrol->private_value;629 struct rt722_sdca_priv *rt722 = snd_soc_component_get_drvdata(component);630 unsigned int boost_step = 0x0a00;631 unsigned int vol_max = 0x1e00;632 unsigned int gain_val[4];633 unsigned int i, adc_vol_flag = 0, changed = 0;634 unsigned int regvalue[4];635 const unsigned int interval_offset = 0xc0;636 int err;637 638 if (strstr(ucontrol->id.name, "FU1E Capture Volume"))639 adc_vol_flag = 1;640 641 /* check all channels */642 for (i = 0; i < p->count; i++) {643 regmap_read(rt722->mbq_regmap, p->reg_base + i, ®value[i]);644 645 gain_val[i] = ucontrol->value.integer.value[i];646 if (gain_val[i] > p->max)647 gain_val[i] = p->max;648 649 if (!adc_vol_flag) /* boost gain */650 gain_val[i] = gain_val[i] * boost_step;651 else { /* ADC gain */652 gain_val[i] = vol_max - ((p->max - gain_val[i]) * interval_offset);653 gain_val[i] &= 0xffff;654 }655 656 if (regvalue[i] != gain_val[i])657 changed = 1;658 }659 660 if (!changed)661 return 0;662 663 for (i = 0; i < p->count; i++) {664 err = regmap_write(rt722->mbq_regmap, p->reg_base + i, gain_val[i]);665 if (err < 0)666 dev_err(&rt722->slave->dev, "%s: %#08x can't be set\n",667 __func__, p->reg_base + i);668 }669 670 return changed;671}672 673#define RT722_SDCA_PR_VALUE(xreg_base, xcount, xmax, xinvert) \674 ((unsigned long)&(struct rt722_sdca_dmic_kctrl_priv) \675 {.reg_base = xreg_base, .count = xcount, .max = xmax, \676 .invert = xinvert})677 678#define RT722_SDCA_FU_CTRL(xname, reg_base, xmax, xinvert, xcount) \679{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \680 .info = rt722_sdca_fu_info, \681 .get = rt722_sdca_fu1e_capture_get, \682 .put = rt722_sdca_fu1e_capture_put, \683 .private_value = RT722_SDCA_PR_VALUE(reg_base, xcount, xmax, xinvert)}684 685#define RT722_SDCA_EXT_TLV(xname, reg_base, xhandler_get,\686 xhandler_put, xcount, xmax, tlv_array) \687{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \688 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \689 SNDRV_CTL_ELEM_ACCESS_READWRITE, \690 .tlv.p = (tlv_array), \691 .info = rt722_sdca_fu_info, \692 .get = xhandler_get, .put = xhandler_put, \693 .private_value = RT722_SDCA_PR_VALUE(reg_base, xcount, xmax, 0) }694 695static const DECLARE_TLV_DB_SCALE(out_vol_tlv, -6525, 75, 0);696static const DECLARE_TLV_DB_SCALE(mic_vol_tlv, -1725, 75, 0);697static const DECLARE_TLV_DB_SCALE(boost_vol_tlv, 0, 1000, 0);698 699static const struct snd_kcontrol_new rt722_sdca_controls[] = {700 /* Headphone playback settings */701 SOC_DOUBLE_R_EXT_TLV("FU05 Playback Volume",702 SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT722_SDCA_ENT_USER_FU05,703 RT722_SDCA_CTL_FU_VOLUME, CH_L),704 SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT722_SDCA_ENT_USER_FU05,705 RT722_SDCA_CTL_FU_VOLUME, CH_R), 0, 0x57, 0,706 rt722_sdca_set_gain_get, rt722_sdca_set_gain_put, out_vol_tlv),707 /* Headset mic capture settings */708 SOC_DOUBLE_EXT("FU0F Capture Switch", SND_SOC_NOPM, 0, 1, 1, 0,709 rt722_sdca_fu0f_capture_get, rt722_sdca_fu0f_capture_put),710 SOC_DOUBLE_R_EXT_TLV("FU0F Capture Volume",711 SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT722_SDCA_ENT_USER_FU0F,712 RT722_SDCA_CTL_FU_VOLUME, CH_L),713 SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT722_SDCA_ENT_USER_FU0F,714 RT722_SDCA_CTL_FU_VOLUME, CH_R), 0, 0x3f, 0,715 rt722_sdca_set_gain_get, rt722_sdca_set_gain_put, mic_vol_tlv),716 SOC_DOUBLE_R_EXT_TLV("FU33 Boost Volume",717 SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT722_SDCA_ENT_PLATFORM_FU44,718 RT722_SDCA_CTL_FU_CH_GAIN, CH_L),719 SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT722_SDCA_ENT_PLATFORM_FU44,720 RT722_SDCA_CTL_FU_CH_GAIN, CH_R), 8, 3, 0,721 rt722_sdca_set_gain_get, rt722_sdca_set_gain_put, boost_vol_tlv),722 /* AMP playback settings */723 SOC_DOUBLE_R_EXT_TLV("FU06 Playback Volume",724 SDW_SDCA_CTL(FUNC_NUM_AMP, RT722_SDCA_ENT_USER_FU06,725 RT722_SDCA_CTL_FU_VOLUME, CH_L),726 SDW_SDCA_CTL(FUNC_NUM_AMP, RT722_SDCA_ENT_USER_FU06,727 RT722_SDCA_CTL_FU_VOLUME, CH_R), 0, 0x57, 0,728 rt722_sdca_set_gain_get, rt722_sdca_set_gain_put, out_vol_tlv),729 /* DMIC capture settings */730 RT722_SDCA_FU_CTRL("FU1E Capture Switch",731 SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT722_SDCA_ENT_USER_FU1E,732 RT722_SDCA_CTL_FU_MUTE, CH_01), 1, 1, 4),733 RT722_SDCA_EXT_TLV("FU1E Capture Volume",734 SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT722_SDCA_ENT_USER_FU1E,735 RT722_SDCA_CTL_FU_VOLUME, CH_01),736 rt722_sdca_dmic_set_gain_get, rt722_sdca_dmic_set_gain_put,737 4, 0x3f, mic_vol_tlv),738 RT722_SDCA_EXT_TLV("FU15 Boost Volume",739 SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT722_SDCA_ENT_FU15,740 RT722_SDCA_CTL_FU_CH_GAIN, CH_01),741 rt722_sdca_dmic_set_gain_get, rt722_sdca_dmic_set_gain_put,742 4, 3, boost_vol_tlv),743};744 745static int rt722_sdca_adc_mux_get(struct snd_kcontrol *kcontrol,746 struct snd_ctl_elem_value *ucontrol)747{748 struct snd_soc_component *component =749 snd_soc_dapm_kcontrol_component(kcontrol);750 struct rt722_sdca_priv *rt722 = snd_soc_component_get_drvdata(component);751 unsigned int val = 0, mask_sft;752 753 if (strstr(ucontrol->id.name, "ADC 22 Mux"))754 mask_sft = 12;755 else if (strstr(ucontrol->id.name, "ADC 24 Mux"))756 mask_sft = 4;757 else if (strstr(ucontrol->id.name, "ADC 25 Mux"))758 mask_sft = 0;759 else760 return -EINVAL;761 762 rt722_sdca_index_read(rt722, RT722_VENDOR_HDA_CTL,763 RT722_HDA_LEGACY_MUX_CTL0, &val);764 765 ucontrol->value.enumerated.item[0] = (val >> mask_sft) & 0x7;766 767 return 0;768}769 770static int rt722_sdca_adc_mux_put(struct snd_kcontrol *kcontrol,771 struct snd_ctl_elem_value *ucontrol)772{773 struct snd_soc_component *component =774 snd_soc_dapm_kcontrol_component(kcontrol);775 struct snd_soc_dapm_context *dapm =776 snd_soc_dapm_kcontrol_dapm(kcontrol);777 struct rt722_sdca_priv *rt722 = snd_soc_component_get_drvdata(component);778 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;779 unsigned int *item = ucontrol->value.enumerated.item;780 unsigned int val, val2 = 0, change, mask_sft;781 782 if (item[0] >= e->items)783 return -EINVAL;784 785 if (strstr(ucontrol->id.name, "ADC 22 Mux"))786 mask_sft = 12;787 else if (strstr(ucontrol->id.name, "ADC 24 Mux"))788 mask_sft = 4;789 else if (strstr(ucontrol->id.name, "ADC 25 Mux"))790 mask_sft = 0;791 else792 return -EINVAL;793 794 val = snd_soc_enum_item_to_val(e, item[0]) << e->shift_l;795 796 rt722_sdca_index_read(rt722, RT722_VENDOR_HDA_CTL,797 RT722_HDA_LEGACY_MUX_CTL0, &val2);798 val2 = (0x7 << mask_sft) & val2;799 800 if (val == val2)801 change = 0;802 else803 change = 1;804 805 if (change)806 rt722_sdca_index_update_bits(rt722, RT722_VENDOR_HDA_CTL,807 RT722_HDA_LEGACY_MUX_CTL0, 0x7 << mask_sft,808 val << mask_sft);809 810 snd_soc_dapm_mux_update_power(dapm, kcontrol,811 item[0], e, NULL);812 813 return change;814}815 816static const char * const adc22_mux_text[] = {817 "MIC2",818 "LINE1",819 "LINE2",820};821 822static const char * const adc07_10_mux_text[] = {823 "DMIC1",824 "DMIC2",825};826 827static SOC_ENUM_SINGLE_DECL(828 rt722_adc22_enum, SND_SOC_NOPM, 0, adc22_mux_text);829 830static SOC_ENUM_SINGLE_DECL(831 rt722_adc24_enum, SND_SOC_NOPM, 0, adc07_10_mux_text);832 833static SOC_ENUM_SINGLE_DECL(834 rt722_adc25_enum, SND_SOC_NOPM, 0, adc07_10_mux_text);835 836static const struct snd_kcontrol_new rt722_sdca_adc22_mux =837 SOC_DAPM_ENUM_EXT("ADC 22 Mux", rt722_adc22_enum,838 rt722_sdca_adc_mux_get, rt722_sdca_adc_mux_put);839 840static const struct snd_kcontrol_new rt722_sdca_adc24_mux =841 SOC_DAPM_ENUM_EXT("ADC 24 Mux", rt722_adc24_enum,842 rt722_sdca_adc_mux_get, rt722_sdca_adc_mux_put);843 844static const struct snd_kcontrol_new rt722_sdca_adc25_mux =845 SOC_DAPM_ENUM_EXT("ADC 25 Mux", rt722_adc25_enum,846 rt722_sdca_adc_mux_get, rt722_sdca_adc_mux_put);847 848static int rt722_sdca_fu42_event(struct snd_soc_dapm_widget *w,849 struct snd_kcontrol *kcontrol, int event)850{851 struct snd_soc_component *component =852 snd_soc_dapm_to_component(w->dapm);853 struct rt722_sdca_priv *rt722 = snd_soc_component_get_drvdata(component);854 unsigned char unmute = 0x0, mute = 0x1;855 856 switch (event) {857 case SND_SOC_DAPM_POST_PMU:858 regmap_write(rt722->regmap,859 SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT722_SDCA_ENT_USER_FU05,860 RT722_SDCA_CTL_FU_MUTE, CH_L), unmute);861 regmap_write(rt722->regmap,862 SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT722_SDCA_ENT_USER_FU05,863 RT722_SDCA_CTL_FU_MUTE, CH_R), unmute);864 break;865 case SND_SOC_DAPM_PRE_PMD:866 regmap_write(rt722->regmap,867 SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT722_SDCA_ENT_USER_FU05,868 RT722_SDCA_CTL_FU_MUTE, CH_L), mute);869 regmap_write(rt722->regmap,870 SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT722_SDCA_ENT_USER_FU05,871 RT722_SDCA_CTL_FU_MUTE, CH_R), mute);872 break;873 }874 return 0;875}876 877static int rt722_sdca_fu21_event(struct snd_soc_dapm_widget *w,878 struct snd_kcontrol *kcontrol, int event)879{880 struct snd_soc_component *component =881 snd_soc_dapm_to_component(w->dapm);882 struct rt722_sdca_priv *rt722 = snd_soc_component_get_drvdata(component);883 unsigned char unmute = 0x0, mute = 0x1;884 885 switch (event) {886 case SND_SOC_DAPM_POST_PMU:887 regmap_write(rt722->regmap,888 SDW_SDCA_CTL(FUNC_NUM_AMP, RT722_SDCA_ENT_USER_FU06,889 RT722_SDCA_CTL_FU_MUTE, CH_L), unmute);890 regmap_write(rt722->regmap,891 SDW_SDCA_CTL(FUNC_NUM_AMP, RT722_SDCA_ENT_USER_FU06,892 RT722_SDCA_CTL_FU_MUTE, CH_R), unmute);893 break;894 case SND_SOC_DAPM_PRE_PMD:895 regmap_write(rt722->regmap,896 SDW_SDCA_CTL(FUNC_NUM_AMP, RT722_SDCA_ENT_USER_FU06,897 RT722_SDCA_CTL_FU_MUTE, CH_L), mute);898 regmap_write(rt722->regmap,899 SDW_SDCA_CTL(FUNC_NUM_AMP, RT722_SDCA_ENT_USER_FU06,900 RT722_SDCA_CTL_FU_MUTE, CH_R), mute);901 break;902 }903 return 0;904}905 906static int rt722_sdca_fu113_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 rt722_sdca_priv *rt722 = snd_soc_component_get_drvdata(component);912 913 switch (event) {914 case SND_SOC_DAPM_POST_PMU:915 rt722->fu1e_dapm_mute = false;916 rt722_sdca_set_fu1e_capture_ctl(rt722);917 break;918 case SND_SOC_DAPM_PRE_PMD:919 rt722->fu1e_dapm_mute = true;920 rt722_sdca_set_fu1e_capture_ctl(rt722);921 break;922 }923 return 0;924}925 926static int rt722_sdca_fu36_event(struct snd_soc_dapm_widget *w,927 struct snd_kcontrol *kcontrol, int event)928{929 struct snd_soc_component *component =930 snd_soc_dapm_to_component(w->dapm);931 struct rt722_sdca_priv *rt722 = snd_soc_component_get_drvdata(component);932 933 switch (event) {934 case SND_SOC_DAPM_POST_PMU:935 rt722->fu0f_dapm_mute = false;936 rt722_sdca_set_fu0f_capture_ctl(rt722);937 break;938 case SND_SOC_DAPM_PRE_PMD:939 rt722->fu0f_dapm_mute = true;940 rt722_sdca_set_fu0f_capture_ctl(rt722);941 break;942 }943 return 0;944}945 946static int rt722_sdca_pde47_event(struct snd_soc_dapm_widget *w,947 struct snd_kcontrol *kcontrol, int event)948{949 struct snd_soc_component *component =950 snd_soc_dapm_to_component(w->dapm);951 struct rt722_sdca_priv *rt722 = snd_soc_component_get_drvdata(component);952 unsigned char ps0 = 0x0, ps3 = 0x3;953 954 switch (event) {955 case SND_SOC_DAPM_POST_PMU:956 regmap_write(rt722->regmap,957 SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT722_SDCA_ENT_PDE40,958 RT722_SDCA_CTL_REQ_POWER_STATE, 0), ps0);959 break;960 case SND_SOC_DAPM_PRE_PMD:961 regmap_write(rt722->regmap,962 SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT722_SDCA_ENT_PDE40,963 RT722_SDCA_CTL_REQ_POWER_STATE, 0), ps3);964 break;965 }966 return 0;967}968 969static int rt722_sdca_pde23_event(struct snd_soc_dapm_widget *w,970 struct snd_kcontrol *kcontrol, int event)971{972 struct snd_soc_component *component =973 snd_soc_dapm_to_component(w->dapm);974 struct rt722_sdca_priv *rt722 = snd_soc_component_get_drvdata(component);975 unsigned char ps0 = 0x0, ps3 = 0x3;976 977 switch (event) {978 case SND_SOC_DAPM_POST_PMU:979 regmap_write(rt722->regmap,980 SDW_SDCA_CTL(FUNC_NUM_AMP, RT722_SDCA_ENT_PDE23,981 RT722_SDCA_CTL_REQ_POWER_STATE, 0), ps0);982 break;983 case SND_SOC_DAPM_PRE_PMD:984 regmap_write(rt722->regmap,985 SDW_SDCA_CTL(FUNC_NUM_AMP, RT722_SDCA_ENT_PDE23,986 RT722_SDCA_CTL_REQ_POWER_STATE, 0), ps3);987 break;988 }989 return 0;990}991 992static int rt722_sdca_pde11_event(struct snd_soc_dapm_widget *w,993 struct snd_kcontrol *kcontrol, int event)994{995 struct snd_soc_component *component =996 snd_soc_dapm_to_component(w->dapm);997 struct rt722_sdca_priv *rt722 = snd_soc_component_get_drvdata(component);998 unsigned char ps0 = 0x0, ps3 = 0x3;999 1000 switch (event) {1001 case SND_SOC_DAPM_POST_PMU:1002 regmap_write(rt722->regmap,1003 SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT722_SDCA_ENT_PDE2A,1004 RT722_SDCA_CTL_REQ_POWER_STATE, 0), ps0);1005 break;1006 case SND_SOC_DAPM_PRE_PMD:1007 regmap_write(rt722->regmap,1008 SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT722_SDCA_ENT_PDE2A,1009 RT722_SDCA_CTL_REQ_POWER_STATE, 0), ps3);1010 break;1011 }1012 return 0;1013}1014 1015static int rt722_sdca_pde12_event(struct snd_soc_dapm_widget *w,1016 struct snd_kcontrol *kcontrol, int event)1017{1018 struct snd_soc_component *component =1019 snd_soc_dapm_to_component(w->dapm);1020 struct rt722_sdca_priv *rt722 = snd_soc_component_get_drvdata(component);1021 unsigned char ps0 = 0x0, ps3 = 0x3;1022 1023 switch (event) {1024 case SND_SOC_DAPM_POST_PMU:1025 regmap_write(rt722->regmap,1026 SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT722_SDCA_ENT_PDE12,1027 RT722_SDCA_CTL_REQ_POWER_STATE, 0), ps0);1028 break;1029 case SND_SOC_DAPM_PRE_PMD:1030 regmap_write(rt722->regmap,1031 SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT722_SDCA_ENT_PDE12,1032 RT722_SDCA_CTL_REQ_POWER_STATE, 0), ps3);1033 break;1034 }1035 return 0;1036}1037 1038static const struct snd_soc_dapm_widget rt722_sdca_dapm_widgets[] = {1039 SND_SOC_DAPM_OUTPUT("HP"),1040 SND_SOC_DAPM_OUTPUT("SPK"),1041 SND_SOC_DAPM_INPUT("MIC2"),1042 SND_SOC_DAPM_INPUT("LINE1"),1043 SND_SOC_DAPM_INPUT("LINE2"),1044 SND_SOC_DAPM_INPUT("DMIC1_2"),1045 SND_SOC_DAPM_INPUT("DMIC3_4"),1046 1047 SND_SOC_DAPM_SUPPLY("PDE 23", SND_SOC_NOPM, 0, 0,1048 rt722_sdca_pde23_event,1049 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),1050 SND_SOC_DAPM_SUPPLY("PDE 47", SND_SOC_NOPM, 0, 0,1051 rt722_sdca_pde47_event,1052 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),1053 SND_SOC_DAPM_SUPPLY("PDE 11", SND_SOC_NOPM, 0, 0,1054 rt722_sdca_pde11_event,1055 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),1056 SND_SOC_DAPM_SUPPLY("PDE 12", SND_SOC_NOPM, 0, 0,1057 rt722_sdca_pde12_event,1058 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),1059 1060 SND_SOC_DAPM_DAC_E("FU 21", NULL, SND_SOC_NOPM, 0, 0,1061 rt722_sdca_fu21_event,1062 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),1063 SND_SOC_DAPM_DAC_E("FU 42", NULL, SND_SOC_NOPM, 0, 0,1064 rt722_sdca_fu42_event,1065 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),1066 SND_SOC_DAPM_ADC_E("FU 36", NULL, SND_SOC_NOPM, 0, 0,1067 rt722_sdca_fu36_event,1068 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),1069 SND_SOC_DAPM_ADC_E("FU 113", NULL, SND_SOC_NOPM, 0, 0,1070 rt722_sdca_fu113_event,1071 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),1072 SND_SOC_DAPM_MUX("ADC 22 Mux", SND_SOC_NOPM, 0, 0,1073 &rt722_sdca_adc22_mux),1074 SND_SOC_DAPM_MUX("ADC 24 Mux", SND_SOC_NOPM, 0, 0,1075 &rt722_sdca_adc24_mux),1076 SND_SOC_DAPM_MUX("ADC 25 Mux", SND_SOC_NOPM, 0, 0,1077 &rt722_sdca_adc25_mux),1078 1079 SND_SOC_DAPM_AIF_IN("DP1RX", "DP1 Headphone Playback", 0, SND_SOC_NOPM, 0, 0),1080 SND_SOC_DAPM_AIF_OUT("DP2TX", "DP2 Headset Capture", 0, SND_SOC_NOPM, 0, 0),1081 SND_SOC_DAPM_AIF_IN("DP3RX", "DP3 Speaker Playback", 0, SND_SOC_NOPM, 0, 0),1082 SND_SOC_DAPM_AIF_OUT("DP6TX", "DP6 DMic Capture", 0, SND_SOC_NOPM, 0, 0),1083};1084 1085static const struct snd_soc_dapm_route rt722_sdca_audio_map[] = {1086 {"FU 42", NULL, "DP1RX"},1087 {"FU 21", NULL, "DP3RX"},1088 1089 {"ADC 22 Mux", "MIC2", "MIC2"},1090 {"ADC 22 Mux", "LINE1", "LINE1"},1091 {"ADC 22 Mux", "LINE2", "LINE2"},1092 {"ADC 24 Mux", "DMIC1", "DMIC1_2"},1093 {"ADC 24 Mux", "DMIC2", "DMIC3_4"},1094 {"ADC 25 Mux", "DMIC1", "DMIC1_2"},1095 {"ADC 25 Mux", "DMIC2", "DMIC3_4"},1096 {"FU 36", NULL, "PDE 12"},1097 {"FU 36", NULL, "ADC 22 Mux"},1098 {"FU 113", NULL, "PDE 11"},1099 {"FU 113", NULL, "ADC 24 Mux"},1100 {"FU 113", NULL, "ADC 25 Mux"},1101 {"DP2TX", NULL, "FU 36"},1102 {"DP6TX", NULL, "FU 113"},1103 1104 {"HP", NULL, "PDE 47"},1105 {"HP", NULL, "FU 42"},1106 {"SPK", NULL, "PDE 23"},1107 {"SPK", NULL, "FU 21"},1108};1109 1110static int rt722_sdca_parse_dt(struct rt722_sdca_priv *rt722, struct device *dev)1111{1112 device_property_read_u32(dev, "realtek,jd-src", &rt722->jd_src);1113 1114 return 0;1115}1116 1117static int rt722_sdca_probe(struct snd_soc_component *component)1118{1119 struct rt722_sdca_priv *rt722 = snd_soc_component_get_drvdata(component);1120 int ret;1121 1122 rt722_sdca_parse_dt(rt722, &rt722->slave->dev);1123 rt722->component = component;1124 1125 ret = pm_runtime_resume(component->dev);1126 if (ret < 0 && ret != -EACCES)1127 return ret;1128 1129 return 0;1130}1131 1132static const struct snd_soc_component_driver soc_sdca_dev_rt722 = {1133 .probe = rt722_sdca_probe,1134 .controls = rt722_sdca_controls,1135 .num_controls = ARRAY_SIZE(rt722_sdca_controls),1136 .dapm_widgets = rt722_sdca_dapm_widgets,1137 .num_dapm_widgets = ARRAY_SIZE(rt722_sdca_dapm_widgets),1138 .dapm_routes = rt722_sdca_audio_map,1139 .num_dapm_routes = ARRAY_SIZE(rt722_sdca_audio_map),1140 .set_jack = rt722_sdca_set_jack_detect,1141 .endianness = 1,1142};1143 1144static int rt722_sdca_set_sdw_stream(struct snd_soc_dai *dai, void *sdw_stream,1145 int direction)1146{1147 snd_soc_dai_dma_data_set(dai, direction, sdw_stream);1148 1149 return 0;1150}1151 1152static void rt722_sdca_shutdown(struct snd_pcm_substream *substream,1153 struct snd_soc_dai *dai)1154{1155 snd_soc_dai_set_dma_data(dai, substream, NULL);1156}1157 1158static int rt722_sdca_pcm_hw_params(struct snd_pcm_substream *substream,1159 struct snd_pcm_hw_params *params,1160 struct snd_soc_dai *dai)1161{1162 struct snd_soc_component *component = dai->component;1163 struct rt722_sdca_priv *rt722 = snd_soc_component_get_drvdata(component);1164 struct sdw_stream_config stream_config;1165 struct sdw_port_config port_config;1166 enum sdw_data_direction direction;1167 struct sdw_stream_runtime *sdw_stream;1168 int retval, port, num_channels;1169 unsigned int sampling_rate;1170 1171 dev_dbg(dai->dev, "%s %s", __func__, dai->name);1172 sdw_stream = snd_soc_dai_get_dma_data(dai, substream);1173 1174 if (!sdw_stream)1175 return -EINVAL;1176 1177 if (!rt722->slave)1178 return -EINVAL;1179 1180 /*1181 * RT722_AIF1 with port = 1 for headphone playback1182 * RT722_AIF1 with port = 2 for headset-mic capture1183 * RT722_AIF2 with port = 3 for speaker playback1184 * RT722_AIF3 with port = 6 for digital-mic capture1185 */1186 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {1187 direction = SDW_DATA_DIR_RX;1188 if (dai->id == RT722_AIF1)1189 port = 1;1190 else if (dai->id == RT722_AIF2)1191 port = 3;1192 else1193 return -EINVAL;1194 } else {1195 direction = SDW_DATA_DIR_TX;1196 if (dai->id == RT722_AIF1)1197 port = 2;1198 else if (dai->id == RT722_AIF3)1199 port = 6;1200 else1201 return -EINVAL;1202 }1203 stream_config.frame_rate = params_rate(params);1204 stream_config.ch_count = params_channels(params);1205 stream_config.bps = snd_pcm_format_width(params_format(params));1206 stream_config.direction = direction;1207 1208 num_channels = params_channels(params);1209 port_config.ch_mask = GENMASK(num_channels - 1, 0);1210 port_config.num = port;1211 1212 retval = sdw_stream_add_slave(rt722->slave, &stream_config,1213 &port_config, 1, sdw_stream);1214 if (retval) {1215 dev_err(dai->dev, "%s: Unable to configure port\n", __func__);1216 return retval;1217 }1218 1219 if (params_channels(params) > 16) {1220 dev_err(component->dev, "%s: Unsupported channels %d\n",1221 __func__, params_channels(params));1222 return -EINVAL;1223 }1224 1225 /* sampling rate configuration */1226 switch (params_rate(params)) {1227 case 44100:1228 sampling_rate = RT722_SDCA_RATE_44100HZ;1229 break;1230 case 48000:1231 sampling_rate = RT722_SDCA_RATE_48000HZ;1232 break;1233 case 96000:1234 sampling_rate = RT722_SDCA_RATE_96000HZ;1235 break;1236 case 192000:1237 sampling_rate = RT722_SDCA_RATE_192000HZ;1238 break;1239 default:1240 dev_err(component->dev, "%s: Rate %d is not supported\n",1241 __func__, params_rate(params));1242 return -EINVAL;1243 }1244 1245 /* set sampling frequency */1246 if (dai->id == RT722_AIF1) {1247 regmap_write(rt722->regmap,1248 SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT722_SDCA_ENT_CS01,1249 RT722_SDCA_CTL_SAMPLE_FREQ_INDEX, 0), sampling_rate);1250 regmap_write(rt722->regmap,1251 SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT722_SDCA_ENT_CS11,1252 RT722_SDCA_CTL_SAMPLE_FREQ_INDEX, 0), sampling_rate);1253 }1254 1255 if (dai->id == RT722_AIF2)1256 regmap_write(rt722->regmap,1257 SDW_SDCA_CTL(FUNC_NUM_AMP, RT722_SDCA_ENT_CS31,1258 RT722_SDCA_CTL_SAMPLE_FREQ_INDEX, 0), sampling_rate);1259 1260 if (dai->id == RT722_AIF3)1261 regmap_write(rt722->regmap,1262 SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT722_SDCA_ENT_CS1F,1263 RT722_SDCA_CTL_SAMPLE_FREQ_INDEX, 0), sampling_rate);1264 1265 return 0;1266}1267 1268static int rt722_sdca_pcm_hw_free(struct snd_pcm_substream *substream,1269 struct snd_soc_dai *dai)1270{1271 struct snd_soc_component *component = dai->component;1272 struct rt722_sdca_priv *rt722 = snd_soc_component_get_drvdata(component);1273 struct sdw_stream_runtime *sdw_stream =1274 snd_soc_dai_get_dma_data(dai, substream);1275 1276 if (!rt722->slave)1277 return -EINVAL;1278 1279 sdw_stream_remove_slave(rt722->slave, sdw_stream);1280 return 0;1281}1282 1283#define RT722_STEREO_RATES (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | \1284 SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000)1285#define RT722_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \1286 SNDRV_PCM_FMTBIT_S24_LE)1287 1288static const struct snd_soc_dai_ops rt722_sdca_ops = {1289 .hw_params = rt722_sdca_pcm_hw_params,1290 .hw_free = rt722_sdca_pcm_hw_free,1291 .set_stream = rt722_sdca_set_sdw_stream,1292 .shutdown = rt722_sdca_shutdown,1293};1294 1295static struct snd_soc_dai_driver rt722_sdca_dai[] = {1296 {1297 .name = "rt722-sdca-aif1",1298 .id = RT722_AIF1,1299 .playback = {1300 .stream_name = "DP1 Headphone Playback",1301 .channels_min = 1,1302 .channels_max = 2,1303 .rates = RT722_STEREO_RATES,1304 .formats = RT722_FORMATS,1305 },1306 .capture = {1307 .stream_name = "DP2 Headset Capture",1308 .channels_min = 1,1309 .channels_max = 2,1310 .rates = RT722_STEREO_RATES,1311 .formats = RT722_FORMATS,1312 },1313 .ops = &rt722_sdca_ops,1314 },1315 {1316 .name = "rt722-sdca-aif2",1317 .id = RT722_AIF2,1318 .playback = {1319 .stream_name = "DP3 Speaker Playback",1320 .channels_min = 1,1321 .channels_max = 2,1322 .rates = RT722_STEREO_RATES,1323 .formats = RT722_FORMATS,1324 },1325 .ops = &rt722_sdca_ops,1326 },1327 {1328 .name = "rt722-sdca-aif3",1329 .id = RT722_AIF3,1330 .capture = {1331 .stream_name = "DP6 DMic Capture",1332 .channels_min = 1,1333 .channels_max = 4,1334 .rates = RT722_STEREO_RATES,1335 .formats = RT722_FORMATS,1336 },1337 .ops = &rt722_sdca_ops,1338 }1339};1340 1341int rt722_sdca_init(struct device *dev, struct regmap *regmap,1342 struct regmap *mbq_regmap, struct sdw_slave *slave)1343{1344 struct rt722_sdca_priv *rt722;1345 1346 rt722 = devm_kzalloc(dev, sizeof(*rt722), GFP_KERNEL);1347 if (!rt722)1348 return -ENOMEM;1349 1350 dev_set_drvdata(dev, rt722);1351 rt722->slave = slave;1352 rt722->regmap = regmap;1353 rt722->mbq_regmap = mbq_regmap;1354 1355 mutex_init(&rt722->calibrate_mutex);1356 mutex_init(&rt722->disable_irq_lock);1357 1358 INIT_DELAYED_WORK(&rt722->jack_detect_work, rt722_sdca_jack_detect_handler);1359 INIT_DELAYED_WORK(&rt722->jack_btn_check_work, rt722_sdca_btn_check_handler);1360 1361 /*1362 * Mark hw_init to false1363 * HW init will be performed when device reports present1364 */1365 rt722->hw_init = false;1366 rt722->first_hw_init = false;1367 rt722->fu1e_dapm_mute = true;1368 rt722->fu0f_dapm_mute = true;1369 rt722->fu0f_mixer_l_mute = rt722->fu0f_mixer_r_mute = true;1370 rt722->fu1e_mixer_mute[0] = rt722->fu1e_mixer_mute[1] =1371 rt722->fu1e_mixer_mute[2] = rt722->fu1e_mixer_mute[3] = true;1372 1373 return devm_snd_soc_register_component(dev,1374 &soc_sdca_dev_rt722, rt722_sdca_dai, ARRAY_SIZE(rt722_sdca_dai));1375}1376 1377static void rt722_sdca_dmic_preset(struct rt722_sdca_priv *rt722)1378{1379 /* Set AD07 power entity floating control */1380 rt722_sdca_index_write(rt722, RT722_VENDOR_HDA_CTL,1381 RT722_ADC0A_08_PDE_FLOAT_CTL, 0x2a29);1382 /* Set AD10 power entity floating control */1383 rt722_sdca_index_write(rt722, RT722_VENDOR_HDA_CTL,1384 RT722_ADC10_PDE_FLOAT_CTL, 0x2a00);1385 /* Set DMIC1/DMIC2 power entity floating control */1386 rt722_sdca_index_write(rt722, RT722_VENDOR_HDA_CTL,1387 RT722_DMIC1_2_PDE_FLOAT_CTL, 0x2a2a);1388 /* Set DMIC2 IT entity floating control */1389 rt722_sdca_index_write(rt722, RT722_VENDOR_HDA_CTL,1390 RT722_DMIC_ENT_FLOAT_CTL, 0x2626);1391 /* Set AD10 FU entity floating control */1392 rt722_sdca_index_write(rt722, RT722_VENDOR_HDA_CTL,1393 RT722_ADC_ENT_FLOAT_CTL, 0x1e00);1394 /* Set DMIC2 FU entity floating control */1395 rt722_sdca_index_write(rt722, RT722_VENDOR_HDA_CTL,1396 RT722_DMIC_GAIN_ENT_FLOAT_CTL0, 0x1515);1397 /* Set AD10 FU channel floating control */1398 rt722_sdca_index_write(rt722, RT722_VENDOR_HDA_CTL,1399 RT722_ADC_VOL_CH_FLOAT_CTL, 0x0304);1400 /* Set DMIC2 FU channel floating control */1401 rt722_sdca_index_write(rt722, RT722_VENDOR_HDA_CTL,1402 RT722_DMIC_GAIN_ENT_FLOAT_CTL2, 0x0304);1403 /* vf71f_r12_07_06 and vf71f_r13_07_06 = 2’b00 */1404 rt722_sdca_index_write(rt722, RT722_VENDOR_HDA_CTL,1405 RT722_HDA_LEGACY_CONFIG_CTL0, 0x0000);1406 /* Enable vf707_r12_05/vf707_r13_05 */1407 regmap_write(rt722->regmap,1408 SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT722_SDCA_ENT_IT26,1409 RT722_SDCA_CTL_VENDOR_DEF, 0), 0x01);1410 /* Fine tune PDE2A latency */1411 regmap_write(rt722->regmap, 0x2f5c, 0x25);1412}1413 1414static void rt722_sdca_amp_preset(struct rt722_sdca_priv *rt722)1415{1416 /* Set DVQ=01 */1417 rt722_sdca_index_write(rt722, RT722_VENDOR_REG, RT722_CLSD_CTRL6,1418 0xc215);1419 /* Reset dc_cal_top */1420 rt722_sdca_index_write(rt722, RT722_VENDOR_CALI, RT722_DC_CALIB_CTRL,1421 0x702c);1422 /* W1C Trigger Calibration */1423 rt722_sdca_index_write(rt722, RT722_VENDOR_CALI, RT722_DC_CALIB_CTRL,1424 0xf02d);1425 /* Set DAC02/ClassD power entity floating control */1426 rt722_sdca_index_write(rt722, RT722_VENDOR_HDA_CTL, RT722_AMP_PDE_FLOAT_CTL,1427 0x2323);1428 /* Set EAPD high */1429 rt722_sdca_index_write(rt722, RT722_VENDOR_HDA_CTL, RT722_EAPD_CTL,1430 0x0002);1431 /* Enable vf707_r14 */1432 regmap_write(rt722->regmap,1433 SDW_SDCA_CTL(FUNC_NUM_AMP, RT722_SDCA_ENT_OT23,1434 RT722_SDCA_CTL_VENDOR_DEF, CH_08), 0x04);1435}1436 1437static void rt722_sdca_jack_preset(struct rt722_sdca_priv *rt722)1438{1439 int loop_check, chk_cnt = 100, ret;1440 unsigned int calib_status = 0;1441 1442 /* Config analog bias */1443 rt722_sdca_index_write(rt722, RT722_VENDOR_REG, RT722_ANALOG_BIAS_CTL3,1444 0xa081);1445 /* GE related settings */1446 rt722_sdca_index_write(rt722, RT722_VENDOR_HDA_CTL, RT722_GE_RELATED_CTL2,1447 0xa009);1448 /* Button A, B, C, D bypass mode */1449 rt722_sdca_index_write(rt722, RT722_VENDOR_HDA_CTL, RT722_UMP_HID_CTL4,1450 0xcf00);1451 /* HID1 slot enable */1452 rt722_sdca_index_write(rt722, RT722_VENDOR_HDA_CTL, RT722_UMP_HID_CTL5,1453 0x000f);1454 /* Report ID for HID1 */1455 rt722_sdca_index_write(rt722, RT722_VENDOR_HDA_CTL, RT722_UMP_HID_CTL0,1456 0x1100);1457 /* OSC/OOC for slot 2, 3 */1458 rt722_sdca_index_write(rt722, RT722_VENDOR_HDA_CTL, RT722_UMP_HID_CTL7,1459 0x0c12);1460 /* Set JD de-bounce clock control */1461 rt722_sdca_index_write(rt722, RT722_VENDOR_REG, RT722_JD_CTRL1,1462 0x7002);1463 /* Set DVQ=01 */1464 rt722_sdca_index_write(rt722, RT722_VENDOR_REG, RT722_CLSD_CTRL6,1465 0xc215);1466 /* FSM switch to calibration manual mode */1467 rt722_sdca_index_write(rt722, RT722_VENDOR_REG, RT722_FSM_CTL,1468 0x4100);1469 /* W1C Trigger DC calibration (HP) */1470 rt722_sdca_index_write(rt722, RT722_VENDOR_CALI, RT722_DAC_DC_CALI_CTL3,1471 0x008d);1472 /* check HP calibration FSM status */1473 for (loop_check = 0; loop_check < chk_cnt; loop_check++) {1474 ret = rt722_sdca_index_read(rt722, RT722_VENDOR_CALI,1475 RT722_DAC_DC_CALI_CTL3, &calib_status);1476 if (ret < 0 || loop_check == chk_cnt)1477 dev_dbg(&rt722->slave->dev, "calibration failed!, ret=%d\n", ret);1478 if ((calib_status & 0x0040) == 0x0)1479 break;1480 }1481 /* Set ADC09 power entity floating control */1482 rt722_sdca_index_write(rt722, RT722_VENDOR_HDA_CTL, RT722_ADC0A_08_PDE_FLOAT_CTL,1483 0x2a12);1484 /* Set MIC2 and LINE1 power entity floating control */1485 rt722_sdca_index_write(rt722, RT722_VENDOR_HDA_CTL, RT722_MIC2_LINE2_PDE_FLOAT_CTL,1486 0x3429);1487 /* Set ET41h and LINE2 power entity floating control */1488 rt722_sdca_index_write(rt722, RT722_VENDOR_HDA_CTL, RT722_ET41_LINE2_PDE_FLOAT_CTL,1489 0x4112);1490 /* Set DAC03 and HP power entity floating control */1491 rt722_sdca_index_write(rt722, RT722_VENDOR_HDA_CTL, RT722_DAC03_HP_PDE_FLOAT_CTL,1492 0x4040);1493 rt722_sdca_index_write(rt722, RT722_VENDOR_HDA_CTL, RT722_ENT_FLOAT_CTRL_1,1494 0x4141);1495 rt722_sdca_index_write(rt722, RT722_VENDOR_HDA_CTL, RT722_FLOAT_CTRL_1,1496 0x0101);1497 /* Fine tune PDE40 latency */1498 regmap_write(rt722->regmap, 0x2f58, 0x07);1499 regmap_write(rt722->regmap, 0x2f03, 0x06);1500 /* MIC VRefo */1501 rt722_sdca_index_update_bits(rt722, RT722_VENDOR_REG,1502 RT722_COMBO_JACK_AUTO_CTL1, 0x0200, 0x0200);1503 rt722_sdca_index_update_bits(rt722, RT722_VENDOR_REG,1504 RT722_VREFO_GAT, 0x4000, 0x4000);1505 /* Release HP-JD, EN_CBJ_TIE_GL/R open, en_osw gating auto done bit */1506 rt722_sdca_index_write(rt722, RT722_VENDOR_REG, RT722_DIGITAL_MISC_CTRL4,1507 0x0010);1508}1509 1510int rt722_sdca_io_init(struct device *dev, struct sdw_slave *slave)1511{1512 struct rt722_sdca_priv *rt722 = dev_get_drvdata(dev);1513 1514 rt722->disable_irq = false;1515 1516 if (rt722->hw_init)1517 return 0;1518 1519 if (rt722->first_hw_init) {1520 regcache_cache_only(rt722->regmap, false);1521 regcache_cache_bypass(rt722->regmap, true);1522 regcache_cache_only(rt722->mbq_regmap, false);1523 regcache_cache_bypass(rt722->mbq_regmap, true);1524 } else {1525 /*1526 * PM runtime is only enabled when a Slave reports as Attached1527 */1528 1529 /* set autosuspend parameters */1530 pm_runtime_set_autosuspend_delay(&slave->dev, 3000);1531 pm_runtime_use_autosuspend(&slave->dev);1532 1533 /* update count of parent 'active' children */1534 pm_runtime_set_active(&slave->dev);1535 1536 /* make sure the device does not suspend immediately */1537 pm_runtime_mark_last_busy(&slave->dev);1538 1539 pm_runtime_enable(&slave->dev);1540 }1541 1542 pm_runtime_get_noresume(&slave->dev);1543 1544 rt722_sdca_dmic_preset(rt722);1545 rt722_sdca_amp_preset(rt722);1546 rt722_sdca_jack_preset(rt722);1547 1548 if (rt722->first_hw_init) {1549 regcache_cache_bypass(rt722->regmap, false);1550 regcache_mark_dirty(rt722->regmap);1551 regcache_cache_bypass(rt722->mbq_regmap, false);1552 regcache_mark_dirty(rt722->mbq_regmap);1553 } else1554 rt722->first_hw_init = true;1555 1556 /* Mark Slave initialization complete */1557 rt722->hw_init = true;1558 1559 pm_runtime_mark_last_busy(&slave->dev);1560 pm_runtime_put_autosuspend(&slave->dev);1561 1562 dev_dbg(&slave->dev, "%s hw_init complete\n", __func__);1563 return 0;1564}1565 1566MODULE_DESCRIPTION("ASoC RT722 SDCA SDW driver");1567MODULE_AUTHOR("Jack Yu <jack.yu@realtek.com>");1568MODULE_LICENSE("GPL");1569