if (!IS_ERR(pdata.vbus_extcon.edev) ||
of_property_read_bool(np, "usb-role-switch"))
data->usbmisc_data->ext_vbus = 1;
+
+ /* usbmisc needs to know dr mode to choose wakeup setting */
+ data->usbmisc_data->available_role =
+ ci_hdrc_query_available_role(data->ci_pdev);
}
ret = imx_usbmisc_init_post(data->usbmisc_data);
unsigned int ext_id:1; /* ID from exteranl event */
unsigned int ext_vbus:1; /* Vbus from exteranl event */
struct usb_phy *usb_phy;
+ enum usb_dr_mode available_role; /* runtime usb dr mode */
};
int imx_usbmisc_init(struct imx_usbmisc_data *data);
}
EXPORT_SYMBOL_GPL(ci_hdrc_remove_device);
+/**
+ * ci_hdrc_query_available_role: get runtime available operation mode
+ *
+ * The glue layer can get current operation mode (host/peripheral/otg)
+ * This function should be called after ci core device has created.
+ *
+ * @pdev: the platform device of ci core.
+ *
+ * Return runtime usb_dr_mode.
+ */
+enum usb_dr_mode ci_hdrc_query_available_role(struct platform_device *pdev)
+{
+ struct ci_hdrc *ci = platform_get_drvdata(pdev);
+
+ if (!ci)
+ return USB_DR_MODE_UNKNOWN;
+ if (ci->roles[CI_ROLE_HOST] && ci->roles[CI_ROLE_GADGET])
+ return USB_DR_MODE_OTG;
+ else if (ci->roles[CI_ROLE_HOST])
+ return USB_DR_MODE_HOST;
+ else if (ci->roles[CI_ROLE_GADGET])
+ return USB_DR_MODE_PERIPHERAL;
+ else
+ return USB_DR_MODE_UNKNOWN;
+}
+EXPORT_SYMBOL_GPL(ci_hdrc_query_available_role);
+
static inline void ci_role_destroy(struct ci_hdrc *ci)
{
ci_hdrc_gadget_destroy(ci);
int empty_td_slot_index = (CI_MAX_BUF_SIZE - node->td_remaining_size)
/ CI_HDRC_PAGE_SIZE;
int i;
+ u32 token;
- node->ptr->token +=
- cpu_to_le32(sg_dma_len(s) << __ffs(TD_TOTAL_BYTES));
+ token = le32_to_cpu(node->ptr->token) + (sg_dma_len(s) << __ffs(TD_TOTAL_BYTES));
+ node->ptr->token = cpu_to_le32(token);
for (i = empty_td_slot_index; i < TD_PAGE_COUNT; i++) {
u32 page = (u32) sg_dma_address(s) +
{
u32 wakeup_setting = MX6_USB_OTG_WAKEUP_BITS;
- if (data->ext_id)
+ if (data->ext_id || data->available_role != USB_DR_MODE_OTG)
wakeup_setting &= ~MX6_BM_ID_WAKEUP;
- if (data->ext_vbus)
+ if (data->ext_vbus || data->available_role == USB_DR_MODE_HOST)
wakeup_setting &= ~MX6_BM_VBUS_WAKEUP;
return wakeup_setting;
struct ci_hdrc_platform_data *platdata);
/* Remove ci hdrc device */
void ci_hdrc_remove_device(struct platform_device *pdev);
+/* Get current available role */
+enum usb_dr_mode ci_hdrc_query_available_role(struct platform_device *pdev);
#endif