Пример #1
0
/* *
 * usbd_proc_write - implement proc file system write.
 * @file
 * @buf
 * @count
 * @pos
 *
 * Proc file system write function, used to signal monitor actions complete.
 * (Hotplug script (or whatever) writes to the file to signal the completion
 * of the script.)  An ugly hack.
 */
static ssize_t usbd_proc_write (struct file *file, const char *buf, size_t count, loff_t * pos)
{
        struct usb_device_instance *device;
	size_t n = count;
	char command[64];
	char *cp = command;
	int i = 0;

	MOD_INC_USE_COUNT;
	//printk(KERN_DEBUG "%s: count=%u\n",__FUNCTION__,count);
	while ((n > 0) && (i < 64)) {
		// Not too efficient, but it shouldn't matter
		if (copy_from_user (cp++, buf + (count - n), 1)) {
			count = -EFAULT;
			break;
		}
		*cp = '\0';
		i++;
		n -= 1;
		//printk(KERN_DEBUG "%s: %u/%u %02x\n",__FUNCTION__,count-n,count,c);
	}
	if (!strncmp (command, "plug", 4)) {
		udc_connect ();
	} 
        else if (!strncmp (command, "unplug", 6)) {
		udc_disconnect ();
                if ((device = device_array[0])) {
                        usbd_device_event (device, DEVICE_RESET, 0);
                }
	}
	MOD_DEC_USE_COUNT;
	return (count);
}
Пример #2
0
static int
bi_udc_resume(struct device *dev, u32 level)
{
	int ret = 0;
	struct usb_device_instance *device = device_array[0];

	switch (level) {
	case RESUME_POWER_ON:
		dbg_pm (0, "RESUME_POWER_ON");
		if (udc_init ()) {
			dbg_init (0, "udc_init failed");
		}
		if (device) {
			udc_enable (device);		/* enable UDC */
			udc_all_interrupts (device);	/* enable interrupts */
		}
		udc_connect ();			/* enable USB pullup */

		dbg_init (1, "MOD_INC_USE_COUNT %d", 
			GET_USE_COUNT (THIS_MODULE));
		dbg_pm (0, "RESUME_POWER_ON: finished");
		break;
	}

	return ret;
}
Пример #3
0
/*
 * usbd_pm_callback
 * @dev:
 * @rqst:
 * @unused:
 *
 * Used to signal power management events.
 */
