TP-Link and ASUS OnHub devices are very similar, sharing many of the
same characteristics and much of their Device Tree. They both run a
version of ChromeOS for their factory firmware, and so installation
instructions look very similar to Google Wifi [1].
Things I've tested, and are working:
* Ethernet
* WiFi (2.4 and 5 GHz)
* LEDs
* USB
* eMMC
* Serial console (if you wire it up yourself)
* 2x CPU
* Speaker
== Installation instructions summary ==
1. Flash *-factory.bin to a USB drive (e.g., with `dd`)
2. Insert USB drive, to boot OpenWrt from USB
3. Copy the same *-factory.bin over to device, and flash it to eMMC to
make OpenWrt permanent
== Developer mode, booting from USB (Step 2) ==
To enter Developer Mode and boot OpenWrt from a USB stick:
1. Unplug power
2. Gain access to the "developer switch" through the bottom of the
device
3. Hold down the "reset switch" (near the USB port / power plug)
4. Plug power back in
5. The LED on the device should turn white, then blink orange, then
red. Release the reset switch.
6. Insert USB drive with OpenWrt factory.bin
7. Press the hidden developer switch under the device to boot to USB;
you should see some activity lights (if you have any) on your USB
drive
8. Depending on your configuration, the router's LED(s) should come on.
You're now running OpenWrt off a USB stick.
These instructions are derived from:
https://www.exploitee.rs/index.php/Rooting_The_Google_OnHub#Enabling_%22Developer_Mode%22_on_the_OnHub
https://www.exploitee.rs/index.php/Asus_OnHub#Enabling_%22Developer_Mode%22_on_the_OnHub
~~Finding the developer switch:~~ for TP-Link, the developer switch is
on the bottom of the device, underneath some of the rubber padding and a
screw. For ASUS, remove the entire base, via 4 screws under the rubber
feet. See the Exploitee instructions for more info and photos.
== Making OpenWrt permanent (on eMMC) (Step 3) ==
Once you're running OpenWrt via USB:
1. Connect Ethernet to the LAN port; router's LAN address should be at
192.168.1.1
2. Connect another system to the router's LAN, and copy the factory.bin
image over, via SCP and SSH:
scp -O openwrt-ipq806x-chromium-tplink_onhub-squashfs-factory.bin root@192.168.1.1:
ssh root@192.168.1.1 -C "dd if=/dev/zero bs=512 seek=
7552991 of=/dev/mmcblk0 count=33 && \
dd if=/root/openwrt-ipq806x-chromium-tplink_onhub-squashfs-factory.bin of=/dev/mmcblk0"
3. Reboot and remove the USB drive.
== Developer mode beep ==
Note that every time you boot the OnHub in developer mode, the device
will play a loud "beep" after a few seconds. This is described in the
Chromium docs [2], and is intended to make it clear that the device is
not running Google software. It is nontrivial to completely disable this
beep, although it's possible to "acknowledge" developer mode (and skip
the beep) by using a USB keyboard to press CTRL+D every time you boot.
[1] https://openwrt.org/toh/google/wifi
[2] https://chromium.googlesource.com/chromiumos/docs/+/HEAD/developer_mode.md
Signed-off-by: Brian Norris <computersforpeace@gmail.com>
ARCH:=arm
BOARD:=ipq806x
BOARDNAME:=Qualcomm Atheros IPQ806X
-FEATURES:=squashfs nand fpu ramdisk
+FEATURES:=squashfs fpu ramdisk
CPU_TYPE:=cortex-a15
CPU_SUBTYPE:=neon-vfpv4
-SUBTARGETS:=generic
+SUBTARGETS:=generic chromium
KERNEL_PATCHVER:=5.15
ucidef_add_switch "switch0" \
"2:lan:1" "3:lan:2" "4:lan:3" "5:lan:4" "6@eth1" "1:wan" "0@eth0"
;;
+asus,onhub |\
+tplink,onhub)
+ ucidef_set_interfaces_lan_wan "eth1" "eth0"
+ ucidef_add_switch "switch0" \
+ "1:lan" "6@eth1" "2:wan" "0@eth0"
+ ;;
ubnt,unifi-ac-hd)
ucidef_set_interface_lan "eth0 eth1"
;;
board=$(board_name)
+dt_base64_extract() {
+ local target_dir="/sys$DEVPATH"
+ local source="$target_dir/../../of_node/qcom,ath10k-calibration-data-base64"
+
+ [ -e "$source" ] || caldata_die "cannot find base64 calibration data: $source"
+ [ -d "$target_dir" ] || \
+ caldata_die "no sysfs dir to write: $target"
+
+ echo 1 > "$target_dir/loading"
+ base64decode.uc "$source" > "$target_dir/data"
+ if [ $? != 0 ]; then
+ echo 1 > "$target_dir/loading"
+ caldata_die \
+ "failed to write calibration data to $target_dir/data"
+ else
+ echo 0 > "$target_dir/loading"
+ fi
+}
+
case "$FIRMWARE" in
"ath10k/cal-pci-0000:01:00.0.bin")
case "$board" in
+ asus,onhub |\
+ tplink,onhub)
+ dt_base64_extract
+ ;;
meraki,mr52)
CI_UBIPART=art
caldata_extract_ubi "ART" 0x1000 0x844
;;
esac
;;
+"ath10k/cal-pci-0001:01:00.0.bin")
+ case "$board" in
+ asus,onhub |\
+ tplink,onhub)
+ dt_base64_extract
+ ;;
+ esac
+ ;;
"ath10k/pre-cal-pci-0001:01:00.0.bin")
case $board in
asrock,g10)
;;
"ath10k/cal-pci-0002:01:00.0.bin")
case "$board" in
+ asus,onhub |\
+ tplink,onhub)
+ dt_base64_extract
+ ;;
meraki,mr42)
CI_UBIPART=art
caldata_extract_ubi "ART" 0x9000 0x844
MTD_CONFIG_ARGS="-s 0x200000"
default_do_upgrade "$1"
;;
+ asus,onhub |\
+ tplink,onhub)
+ export_bootdevice
+ export_partdevice CI_ROOTDEV 0
+ CI_KERNPART="kernel"
+ CI_ROOTPART="rootfs"
+ CI_DATAPART="rootfs_data"
+ emmc_do_upgrade "$1"
+ ;;
tplink,vr2600v)
MTD_CONFIG_ARGS="-s 0x200000"
default_do_upgrade "$1"
;;
esac
}
+
+platform_copy_config() {
+ case "${board_name}" in
+ asus,onhub |\
+ tplink,onhub)
+ emmc_copy_config
+ ;;
+ esac
+ return 0
+}
--- /dev/null
+#!/usr/bin/ucode
+
+import { stdin, open, error } from 'fs';
+
+if (length(ARGV) == 0 && stdin.isatty()) {
+ warn("usage: b64decode [stdin|path]\n");
+ exit(1);
+}
+
+let fp = stdin;
+let source = ARGV[0];
+
+if (source) {
+ fp = open(source);
+ if (!fp) {
+ warn('b64decode: unable to open ${source}: ${error()}\n');
+ exit(1);
+ }
+}
+
+print(b64dec(fp.read("all")));
+fp.close();
+exit(0);
--- /dev/null
+CONFIG_BLK_DEV_SD=y
+CONFIG_LEDS_LP5523=y
+CONFIG_LEDS_LP55XX_COMMON=y
+CONFIG_PHY_QCOM_IPQ806X_USB=y
+CONFIG_SCSI=y
+CONFIG_SCSI_COMMON=y
+CONFIG_SG_POOL=y
+CONFIG_USB_DWC3=y
+CONFIG_USB_DWC3_HOST=y
+CONFIG_USB_DWC3_QCOM=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_XHCI_HCD=y
+CONFIG_USB_XHCI_PLATFORM=y
--- /dev/null
+BOARDNAME:=Google Chromium
+FEATURES += emmc boot-part rootfs-part
--- /dev/null
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2014 The ChromiumOS Authors
+ */
+
+#include "qcom-ipq8064-onhub.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/soc/qcom,gsbi.h>
+
+/ {
+ model = "ASUS OnHub";
+ compatible = "asus,onhub", "google,arkham", "qcom,ipq8064";
+
+ chosen {
+ bootargs-append = " rootwait";
+ };
+};
+
+&qcom_pinmux {
+ ap3223_pins: ap3223_pinmux {
+ pins = "gpio22";
+ function = "gpio";
+ bias-none;
+ };
+
+ i2c7_pins: i2c7_pinmux {
+ mux {
+ pins = "gpio8", "gpio9";
+ function = "gsbi7";
+ };
+ data {
+ pins = "gpio8";
+ bias-disable;
+ };
+ clk {
+ pins = "gpio9";
+ bias-disable;
+ };
+ };
+};
+
+&gsbi7 {
+ status = "okay";
+ qcom,mode = <GSBI_PROT_I2C_UART>;
+};
+
+&gsbi7_i2c {
+ status = "okay";
+ clock-frequency = <100000>;
+ pinctrl-0 = <&i2c7_pins>;
+ pinctrl-names = "default";
+
+ ap3223@1c {
+ compatible = "dynaimage,ap3223";
+ reg = <0x1c>;
+
+ pinctrl-0 = <&ap3223_pins>;
+ pinctrl-names = "default";
+
+ int-gpio = <&qcom_pinmux 22 GPIO_ACTIVE_LOW>;
+ };
+
+ led-controller@32 {
+ compatible = "national,lp5523";
+ reg = <0x32>;
+ clock-mode = /bits/ 8 <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ led@4 {
+ reg = <4>;
+ color = <LED_COLOR_ID_GREEN>;
+ chan-name = "green:status";
+ linux,default-trigger = "default-on";
+ led-cur = /bits/ 8 <0xfa>;
+ max-cur = /bits/ 8 <0xff>;
+ };
+
+ led@5 {
+ reg = <5>;
+ color = <LED_COLOR_ID_BLUE>;
+ chan-name = "blue:status";
+ led-cur = /bits/ 8 <0xfa>;
+ max-cur = /bits/ 8 <0xff>;
+ };
+
+ led@8 {
+ reg = <8>;
+ color = <LED_COLOR_ID_RED>;
+ chan-name = "red:status";
+ led-cur = /bits/ 8 <0xfa>;
+ max-cur = /bits/ 8 <0xff>;
+ };
+ };
+};
--- /dev/null
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2014 The ChromiumOS Authors
+ */
+
+#include "qcom-ipq8064-smb208.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/soc/qcom,tcsr.h>
+
+/ {
+ aliases {
+ ethernet0 = &gmac0;
+ ethernet1 = &gmac2;
+ mdio-gpio0 = &mdio;
+ serial0 = &gsbi4_serial;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ reserved-memory {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ rsvd@41200000 {
+ reg = <0x41200000 0x300000>;
+ no-map;
+ };
+ };
+
+ mdio: mdio {
+ compatible = "virtual,mdio-gpio";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ gpios = <&qcom_pinmux 1 GPIO_ACTIVE_HIGH>,
+ <&qcom_pinmux 0 GPIO_ACTIVE_HIGH>;
+ pinctrl-0 = <&mdio_pins>;
+ pinctrl-names = "default";
+
+ phy0: ethernet-phy@0 {
+ reg = <0>;
+ qca,ar8327-initvals = <
+ 0x00004 0x7600000 /* PAD0_MODE */
+ 0x00008 0x1000000 /* PAD5_MODE */
+ 0x0000c 0x80 /* PAD6_MODE */
+ 0x000e4 0xaa545 /* MAC_POWER_SEL */
+ 0x000e0 0xc74164de /* SGMII_CTRL */
+ 0x0007c 0x4e /* PORT0_STATUS */
+ 0x00094 0x4e /* PORT6_STATUS */
+ >;
+ };
+
+ phy1: ethernet-phy@1 {
+ reg = <1>;
+ };
+ };
+
+ soc {
+ rng@1a500000 {
+ status = "disabled";
+ };
+
+ sound {
+ compatible = "google,storm-audio";
+ qcom,model = "ipq806x-storm";
+ cpu = <&lpass>;
+ codec = <&max98357a>;
+ };
+
+ lpass: lpass@28100000 {
+ status = "okay";
+ pinctrl-names = "default", "idle";
+ pinctrl-0 = <&mi2s_default>;
+ pinctrl-1 = <&mi2s_idle>;
+ };
+
+ max98357a: max98357a {
+ compatible = "maxim,max98357a";
+ #sound-dai-cells = <1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdmode_pins>;
+ sdmode-gpios = <&qcom_pinmux 25 GPIO_ACTIVE_HIGH>;
+ };
+ };
+};
+
+&qcom_pinmux {
+ rgmii0_pins: rgmii0_pins {
+ mux {
+ pins = "gpio2", "gpio66";
+ drive-strength = <8>;
+ bias-disable;
+ };
+ };
+ mi2s_pins {
+ mi2s_default: mi2s_default {
+ dout {
+ pins = "gpio32";
+ function = "mi2s";
+ drive-strength = <16>;
+ bias-disable;
+ };
+ sync {
+ pins = "gpio27";
+ function = "mi2s";
+ drive-strength = <16>;
+ bias-disable;
+ };
+ clk {
+ pins = "gpio28";
+ function = "mi2s";
+ drive-strength = <16>;
+ bias-disable;
+ };
+ };
+ mi2s_idle: mi2s_idle {
+ dout {
+ pins = "gpio32";
+ function = "mi2s";
+ drive-strength = <2>;
+ bias-pull-down;
+ };
+ sync {
+ pins = "gpio27";
+ function = "mi2s";
+ drive-strength = <2>;
+ bias-pull-down;
+ };
+ clk {
+ pins = "gpio28";
+ function = "mi2s";
+ drive-strength = <2>;
+ bias-pull-down;
+ };
+ };
+ };
+
+ mdio_pins: mdio_pins {
+ mux {
+ pins = "gpio0", "gpio1";
+ function = "gpio";
+ drive-strength = <8>;
+ bias-disable;
+ };
+ rst {
+ pins = "gpio26";
+ output-low;
+ };
+ };
+
+ sdmode_pins: sdmode_pinmux {
+ pins = "gpio25";
+ function = "gpio";
+ drive-strength = <16>;
+ bias-disable;
+ };
+
+ sdcc1_pins: sdcc1_pinmux {
+ mux {
+ pins = "gpio38", "gpio39", "gpio40",
+ "gpio41", "gpio42", "gpio43",
+ "gpio44", "gpio45", "gpio46",
+ "gpio47";
+ function = "sdc1";
+ };
+ cmd {
+ pins = "gpio45";
+ drive-strength = <10>;
+ bias-pull-up;
+ };
+ data {
+ pins = "gpio38", "gpio39", "gpio40",
+ "gpio41", "gpio43", "gpio44",
+ "gpio46", "gpio47";
+ drive-strength = <10>;
+ bias-pull-up;
+ };
+ clk {
+ pins = "gpio42";
+ drive-strength = <16>;
+ bias-pull-down;
+ };
+ };
+
+ i2c1_pins: i2c1_pinmux {
+ pins = "gpio53", "gpio54";
+ function = "gsbi1";
+ bias-disable;
+ };
+
+ rpm_i2c_pinmux: rpm_i2c_pinmux {
+ mux {
+ pins = "gpio12", "gpio13";
+ function = "gsbi4";
+ drive-strength = <12>;
+ bias-disable;
+ };
+ };
+
+ spi_pins: spi_pins {
+ mux {
+ pins = "gpio18", "gpio19", "gpio21";
+ function = "gsbi5";
+ bias-pull-down;
+ /delete-property/ bias-none;
+ /delete-property/ drive-strength;
+ };
+ data {
+ pins = "gpio18", "gpio19";
+ drive-strength = <10>;
+ };
+ cs {
+ pins = "gpio20";
+ drive-strength = <10>;
+ bias-pull-up;
+ };
+ clk {
+ pins = "gpio21";
+ drive-strength = <12>;
+ };
+ };
+
+ fw_pinmux {
+ wp {
+ pins = "gpio17";
+ output-low;
+ };
+ recovery {
+ pins = "gpio16";
+ bias-none;
+ };
+ developer {
+ pins = "gpio15";
+ bias-none;
+ };
+ };
+
+ spi6_pins: spi6_pins {
+ mux {
+ pins = "gpio55", "gpio56", "gpio58";
+ function = "gsbi6";
+ bias-pull-down;
+ };
+ data {
+ pins = "gpio55", "gpio56";
+ drive-strength = <10>;
+ };
+ cs {
+ pins = "gpio57";
+ drive-strength = <10>;
+ bias-pull-up;
+ output-high;
+ };
+ clk {
+ pins = "gpio58";
+ drive-strength = <12>;
+ };
+ };
+};
+
+&gmac0 {
+ status = "okay";
+ phy-mode = "rgmii";
+ qcom,id = <0>;
+ phy-handle = <&phy1>;
+
+ pinctrl-0 = <&rgmii0_pins>;
+ pinctrl-names = "default";
+
+ fixed-link {
+ speed = <1000>;
+ full-duplex;
+ };
+};
+
+&gmac2 {
+ status = "okay";
+ phy-mode = "sgmii";
+ qcom,id = <2>;
+ phy-handle = <&phy0>;
+
+ fixed-link {
+ speed = <1000>;
+ full-duplex;
+ };
+};
+
+&gsbi1 {
+ status = "okay";
+ qcom,mode = <GSBI_PROT_I2C_UART>;
+};
+
+&gsbi1_i2c {
+ status = "okay";
+
+ clock-frequency = <100000>;
+
+ pinctrl-0 = <&i2c1_pins>;
+ pinctrl-names = "default";
+
+ tpm@20 {
+ compatible = "infineon,slb9645tt";
+ reg = <0x20>;
+ powered-while-suspended;
+ };
+};
+
+&gsbi4 {
+ status = "okay";
+ qcom,mode = <GSBI_PROT_I2C_UART>;
+};
+
+&gsbi4_serial {
+ status = "okay";
+};
+
+&gsbi5 {
+ status = "okay";
+ qcom,mode = <GSBI_PROT_SPI>;
+
+ spi4: spi@1a280000 {
+ status = "okay";
+ spi-max-frequency = <50000000>;
+ pinctrl-0 = <&spi_pins>;
+ pinctrl-names = "default";
+
+ cs-gpios = <&qcom_pinmux 20 0>;
+
+ flash: flash@0 {
+ compatible = "jedec,spi-nor";
+ spi-max-frequency = <50000000>;
+ reg = <0>;
+ };
+ };
+};
+
+&gsbi6 {
+ status = "okay";
+ qcom,mode = <GSBI_PROT_SPI>;
+};
+
+&gsbi6_spi {
+ status = "okay";
+ spi-max-frequency = <25000000>;
+
+ pinctrl-0 = <&spi6_pins>;
+ pinctrl-names = "default";
+
+ cs-gpios = <&qcom_pinmux 57 GPIO_ACTIVE_HIGH>;
+
+ dmas = <&adm_dma 8 0xb>,
+ <&adm_dma 7 0x14>;
+ dma-names = "rx", "tx";
+
+ /*
+ * This "spidev" was included in the manufacturer device tree. I suspect
+ * it's the (unused) Zigbee radio -- SiliconLabs EM3581 Zigbee? There's
+ * no driver or binding for this at the moment.
+ */
+ spidev@0 {
+ compatible = "spidev";
+ reg = <0>;
+ spi-max-frequency = <25000000>;
+ };
+};
+
+&pcie0 {
+ status = "okay";
+
+ pcie@0 {
+ reg = <0 0 0 0 0>;
+ #interrupt-cells = <1>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ device_type = "pci";
+
+ ath10k@0,0 {
+ reg = <0 0 0 0 0>;
+ device_type = "pci";
+ qcom,ath10k-sa-gpio = <2 3 4 0>;
+ qcom,ath10k-sa-gpio-func = <5 5 5 0>;
+ };
+ };
+};
+
+&pcie1 {
+ status = "okay";
+
+ pcie@0 {
+ reg = <0 0 0 0 0>;
+ #interrupt-cells = <1>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ device_type = "pci";
+
+ ath10k@0,0 {
+ reg = <0 0 0 0 0>;
+ device_type = "pci";
+ qcom,ath10k-sa-gpio = <2 3 4 0>;
+ qcom,ath10k-sa-gpio-func = <5 5 5 0>;
+ };
+ };
+};
+
+&pcie2 {
+ status = "okay";
+
+ pcie@0 {
+ reg = <0 0 0 0 0>;
+ #interrupt-cells = <1>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ device_type = "pci";
+
+ ath10k@0,0 {
+ reg = <0 0 0 0 0>;
+ device_type = "pci";
+ };
+ };
+};
+
+&rpm {
+ pinctrl-0 = <&rpm_i2c_pinmux>;
+ pinctrl-names = "default";
+};
+
+&sdcc1 {
+ status = "okay";
+ pinctrl-0 = <&sdcc1_pins>;
+ pinctrl-names = "default";
+ /delete-property/ mmc-ddr-1_8v;
+};
+
+&tcsr {
+ compatible = "qcom,tcsr-ipq8064", "qcom,tcsr", "syscon";
+ qcom,usb-ctrl-select = <TCSR_USB_SELECT_USB3_DUAL>;
+};
+
+&hs_phy_0 {
+ status = "okay";
+};
+
+&ss_phy_0 {
+ status = "okay";
+};
+
+&usb3_0 {
+ status = "okay";
+};
+
+&hs_phy_1 {
+ status = "okay";
+};
+
+&ss_phy_1 {
+ status = "okay";
+};
+
+&usb3_1 {
+ status = "okay";
+};
--- /dev/null
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2014 The ChromiumOS Authors
+ */
+
+#include "qcom-ipq8064-onhub.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/soc/qcom,gsbi.h>
+
+/ {
+ model = "TP-Link OnHub";
+ compatible = "tplink,onhub", "google,whirlwind-sp5", "qcom,ipq8064";
+
+ chosen {
+ bootargs-append = " rootwait";
+ };
+};
+
+&qcom_pinmux {
+ i2c7_pins: i2c7_pinmux {
+ mux {
+ pins = "gpio8", "gpio9";
+ function = "gsbi7";
+ };
+ data {
+ pins = "gpio8";
+ bias-disable;
+ };
+ clk {
+ pins = "gpio9";
+ bias-disable;
+ };
+ };
+};
+
+&gsbi7 {
+ status = "okay";
+ qcom,mode = <GSBI_PROT_I2C_UART>;
+};
+
+&gsbi7_i2c {
+ status = "okay";
+ clock-frequency = <100000>;
+ pinctrl-0 = <&i2c7_pins>;
+ pinctrl-names = "default";
+
+ led-controller@32 {
+ compatible = "national,lp5523";
+ reg = <0x32>;
+ clock-mode = /bits/ 8 <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ led@0 {
+ reg = <0>;
+ color = <LED_COLOR_ID_RED>;
+ chan-name = "red:status-0";
+ linux,default-trigger = "default-on";
+ led-cur = /bits/ 8 <0x64>;
+ max-cur = /bits/ 8 <0x78>;
+ };
+
+ led@1 {
+ reg = <1>;
+ color = <LED_COLOR_ID_GREEN>;
+ chan-name = "green:status-0";
+ led-cur = /bits/ 8 <0x64>;
+ max-cur = /bits/ 8 <0x78>;
+ };
+
+ led@2 {
+ reg = <2>;
+ color = <LED_COLOR_ID_BLUE>;
+ chan-name = "blue:status-0";
+ led-cur = /bits/ 8 <0x64>;
+ max-cur = /bits/ 8 <0x78>;
+ };
+
+ led@3 {
+ reg = <3>;
+ color = <LED_COLOR_ID_RED>;
+ chan-name = "red:status-1";
+ led-cur = /bits/ 8 <0x64>;
+ max-cur = /bits/ 8 <0x78>;
+ };
+
+ led@4 {
+ reg = <4>;
+ color = <LED_COLOR_ID_GREEN>;
+ chan-name = "green:status-1";
+ linux,default-trigger = "default-on";
+ led-cur = /bits/ 8 <0x64>;
+ max-cur = /bits/ 8 <0x78>;
+ };
+
+ led@5 {
+ reg = <5>;
+ color = <LED_COLOR_ID_BLUE>;
+ chan-name = "blue:status-1";
+ led-cur = /bits/ 8 <0x64>;
+ max-cur = /bits/ 8 <0x78>;
+ };
+
+ led@6 {
+ reg = <6>;
+ color = <LED_COLOR_ID_RED>;
+ chan-name = "red:status-2";
+ led-cur = /bits/ 8 <0x64>;
+ max-cur = /bits/ 8 <0x78>;
+ };
+
+ led@7 {
+ reg = <7>;
+ color = <LED_COLOR_ID_GREEN>;
+ chan-name = "green:status-2";
+ led-cur = /bits/ 8 <0x64>;
+ max-cur = /bits/ 8 <0x78>;
+ };
+
+ led@8 {
+ reg = <8>;
+ color = <LED_COLOR_ID_BLUE>;
+ chan-name = "blue:status-2";
+ linux,default-trigger = "default-on";
+ led-cur = /bits/ 8 <0x64>;
+ max-cur = /bits/ 8 <0x78>;
+ };
+ };
+
+ led-controller@33 {
+ compatible = "national,lp5523";
+ reg = <0x33>;
+ clock-mode = /bits/ 8 <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ led@0 {
+ reg = <0>;
+ color = <LED_COLOR_ID_RED>;
+ chan-name = "red:status-3";
+ linux,default-trigger = "default-on";
+ led-cur = /bits/ 8 <0x64>;
+ max-cur = /bits/ 8 <0x78>;
+ };
+
+ led@1 {
+ reg = <1>;
+ color = <LED_COLOR_ID_GREEN>;
+ chan-name = "green:status-3";
+ led-cur = /bits/ 8 <0x64>;
+ max-cur = /bits/ 8 <0x78>;
+ };
+
+ led@2 {
+ reg = <2>;
+ color = <LED_COLOR_ID_BLUE>;
+ chan-name = "blue:status-3";
+ led-cur = /bits/ 8 <0x64>;
+ max-cur = /bits/ 8 <0x78>;
+ };
+
+ led@3 {
+ reg = <3>;
+ color = <LED_COLOR_ID_RED>;
+ chan-name = "red:status-4";
+ led-cur = /bits/ 8 <0x64>;
+ max-cur = /bits/ 8 <0x78>;
+ };
+
+ led@4 {
+ reg = <4>;
+ color = <LED_COLOR_ID_GREEN>;
+ chan-name = "green:status-4";
+ linux,default-trigger = "default-on";
+ led-cur = /bits/ 8 <0x64>;
+ max-cur = /bits/ 8 <0x78>;
+ };
+
+ led@5 {
+ reg = <5>;
+ color = <LED_COLOR_ID_BLUE>;
+ chan-name = "blue:status-4";
+ led-cur = /bits/ 8 <0x64>;
+ max-cur = /bits/ 8 <0x78>;
+ };
+
+ led@6 {
+ reg = <6>;
+ color = <LED_COLOR_ID_RED>;
+ chan-name = "red:status-5";
+ led-cur = /bits/ 8 <0x64>;
+ max-cur = /bits/ 8 <0x78>;
+ };
+
+ led@7 {
+ reg = <7>;
+ color = <LED_COLOR_ID_GREEN>;
+ chan-name = "green:status-5";
+ led-cur = /bits/ 8 <0x64>;
+ max-cur = /bits/ 8 <0x78>;
+ };
+
+ led@8 {
+ reg = <8>;
+ color = <LED_COLOR_ID_BLUE>;
+ chan-name = "blue:status-5";
+ linux,default-trigger = "default-on";
+ led-cur = /bits/ 8 <0x64>;
+ max-cur = /bits/ 8 <0x78>;
+ };
+ };
+};
BOARDNAME:=Generic
+FEATURES += nand
--- /dev/null
+define Build/cros-gpt
+ cp $@ $@.tmp 2>/dev/null || true
+ ptgen -o $@.tmp -g \
+ -T cros_kernel -N kernel -p $(CONFIG_TARGET_KERNEL_PARTSIZE)m \
+ -N rootfs -p $(CONFIG_TARGET_ROOTFS_PARTSIZE)m \
+ -N rootfs_data -p \
+ $$((3687-$(CONFIG_TARGET_ROOTFS_PARTSIZE)-\
+ $(CONFIG_TARGET_KERNEL_PARTSIZE)))m
+ cat $@.tmp >> $@
+ rm $@.tmp
+endef
+
+define Build/append-kernel-part
+ dd if=$(IMAGE_KERNEL) bs=$(CONFIG_TARGET_KERNEL_PARTSIZE)M conv=sync >> $@
+endef
+
+# NB: Chrome OS bootloaders replace the '%U' in command lines with the UUID of
+# the kernel partition it chooses to boot from. This gives a flexible way to
+# consistently build and sign kernels that always use the subsequent
+# (PARTNROFF=1) partition as their rootfs.
+define Build/cros-vboot
+ $(STAGING_DIR_HOST)/bin/cros-vbutil \
+ -k $@ -c "root=PARTUUID=%U/PARTNROFF=1" -o $@.new
+ @mv $@.new $@
+endef
+
+define Device/OnhubImage
+ KERNEL_LOADADDR = 0x44208000
+ SOC := qcom-ipq8064
+ KERNEL_SUFFIX := -fit-zImage.itb.vboot
+ KERNEL_NAME := zImage
+ KERNEL = kernel-bin | fit none $$(KDIR)/image-$$(DEVICE_DTS).dtb | cros-vboot
+ IMAGES := factory.bin sysupgrade.bin
+ IMAGE/factory.bin := cros-gpt | append-kernel-part | append-rootfs
+ IMAGE/sysupgrade.bin := sysupgrade-tar | append-metadata
+ DEVICE_PACKAGES := ath10k-firmware-qca988x-ct e2fsprogs kmod-fs-ext4 losetup \
+ partx-utils mkf2fs kmod-fs-f2fs \
+ ucode kmod-google-firmware kmod-tpm-i2c-infineon \
+ kmod-sound-soc-ipq8064-storm kmod-usb-storage
+endef
+
+define Device/asus_onhub
+ $(call Device/OnhubImage)
+ DEVICE_VENDOR := ASUS
+ DEVICE_MODEL := OnHub SRT-AC1900
+ DEVICE_DTS := $$(SOC)-asus-onhub
+ BOARD_NAME := asus-onhub
+endef
+TARGET_DEVICES += asus_onhub
+
+define Device/tplink_onhub
+ $(call Device/OnhubImage)
+ DEVICE_VENDOR := TP-Link
+ DEVICE_MODEL := OnHub AC1900 Cloud Router
+ DEVICE_DTS := $$(SOC)-tplink-onhub
+ BOARD_NAME := tplink-onhub
+endef
+TARGET_DEVICES += tplink_onhub