All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/2] ALSA: usb-audio: scarlett2: Read all configuration at init time
@ 2021-06-06 14:16 Geoffrey D. Bennett
  2021-06-06 14:16 ` [PATCH 1/2] ALSA: usb-audio: scarlett2: Read mixer volumes " Geoffrey D. Bennett
                   ` (2 more replies)
  0 siblings, 3 replies; 11+ messages in thread
From: Geoffrey D. Bennett @ 2021-06-06 14:16 UTC (permalink / raw)
  To: alsa-devel, Takashi Iwai
  Cc: Daniel Sales, Markus Schroetter, Vladimir Sadovnikov, Alex Fellows

These two patches add support for reading the mixer volumes and mux
configuration from the hardware when the driver is initialising.

Previously the ALSA volume controls were initialised to zero and the
mux configuration set to a fixed default instead of being initialised
to match the hardware state.

The ALSA controls for the Scarlett Gen 2 interfaces should now always
be in sync with the hardware. Thanks to Vladimir Sadovnikov for
figuring out how to do this.

Takashi, if these pass your review, I believe that they are
appropriate for:
#Cc: stable@vger.kernel.org

Geoffrey D. Bennett (2):
  ALSA: usb-audio: scarlett2: Read mixer volumes at init time
  ALSA: usb-audio: scarlett2: Read mux at init time

 sound/usb/mixer_scarlett_gen2.c | 227 ++++++++++++++++++++++----------
 1 file changed, 161 insertions(+), 66 deletions(-)

-- 
2.31.1


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

* [PATCH 1/2] ALSA: usb-audio: scarlett2: Read mixer volumes at init time
  2021-06-06 14:16 [PATCH 0/2] ALSA: usb-audio: scarlett2: Read all configuration at init time Geoffrey D. Bennett
@ 2021-06-06 14:16 ` Geoffrey D. Bennett
  2021-06-06 14:32   ` Markus
  2021-06-07  5:23     ` kernel test robot
  2021-06-06 14:17 ` [PATCH 2/2] ALSA: usb-audio: scarlett2: Read mux " Geoffrey D. Bennett
  2021-06-07  7:23 ` [PATCH 0/2] ALSA: usb-audio: scarlett2: Read all configuration " Takashi Iwai
  2 siblings, 2 replies; 11+ messages in thread
From: Geoffrey D. Bennett @ 2021-06-06 14:16 UTC (permalink / raw)
  To: alsa-devel, Takashi Iwai
  Cc: Daniel Sales, Markus Schroetter, Vladimir Sadovnikov, Alex Fellows

Add support for reading the mixer volumes from the hardware when the
driver is initialising. Previously these ALSA volume controls were
initialised to zero instead of being initialised to match the hardware
state.

Fixes: 9e4d5c1be21f ("ALSA: usb-audio: Scarlett Gen 2 mixer interface")
Suggested-by: Vladimir Sadovnikov <sadko4u@gmail.com>
Signed-off-by: Geoffrey D. Bennett <g@b4.vu>
---
 sound/usb/mixer_scarlett_gen2.c | 57 +++++++++++++++++++++++++++++++--
 1 file changed, 55 insertions(+), 2 deletions(-)

diff --git a/sound/usb/mixer_scarlett_gen2.c b/sound/usb/mixer_scarlett_gen2.c
index 4caf379d5b99..b0043906c77f 100644
--- a/sound/usb/mixer_scarlett_gen2.c
+++ b/sound/usb/mixer_scarlett_gen2.c
@@ -117,11 +117,12 @@
 #define SCARLETT2_MIXER_MAX_DB 6
 #define SCARLETT2_MIXER_MAX_VALUE \
 	((SCARLETT2_MIXER_MAX_DB - SCARLETT2_MIXER_MIN_DB) * 2)
+#define SCARLETT2_MIXER_VALUE_COUNT (SCARLETT2_MIXER_MAX_VALUE + 1)
 
 /* map from (dB + 80) * 2 to mixer value
  * for dB in 0 .. 172: int(8192 * pow(10, ((dB - 160) / 2 / 20)))
  */
-static const u16 scarlett2_mixer_values[173] = {
+static const u16 scarlett2_mixer_values[SCARLETT2_MIXER_VALUE_COUNT] = {
 	0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2,
 	2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 8, 8,
 	9, 9, 10, 10, 11, 12, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
@@ -465,6 +466,7 @@ static int scarlett2_get_port_start_num(const struct scarlett2_ports *ports,
 
 #define SCARLETT2_USB_INIT_SEQ 0x00000000
 #define SCARLETT2_USB_GET_METER_LEVELS 0x00001001
+#define SCARLETT2_USB_GET_MIX 0x00002001
 #define SCARLETT2_USB_SET_MIX 0x00002002
 #define SCARLETT2_USB_SET_MUX 0x00003002
 #define SCARLETT2_USB_GET_DATA 0x00800000
@@ -784,6 +786,49 @@ static int scarlett2_usb_get_volume_status(
 				 buf, sizeof(*buf));
 }
 
+/* Send a USB message to get the volumes for all inputs of one mix
+ * and put the values into private->mix[]
+ */
+static int scarlett2_usb_get_mix(struct usb_mixer_interface *mixer,
+				 int mix_num)
+{
+	struct scarlett2_mixer_data *private = mixer->private_data;
+	const struct scarlett2_device_info *info = private->info;
+
+	int num_mixer_in =
+		info->ports[SCARLETT2_PORT_TYPE_MIX].num[SCARLETT2_PORT_OUT];
+	int err, i, j, k;
+
+	struct {
+		__le16 mix_num;
+		__le16 count;
+	} __packed req;
+
+	__le16 data[SCARLETT2_INPUT_MIX_MAX];
+
+	req.mix_num = mix_num;
+	req.count = num_mixer_in;
+
+	err = scarlett2_usb(mixer, SCARLETT2_USB_GET_MIX,
+			    &req, sizeof(req),
+			    data, num_mixer_in * sizeof(u16));
+	if (err < 0)
+		return err;
+
+	for (i = 0, j = mix_num * num_mixer_in; i < num_mixer_in; i++, j++) {
+		u16 mixer_value = le16_to_cpu(data[i]);
+
+		for (k = 0; k < SCARLETT2_MIXER_VALUE_COUNT; k++)
+			if (scarlett2_mixer_values[k] >= mixer_value)
+				break;
+		if (k == SCARLETT2_MIXER_VALUE_COUNT)
+			k = SCARLETT2_MIXER_MAX_VALUE;
+		private->mix[j] = k;
+	}
+
+	return 0;
+}
+
 /* Send a USB message to set the volumes for all inputs of one mix
  * (values obtained from private->mix[])
  */
@@ -1831,7 +1876,7 @@ static int scarlett2_init_private(struct usb_mixer_interface *mixer,
 	return scarlett2_usb(mixer, SCARLETT2_USB_INIT_SEQ, NULL, 0, NULL, 0);
 }
 
-/* Read line-in config and line-out volume settings on start */
+/* Read configuration from the interface on start */
 static int scarlett2_read_configs(struct usb_mixer_interface *mixer)
 {
 	struct scarlett2_mixer_data *private = mixer->private_data;
@@ -1839,6 +1884,8 @@ static int scarlett2_read_configs(struct usb_mixer_interface *mixer)
 	const struct scarlett2_ports *ports = info->ports;
 	int num_line_out =
 		ports[SCARLETT2_PORT_TYPE_ANALOGUE].num[SCARLETT2_PORT_OUT];
+	int num_mixer_out =
+		ports[SCARLETT2_PORT_TYPE_MIX].num[SCARLETT2_PORT_IN];
 	u8 level_switches[SCARLETT2_LEVEL_SWITCH_MAX];
 	u8 pad_switches[SCARLETT2_PAD_SWITCH_MAX];
 	struct scarlett2_usb_volume_status volume_status;
@@ -1894,6 +1941,12 @@ static int scarlett2_read_configs(struct usb_mixer_interface *mixer)
 	for (i = 0; i < info->button_count; i++)
 		private->buttons[i] = !!volume_status.buttons[i];
 
+	for (i = 0; i < num_mixer_out; i++) {
+		err = scarlett2_usb_get_mix(mixer, i);
+		if (err < 0)
+			return err;
+	}
+
 	return 0;
 }
 
-- 
2.31.1


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

* [PATCH 2/2] ALSA: usb-audio: scarlett2: Read mux at init time
  2021-06-06 14:16 [PATCH 0/2] ALSA: usb-audio: scarlett2: Read all configuration at init time Geoffrey D. Bennett
  2021-06-06 14:16 ` [PATCH 1/2] ALSA: usb-audio: scarlett2: Read mixer volumes " Geoffrey D. Bennett
