> The YL-9200 board switches a transistor to provide pullup Presumably driving through a pulldown, so that when the board resets it doesn't wrongly present itself as ready to respond to a USB host.
> This modification adds a field to allow the state of the pin > level to be specified Here's a replacement patch, addressing the critical issues I had mentioned to you before: (a) not breaking every existing at91rm9200 board, and (b) applying atop a previous patch [1]. When replacing this I happened to notice two small glitches in the cleanup code of that previous patch, so I may instead just merge this into an updated version of that patch. - Dave [1] http://marc.info/?l=linux-usb&m=119878579910739&w=2 ======= CUT HERE Add a mechanism whereby AT91 boards can drive the D+ pullup through an inverter. Based on a patch from Steve Birtles. Signed-off-by: David Brownell <[EMAIL PROTECTED]> --- drivers/usb/gadget/at91_udc.c | 13 ++++++++++--- include/asm-arm/arch-at91/board.h | 3 ++- 2 files changed, 12 insertions(+), 4 deletions(-) --- at91.orig/drivers/usb/gadget/at91_udc.c 2008-01-01 08:28:36.000000000 -0800 +++ at91/drivers/usb/gadget/at91_udc.c 2008-01-01 08:42:46.000000000 -0800 @@ -880,6 +880,8 @@ static void clk_off(struct at91_udc *udc */ static void pullup(struct at91_udc *udc, int is_on) { + int active = !udc->board.pullup_inverted; + if (!udc->enabled || !udc->vbus) is_on = 0; DBG("%sactive\n", is_on ? "" : "in"); @@ -889,7 +891,7 @@ static void pullup(struct at91_udc *udc, at91_udp_write(udc, AT91_UDP_ICR, AT91_UDP_RXRSM); at91_udp_write(udc, AT91_UDP_TXVC, 0); if (cpu_is_at91rm9200()) - gpio_set_value(udc->board.pullup_pin, 1); + gpio_set_value(udc->board.pullup_pin, active); else if (cpu_is_at91sam9260() || cpu_is_at91sam9263()) { u32 txvc = at91_udp_read(udc, AT91_UDP_TXVC); @@ -907,7 +909,7 @@ static void pullup(struct at91_udc *udc, at91_udp_write(udc, AT91_UDP_IDR, AT91_UDP_RXRSM); at91_udp_write(udc, AT91_UDP_TXVC, AT91_UDP_TXVC_TXVDIS); if (cpu_is_at91rm9200()) - gpio_set_value(udc->board.pullup_pin, 0); + gpio_set_value(udc->board.pullup_pin, !active); else if (cpu_is_at91sam9260() || cpu_is_at91sam9263()) { u32 txvc = at91_udp_read(udc, AT91_UDP_TXVC); @@ -1683,7 +1685,8 @@ static int __init at91udc_probe(struct p DBG("D+ pullup is busy\n"); goto fail0; } - gpio_direction_output(udc->board.pullup_pin, 0); + gpio_direction_output(udc->board.pullup_pin, + udc->board.pullup_inverted); } udc->udp_baseaddr = ioremap(res->start, res->end - res->start + 1); @@ -1766,6 +1769,7 @@ fail0a: if (cpu_is_at91rm9200()) gpio_free(udc->board.pullup_pin); fail0: + iounmap(udc->udp_baseaddr); release_mem_region(res->start, res->end - res->start + 1); DBG("%s probe failed, %d\n", driver_name, retval); return retval; @@ -1792,6 +1796,9 @@ static int __exit at91udc_remove(struct free_irq(udc->udp_irq, udc); device_unregister(&udc->gadget.dev); + if (cpu_is_at91rm9200()) + gpio_free(udc->board.pullup_pin); + iounmap(udc->udp_baseaddr); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); release_mem_region(res->start, res->end - res->start + 1); --- at91.orig/include/asm-arm/arch-at91/board.h 2008-01-01 08:29:02.000000000 -0800 +++ at91/include/asm-arm/arch-at91/board.h 2008-01-01 08:33:26.000000000 -0800 @@ -40,7 +40,8 @@ /* USB Device */ struct at91_udc_data { u8 vbus_pin; /* high == host powering us */ - u8 pullup_pin; /* high == D+ pulled up */ + u8 pullup_pin; /* active == D+ pulled up */ + u8 pullup_inverted; /* true == pullup_pin is active low */ }; extern void __init at91_add_device_udc(struct at91_udc_data *data); - To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html