void imx_udc_init_ep(struct imx_udc_struct *imx_usb)
{
	int i, max, temp;
	struct imx_ep_struct *imx_ep;
	for (i = 0; i < IMX_USB_NB_EP; i++) {
		imx_ep = &imx_usb->imx_ep[i];
		switch (imx_ep->fifosize) {
		case 8:
			max = 0;
			break;
		case 16:
			max = 1;
			break;
		case 32:
			max = 2;
			break;
		case 64:
			max = 3;
			break;
		default:
			max = 1;
			break;
		}
		temp = (EP_DIR(imx_ep) << 7) | (max << 5)
			| (imx_ep->bmAttributes << 3);
		__raw_writel(temp, imx_usb->base + USB_EP_STAT(i));
		__raw_writel(temp | EPSTAT_FLUSH,
						imx_usb->base + USB_EP_STAT(i));
		D_INI(imx_usb->dev, "<%s> ep%d_stat %08x\n", __func__, i,
			__raw_readl(imx_usb->base + USB_EP_STAT(i)));
	}
}
/* Reserve endpoint */
int usb_drv_request_endpoint(int type, int dir)
{
    int ep_num, ep_dir;
    int ep_type;

    /* Safety */
    ep_dir = EP_DIR(dir);
    ep_type = type & USB_ENDPOINT_XFERTYPE_MASK;

    logf("req: %s %s", XFER_DIR_STR(ep_dir), XFER_TYPE_STR(ep_type));
    
    /* Find an available ep/dir pair */
    for (ep_num=1;ep_num<USB_NUM_ENDPOINTS;ep_num++)
    {
        struct endpoint_t* endpoint = &endpoints[ep_num];
        
        if (endpoint->type == ep_type &&
            endpoint->dir == ep_dir &&
            !endpoint->allocated)
        {
            /* mark endpoint as taken */
            endpoint->allocated = true;
            
            /* enable interrupt from this endpoint */
            EN_INT |= (1<<(ep_num+7));
            
            logf("add: ep%d %s", ep_num, XFER_DIR_STR(ep_dir));
            return (ep_num | (dir & USB_ENDPOINT_DIR_MASK));
        }
    }
    return -1;
}
Beispiel #3
0
static void write_epcs(struct rt_ep_struct *rt_ep, u8 val)
{
	int idx = EP_NO(rt_ep);
	int dir = EP_DIR(rt_ep);

	if(idx == 0)
		usb_write(EP0CS, val);
	else
		(dir == EP_IN ? /*IN */ usb_write(0x7 + idx*8, val) : usb_write(0x3 + idx*8, val) );
}
Beispiel #4
0
static u8 read_epcs(struct rt_ep_struct *rt_ep)
{
	int idx = EP_NO(rt_ep);
	int dir = EP_DIR(rt_ep);

	if(idx == 0)
		return usb_read(EP0CS);

	return (dir == EP_IN ? usb_read(0x7 + idx*8) : usb_read(0x3 + idx*8) );
}
Beispiel #5
0
static struct rt_request *get_unhandled_req(struct rt_ep_struct *rt_ep)
{
	struct rt_request *req = NULL;

	if(EP_DIR(rt_ep) == EP_OUT)
		FATAL_ERROR("Out EP");

