gpio-plat-samsung.c 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. /*
  2. * Copyright 2008 Openmoko, Inc.
  3. * Copyright 2008 Simtec Electronics
  4. * Ben Dooks <ben@simtec.co.uk>
  5. * http://armlinux.simtec.co.uk/
  6. *
  7. * Copyright (c) 2009 Samsung Electronics Co., Ltd.
  8. * http://www.samsung.com/
  9. *
  10. * SAMSUNG - GPIOlib support
  11. *
  12. * This program is free software; you can redistribute it and/or modify
  13. * it under the terms of the GNU General Public License version 2 as
  14. * published by the Free Software Foundation.
  15. */
  16. #include <linux/kernel.h>
  17. #include <linux/irq.h>
  18. #include <linux/io.h>
  19. #include <linux/gpio.h>
  20. #include <plat/gpio-core.h>
  21. #include <plat/gpio-cfg.h>
  22. #include <plat/gpio-cfg-helpers.h>
  23. #ifndef DEBUG_GPIO
  24. #define gpio_dbg(x...) do { } while (0)
  25. #else
  26. #define gpio_dbg(x...) printk(KERN_DEBUG x)
  27. #endif
  28. /* The samsung_gpiolib_4bit routines are to control the gpio banks where
  29. * the gpio configuration register (GPxCON) has 4 bits per GPIO, as the
  30. * following example:
  31. *
  32. * base + 0x00: Control register, 4 bits per gpio
  33. * gpio n: 4 bits starting at (4*n)
  34. * 0000 = input, 0001 = output, others mean special-function
  35. * base + 0x04: Data register, 1 bit per gpio
  36. * bit n: data bit n
  37. *
  38. * Note, since the data register is one bit per gpio and is at base + 0x4
  39. * we can use s3c_gpiolib_get and s3c_gpiolib_set to change the state of
  40. * the output.
  41. */
  42. static int samsung_gpiolib_4bit_input(struct gpio_chip *chip,
  43. unsigned int offset)
  44. {
  45. struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);
  46. void __iomem *base = ourchip->base;
  47. unsigned long con;
  48. con = __raw_readl(base + GPIOCON_OFF);
  49. con &= ~(0xf << con_4bit_shift(offset));
  50. __raw_writel(con, base + GPIOCON_OFF);
  51. gpio_dbg("%s: %p: CON now %08lx\n", __func__, base, con);
  52. return 0;
  53. }
  54. static int samsung_gpiolib_4bit_output(struct gpio_chip *chip,
  55. unsigned int offset, int value)
  56. {
  57. struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);
  58. void __iomem *base = ourchip->base;
  59. unsigned long con;
  60. unsigned long dat;
  61. con = __raw_readl(base + GPIOCON_OFF);
  62. con &= ~(0xf << con_4bit_shift(offset));
  63. con |= 0x1 << con_4bit_shift(offset);
  64. dat = __raw_readl(base + GPIODAT_OFF);
  65. if (value)
  66. dat |= 1 << offset;
  67. else
  68. dat &= ~(1 << offset);
  69. __raw_writel(dat, base + GPIODAT_OFF);
  70. __raw_writel(con, base + GPIOCON_OFF);
  71. __raw_writel(dat, base + GPIODAT_OFF);
  72. gpio_dbg("%s: %p: CON %08lx, DAT %08lx\n", __func__, base, con, dat);
  73. return 0;
  74. }
  75. /* The next set of routines are for the case where the GPIO configuration
  76. * registers are 4 bits per GPIO but there is more than one register (the
  77. * bank has more than 8 GPIOs.
  78. *
  79. * This case is the similar to the 4 bit case, but the registers are as
  80. * follows:
  81. *
  82. * base + 0x00: Control register, 4 bits per gpio (lower 8 GPIOs)
  83. * gpio n: 4 bits starting at (4*n)
  84. * 0000 = input, 0001 = output, others mean special-function
  85. * base + 0x04: Control register, 4 bits per gpio (up to 8 additions GPIOs)
  86. * gpio n: 4 bits starting at (4*n)
  87. * 0000 = input, 0001 = output, others mean special-function
  88. * base + 0x08: Data register, 1 bit per gpio
  89. * bit n: data bit n
  90. *
  91. * To allow us to use the s3c_gpiolib_get and s3c_gpiolib_set routines we
  92. * store the 'base + 0x4' address so that these routines see the data
  93. * register at ourchip->base + 0x04.
  94. */
  95. static int samsung_gpiolib_4bit2_input(struct gpio_chip *chip,
  96. unsigned int offset)
  97. {
  98. struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);
  99. void __iomem *base = ourchip->base;
  100. void __iomem *regcon = base;
  101. unsigned long con;
  102. if (offset > 7)
  103. offset -= 8;
  104. else
  105. regcon -= 4;
  106. con = __raw_readl(regcon);
  107. con &= ~(0xf << con_4bit_shift(offset));
  108. __raw_writel(con, regcon);
  109. gpio_dbg("%s: %p: CON %08lx\n", __func__, base, con);
  110. return 0;
  111. }
  112. static int samsung_gpiolib_4bit2_output(struct gpio_chip *chip,
  113. unsigned int offset, int value)
  114. {
  115. struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);
  116. void __iomem *base = ourchip->base;
  117. void __iomem *regcon = base;
  118. unsigned long con;
  119. unsigned long dat;
  120. unsigned con_offset = offset;
  121. if (con_offset > 7)
  122. con_offset -= 8;
  123. else
  124. regcon -= 4;
  125. con = __raw_readl(regcon);
  126. con &= ~(0xf << con_4bit_shift(con_offset));
  127. con |= 0x1 << con_4bit_shift(con_offset);
  128. dat = __raw_readl(base + GPIODAT_OFF);
  129. if (value)
  130. dat |= 1 << offset;
  131. else
  132. dat &= ~(1 << offset);
  133. __raw_writel(dat, base + GPIODAT_OFF);
  134. __raw_writel(con, regcon);
  135. __raw_writel(dat, base + GPIODAT_OFF);
  136. gpio_dbg("%s: %p: CON %08lx, DAT %08lx\n", __func__, base, con, dat);
  137. return 0;
  138. }
  139. void __init samsung_gpiolib_add_4bit(struct s3c_gpio_chip *chip)
  140. {
  141. chip->chip.direction_input = samsung_gpiolib_4bit_input;
  142. chip->chip.direction_output = samsung_gpiolib_4bit_output;
  143. chip->pm = __gpio_pm(&s3c_gpio_pm_4bit);
  144. }
  145. void __init samsung_gpiolib_add_4bit2(struct s3c_gpio_chip *chip)
  146. {
  147. chip->chip.direction_input = samsung_gpiolib_4bit2_input;
  148. chip->chip.direction_output = samsung_gpiolib_4bit2_output;
  149. chip->pm = __gpio_pm(&s3c_gpio_pm_4bit);
  150. }
  151. void __init samsung_gpiolib_add_4bit_chips(struct s3c_gpio_chip *chip,
  152. int nr_chips)
  153. {
  154. for (; nr_chips > 0; nr_chips--, chip++) {
  155. samsung_gpiolib_add_4bit(chip);
  156. s3c_gpiolib_add(chip);
  157. }
  158. }
  159. void __init samsung_gpiolib_add_4bit2_chips(struct s3c_gpio_chip *chip,
  160. int nr_chips)
  161. {
  162. for (; nr_chips > 0; nr_chips--, chip++) {
  163. samsung_gpiolib_add_4bit2(chip);
  164. s3c_gpiolib_add(chip);
  165. }
  166. }
  167. void __init samsung_gpiolib_add_2bit_chips(struct s3c_gpio_chip *chip,
  168. int nr_chips)
  169. {
  170. for (; nr_chips > 0; nr_chips--, chip++)
  171. s3c_gpiolib_add(chip);
  172. }