Beispiel #1
0
static int hid_gaff_play(struct input_dev *dev, void *data,
			 struct ff_effect *effect)
{
	struct hid_device *hid = input_get_drvdata(dev);
	struct gaff_device *gaff = data;
	int left, right;

	left = effect->u.rumble.strong_magnitude;
	right = effect->u.rumble.weak_magnitude;

	dbg_hid("called with 0x%04x 0x%04x", left, right);

	left = left * 0xfe / 0xffff;
	right = right * 0xfe / 0xffff;

	gaff->report->field[0]->value[0] = 0x51;
	gaff->report->field[0]->value[1] = 0x0;
	gaff->report->field[0]->value[2] = right;
	gaff->report->field[0]->value[3] = 0;
	gaff->report->field[0]->value[4] = left;
	gaff->report->field[0]->value[5] = 0;
	dbg_hid("running with 0x%02x 0x%02x", left, right);
	usbhid_submit_report(hid, gaff->report, USB_DIR_OUT);

	gaff->report->field[0]->value[0] = 0xfa;
	gaff->report->field[0]->value[1] = 0xfe;
	gaff->report->field[0]->value[2] = 0x0;
	gaff->report->field[0]->value[4] = 0x0;

	usbhid_submit_report(hid, gaff->report, USB_DIR_OUT);

	return 0;
}
Beispiel #2
0
static int gaff_init(struct hid_device *hid)
{
	struct gaff_device *gaff;
	struct hid_report *report;
	struct hid_input *hidinput = list_entry(hid->inputs.next,
						struct hid_input, list);
	struct list_head *report_list =
			&hid->report_enum[HID_OUTPUT_REPORT].report_list;
	struct list_head *report_ptr = report_list;
	struct input_dev *dev = hidinput->input;
	int error;

	if (list_empty(report_list)) {
		dev_err(&hid->dev, "no output reports found\n");
		return -ENODEV;
	}

	report_ptr = report_ptr->next;

	report = list_entry(report_ptr, struct hid_report, list);
	if (report->maxfield < 1) {
		dev_err(&hid->dev, "no fields in the report\n");
		return -ENODEV;
	}

	if (report->field[0]->report_count < 6) {
		dev_err(&hid->dev, "not enough values in the field\n");
		return -ENODEV;
	}

	gaff = kzalloc(sizeof(struct gaff_device), GFP_KERNEL);
	if (!gaff)
		return -ENOMEM;

	set_bit(FF_RUMBLE, dev->ffbit);

	error = input_ff_create_memless(dev, gaff, hid_gaff_play);
	if (error) {
		kfree(gaff);
		return error;
	}

	gaff->report = report;
	gaff->report->field[0]->value[0] = 0x51;
	gaff->report->field[0]->value[1] = 0x00;
	gaff->report->field[0]->value[2] = 0x00;
	gaff->report->field[0]->value[3] = 0x00;
	usbhid_submit_report(hid, gaff->report, USB_DIR_OUT);

	gaff->report->field[0]->value[0] = 0xfa;
	gaff->report->field[0]->value[1] = 0xfe;

	usbhid_submit_report(hid, gaff->report, USB_DIR_OUT);

	dev_info(&hid->dev, "Force Feedback for GreenAsia 0x12"
	       " devices by Lukasz Lubojanski <*****@*****.**>\n");

	return 0;
}
static int zpff_play(struct input_dev *dev, void *data,
                     struct ff_effect *effect)
{
    struct hid_device *hid = input_get_drvdata(dev);
    struct zpff_device *zpff = data;
    int left, right;

    /*
     * The following is specified the other way around in the Zeroplus
     * datasheet but the order below is correct for the XFX Executioner;
     * however it is possible that the XFX Executioner is an exception
     */

    left = effect->u.rumble.strong_magnitude;
    right = effect->u.rumble.weak_magnitude;
    dbg_hid("called with 0x%04x 0x%04x\n", left, right);

    left = left * 0x7f / 0xffff;
    right = right * 0x7f / 0xffff;

    zpff->report->field[2]->value[0] = left;
    zpff->report->field[3]->value[0] = right;
    dbg_hid("running with 0x%02x 0x%02x\n", left, right);
    usbhid_submit_report(hid, zpff->report, USB_DIR_OUT);

    return 0;
}
static int play_effect(struct input_dev *dev, void *data,
			 struct ff_effect *effect)
{
	struct hid_device *hid = input_get_drvdata(dev);
	struct lg2ff_device *lg2ff = data;
	int weak, strong;

	strong = effect->u.rumble.strong_magnitude;
	weak = effect->u.rumble.weak_magnitude;

	if (weak || strong) {
		weak = weak * 0xff / 0xffff;
		strong = strong * 0xff / 0xffff;

		lg2ff->report->field[0]->value[0] = 0x51;
		lg2ff->report->field[0]->value[2] = weak;
		lg2ff->report->field[0]->value[4] = strong;
	} else {
		lg2ff->report->field[0]->value[0] = 0xf3;
		lg2ff->report->field[0]->value[2] = 0x00;
		lg2ff->report->field[0]->value[4] = 0x00;
	}

