⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 isp116x-hcd.c

📁 U-boot源码 ARM7启动代码
💻 C
📖 第 1 页 / 共 3 页
字号:
		isp116x_show_regs(isp116x);		break;	case RH_SET_FEATURE | RH_OTHER | RH_CLASS:		DBG("RH_SET_FEATURE | RH_OTHER | RH_CLASS");		switch (wValue) {		case RH_PORT_SUSPEND:			isp116x_write_reg32(isp116x, HCRHPORT1 + wIndex - 1,					    RH_PS_PSS);			len = 0;			break;		case RH_PORT_RESET:			/* Spin until any current reset finishes */			while (1) {				tmp =				    isp116x_read_reg32(isp116x,						       HCRHPORT1 + wIndex - 1);				if (!(tmp & RH_PS_PRS))					break;				wait_ms(1);			}			isp116x_write_reg32(isp116x, HCRHPORT1 + wIndex - 1,					    RH_PS_PRS);			wait_ms(10);			len = 0;			break;		case RH_PORT_POWER:			isp116x_write_reg32(isp116x, HCRHPORT1 + wIndex - 1,					    RH_PS_PPS);			len = 0;			break;		case RH_PORT_ENABLE:			isp116x_write_reg32(isp116x, HCRHPORT1 + wIndex - 1,					    RH_PS_PES);			len = 0;			break;		default:			ERR("invalid wValue");			stat = USB_ST_STALLED;		}		isp116x_show_regs(isp116x);		break;	case RH_SET_ADDRESS:		DBG("RH_SET_ADDRESS");		rh_devnum = wValue;		len = 0;		break;	case RH_GET_DESCRIPTOR:		DBG("RH_GET_DESCRIPTOR: %x, %d", wValue, wLength);		switch (wValue) {		case (USB_DT_DEVICE << 8):	/* device descriptor */			len = min_t(unsigned int,				    leni, min_t(unsigned int,						sizeof(root_hub_dev_des),						wLength));			data_buf = root_hub_dev_des;			break;		case (USB_DT_CONFIG << 8):	/* configuration descriptor */			len = min_t(unsigned int,				    leni, min_t(unsigned int,						sizeof(root_hub_config_des),						wLength));			data_buf = root_hub_config_des;			break;		case ((USB_DT_STRING << 8) | 0x00):	/* string 0 descriptors */			len = min_t(unsigned int,				    leni, min_t(unsigned int,						sizeof(root_hub_str_index0),						wLength));			data_buf = root_hub_str_index0;			break;		case ((USB_DT_STRING << 8) | 0x01):	/* string 1 descriptors */			len = min_t(unsigned int,				    leni, min_t(unsigned int,						sizeof(root_hub_str_index1),						wLength));			data_buf = root_hub_str_index1;			break;		default:			ERR("invalid wValue");			stat = USB_ST_STALLED;		}		break;	case RH_GET_DESCRIPTOR | RH_CLASS:		DBG("RH_GET_DESCRIPTOR | RH_CLASS");		tmp = isp116x_read_reg32(isp116x, HCRHDESCA);		data_buf[0] = 0x09;	/* min length; */		data_buf[1] = 0x29;		data_buf[2] = tmp & RH_A_NDP;		data_buf[3] = 0;		if (tmp & RH_A_PSM)	/* per-port power switching? */			data_buf[3] |= 0x01;		if (tmp & RH_A_NOCP)	/* no overcurrent reporting? */			data_buf[3] |= 0x10;		else if (tmp & RH_A_OCPM)	/* per-port overcurrent rep? */			data_buf[3] |= 0x08;		/* Corresponds to data_buf[4-7] */		datab[1] = 0;		data_buf[5] = (tmp & RH_A_POTPGT) >> 24;		tmp = isp116x_read_reg32(isp116x, HCRHDESCB);		data_buf[7] = tmp & RH_B_DR;		if (data_buf[2] < 7)			data_buf[8] = 0xff;		else {			data_buf[0] += 2;			data_buf[8] = (tmp & RH_B_DR) >> 8;			data_buf[10] = data_buf[9] = 0xff;		}		len = min_t(unsigned int, leni,			    min_t(unsigned int, data_buf[0], wLength));		break;	case RH_GET_CONFIGURATION:		DBG("RH_GET_CONFIGURATION");		*(__u8 *) data_buf = 0x01;		len = 1;		break;	case RH_SET_CONFIGURATION:		DBG("RH_SET_CONFIGURATION");		isp116x_write_reg32(isp116x, HCRHSTATUS, RH_HS_LPSC);		len = 0;		break;	default:		ERR("*** *** *** unsupported root hub command *** *** ***");		stat = USB_ST_STALLED;	}	len = min_t(int, len, leni);	if (buffer != data_buf)		memcpy(buffer, data_buf, len);	dev->act_len = len;	dev->status = stat;	DBG("dev act_len %d, status %d", dev->act_len, dev->status);	dump_msg(dev, pipe, buffer, transfer_len, "RH(ret)");	return stat;}/* --- Transfer functions -------------------------------------------------- */int submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer,		   int len, int interval){	DBG("dev=%p pipe=%#lx buf=%p size=%d int=%d",	    dev, pipe, buffer, len, interval);	return -1;}int submit_control_msg(struct usb_device *dev, unsigned long pipe, void *buffer,		       int len, struct devrequest *setup){	int devnum = usb_pipedevice(pipe);	int epnum = usb_pipeendpoint(pipe);	int max = max_transfer_len(dev, pipe);	int dir_in = usb_pipein(pipe);	int done, ret;	/* Control message is for the HUB? */	if (devnum == rh_devnum)		return isp116x_submit_rh_msg(dev, pipe, buffer, len, setup);	/* Ok, no HUB message so send the message to the device */	/* Setup phase */	DBG("--- SETUP PHASE --------------------------------");	usb_settoggle(dev, epnum, 1, 0);	ret = isp116x_submit_job(dev, pipe,				 PTD_DIR_SETUP,				 setup, sizeof(struct devrequest));	if (ret < 0) {		DBG("control setup phase error (ret = %d", ret);		return -1;	}	/* Data phase */	DBG("--- DATA PHASE ---------------------------------");	done = 0;	usb_settoggle(dev, epnum, !dir_in, 1);	while (done < len) {		ret = isp116x_submit_job(dev, pipe,					 dir_in ? PTD_DIR_IN : PTD_DIR_OUT,					 (__u8 *) buffer + done,					 max > len - done ? len - done : max);		if (ret < 0) {			DBG("control data phase error (ret = %d)", ret);			return -1;		}		done += ret;		if (dir_in && ret < max)	/* short packet */			break;	}	/* Status phase */	DBG("--- STATUS PHASE -------------------------------");	usb_settoggle(dev, epnum, !dir_in, 1);	ret = isp116x_submit_job(dev, pipe,				 !dir_in ? PTD_DIR_IN : PTD_DIR_OUT, NULL, 0);	if (ret < 0) {		DBG("control status phase error (ret = %d", ret);		return -1;	}	dev->act_len = done;	dump_msg(dev, pipe, buffer, len, "DEV(ret)");	return done;}int submit_bulk_msg(struct usb_device *dev, unsigned long pipe, void *buffer,		    int len){	int dir_out = usb_pipeout(pipe);	int max = max_transfer_len(dev, pipe);	int done, ret;	DBG("--- BULK ---------------------------------------");	DBG("dev=%ld pipe=%ld buf=%p size=%d dir_out=%d",	    usb_pipedevice(pipe), usb_pipeendpoint(pipe), buffer, len, dir_out);	done = 0;	while (done < len) {		ret = isp116x_submit_job(dev, pipe,					 !dir_out ? PTD_DIR_IN : PTD_DIR_OUT,					 (__u8 *) buffer + done,					 max > len - done ? len - done : max);		if (ret < 0) {			DBG("error on bulk message (ret = %d)", ret);			return -1;		}		done += ret;		if (!dir_out && ret < max)	/* short packet */			break;	}	dev->act_len = done;	return 0;}/* --- Basic functions ----------------------------------------------------- */static int isp116x_sw_reset(struct isp116x *isp116x){	int retries = 15;	int ret = 0;	DBG("");	isp116x->disabled = 1;	isp116x_write_reg16(isp116x, HCSWRES, HCSWRES_MAGIC);	isp116x_write_reg32(isp116x, HCCMDSTAT, HCCMDSTAT_HCR);	while (--retries) {		/* It usually resets within 1 ms */		wait_ms(1);		if (!(isp116x_read_reg32(isp116x, HCCMDSTAT) & HCCMDSTAT_HCR))			break;	}	if (!retries) {		ERR("software reset timeout");		ret = -1;	}	return ret;}static int isp116x_reset(struct isp116x *isp116x){	unsigned long t;	u16 clkrdy = 0;	int ret, timeout = 15 /* ms */ ;	DBG("");	ret = isp116x_sw_reset(isp116x);	if (ret)		return ret;	for (t = 0; t < timeout; t++) {		clkrdy = isp116x_read_reg16(isp116x, HCuPINT) & HCuPINT_CLKRDY;		if (clkrdy)			break;		wait_ms(1);	}	if (!clkrdy) {		ERR("clock not ready after %dms", timeout);		/* After sw_reset the clock won't report to be ready, if		   H_WAKEUP pin is high. */		ERR("please make sure that the H_WAKEUP pin is pulled low!");		ret = -1;	}	return ret;}static void isp116x_stop(struct isp116x *isp116x){	u32 val;	DBG("");	isp116x_write_reg16(isp116x, HCuPINTENB, 0);	/* Switch off ports' power, some devices don't come up	   after next 'start' without this */	val = isp116x_read_reg32(isp116x, HCRHDESCA);	val &= ~(RH_A_NPS | RH_A_PSM);	isp116x_write_reg32(isp116x, HCRHDESCA, val);	isp116x_write_reg32(isp116x, HCRHSTATUS, RH_HS_LPS);	isp116x_sw_reset(isp116x);}/* *  Configure the chip. The chip must be successfully reset by now. */static int isp116x_start(struct isp116x *isp116x){	struct isp116x_platform_data *board = isp116x->board;	u32 val;	DBG("");	/* Clear interrupt status and disable all interrupt sources */	isp116x_write_reg16(isp116x, HCuPINT, 0xff);	isp116x_write_reg16(isp116x, HCuPINTENB, 0);	isp116x_write_reg16(isp116x, HCITLBUFLEN, ISP116x_ITL_BUFSIZE);	isp116x_write_reg16(isp116x, HCATLBUFLEN, ISP116x_ATL_BUFSIZE);	/* Hardware configuration */	val = HCHWCFG_DBWIDTH(1);	if (board->sel15Kres)		val |= HCHWCFG_15KRSEL;	/* Remote wakeup won't work without working clock */	if (board->remote_wakeup_enable)		val |= HCHWCFG_CLKNOTSTOP;	if (board->oc_enable)		val |= HCHWCFG_ANALOG_OC;	isp116x_write_reg16(isp116x, HCHWCFG, val);	/* --- Root hub configuration */	val = (25 << 24) & RH_A_POTPGT;	/* AN10003_1.pdf recommends RH_A_NPS (no power switching) to	   be always set. Yet, instead, we request individual port	   power switching. */	val |= RH_A_PSM;	/* Report overcurrent per port */	val |= RH_A_OCPM;	isp116x_write_reg32(isp116x, HCRHDESCA, val);	isp116x->rhdesca = isp116x_read_reg32(isp116x, HCRHDESCA);	val = RH_B_PPCM;	isp116x_write_reg32(isp116x, HCRHDESCB, val);	isp116x->rhdescb = isp116x_read_reg32(isp116x, HCRHDESCB);	val = 0;	if (board->remote_wakeup_enable)		val |= RH_HS_DRWE;	isp116x_write_reg32(isp116x, HCRHSTATUS, val);	isp116x->rhstatus = isp116x_read_reg32(isp116x, HCRHSTATUS);	isp116x_write_reg32(isp116x, HCFMINTVL, 0x27782edf);	/* Go operational */	val = HCCONTROL_USB_OPER;	if (board->remote_wakeup_enable)		val |= HCCONTROL_RWE;	isp116x_write_reg32(isp116x, HCCONTROL, val);	/* Disable ports to avoid race in device enumeration */	isp116x_write_reg32(isp116x, HCRHPORT1, RH_PS_CCS);	isp116x_write_reg32(isp116x, HCRHPORT2, RH_PS_CCS);	isp116x_show_regs(isp116x);	isp116x->disabled = 0;	return 0;}/* --- Init functions ------------------------------------------------------ */int isp116x_check_id(struct isp116x *isp116x){	int val;	val = isp116x_read_reg16(isp116x, HCCHIPID);	if ((val & HCCHIPID_MASK) != HCCHIPID_MAGIC) {		ERR("invalid chip ID %04x", val);		return -1;	}	return 0;}int usb_lowlevel_init(void){	struct isp116x *isp116x = &isp116x_dev;	DBG("");	got_rhsc = rh_devnum = 0;	/* Init device registers addr */	isp116x->addr_reg = (u16 *) ISP116X_HCD_ADDR;	isp116x->data_reg = (u16 *) ISP116X_HCD_DATA;	/* Setup specific board settings */#ifdef ISP116X_HCD_SEL15kRES	isp116x_board.sel15Kres = 1;#endif#ifdef ISP116X_HCD_OC_ENABLE	isp116x_board.oc_enable = 1;#endif#ifdef ISP116X_HCD_REMOTE_WAKEUP_ENABLE	isp116x_board.remote_wakeup_enable = 1;#endif	isp116x->board = &isp116x_board;	/* Try to get ISP116x silicon chip ID */	if (isp116x_check_id(isp116x) < 0)		return -1;	isp116x->disabled = 1;	isp116x->sleeping = 0;	isp116x_reset(isp116x);	isp116x_start(isp116x);	return 0;}int usb_lowlevel_stop(void){	struct isp116x *isp116x = &isp116x_dev;	DBG("");	if (!isp116x->disabled)		isp116x_stop(isp116x);	return 0;}#endif				/* CONFIG_USB_ISP116X_HCD */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -