Sona TI351/TI AM62A EVK Integration Guide

This tutorial shows how to integrate the Sona TI351 module on the TI AM62A-LP EVK (SK-AM62A-LP). The Sona Ti351 uses SDIO for the Wi-Fi interface and UART for the Bluetooth interface. It is assumed the user is familiar with Linux and embedded systems. Included in this tutorial are the physical setup, Yocto setup and build, and verifying the Wi-Fi and Bluetooth are functional.

Requirements

Required items:

Physical setup

i.MX 8M Plus (imx8mp)

The Sona TI351 is plugged into the M.2 slot on the AM62A. For this guide, the image is flashed to a microSD card and the AM62A is booted from it. Please refer to the pictures below reference:

Sona TI351 Plugged into the M.2 Slot:
Image

microSD card attached to AM62A-EVK:
Image

Configure the DIP switched to boot from the microSD card:
Image

Yocto setup and build

Create your project folders

mkdir -p ~/Yocto/TI/AM62A/TI351/ReleaseCandidate
cd ~/Yocto/TI/AM62A/TI351/ReleaseCandidate

Download the Yocto release and setup the build environment

git clone -b scarthgap https://git.yoctoproject.org/poky
cd poky
. oe-init-build-env am62a-ti351-rc

Note: This guide uses the scarthgap release which was the latest yocto release at the time of writing. Please check https://git.yoctoproject.org/poky for the latest release version or the version you prefer to use.

Download the required meta-layers

This is minimum list of meta-layers required for the build. The branch of these layers must match the branch of poky that you are using. Please add any other layers that are needed for your project.

Create sources directory

cd ~/Yocto/TI/AM62A/TI351/ReleaseCandidate/poky
mkdir sources
cd sources

meta-ti

git clone -b scarthgap git://git.yoctoproject.org/meta-ti

meta-arm

git clone -b scarthgap git://git.yoctoproject.org/meta-arm

meta-openembedded

git clone -b scarthgap git://git.openembedded.org/meta-openembedded

meta-summit-radio

git clone -b lrd-12.103.0.x https://github.com/LairdCP/meta-summit-radio

Note: This is the code for the Sona TI351.As of this writing, the latest version is lrd-12.103.0.x. It is recommended that you use the latest version. Please check https://github.com/LairdCP/meta-summit-radio for the latest release.

Edit the bblayers.conf file

Edit your bblayers.conf file.

cd ~/Yocto/TI/AM62A/TI351/ReleaseCandidate/poky/am62a-ti351-rc/conf
vi bblayers.conf

Add the following to the BBLAYERS ?= sectoin of the file.

BBLAYERS ?= " \
  /home/monroe2112/Massive/Yocto/TI/AM62/TI351/ReleaseCandidate/poky/meta \
  /home/monroe2112/Massive/Yocto/TI/AM62/TI351/ReleaseCandidate/poky/meta-poky \
  /home/monroe2112/Massive/Yocto/TI/AM62/TI351/ReleaseCandidate/poky/meta-yocto-bsp \
  \	
  /home/monroe2112/Massive/Yocto/TI/AM62/TI351/ReleaseCandidate/poky/sources/meta-ti/meta-ti-bsp \
  /home/monroe2112/Massive/Yocto/TI/AM62/TI351/ReleaseCandidate/poky/sources/meta-ti/meta-ti-extras \
  \
  /home/monroe2112/Massive/Yocto/TI/AM62/TI351/ReleaseCandidate/poky/sources/meta-arm/meta-arm \
  /home/monroe2112/Massive/Yocto/TI/AM62/TI351/ReleaseCandidate/poky/sources/meta-arm/meta-arm-toolchain \
  \
  /home/monroe2112/Massive/Yocto/TI/AM62/TI351/ReleaseCandidate/poky/sources/meta-openembedded/meta-oe \
  /home/monroe2112/Massive/Yocto/TI/AM62/TI351/ReleaseCandidate/poky/sources/meta-openembedded/meta-multimedia \
  /home/monroe2112/Massive/Yocto/TI/AM62/TI351/ReleaseCandidate/poky/sources/meta-openembedded/meta-python \
  /home/monroe2112/Massive/Yocto/TI/AM62/TI351/ReleaseCandidate/poky/sources/meta-openembedded/meta-gnome \
  /home/monroe2112/Massive/Yocto/TI/AM62/TI351/ReleaseCandidate/poky/sources/meta-openembedded/meta-networking \
  /home/monroe2112/Massive/Yocto/TI/AM62/TI351/ReleaseCandidate/poky/sources/meta-openembedded/meta-filesystems \
  /home/monroe2112/Massive/Yocto/TI/AM62/TI351/ReleaseCandidate/poky/sources/meta-summit-radio/meta-summit-radio \
  "

