[PATCH 0/3] ASoC: sun50i-codec-analog: Internal bias support
This series adds support for enabling the codec's internal microphone bias, which is needed on at least some versions of the PinePhone.
Arnaud Ferraris (2): ASoC: dt-bindings: sun50i-codec: Add binding for internal bias ASoC: sun50i-codec-analog: Add support for internal bias
Samuel Holland (1): arm64: dts: allwinner: pinephone: Enable internal HMIC bias
.../allwinner,sun50i-a64-codec-analog.yaml | 5 ++++ .../allwinner/sun50i-a64-pinephone-1.0.dts | 4 +++ .../allwinner/sun50i-a64-pinephone-1.1.dts | 4 +++ sound/soc/sunxi/sun50i-codec-analog.c | 29 +++++++++++++++++++ 4 files changed, 42 insertions(+)
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 adds a device-tree property to the sun50i-codec-analog driver to take advantage of this feature.
Signed-off-by: Arnaud Ferraris arnaud.ferraris@collabora.com [Samuel: split binding and implementation patches] Signed-off-by: Samuel Holland samuel@sholland.org ---
.../bindings/sound/allwinner,sun50i-a64-codec-analog.yaml | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/Documentation/devicetree/bindings/sound/allwinner,sun50i-a64-codec-analog.yaml b/Documentation/devicetree/bindings/sound/allwinner,sun50i-a64-codec-analog.yaml index 3b764415c9ab..66859eb8f79a 100644 --- a/Documentation/devicetree/bindings/sound/allwinner,sun50i-a64-codec-analog.yaml +++ b/Documentation/devicetree/bindings/sound/allwinner,sun50i-a64-codec-analog.yaml @@ -21,6 +21,11 @@ properties: description: Regulator for the headphone amplifier
+ allwinner,internal-bias-resistor: + description: + Enable the internal 2.2K bias resistor between HBIAS and MICDET pins + type: boolean + required: - compatible - reg
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(+)
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");
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?
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
Revisions 1.0 and 1.1 of the PinePhone mainboard do not have an external resistor connecting HBIAS to MIC2P. Enable the internal resistor to provide the necessary headeset microphone bias.
Signed-off-by: Samuel Holland samuel@sholland.org ---
arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone-1.0.dts | 4 ++++ arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone-1.1.dts | 4 ++++ 2 files changed, 8 insertions(+)
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone-1.0.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone-1.0.dts index fb65319a3bd3..219f720b8b7d 100644 --- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone-1.0.dts +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone-1.0.dts @@ -10,6 +10,10 @@ / { compatible = "pine64,pinephone-1.0", "pine64,pinephone", "allwinner,sun50i-a64"; };
+&codec_analog { + allwinner,internal-bias-resistor; +}; + &sgm3140 { enable-gpios = <&pio 2 3 GPIO_ACTIVE_HIGH>; /* PC3 */ flash-gpios = <&pio 3 24 GPIO_ACTIVE_HIGH>; /* PD24 */ diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone-1.1.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone-1.1.dts index 5e59d3752178..723af64a9cee 100644 --- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone-1.1.dts +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone-1.1.dts @@ -29,6 +29,10 @@ &backlight { default-brightness-level = <400>; };
+&codec_analog { + allwinner,internal-bias-resistor; +}; + &sgm3140 { enable-gpios = <&pio 3 24 GPIO_ACTIVE_HIGH>; /* PD24 */ flash-gpios = <&pio 2 3 GPIO_ACTIVE_HIGH>; /* PC3 */
participants (2)
-
Mark Brown
-
Samuel Holland