public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/2] ALSA: usb-audio: Add basic support for RME Digiface USB
@ 2024-09-01 21:31 Asahi Lina
  2024-09-01 21:31 ` [PATCH 1/2] ALSA: usb-audio: Add quirk " Asahi Lina
  2024-09-01 21:31 ` [PATCH 2/2] ALSA: usb-audio: Add mixer " Asahi Lina
  0 siblings, 2 replies; 8+ messages in thread
From: Asahi Lina @ 2024-09-01 21:31 UTC (permalink / raw)
  To: Jaroslav Kysela, Takashi Iwai
  Cc: Geoffrey D. Bennett, Takashi Sakamoto, Mark Hills, Arun Raghavan,
	Cyan Nyan, linux-sound, linux-kernel, Asahi Lina

Hi everyone,

This series adds basic support for the RME Digiface USB interface. This
is a 4x ADAT I/O interface with an extra headphones output and support
for S/PDIF mode.

There are 3 streaming configurations:

- 32in/34out at 1x speed mode
- 16in/18out at 2x speed mode
- 8in/10out at 4x speed mode

The appropriate speed mode is automatically set based on the PCM rate,
and this governs the available channel count.

The first commit adds basic init and streaming support. This is enough
to use the interface in its default settings (ADAT outputs, internal
sync) using the ALSA PCM.

The second commit adds basic mixer controls to set up the I/O features
(output modes, sync source) and report I/O status.

This series does not implement the output faders, matrix mixer, or input
level meters. These features are more useful when the interface is used
as a router (possibly stand-alone), and are not really something that
can be exposed via ALSA mixer controls usable via something like
alsamixer (the matrix mixer has up to 2048 possible mixer nodes). Since
we expect users to use a dedicated control app, the intent is that the
app directly controls these features via the libusb API. This is similar
to how things work with some FireWire interfaces (ffado-mixer) today.

Of course, there is room for extending the mixer interface to add more
controls in the future, once we settle on a mechanism to expose
complex/large matrix mixers.

Signed-off-by: Asahi Lina <lina@asahilina.net>
---
Asahi Lina (1):
      ALSA: usb-audio: Add mixer quirk for RME Digiface USB

Cyan Nyan (1):
      ALSA: usb-audio: Add quirk for RME Digiface USB

 sound/usb/mixer_quirks.c | 413 +++++++++++++++++++++++++++++++++++++++++++++++
 sound/usb/quirks-table.h | 194 +++++++++++++++++++++-
 sound/usb/quirks.c       |  58 +++++++
 3 files changed, 664 insertions(+), 1 deletion(-)
---
base-commit: 8400291e289ee6b2bf9779ff1c83a291501f017b
change-id: 20240902-rme-digiface-cc14c71cd2ea

Cheers,
~~ Lina


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 1/2] ALSA: usb-audio: Add quirk for RME Digiface USB
  2024-09-01 21:31 [PATCH 0/2] ALSA: usb-audio: Add basic support for RME Digiface USB Asahi Lina
