clk: imx: correct i.MX7D AV PLL num/denom offset
[sfrench/cifs-2.6.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_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         .midi_addr_range = 12,
157         .midi_rx_addrs = {0x000080180000ull, 0},
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         .midi_high_addr = 0x0000801003f4ull,
168         .midi_addr_range = SND_FF_MAXIMIM_MIDI_QUADS * 4,
169         .midi_rx_addrs = {0x000080180000ull, 0x000080190000ull},
170 };
171
172 static const struct snd_ff_spec spec_ucx = {
173         .name = "FirefaceUCX",
174         .pcm_capture_channels = {18, 14, 12},
175         .pcm_playback_channels = {18, 14, 12},
176         .midi_in_ports = 2,
177         .midi_out_ports = 2,
178         .protocol = &snd_ff_protocol_latter,
179         .midi_high_addr = 0xffff00000034ull,
180         .midi_addr_range = 0x80,
181         .midi_rx_addrs = {0xffff00000030ull, 0xffff00000030ull},
182 };
183
184 static const struct ieee1394_device_id snd_ff_id_table[] = {
185         /* Fireface 800 */
186         {
187                 .match_flags    = IEEE1394_MATCH_VENDOR_ID |
188                                   IEEE1394_MATCH_SPECIFIER_ID |
189                                   IEEE1394_MATCH_VERSION |
190                                   IEEE1394_MATCH_MODEL_ID,
191                 .vendor_id      = OUI_RME,
192                 .specifier_id   = OUI_RME,
193                 .version        = 0x000001,
194                 .model_id       = 0x101800,
195                 .driver_data    = (kernel_ulong_t)&spec_ff800,
196         },
197         /* Fireface 400 */
198         {
199                 .match_flags    = IEEE1394_MATCH_VENDOR_ID |
200                                   IEEE1394_MATCH_SPECIFIER_ID |
201                                   IEEE1394_MATCH_VERSION |
202                                   IEEE1394_MATCH_MODEL_ID,
203                 .vendor_id      = OUI_RME,
204                 .specifier_id   = OUI_RME,
205                 .version        = 0x000002,
206                 .model_id       = 0x101800,
207                 .driver_data    = (kernel_ulong_t)&spec_ff400,
208         },
209         // Fireface UCX.
210         {
211                 .match_flags    = IEEE1394_MATCH_VENDOR_ID |
212                                   IEEE1394_MATCH_SPECIFIER_ID |
213                                   IEEE1394_MATCH_VERSION |
214                                   IEEE1394_MATCH_MODEL_ID,
215                 .vendor_id      = OUI_RME,
216                 .specifier_id   = OUI_RME,
217                 .version        = 0x000004,
218                 .model_id       = 0x101800,
219                 .driver_data    = (kernel_ulong_t)&spec_ucx,
220         },
221         {}
222 };
223 MODULE_DEVICE_TABLE(ieee1394, snd_ff_id_table);
224
225 static struct fw_driver ff_driver = {
226         .driver = {
227                 .owner  = THIS_MODULE,
228                 .name   = "snd-fireface",
229                 .bus    = &fw_bus_type,
230         },
231         .probe    = snd_ff_probe,
232         .update   = snd_ff_update,
233         .remove   = snd_ff_remove,
234         .id_table = snd_ff_id_table,
235 };
236
237 static int __init snd_ff_init(void)
238 {
239         return driver_register(&ff_driver.driver);
240 }
241
242 static void __exit snd_ff_exit(void)
243 {
244         driver_unregister(&ff_driver.driver);
245 }
246
247 module_init(snd_ff_init);
248 module_exit(snd_ff_exit);