1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * oxfw.c - a part of driver for OXFW970/971 based devices
4 *
5 * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
6 */
7
8#include "oxfw.h"
9
10#define OXFORD_FIRMWARE_ID_ADDRESS	(CSR_REGISTER_BASE + 0x50000)
11/* 0x970?vvvv or 0x971?vvvv, where vvvv = firmware version */
12
13#define OXFORD_HARDWARE_ID_ADDRESS	(CSR_REGISTER_BASE + 0x90020)
14#define OXFORD_HARDWARE_ID_OXFW970	0x39443841
15#define OXFORD_HARDWARE_ID_OXFW971	0x39373100
16
17#define VENDOR_LOUD		0x000ff2
18#define VENDOR_GRIFFIN		0x001292
19#define VENDOR_BEHRINGER	0x001564
20#define VENDOR_LACIE		0x00d04b
21#define VENDOR_TASCAM		0x00022e
22#define OUI_STANTON		0x001260
23#define OUI_APOGEE		0x0003db
24
25#define MODEL_SATELLITE		0x00200f
26
27#define SPECIFIER_1394TA	0x00a02d
28#define VERSION_AVC		0x010001
29
30MODULE_DESCRIPTION("Oxford Semiconductor FW970/971 driver");
31MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
32MODULE_LICENSE("GPL v2");
33MODULE_ALIAS("snd-firewire-speakers");
34MODULE_ALIAS("snd-scs1x");
35
36struct compat_info {
37	const char *driver_name;
38	const char *vendor_name;
39	const char *model_name;
40};
41
42static bool detect_loud_models(struct fw_unit *unit)
43{
44	const char *const models[] = {
45		"Onyxi",
46		"Onyx-i",
47		"Onyx 1640i",
48		"d.Pro",
49		"Mackie Onyx Satellite",
50		"Tapco LINK.firewire 4x6",
51		"U.420"};
52	char model[32];
53	int err;
54
55	err = fw_csr_string(unit->directory, CSR_MODEL,
56			    model, sizeof(model));
57	if (err < 0)
58		return false;
59
60	return match_string(models, ARRAY_SIZE(models), model) >= 0;
61}
62
63static int name_card(struct snd_oxfw *oxfw)
64{
65	struct fw_device *fw_dev = fw_parent_device(oxfw->unit);
66	const struct compat_info *info;
67	char vendor[24];
68	char model[32];
69	const char *d, *v, *m;
70	u32 firmware;
71	int err;
72
73	/* get vendor name from root directory */
74	err = fw_csr_string(fw_dev->config_rom + 5, CSR_VENDOR,
75			    vendor, sizeof(vendor));
76	if (err < 0)
77		goto end;
78
79	/* get model name from unit directory */
80	err = fw_csr_string(oxfw->unit->directory, CSR_MODEL,
81			    model, sizeof(model));
82	if (err < 0)
83		goto end;
84
85	err = snd_fw_transaction(oxfw->unit, TCODE_READ_QUADLET_REQUEST,
86				 OXFORD_FIRMWARE_ID_ADDRESS, &firmware, 4, 0);
87	if (err < 0)
88		goto end;
89	be32_to_cpus(&firmware);
90
91	/* to apply card definitions */
92	if (oxfw->entry->vendor_id == VENDOR_GRIFFIN ||
93	    oxfw->entry->vendor_id == VENDOR_LACIE) {
94		info = (const struct compat_info *)oxfw->entry->driver_data;
95		d = info->driver_name;
96		v = info->vendor_name;
97		m = info->model_name;
98	} else {
99		d = "OXFW";
100		v = vendor;
101		m = model;
102	}
103
104	strcpy(oxfw->card->driver, d);
105	strcpy(oxfw->card->mixername, m);
106	strcpy(oxfw->card->shortname, m);
107
108	snprintf(oxfw->card->longname, sizeof(oxfw->card->longname),
109		 "%s %s (OXFW%x %04x), GUID %08x%08x at %s, S%d",
110		 v, m, firmware >> 20, firmware & 0xffff,
111		 fw_dev->config_rom[3], fw_dev->config_rom[4],
112		 dev_name(&oxfw->unit->device), 100 << fw_dev->max_speed);
113end:
114	return err;
115}
116
117static void oxfw_card_free(struct snd_card *card)
118{
119	struct snd_oxfw *oxfw = card->private_data;
120
121	if (oxfw->has_output || oxfw->has_input)
122		snd_oxfw_stream_destroy_duplex(oxfw);
123}
124
125static int detect_quirks(struct snd_oxfw *oxfw)
126{
127	struct fw_device *fw_dev = fw_parent_device(oxfw->unit);
128	struct fw_csr_iterator it;
129	int key, val;
130	int vendor, model;
131
132	/*
133	 * Add ALSA control elements for two models to keep compatibility to
134	 * old firewire-speaker module.
135	 */
136	if (oxfw->entry->vendor_id == VENDOR_GRIFFIN)
137		return snd_oxfw_add_spkr(oxfw, false);
138	if (oxfw->entry->vendor_id == VENDOR_LACIE)
139		return snd_oxfw_add_spkr(oxfw, true);
140
141	/*
142	 * Stanton models supports asynchronous transactions for unique MIDI
143	 * messages.
144	 */
145	if (oxfw->entry->vendor_id == OUI_STANTON) {
146		/* No physical MIDI ports. */
147		oxfw->midi_input_ports = 0;
148		oxfw->midi_output_ports = 0;
149
150		return snd_oxfw_scs1x_add(oxfw);
151	}
152
153	/*
154	 * TASCAM FireOne has physical control and requires a pair of additional
155	 * MIDI ports.
156	 */
157	if (oxfw->entry->vendor_id == VENDOR_TASCAM) {
158		oxfw->midi_input_ports++;
159		oxfw->midi_output_ports++;
160		return 0;
161	}
162
163	/* Seek from Root Directory of Config ROM. */
164	vendor = model = 0;
165	fw_csr_iterator_init(&it, fw_dev->config_rom + 5);
166	while (fw_csr_iterator_next(&it, &key, &val)) {
167		if (key == CSR_VENDOR)
168			vendor = val;
169		else if (key == CSR_MODEL)
170			model = val;
171	}
172
173	/*
174	 * Mackie Onyx Satellite with base station has a quirk to report a wrong
175	 * value in 'dbs' field of CIP header against its format information.
176	 */
177	if (vendor == VENDOR_LOUD && model == MODEL_SATELLITE)
178		oxfw->wrong_dbs = true;
179
180	return 0;
181}
182
183static void do_registration(struct work_struct *work)
184{
185	struct snd_oxfw *oxfw = container_of(work, struct snd_oxfw, dwork.work);
186	int err;
187
188	if (oxfw->registered)
189		return;
190
191	err = snd_card_new(&oxfw->unit->device, -1, NULL, THIS_MODULE, 0,
192			   &oxfw->card);
193	if (err < 0)
194		return;
195	oxfw->card->private_free = oxfw_card_free;
196	oxfw->card->private_data = oxfw;
197
198	err = name_card(oxfw);
199	if (err < 0)
200		goto error;
201
202	err = snd_oxfw_stream_discover(oxfw);
203	if (err < 0)
204		goto error;
205
206	err = detect_quirks(oxfw);
207	if (err < 0)
208		goto error;
209
210	if (oxfw->has_output || oxfw->has_input) {
211		err = snd_oxfw_stream_init_duplex(oxfw);
212		if (err < 0)
213			goto error;
214
215		err = snd_oxfw_create_pcm(oxfw);
216		if (err < 0)
217			goto error;
218
219		snd_oxfw_proc_init(oxfw);
220
221		err = snd_oxfw_create_midi(oxfw);
222		if (err < 0)
223			goto error;
224
225		err = snd_oxfw_create_hwdep(oxfw);
226		if (err < 0)
227			goto error;
228	}
229
230	err = snd_card_register(oxfw->card);
231	if (err < 0)
232		goto error;
233
234	oxfw->registered = true;
235
236	return;
237error:
238	snd_card_free(oxfw->card);
239	dev_info(&oxfw->unit->device,
240		 "Sound card registration failed: %d\n", err);
241}
242
243static int oxfw_probe(struct fw_unit *unit,
244		      const struct ieee1394_device_id *entry)
245{
246	struct snd_oxfw *oxfw;
247
248	if (entry->vendor_id == VENDOR_LOUD && !detect_loud_models(unit))
249		return -ENODEV;
250
251	/* Allocate this independent of sound card instance. */
252	oxfw = devm_kzalloc(&unit->device, sizeof(struct snd_oxfw), GFP_KERNEL);
253	if (!oxfw)
254		return -ENOMEM;
255	oxfw->unit = fw_unit_get(unit);
256	dev_set_drvdata(&unit->device, oxfw);
257
258	oxfw->entry = entry;
259	mutex_init(&oxfw->mutex);
260	spin_lock_init(&oxfw->lock);
261	init_waitqueue_head(&oxfw->hwdep_wait);
262
263	/* Allocate and register this sound card later. */
264	INIT_DEFERRABLE_WORK(&oxfw->dwork, do_registration);
265	snd_fw_schedule_registration(unit, &oxfw->dwork);
266
267	return 0;
268}
269
270static void oxfw_bus_reset(struct fw_unit *unit)
271{
272	struct snd_oxfw *oxfw = dev_get_drvdata(&unit->device);
273
274	if (!oxfw->registered)
275		snd_fw_schedule_registration(unit, &oxfw->dwork);
276
277	fcp_bus_reset(oxfw->unit);
278
279	if (oxfw->registered) {
280		if (oxfw->has_output || oxfw->has_input) {
281			mutex_lock(&oxfw->mutex);
282			snd_oxfw_stream_update_duplex(oxfw);
283			mutex_unlock(&oxfw->mutex);
284		}
285
286		if (oxfw->entry->vendor_id == OUI_STANTON)
287			snd_oxfw_scs1x_update(oxfw);
288	}
289}
290
291static void oxfw_remove(struct fw_unit *unit)
292{
293	struct snd_oxfw *oxfw = dev_get_drvdata(&unit->device);
294
295	/*
296	 * Confirm to stop the work for registration before the sound card is
297	 * going to be released. The work is not scheduled again because bus
298	 * reset handler is not called anymore.
299	 */
300	cancel_delayed_work_sync(&oxfw->dwork);
301
302	if (oxfw->registered) {
303		// Block till all of ALSA character devices are released.
304		snd_card_free(oxfw->card);
305	}
306
307	mutex_destroy(&oxfw->mutex);
308	fw_unit_put(oxfw->unit);
309}
310
311static const struct compat_info griffin_firewave = {
312	.driver_name = "FireWave",
313	.vendor_name = "Griffin",
314	.model_name = "FireWave",
315};
316
317static const struct compat_info lacie_speakers = {
318	.driver_name = "FWSpeakers",
319	.vendor_name = "LaCie",
320	.model_name = "FireWire Speakers",
321};
322
323static const struct ieee1394_device_id oxfw_id_table[] = {
324	{
325		.match_flags  = IEEE1394_MATCH_VENDOR_ID |
326				IEEE1394_MATCH_MODEL_ID |
327				IEEE1394_MATCH_SPECIFIER_ID |
328				IEEE1394_MATCH_VERSION,
329		.vendor_id    = VENDOR_GRIFFIN,
330		.model_id     = 0x00f970,
331		.specifier_id = SPECIFIER_1394TA,
332		.version      = VERSION_AVC,
333		.driver_data  = (kernel_ulong_t)&griffin_firewave,
334	},
335	{
336		.match_flags  = IEEE1394_MATCH_VENDOR_ID |
337				IEEE1394_MATCH_MODEL_ID |
338				IEEE1394_MATCH_SPECIFIER_ID |
339				IEEE1394_MATCH_VERSION,
340		.vendor_id    = VENDOR_LACIE,
341		.model_id     = 0x00f970,
342		.specifier_id = SPECIFIER_1394TA,
343		.version      = VERSION_AVC,
344		.driver_data  = (kernel_ulong_t)&lacie_speakers,
345	},
346	/* Behringer,F-Control Audio 202 */
347	{
348		.match_flags	= IEEE1394_MATCH_VENDOR_ID |
349				  IEEE1394_MATCH_MODEL_ID,
350		.vendor_id	= VENDOR_BEHRINGER,
351		.model_id	= 0x00fc22,
352	},
353	/*
354	 * Any Mackie(Loud) models (name string/model id):
355	 *  Onyx-i series (former models):	0x081216
356	 *  Mackie Onyx Satellite:		0x00200f
357	 *  Tapco LINK.firewire 4x6:		0x000460
358	 *  d.2 pro/d.4 pro (built-in card):	Unknown
359	 *  U.420:				Unknown
360	 *  U.420d:				Unknown
361	 */
362	{
363		.match_flags	= IEEE1394_MATCH_VENDOR_ID |
364				  IEEE1394_MATCH_SPECIFIER_ID |
365				  IEEE1394_MATCH_VERSION,
366		.vendor_id	= VENDOR_LOUD,
367		.specifier_id	= SPECIFIER_1394TA,
368		.version	= VERSION_AVC,
369	},
370	/* TASCAM, FireOne */
371	{
372		.match_flags	= IEEE1394_MATCH_VENDOR_ID |
373				  IEEE1394_MATCH_MODEL_ID,
374		.vendor_id	= VENDOR_TASCAM,
375		.model_id	= 0x800007,
376	},
377	/* Stanton, Stanton Controllers & Systems 1 Mixer (SCS.1m) */
378	{
379		.match_flags	= IEEE1394_MATCH_VENDOR_ID |
380				  IEEE1394_MATCH_MODEL_ID,
381		.vendor_id	= OUI_STANTON,
382		.model_id	= 0x001000,
383	},
384	/* Stanton, Stanton Controllers & Systems 1 Deck (SCS.1d) */
385	{
386		.match_flags	= IEEE1394_MATCH_VENDOR_ID |
387				  IEEE1394_MATCH_MODEL_ID,
388		.vendor_id	= OUI_STANTON,
389		.model_id	= 0x002000,
390	},
391	// APOGEE, duet FireWire
392	{
393		.match_flags	= IEEE1394_MATCH_VENDOR_ID |
394				  IEEE1394_MATCH_MODEL_ID,
395		.vendor_id	= OUI_APOGEE,
396		.model_id	= 0x01dddd,
397	},
398	{ }
399};
400MODULE_DEVICE_TABLE(ieee1394, oxfw_id_table);
401
402static struct fw_driver oxfw_driver = {
403	.driver   = {
404		.owner	= THIS_MODULE,
405		.name	= KBUILD_MODNAME,
406		.bus	= &fw_bus_type,
407	},
408	.probe    = oxfw_probe,
409	.update   = oxfw_bus_reset,
410	.remove   = oxfw_remove,
411	.id_table = oxfw_id_table,
412};
413
414static int __init snd_oxfw_init(void)
415{
416	return driver_register(&oxfw_driver.driver);
417}
418
419static void __exit snd_oxfw_exit(void)
420{
421	driver_unregister(&oxfw_driver.driver);
422}
423
424module_init(snd_oxfw_init);
425module_exit(snd_oxfw_exit);
426