root/arch/mips/bcm63xx/gpio.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. bcm63xx_gpio_out_low_reg_init
  2. bcm63xx_gpio_set
  3. bcm63xx_gpio_get
  4. bcm63xx_gpio_set_direction
  5. bcm63xx_gpio_direction_input
  6. bcm63xx_gpio_direction_output
  7. bcm63xx_gpio_init

   1 /*
   2  * This file is subject to the terms and conditions of the GNU General Public
   3  * License.  See the file "COPYING" in the main directory of this archive
   4  * for more details.
   5  *
   6  * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
   7  * Copyright (C) 2008-2011 Florian Fainelli <florian@openwrt.org>
   8  */
   9 
  10 #include <linux/kernel.h>
  11 #include <linux/init.h>
  12 #include <linux/spinlock.h>
  13 #include <linux/platform_device.h>
  14 #include <linux/gpio/driver.h>
  15 
  16 #include <bcm63xx_cpu.h>
  17 #include <bcm63xx_gpio.h>
  18 #include <bcm63xx_io.h>
  19 #include <bcm63xx_regs.h>
  20 
  21 static u32 gpio_out_low_reg;
  22 
  23 static void bcm63xx_gpio_out_low_reg_init(void)
  24 {
  25         switch (bcm63xx_get_cpu_id()) {
  26         case BCM6345_CPU_ID:
  27                 gpio_out_low_reg = GPIO_DATA_LO_REG_6345;
  28                 break;
  29         default:
  30                 gpio_out_low_reg = GPIO_DATA_LO_REG;
  31                 break;
  32         }
  33 }
  34 
  35 static DEFINE_SPINLOCK(bcm63xx_gpio_lock);
  36 static u32 gpio_out_low, gpio_out_high;
  37 
  38 static void bcm63xx_gpio_set(struct gpio_chip *chip,
  39                              unsigned gpio, int val)
  40 {
  41         u32 reg;
  42         u32 mask;
  43         u32 *v;
  44         unsigned long flags;
  45 
  46         if (gpio >= chip->ngpio)
  47                 BUG();
  48 
  49         if (gpio < 32) {
  50                 reg = gpio_out_low_reg;
  51                 mask = 1 << gpio;
  52                 v = &gpio_out_low;
  53         } else {
  54                 reg = GPIO_DATA_HI_REG;
  55                 mask = 1 << (gpio - 32);
  56                 v = &gpio_out_high;
  57         }
  58 
  59         spin_lock_irqsave(&bcm63xx_gpio_lock, flags);
  60         if (val)
  61                 *v |= mask;
  62         else
  63                 *v &= ~mask;
  64         bcm_gpio_writel(*v, reg);
  65         spin_unlock_irqrestore(&bcm63xx_gpio_lock, flags);
  66 }
  67 
  68 static int bcm63xx_gpio_get(struct gpio_chip *chip, unsigned gpio)
  69 {
  70         u32 reg;
  71         u32 mask;
  72 
  73         if (gpio >= chip->ngpio)
  74                 BUG();
  75 
  76         if (gpio < 32) {
  77                 reg = gpio_out_low_reg;
  78                 mask = 1 << gpio;
  79         } else {
  80                 reg = GPIO_DATA_HI_REG;
  81                 mask = 1 << (gpio - 32);
  82         }
  83 
  84         return !!(bcm_gpio_readl(reg) & mask);
  85 }
  86 
  87 static int bcm63xx_gpio_set_direction(struct gpio_chip *chip,
  88                                       unsigned gpio, int dir)
  89 {
  90         u32 reg;
  91         u32 mask;
  92         u32 tmp;
  93         unsigned long flags;
  94 
  95         if (gpio >= chip->ngpio)
  96                 BUG();
  97 
  98         if (gpio < 32) {
  99                 reg = GPIO_CTL_LO_REG;
 100                 mask = 1 << gpio;
 101         } else {
 102                 reg = GPIO_CTL_HI_REG;
 103                 mask = 1 << (gpio - 32);
 104         }
 105 
 106         spin_lock_irqsave(&bcm63xx_gpio_lock, flags);
 107         tmp = bcm_gpio_readl(reg);
 108         if (dir == BCM63XX_GPIO_DIR_IN)
 109                 tmp &= ~mask;
 110         else
 111                 tmp |= mask;
 112         bcm_gpio_writel(tmp, reg);
 113         spin_unlock_irqrestore(&bcm63xx_gpio_lock, flags);
 114 
 115         return 0;
 116 }
 117 
 118 static int bcm63xx_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
 119 {
 120         return bcm63xx_gpio_set_direction(chip, gpio, BCM63XX_GPIO_DIR_IN);
 121 }
 122 
 123 static int bcm63xx_gpio_direction_output(struct gpio_chip *chip,
 124                                          unsigned gpio, int value)
 125 {
 126         bcm63xx_gpio_set(chip, gpio, value);
 127         return bcm63xx_gpio_set_direction(chip, gpio, BCM63XX_GPIO_DIR_OUT);
 128 }
 129 
 130 
 131 static struct gpio_chip bcm63xx_gpio_chip = {
 132         .label                  = "bcm63xx-gpio",
 133         .direction_input        = bcm63xx_gpio_direction_input,
 134         .direction_output       = bcm63xx_gpio_direction_output,
 135         .get                    = bcm63xx_gpio_get,
 136         .set                    = bcm63xx_gpio_set,
 137         .base                   = 0,
 138 };
 139 
 140 int __init bcm63xx_gpio_init(void)
 141 {
 142         bcm63xx_gpio_out_low_reg_init();
 143 
 144         gpio_out_low = bcm_gpio_readl(gpio_out_low_reg);
 145         if (!BCMCPU_IS_6345())
 146                 gpio_out_high = bcm_gpio_readl(GPIO_DATA_HI_REG);
 147         bcm63xx_gpio_chip.ngpio = bcm63xx_gpio_count();
 148         pr_info("registering %d GPIOs\n", bcm63xx_gpio_chip.ngpio);
 149 
 150         return gpiochip_add_data(&bcm63xx_gpio_chip, NULL);
 151 }

/* [<][>][^][v][top][bottom][index][help] */