LoginSignup
3
0

More than 1 year has passed since last update.

Ultra96-V2 の WiFi で超苦労した話(v2021.1編)

Posted at

はじめに

以前、Ultra96-V2 の WiFi を Xilinx 社の提供する linux-xlnx v2019.1 で動かす方法について Qiita に次のような記事を投稿しました。

上の記事では linux-xlnx v2019.1 (Linux Kernel 5.4 をベース) を対象にしていましたが、linux-xlnx v2021.1 (Linux Kernel 5.10 をベース) では上の記事で紹介した方法では Ultra96-V2 の WiFi を動かすことができませんでした。

この記事では、Ultra96-V2 向け Debian GNU/Linux (v2021.1版) で WiFi を動かすために ATWILC3000 の Linux Driver を組み込む方法を紹介します。

Linux Driver のリポジトリ

linux-xlnx v2019.1 では ATWILC3000 の Linux Driver は Avnet が提供しているものを使っていましたが、この Linux Driver は linux-xlnx v2021.1 ではコンパイルできませんでした。そこで linux-xlnx v2021.1 では WiFi Chip の製造元である Microchip 社が提供している Linux Driver を使います。

Microchip 社の提供する Linux Driver は github で公開されています。

上記のリポジトリは Linux Kernel 全体の Fork になっています(かなりデカいので注意)。該当する Linux Driver のソースコードは drivers/net/wireless/microchip/wilc1000 にあります。また、linux-xlnx v2021.1 からは新に mmc のパワー制御のための Linux Driver が必要になります。ATWILC3000 用のパワー制御用 Linux Driver のソースコードは drivers/mmc/core/pwrseq_wilc.c です。

パッチのリポジトリ

上記の Linux Driver を試したところ、私の Ultra96-V2 では動作しませんでした。いろいろ調べた結果、Avnet の提供するパッチをあてる必要があることがわかりました。パッチは次の URL にあります。

Linux Kernel のソースコードに追加する

Microchip 社の Linux Driver をダウンロード

shell$ git clone --depth 1 https://github.com/linux4sam/linux-at91

Avnet 社の meta-avnet をダウンロード

shell$ git clone --depth 1 -b 2021.1 https://github.com/Avnet/meta-avnet

linux-xlnx v2021.1 をダウンロード

linux-xlnx v2021.1 をダウンロードします。ディレクトリは linux-xlnx-v2021.1-zynqmp-fpga としています。

shell$ git clone --depth 1 -b xilinx-v2021.1 https://github.com/Xilinx/linux-xlnx.git linux-xlnx-v2021.1-zynqmp-fpga
shell$ cd linux-xlnx-v2021.1-zynqmp-fpga

ATWILC3000 の Linux Driver を linux-xlnx v2021.1 にコピー

drivers/net/wireless/microchip/wilc1000/ にあるソースファイルを drivers/staging/wilc3000/ にコピーします。