	usbhid_submit_report(hid, lg2ff->report, USB_DIR_OUT);
	return 0;
}
Beispiel #5
0
static void g19_feature_report_4_send(struct hid_device *hdev, int which)
{
	struct g19_data *g19data = hid_get_g19data(hdev);

	if (which == G19_REPORT_4_INIT) {
		g19data->feature_report_4->field[0]->value[0] = 0x02;
		g19data->feature_report_4->field[0]->value[1] = 0x00;
		g19data->feature_report_4->field[0]->value[2] = 0x00;
		g19data->feature_report_4->field[0]->value[3] = 0x00;
	} else if (which == G19_REPORT_4_FINALIZE) {
		g19data->feature_report_4->field[0]->value[0] = 0x02;
		g19data->feature_report_4->field[0]->value[1] = 0x80;
		g19data->feature_report_4->field[0]->value[2] = 0x00;
		g19data->feature_report_4->field[0]->value[3] = 0xFF;
	} else {
		return;
	}

#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)

	hid_hw_request(hdev, g19data->feature_report_4, HID_REQ_SET_REPORT);

#else

	usbhid_submit_report(hdev, g19data->feature_report_4, USB_DIR_OUT);

#endif
}
Beispiel #6
0
static int egalax_probe(struct hid_device *hdev, const struct hid_device_id *id)
{
	int ret;
	struct egalax_data *td;
	struct hid_report *report;

	td = kzalloc(sizeof(struct egalax_data), GFP_KERNEL);
	if (!td) {
		hid_err(hdev, "cannot allocate eGalax data\n");
		return -ENOMEM;
	}
	hid_set_drvdata(hdev, td);

	ret = hid_parse(hdev);
	if (ret)
		goto end;

	ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
	if (ret)
		goto end;

	report = hdev->report_enum[HID_FEATURE_REPORT].report_id_hash[5]; 
	if (report) {
		report->field[0]->value[0] = 2;
		usbhid_submit_report(hdev, report, USB_DIR_OUT);
	}

end:
	if (ret)
		kfree(td);

	return ret;
}
static int sjoyff_init(struct hid_device *hid)
{
	struct sjoyff_device *sjoyff;
	struct hid_report *report;
	struct hid_input *hidinput = list_entry(hid->inputs.next,
						struct hid_input, list);
	struct list_head *report_list =
			&hid->report_enum[HID_OUTPUT_REPORT].report_list;
	struct list_head *report_ptr = report_list;
	struct input_dev *dev;
	int error;

	if (list_empty(report_list)) {
		hid_err(hid, "no output reports found\n");
		return -ENODEV;
	}

	report_ptr = report_ptr->next;

	if (report_ptr == report_list) {
		hid_err(hid, "required output report is missing\n");
		return -ENODEV;
	}

	report = list_entry(report_ptr, struct hid_report, list);
	if (report->maxfield < 1) {
		hid_err(hid, "no fields in the report\n");
		return -ENODEV;
	}

	if (report->field[0]->report_count < 3) {
		hid_err(hid, "not enough values in the field\n");
		return -ENODEV;
	}

	sjoyff = kzalloc(sizeof(struct sjoyff_device), GFP_KERNEL);
	if (!sjoyff)
		return -ENOMEM;

	dev = hidinput->input;

	set_bit(FF_RUMBLE, dev->ffbit);

	error = input_ff_create_memless(dev, sjoyff, hid_sjoyff_play);
	if (error) {
		kfree(sjoyff);
		return error;
	}

	sjoyff->report = report;
	sjoyff->report->field[0]->value[0] = 0x01;
	sjoyff->report->field[0]->value[1] = 0x00;
	sjoyff->report->field[0]->value[2] = 0x00;
	usbhid_submit_report(hid, sjoyff->report, USB_DIR_OUT);

	hid_info(hid, "Force feedback for SmartJoy PLUS PS2/USB adapter\n");

	return 0;
}
Beispiel #8
0
static int mosart_reset_resume(struct hid_device *hdev)
{
    struct hid_report_enum *re = hdev->report_enum
                                     + HID_FEATURE_REPORT;
    struct hid_report *r = re->report_id_hash[7];

    r->field[0]->value[0] = 0x02;
    usbhid_submit_report(hdev, r, USB_DIR_OUT);
    return 0;
}
Beispiel #9
0
static void g15_msg_send(struct hid_device *hdev, u8 msg, u8 value1, u8 value2)
{
	struct g15_data *g15data = hid_get_g15data(hdev);

	g15data->led_report->field[0]->value[0] = msg;
	g15data->led_report->field[0]->value[1] = value1;
	g15data->led_report->field[0]->value[2] = value2;

	usbhid_submit_report(hdev, g15data->led_report, USB_DIR_OUT);
}
static int drff_play(struct input_dev *dev, void *data,
				 struct ff_effect *effect)
{
	struct hid_device *hid = input_get_drvdata(dev);
	struct drff_device *drff = data;
	int strong, weak;

	strong = effect->u.rumble.strong_magnitude;
	weak = effect->u.rumble.weak_magnitude;

	dbg_hid("called with 0x%04x 0x%04x", strong, weak);

	if (strong || weak) {
		strong = strong * 0xff / 0xffff;
		weak = weak * 0xff / 0xffff;

		/* While reverse engineering this device, I found that when
		   this value is set, it causes the strong rumble to function
		   at a near maximum speed, so we'll bypass it. */
		if (weak == 0x0a)
			weak = 0x0b;

		drff->report->field[0]->value[0] = 0x51;
		drff->report->field[0]->value[1] = 0x00;
		drff->report->field[0]->value[2] = weak;
		drff->report->field[0]->value[4] = strong;
		usbhid_submit_report(hid, drff->report, USB_DIR_OUT);

		drff->report->field[0]->value[0] = 0xfa;
		drff->report->field[0]->value[1] = 0xfe;
	} else {
		drff->report->field[0]->value[0] = 0xf3;
		drff->report->field[0]->value[1] = 0x00;
	}

