isp116x-hcd is a USB host controller driver for Philips' isp1160 and isp1161 chips. The driver has the following properties.
The driver is a part of the 2.6.13 and later mainline kernels. The driver is available also for a few older kernels.
Kernel 2.6.13 - There is a one, related to power switching of ports. Apply the following patch to fix it. Also, this patch converts the driver to a new platform code interface, reducing the amount of the platform support code needed for the driver. If you'll use the unpatched driver from 2.6.13 then see a separate page about setting up its platform support code.
Implement entering deep sleep.
For kernel, the isp116x host controller is usually defined as a platrorm device on a so called platform bus. And you need to provide platform support code for it. Here are recommendations and an example for the platform support code.
The file include/linux/usb_isp116x.h contains
a declaration of the
struct isp116x_platform_data, which you must
define and initialize to reflect specifics of your platform.
The struct members are explained in that header file. Here
follow some additional recommendations for some of the
members of this srtucture. As a rule, set a struct member
iff you know you need to set it.
int_act_high, int_edge_triggereddelayinclude/linux/usb_isp116x.h and
drivers/usb/host/isp116x-hcd.c as wrong choice
of the delay type or an incorrect implementation
of the platform-specific delay function is the major source
of problems when trying to get the driver working.
Here is an example platform code I use on my LH7A400
(a SoC with an ARM core) based boards; in my case it goes
into arch/arm/mach-lh7a40x/arch-lpd7a40x.c file.
#include <linux/usb_isp116x.h>
/* Platform delay */
static void isp116x_pfm_delay(struct device *dev, int delay)
{
/* On this platform, we work with 200MHz clock, giving
5 ns per instruction. The cycle below involves 2
instructions and we lose 2 more instruction times due
to pipeline flush at jump. I.e., we consume 20 ns
per cycle.
*/
int cyc = delay / 20;
__asm__ volatile ("0:\n"
" subs %0, %1, #1\n"
" bge 0b\n"
:"=r" (cyc)
:"0"(cyc)
);
}
/* Define chip configuration */
static struct isp116x_platform_data isp116x_pfm_data = {
.sel15Kres = 1,
.remote_wakeup_enable = 1,
.delay = isp116x_pfm_delay,
};
/* Define chip address and IRQ line */
static struct resource isp116x_pfm_resources[] = {
[0] = { /// data (A0 = 0)
.start = USB_IO_PHYS,
.end = USB_IO_PHYS + 1,
.flags = IORESOURCE_MEM,
},
[1] = { /// addr (A0 = 1)
.start = USB_IO_PHYS + 2,
.end = USB_IO_PHYS + 3,
.flags = IORESOURCE_MEM,
},
[2] = {
.start = IRQ_USB,
.end = IRQ_USB,
.flags = IORESOURCE_IRQ,
},
};
static struct platform_device isp116x_pfm_usbhost_device = {
.name = "isp116x-hcd",
.num_resources = ARRAY_SIZE(isp116x_pfm_resources),
.resource = isp116x_pfm_resources,
.dev.platform_data = &isp116x_pfm_data,
};
static struct platform_device *lpd7a40x_devs[] __initdata = {
...
&isp116x_pfm_usbhost_device,
};
For now, the H_WAKEUP pin of the isp116x chip must be pulled low. Otherwise the chip won't report clock to be ready after a software reset, resulting in failed probing. However, if you are interested in putting the chip into a deep sleep in the future then connect this pin to a GPIO, because the H_WAKEUP pin must be manipulated to enter that mode. Currently the driver does not support entering the deep sleep. I will implement it, when I get a proper platform.
First, there has been a number of postings on configuring isp116x in both linux-usb-devel and linux-arm-kernel mailing lists starting from 2005. So please browse the archives.
Second, of course, you can contact me at the e-mail address below (after preprocessing it :) But if you contact me then please CC also to one of the abovementioned mailing lists. This is not just to make my life easier, but yours too.