it.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548
  1. /* $OpenBSD: it.c,v 1.46 2015/03/14 03:38:47 jsg Exp $ */
  2. /*
  3. * Copyright (c) 2007-2008 Oleg Safiullin <form@pdp-11.org.ru>
  4. * Copyright (c) 2006-2007 Juan Romero Pardines <juan@xtrarom.org>
  5. * Copyright (c) 2003 Julien Bordet <zejames@greyhats.org>
  6. * All rights reserved.
  7. *
  8. * Redistribution and use in source and binary forms, with or without
  9. * modification, are permitted provided that the following conditions
  10. * are met:
  11. * 1. Redistributions of source code must retain the above copyright
  12. * notice, this list of conditions and the following disclaimer.
  13. * 2. Redistributions in binary form must reproduce the above copyright
  14. * notice, this list of conditions and the following disclaimer in the
  15. * documentation and/or other materials provided with the distribution.
  16. *
  17. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  18. * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  19. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  20. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  21. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  22. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  23. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  24. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  25. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  26. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27. */
  28. #include <sys/param.h>
  29. #include <sys/systm.h>
  30. #include <sys/device.h>
  31. #include <sys/sensors.h>
  32. #include <machine/bus.h>
  33. #include <dev/isa/isavar.h>
  34. #include <dev/isa/itvar.h>
  35. #if defined(ITDEBUG)
  36. #define DPRINTF(x) do { printf x; } while (0)
  37. #else
  38. #define DPRINTF(x)
  39. #endif
  40. int it_match(struct device *, void *, void *);
  41. void it_attach(struct device *, struct device *, void *);
  42. int it_activate(struct device *, int);
  43. u_int8_t it_readreg(bus_space_tag_t, bus_space_handle_t, int);
  44. void it_writereg(bus_space_tag_t, bus_space_handle_t, int, u_int8_t);
  45. void it_enter(bus_space_tag_t, bus_space_handle_t, int);
  46. void it_exit(bus_space_tag_t, bus_space_handle_t);
  47. u_int8_t it_ec_readreg(struct it_softc *, int);
  48. void it_ec_writereg(struct it_softc *, int, u_int8_t);
  49. void it_ec_refresh(void *arg);
  50. int it_wdog_cb(void *, int);
  51. /*
  52. * IT87-compatible chips can typically measure voltages up to 4.096 V.
  53. * To measure higher voltages the input is attenuated with (external)
  54. * resistors. Negative voltages are measured using a reference
  55. * voltage. So we have to convert the sensor values back to real
  56. * voltages by applying the appropriate resistor factor.
  57. */
  58. #define RFACT_NONE 10000
  59. #define RFACT(x, y) (RFACT_NONE * ((x) + (y)) / (y))
  60. struct {
  61. enum sensor_type type;
  62. const char *desc;
  63. } it_sensors[IT_EC_NUMSENSORS] = {
  64. #define IT_TEMP_BASE 0
  65. #define IT_TEMP_COUNT 3
  66. { SENSOR_TEMP, NULL },
  67. { SENSOR_TEMP, NULL },
  68. { SENSOR_TEMP, NULL },
  69. #define IT_FAN_BASE 3
  70. #define IT_FAN_COUNT 5
  71. { SENSOR_FANRPM, NULL },
  72. { SENSOR_FANRPM, NULL },
  73. { SENSOR_FANRPM, NULL },
  74. { SENSOR_FANRPM, NULL },
  75. { SENSOR_FANRPM, NULL },
  76. #define IT_VOLT_BASE 8
  77. #define IT_VOLT_COUNT 9
  78. { SENSOR_VOLTS_DC, "VCORE_A" },
  79. { SENSOR_VOLTS_DC, "VCORE_B" },
  80. { SENSOR_VOLTS_DC, "+3.3V" },
  81. { SENSOR_VOLTS_DC, "+5V" },
  82. { SENSOR_VOLTS_DC, "+12V" },
  83. { SENSOR_VOLTS_DC, "-12V" },
  84. { SENSOR_VOLTS_DC, "-5V" },
  85. { SENSOR_VOLTS_DC, "+5VSB" },
  86. { SENSOR_VOLTS_DC, "VBAT" }
  87. };
  88. /* rfact values for voltage sensors */
  89. int it_vrfact[IT_VOLT_COUNT] = {
  90. RFACT_NONE, /* VCORE_A */
  91. RFACT_NONE, /* VCORE_A */
  92. RFACT_NONE, /* +3.3V */
  93. RFACT(68, 100), /* +5V */
  94. RFACT(30, 10), /* +12V */
  95. RFACT(83, 20), /* -12V */
  96. RFACT(21, 10), /* -5V */
  97. RFACT(68, 100), /* +5VSB */
  98. RFACT_NONE /* VBAT */
  99. };
  100. int it_fan_regs[] = {
  101. IT_EC_FAN_TAC1, IT_EC_FAN_TAC2, IT_EC_FAN_TAC3,
  102. IT_EC_FAN_TAC4_LSB, IT_EC_FAN_TAC5_LSB
  103. };
  104. int it_fan_ext_regs[] = {
  105. IT_EC_FAN_EXT_TAC1, IT_EC_FAN_EXT_TAC2, IT_EC_FAN_EXT_TAC3,
  106. IT_EC_FAN_TAC4_MSB, IT_EC_FAN_TAC5_MSB
  107. };
  108. LIST_HEAD(, it_softc) it_softc_list = LIST_HEAD_INITIALIZER(it_softc_list);
  109. int
  110. it_match(struct device *parent, void *match, void *aux)
  111. {
  112. struct isa_attach_args *ia = aux;
  113. struct it_softc *sc;
  114. bus_space_handle_t ioh;
  115. int ec_iobase, found = 0;
  116. u_int16_t cr;
  117. if (ia->ipa_io[0].base != IO_IT1 && ia->ipa_io[0].base != IO_IT2)
  118. return (0);
  119. /* map i/o space */
  120. if (bus_space_map(ia->ia_iot, ia->ipa_io[0].base, 2, 0, &ioh) != 0) {
  121. DPRINTF(("it_match: can't map i/o space"));
  122. return (0);
  123. }
  124. /* enter MB PnP mode */
  125. it_enter(ia->ia_iot, ioh, ia->ipa_io[0].base);
  126. /*
  127. * SMSC or similar SuperIO chips use 0x55 magic to enter PnP mode
  128. * and 0xaa to exit. These chips also enter PnP mode via ITE
  129. * `enter MB PnP mode' sequence, so force chip to exit PnP mode
  130. * if this is the case.
  131. */
  132. bus_space_write_1(ia->ia_iot, ioh, IT_IO_ADDR, 0xaa);
  133. /* get chip id */
  134. cr = it_readreg(ia->ia_iot, ioh, IT_CHIPID1) << 8;
  135. cr |= it_readreg(ia->ia_iot, ioh, IT_CHIPID2);
  136. switch (cr) {
  137. case IT_ID_8705:
  138. case IT_ID_8712:
  139. case IT_ID_8716:
  140. case IT_ID_8718:
  141. case IT_ID_8720:
  142. case IT_ID_8721:
  143. case IT_ID_8726:
  144. case IT_ID_8728:
  145. case IT_ID_8772:
  146. /* get environment controller base address */
  147. it_writereg(ia->ia_iot, ioh, IT_LDN, IT_EC_LDN);
  148. ec_iobase = it_readreg(ia->ia_iot, ioh, IT_EC_MSB) << 8;
  149. ec_iobase |= it_readreg(ia->ia_iot, ioh, IT_EC_LSB);
  150. /* check if device already attached */
  151. LIST_FOREACH(sc, &it_softc_list, sc_list)
  152. if (sc->sc_ec_iobase == ec_iobase)
  153. break;
  154. if (sc == NULL) {
  155. ia->ipa_nio = 1;
  156. ia->ipa_io[0].length = 2;
  157. ia->ipa_nmem = ia->ipa_nirq = ia->ipa_ndrq = 0;
  158. found++;
  159. }
  160. break;
  161. }
  162. /* exit MB PnP mode */
  163. it_exit(ia->ia_iot, ioh);
  164. /* unmap i/o space */
  165. bus_space_unmap(ia->ia_iot, ioh, 2);
  166. return (found);
  167. }
  168. void
  169. it_attach(struct device *parent, struct device *self, void *aux)
  170. {
  171. struct it_softc *sc = (void *)self;
  172. struct isa_attach_args *ia = aux;
  173. int i;
  174. sc->sc_iot = ia->ia_iot;
  175. sc->sc_iobase = ia->ipa_io[0].base;
  176. if (bus_space_map(sc->sc_iot, sc->sc_iobase, 2, 0, &sc->sc_ioh) != 0) {
  177. printf(": can't map i/o space\n");
  178. return;
  179. }
  180. /* enter MB PnP mode */
  181. it_enter(sc->sc_iot, sc->sc_ioh, sc->sc_iobase);
  182. /* get chip id and rev */
  183. sc->sc_chipid = it_readreg(sc->sc_iot, sc->sc_ioh, IT_CHIPID1) << 8;
  184. sc->sc_chipid |= it_readreg(sc->sc_iot, sc->sc_ioh, IT_CHIPID2);
  185. sc->sc_chiprev = it_readreg(sc->sc_iot, sc->sc_ioh, IT_CHIPREV) & 0x0f;
  186. /* get environment controller base address */
  187. it_writereg(sc->sc_iot, sc->sc_ioh, IT_LDN, IT_EC_LDN);
  188. sc->sc_ec_iobase = it_readreg(sc->sc_iot, sc->sc_ioh, IT_EC_MSB) << 8;
  189. sc->sc_ec_iobase |= it_readreg(sc->sc_iot, sc->sc_ioh, IT_EC_LSB);
  190. /* initialize watchdog timer */
  191. if (sc->sc_chipid != IT_ID_8705) {
  192. it_writereg(sc->sc_iot, sc->sc_ioh, IT_LDN, IT_WDT_LDN);
  193. it_writereg(sc->sc_iot, sc->sc_ioh, IT_WDT_CSR, 0x00);
  194. it_writereg(sc->sc_iot, sc->sc_ioh, IT_WDT_TCR, 0x00);
  195. wdog_register(it_wdog_cb, sc);
  196. }
  197. /* exit MB PnP mode and unmap */
  198. it_exit(sc->sc_iot, sc->sc_ioh);
  199. LIST_INSERT_HEAD(&it_softc_list, sc, sc_list);
  200. printf(": IT%xF rev %X", sc->sc_chipid, sc->sc_chiprev);
  201. if (sc->sc_ec_iobase == 0) {
  202. printf(", EC disabled\n");
  203. return;
  204. }
  205. printf(", EC port 0x%x\n", sc->sc_ec_iobase);
  206. /* map environment controller i/o space */
  207. sc->sc_ec_iot = ia->ia_iot;
  208. if (bus_space_map(sc->sc_ec_iot, sc->sc_ec_iobase, 8, 0,
  209. &sc->sc_ec_ioh) != 0) {
  210. printf("%s: can't map EC i/o space\n", sc->sc_dev.dv_xname);
  211. return;
  212. }
  213. /* initialize sensor structures */
  214. for (i = 0; i < IT_EC_NUMSENSORS; i++) {
  215. sc->sc_sensors[i].type = it_sensors[i].type;
  216. if (it_sensors[i].desc != NULL)
  217. strlcpy(sc->sc_sensors[i].desc, it_sensors[i].desc,
  218. sizeof(sc->sc_sensors[i].desc));
  219. }
  220. /* register sensor update task */
  221. if (sensor_task_register(sc, it_ec_refresh, IT_EC_INTERVAL) == NULL) {
  222. printf("%s: unable to register update task\n",
  223. sc->sc_dev.dv_xname);
  224. bus_space_unmap(sc->sc_ec_iot, sc->sc_ec_ioh, 8);
  225. return;
  226. }
  227. /* use 16-bit FAN tachometer registers for newer chips */
  228. if (sc->sc_chipid != IT_ID_8705 && sc->sc_chipid != IT_ID_8712)
  229. it_ec_writereg(sc, IT_EC_FAN_ECER,
  230. it_ec_readreg(sc, IT_EC_FAN_ECER) | 0x07);
  231. /* activate monitoring */
  232. it_ec_writereg(sc, IT_EC_CFG,
  233. it_ec_readreg(sc, IT_EC_CFG) | IT_EC_CFG_START | IT_EC_CFG_INTCLR);
  234. /* initialize sensors */
  235. strlcpy(sc->sc_sensordev.xname, sc->sc_dev.dv_xname,
  236. sizeof(sc->sc_sensordev.xname));
  237. for (i = 0; i < IT_EC_NUMSENSORS; i++)
  238. sensor_attach(&sc->sc_sensordev, &sc->sc_sensors[i]);
  239. sensordev_install(&sc->sc_sensordev);
  240. }
  241. int
  242. it_activate(struct device *self, int act)
  243. {
  244. switch (act) {
  245. case DVACT_POWERDOWN:
  246. wdog_shutdown(self);
  247. break;
  248. }
  249. return (0);
  250. }
  251. u_int8_t
  252. it_readreg(bus_space_tag_t iot, bus_space_handle_t ioh, int r)
  253. {
  254. bus_space_write_1(iot, ioh, IT_IO_ADDR, r);
  255. return (bus_space_read_1(iot, ioh, IT_IO_DATA));
  256. }
  257. void
  258. it_writereg(bus_space_tag_t iot, bus_space_handle_t ioh, int r, u_int8_t v)
  259. {
  260. bus_space_write_1(iot, ioh, IT_IO_ADDR, r);
  261. bus_space_write_1(iot, ioh, IT_IO_DATA, v);
  262. }
  263. void
  264. it_enter(bus_space_tag_t iot, bus_space_handle_t ioh, int iobase)
  265. {
  266. bus_space_write_1(iot, ioh, IT_IO_ADDR, 0x87);
  267. bus_space_write_1(iot, ioh, IT_IO_ADDR, 0x01);
  268. bus_space_write_1(iot, ioh, IT_IO_ADDR, 0x55);
  269. if (iobase == IO_IT1)
  270. bus_space_write_1(iot, ioh, IT_IO_ADDR, 0x55);
  271. else
  272. bus_space_write_1(iot, ioh, IT_IO_ADDR, 0xaa);
  273. }
  274. void
  275. it_exit(bus_space_tag_t iot, bus_space_handle_t ioh)
  276. {
  277. bus_space_write_1(iot, ioh, IT_IO_ADDR, IT_CCR);
  278. bus_space_write_1(iot, ioh, IT_IO_DATA, 0x02);
  279. }
  280. u_int8_t
  281. it_ec_readreg(struct it_softc *sc, int r)
  282. {
  283. bus_space_write_1(sc->sc_ec_iot, sc->sc_ec_ioh, IT_EC_ADDR, r);
  284. return (bus_space_read_1(sc->sc_ec_iot, sc->sc_ec_ioh, IT_EC_DATA));
  285. }
  286. void
  287. it_ec_writereg(struct it_softc *sc, int r, u_int8_t v)
  288. {
  289. bus_space_write_1(sc->sc_ec_iot, sc->sc_ec_ioh, IT_EC_ADDR, r);
  290. bus_space_write_1(sc->sc_ec_iot, sc->sc_ec_ioh, IT_EC_DATA, v);
  291. }
  292. void
  293. it_ec_refresh(void *arg)
  294. {
  295. struct it_softc *sc = arg;
  296. int i, sdata, divisor, odivisor, ndivisor;
  297. u_int8_t cr, ecr;
  298. /* refresh temp sensors */
  299. cr = it_ec_readreg(sc, IT_EC_ADC_TEMPER);
  300. for (i = 0; i < IT_TEMP_COUNT; i++) {
  301. sc->sc_sensors[IT_TEMP_BASE + i].flags &=
  302. SENSOR_FINVALID;
  303. if (!(cr & (1 << i)) && !(cr & (1 << (i + 3)))) {
  304. sc->sc_sensors[IT_TEMP_BASE + i].flags |=
  305. SENSOR_FINVALID;
  306. continue;
  307. }
  308. sdata = it_ec_readreg(sc, IT_EC_TEMPBASE + i);
  309. /* convert to degF */
  310. sc->sc_sensors[IT_TEMP_BASE + i].value =
  311. sdata * 1000000 + 273150000;
  312. }
  313. /* refresh volt sensors */
  314. cr = it_ec_readreg(sc, IT_EC_ADC_VINER);
  315. for (i = 0; i < IT_VOLT_COUNT; i++) {
  316. sc->sc_sensors[IT_VOLT_BASE + i].flags &=
  317. SENSOR_FINVALID;
  318. if ((i < 8) && !(cr & (1 << i))) {
  319. sc->sc_sensors[IT_VOLT_BASE + i].flags |=
  320. SENSOR_FINVALID;
  321. continue;
  322. }
  323. sdata = it_ec_readreg(sc, IT_EC_VOLTBASE + i);
  324. /* voltage returned as (mV >> 4) */
  325. sc->sc_sensors[IT_VOLT_BASE + i].value = sdata << 4;
  326. /* these two values are negative and formula is different */
  327. if (i == 5 || i == 6)
  328. sc->sc_sensors[IT_VOLT_BASE + i].value -= IT_EC_VREF;
  329. /* rfact is (factor * 10^4) */
  330. sc->sc_sensors[IT_VOLT_BASE + i].value *= it_vrfact[i];
  331. /* division by 10 gets us back to uVDC */
  332. sc->sc_sensors[IT_VOLT_BASE + i].value /= 10;
  333. if (i == 5 || i == 6)
  334. sc->sc_sensors[IT_VOLT_BASE + i].value +=
  335. IT_EC_VREF * 1000;
  336. }
  337. /* refresh fan sensors */
  338. cr = it_ec_readreg(sc, IT_EC_FAN_MCR);
  339. if (sc->sc_chipid != IT_ID_8705 && sc->sc_chipid != IT_ID_8712) {
  340. /* use 16-bit FAN tachometer registers */
  341. ecr = it_ec_readreg(sc, IT_EC_FAN_ECER);
  342. for (i = 0; i < IT_FAN_COUNT; i++) {
  343. sc->sc_sensors[IT_FAN_BASE + i].flags &=
  344. ~SENSOR_FINVALID;
  345. if (i < 3 && !(cr & (1 << (i + 4)))) {
  346. sc->sc_sensors[IT_FAN_BASE + i].flags |=
  347. SENSOR_FINVALID;
  348. continue;
  349. } else if (i > 2 && !(ecr & (1 << (i + 1)))) {
  350. sc->sc_sensors[IT_FAN_BASE + i].flags |=
  351. SENSOR_FINVALID;
  352. continue;
  353. }
  354. sdata = it_ec_readreg(sc, it_fan_regs[i]);
  355. sdata |= it_ec_readreg(sc, it_fan_ext_regs[i]) << 8;
  356. if (sdata == 0 || sdata == 0xffff)
  357. sc->sc_sensors[IT_FAN_BASE + i].value = 0;
  358. else
  359. sc->sc_sensors[IT_FAN_BASE + i].value =
  360. 675000 / sdata;
  361. }
  362. } else {
  363. /* use 8-bit FAN tachometer & FAN divisor registers */
  364. odivisor = ndivisor = divisor =
  365. it_ec_readreg(sc, IT_EC_FAN_DIV);
  366. for (i = 0; i < IT_FAN_COUNT; i++) {
  367. if (i > 2 || !(cr & (1 << (i + 4)))) {
  368. sc->sc_sensors[IT_FAN_BASE + i].flags |=
  369. SENSOR_FINVALID;
  370. continue;
  371. }
  372. sc->sc_sensors[IT_FAN_BASE + i].flags &=
  373. ~SENSOR_FINVALID;
  374. sdata = it_ec_readreg(sc, it_fan_regs[i]);
  375. if (sdata == 0xff) {
  376. sc->sc_sensors[IT_FAN_BASE + i].value = 0;
  377. if (i == 2)
  378. ndivisor ^= 0x40;
  379. else {
  380. ndivisor &= ~(7 << (i * 3));
  381. ndivisor |= ((divisor + 1) & 7) <<
  382. (i * 3);
  383. }
  384. } else if (sdata != 0) {
  385. if (i == 2)
  386. divisor = divisor & 1 ? 3 : 1;
  387. sc->sc_sensors[IT_FAN_BASE + i].value =
  388. 1350000 / (sdata << (divisor & 7));
  389. } else
  390. sc->sc_sensors[IT_FAN_BASE + i].value = 0;
  391. }
  392. if (ndivisor != odivisor)
  393. it_ec_writereg(sc, IT_EC_FAN_DIV, ndivisor);
  394. }
  395. }
  396. int
  397. it_wdog_cb(void *arg, int period)
  398. {
  399. struct it_softc *sc = arg;
  400. int minutes = 0;
  401. /* enter MB PnP mode and select WDT device */
  402. it_enter(sc->sc_iot, sc->sc_ioh, sc->sc_iobase);
  403. it_writereg(sc->sc_iot, sc->sc_ioh, IT_LDN, IT_WDT_LDN);
  404. /* disable watchdog timer */
  405. it_writereg(sc->sc_iot, sc->sc_ioh, IT_WDT_TCR, 0x00);
  406. /* 1000s should be enough for everyone */
  407. if (period > 1000)
  408. period = 1000;
  409. else if (period < 0)
  410. period = 0;
  411. if (period > 0) {
  412. /*
  413. * Older IT8712F chips have 8-bit timeout counter.
  414. * Use minutes for 16-bit values for these chips.
  415. */
  416. if (sc->sc_chipid == IT_ID_8712 && sc->sc_chiprev < 0x8 &&
  417. period > 0xff) {
  418. if (period % 60 >= 30)
  419. period += 60;
  420. period /= 60;
  421. minutes++;
  422. }
  423. /* set watchdog timeout (low byte) */
  424. it_writereg(sc->sc_iot, sc->sc_ioh, IT_WDT_TMO_LSB,
  425. period & 0xff);
  426. if (minutes) {
  427. /* enable watchdog timer */
  428. it_writereg(sc->sc_iot, sc->sc_ioh, IT_WDT_TCR,
  429. IT_WDT_TCR_KRST | IT_WDT_TCR_PWROK);
  430. period *= 60;
  431. } else {
  432. /* set watchdog timeout (high byte) */
  433. it_writereg(sc->sc_iot, sc->sc_ioh, IT_WDT_TMO_MSB,
  434. period >> 8);
  435. /* enable watchdog timer */
  436. it_writereg(sc->sc_iot, sc->sc_ioh, IT_WDT_TCR,
  437. IT_WDT_TCR_SECS | IT_WDT_TCR_KRST |
  438. IT_WDT_TCR_PWROK);
  439. }
  440. }
  441. /* exit MB PnP mode */
  442. it_exit(sc->sc_iot, sc->sc_ioh);
  443. return (period);
  444. }
  445. struct cfattach it_ca = {
  446. sizeof(struct it_softc),
  447. it_match,
  448. it_attach,
  449. NULL,
  450. it_activate
  451. };
  452. struct cfdriver it_cd = {
  453. NULL, "it", DV_DULL
  454. };