Friday, 17 October 2008

USB host mode on the Treo 650

Previously I'd always just assumed the USB host pins were separate from the USB client ones, so we wouldn't be able to use the USB port on the multiconnector as a host. Turns out I was wrong. Sleep_Walker pointed out that the PXA27x's USB client pins can the routed to the host controller. I had to try it. So I cut the USB connectors of an old dead motherboard with a jigsaw and soldered the D+ pins and D- pins of each connector respectively together. I then ran +5V from my PC because the Treo can't supply it. Any +5V source should do, so a battery pack or some kind of charge powered by the treo's 3.7V output would also work, the PC was just the closest handy source. I then configured USB port 2 in host mode and powered it up.
I found low-speed devices (like old mice) just work, but full-speed (USB1.1+ devices) fail to detect. There seems to be an extra strong pull-down on the USB+ pin, probably as part of the USB client hardware. To get around this we can turn on the Treo's own usb client pullups and trick itself into realising there's a full-speed device attached. ;-) Anyway here's the result, a USB keyboard (with builtin hub) and mouse controlling the Treo directly:

Virtually every USB device with a Linux driver I've tried works. I'm looking to get a USB wifi dongle. Not sure it'll be so easy to mount inside as the Eee PC upgrades are. ;-) Update: Sleep_Walker has now tried the same thing on the 680. He reports that there's no pulldown problems on the 680 so full-speed devices detect correctly without any hacks. He also tried a slightly easy way of doing it, all you need is standard powered USB hub (to supply the +5V) and a USB gender changer, no soldering required.

Friday, 10 October 2008

Success: Two-way phone call with Treo 650 in Linux

Now that I have a VOIP account that can make unmetered calls to mobiles I decided to try having a play with getting two-way phone calls working from Linux on the Treo 650. I turned on the phone part in Palm OS, booted this kernel and reset the power on the gsm module with:
echo 0 > /sys/devices/platform/palmt650-pm-gsm/power_on
echo 1 > /sys/devices/platform/palmt650-pm-gsm/power_on
echo 1 > /sys/devices/platform/palmt650-pm-gsm/wake
I then fired open minicom and opened /dev/ttyS0 at baud 460800 without flow control. I then connected the modem to the network and entered my subsidy unlock pin:
Once connected, I called my phone via VOIP and then answered with the ATA command:

At that point I opened up a few terminal windows and started fiddling with ALSA. I first started playing some white noise so I could heer when I started transmitting:
cat /dev/urandom > /dev/dsp
I discovered you can divert PCM to be transmitted by the phone using:
      Master Mono: Enable, set transmit volume
              PCM: Enable, set PCM volume
PCM Play to Phone: Enable to route PCM signal to the phone module
After some more fiddling I routed the microphone to the phone. The labeling of the Mic controls in the ALSA driver is rather strange but here are the key settings:
      Master Mono: Enable, set transmit volume
Mic Select Source: mic1=handset, mic2=headset
            Mic 2: Selected mic volume
   Mic 1 to phone: Enable/disable handset mic 
   Mic 2 to phone: Enable/disable oheadset mic
   Mic 20dB Boost: Useful in speakerphone mode, you can talk from quite a distance.

Mic 1: [irrelevant?]
Mic select:  [irrelevant?]
After that I managed to get the incoming audio going out the handset earpiece with these settings:
         Master: Enable, earpiece volume
Master Left Inv: Enable
          Phone: Seems you don't need to unmute, but need to set volume.
Phone to Master: Enable
            Aux: Set a high volume (weird stuff happens if low)
    Out3 LR Mux: Master Mix (mislabeled, it's actually out2)
I've made an ALSA state file for working two-way phone audio with the handset.