Archos A101 G9 "Turbo ICS" Linux notes

This is a collection of notes specific to a linux-based system. All of these notes are specific to the Archos 101 G9 Turbo and some things (such as kernel modules) might be different on non-Turbo models or Archos A80 G9 models, respectively. This notes are mostly system-independent. These notes are the basic low-level steps needed to provide specific functionalities on your native Linux system (e.g. Debian, Slackware or LFS) running on your Archos A101 G9 Turbo and might not be useful for Android systems.

Some work was already done beforehand by  BasysKom and the Mer Project. Packages and patches of their gen9 adaption is still alive on their OBS, provided by some people:


Hardware drivers / Kernel source

There two linux kernel sources available, knowing to work with the G9 series:

archos-gpl-gen9-kernel-ics

The archos-gpl-gen9-kernel-ics kernel provided by archos. It provides two branches: The (master) 3.0.8 and the linux-ics-3.0.21 branch. The latter one is basically what one might want, though there is trouble with the wifi driver.

archos-gen9-mer-adaption-kernel-ics

The  Mer gen9 adaption kernel source. This one also provides two branches: master and pvr. The master branch is the same as the archos-gpl-gen9-kernel-ics 3.0.8 branch with some additional patches/fixes. The pvr branch contains several fixes and additional OMAPDRM support. If OMAPDRM is not important for you, you might still want to get the fixes provided by the pvr branch. If you still insist on sticking with the master branch, take a look at  notmarts Mer adaption kernel package. (Note: The author uses the pvr branch of this kernel during all further kernel-related instructions)

Note: Whatever kernel you choose, if you use GCC >= 4.7 the compiled kernel will not boot unless you pass -mno-unaligned-access to the KBUILD_CFLAGS. There is a patch adding this flag in the  Mer adaption branches. (According to  this article, linaro-gcc is affected even in earlier versions)


Additional wl12xx and btwilink drivers

If you have problems getting the kernel-shipped versions of these drivers to work, or anyone of them is causing trouble (e.g. random connection loss, kernel oops), you might want to compile other versions provided by TI. Archos seemed to have taken  the same approach. For the author it was impossible to compile the archos-provided compat-wireless sources, but at least the TI version used by them -- r5.00.18-build_199 -- was helpful.

WLAN-OpenLink? / wl12xx

TI provides all the needed code on their  OpenLink github page. What we are interested in are the compat, compat-wireless and wl12xx repositories. Go to the work directory of your choice and clone these repositories: (Note: Let $WORKDIR be the directory you wish to work in)

$ cd $WORKDIR
$ git clone https://github.com/TI-OpenLink/compat.git
Cloning into 'compat'...
remote: Counting objects: 3658, done.
remote: Compressing objects: 100% (1495/1495), done.
remote: Total 3658 (delta 2100), reused 3657 (delta 2100)
Receiving objects: 100% (3658/3658), 1.11 MiB | 368 KiB/s, done.
Resolving deltas: 100% (2100/2100), done.
$ git clone https://github.com/TI-OpenLink/compat-wireless.git
Cloning into 'compat-wireless'...
remote: Counting objects: 8709, done.
remote: Compressing objects: 100% (3045/3045), done.
remote: Total 8709 (delta 5651), reused 8701 (delta 5648)
Receiving objects: 100% (8709/8709), 3.26 MiB | 1.06 MiB/s, done.
Resolving deltas: 100% (5651/5651), done.
$ git clone https://github.com/TI-OpenLink/wl12xx.git
Cloning into 'wl12xx'...
remote: Counting objects: 2379170, done.
remote: Compressing objects: 100% (363568/363568), done.
remote: Total 2379170 (delta 1993125), reused 2379074 (delta 1993039)
Receiving objects: 100% (2379170/2379170), 506.14 MiB | 1.11 MiB/s, done.
Resolving deltas: 100% (1993125/1993125), done.
Checking out files: 100% (37602/37602), done.

Now we need the correct branches of all of them. It is up to you to use the r5.00.18-build_199 tagged version of wl12xx or a newer one. The r5_3.2 branch is known to work well. For compat and compat-wireless, just checkout the master branches.

$ cd $WORKDIR/compat
$ git checkout master
Branch master set up to track remote branch master from origin.
Switched to a new branch 'master'
$ cd $WORKDIR/compat-wireless
$ git checkout master
Branch master set up to track remote branch master from origin.
Switched to a new branch 'master'
$ cd $WORKDIR/wl12xx
$ git checkout r5_3.2
Branch r5_3.2 set up to track remote branch r5_3.2 from origin.
Switched to a new branch 'r5_3.2'

