linux/sound/firewire/bebob/bebob_maudio.c

// SPDX-License-Identifier: GPL-2.0-only
/*
 * bebob_maudio.c - a part of driver for BeBoB based devices
 *
 * Copyright (c) 2013-2014 Takashi Sakamoto
 */

#include "./bebob.h"
#include <sound/control.h>

/*
 * Just powering on, Firewire 410/Audiophile/1814 and ProjectMix I/O wait to
 * download firmware blob. To enable these devices, drivers should upload
 * firmware blob and send a command to initialize configuration to factory
 * settings when completing uploading. Then these devices generate bus reset
 * and are recognized as new devices with the firmware.
 *
 * But with firmware version 5058 or later, the firmware is stored to flash
 * memory in the device and drivers can tell bootloader to load the firmware
 * by sending a cue. This cue must be sent one time.
 *
 * For streaming, both of output and input streams are needed for Firewire 410
 * and Ozonic. The single stream is OK for the other devices even if the clock
 * source is not SYT-Match (I note no devices use SYT-Match).
 *
 * Without streaming, the devices except for Firewire Audiophile can mix any
 * input and output. For this reason, Audiophile cannot be used as standalone
 * mixer.
 *
 * Firewire 1814 and ProjectMix I/O uses special firmware. It will be freezed
 * when receiving any commands which the firmware can't understand. These
 * devices utilize completely different system to control. It is some
 * write-transaction directly into a certain address. All of addresses for mixer
 * functionality is between 0xffc700700000 to 0xffc70070009c.
 */

/* Offset from information register */
#define INFO_OFFSET_SW_DATE

/* Bootloader Protocol Version 1 */
#define MAUDIO_BOOTLOADER_CUE1
/*
 * Initializing configuration to factory settings (= 0x1101), (swapped in line),
 * Command code is zero (= 0x00),
 * the number of operands is zero (= 0x00)(at least significant byte)
 */
#define MAUDIO_BOOTLOADER_CUE2
/* padding */
#define MAUDIO_BOOTLOADER_CUE3

#define MAUDIO_SPECIFIC_ADDRESS

#define METER_OFFSET

/* some device has sync info after metering data */
#define METER_SIZE_SPECIAL
#define METER_SIZE_FW410
#define METER_SIZE_AUDIOPHILE
#define METER_SIZE_SOLO
#define METER_SIZE_OZONIC
#define METER_SIZE_NRV10

/* labels for metering */
#define ANA_IN
#define ANA_OUT
#define DIG_IN
#define SPDIF_IN
#define ADAT_IN
#define DIG_OUT
#define SPDIF_OUT
#define ADAT_OUT
#define STRM_IN
#define AUX_OUT
#define HP_OUT
/* for NRV */
#define UNKNOWN_METER

struct special_params {};

/*
 * For some M-Audio devices, this module just send cue to load firmware. After
 * loading, the device generates bus reset and newly detected.
 *
 * If we make any transactions to load firmware, the operation may failed.
 */
int snd_bebob_maudio_load_firmware(struct fw_unit *unit)
{}

static inline int
get_meter(struct snd_bebob *bebob, void *buf, unsigned int size)
{}

static int
check_clk_sync(struct snd_bebob *bebob, unsigned int size, bool *sync)
{}

/*
 * dig_fmt: 0x00:S/PDIF, 0x01:ADAT
 * clk_lock: 0x00:unlock, 0x01:lock
 */
static int
avc_maudio_set_special_clk(struct snd_bebob *bebob, unsigned int clk_src,
			   unsigned int dig_in_fmt, unsigned int dig_out_fmt,
			   unsigned int clk_lock)
{}
static void
special_stream_formation_set(struct snd_bebob *bebob)
{}

static int add_special_controls(struct snd_bebob *bebob);
int
snd_bebob_maudio_special_discover(struct snd_bebob *bebob, bool is1814)
{}

/* Input plug shows actual rate. Output plug is needless for this purpose. */
static int special_get_rate(struct snd_bebob *bebob, unsigned int *rate)
{}
static int special_set_rate(struct snd_bebob *bebob, unsigned int rate)
{}

