Labels

Friday 25 November 2016

Understanding of linux SPI driver Model

The kernel SPI subsystem is divided into Controller Driver and Protocol Drivers.

Controller Driver
A controller driver is represented by the structure spi_master. The driver for an SPI controller manages access to spi slave devices through a queue of spi_message transactions, copying data between CPU memory and an SPI slave device. For each such message it queues, it calls the message’s completion function when the transaction completes.
Protocol Driver
A Protocol driver is represented by the structure spi_driver, they pass messages through the controller driver to communicate with a Slave or Master device on the other side of an SPI link. 


Initializing and probing of SPI Controller Driver
For embedded System-on-Chip (SOC) based boards, SPI master controllers connect to their drivers using some non SPI bus, such as the platform bus. Initializing and probing SPI controller driver is performed using the platform bus. During the initial stage of platform driver registration stage of probe() in that code includes calling spi_alloc_master which allocated the structure spi_master in the kernel and during final stage calling spi_register_master() to hook up to this SPI bus glue.
SPI controller’s will usually be platform devices, and the controller may need some platform_data in order to operate properly. The “struct platform_device” will include resources like the physical address of the controller’s first register and its IRQ.
Platforms will often abstract the “register SPI controller” operation,maybe coupling it with code to initialize pin configurations in the board initialization files. This is because most SOCs have several SPI-capable controllers, and only the ones actually usable on a given board should normally be set up and registered.
1 /* spi bus : spi0 */
2 static struct platform_device mysoc_spi_dev0 = {
3 .name = “mysoc_spi”,
4 .id = 0,
5 . resource = &mysoc_spi_resources [0] ,
6 . num_resources = 2,
7 . dev = {
8 . platform_data = &mysoc_spi_dev0_data ,
9 },
10 };
11
21 static int __init mysoc_spi_init ( void )
22 {
23 …
24 platform_device_register (&mysoc_spi_dev0 );
25 …
28 }
29
 Listing 1: Registration of the SPI platform device with the platform bus.
On the driver’s side, the registration with the platform bus is achieved by populating a structure platform_driver and passing it to the macro module_platform_driver() as argument (Listing-2). The platform bus simply compares the driver.name member against the name of each device, as defined in the platform_device data structure (Listing 1); if they are the same the device matches the platform driver.
1 # define DRIVER_NAME “mysoc_spi”
2
3 static struct platform_driver mysoc_spi_driver = {
4 .probe = mysoc_spi_probe ,
5 .remove = mysoc_spi_remove,
6 .driver = {
7 .name = DRIVER_NAME ,
8 .owner = THIS_MODULE ,
9 .pm = &mysoc_spi_pm_ops ,
10 },
11 };
12 module_platform_driver ( mysoc_spi_driver );
Listing 2: Registration of the SPI platform driver with the platform bus.

 
As usual, binding a device to a driver involves calling the driver’s probe() function passing a pointer to the device as a parameter. The SPI controller driver registers with the SPI subsystem by using a structure spi_master that is instantiated and initialized by the SPI platform driver’s probe() function, as shown in Listing 3.
The sequence of operations performed on probing are the following:
  1. Get the device resource definitions.
  2. Allocate the appropriate memory and remap it to a virtual address for being accessed by the kernel.
  3. Load the device settings.
  4. Configure the device hardware.
  5. Register with the power management system.
  6. Create the per-device sysfs nodes.
  7. Request the interrupt and register the IRQ.
  8. Set up the struct spi_master and register the master controller driver with the SPI core.
On successful completion of above steps the driver is bounded to the devices representing the mysoc SPI controllers.

1 /* Probe function */
2 static int mysoc_spi_probe ( struct platform_device * pdev )
3 {
4 …
5 struct spi_master *master;
6 …
7 /* Allocate master */
8 master = spi_alloc_master(&pdev->dev, sizeof(struct spi_master));
9 …
10 /* Register with the SPI framework */
11 status = spi_register_master(master);
12 …
14 }

Listing 3: Registration of the SPI Controller Driver.

Saturday 12 November 2016

what is the difference between u-boot.bin and u-boot.img?

u-boot.bin is the binary compiled U-Boot bootloader.
u-boot.img contains u-boot.bin along with an additional header to be used by the boot ROM to determine how and where to load and execute U-Boot.
The way in which these files are deployed can depend upon the nature of your device, its boot ROM and where the files are loaded from.
Boot ROMs are generally provided by the SoC/CPU vendor. These days, many boot ROMs are capable of loading u-boot.img, reading the file's header, loading u-boot.bin into memory and finally executing it. Some boot ROMs are complex enough to load u-boot.bin directly or even the OS kernel. While others may load an intermediate bootloader (MLO/X-Loader) first which then takes responsibility for loading U-Boot as the secondary bootloader once external memory is initialized.
This image depicts the latter case as implemented by some TI OMAP processors: TI OMAP Boot Sequence
This boot process is reduced by some devices by moving many of the X-Loader tasks into U-Boot and placing boot parameters (such as memory addresses) into the header of u-boot.imgavoiding the need for an intermediate bootloader.

System Boot process: