FMRX-Enabler for Nokia N900 Smartphone (Developer's Information)

by Martin Grimme

1. Introduction

The Nokia N900 smartphone has a FM receiver built-in, but the hardware is disabled by default. The FMRX-Enabler is a D-Bus service for enabling the FM receiver on request by applications. It also takes care about powering down the FM receiver hardware again when no applications are using it anymore.

2. Dependency for FM radio applications

Applications that want to use the FM radio should specify the package n900-fmrx-enabler as dependency. That way they can be sure to be able to request enabling the FM receiver hardware.

3. D-Bus Interface

The D-Bus interface of the FMRX-Enabler is on the system bus:

There is one method for requesting to enable the FM receiver hardware:

request(): (status, device)

Requests to enable the FM receiver and returns a tuple consisting of a return status code and the path to the device file for controlling the FM radio. Repeatedly invoke this method (about once per minute) while using the FM radio to avoid the FMRX-Enabler to power the FM receiver down.

The return status code is one of:

Example using dbus-send in the shell:

dbus-send --system --print-reply \
          --dest=de.pycage.FMRXEnabler \
          /de/pycage/FMRXEnabler\
          de.pycage.FMRXEnabler.request

Example code in Python:

import dbus

bus = dbus.SystemBus()
obj = bus.get_object("de.pycage.FMRXEnabler", "/de/pycage/FMRXEnabler")
enabler = dbus.Interface(obj, "de.pycage.FMRXEnabler")
status, device = enabler.request()

4. Control Interfaces

The FM radio driver provides two interfaces for controlling the receiver.

Video4Linux2 Interface

The Video4Linux2 (V4L2) interface can be used by opening the device file that was returned by the request() method. It is a standard V4L2 interface supporting these ioctl operations:

The Python module pyFMRadio allows controlling the V4L2 radio driver in Python.

sysfs Interface

Many features of the FM radio driver are only available through its sysfs interface.

The proper path of the sysfs interface can, for instance, be found using this shell command:

F=`find /sys/class/i2c-adapter -name "fm_frequency"`
SYSFS_HOME=`dirname ${F}`

Only root can write values using the sysfs interface.

The supplied test script /usr/bin/fmradio-tool demonstrates controlling the radio with the sysfs interface.

5. Getting Sound

The FM receiver in the N900 does not directly send output to the speakers. You have to enable the PGA Line2 and capture audio from PGA:

# set input source
amixer -qc0 cset iface=MIXER,name='Input Select' 'ADC'
amixer -qc0 cset iface=MIXER,name='PGA Capture Switch' on

# enable line 
amixer -qc0 cset iface=MIXER,name='Left PGA Mixer Line2L Switch' on
amixer -qc0 cset iface=MIXER,name='Right PGA Mixer Line2R Switch' on

Mixer Settings for Headphone Output

amixer -qc0 cset iface=MIXER,name='Left DAC_L1 Mixer Line Switch' on
amixer -qc0 cset iface=MIXER,name='Left DAC_L1 Mixer HP Switch' off
amixer -qc0 cset iface=MIXER,name='Right DAC_R1 Mixer Line Switch' on
amixer -qc0 cset iface=MIXER,name='Right DAC_R1 Mixer HP Switch' off

amixer -qc0 cset iface=MIXER,name='HP DAC Playback Volume' 0,0
amixer -qc0 cset iface=MIXER,name='Speaker Function' 0

Mixer Settings for Speaker Output

# set headphone volume low or it will blow your ears away :)
amixer -qc0 cset iface=MIXER,name='Headphone Playback Volume' 5,5
  
amixer -qc0 cset iface=MIXER,name='Left DAC_L1 Mixer Line Switch' off
amixer -qc0 cset iface=MIXER,name='Left DAC_L1 Mixer HP Switch' on
amixer -qc0 cset iface=MIXER,name='Right DAC_R1 Mixer Line Switch' off
amixer -qc0 cset iface=MIXER,name='Right DAC_R1 Mixer HP Switch' on

amixer -qc0 cset iface=MIXER,name='HP DAC Playback Volume' 50,50
amixer -qc0 cset iface=MIXER,name='Speaker Function' 1

Piping Sound through Pulseaudio

With these mixer settings you can just pipe the sound through pulseaudio, like this:

gst-launch pulsesrc ! pulsesink

This captures the sound from the PGA and outputs it through Pulseaudio.