Esempio n. 1
0
/*
 * 	udc_disable - disable USB device controller
 */
static void udc_disable(struct lh7a40x_udc *dev)
{
	DEBUG("%s, %p\n", __FUNCTION__, dev);

	udc_set_address(dev, 0);

	/* Disable interrupts */
	usb_write(0, USB_IN_INT_EN);
	usb_write(0, USB_OUT_INT_EN);
	usb_write(0, USB_INT_EN);

	/* Disable the USB */
	usb_write(0, USB_PM);

#ifdef CONFIG_ARCH_LH7A404
	/* Disable USB power */
	set_portc_dr(1, 0);
#endif

	/* if hardware supports it, disconnect from usb */
	/* make_usb_disappear(); */

	dev->ep0state = WAIT_FOR_SETUP;
	dev->gadget.speed = USB_SPEED_UNKNOWN;
	dev->usb_address = 0;
}
Esempio n. 2
0
/*
 * 	udc_disable - disable USB device controller
 */
static void udc_disable(struct s3c_udc *dev)
{
	DEBUG_SETUP("%s: %p\n", __FUNCTION__, dev);

	udc_set_address(dev, 0);

	dev->ep0state = WAIT_FOR_SETUP;
	dev->gadget.speed = USB_SPEED_UNKNOWN;
	dev->usb_address = 0;

	/* usb power disable */
#if defined(CONFIG_CPU_S3C2450) || defined(CONFIG_CPU_S3C2416)
	s3c2410_gpio_pullup(S3C2443_GPH14, 1); /* pull-down enable */
	s3c2410_gpio_pullup(S3C2410_GPF2, 1);  /* pull-down enable */
#else
	s3c2410_gpio_pullup(S3C2443_GPH14, 2); /* pull-down enable */
#endif
	s3c2410_gpio_cfgpin(S3C2443_GPH14, S3C2443_GPH14_OUTP);
	s3c2410_gpio_setpin(S3C2443_GPH14, 0);

	/* usb clock disable */
	__raw_writel(0, S3C_UCLKCON);

	/* USB Port is Suspend mode */
	__raw_writel(__raw_readl(S3C2410_MISCCR)|(1<<12), S3C2410_MISCCR);

	/* PHY power disable */
	__raw_writel(__raw_readl(S3C_PWRCFG)&~(1<<4), S3C_PWRCFG);

}
Esempio n. 3
0
/*
 * 	udc_disable - disable USB device controller
 */
static void udc_disable(struct s3c_udc *dev)
{
	DEBUG_SETUP("%s: %p\n", __FUNCTION__, dev);

	udc_set_address(dev, 0);

	dev->ep0state = WAIT_FOR_SETUP;
	dev->gadget.speed = USB_SPEED_UNKNOWN;
	dev->usb_address = 0;
	__raw_writel(__raw_readl(S3C_PWRCFG)&~(1<<4), S3C_PWRCFG);
}
/*
 * 	udc_disable - disable USB device controller
 */
static void udc_disable(struct s3c_udc *dev)
{
	DEBUG_SETUP("%s: %p\n", __FUNCTION__, dev);

	udc_set_address(dev, 0);

	dev->ep0state = WAIT_FOR_SETUP;
	dev->gadget.speed = USB_SPEED_UNKNOWN;
	dev->usb_address = 0;
	//writel(readl(S3C_USBOTG_PHYPWR)|(0x7<<1), S3C_USBOTG_PHYPWR);
        otg_phy_init(0x42); /* 2010-0208, added by CVKK(JC) */
	dev->udc_state = USB_STATE_NOTATTACHED;
}
Esempio n. 5
0
/*
 * 	udc_disable - disable USB device controller
 */
