drivers: usb: device: nrf: Adapt to control clock using onoff
Change to use onoff service when controlling HFXO. Signed-off-by: Krzysztof Chruscinski <krzysztof.chruscinski@nordicsemi.no>
This commit is contained in:
parent
2b4763076e
commit
9e546fdf7e
1 changed files with 28 additions and 53 deletions
|
@ -242,6 +242,9 @@ K_MEM_POOL_DEFINE(ep_buf_pool, EP_BUF_POOL_BLOCK_MIN_SZ,
|
||||||
* @brief USBD control structure
|
* @brief USBD control structure
|
||||||
*
|
*
|
||||||
* @param status_cb Status callback for USB DC notifications
|
* @param status_cb Status callback for USB DC notifications
|
||||||
|
* @param hfxo_cli Onoff client used to control HFXO
|
||||||
|
* @param hfxo_mgr Pointer to onoff manager associated with HFXO.
|
||||||
|
* @param clk_requested Flag used to protect against double stop.
|
||||||
* @param attached USBD Attached flag
|
* @param attached USBD Attached flag
|
||||||
* @param ready USBD Ready flag set after pullup
|
* @param ready USBD Ready flag set after pullup
|
||||||
* @param usb_work USBD work item
|
* @param usb_work USBD work item
|
||||||
|
@ -251,6 +254,9 @@ K_MEM_POOL_DEFINE(ep_buf_pool, EP_BUF_POOL_BLOCK_MIN_SZ,
|
||||||
*/
|
*/
|
||||||
struct nrf_usbd_ctx {
|
struct nrf_usbd_ctx {
|
||||||
usb_dc_status_callback status_cb;
|
usb_dc_status_callback status_cb;
|
||||||
|
struct onoff_client hfxo_cli;
|
||||||
|
struct onoff_manager *hfxo_mgr;
|
||||||
|
atomic_t clk_requested;
|
||||||
|
|
||||||
bool attached;
|
bool attached;
|
||||||
bool ready;
|
bool ready;
|
||||||
|
@ -523,62 +529,26 @@ void usb_dc_nrfx_power_event_callback(nrf_power_event_t event)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/* Stopping HFXO, algorithm supports case when stop comes before clock is
|
||||||
* @brief Enable/Disable the HF clock
|
* started. In that case, it is stopped from the callback context.
|
||||||
*
|
|
||||||
* Toggle the HF clock. It needs to be enabled for USBD data exchange
|
|
||||||
*
|
|
||||||
* @param on Set true to enable the HF clock, false to disable.
|
|
||||||
* @param blocking Set true to block wait till HF clock stabilizes.
|
|
||||||
*
|
|
||||||
* @return 0 on success, error number otherwise
|
|
||||||
*/
|
*/
|
||||||
static int hf_clock_enable(bool on, bool blocking)
|
static int hfxo_stop(struct nrf_usbd_ctx *ctx)
|
||||||
{
|
{
|
||||||
int ret = -ENODEV;
|
if (atomic_cas(&ctx->clk_requested, 1, 0)) {
|
||||||
struct device *clock;
|
return onoff_cancel_or_release(ctx->hfxo_mgr, &ctx->hfxo_cli);
|
||||||
static bool clock_requested;
|
|
||||||
|
|
||||||
clock = device_get_binding(DT_LABEL(DT_INST(0, nordic_nrf_clock)));
|
|
||||||
if (!clock) {
|
|
||||||
LOG_ERR("NRF HF Clock device not found!");
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (on) {
|
return 0;
|
||||||
if (clock_requested) {
|
}
|
||||||
/* Do not request HFCLK multiple times. */
|
|
||||||
return 0;
|
static int hfxo_start(struct nrf_usbd_ctx *ctx)
|
||||||
}
|
{
|
||||||
ret = clock_control_on(clock, CLOCK_CONTROL_NRF_SUBSYS_HF);
|
if (atomic_cas(&ctx->clk_requested, 0, 1)) {
|
||||||
while (blocking &&
|
sys_notify_init_spinwait(&ctx->hfxo_cli.notify);
|
||||||
clock_control_get_status(clock,
|
|
||||||
CLOCK_CONTROL_NRF_SUBSYS_HF) !=
|
return onoff_request(ctx->hfxo_mgr, &ctx->hfxo_cli);
|
||||||
CLOCK_CONTROL_STATUS_ON) {
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (!clock_requested) {
|
|
||||||
/* Cancel the operation if clock has not
|
|
||||||
* been requested by this driver before.
|
|
||||||
*/
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
ret = clock_control_off(clock, CLOCK_CONTROL_NRF_SUBSYS_HF);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret && (blocking || (ret != -EINPROGRESS))) {
|
|
||||||
LOG_ERR("HF clock %s fail: %d",
|
|
||||||
on ? "start" : "stop", ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
clock_requested = on;
|
|
||||||
LOG_DBG("HF clock %s success (%d)", on ? "start" : "stop", ret);
|
|
||||||
|
|
||||||
/* NOTE: Non-blocking HF clock enable can return -EINPROGRESS
|
|
||||||
* if HF clock start was already requested. Such error code
|
|
||||||
* does not need to be propagated, hence returned value is 0.
|
|
||||||
*/
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -766,13 +736,15 @@ static void eps_ctx_uninit(void)
|
||||||
static inline void usbd_work_process_pwr_events(struct usbd_pwr_event *pwr_evt)
|
static inline void usbd_work_process_pwr_events(struct usbd_pwr_event *pwr_evt)
|
||||||
{
|
{
|
||||||
struct nrf_usbd_ctx *ctx = get_usbd_ctx();
|
struct nrf_usbd_ctx *ctx = get_usbd_ctx();
|
||||||
|
int err;
|
||||||
|
|
||||||
switch (pwr_evt->state) {
|
switch (pwr_evt->state) {
|
||||||
case USBD_ATTACHED:
|
case USBD_ATTACHED:
|
||||||
if (!nrfx_usbd_is_enabled()) {
|
if (!nrfx_usbd_is_enabled()) {
|
||||||
LOG_DBG("USB detected");
|
LOG_DBG("USB detected");
|
||||||
nrfx_usbd_enable();
|
nrfx_usbd_enable();
|
||||||
(void) hf_clock_enable(true, false);
|
err = hfxo_start(ctx);
|
||||||
|
__ASSERT_NO_MSG(err >= 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* No callback here.
|
/* No callback here.
|
||||||
|
@ -795,7 +767,8 @@ static inline void usbd_work_process_pwr_events(struct usbd_pwr_event *pwr_evt)
|
||||||
case USBD_DETACHED:
|
case USBD_DETACHED:
|
||||||
ctx->ready = false;
|
ctx->ready = false;
|
||||||
nrfx_usbd_disable();
|
nrfx_usbd_disable();
|
||||||
(void) hf_clock_enable(false, false);
|
err = hfxo_stop(ctx);
|
||||||
|
__ASSERT_NO_MSG(err >= 0);
|
||||||
|
|
||||||
LOG_DBG("USB Removed");
|
LOG_DBG("USB Removed");
|
||||||
|
|
||||||
|
@ -1363,6 +1336,8 @@ int usb_dc_attach(void)
|
||||||
|
|
||||||
k_work_init(&ctx->usb_work, usbd_work_handler);
|
k_work_init(&ctx->usb_work, usbd_work_handler);
|
||||||
k_mutex_init(&ctx->drv_lock);
|
k_mutex_init(&ctx->drv_lock);
|
||||||
|
ctx->hfxo_mgr =
|
||||||
|
z_nrf_clock_control_get_onoff(CLOCK_CONTROL_NRF_SUBSYS_HF);
|
||||||
|
|
||||||
IRQ_CONNECT(DT_INST_IRQN(0), DT_INST_IRQ(0, priority),
|
IRQ_CONNECT(DT_INST_IRQN(0), DT_INST_IRQ(0, priority),
|
||||||
nrfx_isr, nrfx_usbd_irq_handler, 0);
|
nrfx_isr, nrfx_usbd_irq_handler, 0);
|
||||||
|
@ -1415,7 +1390,7 @@ int usb_dc_detach(void)
|
||||||
nrfx_usbd_uninit();
|
nrfx_usbd_uninit();
|
||||||
}
|
}
|
||||||
|
|
||||||
(void) hf_clock_enable(false, false);
|
(void)hfxo_stop(ctx);
|
||||||
nrf5_power_usb_power_int_enable(false);
|
nrf5_power_usb_power_int_enable(false);
|
||||||
|
|
||||||
ctx->attached = false;
|
ctx->attached = false;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue