I would like being able to test patches on the Droid 4 without having to carry a development phone around all the time. Testing on my day-to-day phone is not a good idea, since that means being offline during the tests. A simple solution would be to do the testing remotely, which should also allow doing automated tests for KernelCI. Unfortunatley doing this on a phone is a bit harder than on an average development board due to the hardware design. Remote testing requires three things:
- Access to debug / serial console
- Automated way to force power on/off (reset) the device
- Possibility to upload new kernel
On Droid 4 the serial console is multiplexed on the USB port, so that can be easily solved by connecting a serial cable (3.3V TTL) to the phone’s microUSB port. Unfortunately that means the phone will run out of battery after some time (serial only works when 5V is not attached). Also copying the kernel cannot be copied via USB that way. So either transmission must be done wireless (WLAN, bluetooth) or exchanged directly on the SD card.
To solve the battery issue I removed the phone’s battery and soldered some wires to the + and - connectors. I connected those to a DC-DC buck converter step down module configured to output 3.7V. The other side of the DC-DC can be supplied with 5V, so that the phone can be powered directly from USB. This solves the issue of having to worry about an empty battery whenever one wants to develop or test patches. Also it’s possible to easily poweroff the phone by unplugging the USB connector, which brings us to the next step:
When we attach the phone’s power-supply USB connector to a USB hub
uhubctl (github project),
we can actually forcibly poweroff the phone using software. Unfortunately
the Droid 4 will not power on automatically when “battery” is plugged in.
I’m aware of two methods to power on the phone: Either press the power button or insert a USB cable. Replacing the button is a bit of work, so I went for the USB option. For this I build a Y-cable with MicroUSB connector on one side, data lines go to a USB-serial converter, GND is split to USB-serial converter and a USB-A connector and Vcc is connected to the same USB-A connector. Now both can be plugged into the USB hub and the phone can be powered on by enabling the port with the USB-A connector. It needs to be disabled again to get serial output working.
Last but not least I had to find a way to upload new kernel, modules,
… to the phone. For this a colleague from Collabora pointed me to
SDWire, which can be
connected to the phone using a µSD extension cable. That device allows
to multiplex a SD card to either the SD card slot from the phone or
a USB card reader. The multiplexing is also done via USB, i.e. using
sd-mux-ctrl (github project).
With that everything is in place to do remote testing of the Droid 4.
Laptop -> [USB Hub]
Port 1 -> Voltage regulator as battery replacement
Port 2 -> Power lines are connected to phone USB port
Port 3 -> USB-Serial dongle connected to Phone USB port
Port 4 -> SDWire + µSD extension cable
- Connect SD-card to laptop:
sd-mux-ctrl -e sdwire-23 -s
- Mount SD card, copy kernel/…, umount SD card
- Connect SD-card to phone:
sd-mux-ctrl -e sdwire-23 -d
- Open serial port:
picocom -b 115200 /dev/ttyUSB0
- Power on 'battery':
uhubctl --vendor 2109:2811 -p 1 -a 1
- Power on USB 'cable':
uhubctl --vendor 2109:2811 -p 2 -a 1
- Power off USB 'cable':
uhubctl --vendor 2109:2811 -p 2 -a 0
- Do the tests :)
- Power off 'battery':
uhubctl --vendor 2109:2811 -p 1 -a 0
Unfortunately there are two annoying issues: The FTDI driver (
seems to have some problems being connected to the USB hub. After a few seconds/minutes
errors appear in the kernel log and the device stops functioning until the serial
software is restarted. This can be avoided by connecting the USB-serial adapter to
a different USB port.
Also the mainline kernel has problems being powered on by plugging in the USB
cable at the moment (5.4-rc1). During early boot the kernel will crash with a
The root cause has not yet been found.
Update: The issue can be avoided by disabling