18
18
#include <zephyr/usb/usb_device.h>
19
19
#include <zephyr/usb/usb_ch9.h>
20
20
#include <zephyr/usb/class/usb_hid.h>
21
+ #include <zephyr/usb/class/usbd_hid.h>
21
22
22
23
#define MODULE usb_state
23
24
#include <caf/events/module_state_event.h>
@@ -58,6 +59,7 @@ struct usb_hid_device {
58
59
uint32_t report_bm ;
59
60
uint8_t hid_protocol ;
60
61
uint8_t sent_report_id ;
62
+ uint32_t idle_duration [REPORT_ID_COUNT ];
61
63
bool report_enabled [REPORT_ID_COUNT ];
62
64
bool enabled ;
63
65
};
@@ -70,7 +72,16 @@ BUILD_ASSERT(IS_ENABLED(CONFIG_DESKTOP_USB_STACK_NEXT) ||
70
72
"Unsupported USB stack" );
71
73
72
74
#if CONFIG_DESKTOP_USB_STACK_NEXT
73
- static struct usb_hid_device usb_hid_device [0 ];
75
+ #define USB_NEXT_USB_HID_DEVICE_INIT (node_id ) \
76
+ { \
77
+ .dev = DEVICE_DT_GET(node_id), \
78
+ .hid_protocol = HID_PROTOCOL_REPORT, \
79
+ .sent_report_id = REPORT_ID_COUNT, \
80
+ },
81
+
82
+ static struct usb_hid_device usb_hid_device [] = {
83
+ DT_FOREACH_STATUS_OKAY (zephyr_hid_device , USB_NEXT_USB_HID_DEVICE_INIT )
84
+ };
74
85
#else
75
86
static struct usb_hid_device usb_hid_device [CONFIG_USB_HID_DEVICE_COUNT ];
76
87
#endif
@@ -220,11 +231,6 @@ static void report_sent(const struct device *dev, bool error)
220
231
usb_hid -> sent_report_id = REPORT_ID_COUNT ;
221
232
}
222
233
223
- static void report_sent_cb (const struct device * dev )
224
- {
225
- report_sent (dev , false);
226
- }
227
-
228
234
static void send_hid_report (const struct hid_report_event * event )
229
235
{
230
236
struct usb_hid_device * usb_hid = NULL ;
@@ -288,7 +294,15 @@ static void send_hid_report(const struct hid_report_event *event)
288
294
int err = 0 ;
289
295
290
296
if (IS_ENABLED (CONFIG_DESKTOP_USB_STACK_NEXT )) {
291
- LOG_WRN ("send_hid_report not integrated for USB next" );
297
+ /* USB next stack expects buffer alignment. */
298
+ if (IS_ALIGNED (report_buffer , sizeof (void * ))) {
299
+ err = hid_device_submit_report (usb_hid -> dev , report_size , report_buffer );
300
+ } else {
301
+ uint8_t temp [report_size ] __aligned (sizeof (void * ));
302
+
303
+ memcpy (temp , report_buffer , report_size );
304
+ err = hid_device_submit_report (usb_hid -> dev , report_size , temp );
305
+ }
292
306
} else {
293
307
__ASSERT_NO_MSG (IS_ENABLED (CONFIG_DESKTOP_USB_STACK_LEGACY ));
294
308
err = hid_int_ep_write (usb_hid -> dev , report_buffer , report_size , NULL );
@@ -300,11 +314,11 @@ static void send_hid_report(const struct hid_report_event *event)
300
314
}
301
315
}
302
316
303
- static void broadcast_usb_state (void )
317
+ static void broadcast_usb_state (enum usb_state broadcast_state )
304
318
{
305
319
struct usb_state_event * event = new_usb_state_event ();
306
320
307
- event -> state = state ;
321
+ event -> state = broadcast_state ;
308
322
309
323
APP_EVENT_SUBMIT (event );
310
324
}
@@ -633,14 +647,19 @@ static int set_report_legacy(const struct device *dev, struct usb_setup_packet *
633
647
return err ;
634
648
}
635
649
650
+ static void report_sent_cb_legacy (const struct device * dev )
651
+ {
652
+ report_sent (dev , false);
653
+ }
654
+
636
655
static int usb_init_legacy_hid_device_init (struct usb_hid_device * usb_hid_dev ,
637
656
const struct device * dev ,
638
657
uint32_t report_bm )
639
658
{
640
659
static const struct hid_ops hid_ops = {
641
660
.get_report = get_report_legacy ,
642
661
.set_report = set_report_legacy ,
643
- .int_in_ready = report_sent_cb ,
662
+ .int_in_ready = report_sent_cb_legacy ,
644
663
.protocol_change = protocol_change ,
645
664
};
646
665
@@ -754,7 +773,7 @@ static void usb_init_legacy_status_cb(enum usb_dc_status_code cb_status, const u
754
773
755
774
/* Update state. */
756
775
state = new_state ;
757
- broadcast_usb_state ();
776
+ broadcast_usb_state (state );
758
777
759
778
/* HID subscribe when entering active state. */
760
779
if (state == USB_STATE_ACTIVE ) {
@@ -811,6 +830,121 @@ static int usb_init_legacy(void)
811
830
return 0 ;
812
831
}
813
832
833
+ static bool is_usb_active_next (void )
834
+ {
835
+ bool usb_active = false;
836
+
837
+ for (size_t i = 0 ; i < ARRAY_SIZE (usb_hid_device ); i ++ ) {
838
+ if (usb_hid_device [i ].enabled ) {
839
+ usb_active = true;
840
+ break ;
841
+ }
842
+ }
843
+
844
+ return usb_active ;
845
+ }
846
+
847
+ static void iface_ready_next (const struct device * dev , const bool ready )
848
+ {
849
+ struct usb_hid_device * usb_hid = dev_to_hid (dev );
850
+ bool was_usb_active = is_usb_active_next ();
851
+
852
+ update_usb_hid (usb_hid , ready );
853
+
854
+ bool is_usb_active = is_usb_active_next ();
855
+
856
+ if (state == USB_STATE_SUSPENDED ) {
857
+ /* USB state update is delayed if USB is suspended. */
858
+ return ;
859
+ }
860
+
861
+ if (!was_usb_active && is_usb_active ) {
862
+ broadcast_usb_state (USB_STATE_ACTIVE );
863
+ } else if (was_usb_active && !is_usb_active ) {
864
+ broadcast_usb_state (state );
865
+ }
866
+ }
867
+
868
+ static int get_report_next (const struct device * dev , const uint8_t type , const uint8_t id ,
869
+ const uint16_t len , uint8_t * const buf )
870
+ {
871
+ /* Omit the first byte - HID report ID. */
872
+ return get_report (dev , type , id , buf + 1 , len - 1 );
873
+ }
874
+
875
+ static int set_report_next (const struct device * dev , const uint8_t type , const uint8_t id ,
876
+ const uint16_t len , const uint8_t * const buf )
877
+ {
878
+ /* Omit the first byte - HID report ID. */
879
+ return set_report (dev , type , id , buf + 1 , len - 1 );
880
+ }
881
+
882
+ static void set_idle_next (const struct device * dev , const uint8_t id , const uint32_t duration )
883
+ {
884
+ struct usb_hid_device * usb_hid = dev_to_hid (dev );
885
+
886
+ usb_hid -> idle_duration [id ] = duration ;
887
+ }
888
+
889
+ static uint32_t get_idle_next (const struct device * dev , const uint8_t id )
890
+ {
891
+ struct usb_hid_device * usb_hid = dev_to_hid (dev );
892
+
893
+ return usb_hid -> idle_duration [id ];
894
+ }
895
+
896
+ static void report_sent_cb_next (const struct device * dev )
897
+ {
898
+ struct usb_hid_device * usb_hid = dev_to_hid (dev );
899
+
900
+ /* USB next stack does not explicitly indicate failed transfers. */
901
+ if (usb_hid -> enabled ) {
902
+ report_sent (dev , false);
903
+ } else {
904
+ report_sent (dev , true);
905
+ }
906
+ }
907
+
908
+ static int usb_init_next_hid_device_init (struct usb_hid_device * usb_hid_dev , uint32_t report_bm )
909
+ {
910
+ static const struct hid_device_ops hid_ops = {
911
+ .iface_ready = iface_ready_next ,
912
+ .get_report = get_report_next ,
913
+ .set_report = set_report_next ,
914
+ .set_idle = set_idle_next ,
915
+ .get_idle = get_idle_next ,
916
+ .set_protocol = protocol_change ,
917
+ .input_report_done = report_sent_cb_next ,
918
+ };
919
+
920
+ usb_hid_dev -> report_bm = report_bm ;
921
+
922
+ int err = hid_device_register (usb_hid_dev -> dev , hid_report_desc , hid_report_desc_size ,
923
+ & hid_ops );
924
+
925
+ if (err ) {
926
+ LOG_ERR ("hid_device_register failed for %p (err: %d)" ,
927
+ (void * )usb_hid_dev -> dev , err );
928
+ }
929
+
930
+ return err ;
931
+ }
932
+
933
+ static int usb_init_next_hids_init (void )
934
+ {
935
+ int err = 0 ;
936
+
937
+ for (size_t i = 0 ; i < ARRAY_SIZE (usb_hid_device ); i ++ ) {
938
+ err = usb_init_next_hid_device_init (& usb_hid_device [i ], get_report_bm (i ));
939
+ if (err ) {
940
+ LOG_ERR ("usb_init_next_hid_device_init failed (err: %d)" , err );
941
+ break ;
942
+ }
943
+ }
944
+
945
+ return err ;
946
+ }
947
+
814
948
static void usb_init_next_status_cb (struct usbd_contex * const contex ,
815
949
const struct usbd_msg * const msg )
816
950
{
@@ -871,7 +1005,11 @@ static void usb_init_next_status_cb(struct usbd_contex *const contex,
871
1005
}
872
1006
873
1007
if (new_state != state ) {
874
- broadcast_usb_state (new_state );
1008
+ if ((state == USB_STATE_SUSPENDED ) && is_usb_active_next ()) {
1009
+ broadcast_usb_state (USB_STATE_ACTIVE );
1010
+ } else {
1011
+ broadcast_usb_state (new_state );
1012
+ }
875
1013
state = new_state ;
876
1014
}
877
1015
}
@@ -1016,15 +1154,21 @@ static struct usbd_contex *usb_init_next_usbd_init(void)
1016
1154
1017
1155
static int usb_init_next (void )
1018
1156
{
1157
+ int err = usb_init_next_hids_init ();
1158
+
1159
+ if (err ) {
1160
+ LOG_ERR ("usb_init_next_hids_init failed (err: %d)" , err );
1161
+ return err ;
1162
+ }
1163
+
1019
1164
struct usbd_contex * usbd = usb_init_next_usbd_init ();
1020
1165
1021
1166
if (!usbd ) {
1022
1167
LOG_ERR ("usb_init_next_usbd_init failed" );
1023
1168
return - ENXIO ;
1024
1169
}
1025
1170
1026
- int err = usbd_msg_register_cb (usbd , usb_init_next_status_cb );
1027
-
1171
+ err = usbd_msg_register_cb (usbd , usb_init_next_status_cb );
1028
1172
if (err ) {
1029
1173
LOG_ERR ("usbd_msg_register_cb failed (err: %d)" , err );
1030
1174
return err ;
0 commit comments