Add driver type detection
This commit is contained in:
79
src/alsa.c
79
src/alsa.c
@@ -5,10 +5,15 @@
|
|||||||
#include <alsa/sound/uapi/tlv.h>
|
#include <alsa/sound/uapi/tlv.h>
|
||||||
|
|
||||||
#include "alsa.h"
|
#include "alsa.h"
|
||||||
|
#include "scarlett2.h"
|
||||||
#include "scarlett2-firmware.h"
|
#include "scarlett2-firmware.h"
|
||||||
|
#include "scarlett2-ioctls.h"
|
||||||
#include "stringhelper.h"
|
#include "stringhelper.h"
|
||||||
#include "window-iface.h"
|
#include "window-iface.h"
|
||||||
|
|
||||||
|
#define MAJOR_HWDEP_VERSION_SCARLETT2 1
|
||||||
|
#define MAJOR_HWDEP_VERSION_FCP 2
|
||||||
|
|
||||||
#define MAX_TLV_RANGE_SIZE 1024
|
#define MAX_TLV_RANGE_SIZE 1024
|
||||||
|
|
||||||
// TLV type for channel labels
|
// TLV type for channel labels
|
||||||
@@ -1067,7 +1072,81 @@ static void alsa_get_serial_number(struct alsa_card *card) {
|
|||||||
card->serial = strdup(serial);
|
card->serial = strdup(serial);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// return true if the Firmware Version control exists and is writable
|
||||||
|
// and locked (i.e. the FCP server is running)
|
||||||
|
static int check_firmware_version_locked(struct alsa_card *card) {
|
||||||
|
snd_ctl_elem_id_t *id;
|
||||||
|
snd_ctl_elem_info_t *info;
|
||||||
|
|
||||||
|
snd_ctl_elem_id_alloca(&id);
|
||||||
|
snd_ctl_elem_info_alloca(&info);
|
||||||
|
|
||||||
|
// look for the Firmware Version control
|
||||||
|
snd_ctl_elem_id_set_interface(id, SND_CTL_ELEM_IFACE_CARD);
|
||||||
|
snd_ctl_elem_id_set_name(id, "Firmware Version");
|
||||||
|
snd_ctl_elem_info_set_id(info, id);
|
||||||
|
|
||||||
|
// no Firmware Version control found
|
||||||
|
int err = snd_ctl_elem_info(card->handle, info);
|
||||||
|
if (err < 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return snd_ctl_elem_info_is_writable(info) &&
|
||||||
|
snd_ctl_elem_info_is_locked(info);
|
||||||
|
}
|
||||||
|
|
||||||
|
// return the driver type for this card
|
||||||
|
// DRIVER_TYPE_NONE: no driver
|
||||||
|
// DRIVER_TYPE_HWDEP: Scarlett2 driver
|
||||||
|
// DRIVER_TYPE_SOCKET: FCP driver
|
||||||
|
// DRIVER_TYPE_SOCKET_UNINIT: FCP driver, but not initialised
|
||||||
|
static int get_driver_type(struct alsa_card *card) {
|
||||||
|
snd_hwdep_t *hwdep;
|
||||||
|
|
||||||
|
int err = scarlett2_open_card(card->device, &hwdep);
|
||||||
|
|
||||||
|
// no hwdep for this card - driver type none
|
||||||
|
if (err == -ENOENT)
|
||||||
|
return DRIVER_TYPE_NONE;
|
||||||
|
|
||||||
|
// if we get EPERM, it's FCP but no server running
|
||||||
|
if (err == -EPERM)
|
||||||
|
return DRIVER_TYPE_SOCKET_UNINIT;
|
||||||
|
|
||||||
|
// if we get EBUSY, it's FCP
|
||||||
|
if (err == -EBUSY)
|
||||||
|
// fcp-server locks the Firmware Version control when it has
|
||||||
|
// finished starting up
|
||||||
|
return check_firmware_version_locked(card) ?
|
||||||
|
DRIVER_TYPE_SOCKET : DRIVER_TYPE_SOCKET_UNINIT;
|
||||||
|
|
||||||
|
// failed to open hwdep
|
||||||
|
if (err < 0)
|
||||||
|
return DRIVER_TYPE_NONE;
|
||||||
|
|
||||||
|
// we can open hwdep, so now check the protocol version
|
||||||
|
int ver = scarlett2_get_protocol_version(hwdep);
|
||||||
|
scarlett2_close(hwdep);
|
||||||
|
|
||||||
|
// failed to get protocol version
|
||||||
|
if (ver < 0)
|
||||||
|
return DRIVER_TYPE_NONE;
|
||||||
|
|
||||||
|
// hwdep protocol version 1.x.x is Scarlett2 driver
|
||||||
|
if (SCARLETT2_HWDEP_VERSION_MAJOR(ver) == MAJOR_HWDEP_VERSION_SCARLETT2)
|
||||||
|
return DRIVER_TYPE_HWDEP;
|
||||||
|
|
||||||
|
// hwdep protocol version 2.x.x is FCP driver (but not initialised,
|
||||||
|
// because we were able to open the hwdep)
|
||||||
|
if (SCARLETT2_HWDEP_VERSION_MAJOR(ver) == MAJOR_HWDEP_VERSION_FCP)
|
||||||
|
return DRIVER_TYPE_SOCKET_UNINIT;
|
||||||
|
|
||||||
|
return DRIVER_TYPE_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
static void card_init(struct alsa_card *card) {
|
static void card_init(struct alsa_card *card) {
|
||||||
|
card->driver_type = get_driver_type(card);
|
||||||
|
|
||||||
alsa_get_elem_list(card);
|
alsa_get_elem_list(card);
|
||||||
alsa_set_lr_nums(card);
|
alsa_set_lr_nums(card);
|
||||||
alsa_get_routing_controls(card);
|
alsa_get_routing_controls(card);
|
||||||
|
|||||||
14
src/alsa.h
14
src/alsa.h
@@ -41,6 +41,19 @@ enum {
|
|||||||
HW_TYPE_COUNT
|
HW_TYPE_COUNT
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// driver types
|
||||||
|
// NONE is 1st Gen or Scarlett2 before hwdep support was added
|
||||||
|
// (no erase config or firmware update support)
|
||||||
|
// HWDEP is the Scarlett2 driver after hwdep support was added
|
||||||
|
// SOCKET is the FCP driver
|
||||||
|
enum {
|
||||||
|
DRIVER_TYPE_NONE,
|
||||||
|
DRIVER_TYPE_HWDEP,
|
||||||
|
DRIVER_TYPE_SOCKET,
|
||||||
|
DRIVER_TYPE_SOCKET_UNINIT,
|
||||||
|
DRIVER_TYPE_COUNT
|
||||||
|
};
|
||||||
|
|
||||||
// names for the hardware types
|
// names for the hardware types
|
||||||
extern const char *hw_type_names[HW_TYPE_COUNT];
|
extern const char *hw_type_names[HW_TYPE_COUNT];
|
||||||
|
|
||||||
@@ -162,6 +175,7 @@ struct alsa_card {
|
|||||||
uint32_t pid;
|
uint32_t pid;
|
||||||
char *serial;
|
char *serial;
|
||||||
char *name;
|
char *name;
|
||||||
|
int driver_type;
|
||||||
char *fcp_socket;
|
char *fcp_socket;
|
||||||
int best_firmware_version;
|
int best_firmware_version;
|
||||||
snd_ctl_t *handle;
|
snd_ctl_t *handle;
|
||||||
|
|||||||
Reference in New Issue
Block a user