mirror of
https://github.com/LibreELEC/LibreELEC.tv.git
synced 2025-07-24 11:16:51 +00:00
Merge pull request #883 from PimentNoir/i.mx6-stable
i.MX6 4.4 kernel: update the patches set to all known in the wild
This commit is contained in:
commit
ae704a715f
@ -210,6 +210,7 @@ CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
|
||||
CONFIG_ARCH_USE_BUILTIN_BSWAP=y
|
||||
CONFIG_HAVE_KPROBES=y
|
||||
CONFIG_HAVE_KRETPROBES=y
|
||||
CONFIG_HAVE_OPTPROBES=y
|
||||
CONFIG_HAVE_ARCH_TRACEHOOK=y
|
||||
CONFIG_HAVE_DMA_ATTRS=y
|
||||
CONFIG_HAVE_DMA_CONTIGUOUS=y
|
||||
@ -4679,6 +4680,7 @@ CONFIG_HID_MONTEREY=m
|
||||
CONFIG_HID_MULTITOUCH=m
|
||||
CONFIG_HID_NTRIG=m
|
||||
CONFIG_HID_ORTEK=m
|
||||
CONFIG_HID_OUYA=m
|
||||
CONFIG_HID_PANTHERLORD=m
|
||||
CONFIG_PANTHERLORD_FF=y
|
||||
CONFIG_HID_PENMOUNT=m
|
||||
@ -4698,6 +4700,7 @@ CONFIG_HID_SONY=m
|
||||
CONFIG_SONY_FF=y
|
||||
CONFIG_HID_SPEEDLINK=m
|
||||
CONFIG_HID_STEELSERIES=m
|
||||
CONFIG_HID_SPINELPLUS=m
|
||||
CONFIG_HID_SUNPLUS=m
|
||||
CONFIG_HID_RMI=m
|
||||
CONFIG_HID_GREENASIA=m
|
||||
|
@ -1,31 +0,0 @@
|
||||
diff -rU5 a/drivers/media/dvb-core/dvb-usb-ids.h b/drivers/media/dvb-core/dvb-usb-ids.h
|
||||
--- a/drivers/media/dvb-core/dvb-usb-ids.h 2015-11-02 01:05:25.000000000 +0100
|
||||
+++ b/drivers/media/dvb-core/dvb-usb-ids.h 2015-11-30 12:53:14.482337310 +0100
|
||||
@@ -239,10 +239,11 @@
|
||||
#define USB_PID_AVERMEDIA_A835B_3835 0x3835
|
||||
#define USB_PID_AVERMEDIA_A835B_4835 0x4835
|
||||
#define USB_PID_AVERMEDIA_1867 0x1867
|
||||
#define USB_PID_AVERMEDIA_A867 0xa867
|
||||
#define USB_PID_AVERMEDIA_H335 0x0335
|
||||
+#define USB_PID_AVERMEDIA_TD110 0xa110
|
||||
#define USB_PID_AVERMEDIA_TWINSTAR 0x0825
|
||||
#define USB_PID_TECHNOTREND_CONNECT_S2400 0x3006
|
||||
#define USB_PID_TECHNOTREND_CONNECT_S2400_8KEEPROM 0x3009
|
||||
#define USB_PID_TECHNOTREND_CONNECT_CT3650 0x300d
|
||||
#define USB_PID_TECHNOTREND_CONNECT_S2_4600 0x3011
|
||||
diff -rU5 a/drivers/media/usb/dvb-usb-v2/af9035.c b/drivers/media/usb/dvb-usb-v2/af9035.c
|
||||
--- a/drivers/media/usb/dvb-usb-v2/af9035.c 2015-11-02 01:05:25.000000000 +0100
|
||||
+++ b/drivers/media/usb/dvb-usb-v2/af9035.c 2015-11-30 17:15:09.149803276 +0100
|
||||
@@ -2051,10 +2051,12 @@
|
||||
&af9035_props, "Avermedia A835B(2835)", RC_MAP_IT913X_V2) },
|
||||
{ DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A835B_3835,
|
||||
&af9035_props, "Avermedia A835B(3835)", RC_MAP_IT913X_V2) },
|
||||
{ DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A835B_4835,
|
||||
&af9035_props, "Avermedia A835B(4835)", RC_MAP_IT913X_V2) },
|
||||
+ { DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_TD110,
|
||||
+ &af9035_props, "Avermedia AverTV Volar HD 2 (TD110)", RC_MAP_AVERMEDIA_RM_KS) },
|
||||
{ DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_H335,
|
||||
&af9035_props, "Avermedia H335", RC_MAP_IT913X_V2) },
|
||||
{ DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_UB499_2T_T09,
|
||||
&af9035_props, "Kworld UB499-2T T09", RC_MAP_IT913X_V1) },
|
||||
{ DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_SVEON_STV22_IT9137,
|
@ -0,0 +1,315 @@
|
||||
diff -Naur linux-3.19.orig/drivers/hid/hid-core.c linux-3.19/drivers/hid/hid-core.c
|
||||
--- linux-3.19.orig/drivers/hid/hid-core.c 2015-02-20 14:01:17.080322846 -0800
|
||||
+++ linux-3.19/drivers/hid/hid-core.c 2015-02-20 14:03:30.375519421 -0800
|
||||
@@ -1884,6 +1884,7 @@
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_18) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_ORTEK, USB_DEVICE_ID_ORTEK_PKB1700) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_ORTEK, USB_DEVICE_ID_ORTEK_WKB2000) },
|
||||
+ { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_OUYA, USB_DEVICE_ID_OUYA_CONTROLLER) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_PENMOUNT, USB_DEVICE_ID_PENMOUNT_6000) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_PHILIPS, USB_DEVICE_ID_PHILIPS_SPINEL_PLUS_1) },
|
||||
diff -Naur linux-3.19.orig/drivers/hid/hid-ids.h linux-3.19/drivers/hid/hid-ids.h
|
||||
--- linux-3.19.orig/drivers/hid/hid-ids.h 2015-02-20 14:01:17.080322846 -0800
|
||||
+++ linux-3.19/drivers/hid/hid-ids.h 2015-02-20 14:03:30.382519482 -0800
|
||||
@@ -721,6 +721,9 @@
|
||||
#define USB_DEVICE_ID_ORTEK_PKB1700 0x1700
|
||||
#define USB_DEVICE_ID_ORTEK_WKB2000 0x2000
|
||||
|
||||
+#define USB_VENDOR_ID_OUYA 0x2836
|
||||
+#define USB_DEVICE_ID_OUYA_CONTROLLER 0x0001
|
||||
+
|
||||
#define USB_VENDOR_ID_PLANTRONICS 0x047f
|
||||
|
||||
#define USB_VENDOR_ID_PANASONIC 0x04da
|
||||
diff -Naur linux-3.19.orig/drivers/hid/hid-ouya.c linux-3.19/drivers/hid/hid-ouya.c
|
||||
--- linux-3.19.orig/drivers/hid/hid-ouya.c 1969-12-31 16:00:00.000000000 -0800
|
||||
+++ linux-3.19/drivers/hid/hid-ouya.c 2015-02-20 14:03:30.371519386 -0800
|
||||
@@ -0,0 +1,260 @@
|
||||
+/*
|
||||
+ * HID driver for OUYA Game Controller(s)
|
||||
+ *
|
||||
+ * Copyright (c) 2013 OUYA
|
||||
+ */
|
||||
+
|
||||
+#include <linux/device.h>
|
||||
+#include <linux/input.h>
|
||||
+#include <linux/hid.h>
|
||||
+#include <linux/module.h>
|
||||
+
|
||||
+#include "hid-ids.h"
|
||||
+
|
||||
+#define OUYA_TOUCHPAD_FIXUP (1 << 0)
|
||||
+
|
||||
+struct ouya_sc {
|
||||
+ unsigned long quirks;
|
||||
+};
|
||||
+
|
||||
+/* Fixed report descriptor */
|
||||
+static __u8 ouya_rdesc_fixed[] = {
|
||||
+
|
||||
+ 0x05, 0x01, /* Usage Page (Desktop), */
|
||||
+ 0x09, 0x05, /* Usage (Game Pad), */
|
||||
+
|
||||
+ 0xA1, 0x01, /* Collection (Application), */
|
||||
+ 0x85, 0x07, /* Report ID (7), */
|
||||
+
|
||||
+ 0xA1, 0x00, /* Collection (Physical), */
|
||||
+ 0x09, 0x30, /* Usage (X), */
|
||||
+ 0x09, 0x31, /* Usage (Y), */
|
||||
+ 0x15, 0x00, /* Logical Minimum (0), */
|
||||
+ 0x26, 0xFF, 0x00, /* Logical Maximum (255), */
|
||||
+ 0x35, 0x00, /* Physical Minimum (0), */
|
||||
+ 0x46, 0xFF, 0x00, /* Physical Maximum (255), */
|
||||
+ 0x95, 0x02, /* Report Count (2), */
|
||||
+ 0x75, 0x08, /* Report Size (8), */
|
||||
+ 0x81, 0x02, /* Input (Variable), */
|
||||
+ 0xC0, /* End Collection, */
|
||||
+
|
||||
+ 0xA1, 0x00, /* Collection (Physical), */
|
||||
+ 0x09, 0x33, /* Usage (Rx), */
|
||||
+ 0x09, 0x34, /* Usage (Ry), */
|
||||
+ 0x15, 0x00, /* Logical Minimum (0), */
|
||||
+ 0x26, 0xFF, 0x00, /* Logical Maximum (255), */
|
||||
+ 0x35, 0x00, /* Physical Minimum (0), */
|
||||
+ 0x46, 0xFF, 0x00, /* Physical Maximum (255), */
|
||||
+ 0x95, 0x02, /* Report Count (2), */
|
||||
+ 0x75, 0x08, /* Report Size (8), */
|
||||
+ 0x81, 0x02, /* Input (Variable), */
|
||||
+ 0xC0, /* End Collection, */
|
||||
+
|
||||
+ 0xA1, 0x00, /* Collection (Physical), */
|
||||
+ 0x09, 0x32, /* Usage (Z), */
|
||||
+ 0x15, 0x00, /* Logical Minimum (0), */
|
||||
+ 0x26, 0xFF, 0x00, /* Logical Maximum (255), */
|
||||
+ 0x35, 0x00, /* Physical Minimum (0), */
|
||||
+ 0x46, 0xFF, 0x00, /* Physical Maximum (255), */
|
||||
+ 0x95, 0x01, /* Report Count (1), */
|
||||
+ 0x75, 0x08, /* Report Size (8), */
|
||||
+ 0x81, 0x02, /* Input (Variable), */
|
||||
+ 0xC0, /* End Collection, */
|
||||
+
|
||||
+ 0xA1, 0x00, /* Collection (Physical), */
|
||||
+ 0x09, 0x35, /* Usage (Rz), */
|
||||
+ 0x15, 0x00, /* Logical Minimum (0), */
|
||||
+ 0x26, 0xFF, 0x00, /* Logical Maximum (255), */
|
||||
+ 0x35, 0x00, /* Physical Minimum (0), */
|
||||
+ 0x46, 0xFF, 0x00, /* Physical Maximum (255), */
|
||||
+ 0x95, 0x01, /* Report Count (1), */
|
||||
+ 0x75, 0x08, /* Report Size (8), */
|
||||
+ 0x81, 0x02, /* Input (Variable), */
|
||||
+ 0xC0, /* End Collection, */
|
||||
+
|
||||
+ 0x05, 0x09, /* Usage Page (Button), */
|
||||
+ 0x19, 0x01, /* Usage Minimum (01h), */
|
||||
+ 0x29, 0x10, /* Usage Maximum (10h), */
|
||||
+ 0x95, 0x10, /* Report Count (16), */
|
||||
+ 0x75, 0x01, /* Report Size (1), */
|
||||
+ 0x81, 0x02, /* Input (Variable), */
|
||||
+
|
||||
+ /* ORIGINAL REPORT DESCRIPTOR FOR TOUCHPAD INPUT */
|
||||
+ /* 06 00 ff a1 02 09 02 15 00 26 ff 00 35 00 46 ff 00 95 03 75 08 81 02 c0 */
|
||||
+
|
||||
+ 0x06, 0x00, 0xFF, /* Usage Page (Custom), */
|
||||
+ 0x09, 0x02, /* Usage (Mouse), */
|
||||
+ 0x09, 0x01, /* Usage (Pointer), */
|
||||
+ 0xA1, 0x00, /* Collection (Physical), */
|
||||
+ 0x05, 0x09, /* Usage Page (Button), */
|
||||
+ 0x19, 0x01, /* Usage Minimum (01h), */
|
||||
+ 0x29, 0x03, /* Usage Maximum (03h), */
|
||||
+ 0x15, 0x00, /* Logical Minimum (0), */
|
||||
+ 0x25, 0x01, /* Logical Maximum (1), */
|
||||
+ 0x95, 0x03, /* Report Count (3), */
|
||||
+ 0x75, 0x01, /* Report Size (1), */
|
||||
+ 0x81, 0x02, /* Input (Variable), */
|
||||
+ 0x95, 0x01, /* Report Count (1), */
|
||||
+ 0x75, 0x05, /* Report Size (5), */
|
||||
+ 0x81, 0x01, /* Input (Constant), */
|
||||
+ 0x05, 0x01, /* Usage Page (Desktop), */
|
||||
+ 0x09, 0x30, /* Usage (X), */
|
||||
+ 0x09, 0x31, /* Usage (Y), */
|
||||
+ 0x15, 0x81, /* Logical Minimum (-127), */
|
||||
+ 0x25, 0x7f, /* Logical Maximum (127), */
|
||||
+ 0x95, 0x02, /* Report Count (2), */
|
||||
+ 0x75, 0x08, /* Report Size (8), */
|
||||
+ 0x81, 0x06, /* Input (Relative), */
|
||||
+ 0xC0, /* End Collection, */
|
||||
+
|
||||
+ 0x06, 0x00, 0xFF, /* Usage Page (Custom), */
|
||||
+ 0xA1, 0x02, /* Collection (Logical), */
|
||||
+ 0x75, 0x08, /* Report Size (8), */
|
||||
+ 0x95, 0x07, /* Report Count (7), */
|
||||
+ 0x46, 0xFF, 0x00, /* Physical Maximum (255), */
|
||||
+ 0x26, 0xFF, 0x00, /* Logical Maximum (255), */
|
||||
+ 0x09, 0x01, /* Usage (Pointer), */
|
||||
+ 0x91, 0x02, /* Output (Variable), */
|
||||
+ 0xC0, /* End Collection, */
|
||||
+
|
||||
+ 0xC0, /* End Collection */
|
||||
+
|
||||
+
|
||||
+ 0x06, 0x00, 0xFF, /* Usage Page (Custom), */
|
||||
+ 0x05, 0x0C, /* Usage Page (Consumer), */
|
||||
+ 0x09, 0x01, /* Usage (Consumer Control), */
|
||||
+
|
||||
+ 0xA1, 0x01, /* Collection (Application), */
|
||||
+ 0x85, 0x03, /* Report ID (3), */
|
||||
+ 0x05, 0x01, /* Usage Page (Desktop), */
|
||||
+ 0x09, 0x06, /* Usage (Keyboard), */
|
||||
+ 0xA1, 0x02, /* Collection (Logical), */
|
||||
+ 0x05, 0x06, /* Usage Page (Generic), */
|
||||
+ 0x09, 0x20, /* Usage (Battery Strgth), */
|
||||
+ 0x15, 0x00, /* Logical Minimum (0), */
|
||||
+ 0x26, 0xFF, 0x00, /* Logical Maximum (255), */
|
||||
+ 0x75, 0x08, /* Report Size (8), */
|
||||
+ 0x95, 0x01, /* Report Count (1), */
|
||||
+ 0x81, 0x02, /* Input (Variable), */
|
||||
+ 0x06, 0xBC, 0xFF, /* Usage Page (Custom), */
|
||||
+
|
||||
+ 0x0A, 0xAD, 0xBD, /* UNKNOWN */
|
||||
+
|
||||
+ 0x75, 0x08, /* Report Size (8), */
|
||||
+ 0x95, 0x06, /* Report Count (6), */
|
||||
+ 0x81, 0x02, /* Input (Variable), */
|
||||
+ 0xC0, /* End Collection, */
|
||||
+
|
||||
+ 0xC0, /* End Collection */
|
||||
+
|
||||
+ 0x00
|
||||
+};
|
||||
+
|
||||
+static __u8 *ouya_report_fixup(struct hid_device *hdev, __u8 *rdesc,
|
||||
+ unsigned int *rsize)
|
||||
+{
|
||||
+ struct ouya_sc *sc = hid_get_drvdata(hdev);
|
||||
+
|
||||
+ if (sc->quirks & OUYA_TOUCHPAD_FIXUP) {
|
||||
+ rdesc = ouya_rdesc_fixed;
|
||||
+ *rsize = sizeof(ouya_rdesc_fixed);
|
||||
+ }
|
||||
+ return rdesc;
|
||||
+}
|
||||
+
|
||||
+static int ouya_input_mapping(struct hid_device *hdev, struct hid_input *hi,
|
||||
+ struct hid_field *field, struct hid_usage *usage,
|
||||
+ unsigned long **bit, int *max)
|
||||
+{
|
||||
+ struct ouya_sc *sc = hid_get_drvdata(hdev);
|
||||
+
|
||||
+ if (!(sc->quirks & OUYA_TOUCHPAD_FIXUP)) {
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ if ((usage->hid & 0x90000) == 0x90000 &&
|
||||
+ (field->physical & 0xff000000) == 0xff000000 &&
|
||||
+ usage->collection_index == 5 &&
|
||||
+ field->report_count == 3) {
|
||||
+
|
||||
+ hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_MOUSE + (usage->hid - 0x90001));
|
||||
+
|
||||
+ return 1;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int ouya_probe(struct hid_device *hdev, const struct hid_device_id *id)
|
||||
+{
|
||||
+ int ret;
|
||||
+ struct ouya_sc *sc;
|
||||
+
|
||||
+ sc = kzalloc(sizeof(*sc), GFP_KERNEL);
|
||||
+ if (sc == NULL) {
|
||||
+ hid_err(hdev, "can't alloc ouya descriptor\n");
|
||||
+ return -ENOMEM;
|
||||
+ }
|
||||
+
|
||||
+ if(((hdev->version & 0xff00) == 0x0100 && (hdev->version & 0xff) >= 0x04) ||
|
||||
+ ((hdev->version & 0xff00) == 0xe100 && (hdev->version & 0xff) >= 0x3a)) {
|
||||
+ hid_info(hdev, "ouya controller - new version\n");
|
||||
+ sc->quirks = OUYA_TOUCHPAD_FIXUP;
|
||||
+ } else {
|
||||
+ sc->quirks = 0;
|
||||
+ }
|
||||
+ hid_set_drvdata(hdev, sc);
|
||||
+
|
||||
+ ret = hid_parse(hdev);
|
||||
+ if (ret) {
|
||||
+ hid_err(hdev, "parse failed\n");
|
||||
+ goto err_free;
|
||||
+ }
|
||||
+
|
||||
+ ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT |
|
||||
+ HID_CONNECT_HIDDEV_FORCE);
|
||||
+ if (ret) {
|
||||
+ hid_err(hdev, "hw start failed\n");
|
||||
+ goto err_free;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+
|
||||
+err_free:
|
||||
+ kfree(sc);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static void ouya_remove(struct hid_device *hdev)
|
||||
+{
|
||||
+ hid_hw_stop(hdev);
|
||||
+ kfree(hid_get_drvdata(hdev));
|
||||
+}
|
||||
+
|
||||
+static const struct hid_device_id ouya_devices[] = {
|
||||
+ { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_OUYA, USB_DEVICE_ID_OUYA_CONTROLLER) },
|
||||
+ { }
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(hid, ouya_devices);
|
||||
+
|
||||
+static struct hid_driver ouya_driver = {
|
||||
+ .name = "ouya",
|
||||
+ .id_table = ouya_devices,
|
||||
+ .probe = ouya_probe,
|
||||
+ .remove = ouya_remove,
|
||||
+ .input_mapping = ouya_input_mapping,
|
||||
+ .report_fixup = ouya_report_fixup
|
||||
+};
|
||||
+
|
||||
+static int __init ouya_init(void)
|
||||
+{
|
||||
+ return hid_register_driver(&ouya_driver);
|
||||
+}
|
||||
+
|
||||
+static void __exit ouya_exit(void)
|
||||
+{
|
||||
+ hid_unregister_driver(&ouya_driver);
|
||||
+}
|
||||
+
|
||||
+module_init(ouya_init);
|
||||
+module_exit(ouya_exit);
|
||||
diff -Naur linux-3.19.orig/drivers/hid/Kconfig linux-3.19/drivers/hid/Kconfig
|
||||
--- linux-3.19.orig/drivers/hid/Kconfig 2015-02-20 14:01:17.081322855 -0800
|
||||
+++ linux-3.19/drivers/hid/Kconfig 2015-02-20 14:03:30.381519473 -0800
|
||||
@@ -528,6 +528,12 @@
|
||||
- Ortek WKB-2000
|
||||
- Skycable wireless presenter
|
||||
|
||||
+config HID_OUYA
|
||||
+ tristate "OUYA Game Controller"
|
||||
+ depends on USB_HID
|
||||
+ ---help---
|
||||
+ Support for OUYA Game Controller.
|
||||
+
|
||||
config HID_PANTHERLORD
|
||||
tristate "Pantherlord/GreenAsia game controller"
|
||||
depends on HID
|
||||
diff -Naur linux-3.19.orig/drivers/hid/Makefile linux-3.19/drivers/hid/Makefile
|
||||
--- linux-3.19.orig/drivers/hid/Makefile 2015-02-20 14:01:17.081322855 -0800
|
||||
+++ linux-3.19/drivers/hid/Makefile 2015-02-20 14:03:30.382519482 -0800
|
||||
@@ -70,6 +70,7 @@
|
||||
obj-$(CONFIG_HID_MULTITOUCH) += hid-multitouch.o
|
||||
obj-$(CONFIG_HID_NTRIG) += hid-ntrig.o
|
||||
obj-$(CONFIG_HID_ORTEK) += hid-ortek.o
|
||||
+obj-$(CONFIG_HID_OUYA) += hid-ouya.o
|
||||
obj-$(CONFIG_HID_PRODIKEYS) += hid-prodikeys.o
|
||||
obj-$(CONFIG_HID_PANTHERLORD) += hid-pl.o
|
||||
obj-$(CONFIG_HID_PENMOUNT) += hid-penmount.o
|
@ -0,0 +1,164 @@
|
||||
diff -Naur linux-3.19/drivers/hid/hid-core.c linux-3.19.patch/drivers/hid/hid-core.c
|
||||
--- linux-3.19/drivers/hid/hid-core.c 2015-02-09 03:54:22.000000000 +0100
|
||||
+++ linux-3.19.patch/drivers/hid/hid-core.c 2015-02-11 00:06:14.966131308 +0100
|
||||
@@ -1886,6 +1886,10 @@
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_ORTEK, USB_DEVICE_ID_ORTEK_WKB2000) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_PENMOUNT, USB_DEVICE_ID_PENMOUNT_6000) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE) },
|
||||
+ { HID_USB_DEVICE(USB_VENDOR_ID_PHILIPS, USB_DEVICE_ID_PHILIPS_SPINEL_PLUS_1) },
|
||||
+ { HID_USB_DEVICE(USB_VENDOR_ID_PHILIPS, USB_DEVICE_ID_PHILIPS_SPINEL_PLUS_2) },
|
||||
+ { HID_USB_DEVICE(USB_VENDOR_ID_PHILIPS, USB_DEVICE_ID_PHILIPS_SPINEL_PLUS_3) },
|
||||
+ { HID_USB_DEVICE(USB_VENDOR_ID_PHILIPS, USB_DEVICE_ID_PHILIPS_SPINEL_PLUS_4) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS, HID_ANY_ID) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_KEYBOARD) },
|
||||
#if IS_ENABLED(CONFIG_HID_ROCCAT)
|
||||
diff -Naur linux-3.19/drivers/hid/hid-ids.h linux-3.19.patch/drivers/hid/hid-ids.h
|
||||
--- linux-3.19/drivers/hid/hid-ids.h 2015-02-09 03:54:22.000000000 +0100
|
||||
+++ linux-3.19.patch/drivers/hid/hid-ids.h 2015-02-11 00:04:45.885977057 +0100
|
||||
@@ -743,6 +743,10 @@
|
||||
|
||||
#define USB_VENDOR_ID_PHILIPS 0x0471
|
||||
#define USB_DEVICE_ID_PHILIPS_IEEE802154_DONGLE 0x0617
|
||||
+#define USB_DEVICE_ID_PHILIPS_SPINEL_PLUS_1 0x206c
|
||||
+#define USB_DEVICE_ID_PHILIPS_SPINEL_PLUS_2 0x20cc
|
||||
+#define USB_DEVICE_ID_PHILIPS_SPINEL_PLUS_3 0x0613
|
||||
+#define USB_DEVICE_ID_PHILIPS_SPINEL_PLUS_4 0x2168
|
||||
|
||||
#define USB_VENDOR_ID_PI_ENGINEERING 0x05f3
|
||||
#define USB_DEVICE_ID_PI_ENGINEERING_VEC_USB_FOOTPEDAL 0xff
|
||||
diff -Naur linux-3.19/drivers/hid/hid-spinelplus.c linux-3.19.patch/drivers/hid/hid-spinelplus.c
|
||||
--- linux-3.19/drivers/hid/hid-spinelplus.c 1970-01-01 01:00:00.000000000 +0100
|
||||
+++ linux-3.19.patch/drivers/hid/hid-spinelplus.c 2015-02-11 00:04:45.886977059 +0100
|
||||
@@ -0,0 +1,105 @@
|
||||
+/*
|
||||
+ * HID driver for "PHILIPS MCE USB IR Receiver- Spinel plus" remotes
|
||||
+ *
|
||||
+ * Copyright (c) 2010 Panagiotis Skintzos
|
||||
+ *
|
||||
+ * Renamed to Spinel, cleanup and modified to also support
|
||||
+ * Spinel Plus 0471:20CC by Stephan Raue 2012.
|
||||
+ */
|
||||
+
|
||||
+/*
|
||||
+ * This program is free software; you can redistribute it and/or modify it
|
||||
+ * under the terms of the GNU General Public License as published by the Free
|
||||
+ * Software Foundation; either version 2 of the License, or (at your option)
|
||||
+ * any later version.
|
||||
+ */
|
||||
+
|
||||
+#include <linux/device.h>
|
||||
+#include <linux/input.h>
|
||||
+#include <linux/hid.h>
|
||||
+#include <linux/module.h>
|
||||
+
|
||||
+#include "hid-ids.h"
|
||||
+
|
||||
+#define spinelplus_map_key(c) set_bit(EV_REP, hi->input->evbit); \
|
||||
+ hid_map_usage_clear(hi, usage, bit, max, EV_KEY, (c))
|
||||
+
|
||||
+static int spinelplus_input_mapping(struct hid_device *hdev,
|
||||
+ struct hid_input *hi, struct hid_field *field, struct hid_usage *usage,
|
||||
+ unsigned long **bit, int *max)
|
||||
+{
|
||||
+ switch (usage->hid) {
|
||||
+ case 0xffbc000d: spinelplus_map_key(KEY_MEDIA); break;
|
||||
+ case 0xffbc0024: spinelplus_map_key(KEY_MEDIA); break;
|
||||
+ case 0xffbc0027: spinelplus_map_key(KEY_ZOOM); break;
|
||||
+ case 0xffbc0033: spinelplus_map_key(KEY_HOME); break;
|
||||
+ case 0xffbc0035: spinelplus_map_key(KEY_CAMERA); break;
|
||||
+ case 0xffbc0036: spinelplus_map_key(KEY_EPG); break;
|
||||
+ case 0xffbc0037: spinelplus_map_key(KEY_DVD); break;
|
||||
+ case 0xffbc0038: spinelplus_map_key(KEY_HOME); break;
|
||||
+ case 0xffbc0039: spinelplus_map_key(KEY_MP3); break;
|
||||
+ case 0xffbc003a: spinelplus_map_key(KEY_VIDEO); break;
|
||||
+ case 0xffbc005a: spinelplus_map_key(KEY_TEXT); break;
|
||||
+ case 0xffbc005b: spinelplus_map_key(KEY_RED); break;
|
||||
+ case 0xffbc005c: spinelplus_map_key(KEY_GREEN); break;
|
||||
+ case 0xffbc005d: spinelplus_map_key(KEY_YELLOW); break;
|
||||
+ case 0xffbc005e: spinelplus_map_key(KEY_BLUE); break;
|
||||
+ default:
|
||||
+ return 0;
|
||||
+ }
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
+static int spinelplus_probe(struct hid_device *hdev,
|
||||
+ const struct hid_device_id *id)
|
||||
+{
|
||||
+ int ret;
|
||||
+ /* Connect only to hid input (not hiddev & hidraw)*/
|
||||
+ unsigned int cmask = HID_CONNECT_HIDINPUT;
|
||||
+
|
||||
+ ret = hid_parse(hdev);
|
||||
+ if (ret) {
|
||||
+ dev_err(&hdev->dev, "parse failed\n");
|
||||
+ goto err_free;
|
||||
+ }
|
||||
+
|
||||
+ ret = hid_hw_start(hdev, cmask);
|
||||
+ if (ret) {
|
||||
+ dev_err(&hdev->dev, "hw start failed\n");
|
||||
+ goto err_free;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+err_free:
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static const struct hid_device_id spinelplus_devices[] = {
|
||||
+ { HID_USB_DEVICE(USB_VENDOR_ID_PHILIPS,USB_DEVICE_ID_PHILIPS_SPINEL_PLUS_1) },
|
||||
+ { HID_USB_DEVICE(USB_VENDOR_ID_PHILIPS,USB_DEVICE_ID_PHILIPS_SPINEL_PLUS_2) },
|
||||
+ { HID_USB_DEVICE(USB_VENDOR_ID_PHILIPS,USB_DEVICE_ID_PHILIPS_SPINEL_PLUS_3) },
|
||||
+ { HID_USB_DEVICE(USB_VENDOR_ID_PHILIPS,USB_DEVICE_ID_PHILIPS_SPINEL_PLUS_4) },
|
||||
+ { }
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(hid, spinelplus_devices);
|
||||
+
|
||||
+static struct hid_driver spinelplus_driver = {
|
||||
+ .name = "SpinelPlus",
|
||||
+ .id_table = spinelplus_devices,
|
||||
+ .input_mapping = spinelplus_input_mapping,
|
||||
+ .probe = spinelplus_probe,
|
||||
+};
|
||||
+
|
||||
+static int __init spinelplus_init(void)
|
||||
+{
|
||||
+ return hid_register_driver(&spinelplus_driver);
|
||||
+}
|
||||
+
|
||||
+static void __exit spinelplus_exit(void)
|
||||
+{
|
||||
+ hid_unregister_driver(&spinelplus_driver);
|
||||
+}
|
||||
+
|
||||
+module_init(spinelplus_init);
|
||||
+module_exit(spinelplus_exit);
|
||||
+MODULE_LICENSE("GPL");
|
||||
diff -Naur linux-3.19/drivers/hid/Kconfig linux-3.19.patch/drivers/hid/Kconfig
|
||||
--- linux-3.19/drivers/hid/Kconfig 2015-02-09 03:54:22.000000000 +0100
|
||||
+++ linux-3.19.patch/drivers/hid/Kconfig 2015-02-11 00:04:45.886977059 +0100
|
||||
@@ -702,6 +702,12 @@
|
||||
---help---
|
||||
Support for Steelseries SRW-S1 steering wheel
|
||||
|
||||
+config HID_SPINELPLUS
|
||||
+ tristate "Spinel Plus remote control"
|
||||
+ depends on USB_HID
|
||||
+ ---help---
|
||||
+ Say Y here if you have a Spinel Plus (0471:206c/20cc/0613/2168) remote
|
||||
+
|
||||
config HID_SUNPLUS
|
||||
tristate "Sunplus wireless desktop"
|
||||
depends on HID
|
||||
diff -Naur linux-3.19/drivers/hid/Makefile linux-3.19.patch/drivers/hid/Makefile
|
||||
--- linux-3.19/drivers/hid/Makefile 2015-02-09 03:54:22.000000000 +0100
|
||||
+++ linux-3.19.patch/drivers/hid/Makefile 2015-02-11 00:04:45.886977059 +0100
|
||||
@@ -107,6 +107,7 @@
|
||||
obj-$(CONFIG_HID_SMARTJOYPLUS) += hid-sjoy.o
|
||||
obj-$(CONFIG_HID_SONY) += hid-sony.o
|
||||
obj-$(CONFIG_HID_SPEEDLINK) += hid-speedlink.o
|
||||
+obj-$(CONFIG_HID_SPINELPLUS) += hid-spinelplus.o
|
||||
obj-$(CONFIG_HID_STEELSERIES) += hid-steelseries.o
|
||||
obj-$(CONFIG_HID_SUNPLUS) += hid-sunplus.o
|
||||
obj-$(CONFIG_HID_GREENASIA) += hid-gaff.o
|
@ -0,0 +1,21 @@
|
||||
diff -Naur linux-3.17.1/drivers/media/rc/mceusb.c linux-3.17.1.patch/drivers/media/rc/mceusb.c
|
||||
--- linux-3.17.1/drivers/media/rc/mceusb.c 2014-10-15 12:29:30.000000000 +0200
|
||||
+++ linux-3.17.1.patch/drivers/media/rc/mceusb.c 2014-10-16 11:45:57.480176874 +0200
|
||||
@@ -188,6 +188,8 @@
|
||||
#define VENDOR_TWISTEDMELON 0x2596
|
||||
#define VENDOR_HAUPPAUGE 0x2040
|
||||
#define VENDOR_PCTV 0x2013
|
||||
+#define VENDOR_ADAPTEC 0x03f3
|
||||
+
|
||||
|
||||
enum mceusb_model_type {
|
||||
MCE_GEN2 = 0, /* Most boards */
|
||||
@@ -401,6 +403,8 @@
|
||||
.driver_info = HAUPPAUGE_CX_HYBRID_TV },
|
||||
{ USB_DEVICE(VENDOR_PCTV, 0x025e),
|
||||
.driver_info = HAUPPAUGE_CX_HYBRID_TV },
|
||||
+ /* Adaptec / HP eHome Receiver */
|
||||
+ { USB_DEVICE(VENDOR_ADAPTEC, 0x0094) },
|
||||
|
||||
/* Terminating entry */
|
||||
{ }
|
@ -0,0 +1,28 @@
|
||||
--- linux/drivers/media/rc/ir-rc6-decoder.c 2012-11-25 22:08:13.148418669 -0800
|
||||
+++ linux.patch/drivers/media/rc/ir-rc6-decoder.c 2012-11-25 22:07:48.864417975 -0800
|
||||
@@ -39,7 +39,6 @@
|
||||
#define RC6_STARTBIT_MASK 0x08 /* for the header bits */
|
||||
#define RC6_6A_MCE_TOGGLE_MASK 0x8000 /* for the body bits */
|
||||
#define RC6_6A_LCC_MASK 0xffff0000 /* RC6-6A-32 long customer code mask */
|
||||
-#define RC6_6A_MCE_CC 0x800f0000 /* MCE customer code */
|
||||
#ifndef CHAR_BIT
|
||||
#define CHAR_BIT 8 /* Normally in <limits.h> */
|
||||
#endif
|
||||
@@ -257,14 +256,9 @@ again:
|
||||
toggle = 0;
|
||||
break;
|
||||
case 32:
|
||||
- if ((scancode & RC6_6A_LCC_MASK) == RC6_6A_MCE_CC) {
|
||||
- protocol = RC_TYPE_RC6_MCE;
|
||||
- toggle = !!(scancode & RC6_6A_MCE_TOGGLE_MASK);
|
||||
- scancode &= ~RC6_6A_MCE_TOGGLE_MASK;
|
||||
- } else {
|
||||
- protocol = RC_BIT_RC6_6A_32;
|
||||
- toggle = 0;
|
||||
- }
|
||||
+ protocol = RC_TYPE_RC6_MCE;
|
||||
+ toggle = !!(scancode & RC6_6A_MCE_TOGGLE_MASK);
|
||||
+ scancode &= ~RC6_6A_MCE_TOGGLE_MASK;
|
||||
break;
|
||||
default:
|
||||
IR_dprintk(1, "RC6(6A) unsupported length\n");
|
@ -0,0 +1,13 @@
|
||||
diff -Naur linux-3.9.4/drivers/media/rc/mceusb.c linux-3.9.4.patch/drivers/media/rc/mceusb.c
|
||||
--- linux-3.9.4/drivers/media/rc/mceusb.c 2013-05-24 20:45:59.000000000 +0200
|
||||
+++ linux-3.9.4.patch/drivers/media/rc/mceusb.c 2013-05-27 12:28:12.811230633 +0200
|
||||
@@ -309,6 +309,9 @@
|
||||
/* SMK/I-O Data GV-MC7/RCKIT Receiver */
|
||||
{ USB_DEVICE(VENDOR_SMK, 0x0353),
|
||||
.driver_info = MCE_GEN2_NO_TX },
|
||||
+ /* SMK Manufacturing, Inc. Receiver */
|
||||
+ { USB_DEVICE(VENDOR_SMK, 0x0357),
|
||||
+ .driver_info = MCE_GEN2_NO_TX },
|
||||
/* Tatung eHome Infrared Transceiver */
|
||||
{ USB_DEVICE(VENDOR_TATUNG, 0x9150) },
|
||||
/* Shuttle eHome Infrared Transceiver */
|
@ -0,0 +1,70 @@
|
||||
From 7051422474e4c4e302ede3d07ffd8ef2682e07a2 Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Saraev <stefan@saraev.ca>
|
||||
Date: Tue, 22 Apr 2014 16:05:14 +0300
|
||||
Subject: [PATCH] [RFC] hid/sony: add autorepeat for PS3 remotes
|
||||
|
||||
adapted to 3.17
|
||||
|
||||
Betreff: [RFC] hid/sony: add autorepeat for PS3 remotes
|
||||
Von: David Dillow <dave@thedillows.org>
|
||||
Datum: 28.06.2013 04:28
|
||||
An: linux-input@vger.kernel.org
|
||||
Kopie (CC): Stephan Raue <stephan@openelec.tv>
|
||||
|
||||
Some applications using the PS3 remote would like to have autorepeat
|
||||
from the device. Use the input subsystem's software emulation to provide
|
||||
this capability, and enable those that don't need it to turn it off.
|
||||
---
|
||||
I'm not sure this is the correct approach, or if it is even appropriate
|
||||
for a remote to do autorepeat. However, the media/rc subsystem does do
|
||||
it by default, and it's been requested by users, so there is at least
|
||||
some demand.
|
||||
|
||||
This compiled against the hid-sony driver with the PS3 remote changes
|
||||
merged, but I have done no testing of it. If the approach seems
|
||||
reasonable, I'll try to test it when the MythTV is idle.
|
||||
---
|
||||
drivers/hid/hid-sony.c | 21 +++++++++++++++++++++
|
||||
1 file changed, 21 insertions(+)
|
||||
|
||||
diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c
|
||||
index 661f94f..2256e35 100644
|
||||
--- a/drivers/hid/hid-sony.c
|
||||
+++ b/drivers/hid/hid-sony.c
|
||||
@@ -1111,6 +1111,25 @@ static int ps3remote_mapping(struct hid_device *hdev, struct hid_input *hi,
|
||||
return 1;
|
||||
}
|
||||
|
||||
+static int ps3remote_setup_repeat(struct hid_device *hdev)
|
||||
+{
|
||||
+ struct hid_input *hidinput = list_first_entry(&hdev->inputs,
|
||||
+ struct hid_input, list);
|
||||
+ struct input_dev *input = hidinput->input;
|
||||
+
|
||||
+ /*
|
||||
+ * Set up autorepeat defaults per the remote control subsystem;
|
||||
+ * this must be done after hid_hw_start(), as having these non-zero
|
||||
+ * at the time of input_register_device() tells the input system that
|
||||
+ * the hardware does the autorepeat, and the PS3 remote does not.
|
||||
+ */
|
||||
+ set_bit(EV_REP, input->evbit);
|
||||
+ input->rep[REP_DELAY] = 500;
|
||||
+ input->rep[REP_PERIOD] = 125;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static __u8 *sony_report_fixup(struct hid_device *hdev, __u8 *rdesc,
|
||||
unsigned int *rsize)
|
||||
{
|
||||
@@ -2339,6 +2358,8 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id)
|
||||
sony_init_work(sc, dualshock4_state_worker);
|
||||
} else if (sc->quirks & MOTION_CONTROLLER) {
|
||||
sony_init_work(sc, motion_state_worker);
|
||||
+ } else if (sc->quirks & PS3REMOTE) {
|
||||
+ ret = ps3remote_setup_repeat(hdev);
|
||||
} else {
|
||||
ret = 0;
|
||||
}
|
||||
--
|
||||
1.9.1
|
@ -0,0 +1,21 @@
|
||||
diff -Naur linux-3.16.1/drivers/media/rc/imon.c linux-3.16.1.patch/drivers/media/rc/imon.c
|
||||
--- linux-3.16.1/drivers/media/rc/imon.c 2014-08-14 04:36:35.000000000 +0200
|
||||
+++ linux-3.16.1.patch/drivers/media/rc/imon.c 2014-08-15 13:57:16.587620642 +0200
|
||||
@@ -1344,6 +1344,17 @@
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
+ * For users without stabilized, just ignore any value getting
|
||||
+ * to close to the diagonal.
|
||||
+ */
|
||||
+ if ((abs(rel_y) < 2 && abs(rel_x) < 2) ||
|
||||
+ abs(abs(rel_y) - abs(rel_x)) < 2 ) {
|
||||
+ spin_lock_irqsave(&ictx->kc_lock, flags);
|
||||
+ ictx->kc = KEY_UNKNOWN;
|
||||
+ spin_unlock_irqrestore(&ictx->kc_lock, flags);
|
||||
+ return;
|
||||
+ }
|
||||
+ /*
|
||||
* Hack alert: instead of using keycodes, we have
|
||||
* to use hard-coded scancodes here...
|
||||
*/
|
@ -0,0 +1,963 @@
|
||||
From 627e828fcf1bb9fc71dbbeca29acd33162efb448 Mon Sep 17 00:00:00 2001
|
||||
From: Matt DeVillier <matt.devillier@gmail.com>
|
||||
Date: Wed, 2 Mar 2016 23:11:33 -0600
|
||||
Subject: [PATCH 1/1] linux/drivers/input/joystick/xpad: fixes for xbox360/one controllers
|
||||
|
||||
merged from https://github.com/paroj/xpad
|
||||
|
||||
- fixed blinking LED on Xbox 360 Wireless Controllers
|
||||
- only expose actually connected Xbox 360 Wireless Controllers
|
||||
- fixed kernel warnings due to submitting active URB requests
|
||||
- updated Xbox One controller force feedback
|
||||
- controller still works after suspend/ resume
|
||||
- Xbox 360 Wireless button mappings are now compatible with Xbox 360 (non-wireless) mappings
|
||||
|
||||
Signed-off-by: Matt DeVillier <matt.devillier@gmail.com>
|
||||
---
|
||||
drivers/input/joystick/xpad.c | 608 ++++++++++++++++++++++++++++++------------
|
||||
1 file changed, 432 insertions(+), 176 deletions(-)
|
||||
|
||||
diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c
|
||||
index fd4100d..1ee6626 100644
|
||||
--- a/drivers/input/joystick/xpad.c
|
||||
+++ b/drivers/input/joystick/xpad.c
|
||||
@@ -74,12 +74,15 @@
|
||||
*
|
||||
* Later changes can be tracked in SCM.
|
||||
*/
|
||||
-
|
||||
+#define DEBUG
|
||||
#include <linux/kernel.h>
|
||||
+#include <linux/input.h>
|
||||
+#include <linux/rcupdate.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/stat.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/usb/input.h>
|
||||
+#include <linux/usb/quirks.h>
|
||||
|
||||
#define DRIVER_AUTHOR "Marko Friedemann <mfr@bmx-chemnitz.de>"
|
||||
#define DRIVER_DESC "X-Box pad driver"
|
||||
@@ -125,7 +128,8 @@ static const struct xpad_device {
|
||||
{ 0x045e, 0x0289, "Microsoft X-Box pad v2 (US)", 0, XTYPE_XBOX },
|
||||
{ 0x045e, 0x028e, "Microsoft X-Box 360 pad", 0, XTYPE_XBOX360 },
|
||||
{ 0x045e, 0x02d1, "Microsoft X-Box One pad", 0, XTYPE_XBOXONE },
|
||||
- { 0x045e, 0x02dd, "Microsoft X-Box One pad (Covert Forces)", 0, XTYPE_XBOXONE },
|
||||
+ { 0x045e, 0x02dd, "Microsoft X-Box One pad (Firmware 2015)", 0, XTYPE_XBOXONE },
|
||||
+ { 0x0e6f, 0x0139, "Afterglow Prismatic Wired Controller", 0, XTYPE_XBOXONE },
|
||||
{ 0x045e, 0x0291, "Xbox 360 Wireless Receiver (XBOX)", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360W },
|
||||
{ 0x045e, 0x0719, "Xbox 360 Wireless Receiver", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360W },
|
||||
{ 0x044f, 0x0f07, "Thrustmaster, Inc. Controller", 0, XTYPE_XBOX },
|
||||
@@ -298,6 +302,7 @@ static struct usb_device_id xpad_table[] = {
|
||||
XPAD_XBOX360_VENDOR(0x044f), /* Thrustmaster X-Box 360 controllers */
|
||||
XPAD_XBOX360_VENDOR(0x045e), /* Microsoft X-Box 360 controllers */
|
||||
XPAD_XBOXONE_VENDOR(0x045e), /* Microsoft X-Box One controllers */
|
||||
+ XPAD_XBOXONE_VENDOR(0x0e6f), /* 0x0e6f X-Box One controllers */
|
||||
XPAD_XBOX360_VENDOR(0x046d), /* Logitech X-Box 360 style controllers */
|
||||
XPAD_XBOX360_VENDOR(0x0738), /* Mad Catz X-Box 360 controllers */
|
||||
{ USB_DEVICE(0x0738, 0x4540) }, /* Mad Catz Beat Pad */
|
||||
@@ -317,21 +322,42 @@ static struct usb_device_id xpad_table[] = {
|
||||
|
||||
MODULE_DEVICE_TABLE(usb, xpad_table);
|
||||
|
||||
+struct xpad_output_packet {
|
||||
+ u8 data[XPAD_PKT_LEN];
|
||||
+ u8 len;
|
||||
+ bool pending;
|
||||
+};
|
||||
+
|
||||
+#define XPAD_OUT_CMD_IDX 0
|
||||
+#define XPAD_OUT_FF_IDX 1
|
||||
+#define XPAD_OUT_LED_IDX (1 + IS_ENABLED(CONFIG_JOYSTICK_XPAD_FF))
|
||||
+#define XPAD_NUM_OUT_PACKETS (1 + \
|
||||
+ IS_ENABLED(CONFIG_JOYSTICK_XPAD_FF) + \
|
||||
+ IS_ENABLED(CONFIG_JOYSTICK_XPAD_LEDS))
|
||||
+
|
||||
struct usb_xpad {
|
||||
struct input_dev *dev; /* input device interface */
|
||||
+ struct input_dev __rcu *x360w_dev;
|
||||
struct usb_device *udev; /* usb device */
|
||||
struct usb_interface *intf; /* usb interface */
|
||||
|
||||
- int pad_present;
|
||||
+ bool pad_present;
|
||||
+ bool input_created;
|
||||
|
||||
struct urb *irq_in; /* urb for interrupt in report */
|
||||
unsigned char *idata; /* input data */
|
||||
dma_addr_t idata_dma;
|
||||
|
||||
struct urb *irq_out; /* urb for interrupt out report */
|
||||
+ struct usb_anchor irq_out_anchor;
|
||||
+ bool irq_out_active; /* we must not use an active URB */
|
||||
+ u8 odata_serial; /* serial number for xbox one protocol */
|
||||
unsigned char *odata; /* output data */
|
||||
dma_addr_t odata_dma;
|
||||
- struct mutex odata_mutex;
|
||||
+ spinlock_t odata_lock;
|
||||
+
|
||||
+ struct xpad_output_packet out_packets[XPAD_NUM_OUT_PACKETS];
|
||||
+ int last_out_packet;
|
||||
|
||||
#if defined(CONFIG_JOYSTICK_XPAD_LEDS)
|
||||
struct xpad_led *led;
|
||||
@@ -343,8 +369,12 @@ struct usb_xpad {
|
||||
int xtype; /* type of xbox device */
|
||||
int pad_nr; /* the order x360 pads were attached */
|
||||
const char *name; /* name of the device */
|
||||
+ struct work_struct work; /* init/remove device from callback */
|
||||
};
|
||||
|
||||
+static int xpad_init_input(struct usb_xpad *xpad);
|
||||
+static void xpad_deinit_input(struct usb_xpad *xpad);
|
||||
+
|
||||
/*
|
||||
* xpad_process_packet
|
||||
*
|
||||
@@ -424,11 +454,9 @@ static void xpad_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *d
|
||||
* http://www.free60.org/wiki/Gamepad
|
||||
*/
|
||||
|
||||
-static void xpad360_process_packet(struct usb_xpad *xpad,
|
||||
+static void xpad360_process_packet(struct usb_xpad *xpad, struct input_dev *dev,
|
||||
u16 cmd, unsigned char *data)
|
||||
{
|
||||
- struct input_dev *dev = xpad->dev;
|
||||
-
|
||||
/* digital pad */
|
||||
if (xpad->mapping & MAP_DPAD_TO_BUTTONS) {
|
||||
/* dpad as buttons (left, right, up, down) */
|
||||
@@ -495,7 +523,30 @@ static void xpad360_process_packet(struct usb_xpad *xpad,
|
||||
input_sync(dev);
|
||||
}
|
||||
|
||||
-static void xpad_identify_controller(struct usb_xpad *xpad);
|
||||
+static void xpad_presence_work(struct work_struct *work)
|
||||
+{
|
||||
+ struct usb_xpad *xpad = container_of(work, struct usb_xpad, work);
|
||||
+ int error;
|
||||
+
|
||||
+ if (xpad->pad_present) {
|
||||
+ error = xpad_init_input(xpad);
|
||||
+ if (error) {
|
||||
+ /* complain only, not much else we can do here */
|
||||
+ dev_err(&xpad->dev->dev,
|
||||
+ "unable to init device: %d\n", error);
|
||||
+ } else {
|
||||
+ rcu_assign_pointer(xpad->x360w_dev, xpad->dev);
|
||||
+ }
|
||||
+ } else {
|
||||
+ RCU_INIT_POINTER(xpad->x360w_dev, NULL);
|
||||
+ synchronize_rcu();
|
||||
+ /*
|
||||
+ * Now that we are sure xpad360w_process_packet is not
|
||||
+ * using input device we can get rid of it.
|
||||
+ */
|
||||
+ xpad_deinit_input(xpad);
|
||||
+ }
|
||||
+}
|
||||
|
||||
/*
|
||||
* xpad360w_process_packet
|
||||
@@ -513,24 +564,28 @@ static void xpad_identify_controller(struct usb_xpad *xpad);
|
||||
*/
|
||||
static void xpad360w_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *data)
|
||||
{
|
||||
+ struct input_dev *dev;
|
||||
+ bool present;
|
||||
+
|
||||
/* Presence change */
|
||||
if (data[0] & 0x08) {
|
||||
- if (data[1] & 0x80) {
|
||||
- xpad->pad_present = 1;
|
||||
- /*
|
||||
- * Light up the segment corresponding to
|
||||
- * controller number.
|
||||
- */
|
||||
- xpad_identify_controller(xpad);
|
||||
- } else
|
||||
- xpad->pad_present = 0;
|
||||
+ present = (data[1] & 0x80) != 0;
|
||||
+
|
||||
+ if (xpad->pad_present != present) {
|
||||
+ xpad->pad_present = present;
|
||||
+ schedule_work(&xpad->work);
|
||||
+ }
|
||||
}
|
||||
|
||||
/* Valid pad data */
|
||||
- if (!(data[1] & 0x1))
|
||||
+ if (data[1] != 0x1)
|
||||
return;
|
||||
|
||||
- xpad360_process_packet(xpad, cmd, &data[4]);
|
||||
+ rcu_read_lock();
|
||||
+ dev = rcu_dereference(xpad->x360w_dev);
|
||||
+ if (dev)
|
||||
+ xpad360_process_packet(xpad, dev, cmd, &data[4]);
|
||||
+ rcu_read_unlock();
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -659,7 +714,7 @@ static void xpad_irq_in(struct urb *urb)
|
||||
|
||||
switch (xpad->xtype) {
|
||||
case XTYPE_XBOX360:
|
||||
- xpad360_process_packet(xpad, 0, xpad->idata);
|
||||
+ xpad360_process_packet(xpad, xpad->dev, 0, xpad->idata);
|
||||
break;
|
||||
case XTYPE_XBOX360W:
|
||||
xpad360w_process_packet(xpad, 0, xpad->idata);
|
||||
@@ -678,18 +733,73 @@ exit:
|
||||
__func__, retval);
|
||||
}
|
||||
|
||||
+/* Callers must hold xpad->odata_lock spinlock */
|
||||
+static bool xpad_prepare_next_out_packet(struct usb_xpad *xpad)
|
||||
+{
|
||||
+ struct xpad_output_packet *pkt, *packet = NULL;
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; i < XPAD_NUM_OUT_PACKETS; i++) {
|
||||
+ if (++xpad->last_out_packet >= XPAD_NUM_OUT_PACKETS)
|
||||
+ xpad->last_out_packet = 0;
|
||||
+
|
||||
+ pkt = &xpad->out_packets[xpad->last_out_packet];
|
||||
+ if (pkt->pending) {
|
||||
+ dev_dbg(&xpad->intf->dev,
|
||||
+ "%s - found pending output packet %d\n",
|
||||
+ __func__, xpad->last_out_packet);
|
||||
+ packet = pkt;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (packet) {
|
||||
+ memcpy(xpad->odata, packet->data, packet->len);
|
||||
+ xpad->irq_out->transfer_buffer_length = packet->len;
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
+ return false;
|
||||
+}
|
||||
+
|
||||
+/* Callers must hold xpad->odata_lock spinlock */
|
||||
+static int xpad_try_sending_next_out_packet(struct usb_xpad *xpad)
|
||||
+{
|
||||
+ int error;
|
||||
+
|
||||
+ if (!xpad->irq_out_active && xpad_prepare_next_out_packet(xpad)) {
|
||||
+ usb_anchor_urb(xpad->irq_out, &xpad->irq_out_anchor);
|
||||
+ error = usb_submit_urb(xpad->irq_out, GFP_ATOMIC);
|
||||
+ if (error) {
|
||||
+ dev_err(&xpad->intf->dev,
|
||||
+ "%s - usb_submit_urb failed with result %d\n",
|
||||
+ __func__, error);
|
||||
+ usb_unanchor_urb(xpad->irq_out);
|
||||
+ return -EIO;
|
||||
+ }
|
||||
+
|
||||
+ xpad->irq_out_active = true;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static void xpad_irq_out(struct urb *urb)
|
||||
{
|
||||
struct usb_xpad *xpad = urb->context;
|
||||
struct device *dev = &xpad->intf->dev;
|
||||
- int retval, status;
|
||||
+ int status = urb->status;
|
||||
+ int error;
|
||||
+ unsigned long flags;
|
||||
|
||||
- status = urb->status;
|
||||
+ spin_lock_irqsave(&xpad->odata_lock, flags);
|
||||
|
||||
switch (status) {
|
||||
case 0:
|
||||
/* success */
|
||||
- return;
|
||||
+ xpad->out_packets[xpad->last_out_packet].pending = false;
|
||||
+ xpad->irq_out_active = xpad_prepare_next_out_packet(xpad);
|
||||
+ break;
|
||||
|
||||
case -ECONNRESET:
|
||||
case -ENOENT:
|
||||
@@ -697,43 +807,52 @@ static void xpad_irq_out(struct urb *urb)
|
||||
/* this urb is terminated, clean up */
|
||||
dev_dbg(dev, "%s - urb shutting down with status: %d\n",
|
||||
__func__, status);
|
||||
- return;
|
||||
+ xpad->irq_out_active = false;
|
||||
+ break;
|
||||
|
||||
default:
|
||||
dev_dbg(dev, "%s - nonzero urb status received: %d\n",
|
||||
__func__, status);
|
||||
- goto exit;
|
||||
+ break;
|
||||
}
|
||||
|
||||
-exit:
|
||||
- retval = usb_submit_urb(urb, GFP_ATOMIC);
|
||||
- if (retval)
|
||||
- dev_err(dev, "%s - usb_submit_urb failed with result %d\n",
|
||||
- __func__, retval);
|
||||
+ if (xpad->irq_out_active) {
|
||||
+ usb_anchor_urb(urb, &xpad->irq_out_anchor);
|
||||
+ error = usb_submit_urb(urb, GFP_ATOMIC);
|
||||
+ if (error) {
|
||||
+ dev_err(dev,
|
||||
+ "%s - usb_submit_urb failed with result %d\n",
|
||||
+ __func__, error);
|
||||
+ usb_unanchor_urb(urb);
|
||||
+ xpad->irq_out_active = false;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ spin_unlock_irqrestore(&xpad->odata_lock, flags);
|
||||
}
|
||||
|
||||
static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad)
|
||||
{
|
||||
struct usb_endpoint_descriptor *ep_irq_out;
|
||||
int ep_irq_out_idx;
|
||||
- int error;
|
||||
|
||||
if (xpad->xtype == XTYPE_UNKNOWN)
|
||||
return 0;
|
||||
|
||||
+ init_usb_anchor(&xpad->irq_out_anchor);
|
||||
+
|
||||
xpad->odata = usb_alloc_coherent(xpad->udev, XPAD_PKT_LEN,
|
||||
GFP_KERNEL, &xpad->odata_dma);
|
||||
if (!xpad->odata) {
|
||||
- error = -ENOMEM;
|
||||
- goto fail1;
|
||||
+ return -ENOMEM;
|
||||
}
|
||||
|
||||
- mutex_init(&xpad->odata_mutex);
|
||||
+ spin_lock_init(&xpad->odata_lock);
|
||||
|
||||
xpad->irq_out = usb_alloc_urb(0, GFP_KERNEL);
|
||||
if (!xpad->irq_out) {
|
||||
- error = -ENOMEM;
|
||||
- goto fail2;
|
||||
+ usb_free_coherent(xpad->udev, XPAD_PKT_LEN, xpad->odata, xpad->odata_dma);
|
||||
+ return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Xbox One controller has in/out endpoints swapped. */
|
||||
@@ -748,15 +867,18 @@ static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad)
|
||||
xpad->irq_out->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
|
||||
|
||||
return 0;
|
||||
-
|
||||
- fail2: usb_free_coherent(xpad->udev, XPAD_PKT_LEN, xpad->odata, xpad->odata_dma);
|
||||
- fail1: return error;
|
||||
}
|
||||
|
||||
static void xpad_stop_output(struct usb_xpad *xpad)
|
||||
{
|
||||
- if (xpad->xtype != XTYPE_UNKNOWN)
|
||||
- usb_kill_urb(xpad->irq_out);
|
||||
+ if (xpad->xtype != XTYPE_UNKNOWN) {
|
||||
+ if (!usb_wait_anchor_empty_timeout(&xpad->irq_out_anchor,
|
||||
+ 5000)) {
|
||||
+ dev_warn(&xpad->intf->dev,
|
||||
+ "timed out waiting for output URB to complete, killing\n");
|
||||
+ usb_kill_anchored_urbs(&xpad->irq_out_anchor);
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
|
||||
static void xpad_deinit_output(struct usb_xpad *xpad)
|
||||
@@ -770,27 +892,60 @@ static void xpad_deinit_output(struct usb_xpad *xpad)
|
||||
|
||||
static int xpad_inquiry_pad_presence(struct usb_xpad *xpad)
|
||||
{
|
||||
+ struct xpad_output_packet *packet =
|
||||
+ &xpad->out_packets[XPAD_OUT_CMD_IDX];
|
||||
+ unsigned long flags;
|
||||
+ int retval;
|
||||
+
|
||||
+ spin_lock_irqsave(&xpad->odata_lock, flags);
|
||||
+
|
||||
+ packet->data[0] = 0x08;
|
||||
+ packet->data[1] = 0x00;
|
||||
+ packet->data[2] = 0x0F;
|
||||
+ packet->data[3] = 0xC0;
|
||||
+ packet->data[4] = 0x00;
|
||||
+ packet->data[5] = 0x00;
|
||||
+ packet->data[6] = 0x00;
|
||||
+ packet->data[7] = 0x00;
|
||||
+ packet->data[8] = 0x00;
|
||||
+ packet->data[9] = 0x00;
|
||||
+ packet->data[10] = 0x00;
|
||||
+ packet->data[11] = 0x00;
|
||||
+ packet->len = 12;
|
||||
+ packet->pending = true;
|
||||
+
|
||||
+ /* Reset the sequence so we send out presence first */
|
||||
+ xpad->last_out_packet = -1;
|
||||
+ retval = xpad_try_sending_next_out_packet(xpad);
|
||||
+
|
||||
+ spin_unlock_irqrestore(&xpad->odata_lock, flags);
|
||||
+
|
||||
+ return retval;
|
||||
+}
|
||||
+
|
||||
+static int xpad_start_xbox_one(struct usb_xpad *xpad)
|
||||
+{
|
||||
+ struct xpad_output_packet *packet =
|
||||
+ &xpad->out_packets[XPAD_OUT_CMD_IDX];
|
||||
+ unsigned long flags;
|
||||
int retval;
|
||||
|
||||
- mutex_lock(&xpad->odata_mutex);
|
||||
+ spin_lock_irqsave(&xpad->odata_lock, flags);
|
||||
|
||||
- xpad->odata[0] = 0x08;
|
||||
- xpad->odata[1] = 0x00;
|
||||
- xpad->odata[2] = 0x0F;
|
||||
- xpad->odata[3] = 0xC0;
|
||||
- xpad->odata[4] = 0x00;
|
||||
- xpad->odata[5] = 0x00;
|
||||
- xpad->odata[6] = 0x00;
|
||||
- xpad->odata[7] = 0x00;
|
||||
- xpad->odata[8] = 0x00;
|
||||
- xpad->odata[9] = 0x00;
|
||||
- xpad->odata[10] = 0x00;
|
||||
- xpad->odata[11] = 0x00;
|
||||
- xpad->irq_out->transfer_buffer_length = 12;
|
||||
+ /* Xbox one controller needs to be initialized. */
|
||||
+ packet->data[0] = 0x05;
|
||||
+ packet->data[1] = 0x20;
|
||||
+ packet->data[2] = xpad->odata_serial++; /* packet serial */
|
||||
+ packet->data[3] = 0x01; /* rumble bit enable? */
|
||||
+ packet->data[4] = 0x00;
|
||||
+ packet->len = 5;
|
||||
+ packet->pending = true;
|
||||
|
||||
- retval = usb_submit_urb(xpad->irq_out, GFP_KERNEL);
|
||||
+ /* Reset the sequence so we send out start packet first */
|
||||
+ xpad->last_out_packet = -1;
|
||||
+ retval = xpad_try_sending_next_out_packet(xpad);
|
||||
|
||||
- mutex_unlock(&xpad->odata_mutex);
|
||||
+ spin_unlock_irqrestore(&xpad->odata_lock, flags);
|
||||
|
||||
return retval;
|
||||
}
|
||||
@@ -799,8 +954,11 @@ static int xpad_inquiry_pad_presence(struct usb_xpad *xpad)
|
||||
static int xpad_play_effect(struct input_dev *dev, void *data, struct ff_effect *effect)
|
||||
{
|
||||
struct usb_xpad *xpad = input_get_drvdata(dev);
|
||||
+ struct xpad_output_packet *packet = &xpad->out_packets[XPAD_OUT_FF_IDX];
|
||||
__u16 strong;
|
||||
__u16 weak;
|
||||
+ int retval;
|
||||
+ unsigned long flags;
|
||||
|
||||
if (effect->type != FF_RUMBLE)
|
||||
return 0;
|
||||
@@ -808,69 +966,81 @@ static int xpad_play_effect(struct input_dev *dev, void *data, struct ff_effect
|
||||
strong = effect->u.rumble.strong_magnitude;
|
||||
weak = effect->u.rumble.weak_magnitude;
|
||||
|
||||
+ spin_lock_irqsave(&xpad->odata_lock, flags);
|
||||
+
|
||||
switch (xpad->xtype) {
|
||||
case XTYPE_XBOX:
|
||||
- xpad->odata[0] = 0x00;
|
||||
- xpad->odata[1] = 0x06;
|
||||
- xpad->odata[2] = 0x00;
|
||||
- xpad->odata[3] = strong / 256; /* left actuator */
|
||||
- xpad->odata[4] = 0x00;
|
||||
- xpad->odata[5] = weak / 256; /* right actuator */
|
||||
- xpad->irq_out->transfer_buffer_length = 6;
|
||||
+ packet->data[0] = 0x00;
|
||||
+ packet->data[1] = 0x06;
|
||||
+ packet->data[2] = 0x00;
|
||||
+ packet->data[3] = strong / 256; /* left actuator */
|
||||
+ packet->data[4] = 0x00;
|
||||
+ packet->data[5] = weak / 256; /* right actuator */
|
||||
+ packet->len = 6;
|
||||
+ packet->pending = true;
|
||||
break;
|
||||
|
||||
case XTYPE_XBOX360:
|
||||
- xpad->odata[0] = 0x00;
|
||||
- xpad->odata[1] = 0x08;
|
||||
- xpad->odata[2] = 0x00;
|
||||
- xpad->odata[3] = strong / 256; /* left actuator? */
|
||||
- xpad->odata[4] = weak / 256; /* right actuator? */
|
||||
- xpad->odata[5] = 0x00;
|
||||
- xpad->odata[6] = 0x00;
|
||||
- xpad->odata[7] = 0x00;
|
||||
- xpad->irq_out->transfer_buffer_length = 8;
|
||||
+ packet->data[0] = 0x00;
|
||||
+ packet->data[1] = 0x08;
|
||||
+ packet->data[2] = 0x00;
|
||||
+ packet->data[3] = strong / 256; /* left actuator? */
|
||||
+ packet->data[4] = weak / 256; /* right actuator? */
|
||||
+ packet->data[5] = 0x00;
|
||||
+ packet->data[6] = 0x00;
|
||||
+ packet->data[7] = 0x00;
|
||||
+ packet->len = 8;
|
||||
+ packet->pending = true;
|
||||
break;
|
||||
|
||||
case XTYPE_XBOX360W:
|
||||
- xpad->odata[0] = 0x00;
|
||||
- xpad->odata[1] = 0x01;
|
||||
- xpad->odata[2] = 0x0F;
|
||||
- xpad->odata[3] = 0xC0;
|
||||
- xpad->odata[4] = 0x00;
|
||||
- xpad->odata[5] = strong / 256;
|
||||
- xpad->odata[6] = weak / 256;
|
||||
- xpad->odata[7] = 0x00;
|
||||
- xpad->odata[8] = 0x00;
|
||||
- xpad->odata[9] = 0x00;
|
||||
- xpad->odata[10] = 0x00;
|
||||
- xpad->odata[11] = 0x00;
|
||||
- xpad->irq_out->transfer_buffer_length = 12;
|
||||
+ packet->data[0] = 0x00;
|
||||
+ packet->data[1] = 0x01;
|
||||
+ packet->data[2] = 0x0F;
|
||||
+ packet->data[3] = 0xC0;
|
||||
+ packet->data[4] = 0x00;
|
||||
+ packet->data[5] = strong / 256;
|
||||
+ packet->data[6] = weak / 256;
|
||||
+ packet->data[7] = 0x00;
|
||||
+ packet->data[8] = 0x00;
|
||||
+ packet->data[9] = 0x00;
|
||||
+ packet->data[10] = 0x00;
|
||||
+ packet->data[11] = 0x00;
|
||||
+ packet->len = 12;
|
||||
+ packet->pending = true;
|
||||
break;
|
||||
|
||||
case XTYPE_XBOXONE:
|
||||
- xpad->odata[0] = 0x09; /* activate rumble */
|
||||
- xpad->odata[1] = 0x08;
|
||||
- xpad->odata[2] = 0x00;
|
||||
- xpad->odata[3] = 0x08; /* continuous effect */
|
||||
- xpad->odata[4] = 0x00; /* simple rumble mode */
|
||||
- xpad->odata[5] = 0x03; /* L and R actuator only */
|
||||
- xpad->odata[6] = 0x00; /* TODO: LT actuator */
|
||||
- xpad->odata[7] = 0x00; /* TODO: RT actuator */
|
||||
- xpad->odata[8] = strong / 256; /* left actuator */
|
||||
- xpad->odata[9] = weak / 256; /* right actuator */
|
||||
- xpad->odata[10] = 0x80; /* length of pulse */
|
||||
- xpad->odata[11] = 0x00; /* stop period of pulse */
|
||||
- xpad->irq_out->transfer_buffer_length = 12;
|
||||
+ packet->data[0] = 0x09; /* activate rumble */
|
||||
+ packet->data[1] = 0x08;
|
||||
+ packet->data[2] = xpad->odata_serial++;
|
||||
+ packet->data[3] = 0x08; /* continuous effect */
|
||||
+ packet->data[4] = 0x00; /* simple rumble mode */
|
||||
+ packet->data[5] = 0x03; /* L and R actuator only */
|
||||
+ packet->data[6] = 0x00; /* TODO: LT actuator */
|
||||
+ packet->data[7] = 0x00; /* TODO: RT actuator */
|
||||
+ packet->data[8] = strong / 512; /* left actuator */
|
||||
+ packet->data[9] = weak / 512; /* right actuator */
|
||||
+ packet->data[10] = 0x80; /* length of pulse */
|
||||
+ packet->data[11] = 0x00; /* stop period of pulse */
|
||||
+ packet->data[12] = 0x00;
|
||||
+ packet->len = 13;
|
||||
+ packet->pending = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
dev_dbg(&xpad->dev->dev,
|
||||
"%s - rumble command sent to unsupported xpad type: %d\n",
|
||||
__func__, xpad->xtype);
|
||||
- return -EINVAL;
|
||||
+ retval = -EINVAL;
|
||||
+ goto out;
|
||||
}
|
||||
|
||||
- return usb_submit_urb(xpad->irq_out, GFP_ATOMIC);
|
||||
+ retval = xpad_try_sending_next_out_packet(xpad);
|
||||
+
|
||||
+out:
|
||||
+ spin_unlock_irqrestore(&xpad->odata_lock, flags);
|
||||
+ return retval;
|
||||
}
|
||||
|
||||
static int xpad_init_ff(struct usb_xpad *xpad)
|
||||
@@ -921,36 +1091,44 @@ struct xpad_led {
|
||||
*/
|
||||
static void xpad_send_led_command(struct usb_xpad *xpad, int command)
|
||||
{
|
||||
+ struct xpad_output_packet *packet =
|
||||
+ &xpad->out_packets[XPAD_OUT_LED_IDX];
|
||||
+ unsigned long flags;
|
||||
+
|
||||
command %= 16;
|
||||
|
||||
- mutex_lock(&xpad->odata_mutex);
|
||||
+ spin_lock_irqsave(&xpad->odata_lock, flags);
|
||||
|
||||
switch (xpad->xtype) {
|
||||
case XTYPE_XBOX360:
|
||||
- xpad->odata[0] = 0x01;
|
||||
- xpad->odata[1] = 0x03;
|
||||
- xpad->odata[2] = command;
|
||||
- xpad->irq_out->transfer_buffer_length = 3;
|
||||
+ packet->data[0] = 0x01;
|
||||
+ packet->data[1] = 0x03;
|
||||
+ packet->data[2] = command;
|
||||
+ packet->len = 3;
|
||||
+ packet->pending = true;
|
||||
break;
|
||||
+
|
||||
case XTYPE_XBOX360W:
|
||||
- xpad->odata[0] = 0x00;
|
||||
- xpad->odata[1] = 0x00;
|
||||
- xpad->odata[2] = 0x08;
|
||||
- xpad->odata[3] = 0x40 + command;
|
||||
- xpad->odata[4] = 0x00;
|
||||
- xpad->odata[5] = 0x00;
|
||||
- xpad->odata[6] = 0x00;
|
||||
- xpad->odata[7] = 0x00;
|
||||
- xpad->odata[8] = 0x00;
|
||||
- xpad->odata[9] = 0x00;
|
||||
- xpad->odata[10] = 0x00;
|
||||
- xpad->odata[11] = 0x00;
|
||||
- xpad->irq_out->transfer_buffer_length = 12;
|
||||
+ packet->data[0] = 0x00;
|
||||
+ packet->data[1] = 0x00;
|
||||
+ packet->data[2] = 0x08;
|
||||
+ packet->data[3] = 0x40 + command;
|
||||
+ packet->data[4] = 0x00;
|
||||
+ packet->data[5] = 0x00;
|
||||
+ packet->data[6] = 0x00;
|
||||
+ packet->data[7] = 0x00;
|
||||
+ packet->data[8] = 0x00;
|
||||
+ packet->data[9] = 0x00;
|
||||
+ packet->data[10] = 0x00;
|
||||
+ packet->data[11] = 0x00;
|
||||
+ packet->len = 12;
|
||||
+ packet->pending = true;
|
||||
break;
|
||||
}
|
||||
|
||||
- usb_submit_urb(xpad->irq_out, GFP_KERNEL);
|
||||
- mutex_unlock(&xpad->odata_mutex);
|
||||
+ xpad_try_sending_next_out_packet(xpad);
|
||||
+
|
||||
+ spin_unlock_irqrestore(&xpad->odata_lock, flags);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -959,7 +1137,7 @@ static void xpad_send_led_command(struct usb_xpad *xpad, int command)
|
||||
*/
|
||||
static void xpad_identify_controller(struct usb_xpad *xpad)
|
||||
{
|
||||
- xpad_send_led_command(xpad, (xpad->pad_nr % 4) + 2);
|
||||
+ led_set_brightness(&xpad->led->led_cdev, (xpad->pad_nr % 4) + 2);
|
||||
}
|
||||
|
||||
static void xpad_led_set(struct led_classdev *led_cdev,
|
||||
@@ -1001,14 +1179,7 @@ static int xpad_led_probe(struct usb_xpad *xpad)
|
||||
if (error)
|
||||
goto err_free_id;
|
||||
|
||||
- if (xpad->xtype == XTYPE_XBOX360) {
|
||||
- /*
|
||||
- * Light up the segment corresponding to controller
|
||||
- * number on wired devices. On wireless we'll do that
|
||||
- * when they respond to "presence" packet.
|
||||
- */
|
||||
- xpad_identify_controller(xpad);
|
||||
- }
|
||||
+ xpad_identify_controller(xpad);
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -1036,37 +1207,73 @@ static void xpad_led_disconnect(struct usb_xpad *xpad) { }
|
||||
static void xpad_identify_controller(struct usb_xpad *xpad) { }
|
||||
#endif
|
||||
|
||||
-static int xpad_open(struct input_dev *dev)
|
||||
+static int xpad_start_input(struct usb_xpad *xpad)
|
||||
{
|
||||
- struct usb_xpad *xpad = input_get_drvdata(dev);
|
||||
-
|
||||
- /* URB was submitted in probe */
|
||||
- if (xpad->xtype == XTYPE_XBOX360W)
|
||||
- return 0;
|
||||
+ int error;
|
||||
|
||||
- xpad->irq_in->dev = xpad->udev;
|
||||
if (usb_submit_urb(xpad->irq_in, GFP_KERNEL))
|
||||
return -EIO;
|
||||
|
||||
if (xpad->xtype == XTYPE_XBOXONE) {
|
||||
- /* Xbox one controller needs to be initialized. */
|
||||
- xpad->odata[0] = 0x05;
|
||||
- xpad->odata[1] = 0x20;
|
||||
- xpad->irq_out->transfer_buffer_length = 2;
|
||||
- return usb_submit_urb(xpad->irq_out, GFP_KERNEL);
|
||||
+ error = xpad_start_xbox_one(xpad);
|
||||
+ if (error) {
|
||||
+ usb_kill_urb(xpad->irq_in);
|
||||
+ return error;
|
||||
+ }
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static void xpad_close(struct input_dev *dev)
|
||||
+static void xpad_stop_input(struct usb_xpad *xpad)
|
||||
{
|
||||
- struct usb_xpad *xpad = input_get_drvdata(dev);
|
||||
+ usb_kill_urb(xpad->irq_in);
|
||||
+}
|
||||
+
|
||||
+static int xpad360w_start_input(struct usb_xpad *xpad)
|
||||
+{
|
||||
+ int error;
|
||||
+
|
||||
+ error = usb_submit_urb(xpad->irq_in, GFP_KERNEL);
|
||||
+ if (error)
|
||||
+ return -EIO;
|
||||
|
||||
- if (xpad->xtype != XTYPE_XBOX360W)
|
||||
+ /*
|
||||
+ * Send presence packet.
|
||||
+ * This will force the controller to resend connection packets.
|
||||
+ * This is useful in the case we activate the module after the
|
||||
+ * adapter has been plugged in, as it won't automatically
|
||||
+ * send us info about the controllers.
|
||||
+ */
|
||||
+ error = xpad_inquiry_pad_presence(xpad);
|
||||
+ if (error) {
|
||||
usb_kill_urb(xpad->irq_in);
|
||||
+ return error;
|
||||
+ }
|
||||
|
||||
- xpad_stop_output(xpad);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void xpad360w_stop_input(struct usb_xpad *xpad)
|
||||
+{
|
||||
+ usb_kill_urb(xpad->irq_in);
|
||||
+
|
||||
+ /* Make sure we are done with presence work if it was scheduled */
|
||||
+ flush_work(&xpad->work);
|
||||
+}
|
||||
+
|
||||
+static int xpad_open(struct input_dev *dev)
|
||||
+{
|
||||
+ struct usb_xpad *xpad = input_get_drvdata(dev);
|
||||
+
|
||||
+ return xpad_start_input(xpad);
|
||||
+}
|
||||
+
|
||||
+static void xpad_close(struct input_dev *dev)
|
||||
+{
|
||||
+ struct usb_xpad *xpad = input_get_drvdata(dev);
|
||||
+
|
||||
+ xpad_stop_input(xpad);
|
||||
}
|
||||
|
||||
static void xpad_set_up_abs(struct input_dev *input_dev, signed short abs)
|
||||
@@ -1097,8 +1304,11 @@ static void xpad_set_up_abs(struct input_dev *input_dev, signed short abs)
|
||||
|
||||
static void xpad_deinit_input(struct usb_xpad *xpad)
|
||||
{
|
||||
- xpad_led_disconnect(xpad);
|
||||
- input_unregister_device(xpad->dev);
|
||||
+ if (xpad->input_created) {
|
||||
+ xpad->input_created = false;
|
||||
+ xpad_led_disconnect(xpad);
|
||||
+ input_unregister_device(xpad->dev);
|
||||
+ }
|
||||
}
|
||||
|
||||
static int xpad_init_input(struct usb_xpad *xpad)
|
||||
@@ -1118,8 +1328,10 @@ static int xpad_init_input(struct usb_xpad *xpad)
|
||||
|
||||
input_set_drvdata(input_dev, xpad);
|
||||
|
||||
- input_dev->open = xpad_open;
|
||||
- input_dev->close = xpad_close;
|
||||
+ if (xpad->xtype != XTYPE_XBOX360W) {
|
||||
+ input_dev->open = xpad_open;
|
||||
+ input_dev->close = xpad_close;
|
||||
+ }
|
||||
|
||||
__set_bit(EV_KEY, input_dev->evbit);
|
||||
|
||||
@@ -1181,6 +1393,7 @@ static int xpad_init_input(struct usb_xpad *xpad)
|
||||
if (error)
|
||||
goto err_disconnect_led;
|
||||
|
||||
+ xpad->input_created = true;
|
||||
return 0;
|
||||
|
||||
err_disconnect_led:
|
||||
@@ -1241,6 +1454,7 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
|
||||
xpad->mapping = xpad_device[i].mapping;
|
||||
xpad->xtype = xpad_device[i].xtype;
|
||||
xpad->name = xpad_device[i].name;
|
||||
+ INIT_WORK(&xpad->work, xpad_presence_work);
|
||||
|
||||
if (xpad->xtype == XTYPE_UNKNOWN) {
|
||||
if (intf->cur_altsetting->desc.bInterfaceClass == USB_CLASS_VENDOR_SPEC) {
|
||||
@@ -1277,10 +1491,6 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
|
||||
|
||||
usb_set_intfdata(intf, xpad);
|
||||
|
||||
- error = xpad_init_input(xpad);
|
||||
- if (error)
|
||||
- goto err_deinit_output;
|
||||
-
|
||||
if (xpad->xtype == XTYPE_XBOX360W) {
|
||||
/*
|
||||
* Submit the int URB immediately rather than waiting for open
|
||||
@@ -1289,28 +1499,24 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
|
||||
* exactly the message that a controller has arrived that
|
||||
* we're waiting for.
|
||||
*/
|
||||
- xpad->irq_in->dev = xpad->udev;
|
||||
- error = usb_submit_urb(xpad->irq_in, GFP_KERNEL);
|
||||
+ error = xpad360w_start_input(xpad);
|
||||
if (error)
|
||||
- goto err_deinit_input;
|
||||
-
|
||||
+ goto err_deinit_output;
|
||||
/*
|
||||
- * Send presence packet.
|
||||
- * This will force the controller to resend connection packets.
|
||||
- * This is useful in the case we activate the module after the
|
||||
- * adapter has been plugged in, as it won't automatically
|
||||
- * send us info about the controllers.
|
||||
+ * Wireless controllers require RESET_RESUME to work properly
|
||||
+ * after suspend. Ideally this quirk should be in usb core
|
||||
+ * quirk list, but we have too many vendors producing these
|
||||
+ * controllers and we'd need to maintain 2 identical lists
|
||||
+ * here in this driver and in usb core.
|
||||
*/
|
||||
- error = xpad_inquiry_pad_presence(xpad);
|
||||
+ udev->quirks |= USB_QUIRK_RESET_RESUME;
|
||||
+ } else {
|
||||
+ error = xpad_init_input(xpad);
|
||||
if (error)
|
||||
- goto err_kill_in_urb;
|
||||
+ goto err_deinit_output;
|
||||
}
|
||||
return 0;
|
||||
|
||||
-err_kill_in_urb:
|
||||
- usb_kill_urb(xpad->irq_in);
|
||||
-err_deinit_input:
|
||||
- xpad_deinit_input(xpad);
|
||||
err_deinit_output:
|
||||
xpad_deinit_output(xpad);
|
||||
err_free_in_urb:
|
||||
@@ -1320,19 +1526,24 @@ err_free_idata:
|
||||
err_free_mem:
|
||||
kfree(xpad);
|
||||
return error;
|
||||
-
|
||||
}
|
||||
|
||||
static void xpad_disconnect(struct usb_interface *intf)
|
||||
{
|
||||
- struct usb_xpad *xpad = usb_get_intfdata (intf);
|
||||
+ struct usb_xpad *xpad = usb_get_intfdata(intf);
|
||||
+
|
||||
+ if (xpad->xtype == XTYPE_XBOX360W)
|
||||
+ xpad360w_stop_input(xpad);
|
||||
|
||||
xpad_deinit_input(xpad);
|
||||
- xpad_deinit_output(xpad);
|
||||
|
||||
- if (xpad->xtype == XTYPE_XBOX360W) {
|
||||
- usb_kill_urb(xpad->irq_in);
|
||||
- }
|
||||
+ /*
|
||||
+ * Now that both input device and LED device are gone we can
|
||||
+ * stop output URB.
|
||||
+ */
|
||||
+ xpad_stop_output(xpad);
|
||||
+
|
||||
+ xpad_deinit_output(xpad);
|
||||
|
||||
usb_free_urb(xpad->irq_in);
|
||||
usb_free_coherent(xpad->udev, XPAD_PKT_LEN,
|
||||
@@ -1343,10 +1554,55 @@ static void xpad_disconnect(struct usb_interface *intf)
|
||||
usb_set_intfdata(intf, NULL);
|
||||
}
|
||||
|
||||
+static int xpad_suspend(struct usb_interface *intf, pm_message_t message)
|
||||
+{
|
||||
+ struct usb_xpad *xpad = usb_get_intfdata(intf);
|
||||
+ struct input_dev *input = xpad->dev;
|
||||
+
|
||||
+ if (xpad->xtype == XTYPE_XBOX360W) {
|
||||
+ /*
|
||||
+ * Wireless controllers always listen to input so
|
||||
+ * they are notified when controller shows up
|
||||
+ * or goes away.
|
||||
+ */
|
||||
+ xpad360w_stop_input(xpad);
|
||||
+ } else {
|
||||
+ mutex_lock(&input->mutex);
|
||||
+ if (input->users)
|
||||
+ xpad_stop_input(xpad);
|
||||
+ mutex_unlock(&input->mutex);
|
||||
+ }
|
||||
+
|
||||
+ xpad_stop_output(xpad);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int xpad_resume(struct usb_interface *intf)
|
||||
+{
|
||||
+ struct usb_xpad *xpad = usb_get_intfdata(intf);
|
||||
+ struct input_dev *input = xpad->dev;
|
||||
+ int retval = 0;
|
||||
+
|
||||
+ if (xpad->xtype == XTYPE_XBOX360W) {
|
||||
+ retval = xpad360w_start_input(xpad);
|
||||
+ } else {
|
||||
+ mutex_lock(&input->mutex);
|
||||
+ if (input->users)
|
||||
+ retval = xpad_start_input(xpad);
|
||||
+ mutex_unlock(&input->mutex);
|
||||
+ }
|
||||
+
|
||||
+ return retval;
|
||||
+}
|
||||
+
|
||||
static struct usb_driver xpad_driver = {
|
||||
.name = "xpad",
|
||||
.probe = xpad_probe,
|
||||
.disconnect = xpad_disconnect,
|
||||
+ .suspend = xpad_suspend,
|
||||
+ .resume = xpad_resume,
|
||||
+ .reset_resume = xpad_resume,
|
||||
.id_table = xpad_table,
|
||||
};
|
||||
|
||||
@@ -1354,4 +1610,4 @@ module_usb_driver(xpad_driver);
|
||||
|
||||
MODULE_AUTHOR(DRIVER_AUTHOR);
|
||||
MODULE_DESCRIPTION(DRIVER_DESC);
|
||||
-MODULE_LICENSE("GPL");
|
||||
+MODULE_LICENSE("GPL");
|
||||
\ No newline at end of file
|
||||
--
|
||||
2.5.0
|
||||
|
@ -0,0 +1,12 @@
|
||||
diff -Naur linux-3.7.2/drivers/media/dvb-frontends/stb0899_drv.c linux-3.7.2.patch/drivers/media/dvb-frontends/stb0899_drv.c
|
||||
--- linux-3.7.2/drivers/media/dvb-frontends/stb0899_drv.c 2013-01-11 18:19:28.000000000 +0100
|
||||
+++ linux-3.7.2.patch/drivers/media/dvb-frontends/stb0899_drv.c 2013-01-16 10:25:43.479645317 +0100
|
||||
@@ -1581,7 +1581,7 @@
|
||||
.frequency_max = 2150000,
|
||||
.frequency_stepsize = 0,
|
||||
.frequency_tolerance = 0,
|
||||
- .symbol_rate_min = 5000000,
|
||||
+ .symbol_rate_min = 1000000,
|
||||
.symbol_rate_max = 45000000,
|
||||
|
||||
.caps = FE_CAN_INVERSION_AUTO |
|
@ -0,0 +1,138 @@
|
||||
diff -Naur linux-3.7.2/drivers/media/dvb-frontends/stb0899_algo.c linux-3.7.2.patch/drivers/media/dvb-frontends/stb0899_algo.c
|
||||
--- linux-3.7.2/drivers/media/dvb-frontends/stb0899_algo.c 2013-01-11 18:19:28.000000000 +0100
|
||||
+++ linux-3.7.2.patch/drivers/media/dvb-frontends/stb0899_algo.c 2013-01-16 10:28:33.633409961 +0100
|
||||
@@ -206,7 +206,6 @@
|
||||
static enum stb0899_status stb0899_search_tmg(struct stb0899_state *state)
|
||||
{
|
||||
struct stb0899_internal *internal = &state->internal;
|
||||
- struct stb0899_params *params = &state->params;
|
||||
|
||||
short int derot_step, derot_freq = 0, derot_limit, next_loop = 3;
|
||||
int index = 0;
|
||||
@@ -216,10 +215,9 @@
|
||||
|
||||
/* timing loop computation & symbol rate optimisation */
|
||||
derot_limit = (internal->sub_range / 2L) / internal->mclk;
|
||||
- derot_step = (params->srate / 2L) / internal->mclk;
|
||||
+ derot_step = internal->derot_step * 4; /* dertot_step = decreasing delta */
|
||||
|
||||
while ((stb0899_check_tmg(state) != TIMINGOK) && next_loop) {
|
||||
- index++;
|
||||
derot_freq += index * internal->direction * derot_step; /* next derot zig zag position */
|
||||
|
||||
if (abs(derot_freq) > derot_limit)
|
||||
@@ -230,6 +228,7 @@
|
||||
STB0899_SETFIELD_VAL(CFRL, cfr[1], LSB(state->config->inversion * derot_freq));
|
||||
stb0899_write_regs(state, STB0899_CFRM, cfr, 2); /* derotator frequency */
|
||||
}
|
||||
+ index++;
|
||||
internal->direction = -internal->direction; /* Change zigzag direction */
|
||||
}
|
||||
|
||||
@@ -278,14 +277,18 @@
|
||||
{
|
||||
struct stb0899_internal *internal = &state->internal;
|
||||
|
||||
- short int derot_freq = 0, last_derot_freq = 0, derot_limit, next_loop = 3;
|
||||
+ short int derot_freq = 0, last_derot_freq = 0, derot_limit, derot_step, next_loop = 3;
|
||||
int index = 0;
|
||||
+ int base_freq;
|
||||
u8 cfr[2];
|
||||
u8 reg;
|
||||
|
||||
internal->status = NOCARRIER;
|
||||
derot_limit = (internal->sub_range / 2L) / internal->mclk;
|
||||
derot_freq = internal->derot_freq;
|
||||
+ derot_step = internal->derot_step * 2;
|
||||
+ last_derot_freq = internal->derot_freq;
|
||||
+ base_freq = internal->derot_freq;
|
||||
|
||||
reg = stb0899_read_reg(state, STB0899_CFD);
|
||||
STB0899_SETFIELD_VAL(CFD_ON, reg, 1);
|
||||
@@ -294,11 +297,10 @@
|
||||
do {
|
||||
dprintk(state->verbose, FE_DEBUG, 1, "Derot Freq=%d, mclk=%d", derot_freq, internal->mclk);
|
||||
if (stb0899_check_carrier(state) == NOCARRIER) {
|
||||
- index++;
|
||||
last_derot_freq = derot_freq;
|
||||
- derot_freq += index * internal->direction * internal->derot_step; /* next zig zag derotator position */
|
||||
+ derot_freq += index * internal->direction * derot_step; /* next zig zag derotator position */
|
||||
|
||||
- if(abs(derot_freq) > derot_limit)
|
||||
+ if (derot_freq > base_freq + derot_limit || derot_freq < base_freq - derot_limit)
|
||||
next_loop--;
|
||||
|
||||
if (next_loop) {
|
||||
@@ -310,9 +312,10 @@
|
||||
STB0899_SETFIELD_VAL(CFRL, cfr[1], LSB(state->config->inversion * derot_freq));
|
||||
stb0899_write_regs(state, STB0899_CFRM, cfr, 2); /* derotator frequency */
|
||||
}
|
||||
+ index++;
|
||||
+ internal->direction = -internal->direction; /* Change zigzag direction */
|
||||
}
|
||||
|
||||
- internal->direction = -internal->direction; /* Change zigzag direction */
|
||||
} while ((internal->status != CARRIEROK) && next_loop);
|
||||
|
||||
if (internal->status == CARRIEROK) {
|
||||
@@ -338,6 +341,7 @@
|
||||
int lock = 0, index = 0, dataTime = 500, loop;
|
||||
u8 reg;
|
||||
|
||||
+ msleep(1);
|
||||
internal->status = NODATA;
|
||||
|
||||
/* RESET FEC */
|
||||
@@ -348,6 +352,7 @@
|
||||
reg = stb0899_read_reg(state, STB0899_TSTRES);
|
||||
STB0899_SETFIELD_VAL(FRESACS, reg, 0);
|
||||
stb0899_write_reg(state, STB0899_TSTRES, reg);
|
||||
+ msleep(1);
|
||||
|
||||
if (params->srate <= 2000000)
|
||||
dataTime = 2000;
|
||||
@@ -363,6 +368,7 @@
|
||||
|
||||
stb0899_write_reg(state, STB0899_DSTATUS2, 0x00); /* force search loop */
|
||||
while (1) {
|
||||
+ msleep(1); // Alex: added 1 mSec
|
||||
/* WARNING! VIT LOCKED has to be tested before VIT_END_LOOOP */
|
||||
reg = stb0899_read_reg(state, STB0899_VSTATUS);
|
||||
lock = STB0899_GETFIELD(VSTATUS_LOCKEDVIT, reg);
|
||||
@@ -390,20 +396,21 @@
|
||||
short int derot_freq, derot_step, derot_limit, next_loop = 3;
|
||||
u8 cfr[2];
|
||||
u8 reg;
|
||||
- int index = 1;
|
||||
+ int index = 0;
|
||||
+ int base_freq;
|
||||
|
||||
struct stb0899_internal *internal = &state->internal;
|
||||
- struct stb0899_params *params = &state->params;
|
||||
|
||||
- derot_step = (params->srate / 4L) / internal->mclk;
|
||||
+ derot_step = internal->derot_step;
|
||||
derot_limit = (internal->sub_range / 2L) / internal->mclk;
|
||||
derot_freq = internal->derot_freq;
|
||||
+ base_freq = internal->derot_freq;
|
||||
|
||||
do {
|
||||
if ((internal->status != CARRIEROK) || (stb0899_check_data(state) != DATAOK)) {
|
||||
|
||||
derot_freq += index * internal->direction * derot_step; /* next zig zag derotator position */
|
||||
- if (abs(derot_freq) > derot_limit)
|
||||
+ if (derot_freq > base_freq + derot_limit || derot_freq < base_freq - derot_limit)
|
||||
next_loop--;
|
||||
|
||||
if (next_loop) {
|
||||
@@ -417,9 +424,9 @@
|
||||
stb0899_write_regs(state, STB0899_CFRM, cfr, 2); /* derotator frequency */
|
||||
|
||||
stb0899_check_carrier(state);
|
||||
- index++;
|
||||
}
|
||||
}
|
||||
+ index++;
|
||||
internal->direction = -internal->direction; /* change zig zag direction */
|
||||
} while ((internal->status != DATAOK) && next_loop);
|
||||
|
@ -0,0 +1,62 @@
|
||||
diff -Naur linux-3.7.2/drivers/media/dvb-frontends/stb0899_drv.c linux-3.7.2.patch/drivers/media/dvb-frontends/stb0899_drv.c
|
||||
--- linux-3.7.2/drivers/media/dvb-frontends/stb0899_drv.c 2013-01-11 18:19:28.000000000 +0100
|
||||
+++ linux-3.7.2.patch/drivers/media/dvb-frontends/stb0899_drv.c 2013-01-16 10:33:10.323380937 +0100
|
||||
@@ -971,6 +971,16 @@
|
||||
|
||||
*strength = stb0899_table_lookup(stb0899_dvbsrf_tab, ARRAY_SIZE(stb0899_dvbsrf_tab) - 1, val);
|
||||
*strength += 750;
|
||||
+
|
||||
+ const int MIN_STRENGTH_DVBS = 0;
|
||||
+ const int MAX_STRENGTH_DVBS = 680;
|
||||
+ if (*strength < MIN_STRENGTH_DVBS)
|
||||
+ *strength = 0;
|
||||
+ else if(*strength > MAX_STRENGTH_DVBS)
|
||||
+ *strength = 0xFFFF;
|
||||
+ else
|
||||
+ *strength = (*strength - MIN_STRENGTH_DVBS) * 0xFFFF / (MAX_STRENGTH_DVBS - MIN_STRENGTH_DVBS);
|
||||
+
|
||||
dprintk(state->verbose, FE_DEBUG, 1, "AGCIQVALUE = 0x%02x, C = %d * 0.1 dBm",
|
||||
val & 0xff, *strength);
|
||||
}
|
||||
@@ -983,6 +993,7 @@
|
||||
|
||||
*strength = stb0899_table_lookup(stb0899_dvbs2rf_tab, ARRAY_SIZE(stb0899_dvbs2rf_tab) - 1, val);
|
||||
*strength += 950;
|
||||
+ *strength = *strength << 4;
|
||||
dprintk(state->verbose, FE_DEBUG, 1, "IF_AGC_GAIN = 0x%04x, C = %d * 0.1 dBm",
|
||||
val & 0x3fff, *strength);
|
||||
}
|
||||
@@ -1016,6 +1027,16 @@
|
||||
val = MAKEWORD16(buf[0], buf[1]);
|
||||
|
||||
*snr = stb0899_table_lookup(stb0899_cn_tab, ARRAY_SIZE(stb0899_cn_tab) - 1, val);
|
||||
+
|
||||
+ const int MIN_SNR_DVBS = 0;
|
||||
+ const int MAX_SNR_DVBS = 200;
|
||||
+ if (*snr < MIN_SNR_DVBS)
|
||||
+ *snr = 0;
|
||||
+ else if(*snr > MAX_SNR_DVBS)
|
||||
+ *snr = 0xFFFF;
|
||||
+ else
|
||||
+ *snr = (*snr - MIN_SNR_DVBS) * 0xFFFF / (MAX_SNR_DVBS - MIN_SNR_DVBS);
|
||||
+
|
||||
dprintk(state->verbose, FE_DEBUG, 1, "NIR = 0x%02x%02x = %u, C/N = %d * 0.1 dBm\n",
|
||||
buf[0], buf[1], val, *snr);
|
||||
}
|
||||
@@ -1040,6 +1061,16 @@
|
||||
val = (quantn - estn) / 10;
|
||||
}
|
||||
*snr = val;
|
||||
+
|
||||
+ const int MIN_SNR_DVBS2 = 10;
|
||||
+ const int MAX_SNR_DVBS2 = 70;
|
||||
+ if (*snr < MIN_SNR_DVBS2)
|
||||
+ *snr = 0;
|
||||
+ else if(*snr > MAX_SNR_DVBS2)
|
||||
+ *snr = 0xFFFF;
|
||||
+ else
|
||||
+ *snr = (*snr - MIN_SNR_DVBS2) * 0xFFFF / (MAX_SNR_DVBS2 - MIN_SNR_DVBS2);
|
||||
+
|
||||
dprintk(state->verbose, FE_DEBUG, 1, "Es/N0 quant = %d (%d) estimate = %u (%d), C/N = %d * 0.1 dBm",
|
||||
quant, quantn, est, estn, val);
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
diff -Naur linux-3.7.9/drivers/media/usb/dvb-usb/pctv452e.c linux-3.7.9.patch/drivers/media/usb/dvb-usb/pctv452e.c
|
||||
--- linux-3.7.9/drivers/media/usb/dvb-usb/pctv452e.c 2013-01-11 18:19:28.000000000 +0100
|
||||
+++ linux-3.7.9.patch/drivers/media/usb/dvb-usb/pctv452e.c 2013-01-16 10:35:01.131342123 +0100
|
||||
@@ -995,11 +995,11 @@
|
||||
/* parameter for the MPEG2-data transfer */
|
||||
.stream = {
|
||||
.type = USB_ISOC,
|
||||
- .count = 7,
|
||||
+ .count = 4,
|
||||
.endpoint = 0x02,
|
||||
.u = {
|
||||
.isoc = {
|
||||
- .framesperurb = 4,
|
||||
+ .framesperurb = 64,
|
||||
.framesize = 940,
|
||||
.interval = 1
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
From 1efc21701d94ed0c5b91467b042bed8b8becd5cc Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Arno=20Bauern=C3=B6ppel?= <arno@aziraphale.net>
|
||||
Date: Sun, 15 Nov 2015 19:24:10 -0200
|
||||
Subject: [media] Add support for dvb usb stick Hauppauge WinTV-soloHD
|
||||
|
||||
This patch adds support for the DVB-T/C/T2 usb stick WinTV-soloHD from
|
||||
Hauppauge. It adds the usb ID 2040:0264 Hauppauge to the cards of the
|
||||
driver em28xx.
|
||||
|
||||
I successfully tested DVB-T/C and the IR remote control with the
|
||||
firmware dvb-demod-si2168-b40-01.fw.
|
||||
|
||||
Signed-off-by: Arno Bauernoeppel <arno@aziraphale.net>
|
||||
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
|
||||
|
||||
diff --git a/drivers/media/dvb-core/dvb-usb-ids.h b/drivers/media/dvb-core/dvb-usb-ids.h
|
||||
index 0a46580..1c1c298 100644
|
||||
--- a/drivers/media/dvb-core/dvb-usb-ids.h
|
||||
+++ b/drivers/media/dvb-core/dvb-usb-ids.h
|
||||
@@ -389,4 +389,5 @@
|
||||
#define USB_PID_PCTV_2002E_SE 0x025d
|
||||
#define USB_PID_SVEON_STV27 0xd3af
|
||||
#define USB_PID_TURBOX_DTT_2000 0xd3a4
|
||||
+#define USB_PID_WINTV_SOLOHD 0x0264
|
||||
#endif
|
||||
diff --git a/drivers/media/usb/em28xx/em28xx-cards.c b/drivers/media/usb/em28xx/em28xx-cards.c
|
||||
index 5373dce..a1b6ef5 100644
|
||||
--- a/drivers/media/usb/em28xx/em28xx-cards.c
|
||||
+++ b/drivers/media/usb/em28xx/em28xx-cards.c
|
||||
@@ -2475,6 +2475,8 @@ struct usb_device_id em28xx_id_table[] = {
|
||||
.driver_info = EM28178_BOARD_PCTV_461E },
|
||||
{ USB_DEVICE(0x2013, 0x025f),
|
||||
.driver_info = EM28178_BOARD_PCTV_292E },
|
||||
+ { USB_DEVICE(0x2040, 0x0264), /* Hauppauge WinTV-soloHD */
|
||||
+ .driver_info = EM28178_BOARD_PCTV_292E },
|
||||
{ USB_DEVICE(0x0413, 0x6f07),
|
||||
.driver_info = EM2861_BOARD_LEADTEK_VC100 },
|
||||
{ USB_DEVICE(0xeb1a, 0x8179),
|
||||
--
|
||||
cgit v0.10.2
|
||||
|
@ -0,0 +1,18 @@
|
||||
diff -rupN a/drivers/media/dvb-frontends/ds3000.c b/drivers/media/dvb-frontends/ds3000.c
|
||||
--- a/drivers/media/dvb-frontends/ds3000.c 2015-01-28 23:24:59.000000000 +0100
|
||||
+++ b/drivers/media/dvb-frontends/ds3000.c 2015-01-29 21:57:56.000000000 +0100
|
||||
@@ -958,6 +958,14 @@ static int ds3000_set_frontend(struct dv
|
||||
/* enable ac coupling */
|
||||
ds3000_writereg(state, 0x25, 0x8a);
|
||||
|
||||
+ dprintk("%s() frequency:%u symbol_rate:%u\n", __func__, c->frequency, c->symbol_rate);
|
||||
+
|
||||
+ if (c->symbol_rate < ds3000_ops.info.symbol_rate_min || c->symbol_rate > ds3000_ops.info.symbol_rate_max ) {
|
||||
+ dprintk("%s() symbol_rate %u out of range (%u ... %u)\n", __func__, c->symbol_rate,
|
||||
+ ds3000_ops.info.symbol_rate_min, ds3000_ops.info.symbol_rate_max);
|
||||
+ return 1;
|
||||
+ }
|
||||
+
|
||||
/* enhance symbol rate performance */
|
||||
if ((c->symbol_rate / 1000) <= 5000) {
|
||||
value = 29777 / (c->symbol_rate / 1000) + 1;
|
@ -0,0 +1,25 @@
|
||||
diff -urN a/drivers/media/dvb-core/dvb-usb-ids.h b/drivers/media/dvb-core/dvb-usb-ids.h
|
||||
--- a/drivers/media/dvb-core/dvb-usb-ids.h 2016-01-11 01:01:32.000000000 +0200
|
||||
+++ b/drivers/media/dvb-core/dvb-usb-ids.h 2016-01-13 12:42:17.648388583 +0200
|
||||
@@ -247,6 +247,7 @@
|
||||
#define USB_PID_TECHNOTREND_CONNECT_CT3650 0x300d
|
||||
#define USB_PID_TECHNOTREND_CONNECT_S2_4600 0x3011
|
||||
#define USB_PID_TECHNOTREND_CONNECT_CT2_4650_CI 0x3012
|
||||
+#define USB_PID_TECHNOTREND_CONNECT_CT2_4650_CI_2 0x3015
|
||||
#define USB_PID_TECHNOTREND_TVSTICK_CT2_4400 0x3014
|
||||
#define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY 0x005a
|
||||
#define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY_2 0x0081
|
||||
diff -urN a/drivers/media/usb/dvb-usb-v2/dvbsky.c b/drivers/media/usb/dvb-usb-v2/dvbsky.c
|
||||
--- a/drivers/media/usb/dvb-usb-v2/dvbsky.c 2016-01-11 01:01:32.000000000 +0200
|
||||
+++ b/drivers/media/usb/dvb-usb-v2/dvbsky.c 2016-01-13 12:41:17.480386735 +0200
|
||||
@@ -847,6 +847,10 @@
|
||||
USB_PID_TECHNOTREND_CONNECT_CT2_4650_CI,
|
||||
&dvbsky_t680c_props, "TechnoTrend TT-connect CT2-4650 CI",
|
||||
RC_MAP_TT_1500) },
|
||||
+ { DVB_USB_DEVICE(USB_VID_TECHNOTREND,
|
||||
+ USB_PID_TECHNOTREND_CONNECT_CT2_4650_CI_2,
|
||||
+ &dvbsky_t680c_props, "TechnoTrend TT-connect CT2-4650 CI v1.1",
|
||||
+ RC_MAP_TT_1500) },
|
||||
{ DVB_USB_DEVICE(USB_VID_TERRATEC,
|
||||
USB_PID_TERRATEC_H7_3,
|
||||
&dvbsky_t680c_props, "Terratec H7 Rev.4",
|
@ -0,0 +1,25 @@
|
||||
taken from https://bugzilla.kernel.org/show_bug.cgi?id=108691
|
||||
diff --git a/drivers/media/usb/dvb-usb-v2/af9035.c b/drivers/media/usb/dvb-usb-v2/af9035.c
|
||||
--- a/drivers/media/usb/dvb-usb-v2/af9035.c
|
||||
+++ b/drivers/media/usb/dvb-usb-v2/af9035.c
|
||||
@@ -2053,6 +2053,8 @@ static const struct usb_device_id af9035_id_table[] = {
|
||||
&af9035_props, "Avermedia A835B(3835)", RC_MAP_IT913X_V2) },
|
||||
{ DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A835B_4835,
|
||||
&af9035_props, "Avermedia A835B(4835)", RC_MAP_IT913X_V2) },
|
||||
+ { DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_TD110,
|
||||
+ &af9035_props, "Avermedia AverTV Volar HD 2 (TD110)", RC_MAP_AVERMEDIA_RM_KS) },
|
||||
{ DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_H335,
|
||||
&af9035_props, "Avermedia H335", RC_MAP_IT913X_V2) },
|
||||
{ DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_UB499_2T_T09,
|
||||
|
||||
diff --git a/drivers/media/dvb-core/dvb-usb-ids.h b/drivers/media/dvb-core/dvb-usb-ids.h
|
||||
--- a/drivers/media/dvb-core/dvb-usb-ids.h
|
||||
+++ b/drivers/media/dvb-core/dvb-usb-ids.h
|
||||
@@ -242,6 +242,7 @@
|
||||
#define USB_PID_AVERMEDIA_1867 0x1867
|
||||
#define USB_PID_AVERMEDIA_A867 0xa867
|
||||
#define USB_PID_AVERMEDIA_H335 0x0335
|
||||
+#define USB_PID_AVERMEDIA_TD110 0xa110
|
||||
#define USB_PID_AVERMEDIA_TWINSTAR 0x0825
|
||||
#define USB_PID_TECHNOTREND_CONNECT_S2400 0x3006
|
||||
#define USB_PID_TECHNOTREND_CONNECT_S2400_8KEEPROM 0x3009
|
@ -0,0 +1,50 @@
|
||||
diff --git a/drivers/media/usb/dvb-usb/az6027.c b/drivers/media/usb/dvb-usb/az6027.c
|
||||
index 92e47d6..2e71136 100644
|
||||
--- a/drivers/media/usb/dvb-usb/az6027.c
|
||||
+++ b/drivers/media/usb/dvb-usb/az6027.c
|
||||
@@ -1090,6 +1090,7 @@ static struct usb_device_id az6027_usb_table[] = {
|
||||
{ USB_DEVICE(USB_VID_TECHNISAT, USB_PID_TECHNISAT_USB2_HDCI_V2) },
|
||||
{ USB_DEVICE(USB_VID_ELGATO, USB_PID_ELGATO_EYETV_SAT) },
|
||||
{ USB_DEVICE(USB_VID_ELGATO, USB_PID_ELGATO_EYETV_SAT_V2) },
|
||||
+ { USB_DEVICE(USB_VID_ELGATO, USB_PID_ELGATO_EYETV_SAT_V3) },
|
||||
{ },
|
||||
};
|
||||
|
||||
@@ -1138,7 +1139,7 @@ static struct dvb_usb_device_properties az6027_properties = {
|
||||
|
||||
.i2c_algo = &az6027_i2c_algo,
|
||||
|
||||
- .num_device_descs = 7,
|
||||
+ .num_device_descs = 8,
|
||||
.devices = {
|
||||
{
|
||||
.name = "AZUREWAVE DVB-S/S2 USB2.0 (AZ6027)",
|
||||
@@ -1168,6 +1169,10 @@ static struct dvb_usb_device_properties az6027_properties = {
|
||||
.name = "Elgato EyeTV Sat",
|
||||
.cold_ids = { &az6027_usb_table[6], NULL },
|
||||
.warm_ids = { NULL },
|
||||
+ }, {
|
||||
+ .name = "Elgato EyeTV Sat",
|
||||
+ .cold_ids = { &az6027_usb_table[7], NULL },
|
||||
+ .warm_ids = { NULL },
|
||||
},
|
||||
{ NULL },
|
||||
}
|
||||
|
||||
warning: LF will be replaced by CRLF in az6027.c.
|
||||
The file will have its original line endings in your working directory.
|
||||
diff --git a/drivers/media/dvb-core/dvb-usb-ids.h b/drivers/media/dvb-core/dvb-usb-ids.h
|
||||
index c117fb3..7552f38 100644
|
||||
--- a/drivers/media/dvb-core/dvb-usb-ids.h
|
||||
+++ b/drivers/media/dvb-core/dvb-usb-ids.h
|
||||
@@ -365,6 +365,7 @@
|
||||
#define USB_PID_ELGATO_EYETV_DTT_Dlx 0x0020
|
||||
#define USB_PID_ELGATO_EYETV_SAT 0x002a
|
||||
#define USB_PID_ELGATO_EYETV_SAT_V2 0x0025
|
||||
+#define USB_PID_ELGATO_EYETV_SAT_V3 0x0036
|
||||
#define USB_PID_DVB_T_USB_STICK_HIGH_SPEED_COLD 0x5000
|
||||
#define USB_PID_DVB_T_USB_STICK_HIGH_SPEED_WARM 0x5001
|
||||
#define USB_PID_FRIIO_WHITE 0x0001
|
||||
|
||||
warning: LF will be replaced by CRLF in dvb-usb-ids.h.
|
||||
The file will have its original line endings in your working directory.
|
@ -0,0 +1,22 @@
|
||||
diff --git a/drivers/media/pci/cx23885/cx23885-dvb.c b/drivers/media/pci/cx23885/cx23885-dvb.c
|
||||
index 31765aa..f041b69 100644
|
||||
--- a/drivers/media/pci/cx23885/cx23885-dvb.c
|
||||
+++ b/drivers/media/pci/cx23885/cx23885-dvb.c
|
||||
@@ -1139,7 +1139,7 @@ static int dvb_register_ci_mac(struct cx23885_tsport *port)
|
||||
u8 eeprom[256]; /* 24C02 i2c eeprom */
|
||||
struct sp2_config sp2_config;
|
||||
struct i2c_board_info info;
|
||||
- struct cx23885_i2c *i2c_bus2 = &dev->i2c_bus[1];
|
||||
+ struct cx23885_i2c *i2c_bus = &dev->i2c_bus[0];
|
||||
|
||||
/* attach CI */
|
||||
memset(&sp2_config, 0, sizeof(sp2_config));
|
||||
@@ -1151,7 +1151,7 @@ static int dvb_register_ci_mac(struct cx23885_tsport *port)
|
||||
info.addr = 0x40;
|
||||
info.platform_data = &sp2_config;
|
||||
request_module(info.type);
|
||||
- client_ci = i2c_new_device(&i2c_bus2->i2c_adap, &info);
|
||||
+ client_ci = i2c_new_device(&i2c_bus->i2c_adap, &info);
|
||||
if (client_ci == NULL || client_ci->dev.driver == NULL)
|
||||
return -ENODEV;
|
||||
if (!try_module_get(client_ci->dev.driver->owner)) {
|
@ -0,0 +1,48 @@
|
||||
From: cvh <namerp@googlemail.com>
|
||||
Date: Sun, 29 May 2016 23:00:40 +0200
|
||||
Subject: [PATCH] [media] Add support for Terratec Cinergy S2 Rev.3
|
||||
|
||||
---
|
||||
drivers/media/usb/dvb-usb/dw2102.c | 8 +++++++-
|
||||
1 file changed, 7 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/media/usb/dvb-usb/dw2102.c b/drivers/media/usb/dvb-usb/dw2102.c
|
||||
index 49b55d7..961f64e 100644
|
||||
--- a/drivers/media/usb/dvb-usb/dw2102.c
|
||||
+++ b/drivers/media/usb/dvb-usb/dw2102.c
|
||||
@@ -1683,6 +1683,7 @@ enum dw2102_table_entry {
|
||||
TEVII_S421,
|
||||
TEVII_S632,
|
||||
TERRATEC_CINERGY_S2_R2,
|
||||
+ TERRATEC_CINERGY_S2_R3,
|
||||
GOTVIEW_SAT_HD,
|
||||
GENIATECH_T220,
|
||||
TECHNOTREND_S2_4600,
|
||||
@@ -1709,6 +1710,7 @@ static struct usb_device_id dw2102_table[] = {
|
||||
[TEVII_S421] = {USB_DEVICE(0x9022, USB_PID_TEVII_S421)},
|
||||
[TEVII_S632] = {USB_DEVICE(0x9022, USB_PID_TEVII_S632)},
|
||||
[TERRATEC_CINERGY_S2_R2] = {USB_DEVICE(USB_VID_TERRATEC, 0x00b0)},
|
||||
+ [TERRATEC_CINERGY_S2_R3] = {USB_DEVICE(USB_VID_TERRATEC, 0x0102)},
|
||||
[GOTVIEW_SAT_HD] = {USB_DEVICE(0x1FE1, USB_PID_GOTVIEW_SAT_HD)},
|
||||
[GENIATECH_T220] = {USB_DEVICE(0x1f4d, 0xD220)},
|
||||
[TECHNOTREND_S2_4600] = {USB_DEVICE(USB_VID_TECHNOTREND,
|
||||
@@ -2118,7 +2120,7 @@ static struct dvb_usb_device_properties su3000_properties = {
|
||||
}},
|
||||
}
|
||||
},
|
||||
- .num_device_descs = 5,
|
||||
+ .num_device_descs = 6,
|
||||
.devices = {
|
||||
{ "SU3000HD DVB-S USB2.0",
|
||||
{ &dw2102_table[GENIATECH_SU3000], NULL },
|
||||
@@ -2136,6 +2138,10 @@ static struct dvb_usb_device_properties su3000_properties = {
|
||||
{ &dw2102_table[TERRATEC_CINERGY_S2_R2], NULL },
|
||||
{ NULL },
|
||||
},
|
||||
+ { "Terratec Cinergy S2 USB HD Rev.3",
|
||||
+ { &dw2102_table[TERRATEC_CINERGY_S2_R3], NULL },
|
||||
+ { NULL },
|
||||
+ },
|
||||
{ "GOTVIEW Satellite HD",
|
||||
{ &dw2102_table[GOTVIEW_SAT_HD], NULL },
|
||||
{ NULL },
|
@ -0,0 +1,26 @@
|
||||
From 57f0b99ca9a2db948fa70988c447553683368be1 Mon Sep 17 00:00:00 2001
|
||||
From: Nell Hardcastle <nell@dev-nell.com>
|
||||
Date: Thu, 29 May 2014 22:06:50 -0700
|
||||
Subject: [PATCH] eMMC: Don't initialize partitions on RPMB flagged areas.
|
||||
|
||||
Prevents a lot of pointless hanging at boot on some devices.
|
||||
---
|
||||
drivers/mmc/card/block.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
|
||||
index 4409d79..56df902 100644
|
||||
--- a/drivers/mmc/card/block.c
|
||||
+++ b/drivers/mmc/card/block.c
|
||||
@@ -2254,7 +2254,7 @@ static int mmc_blk_alloc_parts(struct mmc_card *card, struct mmc_blk_data *md)
|
||||
return 0;
|
||||
|
||||
for (idx = 0; idx < card->nr_parts; idx++) {
|
||||
- if (card->part[idx].size) {
|
||||
+ if (card->part[idx].size && !(card->part[idx].area_type & MMC_BLK_DATA_AREA_RPMB)) {
|
||||
ret = mmc_blk_alloc_part(card, md,
|
||||
card->part[idx].part_cfg,
|
||||
card->part[idx].size >> 9,
|
||||
--
|
||||
1.7.10.4
|
||||
|
Loading…
x
Reference in New Issue
Block a user