brintos

brintos / linux-shallow public Read only

0
0
Text · 46.2 KiB · e5bd9ef Raw
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, &regvalue);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, &regvalue[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