LAN969x GPIO
1. LAN969x GPIO
1.1. SoC Resources
LAN969x GPIO controller supports 67 gpio pins. Most of the GPIO pins have alternate functions which will be handled by the Linux driver.
1.2. Kernel configurations
Following kernel config options should be enabled to use LAN969x GPIO Controller:
-
CONFIG_PINCTRL_OCELOT
- GPIO controller config option.
1.3. Devicetree Configuration
To use GPIO pins of a specific peripheral, configure following properties in device tree:
-
compatible
string must be set tomicrochip,lan969x-pinctrl
. -
reg
property must be set to<0xe20100d4 0xd4>
and<0xe2010370 0xa8>
. -
gpio-controller
property must be added. -
interrupt-controller
property mus be added. -
#gpio-cells
property must be set to 2 -
gpio-ranges
property must be set to<&gpio 0 0 67>
-
interrupts
property must be set with GPIO block interrupt details as<GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>
.
Peripheral | Shared Peripheral Interrupt | CPU INTR |
---|---|---|
gpio |
47 |
15 |
- Note
-
Shared peripheral interrupt lines start at index ID32. So, CPU INTR must be calculated as [Shared peripheral interrupt number - 32].
-
pins
must be set with list of GPIO pins required. For example for mcan0, it should be set as"GPIO_35", "GPIO_36"
. -
function
must be set to function name corresponding to GPIO pins and the peripheral we are trying to enable. Refer below table for function names:
-
Pin | FUNC0 | FUNC1 | FUNC2 | FUNC3 | FUNC4 | FUNC5 | FUNC6 |
---|---|---|---|---|---|---|---|
0 |
GPIO |
irq0 |
fc_shrd |
pcie_perst |
none |
none |
none |
1 |
GPIO |
irq1 |
fc_shrd |
usb_power |
none |
none |
none |
2 |
GPIO |
fc |
none |
none |
none |
none |
none |
3 |
GPIO |
fc |
none |
none |
none |
none |
none |
4 |
GPIO |
fc |
none |
none |
none |
none |
none |
5 |
GPIO |
sgpio_A |
none |
clkmon |
none |
none |
none |
6 |
GPIO |
sgpio_A |
none |
clkmon |
none |
none |
none |
7 |
GPIO |
sgpio_A |
none |
clkmon |
none |
none |
none |
8 |
GPIO |
sgpio_A |
none |
clkmon |
none |
none |
none |
9 |
GPIO |
miim |
miim_sA |
clkmon |
none |
none |
none |
10 |
GPIO |
miim |
miim_sA |
clkmon |
none |
none |
none |
11 |
GPIO |
miim_irq |
miim_sA |
clkmon |
none |
none |
none |
12 |
GPIO |
irq3 |
fc_shrd |
usb2phy_rst |
none |
none |
none |
13 |
GPIO |
irq4 |
fc_shrd |
usb_over_detect |
none |
none |
none |
14 |
GPIO |
emmc_sd |
qspi1 |
fc |
none |
none |
none |
15 |
GPIO |
emmc_sd |
qspi1 |
fc |
none |
none |
none |
16 |
GPIO |
emmc_sd |
qspi1 |
fc |
none |
none |
none |
17 |
GPIO |
emmc_sd |
qspi1 |
ptpsync_0 |
usb_power |
none |
none |
18 |
GPIO |
emmc_sd |
qspi1 |
ptpsync_1 |
usb2phy_rst |
none |
none |
19 |
GPIO |
emmc_sd |
qspi1 |
ptpsync_2 |
usb_over_detect |
none |
none |
20 |
GPIO |
emmc_sd |
none |
fc_shrd |
none |
none |
none |
21 |
GPIO |
emmc_sd |
none |
fc_shrd |
none |
none |
none |
22 |
GPIO |
emmc_sd |
none |
fc_shrd |
none |
none |
none |
23 |
GPIO |
emmc_sd |
none |
fc_shrd |
none |
none |
none |
24 |
GPIO |
emmc_sd |
none |
none |
none |
none |
none |
25 |
GPIO |
fan |
fusa |
can0_A |
qspi1 |
none |
none |
26 |
GPIO |
fan |
fusa |
can0_A |
qspi1 |
none |
none |
27 |
GPIO |
synce |
fc |
miim |
qspi1 |
none |
none |
28 |
GPIO |
synce |
fc |
miim |
qspi1 |
none |
none |
29 |
GPIO |
synce |
fc |
miim_irq |
qspi1 |
none |
none |
30 |
GPIO |
ptpsync_0 |
usb_ulpi |
fc_shrd |
qspi1 |
none |
none |
31 |
GPIO |
ptpsync_1 |
usb_ulpi |
fc_shrd |
none |
none |
none |
32 |
GPIO |
ptpsync_2 |
usb_ulpi |
fc_shrd |
none |
none |
none |
33 |
GPIO |
sd |
usb_ulpi |
fc_shrd |
none |
none |
none |
34 |
GPIO |
sd |
usb_ulpi |
can1 |
fc_shrd |
none |
none |
35 |
GPIO |
sd |
usb_ulpi |
can1 |
fc_shrd |
none |
none |
36 |
GPIO |
sd |
usb_ulpi |
pcie_perst |
fc_shrd |
none |
none |
37 |
GPIO |
sd |
usb_ulpi |
can0_B |
none |
none |
none |
38 |
GPIO |
sd |
usb_ulpi |
can0_B |
none |
none |
none |
39 |
GPIO |
sd |
usb_ulpi |
miim |
none |
none |
none |
40 |
GPIO |
sd |
usb_ulpi |
miim |
none |
none |
none |
41 |
GPIO |
sd |
usb_ulpi |
miim_irq |
none |
none |
none |
42 |
GPIO |
ptpsync_3 |
can1 |
none |
none |
none |
none |
43 |
GPIO |
ptpsync_4 |
can1 |
none |
none |
none |
none |
44 |
GPIO |
ptpsync_5 |
sfp_sd |
none |
none |
none |
none |
45 |
GPIO |
ptpsync_6 |
sfp_sd |
none |
none |
none |
none |
46 |
GPIO |
ptpsync_7 |
sfp_sd |
none |
none |
none |
none |
47 |
GPIO |
none |
sfp_sd |
none |
none |
none |
none |
48 |
GPIO |
none |
sfp_sd |
none |
none |
none |
none |
49 |
GPIO |
none |
sfp_sd |
none |
none |
none |
none |
50 |
GPIO |
none |
sfp_sd |
none |
none |
none |
none |
51 |
GPIO |
none |
sfp_sd |
none |
none |
none |
none |
52 |
GPIO |
fan |
sfp_sd |
none |
none |
none |
none |
53 |
GPIO |
fan |
sfp_sd |
none |
none |
none |
none |
54 |
GPIO |
synce |
fc |
none |
none |
none |
none |
55 |
GPIO |
synce |
fc |
none |
none |
none |
none |
56 |
GPIO |
synce |
fc |
none |
none |
none |
none |
57 |
GPIO |
sfp_sd |
fc_shrd |
twi |
ptpsync_3 |
none |
none |
58 |
GPIO |
sfp_sd |
fc_shrd |
twi |
ptpsync_4 |
none |
none |
59 |
GPIO |
sfp_sd |
fc_shrd |
twi |
ptpsync_5 |
none |
none |
60 |
GPIO |
sfp_sd |
fc_shrd |
twi |
ptpsync_6 |
none |
none |
61 |
GPIO |
miim |
fc_shrd |
twi |
none |
none |
none |
62 |
GPIO |
miim |
fc_shrd |
twi |
none |
none |
none |
63 |
GPIO |
miim_irq |
fc_shrd |
twi |
none |
none |
none |
64 |
GPIO |
fc |
fc_shrd |
twi |
none |
none |
none |
65 |
GPIO |
fc |
fc_shrd |
twi |
none |
none |
none |
66 |
GPIO |
fc |
fc_shrd |
twi |
none |
none |
none |
- Note
-
LAN969x GPIO controller supports 8 Alternate functions. FUNC0 is GPIO mode and FUNC7 is Reserved. Function names for FUNC1-FUNC6 alternate modes are listed above.
1.3.2. Example
Following example shows how a GPIO controller should be defined in DT to enable GPIO pins for a fan and an MDIO bus:
dtsi file:
/ { axi: axi { gpio: pinctrl@e20100d4 { compatible = "microchip,lan969x-pinctrl"; reg = <0xe20100d4 0xd4>, <0xe2010370 0xa8>; gpio-controller; #gpio-cells = <2>; gpio-ranges = <&gpio 0 0 66>; interrupt-controller; interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>; #interrupt-cells = <2>; #address-cells = <1>; }; }; fan_pins: fan-pins { pins = "GPIO_25", "GPIO_26"; function = "fan"; }; mdio_pins: mdio-pins { pins = "GPIO_9", "GPIO_10"; function = "miim"; }; mdio_irq_pins: mdio-irq-pins { pins = "GPIO_11"; function = "miim_irq"; }; };
dts file changes to use the defined pincontrol:
&hwmon { pinctrl-0 = <&fan_pins>; pinctrl-names = "default"; }; &mdio0 { pinctrl-0 = <&mdio_pins>, <&mdio_irq_pins>; pinctrl-names = "default"; reset-gpios = <&gpio 62 GPIO_ACTIVE_LOW>; status = "okay";
1.4. UserSpace
1.4.1. Confirm instances are created
Checking if the pinctrl driver is registered and respective peripheral is created or not.
# dmesg | grep pinctrl [ 0.009597] pinctrl core: initialized pinctrl subsystem [ 0.093905] pinctrl-ocelot e20100d4.pinctrl: driver registered
1.4.2. Displaying pin control configuration
You can list the pinctrl devices in the system with
# cat /sys/kernel/debug/pinctrl/pinctrl-devices name [pinmux] [pinconf] lan969x-pinctrl yes yes e2010230.gpio-input yes yes e2010230.gpio-output yes yes
Here the lan969x-pinctrl is the device described on this page, and the e2010230.gpio-input and e2010230.gpio-output is the Serial GPIO Controller described here.
Then you can list the groups of pinctrls using:
# cat /sys/kernel/debug/pinctrl/pinctrl-handles Requested pin control handlers their pinmux maps: device: e0040200.serial current state: default state: default type: MUX_GROUP controller lan969x-pinctrl group: GPIO_3 (3) function: fc (6) type: MUX_GROUP controller lan969x-pinctrl group: GPIO_4 (4) function: fc (6) device: e0064600.i2c current state: default state: default type: MUX_GROUP controller lan969x-pinctrl group: GPIO_55 (55) function: fc (6) type: MUX_GROUP controller lan969x-pinctrl group: GPIO_56 (56) function: fc (6) device: e0060400.spi current state: default state: default type: MUX_GROUP controller lan969x-pinctrl group: GPIO_64 (64) function: fc (6) type: MUX_GROUP controller lan969x-pinctrl group: GPIO_65 (65) function: fc (6) type: MUX_GROUP controller lan969x-pinctrl group: GPIO_66 (66) function: fc (6) device: e20101a8.mdio current state: default state: default type: MUX_GROUP controller lan969x-pinctrl group: GPIO_9 (9) function: miim (63) type: MUX_GROUP controller lan969x-pinctrl group: GPIO_10 (10) function: miim (63) type: MUX_GROUP controller lan969x-pinctrl group: GPIO_11 (11) function: miim_irq (69) device: e00c0000.switch current state: default state: default type: MUX_GROUP controller lan969x-pinctrl group: GPIO_58 (58) function: ptpsync_4 (85) type: MUX_GROUP controller lan969x-pinctrl group: GPIO_59 (59) function: ptpsync_5 (86) device: axi:usb@300000 current state: default state: default type: MUX_GROUP controller lan969x-pinctrl group: GPIO_30 (30) function: usb_ulpi (130) type: MUX_GROUP controller lan969x-pinctrl group: GPIO_31 (31) function: usb_ulpi (130) type: MUX_GROUP controller lan969x-pinctrl group: GPIO_32 (32) function: usb_ulpi (130) type: MUX_GROUP controller lan969x-pinctrl group: GPIO_33 (33) function: usb_ulpi (130) type: MUX_GROUP controller lan969x-pinctrl group: GPIO_34 (34) function: usb_ulpi (130) type: MUX_GROUP controller lan969x-pinctrl group: GPIO_35 (35) function: usb_ulpi (130) type: MUX_GROUP controller lan969x-pinctrl group: GPIO_36 (36) function: usb_ulpi (130) type: MUX_GROUP controller lan969x-pinctrl group: GPIO_37 (37) function: usb_ulpi (130) type: MUX_GROUP controller lan969x-pinctrl group: GPIO_38 (38) function: usb_ulpi (130) type: MUX_GROUP controller lan969x-pinctrl group: GPIO_39 (39) function: usb_ulpi (130) type: MUX_GROUP controller lan969x-pinctrl group: GPIO_40 (40) function: usb_ulpi (130) type: MUX_GROUP controller lan969x-pinctrl group: GPIO_41 (41) function: usb_ulpi (130) type: MUX_GROUP controller lan969x-pinctrl group: GPIO_12 (12) function: usb2phy_rst (128) type: MUX_GROUP controller lan969x-pinctrl group: GPIO_13 (13) function: usb_over_detect (129) type: MUX_GROUP controller lan969x-pinctrl group: GPIO_1 (1) function: usb_power (127) device: e2020100.hwmon current state: default state: default type: MUX_GROUP controller lan969x-pinctrl group: GPIO_25 (25) function: fan (5) type: MUX_GROUP controller lan969x-pinctrl group: GPIO_26 (26) function: fan (5) device: e0830000.sdhci-host current state: default state: default type: MUX_GROUP controller lan969x-pinctrl group: GPIO_14 (14) function: emmc_sd (133) type: MUX_GROUP controller lan969x-pinctrl group: GPIO_15 (15) function: emmc_sd (133) type: MUX_GROUP controller lan969x-pinctrl group: GPIO_16 (16) function: emmc_sd (133) type: MUX_GROUP controller lan969x-pinctrl group: GPIO_17 (17) function: emmc_sd (133) type: MUX_GROUP controller lan969x-pinctrl group: GPIO_18 (18) function: emmc_sd (133) type: MUX_GROUP controller lan969x-pinctrl group: GPIO_19 (19) function: emmc_sd (133) type: MUX_GROUP controller lan969x-pinctrl group: GPIO_20 (20) function: emmc_sd (133) type: MUX_GROUP controller lan969x-pinctrl group: GPIO_21 (21) function: emmc_sd (133) type: MUX_GROUP controller lan969x-pinctrl group: GPIO_22 (22) function: emmc_sd (133) type: MUX_GROUP controller lan969x-pinctrl group: GPIO_23 (23) function: emmc_sd (133) type: MUX_GROUP controller lan969x-pinctrl group: GPIO_24 (24) function: emmc_sd (133) device: e2010230.gpio current state: default state: default type: MUX_GROUP controller lan969x-pinctrl group: GPIO_5 (5) function: sgpio_a (104) type: MUX_GROUP controller lan969x-pinctrl group: GPIO_6 (6) function: sgpio_a (104) type: MUX_GROUP controller lan969x-pinctrl group: GPIO_7 (7) function: sgpio_a (104) type: MUX_GROUP controller lan969x-pinctrl group: GPIO_8 (8) function: sgpio_a (104) device: e2010230.gpio current state: none device: e2010230.gpio current state: none
1.4.3. Configuring GPIO pin using Sysfs interface
- Mounting Sysfs
-
The root file system being used may not have sysfs mounted and it cannot be used if it’s not mounted. The directory /sys is also needed to mount the sysfs on. The root file system must be writable to do the following steps.
- Identify the GPIO chips
-
Use command
ls /sys/class/gpio/
to list all the gpio chips. - Steps to configure a GPIO pin
-
-
Export a GPIO pin using command
echo X > /sys/class/gpio/export
. -
Read direction and value from GPIO pin using command
cat /sys/class/gpio/gpioX/direction
for direction andcat /sys/class/gpio/gpioX/value
for value, where X is pin number. -
If direction of a pin is
out
, we can write0
or1
to value file of pin and also can read its value. -
If direction of a pin is
in
, we can only read its value but cannot write to it, we would get an error because it is not valid to set the value of an input pin. -
Unexport a GPIO pin using command
echo X > /sys/class/gpio/unexport
.
-
Following example configures GPIO pin 51(physical pin number 32) and validates voltage on pin using a multimeter:
# ls /sys/class/gpio/ export gpiochip0 unexport
Export GPIO pin 51:
# echo 51 > /sys/class/gpio/export # ls /sys/class/gpio/ export gpio51 gpiochip0 unexport
Check default direction and value:
# cat /sys/class/gpio/gpio51/value 1 # # cat /sys/class/gpio/gpio51/direction in #
Now, measure voltage on physical pin number 32 and you should see voltage of approximately 3.3v.
Change direction of GPIO pin 51 to out
and set value to zero:
# echo out > /sys/class/gpio/gpio51/direction # # # cat /sys/class/gpio/gpio51/value 0 #
Again measure voltage on physical pin number 32 and you should see voltage close to zero.