xref: /linux/drivers/hid/hid-sony.c (revision 0da8ea6581d59f523880e7856bccfb35d33cffdf)
1bd28ce00SJiri Slaby /*
2078328daSJiri Kosina  *  HID driver for Sony / PS2 / PS3 BD devices.
3bd28ce00SJiri Slaby  *
4bd28ce00SJiri Slaby  *  Copyright (c) 1999 Andreas Gal
5bd28ce00SJiri Slaby  *  Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz>
6bd28ce00SJiri Slaby  *  Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc
7bd28ce00SJiri Slaby  *  Copyright (c) 2008 Jiri Slaby
8078328daSJiri Kosina  *  Copyright (c) 2012 David Dillow <dave@thedillows.org>
9078328daSJiri Kosina  *  Copyright (c) 2006-2013 Jiri Kosina
10f04d5140SColin Leitner  *  Copyright (c) 2013 Colin Leitner <colin.leitner@gmail.com>
11bd28ce00SJiri Slaby  */
12bd28ce00SJiri Slaby 
13bd28ce00SJiri Slaby /*
14bd28ce00SJiri Slaby  * This program is free software; you can redistribute it and/or modify it
15bd28ce00SJiri Slaby  * under the terms of the GNU General Public License as published by the Free
16bd28ce00SJiri Slaby  * Software Foundation; either version 2 of the License, or (at your option)
17bd28ce00SJiri Slaby  * any later version.
18bd28ce00SJiri Slaby  */
19bd28ce00SJiri Slaby 
20078328daSJiri Kosina /* NOTE: in order for the Sony PS3 BD Remote Control to be found by
21078328daSJiri Kosina  * a Bluetooth host, the key combination Start+Enter has to be kept pressed
22078328daSJiri Kosina  * for about 7 seconds with the Bluetooth Host Controller in discovering mode.
23078328daSJiri Kosina  *
24078328daSJiri Kosina  * There will be no PIN request from the device.
25078328daSJiri Kosina  */
26078328daSJiri Kosina 
27bd28ce00SJiri Slaby #include <linux/device.h>
28bd28ce00SJiri Slaby #include <linux/hid.h>
29bd28ce00SJiri Slaby #include <linux/module.h>
305a0e3ad6STejun Heo #include <linux/slab.h>
31bd28ce00SJiri Slaby #include <linux/usb.h>
3240e32ee6SJiri Kosina #include <linux/leds.h>
33bd28ce00SJiri Slaby 
34bd28ce00SJiri Slaby #include "hid-ids.h"
35bd28ce00SJiri Slaby 
36f1c458caSSven Eckelmann #define VAIO_RDESC_CONSTANT     BIT(0)
37f1c458caSSven Eckelmann #define SIXAXIS_CONTROLLER_USB  BIT(1)
38f1c458caSSven Eckelmann #define SIXAXIS_CONTROLLER_BT   BIT(2)
39f1c458caSSven Eckelmann #define BUZZ_CONTROLLER         BIT(3)
40f1c458caSSven Eckelmann #define PS3REMOTE		BIT(4)
418ab1676bSFrank Praznik #define DUALSHOCK4_CONTROLLER_USB BIT(5)
428ab1676bSFrank Praznik #define DUALSHOCK4_CONTROLLER_BT  BIT(6)
43cc6e0bbbSJiri Kosina 
448ab1676bSFrank Praznik #define SONY_LED_SUPPORT (SIXAXIS_CONTROLLER_USB | BUZZ_CONTROLLER | DUALSHOCK4_CONTROLLER_USB)
4560781cf4SFrank Praznik 
4660781cf4SFrank Praznik #define MAX_LEDS 4
470a286ef2SSven Eckelmann 
4861ab44beSSimon Wood static const u8 sixaxis_rdesc_fixup[] = {
4961ab44beSSimon Wood 	0x95, 0x13, 0x09, 0x01, 0x81, 0x02, 0x95, 0x0C,
5061ab44beSSimon Wood 	0x81, 0x01, 0x75, 0x10, 0x95, 0x04, 0x26, 0xFF,
5161ab44beSSimon Wood 	0x03, 0x46, 0xFF, 0x03, 0x09, 0x01, 0x81, 0x02
5261ab44beSSimon Wood };
5361ab44beSSimon Wood 
54e57a67daSMauro Carvalho Chehab static const u8 sixaxis_rdesc_fixup2[] = {
55e57a67daSMauro Carvalho Chehab 	0x05, 0x01, 0x09, 0x04, 0xa1, 0x01, 0xa1, 0x02,
56e57a67daSMauro Carvalho Chehab 	0x85, 0x01, 0x75, 0x08, 0x95, 0x01, 0x15, 0x00,
57e57a67daSMauro Carvalho Chehab 	0x26, 0xff, 0x00, 0x81, 0x03, 0x75, 0x01, 0x95,
58e57a67daSMauro Carvalho Chehab 	0x13, 0x15, 0x00, 0x25, 0x01, 0x35, 0x00, 0x45,
59e57a67daSMauro Carvalho Chehab 	0x01, 0x05, 0x09, 0x19, 0x01, 0x29, 0x13, 0x81,
60e57a67daSMauro Carvalho Chehab 	0x02, 0x75, 0x01, 0x95, 0x0d, 0x06, 0x00, 0xff,
61e57a67daSMauro Carvalho Chehab 	0x81, 0x03, 0x15, 0x00, 0x26, 0xff, 0x00, 0x05,
62e57a67daSMauro Carvalho Chehab 	0x01, 0x09, 0x01, 0xa1, 0x00, 0x75, 0x08, 0x95,
63e57a67daSMauro Carvalho Chehab 	0x04, 0x35, 0x00, 0x46, 0xff, 0x00, 0x09, 0x30,
64e57a67daSMauro Carvalho Chehab 	0x09, 0x31, 0x09, 0x32, 0x09, 0x35, 0x81, 0x02,
65e57a67daSMauro Carvalho Chehab 	0xc0, 0x05, 0x01, 0x95, 0x13, 0x09, 0x01, 0x81,
66e57a67daSMauro Carvalho Chehab 	0x02, 0x95, 0x0c, 0x81, 0x01, 0x75, 0x10, 0x95,
67e57a67daSMauro Carvalho Chehab 	0x04, 0x26, 0xff, 0x03, 0x46, 0xff, 0x03, 0x09,
68e57a67daSMauro Carvalho Chehab 	0x01, 0x81, 0x02, 0xc0, 0xa1, 0x02, 0x85, 0x02,
69e57a67daSMauro Carvalho Chehab 	0x75, 0x08, 0x95, 0x30, 0x09, 0x01, 0xb1, 0x02,
70e57a67daSMauro Carvalho Chehab 	0xc0, 0xa1, 0x02, 0x85, 0xee, 0x75, 0x08, 0x95,
71e57a67daSMauro Carvalho Chehab 	0x30, 0x09, 0x01, 0xb1, 0x02, 0xc0, 0xa1, 0x02,
72e57a67daSMauro Carvalho Chehab 	0x85, 0xef, 0x75, 0x08, 0x95, 0x30, 0x09, 0x01,
73e57a67daSMauro Carvalho Chehab 	0xb1, 0x02, 0xc0, 0xc0,
74e57a67daSMauro Carvalho Chehab };
75e57a67daSMauro Carvalho Chehab 
76078328daSJiri Kosina static __u8 ps3remote_rdesc[] = {
77078328daSJiri Kosina 	0x05, 0x01,          /* GUsagePage Generic Desktop */
78078328daSJiri Kosina 	0x09, 0x05,          /* LUsage 0x05 [Game Pad] */
79078328daSJiri Kosina 	0xA1, 0x01,          /* MCollection Application (mouse, keyboard) */
80078328daSJiri Kosina 
81078328daSJiri Kosina 	 /* Use collection 1 for joypad buttons */
82078328daSJiri Kosina 	 0xA1, 0x02,         /* MCollection Logical (interrelated data) */
83078328daSJiri Kosina 
84078328daSJiri Kosina 	  /* Ignore the 1st byte, maybe it is used for a controller
85078328daSJiri Kosina 	   * number but it's not needed for correct operation */
86078328daSJiri Kosina 	  0x75, 0x08,        /* GReportSize 0x08 [8] */
87078328daSJiri Kosina 	  0x95, 0x01,        /* GReportCount 0x01 [1] */
88078328daSJiri Kosina 	  0x81, 0x01,        /* MInput 0x01 (Const[0] Arr[1] Abs[2]) */
89078328daSJiri Kosina 
90078328daSJiri Kosina 	  /* Bytes from 2nd to 4th are a bitmap for joypad buttons, for these
91078328daSJiri Kosina 	   * buttons multiple keypresses are allowed */
92078328daSJiri Kosina 	  0x05, 0x09,        /* GUsagePage Button */
93078328daSJiri Kosina 	  0x19, 0x01,        /* LUsageMinimum 0x01 [Button 1 (primary/trigger)] */
94078328daSJiri Kosina 	  0x29, 0x18,        /* LUsageMaximum 0x18 [Button 24] */
95078328daSJiri Kosina 	  0x14,              /* GLogicalMinimum [0] */
96078328daSJiri Kosina 	  0x25, 0x01,        /* GLogicalMaximum 0x01 [1] */
97078328daSJiri Kosina 	  0x75, 0x01,        /* GReportSize 0x01 [1] */
98078328daSJiri Kosina 	  0x95, 0x18,        /* GReportCount 0x18 [24] */
99078328daSJiri Kosina 	  0x81, 0x02,        /* MInput 0x02 (Data[0] Var[1] Abs[2]) */
100078328daSJiri Kosina 
101078328daSJiri Kosina 	  0xC0,              /* MEndCollection */
102078328daSJiri Kosina 
103078328daSJiri Kosina 	 /* Use collection 2 for remote control buttons */
104078328daSJiri Kosina 	 0xA1, 0x02,         /* MCollection Logical (interrelated data) */
105078328daSJiri Kosina 
106078328daSJiri Kosina 	  /* 5th byte is used for remote control buttons */
107078328daSJiri Kosina 	  0x05, 0x09,        /* GUsagePage Button */
108078328daSJiri Kosina 	  0x18,              /* LUsageMinimum [No button pressed] */
109078328daSJiri Kosina 	  0x29, 0xFE,        /* LUsageMaximum 0xFE [Button 254] */
110078328daSJiri Kosina 	  0x14,              /* GLogicalMinimum [0] */
111078328daSJiri Kosina 	  0x26, 0xFE, 0x00,  /* GLogicalMaximum 0x00FE [254] */
112078328daSJiri Kosina 	  0x75, 0x08,        /* GReportSize 0x08 [8] */
113078328daSJiri Kosina 	  0x95, 0x01,        /* GReportCount 0x01 [1] */
114078328daSJiri Kosina 	  0x80,              /* MInput  */
115078328daSJiri Kosina 
116078328daSJiri Kosina 	  /* Ignore bytes from 6th to 11th, 6th to 10th are always constant at
117078328daSJiri Kosina 	   * 0xff and 11th is for press indication */
118078328daSJiri Kosina 	  0x75, 0x08,        /* GReportSize 0x08 [8] */
119078328daSJiri Kosina 	  0x95, 0x06,        /* GReportCount 0x06 [6] */
120078328daSJiri Kosina 	  0x81, 0x01,        /* MInput 0x01 (Const[0] Arr[1] Abs[2]) */
121078328daSJiri Kosina 
122078328daSJiri Kosina 	  /* 12th byte is for battery strength */
123078328daSJiri Kosina 	  0x05, 0x06,        /* GUsagePage Generic Device Controls */
124078328daSJiri Kosina 	  0x09, 0x20,        /* LUsage 0x20 [Battery Strength] */
125078328daSJiri Kosina 	  0x14,              /* GLogicalMinimum [0] */
126078328daSJiri Kosina 	  0x25, 0x05,        /* GLogicalMaximum 0x05 [5] */
127078328daSJiri Kosina 	  0x75, 0x08,        /* GReportSize 0x08 [8] */
128078328daSJiri Kosina 	  0x95, 0x01,        /* GReportCount 0x01 [1] */
129078328daSJiri Kosina 	  0x81, 0x02,        /* MInput 0x02 (Data[0] Var[1] Abs[2]) */
130078328daSJiri Kosina 
131078328daSJiri Kosina 	  0xC0,              /* MEndCollection */
132078328daSJiri Kosina 
133078328daSJiri Kosina 	 0xC0                /* MEndCollection [Game Pad] */
134078328daSJiri Kosina };
135078328daSJiri Kosina 
136078328daSJiri Kosina static const unsigned int ps3remote_keymap_joypad_buttons[] = {
137078328daSJiri Kosina 	[0x01] = KEY_SELECT,
138078328daSJiri Kosina 	[0x02] = BTN_THUMBL,		/* L3 */
139078328daSJiri Kosina 	[0x03] = BTN_THUMBR,		/* R3 */
140078328daSJiri Kosina 	[0x04] = BTN_START,
141078328daSJiri Kosina 	[0x05] = KEY_UP,
142078328daSJiri Kosina 	[0x06] = KEY_RIGHT,
143078328daSJiri Kosina 	[0x07] = KEY_DOWN,
144078328daSJiri Kosina 	[0x08] = KEY_LEFT,
145078328daSJiri Kosina 	[0x09] = BTN_TL2,		/* L2 */
146078328daSJiri Kosina 	[0x0a] = BTN_TR2,		/* R2 */
147078328daSJiri Kosina 	[0x0b] = BTN_TL,		/* L1 */
148078328daSJiri Kosina 	[0x0c] = BTN_TR,		/* R1 */
149078328daSJiri Kosina 	[0x0d] = KEY_OPTION,		/* options/triangle */
150078328daSJiri Kosina 	[0x0e] = KEY_BACK,		/* back/circle */
151078328daSJiri Kosina 	[0x0f] = BTN_0,			/* cross */
152078328daSJiri Kosina 	[0x10] = KEY_SCREEN,		/* view/square */
153078328daSJiri Kosina 	[0x11] = KEY_HOMEPAGE,		/* PS button */
154078328daSJiri Kosina 	[0x14] = KEY_ENTER,
155078328daSJiri Kosina };
156078328daSJiri Kosina static const unsigned int ps3remote_keymap_remote_buttons[] = {
157078328daSJiri Kosina 	[0x00] = KEY_1,
158078328daSJiri Kosina 	[0x01] = KEY_2,
159078328daSJiri Kosina 	[0x02] = KEY_3,
160078328daSJiri Kosina 	[0x03] = KEY_4,
161078328daSJiri Kosina 	[0x04] = KEY_5,
162078328daSJiri Kosina 	[0x05] = KEY_6,
163078328daSJiri Kosina 	[0x06] = KEY_7,
164078328daSJiri Kosina 	[0x07] = KEY_8,
165078328daSJiri Kosina 	[0x08] = KEY_9,
166078328daSJiri Kosina 	[0x09] = KEY_0,
167078328daSJiri Kosina 	[0x0e] = KEY_ESC,		/* return */
168078328daSJiri Kosina 	[0x0f] = KEY_CLEAR,
169078328daSJiri Kosina 	[0x16] = KEY_EJECTCD,
170078328daSJiri Kosina 	[0x1a] = KEY_MENU,		/* top menu */
171078328daSJiri Kosina 	[0x28] = KEY_TIME,
172078328daSJiri Kosina 	[0x30] = KEY_PREVIOUS,
173078328daSJiri Kosina 	[0x31] = KEY_NEXT,
174078328daSJiri Kosina 	[0x32] = KEY_PLAY,
175078328daSJiri Kosina 	[0x33] = KEY_REWIND,		/* scan back */
176078328daSJiri Kosina 	[0x34] = KEY_FORWARD,		/* scan forward */
177078328daSJiri Kosina 	[0x38] = KEY_STOP,
178078328daSJiri Kosina 	[0x39] = KEY_PAUSE,
179078328daSJiri Kosina 	[0x40] = KEY_CONTEXT_MENU,	/* pop up/menu */
180078328daSJiri Kosina 	[0x60] = KEY_FRAMEBACK,		/* slow/step back */
181078328daSJiri Kosina 	[0x61] = KEY_FRAMEFORWARD,	/* slow/step forward */
182078328daSJiri Kosina 	[0x63] = KEY_SUBTITLE,
183078328daSJiri Kosina 	[0x64] = KEY_AUDIO,
184078328daSJiri Kosina 	[0x65] = KEY_ANGLE,
185078328daSJiri Kosina 	[0x70] = KEY_INFO,		/* display */
186078328daSJiri Kosina 	[0x80] = KEY_BLUE,
187078328daSJiri Kosina 	[0x81] = KEY_RED,
188078328daSJiri Kosina 	[0x82] = KEY_GREEN,
189078328daSJiri Kosina 	[0x83] = KEY_YELLOW,
190078328daSJiri Kosina };
191078328daSJiri Kosina 
192f04d5140SColin Leitner static const unsigned int buzz_keymap[] = {
193f04d5140SColin Leitner 	/* The controller has 4 remote buzzers, each with one LED and 5
194f04d5140SColin Leitner 	 * buttons.
195f04d5140SColin Leitner 	 *
196f04d5140SColin Leitner 	 * We use the mapping chosen by the controller, which is:
197f04d5140SColin Leitner 	 *
198f04d5140SColin Leitner 	 * Key          Offset
199f04d5140SColin Leitner 	 * -------------------
200f04d5140SColin Leitner 	 * Buzz              1
201f04d5140SColin Leitner 	 * Blue              5
202f04d5140SColin Leitner 	 * Orange            4
203f04d5140SColin Leitner 	 * Green             3
204f04d5140SColin Leitner 	 * Yellow            2
205f04d5140SColin Leitner 	 *
206f04d5140SColin Leitner 	 * So, for example, the orange button on the third buzzer is mapped to
207f04d5140SColin Leitner 	 * BTN_TRIGGER_HAPPY14
208f04d5140SColin Leitner 	 */
209f04d5140SColin Leitner 	[ 1] = BTN_TRIGGER_HAPPY1,
210f04d5140SColin Leitner 	[ 2] = BTN_TRIGGER_HAPPY2,
211f04d5140SColin Leitner 	[ 3] = BTN_TRIGGER_HAPPY3,
212f04d5140SColin Leitner 	[ 4] = BTN_TRIGGER_HAPPY4,
213f04d5140SColin Leitner 	[ 5] = BTN_TRIGGER_HAPPY5,
214f04d5140SColin Leitner 	[ 6] = BTN_TRIGGER_HAPPY6,
215f04d5140SColin Leitner 	[ 7] = BTN_TRIGGER_HAPPY7,
216f04d5140SColin Leitner 	[ 8] = BTN_TRIGGER_HAPPY8,
217f04d5140SColin Leitner 	[ 9] = BTN_TRIGGER_HAPPY9,
218f04d5140SColin Leitner 	[10] = BTN_TRIGGER_HAPPY10,
219f04d5140SColin Leitner 	[11] = BTN_TRIGGER_HAPPY11,
220f04d5140SColin Leitner 	[12] = BTN_TRIGGER_HAPPY12,
221f04d5140SColin Leitner 	[13] = BTN_TRIGGER_HAPPY13,
222f04d5140SColin Leitner 	[14] = BTN_TRIGGER_HAPPY14,
223f04d5140SColin Leitner 	[15] = BTN_TRIGGER_HAPPY15,
224f04d5140SColin Leitner 	[16] = BTN_TRIGGER_HAPPY16,
225f04d5140SColin Leitner 	[17] = BTN_TRIGGER_HAPPY17,
226f04d5140SColin Leitner 	[18] = BTN_TRIGGER_HAPPY18,
227f04d5140SColin Leitner 	[19] = BTN_TRIGGER_HAPPY19,
228f04d5140SColin Leitner 	[20] = BTN_TRIGGER_HAPPY20,
229f04d5140SColin Leitner };
230f04d5140SColin Leitner 
231cc6e0bbbSJiri Kosina struct sony_sc {
2320a286ef2SSven Eckelmann 	struct hid_device *hdev;
23360781cf4SFrank Praznik 	struct led_classdev *leds[MAX_LEDS];
234cc6e0bbbSJiri Kosina 	unsigned long quirks;
2350a286ef2SSven Eckelmann 	struct work_struct state_worker;
236f04d5140SColin Leitner 
2379f323b68SSven Eckelmann #ifdef CONFIG_SONY_FF
2389f323b68SSven Eckelmann 	__u8 left;
2399f323b68SSven Eckelmann 	__u8 right;
2409f323b68SSven Eckelmann #endif
2419f323b68SSven Eckelmann 
24260781cf4SFrank Praznik 	__u8 led_state[MAX_LEDS];
24360781cf4SFrank Praznik 	__u8 led_count;
244cc6e0bbbSJiri Kosina };
245cc6e0bbbSJiri Kosina 
246078328daSJiri Kosina static __u8 *ps3remote_fixup(struct hid_device *hdev, __u8 *rdesc,
247078328daSJiri Kosina 			     unsigned int *rsize)
248078328daSJiri Kosina {
249078328daSJiri Kosina 	*rsize = sizeof(ps3remote_rdesc);
250078328daSJiri Kosina 	return ps3remote_rdesc;
251078328daSJiri Kosina }
252078328daSJiri Kosina 
253078328daSJiri Kosina static int ps3remote_mapping(struct hid_device *hdev, struct hid_input *hi,
254078328daSJiri Kosina 			     struct hid_field *field, struct hid_usage *usage,
255078328daSJiri Kosina 			     unsigned long **bit, int *max)
256078328daSJiri Kosina {
257078328daSJiri Kosina 	unsigned int key = usage->hid & HID_USAGE;
258078328daSJiri Kosina 
259078328daSJiri Kosina 	if ((usage->hid & HID_USAGE_PAGE) != HID_UP_BUTTON)
260078328daSJiri Kosina 		return -1;
261078328daSJiri Kosina 
262078328daSJiri Kosina 	switch (usage->collection_index) {
263078328daSJiri Kosina 	case 1:
264078328daSJiri Kosina 		if (key >= ARRAY_SIZE(ps3remote_keymap_joypad_buttons))
265078328daSJiri Kosina 			return -1;
266078328daSJiri Kosina 
267078328daSJiri Kosina 		key = ps3remote_keymap_joypad_buttons[key];
268078328daSJiri Kosina 		if (!key)
269078328daSJiri Kosina 			return -1;
270078328daSJiri Kosina 		break;
271078328daSJiri Kosina 	case 2:
272078328daSJiri Kosina 		if (key >= ARRAY_SIZE(ps3remote_keymap_remote_buttons))
273078328daSJiri Kosina 			return -1;
274078328daSJiri Kosina 
275078328daSJiri Kosina 		key = ps3remote_keymap_remote_buttons[key];
276078328daSJiri Kosina 		if (!key)
277078328daSJiri Kosina 			return -1;
278078328daSJiri Kosina 		break;
279078328daSJiri Kosina 	default:
280078328daSJiri Kosina 		return -1;
281078328daSJiri Kosina 	}
282078328daSJiri Kosina 
283078328daSJiri Kosina 	hid_map_usage_clear(hi, usage, bit, max, EV_KEY, key);
284078328daSJiri Kosina 	return 1;
285078328daSJiri Kosina }
286078328daSJiri Kosina 
287078328daSJiri Kosina 
288cc6e0bbbSJiri Kosina /* Sony Vaio VGX has wrongly mouse pointer declared as constant */
28973e4008dSNikolai Kondrashov static __u8 *sony_report_fixup(struct hid_device *hdev, __u8 *rdesc,
29073e4008dSNikolai Kondrashov 		unsigned int *rsize)
291cc6e0bbbSJiri Kosina {
292cc6e0bbbSJiri Kosina 	struct sony_sc *sc = hid_get_drvdata(hdev);
293cc6e0bbbSJiri Kosina 
29499d24902SFernando Luis Vázquez Cao 	/*
29599d24902SFernando Luis Vázquez Cao 	 * Some Sony RF receivers wrongly declare the mouse pointer as a
29699d24902SFernando Luis Vázquez Cao 	 * a constant non-data variable.
29799d24902SFernando Luis Vázquez Cao 	 */
29899d24902SFernando Luis Vázquez Cao 	if ((sc->quirks & VAIO_RDESC_CONSTANT) && *rsize >= 56 &&
29999d24902SFernando Luis Vázquez Cao 	    /* usage page: generic desktop controls */
30099d24902SFernando Luis Vázquez Cao 	    /* rdesc[0] == 0x05 && rdesc[1] == 0x01 && */
30199d24902SFernando Luis Vázquez Cao 	    /* usage: mouse */
30299d24902SFernando Luis Vázquez Cao 	    rdesc[2] == 0x09 && rdesc[3] == 0x02 &&
30399d24902SFernando Luis Vázquez Cao 	    /* input (usage page for x,y axes): constant, variable, relative */
30499d24902SFernando Luis Vázquez Cao 	    rdesc[54] == 0x81 && rdesc[55] == 0x07) {
305a4649184SFernando Luis Vázquez Cao 		hid_info(hdev, "Fixing up Sony RF Receiver report descriptor\n");
30699d24902SFernando Luis Vázquez Cao 		/* input: data, variable, relative */
307cc6e0bbbSJiri Kosina 		rdesc[55] = 0x06;
308cc6e0bbbSJiri Kosina 	}
30961ab44beSSimon Wood 
31061ab44beSSimon Wood 	/* The HID descriptor exposed over BT has a trailing zero byte */
31161ab44beSSimon Wood 	if ((((sc->quirks & SIXAXIS_CONTROLLER_USB) && *rsize == 148) ||
31261ab44beSSimon Wood 			((sc->quirks & SIXAXIS_CONTROLLER_BT) && *rsize == 149)) &&
31361ab44beSSimon Wood 			rdesc[83] == 0x75) {
31461ab44beSSimon Wood 		hid_info(hdev, "Fixing up Sony Sixaxis report descriptor\n");
31561ab44beSSimon Wood 		memcpy((void *)&rdesc[83], (void *)&sixaxis_rdesc_fixup,
31661ab44beSSimon Wood 			sizeof(sixaxis_rdesc_fixup));
317e57a67daSMauro Carvalho Chehab 	} else if (sc->quirks & SIXAXIS_CONTROLLER_USB &&
318e57a67daSMauro Carvalho Chehab 		   *rsize > sizeof(sixaxis_rdesc_fixup2)) {
319e57a67daSMauro Carvalho Chehab 		hid_info(hdev, "Sony Sixaxis clone detected. Using original report descriptor (size: %d clone; %d new)\n",
320e57a67daSMauro Carvalho Chehab 			 *rsize, (int)sizeof(sixaxis_rdesc_fixup2));
321e57a67daSMauro Carvalho Chehab 		*rsize = sizeof(sixaxis_rdesc_fixup2);
322e57a67daSMauro Carvalho Chehab 		memcpy(rdesc, &sixaxis_rdesc_fixup2, *rsize);
32361ab44beSSimon Wood 	}
324078328daSJiri Kosina 
325078328daSJiri Kosina 	if (sc->quirks & PS3REMOTE)
326078328daSJiri Kosina 		return ps3remote_fixup(hdev, rdesc, rsize);
327078328daSJiri Kosina 
32873e4008dSNikolai Kondrashov 	return rdesc;
329cc6e0bbbSJiri Kosina }
330cc6e0bbbSJiri Kosina 
331c9e4d877SSimon Wood static int sony_raw_event(struct hid_device *hdev, struct hid_report *report,
332c9e4d877SSimon Wood 		__u8 *rd, int size)
333c9e4d877SSimon Wood {
334c9e4d877SSimon Wood 	struct sony_sc *sc = hid_get_drvdata(hdev);
335c9e4d877SSimon Wood 
336c9e4d877SSimon Wood 	/* Sixaxis HID report has acclerometers/gyro with MSByte first, this
337c9e4d877SSimon Wood 	 * has to be BYTE_SWAPPED before passing up to joystick interface
338c9e4d877SSimon Wood 	 */
339c9e4d877SSimon Wood 	if ((sc->quirks & (SIXAXIS_CONTROLLER_USB | SIXAXIS_CONTROLLER_BT)) &&
340c9e4d877SSimon Wood 			rd[0] == 0x01 && size == 49) {
341c9e4d877SSimon Wood 		swap(rd[41], rd[42]);
342c9e4d877SSimon Wood 		swap(rd[43], rd[44]);
343c9e4d877SSimon Wood 		swap(rd[45], rd[46]);
344c9e4d877SSimon Wood 		swap(rd[47], rd[48]);
345c9e4d877SSimon Wood 	}
346c9e4d877SSimon Wood 
347c9e4d877SSimon Wood 	return 0;
348c9e4d877SSimon Wood }
349c9e4d877SSimon Wood 
350f04d5140SColin Leitner static int sony_mapping(struct hid_device *hdev, struct hid_input *hi,
351f04d5140SColin Leitner 			struct hid_field *field, struct hid_usage *usage,
352f04d5140SColin Leitner 			unsigned long **bit, int *max)
353f04d5140SColin Leitner {
354f04d5140SColin Leitner 	struct sony_sc *sc = hid_get_drvdata(hdev);
355f04d5140SColin Leitner 
356f04d5140SColin Leitner 	if (sc->quirks & BUZZ_CONTROLLER) {
357f04d5140SColin Leitner 		unsigned int key = usage->hid & HID_USAGE;
358f04d5140SColin Leitner 
359f04d5140SColin Leitner 		if ((usage->hid & HID_USAGE_PAGE) != HID_UP_BUTTON)
360f04d5140SColin Leitner 			return -1;
361f04d5140SColin Leitner 
362f04d5140SColin Leitner 		switch (usage->collection_index) {
363f04d5140SColin Leitner 		case 1:
364f04d5140SColin Leitner 			if (key >= ARRAY_SIZE(buzz_keymap))
365f04d5140SColin Leitner 				return -1;
366f04d5140SColin Leitner 
367f04d5140SColin Leitner 			key = buzz_keymap[key];
368f04d5140SColin Leitner 			if (!key)
369f04d5140SColin Leitner 				return -1;
370f04d5140SColin Leitner 			break;
371f04d5140SColin Leitner 		default:
372f04d5140SColin Leitner 			return -1;
373f04d5140SColin Leitner 		}
374f04d5140SColin Leitner 
375f04d5140SColin Leitner 		hid_map_usage_clear(hi, usage, bit, max, EV_KEY, key);
376f04d5140SColin Leitner 		return 1;
377f04d5140SColin Leitner 	}
378f04d5140SColin Leitner 
379078328daSJiri Kosina 	if (sc->quirks & PS3REMOTE)
380078328daSJiri Kosina 		return ps3remote_mapping(hdev, hi, field, usage, bit, max);
381078328daSJiri Kosina 
3826f498018SBenjamin Tissoires 	/* Let hid-core decide for the others */
3836f498018SBenjamin Tissoires 	return 0;
384f04d5140SColin Leitner }
385f04d5140SColin Leitner 
3865710fabfSAntonio Ospite /*
3875710fabfSAntonio Ospite  * The Sony Sixaxis does not handle HID Output Reports on the Interrupt EP
3885710fabfSAntonio Ospite  * like it should according to usbhid/hid-core.c::usbhid_output_raw_report()
3895710fabfSAntonio Ospite  * so we need to override that forcing HID Output Reports on the Control EP.
3905710fabfSAntonio Ospite  *
3915710fabfSAntonio Ospite  * There is also another issue about HID Output Reports via USB, the Sixaxis
3925710fabfSAntonio Ospite  * does not want the report_id as part of the data packet, so we have to
3935710fabfSAntonio Ospite  * discard buf[0] when sending the actual control message, even for numbered
3945710fabfSAntonio Ospite  * reports, humpf!
3955710fabfSAntonio Ospite  */
396569b10a5SAntonio Ospite static int sixaxis_usb_output_raw_report(struct hid_device *hid, __u8 *buf,
397569b10a5SAntonio Ospite 		size_t count, unsigned char report_type)
398569b10a5SAntonio Ospite {
399569b10a5SAntonio Ospite 	struct usb_interface *intf = to_usb_interface(hid->dev.parent);
400569b10a5SAntonio Ospite 	struct usb_device *dev = interface_to_usbdev(intf);
401569b10a5SAntonio Ospite 	struct usb_host_interface *interface = intf->cur_altsetting;
402569b10a5SAntonio Ospite 	int report_id = buf[0];
403569b10a5SAntonio Ospite 	int ret;
404569b10a5SAntonio Ospite 
4055710fabfSAntonio Ospite 	if (report_type == HID_OUTPUT_REPORT) {
4065710fabfSAntonio Ospite 		/* Don't send the Report ID */
4075710fabfSAntonio Ospite 		buf++;
4085710fabfSAntonio Ospite 		count--;
4095710fabfSAntonio Ospite 	}
4105710fabfSAntonio Ospite 
411569b10a5SAntonio Ospite 	ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
412569b10a5SAntonio Ospite 		HID_REQ_SET_REPORT,
413569b10a5SAntonio Ospite 		USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
414569b10a5SAntonio Ospite 		((report_type + 1) << 8) | report_id,
415569b10a5SAntonio Ospite 		interface->desc.bInterfaceNumber, buf, count,
416569b10a5SAntonio Ospite 		USB_CTRL_SET_TIMEOUT);
417569b10a5SAntonio Ospite 
4185710fabfSAntonio Ospite 	/* Count also the Report ID, in case of an Output report. */
4195710fabfSAntonio Ospite 	if (ret > 0 && report_type == HID_OUTPUT_REPORT)
4205710fabfSAntonio Ospite 		ret++;
4215710fabfSAntonio Ospite 
422569b10a5SAntonio Ospite 	return ret;
423569b10a5SAntonio Ospite }
424569b10a5SAntonio Ospite 
425bd28ce00SJiri Slaby /*
426bd28ce00SJiri Slaby  * Sending HID_REQ_GET_REPORT changes the operation mode of the ps3 controller
427bd28ce00SJiri Slaby  * to "operational".  Without this, the ps3 controller will not report any
428bd28ce00SJiri Slaby  * events.
429bd28ce00SJiri Slaby  */
430816651a7SAntonio Ospite static int sixaxis_set_operational_usb(struct hid_device *hdev)
431bd28ce00SJiri Slaby {
432bd28ce00SJiri Slaby 	int ret;
433bd28ce00SJiri Slaby 	char *buf = kmalloc(18, GFP_KERNEL);
434bd28ce00SJiri Slaby 
435bd28ce00SJiri Slaby 	if (!buf)
436bd28ce00SJiri Slaby 		return -ENOMEM;
437bd28ce00SJiri Slaby 
438f204828aSBenjamin Tissoires 	ret = hdev->hid_get_raw_report(hdev, 0xf2, buf, 17, HID_FEATURE_REPORT);
439f204828aSBenjamin Tissoires 
440bd28ce00SJiri Slaby 	if (ret < 0)
4414291ee30SJoe Perches 		hid_err(hdev, "can't set operational mode\n");
442bd28ce00SJiri Slaby 
443bd28ce00SJiri Slaby 	kfree(buf);
444bd28ce00SJiri Slaby 
445bd28ce00SJiri Slaby 	return ret;
446bd28ce00SJiri Slaby }
447bd28ce00SJiri Slaby 
448816651a7SAntonio Ospite static int sixaxis_set_operational_bt(struct hid_device *hdev)
449f9ce7c28SBastien Nocera {
450fddb33f2SAntonio Ospite 	unsigned char buf[] = { 0xf4,  0x42, 0x03, 0x00, 0x00 };
451f9ce7c28SBastien Nocera 	return hdev->hid_output_raw_report(hdev, buf, sizeof(buf), HID_FEATURE_REPORT);
452f9ce7c28SBastien Nocera }
453f9ce7c28SBastien Nocera 
45460781cf4SFrank Praznik static void buzz_set_leds(struct hid_device *hdev, const __u8 *leds)
455f04d5140SColin Leitner {
456f04d5140SColin Leitner 	struct list_head *report_list =
457f04d5140SColin Leitner 		&hdev->report_enum[HID_OUTPUT_REPORT].report_list;
458f04d5140SColin Leitner 	struct hid_report *report = list_entry(report_list->next,
459f04d5140SColin Leitner 		struct hid_report, list);
460f04d5140SColin Leitner 	__s32 *value = report->field[0]->value;
461f04d5140SColin Leitner 
462f04d5140SColin Leitner 	value[0] = 0x00;
46360781cf4SFrank Praznik 	value[1] = leds[0] ? 0xff : 0x00;
46460781cf4SFrank Praznik 	value[2] = leds[1] ? 0xff : 0x00;
46560781cf4SFrank Praznik 	value[3] = leds[2] ? 0xff : 0x00;
46660781cf4SFrank Praznik 	value[4] = leds[3] ? 0xff : 0x00;
467f04d5140SColin Leitner 	value[5] = 0x00;
468f04d5140SColin Leitner 	value[6] = 0x00;
469f04d5140SColin Leitner 	hid_hw_request(hdev, report, HID_REQ_SET_REPORT);
470f04d5140SColin Leitner }
471f04d5140SColin Leitner 
47260781cf4SFrank Praznik static void sony_set_leds(struct hid_device *hdev, const __u8 *leds, int count)
4730a286ef2SSven Eckelmann {
4740a286ef2SSven Eckelmann 	struct sony_sc *drv_data = hid_get_drvdata(hdev);
47560781cf4SFrank Praznik 	int n;
4760a286ef2SSven Eckelmann 
47760781cf4SFrank Praznik 	BUG_ON(count > MAX_LEDS);
47860781cf4SFrank Praznik 
47960781cf4SFrank Praznik 	if (drv_data->quirks & BUZZ_CONTROLLER && count == 4) {
4800a286ef2SSven Eckelmann 		buzz_set_leds(hdev, leds);
48160781cf4SFrank Praznik 	} else if ((drv_data->quirks & SIXAXIS_CONTROLLER_USB) ||
4828ab1676bSFrank Praznik 		   (drv_data->quirks & DUALSHOCK4_CONTROLLER_USB)) {
48360781cf4SFrank Praznik 		for (n = 0; n < count; n++)
48460781cf4SFrank Praznik 			drv_data->led_state[n] = leds[n];
4850a286ef2SSven Eckelmann 		schedule_work(&drv_data->state_worker);
4860a286ef2SSven Eckelmann 	}
4870a286ef2SSven Eckelmann }
4880a286ef2SSven Eckelmann 
489c5382519SSven Eckelmann static void sony_led_set_brightness(struct led_classdev *led,
490f04d5140SColin Leitner 				    enum led_brightness value)
491f04d5140SColin Leitner {
492f04d5140SColin Leitner 	struct device *dev = led->dev->parent;
493f04d5140SColin Leitner 	struct hid_device *hdev = container_of(dev, struct hid_device, dev);
494f04d5140SColin Leitner 	struct sony_sc *drv_data;
495f04d5140SColin Leitner 
496f04d5140SColin Leitner 	int n;
497f04d5140SColin Leitner 
498f04d5140SColin Leitner 	drv_data = hid_get_drvdata(hdev);
4992251b85fSSven Eckelmann 	if (!drv_data) {
500f04d5140SColin Leitner 		hid_err(hdev, "No device data\n");
501f04d5140SColin Leitner 		return;
502f04d5140SColin Leitner 	}
503f04d5140SColin Leitner 
50460781cf4SFrank Praznik 	for (n = 0; n < drv_data->led_count; n++) {
5052251b85fSSven Eckelmann 		if (led == drv_data->leds[n]) {
50660781cf4SFrank Praznik 			if (value != drv_data->led_state[n]) {
50760781cf4SFrank Praznik 				drv_data->led_state[n] = value;
50860781cf4SFrank Praznik 				sony_set_leds(hdev, drv_data->led_state, drv_data->led_count);
509f04d5140SColin Leitner 			}
510f04d5140SColin Leitner 			break;
511f04d5140SColin Leitner 		}
512f04d5140SColin Leitner 	}
513f04d5140SColin Leitner }
514f04d5140SColin Leitner 
515c5382519SSven Eckelmann static enum led_brightness sony_led_get_brightness(struct led_classdev *led)
516f04d5140SColin Leitner {
517f04d5140SColin Leitner 	struct device *dev = led->dev->parent;
518f04d5140SColin Leitner 	struct hid_device *hdev = container_of(dev, struct hid_device, dev);
519f04d5140SColin Leitner 	struct sony_sc *drv_data;
520f04d5140SColin Leitner 
521f04d5140SColin Leitner 	int n;
522f04d5140SColin Leitner 	int on = 0;
523f04d5140SColin Leitner 
524f04d5140SColin Leitner 	drv_data = hid_get_drvdata(hdev);
5252251b85fSSven Eckelmann 	if (!drv_data) {
526f04d5140SColin Leitner 		hid_err(hdev, "No device data\n");
527f04d5140SColin Leitner 		return LED_OFF;
528f04d5140SColin Leitner 	}
529f04d5140SColin Leitner 
53060781cf4SFrank Praznik 	for (n = 0; n < drv_data->led_count; n++) {
5312251b85fSSven Eckelmann 		if (led == drv_data->leds[n]) {
53260781cf4SFrank Praznik 			on = !!(drv_data->led_state[n]);
533f04d5140SColin Leitner 			break;
534f04d5140SColin Leitner 		}
535f04d5140SColin Leitner 	}
536f04d5140SColin Leitner 
537f04d5140SColin Leitner 	return on ? LED_FULL : LED_OFF;
538f04d5140SColin Leitner }
539f04d5140SColin Leitner 
5400a286ef2SSven Eckelmann static void sony_leds_remove(struct hid_device *hdev)
5410a286ef2SSven Eckelmann {
5420a286ef2SSven Eckelmann 	struct sony_sc *drv_data;
5430a286ef2SSven Eckelmann 	struct led_classdev *led;
5440a286ef2SSven Eckelmann 	int n;
5450a286ef2SSven Eckelmann 
5460a286ef2SSven Eckelmann 	drv_data = hid_get_drvdata(hdev);
5470a286ef2SSven Eckelmann 	BUG_ON(!(drv_data->quirks & SONY_LED_SUPPORT));
5480a286ef2SSven Eckelmann 
54960781cf4SFrank Praznik 	for (n = 0; n < drv_data->led_count; n++) {
5500a286ef2SSven Eckelmann 		led = drv_data->leds[n];
5510a286ef2SSven Eckelmann 		drv_data->leds[n] = NULL;
5520a286ef2SSven Eckelmann 		if (!led)
5530a286ef2SSven Eckelmann 			continue;
5540a286ef2SSven Eckelmann 		led_classdev_unregister(led);
5550a286ef2SSven Eckelmann 		kfree(led);
5560a286ef2SSven Eckelmann 	}
55760781cf4SFrank Praznik 
55860781cf4SFrank Praznik 	drv_data->led_count = 0;
5590a286ef2SSven Eckelmann }
5600a286ef2SSven Eckelmann 
561c5382519SSven Eckelmann static int sony_leds_init(struct hid_device *hdev)
562f04d5140SColin Leitner {
563f04d5140SColin Leitner 	struct sony_sc *drv_data;
56440e32ee6SJiri Kosina 	int n, ret = 0;
56560781cf4SFrank Praznik 	int max_brightness;
56640e32ee6SJiri Kosina 	struct led_classdev *led;
56740e32ee6SJiri Kosina 	size_t name_sz;
56840e32ee6SJiri Kosina 	char *name;
5690a286ef2SSven Eckelmann 	size_t name_len;
5700a286ef2SSven Eckelmann 	const char *name_fmt;
57160781cf4SFrank Praznik 	static const __u8 initial_values[MAX_LEDS] = { 0x00, 0x00, 0x00, 0x00 };
572f04d5140SColin Leitner 
573f04d5140SColin Leitner 	drv_data = hid_get_drvdata(hdev);
5740a286ef2SSven Eckelmann 	BUG_ON(!(drv_data->quirks & SONY_LED_SUPPORT));
575f04d5140SColin Leitner 
5760a286ef2SSven Eckelmann 	if (drv_data->quirks & BUZZ_CONTROLLER) {
5770a286ef2SSven Eckelmann 		name_len = strlen("::buzz#");
5780a286ef2SSven Eckelmann 		name_fmt = "%s::buzz%d";
5799446edb9SKees Cook 		/* Validate expected report characteristics. */
5809446edb9SKees Cook 		if (!hid_validate_values(hdev, HID_OUTPUT_REPORT, 0, 0, 7))
5819446edb9SKees Cook 			return -ENODEV;
5820a286ef2SSven Eckelmann 	} else {
5830a286ef2SSven Eckelmann 		name_len = strlen("::sony#");
5840a286ef2SSven Eckelmann 		name_fmt = "%s::sony%d";
5850a286ef2SSven Eckelmann 	}
5869446edb9SKees Cook 
5878ab1676bSFrank Praznik 	if (drv_data->quirks & DUALSHOCK4_CONTROLLER_USB) {
58860781cf4SFrank Praznik 		drv_data->led_count = 3;
58960781cf4SFrank Praznik 		max_brightness = 255;
59060781cf4SFrank Praznik 	} else {
59160781cf4SFrank Praznik 		drv_data->led_count = 4;
59260781cf4SFrank Praznik 		max_brightness = 1;
59360781cf4SFrank Praznik 	}
59460781cf4SFrank Praznik 
595f04d5140SColin Leitner 	/* Clear LEDs as we have no way of reading their initial state. This is
596f04d5140SColin Leitner 	 * only relevant if the driver is loaded after somebody actively set the
597f04d5140SColin Leitner 	 * LEDs to on */
59860781cf4SFrank Praznik 	sony_set_leds(hdev, initial_values, drv_data->led_count);
599f04d5140SColin Leitner 
6000a286ef2SSven Eckelmann 	name_sz = strlen(dev_name(&hdev->dev)) + name_len + 1;
601f04d5140SColin Leitner 
60260781cf4SFrank Praznik 	for (n = 0; n < drv_data->led_count; n++) {
603f04d5140SColin Leitner 		led = kzalloc(sizeof(struct led_classdev) + name_sz, GFP_KERNEL);
604f04d5140SColin Leitner 		if (!led) {
605f04d5140SColin Leitner 			hid_err(hdev, "Couldn't allocate memory for LED %d\n", n);
6068cd5fcdaSJulia Lawall 			ret = -ENOMEM;
607f04d5140SColin Leitner 			goto error_leds;
608f04d5140SColin Leitner 		}
609f04d5140SColin Leitner 
610f04d5140SColin Leitner 		name = (void *)(&led[1]);
6110a286ef2SSven Eckelmann 		snprintf(name, name_sz, name_fmt, dev_name(&hdev->dev), n + 1);
612f04d5140SColin Leitner 		led->name = name;
613f04d5140SColin Leitner 		led->brightness = 0;
61460781cf4SFrank Praznik 		led->max_brightness = max_brightness;
615c5382519SSven Eckelmann 		led->brightness_get = sony_led_get_brightness;
616c5382519SSven Eckelmann 		led->brightness_set = sony_led_set_brightness;
617f04d5140SColin Leitner 
6188cd5fcdaSJulia Lawall 		ret = led_classdev_register(&hdev->dev, led);
6198cd5fcdaSJulia Lawall 		if (ret) {
620f04d5140SColin Leitner 			hid_err(hdev, "Failed to register LED %d\n", n);
621f04d5140SColin Leitner 			kfree(led);
622f04d5140SColin Leitner 			goto error_leds;
623f04d5140SColin Leitner 		}
624f04d5140SColin Leitner 
6252251b85fSSven Eckelmann 		drv_data->leds[n] = led;
626f04d5140SColin Leitner 	}
627f04d5140SColin Leitner 
628f04d5140SColin Leitner 	return ret;
629f04d5140SColin Leitner 
630f04d5140SColin Leitner error_leds:
6310a286ef2SSven Eckelmann 	sony_leds_remove(hdev);
632f04d5140SColin Leitner 
633f04d5140SColin Leitner 	return ret;
634f04d5140SColin Leitner }
635f04d5140SColin Leitner 
636cad665a2SFrank Praznik static void sixaxis_state_worker(struct work_struct *work)
637a08c22c0SSven Eckelmann {
63892b5c411SSven Eckelmann 	struct sony_sc *sc = container_of(work, struct sony_sc, state_worker);
639a08c22c0SSven Eckelmann 	unsigned char buf[] = {
640a08c22c0SSven Eckelmann 		0x01,
641a08c22c0SSven Eckelmann 		0x00, 0xff, 0x00, 0xff, 0x00,
6420a286ef2SSven Eckelmann 		0x00, 0x00, 0x00, 0x00, 0x00,
643a08c22c0SSven Eckelmann 		0xff, 0x27, 0x10, 0x00, 0x32,
644a08c22c0SSven Eckelmann 		0xff, 0x27, 0x10, 0x00, 0x32,
645a08c22c0SSven Eckelmann 		0xff, 0x27, 0x10, 0x00, 0x32,
646a08c22c0SSven Eckelmann 		0xff, 0x27, 0x10, 0x00, 0x32,
647a08c22c0SSven Eckelmann 		0x00, 0x00, 0x00, 0x00, 0x00
648a08c22c0SSven Eckelmann 	};
6499f323b68SSven Eckelmann 
6500a286ef2SSven Eckelmann #ifdef CONFIG_SONY_FF
6510bd88dd3SFrank Praznik 	buf[3] = sc->right ? 1 : 0;
6529f323b68SSven Eckelmann 	buf[5] = sc->left;
6530a286ef2SSven Eckelmann #endif
6540a286ef2SSven Eckelmann 
65560781cf4SFrank Praznik 	buf[10] |= sc->led_state[0] << 1;
65660781cf4SFrank Praznik 	buf[10] |= sc->led_state[1] << 2;
65760781cf4SFrank Praznik 	buf[10] |= sc->led_state[2] << 3;
65860781cf4SFrank Praznik 	buf[10] |= sc->led_state[3] << 4;
6599f323b68SSven Eckelmann 
6609f323b68SSven Eckelmann 	sc->hdev->hid_output_raw_report(sc->hdev, buf, sizeof(buf),
6619f323b68SSven Eckelmann 					HID_OUTPUT_REPORT);
6629f323b68SSven Eckelmann }
6639f323b68SSven Eckelmann 
6640bd88dd3SFrank Praznik static void dualshock4_state_worker(struct work_struct *work)
6650bd88dd3SFrank Praznik {
6660bd88dd3SFrank Praznik 	struct sony_sc *sc = container_of(work, struct sony_sc, state_worker);
667*0da8ea65SFrank Praznik 	struct hid_device *hdev = sc->hdev;
668*0da8ea65SFrank Praznik 	struct list_head *head, *list;
669*0da8ea65SFrank Praznik 	struct hid_report *report;
670*0da8ea65SFrank Praznik 	__s32 *value;
671*0da8ea65SFrank Praznik 
672*0da8ea65SFrank Praznik 	list = &hdev->report_enum[HID_OUTPUT_REPORT].report_list;
673*0da8ea65SFrank Praznik 
674*0da8ea65SFrank Praznik 	list_for_each(head, list) {
675*0da8ea65SFrank Praznik 		report = list_entry(head, struct hid_report, list);
676*0da8ea65SFrank Praznik 
677*0da8ea65SFrank Praznik 		/* Report 5 is used to send data to the controller via USB */
678*0da8ea65SFrank Praznik 		if ((sc->quirks & DUALSHOCK4_CONTROLLER_USB) && report->id == 5)
679*0da8ea65SFrank Praznik 			break;
680*0da8ea65SFrank Praznik 	}
681*0da8ea65SFrank Praznik 
682*0da8ea65SFrank Praznik 	if (head == list) {
683*0da8ea65SFrank Praznik 		hid_err(hdev, "Dualshock 4 output report not found\n");
684*0da8ea65SFrank Praznik 		return;
685*0da8ea65SFrank Praznik 	}
686*0da8ea65SFrank Praznik 
687*0da8ea65SFrank Praznik 	value = report->field[0]->value;
688*0da8ea65SFrank Praznik 	value[0] = 0x03;
6890bd88dd3SFrank Praznik 
6900bd88dd3SFrank Praznik #ifdef CONFIG_SONY_FF
691*0da8ea65SFrank Praznik 	value[3] = sc->right;
692*0da8ea65SFrank Praznik 	value[4] = sc->left;
6930bd88dd3SFrank Praznik #endif
6940bd88dd3SFrank Praznik 
695*0da8ea65SFrank Praznik 	value[5] = sc->led_state[0];
696*0da8ea65SFrank Praznik 	value[6] = sc->led_state[1];
697*0da8ea65SFrank Praznik 	value[7] = sc->led_state[2];
69860781cf4SFrank Praznik 
699*0da8ea65SFrank Praznik 	hid_hw_request(hdev, report, HID_REQ_SET_REPORT);
7000bd88dd3SFrank Praznik }
7010bd88dd3SFrank Praznik 
7020a286ef2SSven Eckelmann #ifdef CONFIG_SONY_FF
7039f323b68SSven Eckelmann static int sony_play_effect(struct input_dev *dev, void *data,
7049f323b68SSven Eckelmann 			    struct ff_effect *effect)
7059f323b68SSven Eckelmann {
706a08c22c0SSven Eckelmann 	struct hid_device *hid = input_get_drvdata(dev);
7079f323b68SSven Eckelmann 	struct sony_sc *sc = hid_get_drvdata(hid);
708a08c22c0SSven Eckelmann 
709a08c22c0SSven Eckelmann 	if (effect->type != FF_RUMBLE)
710a08c22c0SSven Eckelmann 		return 0;
711a08c22c0SSven Eckelmann 
7129f323b68SSven Eckelmann 	sc->left = effect->u.rumble.strong_magnitude / 256;
7130bd88dd3SFrank Praznik 	sc->right = effect->u.rumble.weak_magnitude / 256;
714a08c22c0SSven Eckelmann 
71592b5c411SSven Eckelmann 	schedule_work(&sc->state_worker);
7169f323b68SSven Eckelmann 	return 0;
717a08c22c0SSven Eckelmann }
718a08c22c0SSven Eckelmann 
719a08c22c0SSven Eckelmann static int sony_init_ff(struct hid_device *hdev)
720a08c22c0SSven Eckelmann {
721a08c22c0SSven Eckelmann 	struct hid_input *hidinput = list_entry(hdev->inputs.next,
722a08c22c0SSven Eckelmann 						struct hid_input, list);
723a08c22c0SSven Eckelmann 	struct input_dev *input_dev = hidinput->input;
724a08c22c0SSven Eckelmann 
725a08c22c0SSven Eckelmann 	input_set_capability(input_dev, EV_FF, FF_RUMBLE);
726a08c22c0SSven Eckelmann 	return input_ff_create_memless(input_dev, NULL, sony_play_effect);
727a08c22c0SSven Eckelmann }
728a08c22c0SSven Eckelmann 
7299f323b68SSven Eckelmann static void sony_destroy_ff(struct hid_device *hdev)
7309f323b68SSven Eckelmann {
7319f323b68SSven Eckelmann 	struct sony_sc *sc = hid_get_drvdata(hdev);
7329f323b68SSven Eckelmann 
73392b5c411SSven Eckelmann 	cancel_work_sync(&sc->state_worker);
7349f323b68SSven Eckelmann }
7359f323b68SSven Eckelmann 
736a08c22c0SSven Eckelmann #else
737a08c22c0SSven Eckelmann static int sony_init_ff(struct hid_device *hdev)
738a08c22c0SSven Eckelmann {
739a08c22c0SSven Eckelmann 	return 0;
740a08c22c0SSven Eckelmann }
7419f323b68SSven Eckelmann 
7429f323b68SSven Eckelmann static void sony_destroy_ff(struct hid_device *hdev)
7439f323b68SSven Eckelmann {
7449f323b68SSven Eckelmann }
745a08c22c0SSven Eckelmann #endif
746a08c22c0SSven Eckelmann 
747bd28ce00SJiri Slaby static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id)
748bd28ce00SJiri Slaby {
749bd28ce00SJiri Slaby 	int ret;
750cc6e0bbbSJiri Kosina 	unsigned long quirks = id->driver_data;
751cc6e0bbbSJiri Kosina 	struct sony_sc *sc;
752f04d5140SColin Leitner 	unsigned int connect_mask = HID_CONNECT_DEFAULT;
753cc6e0bbbSJiri Kosina 
754abf832bfSBenjamin Tissoires 	sc = devm_kzalloc(&hdev->dev, sizeof(*sc), GFP_KERNEL);
755cc6e0bbbSJiri Kosina 	if (sc == NULL) {
7564291ee30SJoe Perches 		hid_err(hdev, "can't alloc sony descriptor\n");
757cc6e0bbbSJiri Kosina 		return -ENOMEM;
758cc6e0bbbSJiri Kosina 	}
759cc6e0bbbSJiri Kosina 
760cc6e0bbbSJiri Kosina 	sc->quirks = quirks;
761cc6e0bbbSJiri Kosina 	hid_set_drvdata(hdev, sc);
7620a286ef2SSven Eckelmann 	sc->hdev = hdev;
763bd28ce00SJiri Slaby 
764bd28ce00SJiri Slaby 	ret = hid_parse(hdev);
765bd28ce00SJiri Slaby 	if (ret) {
7664291ee30SJoe Perches 		hid_err(hdev, "parse failed\n");
767abf832bfSBenjamin Tissoires 		return ret;
768bd28ce00SJiri Slaby 	}
769bd28ce00SJiri Slaby 
770f04d5140SColin Leitner 	if (sc->quirks & VAIO_RDESC_CONSTANT)
771f04d5140SColin Leitner 		connect_mask |= HID_CONNECT_HIDDEV_FORCE;
772f04d5140SColin Leitner 	else if (sc->quirks & SIXAXIS_CONTROLLER_USB)
773f04d5140SColin Leitner 		connect_mask |= HID_CONNECT_HIDDEV_FORCE;
774f04d5140SColin Leitner 	else if (sc->quirks & SIXAXIS_CONTROLLER_BT)
775f04d5140SColin Leitner 		connect_mask |= HID_CONNECT_HIDDEV_FORCE;
776f04d5140SColin Leitner 
777f04d5140SColin Leitner 	ret = hid_hw_start(hdev, connect_mask);
778bd28ce00SJiri Slaby 	if (ret) {
7794291ee30SJoe Perches 		hid_err(hdev, "hw start failed\n");
780abf832bfSBenjamin Tissoires 		return ret;
781bd28ce00SJiri Slaby 	}
782bd28ce00SJiri Slaby 
783569b10a5SAntonio Ospite 	if (sc->quirks & SIXAXIS_CONTROLLER_USB) {
784569b10a5SAntonio Ospite 		hdev->hid_output_raw_report = sixaxis_usb_output_raw_report;
785816651a7SAntonio Ospite 		ret = sixaxis_set_operational_usb(hdev);
786cad665a2SFrank Praznik 		INIT_WORK(&sc->state_worker, sixaxis_state_worker);
787569b10a5SAntonio Ospite 	}
788816651a7SAntonio Ospite 	else if (sc->quirks & SIXAXIS_CONTROLLER_BT)
789816651a7SAntonio Ospite 		ret = sixaxis_set_operational_bt(hdev);
7908ab1676bSFrank Praznik 	else if (sc->quirks & DUALSHOCK4_CONTROLLER_USB) {
791f9ce7c28SBastien Nocera 		ret = 0;
7920bd88dd3SFrank Praznik 		INIT_WORK(&sc->state_worker, dualshock4_state_worker);
7930bd88dd3SFrank Praznik 	} else {
7940bd88dd3SFrank Praznik 		ret = 0;
7950bd88dd3SFrank Praznik 	}
796f9ce7c28SBastien Nocera 
7974dfdc464SJiri Kosina 	if (ret < 0)
798bd28ce00SJiri Slaby 		goto err_stop;
799bd28ce00SJiri Slaby 
8000a286ef2SSven Eckelmann 	if (sc->quirks & SONY_LED_SUPPORT) {
8010a286ef2SSven Eckelmann 		ret = sony_leds_init(hdev);
8020a286ef2SSven Eckelmann 		if (ret < 0)
8030a286ef2SSven Eckelmann 			goto err_stop;
8040a286ef2SSven Eckelmann 	}
8050a286ef2SSven Eckelmann 
806a08c22c0SSven Eckelmann 	ret = sony_init_ff(hdev);
807a08c22c0SSven Eckelmann 	if (ret < 0)
808a08c22c0SSven Eckelmann 		goto err_stop;
809a08c22c0SSven Eckelmann 
810bd28ce00SJiri Slaby 	return 0;
811bd28ce00SJiri Slaby err_stop:
8120a286ef2SSven Eckelmann 	if (sc->quirks & SONY_LED_SUPPORT)
8130a286ef2SSven Eckelmann 		sony_leds_remove(hdev);
814bd28ce00SJiri Slaby 	hid_hw_stop(hdev);
815bd28ce00SJiri Slaby 	return ret;
816bd28ce00SJiri Slaby }
817bd28ce00SJiri Slaby 
818cc6e0bbbSJiri Kosina static void sony_remove(struct hid_device *hdev)
819cc6e0bbbSJiri Kosina {
820f04d5140SColin Leitner 	struct sony_sc *sc = hid_get_drvdata(hdev);
821f04d5140SColin Leitner 
8220a286ef2SSven Eckelmann 	if (sc->quirks & SONY_LED_SUPPORT)
823c5382519SSven Eckelmann 		sony_leds_remove(hdev);
824f04d5140SColin Leitner 
8259f323b68SSven Eckelmann 	sony_destroy_ff(hdev);
8269f323b68SSven Eckelmann 
827cc6e0bbbSJiri Kosina 	hid_hw_stop(hdev);
828cc6e0bbbSJiri Kosina }
829cc6e0bbbSJiri Kosina 
830bd28ce00SJiri Slaby static const struct hid_device_id sony_devices[] = {
831816651a7SAntonio Ospite 	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER),
832816651a7SAntonio Ospite 		.driver_data = SIXAXIS_CONTROLLER_USB },
83335dca5b4SJiri Kosina 	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_NAVIGATION_CONTROLLER),
83435dca5b4SJiri Kosina 		.driver_data = SIXAXIS_CONTROLLER_USB },
835816651a7SAntonio Ospite 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER),
836816651a7SAntonio Ospite 		.driver_data = SIXAXIS_CONTROLLER_BT },
837cc6e0bbbSJiri Kosina 	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE),
838cc6e0bbbSJiri Kosina 		.driver_data = VAIO_RDESC_CONSTANT },
839a4649184SFernando Luis Vázquez Cao 	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGP_MOUSE),
840a4649184SFernando Luis Vázquez Cao 		.driver_data = VAIO_RDESC_CONSTANT },
841f04d5140SColin Leitner 	/* Wired Buzz Controller. Reported as Sony Hub from its USB ID and as
842f04d5140SColin Leitner 	 * Logitech joystick from the device descriptor. */
843f04d5140SColin Leitner 	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_BUZZ_CONTROLLER),
844f04d5140SColin Leitner 		.driver_data = BUZZ_CONTROLLER },
845f04d5140SColin Leitner 	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_WIRELESS_BUZZ_CONTROLLER),
846f04d5140SColin Leitner 		.driver_data = BUZZ_CONTROLLER },
847078328daSJiri Kosina 	/* PS3 BD Remote Control */
848078328daSJiri Kosina 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_BDREMOTE),
849078328daSJiri Kosina 		.driver_data = PS3REMOTE },
850078328daSJiri Kosina 	/* Logitech Harmony Adapter for PS3 */
851078328daSJiri Kosina 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_PS3),
852078328daSJiri Kosina 		.driver_data = PS3REMOTE },
8530bd88dd3SFrank Praznik 	/* Sony Dualshock 4 controllers for PS4 */
8540bd88dd3SFrank Praznik 	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS4_CONTROLLER),
8558ab1676bSFrank Praznik 		.driver_data = DUALSHOCK4_CONTROLLER_USB },
8560bd88dd3SFrank Praznik 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS4_CONTROLLER),
8578ab1676bSFrank Praznik 		.driver_data = DUALSHOCK4_CONTROLLER_BT },
858bd28ce00SJiri Slaby 	{ }
859bd28ce00SJiri Slaby };
860bd28ce00SJiri Slaby MODULE_DEVICE_TABLE(hid, sony_devices);
861bd28ce00SJiri Slaby 
862bd28ce00SJiri Slaby static struct hid_driver sony_driver = {
863bd28ce00SJiri Slaby 	.name          = "sony",
864bd28ce00SJiri Slaby 	.id_table      = sony_devices,
865f04d5140SColin Leitner 	.input_mapping = sony_mapping,
866bd28ce00SJiri Slaby 	.probe         = sony_probe,
867cc6e0bbbSJiri Kosina 	.remove        = sony_remove,
868cc6e0bbbSJiri Kosina 	.report_fixup  = sony_report_fixup,
869c9e4d877SSimon Wood 	.raw_event     = sony_raw_event
870bd28ce00SJiri Slaby };
871f425458eSH Hartley Sweeten module_hid_driver(sony_driver);
872bd28ce00SJiri Slaby 
873bd28ce00SJiri Slaby MODULE_LICENSE("GPL");
874