/* * host / gadget functions * * renesas_usbhs host/gadget can register itself by below functions. * these functions are called when probe * */ void usbhs_mod_register(struct usbhs_priv *priv, struct usbhs_mod *mod, int id) { struct usbhs_mod_info *info = usbhs_priv_to_modinfo(priv); info->mod[id] = mod; mod->priv = priv; }
void usbhs_mod_autonomy_mode(struct usbhs_priv *priv) { struct usbhs_mod_info *info = usbhs_priv_to_modinfo(priv); info->irq_vbus = usbhsm_autonomy_irq_vbus; priv->pfunc.get_vbus = usbhsm_autonomy_get_vbus; usbhs_irq_callback_update(priv, NULL); }
int usbhs_mod_is_host(struct usbhs_priv *priv) { struct usbhs_mod *mod = usbhs_mod_get_current(priv); struct usbhs_mod_info *info = usbhs_priv_to_modinfo(priv); if (!mod) return -EINVAL; return info->mod[USBHS_HOST] == mod; }
struct usbhs_mod *usbhs_mod_get(struct usbhs_priv *priv, int id) { struct usbhs_mod_info *info = usbhs_priv_to_modinfo(priv); struct usbhs_mod *ret = NULL; switch (id) { case USBHS_HOST: case USBHS_GADGET: ret = info->mod[id]; break; } return ret; }
void usbhs_irq_callback_update(struct usbhs_priv *priv, struct usbhs_mod *mod) { u16 intenb0 = 0; u16 intenb1 = 0; struct usbhs_mod_info *info = usbhs_priv_to_modinfo(priv); usbhs_write(priv, INTENB0, 0); usbhs_write(priv, INTENB1, 0); usbhs_write(priv, BEMPENB, 0); usbhs_write(priv, BRDYENB, 0); if (info->irq_vbus) intenb0 |= VBSE; if (mod) { if (mod->irq_ctrl_stage) intenb0 |= CTRE; if (mod->irq_empty && mod->irq_bempsts) { usbhs_write(priv, BEMPENB, mod->irq_bempsts); intenb0 |= BEMPE; } if (mod->irq_ready && mod->irq_brdysts) { usbhs_write(priv, BRDYENB, mod->irq_brdysts); intenb0 |= BRDYE; } if (mod->irq_attch) intenb1 |= ATTCHE; if (mod->irq_dtch) intenb1 |= DTCHE; if (mod->irq_sign) intenb1 |= SIGNE; if (mod->irq_sack) intenb1 |= SACKE; } if (intenb0) usbhs_write(priv, INTENB0, intenb0); if (intenb1) usbhs_write(priv, INTENB1, intenb1); }
int usbhs_mod_change(struct usbhs_priv *priv, int id) { struct usbhs_mod_info *info = usbhs_priv_to_modinfo(priv); struct usbhs_mod *mod = NULL; int ret = 0; /* id < 0 mean no current */ switch (id) { case USBHS_HOST: case USBHS_GADGET: mod = info->mod[id]; break; default: ret = -EINVAL; } info->curt = mod; return ret; }
void usbhs_irq_callback_update(struct usbhs_priv *priv, struct usbhs_mod *mod) { u16 intenb0 = 0; u16 intenb1 = 0; struct usbhs_mod_info *info = usbhs_priv_to_modinfo(priv); /* * BEMPENB/BRDYENB are picky. * below method is required * * - clear INTSTS0 * - update BEMPENB/BRDYENB * - update INTSTS0 */ usbhs_write(priv, INTENB0, 0); usbhs_write(priv, INTENB1, 0); usbhs_write(priv, BEMPENB, 0); usbhs_write(priv, BRDYENB, 0); /* * see also * usbhs_interrupt */ /* * it don't enable DVSE (intenb0) here * but "mod->irq_dev_state" will be called. */ if (info->irq_vbus) intenb0 |= VBSE; if (mod) { /* * INTSTS0 */ if (mod->irq_ctrl_stage) intenb0 |= CTRE; if (mod->irq_empty && mod->irq_bempsts) { usbhs_write(priv, BEMPENB, mod->irq_bempsts); intenb0 |= BEMPE; } if (mod->irq_ready && mod->irq_brdysts) { usbhs_write(priv, BRDYENB, mod->irq_brdysts); intenb0 |= BRDYE; } /* * INTSTS1 */ if (mod->irq_attch) intenb1 |= ATTCHE; if (mod->irq_dtch) intenb1 |= DTCHE; if (mod->irq_sign) intenb1 |= SIGNE; if (mod->irq_sack) intenb1 |= SACKE; } if (intenb0) usbhs_write(priv, INTENB0, intenb0); if (intenb1) usbhs_write(priv, INTENB1, intenb1); }
struct usbhs_mod *usbhs_mod_get_current(struct usbhs_priv *priv) { struct usbhs_mod_info *info = usbhs_priv_to_modinfo(priv); return info->curt; }