I am attempting to expose the SPI #2 interface from the Intel E3900 series (specifically the E3940) as a spidev interface to CentOS 8 (kernel version 4.18). As a fallback, any method to access the SPI controller through a C/C++ API would be acceptable.
I am trying to determine if the issue is something that must be corrected by the BIOS vendor or something I can fix with an ACPI patch. The vendor (Congatec) has claimed that the SPI interface is currently not supported as a userspace entity, but I am still waiting for my issue to be escalated to their engineering group to confirm that. The vendor also stated that the BIOS setting for the SPIs should be left at "Disabled", but I have also tried the "PCI" and "ACPI" options with no change.
I have attempted to merge together snippets from several references to create an ACPI patch, including:
spidev Linux driver on Intel Atom board
https://www.kernel.org/doc/Documentation/acpi/initrd_table_override.txt
https://www.kernel.org/doc/html/latest/firmware-guide/acpi/enumeration.html
I have recompiled the CentOS 8 kernel to include all the necessary options, and I am able to successfully rebuild the Linux initrd (initramfs in CentOS 8). I confirmed through dmesg logs that my modification is being loaded at boot; I don't see any error messages in the logs, so I am assuming that it is being applied successfully.
For reference, here are the kernel options I have ensured are compiled in (=y). I plan to eventually use kernel modules in concert with the stock kernel, but for now I thought this was the easier path.
CONFIG_MFD_INTEL_LPSS
CONFIG_MFD_INTEL_LPSS_ACPI
CONFIG_MFD_INTEL_LPSS_PCI
CONFIG_X86_INTEL_LPSS
CONFIG_SERIAL_8250_LPSS
CONFIG_PWM_LPSS
CONFIG_PWM_LPSS_PCI
CONFIG_PWM_LPSS_PLATFORM
CONFIG_SPI_PXA2XX
CONFIG_SPI_SPIDEV
CONFIG_SPI_BITBANG
When I dump the unmodified ACPI device tree with the following commands, I am able to see references to three different SPI buses, which correlate with their BIOS settings. As far as I know, the Intel chip only includes two SPI buses, which makes me think this really is something that will need to be fixed in their BIOS.
acpidump >acpidump
acpixtract -a acpidump
iasl -sa *.dat
grep -i spi *.dsl
I have tried several options to patch the device tree that include both references I found and reusing the device-tree configuration from SPI#1 (which I am assuming works), but none have seemed to work. Since the examples I have found are from the E3800 series, I'm hoping that I just have some register setting or pin identifier wrong and it needs to be updated for the E3900 series.
For reference, the SPI#1 bus is used to control other components on the SOM, so I want to avoid using that for general purpose as well.
Thanks in advance for any ideas/support.
DefinitionBlock ("spidev.aml", "SSDT", 2, "INTEL ", "SpiDev", 1)
{
External (_SB_.PCI0.SPI2, DeviceObj)
Scope (\_SB.PCI0.SPI2)
{
Device (FPNT)
{
Method (_HID, 0, NotSerialized) // _HID: Hardware ID
{
Return ("FPNT_DIS")
}
Method (_STA, 0, NotSerialized) // _STA: Status
{
Return (0x0F)
}
Method (_CRS, 0, Serialized) // _CRS: Current Resource Settings
{
Name (BBUF, ResourceTemplate ()
{
SpiSerialBusV2 (0x0000, PolarityLow, FourWireMode, 0x08,
ControllerInitiated, 0x002DC6C0, ClockPolarityLow,
ClockPhaseFirst, "\\_SB.PCI0.SPI2",
0x00, ResourceConsumer, , Exclusive,
)
GpioIo (Exclusive, PullDefault, 0x0000, 0x0000, IoRestrictionOutputOnly,
"\\_SB.GPO1", 0x00, ResourceConsumer, ,
)
{ // Pin list
0x0043
}
GpioInt (Edge, ActiveHigh, ExclusiveAndWake, PullDefault, 0x0000,
"\\_SB.GPO0", 0x00, ResourceConsumer, ,
)
{ // Pin list
0x000E
}
})
Return (BBUF) /* \_SB_.PCI0.SPI2.FPNT._CRS.BBUF */
}
}
}
}
DefinitionBlock ("spidev.aml", "SSDT", 5, "INTEL", "SPIDEV", 1)
{
External (_SB_.PCI0.SPI2, DeviceObj)
Scope (\_SB.PCI0.SPI2)
{
Device (TP0) {
Name (_HID, "SPT0001")
Name (_DDN, "SPI test device connected to CS2")
Name (_DSD, Package() {
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
Package () {
Package (2) { "compatible", "spidev" },
}
})
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, // 1 MHz
ClockPolarityLow, // SPI mode 0
ClockPhaseFirst, // SPI mode 0
"\\_SB.PCI0.SPI2", // SPI host controller
0 // Must be 0
)
})
}
}
}
DefinitionBlock ("spidev.aml", "SSDT", 5, "INTEL", "SPIDEV", 1)
{
External (_SB_.PCI0.SPI2, DeviceObj)
Scope (\_SB.PCI0.SPI2)
{
Device (TP0) {
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, // 1 MHz
ClockPolarityLow, // SPI mode 0
ClockPhaseFirst, // SPI mode 0
"\\_SB.PCI0.SPI2", // SPI host controller
0 // Must be 0
)
})
}
}
}
EDIT: Added dmesg output after applying above via initrd
[ 0.000000] BRK [0x63ef9000, 0x63ef9fff] PGTABLE
[ 0.000000] BRK [0x63efa000, 0x63efafff] PGTABLE
[ 0.000000] RAMDISK: [mem 0x3b4f6000-0x3ce5cfff]
[ 0.000000] ACPI: SSDT ACPI table found in initrd [kernel/firmware/acpi/spidev.aml][0xb7]
[ 0.000000] modified physical RAM map:
[ 0.000000] modified: [mem 0x0000000000000000-0x0000000000000fff] reserved
[ 0.000000] modified: [mem 0x0000000000001000-0x000000000003efff] usable
--
[ 0.000000] ACPI: UEFI 0x00000000798C8400 000042 (v01 ALASKA A M I 00000000 00000000)
[ 0.000000] ACPI: TPM2 0x00000000798C8450 000034 (v04 ALASKA A M I 00000001 AMI 00000000)
[ 0.000000] ACPI: WDAT 0x00000000798C8490 000104 (v01 00000000 00000000)
[ 0.000000] ACPI: Table Upgrade: install [SSDT- INTEL- SPIDEV]
[ 0.000000] ACPI: SSDT 0x00000000774A2000 0000B7 (v05 INTEL SPIDEV 00000001 INTL 20180629)
[ 0.000000] ACPI: Local APIC address 0xfee00000
[ 0.000000] No NUMA configuration found
[ 0.000000] Faking a node at [mem 0x0000000000000000-0x000000017fffffff]
--
[ 1.141553] dw-apb-uart.0: ttyS4 at MMIO 0x91326000 (irq = 4, base_baud = 115200) is a 16550A
[ 1.144263] dw-apb-uart.1: ttyS5 at MMIO 0x91324000 (irq = 5, base_baud = 115200) is a 16550A
[ 1.146886] dw-apb-uart.2: ttyS6 at MMIO 0x91322000 (irq = 6, base_baud = 115200) is a 16550A
[ 1.149799] pxa2xx-spi pxa2xx-spi.4: cs2 >= max 2
[ 1.151063] spi_master spi2: failed to add SPI device SPT0001:00 from ACPI
[ 1.153366] rdac: device handler registered
[ 1.154791] hp_sw: device handler registered
[ 1.156043] emc: device handler registered
[root@localhost ~]# ls /dev/
autofs fuse log nvram tty tty25 tty42 tty6 ttyS5 vcsa1
block gpiochip0 loop-control port tty0 tty26 tty43 tty60 ttyS6 vcsa2
bus gpiochip1 mapper ppp tty1 tty27 tty44 tty61 ttyS7 vcsa3
char gpiochip2 mcelog pps0 tty10 tty28 tty45 tty62 ttyS8 vcsa4
console gpiochip3 mei0 pps1 tty11 tty29 tty46 tty63 ttyS9 vcsa5
core hidraw0 mem ptmx tty12 tty3 tty47 tty7 uhid vcsa6
cpu hpet memory_bandwidth ptp0 tty13 tty30 tty48 tty8 uinput vfio
cpu_dma_latency hugepages mmcblk1 ptp1 tty14 tty31 tty49 tty9 urandom vga_arbiter
cs hwrng mmcblk1boot0 pts tty15 tty32 tty5 ttyS0 usbmon0 vhci
cuse i2c-0 mmcblk1boot1 random tty16 tty33 tty50 ttyS1 usbmon1 vhost-net
disk i2c-1 mmcblk1p1 raw tty17 tty34 tty51 ttyS10 usbmon2 vhost-vsock
dm-0 i2c-2 mmcblk1p2 rtc tty18 tty35 tty52 ttyS11 vcs zero
dm-1 i2c-3 mmcblk1p3 rtc0 tty19 tty36 tty53 ttyS12 vcs1
dri i2c-4 mmcblk1rpmb shm tty2 tty37 tty54 ttyS13 vcs2
drm_dp_aux0 i2c-5 mqueue snapshot tty20 tty38 tty55 ttyS14 vcs3
drm_dp_aux1 initctl net snd tty21 tty39 tty56 ttyS15 vcs4
fb0 input network_latency stderr tty22 tty4 tty57 ttyS2 vcs5
fd kmsg network_throughput stdin tty23 tty40 tty58 ttyS3 vcs6
full kvm null stdout tty24 tty41 tty59 ttyS4 vcsa
EDIT: Added requested tables.dat output https://pastebin.com/TBj8LRVc
EDIT: Added requested status output
[root@localhost ~]# grep -H 15 /sys/bus/acpi/devices/*/status
/sys/bus/acpi/devices/device:19/status:15
/sys/bus/acpi/devices/device:1a/status:15
/sys/bus/acpi/devices/device:1d/status:15
/sys/bus/acpi/devices/device:3e/status:15
/sys/bus/acpi/devices/device:44/status:15
/sys/bus/acpi/devices/device:45/status:15
/sys/bus/acpi/devices/INT33A1:00/status:15
/sys/bus/acpi/devices/INT3452:00/status:15
/sys/bus/acpi/devices/INT3452:01/status:15
/sys/bus/acpi/devices/INT3452:02/status:15
/sys/bus/acpi/devices/INT3452:03/status:15
/sys/bus/acpi/devices/INT3511:00/status:15
/sys/bus/acpi/devices/INT3512:00/status:15
/sys/bus/acpi/devices/LNXPOWER:00/status:15
/sys/bus/acpi/devices/MSFT0101:00/status:15
/sys/bus/acpi/devices/PNP0103:00/status:15
/sys/bus/acpi/devices/PNP0C0D:00/status:15
/sys/bus/acpi/devices/PNP0C0E:00/status:15
EDIT: Added requested lspci output
[root@localhost ~]# lspci -nk -s 19
00:19.0 1180: 8086:5ac2 (rev 0b)
Subsystem: 8086:7270
Kernel driver in use: intel-lpss
00:19.1 1180: 8086:5ac4 (rev 0b)
Subsystem: 8086:7270
Kernel driver in use: intel-lpss
00:19.2 1180: 8086:5ac6 (rev 0b)
Subsystem: 8086:7270
Kernel driver in use: intel-lpss