Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * ff.c - a part of driver for RME Fireface series
0004  *
0005  * Copyright (c) 2015-2017 Takashi Sakamoto
0006  */
0007 
0008 #include "ff.h"
0009 
0010 #define OUI_RME 0x000a35
0011 
0012 MODULE_DESCRIPTION("RME Fireface series Driver");
0013 MODULE_AUTHOR("Takashi Sakamoto <o-takashi@sakamocchi.jp>");
0014 MODULE_LICENSE("GPL v2");
0015 
0016 static void name_card(struct snd_ff *ff)
0017 {
0018     struct fw_device *fw_dev = fw_parent_device(ff->unit);
0019     const char *const names[] = {
0020         [SND_FF_UNIT_VERSION_FF800] = "Fireface800",
0021         [SND_FF_UNIT_VERSION_FF400] = "Fireface400",
0022         [SND_FF_UNIT_VERSION_UFX]   = "FirefaceUFX",
0023         [SND_FF_UNIT_VERSION_UCX]   = "FirefaceUCX",
0024         [SND_FF_UNIT_VERSION_802]   = "Fireface802",
0025     };
0026     const char *name;
0027 
0028     name = names[ff->unit_version];
0029 
0030     strcpy(ff->card->driver, "Fireface");
0031     strcpy(ff->card->shortname, name);
0032     strcpy(ff->card->mixername, name);
0033     snprintf(ff->card->longname, sizeof(ff->card->longname),
0034          "RME %s, GUID %08x%08x at %s, S%d", name,
0035          fw_dev->config_rom[3], fw_dev->config_rom[4],
0036          dev_name(&ff->unit->device), 100 << fw_dev->max_speed);
0037 }
0038 
0039 static void ff_card_free(struct snd_card *card)
0040 {
0041     struct snd_ff *ff = card->private_data;
0042 
0043     snd_ff_stream_destroy_duplex(ff);
0044     snd_ff_transaction_unregister(ff);
0045 
0046     mutex_destroy(&ff->mutex);
0047     fw_unit_put(ff->unit);
0048 }
0049 
0050 static int snd_ff_probe(struct fw_unit *unit, const struct ieee1394_device_id *entry)
0051 {
0052     struct snd_card *card;
0053     struct snd_ff *ff;
0054     int err;
0055 
0056     err = snd_card_new(&unit->device, -1, NULL, THIS_MODULE, sizeof(*ff), &card);
0057     if (err < 0)
0058         return err;
0059     card->private_free = ff_card_free;
0060 
0061     ff = card->private_data;
0062     ff->unit = fw_unit_get(unit);
0063     dev_set_drvdata(&unit->device, ff);
0064     ff->card = card;
0065 
0066     mutex_init(&ff->mutex);
0067     spin_lock_init(&ff->lock);
0068     init_waitqueue_head(&ff->hwdep_wait);
0069 
0070     ff->unit_version = entry->version;
0071     ff->spec = (const struct snd_ff_spec *)entry->driver_data;
0072 
0073     err = snd_ff_transaction_register(ff);
0074     if (err < 0)
0075         goto error;
0076 
0077     name_card(ff);
0078 
0079     err = snd_ff_stream_init_duplex(ff);
0080     if (err < 0)
0081         goto error;
0082 
0083     snd_ff_proc_init(ff);
0084 
0085     err = snd_ff_create_midi_devices(ff);
0086     if (err < 0)
0087         goto error;
0088 
0089     err = snd_ff_create_pcm_devices(ff);
0090     if (err < 0)
0091         goto error;
0092 
0093     err = snd_ff_create_hwdep_devices(ff);
0094     if (err < 0)
0095         goto error;
0096 
0097     err = snd_card_register(card);
0098     if (err < 0)
0099         goto error;
0100 
0101     return 0;
0102 error:
0103     snd_card_free(card);
0104     return err;
0105 }
0106 
0107 static void snd_ff_update(struct fw_unit *unit)
0108 {
0109     struct snd_ff *ff = dev_get_drvdata(&unit->device);
0110 
0111     snd_ff_transaction_reregister(ff);
0112 
0113     snd_ff_stream_update_duplex(ff);
0114 }
0115 
0116 static void snd_ff_remove(struct fw_unit *unit)
0117 {
0118     struct snd_ff *ff = dev_get_drvdata(&unit->device);
0119 
0120     // Block till all of ALSA character devices are released.
0121     snd_card_free(ff->card);
0122 }
0123 
0124 static const struct snd_ff_spec spec_ff800 = {
0125     .pcm_capture_channels = {28, 20, 12},
0126     .pcm_playback_channels = {28, 20, 12},
0127     .midi_in_ports = 1,
0128     .midi_out_ports = 1,
0129     .protocol = &snd_ff_protocol_ff800,
0130     .midi_high_addr = 0x000200000320ull,
0131     .midi_addr_range = 12,
0132     .midi_rx_addrs = {0x000080180000ull, 0},
0133 };
0134 
0135 static const struct snd_ff_spec spec_ff400 = {
0136     .pcm_capture_channels = {18, 14, 10},
0137     .pcm_playback_channels = {18, 14, 10},
0138     .midi_in_ports = 2,
0139     .midi_out_ports = 2,
0140     .protocol = &snd_ff_protocol_ff400,
0141     .midi_high_addr = 0x0000801003f4ull,
0142     .midi_addr_range = SND_FF_MAXIMIM_MIDI_QUADS * 4,
0143     .midi_rx_addrs = {0x000080180000ull, 0x000080190000ull},
0144 };
0145 
0146 static const struct snd_ff_spec spec_ucx = {
0147     .pcm_capture_channels = {18, 14, 12},
0148     .pcm_playback_channels = {18, 14, 12},
0149     .midi_in_ports = 2,
0150     .midi_out_ports = 2,
0151     .protocol = &snd_ff_protocol_latter,
0152     .midi_high_addr = 0xffff00000034ull,
0153     .midi_addr_range = 0x80,
0154     .midi_rx_addrs = {0xffff00000030ull, 0xffff00000030ull},
0155 };
0156 
0157 static const struct snd_ff_spec spec_ufx_802 = {
0158     .pcm_capture_channels = {30, 22, 14},
0159     .pcm_playback_channels = {30, 22, 14},
0160     .midi_in_ports = 1,
0161     .midi_out_ports = 1,
0162     .protocol = &snd_ff_protocol_latter,
0163     .midi_high_addr = 0xffff00000034ull,
0164     .midi_addr_range = 0x80,
0165     .midi_rx_addrs = {0xffff00000030ull, 0xffff00000030ull},
0166 };
0167 
0168 static const struct ieee1394_device_id snd_ff_id_table[] = {
0169     /* Fireface 800 */
0170     {
0171         .match_flags    = IEEE1394_MATCH_VENDOR_ID |
0172                   IEEE1394_MATCH_SPECIFIER_ID |
0173                   IEEE1394_MATCH_VERSION |
0174                   IEEE1394_MATCH_MODEL_ID,
0175         .vendor_id  = OUI_RME,
0176         .specifier_id   = OUI_RME,
0177         .version    = SND_FF_UNIT_VERSION_FF800,
0178         .model_id   = 0x101800,
0179         .driver_data    = (kernel_ulong_t)&spec_ff800,
0180     },
0181     /* Fireface 400 */
0182     {
0183         .match_flags    = IEEE1394_MATCH_VENDOR_ID |
0184                   IEEE1394_MATCH_SPECIFIER_ID |
0185                   IEEE1394_MATCH_VERSION |
0186                   IEEE1394_MATCH_MODEL_ID,
0187         .vendor_id  = OUI_RME,
0188         .specifier_id   = OUI_RME,
0189         .version    = SND_FF_UNIT_VERSION_FF400,
0190         .model_id   = 0x101800,
0191         .driver_data    = (kernel_ulong_t)&spec_ff400,
0192     },
0193     // Fireface UFX.
0194     {
0195         .match_flags    = IEEE1394_MATCH_VENDOR_ID |
0196                   IEEE1394_MATCH_SPECIFIER_ID |
0197                   IEEE1394_MATCH_VERSION |
0198                   IEEE1394_MATCH_MODEL_ID,
0199         .vendor_id  = OUI_RME,
0200         .specifier_id   = OUI_RME,
0201         .version    = SND_FF_UNIT_VERSION_UFX,
0202         .model_id   = 0x101800,
0203         .driver_data    = (kernel_ulong_t)&spec_ufx_802,
0204     },
0205     // Fireface UCX.
0206     {
0207         .match_flags    = IEEE1394_MATCH_VENDOR_ID |
0208                   IEEE1394_MATCH_SPECIFIER_ID |
0209                   IEEE1394_MATCH_VERSION |
0210                   IEEE1394_MATCH_MODEL_ID,
0211         .vendor_id  = OUI_RME,
0212         .specifier_id   = OUI_RME,
0213         .version    = SND_FF_UNIT_VERSION_UCX,
0214         .model_id   = 0x101800,
0215         .driver_data    = (kernel_ulong_t)&spec_ucx,
0216     },
0217     // Fireface 802.
0218     {
0219         .match_flags    = IEEE1394_MATCH_VENDOR_ID |
0220                   IEEE1394_MATCH_SPECIFIER_ID |
0221                   IEEE1394_MATCH_VERSION |
0222                   IEEE1394_MATCH_MODEL_ID,
0223         .vendor_id  = OUI_RME,
0224         .specifier_id   = OUI_RME,
0225         .version    = SND_FF_UNIT_VERSION_802,
0226         .model_id   = 0x101800,
0227         .driver_data    = (kernel_ulong_t)&spec_ufx_802,
0228     },
0229     {}
0230 };
0231 MODULE_DEVICE_TABLE(ieee1394, snd_ff_id_table);
0232 
0233 static struct fw_driver ff_driver = {
0234     .driver = {
0235         .owner  = THIS_MODULE,
0236         .name   = KBUILD_MODNAME,
0237         .bus    = &fw_bus_type,
0238     },
0239     .probe    = snd_ff_probe,
0240     .update   = snd_ff_update,
0241     .remove   = snd_ff_remove,
0242     .id_table = snd_ff_id_table,
0243 };
0244 
0245 static int __init snd_ff_init(void)
0246 {
0247     return driver_register(&ff_driver.driver);
0248 }
0249 
0250 static void __exit snd_ff_exit(void)
0251 {
0252     driver_unregister(&ff_driver.driver);
0253 }
0254 
0255 module_init(snd_ff_init);
0256 module_exit(snd_ff_exit);