xref: /linux/drivers/hid/hid-sony.c (revision abf832bfc349b54fd500f1e3b612f7f3cd9dfcc6)
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 
36816651a7SAntonio Ospite #define VAIO_RDESC_CONSTANT     (1 << 0)
37816651a7SAntonio Ospite #define SIXAXIS_CONTROLLER_USB  (1 << 1)
38816651a7SAntonio Ospite #define SIXAXIS_CONTROLLER_BT   (1 << 2)
39f04d5140SColin Leitner #define BUZZ_CONTROLLER         (1 << 3)
40078328daSJiri Kosina #define PS3REMOTE		(1 << 4)
41cc6e0bbbSJiri Kosina 
4261ab44beSSimon Wood static const u8 sixaxis_rdesc_fixup[] = {
4361ab44beSSimon Wood 	0x95, 0x13, 0x09, 0x01, 0x81, 0x02, 0x95, 0x0C,
4461ab44beSSimon Wood 	0x81, 0x01, 0x75, 0x10, 0x95, 0x04, 0x26, 0xFF,
4561ab44beSSimon Wood 	0x03, 0x46, 0xFF, 0x03, 0x09, 0x01, 0x81, 0x02
4661ab44beSSimon Wood };
4761ab44beSSimon Wood 
48e57a67daSMauro Carvalho Chehab static const u8 sixaxis_rdesc_fixup2[] = {
49e57a67daSMauro Carvalho Chehab 	0x05, 0x01, 0x09, 0x04, 0xa1, 0x01, 0xa1, 0x02,
50e57a67daSMauro Carvalho Chehab 	0x85, 0x01, 0x75, 0x08, 0x95, 0x01, 0x15, 0x00,
51e57a67daSMauro Carvalho Chehab 	0x26, 0xff, 0x00, 0x81, 0x03, 0x75, 0x01, 0x95,
52e57a67daSMauro Carvalho Chehab 	0x13, 0x15, 0x00, 0x25, 0x01, 0x35, 0x00, 0x45,
53e57a67daSMauro Carvalho Chehab 	0x01, 0x05, 0x09, 0x19, 0x01, 0x29, 0x13, 0x81,
54e57a67daSMauro Carvalho Chehab 	0x02, 0x75, 0x01, 0x95, 0x0d, 0x06, 0x00, 0xff,
55e57a67daSMauro Carvalho Chehab 	0x81, 0x03, 0x15, 0x00, 0x26, 0xff, 0x00, 0x05,
56e57a67daSMauro Carvalho Chehab 	0x01, 0x09, 0x01, 0xa1, 0x00, 0x75, 0x08, 0x95,
57e57a67daSMauro Carvalho Chehab 	0x04, 0x35, 0x00, 0x46, 0xff, 0x00, 0x09, 0x30,
58e57a67daSMauro Carvalho Chehab 	0x09, 0x31, 0x09, 0x32, 0x09, 0x35, 0x81, 0x02,
59e57a67daSMauro Carvalho Chehab 	0xc0, 0x05, 0x01, 0x95, 0x13, 0x09, 0x01, 0x81,
60e57a67daSMauro Carvalho Chehab 	0x02, 0x95, 0x0c, 0x81, 0x01, 0x75, 0x10, 0x95,
61e57a67daSMauro Carvalho Chehab 	0x04, 0x26, 0xff, 0x03, 0x46, 0xff, 0x03, 0x09,
62e57a67daSMauro Carvalho Chehab 	0x01, 0x81, 0x02, 0xc0, 0xa1, 0x02, 0x85, 0x02,
63e57a67daSMauro Carvalho Chehab 	0x75, 0x08, 0x95, 0x30, 0x09, 0x01, 0xb1, 0x02,
64e57a67daSMauro Carvalho Chehab 	0xc0, 0xa1, 0x02, 0x85, 0xee, 0x75, 0x08, 0x95,
65e57a67daSMauro Carvalho Chehab 	0x30, 0x09, 0x01, 0xb1, 0x02, 0xc0, 0xa1, 0x02,
66e57a67daSMauro Carvalho Chehab 	0x85, 0xef, 0x75, 0x08, 0x95, 0x30, 0x09, 0x01,
67e57a67daSMauro Carvalho Chehab 	0xb1, 0x02, 0xc0, 0xc0,
68e57a67daSMauro Carvalho Chehab };
69e57a67daSMauro Carvalho Chehab 
70078328daSJiri Kosina static __u8 ps3remote_rdesc[] = {
71078328daSJiri Kosina 	0x05, 0x01,          /* GUsagePage Generic Desktop */
72078328daSJiri Kosina 	0x09, 0x05,          /* LUsage 0x05 [Game Pad] */
73078328daSJiri Kosina 	0xA1, 0x01,          /* MCollection Application (mouse, keyboard) */
74078328daSJiri Kosina 
75078328daSJiri Kosina 	 /* Use collection 1 for joypad buttons */
76078328daSJiri Kosina 	 0xA1, 0x02,         /* MCollection Logical (interrelated data) */
77078328daSJiri Kosina 
78078328daSJiri Kosina 	  /* Ignore the 1st byte, maybe it is used for a controller
79078328daSJiri Kosina 	   * number but it's not needed for correct operation */
80078328daSJiri Kosina 	  0x75, 0x08,        /* GReportSize 0x08 [8] */
81078328daSJiri Kosina 	  0x95, 0x01,        /* GReportCount 0x01 [1] */
82078328daSJiri Kosina 	  0x81, 0x01,        /* MInput 0x01 (Const[0] Arr[1] Abs[2]) */
83078328daSJiri Kosina 
84078328daSJiri Kosina 	  /* Bytes from 2nd to 4th are a bitmap for joypad buttons, for these
85078328daSJiri Kosina 	   * buttons multiple keypresses are allowed */
86078328daSJiri Kosina 	  0x05, 0x09,        /* GUsagePage Button */
87078328daSJiri Kosina 	  0x19, 0x01,        /* LUsageMinimum 0x01 [Button 1 (primary/trigger)] */
88078328daSJiri Kosina 	  0x29, 0x18,        /* LUsageMaximum 0x18 [Button 24] */
89078328daSJiri Kosina 	  0x14,              /* GLogicalMinimum [0] */
90078328daSJiri Kosina 	  0x25, 0x01,        /* GLogicalMaximum 0x01 [1] */
91078328daSJiri Kosina 	  0x75, 0x01,        /* GReportSize 0x01 [1] */
92078328daSJiri Kosina 	  0x95, 0x18,        /* GReportCount 0x18 [24] */
93078328daSJiri Kosina 	  0x81, 0x02,        /* MInput 0x02 (Data[0] Var[1] Abs[2]) */
94078328daSJiri Kosina 
95078328daSJiri Kosina 	  0xC0,              /* MEndCollection */
96078328daSJiri Kosina 
97078328daSJiri Kosina 	 /* Use collection 2 for remote control buttons */
98078328daSJiri Kosina 	 0xA1, 0x02,         /* MCollection Logical (interrelated data) */
99078328daSJiri Kosina 
100078328daSJiri Kosina 	  /* 5th byte is used for remote control buttons */
101078328daSJiri Kosina 	  0x05, 0x09,        /* GUsagePage Button */
102078328daSJiri Kosina 	  0x18,              /* LUsageMinimum [No button pressed] */
103078328daSJiri Kosina 	  0x29, 0xFE,        /* LUsageMaximum 0xFE [Button 254] */
104078328daSJiri Kosina 	  0x14,              /* GLogicalMinimum [0] */
105078328daSJiri Kosina 	  0x26, 0xFE, 0x00,  /* GLogicalMaximum 0x00FE [254] */
106078328daSJiri Kosina 	  0x75, 0x08,        /* GReportSize 0x08 [8] */
107078328daSJiri Kosina 	  0x95, 0x01,        /* GReportCount 0x01 [1] */
108078328daSJiri Kosina 	  0x80,              /* MInput  */
109078328daSJiri Kosina 
110078328daSJiri Kosina 	  /* Ignore bytes from 6th to 11th, 6th to 10th are always constant at
111078328daSJiri Kosina 	   * 0xff and 11th is for press indication */
112078328daSJiri Kosina 	  0x75, 0x08,        /* GReportSize 0x08 [8] */
113078328daSJiri Kosina 	  0x95, 0x06,        /* GReportCount 0x06 [6] */
114078328daSJiri Kosina 	  0x81, 0x01,        /* MInput 0x01 (Const[0] Arr[1] Abs[2]) */
115078328daSJiri Kosina 
116078328daSJiri Kosina 	  /* 12th byte is for battery strength */
117078328daSJiri Kosina 	  0x05, 0x06,        /* GUsagePage Generic Device Controls */
118078328daSJiri Kosina 	  0x09, 0x20,        /* LUsage 0x20 [Battery Strength] */
119078328daSJiri Kosina 	  0x14,              /* GLogicalMinimum [0] */
120078328daSJiri Kosina 	  0x25, 0x05,        /* GLogicalMaximum 0x05 [5] */
121078328daSJiri Kosina 	  0x75, 0x08,        /* GReportSize 0x08 [8] */
122078328daSJiri Kosina 	  0x95, 0x01,        /* GReportCount 0x01 [1] */
123078328daSJiri Kosina 	  0x81, 0x02,        /* MInput 0x02 (Data[0] Var[1] Abs[2]) */
124078328daSJiri Kosina 
125078328daSJiri Kosina 	  0xC0,              /* MEndCollection */
126078328daSJiri Kosina 
127078328daSJiri Kosina 	 0xC0                /* MEndCollection [Game Pad] */
128078328daSJiri Kosina };
129078328daSJiri Kosina 
130078328daSJiri Kosina static const unsigned int ps3remote_keymap_joypad_buttons[] = {
131078328daSJiri Kosina 	[0x01] = KEY_SELECT,
132078328daSJiri Kosina 	[0x02] = BTN_THUMBL,		/* L3 */
133078328daSJiri Kosina 	[0x03] = BTN_THUMBR,		/* R3 */
134078328daSJiri Kosina 	[0x04] = BTN_START,
135078328daSJiri Kosina 	[0x05] = KEY_UP,
136078328daSJiri Kosina 	[0x06] = KEY_RIGHT,
137078328daSJiri Kosina 	[0x07] = KEY_DOWN,
138078328daSJiri Kosina 	[0x08] = KEY_LEFT,
139078328daSJiri Kosina 	[0x09] = BTN_TL2,		/* L2 */
140078328daSJiri Kosina 	[0x0a] = BTN_TR2,		/* R2 */
141078328daSJiri Kosina 	[0x0b] = BTN_TL,		/* L1 */
142078328daSJiri Kosina 	[0x0c] = BTN_TR,		/* R1 */
143078328daSJiri Kosina 	[0x0d] = KEY_OPTION,		/* options/triangle */
144078328daSJiri Kosina 	[0x0e] = KEY_BACK,		/* back/circle */
145078328daSJiri Kosina 	[0x0f] = BTN_0,			/* cross */
146078328daSJiri Kosina 	[0x10] = KEY_SCREEN,		/* view/square */
147078328daSJiri Kosina 	[0x11] = KEY_HOMEPAGE,		/* PS button */
148078328daSJiri Kosina 	[0x14] = KEY_ENTER,
149078328daSJiri Kosina };
150078328daSJiri Kosina static const unsigned int ps3remote_keymap_remote_buttons[] = {
151078328daSJiri Kosina 	[0x00] = KEY_1,
152078328daSJiri Kosina 	[0x01] = KEY_2,
153078328daSJiri Kosina 	[0x02] = KEY_3,
154078328daSJiri Kosina 	[0x03] = KEY_4,
155078328daSJiri Kosina 	[0x04] = KEY_5,
156078328daSJiri Kosina 	[0x05] = KEY_6,
157078328daSJiri Kosina 	[0x06] = KEY_7,
158078328daSJiri Kosina 	[0x07] = KEY_8,
159078328daSJiri Kosina 	[0x08] = KEY_9,
160078328daSJiri Kosina 	[0x09] = KEY_0,
161078328daSJiri Kosina 	[0x0e] = KEY_ESC,		/* return */
162078328daSJiri Kosina 	[0x0f] = KEY_CLEAR,
163078328daSJiri Kosina 	[0x16] = KEY_EJECTCD,
164078328daSJiri Kosina 	[0x1a] = KEY_MENU,		/* top menu */
165078328daSJiri Kosina 	[0x28] = KEY_TIME,
166078328daSJiri Kosina 	[0x30] = KEY_PREVIOUS,
167078328daSJiri Kosina 	[0x31] = KEY_NEXT,
168078328daSJiri Kosina 	[0x32] = KEY_PLAY,
169078328daSJiri Kosina 	[0x33] = KEY_REWIND,		/* scan back */
170078328daSJiri Kosina 	[0x34] = KEY_FORWARD,		/* scan forward */
171078328daSJiri Kosina 	[0x38] = KEY_STOP,
172078328daSJiri Kosina 	[0x39] = KEY_PAUSE,
173078328daSJiri Kosina 	[0x40] = KEY_CONTEXT_MENU,	/* pop up/menu */
174078328daSJiri Kosina 	[0x60] = KEY_FRAMEBACK,		/* slow/step back */
175078328daSJiri Kosina 	[0x61] = KEY_FRAMEFORWARD,	/* slow/step forward */
176078328daSJiri Kosina 	[0x63] = KEY_SUBTITLE,
177078328daSJiri Kosina 	[0x64] = KEY_AUDIO,
178078328daSJiri Kosina 	[0x65] = KEY_ANGLE,
179078328daSJiri Kosina 	[0x70] = KEY_INFO,		/* display */
180078328daSJiri Kosina 	[0x80] = KEY_BLUE,
181078328daSJiri Kosina 	[0x81] = KEY_RED,
182078328daSJiri Kosina 	[0x82] = KEY_GREEN,
183078328daSJiri Kosina 	[0x83] = KEY_YELLOW,
184078328daSJiri Kosina };
185078328daSJiri Kosina 
186f04d5140SColin Leitner static const unsigned int buzz_keymap[] = {
187f04d5140SColin Leitner 	/* The controller has 4 remote buzzers, each with one LED and 5
188f04d5140SColin Leitner 	 * buttons.
189f04d5140SColin Leitner 	 *
190f04d5140SColin Leitner 	 * We use the mapping chosen by the controller, which is:
191f04d5140SColin Leitner 	 *
192f04d5140SColin Leitner 	 * Key          Offset
193f04d5140SColin Leitner 	 * -------------------
194f04d5140SColin Leitner 	 * Buzz              1
195f04d5140SColin Leitner 	 * Blue              5
196f04d5140SColin Leitner 	 * Orange            4
197f04d5140SColin Leitner 	 * Green             3
198f04d5140SColin Leitner 	 * Yellow            2
199f04d5140SColin Leitner 	 *
200f04d5140SColin Leitner 	 * So, for example, the orange button on the third buzzer is mapped to
201f04d5140SColin Leitner 	 * BTN_TRIGGER_HAPPY14
202f04d5140SColin Leitner 	 */
203f04d5140SColin Leitner 	[ 1] = BTN_TRIGGER_HAPPY1,
204f04d5140SColin Leitner 	[ 2] = BTN_TRIGGER_HAPPY2,
205f04d5140SColin Leitner 	[ 3] = BTN_TRIGGER_HAPPY3,
206f04d5140SColin Leitner 	[ 4] = BTN_TRIGGER_HAPPY4,
207f04d5140SColin Leitner 	[ 5] = BTN_TRIGGER_HAPPY5,
208f04d5140SColin Leitner 	[ 6] = BTN_TRIGGER_HAPPY6,
209f04d5140SColin Leitner 	[ 7] = BTN_TRIGGER_HAPPY7,
210f04d5140SColin Leitner 	[ 8] = BTN_TRIGGER_HAPPY8,
211f04d5140SColin Leitner 	[ 9] = BTN_TRIGGER_HAPPY9,
212f04d5140SColin Leitner 	[10] = BTN_TRIGGER_HAPPY10,
213f04d5140SColin Leitner 	[11] = BTN_TRIGGER_HAPPY11,
214f04d5140SColin Leitner 	[12] = BTN_TRIGGER_HAPPY12,
215f04d5140SColin Leitner 	[13] = BTN_TRIGGER_HAPPY13,
216f04d5140SColin Leitner 	[14] = BTN_TRIGGER_HAPPY14,
217f04d5140SColin Leitner 	[15] = BTN_TRIGGER_HAPPY15,
218f04d5140SColin Leitner 	[16] = BTN_TRIGGER_HAPPY16,
219f04d5140SColin Leitner 	[17] = BTN_TRIGGER_HAPPY17,
220f04d5140SColin Leitner 	[18] = BTN_TRIGGER_HAPPY18,
221f04d5140SColin Leitner 	[19] = BTN_TRIGGER_HAPPY19,
222f04d5140SColin Leitner 	[20] = BTN_TRIGGER_HAPPY20,
223f04d5140SColin Leitner };
224f04d5140SColin Leitner 
225cc6e0bbbSJiri Kosina struct sony_sc {
226cc6e0bbbSJiri Kosina 	unsigned long quirks;
227f04d5140SColin Leitner 
228f04d5140SColin Leitner 	void *extra;
229f04d5140SColin Leitner };
230f04d5140SColin Leitner 
231f04d5140SColin Leitner struct buzz_extra {
232f04d5140SColin Leitner 	int led_state;
233f04d5140SColin Leitner 	struct led_classdev *leds[4];
234cc6e0bbbSJiri Kosina };
235cc6e0bbbSJiri Kosina 
236078328daSJiri Kosina static __u8 *ps3remote_fixup(struct hid_device *hdev, __u8 *rdesc,
237078328daSJiri Kosina 			     unsigned int *rsize)
238078328daSJiri Kosina {
239078328daSJiri Kosina 	*rsize = sizeof(ps3remote_rdesc);
240078328daSJiri Kosina 	return ps3remote_rdesc;
241078328daSJiri Kosina }
242078328daSJiri Kosina 
243078328daSJiri Kosina static int ps3remote_mapping(struct hid_device *hdev, struct hid_input *hi,
244078328daSJiri Kosina 			     struct hid_field *field, struct hid_usage *usage,
245078328daSJiri Kosina 			     unsigned long **bit, int *max)
246078328daSJiri Kosina {
247078328daSJiri Kosina 	unsigned int key = usage->hid & HID_USAGE;
248078328daSJiri Kosina 
249078328daSJiri Kosina 	if ((usage->hid & HID_USAGE_PAGE) != HID_UP_BUTTON)
250078328daSJiri Kosina 		return -1;
251078328daSJiri Kosina 
252078328daSJiri Kosina 	switch (usage->collection_index) {
253078328daSJiri Kosina 	case 1:
254078328daSJiri Kosina 		if (key >= ARRAY_SIZE(ps3remote_keymap_joypad_buttons))
255078328daSJiri Kosina 			return -1;
256078328daSJiri Kosina 
257078328daSJiri Kosina 		key = ps3remote_keymap_joypad_buttons[key];
258078328daSJiri Kosina 		if (!key)
259078328daSJiri Kosina 			return -1;
260078328daSJiri Kosina 		break;
261078328daSJiri Kosina 	case 2:
262078328daSJiri Kosina 		if (key >= ARRAY_SIZE(ps3remote_keymap_remote_buttons))
263078328daSJiri Kosina 			return -1;
264078328daSJiri Kosina 
265078328daSJiri Kosina 		key = ps3remote_keymap_remote_buttons[key];
266078328daSJiri Kosina 		if (!key)
267078328daSJiri Kosina 			return -1;
268078328daSJiri Kosina 		break;
269078328daSJiri Kosina 	default:
270078328daSJiri Kosina 		return -1;
271078328daSJiri Kosina 	}
272078328daSJiri Kosina 
273078328daSJiri Kosina 	hid_map_usage_clear(hi, usage, bit, max, EV_KEY, key);
274078328daSJiri Kosina 	return 1;
275078328daSJiri Kosina }
276078328daSJiri Kosina 
277078328daSJiri Kosina 
278cc6e0bbbSJiri Kosina /* Sony Vaio VGX has wrongly mouse pointer declared as constant */
27973e4008dSNikolai Kondrashov static __u8 *sony_report_fixup(struct hid_device *hdev, __u8 *rdesc,
28073e4008dSNikolai Kondrashov 		unsigned int *rsize)
281cc6e0bbbSJiri Kosina {
282cc6e0bbbSJiri Kosina 	struct sony_sc *sc = hid_get_drvdata(hdev);
283cc6e0bbbSJiri Kosina 
28499d24902SFernando Luis Vázquez Cao 	/*
28599d24902SFernando Luis Vázquez Cao 	 * Some Sony RF receivers wrongly declare the mouse pointer as a
28699d24902SFernando Luis Vázquez Cao 	 * a constant non-data variable.
28799d24902SFernando Luis Vázquez Cao 	 */
28899d24902SFernando Luis Vázquez Cao 	if ((sc->quirks & VAIO_RDESC_CONSTANT) && *rsize >= 56 &&
28999d24902SFernando Luis Vázquez Cao 	    /* usage page: generic desktop controls */
29099d24902SFernando Luis Vázquez Cao 	    /* rdesc[0] == 0x05 && rdesc[1] == 0x01 && */
29199d24902SFernando Luis Vázquez Cao 	    /* usage: mouse */
29299d24902SFernando Luis Vázquez Cao 	    rdesc[2] == 0x09 && rdesc[3] == 0x02 &&
29399d24902SFernando Luis Vázquez Cao 	    /* input (usage page for x,y axes): constant, variable, relative */
29499d24902SFernando Luis Vázquez Cao 	    rdesc[54] == 0x81 && rdesc[55] == 0x07) {
295a4649184SFernando Luis Vázquez Cao 		hid_info(hdev, "Fixing up Sony RF Receiver report descriptor\n");
29699d24902SFernando Luis Vázquez Cao 		/* input: data, variable, relative */
297cc6e0bbbSJiri Kosina 		rdesc[55] = 0x06;
298cc6e0bbbSJiri Kosina 	}
29961ab44beSSimon Wood 
30061ab44beSSimon Wood 	/* The HID descriptor exposed over BT has a trailing zero byte */
30161ab44beSSimon Wood 	if ((((sc->quirks & SIXAXIS_CONTROLLER_USB) && *rsize == 148) ||
30261ab44beSSimon Wood 			((sc->quirks & SIXAXIS_CONTROLLER_BT) && *rsize == 149)) &&
30361ab44beSSimon Wood 			rdesc[83] == 0x75) {
30461ab44beSSimon Wood 		hid_info(hdev, "Fixing up Sony Sixaxis report descriptor\n");
30561ab44beSSimon Wood 		memcpy((void *)&rdesc[83], (void *)&sixaxis_rdesc_fixup,
30661ab44beSSimon Wood 			sizeof(sixaxis_rdesc_fixup));
307e57a67daSMauro Carvalho Chehab 	} else if (sc->quirks & SIXAXIS_CONTROLLER_USB &&
308e57a67daSMauro Carvalho Chehab 		   *rsize > sizeof(sixaxis_rdesc_fixup2)) {
309e57a67daSMauro Carvalho Chehab 		hid_info(hdev, "Sony Sixaxis clone detected. Using original report descriptor (size: %d clone; %d new)\n",
310e57a67daSMauro Carvalho Chehab 			 *rsize, (int)sizeof(sixaxis_rdesc_fixup2));
311e57a67daSMauro Carvalho Chehab 		*rsize = sizeof(sixaxis_rdesc_fixup2);
312e57a67daSMauro Carvalho Chehab 		memcpy(rdesc, &sixaxis_rdesc_fixup2, *rsize);
31361ab44beSSimon Wood 	}
314078328daSJiri Kosina 
315078328daSJiri Kosina 	if (sc->quirks & PS3REMOTE)
316078328daSJiri Kosina 		return ps3remote_fixup(hdev, rdesc, rsize);
317078328daSJiri Kosina 
31873e4008dSNikolai Kondrashov 	return rdesc;
319cc6e0bbbSJiri Kosina }
320cc6e0bbbSJiri Kosina 
321c9e4d877SSimon Wood static int sony_raw_event(struct hid_device *hdev, struct hid_report *report,
322c9e4d877SSimon Wood 		__u8 *rd, int size)
323c9e4d877SSimon Wood {
324c9e4d877SSimon Wood 	struct sony_sc *sc = hid_get_drvdata(hdev);
325c9e4d877SSimon Wood 
326c9e4d877SSimon Wood 	/* Sixaxis HID report has acclerometers/gyro with MSByte first, this
327c9e4d877SSimon Wood 	 * has to be BYTE_SWAPPED before passing up to joystick interface
328c9e4d877SSimon Wood 	 */
329c9e4d877SSimon Wood 	if ((sc->quirks & (SIXAXIS_CONTROLLER_USB | SIXAXIS_CONTROLLER_BT)) &&
330c9e4d877SSimon Wood 			rd[0] == 0x01 && size == 49) {
331c9e4d877SSimon Wood 		swap(rd[41], rd[42]);
332c9e4d877SSimon Wood 		swap(rd[43], rd[44]);
333c9e4d877SSimon Wood 		swap(rd[45], rd[46]);
334c9e4d877SSimon Wood 		swap(rd[47], rd[48]);
335c9e4d877SSimon Wood 	}
336c9e4d877SSimon Wood 
337c9e4d877SSimon Wood 	return 0;
338c9e4d877SSimon Wood }
339c9e4d877SSimon Wood 
340f04d5140SColin Leitner static int sony_mapping(struct hid_device *hdev, struct hid_input *hi,
341f04d5140SColin Leitner 			struct hid_field *field, struct hid_usage *usage,
342f04d5140SColin Leitner 			unsigned long **bit, int *max)
343f04d5140SColin Leitner {
344f04d5140SColin Leitner 	struct sony_sc *sc = hid_get_drvdata(hdev);
345f04d5140SColin Leitner 
346f04d5140SColin Leitner 	if (sc->quirks & BUZZ_CONTROLLER) {
347f04d5140SColin Leitner 		unsigned int key = usage->hid & HID_USAGE;
348f04d5140SColin Leitner 
349f04d5140SColin Leitner 		if ((usage->hid & HID_USAGE_PAGE) != HID_UP_BUTTON)
350f04d5140SColin Leitner 			return -1;
351f04d5140SColin Leitner 
352f04d5140SColin Leitner 		switch (usage->collection_index) {
353f04d5140SColin Leitner 		case 1:
354f04d5140SColin Leitner 			if (key >= ARRAY_SIZE(buzz_keymap))
355f04d5140SColin Leitner 				return -1;
356f04d5140SColin Leitner 
357f04d5140SColin Leitner 			key = buzz_keymap[key];
358f04d5140SColin Leitner 			if (!key)
359f04d5140SColin Leitner 				return -1;
360f04d5140SColin Leitner 			break;
361f04d5140SColin Leitner 		default:
362f04d5140SColin Leitner 			return -1;
363f04d5140SColin Leitner 		}
364f04d5140SColin Leitner 
365f04d5140SColin Leitner 		hid_map_usage_clear(hi, usage, bit, max, EV_KEY, key);
366f04d5140SColin Leitner 		return 1;
367f04d5140SColin Leitner 	}
368f04d5140SColin Leitner 
369078328daSJiri Kosina 	if (sc->quirks & PS3REMOTE)
370078328daSJiri Kosina 		return ps3remote_mapping(hdev, hi, field, usage, bit, max);
371078328daSJiri Kosina 
372f04d5140SColin Leitner 	return -1;
373f04d5140SColin Leitner }
374f04d5140SColin Leitner 
3755710fabfSAntonio Ospite /*
3765710fabfSAntonio Ospite  * The Sony Sixaxis does not handle HID Output Reports on the Interrupt EP
3775710fabfSAntonio Ospite  * like it should according to usbhid/hid-core.c::usbhid_output_raw_report()
3785710fabfSAntonio Ospite  * so we need to override that forcing HID Output Reports on the Control EP.
3795710fabfSAntonio Ospite  *
3805710fabfSAntonio Ospite  * There is also another issue about HID Output Reports via USB, the Sixaxis
3815710fabfSAntonio Ospite  * does not want the report_id as part of the data packet, so we have to
3825710fabfSAntonio Ospite  * discard buf[0] when sending the actual control message, even for numbered
3835710fabfSAntonio Ospite  * reports, humpf!
3845710fabfSAntonio Ospite  */
385569b10a5SAntonio Ospite static int sixaxis_usb_output_raw_report(struct hid_device *hid, __u8 *buf,
386569b10a5SAntonio Ospite 		size_t count, unsigned char report_type)
387569b10a5SAntonio Ospite {
388569b10a5SAntonio Ospite 	struct usb_interface *intf = to_usb_interface(hid->dev.parent);
389569b10a5SAntonio Ospite 	struct usb_device *dev = interface_to_usbdev(intf);
390569b10a5SAntonio Ospite 	struct usb_host_interface *interface = intf->cur_altsetting;
391569b10a5SAntonio Ospite 	int report_id = buf[0];
392569b10a5SAntonio Ospite 	int ret;
393569b10a5SAntonio Ospite 
3945710fabfSAntonio Ospite 	if (report_type == HID_OUTPUT_REPORT) {
3955710fabfSAntonio Ospite 		/* Don't send the Report ID */
3965710fabfSAntonio Ospite 		buf++;
3975710fabfSAntonio Ospite 		count--;
3985710fabfSAntonio Ospite 	}
3995710fabfSAntonio Ospite 
400569b10a5SAntonio Ospite 	ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
401569b10a5SAntonio Ospite 		HID_REQ_SET_REPORT,
402569b10a5SAntonio Ospite 		USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
403569b10a5SAntonio Ospite 		((report_type + 1) << 8) | report_id,
404569b10a5SAntonio Ospite 		interface->desc.bInterfaceNumber, buf, count,
405569b10a5SAntonio Ospite 		USB_CTRL_SET_TIMEOUT);
406569b10a5SAntonio Ospite 
4075710fabfSAntonio Ospite 	/* Count also the Report ID, in case of an Output report. */
4085710fabfSAntonio Ospite 	if (ret > 0 && report_type == HID_OUTPUT_REPORT)
4095710fabfSAntonio Ospite 		ret++;
4105710fabfSAntonio Ospite 
411569b10a5SAntonio Ospite 	return ret;
412569b10a5SAntonio Ospite }
413569b10a5SAntonio Ospite 
414bd28ce00SJiri Slaby /*
415bd28ce00SJiri Slaby  * Sending HID_REQ_GET_REPORT changes the operation mode of the ps3 controller
416bd28ce00SJiri Slaby  * to "operational".  Without this, the ps3 controller will not report any
417bd28ce00SJiri Slaby  * events.
418bd28ce00SJiri Slaby  */
419816651a7SAntonio Ospite static int sixaxis_set_operational_usb(struct hid_device *hdev)
420bd28ce00SJiri Slaby {
421bd28ce00SJiri Slaby 	struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
422bd28ce00SJiri Slaby 	struct usb_device *dev = interface_to_usbdev(intf);
423bd28ce00SJiri Slaby 	__u16 ifnum = intf->cur_altsetting->desc.bInterfaceNumber;
424bd28ce00SJiri Slaby 	int ret;
425bd28ce00SJiri Slaby 	char *buf = kmalloc(18, GFP_KERNEL);
426bd28ce00SJiri Slaby 
427bd28ce00SJiri Slaby 	if (!buf)
428bd28ce00SJiri Slaby 		return -ENOMEM;
429bd28ce00SJiri Slaby 
430bd28ce00SJiri Slaby 	ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
431bd28ce00SJiri Slaby 				 HID_REQ_GET_REPORT,
432bd28ce00SJiri Slaby 				 USB_DIR_IN | USB_TYPE_CLASS |
433bd28ce00SJiri Slaby 				 USB_RECIP_INTERFACE,
434bd28ce00SJiri Slaby 				 (3 << 8) | 0xf2, ifnum, buf, 17,
435bd28ce00SJiri Slaby 				 USB_CTRL_GET_TIMEOUT);
436bd28ce00SJiri Slaby 	if (ret < 0)
4374291ee30SJoe Perches 		hid_err(hdev, "can't set operational mode\n");
438bd28ce00SJiri Slaby 
439bd28ce00SJiri Slaby 	kfree(buf);
440bd28ce00SJiri Slaby 
441bd28ce00SJiri Slaby 	return ret;
442bd28ce00SJiri Slaby }
443bd28ce00SJiri Slaby 
444816651a7SAntonio Ospite static int sixaxis_set_operational_bt(struct hid_device *hdev)
445f9ce7c28SBastien Nocera {
446fddb33f2SAntonio Ospite 	unsigned char buf[] = { 0xf4,  0x42, 0x03, 0x00, 0x00 };
447f9ce7c28SBastien Nocera 	return hdev->hid_output_raw_report(hdev, buf, sizeof(buf), HID_FEATURE_REPORT);
448f9ce7c28SBastien Nocera }
449f9ce7c28SBastien Nocera 
450f04d5140SColin Leitner static void buzz_set_leds(struct hid_device *hdev, int leds)
451f04d5140SColin Leitner {
452f04d5140SColin Leitner 	struct list_head *report_list =
453f04d5140SColin Leitner 		&hdev->report_enum[HID_OUTPUT_REPORT].report_list;
454f04d5140SColin Leitner 	struct hid_report *report = list_entry(report_list->next,
455f04d5140SColin Leitner 		struct hid_report, list);
456f04d5140SColin Leitner 	__s32 *value = report->field[0]->value;
457f04d5140SColin Leitner 
458f04d5140SColin Leitner 	value[0] = 0x00;
459f04d5140SColin Leitner 	value[1] = (leds & 1) ? 0xff : 0x00;
460f04d5140SColin Leitner 	value[2] = (leds & 2) ? 0xff : 0x00;
461f04d5140SColin Leitner 	value[3] = (leds & 4) ? 0xff : 0x00;
462f04d5140SColin Leitner 	value[4] = (leds & 8) ? 0xff : 0x00;
463f04d5140SColin Leitner 	value[5] = 0x00;
464f04d5140SColin Leitner 	value[6] = 0x00;
465f04d5140SColin Leitner 	hid_hw_request(hdev, report, HID_REQ_SET_REPORT);
466f04d5140SColin Leitner }
467f04d5140SColin Leitner 
468f04d5140SColin Leitner static void buzz_led_set_brightness(struct led_classdev *led,
469f04d5140SColin Leitner 				    enum led_brightness value)
470f04d5140SColin Leitner {
471f04d5140SColin Leitner 	struct device *dev = led->dev->parent;
472f04d5140SColin Leitner 	struct hid_device *hdev = container_of(dev, struct hid_device, dev);
473f04d5140SColin Leitner 	struct sony_sc *drv_data;
474f04d5140SColin Leitner 	struct buzz_extra *buzz;
475f04d5140SColin Leitner 
476f04d5140SColin Leitner 	int n;
477f04d5140SColin Leitner 
478f04d5140SColin Leitner 	drv_data = hid_get_drvdata(hdev);
479f04d5140SColin Leitner 	if (!drv_data || !drv_data->extra) {
480f04d5140SColin Leitner 		hid_err(hdev, "No device data\n");
481f04d5140SColin Leitner 		return;
482f04d5140SColin Leitner 	}
483f04d5140SColin Leitner 	buzz = drv_data->extra;
484f04d5140SColin Leitner 
485f04d5140SColin Leitner 	for (n = 0; n < 4; n++) {
486f04d5140SColin Leitner 		if (led == buzz->leds[n]) {
487f04d5140SColin Leitner 			int on = !! (buzz->led_state & (1 << n));
488f04d5140SColin Leitner 			if (value == LED_OFF && on) {
489f04d5140SColin Leitner 				buzz->led_state &= ~(1 << n);
490f04d5140SColin Leitner 				buzz_set_leds(hdev, buzz->led_state);
491f04d5140SColin Leitner 			} else if (value != LED_OFF && !on) {
492f04d5140SColin Leitner 				buzz->led_state |= (1 << n);
493f04d5140SColin Leitner 				buzz_set_leds(hdev, buzz->led_state);
494f04d5140SColin Leitner 			}
495f04d5140SColin Leitner 			break;
496f04d5140SColin Leitner 		}
497f04d5140SColin Leitner 	}
498f04d5140SColin Leitner }
499f04d5140SColin Leitner 
500f04d5140SColin Leitner static enum led_brightness buzz_led_get_brightness(struct led_classdev *led)
501f04d5140SColin Leitner {
502f04d5140SColin Leitner 	struct device *dev = led->dev->parent;
503f04d5140SColin Leitner 	struct hid_device *hdev = container_of(dev, struct hid_device, dev);
504f04d5140SColin Leitner 	struct sony_sc *drv_data;
505f04d5140SColin Leitner 	struct buzz_extra *buzz;
506f04d5140SColin Leitner 
507f04d5140SColin Leitner 	int n;
508f04d5140SColin Leitner 	int on = 0;
509f04d5140SColin Leitner 
510f04d5140SColin Leitner 	drv_data = hid_get_drvdata(hdev);
511f04d5140SColin Leitner 	if (!drv_data || !drv_data->extra) {
512f04d5140SColin Leitner 		hid_err(hdev, "No device data\n");
513f04d5140SColin Leitner 		return LED_OFF;
514f04d5140SColin Leitner 	}
515f04d5140SColin Leitner 	buzz = drv_data->extra;
516f04d5140SColin Leitner 
517f04d5140SColin Leitner 	for (n = 0; n < 4; n++) {
518f04d5140SColin Leitner 		if (led == buzz->leds[n]) {
519f04d5140SColin Leitner 			on = !! (buzz->led_state & (1 << n));
520f04d5140SColin Leitner 			break;
521f04d5140SColin Leitner 		}
522f04d5140SColin Leitner 	}
523f04d5140SColin Leitner 
524f04d5140SColin Leitner 	return on ? LED_FULL : LED_OFF;
525f04d5140SColin Leitner }
526f04d5140SColin Leitner 
527f04d5140SColin Leitner static int buzz_init(struct hid_device *hdev)
528f04d5140SColin Leitner {
529f04d5140SColin Leitner 	struct sony_sc *drv_data;
530f04d5140SColin Leitner 	struct buzz_extra *buzz;
53140e32ee6SJiri Kosina 	int n, ret = 0;
53240e32ee6SJiri Kosina 	struct led_classdev *led;
53340e32ee6SJiri Kosina 	size_t name_sz;
53440e32ee6SJiri Kosina 	char *name;
535f04d5140SColin Leitner 
536f04d5140SColin Leitner 	drv_data = hid_get_drvdata(hdev);
537f04d5140SColin Leitner 	BUG_ON(!(drv_data->quirks & BUZZ_CONTROLLER));
538f04d5140SColin Leitner 
539f04d5140SColin Leitner 	buzz = kzalloc(sizeof(*buzz), GFP_KERNEL);
540f04d5140SColin Leitner 	if (!buzz) {
541f04d5140SColin Leitner 		hid_err(hdev, "Insufficient memory, cannot allocate driver data\n");
542f04d5140SColin Leitner 		return -ENOMEM;
543f04d5140SColin Leitner 	}
544f04d5140SColin Leitner 	drv_data->extra = buzz;
545f04d5140SColin Leitner 
546f04d5140SColin Leitner 	/* Clear LEDs as we have no way of reading their initial state. This is
547f04d5140SColin Leitner 	 * only relevant if the driver is loaded after somebody actively set the
548f04d5140SColin Leitner 	 * LEDs to on */
549f04d5140SColin Leitner 	buzz_set_leds(hdev, 0x00);
550f04d5140SColin Leitner 
551f04d5140SColin Leitner 	name_sz = strlen(dev_name(&hdev->dev)) + strlen("::buzz#") + 1;
552f04d5140SColin Leitner 
553f04d5140SColin Leitner 	for (n = 0; n < 4; n++) {
554f04d5140SColin Leitner 		led = kzalloc(sizeof(struct led_classdev) + name_sz, GFP_KERNEL);
555f04d5140SColin Leitner 		if (!led) {
556f04d5140SColin Leitner 			hid_err(hdev, "Couldn't allocate memory for LED %d\n", n);
557f04d5140SColin Leitner 			goto error_leds;
558f04d5140SColin Leitner 		}
559f04d5140SColin Leitner 
560f04d5140SColin Leitner 		name = (void *)(&led[1]);
561f04d5140SColin Leitner 		snprintf(name, name_sz, "%s::buzz%d", dev_name(&hdev->dev), n + 1);
562f04d5140SColin Leitner 		led->name = name;
563f04d5140SColin Leitner 		led->brightness = 0;
564f04d5140SColin Leitner 		led->max_brightness = 1;
565f04d5140SColin Leitner 		led->brightness_get = buzz_led_get_brightness;
566f04d5140SColin Leitner 		led->brightness_set = buzz_led_set_brightness;
567f04d5140SColin Leitner 
568f04d5140SColin Leitner 		if (led_classdev_register(&hdev->dev, led)) {
569f04d5140SColin Leitner 			hid_err(hdev, "Failed to register LED %d\n", n);
570f04d5140SColin Leitner 			kfree(led);
571f04d5140SColin Leitner 			goto error_leds;
572f04d5140SColin Leitner 		}
573f04d5140SColin Leitner 
574f04d5140SColin Leitner 		buzz->leds[n] = led;
575f04d5140SColin Leitner 	}
576f04d5140SColin Leitner 
577f04d5140SColin Leitner 	return ret;
578f04d5140SColin Leitner 
579f04d5140SColin Leitner error_leds:
580f04d5140SColin Leitner 	for (n = 0; n < 4; n++) {
581f04d5140SColin Leitner 		led = buzz->leds[n];
582f04d5140SColin Leitner 		buzz->leds[n] = NULL;
583f04d5140SColin Leitner 		if (!led)
584f04d5140SColin Leitner 			continue;
585f04d5140SColin Leitner 		led_classdev_unregister(led);
586f04d5140SColin Leitner 		kfree(led);
587f04d5140SColin Leitner 	}
588f04d5140SColin Leitner 
589f04d5140SColin Leitner 	kfree(drv_data->extra);
590f04d5140SColin Leitner 	drv_data->extra = NULL;
591f04d5140SColin Leitner 	return ret;
592f04d5140SColin Leitner }
593f04d5140SColin Leitner 
594f04d5140SColin Leitner static void buzz_remove(struct hid_device *hdev)
595f04d5140SColin Leitner {
596f04d5140SColin Leitner 	struct sony_sc *drv_data;
597f04d5140SColin Leitner 	struct buzz_extra *buzz;
59840e32ee6SJiri Kosina 	struct led_classdev *led;
59940e32ee6SJiri Kosina 	int n;
600f04d5140SColin Leitner 
601f04d5140SColin Leitner 	drv_data = hid_get_drvdata(hdev);
602f04d5140SColin Leitner 	BUG_ON(!(drv_data->quirks & BUZZ_CONTROLLER));
603f04d5140SColin Leitner 
604f04d5140SColin Leitner 	buzz = drv_data->extra;
605f04d5140SColin Leitner 
606f04d5140SColin Leitner 	for (n = 0; n < 4; n++) {
607f04d5140SColin Leitner 		led = buzz->leds[n];
608f04d5140SColin Leitner 		buzz->leds[n] = NULL;
609f04d5140SColin Leitner 		if (!led)
610f04d5140SColin Leitner 			continue;
611f04d5140SColin Leitner 		led_classdev_unregister(led);
612f04d5140SColin Leitner 		kfree(led);
613f04d5140SColin Leitner 	}
614f04d5140SColin Leitner 
615f04d5140SColin Leitner 	kfree(drv_data->extra);
616f04d5140SColin Leitner 	drv_data->extra = NULL;
617f04d5140SColin Leitner }
618f04d5140SColin Leitner 
619bd28ce00SJiri Slaby static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id)
620bd28ce00SJiri Slaby {
621bd28ce00SJiri Slaby 	int ret;
622cc6e0bbbSJiri Kosina 	unsigned long quirks = id->driver_data;
623cc6e0bbbSJiri Kosina 	struct sony_sc *sc;
624f04d5140SColin Leitner 	unsigned int connect_mask = HID_CONNECT_DEFAULT;
625cc6e0bbbSJiri Kosina 
626*abf832bfSBenjamin Tissoires 	sc = devm_kzalloc(&hdev->dev, sizeof(*sc), GFP_KERNEL);
627cc6e0bbbSJiri Kosina 	if (sc == NULL) {
6284291ee30SJoe Perches 		hid_err(hdev, "can't alloc sony descriptor\n");
629cc6e0bbbSJiri Kosina 		return -ENOMEM;
630cc6e0bbbSJiri Kosina 	}
631cc6e0bbbSJiri Kosina 
632cc6e0bbbSJiri Kosina 	sc->quirks = quirks;
633cc6e0bbbSJiri Kosina 	hid_set_drvdata(hdev, sc);
634bd28ce00SJiri Slaby 
635bd28ce00SJiri Slaby 	ret = hid_parse(hdev);
636bd28ce00SJiri Slaby 	if (ret) {
6374291ee30SJoe Perches 		hid_err(hdev, "parse failed\n");
638*abf832bfSBenjamin Tissoires 		return ret;
639bd28ce00SJiri Slaby 	}
640bd28ce00SJiri Slaby 
641f04d5140SColin Leitner 	if (sc->quirks & VAIO_RDESC_CONSTANT)
642f04d5140SColin Leitner 		connect_mask |= HID_CONNECT_HIDDEV_FORCE;
643f04d5140SColin Leitner 	else if (sc->quirks & SIXAXIS_CONTROLLER_USB)
644f04d5140SColin Leitner 		connect_mask |= HID_CONNECT_HIDDEV_FORCE;
645f04d5140SColin Leitner 	else if (sc->quirks & SIXAXIS_CONTROLLER_BT)
646f04d5140SColin Leitner 		connect_mask |= HID_CONNECT_HIDDEV_FORCE;
647f04d5140SColin Leitner 
648f04d5140SColin Leitner 	ret = hid_hw_start(hdev, connect_mask);
649bd28ce00SJiri Slaby 	if (ret) {
6504291ee30SJoe Perches 		hid_err(hdev, "hw start failed\n");
651*abf832bfSBenjamin Tissoires 		return ret;
652bd28ce00SJiri Slaby 	}
653bd28ce00SJiri Slaby 
654569b10a5SAntonio Ospite 	if (sc->quirks & SIXAXIS_CONTROLLER_USB) {
655569b10a5SAntonio Ospite 		hdev->hid_output_raw_report = sixaxis_usb_output_raw_report;
656816651a7SAntonio Ospite 		ret = sixaxis_set_operational_usb(hdev);
657569b10a5SAntonio Ospite 	}
658816651a7SAntonio Ospite 	else if (sc->quirks & SIXAXIS_CONTROLLER_BT)
659816651a7SAntonio Ospite 		ret = sixaxis_set_operational_bt(hdev);
660f04d5140SColin Leitner 	else if (sc->quirks & BUZZ_CONTROLLER)
661f04d5140SColin Leitner 		ret = buzz_init(hdev);
662816651a7SAntonio Ospite 	else
663f9ce7c28SBastien Nocera 		ret = 0;
664f9ce7c28SBastien Nocera 
6654dfdc464SJiri Kosina 	if (ret < 0)
666bd28ce00SJiri Slaby 		goto err_stop;
667bd28ce00SJiri Slaby 
668bd28ce00SJiri Slaby 	return 0;
669bd28ce00SJiri Slaby err_stop:
670bd28ce00SJiri Slaby 	hid_hw_stop(hdev);
671bd28ce00SJiri Slaby 	return ret;
672bd28ce00SJiri Slaby }
673bd28ce00SJiri Slaby 
674cc6e0bbbSJiri Kosina static void sony_remove(struct hid_device *hdev)
675cc6e0bbbSJiri Kosina {
676f04d5140SColin Leitner 	struct sony_sc *sc = hid_get_drvdata(hdev);
677f04d5140SColin Leitner 
678f04d5140SColin Leitner 	if (sc->quirks & BUZZ_CONTROLLER)
679f04d5140SColin Leitner 		buzz_remove(hdev);
680f04d5140SColin Leitner 
681cc6e0bbbSJiri Kosina 	hid_hw_stop(hdev);
682cc6e0bbbSJiri Kosina }
683cc6e0bbbSJiri Kosina 
684bd28ce00SJiri Slaby static const struct hid_device_id sony_devices[] = {
685816651a7SAntonio Ospite 	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER),
686816651a7SAntonio Ospite 		.driver_data = SIXAXIS_CONTROLLER_USB },
68735dca5b4SJiri Kosina 	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_NAVIGATION_CONTROLLER),
68835dca5b4SJiri Kosina 		.driver_data = SIXAXIS_CONTROLLER_USB },
689816651a7SAntonio Ospite 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER),
690816651a7SAntonio Ospite 		.driver_data = SIXAXIS_CONTROLLER_BT },
691cc6e0bbbSJiri Kosina 	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE),
692cc6e0bbbSJiri Kosina 		.driver_data = VAIO_RDESC_CONSTANT },
693a4649184SFernando Luis Vázquez Cao 	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGP_MOUSE),
694a4649184SFernando Luis Vázquez Cao 		.driver_data = VAIO_RDESC_CONSTANT },
695f04d5140SColin Leitner 	/* Wired Buzz Controller. Reported as Sony Hub from its USB ID and as
696f04d5140SColin Leitner 	 * Logitech joystick from the device descriptor. */
697f04d5140SColin Leitner 	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_BUZZ_CONTROLLER),
698f04d5140SColin Leitner 		.driver_data = BUZZ_CONTROLLER },
699f04d5140SColin Leitner 	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_WIRELESS_BUZZ_CONTROLLER),
700f04d5140SColin Leitner 		.driver_data = BUZZ_CONTROLLER },
701078328daSJiri Kosina 	/* PS3 BD Remote Control */
702078328daSJiri Kosina 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_BDREMOTE),
703078328daSJiri Kosina 		.driver_data = PS3REMOTE },
704078328daSJiri Kosina 	/* Logitech Harmony Adapter for PS3 */
705078328daSJiri Kosina 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_PS3),
706078328daSJiri Kosina 		.driver_data = PS3REMOTE },
707bd28ce00SJiri Slaby 	{ }
708bd28ce00SJiri Slaby };
709bd28ce00SJiri Slaby MODULE_DEVICE_TABLE(hid, sony_devices);
710bd28ce00SJiri Slaby 
711bd28ce00SJiri Slaby static struct hid_driver sony_driver = {
712bd28ce00SJiri Slaby 	.name          = "sony",
713bd28ce00SJiri Slaby 	.id_table      = sony_devices,
714f04d5140SColin Leitner 	.input_mapping = sony_mapping,
715bd28ce00SJiri Slaby 	.probe         = sony_probe,
716cc6e0bbbSJiri Kosina 	.remove        = sony_remove,
717cc6e0bbbSJiri Kosina 	.report_fixup  = sony_report_fixup,
718c9e4d877SSimon Wood 	.raw_event     = sony_raw_event
719bd28ce00SJiri Slaby };
720f425458eSH Hartley Sweeten module_hid_driver(sony_driver);
721bd28ce00SJiri Slaby 
722bd28ce00SJiri Slaby MODULE_LICENSE("GPL");
723