xref: /openbmc/linux/sound/firewire/bebob/bebob.c (revision 81c29435)
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