@ 2024-09-01 21:31 ` Asahi Lina
  2024-09-02  6:10   ` Takashi Iwai
  2024-09-01 21:31 ` [PATCH 2/2] ALSA: usb-audio: Add mixer " Asahi Lina
  1 sibling, 1 reply; 8+ messages in thread
From: Asahi Lina @ 2024-09-01 21:31 UTC (permalink / raw)
  To: Jaroslav Kysela, Takashi Iwai
  Cc: Geoffrey D. Bennett, Takashi Sakamoto, Mark Hills, Arun Raghavan,
	Cyan Nyan, linux-sound, linux-kernel, Asahi Lina

From: Cyan Nyan <cyan.vtb@gmail.com>

Add trivial support for audio streaming on the RME Digiface USB. Binds
only to the first interface to allow userspace to directly drive the
complex I/O and matrix mixer controls.

Signed-off-by: Cyan Nyan <cyan.vtb@gmail.com>
[Lina: Added 2x/4x sample rate support & boot/format quirks]
Co-developed-by: Asahi Lina <lina@asahilina.net>
Signed-off-by: Asahi Lina <lina@asahilina.net>
---
 sound/usb/quirks-table.h | 190 ++++++++++++++++++++++++++++++++++++++++++++++-
 sound/usb/quirks.c       |  58 +++++++++++++++
 2 files changed, 247 insertions(+), 1 deletion(-)

diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h
index 73abc38a5400..47fd18791396 100644
--- a/sound/usb/quirks-table.h
+++ b/sound/usb/quirks-table.h
@@ -4546,6 +4546,194 @@ YAMAHA_DEVICE(0x7010, "UB99"),
 		}
 	}
 },
-
+{
+	/* Only claim interface 0 */
+	.match_flags = USB_DEVICE_ID_MATCH_VENDOR |
+		       USB_DEVICE_ID_MATCH_PRODUCT |
+		       USB_DEVICE_ID_MATCH_INT_CLASS |
+		       USB_DEVICE_ID_MATCH_INT_NUMBER,
+	.idVendor = 0x2a39,
+	.idProduct = 0x3f8c,
+	.bInterfaceClass = USB_CLASS_VENDOR_SPEC,
+	.bInterfaceNumber = 0,
+	.driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
+		.ifnum = QUIRK_ANY_INTERFACE,
+		.type = QUIRK_COMPOSITE,
+		.data = (const struct snd_usb_audio_quirk[]) {
+			/*
+			 * Three modes depending on sample rate band,
+			 * with different channel counts for in/out
+			 */
+			{
+				.ifnum = 0,
+				.type = QUIRK_AUDIO_FIXED_ENDPOINT,
+				.data = &(const struct audioformat) {
+					.formats = SNDRV_PCM_FMTBIT_S32_LE,
+					.channels = 34, // outputs
+					.fmt_bits = 24,
+					.iface = 0,
+					.altsetting = 1,
+					.altset_idx = 1,
+					.endpoint = 0x02,
+					.ep_idx = 1,
+					.ep_attr = USB_ENDPOINT_XFER_ISOC|
+						USB_ENDPOINT_SYNC_ASYNC,
+					.rates = SNDRV_PCM_RATE_32000 |
+						SNDRV_PCM_RATE_44100 |
+						SNDRV_PCM_RATE_48000,
+					.rate_min = 32000,
+					.rate_max = 48000,
+					.nr_rates = 3,
+					.rate_table = (unsigned int[]) {
+						32000, 44100, 48000,
+					},
+					.sync_ep = 0x81,
+					.sync_iface = 0,
+					.sync_altsetting = 1,
+					.sync_ep_idx = 0,
+					.implicit_fb = 1,
+				},
+			},
+			{
+				.ifnum = 0,
+				.type = QUIRK_AUDIO_FIXED_ENDPOINT,
+				.data = &(const struct audioformat) {
+					.formats = SNDRV_PCM_FMTBIT_S32_LE,
+					.channels = 18, // outputs
+					.fmt_bits = 24,
+					.iface = 0,
+					.altsetting = 1,
+					.altset_idx = 1,
+					.endpoint = 0x02,
+					.ep_idx = 1,
+					.ep_attr = USB_ENDPOINT_XFER_ISOC|
+						USB_ENDPOINT_SYNC_ASYNC,
+					.rates = SNDRV_PCM_RATE_64000 |
+						SNDRV_PCM_RATE_88200 |
+						SNDRV_PCM_RATE_96000,
+					.rate_min = 64000,
+					.rate_max = 96000,
+					.nr_rates = 3,
+					.rate_table = (unsigned int[]) {
+						64000, 88200, 96000,
+					},
+					.sync_ep = 0x81,
+					.sync_iface = 0,
+					.sync_altsetting = 1,
+					.sync_ep_idx = 0,
+					.implicit_fb = 1,
+				},
+			},
+			{
+				.ifnum = 0,
+				.type = QUIRK_AUDIO_FIXED_ENDPOINT,
+				.data = &(const struct audioformat) {
+					.formats = SNDRV_PCM_FMTBIT_S32_LE,
+					.channels = 10, // outputs
+					.fmt_bits = 24,
+					.iface = 0,
+					.altsetting = 1,
+					.altset_idx = 1,
+					.endpoint = 0x02,
+					.ep_idx = 1,
+					.ep_attr = USB_ENDPOINT_XFER_ISOC|
+						USB_ENDPOINT_SYNC_ASYNC,
+					.rates = SNDRV_PCM_RATE_KNOT |
+						SNDRV_PCM_RATE_176400 |
+						SNDRV_PCM_RATE_192000,
+					.rate_min = 128000,
+					.rate_max = 192000,
+					.nr_rates = 3,
+					.rate_table = (unsigned int[]) {
+						128000, 176400, 192000,
+					},
+					.sync_ep = 0x81,
+					.sync_iface = 0,
+					.sync_altsetting = 1,
+					.sync_ep_idx = 0,
+					.implicit_fb = 1,
+				},
+			},
+			{
+				.ifnum = 0,
+				.type = QUIRK_AUDIO_FIXED_ENDPOINT,
+				.data = &(const struct audioformat) {
+					.formats = SNDRV_PCM_FMTBIT_S32_LE,
+					.channels = 32, // inputs
+					.fmt_bits = 24,
+					.iface = 0,
+					.altsetting = 1,
+					.altset_idx = 1,
+					.endpoint = 0x81,
+					.ep_attr = USB_ENDPOINT_XFER_ISOC|
+						USB_ENDPOINT_SYNC_ASYNC|
+						USB_ENDPOINT_USAGE_IMPLICIT_FB,
+					.rates = SNDRV_PCM_RATE_32000 |
+						SNDRV_PCM_RATE_44100 |
+						SNDRV_PCM_RATE_48000,
+					.rate_min = 32000,
+					.rate_max = 48000,
+					.nr_rates = 3,
+					.rate_table = (unsigned int[]) {
+						32000, 44100, 48000,
+					}
+				}
+			},
+			{
+				.ifnum = 0,
+				.type = QUIRK_AUDIO_FIXED_ENDPOINT,
+				.data = &(const struct audioformat) {
+					.formats = SNDRV_PCM_FMTBIT_S32_LE,
+					.channels = 16, // inputs
+					.fmt_bits = 24,
+					.iface = 0,
+					.altsetting = 1,
+					.altset_idx = 1,
+					.endpoint = 0x81,
+					.ep_attr = USB_ENDPOINT_XFER_ISOC|
+						USB_ENDPOINT_SYNC_ASYNC|
+						USB_ENDPOINT_USAGE_IMPLICIT_FB,
+					.rates = SNDRV_PCM_RATE_64000 |
+						SNDRV_PCM_RATE_88200 |
+						SNDRV_PCM_RATE_96000,
+					.rate_min = 64000,
+					.rate_max = 96000,
+					.nr_rates = 3,
+					.rate_table = (unsigned int[]) {
+						64000, 88200, 96000,
+					}
+				}
+			},
+			{
+				.ifnum = 0,
+				.type = QUIRK_AUDIO_FIXED_ENDPOINT,
+				.data = &(const struct audioformat) {
+					.formats = SNDRV_PCM_FMTBIT_S32_LE,
+					.channels = 8, // inputs
+					.fmt_bits = 24,
+					.iface = 0,
+					.altsetting = 1,
+					.altset_idx = 1,
+					.endpoint = 0x81,
+					.ep_attr = USB_ENDPOINT_XFER_ISOC|
+						USB_ENDPOINT_SYNC_ASYNC|
+						USB_ENDPOINT_USAGE_IMPLICIT_FB,
+					.rates = SNDRV_PCM_RATE_KNOT |
+						SNDRV_PCM_RATE_176400 |
+						SNDRV_PCM_RATE_192000,
+					.rate_min = 128000,
+					.rate_max = 192000,
+					.nr_rates = 3,
+					.rate_table = (unsigned int[]) {
+						128000, 176400, 192000,
+					}
+				}
+			},
+			{
+				.ifnum = -1
+			}
+		}
+	}
+},
 #undef USB_DEVICE_VENDOR_SPEC
 #undef USB_AUDIO_DEVICE
diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c
index ea063a14cdd8..3e44595add89 100644
--- a/sound/usb/quirks.c
+++ b/sound/usb/quirks.c
@@ -1389,6 +1389,27 @@ static int snd_usb_motu_m_series_boot_quirk(struct usb_device *dev)
 	return 0;
 }
 
+static int snd_usb_rme_digiface_boot_quirk(struct usb_device *dev)
+{
+	/* Disable mixer, internal clock, all outputs ADAT, 48kHz, TMS off */
+	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
+			16, 0x40, 0x2410, 0x7fff, NULL, 0);
+	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
+			18, 0x40, 0x0104, 0xffff, NULL, 0);
+
+	/* Disable loopback for all inputs */
+	for (int ch = 0; ch < 32; ch++)
+		snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
+				22, 0x40, 0x400, ch, NULL, 0);
+
+	/* Unity gain for all outputs */
+	for (int ch = 0; ch < 34; ch++)
+		snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
+				21, 0x40, 0x9000, 0x100 + ch, NULL, 0);
+
+	return 0;
+}
+
 /*
  * Setup quirks
  */
@@ -1616,6 +1637,8 @@ int snd_usb_apply_boot_quirk(struct usb_device *dev,
 		    get_iface_desc(intf->altsetting)->bInterfaceNumber < 3)
 			return snd_usb_motu_microbookii_boot_quirk(dev);
 		break;
+	case USB_ID(0x2a39, 0x3f8c): /* RME Digiface USB */
+		return snd_usb_rme_digiface_boot_quirk(dev);
 	}
 
 	return 0;
@@ -1771,6 +1794,38 @@ static void mbox3_set_format_quirk(struct snd_usb_substream *subs,
 		dev_warn(&subs->dev->dev, "MBOX3: Couldn't set the sample rate");
 }
 
+static const int rme_digiface_rate_table[] = {
+	32000, 44100, 48000, 0,
+	64000, 88200, 96000, 0,
+	128000, 176400, 192000, 0,
+};
+
+static int rme_digiface_set_format_quirk(struct snd_usb_substream *subs)
+{
+	unsigned int cur_rate = subs->data_endpoint->cur_rate;
+	u16 val;
+	int speed_mode;
+	int id;
+
+	for (id = 0; id < ARRAY_SIZE(rme_digiface_rate_table); id++) {
+		if (rme_digiface_rate_table[id] == cur_rate)
+			break;
+	}
+
+	if (id >= ARRAY_SIZE(rme_digiface_rate_table))
+		return -EINVAL;
+
+	/* 2, 3, 4 for 1x, 2x, 4x */
+	speed_mode = (id >> 2) + 2;
+	val = (id << 3) | (speed_mode << 12);
+
+	/* Set the sample rate */
+	snd_usb_ctl_msg(subs->stream->chip->dev,
+		usb_sndctrlpipe(subs->stream->chip->dev, 0),
+		16, 0x40, val, 0x7078, NULL, 0);
+	return 0;
+}
+
 void snd_usb_set_format_quirk(struct snd_usb_substream *subs,
 			      const struct audioformat *fmt)
 {
@@ -1795,6 +1850,9 @@ void snd_usb_set_format_quirk(struct snd_usb_substream *subs,
 	case USB_ID(0x0dba, 0x5000):
 		mbox3_set_format_quirk(subs, fmt); /* Digidesign Mbox 3 */
 		break;
+	case USB_ID(0x2a39, 0x3f8c): /* RME Digiface USB */
+		rme_digiface_set_format_quirk(subs);
+		break;
 	}
 }
 

-- 
2.46.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 2/2] ALSA: usb-audio: Add mixer quirk for RME Digiface USB
  2024-09-01 21:31 [PATCH 0/2] ALSA: usb-audio: Add basic support for RME Digiface USB Asahi Lina
  2024-09-01 21:31 ` [PATCH 1/2] ALSA: usb-audio: Add quirk " Asahi Lina