shell$ mkdir drivers/staging/wilc3000
shell$ cp ../linux-at91/drivers/net/wireless/microchip/wilc1000/* drivers/staging/wilc3000

drivers/staging/Kconfig と drivers/staging/Makefile に wilc3000 を追加します。

linux-xlnx-v2021.1-zynqmp-fpga-wilc3000.diff
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig
index 9d424b925..2ea288a5e 100644
--- a/drivers/staging/Kconfig
+++ b/drivers/staging/Kconfig
@@ -82,6 +82,8 @@ source "drivers/staging/fbtft/Kconfig"

 source "drivers/staging/fsl-dpaa2/Kconfig"

+source "drivers/staging/wilc3000/Kconfig"
+
 source "drivers/staging/most/Kconfig"

 source "drivers/staging/ks7010/Kconfig"
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile
index 55a321d29..f0152d834 100644
--- a/drivers/staging/Makefile
+++ b/drivers/staging/Makefile
@@ -31,6 +31,7 @@ obj-$(CONFIG_UNISYSSPAR)  += unisys/
 obj-$(CONFIG_XILINX_APF)   += apf/
 obj-$(CONFIG_FB_TFT)       += fbtft/
 obj-$(CONFIG_FSL_DPAA2)        += fsl-dpaa2/
+obj-$(CONFIG_WILC)     += wilc3000/
 obj-$(CONFIG_MOST)     += most/
 obj-$(CONFIG_KS7010)       += ks7010/
 obj-$(CONFIG_GREYBUS)      += greybus/

Avnet のパッチをあてる

drivers/staging/wilc3000 に Avnet が提供しているパッチをあてます。

shell$ patch -d drivers/staging/wilc3000 < ../meta-avnet/recipes-modules/wilc/files/0001-ultra96-modifications-15.5.patch
patching file Kconfig
patching file Makefile
patching file cfg80211.c
patching file debugfs.h
patching file netdev.c
patching file netdev.h
patching file power.c
patching file sdio.c
patching file wlan.c
patching file wlan.h
patching file wlan_cfg.c

ATWILC3000 パワー制御用の Linux Driver を linux-xlnx v2021.1 にコピー

pwrseq_wilc.c を drivers/mmc/core/ にコピーします。

shell$ cp ../linux-at91/drivers/mmc/core/pwrseq_wilc.c drivers/mmc/core/

drivers/mmc/core/Kconfig と drivers/mmc/core/Makefile に pwrseq_wilc を追加します。

linux-xlnx-v2021.1-zynqmp-fpga-pwrseq-wilc.diff
diff --git a/drivers/mmc/core/Kconfig b/drivers/mmc/core/Kconfig
index c12fe13e4..b65ff34fe 100644
--- a/drivers/mmc/core/Kconfig
+++ b/drivers/mmc/core/Kconfig
@@ -34,6 +34,16 @@ config PWRSEQ_SIMPLE
      This driver can also be built as a module. If so, the module
      will be called pwrseq_simple.

+config PWRSEQ_WILC
+   tristate "HW reset support for Microchip WILC BT + WiFi devices"
+   depends on OF
+   help
+     This selects hardware reset support for Microchip WILC BT + WiFi
+     devices. By default this option is set to n.
+
+     This driver can also be built as a module. If so, the module
+     will be called pwrseq_wilc.
+
 config MMC_BLOCK
    tristate "MMC block device driver"
    depends on BLOCK
diff --git a/drivers/mmc/core/Makefile b/drivers/mmc/core/Makefile
index 95ffe008e..058ac3fa9 100644
--- a/drivers/mmc/core/Makefile
+++ b/drivers/mmc/core/Makefile
@@ -13,6 +13,7 @@ mmc_core-$(CONFIG_OF)     += pwrseq.o
 obj-$(CONFIG_PWRSEQ_SIMPLE)    += pwrseq_simple.o
 obj-$(CONFIG_PWRSEQ_SD8787)    += pwrseq_sd8787.o
 obj-$(CONFIG_PWRSEQ_EMMC)  += pwrseq_emmc.o
+obj-$(CONFIG_PWRSEQ_WILC)  += pwrseq_wilc.o
 mmc_core-$(CONFIG_DEBUG_FS)    += debugfs.o
 obj-$(CONFIG_MMC_BLOCK)        += mmc_block.o
 mmc_block-objs         := block.o queue.o

Linux Kernel のイメージに組み込む

Ultra96-V2 では ATWILC3000 は ZynqMP の sdio1 に接続しています。ATWILC3000 を SDIO から制御するためのデバイスドライバは CONFIG_WILC_SDIO です。arch/arm64/configs/xilinx_zynqmp_defconfig に CONFIG_WILC_SDIO=y を追加します。ここではモジュールではなく Linux Kernel Image に組み込んでしまうために =m でなく =y を指定しています。
同様に ATWILC3000 のパワー制御用ドライバを組み込むために CONFIG_PWRSEQ_WILC=y を arch/arm64/configs/xilinx_zynqmp_defconfig に追加します。

diff --git a/arch/arm64/configs/xilinx_zynqmp_defconfig b/arch/arm64/configs/xilinx_zynqmp_defconfig
index cd6b1a7d7..a6cdc6600 100644
--- a/arch/arm64/configs/xilinx_zynqmp_defconfig
+++ b/arch/arm64/configs/xilinx_zynqmp_defconfig
@@ -180,6 +180,8 @@ CONFIG_USB_USBNET=y
 CONFIG_WL18XX=y
 CONFIG_WLCORE_SPI=y
 CONFIG_WLCORE_SDIO=y
+CONFIG_WILC_SDIO=y
+CONFIG_PWRSEQ_WILC=y
 CONFIG_INPUT_EVDEV=y
 CONFIG_KEYBOARD_GPIO=y
 CONFIG_KEYBOARD_GPIO_POLLED=y

Device Tree に組み込む

Ultra96-V2 では ATWILC3000 は ZynqMP の sdio1 に接続しています。したがって Device Tree の sdio1 のデバイスドライバである sdhci1 に ATWILC3000 のデバイスドライバをノードとして追加します。下記の例では wlcore というシンボルでノードを追加しています。

arch/arm64/boot/dts/xilinx/avnet-ultra96v2-rev1.dts
&sdhci1 {
    status = "okay";
    bus-width = <0x4>;
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_sdhci1_default>;
    xlnx,mio-bank = <0>;
    non-removable;
    disable-wp;
    // cap-power-off-card; /* This is not compatible with the WILC3000 and means the WILC will always be powered on */
    non-removeable;
    mmc-pwrseq = <&sdio_pwrseq>;
    vqmmc-supply = <&wmmcsdio_fixed>;
    #address-cells = <1>;
    #size-cells = <0>;
    wlcore: wilc_sdio@0 {
        compatible    = "microchip,wilc3000", "microchip,wilc3000";
        status        = "okay";
        reg           = <0>;
        bus-width     = <4>;
    };
};

wlcore の compatible プロパティには "microchip,wilc3000", "microchip,wilc3000" を指定します。

mmc のパワー制御用のドライバは mmc-pwrseq プロパティで指定します。Ultra96-V2 では <&sdio_pwrseq> を指定します。 <&sdio_pwrseq> はデバイスツリーのトップレベルに次のように記述します。

arch/arm64/boot/dts/xilinx/avnet-ultra96v2-rev1.dts
/ {
    :
    (中略)
    :
    sdio_pwrseq: sdio-pwrseq {
        compatible = "mmc-pwrseq-wilc";
        reset-gpios = <&gpio 7 GPIO_ACTIVE_HIGH>;
        powerdown-gpios = <&gpio 8 GPIO_ACTIVE_HIGH>;
        status = "okay";
    };
};

sdio_pwrseq の compatible プロパティには "mmc-pwrseq-wilc" を指定します。

reset-gpiosプロパティには <&gpio 7 GPIO_ACTIVE_HIGH> を指定します。Ultra96-V2 では ATWILC3000 の RESETN ピンは ZynqMP の MIO7 に接続されています。RESETN の最後の N は Negative(Low Active) を意味するのですが、ここでは GPIO_ACTIVE_HIGH を指定しなければなりません。紛らわしいので注意してください。

powerdown-gpios プロパティには <&gpio 8 GPIO_ACTIVE_HIGH> を指定します。Ultra96-V2 では ATWILC3000 の CHIP_EN ピンは ZynqMP の MIO8 に接続されています。CHIP_EN ピンは High にすることで動作を開始し、Low にすることでパワーダウンします。そういう意味では powerdown-gpios に GPIO_ACTIVE_HIGH を指定するのは少し違和感があるのですが、Linux Driver がそうなっているので仕方がありません。

Firmware を Root File System にインストールしておく

ATWILC3000 の Linux Driver は、起動時に firmware を ATWILC3000 にロードします。firmware は以下の URL にあります。

この firmware は /lib/firmware/mchp になければなりません。Root File System を作る時にインストールしておくか、後で追加してください。ネットワークが使えないと後から追加するのにも不便なので、あらかじめインストールしておいたほうが良いでしょう。

debian10-rootfs# mkdir /lib/firmware/mchp
debian10-rootfs# git clone git://github.com/linux4wilc/firmware  linux4wilc-firmware  
debian10-rootfs# cp linux4wilc-firmware/*.bin /lib/firmware/mchp
debian10-rootfs# rm -rf linux4wilc-firmware  

苦労した点

当初は、Avnet 社のパッチを知らずに Microchip 社の提供する Linux Driver のみで動かそうとして全然動かずに難儀しました。もうあきらめて Ultra96-V2 は古いカーネルで動かしていました。そしたら ある方(この方は Yocto でシステムを構築したらしい)から meta-avnet を使って構築した Linux 5.10 では Ultra96-V2 の WiFi が動いているとのメールをいただきました。さっそく調べたところ、meta-avnet ではパッチをあてていることがわかり、このパッチをあてれば Ultra96-V2 の WiFi が動きました。

メールで教えてくださった方、パッチを提供してくれた Avnet 社、もちろん Linux Driver を提供している Microchip 社にも感謝します。

参考

3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0