Building OpenWRT for Teltonika RUT956

Hi,

I have been trying to get OpenWRT running on the RUT956 for a while now. I took the dts file from the SDK that Teltonika releases, modified it slightly, added the device to the Makefile, and to my surprise after some debugging it actually compiled and is running now.

Other than the similar RUT955 they use the mt7628an SoC now, with the MeiGLink SLM750 modem.

Once I added the mt76x2 wifi driver, even WLAN started working... nice.

But now I am stuck at getting the modem to work. The control pins (modem_power, modem_reset...) are connected to the shift register 74hc595. Somehow it needs to be activated, but I don't see the shift register with the "normal" GPIOs. I am assuming that the dts needs to be modified to match more what OpenWRT expects, but I am still struggling to understand what is going on there. I tried looking at the ar9344_teltonika_rut955-h7v3c0.dts file, but so far could not transfer what I see there into the dts I am using, without breaking everything.

The DTS I am currently using:

// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
/dts-v1/;

#include <dt-bindings/input/input.h>
#include <dt-bindings/gpio/gpio.h>
#include "mt7628an.dtsi"

/ {
	compatible = "teltonika,rut9m", "mediatek,mt7628an-soc";
	model = "Teltonika RUT9M";

	chosen {
		bootargs = "console=ttyS0,115200";
	};

	ext_io {
		compatible = "spi-gpio";
		#address-cells = <1>;
		#size-cells = <0>;

		gpio-sck = <&gpio 3 GPIO_ACTIVE_HIGH>;  // SRCLK
		gpio-mosi = <&gpio 1 GPIO_ACTIVE_HIGH>; // SER
		cs-gpios = <&gpio 2 GPIO_ACTIVE_HIGH>;  // RCLK
		num-chipselects = <1>;

		shift_io: shift_io@0 {
			compatible = "fairchild,74hc595";
			reg = <0>;
			gpio-controller;
			#gpio-cells = <2>;
			registers-number = <2>;
			spi-max-frequency = <10000000>;
		};
	};

	gpio-export {
		compatible = "gpio-export";
		#size-cells = <0>;

		sd_enable {
			gpio-export,name = "sd_enable";
			gpio-export,output = <1>;
			gpios = <&gpio 44 GPIO_ACTIVE_HIGH>;
		};

		gpio_modem_reset {
			gpio-export,name = "modem_reset";
			gpio-export,output = <0>;
			gpios = <&shift_io 11 GPIO_ACTIVE_HIGH>;
		};

		gpio_modem_power {
			gpio-export,name = "modem_power";
			gpio-export,output = <0>;
			gpios = <&shift_io 10 GPIO_ACTIVE_HIGH>;
		};

		gpio_sim_select {
			gpio-export,name = "sim_sel";
			gpio-export,output = <1>;
			gpios = <&shift_io 7 GPIO_ACTIVE_HIGH>;
		};

		gpio_modem_status { // From v5
			gpio-export,name = "modem_status";
			gpio-export,input = <0>;
			gpios = <&gpio 0 GPIO_ACTIVE_LOW>;
		};

		gpio_rs485_rx_en {
			gpio-export,name = "rs485_rx_en";
			gpio-export,output = <0>;
			gpios = <&shift_io 13 GPIO_ACTIVE_HIGH>;
		};

		gpio_dcd {
			gpio-export,name = "dcd";
			gpio-export,output = <0>;
			gpios = <&shift_io 14 GPIO_ACTIVE_HIGH>;
		};
	};

	keys {
		compatible = "gpio-keys";

		reset {
			label = "reset";
			linux,code = <KEY_RESTART>;
			gpios = <&gpio 38 GPIO_ACTIVE_LOW>;
			debounce-interval = <60>;
		};
	};

	leds {
		compatible = "gpio-leds";

		eth1_led {
			label = "eth1_led";
			gpios = <&gpio 43 GPIO_ACTIVE_LOW>;
		};

		eth2_led {
			label = "eth2_led";
			gpios = <&gpio 42 GPIO_ACTIVE_LOW>;
		};

		eth3_led {
			label = "eth3_led";
			gpios = <&gpio 41 GPIO_ACTIVE_LOW>;
		};

		wan_led {
			label = "wan_led";
			gpios = <&gpio 39 GPIO_ACTIVE_LOW>;
		};

		led_gen_2_3 {
			label = "mob_gen_2_3";
			gpios = <&shift_io 5 GPIO_ACTIVE_HIGH>;
		};

		led_gen_4_3 {
			label = "mob_gen_4_3";
			gpios = <&shift_io 6 GPIO_ACTIVE_HIGH>;
		};

		led_ssid_1 {
			label = "mob_ssid_1";
			gpios = <&shift_io 0 GPIO_ACTIVE_HIGH>;
			linux,default-trigger = "timer";
		};

		led_ssid_2 {
			label = "mob_ssid_2";
			gpios = <&shift_io 1 GPIO_ACTIVE_HIGH>;
			linux,default-trigger = "timer";
		};

		led_ssid_3 {
			label = "mob_ssid_3";
			gpios = <&shift_io 2 GPIO_ACTIVE_HIGH>;
			linux,default-trigger = "timer";
		};

		led_ssid_4 {
			label = "mob_ssid_4";
			gpios = <&shift_io 3 GPIO_ACTIVE_HIGH>;
			linux,default-trigger = "timer";
		};

		led_ssid_5 {
			label = "mob_ssid_5";
			gpios = <&shift_io 4 GPIO_ACTIVE_HIGH>;
			linux,default-trigger = "timer";
		};

		led_power {
			label = "power";
			gpios = <&shift_io 15 GPIO_ACTIVE_LOW>;
			default-state = "on";
		};
	};

	tlt_gpios { // Modify according to wiki page "DTS syntax with Libgpiod changes"
		gpiochip_info {
			hw_0 {
				hwver = <0>;
				gpiochip_count = <4>;

				gpiochip_0 = <32>; // Built-in
				gpiochip_1 = <32>; // Built-in
				gpiochip_2 = <32>; // Built-in
				gpiochip_3 = <16>; // Shift Register
			};
		};

		ioman {
			GPIO_40 {
				line_name = "GPIO_IN_1";
			};
			GPIO_108 {
				line_name = "GPIO_OUT_1";
			};
			GPIO_11 {
				compatible_model = "RUT956";
				line_name = "GPIO_ISOLATED_INPUT";
			};
			GPIO_37 {
				compatible_model = "RUT956";
				line_name = "GPIO_IN_2";
			};
			GPIO_104 {
				compatible_model = "RUT956";
				line_name = "GPIO_OUT_2";
			};
			GPIO_105 {
				compatible_model = "RUT956";
				line_name = "GPIO_RELAY_CLOSE_1";
			};
		};

		ledman {
			GPIO_43 {
				line_name = "LED_ETH_GREEN_1";
				active_low;
			};
			GPIO_42 {
				line_name = "LED_ETH_GREEN_2";
				active_low;
			};
			GPIO_41 {
				line_name = "LED_ETH_GREEN_3";
				active_low;
			};
			GPIO_39 {
				line_name = "LED_ETH_GREEN_4";
				active_low;
			};
			GPIO_101 {
				line_name = "LED_TECH_GEN_23";
			};
			GPIO_102 {
				line_name = "LED_TECH_GEN_43";
			};
			GPIO_96 {
				line_name = "LED_SSID_1";
			};
			GPIO_97 {
				line_name = "LED_SSID_2";
			};
			GPIO_98 {
				line_name = "LED_SSID_3";
			};
			GPIO_99 {
				line_name = "LED_SSID_4";
			};
			GPIO_100 {
				line_name = "LED_SSID_5";
			};
			GPIO_111 { // Exists in ioman as GPIO_RELAY_OPEN_1, but not used
				compatible_model = "RUT956";
				compatible_versions = <5 99>;
				line_name = "LED_POWER";
				active_low;
			};
		};

		misc {
			GPIO_0 {
				compatible_versions = <5 99>;
				line_name = "GPIO_MODEM_STATUS";
				active_low;
			};
			GPIO_106 {
				line_name = "GPIO_MODEM_POWER_1";
			};
			GPIO_107 {
				line_name = "GPIO_MODEM_RESET_1";
			};
			GPIO_103 {
				line_name = "GPIO_SIM_SELECT";
			};
			GPIO_44 {
				line_name = "GPIO_SD_ENABLE"; // Duplicates as rts, fix in the future
			};
			GPIO_109 {
				line_name = "GPIO_RS458_RX_EN";
			};
			GPIO_110 {
				line_name = "GPIO_DCD";
			};
		};
	};
};

&state_default {
	gpio {
		groups = "i2s", "p4led_an", "p3led_an", "p2led_an", "p1led_an", "p0led_an", "gpio", "wled_an", "perst", "refclk", "spi cs1";
		function = "gpio";
	};
};

&pcie {
	status = "okay";
};

&pcie0 {
	mt76@0,0 {
		reg = <0x0000 0 0 0 0>;
		mediatek,mtd-eeprom = <&factory 0x28000>;
		ieee80211-freq-limit = <5000000 6000000>;
		mtd-mac-address = <&factory 0xf100>;
		mtd-mac-address-increment = <(-1)>;
	};
};

&spi0 {
	status = "okay";

	flash@0 {
		compatible = "jedec,spi-nor";
		reg = <0>;
		spi-max-frequency = <10000000>;

		partitions {
			compatible = "fixed-partitions";
			#address-cells = <1>;
			#size-cells = <1>;

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

			config: partition@20000 {
				label = "config";
				reg = <0x020000 0x010000>;
				read-only;
			};

			factory: partition@30000 {
				label = "factory";
				reg = <0x030000 0x030000>;
				read-only;
			};

			partition@60000 {
				compatible = "denx,uimage";
				label = "firmware";
				reg = <0x060000 0xf10000>;
			};

			partition@f70000 {
				label = "event-log";
				reg = <0xf70000 0x90000>;
			};
		};
	};
};

