Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
[linux-2.6-microblaze.git] / drivers / input / joystick / iforce / iforce-usb.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2  /*
3  *  Copyright (c) 2000-2002 Vojtech Pavlik <vojtech@ucw.cz>
4  *  Copyright (c) 2001-2002, 2007 Johann Deneux <johann.deneux@gmail.com>
5  *
6  *  USB/RS232 I-Force joysticks and wheels.
7  */
8
9 /*
10  */
11
12 #include <linux/usb.h>
13 #include "iforce.h"
14
15 struct iforce_usb {
16         struct iforce iforce;
17
18         struct usb_device *usbdev;
19         struct usb_interface *intf;
20         struct urb *irq, *out;
21
22         u8 data_in[IFORCE_MAX_LENGTH] ____cacheline_aligned;
23         u8 data_out[IFORCE_MAX_LENGTH] ____cacheline_aligned;
24 };
25
26 static void __iforce_usb_xmit(struct iforce *iforce)
27 {
28         struct iforce_usb *iforce_usb = container_of(iforce, struct iforce_usb,
29                                                      iforce);
30         int n, c;
31         unsigned long flags;
32
33         spin_lock_irqsave(&iforce->xmit_lock, flags);
34
35         if (iforce->xmit.head == iforce->xmit.tail) {
36                 clear_bit(IFORCE_XMIT_RUNNING, iforce->xmit_flags);
37                 spin_unlock_irqrestore(&iforce->xmit_lock, flags);
38                 return;
39         }
40
41         ((char *)iforce_usb->out->transfer_buffer)[0] = iforce->xmit.buf[iforce->xmit.tail];
42         XMIT_INC(iforce->xmit.tail, 1);
43         n = iforce->xmit.buf[iforce->xmit.tail];
44         XMIT_INC(iforce->xmit.tail, 1);
45
46         iforce_usb->out->transfer_buffer_length = n + 1;
47         iforce_usb->out->dev = iforce_usb->usbdev;
48
49         /* Copy rest of data then */
50         c = CIRC_CNT_TO_END(iforce->xmit.head, iforce->xmit.tail, XMIT_SIZE);
51         if (n < c) c=n;
52
53         memcpy(iforce_usb->out->transfer_buffer + 1,
54                &iforce->xmit.buf[iforce->xmit.tail],
55                c);
56         if (n != c) {
57                 memcpy(iforce_usb->out->transfer_buffer + 1 + c,
58                        &iforce->xmit.buf[0],
59                        n-c);
60         }
61         XMIT_INC(iforce->xmit.tail, n);
62
63         if ( (n=usb_submit_urb(iforce_usb->out, GFP_ATOMIC)) ) {
64                 clear_bit(IFORCE_XMIT_RUNNING, iforce->xmit_flags);
65                 dev_warn(&iforce_usb->intf->dev,
66                          "usb_submit_urb failed %d\n", n);
67         }
68
69         /* The IFORCE_XMIT_RUNNING bit is not cleared here. That's intended.
70          * As long as the urb completion handler is not called, the transmiting
71          * is considered to be running */
72         spin_unlock_irqrestore(&iforce->xmit_lock, flags);
73 }
74
75 static void iforce_usb_xmit(struct iforce *iforce)
76 {
77         if (!test_and_set_bit(IFORCE_XMIT_RUNNING, iforce->xmit_flags))
78                 __iforce_usb_xmit(iforce);
79 }
80
81 static int iforce_usb_get_id(struct iforce *iforce, u8 id,
82                              u8 *response_data, size_t *response_len)
83 {
84         struct iforce_usb *iforce_usb = container_of(iforce, struct iforce_usb,
85                                                      iforce);
86         u8 *buf;
87         int status;
88
89         buf = kmalloc(IFORCE_MAX_LENGTH, GFP_KERNEL);
90         if (!buf)
91                 return -ENOMEM;
92
93         status = usb_control_msg(iforce_usb->usbdev,
94                                  usb_rcvctrlpipe(iforce_usb->usbdev, 0),
95                                  id,
96                                  USB_TYPE_VENDOR | USB_DIR_IN |
97                                         USB_RECIP_INTERFACE,
98                                  0, 0, buf, IFORCE_MAX_LENGTH, HZ);
99         if (status < 0) {
100                 dev_err(&iforce_usb->intf->dev,
101                         "usb_submit_urb failed: %d\n", status);
102         } else if (buf[0] != id) {
103                 status = -EIO;
104         } else {
105                 memcpy(response_data, buf, status);
106                 *response_len = status;
107                 status = 0;
108         }
109
110         kfree(buf);
111         return status;
112 }
113
114 static int iforce_usb_start_io(struct iforce *iforce)
115 {
116         struct iforce_usb *iforce_usb = container_of(iforce, struct iforce_usb,
117                                                      iforce);
118
119         if (usb_submit_urb(iforce_usb->irq, GFP_KERNEL))
120                 return -EIO;
121
122         return 0;
123 }
124
125 static void iforce_usb_stop_io(struct iforce *iforce)
126 {
127         struct iforce_usb *iforce_usb = container_of(iforce, struct iforce_usb,
128                                                      iforce);
129
130         usb_kill_urb(iforce_usb->irq);
131         usb_kill_urb(iforce_usb->out);
132 }
133
134 static const struct iforce_xport_ops iforce_usb_xport_ops = {
135         .xmit           = iforce_usb_xmit,
136         .get_id         = iforce_usb_get_id,
137         .start_io       = iforce_usb_start_io,
138         .stop_io        = iforce_usb_stop_io,
139 };
140
141 static void iforce_usb_irq(struct urb *urb)
142 {
143         struct iforce_usb *iforce_usb = urb->context;
144         struct iforce *iforce = &iforce_usb->iforce;
145         struct device *dev = &iforce_usb->intf->dev;
146         int status;
147
148         switch (urb->status) {
149         case 0:
150                 /* success */
151                 break;
152         case -ECONNRESET:
153         case -ENOENT:
154         case -ESHUTDOWN:
155                 /* this urb is terminated, clean up */
156                 dev_dbg(dev, "%s - urb shutting down with status: %d\n",
157                         __func__, urb->status);
158                 return;
159         default:
160                 dev_dbg(dev, "%s - urb has status of: %d\n",
161                         __func__, urb->status);
162                 goto exit;
163         }
164
165         iforce_process_packet(iforce, iforce_usb->data_in[0],
166                               iforce_usb->data_in + 1, urb->actual_length - 1);
167
168 exit:
169         status = usb_submit_urb(urb, GFP_ATOMIC);
170         if (status)
171                 dev_err(dev, "%s - usb_submit_urb failed with result %d\n",
172                         __func__, status);
173 }
174
175 static void iforce_usb_out(struct urb *urb)
176 {
177         struct iforce_usb *iforce_usb = urb->context;
178         struct iforce *iforce = &iforce_usb->iforce;
179
180         if (urb->status) {
181                 clear_bit(IFORCE_XMIT_RUNNING, iforce->xmit_flags);
182                 dev_dbg(&iforce_usb->intf->dev, "urb->status %d, exiting\n",
183                         urb->status);
184                 return;
185         }
186
187         __iforce_usb_xmit(iforce);
188
189         wake_up(&iforce->wait);
190 }
191
192 static int iforce_usb_probe(struct usb_interface *intf,
193                                 const struct usb_device_id *id)
194 {
195         struct usb_device *dev = interface_to_usbdev(intf);
196         struct usb_host_interface *interface;
197         struct usb_endpoint_descriptor *epirq, *epout;
198         struct iforce_usb *iforce_usb;
199         int err = -ENOMEM;
200
201         interface = intf->cur_altsetting;
202
203         if (interface->desc.bNumEndpoints < 2)
204                 return -ENODEV;
205
206         epirq = &interface->endpoint[0].desc;
207         epout = &interface->endpoint[1].desc;
208
209         iforce_usb = kzalloc(sizeof(*iforce_usb), GFP_KERNEL);
210         if (!iforce_usb)
211                 goto fail;
212
213         iforce_usb->irq = usb_alloc_urb(0, GFP_KERNEL);
214         if (!iforce_usb->irq)
215                 goto fail;
216
217         iforce_usb->out = usb_alloc_urb(0, GFP_KERNEL);
218         if (!iforce_usb->out)
219                 goto fail;
220
221         iforce_usb->iforce.xport_ops = &iforce_usb_xport_ops;
222
223         iforce_usb->usbdev = dev;
224         iforce_usb->intf = intf;
225
226         usb_fill_int_urb(iforce_usb->irq, dev,
227                          usb_rcvintpipe(dev, epirq->bEndpointAddress),
228                          iforce_usb->data_in, sizeof(iforce_usb->data_in),
229                          iforce_usb_irq, iforce_usb, epirq->bInterval);
230
231         usb_fill_int_urb(iforce_usb->out, dev,
232                          usb_sndintpipe(dev, epout->bEndpointAddress),
233                          iforce_usb->data_out, sizeof(iforce_usb->data_out),
234                          iforce_usb_out, iforce_usb, epout->bInterval);
235
236         err = iforce_init_device(&intf->dev, BUS_USB, &iforce_usb->iforce);
237         if (err)
238                 goto fail;
239
240         usb_set_intfdata(intf, iforce_usb);
241         return 0;
242
243 fail:
244         if (iforce_usb) {
245                 usb_free_urb(iforce_usb->irq);
246                 usb_free_urb(iforce_usb->out);
247                 kfree(iforce_usb);
248         }
249
250         return err;
251 }
252
253 static void iforce_usb_disconnect(struct usb_interface *intf)
254 {
255         struct iforce_usb *iforce_usb = usb_get_intfdata(intf);
256
257         usb_set_intfdata(intf, NULL);
258
259         input_unregister_device(iforce_usb->iforce.dev);
260
261         usb_free_urb(iforce_usb->irq);
262         usb_free_urb(iforce_usb->out);
263
264         kfree(iforce_usb);
265 }
266
267 static const struct usb_device_id iforce_usb_ids[] = {
268         { USB_DEVICE(0x044f, 0xa01c) },         /* Thrustmaster Motor Sport GT */
269         { USB_DEVICE(0x046d, 0xc281) },         /* Logitech WingMan Force */
270         { USB_DEVICE(0x046d, 0xc291) },         /* Logitech WingMan Formula Force */
271         { USB_DEVICE(0x05ef, 0x020a) },         /* AVB Top Shot Pegasus */
272         { USB_DEVICE(0x05ef, 0x8884) },         /* AVB Mag Turbo Force */
273         { USB_DEVICE(0x05ef, 0x8888) },         /* AVB Top Shot FFB Racing Wheel */
274         { USB_DEVICE(0x061c, 0xc0a4) },         /* ACT LABS Force RS */
275         { USB_DEVICE(0x061c, 0xc084) },         /* ACT LABS Force RS */
276         { USB_DEVICE(0x06a3, 0xff04) },         /* Saitek R440 Force Wheel */
277         { USB_DEVICE(0x06f8, 0x0001) },         /* Guillemot Race Leader Force Feedback */
278         { USB_DEVICE(0x06f8, 0x0003) },         /* Guillemot Jet Leader Force Feedback */
279         { USB_DEVICE(0x06f8, 0x0004) },         /* Guillemot Force Feedback Racing Wheel */
280         { USB_DEVICE(0x06f8, 0xa302) },         /* Guillemot Jet Leader 3D */
281         { }                                     /* Terminating entry */
282 };
283
284 MODULE_DEVICE_TABLE (usb, iforce_usb_ids);
285
286 struct usb_driver iforce_usb_driver = {
287         .name =         "iforce",
288         .probe =        iforce_usb_probe,
289         .disconnect =   iforce_usb_disconnect,
290         .id_table =     iforce_usb_ids,
291 };
292
293 module_usb_driver(iforce_usb_driver);
294
295 MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>, Johann Deneux <johann.deneux@gmail.com>");
296 MODULE_DESCRIPTION("USB I-Force joysticks and wheels driver");
297 MODULE_LICENSE("GPL");