No audio controls available for the imx-audio-card on torizon-minimal build

Good day everyone

A few months ago our company switch from the torizon-os to our own custom torizon-minimal build, which we build for you Verdin iMX8MP module. In our setup we have our custom speaker daemon, which we previously deployed in docker images, but now spaw it as a systemd process directly.

Now our problem: When we deployed our daemon in the container, we were able to set the volume of using the ALSA API in our daemon. Additionally, when spawing a shell in the container we could set the volume using alsamixer.

On our new setup however, this is not possible anymore. We can still play sounds but amixer/alsamixer cannot find any controls:

torizon@verdin-imx8mp-15337330:~$ amixer -c 0 controls
<empty>

But the soundcard gets detected:

torizon@verdin-imx8mp-15337330:~$ cat /proc/asound/cards
 0 [imxaudiocard   ]: imx-audio-card - imx-audio-card
                      imx-audio-card

Our hardware doesn’t have any codec so we disabled it in our dt-overlays (this we did in the torizon-os and in the minimal build):

/dts-v1/;
/plugin/;

#include "imx8mp-pinfunc.h"

/ {
	compatible = "toradex,verdin-imx8mp";
};

&{/} {
/* Defines custom sound card with I2S, using the imx-audio-card driver (imx-card.c).
 * If we do not specify any codec, the driver uses a dummy codec. This driver support different sample sizes, 
 * but only a single sampling rate (48000Hz), so resampling is done in ALSA
 */ 
    sound_i2s_dac {
        compatible = "fsl,imx-audio-card";
        model = "imx-audio-card"; // This is how the card will show up in linux (in /proc/asound/cards)
        pri-dai-link {
            link-name = "sai1";
            format = "i2s";
            cpu {
                sound-dai = <&sai1>;
            };
        };
    };
};

&sai1 {
    status = "okay";
    pinctrl-0 = <&pinctrl_sai1_bclk_lrclk_dout>;
    pinctrl-names = "default";
};

// We configure only 3-I2S lines, rather then the 5 as in the base DT. We don't need DIN nor MCLK
&iomuxc {
    pinctrl_sai1_bclk_lrclk_dout: pinctrl_sai1_bclk_lrclk_dout {
        fsl,pins =
        <MX8MP_IOMUXC_SAI5_MCLK__AUDIOMIX_SAI1_TX_BCLK 0x1d6>, /* SODIMM 30 */
        <MX8MP_IOMUXC_SAI5_RXD1__AUDIOMIX_SAI1_TX_SYNC 0x1d6>, /* SODIMM 32 */
        <MX8MP_IOMUXC_SAI5_RXFS__AUDIOMIX_SAI1_TX_DATA00 0x96>; /* SODIMM 34 */
    };
};

I already tried patching the kernel as discussed in: No soundcard detected on imx7d, Open Embedded Toradex BSP 2.8 , which did not change anything.

Do you have any idea what could be the problem?

Below you can find the dockerfile content and our new recipes that we use in the minimal build (as a new user I could not attach the files).

Dockerfile:

ARG CROSS_SDK_BASE_TAG=3.2.0
ARG BASE_VERSION=3.5.0
##
# Board architecture
##
ARG IMAGE_ARCH=

##
# Directory of the application inside container
##
ARG APP_ROOT=


# BUILD ------------------------------------------------------------------------
FROM torizon/debian-cross-toolchain-${IMAGE_ARCH}:${CROSS_SDK_BASE_TAG} AS build

ARG APP_ROOT
ARG IMAGE_ARCH

# __deps__
RUN apt-get -q -y update && \
    apt-get -q -y install \
    cmake \
# DO NOT REMOVE THIS LABEL: this is used for VS Code automation
    # __torizon_packages_build_start__
	    pkg-config:arm64 \
	    ssh:all \
	    libxml2-utils:arm64 \
	    xsltproc:arm64 \
	    libevent-dev:arm64 \
	    protobuf-compiler:arm64 \
	    libprotobuf-dev:arm64 \
	    libconfig++-dev:arm64 \
	    libasound2-dev:arm64 \
	    libsndfile-dev:arm64 \
	    alsa-utils:arm64 \
    # __torizon_packages_build_end__
