ath79: add support for PISEN WMB001N
authorChuanhong Guo <gch981213@gmail.com>
Sun, 4 Aug 2019 14:13:45 +0000 (22:13 +0800)
committerChuanhong Guo <gch981213@gmail.com>
Thu, 8 Aug 2019 13:00:59 +0000 (21:00 +0800)
Specifications:
- SoC: AR9341
- RAM: 64M
- Flash: 16M
- Ethernet: 1 * FE port
- WiFi: ar934x-wmac
- Sound: WM8918 DAC
         1 * 3.5mm headphone jack
         2 * RCA connectors for speakers
         1 * SPDIF out
- USB: 1 * USB2.0 port

Flash instruction:
 Upload generated factory image via vendor's web interface.

Notes:
A. Audio stuff:
 1. Since AR934x, all pins for peripheral blocks can be mapped to
    any available GPIOs. We currently don't have a PCM/I2S driver
    for AR934x so pinmux for i2s and SPDIF are bound to i2c gpio
    node. This should be moved into I2S node when a PCM/I2S driver
    is available.
 2. The i2c-gpio node is for WM8918. DT binding for it can't be added
    currently due to a missing clock from I2S PLL.

B. Factory image:
 Image contains a image header and a tar.gz archive.
 1. Header: A 288 byte header that has nothing to do with appended
    tarball. Format:
     0x0-0x7 and 0x18-0x1F: magic values
     0x20: Model number string
     0xFC: Action string. It's either "update" or "backup"
     0x11C: A 1 byte checksum. It's XOR result of 0x8-0x11B
    Firmware doesn't care about the rest of the header as long as
    checksum result is correct.
    The same header is used for backup and update routines so the
    magic values and model number can be obtained by generating a
    backup bin and grab values from it.
 2. Tarball: It contains two files named uImage and rootfs, which
    will be flashed into corresponding mtd partition.
 Writing a special utility that can only output a fixed binary
 blob is overkill so factory image header is placed under
 image/bin instead.

C. LED
 The wifi led has "Wi-Fi" marked on the case but vendor's firmware
 used it as system status indicator. I did the same in this device
 support patch.

D. Firmware
 Factory u-boot is built without 'savenv' support so it's impossible
 to change kernel offset. A 2MB kernel partition won't be enough in
 the future. OKLI loader is used here to migrate this problem:
  1. add OKLI image magic support into uImage parser.
  2. build an OKLI loader, compress it with lzma and add a normal
     uImage header.
  3. flash the loader to where the original kernel supposed to be.
  4. create a uImage firmware using OKLI loader.
  5. flash the created firmware to where rootfs supposed to be.
 By doing so, u-boot will start OKLI loader, which will then load
 the actual kernel at 0x20000.

 The kernel partition is 2MB, which is too much for our loader.
 To save this space, "mtd-concat" is used here:
  1. create a 64K (1 erase block) partition for OKLI loader and
     create another partition with the left space.
  2. concatenate rootfs and this partition into a virtual flash.
  3. use the virtual flash for firmware partition.

 Currently OKLI loader is flashed with factory image only.
 sysupgrade won't replace it. Since it only has one function
 and it works for several years, its unlikely to have some bugs
 that requires a replacement.

Signed-off-by: Chuanhong Guo <gch981213@gmail.com>
target/linux/ath79/base-files/etc/board.d/02_network
target/linux/ath79/dts/ar9341_pisen_wmb001n.dts [new file with mode: 0644]
target/linux/ath79/image/Makefile
target/linux/ath79/image/bin/pisen_wmb001n_factory-header.bin [new file with mode: 0644]
target/linux/ath79/image/generic.mk

index e3c1f423f1c918a2b73845ec515e7e7d8ab396b7..3b89c9c58d082a34da52aa6edecaca8d96326680 100755 (executable)
@@ -25,6 +25,7 @@ ath79_setup_interfaces()
        ocedo,koala|\
        ocedo,raccoon|\
        pcs,cap324|\
+       pisen,wmb001n|\
        pisen,wmm003n|\
        pqi,air-pen|\
        tplink,cpe210-v2|\
