aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/hid/hid-sony.c66
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
720struct 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
728struct 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
736struct 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
745union sixaxis_output_report_01 {
746 struct sixaxis_output_report data;
747 __u8 buf[36];
748};
749
720static spinlock_t sony_dev_list_lock; 750static spinlock_t sony_dev_list_lock;
721static LIST_HEAD(sony_device_list); 751static LIST_HEAD(sony_device_list);
722 752
@@ -1244,29 +1274,31 @@ error_leds:
1244static void sixaxis_state_worker(struct work_struct *work) 1274static 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
1272static void dualshock4_state_worker(struct work_struct *work) 1304static void dualshock4_state_worker(struct work_struct *work)