	drff->report->field[0]->value[2] = 0x00;
	drff->report->field[0]->value[4] = 0x00;
	dbg_hid("running with 0x%02x 0x%02x", strong, weak);
	usbhid_submit_report(hid, drff->report, USB_DIR_OUT);

	return 0;
}
static int drff_init(struct hid_device *hid)
{
	struct drff_device *drff;
	struct hid_report *report;
	struct hid_input *hidinput = list_first_entry(&hid->inputs,
						struct hid_input, list);
	struct list_head *report_list =
			&hid->report_enum[HID_OUTPUT_REPORT].report_list;
	struct input_dev *dev = hidinput->input;
	int error;

	if (list_empty(report_list)) {
		hid_err(hid, "no output reports found\n");
		return -ENODEV;
	}

	report = list_first_entry(report_list, struct hid_report, list);
	if (report->maxfield < 1) {
		hid_err(hid, "no fields in the report\n");
		return -ENODEV;
	}

	if (report->field[0]->report_count < 7) {
		hid_err(hid, "not enough values in the field\n");
		return -ENODEV;
	}

	drff = kzalloc(sizeof(struct drff_device), GFP_KERNEL);
	if (!drff)
		return -ENOMEM;

	set_bit(FF_RUMBLE, dev->ffbit);

	error = input_ff_create_memless(dev, drff, drff_play);
	if (error) {
		kfree(drff);
		return error;
	}

	drff->report = report;
	drff->report->field[0]->value[0] = 0xf3;
	drff->report->field[0]->value[1] = 0x00;
	drff->report->field[0]->value[2] = 0x00;
	drff->report->field[0]->value[3] = 0x00;
	drff->report->field[0]->value[4] = 0x00;
	drff->report->field[0]->value[5] = 0x00;
	drff->report->field[0]->value[6] = 0x00;
	usbhid_submit_report(hid, drff->report, USB_DIR_OUT);

	hid_info(hid, "Force Feedback for DragonRise Inc. "
		 "game controllers by Richard Walmsley <*****@*****.**>\n");

	return 0;
}
Beispiel #12
0
static void g13_rgb_send(struct hid_device *hdev)
{
    struct g13_data *data = hid_get_g13data(hdev);

    data->backlight_report->field[0]->value[0] = data->rgb[0];
    data->backlight_report->field[0]->value[1] = data->rgb[1];
    data->backlight_report->field[0]->value[2] = data->rgb[2];
    data->backlight_report->field[0]->value[3] = 0x00;

    usbhid_submit_report(hdev, data->backlight_report, USB_DIR_OUT);
}
Beispiel #13
0
static int emsff_init(struct hid_device *hid)
{
	struct emsff_device *emsff;
	struct hid_report *report;
	struct hid_input *hidinput = list_first_entry(&hid->inputs,
						struct hid_input, list);
	struct list_head *report_list =
			&hid->report_enum[HID_OUTPUT_REPORT].report_list;
	struct input_dev *dev = hidinput->input;
	int error;

	if (list_empty(report_list)) {
		hid_err(hid, "no output reports found\n");
		return -ENODEV;
	}

	report = list_first_entry(report_list, struct hid_report, list);
	if (report->maxfield < 1) {
		hid_err(hid, "no fields in the report\n");
		return -ENODEV;
	}

	if (report->field[0]->report_count < 7) {
		hid_err(hid, "not enough values in the field\n");
		return -ENODEV;
	}

	emsff = kzalloc(sizeof(struct emsff_device), GFP_KERNEL);
	if (!emsff)
		return -ENOMEM;

	set_bit(FF_RUMBLE, dev->ffbit);

	error = input_ff_create_memless(dev, emsff, emsff_play);
	if (error) {
		kfree(emsff);
		return error;
	}

	emsff->report = report;
	emsff->report->field[0]->value[0] = 0x01;
	emsff->report->field[0]->value[1] = 0x00;
	emsff->report->field[0]->value[2] = 0x00;
	emsff->report->field[0]->value[3] = 0x00;
	emsff->report->field[0]->value[4] = 0x00;
	emsff->report->field[0]->value[5] = 0x00;
	emsff->report->field[0]->value[6] = 0x00;
	usbhid_submit_report(hid, emsff->report, USB_DIR_OUT);

	hid_info(hid, "force feedback for EMS based devices by Ignaz Forster <*****@*****.**>\n");

	return 0;
}
Beispiel #14
0
static int tmff_play(struct input_dev *dev, void *data,
		struct ff_effect *effect)
{
	struct hid_device *hid = input_get_drvdata(dev);
	struct tmff_device *tmff = data;
	struct hid_field *ff_field = tmff->ff_field;
	int x, y;
	int left, right;	/* Rumbling */

