mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-06 01:59:54 -04:00
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: Geoffrey D. Bennett <g@b4.vu> Link: https://lore.kernel.org/r/70f0108a9cf99b69f7aa920c4bcdb0cf4bf3da98.1703001053.git.g@b4.vu Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
committed by
Takashi Iwai
parent
103c23ccac
commit
34101a0fb1
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user