4

I want to use a GPIO pin as a new chip select for SPI on an Up Squared board. The Up squared uses an Intel Pentium N4200, so it's a x86 machine. I have managed to this on a Raspberry Pi by using Device Tree Overlays but as this is an x86 machine I may have to use ACPI overlays.

The Up squared has two spi available and they propose here to use ACPI overlays, this repo, which actually works very well. Below one of the asl files they use

/*
 * This ASL can be used to declare a spidev device on SPI0 CS0
 */
DefinitionBlock ("", "SSDT", 5, "INTEL", "SPIDEV0", 1)
{
    External (_SB_.PCI0.SPI1, DeviceObj)

    Scope (\_SB.PCI0.SPI1)
    {
        Device (TP0) {
            Name (_HID, "SPT0001")
            Name (_DDN, "SPI test device connected to CS0")
            Name (_CRS, ResourceTemplate () {
                SpiSerialBus (
                    0,                      // Chip select
                    PolarityLow,            // Chip select is active low
                    FourWireMode,           // Full duplex
                    8,                      // Bits per word is 8 (byte)
                    ControllerInitiated,    // Don't care
                    1000000,                // 10 MHz
                    ClockPolarityLow,       // SPI mode 0
                    ClockPhaseFirst,        // SPI mode 0
                    "\\_SB.PCI0.SPI1",      // SPI host controller
                    0                       // Must be 0
                )
            })
        }
    }
}

I compiled this file using

$ sudo iasl spidev1.0.asl > /dev/null
$ sudo mv spidev1.0.asl /lib/firmware/acpi-upgrades
$ sudo update-initramfs -u -k all

Then I reboot an I can see a device and communicate through it.

up@up:~$ ls /dev/spi*
/dev/spidev1.0

Thus, I decided to write my own overlay based on themeta-acpi samples from intel and I wrote this:

/*
 * This ASL can be used to declare a spidev device on SPI0 CS2
 */
DefinitionBlock ("", "SSDT", 5, "INTEL", "SPIDEV2", 1)
{
    External (_SB_.PCI0.SPI1, DeviceObj)
    External (_SB_.PCI0.GIP0.GPO, DeviceObj)

    Scope (\_SB.PCI0.SPI1)
    {

        Name (_CRS, ResourceTemplate () {
            GpioIo (Exclusive, PullUp, 0, 0, IoRestrictionOutputOnly,
                "\\_SB.PCI0.GIP0.GPO", 0) {
                    22 // pin 22 is BCM25 or 402 in linux
                } 
        })

        Name (_DSD, Package() {
            ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
            Package () {
                Package () { "compatible", "spidev" }, // not sure if this is needed
                Package () {
                    "cs-gpios", Package () {
                        0,
                        0,
                        ^SPI1, 0, 0, 0, // index 0 in _CRS -> pin 22
                    }
                },
            }
        })

        Device (TP2) {
            Name (_HID, "SPT0001")
            Name (_DDN, "SPI test device connected to CS2")
            Name (_CRS, ResourceTemplate () {
                SpiSerialBus (
                    2,                      // Chip select
                    PolarityLow,            // Chip select is active low
                    FourWireMode,           // Full duplex
                    8,                      // Bits per word is 8 (byte)
                    ControllerInitiated,    // Don't care
                    1000000,                // 10 MHz
                    ClockPolarityLow,       // SPI mode 0
                    ClockPhaseFirst,        // SPI mode 0
                    "\\_SB.PCI0.SPI1",      // SPI host controller
                    0                       // Must be 0
                )
            })
        }
    }
}

But I cannot see the new device. What am I missing?

Edit: I have modified the code with a code which actually worked. I can see now a device on /dev/spidev1.2.

However, the CS on pin 22 is low all the time which shouldn't be the case. is the number of the pin correct? I'm using pin numbering from here

Edit 2:

Here is the output of my kernel version

Linux up 5.4.65-rt38+ #1 SMP PREEMPT_RT Mon Feb 28 13:42:31 CET 2022 x86_64 x86_64 x86_64 GNU/Linux

I compiled this up linux repository with the RT patch for the right kernel version.

I also installed the upboard-extras package and I'm actually able to communicate through spi for devices /dev/spidev1.0 and /dev/spidev1.1. So I think I have configured the up squared correctly.

There is nongpio file under /sys/class/gpio

up@up:~/aru$ ls /sys/class/gpio
export  gpiochip0  gpiochip267  gpiochip310  gpiochip357  gpiochip434  unexport

I can set the GPIO to 1 or 0 and I can see the output on a multimeter, so I think I have right permissions for GPIO.

Edit 3:

Please find in this link the .dat result from acpidump -o up2-tables.dat

afvmil
  • 362
  • 3
  • 11
  • See my comments to the answer below. – 0andriy Apr 16 '22 at 21:43
  • @0andriy thanks, I have added the results of `acpidump` to the question under **Edit 3** – afvmil Apr 21 '22 at 13:28
  • Where did you get `"\\_SB.PCI0.GIP0.GPO"` part from? – 0andriy May 19 '22 at 20:32
  • Second issue is `22`. It is not the proper number of the pin. You need to find a mapping based on the schematics. – 0andriy May 19 '22 at 20:40
  • So, I believe you have to use NorthWest GPIO, which is `"\\_SB.GPO1"` with pin 45 (AKA `"AVS_I2S2_BCLK"` in the pinctrl-broxton.c driver). – 0andriy May 19 '22 at 20:56
  • Thanks @0andriy but where did you find this pin 45 ? here's the pinout for up2 (https://github.com/up-board/up-community/wiki/Pinout_UP2) and there's no pin 45. – afvmil Jun 10 '22 at 15:17
  • Does it work? If not, there is no point to tell how I deduced that, since it might be that I missed something. – 0andriy Jun 10 '22 at 22:05
  • Meanwhile you may read this: https://stackoverflow.com/a/55579640 – 0andriy Jun 10 '22 at 22:10

1 Answers1

0

I assume that you are using this board. To be able to use I/O pins(i2c, spi etc.), you need to enable them firstly. Easy way to check you already enabled them or not is that typing in terminal:

uname -a

Output of this will be look like:

 Linux upxtreme-UP-WHL01 5.4.0-1-generic #2~upboard2-Ubuntu SMP Thu Jul 25 13:35:27 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux

In here #2~upboard2-Ubuntu part can be changed accordingto your board type. However if you don't see a similar result, then you didn't configure your board yet. Otherway to check it, go to folder: /sys/class/gpio and check the ngpio file. Inside it, there should be written 28.

To use any I/O pins(i2c, spi etc.), you don't need to change anything on BIOS side, because its coming to you defaultly enabled.

Please check the up-wiki page, and update your board kernel after linux installation. Then your I/O configurations will be enabled. Up-wiki main page.

Yunus Temurlenk
  • 4,085
  • 4
  • 18
  • 39
  • 1
    I modified the post, I can see the GPIOs and I can actually control them. – afvmil Apr 13 '22 at 14:24
  • Thats great, then you should be able to control spi pins also. – Yunus Temurlenk Apr 14 '22 at 05:14
  • I'm already able to control the two spi coming by default on up squared, however I would like to have 8 Chip selects by using other GPIO. I did it on Raspberry pi with Device Tree Overlays but in intel it is done through ACPI which I still cannot manage to make work. – afvmil Apr 14 '22 at 07:17
  • Ahh, you are wrong in there. you can not increase the spi pin numbers because its designed in that way. – Yunus Temurlenk Apr 14 '22 at 07:28
  • @YunusTemurlenk, it's not true, this is pure software issue, not even ACPI – 0andriy Apr 16 '22 at 10:57
  • @0andriy If you check the target [datasheet](https://up-board.org/wp-content/uploads/2021/06/UP-Squared-Datasheet-v2.pdf), you will see spi, i2c pins are reserved with limited number. You cant directly control the pins and decide their functionality. Because they are designed in that way. – Yunus Temurlenk Apr 16 '22 at 20:08
  • @YunusTemurlenk, I didn’t get how that is related to the issue. The chip select signal can be provided by **any** available GPIO line, there is neither ACPI nor hardware limitations. The issue is in Linux kernel that does not allow to use overridden CS in SPI *perpheral* device node description. – 0andriy Apr 16 '22 at 21:33
  • Actually even not that, the SPI node is defined in the original DSDT and adding the list of chip selects won’t work in overlay, because of possible issues a) actual host controller driver is loaded early enough (before the SSDT overlay), b) the original SPI Device node in SSDT already has _CRS method, it may not be overridden (this is an ACPI limitation). So, a) can be fixed by moving overlay to initramfs, while b) requires full DSDT upgrade. – 0andriy Apr 16 '22 at 21:43
  • Thanks @0andriy, I am very new on ACPI overlays. Right now I'm using them to enable the two default SPI of the board (enable meaning make them visible under `/dev/`), so can I assume they are loaded before host controller? To do that I move the generated `.aml` code to `/lib/firmware/acpi-upgrades` and then I `sudo update-initramfs`, should I move it somewhere else? – afvmil Apr 19 '22 at 14:15