(Note: If you wish to use the exact r5.00.18-build_199 version, replace r5_3.2 in the last git command with r5.00.18-build_199')

Now we are ready to import all the files into our compat-wireless tree:

$ cd $WORKDIR/compat-wireless
$ export GIT_TREE=$WORKDIR/wl12xx
$ export GIT_COMPAT_TREE=$WORKDIR/compat-wireless
$ ./scripts/admin-update.sh
... lots of output ...
Base tree: wl12xx.git
Base tree version: r5.00.19-build_257
compat-wireless release: ol_R5.SP6.01

In general people are cross-compiling stuff for their mobile devices, so these instructions are for this case. If you are not cross-compiling and your tablet is currently using the kernel you wish to compile the module for, then just run make. Otherwise, set KLIB to the proper directory in /lib/modules.

We are ready to to build our module. Set KLIB_BUILD to the path of the kernel-source and KLIB to the path of the module directory you wish to install the modules into. CROSS_COMPILE takes the prefix of the cross compiler, e.g. armv7a-unknown-linux-gnueabi- or arm-linux-gnu-. It depends on your toolchain.

$ make ARCH=arm CROSS_COMPILE=armv7a-unknown-linux-gnueabi- KLIB=/path/to/target/kernel/module/dir KLIB_BUILD=/path/to/target/kernel/dir
$ make ARCH=arm CROSS_COMPILE=armv7a-unknown-linux-gnueabi- KLIB=/path/to/target/kernel/module/dir KLIB_BUILD=/path/to/target/kernel/dir install-modules

For the firmware, just use the one provided by the Archos android system. (Note: The author used the NVS files from the archos image and the firmware from  the TI firmware repository)

TI Provides a already set-up and working bluetooth-compat tree in their  OmapZoom WPAN repository. Clone it, check it out and build it like the wl12xx driver: (Note: Instead of the ics-mr1-release branch, a newer one like jb-mr2-release might just work fine, though not tested)

$ cd $WORKDIR
$ git clone git://git.omapzoom.org/platform/hardware/ti/wpan.git
$ cd wpan
$ git checkout ics-mr1-release
$ cd bluetooth-compat
$ make ARCH=arm CROSS_COMPILE=armv7a-unknown-linux-gnueabi- KLIB=/path/to/target/kernel/module/dir KLIB_BUILD=/path/to/target/kernel/dir
$ make ARCH=arm CROSS_COMPILE=armv7a-unknown-linux-gnueabi- KLIB=/path/to/target/kernel/module/dir KLIB_BUILD=/path/to/target/kernel/dir bt-install-modules

You can now use your new btwilink driver. Note that you still need the uim-sysfs package for TI shared transport, i.e. having BT and Wifi working at the same time.


Bluetooth

For getting bluetooth to work, you will need  UIM.

$ cd $WORKDIR
$ git clone git://gitorious.org/uim/uim.git
$ cd uim
$ make CC=armv7a-unknown-linux-gnu-gcc

Copy the uim binary over to a binary dir on your tablet system, e.g. /sbin. Also, if it's not there, copy the 'TIInit_7.2.31.bts' from your android system over to '/lib/firmware/'. For starters, just start uim and load the btwilink module. The dmesg output should look like this:

Bluetooth: Core ver 2.16
NET: Registered protocol family 31
Bluetooth: HCI device and connection manager initialized
Bluetooth: HCI socket layer initialized
Bluetooth: L2CAP socket layer initialized
Bluetooth: SCO socket layer initialized
Bluetooth: Bluetooth Driver for TI WiLink - Version 1.0
(stc): st_register(4) 
(stc):  chnl_id list empty :4 
(stk) : st_kim_start
plat_kim_chip_enable
(stk) :ldisc_install = 1
Bluetooth: BNEP (Ethernet Emulation) ver 1.3
Bluetooth: BNEP filters: protocol multicast
(stc): st_tty_open 
(stk) :line discipline installed
(stk) :TIInit_7.2.31.bts
(stc): add_channel_to_table: id 4
(stc): st_register(2) 
(stc): add_channel_to_table: id 2
(stc): st_register(3) 
(stc): add_channel_to_table: id 3
Bluetooth: RFCOMM TTY layer initialized
Bluetooth: RFCOMM socket layer initialized
Bluetooth: RFCOMM ver 1.11
Bluetooth: HIDP (Human Interface Emulation) ver 1.2

You can now try to start your bluetooth service and try to pair a device, using your favourite BT frontend. If everything works fine, you will want to add a unit file/init script to your system, that UIM gets started automatically on system boot.

NOTE: There were issues in the authors case. If the wl12xx module is initializing itself (i.e. the network connection is established and the firmware is loaded) and the bluetooth module is loaded around that time, the wl12xx module just spits out errors. The currently used workaround is a 5 second sleep timeout after the network initialization script, before starting UIM and loading btwilink.

Here are some systemd unit files, as an example (Tested under ArchLinux?-ARM). It should be sufficient to load the btwilink module via systemds default way (/etc/modules-load.d) and just put the sleep command into the first unit file:

btwilink.service:

[Unit]
Description=Extra BTWiLink module loader
After=network.target
Before=uim.service

[Service]
Type=oneshot
ExecStart=/bin/sleep 5 ; /sbin/modprobe btwilink
KillMode=process

[Install]
WantedBy=multi-user.target

uim.service:

[Unit]
Description=UIM Shared transport service
After=network.target
Before=bluetooth.target

[Service]
ExecStart=/usr/sbin/uim
KillMode=process

[Install]
WantedBy=multi-user.target

Touchscreen

The A101 G9 Turbo was shipped with two different touchscreens. The kernel module pixcir_i2c_tsp or tr16c0-i2c is needed, respectively, for the system to recognize the specific touchscreen.

Note: Because my A101 G9 has a Touchplus TR16C0, I can only provide information for devices using the tr16c0-i2c driver. However, both of them support the following events: EV_SYN, EV_KEY, ABS_MT_SLOT, ABS_MT_POSITION_X, ABS_MT_POSITION_Y and ABS_MT_TRACKING_ID. I could provide an additional ABS_X/Y for the pixcir touchscreen like I provided for tr16c0, but I can't test it.

Getting the touchscreen to work: Kernel driver (TR16C0)

Basic setup

In case of a Touchplus TR16C0, you should find messages similar to this one in your dmesg output after loading the tr16c0-i2c module:

Note: There might also be some messages like tr16c0_i2c_tsp 4-005c: ping ? and tr16c0_i2c_tsp 4-005c: could not talk to tsp.). It is safe to ignore them as long as these last lines indicate that the driver registered an input-device.

tr16c0_i2c_tsp 4-005c: trying v2 fw
<3>54 33 05                                         T3.
tr16c0_i2c_tsp 4-005c: tr16c0_startup_sequence: v5.4.533 5 - 0x00000000
input: tr16c0_i2c_tsp as /devices/virtual/input/input9

You should now have a directory /sys/devices/virtual/input/input9 that contains a subdirectory eventX, where X is a number. This is the name of the device inode created under /dev/input. (i.e., if it contains a subdirectory event6, the corresponding device inode is /dev/input/event6). You can now test your device rudimentarily by running cat /dev/input/eventX and touch the display. You should get some unreadable binary output (and might have to reset your terminal afterwards). A better way to test the function of the touchscreen is by running evtest /dev/input/eventX. The following is an example evtest output of a short single-finger touch event on a free chosen point of the screen:

Input driver version is 1.0.1
Input device ID: bus 0x0 vendor 0x0 product 0x0 version 0x0
Input device name: "tr16c0_i2c_tsp"
Supported events:
  Event type 0 (EV_SYN)
  Event type 1 (EV_KEY)
  Event type 3 (EV_ABS)
    Event code 47 (ABS_MT_SLOT)
      Value      0
      Min        0
      Max        9
    Event code 53 (ABS_MT_POSITION_X)
      Value      0
      Min        0
      Max     1280
    Event code 54 (ABS_MT_POSITION_Y)
      Value      0
      Min        0
      Max      800
    Event code 57 (ABS_MT_TRACKING_ID)
      Value      0
      Min        0
      Max    65535
Properties:
Testing ... (interrupt to exit)
Event: time 2181.920959, type 3 (EV_ABS), code 57 (ABS_MT_TRACKING_ID), value 0
Event: time 2181.920959, type 3 (EV_ABS), code 53 (ABS_MT_POSITION_X), value 566
Event: time 2181.920989, type 3 (EV_ABS), code 54 (ABS_MT_POSITION_Y), value 385
Event: time 2181.920989, -------------- SYN_REPORT ------------
Event: time 2182.055053, type 3 (EV_ABS), code 57 (ABS_MT_TRACKING_ID), value -1
Event: time 2182.055053, -------------- SYN_REPORT ------------

Optional: Patch the driver for xf86-input-evdev compatibility

Because the tr16c0-i2c driver does not report any (single-touch) ABS_X/Y events to the system, but only (multi-touch) ABS_MT_* events, it is necessary to patch the kernel driver for the  xf86-input-evdev xorg driver to work, as it expects ABS_X/Y events for backwards compatibility reasons (older single-touch screens). Also, though that does not apply to the tr16c0 driver because it just populates all processed touch signals as finger touch events, ABS_X/Y is used for pen inputs, while the multitouch resources are used for finger touch input (TODO?)

