Defining the Hardware
Software Development Kits > Guide to Linux Porting
Configuration
In order for the driver to detect and communicate with the chip, the hardware must be described to the kernel. This ensures all necessary clocks, pins, power regulators, and necessary host bus peripherals are correctly configured for the target platform. This hardware configuration is described to the kernel using device tree, which is compiled and passed to the kernel as a binary blob.
A developer may choose to modify an existing board device tree file (.dts), compiling the changes into a single Flattened Device Tree (FDT) binary (.dtb). Alternatively, a device tree "fragment" can be composed and a device tree overlay compiled (.dtbo) allowing that hardware configuration to be changed on boot.
Below is a small snippet from the Morse Micro EKH03 device tree (.dts) file, redacted for brevity and to highlight the required properties and nodes to describe an SDIO connected MM6108.
...
&sdhci {
...
cap-sd-highspeed;
cap-mmc-highspeed;
non-removable;
disable-wp;
cap-sdio-irq;
...
mm6108_sdio: mm6108_sdio@0 {
compatible = "morse,mm610x";
reset-gpios = <&gpio 12 0>;
power-gpios = <&gpio 7 0>,
<&gpio 8 0>;
status = "okay";
reg = <2>;
bus-width = <4>;
};
};
...
For SPI devices, the MM6108 device tree node looks slightly different. The snippet below, taken from the MorseMicro EKH01 EVK, demonstrates how a developer might prepare a devicetree overlay to describe an MM6108 connected to the first SPI bus of the host processor. Of particular note is the different compatible, and the spi-irq-gpios parameter.
/dts-v1/;
/plugin/;
/ {
compatible = "brcm,bcm2835", "brcm,bcm2836",
"brcm,bcm2708", "brcm,bcm2709", "brcm,bcm2711";
fragment@0 {
target = <&spi0>;
frag0: __overlay__ {
pinctrl-0 = <&spi0_pins &spi0_cs_pins>;
cs-gpios = <&gpio 8 1>;
#address-cells = <1>;
#size-cells = <0>;
status = "okay";
mm6108: mm6108@0 {
compatible = "morse,mm610x-spi";
reg = <0>; /* CE0 */
reset-gpios = <&gpio 5 0>;
power-gpios = <&gpio 3 0>,
<&gpio 7 0>;
spi-irq-gpios = <&gpio 25 0>;
spi-max-frequency = <50000000>;
status = "okay";
};
};
};
};
| Property | Note |
| cap-sdio-irq | Enable SDIO IRQ signalling on this bus |
| compatible | Must be “morse,mm610x” in the MM6108 node to correctly probe the SDIO driver Must be “morse,mm610x-spi” in the MM6108 node to correctly probe the SPI driver. |
| reset-gpios | GPIO descriptor connected to the MM6108 RESET line. |
| power-gpios | GPIO descriptor list connected to the MM6108 WAKE and BUSY pins, respectively. |
| spi-irq-gpios | GPIO descriptor connected to the MM6108 SPI_INT pin. |
| status | Must be “okay” to enable the device! |
Due to the target specific requirements of booting a device, there is no one specific approach a developer should use to compile and deploy changes to the device tree. The next three subsections describe three common methods for which device tree changes may be incorporated into a target platform.
Compilation
Example 1 - FDT Blob in KBuild
In some cases, for some targets, the Linux kernel can ease the compilation of and "installation" of the FDT Blob by specifying the device tree le to load in the kernel config. This is useful for targets with limited boot loaders which are unable to hand the FDT blob to the kernel at boot time.
As an example, if we wanted to add HaLow support to the VoCore 2 module, we could add the EKH03 device tree change above to arch/mips/boot/dts/ralink/vocore2.dts.
A kernel checkout configured for a VoCore 2 will have the following kernel options set:
- CONFIG_BUILTIN_DTB
- CONFIG_DTB_VOCORE2
The Kbuild Makefile arch/mips/boot/dts/ralink/Makefile handles compilation of the FDT blob.
For the ambitious reader, it’s worth noting again that the EKH03 snippet above is incomplete and will not function as-is when applied to the vocore2.dts file in the kernel tree. Morse Micro recommends consulting the OpenWrt SDK for more complete examples.
Example 2 - Out-of-Tree Compilation
Devicetree les may also be composed outside of the kernel build tree. As above, the EKH03 device tree change should be added to an out-of-tree board.dts file.
Compilation of the FDT blob will follow steps similar to below:
# preprocess #includes and #defines
$(CPP) -nostdinc -x assembler-with-cpp $(DTS_CPPFLAGS)
-I$(LINUX_DTS_DIR) -I$(LINUX_DTS_DIR)/include
-I$(LINUX_DIR)/include -undef -D__DTS__ -o board.dtb.tmp board.dts
# compile FDT
$(DTC) -O dtb $(FLAGS) -o board.dtb board.dtb.tmp
The FDT blob can simply be appended to the kernel image for "installation", prior to any image compression.
cat board.dtb >> kernel.bin
For devices with an FDT aware bootloader, the compiled FDT blob can be handed to the kernel at boot time by the bootloader. The specific details of how this is carried out are platform specific.
Example 2 - Devicetree Overlay
If flexibility in the hardware configuration is required, devicetree overlay fragments, similar to the fragment used for the EKH01 shown above, can be loaded by FDT aware bootloaders to modify the behaviour of the device FDT. Steps to compile an overlay fragment into a .dtbo mirror the compilation of the FDT blob.
# compile FDT overlay
$(DTC) -@ -O dtb $(FLAGS) -o overlay.dtbo overlay.dts