1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Linux driver for TerraTec DMX 6Fire USB
5 * Device communications
8 * Created: Jan 01, 2011
9 * Copyright: (C) Torsten Schenk
21 static void usb6fire_comm_init_urb(struct comm_runtime *rt, struct urb *urb,
22 u8 *buffer, void *context, void(*handler)(struct urb *urb))
25 urb->transfer_buffer = buffer;
26 urb->pipe = usb_sndintpipe(rt->chip->dev, COMM_EP);
27 urb->complete = handler;
28 urb->context = context;
30 urb->dev = rt->chip->dev;
33 static void usb6fire_comm_receiver_handler(struct urb *urb)
35 struct comm_runtime *rt = urb->context;
36 struct midi_runtime *midi_rt = rt->chip->midi;
39 if (rt->receiver_buffer[0] == 0x10) /* midi in event */
41 midi_rt->in_received(midi_rt,
42 rt->receiver_buffer + 2,
43 rt->receiver_buffer[1]);
46 if (!rt->chip->shutdown) {
48 urb->actual_length = 0;
49 if (usb_submit_urb(urb, GFP_ATOMIC) < 0)
50 dev_warn(&urb->dev->dev,
51 "comm data receiver aborted.\n");
55 static void usb6fire_comm_init_buffer(u8 *buffer, u8 id, u8 request,
63 buffer[1] = 0x05; /* length (starting at buffer[2]) */
70 buffer[1] = 0x0b; /* length (starting at buffer[2]) */
92 static int usb6fire_comm_send_buffer(u8 *buffer, struct usb_device *dev)
97 ret = usb_interrupt_msg(dev, usb_sndintpipe(dev, COMM_EP),
98 buffer, buffer[1] + 2, &actual_len, HZ);
101 else if (actual_len != buffer[1] + 2)
106 static int usb6fire_comm_write8(struct comm_runtime *rt, u8 request,
112 /* 13: maximum length of message */
113 buffer = kmalloc(13, GFP_KERNEL);
117 usb6fire_comm_init_buffer(buffer, 0x00, request, reg, value, 0x00);
118 ret = usb6fire_comm_send_buffer(buffer, rt->chip->dev);
124 static int usb6fire_comm_write16(struct comm_runtime *rt, u8 request,
125 u8 reg, u8 vl, u8 vh)
130 /* 13: maximum length of message */
131 buffer = kmalloc(13, GFP_KERNEL);
135 usb6fire_comm_init_buffer(buffer, 0x00, request, reg, vl, vh);
136 ret = usb6fire_comm_send_buffer(buffer, rt->chip->dev);
142 int usb6fire_comm_init(struct sfire_chip *chip)
144 struct comm_runtime *rt = kzalloc(sizeof(struct comm_runtime),
152 rt->receiver_buffer = kzalloc(COMM_RECEIVER_BUFSIZE, GFP_KERNEL);
153 if (!rt->receiver_buffer) {
162 rt->init_urb = usb6fire_comm_init_urb;
163 rt->write8 = usb6fire_comm_write8;
164 rt->write16 = usb6fire_comm_write16;
166 /* submit an urb that receives communication data from device */
167 urb->transfer_buffer = rt->receiver_buffer;
168 urb->transfer_buffer_length = COMM_RECEIVER_BUFSIZE;
169 urb->pipe = usb_rcvintpipe(chip->dev, COMM_EP);
170 urb->dev = chip->dev;
171 urb->complete = usb6fire_comm_receiver_handler;
174 ret = usb_submit_urb(urb, GFP_KERNEL);
176 kfree(rt->receiver_buffer);
178 dev_err(&chip->dev->dev, "cannot create comm data receiver.");
185 void usb6fire_comm_abort(struct sfire_chip *chip)
187 struct comm_runtime *rt = chip->comm;
190 usb_poison_urb(&rt->receiver);
193 void usb6fire_comm_destroy(struct sfire_chip *chip)
195 struct comm_runtime *rt = chip->comm;
197 kfree(rt->receiver_buffer);