Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ucm2: Intel: avs: Add UCM files for HDA configuration #499

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

amadeuszslawinski-intel

Add configs for devices using HDA codec.

Add configs for devices using HDA codec.

Signed-off-by: Amadeusz Sławiński <amadeuszx.slawinski@linux.intel.com>
@amadeuszslawinski-intel
Copy link
Author

amadeuszslawinski-intel commented Jan 23, 2025

As discussed in https://bugzilla.kernel.org/show_bug.cgi?id=219654 I'm trying to enable HDA configuration for users. I'm using UCMs present in this PR.

On device I'm testing at:

# aplay -l
**** List of PLAYBACK Hardware Devices ****
card 1: hdaudioB0D0 [hdaudioB0D0], device 1: HDAudio Analog (*) []
  Subdevices: 1/1
  Subdevice #0: subdevice #0

Controls:

# amixer -c1 controls
numid=13,iface=CARD,name='Headphone Jack'
numid=12,iface=CARD,name='Internal Mic Phantom Jack'
numid=11,iface=CARD,name='Mic Jack'
numid=14,iface=CARD,name='Speaker Phantom Jack'
numid=10,iface=MIXER,name='Master Playback Switch'
numid=9,iface=MIXER,name='Master Playback Volume'
numid=2,iface=MIXER,name='Headphone Playback Switch'
numid=1,iface=MIXER,name='Line Out Playback Volume'
numid=7,iface=MIXER,name='Mic Boost Volume'
numid=6,iface=MIXER,name='Capture Switch'
numid=5,iface=MIXER,name='Capture Volume'
numid=4,iface=MIXER,name='Auto-Mute Mode'
numid=8,iface=MIXER,name='Internal Mic Boost Volume'
numid=3,iface=MIXER,name='Speaker Playback Switch'

UCM dump:

# alsaucm -c hw:1 dump text
Verb.HiFi {
        Comment "Play HiFi quality Music"
        Device.Headphones {
                Comment Headphones
                Values {
                        CaptureCTL "_ucm0001.hw:hdaudioB0D0"
                        JackControl "Headphone Jack"
                        PlaybackCTL "_ucm0001.hw:hdaudioB0D0"
                        PlaybackMasterElem Master
                        PlaybackMixerElem Headphone
                        PlaybackPCM "_ucm0001.hw:hdaudioB0D0"
                        PlaybackPriority 200
                        PlaybackSwitch "Headphone Playback Switch"
                        PlaybackVolume "Headphone Playback Volume"
                }
        }
        Device.Speaker {
                Comment Speaker
                Values {
                        CaptureCTL "_ucm0001.hw:hdaudioB0D0"
                        PlaybackCTL "_ucm0001.hw:hdaudioB0D0"
                        PlaybackMasterElem Master
                        PlaybackMixerElem Speaker
                        PlaybackPCM "_ucm0001.hw:hdaudioB0D0"
                        PlaybackPriority 100
                        PlaybackSwitch "Speaker Playback Switch"
                        PlaybackVolume "Speaker Playback Volume"
                }
        }
        Device.Mic1 {
                Comment "Headphones Stereo Microphone"
                ConflictingDevices [
                        Mic2
                ]
                Values {
                        CaptureCTL "_ucm0001.hw:hdaudioB0D0"
                        CaptureMasterElem "Mic Boost"
                        CaptureMixerElem Capture
                        CapturePCM "_ucm0001.hw:hdaudioB0D0"
                        CapturePriority 200
                        CaptureSwitch "Capture Switch"
                        CaptureVolume "Capture Volume"
                        JackControl "Mic Jack"
                        PlaybackCTL "_ucm0001.hw:hdaudioB0D0"
                }
        }
        Device.Mic2 {
                Comment "Internal Stereo Microphone"
                ConflictingDevices [
                        Mic1
                ]
                Values {
                        CaptureCTL "_ucm0001.hw:hdaudioB0D0"
                        CaptureMasterElem "Internal Mic Boost"
                        CaptureMixerElem Capture
                        CapturePCM "_ucm0001.hw:hdaudioB0D0"
                        CapturePriority 400
                        CaptureSwitch "Capture Switch"
                        CaptureVolume "Capture Volume"
                        PlaybackCTL "_ucm0001.hw:hdaudioB0D0"
                }
        }
}

With spa-acp-tool:

# spa-acp-tool
>>>card hw:1
>>>list-verbose
card 0: profiles:2 devices:0 ports:0
    properties: (4)
        use-ucm = "true"
        verbose = "true"
        alsa.card = "0"
        device.string = "0"
    profile 0: name:"off" prio:0 (available: yes)
        description:"Off"
        devices: (0)
  * profile 1: name:"pro-audio" prio:1 (available: yes)
        description:"Pro Audio"
        devices: (0)

