← Back to team overview

ubuntu-phone team mailing list archive

FM Radio Status


Dear list,

TL;DR: Much progress was made, but it's complicated.

Thomas Voß and I spent quite some time finding out how the FM Radio
functionality is implemented and talking about how it could be
integrated. Because there is no standard, we have to pretty much handle
it differently for every manufacturer.


The good news: Our krillin/vegetahd (Aquaris E4.5/E5) kernels include
the mt6627 driver for the FM Radio, the firmware files are shipped with
our images (although in the wrong place), the radio is just a character
device ("/dev/fm"), and a couple of ioctl() calls are enough to power it
up and tune it to a frequency. I wrote a very ugly command line client
and pushed it to https://github.com/Sturmflut/mtkfmcli . If you tune it
to a known station, it will correctly report the increased signal
strength, so the chip seems to work.

The bad news: In theory the FM Radio should just be connected to the
audio chip as a normal input, and if you do a "pactl list sources" on
the phone you will see an input port called "input-fm". But if you
switch to it while the FM Radio chip is powered on and tuned, you don't
hear anything, not even the "typical" FM noise.

Turns out MediaTek requires you to call some ioctl()'s on the "/dev/eac"
character device and pass some magic values to enable the audio, and the
magic values seem to be different for every SoC. This is where it gets
ugly, because we're bypassing the platform audio system, and if
something fails, the phone has probably at least be rebooted to restore

The kernel sources published at https://github.com/bq/aquaris-E4.5 don't
contain all the userspace parts MediaTek usually ships, so we have to
refer to other repositories like
https://github.com/suribi/Thunder-Kernel and
https://github.com/JujuXIII/android_kernel_acer_v370_KK for more

Judging from the code there are two possibilities: Either extract the
magic values for every SoC and call the right ioctl()'s on /dev/eac on
our own, or use libhybris to call into the
"/android/system/lib/libaudio.primary.default.so" library, which seems
to offer a "SetFmEnable()" method that abstracts away the exact method
for the SoC in use. Until somebody tries both ways we won't know which
solution is the more viable one.

Also: The MT6627 chip in our devices does not seem to support FM transmit.


Judging from my Aquaris M5 running Android, at least some of the
Qualcomm devices have a "/dev/radio0" device and seem to comply to the
Video4Linux kernel API.

The Google Nexus devices are based on Qualcomm SoCs, but don't seem to
have an FM Radio.

The others

We have no idea about everything else than MediaTek and Qualcomm because
I don't have any other devices.

Future work

Since the whole FM Radio situation is complicated and only a few devices
actually have an FM Radio, we decided that adding FM Radio support to
the platform itself would be a maintenance burden for everybody. So FM
Radio should be implemented as a community-developed, "sideloaded" app
and the roadmap is something like this:

1. Extract the magic values for the MT6582/MT6627 chips first and extend
mtkfmcli into a fully-working command-line client.

2. If step 1 works, clean up the whole code, build a Qt/QML frontend for
mtkfmcli and publish it to the Open Store (we need access to special

3. If step 2 works, add features like RDS and collect more information
on other devices, then turn mtkfmcli into a generic solution for FM
Radio for Ubuntu.

I hereby invite everybody to contribute to mtkfmcli, especially if you
know about low-level Android stuff.


Follow ups