// SPDX-License-Identifier: GPL-2.0-only /* * PiFace Digital, Device Tree Overlay. * Copyright (C) 2020 Thomas Preston * * 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"; }; };