LAN966x GPIO

SoC Resources

LAN966x GPIO controller supports 78 gpio pins. Most of the GPIO pins have alternate functions which will be handled by linux driver.

Kernel configurations

Following kernel config options should be enabled to use LAN966x GPIO Controller:

  • CONFIG_PINCTRL_OCELOT - GPIO controller config option.

Devicetree Configuration

To use GPIO pins of a specific peripheral, configure following properties in device tree:

  • compatible string must be set to microchip,lan966x-pinctrl.

  • reg property must be set with <0xe2004064 0xb4> and <0xe2010024 0x138>.

  • gpio-controller property must be added.

  • #gpio-cells property must be set to 2

  • gpio-ranges property must be set to <&gpio 0 0 78>

  • interrupts property must be set with GPIO block interrupt details as <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>.

Peripheral Shared Peripheral Interrupt CPU INTR

gpio

49

17

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:

GPIO Pin FUNC1 FUNC2 FUNC3 FUNC4 FUNC5 FUNC6

0

-

-

-

-

-

-

1

-

-

-

-

-

-

2

-

-

-

-

-

-

3

-

-

-

-

-

-

4

-

-

-

-

-

-

5

-

-

-

-

-

-

6

-

-

-

-

-

-

7

-

-

-

-

-

-

8

fc0_a

usb_host_b

-

usb_slave_b

-

-

9

fc0_a

usb_host_b

-

-

-

-

10

fc0_a

-

-

-

-

-

11

fc1_a

-

-

-

-

-

12

fc1_a

-

-

-

-

-

13

fc1_a

-

-

-

-

-

14

fc2_a

-

-

-

-

-

15

fc2_a

-

-

-

-

-

16

fc2_a

ib_trig_a

-

ob_trig_a

irq_in_c

irq_out_c

17

fc3_a

ib_trig_a

-

ob_trig_a

irq_in_c

irq_out_c

18

fc3_a

ib_trig_a

-

ob_trig_a

irq_in_c

irq_out_c

19

fc3_a

ib_trig_a

-

ob_trig_a

irq_in_c

irq_out_c

20

fc4_a

ib_trig_a

-

ob_trig_a

irq_in_c

-

21

fc4_a

-

-

ob_trig_a

-

-

22

fc4_a

-

-

ob_trig_a

-

-

23

-

-

-

ob_trig_a

-

-

24

fc0_b

ib_trig_a

usb_host_c

ob_trig_a

irq_in_c

tacho_a

25

fc0_b

ib_trig_a

usb_host_c

ob_trig_a

irq_out_c

sfp_sd

26

fc0_b

ib_trig_a

usb_slave_c

ob_trig_a

can0_a

sfp_sd

27

-

-

-

ob_trig_a

can0_a

-

28

miim_a

-

-

ob_trig_a

irq_out_c

sfp_sd

29

miim_a

-

-

ob_trig_a

-

-

30

fc3_c

can1

-

ob_trig

reco_b

-

31

fc3_c

can1

-

ob_trig

reco_b

-

32

fc3_c

-

sgpio_a

-

miim_slave_a

-

33

fc1_b

-

sgpio_a

-

miim_slave_a

miim_b

34

fc1_b

-

sgpio_a

-

miim_slave_a

miim_b

35

fc1_b

ptpsync_0

sgpio_a

can0_b

-

-

36

-

ptpsync_1

-

can0_b

-

-

37

fc_shrd0

ptpsync_2

twi_slc_gate_ad

-

-

-

38

-

ptpsync_3

-

-

-

-

39

-

ptpsync_4

-

-

-

-

40

fc_shrd1

ptpsync_5

-

-

-

-

41

fc_shrd2

ptpsync_6

twi_slc_gate_ad

-

-

-

42

fc_shrd3

ptpsync_7

twi_slc_gate_ad

-

-

-

43

fc2_b

ob_trig_b

ib_trig_b

irq_out_a

reco_a

irq_in_a

44

fc2_b

ob_trig_b

ib_trig_b

irq_out_a

reco_a

irq_in_a

45

fc2_b

ob_trig_b

ib_trig_b

irq_out_a

-

irq_in_a

46

fc1_c

ob_trig_b

ib_trig_b

irq_out_a

fc_shrd4

irq_in_a

47

fc1_c

ob_trig_b

ib_trig_b

irq_out_a

fc_shrd5

irq_in_a

48

fc1_c

ob_trig_b

ib_trig_b

irq_out_a

fc_shrd6

irq_in_a

49

fc_shrd7

ob_trig_b

ib_trig_b

irq_out_a

twi_slc_gate

irq_in_a

50

fc_shrd16

ob_trig_b

ib_trig_b

irq_out_a

twi_slc_gate

-

51

fc3_b

ob_trig_b

ib_trig_c

irq_out_b

-

irq_in_b

52

fc3_b

ob_trig_b

ib_trig_c

irq_out_b

tacho_b

irq_in_b

53

fc3_b

ob_trig_b

ib_trig_c

irq_out_b

-

irq_in_b

54

fc_shrd8

ob_trig_b

ib_trig_c

irq_out_b

twi_slc_gate

irq_in_b

55

fc_shrd9

ob_trig_b

ib_trig_c

irq_out_b

twi_slc_gate

irq_in_b

56

fc4_b

