Texas Instruments PCIxx12 SDA Standard Compliant SD Host Controller

This article is about getting the above device working properly on Linux. The test was performed with a Toshiba Satellite Pro A120 (same as the Tecra A8) laptop, and Ubuntu Linux, v7.10 (Gutsy).

This article applies if a line that looks like this:
      03:06.3 Generic system peripheral [0805]: Texas Instruments PCIxx12 SDA Standard Compliant SD Host Controller
appears in your lspci.

The PCIid of the device I was working with was 104c:803c. This can be found with lspci -n, as below:
      03:06.3 0805: 104c:803c

Update: There is a kernel patch that I can confirm fixes the problems highlighted on this page. It worked perfectly on my 104c:803c. The patch is detailed here: http://list.drzeus.cx/pipermail/sdhci-devel/2007-December/002089.html. basically just find mmc_delay(2) in core.c and change it to mmc_delay(10) and all the problems are fixed. The solution below remains valid if you don't want to compile your own kernel.

The driver you require is the SDHCI SD Controller driver. Many people will tell you that you require the tifm drivers, but they don't work for this specific device, you need to use the SDHCI driver. As per the driver's home page, the driver was merged into the main kernel as of 2.6.17-rc1. To check that the driver is installed correctly, type dmesg | grep sdhci. This should return something like this:
      [ 274.444000] sdhci: Secure Digital Host Controller Interface driver
      [ 274.444000] sdhci: Copyright(c) Pierre Ossman
      [ 274.444000] sdhci: SDHCI controller found at 0000:03:06.3 [104c:803c] (rev 0)

Even with the driver installed, I found that Linux wouldn't detect SD/MMC cards when I plug them in. I spent ages trying various solutions and eventually found a method that works. You basically need to load the driver (modprobe) with the card in place. Even then though, sometimes it wouldn't detect on the first couple of tries. After lots of mucking around, and endless locking up my PC, I made the bash script below. When this is run with a card in place, you should find that the card is detected successfully. Depending on your configuration, the card may also automatically mount (it does on Ubuntu).

You need to create a file as root in /bin called sd.sh. In Ubuntu you'd open up a terminal and type:
      cd /bin
      sudo gedit sd.sh

Now copy/paste the following lines into this file:
echo -ne "Detecting SD card..."
rm /dev/mmcblk0 2> /dev/null
while [ ! -e /dev/mmcblk0 ]
       modprobe -r fakephp
       modprobe -r sdhci
       modprobe -r mmc_block
       modprobe fakephp || return 1
       setpci -s 03:06.3 86.b=90
       setpci -s 03:06.3 4c.b=02
       setpci -s 03:06.3 04.b=06
       setpci -s 03:06.3 88.b=01
       modprobe sdhci || return 1
       modprobe mmc_block || return 1
       sleep 2
       echo -ne .
echo ""
echo "SD card detected at /dev/mmcblk0"
sleep 1
exit 0

Note that you need to replace 03:06.3 in the example above with the address that appears beside your PCIxx12 SDA device in lspci.

Now you need to make this file executable by typing:
sudo chmod +x sd.sh

The script basically just modprobes the SDHCI drivers until an SD/MMC card is successfully discovered, and then exits. For ease of use I created a launcher button on my panel. That way I can just stick an SD card in, press the button and away I go. To do this in Ubuntu, right click on the panel, click Add to Panel, then click Custom Application Launcher. Call it whatever you want, "SD Launcher" for example. Where it says command, put gnome-terminal -x sudo /bin/./sd.sh. You can now just click this button whenever you want to detect an SD card.

You may find that sometimes a card is detected when you put it in, that's all well and good if it does, but 99 times out of 100 (yeah, I did it that many!) it didn't detect the card when I inserted it and I had to click my magic button.

andy [ at ] burningimage.net