USB host

From Openmoko

Revision as of 14:29, 3 February 2009 by Calamar (Talk | contribs)

Jump to: navigation, search

The mini-USB port on both the Neo 1973 and the Neo FreeRunner supports both USB host and USB device. This opens up a range of possibilities, such as adding USB cameras and USB input devices.

Contents

Using USB host mode

Selecting USB host modes

By default, the mini-USB port is in device mode. To tell the Neo that it is logically a host¹:

# echo host > /sys/devices/platform/s3c2410-ohci/usb_mode

Independent of the logical mode of the USB port, the Neo FreeRunner can provide 5 volt USB power to an attached USB device. To enable this (not available on Neo 1973):

# echo 1 > /sys/devices/platform/neo1973-pm-host.0/hostmode

Note: You may want to run ifconfig usb0 down prior to switching to USB host mode, as the Neo's USB networking may not like having its USB port disappear. You'll probably want to ssh into your Neo over WiFi or Bluetooth before starting all of this, alternatively use an on screen keyboard.

Note that in full USB host mode the FreeRunner will power the external device. To avoid draining the battery use a powered USB hub, then on the FreeRunner enable logical host mode:

# echo host > /sys/devices/platform/s3c2410-ohci/usb_mode

but NOT electrical host mode

# echo 0 > /sys/devices/platform/neo1973-pm-host.0/hostmode

Note that powered USB hubs do not send power upstream, that is, into the host. If you wish to power or charge the FreeRunner, you will need a special USB cable.

¹)Debian note: You'll need the ohci-hcd module: modprobe ohci-hcd

  • NOTE: with [FSO] based distributions one should use the dbus APIs and not the method stated above.

Returning to USB device mode

After doing whatever is needed to safely remove your device and unplugging it you can remove the provision of 5 volt power and return to device mode.

echo 0 > /sys/devices/platform/neo1973-pm-host.0/hostmode
echo device > /sys/devices/platform/s3c2410-ohci/usb_mode

You can now safely restart USB networking

ifconfig usb0 up

USB-Mode-Script

This simple script switches between USB-Modes:

#!/bin/sh
grep -q 'host' /sys/devices/platform/s3c2410-ohci/usb_mode
if [ $? -eq 0 ]
then
echo 0 > /sys/devices/platform/neo1973-pm-host.0/hostmode
echo device > /sys/devices/platform/s3c2410-ohci/usb_mode
ifconfig usb0 up
echo USB-Port is in device-mode now.
else
ifconfig usb0 down
echo host > /sys/devices/platform/s3c2410-ohci/usb_mode
echo 1 > /sys/devices/platform/neo1973-pm-host.0/hostmode
lsusb
echo USB-Port is in host-mode now.
fi

See this bug for a justification for adding the lsusb hack.

USB-Mode-Script (2.6.28+ kernels)

The paths change slightly since 2.6.28:

#!/bin/sh
grep -q 'host' /sys/devices/platform/s3c2410-ohci/usb_mode
if [ $? -eq 0 ]
then
echo 0 > /sys/class/i2c-adapter/i2c-0/0-0073/neo1973-pm-host.0/hostmode 
echo device > /sys/devices/platform/s3c2410-ohci/usb_mode
ifconfig usb0 up
echo USB-Port is in device-mode now.
else
ifconfig usb0 down
echo host > /sys/devices/platform/s3c2410-ohci/usb_mode
echo 1 > /sys/class/i2c-adapter/i2c-0/0-0073/neo1973-pm-host.0/hostmode
lsusb
echo USB-Port is in host-mode now.
fi

Using a GUI

Providing power to connected USB devices while in host mode

Normally, USB host ports provide power to any connected USB device.

Available power in host mode is the full maximum of 500mA according to USB-specifications on the Neo FreeRunner, and no power is available in host mode on the Neo 1973. If your USB device respects USB-standards and consumes not more than 500mA, you may connect it directly to your Neo FreeRunner.

To provide power to USB devices attached to your Neo 1973, or to provide power to your Neo FreeRunner while USB-device connected, you can provide power by using a (modified [for powering FreeRunner]) powered USB hub (see below), or by manually injecting power into the attached USB device (and Neo FreeRunner) via one of the specialized_USB_cables.

Powered USB hubs known to work with the Neo

(please add any known to work)

Providing power to run and charge the Neo while in host mode

A slightly separate issue is power to run and charge the Neo (both types) itself. When the USB port is in device mode, the Neo FreeRunner/1973 can be powered and recharged via the USB port, but when in standard host mode, the Neo FreeRunner is set to provide power and does not charge. Fortunately, control of the direction of power (in or out) is independent of the personality of the USB port (host or device):

