drivers: usb: nordic: implement remote wakeup
Adds remote wakeup support for nRF chips. Signed-off-by: Paweł Zadrożniak <pawel.zadrozniak@nordicsemi.no>
This commit is contained in:
parent
3ecbff501a
commit
804b9e1ada
2 changed files with 62 additions and 25 deletions
|
@ -63,6 +63,7 @@ menuconfig USB_NRF52840
|
||||||
select USB_DEVICE_DRIVER
|
select USB_DEVICE_DRIVER
|
||||||
select HAS_DTS_USB
|
select HAS_DTS_USB
|
||||||
select NRFX_USBD
|
select NRFX_USBD
|
||||||
|
select USB_DEVICE_REMOTE_WAKEUP
|
||||||
help
|
help
|
||||||
nRF52840 USB Device Controller Driver
|
nRF52840 USB Device Controller Driver
|
||||||
|
|
||||||
|
|
|
@ -57,6 +57,7 @@ enum usbd_periph_state {
|
||||||
USBD_ATTACHED,
|
USBD_ATTACHED,
|
||||||
USBD_POWERED,
|
USBD_POWERED,
|
||||||
USBD_SUSPENDED,
|
USBD_SUSPENDED,
|
||||||
|
USBD_RESUMED,
|
||||||
USBD_DEFAULT,
|
USBD_DEFAULT,
|
||||||
USBD_ADDRESS_SET,
|
USBD_ADDRESS_SET,
|
||||||
USBD_CONFIGURED,
|
USBD_CONFIGURED,
|
||||||
|
@ -749,6 +750,9 @@ static inline void usbd_work_process_pwr_events(struct usbd_pwr_event *pwr_evt)
|
||||||
nrfx_usbd_enable();
|
nrfx_usbd_enable();
|
||||||
(void) hf_clock_enable(true, false);
|
(void) hf_clock_enable(true, false);
|
||||||
|
|
||||||
|
if (ctx->status_cb) {
|
||||||
|
ctx->status_cb(USB_DC_CONNECTED, NULL);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case USBD_POWERED:
|
case USBD_POWERED:
|
||||||
|
@ -773,6 +777,22 @@ static inline void usbd_work_process_pwr_events(struct usbd_pwr_event *pwr_evt)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case USBD_SUSPENDED:
|
||||||
|
LOG_DBG("USB Suspend state");
|
||||||
|
nrfx_usbd_suspend();
|
||||||
|
|
||||||
|
if (ctx->status_cb) {
|
||||||
|
ctx->status_cb(USB_DC_SUSPEND, NULL);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case USBD_RESUMED:
|
||||||
|
LOG_DBG("USB resume");
|
||||||
|
|
||||||
|
if (ctx->status_cb) {
|
||||||
|
ctx->status_cb(USB_DC_RESUME, NULL);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1094,37 +1114,34 @@ static void usbd_event_transfer_data(nrfx_usbd_evt_t const *const p_event)
|
||||||
static void usbd_event_handler(nrfx_usbd_evt_t const *const p_event)
|
static void usbd_event_handler(nrfx_usbd_evt_t const *const p_event)
|
||||||
{
|
{
|
||||||
struct nrf_usbd_ep_ctx *ep_ctx;
|
struct nrf_usbd_ep_ctx *ep_ctx;
|
||||||
struct usbd_event *ev;
|
struct usbd_event evt;
|
||||||
|
bool put_evt = false;
|
||||||
|
|
||||||
switch (p_event->type) {
|
switch (p_event->type) {
|
||||||
case NRFX_USBD_EVT_SUSPEND:
|
case NRFX_USBD_EVT_SUSPEND:
|
||||||
LOG_DBG("SUSPEND state detected.");
|
LOG_DBG("SUSPEND state detected.");
|
||||||
|
evt.evt_type = USBD_EVT_POWER;
|
||||||
|
evt.evt.pwr_evt.state = USBD_SUSPENDED;
|
||||||
|
put_evt = true;
|
||||||
break;
|
break;
|
||||||
case NRFX_USBD_EVT_RESUME:
|
case NRFX_USBD_EVT_RESUME:
|
||||||
LOG_DBG("RESUMING from suspend.");
|
LOG_DBG("RESUMING from suspend.");
|
||||||
|
evt.evt_type = USBD_EVT_POWER;
|
||||||
|
evt.evt.pwr_evt.state = USBD_RESUMED;
|
||||||
|
put_evt = true;
|
||||||
break;
|
break;
|
||||||
case NRFX_USBD_EVT_WUREQ:
|
case NRFX_USBD_EVT_WUREQ:
|
||||||
LOG_DBG("RemoteWU initiated.");
|
LOG_DBG("RemoteWU initiated.");
|
||||||
break;
|
break;
|
||||||
case NRFX_USBD_EVT_RESET:
|
case NRFX_USBD_EVT_RESET:
|
||||||
ev = usbd_evt_alloc();
|
evt.evt_type = USBD_EVT_RESET;
|
||||||
if (!ev) {
|
put_evt = true;
|
||||||
return;
|
|
||||||
}
|
|
||||||
ev->evt_type = USBD_EVT_RESET;
|
|
||||||
usbd_evt_put(ev);
|
|
||||||
usbd_work_schedule();
|
|
||||||
break;
|
break;
|
||||||
case NRFX_USBD_EVT_SOF:
|
case NRFX_USBD_EVT_SOF:
|
||||||
#ifdef CONFIG_USB_DEVICE_SOF
|
if (IS_ENABLED(CONFIG_USB_DEVICE_SOF)) {
|
||||||
ev = usbd_evt_alloc();
|
evt.evt_type = USBD_EVT_SOF;
|
||||||
if (!ev) {
|
put_evt = true;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
ev->evt_type = USBD_EVT_SOF;
|
|
||||||
usbd_evt_put(ev);
|
|
||||||
usbd_work_schedule();
|
|
||||||
#endif
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NRFX_USBD_EVT_EPTRANSFER:
|
case NRFX_USBD_EVT_EPTRANSFER:
|
||||||
|
@ -1158,15 +1175,11 @@ static void usbd_event_handler(nrfx_usbd_evt_t const *const p_event)
|
||||||
|
|
||||||
struct nrf_usbd_ep_ctx *ep_ctx =
|
struct nrf_usbd_ep_ctx *ep_ctx =
|
||||||
endpoint_ctx(NRF_USBD_EPOUT(0));
|
endpoint_ctx(NRF_USBD_EPOUT(0));
|
||||||
ev = usbd_evt_alloc();
|
|
||||||
if (!ev) {
|
evt.evt_type = USBD_EVT_EP;
|
||||||
return;
|
evt.evt.ep_evt.ep = ep_ctx;
|
||||||
}
|
evt.evt.ep_evt.evt_type = EP_EVT_SETUP_RECV;
|
||||||
ev->evt_type = USBD_EVT_EP;
|
put_evt = true;
|
||||||
ev->evt.ep_evt.ep = ep_ctx;
|
|
||||||
ev->evt.ep_evt.evt_type = EP_EVT_SETUP_RECV;
|
|
||||||
usbd_evt_put(ev);
|
|
||||||
usbd_work_schedule();
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1174,6 +1187,19 @@ static void usbd_event_handler(nrfx_usbd_evt_t const *const p_event)
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (put_evt) {
|
||||||
|
struct usbd_event *ev;
|
||||||
|
|
||||||
|
ev = usbd_evt_alloc();
|
||||||
|
if (!ev) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ev->evt_type = evt.evt_type;
|
||||||
|
ev->evt = evt.evt;
|
||||||
|
usbd_evt_put(ev);
|
||||||
|
usbd_work_schedule();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void usbd_reinit(void)
|
static inline void usbd_reinit(void)
|
||||||
|
@ -1796,3 +1822,13 @@ int usb_dc_ep_mps(const u8_t ep)
|
||||||
|
|
||||||
return ep_ctx->cfg.max_sz;
|
return ep_ctx->cfg.max_sz;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int usb_dc_wakeup_request(void)
|
||||||
|
{
|
||||||
|
bool res = nrfx_usbd_wakeup_req();
|
||||||
|
|
||||||
|
if (!res) {
|
||||||
|
return -EAGAIN;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue