cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

bebob_maudio.c (21616B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * bebob_maudio.c - a part of driver for BeBoB based devices
      4 *
      5 * Copyright (c) 2013-2014 Takashi Sakamoto
      6 */
      7
      8#include "./bebob.h"
      9#include <sound/control.h>
     10
     11/*
     12 * Just powering on, Firewire 410/Audiophile/1814 and ProjectMix I/O wait to
     13 * download firmware blob. To enable these devices, drivers should upload
     14 * firmware blob and send a command to initialize configuration to factory
     15 * settings when completing uploading. Then these devices generate bus reset
     16 * and are recognized as new devices with the firmware.
     17 *
     18 * But with firmware version 5058 or later, the firmware is stored to flash
     19 * memory in the device and drivers can tell bootloader to load the firmware
     20 * by sending a cue. This cue must be sent one time.
     21 *
     22 * For streaming, both of output and input streams are needed for Firewire 410
     23 * and Ozonic. The single stream is OK for the other devices even if the clock
     24 * source is not SYT-Match (I note no devices use SYT-Match).
     25 *
     26 * Without streaming, the devices except for Firewire Audiophile can mix any
     27 * input and output. For this reason, Audiophile cannot be used as standalone
     28 * mixer.
     29 *
     30 * Firewire 1814 and ProjectMix I/O uses special firmware. It will be freezed
     31 * when receiving any commands which the firmware can't understand. These
     32 * devices utilize completely different system to control. It is some
     33 * write-transaction directly into a certain address. All of addresses for mixer
     34 * functionality is between 0xffc700700000 to 0xffc70070009c.
     35 */
     36
     37/* Offset from information register */
     38#define INFO_OFFSET_SW_DATE	0x20
     39
     40/* Bootloader Protocol Version 1 */
     41#define MAUDIO_BOOTLOADER_CUE1	0x00000001
     42/*
     43 * Initializing configuration to factory settings (= 0x1101), (swapped in line),
     44 * Command code is zero (= 0x00),
     45 * the number of operands is zero (= 0x00)(at least significant byte)
     46 */
     47#define MAUDIO_BOOTLOADER_CUE2	0x01110000
     48/* padding */
     49#define MAUDIO_BOOTLOADER_CUE3	0x00000000
     50
     51#define MAUDIO_SPECIFIC_ADDRESS	0xffc700000000ULL
     52
     53#define METER_OFFSET		0x00600000
     54
     55/* some device has sync info after metering data */
     56#define METER_SIZE_SPECIAL	84	/* with sync info */
     57#define METER_SIZE_FW410	76	/* with sync info */
     58#define METER_SIZE_AUDIOPHILE	60	/* with sync info */
     59#define METER_SIZE_SOLO		52	/* with sync info */
     60#define METER_SIZE_OZONIC	48
     61#define METER_SIZE_NRV10	80
     62
     63/* labels for metering */
     64#define ANA_IN		"Analog In"
     65#define ANA_OUT		"Analog Out"
     66#define DIG_IN		"Digital In"
     67#define SPDIF_IN	"S/PDIF In"
     68#define ADAT_IN		"ADAT In"
     69#define DIG_OUT		"Digital Out"
     70#define SPDIF_OUT	"S/PDIF Out"
     71#define ADAT_OUT	"ADAT Out"
     72#define STRM_IN		"Stream In"
     73#define AUX_OUT		"Aux Out"
     74#define HP_OUT		"HP Out"
     75/* for NRV */
     76#define UNKNOWN_METER	"Unknown"
     77
     78struct special_params {
     79	bool is1814;
     80	unsigned int clk_src;
     81	unsigned int dig_in_fmt;
     82	unsigned int dig_out_fmt;
     83	unsigned int clk_lock;
     84	struct snd_ctl_elem_id *ctl_id_sync;
     85};
     86
     87/*
     88 * For some M-Audio devices, this module just send cue to load firmware. After
     89 * loading, the device generates bus reset and newly detected.
     90 *
     91 * If we make any transactions to load firmware, the operation may failed.
     92 */
     93int snd_bebob_maudio_load_firmware(struct fw_unit *unit)
     94{
     95	struct fw_device *device = fw_parent_device(unit);
     96	int err, rcode;
     97	u64 date;
     98	__le32 *cues;
     99
    100	/* check date of software used to build */
    101	err = snd_bebob_read_block(unit, INFO_OFFSET_SW_DATE,
    102				   &date, sizeof(u64));
    103	if (err < 0)
    104		return err;
    105	/*
    106	 * firmware version 5058 or later has date later than "20070401", but
    107	 * 'date' is not null-terminated.
    108	 */
    109	if (date < 0x3230303730343031LL) {
    110		dev_err(&unit->device,
    111			"Use firmware version 5058 or later\n");
    112		return -ENXIO;
    113	}
    114
    115	cues = kmalloc_array(3, sizeof(*cues), GFP_KERNEL);
    116	if (!cues)
    117		return -ENOMEM;
    118
    119	cues[0] = cpu_to_le32(MAUDIO_BOOTLOADER_CUE1);
    120	cues[1] = cpu_to_le32(MAUDIO_BOOTLOADER_CUE2);
    121	cues[2] = cpu_to_le32(MAUDIO_BOOTLOADER_CUE3);
    122
    123	rcode = fw_run_transaction(device->card, TCODE_WRITE_BLOCK_REQUEST,
    124				   device->node_id, device->generation,
    125				   device->max_speed, BEBOB_ADDR_REG_REQ,
    126				   cues, 3 * sizeof(*cues));
    127	kfree(cues);
    128	if (rcode != RCODE_COMPLETE) {
    129		dev_err(&unit->device,
    130			"Failed to send a cue to load firmware\n");
    131		err = -EIO;
    132	}
    133
    134	return err;
    135}
    136
    137static inline int
    138get_meter(struct snd_bebob *bebob, void *buf, unsigned int size)
    139{
    140	return snd_fw_transaction(bebob->unit, TCODE_READ_BLOCK_REQUEST,
    141				  MAUDIO_SPECIFIC_ADDRESS + METER_OFFSET,
    142				  buf, size, 0);
    143}
    144
    145static int
    146check_clk_sync(struct snd_bebob *bebob, unsigned int size, bool *sync)
    147{
    148	int err;
    149	u8 *buf;
    150
    151	buf = kmalloc(size, GFP_KERNEL);
    152	if (buf == NULL)
    153		return -ENOMEM;
    154
    155	err = get_meter(bebob, buf, size);
    156	if (err < 0)
    157		goto end;
    158
    159	/* if synced, this value is the same as SFC of FDF in CIP header */
    160	*sync = (buf[size - 2] != 0xff);
    161end:
    162	kfree(buf);
    163	return err;
    164}
    165
    166/*
    167 * dig_fmt: 0x00:S/PDIF, 0x01:ADAT
    168 * clk_lock: 0x00:unlock, 0x01:lock
    169 */
    170static int
    171avc_maudio_set_special_clk(struct snd_bebob *bebob, unsigned int clk_src,
    172			   unsigned int dig_in_fmt, unsigned int dig_out_fmt,
    173			   unsigned int clk_lock)
    174{
    175	struct special_params *params = bebob->maudio_special_quirk;
    176	int err;
    177	u8 *buf;
    178
    179	if (amdtp_stream_running(&bebob->rx_stream) ||
    180	    amdtp_stream_running(&bebob->tx_stream))
    181		return -EBUSY;
    182
    183	buf = kmalloc(12, GFP_KERNEL);
    184	if (buf == NULL)
    185		return -ENOMEM;
    186
    187	buf[0]  = 0x00;		/* CONTROL */
    188	buf[1]  = 0xff;		/* UNIT */
    189	buf[2]  = 0x00;		/* vendor dependent */
    190	buf[3]  = 0x04;		/* company ID high */
    191	buf[4]  = 0x00;		/* company ID middle */
    192	buf[5]  = 0x04;		/* company ID low */
    193	buf[6]  = 0xff & clk_src;	/* clock source */
    194	buf[7]  = 0xff & dig_in_fmt;	/* input digital format */
    195	buf[8]  = 0xff & dig_out_fmt;	/* output digital format */
    196	buf[9]  = 0xff & clk_lock;	/* lock these settings */
    197	buf[10] = 0x00;		/* padding  */
    198	buf[11] = 0x00;		/* padding */
    199
    200	err = fcp_avc_transaction(bebob->unit, buf, 12, buf, 12,
    201				  BIT(1) | BIT(2) | BIT(3) | BIT(4) |
    202				  BIT(5) | BIT(6) | BIT(7) | BIT(8) |
    203				  BIT(9));
    204	if ((err > 0) && (err < 10))
    205		err = -EIO;
    206	else if (buf[0] == 0x08) /* NOT IMPLEMENTED */
    207		err = -ENOSYS;
    208	else if (buf[0] == 0x0a) /* REJECTED */
    209		err = -EINVAL;
    210	if (err < 0)
    211		goto end;
    212
    213	params->clk_src		= buf[6];
    214	params->dig_in_fmt	= buf[7];
    215	params->dig_out_fmt	= buf[8];
    216	params->clk_lock	= buf[9];
    217
    218	if (params->ctl_id_sync)
    219		snd_ctl_notify(bebob->card, SNDRV_CTL_EVENT_MASK_VALUE,
    220			       params->ctl_id_sync);
    221
    222	err = 0;
    223end:
    224	kfree(buf);
    225	return err;
    226}
    227static void
    228special_stream_formation_set(struct snd_bebob *bebob)
    229{
    230	static const unsigned int ch_table[2][2][3] = {
    231		/* AMDTP_OUT_STREAM */
    232		{ {  6,  6,  4 },	/* SPDIF */
    233		  { 12,  8,  4 } },	/* ADAT */
    234		/* AMDTP_IN_STREAM */
    235		{ { 10, 10,  2 },	/* SPDIF */
    236		  { 16, 12,  2 } }	/* ADAT */
    237	};
    238	struct special_params *params = bebob->maudio_special_quirk;
    239	unsigned int i, max;
    240
    241	max = SND_BEBOB_STRM_FMT_ENTRIES - 1;
    242	if (!params->is1814)
    243		max -= 2;
    244
    245	for (i = 0; i < max; i++) {
    246		bebob->tx_stream_formations[i + 1].pcm =
    247			ch_table[AMDTP_IN_STREAM][params->dig_in_fmt][i / 2];
    248		bebob->tx_stream_formations[i + 1].midi = 1;
    249
    250		bebob->rx_stream_formations[i + 1].pcm =
    251			ch_table[AMDTP_OUT_STREAM][params->dig_out_fmt][i / 2];
    252		bebob->rx_stream_formations[i + 1].midi = 1;
    253	}
    254}
    255
    256static int add_special_controls(struct snd_bebob *bebob);
    257int
    258snd_bebob_maudio_special_discover(struct snd_bebob *bebob, bool is1814)
    259{
    260	struct special_params *params;
    261	int err;
    262
    263	params = devm_kzalloc(&bebob->card->card_dev,
    264			      sizeof(struct special_params), GFP_KERNEL);
    265	if (!params)
    266		return -ENOMEM;
    267
    268	mutex_lock(&bebob->mutex);
    269
    270	bebob->maudio_special_quirk = (void *)params;
    271	params->is1814 = is1814;
    272
    273	/* initialize these parameters because driver is not allowed to ask */
    274	bebob->rx_stream.context = ERR_PTR(-1);
    275	bebob->tx_stream.context = ERR_PTR(-1);
    276	err = avc_maudio_set_special_clk(bebob, 0x03, 0x00, 0x00, 0x00);
    277	if (err < 0) {
    278		dev_err(&bebob->unit->device,
    279			"fail to initialize clock params: %d\n", err);
    280		goto end;
    281	}
    282
    283	err = add_special_controls(bebob);
    284	if (err < 0)
    285		goto end;
    286
    287	special_stream_formation_set(bebob);
    288
    289	if (params->is1814) {
    290		bebob->midi_input_ports = 1;
    291		bebob->midi_output_ports = 1;
    292	} else {
    293		bebob->midi_input_ports = 2;
    294		bebob->midi_output_ports = 2;
    295	}
    296end:
    297	mutex_unlock(&bebob->mutex);
    298	return err;
    299}
    300
    301/* Input plug shows actual rate. Output plug is needless for this purpose. */
    302static int special_get_rate(struct snd_bebob *bebob, unsigned int *rate)
    303{
    304	int err, trials;
    305
    306	trials = 0;
    307	do {
    308		err = avc_general_get_sig_fmt(bebob->unit, rate,
    309					      AVC_GENERAL_PLUG_DIR_IN, 0);
    310	} while (err == -EAGAIN && ++trials < 3);
    311
    312	return err;
    313}
    314static int special_set_rate(struct snd_bebob *bebob, unsigned int rate)
    315{
    316	struct special_params *params = bebob->maudio_special_quirk;
    317	int err;
    318
    319	err = avc_general_set_sig_fmt(bebob->unit, rate,
    320				      AVC_GENERAL_PLUG_DIR_OUT, 0);
    321	if (err < 0)
    322		goto end;
    323
    324	/*
    325	 * Just after changing sampling rate for output, a followed command
    326	 * for input is easy to fail. This is a workaround fot this issue.
    327	 */
    328	msleep(100);
    329
    330	err = avc_general_set_sig_fmt(bebob->unit, rate,
    331				      AVC_GENERAL_PLUG_DIR_IN, 0);
    332	if (err < 0)
    333		goto end;
    334
    335	if (params->ctl_id_sync)
    336		snd_ctl_notify(bebob->card, SNDRV_CTL_EVENT_MASK_VALUE,
    337			       params->ctl_id_sync);
    338end:
    339	return err;
    340}
    341
    342/* Clock source control for special firmware */
    343static const enum snd_bebob_clock_type special_clk_types[] = {
    344	SND_BEBOB_CLOCK_TYPE_INTERNAL,	/* With digital mute */
    345	SND_BEBOB_CLOCK_TYPE_EXTERNAL,	/* SPDIF/ADAT */
    346	SND_BEBOB_CLOCK_TYPE_EXTERNAL,	/* Word Clock */
    347	SND_BEBOB_CLOCK_TYPE_INTERNAL,
    348};
    349static int special_clk_get(struct snd_bebob *bebob, unsigned int *id)
    350{
    351	struct special_params *params = bebob->maudio_special_quirk;
    352	*id = params->clk_src;
    353	return 0;
    354}
    355static int special_clk_ctl_info(struct snd_kcontrol *kctl,
    356				struct snd_ctl_elem_info *einf)
    357{
    358	static const char *const special_clk_labels[] = {
    359		"Internal with Digital Mute",
    360		"Digital",
    361		"Word Clock",
    362		"Internal"
    363	};
    364	return snd_ctl_enum_info(einf, 1, ARRAY_SIZE(special_clk_types),
    365				 special_clk_labels);
    366}
    367static int special_clk_ctl_get(struct snd_kcontrol *kctl,
    368			       struct snd_ctl_elem_value *uval)
    369{
    370	struct snd_bebob *bebob = snd_kcontrol_chip(kctl);
    371	struct special_params *params = bebob->maudio_special_quirk;
    372	uval->value.enumerated.item[0] = params->clk_src;
    373	return 0;
    374}
    375static int special_clk_ctl_put(struct snd_kcontrol *kctl,
    376			       struct snd_ctl_elem_value *uval)
    377{
    378	struct snd_bebob *bebob = snd_kcontrol_chip(kctl);
    379	struct special_params *params = bebob->maudio_special_quirk;
    380	int err, id;
    381
    382	id = uval->value.enumerated.item[0];
    383	if (id >= ARRAY_SIZE(special_clk_types))
    384		return -EINVAL;
    385
    386	mutex_lock(&bebob->mutex);
    387
    388	err = avc_maudio_set_special_clk(bebob, id,
    389					 params->dig_in_fmt,
    390					 params->dig_out_fmt,
    391					 params->clk_lock);
    392	mutex_unlock(&bebob->mutex);
    393
    394	if (err >= 0)
    395		err = 1;
    396
    397	return err;
    398}
    399static const struct snd_kcontrol_new special_clk_ctl = {
    400	.name	= "Clock Source",
    401	.iface	= SNDRV_CTL_ELEM_IFACE_MIXER,
    402	.access	= SNDRV_CTL_ELEM_ACCESS_READWRITE,
    403	.info	= special_clk_ctl_info,
    404	.get	= special_clk_ctl_get,
    405	.put	= special_clk_ctl_put
    406};
    407
    408/* Clock synchronization control for special firmware */
    409static int special_sync_ctl_info(struct snd_kcontrol *kctl,
    410				 struct snd_ctl_elem_info *einf)
    411{
    412	einf->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
    413	einf->count = 1;
    414	einf->value.integer.min = 0;
    415	einf->value.integer.max = 1;
    416
    417	return 0;
    418}
    419static int special_sync_ctl_get(struct snd_kcontrol *kctl,
    420				struct snd_ctl_elem_value *uval)
    421{
    422	struct snd_bebob *bebob = snd_kcontrol_chip(kctl);
    423	int err;
    424	bool synced = 0;
    425
    426	err = check_clk_sync(bebob, METER_SIZE_SPECIAL, &synced);
    427	if (err >= 0)
    428		uval->value.integer.value[0] = synced;
    429
    430	return 0;
    431}
    432static const struct snd_kcontrol_new special_sync_ctl = {
    433	.name	= "Sync Status",
    434	.iface	= SNDRV_CTL_ELEM_IFACE_MIXER,
    435	.access	= SNDRV_CTL_ELEM_ACCESS_READ,
    436	.info	= special_sync_ctl_info,
    437	.get	= special_sync_ctl_get,
    438};
    439
    440/* Digital input interface control for special firmware */
    441static const char *const special_dig_in_iface_labels[] = {
    442	"S/PDIF Optical", "S/PDIF Coaxial", "ADAT Optical"
    443};
    444static int special_dig_in_iface_ctl_info(struct snd_kcontrol *kctl,
    445					 struct snd_ctl_elem_info *einf)
    446{
    447	return snd_ctl_enum_info(einf, 1,
    448				 ARRAY_SIZE(special_dig_in_iface_labels),
    449				 special_dig_in_iface_labels);
    450}
    451static int special_dig_in_iface_ctl_get(struct snd_kcontrol *kctl,
    452					struct snd_ctl_elem_value *uval)
    453{
    454	struct snd_bebob *bebob = snd_kcontrol_chip(kctl);
    455	struct special_params *params = bebob->maudio_special_quirk;
    456	unsigned int dig_in_iface;
    457	int err, val;
    458
    459	mutex_lock(&bebob->mutex);
    460
    461	err = avc_audio_get_selector(bebob->unit, 0x00, 0x04,
    462				     &dig_in_iface);
    463	if (err < 0) {
    464		dev_err(&bebob->unit->device,
    465			"fail to get digital input interface: %d\n", err);
    466		goto end;
    467	}
    468
    469	/* encoded id for user value */
    470	val = (params->dig_in_fmt << 1) | (dig_in_iface & 0x01);
    471
    472	/* for ADAT Optical */
    473	if (val > 2)
    474		val = 2;
    475
    476	uval->value.enumerated.item[0] = val;
    477end:
    478	mutex_unlock(&bebob->mutex);
    479	return err;
    480}
    481static int special_dig_in_iface_ctl_set(struct snd_kcontrol *kctl,
    482					struct snd_ctl_elem_value *uval)
    483{
    484	struct snd_bebob *bebob = snd_kcontrol_chip(kctl);
    485	struct special_params *params = bebob->maudio_special_quirk;
    486	unsigned int id, dig_in_fmt, dig_in_iface;
    487	int err;
    488
    489	id = uval->value.enumerated.item[0];
    490	if (id >= ARRAY_SIZE(special_dig_in_iface_labels))
    491		return -EINVAL;
    492
    493	/* decode user value */
    494	dig_in_fmt = (id >> 1) & 0x01;
    495	dig_in_iface = id & 0x01;
    496
    497	mutex_lock(&bebob->mutex);
    498
    499	err = avc_maudio_set_special_clk(bebob,
    500					 params->clk_src,
    501					 dig_in_fmt,
    502					 params->dig_out_fmt,
    503					 params->clk_lock);
    504	if (err < 0)
    505		goto end;
    506
    507	/* For ADAT, optical interface is only available. */
    508	if (params->dig_in_fmt > 0) {
    509		err = 1;
    510		goto end;
    511	}
    512
    513	/* For S/PDIF, optical/coaxial interfaces are selectable. */
    514	err = avc_audio_set_selector(bebob->unit, 0x00, 0x04, dig_in_iface);
    515	if (err < 0)
    516		dev_err(&bebob->unit->device,
    517			"fail to set digital input interface: %d\n", err);
    518	err = 1;
    519end:
    520	special_stream_formation_set(bebob);
    521	mutex_unlock(&bebob->mutex);
    522	return err;
    523}
    524static const struct snd_kcontrol_new special_dig_in_iface_ctl = {
    525	.name	= "Digital Input Interface",
    526	.iface	= SNDRV_CTL_ELEM_IFACE_MIXER,
    527	.access	= SNDRV_CTL_ELEM_ACCESS_READWRITE,
    528	.info	= special_dig_in_iface_ctl_info,
    529	.get	= special_dig_in_iface_ctl_get,
    530	.put	= special_dig_in_iface_ctl_set
    531};
    532
    533/* Digital output interface control for special firmware */
    534static const char *const special_dig_out_iface_labels[] = {
    535	"S/PDIF Optical and Coaxial", "ADAT Optical"
    536};
    537static int special_dig_out_iface_ctl_info(struct snd_kcontrol *kctl,
    538					  struct snd_ctl_elem_info *einf)
    539{
    540	return snd_ctl_enum_info(einf, 1,
    541				 ARRAY_SIZE(special_dig_out_iface_labels),
    542				 special_dig_out_iface_labels);
    543}
    544static int special_dig_out_iface_ctl_get(struct snd_kcontrol *kctl,
    545					 struct snd_ctl_elem_value *uval)
    546{
    547	struct snd_bebob *bebob = snd_kcontrol_chip(kctl);
    548	struct special_params *params = bebob->maudio_special_quirk;
    549	mutex_lock(&bebob->mutex);
    550	uval->value.enumerated.item[0] = params->dig_out_fmt;
    551	mutex_unlock(&bebob->mutex);
    552	return 0;
    553}
    554static int special_dig_out_iface_ctl_set(struct snd_kcontrol *kctl,
    555					 struct snd_ctl_elem_value *uval)
    556{
    557	struct snd_bebob *bebob = snd_kcontrol_chip(kctl);
    558	struct special_params *params = bebob->maudio_special_quirk;
    559	unsigned int id;
    560	int err;
    561
    562	id = uval->value.enumerated.item[0];
    563	if (id >= ARRAY_SIZE(special_dig_out_iface_labels))
    564		return -EINVAL;
    565
    566	mutex_lock(&bebob->mutex);
    567
    568	err = avc_maudio_set_special_clk(bebob,
    569					 params->clk_src,
    570					 params->dig_in_fmt,
    571					 id, params->clk_lock);
    572	if (err >= 0) {
    573		special_stream_formation_set(bebob);
    574		err = 1;
    575	}
    576
    577	mutex_unlock(&bebob->mutex);
    578	return err;
    579}
    580static const struct snd_kcontrol_new special_dig_out_iface_ctl = {
    581	.name	= "Digital Output Interface",
    582	.iface	= SNDRV_CTL_ELEM_IFACE_MIXER,
    583	.access	= SNDRV_CTL_ELEM_ACCESS_READWRITE,
    584	.info	= special_dig_out_iface_ctl_info,
    585	.get	= special_dig_out_iface_ctl_get,
    586	.put	= special_dig_out_iface_ctl_set
    587};
    588
    589static int add_special_controls(struct snd_bebob *bebob)
    590{
    591	struct snd_kcontrol *kctl;
    592	struct special_params *params = bebob->maudio_special_quirk;
    593	int err;
    594
    595	kctl = snd_ctl_new1(&special_clk_ctl, bebob);
    596	err = snd_ctl_add(bebob->card, kctl);
    597	if (err < 0)
    598		goto end;
    599
    600	kctl = snd_ctl_new1(&special_sync_ctl, bebob);
    601	err = snd_ctl_add(bebob->card, kctl);
    602	if (err < 0)
    603		goto end;
    604	params->ctl_id_sync = &kctl->id;
    605
    606	kctl = snd_ctl_new1(&special_dig_in_iface_ctl, bebob);
    607	err = snd_ctl_add(bebob->card, kctl);
    608	if (err < 0)
    609		goto end;
    610
    611	kctl = snd_ctl_new1(&special_dig_out_iface_ctl, bebob);
    612	err = snd_ctl_add(bebob->card, kctl);
    613end:
    614	return err;
    615}
    616
    617/* Hardware metering for special firmware */
    618static const char *const special_meter_labels[] = {
    619	ANA_IN, ANA_IN, ANA_IN, ANA_IN,
    620	SPDIF_IN,
    621	ADAT_IN, ADAT_IN, ADAT_IN, ADAT_IN,
    622	ANA_OUT, ANA_OUT,
    623	SPDIF_OUT,
    624	ADAT_OUT, ADAT_OUT, ADAT_OUT, ADAT_OUT,
    625	HP_OUT, HP_OUT,
    626	AUX_OUT
    627};
    628static int
    629special_meter_get(struct snd_bebob *bebob, u32 *target, unsigned int size)
    630{
    631	__be16 *buf;
    632	unsigned int i, c, channels;
    633	int err;
    634
    635	channels = ARRAY_SIZE(special_meter_labels) * 2;
    636	if (size < channels * sizeof(u32))
    637		return -EINVAL;
    638
    639	/* omit last 4 bytes because it's clock info. */
    640	buf = kmalloc(METER_SIZE_SPECIAL - 4, GFP_KERNEL);
    641	if (buf == NULL)
    642		return -ENOMEM;
    643
    644	err = get_meter(bebob, (void *)buf, METER_SIZE_SPECIAL - 4);
    645	if (err < 0)
    646		goto end;
    647
    648	/* Its format is u16 and some channels are unknown. */
    649	i = 0;
    650	for (c = 2; c < channels + 2; c++)
    651		target[i++] = be16_to_cpu(buf[c]) << 16;
    652end:
    653	kfree(buf);
    654	return err;
    655}
    656
    657/* last 4 bytes are omitted because it's clock info. */
    658static const char *const fw410_meter_labels[] = {
    659	ANA_IN, DIG_IN,
    660	ANA_OUT, ANA_OUT, ANA_OUT, ANA_OUT, DIG_OUT,
    661	HP_OUT
    662};
    663static const char *const audiophile_meter_labels[] = {
    664	ANA_IN, DIG_IN,
    665	ANA_OUT, ANA_OUT, DIG_OUT,
    666	HP_OUT, AUX_OUT,
    667};
    668static const char *const solo_meter_labels[] = {
    669	ANA_IN, DIG_IN,
    670	STRM_IN, STRM_IN,
    671	ANA_OUT, DIG_OUT
    672};
    673
    674/* no clock info */
    675static const char *const ozonic_meter_labels[] = {
    676	ANA_IN, ANA_IN,
    677	STRM_IN, STRM_IN,
    678	ANA_OUT, ANA_OUT
    679};
    680/* TODO: need testers. these positions are based on authour's assumption */
    681static const char *const nrv10_meter_labels[] = {
    682	ANA_IN, ANA_IN, ANA_IN, ANA_IN,
    683	DIG_IN,
    684	ANA_OUT, ANA_OUT, ANA_OUT, ANA_OUT,
    685	DIG_IN
    686};
    687static int
    688normal_meter_get(struct snd_bebob *bebob, u32 *buf, unsigned int size)
    689{
    690	const struct snd_bebob_meter_spec *spec = bebob->spec->meter;
    691	unsigned int c, channels;
    692	int err;
    693
    694	channels = spec->num * 2;
    695	if (size < channels * sizeof(u32))
    696		return -EINVAL;
    697
    698	err = get_meter(bebob, (void *)buf, size);
    699	if (err < 0)
    700		goto end;
    701
    702	for (c = 0; c < channels; c++)
    703		be32_to_cpus(&buf[c]);
    704
    705	/* swap stream channels because inverted */
    706	if (spec->labels == solo_meter_labels) {
    707		swap(buf[4], buf[6]);
    708		swap(buf[5], buf[7]);
    709	}
    710end:
    711	return err;
    712}
    713
    714/* for special customized devices */
    715static const struct snd_bebob_rate_spec special_rate_spec = {
    716	.get	= &special_get_rate,
    717	.set	= &special_set_rate,
    718};
    719static const struct snd_bebob_clock_spec special_clk_spec = {
    720	.num	= ARRAY_SIZE(special_clk_types),
    721	.types	= special_clk_types,
    722	.get	= &special_clk_get,
    723};
    724static const struct snd_bebob_meter_spec special_meter_spec = {
    725	.num	= ARRAY_SIZE(special_meter_labels),
    726	.labels	= special_meter_labels,
    727	.get	= &special_meter_get
    728};
    729const struct snd_bebob_spec maudio_special_spec = {
    730	.clock	= &special_clk_spec,
    731	.rate	= &special_rate_spec,
    732	.meter	= &special_meter_spec
    733};
    734
    735/* Firewire 410 specification */
    736static const struct snd_bebob_rate_spec usual_rate_spec = {
    737	.get	= &snd_bebob_stream_get_rate,
    738	.set	= &snd_bebob_stream_set_rate,
    739};
    740static const struct snd_bebob_meter_spec fw410_meter_spec = {
    741	.num	= ARRAY_SIZE(fw410_meter_labels),
    742	.labels	= fw410_meter_labels,
    743	.get	= &normal_meter_get
    744};
    745const struct snd_bebob_spec maudio_fw410_spec = {
    746	.clock	= NULL,
    747	.rate	= &usual_rate_spec,
    748	.meter	= &fw410_meter_spec
    749};
    750
    751/* Firewire Audiophile specification */
    752static const struct snd_bebob_meter_spec audiophile_meter_spec = {
    753	.num	= ARRAY_SIZE(audiophile_meter_labels),
    754	.labels	= audiophile_meter_labels,
    755	.get	= &normal_meter_get
    756};
    757const struct snd_bebob_spec maudio_audiophile_spec = {
    758	.clock	= NULL,
    759	.rate	= &usual_rate_spec,
    760	.meter	= &audiophile_meter_spec
    761};
    762
    763/* Firewire Solo specification */
    764static const struct snd_bebob_meter_spec solo_meter_spec = {
    765	.num	= ARRAY_SIZE(solo_meter_labels),
    766	.labels	= solo_meter_labels,
    767	.get	= &normal_meter_get
    768};
    769const struct snd_bebob_spec maudio_solo_spec = {
    770	.clock	= NULL,
    771	.rate	= &usual_rate_spec,
    772	.meter	= &solo_meter_spec
    773};
    774
    775/* Ozonic specification */
    776static const struct snd_bebob_meter_spec ozonic_meter_spec = {
    777	.num	= ARRAY_SIZE(ozonic_meter_labels),
    778	.labels	= ozonic_meter_labels,
    779	.get	= &normal_meter_get
    780};
    781const struct snd_bebob_spec maudio_ozonic_spec = {
    782	.clock	= NULL,
    783	.rate	= &usual_rate_spec,
    784	.meter	= &ozonic_meter_spec
    785};
    786
    787/* NRV10 specification */
    788static const struct snd_bebob_meter_spec nrv10_meter_spec = {
    789	.num	= ARRAY_SIZE(nrv10_meter_labels),
    790	.labels	= nrv10_meter_labels,
    791	.get	= &normal_meter_get
    792};
    793const struct snd_bebob_spec maudio_nrv10_spec = {
    794	.clock	= NULL,
    795	.rate	= &usual_rate_spec,
    796	.meter	= &nrv10_meter_spec
    797};