Edit the local.conf file

Edit your local.conf file and add the following to the bottom.

vi local.conf 

Change the to am62axx-evm

MACHINE ??= "am62axx-evm" 
MACHINE_FEATURES:remove = "nxp8987 nxp8997 iw612"
MACHINE_FIRMWARE:remove = "linux-firmware-ath10k"
PREFERRED_PROVIDER_wpa-supplicant = "summit-supplicant-ti"
PREFERRED_PROVIDER_wpa-supplicant-cli = "summit-supplicant-ti"
PREFERRED_PROVIDER_wpa-supplicant-passphrase = "summit-supplicant-ti"
PREFERRED_RPROVIDER_wireless-regdb-static = "wireless-regdb"

Copy sample image recipe and edit it

Copy a sample image recipe and rename the recipe to something memorable. Here I’ve used the image keyword, the EVK processor and the radio. This gives a nice understanding of what Wi-Fi module is used and what EVK the image is for.

cd ~/Yocto/TI/AM62A/TI351/ReleaseCandidate/poky/sources/meta-summit-radio/meta-summit-radio/recipes-packages/images

#copy the bitbake recipe example
cp sample-image-lwb5plus.bb image-am62a-ti351.bb

Edit the recipe that you just created and confirm that the IMAGE_INSTALL section looks like below:

vi image-am62a-ti351.bb
IMAGE_INSTALL += "\
	iproute2 \
	rng-tools \
	ca-certificates \
	tzdata \
	ethtool \
	iw \
	kernel-module-ti-backports \
	ti351-firmware \
	summit-supplicant-ti \
	summit-networkmanager-ti \
	vim \
	libedit \
	packagegroup-tools-bluetooth \
	"

Configure the kernel

Run the following command to launch the kernel menuconfig.

bitbake -c menuconfig virtual/kernel

Backports will replace the wireless and Bluetooth stack. The CONFIG_FW_LOADER_USER_HELPER_FALLBACK needs removed to allow for faster loading of the firmware at boot. Make the following modifications:

In the menuconfig use / to search for each of the below configuration parameters in caps.

WLAN
- deselect Device Drivers -> Network device support -> Wireless LAN

CONFIG_FW_LOADER_USER_HELPER_FALLBACK
- deselect Device Drivers -> Generic Driver Options -> Firmware Loader 
    -> Firmware loading Facility ->Force the firmware sysfs fallback mechanism when possible

CONFIG_BT
- deselect Networking support -> Bluetooth subsystem support

CFG80211
- set to module (M) Networking support -> Wireless -> cfg80211 - wireless configuration API

Save your changes and exit menuconfig.

Patch devicetree

There is a patch that needs to be added to your devicetree to allow the Sona-TI351 to be seen in the m.2 slot. The patch can be found here:

For reference, this is the contents of the patch file

diff --git a/arch/arm64/boot/dts/ti/k3-am62a7-sk.dts b/arch/arm64/boot/dts/ti/k3-am62a7-sk.dts
index 0b101d989..58a1d820a 100644
--- a/arch/arm64/boot/dts/ti/k3-am62a7-sk.dts
+++ b/arch/arm64/boot/dts/ti/k3-am62a7-sk.dts
@@ -194,6 +194,29 @@ vddshv_sdio: regulator-5 {
 			 <3300000 0x1>;
 	};
 
+	wlan_lten: regulator-6 {
+		compatible = "regulator-fixed";
+		regulator-name = "wlan_lten";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		vin-supply = <&vcc_3v3_sys>;
+		gpios = <&exp2 23 GPIO_ACTIVE_HIGH>;
+		enable-active-high;
+	};
+
+	wlan_en: regulator-7 {
+		compatible = "regulator-fixed";
+		regulator-name = "wlan_en";
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		vin-supply = <&wlan_lten>;
+		enable-active-high;
+		gpios = <&main_gpio0 71 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&wlan_en_pins_default>;
+	};
+
+
 	leds {
 		compatible = "gpio-leds";
 		pinctrl-names = "default";
@@ -348,6 +371,12 @@ AM62AX_IOPAD(0x01d4, PIN_INPUT, 7) /* (C15) UART0_RTSn.GPIO1_23 */
 		>;
 	};
 
+	wlan_en_pins_default: wlan-en-pins-default {
+		pinctrl-single,pins = <
+			AM62AX_IOPAD(0x124, PIN_OUTPUT, 7) /* (F22) MMC2_SDCD.GPIO0_71 */
+		>;
+	};
+
 	main_dss0_pins_default: main-dss0-pins-default {
 		pinctrl-single,pins = <
 			AM62AX_IOPAD(0x100, PIN_OUTPUT, 0) /* (V17) VOUT0_VSYNC */
@@ -397,6 +426,24 @@ AM62AX_IOPAD(0x1f8, PIN_INPUT_PULLUP, 0) /* (AC2) MMC0_DAT7 */
 		>;
 	};
 
+	main_mmc2_pins_default: main-mmc2-pins-default {
+		pinctrl-single,pins = <
+			AM62AX_IOPAD(0x120, PIN_INPUT, 0) /* (G22) MMC2_CMD */
+			AM62AX_IOPAD(0x118, PIN_INPUT, 0) /* (H22) MMC2_CLK */
+			AM62AX_IOPAD(0x114, PIN_INPUT, 0) /* (E20) MMC2_DAT0 */
+			AM62AX_IOPAD(0x110, PIN_INPUT, 0) /* (F21) MMC2_DAT1 */
+			AM62AX_IOPAD(0x10c, PIN_INPUT, 0) /* (F20) MMC2_DAT2 */
+			AM62AX_IOPAD(0x108, PIN_INPUT, 0) /* (G21) MMC2_DAT3 */
+			AM62AX_IOPAD(0x11c, PIN_INPUT, 0) /* (#N/A) MMC2_CLKB */
+		>;
+	};
+
+	main_wlirq_pins_default: main-wlirq-pins-default {
+		pinctrl-single,pins = <
+			AM62AX_IOPAD(0x128, PIN_INPUT, 7) /* (E21) MMC2_SDWP.GPIO0_72 */
+		>;
+	};
+
 	vddshv_sdio_pins_default: vddshv-sdio-pins-default {
 		pinctrl-single,pins = <
 			AM62AX_IOPAD(0x07c, PIN_OUTPUT, 7) /* (M19) GPMC0_CLK.GPIO0_31 */
@@ -659,6 +706,33 @@ &sdhci1 {
 	disable-wp;
 };
 
+&sdhci2 {
+	status = "okay";
+	vmmc-supply = <&wlan_en>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_mmc2_pins_default>;
+	bus-width = <4>;
+	non-removable;
+	ti,fails-without-test-cd;
+	cap-power-off-card;
+	keep-power-in-suspend;
+	ti,driver-strength-ohm = <50>;
+	/*
+	assigned-clocks = <&k3_clks 157 158>;
+	assigned-clock-parents = <&k3_clks 157 160>;
+	*/
+	#address-cells = <1>;
+	#size-cells = <0>;
+	wlcore: wlcore@2 {
+		compatible = "ti,cc33xx";
+		reg = <2>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&main_wlirq_pins_default>;
+		interrupt-parent = <&main_gpio0>;
+		interrupts = <72 IRQ_TYPE_EDGE_FALLING>;
+	};
+};
+
 &main_gpio0 {
 	status = "okay";
 };

Build image

Depending on the CPU, hard drive, and internet connection this can take a while to run. We recommend running the build overnight if a slower PC is used.

bitbake image-am62a-ti351

When the build is finished it will create an image that can be flashed to an SD card.

cd ~/Yocto/TI/AM62/TI351/ReleaseCandidate/poky/am62a-ti351-rc/deploy-ti/images/am62axx-evm
ls -lah *.wic.xz

Note: Make sure to use the actual file and not the linked file. It should be the one with the timestamp in the filename.

Flashing to an SD Card

Flash the image into SD card. Note: for this particular tutorial the SD card is on /dev/mmcblk0. It may be different for your setup; so make sure you change the command below per your setup.

It is recommend to use either dd from the Linux prompt or to use balenaEtcher to flash the image. The is an example using balenaEtcher.

Image