aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-05-27 22:14:35 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-05-27 22:14:35 -0400
commited2608faa0f701b1dbc65277a9e5c7ff7118bfd4 (patch)
tree542950c65a22d6a149322849b6f45657e12d6a2e /drivers
parent06d2e7812ecd1b585c5e9e7bda8ee90acebaef8c (diff)
parentf49cf3b8b4c841457244c461c66186a719e13bcc (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
Pull more input subsystem updates from Dmitry Torokhov: "Just a few more driver fixes; new drivers will be coming in the next merge window" * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input: Input: pwm-beeper - fix - scheduling while atomic Input: xpad - xbox one elite controller support Input: xpad - add more third-party controllers Input: xpad - prevent spurious input from wired Xbox 360 controllers Input: xpad - move pending clear to the correct location Input: uinput - handle compat ioctl for UI_SET_PHYS
Diffstat (limited to 'drivers')
-rw-r--r--drivers/input/joystick/xpad.c18
-rw-r--r--drivers/input/misc/pwm-beeper.c69
-rw-r--r--drivers/input/misc/uinput.c6
3 files changed, 70 insertions, 23 deletions
diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c
index 1142a93dd90b..804dbcc37d3f 100644
--- a/drivers/input/joystick/xpad.c
+++ b/drivers/input/joystick/xpad.c
@@ -87,7 +87,7 @@
87#define DRIVER_AUTHOR "Marko Friedemann <mfr@bmx-chemnitz.de>" 87#define DRIVER_AUTHOR "Marko Friedemann <mfr@bmx-chemnitz.de>"
88#define DRIVER_DESC "X-Box pad driver" 88#define DRIVER_DESC "X-Box pad driver"
89 89
90#define XPAD_PKT_LEN 32 90#define XPAD_PKT_LEN 64
91 91
92/* xbox d-pads should map to buttons, as is required for DDR pads 92/* xbox d-pads should map to buttons, as is required for DDR pads
93 but we map them to axes when possible to simplify things */ 93 but we map them to axes when possible to simplify things */
@@ -129,6 +129,7 @@ static const struct xpad_device {
129 { 0x045e, 0x028e, "Microsoft X-Box 360 pad", 0, XTYPE_XBOX360 }, 129 { 0x045e, 0x028e, "Microsoft X-Box 360 pad", 0, XTYPE_XBOX360 },
130 { 0x045e, 0x02d1, "Microsoft X-Box One pad", 0, XTYPE_XBOXONE }, 130 { 0x045e, 0x02d1, "Microsoft X-Box One pad", 0, XTYPE_XBOXONE },
131 { 0x045e, 0x02dd, "Microsoft X-Box One pad (Firmware 2015)", 0, XTYPE_XBOXONE }, 131 { 0x045e, 0x02dd, "Microsoft X-Box One pad (Firmware 2015)", 0, XTYPE_XBOXONE },
132 { 0x045e, 0x02e3, "Microsoft X-Box One Elite pad", 0, XTYPE_XBOXONE },
132 { 0x045e, 0x0291, "Xbox 360 Wireless Receiver (XBOX)", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360W }, 133 { 0x045e, 0x0291, "Xbox 360 Wireless Receiver (XBOX)", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360W },
133 { 0x045e, 0x0719, "Xbox 360 Wireless Receiver", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360W }, 134 { 0x045e, 0x0719, "Xbox 360 Wireless Receiver", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360W },
134 { 0x044f, 0x0f07, "Thrustmaster, Inc. Controller", 0, XTYPE_XBOX }, 135 { 0x044f, 0x0f07, "Thrustmaster, Inc. Controller", 0, XTYPE_XBOX },
@@ -173,9 +174,11 @@ static const struct xpad_device {
173 { 0x0e6f, 0x0006, "Edge wireless Controller", 0, XTYPE_XBOX }, 174 { 0x0e6f, 0x0006, "Edge wireless Controller", 0, XTYPE_XBOX },
174 { 0x0e6f, 0x0105, "HSM3 Xbox360 dancepad", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360 }, 175 { 0x0e6f, 0x0105, "HSM3 Xbox360 dancepad", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360 },
175 { 0x0e6f, 0x0113, "Afterglow AX.1 Gamepad for Xbox 360", 0, XTYPE_XBOX360 }, 176 { 0x0e6f, 0x0113, "Afterglow AX.1 Gamepad for Xbox 360", 0, XTYPE_XBOX360 },
177 { 0x0e6f, 0x0139, "Afterglow Prismatic Wired Controller", 0, XTYPE_XBOXONE },
176 { 0x0e6f, 0x0201, "Pelican PL-3601 'TSZ' Wired Xbox 360 Controller", 0, XTYPE_XBOX360 }, 178 { 0x0e6f, 0x0201, "Pelican PL-3601 'TSZ' Wired Xbox 360 Controller", 0, XTYPE_XBOX360 },
177 { 0x0e6f, 0x0213, "Afterglow Gamepad for Xbox 360", 0, XTYPE_XBOX360 }, 179 { 0x0e6f, 0x0213, "Afterglow Gamepad for Xbox 360", 0, XTYPE_XBOX360 },
178 { 0x0e6f, 0x021f, "Rock Candy Gamepad for Xbox 360", 0, XTYPE_XBOX360 }, 180 { 0x0e6f, 0x021f, "Rock Candy Gamepad for Xbox 360", 0, XTYPE_XBOX360 },
181 { 0x0e6f, 0x0146, "Rock Candy Wired Controller for Xbox One", 0, XTYPE_XBOXONE },
179 { 0x0e6f, 0x0301, "Logic3 Controller", 0, XTYPE_XBOX360 }, 182 { 0x0e6f, 0x0301, "Logic3 Controller", 0, XTYPE_XBOX360 },
180 { 0x0e6f, 0x0401, "Logic3 Controller", 0, XTYPE_XBOX360 }, 183 { 0x0e6f, 0x0401, "Logic3 Controller", 0, XTYPE_XBOX360 },
181 { 0x0e8f, 0x0201, "SmartJoy Frag Xpad/PS2 adaptor", 0, XTYPE_XBOX }, 184 { 0x0e8f, 0x0201, "SmartJoy Frag Xpad/PS2 adaptor", 0, XTYPE_XBOX },
@@ -183,6 +186,7 @@ static const struct xpad_device {
183 { 0x0f0d, 0x000a, "Hori Co. DOA4 FightStick", 0, XTYPE_XBOX360 }, 186 { 0x0f0d, 0x000a, "Hori Co. DOA4 FightStick", 0, XTYPE_XBOX360 },
184 { 0x0f0d, 0x000d, "Hori Fighting Stick EX2", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 }, 187 { 0x0f0d, 0x000d, "Hori Fighting Stick EX2", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
185 { 0x0f0d, 0x0016, "Hori Real Arcade Pro.EX", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 }, 188 { 0x0f0d, 0x0016, "Hori Real Arcade Pro.EX", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
189 { 0x0f0d, 0x0067, "HORIPAD ONE", 0, XTYPE_XBOXONE },
186 { 0x0f30, 0x0202, "Joytech Advanced Controller", 0, XTYPE_XBOX }, 190 { 0x0f30, 0x0202, "Joytech Advanced Controller", 0, XTYPE_XBOX },
187 { 0x0f30, 0x8888, "BigBen XBMiniPad Controller", 0, XTYPE_XBOX }, 191 { 0x0f30, 0x8888, "BigBen XBMiniPad Controller", 0, XTYPE_XBOX },
188 { 0x102c, 0xff0c, "Joytech Wireless Advanced Controller", 0, XTYPE_XBOX }, 192 { 0x102c, 0xff0c, "Joytech Wireless Advanced Controller", 0, XTYPE_XBOX },
@@ -199,6 +203,7 @@ static const struct xpad_device {
199 { 0x162e, 0xbeef, "Joytech Neo-Se Take2", 0, XTYPE_XBOX360 }, 203 { 0x162e, 0xbeef, "Joytech Neo-Se Take2", 0, XTYPE_XBOX360 },
200 { 0x1689, 0xfd00, "Razer Onza Tournament Edition", 0, XTYPE_XBOX360 }, 204 { 0x1689, 0xfd00, "Razer Onza Tournament Edition", 0, XTYPE_XBOX360 },
201 { 0x1689, 0xfd01, "Razer Onza Classic Edition", 0, XTYPE_XBOX360 }, 205 { 0x1689, 0xfd01, "Razer Onza Classic Edition", 0, XTYPE_XBOX360 },
206 { 0x24c6, 0x542a, "Xbox ONE spectra", 0, XTYPE_XBOXONE },
202 { 0x24c6, 0x5d04, "Razer Sabertooth", 0, XTYPE_XBOX360 }, 207 { 0x24c6, 0x5d04, "Razer Sabertooth", 0, XTYPE_XBOX360 },
203 { 0x1bad, 0x0002, "Harmonix Rock Band Guitar", 0, XTYPE_XBOX360 }, 208 { 0x1bad, 0x0002, "Harmonix Rock Band Guitar", 0, XTYPE_XBOX360 },
204 { 0x1bad, 0x0003, "Harmonix Rock Band Drumkit", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360 }, 209 { 0x1bad, 0x0003, "Harmonix Rock Band Drumkit", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360 },
@@ -212,6 +217,8 @@ static const struct xpad_device {
212 { 0x24c6, 0x5000, "Razer Atrox Arcade Stick", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 }, 217 { 0x24c6, 0x5000, "Razer Atrox Arcade Stick", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
213 { 0x24c6, 0x5300, "PowerA MINI PROEX Controller", 0, XTYPE_XBOX360 }, 218 { 0x24c6, 0x5300, "PowerA MINI PROEX Controller", 0, XTYPE_XBOX360 },
214 { 0x24c6, 0x5303, "Xbox Airflo wired controller", 0, XTYPE_XBOX360 }, 219 { 0x24c6, 0x5303, "Xbox Airflo wired controller", 0, XTYPE_XBOX360 },
220 { 0x24c6, 0x541a, "PowerA Xbox One Mini Wired Controller", 0, XTYPE_XBOXONE },
221 { 0x24c6, 0x543a, "PowerA Xbox One wired controller", 0, XTYPE_XBOXONE },
215 { 0x24c6, 0x5500, "Hori XBOX 360 EX 2 with Turbo", 0, XTYPE_XBOX360 }, 222 { 0x24c6, 0x5500, "Hori XBOX 360 EX 2 with Turbo", 0, XTYPE_XBOX360 },
216 { 0x24c6, 0x5501, "Hori Real Arcade Pro VX-SA", 0, XTYPE_XBOX360 }, 223 { 0x24c6, 0x5501, "Hori Real Arcade Pro VX-SA", 0, XTYPE_XBOX360 },
217 { 0x24c6, 0x5506, "Hori SOULCALIBUR V Stick", 0, XTYPE_XBOX360 }, 224 { 0x24c6, 0x5506, "Hori SOULCALIBUR V Stick", 0, XTYPE_XBOX360 },
@@ -307,13 +314,16 @@ static struct usb_device_id xpad_table[] = {
307 { USB_DEVICE(0x0738, 0x4540) }, /* Mad Catz Beat Pad */ 314 { USB_DEVICE(0x0738, 0x4540) }, /* Mad Catz Beat Pad */
308 XPAD_XBOXONE_VENDOR(0x0738), /* Mad Catz FightStick TE 2 */ 315 XPAD_XBOXONE_VENDOR(0x0738), /* Mad Catz FightStick TE 2 */
309 XPAD_XBOX360_VENDOR(0x0e6f), /* 0x0e6f X-Box 360 controllers */ 316 XPAD_XBOX360_VENDOR(0x0e6f), /* 0x0e6f X-Box 360 controllers */
317 XPAD_XBOXONE_VENDOR(0x0e6f), /* 0x0e6f X-Box One controllers */
310 XPAD_XBOX360_VENDOR(0x12ab), /* X-Box 360 dance pads */ 318 XPAD_XBOX360_VENDOR(0x12ab), /* X-Box 360 dance pads */
311 XPAD_XBOX360_VENDOR(0x1430), /* RedOctane X-Box 360 controllers */ 319 XPAD_XBOX360_VENDOR(0x1430), /* RedOctane X-Box 360 controllers */
312 XPAD_XBOX360_VENDOR(0x146b), /* BigBen Interactive Controllers */ 320 XPAD_XBOX360_VENDOR(0x146b), /* BigBen Interactive Controllers */
313 XPAD_XBOX360_VENDOR(0x1bad), /* Harminix Rock Band Guitar and Drums */ 321 XPAD_XBOX360_VENDOR(0x1bad), /* Harminix Rock Band Guitar and Drums */
314 XPAD_XBOX360_VENDOR(0x0f0d), /* Hori Controllers */ 322 XPAD_XBOX360_VENDOR(0x0f0d), /* Hori Controllers */
323 XPAD_XBOXONE_VENDOR(0x0f0d), /* Hori Controllers */
315 XPAD_XBOX360_VENDOR(0x1689), /* Razer Onza */ 324 XPAD_XBOX360_VENDOR(0x1689), /* Razer Onza */
316 XPAD_XBOX360_VENDOR(0x24c6), /* PowerA Controllers */ 325 XPAD_XBOX360_VENDOR(0x24c6), /* PowerA Controllers */
326 XPAD_XBOXONE_VENDOR(0x24c6), /* PowerA Controllers */
317 XPAD_XBOX360_VENDOR(0x1532), /* Razer Sabertooth */ 327 XPAD_XBOX360_VENDOR(0x1532), /* Razer Sabertooth */
318 XPAD_XBOX360_VENDOR(0x15e4), /* Numark X-Box 360 controllers */ 328 XPAD_XBOX360_VENDOR(0x15e4), /* Numark X-Box 360 controllers */
319 XPAD_XBOX360_VENDOR(0x162e), /* Joytech X-Box 360 controllers */ 329 XPAD_XBOX360_VENDOR(0x162e), /* Joytech X-Box 360 controllers */
@@ -457,6 +467,10 @@ static void xpad_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *d
457static void xpad360_process_packet(struct usb_xpad *xpad, struct input_dev *dev, 467static void xpad360_process_packet(struct usb_xpad *xpad, struct input_dev *dev,
458 u16 cmd, unsigned char *data) 468 u16 cmd, unsigned char *data)
459{ 469{
470 /* valid pad data */
471 if (data[0] != 0x00)
472 return;
473
460 /* digital pad */ 474 /* digital pad */
461 if (xpad->mapping & MAP_DPAD_TO_BUTTONS) { 475 if (xpad->mapping & MAP_DPAD_TO_BUTTONS) {
462 /* dpad as buttons (left, right, up, down) */ 476 /* dpad as buttons (left, right, up, down) */
@@ -756,6 +770,7 @@ static bool xpad_prepare_next_out_packet(struct usb_xpad *xpad)
756 if (packet) { 770 if (packet) {
757 memcpy(xpad->odata, packet->data, packet->len); 771 memcpy(xpad->odata, packet->data, packet->len);
758 xpad->irq_out->transfer_buffer_length = packet->len; 772 xpad->irq_out->transfer_buffer_length = packet->len;
773 packet->pending = false;
759 return true; 774 return true;
760 } 775 }
761 776
@@ -797,7 +812,6 @@ static void xpad_irq_out(struct urb *urb)
797 switch (status) { 812 switch (status) {
798 case 0: 813 case 0:
799 /* success */ 814 /* success */
800 xpad->out_packets[xpad->last_out_packet].pending = false;
801 xpad->irq_out_active = xpad_prepare_next_out_packet(xpad); 815 xpad->irq_out_active = xpad_prepare_next_out_packet(xpad);
802 break; 816 break;
803 817
diff --git a/drivers/input/misc/pwm-beeper.c b/drivers/input/misc/pwm-beeper.c
index 8d7133268745..5f9655d49a65 100644
--- a/drivers/input/misc/pwm-beeper.c
+++ b/drivers/input/misc/pwm-beeper.c
@@ -20,21 +20,40 @@
20#include <linux/platform_device.h> 20#include <linux/platform_device.h>
21#include <linux/pwm.h> 21#include <linux/pwm.h>
22#include <linux/slab.h> 22#include <linux/slab.h>
23#include <linux/workqueue.h>
23 24
24struct pwm_beeper { 25struct pwm_beeper {
25 struct input_dev *input; 26 struct input_dev *input;
26 struct pwm_device *pwm; 27 struct pwm_device *pwm;
28 struct work_struct work;
27 unsigned long period; 29 unsigned long period;
28}; 30};
29 31
30#define HZ_TO_NANOSECONDS(x) (1000000000UL/(x)) 32#define HZ_TO_NANOSECONDS(x) (1000000000UL/(x))
31 33
34static void __pwm_beeper_set(struct pwm_beeper *beeper)
35{
36 unsigned long period = beeper->period;
37
38 if (period) {
39 pwm_config(beeper->pwm, period / 2, period);
40 pwm_enable(beeper->pwm);
41 } else
42 pwm_disable(beeper->pwm);
43}
44
45static void pwm_beeper_work(struct work_struct *work)
46{
47 struct pwm_beeper *beeper =
48 container_of(work, struct pwm_beeper, work);
49
50 __pwm_beeper_set(beeper);
51}
52
32static int pwm_beeper_event(struct input_dev *input, 53static int pwm_beeper_event(struct input_dev *input,
33 unsigned int type, unsigned int code, int value) 54 unsigned int type, unsigned int code, int value)
34{ 55{
35 int ret = 0;
36 struct pwm_beeper *beeper = input_get_drvdata(input); 56 struct pwm_beeper *beeper = input_get_drvdata(input);
37 unsigned long period;
38 57
39 if (type != EV_SND || value < 0) 58 if (type != EV_SND || value < 0)
40 return -EINVAL; 59 return -EINVAL;
@@ -49,22 +68,31 @@ static int pwm_beeper_event(struct input_dev *input,
49 return -EINVAL; 68 return -EINVAL;
50 } 69 }
51 70
52 if (value == 0) { 71 if (value == 0)
53 pwm_disable(beeper->pwm); 72 beeper->period = 0;
54 } else { 73 else
55 period = HZ_TO_NANOSECONDS(value); 74 beeper->period = HZ_TO_NANOSECONDS(value);
56 ret = pwm_config(beeper->pwm, period / 2, period); 75
57 if (ret) 76 schedule_work(&beeper->work);
58 return ret;
59 ret = pwm_enable(beeper->pwm);
60 if (ret)
61 return ret;
62 beeper->period = period;
63 }
64 77
65 return 0; 78 return 0;
66} 79}
67 80
81static void pwm_beeper_stop(struct pwm_beeper *beeper)
82{
83 cancel_work_sync(&beeper->work);
84
85 if (beeper->period)
86 pwm_disable(beeper->pwm);
87}
88
89static void pwm_beeper_close(struct input_dev *input)
90{
91 struct pwm_beeper *beeper = input_get_drvdata(input);
92
93 pwm_beeper_stop(beeper);
94}
95
68static int pwm_beeper_probe(struct platform_device *pdev) 96static int pwm_beeper_probe(struct platform_device *pdev)
69{ 97{
70 unsigned long pwm_id = (unsigned long)dev_get_platdata(&pdev->dev); 98 unsigned long pwm_id = (unsigned long)dev_get_platdata(&pdev->dev);
@@ -93,6 +121,8 @@ static int pwm_beeper_probe(struct platform_device *pdev)
93 */ 121 */
94 pwm_apply_args(beeper->pwm); 122 pwm_apply_args(beeper->pwm);
95 123
124 INIT_WORK(&beeper->work, pwm_beeper_work);
125
96 beeper->input = input_allocate_device(); 126 beeper->input = input_allocate_device();
97 if (!beeper->input) { 127 if (!beeper->input) {
98 dev_err(&pdev->dev, "Failed to allocate input device\n"); 128 dev_err(&pdev->dev, "Failed to allocate input device\n");
@@ -112,6 +142,7 @@ static int pwm_beeper_probe(struct platform_device *pdev)
112 beeper->input->sndbit[0] = BIT(SND_TONE) | BIT(SND_BELL); 142 beeper->input->sndbit[0] = BIT(SND_TONE) | BIT(SND_BELL);
113 143
114 beeper->input->event = pwm_beeper_event; 144 beeper->input->event = pwm_beeper_event;
145 beeper->input->close = pwm_beeper_close;
115 146
116 input_set_drvdata(beeper->input, beeper); 147 input_set_drvdata(beeper->input, beeper);
117 148
@@ -141,7 +172,6 @@ static int pwm_beeper_remove(struct platform_device *pdev)
141 172
142 input_unregister_device(beeper->input); 173 input_unregister_device(beeper->input);
143 174
144 pwm_disable(beeper->pwm);
145 pwm_free(beeper->pwm); 175 pwm_free(beeper->pwm);
146 176
147 kfree(beeper); 177 kfree(beeper);
@@ -153,8 +183,7 @@ static int __maybe_unused pwm_beeper_suspend(struct device *dev)
153{ 183{
154 struct pwm_beeper *beeper = dev_get_drvdata(dev); 184 struct pwm_beeper *beeper = dev_get_drvdata(dev);
155 185
156 if (beeper->period) 186 pwm_beeper_stop(beeper);
157 pwm_disable(beeper->pwm);
158 187
159 return 0; 188 return 0;
160} 189}
@@ -163,10 +192,8 @@ static int __maybe_unused pwm_beeper_resume(struct device *dev)
163{ 192{
164 struct pwm_beeper *beeper = dev_get_drvdata(dev); 193 struct pwm_beeper *beeper = dev_get_drvdata(dev);
165 194
166 if (beeper->period) { 195 if (beeper->period)
167 pwm_config(beeper->pwm, beeper->period / 2, beeper->period); 196 __pwm_beeper_set(beeper);
168 pwm_enable(beeper->pwm);
169 }
170 197
171 return 0; 198 return 0;
172} 199}
diff --git a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c
index abe1a927b332..65ebbd111702 100644
--- a/drivers/input/misc/uinput.c
+++ b/drivers/input/misc/uinput.c
@@ -981,9 +981,15 @@ static long uinput_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
981} 981}
982 982
983#ifdef CONFIG_COMPAT 983#ifdef CONFIG_COMPAT
984
985#define UI_SET_PHYS_COMPAT _IOW(UINPUT_IOCTL_BASE, 108, compat_uptr_t)
986
984static long uinput_compat_ioctl(struct file *file, 987static long uinput_compat_ioctl(struct file *file,
985 unsigned int cmd, unsigned long arg) 988 unsigned int cmd, unsigned long arg)
986{ 989{
990 if (cmd == UI_SET_PHYS_COMPAT)
991 cmd = UI_SET_PHYS;
992
987 return uinput_ioctl_handler(file, cmd, arg, compat_ptr(arg)); 993 return uinput_ioctl_handler(file, cmd, arg, compat_ptr(arg));
988} 994}
989#endif 995#endif