Unverified Commit 7a372650 authored by David Lin's avatar David Lin Committed by Mark Brown
Browse files

ASoC: nau8825: Add a manually mechanism for detection failure



This patch is to use saradc to check the jack type when auto
detection is still failure.

Signed-off-by: default avatarDavid Lin <CTLIN0@nuvoton.com>
Link: https://lore.kernel.org/r/20221122073855.43024-2-CTLIN0@nuvoton.com


Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent fa0fb073
Loading
Loading
Loading
Loading
+125 −3
Original line number Diff line number Diff line
@@ -1736,6 +1736,121 @@ static int nau8825_button_decode(int value)
	return buttons;
}

static int nau8825_high_imped_detection(struct nau8825 *nau8825)
{
	struct regmap *regmap = nau8825->regmap;
	struct snd_soc_dapm_context *dapm = nau8825->dapm;
	unsigned int adc_mg1, adc_mg2;

	/* Initial phase */
	regmap_update_bits(regmap, NAU8825_REG_HSD_CTRL,
			   NAU8825_SPKR_ENGND1 | NAU8825_SPKR_ENGND2 | NAU8825_SPKR_DWN1R |
			   NAU8825_SPKR_DWN1L, NAU8825_SPKR_ENGND1 | NAU8825_SPKR_ENGND2);
	regmap_update_bits(regmap, NAU8825_REG_ANALOG_CONTROL_1,
			   NAU8825_TESTDACIN_MASK, NAU8825_TESTDACIN_GND);
	regmap_write(regmap, NAU8825_REG_TRIM_SETTINGS, 0x6);
	regmap_update_bits(regmap, NAU8825_REG_MIC_BIAS,
			   NAU8825_MICBIAS_LOWNOISE_MASK | NAU8825_MICBIAS_VOLTAGE_MASK,
			   NAU8825_MICBIAS_LOWNOISE_EN);
	regmap_update_bits(regmap, NAU8825_REG_SAR_CTRL,
			   NAU8825_SAR_INPUT_MASK | NAU8825_SAR_TRACKING_GAIN_MASK |
			   NAU8825_SAR_HV_SEL_MASK | NAU8825_SAR_RES_SEL_MASK |
			   NAU8825_SAR_COMPARE_TIME_MASK | NAU8825_SAR_SAMPLING_TIME_MASK,
			   NAU8825_SAR_HV_SEL_VDDMIC | NAU8825_SAR_RES_SEL_70K);

	snd_soc_dapm_force_enable_pin(dapm, "MICBIAS");
	snd_soc_dapm_force_enable_pin(dapm, "SAR");
	snd_soc_dapm_sync(dapm);

	/* Configure settings for first reading of SARADC */
	regmap_update_bits(regmap, NAU8825_REG_HSD_CTRL,
			   NAU8825_SPKR_ENGND1 | NAU8825_SPKR_ENGND2 | NAU8825_SPKR_DWN1R |
			   NAU8825_SPKR_DWN1L, NAU8825_SPKR_ENGND2);
	regmap_update_bits(regmap, NAU8825_REG_MIC_BIAS,
			   NAU8825_MICBIAS_JKSLV | NAU8825_MICBIAS_JKR2,
			   NAU8825_MICBIAS_JKR2);
	regmap_read(regmap, NAU8825_REG_SARDOUT_RAM_STATUS, &adc_mg1);

	/* Configure settings for second reading of SARADC */
	regmap_update_bits(regmap, NAU8825_REG_MIC_BIAS,
			   NAU8825_MICBIAS_JKSLV | NAU8825_MICBIAS_JKR2, 0);
	regmap_update_bits(regmap, NAU8825_REG_HSD_CTRL,
			   NAU8825_SPKR_ENGND1 | NAU8825_SPKR_ENGND2 | NAU8825_SPKR_DWN1R |
			   NAU8825_SPKR_DWN1L, NAU8825_SPKR_ENGND1 | NAU8825_SPKR_ENGND2 |
			   NAU8825_SPKR_DWN1R | NAU8825_SPKR_DWN1L);
	regmap_update_bits(regmap, NAU8825_REG_HSD_CTRL,
			   NAU8825_SPKR_ENGND1 | NAU8825_SPKR_ENGND2 | NAU8825_SPKR_DWN1R |
			   NAU8825_SPKR_DWN1L, NAU8825_SPKR_ENGND1);
	regmap_update_bits(regmap, NAU8825_REG_MIC_BIAS,
			   NAU8825_MICBIAS_JKSLV | NAU8825_MICBIAS_JKR2,
			   NAU8825_MICBIAS_JKSLV);
	regmap_update_bits(regmap, NAU8825_REG_SAR_CTRL,
			   NAU8825_SAR_INPUT_MASK, NAU8825_SAR_INPUT_JKSLV);
	regmap_read(regmap, NAU8825_REG_SARDOUT_RAM_STATUS, &adc_mg2);

	/* Disable phase */
	snd_soc_dapm_disable_pin(dapm, "SAR");
	snd_soc_dapm_disable_pin(dapm, "MICBIAS");
	snd_soc_dapm_sync(dapm);

	regmap_update_bits(regmap, NAU8825_REG_MIC_BIAS,
			   NAU8825_MICBIAS_JKSLV | NAU8825_MICBIAS_LOWNOISE_MASK |
			   NAU8825_MICBIAS_VOLTAGE_MASK, nau8825->micbias_voltage);
	regmap_update_bits(regmap, NAU8825_REG_HSD_CTRL,
			   NAU8825_SPKR_ENGND1 | NAU8825_SPKR_ENGND2 | NAU8825_SPKR_DWN1R |
			   NAU8825_SPKR_DWN1L, NAU8825_SPKR_ENGND1 | NAU8825_SPKR_ENGND2 |
			   NAU8825_SPKR_DWN1R | NAU8825_SPKR_DWN1L);
	regmap_update_bits(regmap, NAU8825_REG_ANALOG_CONTROL_1,
			   NAU8825_TESTDACIN_MASK, NAU8825_TESTDACIN_GND);
	regmap_write(regmap, NAU8825_REG_TRIM_SETTINGS, 0);
	regmap_update_bits(regmap, NAU8825_REG_SAR_CTRL,
			   NAU8825_SAR_TRACKING_GAIN_MASK | NAU8825_SAR_HV_SEL_MASK,
			   nau8825->sar_voltage << NAU8825_SAR_TRACKING_GAIN_SFT);
	regmap_update_bits(regmap, NAU8825_REG_SAR_CTRL,
			   NAU8825_SAR_COMPARE_TIME_MASK | NAU8825_SAR_SAMPLING_TIME_MASK,
			   (nau8825->sar_compare_time << NAU8825_SAR_COMPARE_TIME_SFT) |
			   (nau8825->sar_sampling_time << NAU8825_SAR_SAMPLING_TIME_SFT));
	dev_dbg(nau8825->dev, "adc_mg1:%x, adc_mg2:%x\n", adc_mg1, adc_mg2);

	/* Confirmation phase */
	if (adc_mg1 > adc_mg2) {
		dev_dbg(nau8825->dev, "OMTP (micgnd1) mic connected\n");

		/* Unground MICGND1 */
		regmap_update_bits(regmap, NAU8825_REG_HSD_CTRL,
				   NAU8825_SPKR_ENGND1 | NAU8825_SPKR_ENGND2,
				   NAU8825_SPKR_ENGND2);
		/* Attach 2kOhm Resistor from MICBIAS to MICGND1 */
		regmap_update_bits(regmap, NAU8825_REG_MIC_BIAS,
				   NAU8825_MICBIAS_JKSLV | NAU8825_MICBIAS_JKR2,
				   NAU8825_MICBIAS_JKR2);
		/* Attach SARADC to MICGND1 */
		regmap_update_bits(regmap, NAU8825_REG_SAR_CTRL,
				   NAU8825_SAR_INPUT_MASK,
				   NAU8825_SAR_INPUT_JKR2);
	} else if (adc_mg1 < adc_mg2) {
		dev_dbg(nau8825->dev, "CTIA (micgnd2) mic connected\n");

		/* Unground MICGND2 */
		regmap_update_bits(regmap, NAU8825_REG_HSD_CTRL,
				   NAU8825_SPKR_ENGND1 | NAU8825_SPKR_ENGND2,
				   NAU8825_SPKR_ENGND1);
		/* Attach 2kOhm Resistor from MICBIAS to MICGND2 */
		regmap_update_bits(regmap, NAU8825_REG_MIC_BIAS,
				   NAU8825_MICBIAS_JKSLV | NAU8825_MICBIAS_JKR2,
				   NAU8825_MICBIAS_JKSLV);
		/* Attach SARADC to MICGND2 */
		regmap_update_bits(regmap, NAU8825_REG_SAR_CTRL,
				   NAU8825_SAR_INPUT_MASK,
				   NAU8825_SAR_INPUT_JKSLV);
	} else {
		dev_err(nau8825->dev, "Jack broken.\n");
		return -EINVAL;
	}

	return 0;
}

static int nau8825_jack_insert(struct nau8825 *nau8825)
{
	struct regmap *regmap = nau8825->regmap;
@@ -1797,8 +1912,15 @@ static int nau8825_jack_insert(struct nau8825 *nau8825)
		snd_soc_dapm_sync(dapm);
		break;
	case 3:
		/* detect error case */
		dev_err(nau8825->dev, "detection error; disable mic function\n");
		/* Detection failure case */
		dev_warn(nau8825->dev,
			 "Detection failure. Try the manually mechanism for jack type checking.\n");
		if (!nau8825_high_imped_detection(nau8825)) {
			type = SND_JACK_HEADSET;
			snd_soc_dapm_force_enable_pin(dapm, "MICBIAS");
			snd_soc_dapm_force_enable_pin(dapm, "SAR");
			snd_soc_dapm_sync(dapm);
		} else
			type = SND_JACK_HEADPHONE;
		break;
	}
+23 −0
Original line number Diff line number Diff line
@@ -155,6 +155,8 @@
/* HSD_CTRL (0xc) */
#define NAU8825_HSD_AUTO_MODE	(1 << 6)
/* 0 - open, 1 - short to GND */
#define NAU8825_SPKR_ENGND1	(1 << 3)
#define NAU8825_SPKR_ENGND2	(1 << 2)
#define NAU8825_SPKR_DWN1R	(1 << 1)
#define NAU8825_SPKR_DWN1L	(1 << 0)

