0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/init.h>
0009 #include <linux/export.h>
0010 #include <linux/gpio.h>
0011
0012 #include <asm/mach-ar7/ar7.h>
0013
0014 #define AR7_GPIO_MAX 32
0015 #define TITAN_GPIO_MAX 51
0016
0017 struct ar7_gpio_chip {
0018 void __iomem *regs;
0019 struct gpio_chip chip;
0020 };
0021
0022 static int ar7_gpio_get_value(struct gpio_chip *chip, unsigned gpio)
0023 {
0024 struct ar7_gpio_chip *gpch = gpiochip_get_data(chip);
0025 void __iomem *gpio_in = gpch->regs + AR7_GPIO_INPUT;
0026
0027 return !!(readl(gpio_in) & (1 << gpio));
0028 }
0029
0030 static int titan_gpio_get_value(struct gpio_chip *chip, unsigned gpio)
0031 {
0032 struct ar7_gpio_chip *gpch = gpiochip_get_data(chip);
0033 void __iomem *gpio_in0 = gpch->regs + TITAN_GPIO_INPUT_0;
0034 void __iomem *gpio_in1 = gpch->regs + TITAN_GPIO_INPUT_1;
0035
0036 return readl(gpio >> 5 ? gpio_in1 : gpio_in0) & (1 << (gpio & 0x1f));
0037 }
0038
0039 static void ar7_gpio_set_value(struct gpio_chip *chip,
0040 unsigned gpio, int value)
0041 {
0042 struct ar7_gpio_chip *gpch = gpiochip_get_data(chip);
0043 void __iomem *gpio_out = gpch->regs + AR7_GPIO_OUTPUT;
0044 unsigned tmp;
0045
0046 tmp = readl(gpio_out) & ~(1 << gpio);
0047 if (value)
0048 tmp |= 1 << gpio;
0049 writel(tmp, gpio_out);
0050 }
0051
0052 static void titan_gpio_set_value(struct gpio_chip *chip,
0053 unsigned gpio, int value)
0054 {
0055 struct ar7_gpio_chip *gpch = gpiochip_get_data(chip);
0056 void __iomem *gpio_out0 = gpch->regs + TITAN_GPIO_OUTPUT_0;
0057 void __iomem *gpio_out1 = gpch->regs + TITAN_GPIO_OUTPUT_1;
0058 unsigned tmp;
0059
0060 tmp = readl(gpio >> 5 ? gpio_out1 : gpio_out0) & ~(1 << (gpio & 0x1f));
0061 if (value)
0062 tmp |= 1 << (gpio & 0x1f);
0063 writel(tmp, gpio >> 5 ? gpio_out1 : gpio_out0);
0064 }
0065
0066 static int ar7_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
0067 {
0068 struct ar7_gpio_chip *gpch = gpiochip_get_data(chip);
0069 void __iomem *gpio_dir = gpch->regs + AR7_GPIO_DIR;
0070
0071 writel(readl(gpio_dir) | (1 << gpio), gpio_dir);
0072
0073 return 0;
0074 }
0075
0076 static int titan_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
0077 {
0078 struct ar7_gpio_chip *gpch = gpiochip_get_data(chip);
0079 void __iomem *gpio_dir0 = gpch->regs + TITAN_GPIO_DIR_0;
0080 void __iomem *gpio_dir1 = gpch->regs + TITAN_GPIO_DIR_1;
0081
0082 if (gpio >= TITAN_GPIO_MAX)
0083 return -EINVAL;
0084
0085 writel(readl(gpio >> 5 ? gpio_dir1 : gpio_dir0) | (1 << (gpio & 0x1f)),
0086 gpio >> 5 ? gpio_dir1 : gpio_dir0);
0087 return 0;
0088 }
0089
0090 static int ar7_gpio_direction_output(struct gpio_chip *chip,
0091 unsigned gpio, int value)
0092 {
0093 struct ar7_gpio_chip *gpch = gpiochip_get_data(chip);
0094 void __iomem *gpio_dir = gpch->regs + AR7_GPIO_DIR;
0095
0096 ar7_gpio_set_value(chip, gpio, value);
0097 writel(readl(gpio_dir) & ~(1 << gpio), gpio_dir);
0098
0099 return 0;
0100 }
0101
0102 static int titan_gpio_direction_output(struct gpio_chip *chip,
0103 unsigned gpio, int value)
0104 {
0105 struct ar7_gpio_chip *gpch = gpiochip_get_data(chip);
0106 void __iomem *gpio_dir0 = gpch->regs + TITAN_GPIO_DIR_0;
0107 void __iomem *gpio_dir1 = gpch->regs + TITAN_GPIO_DIR_1;
0108
0109 if (gpio >= TITAN_GPIO_MAX)
0110 return -EINVAL;
0111
0112 titan_gpio_set_value(chip, gpio, value);
0113 writel(readl(gpio >> 5 ? gpio_dir1 : gpio_dir0) & ~(1 <<
0114 (gpio & 0x1f)), gpio >> 5 ? gpio_dir1 : gpio_dir0);
0115
0116 return 0;
0117 }
0118
0119 static struct ar7_gpio_chip ar7_gpio_chip = {
0120 .chip = {
0121 .label = "ar7-gpio",
0122 .direction_input = ar7_gpio_direction_input,
0123 .direction_output = ar7_gpio_direction_output,
0124 .set = ar7_gpio_set_value,
0125 .get = ar7_gpio_get_value,
0126 .base = 0,
0127 .ngpio = AR7_GPIO_MAX,
0128 }
0129 };
0130
0131 static struct ar7_gpio_chip titan_gpio_chip = {
0132 .chip = {
0133 .label = "titan-gpio",
0134 .direction_input = titan_gpio_direction_input,
0135 .direction_output = titan_gpio_direction_output,
0136 .set = titan_gpio_set_value,
0137 .get = titan_gpio_get_value,
0138 .base = 0,
0139 .ngpio = TITAN_GPIO_MAX,
0140 }
0141 };
0142
0143 static inline int ar7_gpio_enable_ar7(unsigned gpio)
0144 {
0145 void __iomem *gpio_en = ar7_gpio_chip.regs + AR7_GPIO_ENABLE;
0146
0147 writel(readl(gpio_en) | (1 << gpio), gpio_en);
0148
0149 return 0;
0150 }
0151
0152 static inline int ar7_gpio_enable_titan(unsigned gpio)
0153 {
0154 void __iomem *gpio_en0 = titan_gpio_chip.regs + TITAN_GPIO_ENBL_0;
0155 void __iomem *gpio_en1 = titan_gpio_chip.regs + TITAN_GPIO_ENBL_1;
0156
0157 writel(readl(gpio >> 5 ? gpio_en1 : gpio_en0) | (1 << (gpio & 0x1f)),
0158 gpio >> 5 ? gpio_en1 : gpio_en0);
0159
0160 return 0;
0161 }
0162
0163 int ar7_gpio_enable(unsigned gpio)
0164 {
0165 return ar7_is_titan() ? ar7_gpio_enable_titan(gpio) :
0166 ar7_gpio_enable_ar7(gpio);
0167 }
0168 EXPORT_SYMBOL(ar7_gpio_enable);
0169
0170 static inline int ar7_gpio_disable_ar7(unsigned gpio)
0171 {
0172 void __iomem *gpio_en = ar7_gpio_chip.regs + AR7_GPIO_ENABLE;
0173
0174 writel(readl(gpio_en) & ~(1 << gpio), gpio_en);
0175
0176 return 0;
0177 }
0178
0179 static inline int ar7_gpio_disable_titan(unsigned gpio)
0180 {
0181 void __iomem *gpio_en0 = titan_gpio_chip.regs + TITAN_GPIO_ENBL_0;
0182 void __iomem *gpio_en1 = titan_gpio_chip.regs + TITAN_GPIO_ENBL_1;
0183
0184 writel(readl(gpio >> 5 ? gpio_en1 : gpio_en0) & ~(1 << (gpio & 0x1f)),
0185 gpio >> 5 ? gpio_en1 : gpio_en0);
0186
0187 return 0;
0188 }
0189
0190 int ar7_gpio_disable(unsigned gpio)
0191 {
0192 return ar7_is_titan() ? ar7_gpio_disable_titan(gpio) :
0193 ar7_gpio_disable_ar7(gpio);
0194 }
0195 EXPORT_SYMBOL(ar7_gpio_disable);
0196
0197 struct titan_gpio_cfg {
0198 u32 reg;
0199 u32 shift;
0200 u32 func;
0201 };
0202
0203 static const struct titan_gpio_cfg titan_gpio_table[] = {
0204
0205 {4, 24, 1},
0206 {4, 26, 1},
0207 {4, 28, 1},
0208 {4, 30, 1},
0209 {5, 6, 1},
0210 {5, 8, 1},
0211 {5, 10, 1},
0212 {5, 12, 1},
0213 {7, 14, 3},
0214 {7, 16, 3},
0215 {7, 18, 3},
0216 {7, 20, 3},
0217 {7, 22, 3},
0218 {7, 26, 3},
0219 {7, 28, 3},
0220 {7, 30, 3},
0221 {8, 0, 3},
0222 {8, 2, 3},
0223 {8, 4, 3},
0224 {8, 10, 3},
0225 {8, 14, 3},
0226 {8, 16, 3},
0227 {8, 18, 3},
0228 {8, 20, 3},
0229 {9, 8, 3},
0230 {9, 10, 3},
0231 {9, 12, 3},
0232 {9, 14, 3},
0233 {9, 18, 3},
0234 {9, 20, 3},
0235 {9, 24, 3},
0236 {9, 26, 3},
0237 {9, 28, 3},
0238 {9, 30, 3},
0239 {10, 0, 3},
0240 {10, 2, 3},
0241 {10, 8, 3},
0242 {10, 10, 3},
0243 {10, 12, 3},
0244 {10, 14, 3},
0245 {13, 12, 3},
0246 {13, 14, 3},
0247 {13, 16, 3},
0248 {13, 18, 3},
0249 {13, 24, 3},
0250 {13, 26, 3},
0251 {13, 28, 3},
0252 {13, 30, 3},
0253 {14, 2, 3},
0254 {14, 6, 3},
0255 {14, 8, 3},
0256 {14, 12, 3}
0257 };
0258
0259 static int titan_gpio_pinsel(unsigned gpio)
0260 {
0261 struct titan_gpio_cfg gpio_cfg;
0262 u32 mux_status, pin_sel_reg, tmp;
0263 void __iomem *pin_sel = (void __iomem *)KSEG1ADDR(AR7_REGS_PINSEL);
0264
0265 if (gpio >= ARRAY_SIZE(titan_gpio_table))
0266 return -EINVAL;
0267
0268 gpio_cfg = titan_gpio_table[gpio];
0269 pin_sel_reg = gpio_cfg.reg - 1;
0270
0271 mux_status = (readl(pin_sel + pin_sel_reg) >> gpio_cfg.shift) & 0x3;
0272
0273
0274 if (!((mux_status == 0) || (mux_status == gpio_cfg.func)))
0275 return 0;
0276
0277
0278 tmp = readl(pin_sel + pin_sel_reg);
0279 tmp |= ((gpio_cfg.func & 0x3) << gpio_cfg.shift);
0280 writel(tmp, pin_sel + pin_sel_reg);
0281
0282 return 0;
0283 }
0284
0285
0286 static void titan_gpio_init(void)
0287 {
0288 unsigned i;
0289
0290 for (i = 44; i < 48; i++) {
0291 titan_gpio_pinsel(i);
0292 ar7_gpio_enable_titan(i);
0293 titan_gpio_direction_input(&titan_gpio_chip.chip, i);
0294 }
0295 }
0296
0297 int __init ar7_gpio_init(void)
0298 {
0299 int ret;
0300 struct ar7_gpio_chip *gpch;
0301 unsigned size;
0302
0303 if (!ar7_is_titan()) {
0304 gpch = &ar7_gpio_chip;
0305 size = 0x10;
0306 } else {
0307 gpch = &titan_gpio_chip;
0308 size = 0x1f;
0309 }
0310
0311 gpch->regs = ioremap(AR7_REGS_GPIO, size);
0312 if (!gpch->regs) {
0313 printk(KERN_ERR "%s: failed to ioremap regs\n",
0314 gpch->chip.label);
0315 return -ENOMEM;
0316 }
0317
0318 ret = gpiochip_add_data(&gpch->chip, gpch);
0319 if (ret) {
0320 printk(KERN_ERR "%s: failed to add gpiochip\n",
0321 gpch->chip.label);
0322 iounmap(gpch->regs);
0323 return ret;
0324 }
0325 printk(KERN_INFO "%s: registered %d GPIOs\n",
0326 gpch->chip.label, gpch->chip.ngpio);
0327
0328 if (ar7_is_titan())
0329 titan_gpio_init();
0330
0331 return ret;
0332 }