Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 18 additions & 3 deletions drivers/hid/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -598,12 +598,27 @@ config HID_SAMSUNG
Support for Samsung InfraRed remote control or keyboards.

config HID_SONY
tristate "Sony PS3 controller"
tristate "Sony PS2/3/4 accessories"
depends on USB_HID
depends on NEW_LEDS
depends on LEDS_CLASS
select POWER_SUPPLY
---help---
Support for Sony PS3 6-axis controllers.
Support for

* Sony PS3 6-axis controllers
* Sony PS4 DualShock 4 controllers
* Buzz controllers
* Sony PS3 Blue-ray Disk Remote Control (Bluetooth)
* Logitech Harmony adapter for Sony Playstation 3 (Bluetooth)

Support for the Sony PS3 BD Remote is provided by HID_PS3REMOTE.
config SONY_FF
bool "Sony PS2/3/4 accessories force feedback support"
depends on HID_SONY
select INPUT_FF_MEMLESS
---help---
Say Y here if you have a Sony PS2/3/4 accessory and want to enable
force feedback support for it.

config HID_SPEEDLINK
tristate "Speedlink VAD Cezanne mouse support"
Expand Down
5 changes: 5 additions & 0 deletions drivers/hid/hid-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -1782,10 +1782,15 @@ static const struct hid_device_id hid_have_special_driver[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_SIS2_TOUCH, USB_DEVICE_ID_SIS9200_TOUCH) },
{ HID_USB_DEVICE(USB_VENDOR_ID_SIS2_TOUCH, USB_DEVICE_ID_SIS817_TOUCH) },
{ HID_USB_DEVICE(USB_VENDOR_ID_SKYCABLE, USB_DEVICE_ID_SKYCABLE_WIRELESS_PRESENTER) },
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SMK, USB_DEVICE_ID_SMK_PS3_BDREMOTE) },
{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_BUZZ_CONTROLLER) },
{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_WIRELESS_BUZZ_CONTROLLER) },
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_BDREMOTE) },
{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) },
{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_NAVIGATION_CONTROLLER) },
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) },
{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS4_CONTROLLER) },
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS4_CONTROLLER) },
{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE) },
{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGP_MOUSE) },
{ HID_USB_DEVICE(USB_VENDOR_ID_STEELSERIES, USB_DEVICE_ID_STEELSERIES_SRWS1) },
Expand Down
6 changes: 6 additions & 0 deletions drivers/hid/hid-ids.h
Original file line number Diff line number Diff line change
Expand Up @@ -743,12 +743,18 @@
#define USB_VENDOR_ID_SKYCABLE 0x1223
#define USB_DEVICE_ID_SKYCABLE_WIRELESS_PRESENTER 0x3F07

#define USB_VENDOR_ID_SMK 0x0609
#define USB_DEVICE_ID_SMK_PS3_BDREMOTE 0x0306

#define USB_VENDOR_ID_SONY 0x054c
#define USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE 0x024b
#define USB_DEVICE_ID_SONY_VAIO_VGP_MOUSE 0x0374
#define USB_DEVICE_ID_SONY_PS3_BDREMOTE 0x0306
#define USB_DEVICE_ID_SONY_PS3_CONTROLLER 0x0268
#define USB_DEVICE_ID_SONY_PS4_CONTROLLER 0x05c4
#define USB_DEVICE_ID_SONY_NAVIGATION_CONTROLLER 0x042f
#define USB_DEVICE_ID_SONY_BUZZ_CONTROLLER 0x0002
#define USB_DEVICE_ID_SONY_WIRELESS_BUZZ_CONTROLLER 0x1000

#define USB_VENDOR_ID_SOUNDGRAPH 0x15c2
#define USB_DEVICE_ID_SOUNDGRAPH_IMON_FIRST 0x0034
Expand Down
2,091 changes: 2,025 additions & 66 deletions drivers/hid/hid-sony.c

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions drivers/media/dvb-core/dvb-usb-ids.h
Original file line number Diff line number Diff line change
Expand Up @@ -367,4 +367,5 @@
#define USB_PID_TECHNISAT_USB2_HDCI_V2 0x0002
#define USB_PID_TECHNISAT_AIRSTAR_TELESTICK_2 0x0004
#define USB_PID_TECHNISAT_USB2_DVB_S2 0x0500
#define USB_PID_CPYTO_REDI_PC50A 0xa803
#endif
2 changes: 2 additions & 0 deletions drivers/media/usb/dvb-usb-v2/rtl28xxu.c
Original file line number Diff line number Diff line change
Expand Up @@ -1408,6 +1408,8 @@ static const struct usb_device_id rtl28xxu_id_table[] = {
&rtl2832u_props, "Compro VideoMate U620F", NULL) },
{ DVB_USB_DEVICE(USB_VID_KWORLD_2, 0xd394,
&rtl2832u_props, "MaxMedia HU394-T", NULL) },
{ DVB_USB_DEVICE(USB_VID_GTEK, USB_PID_CPYTO_REDI_PC50A,
&rtl2832u_props, "Crypto Redi PC50A", NULL) },
{ }
};
MODULE_DEVICE_TABLE(usb, rtl28xxu_id_table);
Expand Down
67 changes: 55 additions & 12 deletions net/bluetooth/hidp/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -341,9 +341,14 @@ static int hidp_output_raw_report(struct hid_device *hid, unsigned char *data, s
int ret;

if (report_type == HID_OUTPUT_REPORT) {
report_type = HIDP_TRANS_DATA | HIDP_DATA_RTYPE_OUPUT;
return hidp_send_intr_message(session, report_type,
data, count);
/* The Sixaxis and Dualshock 4 wants report sent via the ctrl channel */
if(hid->vendor == 0x54c && (hid->product == 0x5c4 || hid->product == 0x268)) {
report_type = HIDP_TRANS_SET_REPORT | HIDP_DATA_RTYPE_OUPUT;
return hidp_send_ctrl_message(session, report_type, data, count);
} else {
report_type = HIDP_TRANS_DATA | HIDP_DATA_RTYPE_OUPUT;
return hidp_send_intr_message(session, report_type, data, count);
}
} else if (report_type != HID_FEATURE_REPORT) {
return -EINVAL;
}
Expand Down Expand Up @@ -855,6 +860,29 @@ static void hidp_session_dev_del(struct hidp_session *session)
input_unregister_device(session->input);
}

/*
* Asynchronous device registration
* HID device drivers might want to perform I/O during initialization to
* detect device types. Therefore, call device registration in a separate
* worker so the HIDP thread can schedule I/O operations.
* Note that this must be called after the worker thread was initialized
* successfully. This will then add the devices and increase session state
* on success, otherwise it will terminate the session thread.
*/
static void hidp_session_dev_work(struct work_struct *work)
{
struct hidp_session *session = container_of(work,
struct hidp_session,
dev_init);
int ret;

ret = hidp_session_dev_add(session);
if (!ret)
atomic_inc(&session->state);
else
hidp_session_terminate(session);
}

/*
* Create new session object
* Allocate session object, initialize static fields, copy input data into the
Expand Down Expand Up @@ -902,6 +930,7 @@ static int hidp_session_new(struct hidp_session **out, const bdaddr_t *bdaddr,
session->idle_to = req->idle_to;

/* device management */
INIT_WORK(&session->dev_init, hidp_session_dev_work);
setup_timer(&session->timer, hidp_idle_timeout,
(unsigned long)session);

Expand Down Expand Up @@ -1040,8 +1069,8 @@ static void hidp_session_terminate(struct hidp_session *session)
* Probe HIDP session
* This is called from the l2cap_conn core when our l2cap_user object is bound
* to the hci-connection. We get the session via the \user object and can now
* start the session thread, register the HID/input devices and link it into
* the global session list.
* start the session thread, link it into the global session list and
* schedule HID/input device registration.
* The global session-list owns its own reference to the session object so you
* can drop your own reference after registering the l2cap_user object.
*/
Expand All @@ -1063,21 +1092,30 @@ static int hidp_session_probe(struct l2cap_conn *conn,
goto out_unlock;
}

if (session->input) {
ret = hidp_session_dev_add(session);
if (ret)
goto out_unlock;
}

ret = hidp_session_start_sync(session);
if (ret)
goto out_unlock;
goto out_del;

ret = hidp_session_dev_add(session);
if (ret)
goto out_stop;
/* HID device registration is async to allow I/O during probe */
if (session->input)
atomic_inc(&session->state);
else
schedule_work(&session->dev_init);

hidp_session_get(session);
list_add(&session->list, &hidp_session_list);
ret = 0;
goto out_unlock;

out_stop:
hidp_session_terminate(session);
out_del:
if (session->input)
hidp_session_dev_del(session);
out_unlock:
up_write(&hidp_session_sem);
return ret;
Expand Down Expand Up @@ -1107,7 +1145,12 @@ static void hidp_session_remove(struct l2cap_conn *conn,
down_write(&hidp_session_sem);

hidp_session_terminate(session);
hidp_session_dev_del(session);

cancel_work_sync(&session->dev_init);
if (session->input ||
atomic_read(&session->state) > HIDP_SESSION_PREPARING)
hidp_session_dev_del(session);

list_del(&session->list);

up_write(&hidp_session_sem);
Expand Down
2 changes: 2 additions & 0 deletions net/bluetooth/hidp/hidp.h
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ int hidp_get_conninfo(struct hidp_conninfo *ci);

enum hidp_session_state {
HIDP_SESSION_IDLING,
HIDP_SESSION_PREPARING,
HIDP_SESSION_RUNNING,
};

Expand Down Expand Up @@ -156,6 +157,7 @@ struct hidp_session {
unsigned long idle_to;

/* device management */
struct work_struct dev_init;
struct input_dev *input;
struct hid_device *hid;
struct timer_list timer;
Expand Down