	switch (effect->type) {
	case FF_CONSTANT:
		x = tmff_scale_s8(effect->u.ramp.start_level,
					ff_field->logical_minimum,
					ff_field->logical_maximum);
		y = tmff_scale_s8(effect->u.ramp.end_level,
					ff_field->logical_minimum,
					ff_field->logical_maximum);

		dbg_hid("(x, y)=(%04x, %04x)\n", x, y);
		ff_field->value[0] = x;
		ff_field->value[1] = y;
		usbhid_submit_report(hid, tmff->report, USB_DIR_OUT);
		break;

	case FF_RUMBLE:
		left = tmff_scale_u16(effect->u.rumble.weak_magnitude,
					ff_field->logical_minimum,
					ff_field->logical_maximum);
		right = tmff_scale_u16(effect->u.rumble.strong_magnitude,
					ff_field->logical_minimum,
					ff_field->logical_maximum);

		dbg_hid("(left,right)=(%08x, %08x)\n", left, right);
		ff_field->value[0] = left;
		ff_field->value[1] = right;
		usbhid_submit_report(hid, tmff->report, USB_DIR_OUT);
		break;
	}
	return 0;
}
Beispiel #15
0
static void g19_led_send(struct hid_device *hdev)
{
	struct g19_data *g19data = hid_get_g19data(hdev);

	g19data->led_report->field[0]->value[0] = g19data->led&0xFF;

#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)

	hid_hw_request(hdev, g19data->led_report, HID_REQ_SET_REPORT);

#else

	usbhid_submit_report(hdev, g19data->led_report, USB_DIR_OUT);

#endif
}
Beispiel #16
0
static void mt_set_input_mode(struct hid_device *hdev)
{
	struct mt_device *td = hid_get_drvdata(hdev);
	struct hid_report *r;
	struct hid_report_enum *re;

	if (td->inputmode < 0)
		return;

	re = &(hdev->report_enum[HID_FEATURE_REPORT]);
	r = re->report_id_hash[td->inputmode];
	if (r) {
		r->field[0]->value[0] = 0x02;
		usbhid_submit_report(hdev, r, USB_DIR_OUT);
	}
}
Beispiel #17
0
static int zpff_init(struct hid_device *hid)
{
	struct zpff_device *zpff;
	struct hid_report *report;
	struct hid_input *hidinput = list_entry(hid->inputs.next,
						struct hid_input, list);
	struct list_head *report_list =
			&hid->report_enum[HID_OUTPUT_REPORT].report_list;
	struct input_dev *dev = hidinput->input;
	int error;

	if (list_empty(report_list)) {
		dev_err(&hid->dev, "no output report found\n");
		return -ENODEV;
	}

	report = list_entry(report_list->next, struct hid_report, list);

	if (report->maxfield < 4) {
		dev_err(&hid->dev, "not enough fields in report\n");
		return -ENODEV;
	}

	zpff = kzalloc(sizeof(struct zpff_device), GFP_KERNEL);
	if (!zpff)
		return -ENOMEM;

	set_bit(FF_RUMBLE, dev->ffbit);

	error = input_ff_create_memless(dev, zpff, zpff_play);
	if (error) {
		kfree(zpff);
		return error;
	}

	zpff->report = report;
	zpff->report->field[0]->value[0] = 0x00;
	zpff->report->field[1]->value[0] = 0x02;
	zpff->report->field[2]->value[0] = 0x00;
	zpff->report->field[3]->value[0] = 0x00;
	usbhid_submit_report(hid, zpff->report, USB_DIR_OUT);

	dev_info(&hid->dev, "force feedback for Zeroplus based devices by "
	       "Anssi Hannula <*****@*****.**>\n");

	return 0;
}
Beispiel #18
0
static int axff_init(struct hid_device *hid)
{
	struct axff_device *axff;
	struct hid_report *report;
	struct hid_input *hidinput = list_first_entry(&hid->inputs, struct hid_input, list);
	struct list_head *report_list =&hid->report_enum[HID_OUTPUT_REPORT].report_list;
	struct input_dev *dev = hidinput->input;
	int error;

	if (list_empty(report_list)) {
		dev_err(&hid->dev, "no output reports found\n");
		return -ENODEV;
	}

	report = list_first_entry(report_list, struct hid_report, list);

	if (report->maxfield < 4) {
		dev_err(&hid->dev, "no fields in the report: %d\n", report->maxfield);
		return -ENODEV;
	}

	axff = kzalloc(sizeof(struct axff_device), GFP_KERNEL);
	if (!axff)
		return -ENOMEM;

	set_bit(FF_RUMBLE, dev->ffbit);

	error = input_ff_create_memless(dev, axff, axff_play);
	if (error)
		goto err_free_mem;

	axff->report = report;
	axff->report->field[0]->value[0] = 0x00;
	axff->report->field[1]->value[0] = 0x00;
	axff->report->field[2]->value[0] = 0x00;
	axff->report->field[3]->value[0] = 0x00;
	usbhid_submit_report(hid, axff->report, USB_DIR_OUT);

	dev_info(&hid->dev, "Force Feedback for ACRUX game controllers by Sergei Kolzun<*****@*****.**>\n");

	return 0;

err_free_mem:
	kfree(axff);
	return error;
}
Beispiel #19
0
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[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;

}
Beispiel #20
0
static void g15_feature_report_4_send(struct hid_device *hdev, int which)
{
	struct g15_data *g15data = hid_get_g15data(hdev);

	if (which == G15_REPORT_4_INIT) {
		g15data->feature_report_4->field[0]->value[0] = 0x02;
		g15data->feature_report_4->field[0]->value[1] = 0x00;
		g15data->feature_report_4->field[0]->value[2] = 0x00;
		g15data->feature_report_4->field[0]->value[3] = 0x00;
	} else if (which == G15_REPORT_4_FINALIZE) {
		g15data->feature_report_4->field[0]->value[0] = 0x02;
		g15data->feature_report_4->field[0]->value[1] = 0x80;
		g15data->feature_report_4->field[0]->value[2] = 0x00;
		g15data->feature_report_4->field[0]->value[3] = 0xFF;
	} else {
		return;
	}

	usbhid_submit_report(hdev, g15data->feature_report_4, USB_DIR_OUT);
}
int lg2ff_init(struct hid_device *hid)
{
	struct lg2ff_device *lg2ff;
	struct hid_report *report;
	struct hid_input *hidinput = list_entry(hid->inputs.next,
						struct hid_input, list);
	struct input_dev *dev = hidinput->input;
	int error;

	/* Check that the report looks ok */
	report = hid_validate_report(hid, HID_OUTPUT_REPORT, 0, 1, 7);
	if (!report)
		return -ENODEV;

	lg2ff = kmalloc(sizeof(struct lg2ff_device), GFP_KERNEL);
	if (!lg2ff)
		return -ENOMEM;

	set_bit(FF_RUMBLE, dev->ffbit);

	error = input_ff_create_memless(dev, lg2ff, play_effect);
	if (error) {
		kfree(lg2ff);
		return error;
	}

	lg2ff->report = report;
	report->field[0]->value[0] = 0xf3;
	report->field[0]->value[1] = 0x00;
	report->field[0]->value[2] = 0x00;
	report->field[0]->value[3] = 0x00;
	report->field[0]->value[4] = 0x00;
	report->field[0]->value[5] = 0x00;
	report->field[0]->value[6] = 0x00;

	usbhid_submit_report(hid, report, USB_DIR_OUT);

	hid_info(hid, "Force feedback for Logitech RumblePad/Rumblepad 2 by Anssi Hannula <*****@*****.**>\n");

	return 0;
}
static int hid_sjoyff_play(struct input_dev *dev, void *data,
			 struct ff_effect *effect)
{
	struct hid_device *hid = input_get_drvdata(dev);
	struct sjoyff_device *sjoyff = data;
	u32 left, right;