Problem is that even though it seems that UCM was loaded, it doesn't seem to be usable from GUI, only "Dummy output" is present in settings.

@perexg
Copy link
Member

perexg commented Jan 23, 2025

Add -v argument (verbose mode) to spa-acp-tool to see the probing path.

@amadeuszslawinski-intel
Copy link
Author

amadeuszslawinski-intel commented Jan 23, 2025

Looking at previous log I'm starting to suspect that card hw:1 does not work as I expect it too. Anyway after making HDA to enumerate as card 0:

spa-acp-tool log
# spa-acp-tool -v
card has no events
card 0: profiles:2 devices:2 ports:0
type 'help' for usage.
>>>list-verbose
card 0: profiles:2 devices:2 ports:0
    properties: (11)
        use-ucm = "true"
        verbose = "true"
        alsa.card = "0"
        alsa.card_name = "hdaudioB0D0"
        alsa.long_card_name = "LENOVO-20KH006LPB-ThinkPadX1Carbon6th"
        alsa.driver_name = "snd_soc_avs_hdaudio"
        alsa.mixer_name = "Realtek ALC285"
        alsa.components = "HDA:10ec0285,17aa225c,00100002"
        alsa.id = "hdaudioB0D0"
        device.string = "0"
        device.description = "hdaudioB0D0"
    profile 0: name:"off" prio:0 (available: yes)
        description:"Off"
        devices: (0)
  * profile 1: name:"pro-audio" prio:1 (available: yes)
        description:"Pro Audio"
        devices: (2)
          * device 0: direction:playback name:"pro-output-1" prio:0 flags:00000001 devices: "hw:0,1"
          * device 1: direction:capture name:"pro-input-1" prio:0 flags:00000001 devices: "hw:0,1"
  * device 0: direction:playback name:"pro-output-1" prio:0 flags:00000001 devices: "hw:0,1"
        rate:48000 channels:2
        properties: (25)
            alsa.resolution_bits = "32"
            device.api = "alsa"
            device.class = "sound"
            alsa.class = "generic"
            alsa.subclass = "generic-mix"
            alsa.name = ""
            alsa.id = "hdaudioB0D0"
            alsa.subdevice = "0"
            alsa.subdevice_name = "subdevice #0"
            alsa.device = "1"
            alsa.card = "0"
            alsa.card_name = "hdaudioB0D0"
            alsa.long_card_name = "LENOVO-20KH006LPB-ThinkPadX1Carbon6th"
            alsa.driver_name = "snd_soc_avs_hdaudio"
            alsa.mixer_name = "Realtek ALC285"
            alsa.components = "HDA:10ec0285,17aa225c,00100002"
            clock.name = "api.alsa.0"
            device.profile.pro = "true"
            node.group = "pro-audio-0"
            node.link-group = "pro-audio-0"
            api.alsa.auto-link = "true"
            api.alsa.disable-tsched = "true"
            device.profile.name = "pro-output-1"
            device.profile.description = "Pro"
            card.profile.device = "0"
        ports: (0)
  * device 1: direction:capture name:"pro-input-1" prio:0 flags:00000001 devices: "hw:0,1"
        rate:48000 channels:2
        properties: (25)
            alsa.resolution_bits = "32"
            device.api = "alsa"
            device.class = "sound"
            alsa.class = "generic"
            alsa.subclass = "generic-mix"
            alsa.name = ""
            alsa.id = "hdaudioB0D0"
            alsa.subdevice = "0"
            alsa.subdevice_name = "subdevice #0"
            alsa.device = "1"
            alsa.card = "0"
            alsa.card_name = "hdaudioB0D0"
            alsa.long_card_name = "LENOVO-20KH006LPB-ThinkPadX1Carbon6th"
            alsa.driver_name = "snd_soc_avs_hdaudio"
            alsa.mixer_name = "Realtek ALC285"
            alsa.components = "HDA:10ec0285,17aa225c,00100002"
            clock.name = "api.alsa.0"
            device.profile.pro = "true"
            node.group = "pro-audio-0"
            node.link-group = "pro-audio-0"
            api.alsa.auto-link = "true"
            api.alsa.disable-tsched = "true"
            device.profile.name = "pro-input-1"
            device.profile.description = "Pro"
            card.profile.device = "1"
        ports: (0)

@perexg
Copy link
Member

perexg commented Jan 23, 2025