diff --git a/target/linux/ath79/dts/ar9341_pisen_wmb001n.dts b/target/linux/ath79/dts/ar9341_pisen_wmb001n.dts
new file mode 100644 (file)
index 0000000..8029de5
--- /dev/null
@@ -0,0 +1,225 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+#include "ar9341.dtsi"
+
+/ {
+       model = "PISEN WMB001N";
+       compatible = "pisen,wmb001n", "qca,ar9341";
+
+       aliases {
+               serial0 = &uart;
+               led-boot = &wifi;
+               led-failsafe = &wifi;
+               led-running = &wifi;
+               led-upgrade = &wifi;
+       };
+
+       i2c {
+               compatible = "i2c-gpio";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pmx_i2c_gpio &pmx_i2s_spdif>;
+
+               sda-gpios = <&gpio 16 (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN)>;
+               scl-gpios = <&gpio 20 GPIO_ACTIVE_HIGH>;
+               /*
+                * Pull-up resistor for scl is missing on this board.
+                * Following settings trick i2c-gpio to use output mode
+                * instead of open-drain for scl.
+                */
+               i2c-gpio,scl-output-only;
+               i2c-gpio,scl-open-drain;
+       };
+
+       keys {
+               compatible = "gpio-keys";
+
+               reset {
+                       label = "reset";
+                       linux,code = <KEY_RESTART>;
+                       gpios = <&gpio 17 GPIO_ACTIVE_LOW>;
+                       debounce-interval = <60>;
+               };
+
+               vol_down {
+                       label = "volume down";
+                       linux,code = <KEY_VOLUMEDOWN>;
+                       gpios = <&gpio 18 GPIO_ACTIVE_LOW>;
+                       debounce-interval = <60>;
+               };
+
+               vol_up {
+                       label = "volume up";
+                       linux,code = <KEY_VOLUMEUP>;
+                       gpios = <&gpio 19 GPIO_ACTIVE_LOW>;
+                       debounce-interval = <60>;
+               };
+       };
+
+       leds {
+               compatible = "gpio-leds";
+               pinctrl-names = "default";
+               pinctrl-0 = <&jtag_disable_pins>;
+
+               volume1 {
+                       label = "wmb001n:blue:volume1";
+                       gpios = <&gpio 0 GPIO_ACTIVE_HIGH>;
+               };
+
+               volume2 {
+                       label = "wmb001n:blue:volume2";
+                       gpios = <&gpio 1 GPIO_ACTIVE_HIGH>;
+               };
+
+               volume3 {
+                       label = "wmb001n:blue:volume3";
+                       gpios = <&gpio 2 GPIO_ACTIVE_HIGH>;
+               };
+
+               volume4 {
+                       label = "wmb001n:blue:volume4";
+                       gpios = <&gpio 3 GPIO_ACTIVE_HIGH>;
+               };
+
+               volume5 {
+                       label = "wmb001n:blue:volume5";
+                       gpios = <&gpio 4 GPIO_ACTIVE_HIGH>;
+               };
+
+               wifi: wifi {
+                       label = "wmb001n:blue:wifi";
+                       gpios = <&gpio 22 GPIO_ACTIVE_HIGH>;
+               };
+       };
+
+       virtual_flash {
+               compatible = "mtd-concat";
+               devices = <&fwpart1 &fwpart2>;
+
+               partitions {
+                       compatible = "fixed-partitions";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+
+                       partition@0 {
+                               reg = <0x0 0x0>;
+                               label = "firmware";
+                               compatible = "openwrt,okli";
+                       };
+               };
+       };
+};
+
+&pinmux {
+       pmx_i2c_gpio: pinmux_i2c_gpio {
+               pinctrl-single,bits = <0x10 0x0 0xff>,
+                                     <0x14 0x0 0xff>;
+       };
+
+       pmx_i2s_spdif: pinmux_i2s_spdif {
+               pinctrl-single,bits = <0x8 0x0e000000 0xff000000>,
+                                     <0xc 0x0f0c0d 0xffffff>,
+                                     <0x14 0x1900 0xff00>;
+       };
+};
+
+&ref {
+       clock-frequency = <25000000>;
+};
+
+&uart {
+       status = "okay";
+};
+
+&gpio {
+       status = "okay";
+};
+
+&spi {
+       num-cs = <1>;
+
+       status = "okay";
+
+       flash@0 {
+               compatible = "jedec,spi-nor";
+               reg = <0>;
+               spi-max-frequency = <25000000>;
+
+               partitions {
+                       compatible = "fixed-partitions";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+
+                       uboot: partition@0 {
+                               label = "u-boot";
+                               reg = <0x0 0x10000>;
+                               read-only;
+                       };
+
+                       partition@10000 {
+                               label = "u-boot-env";
+                               reg = <0x10000 0x10000>;
+                               read-only;
+                       };
+
+                       fwpart1: partition@20000 {
+                               label = "fwpart1";
+                               reg = <0x20000 0xdc0000>;
+                       };
+
+                       partition@de0000 {
+                               label = "loader";
+                               reg = <0xde0000 0x10000>;
+                       };
+
+                       fwpart2: partition@df0000 {
+                               label = "fwpart2";
+                               reg = <0xdf0000 0x1f0000>;
+                       };
+
+                       partition@fe0000 {
+                               label = "mib0";
+                               reg = <0xfe0000 0x10000>;
+                               read-only;
+                       };
+
+                       art: partition@ff0000 {
+                               label = "art";
+                               reg = <0xff0000 0x10000>;
+                               read-only;
+                       };
+               };
+       };
+};
+
+&eth0 {
+       status = "okay";
+       phy-handle = <&swphy4>;
+       mtd-mac-address = <&art 0x0>;
+};
+
+&eth1 {
+       compatible = "syscon", "simple-mfd";
+       status = "okay";
+
+       gmac-config {
+               device = <&gmac>;
+               switch-phy-swap = <0>;
+       };
+};
+
+&usb {
+       status = "okay";
+};
+
+&usb_phy {
+       status = "okay";
+};
+
+&wmac {
+       status = "okay";
+       mtd-cal-data = <&art 0x1000>;
+};
index 734f27e689c9d76abedad8c89f22a24006ba86ae..24768ef5e0d6bf7ce027a8e0d9b012783b6ddaeb 100644 (file)
@@ -36,6 +36,10 @@ define Build/loader-okli
        mv "$@.new" "$@"
 endef
 
