From 464956f75e9e26bcbbcbef435213e8f5fa854d07 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Sat, 6 Feb 2021 16:13:46 +0100 Subject: HID: intel-ish-hid: Drop if block with an always false condition MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A remove callback is only ever called for a bound device. So there is no need to check for device or driver being NULL. Signed-off-by: Uwe Kleine-König Acked-by: Srinivas Pandruvada Signed-off-by: Jiri Kosina --- drivers/hid/intel-ish-hid/ishtp/bus.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'drivers/hid') diff --git a/drivers/hid/intel-ish-hid/ishtp/bus.c b/drivers/hid/intel-ish-hid/ishtp/bus.c index bba29cd36d29..ccd54f244503 100644 --- a/drivers/hid/intel-ish-hid/ishtp/bus.c +++ b/drivers/hid/intel-ish-hid/ishtp/bus.c @@ -257,17 +257,13 @@ static int ishtp_cl_bus_match(struct device *dev, struct device_driver *drv) static int ishtp_cl_device_remove(struct device *dev) { struct ishtp_cl_device *device = to_ishtp_cl_device(dev); - struct ishtp_cl_driver *driver; - - if (!device || !dev->driver) - return 0; + struct ishtp_cl_driver *driver = to_ishtp_cl_driver(dev->driver); if (device->event_cb) { device->event_cb = NULL; cancel_work_sync(&device->event_work); } - driver = to_ishtp_cl_driver(dev->driver); if (!driver->remove) { dev->driver = NULL; -- cgit v1.2.3 From 7c746603b5c58939ec823cff5dca3894cc3afb3b Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Sat, 6 Feb 2021 16:13:47 +0100 Subject: HID: intel-ish-hid: Simplify logic in ishtp_cl_device_remove() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There is only a single change in behavior: Now dev->driver isn't modified. Assigning to this variable is in the domain of the driver core only. (And it's done in __device_release_driver shortly after bus->remove() (i.e ishtp_cl_device_remove() here) returns.) Signed-off-by: Uwe Kleine-König Acked-by: Srinivas Pandruvada Signed-off-by: Jiri Kosina --- drivers/hid/intel-ish-hid/ishtp/bus.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'drivers/hid') diff --git a/drivers/hid/intel-ish-hid/ishtp/bus.c b/drivers/hid/intel-ish-hid/ishtp/bus.c index ccd54f244503..7f36ce6187a1 100644 --- a/drivers/hid/intel-ish-hid/ishtp/bus.c +++ b/drivers/hid/intel-ish-hid/ishtp/bus.c @@ -258,19 +258,17 @@ static int ishtp_cl_device_remove(struct device *dev) { struct ishtp_cl_device *device = to_ishtp_cl_device(dev); struct ishtp_cl_driver *driver = to_ishtp_cl_driver(dev->driver); + int ret = 0; if (device->event_cb) { device->event_cb = NULL; cancel_work_sync(&device->event_work); } - if (!driver->remove) { - dev->driver = NULL; + if (driver->remove) + ret = driver->remove(device); - return 0; - } - - return driver->remove(device); + return ret; } /** -- cgit v1.2.3 From e71da1fd0e84bc5c87a78b405e40713840eecc80 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Sat, 6 Feb 2021 16:13:48 +0100 Subject: HID: intel-ish-hid: Make remove callback return void MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The driver core ignores the return value of struct bus_type::remove() because there is only little that can be done. To simplify the quest to make this function return void, let struct ishtp_cl_driver::remove() return void, too. All users already unconditionally return 0, this commit makes it obvious that returning an error value is a bad idea. Signed-off-by: Uwe Kleine-König Acked-by: Srinivas Pandruvada Signed-off-by: Jiri Kosina --- drivers/hid/intel-ish-hid/ishtp-fw-loader.c | 4 +--- drivers/hid/intel-ish-hid/ishtp-hid-client.c | 4 +--- drivers/hid/intel-ish-hid/ishtp/bus.c | 5 ++--- drivers/platform/chrome/cros_ec_ishtp.c | 4 +--- include/linux/intel-ish-client-if.h | 2 +- 5 files changed, 6 insertions(+), 13 deletions(-) (limited to 'drivers/hid') diff --git a/drivers/hid/intel-ish-hid/ishtp-fw-loader.c b/drivers/hid/intel-ish-hid/ishtp-fw-loader.c index 6cf59fd26ad7..edb0bd084c27 100644 --- a/drivers/hid/intel-ish-hid/ishtp-fw-loader.c +++ b/drivers/hid/intel-ish-hid/ishtp-fw-loader.c @@ -1015,7 +1015,7 @@ static int loader_ishtp_cl_probe(struct ishtp_cl_device *cl_device) * * Return: 0 */ -static int loader_ishtp_cl_remove(struct ishtp_cl_device *cl_device) +static void loader_ishtp_cl_remove(struct ishtp_cl_device *cl_device) { struct ishtp_cl_data *client_data; struct ishtp_cl *loader_ishtp_cl = ishtp_get_drvdata(cl_device); @@ -1032,8 +1032,6 @@ static int loader_ishtp_cl_remove(struct ishtp_cl_device *cl_device) cancel_work_sync(&client_data->work_ishtp_reset); loader_deinit(loader_ishtp_cl); ishtp_put_device(cl_device); - - return 0; } /** diff --git a/drivers/hid/intel-ish-hid/ishtp-hid-client.c b/drivers/hid/intel-ish-hid/ishtp-hid-client.c index 6ba944b40fdb..0f1b5283bab4 100644 --- a/drivers/hid/intel-ish-hid/ishtp-hid-client.c +++ b/drivers/hid/intel-ish-hid/ishtp-hid-client.c @@ -838,7 +838,7 @@ static int hid_ishtp_cl_probe(struct ishtp_cl_device *cl_device) * * Return: 0 */ -static int hid_ishtp_cl_remove(struct ishtp_cl_device *cl_device) +static void hid_ishtp_cl_remove(struct ishtp_cl_device *cl_device) { struct ishtp_cl *hid_ishtp_cl = ishtp_get_drvdata(cl_device); struct ishtp_cl_data *client_data = ishtp_get_client_data(hid_ishtp_cl); @@ -856,8 +856,6 @@ static int hid_ishtp_cl_remove(struct ishtp_cl_device *cl_device) hid_ishtp_cl = NULL; client_data->num_hid_devices = 0; - - return 0; } /** diff --git a/drivers/hid/intel-ish-hid/ishtp/bus.c b/drivers/hid/intel-ish-hid/ishtp/bus.c index 7f36ce6187a1..ffc9ce5c86ee 100644 --- a/drivers/hid/intel-ish-hid/ishtp/bus.c +++ b/drivers/hid/intel-ish-hid/ishtp/bus.c @@ -258,7 +258,6 @@ static int ishtp_cl_device_remove(struct device *dev) { struct ishtp_cl_device *device = to_ishtp_cl_device(dev); struct ishtp_cl_driver *driver = to_ishtp_cl_driver(dev->driver); - int ret = 0; if (device->event_cb) { device->event_cb = NULL; @@ -266,9 +265,9 @@ static int ishtp_cl_device_remove(struct device *dev) } if (driver->remove) - ret = driver->remove(device); + driver->remove(device); - return ret; + return 0; } /** diff --git a/drivers/platform/chrome/cros_ec_ishtp.c b/drivers/platform/chrome/cros_ec_ishtp.c index f00107017318..9d1e7e03628e 100644 --- a/drivers/platform/chrome/cros_ec_ishtp.c +++ b/drivers/platform/chrome/cros_ec_ishtp.c @@ -703,7 +703,7 @@ end_ishtp_cl_alloc_error: * * Return: 0 */ -static int cros_ec_ishtp_remove(struct ishtp_cl_device *cl_device) +static void cros_ec_ishtp_remove(struct ishtp_cl_device *cl_device) { struct ishtp_cl *cros_ish_cl = ishtp_get_drvdata(cl_device); struct ishtp_cl_data *client_data = ishtp_get_client_data(cros_ish_cl); @@ -712,8 +712,6 @@ static int cros_ec_ishtp_remove(struct ishtp_cl_device *cl_device) cancel_work_sync(&client_data->work_ec_evt); cros_ish_deinit(cros_ish_cl); ishtp_put_device(cl_device); - - return 0; } /** diff --git a/include/linux/intel-ish-client-if.h b/include/linux/intel-ish-client-if.h index 0d6b4bc191c5..94669e21dc8b 100644 --- a/include/linux/intel-ish-client-if.h +++ b/include/linux/intel-ish-client-if.h @@ -36,7 +36,7 @@ struct ishtp_cl_driver { const char *name; const guid_t *guid; int (*probe)(struct ishtp_cl_device *dev); - int (*remove)(struct ishtp_cl_device *dev); + void (*remove)(struct ishtp_cl_device *dev); int (*reset)(struct ishtp_cl_device *dev); const struct dev_pm_ops *pm; }; -- cgit v1.2.3 From 94cad2ddb298699882f98099e7346b7bcb5454e1 Mon Sep 17 00:00:00 2001 From: Ye Xiang Date: Tue, 16 Mar 2021 13:23:34 -0700 Subject: HID: intel_ish-hid: HBM: Use connected standby state bit during suspend/resume The individual sensor drivers implemented in the ISH firmware needs capability to take special actions when there is a change in the system standby state. The ISH core firmware passes this notification to individual sensor drivers in response to the OS request via connected standby bit in the SYSTEM_STATE_STATUS command. This change sets CONNECTED_STANDBY_STATE_BIT bit to 1 during suspend callback and clears during resume callback. Signed-off-by: Ye Xiang [srinivas.pandruvada@linux.intel.com: changelog rewrite] Acked-by: Srinivas Pandruvada Signed-off-by: Jiri Kosina --- drivers/hid/intel-ish-hid/ishtp/hbm.c | 6 +++--- drivers/hid/intel-ish-hid/ishtp/hbm.h | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers/hid') diff --git a/drivers/hid/intel-ish-hid/ishtp/hbm.c b/drivers/hid/intel-ish-hid/ishtp/hbm.c index 30a91d068306..dbfae60f2621 100644 --- a/drivers/hid/intel-ish-hid/ishtp/hbm.c +++ b/drivers/hid/intel-ish-hid/ishtp/hbm.c @@ -914,7 +914,7 @@ static inline void fix_cl_hdr(struct ishtp_msg_hdr *hdr, size_t length, /*** Suspend and resume notification ***/ static uint32_t current_state; -static uint32_t supported_states = 0 | SUSPEND_STATE_BIT; +static uint32_t supported_states = SUSPEND_STATE_BIT | CONNECTED_STANDBY_STATE_BIT; /** * ishtp_send_suspend() - Send suspend message to FW @@ -933,7 +933,7 @@ void ishtp_send_suspend(struct ishtp_device *dev) memset(&state_status_msg, 0, len); state_status_msg.hdr.cmd = SYSTEM_STATE_STATUS; state_status_msg.supported_states = supported_states; - current_state |= SUSPEND_STATE_BIT; + current_state |= (SUSPEND_STATE_BIT | CONNECTED_STANDBY_STATE_BIT); dev->print_log(dev, "%s() sends SUSPEND notification\n", __func__); state_status_msg.states_status = current_state; @@ -959,7 +959,7 @@ void ishtp_send_resume(struct ishtp_device *dev) memset(&state_status_msg, 0, len); state_status_msg.hdr.cmd = SYSTEM_STATE_STATUS; state_status_msg.supported_states = supported_states; - current_state &= ~SUSPEND_STATE_BIT; + current_state &= ~(CONNECTED_STANDBY_STATE_BIT | SUSPEND_STATE_BIT); dev->print_log(dev, "%s() sends RESUME notification\n", __func__); state_status_msg.states_status = current_state; diff --git a/drivers/hid/intel-ish-hid/ishtp/hbm.h b/drivers/hid/intel-ish-hid/ishtp/hbm.h index 7c445b203f2a..08f3f3ceb18c 100644 --- a/drivers/hid/intel-ish-hid/ishtp/hbm.h +++ b/drivers/hid/intel-ish-hid/ishtp/hbm.h @@ -235,6 +235,7 @@ struct dma_xfer_hbm { #define SYSTEM_STATE_QUERY_SUBSCRIBERS 0x3 #define SYSTEM_STATE_STATE_CHANGE_REQ 0x4 /*indicates suspend and resume states*/ +#define CONNECTED_STANDBY_STATE_BIT (1<<0) #define SUSPEND_STATE_BIT (1<<1) struct ish_system_states_header { -- cgit v1.2.3 From 4ce3ba52340165c33d1a43a407a138028e210b21 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Fri, 26 Mar 2021 14:34:34 +0000 Subject: HID: intel-ish-hid: Remove unused variable 'err' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes the following W=1 kernel build warning(s): drivers/hid/intel-ish-hid/ishtp/client.c: In function ‘ishtp_cl_disconnect’: drivers/hid/intel-ish-hid/ishtp/client.c:266:6: warning: variable ‘err’ set but not used [-Wunused-but-set-variable] Cc: Srinivas Pandruvada Cc: Jiri Kosina Cc: Benjamin Tissoires Cc: linux-input@vger.kernel.org Signed-off-by: Lee Jones Acked-by: Srinivas Pandruvada Signed-off-by: Benjamin Tissoires --- drivers/hid/intel-ish-hid/ishtp/client.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers/hid') diff --git a/drivers/hid/intel-ish-hid/ishtp/client.c b/drivers/hid/intel-ish-hid/ishtp/client.c index 1cc157126fce..c81a1f8a9268 100644 --- a/drivers/hid/intel-ish-hid/ishtp/client.c +++ b/drivers/hid/intel-ish-hid/ishtp/client.c @@ -263,7 +263,6 @@ EXPORT_SYMBOL(ishtp_cl_unlink); int ishtp_cl_disconnect(struct ishtp_cl *cl) { struct ishtp_device *dev; - int err; if (WARN_ON(!cl || !cl->dev)) return -ENODEV; @@ -283,7 +282,7 @@ int ishtp_cl_disconnect(struct ishtp_cl *cl) return -ENODEV; } - err = wait_event_interruptible_timeout(cl->wait_ctrl_res, + wait_event_interruptible_timeout(cl->wait_ctrl_res, (dev->dev_state != ISHTP_DEV_ENABLED || cl->state == ISHTP_CL_DISCONNECTED), ishtp_secs_to_jiffies(ISHTP_CL_CONNECT_TIMEOUT)); -- cgit v1.2.3 From a2e7aa05d2ad41a3cfb60323f36a87ed7760bd8b Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Fri, 26 Mar 2021 14:34:35 +0000 Subject: HID: ishtp-hid-client: Move variable to where it's actually used MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes the following W=1 kernel build warning(s): In file included from drivers/hid/intel-ish-hid/ishtp-hid.c:11: drivers/hid/intel-ish-hid/ishtp-hid.h:24:21: warning: ‘hid_ishtp_guid’ defined but not used [-Wunused-const-variable=] Cc: Srinivas Pandruvada Cc: Jiri Kosina Cc: Benjamin Tissoires Cc: Daniel Drubin Cc: linux-input@vger.kernel.org Signed-off-by: Lee Jones Acked-by: Srinivas Pandruvada Signed-off-by: Benjamin Tissoires --- drivers/hid/intel-ish-hid/ishtp-hid-client.c | 5 +++++ drivers/hid/intel-ish-hid/ishtp-hid.h | 5 ----- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers/hid') diff --git a/drivers/hid/intel-ish-hid/ishtp-hid-client.c b/drivers/hid/intel-ish-hid/ishtp-hid-client.c index 0f1b5283bab4..24599280105d 100644 --- a/drivers/hid/intel-ish-hid/ishtp-hid-client.c +++ b/drivers/hid/intel-ish-hid/ishtp-hid-client.c @@ -11,6 +11,11 @@ #include #include "ishtp-hid.h" +/* ISH Transport protocol (ISHTP in short) GUID */ +static const guid_t hid_ishtp_guid = + GUID_INIT(0x33AECD58, 0xB679, 0x4E54, + 0x9B, 0xD9, 0xA0, 0x4D, 0x34, 0xF0, 0xC2, 0x26); + /* Rx ring buffer pool size */ #define HID_CL_RX_RING_SIZE 32 #define HID_CL_TX_RING_SIZE 16 diff --git a/drivers/hid/intel-ish-hid/ishtp-hid.h b/drivers/hid/intel-ish-hid/ishtp-hid.h index 5ffd0da3cf1f..e2423f7d2b54 100644 --- a/drivers/hid/intel-ish-hid/ishtp-hid.h +++ b/drivers/hid/intel-ish-hid/ishtp-hid.h @@ -20,11 +20,6 @@ extern void (*hid_print_trace)(void *unused, const char *format, ...); #define hid_ishtp_trace(client, ...) \ (hid_print_trace)(NULL, __VA_ARGS__) -/* ISH Transport protocol (ISHTP in short) GUID */ -static const guid_t hid_ishtp_guid = - GUID_INIT(0x33AECD58, 0xB679, 0x4E54, - 0x9B, 0xD9, 0xA0, 0x4D, 0x34, 0xF0, 0xC2, 0x26); - /* ISH HID message structure */ struct hostif_msg_hdr { uint8_t command; /* Bit 7: is_response */ -- cgit v1.2.3 From 3977e00eb33bcb62cffdf9475d047b347cf79e06 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Fri, 26 Mar 2021 14:34:36 +0000 Subject: HID: intel-ish-hid: pci-ish: Remove unused variable 'ret' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes the following W=1 kernel build warning(s): drivers/hid/intel-ish-hid/ipc/pci-ish.c: In function ‘ish_resume_handler’: drivers/hid/intel-ish-hid/ipc/pci-ish.c:264:6: warning: variable ‘ret’ set but not used [-Wunused-but-set-variable] Cc: Srinivas Pandruvada Cc: Jiri Kosina Cc: Benjamin Tissoires Cc: Zhang Lixu Cc: Kai-Heng Feng Cc: Daniel Drubin Cc: linux-input@vger.kernel.org Signed-off-by: Lee Jones Acked-by: Srinivas Pandruvada Signed-off-by: Benjamin Tissoires --- drivers/hid/intel-ish-hid/ipc/pci-ish.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers/hid') diff --git a/drivers/hid/intel-ish-hid/ipc/pci-ish.c b/drivers/hid/intel-ish-hid/ipc/pci-ish.c index 06081cf9b85a..61efc30ed9af 100644 --- a/drivers/hid/intel-ish-hid/ipc/pci-ish.c +++ b/drivers/hid/intel-ish-hid/ipc/pci-ish.c @@ -261,7 +261,6 @@ static void __maybe_unused ish_resume_handler(struct work_struct *work) struct pci_dev *pdev = to_pci_dev(ish_resume_device); struct ishtp_device *dev = pci_get_drvdata(pdev); uint32_t fwsts = dev->ops->get_fw_status(dev); - int ret; if (ish_should_leave_d0i3(pdev) && !dev->suspend_flag && IPC_IS_ISH_ILUP(fwsts)) { @@ -273,7 +272,7 @@ static void __maybe_unused ish_resume_handler(struct work_struct *work) /* Waiting to get resume response */ if (dev->resume_flag) - ret = wait_event_interruptible_timeout(dev->resume_wait, + wait_event_interruptible_timeout(dev->resume_wait, !dev->resume_flag, msecs_to_jiffies(WAIT_FOR_RESUME_ACK_MS)); -- cgit v1.2.3 From d5831bee4e1a9eca21570de12baf2043b3df4b41 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Fri, 26 Mar 2021 14:34:37 +0000 Subject: HID: intel-ish: Supply some missing param descriptions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes the following W=1 kernel build warning(s): drivers/hid/intel-ish-hid/ishtp/bus.c:173: warning: Function parameter or member 'fw_client' not described in 'ishtp_get_fw_client_id' drivers/hid/intel-ish-hid/ishtp/bus.c:845: warning: Function parameter or member 'device' not described in 'ishtp_device' drivers/hid/intel-ish-hid/ishtp/bus.c:858: warning: Function parameter or member 'device' not described in 'ishtp_get_pci_device' drivers/hid/intel-ish-hid/ishtp/bus.c:871: warning: Function parameter or member 'cl_device' not described in 'ishtp_trace_callback' drivers/hid/intel-ish-hid/ishtp/bus.c:884: warning: Function parameter or member 'dev' not described in 'ish_hw_reset' Cc: Srinivas Pandruvada Cc: Jiri Kosina Cc: Benjamin Tissoires Cc: "Uwe Kleine-König" Cc: linux-input@vger.kernel.org Signed-off-by: Lee Jones Acked-by: Srinivas Pandruvada Signed-off-by: Benjamin Tissoires --- drivers/hid/intel-ish-hid/ishtp/bus.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers/hid') diff --git a/drivers/hid/intel-ish-hid/ishtp/bus.c b/drivers/hid/intel-ish-hid/ishtp/bus.c index ffc9ce5c86ee..c1c7d5356208 100644 --- a/drivers/hid/intel-ish-hid/ishtp/bus.c +++ b/drivers/hid/intel-ish-hid/ishtp/bus.c @@ -164,6 +164,7 @@ EXPORT_SYMBOL(ishtp_fw_cl_get_client); /** * ishtp_get_fw_client_id() - Get fw client id + * @fw_client: firmware client used to fetch the ID * * This interface is used to reset HW get FW client id. * @@ -835,6 +836,7 @@ int ishtp_use_dma_transfer(void) /** * ishtp_device() - Return device pointer + * @device: ISH-TP client device instance * * This interface is used to return device pointer from ishtp_cl_device * instance. @@ -851,6 +853,7 @@ EXPORT_SYMBOL(ishtp_device); * ishtp_get_pci_device() - Return PCI device dev pointer * This interface is used to return PCI device pointer * from ishtp_cl_device instance. + * @device: ISH-TP client device instance * * Return: device *. */ @@ -862,6 +865,7 @@ EXPORT_SYMBOL(ishtp_get_pci_device); /** * ishtp_trace_callback() - Return trace callback + * @cl_device: ISH-TP client device instance * * This interface is used to return trace callback function pointer. * @@ -875,6 +879,7 @@ EXPORT_SYMBOL(ishtp_trace_callback); /** * ish_hw_reset() - Call HW reset IPC callback + * @dev: ISHTP device instance * * This interface is used to reset HW in case of error. * -- cgit v1.2.3 From 15484948a3504c4f9f4b4db9b4f819a4b6a06aa9 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Fri, 26 Mar 2021 14:34:38 +0000 Subject: HID: intel-ish: Fix a naming disparity and a formatting error Fixes the following W=1 kernel build warning(s): drivers/hid/intel-ish-hid/ishtp/hbm.c:409: warning: expecting prototype for ishtp_client_disconnect_request(). Prototype was for ishtp_hbm_fw_disconnect_req() instead drivers/hid/intel-ish-hid/ishtp/hbm.c:433: warning: wrong kernel-doc identifier on line: Cc: Srinivas Pandruvada Cc: Jiri Kosina Cc: Benjamin Tissoires Cc: linux-input@vger.kernel.org Signed-off-by: Lee Jones Acked-by: Srinivas Pandruvada Signed-off-by: Benjamin Tissoires --- drivers/hid/intel-ish-hid/ishtp/hbm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/hid') diff --git a/drivers/hid/intel-ish-hid/ishtp/hbm.c b/drivers/hid/intel-ish-hid/ishtp/hbm.c index dbfae60f2621..9c031a06e4c4 100644 --- a/drivers/hid/intel-ish-hid/ishtp/hbm.c +++ b/drivers/hid/intel-ish-hid/ishtp/hbm.c @@ -398,7 +398,7 @@ static void ishtp_hbm_cl_connect_res(struct ishtp_device *dev, } /** - * ishtp_client_disconnect_request() - Receive disconnect request + * ishtp_hbm_fw_disconnect_req() - Receive disconnect request * @dev: ISHTP device instance * @disconnect_req: disconnect request structure * @@ -430,7 +430,7 @@ static void ishtp_hbm_fw_disconnect_req(struct ishtp_device *dev, } /** - * ishtp_hbm_dma_xfer_ack(() - Receive transfer ACK + * ishtp_hbm_dma_xfer_ack() - Receive transfer ACK * @dev: ISHTP device instance * @dma_xfer: HBM transfer message * -- cgit v1.2.3 From 73c26336b11add63b6e5e8403806ab5693da8a39 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Fri, 26 Mar 2021 14:34:40 +0000 Subject: HID: intel-ish-hid: Fix a little doc-rot Fixes the following W=1 kernel build warning(s): drivers/hid/intel-ish-hid/ishtp/client.c:121: warning: Function parameter or member 'cl_device' not described in 'ishtp_cl_allocate' drivers/hid/intel-ish-hid/ishtp/client.c:121: warning: Excess function parameter 'dev' description in 'ishtp_cl_allocate' Cc: Srinivas Pandruvada Cc: Jiri Kosina Cc: Benjamin Tissoires Cc: Lee Jones Cc: linux-input@vger.kernel.org Signed-off-by: Lee Jones Acked-by: Srinivas Pandruvada Signed-off-by: Benjamin Tissoires --- drivers/hid/intel-ish-hid/ishtp/client.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/hid') diff --git a/drivers/hid/intel-ish-hid/ishtp/client.c b/drivers/hid/intel-ish-hid/ishtp/client.c index c81a1f8a9268..585a5c4066cb 100644 --- a/drivers/hid/intel-ish-hid/ishtp/client.c +++ b/drivers/hid/intel-ish-hid/ishtp/client.c @@ -111,7 +111,7 @@ static void ishtp_cl_init(struct ishtp_cl *cl, struct ishtp_device *dev) /** * ishtp_cl_allocate() - allocates client structure and sets it up. - * @dev: ishtp device + * @cl_device: ishtp client device * * Allocate memory for new client device and call to initialize each field. * -- cgit v1.2.3 From 99c6f96570336179c3372061df86e0278b1b3a30 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Fri, 26 Mar 2021 14:34:43 +0000 Subject: HID: intel-ish-hid: Fix potential copy/paste error Fixes the following W=1 kernel build warning(s): In file included from drivers/hid/intel-ish-hid/ishtp-hid.c:11: drivers/hid/intel-ish-hid/ishtp-hid.c:263: warning: expecting prototype for ishtp_hid_probe(). Prototype was for ishtp_hid_remove() instead Cc: Srinivas Pandruvada Cc: Jiri Kosina Cc: Benjamin Tissoires Cc: linux-input@vger.kernel.org Signed-off-by: Lee Jones Acked-by: Srinivas Pandruvada Signed-off-by: Benjamin Tissoires --- drivers/hid/intel-ish-hid/ishtp-hid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/hid') diff --git a/drivers/hid/intel-ish-hid/ishtp-hid.c b/drivers/hid/intel-ish-hid/ishtp-hid.c index 393bed0abee9..14c271d7d8a9 100644 --- a/drivers/hid/intel-ish-hid/ishtp-hid.c +++ b/drivers/hid/intel-ish-hid/ishtp-hid.c @@ -254,7 +254,7 @@ err_hid_data: } /** - * ishtp_hid_probe() - Remove registered hid device + * ishtp_hid_remove() - Remove registered hid device * @client_data: client data pointer * * This function is used to destroy allocatd HID device. -- cgit v1.2.3 From 5f87e027913009bfcdd368b8ab9e10c1a8c8b22f Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Fri, 26 Mar 2021 14:34:45 +0000 Subject: HID: intel-ish-hid: ipc: Correct fw_reset_work_fn() function name in header MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes the following W=1 kernel build warning(s): drivers/hid/intel-ish-hid/ipc/ipc.c:553: warning: expecting prototype for ish_fw_reset_work_fn(). Prototype was for fw_reset_work_fn() instead Cc: Srinivas Pandruvada Cc: Jiri Kosina Cc: Benjamin Tissoires Cc: Zhang Lixu Cc: "Krzysztof Wilczyński" Cc: linux-input@vger.kernel.org Signed-off-by: Lee Jones Acked-by: Srinivas Pandruvada Signed-off-by: Benjamin Tissoires --- drivers/hid/intel-ish-hid/ipc/ipc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/hid') diff --git a/drivers/hid/intel-ish-hid/ipc/ipc.c b/drivers/hid/intel-ish-hid/ipc/ipc.c index 47bbeb8b492b..9037816e2bf7 100644 --- a/drivers/hid/intel-ish-hid/ipc/ipc.c +++ b/drivers/hid/intel-ish-hid/ipc/ipc.c @@ -544,7 +544,7 @@ static int ish_fw_reset_handler(struct ishtp_device *dev) #define TIMEOUT_FOR_HW_RDY_MS 300 /** - * ish_fw_reset_work_fn() - FW reset worker function + * fw_reset_work_fn() - FW reset worker function * @unused: not used * * Call ish_fw_reset_handler to complete FW reset -- cgit v1.2.3 From fb42b1da32437ee3c33d3d631f5dbe1a5af9b731 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Fri, 26 Mar 2021 14:34:46 +0000 Subject: HID: ishtp-hid-client: Fix incorrect function name report_bad_packet() Fixes the following W=1 kernel build warning(s): drivers/hid/intel-ish-hid/ishtp-hid-client.c:36: warning: expecting prototype for report_bad_packets(). Prototype was for report_bad_packet() instead Cc: Srinivas Pandruvada Cc: Jiri Kosina Cc: Benjamin Tissoires Cc: Daniel Drubin Cc: linux-input@vger.kernel.org Signed-off-by: Lee Jones Acked-by: Srinivas Pandruvada Signed-off-by: Benjamin Tissoires --- drivers/hid/intel-ish-hid/ishtp-hid-client.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/hid') diff --git a/drivers/hid/intel-ish-hid/ishtp-hid-client.c b/drivers/hid/intel-ish-hid/ishtp-hid-client.c index 24599280105d..042a7091802d 100644 --- a/drivers/hid/intel-ish-hid/ishtp-hid-client.c +++ b/drivers/hid/intel-ish-hid/ishtp-hid-client.c @@ -23,7 +23,7 @@ static const guid_t hid_ishtp_guid = #define cl_data_to_dev(client_data) ishtp_device(client_data->cl_device) /** - * report_bad_packets() - Report bad packets + * report_bad_packet() - Report bad packets * @hid_ishtp_cl: Client instance to get stats * @recv_buf: Raw received host interface message * @cur_pos: Current position index in payload -- cgit v1.2.3 From 509405cd7ed2562d366fdf97fe00c549e33ad94d Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Fri, 26 Mar 2021 14:34:57 +0000 Subject: HID: intel-ish-hid: ishtp-fw-loader: Fix a bunch of formatting issues MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit And demote non-conformant header Fixes the following W=1 kernel build warning(s): drivers/hid/intel-ish-hid/ishtp-fw-loader.c:46: warning: Enum value 'LOADER_CMD_XFER_QUERY' not described in enum 'ish_loader_commands' drivers/hid/intel-ish-hid/ishtp-fw-loader.c:46: warning: Enum value 'LOADER_CMD_XFER_FRAGMENT' not described in enum 'ish_loader_commands' drivers/hid/intel-ish-hid/ishtp-fw-loader.c:46: warning: Enum value 'LOADER_CMD_START' not described in enum 'ish_loader_commands' drivers/hid/intel-ish-hid/ishtp-fw-loader.c:108: warning: Function parameter or member 'reserved' not described in 'loader_msg_hdr' drivers/hid/intel-ish-hid/ishtp-fw-loader.c:196: warning: Function parameter or member 'data' not described in 'response_info' drivers/hid/intel-ish-hid/ishtp-fw-loader.c:196: warning: Function parameter or member 'max_size' not described in 'response_info' drivers/hid/intel-ish-hid/ishtp-fw-loader.c:196: warning: Function parameter or member 'size' not described in 'response_info' drivers/hid/intel-ish-hid/ishtp-fw-loader.c:196: warning: Function parameter or member 'error' not described in 'response_info' drivers/hid/intel-ish-hid/ishtp-fw-loader.c:196: warning: Function parameter or member 'received' not described in 'response_info' drivers/hid/intel-ish-hid/ishtp-fw-loader.c:196: warning: Function parameter or member 'wait_queue' not described in 'response_info' drivers/hid/intel-ish-hid/ishtp-fw-loader.c:233: warning: Function parameter or member 'loader_ishtp_cl' not described in 'ishtp_cl_data' drivers/hid/intel-ish-hid/ishtp-fw-loader.c:233: warning: Function parameter or member 'cl_device' not described in 'ishtp_cl_data' drivers/hid/intel-ish-hid/ishtp-fw-loader.c:233: warning: Function parameter or member 'response' not described in 'ishtp_cl_data' drivers/hid/intel-ish-hid/ishtp-fw-loader.c:233: warning: Function parameter or member 'flag_retry' not described in 'ishtp_cl_data' drivers/hid/intel-ish-hid/ishtp-fw-loader.c:233: warning: Function parameter or member 'retry_count' not described in 'ishtp_cl_data' drivers/hid/intel-ish-hid/ishtp-fw-loader.c:252: warning: Function parameter or member 'client_data' not described in 'get_firmware_variant' drivers/hid/intel-ish-hid/ishtp-fw-loader.c:252: warning: Function parameter or member 'filename' not described in 'get_firmware_variant' drivers/hid/intel-ish-hid/ishtp-fw-loader.c:281: warning: Function parameter or member 'out_msg' not described in 'loader_cl_send' drivers/hid/intel-ish-hid/ishtp-fw-loader.c:281: warning: Function parameter or member 'out_size' not described in 'loader_cl_send' drivers/hid/intel-ish-hid/ishtp-fw-loader.c:281: warning: Function parameter or member 'in_msg' not described in 'loader_cl_send' drivers/hid/intel-ish-hid/ishtp-fw-loader.c:281: warning: Function parameter or member 'in_size' not described in 'loader_cl_send' drivers/hid/intel-ish-hid/ishtp-fw-loader.c:281: warning: expecting prototype for Send message from host to firmware(). Prototype was for loader_cl_send() instead drivers/hid/intel-ish-hid/ishtp-fw-loader.c:445: warning: Function parameter or member 'cl_device' not described in 'loader_cl_event_cb' drivers/hid/intel-ish-hid/ishtp-fw-loader.c:445: warning: Excess function parameter 'device' description in 'loader_cl_event_cb' drivers/hid/intel-ish-hid/ishtp-fw-loader.c:551: warning: expecting prototype for Loads ISH firmware using ishtp interface(). Prototype was for ish_fw_xfer_ishtp() instead drivers/hid/intel-ish-hid/ishtp-fw-loader.c:745: warning: expecting prototype for Start executing ISH main firmware(). Prototype was for ish_fw_start() instead drivers/hid/intel-ish-hid/ishtp-fw-loader.c:767: warning: expecting prototype for Loads ISH firmware from host(). Prototype was for load_fw_from_host() instead Cc: Srinivas Pandruvada Cc: Jiri Kosina Cc: Benjamin Tissoires Cc: Sumit Semwal Cc: "Christian König" Cc: Rushikesh S Kadam Cc: linux-input@vger.kernel.org Cc: linux-media@vger.kernel.org Cc: dri-devel@lists.freedesktop.org Cc: linaro-mm-sig@lists.linaro.org Signed-off-by: Lee Jones Acked-by: Srinivas Pandruvada Signed-off-by: Benjamin Tissoires --- drivers/hid/intel-ish-hid/ishtp-fw-loader.c | 45 +++++++++++++++-------------- 1 file changed, 23 insertions(+), 22 deletions(-) (limited to 'drivers/hid') diff --git a/drivers/hid/intel-ish-hid/ishtp-fw-loader.c b/drivers/hid/intel-ish-hid/ishtp-fw-loader.c index edb0bd084c27..d20d74a890e9 100644 --- a/drivers/hid/intel-ish-hid/ishtp-fw-loader.c +++ b/drivers/hid/intel-ish-hid/ishtp-fw-loader.c @@ -31,13 +31,13 @@ /** * enum ish_loader_commands - ISH loader host commands. - * LOADER_CMD_XFER_QUERY Query the Shim firmware loader for + * @LOADER_CMD_XFER_QUERY: Query the Shim firmware loader for * capabilities - * LOADER_CMD_XFER_FRAGMENT Transfer one firmware image fragment at a + * @LOADER_CMD_XFER_FRAGMENT: Transfer one firmware image fragment at a * time. The command may be executed * multiple times until the entire firmware * image is downloaded to SRAM. - * LOADER_CMD_START Start executing the main firmware. + * @LOADER_CMD_START: Start executing the main firmware. */ enum ish_loader_commands { LOADER_CMD_XFER_QUERY = 0, @@ -95,6 +95,7 @@ static int dma_buf_size_limit = 4 * PAGE_SIZE; /** * struct loader_msg_hdr - Header for ISH Loader commands. * @command: LOADER_CMD* commands. Bit 7 is the response. + * @reserved: Reserved space * @status: Command response status. Non 0, is error * condition. * @@ -173,16 +174,16 @@ struct loader_start { * struct response_info - Encapsulate firmware response related * information for passing between function * loader_cl_send() and process_recv() callback. - * @data Copy the data received from firmware here. - * @max_size Max size allocated for the @data buffer. If the + * @data: Copy the data received from firmware here. + * @max_size: Max size allocated for the @data buffer. If the * received data exceeds this value, we log an * error. - * @size Actual size of data received from firmware. - * @error Returns 0 for success, negative error code for a + * @size: Actual size of data received from firmware. + * @error: Returns 0 for success, negative error code for a * failure in function process_recv(). - * @received Set to true on receiving a valid firmware + * @received: Set to true on receiving a valid firmware * response to host command - * @wait_queue Wait queue for Host firmware loading where the + * @wait_queue: Wait queue for Host firmware loading where the * client sends message to ISH firmware and waits * for response */ @@ -195,13 +196,13 @@ struct response_info { wait_queue_head_t wait_queue; }; -/** +/* * struct ishtp_cl_data - Encapsulate per ISH-TP Client Data. * @work_ishtp_reset: Work queue for reset handling. * @work_fw_load: Work queue for host firmware loading. - * @flag_retry Flag for indicating host firmware loading should + * @flag_retry: Flag for indicating host firmware loading should * be retried. - * @retry_count Count the number of retries. + * @retry_count: Count the number of retries. * * This structure is used to store data per client. */ @@ -240,8 +241,8 @@ struct ishtp_cl_data { /** * get_firmware_variant() - Gets the filename of firmware image to be * loaded based on platform variant. - * @client_data Client data instance. - * @filename Returns firmware filename. + * @client_data: Client data instance. + * @filename: Returns firmware filename. * * Queries the firmware-name device property string. * @@ -266,11 +267,11 @@ static int get_firmware_variant(struct ishtp_cl_data *client_data, /** * loader_cl_send() Send message from host to firmware * @client_data: Client data instance - * @out_msg Message buffer to be sent to firmware - * @out_size Size of out going message - * @in_msg Message buffer where the incoming data copied. + * @out_msg: Message buffer to be sent to firmware + * @out_size: Size of out going message + * @in_msg: Message buffer where the incoming data copied. * This buffer is allocated by calling - * @in_size Max size of incoming message + * @in_size: Max size of incoming message * * Return: Number of bytes copied in the in_msg on success, negative * error code on failure. @@ -435,7 +436,7 @@ end: /** * loader_cl_event_cb() - bus driver callback for incoming message - * @device: Pointer to the ishtp client device for which this + * @cl_device: Pointer to the ishtp client device for which this * message is targeted * * Remove the packet from the list and process the message by calling @@ -536,7 +537,7 @@ static int ish_query_loader_prop(struct ishtp_cl_data *client_data, } /** - * ish_fw_xfer_ishtp() Loads ISH firmware using ishtp interface + * ish_fw_xfer_ishtp() - Loads ISH firmware using ishtp interface * @client_data: Client data instance * @fw: Pointer to firmware data struct in host memory * @@ -733,7 +734,7 @@ end_err_dma_buf_release: } /** - * ish_fw_start() Start executing ISH main firmware + * ish_fw_start() - Start executing ISH main firmware * @client_data: client data instance * * This function sends message to Shim firmware loader to start @@ -756,7 +757,7 @@ static int ish_fw_start(struct ishtp_cl_data *client_data) } /** - * load_fw_from_host() Loads ISH firmware from host + * load_fw_from_host() - Loads ISH firmware from host * @client_data: Client data instance * * This function loads the ISH firmware to ISH SRAM and starts execution -- cgit v1.2.3 From c57179c73562e31d39139ac245b8a2d337e1823b Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Fri, 26 Mar 2021 14:34:58 +0000 Subject: HID: ishtp-hid-client: Fix 'suggest-attribute=format' compiler warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes the following W=1 kernel build warning(s): drivers/hid/intel-ish-hid/ishtp/bus.c: In function ‘ishtp_trace_callback’: drivers/hid/intel-ish-hid/ishtp/bus.c:876:29: warning: return type might be a candidate for a format attribute [-Wsuggest-attribute=format] 876 | return cl_device->ishtp_dev->print_log; | ~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~ Cc: Srinivas Pandruvada Cc: Jiri Kosina Cc: Benjamin Tissoires Cc: Daniel Drubin Cc: linux-input@vger.kernel.org Suggested-by: Arnd Bergmann Signed-off-by: Lee Jones Acked-by: Srinivas Pandruvada Signed-off-by: Benjamin Tissoires --- drivers/hid/intel-ish-hid/ishtp-hid-client.c | 4 ++-- drivers/hid/intel-ish-hid/ishtp-hid.h | 4 ++-- drivers/hid/intel-ish-hid/ishtp/bus.c | 4 ++-- drivers/hid/intel-ish-hid/ishtp/ishtp-dev.h | 4 ++-- include/linux/intel-ish-client-if.h | 8 +++++++- 5 files changed, 15 insertions(+), 9 deletions(-) (limited to 'drivers/hid') diff --git a/drivers/hid/intel-ish-hid/ishtp-hid-client.c b/drivers/hid/intel-ish-hid/ishtp-hid-client.c index 042a7091802d..6b1fa971b33e 100644 --- a/drivers/hid/intel-ish-hid/ishtp-hid-client.c +++ b/drivers/hid/intel-ish-hid/ishtp-hid-client.c @@ -784,7 +784,7 @@ static void hid_ishtp_cl_reset_handler(struct work_struct *work) } } -void (*hid_print_trace)(void *unused, const char *format, ...); +ishtp_print_log ishtp_hid_print_trace; /** * hid_ishtp_cl_probe() - ISHTP client driver probe @@ -823,7 +823,7 @@ static int hid_ishtp_cl_probe(struct ishtp_cl_device *cl_device) INIT_WORK(&client_data->work, hid_ishtp_cl_reset_handler); - hid_print_trace = ishtp_trace_callback(cl_device); + ishtp_hid_print_trace = ishtp_trace_callback(cl_device); rv = hid_ishtp_cl_init(hid_ishtp_cl, 0); if (rv) { diff --git a/drivers/hid/intel-ish-hid/ishtp-hid.h b/drivers/hid/intel-ish-hid/ishtp-hid.h index e2423f7d2b54..f88443a7d935 100644 --- a/drivers/hid/intel-ish-hid/ishtp-hid.h +++ b/drivers/hid/intel-ish-hid/ishtp-hid.h @@ -16,9 +16,9 @@ #define IS_RESPONSE 0x80 /* Used to dump to Linux trace buffer, if enabled */ -extern void (*hid_print_trace)(void *unused, const char *format, ...); +extern ishtp_print_log ishtp_hid_print_trace; #define hid_ishtp_trace(client, ...) \ - (hid_print_trace)(NULL, __VA_ARGS__) + (ishtp_hid_print_trace)(NULL, __VA_ARGS__) /* ISH HID message structure */ struct hostif_msg_hdr { diff --git a/drivers/hid/intel-ish-hid/ishtp/bus.c b/drivers/hid/intel-ish-hid/ishtp/bus.c index c1c7d5356208..f0802b047ed8 100644 --- a/drivers/hid/intel-ish-hid/ishtp/bus.c +++ b/drivers/hid/intel-ish-hid/ishtp/bus.c @@ -869,9 +869,9 @@ EXPORT_SYMBOL(ishtp_get_pci_device); * * This interface is used to return trace callback function pointer. * - * Return: void *. + * Return: *ishtp_print_log() */ -void *ishtp_trace_callback(struct ishtp_cl_device *cl_device) +ishtp_print_log ishtp_trace_callback(struct ishtp_cl_device *cl_device) { return cl_device->ishtp_dev->print_log; } diff --git a/drivers/hid/intel-ish-hid/ishtp/ishtp-dev.h b/drivers/hid/intel-ish-hid/ishtp/ishtp-dev.h index 1cc6364aa957..f579b16e6d7a 100644 --- a/drivers/hid/intel-ish-hid/ishtp/ishtp-dev.h +++ b/drivers/hid/intel-ish-hid/ishtp/ishtp-dev.h @@ -10,6 +10,7 @@ #include #include +#include #include "bus.h" #include "hbm.h" @@ -202,8 +203,7 @@ struct ishtp_device { uint64_t ishtp_host_dma_rx_buf_phys; /* Dump to trace buffers if enabled*/ - __printf(2, 3) void (*print_log)(struct ishtp_device *dev, - const char *format, ...); + ishtp_print_log print_log; /* Debug stats */ unsigned int ipc_rx_cnt; diff --git a/include/linux/intel-ish-client-if.h b/include/linux/intel-ish-client-if.h index 94669e21dc8b..25e2b4e80502 100644 --- a/include/linux/intel-ish-client-if.h +++ b/include/linux/intel-ish-client-if.h @@ -8,11 +8,17 @@ #ifndef _INTEL_ISH_CLIENT_IF_H_ #define _INTEL_ISH_CLIENT_IF_H_ +#include +#include + struct ishtp_cl_device; struct ishtp_device; struct ishtp_cl; struct ishtp_fw_client; +typedef __printf(2, 3) void (*ishtp_print_log)(struct ishtp_device *dev, + const char *format, ...); + /* Client state */ enum cl_state { ISHTP_CL_INITIALIZING = 0, @@ -76,7 +82,7 @@ int ishtp_register_event_cb(struct ishtp_cl_device *device, /* Get the device * from ishtp device instance */ struct device *ishtp_device(struct ishtp_cl_device *cl_device); /* Trace interface for clients */ -void *ishtp_trace_callback(struct ishtp_cl_device *cl_device); +ishtp_print_log ishtp_trace_callback(struct ishtp_cl_device *cl_device); /* Get device pointer of PCI device for DMA acces */ struct device *ishtp_get_pci_device(struct ishtp_cl_device *cl_device); -- cgit v1.2.3 From f2145f8dc566c4f3b5a8deb58dcd12bed4e20194 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Fri, 19 Mar 2021 17:27:16 -0700 Subject: HID: do not use down_interruptible() when unbinding devices Action of unbinding driver from a device is not cancellable and should not fail, and driver core does not pay attention to the result of "remove" method, therefore using down_interruptible() in hid_device_remove() does not make sense. Signed-off-by: Dmitry Torokhov Signed-off-by: Jiri Kosina --- drivers/hid/hid-core.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) (limited to 'drivers/hid') diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 0ae9f6df59d1..ff695ec520f8 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -2303,12 +2303,8 @@ static int hid_device_remove(struct device *dev) { struct hid_device *hdev = to_hid_device(dev); struct hid_driver *hdrv; - int ret = 0; - if (down_interruptible(&hdev->driver_input_lock)) { - ret = -EINTR; - goto end; - } + down(&hdev->driver_input_lock); hdev->io_started = false; hdrv = hdev->driver; @@ -2323,8 +2319,8 @@ static int hid_device_remove(struct device *dev) if (!hdev->io_started) up(&hdev->driver_input_lock); -end: - return ret; + + return 0; } static ssize_t modalias_show(struct device *dev, struct device_attribute *a, -- cgit v1.2.3 From 7383354ad59573b42085df3b089ba925a7d1a15a Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sun, 4 Apr 2021 20:56:09 +0200 Subject: HID: logitech-dj/hidpp: Add info/warn/err messages about 27 MHz keyboard encryption By default 27 MHz Logitech keyboards send the keypresses to the receiver in plain text. Logitech's Windows "Keyboard and Mouse settings" tool allows configuring encryption for the keyboard wireless link. Now there also is a Linux tool for setting this up: https://gitlab.freedesktop.org/jwrdegoede/logitech-27mhz-keyboard-encryption-setup Once a keyboard is paired in encrypted mode, it will no longer work with any receiver other then the receiver it was paired with. If a user accidentally tries to pair another keyboard with the receiver with which a keyboard has been paired in encrypted mode, then the receiver looses the encryption key and the originally paired keyboard will no longer work with either that receiver, or another receiver until the keyboard's encryption key is rewritten by another encrypted mode pairing using the tool. Or until it is reset by following a special reset procedure. This commit adds 3 new log messages related to 27 MHz keyboard link encryption to the Logitech dj / hidpp drivers: 1. An info level message when keyboard encryption is being used 2. A warning message when keyboard encryption is not used 3. An error message when the encryption key has been lost and the keyboard will not work because of this Messages 2. and 3. contain a link to the userspace tool to setup the encryption. The linked page also contains instructions to clear the key (without needing the tool) to help a user recover from the keyboard not working in case 3. Signed-off-by: Hans de Goede Signed-off-by: Jiri Kosina --- drivers/hid/hid-logitech-dj.c | 8 ++++++++ drivers/hid/hid-logitech-hidpp.c | 12 ++++++++++++ 2 files changed, 20 insertions(+) (limited to 'drivers/hid') diff --git a/drivers/hid/hid-logitech-dj.c b/drivers/hid/hid-logitech-dj.c index fa835d565982..18d37b3765f3 100644 --- a/drivers/hid/hid-logitech-dj.c +++ b/drivers/hid/hid-logitech-dj.c @@ -100,6 +100,7 @@ #define HIDPP_DEVICE_TYPE_MASK GENMASK(3, 0) #define HIDPP_LINK_STATUS_MASK BIT(6) #define HIDPP_MANUFACTURER_MASK BIT(7) +#define HIDPP_27MHZ_SECURE_MASK BIT(7) #define HIDPP_DEVICE_TYPE_KEYBOARD 1 #define HIDPP_DEVICE_TYPE_MOUSE 2 @@ -984,6 +985,13 @@ static void logi_hidpp_dev_conn_notif_27mhz(struct hid_device *hdev, workitem->reports_supported |= STD_MOUSE | HIDPP; break; case 3: /* Index 3 is always the keyboard */ + if (hidpp_report->params[HIDPP_PARAM_DEVICE_INFO] & HIDPP_27MHZ_SECURE_MASK) { + hid_info(hdev, "Keyboard connection is encrypted\n"); + } else { + hid_warn(hdev, "Keyboard events are send over the air in plain-text / unencrypted\n"); + hid_warn(hdev, "See: https://gitlab.freedesktop.org/jwrdegoede/logitech-27mhz-keyboard-encryption-setup/\n"); + } + fallthrough; case 4: /* Index 4 is used for an optional separate numpad */ workitem->device_type = HIDPP_DEVICE_TYPE_KEYBOARD; workitem->reports_supported |= STD_KEYBOARD | MULTIMEDIA | diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c index d598094dadd0..69670ca7e1e1 100644 --- a/drivers/hid/hid-logitech-hidpp.c +++ b/drivers/hid/hid-logitech-hidpp.c @@ -56,6 +56,8 @@ MODULE_PARM_DESC(disable_tap_to_click, #define HIDPP_SUB_ID_CONSUMER_VENDOR_KEYS 0x03 #define HIDPP_SUB_ID_ROLLER 0x05 #define HIDPP_SUB_ID_MOUSE_EXTRA_BTNS 0x06 +#define HIDPP_SUB_ID_USER_IFACE_EVENT 0x08 +#define HIDPP_USER_IFACE_EVENT_ENCRYPTION_KEY_LOST BIT(5) #define HIDPP_QUIRK_CLASS_WTP BIT(0) #define HIDPP_QUIRK_CLASS_M560 BIT(1) @@ -3528,6 +3530,16 @@ static int hidpp_raw_hidpp_event(struct hidpp_device *hidpp, u8 *data, return 1; } + if (hidpp->hid_dev->group == HID_GROUP_LOGITECH_27MHZ_DEVICE && + data[0] == REPORT_ID_HIDPP_SHORT && + data[2] == HIDPP_SUB_ID_USER_IFACE_EVENT && + (data[3] & HIDPP_USER_IFACE_EVENT_ENCRYPTION_KEY_LOST)) { + dev_err_ratelimited(&hidpp->hid_dev->dev, + "Error the keyboard's wireless encryption key has been lost, your keyboard will not work unless you re-configure encryption.\n"); + dev_err_ratelimited(&hidpp->hid_dev->dev, + "See: https://gitlab.freedesktop.org/jwrdegoede/logitech-27mhz-keyboard-encryption-setup/\n"); + } + if (hidpp->capabilities & HIDPP_CAPABILITY_HIDPP20_BATTERY) { ret = hidpp20_battery_event_1000(hidpp, data, size); if (ret != 0) -- cgit v1.2.3 From 8dcaa046bf96353c878ddadda506e2708cb4b8c3 Mon Sep 17 00:00:00 2001 From: Ikjoon Jang Date: Thu, 15 Apr 2021 11:29:58 +0800 Subject: HID: google: Add of_match table to Whiskers switch device. Add a device tree match table for "cros-cbas" switch device. Signed-off-by: Ikjoon Jang Reviewed-by: Dmitry Torokhov Acked-by: Jiri Kosina Signed-off-by: Jiri Kosina --- drivers/hid/hid-google-hammer.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'drivers/hid') diff --git a/drivers/hid/hid-google-hammer.c b/drivers/hid/hid-google-hammer.c index e60c31dd05ff..8123b871a3eb 100644 --- a/drivers/hid/hid-google-hammer.c +++ b/drivers/hid/hid-google-hammer.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -272,12 +273,21 @@ static const struct acpi_device_id cbas_ec_acpi_ids[] = { }; MODULE_DEVICE_TABLE(acpi, cbas_ec_acpi_ids); +#ifdef CONFIG_OF +static const struct of_device_id cbas_ec_of_match[] = { + { .compatible = "google,cros-cbas" }, + { }, +}; +MODULE_DEVICE_TABLE(of, cbas_ec_of_match); +#endif + static struct platform_driver cbas_ec_driver = { .probe = cbas_ec_probe, .remove = cbas_ec_remove, .driver = { .name = "cbas_ec", .acpi_match_table = ACPI_PTR(cbas_ec_acpi_ids), + .of_match_table = of_match_ptr(cbas_ec_of_match), .pm = &cbas_ec_pm_ops, }, }; -- cgit v1.2.3 From 042d05b2e30e8a2bb378ecb668a85790dce39355 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Fri, 16 Apr 2021 15:13:18 +0200 Subject: HID: lg-g15: Remove unused size argument from lg_*_event() functions The report-size is already checked in lg_g15_raw_event() before calling the lg_*_event() functions and these functions don't use the passed in size at all, drop the unused parameter. Signed-off-by: Hans de Goede Signed-off-by: Jiri Kosina --- drivers/hid/hid-lg-g15.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'drivers/hid') diff --git a/drivers/hid/hid-lg-g15.c b/drivers/hid/hid-lg-g15.c index bfbba0d41933..b887af72957c 100644 --- a/drivers/hid/hid-lg-g15.c +++ b/drivers/hid/hid-lg-g15.c @@ -464,7 +464,7 @@ static int lg_g15_get_initial_led_brightness(struct lg_g15_data *g15) /******** Input functions ********/ /* On the G15 Mark I Logitech has been quite creative with which bit is what */ -static int lg_g15_event(struct lg_g15_data *g15, u8 *data, int size) +static int lg_g15_event(struct lg_g15_data *g15, u8 *data) { int i, val; @@ -510,7 +510,7 @@ static int lg_g15_event(struct lg_g15_data *g15, u8 *data, int size) return 0; } -static int lg_g15_v2_event(struct lg_g15_data *g15, u8 *data, int size) +static int lg_g15_v2_event(struct lg_g15_data *g15, u8 *data) { int i, val; @@ -542,7 +542,7 @@ static int lg_g15_v2_event(struct lg_g15_data *g15, u8 *data, int size) return 0; } -static int lg_g510_event(struct lg_g15_data *g15, u8 *data, int size) +static int lg_g510_event(struct lg_g15_data *g15, u8 *data) { bool game_mode_enabled; int i, val; @@ -586,7 +586,7 @@ static int lg_g510_event(struct lg_g15_data *g15, u8 *data, int size) return 0; } -static int lg_g510_leds_event(struct lg_g15_data *g15, u8 *data, int size) +static int lg_g510_leds_event(struct lg_g15_data *g15, u8 *data) { bool backlight_disabled; @@ -613,18 +613,18 @@ static int lg_g15_raw_event(struct hid_device *hdev, struct hid_report *report, switch (g15->model) { case LG_G15: if (data[0] == 0x02 && size == 9) - return lg_g15_event(g15, data, size); + return lg_g15_event(g15, data); break; case LG_G15_V2: if (data[0] == 0x02 && size == 5) - return lg_g15_v2_event(g15, data, size); + return lg_g15_v2_event(g15, data); break; case LG_G510: case LG_G510_USB_AUDIO: if (data[0] == 0x03 && size == 5) - return lg_g510_event(g15, data, size); + return lg_g510_event(g15, data); if (data[0] == 0x04 && size == 2) - return lg_g510_leds_event(g15, data, size); + return lg_g510_leds_event(g15, data); break; } -- cgit v1.2.3 From ba3e054e7a70d447aa95883dab87a4eae641d6bc Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Fri, 16 Apr 2021 15:13:19 +0200 Subject: HID: lg-g15: Add a lg_g15_handle_lcd_menu_keys() helper function Factor out the handling of the G15 LCD menu keys out of lg_g15_event() into a new lg_g15_handle_lcd_menu_keys() helper function. This is a preparation patch for adding support for the LCD menu keys on the Logitech Z-10 speakers (with LCD) which use the same funky HID report format. Signed-off-by: Hans de Goede Signed-off-by: Jiri Kosina --- drivers/hid/hid-lg-g15.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) (limited to 'drivers/hid') diff --git a/drivers/hid/hid-lg-g15.c b/drivers/hid/hid-lg-g15.c index b887af72957c..75a27b48d9c9 100644 --- a/drivers/hid/hid-lg-g15.c +++ b/drivers/hid/hid-lg-g15.c @@ -464,6 +464,19 @@ static int lg_g15_get_initial_led_brightness(struct lg_g15_data *g15) /******** Input functions ********/ /* On the G15 Mark I Logitech has been quite creative with which bit is what */ +static void lg_g15_handle_lcd_menu_keys(struct lg_g15_data *g15, u8 *data) +{ + int i, val; + + /* Most left (round/display) button below the LCD */ + input_report_key(g15->input, KEY_KBD_LCD_MENU1, data[8] & 0x80); + /* 4 other buttons below the LCD */ + for (i = 0; i < 4; i++) { + val = data[i + 2] & 0x80; + input_report_key(g15->input, KEY_KBD_LCD_MENU2 + i, val); + } +} + static int lg_g15_event(struct lg_g15_data *g15, u8 *data) { int i, val; @@ -494,13 +507,7 @@ static int lg_g15_event(struct lg_g15_data *g15, u8 *data) /* MR */ input_report_key(g15->input, KEY_MACRO_RECORD_START, data[7] & 0x40); - /* Most left (round) button below the LCD */ - input_report_key(g15->input, KEY_KBD_LCD_MENU1, data[8] & 0x80); - /* 4 other buttons below the LCD */ - for (i = 0; i < 4; i++) { - val = data[i + 2] & 0x80; - input_report_key(g15->input, KEY_KBD_LCD_MENU2 + i, val); - } + lg_g15_handle_lcd_menu_keys(g15, data); /* Backlight cycle button pressed? */ if (data[1] & 0x80) -- cgit v1.2.3 From 614d34f8b3dba62ff0d13d0d45e3220c2960b17d Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Fri, 16 Apr 2021 15:13:20 +0200 Subject: HID: lg-g15: Add a lg_g15_init_input_dev() helper function Factor the input-device setup + KEY_KBD_LCD_MENU capability setting out of lg_g15_probe() into a new lg_g15_init_input_dev() helper function. This is a preparation patch for adding support for the LCD menu keys + LCD brightness control on the Logitech Z-10 speakers (with LCD) which use the same protocol as the G15 keyboards. Signed-off-by: Hans de Goede Signed-off-by: Jiri Kosina --- drivers/hid/hid-lg-g15.c | 42 +++++++++++++++++++++++++----------------- 1 file changed, 25 insertions(+), 17 deletions(-) (limited to 'drivers/hid') diff --git a/drivers/hid/hid-lg-g15.c b/drivers/hid/hid-lg-g15.c index 75a27b48d9c9..eff8c51a8dce 100644 --- a/drivers/hid/hid-lg-g15.c +++ b/drivers/hid/hid-lg-g15.c @@ -709,6 +709,28 @@ static int lg_g15_register_led(struct lg_g15_data *g15, int i) return devm_led_classdev_register(&g15->hdev->dev, &g15->leds[i].cdev); } +/* Common input device init code shared between keyboards and Z-10 speaker handling */ +static void lg_g15_init_input_dev(struct hid_device *hdev, struct input_dev *input, + const char *name) +{ + int i; + + input->name = name; + input->phys = hdev->phys; + input->uniq = hdev->uniq; + input->id.bustype = hdev->bus; + input->id.vendor = hdev->vendor; + input->id.product = hdev->product; + input->id.version = hdev->version; + input->dev.parent = &hdev->dev; + input->open = lg_g15_input_open; + input->close = lg_g15_input_close; + + /* Keys below the LCD, intended for controlling a menu on the LCD */ + for (i = 0; i < 5; i++) + input_set_capability(input, EV_KEY, KEY_KBD_LCD_MENU1 + i); +} + static int lg_g15_probe(struct hid_device *hdev, const struct hid_device_id *id) { u8 gkeys_settings_output_report = 0; @@ -751,6 +773,8 @@ static int lg_g15_probe(struct hid_device *hdev, const struct hid_device_id *id) g15->hdev = hdev; g15->model = id->driver_data; + g15->input = input; + input_set_drvdata(input, hdev); hid_set_drvdata(hdev, (void *)g15); switch (g15->model) { @@ -822,16 +846,7 @@ static int lg_g15_probe(struct hid_device *hdev, const struct hid_device_id *id) goto error_hw_stop; /* Setup and register input device */ - input->name = "Logitech Gaming Keyboard Gaming Keys"; - input->phys = hdev->phys; - input->uniq = hdev->uniq; - input->id.bustype = hdev->bus; - input->id.vendor = hdev->vendor; - input->id.product = hdev->product; - input->id.version = hdev->version; - input->dev.parent = &hdev->dev; - input->open = lg_g15_input_open; - input->close = lg_g15_input_close; + lg_g15_init_input_dev(hdev, input, "Logitech Gaming Keyboard Gaming Keys"); /* G-keys */ for (i = 0; i < gkeys; i++) @@ -842,10 +857,6 @@ static int lg_g15_probe(struct hid_device *hdev, const struct hid_device_id *id) input_set_capability(input, EV_KEY, KEY_MACRO_PRESET1 + i); input_set_capability(input, EV_KEY, KEY_MACRO_RECORD_START); - /* Keys below the LCD, intended for controlling a menu on the LCD */ - for (i = 0; i < 5; i++) - input_set_capability(input, EV_KEY, KEY_KBD_LCD_MENU1 + i); - /* * On the G510 only report headphone and mic mute keys when *not* using * the builtin USB audio device. When the builtin audio is used these @@ -857,9 +868,6 @@ static int lg_g15_probe(struct hid_device *hdev, const struct hid_device_id *id) input_set_capability(input, EV_KEY, KEY_F20); } - g15->input = input; - input_set_drvdata(input, hdev); - ret = input_register_device(input); if (ret) goto error_hw_stop; -- cgit v1.2.3 From 1e5c22983f13fc1ac05fc21772893b2602ddeb66 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Fri, 16 Apr 2021 15:13:21 +0200 Subject: HID: lg-g15: Make the LED-name used by lg_g15_register_led() a parameter Make the LED-name used by lg_g15_register_led() a parameter. This is a preparation patch for adding support for the LCD menu keys + LCD brightness control on the Logitech Z-10 speakers (with LCD) which use the same protocol as the G15 keyboards. Signed-off-by: Hans de Goede Signed-off-by: Jiri Kosina --- drivers/hid/hid-lg-g15.c | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) (limited to 'drivers/hid') diff --git a/drivers/hid/hid-lg-g15.c b/drivers/hid/hid-lg-g15.c index eff8c51a8dce..b76988c19f84 100644 --- a/drivers/hid/hid-lg-g15.c +++ b/drivers/hid/hid-lg-g15.c @@ -652,19 +652,10 @@ static void lg_g15_input_close(struct input_dev *dev) hid_hw_close(hdev); } -static int lg_g15_register_led(struct lg_g15_data *g15, int i) +static int lg_g15_register_led(struct lg_g15_data *g15, int i, const char *name) { - static const char * const led_names[] = { - "g15::kbd_backlight", - "g15::lcd_backlight", - "g15::macro_preset1", - "g15::macro_preset2", - "g15::macro_preset3", - "g15::macro_record", - }; - g15->leds[i].led = i; - g15->leds[i].cdev.name = led_names[i]; + g15->leds[i].cdev.name = name; switch (g15->model) { case LG_G15: @@ -733,6 +724,14 @@ static void lg_g15_init_input_dev(struct hid_device *hdev, struct input_dev *inp static int lg_g15_probe(struct hid_device *hdev, const struct hid_device_id *id) { + static const char * const led_names[] = { + "g15::kbd_backlight", + "g15::lcd_backlight", + "g15::macro_preset1", + "g15::macro_preset2", + "g15::macro_preset3", + "g15::macro_record", + }; u8 gkeys_settings_output_report = 0; u8 gkeys_settings_feature_report = 0; struct hid_report_enum *rep_enum; @@ -874,7 +873,7 @@ static int lg_g15_probe(struct hid_device *hdev, const struct hid_device_id *id) /* Register LED devices */ for (i = 0; i < LG_G15_LED_MAX; i++) { - ret = lg_g15_register_led(g15, i); + ret = lg_g15_register_led(g15, i, led_names[i]); if (ret) goto error_hw_stop; } -- cgit v1.2.3 From cbe5b6b6a77ad262d9f9a56962c9b1ac2f91c0f5 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Fri, 16 Apr 2021 15:13:22 +0200 Subject: HID: lg-g15: Add support for the Logitech Z-10 speakers Add support to hid-lg-g15 for the Logitech Z-10 speakers. This adds support for the LCD menu keys found on these speakers, as well as support for controlling the LCD's brightness through a LED classdev. Signed-off-by: Hans de Goede Signed-off-by: Jiri Kosina --- drivers/hid/hid-ids.h | 1 + drivers/hid/hid-lg-g15.c | 38 +++++++++++++++++++++++++++++++++++++- 2 files changed, 38 insertions(+), 1 deletion(-) (limited to 'drivers/hid') diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 84b8da3e7d09..b0b0a55de26d 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -763,6 +763,7 @@ #define I2C_DEVICE_ID_LG_7010 0x7010 #define USB_VENDOR_ID_LOGITECH 0x046d +#define USB_DEVICE_ID_LOGITECH_Z_10_SPK 0x0a07 #define USB_DEVICE_ID_LOGITECH_AUDIOHUB 0x0a0e #define USB_DEVICE_ID_LOGITECH_T651 0xb00c #define USB_DEVICE_ID_LOGITECH_DINOVO_EDGE_KBD 0xb309 diff --git a/drivers/hid/hid-lg-g15.c b/drivers/hid/hid-lg-g15.c index b76988c19f84..701ddb98e7d2 100644 --- a/drivers/hid/hid-lg-g15.c +++ b/drivers/hid/hid-lg-g15.c @@ -28,6 +28,7 @@ enum lg_g15_model { LG_G15_V2, LG_G510, LG_G510_USB_AUDIO, + LG_Z10, }; enum lg_g15_led_type { @@ -457,6 +458,13 @@ static int lg_g15_get_initial_led_brightness(struct lg_g15_data *g15) return ret; return lg_g510_update_mkey_led_brightness(g15); + case LG_Z10: + /* + * Getting the LCD backlight brightness is not supported. + * Reading Feature(2) fails with -EPIPE and this crashes + * the LCD and touch keys part of the speakers. + */ + return 0; } return -EINVAL; /* Never reached */ } @@ -626,6 +634,12 @@ static int lg_g15_raw_event(struct hid_device *hdev, struct hid_report *report, if (data[0] == 0x02 && size == 5) return lg_g15_v2_event(g15, data); break; + case LG_Z10: + if (data[0] == 0x02 && size == 9) { + lg_g15_handle_lcd_menu_keys(g15, data); + input_sync(g15->input); + } + break; case LG_G510: case LG_G510_USB_AUDIO: if (data[0] == 0x03 && size == 5) @@ -660,8 +674,10 @@ static int lg_g15_register_led(struct lg_g15_data *g15, int i, const char *name) switch (g15->model) { case LG_G15: case LG_G15_V2: - g15->leds[i].cdev.brightness_set_blocking = lg_g15_led_set; g15->leds[i].cdev.brightness_get = lg_g15_led_get; + fallthrough; + case LG_Z10: + g15->leds[i].cdev.brightness_set_blocking = lg_g15_led_set; if (i < LG_G15_BRIGHTNESS_MAX) { g15->leds[i].cdev.flags = LED_BRIGHT_HW_CHANGED; g15->leds[i].cdev.max_brightness = 2; @@ -802,6 +818,9 @@ static int lg_g15_probe(struct hid_device *hdev, const struct hid_device_id *id) gkeys_settings_feature_report = 0x01; gkeys = 18; break; + case LG_Z10: + connect_mask = HID_CONNECT_HIDRAW; + break; } ret = hid_hw_start(hdev, connect_mask); @@ -844,6 +863,19 @@ static int lg_g15_probe(struct hid_device *hdev, const struct hid_device_id *id) if (ret) goto error_hw_stop; + if (g15->model == LG_Z10) { + lg_g15_init_input_dev(hdev, g15->input, "Logitech Z-10 LCD Menu Keys"); + ret = input_register_device(g15->input); + if (ret) + goto error_hw_stop; + + ret = lg_g15_register_led(g15, 1, "z-10::lcd_backlight"); + if (ret) + goto error_hw_stop; + + return 0; /* All done */ + } + /* Setup and register input device */ lg_g15_init_input_dev(hdev, input, "Logitech Gaming Keyboard Gaming Keys"); @@ -904,6 +936,10 @@ static const struct hid_device_id lg_g15_devices[] = { { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G510_USB_AUDIO), .driver_data = LG_G510_USB_AUDIO }, + /* Z-10 speakers */ + { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, + USB_DEVICE_ID_LOGITECH_Z_10_SPK), + .driver_data = LG_Z10 }, { } }; MODULE_DEVICE_TABLE(hid, lg_g15_devices); -- cgit v1.2.3 From b413c59ead320a21eb72ab7c2e0f0a81911f67ab Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Fri, 16 Apr 2021 15:13:23 +0200 Subject: HID: lg-g15 + ite: Add MODULE_AUTHOR I noticed that the 2 HID drivers which I've written and maintain were missing a MODULE_AUTHOR tag, add this so that people can easily figure out who to email with questions. Signed-off-by: Hans de Goede Signed-off-by: Jiri Kosina --- drivers/hid/hid-ite.c | 1 + drivers/hid/hid-lg-g15.c | 1 + 2 files changed, 2 insertions(+) (limited to 'drivers/hid') diff --git a/drivers/hid/hid-ite.c b/drivers/hid/hid-ite.c index 14fc068affad..430fa4f52ed3 100644 --- a/drivers/hid/hid-ite.c +++ b/drivers/hid/hid-ite.c @@ -135,4 +135,5 @@ static struct hid_driver ite_driver = { }; module_hid_driver(ite_driver); +MODULE_AUTHOR("Hans de Goede "); MODULE_LICENSE("GPL"); diff --git a/drivers/hid/hid-lg-g15.c b/drivers/hid/hid-lg-g15.c index 701ddb98e7d2..b2a08233f8d5 100644 --- a/drivers/hid/hid-lg-g15.c +++ b/drivers/hid/hid-lg-g15.c @@ -952,4 +952,5 @@ static struct hid_driver lg_g15_driver = { }; module_hid_driver(lg_g15_driver); +MODULE_AUTHOR("Hans de Goede "); MODULE_LICENSE("GPL"); -- cgit v1.2.3 From eb134536cf6fb2e50b5ced653f7c34d306b2d73f Mon Sep 17 00:00:00 2001 From: Ahelenia Ziemiańska Date: Mon, 8 Mar 2021 18:42:13 +0100 Subject: HID: input: replace outdated HID numbers+comments with macros MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These were untouched since 2.3.99-pre3, and the explanatory comment for HID_DG_TIPPRESSURE is TipPressure in other places Signed-off-by: Ahelenia Ziemiańska Signed-off-by: Jiri Kosina --- drivers/hid/hid-input.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/hid') diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index 18f5e28d475c..c62c6a9b2132 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c @@ -1313,12 +1313,12 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct return; } - if (usage->hid == (HID_UP_DIGITIZER | 0x003c)) { /* Invert */ + if (usage->hid == HID_DG_INVERT) { *quirks = value ? (*quirks | HID_QUIRK_INVERT) : (*quirks & ~HID_QUIRK_INVERT); return; } - if (usage->hid == (HID_UP_DIGITIZER | 0x0032)) { /* InRange */ + if (usage->hid == HID_DG_INRANGE) { if (value) { input_event(input, usage->type, (*quirks & HID_QUIRK_INVERT) ? BTN_TOOL_RUBBER : usage->code, 1); return; @@ -1328,7 +1328,7 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct return; } - if (usage->hid == (HID_UP_DIGITIZER | 0x0030) && (*quirks & HID_QUIRK_NOTOUCH)) { /* Pressure */ + if (usage->hid == HID_DG_TIPPRESSURE && (*quirks & HID_QUIRK_NOTOUCH)) { int a = field->logical_minimum; int b = field->logical_maximum; input_event(input, EV_KEY, BTN_TOUCH, value > a + ((b - a) >> 3)); -- cgit v1.2.3 From b15b253c908235bb10bdbc36f7e33ab40758215f Mon Sep 17 00:00:00 2001 From: Hyeonggon Yoo <42.hyeyoo@gmail.com> Date: Mon, 24 May 2021 23:57:43 +0900 Subject: HID: usbmouse: Avoid GFP_ATOMIC when GFP_KERNEL is possible probe in usb don't need to be atomic. So GFP_KERNEL can be used here, instead of GFP_ATOMIC. Signed-off-by: Hyeonggon Yoo <42.hyeyoo@gmail.com> Signed-off-by: Jiri Kosina --- drivers/hid/usbhid/usbmouse.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/hid') diff --git a/drivers/hid/usbhid/usbmouse.c b/drivers/hid/usbhid/usbmouse.c index 073127e65ac1..c89332017d5d 100644 --- a/drivers/hid/usbhid/usbmouse.c +++ b/drivers/hid/usbhid/usbmouse.c @@ -130,7 +130,7 @@ static int usb_mouse_probe(struct usb_interface *intf, const struct usb_device_i if (!mouse || !input_dev) goto fail1; - mouse->data = usb_alloc_coherent(dev, 8, GFP_ATOMIC, &mouse->data_dma); + mouse->data = usb_alloc_coherent(dev, 8, GFP_KERNEL, &mouse->data_dma); if (!mouse->data) goto fail1; -- cgit v1.2.3 From f8e5388a9da05708fb6d5a0137b287dbfd32d29c Mon Sep 17 00:00:00 2001 From: Austin Kim Date: Thu, 27 May 2021 08:16:37 +0100 Subject: HID: intel-ish-hid: Fix minor typos in comments Change "poiner" to "pointer" in comments. Signed-off-by: Austin Kim Signed-off-by: Jiri Kosina --- drivers/hid/intel-ish-hid/ishtp-fw-loader.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/hid') diff --git a/drivers/hid/intel-ish-hid/ishtp-fw-loader.c b/drivers/hid/intel-ish-hid/ishtp-fw-loader.c index 6cf59fd26ad7..a8fe893aed62 100644 --- a/drivers/hid/intel-ish-hid/ishtp-fw-loader.c +++ b/drivers/hid/intel-ish-hid/ishtp-fw-loader.c @@ -455,7 +455,7 @@ static void loader_cl_event_cb(struct ishtp_cl_device *cl_device) /** * ish_query_loader_prop() - Query ISH Shim firmware loader * @client_data: Client data instance - * @fw: Poiner to firmware data struct in host memory + * @fw: Pointer to firmware data struct in host memory * @fw_info: Loader firmware properties * * This function queries the ISH Shim firmware loader for capabilities. -- cgit v1.2.3 From b5539722eb832441f309642fe5102cc3536f92b8 Mon Sep 17 00:00:00 2001 From: Zoltan Tamas Vajda Date: Thu, 3 Jun 2021 20:58:14 +0200 Subject: HID: hid-input: add Surface Go battery quirk The Elantech touchscreen/digitizer in the Surface Go mistakenly reports having a battery. This results in a low battery message every time you try to use the pen. This patch adds a quirk to ignore the non-existent battery and gets rid of the false low battery messages. Signed-off-by: Zoltan Tamas Vajda Signed-off-by: Jiri Kosina --- drivers/hid/hid-ids.h | 1 + drivers/hid/hid-input.c | 2 ++ 2 files changed, 3 insertions(+) (limited to 'drivers/hid') diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index b84a0a11e05b..63ca5959dc67 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -396,6 +396,7 @@ #define USB_DEVICE_ID_HP_X2_10_COVER 0x0755 #define I2C_DEVICE_ID_HP_SPECTRE_X360_15 0x2817 #define USB_DEVICE_ID_ASUS_UX550_TOUCHSCREEN 0x2706 +#define I2C_DEVICE_ID_SURFACE_GO_TOUCHSCREEN 0x261A #define USB_VENDOR_ID_ELECOM 0x056e #define USB_DEVICE_ID_ELECOM_BM084 0x0061 diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index abbfa91e73e4..68c8644234a4 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c @@ -326,6 +326,8 @@ static const struct hid_device_id hid_battery_quirks[] = { HID_BATTERY_QUIRK_IGNORE }, { HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_HP_SPECTRE_X360_15), HID_BATTERY_QUIRK_IGNORE }, + { HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_SURFACE_GO_TOUCHSCREEN), + HID_BATTERY_QUIRK_IGNORE }, {} }; -- cgit v1.2.3 From 65e4122d2ea758a1834a5ddf9c555a4d2c1dd66a Mon Sep 17 00:00:00 2001 From: Even Xu Date: Thu, 10 Jun 2021 14:21:52 +0800 Subject: HID: intel-ish-hid: Set ISH driver depends on x86 During ISH DMA enabling, some platforms (such as EHL) don't support cache snooping, driver needs involve clflush_cache_range API which isn't supported by all archs (such as ARM). Considering ISH only exists on Intel platforms, add the dependence in Kconfig to avoid build warnings or errors on other archs. Acked-by: Pandruvada, Srinivas Signed-off-by: Even Xu Signed-off-by: Jiri Kosina --- drivers/hid/intel-ish-hid/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/hid') diff --git a/drivers/hid/intel-ish-hid/Kconfig b/drivers/hid/intel-ish-hid/Kconfig index c6c9cfe2475e..689da84a520d 100644 --- a/drivers/hid/intel-ish-hid/Kconfig +++ b/drivers/hid/intel-ish-hid/Kconfig @@ -5,6 +5,7 @@ menu "Intel ISH HID support" config INTEL_ISH_HID tristate "Intel Integrated Sensor Hub" default n + depends on X86 select HID help The Integrated Sensor Hub (ISH) enables the ability to offload -- cgit v1.2.3 From 4aae88b9a9749f5b1c74f004ed8bd8efbaa96440 Mon Sep 17 00:00:00 2001 From: Even Xu Date: Thu, 10 Jun 2021 14:21:53 +0800 Subject: HID: intel-ish-hid: ishtp: Add dma_no_cache_snooping() callback Different platforms have different DMA capability, on most of platforms, DMA support cache snooping. But few platforms, such as ElkhartLake (EHL), don't support cache snooping which requires cache flush from driver. So add a hardware level callback to let ishtp driver know if cache flush is needed. As most of platform support cache snooping, so driver will not do cache flush by default, until platform implements this callback and return true explicitly. Acked-by: Pandruvada, Srinivas Signed-off-by: Even Xu Signed-off-by: Jiri Kosina --- drivers/hid/intel-ish-hid/ishtp/client.c | 18 ++++++++++++++++++ drivers/hid/intel-ish-hid/ishtp/ishtp-dev.h | 1 + 2 files changed, 19 insertions(+) (limited to 'drivers/hid') diff --git a/drivers/hid/intel-ish-hid/ishtp/client.c b/drivers/hid/intel-ish-hid/ishtp/client.c index 585a5c4066cb..405e0d5212cc 100644 --- a/drivers/hid/intel-ish-hid/ishtp/client.c +++ b/drivers/hid/intel-ish-hid/ishtp/client.c @@ -10,6 +10,7 @@ #include #include #include +#include #include "hbm.h" #include "client.h" @@ -772,6 +773,14 @@ static void ishtp_cl_send_msg_dma(struct ishtp_device *dev, /* write msg to dma buf */ memcpy(msg_addr, cl_msg->send_buf.data, cl_msg->send_buf.size); + /* + * if current fw don't support cache snooping, driver have to + * flush the cache manually. + */ + if (dev->ops->dma_no_cache_snooping && + dev->ops->dma_no_cache_snooping(dev)) + clflush_cache_range(msg_addr, cl_msg->send_buf.size); + /* send dma_xfer hbm msg */ off = msg_addr - (unsigned char *)dev->ishtp_host_dma_tx_buf; ishtp_hbm_hdr(&hdr, sizeof(struct dma_xfer_hbm)); @@ -996,6 +1005,15 @@ void recv_ishtp_cl_msg_dma(struct ishtp_device *dev, void *msg, } buffer = rb->buffer.data; + + /* + * if current fw don't support cache snooping, driver have to + * flush the cache manually. + */ + if (dev->ops->dma_no_cache_snooping && + dev->ops->dma_no_cache_snooping(dev)) + clflush_cache_range(msg, hbm->msg_length); + memcpy(buffer, msg, hbm->msg_length); rb->buf_idx = hbm->msg_length; diff --git a/drivers/hid/intel-ish-hid/ishtp/ishtp-dev.h b/drivers/hid/intel-ish-hid/ishtp/ishtp-dev.h index f579b16e6d7a..32142c7d9a04 100644 --- a/drivers/hid/intel-ish-hid/ishtp/ishtp-dev.h +++ b/drivers/hid/intel-ish-hid/ishtp/ishtp-dev.h @@ -119,6 +119,7 @@ struct ishtp_hw_ops { unsigned long buffer_length); uint32_t (*get_fw_status)(struct ishtp_device *dev); void (*sync_fw_clock)(struct ishtp_device *dev); + bool (*dma_no_cache_snooping)(struct ishtp_device *dev); }; /** -- cgit v1.2.3 From aa59d6bb5ec88e30802174f9accc5d2dc50209ad Mon Sep 17 00:00:00 2001 From: Even Xu Date: Thu, 10 Jun 2021 14:21:54 +0800 Subject: HID: intel-ish-hid: ipc: Specify that EHL no cache snooping Specify that EHL doesn't support DMA cache snooping. Acked-by: Pandruvada, Srinivas Signed-off-by: Even Xu Signed-off-by: Jiri Kosina --- drivers/hid/intel-ish-hid/ipc/ipc.c | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) (limited to 'drivers/hid') diff --git a/drivers/hid/intel-ish-hid/ipc/ipc.c b/drivers/hid/intel-ish-hid/ipc/ipc.c index 9037816e2bf7..45e0c7b1c9ec 100644 --- a/drivers/hid/intel-ish-hid/ipc/ipc.c +++ b/drivers/hid/intel-ish-hid/ipc/ipc.c @@ -889,6 +889,29 @@ static uint32_t ish_ipc_get_header(struct ishtp_device *dev, int length, return drbl_val; } +/** + * _dma_no_cache_snooping() + * + * Check on current platform, DMA supports cache snooping or not. + * This callback is used to notify uplayer driver if manully cache + * flush is needed when do DMA operation. + * + * Please pay attention to this callback implementation, if declare + * having cache snooping on a cache snooping not supported platform + * will cause uplayer driver receiving mismatched data; and if + * declare no cache snooping on a cache snooping supported platform + * will cause cache be flushed twice and performance hit. + * + * @dev: ishtp device pointer + * + * Return: false - has cache snooping capability + * true - no cache snooping, need manually cache flush + */ +static bool _dma_no_cache_snooping(struct ishtp_device *dev) +{ + return dev->pdev->device == EHL_Ax_DEVICE_ID; +} + static const struct ishtp_hw_ops ish_hw_ops = { .hw_reset = _ish_hw_reset, .ipc_reset = _ish_ipc_reset, @@ -897,7 +920,8 @@ static const struct ishtp_hw_ops ish_hw_ops = { .write = write_ipc_to_queue, .get_fw_status = _ish_read_fw_sts_reg, .sync_fw_clock = _ish_sync_fw_clock, - .ishtp_read_hdr = _ishtp_read_hdr + .ishtp_read_hdr = _ishtp_read_hdr, + .dma_no_cache_snooping = _dma_no_cache_snooping }; /** -- cgit v1.2.3 From a3af901c89685acb590b49ce054ea7e3015a770a Mon Sep 17 00:00:00 2001 From: Hyeonggon Yoo <42.hyeyoo@gmail.com> Date: Sat, 29 May 2021 19:03:57 +0900 Subject: HID: usbkbd: Avoid GFP_ATOMIC when GFP_KERNEL is possible usb_kbd_alloc_mem is called in usb_kbd_probe, which is not in atomic context. So constraints can be relaxed here. Use GFP_KERNEL instead of GFP_ATOMIC. Signed-off-by: Hyeonggon Yoo <42.hyeyoo@gmail.com> Signed-off-by: Jiri Kosina --- drivers/hid/usbhid/usbkbd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/hid') diff --git a/drivers/hid/usbhid/usbkbd.c b/drivers/hid/usbhid/usbkbd.c index e22434dfc9ef..df02002066ce 100644 --- a/drivers/hid/usbhid/usbkbd.c +++ b/drivers/hid/usbhid/usbkbd.c @@ -239,11 +239,11 @@ static int usb_kbd_alloc_mem(struct usb_device *dev, struct usb_kbd *kbd) return -1; if (!(kbd->led = usb_alloc_urb(0, GFP_KERNEL))) return -1; - if (!(kbd->new = usb_alloc_coherent(dev, 8, GFP_ATOMIC, &kbd->new_dma))) + if (!(kbd->new = usb_alloc_coherent(dev, 8, GFP_KERNEL, &kbd->new_dma))) return -1; if (!(kbd->cr = kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL))) return -1; - if (!(kbd->leds = usb_alloc_coherent(dev, 1, GFP_ATOMIC, &kbd->leds_dma))) + if (!(kbd->leds = usb_alloc_coherent(dev, 1, GFP_KERNEL, &kbd->leds_dma))) return -1; return 0; -- cgit v1.2.3 From fb1a79a6b6e1223ddb18f12aa35e36f832da2290 Mon Sep 17 00:00:00 2001 From: Pascal Giard Date: Fri, 4 Jun 2021 12:10:23 -0400 Subject: HID: sony: fix freeze when inserting ghlive ps3/wii dongles This commit fixes a freeze on insertion of a Guitar Hero Live PS3/WiiU USB dongle. Indeed, with the current implementation, inserting one of those USB dongles will lead to a hard freeze. I apologize for not catching this earlier, it didn't occur on my old laptop. While the issue was isolated to memory alloc/free, I could not figure out why it causes a freeze. So this patch fixes this issue by simplifying memory allocation and usage. We remind that for the dongle to work properly, a control URB needs to be sent periodically. We used to alloc/free the URB each time this URB needed to be sent. With this patch, the memory for the URB is allocated on the probe, reused for as long as the dongle is plugged in, and freed once the dongle is unplugged. Signed-off-by: Pascal Giard Signed-off-by: Jiri Kosina --- drivers/hid/hid-sony.c | 98 +++++++++++++++++++++++++------------------------- 1 file changed, 49 insertions(+), 49 deletions(-) (limited to 'drivers/hid') diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c index 8319b0ce385a..b3722c51ec78 100644 --- a/drivers/hid/hid-sony.c +++ b/drivers/hid/hid-sony.c @@ -597,9 +597,8 @@ struct sony_sc { /* DS4 calibration data */ struct ds4_calibration_data ds4_calib_data[6]; /* GH Live */ + struct urb *ghl_urb; struct timer_list ghl_poke_timer; - struct usb_ctrlrequest *ghl_cr; - u8 *ghl_databuf; }; static void sony_set_leds(struct sony_sc *sc); @@ -625,66 +624,54 @@ static inline void sony_schedule_work(struct sony_sc *sc, static void ghl_magic_poke_cb(struct urb *urb) { - if (urb) { - /* Free sc->ghl_cr and sc->ghl_databuf allocated in - * ghl_magic_poke() - */ - kfree(urb->setup_packet); - kfree(urb->transfer_buffer); - } + struct sony_sc *sc = urb->context; + + if (urb->status < 0) + hid_err(sc->hdev, "URB transfer failed : %d", urb->status); + + mod_timer(&sc->ghl_poke_timer, jiffies + GHL_GUITAR_POKE_INTERVAL*HZ); } static void ghl_magic_poke(struct timer_list *t) { + int ret; struct sony_sc *sc = from_timer(sc, t, ghl_poke_timer); - int ret; + ret = usb_submit_urb(sc->ghl_urb, GFP_ATOMIC); + if (ret < 0) + hid_err(sc->hdev, "usb_submit_urb failed: %d", ret); +} + +static int ghl_init_urb(struct sony_sc *sc, struct usb_device *usbdev) +{ + struct usb_ctrlrequest *cr; + u16 poke_size; + u8 *databuf; unsigned int pipe; - struct urb *urb; - struct usb_device *usbdev = to_usb_device(sc->hdev->dev.parent->parent); - const u16 poke_size = - ARRAY_SIZE(ghl_ps3wiiu_magic_data); + poke_size = ARRAY_SIZE(ghl_ps3wiiu_magic_data); pipe = usb_sndctrlpipe(usbdev, 0); - if (!sc->ghl_cr) { - sc->ghl_cr = kzalloc(sizeof(*sc->ghl_cr), GFP_ATOMIC); - if (!sc->ghl_cr) - goto resched; - } - - if (!sc->ghl_databuf) { - sc->ghl_databuf = kzalloc(poke_size, GFP_ATOMIC); - if (!sc->ghl_databuf) - goto resched; - } + cr = devm_kzalloc(&sc->hdev->dev, sizeof(*cr), GFP_ATOMIC); + if (cr == NULL) + return -ENOMEM; - urb = usb_alloc_urb(0, GFP_ATOMIC); - if (!urb) - goto resched; + databuf = devm_kzalloc(&sc->hdev->dev, poke_size, GFP_ATOMIC); + if (databuf == NULL) + return -ENOMEM; - sc->ghl_cr->bRequestType = + cr->bRequestType = USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT; - sc->ghl_cr->bRequest = USB_REQ_SET_CONFIGURATION; - sc->ghl_cr->wValue = cpu_to_le16(ghl_ps3wiiu_magic_value); - sc->ghl_cr->wIndex = 0; - sc->ghl_cr->wLength = cpu_to_le16(poke_size); - memcpy(sc->ghl_databuf, ghl_ps3wiiu_magic_data, poke_size); - + cr->bRequest = USB_REQ_SET_CONFIGURATION; + cr->wValue = cpu_to_le16(ghl_ps3wiiu_magic_value); + cr->wIndex = 0; + cr->wLength = cpu_to_le16(poke_size); + memcpy(databuf, ghl_ps3wiiu_magic_data, poke_size); usb_fill_control_urb( - urb, usbdev, pipe, - (unsigned char *) sc->ghl_cr, sc->ghl_databuf, - poke_size, ghl_magic_poke_cb, NULL); - ret = usb_submit_urb(urb, GFP_ATOMIC); - if (ret < 0) { - kfree(sc->ghl_databuf); - kfree(sc->ghl_cr); - } - usb_free_urb(urb); - -resched: - /* Reschedule for next time */ - mod_timer(&sc->ghl_poke_timer, jiffies + GHL_GUITAR_POKE_INTERVAL*HZ); + sc->ghl_urb, usbdev, pipe, + (unsigned char *) cr, databuf, poke_size, + ghl_magic_poke_cb, sc); + return 0; } static int guitar_mapping(struct hid_device *hdev, struct hid_input *hi, @@ -2981,6 +2968,7 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id) int ret; unsigned long quirks = id->driver_data; struct sony_sc *sc; + struct usb_device *usbdev; unsigned int connect_mask = HID_CONNECT_DEFAULT; if (!strcmp(hdev->name, "FutureMax Dance Mat")) @@ -3000,6 +2988,7 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id) sc->quirks = quirks; hid_set_drvdata(hdev, sc); sc->hdev = hdev; + usbdev = to_usb_device(sc->hdev->dev.parent->parent); ret = hid_parse(hdev); if (ret) { @@ -3042,6 +3031,15 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id) } if (sc->quirks & GHL_GUITAR_PS3WIIU) { + sc->ghl_urb = usb_alloc_urb(0, GFP_ATOMIC); + if (!sc->ghl_urb) + return -ENOMEM; + ret = ghl_init_urb(sc, usbdev); + if (ret) { + hid_err(hdev, "error preparing URB\n"); + return ret; + } + timer_setup(&sc->ghl_poke_timer, ghl_magic_poke, 0); mod_timer(&sc->ghl_poke_timer, jiffies + GHL_GUITAR_POKE_INTERVAL*HZ); @@ -3054,8 +3052,10 @@ static void sony_remove(struct hid_device *hdev) { struct sony_sc *sc = hid_get_drvdata(hdev); - if (sc->quirks & GHL_GUITAR_PS3WIIU) + if (sc->quirks & GHL_GUITAR_PS3WIIU) { del_timer_sync(&sc->ghl_poke_timer); + usb_free_urb(sc->ghl_urb); + } hid_hw_close(hdev); -- cgit v1.2.3 From 2b2bcc76e2ffbaff7e6ec1c62cb9c10881dc70cd Mon Sep 17 00:00:00 2001 From: Maximilian Luz Date: Tue, 8 Jun 2021 15:29:51 +0200 Subject: HID: surface-hid: Fix get-report request Getting a report (e.g. feature report) from a device requires us to send a request indicating which report we want to retrieve and then waiting for the corresponding response containing that report. We already provide the response structure to the request call, but the request isn't marked as a request that expects a response. Thus the request returns before we receive the response and the response buffer indicates a zero length response due to that. This essentially means that the get-report calls are broken and will always indicate that a report of length zero has been read. Fix this by appropriately marking the request. Fixes: b05ff1002a5c ("HID: Add support for Surface Aggregator Module HID transport") Signed-off-by: Maximilian Luz Signed-off-by: Jiri Kosina --- drivers/hid/surface-hid/surface_hid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/hid') diff --git a/drivers/hid/surface-hid/surface_hid.c b/drivers/hid/surface-hid/surface_hid.c index 3477b31611ae..a3a70e4f3f6c 100644 --- a/drivers/hid/surface-hid/surface_hid.c +++ b/drivers/hid/surface-hid/surface_hid.c @@ -143,7 +143,7 @@ static int ssam_hid_get_raw_report(struct surface_hid_device *shid, u8 rprt_id, rqst.target_id = shid->uid.target; rqst.instance_id = shid->uid.instance; rqst.command_id = SURFACE_HID_CID_GET_FEATURE_REPORT; - rqst.flags = 0; + rqst.flags = SSAM_REQUEST_HAS_RESPONSE; rqst.length = sizeof(rprt_id); rqst.payload = &rprt_id; -- cgit v1.2.3 From f264481ad614dfd9aae59eeefa5fc664cdf173ae Mon Sep 17 00:00:00 2001 From: Basavaraj Natikar Date: Fri, 18 Jun 2021 13:48:36 +0530 Subject: HID: amd_sfh: Extend driver capabilities for multi-generation support Initial driver support only covered the first generation of SFH platforms. In order to support the future generations introduce ops selection to distinguish the different platforms. Signed-off-by: Basavaraj Natikar Reviewed-by: Nehal Shah Reviewed-by: Shyam Sundar S K Signed-off-by: Jiri Kosina --- drivers/hid/amd-sfh-hid/amd_sfh_client.c | 4 +- drivers/hid/amd-sfh-hid/amd_sfh_pcie.c | 80 ++++++++++++++++++++++++++++++-- drivers/hid/amd-sfh-hid/amd_sfh_pcie.h | 27 +++++++++++ 3 files changed, 105 insertions(+), 6 deletions(-) (limited to 'drivers/hid') diff --git a/drivers/hid/amd-sfh-hid/amd_sfh_client.c b/drivers/hid/amd-sfh-hid/amd_sfh_client.c index 3589d9945da1..d3d5dcec7cf1 100644 --- a/drivers/hid/amd-sfh-hid/amd_sfh_client.c +++ b/drivers/hid/amd-sfh-hid/amd_sfh_client.c @@ -202,7 +202,7 @@ 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; @@ -230,7 +230,7 @@ int amd_sfh_hid_client_deinit(struct amd_mp2_dev *privdata) 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); diff --git a/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c b/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c index ddecc84fd6f0..48ff54dc5d70 100644 --- a/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c +++ b/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c @@ -30,6 +30,48 @@ 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 +140,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 +150,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) @@ -130,8 +170,38 @@ int amd_mp2_get_sensor_num(struct amd_mp2_dev *privdata, u8 *sensor_id) 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) @@ -164,6 +234,8 @@ static int amd_mp2_pci_probe(struct pci_dev *pdev, const struct pci_device_id *i 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..6297d78c7aef 100644 --- a/drivers/hid/amd-sfh-hid/amd_sfh_pcie.h +++ b/drivers/hid/amd-sfh-hid/amd_sfh_pcie.h @@ -22,9 +22,13 @@ #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 + /* SFH Command register */ union sfh_cmd_base { u32 ul; @@ -33,6 +37,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 +74,9 @@ struct amd_mp2_dev { struct pci_dev *pdev; struct amdtp_cl_data *cl_data; void __iomem *mmio; + const struct amd_mp2_ops *mp2_ops; + /* mp2 active control status */ + u32 mp2_acs; }; struct amd_mp2_sensor_info { @@ -69,10 +85,21 @@ struct amd_mp2_sensor_info { dma_addr_t dma_address; }; +enum mem_use_type { + USE_DRAM, + USE_C2P_REG, +}; + 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 -- cgit v1.2.3 From 0aad9c95eb9a2b086322e28ae2e58ad25598604e Mon Sep 17 00:00:00 2001 From: Basavaraj Natikar Date: Fri, 18 Jun 2021 13:48:37 +0530 Subject: HID: amd_sfh: Extend ALS support for newer AMD platform Extend ALS support for AMD next generation SoC's like Renoir, Cezanne. AMD next generation platforms use C2P message register to read ALS sensor data instead of DRAM address. Signed-off-by: Basavaraj Natikar Reviewed-by: Nehal Shah Reviewed-by: Shyam Sundar S K Signed-off-by: Jiri Kosina --- drivers/hid/amd-sfh-hid/amd_sfh_client.c | 39 ++++++++++------------ drivers/hid/amd-sfh-hid/amd_sfh_hid.h | 10 ++++-- drivers/hid/amd-sfh-hid/amd_sfh_pcie.c | 5 +++ drivers/hid/amd-sfh-hid/amd_sfh_pcie.h | 2 ++ .../amd-sfh-hid/hid_descriptor/amd_sfh_hid_desc.c | 14 ++++++-- .../amd-sfh-hid/hid_descriptor/amd_sfh_hid_desc.h | 1 - 6 files changed, 45 insertions(+), 26 deletions(-) (limited to 'drivers/hid') diff --git a/drivers/hid/amd-sfh-hid/amd_sfh_client.c b/drivers/hid/amd-sfh-hid/amd_sfh_client.c index d3d5dcec7cf1..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; } @@ -205,28 +203,27 @@ int amd_sfh_hid_client_init(struct amd_mp2_dev *privdata) 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++) @@ -237,9 +234,9 @@ int amd_sfh_hid_client_deinit(struct amd_mp2_dev *privdata) 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..359c5de96af8 100644 --- a/drivers/hid/amd-sfh-hid/amd_sfh_hid.h +++ b/drivers/hid/amd-sfh-hid/amd_sfh_hid.h @@ -14,6 +14,11 @@ #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 48ff54dc5d70..ff131f450bdc 100644 --- a/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c +++ b/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c @@ -230,6 +230,11 @@ 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; diff --git a/drivers/hid/amd-sfh-hid/amd_sfh_pcie.h b/drivers/hid/amd-sfh-hid/amd_sfh_pcie.h index 6297d78c7aef..0886b2ad033e 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 +#include "amd_sfh_hid.h" #define PCI_DEVICE_ID_AMD_MP2 0x15E4 @@ -75,6 +76,7 @@ struct amd_mp2_dev { 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; }; 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..cdc0a8d32249 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 @@ -174,8 +175,12 @@ 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 accel3_input_report acc_input; struct gyro_input_report gyro_input; struct magno_input_report magno_input; @@ -213,7 +218,12 @@ 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; 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..a23c1046627f 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 @@ -103,5 +103,4 @@ struct als_input_report { 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 -- cgit v1.2.3 From 24a31ea94922d391a96a9dd0a9a830de65423817 Mon Sep 17 00:00:00 2001 From: Basavaraj Natikar Date: Fri, 18 Jun 2021 13:48:38 +0530 Subject: HID: amd_sfh: Add initial support for HPD sensor Add Human Presence Detection (HPD) sensors support on AMD next generation HPD supported platforms. Signed-off-by: Basavaraj Natikar Reviewed-by: Nehal Shah Reviewed-by: Shyam Sundar S K Signed-off-by: Jiri Kosina --- drivers/hid/amd-sfh-hid/amd_sfh_hid.h | 2 +- drivers/hid/amd-sfh-hid/amd_sfh_pcie.c | 4 + drivers/hid/amd-sfh-hid/amd_sfh_pcie.h | 14 +++ .../amd-sfh-hid/hid_descriptor/amd_sfh_hid_desc.c | 34 ++++++- .../amd-sfh-hid/hid_descriptor/amd_sfh_hid_desc.h | 10 ++ .../hid_descriptor/amd_sfh_hid_report_desc.h | 112 +++++++++++++++++++++ 6 files changed, 174 insertions(+), 2 deletions(-) (limited to 'drivers/hid') diff --git a/drivers/hid/amd-sfh-hid/amd_sfh_hid.h b/drivers/hid/amd-sfh-hid/amd_sfh_hid.h index 359c5de96af8..ae2ac9191ba7 100644 --- a/drivers/hid/amd-sfh-hid/amd_sfh_hid.h +++ b/drivers/hid/amd-sfh-hid/amd_sfh_hid.h @@ -9,7 +9,7 @@ #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 diff --git a/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c b/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c index ff131f450bdc..96e2577fa37e 100644 --- a/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c +++ b/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c @@ -24,6 +24,7 @@ #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; @@ -165,6 +166,9 @@ 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; } diff --git a/drivers/hid/amd-sfh-hid/amd_sfh_pcie.h b/drivers/hid/amd-sfh-hid/amd_sfh_pcie.h index 0886b2ad033e..2d5c57e3782d 100644 --- a/drivers/hid/amd-sfh-hid/amd_sfh_pcie.h +++ b/drivers/hid/amd-sfh-hid/amd_sfh_pcie.h @@ -30,6 +30,8 @@ #define V2_STATUS 0x2 +#define HPD_IDX 16 + /* SFH Command register */ union sfh_cmd_base { u32 ul; @@ -92,6 +94,18 @@ enum mem_use_type { 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); 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 cdc0a8d32249..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 @@ -50,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; } @@ -99,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; } @@ -120,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; @@ -162,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; } @@ -181,10 +204,12 @@ u8 get_input_report(u8 current_index, int sensor_idx, int report_id, struct amd_ 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) @@ -227,6 +252,13 @@ u8 get_input_report(u8 current_index, int sensor_idx, int report_id, struct amd_ 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 a23c1046627f..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,6 +100,16 @@ 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); 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 -- cgit v1.2.3 From 424d8237945c6c448c8b3f23885d464fb5685c97 Mon Sep 17 00:00:00 2001 From: Jason Gerecke Date: Wed, 23 Jun 2021 09:58:09 -0700 Subject: HID: wacom: Correct base usage for capacitive ExpressKey status bits The capacitive status of ExpressKeys is reported with usages beginning at 0x940, not 0x950. Bring our driver into alignment with reality. Signed-off-by: Jason Gerecke Signed-off-by: Jiri Kosina --- drivers/hid/wacom_wac.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/hid') diff --git a/drivers/hid/wacom_wac.h b/drivers/hid/wacom_wac.h index 71c886245dbf..8f16654eca09 100644 --- a/drivers/hid/wacom_wac.h +++ b/drivers/hid/wacom_wac.h @@ -122,7 +122,7 @@ #define WACOM_HID_WD_TOUCHONOFF (WACOM_HID_UP_WACOMDIGITIZER | 0x0454) #define WACOM_HID_WD_BATTERY_LEVEL (WACOM_HID_UP_WACOMDIGITIZER | 0x043b) #define WACOM_HID_WD_EXPRESSKEY00 (WACOM_HID_UP_WACOMDIGITIZER | 0x0910) -#define WACOM_HID_WD_EXPRESSKEYCAP00 (WACOM_HID_UP_WACOMDIGITIZER | 0x0950) +#define WACOM_HID_WD_EXPRESSKEYCAP00 (WACOM_HID_UP_WACOMDIGITIZER | 0x0940) #define WACOM_HID_WD_MODE_CHANGE (WACOM_HID_UP_WACOMDIGITIZER | 0x0980) #define WACOM_HID_WD_MUTE_DEVICE (WACOM_HID_UP_WACOMDIGITIZER | 0x0981) #define WACOM_HID_WD_CONTROLPANEL (WACOM_HID_UP_WACOMDIGITIZER | 0x0982) -- cgit v1.2.3 From bcfa8d14570d85c998a9b706b074ab151b286edf Mon Sep 17 00:00:00 2001 From: Thomas Weißschuh Date: Tue, 15 Jun 2021 23:41:03 +0200 Subject: HID: input: Add support for Programmable Buttons MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Map them to KEY_MACRO# event codes. These buttons are defined by HID as follows: "The user defines the function of these buttons to control software applications or GUI objects." This matches the semantics of the KEY_MACRO# input event codes that Linux supports. Also add support for HID "Named Array" collections. Also add hid-debug support for KEY_MACRO#. Signed-off-by: Thomas Weißschuh Signed-off-by: Jiri Kosina --- drivers/hid/hid-debug.c | 11 +++++++++++ drivers/hid/hid-input.c | 22 ++++++++++++++++++++++ include/linux/hid.h | 1 + 3 files changed, 34 insertions(+) (limited to 'drivers/hid') diff --git a/drivers/hid/hid-debug.c b/drivers/hid/hid-debug.c index 59f8d716d78f..0e76d9b4530a 100644 --- a/drivers/hid/hid-debug.c +++ b/drivers/hid/hid-debug.c @@ -122,6 +122,7 @@ static const struct hid_usage_entry hid_usage_table[] = { { 9, 0, "Button" }, { 10, 0, "Ordinal" }, { 12, 0, "Consumer" }, + {0, 0x003, "ProgrammableButtons"}, {0, 0x238, "HorizontalWheel"}, { 13, 0, "Digitizers" }, {0, 0x01, "Digitizer"}, @@ -939,6 +940,16 @@ static const char *keys[KEY_MAX + 1] = { [KEY_KBDINPUTASSIST_NEXTGROUP] = "KbdInputAssistNextGroup", [KEY_KBDINPUTASSIST_ACCEPT] = "KbdInputAssistAccept", [KEY_KBDINPUTASSIST_CANCEL] = "KbdInputAssistCancel", + [KEY_MACRO1] = "Macro1", [KEY_MACRO2] = "Macro2", [KEY_MACRO3] = "Macro3", + [KEY_MACRO4] = "Macro4", [KEY_MACRO5] = "Macro5", [KEY_MACRO6] = "Macro6", + [KEY_MACRO7] = "Macro7", [KEY_MACRO8] = "Macro8", [KEY_MACRO9] = "Macro9", + [KEY_MACRO10] = "Macro10", [KEY_MACRO11] = "Macro11", [KEY_MACRO12] = "Macro12", + [KEY_MACRO13] = "Macro13", [KEY_MACRO14] = "Macro14", [KEY_MACRO15] = "Macro15", + [KEY_MACRO16] = "Macro16", [KEY_MACRO17] = "Macro17", [KEY_MACRO18] = "Macro18", + [KEY_MACRO19] = "Macro19", [KEY_MACRO20] = "Macro20", [KEY_MACRO21] = "Macro21", + [KEY_MACRO22] = "Macro22", [KEY_MACRO23] = "Macro23", [KEY_MACRO24] = "Macro24", + [KEY_MACRO25] = "Macro25", [KEY_MACRO26] = "Macro26", [KEY_MACRO27] = "Macro27", + [KEY_MACRO28] = "Macro28", [KEY_MACRO29] = "Macro29", [KEY_MACRO30] = "Macro30", }; static const char *relatives[REL_MAX + 1] = { diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index c62c6a9b2132..56bdd55fbfb3 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c @@ -567,6 +567,16 @@ static void hidinput_update_battery(struct hid_device *dev, int value) } #endif /* CONFIG_HID_BATTERY_STRENGTH */ +static bool hidinput_field_in_collection(struct hid_device *device, struct hid_field *field, + unsigned int type, unsigned int usage) +{ + struct hid_collection *collection; + + collection = &device->collection[field->usage->collection_index]; + + return collection->type == type && collection->usage == usage; +} + static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_field *field, struct hid_usage *usage) { @@ -632,6 +642,18 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel else code += BTN_TRIGGER_HAPPY - 0x10; break; + case HID_CP_CONSUMER_CONTROL: + if (hidinput_field_in_collection(device, field, + HID_COLLECTION_NAMED_ARRAY, + HID_CP_PROGRAMMABLEBUTTONS)) { + if (code <= 0x1d) + code += KEY_MACRO1; + else + code += BTN_TRIGGER_HAPPY - 0x1e; + } else { + goto ignore; + } + break; default: switch (field->physical) { case HID_GD_MOUSE: diff --git a/include/linux/hid.h b/include/linux/hid.h index 271021e20a3f..fb0e4dde6175 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -102,6 +102,7 @@ struct hid_item { #define HID_COLLECTION_PHYSICAL 0 #define HID_COLLECTION_APPLICATION 1 #define HID_COLLECTION_LOGICAL 2 +#define HID_COLLECTION_NAMED_ARRAY 4 /* * HID report descriptor global item tags -- cgit v1.2.3 From 978e786c5e9bf538da0a4807539608a52d9be16b Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sat, 29 May 2021 17:14:22 +0200 Subject: HID: usbhid: Implement may_wakeup ll-driver callback Without a ll-driver callback hid_hw_may_wakeup() will return: device_may_wakeup(hdev->dev.parent), usb_hid_driver instantiated hid devices have their parent set to the usb-interface to which the usb_hid_driver is bound, but the power/wakeup* sysfs attributes are part of the usb-device. Add a may_wakeup ll-driver callback which calls device_may_wakeup() on the usb-device instead. Signed-off-by: Hans de Goede Reviewed-by: Benjamin Tissoires Signed-off-by: Jiri Kosina --- drivers/hid/usbhid/hid-core.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers/hid') diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c index 4e9077363c96..06130dc431a0 100644 --- a/drivers/hid/usbhid/hid-core.c +++ b/drivers/hid/usbhid/hid-core.c @@ -1304,6 +1304,13 @@ static int usbhid_idle(struct hid_device *hid, int report, int idle, return hid_set_idle(dev, ifnum, report, idle); } +static bool usbhid_may_wakeup(struct hid_device *hid) +{ + struct usb_device *dev = hid_to_usb_dev(hid); + + return device_may_wakeup(&dev->dev); +} + struct hid_ll_driver usb_hid_driver = { .parse = usbhid_parse, .start = usbhid_start, @@ -1316,6 +1323,7 @@ struct hid_ll_driver usb_hid_driver = { .raw_request = usbhid_raw_request, .output_report = usbhid_output_report, .idle = usbhid_idle, + .may_wakeup = usbhid_may_wakeup, }; EXPORT_SYMBOL_GPL(usb_hid_driver); -- cgit v1.2.3 From 622d97cf7f2b4efb36bec3c85b5c1db5e3dfd586 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sat, 29 May 2021 17:14:23 +0200 Subject: HID: logitech-dj: Implement may_wakeup ll-driver callback Without a ll-driver callback hid_hw_may_wakeup() will return: device_may_wakeup(hdev->dev.parent), but for the hid devices instantiated by logitech-dj for devices behind the receiver the logitech-dj hid(pp)-device is the parent. Add a logi_dj_ll_may_wakeup() callback which calls hid_hw_may_wakeup() on the logitech-dj hid(pp) parent-hid-device. Signed-off-by: Hans de Goede Reviewed-by: Benjamin Tissoires Signed-off-by: Jiri Kosina --- drivers/hid/hid-logitech-dj.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers/hid') diff --git a/drivers/hid/hid-logitech-dj.c b/drivers/hid/hid-logitech-dj.c index fa835d565982..f96349faa5f4 100644 --- a/drivers/hid/hid-logitech-dj.c +++ b/drivers/hid/hid-logitech-dj.c @@ -1489,6 +1489,13 @@ static void logi_dj_ll_stop(struct hid_device *hid) dbg_hid("%s\n", __func__); } +static bool logi_dj_ll_may_wakeup(struct hid_device *hid) +{ + struct dj_device *djdev = hid->driver_data; + struct dj_receiver_dev *djrcv_dev = djdev->dj_receiver_dev; + + return hid_hw_may_wakeup(djrcv_dev->hidpp); +} static struct hid_ll_driver logi_dj_ll_driver = { .parse = logi_dj_ll_parse, @@ -1497,6 +1504,7 @@ static struct hid_ll_driver logi_dj_ll_driver = { .open = logi_dj_ll_open, .close = logi_dj_ll_close, .raw_request = logi_dj_ll_raw_request, + .may_wakeup = logi_dj_ll_may_wakeup, }; static int logi_dj_dj_event(struct hid_device *hdev, -- cgit v1.2.3 From 498d0ddc6ae931e4e79a57c56b6dd4576aa435b6 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sat, 29 May 2021 17:14:24 +0200 Subject: HID: multitouch: Disable event reporting on suspend when the device is not a wakeup-source Disable event reporting on suspend when the hid device is not a wakeup-source. This should help save some extra power in this case. Signed-off-by: Hans de Goede Reviewed-by: Benjamin Tissoires Signed-off-by: Jiri Kosina --- drivers/hid/hid-multitouch.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/hid') diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index 2e4fb76c45f3..3ea7cb1cda84 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -1768,7 +1768,8 @@ static int mt_suspend(struct hid_device *hdev, pm_message_t state) struct mt_device *td = hid_get_drvdata(hdev); /* High latency is desirable for power savings during S3/S0ix */ - if (td->mtclass.quirks & MT_QUIRK_DISABLE_WAKEUP) + if ((td->mtclass.quirks & MT_QUIRK_DISABLE_WAKEUP) || + !hid_hw_may_wakeup(hdev)) mt_set_modes(hdev, HID_LATENCY_HIGH, false, false); else mt_set_modes(hdev, HID_LATENCY_HIGH, true, true); -- cgit v1.2.3 From 3b770932eefb7c0c6319d332023efee87eb12913 Mon Sep 17 00:00:00 2001 From: Yang Yingliang Date: Tue, 11 May 2021 19:30:33 +0800 Subject: HID: thrustmaster: Switch to kmemdup() when allocate change_request Use kmemdup() helper instead of open-coding to simplify the code when allocate change_request. Signed-off-by: Yang Yingliang Signed-off-by: Jiri Kosina --- drivers/hid/hid-thrustmaster.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers/hid') diff --git a/drivers/hid/hid-thrustmaster.c b/drivers/hid/hid-thrustmaster.c index f643b1cb112d..cdc7d82ae9ed 100644 --- a/drivers/hid/hid-thrustmaster.c +++ b/drivers/hid/hid-thrustmaster.c @@ -311,12 +311,13 @@ static int thrustmaster_probe(struct hid_device *hdev, const struct hid_device_i goto error4; } - tm_wheel->change_request = kzalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL); + tm_wheel->change_request = kmemdup(&change_request, + sizeof(struct usb_ctrlrequest), + GFP_KERNEL); if (!tm_wheel->change_request) { ret = -ENOMEM; goto error5; } - memcpy(tm_wheel->change_request, &change_request, sizeof(struct usb_ctrlrequest)); tm_wheel->usb_dev = interface_to_usbdev(to_usb_interface(hdev->dev.parent)); hid_set_drvdata(hdev, tm_wheel); -- cgit v1.2.3