summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/hid/Kconfig21
-rw-r--r--drivers/hid/Makefile21
-rw-r--r--drivers/hid/hid-core.c3
-rw-r--r--drivers/hid/hid-ids.h6
-rw-r--r--drivers/hid/hid-input.c11
-rw-r--r--drivers/hid/hid-lg.c9
-rw-r--r--drivers/hid/hid-lg.h4
-rw-r--r--drivers/hid/hid-lg4ff.c194
-rw-r--r--drivers/hid/hid-magicmouse.c2
-rw-r--r--drivers/hid/hid-multitouch.c185
-rw-r--r--drivers/hid/hid-picolcd.c2748
-rw-r--r--drivers/hid/hid-picolcd.h309
-rw-r--r--drivers/hid/hid-picolcd_backlight.c122
-rw-r--r--drivers/hid/hid-picolcd_cir.c152
-rw-r--r--drivers/hid/hid-picolcd_core.c689
-rw-r--r--drivers/hid/hid-picolcd_debugfs.c899
-rw-r--r--drivers/hid/hid-picolcd_fb.c615
-rw-r--r--drivers/hid/hid-picolcd_lcd.c107
-rw-r--r--drivers/hid/hid-picolcd_leds.c175
-rw-r--r--drivers/hid/hid-ps3remote.c215
-rw-r--r--drivers/hid/hid-uclogic.c98
-rw-r--r--drivers/hid/hid-wacom.c169
-rw-r--r--drivers/hid/hid-wiimote-ext.c97
-rw-r--r--drivers/input/evdev.c78
-rw-r--r--drivers/input/input-mt.c305
-rw-r--r--drivers/input/input.c254
-rw-r--r--drivers/input/misc/uinput.c2
-rw-r--r--drivers/input/mouse/alps.c2
-rw-r--r--drivers/input/mouse/bcm5974.c348
-rw-r--r--drivers/input/mouse/elantech.c4
-rw-r--r--drivers/input/mouse/sentelic.c2
-rw-r--r--drivers/input/mouse/synaptics.c4
-rw-r--r--drivers/input/tablet/wacom_wac.c6
-rw-r--r--drivers/input/touchscreen/atmel_mxt_ts.c2
-rw-r--r--drivers/input/touchscreen/cyttsp_core.c2
-rw-r--r--drivers/input/touchscreen/edt-ft5x06.c2
-rw-r--r--drivers/input/touchscreen/egalax_ts.c2
-rw-r--r--drivers/input/touchscreen/ili210x.c2
-rw-r--r--drivers/input/touchscreen/mms114.c2
-rw-r--r--drivers/input/touchscreen/penmount.c2
-rw-r--r--drivers/input/touchscreen/wacom_w8001.c2
41 files changed, 4599 insertions, 3273 deletions
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
index fbf49503508d..bf0617e47b89 100644
--- a/drivers/hid/Kconfig
+++ b/drivers/hid/Kconfig
@@ -527,6 +527,14 @@ config HID_PICOLCD_LEDS
---help---
Provide access to PicoLCD's GPO pins via leds class.
+config HID_PICOLCD_CIR
+ bool "CIR via RC class" if EXPERT
+ default !EXPERT
+ depends on HID_PICOLCD
+ depends on HID_PICOLCD=RC_CORE || RC_CORE=y
+ ---help---
+ Provide access to PicoLCD's CIR interface via remote control (LIRC).
+
config HID_PRIMAX
tristate "Primax non-fully HID-compliant devices"
depends on USB_HID
@@ -534,6 +542,15 @@ config HID_PRIMAX
Support for Primax devices that are not fully compliant with the
HID standard.
+config HID_PS3REMOTE
+ tristate "Sony PS3 BD Remote Control"
+ depends on BT_HIDP
+ ---help---
+ Support for the Sony PS3 Blue-ray Disk Remote Control and Logitech
+ Harmony Adapter for PS3, which connect over Bluetooth.
+
+ Support for the 6-axis controllers is provided by HID_SONY.
+
config HID_ROCCAT
tristate "Roccat device support"
depends on USB_HID
@@ -561,7 +578,9 @@ config HID_SONY
tristate "Sony PS3 controller"
depends on USB_HID
---help---
- Support for Sony PS3 controller.
+ Support for Sony PS3 6-axis controllers.
+
+ Support for the Sony PS3 BD Remote is provided by HID_PS3REMOTE.
config HID_SPEEDLINK
tristate "Speedlink VAD Cezanne mouse support"
diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile
index f975485f88b2..5a3690ff9bf2 100644
--- a/drivers/hid/Makefile
+++ b/drivers/hid/Makefile
@@ -69,7 +69,28 @@ obj-$(CONFIG_HID_PRODIKEYS) += hid-prodikeys.o
obj-$(CONFIG_HID_PANTHERLORD) += hid-pl.o
obj-$(CONFIG_HID_PETALYNX) += hid-petalynx.o
obj-$(CONFIG_HID_PICOLCD) += hid-picolcd.o
+hid-picolcd-y += hid-picolcd_core.o
+ifdef CONFIG_HID_PICOLCD_FB
+hid-picolcd-y += hid-picolcd_fb.o
+endif
+ifdef CONFIG_HID_PICOLCD_BACKLIGHT
+hid-picolcd-y += hid-picolcd_backlight.o
+endif
+ifdef CONFIG_HID_PICOLCD_LCD
+hid-picolcd-y += hid-picolcd_lcd.o
+endif
+ifdef CONFIG_HID_PICOLCD_LEDS
+hid-picolcd-y += hid-picolcd_leds.o
+endif
+ifdef CONFIG_HID_PICOLCD_CIR
+hid-picolcd-y += hid-picolcd_cir.o
+endif
+ifdef CONFIG_DEBUG_FS
+hid-picolcd-y += hid-picolcd_debugfs.o
+endif
+
obj-$(CONFIG_HID_PRIMAX) += hid-primax.o
+obj-$(CONFIG_HID_PS3REMOTE) += hid-ps3remote.o
obj-$(CONFIG_HID_ROCCAT) += hid-roccat.o hid-roccat-common.o \
hid-roccat-arvo.o hid-roccat-isku.o hid-roccat-kone.o \
hid-roccat-koneplus.o hid-roccat-kovaplus.o hid-roccat-pyra.o \
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 8bcd168fffae..9072e0ed1876 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -1566,6 +1566,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER) },
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER_2) },
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RECEIVER) },
+ { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_PS3) },
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_DESKTOP) },
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_EDGE) },
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_MINI) },
@@ -1639,6 +1640,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE) },
{ HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE) },
{ HID_USB_DEVICE(USB_VENDOR_ID_SKYCABLE, USB_DEVICE_ID_SKYCABLE_WIRELESS_PRESENTER) },
+ { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_BDREMOTE) },
{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) },
{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_NAVIGATION_CONTROLLER) },
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) },
@@ -1663,6 +1665,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP8060U) },
{ HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP1062) },
{ HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_WIRELESS_TABLET_TWHL850) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_TWHA60) },
{ HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_SMARTJOY_PLUS) },
{ HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_SUPER_JOY_BOX_3) },
{ HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_DUAL_USB_JOYPAD) },
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index 1dcb76ff51e3..a534375fdf2e 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -283,6 +283,9 @@
#define USB_VENDOR_ID_EMS 0x2006
#define USB_DEVICE_ID_EMS_TRIO_LINKER_PLUS_II 0x0118
+#define USB_VENDOR_ID_FLATFROG 0x25b5
+#define USB_DEVICE_ID_MULTITOUCH_3200 0x0002
+
#define USB_VENDOR_ID_ESSENTIAL_REALITY 0x0d7f
#define USB_DEVICE_ID_ESSENTIAL_REALITY_P5 0x0100
@@ -496,6 +499,7 @@
#define USB_DEVICE_ID_LOGITECH_RECEIVER 0xc101
#define USB_DEVICE_ID_LOGITECH_HARMONY_FIRST 0xc110
#define USB_DEVICE_ID_LOGITECH_HARMONY_LAST 0xc14f
+#define USB_DEVICE_ID_LOGITECH_HARMONY_PS3 0x0306
#define USB_DEVICE_ID_LOGITECH_RUMBLEPAD_CORD 0xc20a
#define USB_DEVICE_ID_LOGITECH_RUMBLEPAD 0xc211
#define USB_DEVICE_ID_LOGITECH_EXTREME_3D 0xc215
@@ -683,6 +687,7 @@
#define USB_VENDOR_ID_SONY 0x054c
#define USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE 0x024b
+#define USB_DEVICE_ID_SONY_PS3_BDREMOTE 0x0306
#define USB_DEVICE_ID_SONY_PS3_CONTROLLER 0x0268
#define USB_DEVICE_ID_SONY_NAVIGATION_CONTROLLER 0x042f
@@ -758,6 +763,7 @@
#define USB_DEVICE_ID_UCLOGIC_TABLET_WP8060U 0x0005
#define USB_DEVICE_ID_UCLOGIC_TABLET_WP1062 0x0064
#define USB_DEVICE_ID_UCLOGIC_WIRELESS_TABLET_TWHL850 0x0522
+#define USB_DEVICE_ID_UCLOGIC_TABLET_TWHA60 0x0781
#define USB_VENDOR_ID_UNITEC 0x227d
#define USB_DEVICE_ID_UNITEC_USB_TOUCH_0709 0x0709
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
index 811bfad64609..d917c0d53685 100644
--- a/drivers/hid/hid-input.c
+++ b/drivers/hid/hid-input.c
@@ -1154,6 +1154,7 @@ static void report_features(struct hid_device *hid)
int hidinput_connect(struct hid_device *hid, unsigned int force)
{
+ struct hid_driver *drv = hid->driver;
struct hid_report *report;
struct hid_input *hidinput = NULL;
struct input_dev *input_dev;
@@ -1228,6 +1229,8 @@ int hidinput_connect(struct hid_device *hid, unsigned int force)
* UGCI) cram a lot of unrelated inputs into the
* same interface. */
hidinput->report = report;
+ if (drv->input_configured)
+ drv->input_configured(hid, hidinput);
if (input_register_device(hidinput->input))
goto out_cleanup;
hidinput = NULL;
@@ -1235,8 +1238,12 @@ int hidinput_connect(struct hid_device *hid, unsigned int force)
}
}
- if (hidinput && input_register_device(hidinput->input))
- goto out_cleanup;
+ if (hidinput) {
+ if (drv->input_configured)
+ drv->input_configured(hid, hidinput);
+ if (input_register_device(hidinput->input))
+ goto out_cleanup;
+ }
return 0;
diff --git a/drivers/hid/hid-lg.c b/drivers/hid/hid-lg.c
index fc37ed6b108c..afc4de389f81 100644
--- a/drivers/hid/hid-lg.c
+++ b/drivers/hid/hid-lg.c
@@ -342,6 +342,9 @@ static int lg_event(struct hid_device *hdev, struct hid_field *field,
-value);
return 1;
}
+ if (drv_data->quirks & LG_FF4) {
+ return lg4ff_adjust_input_event(hdev, field, usage, value, drv_data);
+ }
return 0;
}
@@ -358,7 +361,7 @@ static int lg_probe(struct hid_device *hdev, const struct hid_device_id *id)
return -ENOMEM;
}
drv_data->quirks = id->driver_data;
-
+
hid_set_drvdata(hdev, (void *)drv_data);
if (drv_data->quirks & LG_NOGET)
@@ -380,7 +383,7 @@ static int lg_probe(struct hid_device *hdev, const struct hid_device_id *id)
}
/* Setup wireless link with Logitech Wii wheel */
- if(hdev->product == USB_DEVICE_ID_LOGITECH_WII_WHEEL) {
+ if (hdev->product == USB_DEVICE_ID_LOGITECH_WII_WHEEL) {
unsigned char buf[] = { 0x00, 0xAF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
ret = hdev->hid_output_raw_report(hdev, buf, sizeof(buf), HID_FEATURE_REPORT);
@@ -476,7 +479,7 @@ static const struct hid_device_id lg_devices[] = {
.driver_data = LG_NOGET | LG_FF4 },
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WII_WHEEL),
.driver_data = LG_FF4 },
- { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_FFG ),
+ { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_FFG),
.driver_data = LG_FF },
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2),
.driver_data = LG_FF2 },
diff --git a/drivers/hid/hid-lg.h b/drivers/hid/hid-lg.h
index d64cf8d2751e..142ce3f5f055 100644
--- a/drivers/hid/hid-lg.h
+++ b/drivers/hid/hid-lg.h
@@ -25,9 +25,13 @@ static inline int lg3ff_init(struct hid_device *hdev) { return -1; }
#endif
#ifdef CONFIG_LOGIWHEELS_FF
+int lg4ff_adjust_input_event(struct hid_device *hid, struct hid_field *field,
+ struct hid_usage *usage, __s32 value, struct lg_drv_data *drv_data);
int lg4ff_init(struct hid_device *hdev);
int lg4ff_deinit(struct hid_device *hdev);
#else
+static inline int lg4ff_adjust_input_event(struct hid_device *hid, struct hid_field *field,
+ struct hid_usage *usage, __s32 value, struct lg_drv_data *drv_data) { return 0; }
static inline int lg4ff_init(struct hid_device *hdev) { return -1; }
static inline int lg4ff_deinit(struct hid_device *hdev) { return -1; }
#endif
diff --git a/drivers/hid/hid-lg4ff.c b/drivers/hid/hid-lg4ff.c
index f3390ee6105c..4fb4a80928c8 100644
--- a/drivers/hid/hid-lg4ff.c
+++ b/drivers/hid/hid-lg4ff.c
@@ -43,6 +43,11 @@
#define G27_REV_MAJ 0x12
#define G27_REV_MIN 0x38
+#define DFP_X_MIN 0
+#define DFP_X_MAX 16383
+#define DFP_PEDAL_MIN 0
+#define DFP_PEDAL_MAX 255
+
#define to_hid_device(pdev) container_of(pdev, struct hid_device, dev)
static void hid_lg4ff_set_range_dfp(struct hid_device *hid, u16 range);
@@ -53,6 +58,7 @@ static ssize_t lg4ff_range_store(struct device *dev, struct device_attribute *at
static DEVICE_ATTR(range, S_IRWXU | S_IRWXG | S_IRWXO, lg4ff_range_show, lg4ff_range_store);
struct lg4ff_device_entry {
+ __u32 product_id;
__u16 range;
__u16 min_range;
__u16 max_range;
@@ -129,26 +135,77 @@ static const struct lg4ff_usb_revision lg4ff_revs[] = {
{G27_REV_MAJ, G27_REV_MIN, &native_g27}, /* G27 */
};
+/* Recalculates X axis value accordingly to currently selected range */
+static __s32 lg4ff_adjust_dfp_x_axis(__s32 value, __u16 range)
+{
+ __u16 max_range;
+ __s32 new_value;
+
+ if (range == 900)
+ return value;
+ else if (range == 200)
+ return value;
+ else if (range < 200)
+ max_range = 200;
+ else
+ max_range = 900;
+
+ new_value = 8192 + mult_frac(value - 8192, max_range, range);
+ if (new_value < 0)
+ return 0;
+ else if (new_value > 16383)
+ return 16383;
+ else
+ return new_value;
+}
+
+int lg4ff_adjust_input_event(struct hid_device *hid, struct hid_field *field,
+ struct hid_usage *usage, __s32 value, struct lg_drv_data *drv_data)
+{
+ struct lg4ff_device_entry *entry = drv_data->device_props;
+ __s32 new_value = 0;
+
+ if (!entry) {
+ hid_err(hid, "Device properties not found");
+ return 0;
+ }
+
+ switch (entry->product_id) {
+ case USB_DEVICE_ID_LOGITECH_DFP_WHEEL:
+ switch (usage->code) {
+ case ABS_X:
+ new_value = lg4ff_adjust_dfp_x_axis(value, entry->range);
+ input_event(field->hidinput->input, usage->type, usage->code, new_value);
+ return 1;
+ default:
+ return 0;
+ }
+ default:
+ return 0;
+ }
+}
+
static int hid_lg4ff_play(struct input_dev *dev, void *data, struct ff_effect *effect)
{
struct hid_device *hid = input_get_drvdata(dev);
struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list;
struct hid_report *report = list_entry(report_list->next, struct hid_report, list);
+ __s32 *value = report->field[0]->value;
int x;
-#define CLAMP(x) if (x < 0) x = 0; if (x > 0xff) x = 0xff
+#define CLAMP(x) do { if (x < 0) x = 0; else if (x > 0xff) x = 0xff; } while (0)
switch (effect->type) {
case FF_CONSTANT:
x = effect->u.ramp.start_level + 0x80; /* 0x80 is no force */
CLAMP(x);
- report->field[0]->value[0] = 0x11; /* Slot 1 */
- report->field[0]->value[1] = 0x08;
- report->field[0]->value[2] = x;
- report->field[0]->value[3] = 0x80;
- report->field[0]->value[4] = 0x00;
- report->field[0]->value[5] = 0x00;
- report->field[0]->value[6] = 0x00;
+ value[0] = 0x11; /* Slot 1 */
+ value[1] = 0x08;
+ value[2] = x;
+ value[3] = 0x80;
+ value[4] = 0x00;
+ value[5] = 0x00;
+ value[6] = 0x00;
usbhid_submit_report(hid, report, USB_DIR_OUT);
break;
@@ -163,14 +220,15 @@ static void hid_lg4ff_set_autocenter_default(struct input_dev *dev, u16 magnitud
struct hid_device *hid = input_get_drvdata(dev);
struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list;
struct hid_report *report = list_entry(report_list->next, struct hid_report, list);
+ __s32 *value = report->field[0]->value;
- report->field[0]->value[0] = 0xfe;
- report->field[0]->value[1] = 0x0d;
- report->field[0]->value[2] = magnitude >> 13;
- report->field[0]->value[3] = magnitude >> 13;
- report->field[0]->value[4] = magnitude >> 8;
- report->field[0]->value[5] = 0x00;
- report->field[0]->value[6] = 0x00;
+ value[0] = 0xfe;
+ value[1] = 0x0d;
+ value[2] = magnitude >> 13;
+ value[3] = magnitude >> 13;
+ value[4] = magnitude >> 8;
+ value[5] = 0x00;
+ value[6] = 0x00;
usbhid_submit_report(hid, report, USB_DIR_OUT);
}
@@ -181,16 +239,16 @@ static void hid_lg4ff_set_autocenter_ffex(struct input_dev *dev, u16 magnitude)
struct hid_device *hid = input_get_drvdata(dev);
struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list;
struct hid_report *report = list_entry(report_list->next, struct hid_report, list);
+ __s32 *value = report->field[0]->value;
magnitude = magnitude * 90 / 65535;
-
- report->field[0]->value[0] = 0xfe;
- report->field[0]->value[1] = 0x03;
- report->field[0]->value[2] = magnitude >> 14;
- report->field[0]->value[3] = magnitude >> 14;
- report->field[0]->value[4] = magnitude;
- report->field[0]->value[5] = 0x00;
- report->field[0]->value[6] = 0x00;
+ value[0] = 0xfe;
+ value[1] = 0x03;
+ value[2] = magnitude >> 14;
+ value[3] = magnitude >> 14;
+ value[4] = magnitude;
+ value[5] = 0x00;
+ value[6] = 0x00;
usbhid_submit_report(hid, report, USB_DIR_OUT);
}
@@ -200,15 +258,17 @@ static void hid_lg4ff_set_range_g25(struct hid_device *hid, u16 range)
{
struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list;
struct hid_report *report = list_entry(report_list->next, struct hid_report, list);
+ __s32 *value = report->field[0]->value;
+
dbg_hid("G25/G27/DFGT: setting range to %u\n", range);
- report->field[0]->value[0] = 0xf8;
- report->field[0]->value[1] = 0x81;
- report->field[0]->value[2] = range & 0x00ff;
- report->field[0]->value[3] = (range & 0xff00) >> 8;
- report->field[0]->value[4] = 0x00;
- report->field[0]->value[5] = 0x00;
- report->field[0]->value[6] = 0x00;
+ value[0] = 0xf8;
+ value[1] = 0x81;
+ value[2] = range & 0x00ff;
+ value[3] = (range & 0xff00) >> 8;
+ value[4] = 0x00;
+ value[5] = 0x00;
+ value[6] = 0x00;
usbhid_submit_report(hid, report, USB_DIR_OUT);
}
@@ -219,16 +279,18 @@ static void hid_lg4ff_set_range_dfp(struct hid_device *hid, __u16 range)
struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list;
struct hid_report *report = list_entry(report_list->next, struct hid_report, list);
int start_left, start_right, full_range;
+ __s32 *value = report->field[0]->value;
+
dbg_hid("Driving Force Pro: setting range to %u\n", range);
/* Prepare "coarse" limit command */
- report->field[0]->value[0] = 0xf8;
- report->field[0]->value[1] = 0x00; /* Set later */
- 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;
+ value[0] = 0xf8;
+ value[1] = 0x00; /* Set later */
+ value[2] = 0x00;
+ value[3] = 0x00;
+ value[4] = 0x00;
+ value[5] = 0x00;
+ value[6] = 0x00;
if (range > 200) {
report->field[0]->value[1] = 0x03;
@@ -240,13 +302,13 @@ static void hid_lg4ff_set_range_dfp(struct hid_device *hid, __u16 range)
usbhid_submit_report(hid, report, USB_DIR_OUT);
/* Prepare "fine" limit command */
- report->field[0]->value[0] = 0x81;
- report->field[0]->value[1] = 0x0b;
- 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;
+ value[0] = 0x81;
+ value[1] = 0x0b;
+ value[2] = 0x00;
+ value[3] = 0x00;
+ value[4] = 0x00;
+ value[5] = 0x00;
+ value[6] = 0x00;
if (range == 200 || range == 900) { /* Do not apply any fine limit */
usbhid_submit_report(hid, report, USB_DIR_OUT);
@@ -257,11 +319,11 @@ static void hid_lg4ff_set_range_dfp(struct hid_device *hid, __u16 range)
start_left = (((full_range - range + 1) * 2047) / full_range);
start_right = 0xfff - start_left;
- report->field[0]->value[2] = start_left >> 4;
- report->field[0]->value[3] = start_right >> 4;
- report->field[0]->value[4] = 0xff;
- report->field[0]->value[5] = (start_right & 0xe) << 4 | (start_left & 0xe);
- report->field[0]->value[6] = 0xff;
+ value[2] = start_left >> 4;
+ value[3] = start_right >> 4;
+ value[4] = 0xff;
+ value[5] = (start_right & 0xe) << 4 | (start_left & 0xe);
+ value[6] = 0xff;
usbhid_submit_report(hid, report, USB_DIR_OUT);
}
@@ -344,14 +406,15 @@ static void lg4ff_set_leds(struct hid_device *hid, __u8 leds)
{
struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list;
struct hid_report *report = list_entry(report_list->next, struct hid_report, list);
-
- report->field[0]->value[0] = 0xf8;
- report->field[0]->value[1] = 0x12;
- report->field[0]->value[2] = leds;
- report->field[0]->value[3] = 0x00;
- report->field[0]->value[4] = 0x00;
- report->field[0]->value[5] = 0x00;
- report->field[0]->value[6] = 0x00;
+ __s32 *value = report->field[0]->value;
+
+ value[0] = 0xf8;
+ value[1] = 0x12;
+ value[2] = leds;
+ value[3] = 0x00;
+ value[4] = 0x00;
+ value[5] = 0x00;
+ value[6] = 0x00;
usbhid_submit_report(hid, report, USB_DIR_OUT);
}
@@ -501,7 +564,7 @@ int lg4ff_init(struct hid_device *hid)
/* Check if autocentering is available and
* set the centering force to zero by default */
if (test_bit(FF_AUTOCENTER, dev->ffbit)) {
- if(rev_maj == FFEX_REV_MAJ && rev_min == FFEX_REV_MIN) /* Formula Force EX expects different autocentering command */
+ if (rev_maj == FFEX_REV_MAJ && rev_min == FFEX_REV_MIN) /* Formula Force EX expects different autocentering command */
dev->ff->set_autocenter = hid_lg4ff_set_autocenter_ffex;
else
dev->ff->set_autocenter = hid_lg4ff_set_autocenter_default;
@@ -524,6 +587,7 @@ int lg4ff_init(struct hid_device *hid)
}
drv_data->device_props = entry;
+ entry->product_id = lg4ff_devices[i].product_id;
entry->min_range = lg4ff_devices[i].min_range;
entry->max_range = lg4ff_devices[i].max_range;
entry->set_range = lg4ff_devices[i].set_range;
@@ -534,6 +598,18 @@ int lg4ff_init(struct hid_device *hid)
return error;
dbg_hid("sysfs interface created\n");
+ /* Set default axes parameters */
+ switch (lg4ff_devices[i].product_id) {
+ case USB_DEVICE_ID_LOGITECH_DFP_WHEEL:
+ dbg_hid("Setting axes parameters for Driving Force Pro\n");
+ input_set_abs_params(dev, ABS_X, DFP_X_MIN, DFP_X_MAX, 0, 0);
+ input_set_abs_params(dev, ABS_Y, DFP_PEDAL_MIN, DFP_PEDAL_MAX, 0, 0);
+ input_set_abs_params(dev, ABS_RZ, DFP_PEDAL_MIN, DFP_PEDAL_MAX, 0, 0);
+ break;
+ default:
+ break;
+ }
+
/* Set the maximum range to start with */
entry->range = entry->max_range;
if (entry->set_range != NULL)
@@ -594,6 +670,8 @@ out:
return 0;
}
+
+
int lg4ff_deinit(struct hid_device *hid)
{
struct lg4ff_device_entry *entry;
diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c
index 73647266daad..25ddf3e3aec6 100644
--- a/drivers/hid/hid-magicmouse.c
+++ b/drivers/hid/hid-magicmouse.c
@@ -392,7 +392,7 @@ static int magicmouse_setup_input(struct input_dev *input, struct hid_device *hd
__set_bit(EV_ABS, input->evbit);
- error = input_mt_init_slots(input, 16);
+ error = input_mt_init_slots(input, 16, 0);
if (error)
return error;
input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, 0, 255 << 2,
diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
index 59c8b5c1d2de..ee0b76b398cb 100644
--- a/drivers/hid/hid-multitouch.c
+++ b/drivers/hid/hid-multitouch.c
@@ -51,12 +51,12 @@ MODULE_LICENSE("GPL");
#define MT_QUIRK_VALID_IS_INRANGE (1 << 5)
#define MT_QUIRK_VALID_IS_CONFIDENCE (1 << 6)
#define MT_QUIRK_SLOT_IS_CONTACTID_MINUS_ONE (1 << 8)
+#define MT_QUIRK_NO_AREA (1 << 9)
struct mt_slot {
__s32 x, y, p, w, h;
__s32 contactid; /* the device ContactID assigned to this slot */
bool touch_state; /* is the touch valid? */
- bool seen_in_this_frame;/* has this slot been updated */
};
struct mt_class {
@@ -92,8 +92,9 @@ struct mt_device {
__u8 touches_by_report; /* how many touches are present in one report:
* 1 means we should use a serial protocol
* > 1 means hybrid (multitouch) protocol */
+ bool serial_maybe; /* need to check for serial protocol */
bool curvalid; /* is the current contact valid? */
- struct mt_slot *slots;
+ unsigned mt_flags; /* flags to pass to input-mt */
};
/* classes of device behavior */
@@ -115,6 +116,7 @@ struct mt_device {
#define MT_CLS_EGALAX_SERIAL 0x0104
#define MT_CLS_TOPSEED 0x0105
#define MT_CLS_PANASONIC 0x0106
+#define MT_CLS_FLATFROG 0x0107
#define MT_DEFAULT_MAXCONTACT 10
@@ -134,25 +136,6 @@ static int cypress_compute_slot(struct mt_device *td)
return -1;
}
-static int find_slot_from_contactid(struct mt_device *td)
-{
- int i;
- for (i = 0; i < td->maxcontacts; ++i) {
- if (td->slots[i].contactid == td->curdata.contactid &&
- td->slots[i].touch_state)
- return i;
- }
- for (i = 0; i < td->maxcontacts; ++i) {
- if (!td->slots[i].seen_in_this_frame &&
- !td->slots[i].touch_state)
- return i;
- }
- /* should not occurs. If this happens that means
- * that the device sent more touches that it says
- * in the report descriptor. It is ignored then. */
- return -1;
-}
-
static struct mt_class mt_classes[] = {
{ .name = MT_CLS_DEFAULT,
.quirks = MT_QUIRK_NOT_SEEN_MEANS_UP },
@@ -190,7 +173,9 @@ static struct mt_class mt_classes[] = {
MT_QUIRK_SLOT_IS_CONTACTID,
.sn_move = 2048,
.sn_width = 128,
- .sn_height = 128 },
+ .sn_height = 128,
+ .maxcontacts = 60,
+ },
{ .name = MT_CLS_CYPRESS,
.quirks = MT_QUIRK_NOT_SEEN_MEANS_UP |
MT_QUIRK_CYPRESS,
@@ -216,6 +201,12 @@ static struct mt_class mt_classes[] = {
.quirks = MT_QUIRK_NOT_SEEN_MEANS_UP,
.maxcontacts = 4 },
+ { .name = MT_CLS_FLATFROG,
+ .quirks = MT_QUIRK_NOT_SEEN_MEANS_UP |
+ MT_QUIRK_NO_AREA,
+ .sn_move = 2048,
+ .maxcontacts = 40,
+ },
{ }
};
@@ -319,24 +310,16 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
* We need to ignore fields that belong to other collections
* such as Mouse that might have the same GenericDesktop usages. */
if (field->application == HID_DG_TOUCHSCREEN)
- set_bit(INPUT_PROP_DIRECT, hi->input->propbit);
+ td->mt_flags |= INPUT_MT_DIRECT;
else if (field->application != HID_DG_TOUCHPAD)
return 0;
- /* In case of an indirect device (touchpad), we need to add
- * specific BTN_TOOL_* to be handled by the synaptics xorg
- * driver.
- * We also consider that touchscreens providing buttons are touchpads.
+ /*
+ * Model touchscreens providing buttons as touchpads.
*/
if (field->application == HID_DG_TOUCHPAD ||
- (usage->hid & HID_USAGE_PAGE) == HID_UP_BUTTON ||
- cls->is_indirect) {
- set_bit(INPUT_PROP_POINTER, hi->input->propbit);
- set_bit(BTN_TOOL_FINGER, hi->input->keybit);
- set_bit(BTN_TOOL_DOUBLETAP, hi->input-&