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 to microchip,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.1. References

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 and cat /sys/class/gpio/gpioX/value for value, where X is pin number.

  • If direction of a pin is out, we can write 0 or 1 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.