1 /* 2 * digi00x.c - a part of driver for Digidesign Digi 002/003 family 3 * 4 * Copyright (c) 2014-2015 Takashi Sakamoto 5 * 6 * Licensed under the terms of the GNU General Public License, version 2. 7 */ 8 9 #include "digi00x.h" 10 11 MODULE_DESCRIPTION("Digidesign Digi 002/003 family Driver"); 12 MODULE_AUTHOR("Takashi Sakamoto <o-takashi@sakamocchi.jp>"); 13 MODULE_LICENSE("GPL v2"); 14 15 #define VENDOR_DIGIDESIGN 0x00a07e 16 #define MODEL_CONSOLE 0x000001 17 #define MODEL_RACK 0x000002 18 19 static int name_card(struct snd_dg00x *dg00x) 20 { 21 struct fw_device *fw_dev = fw_parent_device(dg00x->unit); 22 char name[32] = {0}; 23 char *model; 24 int err; 25 26 err = fw_csr_string(dg00x->unit->directory, CSR_MODEL, name, 27 sizeof(name)); 28 if (err < 0) 29 return err; 30 31 model = skip_spaces(name); 32 33 strcpy(dg00x->card->driver, "Digi00x"); 34 strcpy(dg00x->card->shortname, model); 35 strcpy(dg00x->card->mixername, model); 36 snprintf(dg00x->card->longname, sizeof(dg00x->card->longname), 37 "Digidesign %s, GUID %08x%08x at %s, S%d", model, 38 fw_dev->config_rom[3], fw_dev->config_rom[4], 39 dev_name(&dg00x->unit->device), 100 << fw_dev->max_speed); 40 41 return 0; 42 } 43 44 static void dg00x_free(struct snd_dg00x *dg00x) 45 { 46 snd_dg00x_stream_destroy_duplex(dg00x); 47 snd_dg00x_transaction_unregister(dg00x); 48 49 fw_unit_put(dg00x->unit); 50 51 mutex_destroy(&dg00x->mutex); 52 } 53 54 static void dg00x_card_free(struct snd_card *card) 55 { 56 dg00x_free(card->private_data); 57 } 58 59 static void do_registration(struct work_struct *work) 60 { 61 struct snd_dg00x *dg00x = 62 container_of(work, struct snd_dg00x, dwork.work); 63 int err; 64 65 if (dg00x->registered) 66 return; 67 68 err = snd_card_new(&dg00x->unit->device, -1, NULL, THIS_MODULE, 0, 69 &dg00x->card); 70 if (err < 0) 71 return; 72 73 err = name_card(dg00x); 74 if (err < 0) 75 goto error; 76 77 err = snd_dg00x_stream_init_duplex(dg00x); 78 if (err < 0) 79 goto error; 80 81 snd_dg00x_proc_init(dg00x); 82 83 err = snd_dg00x_create_pcm_devices(dg00x); 84 if (err < 0) 85 goto error; 86 87 err = snd_dg00x_create_midi_devices(dg00x); 88 if (err < 0) 89 goto error; 90 91 err = snd_dg00x_create_hwdep_device(dg00x); 92 if (err < 0) 93 goto error; 94 95 err = snd_dg00x_transaction_register(dg00x); 96 if (err < 0) 97 goto error; 98 99 err = snd_card_register(dg00x->card); 100 if (err < 0) 101 goto error; 102 103 dg00x->card->private_free = dg00x_card_free; 104 dg00x->card->private_data = dg00x; 105 dg00x->registered = true; 106 107 return; 108 error: 109 snd_dg00x_transaction_unregister(dg00x); 110 snd_dg00x_stream_destroy_duplex(dg00x); 111 snd_card_free(dg00x->card); 112 dev_info(&dg00x->unit->device, 113 "Sound card registration failed: %d\n", err); 114 } 115 116 static int snd_dg00x_probe(struct fw_unit *unit, 117 const struct ieee1394_device_id *entry) 118 { 119 struct snd_dg00x *dg00x; 120 121 /* Allocate this independent of sound card instance. */ 122 dg00x = kzalloc(sizeof(struct snd_dg00x), GFP_KERNEL); 123 if (dg00x == NULL) 124 return -ENOMEM; 125 126 dg00x->unit = fw_unit_get(unit); 127 dev_set_drvdata(&unit->device, dg00x); 128 129 mutex_init(&dg00x->mutex); 130 spin_lock_init(&dg00x->lock); 131 init_waitqueue_head(&dg00x->hwdep_wait); 132 133 dg00x->is_console = entry->model_id == MODEL_CONSOLE; 134 135 /* Allocate and register this sound card later. */ 136 INIT_DEFERRABLE_WORK(&dg00x->dwork, do_registration); 137 snd_fw_schedule_registration(unit, &dg00x->dwork); 138 139 return 0; 140 } 141 142 static void snd_dg00x_update(struct fw_unit *unit) 143 { 144 struct snd_dg00x *dg00x = dev_get_drvdata(&unit->device); 145 146 /* Postpone a workqueue for deferred registration. */ 147 if (!dg00x->registered) 148 snd_fw_schedule_registration(unit, &dg00x->dwork); 149 150 snd_dg00x_transaction_reregister(dg00x); 151 152 /* 153 * After registration, userspace can start packet streaming, then this 154 * code block works fine. 155 */ 156 if (dg00x->registered) { 157 mutex_lock(&dg00x->mutex); 158 snd_dg00x_stream_update_duplex(dg00x); 159 mutex_unlock(&dg00x->mutex); 160 } 161 } 162 163 static void snd_dg00x_remove(struct fw_unit *unit) 164 { 165 struct snd_dg00x *dg00x = dev_get_drvdata(&unit->device); 166 167 /* 168 * Confirm to stop the work for registration before the sound card is 169 * going to be released. The work is not scheduled again because bus 170 * reset handler is not called anymore. 171 */ 172 cancel_delayed_work_sync(&dg00x->dwork); 173 174 if (dg00x->registered) { 175 /* No need to wait for releasing card object in this context. */ 176 snd_card_free_when_closed(dg00x->card); 177 } else { 178 /* Don't forget this case. */ 179 dg00x_free(dg00x); 180 } 181 } 182 183 static const struct ieee1394_device_id snd_dg00x_id_table[] = { 184 /* Both of 002/003 use the same ID. */ 185 { 186 .match_flags = IEEE1394_MATCH_VENDOR_ID | 187 IEEE1394_MATCH_MODEL_ID, 188 .vendor_id = VENDOR_DIGIDESIGN, 189 .model_id = MODEL_CONSOLE, 190 }, 191 { 192 .match_flags = IEEE1394_MATCH_VENDOR_ID | 193 IEEE1394_MATCH_MODEL_ID, 194 .vendor_id = VENDOR_DIGIDESIGN, 195 .model_id = MODEL_RACK, 196 }, 197 {} 198 }; 199 MODULE_DEVICE_TABLE(ieee1394, snd_dg00x_id_table); 200 201 static struct fw_driver dg00x_driver = { 202 .driver = { 203 .owner = THIS_MODULE, 204 .name = "snd-firewire-digi00x", 205 .bus = &fw_bus_type, 206 }, 207 .probe = snd_dg00x_probe, 208 .update = snd_dg00x_update, 209 .remove = snd_dg00x_remove, 210 .id_table = snd_dg00x_id_table, 211 }; 212 213 static int __init snd_dg00x_init(void) 214 { 215 return driver_register(&dg00x_driver.driver); 216 } 217 218 static void __exit snd_dg00x_exit(void) 219 { 220 driver_unregister(&dg00x_driver.driver); 221 } 222 223 module_init(snd_dg00x_init); 224 module_exit(snd_dg00x_exit); 225