root/arch/mips/ar7/gpio.c

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

DEFINITIONS

This source file includes following definitions.
  1. ar7_gpio_get_value
  2. titan_gpio_get_value
  3. ar7_gpio_set_value
  4. titan_gpio_set_value
  5. ar7_gpio_direction_input
  6. titan_gpio_direction_input
  7. ar7_gpio_direction_output
  8. titan_gpio_direction_output
  9. ar7_gpio_enable_ar7
  10. ar7_gpio_enable_titan
  11. ar7_gpio_enable
  12. ar7_gpio_disable_ar7
  13. ar7_gpio_disable_titan
  14. ar7_gpio_disable
  15. titan_gpio_pinsel
  16. titan_gpio_init
  17. ar7_gpio_init

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  * Copyright (C) 2007 Felix Fietkau <nbd@openwrt.org>
   4  * Copyright (C) 2007 Eugene Konev <ejka@openwrt.org>
   5  * Copyright (C) 2009-2010 Florian Fainelli <florian@openwrt.org>
   6  */
   7 
   8 #include <linux/init.h>
   9 #include <linux/export.h>
  10 #include <linux/gpio.h>
  11 
  12 #include <asm/mach-ar7/ar7.h>
  13 
  14 #define AR7_GPIO_MAX 32
  15 #define TITAN_GPIO_MAX 51
  16 
  17 struct ar7_gpio_chip {
  18         void __iomem            *regs;
  19         struct gpio_chip        chip;
  20 };
  21 
  22 static int ar7_gpio_get_value(struct gpio_chip *chip, unsigned gpio)
  23 {
  24         struct ar7_gpio_chip *gpch = gpiochip_get_data(chip);
  25         void __iomem *gpio_in = gpch->regs + AR7_GPIO_INPUT;
  26 
  27         return !!(readl(gpio_in) & (1 << gpio));
  28 }
  29 
  30 static int titan_gpio_get_value(struct gpio_chip *chip, unsigned gpio)
  31 {
  32         struct ar7_gpio_chip *gpch = gpiochip_get_data(chip);
  33         void __iomem *gpio_in0 = gpch->regs + TITAN_GPIO_INPUT_0;
  34         void __iomem *gpio_in1 = gpch->regs + TITAN_GPIO_INPUT_1;
  35 
  36         return readl(gpio >> 5 ? gpio_in1 : gpio_in0) & (1 << (gpio & 0x1f));
  37 }
  38 
  39 static void ar7_gpio_set_value(struct gpio_chip *chip,
  40                                 unsigned gpio, int value)
  41 {
  42         struct ar7_gpio_chip *gpch = gpiochip_get_data(chip);
  43         void __iomem *gpio_out = gpch->regs + AR7_GPIO_OUTPUT;
  44         unsigned tmp;
  45 
  46         tmp = readl(gpio_out) & ~(1 << gpio);
  47         if (value)
  48                 tmp |= 1 << gpio;
  49         writel(tmp, gpio_out);
  50 }
  51 
  52 static void titan_gpio_set_value(struct gpio_chip *chip,
  53                                 unsigned gpio, int value)
  54 {
  55         struct ar7_gpio_chip *gpch = gpiochip_get_data(chip);
  56         void __iomem *gpio_out0 = gpch->regs + TITAN_GPIO_OUTPUT_0;
  57         void __iomem *gpio_out1 = gpch->regs + TITAN_GPIO_OUTPUT_1;
  58         unsigned tmp;
  59 
  60         tmp = readl(gpio >> 5 ? gpio_out1 : gpio_out0) & ~(1 << (gpio & 0x1f));
  61         if (value)
  62                 tmp |= 1 << (gpio & 0x1f);
  63         writel(tmp, gpio >> 5 ? gpio_out1 : gpio_out0);
  64 }
  65 
  66 static int ar7_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
  67 {
  68         struct ar7_gpio_chip *gpch = gpiochip_get_data(chip);
  69         void __iomem *gpio_dir = gpch->regs + AR7_GPIO_DIR;
  70 
  71         writel(readl(gpio_dir) | (1 << gpio), gpio_dir);
  72 
  73         return 0;
  74 }
  75 
  76 static int titan_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
  77 {
  78         struct ar7_gpio_chip *gpch = gpiochip_get_data(chip);
  79         void __iomem *gpio_dir0 = gpch->regs + TITAN_GPIO_DIR_0;
  80         void __iomem *gpio_dir1 = gpch->regs + TITAN_GPIO_DIR_1;
  81 
  82         if (gpio >= TITAN_GPIO_MAX)
  83                 return -EINVAL;
  84 
  85         writel(readl(gpio >> 5 ? gpio_dir1 : gpio_dir0) | (1 << (gpio & 0x1f)),
  86                         gpio >> 5 ? gpio_dir1 : gpio_dir0);
  87         return 0;
  88 }
  89 
  90 static int ar7_gpio_direction_output(struct gpio_chip *chip,
  91                                         unsigned gpio, int value)
  92 {
  93         struct ar7_gpio_chip *gpch = gpiochip_get_data(chip);
  94         void __iomem *gpio_dir = gpch->regs + AR7_GPIO_DIR;
  95 
  96         ar7_gpio_set_value(chip, gpio, value);
  97         writel(readl(gpio_dir) & ~(1 << gpio), gpio_dir);
  98 
  99         return 0;
 100 }
 101 
 102 static int titan_gpio_direction_output(struct gpio_chip *chip,
 103                                         unsigned gpio, int value)
 104 {
 105         struct ar7_gpio_chip *gpch = gpiochip_get_data(chip);
 106         void __iomem *gpio_dir0 = gpch->regs + TITAN_GPIO_DIR_0;
 107         void __iomem *gpio_dir1 = gpch->regs + TITAN_GPIO_DIR_1;
 108 
 109         if (gpio >= TITAN_GPIO_MAX)
 110                 return -EINVAL;
 111 
 112         titan_gpio_set_value(chip, gpio, value);
 113         writel(readl(gpio >> 5 ? gpio_dir1 : gpio_dir0) & ~(1 <<
 114                 (gpio & 0x1f)), gpio >> 5 ? gpio_dir1 : gpio_dir0);
 115 
 116         return 0;
 117 }
 118 
 119 static struct ar7_gpio_chip ar7_gpio_chip = {
 120         .chip = {
 121                 .label                  = "ar7-gpio",
 122                 .direction_input        = ar7_gpio_direction_input,
 123                 .direction_output       = ar7_gpio_direction_output,
 124                 .set                    = ar7_gpio_set_value,
 125                 .get                    = ar7_gpio_get_value,
 126                 .base                   = 0,
 127                 .ngpio                  = AR7_GPIO_MAX,
 128         }
 129 };
 130 
 131 static struct ar7_gpio_chip titan_gpio_chip = {
 132         .chip = {
 133                 .label                  = "titan-gpio",
 134                 .direction_input        = titan_gpio_direction_input,
 135                 .direction_output       = titan_gpio_direction_output,
 136                 .set                    = titan_gpio_set_value,
 137                 .get                    = titan_gpio_get_value,
 138                 .base                   = 0,
 139                 .ngpio                  = TITAN_GPIO_MAX,
 140         }
 141 };
 142 
 143 static inline int ar7_gpio_enable_ar7(unsigned gpio)
 144 {
 145         void __iomem *gpio_en = ar7_gpio_chip.regs + AR7_GPIO_ENABLE;
 146 
 147         writel(readl(gpio_en) | (1 << gpio), gpio_en);
 148 
 149         return 0;
 150 }
 151 
 152 static inline int ar7_gpio_enable_titan(unsigned gpio)
 153 {
 154         void __iomem *gpio_en0 = titan_gpio_chip.regs  + TITAN_GPIO_ENBL_0;
 155         void __iomem *gpio_en1 = titan_gpio_chip.regs  + TITAN_GPIO_ENBL_1;
 156 
 157         writel(readl(gpio >> 5 ? gpio_en1 : gpio_en0) | (1 << (gpio & 0x1f)),
 158                 gpio >> 5 ? gpio_en1 : gpio_en0);
 159 
 160         return 0;
 161 }
 162 
 163 int ar7_gpio_enable(unsigned gpio)
 164 {
 165         return ar7_is_titan() ? ar7_gpio_enable_titan(gpio) :
 166                                 ar7_gpio_enable_ar7(gpio);
 167 }
 168 EXPORT_SYMBOL(ar7_gpio_enable);
 169 
 170 static inline int ar7_gpio_disable_ar7(unsigned gpio)
 171 {
 172         void __iomem *gpio_en = ar7_gpio_chip.regs + AR7_GPIO_ENABLE;
 173 
 174         writel(readl(gpio_en) & ~(1 << gpio), gpio_en);
 175 
 176         return 0;
 177 }
 178 
 179 static inline int ar7_gpio_disable_titan(unsigned gpio)
 180 {
 181         void __iomem *gpio_en0 = titan_gpio_chip.regs + TITAN_GPIO_ENBL_0;
 182         void __iomem *gpio_en1 = titan_gpio_chip.regs + TITAN_GPIO_ENBL_1;
 183 
 184         writel(readl(gpio >> 5 ? gpio_en1 : gpio_en0) & ~(1 << (gpio & 0x1f)),
 185                         gpio >> 5 ? gpio_en1 : gpio_en0);
 186 
 187         return 0;
 188 }
 189 
 190 int ar7_gpio_disable(unsigned gpio)
 191 {
 192         return ar7_is_titan() ? ar7_gpio_disable_titan(gpio) :
 193                                 ar7_gpio_disable_ar7(gpio);
 194 }
 195 EXPORT_SYMBOL(ar7_gpio_disable);
 196 
 197 struct titan_gpio_cfg {
 198         u32 reg;
 199         u32 shift;
 200         u32 func;
 201 };
 202 
 203 static const struct titan_gpio_cfg titan_gpio_table[] = {
 204         /* reg, start bit, mux value */
 205         {4, 24, 1},
 206         {4, 26, 1},
 207         {4, 28, 1},
 208         {4, 30, 1},
 209         {5, 6, 1},
 210         {5, 8, 1},
 211         {5, 10, 1},
 212         {5, 12, 1},
 213         {7, 14, 3},
 214         {7, 16, 3},
 215         {7, 18, 3},
 216         {7, 20, 3},
 217         {7, 22, 3},
 218         {7, 26, 3},
 219         {7, 28, 3},
 220         {7, 30, 3},
 221         {8, 0, 3},
 222         {8, 2, 3},
 223         {8, 4, 3},
 224         {8, 10, 3},
 225         {8, 14, 3},
 226         {8, 16, 3},
 227         {8, 18, 3},
 228         {8, 20, 3},
 229         {9, 8, 3},
 230         {9, 10, 3},
 231         {9, 12, 3},
 232         {9, 14, 3},
 233         {9, 18, 3},
 234         {9, 20, 3},
 235         {9, 24, 3},
 236         {9, 26, 3},
 237         {9, 28, 3},
 238         {9, 30, 3},
 239         {10, 0, 3},
 240         {10, 2, 3},
 241         {10, 8, 3},
 242         {10, 10, 3},
 243         {10, 12, 3},
 244         {10, 14, 3},
 245         {13, 12, 3},
 246         {13, 14, 3},
 247         {13, 16, 3},
 248         {13, 18, 3},
 249         {13, 24, 3},
 250         {13, 26, 3},
 251         {13, 28, 3},
 252         {13, 30, 3},
 253         {14, 2, 3},
 254         {14, 6, 3},
 255         {14, 8, 3},
 256         {14, 12, 3}
 257 };
 258 
 259 static int titan_gpio_pinsel(unsigned gpio)
 260 {
 261         struct titan_gpio_cfg gpio_cfg;
 262         u32 mux_status, pin_sel_reg, tmp;
 263         void __iomem *pin_sel = (void __iomem *)KSEG1ADDR(AR7_REGS_PINSEL);
 264 
 265         if (gpio >= ARRAY_SIZE(titan_gpio_table))
 266                 return -EINVAL;
 267 
 268         gpio_cfg = titan_gpio_table[gpio];
 269         pin_sel_reg = gpio_cfg.reg - 1;
 270 
 271         mux_status = (readl(pin_sel + pin_sel_reg) >> gpio_cfg.shift) & 0x3;
 272 
 273         /* Check the mux status */
 274         if (!((mux_status == 0) || (mux_status == gpio_cfg.func)))
 275                 return 0;
 276 
 277         /* Set the pin sel value */
 278         tmp = readl(pin_sel + pin_sel_reg);
 279         tmp |= ((gpio_cfg.func & 0x3) << gpio_cfg.shift);
 280         writel(tmp, pin_sel + pin_sel_reg);
 281 
 282         return 0;
 283 }
 284 
 285 /* Perform minimal Titan GPIO configuration */
 286 static void titan_gpio_init(void)
 287 {
 288         unsigned i;
 289 
 290         for (i = 44; i < 48; i++) {
 291                 titan_gpio_pinsel(i);
 292                 ar7_gpio_enable_titan(i);
 293                 titan_gpio_direction_input(&titan_gpio_chip.chip, i);
 294         }
 295 }
 296 
 297 int __init ar7_gpio_init(void)
 298 {
 299         int ret;
 300         struct ar7_gpio_chip *gpch;
 301         unsigned size;
 302 
 303         if (!ar7_is_titan()) {
 304                 gpch = &ar7_gpio_chip;
 305                 size = 0x10;
 306         } else {
 307                 gpch = &titan_gpio_chip;
 308                 size = 0x1f;
 309         }
 310 
 311         gpch->regs = ioremap_nocache(AR7_REGS_GPIO, size);
 312         if (!gpch->regs) {
 313                 printk(KERN_ERR "%s: failed to ioremap regs\n",
 314                                         gpch->chip.label);
 315                 return -ENOMEM;
 316         }
 317 
 318         ret = gpiochip_add_data(&gpch->chip, gpch);
 319         if (ret) {
 320                 printk(KERN_ERR "%s: failed to add gpiochip\n",
 321                                         gpch->chip.label);
 322                 return ret;
 323         }
 324         printk(KERN_INFO "%s: registered %d GPIOs\n",
 325                                 gpch->chip.label, gpch->chip.ngpio);
 326 
 327         if (ar7_is_titan())
 328                 titan_gpio_init();
 329 
 330         return ret;
 331 }

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