Volumio2 icon indicating copy to clipboard operation
Volumio2 copied to clipboard

Using Alsa UCM for Intel x86 baytrail/ cherrytrail devices

Open gkkpch opened this issue 4 years ago • 0 comments

Some Intel soc audio codecs found on cherry and baytrail devices (as seen on Intel Atom and some Intel Celeron) are fairly complicated to configure properly. By using Alsa UCM, the complicated low level setting of mixers is being taken care of based on a set of codec-specific UCM configuration files. Enabling headphones or a speaker now comes down to executing a simple alsaucm command only.

While testing alsaucm successfully on a Z8350 with an rt5640 codec the last few days, I stumbled over an issue, for which we should find an elegant fix. Not only are these codecs a little complicated, some also offer different output channels on a single output device. So we now not only have to deal with single device cards, multi-device cards (we cover these two really well) but also with multi-channel output from a single- or muti-device card. As an example, the rt5640 and rt5651 codecs offer speaker and headphones routing (and a few more which are irrelevant for us).

Currently I can pre-configure rt5640's headphones and speakers at x86 build time, but then either both of them are active or only one of the two. This seem to work OKish with Volumio, but having speakers and headphones active at the same time makes little sense and whichever single one is fixed at build time is bound to be the wrong one. To switch between the two it at runtime only needs a simple script command, something like this:

  /usr/bin/alsaucm -c {devicecardname}  reset set _verb HiFi set _enadev {Headphones|Speaker}
e.g.
  /usr/bin/alsaucm -c bytcr-rt5640  reset set _verb HiFi set _enadev Headphones

Currently, alsa ucm treats speaker and headphones as "conflicting" devices, so with alsaucm you enable one, the other one gets silenced automatically. There is probably nothing else we need.

I believe there is not much we need to add to make this working.

  • The prettyname in cards.json must be standardised for these devices, either "Headphones" or "Speaker". They are consistently named like this in alsa ucm configurations, for us no issue. I only found one with RC aout, but has no spekers or headphone. That one would not need our fix.
  • Valid cards are listed in /usr/share/alsa/ucm folders:
volumio@volumio:/volumio/app/plugins/audio_interface/alsa_controller$ ls -l /usr/share/alsa/ucm
total 21
drwxr-xr-x 2 root root 1024 Feb 20 21:41 byt-max98090
drwxr-xr-x 2 root root 1024 Feb 20 21:41 byt-rt5640
drwxr-xr-x 2 root root 1024 Feb 20 21:41 bytcht-da7213
drwxr-xr-x 2 root root 1024 Feb 20 21:41 bytcht-nocodec
drwxr-xr-x 2 root root 1024 Feb 20 21:41 bytcht-pcm512x
drwxr-xr-x 2 root root 1024 Feb 21 15:13 bytcr-rt5640
drwxr-xr-x 2 root root 1024 Feb 20 21:41 bytcr-rt5651
drwxr-xr-x 2 root root 1024 Feb 20 21:41 cht-bsw-rt5672
drwxr-xr-x 2 root root 1024 Feb 20 21:41 chtmax98090
drwxr-xr-x 2 root root 1024 Feb 20 21:41 chtnau8824
drwxr-xr-x 2 root root 1024 Feb 20 21:41 chtrt5645
drwxr-xr-x 2 root root 1024 Feb 20 21:41 skl_hda_card
drwxr-xr-x 2 root root 1024 Feb 20 21:41 sof-bdw-rt5677
drwxr-xr-x 2 root root 1024 Feb 20 21:41 sof-bxt-pcm512x
drwxr-xr-x 2 root root 1024 Feb 20 21:41 sof-bxtda7219max
drwxr-xr-x 2 root root 1024 Feb 20 21:41 sof-bytcht-da7213
drwxr-xr-x 2 root root 1024 Feb 20 21:41 sof-bytcr-rt5640
drwxr-xr-x 2 root root 1024 Feb 20 21:41 sof-bytcr-rt5651
drwxr-xr-x 2 root root 1024 Feb 20 21:41 sof-cht-bsw-rt5672
drwxr-xr-x 2 root root 1024 Feb 20 21:41 sof-chtmax98090
drwxr-xr-x 2 root root 1024 Feb 20 21:41 sof-chtrt5645

There is also "alsaucm listcards", which brings a list of supported cards, but is perhaps more difficult to parse as non-numbered lines do not count:

volumio@volumio:/volumio/app/plugins/audio_interface/alsa_controller$ alsaucm listcards
  0: byt-max98090
    Orco internal card
  1: byt-rt5640
  2: bytcht-da7213
  3: bytcht-nocodec
  4: bytcht-pcm512x
  5: bytcr-rt5640
  6: bytcr-rt5651
  7: cht-bsw-rt5672
  8: chtmax98090
    chtmax98090 internal card
  9: chtnau8824
    chtnau8824 internal card
  10: chtrt5645
    Intel SoC Audio Device
  11: skl_hda_card
  12: sof-bdw-rt5677
    Samus internal card
  13: sof-bxt-pcm512x
  14: sof-bxtda7219max
    sof-bxtda7219max internal card
  15: sof-bytcht-da7213
  16: sof-bytcr-rt5640
  17: sof-bytcr-rt5651
  18: sof-cht-bsw-rt5672
  19: sof-chtmax98090
    sof-chtmax98090 internal card
  20: sof-chtrt5645
    SOF chtrt5645 audio device

To handle a bay/cherrytrail multi channel card device, a cards.json entry could look like this

{"name": "bytcr-rt5640", "multidevice": true, "devices":[{"number":0, "prettyname": "Headphone", "defaultmixer": "DAC1"}, {"number":0, "prettyname": "Speaker", "defaultmixer": "DAC1"}],"type":"integrated"},

Note, the card device number is the same, this is intended. For our purpose, the prettyname makes the necessary the distinction. So, after selecting a Output Device, Volumio should check

  • a) whether this is a ucm device
  • b) when it is, issue the above mentioned alsaucm command with the "prettyname" as target device.

The same command should also be called when starting up volumio, based on the the saved configuration.

There is one more issue: the rt5640 and rt5651 codecs do not work with 24/32bit rates, I activated resampling to 16bit. When people want better audio quality, then they should probably look for a USB DAC.

gkkpch avatar Feb 21 '21 18:02 gkkpch