cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

rt715-sdca.c (30048B)


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