diff options
-rw-r--r-- | drivers/hid/hid-sony.c | 66 |
1 files changed, 49 insertions, 17 deletions
diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c index 243209c4dcaf..58e0bfadd6bf 100644 --- a/drivers/hid/hid-sony.c +++ b/drivers/hid/hid-sony.c | |||
@@ -717,6 +717,36 @@ static enum power_supply_property sony_battery_props[] = { | |||
717 | POWER_SUPPLY_PROP_STATUS, | 717 | POWER_SUPPLY_PROP_STATUS, |
718 | }; | 718 | }; |
719 | 719 | ||
720 | struct sixaxis_led { | ||
721 | __u8 time_enabled; /* the total time the led is active (0xff means forever) */ | ||
722 | __u8 duty_length; /* how long a cycle is in deciseconds (0 means "really fast") */ | ||
723 | __u8 enabled; | ||
724 | __u8 duty_off; /* % of duty_length the led is off (0xff means 100%) */ | ||
725 | __u8 duty_on; /* % of duty_length the led is on (0xff mean 100%) */ | ||
726 | } __packed; | ||
727 | |||
728 | struct sixaxis_rumble { | ||
729 | __u8 padding; | ||
730 | __u8 right_duration; /* Right motor duration (0xff means forever) */ | ||
731 | __u8 right_motor_on; /* Right (small) motor on/off, only supports values of 0 or 1 (off/on) */ | ||
732 | __u8 left_duration; /* Left motor duration (0xff means forever) */ | ||
733 | __u8 left_motor_force; /* left (large) motor, supports force values from 0 to 255 */ | ||
734 | } __packed; | ||
735 | |||
736 | struct sixaxis_output_report { | ||
737 | __u8 report_id; | ||
738 | struct sixaxis_rumble rumble; | ||
739 | __u8 padding[4]; | ||
740 | __u8 leds_bitmap; /* bitmap of enabled LEDs: LED_1 = 0x02, LED_2 = 0x04, ... */ | ||
741 | struct sixaxis_led led[4]; /* LEDx at (4 - x) */ | ||
742 | struct sixaxis_led _reserved; /* LED5, not actually soldered */ | ||
743 | } __packed; | ||
744 | |||
745 | union sixaxis_output_report_01 { | ||
746 | struct sixaxis_output_report data; | ||
747 | __u8 buf[36]; | ||
748 | }; | ||
749 | |||
720 | static spinlock_t sony_dev_list_lock; | 750 | static spinlock_t sony_dev_list_lock; |
721 | static LIST_HEAD(sony_device_list); | 751 | static LIST_HEAD(sony_device_list); |
722 | 752 | ||
@@ -1244,29 +1274,31 @@ error_leds: | |||
1244 | static void sixaxis_state_worker(struct work_struct *work) | 1274 | static void sixaxis_state_worker(struct work_struct *work) |
1245 | { | 1275 | { |
1246 | struct sony_sc *sc = container_of(work, struct sony_sc, state_worker); | 1276 | struct sony_sc *sc = container_of(work, struct sony_sc, state_worker); |
1247 | unsigned char buf[] = { | 1277 | union sixaxis_output_report_01 report = { |
1248 | 0x01, | 1278 | .buf = { |
1249 | 0x00, 0xff, 0x00, 0xff, 0x00, | 1279 | 0x01, |
1250 | 0x00, 0x00, 0x00, 0x00, 0x00, | 1280 | 0x00, 0xff, 0x00, 0xff, 0x00, |
1251 | 0xff, 0x27, 0x10, 0x00, 0x32, | 1281 | 0x00, 0x00, 0x00, 0x00, 0x00, |
1252 | 0xff, 0x27, 0x10, 0x00, 0x32, | 1282 | 0xff, 0x27, 0x10, 0x00, 0x32, |
1253 | 0xff, 0x27, 0x10, 0x00, 0x32, | 1283 | 0xff, 0x27, 0x10, 0x00, 0x32, |
1254 | 0xff, 0x27, 0x10, 0x00, 0x32, | 1284 | 0xff, 0x27, 0x10, 0x00, 0x32, |
1255 | 0x00, 0x00, 0x00, 0x00, 0x00 | 1285 | 0xff, 0x27, 0x10, 0x00, 0x32, |
1286 | 0x00, 0x00, 0x00, 0x00, 0x00 | ||
1287 | } | ||
1256 | }; | 1288 | }; |
1257 | 1289 | ||
1258 | #ifdef CONFIG_SONY_FF | 1290 | #ifdef CONFIG_SONY_FF |
1259 | buf[3] = sc->right ? 1 : 0; | 1291 | report.data.rumble.right_motor_on = sc->right ? 1 : 0; |
1260 | buf[5] = sc->left; | 1292 | report.data.rumble.left_motor_force = sc->left; |
1261 | #endif | 1293 | #endif |
1262 | 1294 | ||
1263 | buf[10] |= sc->led_state[0] << 1; | 1295 | report.data.leds_bitmap |= sc->led_state[0] << 1; |
1264 | buf[10] |= sc->led_state[1] << 2; | 1296 | report.data.leds_bitmap |= sc->led_state[1] << 2; |
1265 | buf[10] |= sc->led_state[2] << 3; | 1297 | report.data.leds_bitmap |= sc->led_state[2] << 3; |
1266 | buf[10] |= sc->led_state[3] << 4; | 1298 | report.data.leds_bitmap |= sc->led_state[3] << 4; |
1267 | 1299 | ||
1268 | hid_hw_raw_request(sc->hdev, 0x01, buf, sizeof(buf), HID_OUTPUT_REPORT, | 1300 | hid_hw_raw_request(sc->hdev, report.data.report_id, report.buf, |
1269 | HID_REQ_SET_REPORT); | 1301 | sizeof(report), HID_OUTPUT_REPORT, HID_REQ_SET_REPORT); |
1270 | } | 1302 | } |
1271 | 1303 | ||
1272 | static void dualshock4_state_worker(struct work_struct *work) | 1304 | static void dualshock4_state_worker(struct work_struct *work) |