1da607e19SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
2fd6f4b0dSTakashi Sakamoto /*
3fd6f4b0dSTakashi Sakamoto * bebob.c - a part of driver for BeBoB based devices
4fd6f4b0dSTakashi Sakamoto *
5fd6f4b0dSTakashi Sakamoto * Copyright (c) 2013-2014 Takashi Sakamoto
6fd6f4b0dSTakashi Sakamoto */
7fd6f4b0dSTakashi Sakamoto
8fd6f4b0dSTakashi Sakamoto /*
9fd6f4b0dSTakashi Sakamoto * BeBoB is 'BridgeCo enhanced Breakout Box'. This is installed to firewire
10fd6f4b0dSTakashi Sakamoto * devices with DM1000/DM1100/DM1500 chipset. It gives common way for host
11fd6f4b0dSTakashi Sakamoto * system to handle BeBoB based devices.
12fd6f4b0dSTakashi Sakamoto */
13fd6f4b0dSTakashi Sakamoto
14fd6f4b0dSTakashi Sakamoto #include "bebob.h"
15fd6f4b0dSTakashi Sakamoto
16fd6f4b0dSTakashi Sakamoto MODULE_DESCRIPTION("BridgeCo BeBoB driver");
17fd6f4b0dSTakashi Sakamoto MODULE_AUTHOR("Takashi Sakamoto <o-takashi@sakamocchi.jp>");
18*81c29435STakashi Sakamoto MODULE_LICENSE("GPL");
19fd6f4b0dSTakashi Sakamoto
20fd6f4b0dSTakashi Sakamoto static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
21fd6f4b0dSTakashi Sakamoto static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
22fd6f4b0dSTakashi Sakamoto static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
23fd6f4b0dSTakashi Sakamoto
24fd6f4b0dSTakashi Sakamoto module_param_array(index, int, NULL, 0444);
25fd6f4b0dSTakashi Sakamoto MODULE_PARM_DESC(index, "card index");
26fd6f4b0dSTakashi Sakamoto module_param_array(id, charp, NULL, 0444);
27fd6f4b0dSTakashi Sakamoto MODULE_PARM_DESC(id, "ID string");
28fd6f4b0dSTakashi Sakamoto module_param_array(enable, bool, NULL, 0444);
29fd6f4b0dSTakashi Sakamoto MODULE_PARM_DESC(enable, "enable BeBoB sound card");
30fd6f4b0dSTakashi Sakamoto
31fd6f4b0dSTakashi Sakamoto static DEFINE_MUTEX(devices_mutex);
32fd6f4b0dSTakashi Sakamoto static DECLARE_BITMAP(devices_used, SNDRV_CARDS);
33fd6f4b0dSTakashi Sakamoto
34fd6f4b0dSTakashi Sakamoto /* Offsets from information register. */
357b4d7dcfSTakashi Sakamoto #define INFO_OFFSET_BEBOB_VERSION 0x08
36fd6f4b0dSTakashi Sakamoto #define INFO_OFFSET_GUID 0x10
37fd6f4b0dSTakashi Sakamoto #define INFO_OFFSET_HW_MODEL_ID 0x18
38fd6f4b0dSTakashi Sakamoto #define INFO_OFFSET_HW_MODEL_REVISION 0x1c
39fd6f4b0dSTakashi Sakamoto
40fd6f4b0dSTakashi Sakamoto #define VEN_EDIROL 0x000040ab
41fd6f4b0dSTakashi Sakamoto #define VEN_PRESONUS 0x00000a92
42fd6f4b0dSTakashi Sakamoto #define VEN_BRIDGECO 0x000007f5
431b337e8dSTakashi Sakamoto #define VEN_MACKIE 0x00000ff2
44fd6f4b0dSTakashi Sakamoto #define VEN_STANTON 0x00001260
45fd6f4b0dSTakashi Sakamoto #define VEN_TASCAM 0x0000022e
46fd6f4b0dSTakashi Sakamoto #define VEN_BEHRINGER 0x00001564
47fd6f4b0dSTakashi Sakamoto #define VEN_APOGEE 0x000003db
48fd6f4b0dSTakashi Sakamoto #define VEN_ESI 0x00000f1b
49fd6f4b0dSTakashi Sakamoto #define VEN_CME 0x0000000a
50fd6f4b0dSTakashi Sakamoto #define VEN_PHONIC 0x00001496
51fd6f4b0dSTakashi Sakamoto #define VEN_LYNX 0x000019e5
52fd6f4b0dSTakashi Sakamoto #define VEN_ICON 0x00001a9e
53fd6f4b0dSTakashi Sakamoto #define VEN_PRISMSOUND 0x00001198
54326b9cacSTakashi Sakamoto #define VEN_TERRATEC 0x00000aac
558ac98a35STakashi Sakamoto #define VEN_YAMAHA 0x0000a0de
5625784ec2STakashi Sakamoto #define VEN_FOCUSRITE 0x0000130e
57e6b54fbcSTakashi Sakamoto #define VEN_MAUDIO 0x00000d6c
58146a5e3cSTakashi Sakamoto #define VEN_DIGIDESIGN 0x00a07e
5950ebe562STakashi Sakamoto #define OUI_SHOUYO 0x002327
6025784ec2STakashi Sakamoto
6125784ec2STakashi Sakamoto #define MODEL_FOCUSRITE_SAFFIRE_BOTH 0x00000000
629076c22dSTakashi Sakamoto #define MODEL_MAUDIO_AUDIOPHILE_BOTH 0x00010060
633149ac48STakashi Sakamoto #define MODEL_MAUDIO_FW1814 0x00010071
643149ac48STakashi Sakamoto #define MODEL_MAUDIO_PROJECTMIX 0x00010091
655ec85c19STakashi Sakamoto #define MODEL_MAUDIO_PROFIRELIGHTBRIDGE 0x000100a1
66fd6f4b0dSTakashi Sakamoto
67fd6f4b0dSTakashi Sakamoto static int
name_device(struct snd_bebob * bebob)68093dd449STakashi Sakamoto name_device(struct snd_bebob *bebob)
69fd6f4b0dSTakashi Sakamoto {
70fd6f4b0dSTakashi Sakamoto struct fw_device *fw_dev = fw_parent_device(bebob->unit);
71fd6f4b0dSTakashi Sakamoto char vendor[24] = {0};
72fd6f4b0dSTakashi Sakamoto char model[32] = {0};
73791c67b4STakashi Sakamoto u32 hw_id;
74fd6f4b0dSTakashi Sakamoto u32 data[2] = {0};
75fd6f4b0dSTakashi Sakamoto u32 revision;
76fd6f4b0dSTakashi Sakamoto int err;
77fd6f4b0dSTakashi Sakamoto
78fd6f4b0dSTakashi Sakamoto /* get vendor name from root directory */
79fd6f4b0dSTakashi Sakamoto err = fw_csr_string(fw_dev->config_rom + 5, CSR_VENDOR,
80fd6f4b0dSTakashi Sakamoto vendor, sizeof(vendor));
81fd6f4b0dSTakashi Sakamoto if (err < 0)
82fd6f4b0dSTakashi Sakamoto goto end;
83fd6f4b0dSTakashi Sakamoto
84fd6f4b0dSTakashi Sakamoto /* get model name from unit directory */
85fd6f4b0dSTakashi Sakamoto err = fw_csr_string(bebob->unit->directory, CSR_MODEL,
86fd6f4b0dSTakashi Sakamoto model, sizeof(model));
87fd6f4b0dSTakashi Sakamoto if (err < 0)
88fd6f4b0dSTakashi Sakamoto goto end;
89fd6f4b0dSTakashi Sakamoto
90fd6f4b0dSTakashi Sakamoto /* get hardware id */
91fd6f4b0dSTakashi Sakamoto err = snd_bebob_read_quad(bebob->unit, INFO_OFFSET_HW_MODEL_ID,
92791c67b4STakashi Sakamoto &hw_id);
93fd6f4b0dSTakashi Sakamoto if (err < 0)
94fd6f4b0dSTakashi Sakamoto goto end;
95fd6f4b0dSTakashi Sakamoto
96fd6f4b0dSTakashi Sakamoto /* get hardware revision */
97fd6f4b0dSTakashi Sakamoto err = snd_bebob_read_quad(bebob->unit, INFO_OFFSET_HW_MODEL_REVISION,
98fd6f4b0dSTakashi Sakamoto &revision);
99fd6f4b0dSTakashi Sakamoto if (err < 0)
100fd6f4b0dSTakashi Sakamoto goto end;
101fd6f4b0dSTakashi Sakamoto
102fd6f4b0dSTakashi Sakamoto /* get GUID */
103fd6f4b0dSTakashi Sakamoto err = snd_bebob_read_block(bebob->unit, INFO_OFFSET_GUID,
104fd6f4b0dSTakashi Sakamoto data, sizeof(data));
105fd6f4b0dSTakashi Sakamoto if (err < 0)
106fd6f4b0dSTakashi Sakamoto goto end;
107fd6f4b0dSTakashi Sakamoto
108fd6f4b0dSTakashi Sakamoto strcpy(bebob->card->driver, "BeBoB");
109fd6f4b0dSTakashi Sakamoto strcpy(bebob->card->shortname, model);
110fd6f4b0dSTakashi Sakamoto strcpy(bebob->card->mixername, model);
111fd6f4b0dSTakashi Sakamoto snprintf(bebob->card->longname, sizeof(bebob->card->longname),
112fd6f4b0dSTakashi Sakamoto "%s %s (id:%d, rev:%d), GUID %08x%08x at %s, S%d",
113791c67b4STakashi Sakamoto vendor, model, hw_id, revision,
114fd6f4b0dSTakashi Sakamoto data[0], data[1], dev_name(&bebob->unit->device),
115fd6f4b0dSTakashi Sakamoto 100 << fw_dev->max_speed);
116fd6f4b0dSTakashi Sakamoto end:
117fd6f4b0dSTakashi Sakamoto return err;
118fd6f4b0dSTakashi Sakamoto }
119fd6f4b0dSTakashi Sakamoto
1203babca45STakashi Sakamoto static void
bebob_card_free(struct snd_card * card)1213babca45STakashi Sakamoto bebob_card_free(struct snd_card *card)
12204a2c73cSTakashi Sakamoto {
1233babca45STakashi Sakamoto struct snd_bebob *bebob = card->private_data;
1243babca45STakashi Sakamoto
125873608dcSTakashi Sakamoto mutex_lock(&devices_mutex);
126873608dcSTakashi Sakamoto clear_bit(bebob->card_index, devices_used);
127873608dcSTakashi Sakamoto mutex_unlock(&devices_mutex);
128873608dcSTakashi Sakamoto
12904a2c73cSTakashi Sakamoto snd_bebob_stream_destroy_duplex(bebob);
13081bfb89eSTakashi Sakamoto
13181bfb89eSTakashi Sakamoto mutex_destroy(&bebob->mutex);
13281bfb89eSTakashi Sakamoto fw_unit_put(bebob->unit);
13304a2c73cSTakashi Sakamoto }
13404a2c73cSTakashi Sakamoto
13525784ec2STakashi Sakamoto static const struct snd_bebob_spec *
get_saffire_spec(struct fw_unit * unit)13625784ec2STakashi Sakamoto get_saffire_spec(struct fw_unit *unit)
13725784ec2STakashi Sakamoto {
13825784ec2STakashi Sakamoto char name[24] = {0};
13925784ec2STakashi Sakamoto
14025784ec2STakashi Sakamoto if (fw_csr_string(unit->directory, CSR_MODEL, name, sizeof(name)) < 0)
14125784ec2STakashi Sakamoto return NULL;
14225784ec2STakashi Sakamoto
14325784ec2STakashi Sakamoto if (strcmp(name, "SaffireLE") == 0)
14425784ec2STakashi Sakamoto return &saffire_le_spec;
14525784ec2STakashi Sakamoto else
14625784ec2STakashi Sakamoto return &saffire_spec;
14725784ec2STakashi Sakamoto }
14825784ec2STakashi Sakamoto
1499076c22dSTakashi Sakamoto static bool
check_audiophile_booted(struct fw_unit * unit)1509076c22dSTakashi Sakamoto check_audiophile_booted(struct fw_unit *unit)
1519076c22dSTakashi Sakamoto {
1522e57069cSTakashi Sakamoto char name[28] = {0};
1539076c22dSTakashi Sakamoto
1549076c22dSTakashi Sakamoto if (fw_csr_string(unit->directory, CSR_MODEL, name, sizeof(name)) < 0)
1559076c22dSTakashi Sakamoto return false;
1569076c22dSTakashi Sakamoto
1572e57069cSTakashi Sakamoto return strncmp(name, "FW Audiophile Bootloader", 24) != 0;
1589076c22dSTakashi Sakamoto }
1599076c22dSTakashi Sakamoto
detect_quirks(struct snd_bebob * bebob,const struct ieee1394_device_id * entry)16093cd12d6STakashi Sakamoto static int detect_quirks(struct snd_bebob *bebob, const struct ieee1394_device_id *entry)
16193cd12d6STakashi Sakamoto {
162e6b54fbcSTakashi Sakamoto if (entry->vendor_id == VEN_MAUDIO) {
16393cd12d6STakashi Sakamoto switch (entry->model_id) {
16493cd12d6STakashi Sakamoto case MODEL_MAUDIO_PROFIRELIGHTBRIDGE:
16593cd12d6STakashi Sakamoto // M-Audio ProFire Lightbridge has a quirk to transfer packets with
16693cd12d6STakashi Sakamoto // discontinuous cycle or data block counter in early stage of packet
16793cd12d6STakashi Sakamoto // streaming. The cycle span from the first packet with event is variable.
16893cd12d6STakashi Sakamoto bebob->quirks |= SND_BEBOB_QUIRK_INITIAL_DISCONTINUOUS_DBC;
16993cd12d6STakashi Sakamoto break;
17093cd12d6STakashi Sakamoto case MODEL_MAUDIO_FW1814:
17193cd12d6STakashi Sakamoto case MODEL_MAUDIO_PROJECTMIX:
17293cd12d6STakashi Sakamoto // At high sampling rate, M-Audio special firmware transmits empty packet
17393cd12d6STakashi Sakamoto // with the value of dbc incremented by 8.
17493cd12d6STakashi Sakamoto bebob->quirks |= SND_BEBOB_QUIRK_WRONG_DBC;
17593cd12d6STakashi Sakamoto break;
17693cd12d6STakashi Sakamoto default:
17793cd12d6STakashi Sakamoto break;
17893cd12d6STakashi Sakamoto }
17993cd12d6STakashi Sakamoto }
18093cd12d6STakashi Sakamoto
18193cd12d6STakashi Sakamoto return 0;
18293cd12d6STakashi Sakamoto }
18393cd12d6STakashi Sakamoto
bebob_probe(struct fw_unit * unit,const struct ieee1394_device_id * entry)18481bfb89eSTakashi Sakamoto static int bebob_probe(struct fw_unit *unit, const struct ieee1394_device_id *entry)
185fd6f4b0dSTakashi Sakamoto {
186fd6f4b0dSTakashi Sakamoto unsigned int card_index;
18781bfb89eSTakashi Sakamoto struct snd_card *card;
18881bfb89eSTakashi Sakamoto struct snd_bebob *bebob;
18981bfb89eSTakashi Sakamoto const struct snd_bebob_spec *spec;
190fd6f4b0dSTakashi Sakamoto int err;
191fd6f4b0dSTakashi Sakamoto
19281bfb89eSTakashi Sakamoto if (entry->vendor_id == VEN_FOCUSRITE &&
19381bfb89eSTakashi Sakamoto entry->model_id == MODEL_FOCUSRITE_SAFFIRE_BOTH)
19481bfb89eSTakashi Sakamoto spec = get_saffire_spec(unit);
195e6b54fbcSTakashi Sakamoto else if (entry->vendor_id == VEN_MAUDIO &&
19681bfb89eSTakashi Sakamoto entry->model_id == MODEL_MAUDIO_AUDIOPHILE_BOTH &&
19781bfb89eSTakashi Sakamoto !check_audiophile_booted(unit))
19881bfb89eSTakashi Sakamoto spec = NULL;
19981bfb89eSTakashi Sakamoto else
20081bfb89eSTakashi Sakamoto spec = (const struct snd_bebob_spec *)entry->driver_data;
20181bfb89eSTakashi Sakamoto
20281bfb89eSTakashi Sakamoto if (spec == NULL) {
203e6b54fbcSTakashi Sakamoto // To boot up M-Audio models.
204e6b54fbcSTakashi Sakamoto if (entry->vendor_id == VEN_MAUDIO || entry->vendor_id == VEN_BRIDGECO)
20581bfb89eSTakashi Sakamoto return snd_bebob_maudio_load_firmware(unit);
20681bfb89eSTakashi Sakamoto else
20781bfb89eSTakashi Sakamoto return -ENODEV;
20881bfb89eSTakashi Sakamoto }
20904a2c73cSTakashi Sakamoto
210fd6f4b0dSTakashi Sakamoto mutex_lock(&devices_mutex);
211fd6f4b0dSTakashi Sakamoto for (card_index = 0; card_index < SNDRV_CARDS; card_index++) {
212fd6f4b0dSTakashi Sakamoto if (!test_bit(card_index, devices_used) && enable[card_index])
213fd6f4b0dSTakashi Sakamoto break;
214fd6f4b0dSTakashi Sakamoto }
215fd6f4b0dSTakashi Sakamoto if (card_index >= SNDRV_CARDS) {
21604a2c73cSTakashi Sakamoto mutex_unlock(&devices_mutex);
21781bfb89eSTakashi Sakamoto return -ENOENT;
218fd6f4b0dSTakashi Sakamoto }
219fd6f4b0dSTakashi Sakamoto
22081bfb89eSTakashi Sakamoto err = snd_card_new(&unit->device, index[card_index], id[card_index], THIS_MODULE,
22181bfb89eSTakashi Sakamoto sizeof(*bebob), &card);
22204a2c73cSTakashi Sakamoto if (err < 0) {
22304a2c73cSTakashi Sakamoto mutex_unlock(&devices_mutex);
22481bfb89eSTakashi Sakamoto return err;
2251fc9522aSTakashi Sakamoto }
22681bfb89eSTakashi Sakamoto card->private_free = bebob_card_free;
227873608dcSTakashi Sakamoto set_bit(card_index, devices_used);
228873608dcSTakashi Sakamoto mutex_unlock(&devices_mutex);
2291fc9522aSTakashi Sakamoto
23081bfb89eSTakashi Sakamoto bebob = card->private_data;
23181bfb89eSTakashi Sakamoto bebob->unit = fw_unit_get(unit);
23281bfb89eSTakashi Sakamoto dev_set_drvdata(&unit->device, bebob);
23381bfb89eSTakashi Sakamoto bebob->card = card;
23481bfb89eSTakashi Sakamoto bebob->card_index = card_index;
23581bfb89eSTakashi Sakamoto
23681bfb89eSTakashi Sakamoto bebob->spec = spec;
23781bfb89eSTakashi Sakamoto mutex_init(&bebob->mutex);
23881bfb89eSTakashi Sakamoto spin_lock_init(&bebob->lock);
23981bfb89eSTakashi Sakamoto init_waitqueue_head(&bebob->hwdep_wait);
2403babca45STakashi Sakamoto
241093dd449STakashi Sakamoto err = name_device(bebob);
242fd6f4b0dSTakashi Sakamoto if (err < 0)
243fd6f4b0dSTakashi Sakamoto goto error;
244fd6f4b0dSTakashi Sakamoto
24593cd12d6STakashi Sakamoto err = detect_quirks(bebob, entry);
24693cd12d6STakashi Sakamoto if (err < 0)
24793cd12d6STakashi Sakamoto goto error;
24893cd12d6STakashi Sakamoto
24904a2c73cSTakashi Sakamoto if (bebob->spec == &maudio_special_spec) {
25081bfb89eSTakashi Sakamoto if (entry->model_id == MODEL_MAUDIO_FW1814)
2513149ac48STakashi Sakamoto err = snd_bebob_maudio_special_discover(bebob, true);
2523149ac48STakashi Sakamoto else
25304a2c73cSTakashi Sakamoto err = snd_bebob_maudio_special_discover(bebob, false);
25404a2c73cSTakashi Sakamoto } else {
255eb7b3a05STakashi Sakamoto err = snd_bebob_stream_discover(bebob);
25604a2c73cSTakashi Sakamoto }
25704a2c73cSTakashi Sakamoto if (err < 0)
25804a2c73cSTakashi Sakamoto goto error;
25904a2c73cSTakashi Sakamoto
26004a2c73cSTakashi Sakamoto err = snd_bebob_stream_init_duplex(bebob);
261fd6f4b0dSTakashi Sakamoto if (err < 0)
262fd6f4b0dSTakashi Sakamoto goto error;
263eb7b3a05STakashi Sakamoto
264ad9697baSTakashi Sakamoto snd_bebob_proc_init(bebob);
265ad9697baSTakashi Sakamoto
26604a2c73cSTakashi Sakamoto if (bebob->midi_input_ports > 0 || bebob->midi_output_ports > 0) {
267248b7802STakashi Sakamoto err = snd_bebob_create_midi_devices(bebob);
268248b7802STakashi Sakamoto if (err < 0)
269248b7802STakashi Sakamoto goto error;
270248b7802STakashi Sakamoto }
271248b7802STakashi Sakamoto
272fbbebd2cSTakashi Sakamoto err = snd_bebob_create_pcm_devices(bebob);
273fbbebd2cSTakashi Sakamoto if (err < 0)
274fbbebd2cSTakashi Sakamoto goto error;
275fbbebd2cSTakashi Sakamoto
276618eabeaSTakashi Sakamoto err = snd_bebob_create_hwdep_device(bebob);
277618eabeaSTakashi Sakamoto if (err < 0)
278618eabeaSTakashi Sakamoto goto error;
279618eabeaSTakashi Sakamoto
28081bfb89eSTakashi Sakamoto err = snd_card_register(card);
281eb7b3a05STakashi Sakamoto if (err < 0)
282eb7b3a05STakashi Sakamoto goto error;
283eb7b3a05STakashi Sakamoto
284e6b54fbcSTakashi Sakamoto if (entry->vendor_id == VEN_MAUDIO &&
28581bfb89eSTakashi Sakamoto (entry->model_id == MODEL_MAUDIO_FW1814 || entry->model_id == MODEL_MAUDIO_PROJECTMIX)) {
28681bfb89eSTakashi Sakamoto // This is a workaround. This bus reset seems to have an effect to make devices
28781bfb89eSTakashi Sakamoto // correctly handling transactions. Without this, the devices have gap_count
28881bfb89eSTakashi Sakamoto // mismatch. This causes much failure of transaction.
28981bfb89eSTakashi Sakamoto //
29081bfb89eSTakashi Sakamoto // Just after registration, user-land application receive signals from dbus and
29181bfb89eSTakashi Sakamoto // starts I/Os. To avoid I/Os till the future bus reset, registration is done in
29281bfb89eSTakashi Sakamoto // next update().
29381bfb89eSTakashi Sakamoto fw_schedule_bus_reset(fw_parent_device(bebob->unit)->card, false, true);
2949b1ee0b2STakashi Sakamoto }
295eb7b3a05STakashi Sakamoto
29604a2c73cSTakashi Sakamoto return 0;
29781bfb89eSTakashi Sakamoto error:
29881bfb89eSTakashi Sakamoto snd_card_free(card);
29981bfb89eSTakashi Sakamoto return err;
300fd6f4b0dSTakashi Sakamoto }
301fd6f4b0dSTakashi Sakamoto
3023800e6f9STakashi Sakamoto /*
3033800e6f9STakashi Sakamoto * This driver doesn't update streams in bus reset handler.
3043800e6f9STakashi Sakamoto *
3053800e6f9STakashi Sakamoto * DM1000/ DM1100/DM1500 chipsets with BeBoB firmware transfer packets with
3063800e6f9STakashi Sakamoto * discontinued counter at bus reset. This discontinuity is immediately
3073800e6f9STakashi Sakamoto * detected in packet streaming layer, then it sets XRUN to PCM substream.
3083800e6f9STakashi Sakamoto *
3093800e6f9STakashi Sakamoto * ALSA PCM applications can know the XRUN by getting -EPIPE from PCM operation.
3103800e6f9STakashi Sakamoto * Then, they can recover the PCM substream by executing ioctl(2) with
3113800e6f9STakashi Sakamoto * SNDRV_PCM_IOCTL_PREPARE. 'struct snd_pcm_ops.prepare' is called and drivers
3123800e6f9STakashi Sakamoto * restart packet streaming.
3133800e6f9STakashi Sakamoto *
3143800e6f9STakashi Sakamoto * The above processing may be executed before this bus-reset handler is
3153800e6f9STakashi Sakamoto * executed. When this handler updates streams with current isochronous
3163800e6f9STakashi Sakamoto * channels, the streams already have the current ones.
3173800e6f9STakashi Sakamoto */
318fd6f4b0dSTakashi Sakamoto static void
bebob_update(struct fw_unit * unit)319fd6f4b0dSTakashi Sakamoto bebob_update(struct fw_unit *unit)
320fd6f4b0dSTakashi Sakamoto {
321fd6f4b0dSTakashi Sakamoto struct snd_bebob *bebob = dev_get_drvdata(&unit->device);
3229076c22dSTakashi Sakamoto
3239076c22dSTakashi Sakamoto if (bebob == NULL)
3249076c22dSTakashi Sakamoto return;
3259076c22dSTakashi Sakamoto
326fd6f4b0dSTakashi Sakamoto fcp_bus_reset(bebob->unit);
327fd6f4b0dSTakashi Sakamoto }
328fd6f4b0dSTakashi Sakamoto
bebob_remove(struct fw_unit * unit)329fd6f4b0dSTakashi Sakamoto static void bebob_remove(struct fw_unit *unit)
330fd6f4b0dSTakashi Sakamoto {
331fd6f4b0dSTakashi Sakamoto struct snd_bebob *bebob = dev_get_drvdata(&unit->device);
3329076c22dSTakashi Sakamoto
3339076c22dSTakashi Sakamoto if (bebob == NULL)
3349076c22dSTakashi Sakamoto return;
3359076c22dSTakashi Sakamoto
33661ccc6f6STakashi Sakamoto // Block till all of ALSA character devices are released.
33761ccc6f6STakashi Sakamoto snd_card_free(bebob->card);
33804a2c73cSTakashi Sakamoto }
3395b14ec25STakashi Sakamoto
3406b9866c8SJulia Lawall static const struct snd_bebob_rate_spec normal_rate_spec = {
3411fc9522aSTakashi Sakamoto .get = &snd_bebob_stream_get_rate,
3421fc9522aSTakashi Sakamoto .set = &snd_bebob_stream_set_rate
3431fc9522aSTakashi Sakamoto };
3441fc9522aSTakashi Sakamoto static const struct snd_bebob_spec spec_normal = {
3451fc9522aSTakashi Sakamoto .clock = NULL,
3461fc9522aSTakashi Sakamoto .rate = &normal_rate_spec,
3471fc9522aSTakashi Sakamoto .meter = NULL
3481fc9522aSTakashi Sakamoto };
3491fc9522aSTakashi Sakamoto
350270e6012STakashi Sakamoto #define SPECIFIER_1394TA 0x00a02d
351270e6012STakashi Sakamoto
352270e6012STakashi Sakamoto // The immediate entry for version in unit directory differs depending on models:
353270e6012STakashi Sakamoto // * 0x010001
354270e6012STakashi Sakamoto // * 0x014001
355270e6012STakashi Sakamoto #define SND_BEBOB_DEV_ENTRY(vendor, model, data) \
356270e6012STakashi Sakamoto { \
357270e6012STakashi Sakamoto .match_flags = IEEE1394_MATCH_VENDOR_ID | \
358270e6012STakashi Sakamoto IEEE1394_MATCH_MODEL_ID | \
359270e6012STakashi Sakamoto IEEE1394_MATCH_SPECIFIER_ID, \
360270e6012STakashi Sakamoto .vendor_id = vendor, \
361270e6012STakashi Sakamoto .model_id = model, \
362270e6012STakashi Sakamoto .specifier_id = SPECIFIER_1394TA, \
363270e6012STakashi Sakamoto .driver_data = (kernel_ulong_t)data \
364270e6012STakashi Sakamoto }
365270e6012STakashi Sakamoto
366fd6f4b0dSTakashi Sakamoto static const struct ieee1394_device_id bebob_id_table[] = {
367fd6f4b0dSTakashi Sakamoto /* Edirol, FA-66 */
3681fc9522aSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_EDIROL, 0x00010049, &spec_normal),
369fd6f4b0dSTakashi Sakamoto /* Edirol, FA-101 */
3701fc9522aSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_EDIROL, 0x00010048, &spec_normal),
371fd6f4b0dSTakashi Sakamoto /* Presonus, FIREBOX */
3721fc9522aSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_PRESONUS, 0x00010000, &spec_normal),
373fd6f4b0dSTakashi Sakamoto /* PreSonus, FIREPOD/FP10 */
3741fc9522aSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_PRESONUS, 0x00010066, &spec_normal),
375fd6f4b0dSTakashi Sakamoto /* PreSonus, Inspire1394 */
3761fc9522aSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_PRESONUS, 0x00010001, &spec_normal),
377fd6f4b0dSTakashi Sakamoto /* BridgeCo, RDAudio1 */
3781fc9522aSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_BRIDGECO, 0x00010048, &spec_normal),
379fd6f4b0dSTakashi Sakamoto /* BridgeCo, Audio5 */
3801fc9522aSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_BRIDGECO, 0x00010049, &spec_normal),
381fd6f4b0dSTakashi Sakamoto /* Mackie, Onyx 1220/1620/1640 (Firewire I/O Card) */
3821b337e8dSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_MACKIE, 0x00010065, &spec_normal),
3835d6fb80aSTakashi Sakamoto // Mackie, d.2 (optional Firewire card with DM1000).
3841b337e8dSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_MACKIE, 0x00010067, &spec_normal),
385fd6f4b0dSTakashi Sakamoto /* Stanton, ScratchAmp */
3861fc9522aSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_STANTON, 0x00000001, &spec_normal),
387fd6f4b0dSTakashi Sakamoto /* Tascam, IF-FW DM */
3881fc9522aSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_TASCAM, 0x00010067, &spec_normal),
389fd6f4b0dSTakashi Sakamoto /* Behringer, XENIX UFX 1204 */
3901fc9522aSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_BEHRINGER, 0x00001204, &spec_normal),
391fd6f4b0dSTakashi Sakamoto /* Behringer, XENIX UFX 1604 */
3921fc9522aSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_BEHRINGER, 0x00001604, &spec_normal),
393fd6f4b0dSTakashi Sakamoto /* Behringer, Digital Mixer X32 series (X-UF Card) */
3941fc9522aSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_BEHRINGER, 0x00000006, &spec_normal),
395cf8a4719STakashi Sakamoto /* Behringer, F-Control Audio 1616 */
396cf8a4719STakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_BEHRINGER, 0x001616, &spec_normal),
397cf8a4719STakashi Sakamoto /* Behringer, F-Control Audio 610 */
398cf8a4719STakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_BEHRINGER, 0x000610, &spec_normal),
399fd6f4b0dSTakashi Sakamoto /* Apogee Electronics, Rosetta 200/400 (X-FireWire card) */
400fd6f4b0dSTakashi Sakamoto /* Apogee Electronics, DA/AD/DD-16X (X-FireWire card) */
4011fc9522aSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_APOGEE, 0x00010048, &spec_normal),
402fd6f4b0dSTakashi Sakamoto /* Apogee Electronics, Ensemble */
403644b2e97STakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_APOGEE, 0x01eeee, &spec_normal),
404fd6f4b0dSTakashi Sakamoto /* ESI, Quatafire610 */
4051fc9522aSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_ESI, 0x00010064, &spec_normal),
406fd6f4b0dSTakashi Sakamoto /* CME, MatrixKFW */
4071fc9522aSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_CME, 0x00030000, &spec_normal),
4081586d461STakashi Sakamoto // Phonic Helix Board 12 FireWire MkII.
4091fc9522aSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_PHONIC, 0x00050000, &spec_normal),
4101586d461STakashi Sakamoto // Phonic Helix Board 18 FireWire MkII.
4111fc9522aSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_PHONIC, 0x00060000, &spec_normal),
4121586d461STakashi Sakamoto // Phonic Helix Board 24 FireWire MkII.
4131fc9522aSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_PHONIC, 0x00070000, &spec_normal),
4141586d461STakashi Sakamoto // Phonic FireFly 808 FireWire.
4151586d461STakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_PHONIC, 0x00080000, &spec_normal),
4161586d461STakashi Sakamoto // Phonic FireFly 202, 302, 808 Universal.
4171586d461STakashi Sakamoto // Phinic Helix Board 12/18/24 FireWire, 12/18/24 Universal
4181fc9522aSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_PHONIC, 0x00000000, &spec_normal),
419fd6f4b0dSTakashi Sakamoto /* Lynx, Aurora 8/16 (LT-FW) */
4201fc9522aSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_LYNX, 0x00000001, &spec_normal),
421fd6f4b0dSTakashi Sakamoto /* ICON, FireXon */
4221fc9522aSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_ICON, 0x00000001, &spec_normal),
423fd6f4b0dSTakashi Sakamoto /* PrismSound, Orpheus */
4241fc9522aSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_PRISMSOUND, 0x00010048, &spec_normal),
425fd6f4b0dSTakashi Sakamoto /* PrismSound, ADA-8XR */
4261fc9522aSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_PRISMSOUND, 0x0000ada8, &spec_normal),
427326b9cacSTakashi Sakamoto /* TerraTec Electronic GmbH, PHASE 88 Rack FW */
428326b9cacSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_TERRATEC, 0x00000003, &phase88_rack_spec),
429326b9cacSTakashi Sakamoto /* TerraTec Electronic GmbH, PHASE 24 FW */
430e15c282eSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_TERRATEC, 0x00000004, &yamaha_terratec_spec),
431326b9cacSTakashi Sakamoto /* TerraTec Electronic GmbH, Phase X24 FW */
432e15c282eSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_TERRATEC, 0x00000007, &yamaha_terratec_spec),
433326b9cacSTakashi Sakamoto /* TerraTec Electronic GmbH, EWS MIC2/MIC8 */
434326b9cacSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_TERRATEC, 0x00000005, &spec_normal),
435a07ebc7eSTakashi Sakamoto // Terratec Electronic GmbH, Aureon 7.1 Firewire.
436a07ebc7eSTakashi Sakamoto // AcousticReality, eAR Master One, Eroica, Figaro, and Ciaccona. Perhaps Terratec OEM.
437326b9cacSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_TERRATEC, 0x00000002, &spec_normal),
4388ac98a35STakashi Sakamoto /* Yamaha, GO44 */
439e15c282eSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_YAMAHA, 0x0010000b, &yamaha_terratec_spec),
4408ac98a35STakashi Sakamoto /* YAMAHA, GO46 */
441e15c282eSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_YAMAHA, 0x0010000c, &yamaha_terratec_spec),
44225784ec2STakashi Sakamoto /* Focusrite, SaffirePro 26 I/O */
44325784ec2STakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_FOCUSRITE, 0x00000003, &saffirepro_26_spec),
44425784ec2STakashi Sakamoto /* Focusrite, SaffirePro 10 I/O */
445270e6012STakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_FOCUSRITE, 0x000006, &saffirepro_10_spec),
44625784ec2STakashi Sakamoto /* Focusrite, Saffire(no label and LE) */
44725784ec2STakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_FOCUSRITE, MODEL_FOCUSRITE_SAFFIRE_BOTH,
44825784ec2STakashi Sakamoto &saffire_spec),
449e6b54fbcSTakashi Sakamoto // M-Audio, Firewire 410. The vendor field is left as BridgeCo. AG.
450e6b54fbcSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_BRIDGECO, 0x00010058, NULL),
451e6b54fbcSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_BRIDGECO, 0x00010046, &maudio_fw410_spec),
4529076c22dSTakashi Sakamoto /* M-Audio, Firewire Audiophile */
453e6b54fbcSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_MAUDIO, MODEL_MAUDIO_AUDIOPHILE_BOTH,
4549076c22dSTakashi Sakamoto &maudio_audiophile_spec),
4559076c22dSTakashi Sakamoto /* M-Audio, Firewire Solo */
456e6b54fbcSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_MAUDIO, 0x00010062, &maudio_solo_spec),
4579076c22dSTakashi Sakamoto /* M-Audio, Ozonic */
458e6b54fbcSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_MAUDIO, 0x0000000a, &maudio_ozonic_spec),
4599076c22dSTakashi Sakamoto /* M-Audio NRV10 */
460e6b54fbcSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_MAUDIO, 0x00010081, &maudio_nrv10_spec),
4619076c22dSTakashi Sakamoto /* M-Audio, ProFireLightbridge */
462e6b54fbcSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_MAUDIO, MODEL_MAUDIO_PROFIRELIGHTBRIDGE, &spec_normal),
4633149ac48STakashi Sakamoto /* Firewire 1814 */
464e6b54fbcSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_MAUDIO, 0x00010070, NULL), /* bootloader */
465e6b54fbcSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_MAUDIO, MODEL_MAUDIO_FW1814,
4663149ac48STakashi Sakamoto &maudio_special_spec),
4673149ac48STakashi Sakamoto /* M-Audio ProjectMix */
468e6b54fbcSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_MAUDIO, MODEL_MAUDIO_PROJECTMIX,
4693149ac48STakashi Sakamoto &maudio_special_spec),
470146a5e3cSTakashi Sakamoto /* Digidesign Mbox 2 Pro */
471146a5e3cSTakashi Sakamoto SND_BEBOB_DEV_ENTRY(VEN_DIGIDESIGN, 0x0000a9, &spec_normal),
47250ebe562STakashi Sakamoto // Toneweal FW66.
47350ebe562STakashi Sakamoto SND_BEBOB_DEV_ENTRY(OUI_SHOUYO, 0x020002, &spec_normal),
474fd6f4b0dSTakashi Sakamoto /* IDs are unknown but able to be supported */
475fd6f4b0dSTakashi Sakamoto /* Apogee, Mini-ME Firewire */
476fd6f4b0dSTakashi Sakamoto /* Apogee, Mini-DAC Firewire */
477fd6f4b0dSTakashi Sakamoto /* Cakawalk, Sonar Power Studio 66 */
478fd6f4b0dSTakashi Sakamoto /* CME, UF400e */
479fd6f4b0dSTakashi Sakamoto /* ESI, Quotafire XL */
480fd6f4b0dSTakashi Sakamoto /* Infrasonic, DewX */
481fd6f4b0dSTakashi Sakamoto /* Infrasonic, Windy6 */
482fd6f4b0dSTakashi Sakamoto /* Mackie, Digital X Bus x.200 */
483fd6f4b0dSTakashi Sakamoto /* Mackie, Digital X Bus x.400 */
484fd6f4b0dSTakashi Sakamoto /* Rolf Spuler, Firewire Guitar */
485fd6f4b0dSTakashi Sakamoto {}
486fd6f4b0dSTakashi Sakamoto };
487fd6f4b0dSTakashi Sakamoto MODULE_DEVICE_TABLE(ieee1394, bebob_id_table);
488fd6f4b0dSTakashi Sakamoto
489fd6f4b0dSTakashi Sakamoto static struct fw_driver bebob_driver = {
490fd6f4b0dSTakashi Sakamoto .driver = {
491fd6f4b0dSTakashi Sakamoto .owner = THIS_MODULE,
4929c0d16acSTakashi Sakamoto .name = KBUILD_MODNAME,
493fd6f4b0dSTakashi Sakamoto .bus = &fw_bus_type,
494fd6f4b0dSTakashi Sakamoto },
495fd6f4b0dSTakashi Sakamoto .probe = bebob_probe,
496fd6f4b0dSTakashi Sakamoto .update = bebob_update,
497fd6f4b0dSTakashi Sakamoto .remove = bebob_remove,
498fd6f4b0dSTakashi Sakamoto .id_table = bebob_id_table,
499fd6f4b0dSTakashi Sakamoto };
500fd6f4b0dSTakashi Sakamoto
501fd6f4b0dSTakashi Sakamoto static int __init
snd_bebob_init(void)502fd6f4b0dSTakashi Sakamoto snd_bebob_init(void)
503fd6f4b0dSTakashi Sakamoto {
504fd6f4b0dSTakashi Sakamoto return driver_register(&bebob_driver.driver);
505fd6f4b0dSTakashi Sakamoto }
506fd6f4b0dSTakashi Sakamoto
507fd6f4b0dSTakashi Sakamoto static void __exit
snd_bebob_exit(void)508fd6f4b0dSTakashi Sakamoto snd_bebob_exit(void)
509fd6f4b0dSTakashi Sakamoto {
510fd6f4b0dSTakashi Sakamoto driver_unregister(&bebob_driver.driver);
511fd6f4b0dSTakashi Sakamoto }
512fd6f4b0dSTakashi Sakamoto
513fd6f4b0dSTakashi Sakamoto module_init(snd_bebob_init);
514fd6f4b0dSTakashi Sakamoto module_exit(snd_bebob_exit);
515