@ 2021-06-06 14:17 ` Geoffrey D. Bennett
  2021-06-06 14:33   ` Markus
  2021-06-07  7:23 ` [PATCH 0/2] ALSA: usb-audio: scarlett2: Read all configuration " Takashi Iwai
  2 siblings, 1 reply; 11+ messages in thread
From: Geoffrey D. Bennett @ 2021-06-06 14:17 UTC (permalink / raw)
  To: alsa-devel, Takashi Iwai
  Cc: Daniel Sales, Markus Schroetter, Vladimir Sadovnikov, Alex Fellows

Add support for retrieving the mux configuration from the hardware
when the driver is initialising. Previously the ALSA controls were
initialised to a default hard-coded state instead of being initialised
to match the hardware state.

Fixes: 9e4d5c1be21f ("ALSA: usb-audio: Scarlett Gen 2 mixer interface")
Suggested-by: Vladimir Sadovnikov <sadko4u@gmail.com>
Signed-off-by: Geoffrey D. Bennett <g@b4.vu>
---
 sound/usb/mixer_scarlett_gen2.c | 170 ++++++++++++++++++++------------
 1 file changed, 106 insertions(+), 64 deletions(-)

diff --git a/sound/usb/mixer_scarlett_gen2.c b/sound/usb/mixer_scarlett_gen2.c
index b0043906c77f..48cf3e1954e0 100644
--- a/sound/usb/mixer_scarlett_gen2.c
+++ b/sound/usb/mixer_scarlett_gen2.c
@@ -32,6 +32,10 @@
  * Scarlett 6i6 support added in June 2019 (thanks to Martin Wittmann
  * for providing usbmon output and testing).
  *
+ * Support for loading mixer volume and mux configuration from the
+ * interface during driver initialisation added in May 2021 (thanks to
+ * Vladimir Sadovnikov for figuring out how).
+ *
  * This ALSA mixer gives access to:
  *  - input, output, mixer-matrix muxes
  *  - 18x10 mixer-matrix gain stages
@@ -228,6 +232,7 @@ struct scarlett2_mixer_data {
 	struct delayed_work work;
 	const struct scarlett2_device_info *info;
 	int num_mux_srcs;
+	int num_mux_dsts;
 	u16 scarlett2_seq;
 	u8 vol_updated;
 	u8 master_vol;
@@ -468,6 +473,7 @@ static int scarlett2_get_port_start_num(const struct scarlett2_ports *ports,
 #define SCARLETT2_USB_GET_METER_LEVELS 0x00001001
 #define SCARLETT2_USB_GET_MIX 0x00002001
 #define SCARLETT2_USB_SET_MIX 0x00002002
+#define SCARLETT2_USB_GET_MUX 0x00003001
 #define SCARLETT2_USB_SET_MUX 0x00003002
 #define SCARLETT2_USB_GET_DATA 0x00800000
 #define SCARLETT2_USB_SET_DATA 0x00800001
@@ -877,6 +883,94 @@ static u32 scarlett2_mux_src_num_to_id(const struct scarlett2_ports *ports,
 	return 0;
 }
 
+/* Convert a hardware ID to a port number index */
+static u32 scarlett2_mux_id_to_num(const struct scarlett2_ports *ports,
+				   int direction,
+				   u32 id)
+{
+	int port_type;
+	int port_num = 0;
+
+	for (port_type = 0;
+	     port_type < SCARLETT2_PORT_TYPE_COUNT;
+	     port_type++) {
+		struct scarlett2_ports port = ports[port_type];
+		int count = port.num[direction];
+
+		if (id >= port.id && id < port.id + count)
+			return port_num + id - port.id;
+		port_num += count;
+	}
+
+	/* Oops */
+	return -1;
+}
+
+/* Convert one mux entry from the interface and load into private->mux[] */
+static void scarlett2_usb_populate_mux(struct scarlett2_mixer_data *private,
+				       u32 mux_entry)
+{
+	const struct scarlett2_device_info *info = private->info;
+	const struct scarlett2_ports *ports = info->ports;
+
+	int dst_idx, src_idx;
+
+	dst_idx = scarlett2_mux_id_to_num(ports, SCARLETT2_PORT_OUT,
+					  mux_entry & 0xFFF);
+	if (dst_idx < 0)
+		return;
+
+	if (dst_idx >= private->num_mux_dsts) {
+		usb_audio_err(private->mixer->chip,
+			"BUG: scarlett2_mux_id_to_num(%06x, OUT): %d >= %d",
+			mux_entry, dst_idx, private->num_mux_dsts);
+		return;
+	}
+
+	src_idx = scarlett2_mux_id_to_num(ports, SCARLETT2_PORT_IN,
+					  mux_entry >> 12);
+	if (src_idx < 0)
+		return;
+
+	if (src_idx >= private->num_mux_srcs) {
+		usb_audio_err(private->mixer->chip,
+			"BUG: scarlett2_mux_id_to_num(%06x, IN): %d >= %d",
+			mux_entry, src_idx, private->num_mux_srcs);
+		return;
+	}
+
+	private->mux[dst_idx] = src_idx;
+}
+
+/* Send USB message to get mux inputs and then populate private->mux[] */
+static int scarlett2_usb_get_mux(struct usb_mixer_interface *mixer)
+{
+	struct scarlett2_mixer_data *private = mixer->private_data;
+	int count = private->num_mux_dsts;
+	int err, i;
+
+	struct {
+		__le16 num;
+		__le16 count;
+	} __packed req;
+
+	__le32 data[SCARLETT2_MUX_MAX];
+
+	req.num = 0;
+	req.count = cpu_to_le16(count);
+
+	err = scarlett2_usb(mixer, SCARLETT2_USB_GET_MUX,
+			    &req, sizeof(req),
+			    data, count * sizeof(u32));
+	if (err < 0)
+		return err;
+
+	for (i = 0; i < count; i++)
+		scarlett2_usb_populate_mux(private, le32_to_cpu(data[i]));
+
+	return 0;
+}
+
 /* Send USB messages to set mux inputs */
 static int scarlett2_usb_set_mux(struct usb_mixer_interface *mixer)
 {
@@ -1783,72 +1877,23 @@ static void scarlett2_private_suspend(struct usb_mixer_interface *mixer)
 
 /*** Initialisation ***/
 
-static int scarlett2_count_mux_srcs(const struct scarlett2_ports *ports)
+static void scarlett2_count_mux_io(struct scarlett2_mixer_data *private)
 {
-	int port_type, count = 0;
+	const struct scarlett2_ports *ports = private->info->ports;
+	int port_type, srcs = 0, dsts = 0;
 
 	for (port_type = 0;
 	     port_type < SCARLETT2_PORT_TYPE_COUNT;
-	     port_type++)
-		count += ports[port_type].num[SCARLETT2_PORT_IN];
-
-	return count;
-}
-
-/* Default routing connects PCM outputs and inputs to Analogue,
- * S/PDIF, then ADAT
- */
-static void scarlett2_init_routing(u8 *mux,
-				   const struct scarlett2_ports *ports)
-{
-	int i, input_num, input_count, port_type;
-	int output_num, output_count, port_type_connect_num;
-
-	static const int connect_order[] = {
-		SCARLETT2_PORT_TYPE_ANALOGUE,
-		SCARLETT2_PORT_TYPE_SPDIF,
-		SCARLETT2_PORT_TYPE_ADAT,
-		-1
-	};
-
-	/* Assign PCM inputs (routing outputs) */
-	output_num = scarlett2_get_port_start_num(ports,
-						  SCARLETT2_PORT_OUT,
-						  SCARLETT2_PORT_TYPE_PCM);
-	output_count = ports[SCARLETT2_PORT_TYPE_PCM].num[SCARLETT2_PORT_OUT];
-
-	for (port_type = connect_order[port_type_connect_num = 0];
-	     port_type >= 0;
-	     port_type = connect_order[++port_type_connect_num]) {
-		input_num = scarlett2_get_port_start_num(
-			ports, SCARLETT2_PORT_IN, port_type);
-		input_count = ports[port_type].num[SCARLETT2_PORT_IN];
-		for (i = 0;
-		     i < input_count && output_count;
-		     i++, output_count--)
-			mux[output_num++] = input_num++;
+	     port_type++) {
+		srcs += ports[port_type].num[SCARLETT2_PORT_IN];
+		dsts += ports[port_type].num[SCARLETT2_PORT_OUT_44];
 	}
 
-	/* Assign PCM outputs (routing inputs) */
-	input_num = scarlett2_get_port_start_num(ports,
-						 SCARLETT2_PORT_IN,
-						 SCARLETT2_PORT_TYPE_PCM);
-	input_count = ports[SCARLETT2_PORT_TYPE_PCM].num[SCARLETT2_PORT_IN];
-
-	for (port_type = connect_order[port_type_connect_num = 0];
-	     port_type >= 0;
-	     port_type = connect_order[++port_type_connect_num]) {
-		output_num = scarlett2_get_port_start_num(
-			ports, SCARLETT2_PORT_OUT, port_type);
-		output_count = ports[port_type].num[SCARLETT2_PORT_OUT];
-		for (i = 0;
-		     i < output_count && input_count;
-		     i++, input_count--)
-			mux[output_num++] = input_num++;
-	}
+	private->num_mux_srcs = srcs;
+	private->num_mux_dsts = dsts;
 }
 
-/* Initialise private data, routing, sequence number */
+/* Initialise private data and sequence number */
 static int scarlett2_init_private(struct usb_mixer_interface *mixer,
 				  const struct scarlett2_device_info *info)
 {
@@ -1862,16 +1907,13 @@ static int scarlett2_init_private(struct usb_mixer_interface *mixer,
 	mutex_init(&private->data_mutex);
 	INIT_DELAYED_WORK(&private->work, scarlett2_config_save_work);
 	private->info = info;
-	private->num_mux_srcs = scarlett2_count_mux_srcs(info->ports);
+	scarlett2_count_mux_io(private);
 	private->scarlett2_seq = 0;
 	private->mixer = mixer;
 	mixer->private_data = private;
 	mixer->private_free = scarlett2_private_free;
 	mixer->private_suspend = scarlett2_private_suspend;
 
-	/* Setup default routing */
-	scarlett2_init_routing(private->mux, info->ports);
-
 	/* Initialise the sequence number used for the proprietary commands */
 	return scarlett2_usb(mixer, SCARLETT2_USB_INIT_SEQ, NULL, 0, NULL, 0);
 }
@@ -1947,7 +1989,7 @@ static int scarlett2_read_configs(struct usb_mixer_interface *mixer)
 			return err;
 	}
 
-	return 0;
+	return scarlett2_usb_get_mux(mixer);
 }
 
 /* Notify on volume change */
@@ -2055,7 +2097,7 @@ static int snd_scarlett_gen2_controls_create(struct usb_mixer_interface *mixer,
 {
 	int err;
 
-	/* Initialise private data, routing, sequence number */
+	/* Initialise private data and sequence number */
 	err = scarlett2_init_private(mixer, info);
 	if (err < 0)
 		return err;
-- 
2.31.1


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

* Re: [PATCH 1/2] ALSA: usb-audio: scarlett2: Read mixer volumes at init time
  2021-06-06 14:16 ` [PATCH 1/2] ALSA: usb-audio: scarlett2: Read mixer volumes " Geoffrey D. Bennett