The following  patch addresses this issue.

Optional: Setting up a symlink to the input device via udev

Depending on whether you plugged in some other USB devices (e.g. a USB keyboard, or a USB hub with some other input devices) that also create event interfaces, your device might not be called /dev/input/event6 all the time, though you might have some scripts that rely on it). You might want to create a symlink (in case of a static /dev, or via init-scripts) or let udev create a symlink (in case of a devtmpfs with udev). Usually, modern linux distributions use udev, so you just have to create a new file in /etc/udev/rules.d/, containing something like this:

KERNEL=="event*", SUBSYSTEM=="input", SUBSYSTEMS=="input", ATTRS{name}=="tr16c0_i2c_tsp", SYMLINK="input/touchscreen"

This udev rule creates a symlink pointing from /dev/input/touchscreen to the respective eventX device. This helps writing scripts and using utilities. Xorg itself can detect the device by the used driver and won't use this symlink.

You are now ready to use it with Xorg.

Getting the touchscreen to work: Xorg input

There are different input drivers available (these are just the one I tried):

xf86-input-evdev

Note: xf86-input-evdev will not work unless you patch your kernel driver.

xf86-input-evdev is one of the default Xorg input drivers. The main advantage is that most utilities work together with it, like touchegg (and therefore kde multitouch gestures, which is just a fork of touchegg), because ist just reports the plain events to the userland.

Put the following code into a file in /etc/X11/xorg.conf.d/:

Section "InputClass"
    Identifier "Archos Touchscreen"
    MatchProduct "tr16c0_i2c_tsp"
    Option "Ignore" "off"
    Option "CorePointer" "on"
    Driver "evdev"
EndSection

It should work right out of the box. Enjoy!

xf86-input-mtev

xf86-input-mtev should work for TR16C0, by using the  patches of the MeeGo community. If these don't work there is also another  patchset on OE-lite.

This driver preprocesses the multitouch gestures as button events. This has the advantage that all the gestures work out of the box with no extra utilities, but the effects are bound to this driver. For example, two-finger touch creates a right mouse button event(if patched). This means that these events are statically defined by the driver and utilities like touchegg won't work. This is why the author recommends xf86-input-evdev if it works with your touchscreen.

Note: The latter one worked in my case. Also, I still have to test whether xf86-input-mtev is aware of multitouch gestures.

Now, here is an example xorg-config snippet usable by xorg.conf.d-automagic configuration:

Section "InputClass"
    Identifier "Archos Touchscreen"
    MatchProduct "tr16c0_i2c_tsp"
    Option "Ignore" "off"
    Option "CorePointer" "on"
    Driver "mtev"
EndSection

Testing your input driver

Now you can test your display by running xinput in a terminal. First you call xinput list to list all the available input devices, then you test it:

$ xinput list
⎡ Virtual core pointer                          id=2    [master pointer  (3)]
⎜   ↳ Virtual core XTEST pointer                id=4    [slave  pointer  (2)]
⎜   ↳ tr16c0_i2c_tsp                            id=8    [slave  pointer  (2)]
⎣ Virtual core keyboard                         id=3    [master keyboard (2)]
    ↳ Virtual core XTEST keyboard               id=5    [slave  keyboard (3)]
    ↳ gpio-keys                                 id=6    [slave  keyboard (3)]
    ↳ twl6030_pwrbutton                         id=7    [slave  keyboard (3)]

$ xinput test 8
unknown class
motion a[0]=433 a[1]=376 a[2]=0 a[3]=0 a[4]=0 
button press   1 a[0]=433 a[1]=376 a[2]=0 a[3]=0 a[4]=0 
button release 1 

Now you're done, your touchscreen is set up!

Additional information

There are some interesting touch-projects out there that might provide helpful, although none of them were tested:

  • , a multitouch gesture manager.
  •  tslib, a touchscreen library. It might be worthwile to take a look at the  OpenBricks Mercurial.

TODO

In that order, I will add the following topics (sorting criteria is importance vs. complexicity):

  • Sound (Some talk about  OMAP path setting)
  • Provide more kernel-related information (How to build a kernel+initrd(Maybe? That should be clear), providing a newer kernel with the archos patches (WIP))
  • Graphics(Some words about OMAPDSS, Xorg on top of OMAPFB, when providing a newer kernel: OMAPDRM)
  • Android-gadget related information(USB-Tethering, ...)
  • Ducati-IVA (Video acceleration & Camera)