Background
I have a question and was wondering if any of you folks could point me in the right direction (I know this is not the best place but I don’t know who else to ask). I’m using the SparkFun Audio Codec Breakout - WM8960.
I have been searching everywhere online to make this board work with the PI as it is usually used with arduinos but I get stuck at powering the electret mic with micbias.
Currently the Waveshare WM8960 soundcard overlay is the only one I have found for this audio chip. I am not entirely sure if it is the MICBIAS control that is not working but after all the troubleshooting, it is the consistent thing that keeps coming back up as it never reads any voltage while recording. Speakers work great by the way.
The Project
Full Wiring Diagram
Power
Pi 3.3V (Physical Pin 1 or 17) → WM8960 3V3
Pi 5V (Physical Pin 2 or 4) → WM8960 VIN
Pi Ground (Any GND Pin, e.g., Pin 6) → WM8960 GND
I2C
Pi SDA (GPIO 2, Physical Pin 3) → WM8960 SDA
Pi SCL (GPIO 3, Physical Pin 5) → WM8960 SCL
I2S
Pi BCLK (Bit Clock) (GPIO 18, Physical Pin 12) → WM8960 BCLK
Pi LRC / WS (Left/Right Clock / Word Select) (GPIO 19, Physical Pin 35) → WM8960 DACLRC (also referred to as DLRC on top silkscreen) - The datasheet notes this often serves as the frame clock for both ADC and DAC when the ADC is enabled.
Pi DOUT (Data Out from Pi / Data In to Codec) (GPIO 21, Physical Pin 40) → WM8960 DACDAT (also referred to as DDAT on top silkscreen)
Pi DIN (Data In to Pi / Data Out from Codec) (GPIO 20, Physical Pin 38) → WM8960 ADCDAT (also referred to as ADAT on top silkscreen)
MIC
MICBIAS → 2.2kohm resistor → LINPUT2
MIC+ → LINPUT2
MIC- → LINPUT1
LINPUT1 → JUMPER → GND
I am attempting to connect this board to a Raspberry PI 4. It currently runs the latest version of Raspberry PI OS and by default the wb8960-soundcard overlay is this one.
I am connecting an analog speaker and what I believe is a Electret Microphone from this ATT 210 phone. The basic idea is, I am taking over the phone’s matrix keypad with the PI and it’s audio, not using any of the board in the phone whatsoever besides the matrix keypad. I have already setup the keypad matrix to the PI GPIO but then I needed audio. This phone is small so I cannot use a hat for the project. In fact, I purchased this audio hat first. The second issue I had was I wanted to use the original phone microphone because it will likely be better than a MEMS mic sitting in the housing. I found that the SparkFun WM8960 Board checked all the boxes as it supports external electret mics.
I setup the speaker and it worked after turning on the “Left Out Mixer PCM” setting.
Then I turned to the microphone…
The Mic Setup
I set the microphone up in a differential configuration. This means I connected it in the following way:
MICBIAS → 2.2kohm resistor → LINPUT2
MIC+ → LINPUT2
MIC- → LINPUT1
LINPUT1 → JUMPER → GND
Previously I did try to do a standard mic setup but it yielded the same results:
MICBIAS → 2.2kohm resistor → LINPUT1
MIC+ → LINPUT1
MIC- → GND
The Card is 3 so for code examples below I have listed 3,0 which is targeting the WM8960.
Full alsamixer Settings
headphone - off (I have tried this setting on and off)
headphone playback zc - off
speaker - db gain: -17 -17
speaker ac - 0
speaker dc - 0
speaker playback zc - off
PCM Playback - 00 (enabled)
Mono Output Mixer Left - off
Mono Output Mixer Right - off
Playback - DB -20 -20
capture volume zc - off - (NOTE: I have had this off and on and neither make a difference)
3d - mute
3d filter lower cut-off - low
3d filter upper cut-off - high
ADC data - left data = left adc; right data = right adc
ADC high pass filter - off
ADC polarity - no inversion
ALC attack - 13
ALC Decay - 20
ALC Function - off
ALC Hold time - 0
ALC Max Gain - 100
ALC Min Gain - 0
ALC Mode - ALC
DAC Deemphasis - off
DAC Filter Characteristics - Normal
DAC Mono Mix - mono
DAC Polarity - No Inversion
Left Boost Mixer LINPUT1 - 00 (Enabled)
Left Boost Mixer LINPUT2 - Off (I have )
Left Boost Mixer LINPUT3- Off
Left Input Boost Mixer LINPUT1 - DB Gain 29 - 100%
Left Input Boost Mixer LINPUT2 - DB Gain 29 - 100%
Left Input Boost Mixer LINPUT3 - DB Gain mute - 0%
Left Input Mixer Boost - 00 (ENABLED)
Left Output Mixer Boost Bypass - db gain -15
Left Output Mixer LINPUT3 - db gain -15
Left Out Mixer PCM - 00 (ENABLED)
Noise Gate - off
Noise Gate Threshold - 0
Right Boost Mixer RINPUT1 - off
Right Boost Mixer RINPUT2 - off
Right Boost Mixer RINPUT3 - off
Right Input Boost Mixer RINPUT1 - DB Gain - 0%
Right Input Boost Mixer RINPUT2 - DB Gain mute - 0%
Right Input Boost Mixer RINPUT3 - DB Gain mute - 0%
Right Input Mixer Boost - off
Right Output Mixer Boost Bypass - DB Gain -15
Right Output Mixer PCM - off
Right Output Mixer RINPUT3 - DB Gain -15
/boot/firmware/config.txt
# For more options and information see
# http://rptl.io/configtxt
# Some settings may impact device functionality. See link above for details
dtdebug=1
# Uncomment some or all of these to enable the optional hardware interfaces
dtparam=i2c_arm=on
dtparam=i2s=on
#dtparam=spi=on
# Enable audio (loads snd_bcm2835)
dtparam=audio=on
# Additional overlays and parameters are documented
# /boot/firmware/overlays/README
# Automatically load overlays for detected cameras
camera_auto_detect=1
# Automatically load overlays for detected DSI displays
display_auto_detect=1
# Automatically load initramfs files, if found
auto_initramfs=1
# Enable DRM VC4 V3D driver
dtoverlay=vc4-kms-v3d
max_framebuffers=2
# Don't have the firmware create an initial video= setting in cmdline.txt.
# Use the kernel's default instead.
disable_fw_kms_setup=1
# Run in 64-bit mode
arm_64bit=1
# Disable compensation for displays with overscan
disable_overscan=1
# Run as fast as firmware / board allows
arm_boost=1
[cm4]
# Enable host mode on the 2711 built-in XHCI USB controller.
# This line should be removed if the legacy DWC2 controller is required
# (e.g. for USB device mode) or if USB support is not required.
otg_mode=1
[cm5]
dtoverlay=dwc2,dr_mode=host
[all]
dtoverlay=wm8960-soundcard
The Problem
When trying to record audio, the audio file is completely silent. I have used the following commands to record and then test the file.
Note: I have also attempted to listen to the file and it is silent. I have also attempted to pipe the recording into the speaker and can confirm, I hear nothing.
arecord -D plughw:3,0 -f S16_LE -r 44100 -c 1 -d 10 test-mic.wav
sox test-mic.wav -n stat
Levels Remain at 0
arecord -D plughw:3,0 -f S16_LE -r 44100 -c1 -V mono /dev/null
Suspected Issue
After a lot of trial and error, I believe the issue boils down to the MICBIAS not supplying voltage to the microphone. I have tested with my multimeter and it never seems to activate while recording on the device. I am not sure why voltage is not being supplied when recording, whether it is a setting I missed or if it is because the dtoverlay does not set MICBIAS
When running dmesg | grep -i wm8960
I get the following messages
[ 7.450473] wm8960 1-001a: supply DCVDD not found, using dummy regulator
[ 7.450704] wm8960 1-001a: supply DBVDD not found, using dummy regulator
[ 7.450891] wm8960 1-001a: supply SPKVDD1 not found, using dummy regulator
[ 7.450949] wm8960 1-001a: supply SPKVDD2 not found, using dummy regulator
I am not sure if this is relevant or not to my issue.
What Have I Tried
I have tried changing the audio capture controls around a lot and none seem to make the MIC work. I began looking into the built in dtoverlay. I don’t know much about overlays but noticed the official one bundled with the OS is for this this audio hat specifically and may hold the key to my issue.
I attempted to modify the dtoverlay to add some things that I might need. Granted, my knowledge is extremely limited with this and likely not correct. Here are the changes I made.
Within fragment@2 I added micbias-supply
and micbias-resistor
like so:
fragment@2 {
target = <&i2c1>;
__overlay__ {
#address-cells = <1>;
#size-cells = <0>;
status = "okay";
wm8960: wm8960@1a {
compatible = "wlf,wm8960";
reg = <0x1a>;
#sound-dai-cells = <0>;
AVDD-supply = <&vdd_5v0_reg>;
DVDD-supply = <&vdd_3v3_reg>;
clocks = <&wm8960_mclk>;
clock-names = "mclk";
micbias-supply = <&vdd_3v3_reg>;
micbias-resistor = <2200>;
};
};
};
Within fragment@3 I added the LINPUT2 to the simple-audio-card,routing section like so:
simple-audio-card,routing =
"Headphone Jack", "HP_L",
"Headphone Jack", "HP_R",
"Speaker", "SPK_LP",
"Speaker", "SPK_LN",
"LINPUT1", "Mic Jack",
"LINPUT2", "Mic Jack",
"LINPUT3", "Mic Jack",
"RINPUT1", "Mic Jack",
"RINPUT2", "Mic Jack";
For compiling I used the following commands for all of my attempts
sudo dtc -@ -I dts -O dtb -o wm8960-soundcard-bias.dtbo wm8960-soundcard-bias-overlay.dts
sudo cp wm8960-soundcard-bias.dtbo /boot/firmware/overlays/
Then updated the config.txt file to match the correct name of the new dtoverlay dtoverlay=wm8960-soundcard-bias
and rebooted.
To test that the audio card actually applied these settings to the device tree I ran the following commands:
sudo dtc -I fs -O dts /proc/device-tree > /tmp/flat.dts
grep -R "micbias" -n /tmp/flat.dts
Which yielded this result
253: micbias-resistor = <0x898>;
261: micbias-supply = <0xef>;
Conclusion
I have tried rewiring the audio a few times to ensure it wasn’t an issue with the wiring. I have checked that nothing is shorted on the hardware side and I2C is communicating. I have check voltages and everything is good except the MICBIAS pin. The speakers work.
I am not sure where to go from here. I assume that this audio hat does not require MICBIAS because of the built in MEMS microphone and therefore the controls are not in the dtoverlay. I do not know enough about dtoverlays to make the necessary modifications to port to the SparkFun WM8960 Breakout Board.
If anyone could point me in the right direction I would truly appreciate it.