ASoC: tlv320adcx140: Add a new kcontrol

Add a new kcontrol for phase calib

Signed-off-by: Kevin Lu <luminlong@139.com>
Link: https://lore.kernel.org/r/20220815112715.21617-1-luminlong@139.com
Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
Kevin Lu 2022-08-15 19:27:15 +08:00 committed by Mark Brown
parent ea15d3bd3c
commit 4e82971f7b
No known key found for this signature in database
GPG Key ID: 24D68B725D5487D0
2 changed files with 60 additions and 0 deletions

View File

@ -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,

View File

@ -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)