ALSA: oxfw: support the case that AV/C Stream Format Information command is not available
Miglia Harmony Audio does neither support AV/C Stream Format Information command nor AV/C Extended Stream Format Information command. This commit adds a workaround for the case and uses the hard-coded formats. Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp> Link: https://lore.kernel.org/r/20240218074128.95210-3-o-takashi@sakamocchi.jp Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
parent
5c0a35b26f
commit
25ab2b2f6a
@ -486,26 +486,57 @@ int snd_oxfw_stream_get_current_formation(struct snd_oxfw *oxfw,
|
||||
enum avc_general_plug_dir dir,
|
||||
struct snd_oxfw_stream_formation *formation)
|
||||
{
|
||||
u8 *format;
|
||||
unsigned int len;
|
||||
int err;
|
||||
|
||||
len = AVC_GENERIC_FRAME_MAXIMUM_BYTES;
|
||||
format = kmalloc(len, GFP_KERNEL);
|
||||
if (format == NULL)
|
||||
return -ENOMEM;
|
||||
if (!(oxfw->quirks & SND_OXFW_QUIRK_STREAM_FORMAT_INFO_UNSUPPORTED)) {
|
||||
u8 *format;
|
||||
unsigned int len;
|
||||
|
||||
err = avc_stream_get_format_single(oxfw->unit, dir, 0, format, &len);
|
||||
if (err < 0)
|
||||
goto end;
|
||||
if (len < 3) {
|
||||
err = -EIO;
|
||||
goto end;
|
||||
len = AVC_GENERIC_FRAME_MAXIMUM_BYTES;
|
||||
format = kmalloc(len, GFP_KERNEL);
|
||||
if (format == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
err = avc_stream_get_format_single(oxfw->unit, dir, 0, format, &len);
|
||||
if (err >= 0) {
|
||||
if (len < 3)
|
||||
err = -EIO;
|
||||
else
|
||||
err = snd_oxfw_stream_parse_format(format, formation);
|
||||
}
|
||||
|
||||
kfree(format);
|
||||
} else {
|
||||
// Miglia Harmony Audio does not support Extended Stream Format Information
|
||||
// command. Use the duplicated hard-coded format, instead.
|
||||
unsigned int rate;
|
||||
u8 *const *formats;
|
||||
int i;
|
||||
|
||||
err = avc_general_get_sig_fmt(oxfw->unit, &rate, dir, 0);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
if (dir == AVC_GENERAL_PLUG_DIR_IN)
|
||||
formats = oxfw->rx_stream_formats;
|
||||
else
|
||||
formats = oxfw->tx_stream_formats;
|
||||
|
||||
for (i = 0; (i < SND_OXFW_STREAM_FORMAT_ENTRIES); ++i) {
|
||||
if (!formats[i])
|
||||
continue;
|
||||
|
||||
err = snd_oxfw_stream_parse_format(formats[i], formation);
|
||||
if (err < 0)
|
||||
continue;
|
||||
|
||||
if (formation->rate == rate)
|
||||
break;
|
||||
}
|
||||
if (i == SND_OXFW_STREAM_FORMAT_ENTRIES)
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
err = snd_oxfw_stream_parse_format(format, formation);
|
||||
end:
|
||||
kfree(format);
|
||||
return err;
|
||||
}
|
||||
|
||||
@ -600,14 +631,33 @@ assume_stream_formats(struct snd_oxfw *oxfw, enum avc_general_plug_dir dir,
|
||||
unsigned int i, eid;
|
||||
int err;
|
||||
|
||||
/* get format at current sampling rate */
|
||||
err = avc_stream_get_format_single(oxfw->unit, dir, pid, buf, len);
|
||||
if (err < 0) {
|
||||
dev_err(&oxfw->unit->device,
|
||||
"fail to get current stream format for isoc %s plug %d:%d\n",
|
||||
(dir == AVC_GENERAL_PLUG_DIR_IN) ? "in" : "out",
|
||||
pid, err);
|
||||
goto end;
|
||||
// get format at current sampling rate.
|
||||
if (!(oxfw->quirks & SND_OXFW_QUIRK_STREAM_FORMAT_INFO_UNSUPPORTED)) {
|
||||
err = avc_stream_get_format_single(oxfw->unit, dir, pid, buf, len);
|
||||
if (err < 0) {
|
||||
dev_err(&oxfw->unit->device,
|
||||
"fail to get current stream format for isoc %s plug %d:%d\n",
|
||||
(dir == AVC_GENERAL_PLUG_DIR_IN) ? "in" : "out",
|
||||
pid, err);
|
||||
goto end;
|
||||
}
|
||||
} else {
|
||||
// Miglia Harmony Audio does not support Extended Stream Format Information
|
||||
// command. Use the hard-coded format, instead.
|
||||
buf[0] = 0x90;
|
||||
buf[1] = 0x40;
|
||||
buf[2] = avc_stream_rate_table[0];
|
||||
buf[3] = 0x00;
|
||||
buf[4] = 0x01;
|
||||
|
||||
if (dir == AVC_GENERAL_PLUG_DIR_IN)
|
||||
buf[5] = 0x08;
|
||||
else
|
||||
buf[5] = 0x02;
|
||||
|
||||
buf[6] = 0x06;
|
||||
|
||||
*len = 7;
|
||||
}
|
||||
|
||||
/* parse and set stream format */
|
||||
|
@ -52,6 +52,8 @@ enum snd_oxfw_quirk {
|
||||
// performs media clock recovery voluntarily. In the recovery, the packets with NO_INFO
|
||||
// are ignored, thus driver should transfer packets with timestamp.
|
||||
SND_OXFW_QUIRK_VOLUNTARY_RECOVERY = 0x20,
|
||||
// Miglia Harmony Audio does not support AV/C Stream Format Information command.
|
||||
SND_OXFW_QUIRK_STREAM_FORMAT_INFO_UNSUPPORTED = 0x40,
|
||||
};
|
||||
|
||||
/* This is an arbitrary number for convinience. */
|
||||
|
Loading…
Reference in New Issue
Block a user