/* Clock source control for special firmware */
static const enum snd_bebob_clock_type special_clk_types[] =;
static int special_clk_get(struct snd_bebob *bebob, unsigned int *id)
{}
static int special_clk_ctl_info(struct snd_kcontrol *kctl,
				struct snd_ctl_elem_info *einf)
{}
static int special_clk_ctl_get(struct snd_kcontrol *kctl,
			       struct snd_ctl_elem_value *uval)
{}
static int special_clk_ctl_put(struct snd_kcontrol *kctl,
			       struct snd_ctl_elem_value *uval)
{}
static const struct snd_kcontrol_new special_clk_ctl =;

/* Clock synchronization control for special firmware */
static int special_sync_ctl_info(struct snd_kcontrol *kctl,
				 struct snd_ctl_elem_info *einf)
{}
static int special_sync_ctl_get(struct snd_kcontrol *kctl,
				struct snd_ctl_elem_value *uval)
{}
static const struct snd_kcontrol_new special_sync_ctl =;

/* Digital input interface control for special firmware */
static const char *const special_dig_in_iface_labels[] =;
static int special_dig_in_iface_ctl_info(struct snd_kcontrol *kctl,
					 struct snd_ctl_elem_info *einf)
{}
static int special_dig_in_iface_ctl_get(struct snd_kcontrol *kctl,
					struct snd_ctl_elem_value *uval)
{}
static int special_dig_in_iface_ctl_set(struct snd_kcontrol *kctl,
					struct snd_ctl_elem_value *uval)
{}
static const struct snd_kcontrol_new special_dig_in_iface_ctl =;

/* Digital output interface control for special firmware */
static const char *const special_dig_out_iface_labels[] =;
static int special_dig_out_iface_ctl_info(struct snd_kcontrol *kctl,
					  struct snd_ctl_elem_info *einf)
{}
static int special_dig_out_iface_ctl_get(struct snd_kcontrol *kctl,
					 struct snd_ctl_elem_value *uval)
{}
static int special_dig_out_iface_ctl_set(struct snd_kcontrol *kctl,
					 struct snd_ctl_elem_value *uval)
{}
static const struct snd_kcontrol_new special_dig_out_iface_ctl =;

static int add_special_controls(struct snd_bebob *bebob)
{}

/* Hardware metering for special firmware */
static const char *const special_meter_labels[] =;
static int
special_meter_get(struct snd_bebob *bebob, u32 *target, unsigned int size)
{}

/* last 4 bytes are omitted because it's clock info. */
static const char *const fw410_meter_labels[] =;
static const char *const audiophile_meter_labels[] =;
static const char *const solo_meter_labels[] =;

/* no clock info */
static const char *const ozonic_meter_labels[] =;
/* TODO: need testers. these positions are based on authour's assumption */
static const char *const nrv10_meter_labels[] =;
static int
normal_meter_get(struct snd_bebob *bebob, u32 *buf, unsigned int size)
{}

/* for special customized devices */
static const struct snd_bebob_rate_spec special_rate_spec =;
static const struct snd_bebob_clock_spec special_clk_spec =;
static const struct snd_bebob_meter_spec special_meter_spec =;
const struct snd_bebob_spec maudio_special_spec =;

/* Firewire 410 specification */
static const struct snd_bebob_rate_spec usual_rate_spec =;
static const struct snd_bebob_meter_spec fw410_meter_spec =;
const struct snd_bebob_spec maudio_fw410_spec =;

/* Firewire Audiophile specification */
static const struct snd_bebob_meter_spec audiophile_meter_spec =;
const struct snd_bebob_spec maudio_audiophile_spec =;

/* Firewire Solo specification */
static const struct snd_bebob_meter_spec solo_meter_spec =;
const struct snd_bebob_spec maudio_solo_spec =;

/* Ozonic specification */
static const struct snd_bebob_meter_spec ozonic_meter_spec =;
const struct snd_bebob_spec maudio_ozonic_spec =;

/* NRV10 specification */
static const struct snd_bebob_meter_spec nrv10_meter_spec =;
const struct snd_bebob_spec maudio_nrv10_spec =;