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_KERNEL); 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 uhid_hid_input(struct input_dev *input, unsigned int type, unsigned int code, int value) { struct hid_device *hid = input_get_drvdata(input); struct uhid_device *uhid = hid->driver_data; unsigned long flags; struct uhid_event *ev; struct hid_field *field; struct hid_report *report; int offset; ev = kzalloc(sizeof(*ev), GFP_ATOMIC); if (!ev) return -ENOMEM; switch (type) { case EV_LED: offset = hidinput_find_field(hid, type, code, &field); if (offset == -1) { hid_warn(input, "event field not found\n"); kfree(ev); return -1; } hid_set_field(field, offset, value); report = field->report; ev->type = UHID_OUTPUT; ev->u.output.rtype = UHID_OUTPUT_REPORT; hid_output_report(report, ev->u.output.data); ev->u.output.size = ((report->size - 1) >> 3) + 1 + (report->id > 0); break; default: ev->type = UHID_OUTPUT_EV; ev->u.output_ev.type = type; ev->u.output_ev.code = code; ev->u.output_ev.value = value; } spin_lock_irqsave(&uhid->qlock, flags); uhid_queue(uhid, ev); spin_unlock_irqrestore(&uhid->qlock, flags); return 0; }
static int logi_dj_ll_input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) { 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[8]; 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); 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]); usbhid_submit_report(dj_rcv_hiddev, report, USB_DIR_OUT); return 0; }