I forgot that -v should be used multiple times to increase verbosity like -vvvvvvv.

EDIT: And you can select card with -c like: spa-acp-tool -c 1 -vvvvvvvvv

@amadeuszslawinski-intel
Copy link
Author

amadeuszslawinski-intel commented Jan 23, 2025

Yes and call list-verbose from command line, I was just confused by it not working in interactive mode (I tried both card 1 and card hw:1).

New part of output attached, the rest is as in previous log:
# spa-acp-tool -vvvvvvv -c 0 list-verbose
UCM available for card hw:0
UCM _alibpref=_ucm0001.
Set UCM verb to HiFi
Got CapturePCM for device Mic2: _ucm0001.hw:hdaudioB0D0
Got PlaybackCTL for device Mic2: _ucm0001.hw:hdaudioB0D0
Got CaptureCTL for device Mic2: _ucm0001.hw:hdaudioB0D0
Got CaptureVolume for device Mic2: Capture Volume
Got CaptureSwitch for device Mic2: Capture Switch
Got CaptureMixerElem for device Mic2: Capture
Got CaptureMasterElem for device Mic2: Internal Mic Boost
Got CapturePriority for device Mic2: 400
UCM file does not specify 'CaptureChannels' for device Mic2, assuming stereo.
No _supporteddevs for device Mic2
Got CapturePCM for device Mic1: _ucm0001.hw:hdaudioB0D0
Got PlaybackCTL for device Mic1: _ucm0001.hw:hdaudioB0D0
Got CaptureCTL for device Mic1: _ucm0001.hw:hdaudioB0D0
Got CaptureVolume for device Mic1: Capture Volume
Got CaptureSwitch for device Mic1: Capture Switch
Got CaptureMixerElem for device Mic1: Capture
Got CaptureMasterElem for device Mic1: Mic Boost
Got CapturePriority for device Mic1: 200
Got JackControl for device Mic1: Mic Jack
UCM file does not specify 'CaptureChannels' for device Mic1, assuming stereo.
No _supporteddevs for device Mic1
Got PlaybackPCM for device Speaker: _ucm0001.hw:hdaudioB0D0
Got PlaybackCTL for device Speaker: _ucm0001.hw:hdaudioB0D0
Got PlaybackVolume for device Speaker: Speaker Playback Volume
Got PlaybackSwitch for device Speaker: Speaker Playback Switch
Got PlaybackMixerElem for device Speaker: Speaker
Got PlaybackMasterElem for device Speaker: Master
Got PlaybackPriority for device Speaker: 100
Got CaptureCTL for device Speaker: _ucm0001.hw:hdaudioB0D0
UCM file does not specify 'PlaybackChannels' for device Speaker, assuming stereo.
No _conflictingdevs for device Speaker
No _supporteddevs for device Speaker
Got PlaybackPCM for device Headphones: _ucm0001.hw:hdaudioB0D0
Got PlaybackCTL for device Headphones: _ucm0001.hw:hdaudioB0D0
Got PlaybackVolume for device Headphones: Headphone Playback Volume
Got PlaybackSwitch for device Headphones: Headphone Playback Switch
Got PlaybackMixerElem for device Headphones: Headphone
Got PlaybackMasterElem for device Headphones: Master
Got PlaybackPriority for device Headphones: 200
Got CaptureCTL for device Headphones: _ucm0001.hw:hdaudioB0D0
Got JackControl for device Headphones: Headphone Jack
UCM file does not specify 'PlaybackChannels' for device Headphones, assuming stereo.
No _conflictingdevs for device Headphones
No _supporteddevs for device Headphones
Found UCM profiles
UCM mapping: HiFi: hw:hdaudioB0D0: source dev Mic2
UCM mapping: HiFi: hw:hdaudioB0D0: source dev Mic1
UCM mapping: HiFi: hw:hdaudioB0D0: sink dev Speaker
UCM mapping: HiFi: hw:hdaudioB0D0: sink dev Headphones
Profile HiFi (Play HiFi quality Music), input=null, output=null priority=8000, supported=yes n_input_mappings=1, n_output_mappings=1
Input HiFi: hw:hdaudioB0D0: source
Output HiFi: hw:hdaudioB0D0: sink
Set ucm verb to HiFi
Trying _ucm0001.hw:hdaudioB0D0 with SND_PCM_NO_AUTO_FORMAT ...
open '/dev/snd/pcmC0D0p' failed (-2)
Error opening PCM device _ucm0001.hw:hdaudioB0D0: No such file or directory
Trying hw:0,1 with SND_PCM_NO_AUTO_FORMAT ...
ALSA device open 'hw:0,1' playback: 0x55ec9ace0750
Maximum hw buffer size is 10922 ms
Set buffer size first (to 65536 samples), period size second (to 1024 samples).
Device hw:0,1 doesn't support 64 channels, changed to 2.
ALSA device close 0x55ec9ace0750
Trying hw:0,1 with SND_PCM_NO_AUTO_FORMAT ...
ALSA device open 'hw:0,1' capture: 0x55ec9acdfaa0
Maximum hw buffer size is 10922 ms
Set buffer size first (to 65536 samples), period size second (to 1024 samples).
Device hw:0,1 doesn't support 64 channels, changed to 2.
ALSA device close 0x55ec9acdfaa0
Found 0 jacks.
activate profile: pro-audio (1)
Device: Pro mapping 'Pro' (pro-output-1).
Device: Pro mapping 'Pro' (pro-input-1).

