Esempio n. 1
0
/* bi_modinit - commission bus interface driver
 */
int __init bi_modinit(void)
{
    struct usb_bus_instance * bus;
    struct usb_device_instance * device;
    //extern const char __usbd_module_info[];

    //printk(KERN_INFO "%s (dbg=\"%s\")\n", __usbd_module_info, dbg?dbg:"");

    if (0 != scan_debug_options("usb-bus",dbg_table,dbg)) {
        printk("Failed to scan dbg in bi_modinit\n");
    }

    if (bi_udc_init()) {
        return(-EINVAL);
    }

    // register this bus interface driver and create the device driver instance
    if ((bus = usbd_register_bus(&bi_driver))==NULL) {
        bi_udc_exit();
        return -EINVAL;
    }

    // see if we can scrounge up something to set a sort of unique device
    // address
    if (!udc_serial_init(bus)) {
        dbg_init(1,"serial: %s %04x", bus->serial_number_str,
                 bus->serial_number);
    }

    if ((device = usbd_register_device(NULL, bus, 8))==NULL) {
        usbd_deregister_bus(bus);
        bi_udc_exit();
        return -EINVAL;
    }

#ifdef CONFIG_PM
    // register with power management
    pm_dev = pm_register(PM_USB_DEV, PM_SYS_UNKNOWN, bi_pm_event);
    pm_dev->data = device;
#endif

    bus->device = device;
    device_array[0] = device;

    // initialize the device
    {
        struct usb_endpoint_instance *endpoint = device->bus->endpoint_array + 0;

        // setup endpoint zero

        endpoint->endpoint_address = 0;

        endpoint->tx_attributes = 0;
        endpoint->tx_transferSize = 255;
        endpoint->tx_packetSize = udc_ep0_packetsize();

        endpoint->rcv_attributes = 0;
        endpoint->rcv_transferSize = 0x8;
        endpoint->rcv_packetSize = udc_ep0_packetsize();

        udc_setup_ep(device, 0, endpoint);
    }

    // hopefully device enumeration will finish this process
    udc_startup_events(device);

#ifdef CONFIG_PM
    dbg_pm(0,"pm_dev->callback#%p",pm_dev->callback);
    if (!udc_connected()) {
       /* Fake a call from the PM system to suspend the UDC until it
           is needed (cable connect, etc) */
        (void) bi_pm_event(pm_dev,PM_SUSPEND,NULL);
    /* There appears to be no constant for this, but inspection
           of arch/arm/mach-l7200/apm.c:send_event() shows that the
           suspended state is 3 (i.e. pm_send_all(PM_SUSPEND, (void *)3))
           corresponding to ACPI_D3. */
    pm_dev->state = 3;
    }
#endif
    if (dbgflg_usbdbi_tick > 0) {
        // start ticker
        ticker_kickoff();
    }

    dbgLEAVE(dbgflg_usbdbi_init,1);
    return 0;
}
Esempio n. 2
0
/* bi_modinit - commission bus interface driver
 */
static int __init bi_modinit (void)
{
	extern const char __usbd_module_info[];
	struct usb_bus_instance *bus;
	struct usb_device_instance *device;
	struct bi_data *data;


	printk (KERN_INFO "%s (dbg=\"%s\")\n", __usbd_module_info, dbg ? dbg : "");

	// process debug options
	if (0 != scan_debug_options ("usbd-bi", dbg_table, dbg)) {
		return -EINVAL;
	}
	// check if we can see the UDC
	if (bi_udc_init ()) {
		return -EINVAL;
	}
	// allocate a bi private data structure
	if ((data = kmalloc (sizeof (struct bi_data), GFP_KERNEL)) == NULL) {
		bi_udc_exit ();
		return -EINVAL;
	}
	memset (data, 0, sizeof (struct bi_data));

	// register this bus interface driver and create the device driver instance
	if ((bus = usbd_register_bus (&bi_driver)) == NULL) {
		kfree (data);
		bi_udc_exit ();
		return -EINVAL;
	}

	bus->privdata = data;

	// see if we can scrounge up something to set a sort of unique device address
	if (!udc_serial_init (bus)) {
		dbg_init (1, "serial: %s %04x\n", bus->serial_number_str, bus->serial_number);
	}


	if ((device = usbd_register_device (NULL, bus, 8)) == NULL) {
		usbd_deregister_bus (bus);
		kfree (data);
		bi_udc_exit ();
		return -EINVAL;
	}
#if defined(CONFIG_PM) && !defined(CONFIG_USBD_MONITOR) && !defined(CONFIG_USBD_MONITOR_MODULE)
	// register with power management 
	pm_dev = pm_register (PM_USB_DEV, PM_SYS_UNKNOWN, bi_pm_event);
	pm_dev->data = device;
#endif

#ifdef CONFIG_DPM	/* MVL-CEE */
	bi_udc_ldm_driver_register();
	bi_udc_ldm_device_register();
#endif

	bus->device = device;
	device_array[0] = device;

	// initialize the device
	{
		struct usb_endpoint_instance *endpoint = device->bus->endpoint_array + 0;

		// setup endpoint zero

		endpoint->endpoint_address = 0;

		endpoint->tx_attributes = 0;
		endpoint->tx_transferSize = 255;
		endpoint->tx_packetSize = udc_ep0_packetsize ();

		endpoint->rcv_attributes = 0;
		endpoint->rcv_transferSize = 0x8;
		endpoint->rcv_packetSize = udc_ep0_packetsize ();

		udc_setup_ep (device, 0, endpoint);
	}

	// hopefully device enumeration will finish this process
        printk(KERN_INFO"bi_modinit: call udc_startup_events\n");
	udc_startup_events (device);

#if defined(CONFIG_PM) && !defined(CONFIG_USBD_MONITOR) && !defined(CONFIG_USBD_MONITOR_MODULE)
	dbg_pm (0, "pm_dev->callback#%p", pm_dev->callback);
	if (!udc_connected ()) {
		/* Fake a call from the PM system to suspend the UDC until it
		   is needed (cable connect, etc) */
		(void) bi_pm_event (pm_dev, PM_SUSPEND, NULL);
		/* There appears to be no constant for this, but inspection
		   of arch/arm/mach-l7200/apm.c:send_event() shows that the
		   suspended state is 3 (i.e. pm_send_all(PM_SUSPEND, (void *)3))
		   corresponding to ACPI_D3. */
		pm_dev->state = 3;
	}
#endif
	if (dbgflg_usbdbi_tick > 0) {
		// start ticker
		ticker_kickoff ();
	}

#ifdef CONFIG_USBD_PROCFS
	{
		struct proc_dir_entry *p;

		// create proc filesystem entries
		if ((p = create_proc_entry ("usbd", 0, 0)) == NULL) {
			return -ENOMEM;
		}
		p->proc_fops = &usbd_proc_operations_functions;
	}
#endif
	dbgLEAVE (dbgflg_usbdbi_init, 1);
	return 0;
}