hid: rkvr: change sync implement
authorlanshh <lsh@rock-chips.com>
Tue, 11 Oct 2016 08:13:52 +0000 (16:13 +0800)
committerHuang, Tao <huangtao@rock-chips.com>
Fri, 14 Oct 2016 01:53:22 +0000 (09:53 +0800)
Change-Id: I2c18d79339f067e8b567be0568ff3de8a8934a27
Signed-off-by: lanshh <lsh@rock-chips.com>
drivers/hid/hid-rkvr.c
drivers/hid/hid-rkvr.h

index 63d7fc00a53c5135f1b3988b1461fb5999627ebe..ec75de69582f98058beeb5de583a85c5e2b86d06 100644 (file)
@@ -71,7 +71,6 @@ static unsigned int count_array[15] = {0,};
 static unsigned long old_jiffy_array[15] = {0,};
 static int rkvr_index;
 static int opens;
-static char sync_string[64];
 
 struct sensor_hid_data {
        void *priv;
@@ -567,6 +566,31 @@ static int rkvr_report_event(struct hid_device *hid, u8 *data, int len)
        return ret;
 }
 
+/******************************************
+ *--------------------
+ *| ID | BUF .....   |
+ *--------------------
+ *
+ ******************************************/
+static int rkvr_send_report(struct device *dev, unsigned char *data, size_t len)
+{
+       struct hid_device *hid = container_of(dev, struct hid_device, dev);
+       unsigned char reportnum = HID_REPORT_ID_RKVR;
+       unsigned char rtype = HID_OUTPUT_REPORT;
+       int ret = -EINVAL;
+
+       ret = hid_hw_raw_request(hid, reportnum, (unsigned char *)data, len, rtype, HID_REQ_SET_REPORT);
+       if (ret != len) {
+               hid_err(hid, "rkvr_send_report fail\n");
+               ret = -EIO;
+               goto fail;
+       }
+       hid_info(hid, "rkvr_send_report ok\n");
+       ret = 0;
+fail:
+       return ret;
+}
+
 /*
  * for enable sensor data
  ************************************
@@ -577,64 +601,62 @@ static int rkvr_report_event(struct hid_device *hid, u8 *data, int len)
  ***********************************
  */
 
-static int hid_report_sync(struct device *dev, const char *data, size_t len)
+static int hid_report_sync(struct device *dev, const char *data, size_t count)
 {
        struct hid_device *hid = container_of(dev, struct hid_device, dev);
        u64 *tmp;
-       unsigned char buf[64];
+       unsigned char buf[64] = {HID_REPORT_ID_RKVR, RKVR_ID_SYNC};
        unsigned char buf2[3] = {0};
        char *colon;
        int i, ret = 0;
        char *p;
-       unsigned char report_number = HID_REPORT_ID_CRYP;
-       unsigned char report_type = HID_SYNCW_REPORT;
+       size_t len;
 
-       p = kmalloc(sizeof(*p) * len, GFP_KERNEL);
+       p = kmalloc(sizeof(*p) * count, GFP_KERNEL);
        if (!p) {
                hid_err(hid, "no mem\n");
                return -ENOMEM;
        }
-       memcpy(p, data, len);
-       colon = strchr(p, ':');
+       memcpy(p, data, count);
+       colon = strnchr(p, count, ':');
        if (!colon) {
                hid_err(hid, "must have conlon\n");
                ret = -EINVAL;
                goto fail;
        }
-       if (colon - p + 1 >= len) {
+       if (colon - p + 1 >= count) {
                hid_err(hid, "must have sync string after conlon\n");
                ret = -EINVAL;
                goto fail;
        }
        colon[0] = 0;
        colon++;
-       tmp = (u64 *)(buf + 1);
+       tmp = (u64 *)(buf + 2);
        if (kstrtoull(p, 10, tmp)) {
                hid_err(hid, "convert rand string fail,only decimal string allowed\n");
                ret = -EINVAL;
                goto fail;
        }
-       len = min((len - (colon - p)) / 2, sizeof(buf) - 9);
+       hid_info(hid, "uint64 %llu\n", *(u64 *)(buf + 2));
+       len = min((count - (colon - p)) / 2, sizeof(buf) - (sizeof(*tmp) + 2));
        for (i = 0; i < len; i++) {
                buf2[0] = colon[i * 2];
                buf2[1] = colon[i * 2 + 1];
-               if (kstrtou8(buf2, 16, &buf[9 + i])) {
+               if (kstrtou8(buf2, 16, &buf[sizeof(*tmp) + 2 + i])) {
                        hid_err(hid, "err sync string,only hex string allowed\n");
                        ret = -EINVAL;
                        goto fail;
                }
        }
-
-       len = i + 9;
-       ret = hid_hw_raw_request(hid, report_number, (unsigned char *)buf, len,
-               report_type, HID_REQ_SET_REPORT);
-       if (ret != len) {
+       len = i + sizeof(*tmp) + 2;
+       ret = rkvr_send_report(dev, (unsigned char *)buf, len);
+       if (ret) {
                hid_err(hid, "hid_report_encrypt fail\n");
                ret = -EIO;
                goto fail;
        }
        hid_info(hid, "hid_report_encrypt ok\n");
-       ret = 0;
+       ret = count;
 fail:
        kfree(p);
 
@@ -725,8 +747,10 @@ static ssize_t rkvr_dev_attr_sync_store(struct device *dev, struct device_attrib
                        const char *buf, size_t count)
 {
        struct hidraw *devraw = dev_get_drvdata(dev);
+       int ret;
 
-       return hid_report_sync(&devraw->hid->dev, buf, count);
+       ret = hid_report_sync(&devraw->hid->dev, buf, count - 1);
+       return ret > 0 ? count : ret;
 }
 
 static DEVICE_ATTR(sync, S_IWUSR, NULL, rkvr_dev_attr_sync_store);
@@ -888,8 +912,6 @@ static int rkvr_connect(struct hid_device *hid)
                hid_err(hid, "rkvr_connect:hid_hw_open fail\n");
                goto out;
        }
-       if (strlen(sync_string))
-               hid_report_sync(&hid->dev, sync_string, strlen(sync_string));
 
        init_waitqueue_head(&dev->wait);
        spin_lock_init(&dev->list_lock);
@@ -1183,8 +1205,8 @@ static void rkvr_remove(struct hid_device *hdev)
        struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
 
        if (intf->cur_altsetting->desc.bInterfaceNumber == RKVR_INTERFACE_USB_SENSOR_ID) {
-               rkvr_keys_remove(hdev);
                rkvr_hw_stop(hdev);
+               rkvr_keys_remove(hdev);
        } else {
                hid_hw_stop(hdev);
        }
index 309bc37cb550970a3fac5dd6b843d792b183ea8b..32d38ff7e4b655db4e12d920fae06d4b30b89652 100644 (file)
 #define __HID_RKVR_H
 
 #define HIDRKVRHANDSHAKE(len)  _IOC(_IOC_WRITE, 'H', 0x1A, len)
+
+#define HID_REPORT_ID_RKVR     3
+#define RKVR_ID_IDLE   1
+#define RKVR_ID_SYNC   2
+
 #define HID_REPORT_ID_R        4
 #define HID_REPORT_ID_W        5
 #define HID_REPORT_ID_CRYP     6
+
 #define HID_REGR_REPORT        (4 - 1)
 #define HID_REGW_REPORT        (5 - 1)