]> Git Repo - linux.git/blob - sound/firewire/fireface/ff.c
Merge tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm
[linux.git] / sound / firewire / fireface / ff.c
1 /*
2  * ff.c - a part of driver for RME Fireface series
3  *
4  * Copyright (c) 2015-2017 Takashi Sakamoto
5  *
6  * Licensed under the terms of the GNU General Public License, version 2.
7  */
8
9 #include "ff.h"
10
11 #define OUI_RME 0x000a35
12
13 MODULE_DESCRIPTION("RME Fireface series Driver");
14 MODULE_AUTHOR("Takashi Sakamoto <[email protected]>");
15 MODULE_LICENSE("GPL v2");
16
17 static void name_card(struct snd_ff *ff)
18 {
19         struct fw_device *fw_dev = fw_parent_device(ff->unit);
20
21         strcpy(ff->card->driver, "Fireface");
22         strcpy(ff->card->shortname, ff->spec->name);
23         strcpy(ff->card->mixername, ff->spec->name);
24         snprintf(ff->card->longname, sizeof(ff->card->longname),
25                  "RME %s, GUID %08x%08x at %s, S%d", ff->spec->name,
26                  fw_dev->config_rom[3], fw_dev->config_rom[4],
27                  dev_name(&ff->unit->device), 100 << fw_dev->max_speed);
28 }
29
30 static void ff_card_free(struct snd_card *card)
31 {
32         struct snd_ff *ff = card->private_data;
33
34         snd_ff_stream_destroy_duplex(ff);
35         snd_ff_transaction_unregister(ff);
36 }
37
38 static void do_registration(struct work_struct *work)
39 {
40         struct snd_ff *ff = container_of(work, struct snd_ff, dwork.work);
41         int err;
42
43         if (ff->registered)
44                 return;
45
46         err = snd_card_new(&ff->unit->device, -1, NULL, THIS_MODULE, 0,
47                            &ff->card);
48         if (err < 0)
49                 return;
50         ff->card->private_free = ff_card_free;
51         ff->card->private_data = ff;
52
53         err = snd_ff_transaction_register(ff);
54         if (err < 0)
55                 goto error;
56
57         name_card(ff);
58
59         err = snd_ff_stream_init_duplex(ff);
60         if (err < 0)
61                 goto error;
62
63         snd_ff_proc_init(ff);
64
65         err = snd_ff_create_midi_devices(ff);
66         if (err < 0)
67                 goto error;
68
69         err = snd_ff_create_pcm_devices(ff);
70         if (err < 0)
71                 goto error;
72
73         err = snd_ff_create_hwdep_devices(ff);
74         if (err < 0)
75                 goto error;
76
77         err = snd_card_register(ff->card);
78         if (err < 0)
79                 goto error;
80
81         ff->registered = true;
82
83         return;
84 error:
85         snd_card_free(ff->card);
86         dev_info(&ff->unit->device,
87                  "Sound card registration failed: %d\n", err);
88 }
89
90 static int snd_ff_probe(struct fw_unit *unit,
91                            const struct ieee1394_device_id *entry)
92 {
93         struct snd_ff *ff;
94
95         ff = devm_kzalloc(&unit->device, sizeof(struct snd_ff), GFP_KERNEL);
96         if (!ff)
97                 return -ENOMEM;
98         ff->unit = fw_unit_get(unit);
99         dev_set_drvdata(&unit->device, ff);
100
101         mutex_init(&ff->mutex);
102         spin_lock_init(&ff->lock);
103         init_waitqueue_head(&ff->hwdep_wait);
104
105         ff->spec = (const struct snd_ff_spec *)entry->driver_data;
106
107         /* Register this sound card later. */
108         INIT_DEFERRABLE_WORK(&ff->dwork, do_registration);
109         snd_fw_schedule_registration(unit, &ff->dwork);
110
111         return 0;
112 }
113
114 static void snd_ff_update(struct fw_unit *unit)
115 {
116         struct snd_ff *ff = dev_get_drvdata(&unit->device);
117
118         /* Postpone a workqueue for deferred registration. */
119         if (!ff->registered)
120                 snd_fw_schedule_registration(unit, &ff->dwork);
121
122         snd_ff_transaction_reregister(ff);
123
124         if (ff->registered)
125                 snd_ff_stream_update_duplex(ff);
126 }
127
128 static void snd_ff_remove(struct fw_unit *unit)
129 {
130         struct snd_ff *ff = dev_get_drvdata(&unit->device);
131
132         /*
133          * Confirm to stop the work for registration before the sound card is
134          * going to be released. The work is not scheduled again because bus
135          * reset handler is not called anymore.
136          */
137         cancel_work_sync(&ff->dwork.work);
138
139         if (ff->registered) {
140                 // Block till all of ALSA character devices are released.
141                 snd_card_free(ff->card);
142         }
143
144         mutex_destroy(&ff->mutex);
145         fw_unit_put(ff->unit);
146 }
147
148 static const struct snd_ff_spec spec_ff800 = {
149         .name = "Fireface800",
150         .pcm_capture_channels = {28, 20, 12},
151         .pcm_playback_channels = {28, 20, 12},
152         .midi_in_ports = 1,
153         .midi_out_ports = 1,
154         .protocol = &snd_ff_protocol_ff800,
155         .midi_high_addr = 0x000200000320ull,
156 };
157
158 static const struct snd_ff_spec spec_ff400 = {
159         .name = "Fireface400",
160         .pcm_capture_channels = {18, 14, 10},
161         .pcm_playback_channels = {18, 14, 10},
162         .midi_in_ports = 2,
163         .midi_out_ports = 2,
164         .protocol = &snd_ff_protocol_ff400,
165         .midi_high_addr = 0x0000801003f4ull,
166 };
167
168 static const struct ieee1394_device_id snd_ff_id_table[] = {
169         /* Fireface 800 */
170         {
171                 .match_flags    = IEEE1394_MATCH_VENDOR_ID |
172                                   IEEE1394_MATCH_SPECIFIER_ID |
173                                   IEEE1394_MATCH_VERSION |
174                                   IEEE1394_MATCH_MODEL_ID,
175                 .vendor_id      = OUI_RME,
176                 .specifier_id   = OUI_RME,
177                 .version        = 0x000001,
178                 .model_id       = 0x101800,
179                 .driver_data    = (kernel_ulong_t)&spec_ff800,
180         },
181         /* Fireface 400 */
182         {
183                 .match_flags    = IEEE1394_MATCH_VENDOR_ID |
184                                   IEEE1394_MATCH_SPECIFIER_ID |
185                                   IEEE1394_MATCH_VERSION |
186                                   IEEE1394_MATCH_MODEL_ID,
187                 .vendor_id      = OUI_RME,
188                 .specifier_id   = OUI_RME,
189                 .version        = 0x000002,
190                 .model_id       = 0x101800,
191                 .driver_data    = (kernel_ulong_t)&spec_ff400,
192         },
193         {}
194 };
195 MODULE_DEVICE_TABLE(ieee1394, snd_ff_id_table);
196
197 static struct fw_driver ff_driver = {
198         .driver = {
199                 .owner  = THIS_MODULE,
200                 .name   = "snd-fireface",
201                 .bus    = &fw_bus_type,
202         },
203         .probe    = snd_ff_probe,
204         .update   = snd_ff_update,
205         .remove   = snd_ff_remove,
206         .id_table = snd_ff_id_table,
207 };
208
209 static int __init snd_ff_init(void)
210 {
211         return driver_register(&ff_driver.driver);
212 }
213
214 static void __exit snd_ff_exit(void)
215 {
216         driver_unregister(&ff_driver.driver);
217 }
218
219 module_init(snd_ff_init);
220 module_exit(snd_ff_exit);
This page took 0.044229 seconds and 4 git commands to generate.