# DO NOT REMOVE THIS LABEL: this is used for VS Code automation
    && \
    apt-get clean && apt-get autoremove && \
    rm -rf /var/lib/apt/lists/*
# __deps__

COPY . ${APP_ROOT}
WORKDIR ${APP_ROOT}

# Add GitHub's SSH host keys to the known hosts and install your dependencies
RUN --mount=type=ssh,id=private-key mkdir -p -m 0600 ~/.ssh && \
    ssh-keyscan github.com >> ~/.ssh/known_hosts 

# Remove the code from the debug builds, inside this container, to build the
# release version from a clean build
RUN rm -rf ${APP_ROOT}/build-${IMAGE_ARCH}

RUN --mount=type=ssh,id=private-key if [ "$IMAGE_ARCH" = "arm64" ] ; then \
        cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_COMPILER=aarch64-linux-gnu-g++ -DCMAKE_C_COMPILER=aarch64-linux-gnu-gcc -Bbuild-${IMAGE_ARCH} -DRUN_TESTS=OFF; \
    elif [ "$IMAGE_ARCH" = "armhf" ] ; then \
        cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_COMPILER=arm-linux-gnueabihf-g++ -DCMAKE_C_COMPILER=arm-linux-gnueabihf-gcc -Bbuild-${IMAGE_ARCH} ; \
    fi

RUN cmake --build build-${IMAGE_ARCH}

# BUILD ------------------------------------------------------------------------


##
# Deploy Step
##
FROM --platform=linux/${IMAGE_ARCH} torizon/debian:${BASE_VERSION} AS deploy

ARG IMAGE_ARCH
ARG APP_ROOT

RUN apt-get -y update && apt-get install -y --no-install-recommends \
# DO NOT REMOVE THIS LABEL: this is used for VS Code automation
    # __torizon_packages_prod_start__
	    libevent-dev:arm64 \
	    protobuf-compiler:arm64 \
	    libprotobuf-dev:arm64 \
	    libconfig++-dev:arm64 \
	    libasound2-dev:arm64 \
	    libsndfile-dev:arm64 \
	    alsa-utils:arm64 \
    # __torizon_packages_prod_end__
# DO NOT REMOVE THIS LABEL: this is used for VS Code automation
	&& apt-get clean && apt-get autoremove && rm -rf /var/lib/apt/lists/*

# Copy the application compiled in the build step to the $APP_ROOT directory
# path inside the container, where $APP_ROOT is the torizon_app_root
# configuration defined in settings.json
COPY --from=build ${APP_ROOT}/build-${IMAGE_ARCH}/bin ${APP_ROOT}
COPY --from=build ${APP_ROOT}/build-${IMAGE_ARCH}/_deps/scewo-messages-build/lib/libscewo-messages.so* /usr/lib/
COPY --from=build ${APP_ROOT}/build-${IMAGE_ARCH}/_deps/scewo-library-build/lib/libscewo.so* /usr/lib/
COPY --from=build ${APP_ROOT}/build-${IMAGE_ARCH}/_deps/log4cplus-build/src/liblog4cplus.so* /usr/lib/
# Workaround until we know how to fux our logging, like this the default logging (console logger) is used, which we can access with 'docker logs'
# COPY config/logging.ini /etc/speaker-daemon/ 

# Copy sound and config files to container
COPY config/sounds.cfg /etc/speaker-daemon/
COPY config/sounds/ /var/lib/speaker-daemon/sounds/
COPY config/.asoundrc /root/

# "cd" (enter) into the APP_ROOT directory
WORKDIR ${APP_ROOT}

# Command executed in runtime when the container starts
CMD ["./speaker-daemon"]

# DEPLOY -----------------------------------------------------------------------

Recipe:

SUMMARY = "Speaker Daemon on SCEWO wheelchair"
AUTHOR = "SCEWO"
HOMEPAGE = "https://scewo.ch/"
LICENSE = "SCEWO-1.0"
LIC_FILES_CHKSUM = "file://${SCEWO_LICENSE_PATH};md5=${SCEWO_LICENSE_CHECKSUM}"

inherit cmake pkgconfig systemd

BRANCH ?= "main"

FILESEXTRAPATHS:prepend := "${THISDIR}/files:"

SYSTEM_D_SERVICE_NAME = "speaker-daemon"

SRC_URI = " \
    gitsm://git@github.com/Scewo/imx8-speaker-daemon.git;protocol=ssh;branch=${BRANCH} \
    file://${SYSTEM_D_SERVICE_NAME}.service \
"

S = "${WORKDIR}/git"

DEPENDS = " \
  scewo-messages \
  alsa-lib \
  libsndfile1 \
  libconfig \
"

SPEAKER_DAEMON_DATA_DIR="${datadir}/${BPN}"
SOUNDS_DIR="${SPEAKER_DAEMON_DATA_DIR}/sounds/"

EXTRA_OECMAKE = " \
    -DBUILD_TESTS=OFF \
    -DFETCHCONTENT_FULLY_DISCONNECTED=OFF \
    -DYOCTO_BUILD=ON \
    -DSOUNDS_DIR=${SOUNDS_DIR} \
"

SYSTEMD_SERVICE:${PN} = "${SYSTEM_D_SERVICE_NAME}.service"
SYSTEMD_AUTO_ENABLE:${PN} = "enable"


do_install:append() {
    # install logging configuration
    install -D -m 0644 ${S}/config/logging.ini ${D}${sysconfdir}/${BPN}/logging.ini

    # install sound configuration
    install -D -m 0644 ${S}/config/sounds.cfg ${D}${sysconfdir}/${BPN}/sounds.cfg

    # install sound files
    install -d -m 0755 ${D}${SOUNDS_DIR}
    cp -R ${S}/config/sounds/* ${D}${SOUNDS_DIR}
    chmod -R ug=rwX ${D}${SPEAKER_DAEMON_DATA_DIR}
    chmod -R o=rX ${D}${SPEAKER_DAEMON_DATA_DIR}
    
    # Install systemd service
    install -d ${D}${systemd_system_unitdir}
    install -m 0644 ${WORKDIR}/${SYSTEM_D_SERVICE_NAME}.service ${D}${systemd_system_unitdir}/
}

Hi, I’m the Toradex AI Assistant.

I might make mistakes or occasionally get you wrong. Our support team will step in if needed.


I’d be glad to help! Could you let me know which version of Torizon OS you are using? To get specific information about your system, please run the tdx-info command and share the output. You can find more details about this command at tdx-info documentation.

Understanding your exact OS version and hardware setup is important because audio control configuration varies significantly between different Torizon OS versions and build configurations. This will help me provide the most accurate guidance for your custom Torizon minimal build issue with ALSA controls.

Best regards, Toradex AI Assistant.


Did you like my answer? :+1: :-1:

If I answered your question, please tick the “Solution” checkbox.

For follow-up questions to me, please use @ToradexAI in your post.

Hello @Fungiking,

A few possible issues come to mind:

  • Permission issues: Which permissions did your container have? Maybe the user that is running your service does not have the same permissions. Testing with root to understand if this may be an issue would be a possibility.
  • Missing libraries: are you sure the packages needed by your service result in the same functionality being available to the system as in your container? The list appears smaller on the recipe, but I did not look into the full dependencies here.
  • Configuration files: I see that you add configuration files in your recipe. Have you checked if these configuration files are actually in the running system? Maybe another recipe has replaced them with incorrect or unintended content.

Please let me know if any of these help.

Best Regards,
Bruno

Hi @bruno.tx, thanks for your quick answer. We already checked 1). I will try 2) and 3) tomorrow and report back :slight_smile:

1 Like

Hi @bruno.tx, you where right indeed. It was the asound.conf config file that was missing. Thank you for your help.

1 Like

Hello @Fungiking,

Thanks for the update!

Best Regards,
Bruno