@ 2021-06-06 14:32   ` Markus
  2021-06-07  5:23     ` kernel test robot
  1 sibling, 0 replies; 11+ messages in thread
From: Markus @ 2021-06-06 14:32 UTC (permalink / raw)
  To: alsa-devel

On 06.06.21 16:16, Geoffrey D. Bennett wrote:
> Add support for reading the mixer volumes from the hardware when the
> driver is initialising. Previously these ALSA volume controls were
> initialised to zero instead of being initialised to match the hardware
> state.
>
> Fixes: 9e4d5c1be21f ("ALSA: usb-audio: Scarlett Gen 2 mixer interface")
> Suggested-by: Vladimir Sadovnikov <sadko4u@gmail.com>
> Signed-off-by: Geoffrey D. Bennett <g@b4.vu>

Tested-by: Markus Schroetter <project.m.schroetter@gmail.com>

> ---
>  sound/usb/mixer_scarlett_gen2.c | 57 +++++++++++++++++++++++++++++++--
>  1 file changed, 55 insertions(+), 2 deletions(-)
>
> diff --git a/sound/usb/mixer_scarlett_gen2.c b/sound/usb/mixer_scarlett_gen2.c
> index 4caf379d5b99..b0043906c77f 100644
> --- a/sound/usb/mixer_scarlett_gen2.c
> +++ b/sound/usb/mixer_scarlett_gen2.c
> @@ -117,11 +117,12 @@
>  #define SCARLETT2_MIXER_MAX_DB 6
>  #define SCARLETT2_MIXER_MAX_VALUE \
>  	((SCARLETT2_MIXER_MAX_DB - SCARLETT2_MIXER_MIN_DB) * 2)
> +#define SCARLETT2_MIXER_VALUE_COUNT (SCARLETT2_MIXER_MAX_VALUE + 1)
>  
>  /* map from (dB + 80) * 2 to mixer value
>   * for dB in 0 .. 172: int(8192 * pow(10, ((dB - 160) / 2 / 20)))
>   */
> -static const u16 scarlett2_mixer_values[173] = {
> +static const u16 scarlett2_mixer_values[SCARLETT2_MIXER_VALUE_COUNT] = {
>  	0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2,
>  	2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 8, 8,
>  	9, 9, 10, 10, 11, 12, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
> @@ -465,6 +466,7 @@ static int scarlett2_get_port_start_num(const struct scarlett2_ports *ports,
>  
>  #define SCARLETT2_USB_INIT_SEQ 0x00000000
>  #define SCARLETT2_USB_GET_METER_LEVELS 0x00001001
> +#define SCARLETT2_USB_GET_MIX 0x00002001
>  #define SCARLETT2_USB_SET_MIX 0x00002002
>  #define SCARLETT2_USB_SET_MUX 0x00003002
>  #define SCARLETT2_USB_GET_DATA 0x00800000
> @@ -784,6 +786,49 @@ static int scarlett2_usb_get_volume_status(
>  				 buf, sizeof(*buf));
>  }
>  
> +/* Send a USB message to get the volumes for all inputs of one mix
> + * and put the values into private->mix[]
> + */
> +static int scarlett2_usb_get_mix(struct usb_mixer_interface *mixer,
> +				 int mix_num)
> +{
> +	struct scarlett2_mixer_data *private = mixer->private_data;
> +	const struct scarlett2_device_info *info = private->info;
> +
> +	int num_mixer_in =
> +		info->ports[SCARLETT2_PORT_TYPE_MIX].num[SCARLETT2_PORT_OUT];
> +	int err, i, j, k;
> +
> +	struct {
> +		__le16 mix_num;
> +		__le16 count;
> +	} __packed req;
> +
> +	__le16 data[SCARLETT2_INPUT_MIX_MAX];
> +
> +	req.mix_num = mix_num;
> +	req.count = num_mixer_in;
> +
> +	err = scarlett2_usb(mixer, SCARLETT2_USB_GET_MIX,
> +			    &req, sizeof(req),
> +			    data, num_mixer_in * sizeof(u16));
> +	if (err < 0)
> +		return err;
> +
> +	for (i = 0, j = mix_num * num_mixer_in; i < num_mixer_in; i++, j++) {
> +		u16 mixer_value = le16_to_cpu(data[i]);
> +
> +		for (k = 0; k < SCARLETT2_MIXER_VALUE_COUNT; k++)
> +			if (scarlett2_mixer_values[k] >= mixer_value)
> +				break;
> +		if (k == SCARLETT2_MIXER_VALUE_COUNT)
> +			k = SCARLETT2_MIXER_MAX_VALUE;
> +		private->mix[j] = k;
> +	}
> +
> +	return 0;
> +}
> +
>  /* Send a USB message to set the volumes for all inputs of one mix
>   * (values obtained from private->mix[])
>   */
> @@ -1831,7 +1876,7 @@ static int scarlett2_init_private(struct usb_mixer_interface *mixer,
>  	return scarlett2_usb(mixer, SCARLETT2_USB_INIT_SEQ, NULL, 0, NULL, 0);
>  }
>  
> -/* Read line-in config and line-out volume settings on start */
> +/* Read configuration from the interface on start */
>  static int scarlett2_read_configs(struct usb_mixer_interface *mixer)
>  {
>  	struct scarlett2_mixer_data *private = mixer->private_data;
> @@ -1839,6 +1884,8 @@ static int scarlett2_read_configs(struct usb_mixer_interface *mixer)
>  	const struct scarlett2_ports *ports = info->ports;
>  	int num_line_out =
>  		ports[SCARLETT2_PORT_TYPE_ANALOGUE].num[SCARLETT2_PORT_OUT];
> +	int num_mixer_out =
> +		ports[SCARLETT2_PORT_TYPE_MIX].num[SCARLETT2_PORT_IN];
>  	u8 level_switches[SCARLETT2_LEVEL_SWITCH_MAX];
>  	u8 pad_switches[SCARLETT2_PAD_SWITCH_MAX];
>  	struct scarlett2_usb_volume_status volume_status;
> @@ -1894,6 +1941,12 @@ static int scarlett2_read_configs(struct usb_mixer_interface *mixer)
>  	for (i = 0; i < info->button_count; i++)
>  		private->buttons[i] = !!volume_status.buttons[i];
>  
> +	for (i = 0; i < num_mixer_out; i++) {
> +		err = scarlett2_usb_get_mix(mixer, i);
> +		if (err < 0)
> +			return err;
> +	}
> +
>  	return 0;
>  }
>  

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

* Re: [PATCH 2/2] ALSA: usb-audio: scarlett2: Read mux at init time
  2021-06-06 14:17 ` [PATCH 2/2] ALSA: usb-audio: scarlett2: Read mux " Geoffrey D. Bennett
@ 2021-06-06 14:33   ` Markus
  0 siblings, 0 replies; 11+ messages in thread
From: Markus @ 2021-06-06 14:33 UTC (permalink / raw)
  To: alsa-devel

On 06.06.21 16:17, Geoffrey D. Bennett wrote:

> Add support for retrieving the mux configuration from the hardware
> when the driver is initialising. Previously the ALSA controls were
> initialised to a default hard-coded state instead of being initialised
> to match the hardware state.
>
> Fixes: 9e4d5c1be21f ("ALSA: usb-audio: Scarlett Gen 2 mixer interface")
> Suggested-by: Vladimir Sadovnikov <sadko4u@gmail.com>
> Signed-off-by: Geoffrey D. Bennett <g@b4.vu>

Tested-by: Markus Schroetter <project.m.schroetter@gmail.com>

> ---
>  sound/usb/mixer_scarlett_gen2.c | 170 ++++++++++++++++++++------------
>  1 file changed, 106 insertions(+), 64 deletions(-)
>
> diff --git a/sound/usb/mixer_scarlett_gen2.c b/sound/usb/mixer_scarlett_gen2.c
> index b0043906c77f..48cf3e1954e0 100644
> --- a/sound/usb/mixer_scarlett_gen2.c
> +++ b/sound/usb/mixer_scarlett_gen2.c
> @@ -32,6 +32,10 @@
>   * Scarlett 6i6 support added in June 2019 (thanks to Martin Wittmann
>   * for providing usbmon output and testing).
>   *
> + * Support for loading mixer volume and mux configuration from the
> + * interface during driver initialisation added in May 2021 (thanks to
> + * Vladimir Sadovnikov for figuring out how).
> + *
>   * This ALSA mixer gives access to:
>   *  - input, output, mixer-matrix muxes
>   *  - 18x10 mixer-matrix gain stages
> @@ -228,6 +232,7 @@ struct scarlett2_mixer_data {
>  	struct delayed_work work;
>  	const struct scarlett2_device_info *info;
>  	int num_mux_srcs;
> +	int num_mux_dsts;
>  	u16 scarlett2_seq;
>  	u8 vol_updated;
>  	u8 master_vol;
> @@ -468,6 +473,7 @@ static int scarlett2_get_port_start_num(const struct scarlett2_ports *ports,
>  #define SCARLETT2_USB_GET_METER_LEVELS 0x00001001
>  #define SCARLETT2_USB_GET_MIX 0x00002001
>  #define SCARLETT2_USB_SET_MIX 0x00002002
> +#define SCARLETT2_USB_GET_MUX 0x00003001
>  #define SCARLETT2_USB_SET_MUX 0x00003002
>  #define SCARLETT2_USB_GET_DATA 0x00800000
>  #define SCARLETT2_USB_SET_DATA 0x00800001
> @@ -877,6 +883,94 @@ static u32 scarlett2_mux_src_num_to_id(const struct scarlett2_ports *ports,
>  	return 0;
>  }
>  
> +/* Convert a hardware ID to a port number index */
> +static u32 scarlett2_mux_id_to_num(const struct scarlett2_ports *ports,
> +				   int direction,
> +				   u32 id)
> +{
> +	int port_type;
> +	int port_num = 0;
> +
> +	for (port_type = 0;
> +	     port_type < SCARLETT2_PORT_TYPE_COUNT;
> +	     port_type++) {
> +		struct scarlett2_ports port = ports[port_type];
> +		int count = port.num[direction];
> +
> +		if (id >= port.id && id < port.id + count)
> +			return port_num + id - port.id;
> +		port_num += count;
> +	}
> +
> +	/* Oops */
> +	return -1;
> +}
> +
> +/* Convert one mux entry from the interface and load into private->mux[] */
> +static void scarlett2_usb_populate_mux(struct scarlett2_mixer_data *private,
> +				       u32 mux_entry)
> +{
> +	const struct scarlett2_device_info *info = private->info;
> +	const struct scarlett2_ports *ports = info->ports;
> +
> +	int dst_idx, src_idx;
> +
> +	dst_idx = scarlett2_mux_id_to_num(ports, SCARLETT2_PORT_OUT,
> +					  mux_entry & 0xFFF);
> +	if (dst_idx < 0)
> +		return;
> +
> +	if (dst_idx >= private->num_mux_dsts) {
> +		usb_audio_err(private->mixer->chip,
> +			"BUG: scarlett2_mux_id_to_num(%06x, OUT): %d >= %d",
> +			mux_entry, dst_idx, private->num_mux_dsts);
> +		return;
> +	}
> +
> +	src_idx = scarlett2_mux_id_to_num(ports, SCARLETT2_PORT_IN,
> +					  mux_entry >> 12);
> +	if (src_idx < 0)
> +		return;
> +
> +	if (src_idx >= private->num_mux_srcs) {
> +		usb_audio_err(private->mixer->chip,
> +			"BUG: scarlett2_mux_id_to_num(%06x, IN): %d >= %d",
> +			mux_entry, src_idx, private->num_mux_srcs);
> +		return;
> +	}
> +
> +	private->mux[dst_idx] = src_idx;
> +}
> +
> +/* Send USB message to get mux inputs and then populate private->mux[] */
> +static int scarlett2_usb_get_mux(struct usb_mixer_interface *mixer)
> +{
> +	struct scarlett2_mixer_data *private = mixer->private_data;
> +	int count = private->num_mux_dsts;
> +	int err, i;
> +
> +	struct {
> +		__le16 num;
> +		__le16 count;
> +	} __packed req;
> +
> +	__le32 data[SCARLETT2_MUX_MAX];
> +
> +	req.num = 0;
> +	req.count = cpu_to_le16(count);
> +
> +	err = scarlett2_usb(mixer, SCARLETT2_USB_GET_MUX,
> +			    &req, sizeof(req),
> +			    data, count * sizeof(u32));
> +	if (err < 0)
> +		return err;
> +
> +	for (i = 0; i < count; i++)
> +		scarlett2_usb_populate_mux(private, le32_to_cpu(data[i]));
> +
> +	return 0;
> +}
> +
>  /* Send USB messages to set mux inputs */
>  static int scarlett2_usb_set_mux(struct usb_mixer_interface *mixer)
>  {
> @@ -1783,72 +1877,23 @@ static void scarlett2_private_suspend(struct usb_mixer_interface *mixer)
>  
>  /*** Initialisation ***/
>  
> -static int scarlett2_count_mux_srcs(const struct scarlett2_ports *ports)
> +static void scarlett2_count_mux_io(struct scarlett2_mixer_data *private)
>  {
> -	int port_type, count = 0;
> +	const struct scarlett2_ports *ports = private->info->ports;
> +	int port_type, srcs = 0, dsts = 0;
>  
>  	for (port_type = 0;
>  	     port_type < SCARLETT2_PORT_TYPE_COUNT;
> -	     port_type++)
> -		count += ports[port_type].num[SCARLETT2_PORT_IN];
> -
> -	return count;
> -}
> -
> -/* Default routing connects PCM outputs and inputs to Analogue,
> - * S/PDIF, then ADAT
> - */
> -static void scarlett2_init_routing(u8 *mux,
> -				   const struct scarlett2_ports *ports)
> -{
> -	int i, input_num, input_count, port_type;
> -	int output_num, output_count, port_type_connect_num;
> -
> -	static const int connect_order[] = {
> -		SCARLETT2_PORT_TYPE_ANALOGUE,
> -		SCARLETT2_PORT_TYPE_SPDIF,
> -		SCARLETT2_PORT_TYPE_ADAT,
> -		-1
> -	};
> -
> -	/* Assign PCM inputs (routing outputs) */
> -	output_num = scarlett2_get_port_start_num(ports,
> -						  SCARLETT2_PORT_OUT,
> -						  SCARLETT2_PORT_TYPE_PCM);
> -	output_count = ports[SCARLETT2_PORT_TYPE_PCM].num[SCARLETT2_PORT_OUT];
> -
> -	for (port_type = connect_order[port_type_connect_num = 0];
> -	     port_type >= 0;
> -	     port_type = connect_order[++port_type_connect_num]) {
> -		input_num = scarlett2_get_port_start_num(
> -			ports, SCARLETT2_PORT_IN, port_type);
> -		input_count = ports[port_type].num[SCARLETT2_PORT_IN];
> -		for (i = 0;
> -		     i < input_count && output_count;
> -		     i++, output_count--)
> -			mux[output_num++] = input_num++;
> +	     port_type++) {
> +		srcs += ports[port_type].num[SCARLETT2_PORT_IN];
> +		dsts += ports[port_type].num[SCARLETT2_PORT_OUT_44];
>  	}
>  
> -	/* Assign PCM outputs (routing inputs) */
> -	input_num = scarlett2_get_port_start_num(ports,
> -						 SCARLETT2_PORT_IN,
> -						 SCARLETT2_PORT_TYPE_PCM);
> -	input_count = ports[SCARLETT2_PORT_TYPE_PCM].num[SCARLETT2_PORT_IN];
> -
> -	for (port_type = connect_order[port_type_connect_num = 0];
> -	     port_type >= 0;
> -	     port_type = connect_order[++port_type_connect_num]) {
> -		output_num = scarlett2_get_port_start_num(
> -			ports, SCARLETT2_PORT_OUT, port_type);
> -		output_count = ports[port_type].num[SCARLETT2_PORT_OUT];
> -		for (i = 0;
> -		     i < output_count && input_count;
> -		     i++, input_count--)
> -			mux[output_num++] = input_num++;
> -	}
> +	private->num_mux_srcs = srcs;
> +	private->num_mux_dsts = dsts;
>  }
>  
> -/* Initialise private data, routing, sequence number */
> +/* Initialise private data and sequence number */
>  static int scarlett2_init_private(struct usb_mixer_interface *mixer,
>  				  const struct scarlett2_device_info *info)
>  {
> @@ -1862,16 +1907,13 @@ static int scarlett2_init_private(struct usb_mixer_interface *mixer,
>  	mutex_init(&private->data_mutex);
>  	INIT_DELAYED_WORK(&private->work, scarlett2_config_save_work);
>  	private->info = info;
> -	private->num_mux_srcs = scarlett2_count_mux_srcs(info->ports);
> +	scarlett2_count_mux_io(private);
>  	private->scarlett2_seq = 0;
>  	private->mixer = mixer;
>  	mixer->private_data = private;
>  	mixer->private_free = scarlett2_private_free;
>  	mixer->private_suspend = scarlett2_private_suspend;
>  
> -	/* Setup default routing */
> -	scarlett2_init_routing(private->mux, info->ports);
> -
>  	/* Initialise the sequence number used for the proprietary commands */
>  	return scarlett2_usb(mixer, SCARLETT2_USB_INIT_SEQ, NULL, 0, NULL, 0);
>  }
> @@ -1947,7 +1989,7 @@ static int scarlett2_read_configs(struct usb_mixer_interface *mixer)
>  			return err;
>  	}
>  
> -	return 0;
> +	return scarlett2_usb_get_mux(mixer);
>  }
>  
>  /* Notify on volume change */
> @@ -2055,7 +2097,7 @@ static int snd_scarlett_gen2_controls_create(struct usb_mixer_interface *mixer,
>  {
>  	int err;
>  
> -	/* Initialise private data, routing, sequence number */
> +	/* Initialise private data and sequence number */
>  	err = scarlett2_init_private(mixer, info);
>  	if (err < 0)
>  		return err;

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

* Re: [PATCH 1/2] ALSA: usb-audio: scarlett2: Read mixer volumes at init time
  2021-06-06 14:16 ` [PATCH 1/2] ALSA: usb-audio: scarlett2: Read mixer volumes " Geoffrey D. Bennett
@ 2021-06-07  5:23     ` kernel test robot
  2021-06-07  5:23     ` kernel test robot
  1 sibling, 0 replies; 11+ messages in thread
From: kernel test robot @ 2021-06-07  5:23 UTC (permalink / raw)
  To: Geoffrey D. Bennett, alsa-devel, Takashi Iwai
  Cc: Daniel Sales, Markus Schroetter, kbuild-all, Vladimir Sadovnikov,
	Alex Fellows

[-- Attachment #1: Type: text/plain, Size: 3877 bytes --]

Hi "Geoffrey,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on v5.13-rc4]
[also build test WARNING on next-20210604]
[cannot apply to sound/for-next]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Geoffrey-D-Bennett/ALSA-usb-audio-scarlett2-Read-all-configuration-at-init-time/20210606-222037
base:    8124c8a6b35386f73523d27eacb71b5364a68c4c
config: xtensa-randconfig-s032-20210607 (attached as .config)
compiler: xtensa-linux-gcc (GCC) 9.3.0
reproduce:
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # apt-get install sparse
        # sparse version: v0.6.3-341-g8af24329-dirty
        # https://github.com/0day-ci/linux/commit/4cd436ec424b3564c2dcf9b3b8fd83c8894051f1
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Geoffrey-D-Bennett/ALSA-usb-audio-scarlett2-Read-all-configuration-at-init-time/20210606-222037
        git checkout 4cd436ec424b3564c2dcf9b3b8fd83c8894051f1
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' W=1 ARCH=xtensa 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>


sparse warnings: (new ones prefixed by >>)
>> sound/usb/mixer_scarlett_gen2.c:809:21: sparse: sparse: incorrect type in assignment (different base types) @@     expected restricted __le16 [usertype] mix_num @@     got int mix_num @@
   sound/usb/mixer_scarlett_gen2.c:809:21: sparse:     expected restricted __le16 [usertype] mix_num
   sound/usb/mixer_scarlett_gen2.c:809:21: sparse:     got int mix_num
>> sound/usb/mixer_scarlett_gen2.c:810:19: sparse: sparse: incorrect type in assignment (different base types) @@     expected restricted __le16 [usertype] count @@     got int num_mixer_in @@
   sound/usb/mixer_scarlett_gen2.c:810:19: sparse:     expected restricted __le16 [usertype] count
   sound/usb/mixer_scarlett_gen2.c:810:19: sparse:     got int num_mixer_in

vim +809 sound/usb/mixer_scarlett_gen2.c

   788	
   789	/* Send a USB message to get the volumes for all inputs of one mix
   790	 * and put the values into private->mix[]
   791	 */
   792	static int scarlett2_usb_get_mix(struct usb_mixer_interface *mixer,
   793					 int mix_num)
   794	{
   795		struct scarlett2_mixer_data *private = mixer->private_data;
   796		const struct scarlett2_device_info *info = private->info;
   797	
   798		int num_mixer_in =
   799			info->ports[SCARLETT2_PORT_TYPE_MIX].num[SCARLETT2_PORT_OUT];
   800		int err, i, j, k;
   801	
   802		struct {
   803			__le16 mix_num;
   804			__le16 count;
   805		} __packed req;
   806	
   807		__le16 data[SCARLETT2_INPUT_MIX_MAX];
   808	
 > 809		req.mix_num = mix_num;
 > 810		req.count = num_mixer_in;
   811	
   812		err = scarlett2_usb(mixer, SCARLETT2_USB_GET_MIX,
   813				    &req, sizeof(req),
   814				    data, num_mixer_in * sizeof(u16));
   815		if (err < 0)
   816			return err;
   817	
   818		for (i = 0, j = mix_num * num_mixer_in; i < num_mixer_in; i++, j++) {
   819			u16 mixer_value = le16_to_cpu(data[i]);
   820	
   821			for (k = 0; k < SCARLETT2_MIXER_VALUE_COUNT; k++)
   822				if (scarlett2_mixer_values[k] >= mixer_value)
   823					break;
   824			if (k == SCARLETT2_MIXER_VALUE_COUNT)
   825				k = SCARLETT2_MIXER_MAX_VALUE;
   826			private->mix[j] = k;
   827		}
   828	
   829		return 0;
   830	}
   831	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 28418 bytes --]

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

* Re: [PATCH 1/2] ALSA: usb-audio: scarlett2: Read mixer volumes at init time
@ 2021-06-07  5:23     ` kernel test robot
  0 siblings, 0 replies; 11+ messages in thread
From: kernel test robot @ 2021-06-07  5:23 UTC (permalink / raw)
  To: kbuild-all

[-- Attachment #1: Type: text/plain, Size: 3968 bytes --]

Hi "Geoffrey,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on v5.13-rc4]
[also build test WARNING on next-20210604]
[cannot apply to sound/for-next]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Geoffrey-D-Bennett/ALSA-usb-audio-scarlett2-Read-all-configuration-at-init-time/20210606-222037
base:    8124c8a6b35386f73523d27eacb71b5364a68c4c
config: xtensa-randconfig-s032-20210607 (attached as .config)
compiler: xtensa-linux-gcc (GCC) 9.3.0
reproduce:
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # apt-get install sparse
        # sparse version: v0.6.3-341-g8af24329-dirty
        # https://github.com/0day-ci/linux/commit/4cd436ec424b3564c2dcf9b3b8fd83c8894051f1
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Geoffrey-D-Bennett/ALSA-usb-audio-scarlett2-Read-all-configuration-at-init-time/20210606-222037
        git checkout 4cd436ec424b3564c2dcf9b3b8fd83c8894051f1
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' W=1 ARCH=xtensa 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>


sparse warnings: (new ones prefixed by >>)
>> sound/usb/mixer_scarlett_gen2.c:809:21: sparse: sparse: incorrect type in assignment (different base types) @@     expected restricted __le16 [usertype] mix_num @@     got int mix_num @@
   sound/usb/mixer_scarlett_gen2.c:809:21: sparse:     expected restricted __le16 [usertype] mix_num
   sound/usb/mixer_scarlett_gen2.c:809:21: sparse:     got int mix_num
>> sound/usb/mixer_scarlett_gen2.c:810:19: sparse: sparse: incorrect type in assignment (different base types) @@     expected restricted __le16 [usertype] count @@     got int num_mixer_in @@
   sound/usb/mixer_scarlett_gen2.c:810:19: sparse:     expected restricted __le16 [usertype] count
   sound/usb/mixer_scarlett_gen2.c:810:19: sparse:     got int num_mixer_in

vim +809 sound/usb/mixer_scarlett_gen2.c

   788	
   789	/* Send a USB message to get the volumes for all inputs of one mix
   790	 * and put the values into private->mix[]
   791	 */
   792	static int scarlett2_usb_get_mix(struct usb_mixer_interface *mixer,
   793					 int mix_num)
   794	{
   795		struct scarlett2_mixer_data *private = mixer->private_data;
   796		const struct scarlett2_device_info *info = private->info;
   797	
   798		int num_mixer_in =
   799			info->ports[SCARLETT2_PORT_TYPE_MIX].num[SCARLETT2_PORT_OUT];
   800		int err, i, j, k;
   801	
   802		struct {
   803			__le16 mix_num;
   804			__le16 count;
   805		} __packed req;
   806	
   807		__le16 data[SCARLETT2_INPUT_MIX_MAX];
   808	
 > 809		req.mix_num = mix_num;
 > 810		req.count = num_mixer_in;
   811	
   812		err = scarlett2_usb(mixer, SCARLETT2_USB_GET_MIX,
   813				    &req, sizeof(req),
   814				    data, num_mixer_in * sizeof(u16));
   815		if (err < 0)
   816			return err;
   817	
   818		for (i = 0, j = mix_num * num_mixer_in; i < num_mixer_in; i++, j++) {
   819			u16 mixer_value = le16_to_cpu(data[i]);
   820	
   821			for (k = 0; k < SCARLETT2_MIXER_VALUE_COUNT; k++)
   822				if (scarlett2_mixer_values[k] >= mixer_value)
   823					break;
   824			if (k == SCARLETT2_MIXER_VALUE_COUNT)
   825				k = SCARLETT2_MIXER_MAX_VALUE;
   826			private->mix[j] = k;
   827		}
   828	
   829		return 0;
   830	}
   831	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org

[-- Attachment #2: config.gz --]
[-- Type: application/gzip, Size: 28418 bytes --]

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

* Re: [PATCH 0/2] ALSA: usb-audio: scarlett2: Read all configuration at init time
  2021-06-06 14:16 [PATCH 0/2] ALSA: usb-audio: scarlett2: Read all configuration at init time Geoffrey D. Bennett
  2021-06-06 14:16 ` [PATCH 1/2] ALSA: usb-audio: scarlett2: Read mixer volumes " Geoffrey D. Bennett
  2021-06-06 14:17 ` [PATCH 2/2] ALSA: usb-audio: scarlett2: Read mux " Geoffrey D. Bennett
@ 2021-06-07  7:23 ` Takashi Iwai
       [not found]   ` <3c7a458a-a5cd-08e4-a462-293c5bf633ec@gmail.com>
  2021-06-07 19:51   ` Geoffrey D. Bennett
  2 siblings, 2 replies; 11+ messages in thread
From: Takashi Iwai @ 2021-06-07  7:23 UTC (permalink / raw)
  To: Geoffrey D. Bennett
  Cc: Daniel Sales, alsa-devel, Vladimir Sadovnikov, Markus Schroetter,
	Alex Fellows

On Sun, 06 Jun 2021 16:16:44 +0200,
Geoffrey D. Bennett wrote:
> 
> These two patches add support for reading the mixer volumes and mux
> configuration from the hardware when the driver is initialising.
> 
> Previously the ALSA volume controls were initialised to zero and the
> mux configuration set to a fixed default instead of being initialised
> to match the hardware state.
> 
> The ALSA controls for the Scarlett Gen 2 interfaces should now always
> be in sync with the hardware. Thanks to Vladimir Sadovnikov for
> figuring out how to do this.
> 
> Takashi, if these pass your review, I believe that they are
> appropriate for:
> #Cc: stable@vger.kernel.org

Well, in general, having a proper fixed value for the initial mixer
value is the right thing, which is a part of the driver's role.
Though, in snd-usb-audio, we don't set up the initial values just
because of laziness; since the topology in USB audio is variable per
device and often hard to parse correctly, it's difficult to determine
the suitable initial values, hence we leave untouched.  So, in that
sense, setting the zero isn't wrong, rather safer, per se.

However, Scarlett 2 seems to want to be different; it has already some
initialization code to read the existing configs.  So this change
sounds more or less acceptable.  But it's questionable whether it's
really for stable as a "fix".

In anyway, please fix the bug ktest bot spotted, the missing endian
conversions and resubmit.


thanks,

Takashi

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

* Re: [PATCH 0/2] ALSA: usb-audio: scarlett2: Read all configuration at init time
       [not found]   ` <3c7a458a-a5cd-08e4-a462-293c5bf633ec@gmail.com>
@ 2021-06-07 15:12     ` Takashi Iwai
  2021-06-07 17:18       ` Markus Schroetter
  0 siblings, 1 reply; 11+ messages in thread
From: Takashi Iwai @ 2021-06-07 15:12 UTC (permalink / raw)
  To: Vladimir Sadovnikov
  Cc: Daniel Sales, alsa-devel, Geoffrey D. Bennett, Markus Schroetter,
	Alex Fellows

On Mon, 07 Jun 2021 17:00:10 +0200,
Vladimir Sadovnikov wrote:
> 
> Hello!
> 
> I would like to say some words from my side.
> 
> The Scarlett device (especially 18i20) is pretty complicated device
> and holds a lot of settings in it's internal
> configuration area (hardware and software).
> 
> So this is not the only patch which will configure the driver in proper way.
> Since the device stores it's internal state (and that's good for power
> safety and mobility), ideally, we should get
> the almost fully compatible mixer settings with the original Focusrite
> Control Software.
> 
> The huge amount of job I've already done i my fork of Geoffrey's driver:
> https://github.com/sadko4u/focusrite-scarlett-backports/blob/master/prod-drv/mixer_scarlett_gen2.c
> 
> So we're planning to work on integrating our changes into the common
> patch sets and will submit changes here.

Sure, I don't mean against the patches, this looks like an acceptable
approach.  So don't worry, I'd take the patches once when the fixed
version is submitted.

However, from the system design POV, all those configurations should
be a software issue, and ideally we shouldn't  rely on the hardware
preset state which has been done *somehow* -- it may allow malfunction
easily.  One thing I've learned over years is that you can never trust
hardware :)


Takashi

> 
> Best,
> Vladimir
> 
> 07.06.2021 10:23, Takashi Iwai пишет:
> > On Sun, 06 Jun 2021 16:16:44 +0200,
> > Geoffrey D. Bennett wrote:
> >> These two patches add support for reading the mixer volumes and mux
> >> configuration from the hardware when the driver is initialising.
> >>
> >> Previously the ALSA volume controls were initialised to zero and the
> >> mux configuration set to a fixed default instead of being initialised
> >> to match the hardware state.
> >>
> >> The ALSA controls for the Scarlett Gen 2 interfaces should now always
> >> be in sync with the hardware. Thanks to Vladimir Sadovnikov for
> >> figuring out how to do this.
> >>
> >> Takashi, if these pass your review, I believe that they are
> >> appropriate for:
> >> #Cc: stable@vger.kernel.org
> > Well, in general, having a proper fixed value for the initial mixer
> > value is the right thing, which is a part of the driver's role.
> > Though, in snd-usb-audio, we don't set up the initial values just
> > because of laziness; since the topology in USB audio is variable per
> > device and often hard to parse correctly, it's difficult to determine
> > the suitable initial values, hence we leave untouched.  So, in that
> > sense, setting the zero isn't wrong, rather safer, per se.
> >
> > However, Scarlett 2 seems to want to be different; it has already some
> > initialization code to read the existing configs.  So this change
> > sounds more or less acceptable.  But it's questionable whether it's
> > really for stable as a "fix".
> >
> > In anyway, please fix the bug ktest bot spotted, the missing endian
> > conversions and resubmit.
> >
> >
> > thanks,
> >
> > Takashi
> 
> 

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

* Re: [PATCH 0/2] ALSA: usb-audio: scarlett2: Read all configuration at init time
  2021-06-07 15:12     ` Takashi Iwai
@ 2021-06-07 17:18       ` Markus Schroetter
  0 siblings, 0 replies; 11+ messages in thread
From: Markus Schroetter @ 2021-06-07 17:18 UTC (permalink / raw)
  To: Takashi Iwai, Vladimir Sadovnikov
  Cc: Daniel Sales, alsa-devel, Geoffrey D. Bennett, Alex Fellows

Hello all,

if I may add to this; I agree with Daniel here. Geoffreys proposed
changes are already a big improvement to the usability. They avoid a lot
of confusion, especially for new users, caused by the hardware being out
of sync with alsamixer; and also helping with identifying the changes
that Windows did to the configuration from what I can tell.
Additionally, it makes it easier to just adjust the current
configuration after a reboot. Rather than having to either start from
scratch or work from restoring an already stored configuration.

Since I think it'd be an improvement for most users, I'd appreciate it
if these changes could be integrated until a better solution is available.

Best Regards,
Markus

On 07.06.21 17:12, Takashi Iwai wrote:
> On Mon, 07 Jun 2021 17:00:10 +0200,
> Vladimir Sadovnikov wrote:
>> Hello!
>>
>> I would like to say some words from my side.
>>
>> The Scarlett device (especially 18i20) is pretty complicated device
>> and holds a lot of settings in it's internal
>> configuration area (hardware and software).
>>
>> So this is not the only patch which will configure the driver in proper way.
>> Since the device stores it's internal state (and that's good for power
>> safety and mobility), ideally, we should get
>> the almost fully compatible mixer settings with the original Focusrite
>> Control Software.
>>
>> The huge amount of job I've already done i my fork of Geoffrey's driver:
>> https://github.com/sadko4u/focusrite-scarlett-backports/blob/master/prod-drv/mixer_scarlett_gen2.c
>>
>> So we're planning to work on integrating our changes into the common
>> patch sets and will submit changes here.
> Sure, I don't mean against the patches, this looks like an acceptable
> approach.  So don't worry, I'd take the patches once when the fixed
> version is submitted.
>
> However, from the system design POV, all those configurations should
> be a software issue, and ideally we shouldn't  rely on the hardware
> preset state which has been done *somehow* -- it may allow malfunction
> easily.  One thing I've learned over years is that you can never trust
> hardware :)
>
>
> Takashi
>
>> Best,
>> Vladimir
>>
>> 07.06.2021 10:23, Takashi Iwai пишет:
>>> On Sun, 06 Jun 2021 16:16:44 +0200,
>>> Geoffrey D. Bennett wrote:
>>>> These two patches add support for reading the mixer volumes and mux
>>>> configuration from the hardware when the driver is initialising.
>>>>
>>>> Previously the ALSA volume controls were initialised to zero and the
>>>> mux configuration set to a fixed default instead of being initialised
>>>> to match the hardware state.
>>>>
>>>> The ALSA controls for the Scarlett Gen 2 interfaces should now always
>>>> be in sync with the hardware. Thanks to Vladimir Sadovnikov for
>>>> figuring out how to do this.
>>>>
>>>> Takashi, if these pass your review, I believe that they are
>>>> appropriate for:
>>>> #Cc: stable@vger.kernel.org
>>> Well, in general, having a proper fixed value for the initial mixer
>>> value is the right thing, which is a part of the driver's role.
>>> Though, in snd-usb-audio, we don't set up the initial values just
>>> because of laziness; since the topology in USB audio is variable per
>>> device and often hard to parse correctly, it's difficult to determine
>>> the suitable initial values, hence we leave untouched.  So, in that
>>> sense, setting the zero isn't wrong, rather safer, per se.
>>>
>>> However, Scarlett 2 seems to want to be different; it has already some
>>> initialization code to read the existing configs.  So this change
>>> sounds more or less acceptable.  But it's questionable whether it's
>>> really for stable as a "fix".
>>>
>>> In anyway, please fix the bug ktest bot spotted, the missing endian
>>> conversions and resubmit.
>>>
>>>
>>> thanks,
>>>
>>> Takashi
>>

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

* Re: [PATCH 0/2] ALSA: usb-audio: scarlett2: Read all configuration at init time
  2021-06-07  7:23 ` [PATCH 0/2] ALSA: usb-audio: scarlett2: Read all configuration " Takashi Iwai
       [not found]   ` <3c7a458a-a5cd-08e4-a462-293c5bf633ec@gmail.com>
@ 2021-06-07 19:51   ` Geoffrey D. Bennett
  1 sibling, 0 replies; 11+ messages in thread
From: Geoffrey D. Bennett @ 2021-06-07 19:51 UTC (permalink / raw)
  To: Takashi Iwai
  Cc: Daniel Sales, alsa-devel, Vladimir Sadovnikov, Markus Schroetter,
	Alex Fellows

On Mon, Jun 07, 2021 at 09:23:34AM +0200, Takashi Iwai wrote:
> On Sun, 06 Jun 2021 16:16:44 +0200,
> Geoffrey D. Bennett wrote:
> > 
> > These two patches add support for reading the mixer volumes and mux
> > configuration from the hardware when the driver is initialising.
> > 
> > Previously the ALSA volume controls were initialised to zero and the
> > mux configuration set to a fixed default instead of being initialised
> > to match the hardware state.
> > 
> > The ALSA controls for the Scarlett Gen 2 interfaces should now always
> > be in sync with the hardware. Thanks to Vladimir Sadovnikov for
> > figuring out how to do this.
> > 
> > Takashi, if these pass your review, I believe that they are
> > appropriate for:
> > #Cc: stable@vger.kernel.org
> 
> Well, in general, having a proper fixed value for the initial mixer
> value is the right thing, which is a part of the driver's role.
> Though, in snd-usb-audio, we don't set up the initial values just
> because of laziness; since the topology in USB audio is variable per
> device and often hard to parse correctly, it's difficult to determine
> the suitable initial values, hence we leave untouched.  So, in that
> sense, setting the zero isn't wrong, rather safer, per se.
> 
> However, Scarlett 2 seems to want to be different; it has already some
> initialization code to read the existing configs.  So this change
> sounds more or less acceptable.  But it's questionable whether it's
> really for stable as a "fix".

For the Scarlett devices, the sensible (but not all good)
initialisation options are:

1. Don't load configuration from hardware so the ALSA controls show
default values not in sync with hardware. This is a bad user
experience.

2. Reset hardware configuration to hard-coded defaults so ALSA
controls will be in sync with hardware. This is a really bad user
experience as it is common for the device to be configured using the
proprietary vendor-supplied software and then connected to Linux with
the expectation that the configuration is kept.

3. Load configuration from hardware so ALSA controls are in sync with
hardware. This is a good user experience.

Before these two patches, it was option (1) for the mix/mux controls
and option (3) for the remainder of the controls. I would call this
definitely not sensible behaviour.

I got many queries as to the apparently strange workings of the driver
due to this; certainly many users besides myself considered the
original behaviour a bug so it does fit the rule "It must fix a real
bug that bothers people" from
Documentation/process/stable-kernel-rules.rst

You might consider that it does not meet the "It must be obviously
correct and tested" rule though, and I could agree with that. Perhaps
leave it out from stable for now and revisit later after we get more
test results? Is there a particular amount of time or number of test
success reports that you would consider sufficient?

> In anyway, please fix the bug ktest bot spotted, the missing endian
> conversions and resubmit.

Thanks, I have resubmitted.

Regards,
Geoffrey.

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

end of thread, other threads:[~2021-06-07 19:52 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-06-06 14:16 [PATCH 0/2] ALSA: usb-audio: scarlett2: Read all configuration at init time Geoffrey D. Bennett
2021-06-06 14:16 ` [PATCH 1/2] ALSA: usb-audio: scarlett2: Read mixer volumes " Geoffrey D. Bennett
2021-06-06 14:32   ` Markus
2021-06-07  5:23   ` kernel test robot
2021-06-07  5:23     ` kernel test robot
2021-06-06 14:17 ` [PATCH 2/2] ALSA: usb-audio: scarlett2: Read mux " Geoffrey D. Bennett
2021-06-06 14:33   ` Markus
2021-06-07  7:23 ` [PATCH 0/2] ALSA: usb-audio: scarlett2: Read all configuration " Takashi Iwai
     [not found]   ` <3c7a458a-a5cd-08e4-a462-293c5bf633ec@gmail.com>
2021-06-07 15:12     ` Takashi Iwai
2021-06-07 17:18       ` Markus Schroetter
2021-06-07 19:51   ` Geoffrey D. Bennett

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.