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 <emil.obalski@nordicsemi.no>
This commit is contained in:
Emil Obalski 2020-08-17 15:17:14 +02:00 committed by Carles Cufí
commit 0d8bd579a5
5 changed files with 43 additions and 30 deletions

View file

@ -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
******

View file

@ -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;

View file

@ -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);
}

View file

@ -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");

View file

@ -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