diff mbox series

[2/3] ASoC: sun50i-codec-analog: Add support for internal bias

Message ID 20220616062554.57266-3-samuel@sholland.org (mailing list archive)
State Superseded
Headers show
Series ASoC: sun50i-codec-analog: Internal bias support | expand

Commit Message

Samuel Holland June 16, 2022, 6:25 a.m. UTC
From: Arnaud Ferraris <arnaud.ferraris@collabora.com>

In order to properly bias headset microphones, there should be a pull-up
resistor between pins HBIAS and MIC2P. This can be an external resistor,
but the codec also provides an internal 2.2K resistor which is enabled
by a register.

This patch enables or disables the internal bias resistor based on a
device tree property.

Signed-off-by: Arnaud Ferraris <arnaud.ferraris@collabora.com>
[Samuel: split binding and implementation patches]
Signed-off-by: Samuel Holland <samuel@sholland.org>
---

 sound/soc/sunxi/sun50i-codec-analog.c | 29 +++++++++++++++++++++++++++
 1 file changed, 29 insertions(+)

Comments

Mark Brown June 16, 2022, 8:28 a.m. UTC | #1
On Thu, Jun 16, 2022 at 01:25:53AM -0500, Samuel Holland wrote:

> +static int sun50i_a64_codec_probe(struct snd_soc_component *component)
> +{
> +	struct sun50i_codec_analog *codec = snd_soc_component_get_drvdata(component);
> +
> +	regmap_update_bits(component->regmap, SUN50I_ADDA_JACK_MIC_CTRL,
> +			   BIT(SUN50I_ADDA_JACK_MIC_CTRL_INNERRESEN),
> +			   codec->internal_bias_resistor <<
> +				SUN50I_ADDA_JACK_MIC_CTRL_INNERRESEN);
> +
> +	return 0;
> +}

It doesn't make much practical difference but is there any reason this
can't be done in the main device probe?
Samuel Holland June 21, 2022, 3:53 a.m. UTC | #2
On 6/16/22 3:28 AM, Mark Brown wrote:
> On Thu, Jun 16, 2022 at 01:25:53AM -0500, Samuel Holland wrote:
> 
>> +static int sun50i_a64_codec_probe(struct snd_soc_component *component)
>> +{
>> +	struct sun50i_codec_analog *codec = snd_soc_component_get_drvdata(component);
>> +
>> +	regmap_update_bits(component->regmap, SUN50I_ADDA_JACK_MIC_CTRL,
>> +			   BIT(SUN50I_ADDA_JACK_MIC_CTRL_INNERRESEN),
>> +			   codec->internal_bias_resistor <<
>> +				SUN50I_ADDA_JACK_MIC_CTRL_INNERRESEN);
>> +
>> +	return 0;
>> +}
> 
> It doesn't make much practical difference but is there any reason this
> can't be done in the main device probe?

There's no particular reason, and doing it in the device probe would be much
simpler. I'll do that for v2.

Regards,
Samuel
diff mbox series

Patch

diff --git a/sound/soc/sunxi/sun50i-codec-analog.c b/sound/soc/sunxi/sun50i-codec-analog.c
index a41e25ad0aaf..699a5a318875 100644
--- a/sound/soc/sunxi/sun50i-codec-analog.c
+++ b/sound/soc/sunxi/sun50i-codec-analog.c
@@ -117,8 +117,13 @@ 
 #define SUN50I_ADDA_HS_MBIAS_CTRL_MMICBIASEN	7
 
 #define SUN50I_ADDA_JACK_MIC_CTRL	0x1d
+#define SUN50I_ADDA_JACK_MIC_CTRL_INNERRESEN	6
 #define SUN50I_ADDA_JACK_MIC_CTRL_HMICBIASEN	5
 
+struct sun50i_codec_analog {
+	bool	internal_bias_resistor;
+};
+
 /* mixer controls */
 static const struct snd_kcontrol_new sun50i_a64_codec_mixer_controls[] = {
 	SOC_DAPM_DOUBLE_R("Mic1 Playback Switch",
@@ -471,6 +476,18 @@  static const struct snd_soc_dapm_route sun50i_a64_codec_routes[] = {
 	{ "EARPIECE", NULL, "Earpiece Amp" },
 };
 
+static int sun50i_a64_codec_probe(struct snd_soc_component *component)
+{
+	struct sun50i_codec_analog *codec = snd_soc_component_get_drvdata(component);
+
+	regmap_update_bits(component->regmap, SUN50I_ADDA_JACK_MIC_CTRL,
+			   BIT(SUN50I_ADDA_JACK_MIC_CTRL_INNERRESEN),
+			   codec->internal_bias_resistor <<
+				SUN50I_ADDA_JACK_MIC_CTRL_INNERRESEN);
+
+	return 0;
+}
+
 static int sun50i_a64_codec_suspend(struct snd_soc_component *component)
 {
 	return regmap_update_bits(component->regmap, SUN50I_ADDA_HP_CTRL,
@@ -491,6 +508,7 @@  static const struct snd_soc_component_driver sun50i_codec_analog_cmpnt_drv = {
 	.num_dapm_widgets	= ARRAY_SIZE(sun50i_a64_codec_widgets),
 	.dapm_routes		= sun50i_a64_codec_routes,
 	.num_dapm_routes	= ARRAY_SIZE(sun50i_a64_codec_routes),
+	.probe			= sun50i_a64_codec_probe,
 	.suspend		= sun50i_a64_codec_suspend,
 	.resume			= sun50i_a64_codec_resume,
 };
@@ -505,9 +523,20 @@  MODULE_DEVICE_TABLE(of, sun50i_codec_analog_of_match);
 
 static int sun50i_codec_analog_probe(struct platform_device *pdev)
 {
+	struct sun50i_codec_analog *codec;
 	struct regmap *regmap;
 	void __iomem *base;
 
+	codec = devm_kzalloc(&pdev->dev, sizeof(*codec), GFP_KERNEL);
+	if (!codec)
+		return -ENOMEM;
+
+	platform_set_drvdata(pdev, codec);
+
+	codec->internal_bias_resistor =
+		device_property_read_bool(&pdev->dev,
+					  "allwinner,internal-bias-resistor");
+
 	base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(base)) {
 		dev_err(&pdev->dev, "Failed to map the registers\n");