comm.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * Linux driver for TerraTec DMX 6Fire USB
  4. *
  5. * Device communications
  6. *
  7. * Author: Torsten Schenk <[email protected]>
  8. * Created: Jan 01, 2011
  9. * Copyright: (C) Torsten Schenk
  10. */
  11. #include "comm.h"
  12. #include "chip.h"
  13. #include "midi.h"
  14. enum {
  15. COMM_EP = 1,
  16. COMM_FPGA_EP = 2
  17. };
  18. static void usb6fire_comm_init_urb(struct comm_runtime *rt, struct urb *urb,
  19. u8 *buffer, void *context, void(*handler)(struct urb *urb))
  20. {
  21. usb_init_urb(urb);
  22. urb->transfer_buffer = buffer;
  23. urb->pipe = usb_sndintpipe(rt->chip->dev, COMM_EP);
  24. urb->complete = handler;
  25. urb->context = context;
  26. urb->interval = 1;
  27. urb->dev = rt->chip->dev;
  28. }
  29. static void usb6fire_comm_receiver_handler(struct urb *urb)
  30. {
  31. struct comm_runtime *rt = urb->context;
  32. struct midi_runtime *midi_rt = rt->chip->midi;
  33. if (!urb->status) {
  34. if (rt->receiver_buffer[0] == 0x10) /* midi in event */
  35. if (midi_rt)
  36. midi_rt->in_received(midi_rt,
  37. rt->receiver_buffer + 2,
  38. rt->receiver_buffer[1]);
  39. }
  40. if (!rt->chip->shutdown) {
  41. urb->status = 0;
  42. urb->actual_length = 0;
  43. if (usb_submit_urb(urb, GFP_ATOMIC) < 0)
  44. dev_warn(&urb->dev->dev,
  45. "comm data receiver aborted.\n");
  46. }
  47. }
  48. static void usb6fire_comm_init_buffer(u8 *buffer, u8 id, u8 request,
  49. u8 reg, u8 vl, u8 vh)
  50. {
  51. buffer[0] = 0x01;
  52. buffer[2] = request;
  53. buffer[3] = id;
  54. switch (request) {
  55. case 0x02:
  56. buffer[1] = 0x05; /* length (starting at buffer[2]) */
  57. buffer[4] = reg;
  58. buffer[5] = vl;
  59. buffer[6] = vh;
  60. break;
  61. case 0x12:
  62. buffer[1] = 0x0b; /* length (starting at buffer[2]) */
  63. buffer[4] = 0x00;
  64. buffer[5] = 0x18;
  65. buffer[6] = 0x05;
  66. buffer[7] = 0x00;
  67. buffer[8] = 0x01;
  68. buffer[9] = 0x00;
  69. buffer[10] = 0x9e;
  70. buffer[11] = reg;
  71. buffer[12] = vl;
  72. break;
  73. case 0x20:
  74. case 0x21:
  75. case 0x22:
  76. buffer[1] = 0x04;
  77. buffer[4] = reg;
  78. buffer[5] = vl;
  79. break;
  80. }
  81. }
  82. static int usb6fire_comm_send_buffer(u8 *buffer, struct usb_device *dev)
  83. {
  84. int ret;
  85. int actual_len;
  86. ret = usb_interrupt_msg(dev, usb_sndintpipe(dev, COMM_EP),
  87. buffer, buffer[1] + 2, &actual_len, 1000);
  88. if (ret < 0)
  89. return ret;
  90. else if (actual_len != buffer[1] + 2)
  91. return -EIO;
  92. return 0;
  93. }
  94. static int usb6fire_comm_write8(struct comm_runtime *rt, u8 request,
  95. u8 reg, u8 value)
  96. {
  97. u8 *buffer;
  98. int ret;
  99. /* 13: maximum length of message */
  100. buffer = kmalloc(13, GFP_KERNEL);
  101. if (!buffer)
  102. return -ENOMEM;
  103. usb6fire_comm_init_buffer(buffer, 0x00, request, reg, value, 0x00);
  104. ret = usb6fire_comm_send_buffer(buffer, rt->chip->dev);
  105. kfree(buffer);
  106. return ret;
  107. }
  108. static int usb6fire_comm_write16(struct comm_runtime *rt, u8 request,
  109. u8 reg, u8 vl, u8 vh)
  110. {
  111. u8 *buffer;
  112. int ret;
  113. /* 13: maximum length of message */
  114. buffer = kmalloc(13, GFP_KERNEL);
  115. if (!buffer)
  116. return -ENOMEM;
  117. usb6fire_comm_init_buffer(buffer, 0x00, request, reg, vl, vh);
  118. ret = usb6fire_comm_send_buffer(buffer, rt->chip->dev);
  119. kfree(buffer);
  120. return ret;
  121. }
  122. int usb6fire_comm_init(struct sfire_chip *chip)
  123. {
  124. struct comm_runtime *rt = kzalloc(sizeof(struct comm_runtime),
  125. GFP_KERNEL);
  126. struct urb *urb;
  127. int ret;
  128. if (!rt)
  129. return -ENOMEM;
  130. rt->receiver_buffer = kzalloc(COMM_RECEIVER_BUFSIZE, GFP_KERNEL);
  131. if (!rt->receiver_buffer) {
  132. kfree(rt);
  133. return -ENOMEM;
  134. }
  135. urb = &rt->receiver;
  136. rt->serial = 1;
  137. rt->chip = chip;
  138. usb_init_urb(urb);
  139. rt->init_urb = usb6fire_comm_init_urb;
  140. rt->write8 = usb6fire_comm_write8;
  141. rt->write16 = usb6fire_comm_write16;
  142. /* submit an urb that receives communication data from device */
  143. urb->transfer_buffer = rt->receiver_buffer;
  144. urb->transfer_buffer_length = COMM_RECEIVER_BUFSIZE;
  145. urb->pipe = usb_rcvintpipe(chip->dev, COMM_EP);
  146. urb->dev = chip->dev;
  147. urb->complete = usb6fire_comm_receiver_handler;
  148. urb->context = rt;
  149. urb->interval = 1;
  150. ret = usb_submit_urb(urb, GFP_KERNEL);
  151. if (ret < 0) {
  152. kfree(rt->receiver_buffer);
  153. kfree(rt);
  154. dev_err(&chip->dev->dev, "cannot create comm data receiver.");
  155. return ret;
  156. }
  157. chip->comm = rt;
  158. return 0;
  159. }
  160. void usb6fire_comm_abort(struct sfire_chip *chip)
  161. {
  162. struct comm_runtime *rt = chip->comm;
  163. if (rt)
  164. usb_poison_urb(&rt->receiver);
  165. }
  166. void usb6fire_comm_destroy(struct sfire_chip *chip)
  167. {
  168. struct comm_runtime *rt = chip->comm;
  169. kfree(rt->receiver_buffer);
  170. kfree(rt);
  171. chip->comm = NULL;
  172. }