isp116x-hcd

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.

Known bugs

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.

Todo

Implement entering deep sleep.

Getting the driver working

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_triggered
Whenever your platform supports level-triggered interrupts, use these. Success with configuring level-triggered interrupts has been reported even on platforms, which don't support level-triggered interrupts, but for which the 166 ns edge-triggered interrupt pulse is too short to be detected (like PXA255 SoC).
delay
Read CAREFULLY the comments in both include/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,
};

Hardware considerations

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.

Still help needed

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.


Olav Kongas 2005, <ok@a-r-t-e-c-d-e-s-i-g-n.ee>