gpio-plat-samsung.c 5.4 KB

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