+define Build/append-loader-okli
+       cat "$(KDIR)/loader-$(word 1,$(1)).$(LOADER_TYPE)" >> "$@"
+endef
+
 define Build/relocate-kernel
        rm -rf $@.relocate
        $(CP) ../../generic/image/relocate $@.relocate
diff --git a/target/linux/ath79/image/bin/pisen_wmb001n_factory-header.bin b/target/linux/ath79/image/bin/pisen_wmb001n_factory-header.bin
new file mode 100644 (file)
index 0000000..99e1e8a
Binary files /dev/null and b/target/linux/ath79/image/bin/pisen_wmb001n_factory-header.bin differ
index abaf1a3e07ea5c34f262fa387c06b8696f0e16a5..5127cfd510b53ba300b69fbd7d67a48dd5d308a4 100644 (file)
@@ -58,6 +58,18 @@ define Build/nec-fw
   mv $@.new $@
 endef
 
+define Build/pisen_wmb001n-factory
+  -[ -f "$@" ] && \
+  mkdir -p "$@.tmp" && \
+  cp "$(KDIR)/loader-$(word 1,$(1)).uImage" "$@.tmp/uImage" && \
+  mv "$@" "$@.tmp/rootfs" && \
+  cp "bin/pisen_wmb001n_factory-header.bin" "$@" && \
+  $(TAR) -cp --numeric-owner --owner=0 --group=0 --mode=a-s --sort=name \
+    $(if $(SOURCE_DATE_EPOCH),--mtime="@$(SOURCE_DATE_EPOCH)") \
+    -C "$@.tmp" . | gzip -9n >> "$@" && \
+  rm -rf "$@.tmp"
+endef
+
 define Device/seama
   KERNEL := kernel-bin | append-dtb | relocate-kernel | lzma
   KERNEL_INITRAMFS := $$(KERNEL) | seama
@@ -775,6 +787,23 @@ define Device/netgear_wndr3700v2
 endef
 TARGET_DEVICES += netgear_wndr3700v2
 
+define Device/pisen_wmb001n
+  ATH_SOC := ar9341
+  DEVICE_VENDOR := PISEN
+  DEVICE_MODEL := WMB001N
+  IMAGE_SIZE := 14080k
+  DEVICE_PACKAGES := kmod-i2c-core kmod-i2c-gpio kmod-usb2
+  LOADER_TYPE := bin
+  LOADER_FLASH_OFFS := 0x20000
+  COMPILE := loader-$(1).bin loader-$(1).uImage
+  COMPILE/loader-$(1).bin := loader-okli-compile
+  COMPILE/loader-$(1).uImage := append-loader-okli $(1) | pad-to 64k | lzma | uImage lzma
+  KERNEL := kernel-bin | append-dtb | lzma | uImage lzma -M 0x4f4b4c49
+  IMAGES += factory.bin
+  IMAGE/factory.bin := $$(IMAGE/sysupgrade.bin) | pisen_wmb001n-factory $(1)
+endef
+TARGET_DEVICES += pisen_wmb001n
+
 define Device/pisen_wmm003n
   $(Device/tplink-8mlzma)
   ATH_SOC := ar9331