	left = effect->u.rumble.strong_magnitude;
	right = effect->u.rumble.weak_magnitude;
	dev_dbg(&dev->dev, "called with 0x%08x 0x%08x\n", left, right);

	left = left * 0xff / 0xffff;
	right = (right != 0); /* on/off only */

	sjoyff->report->field[0]->value[1] = right;
	sjoyff->report->field[0]->value[2] = left;
	dev_dbg(&dev->dev, "running with 0x%02x 0x%02x\n", left, right);
	usbhid_submit_report(hid, sjoyff->report, USB_DIR_OUT);

	return 0;
}
static int hid_plff_play(struct input_dev *dev, void *data,
			 struct ff_effect *effect)
{
	struct hid_device *hid = input_get_drvdata(dev);
	struct plff_device *plff = data;
	int left, right;

	left = effect->u.rumble.strong_magnitude;
	right = effect->u.rumble.weak_magnitude;
	debug("called with 0x%04x 0x%04x", left, right);

	left = left * 0x7f / 0xffff;
	right = right * 0x7f / 0xffff;

	*plff->strong = left;
	*plff->weak = right;
	debug("running with 0x%02x 0x%02x", left, right);
	usbhid_submit_report(hid, plff->report, USB_DIR_OUT);

	return 0;
}
Beispiel #24
0
static int zpff_init(struct hid_device *hid)
{
	struct zpff_device *zpff;
	struct hid_report *report;
	struct hid_input *hidinput = list_entry(hid->inputs.next,
						struct hid_input, list);
	struct input_dev *dev = hidinput->input;
	int i, error;

	for (i = 0; i < 4; i++) {
		report = hid_validate_values(hid, HID_OUTPUT_REPORT, 0, i, 1);
		if (!report)
			return -ENODEV;
	}

	zpff = kzalloc(sizeof(struct zpff_device), GFP_KERNEL);
	if (!zpff)
		return -ENOMEM;

	set_bit(FF_RUMBLE, dev->ffbit);

	error = input_ff_create_memless(dev, zpff, zpff_play);
	if (error) {
		kfree(zpff);
		return error;
	}

	zpff->report = report;
	zpff->report->field[0]->value[0] = 0x00;
	zpff->report->field[1]->value[0] = 0x02;
	zpff->report->field[2]->value[0] = 0x00;
	zpff->report->field[3]->value[0] = 0x00;
	usbhid_submit_report(hid, zpff->report, USB_DIR_OUT);

	dev_info(&hid->dev, "force feedback for Zeroplus based devices by "
	       "Anssi Hannula <*****@*****.**>\n");

	return 0;
}
Beispiel #25
0
static int mosart_probe(struct hid_device *hdev, const struct hid_device_id *id)
{
    int ret;
    struct mosart_data *td;


    td = kmalloc(sizeof(struct mosart_data), GFP_KERNEL);
    if (!td) {
        hid_err(hdev, "cannot allocate MosArt data\n");
        return -ENOMEM;
    }
    td->valid = false;
    td->activity = false;
    td->activity_now = false;
    td->first = false;
    hid_set_drvdata(hdev, td);

    /* currently, it's better to have one evdev device only */
#if 0
    hdev->quirks |= HID_QUIRK_MULTI_INPUT;
#endif

    ret = hid_parse(hdev);
    if (ret == 0)
        ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);

    if (ret == 0) {
        struct hid_report_enum *re = hdev->report_enum
                                         + HID_FEATURE_REPORT;
        struct hid_report *r = re->report_id_hash[7];

        r->field[0]->value[0] = 0x02;
        usbhid_submit_report(hdev, r, USB_DIR_OUT);
    } else
        kfree(td);

    return ret;
}
Beispiel #26
0
static int emsff_play(struct input_dev *dev, void *data,
			 struct ff_effect *effect)
{
	struct hid_device *hid = input_get_drvdata(dev);
	struct emsff_device *emsff = data;
	int weak, strong;

	weak = effect->u.rumble.weak_magnitude;
	strong = effect->u.rumble.strong_magnitude;

	dbg_hid("called with 0x%04x 0x%04x\n", strong, weak);

	weak = weak * 0xff / 0xffff;
	strong = strong * 0xff / 0xffff;

	emsff->report->field[0]->value[1] = weak;
	emsff->report->field[0]->value[2] = strong;