I assume that:
No _supporteddevs for device Speaker
is just informative that UCM does not contain that part, or does it mean that it will not work?

There is also:

open '/dev/snd/pcmC0D0p' failed (-2)
Error opening PCM device _ucm0001.hw:hdaudioB0D0: No such file or directory

why does it try to open device '0', when in aplay -l output there is only device '1' on card 0: card 0: hdaudioB0D0 [hdaudioB0D0], device 1: HDAudio Analog (*) []
but overall it seems to go further and tries hw:0,1 later and it succeeds from what I can tell from above log and dmesg.

@perexg
Copy link
Member

perexg commented Jan 23, 2025

Thanks.

I assume that: No _supporteddevs for device Speaker is just informative that UCM does not contain that part, or does it mean that it will not work?

You can ignore this warning.

open '/dev/snd/pcmC0D0p' failed (-2)
Error opening PCM device _ucm0001.hw:hdaudioB0D0: No such file or directory

It's the real error. As you can see, UCM config specifies that the playback is on device 0:

        Device.Speaker {
                Comment Speaker
                Values {
                        CaptureCTL "_ucm0001.hw:hdaudioB0D0"
                        PlaybackCTL "_ucm0001.hw:hdaudioB0D0"
                        PlaybackMasterElem Master
                        PlaybackMixerElem Speaker
                        PlaybackPCM "_ucm0001.hw:hdaudioB0D0"
                                     ^^^^^^^^^^^^^^^^^^^^^^^^ no device parameter means 0 by default
                        PlaybackPriority 100
                        PlaybackSwitch "Speaker Playback Switch"
                        PlaybackVolume "Speaker Playback Volume"
                }
        }

why does it try to open device '0', when in aplay -l output there is only device '1' on card 0: card 0: hdaudioB0D0 [hdaudioB0D0], device 1: HDAudio Analog (*) [] but overall it seems to go further and tries hw:0,1 later and it succeeds from what I can tell from above log and dmesg.

The hw:0,1 seems to be used for direct "Pro" devices only (not sure why Wim used this really misleading name). It has nothing related to UCM.

@amadeuszslawinski-intel
Copy link
Author

Yeah, the device IDs not starting from '0' were one of the things that always bothered me a bit, but I considered them just a cosmetic nuisance not something that may cause problems.

Seems like in soc_new_pcm_runtime() regardless of whether we create struct snd_soc_pcm_runtime for BE or FE the id is being raised by 1. As ASoC creates BEs first it ends up creating FEs starting from id that is not 0.

With simple patch like:

--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -558,7 +558,8 @@ static struct snd_soc_pcm_runtime *soc_new_pcm_runtime(
         */
        rtd->card       = card;
        rtd->dai_link   = dai_link;
-       rtd->id         = card->num_rtd++;
+       if (!rtd->dai_link->no_pcm)
+               rtd->id         = card->num_rtd++;
        rtd->pmdown_time = pmdown_time;                 /* default power off timeout */

        /* see for_each_card_rtds */

it seems to create devices with IDs starting from 0. And the error also seems to be gone when loading UCMs.

However there are sadly arguments against this approach:

  • while rtd->id is not used much, few boards seem to be using it as index into a table, above may break this use
    (although include/sound/simple_card_utils.h: * the ID stored in rtd->id may not be a valid array index. suggests that maybe it is a bad idea, but I'm not sure how generic that comment is)
  • this will break user scripts, with hardcoded device IDs
  • this will also break some UCMs with hardcoded IDs

Probably more backward compatible solution will be to add Device parameter like one HDMI has to HDA.

Do you think, I should try proceeding with kernel patch or is it better to just improve UCM file to accept parameter?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants