fbtft_device - notro/fbtft GitHub Wiki

fbtft_device is a kernel module for registering FBTFT devices.

Note: fbtft_device is not available starting from Linux 5.4

Background

To understand the need for this module we need to know a little bit about the Linux kernel. For the kernel to operate some device like a keyboard or a screen, it needs to know how to do it. This is what a device driver provides, it's a piece of code. But there is one piece missing, and that is something informing the kernel about the presence of the keyboard or screen. This is what the device provides. A device is a data structure that contains information about the device, like which bus it is connected to (SPI, PCI, USB), IO addresses and other device specific information. When the kernel has a driver that supports a device, it hands control of the device to the driver (binding.txt).

Some ways a Linux device can be created:

  • In the platform or board file
    When the information changes, the kernel has to be rebuilt.
  • Device Tree
    Supported on later versions of raspbian (more details)
  • A bus driver detects a new hardware device on the bus, and creates a matching Linux device.
    A bus like SPI, doesn't have enumeration capabilities. The same goes for GPIOs.
  • A kernel module

The displays that FBTFT supports uses SPI and/or GPIO. These busses can't find out what is connected to them, so we must tell the kernel about them. To be able to provide a prebuilt kernel for all displays, we need a kernel module that can provide that information.

fbtft_device does this. It has device information for all the displays it supports, with default values. These values can be changed with module parameters.

Usage

There is one required module parameter, and that is name. It specifies which display (device) to register.

sudo modprobe fbtft_device name=adafruit22

fbtft_device prints information to the kernel log

$ dmesg
fbtft_device:  SPI devices registered:
fbtft_device:      spidev spi0.0 500kHz 8 bits mode=0x00
fbtft_device:      spidev spi0.1 500kHz 8 bits mode=0x00
fbtft_device:  'fb' Platform devices registered:
fbtft_device:      bcm2708_fb id=-1 pdata? no
fbtft_device: Deleting spi0.0
fbtft_device:  GPIOS used by 'adafruit22':
fbtft_device:    'reset' = GPIO25
fbtft_device:    'led' = GPIO23
fbtft_device:  SPI devices registered:
fbtft_device:      spidev spi0.1 500kHz 8 bits mode=0x00
fbtft_device:      fb_hx8340bn spi0.0 32000kHz 8 bits mode=0x00
graphics fb1: fb_hx8340bn frame buffer, 176x220, 75 KiB video memory, 16 KiB buffer memory, fps=20, spi0.0 at 32 MHz

First it lists all SPI devices and platform devices with a name containing 'fb' (framebuffer) that was registered before the module was loaded.
Then it deletes the device connected to spi0.0 (spidev) so we can register a new one.
Then it tells which GPIOs that is associated with this display.
Then it lists which SPI devices that are currently registered (spi0.0 means SPI busnum.chipselect).
And lastly the driver is loaded.

Supported devices

The special name list will write the supported devices to the kernel log.

sudo modprobe fbtft_device name=list; dmesg | tail -30
ERROR: could not insert 'fbtft_device': Operation canceled
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
fbtft_device:  Supported displays:
fbtft_device:      adafruit18
fbtft_device:      adafruit18_green
fbtft_device:      adafruit22
fbtft_device:      flexfb
fbtft_device:      flexpfb
fbtft_device:      hy28a
fbtft_device:      itdb28
fbtft_device:      itdb28_spi
fbtft_device:      mi0283qt-2
fbtft_device:      mi0283qt-9a
fbtft_device:      nokia3310
fbtft_device:      pioled
fbtft_device:      sainsmart18
fbtft_device:      sainsmart32
fbtft_device:      sainsmart32_fast
fbtft_device:      sainsmart32_latched
fbtft_device:      sainsmart32_spi
fbtft_device:      spidev
fbtft_device:

