root/drivers/hid/hid-lg2ff.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. play_effect
  2. lg2ff_init

   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 
  18 struct lg2ff_device {
  19         struct hid_report *report;
  20 };
  21 
  22 static 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 
  49 int 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 }

/* [<][>][^][v][top][bottom][index][help] */