imx8mp runtime pin muxing

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

imx8mp runtime pin muxing

Jump to solution
500 Views
Marco_Savo
Contributor II

We're working on a custom board using imx8mp processor. In our new design, our hardware engineers as a solution for pin expansion are using some kind of multiplexing/demultiplexing using shift registers; setting one gpio one set of input output becomes available, unsetting it become the latter. For what I could see, this is called runtime pinmuxing. I am using yocto kirkstone, and as far as I could see there is something called runtime pinmuxing via debugfs.

Can something like this could work?

 

 

Runtime Pinmuxing

Runtime pinmuxing is a technique for configuring the IOMUXC register set dynamically at runtime. This is useful for applications that need to change the pinmux configuration based on runtime conditions, such as the boot stage or the application's needs.

Complete example of a .dts file that demonstrates how to use runtime pinmuxing with the i.MX 8MP SoC. This example configures the GPIO1_IO03 pin to be used as a GPIO input pin.
DTS

/dts-v1/;

#include "imx8mp-pinfunc.h"

/*
 * Set up the IOMUXC register for GPIO1_IO03 to be used as a GPIO input pin.
 */
&iomuxc {
  pinctrl_gpio1_io03: gpio1_io03_gpio {
    fsl,pins = <
      MX8MP_IOMUXC_GPIO1_IO03_GPIO1_IO03    /* GPIO1_IO03 */
    >;
  };
};

Using Runtime Pinmuxing

To use runtime pinmuxing, you will need to write a driver that sets the IOMUXC registers at runtime. The driver will need to be able to identify the pin that needs to be configured and the desired pinmux setting.

Here is an example of a driver that sets the pinmux configuration for GPIO1_IO03 to be used as a GPIO input pin:


#include <linux/gpio.h>
#include <linux/iomuxc.h>

static int gpio1_io03_pinmux_set(struct gpio_chip *chip, unsigned int offset,
                                int value)
{
  if (value) {
    /* Set the IOMUXC register for GPIO1_IO03 to be used as a GPIO input pin. */
    iomuxc_set_gpr_register( IOMUXC_GPR1, MX8MP_GPIO1_IOMUXC_GPR1_GPIO1_IO03_GPIO, 1);
  } else {
    /* Set the IOMUXC register for GPIO1_IO03 to be used as GPIO1_IO03 */
    iomuxc_set_gpr_register( IOMUXC_GPR1, MX8MP_GPIO1_IOMUXC_GPR1_GPIO1_IO03_GPIO, 0);
  }

  return 0;
}

static struct gpio_chip gpio1_io03_chip = {
  .label = "gpio1_io03",
  .base = GPIO1_IO03,
  .ngpio = 1,
  .set = gpio1_io03_pinmux_set,
};

static int __init gpio1_io03_init(void)
{
  int ret;

  ret = gpiochip_add(&gpio1_io03_chip);
  if (ret) {
    return ret;
  }

  return 0;
}

arch_initcall(gpio1_io03_init);

Here are the steps on how to create a debugfs file for runtime pinmuxing:

1. Create a debugfs directory:

sudo mkdir /sys/kernel/debug/pinctrl/<controller>

where <controller> is the name of the pinctrl controller you want to use. For example, to create a debugfs directory for the IMX 8MP iomuxc controller, you would use the following command:

sudo mkdir /sys/kernel/debug/pinctrl/imx8mp-iomuxc

2. Create a debugfs file:

sudo touch /sys/kernel/debug/pinctrl/<controller>/pinmux-select

where <controller> is the name of the pinctrl controller you want to use. For example, to create a debugfs file for the IMX 8MP iomuxc controller, you would use the following command:

sudo touch /sys/kernel/debug/pinctrl/imx8mp-iomuxc/pinmux-select

3. Modify the permissions of the debugfs file:


sudo chmod 666 /sys/kernel/debug/pinctrl/<controller>/pinmux-select

where <controller> is the name of the pinctrl controller you want to use. For example, to modify the permissions of the IMX 8MP iomuxc controller's debugfs file, you would use the following command:

sudo chmod 666 /sys/kernel/debug/pinctrl/imx8mp-iomuxc/pinmux-select


4. Create a script to set the pinmux configuration:

#!/bin/bash

pinmux="<pinmux-setting>"

echo "$pinmux" > /sys/kernel/debug/pinctrl/<controller>/pinmux-select


where <pinmux-setting> is the desired pinmux setting. For example, the following script would set the GPIO1_IO03 pin to be used as a GPIO input pin:

#!/bin/bash

pinmux="imx8mp-iomuxc-44:gpio1_io03:1"

echo "$pinmux" > /sys/kernel/debug/pinctrl/imx8mp-iomuxc/pinmux-select

5. Save the script and make it executable:

sudo chmod +x <script-name>
./set-pinmux.sh

 

0 Kudos
1 Solution
479 Views
JosephAtNXP
NXP TechSupport
NXP TechSupport

Hi,

Thank you for your interest in NXP Semiconductor products,

Yes, this could work. Also this.

But have in mind that linux GPIOs and device-specific pins are assigned at boot time within the device tree. There is no way to reassign these dynamically while the Linux kernel is running without rewriting the affected drivers to add this functionality or unloading these drivers, which seems the best option.

Regards

View solution in original post

1 Reply
480 Views
JosephAtNXP
NXP TechSupport
NXP TechSupport

Hi,

Thank you for your interest in NXP Semiconductor products,

Yes, this could work. Also this.

But have in mind that linux GPIOs and device-specific pins are assigned at boot time within the device tree. There is no way to reassign these dynamically while the Linux kernel is running without rewriting the affected drivers to add this functionality or unloading these drivers, which seems the best option.

Regards