17
17
#include <zephyr/kernel.h>
18
18
#include <zephyr/sys/mem_blocks.h>
19
19
#include <zephyr/drivers/usb/udc.h>
20
+ #include <zephyr/drivers/pinctrl.h>
20
21
#include <zephyr/drivers/clock_control.h>
21
22
22
23
#include <zephyr/logging/log.h>
@@ -33,6 +34,7 @@ struct rpi_pico_config {
33
34
void (* irq_enable_func )(const struct device * dev );
34
35
void (* irq_disable_func )(const struct device * dev );
35
36
const struct device * clk_dev ;
37
+ struct pinctrl_dev_config * const pcfg ;
36
38
clock_control_subsys_t clk_sys ;
37
39
};
38
40
@@ -105,6 +107,19 @@ static void ALWAYS_INLINE rpi_pico_bit_clr(const mm_reg_t reg, const uint32_t bi
105
107
sys_write32 (bit , REG_ALIAS_CLR_BITS | reg );
106
108
}
107
109
110
+
111
+ static void sie_dp_pullup (const struct device * dev , const bool enable )
112
+ {
113
+ const struct rpi_pico_config * config = dev -> config ;
114
+ usb_hw_t * base = config -> base ;
115
+
116
+ if (enable ) {
117
+ rpi_pico_bit_set ((mm_reg_t )& base -> sie_ctrl , USB_SIE_CTRL_PULLUP_EN_BITS );
118
+ } else {
119
+ rpi_pico_bit_clr ((mm_reg_t )& base -> sie_ctrl , USB_SIE_CTRL_PULLUP_EN_BITS );
120
+ }
121
+ }
122
+
108
123
static void ALWAYS_INLINE sie_status_clr (const struct device * dev , const uint32_t bit )
109
124
{
110
125
const struct rpi_pico_config * config = dev -> config ;
@@ -639,6 +654,7 @@ static void rpi_pico_handle_buff_status(const struct device *dev)
639
654
static void rpi_pico_isr_handler (const struct device * dev )
640
655
{
641
656
const struct rpi_pico_config * config = dev -> config ;
657
+ const struct pinctrl_dev_config * const pcfg = config -> pcfg ;
642
658
struct rpi_pico_data * priv = udc_get_private (dev );
643
659
usb_hw_t * base = config -> base ;
644
660
uint32_t status = base -> ints ;
@@ -652,15 +668,35 @@ static void rpi_pico_isr_handler(const struct device *dev)
652
668
if (status & USB_INTS_DEV_CONN_DIS_BITS ) {
653
669
uint32_t sie_status ;
654
670
671
+ sie_status = sys_read32 ((mm_reg_t )& base -> sie_status );
672
+ LOG_DBG ("CONNECTED bit %u, VBUS_DETECTED bit %u" ,
673
+ (bool )(sie_status & USB_SIE_STATUS_CONNECTED_BITS ),
674
+ (bool )(sie_status & USB_SIE_STATUS_VBUS_DETECTED_BITS ));
675
+
676
+ if (pcfg != NULL && !(sie_status & USB_SIE_STATUS_CONNECTED_BITS ) &&
677
+ !(sie_status & USB_SIE_STATUS_VBUS_DETECTED_BITS )) {
678
+ sie_dp_pullup (dev , false);
679
+ udc_submit_event (dev , UDC_EVT_VBUS_REMOVED , 0 );
680
+ }
681
+
655
682
handled |= USB_INTS_DEV_CONN_DIS_BITS ;
656
683
sie_status_clr (dev , USB_SIE_STATUS_CONNECTED_BITS );
684
+ }
685
+
686
+ if (status & USB_INTS_VBUS_DETECT_BITS ) {
687
+ uint32_t sie_status ;
657
688
658
689
sie_status = sys_read32 ((mm_reg_t )& base -> sie_status );
659
- if (sie_status & USB_SIE_STATUS_CONNECTED_BITS ) {
690
+ LOG_DBG ("VBUS_DETECTED bit %u" ,
691
+ (bool )(sie_status & USB_SIE_STATUS_VBUS_DETECTED_BITS ));
692
+
693
+ if (pcfg != NULL && (sie_status & USB_SIE_STATUS_VBUS_DETECTED_BITS )) {
694
+ sie_dp_pullup (dev , true);
660
695
udc_submit_event (dev , UDC_EVT_VBUS_READY , 0 );
661
- } else {
662
- udc_submit_event (dev , UDC_EVT_VBUS_REMOVED , 0 );
663
696
}
697
+
698
+ handled |= USB_INTS_VBUS_DETECT_BITS ;
699
+ sie_status_clr (dev , USB_SIE_STATUS_VBUS_DETECTED_BITS );
664
700
}
665
701
666
702
if ((status & (USB_INTS_BUFF_STATUS_BITS | USB_INTS_SETUP_REQ_BITS )) &&
@@ -943,6 +979,7 @@ static int udc_rpi_pico_host_wakeup(const struct device *dev)
943
979
static int udc_rpi_pico_enable (const struct device * dev )
944
980
{
945
981
const struct rpi_pico_config * config = dev -> config ;
982
+ const struct pinctrl_dev_config * const pcfg = config -> pcfg ;
946
983
usb_device_dpram_t * dpram = config -> dpram ;
947
984
usb_hw_t * base = config -> base ;
948
985
@@ -958,9 +995,11 @@ static int udc_rpi_pico_enable(const struct device *dev)
958
995
sys_write32 (USB_USB_MUXING_TO_PHY_BITS | USB_USB_MUXING_SOFTCON_BITS ,
959
996
(mm_reg_t )& base -> muxing );
960
997
961
- /* Force VBUS detect so the device thinks it is plugged into a host */
962
- sys_write32 (USB_USB_PWR_VBUS_DETECT_BITS | USB_USB_PWR_VBUS_DETECT_OVERRIDE_EN_BITS ,
963
- (mm_reg_t )& base -> pwr );
998
+ if (pcfg == NULL ) {
999
+ /* Force VBUS detect so the device thinks it is plugged into a host */
1000
+ sys_write32 (USB_USB_PWR_VBUS_DETECT_BITS |
1001
+ USB_USB_PWR_VBUS_DETECT_OVERRIDE_EN_BITS , (mm_reg_t )& base -> pwr );
1002
+ }
964
1003
965
1004
/* Enable an interrupt per EP0 transaction */
966
1005
sys_write32 (USB_SIE_CTRL_EP0_INT_1BUF_BITS , (mm_reg_t )& base -> sie_ctrl );
@@ -981,8 +1020,10 @@ static int udc_rpi_pico_enable(const struct device *dev)
981
1020
USB_INTE_BUFF_STATUS_BITS ,
982
1021
(mm_reg_t )& base -> inte );
983
1022
984
- /* Present full speed device by enabling pull up on DP */
985
- rpi_pico_bit_set ((mm_reg_t )& base -> sie_ctrl , USB_SIE_CTRL_PULLUP_EN_BITS );
1023
+ if (sys_read32 ((mm_reg_t )& base -> sie_status ) & USB_SIE_STATUS_VBUS_DETECTED_BITS ) {
1024
+ /* Present full speed device by enabling pull up on DP */
1025
+ sie_dp_pullup (dev , true);
1026
+ }
986
1027
987
1028
/* Enable the USB controller in device mode. */
988
1029
sys_write32 (USB_MAIN_CTRL_CONTROLLER_EN_BITS , (mm_reg_t )& base -> main_ctrl );
@@ -1007,6 +1048,8 @@ static int udc_rpi_pico_disable(const struct device *dev)
1007
1048
static int udc_rpi_pico_init (const struct device * dev )
1008
1049
{
1009
1050
const struct rpi_pico_config * config = dev -> config ;
1051
+ const struct pinctrl_dev_config * const pcfg = config -> pcfg ;
1052
+ int err ;
1010
1053
1011
1054
if (udc_ep_enable_internal (dev , USB_CONTROL_EP_OUT ,
1012
1055
USB_EP_TYPE_CONTROL , 64 , 0 )) {
@@ -1020,6 +1063,14 @@ static int udc_rpi_pico_init(const struct device *dev)
1020
1063
return - EIO ;
1021
1064
}
1022
1065
1066
+ if (pcfg != NULL ) {
1067
+ err = pinctrl_apply_state (pcfg , PINCTRL_STATE_DEFAULT );
1068
+ if (err ) {
1069
+ LOG_ERR ("Failed to apply default pinctrl state (%d)" , err );
1070
+ return err ;
1071
+ }
1072
+ }
1073
+
1023
1074
return clock_control_on (config -> clk_dev , config -> clk_sys );
1024
1075
}
1025
1076
@@ -1132,7 +1183,16 @@ static const struct udc_api udc_rpi_pico_api = {
1132
1183
1133
1184
#define DT_DRV_COMPAT raspberrypi_pico_usbd
1134
1185
1186
+ #define UDC_RPI_PICO_PINCTRL_DT_INST_DEFINE (n ) \
1187
+ COND_CODE_1(DT_INST_PINCTRL_HAS_NAME(n, default), \
1188
+ (PINCTRL_DT_INST_DEFINE(n)), ())
1189
+
1190
+ #define UDC_RPI_PICO_PINCTRL_DT_INST_DEV_CONFIG_GET (n ) \
1191
+ COND_CODE_1(DT_INST_PINCTRL_HAS_NAME(n, default), \
1192
+ ((void *)PINCTRL_DT_INST_DEV_CONFIG_GET(n)), (NULL))
1193
+
1135
1194
#define UDC_RPI_PICO_DEVICE_DEFINE (n ) \
1195
+ UDC_RPI_PICO_PINCTRL_DT_INST_DEFINE(n); \
1136
1196
K_THREAD_STACK_DEFINE(udc_rpi_pico_stack_##n, CONFIG_UDC_RPI_PICO_STACK_SIZE); \
1137
1197
\
1138
1198
SYS_MEM_BLOCKS_DEFINE_STATIC_WITH_EXT_BUF(rpi_pico_mb_##n, \
@@ -1190,6 +1250,7 @@ static const struct udc_api udc_rpi_pico_api = {
1190
1250
.make_thread = udc_rpi_pico_make_thread_##n, \
1191
1251
.irq_enable_func = udc_rpi_pico_irq_enable_func_##n, \
1192
1252
.irq_disable_func = udc_rpi_pico_irq_disable_func_##n, \
1253
+ .pcfg = UDC_RPI_PICO_PINCTRL_DT_INST_DEV_CONFIG_GET(n), \
1193
1254
.clk_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(n)), \
1194
1255
.clk_sys = (void *)DT_INST_PHA_BY_IDX(n, clocks, 0, clk_id), \
1195
1256
}; \
0 commit comments