	dbg_hid("running with 0x%02x 0x%02x\n", strong, weak);
	usbhid_submit_report(hid, emsff->report, USB_DIR_OUT);

	return 0;
}
Beispiel #27
0
static int zpff_play(struct input_dev *dev, void *data,
			 struct ff_effect *effect)
{
	struct hid_device *hid = input_get_drvdata(dev);
	struct zpff_device *zpff = data;
	int left, right;

	

	left = effect->u.rumble.strong_magnitude;
	right = effect->u.rumble.weak_magnitude;
	dbg_hid("called with 0x%04x 0x%04x\n", left, right);

	left = left * 0x7f / 0xffff;
	right = right * 0x7f / 0xffff;

	zpff->report->field[2]->value[0] = left;
	zpff->report->field[3]->value[0] = right;
	dbg_hid("running with 0x%02x 0x%02x\n", left, right);
	usbhid_submit_report(hid, zpff->report, USB_DIR_OUT);

	return 0;
}
static int logi_dj_recv_send_report(struct dj_receiver_dev *djrcv_dev,
				    struct dj_report *dj_report)
{
	struct hid_device *hdev = djrcv_dev->hdev;
	struct hid_report *report;
	struct hid_report_enum *output_report_enum;
	u8 *data = (u8 *)(&dj_report->device_index);
	int i;

	output_report_enum = &hdev->report_enum[HID_OUTPUT_REPORT];
	report = output_report_enum->report_id_hash[REPORT_ID_DJ_SHORT];

	if (!report) {
		dev_err(&hdev->dev, "%s: unable to find dj report\n", __func__);
		return -ENODEV;
	}

	for (i = 0; i < report->field[0]->report_count; i++)
		report->field[0]->value[i] = data[i];

	usbhid_submit_report(hdev, report, USB_DIR_OUT);

