2019-05-29 16:57:59 -07:00
|
|
|
// SPDX-License-Identifier: GPL-2.0-only
|
2011-03-15 07:53:21 +01:00
|
|
|
/*
|
2014-11-29 00:59:25 +09:00
|
|
|
* oxfw.c - a part of driver for OXFW970/971 based devices
|
2011-03-15 07:53:21 +01:00
|
|
|
*
|
|
|
|
* Copyright (c) Clemens Ladisch <clemens@ladisch.de>
|
|
|
|
*/
|
|
|
|
|
2014-11-29 00:59:27 +09:00
|
|
|
#include "oxfw.h"
|
2011-03-15 07:53:21 +01:00
|
|
|
|
|
|
|
#define OXFORD_FIRMWARE_ID_ADDRESS (CSR_REGISTER_BASE + 0x50000)
|
|
|
|
/* 0x970?vvvv or 0x971?vvvv, where vvvv = firmware version */
|
|
|
|
|
|
|
|
#define OXFORD_HARDWARE_ID_ADDRESS (CSR_REGISTER_BASE + 0x90020)
|
|
|
|
#define OXFORD_HARDWARE_ID_OXFW970 0x39443841
|
|
|
|
#define OXFORD_HARDWARE_ID_OXFW971 0x39373100
|
|
|
|
|
2014-12-09 00:10:45 +09:00
|
|
|
#define VENDOR_LOUD 0x000ff2
|
2011-03-15 07:53:21 +01:00
|
|
|
#define VENDOR_GRIFFIN 0x001292
|
2014-12-09 00:10:45 +09:00
|
|
|
#define VENDOR_BEHRINGER 0x001564
|
2011-03-15 07:53:21 +01:00
|
|
|
#define VENDOR_LACIE 0x00d04b
|
2015-10-18 17:09:40 +09:00
|
|
|
#define VENDOR_TASCAM 0x00022e
|
2015-12-22 09:15:45 +09:00
|
|
|
#define OUI_STANTON 0x001260
|
ALSA: oxfw: add support for APOGEE duet FireWire
This commit adds support for APOGEE duet FireWire, launched 2007, already
discontinued. This model uses Oxford Semiconductor FW971 as its
communication engine. Below is information on Configuration ROM of this
unit. The unit supports some AV/C commands defined by Audio subunit
specification and vendor dependent commands.
$ ./hinawa-config-rom-printer /dev/fw1
{ 'bus-info': { 'adj': False,
'bmc': False,
'chip_ID': 42949742248,
'cmc': False,
'cyc_clk_acc': 255,
'generation': 0,
'imc': False,
'isc': True,
'link_spd': 3,
'max_ROM': 0,
'max_rec': 64,
'name': '1394',
'node_vendor_ID': 987,
'pmc': False},
'root-directory': [ ['VENDOR', 987],
['DESCRIPTOR', 'Apogee Electronics'],
['MODEL', 122333],
['DESCRIPTOR', 'Duet'],
[ 'NODE_CAPABILITIES',
{ 'addressing': {'64': True, 'fix': True, 'prv': False},
'misc': {'int': False, 'ms': False, 'spt': True},
'state': { 'atn': False,
'ded': False,
'drq': True,
'elo': False,
'init': False,
'lst': True,
'off': False},
'testing': {'bas': False, 'ext': False}}],
[ 'UNIT',
[ ['SPECIFIER_ID', 41005],
['VERSION', 65537],
['MODEL', 122333],
['DESCRIPTOR', 'Duet']]]]}
Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2018-11-13 12:01:30 +09:00
|
|
|
#define OUI_APOGEE 0x0003db
|
ALSA: oxfw: add support for Miglia Harmony Audio
Miglia Technology ships Harmony Audio 2004. It uses Oxford Semiconductor
OXFW970 for communication function in IEEE 1394 bus. This commit adds
support for the model.
In my opinion, the firmware of ASIC is really the initial stage, since
it has the following quirks.
* It skips several isochronous cycles to transmit isochronous packets
when receiving any asynchronous transaction.
* The value of dbc field in the transmitted packet is the number of
accumulated quadlets in CIP payload, instead of the accumulated data
blocks. Furthermore, the value includes the quadlets of CIP payload in
the packet.
* It neither supports AV/C Stream Format Information command nor AV/C
Extended Stream Format Information command.
* The vendor and model information in root directory of configuration
ROM includes some mistakes.
Additionally, when operating at 96.0 kHz, it often skips much isochronous
cycles to transmit the isochronous packets. The issue is detected as cycle
discontinuity and ALSA PCM application receives -EIO at any operation for
PCM substream. I have never found any workaround yet.
$ config-rom-pretty-printer < /sys/bus/firewire/devices/fw1/config_rom
ROM header and bus information block
-----------------------------------------------------------------
1024 04249e04 bus_info_length 4, crc_length 36, crc 40452
1028 31333934 bus_name "1394"
1032 20ff5003 irmc 0, cmc 0, isc 1, bmc 0, cyc_clk_acc 255, max_rec 5 (64)
1036 0030e002 company_id 0030e0 |
1040 00454647 device_id 8594474567 | EUI-64 13757098081207879
root directory
-----------------------------------------------------------------
1044 00062d69 directory_length 6, crc 11625
1048 030030e0 vendor
1052 8100000a --> descriptor leaf at 1092
1056 1700f970 model
1060 81000011 --> descriptor leaf at 1128
1064 0c0083c0 node capabilities: per IEEE 1394
1068 d1000001 --> unit directory at 1072
unit directory at 1072
-----------------------------------------------------------------
1072 00046ff9 directory_length 4, crc 28665 (should be 43676)
1076 1200a02d specifier id
1080 13010001 version
1084 1700f970 model
1088 8100000f --> descriptor leaf at 1148
descriptor leaf at 1092
-----------------------------------------------------------------
1092 00085f8a leaf_length 8, crc 24458
1096 00000000 textual descriptor
1100 00000000 minimal ASCII
1104 4d69676c "Migl"
1108 69612054 "ia T"
1112 6563686e "echn"
1116 6f6c6f67 "olog"
1120 79204c74 "y Lt"
1124 642e0000 "d."
descriptor leaf at 1128
-----------------------------------------------------------------
1128 00040514 leaf_length 4, crc 1300
1132 00000000 textual descriptor
1136 00000000 minimal ASCII
1140 4f584657 "OXFW"
1144 20393730 " 970"
descriptor leaf at 1148
-----------------------------------------------------------------
1148 0005a1dc leaf_length 5, crc 41436
1152 00000000 textual descriptor
1156 00000000 minimal ASCII
1160 4861726d "Harm"
1164 6f6e7941 "onyA"
1168 7564696f "udio"
Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Link: https://lore.kernel.org/r/20240218074128.95210-5-o-takashi@sakamocchi.jp
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2024-02-18 16:41:28 +09:00
|
|
|
#define OUI_OXFORD 0x0030e0
|
2011-03-15 07:53:21 +01:00
|
|
|
|
2015-09-20 21:18:55 +09:00
|
|
|
#define MODEL_SATELLITE 0x00200f
|
2021-05-18 17:45:57 +09:00
|
|
|
#define MODEL_SCS1M 0x001000
|
|
|
|
#define MODEL_DUET_FW 0x01dddd
|
2021-10-28 22:03:25 +09:00
|
|
|
#define MODEL_ONYX_1640I 0x001640
|
2015-09-20 21:18:55 +09:00
|
|
|
|
2011-03-15 07:53:21 +01:00
|
|
|
#define SPECIFIER_1394TA 0x00a02d
|
|
|
|
#define VERSION_AVC 0x010001
|
|
|
|
|
2014-11-29 00:59:25 +09:00
|
|
|
MODULE_DESCRIPTION("Oxford Semiconductor FW970/971 driver");
|
2011-03-15 07:53:21 +01:00
|
|
|
MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
|
2023-06-11 23:44:45 +09:00
|
|
|
MODULE_LICENSE("GPL");
|
2014-11-29 00:59:25 +09:00
|
|
|
MODULE_ALIAS("snd-firewire-speakers");
|
2015-12-22 09:15:45 +09:00
|
|
|
MODULE_ALIAS("snd-scs1x");
|
2011-03-15 07:53:21 +01:00
|
|
|
|
2015-12-16 20:37:57 +09:00
|
|
|
struct compat_info {
|
|
|
|
const char *driver_name;
|
|
|
|
const char *vendor_name;
|
|
|
|
const char *model_name;
|
|
|
|
};
|
|
|
|
|
2014-12-09 00:10:45 +09:00
|
|
|
static bool detect_loud_models(struct fw_unit *unit)
|
|
|
|
{
|
2023-06-27 12:32:53 +01:00
|
|
|
static const char *const models[] = {
|
2014-12-09 00:10:45 +09:00
|
|
|
"Onyxi",
|
|
|
|
"Onyx-i",
|
ALSA: oxfw: add support for Mackie Onyx 1640i
As of kernel 4.10, ALSA OXFW driver has no entry for Onyx 1640i produced
by Mackie (Loud Technologies). This commit supplement it.
I note that there're two models produced by Mackie (Loud Technologies),
which have the same name 'Onyx 1640i'. The former model based on OXFW970,
the latter model based on Dice. This is probably due to low quality of
communication of OXFW series.
Additionally, the tester reports his or her experiences to get unexpected
result at higher sampling transmission frequency as 88.2/96.0 kHz. We
didn't have further investigation yet[0].
$ ./linux-firewire-utils/src/crpp < config_rom
ROM header and bus information block
-----------------------------------------------------------------
400 042525ce bus_info_length 4, crc_length 37, crc 9678
404 31333934 bus_name "1394"
408 20ff5003 irmc 0, cmc 0, isc 1, bmc 0, cyc_clk_acc 255, max_rec 5 (64)
40c 000ff205 company_id 000ff2 |
410 00000fcf device_id 0500000fcf | EUI-64 000ff20500000fcf
root directory
-----------------------------------------------------------------
414 0006c1b7 directory_length 6, crc 49591
418 03000ff2 vendor
41c 8100000a --> descriptor leaf at 444
420 17001640 model
424 81000011 --> descriptor leaf at 468
428 0c0083c0 node capabilities per IEEE 1394
42c d1000001 --> unit directory at 430
unit directory at 430
-----------------------------------------------------------------
430 00040b97 directory_length 4, crc 2967
434 1200a02d specifier id: 1394 TA
438 13010001 version: AV/C
43c 17001640 model
440 81000010 --> descriptor leaf at 480
descriptor leaf at 444
-----------------------------------------------------------------
444 0008a886 leaf_length 8, crc 43142
448 00000000 textual descriptor
44c 00000000 minimal ASCII
450 4c6f7564 "Loud"
454 20546563 " Tec"
458 686e6f6c "hnol"
45c 6f676965 "ogie"
460 7320496e "s In"
464 632e0000 "c."
descriptor leaf at 468
-----------------------------------------------------------------
468 00059fcf leaf_length 5, crc 40911
46c 00000000 textual descriptor
470 00000000 minimal ASCII
474 4f6e7978 "Onyx"
478 20313634 " 164"
47c 30690000 "0i"
descriptor leaf at 480
-----------------------------------------------------------------
480 00059fcf leaf_length 5, crc 40911
484 00000000 textual descriptor
488 00000000 minimal ASCII
48c 4f6e7978 "Onyx"
490 20313634 " 164"
494 30690000 "0i"
[0]: [FFADO-user] Mackie 1640i issues (finer details)
https://sourceforge.net/p/ffado/mailman/message/35229260/
Tested-by: Seth O'Bannion <saobannion@gmail.com>
Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2017-01-03 11:36:08 +09:00
|
|
|
"Onyx 1640i",
|
2014-12-09 00:10:45 +09:00
|
|
|
"d.Pro",
|
|
|
|
"U.420"};
|
|
|
|
char model[32];
|
|
|
|
int err;
|
|
|
|
|
|
|
|
err = fw_csr_string(unit->directory, CSR_MODEL,
|
|
|
|
model, sizeof(model));
|
|
|
|
if (err < 0)
|
2014-12-12 22:28:10 +03:00
|
|
|
return false;
|
2014-12-09 00:10:45 +09:00
|
|
|
|
2018-05-21 19:58:06 +08:00
|
|
|
return match_string(models, ARRAY_SIZE(models), model) >= 0;
|
2014-12-09 00:10:45 +09:00
|
|
|
}
|
|
|
|
|
2021-06-07 17:12:44 +09:00
|
|
|
static int name_card(struct snd_oxfw *oxfw, const struct ieee1394_device_id *entry)
|
2011-03-15 07:53:21 +01:00
|
|
|
{
|
2014-12-09 00:10:40 +09:00
|
|
|
struct fw_device *fw_dev = fw_parent_device(oxfw->unit);
|
2015-12-16 20:37:57 +09:00
|
|
|
const struct compat_info *info;
|
2014-12-09 00:10:45 +09:00
|
|
|
char vendor[24];
|
|
|
|
char model[32];
|
2014-12-09 00:10:40 +09:00
|
|
|
const char *d, *v, *m;
|
|
|
|
u32 firmware;
|
2011-03-15 07:53:21 +01:00
|
|
|
int err;
|
|
|
|
|
2014-12-09 00:10:45 +09:00
|
|
|
/* get vendor name from root directory */
|
|
|
|
err = fw_csr_string(fw_dev->config_rom + 5, CSR_VENDOR,
|
|
|
|
vendor, sizeof(vendor));
|
|
|
|
if (err < 0)
|
|
|
|
goto end;
|
|
|
|
|
|
|
|
/* get model name from unit directory */
|
|
|
|
err = fw_csr_string(oxfw->unit->directory, CSR_MODEL,
|
|
|
|
model, sizeof(model));
|
|
|
|
if (err < 0)
|
|
|
|
goto end;
|
|
|
|
|
2014-12-09 00:10:40 +09:00
|
|
|
err = snd_fw_transaction(oxfw->unit, TCODE_READ_QUADLET_REQUEST,
|
|
|
|
OXFORD_FIRMWARE_ID_ADDRESS, &firmware, 4, 0);
|
|
|
|
if (err < 0)
|
|
|
|
goto end;
|
|
|
|
be32_to_cpus(&firmware);
|
|
|
|
|
2021-05-18 17:45:54 +09:00
|
|
|
if (firmware >> 20 == 0x970)
|
|
|
|
oxfw->quirks |= SND_OXFW_QUIRK_JUMBO_PAYLOAD;
|
|
|
|
|
2014-12-09 00:10:45 +09:00
|
|
|
/* to apply card definitions */
|
2021-06-07 17:12:44 +09:00
|
|
|
if (entry->vendor_id == VENDOR_GRIFFIN || entry->vendor_id == VENDOR_LACIE) {
|
|
|
|
info = (const struct compat_info *)entry->driver_data;
|
2015-12-15 23:56:20 +09:00
|
|
|
d = info->driver_name;
|
|
|
|
v = info->vendor_name;
|
|
|
|
m = info->model_name;
|
2014-12-09 00:10:45 +09:00
|
|
|
} else {
|
|
|
|
d = "OXFW";
|
|
|
|
v = vendor;
|
|
|
|
m = model;
|
|
|
|
}
|
2014-12-09 00:10:40 +09:00
|
|
|
|
2025-07-10 12:06:02 +02:00
|
|
|
strscpy(oxfw->card->driver, d);
|
|
|
|
strscpy(oxfw->card->mixername, m);
|
|
|
|
strscpy(oxfw->card->shortname, m);
|
2014-12-09 00:10:40 +09:00
|
|
|
|
2023-09-15 10:27:59 +02:00
|
|
|
scnprintf(oxfw->card->longname, sizeof(oxfw->card->longname),
|
|
|
|
"%s %s (OXFW%x %04x), GUID %08x%08x at %s, S%d",
|
|
|
|
v, m, firmware >> 20, firmware & 0xffff,
|
|
|
|
fw_dev->config_rom[3], fw_dev->config_rom[4],
|
|
|
|
dev_name(&oxfw->unit->device), 100 << fw_dev->max_speed);
|
2014-12-09 00:10:40 +09:00
|
|
|
end:
|
|
|
|
return err;
|
2011-03-15 07:53:21 +01:00
|
|
|
}
|
|
|
|
|
2018-10-10 15:35:02 +09:00
|
|
|
static void oxfw_card_free(struct snd_card *card)
|
2011-03-15 07:53:21 +01:00
|
|
|
{
|
2018-10-10 15:35:02 +09:00
|
|
|
struct snd_oxfw *oxfw = card->private_data;
|
|
|
|
|
2020-01-13 16:34:17 +09:00
|
|
|
if (oxfw->has_output || oxfw->has_input)
|
|
|
|
snd_oxfw_stream_destroy_duplex(oxfw);
|
2021-06-07 17:12:44 +09:00
|
|
|
|
|
|
|
mutex_destroy(&oxfw->mutex);
|
|
|
|
fw_unit_put(oxfw->unit);
|
2011-03-15 07:53:21 +01:00
|
|
|
}
|
|
|
|
|
2021-06-07 17:12:44 +09:00
|
|
|
static int detect_quirks(struct snd_oxfw *oxfw, const struct ieee1394_device_id *entry)
|
2015-09-20 21:18:55 +09:00
|
|
|
{
|
|
|
|
struct fw_device *fw_dev = fw_parent_device(oxfw->unit);
|
|
|
|
struct fw_csr_iterator it;
|
|
|
|
int key, val;
|
|
|
|
int vendor, model;
|
|
|
|
|
2015-12-15 23:56:21 +09:00
|
|
|
/*
|
|
|
|
* Add ALSA control elements for two models to keep compatibility to
|
|
|
|
* old firewire-speaker module.
|
|
|
|
*/
|
2021-06-07 17:12:44 +09:00
|
|
|
if (entry->vendor_id == VENDOR_GRIFFIN)
|
2015-12-16 20:37:56 +09:00
|
|
|
return snd_oxfw_add_spkr(oxfw, false);
|
2021-06-07 17:12:44 +09:00
|
|
|
if (entry->vendor_id == VENDOR_LACIE)
|
2015-12-16 20:37:56 +09:00
|
|
|
return snd_oxfw_add_spkr(oxfw, true);
|
2015-12-15 23:56:21 +09:00
|
|
|
|
2015-12-22 09:15:45 +09:00
|
|
|
/*
|
|
|
|
* Stanton models supports asynchronous transactions for unique MIDI
|
|
|
|
* messages.
|
|
|
|
*/
|
2021-06-07 17:12:44 +09:00
|
|
|
if (entry->vendor_id == OUI_STANTON) {
|
|
|
|
oxfw->quirks |= SND_OXFW_QUIRK_SCS_TRANSACTION;
|
|
|
|
if (entry->model_id == MODEL_SCS1M)
|
2021-05-18 17:45:57 +09:00
|
|
|
oxfw->quirks |= SND_OXFW_QUIRK_BLOCKING_TRANSMISSION;
|
|
|
|
|
|
|
|
// No physical MIDI ports.
|
2015-12-22 09:15:46 +09:00
|
|
|
oxfw->midi_input_ports = 0;
|
|
|
|
oxfw->midi_output_ports = 0;
|
|
|
|
|
2015-12-22 09:15:45 +09:00
|
|
|
return snd_oxfw_scs1x_add(oxfw);
|
2015-12-22 09:15:46 +09:00
|
|
|
}
|
2015-12-22 09:15:45 +09:00
|
|
|
|
2021-08-12 11:28:39 +09:00
|
|
|
if (entry->vendor_id == OUI_APOGEE && entry->model_id == MODEL_DUET_FW) {
|
|
|
|
oxfw->quirks |= SND_OXFW_QUIRK_BLOCKING_TRANSMISSION |
|
|
|
|
SND_OXFW_QUIRK_IGNORE_NO_INFO_PACKET;
|
|
|
|
}
|
2021-05-18 17:45:57 +09:00
|
|
|
|
2015-12-15 23:56:20 +09:00
|
|
|
/*
|
|
|
|
* TASCAM FireOne has physical control and requires a pair of additional
|
|
|
|
* MIDI ports.
|
|
|
|
*/
|
2021-06-07 17:12:44 +09:00
|
|
|
if (entry->vendor_id == VENDOR_TASCAM) {
|
2015-12-15 23:56:20 +09:00
|
|
|
oxfw->midi_input_ports++;
|
|
|
|
oxfw->midi_output_ports++;
|
2015-12-15 23:56:21 +09:00
|
|
|
return 0;
|
2015-12-15 23:56:20 +09:00
|
|
|
}
|
|
|
|
|
2015-09-20 21:18:55 +09:00
|
|
|
/* Seek from Root Directory of Config ROM. */
|
|
|
|
vendor = model = 0;
|
|
|
|
fw_csr_iterator_init(&it, fw_dev->config_rom + 5);
|
|
|
|
while (fw_csr_iterator_next(&it, &key, &val)) {
|
|
|
|
if (key == CSR_VENDOR)
|
|
|
|
vendor = val;
|
|
|
|
else if (key == CSR_MODEL)
|
|
|
|
model = val;
|
|
|
|
}
|
|
|
|
|
2021-09-13 11:10:42 +09:00
|
|
|
if (vendor == VENDOR_LOUD) {
|
|
|
|
// Mackie Onyx Satellite with base station has a quirk to report a wrong
|
|
|
|
// value in 'dbs' field of CIP header against its format information.
|
2021-05-18 17:45:56 +09:00
|
|
|
oxfw->quirks |= SND_OXFW_QUIRK_WRONG_DBS;
|
2015-12-15 23:56:21 +09:00
|
|
|
|
2021-09-13 11:10:42 +09:00
|
|
|
// OXFW971-based models may transfer events by blocking method.
|
|
|
|
if (!(oxfw->quirks & SND_OXFW_QUIRK_JUMBO_PAYLOAD))
|
|
|
|
oxfw->quirks |= SND_OXFW_QUIRK_BLOCKING_TRANSMISSION;
|
2021-10-28 22:03:25 +09:00
|
|
|
|
|
|
|
if (model == MODEL_ONYX_1640I) {
|
|
|
|
//Unless receiving packets without NOINFO packet, the device transfers
|
|
|
|
//mostly half of events in packets than expected.
|
|
|
|
oxfw->quirks |= SND_OXFW_QUIRK_IGNORE_NO_INFO_PACKET |
|
|
|
|
SND_OXFW_QUIRK_VOLUNTARY_RECOVERY;
|
|
|
|
}
|
2021-09-13 11:10:42 +09:00
|
|
|
}
|
|
|
|
|
2015-12-15 23:56:21 +09:00
|
|
|
return 0;
|
2015-09-20 21:18:55 +09:00
|
|
|
}
|
|
|
|
|
2021-06-07 17:12:44 +09:00
|
|
|
static int oxfw_probe(struct fw_unit *unit, const struct ieee1394_device_id *entry)
|
2011-03-15 07:53:21 +01:00
|
|
|
{
|
2021-06-07 17:12:44 +09:00
|
|
|
struct snd_card *card;
|
|
|
|
struct snd_oxfw *oxfw;
|
2011-03-15 07:53:21 +01:00
|
|
|
int err;
|
|
|
|
|
2021-06-07 17:12:44 +09:00
|
|
|
if (entry->vendor_id == VENDOR_LOUD && entry->model_id == 0 && !detect_loud_models(unit))
|
|
|
|
return -ENODEV;
|
2014-12-09 00:10:45 +09:00
|
|
|
|
2021-06-07 17:12:44 +09:00
|
|
|
err = snd_card_new(&unit->device, -1, NULL, THIS_MODULE, sizeof(*oxfw), &card);
|
2011-03-15 07:53:21 +01:00
|
|
|
if (err < 0)
|
2021-06-07 17:12:44 +09:00
|
|
|
return err;
|
|
|
|
card->private_free = oxfw_card_free;
|
2011-03-15 07:53:21 +01:00
|
|
|
|
2021-06-07 17:12:44 +09:00
|
|
|
oxfw = card->private_data;
|
|
|
|
oxfw->unit = fw_unit_get(unit);
|
|
|
|
dev_set_drvdata(&unit->device, oxfw);
|
|
|
|
oxfw->card = card;
|
|
|
|
|
|
|
|
mutex_init(&oxfw->mutex);
|
|
|
|
spin_lock_init(&oxfw->lock);
|
|
|
|
init_waitqueue_head(&oxfw->hwdep_wait);
|
|
|
|
|
|
|
|
err = name_card(oxfw, entry);
|
2016-03-31 08:47:07 +09:00
|
|
|
if (err < 0)
|
|
|
|
goto error;
|
2011-03-15 07:53:21 +01:00
|
|
|
|
ALSA: oxfw: add support for Miglia Harmony Audio
Miglia Technology ships Harmony Audio 2004. It uses Oxford Semiconductor
OXFW970 for communication function in IEEE 1394 bus. This commit adds
support for the model.
In my opinion, the firmware of ASIC is really the initial stage, since
it has the following quirks.
* It skips several isochronous cycles to transmit isochronous packets
when receiving any asynchronous transaction.
* The value of dbc field in the transmitted packet is the number of
accumulated quadlets in CIP payload, instead of the accumulated data
blocks. Furthermore, the value includes the quadlets of CIP payload in
the packet.
* It neither supports AV/C Stream Format Information command nor AV/C
Extended Stream Format Information command.
* The vendor and model information in root directory of configuration
ROM includes some mistakes.
Additionally, when operating at 96.0 kHz, it often skips much isochronous
cycles to transmit the isochronous packets. The issue is detected as cycle
discontinuity and ALSA PCM application receives -EIO at any operation for
PCM substream. I have never found any workaround yet.
$ config-rom-pretty-printer < /sys/bus/firewire/devices/fw1/config_rom
ROM header and bus information block
-----------------------------------------------------------------
1024 04249e04 bus_info_length 4, crc_length 36, crc 40452
1028 31333934 bus_name "1394"
1032 20ff5003 irmc 0, cmc 0, isc 1, bmc 0, cyc_clk_acc 255, max_rec 5 (64)
1036 0030e002 company_id 0030e0 |
1040 00454647 device_id 8594474567 | EUI-64 13757098081207879
root directory
-----------------------------------------------------------------
1044 00062d69 directory_length 6, crc 11625
1048 030030e0 vendor
1052 8100000a --> descriptor leaf at 1092
1056 1700f970 model
1060 81000011 --> descriptor leaf at 1128
1064 0c0083c0 node capabilities: per IEEE 1394
1068 d1000001 --> unit directory at 1072
unit directory at 1072
-----------------------------------------------------------------
1072 00046ff9 directory_length 4, crc 28665 (should be 43676)
1076 1200a02d specifier id
1080 13010001 version
1084 1700f970 model
1088 8100000f --> descriptor leaf at 1148
descriptor leaf at 1092
-----------------------------------------------------------------
1092 00085f8a leaf_length 8, crc 24458
1096 00000000 textual descriptor
1100 00000000 minimal ASCII
1104 4d69676c "Migl"
1108 69612054 "ia T"
1112 6563686e "echn"
1116 6f6c6f67 "olog"
1120 79204c74 "y Lt"
1124 642e0000 "d."
descriptor leaf at 1128
-----------------------------------------------------------------
1128 00040514 leaf_length 4, crc 1300
1132 00000000 textual descriptor
1136 00000000 minimal ASCII
1140 4f584657 "OXFW"
1144 20393730 " 970"
descriptor leaf at 1148
-----------------------------------------------------------------
1148 0005a1dc leaf_length 5, crc 41436
1152 00000000 textual descriptor
1156 00000000 minimal ASCII
1160 4861726d "Harm"
1164 6f6e7941 "onyA"
1168 7564696f "udio"
Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Link: https://lore.kernel.org/r/20240218074128.95210-5-o-takashi@sakamocchi.jp
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2024-02-18 16:41:28 +09:00
|
|
|
if (entry->vendor_id == OUI_OXFORD && entry->model_id == 0x00f970) {
|
|
|
|
oxfw->quirks |= SND_OXFW_QUIRK_STREAM_FORMAT_INFO_UNSUPPORTED |
|
|
|
|
SND_OXFW_QUIRK_DBC_IS_TOTAL_PAYLOAD_QUADLETS;
|
|
|
|
}
|
|
|
|
|
2017-04-03 21:13:40 +09:00
|
|
|
err = snd_oxfw_stream_discover(oxfw);
|
2014-12-09 00:10:42 +09:00
|
|
|
if (err < 0)
|
|
|
|
goto error;
|
|
|
|
|
2021-06-07 17:12:44 +09:00
|
|
|
err = detect_quirks(oxfw, entry);
|
2015-12-15 23:56:21 +09:00
|
|
|
if (err < 0)
|
|
|
|
goto error;
|
2015-09-20 21:18:55 +09:00
|
|
|
|
2020-01-13 16:34:17 +09:00
|
|
|
if (oxfw->has_output || oxfw->has_input) {
|
|
|
|
err = snd_oxfw_stream_init_duplex(oxfw);
|
|
|
|
if (err < 0)
|
|
|
|
goto error;
|
2011-03-15 07:53:21 +01:00
|
|
|
|
2020-01-13 16:34:17 +09:00
|
|
|
err = snd_oxfw_create_pcm(oxfw);
|
|
|
|
if (err < 0)
|
|
|
|
goto error;
|
2011-03-15 07:53:21 +01:00
|
|
|
|
2020-01-13 16:34:17 +09:00
|
|
|
snd_oxfw_proc_init(oxfw);
|
2014-12-09 00:10:43 +09:00
|
|
|
|
2020-01-13 16:34:17 +09:00
|
|
|
err = snd_oxfw_create_midi(oxfw);
|
|
|
|
if (err < 0)
|
|
|
|
goto error;
|
2014-12-09 00:10:48 +09:00
|
|
|
|
2020-01-13 16:34:17 +09:00
|
|
|
err = snd_oxfw_create_hwdep(oxfw);
|
|
|
|
if (err < 0)
|
|
|
|
goto error;
|
|
|
|
}
|
2014-12-09 00:10:49 +09:00
|
|
|
|
2021-06-07 17:12:44 +09:00
|
|
|
err = snd_card_register(card);
|
2011-03-15 07:53:21 +01:00
|
|
|
if (err < 0)
|
|
|
|
goto error;
|
|
|
|
|
|
|
|
return 0;
|
2021-06-07 17:12:44 +09:00
|
|
|
error:
|
|
|
|
snd_card_free(card);
|
|
|
|
return err;
|
2011-03-15 07:53:21 +01:00
|
|
|
}
|
|
|
|
|
2014-11-29 00:59:25 +09:00
|
|
|
static void oxfw_bus_reset(struct fw_unit *unit)
|
2011-03-15 07:53:21 +01:00
|
|
|
{
|
2014-11-29 00:59:25 +09:00
|
|
|
struct snd_oxfw *oxfw = dev_get_drvdata(&unit->device);
|
2011-03-15 07:53:21 +01:00
|
|
|
|
2014-11-29 00:59:25 +09:00
|
|
|
fcp_bus_reset(oxfw->unit);
|
2011-03-15 07:53:21 +01:00
|
|
|
|
2021-06-07 17:12:44 +09:00
|
|
|
if (oxfw->has_output || oxfw->has_input) {
|
|
|
|
mutex_lock(&oxfw->mutex);
|
|
|
|
snd_oxfw_stream_update_duplex(oxfw);
|
|
|
|
mutex_unlock(&oxfw->mutex);
|
2016-03-31 08:47:07 +09:00
|
|
|
}
|
2021-06-07 17:12:44 +09:00
|
|
|
|
|
|
|
if (oxfw->quirks & SND_OXFW_QUIRK_SCS_TRANSACTION)
|
|
|
|
snd_oxfw_scs1x_update(oxfw);
|
2011-03-15 07:53:21 +01:00
|
|
|
}
|
|
|
|
|
2014-11-29 00:59:25 +09:00
|
|
|
static void oxfw_remove(struct fw_unit *unit)
|
2013-06-09 18:15:00 +02:00
|
|
|
{
|
2014-11-29 00:59:25 +09:00
|
|
|
struct snd_oxfw *oxfw = dev_get_drvdata(&unit->device);
|
2013-06-09 18:15:00 +02:00
|
|
|
|
2021-06-07 17:12:44 +09:00
|
|
|
// Block till all of ALSA character devices are released.
|
|
|
|
snd_card_free(oxfw->card);
|
2013-06-09 18:15:00 +02:00
|
|
|
}
|
|
|
|
|
2015-12-16 20:37:57 +09:00
|
|
|
static const struct compat_info griffin_firewave = {
|
2013-06-09 18:15:00 +02:00
|
|
|
.driver_name = "FireWave",
|
2014-12-09 00:10:40 +09:00
|
|
|
.vendor_name = "Griffin",
|
|
|
|
.model_name = "FireWave",
|
2013-06-09 18:15:00 +02:00
|
|
|
};
|
|
|
|
|
2015-12-16 20:37:57 +09:00
|
|
|
static const struct compat_info lacie_speakers = {
|
2013-06-09 18:15:00 +02:00
|
|
|
.driver_name = "FWSpeakers",
|
2014-12-09 00:10:40 +09:00
|
|
|
.vendor_name = "LaCie",
|
|
|
|
.model_name = "FireWire Speakers",
|
2013-06-09 18:15:00 +02:00
|
|
|
};
|
|
|
|
|
2021-05-18 17:45:49 +09:00
|
|
|
#define OXFW_DEV_ENTRY(vendor, model, data) \
|
|
|
|
{ \
|
|
|
|
.match_flags = IEEE1394_MATCH_VENDOR_ID | \
|
|
|
|
IEEE1394_MATCH_MODEL_ID | \
|
|
|
|
IEEE1394_MATCH_SPECIFIER_ID | \
|
|
|
|
IEEE1394_MATCH_VERSION, \
|
|
|
|
.vendor_id = vendor, \
|
|
|
|
.model_id = model, \
|
|
|
|
.specifier_id = SPECIFIER_1394TA, \
|
|
|
|
.version = VERSION_AVC, \
|
|
|
|
.driver_data = (kernel_ulong_t)data, \
|
|
|
|
}
|
|
|
|
|
2014-11-29 00:59:25 +09:00
|
|
|
static const struct ieee1394_device_id oxfw_id_table[] = {
|
2021-05-18 17:45:53 +09:00
|
|
|
//
|
|
|
|
// OXFW970 devices:
|
|
|
|
// Initial firmware has a quirk to postpone isoc packet transmission during finishing async
|
|
|
|
// transaction. As a result, several isochronous cycles are skipped to transfer the packets
|
|
|
|
// and the audio data frames which should have been transferred during the cycles are put
|
|
|
|
// into packet at the first isoc cycle after the postpone. Furthermore, the value of SYT
|
|
|
|
// field in CIP header is not reliable as synchronization timing,
|
|
|
|
//
|
2021-05-18 17:45:49 +09:00
|
|
|
OXFW_DEV_ENTRY(VENDOR_GRIFFIN, 0x00f970, &griffin_firewave),
|
|
|
|
OXFW_DEV_ENTRY(VENDOR_LACIE, 0x00f970, &lacie_speakers),
|
ALSA: oxfw: add support for Miglia Harmony Audio
Miglia Technology ships Harmony Audio 2004. It uses Oxford Semiconductor
OXFW970 for communication function in IEEE 1394 bus. This commit adds
support for the model.
In my opinion, the firmware of ASIC is really the initial stage, since
it has the following quirks.
* It skips several isochronous cycles to transmit isochronous packets
when receiving any asynchronous transaction.
* The value of dbc field in the transmitted packet is the number of
accumulated quadlets in CIP payload, instead of the accumulated data
blocks. Furthermore, the value includes the quadlets of CIP payload in
the packet.
* It neither supports AV/C Stream Format Information command nor AV/C
Extended Stream Format Information command.
* The vendor and model information in root directory of configuration
ROM includes some mistakes.
Additionally, when operating at 96.0 kHz, it often skips much isochronous
cycles to transmit the isochronous packets. The issue is detected as cycle
discontinuity and ALSA PCM application receives -EIO at any operation for
PCM substream. I have never found any workaround yet.
$ config-rom-pretty-printer < /sys/bus/firewire/devices/fw1/config_rom
ROM header and bus information block
-----------------------------------------------------------------
1024 04249e04 bus_info_length 4, crc_length 36, crc 40452
1028 31333934 bus_name "1394"
1032 20ff5003 irmc 0, cmc 0, isc 1, bmc 0, cyc_clk_acc 255, max_rec 5 (64)
1036 0030e002 company_id 0030e0 |
1040 00454647 device_id 8594474567 | EUI-64 13757098081207879
root directory
-----------------------------------------------------------------
1044 00062d69 directory_length 6, crc 11625
1048 030030e0 vendor
1052 8100000a --> descriptor leaf at 1092
1056 1700f970 model
1060 81000011 --> descriptor leaf at 1128
1064 0c0083c0 node capabilities: per IEEE 1394
1068 d1000001 --> unit directory at 1072
unit directory at 1072
-----------------------------------------------------------------
1072 00046ff9 directory_length 4, crc 28665 (should be 43676)
1076 1200a02d specifier id
1080 13010001 version
1084 1700f970 model
1088 8100000f --> descriptor leaf at 1148
descriptor leaf at 1092
-----------------------------------------------------------------
1092 00085f8a leaf_length 8, crc 24458
1096 00000000 textual descriptor
1100 00000000 minimal ASCII
1104 4d69676c "Migl"
1108 69612054 "ia T"
1112 6563686e "echn"
1116 6f6c6f67 "olog"
1120 79204c74 "y Lt"
1124 642e0000 "d."
descriptor leaf at 1128
-----------------------------------------------------------------
1128 00040514 leaf_length 4, crc 1300
1132 00000000 textual descriptor
1136 00000000 minimal ASCII
1140 4f584657 "OXFW"
1144 20393730 " 970"
descriptor leaf at 1148
-----------------------------------------------------------------
1148 0005a1dc leaf_length 5, crc 41436
1152 00000000 textual descriptor
1156 00000000 minimal ASCII
1160 4861726d "Harm"
1164 6f6e7941 "onyA"
1168 7564696f "udio"
Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Link: https://lore.kernel.org/r/20240218074128.95210-5-o-takashi@sakamocchi.jp
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2024-02-18 16:41:28 +09:00
|
|
|
// Miglia HarmonyAudio (HA02). The numeric vendor ID is ASIC vendor and the model ID is the
|
|
|
|
// default value of ASIC.
|
|
|
|
OXFW_DEV_ENTRY(OUI_OXFORD, 0x00f970, NULL),
|
2021-05-18 17:45:53 +09:00
|
|
|
// Behringer,F-Control Audio 202. The value of SYT field is not reliable at all.
|
2021-05-18 17:45:49 +09:00
|
|
|
OXFW_DEV_ENTRY(VENDOR_BEHRINGER, 0x00fc22, NULL),
|
2021-05-18 17:45:53 +09:00
|
|
|
// Loud Technologies, Tapco Link.FireWire 4x6. The value of SYT field is always 0xffff.
|
2021-05-18 17:45:51 +09:00
|
|
|
OXFW_DEV_ENTRY(VENDOR_LOUD, 0x000460, NULL),
|
2021-05-18 17:45:53 +09:00
|
|
|
// Loud Technologies, Mackie Onyx Satellite. Although revised version of firmware is
|
|
|
|
// installed to avoid the postpone, the value of SYT field is always 0xffff.
|
2021-05-18 17:45:52 +09:00
|
|
|
OXFW_DEV_ENTRY(VENDOR_LOUD, MODEL_SATELLITE, NULL),
|
2021-05-18 17:45:53 +09:00
|
|
|
|
|
|
|
//
|
|
|
|
// OXFW971 devices:
|
|
|
|
// The value of SYT field in CIP header is enough reliable. Both of blocking and non-blocking
|
|
|
|
// transmission methods are available.
|
|
|
|
//
|
2021-05-18 17:45:52 +09:00
|
|
|
// Any Mackie(Loud) models (name string/model id):
|
|
|
|
// Onyx-i series (former models): 0x081216
|
|
|
|
// Onyx 1640i: 0x001640
|
|
|
|
// d.2 pro/d.4 pro (built-in card): Unknown
|
|
|
|
// U.420: Unknown
|
|
|
|
// U.420d: Unknown
|
2014-12-09 00:10:45 +09:00
|
|
|
{
|
|
|
|
.match_flags = IEEE1394_MATCH_VENDOR_ID |
|
|
|
|
IEEE1394_MATCH_SPECIFIER_ID |
|
|
|
|
IEEE1394_MATCH_VERSION,
|
|
|
|
.vendor_id = VENDOR_LOUD,
|
2021-05-18 17:45:50 +09:00
|
|
|
.model_id = 0,
|
2014-12-09 00:10:45 +09:00
|
|
|
.specifier_id = SPECIFIER_1394TA,
|
|
|
|
.version = VERSION_AVC,
|
|
|
|
},
|
2021-05-18 17:45:49 +09:00
|
|
|
// TASCAM, FireOne.
|
|
|
|
OXFW_DEV_ENTRY(VENDOR_TASCAM, 0x800007, NULL),
|
|
|
|
// Stanton, Stanton Controllers & Systems 1 Mixer (SCS.1m).
|
2021-05-18 17:45:57 +09:00
|
|
|
OXFW_DEV_ENTRY(OUI_STANTON, MODEL_SCS1M, NULL),
|
2021-05-18 17:45:49 +09:00
|
|
|
// Stanton, Stanton Controllers & Systems 1 Deck (SCS.1d).
|
|
|
|
OXFW_DEV_ENTRY(OUI_STANTON, 0x002000, NULL),
|
|
|
|
// APOGEE, duet FireWire.
|
2021-05-18 17:45:57 +09:00
|
|
|
OXFW_DEV_ENTRY(OUI_APOGEE, MODEL_DUET_FW, NULL),
|
2011-03-15 07:53:21 +01:00
|
|
|
{ }
|
|
|
|
};
|
2014-11-29 00:59:25 +09:00
|
|
|
MODULE_DEVICE_TABLE(ieee1394, oxfw_id_table);
|
2011-03-15 07:53:21 +01:00
|
|
|
|
2014-11-29 00:59:25 +09:00
|
|
|
static struct fw_driver oxfw_driver = {
|
2011-03-15 07:53:21 +01:00
|
|
|
.driver = {
|
|
|
|
.owner = THIS_MODULE,
|
|
|
|
.name = KBUILD_MODNAME,
|
|
|
|
.bus = &fw_bus_type,
|
|
|
|
},
|
2014-11-29 00:59:25 +09:00
|
|
|
.probe = oxfw_probe,
|
|
|
|
.update = oxfw_bus_reset,
|
|
|
|
.remove = oxfw_remove,
|
|
|
|
.id_table = oxfw_id_table,
|
2011-03-15 07:53:21 +01:00
|
|
|
};
|
|
|
|
|
2014-11-29 00:59:25 +09:00
|
|
|
static int __init snd_oxfw_init(void)
|
2011-03-15 07:53:21 +01:00
|
|
|
{
|
2014-11-29 00:59:25 +09:00
|
|
|
return driver_register(&oxfw_driver.driver);
|
2011-03-15 07:53:21 +01:00
|
|
|
}
|
|
|
|
|
2014-11-29 00:59:25 +09:00
|
|
|
static void __exit snd_oxfw_exit(void)
|
2011-03-15 07:53:21 +01:00
|
|
|
{
|
2014-11-29 00:59:25 +09:00
|
|
|
driver_unregister(&oxfw_driver.driver);
|
2011-03-15 07:53:21 +01:00
|
|
|
}
|
|
|
|
|
2014-11-29 00:59:25 +09:00
|
|
|
module_init(snd_oxfw_init);
|
|
|
|
module_exit(snd_oxfw_exit);
|