Hi David,
On Jan 2, 2008, at 1:36 AM, David Brownell wrote:
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.
I'm just the fire brigade called after the kiddies have been playing
with matches. ;-)
Actually it's floating, PC4 directly drives a PNP transistor through
a 4.7k, one side of the PNP is connected to the 3v3 rail
the other side through a limiting resistor to the D+
( Remember a few weeks back where there was a discussion about the,
the USART and how I should let the USARTS init
then re-write my changes to the registers in the Board file ,
rather than change the existing USART code when not all pins were
implemented)
And I pointed out how dangerous that might be, well here's an example.
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].
a.)That's why I added the code to initially set the flag to 1, but
I cannot see why my patch would break existing boards.
b.). Yes sorry about that it won't happen again , I was in the
process of merging forward.
Just a couple of questions,
1. The way the patch is now:
int active = !udc->board.pullup_inverted;
will that not force all existing code bases to implement a patch to
add 'pullup_inverted'
to their board code because an initial state of active is not set ,
in any existing board code ?
(which is what i specifically tried to avoid)
Also the name "pullup_inverted" suggests a negative situation
I.E
pullup_inverted = 0; (do not invert the signal)
pullup_inverted = 1; (do invert the signal)
Whereas the reverse is actually true.
2. What happends if the user passes in a value that is not 1 or 0 ,
will the call
gpio_set_value , automatically mask it off?
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.
That would be great and I would really appreciate it.
Steve
- 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