1/* 2 * File: arch/blackfin/kernel/bfin_gpio.c 3 * Based on: 4 * Author: Michael Hennerich (hennerich@blackfin.uclinux.org) 5 * 6 * Created: 7 * Description: GPIO Abstraction Layer 8 * 9 * Modified: 10 * Copyright 2006 Analog Devices Inc. 11 * 12 * Bugs: Enter bugs at http://blackfin.uclinux.org/ 13 * 14 * This program is free software; you can redistribute it and/or modify 15 * it under the terms of the GNU General Public License as published by 16 * the Free Software Foundation; either version 2 of the License, or 17 * (at your option) any later version. 18 * 19 * This program is distributed in the hope that it will be useful, 20 * but WITHOUT ANY WARRANTY; without even the implied warranty of 21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22 * GNU General Public License for more details. 23 * 24 * You should have received a copy of the GNU General Public License 25 * along with this program; if not, see the file COPYING, or write 26 * to the Free Software Foundation, Inc., 27 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 28 */ 29 30/* 31* Number BF537/6/4 BF561 BF533/2/1 32* 33* GPIO_0 PF0 PF0 PF0 34* GPIO_1 PF1 PF1 PF1 35* GPIO_2 PF2 PF2 PF2 36* GPIO_3 PF3 PF3 PF3 37* GPIO_4 PF4 PF4 PF4 38* GPIO_5 PF5 PF5 PF5 39* GPIO_6 PF6 PF6 PF6 40* GPIO_7 PF7 PF7 PF7 41* GPIO_8 PF8 PF8 PF8 42* GPIO_9 PF9 PF9 PF9 43* GPIO_10 PF10 PF10 PF10 44* GPIO_11 PF11 PF11 PF11 45* GPIO_12 PF12 PF12 PF12 46* GPIO_13 PF13 PF13 PF13 47* GPIO_14 PF14 PF14 PF14 48* GPIO_15 PF15 PF15 PF15 49* GPIO_16 PG0 PF16 50* GPIO_17 PG1 PF17 51* GPIO_18 PG2 PF18 52* GPIO_19 PG3 PF19 53* GPIO_20 PG4 PF20 54* GPIO_21 PG5 PF21 55* GPIO_22 PG6 PF22 56* GPIO_23 PG7 PF23 57* GPIO_24 PG8 PF24 58* GPIO_25 PG9 PF25 59* GPIO_26 PG10 PF26 60* GPIO_27 PG11 PF27 61* GPIO_28 PG12 PF28 62* GPIO_29 PG13 PF29 63* GPIO_30 PG14 PF30 64* GPIO_31 PG15 PF31 65* GPIO_32 PH0 PF32 66* GPIO_33 PH1 PF33 67* GPIO_34 PH2 PF34 68* GPIO_35 PH3 PF35 69* GPIO_36 PH4 PF36 70* GPIO_37 PH5 PF37 71* GPIO_38 PH6 PF38 72* GPIO_39 PH7 PF39 73* GPIO_40 PH8 PF40 74* GPIO_41 PH9 PF41 75* GPIO_42 PH10 PF42 76* GPIO_43 PH11 PF43 77* GPIO_44 PH12 PF44 78* GPIO_45 PH13 PF45 79* GPIO_46 PH14 PF46 80* GPIO_47 PH15 PF47 81*/ 82 83#include <linux/module.h> 84#include <linux/err.h> 85#include <asm/blackfin.h> 86#include <asm/gpio.h> 87#include <linux/irq.h> 88 89#ifdef BF533_FAMILY 90static struct gpio_port_t *gpio_bankb[gpio_bank(MAX_BLACKFIN_GPIOS)] = { 91 (struct gpio_port_t *) FIO_FLAG_D, 92}; 93#endif 94 95#ifdef BF537_FAMILY 96static struct gpio_port_t *gpio_bankb[gpio_bank(MAX_BLACKFIN_GPIOS)] = { 97 (struct gpio_port_t *) PORTFIO, 98 (struct gpio_port_t *) PORTGIO, 99 (struct gpio_port_t *) PORTHIO, 100}; 101 102static unsigned short *port_fer[gpio_bank(MAX_BLACKFIN_GPIOS)] = { 103 (unsigned short *) PORTF_FER, 104 (unsigned short *) PORTG_FER, 105 (unsigned short *) PORTH_FER, 106}; 107 108#endif 109 110#ifdef BF561_FAMILY 111static struct gpio_port_t *gpio_bankb[gpio_bank(MAX_BLACKFIN_GPIOS)] = { 112 (struct gpio_port_t *) FIO0_FLAG_D, 113 (struct gpio_port_t *) FIO1_FLAG_D, 114 (struct gpio_port_t *) FIO2_FLAG_D, 115}; 116#endif 117 118static unsigned short reserved_map[gpio_bank(MAX_BLACKFIN_GPIOS)]; 119 120#ifdef CONFIG_PM 121static unsigned short wakeup_map[gpio_bank(MAX_BLACKFIN_GPIOS)]; 122static unsigned char wakeup_flags_map[MAX_BLACKFIN_GPIOS]; 123static struct gpio_port_s gpio_bank_saved[gpio_bank(MAX_BLACKFIN_GPIOS)]; 124 125#ifdef BF533_FAMILY 126static unsigned int sic_iwr_irqs[gpio_bank(MAX_BLACKFIN_GPIOS)] = {IRQ_PROG_INTB}; 127#endif 128 129#ifdef BF537_FAMILY 130static unsigned int sic_iwr_irqs[gpio_bank(MAX_BLACKFIN_GPIOS)] = {IRQ_PROG_INTB, IRQ_PORTG_INTB, IRQ_MAC_TX}; 131#endif 132 133#ifdef BF561_FAMILY 134static unsigned int sic_iwr_irqs[gpio_bank(MAX_BLACKFIN_GPIOS)] = {IRQ_PROG0_INTB, IRQ_PROG1_INTB, IRQ_PROG2_INTB}; 135#endif 136 137#endif /* CONFIG_PM */ 138 139inline int check_gpio(unsigned short gpio) 140{ 141 if (gpio >= MAX_BLACKFIN_GPIOS) 142 return -EINVAL; 143 return 0; 144} 145 146#ifdef BF537_FAMILY 147static void port_setup(unsigned short gpio, unsigned short usage) 148{ 149 if (usage == GPIO_USAGE) { 150 if (*port_fer[gpio_bank(gpio)] & gpio_bit(gpio)) 151 printk(KERN_WARNING "bfin-gpio: Possible Conflict with Peripheral " 152 "usage and GPIO %d detected!\n", gpio); 153 *port_fer[gpio_bank(gpio)] &= ~gpio_bit(gpio); 154 } else 155 *port_fer[gpio_bank(gpio)] |= gpio_bit(gpio); 156 SSYNC(); 157} 158#else 159# define port_setup(...) do { } while (0) 160#endif 161 162 163static void default_gpio(unsigned short gpio) 164{ 165 unsigned short bank,bitmask; 166 167 bank = gpio_bank(gpio); 168 bitmask = gpio_bit(gpio); 169 170 gpio_bankb[bank]->maska_clear = bitmask; 171 gpio_bankb[bank]->maskb_clear = bitmask; 172 SSYNC(); 173 gpio_bankb[bank]->inen &= ~bitmask; 174 gpio_bankb[bank]->dir &= ~bitmask; 175 gpio_bankb[bank]->polar &= ~bitmask; 176 gpio_bankb[bank]->both &= ~bitmask; 177 gpio_bankb[bank]->edge &= ~bitmask; 178} 179 180static int __init bfin_gpio_init(void) 181{ 182 int i; 183 184 printk(KERN_INFO "Blackfin GPIO Controller\n"); 185 186 for (i = 0; i < MAX_BLACKFIN_GPIOS; i+=GPIO_BANKSIZE) 187 reserved_map[gpio_bank(i)] = 0; 188 189#if defined(BF537_FAMILY) && (defined(CONFIG_BFIN_MAC) || \ 190 defined(CONFIG_BFIN_MAC_MODULE)) 191# if defined(CONFIG_BFIN_MAC_RMII) 192 reserved_map[gpio_bank(PORT_H)] = 0xC373; 193# else 194 reserved_map[gpio_bank(PORT_H)] = 0xFFFF; 195# endif 196#endif 197 198 return 0; 199} 200 201arch_initcall(bfin_gpio_init); 202 203 204/*********************************************************** 205* 206* FUNCTIONS: Blackfin General Purpose Ports Access Functions 207* 208* INPUTS/OUTPUTS: 209* gpio - GPIO Number between 0 and MAX_BLACKFIN_GPIOS 210* 211* 212* DESCRIPTION: These functions abstract direct register access 213* to Blackfin processor General Purpose 214* Ports Regsiters 215* 216* CAUTION: These functions do not belong to the GPIO Driver API 217************************************************************* 218* MODIFICATION HISTORY : 219**************************************************************/ 220 221/* Set a specific bit */ 222 223#define SET_GPIO(name) \ 224void set_gpio_ ## name(unsigned short gpio, unsigned short arg) \ 225{ \ 226 unsigned long flags; \ 227 BUG_ON(!(reserved_map[gpio_bank(gpio)] & gpio_bit(gpio))); \ 228 local_irq_save(flags); \ 229 if (arg) \ 230 gpio_bankb[gpio_bank(gpio)]->name |= gpio_bit(gpio); \ 231 else \ 232 gpio_bankb[gpio_bank(gpio)]->name &= ~gpio_bit(gpio); \ 233 local_irq_restore(flags); \ 234} \ 235EXPORT_SYMBOL(set_gpio_ ## name); 236 237SET_GPIO(dir) 238SET_GPIO(inen) 239SET_GPIO(polar) 240SET_GPIO(edge) 241SET_GPIO(both) 242 243 244#define SET_GPIO_SC(name) \ 245void set_gpio_ ## name(unsigned short gpio, unsigned short arg) \ 246{ \ 247 BUG_ON(!(reserved_map[gpio_bank(gpio)] & gpio_bit(gpio))); \ 248 if (arg) \ 249 gpio_bankb[gpio_bank(gpio)]->name ## _set = gpio_bit(gpio); \ 250 else \ 251 gpio_bankb[gpio_bank(gpio)]->name ## _clear = gpio_bit(gpio); \ 252} \ 253EXPORT_SYMBOL(set_gpio_ ## name); 254 255SET_GPIO_SC(maska) 256SET_GPIO_SC(maskb) 257 258#if defined(ANOMALY_05000311) 259void set_gpio_data(unsigned short gpio, unsigned short arg) 260{ 261 unsigned long flags; 262 BUG_ON(!(reserved_map[gpio_bank(gpio)] & gpio_bit(gpio))); 263 local_irq_save(flags); 264 if (arg) 265 gpio_bankb[gpio_bank(gpio)]->data_set = gpio_bit(gpio); 266 else 267 gpio_bankb[gpio_bank(gpio)]->data_clear = gpio_bit(gpio); 268 bfin_read_CHIPID(); 269 local_irq_restore(flags); 270} 271EXPORT_SYMBOL(set_gpio_data); 272#else 273SET_GPIO_SC(data) 274#endif 275 276 277#if defined(ANOMALY_05000311) 278void set_gpio_toggle(unsigned short gpio) 279{ 280 unsigned long flags; 281 BUG_ON(!(reserved_map[gpio_bank(gpio)] & gpio_bit(gpio))); 282 local_irq_save(flags); 283 gpio_bankb[gpio_bank(gpio)]->toggle = gpio_bit(gpio); 284 bfin_read_CHIPID(); 285 local_irq_restore(flags); 286} 287#else 288void set_gpio_toggle(unsigned short gpio) 289{ 290 BUG_ON(!(reserved_map[gpio_bank(gpio)] & gpio_bit(gpio))); 291 gpio_bankb[gpio_bank(gpio)]->toggle = gpio_bit(gpio); 292} 293#endif 294EXPORT_SYMBOL(set_gpio_toggle); 295 296 297/*Set current PORT date (16-bit word)*/ 298 299#define SET_GPIO_P(name) \ 300void set_gpiop_ ## name(unsigned short gpio, unsigned short arg) \ 301{ \ 302 gpio_bankb[gpio_bank(gpio)]->name = arg; \ 303} \ 304EXPORT_SYMBOL(set_gpiop_ ## name); 305 306SET_GPIO_P(dir) 307SET_GPIO_P(inen) 308SET_GPIO_P(polar) 309SET_GPIO_P(edge) 310SET_GPIO_P(both) 311SET_GPIO_P(maska) 312SET_GPIO_P(maskb) 313 314 315#if defined(ANOMALY_05000311) 316void set_gpiop_data(unsigned short gpio, unsigned short arg) 317{ 318 unsigned long flags; 319 local_irq_save(flags); 320 gpio_bankb[gpio_bank(gpio)]->data = arg; 321 bfin_read_CHIPID(); 322 local_irq_restore(flags); 323} 324EXPORT_SYMBOL(set_gpiop_data); 325#else 326SET_GPIO_P(data) 327#endif 328 329 330 331/* Get a specific bit */ 332 333#define GET_GPIO(name) \ 334unsigned short get_gpio_ ## name(unsigned short gpio) \ 335{ \ 336 return (0x01 & (gpio_bankb[gpio_bank(gpio)]->name >> gpio_sub_n(gpio))); \ 337} \ 338EXPORT_SYMBOL(get_gpio_ ## name); 339 340GET_GPIO(dir) 341GET_GPIO(inen) 342GET_GPIO(polar) 343GET_GPIO(edge) 344GET_GPIO(both) 345GET_GPIO(maska) 346GET_GPIO(maskb) 347 348 349#if defined(ANOMALY_05000311) 350unsigned short get_gpio_data(unsigned short gpio) 351{ 352 unsigned long flags; 353 unsigned short ret; 354 BUG_ON(!(reserved_map[gpio_bank(gpio)] & gpio_bit(gpio))); 355 local_irq_save(flags); 356 ret = 0x01 & (gpio_bankb[gpio_bank(gpio)]->data >> gpio_sub_n(gpio)); 357 bfin_read_CHIPID(); 358 local_irq_restore(flags); 359 return ret; 360} 361EXPORT_SYMBOL(get_gpio_data); 362#else 363GET_GPIO(data) 364#endif 365 366/*Get current PORT date (16-bit word)*/ 367 368#define GET_GPIO_P(name) \ 369unsigned short get_gpiop_ ## name(unsigned short gpio) \ 370{ \ 371 return (gpio_bankb[gpio_bank(gpio)]->name);\ 372} \ 373EXPORT_SYMBOL(get_gpiop_ ## name); 374 375GET_GPIO_P(dir) 376GET_GPIO_P(inen) 377GET_GPIO_P(polar) 378GET_GPIO_P(edge) 379GET_GPIO_P(both) 380GET_GPIO_P(maska) 381GET_GPIO_P(maskb) 382 383#if defined(ANOMALY_05000311) 384unsigned short get_gpiop_data(unsigned short gpio) 385{ 386 unsigned long flags; 387 unsigned short ret; 388 local_irq_save(flags); 389 ret = gpio_bankb[gpio_bank(gpio)]->data; 390 bfin_read_CHIPID(); 391 local_irq_restore(flags); 392 return ret; 393} 394EXPORT_SYMBOL(get_gpiop_data); 395#else 396GET_GPIO_P(data) 397#endif 398 399#ifdef CONFIG_PM 400/*********************************************************** 401* 402* FUNCTIONS: Blackfin PM Setup API 403* 404* INPUTS/OUTPUTS: 405* gpio - GPIO Number between 0 and MAX_BLACKFIN_GPIOS 406* type - 407* PM_WAKE_RISING 408* PM_WAKE_FALLING 409* PM_WAKE_HIGH 410* PM_WAKE_LOW 411* PM_WAKE_BOTH_EDGES 412* 413* DESCRIPTION: Blackfin PM Driver API 414* 415* CAUTION: 416************************************************************* 417* MODIFICATION HISTORY : 418**************************************************************/ 419int gpio_pm_wakeup_request(unsigned short gpio, unsigned char type) 420{ 421 unsigned long flags; 422 423 if ((check_gpio(gpio) < 0) || !type) 424 return -EINVAL; 425 426 local_irq_save(flags); 427 428 wakeup_map[gpio_bank(gpio)] |= gpio_bit(gpio); 429 wakeup_flags_map[gpio] = type; 430 local_irq_restore(flags); 431 432 return 0; 433} 434EXPORT_SYMBOL(gpio_pm_wakeup_request); 435 436void gpio_pm_wakeup_free(unsigned short gpio) 437{ 438 unsigned long flags; 439 440 if (check_gpio(gpio) < 0) 441 return; 442 443 local_irq_save(flags); 444 445 wakeup_map[gpio_bank(gpio)] &= ~gpio_bit(gpio); 446 447 local_irq_restore(flags); 448} 449EXPORT_SYMBOL(gpio_pm_wakeup_free); 450 451static int bfin_gpio_wakeup_type(unsigned short gpio, unsigned char type) 452{ 453 port_setup(gpio, GPIO_USAGE); 454 set_gpio_dir(gpio, 0); 455 set_gpio_inen(gpio, 1); 456 457 if (type & (PM_WAKE_RISING | PM_WAKE_FALLING)) 458 set_gpio_edge(gpio, 1); 459 else 460 set_gpio_edge(gpio, 0); 461 462 if ((type & (PM_WAKE_BOTH_EDGES)) == (PM_WAKE_BOTH_EDGES)) 463 set_gpio_both(gpio, 1); 464 else 465 set_gpio_both(gpio, 0); 466 467 if ((type & (PM_WAKE_FALLING | PM_WAKE_LOW))) 468 set_gpio_polar(gpio, 1); 469 else 470 set_gpio_polar(gpio, 0); 471 472 SSYNC(); 473 474 return 0; 475} 476 477u32 gpio_pm_setup(void) 478{ 479 u32 sic_iwr = 0; 480 u16 bank, mask, i, gpio; 481 482 for (i = 0; i < MAX_BLACKFIN_GPIOS; i+=GPIO_BANKSIZE) { 483 mask = wakeup_map[gpio_bank(i)]; 484 bank = gpio_bank(i); 485 486 gpio_bank_saved[bank].maskb = gpio_bankb[bank]->maskb; 487 gpio_bankb[bank]->maskb = 0; 488 489 if (mask) { 490#ifdef BF537_FAMILY 491 gpio_bank_saved[bank].fer = *port_fer[bank]; 492#endif 493 gpio_bank_saved[bank].inen = gpio_bankb[bank]->inen; 494 gpio_bank_saved[bank].polar = gpio_bankb[bank]->polar; 495 gpio_bank_saved[bank].dir = gpio_bankb[bank]->dir; 496 gpio_bank_saved[bank].edge = gpio_bankb[bank]->edge; 497 gpio_bank_saved[bank].both = gpio_bankb[bank]->both; 498 gpio_bank_saved[bank].reserved = reserved_map[bank]; 499 500 gpio = i; 501 502 while (mask) { 503 if (mask & 1) { 504 reserved_map[gpio_bank(gpio)] |= 505 gpio_bit(gpio); 506 bfin_gpio_wakeup_type(gpio, 507 wakeup_flags_map[gpio]); 508 set_gpio_data(gpio, 0); /*Clear*/ 509 } 510 gpio++; 511 mask >>= 1; 512 } 513 514 sic_iwr |= 1 << 515 (sic_iwr_irqs[bank] - (IRQ_CORETMR + 1)); 516 gpio_bankb[bank]->maskb_set = wakeup_map[gpio_bank(i)]; 517 } 518 } 519 520 if (sic_iwr) 521 return sic_iwr; 522 else 523 return IWR_ENABLE_ALL; 524} 525 526 527void gpio_pm_restore(void) 528{ 529 u16 bank, mask, i; 530 531 for (i = 0; i < MAX_BLACKFIN_GPIOS; i+=GPIO_BANKSIZE) { 532 mask = wakeup_map[gpio_bank(i)]; 533 bank = gpio_bank(i); 534 535 if (mask) { 536#ifdef BF537_FAMILY 537 *port_fer[bank] = gpio_bank_saved[bank].fer; 538#endif 539 gpio_bankb[bank]->inen = gpio_bank_saved[bank].inen; 540 gpio_bankb[bank]->dir = gpio_bank_saved[bank].dir; 541 gpio_bankb[bank]->polar = gpio_bank_saved[bank].polar; 542 gpio_bankb[bank]->edge = gpio_bank_saved[bank].edge; 543 gpio_bankb[bank]->both = gpio_bank_saved[bank].both; 544 545 reserved_map[bank] = gpio_bank_saved[bank].reserved; 546 547 } 548 549 gpio_bankb[bank]->maskb = gpio_bank_saved[bank].maskb; 550 } 551} 552 553#endif 554 555/*********************************************************** 556* 557* FUNCTIONS: Blackfin GPIO Driver 558* 559* INPUTS/OUTPUTS: 560* gpio - GPIO Number between 0 and MAX_BLACKFIN_GPIOS 561* 562* 563* DESCRIPTION: Blackfin GPIO Driver API 564* 565* CAUTION: 566************************************************************* 567* MODIFICATION HISTORY : 568**************************************************************/ 569 570int gpio_request(unsigned short gpio, const char *label) 571{ 572 unsigned long flags; 573 574 if (check_gpio(gpio) < 0) 575 return -EINVAL; 576 577 local_irq_save(flags); 578 579 if (unlikely(reserved_map[gpio_bank(gpio)] & gpio_bit(gpio))) { 580 printk(KERN_ERR "bfin-gpio: GPIO %d is already reserved!\n", gpio); 581 dump_stack(); 582 local_irq_restore(flags); 583 return -EBUSY; 584 } 585 reserved_map[gpio_bank(gpio)] |= gpio_bit(gpio); 586 587 local_irq_restore(flags); 588 589 port_setup(gpio, GPIO_USAGE); 590 591 return 0; 592} 593EXPORT_SYMBOL(gpio_request); 594 595 596void gpio_free(unsigned short gpio) 597{ 598 unsigned long flags; 599 600 if (check_gpio(gpio) < 0) 601 return; 602 603 local_irq_save(flags); 604 605 if (unlikely(!(reserved_map[gpio_bank(gpio)] & gpio_bit(gpio)))) { 606 printk(KERN_ERR "bfin-gpio: GPIO %d wasn't reserved!\n", gpio); 607 dump_stack(); 608 local_irq_restore(flags); 609 return; 610 } 611 612 default_gpio(gpio); 613 614 reserved_map[gpio_bank(gpio)] &= ~gpio_bit(gpio); 615 616 local_irq_restore(flags); 617} 618EXPORT_SYMBOL(gpio_free); 619 620 621void gpio_direction_input(unsigned short gpio) 622{ 623 unsigned long flags; 624 625 BUG_ON(!(reserved_map[gpio_bank(gpio)] & gpio_bit(gpio))); 626 627 local_irq_save(flags); 628 gpio_bankb[gpio_bank(gpio)]->dir &= ~gpio_bit(gpio); 629 gpio_bankb[gpio_bank(gpio)]->inen |= gpio_bit(gpio); 630 local_irq_restore(flags); 631} 632EXPORT_SYMBOL(gpio_direction_input); 633 634void gpio_direction_output(unsigned short gpio) 635{ 636 unsigned long flags; 637 638 BUG_ON(!(reserved_map[gpio_bank(gpio)] & gpio_bit(gpio))); 639 640 local_irq_save(flags); 641 gpio_bankb[gpio_bank(gpio)]->inen &= ~gpio_bit(gpio); 642 gpio_bankb[gpio_bank(gpio)]->dir |= gpio_bit(gpio); 643 local_irq_restore(flags); 644} 645EXPORT_SYMBOL(gpio_direction_output); 646