&wmac {
	status = "okay";
	mtd-mac-address = <&config 0x0>;
	mtd-mac-address-increment = <2>;
	mediatek,mtd-eeprom = <&factory 0x20000>;
};

&ethernet {
	mtd-mac-address = <&config 0x0>;
};

&esw {
	mediatek,portmap = <0x2f>;
};

&i2c {
	status = "okay";
	hwmon@0x4d {
		compatible = "mcp3221";
		reg = <0x4d>;
		reference-voltage-microvolt = <3300000>;
	};

	hwmon@0x48 {
		compatible = "ti,tla2021";
		reg = <0x48>;
	};
};

&uart1 {
	linux,rs485-enabled-at-boot-time;
	rs485-rts-delay = <0 0>;
	rs485-rx-during-tx;
	rts-gpios = <&gpio 44 GPIO_ACTIVE_HIGH>;
	status = "okay";
};

I guess my question is, do I even have to modify the dts or can somehow activate the modem from the running OpenWRT?

1 Like

Well, turns out I don't need to modify the DTS (unless I want to check this in, which is eventually the goal)

All I was missing was the kmod-gpio-nxp-74hc164 kernel module, with that /sys/class/gpio/modem_power/ appeared and I can turn the modem on now. Yay!

1 Like

Hello! [moobsen]I need your help, I messed up my bootloader and I can’t find it anywhere, could you share yours? I have RUT950 them the same!!!! Thank you in advance !

Moobsen can you share your openwrt to this rut956?

As far as I am aware I have not touched the bootloader and I am not sure how to extract it.

1 Like

Do you mean the built image? Sure. But be aware, that not everything works. I have two RUT956, and they seem to have internal differences. For me the modem only works in one of them (so far). The difference seems to be that one uses the 74hc595 shift register to control the modem, and the other does not. ( the so far not working one)

Also be aware that in that build there is no luci (the web interface). But ssh, wifi and opkg should work, so it should be fairly easy to install, if needed.

https://moobsen.com/openwrt-ramips-mt76x8-teltonika_rut9m-squashfs-sysupgrade.bin

That's exactly what I asked you to share: the bootloader was damaged! Maybe someone here can tell you how to make a backup of the bootloader through the terminal without a programmer! Because I already searched everything and couldn’t find the bootloader!!!!

root@:~# cat /proc/mtd
dev: size erasesize name
mtd0: 00020000 00010000 "u-boot"
mtd1: 00010000 00010000 "config"
mtd2: 00030000 00010000 "factory"
mtd3: 00f10000 00010000 "firmware"
mtd4: 001b0000 00010000 "kernel"
mtd5: 00d60000 00010000 "rootfs"
mtd6: 00270000 00010000 "rootfs_data"
mtd7: 00090000 00010000 "event-log"
root@:~# cat /dev/mtd0 > /tmp/mtd0

And you have a copy of each partition. However, you still have to give it boot via an external programmer, having previously desoldered the flash. Well, unless it can be done somehow through this connector on the PCB

If moobsen has a simple programmer like ch341a and he agrees, I will give the pinout for the programmer!!!

If I restore mine, I will try to help you; I am an electronics engineer; I can help you with the electrical part, but I am not very familiar with the software.....

Sorry that it took a while, busy times... but here is the first mtd partition from my "working" RUT956, copied with dd:
https://moobsen.com/uboot-rut956.bin
Meanwhile I am still stuck with one router doing just fine with the above image, while I can not turn on the modem in the other. There must be some hardware differences with how the GPIOs are controlled, but so far I could not figure out what those are exactly.
Did anyone try the above openwrt image?

1 Like