aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hid/hid-logitech-dj.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hid/hid-logitech-dj.c')
-rw-r--r--drivers/hid/hid-logitech-dj.c76
1 files changed, 32 insertions, 44 deletions
diff --git a/drivers/hid/hid-logitech-dj.c b/drivers/hid/hid-logitech-dj.c
index 2b56efcbdf61..5e8a7ed42344 100644
--- a/drivers/hid/hid-logitech-dj.c
+++ b/drivers/hid/hid-logitech-dj.c
@@ -26,6 +26,7 @@
26#include <linux/hid.h> 26#include <linux/hid.h>
27#include <linux/module.h> 27#include <linux/module.h>
28#include <linux/usb.h> 28#include <linux/usb.h>
29#include <asm/unaligned.h>
29#include "usbhid/usbhid.h" 30#include "usbhid/usbhid.h"
30#include "hid-ids.h" 31#include "hid-ids.h"
31#include "hid-logitech-dj.h" 32#include "hid-logitech-dj.h"
@@ -155,6 +156,14 @@ static const char media_descriptor[] = {
155/* Maximum size of all defined hid reports in bytes (including report id) */ 156/* Maximum size of all defined hid reports in bytes (including report id) */
156#define MAX_REPORT_SIZE 8 157#define MAX_REPORT_SIZE 8
157 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
158/* Number of possible hid report types that can be created by this driver. 167/* Number of possible hid report types that can be created by this driver.
159 * 168 *
160 * Right now, RF report types have the same report types (or report id's) 169 * Right now, RF report types have the same report types (or report id's)
@@ -265,8 +274,8 @@ static void logi_dj_recv_add_djhid_device(struct dj_receiver_dev *djrcv_dev,
265 goto dj_device_allocate_fail; 274 goto dj_device_allocate_fail;
266 } 275 }
267 276
268 dj_dev->reports_supported = le32_to_cpu( 277 dj_dev->reports_supported = get_unaligned_le32(
269 dj_report->report_params[DEVICE_PAIRED_RF_REPORT_TYPE]); 278 dj_report->report_params + DEVICE_PAIRED_RF_REPORT_TYPE);
270 dj_dev->hdev = dj_hiddev; 279 dj_dev->hdev = dj_hiddev;
271 dj_dev->dj_receiver_dev = djrcv_dev; 280 dj_dev->dj_receiver_dev = djrcv_dev;
272 dj_dev->device_index = dj_report->device_index; 281 dj_dev->device_index = dj_report->device_index;
@@ -473,9 +482,17 @@ static int logi_dj_output_hidraw_report(struct hid_device *hid, u8 * buf,
473 return 0; 482 return 0;
474} 483}
475 484
485static void rdcat(char **rdesc, unsigned int *rsize, const char *data, unsigned int size)
486{
487 memcpy(*rdesc + *rsize, data, size);
488 *rsize += size;
489}
490
476static int logi_dj_ll_parse(struct hid_device *hid) 491static int logi_dj_ll_parse(struct hid_device *hid)
477{ 492{
478 struct dj_device *djdev = hid->driver_data; 493 struct dj_device *djdev = hid->driver_data;
494 unsigned int rsize = 0;
495 char *rdesc;
479 int retval; 496 int retval;
480 497
481 dbg_hid("%s\n", __func__); 498 dbg_hid("%s\n", __func__);
@@ -483,70 +500,38 @@ static int logi_dj_ll_parse(struct hid_device *hid)
483 djdev->hdev->version = 0x0111; 500 djdev->hdev->version = 0x0111;
484 djdev->hdev->country = 0x00; 501 djdev->hdev->country = 0x00;
485 502
503 rdesc = kmalloc(MAX_RDESC_SIZE, GFP_KERNEL);
504 if (!rdesc)
505 return -ENOMEM;
506
486 if (djdev->reports_supported & STD_KEYBOARD) { 507 if (djdev->reports_supported & STD_KEYBOARD) {
487 dbg_hid("%s: sending a kbd descriptor, reports_supported: %x\n", 508 dbg_hid("%s: sending a kbd descriptor, reports_supported: %x\n",
488 __func__, djdev->reports_supported); 509 __func__, djdev->reports_supported);
489 retval = hid_parse_report(hid, 510 rdcat(&rdesc, &rsize, kbd_descriptor, sizeof(kbd_descriptor));
490 (u8 *) kbd_descriptor,
491 sizeof(kbd_descriptor));
492 if (retval) {
493 dbg_hid("%s: sending a kbd descriptor, hid_parse failed"
494 " error: %d\n", __func__, retval);
495 return retval;
496 }
497 } 511 }
498 512
499 if (djdev->reports_supported & STD_MOUSE) { 513 if (djdev->reports_supported & STD_MOUSE) {
500 dbg_hid("%s: sending a mouse descriptor, reports_supported: " 514 dbg_hid("%s: sending a mouse descriptor, reports_supported: "
501 "%x\n", __func__, djdev->reports_supported); 515 "%x\n", __func__, djdev->reports_supported);
502 retval = hid_parse_report(hid, 516 rdcat(&rdesc, &rsize, mse_descriptor, sizeof(mse_descriptor));
503 (u8 *) mse_descriptor,
504 sizeof(mse_descriptor));
505 if (retval) {
506 dbg_hid("%s: sending a mouse descriptor, hid_parse "
507 "failed error: %d\n", __func__, retval);
508 return retval;
509 }
510 } 517 }
511 518
512 if (djdev->reports_supported & MULTIMEDIA) { 519 if (djdev->reports_supported & MULTIMEDIA) {
513 dbg_hid("%s: sending a multimedia report descriptor: %x\n", 520 dbg_hid("%s: sending a multimedia report descriptor: %x\n",
514 __func__, djdev->reports_supported); 521 __func__, djdev->reports_supported);
515 retval = hid_parse_report(hid, 522 rdcat(&rdesc, &rsize, consumer_descriptor, sizeof(consumer_descriptor));
516 (u8 *) consumer_descriptor,
517 sizeof(consumer_descriptor));
518 if (retval) {
519 dbg_hid("%s: sending a consumer_descriptor, hid_parse "
520 "failed error: %d\n", __func__, retval);
521 return retval;
522 }
523 } 523 }
524 524
525 if (djdev->reports_supported & POWER_KEYS) { 525 if (djdev->reports_supported & POWER_KEYS) {
526 dbg_hid("%s: sending a power keys report descriptor: %x\n", 526 dbg_hid("%s: sending a power keys report descriptor: %x\n",
527 __func__, djdev->reports_supported); 527 __func__, djdev->reports_supported);
528 retval = hid_parse_report(hid, 528 rdcat(&rdesc, &rsize, syscontrol_descriptor, sizeof(syscontrol_descriptor));
529 (u8 *) syscontrol_descriptor,
530 sizeof(syscontrol_descriptor));
531 if (retval) {
532 dbg_hid("%s: sending a syscontrol_descriptor, "
533 "hid_parse failed error: %d\n",
534 __func__, retval);
535 return retval;
536 }
537 } 529 }
538 530
539 if (djdev->reports_supported & MEDIA_CENTER) { 531 if (djdev->reports_supported & MEDIA_CENTER) {
540 dbg_hid("%s: sending a media center report descriptor: %x\n", 532 dbg_hid("%s: sending a media center report descriptor: %x\n",
541 __func__, djdev->reports_supported); 533 __func__, djdev->reports_supported);
542 retval = hid_parse_report(hid, 534 rdcat(&rdesc, &rsize, media_descriptor, sizeof(media_descriptor));
543 (u8 *) media_descriptor,
544 sizeof(media_descriptor));
545 if (retval) {
546 dbg_hid("%s: sending a media_descriptor, hid_parse "
547 "failed error: %d\n", __func__, retval);
548 return retval;
549 }
550 } 535 }
551 536
552 if (djdev->reports_supported & KBD_LEDS) { 537 if (djdev->reports_supported & KBD_LEDS) {
@@ -554,7 +539,10 @@ static int logi_dj_ll_parse(struct hid_device *hid)
554 __func__, djdev->reports_supported); 539 __func__, djdev->reports_supported);
555 } 540 }
556 541
557 return 0; 542 retval = hid_parse_report(hid, rdesc, rsize);
543 kfree(rdesc);
544
545 return retval;
558} 546}
559 547
560static int logi_dj_ll_input_event(struct input_dev *dev, unsigned int type, 548static int logi_dj_ll_input_event(struct input_dev *dev, unsigned int type,