	return 0;
}
Beispiel #29
0
static int g19_probe(struct hid_device *hdev,
		     const struct hid_device_id *id)
{
        unsigned long irq_flags;
	int error;
	struct g19_data *data;
	int i;
	int led_num;
	struct usb_interface *intf;
	struct usb_device *usbdev;
	struct list_head *feature_report_list =
		&hdev->report_enum[HID_FEATURE_REPORT].report_list;
	struct hid_report *report;
	char *led_name;

	dev_dbg(&hdev->dev, "Logitech G19 HID hardware probe...");

	/* Get the usb device to send the start report on */
	intf = to_usb_interface(hdev->dev.parent);
	usbdev = interface_to_usbdev(intf);

	/*
	 * Let's allocate the g19 data structure, set some reasonable
	 * defaults, and associate it with the device
	 */
	data = kzalloc(sizeof(struct g19_data), GFP_KERNEL);
	if (data == NULL) {
		dev_err(&hdev->dev, "can't allocate space for Logitech G19 device attributes\n");
		error = -ENOMEM;
		goto err_no_cleanup;
	}

	spin_lock_init(&data->lock);

	init_completion(&data->ready);

	data->hdev = hdev;

	data->ep1_urb = usb_alloc_urb(0, GFP_KERNEL);
	if (data->ep1_urb == NULL) {
		dev_err(&hdev->dev, G19_NAME ": ERROR: can't alloc ep1 urb stuff\n");
		error = -ENOMEM;
		goto err_cleanup_data;
	}

	hid_set_drvdata(hdev, data);

	dbg_hid("Preparing to parse " G19_NAME " hid reports\n");

	/* Parse the device reports and start it up */
	error = hid_parse(hdev);
	if (error) {
		dev_err(&hdev->dev, G19_NAME " device report parse failed\n");
		error = -EINVAL;
		goto err_cleanup_ep1_urb;
	}

	error = hid_hw_start(hdev, HID_CONNECT_DEFAULT | HID_CONNECT_HIDINPUT_FORCE);
	if (error) {
		dev_err(&hdev->dev, G19_NAME " hardware start failed\n");
		error = -EINVAL;
		goto err_cleanup_ep1_urb;
	}

	dbg_hid(G19_NAME " claimed: %d\n", hdev->claimed);

	error = hdev->ll_driver->open(hdev);
	if (error) {
		dev_err(&hdev->dev, G19_NAME " failed to open input interrupt pipe for key and joystick events\n");
		error = -EINVAL;
		goto err_cleanup_ep1_urb;
	}

	/* Set up the input device for the key I/O */
	data->input_dev = input_allocate_device();
	if (data->input_dev == NULL) {
		dev_err(&hdev->dev, G19_NAME " error initializing the input device");
		error = -ENOMEM;
		goto err_cleanup_ep1_urb;
	}

	input_set_drvdata(data->input_dev, hdev);

	data->input_dev->name = G19_NAME;
	data->input_dev->phys = hdev->phys;
	data->input_dev->uniq = hdev->uniq;
	data->input_dev->id.bustype = hdev->bus;
	data->input_dev->id.vendor = hdev->vendor;
	data->input_dev->id.product = hdev->product;
	data->input_dev->id.version = hdev->version;
	data->input_dev->dev.parent = hdev->dev.parent;
	data->input_dev->keycode = data->keycode;
	data->input_dev->keycodemax = G19_KEYMAP_SIZE;
	data->input_dev->keycodesize = sizeof(int);
	data->input_dev->setkeycode = g19_input_setkeycode;
	data->input_dev->getkeycode = g19_input_getkeycode;

	input_set_capability(data->input_dev, EV_KEY, KEY_UNKNOWN);
	data->input_dev->evbit[0] |= BIT_MASK(EV_REP);

	g19_initialize_keymap(data);

	error = input_register_device(data->input_dev);
	if (error) {
		dev_err(&hdev->dev, G19_NAME " error registering the input device");
		error = -EINVAL;
		goto err_cleanup_input_dev;
	}

	if (list_empty(feature_report_list)) {
		dev_err(&hdev->dev, "no feature report found\n");
		error = -ENODEV;
		goto err_cleanup_input_dev_reg;
	}
	dbg_hid(G19_NAME " feature report found\n");

	list_for_each_entry(report, feature_report_list, list) {
		switch (report->id) {
		case 0x04:
			data->feature_report_4 = report;
			break;
		case 0x05:
			data->led_report = report;
			break;
		case 0x06:
			data->start_input_report = report;
			break;
		case 0x07:
			data->backlight_report = report;
			break;
		default:
			break;
		}
		dbg_hid(G19_NAME " Feature report: id=%u type=%u size=%u maxfield=%u report_count=%u\n",
			report->id, report->type, report->size,
			report->maxfield, report->field[0]->report_count);
	}

	dbg_hid("Found all reports\n");

	/* Create the LED structures */
	for (i = 0; i < LED_COUNT; i++) {
		data->led_cdev[i] = kzalloc(sizeof(struct led_classdev), GFP_KERNEL);
		if (data->led_cdev[i] == NULL) {
			dev_err(&hdev->dev, G19_NAME " error allocating memory for led %d", i);
			error = -ENOMEM;
			goto err_cleanup_led_structs;
		}
		/* Set the accessor functions by copying from template*/
		*(data->led_cdev[i]) = g19_led_cdevs[i];

		/*
		 * Allocate memory for the LED name
		 *
		 * Since led_classdev->name is a const char* we'll use an
		 * intermediate until the name is formatted with sprintf().
		 */
		led_name = kzalloc(sizeof(char)*20, GFP_KERNEL);
		if (led_name == NULL) {
			dev_err(&hdev->dev, G19_NAME " error allocating memory for led %d name", i);
			error = -ENOMEM;
			goto err_cleanup_led_structs;
		}
		switch (i) {
		case G19_LED_M1:
		case G19_LED_M2:
		case G19_LED_M3:
			sprintf(led_name, "g19_%d:orange:m%d", hdev->minor, i+1);
			break;
		case G19_LED_MR:
			sprintf(led_name, "g19_%d:red:mr", hdev->minor);
			break;
		case G19_LED_BL_R:
			sprintf(led_name, "g19_%d:red:bl", hdev->minor);
			break;
		case G19_LED_BL_G:
			sprintf(led_name, "g19_%d:green:bl", hdev->minor);
			break;
		case G19_LED_BL_B:
			sprintf(led_name, "g19_%d:blue:bl", hdev->minor);
			break;
		case G19_LED_BL_SCREEN:
			sprintf(led_name, "g19_%d:white:screen", hdev->minor);
			break;

		}
		data->led_cdev[i]->name = led_name;
	}

	for (i = 0; i < LED_COUNT; i++) {
		led_num = i;
		error = led_classdev_register(&hdev->dev, data->led_cdev[i]);
		if (error < 0) {
			dev_err(&hdev->dev, G19_NAME " error registering led %d", i);
			error = -EINVAL;
			goto err_cleanup_registered_leds;
		}
	}

	data->gfb_data = gfb_probe(hdev, GFB_PANEL_TYPE_320_240_16);
	if (data->gfb_data == NULL) {
		dev_err(&hdev->dev, G19_NAME " error registering framebuffer\n");
		goto err_cleanup_registered_leds;
	}

	dbg_hid("Waiting for G19 to activate\n");

	/* Add the sysfs attributes */
	error = sysfs_create_group(&(hdev->dev.kobj), &g19_attr_group);
	if (error) {
		dev_err(&hdev->dev, G19_NAME " failed to create sysfs group attributes\n");
		goto err_cleanup_registered_leds;
	}

	/*
	 * Wait here for stage 1 (substages 1-3) to complete
	 */
	wait_for_completion_timeout(&data->ready, HZ);

	/* Protect data->ready_stages before checking whether we're ready to proceed */
	spin_lock_irqsave(&data->lock, irq_flags);
	if (data->ready_stages != G19_READY_STAGE_1) {
		dev_warn(&hdev->dev, G19_NAME " hasn't completed stage 1 yet, forging ahead with initialization\n");
		/* Force the stage */
		data->ready_stages = G19_READY_STAGE_1;
	}
	init_completion(&data->ready);
	data->ready_stages |= G19_READY_SUBSTAGE_4;
	spin_unlock_irqrestore(&data->lock, irq_flags);

	/*
	 * Send the init report, then follow with the input report to trigger
	 * report 6 and wait for us to get a response.
	 */
	g19_feature_report_4_send(hdev, G19_REPORT_4_INIT);
	usbhid_submit_report(hdev, data->start_input_report, USB_DIR_IN);
	wait_for_completion_timeout(&data->ready, HZ);

	/* Protect data->ready_stages before checking whether we're ready to proceed */
	spin_lock_irqsave(&data->lock, irq_flags);
	if (data->ready_stages != G19_READY_STAGE_2) {
		dev_warn(&hdev->dev, G19_NAME " hasn't completed stage 2 yet, forging ahead with initialization\n");
		/* Force the stage */
		data->ready_stages = G19_READY_STAGE_2;
	}
	init_completion(&data->ready);
	data->ready_stages |= G19_READY_SUBSTAGE_6;
	spin_unlock_irqrestore(&data->lock, irq_flags);

	/*
	 * Clear the LEDs
	 */
	g19_led_send(hdev);

	data->rgb[0] = G19_DEFAULT_RED;
	data->rgb[1] = G19_DEFAULT_GREEN;
	data->rgb[2] = G19_DEFAULT_BLUE;
	g19_rgb_send(hdev);

	data->screen_bl = G19_DEFAULT_BRIGHTNESS;
	g19_screen_bl_send(hdev);

	/*
	 * Send the finalize report, then follow with the input report to trigger
	 * report 6 and wait for us to get a response.
	 */
	g19_feature_report_4_send(hdev, G19_REPORT_4_FINALIZE);
	usbhid_submit_report(hdev, data->start_input_report, USB_DIR_IN);
	usbhid_submit_report(hdev, data->start_input_report, USB_DIR_IN);
	wait_for_completion_timeout(&data->ready, HZ);

	/* Protect data->ready_stages before checking whether we're ready to proceed */
	spin_lock_irqsave(&data->lock, irq_flags);

	if (data->ready_stages != G19_READY_STAGE_3) {
		dev_warn(&hdev->dev, G19_NAME " hasn't completed stage 3 yet, forging ahead with initialization\n");
		/* Force the stage */
		data->ready_stages = G19_READY_STAGE_3;
	} else {
		dbg_hid(G19_NAME " stage 3 complete\n");
	}

	spin_unlock_irqrestore(&data->lock, irq_flags);

	g19_set_keymap_switching(hdev, 1);

	g19_ep1_read(hdev);

	dbg_hid("G19 activated and initialized\n");

	/* Everything went well */
	return 0;

err_cleanup_registered_leds:
	for (i = 0; i < led_num; i++)
		led_classdev_unregister(data->led_cdev[i]);

err_cleanup_led_structs:
	for (i = 0; i < LED_COUNT; i++) {
		if (data->led_cdev[i] != NULL) {
			if (data->led_cdev[i]->name != NULL)
				kfree(data->led_cdev[i]->name);
			kfree(data->led_cdev[i]);
		}
	}

err_cleanup_input_dev_reg:
	input_unregister_device(data->input_dev);

err_cleanup_input_dev:
	input_free_device(data->input_dev);

err_cleanup_ep1_urb:
	usb_free_urb(data->ep1_urb);



err_cleanup_data:
	/* Make sure we clean up the allocated data structure */
	kfree(data);

err_no_cleanup:

	hid_set_drvdata(hdev, NULL);

	return error;
}
Beispiel #30
0
static int g19_input_get_keycode(struct input_dev * dev,
                                 unsigned int scancode,
                                 unsigned int * keycode)
{
	int retval;
	
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)
	
	struct input_keymap_entry ke = {
		.flags    = 0,
		.len      = sizeof(scancode),
		.index    = scancode,
		.scancode = { scancode },
	};
	
	retval   = input_get_keycode(dev, &ke);
	*keycode = ke.keycode;
	
