mirror of
https://github.com/torvalds/linux.git
synced 2024-11-22 20:22:09 +00:00
ASoC: max98390: Fix dsm calibration reading
With the change introduced by6ac246105b
, the calibration can only be done after the codec probe (but questionable if it is working since 203A_AMP_EN is 0) or when the codec is powered up for audio use, in other cases "AMP is not ready to run calibration" is printed. This changes how this worked before the patch: the codec was force powered on for the duration of the calibration readout, then shut down. So, if a calibration was asked when the codec was active, it would have powered it down? To correct the calibration logic: check if the codec is powered on and if it is not then enable it, do the readout and put it back to disabled. Do this while keeping the dapm locked to avoid interfering with normal operation via DAPM. Fixes:6ac246105b
("ASoC: max98390: Remove unnecessary amp on/off conrtol") Reported-by: Fred Oh <fred.oh@linux.intel.com> Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com> Link: https://lore.kernel.org/r/20220916111349.4433-1-peter.ujfalusi@linux.intel.com Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
parent
12e51866c7
commit
9dd28b467c
@ -161,8 +161,6 @@ static struct reg_default max98390_reg_defaults[] = {
|
|||||||
{MAX98390_R23FF_GLOBAL_EN, 0x00},
|
{MAX98390_R23FF_GLOBAL_EN, 0x00},
|
||||||
};
|
};
|
||||||
|
|
||||||
static int max98390_dsm_calibrate(struct snd_soc_component *component);
|
|
||||||
|
|
||||||
static int max98390_dai_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
|
static int max98390_dai_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
|
||||||
{
|
{
|
||||||
struct snd_soc_component *component = codec_dai->component;
|
struct snd_soc_component *component = codec_dai->component;
|
||||||
@ -635,20 +633,49 @@ static int max98390_dsm_calib_get(struct snd_kcontrol *kcontrol,
|
|||||||
static int max98390_dsm_calib_put(struct snd_kcontrol *kcontrol,
|
static int max98390_dsm_calib_put(struct snd_kcontrol *kcontrol,
|
||||||
struct snd_ctl_elem_value *ucontrol)
|
struct snd_ctl_elem_value *ucontrol)
|
||||||
{
|
{
|
||||||
unsigned int val;
|
struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
|
||||||
struct snd_soc_component *component =
|
struct max98390_priv *max98390 = snd_soc_component_get_drvdata(component);
|
||||||
snd_soc_kcontrol_component(kcontrol);
|
struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
|
||||||
struct max98390_priv *max98390 =
|
unsigned int rdc, rdc_cal_result, rdc_integer, rdc_factor, temp, val;
|
||||||
snd_soc_component_get_drvdata(component);
|
|
||||||
|
snd_soc_dapm_mutex_lock(dapm);
|
||||||
|
|
||||||
regmap_read(max98390->regmap, MAX98390_R23FF_GLOBAL_EN, &val);
|
regmap_read(max98390->regmap, MAX98390_R23FF_GLOBAL_EN, &val);
|
||||||
if (val == 0x1)
|
if (!val) {
|
||||||
max98390_dsm_calibrate(component);
|
/* Enable the codec for the duration of calibration readout */
|
||||||
else {
|
regmap_update_bits(max98390->regmap, MAX98390_R203A_AMP_EN,
|
||||||
dev_err(component->dev, "AMP is not ready to run calibration\n");
|
MAX98390_AMP_EN_MASK, 1);
|
||||||
return -ECANCELED;
|
regmap_update_bits(max98390->regmap, MAX98390_R23FF_GLOBAL_EN,
|
||||||
|
MAX98390_GLOBAL_EN_MASK, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
regmap_read(max98390->regmap, THERMAL_RDC_RD_BACK_BYTE1, &rdc);
|
||||||
|
regmap_read(max98390->regmap, THERMAL_RDC_RD_BACK_BYTE0, &rdc_cal_result);
|
||||||
|
regmap_read(max98390->regmap, MAX98390_MEAS_ADC_CH2_READ, &temp);
|
||||||
|
|
||||||
|
if (!val) {
|
||||||
|
/* Disable the codec if it was disabled */
|
||||||
|
regmap_update_bits(max98390->regmap, MAX98390_R23FF_GLOBAL_EN,
|
||||||
|
MAX98390_GLOBAL_EN_MASK, 0);
|
||||||
|
regmap_update_bits(max98390->regmap, MAX98390_R203A_AMP_EN,
|
||||||
|
MAX98390_AMP_EN_MASK, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
snd_soc_dapm_mutex_unlock(dapm);
|
||||||
|
|
||||||
|
rdc_cal_result |= (rdc << 8) & 0x0000FFFF;
|
||||||
|
if (rdc_cal_result)
|
||||||
|
max98390->ref_rdc_value = 268435456U / rdc_cal_result;
|
||||||
|
|
||||||
|
max98390->ambient_temp_value = temp * 52 - 1188;
|
||||||
|
|
||||||
|
rdc_integer = rdc_cal_result * 937 / 65536;
|
||||||
|
rdc_factor = ((rdc_cal_result * 937 * 100) / 65536) - (rdc_integer * 100);
|
||||||
|
|
||||||
|
dev_info(component->dev,
|
||||||
|
"rdc resistance about %d.%02d ohm, reg=0x%X temp reg=0x%X\n",
|
||||||
|
rdc_integer, rdc_factor, rdc_cal_result, temp);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -828,34 +855,6 @@ err:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int max98390_dsm_calibrate(struct snd_soc_component *component)
|
|
||||||
{
|
|
||||||
unsigned int rdc, rdc_cal_result, temp;
|
|
||||||
unsigned int rdc_integer, rdc_factor;
|
|
||||||
struct max98390_priv *max98390 =
|
|
||||||
snd_soc_component_get_drvdata(component);
|
|
||||||
|
|
||||||
regmap_read(max98390->regmap,
|
|
||||||
THERMAL_RDC_RD_BACK_BYTE1, &rdc);
|
|
||||||
regmap_read(max98390->regmap,
|
|
||||||
THERMAL_RDC_RD_BACK_BYTE0, &rdc_cal_result);
|
|
||||||
rdc_cal_result |= (rdc << 8) & 0x0000FFFF;
|
|
||||||
if (rdc_cal_result)
|
|
||||||
max98390->ref_rdc_value = 268435456U / rdc_cal_result;
|
|
||||||
|
|
||||||
regmap_read(max98390->regmap, MAX98390_MEAS_ADC_CH2_READ, &temp);
|
|
||||||
max98390->ambient_temp_value = temp * 52 - 1188;
|
|
||||||
|
|
||||||
rdc_integer = rdc_cal_result * 937 / 65536;
|
|
||||||
rdc_factor = ((rdc_cal_result * 937 * 100) / 65536)
|
|
||||||
- (rdc_integer * 100);
|
|
||||||
|
|
||||||
dev_info(component->dev, "rdc resistance about %d.%02d ohm, reg=0x%X temp reg=0x%X\n",
|
|
||||||
rdc_integer, rdc_factor, rdc_cal_result, temp);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void max98390_init_regs(struct snd_soc_component *component)
|
static void max98390_init_regs(struct snd_soc_component *component)
|
||||||
{
|
{
|
||||||
struct max98390_priv *max98390 =
|
struct max98390_priv *max98390 =
|
||||||
|
Loading…
Reference in New Issue
Block a user