1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Linux driver for TerraTec DMX 6Fire USB
5 * Device communications
7 * Author: Torsten Schenk <torsten.schenk@zoho.com>
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
);