dwhinham / mt32-pi

🎹🎶 A baremetal kernel that turns your Raspberry Pi 3 or later into a Roland MT-32 emulator and SoundFont synthesizer based on Circle, Munt, and FluidSynth.
https://twitter.com/d0pefish
GNU General Public License v3.0
1.28k stars 81 forks source link

💡 [FEATURE] Support Waveshare WM8960 DAC #273

Closed probonopd closed 2 years ago

probonopd commented 2 years ago

Is your feature request related to a problem? Please describe.

The Waveshare WM8960 audio hat is an inexpensive DAC with built in speaker amplifier.

It is based on the Wolfson Microelectronics WM8960 "Stereo CODEC with 1W Stereo Class D Speaker Drivers and Headphone Drivers for Portable Audio Applications".

Describe the solution you'd like

It would be nice if it could be supported.

Describe alternatives you've considered

Buying yet another DAC, just for mt32-pi. But the alternatives are often more costly and lack the speaker amplifier.

Additional context

pi@rpizero:~ $ aplay -l
**** List of PLAYBACK Hardware Devices ****
card 0: wm8960soundcard [wm8960-soundcard], device 0: bcm2835-i2s-wm8960-hifi wm8960-hifi-0 []
  Subdevices: 1/1
  Subdevice #0: subdevice #0

pi@rpizero:~ $ arecord -l
**** List of CAPTURE Hardware Devices ****
card 0: wm8960soundcard [wm8960-soundcard], device 0: bcm2835-i2s-wm8960-hifi wm8960-hifi-0 []
  Subdevices: 1/1
  Subdevice #0: subdevice #0

pi@rpizero:~ $ i2cdetect -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- UU -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --

More information: https://www.kernel.org/doc/Documentation/devicetree/bindings/sound/wm8960.txt

probonopd commented 2 years ago

Setting i2c_dac_address in mt32-pi.cfg as described on https://github.com/dwhinham/mt32-pi/wiki/I²S-DACs does not make this work. Probably some initialization sequence is needed?

Here is the Linux driver: https://github.com/waveshare/WM8960-Audio-HAT/blob/0e427ada34b365e40b4b7822f74be96c6b57d589/wm8960.c

Here is the data sheet of the WM8960: https://www.waveshare.com/w/upload/1/18/WM8960_v4.2.pdf

It says:

Each analogue output of the WM8960 can be independently enabled or disabled. The analogue mixer associated with each output is powered on or off along with the output pin. All outputs are disabled by default. To save power, unused outputs should remain disabled.

So I think we need to find an init sequence that enables the speaker and/or headphone (OUT3) output.

Looking at Table 26, "Analogue Output Control", to enable OUT3 one must set the value of the first bit at address 0x1A to 1.

Possibly one also needs to configure the WM8960 to use i2s (Table 33).

For the speaker output, more needs to be done which I don't quite understand yet (Table 28). it is also possible to switch automatically from headphone to speaker (Table 29).

dwhinham commented 2 years ago

This looks like a decent DAC, and as always I'd like to support it, but it's difficult for me to add support for new DACs without having the hardware in front of me.

I'll gladly accept a patch for it, on the understanding that I will be unable to test it or maintain it, otherwise I've added it to the Amazon wishlist, so if someone purchases it I'll try to get it working.

The approach I've used before is to do dumps of all of the i2c registers of the device, using Linux - once without the driver loaded (no devicetree etc), and once with it loaded (and in a working state that produces sound).

Then compare the two, and cross-reference with the datasheet and try to work out the minimum required register pokes.

probonopd commented 2 years ago

The approach I've used before is to do dumps of all of the i2c registers of the device, using Linux

Using i2cdump? Do you have a command to do that?

dwhinham commented 2 years ago

I can't remember, sorry; been a long time since I did this

probonopd commented 2 years ago

A PR for supporting the WM8960 DAC has arrived in Circle:

https://github.com/rsta2/circle/pull/286

It even auto-detects well-known DACs on i2c.

dwhinham commented 2 years ago

Yes, I can see - I get notifications.

I'll wait to see if it gets tested and/or amended by Rene before doing anything, because like I say I do not own this hardware, and I don't want any "auto-detection" to break existing setups.