diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2021-06-30 20:31:32 +0200 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2021-06-30 20:31:32 +0200 |
commit | df04fbe8680bfe07f3d7487eccff9f768bb02533 (patch) | |
tree | 8ab930bbb5cc90152163fb3e19038e4fa4b3f0ab /drivers/hid/amd-sfh-hid | |
parent | Merge tag 'edac_updates_for_v5.14' of git://git.kernel.org/pub/scm/linux/kern... (diff) | |
parent | Merge branch 'for-5.14/multitouch' into for-linus (diff) | |
download | linux-df04fbe8680bfe07f3d7487eccff9f768bb02533.tar.xz linux-df04fbe8680bfe07f3d7487eccff9f768bb02533.zip |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid
Pull HID updates from Jiri Kosina:
- patch series that ensures that hid-multitouch driver disables touch
and button-press reporting on hid-mt devices during suspend when the
device is not configured as a wakeup-source, from Hans de Goede
- support for ISH DMA on Intel EHL platform, from Even Xu
- support for Renoir and Cezanne SoCs, Ambient Light Sensor and Human
Presence Detection sensor for amd-sfh driver, from Basavaraj Natikar
- other assorted code cleanups and device-specific fixes/quirks
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid: (45 commits)
HID: thrustmaster: Switch to kmemdup() when allocate change_request
HID: multitouch: Disable event reporting on suspend when the device is not a wakeup-source
HID: logitech-dj: Implement may_wakeup ll-driver callback
HID: usbhid: Implement may_wakeup ll-driver callback
HID: core: Add hid_hw_may_wakeup() function
HID: input: Add support for Programmable Buttons
HID: wacom: Correct base usage for capacitive ExpressKey status bits
HID: amd_sfh: Add initial support for HPD sensor
HID: amd_sfh: Extend ALS support for newer AMD platform
HID: amd_sfh: Extend driver capabilities for multi-generation support
HID: surface-hid: Fix get-report request
HID: sony: fix freeze when inserting ghlive ps3/wii dongles
HID: usbkbd: Avoid GFP_ATOMIC when GFP_KERNEL is possible
HID: amd_sfh: change in maintainer
HID: intel-ish-hid: ipc: Specify that EHL no cache snooping
HID: intel-ish-hid: ishtp: Add dma_no_cache_snooping() callback
HID: intel-ish-hid: Set ISH driver depends on x86
HID: hid-input: add Surface Go battery quirk
HID: intel-ish-hid: Fix minor typos in comments
HID: usbmouse: Avoid GFP_ATOMIC when GFP_KERNEL is possible
...
Diffstat (limited to 'drivers/hid/amd-sfh-hid')
-rw-r--r-- | drivers/hid/amd-sfh-hid/amd_sfh_client.c | 43 | ||||
-rw-r--r-- | drivers/hid/amd-sfh-hid/amd_sfh_hid.h | 12 | ||||
-rw-r--r-- | drivers/hid/amd-sfh-hid/amd_sfh_pcie.c | 89 | ||||
-rw-r--r-- | drivers/hid/amd-sfh-hid/amd_sfh_pcie.h | 43 | ||||
-rw-r--r-- | drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_desc.c | 48 | ||||
-rw-r--r-- | drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_desc.h | 11 | ||||
-rw-r--r-- | drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_report_desc.h | 112 |
7 files changed, 324 insertions, 34 deletions
diff --git a/drivers/hid/amd-sfh-hid/amd_sfh_client.c b/drivers/hid/amd-sfh-hid/amd_sfh_client.c index 3589d9945da1..efb849411d25 100644 --- a/drivers/hid/amd-sfh-hid/amd_sfh_client.c +++ b/drivers/hid/amd-sfh-hid/amd_sfh_client.c @@ -77,6 +77,7 @@ int amd_sfh_get_report(struct hid_device *hid, int report_id, int report_type) 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 amd_input_data *in_data = cli_data->in_data; struct request_list *req_node; u8 current_index, sensor_index; u8 report_id, node_type; @@ -101,13 +102,11 @@ static void amd_sfh_work(struct work_struct *work) 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]); + report_size = get_input_report(current_index, sensor_index, report_id, in_data); 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); + in_data->input_report[current_index], report_size, 0); else pr_err("AMDSFH: Invalid report size\n"); } @@ -119,21 +118,22 @@ static void amd_sfh_work(struct work_struct *work) 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); + struct amd_input_data *in_data = cli_data->in_data; 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]); + report_size = get_input_report(i, cli_data->sensor_idx[i], cli_data->report_id[i], + in_data); hid_input_report(cli_data->hid_sensor_hubs[i], HID_INPUT_REPORT, - cli_data->input_report[i], report_size, 0); + in_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 amd_input_data *in_data = &privdata->in_data; struct amdtp_cl_data *cl_data = privdata->cl_data; struct amd_mp2_sensor_info info; struct device *dev; @@ -143,18 +143,16 @@ int amd_sfh_hid_client_init(struct amd_mp2_dev *privdata) int rc, i; dev = &privdata->pdev->dev; - cl_data = devm_kzalloc(dev, 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); + cl_data->in_data = in_data; for (i = 0; i < cl_data->num_hid_devices; i++) { - cl_data->sensor_virt_addr[i] = dma_alloc_coherent(dev, sizeof(int) * 8, + in_data->sensor_virt_addr[i] = dma_alloc_coherent(dev, sizeof(int) * 8, &cl_data->sensor_dma_addr[i], GFP_KERNEL); cl_data->sensor_sts[i] = 0; @@ -181,8 +179,8 @@ int amd_sfh_hid_client_init(struct amd_mp2_dev *privdata) rc = -ENOMEM; goto cleanup; } - cl_data->input_report[i] = devm_kzalloc(dev, input_report_size, GFP_KERNEL); - if (!cl_data->input_report[i]) { + in_data->input_report[i] = devm_kzalloc(dev, input_report_size, GFP_KERNEL); + if (!in_data->input_report[i]) { rc = -ENOMEM; goto cleanup; } @@ -202,44 +200,43 @@ int amd_sfh_hid_client_init(struct amd_mp2_dev *privdata) rc = amdtp_hid_probe(cl_data->cur_hid_dev, cl_data); if (rc) return rc; - amd_start_sensor(privdata, info); + privdata->mp2_ops->start(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]) { + if (in_data->sensor_virt_addr[i]) { dma_free_coherent(&privdata->pdev->dev, 8 * sizeof(int), - cl_data->sensor_virt_addr[i], + in_data->sensor_virt_addr[i], cl_data->sensor_dma_addr[i]); } devm_kfree(dev, cl_data->feature_report[i]); - devm_kfree(dev, cl_data->input_report[i]); + devm_kfree(dev, in_data->input_report[i]); devm_kfree(dev, cl_data->report_descr[i]); } - devm_kfree(dev, cl_data); return rc; } int amd_sfh_hid_client_deinit(struct amd_mp2_dev *privdata) { struct amdtp_cl_data *cl_data = privdata->cl_data; + struct amd_input_data *in_data = cl_data->in_data; int i; for (i = 0; i < cl_data->num_hid_devices; i++) - amd_stop_sensor(privdata, i); + privdata->mp2_ops->stop(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]) { + if (in_data->sensor_virt_addr[i]) { dma_free_coherent(&privdata->pdev->dev, 8 * sizeof(int), - cl_data->sensor_virt_addr[i], + in_data->sensor_virt_addr[i], cl_data->sensor_dma_addr[i]); } } diff --git a/drivers/hid/amd-sfh-hid/amd_sfh_hid.h b/drivers/hid/amd-sfh-hid/amd_sfh_hid.h index d7eac1728e31..ae2ac9191ba7 100644 --- a/drivers/hid/amd-sfh-hid/amd_sfh_hid.h +++ b/drivers/hid/amd-sfh-hid/amd_sfh_hid.h @@ -9,11 +9,16 @@ #ifndef AMDSFH_HID_H #define AMDSFH_HID_H -#define MAX_HID_DEVICES 4 +#define MAX_HID_DEVICES 5 #define BUS_AMD_AMDTP 0x20 #define AMD_SFH_HID_VENDOR 0x1022 #define AMD_SFH_HID_PRODUCT 0x0001 +struct amd_input_data { + u32 *sensor_virt_addr[MAX_HID_DEVICES]; + u8 *input_report[MAX_HID_DEVICES]; +}; + struct amdtp_cl_data { u8 init_done; u32 cur_hid_dev; @@ -26,7 +31,6 @@ struct amdtp_cl_data { 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]; dma_addr_t sensor_dma_addr[MAX_HID_DEVICES]; u32 sensor_sts[MAX_HID_DEVICES]; u32 sensor_requested_cnt[MAX_HID_DEVICES]; @@ -34,8 +38,8 @@ struct amdtp_cl_data { 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 amd_input_data *in_data; struct delayed_work work; struct delayed_work work_buffer; }; @@ -64,4 +68,6 @@ 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); +u8 get_input_report(u8 current_index, int sensor_idx, int report_id, + struct amd_input_data *in_data); #endif diff --git a/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c b/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c index ddecc84fd6f0..96e2577fa37e 100644 --- a/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c +++ b/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c @@ -24,12 +24,55 @@ #define ACEL_EN BIT(0) #define GYRO_EN BIT(1) #define MAGNO_EN BIT(2) +#define HPD_EN BIT(16) #define ALS_EN BIT(19) static int sensor_mask_override = -1; module_param_named(sensor_mask, sensor_mask_override, int, 0444); MODULE_PARM_DESC(sensor_mask, "override the detected sensors mask"); +static void amd_start_sensor_v2(struct amd_mp2_dev *privdata, struct amd_mp2_sensor_info info) +{ + union sfh_cmd_base cmd_base; + + cmd_base.ul = 0; + cmd_base.cmd_v2.cmd_id = ENABLE_SENSOR; + cmd_base.cmd_v2.period = info.period; + cmd_base.cmd_v2.sensor_id = info.sensor_idx; + cmd_base.cmd_v2.length = 16; + + if (info.sensor_idx == als_idx) + cmd_base.cmd_v2.mem_type = USE_C2P_REG; + + writeq(info.dma_address, privdata->mmio + AMD_C2P_MSG1); + writel(cmd_base.ul, privdata->mmio + AMD_C2P_MSG0); +} + +static void amd_stop_sensor_v2(struct amd_mp2_dev *privdata, u16 sensor_idx) +{ + union sfh_cmd_base cmd_base; + + cmd_base.ul = 0; + cmd_base.cmd_v2.cmd_id = DISABLE_SENSOR; + cmd_base.cmd_v2.period = 0; + cmd_base.cmd_v2.sensor_id = sensor_idx; + cmd_base.cmd_v2.length = 16; + + writeq(0x0, privdata->mmio + AMD_C2P_MSG2); + writel(cmd_base.ul, privdata->mmio + AMD_C2P_MSG0); +} + +static void amd_stop_all_sensor_v2(struct amd_mp2_dev *privdata) +{ + union sfh_cmd_base cmd_base; + + cmd_base.cmd_v2.cmd_id = STOP_ALL_SENSORS; + cmd_base.cmd_v2.period = 0; + cmd_base.cmd_v2.sensor_id = 0; + + writel(cmd_base.ul, privdata->mmio + AMD_C2P_MSG0); +} + void amd_start_sensor(struct amd_mp2_dev *privdata, struct amd_mp2_sensor_info info) { union sfh_cmd_param cmd_param; @@ -98,7 +141,6 @@ int amd_mp2_get_sensor_num(struct amd_mp2_dev *privdata, u8 *sensor_id) { int activestatus, num_of_sensors = 0; const struct dmi_system_id *dmi_id; - u32 activecontrolstatus; if (sensor_mask_override == -1) { dmi_id = dmi_first_match(dmi_sensor_mask_overrides); @@ -109,8 +151,7 @@ int amd_mp2_get_sensor_num(struct amd_mp2_dev *privdata, u8 *sensor_id) if (sensor_mask_override >= 0) { activestatus = sensor_mask_override; } else { - activecontrolstatus = readl(privdata->mmio + AMD_P2C_MSG3); - activestatus = activecontrolstatus >> 4; + activestatus = privdata->mp2_acs >> 4; } if (ACEL_EN & activestatus) @@ -125,13 +166,46 @@ int amd_mp2_get_sensor_num(struct amd_mp2_dev *privdata, u8 *sensor_id) if (ALS_EN & activestatus) sensor_id[num_of_sensors++] = als_idx; + if (HPD_EN & activestatus) + sensor_id[num_of_sensors++] = HPD_IDX; + return num_of_sensors; } static void amd_mp2_pci_remove(void *privdata) { + struct amd_mp2_dev *mp2 = privdata; amd_sfh_hid_client_deinit(privdata); - amd_stop_all_sensors(privdata); + mp2->mp2_ops->stop_all(mp2); +} + +static const struct amd_mp2_ops amd_sfh_ops_v2 = { + .start = amd_start_sensor_v2, + .stop = amd_stop_sensor_v2, + .stop_all = amd_stop_all_sensor_v2, +}; + +static const struct amd_mp2_ops amd_sfh_ops = { + .start = amd_start_sensor, + .stop = amd_stop_sensor, + .stop_all = amd_stop_all_sensors, +}; + +static void mp2_select_ops(struct amd_mp2_dev *privdata) +{ + u8 acs; + + privdata->mp2_acs = readl(privdata->mmio + AMD_P2C_MSG3); + acs = privdata->mp2_acs & GENMASK(3, 0); + + switch (acs) { + case V2_STATUS: + privdata->mp2_ops = &amd_sfh_ops_v2; + break; + default: + privdata->mp2_ops = &amd_sfh_ops; + break; + } } static int amd_mp2_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) @@ -160,10 +234,17 @@ static int amd_mp2_pci_probe(struct pci_dev *pdev, const struct pci_device_id *i rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); return rc; } + + privdata->cl_data = devm_kzalloc(&pdev->dev, sizeof(struct amdtp_cl_data), GFP_KERNEL); + if (!privdata->cl_data) + return -ENOMEM; + rc = devm_add_action_or_reset(&pdev->dev, amd_mp2_pci_remove, privdata); if (rc) return rc; + mp2_select_ops(privdata); + return amd_sfh_hid_client_init(privdata); } diff --git a/drivers/hid/amd-sfh-hid/amd_sfh_pcie.h b/drivers/hid/amd-sfh-hid/amd_sfh_pcie.h index 489415f7c22c..2d5c57e3782d 100644 --- a/drivers/hid/amd-sfh-hid/amd_sfh_pcie.h +++ b/drivers/hid/amd-sfh-hid/amd_sfh_pcie.h @@ -10,6 +10,7 @@ #define PCIE_MP2_AMD_H #include <linux/pci.h> +#include "amd_sfh_hid.h" #define PCI_DEVICE_ID_AMD_MP2 0x15E4 @@ -22,9 +23,15 @@ #define AMD_C2P_MSG1 0x10504 #define AMD_C2P_MSG2 0x10508 +#define AMD_C2P_MSG(regno) (0x10500 + ((regno) * 4)) + /* MP2 P2C Message Registers */ #define AMD_P2C_MSG3 0x1068C /* Supported Sensors info */ +#define V2_STATUS 0x2 + +#define HPD_IDX 16 + /* SFH Command register */ union sfh_cmd_base { u32 ul; @@ -33,6 +40,15 @@ union sfh_cmd_base { u32 sensor_id : 8; u32 period : 16; } s; + struct { + u32 cmd_id : 4; + u32 intr_enable : 1; + u32 rsvd1 : 3; + u32 length : 7; + u32 mem_type : 1; + u32 sensor_id : 8; + u32 period : 8; + } cmd_v2; }; union sfh_cmd_param { @@ -61,6 +77,10 @@ struct amd_mp2_dev { struct pci_dev *pdev; struct amdtp_cl_data *cl_data; void __iomem *mmio; + const struct amd_mp2_ops *mp2_ops; + struct amd_input_data in_data; + /* mp2 active control status */ + u32 mp2_acs; }; struct amd_mp2_sensor_info { @@ -69,10 +89,33 @@ struct amd_mp2_sensor_info { dma_addr_t dma_address; }; +enum mem_use_type { + USE_DRAM, + USE_C2P_REG, +}; + +struct hpd_status { + union { + struct { + u32 human_presence_report : 4; + u32 human_presence_actual : 4; + u32 probablity : 8; + u32 object_distance : 16; + } shpd; + u32 val; + }; +}; + 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); + +struct amd_mp2_ops { + void (*start)(struct amd_mp2_dev *privdata, struct amd_mp2_sensor_info info); + void (*stop)(struct amd_mp2_dev *privdata, u16 sensor_idx); + void (*stop_all)(struct amd_mp2_dev *privdata); +}; #endif diff --git a/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_desc.c b/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_desc.c index 6e3ad66e57a4..0c3697219382 100644 --- a/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_desc.c +++ b/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_desc.c @@ -12,6 +12,7 @@ #include "amd_sfh_pcie.h" #include "amd_sfh_hid_desc.h" #include "amd_sfh_hid_report_desc.h" +#include "amd_sfh_hid.h" #define AMD_SFH_FW_MULTIPLIER (1000) #define HID_USAGE_SENSOR_PROP_REPORTING_STATE_ALL_EVENTS_ENUM 0x41 @@ -49,6 +50,11 @@ int get_report_descriptor(int sensor_idx, u8 *rep_desc) memcpy(rep_desc, als_report_descriptor, sizeof(als_report_descriptor)); break; + case HPD_IDX: /* HPD sensor */ + memset(rep_desc, 0, sizeof(hpd_report_descriptor)); + memcpy(rep_desc, hpd_report_descriptor, + sizeof(hpd_report_descriptor)); + break; default: break; } @@ -98,6 +104,17 @@ u32 get_descr_sz(int sensor_idx, int descriptor_name) return sizeof(struct als_feature_report); } break; + case HPD_IDX: + switch (descriptor_name) { + case descr_size: + return sizeof(hpd_report_descriptor); + case input_size: + return sizeof(struct hpd_input_report); + case feature_size: + return sizeof(struct hpd_feature_report); + } + break; + default: break; } @@ -119,6 +136,7 @@ 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 hpd_feature_report hpd_feature; struct als_feature_report als_feature; u8 report_size = 0; @@ -161,6 +179,12 @@ u8 get_feature_report(int sensor_idx, int report_id, u8 *feature_report) memcpy(feature_report, &als_feature, sizeof(als_feature)); report_size = sizeof(als_feature); break; + case HPD_IDX: /* human presence detection sensor */ + get_common_features(&hpd_feature.common_property, report_id); + memcpy(feature_report, &hpd_feature, sizeof(hpd_feature)); + report_size = sizeof(hpd_feature); + break; + default: break; } @@ -174,12 +198,18 @@ static void get_common_inputs(struct common_input_property *common, int report_i 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) +u8 get_input_report(u8 current_index, int sensor_idx, int report_id, struct amd_input_data *in_data) { + struct amd_mp2_dev *privdata = container_of(in_data, struct amd_mp2_dev, in_data); + u32 *sensor_virt_addr = in_data->sensor_virt_addr[current_index]; + u8 *input_report = in_data->input_report[current_index]; + u8 supported_input = privdata->mp2_acs & GENMASK(3, 0); + struct magno_input_report magno_input; struct accel3_input_report acc_input; struct gyro_input_report gyro_input; - struct magno_input_report magno_input; + struct hpd_input_report hpd_input; struct als_input_report als_input; + struct hpd_status hpdstatus; u8 report_size = 0; if (!sensor_virt_addr || !input_report) @@ -213,10 +243,22 @@ u8 get_input_report(int sensor_idx, int report_id, u8 *input_report, u32 *sensor 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; + /* For ALS ,V2 Platforms uses C2P_MSG5 register instead of DRAM access method */ + if (supported_input == V2_STATUS) + als_input.illuminance_value = (int)readl(privdata->mmio + AMD_C2P_MSG(5)); + else + 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; + case HPD_IDX: /* hpd */ + get_common_inputs(&hpd_input.common_property, report_id); + hpdstatus.val = readl(privdata->mmio + AMD_C2P_MSG(4)); + hpd_input.human_presence = hpdstatus.shpd.human_presence_actual; + report_size = sizeof(hpd_input); + memcpy(input_report, &hpd_input, sizeof(hpd_input)); + break; default: break; } diff --git a/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_desc.h b/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_desc.h index 095c471d8fd6..16f563d1823b 100644 --- a/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_desc.h +++ b/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_desc.h @@ -100,8 +100,17 @@ struct als_input_report { int illuminance_value; } __packed; +struct hpd_feature_report { + struct common_feature_property common_property; +} __packed; + +struct hpd_input_report { + struct common_input_property common_property; + /* values specific to human presence sensor */ + u8 human_presence; +} __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 --git a/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_report_desc.h b/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_report_desc.h index 44271d39b322..66d6b26e4708 100644 --- a/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_report_desc.h +++ b/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_report_desc.h @@ -642,4 +642,116 @@ const u8 als_report_descriptor[] = { 0X81, 0x02, /* HID Input (Data_Arr_Abs) */ 0xC0 /* HID end collection */ }; + +/* BIOMETRIC PRESENCE*/ +static const u8 hpd_report_descriptor[] = { +0x05, 0x20, /* Usage page */ +0x09, 0x11, /* BIOMETRIC PRESENCE */ +0xA1, 0x00, /* HID Collection (Physical) */ + +//feature reports(xmit/receive) +0x85, 5, /* 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_Var_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, 0xB1, 0x04, /* HID usage sensor data BIOMETRIC HUMAN PRESENCE */ +0x15, 0, /* HID logical Min_8(0) */ +0x25, 1, /* HID logical Max_8(1) */ +0x75, 8, /* HID report size(8) */ +0x95, 1, /* HID report count (1) */ +0X81, 0x02, /* HID Input (Data_Var_Abs) */ +0xC0 /* HID end collection */ +}; #endif |