cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

hid-lg2ff.c (2241B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 *  Force feedback support for Logitech RumblePad and Rumblepad 2
      4 *
      5 *  Copyright (c) 2008 Anssi Hannula <anssi.hannula@gmail.com>
      6 */
      7
      8/*
      9 */
     10
     11
     12#include <linux/input.h>
     13#include <linux/slab.h>
     14#include <linux/hid.h>
     15
     16#include "hid-lg.h"
     17
     18struct lg2ff_device {
     19	struct hid_report *report;
     20};
     21
     22static int play_effect(struct input_dev *dev, void *data,
     23			 struct ff_effect *effect)
     24{
     25	struct hid_device *hid = input_get_drvdata(dev);
     26	struct lg2ff_device *lg2ff = data;
     27	int weak, strong;
     28
     29	strong = effect->u.rumble.strong_magnitude;
     30	weak = effect->u.rumble.weak_magnitude;
     31
     32	if (weak || strong) {
     33		weak = weak * 0xff / 0xffff;
     34		strong = strong * 0xff / 0xffff;
     35
     36		lg2ff->report->field[0]->value[0] = 0x51;
     37		lg2ff->report->field[0]->value[2] = weak;
     38		lg2ff->report->field[0]->value[4] = strong;
     39	} else {
     40		lg2ff->report->field[0]->value[0] = 0xf3;
     41		lg2ff->report->field[0]->value[2] = 0x00;
     42		lg2ff->report->field[0]->value[4] = 0x00;
     43	}
     44
     45	hid_hw_request(hid, lg2ff->report, HID_REQ_SET_REPORT);
     46	return 0;
     47}
     48
     49int lg2ff_init(struct hid_device *hid)
     50{
     51	struct lg2ff_device *lg2ff;
     52	struct hid_report *report;
     53	struct hid_input *hidinput;
     54	struct input_dev *dev;
     55	int error;
     56
     57	if (list_empty(&hid->inputs)) {
     58		hid_err(hid, "no inputs found\n");
     59		return -ENODEV;
     60	}
     61	hidinput = list_entry(hid->inputs.next, struct hid_input, list);
     62	dev = hidinput->input;
     63
     64	/* Check that the report looks ok */
     65	report = hid_validate_values(hid, HID_OUTPUT_REPORT, 0, 0, 7);
     66	if (!report)
     67		return -ENODEV;
     68
     69	lg2ff = kmalloc(sizeof(struct lg2ff_device), GFP_KERNEL);
     70	if (!lg2ff)
     71		return -ENOMEM;
     72
     73	set_bit(FF_RUMBLE, dev->ffbit);
     74
     75	error = input_ff_create_memless(dev, lg2ff, play_effect);
     76	if (error) {
     77		kfree(lg2ff);
     78		return error;
     79	}
     80
     81	lg2ff->report = report;
     82	report->field[0]->value[0] = 0xf3;
     83	report->field[0]->value[1] = 0x00;
     84	report->field[0]->value[2] = 0x00;
     85	report->field[0]->value[3] = 0x00;
     86	report->field[0]->value[4] = 0x00;
     87	report->field[0]->value[5] = 0x00;
     88	report->field[0]->value[6] = 0x00;
     89
     90	hid_hw_request(hid, report, HID_REQ_SET_REPORT);
     91
     92	hid_info(hid, "Force feedback for Logitech variant 2 rumble devices by Anssi Hannula <anssi.hannula@gmail.com>\n");
     93
     94	return 0;
     95}