hid: rkvr: add sync process before start snesor data transfer if sync_string no empty
authorlanshh <lsh@rock-chips.com>
Fri, 2 Sep 2016 02:34:32 +0000 (10:34 +0800)
committerHuang, Tao <huangtao@rock-chips.com>
Fri, 2 Sep 2016 09:19:44 +0000 (17:19 +0800)
Change-Id: Ifd20949963171fff4df694b58b629065a37ea492
Signed-off-by: lanshh <lsh@rock-chips.com>
drivers/hid/hid-rkvr.c
drivers/hid/hid-rkvr.h

index 2eeac6d6654aa506bcb61280379b98809d5c5793..1087d90209536d2de62409d6fc0746bac1ac5086 100644 (file)
@@ -71,6 +71,7 @@ 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;
@@ -566,6 +567,80 @@ static int rkvr_report_event(struct hid_device *hid, u8 *data, int len)
        return ret;
 }
 
+/*
+ * for enable sensor data
+ ************************************
+ * buf contents ---->
+ * first 8 bytes :random digits
+ * left bytes    :encryt data
+ * eg:32654:3AA4618F6B455D37F06279EC2D6BC478C759443277F3E4E982203562E7ED
+ ***********************************
+ */
+
+static int hid_report_sync(struct device *dev, const char *data, size_t len)
+{
+       struct hid_device *hid = container_of(dev, struct hid_device, dev);
+       u64 *tmp;
+       unsigned char buf[64];
+       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;
+
+       p = kmalloc(sizeof(*p) * len, GFP_KERNEL);
+       if (!p) {
+               hid_err(hid, "no mem\n");
+               return -ENOMEM;
+       }
+       memcpy(p, data, len);
+       colon = strchr(p, ':');
+       if (!colon) {
+               hid_err(hid, "must have conlon\n");
+               ret = -EINVAL;
+               goto fail;
+       }
+       if (colon - p + 1 >= len) {
+               hid_err(hid, "must have sync string after conlon\n");
+               ret = -EINVAL;
+               goto fail;
+       }
+       colon[0] = 0;
+       colon++;
+       tmp = (u64 *)(buf + 1);
+       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);
+       for (i = 0; i < len; i++) {
+               buf2[0] = colon[i * 2];
+               buf2[1] = colon[i * 2 + 1];
+               if (kstrtou8(buf2, 16, &buf[9 + 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) {
+               hid_err(hid, "hid_report_encrypt fail\n");
+               ret = -EIO;
+               goto fail;
+       }
+       hid_info(hid, "hid_report_encrypt ok\n");
+       ret = 0;
+fail:
+       kfree(p);
+
+       return ret;
+}
+
 static void hid_report_fill_rw(unsigned char *buf, u8 reg, u8 *data, int len, int w)
 {
        if (w)
@@ -577,13 +652,12 @@ static void hid_report_fill_rw(unsigned char *buf, u8 reg, u8 *data, int len, in
 }
 
 #if DEBUG_SYS
-#define HID_OUTPUT_READREG     3
 
 static int hid_report_readreg(struct device *dev, u8 reg, u8 *data, int len)
 {
        struct hid_device *hid = container_of(dev, struct hid_device, dev);
        unsigned char report_number = reg;
-       unsigned char report_type = HID_OUTPUT_READREG;
+       unsigned char report_type = HID_REGR_REPORT;
        char buf[1 + sizeof(data) * len];
        int readlen = 1 + sizeof(data) * len;
        int ret;
@@ -602,8 +676,8 @@ static int hid_report_readreg(struct device *dev, u8 reg, u8 *data, int len)
 static int hid_report_writereg(struct device *dev, u8 reg, u8 data)
 {
        struct hid_device *hid = container_of(dev, struct hid_device, dev);
-       unsigned char report_number = 5;
-       unsigned char report_type = HID_OUTPUT_REPORT;
+       unsigned char report_number = HID_REPORT_ID_W;
+       unsigned char report_type = HID_REGW_REPORT;
        char buf[3 + sizeof(data)];
        int ret;
 
@@ -621,12 +695,11 @@ static ssize_t rkvr_dev_attr_debug_store(struct device *dev, struct device_attri
                        const char *buf, size_t count)
 {
        struct hidraw *devraw;
-       struct hid_device *hid = container_of(dev, struct hid_device, dev);
 
        devraw = dev_get_drvdata(dev);
        if (0 == strncmp(buf, "write", 5))
                hid_report_writereg(&devraw->hid->dev, 0, 0);
-       hid_info(hid, "%s\n", buf);
+       hid_info(devraw->hid, "%s\n", buf);
 
        return count;
 }
@@ -647,13 +720,23 @@ static ssize_t rkvr_dev_attr_debug_show(struct device *dev, struct device_attrib
        return count;
 }
 static DEVICE_ATTR(debug, 0664, rkvr_dev_attr_debug_show, rkvr_dev_attr_debug_store);
+
+static ssize_t rkvr_dev_attr_sync_store(struct device *dev, struct device_attribute *attr,
+                       const char *buf, size_t count)
+{
+       struct hidraw *devraw = dev_get_drvdata(dev);
+
+       return hid_report_sync(&devraw->hid->dev, buf, count);
+}
+
+static DEVICE_ATTR(sync, S_IWUSR, NULL, rkvr_dev_attr_sync_store);
 #endif
 
 static int rkvr_hid_read(struct rkvr_iio_hw_device *hdev, int reg, unsigned char *data, int len)
 {
        struct hid_device *hid = container_of(hdev->dev, struct hid_device, dev);
        unsigned char report_number = reg;
-       unsigned char report_type = HID_OUTPUT_READREG;
+       unsigned char report_type = HID_REGR_REPORT;
        char buf[1 + sizeof(data) * len];
        int readlen = 1 + sizeof(data) * len;
        int ret;
@@ -671,8 +754,8 @@ static int rkvr_hid_read(struct rkvr_iio_hw_device *hdev, int reg, unsigned char
 static int rkvr_hid_write(struct rkvr_iio_hw_device *hdev, int reg, unsigned char data)
 {
        struct hid_device *hid = container_of(hdev->dev, struct hid_device, dev);
-       unsigned char report_number = 5;
-       unsigned char report_type = HID_OUTPUT_REPORT;
+       unsigned char report_number = HID_REPORT_ID_W;
+       unsigned char report_type = HID_REGW_REPORT;
        char buf[3 + sizeof(data)];
        int ret;
 
@@ -758,6 +841,7 @@ static int rkvr_connect(struct hid_device *hid)
        dev_set_drvdata(dev->dev, dev);
 #if DEBUG_SYS
        device_create_file(dev->dev, &dev_attr_debug);
+       device_create_file(dev->dev, &dev_attr_sync);
 #endif
 
        {
@@ -804,6 +888,8 @@ 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);
@@ -892,6 +978,7 @@ static void rkvr_disconnect(struct hid_device *hid)
        inv_hid_unregister_and_destroy_devcie_by_name("hid-rkvr");
 #if DEBUG_SYS
        device_remove_file(hidraw->dev, &dev_attr_debug);
+       device_remove_file(hidraw->dev, &dev_attr_sync);
 #endif
 
        device_destroy(rkvr_class, MKDEV(rkvr_major, hidraw->minor));
@@ -1033,6 +1120,41 @@ int rkvr_sensor_register_callback(int (*callback)(char *, size_t, void *), void
 }
 EXPORT_SYMBOL_GPL(rkvr_sensor_register_callback);
 
+static int rkvr_sync_exec(const char *p, size_t c)
+{
+       int minor;
+       int ret = c;
+       int exist = 0;
+
+       mutex_lock(&minors_lock);
+       pr_info("rkvr_sync_exec %s\n", p);
+       for (minor = 0; minor < RKVR_HIDRAW_MAX_DEVICES; minor++) {
+               if (!rkvr_hidraw_table[minor] || !rkvr_hidraw_table[minor]->exist)
+                       continue;
+               if (hid_report_sync(&rkvr_hidraw_table[minor]->hid->dev, p, c)) {
+                       hid_err(rkvr_hidraw_table[minor]->hid, "hid_report_sync failed\n");
+                       ret = -EIO;
+                       goto exit;
+               }
+               exist++;
+       }
+       if (!exist)
+               ret = -ENODEV;
+exit:
+       mutex_unlock(&minors_lock);
+
+       return ret;
+}
+
+int rkvr_sensor_sync_inv(const char *p, size_t c)
+{
+       snprintf(sync_string, sizeof(sync_string), "%s", p);
+
+       return rkvr_sync_exec(sync_string, strlen(sync_string));
+}
+
+EXPORT_SYMBOL_GPL(rkvr_sensor_sync_inv);
+
 static int rkvr_probe(struct hid_device *hdev, const struct hid_device_id *id)
 {
        int retval;
@@ -1102,7 +1224,7 @@ static int rkvr_raw_event(struct hid_device *hdev, struct hid_report *report, u8
        if (++count >= 1000) {
                unsigned long cur_jiffy = jiffies;
 
-               hid_info(hdev, "rkvr: %d Hz, hidrkvr %d\n", (int)(1000 * HZ / (cur_jiffy - old_jiffy)), (hdev->hidraw ? 1 : 0));
+               hid_dbg(hdev, "rkvr: %d Hz, hidrkvr %d\n", (int)(1000 * HZ / (cur_jiffy - old_jiffy)), (hdev->hidraw ? 1 : 0));
                count = 0;
                old_jiffy = cur_jiffy;
        }
index df2778fc803d1a22d7540528d68bf11ce23798c6..ff1cd9fd4c69f1b2e85995b7cf55d28f6f43ec94 100644 (file)
@@ -9,6 +9,16 @@
 #ifndef __HID_RKVR_H
 #define __HID_RKVR_H
 
+#define HIDRKVRHANDSHAKE(len)  _IOC(_IOC_WRITE, 'H', 0x07, len)
+#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)
+
+#define HID_SYNCW_REPORT       (7 - 1)
+#define HID_SYNCR_REPORT       (8 - 1)
+
 enum tracker_message_type {
        TrackerMessage_None              = 0,
        TrackerMessage_Sensors           = 1,
@@ -21,6 +31,7 @@ enum tracker_message_type {
 #define DYNAMIC_LOAD_MPU6500 0
 
 int rkvr_sensor_register_callback(int (*callback)(char *, size_t, void *), void *priv);
+int rkvr_sensor_sync_inv(const char *p, size_t c);
 
 struct rkvr_iio_hw_device {
        struct device *dev;