brintos

brintos / linux-shallow public Read only

0
0
Text · 29.6 KiB · 7e10fd9 Raw
1085 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2//3// rt715-sdca.c -- rt715 ALSA SoC audio driver4//5// Copyright(c) 2020 Realtek Semiconductor Corp.6//7//8//9 10#include <linux/module.h>11#include <linux/moduleparam.h>12#include <linux/kernel.h>13#include <linux/init.h>14#include <linux/pm_runtime.h>15#include <linux/pm.h>16#include <linux/soundwire/sdw.h>17#include <linux/regmap.h>18#include <linux/slab.h>19#include <linux/platform_device.h>20#include <sound/core.h>21#include <sound/pcm.h>22#include <sound/pcm_params.h>23#include <sound/sdw.h>24#include <sound/soc.h>25#include <sound/soc-dapm.h>26#include <sound/initval.h>27#include <sound/tlv.h>28#include <linux/soundwire/sdw_registers.h>29 30#include "rt715-sdca.h"31 32static int rt715_sdca_index_write(struct rt715_sdca_priv *rt715,33		unsigned int nid, unsigned int reg, unsigned int value)34{35	struct regmap *regmap = rt715->mbq_regmap;36	unsigned int addr;37	int ret;38 39	addr = (nid << 20) | reg;40 41	ret = regmap_write(regmap, addr, value);42	if (ret < 0)43		dev_err(&rt715->slave->dev,44			"%s: Failed to set private value: %08x <= %04x %d\n",45			__func__, addr, value, ret);46 47	return ret;48}49 50static int rt715_sdca_index_read(struct rt715_sdca_priv *rt715,51		unsigned int nid, unsigned int reg, unsigned int *value)52{53	struct regmap *regmap = rt715->mbq_regmap;54	unsigned int addr;55	int ret;56 57	addr = (nid << 20) | reg;58 59	ret = regmap_read(regmap, addr, value);60	if (ret < 0)61		dev_err(&rt715->slave->dev,62			"%s: Failed to get private value: %06x => %04x ret=%d\n",63			__func__, addr, *value, ret);64 65	return ret;66}67 68static int rt715_sdca_index_update_bits(struct rt715_sdca_priv *rt715,69	unsigned int nid, unsigned int reg, unsigned int mask, unsigned int val)70{71	unsigned int tmp;72	int ret;73 74	ret = rt715_sdca_index_read(rt715, nid, reg, &tmp);75	if (ret < 0)76		return ret;77 78	set_mask_bits(&tmp, mask, val);79 80	return rt715_sdca_index_write(rt715, nid, reg, tmp);81}82 83static inline unsigned int rt715_sdca_vol_gain(unsigned int u_ctrl_val,84		unsigned int vol_max, unsigned int vol_gain_sft)85{86	unsigned int val;87 88	if (u_ctrl_val > vol_max)89		u_ctrl_val = vol_max;90	val = u_ctrl_val;91	u_ctrl_val =92		((abs(u_ctrl_val - vol_gain_sft) * RT715_SDCA_DB_STEP) << 8) / 1000;93	if (val <= vol_gain_sft) {94		u_ctrl_val = ~u_ctrl_val;95		u_ctrl_val += 1;96	}97	u_ctrl_val &= 0xffff;98 99	return u_ctrl_val;100}101 102static inline unsigned int rt715_sdca_boost_gain(unsigned int u_ctrl_val,103		unsigned int b_max, unsigned int b_gain_sft)104{105	if (u_ctrl_val > b_max)106		u_ctrl_val = b_max;107 108	return (u_ctrl_val * 10) << b_gain_sft;109}110 111static inline unsigned int rt715_sdca_get_gain(unsigned int reg_val,112		unsigned int gain_sft)113{114	unsigned int neg_flag = 0;115 116	if (reg_val & BIT(15)) {117		reg_val = ~(reg_val - 1) & 0xffff;118		neg_flag = 1;119	}120	reg_val *= 1000;121	reg_val >>= 8;122	if (neg_flag)123		reg_val = gain_sft - reg_val / RT715_SDCA_DB_STEP;124	else125		reg_val = gain_sft + reg_val / RT715_SDCA_DB_STEP;126 127	return reg_val;128}129 130/* SDCA Volume/Boost control */131static int rt715_sdca_set_amp_gain_put(struct snd_kcontrol *kcontrol,132		struct snd_ctl_elem_value *ucontrol)133{134	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);135	struct soc_mixer_control *mc =136		(struct soc_mixer_control *)kcontrol->private_value;137	struct rt715_sdca_priv *rt715 = snd_soc_component_get_drvdata(component);138	unsigned int gain_val, i, k_changed = 0;139	int ret;140 141	for (i = 0; i < 2; i++) {142		if (ucontrol->value.integer.value[i] != rt715->kctl_2ch_orig[i]) {143			k_changed = 1;144			break;145		}146	}147 148	for (i = 0; i < 2; i++) {149		rt715->kctl_2ch_orig[i] = ucontrol->value.integer.value[i];150		gain_val =151			rt715_sdca_vol_gain(ucontrol->value.integer.value[i], mc->max,152				mc->shift);153		ret = regmap_write(rt715->mbq_regmap, mc->reg + i, gain_val);154		if (ret != 0) {155			dev_err(component->dev, "%s: Failed to write 0x%x=0x%x\n",156				__func__, mc->reg + i, gain_val);157			return ret;158		}159	}160 161	return k_changed;162}163 164static int rt715_sdca_set_amp_gain_4ch_put(struct snd_kcontrol *kcontrol,165		struct snd_ctl_elem_value *ucontrol)166{167	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);168	struct rt715_sdca_priv *rt715 = snd_soc_component_get_drvdata(component);169	struct rt715_sdca_kcontrol_private *p =170		(struct rt715_sdca_kcontrol_private *)kcontrol->private_value;171	unsigned int reg_base = p->reg_base, k_changed = 0;172	const unsigned int gain_sft = 0x2f;173	unsigned int gain_val, i;174	int ret;175 176	for (i = 0; i < 4; i++) {177		if (ucontrol->value.integer.value[i] != rt715->kctl_4ch_orig[i]) {178			k_changed = 1;179			break;180		}181	}182 183	for (i = 0; i < 4; i++) {184		rt715->kctl_4ch_orig[i] = ucontrol->value.integer.value[i];185		gain_val =186			rt715_sdca_vol_gain(ucontrol->value.integer.value[i], p->max,187				gain_sft);188		ret = regmap_write(rt715->mbq_regmap, reg_base + i,189				gain_val);190		if (ret != 0) {191			dev_err(component->dev, "%s: Failed to write 0x%x=0x%x\n",192				__func__, reg_base + i, gain_val);193			return ret;194		}195	}196 197	return k_changed;198}199 200static int rt715_sdca_set_amp_gain_8ch_put(struct snd_kcontrol *kcontrol,201		struct snd_ctl_elem_value *ucontrol)202{203	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);204	struct rt715_sdca_priv *rt715 = snd_soc_component_get_drvdata(component);205	struct rt715_sdca_kcontrol_private *p =206		(struct rt715_sdca_kcontrol_private *)kcontrol->private_value;207	unsigned int reg_base = p->reg_base, i, k_changed = 0;208	const unsigned int gain_sft = 8;209	unsigned int gain_val, reg;210	int ret;211 212	for (i = 0; i < 8; i++) {213		if (ucontrol->value.integer.value[i] != rt715->kctl_8ch_orig[i]) {214			k_changed = 1;215			break;216		}217	}218 219	for (i = 0; i < 8; i++) {220		rt715->kctl_8ch_orig[i] = ucontrol->value.integer.value[i];221		gain_val =222			rt715_sdca_boost_gain(ucontrol->value.integer.value[i], p->max,223				gain_sft);224		reg = i < 7 ? reg_base + i : (reg_base - 1) | BIT(15);225		ret = regmap_write(rt715->mbq_regmap, reg, gain_val);226		if (ret != 0) {227			dev_err(component->dev, "%s: Failed to write 0x%x=0x%x\n",228				__func__, reg, gain_val);229			return ret;230		}231	}232 233	return k_changed;234}235 236static int rt715_sdca_set_amp_gain_get(struct snd_kcontrol *kcontrol,237		struct snd_ctl_elem_value *ucontrol)238{239	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);240	struct soc_mixer_control *mc =241		(struct soc_mixer_control *)kcontrol->private_value;242	struct rt715_sdca_priv *rt715 = snd_soc_component_get_drvdata(component);243	unsigned int val, i;244	int ret;245 246	for (i = 0; i < 2; i++) {247		ret = regmap_read(rt715->mbq_regmap, mc->reg + i, &val);248		if (ret < 0) {249			dev_err(component->dev, "%s: Failed to read 0x%x, ret=%d\n",250				__func__, mc->reg + i, ret);251			return ret;252		}253		ucontrol->value.integer.value[i] = rt715_sdca_get_gain(val, mc->shift);254	}255 256	return 0;257}258 259static int rt715_sdca_set_amp_gain_4ch_get(struct snd_kcontrol *kcontrol,260		struct snd_ctl_elem_value *ucontrol)261{262	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);263	struct rt715_sdca_priv *rt715 = snd_soc_component_get_drvdata(component);264	struct rt715_sdca_kcontrol_private *p =265		(struct rt715_sdca_kcontrol_private *)kcontrol->private_value;266	unsigned int reg_base = p->reg_base, i;267	const unsigned int gain_sft = 0x2f;268	unsigned int val;269	int ret;270 271	for (i = 0; i < 4; i++) {272		ret = regmap_read(rt715->mbq_regmap, reg_base + i, &val);273		if (ret < 0) {274			dev_err(component->dev, "%s: Failed to read 0x%x, ret=%d\n",275				__func__, reg_base + i, ret);276			return ret;277		}278		ucontrol->value.integer.value[i] = rt715_sdca_get_gain(val, gain_sft);279	}280 281	return 0;282}283 284static int rt715_sdca_set_amp_gain_8ch_get(struct snd_kcontrol *kcontrol,285		struct snd_ctl_elem_value *ucontrol)286{287	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);288	struct rt715_sdca_priv *rt715 = snd_soc_component_get_drvdata(component);289	struct rt715_sdca_kcontrol_private *p =290		(struct rt715_sdca_kcontrol_private *)kcontrol->private_value;291	unsigned int reg_base = p->reg_base;292	const unsigned int gain_sft = 8;293	unsigned int val_l, val_r;294	unsigned int i, reg;295	int ret;296 297	for (i = 0; i < 8; i += 2) {298		ret = regmap_read(rt715->mbq_regmap, reg_base + i, &val_l);299		if (ret < 0) {300			dev_err(component->dev, "%s: Failed to read 0x%x, ret=%d\n",301				__func__, reg_base + i, ret);302			return ret;303		}304		ucontrol->value.integer.value[i] = (val_l >> gain_sft) / 10;305 306		reg = (i == 6) ? (reg_base - 1) | BIT(15) : reg_base + 1 + i;307		ret = regmap_read(rt715->mbq_regmap, reg, &val_r);308		if (ret < 0) {309			dev_err(component->dev, "%s: Failed to read 0x%x, ret=%d\n",310				__func__, reg, ret);311			return ret;312		}313		ucontrol->value.integer.value[i + 1] = (val_r >> gain_sft) / 10;314	}315 316	return 0;317}318 319static const DECLARE_TLV_DB_SCALE(in_vol_tlv, -1725, 75, 0);320static const DECLARE_TLV_DB_SCALE(mic_vol_tlv, 0, 1000, 0);321 322static int rt715_sdca_get_volsw(struct snd_kcontrol *kcontrol,323	struct snd_ctl_elem_value *ucontrol)324{325	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);326	struct rt715_sdca_kcontrol_private *p =327		(struct rt715_sdca_kcontrol_private *)kcontrol->private_value;328	unsigned int reg_base = p->reg_base;329	unsigned int invert = p->invert, i;330	int val;331 332	for (i = 0; i < p->count; i += 2) {333		val = snd_soc_component_read(component, reg_base + i);334		if (val < 0)335			return -EINVAL;336		ucontrol->value.integer.value[i] = invert ? p->max - val : val;337 338		val = snd_soc_component_read(component, reg_base + 1 + i);339		if (val < 0)340			return -EINVAL;341		ucontrol->value.integer.value[i + 1] =342			invert ? p->max - val : val;343	}344 345	return 0;346}347 348static int rt715_sdca_put_volsw(struct snd_kcontrol *kcontrol,349	struct snd_ctl_elem_value *ucontrol)350{351	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);352	struct rt715_sdca_priv *rt715 = snd_soc_component_get_drvdata(component);353	struct rt715_sdca_kcontrol_private *p =354		(struct rt715_sdca_kcontrol_private *)kcontrol->private_value;355	unsigned int val[4] = {0}, val_mask, i, k_changed = 0;356	unsigned int reg = p->reg_base;357	unsigned int shift = p->shift;358	unsigned int max = p->max;359	unsigned int mask = (1 << fls(max)) - 1;360	unsigned int invert = p->invert;361	int err;362 363	for (i = 0; i < 4; i++) {364		if (ucontrol->value.integer.value[i] != rt715->kctl_switch_orig[i]) {365			k_changed = 1;366			break;367		}368	}369 370	for (i = 0; i < 2; i++) {371		rt715->kctl_switch_orig[i * 2] = ucontrol->value.integer.value[i * 2];372		val[i * 2] = ucontrol->value.integer.value[i * 2] & mask;373		if (invert)374			val[i * 2] = max - val[i * 2];375		val_mask = mask << shift;376		val[i * 2] <<= shift;377 378		rt715->kctl_switch_orig[i * 2 + 1] =379			ucontrol->value.integer.value[i * 2 + 1];380		val[i * 2 + 1] =381			ucontrol->value.integer.value[i * 2 + 1] & mask;382		if (invert)383			val[i * 2 + 1] = max - val[i * 2 + 1];384 385		val[i * 2 + 1] <<=  shift;386 387		err = snd_soc_component_update_bits(component, reg + i * 2, val_mask,388				val[i * 2]);389		if (err < 0)390			return err;391 392		err = snd_soc_component_update_bits(component, reg + 1 + i * 2,393			val_mask, val[i * 2 + 1]);394		if (err < 0)395			return err;396	}397 398	return k_changed;399}400 401static int rt715_sdca_fu_info(struct snd_kcontrol *kcontrol,402	struct snd_ctl_elem_info *uinfo)403{404	struct rt715_sdca_kcontrol_private *p =405		(struct rt715_sdca_kcontrol_private *)kcontrol->private_value;406 407	if (p->max == 1)408		uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;409	else410		uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;411	uinfo->count = p->count;412	uinfo->value.integer.min = 0;413	uinfo->value.integer.max = p->max;414	return 0;415}416 417#define RT715_SDCA_PR_VALUE(xreg_base, xcount, xmax, xshift, xinvert) \418	((unsigned long)&(struct rt715_sdca_kcontrol_private) \419		{.reg_base = xreg_base, .count = xcount, .max = xmax, \420		.shift = xshift, .invert = xinvert})421 422#define RT715_SDCA_FU_CTRL(xname, reg_base, xshift, xmax, xinvert, xcount) \423{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \424	.info = rt715_sdca_fu_info, \425	.get = rt715_sdca_get_volsw, \426	.put = rt715_sdca_put_volsw, \427	.private_value = RT715_SDCA_PR_VALUE(reg_base, xcount, xmax, \428					xshift, xinvert)}429 430#define SOC_DOUBLE_R_EXT(xname, reg_left, reg_right, xshift, xmax, xinvert,\431	 xhandler_get, xhandler_put) \432{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \433	.info = snd_soc_info_volsw, \434	.get = xhandler_get, .put = xhandler_put, \435	.private_value = SOC_DOUBLE_R_VALUE(reg_left, reg_right, xshift, \436					    xmax, xinvert) }437 438#define RT715_SDCA_EXT_TLV(xname, reg_base, xhandler_get,\439	 xhandler_put, tlv_array, xcount, xmax) \440{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \441	.access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \442		 SNDRV_CTL_ELEM_ACCESS_READWRITE, \443	.tlv.p = (tlv_array), \444	.info = rt715_sdca_fu_info, \445	.get = xhandler_get, .put = xhandler_put, \446	.private_value = RT715_SDCA_PR_VALUE(reg_base, xcount, xmax, 0, 0) }447 448#define RT715_SDCA_BOOST_EXT_TLV(xname, reg_base, xhandler_get,\449	 xhandler_put, tlv_array, xcount, xmax) \450{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \451	.access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \452		 SNDRV_CTL_ELEM_ACCESS_READWRITE, \453	.tlv.p = (tlv_array), \454	.info = rt715_sdca_fu_info, \455	.get = xhandler_get, .put = xhandler_put, \456	.private_value = RT715_SDCA_PR_VALUE(reg_base, xcount, xmax, 0, 0) }457 458static const struct snd_kcontrol_new rt715_sdca_snd_controls[] = {459	/* Capture switch */460	SOC_DOUBLE_R("FU0A Capture Switch",461		SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_ADC7_27_VOL,462			RT715_SDCA_FU_MUTE_CTRL, CH_01),463		SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_ADC7_27_VOL,464			RT715_SDCA_FU_MUTE_CTRL, CH_02),465			0, 1, 1),466	RT715_SDCA_FU_CTRL("FU02 Capture Switch",467		SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_ADC8_9_VOL,468			RT715_SDCA_FU_MUTE_CTRL, CH_01),469			0, 1, 1, 4),470	RT715_SDCA_FU_CTRL("FU06 Capture Switch",471		SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_ADC10_11_VOL,472			RT715_SDCA_FU_MUTE_CTRL, CH_01),473			0, 1, 1, 4),474	/* Volume Control */475	SOC_DOUBLE_R_EXT_TLV("FU0A Capture Volume",476		SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_ADC7_27_VOL,477			RT715_SDCA_FU_VOL_CTRL, CH_01),478		SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_ADC7_27_VOL,479			RT715_SDCA_FU_VOL_CTRL, CH_02),480			0x2f, 0x3f, 0,481		rt715_sdca_set_amp_gain_get, rt715_sdca_set_amp_gain_put,482		in_vol_tlv),483	RT715_SDCA_EXT_TLV("FU02 Capture Volume",484		SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_ADC8_9_VOL,485			RT715_SDCA_FU_VOL_CTRL, CH_01),486		rt715_sdca_set_amp_gain_4ch_get,487		rt715_sdca_set_amp_gain_4ch_put,488		in_vol_tlv, 4, 0x3f),489	RT715_SDCA_EXT_TLV("FU06 Capture Volume",490		SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_ADC10_11_VOL,491			RT715_SDCA_FU_VOL_CTRL, CH_01),492		rt715_sdca_set_amp_gain_4ch_get,493		rt715_sdca_set_amp_gain_4ch_put,494		in_vol_tlv, 4, 0x3f),495	/* MIC Boost Control */496	RT715_SDCA_BOOST_EXT_TLV("FU0E Boost",497		SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_DMIC_GAIN_EN,498			RT715_SDCA_FU_DMIC_GAIN_CTRL, CH_01),499			rt715_sdca_set_amp_gain_8ch_get,500			rt715_sdca_set_amp_gain_8ch_put,501			mic_vol_tlv, 8, 3),502	RT715_SDCA_BOOST_EXT_TLV("FU0C Boost",503		SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_AMIC_GAIN_EN,504			RT715_SDCA_FU_DMIC_GAIN_CTRL, CH_01),505			rt715_sdca_set_amp_gain_8ch_get,506			rt715_sdca_set_amp_gain_8ch_put,507			mic_vol_tlv, 8, 3),508};509 510static int rt715_sdca_mux_get(struct snd_kcontrol *kcontrol,511			struct snd_ctl_elem_value *ucontrol)512{513	struct snd_soc_component *component =514		snd_soc_dapm_kcontrol_component(kcontrol);515	struct rt715_sdca_priv *rt715 = snd_soc_component_get_drvdata(component);516	unsigned int val, mask_sft;517 518	if (strstr(ucontrol->id.name, "ADC 22 Mux"))519		mask_sft = 12;520	else if (strstr(ucontrol->id.name, "ADC 23 Mux"))521		mask_sft = 8;522	else if (strstr(ucontrol->id.name, "ADC 24 Mux"))523		mask_sft = 4;524	else if (strstr(ucontrol->id.name, "ADC 25 Mux"))525		mask_sft = 0;526	else527		return -EINVAL;528 529	rt715_sdca_index_read(rt715, RT715_VENDOR_HDA_CTL,530		RT715_HDA_LEGACY_MUX_CTL1, &val);531	val = (val >> mask_sft) & 0xf;532 533	/*534	 * The first two indices of ADC Mux 24/25 are routed to the same535	 * hardware source. ie, ADC Mux 24 0/1 will both connect to MIC2.536	 * To have a unique set of inputs, we skip the index1 of the muxes.537	 */538	if ((strstr(ucontrol->id.name, "ADC 24 Mux") ||539		strstr(ucontrol->id.name, "ADC 25 Mux")) && val > 0)540		val -= 1;541	ucontrol->value.enumerated.item[0] = val;542 543	return 0;544}545 546static int rt715_sdca_mux_put(struct snd_kcontrol *kcontrol,547			struct snd_ctl_elem_value *ucontrol)548{549	struct snd_soc_component *component =550		snd_soc_dapm_kcontrol_component(kcontrol);551	struct snd_soc_dapm_context *dapm =552				snd_soc_dapm_kcontrol_dapm(kcontrol);553	struct rt715_sdca_priv *rt715 = snd_soc_component_get_drvdata(component);554	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;555	unsigned int *item = ucontrol->value.enumerated.item;556	unsigned int val, val2 = 0, change, mask_sft;557 558	if (item[0] >= e->items)559		return -EINVAL;560 561	if (strstr(ucontrol->id.name, "ADC 22 Mux"))562		mask_sft = 12;563	else if (strstr(ucontrol->id.name, "ADC 23 Mux"))564		mask_sft = 8;565	else if (strstr(ucontrol->id.name, "ADC 24 Mux"))566		mask_sft = 4;567	else if (strstr(ucontrol->id.name, "ADC 25 Mux"))568		mask_sft = 0;569	else570		return -EINVAL;571 572	/* Verb ID = 0x701h, nid = e->reg */573	val = snd_soc_enum_item_to_val(e, item[0]) << e->shift_l;574 575	rt715_sdca_index_read(rt715, RT715_VENDOR_HDA_CTL,576		RT715_HDA_LEGACY_MUX_CTL1, &val2);577	val2 = (val2 >> mask_sft) & 0xf;578 579	change = val != val2;580 581	if (change)582		rt715_sdca_index_update_bits(rt715, RT715_VENDOR_HDA_CTL,583			RT715_HDA_LEGACY_MUX_CTL1, 0xf << mask_sft, val << mask_sft);584 585	snd_soc_dapm_mux_update_power(dapm, kcontrol, item[0], e, NULL);586 587	return change;588}589 590static const char * const adc_22_23_mux_text[] = {591	"MIC1",592	"MIC2",593	"LINE1",594	"LINE2",595	"DMIC1",596	"DMIC2",597	"DMIC3",598	"DMIC4",599};600 601/*602 * Due to mux design for nid 24 (MUX_IN3)/25 (MUX_IN4), connection index 0 and603 * 1 will be connected to the same dmic source, therefore we skip index 1 to604 * avoid misunderstanding on usage of dapm routing.605 */606static int rt715_adc_24_25_values[] = {607	0,608	2,609	3,610	4,611	5,612};613 614static const char * const adc_24_mux_text[] = {615	"MIC2",616	"DMIC1",617	"DMIC2",618	"DMIC3",619	"DMIC4",620};621 622static const char * const adc_25_mux_text[] = {623	"MIC1",624	"DMIC1",625	"DMIC2",626	"DMIC3",627	"DMIC4",628};629 630static SOC_ENUM_SINGLE_DECL(rt715_adc22_enum, SND_SOC_NOPM, 0,631	adc_22_23_mux_text);632 633static SOC_ENUM_SINGLE_DECL(rt715_adc23_enum, SND_SOC_NOPM, 0,634	adc_22_23_mux_text);635 636static SOC_VALUE_ENUM_SINGLE_DECL(rt715_adc24_enum,637	SND_SOC_NOPM, 0, 0xf,638	adc_24_mux_text, rt715_adc_24_25_values);639static SOC_VALUE_ENUM_SINGLE_DECL(rt715_adc25_enum,640	SND_SOC_NOPM, 0, 0xf,641	adc_25_mux_text, rt715_adc_24_25_values);642 643static const struct snd_kcontrol_new rt715_adc22_mux =644	SOC_DAPM_ENUM_EXT("ADC 22 Mux", rt715_adc22_enum,645			rt715_sdca_mux_get, rt715_sdca_mux_put);646 647static const struct snd_kcontrol_new rt715_adc23_mux =648	SOC_DAPM_ENUM_EXT("ADC 23 Mux", rt715_adc23_enum,649			rt715_sdca_mux_get, rt715_sdca_mux_put);650 651static const struct snd_kcontrol_new rt715_adc24_mux =652	SOC_DAPM_ENUM_EXT("ADC 24 Mux", rt715_adc24_enum,653			rt715_sdca_mux_get, rt715_sdca_mux_put);654 655static const struct snd_kcontrol_new rt715_adc25_mux =656	SOC_DAPM_ENUM_EXT("ADC 25 Mux", rt715_adc25_enum,657			rt715_sdca_mux_get, rt715_sdca_mux_put);658 659static int rt715_sdca_pde23_24_event(struct snd_soc_dapm_widget *w,660	struct snd_kcontrol *kcontrol, int event)661{662	struct snd_soc_component *component =663		snd_soc_dapm_to_component(w->dapm);664	struct rt715_sdca_priv *rt715 = snd_soc_component_get_drvdata(component);665 666	switch (event) {667	case SND_SOC_DAPM_POST_PMU:668		regmap_write(rt715->regmap,669			SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_CREQ_POW_EN,670				RT715_SDCA_REQ_POW_CTRL,671				CH_00), 0x00);672		break;673	case SND_SOC_DAPM_PRE_PMD:674		regmap_write(rt715->regmap,675			SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_CREQ_POW_EN,676				RT715_SDCA_REQ_POW_CTRL,677				CH_00), 0x03);678		break;679	}680	return 0;681}682 683static const struct snd_soc_dapm_widget rt715_sdca_dapm_widgets[] = {684	SND_SOC_DAPM_INPUT("DMIC1"),685	SND_SOC_DAPM_INPUT("DMIC2"),686	SND_SOC_DAPM_INPUT("DMIC3"),687	SND_SOC_DAPM_INPUT("DMIC4"),688	SND_SOC_DAPM_INPUT("MIC1"),689	SND_SOC_DAPM_INPUT("MIC2"),690	SND_SOC_DAPM_INPUT("LINE1"),691	SND_SOC_DAPM_INPUT("LINE2"),692 693	SND_SOC_DAPM_SUPPLY("PDE23_24", SND_SOC_NOPM, 0, 0,694		rt715_sdca_pde23_24_event,695		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),696 697	SND_SOC_DAPM_ADC("ADC 07", NULL, SND_SOC_NOPM, 4, 0),698	SND_SOC_DAPM_ADC("ADC 08", NULL, SND_SOC_NOPM, 4, 0),699	SND_SOC_DAPM_ADC("ADC 09", NULL, SND_SOC_NOPM, 4, 0),700	SND_SOC_DAPM_ADC("ADC 27", NULL, SND_SOC_NOPM, 4, 0),701	SND_SOC_DAPM_MUX("ADC 22 Mux", SND_SOC_NOPM, 0, 0,702		&rt715_adc22_mux),703	SND_SOC_DAPM_MUX("ADC 23 Mux", SND_SOC_NOPM, 0, 0,704		&rt715_adc23_mux),705	SND_SOC_DAPM_MUX("ADC 24 Mux", SND_SOC_NOPM, 0, 0,706		&rt715_adc24_mux),707	SND_SOC_DAPM_MUX("ADC 25 Mux", SND_SOC_NOPM, 0, 0,708		&rt715_adc25_mux),709	SND_SOC_DAPM_AIF_OUT("DP4TX", "DP4 Capture", 0, SND_SOC_NOPM, 0, 0),710	SND_SOC_DAPM_AIF_OUT("DP6TX", "DP6 Capture", 0, SND_SOC_NOPM, 0, 0),711};712 713static const struct snd_soc_dapm_route rt715_sdca_audio_map[] = {714	{"DP6TX", NULL, "ADC 09"},715	{"DP6TX", NULL, "ADC 08"},716	{"DP4TX", NULL, "ADC 07"},717	{"DP4TX", NULL, "ADC 27"},718	{"DP4TX", NULL, "ADC 09"},719	{"DP4TX", NULL, "ADC 08"},720 721	{"LINE1", NULL, "PDE23_24"},722	{"LINE2", NULL, "PDE23_24"},723	{"MIC1", NULL, "PDE23_24"},724	{"MIC2", NULL, "PDE23_24"},725	{"DMIC1", NULL, "PDE23_24"},726	{"DMIC2", NULL, "PDE23_24"},727	{"DMIC3", NULL, "PDE23_24"},728	{"DMIC4", NULL, "PDE23_24"},729 730	{"ADC 09", NULL, "ADC 22 Mux"},731	{"ADC 08", NULL, "ADC 23 Mux"},732	{"ADC 07", NULL, "ADC 24 Mux"},733	{"ADC 27", NULL, "ADC 25 Mux"},734	{"ADC 22 Mux", "MIC1", "MIC1"},735	{"ADC 22 Mux", "MIC2", "MIC2"},736	{"ADC 22 Mux", "LINE1", "LINE1"},737	{"ADC 22 Mux", "LINE2", "LINE2"},738	{"ADC 22 Mux", "DMIC1", "DMIC1"},739	{"ADC 22 Mux", "DMIC2", "DMIC2"},740	{"ADC 22 Mux", "DMIC3", "DMIC3"},741	{"ADC 22 Mux", "DMIC4", "DMIC4"},742	{"ADC 23 Mux", "MIC1", "MIC1"},743	{"ADC 23 Mux", "MIC2", "MIC2"},744	{"ADC 23 Mux", "LINE1", "LINE1"},745	{"ADC 23 Mux", "LINE2", "LINE2"},746	{"ADC 23 Mux", "DMIC1", "DMIC1"},747	{"ADC 23 Mux", "DMIC2", "DMIC2"},748	{"ADC 23 Mux", "DMIC3", "DMIC3"},749	{"ADC 23 Mux", "DMIC4", "DMIC4"},750	{"ADC 24 Mux", "MIC2", "MIC2"},751	{"ADC 24 Mux", "DMIC1", "DMIC1"},752	{"ADC 24 Mux", "DMIC2", "DMIC2"},753	{"ADC 24 Mux", "DMIC3", "DMIC3"},754	{"ADC 24 Mux", "DMIC4", "DMIC4"},755	{"ADC 25 Mux", "MIC1", "MIC1"},756	{"ADC 25 Mux", "DMIC1", "DMIC1"},757	{"ADC 25 Mux", "DMIC2", "DMIC2"},758	{"ADC 25 Mux", "DMIC3", "DMIC3"},759	{"ADC 25 Mux", "DMIC4", "DMIC4"},760};761 762static int rt715_sdca_probe(struct snd_soc_component *component)763{764	struct rt715_sdca_priv *rt715 = snd_soc_component_get_drvdata(component);765	int ret;766 767	if (!rt715->first_hw_init)768		return 0;769 770	ret = pm_runtime_resume(component->dev);771	if (ret < 0 && ret != -EACCES)772		return ret;773 774	return 0;775}776 777static const struct snd_soc_component_driver soc_codec_dev_rt715_sdca = {778	.probe = rt715_sdca_probe,779	.controls = rt715_sdca_snd_controls,780	.num_controls = ARRAY_SIZE(rt715_sdca_snd_controls),781	.dapm_widgets = rt715_sdca_dapm_widgets,782	.num_dapm_widgets = ARRAY_SIZE(rt715_sdca_dapm_widgets),783	.dapm_routes = rt715_sdca_audio_map,784	.num_dapm_routes = ARRAY_SIZE(rt715_sdca_audio_map),785	.endianness = 1,786};787 788static int rt715_sdca_set_sdw_stream(struct snd_soc_dai *dai, void *sdw_stream,789				int direction)790{791	snd_soc_dai_dma_data_set(dai, direction, sdw_stream);792 793	return 0;794}795 796static void rt715_sdca_shutdown(struct snd_pcm_substream *substream,797				struct snd_soc_dai *dai)798 799{800	snd_soc_dai_set_dma_data(dai, substream, NULL);801}802 803static int rt715_sdca_pcm_hw_params(struct snd_pcm_substream *substream,804				struct snd_pcm_hw_params *params,805				struct snd_soc_dai *dai)806{807	struct snd_soc_component *component = dai->component;808	struct rt715_sdca_priv *rt715 = snd_soc_component_get_drvdata(component);809	struct sdw_stream_config stream_config = {0};810	struct sdw_port_config port_config = {0};811	struct sdw_stream_runtime *sdw_stream;812	int retval;813	unsigned int val;814 815	sdw_stream = snd_soc_dai_get_dma_data(dai, substream);816 817	if (!sdw_stream)818		return -EINVAL;819 820	if (!rt715->slave)821		return -EINVAL;822 823	snd_sdw_params_to_config(substream, params, &stream_config, &port_config);824 825	switch (dai->id) {826	case RT715_AIF1:827		port_config.num = 6;828		rt715_sdca_index_write(rt715, RT715_VENDOR_REG, RT715_SDW_INPUT_SEL,829			0xa500);830		break;831	case RT715_AIF2:832		port_config.num = 4;833		rt715_sdca_index_write(rt715, RT715_VENDOR_REG, RT715_SDW_INPUT_SEL,834			0xaf00);835		break;836	default:837		dev_err(component->dev, "%s: Invalid DAI id %d\n", __func__, dai->id);838		return -EINVAL;839	}840 841	retval = sdw_stream_add_slave(rt715->slave, &stream_config,842					&port_config, 1, sdw_stream);843	if (retval) {844		dev_err(component->dev, "%s: Unable to configure port, retval:%d\n",845			__func__, retval);846		return retval;847	}848 849	switch (params_rate(params)) {850	case 8000:851		val = 0x1;852		break;853	case 11025:854		val = 0x2;855		break;856	case 12000:857		val = 0x3;858		break;859	case 16000:860		val = 0x4;861		break;862	case 22050:863		val = 0x5;864		break;865	case 24000:866		val = 0x6;867		break;868	case 32000:869		val = 0x7;870		break;871	case 44100:872		val = 0x8;873		break;874	case 48000:875		val = 0x9;876		break;877	case 88200:878		val = 0xa;879		break;880	case 96000:881		val = 0xb;882		break;883	case 176400:884		val = 0xc;885		break;886	case 192000:887		val = 0xd;888		break;889	case 384000:890		val = 0xe;891		break;892	case 768000:893		val = 0xf;894		break;895	default:896		dev_err(component->dev, "%s: Unsupported sample rate %d\n",897			__func__, params_rate(params));898		return -EINVAL;899	}900 901	regmap_write(rt715->regmap,902		SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_CS_FREQ_IND_EN,903			RT715_SDCA_FREQ_IND_CTRL, CH_00), val);904 905	return 0;906}907 908static int rt715_sdca_pcm_hw_free(struct snd_pcm_substream *substream,909				struct snd_soc_dai *dai)910{911	struct snd_soc_component *component = dai->component;912	struct rt715_sdca_priv *rt715 = snd_soc_component_get_drvdata(component);913	struct sdw_stream_runtime *sdw_stream =914		snd_soc_dai_get_dma_data(dai, substream);915 916	if (!rt715->slave)917		return -EINVAL;918 919	sdw_stream_remove_slave(rt715->slave, sdw_stream);920	return 0;921}922 923#define RT715_STEREO_RATES (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000)924#define RT715_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \925			SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S8)926 927static const struct snd_soc_dai_ops rt715_sdca_ops = {928	.hw_params	= rt715_sdca_pcm_hw_params,929	.hw_free	= rt715_sdca_pcm_hw_free,930	.set_stream	= rt715_sdca_set_sdw_stream,931	.shutdown	= rt715_sdca_shutdown,932};933 934static struct snd_soc_dai_driver rt715_sdca_dai[] = {935	{936		.name = "rt715-sdca-aif1",937		.id = RT715_AIF1,938		.capture = {939			.stream_name = "DP6 Capture",940			.channels_min = 1,941			.channels_max = 2,942			.rates = RT715_STEREO_RATES,943			.formats = RT715_FORMATS,944		},945		.ops = &rt715_sdca_ops,946	},947	{948		.name = "rt715-sdca-aif2",949		.id = RT715_AIF2,950		.capture = {951			.stream_name = "DP4 Capture",952			.channels_min = 1,953			.channels_max = 2,954			.rates = RT715_STEREO_RATES,955			.formats = RT715_FORMATS,956		},957		.ops = &rt715_sdca_ops,958	},959};960 961/* Bus clock frequency */962#define RT715_CLK_FREQ_9600000HZ 9600000963#define RT715_CLK_FREQ_12000000HZ 12000000964#define RT715_CLK_FREQ_6000000HZ 6000000965#define RT715_CLK_FREQ_4800000HZ 4800000966#define RT715_CLK_FREQ_2400000HZ 2400000967#define RT715_CLK_FREQ_12288000HZ 12288000968 969int rt715_sdca_init(struct device *dev, struct regmap *mbq_regmap,970	struct regmap *regmap, struct sdw_slave *slave)971{972	struct rt715_sdca_priv *rt715;973	int ret;974 975	rt715 = devm_kzalloc(dev, sizeof(*rt715), GFP_KERNEL);976	if (!rt715)977		return -ENOMEM;978 979	dev_set_drvdata(dev, rt715);980	rt715->slave = slave;981	rt715->regmap = regmap;982	rt715->mbq_regmap = mbq_regmap;983	rt715->hw_sdw_ver = slave->id.sdw_version;984 985	regcache_cache_only(rt715->regmap, true);986	regcache_cache_only(rt715->mbq_regmap, true);987 988	/*989	 * Mark hw_init to false990	 * HW init will be performed when device reports present991	 */992	rt715->hw_init = false;993	rt715->first_hw_init = false;994 995	ret = devm_snd_soc_register_component(dev,996			&soc_codec_dev_rt715_sdca,997			rt715_sdca_dai,998			ARRAY_SIZE(rt715_sdca_dai));999	if (ret < 0)1000		return ret;1001 1002	/* set autosuspend parameters */1003	pm_runtime_set_autosuspend_delay(dev, 3000);1004	pm_runtime_use_autosuspend(dev);1005 1006	/* make sure the device does not suspend immediately */1007	pm_runtime_mark_last_busy(dev);1008 1009	pm_runtime_enable(dev);1010 1011	/* important note: the device is NOT tagged as 'active' and will remain1012	 * 'suspended' until the hardware is enumerated/initialized. This is required1013	 * to make sure the ASoC framework use of pm_runtime_get_sync() does not silently1014	 * fail with -EACCESS because of race conditions between card creation and enumeration1015	 */1016 1017	dev_dbg(dev, "%s\n", __func__);1018 1019	return ret;1020}1021 1022int rt715_sdca_io_init(struct device *dev, struct sdw_slave *slave)1023{1024	struct rt715_sdca_priv *rt715 = dev_get_drvdata(dev);1025	unsigned int hw_ver;1026 1027	if (rt715->hw_init)1028		return 0;1029 1030	regcache_cache_only(rt715->regmap, false);1031	regcache_cache_only(rt715->mbq_regmap, false);1032 1033	/*1034	 * PM runtime status is marked as 'active' only when a Slave reports as Attached1035	 */1036	if (!rt715->first_hw_init) {1037		/* update count of parent 'active' children */1038		pm_runtime_set_active(&slave->dev);1039 1040		rt715->first_hw_init = true;1041	}1042 1043	pm_runtime_get_noresume(&slave->dev);1044 1045	rt715_sdca_index_read(rt715, RT715_VENDOR_REG,1046		RT715_PRODUCT_NUM, &hw_ver);1047	hw_ver = hw_ver & 0x000f;1048 1049	/* set clock selector = external */1050	regmap_write(rt715->regmap,1051		SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_CX_CLK_SEL_EN,1052			RT715_SDCA_CX_CLK_SEL_CTRL, CH_00), 0x1);1053	/* set GPIO_4/5/6 to be 3rd/4th DMIC usage */1054	if (hw_ver == 0x0)1055		rt715_sdca_index_update_bits(rt715, RT715_VENDOR_REG,1056			RT715_AD_FUNC_EN, 0x54, 0x54);1057	else if (hw_ver == 0x1) {1058		rt715_sdca_index_update_bits(rt715, RT715_VENDOR_REG,1059			RT715_AD_FUNC_EN, 0x55, 0x55);1060		rt715_sdca_index_update_bits(rt715, RT715_VENDOR_REG,1061			RT715_REV_1, 0x40, 0x40);1062	}1063	/* DFLL Calibration trigger */1064	rt715_sdca_index_update_bits(rt715, RT715_VENDOR_REG,1065			RT715_DFLL_VAD, 0x1, 0x1);1066	/* trigger mode = VAD enable */1067	regmap_write(rt715->regmap,1068		SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_SMPU_TRIG_ST_EN,1069			RT715_SDCA_SMPU_TRIG_EN_CTRL, CH_00), 0x2);1070	/* SMPU-1 interrupt enable mask */1071	regmap_update_bits(rt715->regmap, RT715_INT_MASK, 0x1, 0x1);1072 1073	/* Mark Slave initialization complete */1074	rt715->hw_init = true;1075 1076	pm_runtime_mark_last_busy(&slave->dev);1077	pm_runtime_put_autosuspend(&slave->dev);1078 1079	return 0;1080}1081 1082MODULE_DESCRIPTION("ASoC rt715 driver SDW SDCA");1083MODULE_AUTHOR("Jack Yu <jack.yu@realtek.com>");1084MODULE_LICENSE("GPL v2");1085