^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * Rockchip VR driver for Linux
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (C) ROCKCHIP, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * This program is free software; you can redistribute it and/or modify it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * under the terms of the GNU General Public License as published by the Free
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Software Foundation; either version 2 of the License, or (at your option)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * any later version.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * Driver for Rockchip VR devices. Based on hidraw driver.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/cdev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/poll.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/usb.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/hidraw.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/input.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/notifier.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/fb.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include "hid-rkvr.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include "hid-ids.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define USB_TRACKER_INTERFACE_PROTOCOL 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) /* define rkvr interface number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define RKVR_INTERFACE_USB_AUDIO_ID 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define RKVR_INTERFACE_USB_SENSOR_ID 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define RKVR_INTERFACE_USB_AUDIO_KEY_ID 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) /* number of reports to buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define RKVR_HIDRAW_BUFFER_SIZE 64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define RKVR_HIDRAW_MAX_DEVICES 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define RKVR_FIRST_MINOR 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define RK_HID_GEAR_TOUCH
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) static struct class *rkvr_class;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) static struct hidraw *rkvr_hidraw_table[RKVR_HIDRAW_MAX_DEVICES];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) static struct hid_capability
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) __u8 suspend_notify;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) } rkvr_hid_capability[RKVR_HIDRAW_MAX_DEVICES];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) static DEFINE_MUTEX(minors_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) struct keymap_t {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) __u16 key_menu_up:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) __u16 key_menu_down:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) __u16 key_home_up:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) __u16 key_home_down:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) __u16 key_power_up:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) __u16 key_power_down:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) __u16 key_volup_up:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) __u16 key_volup_down:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) __u16 key_voldn_up:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) __u16 key_voldn_down:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) __u16 key_esc_up:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) __u16 key_esc_down:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) /*for touch panel **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) __u16 key_up_pressed:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) __u16 key_up_released:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) __u16 key_down_pressed:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) __u16 key_down_released:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) __u16 key_left_pressed:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) __u16 key_left_released:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) __u16 key_right_pressed:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) __u16 key_right_released:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) __u16 key_enter_pressed:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) __u16 key_enter_released:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) __u16 key_pressed:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) __u16 psensor_on:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) __u16 psensor_off:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) } __packed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) union rkvr_data_t {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) struct rkvr_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) __u8 buf_head[6];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) __u8 buf_sensortemperature[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) __u8 buf_sensor[40];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) __u8 buf_reserve[10];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) struct keymap_t key_map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) } rkvr_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) __u8 buf[62];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) } __packed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) static int rkvr_major;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) static struct cdev rkvr_cdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) static unsigned int count_array[15] = {0,};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) static unsigned long old_jiffy_array[15] = {0,};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) static int rkvr_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) static int opens;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) struct sensor_hid_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) void *priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) int (*send_event)(char *raw_data, size_t raw_len, void *priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) } sensorData;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) static DEFINE_MUTEX(device_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) static struct list_head rkvr_hid_hw_device_list = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) .next = &rkvr_hid_hw_device_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) .prev = &rkvr_hid_hw_device_list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) static struct rkvr_iio_hw_device *inv_hid_alloc(const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) struct rkvr_iio_hw_device *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) const char *s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) if (!name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) s = kstrdup_const(name, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) if (!s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) p = kzalloc(sizeof(*p), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) p->name = s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) return p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) pr_err("%s error!\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) if (s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) kfree_const(s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) static void inv_hid_free(struct rkvr_iio_hw_device *hw_device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) kfree_const(hw_device->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) kfree(hw_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) static int inv_hid_register_devcie(struct rkvr_iio_hw_device *hw_device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) mutex_lock(&device_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) if (hw_device->name && (!list_empty(&rkvr_hid_hw_device_list))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) struct rkvr_iio_hw_device *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) list_for_each_entry(p, &rkvr_hid_hw_device_list, l) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) if (!strcmp(hw_device->name, p->name)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) pr_err("%s already exist ,abort\n", hw_device->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) mutex_unlock(&device_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) list_add_tail(&hw_device->l, &rkvr_hid_hw_device_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) mutex_unlock(&device_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) static void inv_hid_unregister_and_destroy_devcie_by_name(const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) struct rkvr_iio_hw_device *p = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) mutex_lock(&device_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) list_for_each_entry(p, &rkvr_hid_hw_device_list, l) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) if (!strcmp(name, p->name)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) list_del(&p->l);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) if (p) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) pr_info("find dev with name %s,free now\n", name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) inv_hid_free(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) mutex_unlock(&device_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) static ssize_t rkvr_hidraw_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) struct hidraw_list *list = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) int ret = 0, len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) DECLARE_WAITQUEUE(wait, current);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) mutex_lock(&list->read_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) while (ret == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) if (list->head == list->tail) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) add_wait_queue(&list->hidraw->wait, &wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) set_current_state(TASK_INTERRUPTIBLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) while (list->head == list->tail) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) if (signal_pending(current)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) ret = -ERESTARTSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) if (!list->hidraw->exist) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) if (file->f_flags & O_NONBLOCK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) ret = -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) /* allow O_NONBLOCK to work well from other threads */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) mutex_unlock(&list->read_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) schedule();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) mutex_lock(&list->read_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) set_current_state(TASK_INTERRUPTIBLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) set_current_state(TASK_RUNNING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) remove_wait_queue(&list->hidraw->wait, &wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) len = list->buffer[list->tail].len > count ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) count : list->buffer[list->tail].len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) if (list->buffer[list->tail].value) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) if (copy_to_user(buffer, list->buffer[list->tail].value, len)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) ret = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) ret = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) if (opens > 0 && rkvr_index < 15) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) if (++count_array[rkvr_index] >= 1000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) unsigned long cur_jiffy = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) hid_dbg(list->hidraw->hid, "rkvr: %d Hz, read(%d) (%d:%s)\n", (int)(1000 * HZ / (cur_jiffy - old_jiffy_array[rkvr_index])), rkvr_index, current->pid, current->comm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) count_array[rkvr_index] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) old_jiffy_array[rkvr_index] = cur_jiffy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) if (++rkvr_index >= opens)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) rkvr_index = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) rkvr_index = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) kfree(list->buffer[list->tail].value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) list->buffer[list->tail].value = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) list->tail = (list->tail + 1) & (RKVR_HIDRAW_BUFFER_SIZE - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) mutex_unlock(&list->read_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) /* The first byte is expected to be a report number.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) * This function is to be called with the minors_lock mutex held
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) static ssize_t rkvr_hidraw_send_report(struct file *file, const char __user *buffer, size_t count, unsigned char report_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) unsigned int minor = iminor(file_inode(file));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) struct hid_device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) __u8 *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) if (!rkvr_hidraw_table[minor] || !rkvr_hidraw_table[minor]->exist) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) dev = rkvr_hidraw_table[minor]->hid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) if (count > HID_MAX_BUFFER_SIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) hid_warn(dev, "rkvr - pid %d passed too large report\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) task_pid_nr(current));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) if (count < 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) hid_warn(dev, "rkvr - pid %d passed too short report\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) task_pid_nr(current));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) buf = kmalloc(count * sizeof(__u8), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) if (!buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) if (copy_from_user(buf, buffer, count)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) ret = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) if ((report_type == HID_OUTPUT_REPORT) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) !(dev->quirks & HID_QUIRK_NO_OUTPUT_REPORTS_ON_INTR_EP)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) ret = hid_hw_output_report(dev, buf, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) * compatibility with old implementation of USB-HID and I2C-HID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) * if the device does not support receiving output reports,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) * on an interrupt endpoint, fallback to SET_REPORT HID command.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) if (ret != -ENOSYS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) ret = hid_hw_raw_request(dev, buf[0], buf, count, report_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) HID_REQ_SET_REPORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) out_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) kfree(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) /* the first byte is expected to be a report number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) static ssize_t rkvr_hidraw_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) ssize_t ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) mutex_lock(&minors_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) ret = rkvr_hidraw_send_report(file, buffer, count, HID_OUTPUT_REPORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) mutex_unlock(&minors_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) /* This function performs a Get_Report transfer over the control endpoint
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) * per section 7.2.1 of the HID specification, version 1.1. The first byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) * of buffer is the report number to request, or 0x0 if the defice does not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) * use numbered reports. The report_type parameter can be HID_FEATURE_REPORT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) * or HID_INPUT_REPORT. This function is to be called with the minors_lock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) * mutex held.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) static ssize_t rkvr_hidraw_get_report(struct file *file, char __user *buffer, size_t count, unsigned char report_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) unsigned int minor = iminor(file_inode(file));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) struct hid_device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) __u8 *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) int ret = 0, len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) unsigned char report_number;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) dev = rkvr_hidraw_table[minor]->hid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) if (!dev->ll_driver->raw_request) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) if (count > HID_MAX_BUFFER_SIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) hid_warn(dev, "rkvr - hidraw: pid %d passed too large report\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) task_pid_nr(current));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) if (count < 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) hid_warn(dev, "rkvr - hidraw: pid %d passed too short report\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) task_pid_nr(current));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) buf = kmalloc(count * sizeof(__u8), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) if (!buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) * Read the first byte from the user. This is the report number,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) * which is passed to hid_hw_raw_request().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) if (copy_from_user(&report_number, buffer, 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) ret = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) ret = hid_hw_raw_request(dev, report_number, buf, count, report_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) HID_REQ_GET_REPORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) len = (ret < count) ? ret : count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) if (copy_to_user(buffer, buf, len)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) ret = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) ret = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) out_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) kfree(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) static unsigned int rkvr_hidraw_poll(struct file *file, poll_table *wait)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) struct hidraw_list *list = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) poll_wait(file, &list->hidraw->wait, wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) if (list->head != list->tail)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) return POLLIN | POLLRDNORM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) if (!list->hidraw->exist)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) return POLLERR | POLLHUP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) static int rkvr_hidraw_open(struct inode *inode, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) unsigned int minor = iminor(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) struct hidraw *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) struct hidraw_list *list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) list = kzalloc(sizeof(*list), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) if (!list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) mutex_lock(&minors_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) if (!rkvr_hidraw_table[minor] || !rkvr_hidraw_table[minor]->exist) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) err = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) dev = rkvr_hidraw_table[minor];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) if (!dev->open++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) err = hid_hw_power(dev->hid, PM_HINT_FULLON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) dev->open--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) err = hid_hw_open(dev->hid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) hid_hw_power(dev->hid, PM_HINT_NORMAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) dev->open--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) list->hidraw = rkvr_hidraw_table[minor];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) mutex_init(&list->read_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) spin_lock_irqsave(&rkvr_hidraw_table[minor]->list_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) list_add_tail(&list->node, &rkvr_hidraw_table[minor]->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) spin_unlock_irqrestore(&rkvr_hidraw_table[minor]->list_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) file->private_data = list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) opens = dev->open;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) out_unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) mutex_unlock(&minors_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) kfree(list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) static int rkvr_hidraw_fasync(int fd, struct file *file, int on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) struct hidraw_list *list = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) return fasync_helper(fd, file, on, &list->fasync);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) static void rkvr_drop_ref(struct hidraw *hidraw, int exists_bit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) if (exists_bit) { /*hw removed**/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) hidraw->exist = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) if (hidraw->open) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) hid_hw_close(hidraw->hid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) wake_up_interruptible(&hidraw->wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) --hidraw->open;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) if (!hidraw->open) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) if (!hidraw->exist) { /*no opened && no hardware,delete all**/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) rkvr_hidraw_table[hidraw->minor] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) kfree(hidraw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) /* close device for last reader */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) hid_hw_power(hidraw->hid, PM_HINT_NORMAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) hid_hw_close(hidraw->hid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) static int rkvr_hidraw_release(struct inode *inode, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) unsigned int minor = iminor(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) struct hidraw_list *list = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) mutex_lock(&minors_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) spin_lock_irqsave(&rkvr_hidraw_table[minor]->list_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) list_del(&list->node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) spin_unlock_irqrestore(&rkvr_hidraw_table[minor]->list_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) kfree(list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) rkvr_drop_ref(rkvr_hidraw_table[minor], 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) mutex_unlock(&minors_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) static void rkvr_send_key_event(struct input_dev *input, int key_value, int state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) if (!input) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) if (state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) input_report_key(input, key_value, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) input_sync(input);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) input_report_key(input, key_value, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) input_sync(input);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) static int rkvr_keys_event(struct hid_device *hdev, void *data, unsigned long len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) struct input_dev *input = hdev->hiddev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) union rkvr_data_t *rkvr_data = (union rkvr_data_t *)data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) if (rkvr_data->rkvr_data.key_map.key_menu_up)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) rkvr_send_key_event(input, KEY_MENU, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) else if (rkvr_data->rkvr_data.key_map.key_menu_down)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) rkvr_send_key_event(input, KEY_MENU, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) else if (rkvr_data->rkvr_data.key_map.key_home_up)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) rkvr_send_key_event(input, KEY_HOME, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) else if (rkvr_data->rkvr_data.key_map.key_home_down)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) rkvr_send_key_event(input, KEY_HOME, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) else if (rkvr_data->rkvr_data.key_map.key_power_up)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) rkvr_send_key_event(input, KEY_POWER, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) else if (rkvr_data->rkvr_data.key_map.key_power_down)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) rkvr_send_key_event(input, KEY_POWER, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) else if (rkvr_data->rkvr_data.key_map.key_volup_up)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) rkvr_send_key_event(input, KEY_VOLUMEUP, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) else if (rkvr_data->rkvr_data.key_map.key_volup_down)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) rkvr_send_key_event(input, KEY_VOLUMEUP, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) else if (rkvr_data->rkvr_data.key_map.key_voldn_up)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) rkvr_send_key_event(input, KEY_VOLUMEDOWN, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) else if (rkvr_data->rkvr_data.key_map.key_voldn_down)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) rkvr_send_key_event(input, KEY_VOLUMEDOWN, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) else if (rkvr_data->rkvr_data.key_map.key_esc_up)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) rkvr_send_key_event(input, KEY_ESC, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) else if (rkvr_data->rkvr_data.key_map.key_esc_down)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) rkvr_send_key_event(input, KEY_ESC, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) else if (rkvr_data->rkvr_data.key_map.key_up_pressed) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) rkvr_send_key_event(input, KEY_UP, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) rkvr_send_key_event(input, KEY_UP, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) } else if (rkvr_data->rkvr_data.key_map.key_down_pressed) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) rkvr_send_key_event(input, KEY_DOWN, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) rkvr_send_key_event(input, KEY_DOWN, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) } else if (rkvr_data->rkvr_data.key_map.key_left_pressed) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) rkvr_send_key_event(input, KEY_LEFT, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) rkvr_send_key_event(input, KEY_LEFT, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) } else if (rkvr_data->rkvr_data.key_map.key_right_pressed) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) rkvr_send_key_event(input, KEY_RIGHT, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) rkvr_send_key_event(input, KEY_RIGHT, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) } else if (rkvr_data->rkvr_data.key_map.key_enter_pressed) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) input_event(input, EV_MSC, MSC_SCAN, 0x90001);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) rkvr_send_key_event(input, BTN_MOUSE, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) input_event(input, EV_MSC, MSC_SCAN, 0x90001);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) rkvr_send_key_event(input, BTN_MOUSE, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) if (rkvr_data->rkvr_data.key_map.psensor_on) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) hid_info(hdev, "event: psensor_on\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) rkvr_send_key_event(input, KEY_POWER, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) rkvr_send_key_event(input, KEY_POWER, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) } else if (rkvr_data->rkvr_data.key_map.psensor_off) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) hid_info(hdev, "event: psensor_off\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) rkvr_send_key_event(input, KEY_POWER, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) rkvr_send_key_event(input, KEY_POWER, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) static int rkvr_report_event(struct hid_device *hid, u8 *data, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) struct hidraw *dev = hid->hidraw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) struct hidraw_list *list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) union rkvr_data_t *rkvr_data = (union rkvr_data_t *)data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) struct sensor_hid_data *pdata = hid_get_drvdata(hid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) spin_lock_irqsave(&dev->list_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) if (hid->hiddev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) rkvr_keys_event(hid, data, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) if (pdata && pdata->priv && pdata->send_event) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) pdata->send_event(rkvr_data->buf, len, pdata->priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) spin_unlock_irqrestore(&dev->list_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) list_for_each_entry(list, &dev->list, node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) int new_head = (list->head + 1) & (RKVR_HIDRAW_BUFFER_SIZE - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) if (new_head == list->tail)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) list->buffer[list->head].value = kmemdup(data, len, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) if (!list->buffer[list->head].value) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) list->buffer[list->head].len = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) list->head = new_head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) kill_fasync(&list->fasync, SIGIO, POLL_IN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) spin_unlock_irqrestore(&dev->list_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) wake_up_interruptible(&dev->wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) /******************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) *--------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) *| ID | BUF ..... |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) *--------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) ******************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) static int rkvr_send_report(struct device *dev, unsigned char *data, size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) struct hid_device *hid = container_of(dev, struct hid_device, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) unsigned char reportnum = HID_REPORT_ID_RKVR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) unsigned char rtype = HID_OUTPUT_REPORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) int ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) ret = hid_hw_raw_request(hid, reportnum, (unsigned char *)data, len, rtype, HID_REQ_SET_REPORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) if (ret != len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) hid_err(hid, "rkvr_send_report fail\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) hid_info(hid, "rkvr_send_report ok\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) static int rkvr_recv_report(struct device *dev, u8 type, u8 *data, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) struct hid_device *hid = container_of(dev, struct hid_device, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) unsigned char report_number = type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) unsigned char report_type = HID_MISC_REPORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) char buf[1 + sizeof(*data) * len];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) int readlen = 1 + sizeof(*data) * len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) ret = hid_hw_raw_request(hid, report_number, (unsigned char *)buf, readlen, report_type, HID_REQ_GET_REPORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) if (ret != readlen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) hid_info(hid, "rkvr_recv_report fail\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) memcpy(data, &buf[1], len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) hid_info(hid, "rkvr_recv_report %02x\n", type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) * for enable sensor data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) ************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) * buf contents ---->
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) * first 8 bytes :random digits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) * left bytes :encryt data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) * eg:32654:3AA4618F6B455D37F06279EC2D6BC478C759443277F3E4E982203562E7ED
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) ***********************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) static int hid_report_sync(struct device *dev, const char *data, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) struct hid_device *hid = container_of(dev, struct hid_device, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) u64 *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) unsigned char buf[64] = {HID_REPORT_ID_RKVR, RKVR_ID_SYNC};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) unsigned char buf2[3] = {0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) char *colon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) int i, ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) char *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) size_t len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) p = kmalloc(sizeof(*p) * count, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) if (!p) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) hid_err(hid, "no mem\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) memcpy(p, data, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) colon = strnchr(p, count, ':');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) if (!colon) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) hid_err(hid, "must have conlon\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) if (colon - p + 1 >= count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) hid_err(hid, "must have sync string after conlon\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) colon[0] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) colon++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) tmp = (u64 *)(buf + 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) if (kstrtoull(p, 10, tmp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) hid_err(hid, "convert rand string fail,only decimal string allowed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) hid_info(hid, "uint64 %llu\n", *(u64 *)(buf + 2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) len = min((count - (colon - p)) / 2, sizeof(buf) - (sizeof(*tmp) + 2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) for (i = 0; i < len; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) buf2[0] = colon[i * 2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) buf2[1] = colon[i * 2 + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) if (kstrtou8(buf2, 16, &buf[sizeof(*tmp) + 2 + i])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) hid_err(hid, "err sync string,only hex string allowed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) len = i + sizeof(*tmp) + 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) ret = rkvr_send_report(dev, (unsigned char *)buf, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) hid_err(hid, "hid_report_encrypt fail\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) hid_info(hid, "hid_report_encrypt ok\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) ret = count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) kfree(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) static int hid_get_capability(struct device *dev, struct hid_capability *caps)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) struct hid_device *hid = container_of(dev, struct hid_device, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) u8 data = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) caps->suspend_notify = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) if (!rkvr_recv_report(dev, RKVR_ID_CAPS, &data, 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) hid_info(hid, "hid_get_capability %d\n", data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) caps->suspend_notify = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) static void hid_report_fill_rw(unsigned char *buf, u8 reg, u8 *data, int len, int w)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) if (w)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) buf[0] = (1 << 7) | (len & 0x7f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) buf[0] = len & 0x7f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) buf[1] = reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) memcpy(&buf[2], data, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) #if DEBUG_SYS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) static int hid_report_readreg(struct device *dev, u8 reg, u8 *data, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) struct hid_device *hid = container_of(dev, struct hid_device, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) unsigned char report_number = reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) unsigned char report_type = HID_REGR_REPORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) char buf[1 + sizeof(*data) * len];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) int readlen = 1 + sizeof(*data) * len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) ret = hid_hw_raw_request(hid, report_number, (unsigned char *)buf, readlen, report_type, HID_REQ_GET_REPORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) if (ret != readlen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) hid_info(hid, "id_hw_raw_request fail\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) memcpy(data, &buf[1], readlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) hid_info(hid, "hid_report_readreg %02x %02x\n", reg, data[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) static int hid_report_writereg(struct device *dev, u8 reg, u8 data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) struct hid_device *hid = container_of(dev, struct hid_device, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) unsigned char report_number = HID_REPORT_ID_W;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) unsigned char report_type = HID_REGW_REPORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) char buf[3 + sizeof(data)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) hid_report_fill_rw(&buf[1], reg, &data, sizeof(data), 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) ret = hid_hw_raw_request(hid, report_number, (unsigned char *)buf, 4, report_type, HID_REQ_SET_REPORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) if (ret != 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) hid_info(hid, "id_hw_raw_request fail\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) hid_info(hid, "id_hw_raw_request ok\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) static ssize_t rkvr_dev_attr_debug_store(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) struct hidraw *devraw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) devraw = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) if (0 == strncmp(buf, "write", 5))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) hid_report_writereg(&devraw->hid->dev, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) hid_info(devraw->hid, "%s\n", buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) static ssize_t rkvr_dev_attr_debug_show(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) size_t count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) u8 mpu6500_id = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) struct hidraw *devraw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) devraw = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) if (!hid_report_readreg(&devraw->hid->dev, 0x75 | 0x80, &mpu6500_id, 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) count += sprintf(&buf[count], "reg value %d\n", mpu6500_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) count += sprintf(&buf[count], "read fail\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) static DEVICE_ATTR(debug, 0664, rkvr_dev_attr_debug_show, rkvr_dev_attr_debug_store);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) static ssize_t rkvr_dev_attr_sync_store(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) struct hidraw *devraw = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) ret = hid_report_sync(&devraw->hid->dev, buf, count - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) return ret > 0 ? count : ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) static DEVICE_ATTR(sync, S_IWUSR, NULL, rkvr_dev_attr_sync_store);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) static int rkvr_hid_read(struct rkvr_iio_hw_device *hdev, int reg, unsigned char *data, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) struct hid_device *hid = container_of(hdev->dev, struct hid_device, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) unsigned char report_number = reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) unsigned char report_type = HID_REGR_REPORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) char buf[1 + sizeof(*data) * len];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) int readlen = 1 + sizeof(*data) * len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) ret = hid_hw_raw_request(hid, report_number, (unsigned char *)buf, readlen, report_type, HID_REQ_GET_REPORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) if (ret != readlen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) hid_err(hid, "id_hw_raw_request fail\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) memcpy(data, &buf[1], sizeof(*data) * len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) static int rkvr_hid_write(struct rkvr_iio_hw_device *hdev, int reg, unsigned char data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) struct hid_device *hid = container_of(hdev->dev, struct hid_device, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) unsigned char report_number = HID_REPORT_ID_W;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) unsigned char report_type = HID_REGW_REPORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) char buf[3 + sizeof(data)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) hid_report_fill_rw(&buf[1], reg, &data, sizeof(data), 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) ret = hid_hw_raw_request(hid, report_number, (unsigned char *)buf, 4, report_type, HID_REQ_SET_REPORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) if (ret != 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) hid_info(hid, "id_hw_raw_request fail\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) hid_info(hid, "id_hw_raw_request ok\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) static int rkvr_hid_open(struct rkvr_iio_hw_device *hdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) struct hid_device *hid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) hid = container_of(hdev->dev, struct hid_device, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) err = hid_hw_power(hid, PM_HINT_FULLON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) err = hid_hw_open(hid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) hid_hw_power(hid, PM_HINT_NORMAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) static void rkvr_hid_close(struct rkvr_iio_hw_device *hdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) struct hid_device *hid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) hid = container_of(hdev->dev, struct hid_device, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) hid_hw_power(hid, PM_HINT_NORMAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) hid_hw_close(hid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) #if DYNAMIC_LOAD_MPU6500
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) static int register_mpu6500;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) struct platform_device mpu6500_dev = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) .name = "mpu6500",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) static int rkvr_connect(struct hid_device *hid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) int minor, result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) struct hidraw *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) /* we accept any HID device, no matter the applications */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) dev = kzalloc(sizeof(*dev), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) if (!dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) result = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) mutex_lock(&minors_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) for (minor = 0; minor < RKVR_HIDRAW_MAX_DEVICES; minor++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) if (rkvr_hidraw_table[minor])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) rkvr_hidraw_table[minor] = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) result = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) if (result) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) mutex_unlock(&minors_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) kfree(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) dev->dev = device_create(rkvr_class, &hid->dev, MKDEV(rkvr_major, minor),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) NULL, "%s%d", "rkvr", minor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) if (IS_ERR(dev->dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) rkvr_hidraw_table[minor] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) mutex_unlock(&minors_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) result = PTR_ERR(dev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) kfree(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) dev_set_drvdata(dev->dev, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) #if DEBUG_SYS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) device_create_file(dev->dev, &dev_attr_debug);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) device_create_file(dev->dev, &dev_attr_sync);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) struct rkvr_iio_hw_device *hw_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) hw_device = inv_hid_alloc("hid-rkvr");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) if (!hw_device) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) hid_err(hid, "inv_hid_alloc(\"hid-rkvr\") fail\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) rkvr_hidraw_table[minor] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) mutex_unlock(&minors_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) result = PTR_ERR(dev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) kfree(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) hw_device->dev = &hid->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) hw_device->open = rkvr_hid_open;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) hw_device->close = rkvr_hid_close;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) hw_device->read = rkvr_hid_read;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) hw_device->write = rkvr_hid_write;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) if (inv_hid_register_devcie(hw_device)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) hid_err(hid, "inv_hid_register_devcie(\"hid-rkvr\") fail\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) inv_hid_free(hw_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) rkvr_hidraw_table[minor] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) mutex_unlock(&minors_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) result = PTR_ERR(dev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) kfree(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) #if DYNAMIC_LOAD_MPU6500
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) if (!register_mpu6500) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) register_mpu6500 = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) hid_info(hid, "--->platform_device_register-->\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) platform_device_register(&mpu6500_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) if (hid_hw_open(hid)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) rkvr_hidraw_table[minor] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) mutex_unlock(&minors_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) result = PTR_ERR(dev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) kfree(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) hid_err(hid, "rkvr_connect:hid_hw_open fail\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) init_waitqueue_head(&dev->wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) spin_lock_init(&dev->list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) INIT_LIST_HEAD(&dev->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) dev->hid = hid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) dev->minor = minor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) dev->exist = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) hid->hidraw = dev; /*struct hidraw * **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) hid_get_capability(&hid->dev, &rkvr_hid_capability[minor]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) mutex_unlock(&minors_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) static int rkvr_keys_remove(struct hid_device *hdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) struct input_dev *input = hdev->hiddev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) input_unregister_device(input);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) static unsigned int key_codes[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) KEY_MENU,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) KEY_HOME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) KEY_POWER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) KEY_VOLUMEUP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) KEY_VOLUMEDOWN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) KEY_WAKEUP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) KEY_ESC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) KEY_LEFT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) KEY_RIGHT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) KEY_UP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) KEY_DOWN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) KEY_ENTER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) BTN_MOUSE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) static int __must_check rkvr_keys_probe(struct hid_device *hdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) struct device *dev = &hdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) struct input_dev *input = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) int i, error = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) input = devm_input_allocate_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) if (!input) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) hid_err(hdev, "input_allocate_device fail\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) input->name = "rkvr-keypad";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) input->phys = "rkvr-keys/input0";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) input->dev.parent = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) input->id.bustype = BUS_HOST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) input->id.vendor = 0x071b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) input->id.product = 0x3205;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) input->id.version = 0x0001;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) for (i = 0; i < sizeof(key_codes) / sizeof(key_codes[0]); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) hid_info(hdev, "input_set_capability %d\n", key_codes[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) input_set_capability(input, EV_KEY, key_codes[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) #ifdef RK_HID_GEAR_TOUCH
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) set_bit(EV_REL, input->evbit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) input_set_capability(input, EV_REL, REL_X);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) input_set_capability(input, EV_REL, REL_Y);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) input_set_capability(input, EV_MSC, MSC_SCAN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) input_set_capability(input, EV_KEY, 0x110);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) error = input_register_device(input);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) hid_err(hdev, "rkvr-s: Unable to register input device, error: %d\n", error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) hdev->hiddev = input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) static inline int __must_check rkvr_hw_start(struct hid_device *hdev, unsigned int connect_mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) int ret = hdev->ll_driver->start(hdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) ret = rkvr_connect(hdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) hdev->ll_driver->stop(hdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) static void rkvr_disconnect(struct hid_device *hid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) struct hidraw *hidraw = hid->hidraw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) mutex_lock(&minors_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) /* always unregistering inv_hid_device when hardware disconnect */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) inv_hid_unregister_and_destroy_devcie_by_name("hid-rkvr");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) #if DEBUG_SYS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) device_remove_file(hidraw->dev, &dev_attr_debug);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) device_remove_file(hidraw->dev, &dev_attr_sync);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) device_destroy(rkvr_class, MKDEV(rkvr_major, hidraw->minor));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) rkvr_drop_ref(hidraw, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) mutex_unlock(&minors_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) static void rkvr_hw_stop(struct hid_device *hdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) rkvr_disconnect(hdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) hdev->ll_driver->stop(hdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) static long rkvr_hidraw_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) struct inode *inode = file_inode(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) unsigned int minor = iminor(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) long ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) struct hidraw *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) void __user *user_arg = (void __user *)arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) mutex_lock(&minors_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) dev = rkvr_hidraw_table[minor];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) if (!dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) case HIDIOCGRDESCSIZE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) if (put_user(dev->hid->rsize, (int __user *)arg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) ret = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) case HIDIOCGRDESC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) __u32 len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) if (get_user(len, (int __user *)arg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) ret = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) else if (len > HID_MAX_DESCRIPTOR_SIZE - 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) else if (copy_to_user(user_arg + offsetof(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) struct hidraw_report_descriptor,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) value[0]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) dev->hid->rdesc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) min(dev->hid->rsize, len)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) ret = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) case HIDIOCGRAWINFO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) struct hidraw_devinfo dinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) dinfo.bustype = dev->hid->bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) dinfo.vendor = dev->hid->vendor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) dinfo.product = dev->hid->product;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) if (copy_to_user(user_arg, &dinfo, sizeof(dinfo)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) ret = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) struct hid_device *hid = dev->hid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) if (_IOC_TYPE(cmd) != 'H') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) if (_IOC_NR(cmd) == _IOC_NR(HIDIOCSFEATURE(0))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) int len = _IOC_SIZE(cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) ret = rkvr_hidraw_send_report(file, user_arg, len, HID_FEATURE_REPORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) if (_IOC_NR(cmd) == _IOC_NR(HIDIOCGFEATURE(0))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) int len = _IOC_SIZE(cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) ret = rkvr_hidraw_get_report(file, user_arg, len, HID_FEATURE_REPORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) if (_IOC_NR(cmd) == _IOC_NR(HIDRKVRHANDSHAKE(0))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) int len = _IOC_SIZE(cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) char *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) buf = kzalloc(len + 1, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) if (!buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) if (copy_from_user(buf, user_arg, len)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) ret = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) kfree(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) ret = hid_report_sync(&hid->dev, buf, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) kfree(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) /* Begin Read-only ioctls. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) if (_IOC_DIR(cmd) != _IOC_READ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) if (_IOC_NR(cmd) == _IOC_NR(HIDIOCGRAWNAME(0))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) int len = strlen(hid->name) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) if (len > _IOC_SIZE(cmd))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) len = _IOC_SIZE(cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) ret = copy_to_user(user_arg, hid->name, len) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) -EFAULT : len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) if (_IOC_NR(cmd) == _IOC_NR(HIDIOCGRAWPHYS(0))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) int len = strlen(hid->phys) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) if (len > _IOC_SIZE(cmd))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) len = _IOC_SIZE(cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) ret = copy_to_user(user_arg, hid->phys, len) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) -EFAULT : len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) ret = -ENOTTY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) mutex_unlock(&minors_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) static const struct file_operations rkvr_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) .read = rkvr_hidraw_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) .write = rkvr_hidraw_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) .poll = rkvr_hidraw_poll,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) .open = rkvr_hidraw_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) .release = rkvr_hidraw_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) .unlocked_ioctl = rkvr_hidraw_ioctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) #ifdef CONFIG_COMPAT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) .compat_ioctl = rkvr_hidraw_ioctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) .fasync = rkvr_hidraw_fasync,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) .llseek = noop_llseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) int rkvr_sensor_register_callback(int (*callback)(char *, size_t, void *), void *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) sensorData.priv = priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) sensorData.send_event = callback;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) EXPORT_SYMBOL_GPL(rkvr_sensor_register_callback);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) static int rkvr_fb_event_notify(struct notifier_block *self,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) unsigned long action, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) unsigned char buf[3] = {HID_REPORT_ID_RKVR, RKVR_ID_IDLE, 0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) struct hid_device *hid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) struct fb_event *event = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) int blank_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) if (action != FB_EARLY_EVENT_BLANK && action != FB_EVENT_BLANK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) return NOTIFY_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) blank_mode = *((int *)event->data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) mutex_lock(&minors_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) for (i = 0; i < RKVR_HIDRAW_MAX_DEVICES; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) if (!rkvr_hidraw_table[i] || !rkvr_hidraw_table[i]->exist)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) if (!rkvr_hid_capability[i].suspend_notify) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) hid = rkvr_hidraw_table[i]->hid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) if (action == FB_EARLY_EVENT_BLANK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) switch (blank_mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) case FB_BLANK_UNBLANK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) rkvr_send_report(&hid->dev, buf, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) } else if (action == FB_EVENT_BLANK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) switch (blank_mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) case FB_BLANK_UNBLANK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) buf[2] = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) rkvr_send_report(&hid->dev, buf, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) mutex_unlock(&minors_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) return NOTIFY_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) static struct notifier_block rkvr_fb_notifier = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) .notifier_call = rkvr_fb_event_notify,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) static int rkvr_probe(struct hid_device *hdev, const struct hid_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) int retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) retval = hid_parse(hdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) if (retval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) hid_err(hdev, "rkvr - parse failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) hid_set_drvdata(hdev, &sensorData);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) if (intf->cur_altsetting->desc.bInterfaceNumber == RKVR_INTERFACE_USB_SENSOR_ID) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) retval = rkvr_keys_probe(hdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) if (retval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) hid_err(hdev, "rkvr_keys_probe failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) goto exit_stop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) retval = rkvr_hw_start(hdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) if (retval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) hid_err(hdev, "rkvr - rkvr hw start failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) rkvr_keys_remove(hdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) goto exit_stop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) retval = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) if (retval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) hid_err(hdev, "rkvr - hid hw start failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) exit_stop:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) hid_hw_stop(hdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) static void rkvr_remove(struct hid_device *hdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) if (intf->cur_altsetting->desc.bInterfaceNumber == RKVR_INTERFACE_USB_SENSOR_ID) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) rkvr_hw_stop(hdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) rkvr_keys_remove(hdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) hid_hw_stop(hdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) static int rkvr_raw_event(struct hid_device *hdev, struct hid_report *report, u8 *data, int size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) int retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) static unsigned int count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) static unsigned long old_jiffy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) if (intf->cur_altsetting->desc.bInterfaceNumber != RKVR_INTERFACE_USB_SENSOR_ID) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) hid_info(hdev, "%s,ignored interface number is %d\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) intf->cur_altsetting->desc.bInterfaceNumber);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) /* print sensor poll frequency */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) if (++count >= 1000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) unsigned long cur_jiffy = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) hid_dbg(hdev, "rkvr: %d Hz, hidrkvr %d\n", (int)(1000 * HZ / (cur_jiffy - old_jiffy)), (hdev->hidraw ? 1 : 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) old_jiffy = cur_jiffy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) if (hdev->hidraw || hdev->hiddev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) retval = rkvr_report_event(hdev, data, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) if (retval < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) hid_info(hdev, "rkvr: raw event err %d\n", retval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) static const struct hid_device_id rkvr_devices[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) { HID_USB_DEVICE(USB_VENDOR_ID_ROCKCHIP, USB_DEVICE_ID_NANOC) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) MODULE_DEVICE_TABLE(hid, rkvr_devices);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) static struct hid_driver rkvr_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) .name = "rkvr",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) .id_table = rkvr_devices,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) .probe = rkvr_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) .remove = rkvr_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) .raw_event = rkvr_raw_event
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) static int __init rkvr_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) int retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) dev_t dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) rkvr_class = class_create(THIS_MODULE, "rkvr");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) if (IS_ERR(rkvr_class))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) return PTR_ERR(rkvr_class);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) retval = hid_register_driver(&rkvr_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) if (retval < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) pr_warn("rkvr_init - Can't register drive.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) goto out_class;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) retval = alloc_chrdev_region(&dev_id, RKVR_FIRST_MINOR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) RKVR_HIDRAW_MAX_DEVICES, "rkvr");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) if (retval < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) pr_warn("rkvr_init - Can't allocate chrdev region.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) goto out_register;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) rkvr_major = MAJOR(dev_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) cdev_init(&rkvr_cdev, &rkvr_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) cdev_add(&rkvr_cdev, dev_id, RKVR_HIDRAW_MAX_DEVICES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) retval = fb_register_client(&rkvr_fb_notifier);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) if (retval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) pr_warn("rkvr_init - Can't register fb notifier\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) goto out_chardev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) out_chardev:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) unregister_chrdev_region(dev_id, RKVR_HIDRAW_MAX_DEVICES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) out_register:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) hid_unregister_driver(&rkvr_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) out_class:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) class_destroy(rkvr_class);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) static void __exit rkvr_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) dev_t dev_id = MKDEV(rkvr_major, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) fb_unregister_client(&rkvr_fb_notifier);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) cdev_del(&rkvr_cdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) unregister_chrdev_region(dev_id, RKVR_HIDRAW_MAX_DEVICES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) hid_unregister_driver(&rkvr_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) class_destroy(rkvr_class);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) module_init(rkvr_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) module_exit(rkvr_exit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) MODULE_AUTHOR("zwp");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) MODULE_DESCRIPTION("USB ROCKCHIP VR char device driver.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) MODULE_LICENSE("GPL v2");