[PATCH 1/2] ALSA: usb-audio: scarlett2: Read mixer volumes at init time

Markus project.m.schroetter at gmail.com
Sun Jun 6 16:32:24 CEST 2021


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 at gmail.com>
> Signed-off-by: Geoffrey D. Bennett <g at b4.vu>

Tested-by: Markus Schroetter <project.m.schroetter at 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;
>  }
>  


More information about the Alsa-devel mailing list