[PATCH v3 7/7] ipq806x: Initial TP-Link and ASUS OnHub support

Christian Marangi ansuelsmth at gmail.com
Thu Jan 12 06:34:41 PST 2023


On Tue, Jan 10, 2023 at 11:06:52PM -0800, Brian Norris wrote:
> 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 at 192.168.1.1:
>      ssh root at 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 at gmail.com>
> ---
>  * There might be better ways to handle the multi-color LED support,
>    but for now, each color is a separate LED
>  * A variety of people have been interested in this work, and a few have
>    tested versions of it already:
>      https://forum.openwrt.org/t/onhub-tp-link-tgr1900-future-support/17899
>  * This is dependent on an fstools change, to ensure it can find our
>    'rootfs_data' properly:
>      [PATCH fstools v2] partname: Ignore root=PARTUUID...
>      https://patchwork.ozlabs.org/project/openwrt/patch/20230107020424.1703752-1-computersforpeace@gmail.com/
> 
> Changes in v3:
>  * use 'ucode' for base64, to reduce dependency complexity and avoid
>    bringing in coreutils
>  * simplify installation instructions
>  * add back in second CPU / drop maxcpus=1 (I had apparently already
>    fixed this, but kept the maxcpus=1)
> 
> Changes in v2:
>  * Drop custom ath10k base64 property
>  * Provide base64 caldata parsing via
>    /etc/hotplug.d/firmware/11-ath10k-caldata instead
>  * add coreutils-base64 dependency
>  * add 3rd (rootfs_data) partition, to better handle sysupgrade and
>    utilize the whole disk
> 
>  target/linux/ipq806x/Makefile                 |   4 +-
>  .../ipq806x/base-files/etc/board.d/01_leds    |  11 +
>  .../ipq806x/base-files/etc/board.d/02_network |   6 +
>  .../etc/hotplug.d/firmware/11-ath10k-caldata  |  35 ++
>  .../base-files/lib/upgrade/platform.sh        |  19 +
>  .../base-files/usr/bin/base64decode.uc        |  23 +
>  target/linux/ipq806x/chromium/config-default  |  13 +
>  target/linux/ipq806x/chromium/target.mk       |   2 +
>  .../arm/boot/dts/qcom-ipq8064-asus-onhub.dts  |  95 ++++
>  .../arch/arm/boot/dts/qcom-ipq8064-onhub.dtsi | 463 ++++++++++++++++++
>  .../boot/dts/qcom-ipq8064-tplink-onhub.dts    | 207 ++++++++
>  target/linux/ipq806x/generic/target.mk        |   1 +
>  target/linux/ipq806x/image/chromium.mk        |  58 +++
>  13 files changed, 935 insertions(+), 2 deletions(-)
>  create mode 100755 target/linux/ipq806x/base-files/usr/bin/base64decode.uc
>  create mode 100644 target/linux/ipq806x/chromium/config-default
>  create mode 100644 target/linux/ipq806x/chromium/target.mk
>  create mode 100644 target/linux/ipq806x/files-5.15/arch/arm/boot/dts/qcom-ipq8064-asus-onhub.dts
>  create mode 100644 target/linux/ipq806x/files-5.15/arch/arm/boot/dts/qcom-ipq8064-onhub.dtsi
>  create mode 100644 target/linux/ipq806x/files-5.15/arch/arm/boot/dts/qcom-ipq8064-tplink-onhub.dts
>  create mode 100644 target/linux/ipq806x/image/chromium.mk
> 
> diff --git a/target/linux/ipq806x/Makefile b/target/linux/ipq806x/Makefile
> index 862ad7da004b..5c89d413c0d3 100644
> --- a/target/linux/ipq806x/Makefile
> +++ b/target/linux/ipq806x/Makefile
> @@ -5,10 +5,10 @@ include $(TOPDIR)/rules.mk
>  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
>  
> diff --git a/target/linux/ipq806x/base-files/etc/board.d/01_leds b/target/linux/ipq806x/base-files/etc/board.d/01_leds
> index 2b259b903614..80a337c6a4d4 100644
> --- a/target/linux/ipq806x/base-files/etc/board.d/01_leds
> +++ b/target/linux/ipq806x/base-files/etc/board.d/01_leds
> @@ -9,6 +9,9 @@ board_config_update
>  board=$(board_name)
>  
>  case "$board" in
> +asus,onhub)
> +	ucidef_set_led_default "status" "STATUS" "LED_Green" "1"