@@ -207,6 +209,17 @@
#define NAU8825_SAR_INPUT_JKR2	(0 << 11)
#define NAU8825_SAR_TRACKING_GAIN_SFT	8
#define NAU8825_SAR_TRACKING_GAIN_MASK	(0x7 << NAU8825_SAR_TRACKING_GAIN_SFT)
#define NAU8825_SAR_HV_SEL_SFT		7
#define NAU8825_SAR_HV_SEL_MASK		(1 << NAU8825_SAR_HV_SEL_SFT)
#define NAU8825_SAR_HV_SEL_MICBIAS	(0 << NAU8825_SAR_HV_SEL_SFT)
#define NAU8825_SAR_HV_SEL_VDDMIC	(1 << NAU8825_SAR_HV_SEL_SFT)
#define NAU8825_SAR_RES_SEL_SFT		4
#define NAU8825_SAR_RES_SEL_MASK	(0x7 << NAU8825_SAR_RES_SEL_SFT)
#define NAU8825_SAR_RES_SEL_35K		(0 << NAU8825_SAR_RES_SEL_SFT)
#define NAU8825_SAR_RES_SEL_70K		(1 << NAU8825_SAR_RES_SEL_SFT)
#define NAU8825_SAR_RES_SEL_170K	(2 << NAU8825_SAR_RES_SEL_SFT)
#define NAU8825_SAR_RES_SEL_360K	(3 << NAU8825_SAR_RES_SEL_SFT)
#define NAU8825_SAR_RES_SEL_SHORTED	(4 << NAU8825_SAR_RES_SEL_SFT)
#define NAU8825_SAR_COMPARE_TIME_SFT	2
#define NAU8825_SAR_COMPARE_TIME_MASK	(3 << 2)
#define NAU8825_SAR_SAMPLING_TIME_SFT	0
@@ -385,6 +398,13 @@
#define NAU8825_BIAS_VMID_SEL_SFT	4
#define NAU8825_BIAS_VMID_SEL_MASK	(3 << NAU8825_BIAS_VMID_SEL_SFT)

/* ANALOG_CONTROL_1 (0x69) */
#define NAU8825_TESTDACIN_SFT		14
#define NAU8825_TESTDACIN_MASK		(0x3 << NAU8825_TESTDACIN_SFT)
#define NAU8825_TESTDACIN_HIGH		(1 << NAU8825_TESTDACIN_SFT)
#define NAU8825_TESTDACIN_LOW		(2 << NAU8825_TESTDACIN_SFT)
#define NAU8825_TESTDACIN_GND		(3 << NAU8825_TESTDACIN_SFT)

/* ANALOG_CONTROL_2 (0x6a) */
#define NAU8825_HP_NON_CLASSG_CURRENT_2xADJ (1 << 12)
#define NAU8825_DAC_CAPACITOR_MSB (1 << 1)
@@ -412,6 +432,9 @@
/* MIC_BIAS (0x74) */
#define NAU8825_MICBIAS_JKSLV	(1 << 14)
#define NAU8825_MICBIAS_JKR2	(1 << 12)
#define NAU8825_MICBIAS_LOWNOISE_SFT	10
#define NAU8825_MICBIAS_LOWNOISE_MASK	(0x1 << NAU8825_MICBIAS_LOWNOISE_SFT)
#define NAU8825_MICBIAS_LOWNOISE_EN	(0x1 << NAU8825_MICBIAS_LOWNOISE_SFT)
#define NAU8825_MICBIAS_POWERUP_SFT	8
#define NAU8825_MICBIAS_VOLTAGE_SFT	0
#define NAU8825_MICBIAS_VOLTAGE_MASK	0x7