megi's PinePhone Development Log RSS

Genocide is bad

2020–09–29: New codec driver in my 5.9 kernel

Samuel updated his codec patches a few days ago, noting in the dev chat:

I have a branch ready for anyone wanting to test the new audio patches: https://github.com/smaeul/linux/commits/pine64-5.9 three notes:

  1. Set PulseAudio to use a 48 kHz sample rate and an 8 kHz alternate rate. Both must be multiples of 8 kHz or modem/BT audio won't work.
  2. You must use a QDAI config with the codec as master (modem as slave) and an 8 kHz sample rate. Use AT+QDAI=1,1,0,1,0,0,1,1 unless you have a very good reason not to.
  3. You must use a BT config with the codec as master (BT as slave) and 2 PCM slots. Use len=2 offset=00f6 { 85 10 }.

This does include jack detection and headset mic button detection. I don't have any three-button headsets, so I can't test the volume up/down functionality. it has the „80% solution“ to call audio quality – it will sound fine unless something tries to play/record audio from/to the CPU at a sample rate >8 kHz during a call

To clarify note 1 above: you can use both 44.1 kHz streams (music) and 8 kHz streams (modem), but not at the same time. so unless you have some way to kill all 44.1 kHz streams before starting a call (can UCM do that?), the sample rates have to be compatible

And some time later:

I pushed some more changes, including a fix for the high-pitched whine from the speaker it was a harmonic from the audio PLL, and I believe it's leaking from VCC-PLL → AVCC, since the noise is the same on the headphones and speaker.

So I made two changes:

  1. triple the frequency of PLL_AUDIO, which needed to be done anyway for using the sample rate converter. now the harmonic at 44100 (previously the whine) is inaudible, and the harmonic at 48000 is lower frequency, so less annoying
  2. decreased the PLL bias current, which drastically decreases the volume of both the harmonics and the white noise if you want to try out a different series of frequencies (1×, 4×, 6×), adjust the last two hunks in https://github.com/smaeul/linux/commit/7b51d5b09136

So I spent some time pulling the new codec patches to my kernel and rebasing my patches for X-Powers AC100 codec support on top of them, so that I can merge them into my kernel.

This went fine, and the results are as described by Samuel. Modem audio is nice and smooth, as long as you don't use alsa PCM interfaces during a call with any other sample rate than 8kHz. And the new jack detection works too.

One issue that people may hit with the new codec support is that some ALSA controls were renamed. I made the list of changes from the code diffs:

#!/bin/sh

sed -i 's/AIF1 AD0 Mixer AIF1 DA0 Capture Switch/AIF1 Slot 0 Digital ADC Capture Switch/' "$1"
sed -i 's/AIF1 AD0 Mixer AIF2 DAC Capture Switch/AIF2 Digital ADC Capture Switch/' "$1"
sed -i 's/AIF1 AD0 Mixer ADC Capture Switch/AIF1 Data Digital ADC Capture Switch/' "$1"
sed -i 's/AIF1 AD0 Mixer AIF2 DAC Rev Capture Switch/AIF2 Inv Digital ADC Capture Switch/' "$1"
sed -i 's/DAC Mixer AIF1 DA0 Playback Switch/AIF1 Slot 0 Digital DAC Playback Switch/' "$1"
sed -i 's/DAC Mixer AIF1 DA1 Playback Switch/AIF1 Slot 1 Digital DAC Playback Switch/' "$1"
sed -i 's/DAC Mixer AIF2 DAC Playback Switch/AIF2 Digital DAC Playback Switch/' "$1"
sed -i 's/DAC Mixer ADC Playback Switch/ADC Digital DAC Playback Switch/' "$1"
sed -i 's/AIF3 DAC Playback Route/AIF2 DAC Source Playback Route/' "$1"
sed -i 's/AIF3 ADC Capture Route/AIF3 ADC Source Capture Route/' "$1"

exit

# and then manually:

AIF2 DAC Source Playback Route:
        "None", "AIF2 Left", "AIF2 Right" 
        "AIF2", "AIF3+2", "AIF2+3"        

AIF3 ADC Output Mux:
        "None", "AIF2 Left", "AIF2 Right" 
        "None", "AIF2 ADCL", "AIF2 ADCR"  

Remove "AIF3 Loopback Switch"
       "AIF1 Loopback Switch"
       "AIF2 Loopback Switch"


##########################
# Direct mapping from old to new names (semantics are the same):
##########################

- "AIF1 AD0 Mixer AIF1 DA0 Capture Switch"
+ "AIF1 Slot 0 Digital ADC Capture Switch"

- "AIF1 AD0 Mixer AIF2 DAC Capture Switch"
+ "AIF2 Digital ADC Capture Switch"

- "AIF1 AD0 Mixer ADC Capture Switch"
+ "AIF1 Data Digital ADC Capture Switch"

- "AIF1 AD0 Mixer AIF2 DAC Rev Capture Switch"
+ "AIF2 Inv Digital ADC Capture Switch"

- "DAC Mixer AIF1 DA0 Playback Switch"
+ "AIF1 Slot 0 Digital DAC Playback Switch"

- "DAC Mixer AIF1 DA1 Playback Switch",
+ "AIF1 Slot 1 Digital DAC Playback Switch",

- "DAC Mixer AIF2 DAC Playback Switch"
+ "AIF2 Digital DAC Playback Switch"

- "DAC Mixer ADC Playback Switch"
+ "ADC Digital DAC Playback Switch"

- "AIF3 DAC Playback Route"            "None", "AIF2 Left", "AIF2 Right"
+ "AIF2 DAC Source Playback Route"     "AIF2", "AIF3+2", "AIF2+3"

- "AIF3 ADC Capture Route"             "None", "AIF2 Left", "AIF2 Right"
+ "AIF3 ADC Source Capture Route"      "None", "AIF2 ADCL", "AIF2 ADCR"

- "AIF3 Loopback Switch"
- "AIF1 Loopback Switch"
- "AIF2 Loopback Switch"

You can run the above script to patch up your UCM profile or whatever. I've updated my call audio setup script, for the new controls too.

If you like to test new audio patches you can grab my kernel at usual places: https://xff.cz/kernels or at https://megous.com/git/linux/

Modem reset

It turns out that Quectel managed to break modem reset via AT+CFUN=1,1, while adding support for fast poweroff. This manifests itself by modem powering off instead of rebooting when fast poweroff is enabled.

I had to patch my modem driver to disable fast poweroff during a reset after QDAI update, so that QDAI updates work smoothly with the new QDAI necessary for the above mentioned codec changes.