static void udc_disable(struct elfin_udc *dev)
{
	DPRINTK("%s, %p\n", __FUNCTION__, dev);

	udc_set_address(dev, 0);

	if (udc_clock) {
		clk_disable(udc_clock);
		clk_unuse(udc_clock);
		clk_put(udc_clock);
		udc_clock = NULL;
        }

	dev->ep0state = WAIT_FOR_SETUP;
	dev->gadget.speed = USB_SPEED_UNKNOWN;
	dev->usb_address = 0;
}
Esempio n. 6
0
static void S3C24X0_udc_ep0(void)
{
	u_int8_t ep0csr;
	struct usb_endpoint_instance *ep0 = udc_device->bus->endpoint_array;

	S3C24X0_UDC_SETIX(0);
	ep0csr = inl(S3C24X0_UDC_IN_CSR1_REG);

	/* clear stall status */
	if (ep0csr & S3C24X0_UDC_EP0_CSR_SENTSTL) {
	    	/* serial_printf("Clearing SENT_STALL\n"); */
		clear_ep0_sst();
		if (ep0csr & S3C24X0_UDC_EP0_CSR_SOPKTRDY)
			clear_ep0_opr();
		ep0->state = EP0_IDLE;
		return;
	}

	/* clear setup end */
	if (ep0csr & S3C24X0_UDC_EP0_CSR_SE
	    /* && ep0->state != EP0_IDLE */) {
	    	/* serial_printf("Clearing SETUP_END\n"); */
		clear_ep0_se();
#if 1
		if (ep0csr & S3C24X0_UDC_EP0_CSR_SOPKTRDY) {
			/* Flush FIFO */
			while (inl(S3C24X0_UDC_OUT_FIFO_CNT1_REG))
				inl(S3C24X0_UDC_EP0_FIFO_REG);
			clear_ep0_opr();
		}
#endif
		ep0->state = EP0_IDLE;
		return;
	}

	/* Don't ever put [serial] debugging in non-error codepaths here, it
	 * will violate the tight timing constraints of this USB Device
	 * controller (and lead to bus enumeration failures) */

	switch (ep0->state) {
		int i, fifo_count;
		unsigned char *datap;
	case EP0_IDLE:
		if (!(ep0csr & S3C24X0_UDC_EP0_CSR_OPKRDY))
			break;

		datap = (unsigned char *) &ep0_urb->device_request;
		/* host->device packet has been received */

		/* pull it out of the fifo */
		fifo_count = fifo_count_out();
		for (i = 0; i < fifo_count; i++) {
			*datap = (unsigned char)inl(S3C24X0_UDC_EP0_FIFO_REG);
			datap++;
		}
		if (fifo_count != 8) {
			debug("STRANGE FIFO COUNT: %u bytes\n", fifo_count);
			set_ep0_ss();
			return;
		}

		if (ep0_urb->device_request.wLength == 0) {
			if (ep0_recv_setup(ep0_urb)) {
				/* Not a setup packet, stall next EP0 transaction */
				debug("can't parse setup packet1\n");
				set_ep0_ss();
				set_ep0_de_out();
				ep0->state = EP0_IDLE;
				return;
			}
			/* There are some requests with which we need to deal
			 * manually here */
			switch (ep0_urb->device_request.bRequest) {
			case USB_REQ_SET_CONFIGURATION:
				if (!ep0_urb->device_request.wValue)
					usbd_device_event_irq(udc_device,
							DEVICE_DE_CONFIGURED, 0);
				else
					usbd_device_event_irq(udc_device,
							DEVICE_CONFIGURED, 0);
				break;
			case USB_REQ_SET_ADDRESS:
				udc_set_address(udc_device->address);
				usbd_device_event_irq(udc_device,
						DEVICE_ADDRESS_ASSIGNED, 0);
				break;
			default:
				break;
			}
			set_ep0_de_out();
			ep0->state = EP0_IDLE;
		} else {
			if ((ep0_urb->device_request.bmRequestType & USB_REQ_DIRECTION_MASK) == USB_REQ_HOST2DEVICE) {
				clear_ep0_opr();
				ep0->state = EP0_OUT_DATA_PHASE;
				ep0_urb->buffer = ep0_urb->buffer_data;
				ep0_urb->buffer_length = sizeof(ep0_urb->buffer_data);
				ep0_urb->actual_length = 0;
			} else {
				ep0->state = EP0_IN_DATA_PHASE;

				if (ep0_recv_setup(ep0_urb)) {
					/* Not a setup packet, stall next EP0 transaction */
					debug("can't parse setup packet2\n");
					set_ep0_ss();
					//set_ep0_de_out();
					ep0->state = EP0_IDLE;
					return;
				}
				clear_ep0_opr();
				ep0->tx_urb = ep0_urb;
				ep0->sent = ep0->last = 0;

				if (S3C24X0_write_noniso_tx_fifo(ep0)) {
					ep0->state = EP0_IDLE;
					set_ep0_de_in();
				} else
					set_ep0_ipr();
			}
		}
		break;
	case EP0_IN_DATA_PHASE:
		if (!(ep0csr & S3C24X0_UDC_EP0_CSR_IPKRDY)) {
			ep0->sent += ep0->last;

			if (S3C24X0_write_noniso_tx_fifo(ep0)) {
				ep0->state = EP0_IDLE;
				set_ep0_de_in();
			} else
				set_ep0_ipr();
		}
		break;
	case EP0_OUT_DATA_PHASE:
		if (ep0csr & S3C24X0_UDC_EP0_CSR_OPKRDY) {
			u32 urb_avail = ep0_urb->buffer_length - ep0_urb->actual_length;
			u_int8_t *cp = ep0_urb->buffer + ep0_urb->actual_length;
			int i, fifo_count;

			fifo_count = fifo_count_out();
			if (fifo_count < urb_avail)
				urb_avail = fifo_count;

			for (i = 0; i < urb_avail; i++)
				*cp++ = inl(S3C24X0_UDC_EP0_FIFO_REG);

			ep0_urb->actual_length += urb_avail;

			if (fifo_count < ep0->rcv_packetSize ||
			    ep0_urb->actual_length >= ep0_urb->device_request.wLength) {
				ep0->state = EP0_IDLE;
				if (ep0_recv_setup(ep0_urb)) {
					/* Not a setup packet, stall next EP0 transaction */
					debug("can't parse setup packet3\n");
					set_ep0_ss();
					//set_ep0_de_out();
					return;
				}
				set_ep0_de_out();
			} else
				clear_ep0_opr();
		}
		break;
	case EP0_END_XFER:
		ep0->state = EP0_IDLE;
		break;
	case EP0_STALL:
		//set_ep0_ss;
		ep0->state = EP0_IDLE;
		break;
	}
}
Esempio n. 7
0
/**
 * bi_device_event - handle generic bus event
 * @device: device pointer
 * @event: interrupt event
 *
 * Called by usb core layer to inform bus of an event.
 */