@ 2024-09-01 21:31 ` Asahi Lina
  2024-09-02  7:29   ` kernel test robot
  1 sibling, 1 reply; 8+ messages in thread
From: Asahi Lina @ 2024-09-01 21:31 UTC (permalink / raw)
  To: Jaroslav Kysela, Takashi Iwai
  Cc: Geoffrey D. Bennett, Takashi Sakamoto, Mark Hills, Arun Raghavan,
	Cyan Nyan, linux-sound, linux-kernel, Asahi Lina

Implement sync, output format, and input status mixer controls, to allow
the interface to be used as a straight ADAT/SPDIF (+ Headphones) I/O
interface.

This does not implement the matrix mixer, output gain controls, or input
level meter feedback. The full mixer interface is only really usable
using a dedicated userspace control app (there are too many mixer nodes
for alsamixer to be usable), so for now we leave it up to userspace to
directly control these features using raw USB control messages. This is
similar to how it's done with some FireWire interfaces (ffado-mixer).

Signed-off-by: Asahi Lina <lina@asahilina.net>
---
 sound/usb/mixer_quirks.c | 413 +++++++++++++++++++++++++++++++++++++++++++++++
 sound/usb/quirks-table.h |   4 +
 2 files changed, 417 insertions(+)

diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c
index 2bc344cf54a8..7c83210d324c 100644
--- a/sound/usb/mixer_quirks.c
+++ b/sound/usb/mixer_quirks.c
@@ -14,6 +14,7 @@
  *	    Przemek Rudy (prudy1@o2.pl)
  */
 
+#include <linux/bitfield.h>
 #include <linux/hid.h>
 #include <linux/init.h>
 #include <linux/math64.h>
@@ -2925,6 +2926,415 @@ static int snd_bbfpro_controls_create(struct usb_mixer_interface *mixer)
 	return 0;
 }
 
