This driver supports Rockchip USB 1.1 HOST
controller.
+config USB11_HOST_EN
+ bool "---usb1.1 host controller enable"
+ depends on USB11_HOST
+ default y
+
config USB20_HOST
tristate "Rockchip USB 2.0 host controller"
depends on USB
This driver supports Rockchip USB2.0 host
controller.
+config USB20_HOST_EN
+ bool "---usb2.0 host controller enable"
+ depends on USB20_HOST
+ default y
+
config USB20_OTG
tristate "RockChip USB 2.0 OTG controller"
depends on USB||USB_GADGET
endchoice
config DWC_CONN_EN
- bool "connect to PC when vbus detect"
- default y
+ bool "---connect to PC when vbus detect"
depends on DWC_OTG_DEVICE_ONLY
+ default y
help
USB2.0 OTG controller always polling the USB vbus
if selected, device will connect to PC automatic
+config USB20_OTG_EN
+ bool "---usb2.0 otg host controller enable"
+ depends on DWC_OTG_HOST_ONLY
+ default y
+
config DWC_OTG_DEBUG
bool "DWC_OTG debug messages"
depends on USB11_HOST || USB20_HOST || USB20_OTG
}
DEVICE_ATTR(wr_reg_test, S_IRUGO|S_IWUSR, wr_reg_test_show, 0);
-extern int dwc_debug(int flag);
+extern int dwc_debug(dwc_otg_core_if_t *core_if, int flag);
static ssize_t debug_show( struct device *_dev,
struct device_attribute *attr, char *buf)
{
const char *buf, size_t count )
{
uint32_t val = simple_strtoul(buf, NULL, 16);
- dwc_debug(val);
+ dwc_otg_device_t *otg_dev = _dev->platform_data;
+ dwc_otg_dump_global_registers( otg_dev->core_if);
+ dwc_debug(otg_dev->core_if,val);
return count;
}
DEVICE_ATTR(debug, S_IRUGO|S_IWUSR, debug_show, debug_store);
+
+
/**@}*/
/**
#include "dwc_otg_regs.h"
#include "dwc_otg_driver.h"
#include "dwc_otg_cil.h"
+#include "dwc_otg_pcd.h"
static dwc_otg_core_if_t * dwc_core_if = NULL;
/**
* This function is called to initialize the DWC_otg CSR data
DWC_PRINT("core_if->usb_mode = %x\n",_core_if->usb_mode);
DWC_PRINT("core_if->usb_wakeup = %x\n",_core_if->usb_wakeup);
}
-int dwc_debug(int flag)
+int dwc_debug(dwc_otg_core_if_t *core_if, int flag)
{
- dwc_otg_core_if_t *core_if = dwc_core_if;
+ //dwc_otg_core_if_t *core_if = dwc_core_if;
+ struct dwc_otg_device *otg_dev;
+ dwc_otg_pcd_t * pcd;
switch(flag)
{
case 1:
dwc_otg_dump_host_registers(core_if);
break;
case 2:
- dwc_otg_dump_global_registers(core_if);
- dwc_otg_dump_dev_registers(core_if);
+ otg_dev = core_if->otg_dev;
+ pcd = otg_dev->pcd;
+ pcd->vbus_status = 0;
break;
case 3:
dump_scu_regs();
extern void dwc_otg_cil_register_hcd_callbacks( dwc_otg_core_if_t *_core_if,
dwc_otg_cil_callbacks_t *_cb,
void *_p);
-extern int dwc_debug(int flag);
+extern int dwc_debug(dwc_otg_core_if_t *core_if, int flag);
#endif
}
static DRIVER_ATTR(debuglevel, S_IRUGO|S_IWUSR, dbg_level_show, dbg_level_store);
-#ifdef CONFIG_DWC_OTG_DEVICE_ONLY
+static ssize_t dwc_otg_enable_show( struct device *_dev,
+ struct device_attribute *attr, char *buf)
+{
+ dwc_otg_device_t *otg_dev = _dev->platform_data;
+ return sprintf (buf, "%d\n", otg_dev->hcd->host_enabled);
+}
+
+static ssize_t dwc_otg_enable_store( struct device *_dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count )
+{
+ dwc_otg_device_t *otg_dev = _dev->platform_data;
+ dwc_otg_core_if_t *_core_if = otg_dev->core_if;
+ struct platform_device *pdev = to_platform_device(_dev);
+ uint32_t val = simple_strtoul(buf, NULL, 16);
+ if(otg_dev->hcd->host_enabled == val)
+ return count;
+
+ otg_dev->hcd->host_enabled = val;
+ if(val == 0) // enable -> disable
+ {
+ DWC_PRINT("disable host controller:%s\n",pdev->name);
+ #if 1
+ if (_core_if->hcd_cb && _core_if->hcd_cb->disconnect) {
+ _core_if->hcd_cb->disconnect( _core_if->hcd_cb->p );
+ }
+ #endif
+ if (_core_if->hcd_cb && _core_if->hcd_cb->stop) {
+ _core_if->hcd_cb->stop( _core_if->hcd_cb->p );
+ }
+ clk_disable(otg_dev->phyclk);
+ clk_disable(otg_dev->ahbclk);
+ }
+ else if(val == 1)
+ {
+ DWC_PRINT("enable host controller:%s\n",pdev->name);
+ clk_enable(otg_dev->phyclk);
+ clk_enable(otg_dev->ahbclk);
+ if (_core_if->hcd_cb && _core_if->hcd_cb->start) {
+ _core_if->hcd_cb->start( _core_if->hcd_cb->p );
+ }
+ }
+
+ return count;
+}
+static DEVICE_ATTR(enable, S_IRUGO|S_IWUSR, dwc_otg_enable_show, dwc_otg_enable_store);
+
static ssize_t dwc_otg_conn_en_show(struct device_driver *_drv, char *_buf)
{
+#ifdef CONFIG_DWC_OTG_DEVICE_ONLY
dwc_otg_device_t *otg_dev = g_otgdev;
dwc_otg_pcd_t *_pcd = otg_dev->pcd;
return sprintf (_buf, "%d\n", _pcd->conn_en);
+#endif
}
static ssize_t dwc_otg_conn_en_store(struct device_driver *_drv, const char *_buf,
size_t _count)
{
+#ifdef CONFIG_DWC_OTG_DEVICE_ONLY
int enable = simple_strtoul(_buf, NULL, 10);
dwc_otg_device_t *otg_dev = g_otgdev;
dwc_otg_pcd_t *_pcd = otg_dev->pcd;
_pcd->conn_en = enable;
return _count;
+#endif
}
static DRIVER_ATTR(dwc_otg_conn_en, S_IRUGO|S_IWUSR, dwc_otg_conn_en_show, dwc_otg_conn_en_store);
+#ifdef CONFIG_DWC_OTG_DEVICE_ONLY
static ssize_t vbus_status_show(struct device_driver *_drv, char *_buf)
{
dwc_otg_device_t *otg_dev = g_otgdev;
* Create Device Attributes in sysfs
*/
dwc_otg_attr_create(dev);
+#ifdef CONFIG_DWC_OTG_HOST_ONLY
+ retval |= device_create_file(dev, &dev_attr_enable);
+#endif
/*
* Disable the global interrupt until all the interrupt
* handlers are installed.
*/
dwc_otg_enable_global_interrupts( dwc_otg_device->core_if );
+#ifdef CONFIG_DWC_OTG_HOST_ONLY
+#ifndef CONFIG_USB20_OTG_EN
+ clk_disable(otg_dev->phyclk);
+ clk_disable(otg_dev->ahbclk);
+#endif
+#endif
DWC_PRINT("dwc_otg_driver_probe end, everest\n");
return 0;
fail:
* Create Device Attributes in sysfs
*/
dwc_otg_attr_create(dev);
+ retval |= device_create_file(dev, &dev_attr_enable);
/*
* Disable the global interrupt until all the interrupt
* handlers are installed.
*/
dwc_otg_enable_global_interrupts( dwc_otg_device->core_if );
+#ifndef CONFIG_USB11_HOST_EN
+ clk_disable(phyclk);
+ clk_disable(ahbclk);
+#endif
DWC_PRINT("host11_driver_probe end, everest\n");
return 0;
* Create Device Attributes in sysfs
*/
dwc_otg_attr_create(dev);
+ retval |= device_create_file(dev, &dev_attr_enable);
/*
* Disable the global interrupt until all the interrupt
* handlers are installed.
*/
dwc_otg_enable_global_interrupts( dwc_otg_device->core_if );
+#ifndef CONFIG_USB20_HOST_EN
+ clk_disable(phyclk);
+ clk_disable(ahbclk);
+#endif
DWC_PRINT("host20_driver_probe end, everest\n");
return 0;
dwc_otg_core_if_t *core_if = dwc_otg_hcd->core_if;
hprt0_data_t hprt0;
pcgcctl_data_t pcgcctl;
- //dwc_debug(1);
if(core_if->op_state == B_PERIPHERAL)
{
dwc_write_reg32(core_if->pcgcctl, pcgcctl.d32);
udelay(2);
#endif
- //dwc_debug(3);
- //dwc_debug(1);
gintmsk.d32 = dwc_read_reg32(&core_if->core_global_regs->gintmsk);
gintmsk.b.portintr = 0;
dwc_write_reg32(&core_if->core_global_regs->gintmsk, gintmsk.d32);
}
}
}
-
+#if 0
/**
* Responds with an error status of ETIMEDOUT to all URBs in the non-periodic
* and periodic schedules. The QTD associated with each URB is removed from
kill_urbs_in_qh_list(_hcd, &_hcd->periodic_sched_assigned);
kill_urbs_in_qh_list(_hcd, &_hcd->periodic_sched_queued);
}
-
+#endif
/**
* HCD Callback function for disconnect of the HCD.
*
}
/* Respond with an error status to all URBs in the schedule. */
- kill_all_urbs(dwc_otg_hcd);
+ // yk@20101227 handle kernel panic bug when disconnect
+ //kill_all_urbs(dwc_otg_hcd);
if (dwc_otg_is_host_mode(dwc_otg_hcd->core_if)) {
/* Clean up any host channels that were in use. */
dwc_otg_hcd->core_if = otg_dev->core_if;
otg_dev->hcd = dwc_otg_hcd;
+
+#ifdef CONFIG_USB20_OTG_EN
+ dwc_otg_hcd->host_enabled = 1;
+#else
+ dwc_otg_hcd->host_enabled = 0;
+#endif
/* Register the HCD CIL Callbacks */
dwc_otg_cil_register_hcd_callbacks(otg_dev->core_if,
DWC_ERROR("%s: status_buf allocation failed\n", __func__);
goto error3;
}
-
+
DWC_PRINT("%s end,everest\n",__func__);
// DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD Initialized HCD, bus=%s, usbbus=%d\n",
// dev->bus_id, hcd->self.busnum);
dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
dwc_otg_hcd->core_if = otg_dev->core_if;
otg_dev->hcd = dwc_otg_hcd;
+
+#ifdef CONFIG_USB11_HOST_EN
+ dwc_otg_hcd->host_enabled = 1;
+#else
+ dwc_otg_hcd->host_enabled = 0;
+#endif
spin_lock_init(&dwc_otg_hcd->global_lock);
dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
dwc_otg_hcd->core_if = otg_dev->core_if;
otg_dev->hcd = dwc_otg_hcd;
+
+#ifdef CONFIG_USB20_HOST_EN
+ dwc_otg_hcd->host_enabled = 1;
+#else
+ dwc_otg_hcd->host_enabled = 0;
+#endif
spin_lock_init(&dwc_otg_hcd->global_lock);
DWC_ERROR("%s: status_buf allocation failed\n", __func__);
goto error3;
}
-
+
DWC_PRINT("%s end,everest\n",__func__);
-// DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD Initialized HCD, bus=%s, usbbus=%d\n",
-// dev->bus_id, hcd->self.busnum);
return 0;
}
/* Initialize the bus state. If the core is in Device Mode
* HALT the USB bus and return. */
- if (dwc_otg_is_device_mode (core_if)) {
+ if (!dwc_otg_hcd->host_enabled || dwc_otg_is_device_mode (core_if)) {
DWC_PRINT("dwc_otg_hcd_start controller in device mode,everest\n");
//_hcd->state = HC_STATE_HALT;
goto out;
if(urb_qtd == NULL)
{
DWC_PRINT("%s,urb_qtd is null\n",__func__);
+ goto urb_qtd_null;
//return -1;
}
dwc_otg_hcd = hcd_to_dwc_otg_hcd(_hcd);
dwc_otg_hcd_qh_remove(dwc_otg_hcd, qh);
}
#endif
+
+urb_qtd_null:
spin_unlock_irqrestore(&dwc_otg_hcd->global_lock, flags);
_urb->hcpriv = NULL;
usb_hcd_unlink_urb_from_ep(_hcd, _urb);
uint64_t hfnum_other_frrem_accum_b;
#endif
+ /** Flag to indicate whether host controller is enabled. */
+ uint8_t host_enabled;
+
} dwc_otg_hcd_t;
/** Gets the dwc_otg_hcd from a struct usb_hcd */
handle_hc_ack_intr(_hcd, _hc, _hc_regs, _qtd);
} else if(hcint.b.datatglerr){
DWC_PRINT("%s, DATA toggle error, Channel %d\n",__func__, _hc->hc_num);
- dwc_debug(1);
clear_hc_int(_hc_regs,chhltd);
} else {
if (_hc->ep_type == DWC_OTG_EP_TYPE_INTR ||