NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: port-evbarm/59873: RPI 3B vcaudio(4) puts bogus errors on audioplay(1)
The following reply was made to PR port-evbarm/59873; it has been noted by GNATS.
From: mlelstv%serpens.de@localhost (Michael van Elst)
To: gnats-bugs%netbsd.org@localhost
Cc:
Subject: Re: port-evbarm/59873: RPI 3B vcaudio(4) puts bogus errors on audioplay(1)
Date: Thu, 1 Jan 2026 08:04:02 -0000 (UTC)
tsutsui%ceres.dti.ne.jp@localhost (Izumi Tsutsui) writes:
>On my Raspberry Pi 3B, if audioplay(1) is passed non-existent audio file,
>the kernel emits the following errors:
>armv7-% audioplay non-existent-file.wav
>audioplay: could not open non-existent-file.wav: No such file or directory
>[ 314735.791236] audio0(vcaudio0): setting play.port=0 failed: errno=22
>[ 314735.791236] audio0(vcaudio0): setting play.port=0 failed: errno=22
>```
>Wrong return values (EINVAL) or bad error handling in
>vcaudio_set_port() (in VCAUDIO_OUTPUT_SELECT case?)
>in src/sys/arch/arm/broadcom/bcm2835_vcaudio.c ?
The audio driver maintains the idea of well-known ports of an
audio device. audioplay lets you select with option -p the
values "speaker", "headphone" and "line" which results in a
bitmask with one bit set. The default is none (a bitmask value
of zero).
The audio driver has a heuristic to find these ports by looking
at mixer controls of type AUDIO_MIXER_ENUM or AUDIO_MIXER_SET
that match well-knwon names (differently for input and output).
static const struct portname itable[] = {
{ AudioNmicrophone, AUDIO_MICROPHONE },
{ AudioNline, AUDIO_LINE_IN },
{ AudioNcd, AUDIO_CD },
{ 0, 0 }
};
static const struct portname otable[] = {
{ AudioNspeaker, AUDIO_SPEAKER },
{ AudioNheadphone, AUDIO_HEADPHONE },
{ AudioNline, AUDIO_LINE_OUT },
{ 0, 0 }
};
Since vcaudio provides a mixer control named AudioNheadphone, the audio
driver collects this as a well-known port name.
# audioctl play.avail_ports
play.avail_ports=0x2
That's
sys/audioio.h:#define AUDIO_HEADPHONE 0x02 /* headphone jack */
The audio driver also tries to find a mixer control named "select"
to select well-known ports.
Most devices don't have well known ports, and playing audio
with no port selected is accepted for them as a special
case.
int
au_set_port(struct audio_softc *sc, struct au_mixer_ports *ports, u_int port)
{
...
if (port == 0) {
if (ports->allports == 0)
return 0; /* Allow this special case. */
else if (ports->isdual) {
if (ports->cur_port == -1) {
return 0;
} else {
port = ports->aumask[ports->cur_port];
ports->cur_port = -1;
use_mixerout = 0;
}
}
}
if (ports->index == -1)
return EINVAL;
...
The index is set from finding a well-known port, so that's not the
error. But the following codes tries to match a well-known port and
also fails with EINVAL if none is found. An AUDIO_MIXER_ENUM allows
to ask for a single port, an AUDIO_MIXER_SET allows a bitmap of
well-known ports, but selecting no port fails.
When you play audio with 'audioplay -p headphone', no error will
be generated. Unfortunately, it also selects the headphones output.
The whole idea of "well-known" ports is outdated, in particular
the assumption that a device has only such ports or none. Using
the name for classification is also questionable.
N.B. audioplay calls it "headphone" while the driver calls it
"headphones". That's from
else if (strncmp(optarg, "headphone", len) == 0)
port |= AUDIO_HEADPHONE;
but the drivers use:
#define AudioNheadphone "headphones"
Home |
Main Index |
Thread Index |
Old Index