int imxrt_iomux_configure()

in arch/arm/src/imxrt/imxrt_iomuxc_ver2.c [264:747]


int imxrt_iomux_configure(uintptr_t padctl, iomux_pinset_t ioset)
{
  uint32_t regval = 0;

  /* Enable IOMUXC clock if it is not already enabled */

  imxrt_clockall_iomuxc();
#if 0
  imxrt_clockall_iomuxc_gpr();
#endif

#if 0 /* Are low-power domain, Secure Non-volatile Storage (SNVS) IOMUXC clocks needed? */
  imxrt_clockall_iomuxc_snvs();
  imxrt_clockall_iomuxc_snvs_gpr();
#endif

  DEBUGASSERT(padctl >= IMXRT_PADCTL_GPIO_EMC_B1_00);

  if (padctl <= IMXRT_PADCTL_GPIO_EMC_B1_41)
    {
      /* GPIO_EMC_B1 ********************************************************/

      /* Select drive strength */

      if ((ioset & IOMUX_DRIVE_MASK) == IOMUX_DRIVE_HIGHSTRENGTH)
        {
          regval &= ~PADCTL_EMC_B1_PDRV;
        }
      else
        {
          regval |= PADCTL_EMC_B1_PDRV;
        }

      /* Handle pull/keep selection */

      switch (ioset & IOMUX_PULL_MASK)
        {
          case IOMUX_PULL_UP:
            regval |= PADCTL_EMC_B1_PULL_UP;
            break;

          case IOMUX_PULL_DOWN:
            regval |= PADCTL_EMC_B1_PULL_DOWN;
            break;

          case IOMUX_PULL_NONE:
            regval |= PADCTL_EMC_B1_PULL_NONE;
            break;

          default:
            break;
        }

      /* Select CMOS output or Open Drain output */

      if ((ioset & IOMUX_OPENDRAIN) != 0)
        {
          regval |= PADCTL_EMC_B1_ODE;
        }
      else
        {
          regval &= ~(PADCTL_EMC_B1_ODE);
        }
    }
  else if (padctl <= IMXRT_PADCTL_GPIO_EMC_B2_20)
    {
      /* GPIO_EMC_B2 ********************************************************/

      /* Select drive strength */

      if ((ioset & IOMUX_DRIVE_MASK) == IOMUX_DRIVE_HIGHSTRENGTH)
        {
          regval &= ~PADCTL_EMC_B2_PDRV;
        }
      else
        {
          regval |= PADCTL_EMC_B2_PDRV;
        }

      /* Handle pull/keep selection */

      switch (ioset & IOMUX_PULL_MASK)
        {
          case IOMUX_PULL_UP:
            regval |= PADCTL_EMC_B2_PULL_UP;
            break;

          case IOMUX_PULL_DOWN:
            regval |= PADCTL_EMC_B2_PULL_DOWN;
            break;

          case IOMUX_PULL_NONE:
            regval |= PADCTL_EMC_B2_PULL_NONE;
            break;

          default:
            break;
        }

      /* Select CMOS output or Open Drain output */

      if ((ioset & IOMUX_OPENDRAIN) != 0)
        {
          regval |= PADCTL_EMC_B2_ODE;
        }
      else
        {
          regval &= ~(PADCTL_EMC_B2_ODE);
        }
    }
  else if (padctl <= IMXRT_PADCTL_GPIO_AD_35)
    {
      /* GPIO_AD ************************************************************/

      /* Select slow/fast slew rate */

      if ((ioset & IOMUX_SLEW_FAST) != 0)
        {
          regval |= PADCTL_AD_SRE;
        }
      else
        {
          regval &= ~(PADCTL_AD_SRE);
        }

      /* Select drive strength */

      if ((ioset & IOMUX_DRIVE_MASK) == IOMUX_DRIVE_HIGHSTRENGTH)
        {
          regval |= PADCTL_AD_DSE;
        }
      else
        {
          regval &= ~(PADCTL_AD_DSE);
        }

      /* Handle pull/keep selection */

      switch (ioset & IOMUX_PULL_MASK)
        {
          case IOMUX_PULL_UP:
            regval &= ~(PADCTL_AD_PUS | PADCTL_AD_PUE);
            regval |= (PADCTL_AD_PUE | PADCTL_AD_PULL_UP);
            break;

          case IOMUX_PULL_DOWN:
            regval &= ~(PADCTL_AD_PUS | PADCTL_AD_PUE);
            regval |= (PADCTL_AD_PUE | PADCTL_AD_PULL_DOWN);
            break;

          case IOMUX_PULL_NONE:
            regval &= ~PADCTL_AD_PUE;
            break;

          default:
            break;
        }

      /* Select CMOS output or Open Drain output */

      if ((ioset & IOMUX_OPENDRAIN) != 0)
        {
          regval |= PADCTL_AD_ODE;
        }
      else
        {
          regval &= ~(PADCTL_AD_ODE);
        }
    }
  else if (padctl <= IMXRT_PADCTL_GPIO_SD_B1_05)
    {
      /* GPIO_SD_B1 *********************************************************/

      /* Select drive strength */

      if ((ioset & IOMUX_DRIVE_MASK) == IOMUX_DRIVE_HIGHSTRENGTH)
        {
          regval &= ~(PADCTL_SD_DISP_B1_PDRV);
        }
      else
        {
          regval |= PADCTL_SD_DISP_B1_PDRV;
        }

      /* Handle pull/keep selection */

      regval &= ~(PADCTL_SD_DISP_B1_PULL_MASK);

      switch (ioset & IOMUX_PULL_MASK)
        {
          case IOMUX_PULL_UP:
            regval |= PADCTL_SD_DISP_B1_PULL_UP;
            break;

          case IOMUX_PULL_DOWN:
            regval |= PADCTL_SD_DISP_B1_PULL_DOWN;
            break;

          case IOMUX_PULL_NONE:
            regval |= PADCTL_SD_DISP_B1_PULL_NONE;
            break;

          default:
            break;
        }

      /* Select CMOS output or Open Drain output */

      if ((ioset & IOMUX_OPENDRAIN) != 0)
        {
          regval |= PADCTL_SD_DISP_B1_ODE;
        }
      else
        {
          regval &= ~(PADCTL_SD_DISP_B1_ODE);
        }
    }
  else if (padctl <= IMXRT_PADCTL_GPIO_SD_B2_11)
    {
      /* GPIO_SD_B2 *********************************************************/

      /* Select drive strength */

      if ((ioset & IOMUX_DRIVE_MASK) == IOMUX_DRIVE_HIGHSTRENGTH)
        {
          regval |= PADCTL_SD_B2_PDRV;
        }
      else
        {
          regval &= ~(PADCTL_SD_B2_PDRV);
        }

      /* Handle pull/keep selection */

      regval &= ~(PADCTL_SD_B2_PULL_MASK);

      switch (ioset & IOMUX_PULL_MASK)
        {
          case IOMUX_PULL_UP:
            regval |= PADCTL_SD_B2_PULL_UP;
            break;

          case IOMUX_PULL_DOWN:
            regval |= PADCTL_SD_B2_PULL_DOWN;
            break;

          case IOMUX_PULL_NONE:
            regval |= PADCTL_SD_B2_PULL_NONE;
            break;

          default:
            break;
        }

      /* Select CMOS output or Open Drain output */

      if ((ioset & IOMUX_OPENDRAIN) != 0)
        {
          regval |= PADCTL_SD_B2_ODE;
        }
      else
        {
          regval &= ~(PADCTL_SD_B2_ODE);
        }
    }
  else if (padctl <= IMXRT_PADCTL_GPIO_DISP_B1_11)
    {
      /* GPIO_DISP_B1 *******************************************************/

      /* Select drive strength */

      if ((ioset & IOMUX_DRIVE_MASK) == IOMUX_DRIVE_HIGHSTRENGTH)
        {
          regval &= ~(PADCTL_SD_DISP_B1_PDRV);
        }
      else
        {
          regval |= PADCTL_SD_DISP_B1_PDRV;
        }

      /* Handle pull/keep selection */

      regval &= ~(PADCTL_SD_DISP_B1_PULL_MASK);

      switch (ioset & IOMUX_PULL_MASK)
        {
          case IOMUX_PULL_UP:
            regval |= PADCTL_SD_DISP_B1_PULL_UP;
            break;

          case IOMUX_PULL_DOWN:
            regval |= PADCTL_SD_DISP_B1_PULL_DOWN;
            break;

          case IOMUX_PULL_NONE:
            regval |= PADCTL_SD_DISP_B1_PULL_NONE;
            break;

          default:
            break;
        }

      /* Select CMOS output or Open Drain output */

      if ((ioset & IOMUX_OPENDRAIN) != 0)
        {
          regval |= PADCTL_SD_DISP_B1_ODE;
        }
      else
        {
          regval &= ~(PADCTL_SD_DISP_B1_ODE);
        }
    }
  else if (padctl <= IMXRT_PADCTL_GPIO_DISP_B2_15)
    {
      /* GPIO_DISP_B2 *******************************************************/

      /* Select slow/fast slew rate */

      if ((ioset & IOMUX_SLEW_FAST) != 0)
        {
          regval |= PADCTL_DISP_B2_SRE;
        }
      else
        {
          regval &= ~(PADCTL_DISP_B2_SRE);
        }

      /* Select drive strength */

      if ((ioset & IOMUX_DRIVE_MASK) == IOMUX_DRIVE_HIGHSTRENGTH)
        {
          regval |= PADCTL_DISP_B2_DSE;
        }
      else
        {
          regval &= ~(PADCTL_DISP_B2_DSE);
        }

      /* Handle pull/keep selection */

      switch (ioset & IOMUX_PULL_MASK)
        {
          case IOMUX_PULL_UP:
            regval &= ~(PADCTL_DISP_B2_PUE | PADCTL_DISP_B2_PUS);
            regval |= (PADCTL_DISP_B2_PUE | PADCTL_DISP_B2_PULL_UP);
            break;

          case IOMUX_PULL_DOWN:
            regval &= ~(PADCTL_DISP_B2_PUE | PADCTL_DISP_B2_PUS);
            regval |= (PADCTL_DISP_B2_PUE | PADCTL_DISP_B2_PULL_DOWN);
            break;

          case IOMUX_PULL_NONE:
            regval &= ~PADCTL_DISP_B2_PUE;
            break;

          default:
            break;
        }

      /* Select CMOS output or Open Drain output */

      if ((ioset & IOMUX_OPENDRAIN) != 0)
        {
          regval |= PADCTL_DISP_B2_ODE;
        }
      else
        {
          regval &= ~(PADCTL_DISP_B2_ODE);
        }
    }
  else if (padctl <= IMXRT_PADCTL_GPIO_LPSR_15)
    {
      DEBUGASSERT(padctl >= IMXRT_PADCTL_GPIO_LPSR_00);

      /* GPIO_LPSR **********************************************************/

      /* Select slow/fast slew rate */

      if ((ioset & IOMUX_SLEW_FAST) != 0)
        {
          regval |= PADCTL_LPSR_SRE;
        }
      else
        {
          regval &= ~(PADCTL_LPSR_SRE);
        }

      /* Select drive strength */

      if ((ioset & IOMUX_DRIVE_MASK) == IOMUX_DRIVE_HIGHSTRENGTH)
        {
          regval |= PADCTL_LPSR_DSE;
        }
      else
        {
          regval &= ~(PADCTL_LPSR_DSE);
        }

      /* Handle pull/keep selection */

      switch (ioset & IOMUX_PULL_MASK)
        {
          case IOMUX_PULL_UP:
            regval &= ~(PADCTL_LPSR_PUE | PADCTL_LPSR_PUS);
            regval |= (PADCTL_LPSR_PUE | PADCTL_LPSR_PULL_UP);
            break;

          case IOMUX_PULL_DOWN:
            regval &= ~(PADCTL_LPSR_PUE | PADCTL_LPSR_PUS);
            regval |= (PADCTL_LPSR_PUE | PADCTL_LPSR_PULL_DOWN);
            break;

          case IOMUX_PULL_NONE:
            regval &= ~PADCTL_LPSR_PUE;
            break;

          default:
            break;
        }

      /* Select CMOS output or Open Drain output */

      if ((ioset & IOMUX_OPENDRAIN) != 0)
        {
          regval |= PADCTL_LPSR_ODE;
        }
      else
        {
          regval &= ~(PADCTL_LPSR_ODE);
        }
    }
  else if (padctl <= IMXRT_PADCTL_GPIO_SNVS_09)
    {
      DEBUGASSERT(padctl >= IMXRT_PADCTL_TEST_MODE);

      /* GPIO_SNVS **********************************************************/

      /* Handle pull/keep selection */

      switch (ioset & IOMUX_PULL_MASK)
        {
          case IOMUX_PULL_UP:
            regval &= ~(PADCTL_SNVS_PUE | PADCTL_SNVS_PUS);
            regval |= (PADCTL_SNVS_PUE | PADCTL_SNVS_PULL_UP);
            break;

          case IOMUX_PULL_DOWN:
            regval &= ~(PADCTL_SNVS_PUE | PADCTL_SNVS_PUS);
            regval |= (PADCTL_SNVS_PUE | PADCTL_SNVS_PULL_DOWN);
            break;

          case IOMUX_PULL_NONE:
            regval &= ~PADCTL_SNVS_PUE;
            break;

          default:
            break;
        }

      /* Select CMOS output or Open Drain output */

      if ((ioset & IOMUX_OPENDRAIN) != 0)
        {
          regval |= PADCTL_SNVS_ODE;
        }
      else
        {
          regval &= ~(PADCTL_SNVS_ODE);
        }
    }
  else
    {
      /* We should never get here, unless padctl is not a valid register */

      return ERROR;
    }

  /* Write the result to the specified Pad Control register */

  putreg32(regval, padctl);
  return OK;
}