I am trying to get the GPIO pins on my mainboard working but I don't know the numbers/descriptions of the pins and if a driver is loaded or not.
I found this guide where it says that I should echo the pin description and redirect the output into /sys/class/gpio/export
/sys/class/gpio # echo 0 > export
So I did. The /sys/class/gpio/ folder exists on my system and it contains the following:
[user@host ~]$ ls -l /sys/class/gpio/
total 0
--w------- 1 root root 4096 Nov 30 18:12 export
--w------- 1 root root 4096 Nov 30 18:12 unexport
[user@host ~]$
(By the way if I see this folder does it mean a driver is loaded?)
Then I tried several pin names from the datasheet of my mainboard but I always get the following
[root@host gpio]# echo 31 > export
echo: write error: Invalid argument
[root@host gpio]#
I am using Arch Linux and my kernel version is 4.19.2-arch1-1-ARCH.
The Mainboard I use is a Supermicro X10SBA. https://www.supermicro.com/products/motherboard/celeron/x10/x10sba.cfm
The only thing I can find about GPIOs on the Motherboard is on Page 2-25 in the X10SBA Mainboard Datasheet :
1 +3.3V
2 SOC_P3V3_GPIO_S5_31
3 SOC_P3V3_GPIO_S5_32
4 SOC_P3V3_GPIO_S5_33
5 SOC_P3V3_GPIO_S5_34
6 SOC_P3V3_GPIO_S5_35
7 SOC_P3V3_GPIO_S5_36
8 SOC_P3V3_GPIO_S5_37
9 SOC_P3V3_GPIO_S5_38
10 GND
From my understanding it means the board has eight GPIOs.
So I tried to echo various different combinations into /sys/class/gpio/export like
echo SOC_P3V3_GPIO_S5_31 > export
echo 111 > export
echo 531 > export
echo S531 > export
echo S5_31 > export
...
And so on. Nothing worked.
Am I doing something fundamentally wrong here? Where are the definitions of these GPIO names? Where does export get its information from? Do I have to make these definitions myself first? Maybe do I have to recompile my kernel?
I went on and tried to find out which chip is used for the GPIO headers.
Next to the GPIO Pin headers (JP1) on the board, there is a Chip NXP GTL2010 (Datasheet) and the pins are connected to it from D1 through to D8. I guess this chip is just doing some voltage translation to make the output 3.3V or 5V. So the signal must be coming from The S1-S8 pins. Unfortunately I could not find where these source pins of the GTL2010 are connected to as the traces lead to vias on the board.
But I assume the pins go directly to the CPU. I'm not 100% sure on that. But its my assumption.
The CPU on board is an Intel Celeron J1900. But unfortunately I couln't find a datasheet or any information about it if it has GPIOs.
Is there some possibility to list the GPIOs on board in Linux? How can I check if there is already some GPIO driver used on my system?
Edit
After some research in the CPU datasheet I found that the GPIO_BASE_ADDRESS register (datasheet p. 1219) needs to be set in order to change GPIO settings. The register expects the base address in the I/O space where the GPIO logic is located. Now I don‘t understand which address I should put here. Can this be any 256 free bytes in the I/O space?
Besides that I don’t understand how to access the GPIO_BASE_ADDRESS register. The datasheet states that the register is in the PCI Configuration Space. Bus 0, Device 31 (hex 1f), Function 0. (Datasheet page 56)
Now lspci gives me the following output for device 31:
[user@host ~]$ sudo lspci -vvvvvv
...
00:1f.0 ISA bridge: Intel Corporation Atom Processor Z36xxx/Z37xxx Series Power Control Unit (rev 0e)
Subsystem: Super Micro Computer Inc Atom Processor Z36xxx/Z37xxx Series Power Control Unit
Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx-
Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
Latency: 0
Capabilities: [e0] Vendor Specific Information: Len=0c <?>
Kernel driver in use: lpc_ich
Kernel modules: lpc_ich
00:1f.3 SMBus: Intel Corporation Atom Processor E3800 Series SMBus Controller (rev 0e)
Subsystem: Super Micro Computer Inc Atom Processor E3800 Series SMBus Controller
Control: I/O+ Mem+ BusMaster- SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx-
Status: Cap+ 66MHz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
Interrupt: pin B routed to IRQ 18
Region 0: Memory at 90a04000 (32-bit, non-prefetchable) [size=32]
Region 4: I/O ports at e000 [size=32]
Capabilities: [50] Power Management version 3
Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0-,D1-,D2-,D3hot-,D3cold-)
Status: D0 NoSoftRst+ PME-Enable- DSel=0 DScale=0 PME-
Kernel driver in use: i801_smbus
Kernel modules: i2c_i801
I am not sure how to access this area to write a base address to the register and I don‘t know where in IO space I should put my registers. And how do I realize this in C? Can I make use of existing Linux funtions to implement this?
Edit
The hexdump of the configuration space outputs the following:
[user@host ~]$ sudo lspci -xxx -s 00:1f.0
[sudo] password for user:
00:1f.0 ISA bridge: Intel Corporation Atom Processor Z36xxx/Z37xxx Series Power Control Unit (rev 0e)
00: 86 80 1c 0f 07 00 10 02 0e 00 01 06 00 00 80 00
10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
20: 00 00 00 00 00 00 00 00 00 00 00 00 d9 15 16 08
30: 00 00 00 00 e0 00 00 00 00 00 00 00 00 00 00 00
40: 03 04 00 00 02 30 d0 fe 03 05 00 00 02 c0 d0 fe
50: 02 80 d0 fe 02 10 d0 fe 02 00 f0 fe 02 50 d0 fe
60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
d0: 00 00 00 00 00 00 00 00 cf ff 00 00 00 00 00 00
e0: 09 00 0c 10 00 00 00 00 00 00 00 00 00 00 00 00
f0: 01 c0 d1 fe 00 00 00 00 1a 0f 0e 01 03 03 00 00
[user@host ~]$
From my interpretation the ACPI_BASE_ADDRESS register (manual page 1217) contains „03 04 00 00“.
The GPIO_BASE_ADDRESS register (manual page 1219) contains „03 05 00 00“.
Grepping for acpi in dmesg returns several entries (too much to post here).
/proc/ioports outputs the following:
[user@host ~]$ sudo cat /proc/ioports
[sudo] password for user:
0000-006f : PCI Bus 0000:00
0000-001f : dma1
0020-0021 : pic1
0040-0043 : timer0
0050-0053 : timer1
0060-0060 : keyboard
0064-0064 : keyboard
0070-0077 : PCI Bus 0000:00
0070-0077 : rtc0
0078-0cf7 : PCI Bus 0000:00
0080-008f : dma page reg
00a0-00a1 : pic2
00c0-00df : dma2
00f0-00ff : fpu
02e0-02e7 : serial
02f8-02ff : serial
03e0-03e7 : serial
03f8-03ff : serial
0400-047f : pnp 00:01
0400-0403 : ACPI PM1a_EVT_BLK
0404-0405 : ACPI PM1a_CNT_BLK
0408-040b : ACPI PM_TMR
0420-042f : ACPI GPE0_BLK
0430-0433 : iTCO_wdt.0.auto
0430-0433 : iTCO_wdt
0450-0450 : ACPI PM2_CNT_BLK
0460-047f : iTCO_wdt.0.auto
0460-047f : iTCO_wdt
0500-05fe : pnp 00:01
0600-061f : pnp 00:01
0680-069f : pnp 00:01
0a30-0a3f : pnp 00:07
0cf8-0cff : PCI conf1
0d00-ffff : PCI Bus 0000:00
1000-1fff : PCI Bus 0000:01
b000-cfff : PCI Bus 0000:03
b000-cfff : PCI Bus 0000:04
b000-bfff : PCI Bus 0000:07
b000-b01f : 0000:07:00.0
b000-b01f : ahci
b020-b023 : 0000:07:00.0
b020-b023 : ahci
b030-b037 : 0000:07:00.0
b030-b037 : ahci
b040-b043 : 0000:07:00.0
b040-b043 : ahci
b050-b057 : 0000:07:00.0
b050-b057 : ahci
c000-cfff : PCI Bus 0000:05
c000-c01f : 0000:05:00.0
d000-dfff : PCI Bus 0000:02
d000-d01f : 0000:02:00.0
e000-e01f : 0000:00:1f.3
e000-e01f : i801_smbus
e020-e027 : 0000:00:02.0