	if (!list_empty(&rt_ep->queue)){
		req = list_entry(rt_ep->queue.next, struct rt_request, queue);
	}else {
void imx_udc_config(struct imx_udc_struct *imx_usb)
{
	u8 ep_conf[5];
	u8 i, j, cfg;
	struct imx_ep_struct *imx_ep;

	/*                        */
	do {} while (!(__raw_readl(imx_usb->base + USB_DADR) & DADR_CFG));

	/*                                              */
	for (j = 0; j < 5; j++) {
		i = (j == 2 ? imx_usb->imx_ep[0].fifosize : 0x00);
		__raw_writeb(i, imx_usb->base + USB_DDAT);
		do {} while (__raw_readl(imx_usb->base + USB_DADR) & DADR_BSY);
	}

	/*                                                 
                                                
  */
	for (cfg = 1; cfg < 3; cfg++) {
		for (i = 1; i < IMX_USB_NB_EP; i++) {
			imx_ep = &imx_usb->imx_ep[i];
			/*                   */
			ep_conf[0] = (i << 4) | (cfg << 2);
			/*                  */
			ep_conf[1] = (imx_ep->bmAttributes << 3) |
					(EP_DIR(imx_ep) << 2);
			/*                 */
			ep_conf[2] = imx_ep->fifosize;
			/*        */
			ep_conf[3] = 0xC0;
			/*         */
			ep_conf[4] = i;

			D_INI(imx_usb->dev,
				"<%s> ep%d_conf[%d]:"
				"[%02x-%02x-%02x-%02x-%02x]\n",
				__func__, i, cfg,
				ep_conf[0], ep_conf[1], ep_conf[2],
				ep_conf[3], ep_conf[4]);

			for (j = 0; j < 5; j++) {
				__raw_writeb(ep_conf[j],
					imx_usb->base + USB_DDAT);
				do {} while (__raw_readl(imx_usb->base
								+ USB_DADR)
					& DADR_BSY);
			}
		}
	}

	/*                       */
	do {} while (__raw_readl(imx_usb->base + USB_DADR) & DADR_CFG);
}
void imx_udc_config(struct imx_udc_struct *imx_usb)
{
	u8 ep_conf[5];
	u8 i, j, cfg;
	struct imx_ep_struct *imx_ep;

	/* wait CFG bit to assert */
	do {} while (!(__raw_readl(imx_usb->base + USB_DADR) & DADR_CFG));

	/* Download the endpoint buffer for endpoint 0. */
	for (j = 0; j < 5; j++) {
		i = (j == 2 ? imx_usb->imx_ep[0].fifosize : 0x00);
		__raw_writeb(i, imx_usb->base + USB_DDAT);
		do {} while (__raw_readl(imx_usb->base + USB_DADR) & DADR_BSY);
	}

	/* Download the endpoint buffers for endpoints 1-5.
	 * We specify two configurations, one interface
	 */
	for (cfg = 1; cfg < 3; cfg++) {
		for (i = 1; i < IMX_USB_NB_EP; i++) {
			imx_ep = &imx_usb->imx_ep[i];
			/* EP no | Config no */
			ep_conf[0] = (i << 4) | (cfg << 2);
			/* Type | Direction */
			ep_conf[1] = (imx_ep->bmAttributes << 3) |
					(EP_DIR(imx_ep) << 2);
			/* Max packet size */
			ep_conf[2] = imx_ep->fifosize;
			/* TRXTYP */
			ep_conf[3] = 0xC0;
			/* FIFO no */
			ep_conf[4] = i;

			D_INI(imx_usb->dev,
				"<%s> ep%d_conf[%d]:"
				"[%02x-%02x-%02x-%02x-%02x]\n",
				__func__, i, cfg,
				ep_conf[0], ep_conf[1], ep_conf[2],
				ep_conf[3], ep_conf[4]);

			for (j = 0; j < 5; j++) {
				__raw_writeb(ep_conf[j],
					imx_usb->base + USB_DDAT);
				do {} while (__raw_readl(imx_usb->base
								+ USB_DADR)
					& DADR_BSY);
			}
		}
	}

	/* wait CFG bit to clear */
	do {} while (__raw_readl(imx_usb->base + USB_DADR) & DADR_CFG);
}
/* Free endpoint */
void usb_drv_release_endpoint(int ep)
{
    int ep_num = EP_NUM(ep);
    int ep_dir = EP_DIR(ep);

    logf("rel: ep%d %s", ep_num, XFER_DIR_STR(ep_dir));
    endpoints[ep_num].allocated = false;
    
    /* disable interrupt from this endpoint */
    EN_INT &= ~(1<<(ep_num+7));
}
Beispiel #9
0
static void rt_ep_rst(struct rt_ep_struct *rt_ep)
{
	u8 reg = 0;
	u8 idx = EP_NO(rt_ep);
	u8 dir = EP_DIR(rt_ep);
	if(dir == EP_IN )
		reg |= ENDPRST_IO | idx;
	usb_write(ENDPRST, reg);

	reg |= ENDPRST_TOGRST | ENDPRST_FIFORST;
	usb_write(ENDPRST, reg);	        
}
Beispiel #10
0
void usb_core_release_endpoint(int ep)
{
    int dir;

    usb_drv_release_endpoint(ep);

    dir = EP_DIR(ep);
    ep = EP_NUM(ep);

    ep_data[ep].completion_handler[dir] = NULL;
    ep_data[ep].control_handler[dir] = NULL;
}
Beispiel #11
0
static void rt_ep_irq_disable(struct rt_ep_struct *rt_ep)
{
	u8 reg;
	u8 idx = EP_NO(rt_ep);
	u8 dir = EP_DIR(rt_ep);

	if(idx == 0 /* ep0 */){
		usb_write(IN07IEN, (usb_read(IN07IEN) & ~(0x1)) );
		usb_write(OUT07IEN, (usb_read(OUT07IEN) & ~(0x1)) );
	}else{
		reg = usb_read(dir ? IN07IEN : OUT07IEN);
		reg = reg & ~(0x1 << idx);
		usb_write(dir == EP_IN ? IN07IEN : OUT07IEN, reg);
		reg = usb_read(dir ? IN07IEN : OUT07IEN);
	}
}
Beispiel #12
0
int usb_core_request_endpoint(int type, int dir, struct usb_class_driver* drv)
{
    int ret, ep;

    ret = usb_drv_request_endpoint(type, dir);

    if(ret == -1)
        return -1;

    dir = EP_DIR(ret);
    ep = EP_NUM(ret);

    ep_data[ep].completion_handler[dir] = drv->transfer_complete;
    ep_data[ep].control_handler[dir] = drv->control_request;

    return ret;
}
Beispiel #13
0
void usb_core_handle_transfer_completion(
    struct usb_transfer_completion_event_data* event)
{
    completion_handler_t handler;
    int ep = event->endpoint;

    switch(ep) {
        case EP_CONTROL:
            logf("ctrl handled %ld",current_tick);
            usb_core_control_request_handler(
                (struct usb_ctrlrequest*)event->data);
            break;
        default:
            handler = ep_data[ep].completion_handler[EP_DIR(event->dir)];
            if(handler != NULL)
                handler(ep, event->dir, event->status, event->length);
            break;
    }
}
Beispiel #14
0
void rt_ep_stall(struct rt_ep_struct *rt_ep)
{
	u8 tmp;
	u32 addr;
	int idx = EP_NO(rt_ep);
	int dir = EP_DIR(rt_ep);

	if(idx == 0){
		tmp = usb_read(EP0CS);
		tmp |= 0x1;
		usb_write(EP0CS, tmp);
	}else{
		addr = (dir == EP_IN ? 0x006 : 0x002) + idx * 8;
		tmp = usb_read(addr);
		tmp |= 0x40;
		usb_write(addr, tmp);
	}
	return;
}
void imx_udc_init_fifo(struct imx_udc_struct *imx_usb)
{
	int i, temp;
	struct imx_ep_struct *imx_ep;
	for (i = 0; i < IMX_USB_NB_EP; i++) {
		imx_ep = &imx_usb->imx_ep[i];

		/*              */
		temp = EP_DIR(imx_ep) ? 0x0B000000 : 0x0F000000;
		__raw_writel(temp, imx_usb->base + USB_EP_FCTRL(i));
		D_INI(imx_usb->dev, "<%s> ep%d_fctrl %08x\n", __func__, i,
			__raw_readl(imx_usb->base + USB_EP_FCTRL(i)));

		/*            */
		temp = (i ? imx_ep->fifosize / 2 : 0);
		__raw_writel(temp, imx_usb->base + USB_EP_FALRM(i));
		D_INI(imx_usb->dev, "<%s> ep%d_falrm %08x\n", __func__, i,
			__raw_readl(imx_usb->base + USB_EP_FALRM(i)));
	}
}
Beispiel #16
0
static u32 rt_fifo_bcount(struct rt_ep_struct *rt_ep)
{
	u8 low, high;
	u32 rc;

	int idx = EP_NO(rt_ep);
	int dir = EP_DIR(rt_ep);

	if(idx == 0)
		return 0;

	if(dir /* IN */){
		low = usb_read(0x004 + idx*8);
		high = usb_read( (0x004 + idx*8)+1 );
	}else{  /* OUT */
		low = usb_read(0x000 + idx*8);
		high = usb_read( (0x000 + idx*8)+1 );
	}
	rc = high | low;
	return rc;
}
static int handle_ep(struct imx_ep_struct *imx_ep)
{
	struct imx_request *req;
	int completed = 0;

	do {
		if (!list_empty(&imx_ep->queue))
			req = list_entry(imx_ep->queue.next,
				struct imx_request, queue);
		else {
			D_REQ(imx_ep->imx_usb->dev, "<%s> no request on %s\n",
				__func__, imx_ep->ep.name);
			return 0;
		}

		if (EP_DIR(imx_ep))	/*         */
			completed = write_fifo(imx_ep, req);
		else			/*           */
			completed = read_fifo(imx_ep, req);

		dump_ep_stat(__func__, imx_ep);

	} while (completed);
Beispiel #18
0
void usb_drv_release_endpoint(int ep)
{
    if ((ep & 0x7f) == 0)
        return;
    endpoints[EP_NUM(ep)][EP_DIR(ep)].active = false;
}