xref: /linux/sound/soc/codecs/rt712-sdca-dmic.c (revision 33e02dc69afbd8f1b85a51d74d72f139ba4ca623)
163a51128SShuming Fan // SPDX-License-Identifier: GPL-2.0-only
263a51128SShuming Fan //
363a51128SShuming Fan // rt712-sdca-dmic.c -- rt712 SDCA DMIC ALSA SoC audio driver
463a51128SShuming Fan //
563a51128SShuming Fan // Copyright(c) 2023 Realtek Semiconductor Corp.
663a51128SShuming Fan //
763a51128SShuming Fan //
863a51128SShuming Fan 
963a51128SShuming Fan #include <linux/module.h>
1063a51128SShuming Fan #include <linux/mod_devicetable.h>
1163a51128SShuming Fan #include <linux/pm_runtime.h>
1263a51128SShuming Fan #include <linux/soundwire/sdw_registers.h>
1363a51128SShuming Fan #include <linux/slab.h>
1463a51128SShuming Fan #include <sound/core.h>
1563a51128SShuming Fan #include <sound/pcm.h>
1663a51128SShuming Fan #include <sound/pcm_params.h>
1763a51128SShuming Fan #include <sound/tlv.h>
1863a51128SShuming Fan #include "rt712-sdca.h"
1963a51128SShuming Fan #include "rt712-sdca-dmic.h"
2063a51128SShuming Fan 
rt712_sdca_dmic_readable_register(struct device * dev,unsigned int reg)2163a51128SShuming Fan static bool rt712_sdca_dmic_readable_register(struct device *dev, unsigned int reg)
2263a51128SShuming Fan {
2363a51128SShuming Fan 	switch (reg) {
2463a51128SShuming Fan 	case 0x201a ... 0x201f:
2563a51128SShuming Fan 	case 0x2029 ... 0x202a:
2663a51128SShuming Fan 	case 0x202d ... 0x2034:
2763a51128SShuming Fan 	case 0x2230 ... 0x2232:
2863a51128SShuming Fan 	case 0x2f01 ... 0x2f0a:
2963a51128SShuming Fan 	case 0x2f35 ... 0x2f36:
3063a51128SShuming Fan 	case 0x2f52:
3163a51128SShuming Fan 	case 0x2f58 ... 0x2f59:
3263a51128SShuming Fan 	case 0x3201:
3363a51128SShuming Fan 	case 0x320c:
3463a51128SShuming Fan 		return true;
3563a51128SShuming Fan 	default:
3663a51128SShuming Fan 		return false;
3763a51128SShuming Fan 	}
3863a51128SShuming Fan }
3963a51128SShuming Fan 
rt712_sdca_dmic_volatile_register(struct device * dev,unsigned int reg)4063a51128SShuming Fan static bool rt712_sdca_dmic_volatile_register(struct device *dev, unsigned int reg)
4163a51128SShuming Fan {
4263a51128SShuming Fan 	switch (reg) {
4363a51128SShuming Fan 	case 0x201b:
4463a51128SShuming Fan 	case 0x201c:
4563a51128SShuming Fan 	case 0x201d:
4663a51128SShuming Fan 	case 0x201f:
4763a51128SShuming Fan 	case 0x202d ... 0x202f:
4863a51128SShuming Fan 	case 0x2230:
4963a51128SShuming Fan 	case 0x2f01:
5063a51128SShuming Fan 	case 0x2f35:
5163a51128SShuming Fan 	case 0x320c:
5263a51128SShuming Fan 		return true;
5363a51128SShuming Fan 	default:
5463a51128SShuming Fan 		return false;
5563a51128SShuming Fan 	}
5663a51128SShuming Fan }
5763a51128SShuming Fan 
rt712_sdca_dmic_mbq_readable_register(struct device * dev,unsigned int reg)5863a51128SShuming Fan static bool rt712_sdca_dmic_mbq_readable_register(struct device *dev, unsigned int reg)
5963a51128SShuming Fan {
6063a51128SShuming Fan 	switch (reg) {
6163a51128SShuming Fan 	case 0x2000000 ... 0x200008e:
6263a51128SShuming Fan 	case 0x5300000 ... 0x530000e:
6363a51128SShuming Fan 	case 0x5400000 ... 0x540000e:
6463a51128SShuming Fan 	case 0x5600000 ... 0x5600008:
6563a51128SShuming Fan 	case 0x5700000 ... 0x570000d:
6663a51128SShuming Fan 	case 0x5800000 ... 0x5800021:
6763a51128SShuming Fan 	case 0x5900000 ... 0x5900028:
6863a51128SShuming Fan 	case 0x5a00000 ... 0x5a00009:
6963a51128SShuming Fan 	case 0x5b00000 ... 0x5b00051:
7063a51128SShuming Fan 	case 0x5c00000 ... 0x5c0009a:
7163a51128SShuming Fan 	case 0x5d00000 ... 0x5d00009:
7263a51128SShuming Fan 	case 0x5f00000 ... 0x5f00030:
7363a51128SShuming Fan 	case 0x6100000 ... 0x6100068:
7463a51128SShuming Fan 	case SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT712_SDCA_ENT_USER_FU1E, RT712_SDCA_CTL_FU_VOLUME, CH_01):
7563a51128SShuming Fan 	case SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT712_SDCA_ENT_USER_FU1E, RT712_SDCA_CTL_FU_VOLUME, CH_02):
7663a51128SShuming Fan 	case SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT712_SDCA_ENT_USER_FU1E, RT712_SDCA_CTL_FU_VOLUME, CH_03):
7763a51128SShuming Fan 	case SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT712_SDCA_ENT_USER_FU1E, RT712_SDCA_CTL_FU_VOLUME, CH_04):
7863a51128SShuming Fan 	case SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT712_SDCA_ENT_PLATFORM_FU15, RT712_SDCA_CTL_FU_CH_GAIN, CH_01):
7963a51128SShuming Fan 	case SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT712_SDCA_ENT_PLATFORM_FU15, RT712_SDCA_CTL_FU_CH_GAIN, CH_02):
8063a51128SShuming Fan 	case SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT712_SDCA_ENT_PLATFORM_FU15, RT712_SDCA_CTL_FU_CH_GAIN, CH_03):
8163a51128SShuming Fan 	case SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT712_SDCA_ENT_PLATFORM_FU15, RT712_SDCA_CTL_FU_CH_GAIN, CH_04):
8263a51128SShuming Fan 		return true;
8363a51128SShuming Fan 	default:
8463a51128SShuming Fan 		return false;
8563a51128SShuming Fan 	}
8663a51128SShuming Fan }
8763a51128SShuming Fan 
rt712_sdca_dmic_mbq_volatile_register(struct device * dev,unsigned int reg)8863a51128SShuming Fan static bool rt712_sdca_dmic_mbq_volatile_register(struct device *dev, unsigned int reg)
8963a51128SShuming Fan {
9063a51128SShuming Fan 	switch (reg) {
9163a51128SShuming Fan 	case 0x2000000:
9263a51128SShuming Fan 	case 0x200001a:
9363a51128SShuming Fan 	case 0x2000024:
9463a51128SShuming Fan 	case 0x2000046:
9563a51128SShuming Fan 	case 0x200008a:
9663a51128SShuming Fan 	case 0x5800000:
9763a51128SShuming Fan 	case 0x5800001:
9863a51128SShuming Fan 	case 0x6100008:
9963a51128SShuming Fan 		return true;
10063a51128SShuming Fan 	default:
10163a51128SShuming Fan 		return false;
10263a51128SShuming Fan 	}
10363a51128SShuming Fan }
10463a51128SShuming Fan 
10563a51128SShuming Fan static const struct regmap_config rt712_sdca_dmic_regmap = {
10663a51128SShuming Fan 	.reg_bits = 32,
10763a51128SShuming Fan 	.val_bits = 8,
10863a51128SShuming Fan 	.readable_reg = rt712_sdca_dmic_readable_register,
10963a51128SShuming Fan 	.volatile_reg = rt712_sdca_dmic_volatile_register,
11063a51128SShuming Fan 	.max_register = 0x40981300,
11163a51128SShuming Fan 	.reg_defaults = rt712_sdca_dmic_reg_defaults,
11263a51128SShuming Fan 	.num_reg_defaults = ARRAY_SIZE(rt712_sdca_dmic_reg_defaults),
113f438c799SMark Brown 	.cache_type = REGCACHE_MAPLE,
11463a51128SShuming Fan 	.use_single_read = true,
11563a51128SShuming Fan 	.use_single_write = true,
11663a51128SShuming Fan };
11763a51128SShuming Fan 
11863a51128SShuming Fan static const struct regmap_config rt712_sdca_dmic_mbq_regmap = {
11963a51128SShuming Fan 	.name = "sdw-mbq",
12063a51128SShuming Fan 	.reg_bits = 32,
12163a51128SShuming Fan 	.val_bits = 16,
12263a51128SShuming Fan 	.readable_reg = rt712_sdca_dmic_mbq_readable_register,
12363a51128SShuming Fan 	.volatile_reg = rt712_sdca_dmic_mbq_volatile_register,
12463a51128SShuming Fan 	.max_register = 0x40800f14,
12563a51128SShuming Fan 	.reg_defaults = rt712_sdca_dmic_mbq_defaults,
12663a51128SShuming Fan 	.num_reg_defaults = ARRAY_SIZE(rt712_sdca_dmic_mbq_defaults),
127f438c799SMark Brown 	.cache_type = REGCACHE_MAPLE,
12863a51128SShuming Fan 	.use_single_read = true,
12963a51128SShuming Fan 	.use_single_write = true,
13063a51128SShuming Fan };
13163a51128SShuming Fan 
rt712_sdca_dmic_index_write(struct rt712_sdca_dmic_priv * rt712,unsigned int nid,unsigned int reg,unsigned int value)13263a51128SShuming Fan static int rt712_sdca_dmic_index_write(struct rt712_sdca_dmic_priv *rt712,
13363a51128SShuming Fan 		unsigned int nid, unsigned int reg, unsigned int value)
13463a51128SShuming Fan {
13563a51128SShuming Fan 	int ret;
13663a51128SShuming Fan 	struct regmap *regmap = rt712->mbq_regmap;
13763a51128SShuming Fan 	unsigned int addr = (nid << 20) | reg;
13863a51128SShuming Fan 
13963a51128SShuming Fan 	ret = regmap_write(regmap, addr, value);
14063a51128SShuming Fan 	if (ret < 0)
14163a51128SShuming Fan 		dev_err(&rt712->slave->dev,
142*f892e66fSPierre-Louis Bossart 			"%s: Failed to set private value: %06x <= %04x ret=%d\n",
143*f892e66fSPierre-Louis Bossart 			__func__, addr, value, ret);
14463a51128SShuming Fan 
14563a51128SShuming Fan 	return ret;
14663a51128SShuming Fan }
14763a51128SShuming Fan 
rt712_sdca_dmic_index_read(struct rt712_sdca_dmic_priv * rt712,unsigned int nid,unsigned int reg,unsigned int * value)14863a51128SShuming Fan static int rt712_sdca_dmic_index_read(struct rt712_sdca_dmic_priv *rt712,
14963a51128SShuming Fan 		unsigned int nid, unsigned int reg, unsigned int *value)
15063a51128SShuming Fan {
15163a51128SShuming Fan 	int ret;
15263a51128SShuming Fan 	struct regmap *regmap = rt712->mbq_regmap;
15363a51128SShuming Fan 	unsigned int addr = (nid << 20) | reg;
15463a51128SShuming Fan 
15563a51128SShuming Fan 	ret = regmap_read(regmap, addr, value);
15663a51128SShuming Fan 	if (ret < 0)
15763a51128SShuming Fan 		dev_err(&rt712->slave->dev,
158*f892e66fSPierre-Louis Bossart 			"%s: Failed to get private value: %06x => %04x ret=%d\n",
159*f892e66fSPierre-Louis Bossart 			__func__, addr, *value, ret);
16063a51128SShuming Fan 
16163a51128SShuming Fan 	return ret;
16263a51128SShuming Fan }
16363a51128SShuming Fan 
rt712_sdca_dmic_index_update_bits(struct rt712_sdca_dmic_priv * rt712,unsigned int nid,unsigned int reg,unsigned int mask,unsigned int val)16463a51128SShuming Fan static int rt712_sdca_dmic_index_update_bits(struct rt712_sdca_dmic_priv *rt712,
16563a51128SShuming Fan 	unsigned int nid, unsigned int reg, unsigned int mask, unsigned int val)
16663a51128SShuming Fan {
16763a51128SShuming Fan 	unsigned int tmp;
16863a51128SShuming Fan 	int ret;
16963a51128SShuming Fan 
17063a51128SShuming Fan 	ret = rt712_sdca_dmic_index_read(rt712, nid, reg, &tmp);
17163a51128SShuming Fan 	if (ret < 0)
17263a51128SShuming Fan 		return ret;
17363a51128SShuming Fan 
17463a51128SShuming Fan 	set_mask_bits(&tmp, mask, val);
17563a51128SShuming Fan 	return rt712_sdca_dmic_index_write(rt712, nid, reg, tmp);
17663a51128SShuming Fan }
17763a51128SShuming Fan 
rt712_sdca_dmic_io_init(struct device * dev,struct sdw_slave * slave)17863a51128SShuming Fan static int rt712_sdca_dmic_io_init(struct device *dev, struct sdw_slave *slave)
17963a51128SShuming Fan {
18063a51128SShuming Fan 	struct rt712_sdca_dmic_priv *rt712 = dev_get_drvdata(dev);
18163a51128SShuming Fan 
18263a51128SShuming Fan 	if (rt712->hw_init)
18363a51128SShuming Fan 		return 0;
18463a51128SShuming Fan 
18563a51128SShuming Fan 	regcache_cache_only(rt712->regmap, false);
18663a51128SShuming Fan 	regcache_cache_only(rt712->mbq_regmap, false);
18749ae74abSPierre-Louis Bossart 	if (rt712->first_hw_init) {
18849ae74abSPierre-Louis Bossart 		regcache_cache_bypass(rt712->regmap, true);
18963a51128SShuming Fan 		regcache_cache_bypass(rt712->mbq_regmap, true);
19063a51128SShuming Fan 	} else {
19163a51128SShuming Fan 		/*
1928d890eceSPierre-Louis Bossart 		 * PM runtime status is marked as 'active' only when a Slave reports as Attached
19363a51128SShuming Fan 		 */
19463a51128SShuming Fan 
19563a51128SShuming Fan 		/* update count of parent 'active' children */
19663a51128SShuming Fan 		pm_runtime_set_active(&slave->dev);
19763a51128SShuming Fan 	}
19863a51128SShuming Fan 
19963a51128SShuming Fan 	pm_runtime_get_noresume(&slave->dev);
20063a51128SShuming Fan 
20163a51128SShuming Fan 	rt712_sdca_dmic_index_write(rt712, RT712_VENDOR_HDA_CTL,
20263a51128SShuming Fan 		RT712_ADC0A_08_PDE_FLOAT_CTL, 0x1112);
20363a51128SShuming Fan 	rt712_sdca_dmic_index_write(rt712, RT712_VENDOR_HDA_CTL,
20463a51128SShuming Fan 		RT712_ADC0B_11_PDE_FLOAT_CTL, 0x1111);
20563a51128SShuming Fan 	rt712_sdca_dmic_index_write(rt712, RT712_VENDOR_HDA_CTL,
20663a51128SShuming Fan 		RT712_DMIC1_2_PDE_FLOAT_CTL, 0x1111);
20763a51128SShuming Fan 	rt712_sdca_dmic_index_write(rt712, RT712_VENDOR_HDA_CTL,
20863a51128SShuming Fan 		RT712_I2S_IN_OUT_PDE_FLOAT_CTL, 0x1155);
20963a51128SShuming Fan 	rt712_sdca_dmic_index_write(rt712, RT712_VENDOR_HDA_CTL,
21063a51128SShuming Fan 		RT712_DMIC_ENT_FLOAT_CTL, 0x2626);
21163a51128SShuming Fan 	rt712_sdca_dmic_index_write(rt712, RT712_VENDOR_HDA_CTL,
21263a51128SShuming Fan 		RT712_ADC_ENT_FLOAT_CTL, 0x1e19);
21363a51128SShuming Fan 	rt712_sdca_dmic_index_write(rt712, RT712_VENDOR_HDA_CTL,
21463a51128SShuming Fan 		RT712_DMIC_GAIN_ENT_FLOAT_CTL0, 0x1515);
21563a51128SShuming Fan 	rt712_sdca_dmic_index_write(rt712, RT712_VENDOR_HDA_CTL,
21663a51128SShuming Fan 		RT712_ADC_VOL_CH_FLOAT_CTL2, 0x0304);
21763a51128SShuming Fan 	rt712_sdca_dmic_index_write(rt712, RT712_VENDOR_HDA_CTL,
21863a51128SShuming Fan 		RT712_DMIC_GAIN_ENT_FLOAT_CTL2, 0x0304);
21963a51128SShuming Fan 	rt712_sdca_dmic_index_write(rt712, RT712_VENDOR_HDA_CTL,
22063a51128SShuming Fan 		RT712_HDA_LEGACY_CONFIG_CTL0, 0x0050);
22163a51128SShuming Fan 	regmap_write(rt712->regmap,
22263a51128SShuming Fan 		SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT712_SDCA_ENT_IT26, RT712_SDCA_CTL_VENDOR_DEF, 0), 0x01);
22363a51128SShuming Fan 	rt712_sdca_dmic_index_write(rt712, RT712_ULTRA_SOUND_DET,
22463a51128SShuming Fan 		RT712_ULTRA_SOUND_DETECTOR6, 0x3200);
22563a51128SShuming Fan 	regmap_write(rt712->regmap, RT712_RC_CAL, 0x23);
22663a51128SShuming Fan 	regmap_write(rt712->regmap, 0x2f52, 0x00);
22763a51128SShuming Fan 
22863a51128SShuming Fan 	if (rt712->first_hw_init) {
22963a51128SShuming Fan 		regcache_cache_bypass(rt712->regmap, false);
23063a51128SShuming Fan 		regcache_mark_dirty(rt712->regmap);
23163a51128SShuming Fan 		regcache_cache_bypass(rt712->mbq_regmap, false);
23263a51128SShuming Fan 		regcache_mark_dirty(rt712->mbq_regmap);
23363a51128SShuming Fan 	} else
23463a51128SShuming Fan 		rt712->first_hw_init = true;
23563a51128SShuming Fan 
23663a51128SShuming Fan 	/* Mark Slave initialization complete */
23763a51128SShuming Fan 	rt712->hw_init = true;
23863a51128SShuming Fan 
23963a51128SShuming Fan 	pm_runtime_mark_last_busy(&slave->dev);
24063a51128SShuming Fan 	pm_runtime_put_autosuspend(&slave->dev);
24163a51128SShuming Fan 
24263a51128SShuming Fan 	dev_dbg(&slave->dev, "%s hw_init complete\n", __func__);
24363a51128SShuming Fan 	return 0;
24463a51128SShuming Fan }
24563a51128SShuming Fan 
rt712_sdca_dmic_set_gain_get(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)24663a51128SShuming Fan static int rt712_sdca_dmic_set_gain_get(struct snd_kcontrol *kcontrol,
24763a51128SShuming Fan 		struct snd_ctl_elem_value *ucontrol)
24863a51128SShuming Fan {
24963a51128SShuming Fan 	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
25063a51128SShuming Fan 	struct rt712_sdca_priv *rt712 = snd_soc_component_get_drvdata(component);
25163a51128SShuming Fan 	struct rt712_sdca_dmic_kctrl_priv *p =
25263a51128SShuming Fan 		(struct rt712_sdca_dmic_kctrl_priv *)kcontrol->private_value;
25363a51128SShuming Fan 	unsigned int regvalue, ctl, i;
25463a51128SShuming Fan 	unsigned int adc_vol_flag = 0;
25563a51128SShuming Fan 	const unsigned int interval_offset = 0xc0;
25663a51128SShuming Fan 
25763a51128SShuming Fan 	if (strstr(ucontrol->id.name, "FU1E Capture Volume"))
25863a51128SShuming Fan 		adc_vol_flag = 1;
25963a51128SShuming Fan 
26063a51128SShuming Fan 	/* check all channels */
26163a51128SShuming Fan 	for (i = 0; i < p->count; i++) {
26263a51128SShuming Fan 		regmap_read(rt712->mbq_regmap, p->reg_base + i, &regvalue);
26363a51128SShuming Fan 
26463a51128SShuming Fan 		if (!adc_vol_flag) /* boost gain */
26563a51128SShuming Fan 			ctl = regvalue / 0x0a00;
26663a51128SShuming Fan 		else { /* ADC gain */
26763a51128SShuming Fan 			if (adc_vol_flag)
26863a51128SShuming Fan 				ctl = p->max - (((0x1e00 - regvalue) & 0xffff) / interval_offset);
26963a51128SShuming Fan 			else
27063a51128SShuming Fan 				ctl = p->max - (((0 - regvalue) & 0xffff) / interval_offset);
27163a51128SShuming Fan 		}
27263a51128SShuming Fan 
27363a51128SShuming Fan 		ucontrol->value.integer.value[i] = ctl;
27463a51128SShuming Fan 	}
27563a51128SShuming Fan 
27663a51128SShuming Fan 	return 0;
27763a51128SShuming Fan }
27863a51128SShuming Fan 
rt712_sdca_dmic_set_gain_put(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)27963a51128SShuming Fan static int rt712_sdca_dmic_set_gain_put(struct snd_kcontrol *kcontrol,
28063a51128SShuming Fan 		struct snd_ctl_elem_value *ucontrol)
28163a51128SShuming Fan {
28263a51128SShuming Fan 	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
28363a51128SShuming Fan 	struct rt712_sdca_dmic_kctrl_priv *p =
28463a51128SShuming Fan 		(struct rt712_sdca_dmic_kctrl_priv *)kcontrol->private_value;
28563a51128SShuming Fan 	struct rt712_sdca_priv *rt712 = snd_soc_component_get_drvdata(component);
28663a51128SShuming Fan 	unsigned int gain_val[4];
28763a51128SShuming Fan 	unsigned int i, adc_vol_flag = 0, changed = 0;
28863a51128SShuming Fan 	unsigned int regvalue[4];
28963a51128SShuming Fan 	const unsigned int interval_offset = 0xc0;
29063a51128SShuming Fan 	int err;
29163a51128SShuming Fan 
29263a51128SShuming Fan 	if (strstr(ucontrol->id.name, "FU1E Capture Volume"))
29363a51128SShuming Fan 		adc_vol_flag = 1;
29463a51128SShuming Fan 
29563a51128SShuming Fan 	/* check all channels */
29663a51128SShuming Fan 	for (i = 0; i < p->count; i++) {
29763a51128SShuming Fan 		regmap_read(rt712->mbq_regmap, p->reg_base + i, &regvalue[i]);
29863a51128SShuming Fan 
29963a51128SShuming Fan 		gain_val[i] = ucontrol->value.integer.value[i];
30063a51128SShuming Fan 		if (gain_val[i] > p->max)
30163a51128SShuming Fan 			gain_val[i] = p->max;
30263a51128SShuming Fan 
30363a51128SShuming Fan 		if (!adc_vol_flag) /* boost gain */
30463a51128SShuming Fan 			gain_val[i] = gain_val[i] * 0x0a00;
30563a51128SShuming Fan 		else { /* ADC gain */
30663a51128SShuming Fan 			gain_val[i] = 0x1e00 - ((p->max - gain_val[i]) * interval_offset);
30763a51128SShuming Fan 			gain_val[i] &= 0xffff;
30863a51128SShuming Fan 		}
30963a51128SShuming Fan 
31063a51128SShuming Fan 		if (regvalue[i] != gain_val[i])
31163a51128SShuming Fan 			changed = 1;
31263a51128SShuming Fan 	}
31363a51128SShuming Fan 
31463a51128SShuming Fan 	if (!changed)
31563a51128SShuming Fan 		return 0;
31663a51128SShuming Fan 
31763a51128SShuming Fan 	for (i = 0; i < p->count; i++) {
31863a51128SShuming Fan 		err = regmap_write(rt712->mbq_regmap, p->reg_base + i, gain_val[i]);
31963a51128SShuming Fan 		if (err < 0)
320*f892e66fSPierre-Louis Bossart 			dev_err(&rt712->slave->dev, "%s: 0x%08x can't be set\n",
321*f892e66fSPierre-Louis Bossart 				__func__, p->reg_base + i);
32263a51128SShuming Fan 	}
32363a51128SShuming Fan 
32463a51128SShuming Fan 	return changed;
32563a51128SShuming Fan }
32663a51128SShuming Fan 
rt712_sdca_set_fu1e_capture_ctl(struct rt712_sdca_dmic_priv * rt712)32763a51128SShuming Fan static int rt712_sdca_set_fu1e_capture_ctl(struct rt712_sdca_dmic_priv *rt712)
32863a51128SShuming Fan {
32963a51128SShuming Fan 	int err, i;
33063a51128SShuming Fan 	unsigned int ch_mute;
33163a51128SShuming Fan 
33263a51128SShuming Fan 	for (i = 0; i < ARRAY_SIZE(rt712->fu1e_mixer_mute); i++) {
33363a51128SShuming Fan 		ch_mute = (rt712->fu1e_dapm_mute || rt712->fu1e_mixer_mute[i]) ? 0x01 : 0x00;
33463a51128SShuming Fan 		err = regmap_write(rt712->regmap,
33563a51128SShuming Fan 				SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT712_SDCA_ENT_USER_FU1E,
33663a51128SShuming Fan 				RT712_SDCA_CTL_FU_MUTE, CH_01) + i, ch_mute);
33763a51128SShuming Fan 		if (err < 0)
33863a51128SShuming Fan 			return err;
33963a51128SShuming Fan 	}
34063a51128SShuming Fan 
34163a51128SShuming Fan 	return 0;
34263a51128SShuming Fan }
34363a51128SShuming Fan 
rt712_sdca_dmic_fu1e_capture_get(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)34463a51128SShuming Fan static int rt712_sdca_dmic_fu1e_capture_get(struct snd_kcontrol *kcontrol,
34563a51128SShuming Fan 			struct snd_ctl_elem_value *ucontrol)
34663a51128SShuming Fan {
34763a51128SShuming Fan 	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
34863a51128SShuming Fan 	struct rt712_sdca_dmic_priv *rt712 = snd_soc_component_get_drvdata(component);
34963a51128SShuming Fan 	struct rt712_sdca_dmic_kctrl_priv *p =
35063a51128SShuming Fan 		(struct rt712_sdca_dmic_kctrl_priv *)kcontrol->private_value;
35163a51128SShuming Fan 	unsigned int i;
35263a51128SShuming Fan 
35363a51128SShuming Fan 	for (i = 0; i < p->count; i++)
35463a51128SShuming Fan 		ucontrol->value.integer.value[i] = !rt712->fu1e_mixer_mute[i];
35563a51128SShuming Fan 
35663a51128SShuming Fan 	return 0;
35763a51128SShuming Fan }
35863a51128SShuming Fan 
rt712_sdca_dmic_fu1e_capture_put(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)35963a51128SShuming Fan static int rt712_sdca_dmic_fu1e_capture_put(struct snd_kcontrol *kcontrol,
36063a51128SShuming Fan 			struct snd_ctl_elem_value *ucontrol)
36163a51128SShuming Fan {
36263a51128SShuming Fan 	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
36363a51128SShuming Fan 	struct rt712_sdca_dmic_priv *rt712 = snd_soc_component_get_drvdata(component);
36463a51128SShuming Fan 	struct rt712_sdca_dmic_kctrl_priv *p =
36563a51128SShuming Fan 		(struct rt712_sdca_dmic_kctrl_priv *)kcontrol->private_value;
36663a51128SShuming Fan 	int err, changed = 0, i;
36763a51128SShuming Fan 
36863a51128SShuming Fan 	for (i = 0; i < p->count; i++) {
36963a51128SShuming Fan 		if (rt712->fu1e_mixer_mute[i] != !ucontrol->value.integer.value[i])
37063a51128SShuming Fan 			changed = 1;
37163a51128SShuming Fan 		rt712->fu1e_mixer_mute[i] = !ucontrol->value.integer.value[i];
37263a51128SShuming Fan 	}
37363a51128SShuming Fan 
37463a51128SShuming Fan 	err = rt712_sdca_set_fu1e_capture_ctl(rt712);
37563a51128SShuming Fan 	if (err < 0)
37663a51128SShuming Fan 		return err;
37763a51128SShuming Fan 
37863a51128SShuming Fan 	return changed;
37963a51128SShuming Fan }
38063a51128SShuming Fan 
rt712_sdca_fu_info(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_info * uinfo)38163a51128SShuming Fan static int rt712_sdca_fu_info(struct snd_kcontrol *kcontrol,
38263a51128SShuming Fan 	struct snd_ctl_elem_info *uinfo)
38363a51128SShuming Fan {
38463a51128SShuming Fan 	struct rt712_sdca_dmic_kctrl_priv *p =
38563a51128SShuming Fan 		(struct rt712_sdca_dmic_kctrl_priv *)kcontrol->private_value;
38663a51128SShuming Fan 
38763a51128SShuming Fan 	if (p->max == 1)
38863a51128SShuming Fan 		uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
38963a51128SShuming Fan 	else
39063a51128SShuming Fan 		uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
39163a51128SShuming Fan 	uinfo->count = p->count;
39263a51128SShuming Fan 	uinfo->value.integer.min = 0;
39363a51128SShuming Fan 	uinfo->value.integer.max = p->max;
39463a51128SShuming Fan 	return 0;
39563a51128SShuming Fan }
39663a51128SShuming Fan 
39763a51128SShuming Fan #define RT712_SDCA_PR_VALUE(xreg_base, xcount, xmax, xinvert) \
39863a51128SShuming Fan 	((unsigned long)&(struct rt712_sdca_dmic_kctrl_priv) \
39963a51128SShuming Fan 		{.reg_base = xreg_base, .count = xcount, .max = xmax, \
40063a51128SShuming Fan 		.invert = xinvert})
40163a51128SShuming Fan 
40263a51128SShuming Fan #define RT712_SDCA_FU_CTRL(xname, reg_base, xmax, xinvert, xcount) \
40363a51128SShuming Fan {	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
40463a51128SShuming Fan 	.info = rt712_sdca_fu_info, \
40563a51128SShuming Fan 	.get = rt712_sdca_dmic_fu1e_capture_get, \
40663a51128SShuming Fan 	.put = rt712_sdca_dmic_fu1e_capture_put, \
40763a51128SShuming Fan 	.private_value = RT712_SDCA_PR_VALUE(reg_base, xcount, xmax, xinvert)}
40863a51128SShuming Fan 
40963a51128SShuming Fan #define RT712_SDCA_EXT_TLV(xname, reg_base, xhandler_get,\
41063a51128SShuming Fan 	 xhandler_put, xcount, xmax, tlv_array) \
41163a51128SShuming Fan {	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
41263a51128SShuming Fan 	.access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
41363a51128SShuming Fan 		 SNDRV_CTL_ELEM_ACCESS_READWRITE, \
41463a51128SShuming Fan 	.tlv.p = (tlv_array), \
41563a51128SShuming Fan 	.info = rt712_sdca_fu_info, \
41663a51128SShuming Fan 	.get = xhandler_get, .put = xhandler_put, \
41763a51128SShuming Fan 	.private_value = RT712_SDCA_PR_VALUE(reg_base, xcount, xmax, 0) }
41863a51128SShuming Fan 
41963a51128SShuming Fan static const DECLARE_TLV_DB_SCALE(in_vol_tlv, -1725, 75, 0);
42063a51128SShuming Fan static const DECLARE_TLV_DB_SCALE(mic_vol_tlv, 0, 1000, 0);
42163a51128SShuming Fan 
42263a51128SShuming Fan static const struct snd_kcontrol_new rt712_sdca_dmic_snd_controls[] = {
42363a51128SShuming Fan 	RT712_SDCA_FU_CTRL("FU1E Capture Switch",
42463a51128SShuming Fan 		SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT712_SDCA_ENT_USER_FU1E, RT712_SDCA_CTL_FU_MUTE, CH_01),
42563a51128SShuming Fan 		1, 1, 4),
42663a51128SShuming Fan 	RT712_SDCA_EXT_TLV("FU1E Capture Volume",
42763a51128SShuming Fan 		SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT712_SDCA_ENT_USER_FU1E, RT712_SDCA_CTL_FU_VOLUME, CH_01),
42863a51128SShuming Fan 		rt712_sdca_dmic_set_gain_get, rt712_sdca_dmic_set_gain_put, 4, 0x3f, in_vol_tlv),
42963a51128SShuming Fan 	RT712_SDCA_EXT_TLV("FU15 Boost Volume",
43063a51128SShuming Fan 		SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT712_SDCA_ENT_PLATFORM_FU15, RT712_SDCA_CTL_FU_CH_GAIN, CH_01),
43163a51128SShuming Fan 		rt712_sdca_dmic_set_gain_get, rt712_sdca_dmic_set_gain_put, 4, 3, mic_vol_tlv),
43263a51128SShuming Fan };
43363a51128SShuming Fan 
rt712_sdca_dmic_mux_get(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)43463a51128SShuming Fan static int rt712_sdca_dmic_mux_get(struct snd_kcontrol *kcontrol,
43563a51128SShuming Fan 			struct snd_ctl_elem_value *ucontrol)
43663a51128SShuming Fan {
43763a51128SShuming Fan 	struct snd_soc_component *component =
43863a51128SShuming Fan 		snd_soc_dapm_kcontrol_component(kcontrol);
43963a51128SShuming Fan 	struct rt712_sdca_dmic_priv *rt712 = snd_soc_component_get_drvdata(component);
44063a51128SShuming Fan 	unsigned int val = 0, mask_sft;
44163a51128SShuming Fan 
44263a51128SShuming Fan 	if (strstr(ucontrol->id.name, "ADC 25 Mux"))
44363a51128SShuming Fan 		mask_sft = 8;
44463a51128SShuming Fan 	else if (strstr(ucontrol->id.name, "ADC 26 Mux"))
44563a51128SShuming Fan 		mask_sft = 4;
44663a51128SShuming Fan 	else
44763a51128SShuming Fan 		return -EINVAL;
44863a51128SShuming Fan 
44963a51128SShuming Fan 	rt712_sdca_dmic_index_read(rt712, RT712_VENDOR_HDA_CTL,
45063a51128SShuming Fan 		RT712_HDA_LEGACY_MUX_CTL0, &val);
45163a51128SShuming Fan 
45263a51128SShuming Fan 	ucontrol->value.enumerated.item[0] = (val >> mask_sft) & 0x7;
45363a51128SShuming Fan 
45463a51128SShuming Fan 	return 0;
45563a51128SShuming Fan }
45663a51128SShuming Fan 
rt712_sdca_dmic_mux_put(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)45763a51128SShuming Fan static int rt712_sdca_dmic_mux_put(struct snd_kcontrol *kcontrol,
45863a51128SShuming Fan 			struct snd_ctl_elem_value *ucontrol)
45963a51128SShuming Fan {
46063a51128SShuming Fan 	struct snd_soc_component *component =
46163a51128SShuming Fan 		snd_soc_dapm_kcontrol_component(kcontrol);
46263a51128SShuming Fan 	struct snd_soc_dapm_context *dapm =
46363a51128SShuming Fan 		snd_soc_dapm_kcontrol_dapm(kcontrol);
46463a51128SShuming Fan 	struct rt712_sdca_dmic_priv *rt712 = snd_soc_component_get_drvdata(component);
46563a51128SShuming Fan 	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
46663a51128SShuming Fan 	unsigned int *item = ucontrol->value.enumerated.item;
46763a51128SShuming Fan 	unsigned int val, val2 = 0, change, mask_sft;
46863a51128SShuming Fan 
46963a51128SShuming Fan 	if (item[0] >= e->items)
47063a51128SShuming Fan 		return -EINVAL;
47163a51128SShuming Fan 
47263a51128SShuming Fan 	if (strstr(ucontrol->id.name, "ADC 25 Mux"))
47363a51128SShuming Fan 		mask_sft = 8;
47463a51128SShuming Fan 	else if (strstr(ucontrol->id.name, "ADC 26 Mux"))
47563a51128SShuming Fan 		mask_sft = 4;
47663a51128SShuming Fan 	else
47763a51128SShuming Fan 		return -EINVAL;
47863a51128SShuming Fan 
47963a51128SShuming Fan 	val = snd_soc_enum_item_to_val(e, item[0]) << e->shift_l;
48063a51128SShuming Fan 
48163a51128SShuming Fan 	rt712_sdca_dmic_index_read(rt712, RT712_VENDOR_HDA_CTL,
48263a51128SShuming Fan 		RT712_HDA_LEGACY_MUX_CTL0, &val2);
48363a51128SShuming Fan 	val2 = (0x7 << mask_sft) & val2;
48463a51128SShuming Fan 
48563a51128SShuming Fan 	if (val == val2)
48663a51128SShuming Fan 		change = 0;
48763a51128SShuming Fan 	else
48863a51128SShuming Fan 		change = 1;
48963a51128SShuming Fan 
49063a51128SShuming Fan 	if (change)
49163a51128SShuming Fan 		rt712_sdca_dmic_index_update_bits(rt712, RT712_VENDOR_HDA_CTL,
49263a51128SShuming Fan 			RT712_HDA_LEGACY_MUX_CTL0, 0x7 << mask_sft,
49363a51128SShuming Fan 			val << mask_sft);
49463a51128SShuming Fan 
49563a51128SShuming Fan 	snd_soc_dapm_mux_update_power(dapm, kcontrol,
49663a51128SShuming Fan 		item[0], e, NULL);
49763a51128SShuming Fan 
49863a51128SShuming Fan 	return change;
49963a51128SShuming Fan }
50063a51128SShuming Fan 
50163a51128SShuming Fan static const char * const adc_mux_text[] = {
50263a51128SShuming Fan 	"DMIC1",
50363a51128SShuming Fan 	"DMIC2",
50463a51128SShuming Fan };
50563a51128SShuming Fan 
50663a51128SShuming Fan static SOC_ENUM_SINGLE_DECL(
50763a51128SShuming Fan 	rt712_adc25_enum, SND_SOC_NOPM, 0, adc_mux_text);
50863a51128SShuming Fan 
50963a51128SShuming Fan static SOC_ENUM_SINGLE_DECL(
51063a51128SShuming Fan 	rt712_adc26_enum, SND_SOC_NOPM, 0, adc_mux_text);
51163a51128SShuming Fan 
51263a51128SShuming Fan static const struct snd_kcontrol_new rt712_sdca_dmic_adc25_mux =
51363a51128SShuming Fan 	SOC_DAPM_ENUM_EXT("ADC 25 Mux", rt712_adc25_enum,
51463a51128SShuming Fan 			rt712_sdca_dmic_mux_get, rt712_sdca_dmic_mux_put);
51563a51128SShuming Fan 
51663a51128SShuming Fan static const struct snd_kcontrol_new rt712_sdca_dmic_adc26_mux =
51763a51128SShuming Fan 	SOC_DAPM_ENUM_EXT("ADC 26 Mux", rt712_adc26_enum,
51863a51128SShuming Fan 			rt712_sdca_dmic_mux_get, rt712_sdca_dmic_mux_put);
51963a51128SShuming Fan 
rt712_sdca_dmic_fu1e_event(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kcontrol,int event)52063a51128SShuming Fan static int rt712_sdca_dmic_fu1e_event(struct snd_soc_dapm_widget *w,
52163a51128SShuming Fan 	struct snd_kcontrol *kcontrol, int event)
52263a51128SShuming Fan {
52363a51128SShuming Fan 	struct snd_soc_component *component =
52463a51128SShuming Fan 		snd_soc_dapm_to_component(w->dapm);
52563a51128SShuming Fan 	struct rt712_sdca_dmic_priv *rt712 = snd_soc_component_get_drvdata(component);
52663a51128SShuming Fan 
52763a51128SShuming Fan 	switch (event) {
52863a51128SShuming Fan 	case SND_SOC_DAPM_POST_PMU:
52963a51128SShuming Fan 		rt712->fu1e_dapm_mute = false;
53063a51128SShuming Fan 		rt712_sdca_set_fu1e_capture_ctl(rt712);
53163a51128SShuming Fan 		break;
53263a51128SShuming Fan 	case SND_SOC_DAPM_PRE_PMD:
53363a51128SShuming Fan 		rt712->fu1e_dapm_mute = true;
53463a51128SShuming Fan 		rt712_sdca_set_fu1e_capture_ctl(rt712);
53563a51128SShuming Fan 		break;
53663a51128SShuming Fan 	}
53763a51128SShuming Fan 	return 0;
53863a51128SShuming Fan }
53963a51128SShuming Fan 
rt712_sdca_dmic_pde11_event(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kcontrol,int event)54063a51128SShuming Fan static int rt712_sdca_dmic_pde11_event(struct snd_soc_dapm_widget *w,
54163a51128SShuming Fan 	struct snd_kcontrol *kcontrol, int event)
54263a51128SShuming Fan {
54363a51128SShuming Fan 	struct snd_soc_component *component =
54463a51128SShuming Fan 		snd_soc_dapm_to_component(w->dapm);
54563a51128SShuming Fan 	struct rt712_sdca_dmic_priv *rt712 = snd_soc_component_get_drvdata(component);
54663a51128SShuming Fan 	unsigned char ps0 = 0x0, ps3 = 0x3;
54763a51128SShuming Fan 
54863a51128SShuming Fan 	switch (event) {
54963a51128SShuming Fan 	case SND_SOC_DAPM_POST_PMU:
55063a51128SShuming Fan 		regmap_write(rt712->regmap,
55163a51128SShuming Fan 			SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT712_SDCA_ENT_PDE11,
55263a51128SShuming Fan 				RT712_SDCA_CTL_REQ_POWER_STATE, 0),
55363a51128SShuming Fan 				ps0);
55463a51128SShuming Fan 		break;
55563a51128SShuming Fan 	case SND_SOC_DAPM_PRE_PMD:
55663a51128SShuming Fan 		regmap_write(rt712->regmap,
55763a51128SShuming Fan 			SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT712_SDCA_ENT_PDE11,
55863a51128SShuming Fan 				RT712_SDCA_CTL_REQ_POWER_STATE, 0),
55963a51128SShuming Fan 				ps3);
56063a51128SShuming Fan 		break;
56163a51128SShuming Fan 	}
56263a51128SShuming Fan 	return 0;
56363a51128SShuming Fan }
56463a51128SShuming Fan 
56563a51128SShuming Fan static const struct snd_soc_dapm_widget rt712_sdca_dmic_dapm_widgets[] = {
56663a51128SShuming Fan 	SND_SOC_DAPM_INPUT("DMIC1"),
56763a51128SShuming Fan 	SND_SOC_DAPM_INPUT("DMIC2"),
56863a51128SShuming Fan 
56963a51128SShuming Fan 	SND_SOC_DAPM_SUPPLY("PDE 11", SND_SOC_NOPM, 0, 0,
57063a51128SShuming Fan 		rt712_sdca_dmic_pde11_event,
57163a51128SShuming Fan 		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
57263a51128SShuming Fan 
57363a51128SShuming Fan 	SND_SOC_DAPM_ADC_E("FU 1E", NULL, SND_SOC_NOPM, 0, 0,
57463a51128SShuming Fan 		rt712_sdca_dmic_fu1e_event,
57563a51128SShuming Fan 		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
57663a51128SShuming Fan 	SND_SOC_DAPM_MUX("ADC 25 Mux", SND_SOC_NOPM, 0, 0,
57763a51128SShuming Fan 		&rt712_sdca_dmic_adc25_mux),
57863a51128SShuming Fan 	SND_SOC_DAPM_MUX("ADC 26 Mux", SND_SOC_NOPM, 0, 0,
57963a51128SShuming Fan 		&rt712_sdca_dmic_adc26_mux),
58063a51128SShuming Fan 
58163a51128SShuming Fan 	SND_SOC_DAPM_AIF_OUT("DP2TX", "DP2 Capture", 0, SND_SOC_NOPM, 0, 0),
58263a51128SShuming Fan };
58363a51128SShuming Fan 
58463a51128SShuming Fan static const struct snd_soc_dapm_route rt712_sdca_dmic_audio_map[] = {
58563a51128SShuming Fan 	{"DP2TX", NULL, "FU 1E"},
58663a51128SShuming Fan 
58763a51128SShuming Fan 	{"FU 1E", NULL, "PDE 11"},
58863a51128SShuming Fan 	{"FU 1E", NULL, "ADC 25 Mux"},
58963a51128SShuming Fan 	{"FU 1E", NULL, "ADC 26 Mux"},
59063a51128SShuming Fan 	{"ADC 25 Mux", "DMIC1", "DMIC1"},
59163a51128SShuming Fan 	{"ADC 25 Mux", "DMIC2", "DMIC2"},
59263a51128SShuming Fan 	{"ADC 26 Mux", "DMIC1", "DMIC1"},
59363a51128SShuming Fan 	{"ADC 26 Mux", "DMIC2", "DMIC2"},
59463a51128SShuming Fan };
59563a51128SShuming Fan 
rt712_sdca_dmic_probe(struct snd_soc_component * component)59663a51128SShuming Fan static int rt712_sdca_dmic_probe(struct snd_soc_component *component)
59763a51128SShuming Fan {
59863a51128SShuming Fan 	struct rt712_sdca_dmic_priv *rt712 = snd_soc_component_get_drvdata(component);
59963a51128SShuming Fan 	int ret;
60063a51128SShuming Fan 
60163a51128SShuming Fan 	rt712->component = component;
60263a51128SShuming Fan 
6038d890eceSPierre-Louis Bossart 	if (!rt712->first_hw_init)
6048d890eceSPierre-Louis Bossart 		return 0;
6058d890eceSPierre-Louis Bossart 
60663a51128SShuming Fan 	ret = pm_runtime_resume(component->dev);
60763a51128SShuming Fan 	if (ret < 0 && ret != -EACCES)
60863a51128SShuming Fan 		return ret;
60963a51128SShuming Fan 
61063a51128SShuming Fan 	return 0;
61163a51128SShuming Fan }
61263a51128SShuming Fan 
61363a51128SShuming Fan static const struct snd_soc_component_driver soc_sdca_dev_rt712_dmic = {
61463a51128SShuming Fan 	.probe = rt712_sdca_dmic_probe,
61563a51128SShuming Fan 	.controls = rt712_sdca_dmic_snd_controls,
61663a51128SShuming Fan 	.num_controls = ARRAY_SIZE(rt712_sdca_dmic_snd_controls),
61763a51128SShuming Fan 	.dapm_widgets = rt712_sdca_dmic_dapm_widgets,
61863a51128SShuming Fan 	.num_dapm_widgets = ARRAY_SIZE(rt712_sdca_dmic_dapm_widgets),
61963a51128SShuming Fan 	.dapm_routes = rt712_sdca_dmic_audio_map,
62063a51128SShuming Fan 	.num_dapm_routes = ARRAY_SIZE(rt712_sdca_dmic_audio_map),
62163a51128SShuming Fan 	.endianness = 1,
62263a51128SShuming Fan };
62363a51128SShuming Fan 
rt712_sdca_dmic_set_sdw_stream(struct snd_soc_dai * dai,void * sdw_stream,int direction)62463a51128SShuming Fan static int rt712_sdca_dmic_set_sdw_stream(struct snd_soc_dai *dai, void *sdw_stream,
62563a51128SShuming Fan 				int direction)
62663a51128SShuming Fan {
62763a51128SShuming Fan 	snd_soc_dai_dma_data_set(dai, direction, sdw_stream);
62863a51128SShuming Fan 
62963a51128SShuming Fan 	return 0;
63063a51128SShuming Fan }
63163a51128SShuming Fan 
rt712_sdca_dmic_shutdown(struct snd_pcm_substream * substream,struct snd_soc_dai * dai)63263a51128SShuming Fan static void rt712_sdca_dmic_shutdown(struct snd_pcm_substream *substream,
63363a51128SShuming Fan 				struct snd_soc_dai *dai)
63463a51128SShuming Fan {
63563a51128SShuming Fan 	snd_soc_dai_set_dma_data(dai, substream, NULL);
63663a51128SShuming Fan }
63763a51128SShuming Fan 
rt712_sdca_dmic_hw_params(struct snd_pcm_substream * substream,struct snd_pcm_hw_params * params,struct snd_soc_dai * dai)63863a51128SShuming Fan static int rt712_sdca_dmic_hw_params(struct snd_pcm_substream *substream,
63963a51128SShuming Fan 				struct snd_pcm_hw_params *params,
64063a51128SShuming Fan 				struct snd_soc_dai *dai)
64163a51128SShuming Fan {
64263a51128SShuming Fan 	struct snd_soc_component *component = dai->component;
64363a51128SShuming Fan 	struct rt712_sdca_dmic_priv *rt712 = snd_soc_component_get_drvdata(component);
64463a51128SShuming Fan 	struct sdw_stream_config stream_config;
64563a51128SShuming Fan 	struct sdw_port_config port_config;
64663a51128SShuming Fan 	struct sdw_stream_runtime *sdw_stream;
64763a51128SShuming Fan 	int retval, num_channels;
64863a51128SShuming Fan 	unsigned int sampling_rate;
64963a51128SShuming Fan 
65063a51128SShuming Fan 	dev_dbg(dai->dev, "%s %s", __func__, dai->name);
65163a51128SShuming Fan 	sdw_stream = snd_soc_dai_get_dma_data(dai, substream);
65263a51128SShuming Fan 
65363a51128SShuming Fan 	if (!sdw_stream)
65463a51128SShuming Fan 		return -EINVAL;
65563a51128SShuming Fan 
65663a51128SShuming Fan 	if (!rt712->slave)
65763a51128SShuming Fan 		return -EINVAL;
65863a51128SShuming Fan 
65963a51128SShuming Fan 	stream_config.frame_rate = params_rate(params);
66063a51128SShuming Fan 	stream_config.ch_count = params_channels(params);
66163a51128SShuming Fan 	stream_config.bps = snd_pcm_format_width(params_format(params));
66263a51128SShuming Fan 	stream_config.direction = SDW_DATA_DIR_TX;
66363a51128SShuming Fan 
66463a51128SShuming Fan 	num_channels = params_channels(params);
66563a51128SShuming Fan 	port_config.ch_mask = GENMASK(num_channels - 1, 0);
66663a51128SShuming Fan 	port_config.num = 2;
66763a51128SShuming Fan 
66863a51128SShuming Fan 	retval = sdw_stream_add_slave(rt712->slave, &stream_config,
66963a51128SShuming Fan 					&port_config, 1, sdw_stream);
67063a51128SShuming Fan 	if (retval) {
671*f892e66fSPierre-Louis Bossart 		dev_err(dai->dev, "%s: Unable to configure port\n", __func__);
67263a51128SShuming Fan 		return retval;
67363a51128SShuming Fan 	}
67463a51128SShuming Fan 
67563a51128SShuming Fan 	if (params_channels(params) > 4) {
676*f892e66fSPierre-Louis Bossart 		dev_err(component->dev, "%s: Unsupported channels %d\n",
677*f892e66fSPierre-Louis Bossart 			__func__, params_channels(params));
67863a51128SShuming Fan 		return -EINVAL;
67963a51128SShuming Fan 	}
68063a51128SShuming Fan 
68163a51128SShuming Fan 	/* sampling rate configuration */
68263a51128SShuming Fan 	switch (params_rate(params)) {
68363a51128SShuming Fan 	case 16000:
68463a51128SShuming Fan 		sampling_rate = RT712_SDCA_RATE_16000HZ;
68563a51128SShuming Fan 		break;
68663a51128SShuming Fan 	case 32000:
68763a51128SShuming Fan 		sampling_rate = RT712_SDCA_RATE_32000HZ;
68863a51128SShuming Fan 		break;
68963a51128SShuming Fan 	case 44100:
69063a51128SShuming Fan 		sampling_rate = RT712_SDCA_RATE_44100HZ;
69163a51128SShuming Fan 		break;
69263a51128SShuming Fan 	case 48000:
69363a51128SShuming Fan 		sampling_rate = RT712_SDCA_RATE_48000HZ;
69463a51128SShuming Fan 		break;
69563a51128SShuming Fan 	case 96000:
69663a51128SShuming Fan 		sampling_rate = RT712_SDCA_RATE_96000HZ;
69763a51128SShuming Fan 		break;
69863a51128SShuming Fan 	case 192000:
69963a51128SShuming Fan 		sampling_rate = RT712_SDCA_RATE_192000HZ;
70063a51128SShuming Fan 		break;
70163a51128SShuming Fan 	default:
702*f892e66fSPierre-Louis Bossart 		dev_err(component->dev, "%s: Rate %d is not supported\n",
703*f892e66fSPierre-Louis Bossart 			__func__, params_rate(params));
70463a51128SShuming Fan 		return -EINVAL;
70563a51128SShuming Fan 	}
70663a51128SShuming Fan 
70763a51128SShuming Fan 	/* set sampling frequency */
70863a51128SShuming Fan 	regmap_write(rt712->regmap,
70963a51128SShuming Fan 		SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT712_SDCA_ENT_CS1F, RT712_SDCA_CTL_SAMPLE_FREQ_INDEX, 0),
71063a51128SShuming Fan 		sampling_rate);
71163a51128SShuming Fan 	regmap_write(rt712->regmap,
71263a51128SShuming Fan 		SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT712_SDCA_ENT_CS1C, RT712_SDCA_CTL_SAMPLE_FREQ_INDEX, 0),
71363a51128SShuming Fan 		sampling_rate);
71463a51128SShuming Fan 
71563a51128SShuming Fan 	return 0;
71663a51128SShuming Fan }
71763a51128SShuming Fan 
rt712_sdca_dmic_hw_free(struct snd_pcm_substream * substream,struct snd_soc_dai * dai)71863a51128SShuming Fan static int rt712_sdca_dmic_hw_free(struct snd_pcm_substream *substream,
71963a51128SShuming Fan 				struct snd_soc_dai *dai)
72063a51128SShuming Fan {
72163a51128SShuming Fan 	struct snd_soc_component *component = dai->component;
72263a51128SShuming Fan 	struct rt712_sdca_dmic_priv *rt712 = snd_soc_component_get_drvdata(component);
72363a51128SShuming Fan 	struct sdw_stream_runtime *sdw_stream =
72463a51128SShuming Fan 		snd_soc_dai_get_dma_data(dai, substream);
72563a51128SShuming Fan 
72663a51128SShuming Fan 	if (!rt712->slave)
72763a51128SShuming Fan 		return -EINVAL;
72863a51128SShuming Fan 
72963a51128SShuming Fan 	sdw_stream_remove_slave(rt712->slave, sdw_stream);
73063a51128SShuming Fan 	return 0;
73163a51128SShuming Fan }
73263a51128SShuming Fan 
73363a51128SShuming Fan #define RT712_STEREO_RATES (SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \
73463a51128SShuming Fan 			SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000)
73563a51128SShuming Fan #define RT712_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
73663a51128SShuming Fan 			SNDRV_PCM_FMTBIT_S24_LE)
73763a51128SShuming Fan 
73863a51128SShuming Fan static const struct snd_soc_dai_ops rt712_sdca_dmic_ops = {
73963a51128SShuming Fan 	.hw_params	= rt712_sdca_dmic_hw_params,
74063a51128SShuming Fan 	.hw_free	= rt712_sdca_dmic_hw_free,
74163a51128SShuming Fan 	.set_stream	= rt712_sdca_dmic_set_sdw_stream,
74263a51128SShuming Fan 	.shutdown	= rt712_sdca_dmic_shutdown,
74363a51128SShuming Fan };
74463a51128SShuming Fan 
74563a51128SShuming Fan static struct snd_soc_dai_driver rt712_sdca_dmic_dai[] = {
74663a51128SShuming Fan 	{
74763a51128SShuming Fan 		.name = "rt712-sdca-dmic-aif1",
74863a51128SShuming Fan 		.id = RT712_AIF1,
74963a51128SShuming Fan 		.capture = {
75063a51128SShuming Fan 			.stream_name = "DP2 Capture",
75163a51128SShuming Fan 			.channels_min = 1,
75263a51128SShuming Fan 			.channels_max = 4,
75363a51128SShuming Fan 			.rates = RT712_STEREO_RATES,
75463a51128SShuming Fan 			.formats = RT712_FORMATS,
75563a51128SShuming Fan 		},
75663a51128SShuming Fan 		.ops = &rt712_sdca_dmic_ops,
75763a51128SShuming Fan 	},
75863a51128SShuming Fan };
75963a51128SShuming Fan 
rt712_sdca_dmic_init(struct device * dev,struct regmap * regmap,struct regmap * mbq_regmap,struct sdw_slave * slave)76063a51128SShuming Fan static int rt712_sdca_dmic_init(struct device *dev, struct regmap *regmap,
76163a51128SShuming Fan 			struct regmap *mbq_regmap, struct sdw_slave *slave)
76263a51128SShuming Fan {
76363a51128SShuming Fan 	struct rt712_sdca_dmic_priv *rt712;
76463a51128SShuming Fan 	int ret;
76563a51128SShuming Fan 
76663a51128SShuming Fan 	rt712 = devm_kzalloc(dev, sizeof(*rt712), GFP_KERNEL);
76763a51128SShuming Fan 	if (!rt712)
76863a51128SShuming Fan 		return -ENOMEM;
76963a51128SShuming Fan 
77063a51128SShuming Fan 	dev_set_drvdata(dev, rt712);
77163a51128SShuming Fan 	rt712->slave = slave;
77263a51128SShuming Fan 	rt712->regmap = regmap;
77363a51128SShuming Fan 	rt712->mbq_regmap = mbq_regmap;
77463a51128SShuming Fan 
77549ae74abSPierre-Louis Bossart 	regcache_cache_only(rt712->regmap, true);
77649ae74abSPierre-Louis Bossart 	regcache_cache_only(rt712->mbq_regmap, true);
77749ae74abSPierre-Louis Bossart 
77863a51128SShuming Fan 	/*
77963a51128SShuming Fan 	 * Mark hw_init to false
78063a51128SShuming Fan 	 * HW init will be performed when device reports present
78163a51128SShuming Fan 	 */
78263a51128SShuming Fan 	rt712->hw_init = false;
78363a51128SShuming Fan 	rt712->first_hw_init = false;
78463a51128SShuming Fan 	rt712->fu1e_dapm_mute = true;
78563a51128SShuming Fan 	rt712->fu1e_mixer_mute[0] = rt712->fu1e_mixer_mute[1] =
78663a51128SShuming Fan 		rt712->fu1e_mixer_mute[2] = rt712->fu1e_mixer_mute[3] = true;
78763a51128SShuming Fan 
78863a51128SShuming Fan 	ret =  devm_snd_soc_register_component(dev,
78963a51128SShuming Fan 			&soc_sdca_dev_rt712_dmic,
79063a51128SShuming Fan 			rt712_sdca_dmic_dai,
79163a51128SShuming Fan 			ARRAY_SIZE(rt712_sdca_dmic_dai));
7928d890eceSPierre-Louis Bossart 	if (ret < 0)
79363a51128SShuming Fan 		return ret;
7948d890eceSPierre-Louis Bossart 
7958d890eceSPierre-Louis Bossart 	/* set autosuspend parameters */
7968d890eceSPierre-Louis Bossart 	pm_runtime_set_autosuspend_delay(dev, 3000);
7978d890eceSPierre-Louis Bossart 	pm_runtime_use_autosuspend(dev);
7988d890eceSPierre-Louis Bossart 
7998d890eceSPierre-Louis Bossart 	/* make sure the device does not suspend immediately */
8008d890eceSPierre-Louis Bossart 	pm_runtime_mark_last_busy(dev);
8018d890eceSPierre-Louis Bossart 
8028d890eceSPierre-Louis Bossart 	pm_runtime_enable(dev);
8038d890eceSPierre-Louis Bossart 
8048d890eceSPierre-Louis Bossart 	/* important note: the device is NOT tagged as 'active' and will remain
8058d890eceSPierre-Louis Bossart 	 * 'suspended' until the hardware is enumerated/initialized. This is required
8068d890eceSPierre-Louis Bossart 	 * to make sure the ASoC framework use of pm_runtime_get_sync() does not silently
8078d890eceSPierre-Louis Bossart 	 * fail with -EACCESS because of race conditions between card creation and enumeration
8088d890eceSPierre-Louis Bossart 	 */
8098d890eceSPierre-Louis Bossart 
8108d890eceSPierre-Louis Bossart 	dev_dbg(dev, "%s\n", __func__);
8118d890eceSPierre-Louis Bossart 
8128d890eceSPierre-Louis Bossart 	return 0;
81363a51128SShuming Fan }
81463a51128SShuming Fan 
81563a51128SShuming Fan 
rt712_sdca_dmic_update_status(struct sdw_slave * slave,enum sdw_slave_status status)81663a51128SShuming Fan static int rt712_sdca_dmic_update_status(struct sdw_slave *slave,
81763a51128SShuming Fan 				enum sdw_slave_status status)
81863a51128SShuming Fan {
81963a51128SShuming Fan 	struct rt712_sdca_dmic_priv *rt712 = dev_get_drvdata(&slave->dev);
82063a51128SShuming Fan 
82163a51128SShuming Fan 	if (status == SDW_SLAVE_UNATTACHED)
82263a51128SShuming Fan 		rt712->hw_init = false;
82363a51128SShuming Fan 
82463a51128SShuming Fan 	/*
82563a51128SShuming Fan 	 * Perform initialization only if slave status is present and
82663a51128SShuming Fan 	 * hw_init flag is false
82763a51128SShuming Fan 	 */
828d7a79616SKrzysztof Kozlowski 	if (rt712->hw_init || status != SDW_SLAVE_ATTACHED)
82963a51128SShuming Fan 		return 0;
83063a51128SShuming Fan 
83163a51128SShuming Fan 	/* perform I/O transfers required for Slave initialization */
83263a51128SShuming Fan 	return rt712_sdca_dmic_io_init(&slave->dev, slave);
83363a51128SShuming Fan }
83463a51128SShuming Fan 
rt712_sdca_dmic_read_prop(struct sdw_slave * slave)83563a51128SShuming Fan static int rt712_sdca_dmic_read_prop(struct sdw_slave *slave)
83663a51128SShuming Fan {
83763a51128SShuming Fan 	struct sdw_slave_prop *prop = &slave->prop;
83863a51128SShuming Fan 	int nval, i;
83963a51128SShuming Fan 	u32 bit;
84063a51128SShuming Fan 	unsigned long addr;
84163a51128SShuming Fan 	struct sdw_dpn_prop *dpn;
84263a51128SShuming Fan 
84363a51128SShuming Fan 	prop->scp_int1_mask = SDW_SCP_INT1_BUS_CLASH | SDW_SCP_INT1_PARITY;
84463a51128SShuming Fan 	prop->quirks = SDW_SLAVE_QUIRKS_INVALID_INITIAL_PARITY;
84563a51128SShuming Fan 
84663a51128SShuming Fan 	prop->paging_support = true;
84763a51128SShuming Fan 
84863a51128SShuming Fan 	/* first we need to allocate memory for set bits in port lists */
84963a51128SShuming Fan 	prop->source_ports = BIT(2); /* BITMAP: 00000100 */
85063a51128SShuming Fan 	prop->sink_ports = 0;
85163a51128SShuming Fan 
85263a51128SShuming Fan 	nval = hweight32(prop->source_ports);
85363a51128SShuming Fan 	prop->src_dpn_prop = devm_kcalloc(&slave->dev, nval,
85463a51128SShuming Fan 		sizeof(*prop->src_dpn_prop), GFP_KERNEL);
85563a51128SShuming Fan 	if (!prop->src_dpn_prop)
85663a51128SShuming Fan 		return -ENOMEM;
85763a51128SShuming Fan 
85863a51128SShuming Fan 	i = 0;
85963a51128SShuming Fan 	dpn = prop->src_dpn_prop;
86063a51128SShuming Fan 	addr = prop->source_ports;
86163a51128SShuming Fan 	for_each_set_bit(bit, &addr, 32) {
86263a51128SShuming Fan 		dpn[i].num = bit;
86363a51128SShuming Fan 		dpn[i].type = SDW_DPN_FULL;
86463a51128SShuming Fan 		dpn[i].simple_ch_prep_sm = true;
86563a51128SShuming Fan 		dpn[i].ch_prep_timeout = 10;
86663a51128SShuming Fan 		i++;
86763a51128SShuming Fan 	}
86863a51128SShuming Fan 
86963a51128SShuming Fan 	/* set the timeout values */
87063a51128SShuming Fan 	prop->clk_stop_timeout = 200;
87163a51128SShuming Fan 
87263a51128SShuming Fan 	/* wake-up event */
87363a51128SShuming Fan 	prop->wake_capable = 1;
87463a51128SShuming Fan 
87563a51128SShuming Fan 	return 0;
87663a51128SShuming Fan }
87763a51128SShuming Fan 
87863a51128SShuming Fan static const struct sdw_device_id rt712_sdca_dmic_id[] = {
87963a51128SShuming Fan 	SDW_SLAVE_ENTRY_EXT(0x025d, 0x1712, 0x3, 0x1, 0),
88063a51128SShuming Fan 	SDW_SLAVE_ENTRY_EXT(0x025d, 0x1713, 0x3, 0x1, 0),
88163a51128SShuming Fan 	SDW_SLAVE_ENTRY_EXT(0x025d, 0x1716, 0x3, 0x1, 0),
88263a51128SShuming Fan 	SDW_SLAVE_ENTRY_EXT(0x025d, 0x1717, 0x3, 0x1, 0),
88363a51128SShuming Fan 	{},
88463a51128SShuming Fan };
88563a51128SShuming Fan MODULE_DEVICE_TABLE(sdw, rt712_sdca_dmic_id);
88663a51128SShuming Fan 
rt712_sdca_dmic_dev_suspend(struct device * dev)88763a51128SShuming Fan static int __maybe_unused rt712_sdca_dmic_dev_suspend(struct device *dev)
88863a51128SShuming Fan {
88963a51128SShuming Fan 	struct rt712_sdca_dmic_priv *rt712 = dev_get_drvdata(dev);
89063a51128SShuming Fan 
89163a51128SShuming Fan 	if (!rt712->hw_init)
89263a51128SShuming Fan 		return 0;
89363a51128SShuming Fan 
89463a51128SShuming Fan 	regcache_cache_only(rt712->regmap, true);
89563a51128SShuming Fan 	regcache_cache_only(rt712->mbq_regmap, true);
89663a51128SShuming Fan 
89763a51128SShuming Fan 	return 0;
89863a51128SShuming Fan }
89963a51128SShuming Fan 
rt712_sdca_dmic_dev_system_suspend(struct device * dev)90063a51128SShuming Fan static int __maybe_unused rt712_sdca_dmic_dev_system_suspend(struct device *dev)
90163a51128SShuming Fan {
90263a51128SShuming Fan 	struct rt712_sdca_dmic_priv *rt712_sdca = dev_get_drvdata(dev);
90363a51128SShuming Fan 
90463a51128SShuming Fan 	if (!rt712_sdca->hw_init)
90563a51128SShuming Fan 		return 0;
90663a51128SShuming Fan 
90763a51128SShuming Fan 	return rt712_sdca_dmic_dev_suspend(dev);
90863a51128SShuming Fan }
90963a51128SShuming Fan 
91063a51128SShuming Fan #define RT712_PROBE_TIMEOUT 5000
91163a51128SShuming Fan 
rt712_sdca_dmic_dev_resume(struct device * dev)91263a51128SShuming Fan static int __maybe_unused rt712_sdca_dmic_dev_resume(struct device *dev)
91363a51128SShuming Fan {
91463a51128SShuming Fan 	struct sdw_slave *slave = dev_to_sdw_dev(dev);
91563a51128SShuming Fan 	struct rt712_sdca_dmic_priv *rt712 = dev_get_drvdata(dev);
91663a51128SShuming Fan 	unsigned long time;
91763a51128SShuming Fan 
91863a51128SShuming Fan 	if (!rt712->first_hw_init)
91963a51128SShuming Fan 		return 0;
92063a51128SShuming Fan 
92163a51128SShuming Fan 	if (!slave->unattach_request)
92263a51128SShuming Fan 		goto regmap_sync;
92363a51128SShuming Fan 
92463a51128SShuming Fan 	time = wait_for_completion_timeout(&slave->initialization_complete,
92563a51128SShuming Fan 				msecs_to_jiffies(RT712_PROBE_TIMEOUT));
92663a51128SShuming Fan 	if (!time) {
927*f892e66fSPierre-Louis Bossart 		dev_err(&slave->dev, "%s: Initialization not complete, timed out\n",
928*f892e66fSPierre-Louis Bossart 			__func__);
92963a51128SShuming Fan 		sdw_show_ping_status(slave->bus, true);
93063a51128SShuming Fan 
93163a51128SShuming Fan 		return -ETIMEDOUT;
93263a51128SShuming Fan 	}
93363a51128SShuming Fan 
93463a51128SShuming Fan regmap_sync:
93563a51128SShuming Fan 	slave->unattach_request = 0;
93663a51128SShuming Fan 	regcache_cache_only(rt712->regmap, false);
93763a51128SShuming Fan 	regcache_sync(rt712->regmap);
93863a51128SShuming Fan 	regcache_cache_only(rt712->mbq_regmap, false);
93963a51128SShuming Fan 	regcache_sync(rt712->mbq_regmap);
94063a51128SShuming Fan 	return 0;
94163a51128SShuming Fan }
94263a51128SShuming Fan 
94363a51128SShuming Fan static const struct dev_pm_ops rt712_sdca_dmic_pm = {
94463a51128SShuming Fan 	SET_SYSTEM_SLEEP_PM_OPS(rt712_sdca_dmic_dev_system_suspend, rt712_sdca_dmic_dev_resume)
94563a51128SShuming Fan 	SET_RUNTIME_PM_OPS(rt712_sdca_dmic_dev_suspend, rt712_sdca_dmic_dev_resume, NULL)
94663a51128SShuming Fan };
94763a51128SShuming Fan 
94863a51128SShuming Fan 
949fd38b4e4SKrzysztof Kozlowski static const struct sdw_slave_ops rt712_sdca_dmic_slave_ops = {
95063a51128SShuming Fan 	.read_prop = rt712_sdca_dmic_read_prop,
95163a51128SShuming Fan 	.update_status = rt712_sdca_dmic_update_status,
95263a51128SShuming Fan };
95363a51128SShuming Fan 
rt712_sdca_dmic_sdw_probe(struct sdw_slave * slave,const struct sdw_device_id * id)95463a51128SShuming Fan static int rt712_sdca_dmic_sdw_probe(struct sdw_slave *slave,
95563a51128SShuming Fan 				const struct sdw_device_id *id)
95663a51128SShuming Fan {
95763a51128SShuming Fan 	struct regmap *regmap, *mbq_regmap;
95863a51128SShuming Fan 
95963a51128SShuming Fan 	/* Regmap Initialization */
96063a51128SShuming Fan 	mbq_regmap = devm_regmap_init_sdw_mbq(slave, &rt712_sdca_dmic_mbq_regmap);
96163a51128SShuming Fan 	if (IS_ERR(mbq_regmap))
96263a51128SShuming Fan 		return PTR_ERR(mbq_regmap);
96363a51128SShuming Fan 
96463a51128SShuming Fan 	regmap = devm_regmap_init_sdw(slave, &rt712_sdca_dmic_regmap);
96563a51128SShuming Fan 	if (IS_ERR(regmap))
96663a51128SShuming Fan 		return PTR_ERR(regmap);
96763a51128SShuming Fan 
96863a51128SShuming Fan 	return rt712_sdca_dmic_init(&slave->dev, regmap, mbq_regmap, slave);
96963a51128SShuming Fan }
97063a51128SShuming Fan 
rt712_sdca_dmic_sdw_remove(struct sdw_slave * slave)97163a51128SShuming Fan static int rt712_sdca_dmic_sdw_remove(struct sdw_slave *slave)
97263a51128SShuming Fan {
97363a51128SShuming Fan 	pm_runtime_disable(&slave->dev);
97463a51128SShuming Fan 
97563a51128SShuming Fan 	return 0;
97663a51128SShuming Fan }
97763a51128SShuming Fan 
97863a51128SShuming Fan static struct sdw_driver rt712_sdca_dmic_sdw_driver = {
97963a51128SShuming Fan 	.driver = {
98063a51128SShuming Fan 		.name = "rt712-sdca-dmic",
98163a51128SShuming Fan 		.pm = &rt712_sdca_dmic_pm,
98263a51128SShuming Fan 	},
98363a51128SShuming Fan 	.probe = rt712_sdca_dmic_sdw_probe,
98463a51128SShuming Fan 	.remove = rt712_sdca_dmic_sdw_remove,
98563a51128SShuming Fan 	.ops = &rt712_sdca_dmic_slave_ops,
98663a51128SShuming Fan 	.id_table = rt712_sdca_dmic_id,
98763a51128SShuming Fan };
98863a51128SShuming Fan module_sdw_driver(rt712_sdca_dmic_sdw_driver);
98963a51128SShuming Fan 
99063a51128SShuming Fan MODULE_DESCRIPTION("ASoC RT712 SDCA DMIC SDW driver");
99163a51128SShuming Fan MODULE_AUTHOR("Shuming Fan <shumingf@realtek.com>");
99263a51128SShuming Fan MODULE_LICENSE("GPL");
993