static int bi_pm_event (struct pm_dev *pm_dev, pm_request_t request, void *unused)
{
	struct usb_device_instance *device;

	dbg_pm (0, "request: %d pm_dev: %p data: %p", request, pm_dev, pm_dev->data);

	if (!(device = pm_dev->data)) {
		dbg_pm (0, "DATA NULL, NO DEVICE");
		return 0;
	}

	switch (request) {
#if defined(CONFIG_IRIS)
	case PM_STANDBY:
	case PM_BLANK:
#endif
	case PM_SUSPEND:
		dbg_pm (0, "PM_SUSPEND");
		if (!pm_suspended) {
			pm_suspended = 1;
			dbg_init (1, "MOD_INC_USE_COUNT %d", GET_USE_COUNT (THIS_MODULE));
			udc_disconnect ();	// disable USB pullup if we can
			udc_disable_interrupts (device);	// disable interupts
			udc_disable ();	// disable UDC
			dbg_pm (0, "PM_SUSPEND: finished");
		}
		break;
#if defined(CONFIG_IRIS)
	case PM_UNBLANK:
#endif
	case PM_RESUME:
		dbg_pm (0, "PM_RESUME");
		if (pm_suspended) {
			// probe for device
			if (udc_init ()) {
				dbg_init (0, "udc_init failed");
				//return -EINVAL;
			}
			udc_enable (device);	// enable UDC
			udc_all_interrupts (device);	// enable interrupts
			udc_connect ();	// enable USB pullup if we can
			//udc_set_address(device->address);
			//udc_reset_ep(0);

			pm_suspended = 0;
			dbg_init (1, "MOD_INC_USE_COUNT %d", GET_USE_COUNT (THIS_MODULE));
			dbg_pm (0, "PM_RESUME: finished");
		}
		break;
	}
	return 0;
}
Пример #4
0
static void usb_udc_init(void)
{
	DBG("usb init start\n");
	
	usbotg_init_ext();
	usbotg_clock_gate(1);
	usb_phy_init();
	usb_set_mode_device();
	//mxc_init_usb_qh();
	//usb_init_eps();
	//mxc_init_ep_struct();
	//ep0_setup();
	//mxc_ep_qh_setup(0, USB_RECV, USB_ENDPOINT_XFER_CONTROL,
			   // USB_MAX_CTRL_PAYLOAD, 0, 0);
	udc_connect();
}
Пример #5
0
int do_neo1973 ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
	int i;

	if (!strcmp(argv[1], "info")) {
		printf("FIC Neo1973 Hardware Revision 0x%04x\n", get_board_rev());
	} else if (!strcmp(argv[1], "power-off")) {
		neo1973_poweroff();
	} else if (!strcmp(argv[1], "charger") || !strcmp(argv[1], "charge")) {
		if (argc < 3)
			goto out_help;
		if (!strcmp(argv[2], "status") || !strcmp(argv[2], "state")) {
			printf("%s\n", neo1973_get_charge_status());
		} else if (!strcmp(argv[2], "autofast")) {
			neo1973_set_charge_mode(NEO1973_CHGCMD_AUTOFAST);
		} else if (!strcmp(argv[2], "!autofast")) {
			neo1973_set_charge_mode(NEO1973_CHGCMD_NO_AUTOFAST);
		} else if (!strcmp(argv[2], "off")) {
			neo1973_set_charge_mode(NEO1973_CHGCMD_OFF);
		} else if (!strcmp(argv[2], "fast")) {
			neo1973_set_charge_mode(NEO1973_CHGCMD_FAST);
		} else
			goto out_help;
	} else if (!strcmp(argv[1], "backlight")) {
		if (argc < 3)
			goto out_help;
		if (!strcmp(argv[2], "on"))
			neo1973_backlight(1);
		else
			neo1973_backlight(0);
	} else if (!strcmp(argv[1], "led")) {
		long led = simple_strtol(argv[2], NULL, 10);
		if (argc < 4)
			goto out_help;
		if (!strcmp(argv[3], "on"))
			neo1973_led(led, 1);
		else
			neo1973_led(led, 0);
	} else if (!strcmp(argv[1], "vibrator")) {
		if (argc < 3)
			goto out_help;
		if (!strcmp(argv[2], "on"))
			neo1973_vibrator(1);
		else
			neo1973_vibrator(0);
	} else if (!strcmp(argv[1], "gsm")) {
		if (argc < 3)
			goto out_help;
		if (!strcmp(argv[2], "on"))
			neo1973_gsm(1);
		else if (!strcmp(argv[2], "off"))
			neo1973_gsm(0);
		else if (!strcmp(argv[2], "version"))
			neo1973_gsmver();
	} else if (!strcmp(argv[1], "gps")) {
		if (argc < 3)
			goto out_help;
		if (!strcmp(argv[2], "on"))
			neo1973_gps(1);
		else
			neo1973_gps(0);
	} else if (!strcmp(argv[1], "udc")) {
		if (argc < 3)
			goto out_help;
		if (!strcmp(argv[2], "pullup")) {
			if (argc < 4)
				goto out_help;
			if (!strcmp(argv[3], "on"))
				udc_connect();
			else
				udc_disconnect();
		} else
			goto out_help;
	} else {
out_help:
		printf("Usage:\n%s\n", cmdtp->usage);
		return 1;
	}

	return 0;
}
Пример #6
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;
}
Пример #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)
{

	//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;
}
Пример #8
0
int ticker_thread (void *data)
{
	struct timer_list ticker;

	// detach

	lock_kernel ();
	exit_mm (current);
	exit_files (current);
	exit_fs (current);

	// setsid equivalent, used at start of kernel thread, no error checks needed, or at least none made :). 
	current->leader = 1;
	current->session = current->pgrp = current->pid;
	current->tty = NULL;
	current->tty_old_pgrp = 0;

	// Name this thread 
	sprintf (current->comm, "usbd-bi");

	// setup signal handler
	current->exit_signal = SIGCHLD;
	spin_lock (&current->sigmask_lock);
	flush_signals (current);
	spin_unlock (&current->sigmask_lock);

	// XXX Run at a high priority, ahead of sync and friends
	// current->nice = -20;
	current->policy = SCHED_OTHER;

	unlock_kernel ();

	// setup timer
	init_timer (&ticker);
	ticker.data = 0;
	ticker.function = ticker_tick;

	// let startup continue
	up (&ticker_sem_start);

	// process loop
	for (ticker_timer_set = ticker_terminating = 0; !ticker_terminating;) {

		char buf[100];
		char *cp;

		if (!ticker_timer_set) {
			mod_timer (&ticker, jiffies + HZ * RETRYTIME);
		}
		// wait for someone to tell us to do something
		down (&ticker_sem_work);

		if (udc_interrupts != udc_interrupts_last) {
			dbg_tick (3, "--------------");
		}
		// do some work
		memset (buf, 0, sizeof (buf));
		cp = buf;

		if (dbgflg_usbdbi_tick) {
			unsigned long flags;
			local_irq_save (flags);
			dbg_tick (2, "[%d]", udc_interrupts);
			udc_regs ();
			local_irq_restore (flags);
		}

#if 0
		// XXX
#if defined(CONFIG_SA1110_CALYPSO) && defined(CONFIG_PM) && defined(CONFIG_USBD_TRAFFIC_KEEPAWAKE)
		/* Check for rx/tx activity, and reset the sleep timer if present */
		if (device->usbd_rxtx_timestamp != device->usbd_last_rxtx_timestamp) {
			extern void resetSleepTimer (void);
			dbg_tick (7, "resetting sleep timer");
			resetSleepTimer ();
			device->usbd_last_rxtx_timestamp = device->usbd_rxtx_timestamp;
		}
#endif
#endif
#if 0
		/* Check for TX endpoint stall.  If the endpoint has
		   stalled, we have probably run into the DMA/TCP window
		   problem, and the only thing we can do is disconnect
		   from the bus, then reconnect (and re-enumerate...). */
		if (reconnect > 0 && 0 >= --reconnect) {
			dbg_init (0, "TX stall disconnect finished");
			udc_connect ();
		} else if (0 != USBD_STALL_TIMEOUT_SECONDS) {
			// Stall watchdog unleashed
			unsigned long now, tx_waiting;
			now = jiffies;
			tx_waiting = (now - tx_queue_head_timestamp (now)) / HZ;
			if (tx_waiting > USBD_STALL_TIMEOUT_SECONDS) {
				/* The URB at the head of the queue has waited too long */
				reconnect = USBD_STALL_DISCONNECT_DURATION;
				dbg_init (0, "TX stalled, disconnecting for %d seconds", reconnect);
				udc_disconnect ();
			}
		}
#endif
	}

	// remove timer
	del_timer (&ticker);

	// let the process stopping us know we are done and return
	up (&ticker_sem_start);
	return 0;
}
Пример #9
0
int fastboot_init(struct cmd_fastboot_interface *interface) 
{
	fastboot_interface = interface;
	return udc_connect();
}