Can't we set this directly in the dt? Also I think we should use a more
descriptive name.

> +	;;
>  buffalo,wxr-2533dhp)
>  	ucidef_set_led_wlan "wlan" "WLAN" "white:wireless" "phy0tpt"
>  	ucidef_set_led_switch "wan" "WAN" "white:internet" "switch0" "0x20"
> @@ -58,6 +61,14 @@ tplink,c2600)
>  	ucidef_set_led_switch "wan" "wan" "white:wan" "switch0" "0x20"
>  	ucidef_set_led_switch "lan" "lan" "white:lan" "switch0" "0x1e"
>  	;;
> +tplink,onhub)
> +	ucidef_set_led_default "led0_red" "LED0_Red" "LED0_Red" "1"
> +	ucidef_set_led_default "led1_green" "LED1_Green" "LED1_Green" "1"
> +	ucidef_set_led_default "led2_blue" "LED2_Blue" "LED2_Blue" "1"
> +	ucidef_set_led_default "led3_red" "LED3_Red" "LED3_Red" "1"
> +	ucidef_set_led_default "led4_green" "LED4_Green" "LED4_Green" "1"
> +	ucidef_set_led_default "led5_blue" "LED5_Blue" "LED5_Blue" "1"
> +	;;

Same here.

Aside from these leds problem rest of the series looks OK. I have just
some concern about the changed name in patch 1 for downstream project
but we can live with that.