ob_trig_b

ib_trig_c

irq_out_b

fc_shrd10

irq_in_b

57

fc4_b

twi_slc_gate

ib_trig_c

irq_out_b

fc_shrd11

irq_in_b

58

fc4_b

twi_slc_gate

ib_trig_c

irq_out_b

fc_shrd12

irq_in_b

59

qspi1

miim_c

-

-

miim_slaveb

-

60

qspi1

miim_c

-

-

miim_slaveb

-

61

qspi1

-

sgpio_b

fc0_c

miim_slaveb

-

62

qspi1

fc_shrd13

sgpio_b

fc0_c

twi_slc_gate

sfp_sd

63

qspi1

fc_shrd14

sgpio_b

fc0_c

twi_slc_gate

sfp_sd

64

qspi1

fc4_c

sgpio_b

fc_shrd15

twi_slc_gate

sfp_sd

65

usb_host_a

fc4_c

-

irq_out_c

twi_slc_gate_ad

-

66

usb_host_a

fc4_c

usb_slave_a

irq_out_c

irq_in_c

-

67

emmc_sd

-

qspi2

-

-

-

68

emmc_sd

-

qspi2

-

-

-

69

emmc_sd

-

qspi2

-

-

-

70

emmc_sd

-

qspi2

-

-

-

71

emmc_sd

-

qspi2

-

-

-

72

emmc_sd

-

qspi2

-

-

-

73

emmc

-

-

sd

-

-

74

emmc

-

fc_shrd17

sd

twi_slc_gate

-

75

emmc

-

fc_shrd18

sd

twi_slc_gate

-

76

emmc

-

fc_shrd19

sd

twi_slc_gate

-

77

emmc_sd

-

fc_shrd20

-

twi_slc_gate

-

Note

LAN966x GPIO controller supports 8 Alternate functions. FUNC0 is GPIO mode and FUNC7 is Reserved. Function names for FUNC1-FUNC6 alternate modes are listed above.

Example

Following example shows how a GPIO controller should be defined in DT to enable GPIO pins for eMMC interface:

dtsi file:

gpio: pinctrl@e2004070 {
	compatible = "microchip,lan966x-pinctrl";
	reg = <GCB_GPIO_ADDR GCB_GPIO_SIZE>,
	    <CHIP_TOP_GPIO_CFG_ADDR CHIP_TOP_GPIO_CFG_SIZE>;
	gpio-controller;
	#gpio-cells = <2>;
	gpio-ranges = <&gpio 0 0 78>;
	interrupt-controller;
	interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
	#interrupt-cells = <2>;

	emmc_sd_pins: emmc-sd-pins {
		/* eMMC_SD - CMD, CLK, D0, D1, D2, D3, RSTN */
		pins = "GPIO_67", "GPIO_68", "GPIO_69", "GPIO_70",
		       "GPIO_71", "GPIO_72", "GPIO_77";
		function = "emmc_sd";
	};

	emmc_pins: emmc-pins {
		/* eMMC - D4, D5, D6, D7 */
		pins = "GPIO_73", "GPIO_74", "GPIO_75", "GPIO_76";
		function = "emmc";
	};
};

dts file changes:

&sdmmc0 {
        bus-width = <8>;
        cap-mmc-highspeed;
        cap-mmc-hw-reset;
        non-removable;
        pinctrl-0 = <&emmc_sd_pins>, <&emmc_pins>;
        pinctrl-names = "default";
        no-1-8-v;
        tx-phase = <0>; /* 180 degrees phase shift */
        status = "okay";
};

UserSpace

Confirm instances are created

  • Check if pinctrl driver is registered and respective peripheral is up or not.

Example on how to use

Checking if the pinctrl driver is registered and respective peripheral(here emmc with above dt example) is created or not.

# dmesg | grep pinctrl
[    0.014851] pinctrl core: initialized pinctrl subsystem
[    0.109830] gpio gpiochip0: (ocelot-gpio): created GPIO range 0->77 ==> e2004064.pinctrl PIN 0->77
[    0.111131] pinctrl-ocelot e2004064.pinctrl: driver registered


# dmesg | grep mmc
[    0.722586] mmc0: SDHCI controller on e0830000.sdio-host [e0830000.sdio-host] using ADMA
[    2.373076] mmc0: new high speed MMC card at address 0001
[    2.378776] mmcblk0: mmc0:0001 IS004G 3.64 GiB
[    2.387639]  mmcblk0:
[    2.388324] mmcblk0boot0: mmc0:0001 IS004G 2.00 MiB
[    2.399663] mmcblk0boot1: mmc0:0001 IS004G 2.00 MiB
[    2.410084] mmcblk0rpmb: mmc0:0001 IS004G 512 KiB, chardev (247:0)


# mount -t debugfs none /sys/kernel/debug/
cat /sys/kernel/debug/mmc0/ios# cat /sys/kernel/debug/mmc0/ios
clock:          46000000 Hz
actual clock:   46000000 Hz
vdd:            21 (3.3 ~ 3.4 V)
bus mode:       2 (push-pull)
chip select:    0 (don't care)
power mode:     2 (on)
bus width:      3 (8 bits)
timing spec:    1 (mmc high-speed)
signal voltage: 0 (3.30 V)
driver type:    0 (driver type B)

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.