// SPDX-License-Identifier: GPL-2.0-only
/*
 * PiFace Digital, Device Tree Overlay.
 * Copyright (C) 2020 Thomas Preston <thomas.preston@codethink.co.uk>
 *
 * The PiFace Digital is a convenient breakout board for the Microchip mcp23s17
 * SPI GPIO port expander.
 *
 * The first eight GPIOs 0..7 (bank A) are connected to eight output terminals
 * and LEDs, plus two relays on the first two outputs. These output loads are
 * active-high.
 *
 * The next eight GPIOs 8..15 (bank B) are connected to eight input terminals
 * with four on-board switches connecting them to ground. Inputs devices are
 * therefore expected to bridge terminals to ground, so the mcp23s17 pullups are
 * activated for GPIO bank B.
 *
 * On PiFace Digital, the mcp23s17 is connected to the Raspberry Pi's SPI0 CS0
 * bus. Each SPI bus supports up to eight addressable child devices. The PiFace
 * Digital only supports addresses 0-4, which can be configured by jumpers JP1
 * and JP2.
 *
 * You can tell the driver about these jumper configurations with the
 * spi-present-mask bitmask:
 *
 *     | JP1 | JP2 | dtoverlay line in /boot/config.txt         |
 *     | --- | --- | ------------------------------------------ |
 *     |  0  |  0  | dtoverlay=pifacedigital                    |
 *     |  0  |  0  | dtoverlay=pifacedigital:spi-present-mask=1 |
 *     |  0  |  1  | dtoverlay=pifacedigital:spi-present-mask=2 |
 *     |  1  |  0  | dtoverlay=pifacedigital:spi-present-mask=4 |
 *     |  1  |  1  | dtoverlay=pifacedigital:spi-present-mask=8 |
 *
 * # Example
 * Set the dtoverlay config in /boot/config.txt and power off the Raspberry Pi:
 *
 *     $ grep pifacedigital /boot/config.txt
 *     dtoverlay=pifacedigital
 *     $ sudo systemctl poweroff
 *
 * Attach the PiFace Digital and power on the Raspberry Pi.
 * Then use the libgpiod tools to query the device:
 *
 *     $ sudo apt install gpiod
 *     $ gpiodetect | grep mcp23s17
 *     gpiochip2 [mcp23s17.0] (16 lines)
 *
 * Set GPIO outputs 0, 2 and 5:
 *
 *     $ gpioset gpiochip2 0=1 2=1 5=1
 *
 * Get GPIO status (input GPIO 8..15 are high, because they are active-low):
 *
 *     $ gpioget gpiochip2 {8..15}
 *     1 1 1 1 1 1 1 1
 *
 * And even monitor interrupts:
 *
 *     $ gpiomon gpiochip2 {8..15}
 *     event: FALLING EDGE offset: 11 timestamp: [1597361662.926741667]
 *     event:  RISING EDGE offset: 11 timestamp: [1597361663.062555051]
 *
 */

/dts-v1/;
/plugin/;

/ {
	compatible = "brcm,bcm2835";

	/* Disable exposing /dev/spidev0.0 */
	fragment@0 {
		target = <&spidev0>;
		__overlay__ {
			status = "disabled";
		};
	};

	/* Add the PiFace Digital device node to the spi0.0 device. */
	fragment@1 {
		target = <&spi0>;
		__overlay__ {
			status = "okay";
			#address-cells = <1>;
			#size-cells = <0>;

			pfdigital: pifacedigital@0 {
				compatible = "microchip,mcp23s17";
				reg = <0>;

				/* Set devices present with 8-bit mask. */
				microchip,spi-present-mask = <0x01>;
				spi-max-frequency = <500000>;

				gpio-controller;
				#gpio-cells = <2>;

				/* This device can pass through interrupts. */
				interrupt-controller;
				#interrupt-cells = <2>;

				/* INTB is connected to GPIO 25.
				 * 0x8 active-low level-sensitive
				 */
				interrupts = <25 0x8>;
				interrupt-parent = <&gpio>;

				/* Configure pull-ups on bank B GPIOs */
				pinctrl-0 = <&pfdigital_irq &pfdigital_pullups>;
				pinctrl-names = "default";
				pfdigital_pullups: pinmux {
					pins =
						"gpio8",
						"gpio9",
						"gpio10",
						"gpio11",
						"gpio12",
						"gpio13",
						"gpio14",
						"gpio15";
					bias-pull-up;
				};
			};
		};
	};

	/* PiFace Digital mcp23s17 INTB pin is connected to GPIO 25. The INTB
	 * pin is configured active-low (0 on interrupt), so expect to see
	 * FALLING_EDGE when inputs are bridged to ground (switch is pressed).
	 */
	fragment@3 {
		target = <&gpio>;
		__overlay__ {
			pfdigital_irq: pifacedigital_irq {
				brcm,pins = <25>;
				brcm,function = <0>; /* input */
			};
		};
	};

	__overrides__ {
		spi-present-mask = <&pfdigital>, "microchip,spi-present-mask:0";
	};
};
