GNU Linux-libre 4.14.328-gnu1
[releases.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 <o-takashi@sakamocchi.jp>");
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_free(struct snd_ff *ff)
31 {
32         snd_ff_stream_destroy_duplex(ff);
33         snd_ff_transaction_unregister(ff);
34
35         fw_unit_put(ff->unit);
36
37         mutex_destroy(&ff->mutex);
38         kfree(ff);
39 }
40
41 static void ff_card_free(struct snd_card *card)
42 {
43         ff_free(card->private_data);
44 }
45
46 static void do_registration(struct work_struct *work)
47 {
48         struct snd_ff *ff = container_of(work, struct snd_ff, dwork.work);
49         int err;
50
51         if (ff->registered)
52                 return;
53
54         err = snd_card_new(&ff->unit->device, -1, NULL, THIS_MODULE, 0,
55                            &ff->card);
56         if (err < 0)
57                 return;
58
59         err = snd_ff_transaction_register(ff);
60         if (err < 0)
61                 goto error;
62
63         name_card(ff);
64
65         err = snd_ff_stream_init_duplex(ff);
66         if (err < 0)
67                 goto error;
68
69         snd_ff_proc_init(ff);
70
71         err = snd_ff_create_midi_devices(ff);
72         if (err < 0)
73                 goto error;
74
75         err = snd_ff_create_pcm_devices(ff);
76         if (err < 0)
77                 goto error;
78
79         err = snd_ff_create_hwdep_devices(ff);
80         if (err < 0)
81                 goto error;
82
83         err = snd_card_register(ff->card);
84         if (err < 0)
85                 goto error;
86
87         ff->card->private_free = ff_card_free;
88         ff->card->private_data = ff;
89         ff->registered = true;
90
91         return;
92 error:
93         snd_ff_transaction_unregister(ff);
94         snd_ff_stream_destroy_duplex(ff);
95         snd_card_free(ff->card);
96         dev_info(&ff->unit->device,
97                  "Sound card registration failed: %d\n", err);
98 }
99
100 static int snd_ff_probe(struct fw_unit *unit,
101                            const struct ieee1394_device_id *entry)
102 {
103         struct snd_ff *ff;
104
105         ff = kzalloc(sizeof(struct snd_ff), GFP_KERNEL);
106         if (ff == NULL)
107                 return -ENOMEM;
108
109         /* initialize myself */
110         ff->unit = fw_unit_get(unit);
111         dev_set_drvdata(&unit->device, ff);
112
113         mutex_init(&ff->mutex);
114         spin_lock_init(&ff->lock);
115         init_waitqueue_head(&ff->hwdep_wait);
116
117         ff->spec = (const struct snd_ff_spec *)entry->driver_data;
118
119         /* Register this sound card later. */
120         INIT_DEFERRABLE_WORK(&ff->dwork, do_registration);
121         snd_fw_schedule_registration(unit, &ff->dwork);
122
123         return 0;
124 }
125
126 static void snd_ff_update(struct fw_unit *unit)
127 {
128         struct snd_ff *ff = dev_get_drvdata(&unit->device);
129
130         /* Postpone a workqueue for deferred registration. */
131         if (!ff->registered)
132                 snd_fw_schedule_registration(unit, &ff->dwork);
133
134         snd_ff_transaction_reregister(ff);
135
136         if (ff->registered)
137                 snd_ff_stream_update_duplex(ff);
138 }
139
140 static void snd_ff_remove(struct fw_unit *unit)
141 {
142         struct snd_ff *ff = dev_get_drvdata(&unit->device);
143
144         /*
145          * Confirm to stop the work for registration before the sound card is
146          * going to be released. The work is not scheduled again because bus
147          * reset handler is not called anymore.
148          */
149         cancel_work_sync(&ff->dwork.work);
150
151         if (ff->registered) {
152                 /* No need to wait for releasing card object in this context. */
153                 snd_card_free_when_closed(ff->card);
154         } else {
155                 /* Don't forget this case. */
156                 ff_free(ff);
157         }
158 }
159
160 static const struct snd_ff_spec spec_ff400 = {
161         .name = "Fireface400",
162         .pcm_capture_channels = {18, 14, 10},
163         .pcm_playback_channels = {18, 14, 10},
164         .midi_in_ports = 2,
165         .midi_out_ports = 2,
166         .protocol = &snd_ff_protocol_ff400,
167 };
168
169 static const struct ieee1394_device_id snd_ff_id_table[] = {
170         /* Fireface 400 */
171         {
172                 .match_flags    = IEEE1394_MATCH_VENDOR_ID |
173                                   IEEE1394_MATCH_SPECIFIER_ID |
174                                   IEEE1394_MATCH_VERSION |
175                                   IEEE1394_MATCH_MODEL_ID,
176                 .vendor_id      = OUI_RME,
177                 .specifier_id   = 0x000a35,
178                 .version        = 0x000002,
179                 .model_id       = 0x101800,
180                 .driver_data    = (kernel_ulong_t)&spec_ff400,
181         },
182         {}
183 };
184 MODULE_DEVICE_TABLE(ieee1394, snd_ff_id_table);
185
186 static struct fw_driver ff_driver = {
187         .driver = {
188                 .owner  = THIS_MODULE,
189                 .name   = "snd-fireface",
190                 .bus    = &fw_bus_type,
191         },
192         .probe    = snd_ff_probe,
193         .update   = snd_ff_update,
194         .remove   = snd_ff_remove,
195         .id_table = snd_ff_id_table,
196 };
197
198 static int __init snd_ff_init(void)
199 {
200         return driver_register(&ff_driver.driver);
201 }
202
203 static void __exit snd_ff_exit(void)
204 {
205         driver_unregister(&ff_driver.driver);
206 }
207
208 module_init(snd_ff_init);
209 module_exit(snd_ff_exit);