brintos

brintos / linux-shallow public Read only

0
0
Text · 32.6 KiB · 299c9b1 Raw
1150 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * rt715.c -- rt715 ALSA SoC audio driver4 *5 * Copyright(c) 2019 Realtek Semiconductor Corp.6 *7 * ALC715 ASoC Codec Driver based Intel Dummy SdW codec driver8 *9 */10 11#include <linux/module.h>12#include <linux/kernel.h>13#include <linux/init.h>14#include <linux/delay.h>15#include <linux/i2c.h>16#include <linux/pm_runtime.h>17#include <linux/pm.h>18#include <linux/soundwire/sdw.h>19#include <linux/regmap.h>20#include <linux/slab.h>21#include <linux/platform_device.h>22#include <linux/regulator/consumer.h>23#include <sound/core.h>24#include <sound/pcm.h>25#include <sound/pcm_params.h>26#include <sound/sdw.h>27#include <sound/soc.h>28#include <sound/soc-dapm.h>29#include <sound/initval.h>30#include <sound/tlv.h>31#include <sound/hda_verbs.h>32 33#include "rt715.h"34 35static int rt715_index_write(struct regmap *regmap, unsigned int reg,36		unsigned int value)37{38	int ret;39	unsigned int addr = ((RT715_PRIV_INDEX_W_H) << 8) | reg;40 41	ret = regmap_write(regmap, addr, value);42	if (ret < 0) {43		pr_err("%s: Failed to set private value: %08x <= %04x %d\n",44		       __func__, addr, value, ret);45	}46 47	return ret;48}49 50static int rt715_index_write_nid(struct regmap *regmap,51		unsigned int nid, unsigned int reg, unsigned int value)52{53	int ret;54	unsigned int addr = ((RT715_PRIV_INDEX_W_H_2 | nid) << 8) | reg;55 56	ret = regmap_write(regmap, addr, value);57	if (ret < 0)58		pr_err("%s: Failed to set private value: %06x <= %04x ret=%d\n",59		       __func__, addr, value, ret);60 61	return ret;62}63 64static int rt715_index_read_nid(struct regmap *regmap,65		unsigned int nid, unsigned int reg, unsigned int *value)66{67	int ret;68	unsigned int addr = ((RT715_PRIV_INDEX_W_H_2 | nid) << 8) | reg;69 70	*value = 0;71	ret = regmap_read(regmap, addr, value);72	if (ret < 0)73		pr_err("%s: Failed to get private value: %06x => %04x ret=%d\n",74		       __func__, addr, *value, ret);75 76	return ret;77}78 79static int rt715_index_update_bits(struct regmap *regmap, unsigned int nid,80			unsigned int reg, unsigned int mask, unsigned int val)81{82	unsigned int tmp, orig;83	int ret;84 85	ret = rt715_index_read_nid(regmap, nid, reg, &orig);86	if (ret < 0)87		return ret;88 89	tmp = orig & ~mask;90	tmp |= val & mask;91 92	return rt715_index_write_nid(regmap, nid, reg, tmp);93}94 95static void rt715_reset(struct regmap *regmap)96{97	regmap_write(regmap, RT715_FUNC_RESET, 0);98	rt715_index_update_bits(regmap, RT715_VENDOR_REGISTERS,99		RT715_VD_CLEAR_CTRL, RT715_CLEAR_HIDDEN_REG,100		RT715_CLEAR_HIDDEN_REG);101}102 103 104static void rt715_get_gain(struct rt715_priv *rt715, unsigned int addr_h,105				unsigned int addr_l, unsigned int val_h,106				unsigned int *r_val, unsigned int *l_val)107{108	int ret;109	/* R Channel */110	*r_val = val_h << 8;111	ret = regmap_read(rt715->regmap, addr_l, r_val);112	if (ret < 0)113		pr_err("Failed to get R channel gain.\n");114 115	/* L Channel */116	val_h |= 0x20;117	*l_val = val_h << 8;118	ret = regmap_read(rt715->regmap, addr_h, l_val);119	if (ret < 0)120		pr_err("Failed to get L channel gain.\n");121}122 123/* For Verb-Set Amplifier Gain (Verb ID = 3h) */124static int rt715_set_amp_gain_put(struct snd_kcontrol *kcontrol,125					struct snd_ctl_elem_value *ucontrol)126{127	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);128	struct snd_soc_dapm_context *dapm =129		snd_soc_component_get_dapm(component);130	struct soc_mixer_control *mc =131		(struct soc_mixer_control *)kcontrol->private_value;132	struct rt715_priv *rt715 = snd_soc_component_get_drvdata(component);133	unsigned int addr_h, addr_l, val_h, val_ll, val_lr;134	unsigned int read_ll, read_rl, i;135	unsigned int k_vol_changed = 0;136 137	for (i = 0; i < 2; i++) {138		if (ucontrol->value.integer.value[i] != rt715->kctl_2ch_vol_ori[i]) {139			k_vol_changed = 1;140			break;141		}142	}143 144	/* Can't use update bit function, so read the original value first */145	addr_h = mc->reg;146	addr_l = mc->rreg;147 148	if (mc->shift == RT715_DIR_OUT_SFT) /* output */149		val_h = 0x80;150	else /* input */151		val_h = 0x0;152 153	rt715_get_gain(rt715, addr_h, addr_l, val_h, &read_rl, &read_ll);154 155	if (dapm->bias_level <= SND_SOC_BIAS_STANDBY)156		regmap_write(rt715->regmap,157				RT715_SET_AUDIO_POWER_STATE, AC_PWRST_D0);158 159	/* L Channel */160	rt715->kctl_2ch_vol_ori[0] = ucontrol->value.integer.value[0];161	/* for gain */162	val_ll = ((ucontrol->value.integer.value[0]) & 0x7f);163	if (val_ll > mc->max)164		val_ll = mc->max;165	/* keep mute status */166	val_ll |= read_ll & 0x80;167 168	/* R Channel */169	rt715->kctl_2ch_vol_ori[1] = ucontrol->value.integer.value[1];170	/* for gain */171	val_lr = ((ucontrol->value.integer.value[1]) & 0x7f);172	if (val_lr > mc->max)173		val_lr = mc->max;174	/* keep mute status */175	val_lr |= read_rl & 0x80;176 177	for (i = 0; i < 3; i++) { /* retry 3 times at most */178 179		if (val_ll == val_lr) {180			/* Set both L/R channels at the same time */181			val_h = (1 << mc->shift) | (3 << 4);182			regmap_write(rt715->regmap, addr_h,183				(val_h << 8) | val_ll);184			regmap_write(rt715->regmap, addr_l,185				(val_h << 8) | val_ll);186		} else {187			/* Lch*/188			val_h = (1 << mc->shift) | (1 << 5);189			regmap_write(rt715->regmap, addr_h,190				(val_h << 8) | val_ll);191			/* Rch */192			val_h = (1 << mc->shift) | (1 << 4);193			regmap_write(rt715->regmap, addr_l,194				(val_h << 8) | val_lr);195		}196		/* check result */197		if (mc->shift == RT715_DIR_OUT_SFT) /* output */198			val_h = 0x80;199		else /* input */200			val_h = 0x0;201 202		rt715_get_gain(rt715, addr_h, addr_l, val_h,203				&read_rl, &read_ll);204		if (read_rl == val_lr && read_ll == val_ll)205			break;206	}207 208	/* D0:power on state, D3: power saving mode */209	if (dapm->bias_level <= SND_SOC_BIAS_STANDBY)210		regmap_write(rt715->regmap,211				RT715_SET_AUDIO_POWER_STATE, AC_PWRST_D3);212	return k_vol_changed;213}214 215static int rt715_set_amp_gain_get(struct snd_kcontrol *kcontrol,216				  struct snd_ctl_elem_value *ucontrol)217{218	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);219	struct rt715_priv *rt715 = snd_soc_component_get_drvdata(component);220	struct soc_mixer_control *mc =221		(struct soc_mixer_control *)kcontrol->private_value;222	unsigned int addr_h, addr_l, val_h;223	unsigned int read_ll, read_rl;224 225	addr_h = mc->reg;226	addr_l = mc->rreg;227	if (mc->shift == RT715_DIR_OUT_SFT) /* output */228		val_h = 0x80;229	else /* input */230		val_h = 0x0;231 232	rt715_get_gain(rt715, addr_h, addr_l, val_h, &read_rl, &read_ll);233 234	if (mc->invert) {235		/* for mute status */236		read_ll = !(read_ll & 0x80);237		read_rl = !(read_rl & 0x80);238	} else {239		/* for gain */240		read_ll = read_ll & 0x7f;241		read_rl = read_rl & 0x7f;242	}243	ucontrol->value.integer.value[0] = read_ll;244	ucontrol->value.integer.value[1] = read_rl;245 246	return 0;247}248 249static int rt715_set_main_switch_put(struct snd_kcontrol *kcontrol,250					struct snd_ctl_elem_value *ucontrol)251{252	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);253	struct snd_soc_dapm_context *dapm =254		snd_soc_component_get_dapm(component);255	struct rt715_priv *rt715 = snd_soc_component_get_drvdata(component);256	static const unsigned int capture_reg_H[] = {257		RT715_SET_GAIN_MIC_ADC_H, RT715_SET_GAIN_LINE_ADC_H,258		RT715_SET_GAIN_MIX_ADC_H, RT715_SET_GAIN_MIX_ADC2_H };259	static const unsigned int capture_reg_L[] = {260		RT715_SET_GAIN_MIC_ADC_L, RT715_SET_GAIN_LINE_ADC_L,261		RT715_SET_GAIN_MIX_ADC_L, RT715_SET_GAIN_MIX_ADC2_L };262	unsigned int addr_h, addr_l, val_h = 0x0, val_ll, val_lr;263	unsigned int k_shift = RT715_DIR_IN_SFT, k_changed = 0;264	unsigned int read_ll, read_rl, i, j, loop_cnt = 4;265 266	for (i = 0; i < 8; i++) {267		if (ucontrol->value.integer.value[i] != rt715->kctl_8ch_switch_ori[i])268			k_changed = 1;269	}270 271	for (j = 0; j < loop_cnt; j++) {272		/* Can't use update bit function, so read the original value first */273		addr_h = capture_reg_H[j];274		addr_l = capture_reg_L[j];275		rt715_get_gain(rt715, addr_h, addr_l, val_h, &read_rl, &read_ll);276 277		if (dapm->bias_level <= SND_SOC_BIAS_STANDBY)278			regmap_write(rt715->regmap,279					RT715_SET_AUDIO_POWER_STATE, AC_PWRST_D0);280 281		/* L Channel */282		/* for mute */283		rt715->kctl_8ch_switch_ori[j * 2] =284			ucontrol->value.integer.value[j * 2];285		val_ll = (!ucontrol->value.integer.value[j * 2]) << 7;286		/* keep gain */287		val_ll |= read_ll & 0x7f;288 289		/* R Channel */290		/* for mute */291		rt715->kctl_8ch_switch_ori[j * 2 + 1] =292			ucontrol->value.integer.value[j * 2 + 1];293		val_lr = (!ucontrol->value.integer.value[j * 2 + 1]) << 7;294		/* keep gain */295		val_lr |= read_rl & 0x7f;296 297		for (i = 0; i < 3; i++) { /* retry 3 times at most */298 299			if (val_ll == val_lr) {300				/* Set both L/R channels at the same time */301				val_h = (1 << k_shift) | (3 << 4);302				regmap_write(rt715->regmap, addr_h,303					(val_h << 8) | val_ll);304				regmap_write(rt715->regmap, addr_l,305					(val_h << 8) | val_ll);306			} else {307				/* Lch*/308				val_h = (1 << k_shift) | (1 << 5);309				regmap_write(rt715->regmap, addr_h,310					(val_h << 8) | val_ll);311				/* Rch */312				val_h = (1 << k_shift) | (1 << 4);313				regmap_write(rt715->regmap, addr_l,314					(val_h << 8) | val_lr);315			}316			val_h = 0x0;317			rt715_get_gain(rt715, addr_h, addr_l, val_h,318					&read_rl, &read_ll);319			if (read_rl == val_lr && read_ll == val_ll)320				break;321		}322	}323 324	/* D0:power on state, D3: power saving mode */325	if (dapm->bias_level <= SND_SOC_BIAS_STANDBY)326		regmap_write(rt715->regmap,327				RT715_SET_AUDIO_POWER_STATE, AC_PWRST_D3);328	return k_changed;329}330 331static int rt715_set_main_switch_get(struct snd_kcontrol *kcontrol,332				  struct snd_ctl_elem_value *ucontrol)333{334	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);335	struct rt715_priv *rt715 = snd_soc_component_get_drvdata(component);336	static const unsigned int capture_reg_H[] = {337		RT715_SET_GAIN_MIC_ADC_H, RT715_SET_GAIN_LINE_ADC_H,338		RT715_SET_GAIN_MIX_ADC_H, RT715_SET_GAIN_MIX_ADC2_H };339	static const unsigned int capture_reg_L[] = {340		RT715_SET_GAIN_MIC_ADC_L, RT715_SET_GAIN_LINE_ADC_L,341		RT715_SET_GAIN_MIX_ADC_L, RT715_SET_GAIN_MIX_ADC2_L };342	unsigned int addr_h, addr_l, val_h = 0x0, i, loop_cnt = 4;343	unsigned int read_ll, read_rl;344 345	for (i = 0; i < loop_cnt; i++) {346		addr_h = capture_reg_H[i];347		addr_l = capture_reg_L[i];348		rt715_get_gain(rt715, addr_h, addr_l, val_h, &read_rl, &read_ll);349 350		ucontrol->value.integer.value[i * 2] = !(read_ll & 0x80);351		ucontrol->value.integer.value[i * 2 + 1] = !(read_rl & 0x80);352	}353 354	return 0;355}356 357static int rt715_set_main_vol_put(struct snd_kcontrol *kcontrol,358					struct snd_ctl_elem_value *ucontrol)359{360	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);361	struct snd_soc_dapm_context *dapm =362		snd_soc_component_get_dapm(component);363	struct rt715_priv *rt715 = snd_soc_component_get_drvdata(component);364	static const unsigned int capture_reg_H[] = {365		RT715_SET_GAIN_MIC_ADC_H, RT715_SET_GAIN_LINE_ADC_H,366		RT715_SET_GAIN_MIX_ADC_H, RT715_SET_GAIN_MIX_ADC2_H };367	static const unsigned int capture_reg_L[] = {368		RT715_SET_GAIN_MIC_ADC_L, RT715_SET_GAIN_LINE_ADC_L,369		RT715_SET_GAIN_MIX_ADC_L, RT715_SET_GAIN_MIX_ADC2_L};370	unsigned int addr_h, addr_l, val_h = 0x0, val_ll, val_lr;371	unsigned int read_ll, read_rl, i, j, loop_cnt = 4, k_changed = 0;372	unsigned int k_shift = RT715_DIR_IN_SFT, k_max = 0x3f;373 374	for (i = 0; i < 8; i++) {375		if (ucontrol->value.integer.value[i] != rt715->kctl_8ch_vol_ori[i])376			k_changed = 1;377	}378 379	for (j = 0; j < loop_cnt; j++) {380		addr_h = capture_reg_H[j];381		addr_l = capture_reg_L[j];382		rt715_get_gain(rt715, addr_h, addr_l, val_h, &read_rl, &read_ll);383 384		if (dapm->bias_level <= SND_SOC_BIAS_STANDBY)385			regmap_write(rt715->regmap,386					RT715_SET_AUDIO_POWER_STATE, AC_PWRST_D0);387 388		/* L Channel */389		/* for gain */390		rt715->kctl_8ch_vol_ori[j * 2] = ucontrol->value.integer.value[j * 2];391		val_ll = ((ucontrol->value.integer.value[j * 2]) & 0x7f);392		if (val_ll > k_max)393			val_ll = k_max;394		/* keep mute status */395		val_ll |= read_ll & 0x80;396 397		/* R Channel */398		/* for gain */399		rt715->kctl_8ch_vol_ori[j * 2 + 1] =400			ucontrol->value.integer.value[j * 2 + 1];401		val_lr = ((ucontrol->value.integer.value[j * 2 + 1]) & 0x7f);402		if (val_lr > k_max)403			val_lr = k_max;404		/* keep mute status */405		val_lr |= read_rl & 0x80;406 407		for (i = 0; i < 3; i++) { /* retry 3 times at most */408			if (val_ll == val_lr) {409				/* Set both L/R channels at the same time */410				val_h = (1 << k_shift) | (3 << 4);411				regmap_write(rt715->regmap, addr_h,412					(val_h << 8) | val_ll);413				regmap_write(rt715->regmap, addr_l,414					(val_h << 8) | val_ll);415			} else {416				/* Lch*/417				val_h = (1 << k_shift) | (1 << 5);418				regmap_write(rt715->regmap, addr_h,419					(val_h << 8) | val_ll);420				/* Rch */421				val_h = (1 << k_shift) | (1 << 4);422				regmap_write(rt715->regmap, addr_l,423					(val_h << 8) | val_lr);424			}425			val_h = 0x0;426			rt715_get_gain(rt715, addr_h, addr_l, val_h,427					&read_rl, &read_ll);428			if (read_rl == val_lr && read_ll == val_ll)429				break;430		}431	}432 433	/* D0:power on state, D3: power saving mode */434	if (dapm->bias_level <= SND_SOC_BIAS_STANDBY)435		regmap_write(rt715->regmap,436				RT715_SET_AUDIO_POWER_STATE, AC_PWRST_D3);437	return k_changed;438}439 440static int rt715_set_main_vol_get(struct snd_kcontrol *kcontrol,441				  struct snd_ctl_elem_value *ucontrol)442{443	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);444	struct rt715_priv *rt715 = snd_soc_component_get_drvdata(component);445	static const unsigned int capture_reg_H[] = {446		RT715_SET_GAIN_MIC_ADC_H, RT715_SET_GAIN_LINE_ADC_H,447		RT715_SET_GAIN_MIX_ADC_H, RT715_SET_GAIN_MIX_ADC2_H };448	static const unsigned int capture_reg_L[] = {449		RT715_SET_GAIN_MIC_ADC_L, RT715_SET_GAIN_LINE_ADC_L,450		RT715_SET_GAIN_MIX_ADC_L, RT715_SET_GAIN_MIX_ADC2_L };451	unsigned int addr_h, addr_l, val_h = 0x0, i, loop_cnt = 4;452	unsigned int read_ll, read_rl;453 454	for (i = 0; i < loop_cnt; i++) {455		addr_h = capture_reg_H[i];456		addr_l = capture_reg_L[i];457		rt715_get_gain(rt715, addr_h, addr_l, val_h, &read_rl, &read_ll);458 459		ucontrol->value.integer.value[i * 2] = read_ll & 0x7f;460		ucontrol->value.integer.value[i * 2 + 1] = read_rl & 0x7f;461	}462 463	return 0;464}465 466static const DECLARE_TLV_DB_SCALE(in_vol_tlv, -1725, 75, 0);467static const DECLARE_TLV_DB_SCALE(mic_vol_tlv, 0, 1000, 0);468 469static int rt715_switch_info(struct snd_kcontrol *kcontrol,470	struct snd_ctl_elem_info *uinfo)471{472	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;473	uinfo->count = 8;474	uinfo->value.integer.min = 0;475	uinfo->value.integer.max = 1;476	return 0;477}478 479static int rt715_vol_info(struct snd_kcontrol *kcontrol,480	struct snd_ctl_elem_info *uinfo)481{482	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;483	uinfo->count = 8;484	uinfo->value.integer.min = 0;485	uinfo->value.integer.max = 0x3f;486	return 0;487}488 489#define SOC_DOUBLE_R_EXT(xname, reg_left, reg_right, xshift, xmax, xinvert,\490	 xhandler_get, xhandler_put) \491{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \492	.info = snd_soc_info_volsw, \493	.get = xhandler_get, .put = xhandler_put, \494	.private_value = SOC_DOUBLE_R_VALUE(reg_left, reg_right, xshift, \495					    xmax, xinvert) }496 497#define RT715_MAIN_SWITCH_EXT(xname, xhandler_get, xhandler_put) \498{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \499	.info = rt715_switch_info, \500	.get = xhandler_get, .put = xhandler_put, \501}502 503#define RT715_MAIN_VOL_EXT_TLV(xname, xhandler_get, xhandler_put, tlv_array) \504{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \505	.access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \506		 SNDRV_CTL_ELEM_ACCESS_READWRITE, \507	.tlv.p = (tlv_array), \508	.info = rt715_vol_info, \509	.get = xhandler_get, .put = xhandler_put, \510}511 512static const struct snd_kcontrol_new rt715_snd_controls[] = {513	/* Capture switch */514	RT715_MAIN_SWITCH_EXT("Capture Switch",515			rt715_set_main_switch_get, rt715_set_main_switch_put),516	/* Volume Control */517	RT715_MAIN_VOL_EXT_TLV("Capture Volume",518			rt715_set_main_vol_get, rt715_set_main_vol_put, in_vol_tlv),519	/* MIC Boost Control */520	SOC_DOUBLE_R_EXT_TLV("DMIC1 Boost", RT715_SET_GAIN_DMIC1_H,521			RT715_SET_GAIN_DMIC1_L, RT715_DIR_IN_SFT, 3, 0,522			rt715_set_amp_gain_get, rt715_set_amp_gain_put,523			mic_vol_tlv),524	SOC_DOUBLE_R_EXT_TLV("DMIC2 Boost", RT715_SET_GAIN_DMIC2_H,525			RT715_SET_GAIN_DMIC2_L, RT715_DIR_IN_SFT, 3, 0,526			rt715_set_amp_gain_get, rt715_set_amp_gain_put,527			mic_vol_tlv),528	SOC_DOUBLE_R_EXT_TLV("DMIC3 Boost", RT715_SET_GAIN_DMIC3_H,529			RT715_SET_GAIN_DMIC3_L, RT715_DIR_IN_SFT, 3, 0,530			rt715_set_amp_gain_get, rt715_set_amp_gain_put,531			mic_vol_tlv),532	SOC_DOUBLE_R_EXT_TLV("DMIC4 Boost", RT715_SET_GAIN_DMIC4_H,533			RT715_SET_GAIN_DMIC4_L, RT715_DIR_IN_SFT, 3, 0,534			rt715_set_amp_gain_get, rt715_set_amp_gain_put,535			mic_vol_tlv),536	SOC_DOUBLE_R_EXT_TLV("MIC1 Boost", RT715_SET_GAIN_MIC1_H,537			RT715_SET_GAIN_MIC1_L, RT715_DIR_IN_SFT, 3, 0,538			rt715_set_amp_gain_get, rt715_set_amp_gain_put,539			mic_vol_tlv),540	SOC_DOUBLE_R_EXT_TLV("MIC2 Boost", RT715_SET_GAIN_MIC2_H,541			RT715_SET_GAIN_MIC2_L, RT715_DIR_IN_SFT, 3, 0,542			rt715_set_amp_gain_get, rt715_set_amp_gain_put,543			mic_vol_tlv),544	SOC_DOUBLE_R_EXT_TLV("LINE1 Boost", RT715_SET_GAIN_LINE1_H,545			RT715_SET_GAIN_LINE1_L, RT715_DIR_IN_SFT, 3, 0,546			rt715_set_amp_gain_get, rt715_set_amp_gain_put,547			mic_vol_tlv),548	SOC_DOUBLE_R_EXT_TLV("LINE2 Boost", RT715_SET_GAIN_LINE2_H,549			RT715_SET_GAIN_LINE2_L, RT715_DIR_IN_SFT, 3, 0,550			rt715_set_amp_gain_get, rt715_set_amp_gain_put,551			mic_vol_tlv),552};553 554static int rt715_mux_get(struct snd_kcontrol *kcontrol,555			struct snd_ctl_elem_value *ucontrol)556{557	struct snd_soc_component *component =558		snd_soc_dapm_kcontrol_component(kcontrol);559	struct rt715_priv *rt715 = snd_soc_component_get_drvdata(component);560	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;561	unsigned int reg, val;562	int ret;563 564	/* nid = e->reg, vid = 0xf01 */565	reg = RT715_VERB_SET_CONNECT_SEL | e->reg;566	ret = regmap_read(rt715->regmap, reg, &val);567	if (ret < 0) {568		dev_err(component->dev, "%s: sdw read failed: %d\n",569			__func__, ret);570		return ret;571	}572 573	/*574	 * The first two indices of ADC Mux 24/25 are routed to the same575	 * hardware source. ie, ADC Mux 24 0/1 will both connect to MIC2.576	 * To have a unique set of inputs, we skip the index1 of the muxes.577	 */578	if ((e->reg == RT715_MUX_IN3 || e->reg == RT715_MUX_IN4) && (val > 0))579		val -= 1;580	ucontrol->value.enumerated.item[0] = val;581 582	return 0;583}584 585static int rt715_mux_put(struct snd_kcontrol *kcontrol,586			struct snd_ctl_elem_value *ucontrol)587{588	struct snd_soc_component *component =589		snd_soc_dapm_kcontrol_component(kcontrol);590	struct snd_soc_dapm_context *dapm =591				snd_soc_dapm_kcontrol_dapm(kcontrol);592	struct rt715_priv *rt715 = snd_soc_component_get_drvdata(component);593	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;594	unsigned int *item = ucontrol->value.enumerated.item;595	unsigned int val, val2 = 0, change, reg;596	int ret;597 598	if (item[0] >= e->items)599		return -EINVAL;600 601	/* Verb ID = 0x701h, nid = e->reg */602	val = snd_soc_enum_item_to_val(e, item[0]) << e->shift_l;603 604	reg = RT715_VERB_SET_CONNECT_SEL | e->reg;605	ret = regmap_read(rt715->regmap, reg, &val2);606	if (ret < 0) {607		dev_err(component->dev, "%s: sdw read failed: %d\n",608			__func__, ret);609		return ret;610	}611 612	if (val == val2)613		change = 0;614	else615		change = 1;616 617	if (change) {618		reg = RT715_VERB_SET_CONNECT_SEL | e->reg;619		regmap_write(rt715->regmap, reg, val);620	}621 622	snd_soc_dapm_mux_update_power(dapm, kcontrol,623						item[0], e, NULL);624 625	return change;626}627 628static const char * const adc_22_23_mux_text[] = {629	"MIC1",630	"MIC2",631	"LINE1",632	"LINE2",633	"DMIC1",634	"DMIC2",635	"DMIC3",636	"DMIC4",637};638 639/*640 * Due to mux design for nid 24 (MUX_IN3)/25 (MUX_IN4), connection index 0 and641 * 1 will be connected to the same dmic source, therefore we skip index 1 to642 * avoid misunderstanding on usage of dapm routing.643 */644static const unsigned int rt715_adc_24_25_values[] = {645	0,646	2,647	3,648	4,649	5,650};651 652static const char * const adc_24_mux_text[] = {653	"MIC2",654	"DMIC1",655	"DMIC2",656	"DMIC3",657	"DMIC4",658};659 660static const char * const adc_25_mux_text[] = {661	"MIC1",662	"DMIC1",663	"DMIC2",664	"DMIC3",665	"DMIC4",666};667 668static SOC_ENUM_SINGLE_DECL(669	rt715_adc22_enum, RT715_MUX_IN1, 0, adc_22_23_mux_text);670 671static SOC_ENUM_SINGLE_DECL(672	rt715_adc23_enum, RT715_MUX_IN2, 0, adc_22_23_mux_text);673 674static SOC_VALUE_ENUM_SINGLE_DECL(rt715_adc24_enum,675	RT715_MUX_IN3, 0, 0xf,676	adc_24_mux_text, rt715_adc_24_25_values);677 678static SOC_VALUE_ENUM_SINGLE_DECL(rt715_adc25_enum,679	RT715_MUX_IN4, 0, 0xf,680	adc_25_mux_text, rt715_adc_24_25_values);681 682static const struct snd_kcontrol_new rt715_adc22_mux =683	SOC_DAPM_ENUM_EXT("ADC 22 Mux", rt715_adc22_enum,684			rt715_mux_get, rt715_mux_put);685 686static const struct snd_kcontrol_new rt715_adc23_mux =687	SOC_DAPM_ENUM_EXT("ADC 23 Mux", rt715_adc23_enum,688			rt715_mux_get, rt715_mux_put);689 690static const struct snd_kcontrol_new rt715_adc24_mux =691	SOC_DAPM_ENUM_EXT("ADC 24 Mux", rt715_adc24_enum,692			rt715_mux_get, rt715_mux_put);693 694static const struct snd_kcontrol_new rt715_adc25_mux =695	SOC_DAPM_ENUM_EXT("ADC 25 Mux", rt715_adc25_enum,696			rt715_mux_get, rt715_mux_put);697 698static const struct snd_soc_dapm_widget rt715_dapm_widgets[] = {699	SND_SOC_DAPM_INPUT("DMIC1"),700	SND_SOC_DAPM_INPUT("DMIC2"),701	SND_SOC_DAPM_INPUT("DMIC3"),702	SND_SOC_DAPM_INPUT("DMIC4"),703	SND_SOC_DAPM_INPUT("MIC1"),704	SND_SOC_DAPM_INPUT("MIC2"),705	SND_SOC_DAPM_INPUT("LINE1"),706	SND_SOC_DAPM_INPUT("LINE2"),707	SND_SOC_DAPM_ADC("ADC 07", NULL, RT715_SET_STREAMID_MIC_ADC, 4, 0),708	SND_SOC_DAPM_ADC("ADC 08", NULL, RT715_SET_STREAMID_LINE_ADC, 4, 0),709	SND_SOC_DAPM_ADC("ADC 09", NULL, RT715_SET_STREAMID_MIX_ADC, 4, 0),710	SND_SOC_DAPM_ADC("ADC 27", NULL, RT715_SET_STREAMID_MIX_ADC2, 4, 0),711	SND_SOC_DAPM_MUX("ADC 22 Mux", SND_SOC_NOPM, 0, 0,712		&rt715_adc22_mux),713	SND_SOC_DAPM_MUX("ADC 23 Mux", SND_SOC_NOPM, 0, 0,714		&rt715_adc23_mux),715	SND_SOC_DAPM_MUX("ADC 24 Mux", SND_SOC_NOPM, 0, 0,716		&rt715_adc24_mux),717	SND_SOC_DAPM_MUX("ADC 25 Mux", SND_SOC_NOPM, 0, 0,718		&rt715_adc25_mux),719	SND_SOC_DAPM_AIF_OUT("DP4TX", "DP4 Capture", 0, SND_SOC_NOPM, 0, 0),720	SND_SOC_DAPM_AIF_OUT("DP6TX", "DP6 Capture", 0, SND_SOC_NOPM, 0, 0),721};722 723static const struct snd_soc_dapm_route rt715_audio_map[] = {724	{"DP6TX", NULL, "ADC 09"},725	{"DP6TX", NULL, "ADC 08"},726	{"DP4TX", NULL, "ADC 07"},727	{"DP4TX", NULL, "ADC 27"},728	{"ADC 09", NULL, "ADC 22 Mux"},729	{"ADC 08", NULL, "ADC 23 Mux"},730	{"ADC 07", NULL, "ADC 24 Mux"},731	{"ADC 27", NULL, "ADC 25 Mux"},732	{"ADC 22 Mux", "MIC1", "MIC1"},733	{"ADC 22 Mux", "MIC2", "MIC2"},734	{"ADC 22 Mux", "LINE1", "LINE1"},735	{"ADC 22 Mux", "LINE2", "LINE2"},736	{"ADC 22 Mux", "DMIC1", "DMIC1"},737	{"ADC 22 Mux", "DMIC2", "DMIC2"},738	{"ADC 22 Mux", "DMIC3", "DMIC3"},739	{"ADC 22 Mux", "DMIC4", "DMIC4"},740	{"ADC 23 Mux", "MIC1", "MIC1"},741	{"ADC 23 Mux", "MIC2", "MIC2"},742	{"ADC 23 Mux", "LINE1", "LINE1"},743	{"ADC 23 Mux", "LINE2", "LINE2"},744	{"ADC 23 Mux", "DMIC1", "DMIC1"},745	{"ADC 23 Mux", "DMIC2", "DMIC2"},746	{"ADC 23 Mux", "DMIC3", "DMIC3"},747	{"ADC 23 Mux", "DMIC4", "DMIC4"},748	{"ADC 24 Mux", "MIC2", "MIC2"},749	{"ADC 24 Mux", "DMIC1", "DMIC1"},750	{"ADC 24 Mux", "DMIC2", "DMIC2"},751	{"ADC 24 Mux", "DMIC3", "DMIC3"},752	{"ADC 24 Mux", "DMIC4", "DMIC4"},753	{"ADC 25 Mux", "MIC1", "MIC1"},754	{"ADC 25 Mux", "DMIC1", "DMIC1"},755	{"ADC 25 Mux", "DMIC2", "DMIC2"},756	{"ADC 25 Mux", "DMIC3", "DMIC3"},757	{"ADC 25 Mux", "DMIC4", "DMIC4"},758};759 760static int rt715_set_bias_level(struct snd_soc_component *component,761				enum snd_soc_bias_level level)762{763	struct snd_soc_dapm_context *dapm =764		snd_soc_component_get_dapm(component);765	struct rt715_priv *rt715 = snd_soc_component_get_drvdata(component);766 767	switch (level) {768	case SND_SOC_BIAS_PREPARE:769		if (dapm->bias_level == SND_SOC_BIAS_STANDBY) {770			regmap_write(rt715->regmap,771						RT715_SET_AUDIO_POWER_STATE,772						AC_PWRST_D0);773			msleep(RT715_POWER_UP_DELAY_MS);774		}775		break;776 777	case SND_SOC_BIAS_STANDBY:778		regmap_write(rt715->regmap,779					RT715_SET_AUDIO_POWER_STATE,780					AC_PWRST_D3);781		break;782 783	default:784		break;785	}786	dapm->bias_level = level;787	return 0;788}789 790static int rt715_probe(struct snd_soc_component *component)791{792	struct rt715_priv *rt715 = snd_soc_component_get_drvdata(component);793	int ret;794 795	if (!rt715->first_hw_init)796		return 0;797 798	ret = pm_runtime_resume(component->dev);799	if (ret < 0 && ret != -EACCES)800		return ret;801 802	return 0;803}804 805static const struct snd_soc_component_driver soc_codec_dev_rt715 = {806	.probe = rt715_probe,807	.set_bias_level = rt715_set_bias_level,808	.controls = rt715_snd_controls,809	.num_controls = ARRAY_SIZE(rt715_snd_controls),810	.dapm_widgets = rt715_dapm_widgets,811	.num_dapm_widgets = ARRAY_SIZE(rt715_dapm_widgets),812	.dapm_routes = rt715_audio_map,813	.num_dapm_routes = ARRAY_SIZE(rt715_audio_map),814	.endianness = 1,815};816 817static int rt715_set_sdw_stream(struct snd_soc_dai *dai, void *sdw_stream,818				int direction)819{820 821	snd_soc_dai_dma_data_set(dai, direction, sdw_stream);822 823	return 0;824}825 826static void rt715_shutdown(struct snd_pcm_substream *substream,827				struct snd_soc_dai *dai)828 829{830	snd_soc_dai_set_dma_data(dai, substream, NULL);831}832 833static int rt715_pcm_hw_params(struct snd_pcm_substream *substream,834				struct snd_pcm_hw_params *params,835				struct snd_soc_dai *dai)836{837	struct snd_soc_component *component = dai->component;838	struct rt715_priv *rt715 = snd_soc_component_get_drvdata(component);839	struct sdw_stream_config stream_config = {0};840	struct sdw_port_config port_config = {0};841	struct sdw_stream_runtime *sdw_stream;842	int retval;843	unsigned int val = 0;844 845	sdw_stream = snd_soc_dai_get_dma_data(dai, substream);846 847	if (!sdw_stream)848		return -EINVAL;849 850	if (!rt715->slave)851		return -EINVAL;852 853	snd_sdw_params_to_config(substream, params, &stream_config, &port_config);854 855	switch (dai->id) {856	case RT715_AIF1:857		port_config.num = 6;858		rt715_index_write(rt715->regmap, RT715_SDW_INPUT_SEL, 0xa500);859		break;860	case RT715_AIF2:861		port_config.num = 4;862		rt715_index_write(rt715->regmap, RT715_SDW_INPUT_SEL, 0xa000);863		break;864	default:865		dev_err(component->dev, "%s: Invalid DAI id %d\n", __func__, dai->id);866		return -EINVAL;867	}868 869	retval = sdw_stream_add_slave(rt715->slave, &stream_config,870					&port_config, 1, sdw_stream);871	if (retval) {872		dev_err(dai->dev, "%s: Unable to configure port\n", __func__);873		return retval;874	}875 876	switch (params_rate(params)) {877	/* bit 14 0:48K 1:44.1K */878	/* bit 15 Stream Type 0:PCM 1:Non-PCM, should always be PCM */879	case 44100:880		val |= 0x40 << 8;881		break;882	case 48000:883		val |= 0x0 << 8;884		break;885	default:886		dev_err(component->dev, "%s: Unsupported sample rate %d\n",887			__func__, params_rate(params));888		return -EINVAL;889	}890 891	if (params_channels(params) <= 16) {892		/* bit 3:0 Number of Channel */893		val |= (params_channels(params) - 1);894	} else {895		dev_err(component->dev, "%s: Unsupported channels %d\n",896			__func__, params_channels(params));897		return -EINVAL;898	}899 900	switch (params_width(params)) {901	/* bit 6:4 Bits per Sample */902	case 8:903		break;904	case 16:905		val |= (0x1 << 4);906		break;907	case 20:908		val |= (0x2 << 4);909		break;910	case 24:911		val |= (0x3 << 4);912		break;913	case 32:914		val |= (0x4 << 4);915		break;916	default:917		return -EINVAL;918	}919 920	regmap_write(rt715->regmap, RT715_MIC_ADC_FORMAT_H, val);921	regmap_write(rt715->regmap, RT715_MIC_LINE_FORMAT_H, val);922	regmap_write(rt715->regmap, RT715_MIX_ADC_FORMAT_H, val);923	regmap_write(rt715->regmap, RT715_MIX_ADC2_FORMAT_H, val);924 925	return retval;926}927 928static int rt715_pcm_hw_free(struct snd_pcm_substream *substream,929				struct snd_soc_dai *dai)930{931	struct snd_soc_component *component = dai->component;932	struct rt715_priv *rt715 = snd_soc_component_get_drvdata(component);933	struct sdw_stream_runtime *sdw_stream =934		snd_soc_dai_get_dma_data(dai, substream);935 936	if (!rt715->slave)937		return -EINVAL;938 939	sdw_stream_remove_slave(rt715->slave, sdw_stream);940	return 0;941}942 943#define RT715_STEREO_RATES (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000)944#define RT715_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \945			SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S8)946 947static const struct snd_soc_dai_ops rt715_ops = {948	.hw_params	= rt715_pcm_hw_params,949	.hw_free	= rt715_pcm_hw_free,950	.set_stream	= rt715_set_sdw_stream,951	.shutdown	= rt715_shutdown,952};953 954static struct snd_soc_dai_driver rt715_dai[] = {955	{956		.name = "rt715-aif1",957		.id = RT715_AIF1,958		.capture = {959			.stream_name = "DP6 Capture",960			.channels_min = 1,961			.channels_max = 2,962			.rates = RT715_STEREO_RATES,963			.formats = RT715_FORMATS,964		},965		.ops = &rt715_ops,966	},967	{968		.name = "rt715-aif2",969		.id = RT715_AIF2,970		.capture = {971			.stream_name = "DP4 Capture",972			.channels_min = 1,973			.channels_max = 2,974			.rates = RT715_STEREO_RATES,975			.formats = RT715_FORMATS,976		},977		.ops = &rt715_ops,978	},979};980 981/* Bus clock frequency */982#define RT715_CLK_FREQ_9600000HZ 9600000983#define RT715_CLK_FREQ_12000000HZ 12000000984#define RT715_CLK_FREQ_6000000HZ 6000000985#define RT715_CLK_FREQ_4800000HZ 4800000986#define RT715_CLK_FREQ_2400000HZ 2400000987#define RT715_CLK_FREQ_12288000HZ 12288000988 989int rt715_clock_config(struct device *dev)990{991	struct rt715_priv *rt715 = dev_get_drvdata(dev);992	unsigned int clk_freq, value;993 994	clk_freq = (rt715->params.curr_dr_freq >> 1);995 996	switch (clk_freq) {997	case RT715_CLK_FREQ_12000000HZ:998		value = 0x0;999		break;1000	case RT715_CLK_FREQ_6000000HZ:1001		value = 0x1;1002		break;1003	case RT715_CLK_FREQ_9600000HZ:1004		value = 0x2;1005		break;1006	case RT715_CLK_FREQ_4800000HZ:1007		value = 0x3;1008		break;1009	case RT715_CLK_FREQ_2400000HZ:1010		value = 0x4;1011		break;1012	case RT715_CLK_FREQ_12288000HZ:1013		value = 0x5;1014		break;1015	default:1016		return -EINVAL;1017	}1018 1019	regmap_write(rt715->regmap, 0xe0, value);1020	regmap_write(rt715->regmap, 0xf0, value);1021 1022	return 0;1023}1024 1025int rt715_init(struct device *dev, struct regmap *sdw_regmap,1026	struct regmap *regmap, struct sdw_slave *slave)1027{1028	struct rt715_priv *rt715;1029	int ret;1030 1031	rt715 = devm_kzalloc(dev, sizeof(*rt715), GFP_KERNEL);1032	if (!rt715)1033		return -ENOMEM;1034 1035	dev_set_drvdata(dev, rt715);1036	rt715->slave = slave;1037	rt715->regmap = regmap;1038	rt715->sdw_regmap = sdw_regmap;1039 1040	regcache_cache_only(rt715->regmap, true);1041 1042	/*1043	 * Mark hw_init to false1044	 * HW init will be performed when device reports present1045	 */1046	rt715->hw_init = false;1047	rt715->first_hw_init = false;1048 1049	ret = devm_snd_soc_register_component(dev,1050						&soc_codec_dev_rt715,1051						rt715_dai,1052						ARRAY_SIZE(rt715_dai));1053	if (ret < 0)1054		return ret;1055 1056	/* set autosuspend parameters */1057	pm_runtime_set_autosuspend_delay(dev, 3000);1058	pm_runtime_use_autosuspend(dev);1059 1060	/* make sure the device does not suspend immediately */1061	pm_runtime_mark_last_busy(dev);1062 1063	pm_runtime_enable(dev);1064 1065	/* important note: the device is NOT tagged as 'active' and will remain1066	 * 'suspended' until the hardware is enumerated/initialized. This is required1067	 * to make sure the ASoC framework use of pm_runtime_get_sync() does not silently1068	 * fail with -EACCESS because of race conditions between card creation and enumeration1069	 */1070 1071	return 0;1072}1073 1074int rt715_io_init(struct device *dev, struct sdw_slave *slave)1075{1076	struct rt715_priv *rt715 = dev_get_drvdata(dev);1077 1078	if (rt715->hw_init)1079		return 0;1080 1081	regcache_cache_only(rt715->regmap, false);1082 1083	/*1084	 *  PM runtime status is marked as 'active' only when a Slave reports as Attached1085	 */1086	if (!rt715->first_hw_init)1087		/* update count of parent 'active' children */1088		pm_runtime_set_active(&slave->dev);1089 1090	pm_runtime_get_noresume(&slave->dev);1091 1092	rt715_reset(rt715->regmap);1093 1094	/* Mute nid=08h/09h */1095	regmap_write(rt715->regmap, RT715_SET_GAIN_LINE_ADC_H, 0xb080);1096	regmap_write(rt715->regmap, RT715_SET_GAIN_MIX_ADC_H, 0xb080);1097	/* Mute nid=07h/27h */1098	regmap_write(rt715->regmap, RT715_SET_GAIN_MIC_ADC_H, 0xb080);1099	regmap_write(rt715->regmap, RT715_SET_GAIN_MIX_ADC2_H, 0xb080);1100 1101	/* Set Pin Widget */1102	regmap_write(rt715->regmap, RT715_SET_PIN_DMIC1, 0x20);1103	regmap_write(rt715->regmap, RT715_SET_PIN_DMIC2, 0x20);1104	regmap_write(rt715->regmap, RT715_SET_PIN_DMIC3, 0x20);1105	regmap_write(rt715->regmap, RT715_SET_PIN_DMIC4, 0x20);1106	/* Set Converter Stream */1107	regmap_write(rt715->regmap, RT715_SET_STREAMID_LINE_ADC, 0x10);1108	regmap_write(rt715->regmap, RT715_SET_STREAMID_MIX_ADC, 0x10);1109	regmap_write(rt715->regmap, RT715_SET_STREAMID_MIC_ADC, 0x10);1110	regmap_write(rt715->regmap, RT715_SET_STREAMID_MIX_ADC2, 0x10);1111	/* Set Configuration Default */1112	regmap_write(rt715->regmap, RT715_SET_DMIC1_CONFIG_DEFAULT1, 0xd0);1113	regmap_write(rt715->regmap, RT715_SET_DMIC1_CONFIG_DEFAULT2, 0x11);1114	regmap_write(rt715->regmap, RT715_SET_DMIC1_CONFIG_DEFAULT3, 0xa1);1115	regmap_write(rt715->regmap, RT715_SET_DMIC1_CONFIG_DEFAULT4, 0x81);1116	regmap_write(rt715->regmap, RT715_SET_DMIC2_CONFIG_DEFAULT1, 0xd1);1117	regmap_write(rt715->regmap, RT715_SET_DMIC2_CONFIG_DEFAULT2, 0x11);1118	regmap_write(rt715->regmap, RT715_SET_DMIC2_CONFIG_DEFAULT3, 0xa1);1119	regmap_write(rt715->regmap, RT715_SET_DMIC2_CONFIG_DEFAULT4, 0x81);1120	regmap_write(rt715->regmap, RT715_SET_DMIC3_CONFIG_DEFAULT1, 0xd0);1121	regmap_write(rt715->regmap, RT715_SET_DMIC3_CONFIG_DEFAULT2, 0x11);1122	regmap_write(rt715->regmap, RT715_SET_DMIC3_CONFIG_DEFAULT3, 0xa1);1123	regmap_write(rt715->regmap, RT715_SET_DMIC3_CONFIG_DEFAULT4, 0x81);1124	regmap_write(rt715->regmap, RT715_SET_DMIC4_CONFIG_DEFAULT1, 0xd1);1125	regmap_write(rt715->regmap, RT715_SET_DMIC4_CONFIG_DEFAULT2, 0x11);1126	regmap_write(rt715->regmap, RT715_SET_DMIC4_CONFIG_DEFAULT3, 0xa1);1127	regmap_write(rt715->regmap, RT715_SET_DMIC4_CONFIG_DEFAULT4, 0x81);1128 1129	/* Finish Initial Settings, set power to D3 */1130	regmap_write(rt715->regmap, RT715_SET_AUDIO_POWER_STATE, AC_PWRST_D3);1131 1132	if (rt715->first_hw_init)1133		regcache_mark_dirty(rt715->regmap);1134	else1135		rt715->first_hw_init = true;1136 1137	/* Mark Slave initialization complete */1138	rt715->hw_init = true;1139 1140	pm_runtime_mark_last_busy(&slave->dev);1141	pm_runtime_put_autosuspend(&slave->dev);1142 1143	return 0;1144}1145 1146MODULE_DESCRIPTION("ASoC rt715 driver");1147MODULE_DESCRIPTION("ASoC rt715 driver SDW");1148MODULE_AUTHOR("Jack Yu <jack.yu@realtek.com>");1149MODULE_LICENSE("GPL v2");1150