Unverified Commit 4e82971f authored by Kevin Lu's avatar Kevin Lu Committed by Mark Brown
Browse files

ASoC: tlv320adcx140: Add a new kcontrol



Add a new kcontrol for phase calib

Signed-off-by: default avatarKevin Lu <luminlong@139.com>
Link: https://lore.kernel.org/r/20220815112715.21617-1-luminlong@139.com


Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent ea15d3bd
Loading
Loading
Loading
Loading
+59 −0
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ struct adcx140_priv {
	struct device *dev;

	bool micbias_vg;
	bool phase_calib_on;

	unsigned int dai_fmt;
	unsigned int slot_width;
@@ -592,6 +593,52 @@ static const struct snd_soc_dapm_route adcx140_audio_map[] = {
	{"MIC4M Input Mux", "Digital", "MIC4M"},
};

#define ADCX140_PHASE_CALIB_SWITCH(xname) {\
	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,\
	.info = adcx140_phase_calib_info, \
	.get = adcx140_phase_calib_get, \
	.put = adcx140_phase_calib_put}

static int adcx140_phase_calib_info(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_info *uinfo)
{
	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
	uinfo->count = 1;
	uinfo->value.integer.min = 0;
	uinfo->value.integer.max = 1;
	return 0;
}

static int adcx140_phase_calib_get(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *value)
{
	struct snd_soc_component *codec =
		snd_soc_kcontrol_component(kcontrol);
	struct adcx140_priv *adcx140 = snd_soc_component_get_drvdata(codec);

	value->value.integer.value[0] = adcx140->phase_calib_on ? 1 : 0;


	return 0;
}

static int adcx140_phase_calib_put(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *value)
{
	struct snd_soc_component *codec
		= snd_soc_kcontrol_component(kcontrol);
	struct adcx140_priv *adcx140 = snd_soc_component_get_drvdata(codec);

	bool v = value->value.integer.value[0] ? true : false;

	if (adcx140->phase_calib_on != v) {
		adcx140->phase_calib_on = v;
		return 1;
	}
	return 0;
}

static const struct snd_kcontrol_new adcx140_snd_controls[] = {
	SOC_SINGLE_TLV("Analog CH1 Mic Gain Volume", ADCX140_CH1_CFG1, 2, 42, 0,
			adc_tlv),
@@ -628,6 +675,7 @@ static const struct snd_kcontrol_new adcx140_snd_controls[] = {
			0, 0xff, 0, dig_vol_tlv),
	SOC_SINGLE_TLV("Digital CH8 Out Volume", ADCX140_CH8_CFG2,
			0, 0xff, 0, dig_vol_tlv),
	ADCX140_PHASE_CALIB_SWITCH("Phase Calibration Switch"),
};

static int adcx140_reset(struct adcx140_priv *adcx140)
@@ -653,6 +701,8 @@ static int adcx140_reset(struct adcx140_priv *adcx140)
static void adcx140_pwr_ctrl(struct adcx140_priv *adcx140, bool power_state)
{
	int pwr_ctrl = 0;
	int ret = 0;
	struct snd_soc_component *component = adcx140->component;

	if (power_state)
		pwr_ctrl = ADCX140_PWR_CFG_ADC_PDZ | ADCX140_PWR_CFG_PLL_PDZ;
@@ -660,6 +710,14 @@ static void adcx140_pwr_ctrl(struct adcx140_priv *adcx140, bool power_state)
	if (adcx140->micbias_vg && power_state)
		pwr_ctrl |= ADCX140_PWR_CFG_BIAS_PDZ;

	if (pwr_ctrl) {
		ret = regmap_write(adcx140->regmap, ADCX140_PHASE_CALIB,
			adcx140->phase_calib_on ? 0x00 : 0x40);
		if (ret)
			dev_err(component->dev, "%s: register write error %d\n",
				__func__, ret);
	}

	regmap_update_bits(adcx140->regmap, ADCX140_PWR_CFG,
			   ADCX140_PWR_CTRL_MSK, pwr_ctrl);
}
@@ -1095,6 +1153,7 @@ static int adcx140_i2c_probe(struct i2c_client *i2c)
	if (!adcx140)
		return -ENOMEM;

	adcx140->phase_calib_on = false;
	adcx140->dev = &i2c->dev;

	adcx140->gpio_reset = devm_gpiod_get_optional(adcx140->dev,
+1 −0
Original line number Diff line number Diff line
@@ -90,6 +90,7 @@
#define ADCX140_PWR_CFG		0x75
#define ADCX140_DEV_STS0	0x76
#define ADCX140_DEV_STS1	0x77
#define ADCX140_PHASE_CALIB		0X7b

#define ADCX140_RESET	BIT(0)