#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.32.9
-# Sat Aug 21 11:03:43 2010
+# Thu Aug 26 13:15:43 2010
#
CONFIG_ARM=y
CONFIG_SYS_SUPPORTS_APM_EMULATION=y
#
# Bluetooth device drivers
#
+# CONFIG_BT_HCIBTUSB is not set
# CONFIG_BT_HCIBTSDIO is not set
CONFIG_BT_HCIUART=y
CONFIG_BT_HCIUART_H4=y
# CONFIG_BT_HCIUART_BCSP is not set
# CONFIG_BT_HCIUART_LL is not set
+# CONFIG_BT_HCIBCM203X is not set
+# CONFIG_BT_HCIBPA10X is not set
+# CONFIG_BT_HCIBFUSB is not set
# CONFIG_BT_HCIVHCI is not set
# CONFIG_BT_MRVL is not set
# CONFIG_BT_HCIBCM4325 is not set
CONFIG_MTD_NAND_RK2818=y
# CONFIG_MTD_NAND_NANDSIM is not set
# CONFIG_MTD_NAND_PLATFORM is not set
+# CONFIG_MTD_ALAUDA is not set
# CONFIG_MTD_ONENAND is not set
#
CONFIG_BLK_DEV_LOOP=y
# CONFIG_BLK_DEV_CRYPTOLOOP is not set
# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_UB is not set
# CONFIG_BLK_DEV_RAM is not set
# CONFIG_CDROM_PKTCDVD is not set
# CONFIG_ATA_OVER_ETH is not set
#
# Enable WiMAX (Networking options) to see the WiMAX drivers
#
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
# CONFIG_WAN is not set
CONFIG_PPP=y
# CONFIG_PPP_MULTILINK is not set
# CONFIG_TOUCHSCREEN_XPT2046_CBN_SPI is not set
# CONFIG_TOUCHSCREEN_XPT2046_320X480_SPI is not set
# CONFIG_TOUCHSCREEN_XPT2046_320X480_CBN_SPI is not set
+# CONFIG_TOUCHSCREEN_IT7250 is not set
# CONFIG_TOUCHSCREEN_AD7879_I2C is not set
# CONFIG_TOUCHSCREEN_AD7879_SPI is not set
# CONFIG_TOUCHSCREEN_AD7879 is not set
# CONFIG_SND_DRIVERS is not set
# CONFIG_SND_ARM is not set
# CONFIG_SND_SPI is not set
+CONFIG_SND_USB=y
+# CONFIG_SND_USB_AUDIO is not set
+# CONFIG_SND_USB_CAIAQ is not set
CONFIG_SND_SOC=y
CONFIG_SND_ROCKCHIP_SOC=y
CONFIG_SND_ROCKCHIP_SOC_I2S=y
CONFIG_USB_ARCH_HAS_HCD=y
# CONFIG_USB_ARCH_HAS_OHCI is not set
# CONFIG_USB_ARCH_HAS_EHCI is not set
-# CONFIG_USB is not set
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
+
+#
+# Miscellaneous USB options
+#
+# CONFIG_USB_DEVICEFS is not set
+CONFIG_USB_DEVICE_CLASS=y
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_SUSPEND is not set
+# CONFIG_USB_OTG is not set
# CONFIG_USB_OTG_WHITELIST is not set
# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+# CONFIG_USB_MON is not set
+# CONFIG_USB_WUSB is not set
+# CONFIG_USB_WUSB_CBAF is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_OXU210HP_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_HWA_HCD is not set
# CONFIG_USB_MUSB_HDRC is not set
# CONFIG_USB_GADGET_MUSB_HDRC is not set
+#
+# USB Device Class drivers
+#
+CONFIG_USB_ACM=y
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
+
#
# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
#
+
+#
+# also be needed; see USB_STORAGE Help for more info
+#
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+
+#
+# USB port drivers
+#
+CONFIG_USB_SERIAL=y
+# CONFIG_USB_SERIAL_CONSOLE is not set
+# CONFIG_USB_EZUSB is not set
+CONFIG_USB_SERIAL_GENERIC=y
+# CONFIG_USB_SERIAL_AIRCABLE is not set
+# CONFIG_USB_SERIAL_ARK3116 is not set
+# CONFIG_USB_SERIAL_BELKIN is not set
+# CONFIG_USB_SERIAL_CH341 is not set
+# CONFIG_USB_SERIAL_WHITEHEAT is not set
+# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
+# CONFIG_USB_SERIAL_CP210X is not set
+# CONFIG_USB_SERIAL_CYPRESS_M8 is not set
+# CONFIG_USB_SERIAL_EMPEG is not set
+# CONFIG_USB_SERIAL_FTDI_SIO is not set
+# CONFIG_USB_SERIAL_FUNSOFT is not set
+# CONFIG_USB_SERIAL_VISOR is not set
+# CONFIG_USB_SERIAL_IPAQ is not set
+# CONFIG_USB_SERIAL_IR is not set
+# CONFIG_USB_SERIAL_EDGEPORT is not set
+# CONFIG_USB_SERIAL_EDGEPORT_TI is not set
+# CONFIG_USB_SERIAL_GARMIN is not set
+# CONFIG_USB_SERIAL_IPW is not set
+# CONFIG_USB_SERIAL_IUU is not set
+# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
+# CONFIG_USB_SERIAL_KEYSPAN is not set
+# CONFIG_USB_SERIAL_KLSI is not set
+# CONFIG_USB_SERIAL_KOBIL_SCT is not set
+# CONFIG_USB_SERIAL_MCT_U232 is not set
+# CONFIG_USB_SERIAL_MOS7720 is not set
+# CONFIG_USB_SERIAL_MOS7840 is not set
+# CONFIG_USB_SERIAL_MOTOROLA is not set
+# CONFIG_USB_SERIAL_NAVMAN is not set
+# CONFIG_USB_SERIAL_PL2303 is not set
+# CONFIG_USB_SERIAL_OTI6858 is not set
+# CONFIG_USB_SERIAL_QUALCOMM is not set
+# CONFIG_USB_SERIAL_SPCP8X5 is not set
+# CONFIG_USB_SERIAL_HP4X is not set
+# CONFIG_USB_SERIAL_SAFE is not set
+# CONFIG_USB_SERIAL_SIEMENS_MPI is not set
+# CONFIG_USB_SERIAL_SIERRAWIRELESS is not set
+# CONFIG_USB_SERIAL_SYMBOL is not set
+# CONFIG_USB_SERIAL_TI is not set
+# CONFIG_USB_SERIAL_CYBERJACK is not set
+# CONFIG_USB_SERIAL_XIRCOM is not set
+CONFIG_USB_SERIAL_OPTION=y
+# CONFIG_USB_SERIAL_OMNINET is not set
+# CONFIG_USB_SERIAL_OPTICON is not set
+# CONFIG_USB_SERIAL_DEBUG is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_SEVSEG is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
+# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_VST is not set
CONFIG_USB_GADGET=y
# CONFIG_USB_GADGET_DEBUG is not set
# CONFIG_USB_GADGET_DEBUG_FILES is not set
#
# CONFIG_USB_GPIO_VBUS is not set
# CONFIG_NOP_USB_XCEIV is not set
-# CONFIG_RK2818_HOST11 is not set
+CONFIG_RK2818_HOST11=y
CONFIG_DWC_OTG=y
# CONFIG_DWC_OTG_DEBUG is not set
# CONFIG_DWC_OTG_HOST_ONLY is not set
-CONFIG_DWC_OTG_DEVICE_ONLY=y
-# CONFIG_DWC_OTG_BOTH_HOST_SLAVE is not set
+# CONFIG_DWC_OTG_DEVICE_ONLY is not set
+CONFIG_DWC_OTG_BOTH_HOST_SLAVE=y
# CONFIG_DWC_OTG_NORMAL_PREFERENCE is not set
# CONFIG_DWC_OTG_HOST_PREFERENCE is not set
CONFIG_DWC_OTG_DEVICE_PREFERENCE=y
#
CONFIG_STAGING=y
# CONFIG_STAGING_EXCLUDE_BUILD is not set
+# CONFIG_USB_IP_COMMON is not set
+# CONFIG_PRISM2_USB is not set
# CONFIG_ECHO is not set
+# CONFIG_COMEDI is not set
+# CONFIG_ASUS_OLED is not set
+# CONFIG_INPUT_MIMIO is not set
+# CONFIG_TRANZPORT is not set
#
# Android
# CONFIG_DST is not set
# CONFIG_POHMELFS is not set
# CONFIG_PLAN9AUTH is not set
+# CONFIG_LINE6_USB is not set
+# CONFIG_USB_SERIAL_QUATECH2 is not set
+# CONFIG_USB_SERIAL_QUATECH_USB2 is not set
+# CONFIG_VT6656 is not set
+# CONFIG_FB_UDL is not set
#
# RAR Register Driver
# CMMB
#
# CONFIG_CMMB is not set
+
#
# File systems
#
//X OP(768, 350, 768, 24, 1, 16, 41, 41),
// OP(720, 350, 720, 24, 1, 15, 41, 21),
// OP(672, 350, 672, 24, 1, 14, 41, 21),
-// OP(624, 350, 624, 24, 1, 13, 41, 21),
+#if defined(CONFIG_MACH_INFO)
+ OP(624, 350, 624, 24, 1, 13, 31, 21),
+#else
OP(600, 350, 600, 24, 1, 12, 41, 21),
+#endif
// OP(576, 350, 576, 24, 1, 12, 41, 21),
// OP(528, 350, 528, 24, 1, 11, 41, 21),
// OP(480, 350, 480, 24, 1, 10, 41, 21),
kref_put(&hub->kref, hub_release);
}
-
+struct usb_hub *g_root_hub20 = NULL;
+struct usb_hub *g_root_hub11 = NULL;
static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id)
{
struct usb_host_interface *desc;
dev_dbg (&intf->dev, "couldn't kmalloc hub struct\n");
return -ENOMEM;
}
-
+ if(hdev->parent == NULL)
+ {
+ if(!g_root_hub20)
+ g_root_hub20 = hub;
+ else if(!g_root_hub11)
+ g_root_hub11 = hub;
+ }
kref_init(&hub->kref);
INIT_LIST_HEAD(&hub->event_list);
hub->intfdev = &intf->dev;
} /* end while (1) */
}
-// cmy@091222: µ±¿ªHost¶Ë¿ÚËùÁ¬½ÓµÄÉ豸£¬¹©host/slaveÇл»ÓÃ
-void hub_disconnect_device()
+
+/* yk@rk 20100730
+ * disconnect all devices on root hub
+ */
+void hub_disconnect_device(struct usb_hub *hub)
{
- if(g_usb_device)
- {
- struct usb_hub *hub = hdev_to_hub(g_usb_device->parent);
- // cmy: ¶Ï¿ªÉ豸Á¬½Ó
hub_port_connect_change(hub, 1, 0, 0x2);
- }
}
static int hub_thread(void *__unused)
* MACROs for defining sysfs attribute
*/
#define DWC_OTG_DEVICE_ATTR_BITFIELD_SHOW(_otg_attr_name_,_addr_,_mask_,_shift_,_string_) \
-static ssize_t _otg_attr_name_##_show (struct device *_dev, char *buf) \
+static ssize_t _otg_attr_name_##_show (struct device *_dev, struct device_attribute *attr, char *buf) \
{ \
dwc_otg_device_t *otg_dev = _dev->platform_data;\
uint32_t val; \
return sprintf (buf, "%s = 0x%x\n", _string_, val); \
}
#define DWC_OTG_DEVICE_ATTR_BITFIELD_STORE(_otg_attr_name_,_addr_,_mask_,_shift_,_string_) \
-static ssize_t _otg_attr_name_##_store (struct device *_dev, const char *buf, size_t count) \
+static ssize_t _otg_attr_name_##_store (struct device *_dev, struct device_attribute *attr, const char *buf, size_t count) \
{ \
dwc_otg_device_t *otg_dev = _dev->platform_data;\
uint32_t set = simple_strtoul(buf, NULL, 16); \
* MACROs for defining sysfs attribute for 32-bit registers
*/
#define DWC_OTG_DEVICE_ATTR_REG_SHOW(_otg_attr_name_,_addr_,_string_) \
-static ssize_t _otg_attr_name_##_show (struct device *_dev, char *buf) \
+static ssize_t _otg_attr_name_##_show (struct device *_dev, struct device_attribute *attr, char *buf) \
{ \
dwc_otg_device_t *otg_dev = _dev->platform_data;\
uint32_t val; \
return sprintf (buf, "%s = 0x%08x\n", _string_, val); \
}
#define DWC_OTG_DEVICE_ATTR_REG_STORE(_otg_attr_name_,_addr_,_string_) \
-static ssize_t _otg_attr_name_##_store (struct device *_dev, const char *buf, size_t count) \
+static ssize_t _otg_attr_name_##_store (struct device *_dev, struct device_attribute *attr, const char *buf, size_t count) \
{ \
dwc_otg_device_t *otg_dev = _dev->platform_data;\
uint32_t val = simple_strtoul(buf, NULL, 16); \
/**
* Show the register offset of the Register Access.
*/
-static ssize_t regoffset_show( struct device *_dev, char *buf)
+static ssize_t regoffset_show( struct device *_dev,
+ struct device_attribute *attr, char *buf)
{
dwc_otg_device_t *otg_dev = _dev->platform_data;
+
return snprintf(buf, sizeof("0xFFFFFFFF\n")+1,"0x%08x\n", otg_dev->reg_offset);
}
/**
* Set the register offset for the next Register Access Read/Write
*/
-static ssize_t regoffset_store( struct device *_dev, const char *buf,
- size_t count )
+static ssize_t regoffset_store( struct device *_dev, struct device_attribute *attr,
+ const char *buf, size_t count )
{
dwc_otg_device_t *otg_dev = _dev->platform_data;
uint32_t offset = simple_strtoul(buf, NULL, 16);
* Show the value of the register at the offset in the reg_offset
* attribute.
*/
-static ssize_t regvalue_show( struct device *_dev, char *buf)
+static ssize_t regvalue_show( struct device *_dev,
+ struct device_attribute *attr, char *buf)
{
dwc_otg_device_t *otg_dev = _dev->platform_data;
uint32_t val;
* attribute.
*
*/
-static ssize_t regvalue_store( struct device *_dev, const char *buf,
- size_t count )
+static ssize_t regvalue_store( struct device *_dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count )
{
dwc_otg_device_t *otg_dev = _dev->platform_data;
volatile uint32_t * addr;
/**
* Show the HNP status bit
*/
-static ssize_t hnp_show( struct device *_dev, char *buf)
+static ssize_t hnp_show( struct device *_dev,
+ struct device_attribute *attr, char *buf)
{
dwc_otg_device_t *otg_dev = _dev->platform_data;
gotgctl_data_t val;
/**
* Set the HNP Request bit
*/
-static ssize_t hnp_store( struct device *_dev, const char *buf,
- size_t count )
+static ssize_t hnp_store( struct device *_dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count )
{
dwc_otg_device_t *otg_dev = _dev->platform_data;
uint32_t in = simple_strtoul(buf, NULL, 16);
/**
* Show the SRP status bit
*/
-static ssize_t srp_show( struct device *_dev, char *buf)
+static ssize_t srp_show( struct device *_dev,
+ struct device_attribute *attr, char *buf)
{
#ifndef DWC_HOST_ONLY
dwc_otg_device_t *otg_dev = _dev->platform_data;
/**
* Set the SRP Request bit
*/
-static ssize_t srp_store( struct device *_dev, const char *buf,
- size_t count )
+static ssize_t srp_store( struct device *_dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count )
{
#ifndef DWC_HOST_ONLY
dwc_otg_device_t *otg_dev = _dev->platform_data;
/**
* Show the Bus Power status
*/
-static ssize_t buspower_show( struct device *_dev, char *buf)
+static ssize_t buspower_show( struct device *_dev,
+ struct device_attribute *attr, char *buf)
{
dwc_otg_device_t *otg_dev = _dev->platform_data;
hprt0_data_t val;
/**
* Set the Bus Power status
*/
-static ssize_t buspower_store( struct device *_dev, const char *buf,
- size_t count )
+static ssize_t buspower_store( struct device *_dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count )
{
dwc_otg_device_t *otg_dev = _dev->platform_data;
uint32_t on = simple_strtoul(buf, NULL, 16);
/**
* Show the Bus Suspend status
*/
-static ssize_t bussuspend_show( struct device *_dev, char *buf)
+static ssize_t bussuspend_show( struct device *_dev,
+ struct device_attribute *attr, char *buf)
{
dwc_otg_device_t *otg_dev = _dev->platform_data;
hprt0_data_t val;
/**
* Set the Bus Suspend status
*/
-static ssize_t bussuspend_store( struct device *_dev, const char *buf,
- size_t count )
+static ssize_t bussuspend_store( struct device *_dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count )
{
dwc_otg_device_t *otg_dev = _dev->platform_data;
uint32_t in = simple_strtoul(buf, NULL, 16);
/**
* Show the status of Remote Wakeup.
*/
-static ssize_t remote_wakeup_show( struct device *_dev, char *buf)
+static ssize_t remote_wakeup_show( struct device *_dev,
+ struct device_attribute *attr,char *buf)
{
#ifndef DWC_HOST_ONLY
dwc_otg_device_t *otg_dev = _dev->platform_data;
* flag is set.
*
*/
-static ssize_t remote_wakeup_store( struct device *_dev, const char *buf,
- size_t count )
+static ssize_t remote_wakeup_store( struct device *_dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count )
{
#ifndef DWC_HOST_ONLY
uint32_t val = simple_strtoul(buf, NULL, 16);
#endif
return count;
}
-DEVICE_ATTR(remote_wakeup, S_IRUGO|S_IWUSR, remote_wakeup_show,
+static DEVICE_ATTR(remote_wakeup, S_IRUGO|S_IWUSR, remote_wakeup_show,
remote_wakeup_store);
/**
* Dump global registers and either host or device registers (depending on the
* current mode of the core).
*/
-static ssize_t regdump_show( struct device *_dev, char *buf)
+static ssize_t regdump_show( struct device *_dev,
+ struct device_attribute *attr, char *buf)
{
dwc_otg_device_t *otg_dev = _dev->platform_data;
dwc_otg_dump_global_registers( otg_dev->core_if);
/**
* Dump the current hcd state.
*/
-static ssize_t hcddump_show( struct device *_dev, char *buf)
+static ssize_t hcddump_show( struct device *_dev,
+ struct device_attribute *attr, char *buf)
{
#ifndef DWC_DEVICE_ONLY
dwc_otg_device_t *otg_dev = _dev->platform_data;
* determine average interrupt latency. Frame remaining is also shown for
* start transfer and two additional sample points.
*/
-static ssize_t hcd_frrem_show( struct device *_dev, char *buf)
+static ssize_t hcd_frrem_show( struct device *_dev,
+ struct device_attribute *attr, char *buf)
{
#ifndef DWC_DEVICE_ONLY
dwc_otg_device_t *otg_dev = _dev->platform_data;
*/
#define RW_REG_COUNT 10000000
#define MSEC_PER_JIFFIE 1000/HZ
-static ssize_t rd_reg_test_show( struct device *_dev, char *buf)
+static ssize_t rd_reg_test_show( struct device *_dev,
+ struct device_attribute *attr, char *buf)
{
int i;
int time;
* Displays the time required to write the GNPTXFSIZ register many times (the
* output shows the number of times the register is written).
*/
-static ssize_t wr_reg_test_show( struct device *_dev, char *buf)
+static ssize_t wr_reg_test_show( struct device *_dev,
+ struct device_attribute *attr, char *buf)
{
int i;
int time;
#include "dwc_otg_driver.h"
#include "dwc_otg_cil.h"
#define SCU_BASE_ADDR_VA RK2818_SCU_BASE
-static dwc_otg_core_if_t * dwc_core_if;
+static dwc_otg_core_if_t * dwc_core_if = NULL;
/**
* This function is called to initialize the DWC_otg CSR data
* structures. The register addresses in the device and host
core_if->srp_timer_started = 0;
core_if->usb_wakeup = 0;
+ if(dwc_core_if == NULL)
dwc_core_if = core_if;
return core_if;
}
for(i = 0; i < num_eps; ++i)
{
- if(!(hwcfg1 & 0x1))
+ if((hwcfg1 & 0x3) == 0x01)
num_in_eps++;
hwcfg1 >>= 2;
for(i = 0; i < num_eps; ++i)
{
- if(!(hwcfg1 & 0x2))
+ if((hwcfg1 & 0x3) == 0x02)
num_out_eps++;
hwcfg1 >>= 2;
}
}
}
+#if 1
+ //yk@rk 20100714
+ if((_core_if->core_params->host_channels <= 2)&&
+ _hc->ep_is_in &&
+ _hc->ep_type == DWC_OTG_EP_TYPE_BULK)
+ {
+ //DWC_PRINT("%s bulk in\n",__func__);
+ hc_intr_mask.b.nak = 1;
+ }
+#endif
}
else
{
dwc_hc_t *_hc,
dwc_otg_halt_status_e _halt_status)
{
- gnptxsts_data_t nptxsts;
- hptxsts_data_t hptxsts;
hcchar_data_t hcchar;
dwc_otg_hc_regs_t *hc_regs;
dwc_otg_core_global_regs_t *global_regs;
* happen when a transfer is aborted by a higher level in
* the stack.
*/
-#ifdef DEBUG
+
DWC_PRINT("*** %s: Channel %d, _hc->halt_pending already set ***\n",
__func__, _hc->hc_num);
+#ifdef DEBUG
/* dwc_otg_dump_global_registers(_core_if); */
/* dwc_otg_dump_host_registers(_core_if); */
#endif
return;
}
+
hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
- hcchar.b.chen = 1;
- hcchar.b.chdis = 1;
-
- if (!_core_if->dma_enable)
- {
- /* Check for space in the request queue to issue the halt. */
- if (_hc->ep_type == DWC_OTG_EP_TYPE_CONTROL ||
- _hc->ep_type == DWC_OTG_EP_TYPE_BULK)
- {
- nptxsts.d32 = dwc_read_reg32(&global_regs->gnptxsts);
- if (nptxsts.b.nptxqspcavail == 0)
- {
- hcchar.b.chen = 0;
- }
- }
- else
- {
- hptxsts.d32 = dwc_read_reg32(&host_global_regs->hptxsts);
- if ((hptxsts.b.ptxqspcavail == 0) || (_core_if->queuing_high_bandwidth))
- {
- hcchar.b.chen = 0;
- }
- }
- }
-
- dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
-
- _hc->halt_status = _halt_status;
-
- if (hcchar.b.chen)
+ //hcchar.b.chen = 1;
+ //hcchar.b.chdis = 1;
+ if(hcchar.b.chen)
{
+ hcchar.b.chen = 0;
+ hcchar.b.chdis = 1;
+ //hcchar.b.epdir = 0;
+ dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
+
_hc->halt_pending = 1;
_hc->halt_on_queue = 0;
- }
- else
+ _hc->halt_status = _halt_status;
+ }
+ else
{
+ DWC_PRINT("%s channel already halt!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n", __func__);
_hc->halt_on_queue = 1;
}
-
+
DWC_DEBUGPL(DBG_HCDV, "%s: Channel %d\n", __func__, _hc->hc_num);
DWC_DEBUGPL(DBG_HCDV, " hcchar: 0x%08x\n", hcchar.d32);
DWC_DEBUGPL(DBG_HCDV, " halt_pending: %d\n", _hc->halt_pending);
{
dwc_otg_core_global_regs_t *global_regs = _core_if->core_global_regs;
volatile grstctl_t greset = { .d32 = 0};
- gusbcfg_data_t usbcfg = { .d32 = 0 };
+ volatile gusbcfg_data_t usbcfg = { .d32 = 0 };
+ volatile gintsts_data_t gintsts = { .d32 = 0 };
int count = 0;
DWC_DEBUGPL(DBG_CILV, "%s\n", __func__);
/* Wait for AHB master IDLE state. */
dwc_write_reg32( &global_regs->gusbcfg, usbcfg.d32 );
/* Wait for 3 PHY Clocks*/
//DWC_PRINT("100ms\n");
- MDELAY(100);
+ mdelay(10);
+ count = 0;
+ if(usbcfg.b.force_hst_mode)
+ do
+ {
+ gintsts.d32 = dwc_read_reg32( &global_regs->gintsts);
+ if (++count > 100)
+ {
+ DWC_WARN("%s() ERROR! Force host mode GINTSTS=%0x\n", __func__,
+ gintsts.d32);
+ break;
+ }
+ mdelay(5);
+ }
+ while (gintsts.b.curmode != DWC_HOST_MODE);
}
_cb->p = _p;
}
-void rk28_usb_force_disconnect( void )
+void rk28_usb_force_disconnect( dwc_otg_core_if_t *core_if )
{
gotgctl_data_t gctrl;
dctl_data_t dctl = {.d32=0};
- if( dwc_core_if == NULL )
- return ;
- gctrl.d32 = dwc_read_reg32( &dwc_core_if->core_global_regs->gotgctl );
+ gctrl.d32 = dwc_read_reg32( &core_if->core_global_regs->gotgctl );
if( !gctrl.b.bsesvld )
return ;
printk("%s\n" , __func__);
/* soft disconnect */
- dctl.d32 = dwc_read_reg32( &dwc_core_if->dev_if->dev_global_regs->dctl );
+ dctl.d32 = dwc_read_reg32( &core_if->dev_if->dev_global_regs->dctl );
dctl.b.sftdiscon = 1;
- dwc_write_reg32( &dwc_core_if->dev_if->dev_global_regs->dctl, dctl.d32 );
+ dwc_write_reg32( &core_if->dev_if->dev_global_regs->dctl, dctl.d32 );
}
/**
MDELAY(100);
if (++count > 10000) *(uint32_t*)NULL=0;
}
- _core_if->op_state = B_PERIPHERAL;
hcd_stop(_core_if);
+ _core_if->op_state = B_PERIPHERAL;
pcd->phy_suspend = 1;
pcd->vbus_status = 0;
dwc_otg_pcd_start_vbus_timer( pcd );
static const char dwc_driver_name[] = "dwc_otg";
-struct dwc_otg_device_t* g_otgdev = NULL;
+dwc_otg_device_t* g_otgdev = NULL;
/*-------------------------------------------------------------------------*/
/* Encapsulate the module parameter settings */
#ifdef CONFIG_RK2818_HOST11
-struct dwc_otg_device_t* g_host11 = NULL;
+dwc_otg_device_t* g_host11 = NULL;
static dwc_otg_core_params_t rk28_host11_module_params = {
.opt = -1,
}
static DRIVER_ATTR(debuglevel, S_IRUGO|S_IWUSR, dbg_level_show, dbg_level_store);
+extern struct usb_hub *g_root_hub20;
+extern struct usb_hub *g_root_hub11;
#ifdef DWC_BOTH_HOST_SLAVE
extern void hcd_start( dwc_otg_core_if_t *_core_if );
extern int rk28_usb_suspend( int exitsuspend );
-extern void hub_disconnect_device();
-extern void rk28_usb_force_disconnect( void );
+extern void hub_disconnect_device(struct usb_hub *hub);
+extern void rk28_usb_force_disconnect( dwc_otg_core_if_t *core_if );
static ssize_t force_usb_mode_show(struct device_driver *_drv, char *_buf)
{
{
rk28_usb_suspend( 1 );
}
+ del_timer(&otg_dev->pcd->check_vbus_timer);
+ rk28_usb_force_disconnect(core_if);
if (core_if->pcd_cb && core_if->pcd_cb->stop ) {
core_if->pcd_cb->stop( core_if->pcd_cb->p );
}
- del_timer(&otg_dev->pcd->check_vbus_timer);
- rk28_usb_force_disconnect();
- core_if->op_state = A_HOST;
+ //core_if->op_state = A_HOST;
/*
* Initialize the Core for Host mode.
*/
void dwc_otg_force_device(dwc_otg_core_if_t *core_if)
{
dwc_otg_device_t *otg_dev = g_otgdev;
+ dwc_otg_disable_global_interrupts( core_if );
+ hub_disconnect_device(g_root_hub20);
+ if (core_if->hcd_cb && core_if->hcd_cb->stop) {
+ core_if->hcd_cb->stop( core_if->hcd_cb->p );
+ }
if(core_if->op_state == B_PERIPHERAL)
{
printk("dwc_otg_force_device,already in B_PERIPHERAL,everest\n");
return;
}
- dwc_otg_disable_global_interrupts( core_if );
- hub_disconnect_device();
- if (core_if->hcd_cb && core_if->hcd_cb->stop) {
- core_if->hcd_cb->stop( core_if->hcd_cb->p );
- }
otg_dev->core_if->op_state = B_PERIPHERAL;
/* Reset the Controller */
dwc_otg_core_reset( core_if );
static ssize_t force_usb_mode_store(struct device_driver *_drv, const char *_buf,
size_t _count )
{
- int new_mode = simple_strtoul(_buf, NULL, 10);
+ int new_mode = simple_strtoul(_buf, NULL, 16);
dwc_otg_device_t *otg_dev = g_otgdev;
dwc_otg_core_if_t *core_if = otg_dev->core_if;
- dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
-
+ DWC_PRINT("%s %d->%d\n",__func__, core_if->usb_mode, new_mode);
if(core_if->usb_mode == new_mode)
{
return _count;
default:
break;
}
- return 0;
+ return _count;
}
int otg_debug( int action )
{
(core_params->max_packet_count < (1 << (core_if->hwcfg3.b.packet_size_cntr_width + 4))),
((1 << (core_if->hwcfg3.b.packet_size_cntr_width + 4)) - 1));
+// yk@rk use 1 channel in host 1.1
retval += DWC_OTG_PARAM_CHECK_VALID(host_channels,
"host_channels",
(core_params->host_channels <= (core_if->hwcfg2.b.num_host_chan + 1)),
- (core_if->hwcfg2.b.num_host_chan + 1));
+ (core_if->hwcfg2.b.num_host_chan));// + 1
retval += DWC_OTG_PARAM_CHECK_VALID(dev_endpoints,
"dev_endpoints",
* This function is the top level interrupt handler for the Common
* (Device and host modes) interrupts.
*/
-static irqreturn_t dwc_otg_common_irq(int _irq, void *_dev, struct pt_regs *_r)
+static irqreturn_t dwc_otg_common_irq(int _irq, void *_dev)
{
dwc_otg_device_t *otg_dev = _dev;
int32_t retval = IRQ_NONE;
*
* @param[in] pdev
*/
-static void dwc_otg_driver_remove(struct platform_device *pdev)
+static int dwc_otg_driver_remove(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
dwc_otg_device_t *otg_dev = dev->platform_data;
if (otg_dev == NULL)
{
/* Memory allocation for the dwc_otg_device failed. */
- return;
+ return 0;
}
/*
dwc_otg_module_params.host_nperio_tx_fifo_size = -1;
dwc_otg_module_params.dev_rx_fifo_size = -1;
#endif
+ return 0;
}
/**
struct device *dev = &_dev->dev;
dwc_otg_device_t *otg_dev = dev->platform_data;
dwc_otg_core_if_t *core_if = otg_dev->core_if;
+ if(core_if->op_state == A_HOST)
+ {
+ printk("%s,A_HOST mode\n", __func__);
+ return 0;
+ }
//gotgctl_data_t gctrl;
#if 0
if( __rkusb_debug_mod() )
dwc_otg_core_global_regs_t *global_regs =
core_if->core_global_regs;
+ if(core_if->op_state == A_HOST)
+ {
+ printk("%s,A_HOST mode\n", __func__);
+ return 0;
+ }
#if 0
if( __rkusb_debug_mod() )
goto sendwakeup;
};
#ifdef CONFIG_RK2818_HOST11
-static void rk28_host11_driver_remove(struct platform_device *pdev)
+
+void rk28_host11_driver_enable(dwc_otg_core_if_t *core_if)
+{
+ unsigned int * otg_phy_con1 = (unsigned int*)(RK2818_REGFILE_BASE+0x3c);
+ unsigned int * scu_clkgate1_con = (unsigned int*)(RK2818_SCU_BASE+0x20);
+ /*
+ * enable usb phy & clockgate host controller
+ */
+ core_if->usb_mode == USB_MODE_FORCE_HOST;
+ core_if->op_state = A_HOST;
+ dwc_modify_reg32(scu_clkgate1_con,0x80000000,0); //clock gate enable
+ udelay(10);
+ dwc_modify_reg32(otg_phy_con1,0x80000000,0);// exit suspend.
+ mdelay(10);
+
+ /*
+ * Initialize the Core for Host mode.
+ */
+ dwc_otg_core_init(core_if);
+ dwc_otg_enable_global_interrupts(core_if);
+ hcd_start( core_if );
+}
+
+void rk28_host11_driver_disable(dwc_otg_core_if_t *core_if)
+{
+ unsigned int * otg_phy_con1 = (unsigned int*)(RK2818_REGFILE_BASE+0x3c);
+ unsigned int * scu_clkgate1_con = (unsigned int*)(RK2818_SCU_BASE+0x20);
+ dwc_otg_disable_global_interrupts( core_if );
+ hub_disconnect_device(g_root_hub11);
+ if (core_if->hcd_cb && core_if->hcd_cb->stop) {
+ core_if->hcd_cb->stop( core_if->hcd_cb->p );
+ }
+ /*
+ *disable usb phy & clockgate host controller
+ */
+ dwc_modify_reg32(otg_phy_con1,0x80000000,0x80000000);// exit suspend.
+ mdelay(10);
+ dwc_modify_reg32(scu_clkgate1_con,0x80000000,0x80000000); //clock gate enable
+}
+extern void dwc_otg_hcd_remove(struct device *_dev);
+extern int __devinit rk28_host11_hcd_init(struct device *_dev);
+
+static int s_host11_enable = 0;
+
+static ssize_t enable_usb11_show(struct device_driver *_drv, char *_buf)
+{
+ return sprintf(_buf, "%d\n", s_host11_enable);
+}
+
+static ssize_t enable_usb11_store(struct device_driver *_drv, const char *_buf,
+ size_t _count )
+{
+ int enabled = simple_strtoul(_buf, NULL, 16);
+ dwc_otg_device_t *otg_dev = g_host11;
+ dwc_otg_core_if_t *core_if = otg_dev->core_if;
+ printk("enable usb11: %d\n", enabled);
+
+ if(enabled)
+ {// enable usb1.1
+ printk("BEGIN enable\n");
+ if(s_host11_enable){
+ printk("HOST1.1 already enable\n");
+ return _count;
+ }
+ rk28_host11_driver_enable(core_if);
+#if 0
+ GPIOSetPinDirection(GPIOPortG_Pin1, GPIO_OUT);
+ GPIOSetPinLevel(GPIOPortG_Pin1, GPIO_LOW);
+ msleep(10);
+
+ GPIOSetPinDirection(GPIOPortB_Pin0, GPIO_OUT);
+ GPIOSetPinLevel(GPIOPortB_Pin0, GPIO_HIGH);
+ msleep(10);
+
+ GPIOSetPinDirection(GPIOPortG_Pin0, GPIO_OUT);
+ GPIOSetPinLevel(GPIOPortG_Pin0, GPIO_HIGH);
+ msleep(10);
+
+ GPIOSetPinDirection(GPIOPortG_Pin1, GPIO_OUT);
+ GPIOSetPinLevel(GPIOPortG_Pin1, GPIO_HIGH);
+#endif
+ s_host11_enable = 1;
+ printk("END\n");
+ }
+ else
+ {// disable usb1.1
+// cmy:
+ printk("BEGIN disable\n");
+ rk28_host11_driver_disable(core_if);
+#if 0
+ GPIOSetPinDirection(GPIOPortB_Pin0, GPIO_OUT);
+ GPIOSetPinLevel(GPIOPortB_Pin0, GPIO_LOW);
+ msleep(10);
+
+ GPIOSetPinDirection(GPIOPortG_Pin0, GPIO_OUT);
+ GPIOSetPinLevel(GPIOPortG_Pin0, GPIO_LOW);
+ msleep(10);
+
+ GPIOSetPinDirection(GPIOPortG_Pin1, GPIO_OUT);
+ GPIOSetPinLevel(GPIOPortG_Pin1, GPIO_LOW);
+#endif
+ s_host11_enable = 0;
+ printk("END\n");
+ }
+
+ return _count;
+}
+
+static DRIVER_ATTR(enable_usb11, 0666/*S_IRUGO|S_IWUSR*/, enable_usb11_show, enable_usb11_store);
+
+static int rk28_host11_driver_remove(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
dwc_otg_device_t *otg_dev = dev->platform_data;
if (otg_dev == NULL)
{
/* Memory allocation for the dwc_otg_device failed. */
- return;
+ return 0;
}
/*
*/
dev->platform_data = 0;
+ return 0;
}
/**
static int rk28_host11_driver_suspend(struct platform_device *_dev , pm_message_t state )
{
- struct device *dev = &_dev->dev;
- dwc_otg_device_t *otg_dev = dev->platform_data;
- dwc_otg_core_if_t *core_if = otg_dev->core_if;
+ //struct device *dev = &_dev->dev;
+ //dwc_otg_device_t *otg_dev = dev->platform_data;
+ //dwc_otg_core_if_t *core_if = otg_dev->core_if;
return 0;
}
static int rk28_host11_driver_resume(struct platform_device *_dev )
{
- struct device *dev = &_dev->dev;
- dwc_otg_device_t *otg_dev = dev->platform_data;
- dwc_otg_core_if_t *core_if = otg_dev->core_if;
+ //struct device *dev = &_dev->dev;
+ //dwc_otg_device_t *otg_dev = dev->platform_data;
+ //dwc_otg_core_if_t *core_if = otg_dev->core_if;
return 0;
}
}
if (driver_create_file(&dwc_otg_driver.driver, &driver_attr_version))
pr_warning("DWC_OTG: Failed to create driver version file\n");
+ if (driver_create_file(&dwc_otg_driver.driver, &driver_attr_debuglevel))
+ pr_warning("DWC_OTG: Failed to create driver debug level file\n");
#ifdef DWC_BOTH_HOST_SLAVE
- driver_create_file(&dwc_otg_driver.driver, &driver_attr_force_usb_mode);
+ retval = driver_create_file(&dwc_otg_driver.driver, &driver_attr_force_usb_mode);
#endif
#ifdef CONFIG_RK2818_HOST11
printk(KERN_ERR "%s retval=%d\n", __func__, retval);
return retval;
}
- if (driver_create_file(&rk28_host11_driver.driver, &driver_attr_version))
- pr_warning("DWC_OTG: Failed to create driver version file\n");
+ retval = driver_create_file(&rk28_host11_driver.driver, &driver_attr_enable_usb11);
#endif
return retval;
}
printk(KERN_DEBUG "dwc_otg_driver_cleanup()\n");
driver_remove_file(&dwc_otg_driver.driver, &driver_attr_version);
+ driver_remove_file(&dwc_otg_driver.driver, &driver_attr_debuglevel);
#ifdef DWC_BOTH_HOST_SLAVE
driver_remove_file(&dwc_otg_driver.driver, &driver_attr_force_usb_mode);
#endif
static int dwc_otg_hcd_suspend(struct usb_hcd *hcd)
{
- return 0;
+#if 1
+ dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd (hcd);
+ 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)
+ {
+ printk("%s, usb device mode\n", __func__);
+ return 0;
+ }
+ hprt0.d32 = dwc_read_reg32(core_if->host_if->hprt0);
+ DWC_PRINT("%s, HPRT0:0x%x\n",__func__,hprt0.d32);
+ //partial power-down
+ if(!hprt0.b.prtsusp)
+ {
+ //hprt0.d32 = 0;
+ hprt0.b.prtsusp = 1;
+ hprt0.b.prtena = 0;
+ dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
+ }
+ udelay(10);
+ hprt0.d32 = dwc_read_reg32(core_if->host_if->hprt0);
+ DWC_PRINT("%s, HPRT0:0x%x\n",__func__,hprt0.d32);
+ if(!hprt0.b.prtsusp)
+ {
+ //hprt0.d32 = 0;
+ hprt0.b.prtsusp = 1;
+ hprt0.b.prtena = 0;
+ dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
+ }
+ mdelay(5);
+#if 1
+ pcgcctl.d32 = dwc_read_reg32(core_if->pcgcctl);
+ pcgcctl.b.pwrclmp = 1;//power clamp
+ dwc_write_reg32(core_if->pcgcctl, pcgcctl.d32);
+ udelay(1);
+ //pcgcctl.b.rstpdwnmodule = 1;//reset PDM
+ pcgcctl.b.stoppclk = 1;//stop phy clk
+ dwc_write_reg32(core_if->pcgcctl, pcgcctl.d32);
+#endif
+#endif
+ //power off
+ return 0;
}
static int dwc_otg_hcd_resume(struct usb_hcd *hcd)
{
+#if 1
+ dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd (hcd);
+ dwc_otg_core_if_t *core_if = dwc_otg_hcd->core_if;
+ hprt0_data_t hprt0;
+ pcgcctl_data_t pcgcctl;
+ gintmsk_data_t gintmsk;
+
+ if(core_if->op_state == B_PERIPHERAL)
+ {
+ printk("%s, usb device mode\n", __func__);
+ return 0;
+ }
+#if 1
+ //partial power-down
+ //power on
+ pcgcctl.d32 = dwc_read_reg32(core_if->pcgcctl);;
+ pcgcctl.b.stoppclk = 0;//stop phy clk
+ dwc_write_reg32(core_if->pcgcctl, pcgcctl.d32);
+ udelay(1);
+ pcgcctl.b.pwrclmp = 0;//power clamp
+ 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);
+
+ hprt0.d32 = dwc_read_reg32(core_if->host_if->hprt0);
+ DWC_PRINT("%s, HPRT0:0x%x\n",__func__,hprt0.d32);
+ hprt0.b.prtpwr = 1;
+ hprt0.b.prtres = 1;
+ hprt0.b.prtena = 0;
+ dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
+ mdelay(20);
+ hprt0.d32 = dwc_read_reg32(core_if->host_if->hprt0);
+ DWC_PRINT("%s, HPRT0:0x%x\n",__func__,hprt0.d32);
+ //hprt0.d32 = 0;
+ hprt0.b.prtpwr = 1;
+ hprt0.b.prtres = 0;
+ hprt0.b.prtena = 0;
+ dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
+ hprt0.d32 = 0;
+ hprt0.b.prtpwr = 1;
+ hprt0.b.prtena = 0;
+ hprt0.b.prtconndet = 1;
+ dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
+
+ hprt0.d32 = dwc_read_reg32(core_if->host_if->hprt0);
+ DWC_PRINT("%s, HPRT0:0x%x\n",__func__,hprt0.d32);
+
+ gintmsk.b.portintr = 1;
+ dwc_write_reg32(&core_if->core_global_regs->gintmsk, gintmsk.d32);
+ mdelay(10);
+#endif
return 0;
}
dwc_hc_t *channel;
int retval = 0;
- printk("dwc_otg_hcd_init everest\n");
-// g_dbg_lvl = 0xff;
-
- DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD INIT\n");
#if 1 //kaiker .these code must execute before usb_create_hcd
/* Set device flags indicating whether the HCD supports DMA. */
static u64 usb_dmamask = 0xffffffffUL;
dev->coherent_dma_mask = 0;
}
#endif
+ printk("dwc_otg_hcd_init everest\n");
+// g_dbg_lvl = 0xff;
+
+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD INIT\n");
/*
* Allocate memory for the base HCD plus the DWC OTG HCD.
/* Initialize the DWC OTG HCD. */
dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
+
+ spin_lock_init(&dwc_otg_hcd->global_lock);
+
dwc_otg_hcd->core_if = otg_dev->core_if;
otg_dev->hcd = dwc_otg_hcd;
dwc_hc_t *channel;
int retval = 0;
- printk("%s everest\n",__func__);
-// g_dbg_lvl = 0xff;
-
- DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD INIT\n");
#if 1 //kaiker .these code must execute before usb_create_hcd
/* Set device flags indicating whether the HCD supports DMA. */
static u64 usb_dmamask = 0xffffffffUL;
dev->coherent_dma_mask = 0;
}
#endif
+ printk("%s everest\n",__func__);
+// g_dbg_lvl = 0xff;
+
+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD INIT\n");
/*
* Allocate memory for the base HCD plus the DWC OTG HCD.
dwc_otg_hcd->core_if = otg_dev->core_if;
otg_dev->hcd = dwc_otg_hcd;
+ spin_lock_init(&dwc_otg_hcd->global_lock);
+
+
/* Register the HCD CIL Callbacks */
dwc_otg_cil_register_hcd_callbacks(otg_dev->core_if,
&rk28_host11_cil_callbacks, hcd);
{
dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd (_hcd);
dwc_otg_core_if_t *core_if = dwc_otg_hcd->core_if;
+ unsigned long flags;
struct usb_device *udev;
struct usb_bus *bus;
DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD START\n");
+ spin_lock_irqsave(&dwc_otg_hcd->global_lock, flags);
#if 0
unsigned int regvalue;
printk("__________________________________________________________________\n");
}
hcd_reinit(dwc_otg_hcd);
out:
+ spin_unlock_irqrestore(&dwc_otg_hcd->global_lock, flags);
return 0;
}
retval = usb_hcd_link_urb_to_ep(_hcd, _urb);
if (retval)
+ {
+ printk("%s, usb_hcd_link_urb_to_ep error\n", __func__);
return retval;
- local_irq_save(flags);
+ }
+ spin_lock_irqsave(&dwc_otg_hcd->global_lock, flags);
#if 1
/*
* Make sure the start of frame interrupt is enabled now that
dwc_otg_hcd_qtd_free(qtd);
}
out:
- local_irq_restore(flags);
+ spin_unlock_irqrestore(&dwc_otg_hcd->global_lock, flags);
+
return retval;
}
return -1;
}
qh = (dwc_otg_qh_t *) _ep->hcpriv;
- local_irq_save(flags);
+ spin_lock_irqsave(&dwc_otg_hcd->global_lock, flags);
retval = usb_hcd_check_unlink_urb(_hcd, _urb, _status);
if (retval) {
- local_irq_restore(flags);
+ spin_unlock_irqrestore(&dwc_otg_hcd->global_lock, flags);
return retval;
}
dwc_otg_hcd_qh_remove(dwc_otg_hcd, qh);
}
#endif
- local_irq_restore(flags);
+ spin_unlock_irqrestore(&dwc_otg_hcd->global_lock, flags);
_urb->hcpriv = NULL;
usb_hcd_unlink_urb_from_ep(_hcd, _urb);
/* Higher layer software sets URB status. */
struct usb_host_endpoint *_ep)
{
+ unsigned long flags;
dwc_otg_qh_t *qh;
dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(_hcd);
+ spin_lock_irqsave(&dwc_otg_hcd->global_lock, flags);
+
DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD EP DISABLE: _bEndpointAddress=0x%02x, "
"endpoint=%d\n", _ep->desc.bEndpointAddress,
dwc_ep_addr_to_endpoint(_ep->desc.bEndpointAddress));
_ep->hcpriv = NULL;
}
+ spin_unlock_irqrestore(&dwc_otg_hcd->global_lock, flags);
+
return;
}
* interrupt.
*
* This function is called by the USB core when an interrupt occurs */
-irqreturn_t dwc_otg_hcd_irq(struct usb_hcd *_hcd,
- struct pt_regs *_regs)
+irqreturn_t dwc_otg_hcd_irq(struct usb_hcd *_hcd)
{
+ irqreturn_t result;
+ unsigned long flags;
dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd (_hcd);
- return IRQ_RETVAL(dwc_otg_hcd_handle_intr(dwc_otg_hcd));
+
+ spin_lock_irqsave(&dwc_otg_hcd->global_lock, flags);
+
+ result = IRQ_RETVAL(dwc_otg_hcd_handle_intr(dwc_otg_hcd));
+
+ spin_unlock_irqrestore(&dwc_otg_hcd->global_lock, flags);
+
+ return result;
}
/** Creates Status Change bitmap for the root hub and root port. The bitmap is
u16 _wLength)
{
int retval = 0;
+ unsigned long flags;
dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd (_hcd);
dwc_otg_core_if_t *core_if = hcd_to_dwc_otg_hcd (_hcd)->core_if;
hprt0_data_t hprt0 = {.d32 = 0};
uint32_t port_status;
+ spin_lock_irqsave(&dwc_otg_hcd->global_lock, flags);
switch (_typeReq) {
case ClearHubFeature:
break;
}
+ spin_unlock_irqrestore(&dwc_otg_hcd->global_lock, flags);
return retval;
}
qh_ptr = _hcd->non_periodic_sched_inactive.next;
num_channels = _hcd->core_if->core_params->host_channels;
while (qh_ptr != &_hcd->non_periodic_sched_inactive &&
+ /*yk@rk 20100714
(_hcd->non_periodic_channels <
num_channels - _hcd->periodic_channels) &&
+ */
!list_empty(&_hcd->free_hc_list)) {
+
+ if((num_channels > 2)&&(_hcd->non_periodic_channels >=
+ num_channels - _hcd->periodic_channels))
+ break;
qh = list_entry(qh_ptr, dwc_otg_qh_t, qh_list_entry);
assign_and_init_hc(_hcd, qh);
/* Tasket to do a reset */
struct tasklet_struct *reset_tasklet;
+ spinlock_t global_lock;
+
#ifdef DEBUG
uint32_t frrem_samples;
uint64_t frrem_accum;
int status);
extern void dwc_otg_hcd_endpoint_disable(struct usb_hcd *hcd,
struct usb_host_endpoint *ep);
-extern irqreturn_t dwc_otg_hcd_irq(struct usb_hcd *hcd,
- struct pt_regs *regs);
+extern irqreturn_t dwc_otg_hcd_irq(struct usb_hcd *hcd);
extern int dwc_otg_hcd_hub_status_data(struct usb_hcd *hcd,
char *buf);
extern int dwc_otg_hcd_hub_control(struct usb_hcd *hcd,
if (dwc_otg_is_host_mode(core_if)) {
gintsts.d32 = dwc_otg_read_core_intr(core_if);
if (!gintsts.d32) {
+ DWC_PRINT("%s,GINTSTS = 0\n",__func__);
return 0;
}
* host channel interrupt and handles them appropriately. */
int32_t dwc_otg_hcd_handle_hc_intr (dwc_otg_hcd_t *_dwc_otg_hcd)
{
- int hcnum;
+ int i;
int retval = 0;
- struct list_head *qh_entry;
- dwc_otg_qh_t *qh;
haint_data_t haint;
/* Clear appropriate bits in HCINTn to clear the interrupt bit in
* GINTSTS */
haint.d32 = dwc_otg_read_host_all_channels_intr(_dwc_otg_hcd->core_if);
-
+#if 1
+ for (i = 0; i < _dwc_otg_hcd->core_if->core_params->host_channels; i++) {
+ if (haint.b2.chint & (1 << i))
+ retval |= dwc_otg_hcd_handle_hc_n_intr(_dwc_otg_hcd, i);
+ }
+#else
+ int hcnum;
+ struct list_head *qh_entry;
+ dwc_otg_qh_t *qh;
/* yk@rk 20100511
* USB Spec2.0 11.18.4
* for all periodic endpoints that have split transactions scheduled within
retval |= dwc_otg_hcd_handle_hc_n_intr (_dwc_otg_hcd, hcnum);
}
}
+#endif
return retval;
}
dwc_otg_transaction_type_e tr_type;
int free_qtd;
+ int continue_trans = 0;
+
DWC_DEBUGPL(DBG_HCDV, " %s: channel %d, halt_status %d\n",
__func__, _hc->hc_num, _halt_status);
-
+ if((!_hc->halt_pending)||
+// (!list_empty(&_hcd->non_periodic_sched_inactive))
+ (_hcd->core_if->core_params->host_channels > 2)||
+ (!_hc->ep_is_in)||
+ (_hc->ep_type != DWC_OTG_EP_TYPE_BULK)
+ )
+ {
+ continue_trans = 1;
+ }
switch (_halt_status) {
case DWC_OTG_HC_XFER_URB_COMPLETE:
free_qtd = 1;
*/
break;
}
-
- /* Try to queue more transfers now that there's a free channel. */
- tr_type = dwc_otg_hcd_select_transactions(_hcd);
- if (tr_type != DWC_OTG_TRANSACTION_NONE) {
- dwc_otg_hcd_queue_transactions(_hcd, tr_type);
+ if(continue_trans)
+ {
+ /* Try to queue more transfers now that there's a free channel. */
+ tr_type = dwc_otg_hcd_select_transactions(_hcd);
+ if (tr_type != DWC_OTG_TRANSACTION_NONE) {
+ dwc_otg_hcd_queue_transactions(_hcd, tr_type);
+ }
}
+ /*
+ * Make sure the start of frame interrupt is enabled now that
+ * we know we should have queued data. The SOF interrupt
+ * handler automatically disables itself when idle to reduce
+ * the number of interrupts. See dwc_otg_hcd_handle_sof_intr()
+ * for the disable
+ */
+ dwc_modify_reg32(&_hcd->core_if->core_global_regs->gintmsk, 0,
+ DWC_SOF_INTR_MASK);
}
/**
* occurs. The core will continue transferring data.
*/
_qtd->error_count = 0;
+ //yk@rk 20100714
+ #if 1
+ if((_hcd->core_if->core_params->host_channels <= 2)
+ &&(!_hc->halt_pending))
+ dwc_otg_hc_halt(_hcd->core_if, _hc, DWC_OTG_HC_XFER_NAK);
+ #endif
goto handle_nak_done;
}
}
handle_nak_done:
+ clear_hc_int(_hc_regs,nak);
+ if(_hcd->core_if->core_params->host_channels > 2)
disable_hc_int(_hc_regs,nak);
return 1;
hcint.d32 = dwc_read_reg32(&_hc_regs->hcint);
hcintmsk.d32 = dwc_read_reg32(&_hc_regs->hcintmsk);
+ if((!hcint.b.xfercomp)&&
+ (_hcd->core_if->core_params->host_channels <= 2)&&
+ (_hc->halt_pending)&&
+ (_hc->ep_is_in)&&
+ (_hc->ep_type == DWC_OTG_EP_TYPE_BULK))
+ {
+ if(hcint.b.ack && !hcintmsk.b.ack)
+ {
+ //DWC_PRINT("Halt pending, ack!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
+ handle_hc_xfercomp_intr(_hcd, _hc, _hc_regs, _qtd);
+ return;
+ }
+ release_channel(_hcd, _hc, _qtd, DWC_OTG_HC_XFER_NAK);
+ clear_hc_int(_hc_regs,chhltd);
+ return;
+ }
+
if (hcint.b.xfercomp) {
/** @todo This is here because of a possible hardware bug. Spec
* says that on SPLIT-ISOC OUT transfers in DMA mode that a HALT
* split transfers. Start splits halt on ACK.
*/
handle_hc_ack_intr(_hcd, _hc, _hc_regs, _qtd);
+ } else if(hcint.b.datatglerr){
+ DWC_PRINT("%s, DATA toggle error\n");
+ dwc_debug(1);
+ clear_hc_int(_hc_regs,chhltd);
} else {
if (_hc->ep_type == DWC_OTG_EP_TYPE_INTR ||
_hc->ep_type == DWC_OTG_EP_TYPE_ISOC) {
"for halting is unknown, hcint 0x%08x, intsts 0x%08x\n",
__func__, _hc->hc_num, hcint.d32,
dwc_read_reg32(&_hcd->core_if->core_global_regs->gintsts));
+ clear_hc_int(_hc_regs,chhltd);
}
}
}
{
dwc_otg_qtd_t *qtd;
struct list_head *pos;
- unsigned long flags;
/* Free each QTD in the QTD list */
- local_irq_save (flags);
for (pos = _qh->qtd_list.next;
pos != &_qh->qtd_list;
pos = _qh->qtd_list.next)
qtd = dwc_list_to_qtd (pos);
dwc_otg_hcd_qtd_free (qtd);
}
- local_irq_restore (flags);
kfree (_qh);
return;
/* yk@rk 20100625
* _urb->dev->tt->hub may be null
*/
+ if((_urb->dev->tt)&&(!_urb->dev->tt->hub))
+ printk("%s tt->hub null!\n",__func__);
if (((_urb->dev->speed == USB_SPEED_LOW) ||
(_urb->dev->speed == USB_SPEED_FULL)) &&
(_urb->dev->tt) && (_urb->dev->tt->hub)&&
/** @todo Account for split transfers in the bus time. */
int bytecount = dwc_hb_mult(_qh->maxp) * dwc_max_packet(_qh->maxp);
+ /*
+ * The results from usb_calc_bus_time are in nanosecs,
+ * so divide the result by 1000 to convert to
+ * microsecs expected by this driver
+ */
_qh->usecs = usb_calc_bus_time(_urb->dev->speed,
usb_pipein(_urb->pipe),
(_qh->ep_type == USB_ENDPOINT_XFER_ISOC),
- bytecount);
+ bytecount) / 1000;
/* Start in a slightly future (micro)frame. */
_qh->sched_frame = dwc_frame_num_inc(_hcd->frame_number,
* non-periodic transactions.
*/
int status;
+/*yk@rk modified for usb host 1.1*/
+#if 0
int num_channels;
-
num_channels = _hcd->core_if->core_params->host_channels;
if ((_hcd->periodic_channels + _hcd->non_periodic_channels < num_channels) &&
(_hcd->periodic_channels < num_channels - 1)) {
_hcd->non_periodic_channels);
status = -ENOSPC;
}
-
+#else
+ status = 0;
+#endif
return status;
}
*/
int dwc_otg_hcd_qh_add (dwc_otg_hcd_t *_hcd, dwc_otg_qh_t *_qh)
{
- //unsigned long flags;
int status = 0;
- //local_irq_save(flags);
+ if (!spin_is_locked(&_hcd->global_lock)) {
+ //pr_err("%s don't have hcd->global_lock\n", __func__);
+ //BUG();
+ }
if (!list_empty(&_qh->qh_list_entry)) {
/* QH already in a schedule. */
* @param[in] _qh QH to remove from schedule. */
void dwc_otg_hcd_qh_remove (dwc_otg_hcd_t *_hcd, dwc_otg_qh_t *_qh)
{
- unsigned long flags;
-
- local_irq_save(flags);
+ if (!spin_is_locked(&_hcd->global_lock)) {
+ //pr_err("%s don't have hcd->global_lock\n", __func__);
+ //BUG();
+ }
if (list_empty(&_qh->qh_list_entry)) {
/* QH is not in a schedule. */
}
done:
- local_irq_restore(flags);
+ ;
}
/**
*/
void dwc_otg_hcd_qh_deactivate(dwc_otg_hcd_t *_hcd, dwc_otg_qh_t *_qh, int sched_next_periodic_split)
{
- unsigned long flags;
- local_irq_save(flags);
-
+ if (!spin_is_locked(&_hcd->global_lock)) {
+ //pr_err("%s don't have hcd->global_lock\n", __func__);
+ //BUG();
+ }
if (dwc_qh_is_non_per(_qh)) {
dwc_otg_hcd_qh_remove(_hcd, _qh);
if (!list_empty(&_qh->qtd_list)) {
/* Add back to inactive non-periodic schedule. */
dwc_otg_hcd_qh_add(_hcd, _qh);
+ return;
}
} else {
uint16_t frame_number = dwc_otg_hcd_get_frame_number(dwc_otg_hcd_to_hcd(_hcd));
}
}
- local_irq_restore(flags);
+
}
/**
ep->dwc_ep.tx_fifo_num = assign_tx_fifo(pcd->otg_dev->core_if);
}
#endif
- ep->dwc_ep.tx_fifo_num = ep->dwc_ep.num ; /* 1,3,5 */
+ /* yk@rk
+ * ep0 -- tx fifo 0
+ * ep1 -- tx fifo 1
+ * ep3 -- tx fifo 2
+ * ep5 -- tx fifo 3
+ */
+ if(ep->dwc_ep.num == 0)
+ ep->dwc_ep.tx_fifo_num = 0;
+ else
+ ep->dwc_ep.tx_fifo_num = (ep->dwc_ep.num>>1)+1 ; /* 1,3,5 */
}
/* Set initial data PID. */
if ((_desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
* @param _gfp_flags the GFP_* flags to use.
*/
static struct usb_request *dwc_otg_pcd_alloc_request(struct usb_ep *_ep,
- int _gfp_flags)
+ gfp_t _gfp_flags)
{
dwc_otg_pcd_request_t *req;
DWC_DEBUGPL(DBG_PCDV,"%s(%p,%d)\n", __func__, _ep, _gfp_flags);
* flag.
*/
static int dwc_otg_pcd_ep_queue(struct usb_ep *_ep,
- struct usb_request *_req, int _gfp_flags)
+ struct usb_request *_req, gfp_t _gfp_flags)
{
int prevented = 0;
dwc_otg_pcd_request_t *req;
/* 20091226,HSL@RK */
if ( !list_empty(&req->queue) )
{
- return -EINVAL;
- printk("%s::req not empty,done it error!\n" , __func__ );
- while(!list_empty(&req->queue) ) {
- ep = container_of(_ep, dwc_otg_pcd_ep_t, ep);
- request_done(ep, req, -ECONNABORTED);
- }
-
+ printk("%s::ep %s req not empty,done it error!\n" , __func__, _ep->name);
+ return -EINVAL;
+ while(!list_empty(&req->queue) ) {
+ ep = container_of(_ep, dwc_otg_pcd_ep_t, ep);
+ request_done(ep, req, -ECONNABORTED);
+ }
}
ep = container_of(_ep, dwc_otg_pcd_ep_t, ep);
* This function is the top level PCD interrupt handler.
*/
static irqreturn_t
-dwc_otg_pcd_irq(int _irq, void *_dev, struct pt_regs *_r)
+dwc_otg_pcd_irq(int _irq, void *_dev)
{
dwc_otg_pcd_t *pcd = _dev;
int32_t retval = IRQ_NONE;
static void dwc_phy_reconnect(struct work_struct *work)
{
- dwc_otg_pcd_t *pcd = container_of(work, dwc_otg_pcd_t, reconnect.work);;
- dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
+ dwc_otg_pcd_t *pcd;
+ dwc_otg_core_if_t *core_if;
gotgctl_data_t gctrl;
dctl_data_t dctl = {.d32=0};
+ pcd = container_of(work, dwc_otg_pcd_t, reconnect.work);
+ core_if = GET_CORE_IF(pcd);
gctrl.d32 = dwc_read_reg32( &core_if->core_global_regs->gotgctl );
if( gctrl.b.bsesvld ) {
dwc_otg_msc_lock();
return 0;
}
#else
+int dwc_otg_set_vbus_status(int status)
+{
+ return 0;
+}
int rk28_usb_suspend( int exitsuspend )
{
return 0;
#include "dwc_otg_pcd.h"
-#define DEBUG_EP0
+//#define DEBUG_EP0
/* request functions defined in "dwc_otg_pcd.c" */
extern void request_done( dwc_otg_pcd_ep_t *_ep, dwc_otg_pcd_request_t *_req,
gusbcfg.d32 = dwc_read_reg32(&global_regs->gusbcfg);
if (_pcd->gadget.speed == USB_SPEED_HIGH)
{
+ depctl.b.mps = 0x200;
if (GET_CORE_IF(_pcd)->hwcfg2.b.hs_phy_type == DWC_HWCFG2_HS_PHY_TYPE_ULPI)
{
/* ULPI interface */
}
else
{
+ depctl.b.mps = 0x40;
/* Full or low speed */
gusbcfg.b.usbtrdtim = 9;
}
dwc_write_reg32( &GET_CORE_IF(_pcd)->core_global_regs->gintsts,
gintsts.d32 );
/* enable ep2out */
- depctl.d32 = 0;
depctl.b.setd0pid = 1;
dwc_write_reg32( &GET_CORE_IF(_pcd)->dev_if->in_ep_regs[1]->diepctl, depctl.d32);
depctl.b.snak = 1;
depctl.b.txfnum = 2;
depctl.b.eptype = 2;
depctl.b.usbactep = 1;
- depctl.b.mps = 0x200;
dwc_write_reg32( &GET_CORE_IF(_pcd)->dev_if->out_ep_regs[2]->doepctl, depctl.d32 );
return 1;
}
* All interrupt registers are processed from LSB to MSB.
*
*/
- extern void dwc_otg_dump_global_registers(dwc_otg_core_if_t *_core_if);
int32_t dwc_otg_pcd_handle_intr( dwc_otg_pcd_t *_pcd )
{
dwc_otg_core_if_t *core_if = GET_CORE_IF(_pcd);
#define HAIER_VENDOR_ID 0x201e
#define HAIER_PRODUCT_CE100 0x2009
+/* Thinkwill products */
+#define THINKWILL_VENDOR_ID 0x19f5
+#define THINKWILL_PRODUCT_ID 0x9909
+
static struct usb_device_id option_ids[] = {
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) },
+ { USB_DEVICE(THINKWILL_VENDOR_ID,THINKWILL_PRODUCT_ID)},
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) },
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA_LIGHT) },
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA_QUAD) },