Adding accelerometer support to KoReader for Kindle Touch: Part 1

Adding accelerometer support to KoReader for Kindle Touch: Part 1

The Kindle 5/Kindle Touch includes a Freescale MMA8453Q accelerometer as part of its internal hardware. It seems to have been added to enable rotation control functionality similar to that found on the later Kindle Oasis model, but support for this feature was never fully implemented by Lab126.

The objective of this article is to permanently re-enable this hardware so that it is accessible by the Kindle. Once this is complete, we can patch KoReader to support rotation control based on the readings of this sensor.

Prior efforts

The presence of this accelerometer has been known about for a number of years; posts on the MobileRead forums indicate that the driver was included in previous firmware versions, but was later removed.

However, it is still possible to initialise the sensor without needing to compile a new kernel or kernel module. Although support is not present within the kernel or main partition, the kernel modules needed are still included within the diagnostics partition of the device.

Copying the kernel modules

To begin re-adding support for the accelerometer, we need to copy the required kernel module over to the main partition.

mntroot rw
mount /dev/mmcblk0p2 /mnt/mmc/
cp /mnt/mmc/lib/modules/2.6.31-rt11-lab126/kernel/arch/arm/mach-mx5/mx50_yoshi_mma8453.ko /lib/modules/2.6.31-rt11-lab126/kernel/drivers/input/keyboard/mx50_yoshi_mma8453.ko

Update dependency list and map files

We can use the insmod command to insert the modules into the kernel, but will need to use the full path when we do so. The paths to the modules are deeply nested and even with tab auto-completion, are tedious to type when adding the modules manually via the shell.

# Inserting modules
insmod /lib/modules/2.6.31-rt11-lab126/kernel/drivers/hwmon/hwmon.ko
insmod /lib/modules/2.6.31-rt11-lab126/kernel/drivers/input/keyboard/mx50_yoshi_mma8453.ko
# Removing modules
rmmod mx50_yoshi_mma8453
rmmod hwmon

By using depmod to update the list of kernel modules and associated map files, we can use the modprobe command to insert the module instead. modprobe handles the process of inserting kernel modules in the correct order, allowing us to replace the commands above with this:

# Do this once
depmod -a
# Inserting module
modprobe mx50_yoshi_mma8453
# Removing module
modprobe -r mx50_yoshi_mma8453

Running lsmod after modprobe mx50_yoshi_mma8453 command shows that both the mx50_yoshi_mma8453 and hwmon modules have been loaded successfully:

[root@kindle root]# lsmod
Module                  Size  Used by
mx50_yoshi_mma8453      8836  0 
hwmon                   2108  1 mx50_yoshi_mma8453
ar6003                344992  0 
g_ether                27444  0 
arcotg_udc             35944  1 g_ether
pkt_monitor             3480  0 
zforce                 24944  0 
whitney_button          6664  0 
fuse                   57256  2 
uio_pdrv_genirq         2688  0 
mxc_epdc_fb            42080  3 
eink_fb_waveform      557320  1 mxc_epdc_fb

Instantiating accelerometer

At this point, the required kernel modules needed to handle input from the sensor have been loaded, but the accelerometer itself has not been initialised. @baf on the MobileRead forum examined the source code provided by Amazon and was able to establish that the accelerometer was an I2C device; support was enabled in previous kernels by setting the CONFIG_MX50_YOSHI_MMA8453 flag at kernel compile time. They were also able to instantiate the I2C device from user-space by writing to the new_device attribute file exposed by the I2C driver:

echo mma8453 0x1c > /sys/devices/virtual/i2c-adapter/i2c-0/new_device

Checking the kernel log with dmesg after running the above command confirms his finding that the device can be successfully instantiated and appears as an input device located at /dev/input/event4:

add mma8453 i2c driver
i2c-adapter i2c-0: The new_device interface is still experimental and may change in a near future
input: mma8453 as /devices/virtual/i2c-adapter/i2c-0/0-001c/input/input5
check mma8453 chip ID
mma8453 0-001c: build time Nov  3 2011 11:21:40
i2c-adapter i2c-0: new_device: Instantiated device mma8453 at 0x1c

Enabling accelerometer on boot

It is now possible for us to access the accelerometer, but we would need to load the required kernel modules and instantiate the accelerometer every time that the Kindle reboots. To avoid this, we will modify the Kindle boot scripts to enable the accelerometer alongside the rest of the input modules.

The Kindle uses Upstart as its init system and the configuration files for this are located within the /etc/upstart/ directory; in this case we will be editing /etc/upstart/modules.conf.

At line 41 of the file, the Kindle board type is checked and various kernel modules are loaded accordingly. The board name for the Kindle Touch is whitney and the whitney_button module is passed to a function called f_modprobe:

  case "$(f_board)" in
    whitney) f_modprobe whitney_button ;;
    yoshi)   f_modprobe mxc_keyb ;;
    *)       f_emit loaded_fakekey ;;

This function is located within /etc/upstart/functions and attempts to insert the specified module into the kernel. If the module is inserted successfully, an initctl event is emitted, otherwise the failure is logged.

f_modprobe() {
 f_log I modules modprobe "loading module $1"
 ( modprobe $* && f_emit loaded_$1 ) || f_log C modules modprobe_failed "failed to load module $1"

To enable the accelerometer on boot, edit the case statement above to load the mx50_yoshi_mma8453 module and initialise the accelerometer:

  case "$(f_board)" in
      f_modprobe whitney_button
      f_modprobe mx50_yoshi_mma8453
      /bin/echo mma8453 0x1c > /sys/devices/virtual/i2c-adapter/i2c-0/new_device   
    yoshi)   f_modprobe mxc_keyb ;;
    *)       f_emit loaded_fakekey ;;


We have now probed the device to check for the presence of the accelerometer, added the required kernel modules to the main partition and edited the Kindle boot scripts to enable the sensor on boot. The next task is to patch KoReader to utilise this support; this will be covered in part 2 of this article.