Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ALSA: bebob: Add skelton for BeBoB based devices

This commit adds a new driver for BeBoB based devices with no specific
operations. Currently this driver just create/remove card instance according
to callbacks.

BeBoB is 'BridgeCo enhanced Breakout Box'. This is installed to firewire
devices with DM1000/DM1100/DM1500 chipset. It gives common way for host
system to handle BeBoB based devices.

Current supported devices:
- Edirol FA-66/FA-101
- PreSonus FIREBOX/FIREPOD/FP10/Inspire1394
- BridgeCo RDAudio1/Audio5
- Mackie Onyx 1220/1620/1640 (Firewire I/O Card)
- Mackie d.2 (Firewire Option)
- Stanton FinalScratch 2 (ScratchAmp)
- Tascam IF-FW DM
- Behringer XENIX UFX 1204/1604
- Behringer Digital Mixer X32 series (X-UF Card)
- Apogee Rosetta 200/Rosetta 400 (X-FireWire card)
- Apogee DA-16X/AD-16X/DD-16X (X-FireWire card)
- Apogee Ensemble
- ESI Quotafire610
- AcousticReality eARMasterOne
- CME MatrixKFW
- Phonix Helix Board 12 MkII/18 MkII/24 MkII
- Phonic Helix Board 12 Universal/18 Universal/24 Universal
- Lynx Aurora 8/16 (LT-FW)
- ICON FireXon
- PrismSound Orpheus/ADA-8XR

Devices possible to be supported if identifying IDs:
- Apogee Mini-Me Firewire/Mini-DAC Firewire
- Behringer F-Control Audio 610/1616
- Cakewalk Sonar Power Studio 66
- CME UF400e
- ESI Quotafire XL
- Infrasonic DewX/Windy6
- Mackie Digital X Bus x.200/400
- Phonic Helix Board 12/18/24
- Phonic FireFly 202/302
- Rolf Spuler Firewire Guitar

Tested-by: David Henningsson <david.henningsson@canonical.com>
Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>

authored by

Takashi Sakamoto and committed by
Takashi Iwai
fd6f4b0d 555e8a8f

