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.h"
|
||||
#include "scarlett2.h"
|
||||
#include "scarlett2-firmware.h"
|
||||
#include "scarlett2-ioctls.h"
|
||||
#include "stringhelper.h"
|
||||
#include "window-iface.h"
|
||||
|
||||
#define MAJOR_HWDEP_VERSION_SCARLETT2 1
|
||||
#define MAJOR_HWDEP_VERSION_FCP 2
|
||||
|
||||
#define MAX_TLV_RANGE_SIZE 1024
|
||||
|
||||
// TLV type for channel labels
|
||||
@@ -1067,7 +1072,81 @@ static void alsa_get_serial_number(struct alsa_card *card) {
|
||||
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) {
|
||||
card->driver_type = get_driver_type(card);
|
||||
|
||||
alsa_get_elem_list(card);
|
||||
alsa_set_lr_nums(card);
|
||||
alsa_get_routing_controls(card);
|
||||
|
||||
14
src/alsa.h
14
src/alsa.h
@@ -41,6 +41,19 @@ enum {
|
||||
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
|
||||
extern const char *hw_type_names[HW_TYPE_COUNT];
|
||||
|
||||
@@ -162,6 +175,7 @@ struct alsa_card {
|
||||
uint32_t pid;
|
||||
char *serial;
|
||||
char *name;
|
||||
int driver_type;
|
||||
char *fcp_socket;
|
||||
int best_firmware_version;
|
||||
snd_ctl_t *handle;
|
||||
|
||||
Reference in New Issue
Block a user