Commit 34101a0f authored by Geoffrey D. Bennett's avatar Geoffrey D. Bennett Committed by Takashi Iwai

ALSA: scarlett2: Retrieve useful flash segment numbers

Call SCARLETT2_USB_INFO_FLASH and SCARLETT2_USB_INFO_SEGMENT to find
the App_Settings and App_Upgrade flash segment numbers, and store them
in the scarlett2_data struct. These will be used later to implement
reset to factory defaults and firmware upgrade functions.
Signed-off-by: default avatarGeoffrey D. Bennett <g@b4.vu>
Link: https://lore.kernel.org/r/70f0108a9cf99b69f7aa920c4bcdb0cf4bf3da98.1703001053.git.g@b4.vuSigned-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent 103c23cc
......@@ -190,6 +190,11 @@ static const u16 scarlett2_mixer_values[SCARLETT2_MIXER_VALUE_COUNT] = {
16345
};
/* Flash segments that we may manipulate */
#define SCARLETT2_SEGMENT_ID_SETTINGS 0
#define SCARLETT2_SEGMENT_ID_FIRMWARE 1
#define SCARLETT2_SEGMENT_ID_COUNT 2
/* Maximum number of analogue outputs */
#define SCARLETT2_ANALOGUE_MAX 10
......@@ -429,6 +434,8 @@ struct scarlett2_data {
int num_mux_srcs;
int num_mux_dsts;
u32 firmware_version;
u8 flash_segment_nums[SCARLETT2_SEGMENT_ID_COUNT];
u8 flash_segment_blocks[SCARLETT2_SEGMENT_ID_COUNT];
u16 scarlett2_seq;
u8 sync_updated;
u8 vol_updated;
......@@ -1160,6 +1167,13 @@ static int scarlett2_get_port_start_num(
#define SCARLETT2_USB_VOLUME_STATUS_OFFSET 0x31
#define SCARLETT2_USB_METER_LEVELS_GET_MAGIC 1
#define SCARLETT2_FLASH_BLOCK_SIZE 4096
#define SCARLETT2_SEGMENT_NUM_MIN 1
#define SCARLETT2_SEGMENT_NUM_MAX 4
#define SCARLETT2_SEGMENT_SETTINGS_NAME "App_Settings"
#define SCARLETT2_SEGMENT_FIRMWARE_NAME "App_Upgrade"
/* volume status is read together (matches scarlett2_config_items[1]) */
struct scarlett2_usb_volume_status {
/* dim/mute buttons */
......@@ -4202,6 +4216,90 @@ static int scarlett2_usb_init(struct usb_mixer_interface *mixer)
return 0;
}
/* Get the flash segment numbers for the App_Settings and App_Upgrade
* segments and put them in the private data
*/
static int scarlett2_get_flash_segment_nums(struct usb_mixer_interface *mixer)
{
struct scarlett2_data *private = mixer->private_data;
int err, count, i;
struct {
__le32 size;
__le32 count;
u8 unknown[8];
} __packed flash_info;
struct {
__le32 size;
__le32 flags;
char name[16];
} __packed segment_info;
err = scarlett2_usb(mixer, SCARLETT2_USB_INFO_FLASH,
NULL, 0,
&flash_info, sizeof(flash_info));
if (err < 0)
return err;
count = le32_to_cpu(flash_info.count);
/* sanity check count */
if (count < SCARLETT2_SEGMENT_NUM_MIN ||
count > SCARLETT2_SEGMENT_NUM_MAX + 1) {
usb_audio_err(mixer->chip,
"invalid flash segment count: %d\n", count);
return -EINVAL;
}
for (i = 0; i < count; i++) {
__le32 segment_num_req = cpu_to_le32(i);
int flash_segment_id;
err = scarlett2_usb(mixer, SCARLETT2_USB_INFO_SEGMENT,
&segment_num_req, sizeof(segment_num_req),
&segment_info, sizeof(segment_info));
if (err < 0) {
usb_audio_err(mixer->chip,
"failed to get flash segment info %d: %d\n",
i, err);
return err;
}
if (!strncmp(segment_info.name,
SCARLETT2_SEGMENT_SETTINGS_NAME, 16))
flash_segment_id = SCARLETT2_SEGMENT_ID_SETTINGS;
else if (!strncmp(segment_info.name,
SCARLETT2_SEGMENT_FIRMWARE_NAME, 16))
flash_segment_id = SCARLETT2_SEGMENT_ID_FIRMWARE;
else
continue;
private->flash_segment_nums[flash_segment_id] = i;
private->flash_segment_blocks[flash_segment_id] =
le32_to_cpu(segment_info.size) /
SCARLETT2_FLASH_BLOCK_SIZE;
}
/* segment 0 is App_Gold and we never want to touch that, so
* use 0 as the "not-found" value
*/
if (!private->flash_segment_nums[SCARLETT2_SEGMENT_ID_SETTINGS]) {
usb_audio_err(mixer->chip,
"failed to find flash segment %s\n",
SCARLETT2_SEGMENT_SETTINGS_NAME);
return -EINVAL;
}
if (!private->flash_segment_nums[SCARLETT2_SEGMENT_ID_FIRMWARE]) {
usb_audio_err(mixer->chip,
"failed to find flash segment %s\n",
SCARLETT2_SEGMENT_FIRMWARE_NAME);
return -EINVAL;
}
return 0;
}
/* Read configuration from the interface on start */
static int scarlett2_read_configs(struct usb_mixer_interface *mixer)
{
......@@ -4517,6 +4615,11 @@ static int snd_scarlett2_controls_create(
if (err < 0)
return err;
/* Get the upgrade & settings flash segment numbers */
err = scarlett2_get_flash_segment_nums(mixer);
if (err < 0)
return err;
/* Add firmware version control */
err = scarlett2_add_firmware_version_ctl(mixer);
if (err < 0)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment