pca9532.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. /* $OpenBSD: pca9532.c,v 1.3 2008/04/17 16:50:17 deraadt Exp $ */
  2. /*
  3. * Copyright (c) 2006 Dale Rahn <drahn@openbsd.org>
  4. *
  5. * Permission to use, copy, modify, and distribute this software for any
  6. * purpose with or without fee is hereby granted, provided that the above
  7. * copyright notice and this permission notice appear in all copies.
  8. *
  9. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  10. * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  11. * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  12. * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  13. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  14. * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  15. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  16. */
  17. #include <sys/param.h>
  18. #include <sys/systm.h>
  19. #include <sys/device.h>
  20. #include <sys/kernel.h>
  21. #include <sys/fcntl.h>
  22. #include <sys/uio.h>
  23. #include <sys/conf.h>
  24. #include <sys/gpio.h>
  25. #include <dev/i2c/i2cvar.h>
  26. #include <dev/gpio/gpiovar.h>
  27. #include "gpio.h"
  28. /* driver for PCA 9532 */
  29. #define PCALED_ADDR 0x60
  30. #define PCALED_GPIO_NPINS 16
  31. struct pcaled_softc {
  32. struct device sc_dev;
  33. i2c_tag_t sc_tag;
  34. int sc_addr;
  35. struct gpio_chipset_tag sc_gpio_gc;
  36. struct gpio_pin sc_gpio_pin[PCALED_GPIO_NPINS];
  37. };
  38. int pcaled_match(struct device *, void *, void *);
  39. void pcaled_attach(struct device *, struct device *, void *);
  40. int pcaled_gpio_pin_read(void *arg, int pin);
  41. void pcaled_gpio_pin_write (void *arg, int pin, int value);
  42. void pcaled_gpio_pin_ctl (void *arg, int pin, int flags);
  43. struct cfattach pcaled_ca = {
  44. sizeof(struct pcaled_softc), pcaled_match, pcaled_attach
  45. };
  46. struct cfdriver pcaled_cd = {
  47. NULL, "pcaled", DV_DULL
  48. };
  49. int
  50. pcaled_match(struct device *parent, void *v, void *arg)
  51. {
  52. struct i2c_attach_args *ia = arg;
  53. int ok = 0;
  54. uint8_t cmd, data;
  55. if (ia->ia_addr != PCALED_ADDR)
  56. return (0);
  57. /* attempt to read input register 0 */
  58. iic_acquire_bus(ia->ia_tag, I2C_F_POLL);
  59. cmd = 0;
  60. if (iic_exec(ia->ia_tag, I2C_OP_READ_WITH_STOP, ia->ia_addr,
  61. &cmd, sizeof cmd, &data, sizeof data, I2C_F_POLL))
  62. goto fail;
  63. cmd = 9;
  64. if (iic_exec(ia->ia_tag, I2C_OP_READ_WITH_STOP, ia->ia_addr,
  65. &cmd, sizeof cmd, &data, sizeof data, I2C_F_POLL))
  66. goto fail;
  67. ok = 1;
  68. fail:
  69. iic_release_bus(ia->ia_tag, I2C_F_POLL);
  70. return (ok);
  71. }
  72. void
  73. pcaled_attach(struct device *parent, struct device *self, void *arg)
  74. {
  75. struct pcaled_softc *sc = (void *)self;
  76. struct i2c_attach_args *ia = arg;
  77. struct gpiobus_attach_args gba;
  78. int i;
  79. uint8_t cmd, data;
  80. sc->sc_tag = ia->ia_tag;
  81. sc->sc_addr = ia->ia_addr;
  82. iic_acquire_bus(sc->sc_tag, I2C_F_POLL);
  83. for (i = 0; i < PCALED_GPIO_NPINS; i++) {
  84. sc->sc_gpio_pin[i].pin_num = i;
  85. sc->sc_gpio_pin[i].pin_caps = GPIO_PIN_INOUT;
  86. if (i < 8)
  87. cmd = 0;
  88. else
  89. cmd = 1;
  90. if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP, sc->sc_addr,
  91. &cmd, sizeof cmd, &data, sizeof data, I2C_F_POLL))
  92. goto fail; /* XXX */
  93. sc->sc_gpio_pin[i].pin_state = (data >> (i & 3)) & 1;
  94. }
  95. sc->sc_gpio_gc.gp_cookie = sc;
  96. sc->sc_gpio_gc.gp_pin_read = pcaled_gpio_pin_read;
  97. sc->sc_gpio_gc.gp_pin_write = pcaled_gpio_pin_write;
  98. sc->sc_gpio_gc.gp_pin_ctl = pcaled_gpio_pin_ctl;
  99. printf(": PCA9532 LED controller\n");
  100. gba.gba_name = "gpio";
  101. gba.gba_gc = &sc->sc_gpio_gc;
  102. gba.gba_pins = sc->sc_gpio_pin;
  103. gba.gba_npins = PCALED_GPIO_NPINS;
  104. #if NGPIO > 0
  105. config_found(&sc->sc_dev, &gba, gpiobus_print);
  106. #endif
  107. fail:
  108. iic_release_bus(sc->sc_tag, I2C_F_POLL);
  109. }
  110. int
  111. pcaled_gpio_pin_read(void *arg, int pin)
  112. {
  113. struct pcaled_softc *sc = arg;
  114. iic_acquire_bus(sc->sc_tag, I2C_F_POLL);
  115. uint8_t cmd, data;
  116. if (pin < 8)
  117. cmd = 0;
  118. else
  119. cmd = 1;
  120. if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP, sc->sc_addr,
  121. &cmd, sizeof cmd, &data, sizeof data, I2C_F_POLL))
  122. goto fail; /* XXX */
  123. fail:
  124. iic_release_bus(sc->sc_tag, I2C_F_POLL);
  125. return (data >> (pin & 3)) & 1;
  126. }
  127. void
  128. pcaled_gpio_pin_write (void *arg, int pin, int value)
  129. {
  130. struct pcaled_softc *sc = arg;
  131. uint8_t cmd, data;
  132. if (pin < 4)
  133. cmd = 6;
  134. else if (pin < 8)
  135. cmd = 7;
  136. else if (pin < 12)
  137. cmd = 8;
  138. else
  139. cmd = 9;
  140. if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP, sc->sc_addr,
  141. &cmd, sizeof cmd, &data, sizeof data, I2C_F_POLL))
  142. goto fail; /* XXX */
  143. data &= ~(0x3 << (2*(pin & 3)));
  144. data |= (value << (2*(pin & 3)));
  145. if (iic_exec(sc->sc_tag, I2C_OP_WRITE_WITH_STOP, sc->sc_addr,
  146. &cmd, sizeof cmd, &data, sizeof data, I2C_F_POLL))
  147. goto fail; /* XXX */
  148. fail:
  149. iic_release_bus(sc->sc_tag, I2C_F_POLL);
  150. }
  151. void
  152. pcaled_gpio_pin_ctl (void *arg, int pin, int flags)
  153. {
  154. /* XXX all pins are inout */
  155. }