4.5 General Purpose IOs

The ATWILC device driver uses 3 GPIOs connected to CHIP_EN, RESET and IRQn. To port the driver to a new host, it is recommended that the corresponding GPIO numbers be updated.

The driver reads the corresponding GPIO numbers from the device tree file. If the GPIOs were not found in the device tree file, the driver uses the static definition of the GPIO numbers defined in wlan.h

Use the following function to read the corresponding GPIO numbers from the device tree file:

	int wilc_of_parse_power_pins(struct wilc *wilc)
{
	static const struct wilc_power_gpios default_gpios[] = {
		{ .reset = GPIO_NUM_RESET,	.chip_en = GPIO_NUM_CHIP_EN, },
	};
	struct device_node *of = wilc->dt_dev->of_node;
	struct wilc_power *power = &wilc->power;
	const struct wilc_power_gpios *gpios = &default_gpios[0];
	int ret;

	power->gpios.reset = of_get_named_gpio_flags(of, "reset-gpios", 0,
						     NULL);
	if (!gpio_is_valid(power->gpios.reset))
		power->gpios.reset = gpios->reset;

	power->gpios.chip_en = of_get_named_gpio_flags(of, "chip_en-gpios", 0,
						       NULL);
	if (!gpio_is_valid(power->gpios.chip_en))
		power->gpios.chip_en = gpios->chip_en;

	if (!gpio_is_valid(power->gpios.chip_en) ||
			!gpio_is_valid(power->gpios.reset))
		return -EINVAL;

	ret = devm_gpio_request(wilc->dev, power->gpios.chip_en, "CHIP_EN");
	if (ret)
		return ret;

	ret = devm_gpio_request(wilc->dev, power->gpios.reset, "RESET");
	return ret;
}

A device tree overlay is used at runtime (by the bootloader in this case) to dynamically modify the device tree, by adding nodes to the tree and making changes to properties in the existing tree. The WILC SDIO DT-Overlay file is present in the dt-overlay-at91 repo.

sama5d4_xplained/sama5d4_xplained_wilc_sdio.dtso file

&mmc1 {
 	#address-cells = <1>;
 	#size-cells = <0>;
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_mmc1_clk_cmd_dat0 &pinctrl_mmc1_dat1_3>;
 	mmc-pwrseq = <&wifi_pwrseq>;
 	non-removable;
 	bus-width = <4>;
 	status = "okay";
 	wifi: slot@0 {
		compatible = "microchip,wilc1000", "microchip,wilc3000", "atmel,wilc_sdio";
		reset-gpios = <&pioB 28 GPIO_ACTIVE_HIGH>;
		chip_en-gpios = <&pioC 30 GPIO_ACTIVE_HIGH>;
		interrupt-parent = <&pioC>;
		interrupts = <27 0>;
		reg = <0>;
		bus-width = <4>;
		status = "okay";
	 };
};

sama5d4_xplained/sama5d4_xplained_wilc_spi.dtso file

&spi1 {
	#address-cells = <1>;
	#size-cells = <0>;
	status = "okay";

	wilc_spi: wilc_spi@0 {
		compatible = "microchip,wilc1000", "microchip,wilc3000";
		spi-max-frequency = <48000000>;
		reg = <0>;
		interrupt-parent = <&pioC>;
		interrupts = <27 0>;
		reset-gpios = <&pioB 28 0>;
		chip_en-gpios = <&pioC 30 0>;
		status = "okay";
	};
};

The following example shows the change required for SPI and SDIO in DT-overlays.

DT-Overlay file for SPI:

github.com/linux4sam/dt-overlay-at91/blob/master/sama5d4_xplained/sama5d4_xplained_wilc_spi.dtso

DT-Overlay files for SDIO:

github.com/linux4sam/dt-overlay-at91/blob/master/sama5d4_xplained/sama5d4_xplained_wilc_sdio.dtso

mmc1: mmc@fc000000 {
		pinctrl-names = "default";
		pinctrl-0 = <&pinctrl_mmc1_clk_cmd_dat0 &pinctrl_mmc1_dat1_3>;
		non-removable;
		vmmc-supply = <&vcc_mmc1_reg>;
		vqmmc-supply = <&vcc_3v3_reg>;
		status = "okay";
		wilc_sdio@0{
			compatible = "microchip,wilc1000", "microchip,wilc3000", "atmel,wilc_sdio";
			reset-gpios = <&pioB 28 0>;
			chip_en-gpios = <&pioC 30 0>;
			irq-gpios = <&pioC 27 0>;
			status = "okay";
			reg = <0>;
			bus-width = <4>;
		};
	};
	
	spi1: spi@fc018000 {
		cs-gpios = <&pioB 21 0>;
		status = "okay";
		wilc_spi@0 {
			compatible = "microchip,wilc1000", "microchip,wilc3000";
			reg = <0>;
			reset-gpios = <&pioB 28 0>;
			chip_en-gpios = <&pioC 30 0>;
			irq-gpios = <&pioC 27 0>;
			status = "okay";
		};
	};