summaryrefslogtreecommitdiff
path: root/sound/usb
diff options
context:
space:
mode:
authorGeoffrey D. Bennett <g@b4.vu>2023-12-27 04:36:29 +1030
committerTakashi Iwai <tiwai@suse.de>2023-12-29 15:52:12 +0100
commit4fa07ff7b625e5578dd974d5c43d701cb3624d84 (patch)
treedbb4dac38364fe38a7db51d0ea907244f704f05b /sound/usb
parentdd57b1213ab60ec9ad603507bd25ed069f9a6b61 (diff)
ALSA: scarlett2: Add support for Gen 4 style parameters
Writing Scarlett Gen 4 parameters differs from Gen 2 and Gen 3: - the values are written into a shared write location - the values are only byte-sized - the read locations now extend beyond 0xFF - a separate NVRAM save step is no longer required This patch implements that alternate write style, triggered by setting the config item size field to zero. The write address is specified through a new config set field gen4_write_addr. Signed-off-by: Geoffrey D. Bennett <g@b4.vu> Signed-off-by: Takashi Iwai <tiwai@suse.de> Link: https://lore.kernel.org/r/1624e6d8a0c629c3bdfe53825b16e8b589724fc4.1703612638.git.g@b4.vu
Diffstat (limited to 'sound/usb')
-rw-r--r--sound/usb/mixer_scarlett2.c53
1 files changed, 48 insertions, 5 deletions
diff --git a/sound/usb/mixer_scarlett2.c b/sound/usb/mixer_scarlett2.c
index b881881124a6..b2555236d113 100644
--- a/sound/usb/mixer_scarlett2.c
+++ b/sound/usb/mixer_scarlett2.c
@@ -320,16 +320,21 @@ enum {
};
/* Location, size, and activation command number for the configuration
- * parameters. Size is in bits and may be 1, 8, or 16.
+ * parameters. Size is in bits and may be 0, 1, 8, or 16.
+ *
+ * A size of 0 indicates that the parameter is a byte-sized Scarlett
+ * Gen 4 configuration which is written through the gen4_write_addr
+ * location (but still read through the given offset location).
*/
struct scarlett2_config {
- u8 offset;
+ u16 offset;
u8 size;
u8 activate;
};
struct scarlett2_config_set {
const struct scarlett2_notification *notifications;
+ u16 gen4_write_addr;
const struct scarlett2_config items[SCARLETT2_CONFIG_COUNT];
};
@@ -1612,9 +1617,12 @@ static int scarlett2_usb_get_config(
if (!config_item->offset)
return -EFAULT;
+ /* Gen 4 style parameters are always 1 byte */
+ size = config_item->size ? config_item->size : 8;
+
/* For byte-sized parameters, retrieve directly into buf */
- if (config_item->size >= 8) {
- size = config_item->size / 8 * count;
+ if (size >= 8) {
+ size = size / 8 * count;
err = scarlett2_usb_get(mixer, config_item->offset, buf, size);
if (err < 0)
return err;
@@ -1684,8 +1692,9 @@ static int scarlett2_usb_set_config(
int config_item_num, int index, int value)
{
struct scarlett2_data *private = mixer->private_data;
+ const struct scarlett2_config_set *config_set = private->config_set;
const struct scarlett2_config *config_item =
- &private->config_set->items[config_item_num];
+ &config_set->items[config_item_num];
int offset, size;
int err;
@@ -1695,6 +1704,36 @@ static int scarlett2_usb_set_config(
if (!config_item->offset)
return -EFAULT;
+ /* Gen 4 style writes are selected with size = 0;
+ * these are only byte-sized values written through a shared
+ * location, different to the read address
+ */
+ if (!config_item->size) {
+ if (!config_set->gen4_write_addr)
+ return -EFAULT;
+
+ /* Place index in gen4_write_addr + 1 */
+ err = scarlett2_usb_set_data(
+ mixer, config_set->gen4_write_addr + 1, 1, index);
+ if (err < 0)
+ return err;
+
+ /* Place value in gen4_write_addr */
+ err = scarlett2_usb_set_data(
+ mixer, config_set->gen4_write_addr, 1, value);
+ if (err < 0)
+ return err;
+
+ /* Request the interface do the write */
+ return scarlett2_usb_activate_config(
+ mixer, config_item->activate);
+ }
+
+ /* Not-Gen 4 style needs NVRAM save, supports
+ * bit-modification, and writing is done to the same place
+ * that the value can be read from
+ */
+
/* Cancel any pending NVRAM save */
cancel_delayed_work_sync(&private->work);
@@ -1736,6 +1775,10 @@ static int scarlett2_usb_set_config(
if (err < 0)
return err;
+ /* Gen 2 style writes to Gen 4 devices don't need saving */
+ if (config_set->gen4_write_addr)
+ return 0;
+
/* Schedule the change to be written to NVRAM */
if (config_item->activate != SCARLETT2_USB_CONFIG_SAVE)
schedule_delayed_work(&private->work, msecs_to_jiffies(2000));