ichsmb.c revision 1.87 1 /* $NetBSD: ichsmb.c,v 1.87 2025/09/15 13:23:03 thorpej Exp $ */
2 /* $OpenBSD: ichiic.c,v 1.44 2020/10/07 11:23:05 jsg Exp $ */
3
4 /*
5 * Copyright (c) 2005, 2006 Alexander Yurchenko <grange (at) openbsd.org>
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 */
19
20 /*
21 * Intel ICH SMBus controller driver.
22 */
23
24 #include <sys/cdefs.h>
25 __KERNEL_RCSID(0, "$NetBSD: ichsmb.c,v 1.87 2025/09/15 13:23:03 thorpej Exp $");
26
27 #include <sys/param.h>
28 #include <sys/device.h>
29 #include <sys/errno.h>
30 #include <sys/kernel.h>
31 #include <sys/mutex.h>
32 #include <sys/condvar.h>
33 #include <sys/module.h>
34
35 #include <sys/bus.h>
36
37 #include <dev/pci/pcidevs.h>
38 #include <dev/pci/pcireg.h>
39 #include <dev/pci/pcivar.h>
40
41 #include <dev/ic/i82801lpcreg.h>
42
43 #include <dev/i2c/i2cvar.h>
44
45 #include <x86/pci/tco.h>
46
47 #ifdef ICHIIC_DEBUG
48 #define DPRINTF(x) printf x
49 #else
50 #define DPRINTF(x)
51 #endif
52
53 #define ICHIIC_DELAY 100
54 #define ICHIIC_TIMEOUT 1
55
56 struct ichsmb_softc {
57 device_t sc_dev;
58
59 bus_space_tag_t sc_iot;
60 bus_space_handle_t sc_ioh;
61 bus_size_t sc_size;
62 pci_chipset_tag_t sc_pc;
63 void * sc_ih;
64 int sc_poll;
65 pci_intr_handle_t *sc_pihp;
66
67 kmutex_t sc_exec_lock;
68 kcondvar_t sc_exec_wait;
69
70 struct i2c_controller sc_i2c_tag;
71 struct {
72 i2c_op_t op;
73 void * buf;
74 size_t len;
75 int flags;
76 int error;
77 bool done;
78 } sc_i2c_xfer;
79 device_t sc_i2c_device;
80
81 bus_space_tag_t sc_tcot;
82 bus_space_handle_t sc_tcoh;
83 bus_size_t sc_tcosz;
84 bus_space_tag_t sc_sbregt;
85 bus_space_handle_t sc_sbregh;
86 bus_size_t sc_sbregsz;
87 bus_space_tag_t sc_pmt;
88 bus_space_handle_t sc_pmh;
89 bus_size_t sc_pmsz;
90 bool sc_tco_probed;
91 device_t sc_tco_device;
92 };
93
94 static int ichsmb_match(device_t, cfdata_t, void *);
95 static void ichsmb_attach(device_t, device_t, void *);
96 static int ichsmb_detach(device_t, int);
97 static int ichsmb_rescan(device_t, const char *, const int *);
98 static void ichsmb_chdet(device_t, device_t);
99
100 static void ichsmb_probe_tco(struct ichsmb_softc *,
101 const struct pci_attach_args *);
102
103 static int ichsmb_i2c_exec(void *, i2c_op_t, i2c_addr_t, const void *,
104 size_t, void *, size_t, int);
105
106 static int ichsmb_intr(void *);
107
108 #include "ioconf.h"
109
110 CFATTACH_DECL3_NEW(ichsmb, sizeof(struct ichsmb_softc),
111 ichsmb_match, ichsmb_attach, ichsmb_detach, NULL, ichsmb_rescan,
112 ichsmb_chdet, DVF_DETACH_SHUTDOWN);
113
114
115 static int
116 ichsmb_match(device_t parent, cfdata_t match, void *aux)
117 {
118 struct pci_attach_args *pa = aux;
119
120 if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_INTEL) {
121 switch (PCI_PRODUCT(pa->pa_id)) {
122 case PCI_PRODUCT_INTEL_6300ESB_SMB:
123 case PCI_PRODUCT_INTEL_63XXESB_SMB:
124 case PCI_PRODUCT_INTEL_82801AA_SMB:
125 case PCI_PRODUCT_INTEL_82801AB_SMB:
126 case PCI_PRODUCT_INTEL_82801BA_SMB:
127 case PCI_PRODUCT_INTEL_82801CA_SMB:
128 case PCI_PRODUCT_INTEL_82801DB_SMB:
129 case PCI_PRODUCT_INTEL_82801E_SMB:
130 case PCI_PRODUCT_INTEL_82801EB_SMB:
131 case PCI_PRODUCT_INTEL_82801FB_SMB:
132 case PCI_PRODUCT_INTEL_82801G_SMB:
133 case PCI_PRODUCT_INTEL_82801H_SMB:
134 case PCI_PRODUCT_INTEL_82801I_SMB:
135 case PCI_PRODUCT_INTEL_82801JD_SMB:
136 case PCI_PRODUCT_INTEL_82801JI_SMB:
137 case PCI_PRODUCT_INTEL_3400_SMB:
138 case PCI_PRODUCT_INTEL_6SERIES_SMB:
139 case PCI_PRODUCT_INTEL_7SERIES_SMB:
140 case PCI_PRODUCT_INTEL_8SERIES_SMB:
141 case PCI_PRODUCT_INTEL_9SERIES_SMB:
142 case PCI_PRODUCT_INTEL_100SERIES_SMB:
143 case PCI_PRODUCT_INTEL_100SERIES_LP_SMB:
144 case PCI_PRODUCT_INTEL_2HS_SMB:
145 case PCI_PRODUCT_INTEL_3HS_SMB:
146 case PCI_PRODUCT_INTEL_3HS_U_SMB:
147 case PCI_PRODUCT_INTEL_4HS_H_SMB:
148 case PCI_PRODUCT_INTEL_4HS_V_SMB:
149 case PCI_PRODUCT_INTEL_CORE4G_M_SMB:
150 case PCI_PRODUCT_INTEL_CORE5G_M_SMB:
151 case PCI_PRODUCT_INTEL_CMTLK_SMB:
152 case PCI_PRODUCT_INTEL_BAYTRAIL_PCU_SMB:
153 case PCI_PRODUCT_INTEL_BSW_PCU_SMB:
154 case PCI_PRODUCT_INTEL_APL_SMB:
155 case PCI_PRODUCT_INTEL_GLK_SMB:
156 case PCI_PRODUCT_INTEL_EHL_SMB:
157 case PCI_PRODUCT_INTEL_JSL_SMB:
158 case PCI_PRODUCT_INTEL_SNR_SMB_LEGACY:
159 case PCI_PRODUCT_INTEL_ADL_N_SMB:
160 case PCI_PRODUCT_INTEL_C600_SMBUS:
161 case PCI_PRODUCT_INTEL_C600_SMB_0:
162 case PCI_PRODUCT_INTEL_C600_SMB_1:
163 case PCI_PRODUCT_INTEL_C600_SMB_2:
164 case PCI_PRODUCT_INTEL_C610_SMB:
165 case PCI_PRODUCT_INTEL_C620_SMB:
166 case PCI_PRODUCT_INTEL_C620_SMB_S:
167 case PCI_PRODUCT_INTEL_EP80579_SMB:
168 case PCI_PRODUCT_INTEL_DH89XXCC_SMB:
169 case PCI_PRODUCT_INTEL_DH89XXCL_SMB:
170 case PCI_PRODUCT_INTEL_C2000_PCU_SMBUS:
171 case PCI_PRODUCT_INTEL_C3K_SMBUS_LEGACY:
172 case PCI_PRODUCT_INTEL_495_YU_SMB:
173 case PCI_PRODUCT_INTEL_5HS_H_SMB:
174 case PCI_PRODUCT_INTEL_5HS_LP_SMB:
175 case PCI_PRODUCT_INTEL_6HS_H_SMB:
176 case PCI_PRODUCT_INTEL_6HS_LP_SMB:
177 case PCI_PRODUCT_INTEL_7HS_SMB:
178 case PCI_PRODUCT_INTEL_SMBUS_MTL:
179 return 1;
180 }
181 }
182 return 0;
183 }
184
185 static void
186 ichsmb_attach(device_t parent, device_t self, void *aux)
187 {
188 struct ichsmb_softc *sc = device_private(self);
189 struct pci_attach_args *pa = aux;
190 pcireg_t conf;
191 const char *intrstr = NULL;
192 char intrbuf[PCI_INTRSTR_LEN];
193
194 sc->sc_dev = self;
195 sc->sc_pc = pa->pa_pc;
196
197 pci_aprint_devinfo(pa, NULL);
198
199 mutex_init(&sc->sc_exec_lock, MUTEX_DEFAULT, IPL_BIO);
200 cv_init(&sc->sc_exec_wait, device_xname(self));
201
202 /* Read configuration */
203 conf = pci_conf_read(pa->pa_pc, pa->pa_tag, SMB_HOSTC);
204 DPRINTF(("%s: conf 0x%08x\n", device_xname(sc->sc_dev), conf));
205
206 if ((conf & SMB_HOSTC_HSTEN) == 0) {
207 aprint_error_dev(self, "SMBus disabled\n");
208 goto out;
209 }
210
211 /* Map I/O space */
212 if (pci_mapreg_map(pa, SMB_BASE, PCI_MAPREG_TYPE_IO, 0,
213 &sc->sc_iot, &sc->sc_ioh, NULL, &sc->sc_size)) {
214 aprint_error_dev(self, "can't map I/O space\n");
215 goto out;
216 }
217
218 sc->sc_poll = 1;
219 sc->sc_ih = NULL;
220 if (conf & SMB_HOSTC_SMIEN) {
221 /* No PCI IRQ */
222 aprint_normal_dev(self, "interrupting at SMI\n");
223 } else {
224 /* Install interrupt handler */
225 if (pci_intr_alloc(pa, &sc->sc_pihp, NULL, 0) == 0) {
226 intrstr = pci_intr_string(pa->pa_pc, sc->sc_pihp[0],
227 intrbuf, sizeof(intrbuf));
228 pci_intr_setattr(pa->pa_pc, &sc->sc_pihp[0],
229 PCI_INTR_MPSAFE, true);
230 sc->sc_ih = pci_intr_establish_xname(pa->pa_pc,
231 sc->sc_pihp[0], IPL_BIO, ichsmb_intr, sc,
232 device_xname(sc->sc_dev));
233 if (sc->sc_ih != NULL) {
234 aprint_normal_dev(self, "interrupting at %s\n",
235 intrstr);
236 sc->sc_poll = 0;
237 } else {
238 pci_intr_release(pa->pa_pc, sc->sc_pihp, 1);
239 sc->sc_pihp = NULL;
240 }
241 }
242 if (sc->sc_poll)
243 aprint_normal_dev(self, "polling\n");
244 }
245
246 /* Attach I2C bus */
247 iic_tag_init(&sc->sc_i2c_tag);
248 sc->sc_i2c_tag.ic_cookie = sc;
249 sc->sc_i2c_tag.ic_exec = ichsmb_i2c_exec;
250
251 /*
252 * Probe to see if there's a TCO hanging here instead of the
253 * LPCIB and map it if we can.
254 */
255 ichsmb_probe_tco(sc, pa);
256
257 sc->sc_i2c_device = NULL;
258 ichsmb_rescan(self, NULL, NULL);
259
260 out: if (!pmf_device_register(self, NULL, NULL))
261 aprint_error_dev(self, "couldn't establish power handler\n");
262 }
263
264 static void
265 ichsmb_probe_tco(struct ichsmb_softc *sc, const struct pci_attach_args *pa)
266 {
267 const device_t self = sc->sc_dev;
268 const pci_chipset_tag_t pc = sc->sc_pc;
269 const pcitag_t p2sb_tag = pci_make_tag(pc,
270 /*bus*/0, /*dev*/0x1f, /*fn*/1);
271 const pcitag_t pmc_tag = pci_make_tag(pc,
272 /*bus*/0, /*dev*/0x1f, /*fn*/2);
273 pcireg_t tcoctl, tcobase, p2sbc, sbreglo, sbreghi;
274 bus_addr_t sbreg, pmbase;
275 int error = EIO;
276
277 /*
278 * Only attempt this on devices where we expect to find a TCO.
279 */
280 switch (PCI_PRODUCT(pa->pa_id)) {
281 case PCI_PRODUCT_INTEL_100SERIES_LP_SMB:
282 case PCI_PRODUCT_INTEL_100SERIES_SMB:
283 break;
284 default:
285 goto fail;
286 }
287
288 /*
289 * Verify the TCO base address register is enabled.
290 */
291 tcoctl = pci_conf_read(pa->pa_pc, pa->pa_tag, SMB_TCOCTL);
292 aprint_debug_dev(self, "TCOCTL=0x%"PRIx32"\n", tcoctl);
293 if ((tcoctl & SMB_TCOCTL_TCO_BASE_EN) == 0) {
294 aprint_debug_dev(self, "TCO disabled\n");
295 goto fail;
296 }
297
298 /*
299 * Verify the TCO base address register has the I/O space bit
300 * set -- otherwise we don't know how to interpret the
301 * register.
302 */
303 tcobase = pci_conf_read(pa->pa_pc, pa->pa_tag, SMB_TCOBASE);
304 aprint_debug_dev(self, "TCOBASE=0x%"PRIx32"\n", tcobase);
305 if ((tcobase & SMB_TCOBASE_IOS) == 0) {
306 aprint_error_dev(self, "unrecognized TCO space\n");
307 goto fail;
308 }
309
310 /*
311 * Map the TCO I/O space.
312 */
313 sc->sc_tcot = sc->sc_iot;
314 error = bus_space_map(sc->sc_tcot, tcobase & SMB_TCOBASE_TCOBA,
315 TCO_REGSIZE, 0, &sc->sc_tcoh);
316 if (error) {
317 aprint_error_dev(self, "failed to map TCO: %d\n", error);
318 goto fail;
319 }
320 sc->sc_tcosz = TCO_REGSIZE;
321
322 /*
323 * Clear the Hide Device bit so we can map the SBREG_BAR from
324 * the P2SB registers; then restore the Hide Device bit so
325 * nobody else gets confused.
326 *
327 * XXX Hope nobody else is trying to touch the P2SB!
328 *
329 * XXX Should we have a way to lock PCI bus enumeration,
330 * e.g. from concurrent drvctl rescan?
331 *
332 * XXX pci_mapreg_info doesn't work to get the size, somehow
333 * comes out as 4. Datasheet for 100-series chipset says the
334 * size is 16 MB, unconditionally, and the type is memory.
335 *
336 * XXX The above XXX comment was probably a result of PEBCAK
337 * when I tried to use 0xe4 instead of 0xe0 for P2SBC -- should
338 * try again with pci_mapreg_info or pci_mapreg_map.
339 */
340 p2sbc = pci_conf_read(pc, p2sb_tag, P2SB_P2SBC);
341 aprint_debug_dev(self, "P2SBC=0x%x\n", p2sbc);
342 pci_conf_write(pc, p2sb_tag, P2SB_P2SBC, p2sbc & ~P2SB_P2SBC_HIDE);
343 aprint_debug_dev(self, "P2SBC=0x%x -> 0x%x\n", p2sbc,
344 pci_conf_read(pc, p2sb_tag, P2SB_P2SBC));
345 sbreglo = pci_conf_read(pc, p2sb_tag, P2SB_SBREG_BAR);
346 sbreghi = pci_conf_read(pc, p2sb_tag, P2SB_SBREG_BARH);
347 aprint_debug_dev(self, "SBREG_BAR=0x%08x 0x%08x\n", sbreglo, sbreghi);
348 pci_conf_write(sc->sc_pc, p2sb_tag, P2SB_P2SBC, p2sbc);
349
350 /*
351 * Map the sideband registers so we can touch the NO_REBOOT
352 * bit.
353 */
354 sbreg = ((uint64_t)sbreghi << 32) | (sbreglo & ~__BITS(0,3));
355 if (((uint64_t)sbreg >> 32) != sbreghi) {
356 /* paranoia for 32-bit non-PAE */
357 aprint_error_dev(self, "can't map 64-bit SBREG\n");
358 goto fail;
359 }
360 sc->sc_sbregt = pa->pa_memt;
361 error = bus_space_map(sc->sc_sbregt, sbreg + SB_SMBUS_BASE,
362 SB_SMBUS_SIZE, 0, &sc->sc_sbregh);
363 if (error) {
364 aprint_error_dev(self, "failed to map SMBUS sideband: %d\n",
365 error);
366 goto fail;
367 }
368 sc->sc_sbregsz = SB_SMBUS_SIZE;
369
370 /*
371 * Map the power management configuration controller's I/O
372 * space. Older manual call this PMBASE for power management;
373 * newer manuals call it ABASE for ACPI. The chapters
374 * describing the registers say `power management' and I can't
375 * find any connection to ACPI (I suppose ACPI firmware logic
376 * probably peeks and pokes registers here?) so we say PMBASE
377 * here.
378 *
379 * XXX Hope nobody else is trying to touch it!
380 */
381 pmbase = pci_conf_read(pc, pmc_tag, LPCIB_PCI_PMBASE);
382 aprint_debug_dev(self, "PMBASE=0x%"PRIxBUSADDR"\n", pmbase);
383 if ((pmbase & 1) != 1) { /* I/O space bit? */
384 aprint_error_dev(self, "unrecognized PMC space\n");
385 goto fail;
386 }
387 sc->sc_pmt = sc->sc_iot;
388 error = bus_space_map(sc->sc_pmt, PCI_MAPREG_IO_ADDR(pmbase),
389 LPCIB_PCI_PM_SIZE, 0, &sc->sc_pmh);
390 if (error) {
391 aprint_error_dev(self, "failed to map PMC space: %d\n", error);
392 goto fail;
393 }
394 sc->sc_pmsz = LPCIB_PCI_PM_SIZE;
395
396 /* Success! */
397 sc->sc_tco_probed = true;
398 return;
399
400 fail: if (sc->sc_pmsz) {
401 bus_space_unmap(sc->sc_pmt, sc->sc_pmh, sc->sc_pmsz);
402 sc->sc_pmsz = 0;
403 }
404 if (sc->sc_sbregsz) {
405 bus_space_unmap(sc->sc_sbregt, sc->sc_sbregh, sc->sc_sbregsz);
406 sc->sc_sbregsz = 0;
407 }
408 if (sc->sc_tcosz) {
409 bus_space_unmap(sc->sc_tcot, sc->sc_tcoh, sc->sc_tcosz);
410 sc->sc_tcosz = 0;
411 }
412 }
413
414 static int
415 ichsmb_tco_set_noreboot(device_t tco, bool noreboot)
416 {
417 device_t self = device_parent(tco);
418 struct ichsmb_softc *sc = device_private(self);
419 uint32_t gc, gc1;
420
421 KASSERTMSG(tco == sc->sc_tco_device || sc->sc_tco_device == NULL,
422 "tco=%p child=%p", tco, sc->sc_tco_device);
423 KASSERTMSG(device_is_a(self, "ichsmb"), "%s@%s",
424 device_xname(tco), device_xname(self));
425
426 /*
427 * Try to clear the No Reboot bit.
428 */
429 gc = bus_space_read_4(sc->sc_sbregt, sc->sc_sbregh, SB_SMBUS_GC);
430 if (noreboot)
431 gc |= SB_SMBUS_GC_NR;
432 else
433 gc &= ~SB_SMBUS_GC_NR;
434 bus_space_write_4(sc->sc_sbregt, sc->sc_sbregh, SB_SMBUS_GC, gc);
435
436 /*
437 * Check whether we could make it what we want.
438 */
439 gc1 = bus_space_read_4(sc->sc_sbregt, sc->sc_sbregh, SB_SMBUS_GC);
440 aprint_debug_dev(self, "gc=0x%x -> 0x%x\n", gc, gc1);
441 if ((gc1 & SB_SMBUS_GC_NR) != (gc & SB_SMBUS_GC_NR))
442 return ENODEV;
443 return 0;
444 }
445
446 static int
447 ichsmb_rescan(device_t self, const char *ifattr, const int *locators)
448 {
449 struct ichsmb_softc *sc = device_private(self);
450
451 if (ifattr_match(ifattr, "i2cbus") && sc->sc_i2c_device == NULL) {
452 sc->sc_i2c_device = iicbus_attach(self, &sc->sc_i2c_tag);
453 }
454 if (sc->sc_tco_probed &&
455 ifattr_match(ifattr, "tcoichbus") &&
456 sc->sc_tco_device == NULL) {
457 struct tco_attach_args ta;
458
459 memset(&ta, 0, sizeof(ta));
460 ta.ta_version = TCO_VERSION_SMBUS;
461 ta.ta_pmt = sc->sc_pmt;
462 ta.ta_pmh = sc->sc_pmh;
463 ta.ta_tcot = sc->sc_tcot;
464 ta.ta_tcoh = sc->sc_tcoh;
465 ta.ta_set_noreboot = &ichsmb_tco_set_noreboot;
466 sc->sc_tco_device = config_found(self, &ta, NULL,
467 CFARGS(.iattr = "tcoichbus"));
468 }
469
470 return 0;
471 }
472
473 static int
474 ichsmb_detach(device_t self, int flags)
475 {
476 struct ichsmb_softc *sc = device_private(self);
477 int error;
478
479 error = config_detach_children(self, flags);
480 if (error)
481 return error;
482
483 iic_tag_fini(&sc->sc_i2c_tag);
484
485 if (sc->sc_ih) {
486 pci_intr_disestablish(sc->sc_pc, sc->sc_ih);
487 sc->sc_ih = NULL;
488 }
489
490 if (sc->sc_pihp) {
491 pci_intr_release(sc->sc_pc, sc->sc_pihp, 1);
492 sc->sc_pihp = NULL;
493 }
494
495 if (sc->sc_pmsz != 0)
496 bus_space_unmap(sc->sc_pmt, sc->sc_pmh, sc->sc_pmsz);
497 if (sc->sc_sbregsz != 0)
498 bus_space_unmap(sc->sc_sbregt, sc->sc_sbregh, sc->sc_sbregsz);
499 if (sc->sc_tcosz != 0)
500 bus_space_unmap(sc->sc_tcot, sc->sc_tcoh, sc->sc_tcosz);
501 if (sc->sc_size != 0)
502 bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_size);
503
504 mutex_destroy(&sc->sc_exec_lock);
505 cv_destroy(&sc->sc_exec_wait);
506
507 return 0;
508 }
509
510 static void
511 ichsmb_chdet(device_t self, device_t child)
512 {
513 struct ichsmb_softc *sc = device_private(self);
514
515 if (sc->sc_i2c_device == child)
516 sc->sc_i2c_device = NULL;
517 if (sc->sc_tco_device == child)
518 sc->sc_tco_device = NULL;
519 }
520
521 static int
522 ichsmb_i2c_exec(void *cookie, i2c_op_t op, i2c_addr_t addr,
523 const void *cmdbuf, size_t cmdlen, void *buf, size_t len, int flags)
524 {
525 struct ichsmb_softc *sc = cookie;
526 const uint8_t *b;
527 uint8_t ctl = 0, st;
528 int retries;
529 char fbuf[64];
530
531 DPRINTF(("%s: exec: op %d, addr 0x%02x, cmdlen %zu, len %zu, "
532 "flags 0x%02x\n", device_xname(sc->sc_dev), op, addr, cmdlen,
533 len, flags));
534
535 mutex_enter(&sc->sc_exec_lock);
536
537 /* Clear status bits */
538 bus_space_write_1(sc->sc_iot, sc->sc_ioh, SMB_HS,
539 SMB_HS_INTR | SMB_HS_DEVERR | SMB_HS_BUSERR | SMB_HS_FAILED);
540 bus_space_barrier(sc->sc_iot, sc->sc_ioh, SMB_HS, 1,
541 BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);
542
543 /* Wait for bus to be idle */
544 for (retries = 100; retries > 0; retries--) {
545 st = bus_space_read_1(sc->sc_iot, sc->sc_ioh, SMB_HS);
546 if (!(st & SMB_HS_BUSY))
547 break;
548 DELAY(ICHIIC_DELAY);
549 }
550 #ifdef ICHIIC_DEBUG
551 snprintb(fbuf, sizeof(fbuf), SMB_HS_BITS, st);
552 printf("%s: exec: st %s\n", device_xname(sc->sc_dev), fbuf);
553 #endif
554 if (st & SMB_HS_BUSY) {
555 mutex_exit(&sc->sc_exec_lock);
556 return (EBUSY);
557 }
558
559 if (sc->sc_poll)
560 flags |= I2C_F_POLL;
561
562 if (!I2C_OP_STOP_P(op) || cmdlen > 1 || len > 2 ||
563 (cmdlen == 0 && len > 1)) {
564 mutex_exit(&sc->sc_exec_lock);
565 return (EINVAL);
566 }
567
568 /* Setup transfer */
569 sc->sc_i2c_xfer.op = op;
570 sc->sc_i2c_xfer.buf = buf;
571 sc->sc_i2c_xfer.len = len;
572 sc->sc_i2c_xfer.flags = flags;
573 sc->sc_i2c_xfer.error = 0;
574 sc->sc_i2c_xfer.done = false;
575
576 /* Set slave address and transfer direction */
577 bus_space_write_1(sc->sc_iot, sc->sc_ioh, SMB_TXSLVA,
578 SMB_TXSLVA_ADDR(addr) |
579 (I2C_OP_READ_P(op) ? SMB_TXSLVA_READ : 0));
580
581 b = (const uint8_t *)cmdbuf;
582 if (cmdlen > 0)
583 /* Set command byte */
584 bus_space_write_1(sc->sc_iot, sc->sc_ioh, SMB_HCMD, b[0]);
585
586 if (I2C_OP_WRITE_P(op)) {
587 /* Write data */
588 b = buf;
589 if (cmdlen == 0 && len == 1)
590 bus_space_write_1(sc->sc_iot, sc->sc_ioh,
591 SMB_HCMD, b[0]);
592 else if (len > 0)
593 bus_space_write_1(sc->sc_iot, sc->sc_ioh,
594 SMB_HD0, b[0]);
595 if (len > 1)
596 bus_space_write_1(sc->sc_iot, sc->sc_ioh,
597 SMB_HD1, b[1]);
598 }
599
600 /* Set SMBus command */
601 if (cmdlen == 0) {
602 if (len == 0)
603 ctl = SMB_HC_CMD_QUICK;
604 else
605 ctl = SMB_HC_CMD_BYTE;
606 } else if (len == 1)
607 ctl = SMB_HC_CMD_BDATA;
608 else if (len == 2)
609 ctl = SMB_HC_CMD_WDATA;
610
611 if ((flags & I2C_F_POLL) == 0)
612 ctl |= SMB_HC_INTREN;
613
614 /* Start transaction */
615 ctl |= SMB_HC_START;
616 bus_space_write_1(sc->sc_iot, sc->sc_ioh, SMB_HC, ctl);
617
618 if (flags & I2C_F_POLL) {
619 /* Poll for completion */
620 DELAY(ICHIIC_DELAY);
621 for (retries = 1000; retries > 0; retries--) {
622 st = bus_space_read_1(sc->sc_iot, sc->sc_ioh, SMB_HS);
623 if ((st & SMB_HS_BUSY) == 0)
624 break;
625 DELAY(ICHIIC_DELAY);
626 }
627 if (st & SMB_HS_BUSY)
628 goto timeout;
629 ichsmb_intr(sc);
630 } else {
631 /* Wait for interrupt */
632 while (! sc->sc_i2c_xfer.done) {
633 if (cv_timedwait(&sc->sc_exec_wait, &sc->sc_exec_lock,
634 ICHIIC_TIMEOUT * hz))
635 goto timeout;
636 }
637 }
638
639 int error = sc->sc_i2c_xfer.error;
640 mutex_exit(&sc->sc_exec_lock);
641
642 return (error);
643
644 timeout:
645 /*
646 * Transfer timeout. Kill the transaction and clear status bits.
647 */
648 bus_space_write_1(sc->sc_iot, sc->sc_ioh, SMB_HC, SMB_HC_KILL);
649 DELAY(ICHIIC_DELAY);
650 st = bus_space_read_1(sc->sc_iot, sc->sc_ioh, SMB_HS);
651 if ((st & SMB_HS_FAILED) == 0) {
652 snprintb(fbuf, sizeof(fbuf), SMB_HS_BITS, st);
653 device_printf(sc->sc_dev, "abort failed, status %s\n",
654 fbuf);
655 }
656 bus_space_write_1(sc->sc_iot, sc->sc_ioh, SMB_HS, st);
657 mutex_exit(&sc->sc_exec_lock);
658 return (ETIMEDOUT);
659 }
660
661 static int
662 ichsmb_intr(void *arg)
663 {
664 struct ichsmb_softc *sc = arg;
665 uint8_t st;
666 uint8_t *b;
667 size_t len;
668 #ifdef ICHIIC_DEBUG
669 char fbuf[64];
670 #endif
671
672 /* Read status */
673 st = bus_space_read_1(sc->sc_iot, sc->sc_ioh, SMB_HS);
674
675 /* Clear status bits */
676 bus_space_write_1(sc->sc_iot, sc->sc_ioh, SMB_HS, st);
677
678 /* XXX Ignore SMBALERT# for now */
679 if ((st & SMB_HS_BUSY) != 0 ||
680 (st & (SMB_HS_INTR | SMB_HS_DEVERR | SMB_HS_BUSERR |
681 SMB_HS_FAILED | SMB_HS_BDONE)) == 0)
682 /* Interrupt was not for us */
683 return (0);
684
685 #ifdef ICHIIC_DEBUG
686 snprintb(fbuf, sizeof(fbuf), SMB_HS_BITS, st);
687 printf("%s: intr st %s\n", device_xname(sc->sc_dev), fbuf);
688 #endif
689
690 if ((sc->sc_i2c_xfer.flags & I2C_F_POLL) == 0)
691 mutex_enter(&sc->sc_exec_lock);
692
693 /* Check for errors */
694 if (st & (SMB_HS_DEVERR | SMB_HS_BUSERR | SMB_HS_FAILED)) {
695 sc->sc_i2c_xfer.error = EIO;
696 goto done;
697 }
698
699 if (st & SMB_HS_INTR) {
700 if (I2C_OP_WRITE_P(sc->sc_i2c_xfer.op))
701 goto done;
702
703 /* Read data */
704 b = sc->sc_i2c_xfer.buf;
705 len = sc->sc_i2c_xfer.len;
706 if (len > 0)
707 b[0] = bus_space_read_1(sc->sc_iot, sc->sc_ioh,
708 SMB_HD0);
709 if (len > 1)
710 b[1] = bus_space_read_1(sc->sc_iot, sc->sc_ioh,
711 SMB_HD1);
712 }
713
714 done:
715 sc->sc_i2c_xfer.done = true;
716 if ((sc->sc_i2c_xfer.flags & I2C_F_POLL) == 0) {
717 cv_signal(&sc->sc_exec_wait);
718 mutex_exit(&sc->sc_exec_lock);
719 }
720 return (1);
721 }
722
723 MODULE(MODULE_CLASS_DRIVER, ichsmb, "pci,iic");
724
725 #ifdef _MODULE
726 #include "ioconf.c"
727 #endif
728
729 static int
730 ichsmb_modcmd(modcmd_t cmd, void *opaque)
731 {
732 int error = 0;
733
734 switch (cmd) {
735 case MODULE_CMD_INIT:
736 #ifdef _MODULE
737 error = config_init_component(cfdriver_ioconf_ichsmb,
738 cfattach_ioconf_ichsmb, cfdata_ioconf_ichsmb);
739 #endif
740 break;
741 case MODULE_CMD_FINI:
742 #ifdef _MODULE
743 error = config_fini_component(cfdriver_ioconf_ichsmb,
744 cfattach_ioconf_ichsmb, cfdata_ioconf_ichsmb);
745 #endif
746 break;
747 default:
748 #ifdef _MODULE
749 error = ENOTTY;
750 #endif
751 break;
752 }
753
754 return error;
755 }
756