extern void hcd_remove(struct platform_device *_dev);
extern void dwc_otg_adp_start(dwc_otg_core_if_t *core_if, uint8_t is_host);
-#ifdef CONFIG_USB20_OTG
-static struct usb20otg_pdata_id usb20otg_pdata[] = {
- {
- .name = "rk3188-usb20otg",
- .pdata = &usb20otg_pdata_rk3188,
- },
- {
- .name = "rk3288-usb20otg",
- .pdata = &usb20otg_pdata_rk3288,
- },
- {
- .name = "rk3036-usb20otg",
- .pdata = &usb20otg_pdata_rk3036,
- },
- {
- .name = "rk3126-usb20otg",
- .pdata = &usb20otg_pdata_rk3126,
- },
- {},
-};
-#endif
-
-#ifdef CONFIG_USB20_HOST
-static struct usb20host_pdata_id usb20host_pdata[] = {
- {
- .name = "rk3188-usb20host",
- .pdata = &usb20host_pdata_rk3188,
- },
- {
- .name = "rk3288-usb20host",
- .pdata = &usb20host_pdata_rk3288,
- },
- {
- .name = "rk3036-usb20host",
- .pdata = &usb20host_pdata_rk3036,
- },
- {
- .name = "rk3126-usb20host",
- .pdata = &usb20host_pdata_rk3126,
- },
- {},
-};
-#endif
+#ifdef CONFIG_RK_USB_UART
static u32 usb_to_uart_status;
+#endif
/*-------------------------------------------------------------------------*/
/* Encapsulate the module parameter settings */
local_irq_restore(flags);
}
-static void dwc_otg_set_force_mode(dwc_otg_core_if_t *core_if, int mode)
-{
- gusbcfg_data_t usbcfg = {.d32 = 0 };
- printk("!!!dwc_otg_set_force_mode\n");
- usbcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->gusbcfg);
- switch (mode) {
- case USB_MODE_FORCE_HOST:
- usbcfg.b.force_host_mode = 1;
- usbcfg.b.force_dev_mode = 0;
- break;
- case USB_MODE_FORCE_DEVICE:
- usbcfg.b.force_host_mode = 0;
- usbcfg.b.force_dev_mode = 1;
- break;
- case USB_MODE_NORMAL:
- usbcfg.b.force_host_mode = 0;
- usbcfg.b.force_dev_mode = 0;
- break;
- }
- DWC_WRITE_REG32(&core_if->core_global_regs->gusbcfg, usbcfg.d32);
-}
-
static ssize_t force_usb_mode_show(struct device_driver *drv, char *buf)
{
dwc_otg_device_t *otg_dev = g_otgdev;
}
static const struct of_device_id usb20_host_of_match[] = {
+#ifdef CONFIG_ARM
{
.compatible = "rockchip,rk3188_usb20_host",
- .data = &usb20host_pdata[RK3188_USB_CTLR],
+ .data = &usb20host_pdata_rk3188,
},
{
.compatible = "rockchip,rk3288_usb20_host",
- .data = &usb20host_pdata[RK3288_USB_CTLR],
+ .data = &usb20host_pdata_rk3288,
},
{
.compatible = "rockchip,rk3036_usb20_host",
- .data = &usb20host_pdata[RK3036_USB_CTLR],
+ .data = &usb20host_pdata_rk3036,
},
{
.compatible = "rockchip,rk3126_usb20_host",
- .data = &usb20host_pdata[RK3126_USB_CTLR],
+ .data = &usb20host_pdata_rk3126,
},
+#endif
{},
};
struct device *dev = &_dev->dev;
struct device_node *node = _dev->dev.of_node;
struct dwc_otg_platform_data *pldata;
- struct usb20host_pdata_id *p;
const struct of_device_id *match =
of_match_device(of_match_ptr(usb20_host_of_match), &_dev->dev);
- if (match) {
- p = (struct usb20host_pdata_id *)match->data;
+ if (match && match->data) {
+ pldata = (void *)match->data;
+ pldata->dev = dev;
} else {
- dev_err(dev, "usb20host match failed\n");
+ dev_err(dev, "usb20otg match failed\n");
return -EINVAL;
}
- dev->platform_data = p->pdata;
- pldata = dev->platform_data;
- pldata->dev = dev;
-
if (!node) {
dev_err(dev, "device node not found\n");
return -EINVAL;
retval = -ENOMEM;
goto clk_disable;
}
- dev_dbg(&_dev->dev, "base=0x%08x\n",
- (unsigned)dwc_otg_device->os_dep.base);
+ dev_dbg(&_dev->dev, "base=0x%p\n", dwc_otg_device->os_dep.base);
+
+ /* Set device flags indicating whether the HCD supports DMA. */
+ if (!_dev->dev.dma_mask)
+ _dev->dev.dma_mask = &_dev->dev.coherent_dma_mask;
+ retval = dma_set_coherent_mask(&_dev->dev, DMA_BIT_MASK(32));
+ if (retval)
+ goto clk_disable;
/*
* Initialize driver data to point to the global DWC_otg
static void dwc_otg_driver_shutdown(struct platform_device *_dev)
{
struct device *dev = &_dev->dev;
- struct dwc_otg_platform_data *pldata = dev->platform_data;
dwc_otg_device_t *otg_dev = dev->platform_data;
dwc_otg_core_if_t *core_if = otg_dev->core_if;
+ struct dwc_otg_platform_data *pldata = otg_dev->pldata;
dctl_data_t dctl = {.d32 = 0 };
+ dwc_otg_pcd_t *pcd = core_if->otg_dev->pcd;
DWC_PRINTF("%s: disconnect USB %s mode\n", __func__,
dwc_otg_is_host_mode(core_if) ? "host" : "device");
- if( pldata->dwc_otg_uart_mode != NULL)
- pldata->dwc_otg_uart_mode( pldata, PHY_USB_MODE);
- if(pldata->phy_suspend != NULL)
- pldata->phy_suspend(pldata, USB_PHY_ENABLED);
if (dwc_otg_is_host_mode(core_if)) {
if (core_if->hcd_cb && core_if->hcd_cb->stop)
core_if->hcd_cb->stop(core_if->hcd_cb_p);
} else {
+ cancel_delayed_work_sync(&pcd->check_vbus_work);
/* soft disconnect */
dctl.d32 =
DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dctl);
/* Clear any pending interrupts */
DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, 0xFFFFFFFF);
+ if (pldata->dwc_otg_uart_mode != NULL)
+ pldata->dwc_otg_uart_mode(pldata, PHY_USB_MODE);
+ if (pldata->phy_suspend != NULL)
+ pldata->phy_suspend(pldata, USB_PHY_ENABLED);
+
}
/**
}
static const struct of_device_id usb20_otg_of_match[] = {
+#ifdef CONFIG_ARM
{
.compatible = "rockchip,rk3188_usb20_otg",
- .data = &usb20otg_pdata[RK3188_USB_CTLR],
+ .data = &usb20otg_pdata_rk3188,
},
{
.compatible = "rockchip,rk3288_usb20_otg",
- .data = &usb20otg_pdata[RK3288_USB_CTLR],
+ .data = &usb20otg_pdata_rk3288,
},
{
.compatible = "rockchip,rk3036_usb20_otg",
- .data = &usb20otg_pdata[RK3036_USB_CTLR],
+ .data = &usb20otg_pdata_rk3036,
},
{
.compatible = "rockchip,rk3126_usb20_otg",
- .data = &usb20otg_pdata[RK3126_USB_CTLR],
+ .data = &usb20otg_pdata_rk3126,
},
+#endif
+#ifdef CONFIG_ARM64
{
+ .compatible = "rockchip,rk3368_usb20_otg",
+ .data = &usb20otg_pdata_rk3368,
},
+#endif
+ { },
};
MODULE_DEVICE_TABLE(of, usb20_otg_of_match);
struct device *dev = &_dev->dev;
struct device_node *node = _dev->dev.of_node;
struct dwc_otg_platform_data *pldata;
- struct usb20otg_pdata_id *p;
const struct of_device_id *match =
of_match_device(of_match_ptr(usb20_otg_of_match), &_dev->dev);
- if (match) {
- p = (struct usb20otg_pdata_id *)match->data;
+ if (match && match->data) {
+ pldata = (void *)match->data;
+ pldata->dev = dev;
} else {
dev_err(dev, "usb20otg match failed\n");
return -EINVAL;
}
- dev->platform_data = p->pdata;
- /* dev->platform_data = &usb20otg_pdata; */
- pldata = dev->platform_data;
- pldata->dev = dev;
-
if (!node) {
dev_err(dev, "device node not found\n");
return -EINVAL;
}
- /*todo : move to usbdev_rk-XX.c */
+
if (pldata->hw_init)
pldata->hw_init();
retval = -ENOMEM;
goto clk_disable;
}
- dev_dbg(&_dev->dev, "base=0x%08x\n",
- (unsigned)dwc_otg_device->os_dep.base);
+ dev_dbg(&_dev->dev, "base=0x%p\n", dwc_otg_device->os_dep.base);
+
+ /* Set device flags indicating whether the HCD supports DMA. */
+ if (!_dev->dev.dma_mask)
+ _dev->dev.dma_mask = &_dev->dev.coherent_dma_mask;
+ retval = dma_set_coherent_mask(&_dev->dev, DMA_BIT_MASK(32));
+ if (retval)
+ goto clk_disable;
/*
* Initialize driver data to point to the global DWC_otg
* perform initial actions required for Internal ADP logic.
*/
if (!dwc_otg_get_param_adp_enable(dwc_otg_device->core_if)) {
- if (pldata->phy_status == USB_PHY_ENABLED) {
+ if (dwc_otg_device->core_if->usb_mode == USB_MODE_NORMAL &&
+ pldata->phy_status == USB_PHY_ENABLED) {
pldata->phy_suspend(pldata, USB_PHY_SUSPEND);
udelay(3);
pldata->clock_enable(pldata, 0);
return retval;
}
+#ifdef CONFIG_PM
+static int dwc_otg_pm_suspend(struct device *dev)
+{
+ dwc_otg_device_t *dwc_otg_device;
+ struct dwc_otg_platform_data *pdata_otg;
+
+ dwc_otg_device = dev_get_platdata(dev);
+
+ dev_dbg(dev, "dwc_otg PM suspend\n");
+
+ if (dwc_otg_device->core_if->op_state == B_PERIPHERAL)
+ return 0;
+
+ pdata_otg = dwc_otg_device->pldata;
+ pdata_otg->phy_suspend(pdata_otg, USB_PHY_SUSPEND);
+
+ return 0;
+}
+
+static int dwc_otg_pm_resume(struct device *dev)
+{
+ dwc_otg_device_t *dwc_otg_device;
+ struct dwc_otg_platform_data *pdata_otg;
+
+ dwc_otg_device = dev_get_platdata(dev);
+
+ dev_dbg(dev, "dwc_otg PM resume\n");
+
+ if (dwc_otg_device->core_if->op_state == B_PERIPHERAL)
+ return 0;
+
+ pdata_otg = dwc_otg_device->pldata;
+ pdata_otg->phy_suspend(pdata_otg, USB_PHY_ENABLED);
+
+ return 0;
+}
+#else
+#define dwc_otg_pm_suspend NULL
+#define dwc_otg_pm_resume NULL
+#endif
+
+static const struct dev_pm_ops dwc_otg_dev_pm_ops = {
+ .suspend = dwc_otg_pm_suspend,
+ .resume = dwc_otg_pm_resume,
+};
+
static struct platform_driver dwc_otg_driver = {
.driver = {
.name = (char *)dwc_otg20_driver_name,
.of_match_table = of_match_ptr(usb20_otg_of_match),
+#ifdef CONFIG_PM
+ .pm = &dwc_otg_dev_pm_ops,
+#endif
},
.probe = otg20_driver_probe,
.remove = otg20_driver_remove,
struct dwc_otg_platform_data *pldata_otg;
struct dwc_otg_platform_data *pldata_host;
struct rkehci_platform_data *pldata_ehci;
- if (cpu_is_rk312x()) {
- pldata_otg = &usb20otg_pdata_rk3126;
- if (usb_to_uart_status)
- pldata_otg->dwc_otg_uart_mode(pldata_otg, PHY_UART_MODE);
- }
+
if (cpu_is_rk3288()) {
#ifdef CONFIG_RK_USB_UART
/* enable USB bypass UART function */
}
#endif
+ } else {
+ dwc_otg_device_t *otg_dev = g_otgdev;
+
+ if (!otg_dev)
+ return;
+
+ pldata_otg = otg_dev->pldata;
+ if (pldata_otg && pldata_otg->phy_power_down)
+ pldata_otg->phy_power_down(PHY_POWER_UP);
}
}
struct dwc_otg_platform_data *pldata_host;
struct rkehci_platform_data *pldata_ehci;
- if (cpu_is_rk312x()) {
- pldata_otg = &usb20otg_pdata_rk3126;
- usb_to_uart_status = pldata_otg->get_status(USB_STATUS_UARTMODE);
- pldata_otg->dwc_otg_uart_mode(pldata_otg, PHY_USB_MODE);
- }
if (cpu_is_rk3288()) {
#ifdef CONFIG_RK_USB_UART
/* disable USB bypass UART function */
RK3288_GRF_UOC1_CON0);
}
#endif
+ } else {
+ dwc_otg_device_t *otg_dev = g_otgdev;
+
+ if (!otg_dev)
+ return;
+
+ pldata_otg = otg_dev->pldata;
+ if (pldata_otg && pldata_otg->phy_power_down)
+ pldata_otg->phy_power_down(PHY_POWER_DOWN);
}
}