int bi_device_event(struct usb_device_instance *device, usb_device_event_t event, int data)
{
    sie_info * sie_data;
    cy_priv_t * cy_priv;
    otg_t * otg;

    sie_data = (sie_info *) device->bus->privdata;
    cy_priv = (cy_priv_t *) sie_data->cy_priv;
    otg = (otg_t *) cy_priv->otg;

    //printk(KERN_DEBUG "bi_device_event: event: %d\n", event);

    if (!device) {
        return 0;
    }
    switch (event) {
    case DEVICE_UNKNOWN:
        break;
    case DEVICE_INIT:
        break;
    case DEVICE_CREATE:         // XXX should this stuff be in DEVICE_INIT?

        bi_config(device);

        // enable udc, enable interrupts, enable connect
        udc_enable(device);
        udc_all_interrupts(device);
        udc_connect();
        break;

    case DEVICE_HUB_CONFIGURED:
        break;

    case DEVICE_RESET:
        device->address = 0;
        udc_set_address(device->address, device);
        udc_reset_ep(0, device);
        udc_all_interrupts(device); // XXX
        break;


    case DEVICE_ADDRESS_ASSIGNED:
        udc_set_address(device->address, device);
        device->status = USBD_OK;
        break;

    case DEVICE_CONFIGURED:
        bi_config(device);
        break;

    case DEVICE_DE_CONFIGURED:
        udc_reset_ep(1, device);
        udc_reset_ep(2, device);
        udc_reset_ep(3, device);
        break;

    case DEVICE_SET_INTERFACE:
        bi_config(device);
        break;

    case DEVICE_SET_FEATURE:
        break;

    case DEVICE_CLEAR_FEATURE:
        break;

    case DEVICE_BUS_INACTIVE:
        // disable suspend interrupt
        udc_suspended_interrupts(device);

        // XXX check on linkup and sl11
        // if we are no longer connected then force a reset
        if (!udc_connected()) {
            usbd_device_event_irq(device, DEVICE_RESET, 0);
        }
        break;

    case DEVICE_BUS_ACTIVITY:
        // enable suspend interrupt
        udc_all_interrupts(device);
        break;

    case DEVICE_POWER_INTERRUPTION:
        break;

    case DEVICE_HUB_RESET:
        break;

    case DEVICE_DESTROY:
        udc_disconnect();
        bi_disable_endpoints(device);
        udc_disable_interrupts(device);
        udc_disable();
        break;

    case DEVICE_BUS_REQUEST:
        otg->b_bus_req = TRUE;
        update_otg_state(otg);
        break;

    case DEVICE_BUS_RELEASE:
        otg->b_bus_req = FALSE;
        update_otg_state(otg);
        break;

    case DEVICE_RCV_URB_RECYCLED:
        udc_rcv_urb_recycled();
        break;

    case DEVICE_ACCEPT_HNP:
        otg->b_hnp_en = TRUE;
        update_otg_state(otg);
    break;

    case DEVICE_REQUEST_SRP:
        //otg->srp_start_flag = TRUE;
        otg->b_bus_req = TRUE;
        otg->b_se0_srp = TRUE;
        update_otg_state(otg);
    break;

    case DEVICE_FUNCTION_PRIVATE:
        break;
    }

    return 0;
}
Esempio n. 8
0
/**
 * bi_device_event - handle generic bus event
 * @device: device pointer
 * @event: interrupt event
 *
 * Called by usb core layer to inform bus of an event.
 */
