2 * Stanton Control System 1 MIDI driver
4 * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
5 * Licensed under the terms of the GNU General Public License, version 2.
8 #include <linux/device.h>
9 #include <linux/firewire.h>
10 #include <linux/firewire-constants.h>
11 #include <linux/interrupt.h>
12 #include <linux/module.h>
13 #include <linux/mod_devicetable.h>
14 #include <linux/slab.h>
15 #include <linux/string.h>
16 #include <linux/wait.h>
17 #include <sound/core.h>
18 #include <sound/initval.h>
19 #include <sound/rawmidi.h>
22 #define OUI_STANTON 0x001260
23 #define MODEL_SCS_1M 0x001000
24 #define MODEL_SCS_1D 0x002000
26 #define HSS1394_ADDRESS 0xc007dedadadaULL
27 #define HSS1394_MAX_PACKET_SIZE 64
29 #define HSS1394_TAG_USER_DATA 0x00
30 #define HSS1394_TAG_CHANGE_ADDRESS 0xf1
33 struct snd_card
*card
;
35 struct fw_address_handler hss_handler
;
36 struct fw_transaction transaction
;
37 bool transaction_running
;
42 bool output_escape_high_nibble
;
43 u8 input_escape_count
;
44 struct snd_rawmidi_substream
*output
;
45 struct snd_rawmidi_substream
*input
;
46 struct tasklet_struct tasklet
;
47 wait_queue_head_t idle_wait
;
51 static const u8 sysex_escape_prefix
[] = {
52 0xf0, /* SysEx begin */
53 0x00, 0x01, 0x60, /* Stanton DJ */
54 0x48, 0x53, 0x53, /* "HSS" */
57 static int scs_output_open(struct snd_rawmidi_substream
*stream
)
59 struct scs
*scs
= stream
->rmidi
->private_data
;
61 scs
->output_status
= 0;
62 scs
->output_bytes
= 1;
63 scs
->output_escaped
= false;
68 static int scs_output_close(struct snd_rawmidi_substream
*stream
)
73 static void scs_output_trigger(struct snd_rawmidi_substream
*stream
, int up
)
75 struct scs
*scs
= stream
->rmidi
->private_data
;
77 ACCESS_ONCE(scs
->output
) = up
? stream
: NULL
;
79 scs
->output_idle
= false;
80 tasklet_schedule(&scs
->tasklet
);
84 static void scs_write_callback(struct fw_card
*card
, int rcode
,
85 void *data
, size_t length
, void *callback_data
)
87 struct scs
*scs
= callback_data
;
89 if (rcode
== RCODE_GENERATION
) {
90 /* TODO: retry this packet */
93 scs
->transaction_running
= false;
94 tasklet_schedule(&scs
->tasklet
);
97 static bool is_valid_running_status(u8 status
)
99 return status
>= 0x80 && status
<= 0xef;
102 static bool is_one_byte_cmd(u8 status
)
104 return status
== 0xf6 ||
108 static bool is_two_bytes_cmd(u8 status
)
110 return (status
>= 0xc0 && status
<= 0xdf) ||
115 static bool is_three_bytes_cmd(u8 status
)
117 return (status
>= 0x80 && status
<= 0xbf) ||
118 (status
>= 0xe0 && status
<= 0xef) ||
122 static bool is_invalid_cmd(u8 status
)
124 return status
== 0xf4 ||
130 static void scs_output_tasklet(unsigned long data
)
132 struct scs
*scs
= (void *)data
;
133 struct snd_rawmidi_substream
*stream
;
136 struct fw_device
*dev
;
139 if (scs
->transaction_running
)
142 stream
= ACCESS_ONCE(scs
->output
);
144 scs
->output_idle
= true;
145 wake_up(&scs
->idle_wait
);
149 i
= scs
->output_bytes
;
151 if (snd_rawmidi_transmit(stream
, &byte
, 1) != 1) {
152 scs
->output_bytes
= i
;
153 scs
->output_idle
= true;
154 wake_up(&scs
->idle_wait
);
158 * Convert from real MIDI to what I think the device expects (no
159 * running status, one command per packet, unescaped SysExs).
161 if (scs
->output_escaped
&& byte
< 0x80) {
162 if (scs
->output_escape_high_nibble
) {
163 if (i
< HSS1394_MAX_PACKET_SIZE
) {
164 scs
->buffer
[i
] = byte
<< 4;
165 scs
->output_escape_high_nibble
= false;
168 scs
->buffer
[i
++] |= byte
& 0x0f;
169 scs
->output_escape_high_nibble
= true;
171 } else if (byte
< 0x80) {
173 if (!is_valid_running_status(scs
->output_status
))
175 scs
->buffer
[0] = HSS1394_TAG_USER_DATA
;
176 scs
->buffer
[i
++] = scs
->output_status
;
178 scs
->buffer
[i
++] = byte
;
179 if ((i
== 3 && is_two_bytes_cmd(scs
->output_status
)) ||
180 (i
== 4 && is_three_bytes_cmd(scs
->output_status
)))
182 if (i
== 1 + ARRAY_SIZE(sysex_escape_prefix
) &&
183 !memcmp(scs
->buffer
+ 1, sysex_escape_prefix
,
184 ARRAY_SIZE(sysex_escape_prefix
))) {
185 scs
->output_escaped
= true;
186 scs
->output_escape_high_nibble
= true;
189 if (i
>= HSS1394_MAX_PACKET_SIZE
)
191 } else if (byte
== 0xf7) {
192 if (scs
->output_escaped
) {
193 if (i
>= 1 && scs
->output_escape_high_nibble
&&
194 scs
->buffer
[0] != HSS1394_TAG_CHANGE_ADDRESS
)
197 if (i
> 1 && scs
->output_status
== 0xf0) {
198 scs
->buffer
[i
++] = 0xf7;
203 scs
->output_escaped
= false;
204 } else if (!is_invalid_cmd(byte
) &&
207 scs
->buffer
[0] = HSS1394_TAG_USER_DATA
;
208 scs
->buffer
[i
++] = byte
;
209 scs
->output_status
= byte
;
210 scs
->output_escaped
= false;
211 if (is_one_byte_cmd(byte
))
215 scs
->output_bytes
= 1;
216 scs
->output_escaped
= false;
218 scs
->transaction_running
= true;
219 dev
= fw_parent_device(scs
->unit
);
220 generation
= dev
->generation
;
221 smp_rmb(); /* node_id vs. generation */
222 fw_send_request(dev
->card
, &scs
->transaction
, TCODE_WRITE_BLOCK_REQUEST
,
223 dev
->node_id
, generation
, dev
->max_speed
,
224 HSS1394_ADDRESS
, scs
->buffer
, i
,
225 scs_write_callback
, scs
);
228 static void scs_output_drain(struct snd_rawmidi_substream
*stream
)
230 struct scs
*scs
= stream
->rmidi
->private_data
;
232 wait_event(scs
->idle_wait
, scs
->output_idle
);
235 static struct snd_rawmidi_ops output_ops
= {
236 .open
= scs_output_open
,
237 .close
= scs_output_close
,
238 .trigger
= scs_output_trigger
,
239 .drain
= scs_output_drain
,
242 static int scs_input_open(struct snd_rawmidi_substream
*stream
)
244 struct scs
*scs
= stream
->rmidi
->private_data
;
246 scs
->input_escape_count
= 0;
251 static int scs_input_close(struct snd_rawmidi_substream
*stream
)
256 static void scs_input_trigger(struct snd_rawmidi_substream
*stream
, int up
)
258 struct scs
*scs
= stream
->rmidi
->private_data
;
260 ACCESS_ONCE(scs
->input
) = up
? stream
: NULL
;
263 static void scs_input_escaped_byte(struct snd_rawmidi_substream
*stream
,
268 nibbles
[0] = byte
>> 4;
269 nibbles
[1] = byte
& 0x0f;
270 snd_rawmidi_receive(stream
, nibbles
, 2);
273 static void scs_input_midi_byte(struct scs
*scs
,
274 struct snd_rawmidi_substream
*stream
,
277 if (scs
->input_escape_count
> 0) {
278 scs_input_escaped_byte(stream
, byte
);
279 scs
->input_escape_count
--;
280 if (scs
->input_escape_count
== 0)
281 snd_rawmidi_receive(stream
, (const u8
[]) { 0xf7 }, 1);
282 } else if (byte
== 0xf9) {
283 snd_rawmidi_receive(stream
, sysex_escape_prefix
,
284 ARRAY_SIZE(sysex_escape_prefix
));
285 scs_input_escaped_byte(stream
, 0x00);
286 scs_input_escaped_byte(stream
, 0xf9);
287 scs
->input_escape_count
= 3;
289 snd_rawmidi_receive(stream
, &byte
, 1);
293 static void scs_input_packet(struct scs
*scs
,
294 struct snd_rawmidi_substream
*stream
,
295 const u8
*data
, unsigned int bytes
)
299 if (data
[0] == HSS1394_TAG_USER_DATA
) {
300 for (i
= 1; i
< bytes
; ++i
)
301 scs_input_midi_byte(scs
, stream
, data
[i
]);
303 snd_rawmidi_receive(stream
, sysex_escape_prefix
,
304 ARRAY_SIZE(sysex_escape_prefix
));
305 for (i
= 0; i
< bytes
; ++i
)
306 scs_input_escaped_byte(stream
, data
[i
]);
307 snd_rawmidi_receive(stream
, (const u8
[]) { 0xf7 }, 1);
311 static struct snd_rawmidi_ops input_ops
= {
312 .open
= scs_input_open
,
313 .close
= scs_input_close
,
314 .trigger
= scs_input_trigger
,
317 static int scs_create_midi(struct scs
*scs
)
319 struct snd_rawmidi
*rmidi
;
322 err
= snd_rawmidi_new(scs
->card
, "SCS.1x", 0, 1, 1, &rmidi
);
325 snprintf(rmidi
->name
, sizeof(rmidi
->name
),
326 "%s MIDI", scs
->card
->shortname
);
327 rmidi
->info_flags
= SNDRV_RAWMIDI_INFO_OUTPUT
|
328 SNDRV_RAWMIDI_INFO_INPUT
|
329 SNDRV_RAWMIDI_INFO_DUPLEX
;
330 rmidi
->private_data
= scs
;
331 snd_rawmidi_set_ops(rmidi
, SNDRV_RAWMIDI_STREAM_OUTPUT
, &output_ops
);
332 snd_rawmidi_set_ops(rmidi
, SNDRV_RAWMIDI_STREAM_INPUT
, &input_ops
);
337 static void handle_hss(struct fw_card
*card
, struct fw_request
*request
,
338 int tcode
, int destination
, int source
, int generation
,
339 unsigned long long offset
, void *data
, size_t length
,
342 struct scs
*scs
= callback_data
;
343 struct snd_rawmidi_substream
*stream
;
345 if (offset
!= scs
->hss_handler
.offset
) {
346 fw_send_response(card
, request
, RCODE_ADDRESS_ERROR
);
349 if (tcode
!= TCODE_WRITE_QUADLET_REQUEST
&&
350 tcode
!= TCODE_WRITE_BLOCK_REQUEST
) {
351 fw_send_response(card
, request
, RCODE_TYPE_ERROR
);
356 stream
= ACCESS_ONCE(scs
->input
);
358 scs_input_packet(scs
, stream
, data
, length
);
361 fw_send_response(card
, request
, RCODE_COMPLETE
);
364 static int scs_init_hss_address(struct scs
*scs
)
369 data
= cpu_to_be64(((u64
)HSS1394_TAG_CHANGE_ADDRESS
<< 56) |
370 scs
->hss_handler
.offset
);
371 err
= snd_fw_transaction(scs
->unit
, TCODE_WRITE_BLOCK_REQUEST
,
372 HSS1394_ADDRESS
, &data
, 8, 0);
374 dev_err(&scs
->unit
->device
, "HSS1394 communication failed\n");
379 static void scs_card_free(struct snd_card
*card
)
381 struct scs
*scs
= card
->private_data
;
383 fw_core_remove_address_handler(&scs
->hss_handler
);
387 static int scs_probe(struct fw_unit
*unit
, const struct ieee1394_device_id
*id
)
389 struct fw_device
*fw_dev
= fw_parent_device(unit
);
390 struct snd_card
*card
;
394 err
= snd_card_new(&unit
->device
, -16, NULL
, THIS_MODULE
,
395 sizeof(*scs
), &card
);
399 scs
= card
->private_data
;
402 tasklet_init(&scs
->tasklet
, scs_output_tasklet
, (unsigned long)scs
);
403 init_waitqueue_head(&scs
->idle_wait
);
404 scs
->output_idle
= true;
406 scs
->buffer
= kmalloc(HSS1394_MAX_PACKET_SIZE
, GFP_KERNEL
);
412 scs
->hss_handler
.length
= HSS1394_MAX_PACKET_SIZE
;
413 scs
->hss_handler
.address_callback
= handle_hss
;
414 scs
->hss_handler
.callback_data
= scs
;
415 err
= fw_core_add_address_handler(&scs
->hss_handler
,
416 &fw_high_memory_region
);
420 card
->private_free
= scs_card_free
;
422 strcpy(card
->driver
, "SCS.1x");
423 strcpy(card
->shortname
, "SCS.1x");
424 fw_csr_string(unit
->directory
, CSR_MODEL
,
425 card
->shortname
, sizeof(card
->shortname
));
426 snprintf(card
->longname
, sizeof(card
->longname
),
427 "Stanton DJ %s (GUID %08x%08x) at %s, S%d",
428 card
->shortname
, fw_dev
->config_rom
[3], fw_dev
->config_rom
[4],
429 dev_name(&unit
->device
), 100 << fw_dev
->max_speed
);
430 strcpy(card
->mixername
, card
->shortname
);
432 err
= scs_init_hss_address(scs
);
436 err
= scs_create_midi(scs
);
440 err
= snd_card_register(card
);
444 dev_set_drvdata(&unit
->device
, scs
);
455 static void scs_update(struct fw_unit
*unit
)
457 struct scs
*scs
= dev_get_drvdata(&unit
->device
);
461 data
= cpu_to_be64(((u64
)HSS1394_TAG_CHANGE_ADDRESS
<< 56) |
462 scs
->hss_handler
.offset
);
463 generation
= fw_parent_device(unit
)->generation
;
464 smp_rmb(); /* node_id vs. generation */
465 snd_fw_transaction(scs
->unit
, TCODE_WRITE_BLOCK_REQUEST
,
466 HSS1394_ADDRESS
, &data
, 8,
467 FW_FIXED_GENERATION
| generation
);
470 static void scs_remove(struct fw_unit
*unit
)
472 struct scs
*scs
= dev_get_drvdata(&unit
->device
);
474 snd_card_disconnect(scs
->card
);
476 ACCESS_ONCE(scs
->output
) = NULL
;
477 ACCESS_ONCE(scs
->input
) = NULL
;
479 wait_event(scs
->idle_wait
, scs
->output_idle
);
481 tasklet_kill(&scs
->tasklet
);
483 snd_card_free_when_closed(scs
->card
);
486 static const struct ieee1394_device_id scs_id_table
[] = {
488 .match_flags
= IEEE1394_MATCH_VENDOR_ID
|
489 IEEE1394_MATCH_MODEL_ID
,
490 .vendor_id
= OUI_STANTON
,
491 .model_id
= MODEL_SCS_1M
,
494 .match_flags
= IEEE1394_MATCH_VENDOR_ID
|
495 IEEE1394_MATCH_MODEL_ID
,
496 .vendor_id
= OUI_STANTON
,
497 .model_id
= MODEL_SCS_1D
,
501 MODULE_DEVICE_TABLE(ieee1394
, scs_id_table
);
503 MODULE_DESCRIPTION("SCS.1x MIDI driver");
504 MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
505 MODULE_LICENSE("GPL v2");
507 static struct fw_driver scs_driver
= {
509 .owner
= THIS_MODULE
,
510 .name
= KBUILD_MODNAME
,
514 .update
= scs_update
,
515 .remove
= scs_remove
,
516 .id_table
= scs_id_table
,
519 static int __init
alsa_scs1x_init(void)
521 return driver_register(&scs_driver
.driver
);
524 static void __exit
alsa_scs1x_exit(void)
526 driver_unregister(&scs_driver
.driver
);
529 module_init(alsa_scs1x_init
);
530 module_exit(alsa_scs1x_exit
);