Merge branches 'for-4.8/upstream-fixes', 'for-4.9/alps', 'for-4.9/hid-input', 'for...
[sfrench/cifs-2.6.git] / drivers / hid / hid-sony.c
index 310436a54a3f308157a272d56d6624c3dd3c98c1..b0bb99a821bd777692cc845ec2992d95834ffeb6 100644 (file)
@@ -8,7 +8,7 @@
  *  Copyright (c) 2012 David Dillow <dave@thedillows.org>
  *  Copyright (c) 2006-2013 Jiri Kosina
  *  Copyright (c) 2013 Colin Leitner <colin.leitner@gmail.com>
- *  Copyright (c) 2014 Frank Praznik <frank.praznik@gmail.com>
+ *  Copyright (c) 2014-2016 Frank Praznik <frank.praznik@gmail.com>
  */
 
 /*
@@ -51,6 +51,7 @@
 #define NAVIGATION_CONTROLLER_USB BIT(9)
 #define NAVIGATION_CONTROLLER_BT  BIT(10)
 #define SINO_LITE_CONTROLLER      BIT(11)
+#define FUTUREMAX_DANCE_MAT       BIT(12)
 
 #define SIXAXIS_CONTROLLER (SIXAXIS_CONTROLLER_USB | SIXAXIS_CONTROLLER_BT)
 #define MOTION_CONTROLLER (MOTION_CONTROLLER_USB | MOTION_CONTROLLER_BT)
@@ -65,6 +66,8 @@
                                MOTION_CONTROLLER_BT | NAVIGATION_CONTROLLER)
 #define SONY_FF_SUPPORT (SIXAXIS_CONTROLLER | DUALSHOCK4_CONTROLLER |\
                                MOTION_CONTROLLER)
+#define SONY_BT_DEVICE (SIXAXIS_CONTROLLER_BT | DUALSHOCK4_CONTROLLER_BT |\
+                       MOTION_CONTROLLER_BT | NAVIGATION_CONTROLLER_BT)
 
 #define MAX_LEDS 4
 
@@ -1048,6 +1051,7 @@ struct sony_sc {
 
        u8 mac_address[6];
        u8 worker_initialized;
+       u8 defer_initialization;
        u8 cable_state;
        u8 battery_charging;
        u8 battery_capacity;
@@ -1058,6 +1062,12 @@ struct sony_sc {
        u8 led_count;
 };
 
+static inline void sony_schedule_work(struct sony_sc *sc)
+{
+       if (!sc->defer_initialization)
+               schedule_work(&sc->state_worker);
+}
+
 static u8 *sixaxis_fixup(struct hid_device *hdev, u8 *rdesc,
                             unsigned int *rsize)
 {
@@ -1125,7 +1135,7 @@ static u8 *sony_report_fixup(struct hid_device *hdev, u8 *rdesc,
 {
        struct sony_sc *sc = hid_get_drvdata(hdev);
 
-       if (sc->quirks & SINO_LITE_CONTROLLER)
+       if (sc->quirks & (SINO_LITE_CONTROLLER | FUTUREMAX_DANCE_MAT))
                return rdesc;
 
        /*
@@ -1317,6 +1327,11 @@ static int sony_raw_event(struct hid_device *hdev, struct hid_report *report,
                dualshock4_parse_report(sc, rd, size);
        }
 
+       if (sc->defer_initialization) {
+               sc->defer_initialization = 0;
+               sony_schedule_work(sc);
+       }
+
        return 0;
 }
 
@@ -1554,7 +1569,7 @@ static void buzz_set_leds(struct sony_sc *sc)
 static void sony_set_leds(struct sony_sc *sc)
 {
        if (!(sc->quirks & BUZZ_CONTROLLER))
-               schedule_work(&sc->state_worker);
+               sony_schedule_work(sc);
        else
                buzz_set_leds(sc);
 }
@@ -1665,7 +1680,7 @@ static int sony_led_blink_set(struct led_classdev *led, unsigned long *delay_on,
                new_off != drv_data->led_delay_off[n]) {
                drv_data->led_delay_on[n] = new_on;
                drv_data->led_delay_off[n] = new_off;
-               schedule_work(&drv_data->state_worker);
+               sony_schedule_work(drv_data);
        }
 
        return 0;
@@ -1865,6 +1880,17 @@ static void dualshock4_send_output_report(struct sony_sc *sc)
        u8 *buf = sc->output_report_dmabuf;
        int offset;
 
+       /*
+        * NOTE: The buf[1] field of the Bluetooth report controls
+        * the Dualshock 4 reporting rate.
+        *
+        * Known values include:
+        *
+        * 0x80 - 1000hz (full speed)
+        * 0xA0 - 31hz
+        * 0xB0 - 20hz
+        * 0xD0 - 66hz
+        */
        if (sc->quirks & DUALSHOCK4_CONTROLLER_USB) {
                memset(buf, 0, DS4_REPORT_0x05_SIZE);
                buf[0] = 0x05;
@@ -1976,7 +2002,7 @@ static int sony_play_effect(struct input_dev *dev, void *data,
        sc->left = effect->u.rumble.strong_magnitude / 256;
        sc->right = effect->u.rumble.weak_magnitude / 256;
 
-       schedule_work(&sc->state_worker);
+       sony_schedule_work(sc);
        return 0;
 }
 
@@ -2039,8 +2065,11 @@ static int sony_battery_get_property(struct power_supply *psy,
        return ret;
 }
 
-static int sony_battery_probe(struct sony_sc *sc)
+static int sony_battery_probe(struct sony_sc *sc, int append_dev_id)
 {
+       const char *battery_str_fmt = append_dev_id ?
+               "sony_controller_battery_%pMR_%i" :
+               "sony_controller_battery_%pMR";
        struct power_supply_config psy_cfg = { .drv_data = sc, };
        struct hid_device *hdev = sc->hdev;
        int ret;
@@ -2056,9 +2085,8 @@ static int sony_battery_probe(struct sony_sc *sc)
        sc->battery_desc.get_property = sony_battery_get_property;
        sc->battery_desc.type = POWER_SUPPLY_TYPE_BATTERY;
        sc->battery_desc.use_for_apm = 0;
-       sc->battery_desc.name = kasprintf(GFP_KERNEL,
-                                         "sony_controller_battery_%pMR",
-                                         sc->mac_address);
+       sc->battery_desc.name = kasprintf(GFP_KERNEL, battery_str_fmt,
+                                         sc->mac_address, sc->device_id);
        if (!sc->battery_desc.name)
                return -ENOMEM;
 
@@ -2094,7 +2122,21 @@ static void sony_battery_remove(struct sony_sc *sc)
  * it will show up as two devices. A global list of connected controllers and
  * their MAC addresses is maintained to ensure that a device is only connected
  * once.
+ *
+ * Some USB-only devices masquerade as Sixaxis controllers and all have the
+ * same dummy Bluetooth address, so a comparison of the connection type is
+ * required.  Devices are only rejected in the case where two devices have
+ * matching Bluetooth addresses on different bus types.
  */
+static inline int sony_compare_connection_type(struct sony_sc *sc0,
+                                               struct sony_sc *sc1)
+{
+       const int sc0_not_bt = !(sc0->quirks & SONY_BT_DEVICE);
+       const int sc1_not_bt = !(sc1->quirks & SONY_BT_DEVICE);
+
+       return sc0_not_bt == sc1_not_bt;
+}
+
 static int sony_check_add_dev_list(struct sony_sc *sc)
 {
        struct sony_sc *entry;
@@ -2107,9 +2149,14 @@ static int sony_check_add_dev_list(struct sony_sc *sc)
                ret = memcmp(sc->mac_address, entry->mac_address,
                                sizeof(sc->mac_address));
                if (!ret) {
-                       ret = -EEXIST;
-                       hid_info(sc->hdev, "controller with MAC address %pMR already connected\n",
+                       if (sony_compare_connection_type(sc, entry)) {
+                               ret = 1;
+                       } else {
+                               ret = -EEXIST;
+                               hid_info(sc->hdev,
+                               "controller with MAC address %pMR already connected\n",
                                sc->mac_address);
+                       }
                        goto unlock;
                }
        }
@@ -2285,10 +2332,14 @@ static inline void sony_cancel_work_sync(struct sony_sc *sc)
 static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id)
 {
        int ret;
+       int append_dev_id;
        unsigned long quirks = id->driver_data;
        struct sony_sc *sc;
        unsigned int connect_mask = HID_CONNECT_DEFAULT;
 
+       if (!strcmp(hdev->name, "FutureMax Dance Mat"))
+               quirks |= FUTUREMAX_DANCE_MAT;
+
        sc = devm_kzalloc(&hdev->dev, sizeof(*sc), GFP_KERNEL);
        if (sc == NULL) {
                hid_err(hdev, "can't alloc sony descriptor\n");
@@ -2341,9 +2392,16 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id)
                 * the Sixaxis does not want the report_id as part of the data
                 * packet, so we have to discard buf[0] when sending the actual
                 * control message, even for numbered reports, humpf!
+                *
+                * Additionally, the Sixaxis on USB isn't properly initialized
+                * until the PS logo button is pressed and as such won't retain
+                * any state set by an output report, so the initial
+                * configuration report is deferred until the first input
+                * report arrives.
                 */
                hdev->quirks |= HID_QUIRK_NO_OUTPUT_REPORTS_ON_INTR_EP;
                hdev->quirks |= HID_QUIRK_SKIP_OUTPUT_REPORT_ID;
+               sc->defer_initialization = 1;
                ret = sixaxis_set_operational_usb(hdev);
                sony_init_output_report(sc, sixaxis_send_output_report);
        } else if ((sc->quirks & SIXAXIS_CONTROLLER_BT) ||
@@ -2379,7 +2437,7 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id)
        if (ret < 0)
                goto err_stop;
 
-       ret = sony_check_add(sc);
+       ret = append_dev_id = sony_check_add(sc);
        if (ret < 0)
                goto err_stop;
 
@@ -2390,7 +2448,7 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id)
        }
 
        if (sc->quirks & SONY_BATTERY_SUPPORT) {
-               ret = sony_battery_probe(sc);
+               ret = sony_battery_probe(sc, append_dev_id);
                if (ret < 0)
                        goto err_stop;
 
@@ -2486,8 +2544,10 @@ static int sony_resume(struct hid_device *hdev)
                 * reinitialized on resume or they won't behave properly.
                 */
                if ((sc->quirks & SIXAXIS_CONTROLLER_USB) ||
-                       (sc->quirks & NAVIGATION_CONTROLLER_USB))
+                       (sc->quirks & NAVIGATION_CONTROLLER_USB)) {
                        sixaxis_set_operational_usb(sc->hdev);
+                       sc->defer_initialization = 1;
+               }
 
                sony_set_leds(sc);
        }