scs1x.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530
  1. /*
  2. * Stanton Control System 1 MIDI driver
  3. *
  4. * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
  5. * Licensed under the terms of the GNU General Public License, version 2.
  6. */
  7. #include <linux/device.h>
  8. #include <linux/firewire.h>
  9. #include <linux/firewire-constants.h>
  10. #include <linux/interrupt.h>
  11. #include <linux/module.h>
  12. #include <linux/mod_devicetable.h>
  13. #include <linux/slab.h>
  14. #include <linux/string.h>
  15. #include <linux/wait.h>
  16. #include <sound/core.h>
  17. #include <sound/initval.h>
  18. #include <sound/rawmidi.h>
  19. #include "lib.h"
  20. #define OUI_STANTON 0x001260
  21. #define MODEL_SCS_1M 0x001000
  22. #define MODEL_SCS_1D 0x002000
  23. #define HSS1394_ADDRESS 0xc007dedadadaULL
  24. #define HSS1394_MAX_PACKET_SIZE 64
  25. #define HSS1394_TAG_USER_DATA 0x00
  26. #define HSS1394_TAG_CHANGE_ADDRESS 0xf1
  27. struct scs {
  28. struct snd_card *card;
  29. struct fw_unit *unit;
  30. struct fw_address_handler hss_handler;
  31. struct fw_transaction transaction;
  32. bool transaction_running;
  33. bool output_idle;
  34. u8 output_status;
  35. u8 output_bytes;
  36. bool output_escaped;
  37. bool output_escape_high_nibble;
  38. u8 input_escape_count;
  39. struct snd_rawmidi_substream *output;
  40. struct snd_rawmidi_substream *input;
  41. struct tasklet_struct tasklet;
  42. wait_queue_head_t idle_wait;
  43. u8 *buffer;
  44. };
  45. static const u8 sysex_escape_prefix[] = {
  46. 0xf0, /* SysEx begin */
  47. 0x00, 0x01, 0x60, /* Stanton DJ */
  48. 0x48, 0x53, 0x53, /* "HSS" */
  49. };
  50. static int scs_output_open(struct snd_rawmidi_substream *stream)
  51. {
  52. struct scs *scs = stream->rmidi->private_data;
  53. scs->output_status = 0;
  54. scs->output_bytes = 1;
  55. scs->output_escaped = false;
  56. return 0;
  57. }
  58. static int scs_output_close(struct snd_rawmidi_substream *stream)
  59. {
  60. return 0;
  61. }
  62. static void scs_output_trigger(struct snd_rawmidi_substream *stream, int up)
  63. {
  64. struct scs *scs = stream->rmidi->private_data;
  65. ACCESS_ONCE(scs->output) = up ? stream : NULL;
  66. if (up) {
  67. scs->output_idle = false;
  68. tasklet_schedule(&scs->tasklet);
  69. }
  70. }
  71. static void scs_write_callback(struct fw_card *card, int rcode,
  72. void *data, size_t length, void *callback_data)
  73. {
  74. struct scs *scs = callback_data;
  75. if (rcode == RCODE_GENERATION) {
  76. /* TODO: retry this packet */
  77. }
  78. scs->transaction_running = false;
  79. tasklet_schedule(&scs->tasklet);
  80. }
  81. static bool is_valid_running_status(u8 status)
  82. {
  83. return status >= 0x80 && status <= 0xef;
  84. }
  85. static bool is_one_byte_cmd(u8 status)
  86. {
  87. return status == 0xf6 ||
  88. status >= 0xf8;
  89. }
  90. static bool is_two_bytes_cmd(u8 status)
  91. {
  92. return (status >= 0xc0 && status <= 0xdf) ||
  93. status == 0xf1 ||
  94. status == 0xf3;
  95. }
  96. static bool is_three_bytes_cmd(u8 status)
  97. {
  98. return (status >= 0x80 && status <= 0xbf) ||
  99. (status >= 0xe0 && status <= 0xef) ||
  100. status == 0xf2;
  101. }
  102. static bool is_invalid_cmd(u8 status)
  103. {
  104. return status == 0xf4 ||
  105. status == 0xf5 ||
  106. status == 0xf9 ||
  107. status == 0xfd;
  108. }
  109. static void scs_output_tasklet(unsigned long data)
  110. {
  111. struct scs *scs = (void *)data;
  112. struct snd_rawmidi_substream *stream;
  113. unsigned int i;
  114. u8 byte;
  115. struct fw_device *dev;
  116. int generation;
  117. if (scs->transaction_running)
  118. return;
  119. stream = ACCESS_ONCE(scs->output);
  120. if (!stream) {
  121. scs->output_idle = true;
  122. wake_up(&scs->idle_wait);
  123. return;
  124. }
  125. i = scs->output_bytes;
  126. for (;;) {
  127. if (snd_rawmidi_transmit(stream, &byte, 1) != 1) {
  128. scs->output_bytes = i;
  129. scs->output_idle = true;
  130. wake_up(&scs->idle_wait);
  131. return;
  132. }
  133. /*
  134. * Convert from real MIDI to what I think the device expects (no
  135. * running status, one command per packet, unescaped SysExs).
  136. */
  137. if (scs->output_escaped && byte < 0x80) {
  138. if (scs->output_escape_high_nibble) {
  139. if (i < HSS1394_MAX_PACKET_SIZE) {
  140. scs->buffer[i] = byte << 4;
  141. scs->output_escape_high_nibble = false;
  142. }
  143. } else {
  144. scs->buffer[i++] |= byte & 0x0f;
  145. scs->output_escape_high_nibble = true;
  146. }
  147. } else if (byte < 0x80) {
  148. if (i == 1) {
  149. if (!is_valid_running_status(scs->output_status))
  150. continue;
  151. scs->buffer[0] = HSS1394_TAG_USER_DATA;
  152. scs->buffer[i++] = scs->output_status;
  153. }
  154. scs->buffer[i++] = byte;
  155. if ((i == 3 && is_two_bytes_cmd(scs->output_status)) ||
  156. (i == 4 && is_three_bytes_cmd(scs->output_status)))
  157. break;
  158. if (i == 1 + ARRAY_SIZE(sysex_escape_prefix) &&
  159. !memcmp(scs->buffer + 1, sysex_escape_prefix,
  160. ARRAY_SIZE(sysex_escape_prefix))) {
  161. scs->output_escaped = true;
  162. scs->output_escape_high_nibble = true;
  163. i = 0;
  164. }
  165. if (i >= HSS1394_MAX_PACKET_SIZE)
  166. i = 1;
  167. } else if (byte == 0xf7) {
  168. if (scs->output_escaped) {
  169. if (i >= 1 && scs->output_escape_high_nibble &&
  170. scs->buffer[0] != HSS1394_TAG_CHANGE_ADDRESS)
  171. break;
  172. } else {
  173. if (i > 1 && scs->output_status == 0xf0) {
  174. scs->buffer[i++] = 0xf7;
  175. break;
  176. }
  177. }
  178. i = 1;
  179. scs->output_escaped = false;
  180. } else if (!is_invalid_cmd(byte) &&
  181. byte < 0xf8) {
  182. i = 1;
  183. scs->buffer[0] = HSS1394_TAG_USER_DATA;
  184. scs->buffer[i++] = byte;
  185. scs->output_status = byte;
  186. scs->output_escaped = false;
  187. if (is_one_byte_cmd(byte))
  188. break;
  189. }
  190. }
  191. scs->output_bytes = 1;
  192. scs->output_escaped = false;
  193. scs->transaction_running = true;
  194. dev = fw_parent_device(scs->unit);
  195. generation = dev->generation;
  196. smp_rmb(); /* node_id vs. generation */
  197. fw_send_request(dev->card, &scs->transaction, TCODE_WRITE_BLOCK_REQUEST,
  198. dev->node_id, generation, dev->max_speed,
  199. HSS1394_ADDRESS, scs->buffer, i,
  200. scs_write_callback, scs);
  201. }
  202. static void scs_output_drain(struct snd_rawmidi_substream *stream)
  203. {
  204. struct scs *scs = stream->rmidi->private_data;
  205. wait_event(scs->idle_wait, scs->output_idle);
  206. }
  207. static struct snd_rawmidi_ops output_ops = {
  208. .open = scs_output_open,
  209. .close = scs_output_close,
  210. .trigger = scs_output_trigger,
  211. .drain = scs_output_drain,
  212. };
  213. static int scs_input_open(struct snd_rawmidi_substream *stream)
  214. {
  215. struct scs *scs = stream->rmidi->private_data;
  216. scs->input_escape_count = 0;
  217. return 0;
  218. }
  219. static int scs_input_close(struct snd_rawmidi_substream *stream)
  220. {
  221. return 0;
  222. }
  223. static void scs_input_trigger(struct snd_rawmidi_substream *stream, int up)
  224. {
  225. struct scs *scs = stream->rmidi->private_data;
  226. ACCESS_ONCE(scs->input) = up ? stream : NULL;
  227. }
  228. static void scs_input_escaped_byte(struct snd_rawmidi_substream *stream,
  229. u8 byte)
  230. {
  231. u8 nibbles[2];
  232. nibbles[0] = byte >> 4;
  233. nibbles[1] = byte & 0x0f;
  234. snd_rawmidi_receive(stream, nibbles, 2);
  235. }
  236. static void scs_input_midi_byte(struct scs *scs,
  237. struct snd_rawmidi_substream *stream,
  238. u8 byte)
  239. {
  240. if (scs->input_escape_count > 0) {
  241. scs_input_escaped_byte(stream, byte);
  242. scs->input_escape_count--;
  243. if (scs->input_escape_count == 0)
  244. snd_rawmidi_receive(stream, (const u8[]) { 0xf7 }, 1);
  245. } else if (byte == 0xf9) {
  246. snd_rawmidi_receive(stream, sysex_escape_prefix,
  247. ARRAY_SIZE(sysex_escape_prefix));
  248. scs_input_escaped_byte(stream, 0x00);
  249. scs_input_escaped_byte(stream, 0xf9);
  250. scs->input_escape_count = 3;
  251. } else {
  252. snd_rawmidi_receive(stream, &byte, 1);
  253. }
  254. }
  255. static void scs_input_packet(struct scs *scs,
  256. struct snd_rawmidi_substream *stream,
  257. const u8 *data, unsigned int bytes)
  258. {
  259. unsigned int i;
  260. if (data[0] == HSS1394_TAG_USER_DATA) {
  261. for (i = 1; i < bytes; ++i)
  262. scs_input_midi_byte(scs, stream, data[i]);
  263. } else {
  264. snd_rawmidi_receive(stream, sysex_escape_prefix,
  265. ARRAY_SIZE(sysex_escape_prefix));
  266. for (i = 0; i < bytes; ++i)
  267. scs_input_escaped_byte(stream, data[i]);
  268. snd_rawmidi_receive(stream, (const u8[]) { 0xf7 }, 1);
  269. }
  270. }
  271. static struct snd_rawmidi_ops input_ops = {
  272. .open = scs_input_open,
  273. .close = scs_input_close,
  274. .trigger = scs_input_trigger,
  275. };
  276. static int scs_create_midi(struct scs *scs)
  277. {
  278. struct snd_rawmidi *rmidi;
  279. int err;
  280. err = snd_rawmidi_new(scs->card, "SCS.1x", 0, 1, 1, &rmidi);
  281. if (err < 0)
  282. return err;
  283. snprintf(rmidi->name, sizeof(rmidi->name),
  284. "%s MIDI", scs->card->shortname);
  285. rmidi->info_flags = SNDRV_RAWMIDI_INFO_OUTPUT |
  286. SNDRV_RAWMIDI_INFO_INPUT |
  287. SNDRV_RAWMIDI_INFO_DUPLEX;
  288. rmidi->private_data = scs;
  289. snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &output_ops);
  290. snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, &input_ops);
  291. return 0;
  292. }
  293. static void handle_hss(struct fw_card *card, struct fw_request *request,
  294. int tcode, int destination, int source, int generation,
  295. unsigned long long offset, void *data, size_t length,
  296. void *callback_data)
  297. {
  298. struct scs *scs = callback_data;
  299. struct snd_rawmidi_substream *stream;
  300. if (offset != scs->hss_handler.offset) {
  301. fw_send_response(card, request, RCODE_ADDRESS_ERROR);
  302. return;
  303. }
  304. if (tcode != TCODE_WRITE_QUADLET_REQUEST &&
  305. tcode != TCODE_WRITE_BLOCK_REQUEST) {
  306. fw_send_response(card, request, RCODE_TYPE_ERROR);
  307. return;
  308. }
  309. if (length >= 1) {
  310. stream = ACCESS_ONCE(scs->input);
  311. if (stream)
  312. scs_input_packet(scs, stream, data, length);
  313. }
  314. fw_send_response(card, request, RCODE_COMPLETE);
  315. }
  316. static int scs_init_hss_address(struct scs *scs)
  317. {
  318. __be64 data;
  319. int err;
  320. data = cpu_to_be64(((u64)HSS1394_TAG_CHANGE_ADDRESS << 56) |
  321. scs->hss_handler.offset);
  322. err = snd_fw_transaction(scs->unit, TCODE_WRITE_BLOCK_REQUEST,
  323. HSS1394_ADDRESS, &data, 8, 0);
  324. if (err < 0)
  325. dev_err(&scs->unit->device, "HSS1394 communication failed\n");
  326. return err;
  327. }
  328. static void scs_card_free(struct snd_card *card)
  329. {
  330. struct scs *scs = card->private_data;
  331. fw_core_remove_address_handler(&scs->hss_handler);
  332. kfree(scs->buffer);
  333. }
  334. static int scs_probe(struct fw_unit *unit, const struct ieee1394_device_id *id)
  335. {
  336. struct fw_device *fw_dev = fw_parent_device(unit);
  337. struct snd_card *card;
  338. struct scs *scs;
  339. int err;
  340. err = snd_card_new(&unit->device, -16, NULL, THIS_MODULE,
  341. sizeof(*scs), &card);
  342. if (err < 0)
  343. return err;
  344. scs = card->private_data;
  345. scs->card = card;
  346. scs->unit = unit;
  347. tasklet_init(&scs->tasklet, scs_output_tasklet, (unsigned long)scs);
  348. init_waitqueue_head(&scs->idle_wait);
  349. scs->output_idle = true;
  350. scs->buffer = kmalloc(HSS1394_MAX_PACKET_SIZE, GFP_KERNEL);
  351. if (!scs->buffer) {
  352. err = -ENOMEM;
  353. goto err_card;
  354. }
  355. scs->hss_handler.length = HSS1394_MAX_PACKET_SIZE;
  356. scs->hss_handler.address_callback = handle_hss;
  357. scs->hss_handler.callback_data = scs;
  358. err = fw_core_add_address_handler(&scs->hss_handler,
  359. &fw_high_memory_region);
  360. if (err < 0)
  361. goto err_buffer;
  362. card->private_free = scs_card_free;
  363. strcpy(card->driver, "SCS.1x");
  364. strcpy(card->shortname, "SCS.1x");
  365. fw_csr_string(unit->directory, CSR_MODEL,
  366. card->shortname, sizeof(card->shortname));
  367. snprintf(card->longname, sizeof(card->longname),
  368. "Stanton DJ %s (GUID %08x%08x) at %s, S%d",
  369. card->shortname, fw_dev->config_rom[3], fw_dev->config_rom[4],
  370. dev_name(&unit->device), 100 << fw_dev->max_speed);
  371. strcpy(card->mixername, card->shortname);
  372. err = scs_init_hss_address(scs);
  373. if (err < 0)
  374. goto err_card;
  375. err = scs_create_midi(scs);
  376. if (err < 0)
  377. goto err_card;
  378. err = snd_card_register(card);
  379. if (err < 0)
  380. goto err_card;
  381. dev_set_drvdata(&unit->device, scs);
  382. return 0;
  383. err_buffer:
  384. kfree(scs->buffer);
  385. err_card:
  386. snd_card_free(card);
  387. return err;
  388. }
  389. static void scs_update(struct fw_unit *unit)
  390. {
  391. struct scs *scs = dev_get_drvdata(&unit->device);
  392. int generation;
  393. __be64 data;
  394. data = cpu_to_be64(((u64)HSS1394_TAG_CHANGE_ADDRESS << 56) |
  395. scs->hss_handler.offset);
  396. generation = fw_parent_device(unit)->generation;
  397. smp_rmb(); /* node_id vs. generation */
  398. snd_fw_transaction(scs->unit, TCODE_WRITE_BLOCK_REQUEST,
  399. HSS1394_ADDRESS, &data, 8,
  400. FW_FIXED_GENERATION | generation);
  401. }
  402. static void scs_remove(struct fw_unit *unit)
  403. {
  404. struct scs *scs = dev_get_drvdata(&unit->device);
  405. snd_card_disconnect(scs->card);
  406. ACCESS_ONCE(scs->output) = NULL;
  407. ACCESS_ONCE(scs->input) = NULL;
  408. wait_event(scs->idle_wait, scs->output_idle);
  409. tasklet_kill(&scs->tasklet);
  410. snd_card_free_when_closed(scs->card);
  411. }
  412. static const struct ieee1394_device_id scs_id_table[] = {
  413. {
  414. .match_flags = IEEE1394_MATCH_VENDOR_ID |
  415. IEEE1394_MATCH_MODEL_ID,
  416. .vendor_id = OUI_STANTON,
  417. .model_id = MODEL_SCS_1M,
  418. },
  419. {
  420. .match_flags = IEEE1394_MATCH_VENDOR_ID |
  421. IEEE1394_MATCH_MODEL_ID,
  422. .vendor_id = OUI_STANTON,
  423. .model_id = MODEL_SCS_1D,
  424. },
  425. {}
  426. };
  427. MODULE_DEVICE_TABLE(ieee1394, scs_id_table);
  428. MODULE_DESCRIPTION("SCS.1x MIDI driver");
  429. MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
  430. MODULE_LICENSE("GPL v2");
  431. static struct fw_driver scs_driver = {
  432. .driver = {
  433. .owner = THIS_MODULE,
  434. .name = KBUILD_MODNAME,
  435. .bus = &fw_bus_type,
  436. },
  437. .probe = scs_probe,
  438. .update = scs_update,
  439. .remove = scs_remove,
  440. .id_table = scs_id_table,
  441. };
  442. static int __init alsa_scs1x_init(void)
  443. {
  444. return driver_register(&scs_driver.driver);
  445. }
  446. static void __exit alsa_scs1x_exit(void)
  447. {
  448. driver_unregister(&scs_driver.driver);
  449. }
  450. module_init(alsa_scs1x_init);
  451. module_exit(alsa_scs1x_exit);