Kernel 4.4 with SPI and 1-wire

From www.chip-community.org
Jump to: navigation, search

I wanted to build my own Kernel based on the NTC 4.4.11 version but with some additional devices enabled, specifically 1-wire temperature sensors and SPI. This page captures the steps I took. There's nothing really new here, it's just a compilation of what other smart folks have done before me. You will need to follow the details from Compile the Linux kernel for CHIP but adapt them to 4.4 as described below. Thank you to renzo, danjperron, brettcvz, and others for blazing the trail!

Kernel config

> diff config-4.4.11-ntc CHIP-linux/.config
39c39
< CONFIG_LOCALVERSION=""
---
> CONFIG_LOCALVERSION="-tve1"
837c837
< # CONFIG_CPU_FREQ_GOV_POWERSAVE is not set
---
> CONFIG_CPU_FREQ_GOV_POWERSAVE=y
840c840
< # CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
---
> CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
1483c1483
< # CONFIG_OF_CONFIGFS is not set
---
> CONFIG_OF_CONFIGFS=y
2926c2926
< CONFIG_W1_MASTER_GPIO=y
---
> CONFIG_W1_MASTER_GPIO=m
2932c2932
< # CONFIG_W1_SLAVE_THERM is not set
---
> CONFIG_W1_SLAVE_THERM=m
  • to find where to make these changes in menuconfig use the search function...
  • only the W1 ones are really necessary for one-wire, and none for SPI
  • the mistake I made most often is to type 'make menuconfig' without the 'ARCH=arm CROSS_COMPILE=/usr/bin/arm-linux-gnueabihf-' options which corrupts .config, i.e.: start over!

Patching the kernel

  • I applied the SPI driver patch described in https://patchwork.kernel.org/patch/5726181/
  • In case you wonder, the patch to honor the SPI clock rate that was needed for kernel 4.3 is already in the 4.4. sources, so no need to apply anything.

Device tree to enable SPI

diff --git a/arch/arm/boot/dts/sun5i-r8-chip.dts b/arch/arm/boot/dts/sun5i-r8-chip.dts
index f894cb5..c48477d 100644
--- a/arch/arm/boot/dts/sun5i-r8-chip.dts
+++ b/arch/arm/boot/dts/sun5i-r8-chip.dts
@@ -229,10 +229,10 @@
        };

        chip_wifi_reg_on_pin: chip_wifi_reg_on_pin@0 {
-               allwinner,pins = "PC19";
-               allwinner,function = "gpio_out";
-               allwinner,drive = <SUN4I_PINCTRL_10_MA>;
-               allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+               allwinner,pins = "PC19";
+               allwinner,function = "gpio_out";
+               allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+               allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
        };

        chip_id_det_pin: chip_id_det_pin@0 {
@@ -245,9 +245,24 @@
        chip_w1_pin: chip_w1_pin@0 {
                allwinner,pins = "PD2";
                allwinner,function = "gpio_in";
-               allwinner,drive = <SUN4I_PINCTRL_10_MA>;
-               allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+               allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+               allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+       };
+
+       spi2_pins_a: spi2@0 {
+               allwinner,pins = "PE1", "PE2", "PE3";
+               allwinner,function = "spi2";
+               allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+               allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+       };
+
+       spi2_cs0_pins_a: spi2_cs0@0 {
+               allwinner,pins = "PE0";
+               allwinner,function = "spi2";
+               allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+               allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
        };
+
 };

 &reg_dcdc2 {
@@ -300,6 +315,23 @@
        status = "okay";
 };

+&spi2{
+       pinctrl-names = "default";
+       pinctrl-0 = <&spi2_pins_a>,
+                   <&spi2_cs0_pins_a>;
+       status = "okay";
+       spi2_0 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               compatible = "spidev";
+               /* compatible = "rohm,dh2228fv";*/
+
+               reg = <0>;
+               spi-max-frequency = <50000000>;
+        };
+};
+
 &tcon0 {
        status = "okay";
 };

Device tree to enable I2C1

I2C1 is the i2c interface available on U13 pins 9 & 11. To enable it add the following to the alias section:

        i2c1 = &i2c1;

And the following snippet to the device tree:

&i2c1 {
        pinctrl-names = "default";
        pinctrl-0 = <&i2c1_pins_a>;
        status = "okay";
        clock-frequency = <400000>;
};

This configures the bus to operate at 400Khz, which most devices these days seem to support. Just leave the clock-frequency line off to run at 100Khz.

Compiling the kernel

  • I used 'touch .scmversion' to avoid getting a '+' at the end of the kernel version
  • the kernel then compiled as described in the HOWTO
  • I also compiled the RTL8723BS driver as described
  • I used the following script to copy everything to chip, of course you will want to change SUFF and CHIP
#! /bin/bash
SUFF=tve1
CHIP=chip1
scp CHIP-linux/arch/arm/boot/zImage root@$CHIP:/boot/vmlinuz-4.4.11-$SUFF
scp CHIP-linux/.config root@$CHIP:/boot/config-4.4.11-$SUFF
scp CHIP-linux/System.map root@$CHIP:/boot/System.map-4.4.11-$SUFF
scp CHIP-linux/arch/arm/boot/dts/sun5i-r8-chip.dtb root@$CHIP:/boot/
rsync -a /tmp/lib/modules/4.4.11-$SUFF/ root@$CHIP:/lib/modules/4.4.11-$SUFF
#rsync -a /tmp/lib/firmware/4.4.11-$SUFF/ root@$CHIP:/lib/firmware/4.4.11-$SUFF

Rebooting

I rebooted into the uboot console and ran "editenv bootcmd" and changed zImage to vmlinuz-4.4.11-tve1 and then booted.