Parameters

  • busnum
    SPI bus number (default=0)

  • cs
    SPI chip select (default=0)

  • speed
    SPI speed in Hz (default varies among displays)

  • mode
    SPI mode (default SPI_MODE_0)

  • rotate
    Angle to rotate display counter clockwise: 0, 90, 180, 270

  • bgr
    Set BGR bit (supported by some drivers). Use if Red and Blue is swapped. Default is don't touch.

  • gpios
    Most displays need GPIOs for signaling. To simplify configuration, pins with the same functionality has been given names:

    • reset - Hardware reset
    • dc - Data/Command (sometimes called RS)
    • led - Backlight

    GPIO only displays

    • db00-15 - Databus
    • cs - Chip Select
    • wr - Write strobe

    fbtft_device have default values for these pin names (a few don't). The values can be changed with the gpios parameter. This is a comma separated array of pin/signal names and GPIO numbers. gpios=pin_name:gpio_number[,pin_name:gpio_number]

    When overriding the defaults using gpios, all gpios must be specified.

    Example showing the default gpio values of itdb28fb

    modprobe fbtft_device name=itdb28  gpios=reset:17,dc:1,wr:0,cs:21,db00:9,db01:11,db02:18,db03:23,db04:24,db05:25,db06:8,db07:7,led:4
    
  • fps
    Frames per second (default 20)
    In effect this states how long the driver will wait after video memory has been changed until display update transfer is started.
    See Debug for a way to show how long the actual transfer takes.
    More info

  • gamma
    String representation of Gamma Curve(s). Driver specific. Not supported by all drivers.
    Mode info

  • txbuflen
    Length of the FBTFT transmit buffer.
    This buffer is used by default on Little Endian architectures like on the Raspberry Pi. The 2 bytes in the 16-bit pixel value has to be swapped before transfer.
    It is also used when other transformation has to be done.
    When FBTFT is compiled on Little Endian, it uses a default buffer of 4096 bytes. txbuflen can be used to change this.
    txbuflen has some special values:

    • -1 makes the buffer the same size as video memory.
    • -2 forces no buffering
  • startbyte
    Sets the Start byte used by some SPI displays. Usually 0x70 (01110000) or 0x74 (01110100).
    Format: 5 bit magic + 1 bit id + 1 bit RS + 1 bit RW. RS and RW is set by FBTFT.

  • init
    Overrides the default init sequence.
    Init sequence Markers: -1: command begin, -2: millisecond delay, -3: end of init sequence
    No spaces allowed.
    Example: init=-1,0x01,-2,150,-1,0x11,-2,500,-1,0xB1,0x01,0x2C,0x2D,-3

  • verbose
    This parameter controls how much information fbtft_device writes to the kernel log

    • 0 - silent
    • 1 - show gpios used
    • 2 - and show devices after registration
    • 3 - and show devices before registration (default)

Custom display

If your display module is not supported by fbtft_device, you can setup your own.
The custom argument is used for this, and the name= argument is passed on as the driver to use.
Example: sudo modprobe fbtft_device custom name=fb_ili9341 buswidth=8 gpios=reset:25,dc:24

  • custom
    Add a custom display device. Use the speed= argument to make it a SPI device, or else it becomes a platform_device

  • width
    Display width, used with the custom argument

  • height
    Display height, used with the custom argument

  • buswidth
    Display bus width, used with the custom argument

Example

Register Sainsmart 1.8 with changes

  • SPI: spi0.1 at 16MHz
  • GPIOs: reset=18 (when overriding, all must be mentioned)
$ sudo modprobe fbtft_device name=sainsmart18 cs=1 speed=16000000 gpios=reset:18,dc:24
 kernel: fbtft_device: Deleting spi0.1
$ dmesg
fbtft_device:  SPI devices registered:
fbtft_device:      spidev spi0.0 500kHz 8 bits mode=0x00
fbtft_device:      spidev spi0.1 500kHz 8 bits mode=0x00
fbtft_device:  'fb' Platform devices registered:
fbtft_device:      bcm2708_fb id=-1 pdata? no
fbtft_device: Deleting spi0.1
fbtft_device:  GPIOS used by 'sainsmart18':
fbtft_device:    'reset' = GPIO18
fbtft_device:    'dc' = GPIO24
fbtft_device:  SPI devices registered:
fbtft_device:      spidev spi0.0 500kHz 8 bits mode=0x00
fbtft_device:      fb_st7735r spi0.1 16000kHz 8 bits mode=0x00
graphics fb1: fb_st7735r frame buffer, 128x160, 40 KiB video memory, 4 KiB buffer memory, fps=20, spi0.1 at 16 MHz

A note on probe()

When loading a driver, it's init() function is called and the device(s) it supports is made known to the kernel.
If the device it supports is registered in the kernel, the drivers probe() function is called with the device as an argument.
So, loading a driver when the device is not present, will just sit there. It is loaded, but it won't do anything before the supported device is present.
A driver can support more than one device.

Builtin

The fbtft_device module can be built as a loadable kernel module, and built into the kernel proper (kernel.img on the RasPi).
When builtin, the parameters to fbtft_device is provided on the kernel command line (/boot/cmdline.txt on the RasPi).
Like this:

fbtft_device.name=hy28a fbtft_device.speed=48000000

There is one limitation however: the linux kernel command line is limited to 1024 characters, and remember that the bootloader also adds to the commandline. Use cat /proc/cmdline | wc --chars to show the length.

References

piwik