int bi_device_event (struct usb_device_instance *device, usb_device_event_t event, int data)
{

	//printk(KERN_DEBUG "bi_device_event: event: %d\n", event);

	if (!device) {
		return 0;
	}

        dbg_usbe (1,"%s", USBD_DEVICE_EVENTS(event));

	switch (event) {
	case DEVICE_UNKNOWN:
		break;
	case DEVICE_INIT:
		break;
	case DEVICE_CREATE:	// XXX should this stuff be in DEVICE_INIT?
		// enable upstream port

		//ep0_enable(device);

		// for net_create
		bi_config (device);

		// enable udc, enable interrupts, enable connect
                printk(KERN_INFO"bi_device_event: call udc_enable\n");
		udc_enable (device);
                printk(KERN_INFO"bi_device_event: call udc_all_interrupts\n");

                // XXX verify
		udc_suspended_interrupts (device);
		//udc_all_interrupts (device);

		dbg_usbe (1, "CREATE done");
		break;

	case DEVICE_HUB_CONFIGURED:
		udc_connect ();
		break;

	case DEVICE_RESET:
		device->address = 0;
		udc_set_address (device->address);
		udc_reset_ep (0);
                
                // XXX verify
		udc_suspended_interrupts (device);
		dbg_usbe (1, "DEVICE RESET done: %d", device->address);
		break;


	case DEVICE_ADDRESS_ASSIGNED:
		udc_set_address (device->address);
		device->status = USBD_OK;

                // XXX verify
		udc_all_interrupts (device);	// XXX
		break;

	case DEVICE_CONFIGURED:
		device->status = USBD_OK;
		bi_config (device);
		break;

	case DEVICE_DE_CONFIGURED:
		{
			int ep;

			for (ep = 1; ep < udc_max_endpoints (); ep++)
				udc_reset_ep (ep);
		}
		break;


	case DEVICE_SET_INTERFACE:
		bi_config (device);
		break;

	case DEVICE_SET_FEATURE:
		break;

	case DEVICE_CLEAR_FEATURE:
		break;

	case DEVICE_BUS_INACTIVE:
		// disable suspend interrupt
		udc_suspended_interrupts (device);

		// XXX check on linkup and sl11
		// if we are no longer connected then force a reset
		if (!udc_connected ()) {
			usbd_device_event_irq (device, DEVICE_RESET, 0);
		}
		break;

	case DEVICE_BUS_ACTIVITY:
		// enable suspend interrupt
		udc_all_interrupts (device);
		break;

	case DEVICE_POWER_INTERRUPTION:
		break;

	case DEVICE_HUB_RESET:
		break;

	case DEVICE_DESTROY:
		udc_disconnect ();
		bi_disable_endpoints (device);
		udc_disable_interrupts (device);
		udc_disable ();
		break;

	case DEVICE_FUNCTION_PRIVATE:
		break;
	}
	return 0;
}