uboot/drivers/gpio/mxs_gpio.c
<<
>>
Prefs
   1/*
   2 * Freescale i.MX28 GPIO control code
   3 *
   4 * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com>
   5 * on behalf of DENX Software Engineering GmbH
   6 *
   7 * SPDX-License-Identifier:     GPL-2.0+
   8 */
   9
  10#include <common.h>
  11#include <netdev.h>
  12#include <asm/errno.h>
  13#include <asm/io.h>
  14#include <asm/arch/iomux.h>
  15#include <asm/arch/imx-regs.h>
  16
  17#if     defined(CONFIG_MX23)
  18#define PINCTRL_BANKS           3
  19#define PINCTRL_DOUT(n)         (0x0500 + ((n) * 0x10))
  20#define PINCTRL_DIN(n)          (0x0600 + ((n) * 0x10))
  21#define PINCTRL_DOE(n)          (0x0700 + ((n) * 0x10))
  22#define PINCTRL_PIN2IRQ(n)      (0x0800 + ((n) * 0x10))
  23#define PINCTRL_IRQEN(n)        (0x0900 + ((n) * 0x10))
  24#define PINCTRL_IRQSTAT(n)      (0x0c00 + ((n) * 0x10))
  25#elif   defined(CONFIG_MX28)
  26#define PINCTRL_BANKS           5
  27#define PINCTRL_DOUT(n)         (0x0700 + ((n) * 0x10))
  28#define PINCTRL_DIN(n)          (0x0900 + ((n) * 0x10))
  29#define PINCTRL_DOE(n)          (0x0b00 + ((n) * 0x10))
  30#define PINCTRL_PIN2IRQ(n)      (0x1000 + ((n) * 0x10))
  31#define PINCTRL_IRQEN(n)        (0x1100 + ((n) * 0x10))
  32#define PINCTRL_IRQSTAT(n)      (0x1400 + ((n) * 0x10))
  33#else
  34#error "Please select CONFIG_MX23 or CONFIG_MX28"
  35#endif
  36
  37#define GPIO_INT_FALL_EDGE      0x0
  38#define GPIO_INT_LOW_LEV        0x1
  39#define GPIO_INT_RISE_EDGE      0x2
  40#define GPIO_INT_HIGH_LEV       0x3
  41#define GPIO_INT_LEV_MASK       (1 << 0)
  42#define GPIO_INT_POL_MASK       (1 << 1)
  43
  44void mxs_gpio_init(void)
  45{
  46        int i;
  47
  48        for (i = 0; i < PINCTRL_BANKS; i++) {
  49                writel(0, MXS_PINCTRL_BASE + PINCTRL_PIN2IRQ(i));
  50                writel(0, MXS_PINCTRL_BASE + PINCTRL_IRQEN(i));
  51                /* Use SCT address here to clear the IRQSTAT bits */
  52                writel(0xffffffff, MXS_PINCTRL_BASE + PINCTRL_IRQSTAT(i) + 8);
  53        }
  54}
  55
  56int gpio_get_value(unsigned gpio)
  57{
  58        uint32_t bank = PAD_BANK(gpio);
  59        uint32_t offset = PINCTRL_DIN(bank);
  60        struct mxs_register_32 *reg =
  61                (struct mxs_register_32 *)(MXS_PINCTRL_BASE + offset);
  62
  63        return (readl(&reg->reg) >> PAD_PIN(gpio)) & 1;
  64}
  65
  66void gpio_set_value(unsigned gpio, int value)
  67{
  68        uint32_t bank = PAD_BANK(gpio);
  69        uint32_t offset = PINCTRL_DOUT(bank);
  70        struct mxs_register_32 *reg =
  71                (struct mxs_register_32 *)(MXS_PINCTRL_BASE + offset);
  72
  73        if (value)
  74                writel(1 << PAD_PIN(gpio), &reg->reg_set);
  75        else
  76                writel(1 << PAD_PIN(gpio), &reg->reg_clr);
  77}
  78
  79int gpio_direction_input(unsigned gpio)
  80{
  81        uint32_t bank = PAD_BANK(gpio);
  82        uint32_t offset = PINCTRL_DOE(bank);
  83        struct mxs_register_32 *reg =
  84                (struct mxs_register_32 *)(MXS_PINCTRL_BASE + offset);
  85
  86        writel(1 << PAD_PIN(gpio), &reg->reg_clr);
  87
  88        return 0;
  89}
  90
  91int gpio_direction_output(unsigned gpio, int value)
  92{
  93        uint32_t bank = PAD_BANK(gpio);
  94        uint32_t offset = PINCTRL_DOE(bank);
  95        struct mxs_register_32 *reg =
  96                (struct mxs_register_32 *)(MXS_PINCTRL_BASE + offset);
  97
  98        gpio_set_value(gpio, value);
  99
 100        writel(1 << PAD_PIN(gpio), &reg->reg_set);
 101
 102        return 0;
 103}
 104
 105int gpio_request(unsigned gpio, const char *label)
 106{
 107        if (PAD_BANK(gpio) >= PINCTRL_BANKS)
 108                return -1;
 109
 110        return 0;
 111}
 112
 113int gpio_free(unsigned gpio)
 114{
 115        return 0;
 116}
 117