+/*
+ * RME Digiface USB
+ */
+
+#define RME_DIGIFACE_READ_STATUS 17
+#define RME_DIGIFACE_STATUS_REG0L 0
+#define RME_DIGIFACE_STATUS_REG0H 1
+#define RME_DIGIFACE_STATUS_REG1L 2
+#define RME_DIGIFACE_STATUS_REG1H 3
+#define RME_DIGIFACE_STATUS_REG2L 4
+#define RME_DIGIFACE_STATUS_REG2H 5
+#define RME_DIGIFACE_STATUS_REG3L 6
+#define RME_DIGIFACE_STATUS_REG3H 7
+
+#define RME_DIGIFACE_CTL_REG1 16
+#define RME_DIGIFACE_CTL_REG2 18
+
+/* Reg is overloaded, 0-7 for status halfwords or 16 or 18 for control registers */
+#define RME_DIGIFACE_REGISTER(reg, mask) (((reg) << 16) | (mask))
+#define RME_DIGIFACE_INVERT BIT(32)
+
+/* Nonconst helpers */
+#define field_get(_mask, _reg) (((_reg) & (_mask)) >> (ffs(_mask) - 1))
+#define field_prep(_mask, _val) (((_val) << (ffs(_mask) - 1)) & (_mask))
+
+static int snd_rme_digiface_write_reg(struct snd_kcontrol *kcontrol, int item, u16 mask, u16 val)
+{
+	struct usb_mixer_elem_list *list = snd_kcontrol_chip(kcontrol);
+	struct snd_usb_audio *chip = list->mixer->chip;
+	struct usb_device *dev = chip->dev;
+	int err;
+
+	err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
+			      item,
+			      USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+			      val, mask, NULL, 0);
+	if (err < 0)
+		dev_err(&dev->dev,
+			"unable to issue control set request %d (ret = %d)",
+			item, err);
+	return err;
+}
+
+static int snd_rme_digiface_read_status(struct snd_kcontrol *kcontrol, u32 status[4])
+{
+	struct usb_mixer_elem_list *list = snd_kcontrol_chip(kcontrol);
+	struct snd_usb_audio *chip = list->mixer->chip;
+	struct usb_device *dev = chip->dev;
+	__le32 buf[4];
+	int err;
+
+	err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0),
+			      RME_DIGIFACE_READ_STATUS,
+			      USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+			      0, 0,
+			      buf, sizeof(buf));
+	if (err < 0) {
+		dev_err(&dev->dev,
+			"unable to issue status read request (ret = %d)",
+			err);
+	} else {
+		for (int i = 0; i < ARRAY_SIZE(buf); i++)
+			status[i] = le32_to_cpu(buf[i]);
+	}
+	return err;
+}
+
+static int snd_rme_digiface_get_status_val(struct snd_kcontrol *kcontrol)
+{
+	int err;
+	u32 status[4];
+	bool invert = kcontrol->private_value & RME_DIGIFACE_INVERT;
+	u8 reg = kcontrol->private_value >> 16;
+	u16 mask = kcontrol->private_value & 0xffff;
+	u16 val;
+
+	err = snd_rme_digiface_read_status(kcontrol, status);
+	if (err < 0)
+		return err;
+
+	switch (reg) {
+	/* Status register halfwords */
+	case RME_DIGIFACE_STATUS_REG0L ... RME_DIGIFACE_STATUS_REG3H:
+		break;
+	case RME_DIGIFACE_CTL_REG1: /* Control register 1, present in halfword 3L */
+		reg = RME_DIGIFACE_STATUS_REG3L;
+		break;
+	case RME_DIGIFACE_CTL_REG2: /* Control register 2, present in halfword 3H */
+		reg = RME_DIGIFACE_STATUS_REG3H;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	if (reg & 1)
+		val = status[reg >> 1] >> 16;
+	else
+		val = status[reg >> 1] & 0xffff;
+
+	if (invert)
+		val ^= mask;
+
+	return field_get(mask, val);
+}
+
+static int snd_rme_digiface_rate_get(struct snd_kcontrol *kcontrol,
+				     struct snd_ctl_elem_value *ucontrol)
+{
+	int freq = snd_rme_digiface_get_status_val(kcontrol);
+
+	if (freq < 0)
+		return freq;
+	if (freq >= ARRAY_SIZE(snd_rme_rate_table))
+		return -EIO;
+
+	ucontrol->value.integer.value[0] = snd_rme_rate_table[freq];
+	return 0;
+}
+
+static int snd_rme_digiface_enum_get(struct snd_kcontrol *kcontrol,
+				     struct snd_ctl_elem_value *ucontrol)
+{
+	int val = snd_rme_digiface_get_status_val(kcontrol);
+
+	if (val < 0)
+		return val;
+
+	ucontrol->value.enumerated.item[0] = val;
+	return 0;
+}
+
+static int snd_rme_digiface_enum_put(struct snd_kcontrol *kcontrol,
+				     struct snd_ctl_elem_value *ucontrol)
+{
+	bool invert = kcontrol->private_value & RME_DIGIFACE_INVERT;
+	u8 reg = kcontrol->private_value >> 16;
+	u16 mask = kcontrol->private_value & 0xffff;
+	u16 val = field_prep(mask, ucontrol->value.enumerated.item[0]);
+
+	if (invert)
+		val ^= mask;
+
+	return snd_rme_digiface_write_reg(kcontrol, reg, mask, val);
+}
+
+static int snd_rme_digiface_current_sync_get(struct snd_kcontrol *kcontrol,
+				     struct snd_ctl_elem_value *ucontrol)
+{
+	int ret = snd_rme_digiface_enum_get(kcontrol, ucontrol);
+
+	/* 7 means internal for current sync */
+	if (ucontrol->value.enumerated.item[0] == 7)
+		ucontrol->value.enumerated.item[0] = 0;
+
+	return ret;
+}
+
+static int snd_rme_digiface_sync_state_get(struct snd_kcontrol *kcontrol,
+					   struct snd_ctl_elem_value *ucontrol)
+{
+	u32 status[4];
+	int err;
+	bool valid, sync;
+
+	err = snd_rme_digiface_read_status(kcontrol, status);
+	if (err < 0)
+		return err;
+
+	valid = status[0] & BIT(kcontrol->private_value);
+	sync = status[0] & BIT(5 + kcontrol->private_value);
+
+	if (!valid)
+		ucontrol->value.enumerated.item[0] = SND_RME_CLOCK_NOLOCK;
+	else if (!sync)
+		ucontrol->value.enumerated.item[0] = SND_RME_CLOCK_LOCK;
+	else
+		ucontrol->value.enumerated.item[0] = SND_RME_CLOCK_SYNC;
+	return 0;
+}
+
+
+static int snd_rme_digiface_format_info(struct snd_kcontrol *kcontrol,
+					struct snd_ctl_elem_info *uinfo)
+{
+	static const char *const format[] = {
+		"ADAT", "S/PDIF"
+	};
+
+	return snd_ctl_enum_info(uinfo, 1,
+				 ARRAY_SIZE(format), format);
+}
+
+
+static int snd_rme_digiface_sync_source_info(struct snd_kcontrol *kcontrol,
+					     struct snd_ctl_elem_info *uinfo)
+{
+	static const char *const sync_sources[] = {
+		"Internal", "Input 1", "Input 2", "Input 3", "Input 4"
+	};
+
+	return snd_ctl_enum_info(uinfo, 1,
+				 ARRAY_SIZE(sync_sources), sync_sources);
+}
+
+static int snd_rme_digiface_rate_info(struct snd_kcontrol *kcontrol,
+				      struct snd_ctl_elem_info *uinfo)
+{
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+	uinfo->count = 1;
+	uinfo->value.integer.min = 0;
+	uinfo->value.integer.max = 200000;
+	uinfo->value.integer.step = 0;
+	return 0;
+}
+
+static const struct snd_kcontrol_new snd_rme_digiface_controls[] = {
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "Input 1 Sync",
+		.access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
+		.info = snd_rme_sync_state_info,
+		.get = snd_rme_digiface_sync_state_get,
+		.private_value = 0,
+	},
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "Input 1 Format",
+		.access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
+		.info = snd_rme_digiface_format_info,
+		.get = snd_rme_digiface_enum_get,
+		.private_value = RME_DIGIFACE_REGISTER(RME_DIGIFACE_STATUS_REG0H, BIT(0)) |
+			RME_DIGIFACE_INVERT,
+	},
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "Input 1 Rate",
+		.access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
+		.info = snd_rme_digiface_rate_info,
+		.get = snd_rme_digiface_rate_get,
+		.private_value = RME_DIGIFACE_REGISTER(RME_DIGIFACE_STATUS_REG1L, GENMASK(3, 0)),
+	},
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "Input 2 Sync",
+		.access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
+		.info = snd_rme_sync_state_info,
+		.get = snd_rme_digiface_sync_state_get,
+		.private_value = 1,
+	},
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "Input 2 Format",
+		.access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
+		.info = snd_rme_digiface_format_info,
+		.get = snd_rme_digiface_enum_get,
+		.private_value = RME_DIGIFACE_REGISTER(RME_DIGIFACE_STATUS_REG0L, BIT(13)) |
+			RME_DIGIFACE_INVERT,
+	},
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "Input 2 Rate",
+		.access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
+		.info = snd_rme_digiface_rate_info,
+		.get = snd_rme_digiface_rate_get,
+		.private_value = RME_DIGIFACE_REGISTER(RME_DIGIFACE_STATUS_REG1L, GENMASK(7, 4)),
+	},
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "Input 3 Sync",
+		.access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
+		.info = snd_rme_sync_state_info,
+		.get = snd_rme_digiface_sync_state_get,
+		.private_value = 2,
+	},
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "Input 3 Format",
+		.access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
+		.info = snd_rme_digiface_format_info,
+		.get = snd_rme_digiface_enum_get,
+		.private_value = RME_DIGIFACE_REGISTER(RME_DIGIFACE_STATUS_REG0L, BIT(14)) |
+			RME_DIGIFACE_INVERT,
+	},
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "Input 3 Rate",
+		.access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
+		.info = snd_rme_digiface_rate_info,
+		.get = snd_rme_digiface_rate_get,
+		.private_value = RME_DIGIFACE_REGISTER(RME_DIGIFACE_STATUS_REG1L, GENMASK(11, 8)),
+	},
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "Input 4 Sync",
+		.access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
+		.info = snd_rme_sync_state_info,
+		.get = snd_rme_digiface_sync_state_get,
+		.private_value = 3,
+	},
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "Input 4 Format",
+		.access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
+		.info = snd_rme_digiface_format_info,
+		.get = snd_rme_digiface_enum_get,
+		.private_value = RME_DIGIFACE_REGISTER(RME_DIGIFACE_STATUS_REG0L, GENMASK(15, 12)) |
+			RME_DIGIFACE_INVERT,
+	},
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "Input 4 Rate",
+		.access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
+		.info = snd_rme_digiface_rate_info,
+		.get = snd_rme_digiface_rate_get,
+		.private_value = RME_DIGIFACE_REGISTER(RME_DIGIFACE_STATUS_REG1L, GENMASK(3, 0)),
+	},
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "Output 1 Format",
+		.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+		.info = snd_rme_digiface_format_info,
+		.get = snd_rme_digiface_enum_get,
+		.put = snd_rme_digiface_enum_put,
+		.private_value = RME_DIGIFACE_REGISTER(RME_DIGIFACE_CTL_REG2, BIT(0)),
+	},
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "Output 2 Format",
+		.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+		.info = snd_rme_digiface_format_info,
+		.get = snd_rme_digiface_enum_get,
+		.put = snd_rme_digiface_enum_put,
+		.private_value = RME_DIGIFACE_REGISTER(RME_DIGIFACE_CTL_REG2, BIT(1)),
+	},
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "Output 3 Format",
+		.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+		.info = snd_rme_digiface_format_info,
+		.get = snd_rme_digiface_enum_get,
+		.put = snd_rme_digiface_enum_put,
+		.private_value = RME_DIGIFACE_REGISTER(RME_DIGIFACE_CTL_REG2, BIT(3)),
+	},
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "Output 4 Format",
+		.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+		.info = snd_rme_digiface_format_info,
+		.get = snd_rme_digiface_enum_get,
+		.put = snd_rme_digiface_enum_put,
+		.private_value = RME_DIGIFACE_REGISTER(RME_DIGIFACE_CTL_REG2, BIT(4)),
+	},
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "Sync Source",
+		.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+		.info = snd_rme_digiface_sync_source_info,
+		.get = snd_rme_digiface_enum_get,
+		.put = snd_rme_digiface_enum_put,
+		.private_value = RME_DIGIFACE_REGISTER(RME_DIGIFACE_CTL_REG1, GENMASK(2, 0)),
+	},
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "Current Sync Source",
+		.access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
+		.info = snd_rme_digiface_sync_source_info,
+		.get = snd_rme_digiface_current_sync_get,
+		.private_value = RME_DIGIFACE_REGISTER(RME_DIGIFACE_STATUS_REG0L, GENMASK(12, 10)),
+	},
+	{
+		/*
+		 * This is writeable, but it is only set by the PCM rate.
+		 * Mixer apps currently need to drive the mixer using raw USB requests,
+		 * so they can also change this that way to configure the rate for
+		 * stand-alone operation when the PCM is closed.
+		 */
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "System Rate",
+		.access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
+		.info = snd_rme_rate_info,
+		.get = snd_rme_digiface_rate_get,
+		.private_value = RME_DIGIFACE_REGISTER(RME_DIGIFACE_CTL_REG1, GENMASK(6, 3)),
+	},
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "Current Rate",
+		.access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
+		.info = snd_rme_rate_info,
+		.get = snd_rme_digiface_rate_get,
+		.private_value = RME_DIGIFACE_REGISTER(RME_DIGIFACE_STATUS_REG1H, GENMASK(7, 4)),
+	}
+};
+
+static int snd_rme_digiface_controls_create(struct usb_mixer_interface *mixer)
+{
+	int err, i;
+
+	for (i = 0; i < ARRAY_SIZE(snd_rme_digiface_controls); ++i) {
+		err = add_single_ctl_with_resume(mixer, 0,
+						 NULL,
+						 &snd_rme_digiface_controls[i],
+						 NULL);
+		if (err < 0)
+			return err;
+	}
+
+	return 0;
+}
+
 /*
  * Pioneer DJ DJM Mixers
  *
@@ -3483,6 +3893,9 @@ int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer)
 	case USB_ID(0x2a39, 0x3fb0): /* RME Babyface Pro FS */
 		err = snd_bbfpro_controls_create(mixer);
 		break;