>  tplink,vr2600v)
>  	ucidef_set_led_usbport "usb" "USB" "white:usb" "usb1-port1" "usb2-port1" "usb3-port1" "usb4-port1"
>  	ucidef_set_led_switch "lan" "lan" "white:lan" "switch0" "0x1e"
> diff --git a/target/linux/ipq806x/base-files/etc/board.d/02_network b/target/linux/ipq806x/base-files/etc/board.d/02_network
> index dbff854731a4..f38876b69f08 100644
> --- a/target/linux/ipq806x/base-files/etc/board.d/02_network
> +++ b/target/linux/ipq806x/base-files/etc/board.d/02_network
> @@ -79,6 +79,12 @@ tplink,ad7200)
>  	ucidef_add_switch "switch0" \
>  		"2:lan:1" "3:lan:2" "4:lan:3" "5:lan:4" "6 at eth1" "1:wan" "0 at eth0"
>  	;;
> +asus,onhub |\
> +tplink,onhub)
> +	ucidef_set_interfaces_lan_wan "eth1" "eth0"
> +	ucidef_add_switch "switch0" \
> +		"1:lan" "6 at eth1" "2:wan" "0 at eth0"
> +	;;
>  ubnt,unifi-ac-hd)
>  	ucidef_set_interface_lan "eth0 eth1"
>  	;;
> diff --git a/target/linux/ipq806x/base-files/etc/hotplug.d/firmware/11-ath10k-caldata b/target/linux/ipq806x/base-files/etc/hotplug.d/firmware/11-ath10k-caldata
> index 398ddf9a290a..a0e2e9d1237b 100644
> --- a/target/linux/ipq806x/base-files/etc/hotplug.d/firmware/11-ath10k-caldata
> +++ b/target/linux/ipq806x/base-files/etc/hotplug.d/firmware/11-ath10k-caldata
> @@ -6,9 +6,32 @@
>  
>  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
> @@ -35,6 +58,14 @@ case "$FIRMWARE" in
>  		;;
>  	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)
> @@ -61,6 +92,10 @@ case "$FIRMWARE" in
>  	;;
>  "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
> diff --git a/target/linux/ipq806x/base-files/lib/upgrade/platform.sh b/target/linux/ipq806x/base-files/lib/upgrade/platform.sh
> index f9e592f4bd8f..67ceaab24fb5 100644
> --- a/target/linux/ipq806x/base-files/lib/upgrade/platform.sh
> +++ b/target/linux/ipq806x/base-files/lib/upgrade/platform.sh
> @@ -57,6 +57,15 @@ platform_do_upgrade() {
>  		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"
> @@ -69,3 +78,13 @@ platform_do_upgrade() {
>  		;;
>  	esac
>  }
> +
> +platform_copy_config() {
> +	case "${board_name}" in
> +	asus,onhub |\
> +	tplink,onhub)
> +		emmc_copy_config
> +		;;
> +	esac
> +	return 0
> +}
> diff --git a/target/linux/ipq806x/base-files/usr/bin/base64decode.uc b/target/linux/ipq806x/base-files/usr/bin/base64decode.uc
> new file mode 100755
> index 000000000000..7dcf30986c04
> --- /dev/null
> +++ b/target/linux/ipq806x/base-files/usr/bin/base64decode.uc
> @@ -0,0 +1,23 @@
> +#!/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);
> diff --git a/target/linux/ipq806x/chromium/config-default b/target/linux/ipq806x/chromium/config-default
> new file mode 100644
> index 000000000000..d7db9f7db35a
> --- /dev/null
> +++ b/target/linux/ipq806x/chromium/config-default
> @@ -0,0 +1,13 @@
> +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
> diff --git a/target/linux/ipq806x/chromium/target.mk b/target/linux/ipq806x/chromium/target.mk
> new file mode 100644
> index 000000000000..3983a9281a5d
> --- /dev/null
> +++ b/target/linux/ipq806x/chromium/target.mk
> @@ -0,0 +1,2 @@
> +BOARDNAME:=Google Chromium
> +FEATURES += emmc boot-part rootfs-part
> diff --git a/target/linux/ipq806x/files-5.15/arch/arm/boot/dts/qcom-ipq8064-asus-onhub.dts b/target/linux/ipq806x/files-5.15/arch/arm/boot/dts/qcom-ipq8064-asus-onhub.dts
> new file mode 100644
> index 000000000000..de0cf978c3e3
> --- /dev/null
> +++ b/target/linux/ipq806x/files-5.15/arch/arm/boot/dts/qcom-ipq8064-asus-onhub.dts
> @@ -0,0 +1,95 @@
> +// 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 at 1c {
> +		compatible = "dynaimage,ap3223";
> +		reg = <0x1c>;
> +
> +		pinctrl-0 = <&ap3223_pins>;
> +		pinctrl-names = "default";
> +
> +		int-gpio = <&qcom_pinmux 22 GPIO_ACTIVE_LOW>;
> +	};
> +
> +	led-controller at 32 {
> +		compatible = "national,lp5523";
> +		reg = <0x32>;
> +		clock-mode = /bits/ 8 <1>;
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +
> +		led at 4 {
> +			reg = <4>;
> +			color = <LED_COLOR_ID_GREEN>;
> +			chan-name = "LED_Green";
> +			led-cur = /bits/ 8 <0xfa>;
> +			max-cur = /bits/ 8 <0xff>;
> +		};
> +
> +		led at 5 {
> +			reg = <5>;
> +			color = <LED_COLOR_ID_BLUE>;
> +			chan-name = "LED_Blue";
> +			led-cur = /bits/ 8 <0xfa>;
> +			max-cur = /bits/ 8 <0xff>;
> +		};
> +
> +		led at 8 {
> +			reg = <8>;
> +			color = <LED_COLOR_ID_RED>;
> +			chan-name = "LED_Red";
> +			led-cur = /bits/ 8 <0xfa>;
> +			max-cur = /bits/ 8 <0xff>;
> +		};
> +	};
> +};
> diff --git a/target/linux/ipq806x/files-5.15/arch/arm/boot/dts/qcom-ipq8064-onhub.dtsi b/target/linux/ipq806x/files-5.15/arch/arm/boot/dts/qcom-ipq8064-onhub.dtsi
> new file mode 100644
> index 000000000000..25ba71da00ef
> --- /dev/null
> +++ b/target/linux/ipq806x/files-5.15/arch/arm/boot/dts/qcom-ipq8064-onhub.dtsi
> @@ -0,0 +1,463 @@
> +// 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 at 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 at 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 at 1 {
> +			reg = <1>;
> +		};
> +	};
> +
> +	soc {
> +		rng at 1a500000 {
> +			status = "disabled";
> +		};
> +
> +		sound {
> +			compatible = "google,storm-audio";
> +			qcom,model = "ipq806x-storm";
> +			cpu = <&lpass>;
> +			codec = <&max98357a>;
> +		};
> +
> +		lpass: lpass at 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 at 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 at 1a280000 {
> +		status = "okay";
> +		spi-max-frequency = <50000000>;
> +		pinctrl-0 = <&spi_pins>;
> +		pinctrl-names = "default";
> +
> +		cs-gpios = <&qcom_pinmux 20 0>;
> +
> +		flash: flash at 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 at 0 {
> +		compatible = "spidev";
> +		reg = <0>;
> +		spi-max-frequency = <25000000>;
> +	};
> +};
> +
> +&pcie0 {
> +	status = "okay";
> +
> +	pcie at 0 {
> +		reg = <0 0 0 0 0>;
> +		#interrupt-cells = <1>;
> +		#size-cells = <2>;
> +		#address-cells = <3>;
> +		device_type = "pci";
> +
> +		ath10k at 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 at 0 {
> +		reg = <0 0 0 0 0>;
> +		#interrupt-cells = <1>;
> +		#size-cells = <2>;
> +		#address-cells = <3>;
> +		device_type = "pci";
> +
> +		ath10k at 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 at 0 {
> +		reg = <0 0 0 0 0>;
> +		#interrupt-cells = <1>;
> +		#size-cells = <2>;
> +		#address-cells = <3>;
> +		device_type = "pci";
> +
> +		ath10k at 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";
> +};
> diff --git a/target/linux/ipq806x/files-5.15/arch/arm/boot/dts/qcom-ipq8064-tplink-onhub.dts b/target/linux/ipq806x/files-5.15/arch/arm/boot/dts/qcom-ipq8064-tplink-onhub.dts
> new file mode 100644
> index 000000000000..493c348c229b
> --- /dev/null
> +++ b/target/linux/ipq806x/files-5.15/arch/arm/boot/dts/qcom-ipq8064-tplink-onhub.dts
> @@ -0,0 +1,207 @@
> +// 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 at 32 {
> +		compatible = "national,lp5523";
> +		reg = <0x32>;
> +		clock-mode = /bits/ 8 <1>;
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +
> +		led at 0 {
> +			reg = <0>;
> +			color = <LED_COLOR_ID_RED>;
> +			chan-name = "LED0_Red";
> +			led-cur = /bits/ 8 <0x64>;
> +			max-cur = /bits/ 8 <0x78>;
> +		};
> +
> +		led at 1 {
> +			reg = <1>;
> +			color = <LED_COLOR_ID_GREEN>;
> +			chan-name = "LED0_Green";
> +			led-cur = /bits/ 8 <0x64>;
> +			max-cur = /bits/ 8 <0x78>;
> +		};
> +
> +		led at 2 {
> +			reg = <2>;
> +			color = <LED_COLOR_ID_BLUE>;
> +			chan-name = "LED0_Blue";
> +			led-cur = /bits/ 8 <0x64>;
> +			max-cur = /bits/ 8 <0x78>;
> +		};
> +
> +		led at 3 {
> +			reg = <3>;
> +			color = <LED_COLOR_ID_RED>;
> +			chan-name = "LED1_Red";
> +			led-cur = /bits/ 8 <0x64>;
> +			max-cur = /bits/ 8 <0x78>;
> +		};
> +
> +		led at 4 {
> +			reg = <4>;
> +			color = <LED_COLOR_ID_GREEN>;
> +			chan-name = "LED1_Green";
> +			led-cur = /bits/ 8 <0x64>;
> +			max-cur = /bits/ 8 <0x78>;
> +		};
> +
> +		led at 5 {
> +			reg = <5>;
> +			color = <LED_COLOR_ID_BLUE>;
> +			chan-name = "LED1_Blue";
> +			led-cur = /bits/ 8 <0x64>;
> +			max-cur = /bits/ 8 <0x78>;
> +		};
> +
> +		led at 6 {
> +			reg = <6>;
> +			color = <LED_COLOR_ID_RED>;
> +			chan-name = "LED2_Red";
> +			led-cur = /bits/ 8 <0x64>;
> +			max-cur = /bits/ 8 <0x78>;
> +		};
> +
> +		led at 7 {
> +			reg = <7>;
> +			color = <LED_COLOR_ID_GREEN>;
> +			chan-name = "LED2_Green";
> +			led-cur = /bits/ 8 <0x64>;
> +			max-cur = /bits/ 8 <0x78>;
> +		};
> +
> +		led at 8 {
> +			reg = <8>;
> +			color = <LED_COLOR_ID_BLUE>;
> +			chan-name = "LED2_Blue";
> +			led-cur = /bits/ 8 <0x64>;
> +			max-cur = /bits/ 8 <0x78>;
> +		};
> +	};
> +
> +	led-controller at 33 {
> +		compatible = "national,lp5523";
> +		reg = <0x33>;
> +		clock-mode = /bits/ 8 <1>;
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +
> +		led at 0 {
> +			reg = <0>;
> +			color = <LED_COLOR_ID_RED>;
> +			chan-name = "LED3_Red";
> +			led-cur = /bits/ 8 <0x64>;
> +			max-cur = /bits/ 8 <0x78>;
> +		};
> +
> +		led at 1 {
> +			reg = <1>;
> +			color = <LED_COLOR_ID_GREEN>;
> +			chan-name = "LED3_Green";
> +			led-cur = /bits/ 8 <0x64>;
> +			max-cur = /bits/ 8 <0x78>;
> +		};
> +
> +		led at 2 {
> +			reg = <2>;
> +			color = <LED_COLOR_ID_BLUE>;
> +			chan-name = "LED3_Blue";
> +			led-cur = /bits/ 8 <0x64>;
> +			max-cur = /bits/ 8 <0x78>;
> +		};
> +
> +		led at 3 {
> +			reg = <3>;
> +			color = <LED_COLOR_ID_RED>;
> +			chan-name = "LED4_Red";
> +			led-cur = /bits/ 8 <0x64>;
> +			max-cur = /bits/ 8 <0x78>;
> +		};
> +
> +		led at 4 {
> +			reg = <4>;
> +			color = <LED_COLOR_ID_GREEN>;
> +			chan-name = "LED4_Green";
> +			led-cur = /bits/ 8 <0x64>;
> +			max-cur = /bits/ 8 <0x78>;
> +		};
> +
> +		led at 5 {
> +			reg = <5>;
> +			color = <LED_COLOR_ID_BLUE>;
> +			chan-name = "LED4_Blue";
> +			led-cur = /bits/ 8 <0x64>;
> +			max-cur = /bits/ 8 <0x78>;
> +		};
> +
> +		led at 6 {
> +			reg = <6>;
> +			color = <LED_COLOR_ID_RED>;
> +			chan-name = "LED5_Red";
> +			led-cur = /bits/ 8 <0x64>;
> +			max-cur = /bits/ 8 <0x78>;
> +		};
> +
> +		led at 7 {
> +			reg = <7>;
> +			color = <LED_COLOR_ID_GREEN>;
> +			chan-name = "LED5_Green";
> +			led-cur = /bits/ 8 <0x64>;
> +			max-cur = /bits/ 8 <0x78>;
> +		};
> +
> +		led at 8 {
> +			reg = <8>;
> +			color = <LED_COLOR_ID_BLUE>;
> +			chan-name = "LED5_Blue";
> +			led-cur = /bits/ 8 <0x64>;
> +			max-cur = /bits/ 8 <0x78>;
> +		};
> +	};
> +};
> diff --git a/target/linux/ipq806x/generic/target.mk b/target/linux/ipq806x/generic/target.mk
> index f5cb1fb19b94..4de636f0e0ae 100644
> --- a/target/linux/ipq806x/generic/target.mk
> +++ b/target/linux/ipq806x/generic/target.mk
> @@ -1 +1,2 @@
>  BOARDNAME:=Generic
> +FEATURES += nand
> diff --git a/target/linux/ipq806x/image/chromium.mk b/target/linux/ipq806x/image/chromium.mk
> new file mode 100644
> index 000000000000..16af6b95ba6c
> --- /dev/null
> +++ b/target/linux/ipq806x/image/chromium.mk
> @@ -0,0 +1,58 @@
> +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
> -- 
> 2.39.0
> 
> 
> _______________________________________________
> openwrt-devel mailing list
> openwrt-devel at lists.openwrt.org
> https://lists.openwrt.org/mailman/listinfo/openwrt-devel

-- 
	Ansuel



More information about the openwrt-devel mailing list