summaryrefslogtreecommitdiff
path: root/sound/usb/mixer_scarlett2.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/usb/mixer_scarlett2.c')
-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));