Root/drivers/hid/hid-logitech-dj.c

1/*
2 * HID driver for Logitech Unifying receivers
3 *
4 * Copyright (c) 2011 Logitech
5 */
6
7/*
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 *
22 */
23
24
25#include <linux/device.h>
26#include <linux/hid.h>
27#include <linux/module.h>
28#include <linux/usb.h>
29#include <asm/unaligned.h>
30#include "usbhid/usbhid.h"
31#include "hid-ids.h"
32#include "hid-logitech-dj.h"
33
34/* Keyboard descriptor (1) */
35static const char kbd_descriptor[] = {
36    0x05, 0x01, /* USAGE_PAGE (generic Desktop) */
37    0x09, 0x06, /* USAGE (Keyboard) */
38    0xA1, 0x01, /* COLLECTION (Application) */
39    0x85, 0x01, /* REPORT_ID (1) */
40    0x95, 0x08, /* REPORT_COUNT (8) */
41    0x75, 0x01, /* REPORT_SIZE (1) */
42    0x15, 0x00, /* LOGICAL_MINIMUM (0) */
43    0x25, 0x01, /* LOGICAL_MAXIMUM (1) */
44    0x05, 0x07, /* USAGE_PAGE (Keyboard) */
45    0x19, 0xE0, /* USAGE_MINIMUM (Left Control) */
46    0x29, 0xE7, /* USAGE_MAXIMUM (Right GUI) */
47    0x81, 0x02, /* INPUT (Data,Var,Abs) */
48    0x95, 0x05, /* REPORT COUNT (5) */
49    0x05, 0x08, /* USAGE PAGE (LED page) */
50    0x19, 0x01, /* USAGE MINIMUM (1) */
51    0x29, 0x05, /* USAGE MAXIMUM (5) */
52    0x91, 0x02, /* OUTPUT (Data, Variable, Absolute) */
53    0x95, 0x01, /* REPORT COUNT (1) */
54    0x75, 0x03, /* REPORT SIZE (3) */
55    0x91, 0x01, /* OUTPUT (Constant) */
56    0x95, 0x06, /* REPORT_COUNT (6) */
57    0x75, 0x08, /* REPORT_SIZE (8) */
58    0x15, 0x00, /* LOGICAL_MINIMUM (0) */
59    0x26, 0xFF, 0x00, /* LOGICAL_MAXIMUM (255) */
60    0x05, 0x07, /* USAGE_PAGE (Keyboard) */
61    0x19, 0x00, /* USAGE_MINIMUM (no event) */
62    0x2A, 0xFF, 0x00, /* USAGE_MAXIMUM (reserved) */
63    0x81, 0x00, /* INPUT (Data,Ary,Abs) */
64    0xC0
65};
66
67/* Mouse descriptor (2) */
68static const char mse_descriptor[] = {
69    0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */
70    0x09, 0x02, /* USAGE (Mouse) */
71    0xA1, 0x01, /* COLLECTION (Application) */
72    0x85, 0x02, /* REPORT_ID = 2 */
73    0x09, 0x01, /* USAGE (pointer) */
74    0xA1, 0x00, /* COLLECTION (physical) */
75    0x05, 0x09, /* USAGE_PAGE (buttons) */
76    0x19, 0x01, /* USAGE_MIN (1) */
77    0x29, 0x10, /* USAGE_MAX (16) */
78    0x15, 0x00, /* LOGICAL_MIN (0) */
79    0x25, 0x01, /* LOGICAL_MAX (1) */
80    0x95, 0x10, /* REPORT_COUNT (16) */
81    0x75, 0x01, /* REPORT_SIZE (1) */
82    0x81, 0x02, /* INPUT (data var abs) */
83    0x05, 0x01, /* USAGE_PAGE (generic desktop) */
84    0x16, 0x01, 0xF8, /* LOGICAL_MIN (-2047) */
85    0x26, 0xFF, 0x07, /* LOGICAL_MAX (2047) */
86    0x75, 0x0C, /* REPORT_SIZE (12) */
87    0x95, 0x02, /* REPORT_COUNT (2) */
88    0x09, 0x30, /* USAGE (X) */
89    0x09, 0x31, /* USAGE (Y) */
90    0x81, 0x06, /* INPUT */
91    0x15, 0x81, /* LOGICAL_MIN (-127) */
92    0x25, 0x7F, /* LOGICAL_MAX (127) */
93    0x75, 0x08, /* REPORT_SIZE (8) */
94    0x95, 0x01, /* REPORT_COUNT (1) */
95    0x09, 0x38, /* USAGE (wheel) */
96    0x81, 0x06, /* INPUT */
97    0x05, 0x0C, /* USAGE_PAGE(consumer) */
98    0x0A, 0x38, 0x02, /* USAGE(AC Pan) */
99    0x95, 0x01, /* REPORT_COUNT (1) */
100    0x81, 0x06, /* INPUT */
101    0xC0, /* END_COLLECTION */
102    0xC0, /* END_COLLECTION */
103};
104
105/* Consumer Control descriptor (3) */
106static const char consumer_descriptor[] = {
107    0x05, 0x0C, /* USAGE_PAGE (Consumer Devices) */
108    0x09, 0x01, /* USAGE (Consumer Control) */
109    0xA1, 0x01, /* COLLECTION (Application) */
110    0x85, 0x03, /* REPORT_ID = 3 */
111    0x75, 0x10, /* REPORT_SIZE (16) */
112    0x95, 0x02, /* REPORT_COUNT (2) */
113    0x15, 0x01, /* LOGICAL_MIN (1) */
114    0x26, 0x8C, 0x02, /* LOGICAL_MAX (652) */
115    0x19, 0x01, /* USAGE_MIN (1) */
116    0x2A, 0x8C, 0x02, /* USAGE_MAX (652) */
117    0x81, 0x00, /* INPUT (Data Ary Abs) */
118    0xC0, /* END_COLLECTION */
119}; /* */
120
121/* System control descriptor (4) */
122static const char syscontrol_descriptor[] = {
123    0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */
124    0x09, 0x80, /* USAGE (System Control) */
125    0xA1, 0x01, /* COLLECTION (Application) */
126    0x85, 0x04, /* REPORT_ID = 4 */
127    0x75, 0x02, /* REPORT_SIZE (2) */
128    0x95, 0x01, /* REPORT_COUNT (1) */
129    0x15, 0x01, /* LOGICAL_MIN (1) */
130    0x25, 0x03, /* LOGICAL_MAX (3) */
131    0x09, 0x82, /* USAGE (System Sleep) */
132    0x09, 0x81, /* USAGE (System Power Down) */
133    0x09, 0x83, /* USAGE (System Wake Up) */
134    0x81, 0x60, /* INPUT (Data Ary Abs NPrf Null) */
135    0x75, 0x06, /* REPORT_SIZE (6) */
136    0x81, 0x03, /* INPUT (Cnst Var Abs) */
137    0xC0, /* END_COLLECTION */
138};
139
140/* Media descriptor (8) */
141static const char media_descriptor[] = {
142    0x06, 0xbc, 0xff, /* Usage Page 0xffbc */
143    0x09, 0x88, /* Usage 0x0088 */
144    0xa1, 0x01, /* BeginCollection */
145    0x85, 0x08, /* Report ID 8 */
146    0x19, 0x01, /* Usage Min 0x0001 */
147    0x29, 0xff, /* Usage Max 0x00ff */
148    0x15, 0x01, /* Logical Min 1 */
149    0x26, 0xff, 0x00, /* Logical Max 255 */
150    0x75, 0x08, /* Report Size 8 */
151    0x95, 0x01, /* Report Count 1 */
152    0x81, 0x00, /* Input */
153    0xc0, /* EndCollection */
154}; /* */
155
156/* Maximum size of all defined hid reports in bytes (including report id) */
157#define MAX_REPORT_SIZE 8
158
159/* Make sure all descriptors are present here */
160#define MAX_RDESC_SIZE \
161    (sizeof(kbd_descriptor) + \
162     sizeof(mse_descriptor) + \
163     sizeof(consumer_descriptor) + \
164     sizeof(syscontrol_descriptor) + \
165     sizeof(media_descriptor))
166
167/* Number of possible hid report types that can be created by this driver.
168 *
169 * Right now, RF report types have the same report types (or report id's)
170 * than the hid report created from those RF reports. In the future
171 * this doesnt have to be true.
172 *
173 * For instance, RF report type 0x01 which has a size of 8 bytes, corresponds
174 * to hid report id 0x01, this is standard keyboard. Same thing applies to mice
175 * reports and consumer control, etc. If a new RF report is created, it doesn't
176 * has to have the same report id as its corresponding hid report, so an
177 * translation may have to take place for future report types.
178 */
179#define NUMBER_OF_HID_REPORTS 32
180static const u8 hid_reportid_size_map[NUMBER_OF_HID_REPORTS] = {
181    [1] = 8, /* Standard keyboard */
182    [2] = 8, /* Standard mouse */
183    [3] = 5, /* Consumer control */
184    [4] = 2, /* System control */
185    [8] = 2, /* Media Center */
186};
187
188
189#define LOGITECH_DJ_INTERFACE_NUMBER 0x02
190
191static struct hid_ll_driver logi_dj_ll_driver;
192
193static int logi_dj_output_hidraw_report(struct hid_device *hid, u8 * buf,
194                    size_t count,
195                    unsigned char report_type);
196static int logi_dj_recv_query_paired_devices(struct dj_receiver_dev *djrcv_dev);
197
198static void logi_dj_recv_destroy_djhid_device(struct dj_receiver_dev *djrcv_dev,
199                        struct dj_report *dj_report)
200{
201    /* Called in delayed work context */
202    struct dj_device *dj_dev;
203    unsigned long flags;
204
205    spin_lock_irqsave(&djrcv_dev->lock, flags);
206    dj_dev = djrcv_dev->paired_dj_devices[dj_report->device_index];
207    djrcv_dev->paired_dj_devices[dj_report->device_index] = NULL;
208    spin_unlock_irqrestore(&djrcv_dev->lock, flags);
209
210    if (dj_dev != NULL) {
211        hid_destroy_device(dj_dev->hdev);
212        kfree(dj_dev);
213    } else {
214        dev_err(&djrcv_dev->hdev->dev, "%s: can't destroy a NULL device\n",
215            __func__);
216    }
217}
218
219static void logi_dj_recv_add_djhid_device(struct dj_receiver_dev *djrcv_dev,
220                      struct dj_report *dj_report)
221{
222    /* Called in delayed work context */
223    struct hid_device *djrcv_hdev = djrcv_dev->hdev;
224    struct usb_interface *intf = to_usb_interface(djrcv_hdev->dev.parent);
225    struct usb_device *usbdev = interface_to_usbdev(intf);
226    struct hid_device *dj_hiddev;
227    struct dj_device *dj_dev;
228
229    /* Device index goes from 1 to 6, we need 3 bytes to store the
230     * semicolon, the index, and a null terminator
231     */
232    unsigned char tmpstr[3];
233
234    if (dj_report->report_params[DEVICE_PAIRED_PARAM_SPFUNCTION] &
235        SPFUNCTION_DEVICE_LIST_EMPTY) {
236        dbg_hid("%s: device list is empty\n", __func__);
237        djrcv_dev->querying_devices = false;
238        return;
239    }
240
241    if ((dj_report->device_index < DJ_DEVICE_INDEX_MIN) ||
242        (dj_report->device_index > DJ_DEVICE_INDEX_MAX)) {
243        dev_err(&djrcv_hdev->dev, "%s: invalid device index:%d\n",
244            __func__, dj_report->device_index);
245        return;
246    }
247
248    if (djrcv_dev->paired_dj_devices[dj_report->device_index]) {
249        /* The device is already known. No need to reallocate it. */
250        dbg_hid("%s: device is already known\n", __func__);
251        return;
252    }
253
254    dj_hiddev = hid_allocate_device();
255    if (IS_ERR(dj_hiddev)) {
256        dev_err(&djrcv_hdev->dev, "%s: hid_allocate_device failed\n",
257            __func__);
258        return;
259    }
260
261    dj_hiddev->ll_driver = &logi_dj_ll_driver;
262    dj_hiddev->hid_output_raw_report = logi_dj_output_hidraw_report;
263
264    dj_hiddev->dev.parent = &djrcv_hdev->dev;
265    dj_hiddev->bus = BUS_USB;
266    dj_hiddev->vendor = le16_to_cpu(usbdev->descriptor.idVendor);
267    dj_hiddev->product = le16_to_cpu(usbdev->descriptor.idProduct);
268    snprintf(dj_hiddev->name, sizeof(dj_hiddev->name),
269        "Logitech Unifying Device. Wireless PID:%02x%02x",
270        dj_report->report_params[DEVICE_PAIRED_PARAM_EQUAD_ID_MSB],
271        dj_report->report_params[DEVICE_PAIRED_PARAM_EQUAD_ID_LSB]);
272
273    usb_make_path(usbdev, dj_hiddev->phys, sizeof(dj_hiddev->phys));
274    snprintf(tmpstr, sizeof(tmpstr), ":%d", dj_report->device_index);
275    strlcat(dj_hiddev->phys, tmpstr, sizeof(dj_hiddev->phys));
276
277    dj_dev = kzalloc(sizeof(struct dj_device), GFP_KERNEL);
278
279    if (!dj_dev) {
280        dev_err(&djrcv_hdev->dev, "%s: failed allocating dj_device\n",
281            __func__);
282        goto dj_device_allocate_fail;
283    }
284
285    dj_dev->reports_supported = get_unaligned_le32(
286        dj_report->report_params + DEVICE_PAIRED_RF_REPORT_TYPE);
287    dj_dev->hdev = dj_hiddev;
288    dj_dev->dj_receiver_dev = djrcv_dev;
289    dj_dev->device_index = dj_report->device_index;
290    dj_hiddev->driver_data = dj_dev;
291
292    djrcv_dev->paired_dj_devices[dj_report->device_index] = dj_dev;
293
294    if (hid_add_device(dj_hiddev)) {
295        dev_err(&djrcv_hdev->dev, "%s: failed adding dj_device\n",
296            __func__);
297        goto hid_add_device_fail;
298    }
299
300    return;
301
302hid_add_device_fail:
303    djrcv_dev->paired_dj_devices[dj_report->device_index] = NULL;
304    kfree(dj_dev);
305dj_device_allocate_fail:
306    hid_destroy_device(dj_hiddev);
307}
308
309static void delayedwork_callback(struct work_struct *work)
310{
311    struct dj_receiver_dev *djrcv_dev =
312        container_of(work, struct dj_receiver_dev, work);
313
314    struct dj_report dj_report;
315    unsigned long flags;
316    int count;
317    int retval;
318
319    dbg_hid("%s\n", __func__);
320
321    spin_lock_irqsave(&djrcv_dev->lock, flags);
322
323    count = kfifo_out(&djrcv_dev->notif_fifo, &dj_report,
324                sizeof(struct dj_report));
325
326    if (count != sizeof(struct dj_report)) {
327        dev_err(&djrcv_dev->hdev->dev, "%s: workitem triggered without "
328            "notifications available\n", __func__);
329        spin_unlock_irqrestore(&djrcv_dev->lock, flags);
330        return;
331    }
332
333    if (!kfifo_is_empty(&djrcv_dev->notif_fifo)) {
334        if (schedule_work(&djrcv_dev->work) == 0) {
335            dbg_hid("%s: did not schedule the work item, was "
336                "already queued\n", __func__);
337        }
338    }
339
340    spin_unlock_irqrestore(&djrcv_dev->lock, flags);
341
342    switch (dj_report.report_type) {
343    case REPORT_TYPE_NOTIF_DEVICE_PAIRED:
344        logi_dj_recv_add_djhid_device(djrcv_dev, &dj_report);
345        break;
346    case REPORT_TYPE_NOTIF_DEVICE_UNPAIRED:
347        logi_dj_recv_destroy_djhid_device(djrcv_dev, &dj_report);
348        break;
349    default:
350    /* A normal report (i. e. not belonging to a pair/unpair notification)
351     * arriving here, means that the report arrived but we did not have a
352     * paired dj_device associated to the report's device_index, this
353     * means that the original "device paired" notification corresponding
354     * to this dj_device never arrived to this driver. The reason is that
355     * hid-core discards all packets coming from a device while probe() is
356     * executing. */
357    if (!djrcv_dev->paired_dj_devices[dj_report.device_index]) {
358        /* ok, we don't know the device, just re-ask the
359         * receiver for the list of connected devices. */
360        retval = logi_dj_recv_query_paired_devices(djrcv_dev);
361        if (!retval) {
362            /* everything went fine, so just leave */
363            break;
364        }
365        dev_err(&djrcv_dev->hdev->dev,
366            "%s:logi_dj_recv_query_paired_devices "
367            "error:%d\n", __func__, retval);
368        }
369        dbg_hid("%s: unexpected report type\n", __func__);
370    }
371}
372
373static void logi_dj_recv_queue_notification(struct dj_receiver_dev *djrcv_dev,
374                       struct dj_report *dj_report)
375{
376    /* We are called from atomic context (tasklet && djrcv->lock held) */
377
378    kfifo_in(&djrcv_dev->notif_fifo, dj_report, sizeof(struct dj_report));
379
380    if (schedule_work(&djrcv_dev->work) == 0) {
381        dbg_hid("%s: did not schedule the work item, was already "
382            "queued\n", __func__);
383    }
384}
385
386static void logi_dj_recv_forward_null_report(struct dj_receiver_dev *djrcv_dev,
387                         struct dj_report *dj_report)
388{
389    /* We are called from atomic context (tasklet && djrcv->lock held) */
390    unsigned int i;
391    u8 reportbuffer[MAX_REPORT_SIZE];
392    struct dj_device *djdev;
393
394    djdev = djrcv_dev->paired_dj_devices[dj_report->device_index];
395
396    if (!djdev) {
397        dbg_hid("djrcv_dev->paired_dj_devices[dj_report->device_index]"
398            " is NULL, index %d\n", dj_report->device_index);
399        kfifo_in(&djrcv_dev->notif_fifo, dj_report, sizeof(struct dj_report));
400
401        if (schedule_work(&djrcv_dev->work) == 0) {
402            dbg_hid("%s: did not schedule the work item, was already "
403            "queued\n", __func__);
404        }
405        return;
406    }
407
408    memset(reportbuffer, 0, sizeof(reportbuffer));
409
410    for (i = 0; i < NUMBER_OF_HID_REPORTS; i++) {
411        if (djdev->reports_supported & (1 << i)) {
412            reportbuffer[0] = i;
413            if (hid_input_report(djdev->hdev,
414                         HID_INPUT_REPORT,
415                         reportbuffer,
416                         hid_reportid_size_map[i], 1)) {
417                dbg_hid("hid_input_report error sending null "
418                    "report\n");
419            }
420        }
421    }
422}
423
424static void logi_dj_recv_forward_report(struct dj_receiver_dev *djrcv_dev,
425                    struct dj_report *dj_report)
426{
427    /* We are called from atomic context (tasklet && djrcv->lock held) */
428    struct dj_device *dj_device;
429
430    dj_device = djrcv_dev->paired_dj_devices[dj_report->device_index];
431
432    if (dj_device == NULL) {
433        dbg_hid("djrcv_dev->paired_dj_devices[dj_report->device_index]"
434            " is NULL, index %d\n", dj_report->device_index);
435        kfifo_in(&djrcv_dev->notif_fifo, dj_report, sizeof(struct dj_report));
436
437        if (schedule_work(&djrcv_dev->work) == 0) {
438            dbg_hid("%s: did not schedule the work item, was already "
439            "queued\n", __func__);
440        }
441        return;
442    }
443
444    if ((dj_report->report_type > ARRAY_SIZE(hid_reportid_size_map) - 1) ||
445        (hid_reportid_size_map[dj_report->report_type] == 0)) {
446        dbg_hid("invalid report type:%x\n", dj_report->report_type);
447        return;
448    }
449
450    if (hid_input_report(dj_device->hdev,
451            HID_INPUT_REPORT, &dj_report->report_type,
452            hid_reportid_size_map[dj_report->report_type], 1)) {
453        dbg_hid("hid_input_report error\n");
454    }
455}
456
457
458static int logi_dj_recv_send_report(struct dj_receiver_dev *djrcv_dev,
459                    struct dj_report *dj_report)
460{
461    struct hid_device *hdev = djrcv_dev->hdev;
462    int sent_bytes;
463
464    if (!hdev->hid_output_raw_report) {
465        dev_err(&hdev->dev, "%s:"
466            "hid_output_raw_report is null\n", __func__);
467        return -ENODEV;
468    }
469
470    sent_bytes = hdev->hid_output_raw_report(hdev, (u8 *) dj_report,
471                         sizeof(struct dj_report),
472                         HID_OUTPUT_REPORT);
473
474    return (sent_bytes < 0) ? sent_bytes : 0;
475}
476
477static int logi_dj_recv_query_paired_devices(struct dj_receiver_dev *djrcv_dev)
478{
479    struct dj_report *dj_report;
480    int retval;
481
482    /* no need to protect djrcv_dev->querying_devices */
483    if (djrcv_dev->querying_devices)
484        return 0;
485
486    dj_report = kzalloc(sizeof(struct dj_report), GFP_KERNEL);
487    if (!dj_report)
488        return -ENOMEM;
489    dj_report->report_id = REPORT_ID_DJ_SHORT;
490    dj_report->device_index = 0xFF;
491    dj_report->report_type = REPORT_TYPE_CMD_GET_PAIRED_DEVICES;
492    retval = logi_dj_recv_send_report(djrcv_dev, dj_report);
493    kfree(dj_report);
494    return retval;
495}
496
497
498static int logi_dj_recv_switch_to_dj_mode(struct dj_receiver_dev *djrcv_dev,
499                      unsigned timeout)
500{
501    struct dj_report *dj_report;
502    int retval;
503
504    dj_report = kzalloc(sizeof(struct dj_report), GFP_KERNEL);
505    if (!dj_report)
506        return -ENOMEM;
507    dj_report->report_id = REPORT_ID_DJ_SHORT;
508    dj_report->device_index = 0xFF;
509    dj_report->report_type = REPORT_TYPE_CMD_SWITCH;
510    dj_report->report_params[CMD_SWITCH_PARAM_DEVBITFIELD] = 0x3F;
511    dj_report->report_params[CMD_SWITCH_PARAM_TIMEOUT_SECONDS] = (u8)timeout;
512    retval = logi_dj_recv_send_report(djrcv_dev, dj_report);
513    kfree(dj_report);
514    return retval;
515}
516
517
518static int logi_dj_ll_open(struct hid_device *hid)
519{
520    dbg_hid("%s:%s\n", __func__, hid->phys);
521    return 0;
522
523}
524
525static void logi_dj_ll_close(struct hid_device *hid)
526{
527    dbg_hid("%s:%s\n", __func__, hid->phys);
528}
529
530static int logi_dj_output_hidraw_report(struct hid_device *hid, u8 * buf,
531                    size_t count,
532                    unsigned char report_type)
533{
534    /* Called by hid raw to send data */
535    dbg_hid("%s\n", __func__);
536
537    return 0;
538}
539
540static void rdcat(char **rdesc, unsigned int *rsize, const char *data, unsigned int size)
541{
542    memcpy(*rdesc + *rsize, data, size);
543    *rsize += size;
544}
545
546static int logi_dj_ll_parse(struct hid_device *hid)
547{
548    struct dj_device *djdev = hid->driver_data;
549    unsigned int rsize = 0;
550    char *rdesc;
551    int retval;
552
553    dbg_hid("%s\n", __func__);
554
555    djdev->hdev->version = 0x0111;
556    djdev->hdev->country = 0x00;
557
558    rdesc = kmalloc(MAX_RDESC_SIZE, GFP_KERNEL);
559    if (!rdesc)
560        return -ENOMEM;
561
562    if (djdev->reports_supported & STD_KEYBOARD) {
563        dbg_hid("%s: sending a kbd descriptor, reports_supported: %x\n",
564            __func__, djdev->reports_supported);
565        rdcat(&rdesc, &rsize, kbd_descriptor, sizeof(kbd_descriptor));
566    }
567
568    if (djdev->reports_supported & STD_MOUSE) {
569        dbg_hid("%s: sending a mouse descriptor, reports_supported: "
570            "%x\n", __func__, djdev->reports_supported);
571        rdcat(&rdesc, &rsize, mse_descriptor, sizeof(mse_descriptor));
572    }
573
574    if (djdev->reports_supported & MULTIMEDIA) {
575        dbg_hid("%s: sending a multimedia report descriptor: %x\n",
576            __func__, djdev->reports_supported);
577        rdcat(&rdesc, &rsize, consumer_descriptor, sizeof(consumer_descriptor));
578    }
579
580    if (djdev->reports_supported & POWER_KEYS) {
581        dbg_hid("%s: sending a power keys report descriptor: %x\n",
582            __func__, djdev->reports_supported);
583        rdcat(&rdesc, &rsize, syscontrol_descriptor, sizeof(syscontrol_descriptor));
584    }
585
586    if (djdev->reports_supported & MEDIA_CENTER) {
587        dbg_hid("%s: sending a media center report descriptor: %x\n",
588            __func__, djdev->reports_supported);
589        rdcat(&rdesc, &rsize, media_descriptor, sizeof(media_descriptor));
590    }
591
592    if (djdev->reports_supported & KBD_LEDS) {
593        dbg_hid("%s: need to send kbd leds report descriptor: %x\n",
594            __func__, djdev->reports_supported);
595    }
596
597    retval = hid_parse_report(hid, rdesc, rsize);
598    kfree(rdesc);
599
600    return retval;
601}
602
603static int logi_dj_ll_input_event(struct input_dev *dev, unsigned int type,
604                  unsigned int code, int value)
605{
606    /* Sent by the input layer to handle leds and Force Feedback */
607    struct hid_device *dj_hiddev = input_get_drvdata(dev);
608    struct dj_device *dj_dev = dj_hiddev->driver_data;
609
610    struct dj_receiver_dev *djrcv_dev =
611        dev_get_drvdata(dj_hiddev->dev.parent);
612    struct hid_device *dj_rcv_hiddev = djrcv_dev->hdev;
613    struct hid_report_enum *output_report_enum;
614
615    struct hid_field *field;
616    struct hid_report *report;
617    unsigned char data[8];
618    int offset;
619
620    dbg_hid("%s: %s, type:%d | code:%d | value:%d\n",
621        __func__, dev->phys, type, code, value);
622
623    if (type != EV_LED)
624        return -1;
625
626    offset = hidinput_find_field(dj_hiddev, type, code, &field);
627
628    if (offset == -1) {
629        dev_warn(&dev->dev, "event field not found\n");
630        return -1;
631    }
632    hid_set_field(field, offset, value);
633    hid_output_report(field->report, &data[0]);
634
635    output_report_enum = &dj_rcv_hiddev->report_enum[HID_OUTPUT_REPORT];
636    report = output_report_enum->report_id_hash[REPORT_ID_DJ_SHORT];
637    hid_set_field(report->field[0], 0, dj_dev->device_index);
638    hid_set_field(report->field[0], 1, REPORT_TYPE_LEDS);
639    hid_set_field(report->field[0], 2, data[1]);
640
641    usbhid_submit_report(dj_rcv_hiddev, report, USB_DIR_OUT);
642
643    return 0;
644
645}
646
647static int logi_dj_ll_start(struct hid_device *hid)
648{
649    dbg_hid("%s\n", __func__);
650    return 0;
651}
652
653static void logi_dj_ll_stop(struct hid_device *hid)
654{
655    dbg_hid("%s\n", __func__);
656}
657
658
659static struct hid_ll_driver logi_dj_ll_driver = {
660    .parse = logi_dj_ll_parse,
661    .start = logi_dj_ll_start,
662    .stop = logi_dj_ll_stop,
663    .open = logi_dj_ll_open,
664    .close = logi_dj_ll_close,
665    .hidinput_input_event = logi_dj_ll_input_event,
666};
667
668
669static int logi_dj_raw_event(struct hid_device *hdev,
670                 struct hid_report *report, u8 *data,
671                 int size)
672{
673    struct dj_receiver_dev *djrcv_dev = hid_get_drvdata(hdev);
674    struct dj_report *dj_report = (struct dj_report *) data;
675    unsigned long flags;
676    bool report_processed = false;
677
678    dbg_hid("%s, size:%d\n", __func__, size);
679
680    /* Here we receive all data coming from iface 2, there are 4 cases:
681     *
682     * 1) Data should continue its normal processing i.e. data does not
683     * come from the DJ collection, in which case we do nothing and
684     * return 0, so hid-core can continue normal processing (will forward
685     * to associated hidraw device)
686     *
687     * 2) Data is from DJ collection, and is intended for this driver i. e.
688     * data contains arrival, departure, etc notifications, in which case
689     * we queue them for delayed processing by the work queue. We return 1
690     * to hid-core as no further processing is required from it.
691     *
692     * 3) Data is from DJ collection, and informs a connection change,
693     * if the change means rf link loss, then we must send a null report
694     * to the upper layer to discard potentially pressed keys that may be
695     * repeated forever by the input layer. Return 1 to hid-core as no
696     * further processing is required.
697     *
698     * 4) Data is from DJ collection and is an actual input event from
699     * a paired DJ device in which case we forward it to the correct hid
700     * device (via hid_input_report() ) and return 1 so hid-core does not do
701     * anything else with it.
702     */
703
704    spin_lock_irqsave(&djrcv_dev->lock, flags);
705    if (dj_report->report_id == REPORT_ID_DJ_SHORT) {
706        switch (dj_report->report_type) {
707        case REPORT_TYPE_NOTIF_DEVICE_PAIRED:
708        case REPORT_TYPE_NOTIF_DEVICE_UNPAIRED:
709            logi_dj_recv_queue_notification(djrcv_dev, dj_report);
710            break;
711        case REPORT_TYPE_NOTIF_CONNECTION_STATUS:
712            if (dj_report->report_params[CONNECTION_STATUS_PARAM_STATUS] ==
713                STATUS_LINKLOSS) {
714                logi_dj_recv_forward_null_report(djrcv_dev, dj_report);
715            }
716            break;
717        default:
718            logi_dj_recv_forward_report(djrcv_dev, dj_report);
719        }
720        report_processed = true;
721    }
722    spin_unlock_irqrestore(&djrcv_dev->lock, flags);
723
724    return report_processed;
725}
726
727static int logi_dj_probe(struct hid_device *hdev,
728             const struct hid_device_id *id)
729{
730    struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
731    struct dj_receiver_dev *djrcv_dev;
732    int retval;
733
734    if (is_dj_device((struct dj_device *)hdev->driver_data))
735        return -ENODEV;
736
737    dbg_hid("%s called for ifnum %d\n", __func__,
738        intf->cur_altsetting->desc.bInterfaceNumber);
739
740    /* Ignore interfaces 0 and 1, they will not carry any data, dont create
741     * any hid_device for them */
742    if (intf->cur_altsetting->desc.bInterfaceNumber !=
743        LOGITECH_DJ_INTERFACE_NUMBER) {
744        dbg_hid("%s: ignoring ifnum %d\n", __func__,
745            intf->cur_altsetting->desc.bInterfaceNumber);
746        return -ENODEV;
747    }
748
749    /* Treat interface 2 */
750
751    djrcv_dev = kzalloc(sizeof(struct dj_receiver_dev), GFP_KERNEL);
752    if (!djrcv_dev) {
753        dev_err(&hdev->dev,
754            "%s:failed allocating dj_receiver_dev\n", __func__);
755        return -ENOMEM;
756    }
757    djrcv_dev->hdev = hdev;
758    INIT_WORK(&djrcv_dev->work, delayedwork_callback);
759    spin_lock_init(&djrcv_dev->lock);
760    if (kfifo_alloc(&djrcv_dev->notif_fifo,
761            DJ_MAX_NUMBER_NOTIFICATIONS * sizeof(struct dj_report),
762            GFP_KERNEL)) {
763        dev_err(&hdev->dev,
764            "%s:failed allocating notif_fifo\n", __func__);
765        kfree(djrcv_dev);
766        return -ENOMEM;
767    }
768    hid_set_drvdata(hdev, djrcv_dev);
769
770    /* Call to usbhid to fetch the HID descriptors of interface 2 and
771     * subsequently call to the hid/hid-core to parse the fetched
772     * descriptors, this will in turn create the hidraw and hiddev nodes
773     * for interface 2 of the receiver */
774    retval = hid_parse(hdev);
775    if (retval) {
776        dev_err(&hdev->dev,
777            "%s:parse of interface 2 failed\n", __func__);
778        goto hid_parse_fail;
779    }
780
781    /* Starts the usb device and connects to upper interfaces hiddev and
782     * hidraw */
783    retval = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
784    if (retval) {
785        dev_err(&hdev->dev,
786            "%s:hid_hw_start returned error\n", __func__);
787        goto hid_hw_start_fail;
788    }
789
790    retval = logi_dj_recv_switch_to_dj_mode(djrcv_dev, 0);
791    if (retval < 0) {
792        dev_err(&hdev->dev,
793            "%s:logi_dj_recv_switch_to_dj_mode returned error:%d\n",
794            __func__, retval);
795        goto switch_to_dj_mode_fail;
796    }
797
798    /* This is enabling the polling urb on the IN endpoint */
799    retval = hdev->ll_driver->open(hdev);
800    if (retval < 0) {
801        dev_err(&hdev->dev, "%s:hdev->ll_driver->open returned "
802            "error:%d\n", __func__, retval);
803        goto llopen_failed;
804    }
805
806    retval = logi_dj_recv_query_paired_devices(djrcv_dev);
807    if (retval < 0) {
808        dev_err(&hdev->dev, "%s:logi_dj_recv_query_paired_devices "
809            "error:%d\n", __func__, retval);
810        goto logi_dj_recv_query_paired_devices_failed;
811    }
812
813    return retval;
814
815logi_dj_recv_query_paired_devices_failed:
816    hdev->ll_driver->close(hdev);
817
818llopen_failed:
819switch_to_dj_mode_fail:
820    hid_hw_stop(hdev);
821
822hid_hw_start_fail:
823hid_parse_fail:
824    kfifo_free(&djrcv_dev->notif_fifo);
825    kfree(djrcv_dev);
826    hid_set_drvdata(hdev, NULL);
827    return retval;
828
829}
830
831#ifdef CONFIG_PM
832static int logi_dj_reset_resume(struct hid_device *hdev)
833{
834    int retval;
835    struct dj_receiver_dev *djrcv_dev = hid_get_drvdata(hdev);
836
837    retval = logi_dj_recv_switch_to_dj_mode(djrcv_dev, 0);
838    if (retval < 0) {
839        dev_err(&hdev->dev,
840            "%s:logi_dj_recv_switch_to_dj_mode returned error:%d\n",
841            __func__, retval);
842    }
843
844    return 0;
845}
846#endif
847
848static void logi_dj_remove(struct hid_device *hdev)
849{
850    struct dj_receiver_dev *djrcv_dev = hid_get_drvdata(hdev);
851    struct dj_device *dj_dev;
852    int i;
853
854    dbg_hid("%s\n", __func__);
855
856    cancel_work_sync(&djrcv_dev->work);
857
858    hdev->ll_driver->close(hdev);
859    hid_hw_stop(hdev);
860
861    /* I suppose that at this point the only context that can access
862     * the djrecv_data is this thread as the work item is guaranteed to
863     * have finished and no more raw_event callbacks should arrive after
864     * the remove callback was triggered so no locks are put around the
865     * code below */
866    for (i = 0; i < (DJ_MAX_PAIRED_DEVICES + DJ_DEVICE_INDEX_MIN); i++) {
867        dj_dev = djrcv_dev->paired_dj_devices[i];
868        if (dj_dev != NULL) {
869            hid_destroy_device(dj_dev->hdev);
870            kfree(dj_dev);
871            djrcv_dev->paired_dj_devices[i] = NULL;
872        }
873    }
874
875    kfifo_free(&djrcv_dev->notif_fifo);
876    kfree(djrcv_dev);
877    hid_set_drvdata(hdev, NULL);
878}
879
880static int logi_djdevice_probe(struct hid_device *hdev,
881             const struct hid_device_id *id)
882{
883    int ret;
884    struct dj_device *dj_dev = hdev->driver_data;
885
886    if (!is_dj_device(dj_dev))
887        return -ENODEV;
888
889    ret = hid_parse(hdev);
890    if (!ret)
891        ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
892
893    return ret;
894}
895
896static const struct hid_device_id logi_dj_receivers[] = {
897    {HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,
898        USB_DEVICE_ID_LOGITECH_UNIFYING_RECEIVER)},
899    {HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,
900        USB_DEVICE_ID_LOGITECH_UNIFYING_RECEIVER_2)},
901    {}
902};
903
904MODULE_DEVICE_TABLE(hid, logi_dj_receivers);
905
906static struct hid_driver logi_djreceiver_driver = {
907    .name = "logitech-djreceiver",
908    .id_table = logi_dj_receivers,
909    .probe = logi_dj_probe,
910    .remove = logi_dj_remove,
911    .raw_event = logi_dj_raw_event,
912#ifdef CONFIG_PM
913    .reset_resume = logi_dj_reset_resume,
914#endif
915};
916
917
918static const struct hid_device_id logi_dj_devices[] = {
919    {HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,
920        USB_DEVICE_ID_LOGITECH_UNIFYING_RECEIVER)},
921    {HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,
922        USB_DEVICE_ID_LOGITECH_UNIFYING_RECEIVER_2)},
923    {}
924};
925
926static struct hid_driver logi_djdevice_driver = {
927    .name = "logitech-djdevice",
928    .id_table = logi_dj_devices,
929    .probe = logi_djdevice_probe,
930};
931
932
933static int __init logi_dj_init(void)
934{
935    int retval;
936
937    dbg_hid("Logitech-DJ:%s\n", __func__);
938
939    retval = hid_register_driver(&logi_djreceiver_driver);
940    if (retval)
941        return retval;
942
943    retval = hid_register_driver(&logi_djdevice_driver);
944    if (retval)
945        hid_unregister_driver(&logi_djreceiver_driver);
946
947    return retval;
948
949}
950
951static void __exit logi_dj_exit(void)
952{
953    dbg_hid("Logitech-DJ:%s\n", __func__);
954
955    hid_unregister_driver(&logi_djdevice_driver);
956    hid_unregister_driver(&logi_djreceiver_driver);
957
958}
959
960module_init(logi_dj_init);
961module_exit(logi_dj_exit);
962MODULE_LICENSE("GPL");
963MODULE_AUTHOR("Logitech");
964MODULE_AUTHOR("Nestor Lopez Casado");
965MODULE_AUTHOR("nlopezcasad@logitech.com");
966

Archive Download this file



interactive