From 0d8bd579a5a3ca819641fb840de97e76b5647ed0 Mon Sep 17 00:00:00 2001 From: Emil Obalski Date: Mon, 17 Aug 2020 15:17:14 +0200 Subject: [PATCH] usb: hid: All hid_ops callbacks get device pointer. This commit extends USB hid API callbacks by adding 'const struct device *dev' parameter. If the application configured more than one HID device then it must specify separate hid_ops for each device as its unable to determine for which device the callback was called. This patch makes it possible to have only one hid_ops within the application and the application is aware for which device the callback was called because of explicit device pointer. Signed-off-by: Emil Obalski --- doc/releases/release-notes-2.4.rst | 4 +++ include/usb/class/usb_hid.h | 9 +++--- samples/subsys/usb/hid-cdc/src/main.c | 4 ++- samples/subsys/usb/hid/src/main.c | 12 +++++--- subsys/usb/class/hid/core.c | 44 +++++++++++++++------------ 5 files changed, 43 insertions(+), 30 deletions(-) diff --git a/doc/releases/release-notes-2.4.rst b/doc/releases/release-notes-2.4.rst index f985a662d68..125d6a8aef9 100644 --- a/doc/releases/release-notes-2.4.rst +++ b/doc/releases/release-notes-2.4.rst @@ -103,6 +103,10 @@ Removed APIs in this release Stable API changes in this release ================================== +* USB + + * HID class callbacks now takes a parameter ``const struct device*`` which + is the HID device for which callback was called. Kernel ****** diff --git a/include/usb/class/usb_hid.h b/include/usb/class/usb_hid.h index 4f2cb3bef92..be81e773ed6 100644 --- a/include/usb/class/usb_hid.h +++ b/include/usb/class/usb_hid.h @@ -57,11 +57,12 @@ struct usb_hid_descriptor { /* Public headers */ -typedef int (*hid_cb_t)(struct usb_setup_packet *setup, int32_t *len, +typedef int (*hid_cb_t)(const struct device *dev, + struct usb_setup_packet *setup, int32_t *len, uint8_t **data); -typedef void (*hid_int_ready_callback)(void); -typedef void (*hid_protocol_cb_t)(uint8_t protocol); -typedef void (*hid_idle_cb_t)(uint16_t report_id); +typedef void (*hid_int_ready_callback)(const struct device *dev); +typedef void (*hid_protocol_cb_t)(const struct device *dev, uint8_t protocol); +typedef void (*hid_idle_cb_t)(const struct device *dev, uint16_t report_id); struct hid_ops { hid_cb_t get_report; diff --git a/samples/subsys/usb/hid-cdc/src/main.c b/samples/subsys/usb/hid-cdc/src/main.c index 6723016f00c..cbef864f38d 100644 --- a/samples/subsys/usb/hid-cdc/src/main.c +++ b/samples/subsys/usb/hid-cdc/src/main.c @@ -192,8 +192,10 @@ static const char *evt_fail = "Unknown event detected!\r\n"; static const char *set_str = "String set to: "; static const char *endl = "\r\n"; -static void in_ready_cb(void) +static void in_ready_cb(const struct device *dev) { + ARG_UNUSED(dev); + k_sem_give(&usb_sem); } diff --git a/samples/subsys/usb/hid/src/main.c b/samples/subsys/usb/hid/src/main.c index e836d927231..a927d5cb585 100644 --- a/samples/subsys/usb/hid/src/main.c +++ b/samples/subsys/usb/hid/src/main.c @@ -72,8 +72,10 @@ static void send_report(struct k_work *work) report_1[1]++; } -static void in_ready_cb(void) +static void in_ready_cb(const struct device *dev) { + ARG_UNUSED(dev); + k_delayed_work_submit(&delayed_report_send, REPORT_TIMEOUT); } @@ -81,7 +83,7 @@ static void status_cb(enum usb_dc_status_code status, const uint8_t *param) { switch (status) { case USB_DC_CONFIGURED: - in_ready_cb(); + in_ready_cb(hdev); break; case USB_DC_SOF: break; @@ -91,17 +93,17 @@ static void status_cb(enum usb_dc_status_code status, const uint8_t *param) } } -static void idle_cb(uint16_t report_id) +static void idle_cb(const struct device *dev, uint16_t report_id) { static uint8_t report_1[2] = { 0x00, 0xEB }; int ret, wrote; - ret = hid_int_ep_write(hdev, report_1, sizeof(report_1), &wrote); + ret = hid_int_ep_write(dev, report_1, sizeof(report_1), &wrote); LOG_DBG("Idle callback: wrote %d bytes with ret %d", wrote, ret); } -static void protocol_cb(uint8_t protocol) +static void protocol_cb(const struct device *dev, uint8_t protocol) { LOG_DBG("New protocol: %s", protocol == HID_PROTOCOL_BOOT ? "boot" : "report"); diff --git a/subsys/usb/class/hid/core.c b/subsys/usb/class/hid/core.c index 38dc4a8f892..3ef36694049 100644 --- a/subsys/usb/class/hid/core.c +++ b/subsys/usb/class/hid/core.c @@ -255,12 +255,12 @@ static int hid_on_set_report(struct hid_device_info *dev_data, return -ENOTSUP; } -static int hid_on_set_protocol(struct hid_device_info *dev_data, - struct usb_setup_packet *setup, int32_t *len, - uint8_t **data) +static int hid_on_set_protocol(const struct device *dev, + struct hid_device_info *dev_data, + struct usb_setup_packet *setup) { #ifdef CONFIG_USB_HID_BOOT_PROTOCOL - uint16_t protocol = (uint8_t)setup->wValue; + uint16_t protocol = setup->wValue; if (protocol > HID_PROTOCOL_REPORT) { LOG_ERR("Unsupported protocol: %u", protocol); @@ -273,7 +273,7 @@ static int hid_on_set_protocol(struct hid_device_info *dev_data, dev_data->protocol = protocol; if (dev_data->ops && dev_data->ops->protocol_change) { - dev_data->ops->protocol_change(protocol); + dev_data->ops->protocol_change(dev, protocol); } } @@ -308,6 +308,8 @@ void hid_clear_idle_ctx(struct hid_device_info *dev_data) void hid_sof_handler(struct hid_device_info *dev_data) { + const struct device *dev = dev_data->common.dev; + for (uint16_t i = 0; i <= CONFIG_USB_HID_REPORTS; i++) { if (dev_data->idle_rate[i]) { dev_data->sof_cnt[i]++; @@ -319,7 +321,7 @@ void hid_sof_handler(struct hid_device_info *dev_data) if (diff < (2 + (dev_data->idle_rate[i] / 10U))) { dev_data->sof_cnt[i] = 0U; if (dev_data->ops && dev_data->ops->on_idle) { - dev_data->ops->on_idle(i); + dev_data->ops->on_idle(dev, i); } } @@ -417,6 +419,7 @@ static int hid_class_handle_req(struct usb_setup_packet *setup, { struct hid_device_info *dev_data; struct usb_dev_data *common; + const struct device *dev; LOG_DBG("Class request:" "bRequest 0x%02x, bmRequestType 0x%02x len %d", @@ -431,12 +434,13 @@ static int hid_class_handle_req(struct usb_setup_packet *setup, } dev_data = CONTAINER_OF(common, struct hid_device_info, common); + dev = common->dev; if (REQTYPE_GET_DIR(setup->bmRequestType) == REQTYPE_DIR_TO_HOST) { switch (setup->bRequest) { case HID_GET_IDLE: if (dev_data->ops && dev_data->ops->get_idle) { - return dev_data->ops->get_idle(setup, len, + return dev_data->ops->get_idle(dev, setup, len, data); } else { return hid_on_get_idle(dev_data, setup, len, @@ -445,8 +449,8 @@ static int hid_class_handle_req(struct usb_setup_packet *setup, break; case HID_GET_REPORT: if (dev_data->ops && dev_data->ops->get_report) { - return dev_data->ops->get_report(setup, len, - data); + return dev_data->ops->get_report(dev, setup, + len, data); } else { return hid_on_get_report(dev_data, setup, len, data); @@ -454,8 +458,8 @@ static int hid_class_handle_req(struct usb_setup_packet *setup, break; case HID_GET_PROTOCOL: if (dev_data->ops && dev_data->ops->get_protocol) { - return dev_data->ops->get_protocol(setup, len, - data); + return dev_data->ops->get_protocol(dev, setup, + len, data); } else { return hid_on_get_protocol(dev_data, setup, len, data); @@ -469,7 +473,7 @@ static int hid_class_handle_req(struct usb_setup_packet *setup, switch (setup->bRequest) { case HID_SET_IDLE: if (dev_data->ops && dev_data->ops->set_idle) { - return dev_data->ops->set_idle(setup, len, + return dev_data->ops->set_idle(dev, setup, len, data); } else { return hid_on_set_idle(dev_data, setup, len, @@ -478,8 +482,8 @@ static int hid_class_handle_req(struct usb_setup_packet *setup, break; case HID_SET_REPORT: if (dev_data->ops && dev_data->ops->set_report) { - return dev_data->ops->set_report(setup, len, - data); + return dev_data->ops->set_report(dev, setup, + len, data); } else { return hid_on_set_report(dev_data, setup, len, data); @@ -487,11 +491,11 @@ static int hid_class_handle_req(struct usb_setup_packet *setup, break; case HID_SET_PROTOCOL: if (dev_data->ops && dev_data->ops->set_protocol) { - return dev_data->ops->set_protocol(setup, len, - data); + return dev_data->ops->set_protocol(dev, setup, + len, data); } else { - return hid_on_set_protocol(dev_data, setup, len, - data); + return hid_on_set_protocol(dev, dev_data, + setup); } break; default: @@ -582,7 +586,7 @@ static void hid_int_in(uint8_t ep, enum usb_dc_ep_cb_status_code ep_status) return; } - dev_data->ops->int_in_ready(); + dev_data->ops->int_in_ready(common->dev); } #ifdef CONFIG_ENABLE_HID_INT_OUT_EP @@ -604,7 +608,7 @@ static void hid_int_out(uint8_t ep, enum usb_dc_ep_cb_status_code ep_status) return; } - dev_data->ops->int_out_ready(); + dev_data->ops->int_out_ready(common->dev); } #endif