|
@@ -44,14 +44,6 @@ static const char kbd_descriptor[] = {
|
|
|
0x19, 0xE0, /* USAGE_MINIMUM (Left Control) */
|
|
|
0x29, 0xE7, /* USAGE_MAXIMUM (Right GUI) */
|
|
|
0x81, 0x02, /* INPUT (Data,Var,Abs) */
|
|
|
- 0x95, 0x05, /* REPORT COUNT (5) */
|
|
|
- 0x05, 0x08, /* USAGE PAGE (LED page) */
|
|
|
- 0x19, 0x01, /* USAGE MINIMUM (1) */
|
|
|
- 0x29, 0x05, /* USAGE MAXIMUM (5) */
|
|
|
- 0x91, 0x02, /* OUTPUT (Data, Variable, Absolute) */
|
|
|
- 0x95, 0x01, /* REPORT COUNT (1) */
|
|
|
- 0x75, 0x03, /* REPORT SIZE (3) */
|
|
|
- 0x91, 0x01, /* OUTPUT (Constant) */
|
|
|
0x95, 0x06, /* REPORT_COUNT (6) */
|
|
|
0x75, 0x08, /* REPORT_SIZE (8) */
|
|
|
0x15, 0x00, /* LOGICAL_MINIMUM (0) */
|
|
@@ -60,6 +52,18 @@ static const char kbd_descriptor[] = {
|
|
|
0x19, 0x00, /* USAGE_MINIMUM (no event) */
|
|
|
0x2A, 0xFF, 0x00, /* USAGE_MAXIMUM (reserved) */
|
|
|
0x81, 0x00, /* INPUT (Data,Ary,Abs) */
|
|
|
+ 0x85, 0x0e, /* REPORT_ID (14) */
|
|
|
+ 0x05, 0x08, /* USAGE PAGE (LED page) */
|
|
|
+ 0x95, 0x05, /* REPORT COUNT (5) */
|
|
|
+ 0x75, 0x01, /* REPORT SIZE (1) */
|
|
|
+ 0x15, 0x00, /* LOGICAL_MINIMUM (0) */
|
|
|
+ 0x25, 0x01, /* LOGICAL_MAXIMUM (1) */
|
|
|
+ 0x19, 0x01, /* USAGE MINIMUM (1) */
|
|
|
+ 0x29, 0x05, /* USAGE MAXIMUM (5) */
|
|
|
+ 0x91, 0x02, /* OUTPUT (Data, Variable, Absolute) */
|
|
|
+ 0x95, 0x01, /* REPORT COUNT (1) */
|
|
|
+ 0x75, 0x03, /* REPORT SIZE (3) */
|
|
|
+ 0x91, 0x01, /* OUTPUT (Constant) */
|
|
|
0xC0
|
|
|
};
|
|
|
|
|
@@ -544,10 +548,37 @@ static int logi_dj_output_hidraw_report(struct hid_device *hid, u8 * buf,
|
|
|
size_t count,
|
|
|
unsigned char report_type)
|
|
|
{
|
|
|
- /* Called by hid raw to send data */
|
|
|
- dbg_hid("%s\n", __func__);
|
|
|
+ struct dj_device *djdev = hid->driver_data;
|
|
|
+ struct dj_receiver_dev *djrcv_dev = djdev->dj_receiver_dev;
|
|
|
+ u8 *out_buf;
|
|
|
+ int ret;
|
|
|
|
|
|
- return 0;
|
|
|
+ if (buf[0] != REPORT_TYPE_LEDS)
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
+ out_buf = kzalloc(DJREPORT_SHORT_LENGTH, GFP_ATOMIC);
|
|
|
+ if (!out_buf)
|
|
|
+ return -ENOMEM;
|
|
|
+
|
|
|
+ if (count < DJREPORT_SHORT_LENGTH - 2)
|
|
|
+ count = DJREPORT_SHORT_LENGTH - 2;
|
|
|
+
|
|
|
+ out_buf[0] = REPORT_ID_DJ_SHORT;
|
|
|
+ out_buf[1] = djdev->device_index;
|
|
|
+ memcpy(out_buf + 2, buf, count);
|
|
|
+
|
|
|
+ /*
|
|
|
+ * hid-generic calls us with hid_output_raw_report(), but the LEDs
|
|
|
+ * are set through a SET_REPORT command. It works for USB-HID devices
|
|
|
+ * because usbhid either calls a SET_REPORT or directly send the output
|
|
|
+ * report depending if the device presents an urbout.
|
|
|
+ * Let be simple, send a SET_REPORT request.
|
|
|
+ */
|
|
|
+ ret = hid_hw_raw_request(djrcv_dev->hdev, out_buf[0], out_buf,
|
|
|
+ DJREPORT_SHORT_LENGTH, report_type, HID_REQ_SET_REPORT);
|
|
|
+
|
|
|
+ kfree(out_buf);
|
|
|
+ return ret;
|
|
|
}
|
|
|
|
|
|
static void rdcat(char *rdesc, unsigned int *rsize, const char *data, unsigned int size)
|
|
@@ -613,58 +644,6 @@ static int logi_dj_ll_parse(struct hid_device *hid)
|
|
|
return retval;
|
|
|
}
|
|
|
|
|
|
-static int logi_dj_ll_input_event(struct input_dev *dev, unsigned int type,
|
|
|
- unsigned int code, int value)
|
|
|
-{
|
|
|
- /* Sent by the input layer to handle leds and Force Feedback */
|
|
|
- struct hid_device *dj_hiddev = input_get_drvdata(dev);
|
|
|
- struct dj_device *dj_dev = dj_hiddev->driver_data;
|
|
|
-
|
|
|
- struct dj_receiver_dev *djrcv_dev =
|
|
|
- dev_get_drvdata(dj_hiddev->dev.parent);
|
|
|
- struct hid_device *dj_rcv_hiddev = djrcv_dev->hdev;
|
|
|
- struct hid_report_enum *output_report_enum;
|
|
|
-
|
|
|
- struct hid_field *field;
|
|
|
- struct hid_report *report;
|
|
|
- unsigned char *data;
|
|
|
- int offset;
|
|
|
-
|
|
|
- dbg_hid("%s: %s, type:%d | code:%d | value:%d\n",
|
|
|
- __func__, dev->phys, type, code, value);
|
|
|
-
|
|
|
- if (type != EV_LED)
|
|
|
- return -1;
|
|
|
-
|
|
|
- offset = hidinput_find_field(dj_hiddev, type, code, &field);
|
|
|
-
|
|
|
- if (offset == -1) {
|
|
|
- dev_warn(&dev->dev, "event field not found\n");
|
|
|
- return -1;
|
|
|
- }
|
|
|
- hid_set_field(field, offset, value);
|
|
|
-
|
|
|
- data = hid_alloc_report_buf(field->report, GFP_ATOMIC);
|
|
|
- if (!data) {
|
|
|
- dev_warn(&dev->dev, "failed to allocate report buf memory\n");
|
|
|
- return -1;
|
|
|
- }
|
|
|
-
|
|
|
- hid_output_report(field->report, &data[0]);
|
|
|
-
|
|
|
- output_report_enum = &dj_rcv_hiddev->report_enum[HID_OUTPUT_REPORT];
|
|
|
- report = output_report_enum->report_id_hash[REPORT_ID_DJ_SHORT];
|
|
|
- hid_set_field(report->field[0], 0, dj_dev->device_index);
|
|
|
- hid_set_field(report->field[0], 1, REPORT_TYPE_LEDS);
|
|
|
- hid_set_field(report->field[0], 2, data[1]);
|
|
|
-
|
|
|
- hid_hw_request(dj_rcv_hiddev, report, HID_REQ_SET_REPORT);
|
|
|
-
|
|
|
- kfree(data);
|
|
|
-
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
static int logi_dj_ll_start(struct hid_device *hid)
|
|
|
{
|
|
|
dbg_hid("%s\n", __func__);
|
|
@@ -683,7 +662,6 @@ static struct hid_ll_driver logi_dj_ll_driver = {
|
|
|
.stop = logi_dj_ll_stop,
|
|
|
.open = logi_dj_ll_open,
|
|
|
.close = logi_dj_ll_close,
|
|
|
- .hidinput_input_event = logi_dj_ll_input_event,
|
|
|
};
|
|
|
|
|
|
|