hid: rkvr: add sync process before start snesor data transfer if sync_string no empty

Change-Id: Ifd20949963171fff4df694b58b629065a37ea492
Signed-off-by: lanshh <lsh@rock-chips.com>
This commit is contained in:
lanshh 2016-09-02 10:34:32 +08:00 committed by Huang, Tao
parent 0eacb88fb9
commit a07dd2733d
2 changed files with 143 additions and 10 deletions

View 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;
}

View 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;