+389
+30
sound/firewire/Kconfig
··· 79 79 To compile this driver as a module, choose M here: the module 80 80 will be called snd-fireworks. 81 81 82 + config SND_BEBOB 83 + tristate "BridgeCo DM1000/DM1100/DM1500 with BeBoB firmware" 84 + select SND_FIREWIRE_LIB 85 + help 86 + Say Y here to include support for FireWire devices based 87 + on BridgeCo DM1000/DM1100/DM1500 with BeBoB firmware: 88 + * Edirol FA-66/FA-101 89 + * PreSonus FIREBOX/FIREPOD/FP10/Inspire1394 90 + * BridgeCo RDAudio1/Audio5 91 + * Mackie Onyx 1220/1620/1640 (Firewire I/O Card) 92 + * Mackie d.2 (Firewire Option) 93 + * Stanton FinalScratch 2 (ScratchAmp) 94 + * Tascam IF-FW/DM 95 + * Behringer XENIX UFX 1204/1604 96 + * Behringer Digital Mixer X32 series (X-UF Card) 97 + * Apogee Rosetta 200/400 (X-FireWire card) 98 + * Apogee DA/AD/DD-16X (X-FireWire card) 99 + * Apogee Ensemble 100 + * ESI Quotafire610 101 + * AcousticReality eARMasterOne 102 + * CME MatrixKFW 103 + * Phonic Helix Board 12 MkII/18 MkII/24 MkII 104 + * Phonic Helix Board 12 Universal/18 Universal/24 Universal 105 + * Lynx Aurora 8/16 (LT-FW) 106 + * ICON FireXon 107 + * PrismSound Orpheus/ADA-8XR 108 + 109 + To compile this driver as a module, choose M here: the module 110 + will be called snd-bebob. 111 + 82 112 endif # SND_FIREWIRE
+1
sound/firewire/Makefile
··· 11 11 obj-$(CONFIG_SND_ISIGHT) += snd-isight.o 12 12 obj-$(CONFIG_SND_SCS1X) += snd-scs1x.o 13 13 obj-$(CONFIG_SND_FIREWORKS) += fireworks/ 14 + obj-$(CONFIG_SND_BEBOB) += bebob/
+2
sound/firewire/bebob/Makefile
··· 1 + snd-bebob-objs := bebob.o 2 + obj-m += snd-bebob.o
+292
sound/firewire/bebob/bebob.c
··· 1 + /* 2 + * bebob.c - a part of driver for BeBoB based devices 3 + * 4 + * Copyright (c) 2013-2014 Takashi Sakamoto 5 + * 6 + * Licensed under the terms of the GNU General Public License, version 2. 7 + */ 8 + 9 + /* 10 + * BeBoB is 'BridgeCo enhanced Breakout Box'. This is installed to firewire 11 + * devices with DM1000/DM1100/DM1500 chipset. It gives common way for host 12 + * system to handle BeBoB based devices. 13 + */ 14 + 15 + #include "bebob.h" 16 + 17 + MODULE_DESCRIPTION("BridgeCo BeBoB driver"); 18 + MODULE_AUTHOR("Takashi Sakamoto <o-takashi@sakamocchi.jp>"); 19 + MODULE_LICENSE("GPL v2"); 20 + 21 + static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; 22 + static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; 23 + static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; 24 + 25 + module_param_array(index, int, NULL, 0444); 26 + MODULE_PARM_DESC(index, "card index"); 27 + module_param_array(id, charp, NULL, 0444); 28 + MODULE_PARM_DESC(id, "ID string"); 29 + module_param_array(enable, bool, NULL, 0444); 30 + MODULE_PARM_DESC(enable, "enable BeBoB sound card"); 31 + 32 + static DEFINE_MUTEX(devices_mutex); 33 + static DECLARE_BITMAP(devices_used, SNDRV_CARDS); 34 + 35 + /* Offsets from information register. */ 36 + #define INFO_OFFSET_GUID 0x10 37 + #define INFO_OFFSET_HW_MODEL_ID 0x18 38 + #define INFO_OFFSET_HW_MODEL_REVISION 0x1c 39 + 40 + #define VEN_EDIROL 0x000040ab 41 + #define VEN_PRESONUS 0x00000a92 42 + #define VEN_BRIDGECO 0x000007f5 43 + #define VEN_MACKIE 0x0000000f 44 + #define VEN_STANTON 0x00001260 45 + #define VEN_TASCAM 0x0000022e 46 + #define VEN_BEHRINGER 0x00001564 47 + #define VEN_APOGEE 0x000003db 48 + #define VEN_ESI 0x00000f1b 49 + #define VEN_ACOUSTIC 0x00000002 50 + #define VEN_CME 0x0000000a 51 + #define VEN_PHONIC 0x00001496 52 + #define VEN_LYNX 0x000019e5 53 + #define VEN_ICON 0x00001a9e 54 + #define VEN_PRISMSOUND 0x00001198 55 + 56 + static int 57 + name_device(struct snd_bebob *bebob, unsigned int vendor_id) 58 + { 59 + struct fw_device *fw_dev = fw_parent_device(bebob->unit); 60 + char vendor[24] = {0}; 61 + char model[32] = {0}; 62 + u32 id; 63 + u32 data[2] = {0}; 64 + u32 revision; 65 + int err; 66 + 67 + /* get vendor name from root directory */ 68 + err = fw_csr_string(fw_dev->config_rom + 5, CSR_VENDOR, 69 + vendor, sizeof(vendor)); 70 + if (err < 0) 71 + goto end; 72 + 73 + /* get model name from unit directory */ 74 + err = fw_csr_string(bebob->unit->directory, CSR_MODEL, 75 + model, sizeof(model)); 76 + if (err < 0) 77 + goto end; 78 + 79 + /* get hardware id */ 80 + err = snd_bebob_read_quad(bebob->unit, INFO_OFFSET_HW_MODEL_ID, 81 + &id); 82 + if (err < 0) 83 + goto end; 84 + 85 + /* get hardware revision */ 86 + err = snd_bebob_read_quad(bebob->unit, INFO_OFFSET_HW_MODEL_REVISION, 87 + &revision); 88 + if (err < 0) 89 + goto end; 90 + 91 + /* get GUID */ 92 + err = snd_bebob_read_block(bebob->unit, INFO_OFFSET_GUID, 93 + data, sizeof(data)); 94 + if (err < 0) 95 + goto end; 96 + 97 + strcpy(bebob->card->driver, "BeBoB"); 98 + strcpy(bebob->card->shortname, model); 99 + strcpy(bebob->card->mixername, model); 100 + snprintf(bebob->card->longname, sizeof(bebob->card->longname), 101 + "%s %s (id:%d, rev:%d), GUID %08x%08x at %s, S%d", 102 + vendor, model, id, revision, 103 + data[0], data[1], dev_name(&bebob->unit->device), 104 + 100 << fw_dev->max_speed); 105 + end: 106 + return err; 107 + } 108 + 109 + static void 110 + bebob_card_free(struct snd_card *card) 111 + { 112 + struct snd_bebob *bebob = card->private_data; 113 + 114 + if (bebob->card_index >= 0) { 115 + mutex_lock(&devices_mutex); 116 + clear_bit(bebob->card_index, devices_used); 117 + mutex_unlock(&devices_mutex); 118 + } 119 + 120 + mutex_destroy(&bebob->mutex); 121 + } 122 + 123 + static int 124 + bebob_probe(struct fw_unit *unit, 125 + const struct ieee1394_device_id *entry) 126 + { 127 + struct snd_card *card; 128 + struct snd_bebob *bebob; 129 + unsigned int card_index; 130 + int err; 131 + 132 + mutex_lock(&devices_mutex); 133 + 134 + for (card_index = 0; card_index < SNDRV_CARDS; card_index++) { 135 + if (!test_bit(card_index, devices_used) && enable[card_index]) 136 + break; 137 + } 138 + if (card_index >= SNDRV_CARDS) { 139 + err = -ENOENT; 140 + goto end; 141 + } 142 + 143 + err = snd_card_new(&unit->device, index[card_index], id[card_index], 144 + THIS_MODULE, sizeof(struct snd_bebob), &card); 145 + if (err < 0) 146 + goto end; 147 + bebob = card->private_data; 148 + bebob->card_index = card_index; 149 + set_bit(card_index, devices_used); 150 + card->private_free = bebob_card_free; 151 + 152 + bebob->card = card; 153 + bebob->unit = unit; 154 + mutex_init(&bebob->mutex); 155 + spin_lock_init(&bebob->lock); 156 + 157 + err = name_device(bebob, entry->vendor_id); 158 + if (err < 0) 159 + goto error; 160 + 161 + err = snd_card_register(card); 162 + if (err < 0) 163 + goto error; 164 + dev_set_drvdata(&unit->device, bebob); 165 + end: 166 + mutex_unlock(&devices_mutex); 167 + return err; 168 + error: 169 + mutex_unlock(&devices_mutex); 170 + snd_card_free(card); 171 + return err; 172 + } 173 + 174 + static void 175 + bebob_update(struct fw_unit *unit) 176 + { 177 + struct snd_bebob *bebob = dev_get_drvdata(&unit->device); 178 + fcp_bus_reset(bebob->unit); 179 + } 180 + 181 + static void bebob_remove(struct fw_unit *unit) 182 + { 183 + struct snd_bebob *bebob = dev_get_drvdata(&unit->device); 184 + snd_card_disconnect(bebob->card); 185 + snd_card_free_when_closed(bebob->card); 186 + } 187 + 188 + static const struct ieee1394_device_id bebob_id_table[] = { 189 + /* Edirol, FA-66 */ 190 + SND_BEBOB_DEV_ENTRY(VEN_EDIROL, 0x00010049), 191 + /* Edirol, FA-101 */ 192 + SND_BEBOB_DEV_ENTRY(VEN_EDIROL, 0x00010048), 193 + /* Presonus, FIREBOX */ 194 + SND_BEBOB_DEV_ENTRY(VEN_PRESONUS, 0x00010000), 195 + /* PreSonus, FIREPOD/FP10 */ 196 + SND_BEBOB_DEV_ENTRY(VEN_PRESONUS, 0x00010066), 197 + /* PreSonus, Inspire1394 */ 198 + SND_BEBOB_DEV_ENTRY(VEN_PRESONUS, 0x00010001), 199 + /* BridgeCo, RDAudio1 */ 200 + SND_BEBOB_DEV_ENTRY(VEN_BRIDGECO, 0x00010048), 201 + /* BridgeCo, Audio5 */ 202 + SND_BEBOB_DEV_ENTRY(VEN_BRIDGECO, 0x00010049), 203 + /* Mackie, Onyx 1220/1620/1640 (Firewire I/O Card) */ 204 + SND_BEBOB_DEV_ENTRY(VEN_MACKIE, 0x00010065), 205 + /* Mackie, d.2 (Firewire Option) */ 206 + SND_BEBOB_DEV_ENTRY(VEN_MACKIE, 0x00010067), 207 + /* Stanton, ScratchAmp */ 208 + SND_BEBOB_DEV_ENTRY(VEN_STANTON, 0x00000001), 209 + /* Tascam, IF-FW DM */ 210 + SND_BEBOB_DEV_ENTRY(VEN_TASCAM, 0x00010067), 211 + /* Behringer, XENIX UFX 1204 */ 212 + SND_BEBOB_DEV_ENTRY(VEN_BEHRINGER, 0x00001204), 213 + /* Behringer, XENIX UFX 1604 */ 214 + SND_BEBOB_DEV_ENTRY(VEN_BEHRINGER, 0x00001604), 215 + /* Behringer, Digital Mixer X32 series (X-UF Card) */ 216 + SND_BEBOB_DEV_ENTRY(VEN_BEHRINGER, 0x00000006), 217 + /* Apogee Electronics, Rosetta 200/400 (X-FireWire card) */ 218 + /* Apogee Electronics, DA/AD/DD-16X (X-FireWire card) */ 219 + SND_BEBOB_DEV_ENTRY(VEN_APOGEE, 0x00010048), 220 + /* Apogee Electronics, Ensemble */ 221 + SND_BEBOB_DEV_ENTRY(VEN_APOGEE, 0x00001eee), 222 + /* ESI, Quatafire610 */ 223 + SND_BEBOB_DEV_ENTRY(VEN_ESI, 0x00010064), 224 + /* AcousticReality, eARMasterOne */ 225 + SND_BEBOB_DEV_ENTRY(VEN_ACOUSTIC, 0x00000002), 226 + /* CME, MatrixKFW */ 227 + SND_BEBOB_DEV_ENTRY(VEN_CME, 0x00030000), 228 + /* Phonic, Helix Board 12 MkII */ 229 + SND_BEBOB_DEV_ENTRY(VEN_PHONIC, 0x00050000), 230 + /* Phonic, Helix Board 18 MkII */ 231 + SND_BEBOB_DEV_ENTRY(VEN_PHONIC, 0x00060000), 232 + /* Phonic, Helix Board 24 MkII */ 233 + SND_BEBOB_DEV_ENTRY(VEN_PHONIC, 0x00070000), 234 + /* Phonic, Helix Board 12 Universal/18 Universal/24 Universal */ 235 + SND_BEBOB_DEV_ENTRY(VEN_PHONIC, 0x00000000), 236 + /* Lynx, Aurora 8/16 (LT-FW) */ 237 + SND_BEBOB_DEV_ENTRY(VEN_LYNX, 0x00000001), 238 + /* ICON, FireXon */ 239 + SND_BEBOB_DEV_ENTRY(VEN_ICON, 0x00000001), 240 + /* PrismSound, Orpheus */ 241 + SND_BEBOB_DEV_ENTRY(VEN_PRISMSOUND, 0x00010048), 242 + /* PrismSound, ADA-8XR */ 243 + SND_BEBOB_DEV_ENTRY(VEN_PRISMSOUND, 0x0000ada8), 244 + /* IDs are unknown but able to be supported */ 245 + /* Apogee, Mini-ME Firewire */ 246 + /* Apogee, Mini-DAC Firewire */ 247 + /* Behringer, F-Control Audio 1616 */ 248 + /* Behringer, F-Control Audio 610 */ 249 + /* Cakawalk, Sonar Power Studio 66 */ 250 + /* CME, UF400e */ 251 + /* ESI, Quotafire XL */ 252 + /* Infrasonic, DewX */ 253 + /* Infrasonic, Windy6 */ 254 + /* Mackie, Digital X Bus x.200 */ 255 + /* Mackie, Digital X Bus x.400 */ 256 + /* Phonic, HB 12 */ 257 + /* Phonic, HB 24 */ 258 + /* Phonic, HB 18 */ 259 + /* Phonic, FireFly 202 */ 260 + /* Phonic, FireFly 302 */ 261 + /* Rolf Spuler, Firewire Guitar */ 262 + {} 263 + }; 264 + MODULE_DEVICE_TABLE(ieee1394, bebob_id_table); 265 + 266 + static struct fw_driver bebob_driver = { 267 + .driver = { 268 + .owner = THIS_MODULE, 269 + .name = "snd-bebob", 270 + .bus = &fw_bus_type, 271 + }, 272 + .probe = bebob_probe, 273 + .update = bebob_update, 274 + .remove = bebob_remove, 275 + .id_table = bebob_id_table, 276 + }; 277 + 278 + static int __init 279 + snd_bebob_init(void) 280 + { 281 + return driver_register(&bebob_driver.driver); 282 + } 283 + 284 + static void __exit 285 + snd_bebob_exit(void) 286 + { 287 + driver_unregister(&bebob_driver.driver); 288 + mutex_destroy(&devices_mutex); 289 + } 290 + 291 + module_init(snd_bebob_init); 292 + module_exit(snd_bebob_exit);
+64
sound/firewire/bebob/bebob.h
··· 1 + /* 2 + * bebob.h - a part of driver for BeBoB based devices 3 + * 4 + * Copyright (c) 2013-2014 Takashi Sakamoto 5 + * 6 + * Licensed under the terms of the GNU General Public License, version 2. 7 + */ 8 + 9 + #ifndef SOUND_BEBOB_H_INCLUDED 10 + #define SOUND_BEBOB_H_INCLUDED 11 + 12 + #include <linux/compat.h> 13 + #include <linux/device.h> 14 + #include <linux/firewire.h> 15 + #include <linux/firewire-constants.h> 16 + #include <linux/module.h> 17 + #include <linux/mod_devicetable.h> 18 + #include <linux/delay.h> 19 + #include <linux/slab.h> 20 + 21 + #include <sound/core.h> 22 + #include <sound/initval.h> 23 + 24 + #include "../lib.h" 25 + #include "../fcp.h" 26 + 27 + /* basic register addresses on DM1000/DM1100/DM1500 */ 28 + #define BEBOB_ADDR_REG_INFO 0xffffc8020000 29 + #define BEBOB_ADDR_REG_REQ 0xffffc8021000 30 + 31 + struct snd_bebob { 32 + struct snd_card *card; 33 + struct fw_unit *unit; 34 + int card_index; 35 + 36 + struct mutex mutex; 37 + spinlock_t lock; 38 + }; 39 + 40 + static inline int 41 + snd_bebob_read_block(struct fw_unit *unit, u64 addr, void *buf, int size) 42 + { 43 + return snd_fw_transaction(unit, TCODE_READ_BLOCK_REQUEST, 44 + BEBOB_ADDR_REG_INFO + addr, 45 + buf, size, 0); 46 + } 47 + 48 + static inline int 49 + snd_bebob_read_quad(struct fw_unit *unit, u64 addr, u32 *buf) 50 + { 51 + return snd_fw_transaction(unit, TCODE_READ_QUADLET_REQUEST, 52 + BEBOB_ADDR_REG_INFO + addr, 53 + (void *)buf, sizeof(u32), 0); 54 + } 55 + 56 + #define SND_BEBOB_DEV_ENTRY(vendor, model) \ 57 + { \ 58 + .match_flags = IEEE1394_MATCH_VENDOR_ID | \ 59 + IEEE1394_MATCH_MODEL_ID, \ 60 + .vendor_id = vendor, \ 61 + .model_id = model, \ 62 + } 63 + 64 + #endif