To recap, the direction of power can be controlled:

Set to 0 (default), no power is provided at the USB port, charging is enabled, and host 15K pulldowns are removed from D+ and D-:

echo 0 > /sys/devices/platform/neo1973-pm-host.0/hostmode

Set to 1, provides up to 500mA USB power at the USB port (FreeRunner only), disables charging from USB, and applies 15K pulldowns to USB D+ and D-:

echo 1 > /sys/devices/platform/neo1973-pm-host.0/hostmode

Next, power must somehow be injected. An unmodified powered USB hub only provides power to the connected devices, but not to the connected host, so the only solution here is to modify a USB-hub¹) or to create a custom cable which will inject power into the host. See specialized_USB_cables for some examples.

(However, as there is a wide range[1] of USB hubs out there, one might find power (on a powered USB hub) is available already on the hub's mini USB 5 pin socket already, so not need a specialized cable after all! Check with a test meter.)

Finally, there is the question of charge rate. The charging logic in the Neo will only charge at 100mA by default. Charging at 500mA will take place only if the charging device responds appropriatly to USB negotiation to increase power consumption. Charging at 1000mA will only take place if the Neo detects the appropriate resistor on the ID pins.

You can manually set the charge rate. See Forcing_fast_charge_mode

¹) often it's sufficient to short a diode in USB-hub to feed power to the host-connector too.

  1. Edit 05 Oct. 2008 : Not being able to find any diode on my (Henrikz) USB Hub (Brand: Equip, Type: 4 port, aluminum) I simply connected +5V (pin 1) from one of the downstream ports to pin 1 of the upstream port.

Power Concerns

You'll need to force the Neo to go into fast charge mode, since it can't do its usual power negotiation over USB.

echo -n fast_cccv >  /sys/devices/platform/s3c2410-i2c/i2c-adapter/i2c-0/0-0008/chgmode

(Also this should be done by kernel when seeing 47K at ID-pin)

Working Examples

USB Keyboard

Pictures here

Connecting a USB-Stick

Connecting-usb-stick-1.jpg

I found this adapter, it has 2 Type A jacks, rather cheap (about 5 €).

Connecting-usb-stick-2.jpg

I borrowed the cable from a card reader, it has the same pinout like the cable that comes with the Neo.

Connecting-usb-stick-3.jpg

With the above commands I could mount the memory stick.

Connecting-usb-stick-4.jpg


Personal tools

The mini-USB port on both the Neo 1973 and the Neo FreeRunner supports both USB host and USB device. This opens up a range of possibilities, such as adding USB cameras and USB input devices.

Using USB host mode

Selecting USB host modes

By default, the mini-USB port is in device mode. To tell the Neo that it is logically a host¹:

# echo host > /sys/devices/platform/s3c2410-ohci/usb_mode

Independent of the logical mode of the USB port, the Neo FreeRunner can provide 5 volt USB power to an attached USB device. To enable this (not available on Neo 1973):

# echo 1 > /sys/devices/platform/neo1973-pm-host.0/hostmode

Note: You may want to run ifconfig usb0 down prior to switching to USB host mode, as the Neo's USB networking may not like having its USB port disappear. You'll probably want to ssh into your Neo over WiFi or Bluetooth before starting all of this, alternatively use an on screen keyboard.

Note that in full USB host mode the FreeRunner will power the external device. To avoid draining the battery use a powered USB hub, then on the FreeRunner enable logical host mode:

# echo host > /sys/devices/platform/s3c2410-ohci/usb_mode

but NOT electrical host mode

# echo 0 > /sys/devices/platform/neo1973-pm-host.0/hostmode

Note that powered USB hubs do not send power upstream, that is, into the host. If you wish to power or charge the FreeRunner, you will need a special USB cable.

¹)Debian note: You'll need the ohci-hcd module: modprobe ohci-hcd

  • NOTE: with [FSO] based distributions one should use the dbus APIs and not the method stated above.

Returning to USB device mode

After doing whatever is needed to safely remove your device and unplugging it you can remove the provision of 5 volt power and return to device mode.

echo 0 > /sys/devices/platform/neo1973-pm-host.0/hostmode
echo device > /sys/devices/platform/s3c2410-ohci/usb_mode

You can now safely restart USB networking

ifconfig usb0 up

USB-Mode-Script

This simple script switches between USB-Modes:

