diff options
Diffstat (limited to 'sys-kernel/linux-sources-redcore-lts-legacy/files/5.10-add-amd-sfh-hid_driver.patch')
-rw-r--r-- | sys-kernel/linux-sources-redcore-lts-legacy/files/5.10-add-amd-sfh-hid_driver.patch | 1783 |
1 files changed, 1783 insertions, 0 deletions
diff --git a/sys-kernel/linux-sources-redcore-lts-legacy/files/5.10-add-amd-sfh-hid_driver.patch b/sys-kernel/linux-sources-redcore-lts-legacy/files/5.10-add-amd-sfh-hid_driver.patch new file mode 100644 index 00000000..dd8badee --- /dev/null +++ b/sys-kernel/linux-sources-redcore-lts-legacy/files/5.10-add-amd-sfh-hid_driver.patch @@ -0,0 +1,1783 @@ +diff -Naur linux-5.10.2/drivers/hid/amd-sfh-hid/amd_sfh_client.c linux-5.10.2-amd/drivers/hid/amd-sfh-hid/amd_sfh_client.c +--- linux-5.10.2/drivers/hid/amd-sfh-hid/amd_sfh_client.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-5.10.2-amd/drivers/hid/amd-sfh-hid/amd_sfh_client.c 2020-12-25 14:25:44.298391979 +0100 +@@ -0,0 +1,246 @@ ++// SPDX-License-Identifier: GPL-2.0-or-later ++/* ++ * AMD SFH Client Layer ++ * Copyright 2020 Advanced Micro Devices, Inc. ++ * Authors: Nehal Bakulchandra Shah <Nehal-Bakulchandra.Shah@amd.com> ++ * Sandeep Singh <Sandeep.singh@amd.com> ++ */ ++ ++#include <linux/dma-mapping.h> ++#include <linux/hid.h> ++#include <linux/list.h> ++#include <linux/slab.h> ++#include <linux/workqueue.h> ++#include <linux/errno.h> ++ ++#include "hid_descriptor/amd_sfh_hid_desc.h" ++#include "amd_sfh_pcie.h" ++#include "amd_sfh_hid.h" ++ ++#define AMD_SFH_IDLE_LOOP 200 ++ ++struct request_list { ++ struct hid_device *hid; ++ struct list_head list; ++ u8 report_id; ++ u8 sensor_idx; ++ u8 report_type; ++ u8 current_index; ++}; ++ ++static struct request_list req_list; ++ ++void amd_sfh_set_report(struct hid_device *hid, int report_id, ++ int report_type) ++{ ++ struct amdtp_hid_data *hid_data = hid->driver_data; ++ struct amdtp_cl_data *cli_data = hid_data->cli_data; ++ int i; ++ ++ for (i = 0; i < cli_data->num_hid_devices; i++) { ++ if (cli_data->hid_sensor_hubs[i] == hid) { ++ cli_data->cur_hid_dev = i; ++ break; ++ } ++ } ++ amdtp_hid_wakeup(hid); ++} ++ ++int amd_sfh_get_report(struct hid_device *hid, int report_id, int report_type) ++{ ++ struct amdtp_hid_data *hid_data = hid->driver_data; ++ struct amdtp_cl_data *cli_data = hid_data->cli_data; ++ int i; ++ ++ for (i = 0; i < cli_data->num_hid_devices; i++) { ++ if (cli_data->hid_sensor_hubs[i] == hid) { ++ struct request_list *new = kzalloc(sizeof(*new), GFP_KERNEL); ++ ++ if (!new) ++ return -ENOMEM; ++ ++ new->current_index = i; ++ new->sensor_idx = cli_data->sensor_idx[i]; ++ new->hid = hid; ++ new->report_type = report_type; ++ new->report_id = report_id; ++ cli_data->report_id[i] = report_id; ++ cli_data->request_done[i] = false; ++ list_add(&new->list, &req_list.list); ++ break; ++ } ++ } ++ schedule_delayed_work(&cli_data->work, 0); ++ return 0; ++} ++ ++static void amd_sfh_work(struct work_struct *work) ++{ ++ struct amdtp_cl_data *cli_data = container_of(work, struct amdtp_cl_data, work.work); ++ struct request_list *req_node; ++ u8 current_index, sensor_index; ++ u8 report_id, node_type; ++ u8 report_size = 0; ++ ++ req_node = list_last_entry(&req_list.list, struct request_list, list); ++ list_del(&req_node->list); ++ current_index = req_node->current_index; ++ sensor_index = req_node->sensor_idx; ++ report_id = req_node->report_id; ++ node_type = req_node->report_type; ++ ++ if (node_type == HID_FEATURE_REPORT) { ++ report_size = get_feature_report(sensor_index, report_id, ++ cli_data->feature_report[current_index]); ++ if (report_size) ++ hid_input_report(cli_data->hid_sensor_hubs[current_index], ++ cli_data->report_type[current_index], ++ cli_data->feature_report[current_index], report_size, 0); ++ else ++ pr_err("AMDSFH: Invalid report size\n"); ++ ++ } else if (node_type == HID_INPUT_REPORT) { ++ report_size = get_input_report(sensor_index, report_id, ++ cli_data->input_report[current_index], ++ cli_data->sensor_virt_addr[current_index]); ++ if (report_size) ++ hid_input_report(cli_data->hid_sensor_hubs[current_index], ++ cli_data->report_type[current_index], ++ cli_data->input_report[current_index], report_size, 0); ++ else ++ pr_err("AMDSFH: Invalid report size\n"); ++ } ++ cli_data->cur_hid_dev = current_index; ++ cli_data->sensor_requested_cnt[current_index] = 0; ++ amdtp_hid_wakeup(cli_data->hid_sensor_hubs[current_index]); ++} ++ ++static void amd_sfh_work_buffer(struct work_struct *work) ++{ ++ struct amdtp_cl_data *cli_data = container_of(work, struct amdtp_cl_data, work_buffer.work); ++ u8 report_size; ++ int i; ++ ++ for (i = 0; i < cli_data->num_hid_devices; i++) { ++ report_size = get_input_report(cli_data->sensor_idx[i], cli_data->report_id[i], ++ cli_data->input_report[i], ++ cli_data->sensor_virt_addr[i]); ++ hid_input_report(cli_data->hid_sensor_hubs[i], HID_INPUT_REPORT, ++ cli_data->input_report[i], report_size, 0); ++ } ++ schedule_delayed_work(&cli_data->work_buffer, msecs_to_jiffies(AMD_SFH_IDLE_LOOP)); ++} ++ ++int amd_sfh_hid_client_init(struct amd_mp2_dev *privdata) ++{ ++ struct amdtp_cl_data *cl_data = privdata->cl_data; ++ struct amd_mp2_sensor_info info; ++ struct device *dev; ++ u32 feature_report_size; ++ u32 input_report_size; ++ u8 cl_idx; ++ int rc, i; ++ ++ dev = &privdata->pdev->dev; ++ cl_data = kzalloc(sizeof(*cl_data), GFP_KERNEL); ++ if (!cl_data) ++ return -ENOMEM; ++ ++ cl_data->num_hid_devices = amd_mp2_get_sensor_num(privdata, &cl_data->sensor_idx[0]); ++ ++ INIT_DELAYED_WORK(&cl_data->work, amd_sfh_work); ++ INIT_DELAYED_WORK(&cl_data->work_buffer, amd_sfh_work_buffer); ++ INIT_LIST_HEAD(&req_list.list); ++ ++ for (i = 0; i < cl_data->num_hid_devices; i++) { ++ cl_data->sensor_virt_addr[i] = dma_alloc_coherent(dev, sizeof(int) * 8, ++ &cl_data->sensor_phys_addr[i], ++ GFP_KERNEL); ++ cl_data->sensor_sts[i] = 0; ++ cl_data->sensor_requested_cnt[i] = 0; ++ cl_data->cur_hid_dev = i; ++ cl_idx = cl_data->sensor_idx[i]; ++ cl_data->report_descr_sz[i] = get_descr_sz(cl_idx, descr_size); ++ if (!cl_data->report_descr_sz[i]) { ++ rc = -EINVAL; ++ goto cleanup; ++ } ++ feature_report_size = get_descr_sz(cl_idx, feature_size); ++ if (!feature_report_size) { ++ rc = -EINVAL; ++ goto cleanup; ++ } ++ input_report_size = get_descr_sz(cl_idx, input_size); ++ if (!input_report_size) { ++ rc = -EINVAL; ++ goto cleanup; ++ } ++ cl_data->feature_report[i] = kzalloc(feature_report_size, GFP_KERNEL); ++ if (!cl_data->feature_report[i]) { ++ rc = -ENOMEM; ++ goto cleanup; ++ } ++ cl_data->input_report[i] = kzalloc(input_report_size, GFP_KERNEL); ++ if (!cl_data->input_report[i]) { ++ rc = -ENOMEM; ++ goto cleanup; ++ } ++ info.period = msecs_to_jiffies(AMD_SFH_IDLE_LOOP); ++ info.sensor_idx = cl_idx; ++ info.phys_address = cl_data->sensor_phys_addr[i]; ++ ++ cl_data->report_descr[i] = kzalloc(cl_data->report_descr_sz[i], GFP_KERNEL); ++ if (!cl_data->report_descr[i]) { ++ rc = -ENOMEM; ++ goto cleanup; ++ } ++ rc = get_report_descriptor(cl_idx, cl_data->report_descr[i]); ++ if (rc) ++ return rc; ++ rc = amdtp_hid_probe(cl_data->cur_hid_dev, cl_data); ++ if (rc) ++ return rc; ++ amd_start_sensor(privdata, info); ++ cl_data->sensor_sts[i] = 1; ++ } ++ privdata->cl_data = cl_data; ++ schedule_delayed_work(&cl_data->work_buffer, msecs_to_jiffies(AMD_SFH_IDLE_LOOP)); ++ return 0; ++ ++cleanup: ++ for (i = 0; i < cl_data->num_hid_devices; i++) { ++ if (cl_data->sensor_virt_addr[i]) { ++ dma_free_coherent(&privdata->pdev->dev, 8 * sizeof(int), ++ cl_data->sensor_virt_addr[i], ++ cl_data->sensor_phys_addr[i]); ++ } ++ kfree(cl_data->feature_report[i]); ++ kfree(cl_data->input_report[i]); ++ kfree(cl_data->report_descr[i]); ++ } ++ kfree(cl_data); ++ return rc; ++} ++ ++int amd_sfh_hid_client_deinit(struct amd_mp2_dev *privdata) ++{ ++ struct amdtp_cl_data *cl_data = privdata->cl_data; ++ int i; ++ ++ for (i = 0; i < cl_data->num_hid_devices; i++) ++ amd_stop_sensor(privdata, i); ++ ++ cancel_delayed_work_sync(&cl_data->work); ++ cancel_delayed_work_sync(&cl_data->work_buffer); ++ amdtp_hid_remove(cl_data); ++ ++ for (i = 0; i < cl_data->num_hid_devices; i++) { ++ if (cl_data->sensor_virt_addr[i]) { ++ dma_free_coherent(&privdata->pdev->dev, 8 * sizeof(int), ++ cl_data->sensor_virt_addr[i], ++ cl_data->sensor_phys_addr[i]); ++ } ++ } ++ kfree(cl_data); ++ return 0; ++} +diff -Naur linux-5.10.2/drivers/hid/amd-sfh-hid/amd_sfh_hid.c linux-5.10.2-amd/drivers/hid/amd-sfh-hid/amd_sfh_hid.c +--- linux-5.10.2/drivers/hid/amd-sfh-hid/amd_sfh_hid.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-5.10.2-amd/drivers/hid/amd-sfh-hid/amd_sfh_hid.c 2020-12-25 14:25:44.298391979 +0100 +@@ -0,0 +1,174 @@ ++// SPDX-License-Identifier: GPL-2.0-or-later ++/* ++ * AMD MP2 Sensors transport driver ++ * ++ * Authors: Nehal Bakulchandra Shah <Nehal-bakulchandra.shah@amd.com> ++ * Sandeep Singh <sandeep.singh@amd.com> ++ */ ++#include <linux/hid.h> ++#include <linux/wait.h> ++#include <linux/sched.h> ++ ++#include "amd_sfh_hid.h" ++ ++#define AMD_SFH_RESPONSE_TIMEOUT 1500 ++ ++/** ++ * amdtp_hid_parse() - hid-core .parse() callback ++ * @hid: hid device instance ++ * ++ * This function gets called during call to hid_add_device ++ * ++ * Return: 0 on success and non zero on error ++ */ ++static int amdtp_hid_parse(struct hid_device *hid) ++{ ++ struct amdtp_hid_data *hid_data = hid->driver_data; ++ struct amdtp_cl_data *cli_data = hid_data->cli_data; ++ ++ return hid_parse_report(hid, cli_data->report_descr[hid_data->index], ++ cli_data->report_descr_sz[hid_data->index]); ++} ++ ++/* Empty callbacks with success return code */ ++static int amdtp_hid_start(struct hid_device *hid) ++{ ++ return 0; ++} ++ ++static void amdtp_hid_stop(struct hid_device *hid) ++{ ++} ++ ++static int amdtp_hid_open(struct hid_device *hid) ++{ ++ return 0; ++} ++ ++static void amdtp_hid_close(struct hid_device *hid) ++{ ++} ++ ++static int amdtp_raw_request(struct hid_device *hdev, u8 reportnum, ++ u8 *buf, size_t len, u8 rtype, int reqtype) ++{ ++ return 0; ++} ++ ++static void amdtp_hid_request(struct hid_device *hid, struct hid_report *rep, int reqtype) ++{ ++ int rc; ++ ++ switch (reqtype) { ++ case HID_REQ_GET_REPORT: ++ rc = amd_sfh_get_report(hid, rep->id, rep->type); ++ if (rc) ++ dev_err(&hid->dev, "AMDSFH get report error\n"); ++ break; ++ case HID_REQ_SET_REPORT: ++ amd_sfh_set_report(hid, rep->id, reqtype); ++ break; ++ default: ++ break; ++ } ++} ++ ++static int amdtp_wait_for_response(struct hid_device *hid) ++{ ++ struct amdtp_hid_data *hid_data = hid->driver_data; ++ struct amdtp_cl_data *cli_data = hid_data->cli_data; ++ int i, ret = 0; ++ ++ for (i = 0; i < cli_data->num_hid_devices; i++) { ++ if (cli_data->hid_sensor_hubs[i] == hid) ++ break; ++ } ++ ++ if (!cli_data->request_done[i]) ++ ret = wait_event_interruptible_timeout(hid_data->hid_wait, ++ cli_data->request_done[i], ++ msecs_to_jiffies(AMD_SFH_RESPONSE_TIMEOUT)); ++ if (ret == -ERESTARTSYS) ++ return -ERESTARTSYS; ++ else if (ret < 0) ++ return -ETIMEDOUT; ++ else ++ return 0; ++} ++ ++void amdtp_hid_wakeup(struct hid_device *hid) ++{ ++ struct amdtp_hid_data *hid_data = hid->driver_data; ++ struct amdtp_cl_data *cli_data = hid_data->cli_data; ++ ++ cli_data->request_done[cli_data->cur_hid_dev] = true; ++ wake_up_interruptible(&hid_data->hid_wait); ++} ++ ++static struct hid_ll_driver amdtp_hid_ll_driver = { ++ .parse = amdtp_hid_parse, ++ .start = amdtp_hid_start, ++ .stop = amdtp_hid_stop, ++ .open = amdtp_hid_open, ++ .close = amdtp_hid_close, ++ .request = amdtp_hid_request, ++ .wait = amdtp_wait_for_response, ++ .raw_request = amdtp_raw_request, ++}; ++ ++int amdtp_hid_probe(u32 cur_hid_dev, struct amdtp_cl_data *cli_data) ++{ ++ struct hid_device *hid; ++ struct amdtp_hid_data *hid_data; ++ int rc; ++ ++ hid = hid_allocate_device(); ++ if (IS_ERR(hid)) ++ return PTR_ERR(hid); ++ ++ hid_data = kzalloc(sizeof(*hid_data), GFP_KERNEL); ++ if (!hid_data) { ++ rc = -ENOMEM; ++ goto err_hid_data; ++ } ++ ++ hid->ll_driver = &amdtp_hid_ll_driver; ++ hid_data->index = cur_hid_dev; ++ hid_data->cli_data = cli_data; ++ init_waitqueue_head(&hid_data->hid_wait); ++ ++ hid->driver_data = hid_data; ++ cli_data->hid_sensor_hubs[cur_hid_dev] = hid; ++ hid->bus = BUS_AMD_AMDTP; ++ hid->vendor = AMD_SFH_HID_VENDOR; ++ hid->product = AMD_SFH_HID_PRODUCT; ++ snprintf(hid->name, sizeof(hid->name), "%s %04X:%04X", "hid-amdtp", ++ hid->vendor, hid->product); ++ ++ rc = hid_add_device(hid); ++ if (rc) ++ goto err_hid_device; ++ return 0; ++ ++err_hid_device: ++ kfree(hid_data); ++err_hid_data: ++ hid_destroy_device(hid); ++ return rc; ++} ++ ++void amdtp_hid_remove(struct amdtp_cl_data *cli_data) ++{ ++ int i; ++ ++ for (i = 0; i < cli_data->num_hid_devices; ++i) { ++ kfree(cli_data->feature_report[i]); ++ kfree(cli_data->input_report[i]); ++ kfree(cli_data->report_descr[i]); ++ if (cli_data->hid_sensor_hubs[i]) { ++ kfree(cli_data->hid_sensor_hubs[i]->driver_data); ++ hid_destroy_device(cli_data->hid_sensor_hubs[i]); ++ cli_data->hid_sensor_hubs[i] = NULL; ++ } ++ } ++} +diff -Naur linux-5.10.2/drivers/hid/amd-sfh-hid/amd_sfh_hid.h linux-5.10.2-amd/drivers/hid/amd-sfh-hid/amd_sfh_hid.h +--- linux-5.10.2/drivers/hid/amd-sfh-hid/amd_sfh_hid.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-5.10.2-amd/drivers/hid/amd-sfh-hid/amd_sfh_hid.h 2020-12-25 14:25:44.299391977 +0100 +@@ -0,0 +1,67 @@ ++/* SPDX-License-Identifier: GPL-2.0-or-later */ ++/* ++ * AMD MP2 Sensors transport driver ++ * ++ * Authors: Nehal Bakulchandra Shah <Nehal-bakulchandra.shah@amd.com> ++ * Sandeep Singh <sandeep.singh@amd.com> ++ */ ++ ++#ifndef AMDSFH_HID_H ++#define AMDSFH_HID_H ++ ++#define MAX_HID_DEVICES 4 ++#define BUS_AMD_AMDTP 0x20 ++#define AMD_SFH_HID_VENDOR 0x1022 ++#define AMD_SFH_HID_PRODUCT 0x0001 ++ ++struct amdtp_cl_data { ++ u8 init_done; ++ u32 cur_hid_dev; ++ u32 hid_dev_count; ++ u32 num_hid_devices; ++ struct device_info *hid_devices; ++ u8 *report_descr[MAX_HID_DEVICES]; ++ int report_descr_sz[MAX_HID_DEVICES]; ++ struct hid_device *hid_sensor_hubs[MAX_HID_DEVICES]; ++ u8 *hid_descr[MAX_HID_DEVICES]; ++ int hid_descr_size[MAX_HID_DEVICES]; ++ phys_addr_t phys_addr_base; ++ u32 *sensor_virt_addr[MAX_HID_DEVICES]; ++ phys_addr_t sensor_phys_addr[MAX_HID_DEVICES]; ++ u32 sensor_sts[MAX_HID_DEVICES]; ++ u32 sensor_requested_cnt[MAX_HID_DEVICES]; ++ u8 report_type[MAX_HID_DEVICES]; ++ u8 report_id[MAX_HID_DEVICES]; ++ u8 sensor_idx[MAX_HID_DEVICES]; ++ u8 *feature_report[MAX_HID_DEVICES]; ++ u8 *input_report[MAX_HID_DEVICES]; ++ u8 request_done[MAX_HID_DEVICES]; ++ struct delayed_work work; ++ struct delayed_work work_buffer; ++}; ++ ++/** ++ * struct amdtp_hid_data - Per instance HID data ++ * @index: Device index in the order of enumeration ++ * @request_done: Get Feature/Input report complete flag ++ * used during get/set request from hid core ++ * @cli_data: Link to the client instance ++ * @hid_wait: Completion waitq ++ * ++ * Used to tie hid->driver data to driver client instance ++ */ ++struct amdtp_hid_data { ++ int index; ++ struct amdtp_cl_data *cli_data; ++ wait_queue_head_t hid_wait; ++}; ++ ++/* Interface functions between HID LL driver and AMD SFH client */ ++void hid_amdtp_set_feature(struct hid_device *hid, char *buf, u32 len, int report_id); ++void hid_amdtp_get_report(struct hid_device *hid, int report_id, int report_type); ++int amdtp_hid_probe(u32 cur_hid_dev, struct amdtp_cl_data *cli_data); ++void amdtp_hid_remove(struct amdtp_cl_data *cli_data); ++int amd_sfh_get_report(struct hid_device *hid, int report_id, int report_type); ++void amd_sfh_set_report(struct hid_device *hid, int report_id, int report_type); ++void amdtp_hid_wakeup(struct hid_device *hid); ++#endif +diff -Naur linux-5.10.2/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c linux-5.10.2-amd/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c +--- linux-5.10.2/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-5.10.2-amd/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c 2020-12-25 14:25:44.299391977 +0100 +@@ -0,0 +1,152 @@ ++// SPDX-License-Identifier: GPL-2.0-or-later ++/* ++ * AMD MP2 PCIe communication driver ++ * Copyright 2020 Advanced Micro Devices, Inc. ++ * ++ * Authors: Shyam Sundar S K <Shyam-sundar.S-k@amd.com> ++ * Sandeep Singh <Sandeep.singh@amd.com> ++ */ ++ ++#include <linux/bitops.h> ++#include <linux/delay.h> ++#include <linux/dma-mapping.h> ++#include <linux/interrupt.h> ++#include <linux/io-64-nonatomic-lo-hi.h> ++#include <linux/module.h> ++#include <linux/slab.h> ++ ++#include "amd_sfh_pcie.h" ++ ++#define DRIVER_NAME "pcie_mp2_amd" ++#define DRIVER_DESC "AMD(R) PCIe MP2 Communication Driver" ++ ++#define ACEL_EN BIT(0) ++#define GYRO_EN BIT(1) ++#define MAGNO_EN BIT(2) ++#define ALS_EN BIT(19) ++ ++void amd_start_sensor(struct amd_mp2_dev *privdata, struct amd_mp2_sensor_info info) ++{ ++ union sfh_cmd_param cmd_param; ++ union sfh_cmd_base cmd_base; ++ ++ /* fill up command register */ ++ memset(&cmd_base, 0, sizeof(cmd_base)); ++ cmd_base.s.cmd_id = ENABLE_SENSOR; ++ cmd_base.s.period = info.period; ++ cmd_base.s.sensor_id = info.sensor_idx; ++ ++ /* fill up command param register */ ++ memset(&cmd_param, 0, sizeof(cmd_param)); ++ cmd_param.s.buf_layout = 1; ++ cmd_param.s.buf_length = 16; ++ ++ writeq(info.phys_address, privdata->mmio + AMD_C2P_MSG2); ++ writel(cmd_param.ul, privdata->mmio + AMD_C2P_MSG1); ++ writel(cmd_base.ul, privdata->mmio + AMD_C2P_MSG0); ++} ++ ++void amd_stop_sensor(struct amd_mp2_dev *privdata, u16 sensor_idx) ++{ ++ union sfh_cmd_base cmd_base; ++ ++ /* fill up command register */ ++ memset(&cmd_base, 0, sizeof(cmd_base)); ++ cmd_base.s.cmd_id = DISABLE_SENSOR; ++ cmd_base.s.period = 0; ++ cmd_base.s.sensor_id = sensor_idx; ++ ++ writeq(0x0, privdata->mmio + AMD_C2P_MSG2); ++ writel(cmd_base.ul, privdata->mmio + AMD_C2P_MSG0); ++} ++ ++void amd_stop_all_sensors(struct amd_mp2_dev *privdata) ++{ ++ union sfh_cmd_base cmd_base; ++ ++ /* fill up command register */ ++ memset(&cmd_base, 0, sizeof(cmd_base)); ++ cmd_base.s.cmd_id = STOP_ALL_SENSORS; ++ cmd_base.s.period = 0; ++ cmd_base.s.sensor_id = 0; ++ ++ writel(cmd_base.ul, privdata->mmio + AMD_C2P_MSG0); ++} ++ ++int amd_mp2_get_sensor_num(struct amd_mp2_dev *privdata, u8 *sensor_id) ++{ ++ int activestatus, num_of_sensors = 0; ++ ++ privdata->activecontrolstatus = readl(privdata->mmio + AMD_P2C_MSG3); ++ activestatus = privdata->activecontrolstatus >> 4; ++ if (ACEL_EN & activestatus) ++ sensor_id[num_of_sensors++] = accel_idx; ++ ++ if (GYRO_EN & activestatus) ++ sensor_id[num_of_sensors++] = gyro_idx; ++ ++ if (MAGNO_EN & activestatus) ++ sensor_id[num_of_sensors++] = mag_idx; ++ ++ if (ALS_EN & activestatus) ++ sensor_id[num_of_sensors++] = als_idx; ++ ++ return num_of_sensors; ++} ++ ++static void amd_mp2_pci_remove(void *privdata) ++{ ++ amd_sfh_hid_client_deinit(privdata); ++ amd_stop_all_sensors(privdata); ++} ++ ++static int amd_mp2_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) ++{ ++ struct amd_mp2_dev *privdata; ++ int rc; ++ ++ privdata = devm_kzalloc(&pdev->dev, sizeof(*privdata), GFP_KERNEL); ++ if (!privdata) ++ return -ENOMEM; ++ ++ privdata->pdev = pdev; ++ pci_set_drvdata(pdev, privdata); ++ rc = pcim_enable_device(pdev); ++ if (rc) ++ return rc; ++ ++ rc = pcim_iomap_regions(pdev, BIT(2), DRIVER_NAME); ++ if (rc) ++ return rc; ++ ++ privdata->mmio = pcim_iomap_table(pdev)[2]; ++ pci_set_master(pdev); ++ rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(64)); ++ if (rc) { ++ rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); ++ return rc; ++ } ++ rc = devm_add_action_or_reset(&pdev->dev, amd_mp2_pci_remove, privdata); ++ if (rc) ++ return rc; ++ ++ return amd_sfh_hid_client_init(privdata); ++} ++ ++static const struct pci_device_id amd_mp2_pci_tbl[] = { ++ { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_MP2) }, ++ { } ++}; ++MODULE_DEVICE_TABLE(pci, amd_mp2_pci_tbl); ++ ++static struct pci_driver amd_mp2_pci_driver = { ++ .name = DRIVER_NAME, ++ .id_table = amd_mp2_pci_tbl, ++ .probe = amd_mp2_pci_probe, ++}; ++module_pci_driver(amd_mp2_pci_driver); ++ ++MODULE_DESCRIPTION(DRIVER_DESC); ++MODULE_LICENSE("Dual BSD/GPL"); ++MODULE_AUTHOR("Shyam Sundar S K <Shyam-sundar.S-k@amd.com>"); ++MODULE_AUTHOR("Sandeep Singh <Sandeep.singh@amd.com>"); +diff -Naur linux-5.10.2/drivers/hid/amd-sfh-hid/amd_sfh_pcie.h linux-5.10.2-amd/drivers/hid/amd-sfh-hid/amd_sfh_pcie.h +--- linux-5.10.2/drivers/hid/amd-sfh-hid/amd_sfh_pcie.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-5.10.2-amd/drivers/hid/amd-sfh-hid/amd_sfh_pcie.h 2020-12-25 14:25:44.299391977 +0100 +@@ -0,0 +1,79 @@ ++/* SPDX-License-Identifier: GPL-2.0-or-later */ ++/* ++ * AMD MP2 PCIe communication driver ++ * Copyright 2020 Advanced Micro Devices, Inc. ++ * Authors: Shyam Sundar S K <Shyam-sundar.S-k@amd.com> ++ * Sandeep Singh <Sandeep.singh@amd.com> ++ */ ++ ++#ifndef PCIE_MP2_AMD_H ++#define PCIE_MP2_AMD_H ++ ++#include <linux/pci.h> ++ ++#define PCI_DEVICE_ID_AMD_MP2 0x15E4 ++ ++#define ENABLE_SENSOR 1 ++#define DISABLE_SENSOR 2 ++#define STOP_ALL_SENSORS 8 ++ ++/* MP2 C2P Message Registers */ ++#define AMD_C2P_MSG0 0x10500 ++#define AMD_C2P_MSG1 0x10504 ++#define AMD_C2P_MSG2 0x10508 ++ ++/* MP2 P2C Message Registers */ ++#define AMD_P2C_MSG3 0x1068C /* Supported Sensors info */ ++ ++/* SFH Command register */ ++union sfh_cmd_base { ++ u32 ul; ++ struct { ++ u32 cmd_id : 8; ++ u32 sensor_id : 8; ++ u32 period : 16; ++ } s; ++}; ++ ++union sfh_cmd_param { ++ u32 ul; ++ struct { ++ u32 buf_layout : 2; ++ u32 buf_length : 6; ++ u32 rsvd : 24; ++ } s; ++}; ++ ++struct sfh_cmd_reg { ++ union sfh_cmd_base cmd_base; ++ union sfh_cmd_param cmd_param; ++ phys_addr_t phys_addr; ++}; ++ ++enum sensor_idx { ++ accel_idx = 0, ++ gyro_idx = 1, ++ mag_idx = 2, ++ als_idx = 19 ++}; ++ ++struct amd_mp2_dev { ++ struct pci_dev *pdev; ++ struct amdtp_cl_data *cl_data; ++ void __iomem *mmio; ++ u32 activecontrolstatus; ++}; ++ ++struct amd_mp2_sensor_info { ++ u8 sensor_idx; ++ u32 period; ++ phys_addr_t phys_address; ++}; ++ ++void amd_start_sensor(struct amd_mp2_dev *privdata, struct amd_mp2_sensor_info info); ++void amd_stop_sensor(struct amd_mp2_dev *privdata, u16 sensor_idx); ++void amd_stop_all_sensors(struct amd_mp2_dev *privdata); ++int amd_mp2_get_sensor_num(struct amd_mp2_dev *privdata, u8 *sensor_id); ++int amd_sfh_hid_client_init(struct amd_mp2_dev *privdata); ++int amd_sfh_hid_client_deinit(struct amd_mp2_dev *privdata); ++#endif +diff -Naur linux-5.10.2/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_desc.c linux-5.10.2-amd/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_desc.c +--- linux-5.10.2/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_desc.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-5.10.2-amd/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_desc.c 2020-12-25 14:25:44.299391977 +0100 +@@ -0,0 +1,224 @@ ++// SPDX-License-Identifier: GPL-2.0-or-later ++/* ++ * AMD SFH Report Descriptor generator ++ * Copyright 2020 Advanced Micro Devices, Inc. ++ * Authors: Nehal Bakulchandra Shah <Nehal-Bakulchandra.Shah@amd.com> ++ * Sandeep Singh <sandeep.singh@amd.com> ++ */ ++ ++#include <linux/kernel.h> ++#include <linux/string.h> ++#include <linux/slab.h> ++#include "amd_sfh_pcie.h" ++#include "amd_sfh_hid_desc.h" ++#include "amd_sfh_hid_report_desc.h" ++ ++#define AMD_SFH_FW_MULTIPLIER (1000) ++#define HID_USAGE_SENSOR_PROP_REPORTING_STATE_ALL_EVENTS_ENUM 0x41 ++#define HID_USAGE_SENSOR_PROP_POWER_STATE_D0_FULL_POWER_ENUM 0x51 ++#define HID_DEFAULT_REPORT_INTERVAL 0x50 ++#define HID_DEFAULT_MIN_VALUE 0X7F ++#define HID_DEFAULT_MAX_VALUE 0x80 ++#define HID_DEFAULT_SENSITIVITY 0x7F ++#define HID_USAGE_SENSOR_PROPERTY_CONNECTION_TYPE_PC_INTEGRATED_ENUM 0x01 ++/* state enums */ ++#define HID_USAGE_SENSOR_STATE_READY_ENUM 0x02 ++#define HID_USAGE_SENSOR_STATE_INITIALIZING_ENUM 0x05 ++#define HID_USAGE_SENSOR_EVENT_DATA_UPDATED_ENUM 0x04 ++ ++int get_report_descriptor(int sensor_idx, u8 *rep_desc) ++{ ++ switch (sensor_idx) { ++ case accel_idx: /* accel */ ++ memset(rep_desc, 0, sizeof(accel3_report_descriptor)); ++ memcpy(rep_desc, accel3_report_descriptor, ++ sizeof(accel3_report_descriptor)); ++ break; ++ case gyro_idx: /* gyro */ ++ memset(rep_desc, 0, sizeof(gyro3_report_descriptor)); ++ memcpy(rep_desc, gyro3_report_descriptor, ++ sizeof(gyro3_report_descriptor)); ++ break; ++ case mag_idx: /* Magnetometer */ ++ memset(rep_desc, 0, sizeof(comp3_report_descriptor)); ++ memcpy(rep_desc, comp3_report_descriptor, ++ sizeof(comp3_report_descriptor)); ++ break; ++ case als_idx: /* ambient light sensor */ ++ memset(rep_desc, 0, sizeof(als_report_descriptor)); ++ memcpy(rep_desc, als_report_descriptor, ++ sizeof(als_report_descriptor)); ++ break; ++ default: ++ break; ++ } ++ return 0; ++} ++ ++u32 get_descr_sz(int sensor_idx, int descriptor_name) ++{ ++ switch (sensor_idx) { ++ case accel_idx: ++ switch (descriptor_name) { ++ case descr_size: ++ return sizeof(accel3_report_descriptor); ++ case input_size: ++ return sizeof(struct accel3_input_report); ++ case feature_size: ++ return sizeof(struct accel3_feature_report); ++ } ++ break; ++ case gyro_idx: ++ switch (descriptor_name) { ++ case descr_size: ++ return sizeof(gyro3_report_descriptor); ++ case input_size: ++ return sizeof(struct gyro_input_report); ++ case feature_size: ++ return sizeof(struct gyro_feature_report); ++ } ++ break; ++ case mag_idx: ++ switch (descriptor_name) { ++ case descr_size: ++ return sizeof(comp3_report_descriptor); ++ case input_size: ++ return sizeof(struct magno_input_report); ++ case feature_size: ++ return sizeof(struct magno_feature_report); ++ } ++ break; ++ case als_idx: ++ switch (descriptor_name) { ++ case descr_size: ++ return sizeof(als_report_descriptor); ++ case input_size: ++ return sizeof(struct als_input_report); ++ case feature_size: ++ return sizeof(struct als_feature_report); ++ } ++ break; ++ default: ++ break; ++ } ++ return 0; ++} ++ ++static void get_common_features(struct common_feature_property *common, int report_id) ++{ ++ common->report_id = report_id; ++ common->connection_type = HID_USAGE_SENSOR_PROPERTY_CONNECTION_TYPE_PC_INTEGRATED_ENUM; ++ common->report_state = HID_USAGE_SENSOR_PROP_REPORTING_STATE_ALL_EVENTS_ENUM; ++ common->power_state = HID_USAGE_SENSOR_PROP_POWER_STATE_D0_FULL_POWER_ENUM; ++ common->sensor_state = HID_USAGE_SENSOR_STATE_INITIALIZING_ENUM; ++ common->report_interval = HID_DEFAULT_REPORT_INTERVAL; ++} ++ ++u8 get_feature_report(int sensor_idx, int report_id, u8 *feature_report) ++{ ++ struct accel3_feature_report acc_feature; ++ struct gyro_feature_report gyro_feature; ++ struct magno_feature_report magno_feature; ++ struct als_feature_report als_feature; ++ u8 report_size = 0; ++ ++ if (!feature_report) ++ return report_size; ++ ++ switch (sensor_idx) { ++ case accel_idx: /* accel */ ++ get_common_features(&acc_feature.common_property, report_id); ++ acc_feature.accel_change_sesnitivity = HID_DEFAULT_SENSITIVITY; ++ acc_feature.accel_sensitivity_min = HID_DEFAULT_MIN_VALUE; ++ acc_feature.accel_sensitivity_max = HID_DEFAULT_MAX_VALUE; ++ memcpy(feature_report, &acc_feature, sizeof(acc_feature)); ++ report_size = sizeof(acc_feature); ++ break; ++ case gyro_idx: /* gyro */ ++ get_common_features(&gyro_feature.common_property, report_id); ++ gyro_feature.gyro_change_sesnitivity = HID_DEFAULT_SENSITIVITY; ++ gyro_feature.gyro_sensitivity_min = HID_DEFAULT_MIN_VALUE; ++ gyro_feature.gyro_sensitivity_max = HID_DEFAULT_MAX_VALUE; ++ memcpy(feature_report, &gyro_feature, sizeof(gyro_feature)); ++ report_size = sizeof(gyro_feature); ++ break; ++ case mag_idx: /* Magnetometer */ ++ get_common_features(&magno_feature.common_property, report_id); ++ magno_feature.magno_headingchange_sensitivity = HID_DEFAULT_SENSITIVITY; ++ magno_feature.heading_min = HID_DEFAULT_MIN_VALUE; ++ magno_feature.heading_max = HID_DEFAULT_MAX_VALUE; ++ magno_feature.flux_change_sensitivity = HID_DEFAULT_MIN_VALUE; ++ magno_feature.flux_min = HID_DEFAULT_MIN_VALUE; ++ magno_feature.flux_max = HID_DEFAULT_MAX_VALUE; ++ memcpy(feature_report, &magno_feature, sizeof(magno_feature)); ++ report_size = sizeof(magno_feature); ++ break; ++ case als_idx: /* ambient light sensor */ ++ get_common_features(&als_feature.common_property, report_id); ++ als_feature.als_change_sesnitivity = HID_DEFAULT_SENSITIVITY; ++ als_feature.als_sensitivity_min = HID_DEFAULT_MIN_VALUE; ++ als_feature.als_sensitivity_max = HID_DEFAULT_MAX_VALUE; ++ memcpy(feature_report, &als_feature, sizeof(als_feature)); ++ report_size = sizeof(als_feature); ++ break; ++ default: ++ break; ++ } ++ return report_size; ++} ++ ++static void get_common_inputs(struct common_input_property *common, int report_id) ++{ ++ common->report_id = report_id; ++ common->sensor_state = HID_USAGE_SENSOR_STATE_READY_ENUM; ++ common->event_type = HID_USAGE_SENSOR_EVENT_DATA_UPDATED_ENUM; ++} ++ ++u8 get_input_report(int sensor_idx, int report_id, u8 *input_report, u32 *sensor_virt_addr) ++{ ++ struct accel3_input_report acc_input; ++ struct gyro_input_report gyro_input; ++ struct magno_input_report magno_input; ++ struct als_input_report als_input; ++ u8 report_size = 0; ++ ++ if (!sensor_virt_addr || !input_report) ++ return report_size; ++ ++ switch (sensor_idx) { ++ case accel_idx: /* accel */ ++ get_common_inputs(&acc_input.common_property, report_id); ++ acc_input.in_accel_x_value = (int)sensor_virt_addr[0] / AMD_SFH_FW_MULTIPLIER; ++ acc_input.in_accel_y_value = (int)sensor_virt_addr[1] / AMD_SFH_FW_MULTIPLIER; ++ acc_input.in_accel_z_value = (int)sensor_virt_addr[2] / AMD_SFH_FW_MULTIPLIER; ++ memcpy(input_report, &acc_input, sizeof(acc_input)); ++ report_size = sizeof(acc_input); ++ break; ++ case gyro_idx: /* gyro */ ++ get_common_inputs(&gyro_input.common_property, report_id); ++ gyro_input.in_angel_x_value = (int)sensor_virt_addr[0] / AMD_SFH_FW_MULTIPLIER; ++ gyro_input.in_angel_y_value = (int)sensor_virt_addr[1] / AMD_SFH_FW_MULTIPLIER; ++ gyro_input.in_angel_z_value = (int)sensor_virt_addr[2] / AMD_SFH_FW_MULTIPLIER; ++ memcpy(input_report, &gyro_input, sizeof(gyro_input)); ++ report_size = sizeof(gyro_input); ++ break; ++ case mag_idx: /* Magnetometer */ ++ get_common_inputs(&magno_input.common_property, report_id); ++ magno_input.in_magno_x = (int)sensor_virt_addr[0] / AMD_SFH_FW_MULTIPLIER; ++ magno_input.in_magno_y = (int)sensor_virt_addr[1] / AMD_SFH_FW_MULTIPLIER; ++ magno_input.in_magno_z = (int)sensor_virt_addr[2] / AMD_SFH_FW_MULTIPLIER; ++ magno_input.in_magno_accuracy = (u16)sensor_virt_addr[3] / AMD_SFH_FW_MULTIPLIER; ++ memcpy(input_report, &magno_input, sizeof(magno_input)); ++ report_size = sizeof(magno_input); ++ break; ++ case als_idx: /* Als */ ++ get_common_inputs(&als_input.common_property, report_id); ++ als_input.illuminance_value = (int)sensor_virt_addr[0] / AMD_SFH_FW_MULTIPLIER; ++ report_size = sizeof(als_input); ++ memcpy(input_report, &als_input, sizeof(als_input)); ++ break; ++ default: ++ break; ++ } ++ return report_size; ++} +diff -Naur linux-5.10.2/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_desc.h linux-5.10.2-amd/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_desc.h +--- linux-5.10.2/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_desc.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-5.10.2-amd/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_desc.h 2020-12-25 14:25:44.299391977 +0100 +@@ -0,0 +1,107 @@ ++/* SPDX-License-Identifier: GPL-2.0-or-later */ ++/* ++ * HID report descriptors, structures and routines ++ * Copyright 2020 Advanced Micro Devices, Inc. ++ * Authors: Nehal Bakulchandra Shah <Nehal-bakulchandra.shah@amd.com> ++ * Sandeep Singh <Sandeep.singh@amd.com> ++ */ ++ ++#ifndef AMD_SFH_HID_DESCRIPTOR_H ++#define AMD_SFH_HID_DESCRIPTOR_H ++ ++enum desc_type { ++ /* Report descriptor name */ ++ descr_size = 1, ++ input_size, ++ feature_size, ++}; ++ ++struct common_feature_property { ++ /* common properties */ ++ u8 report_id; ++ u8 connection_type; ++ u8 report_state; ++ u8 power_state; ++ u8 sensor_state; ++ u32 report_interval; ++} __packed; ++ ++struct common_input_property { ++ /* common properties */ ++ u8 report_id; ++ u8 sensor_state; ++ u8 event_type; ++} __packed; ++ ++struct accel3_feature_report { ++ struct common_feature_property common_property; ++ /* properties specific to this sensor */ ++ u16 accel_change_sesnitivity; ++ s16 accel_sensitivity_max; ++ s16 accel_sensitivity_min; ++} __packed; ++ ++struct accel3_input_report { ++ struct common_input_property common_property; ++ /* values specific to this sensor */ ++ int in_accel_x_value; ++ int in_accel_y_value; ++ int in_accel_z_value; ++ /* include if required to support the "shake" event */ ++ u8 in_accel_shake_detection; ++} __packed; ++ ++struct gyro_feature_report { ++ struct common_feature_property common_property; ++ /* properties specific to this sensor */ ++ u16 gyro_change_sesnitivity; ++ s16 gyro_sensitivity_max; ++ s16 gyro_sensitivity_min; ++} __packed; ++ ++struct gyro_input_report { ++ struct common_input_property common_property; ++ /* values specific to this sensor */ ++ int in_angel_x_value; ++ int in_angel_y_value; ++ int in_angel_z_value; ++} __packed; ++ ++struct magno_feature_report { ++ struct common_feature_property common_property; ++ /*properties specific to this sensor */ ++ u16 magno_headingchange_sensitivity; ++ s16 heading_min; ++ s16 heading_max; ++ u16 flux_change_sensitivity; ++ s16 flux_min; ++ s16 flux_max; ++} __packed; ++ ++struct magno_input_report { ++ struct common_input_property common_property; ++ int in_magno_x; ++ int in_magno_y; ++ int in_magno_z; ++ int in_magno_accuracy; ++} __packed; ++ ++struct als_feature_report { ++ struct common_feature_property common_property; ++ /* properties specific to this sensor */ ++ u16 als_change_sesnitivity; ++ s16 als_sensitivity_max; ++ s16 als_sensitivity_min; ++} __packed; ++ ++struct als_input_report { ++ struct common_input_property common_property; ++ /* values specific to this sensor */ ++ int illuminance_value; ++} __packed; ++ ++int get_report_descriptor(int sensor_idx, u8 rep_desc[]); ++u32 get_descr_sz(int sensor_idx, int descriptor_name); ++u8 get_feature_report(int sensor_idx, int report_id, u8 *feature_report); ++u8 get_input_report(int sensor_idx, int report_id, u8 *input_report, u32 *sensor_virt_addr); ++#endif +diff -Naur linux-5.10.2/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_report_desc.h linux-5.10.2-amd/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_report_desc.h +--- linux-5.10.2/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_report_desc.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-5.10.2-amd/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_report_desc.h 2020-12-25 14:25:44.299391977 +0100 +@@ -0,0 +1,645 @@ ++/* SPDX-License-Identifier: GPL-2.0-or-later */ ++/* ++ * HID descriptor stuructures ++ * Copyright 2020 Advanced Micro Devices, Inc. ++ * Authors: Nehal Bakulchandra Shah <Nehal-bakulchandra.shah@amd.com> ++ * Sandeep Singh <Sandeep.singh@amd.com> ++ */ ++ ++#ifndef AMD_SFH_HID_REPORT_DESCRIPTOR_H ++#define AMD_SFH_HID_REPORT_DESCRIPTOR_H ++ ++// Accelerometer 3D Sensor ++static const u8 accel3_report_descriptor[] = { ++0x05, 0x20, /* Usage page */ ++0x09, 0x73, /* Motion type Accel 3D */ ++0xA1, 0x00, /* HID Collection (Physical) */ ++ ++//feature reports(xmit/receive) ++0x85, 1, /* HID Report ID */ ++0x05, 0x20, /* HID usage page sensor */ ++0x0A, 0x09, 0x03, /* Sensor property and sensor connection type */ ++0x15, 0, /* HID logical MIN_8(0) */ ++0x25, 2, /* HID logical MAX_8(2) */ ++0x75, 8, /* HID report size(8) */ ++0x95, 1, /* HID report count(1) */ ++0xA1, 0x02, /* HID collection (logical) */ ++0x0A, 0x30, 0x08, /* Sensor property connection type intergated sel*/ ++0x0A, 0x31, 0x08, /* Sensor property connection type attached sel */ ++0x0A, 0x32, 0x08, /* Sensor property connection type external sel */ ++0xB1, 0x00, /* HID feature (Data_Arr_Abs) */ ++0xC0, /* HID end collection */ ++0x0A, 0x16, 0x03, /* HID usage sensor property reporting state */ ++0x15, 0, /* HID logical Min_8(0) */ ++0x25, 5, /* HID logical Max_8(5) */ ++0x75, 8, /* HID report size(8) */ ++0x95, 1, /* HID report count(1) */ ++0xA1, 0x02, /* HID collection(logical) */ ++0x0A, 0x40, 0x08, /* Sensor property report state no events sel */ ++0x0A, 0x41, 0x08, /* Sensor property report state all events sel */ ++0x0A, 0x42, 0x08, /* Sensor property report state threshold events sel */ ++0x0A, 0x43, 0x08, /* Sensor property report state no events wake sel */ ++0x0A, 0x44, 0x08, /* Sensor property report state all events wake sel */ ++0x0A, 0x45, 0x08, /* Sensor property report state threshold events wake sel */ ++0xB1, 0x00, /* HID feature (Data_Arr_Abs) */ ++0xC0, /* HID end collection */ ++0x0A, 0x19, 0x03, /* HID usage sensor property power state */ ++0x15, 0, /* HID logical Min_8(0) */ ++0x25, 5, /* HID logical Max_8(5) */ ++0x75, 8, /* HID report size(8) */ ++0x95, 1, /* HID report count(1) */ ++0xA1, 0x02, /* HID collection(logical) */ ++0x0A, 0x50, 0x08, /* Sensor property power state undefined sel */ ++0x0A, 0x51, 0x08, /* Sensor property power state D0 full power sel */ ++0x0A, 0x52, 0x08, /* Sensor property power state D1 low power sel */ ++0x0A, 0x53, 0x08, /* Sensor property power state D2 standby with wake sel */ ++0x0A, 0x54, 0x08, /* Sensor property power state D3 sleep with wake sel */ ++0x0A, 0x55, 0x08, /* Sensor property power state D4 power off sel */ ++0xB1, 0x00, /* HID feature (Data_Arr_Abs) */ ++0xC0, /* HID end collection */ ++0x0A, 0x01, 0x02, /* HID usage sensor state */ ++0x15, 0, /* HID logical Min_8(0) */ ++0x25, 6, /* HID logical Max_8(6) */ ++0x75, 8, /* HID report size(8) */ ++0x95, 1, /* HID report count(1) */ ++0xA1, 0x02, /* HID collection(logical) */ ++0x0A, 0x00, 0x08, /* HID usage sensor state unknown sel */ ++0x0A, 0x01, 0x08, /* HID usage sensor state ready sel */ ++0x0A, 0x02, 0x08, /* HID usage sensor state not available sel */ ++0x0A, 0x03, 0x08, /* HID usage sensor state no data sel */ ++0x0A, 0x04, 0x08, /* HID usage sensor state initializing sel */ ++0x0A, 0x05, 0x08, /* HID usage sensor state access denied sel */ ++0x0A, 0x06, 0x08, /* HID usage sensor state error sel */ ++0xB1, 0x00, /* HID feature (Data_Arr_Abs) */ ++0xC0, /* HID end collection */ ++0x0A, 0x0E, 0x03, /* HID usage sensor property report interval */ ++0x15, 0, /* HID logical Min_8(0) */ ++0x27, 0xFF, 0xFF, 0xFF, 0xFF, /* HID logical Max_32 */ ++ ++0x75, 32, /* HID report size(32) */ ++0x95, 1, /* HID report count(1) */ ++0x55, 0, /* HID unit exponent(0) */ ++0xB1, 0x02, /* HID feature (Data_Arr_Abs) */ ++0x0A, 0x52, 0x14, /* Sensor data motion accel and mod change sensitivity ABS) */ ++ ++0x15, 0, /* HID logical Min_8(0) */ ++0x26, 0xFF, 0xFF, /* HID logical Max_16(0xFF,0xFF) */ ++ ++0x75, 16, /* HID report size(16) */ ++0x95, 1, /* HID report count(1) */ ++0x55, 0x0E, /* HID unit exponent(0x0E) */ ++0xB1, 0x02, /* HID feature (Data_Arr_Abs) */ ++0x0A, 0x52, 0x24, /* HID usage sensor data (motion accel and mod max) */ ++ ++0x16, 0x01, 0x80, /* HID logical Min_16(0x01,0x80) */ ++ ++0x26, 0xFF, 0x7F, /* HID logical Max_16(0xFF,0x7F) */ ++ ++0x75, 16, /* HID report size(16) */ ++0x95, 1, /* HID report count(1) */ ++0x55, 0x0E, /* HID unit exponent(0x0E) */ ++0xB1, 0x02, /* HID feature (Data_Arr_Abs) */ ++0x0A, 0x52, 0x34, /* HID usage sensor data (motion accel and mod min) */ ++ ++0x16, 0x01, 0x80, /* HID logical Min_16(0x01,0x80) */ ++ ++0x26, 0xFF, 0x7F, /* HID logical Max_16(0xFF,0x7F) */ ++ ++0x75, 16, /* HID report size(16) */ ++0x95, 1, /* HID report count(1) */ ++0x55, 0x0E, /* HID unit exponent(0x0E) */ ++0xB1, 0x02, /* HID feature (Data_Arr_Abs) */ ++ ++//input report (transmit) ++0x05, 0x20, /* HID usage page sensors */ ++0x0A, 0x01, 0x02, /* HID usage sensor state */ ++0x15, 0, /* HID logical Min_8(0) */ ++0x25, 6, /* HID logical Max_8(6) */ ++0x75, 8, /* HID report size(8) */ ++0x95, 1, /* HID report count (1) */ ++0xA1, 0x02, /* HID end collection (logical) */ ++0x0A, 0x00, 0x08, /* HID usage sensor state unknown sel */ ++0x0A, 0x01, 0x08, /* HID usage sensor state ready sel */ ++0x0A, 0x02, 0x08, /* HID usage sensor state not available sel */ ++0x0A, 0x03, 0x08, /* HID usage sensor state no data sel */ ++0x0A, 0x04, 0x08, /* HID usage sensor state initializing sel */ ++0x0A, 0x05, 0x08, /* HID usage sensor state access denied sel */ ++0x0A, 0x06, 0x08, /* HID usage sensor state error sel */ ++0X81, 0x00, /* HID Input (Data_Arr_Abs) */ ++0xC0, /* HID end collection */ ++0x0A, 0x02, 0x02, /* HID usage sensor event */ ++0x15, 0, /* HID logical Min_8(0) */ ++0x25, 5, /* HID logical Max_8(5) */ ++0x75, 8, /* HID report size(8) */ ++0x95, 1, /* HID report count (1) */ ++0xA1, 0x02, /* HID end collection (logical) */ ++0x0A, 0x10, 0x08, /* HID usage sensor event unknown sel */ ++0x0A, 0x11, 0x08, /* HID usage sensor event state changed sel */ ++0x0A, 0x12, 0x08, /* HID usage sensor event property changed sel */ ++0x0A, 0x13, 0x08, /* HID usage sensor event data updated sel */ ++0x0A, 0x14, 0x08, /* HID usage sensor event poll response sel */ ++0x0A, 0x15, 0x08, /* HID usage sensor event change sensitivity sel */ ++0X81, 0x00, /* HID Input (Data_Arr_Abs) */ ++0xC0, /* HID end collection */ ++0x0A, 0x53, 0x04, /* HID usage sensor data motion Acceleration X axis */ ++0x17, 0x00, 0x00, 0x01, 0x80, /* HID logical Min_32 */ ++ ++0x27, 0xFF, 0xff, 0XFF, 0XFF, /* HID logical Max_32 */ ++ ++0x75, 32, /* HID report size(32) */ ++0x95, 1, /* HID report count (1) */ ++0x55, 0x0E, /* HID unit exponent(0x0E) */ ++0X81, 0x02, /* HID Input (Data_Arr_Abs) */ ++0x0A, 0x54, 0x04, /* HID usage sensor data motion Acceleration Y axis */ ++0x17, 0X00, 0X00, 0x01, 0x80, /* HID logical Min_32 */ ++ ++0x27, 0xFF, 0xFF, 0XFF, 0XFF, /* HID logical Max_32 */ ++ ++0x75, 32, /* HID report size(32) */ ++0x95, 1, /* HID report count (1) */ ++0x55, 0x0E, /* HID unit exponent(0x0E) */ ++0X81, 0x02, /* HID Input (Data_Arr_Abs) */ ++0x0A, 0x55, 0x04, /* HID usage sensor data motion Acceleration Z axis */ ++0x17, 0X00, 0X00, 0x01, 0x80, /* HID logical Min_32 */ ++ ++0x27, 0XFF, 0XFF, 0xFF, 0x7F, /* HID logical Max_32 */ ++ ++0x75, 32, /* HID report size(32) */ ++0x95, 1, /* HID report count (1) */ ++0x55, 0x0E, /* HID unit exponent(0x0E) */ ++0X81, 0x02, /* HID Input (Data_Arr_Abs) */ ++ ++0x0A, 0x51, 0x04, /* HID usage sensor data motion state */ ++0x15, 0, /* HID logical Min_8(0) False = Still*/ ++0x25, 1, /* HID logical Min_8(1) True = In motion */ ++0x75, 8, /* HID report size(8) */ ++0x95, 1, /* HID report count (1) */ ++0X81, 0x02, /* HID Input (Data_Arr_Abs) */ ++0xC0 /* HID end collection */ ++}; ++ ++const u8 gyro3_report_descriptor[] = { ++0x05, 0x20, /* Usage page */ ++0x09, 0x76, /* Motion type Gyro3D */ ++0xA1, 0x00, /* HID Collection (Physical) */ ++ ++0x85, 2, /* HID Report ID */ ++0x05, 0x20, /* HID usage page sensor */ ++0x0A, 0x09, 0x03, /* Sensor property and sensor connection type */ ++0x15, 0, /* HID logical MIN_8(0) */ ++0x25, 2, /* HID logical MAX_8(2) */ ++0x75, 8, /* HID report size(8) */ ++0x95, 1, /* HID report count(1) */ ++0xA1, 0x02, /* HID collection (logical) */ ++0x0A, 0x30, 0x08, /* Sensor property connection type intergated sel */ ++0x0A, 0x31, 0x08, /* Sensor property connection type attached sel */ ++0x0A, 0x32, 0x08, /* Sensor property connection type external sel */ ++0xB1, 0x00, /* HID feature (Data_Arr_Abs) */ ++0xC0, /* HID end collection */ ++0x0A, 0x16, 0x03, /* HID usage sensor property reporting state */ ++0x15, 0, /* HID logical Min_8(0) */ ++0x25, 5, /* HID logical Max_8(5) */ ++0x75, 8, /* HID report size(8) */ ++0x95, 1, /* HID report count(1) */ ++0xA1, 0x02, /* HID collection(logical) */ ++0x0A, 0x40, 0x08, /* Sensor reporting state no events sel */ ++0x0A, 0x41, 0x08, /* Sensor reporting state all events sel */ ++0x0A, 0x42, 0x08, /* Sensor reporting state threshold events sel */ ++0x0A, 0x43, 0x08, /* Sensor reporting state no events wake sel */ ++0x0A, 0x44, 0x08, /* Sensor reporting state all events wake sel */ ++0x0A, 0x45, 0x08, /* Sensor reporting state threshold events wake sel */ ++0xB1, 0x00, /* HID feature (Data_Arr_Abs) */ ++0xC0, /* HID end collection */ ++0x0A, 0x19, 0x03, /* HID usage sensor property power state */ ++0x15, 0, /* HID logical Min_8(0) */ ++0x25, 5, /* HID logical Max_8(5) */ ++0x75, 8, /* HID report size(8) */ ++0x95, 1, /* HID report count(1) */ ++0xA1, 0x02, /* HID collection(logical) */ ++0x0A, 0x50, 0x08, /* Sensor power state undefined sel */ ++0x0A, 0x51, 0x08, /* Sensor power state D0 full power sel */ ++0x0A, 0x52, 0x08, /* Sensor power state D1 low power sel */ ++0x0A, 0x53, 0x08, /* Sensor power state D2 standby with wake sel */ ++0x0A, 0x54, 0x08, /* Sensor power state D3 sleep with wake sel */ ++0x0A, 0x55, 0x08, /* Sensor power state D4 power off sel */ ++0xB1, 0x00, /* HID feature (Data_Arr_Abs) */ ++0xC0, /* HID end collection */ ++0x0A, 0x01, 0x02, /* HID usage sensor state */ ++0x15, 0, /* HID logical Min_8(0) */ ++0x25, 6, /* HID logical Max_8(6) */ ++0x75, 8, /* HID report size(8) */ ++0x95, 1, /* HID report count(1) */ ++0xA1, 0x02, /* HID collection(logical) */ ++0x0A, 0x00, 0x08, /* HID usage sensor state unknown sel */ ++0x0A, 0x01, 0x08, /* HID usage sensor state ready sel */ ++0x0A, 0x02, 0x08, /* HID usage sensor state not available sel */ ++0x0A, 0x03, 0x08, /* HID usage sensor state no data sel */ ++0x0A, 0x04, 0x08, /* HID usage sensor state initializing sel */ ++0x0A, 0x05, 0x08, /* HID usage sensor state access denied sel */ ++0x0A, 0x06, 0x08, /* HID usage sensor state error sel */ ++0xB1, 0x00, /* HID feature (Data_Arr_Abs) */ ++0xC0, /* HID end collection */ ++0x0A, 0x0E, 0x03, /* HID usage sensor property report interval */ ++0x15, 0, /* HID logical Min_8(0) */ ++0x27, 0xFF, 0xFF, 0xFF, 0xFF, /* HID logical Max_32 */ ++ ++0x75, 32, /* HID report size(32) */ ++0x95, 1, /* HID report count(1) */ ++0x55, 0, /* HID unit exponent(0) */ ++0xB1, 0x02, /* HID feature (Data_Arr_Abs) */ ++0x0A, 0x56, 0x14, /* Angular velocity and mod change sensitivity ABS)*/ ++ ++0x15, 0, /* HID logical Min_8(0) */ ++0x26, 0xFF, 0xFF, /* HID logical Max_16(0xFF,0xFF) */ ++ ++0x75, 16, /* HID report size(16) */ ++0x95, 1, /* HID report count(1) */ ++0x55, 0x0E, /* HID unit exponent(0x0E) */ ++0xB1, 0x02, /* HID feature (Data_Arr_Abs) */ ++0x0A, 0x56, 0x24, /* Sensor data (motion angular velocity and mod max) */ ++ ++0x16, 0x01, 0x80, /* HID logical Min_16(0x01,0x80) */ ++ ++0x26, 0xFF, 0x7F, /* HID logical Max_16(0xFF,0x7F) */ ++ ++0x75, 16, /* HID report size(16) */ ++0x95, 1, /* HID report count(1) */ ++0x55, 0x0E, /* HID unit exponent(0x0E) */ ++0xB1, 0x02, /* HID feature (Data_Arr_Abs) */ ++0x0A, 0x56, 0x34, /* HID usage sensor data (motion accel and mod min) */ ++ ++0x16, 0x01, 0x80, /* HID logical Min_16(0x01,0x80) */ ++ ++0x26, 0xFF, 0x7F, /* HID logical Max_16(0xFF,0x7F) */ ++ ++0x75, 16, /* HID report size(16) */ ++0x95, 1, /* HID report count(1) */ ++0x55, 0x0E, /* HID unit exponent(0x0E) */ ++0xB1, 0x02, /* HID feature (Data_Arr_Abs) */ ++ ++//Input reports(transmit) ++0x05, 0x20, /* HID usage page sensors */ ++0x0A, 0x01, 0x02, /* HID usage sensor state */ ++0x15, 0, /* HID logical Min_8(0) */ ++0x25, 6, /* HID logical Max_8(6) */ ++0x75, 8, /* HID report size(8) */ ++0x95, 1, /* HID report count (1) */ ++0xA1, 0x02, /* HID end collection (logical) */ ++0x0A, 0x00, 0x08, /* HID usage sensor state unknown sel */ ++0x0A, 0x01, 0x08, /* HID usage sensor state ready sel */ ++0x0A, 0x02, 0x08, /* HID usage sensor state not available sel */ ++0x0A, 0x03, 0x08, /* HID usage sensor state no data sel */ ++0x0A, 0x04, 0x08, /* HID usage sensor state initializing sel */ ++0x0A, 0x05, 0x08, /* HID usage sensor state access denied sel */ ++0x0A, 0x06, 0x08, /* HID usage sensor state error sel */ ++0X81, 0x00, /* HID Input (Data_Arr_Abs) */ ++0xC0, /* HID end collection */ ++0x0A, 0x02, 0x02, /* HID usage sensor event */ ++0x15, 0, /* HID logical Min_8(0) */ ++0x25, 5, /* HID logical Max_8(5) */ ++0x75, 8, /* HID report size(8) */ ++0x95, 1, /* HID report count (1) */ ++0xA1, 0x02, /* HID end collection (logical) */ ++0x0A, 0x10, 0x08, /* HID usage sensor event unknown sel */ ++0x0A, 0x11, 0x08, /* HID usage sensor event state changed sel */ ++0x0A, 0x12, 0x08, /* HID usage sensor event property changed sel */ ++0x0A, 0x13, 0x08, /* HID usage sensor event data updated sel */ ++0x0A, 0x14, 0x08, /* HID usage sensor event poll response sel */ ++0x0A, 0x15, 0x08, /* HID usage sensor event change sensitivity sel */ ++0X81, 0x00, /* HID Input (Data_Arr_Abs) */ ++0xC0, /* HID end collection */ ++0x0A, 0x57, 0x04, /* Sensor data motion Angular velocity X axis */ ++0x17, 0x00, 0x00, 0x01, 0x80, /* HID logical Min_32 */ ++ ++0x27, 0xFF, 0xFF, 0xFF, 0x7F, /* HID logical Max_32 */ ++ ++0x75, 32, /* HID report size(32) */ ++0x95, 1, /* HID report count (1) */ ++0x55, 0x0E, /* HID unit exponent(0x0E) */ ++0X81, 0x02, /* HID Input (Data_Arr_Abs) */ ++0x0A, 0x58, 0x04, /* Sensor data motion Angular velocity Y axis */ ++0x17, 0x00, 0x00, 0x01, 0x80, /* HID logical Min_32 */ ++ ++0x27, 0xFF, 0xFF, 0xFF, 0x7F, /* HID logical Max_32 */ ++ ++0x75, 32, /* HID report size(32) */ ++0x95, 1, /* HID report count (1) */ ++0x55, 0x0E, /* HID unit exponent(0x0E) */ ++0X81, 0x02, /* HID Input (Data_Arr_Abs) */ ++0x0A, 0x59, 0x04, /* Sensor data motion Angular velocity Z axis */ ++0x17, 0x00, 0x00, 0x01, 0x80, /* HID logical Min_32 */ ++ ++0x27, 0xFF, 0xFF, 0xFF, 0x7F, /* HID logical Max_32 */ ++ ++0x75, 32, /* HID report size(32) */ ++0x95, 1, /* HID report count (1) */ ++0x55, 0x0E, /* HID unit exponent(0x0E) */ ++0X81, 0x02, /* HID Input (Data_Arr_Abs) */ ++ ++0xC0, /* HID end collection */ ++}; ++ ++const u8 comp3_report_descriptor[] = { ++0x05, 0x20, /* Usage page */ ++0x09, 0x83, /* Motion type Orientation compass 3D */ ++0xA1, 0x00, /* HID Collection (Physical) */ ++ ++0x85, 3, /* HID Report ID */ ++0x05, 0x20, /* HID usage page sensor */ ++0x0A, 0x09, 0x03, /* Sensor property and sensor connection type */ ++0x15, 0, /* HID logical MIN_8(0) */ ++0x25, 2, /* HID logical MAX_8(2) */ ++0x75, 8, /* HID report size(8) */ ++0x95, 1, /* HID report count(1) */ ++0xA1, 0x02, /* HID collection (logical) */ ++0x0A, 0x30, 0x08, /* Sensor property connection type intergated sel */ ++0x0A, 0x31, 0x08, /* Sensor property connection type attached sel */ ++0x0A, 0x32, 0x08, /* Sensor property connection type external sel */ ++0xB1, 0x00, /* HID feature (Data_Arr_Abs) */ ++0xC0, /* HID end collection */ ++0x0A, 0x16, 0x03, /* HID usage sensor property reporting state */ ++0x15, 0, /* HID logical Min_8(0) */ ++0x25, 5, /* HID logical Max_8(5) */ ++0x75, 8, /* HID report size(8) */ ++0x95, 1, /* HID report count(1) */ ++0xA1, 0x02, /* HID collection(logical) */ ++0x0A, 0x40, 0x08, /* Sensor reporting state no events sel */ ++0x0A, 0x41, 0x08, /* Sensor reporting state all events sel */ ++0x0A, 0x42, 0x08, /* Sensor reporting state threshold events sel */ ++0x0A, 0x43, 0x08, /* Sensor reporting state no events wake sel */ ++0x0A, 0x44, 0x08, /* Sensor reporting state all events wake sel */ ++0x0A, 0x45, 0x08, /* Sensor reporting state threshold events wake sel */ ++0xB1, 0x00, /* HID feature (Data_Arr_Abs) */ ++0xC0, /* HID end collection */ ++0x0A, 0x19, 0x03, /* HID usage sensor property power state */ ++0x15, 0, /* HID logical Min_8(0) */ ++0x25, 5, /* HID logical Max_8(5) */ ++0x75, 8, /* HID report size(8) */ ++0x95, 1, /* HID report count(1) */ ++0xA1, 0x02, /* HID collection(logical) */ ++0x0A, 0x50, 0x08, /* Sensor power state undefined sel */ ++0x0A, 0x51, 0x08, /* Sensor power state D0 full power sel */ ++0x0A, 0x52, 0x08, /* Sensor power state D1 low power sel */ ++0x0A, 0x53, 0x08, /* Sensor power state D2 standby with wake sel */ ++0x0A, 0x54, 0x08, /* Sensor power state D3 sleep with wake sel */ ++0x0A, 0x55, 0x08, /* Sensor power state D4 power off sel */ ++0xB1, 0x00, /* HID feature (Data_Arr_Abs) */ ++0xC0, /* HID end collection */ ++0x0A, 0x01, 0x02, /* HID usage sensor state */ ++0x15, 0, /* HID logical Min_8(0) */ ++0x25, 6, /* HID logical Max_8(6) */ ++0x75, 8, /* HID report size(8) */ ++0x95, 1, /* HID report count(1) */ ++0xA1, 0x02, /* HID collection(logical) */ ++0x0A, 0x00, 0x08, /* HID usage sensor state unknown sel */ ++0x0A, 0x01, 0x08, /* HID usage sensor state ready sel */ ++0x0A, 0x02, 0x08, /* HID usage sensor state not available sel */ ++0x0A, 0x03, 0x08, /* HID usage sensor state no data sel */ ++0x0A, 0x04, 0x08, /* HID usage sensor state initializing sel */ ++0x0A, 0x05, 0x08, /* HID usage sensor state access denied sel */ ++0x0A, 0x06, 0x08, /* HID usage sensor state error sel */ ++0xB1, 0x00, /* HID feature (Data_Arr_Abs) */ ++0xC0, /* HID end collection */ ++0x0A, 0x0E, 0x03, /* HID usage sensor property report interval */ ++0x15, 0, /* HID logical Min_8(0) */ ++0x27, 0xFF, 0xFF, 0xFF, 0xFF, /* HID logical Max_32 */ ++0x75, 32, /* HID report size(32) */ ++0x95, 1, /* HID report count(1) */ ++0x55, 0, /* HID unit exponent(0) */ ++0xB1, 0x02, /* HID feature (Data_Arr_Abs) */ ++0x0A, 0x71, 0x14, /* Orientation and mod change sensitivity ABS)*/ ++0x15, 0, /* HID logical Min_8(0) */ ++0x26, 0xFF, 0xFF, /* HID logical Max_16(0xFF,0xFF) */ ++0x75, 16, /* HID report size(16) */ ++0x95, 1, /* HID report count(1) */ ++0x55, 0x0E, /* HID unit exponent(0x0E) */ ++0xB1, 0x02, /* HID feature (Data_Arr_Abs) */ ++0x0A, 0x71, 0x24, /* Sensor data (motion orientation and mod max) */ ++0x16, 0x01, 0x80, /* HID logical Min_16(0x01,0x80) */ ++0x26, 0xFF, 0x7F, /* HID logical Max_16(0xFF,0x7F) */ ++0x75, 16, /* HID report size(16) */ ++0x95, 1, /* HID report count(1) */ ++0x55, 0x0F, /* HID unit exponent(0x0F) */ ++0xB1, 0x02, /* HID feature (Data_Arr_Abs) */ ++0x0A, 0x71, 0x34, /* Sensor data (motion orientation and mod min) */ ++0x16, 0x01, 0x80, /* HID logical Min_16(0x01,0x80) */ ++0x26, 0xFF, 0x7F, /* HID logical Max_16(0xFF,0x7F) */ ++0x75, 16, /* HID report size(16) */ ++0x95, 1, /* HID report count(1) */ ++0x55, 0x0F, /* HID unit exponent(0x0F) */ ++0xB1, 0x02, /* HID feature (Data_Arr_Abs) */ ++0x0A, 0x84, 0x14, /* Maganetic flux and change sensitivity ABS) */ ++0x15, 0, /* HID logical Min_8(0) */ ++0x26, 0xFF, 0xFF, /* HID logical Max_16(0xFF,0xFF) */ ++0x75, 16, /* HID report size(16) */ ++0x95, 1, /* HID report count(1) */ ++0x55, 0x0E, /* HID unit exponent(0x0E) */ ++0xB1, 0x02, /* HID feature (Data_Arr_Abs) */ ++0x0A, 0x84, 0x24, /* Maganetic flux and mod change sensitivity Max) */ ++0x16, 0x01, 0x80, /* HID logical Min_16(0x01,0x80) */ ++0x26, 0xFF, 0x7F, /* HID logical Max_16(0xFF,0x7F) */ ++0x75, 16, /* HID report size(16) */ ++0x95, 1, /* HID report count(1) */ ++0x55, 0x0F, /* HID unit exponent(0x0F) */ ++0xB1, 0x02, /* HID feature (Data_Arr_Abs) */ ++0x0A, 0x84, 0x34, /* Maganetic flux and mod change sensitivity Min */ ++0x16, 0x01, 0x80, /* HID logical Min_16(0x01,0x80) */ ++0x26, 0xFF, 0x7F, /* HID logical Max_16(0xFF,0x7F) */ ++0x75, 16, /* HID report size(16) */ ++0x95, 1, /* HID report count(1) */ ++0x55, 0x0F, /* HID unit exponent(0x0F) */ ++0xB1, 0x02, /* HID feature (Data_Arr_Abs) */ ++ ++//Input reports(transmit) ++0x05, 0x20, /* HID usage page sensors */ ++0x0A, 0x01, 0x02, /* HID usage sensor state */ ++0x15, 0, /* HID logical Min_8(0) */ ++0x25, 6, /* HID logical Max_8(6) */ ++0x75, 8, /* HID report size(8) */ ++0x95, 1, /* HID report count (1) */ ++0xA1, 0x02, /* HID end collection (logical) */ ++0x0A, 0x00, 0x08, /* HID usage sensor state unknown sel */ ++0x0A, 0x01, 0x08, /* HID usage sensor state ready sel */ ++0x0A, 0x02, 0x08, /* HID usage sensor state not available sel */ ++0x0A, 0x03, 0x08, /* HID usage sensor state no data sel */ ++0x0A, 0x04, 0x08, /* HID usage sensor state initializing sel */ ++0x0A, 0x05, 0x08, /* HID usage sensor state access denied sel */ ++0x0A, 0x06, 0x08, /* HID usage sensor state error sel */ ++0X81, 0x00, /* HID Input (Data_Arr_Abs) */ ++0xC0, /* HID end collection */ ++0x0A, 0x02, 0x02, /* HID usage sensor event */ ++0x15, 0, /* HID logical Min_8(0) */ ++0x25, 5, /* HID logical Max_8(5) */ ++0x75, 8, /* HID report size(8) */ ++0x95, 1, /* HID report count (1) */ ++0xA1, 0x02, /* HID end collection (logical) */ ++0x0A, 0x10, 0x08, /* HID usage sensor event unknown sel */ ++0x0A, 0x11, 0x08, /* HID usage sensor event state changed sel */ ++0x0A, 0x12, 0x08, /* HID usage sensor event property changed sel */ ++0x0A, 0x13, 0x08, /* HID usage sensor event data updated sel */ ++0x0A, 0x14, 0x08, /* HID usage sensor event poll response sel */ ++0x0A, 0x15, 0x08, /* HID usage sensor event change sensitivity sel */ ++0X81, 0x00, /* HID Input (Data_Arr_Abs) */ ++0xC0, /* HID end collection */ ++0x0A, 0x85, 0x04, /* Sensor data orientation magnetic flux X axis */ ++0x17, 0x00, 0x00, 0x01, 0x80, /* HID logical Min_32 */ ++0x27, 0xFF, 0xFF, 0xFF, 0x7F, /* HID logical Max_32 */ ++0x75, 32, /* HID report size(32) */ ++0x95, 1, /* HID report count (1) */ ++0x55, 0x0D, /* HID unit exponent(0x0D) */ ++0X81, 0x02, /* HID Input (Data_Arr_Abs) */ ++0x0A, 0x86, 0x04, /* Sensor data orientation magnetic flux Y axis */ ++0x17, 0x00, 0x00, 0x01, 0x80, /* HID logical Min_32 */ ++0x27, 0xFF, 0xFF, 0xFF, 0x7F, /* HID logical Max_32 */ ++0x75, 32, /* HID report size(32) */ ++0x95, 1, /* HID report count (1) */ ++0x55, 0x0D, /* HID unit exponent(0x0D) */ ++0X81, 0x02, /* HID Input (Data_Arr_Abs) */ ++0x0A, 0x87, 0x04, /* Sensor data orientation magnetic flux Z axis */ ++0x17, 0x00, 0x00, 0x01, 0x80, /* HID logical Min_32 */ ++0x27, 0xFF, 0xFF, 0xFF, 0x7F, /* HID logical Max_32 */ ++0x75, 32, /* HID report size(32) */ ++0x95, 1, /* HID report count (1) */ ++0x55, 0x0D, /* HID unit exponent(0x0D) */ ++0X81, 0x02, /* HID Input (Data_Arr_Abs) */ ++0x0A, 0x88, 0x04, /* Sensor data orientation magnetometer accuracy */ ++0x17, 0x00, 0x00, 0x01, 0x80, /* HID logical Min_32 */ ++0x27, 0xFF, 0xFF, 0xFF, 0x7F, /* HID logical Max_32 */ ++0x75, 32, /* HID report size(32) */ ++0x95, 1, /* HID report count (1) */ ++0X81, 0x02, /* HID Input (Data_Arr_Abs) */ ++0xC0 /* HID end collection */ ++}; ++ ++const u8 als_report_descriptor[] = { ++0x05, 0x20, /* HID usage page sensor */ ++0x09, 0x41, /* HID usage sensor type Ambientlight */ ++0xA1, 0x00, /* HID Collection (Physical) */ ++ ++//feature reports(xmit/receive)// ++0x85, 4, /* HID Report ID */ ++0x05, 0x20, /* HID usage page sensor */ ++0x0A, 0x09, 0x03, /* Sensor property and sensor connection type */ ++0x15, 0, /* HID logical MIN_8(0) */ ++0x25, 2, /* HID logical MAX_8(2) */ ++0x75, 8, /* HID report size(8) */ ++0x95, 1, /* HID report count(1) */ ++0xA1, 0x02, /* HID collection (logical) */ ++0x0A, 0x30, 0x08, /* Sensor property connection type intergated sel */ ++0x0A, 0x31, 0x08, /* Sensor property connection type attached sel */ ++0x0A, 0x32, 0x08, /* Sensor property connection type external sel */ ++0xB1, 0x00, /* HID feature (Data_Arr_Abs) */ ++0xC0, /* HID end collection */ ++0x0A, 0x16, 0x03, /* HID usage sensor property reporting state */ ++0x15, 0, /* HID logical Min_8(0) */ ++0x25, 5, /* HID logical Max_8(5) */ ++0x75, 8, /* HID report size(8) */ ++0x95, 1, /* HID report count(1) */ ++0xA1, 0x02, /* HID collection(logical) */ ++0x0A, 0x40, 0x08, /* Sensor reporting state no events sel */ ++0x0A, 0x41, 0x08, /* Sensor reporting state all events sel */ ++0x0A, 0x42, 0x08, /* Sensor reporting state threshold events sel */ ++0x0A, 0x43, 0x08, /* Sensor reporting state no events wake sel */ ++0x0A, 0x44, 0x08, /* Sensor reporting state all events wake sel */ ++0x0A, 0x45, 0x08, /* Sensor reporting state threshold events wake sel */ ++0xB1, 0x00, /* HID feature (Data_Arr_Abs) */ ++0xC0, /* HID end collection */ ++0x0A, 0x19, 0x03, /* HID usage sensor property power state */ ++0x15, 0, /* HID logical Min_8(0) */ ++0x25, 5, /* HID logical Max_8(5) */ ++0x75, 8, /* HID report size(8) */ ++0x95, 1, /* HID report count(1) */ ++0xA1, 0x02, /* HID collection(logical) */ ++0x0A, 0x50, 0x08, /* Sensor power state undefined sel */ ++0x0A, 0x51, 0x08, /* Sensor power state D0 full power sel */ ++0x0A, 0x52, 0x08, /* Sensor power state D1 low power sel */ ++0x0A, 0x53, 0x08, /* Sensor power state D2 standby with wake sel */ ++0x0A, 0x54, 0x08, /* Sensor power state D3 sleep with wake sel */ ++0x0A, 0x55, 0x08, /* Sensor power state D4 power off sel */ ++0xB1, 0x00, /* HID feature (Data_Arr_Abs) */ ++0xC0, /* HID end collection */ ++0x0A, 0x01, 0x02, /* HID usage sensor state */ ++0x15, 0, /* HID logical Min_8(0) */ ++0x25, 6, /* HID logical Max_8(6) */ ++0x75, 8, /* HID report size(8) */ ++0x95, 1, /* HID report count(1) */ ++0xA1, 0x02, /* HID collection(logical) */ ++0x0A, 0x00, 0x08, /* HID usage sensor state unknown sel */ ++0x0A, 0x01, 0x08, /* HID usage sensor state ready sel */ ++0x0A, 0x02, 0x08, /* HID usage sensor state not available sel */ ++0x0A, 0x03, 0x08, /* HID usage sensor state no data sel */ ++0x0A, 0x04, 0x08, /* HID usage sensor state initializing sel */ ++0x0A, 0x05, 0x08, /* HID usage sensor state access denied sel */ ++0x0A, 0x06, 0x08, /* HID usage sensor state error sel */ ++0xB1, 0x00, /* HID feature (Data_Arr_Abs) */ ++0xC0, /* HID end collection */ ++0x0A, 0x0E, 0x03, /* HID usage sensor property report interval */ ++0x15, 0, /* HID logical Min_8(0) */ ++0x27, 0xFF, 0xFF, 0xFF, 0xFF, /* HID logical Max_32 */ ++0x75, 32, /* HID report size(32) */ ++0x95, 1, /* HID report count(1) */ ++0x55, 0, /* HID unit exponent(0) */ ++0xB1, 0x02, /* HID feature (Data_Arr_Abs) */ ++0x0A, 0xD1, 0xE4, /* Light illuminance and sensitivity REL PCT) */ ++0x15, 0, /* HID logical Min_8(0) */ ++0x26, 0x10, 0x27, /* HID logical Max_16(0x10,0x27) */ ++0x75, 16, /* HID report size(16) */ ++0x95, 1, /* HID report count(1) */ ++0x55, 0x0E, /* HID unit exponent(0x0E) */ ++0xB1, 0x02, /* HID feature (Data_Arr_Abs) */ ++0x0A, 0xD1, 0x24, /* Sensor data (Light illuminance and mod max) */ ++0x15, 0, /* HID logical Min_8(0) */ ++0x26, 0xFF, 0xFF, /* HID logical Max_16(0xFF,0xFF) */ ++0x75, 16, /* HID report size(16) */ ++0x95, 1, /* HID report count(1) */ ++0x55, 0x0F, /* HID unit exponent(0x0F) */ ++0xB1, 0x02, /* HID feature (Data_Arr_Abs) */ ++0x0A, 0xD1, 0x34, /* Sensor data (Light illuminance and mod min) */ ++0x15, 0, /* HID logical Min_8(0) */ ++0x26, 0xFF, 0xFF, /* HID logical Max_16(0xFF,0xFF) */ ++0x75, 16, /* HID report size(16) */ ++0x95, 1, /* HID report count(1) */ ++0x55, 0x0F, /* HID unit exponent(0x0F) */ ++0xB1, 0x02, /* HID feature (Data_Arr_Abs) */ ++ ++//Input reports (transmit) ++0x05, 0x20, /* HID usage page sensors */ ++0x0A, 0x01, 0x02, /* HID usage sensor state */ ++0x15, 0, /* HID logical Min_8(0) */ ++0x25, 6, /* HID logical Max_8(6) */ ++0x75, 8, /* HID report size(8) */ ++0x95, 1, /* HID report count (1) */ ++0xA1, 0x02, /* HID end collection (logical) */ ++0x0A, 0x00, 0x08, /* HID usage sensor state unknown sel */ ++0x0A, 0x01, 0x08, /* HID usage sensor state ready sel */ ++0x0A, 0x02, 0x08, /* HID usage sensor state not available sel */ ++0x0A, 0x03, 0x08, /* HID usage sensor state no data sel */ ++0x0A, 0x04, 0x08, /* HID usage sensor state initializing sel */ ++0x0A, 0x05, 0x08, /* HID usage sensor state access denied sel */ ++0x0A, 0x06, 0x08, /* HID usage sensor state error sel */ ++0X81, 0x00, /* HID Input (Data_Arr_Abs) */ ++0xC0, /* HID end collection */ ++0x0A, 0x02, 0x02, /* HID usage sensor event */ ++0x15, 0, /* HID logical Min_8(0) */ ++0x25, 5, /* HID logical Max_8(5) */ ++0x75, 8, /* HID report size(8) */ ++0x95, 1, /* HID report count (1) */ ++0xA1, 0x02, /* HID end collection (logical) */ ++0x0A, 0x10, 0x08, /* HID usage sensor event unknown sel */ ++0x0A, 0x11, 0x08, /* HID usage sensor event state changed sel */ ++0x0A, 0x12, 0x08, /* HID usage sensor event property changed sel */ ++0x0A, 0x13, 0x08, /* HID usage sensor event data updated sel */ ++0x0A, 0x14, 0x08, /* HID usage sensor event poll response sel */ ++0x0A, 0x15, 0x08, /* HID usage sensor event change sensitivity sel */ ++0X81, 0x00, /* HID Input (Data_Arr_Abs) */ ++0xC0, /* HID end collection */ ++0x0A, 0xD1, 0x04, /* HID usage sensor data light illuminance */ ++0x17, 0x00, 0x00, 0x01, 0x80, /* HID logical Min_32 */ ++0x27, 0xFF, 0xFF, 0xFF, 0x7F, /* HID logical Max_32 */ ++0x55, 0x0F, /* HID unit exponent(0x0F) */ ++0x75, 32, /* HID report size(32) */ ++0x95, 1, /* HID report count (1) */ ++0X81, 0x02, /* HID Input (Data_Arr_Abs) */ ++0xC0 /* HID end collection */ ++}; ++#endif +diff -Naur linux-5.10.2/drivers/hid/amd-sfh-hid/Kconfig linux-5.10.2-amd/drivers/hid/amd-sfh-hid/Kconfig +--- linux-5.10.2/drivers/hid/amd-sfh-hid/Kconfig 1970-01-01 01:00:00.000000000 +0100 ++++ linux-5.10.2-amd/drivers/hid/amd-sfh-hid/Kconfig 2020-12-25 14:25:44.298391979 +0100 +@@ -0,0 +1,18 @@ ++# SPDX-License-Identifier: GPL-2.0-or-later ++menu "AMD SFH HID Support" ++ depends on X86_64 || COMPILE_TEST ++ depends on PCI ++ depends on HID ++ ++config AMD_SFH_HID ++ tristate "AMD Sensor Fusion Hub" ++ help ++ If you say yes to this option, support will be included for the ++ AMD Sensor Fusion Hub. ++ This driver will enable sensors functionality on AMD platforms ++ starting from 17h family of RYZEN parts. ++ ++ This driver can also be built as a module. If so, the module will ++ be called amd-sfh. ++ Say Y or M here if you want to support AMD SFH. If unsure, say N. ++endmenu +diff -Naur linux-5.10.2/drivers/hid/amd-sfh-hid/Makefile linux-5.10.2-amd/drivers/hid/amd-sfh-hid/Makefile +--- linux-5.10.2/drivers/hid/amd-sfh-hid/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ linux-5.10.2-amd/drivers/hid/amd-sfh-hid/Makefile 2020-12-25 14:25:44.298391979 +0100 +@@ -0,0 +1,13 @@ ++# SPDX-License-Identifier: GPL-2.0-or-later ++# ++# Makefile - AMD SFH HID drivers ++# Copyright (c) 2019-2020, Advanced Micro Devices, Inc. ++# ++# ++obj-$(CONFIG_AMD_SFH_HID) += amd_sfh.o ++amd_sfh-objs := amd_sfh_hid.o ++amd_sfh-objs += amd_sfh_client.o ++amd_sfh-objs += amd_sfh_pcie.o ++amd_sfh-objs += hid_descriptor/amd_sfh_hid_desc.o ++ ++ccflags-y += -I $(srctree)/$(src)/ +diff -Naur linux-5.10.2/drivers/hid/Kconfig linux-5.10.2-amd/drivers/hid/Kconfig +--- linux-5.10.2/drivers/hid/Kconfig 2020-12-21 13:30:08.000000000 +0100 ++++ linux-5.10.2-amd/drivers/hid/Kconfig 2020-12-25 14:27:01.284205047 +0100 +@@ -1183,4 +1183,6 @@ + + source "drivers/hid/intel-ish-hid/Kconfig" + ++source "drivers/hid/amd-sfh-hid/Kconfig" ++ + endmenu +diff -Naur linux-5.10.2/drivers/hid/Makefile linux-5.10.2-amd/drivers/hid/Makefile +--- linux-5.10.2/drivers/hid/Makefile 2020-12-21 13:30:08.000000000 +0100 ++++ linux-5.10.2-amd/drivers/hid/Makefile 2020-12-25 15:14:25.713530171 +0100 +@@ -142,3 +142,4 @@ + + obj-$(CONFIG_INTEL_ISH_HID) += intel-ish-hid/ + obj-$(INTEL_ISH_FIRMWARE_DOWNLOADER) += intel-ish-hid/ ++obj-$(CONFIG_AMD_SFH_HID) += amd-sfh-hid/ |