gpio-janz-ttl.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * Janz MODULbus VMOD-TTL GPIO Driver
  4. *
  5. * Copyright (c) 2010 Ira W. Snyder <[email protected]>
  6. */
  7. #include <linux/kernel.h>
  8. #include <linux/module.h>
  9. #include <linux/init.h>
  10. #include <linux/interrupt.h>
  11. #include <linux/delay.h>
  12. #include <linux/platform_device.h>
  13. #include <linux/io.h>
  14. #include <linux/gpio/driver.h>
  15. #include <linux/slab.h>
  16. #include <linux/bitops.h>
  17. #include <linux/mfd/janz.h>
  18. #define DRV_NAME "janz-ttl"
  19. #define PORTA_DIRECTION 0x23
  20. #define PORTB_DIRECTION 0x2B
  21. #define PORTC_DIRECTION 0x06
  22. #define PORTA_IOCTL 0x24
  23. #define PORTB_IOCTL 0x2C
  24. #define PORTC_IOCTL 0x07
  25. #define MASTER_INT_CTL 0x00
  26. #define MASTER_CONF_CTL 0x01
  27. #define CONF_PAE BIT(2)
  28. #define CONF_PBE BIT(7)
  29. #define CONF_PCE BIT(4)
  30. struct ttl_control_regs {
  31. __be16 portc;
  32. __be16 portb;
  33. __be16 porta;
  34. __be16 control;
  35. };
  36. struct ttl_module {
  37. struct gpio_chip gpio;
  38. /* base address of registers */
  39. struct ttl_control_regs __iomem *regs;
  40. u8 portc_shadow;
  41. u8 portb_shadow;
  42. u8 porta_shadow;
  43. spinlock_t lock;
  44. };
  45. static int ttl_get_value(struct gpio_chip *gpio, unsigned offset)
  46. {
  47. struct ttl_module *mod = dev_get_drvdata(gpio->parent);
  48. u8 *shadow;
  49. int ret;
  50. if (offset < 8) {
  51. shadow = &mod->porta_shadow;
  52. } else if (offset < 16) {
  53. shadow = &mod->portb_shadow;
  54. offset -= 8;
  55. } else {
  56. shadow = &mod->portc_shadow;
  57. offset -= 16;
  58. }
  59. spin_lock(&mod->lock);
  60. ret = *shadow & BIT(offset);
  61. spin_unlock(&mod->lock);
  62. return !!ret;
  63. }
  64. static void ttl_set_value(struct gpio_chip *gpio, unsigned offset, int value)
  65. {
  66. struct ttl_module *mod = dev_get_drvdata(gpio->parent);
  67. void __iomem *port;
  68. u8 *shadow;
  69. if (offset < 8) {
  70. port = &mod->regs->porta;
  71. shadow = &mod->porta_shadow;
  72. } else if (offset < 16) {
  73. port = &mod->regs->portb;
  74. shadow = &mod->portb_shadow;
  75. offset -= 8;
  76. } else {
  77. port = &mod->regs->portc;
  78. shadow = &mod->portc_shadow;
  79. offset -= 16;
  80. }
  81. spin_lock(&mod->lock);
  82. if (value)
  83. *shadow |= BIT(offset);
  84. else
  85. *shadow &= ~BIT(offset);
  86. iowrite16be(*shadow, port);
  87. spin_unlock(&mod->lock);
  88. }
  89. static void ttl_write_reg(struct ttl_module *mod, u8 reg, u16 val)
  90. {
  91. iowrite16be(reg, &mod->regs->control);
  92. iowrite16be(val, &mod->regs->control);
  93. }
  94. static void ttl_setup_device(struct ttl_module *mod)
  95. {
  96. /* reset the device to a known state */
  97. iowrite16be(0x0000, &mod->regs->control);
  98. iowrite16be(0x0001, &mod->regs->control);
  99. iowrite16be(0x0000, &mod->regs->control);
  100. /* put all ports in open-drain mode */
  101. ttl_write_reg(mod, PORTA_IOCTL, 0x00ff);
  102. ttl_write_reg(mod, PORTB_IOCTL, 0x00ff);
  103. ttl_write_reg(mod, PORTC_IOCTL, 0x000f);
  104. /* set all ports as outputs */
  105. ttl_write_reg(mod, PORTA_DIRECTION, 0x0000);
  106. ttl_write_reg(mod, PORTB_DIRECTION, 0x0000);
  107. ttl_write_reg(mod, PORTC_DIRECTION, 0x0000);
  108. /* set all ports to drive zeroes */
  109. iowrite16be(0x0000, &mod->regs->porta);
  110. iowrite16be(0x0000, &mod->regs->portb);
  111. iowrite16be(0x0000, &mod->regs->portc);
  112. /* enable all ports */
  113. ttl_write_reg(mod, MASTER_CONF_CTL, CONF_PAE | CONF_PBE | CONF_PCE);
  114. }
  115. static int ttl_probe(struct platform_device *pdev)
  116. {
  117. struct janz_platform_data *pdata;
  118. struct ttl_module *mod;
  119. struct gpio_chip *gpio;
  120. int ret;
  121. pdata = dev_get_platdata(&pdev->dev);
  122. if (!pdata) {
  123. dev_err(&pdev->dev, "no platform data\n");
  124. return -ENXIO;
  125. }
  126. mod = devm_kzalloc(&pdev->dev, sizeof(*mod), GFP_KERNEL);
  127. if (!mod)
  128. return -ENOMEM;
  129. platform_set_drvdata(pdev, mod);
  130. spin_lock_init(&mod->lock);
  131. /* get access to the MODULbus registers for this module */
  132. mod->regs = devm_platform_ioremap_resource(pdev, 0);
  133. if (IS_ERR(mod->regs))
  134. return PTR_ERR(mod->regs);
  135. ttl_setup_device(mod);
  136. /* Initialize the GPIO data structures */
  137. gpio = &mod->gpio;
  138. gpio->parent = &pdev->dev;
  139. gpio->label = pdev->name;
  140. gpio->get = ttl_get_value;
  141. gpio->set = ttl_set_value;
  142. gpio->owner = THIS_MODULE;
  143. /* request dynamic allocation */
  144. gpio->base = -1;
  145. gpio->ngpio = 20;
  146. ret = devm_gpiochip_add_data(&pdev->dev, gpio, NULL);
  147. if (ret) {
  148. dev_err(&pdev->dev, "unable to add GPIO chip\n");
  149. return ret;
  150. }
  151. return 0;
  152. }
  153. static struct platform_driver ttl_driver = {
  154. .driver = {
  155. .name = DRV_NAME,
  156. },
  157. .probe = ttl_probe,
  158. };
  159. module_platform_driver(ttl_driver);
  160. MODULE_AUTHOR("Ira W. Snyder <[email protected]>");
  161. MODULE_DESCRIPTION("Janz MODULbus VMOD-TTL Driver");
  162. MODULE_LICENSE("GPL");
  163. MODULE_ALIAS("platform:janz-ttl");