1/* 2 * linux/arch/arm/mach-ep93xx/gpio.c 3 * 4 * Generic EP93xx GPIO handling 5 * 6 * Copyright (c) 2008 Ryan Mallon <ryan@bluewatersys.com> 7 * 8 * Based on code originally from: 9 * linux/arch/arm/mach-ep93xx/core.c 10 * 11 * This program is free software; you can redistribute it and/or modify 12 * it under the terms of the GNU General Public License version 2 as 13 * published by the Free Software Foundation. 14 */ 15 16#define pr_fmt(fmt) "ep93xx " KBUILD_MODNAME ": " fmt 17 18#include <linux/init.h> 19#include <linux/module.h> 20#include <linux/seq_file.h> 21#include <linux/io.h> 22#include <linux/gpio.h> 23#include <linux/irq.h> 24 25#include <mach/hardware.h> 26 27/************************************************************************* 28 * Interrupt handling for EP93xx on-chip GPIOs 29 *************************************************************************/ 30static unsigned char gpio_int_unmasked[3]; 31static unsigned char gpio_int_enabled[3]; 32static unsigned char gpio_int_type1[3]; 33static unsigned char gpio_int_type2[3]; 34static unsigned char gpio_int_debounce[3]; 35 36/* Port ordering is: A B F */ 37static const u8 int_type1_register_offset[3] = { 0x90, 0xac, 0x4c }; 38static const u8 int_type2_register_offset[3] = { 0x94, 0xb0, 0x50 }; 39static const u8 eoi_register_offset[3] = { 0x98, 0xb4, 0x54 }; 40static const u8 int_en_register_offset[3] = { 0x9c, 0xb8, 0x58 }; 41static const u8 int_debounce_register_offset[3] = { 0xa8, 0xc4, 0x64 }; 42 43static void ep93xx_gpio_update_int_params(unsigned port) 44{ 45 BUG_ON(port > 2); 46 47 __raw_writeb(0, EP93XX_GPIO_REG(int_en_register_offset[port])); 48 49 __raw_writeb(gpio_int_type2[port], 50 EP93XX_GPIO_REG(int_type2_register_offset[port])); 51 52 __raw_writeb(gpio_int_type1[port], 53 EP93XX_GPIO_REG(int_type1_register_offset[port])); 54 55 __raw_writeb(gpio_int_unmasked[port] & gpio_int_enabled[port], 56 EP93XX_GPIO_REG(int_en_register_offset[port])); 57} 58 59static inline void ep93xx_gpio_int_mask(unsigned line) 60{ 61 gpio_int_unmasked[line >> 3] &= ~(1 << (line & 7)); 62} 63 64void ep93xx_gpio_int_debounce(unsigned int irq, int enable) 65{ 66 int line = irq_to_gpio(irq); 67 int port = line >> 3; 68 int port_mask = 1 << (line & 7); 69 70 if (enable) 71 gpio_int_debounce[port] |= port_mask; 72 else 73 gpio_int_debounce[port] &= ~port_mask; 74 75 __raw_writeb(gpio_int_debounce[port], 76 EP93XX_GPIO_REG(int_debounce_register_offset[port])); 77} 78EXPORT_SYMBOL(ep93xx_gpio_int_debounce); 79 80static void ep93xx_gpio_ab_irq_handler(unsigned int irq, struct irq_desc *desc) 81{ 82 unsigned char status; 83 int i; 84 85 status = __raw_readb(EP93XX_GPIO_A_INT_STATUS); 86 for (i = 0; i < 8; i++) { 87 if (status & (1 << i)) { 88 int gpio_irq = gpio_to_irq(EP93XX_GPIO_LINE_A(0)) + i; 89 generic_handle_irq(gpio_irq); 90 } 91 } 92 93 status = __raw_readb(EP93XX_GPIO_B_INT_STATUS); 94 for (i = 0; i < 8; i++) { 95 if (status & (1 << i)) { 96 int gpio_irq = gpio_to_irq(EP93XX_GPIO_LINE_B(0)) + i; 97 generic_handle_irq(gpio_irq); 98 } 99 } 100} 101 102static void ep93xx_gpio_f_irq_handler(unsigned int irq, struct irq_desc *desc) 103{ 104 /* 105 * map discontiguous hw irq range to continous sw irq range: 106 * 107 * IRQ_EP93XX_GPIO{0..7}MUX -> gpio_to_irq(EP93XX_GPIO_LINE_F({0..7}) 108 */ 109 int port_f_idx = ((irq + 1) & 7) ^ 4; /* {19..22,47..50} -> {0..7} */ 110 int gpio_irq = gpio_to_irq(EP93XX_GPIO_LINE_F(0)) + port_f_idx; 111 112 generic_handle_irq(gpio_irq); 113} 114 115static void ep93xx_gpio_irq_ack(unsigned int irq) 116{ 117 int line = irq_to_gpio(irq); 118 int port = line >> 3; 119 int port_mask = 1 << (line & 7); 120 121 if ((irq_desc[irq].status & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH) { 122 gpio_int_type2[port] ^= port_mask; /* switch edge direction */ 123 ep93xx_gpio_update_int_params(port); 124 } 125 126 __raw_writeb(port_mask, EP93XX_GPIO_REG(eoi_register_offset[port])); 127} 128 129static void ep93xx_gpio_irq_mask_ack(unsigned int irq) 130{ 131 int line = irq_to_gpio(irq); 132 int port = line >> 3; 133 int port_mask = 1 << (line & 7); 134 135 if ((irq_desc[irq].status & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH) 136 gpio_int_type2[port] ^= port_mask; /* switch edge direction */ 137 138 gpio_int_unmasked[port] &= ~port_mask; 139 ep93xx_gpio_update_int_params(port); 140 141 __raw_writeb(port_mask, EP93XX_GPIO_REG(eoi_register_offset[port])); 142} 143 144static void ep93xx_gpio_irq_mask(unsigned int irq) 145{ 146 int line = irq_to_gpio(irq); 147 int port = line >> 3; 148 149 gpio_int_unmasked[port] &= ~(1 << (line & 7)); 150 ep93xx_gpio_update_int_params(port); 151} 152 153static void ep93xx_gpio_irq_unmask(unsigned int irq) 154{ 155 int line = irq_to_gpio(irq); 156 int port = line >> 3; 157 158 gpio_int_unmasked[port] |= 1 << (line & 7); 159 ep93xx_gpio_update_int_params(port); 160} 161 162/* 163 * gpio_int_type1 controls whether the interrupt is level (0) or 164 * edge (1) triggered, while gpio_int_type2 controls whether it 165 * triggers on low/falling (0) or high/rising (1). 166 */ 167static int ep93xx_gpio_irq_type(unsigned int irq, unsigned int type) 168{ 169 struct irq_desc *desc = irq_desc + irq; 170 const int gpio = irq_to_gpio(irq); 171 const int port = gpio >> 3; 172 const int port_mask = 1 << (gpio & 7); 173 174 gpio_direction_input(gpio); 175 176 switch (type) { 177 case IRQ_TYPE_EDGE_RISING: 178 gpio_int_type1[port] |= port_mask; 179 gpio_int_type2[port] |= port_mask; 180 desc->handle_irq = handle_edge_irq; 181 break; 182 case IRQ_TYPE_EDGE_FALLING: 183 gpio_int_type1[port] |= port_mask; 184 gpio_int_type2[port] &= ~port_mask; 185 desc->handle_irq = handle_edge_irq; 186 break; 187 case IRQ_TYPE_LEVEL_HIGH: 188 gpio_int_type1[port] &= ~port_mask; 189 gpio_int_type2[port] |= port_mask; 190 desc->handle_irq = handle_level_irq; 191 break; 192 case IRQ_TYPE_LEVEL_LOW: 193 gpio_int_type1[port] &= ~port_mask; 194 gpio_int_type2[port] &= ~port_mask; 195 desc->handle_irq = handle_level_irq; 196 break; 197 case IRQ_TYPE_EDGE_BOTH: 198 gpio_int_type1[port] |= port_mask; 199 /* set initial polarity based on current input level */ 200 if (gpio_get_value(gpio)) 201 gpio_int_type2[port] &= ~port_mask; /* falling */ 202 else 203 gpio_int_type2[port] |= port_mask; /* rising */ 204 desc->handle_irq = handle_edge_irq; 205 break; 206 default: 207 pr_err("failed to set irq type %d for gpio %d\n", type, gpio); 208 return -EINVAL; 209 } 210 211 gpio_int_enabled[port] |= port_mask; 212 213 desc->status &= ~IRQ_TYPE_SENSE_MASK; 214 desc->status |= type & IRQ_TYPE_SENSE_MASK; 215 216 ep93xx_gpio_update_int_params(port); 217 218 return 0; 219} 220 221static struct irq_chip ep93xx_gpio_irq_chip = { 222 .name = "GPIO", 223 .ack = ep93xx_gpio_irq_ack, 224 .mask_ack = ep93xx_gpio_irq_mask_ack, 225 .mask = ep93xx_gpio_irq_mask, 226 .unmask = ep93xx_gpio_irq_unmask, 227 .set_type = ep93xx_gpio_irq_type, 228}; 229 230void __init ep93xx_gpio_init_irq(void) 231{ 232 int gpio_irq; 233 234 for (gpio_irq = gpio_to_irq(0); 235 gpio_irq <= gpio_to_irq(EP93XX_GPIO_LINE_MAX_IRQ); ++gpio_irq) { 236 set_irq_chip(gpio_irq, &ep93xx_gpio_irq_chip); 237 set_irq_handler(gpio_irq, handle_level_irq); 238 set_irq_flags(gpio_irq, IRQF_VALID); 239 } 240 241 set_irq_chained_handler(IRQ_EP93XX_GPIO_AB, ep93xx_gpio_ab_irq_handler); 242 set_irq_chained_handler(IRQ_EP93XX_GPIO0MUX, ep93xx_gpio_f_irq_handler); 243 set_irq_chained_handler(IRQ_EP93XX_GPIO1MUX, ep93xx_gpio_f_irq_handler); 244 set_irq_chained_handler(IRQ_EP93XX_GPIO2MUX, ep93xx_gpio_f_irq_handler); 245 set_irq_chained_handler(IRQ_EP93XX_GPIO3MUX, ep93xx_gpio_f_irq_handler); 246 set_irq_chained_handler(IRQ_EP93XX_GPIO4MUX, ep93xx_gpio_f_irq_handler); 247 set_irq_chained_handler(IRQ_EP93XX_GPIO5MUX, ep93xx_gpio_f_irq_handler); 248 set_irq_chained_handler(IRQ_EP93XX_GPIO6MUX, ep93xx_gpio_f_irq_handler); 249 set_irq_chained_handler(IRQ_EP93XX_GPIO7MUX, ep93xx_gpio_f_irq_handler); 250} 251 252 253/************************************************************************* 254 * gpiolib interface for EP93xx on-chip GPIOs 255 *************************************************************************/ 256struct ep93xx_gpio_chip { 257 struct gpio_chip chip; 258 259 void __iomem *data_reg; 260 void __iomem *data_dir_reg; 261}; 262 263#define to_ep93xx_gpio_chip(c) container_of(c, struct ep93xx_gpio_chip, chip) 264 265static int ep93xx_gpio_direction_input(struct gpio_chip *chip, unsigned offset) 266{ 267 struct ep93xx_gpio_chip *ep93xx_chip = to_ep93xx_gpio_chip(chip); 268 unsigned long flags; 269 u8 v; 270 271 local_irq_save(flags); 272 v = __raw_readb(ep93xx_chip->data_dir_reg); 273 v &= ~(1 << offset); 274 __raw_writeb(v, ep93xx_chip->data_dir_reg); 275 local_irq_restore(flags); 276 277 return 0; 278} 279 280static int ep93xx_gpio_direction_output(struct gpio_chip *chip, 281 unsigned offset, int val) 282{ 283 struct ep93xx_gpio_chip *ep93xx_chip = to_ep93xx_gpio_chip(chip); 284 unsigned long flags; 285 int line; 286 u8 v; 287 288 local_irq_save(flags); 289 290 /* Set the value */ 291 v = __raw_readb(ep93xx_chip->data_reg); 292 if (val) 293 v |= (1 << offset); 294 else 295 v &= ~(1 << offset); 296 __raw_writeb(v, ep93xx_chip->data_reg); 297 298 /* Drive as an output */ 299 line = chip->base + offset; 300 if (line <= EP93XX_GPIO_LINE_MAX_IRQ) { 301 /* Ports A/B/F */ 302 ep93xx_gpio_int_mask(line); 303 ep93xx_gpio_update_int_params(line >> 3); 304 } 305 306 v = __raw_readb(ep93xx_chip->data_dir_reg); 307 v |= (1 << offset); 308 __raw_writeb(v, ep93xx_chip->data_dir_reg); 309 310 local_irq_restore(flags); 311 312 return 0; 313} 314 315static int ep93xx_gpio_get(struct gpio_chip *chip, unsigned offset) 316{ 317 struct ep93xx_gpio_chip *ep93xx_chip = to_ep93xx_gpio_chip(chip); 318 319 return !!(__raw_readb(ep93xx_chip->data_reg) & (1 << offset)); 320} 321 322static void ep93xx_gpio_set(struct gpio_chip *chip, unsigned offset, int val) 323{ 324 struct ep93xx_gpio_chip *ep93xx_chip = to_ep93xx_gpio_chip(chip); 325 unsigned long flags; 326 u8 v; 327 328 local_irq_save(flags); 329 v = __raw_readb(ep93xx_chip->data_reg); 330 if (val) 331 v |= (1 << offset); 332 else 333 v &= ~(1 << offset); 334 __raw_writeb(v, ep93xx_chip->data_reg); 335 local_irq_restore(flags); 336} 337 338static void ep93xx_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip) 339{ 340 struct ep93xx_gpio_chip *ep93xx_chip = to_ep93xx_gpio_chip(chip); 341 u8 data_reg, data_dir_reg; 342 int gpio, i; 343 344 data_reg = __raw_readb(ep93xx_chip->data_reg); 345 data_dir_reg = __raw_readb(ep93xx_chip->data_dir_reg); 346 347 gpio = ep93xx_chip->chip.base; 348 for (i = 0; i < chip->ngpio; i++, gpio++) { 349 int is_out = data_dir_reg & (1 << i); 350 351 seq_printf(s, " %s%d gpio-%-3d (%-12s) %s %s", 352 chip->label, i, gpio, 353 gpiochip_is_requested(chip, i) ? : "", 354 is_out ? "out" : "in ", 355 (data_reg & (1 << i)) ? "hi" : "lo"); 356 357 if (!is_out) { 358 int irq = gpio_to_irq(gpio); 359 struct irq_desc *desc = irq_desc + irq; 360 361 if (irq >= 0 && desc->action) { 362 char *trigger; 363 364 switch (desc->status & IRQ_TYPE_SENSE_MASK) { 365 case IRQ_TYPE_NONE: 366 trigger = "(default)"; 367 break; 368 case IRQ_TYPE_EDGE_FALLING: 369 trigger = "edge-falling"; 370 break; 371 case IRQ_TYPE_EDGE_RISING: 372 trigger = "edge-rising"; 373 break; 374 case IRQ_TYPE_EDGE_BOTH: 375 trigger = "edge-both"; 376 break; 377 case IRQ_TYPE_LEVEL_HIGH: 378 trigger = "level-high"; 379 break; 380 case IRQ_TYPE_LEVEL_LOW: 381 trigger = "level-low"; 382 break; 383 default: 384 trigger = "?trigger?"; 385 break; 386 } 387 388 seq_printf(s, " irq-%d %s%s", 389 irq, trigger, 390 (desc->status & IRQ_WAKEUP) 391 ? " wakeup" : ""); 392 } 393 } 394 395 seq_printf(s, "\n"); 396 } 397} 398 399#define EP93XX_GPIO_BANK(name, dr, ddr, base_gpio) \ 400 { \ 401 .chip = { \ 402 .label = name, \ 403 .direction_input = ep93xx_gpio_direction_input, \ 404 .direction_output = ep93xx_gpio_direction_output, \ 405 .get = ep93xx_gpio_get, \ 406 .set = ep93xx_gpio_set, \ 407 .dbg_show = ep93xx_gpio_dbg_show, \ 408 .base = base_gpio, \ 409 .ngpio = 8, \ 410 }, \ 411 .data_reg = EP93XX_GPIO_REG(dr), \ 412 .data_dir_reg = EP93XX_GPIO_REG(ddr), \ 413 } 414 415static struct ep93xx_gpio_chip ep93xx_gpio_banks[] = { 416 EP93XX_GPIO_BANK("A", 0x00, 0x10, 0), 417 EP93XX_GPIO_BANK("B", 0x04, 0x14, 8), 418 EP93XX_GPIO_BANK("C", 0x08, 0x18, 40), 419 EP93XX_GPIO_BANK("D", 0x0c, 0x1c, 24), 420 EP93XX_GPIO_BANK("E", 0x20, 0x24, 32), 421 EP93XX_GPIO_BANK("F", 0x30, 0x34, 16), 422 EP93XX_GPIO_BANK("G", 0x38, 0x3c, 48), 423 EP93XX_GPIO_BANK("H", 0x40, 0x44, 56), 424}; 425 426void __init ep93xx_gpio_init(void) 427{ 428 int i; 429 430 for (i = 0; i < ARRAY_SIZE(ep93xx_gpio_banks); i++) 431 gpiochip_add(&ep93xx_gpio_banks[i].chip); 432} 433