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,122 @@ 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
+ buf [0 ] = id ;
873
+ return get_report (dev , type , id , buf + 1 , len - 1 );
874
+ }
875
+
876
+ static int set_report_next (const struct device * dev , const uint8_t type , const uint8_t id ,
877
+ const uint16_t len , const uint8_t * const buf )
878
+ {
879
+ /* Omit the first byte - HID report ID. */
880
+ return set_report (dev , type , id , buf + 1 , len - 1 );
881
+ }
882
+
883
+ static void set_idle_next (const struct device * dev , const uint8_t id , const uint32_t duration )
884
+ {
885
+ struct usb_hid_device * usb_hid = dev_to_hid (dev );
886
+
887
+ usb_hid -> idle_duration [id ] = duration ;
888
+ }
889
+
890
+ static uint32_t get_idle_next (const struct device * dev , const uint8_t id )
891
+ {
892
+ struct usb_hid_device * usb_hid = dev_to_hid (dev );
893
+
894
+ return usb_hid -> idle_duration [id ];
895
+ }
896
+
897
+ static void report_sent_cb_next (const struct device * dev )
898
+ {
899
+ struct usb_hid_device * usb_hid = dev_to_hid (dev );
900
+
901
+ /* USB next stack does not explicitly indicate failed transfers. */
902
+ if (usb_hid -> enabled ) {
903
+ report_sent (dev , false);
904
+ } else {
905
+ report_sent (dev , true);
906
+ }
907
+ }
908
+
909
+ static int usb_init_next_hid_device_init (struct usb_hid_device * usb_hid_dev , uint32_t report_bm )
910
+ {
911
+ static const struct hid_device_ops hid_ops = {
912
+ .iface_ready = iface_ready_next ,
913
+ .get_report = get_report_next ,
914
+ .set_report = set_report_next ,
915
+ .set_idle = set_idle_next ,
916
+ .get_idle = get_idle_next ,
917
+ .set_protocol = protocol_change ,
918
+ .input_report_done = report_sent_cb_next ,
919
+ };
920
+
921
+ usb_hid_dev -> report_bm = report_bm ;
922
+
923
+ int err = hid_device_register (usb_hid_dev -> dev , hid_report_desc , hid_report_desc_size ,
924
+ & hid_ops );
925
+
926
+ if (err ) {
927
+ LOG_ERR ("hid_device_register failed for %p (err: %d)" ,
928
+ (void * )usb_hid_dev -> dev , err );
929
+ }
930
+
931
+ return err ;
932
+ }
933
+
934
+ static int usb_init_next_hids_init (void )
935
+ {
936
+ int err = 0 ;
937
+
938
+ for (size_t i = 0 ; i < ARRAY_SIZE (usb_hid_device ); i ++ ) {
939
+ err = usb_init_next_hid_device_init (& usb_hid_device [i ], get_report_bm (i ));
940
+ if (err ) {
941
+ LOG_ERR ("usb_init_next_hid_device_init failed (err: %d)" , err );
942
+ break ;
943
+ }
944
+ }
945
+
946
+ return err ;
947
+ }
948
+
814
949
static void usb_init_next_status_cb (struct usbd_contex * const contex ,
815
950
const struct usbd_msg * const msg )
816
951
{
@@ -871,7 +1006,11 @@ static void usb_init_next_status_cb(struct usbd_contex *const contex,
871
1006
}
872
1007
873
1008
if (new_state != state ) {
874
- broadcast_usb_state (new_state );
1009
+ if ((state == USB_STATE_SUSPENDED ) && is_usb_active_next ()) {
1010
+ broadcast_usb_state (USB_STATE_ACTIVE );
1011
+ } else {
1012
+ broadcast_usb_state (new_state );
1013
+ }
875
1014
state = new_state ;
876
1015
}
877
1016
}
@@ -1016,15 +1155,21 @@ static struct usbd_contex *usb_init_next_usbd_init(void)
1016
1155
1017
1156
static int usb_init_next (void )
1018
1157
{
1158
+ int err = usb_init_next_hids_init ();
1159
+
1160
+ if (err ) {
1161
+ LOG_ERR ("usb_init_next_hids_init failed (err: %d)" , err );
1162
+ return err ;
1163
+ }
1164
+
1019
1165
struct usbd_contex * usbd = usb_init_next_usbd_init ();
1020
1166
1021
1167
if (!usbd ) {
1022
1168
LOG_ERR ("usb_init_next_usbd_init failed" );
1023
1169
return - ENXIO ;
1024
1170
}
1025
1171
1026
- int err = usbd_msg_register_cb (usbd , usb_init_next_status_cb );
1027
-
1172
+ err = usbd_msg_register_cb (usbd , usb_init_next_status_cb );
1028
1173
if (err ) {
1029
1174
LOG_ERR ("usbd_msg_register_cb failed (err: %d)" , err );
1030
1175
return err ;
0 commit comments