gpio.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. /*
  2. * Coldfire generic GPIO support.
  3. *
  4. * (C) Copyright 2009, Steven King <sfking@fdwdc.com>
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; version 2 of the License.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. */
  15. #include <linux/kernel.h>
  16. #include <linux/init.h>
  17. #include <linux/device.h>
  18. #include <asm/gpio.h>
  19. #include <asm/pinmux.h>
  20. #include <asm/mcfgpio.h>
  21. #define MCF_CHIP(chip) container_of(chip, struct mcf_gpio_chip, gpio_chip)
  22. int mcf_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
  23. {
  24. unsigned long flags;
  25. MCFGPIO_PORTTYPE dir;
  26. struct mcf_gpio_chip *mcf_chip = MCF_CHIP(chip);
  27. local_irq_save(flags);
  28. dir = mcfgpio_read(mcf_chip->pddr);
  29. dir &= ~mcfgpio_bit(chip->base + offset);
  30. mcfgpio_write(dir, mcf_chip->pddr);
  31. local_irq_restore(flags);
  32. return 0;
  33. }
  34. int mcf_gpio_get_value(struct gpio_chip *chip, unsigned offset)
  35. {
  36. struct mcf_gpio_chip *mcf_chip = MCF_CHIP(chip);
  37. return mcfgpio_read(mcf_chip->ppdr) & mcfgpio_bit(chip->base + offset);
  38. }
  39. int mcf_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
  40. int value)
  41. {
  42. unsigned long flags;
  43. MCFGPIO_PORTTYPE data;
  44. struct mcf_gpio_chip *mcf_chip = MCF_CHIP(chip);
  45. local_irq_save(flags);
  46. /* write the value to the output latch */
  47. data = mcfgpio_read(mcf_chip->podr);
  48. if (value)
  49. data |= mcfgpio_bit(chip->base + offset);
  50. else
  51. data &= ~mcfgpio_bit(chip->base + offset);
  52. mcfgpio_write(data, mcf_chip->podr);
  53. /* now set the direction to output */
  54. data = mcfgpio_read(mcf_chip->pddr);
  55. data |= mcfgpio_bit(chip->base + offset);
  56. mcfgpio_write(data, mcf_chip->pddr);
  57. local_irq_restore(flags);
  58. return 0;
  59. }
  60. void mcf_gpio_set_value(struct gpio_chip *chip, unsigned offset, int value)
  61. {
  62. struct mcf_gpio_chip *mcf_chip = MCF_CHIP(chip);
  63. unsigned long flags;
  64. MCFGPIO_PORTTYPE data;
  65. local_irq_save(flags);
  66. data = mcfgpio_read(mcf_chip->podr);
  67. if (value)
  68. data |= mcfgpio_bit(chip->base + offset);
  69. else
  70. data &= ~mcfgpio_bit(chip->base + offset);
  71. mcfgpio_write(data, mcf_chip->podr);
  72. local_irq_restore(flags);
  73. }
  74. void mcf_gpio_set_value_fast(struct gpio_chip *chip, unsigned offset, int value)
  75. {
  76. struct mcf_gpio_chip *mcf_chip = MCF_CHIP(chip);
  77. if (value)
  78. mcfgpio_write(mcfgpio_bit(chip->base + offset), mcf_chip->setr);
  79. else
  80. mcfgpio_write(~mcfgpio_bit(chip->base + offset), mcf_chip->clrr);
  81. }
  82. int mcf_gpio_request(struct gpio_chip *chip, unsigned offset)
  83. {
  84. struct mcf_gpio_chip *mcf_chip = MCF_CHIP(chip);
  85. return mcf_chip->gpio_to_pinmux ?
  86. mcf_pinmux_request(mcf_chip->gpio_to_pinmux[offset], 0) : 0;
  87. }
  88. void mcf_gpio_free(struct gpio_chip *chip, unsigned offset)
  89. {
  90. struct mcf_gpio_chip *mcf_chip = MCF_CHIP(chip);
  91. mcf_gpio_direction_input(chip, offset);
  92. if (mcf_chip->gpio_to_pinmux)
  93. mcf_pinmux_release(mcf_chip->gpio_to_pinmux[offset], 0);
  94. }
  95. struct bus_type mcf_gpio_subsys = {
  96. .name = "gpio",
  97. .dev_name = "gpio",
  98. };
  99. static int __init mcf_gpio_sysinit(void)
  100. {
  101. return subsys_system_register(&mcf_gpio_subsys, NULL);
  102. }
  103. core_initcall(mcf_gpio_sysinit);