From PINE64
Jump to navigation Jump to search

!Modem on PinePhone

This page is taken from Megi's site.

Quectel EG25-G modem in PinePhone handles WWAN, GPS and cellular services. It is based on Qualcomm MDM 9607 chipset, has 256 MiB DRAM, 256 MiB NAND, and a single Cortex-A7 CPU clocked up to 1.3GHz.

The modem's fir­mware is split into two parts:

   Linux kernel + userspace runs on an ARM CPU
   Modem's fir­mware runs on Hexagon ADSP

Most AT commands are run on a separate DSP processor cores (Hexagon QDSP6 V5), with some being forwarded to a Linux userspace program called atfwd_daemon running on the ARM CPU.

Reverse engineering the existing software for ARM CPU inside the modem is quite easy using ghidra. ADB unlocker was made this way. Modem power driver

My kernel is a bit special, since it contains a special modem power manager driver (released 2020–08–03 along with Linux 5.8).

My driver implements several features:

   it ensures modem is configured properly for audio and sleep
   it implements airplane mode via rfkill interface
   it implements modem suspend/resume
   it hides PinePhone variant differences
   it implements URC caching on all pinephone variants regardless of AP_READY availability
   it makes the modem sleep most of the time
   it handles powerup/po­werdown errors properly
   it checks for killswitch and reports it to userspace/dmesg
   it doesn't waste time during powerdown and waits for actual modem powerdown (it doesn't just sleep for a fixed time)
   it handles SoC wakeup on RI
   it shuts down the modem properly during kernel powerdown/re­boot to avoid data loss inside the modem's NAN­D flash
   it reports all errors to dmesg for easy troublesho­oting/failu­re detection

Enabling and disabling the power to the modem is as simple as:

  1. request powerup

echo 1 > /sys/class/modem-power/modem-power/device/powered

  1. request powerdown

echo 0 > /sys/class/modem-power/modem-power/device/powered

  1. read power status (changes only after power state transition is complete)

cat /sys/class/modem-power/modem-power/device/powered

So there's no need to mess with gpios via sysfs. Connecting to the modem

You can connect to the modem once it's powered up via:

screen /dev/ttyUSB2 115200

Disconnect by CTRL+a k. Setting up the modem for voice calling

Once per a lifetime you have to run AT+QDAI=1,0,0,2,0,1,1,1 and reboot the modem. That will configure audio on the modem side correctly and store the configuration persistently inside the modem. This is not necessary if you use my modem driver.

To setup audio for call use my call audio setup program.

You need to run the program after the call starts twice. Once with your desired audio setup without -2 option and once with -2 option.

To answer a call type ATA, to make a call ATDsomenumber;, to hangup ATH.

That's it. ;)

!!Modem reverse engineering

See this page for details.

!!Unlock ADB access

It's possible to access the Linux side of the modem via adb, or reboot the modem to fastboot mode and boot your own kernel, The modem is rooted by default, and you can install and run your own software inside the modem. It's possible to communicate between A64 and the modem's ARM CPU via USB serial port (ttyGS0 on modem side and ttyUSB1 on A64).

It's also possible to create your own URCs up to 128B in size by sending them as a datagram message to UNIX socket /tmp/.urc_sock. See urc.c.

To install your own program on the modem persistently you need to remount modem's root filesystem read write and install your program somewhere in /usr/bin. Add your startup script to /etc/init.d.

To get adb access to the modem:

   Get adb key via AT+QADBKEY?
   Enter the adb key to the unlocker utility
   Follow the instructions from the qadbkey-unlock
   Install or get adb for your distribution
   adb shell should get you a root shell on the modem
   adb pull and adb push can be used to copy files to/from the modem

On Arch Linux ARM, adb is in the AUR.

!!Modem power management

Various PinePhone variants have SoC GPIOs routed to the modem differently. So you need to be aware of what PinePhone variant you have, when experimenting with the modem.

Power management comes down to:

   letting the modem sleep when it's not in use, and waking it up when it's needed for something,
   and letting the host sleep, and configure the modem to wake the host up, when some important event happens (incoming call, sms, …).

Summary of modem's be­havior related to powerup/po­werdown and power management:

   powerup takes about 14s, unless the modem is too hot (>50–60°C), then it may take as long as 22s due to CPU inside the modem being downclocked from 1.3Ghz to 400MHz
   configuration of the physical UART and ttyUSB2 is shared for some reason, so ATE0 issued on UART will turn echo off also on ttyUSB2
   modem sleeps when an election process based on the status of USB port, DTR pin, etc. results in a positive decision
   modem disables RF based on #W_DISABLE only when configured to do so via AT+QCFG="airplanecontrol"
   modem wakes up the host via USB or RI pin based on AT+QCFG="risignaltype"
   modem will cache URCs based on AP_READY pin's status only when AT+QCFG="apready" is configured
   powerdown takes about the same time as powerup