#else
	
	retval   = input_get_keycode(dev, scancode, keycode);
	
#endif
	
	return retval;
}

static void g19_led_send(struct hid_device *hdev)
{
	struct g19_data *data = hid_get_g19data(hdev);

	data->led_report->field[0]->value[0] = data->led&0xFF;

	usbhid_submit_report(hdev, data->led_report, USB_DIR_OUT);
}

static void g19_screen_bl_send(struct hid_device *hdev)
{
	struct usb_interface *intf;
	struct usb_device *usb_dev;
	struct g19_data *data = hid_get_g19data(hdev);
	unsigned int pipe;
	int i = 0;

	unsigned char cp[9];
	cp[0] = data->screen_bl;
	cp[1] = 0xe2;
	cp[2] = 0x12;
	cp[3] = 0x00;
	cp[4] = 0x8c;
	cp[5] = 0x11;
	cp[6] = 0x00;
	cp[7] = 0x10;
	cp[8] = 0x00;

	intf = to_usb_interface(hdev->dev.parent);
	usb_dev = interface_to_usbdev(intf);
	pipe = usb_sndctrlpipe(usb_dev, 0x00);
	i = usb_control_msg(usb_dev, pipe, 0x0a,
			USB_TYPE_VENDOR | USB_RECIP_INTERFACE, 0, 0, cp, sizeof(cp),
			1 * HZ);
	if (i < 0) {
		dev_warn(&hdev->dev, G19_NAME " error setting LCD backlight level %d\n",
				i);
	}
}

static void g19_rgb_send(struct hid_device *hdev)
{
	struct g19_data *data = hid_get_g19data(hdev);

	data->backlight_report->field[0]->value[0] = data->rgb[0];
	data->backlight_report->field[0]->value[1] = data->rgb[1];
	data->backlight_report->field[0]->value[2] = data->rgb[2];

	usbhid_submit_report(hdev, data->backlight_report, USB_DIR_OUT);
}

static void g19_led_set(struct led_classdev *led_cdev,
			 enum led_brightness value,
			 int led_num)
{
	struct device *dev;
	struct hid_device *hdev;
	struct g19_data *data;
	u8 mask;

	/* Get the device associated with the led */
	dev = led_cdev->dev->parent;

	/* Get the hid associated with the device */
	hdev = container_of(dev, struct hid_device, dev);

	/* Get the underlying data value */
	data = hid_get_g19data(hdev);

	mask = 0x80>>led_num;
	if (value)
		data->led |= mask;
	else
		data->led &= ~mask;

	g19_led_send(hdev);
}

static void g19_led_m1_brightness_set(struct led_classdev *led_cdev,
				      enum led_brightness value)
{
	g19_led_set(led_cdev, value, G19_LED_M1);
}