[Question] Accessing MICBIAS on WM8960 Breakout and Raspberry PI

This is above my head, but two LLMs had similar thoughts on the matter (mainly ALSA settings & manually activate MICBIAS); here’s Claude.ai and below I’ll paste chatgpt’s repsonse
Here’s how I’d attack the “no MICBIAS” problem in three stages: a quick hardware sanity-check, then a custom Device-Tree overlay that actually drives the WM8960’s bias generator, and finally the ALSA commands to turn it on.


1. Quick hardware bypass (prove it’s really the software bias)

Before you go deep into overlays, verify that everything downstream of MICBIAS is working. On the SparkFun breakout the MICBIAS pin simply outputs whatever the WM8960 is told to, through your series resistor and into the electret capsule. You can force-feed it:

  1. Wire Pi 3.3 V → 2.2 kΩ → LINPUT2 (instead of routing through the on-chip MICBIAS pin).

  2. Leave LINPUT1 → GND as you have it.

  3. In alsamixer select your WM8960 card, enable the LINPUT2 boost and set capture volume to ~100%.

  4. Try recording again:

    arecord -D plughw:3,0 -f S16_LE -r 44100 -c1 test.wav && aplay test.wav
    

If you do now hear your microphone, you’ve proven that the I²S chain, boost stages, and everything downstream is good—and the only thing missing is driving that MICBIAS pin in software (Audio Codec Breakout - WM8960 Hookup Guide - SparkFun Learn).


2. Custom DT overlay to actually turn the MICBIAS on

The stock Waveshare HAT overlay (which your OS loads as wm8960-soundcard.dtbo) never declares a MICBIAS supply, so the WM8960 driver never enables its internal bias generator. You need to write a little overlay that:

  • Enables I²S
  • Instantiates the codec on I²C
  • Declares all of its supplies (AVDD, DVDD, DCVDD, DBVDD, SPKVDD1/2)
  • Declares the MICBIAS supply and resistor
  • Hooks up a simple-audio-card node that routes LINPUT2 as your mic input

Below is a complete example. Save it as wm8960-breakout-overlay.dts in, say, ~/dtoverlays/.

/dts-v1/;
/plugin/;

/ {
    compatible = "brcm,bcm2711";

    /* 1) turn on I²S */
    fragment@0 {
        target = <&i2s>;
        __overlay__ { status = "okay"; };
    };

    /* 2) make a fixed 12.288 MHz clock for the codec */
    fragment@1 {
        target-path = "/";
        __overlay__ {
            wm8960_mclk: wm8960_mclk {
                compatible     = "fixed-clock";
                #clock-cells   = <0>;
                clock-frequency = <12288000>;
            };
        };
    };

    /* 3) instantiate the WM8960 on I²C1 and wire up *all* its supplies + MICBIAS */
    fragment@2 {
        target = <&i2c1>;
        __overlay__ {
            #address-cells = <1>;
            #size-cells    = <0>;
            status         = "okay";

            wm8960: codec@1a {
                compatible       = "wlf,wm8960";
                reg              = <0x1a>;
                #sound-dai-cells = <0>;

                /* power rails – the Pi DT should already have these phandles */
                AVDD-supply    = <&vdd_5v0_reg>;   /* analog rail */
                DVDD-supply    = <&vdd_3v3_reg>;   /* digital core */
                DCVDD-supply   = <&vdd_3v3_reg>;
                DBVDD-supply   = <&vdd_3v3_reg>;
                SPKVDD1-supply = <&vdd_5v0_reg>;
                SPKVDD2-supply = <&vdd_5v0_reg>;

                /* *this* is what turns on the on-chip bias generator */
                micbias-supply   = <&vdd_3v3_reg>;
                micbias-resistor = <2200>;

                clocks     = <&wm8960_mclk>;
                clock-names = "mclk";
            };
        };
    };

    /* 4) simple-audio-card: route LINPUT2→Mic Jack and HP→Headphones */
    fragment@3 {
        target = <&sound>;
        __overlay__ {
            compatible = "simple-audio-card";
            simple-audio-card,name   = "WM8960 Breakout";
            simple-audio-card,format = "i2s";

            simple-audio-card,widgets =
                "Microphone", "Mic Jack",
                "Headphone",  "Headphone Jack";

            simple-audio-card,routing =
                "Headphone Jack", "HP_L",
                "Headphone Jack", "HP_R",
                "LINPUT2",       "Mic Jack",
                "LINPUT1",       "Mic Jack";

            simple-audio-card,cpu {
                sound-dai = <&i2s>;
            };
            simple-audio-card,codec {
                sound-dai   = <&wm8960>;
                clocks      = <&wm8960_mclk>;
                clock-names = "mclk";
            };
        };
    };
};

Compile & install:

sudo dtc -@ -I dts -O dtb -o wm8960-breakout.dtbo wm8960-breakout-overlay.dts
sudo cp wm8960-breakout.dtbo /boot/firmware/overlays/

Then in /boot/firmware/config.txt add:

dtparam=i2c_arm=on
dtparam=i2s=on
dtoverlay=wm8960-breakout

Reboot.


3. ALSA: enable the MICBIAS and capture

Once your overlay has defined the micbias-supply, the WM8960 driver will expose a Mic Bias switch in ALSA. Do this:

  1. Open alsamixer -c 3 (replace 3 with your card number).
  2. Press F6, select “WM8960 Breakout.”
  3. Find the Mic Bias control and unmute / set it to On.
  4. Increase Capture Volume (and boost on LINPUT2) to 80–100%.

Or from the shell:

# turn on the on-chip bias generator
amixer -c 3 cset name='Mic Bias' 1

# boost the LINPUT2 path
amixer -c 3 cset name='Left Boost Mixer LINPUT2' 1
amixer -c 3 cset name='Left Input Boost Mixer LINPUT2' 29

# set capture to 100%
amixer -c 3 cset name='Capture Volume' 100

Now your electret mic should see ~2.9 V (0.9 × AVDD by default), and arecord will no longer be silent.


Why this works

Give that a spin and your electret should finally sing!