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 <linux/errno.h>
  12#include <asm/io.h>
  13#include <asm/arch/iomux.h>
  14#include <asm/arch/imx-regs.h>
  15
  16#if     defined(CONFIG_MX23)
  17#define PINCTRL_BANKS           3
  18#define PINCTRL_DOUT(n)         (0x0500 + ((n) * 0x10))
  19#define PINCTRL_DIN(n)          (0x0600 + ((n) * 0x10))
  20#define PINCTRL_DOE(n)          (0x0700 + ((n) * 0x10))
  21#define PINCTRL_PIN2IRQ(n)      (0x0800 + ((n) * 0x10))
  22#define PINCTRL_IRQEN(n)        (0x0900 + ((n) * 0x10))
  23#define PINCTRL_IRQSTAT(n)      (0x0c00 + ((n) * 0x10))
  24#elif   defined(CONFIG_MX28)
  25#define PINCTRL_BANKS           5
  26#define PINCTRL_DOUT(n)         (0x0700 + ((n) * 0x10))
  27#define PINCTRL_DIN(n)          (0x0900 + ((n) * 0x10))
  28#define PINCTRL_DOE(n)          (0x0b00 + ((n) * 0x10))
  29#define PINCTRL_PIN2IRQ(n)      (0x1000 + ((n) * 0x10))
  30#define PINCTRL_IRQEN(n)        (0x1100 + ((n) * 0x10))
  31#define PINCTRL_IRQSTAT(n)      (0x1400 + ((n) * 0x10))
  32#else
  33#error "Please select CONFIG_MX23 or CONFIG_MX28"
  34#endif
  35
  36#define GPIO_INT_FALL_EDGE      0x0
  37#define GPIO_INT_LOW_LEV        0x1
  38#define GPIO_INT_RISE_EDGE      0x2
  39#define GPIO_INT_HIGH_LEV       0x3
  40#define GPIO_INT_LEV_MASK       (1 << 0)
  41#define GPIO_INT_POL_MASK       (1 << 1)
  42
  43void mxs_gpio_init(void)
  44{
  45        int i;
  46
  47        for (i = 0; i < PINCTRL_BANKS; i++) {
  48                writel(0, MXS_PINCTRL_BASE + PINCTRL_PIN2IRQ(i));
  49                writel(0, MXS_PINCTRL_BASE + PINCTRL_IRQEN(i));
  50                /* Use SCT address here to clear the IRQSTAT bits */
  51                writel(0xffffffff, MXS_PINCTRL_BASE + PINCTRL_IRQSTAT(i) + 8);
  52        }
  53}
  54
  55int gpio_get_value(unsigned gpio)
  56{
  57        uint32_t bank = PAD_BANK(gpio);
  58        uint32_t offset = PINCTRL_DIN(bank);
  59        struct mxs_register_32 *reg =
  60                (struct mxs_register_32 *)(MXS_PINCTRL_BASE + offset);
  61
  62        return (readl(&reg->reg) >> PAD_PIN(gpio)) & 1;
  63}
  64
  65void gpio_set_value(unsigned gpio, int value)
  66{
  67        uint32_t bank = PAD_BANK(gpio);
  68        uint32_t offset = PINCTRL_DOUT(bank);
  69        struct mxs_register_32 *reg =
  70                (struct mxs_register_32 *)(MXS_PINCTRL_BASE + offset);
  71
  72        if (value)
  73                writel(1 << PAD_PIN(gpio), &reg->reg_set);
  74        else
  75                writel(1 << PAD_PIN(gpio), &reg->reg_clr);
  76}
  77
  78int gpio_direction_input(unsigned gpio)
  79{
  80        uint32_t bank = PAD_BANK(gpio);
  81        uint32_t offset = PINCTRL_DOE(bank);
  82        struct mxs_register_32 *reg =
  83                (struct mxs_register_32 *)(MXS_PINCTRL_BASE + offset);
  84
  85        writel(1 << PAD_PIN(gpio), &reg->reg_clr);
  86
  87        return 0;
  88}
  89
  90int gpio_direction_output(unsigned gpio, int value)
  91{
  92        uint32_t bank = PAD_BANK(gpio);
  93        uint32_t offset = PINCTRL_DOE(bank);
  94        struct mxs_register_32 *reg =
  95                (struct mxs_register_32 *)(MXS_PINCTRL_BASE + offset);
  96
  97        gpio_set_value(gpio, value);
  98
  99        writel(1 << PAD_PIN(gpio), &reg->reg_set);
 100
 101        return 0;
 102}
 103
 104int gpio_request(unsigned gpio, const char *label)
 105{
 106        if (PAD_BANK(gpio) >= PINCTRL_BANKS)
 107                return -1;
 108
 109        return 0;
 110}
 111
 112int gpio_free(unsigned gpio)
 113{
 114        return 0;
 115}
 116
 117int name_to_gpio(const char *name)
 118{
 119        unsigned bank, pin;
 120        char *end;
 121
 122        bank = simple_strtoul(name, &end, 10);
 123
 124        if (!*end || *end != ':')
 125                return bank;
 126
 127        pin = simple_strtoul(end + 1, NULL, 10);
 128
 129        return (bank << MXS_PAD_BANK_SHIFT) | (pin << MXS_PAD_PIN_SHIFT);
 130}
 131