Skip to content


notro edited this page Jul 13, 2017 · 32 revisions

FBTFT is a dead end

The fbdev maintainer won't accept any new fbdev drivers: No more new fbdev drivers, please, so fbtft can't be moved out of staging. Greg Kroah-Hartman has stated that he will keep fbtft in staging until a matching DRM driver is present in the tree. Patches are still accepted.

There is now a base in place for converting fbtft to drm: drivers/gpu/drm/tinydrm

The FBTFT drivers are now in the Linux kernel: drivers/staging/fbtft.
Development in this github repo has ceased and moved to the staging tree.


FBTFT Framebuffer drivers
M:	Thomas Petazzoni <>
S:	Maintained
F:	drivers/staging/fbtft/

Select the recipients for your patch:

$ ./scripts/ --file drivers/staging/fbtft/
Thomas Petazzoni <> (maintainer:FBTFT Framebuffer...)
Greg Kroah-Hartman <> (supporter:STAGING SUBSYSTEM) (open list:STAGING SUBSYSTEM) (open list)


The path from the staging tree to Linus' tree:

> So if I get this right, this is the tree I'll be basing my work on:
> git://
> So what's with the various staging-* branches?

I have 4 branches in that git tree:
	master - copy of Linus's tree, used to make patches against.
	staging-linus - patches to send to Linus for this -rc series
	staging-next - patches to send to Linus for the next -rc series
	staging-testing - patches that are being "tested" at the moment,
	and will move to staging-next if they pass.

These 28 patches went into staging-testing, and if everything looks ok,
in a day or so will move automatically into staging-next.  When the next
kernel is released by Linus (3.19), I will then have him pull from my
staging-next branch during the merge window period (merge windows are
for subsystem maintainers, not normal developers).

Then, after the big merge window is over, I will take bugfixes that need
to get into this kernel release into staging-linus, and stuff for the
next release (new drivers, changes not fixing regressions, etc.) into
the staging-next branch.

staging-next and staging-linus are pulled into the linux-next tree every
day (see Documenatation/development_model/ for more details about all of

So do your work against staging-testing, and all should be fine.


This is a step-by-step guide showing how to add and compile a new FBTFT driver in 30 minutes.

This guide can also be used to get the latest driver update, if a new kernel hasn't been released yet.
Follow the guide and skip the example driver.

See this for an overview: How-it-works

If you want to contribute code, see Submitting patches

Tested with image 2014-01-07-wheezy-raspbian and FBTFT kernel:

# enable SPI if needed in /etc/modprobe.d/raspi-blacklist.conf
sudo raspi-config # Expand Filesystem
sudo REPO_URI= rpi-update
sudo reboot

Install dependencies

rpi-source is used to download a matching kernel source

sudo wget -O /usr/bin/rpi-source && sudo chmod +x /usr/bin/rpi-source && /usr/bin/rpi-source -q --tag-update

Needed for make menuconfig

sudo apt-get update
sudo apt-get -y install libncurses5-dev

Samba (optional)

Samba can be used to aid development on the Pi.

sudo apt-get -y install samba samba-common-bin

sudo cp /etc/samba/smb.conf /etc/samba/

sudo sed -i '/ Share Definitions /q' /etc/samba/smb.conf
cat <<EOF | sudo tee -a /etc/samba/smb.conf

   comment = Home Directories
   browseable = no
   read only = no
   create mask = 0644
   directory mask = 0755
   valid users = %S

sudo service samba restart
sudo smbpasswd -a pi

Home directory for user pi will be available at \\\pi

Fetch kernel source

Get source, but don't prepare for building yet.

REPO_URI= rpi-source --nomake
gcc version check: mismatch between gcc (4.6.3) and /proc/version (4.7.2)

Follow this guide: gcc version check

REPO_URI= rpi-source --nomake
 *** gcc version check: OK
 *** rpi-update:
 *** Firmware revision: b77683205688d3f6ae2b32a3c7f4e63de1c06a5d
 *** Linux source commit: 342abe67d0e1f12eae17562bfe7615143d2618d1
 *** Download kernel source
 *** Unpack kernel source
 *** set 'EXTRAVERSION = +' in Makefile
 *** Create symlink: /home/pi/linux
 *** Create /lib/modules/<ver>/{build,source} symlinks
 *** .config
 *** Module.symvers

FBTFT source

cd ~/linux/drivers/video/
git clone

# Let make/kbuild see the directory and config options.
echo "obj-y += fbtft/" >> Makefile
sed -i 's/endmenu/source "drivers\/video\/fbtft\/Kconfig"\n\nendmenu/' Kconfig


cd ~/linux
make modules_prepare

If config asks if it should build (NEW) FBTFT drivers, answer m for module. Just press enter to get the default value for any other changes.


Let's make sure it builds before we start changing things.

This can be run from any directory

make -C ~/linux SUBDIRS=drivers/video/fbtft modules

If you just want to build the latest source and not add a driver or display, skip to Install

Example driver: fb_hello

This shows how to add a new driver for the Hello LCD Controller.

Add to ~/linux/drivers/video/fbtft/Kconfig

        tristate "Example FBTFT driver"
        depends on FB_TFT

Add to ~/linux/drivers/video/fbtft/Makefile

obj-$(CONFIG_FB_TFT_HELLO)       += fb_hello.o

Create ~/linux/drivers/video/fbtft/fb_hello.c

 * Copyright and GPL statement
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/delay.h>

#include "fbtft.h"

#define DRVNAME		"fb_hello"
#define WIDTH		128
#define HEIGHT		128

static int init_display(struct fbtft_par *par)
	fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);

	printk("Hello World");

	return 0;

static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
	fbtft_par_dbg(DEBUG_SET_ADDR_WIN, par,
		"%s(xs=%d, ys=%d, xe=%d, ye=%d)\n", __func__, xs, ys, xe, ye);


static struct fbtft_display display = {
	.regwidth = 8,
	.width = WIDTH,
	.height = HEIGHT,
	.fbtftops = {
		.init_display = init_display,
		.set_addr_win = set_addr_win,

    This makes the driver autoload if the device is present
    modprobe will load it from /lib/modules and not the build directory
	If your driver changes doesn't come into effect, this could be why

MODULE_DESCRIPTION("FB driver for the Hello LCD Controller");

Example display: hello

This shows how to add a device for the Hello 1.5 inch display, which uses the SPI bus.

Add to static struct fbtft_device_display displays[] in file ~/linux/drivers/video/fbtft/fbtft_device.c
Keep the list alphabetically sorted on name

	}, {
		.name = "hello15",
		.spi = &(struct spi_board_info) {
			.modalias = "fb_hello",
			.max_speed_hz = 32000000,
			.mode = SPI_MODE_0,
			.platform_data = &(struct fbtft_platform_data) {
				.display = {
					.buswidth = 8,
					.backlight = 1,
				.bgr = true,
				.gpios = (const struct fbtft_gpio []) {
					{ "reset", 25 },
					{ "dc", 24 },

When you copy code from this webpage, all tabs are turned into spaces. If you want to submit your work for inclusion, it has to be tabs.

Show the FBTFT changes made

cd ~/linux/drivers/video/fbtft/
git status
git diff


Start kernel configuration program

cd ~/linux
make menuconfig

Enable fb_hello (press 'm')

Device Drivers  ---> Graphics support  --->  Support for small TFT LCD display modules  --->

<M>   Example FBTFT driver

This has to be done every time the kernel config has changed

make prepare

Show changes to the kernel config


Now rerun the previous build step.


sudo dmesg -C
sudo modprobe fbtft
sudo insmod ~/linux/drivers/video/fbtft/fb_hello.ko
sudo insmod ~/linux/drivers/video/fbtft/fbtft_device.ko name=hello15 debug=3
fbtft_device:  SPI devices registered:
fbtft_device:      spidev spi0.1 500kHz 8 bits mode=0x00
fbtft_device:  'fb' Platform devices registered:
fbtft_device:      bcm2708_fb id=-1 pdata? no

fb_hello spi0.0: fbtft_request_gpios: 'reset' = GPIO25
fb_hello spi0.0: fbtft_request_gpios: 'dc' = GPIO24
fb_hello spi0.0: fbtft_verify_gpios()
fb_hello spi0.0: init_display()
Hello World
fb_hello spi0.0: Elapsed time for display update:   21.914092 ms (fps: 45, lines=128)
graphics fb1: fb_hello frame buffer, 128x128, 32 KiB video memory, 4 KiB buffer memory, fps=20, spi0.0 at 32 MHz

fbtft_device:  GPIOS used by 'hello15':
fbtft_device:    'reset' = GPIO25
fbtft_device:    'dc' = GPIO24
fbtft_device:  SPI devices registered:
fbtft_device:      spidev spi0.1 500kHz 8 bits mode=0x00
fbtft_device:      fb_hello spi0.0 32000kHz 8 bits mode=0x00
sudo rmmod fb_hello fbtft_device fbtft


# only install the new driver
sudo cp ~/linux/drivers/video/fbtft/{fbtft_device.ko,fb_hello.ko} /lib/modules/$(uname -r)/kernel/drivers/video/fbtft/
sudo depmod

# update all drivers/modules
sudo cp -v ~/linux/drivers/video/fbtft/*.ko /lib/modules/$(uname -r)/kernel/drivers/video/fbtft/
sudo depmod
sudo modprobe fbtft_device name=hello15 debug=3

Submitting patches

I you want me to include your driver, follow these rules:

  • The license the code is released under has to be GPL version 2 or later. Add this information at the top of the file.

  • Agree with the Developer's Certificate of Origin 1.1 (12. Sign your work)

  • Follow the Linux kernel coding style
    Use linux/scripts/ --file fb_xxx.c to verify your code.
    Lines can exceed 80 columns if the meaning is hard to grasp when breaking up the line. Never exceed 132 columns.

  • Make an issue and include your driver in a code block for review.

  • When the driver is approved, I can just copy the code from the issue, or you can make a pull request with just one commit in it. If I commit the driver directly from the issue, a Signed-off-by line will be added to the commit message to credit the author.

Except for trivial patches, make an issue first before making a pull request too see if I agree with you. Only one fix/feature per commit and vice versa. I can commit simple changes directly from an issue, a pull request is not needed.

Kernel messages in SSH session

When doing development and testing from a SSH session, it's nice to see the that kernel panic message before everything freezes.

Make file /etc/rsyslog.d/kern_pi.conf with contents:

kern.err  pi

This will show kernel error messages and worse when user pi is logged in.

sudo service rsyslog restart
You can’t perform that action at this time.