+	case USB_ID(0x2a39, 0x3f8c): /* RME Digiface USB */
+		err = snd_rme_digiface_controls_create(mixer);
+		break;
 	case USB_ID(0x2b73, 0x0017): /* Pioneer DJ DJM-250MK2 */
 		err = snd_djm_controls_create(mixer, SND_DJM_250MK2_IDX);
 		break;
diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h
index 47fd18791396..41e75089fb72 100644
--- a/sound/usb/quirks-table.h
+++ b/sound/usb/quirks-table.h
@@ -4564,6 +4564,10 @@ YAMAHA_DEVICE(0x7010, "UB99"),
 			 * Three modes depending on sample rate band,
 			 * with different channel counts for in/out
 			 */
+			{
+				.ifnum = 0,
+				.type = QUIRK_AUDIO_STANDARD_MIXER,
+			},
 			{
 				.ifnum = 0,
 				.type = QUIRK_AUDIO_FIXED_ENDPOINT,

-- 
2.46.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH 1/2] ALSA: usb-audio: Add quirk for RME Digiface USB
  2024-09-01 21:31 ` [PATCH 1/2] ALSA: usb-audio: Add quirk " Asahi Lina
@ 2024-09-02  6:10   ` Takashi Iwai
  2024-09-02  8:12     ` Asahi Lina
  0 siblings, 1 reply; 8+ messages in thread
From: Takashi Iwai @ 2024-09-02  6:10 UTC (permalink / raw)
  To: Asahi Lina
  Cc: Jaroslav Kysela, Takashi Iwai, Geoffrey D. Bennett,
	Takashi Sakamoto, Mark Hills, Arun Raghavan, Cyan Nyan,
	linux-sound, linux-kernel

On Sun, 01 Sep 2024 23:31:50 +0200,
Asahi Lina wrote:
> 
> From: Cyan Nyan <cyan.vtb@gmail.com>
> 
> Add trivial support for audio streaming on the RME Digiface USB. Binds
> only to the first interface to allow userspace to directly drive the
> complex I/O and matrix mixer controls.
> 
> Signed-off-by: Cyan Nyan <cyan.vtb@gmail.com>
> [Lina: Added 2x/4x sample rate support & boot/format quirks]
> Co-developed-by: Asahi Lina <lina@asahilina.net>
> Signed-off-by: Asahi Lina <lina@asahilina.net>
> ---
>  sound/usb/quirks-table.h | 190 ++++++++++++++++++++++++++++++++++++++++++++++-
>  sound/usb/quirks.c       |  58 +++++++++++++++
>  2 files changed, 247 insertions(+), 1 deletion(-)
> 
> diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h
> index 73abc38a5400..47fd18791396 100644
> --- a/sound/usb/quirks-table.h
> +++ b/sound/usb/quirks-table.h
> @@ -4546,6 +4546,194 @@ YAMAHA_DEVICE(0x7010, "UB99"),
>  		}
>  	}
>  },
> -
> +{
> +	/* Only claim interface 0 */
> +	.match_flags = USB_DEVICE_ID_MATCH_VENDOR |
> +		       USB_DEVICE_ID_MATCH_PRODUCT |
> +		       USB_DEVICE_ID_MATCH_INT_CLASS |
> +		       USB_DEVICE_ID_MATCH_INT_NUMBER,
> +	.idVendor = 0x2a39,
> +	.idProduct = 0x3f8c,
> +	.bInterfaceClass = USB_CLASS_VENDOR_SPEC,
> +	.bInterfaceNumber = 0,
> +	.driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
> +		.ifnum = QUIRK_ANY_INTERFACE,
> +		.type = QUIRK_COMPOSITE,
(snip)

Recently the quirk tables are rewritten with macros.
See the commit d79e13f8e8abb5cd3a2a0f9fc9bc3fc750c5b06f
    ALSA: usb-audio: Replace complex quirk lines with macros
in for-next branch of sound.git tree.

Could you try to apply to your new entries, too?


thanks,

Takashi

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 2/2] ALSA: usb-audio: Add mixer quirk for RME Digiface USB
  2024-09-01 21:31 ` [PATCH 2/2] ALSA: usb-audio: Add mixer " Asahi Lina
@ 2024-09-02  7:29   ` kernel test robot
  2024-09-02  7:53     ` Asahi Lina
  0 siblings, 1 reply; 8+ messages in thread
From: kernel test robot @ 2024-09-02  7:29 UTC (permalink / raw)
  To: Asahi Lina, Jaroslav Kysela, Takashi Iwai
  Cc: llvm, oe-kbuild-all, Geoffrey D. Bennett, Takashi Sakamoto,
	Mark Hills, Arun Raghavan, Cyan Nyan, linux-sound, linux-kernel,
	Asahi Lina

Hi Asahi,

kernel test robot noticed the following build warnings:

[auto build test WARNING on 8400291e289ee6b2bf9779ff1c83a291501f017b]