#!/bin/sh
grep -q 'host' /sys/devices/platform/s3c2410-ohci/usb_mode
if [ $? -eq 0 ]
then
echo 0 > /sys/devices/platform/neo1973-pm-host.0/hostmode
echo device > /sys/devices/platform/s3c2410-ohci/usb_mode
ifconfig usb0 up
echo USB-Port is in device-mode now.
else
ifconfig usb0 down
echo host > /sys/devices/platform/s3c2410-ohci/usb_mode
echo 1 > /sys/devices/platform/neo1973-pm-host.0/hostmode
lsusb
echo USB-Port is in host-mode now.
fi

See this bug for a justification for adding the lsusb hack.

USB-Mode-Script (2.6.28+ kernels)

The paths change slightly since 2.6.28:

#!/bin/sh
grep -q 'host' /sys/devices/platform/s3c2410-ohci/usb_mode
if [ $? -eq 0 ]
then
echo 0 > /sys/class/i2c-adapter/i2c-0/0-0073/neo1973-pm-host.0/hostmode 
echo device > /sys/devices/platform/s3c2410-ohci/usb_mode
ifconfig usb0 up
echo USB-Port is in device-mode now.
else
ifconfig usb0 down
echo host > /sys/devices/platform/s3c2410-ohci/usb_mode
echo 1 > /sys/class/i2c-adapter/i2c-0/0-0073/neo1973-pm-host.0/hostmode
lsusb
echo USB-Port is in host-mode now.
fi

Using a GUI

Providing power to connected USB devices while in host mode

Normally, USB host ports provide power to any connected USB device.

Available power in host mode is the full maximum of 500mA according to USB-specifications on the Neo FreeRunner, and no power is available in host mode on the Neo 1973. If your USB device respects USB-standards and consumes not more than 500mA, you may connect it directly to your Neo FreeRunner.

To provide power to USB devices attached to your Neo 1973, or to provide power to your Neo FreeRunner while USB-device connected, you can provide power by using a (modified [for powering FreeRunner]) powered USB hub (see below), or by manually injecting power into the attached USB device (and Neo FreeRunner) via one of the specialized_USB_cables.

Powered USB hubs known to work with the Neo

(please add any known to work)

Providing power to run and charge the Neo while in host mode

A slightly separate issue is power to run and charge the Neo (both types) itself. When the USB port is in device mode, the Neo FreeRunner/1973 can be powered and recharged via the USB port, but when in standard host mode, the Neo FreeRunner is set to provide power and does not charge. Fortunately, control of the direction of power (in or out) is independent of the personality of the USB port (host or device):

To recap, the direction of power can be controlled:

Set to 0 (default), no power is provided at the USB port, charging is enabled, and host 15K pulldowns are removed from D+ and D-:

echo 0 > /sys/devices/platform/neo1973-pm-host.0/hostmode

Set to 1, provides up to 500mA USB power at the USB port (FreeRunner only), disables charging from USB, and applies 15K pulldowns to USB D+ and D-:

echo 1 > /sys/devices/platform/neo1973-pm-host.0/hostmode

Next, power must somehow be injected. An unmodified powered USB hub only provides power to the connected devices, but not to the connected host, so the only solution here is to modify a USB-hub¹) or to create a custom cable which will inject power into the host. See specialized_USB_cables for some examples.

(However, as there is a wide range[1] of USB hubs out there, one might find power (on a powered USB hub) is available already on the hub's mini USB 5 pin socket already, so not need a specialized cable after all! Check with a test meter.)

Finally, there is the question of charge rate. The charging logic in the Neo will only charge at 100mA by default. Charging at 500mA will take place only if the charging device responds appropriatly to USB negotiation to increase power consumption. Charging at 1000mA will only take place if the Neo detects the appropriate resistor on the ID pins.

You can manually set the charge rate. See Forcing_fast_charge_mode

¹) often it's sufficient to short a diode in USB-hub to feed power to the host-connector too.

  1. Edit 05 Oct. 2008 : Not being able to find any diode on my (Henrikz) USB Hub (Brand: Equip, Type: 4 port, aluminum) I simply connected +5V (pin 1) from one of the downstream ports to pin 1 of the upstream port.

Power Concerns

You'll need to force the Neo to go into fast charge mode, since it can't do its usual power negotiation over USB.

echo -n fast_cccv >  /sys/devices/platform/s3c2410-i2c/i2c-adapter/i2c-0/0-0008/chgmode

(Also this should be done by kernel when seeing 47K at ID-pin)

Working Examples

USB Keyboard

Pictures here

Connecting a USB-Stick

Connecting-usb-stick-1.jpg

I found this adapter, it has 2 Type A jacks, rather cheap (about 5 €).

Connecting-usb-stick-2.jpg

I borrowed the cable from a card reader, it has the same pinout like the cable that comes with the Neo.

Connecting-usb-stick-3.jpg

With the above commands I could mount the memory stick.

Connecting-usb-stick-4.jpg