xref: /openbmc/linux/sound/firewire/oxfw/oxfw.c (revision b0ac0009)
11a4e39c2STakashi Sakamoto /*
21a4e39c2STakashi Sakamoto  * oxfw.c - a part of driver for OXFW970/971 based devices
31a4e39c2STakashi Sakamoto  *
41a4e39c2STakashi Sakamoto  * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
51a4e39c2STakashi Sakamoto  * Licensed under the terms of the GNU General Public License, version 2.
61a4e39c2STakashi Sakamoto  */
71a4e39c2STakashi Sakamoto 
8e2786ca6STakashi Sakamoto #include "oxfw.h"
91a4e39c2STakashi Sakamoto 
101a4e39c2STakashi Sakamoto #define OXFORD_FIRMWARE_ID_ADDRESS	(CSR_REGISTER_BASE + 0x50000)
111a4e39c2STakashi Sakamoto /* 0x970?vvvv or 0x971?vvvv, where vvvv = firmware version */
121a4e39c2STakashi Sakamoto 
131a4e39c2STakashi Sakamoto #define OXFORD_HARDWARE_ID_ADDRESS	(CSR_REGISTER_BASE + 0x90020)
141a4e39c2STakashi Sakamoto #define OXFORD_HARDWARE_ID_OXFW970	0x39443841
151a4e39c2STakashi Sakamoto #define OXFORD_HARDWARE_ID_OXFW971	0x39373100
161a4e39c2STakashi Sakamoto 
17ec4dba50STakashi Sakamoto #define VENDOR_LOUD		0x000ff2
181a4e39c2STakashi Sakamoto #define VENDOR_GRIFFIN		0x001292
19ec4dba50STakashi Sakamoto #define VENDOR_BEHRINGER	0x001564
201a4e39c2STakashi Sakamoto #define VENDOR_LACIE		0x00d04b
211a4e39c2STakashi Sakamoto 
221a4e39c2STakashi Sakamoto #define SPECIFIER_1394TA	0x00a02d
231a4e39c2STakashi Sakamoto #define VERSION_AVC		0x010001
241a4e39c2STakashi Sakamoto 
251a4e39c2STakashi Sakamoto MODULE_DESCRIPTION("Oxford Semiconductor FW970/971 driver");
261a4e39c2STakashi Sakamoto MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
271a4e39c2STakashi Sakamoto MODULE_LICENSE("GPL v2");
281a4e39c2STakashi Sakamoto MODULE_ALIAS("snd-firewire-speakers");
291a4e39c2STakashi Sakamoto 
30ec4dba50STakashi Sakamoto static bool detect_loud_models(struct fw_unit *unit)
31ec4dba50STakashi Sakamoto {
32ec4dba50STakashi Sakamoto 	const char *const models[] = {
33ec4dba50STakashi Sakamoto 		"Onyxi",
34ec4dba50STakashi Sakamoto 		"Onyx-i",
35ec4dba50STakashi Sakamoto 		"d.Pro",
36ec4dba50STakashi Sakamoto 		"Mackie Onyx Satellite",
37ec4dba50STakashi Sakamoto 		"Tapco LINK.firewire 4x6",
38ec4dba50STakashi Sakamoto 		"U.420"};
39ec4dba50STakashi Sakamoto 	char model[32];
40ec4dba50STakashi Sakamoto 	unsigned int i;
41ec4dba50STakashi Sakamoto 	int err;
42ec4dba50STakashi Sakamoto 
43ec4dba50STakashi Sakamoto 	err = fw_csr_string(unit->directory, CSR_MODEL,
44ec4dba50STakashi Sakamoto 			    model, sizeof(model));
45ec4dba50STakashi Sakamoto 	if (err < 0)
46ec4dba50STakashi Sakamoto 		return err;
47ec4dba50STakashi Sakamoto 
48ec4dba50STakashi Sakamoto 	for (i = 0; i < ARRAY_SIZE(models); i++) {
49ec4dba50STakashi Sakamoto 		if (strcmp(models[i], model) == 0)
50ec4dba50STakashi Sakamoto 			break;
51ec4dba50STakashi Sakamoto 	}
52ec4dba50STakashi Sakamoto 
53ec4dba50STakashi Sakamoto 	return (i < ARRAY_SIZE(models));
54ec4dba50STakashi Sakamoto }
55ec4dba50STakashi Sakamoto 
56fec7b753STakashi Sakamoto static int name_card(struct snd_oxfw *oxfw)
571a4e39c2STakashi Sakamoto {
58fec7b753STakashi Sakamoto 	struct fw_device *fw_dev = fw_parent_device(oxfw->unit);
59ec4dba50STakashi Sakamoto 	char vendor[24];
60ec4dba50STakashi Sakamoto 	char model[32];
61fec7b753STakashi Sakamoto 	const char *d, *v, *m;
62fec7b753STakashi Sakamoto 	u32 firmware;
631a4e39c2STakashi Sakamoto 	int err;
641a4e39c2STakashi Sakamoto 
65ec4dba50STakashi Sakamoto 	/* get vendor name from root directory */
66ec4dba50STakashi Sakamoto 	err = fw_csr_string(fw_dev->config_rom + 5, CSR_VENDOR,
67ec4dba50STakashi Sakamoto 			    vendor, sizeof(vendor));
68ec4dba50STakashi Sakamoto 	if (err < 0)
69ec4dba50STakashi Sakamoto 		goto end;
70ec4dba50STakashi Sakamoto 
71ec4dba50STakashi Sakamoto 	/* get model name from unit directory */
72ec4dba50STakashi Sakamoto 	err = fw_csr_string(oxfw->unit->directory, CSR_MODEL,
73ec4dba50STakashi Sakamoto 			    model, sizeof(model));
74ec4dba50STakashi Sakamoto 	if (err < 0)
75ec4dba50STakashi Sakamoto 		goto end;
76ec4dba50STakashi Sakamoto 
77fec7b753STakashi Sakamoto 	err = snd_fw_transaction(oxfw->unit, TCODE_READ_QUADLET_REQUEST,
78fec7b753STakashi Sakamoto 				 OXFORD_FIRMWARE_ID_ADDRESS, &firmware, 4, 0);
79fec7b753STakashi Sakamoto 	if (err < 0)
80fec7b753STakashi Sakamoto 		goto end;
81fec7b753STakashi Sakamoto 	be32_to_cpus(&firmware);
82fec7b753STakashi Sakamoto 
83ec4dba50STakashi Sakamoto 	/* to apply card definitions */
84ec4dba50STakashi Sakamoto 	if (oxfw->device_info) {
85fec7b753STakashi Sakamoto 		d = oxfw->device_info->driver_name;
86fec7b753STakashi Sakamoto 		v = oxfw->device_info->vendor_name;
87fec7b753STakashi Sakamoto 		m = oxfw->device_info->model_name;
88ec4dba50STakashi Sakamoto 	} else {
89ec4dba50STakashi Sakamoto 		d = "OXFW";
90ec4dba50STakashi Sakamoto 		v = vendor;
91ec4dba50STakashi Sakamoto 		m = model;
92ec4dba50STakashi Sakamoto 	}
93fec7b753STakashi Sakamoto 
94fec7b753STakashi Sakamoto 	strcpy(oxfw->card->driver, d);
95fec7b753STakashi Sakamoto 	strcpy(oxfw->card->mixername, m);
96fec7b753STakashi Sakamoto 	strcpy(oxfw->card->shortname, m);
97fec7b753STakashi Sakamoto 
98fec7b753STakashi Sakamoto 	snprintf(oxfw->card->longname, sizeof(oxfw->card->longname),
99fec7b753STakashi Sakamoto 		 "%s %s (OXFW%x %04x), GUID %08x%08x at %s, S%d",
100fec7b753STakashi Sakamoto 		 v, m, firmware >> 20, firmware & 0xffff,
101fec7b753STakashi Sakamoto 		 fw_dev->config_rom[3], fw_dev->config_rom[4],
102fec7b753STakashi Sakamoto 		 dev_name(&oxfw->unit->device), 100 << fw_dev->max_speed);
103fec7b753STakashi Sakamoto end:
104fec7b753STakashi Sakamoto 	return err;
1051a4e39c2STakashi Sakamoto }
1061a4e39c2STakashi Sakamoto 
1071a4e39c2STakashi Sakamoto static void oxfw_card_free(struct snd_card *card)
1081a4e39c2STakashi Sakamoto {
1091a4e39c2STakashi Sakamoto 	struct snd_oxfw *oxfw = card->private_data;
1105cd1d3f4STakashi Sakamoto 	unsigned int i;
1115cd1d3f4STakashi Sakamoto 
112b0ac0009STakashi Sakamoto 	for (i = 0; i < SND_OXFW_STREAM_FORMAT_ENTRIES; i++) {
113b0ac0009STakashi Sakamoto 		kfree(oxfw->tx_stream_formats[i]);
1145cd1d3f4STakashi Sakamoto 		kfree(oxfw->rx_stream_formats[i]);
115b0ac0009STakashi Sakamoto 	}
1161a4e39c2STakashi Sakamoto 
1171a4e39c2STakashi Sakamoto 	mutex_destroy(&oxfw->mutex);
1181a4e39c2STakashi Sakamoto }
1191a4e39c2STakashi Sakamoto 
1201a4e39c2STakashi Sakamoto static int oxfw_probe(struct fw_unit *unit,
1211a4e39c2STakashi Sakamoto 		       const struct ieee1394_device_id *id)
1221a4e39c2STakashi Sakamoto {
1231a4e39c2STakashi Sakamoto 	struct snd_card *card;
1241a4e39c2STakashi Sakamoto 	struct snd_oxfw *oxfw;
1251a4e39c2STakashi Sakamoto 	int err;
1261a4e39c2STakashi Sakamoto 
127ec4dba50STakashi Sakamoto 	if ((id->vendor_id == VENDOR_LOUD) && !detect_loud_models(unit))
128ec4dba50STakashi Sakamoto 		return -ENODEV;
129ec4dba50STakashi Sakamoto 
1301a4e39c2STakashi Sakamoto 	err = snd_card_new(&unit->device, -1, NULL, THIS_MODULE,
1311a4e39c2STakashi Sakamoto 			   sizeof(*oxfw), &card);
1321a4e39c2STakashi Sakamoto 	if (err < 0)
1331a4e39c2STakashi Sakamoto 		return err;
1341a4e39c2STakashi Sakamoto 
135e2786ca6STakashi Sakamoto 	card->private_free = oxfw_card_free;
1361a4e39c2STakashi Sakamoto 	oxfw = card->private_data;
1371a4e39c2STakashi Sakamoto 	oxfw->card = card;
1381a4e39c2STakashi Sakamoto 	mutex_init(&oxfw->mutex);
139e2786ca6STakashi Sakamoto 	oxfw->unit = unit;
1401a4e39c2STakashi Sakamoto 	oxfw->device_info = (const struct device_info *)id->driver_data;
1411a4e39c2STakashi Sakamoto 
1425cd1d3f4STakashi Sakamoto 	err = snd_oxfw_stream_discover(oxfw);
1435cd1d3f4STakashi Sakamoto 	if (err < 0)
1445cd1d3f4STakashi Sakamoto 		goto error;
1455cd1d3f4STakashi Sakamoto 
146fec7b753STakashi Sakamoto 	err = name_card(oxfw);
147fec7b753STakashi Sakamoto 	if (err < 0)
148fec7b753STakashi Sakamoto 		goto error;
1491a4e39c2STakashi Sakamoto 
1503713d93aSTakashi Sakamoto 	err = snd_oxfw_create_pcm(oxfw);
1511a4e39c2STakashi Sakamoto 	if (err < 0)
1521a4e39c2STakashi Sakamoto 		goto error;
1531a4e39c2STakashi Sakamoto 
154ec4dba50STakashi Sakamoto 	if (oxfw->device_info) {
15531514bfbSTakashi Sakamoto 		err = snd_oxfw_create_mixer(oxfw);
1561a4e39c2STakashi Sakamoto 		if (err < 0)
1571a4e39c2STakashi Sakamoto 			goto error;
158ec4dba50STakashi Sakamoto 	}
1591a4e39c2STakashi Sakamoto 
1603c96101fSTakashi Sakamoto 	snd_oxfw_proc_init(oxfw);
1613c96101fSTakashi Sakamoto 
162b0ac0009STakashi Sakamoto 	err = snd_oxfw_stream_init_simplex(oxfw, &oxfw->rx_stream);
1631a4e39c2STakashi Sakamoto 	if (err < 0)
1641a4e39c2STakashi Sakamoto 		goto error;
165b0ac0009STakashi Sakamoto 	if (oxfw->has_output) {
166b0ac0009STakashi Sakamoto 		err = snd_oxfw_stream_init_simplex(oxfw, &oxfw->tx_stream);
167b0ac0009STakashi Sakamoto 		if (err < 0)
168b0ac0009STakashi Sakamoto 			goto error;
169b0ac0009STakashi Sakamoto 	}
1701a4e39c2STakashi Sakamoto 
171e2786ca6STakashi Sakamoto 	err = snd_card_register(card);
172e2786ca6STakashi Sakamoto 	if (err < 0) {
173b0ac0009STakashi Sakamoto 		snd_oxfw_stream_destroy_simplex(oxfw, &oxfw->rx_stream);
174b0ac0009STakashi Sakamoto 		if (oxfw->has_output)
175b0ac0009STakashi Sakamoto 			snd_oxfw_stream_destroy_simplex(oxfw, &oxfw->tx_stream);
176e2786ca6STakashi Sakamoto 		goto error;
177e2786ca6STakashi Sakamoto 	}
1781a4e39c2STakashi Sakamoto 	dev_set_drvdata(&unit->device, oxfw);
1791a4e39c2STakashi Sakamoto 
1801a4e39c2STakashi Sakamoto 	return 0;
1811a4e39c2STakashi Sakamoto error:
1821a4e39c2STakashi Sakamoto 	snd_card_free(card);
1831a4e39c2STakashi Sakamoto 	return err;
1841a4e39c2STakashi Sakamoto }
1851a4e39c2STakashi Sakamoto 
1861a4e39c2STakashi Sakamoto static void oxfw_bus_reset(struct fw_unit *unit)
1871a4e39c2STakashi Sakamoto {
1881a4e39c2STakashi Sakamoto 	struct snd_oxfw *oxfw = dev_get_drvdata(&unit->device);
1891a4e39c2STakashi Sakamoto 
1901a4e39c2STakashi Sakamoto 	fcp_bus_reset(oxfw->unit);
1911a4e39c2STakashi Sakamoto 
1921a4e39c2STakashi Sakamoto 	mutex_lock(&oxfw->mutex);
193b0ac0009STakashi Sakamoto 
194b0ac0009STakashi Sakamoto 	snd_oxfw_stream_update_simplex(oxfw, &oxfw->rx_stream);
195b0ac0009STakashi Sakamoto 	if (oxfw->has_output)
196b0ac0009STakashi Sakamoto 		snd_oxfw_stream_update_simplex(oxfw, &oxfw->tx_stream);
197b0ac0009STakashi Sakamoto 
1981a4e39c2STakashi Sakamoto 	mutex_unlock(&oxfw->mutex);
1991a4e39c2STakashi Sakamoto }
2001a4e39c2STakashi Sakamoto 
2011a4e39c2STakashi Sakamoto static void oxfw_remove(struct fw_unit *unit)
2021a4e39c2STakashi Sakamoto {
2031a4e39c2STakashi Sakamoto 	struct snd_oxfw *oxfw = dev_get_drvdata(&unit->device);
2041a4e39c2STakashi Sakamoto 
2051a4e39c2STakashi Sakamoto 	snd_card_disconnect(oxfw->card);
2061a4e39c2STakashi Sakamoto 
207b0ac0009STakashi Sakamoto 	snd_oxfw_stream_destroy_simplex(oxfw, &oxfw->rx_stream);
208b0ac0009STakashi Sakamoto 	if (oxfw->has_output)
209b0ac0009STakashi Sakamoto 		snd_oxfw_stream_destroy_simplex(oxfw, &oxfw->tx_stream);
2101a4e39c2STakashi Sakamoto 
2111a4e39c2STakashi Sakamoto 	snd_card_free_when_closed(oxfw->card);
2121a4e39c2STakashi Sakamoto }
2131a4e39c2STakashi Sakamoto 
2141a4e39c2STakashi Sakamoto static const struct device_info griffin_firewave = {
2151a4e39c2STakashi Sakamoto 	.driver_name = "FireWave",
216fec7b753STakashi Sakamoto 	.vendor_name = "Griffin",
217fec7b753STakashi Sakamoto 	.model_name = "FireWave",
2181a4e39c2STakashi Sakamoto 	.mixer_channels = 6,
2191a4e39c2STakashi Sakamoto 	.mute_fb_id   = 0x01,
2201a4e39c2STakashi Sakamoto 	.volume_fb_id = 0x02,
2211a4e39c2STakashi Sakamoto };
2221a4e39c2STakashi Sakamoto 
2231a4e39c2STakashi Sakamoto static const struct device_info lacie_speakers = {
2241a4e39c2STakashi Sakamoto 	.driver_name = "FWSpeakers",
225fec7b753STakashi Sakamoto 	.vendor_name = "LaCie",
226fec7b753STakashi Sakamoto 	.model_name = "FireWire Speakers",
2271a4e39c2STakashi Sakamoto 	.mixer_channels = 1,
2281a4e39c2STakashi Sakamoto 	.mute_fb_id   = 0x01,
2291a4e39c2STakashi Sakamoto 	.volume_fb_id = 0x01,
2301a4e39c2STakashi Sakamoto };
2311a4e39c2STakashi Sakamoto 
2321a4e39c2STakashi Sakamoto static const struct ieee1394_device_id oxfw_id_table[] = {
2331a4e39c2STakashi Sakamoto 	{
2341a4e39c2STakashi Sakamoto 		.match_flags  = IEEE1394_MATCH_VENDOR_ID |
2351a4e39c2STakashi Sakamoto 				IEEE1394_MATCH_MODEL_ID |
2361a4e39c2STakashi Sakamoto 				IEEE1394_MATCH_SPECIFIER_ID |
2371a4e39c2STakashi Sakamoto 				IEEE1394_MATCH_VERSION,
2381a4e39c2STakashi Sakamoto 		.vendor_id    = VENDOR_GRIFFIN,
2391a4e39c2STakashi Sakamoto 		.model_id     = 0x00f970,
2401a4e39c2STakashi Sakamoto 		.specifier_id = SPECIFIER_1394TA,
2411a4e39c2STakashi Sakamoto 		.version      = VERSION_AVC,
2421a4e39c2STakashi Sakamoto 		.driver_data  = (kernel_ulong_t)&griffin_firewave,
2431a4e39c2STakashi Sakamoto 	},
2441a4e39c2STakashi Sakamoto 	{
2451a4e39c2STakashi Sakamoto 		.match_flags  = IEEE1394_MATCH_VENDOR_ID |
2461a4e39c2STakashi Sakamoto 				IEEE1394_MATCH_MODEL_ID |
2471a4e39c2STakashi Sakamoto 				IEEE1394_MATCH_SPECIFIER_ID |
2481a4e39c2STakashi Sakamoto 				IEEE1394_MATCH_VERSION,
2491a4e39c2STakashi Sakamoto 		.vendor_id    = VENDOR_LACIE,
2501a4e39c2STakashi Sakamoto 		.model_id     = 0x00f970,
2511a4e39c2STakashi Sakamoto 		.specifier_id = SPECIFIER_1394TA,
2521a4e39c2STakashi Sakamoto 		.version      = VERSION_AVC,
2531a4e39c2STakashi Sakamoto 		.driver_data  = (kernel_ulong_t)&lacie_speakers,
2541a4e39c2STakashi Sakamoto 	},
255ec4dba50STakashi Sakamoto 	/* Behringer,F-Control Audio 202 */
256ec4dba50STakashi Sakamoto 	{
257ec4dba50STakashi Sakamoto 		.match_flags	= IEEE1394_MATCH_VENDOR_ID |
258ec4dba50STakashi Sakamoto 				  IEEE1394_MATCH_MODEL_ID,
259ec4dba50STakashi Sakamoto 		.vendor_id	= VENDOR_BEHRINGER,
260ec4dba50STakashi Sakamoto 		.model_id	= 0x00fc22,
261ec4dba50STakashi Sakamoto 	},
262ec4dba50STakashi Sakamoto 	/*
263ec4dba50STakashi Sakamoto 	 * Any Mackie(Loud) models (name string/model id):
264ec4dba50STakashi Sakamoto 	 *  Onyx-i series (former models):	0x081216
265ec4dba50STakashi Sakamoto 	 *  Mackie Onyx Satellite:		0x00200f
266ec4dba50STakashi Sakamoto 	 *  Tapco LINK.firewire 4x6:		0x000460
267ec4dba50STakashi Sakamoto 	 *  d.2 pro:				Unknown
268ec4dba50STakashi Sakamoto 	 *  d.4 pro:				Unknown
269ec4dba50STakashi Sakamoto 	 *  U.420:				Unknown
270ec4dba50STakashi Sakamoto 	 *  U.420d:				Unknown
271ec4dba50STakashi Sakamoto 	 */
272ec4dba50STakashi Sakamoto 	{
273ec4dba50STakashi Sakamoto 		.match_flags	= IEEE1394_MATCH_VENDOR_ID |
274ec4dba50STakashi Sakamoto 				  IEEE1394_MATCH_SPECIFIER_ID |
275ec4dba50STakashi Sakamoto 				  IEEE1394_MATCH_VERSION,
276ec4dba50STakashi Sakamoto 		.vendor_id	= VENDOR_LOUD,
277ec4dba50STakashi Sakamoto 		.specifier_id	= SPECIFIER_1394TA,
278ec4dba50STakashi Sakamoto 		.version	= VERSION_AVC,
279ec4dba50STakashi Sakamoto 	},
2801a4e39c2STakashi Sakamoto 	{ }
2811a4e39c2STakashi Sakamoto };
2821a4e39c2STakashi Sakamoto MODULE_DEVICE_TABLE(ieee1394, oxfw_id_table);
2831a4e39c2STakashi Sakamoto 
2841a4e39c2STakashi Sakamoto static struct fw_driver oxfw_driver = {
2851a4e39c2STakashi Sakamoto 	.driver   = {
2861a4e39c2STakashi Sakamoto 		.owner	= THIS_MODULE,
2871a4e39c2STakashi Sakamoto 		.name	= KBUILD_MODNAME,
2881a4e39c2STakashi Sakamoto 		.bus	= &fw_bus_type,
2891a4e39c2STakashi Sakamoto 	},
2901a4e39c2STakashi Sakamoto 	.probe    = oxfw_probe,
2911a4e39c2STakashi Sakamoto 	.update   = oxfw_bus_reset,
2921a4e39c2STakashi Sakamoto 	.remove   = oxfw_remove,
2931a4e39c2STakashi Sakamoto 	.id_table = oxfw_id_table,
2941a4e39c2STakashi Sakamoto };
2951a4e39c2STakashi Sakamoto 
2961a4e39c2STakashi Sakamoto static int __init snd_oxfw_init(void)
2971a4e39c2STakashi Sakamoto {
2981a4e39c2STakashi Sakamoto 	return driver_register(&oxfw_driver.driver);
2991a4e39c2STakashi Sakamoto }
3001a4e39c2STakashi Sakamoto 
3011a4e39c2STakashi Sakamoto static void __exit snd_oxfw_exit(void)
3021a4e39c2STakashi Sakamoto {
3031a4e39c2STakashi Sakamoto 	driver_unregister(&oxfw_driver.driver);
3041a4e39c2STakashi Sakamoto }
3051a4e39c2STakashi Sakamoto 
3061a4e39c2STakashi Sakamoto module_init(snd_oxfw_init);
3071a4e39c2STakashi Sakamoto module_exit(snd_oxfw_exit);
308