xref: /openbmc/linux/sound/firewire/oxfw/oxfw.c (revision ca460cc2)
1 /*
2  * oxfw.c - a part of driver for OXFW970/971 based devices
3  *
4  * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
5  * Licensed under the terms of the GNU General Public License, version 2.
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_GRIFFIN		0x001292
18 #define VENDOR_LACIE		0x00d04b
19 
20 #define SPECIFIER_1394TA	0x00a02d
21 #define VERSION_AVC		0x010001
22 
23 MODULE_DESCRIPTION("Oxford Semiconductor FW970/971 driver");
24 MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
25 MODULE_LICENSE("GPL v2");
26 MODULE_ALIAS("snd-firewire-speakers");
27 
28 static u32 oxfw_read_firmware_version(struct fw_unit *unit)
29 {
30 	__be32 data;
31 	int err;
32 
33 	err = snd_fw_transaction(unit, TCODE_READ_QUADLET_REQUEST,
34 				 OXFORD_FIRMWARE_ID_ADDRESS, &data, 4, 0);
35 	return err >= 0 ? be32_to_cpu(data) : 0;
36 }
37 
38 static void oxfw_card_free(struct snd_card *card)
39 {
40 	struct snd_oxfw *oxfw = card->private_data;
41 
42 	mutex_destroy(&oxfw->mutex);
43 }
44 
45 static int oxfw_probe(struct fw_unit *unit,
46 		       const struct ieee1394_device_id *id)
47 {
48 	struct fw_device *fw_dev = fw_parent_device(unit);
49 	struct snd_card *card;
50 	struct snd_oxfw *oxfw;
51 	u32 firmware;
52 	int err;
53 
54 	err = snd_card_new(&unit->device, -1, NULL, THIS_MODULE,
55 			   sizeof(*oxfw), &card);
56 	if (err < 0)
57 		return err;
58 
59 	card->private_free = oxfw_card_free;
60 	oxfw = card->private_data;
61 	oxfw->card = card;
62 	mutex_init(&oxfw->mutex);
63 	oxfw->unit = unit;
64 	oxfw->device_info = (const struct device_info *)id->driver_data;
65 
66 	strcpy(card->driver, oxfw->device_info->driver_name);
67 	strcpy(card->shortname, oxfw->device_info->short_name);
68 	firmware = oxfw_read_firmware_version(unit);
69 	snprintf(card->longname, sizeof(card->longname),
70 		 "%s (OXFW%x %04x), GUID %08x%08x at %s, S%d",
71 		 oxfw->device_info->long_name,
72 		 firmware >> 20, firmware & 0xffff,
73 		 fw_dev->config_rom[3], fw_dev->config_rom[4],
74 		 dev_name(&unit->device), 100 << fw_dev->max_speed);
75 	strcpy(card->mixername, "OXFW");
76 
77 	err = snd_oxfw_create_pcm(oxfw);
78 	if (err < 0)
79 		goto error;
80 
81 	err = snd_oxfw_create_mixer(oxfw);
82 	if (err < 0)
83 		goto error;
84 
85 	err = snd_oxfw_stream_init_simplex(oxfw);
86 	if (err < 0)
87 		goto error;
88 
89 	err = snd_card_register(card);
90 	if (err < 0) {
91 		snd_oxfw_stream_destroy_simplex(oxfw);
92 		goto error;
93 	}
94 	dev_set_drvdata(&unit->device, oxfw);
95 
96 	return 0;
97 error:
98 	snd_card_free(card);
99 	return err;
100 }
101 
102 static void oxfw_bus_reset(struct fw_unit *unit)
103 {
104 	struct snd_oxfw *oxfw = dev_get_drvdata(&unit->device);
105 
106 	fcp_bus_reset(oxfw->unit);
107 
108 	mutex_lock(&oxfw->mutex);
109 	snd_oxfw_stream_update_simplex(oxfw);
110 	mutex_unlock(&oxfw->mutex);
111 }
112 
113 static void oxfw_remove(struct fw_unit *unit)
114 {
115 	struct snd_oxfw *oxfw = dev_get_drvdata(&unit->device);
116 
117 	snd_card_disconnect(oxfw->card);
118 
119 	snd_oxfw_stream_destroy_simplex(oxfw);
120 
121 	snd_card_free_when_closed(oxfw->card);
122 }
123 
124 static const struct device_info griffin_firewave = {
125 	.driver_name = "FireWave",
126 	.short_name  = "FireWave",
127 	.long_name   = "Griffin FireWave Surround",
128 	.pcm_constraints = firewave_constraints,
129 	.mixer_channels = 6,
130 	.mute_fb_id   = 0x01,
131 	.volume_fb_id = 0x02,
132 };
133 
134 static const struct device_info lacie_speakers = {
135 	.driver_name = "FWSpeakers",
136 	.short_name  = "FireWire Speakers",
137 	.long_name   = "LaCie FireWire Speakers",
138 	.pcm_constraints = lacie_speakers_constraints,
139 	.mixer_channels = 1,
140 	.mute_fb_id   = 0x01,
141 	.volume_fb_id = 0x01,
142 };
143 
144 static const struct ieee1394_device_id oxfw_id_table[] = {
145 	{
146 		.match_flags  = IEEE1394_MATCH_VENDOR_ID |
147 				IEEE1394_MATCH_MODEL_ID |
148 				IEEE1394_MATCH_SPECIFIER_ID |
149 				IEEE1394_MATCH_VERSION,
150 		.vendor_id    = VENDOR_GRIFFIN,
151 		.model_id     = 0x00f970,
152 		.specifier_id = SPECIFIER_1394TA,
153 		.version      = VERSION_AVC,
154 		.driver_data  = (kernel_ulong_t)&griffin_firewave,
155 	},
156 	{
157 		.match_flags  = IEEE1394_MATCH_VENDOR_ID |
158 				IEEE1394_MATCH_MODEL_ID |
159 				IEEE1394_MATCH_SPECIFIER_ID |
160 				IEEE1394_MATCH_VERSION,
161 		.vendor_id    = VENDOR_LACIE,
162 		.model_id     = 0x00f970,
163 		.specifier_id = SPECIFIER_1394TA,
164 		.version      = VERSION_AVC,
165 		.driver_data  = (kernel_ulong_t)&lacie_speakers,
166 	},
167 	{ }
168 };
169 MODULE_DEVICE_TABLE(ieee1394, oxfw_id_table);
170 
171 static struct fw_driver oxfw_driver = {
172 	.driver   = {
173 		.owner	= THIS_MODULE,
174 		.name	= KBUILD_MODNAME,
175 		.bus	= &fw_bus_type,
176 	},
177 	.probe    = oxfw_probe,
178 	.update   = oxfw_bus_reset,
179 	.remove   = oxfw_remove,
180 	.id_table = oxfw_id_table,
181 };
182 
183 static int __init snd_oxfw_init(void)
184 {
185 	return driver_register(&oxfw_driver.driver);
186 }
187 
188 static void __exit snd_oxfw_exit(void)
189 {
190 	driver_unregister(&oxfw_driver.driver);
191 }
192 
193 module_init(snd_oxfw_init);
194 module_exit(snd_oxfw_exit);
195