gpio.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. /* linux/arch/arm/plat-s3c/gpio.c
  2. *
  3. * Copyright 2008 Simtec Electronics
  4. * Ben Dooks <ben@simtec.co.uk>
  5. * http://armlinux.simtec.co.uk/
  6. *
  7. * S3C series GPIO core
  8. *
  9. * This program is free software; you can redistribute it and/or modify
  10. * it under the terms of the GNU General Public License version 2 as
  11. * published by the Free Software Foundation.
  12. */
  13. #include <linux/kernel.h>
  14. #include <linux/init.h>
  15. #include <linux/io.h>
  16. #include <linux/gpio.h>
  17. #include <mach/gpio-core.h>
  18. #ifdef CONFIG_S3C_GPIO_TRACK
  19. struct s3c_gpio_chip *s3c_gpios[S3C_GPIO_END];
  20. static __init void s3c_gpiolib_track(struct s3c_gpio_chip *chip)
  21. {
  22. unsigned int gpn;
  23. int i;
  24. gpn = chip->chip.base;
  25. for (i = 0; i < chip->chip.ngpio; i++, gpn++) {
  26. BUG_ON(gpn >= ARRAY_SIZE(s3c_gpios));
  27. s3c_gpios[gpn] = chip;
  28. }
  29. }
  30. #endif /* CONFIG_S3C_GPIO_TRACK */
  31. /* Default routines for controlling GPIO, based on the original S3C24XX
  32. * GPIO functions which deal with the case where each gpio bank of the
  33. * chip is as following:
  34. *
  35. * base + 0x00: Control register, 2 bits per gpio
  36. * gpio n: 2 bits starting at (2*n)
  37. * 00 = input, 01 = output, others mean special-function
  38. * base + 0x04: Data register, 1 bit per gpio
  39. * bit n: data bit n
  40. */
  41. static int s3c_gpiolib_input(struct gpio_chip *chip, unsigned offset)
  42. {
  43. struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);
  44. void __iomem *base = ourchip->base;
  45. unsigned long flags;
  46. unsigned long con;
  47. local_irq_save(flags);
  48. con = __raw_readl(base + 0x00);
  49. con &= ~(3 << (offset * 2));
  50. __raw_writel(con, base + 0x00);
  51. local_irq_restore(flags);
  52. return 0;
  53. }
  54. static int s3c_gpiolib_output(struct gpio_chip *chip,
  55. unsigned offset, int value)
  56. {
  57. struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);
  58. void __iomem *base = ourchip->base;
  59. unsigned long flags;
  60. unsigned long dat;
  61. unsigned long con;
  62. local_irq_save(flags);
  63. dat = __raw_readl(base + 0x04);
  64. dat &= ~(1 << offset);
  65. if (value)
  66. dat |= 1 << offset;
  67. __raw_writel(dat, base + 0x04);
  68. con = __raw_readl(base + 0x00);
  69. con &= ~(3 << (offset * 2));
  70. con |= 1 << (offset * 2);
  71. __raw_writel(con, base + 0x00);
  72. __raw_writel(dat, base + 0x04);
  73. local_irq_restore(flags);
  74. return 0;
  75. }
  76. static void s3c_gpiolib_set(struct gpio_chip *chip,
  77. unsigned offset, int value)
  78. {
  79. struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);
  80. void __iomem *base = ourchip->base;
  81. unsigned long flags;
  82. unsigned long dat;
  83. local_irq_save(flags);
  84. dat = __raw_readl(base + 0x04);
  85. dat &= ~(1 << offset);
  86. if (value)
  87. dat |= 1 << offset;
  88. __raw_writel(dat, base + 0x04);
  89. local_irq_restore(flags);
  90. }
  91. static int s3c_gpiolib_get(struct gpio_chip *chip, unsigned offset)
  92. {
  93. struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);
  94. unsigned long val;
  95. val = __raw_readl(ourchip->base + 0x04);
  96. val >>= offset;
  97. val &= 1;
  98. return val;
  99. }
  100. __init void s3c_gpiolib_add(struct s3c_gpio_chip *chip)
  101. {
  102. struct gpio_chip *gc = &chip->chip;
  103. int ret;
  104. BUG_ON(!chip->base);
  105. BUG_ON(!gc->label);
  106. BUG_ON(!gc->ngpio);
  107. if (!gc->direction_input)
  108. gc->direction_input = s3c_gpiolib_input;
  109. if (!gc->direction_output)
  110. gc->direction_output = s3c_gpiolib_output;
  111. if (!gc->set)
  112. gc->set = s3c_gpiolib_set;
  113. if (!gc->get)
  114. gc->get = s3c_gpiolib_get;
  115. #ifdef CONFIG_PM
  116. if (chip->pm != NULL) {
  117. if (!chip->pm->save || !chip->pm->resume)
  118. printk(KERN_ERR "gpio: %s has missing PM functions\n",
  119. gc->label);
  120. } else
  121. printk(KERN_ERR "gpio: %s has no PM function\n", gc->label);
  122. #endif
  123. /* gpiochip_add() prints own failure message on error. */
  124. ret = gpiochip_add(gc);
  125. if (ret >= 0)
  126. s3c_gpiolib_track(chip);
  127. }