Monthly Archives: June 2020

VoCore2 SPI: full duplex

mt7628a has a wafer/silicon bug on SPI, we can not use its SPI in full duplex mode, but we can use bitbang for that mode. For some device do not support half-duplex, maybe this is the only way.

To enable bitbang on VoCore2, we need to modify Linux kernel code, VOCORE2.DTS and kernel setting.

Setup Kernel Setting

  1. call “make kernel_menuconfig”
  2. In menu, select “Device Drivers” => “SPI Support” => <*>   GPIO-based bitbanging SPI Master

VOCORE2.dts

This file is in target/linux/ramips/dts, example of the DTS. We need to set the driver to “spi-gpio” and pinctrl set the pins to GPIO mode.

/dts-v1/;

#include "VOCORE2.dtsi"

#include <dt-bindings/gpio/gpio.h>

/ {
	compatible = "vocore,vocore2", "mediatek,mt7628an-soc";
	model = "VoCore2";

	gpio-leds {
		compatible = "gpio-leds";

		status {
			label = "vocore2:fuchsia:status";
			gpios = <&gpio1 12 GPIO_ACTIVE_HIGH>;
		};
	};

	spi1: spi-gpio {
		status = "okay";

		compatible = "spi-gpio";

		gpio-sck = <&gpio0 7 1>;
        	gpio-miso = <&gpio0 9 1>;
        	gpio-mosi = <&gpio0 8 1>;

        	cs-gpios = <&gpio0 10 1>, <&gpio0 6 1>;
        	num-chipselects = <2>;
	};
};

&pinctrl {
        state_default: pinctrl0 {
                spi {
                        ralink,group = "spi";
                        ralink,function = "gpio";
                };
                spi_cs1 {
                        ralink,group = "spi cs1";
                        ralink,function = "gpio";
                };
        };
};

&i2c {
	status = "okay";
};

&spi1 {
	m25p80@0 {
		#address-cells = <1>;
		#size-cells = <1>;
		compatible = "jedec,spi-nor";
		reg = <0>;
		spi-max-frequency = <10000000>;
		m25p,chunked-io = <32>;

		partition@0 {
			label = "u-boot";
			reg = <0x0 0x30000>;
			read-only;
		};

		partition@30000 {
			label = "u-boot-env";
			reg = <0x30000 0x10000>;
			read-only;
		};

		factory: partition@40000 {
			label = "factory";
			reg = <0x40000 0x10000>;
			read-only;
		};

		partition@50000 {
			label = "firmware";
			reg = <0x50000 0xfb0000>;
		};
	};

	spidev@1 {
		#address-cells = <1>;
		#size-cells = <1>;
		compatible = "rohm,dh2228fv";
		reg = <1>;
		spi-max-frequency = <10000000>;
	};
};

Patch Linux spi-gpio.c

This is because CS1 pins has a default pull low resistor. If we do not patch it, CS1 will be low at startup, conflict with the flash driver who use CS0. So we must at startup setup CS1 pin to output and value to high.

                if (!SPI_N_CHIPSEL)
                        spi_gpio->cs_gpios[0] = SPI_GPIO_NO_CHIPSELECT;
                else
                        for (i = 0; i < SPI_N_CHIPSEL; i++) {
                                status = of_get_named_gpio(np, "cs-gpios", i);
                                if (status < 0) {
                                        dev_err(&pdev->dev,
                                                "invalid cs-gpios property\n");
                                        goto gpio_free;
                                }
                                spi_gpio->cs_gpios[i] = status;

+                               gpio_request(status, dev_name(&pdev->dev));
+                               gpio_direction_output(status, 1);
+                               gpio_free(status);
                        }
        }
#endif

        spi_gpio->bitbang.master = master;
        spi_gpio->bitbang.chipselect = spi_gpio_chipselect;

That is all 🙂 Now the firmware is able to support SPI device in full duplex mode.

Submit patch for OpenWrt on Github

Git is good, but for beginner like me, always feeling no way to give the first bite. I am confused about fork, branch, signed-off-by, push, merge and many other commands, maybe it is pretty clear for the clever boys but not for me. Thanks to adrianschmutzler comment at https://github.com/openwrt/openwrt/pull/3022, I start to understand how it works.

Tutorial

  1. click the “Fork” button on github.com/openwrt/openwrt
  2. goto your forked openwrt, click on “Clone or download”, get the address and clone to your local.
  3. make the change on your local source code.
  4. setup your name and email on your local by command git config –global user.email xxxx@xxxxx.xxx and git config –global user.name “your name”
  5. submit your change by command “git commit -s“, remember to keep that Signed-off-By line and add the reason of the changes to comment.
  6. push the commit by command “git push origin
  7. finally, go to github, create a merge request.

Signed-Off-By is just a text line in the comment to tell other who submit that patch, I am confused about that a long time, I thought it is added by some magic :p

PS: In old good time I only use git init, git commit and git clone. Now good new day comes.