url:    https://github.com/intel-lab-lkp/linux/commits/Asahi-Lina/ALSA-usb-audio-Add-quirk-for-RME-Digiface-USB/20240902-054004
base:   8400291e289ee6b2bf9779ff1c83a291501f017b
patch link:    https://lore.kernel.org/r/20240902-rme-digiface-v1-2-6e88472a2744%40asahilina.net
patch subject: [PATCH 2/2] ALSA: usb-audio: Add mixer quirk for RME Digiface USB
config: mips-mtx1_defconfig (https://download.01.org/0day-ci/archive/20240902/202409021549.DbXWdqGa-lkp@intel.com/config)
compiler: clang version 16.0.6 (https://github.com/llvm/llvm-project 7cbf1a2591520c2491aa35339f227775f4d3adf6)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240902/202409021549.DbXWdqGa-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202409021549.DbXWdqGa-lkp@intel.com/

All warnings (new ones prefixed by >>):

>> sound/usb/mixer_quirks.c:3000:42: warning: shift count >= width of type [-Wshift-count-overflow]
           bool invert = kcontrol->private_value & RME_DIGIFACE_INVERT;
                                                   ^~~~~~~~~~~~~~~~~~~
   sound/usb/mixer_quirks.c:2948:29: note: expanded from macro 'RME_DIGIFACE_INVERT'
   #define RME_DIGIFACE_INVERT BIT(32)
                               ^~~~~~~
   include/vdso/bits.h:7:26: note: expanded from macro 'BIT'
   #define BIT(nr)                 (UL(1) << (nr))
                                          ^  ~~~~
   sound/usb/mixer_quirks.c:3063:42: warning: shift count >= width of type [-Wshift-count-overflow]
           bool invert = kcontrol->private_value & RME_DIGIFACE_INVERT;
                                                   ^~~~~~~~~~~~~~~~~~~
   sound/usb/mixer_quirks.c:2948:29: note: expanded from macro 'RME_DIGIFACE_INVERT'
   #define RME_DIGIFACE_INVERT BIT(32)
                               ^~~~~~~
   include/vdso/bits.h:7:26: note: expanded from macro 'BIT'
   #define BIT(nr)                 (UL(1) << (nr))
                                          ^  ~~~~
   sound/usb/mixer_quirks.c:3160:4: warning: shift count >= width of type [-Wshift-count-overflow]
                           RME_DIGIFACE_INVERT,
                           ^~~~~~~~~~~~~~~~~~~
   sound/usb/mixer_quirks.c:2948:29: note: expanded from macro 'RME_DIGIFACE_INVERT'
   #define RME_DIGIFACE_INVERT BIT(32)
                               ^~~~~~~
   include/vdso/bits.h:7:26: note: expanded from macro 'BIT'
   #define BIT(nr)                 (UL(1) << (nr))
                                          ^  ~~~~
   sound/usb/mixer_quirks.c:3185:4: warning: shift count >= width of type [-Wshift-count-overflow]
                           RME_DIGIFACE_INVERT,
                           ^~~~~~~~~~~~~~~~~~~
   sound/usb/mixer_quirks.c:2948:29: note: expanded from macro 'RME_DIGIFACE_INVERT'
   #define RME_DIGIFACE_INVERT BIT(32)
                               ^~~~~~~
   include/vdso/bits.h:7:26: note: expanded from macro 'BIT'
   #define BIT(nr)                 (UL(1) << (nr))
                                          ^  ~~~~
   sound/usb/mixer_quirks.c:3210:4: warning: shift count >= width of type [-Wshift-count-overflow]
                           RME_DIGIFACE_INVERT,
                           ^~~~~~~~~~~~~~~~~~~
   sound/usb/mixer_quirks.c:2948:29: note: expanded from macro 'RME_DIGIFACE_INVERT'
   #define RME_DIGIFACE_INVERT BIT(32)
                               ^~~~~~~
   include/vdso/bits.h:7:26: note: expanded from macro 'BIT'
   #define BIT(nr)                 (UL(1) << (nr))
                                          ^  ~~~~
   sound/usb/mixer_quirks.c:3235:4: warning: shift count >= width of type [-Wshift-count-overflow]
                           RME_DIGIFACE_INVERT,
                           ^~~~~~~~~~~~~~~~~~~
   sound/usb/mixer_quirks.c:2948:29: note: expanded from macro 'RME_DIGIFACE_INVERT'
   #define RME_DIGIFACE_INVERT BIT(32)
                               ^~~~~~~
   include/vdso/bits.h:7:26: note: expanded from macro 'BIT'
   #define BIT(nr)                 (UL(1) << (nr))
                                          ^  ~~~~
   6 warnings generated.


vim +3000 sound/usb/mixer_quirks.c

  2995	
  2996	static int snd_rme_digiface_get_status_val(struct snd_kcontrol *kcontrol)
  2997	{
  2998		int err;
  2999		u32 status[4];
> 3000		bool invert = kcontrol->private_value & RME_DIGIFACE_INVERT;
  3001		u8 reg = kcontrol->private_value >> 16;
  3002		u16 mask = kcontrol->private_value & 0xffff;
  3003		u16 val;
  3004	
  3005		err = snd_rme_digiface_read_status(kcontrol, status);
  3006		if (err < 0)
  3007			return err;
  3008	
  3009		switch (reg) {
  3010		/* Status register halfwords */
  3011		case RME_DIGIFACE_STATUS_REG0L ... RME_DIGIFACE_STATUS_REG3H:
  3012			break;
  3013		case RME_DIGIFACE_CTL_REG1: /* Control register 1, present in halfword 3L */
  3014			reg = RME_DIGIFACE_STATUS_REG3L;
  3015			break;
  3016		case RME_DIGIFACE_CTL_REG2: /* Control register 2, present in halfword 3H */
  3017			reg = RME_DIGIFACE_STATUS_REG3H;
  3018			break;
  3019		default:
  3020			return -EINVAL;
  3021		}
  3022	
  3023		if (reg & 1)
  3024			val = status[reg >> 1] >> 16;
  3025		else
  3026			val = status[reg >> 1] & 0xffff;
  3027	
  3028		if (invert)
  3029			val ^= mask;
  3030	
  3031		return field_get(mask, val);
  3032	}
  3033	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 2/2] ALSA: usb-audio: Add mixer quirk for RME Digiface USB
  2024-09-02  7:29   ` kernel test robot
@ 2024-09-02  7:53     ` Asahi Lina
  0 siblings, 0 replies; 8+ messages in thread
From: Asahi Lina @ 2024-09-02  7:53 UTC (permalink / raw)
  To: kernel test robot, Jaroslav Kysela, Takashi Iwai
  Cc: llvm, oe-kbuild-all, Geoffrey D. Bennett, Takashi Sakamoto,
	Mark Hills, Arun Raghavan, Cyan Nyan, linux-sound, linux-kernel



On 9/2/24 4:29 PM, kernel test robot wrote:
> Hi Asahi,
> 
> kernel test robot noticed the following build warnings:
> 
> [auto build test WARNING on 8400291e289ee6b2bf9779ff1c83a291501f017b]
> 
> url:    https://github.com/intel-lab-lkp/linux/commits/Asahi-Lina/ALSA-usb-audio-Add-quirk-for-RME-Digiface-USB/20240902-054004
> base:   8400291e289ee6b2bf9779ff1c83a291501f017b
> patch link:    https://lore.kernel.org/r/20240902-rme-digiface-v1-2-6e88472a2744%40asahilina.net
> patch subject: [PATCH 2/2] ALSA: usb-audio: Add mixer quirk for RME Digiface USB
> config: mips-mtx1_defconfig (https://download.01.org/0day-ci/archive/20240902/202409021549.DbXWdqGa-lkp@intel.com/config)
> compiler: clang version 16.0.6 (https://github.com/llvm/llvm-project 7cbf1a2591520c2491aa35339f227775f4d3adf6)
> reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240902/202409021549.DbXWdqGa-lkp@intel.com/reproduce)
> 
> If you fix the issue in a separate patch/commit (i.e. not just a new version of
> the same patch/commit), kindly add following tags
> | Reported-by: kernel test robot <lkp@intel.com>
> | Closes: https://lore.kernel.org/oe-kbuild-all/202409021549.DbXWdqGa-lkp@intel.com/
> 
> All warnings (new ones prefixed by >>):
> 
>>> sound/usb/mixer_quirks.c:3000:42: warning: shift count >= width of type [-Wshift-count-overflow]
>            bool invert = kcontrol->private_value & RME_DIGIFACE_INVERT;
>                                                    ^~~~~~~~~~~~~~~~~~~
>    sound/usb/mixer_quirks.c:2948:29: note: expanded from macro 'RME_DIGIFACE_INVERT'
>    #define RME_DIGIFACE_INVERT BIT(32)

Oops, this was supposed to be BIT(31). I'll fix it for v2.

>                                ^~~~~~~
>    include/vdso/bits.h:7:26: note: expanded from macro 'BIT'
>    #define BIT(nr)                 (UL(1) << (nr))
>                                           ^  ~~~~
>    sound/usb/mixer_quirks.c:3063:42: warning: shift count >= width of type [-Wshift-count-overflow]
>            bool invert = kcontrol->private_value & RME_DIGIFACE_INVERT;
>                                                    ^~~~~~~~~~~~~~~~~~~
>    sound/usb/mixer_quirks.c:2948:29: note: expanded from macro 'RME_DIGIFACE_INVERT'
>    #define RME_DIGIFACE_INVERT BIT(32)
>                                ^~~~~~~
>    include/vdso/bits.h:7:26: note: expanded from macro 'BIT'
>    #define BIT(nr)                 (UL(1) << (nr))
>                                           ^  ~~~~
>    sound/usb/mixer_quirks.c:3160:4: warning: shift count >= width of type [-Wshift-count-overflow]
>                            RME_DIGIFACE_INVERT,
>                            ^~~~~~~~~~~~~~~~~~~
>    sound/usb/mixer_quirks.c:2948:29: note: expanded from macro 'RME_DIGIFACE_INVERT'
>    #define RME_DIGIFACE_INVERT BIT(32)
>                                ^~~~~~~
>    include/vdso/bits.h:7:26: note: expanded from macro 'BIT'
>    #define BIT(nr)                 (UL(1) << (nr))
>                                           ^  ~~~~
>    sound/usb/mixer_quirks.c:3185:4: warning: shift count >= width of type [-Wshift-count-overflow]
>                            RME_DIGIFACE_INVERT,
>                            ^~~~~~~~~~~~~~~~~~~
>    sound/usb/mixer_quirks.c:2948:29: note: expanded from macro 'RME_DIGIFACE_INVERT'
>    #define RME_DIGIFACE_INVERT BIT(32)
>                                ^~~~~~~
>    include/vdso/bits.h:7:26: note: expanded from macro 'BIT'
>    #define BIT(nr)                 (UL(1) << (nr))
>                                           ^  ~~~~
>    sound/usb/mixer_quirks.c:3210:4: warning: shift count >= width of type [-Wshift-count-overflow]
>                            RME_DIGIFACE_INVERT,
>                            ^~~~~~~~~~~~~~~~~~~
>    sound/usb/mixer_quirks.c:2948:29: note: expanded from macro 'RME_DIGIFACE_INVERT'
>    #define RME_DIGIFACE_INVERT BIT(32)
>                                ^~~~~~~
>    include/vdso/bits.h:7:26: note: expanded from macro 'BIT'
>    #define BIT(nr)                 (UL(1) << (nr))
>                                           ^  ~~~~
>    sound/usb/mixer_quirks.c:3235:4: warning: shift count >= width of type [-Wshift-count-overflow]
>                            RME_DIGIFACE_INVERT,
>                            ^~~~~~~~~~~~~~~~~~~
>    sound/usb/mixer_quirks.c:2948:29: note: expanded from macro 'RME_DIGIFACE_INVERT'
>    #define RME_DIGIFACE_INVERT BIT(32)
>                                ^~~~~~~
>    include/vdso/bits.h:7:26: note: expanded from macro 'BIT'
>    #define BIT(nr)                 (UL(1) << (nr))
>                                           ^  ~~~~
>    6 warnings generated.
> 
> 
> vim +3000 sound/usb/mixer_quirks.c
> 
>   2995	
>   2996	static int snd_rme_digiface_get_status_val(struct snd_kcontrol *kcontrol)
>   2997	{
>   2998		int err;
>   2999		u32 status[4];
>> 3000		bool invert = kcontrol->private_value & RME_DIGIFACE_INVERT;
>   3001		u8 reg = kcontrol->private_value >> 16;
>   3002		u16 mask = kcontrol->private_value & 0xffff;
>   3003		u16 val;
>   3004	
>   3005		err = snd_rme_digiface_read_status(kcontrol, status);
>   3006		if (err < 0)
>   3007			return err;
>   3008	
>   3009		switch (reg) {
>   3010		/* Status register halfwords */
>   3011		case RME_DIGIFACE_STATUS_REG0L ... RME_DIGIFACE_STATUS_REG3H:
>   3012			break;
>   3013		case RME_DIGIFACE_CTL_REG1: /* Control register 1, present in halfword 3L */
>   3014			reg = RME_DIGIFACE_STATUS_REG3L;
>   3015			break;
>   3016		case RME_DIGIFACE_CTL_REG2: /* Control register 2, present in halfword 3H */
>   3017			reg = RME_DIGIFACE_STATUS_REG3H;
>   3018			break;
>   3019		default:
>   3020			return -EINVAL;
>   3021		}
>   3022	
>   3023		if (reg & 1)
>   3024			val = status[reg >> 1] >> 16;
>   3025		else
>   3026			val = status[reg >> 1] & 0xffff;
>   3027	
>   3028		if (invert)
>   3029			val ^= mask;
>   3030	
>   3031		return field_get(mask, val);
>   3032	}
>   3033	
> 

~~ Lina

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 1/2] ALSA: usb-audio: Add quirk for RME Digiface USB
  2024-09-02  6:10   ` Takashi Iwai
@ 2024-09-02  8:12     ` Asahi Lina
  2024-09-02  8:16       ` Takashi Iwai
  0 siblings, 1 reply; 8+ messages in thread
From: Asahi Lina @ 2024-09-02  8:12 UTC (permalink / raw)
  To: Takashi Iwai
  Cc: Jaroslav Kysela, Takashi Iwai, Geoffrey D. Bennett,
	Takashi Sakamoto, Mark Hills, Arun Raghavan, Cyan Nyan,
	linux-sound, linux-kernel



On 9/2/24 3:10 PM, Takashi Iwai wrote:
> On Sun, 01 Sep 2024 23:31:50 +0200,
> Asahi Lina wrote:
>>
>> From: Cyan Nyan <cyan.vtb@gmail.com>
>>
>> Add trivial support for audio streaming on the RME Digiface USB. Binds
>> only to the first interface to allow userspace to directly drive the
>> complex I/O and matrix mixer controls.
>>
>> Signed-off-by: Cyan Nyan <cyan.vtb@gmail.com>
>> [Lina: Added 2x/4x sample rate support & boot/format quirks]
>> Co-developed-by: Asahi Lina <lina@asahilina.net>
>> Signed-off-by: Asahi Lina <lina@asahilina.net>
>> ---
>>  sound/usb/quirks-table.h | 190 ++++++++++++++++++++++++++++++++++++++++++++++-
>>  sound/usb/quirks.c       |  58 +++++++++++++++
>>  2 files changed, 247 insertions(+), 1 deletion(-)
>>
>> diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h
>> index 73abc38a5400..47fd18791396 100644
>> --- a/sound/usb/quirks-table.h
>> +++ b/sound/usb/quirks-table.h
>> @@ -4546,6 +4546,194 @@ YAMAHA_DEVICE(0x7010, "UB99"),
>>  		}
>>  	}
>>  },
>> -
>> +{
>> +	/* Only claim interface 0 */
>> +	.match_flags = USB_DEVICE_ID_MATCH_VENDOR |
>> +		       USB_DEVICE_ID_MATCH_PRODUCT |
>> +		       USB_DEVICE_ID_MATCH_INT_CLASS |
>> +		       USB_DEVICE_ID_MATCH_INT_NUMBER,
>> +	.idVendor = 0x2a39,
>> +	.idProduct = 0x3f8c,
>> +	.bInterfaceClass = USB_CLASS_VENDOR_SPEC,
>> +	.bInterfaceNumber = 0,
>> +	.driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
>> +		.ifnum = QUIRK_ANY_INTERFACE,
>> +		.type = QUIRK_COMPOSITE,
> (snip)
> 
> Recently the quirk tables are rewritten with macros.
> See the commit d79e13f8e8abb5cd3a2a0f9fc9bc3fc750c5b06f
>     ALSA: usb-audio: Replace complex quirk lines with macros
> in for-next branch of sound.git tree.
> 
> Could you try to apply to your new entries, too?

Sure! Note that I open-coded the USB match because I need to add
USB_DEVICE_ID_MATCH_INT_NUMBER (to stop the driver from binding to and
claiming all interfaces, QUIRK_DATA_IGNORE() is not enough for that).
Should I leave it like that (since it's the only case so far) or do you
want me to introduce another macro for that case?

I'll rewrite the quirk info stuff with the macros for v2. I'll also
remove USB_ENDPOINT_USAGE_IMPLICIT_FB since I'm pretty sure that does
nothing here (at first I thought I could get it to pick up the implicit
FB with that but I ended up having to specify the sync/implicit_fb stuff
explicitly).

~~ Lina

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 1/2] ALSA: usb-audio: Add quirk for RME Digiface USB
  2024-09-02  8:12     ` Asahi Lina
@ 2024-09-02  8:16       ` Takashi Iwai
  0 siblings, 0 replies; 8+ messages in thread
From: Takashi Iwai @ 2024-09-02  8:16 UTC (permalink / raw)
  To: Asahi Lina
  Cc: Takashi Iwai, Jaroslav Kysela, Takashi Iwai, Geoffrey D. Bennett,
	Takashi Sakamoto, Mark Hills, Arun Raghavan, Cyan Nyan,
	linux-sound, linux-kernel

On Mon, 02 Sep 2024 10:12:18 +0200,
Asahi Lina wrote:
> 
> 
> 
> On 9/2/24 3:10 PM, Takashi Iwai wrote:
> > On Sun, 01 Sep 2024 23:31:50 +0200,
> > Asahi Lina wrote:
> >>
> >> From: Cyan Nyan <cyan.vtb@gmail.com>
> >>
> >> Add trivial support for audio streaming on the RME Digiface USB. Binds
> >> only to the first interface to allow userspace to directly drive the
> >> complex I/O and matrix mixer controls.
> >>
> >> Signed-off-by: Cyan Nyan <cyan.vtb@gmail.com>
> >> [Lina: Added 2x/4x sample rate support & boot/format quirks]
> >> Co-developed-by: Asahi Lina <lina@asahilina.net>
> >> Signed-off-by: Asahi Lina <lina@asahilina.net>
> >> ---
> >>  sound/usb/quirks-table.h | 190 ++++++++++++++++++++++++++++++++++++++++++++++-
> >>  sound/usb/quirks.c       |  58 +++++++++++++++
> >>  2 files changed, 247 insertions(+), 1 deletion(-)
> >>
> >> diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h
> >> index 73abc38a5400..47fd18791396 100644
> >> --- a/sound/usb/quirks-table.h
> >> +++ b/sound/usb/quirks-table.h
> >> @@ -4546,6 +4546,194 @@ YAMAHA_DEVICE(0x7010, "UB99"),
> >>  		}
> >>  	}
> >>  },
> >> -
> >> +{
> >> +	/* Only claim interface 0 */
> >> +	.match_flags = USB_DEVICE_ID_MATCH_VENDOR |
> >> +		       USB_DEVICE_ID_MATCH_PRODUCT |
> >> +		       USB_DEVICE_ID_MATCH_INT_CLASS |
> >> +		       USB_DEVICE_ID_MATCH_INT_NUMBER,
> >> +	.idVendor = 0x2a39,
> >> +	.idProduct = 0x3f8c,
> >> +	.bInterfaceClass = USB_CLASS_VENDOR_SPEC,
> >> +	.bInterfaceNumber = 0,
> >> +	.driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
> >> +		.ifnum = QUIRK_ANY_INTERFACE,
> >> +		.type = QUIRK_COMPOSITE,
> > (snip)
> > 
> > Recently the quirk tables are rewritten with macros.
> > See the commit d79e13f8e8abb5cd3a2a0f9fc9bc3fc750c5b06f
> >     ALSA: usb-audio: Replace complex quirk lines with macros
> > in for-next branch of sound.git tree.
> > 
> > Could you try to apply to your new entries, too?
> 
> Sure! Note that I open-coded the USB match because I need to add
> USB_DEVICE_ID_MATCH_INT_NUMBER (to stop the driver from binding to and
> claiming all interfaces, QUIRK_DATA_IGNORE() is not enough for that).
> Should I leave it like that (since it's the only case so far) or do you
> want me to introduce another macro for that case?

The open-code with match_flags is fine, you can keep that.
If we have other similar cases, we can introduce a macro for cleanup
later, too.


> I'll rewrite the quirk info stuff with the macros for v2. I'll also
> remove USB_ENDPOINT_USAGE_IMPLICIT_FB since I'm pretty sure that does
> nothing here (at first I thought I could get it to pick up the implicit
> FB with that but I ended up having to specify the sync/implicit_fb stuff
> explicitly).

Sounds good.  Thanks!


Takashi

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2024-09-02  8:15 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-09-01 21:31 [PATCH 0/2] ALSA: usb-audio: Add basic support for RME Digiface USB Asahi Lina
2024-09-01 21:31 ` [PATCH 1/2] ALSA: usb-audio: Add quirk " Asahi Lina
2024-09-02  6:10   ` Takashi Iwai
2024-09-02  8:12     ` Asahi Lina
2024-09-02  8:16       ` Takashi Iwai
2024-09-01 21:31 ` [PATCH 2/2] ALSA: usb-audio: Add mixer " Asahi Lina
2024-09-02  7:29   ` kernel test robot
2024-09-02  7:53     ` Asahi Lina

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox