.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * TC Applied Technologies Digital Interface Communications Engine driver |
---|
3 | 4 | * |
---|
4 | 5 | * Copyright (c) Clemens Ladisch <clemens@ladisch.de> |
---|
5 | | - * Licensed under the terms of the GNU General Public License, version 2. |
---|
6 | 6 | */ |
---|
7 | 7 | |
---|
8 | 8 | #include "dice.h" |
---|
.. | .. |
---|
19 | 19 | #define OUI_MAUDIO 0x000d6c |
---|
20 | 20 | #define OUI_MYTEK 0x001ee8 |
---|
21 | 21 | #define OUI_SSL 0x0050c2 // Actually ID reserved by IEEE. |
---|
| 22 | +#define OUI_PRESONUS 0x000a92 |
---|
22 | 23 | |
---|
23 | 24 | #define DICE_CATEGORY_ID 0x04 |
---|
24 | 25 | #define WEISS_CATEGORY_ID 0x00 |
---|
.. | .. |
---|
123 | 124 | strcpy(card->mixername, "DICE"); |
---|
124 | 125 | } |
---|
125 | 126 | |
---|
126 | | -static void dice_free(struct snd_dice *dice) |
---|
127 | | -{ |
---|
128 | | - snd_dice_stream_destroy_duplex(dice); |
---|
129 | | - snd_dice_transaction_destroy(dice); |
---|
130 | | - fw_unit_put(dice->unit); |
---|
131 | | - |
---|
132 | | - mutex_destroy(&dice->mutex); |
---|
133 | | - kfree(dice); |
---|
134 | | -} |
---|
135 | | - |
---|
136 | | -/* |
---|
137 | | - * This module releases the FireWire unit data after all ALSA character devices |
---|
138 | | - * are released by applications. This is for releasing stream data or finishing |
---|
139 | | - * transactions safely. Thus at returning from .remove(), this module still keep |
---|
140 | | - * references for the unit. |
---|
141 | | - */ |
---|
142 | 127 | static void dice_card_free(struct snd_card *card) |
---|
143 | 128 | { |
---|
144 | | - dice_free(card->private_data); |
---|
| 129 | + struct snd_dice *dice = card->private_data; |
---|
| 130 | + |
---|
| 131 | + snd_dice_stream_destroy_duplex(dice); |
---|
| 132 | + snd_dice_transaction_destroy(dice); |
---|
145 | 133 | } |
---|
146 | 134 | |
---|
147 | 135 | static void do_registration(struct work_struct *work) |
---|
.. | .. |
---|
156 | 144 | &dice->card); |
---|
157 | 145 | if (err < 0) |
---|
158 | 146 | return; |
---|
| 147 | + dice->card->private_free = dice_card_free; |
---|
| 148 | + dice->card->private_data = dice; |
---|
159 | 149 | |
---|
160 | 150 | err = snd_dice_transaction_init(dice); |
---|
161 | 151 | if (err < 0) |
---|
.. | .. |
---|
193 | 183 | if (err < 0) |
---|
194 | 184 | goto error; |
---|
195 | 185 | |
---|
196 | | - /* |
---|
197 | | - * After registered, dice instance can be released corresponding to |
---|
198 | | - * releasing the sound card instance. |
---|
199 | | - */ |
---|
200 | | - dice->card->private_free = dice_card_free; |
---|
201 | | - dice->card->private_data = dice; |
---|
202 | 186 | dice->registered = true; |
---|
203 | 187 | |
---|
204 | 188 | return; |
---|
205 | 189 | error: |
---|
206 | | - snd_dice_stream_destroy_duplex(dice); |
---|
207 | | - snd_dice_transaction_destroy(dice); |
---|
208 | | - snd_dice_stream_destroy_duplex(dice); |
---|
209 | 190 | snd_card_free(dice->card); |
---|
210 | 191 | dev_info(&dice->unit->device, |
---|
211 | 192 | "Sound card registration failed: %d\n", err); |
---|
.. | .. |
---|
224 | 205 | } |
---|
225 | 206 | |
---|
226 | 207 | /* Allocate this independent of sound card instance. */ |
---|
227 | | - dice = kzalloc(sizeof(struct snd_dice), GFP_KERNEL); |
---|
228 | | - if (dice == NULL) |
---|
| 208 | + dice = devm_kzalloc(&unit->device, sizeof(struct snd_dice), GFP_KERNEL); |
---|
| 209 | + if (!dice) |
---|
229 | 210 | return -ENOMEM; |
---|
230 | | - |
---|
231 | 211 | dice->unit = fw_unit_get(unit); |
---|
232 | 212 | dev_set_drvdata(&unit->device, dice); |
---|
233 | 213 | |
---|
.. | .. |
---|
262 | 242 | cancel_delayed_work_sync(&dice->dwork); |
---|
263 | 243 | |
---|
264 | 244 | if (dice->registered) { |
---|
265 | | - /* No need to wait for releasing card object in this context. */ |
---|
266 | | - snd_card_free_when_closed(dice->card); |
---|
267 | | - } else { |
---|
268 | | - /* Don't forget this case. */ |
---|
269 | | - dice_free(dice); |
---|
| 245 | + // Block till all of ALSA character devices are released. |
---|
| 246 | + snd_card_free(dice->card); |
---|
270 | 247 | } |
---|
| 248 | + |
---|
| 249 | + mutex_destroy(&dice->mutex); |
---|
| 250 | + fw_unit_put(dice->unit); |
---|
271 | 251 | } |
---|
272 | 252 | |
---|
273 | 253 | static void dice_bus_reset(struct fw_unit *unit) |
---|
.. | .. |
---|
375 | 355 | .model_id = MODEL_ALESIS_IO_BOTH, |
---|
376 | 356 | .driver_data = (kernel_ulong_t)snd_dice_detect_alesis_formats, |
---|
377 | 357 | }, |
---|
| 358 | + // Alesis MasterControl. |
---|
| 359 | + { |
---|
| 360 | + .match_flags = IEEE1394_MATCH_VENDOR_ID | |
---|
| 361 | + IEEE1394_MATCH_MODEL_ID, |
---|
| 362 | + .vendor_id = OUI_ALESIS, |
---|
| 363 | + .model_id = 0x000002, |
---|
| 364 | + .driver_data = (kernel_ulong_t)snd_dice_detect_alesis_mastercontrol_formats, |
---|
| 365 | + }, |
---|
378 | 366 | /* Mytek Stereo 192 DSD-DAC. */ |
---|
379 | 367 | { |
---|
380 | 368 | .match_flags = IEEE1394_MATCH_VENDOR_ID | |
---|
.. | .. |
---|
392 | 380 | .vendor_id = OUI_SSL, |
---|
393 | 381 | .model_id = 0x000070, |
---|
394 | 382 | }, |
---|
| 383 | + // Presonus FireStudio. |
---|
| 384 | + { |
---|
| 385 | + .match_flags = IEEE1394_MATCH_VENDOR_ID | |
---|
| 386 | + IEEE1394_MATCH_MODEL_ID, |
---|
| 387 | + .vendor_id = OUI_PRESONUS, |
---|
| 388 | + .model_id = 0x000008, |
---|
| 389 | + .driver_data = (kernel_ulong_t)snd_dice_detect_presonus_formats, |
---|
| 390 | + }, |
---|
395 | 391 | { |
---|
396 | 392 | .match_flags = IEEE1394_MATCH_VERSION, |
---|
397 | 393 | .version = DICE_INTERFACE, |
---|