w83795g.c 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298
  1. /* $OpenBSD: w83795g.c,v 1.1 2011/07/03 21:30:20 kettenis Exp $ */
  2. /*
  3. * Copyright (c) 2011 Mark Kettenis
  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/sensors.h>
  21. #include <dev/i2c/i2cvar.h>
  22. /* Nuvoton W83795G Hardware Monitor */
  23. #define NVT_BANKSELECT 0x00
  24. #define NVT_CONFIG 0x01
  25. #define NVT_CONFIG_48 0x04
  26. #define NVT_VOLT_CTRL1 0x02
  27. #define NVT_VOLT_CTRL2 0x03
  28. #define NVT_TEMP_CTRL1 0x04
  29. #define NVT_TEMP_CTRL2 0x05
  30. #define NVT_FANIN_CTRL1 0x06
  31. #define NVT_FANIN_CTRL2 0x07
  32. #define NVT_VSEN1 0x10
  33. #define NVT_3VDD 0x1c
  34. #define NVT_3VSB 0x1d
  35. #define NVT_VBAT 0x1e
  36. #define NVT_TR5 0x1f
  37. #define NVT_TR6 0x20
  38. #define NVT_TD1 0x21
  39. #define NVT_TD2 0x22
  40. #define NVT_TD3 0x23
  41. #define NVT_TD4 0x24
  42. #define NVT_FANIN1_COUNT 0x2e
  43. #define NVT_VRLSB 0x3c
  44. /* Voltage */
  45. #define NVT_NUM_VOLTS 15
  46. static const char *nvt_volt_desc[NVT_NUM_VOLTS] = {
  47. "", "", "", "", "", "", "", "", "", "", "",
  48. "VTT", "3VDD", "3VSB", "VBat"
  49. };
  50. /* Temperature */
  51. #define NVT_NUM_TEMPS 6
  52. #define NVT_NUM_TR 2
  53. #define NVT_NUM_TD 4
  54. /* Fan */
  55. #define NVT_NUM_FANS 14
  56. #define NVT_NUM_SENSORS (NVT_NUM_VOLTS + NVT_NUM_TEMPS + NVT_NUM_FANS)
  57. struct nvt_softc {
  58. struct device sc_dev;
  59. i2c_tag_t sc_tag;
  60. i2c_addr_t sc_addr;
  61. uint16_t sc_vctrl;
  62. uint16_t sc_tctrl1, sc_tctrl2;
  63. uint16_t sc_fctrl;
  64. struct ksensor sc_sensors[NVT_NUM_SENSORS];
  65. struct ksensordev sc_sensordev;
  66. };
  67. int nvt_match(struct device *, void *, void *);
  68. void nvt_attach(struct device *, struct device *, void *);
  69. void nvt_refresh(void *);
  70. void nvt_refresh_volts(struct nvt_softc *);
  71. void nvt_refresh_temps(struct nvt_softc *);
  72. void nvt_refresh_fans(struct nvt_softc *);
  73. uint8_t nvt_readreg(struct nvt_softc *, uint8_t);
  74. void nvt_writereg(struct nvt_softc *, uint8_t, uint8_t);
  75. struct cfattach nvt_ca = {
  76. sizeof(struct nvt_softc), nvt_match, nvt_attach
  77. };
  78. struct cfdriver nvt_cd = {
  79. NULL, "nvt", DV_DULL
  80. };
  81. int
  82. nvt_match(struct device *parent, void *match, void *aux)
  83. {
  84. struct i2c_attach_args *ia = aux;
  85. if (strcmp(ia->ia_name, "w83795g") == 0)
  86. return (1);
  87. return (0);
  88. }
  89. void
  90. nvt_attach(struct device *parent, struct device *self, void *aux)
  91. {
  92. struct nvt_softc *sc = (struct nvt_softc *)self;
  93. struct i2c_attach_args *ia = aux;
  94. uint8_t cfg, vctrl1, vctrl2;
  95. uint8_t tctrl1, tctrl2, fctrl1, fctrl2;
  96. int i, j;
  97. sc->sc_tag = ia->ia_tag;
  98. sc->sc_addr = ia->ia_addr;
  99. cfg = nvt_readreg(sc, NVT_CONFIG);
  100. if (cfg & NVT_CONFIG_48)
  101. printf(": W83795ADG");
  102. else
  103. printf(": W83795G");
  104. vctrl1 = nvt_readreg(sc, NVT_VOLT_CTRL1);
  105. vctrl2 = nvt_readreg(sc, NVT_VOLT_CTRL2);
  106. tctrl1 = nvt_readreg(sc, NVT_TEMP_CTRL1);
  107. tctrl2 = nvt_readreg(sc, NVT_TEMP_CTRL2);
  108. fctrl1 = nvt_readreg(sc, NVT_FANIN_CTRL1);
  109. fctrl2 = nvt_readreg(sc, NVT_FANIN_CTRL2);
  110. sc->sc_vctrl = vctrl2 << 8 | vctrl1;
  111. sc->sc_tctrl1 = tctrl1;
  112. sc->sc_tctrl2 = tctrl2;
  113. sc->sc_fctrl = fctrl2 << 8 | fctrl1;
  114. strlcpy(sc->sc_sensordev.xname, sc->sc_dev.dv_xname,
  115. sizeof(sc->sc_sensordev.xname));
  116. for (i = 0; i < NVT_NUM_VOLTS; i++) {
  117. strlcpy(sc->sc_sensors[i].desc, nvt_volt_desc[i],
  118. sizeof(sc->sc_sensors[i].desc));
  119. sc->sc_sensors[i].type = SENSOR_VOLTS_DC;
  120. }
  121. for (j = i + NVT_NUM_TEMPS; i < j; i++)
  122. sc->sc_sensors[i].type = SENSOR_TEMP;
  123. for (j = i + NVT_NUM_FANS; i < j; i++)
  124. sc->sc_sensors[i].type = SENSOR_FANRPM;
  125. for (i = 0; i < NVT_NUM_VOLTS + NVT_NUM_TEMPS + NVT_NUM_FANS; i++)
  126. sensor_attach(&sc->sc_sensordev, &sc->sc_sensors[i]);
  127. if (sensor_task_register(sc, nvt_refresh, 5) == NULL) {
  128. printf(", unable to register update task\n");
  129. return;
  130. }
  131. sensordev_install(&sc->sc_sensordev);
  132. printf("\n");
  133. }
  134. void
  135. nvt_refresh(void *arg)
  136. {
  137. struct nvt_softc *sc = arg;
  138. uint8_t bsr;
  139. iic_acquire_bus(sc->sc_tag, 0);
  140. bsr = nvt_readreg(sc, NVT_BANKSELECT);
  141. if ((bsr & 0x07) != 0x00)
  142. nvt_writereg(sc, NVT_BANKSELECT, bsr & 0xf8);
  143. nvt_refresh_volts(sc);
  144. nvt_refresh_temps(sc);
  145. nvt_refresh_fans(sc);
  146. if ((bsr & 0x07) != 0x00)
  147. nvt_writereg(sc, NVT_BANKSELECT, bsr);
  148. iic_release_bus(sc->sc_tag, 0);
  149. }
  150. void
  151. nvt_refresh_volts(struct nvt_softc *sc)
  152. {
  153. struct ksensor *s = &sc->sc_sensors[0];
  154. uint8_t vrlsb, data;
  155. int i, reg;
  156. for (i = 0; i < NVT_NUM_VOLTS; i++) {
  157. if ((sc->sc_vctrl & (1 << i)) == 0) {
  158. s[i].flags |= SENSOR_FINVALID;
  159. s[i].value = 0;
  160. continue;
  161. }
  162. reg = NVT_VSEN1 + i;
  163. data = nvt_readreg(sc, reg);
  164. vrlsb = nvt_readreg(sc, NVT_VRLSB);
  165. if (reg != NVT_3VDD && reg != NVT_3VSB && reg != NVT_VBAT)
  166. s[i].value = 10000000 - ((data << 3) | (vrlsb >> 6)) * 2000;
  167. else
  168. s[i].value = 10000000 - ((data << 3) | (vrlsb >> 6)) * 6000;
  169. s[i].flags &= ~SENSOR_FINVALID;
  170. }
  171. }
  172. void
  173. nvt_refresh_temps(struct nvt_softc *sc)
  174. {
  175. struct ksensor *s = &sc->sc_sensors[NVT_NUM_VOLTS];
  176. uint8_t vrlsb;
  177. int8_t data;
  178. int i;
  179. for (i = 0; i < NVT_NUM_TEMPS; i++) {
  180. if (i < NVT_NUM_TR
  181. && (sc->sc_tctrl1 & (1 << (2 * i))) == 0) {
  182. s[i].flags |= SENSOR_FINVALID;
  183. s[i].value = 0;
  184. continue;
  185. }
  186. if (i >= NVT_NUM_TR
  187. && (sc->sc_tctrl2 & (1 << (2 * (i - NVT_NUM_TR)))) == 0) {
  188. s[i].flags |= SENSOR_FINVALID;
  189. s[i].value = 0;
  190. continue;
  191. }
  192. data = nvt_readreg(sc, NVT_TR5 + i);
  193. vrlsb = nvt_readreg(sc, NVT_VRLSB);
  194. if (data == -128 && (vrlsb >> 6) == 0) {
  195. s[i].flags |= SENSOR_FINVALID;
  196. s[i].value = 0;
  197. continue;
  198. }
  199. s[i].value = data * 1000000 + (vrlsb >> 6) * 250000;
  200. s[i].value += 273150000;
  201. s[i].flags &= ~SENSOR_FINVALID;
  202. }
  203. }
  204. void
  205. nvt_refresh_fans(struct nvt_softc *sc)
  206. {
  207. struct ksensor *s = &sc->sc_sensors[NVT_NUM_VOLTS + NVT_NUM_TEMPS];
  208. uint8_t data, vrlsb;
  209. uint16_t count;
  210. int i;
  211. for (i = 0; i < NVT_NUM_FANS; i++) {
  212. if ((sc->sc_fctrl & (1 << i)) == 0) {
  213. s[i].flags |= SENSOR_FINVALID;
  214. s[i].value = 0;
  215. continue;
  216. }
  217. data = nvt_readreg(sc, NVT_FANIN1_COUNT + i);
  218. vrlsb = nvt_readreg(sc, NVT_VRLSB);
  219. count = (data << 4) + (vrlsb >> 4);
  220. if (count == 0) {
  221. s[i].flags |= SENSOR_FINVALID;
  222. s[i].value = 0;
  223. continue;
  224. }
  225. s[i].value = 1350000 / (count * 2);
  226. s[i].flags &= ~SENSOR_FINVALID;
  227. }
  228. }
  229. uint8_t
  230. nvt_readreg(struct nvt_softc *sc, uint8_t reg)
  231. {
  232. uint8_t data;
  233. iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
  234. sc->sc_addr, &reg, sizeof reg, &data, sizeof data, 0);
  235. return data;
  236. }
  237. void
  238. nvt_writereg(struct nvt_softc *sc, uint8_t reg, uint8_t data)
  239. {
  240. iic_exec(sc->sc_tag, I2C_OP_WRITE_WITH_STOP,
  241. sc->sc_addr, &reg, sizeof reg, &data, sizeof data, 0);
  242. }