Lines Matching +full:slave +full:- +full:dev

1 /*-
45 #include <dev/pci/pcireg.h>
46 #include <dev/pci/pcivar.h>
47 #include <dev/smbus/smbconf.h>
53 /* Hardware Descriptor Constants - Control Field */
62 /* Hardware Descriptor Constants - Status Field */
182 val = bus_read_4(sc->mmio_res, ISMT_MSTR_MSTS); in ismt_intr()
183 ISMT_DEBUG(sc->pcidev, "%s MSTS=0x%x\n", __func__, val); in ismt_intr()
186 bus_write_4(sc->mmio_res, ISMT_MSTR_MSTS, val); in ismt_intr()
192 ismt_callback(device_t dev, int index, void *data) in ismt_callback() argument
197 sc = device_get_softc(dev); in ismt_callback()
202 (uintptr_t *)&sc->bus_reserved, in ismt_callback()
204 ISMT_DEBUG(dev, "SMB_REQUEST_BUS acquired=%d\n", acquired); in ismt_callback()
211 KASSERT(sc->bus_reserved == curthread, in ismt_callback()
213 ISMT_DEBUG(dev, "SMB_RELEASE_BUS\n"); in ismt_callback()
214 atomic_store_rel_ptr((uintptr_t *)&sc->bus_reserved, in ismt_callback()
231 KASSERT(sc->bus_reserved == curthread, in ismt_alloc_desc()
233 curthread, sc->bus_reserved)); in ismt_alloc_desc()
235 desc = &sc->desc[sc->head++]; in ismt_alloc_desc()
236 if (sc->head == ISMT_DESC_ENTRIES) in ismt_alloc_desc()
237 sc->head = 0; in ismt_alloc_desc()
245 ismt_submit(struct ismt_softc *sc, struct ismt_desc *desc, uint8_t slave, in ismt_submit() argument
250 desc->control |= ISMT_DESC_FAIR; in ismt_submit()
251 if (sc->using_msi) in ismt_submit()
252 desc->control |= ISMT_DESC_INT; in ismt_submit()
254 desc->tgtaddr_rw = ISMT_DESC_ADDR_RW(slave, is_read); in ismt_submit()
255 desc->dptr_low = (sc->dma_buffer_bus_addr & 0xFFFFFFFFLL); in ismt_submit()
256 desc->dptr_high = (sc->dma_buffer_bus_addr >> 32); in ismt_submit()
260 fmhp = sc->head << 16; in ismt_submit()
261 val = bus_read_4(sc->mmio_res, ISMT_MSTR_MCTRL); in ismt_submit()
264 bus_write_4(sc->mmio_res, ISMT_MSTR_MCTRL, val); in ismt_submit()
267 val = bus_read_4(sc->mmio_res, ISMT_MSTR_MCTRL); in ismt_submit()
269 bus_write_4(sc->mmio_res, ISMT_MSTR_MCTRL, val); in ismt_submit()
274 ISMT_DEBUG(sc->pcidev, "%s timeout\n", __func__); in ismt_submit()
278 ISMT_DEBUG(sc->pcidev, "%s status=0x%x\n", __func__, desc->status); in ismt_submit()
280 if (desc->status & ISMT_DESC_SCS) in ismt_submit()
283 if (desc->status & ISMT_DESC_NAK) in ismt_submit()
286 if (desc->status & ISMT_DESC_CRC) in ismt_submit()
289 if (desc->status & ISMT_DESC_COL) in ismt_submit()
292 if (desc->status & ISMT_DESC_LPR) in ismt_submit()
295 if (desc->status & (ISMT_DESC_DLTO | ISMT_DESC_CLTO)) in ismt_submit()
303 ismt_quick(device_t dev, u_char slave, int how) in ismt_quick() argument
309 ISMT_DEBUG(dev, "%s\n", __func__); in ismt_quick()
315 sc = device_get_softc(dev); in ismt_quick()
318 return (ismt_submit(sc, desc, slave, is_read)); in ismt_quick()
322 ismt_sendb(device_t dev, u_char slave, char byte) in ismt_sendb() argument
327 ISMT_DEBUG(dev, "%s\n", __func__); in ismt_sendb()
329 sc = device_get_softc(dev); in ismt_sendb()
331 desc->control = ISMT_DESC_CWRL; in ismt_sendb()
332 desc->wr_len_cmd = byte; in ismt_sendb()
334 return (ismt_submit(sc, desc, slave, 0)); in ismt_sendb()
338 ismt_recvb(device_t dev, u_char slave, char *byte) in ismt_recvb() argument
344 ISMT_DEBUG(dev, "%s\n", __func__); in ismt_recvb()
346 sc = device_get_softc(dev); in ismt_recvb()
348 desc->rd_len = 1; in ismt_recvb()
350 err = ismt_submit(sc, desc, slave, 1); in ismt_recvb()
355 *byte = sc->dma_buffer[0]; in ismt_recvb()
361 ismt_writeb(device_t dev, u_char slave, char cmd, char byte) in ismt_writeb() argument
366 ISMT_DEBUG(dev, "%s\n", __func__); in ismt_writeb()
368 sc = device_get_softc(dev); in ismt_writeb()
370 desc->wr_len_cmd = 2; in ismt_writeb()
371 sc->dma_buffer[0] = cmd; in ismt_writeb()
372 sc->dma_buffer[1] = byte; in ismt_writeb()
374 return (ismt_submit(sc, desc, slave, 0)); in ismt_writeb()
378 ismt_writew(device_t dev, u_char slave, char cmd, short word) in ismt_writew() argument
383 ISMT_DEBUG(dev, "%s\n", __func__); in ismt_writew()
385 sc = device_get_softc(dev); in ismt_writew()
387 desc->wr_len_cmd = 3; in ismt_writew()
388 sc->dma_buffer[0] = cmd; in ismt_writew()
389 sc->dma_buffer[1] = word & 0xFF; in ismt_writew()
390 sc->dma_buffer[2] = word >> 8; in ismt_writew()
392 return (ismt_submit(sc, desc, slave, 0)); in ismt_writew()
396 ismt_readb(device_t dev, u_char slave, char cmd, char *byte) in ismt_readb() argument
402 ISMT_DEBUG(dev, "%s\n", __func__); in ismt_readb()
404 sc = device_get_softc(dev); in ismt_readb()
406 desc->control = ISMT_DESC_CWRL; in ismt_readb()
407 desc->wr_len_cmd = cmd; in ismt_readb()
408 desc->rd_len = 1; in ismt_readb()
410 err = ismt_submit(sc, desc, slave, 1); in ismt_readb()
415 *byte = sc->dma_buffer[0]; in ismt_readb()
421 ismt_readw(device_t dev, u_char slave, char cmd, short *word) in ismt_readw() argument
427 ISMT_DEBUG(dev, "%s\n", __func__); in ismt_readw()
429 sc = device_get_softc(dev); in ismt_readw()
431 desc->control = ISMT_DESC_CWRL; in ismt_readw()
432 desc->wr_len_cmd = cmd; in ismt_readw()
433 desc->rd_len = 2; in ismt_readw()
435 err = ismt_submit(sc, desc, slave, 1); in ismt_readw()
440 *word = sc->dma_buffer[0] | (sc->dma_buffer[1] << 8); in ismt_readw()
446 ismt_pcall(device_t dev, u_char slave, char cmd, short sdata, short *rdata) in ismt_pcall() argument
452 ISMT_DEBUG(dev, "%s\n", __func__); in ismt_pcall()
454 sc = device_get_softc(dev); in ismt_pcall()
456 desc->wr_len_cmd = 3; in ismt_pcall()
457 desc->rd_len = 2; in ismt_pcall()
458 sc->dma_buffer[0] = cmd; in ismt_pcall()
459 sc->dma_buffer[1] = sdata & 0xff; in ismt_pcall()
460 sc->dma_buffer[2] = sdata >> 8; in ismt_pcall()
462 err = ismt_submit(sc, desc, slave, 0); in ismt_pcall()
467 *rdata = sc->dma_buffer[0] | (sc->dma_buffer[1] << 8); in ismt_pcall()
473 ismt_bwrite(device_t dev, u_char slave, char cmd, u_char count, char *buf) in ismt_bwrite() argument
478 ISMT_DEBUG(dev, "%s\n", __func__); in ismt_bwrite()
483 sc = device_get_softc(dev); in ismt_bwrite()
485 desc->control = ISMT_DESC_I2C; in ismt_bwrite()
486 desc->wr_len_cmd = count + 1; in ismt_bwrite()
487 sc->dma_buffer[0] = cmd; in ismt_bwrite()
488 memcpy(&sc->dma_buffer[1], buf, count); in ismt_bwrite()
490 return (ismt_submit(sc, desc, slave, 0)); in ismt_bwrite()
494 ismt_bread(device_t dev, u_char slave, char cmd, u_char *count, char *buf) in ismt_bread() argument
500 ISMT_DEBUG(dev, "%s\n", __func__); in ismt_bread()
505 sc = device_get_softc(dev); in ismt_bread()
507 desc->control = ISMT_DESC_I2C | ISMT_DESC_CWRL; in ismt_bread()
508 desc->wr_len_cmd = cmd; in ismt_bread()
509 desc->rd_len = *count; in ismt_bread()
511 err = ismt_submit(sc, desc, slave, 0); in ismt_bread()
516 memcpy(buf, sc->dma_buffer, desc->rxbytes); in ismt_bread()
517 *count = desc->rxbytes; in ismt_bread()
523 ismt_detach(device_t dev) in ismt_detach() argument
528 ISMT_DEBUG(dev, "%s\n", __func__); in ismt_detach()
529 sc = device_get_softc(dev); in ismt_detach()
531 error = bus_generic_detach(dev); in ismt_detach()
535 device_delete_child(dev, sc->smbdev); in ismt_detach()
537 if (sc->intr_handle != NULL) { in ismt_detach()
538 bus_teardown_intr(dev, sc->intr_res, sc->intr_handle); in ismt_detach()
539 sc->intr_handle = NULL; in ismt_detach()
541 if (sc->intr_res != NULL) { in ismt_detach()
542 bus_release_resource(dev, in ismt_detach()
543 SYS_RES_IRQ, sc->intr_rid, sc->intr_res); in ismt_detach()
544 sc->intr_res = NULL; in ismt_detach()
546 if (sc->using_msi == 1) in ismt_detach()
547 pci_release_msi(dev); in ismt_detach()
549 if (sc->mmio_res != NULL) { in ismt_detach()
550 bus_release_resource(dev, in ismt_detach()
551 SYS_RES_MEMORY, sc->mmio_rid, sc->mmio_res); in ismt_detach()
552 sc->mmio_res = NULL; in ismt_detach()
555 bus_dmamap_unload(sc->desc_dma_tag, sc->desc_dma_map); in ismt_detach()
556 bus_dmamap_unload(sc->dma_buffer_dma_tag, sc->dma_buffer_dma_map); in ismt_detach()
558 bus_dmamem_free(sc->desc_dma_tag, sc->desc, in ismt_detach()
559 sc->desc_dma_map); in ismt_detach()
560 bus_dmamem_free(sc->dma_buffer_dma_tag, sc->dma_buffer, in ismt_detach()
561 sc->dma_buffer_dma_map); in ismt_detach()
563 bus_dma_tag_destroy(sc->desc_dma_tag); in ismt_detach()
564 bus_dma_tag_destroy(sc->dma_buffer_dma_tag); in ismt_detach()
566 pci_disable_busmaster(dev); in ismt_detach()
583 ismt_attach(device_t dev) in ismt_attach() argument
585 struct ismt_softc *sc = device_get_softc(dev); in ismt_attach()
588 sc->pcidev = dev; in ismt_attach()
589 pci_enable_busmaster(dev); in ismt_attach()
591 if ((sc->smbdev = device_add_child(dev, "smbus", -1)) == NULL) { in ismt_attach()
592 device_printf(dev, "no smbus child found\n"); in ismt_attach()
597 sc->mmio_rid = PCIR_BAR(0); in ismt_attach()
598 sc->mmio_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, in ismt_attach()
599 &sc->mmio_rid, RF_ACTIVE); in ismt_attach()
600 if (sc->mmio_res == NULL) { in ismt_attach()
601 device_printf(dev, "cannot allocate mmio region\n"); in ismt_attach()
606 sc->mmio_tag = rman_get_bustag(sc->mmio_res); in ismt_attach()
607 sc->mmio_handle = rman_get_bushandle(sc->mmio_res); in ismt_attach()
610 if ((err = bus_generic_attach(dev)) != 0) { in ismt_attach()
611 device_printf(dev, "failed to attach child: %d\n", err); in ismt_attach()
616 bus_dma_tag_create(bus_get_dma_tag(dev), 4, PAGE_SIZE, in ismt_attach()
619 0, NULL, NULL, &sc->desc_dma_tag); in ismt_attach()
621 bus_dma_tag_create(bus_get_dma_tag(dev), 4, PAGE_SIZE, in ismt_attach()
624 0, NULL, NULL, &sc->dma_buffer_dma_tag); in ismt_attach()
626 bus_dmamap_create(sc->desc_dma_tag, 0, in ismt_attach()
627 &sc->desc_dma_map); in ismt_attach()
628 bus_dmamap_create(sc->dma_buffer_dma_tag, 0, in ismt_attach()
629 &sc->dma_buffer_dma_map); in ismt_attach()
631 bus_dmamem_alloc(sc->desc_dma_tag, in ismt_attach()
632 (void **)&sc->desc, BUS_DMA_WAITOK, in ismt_attach()
633 &sc->desc_dma_map); in ismt_attach()
634 bus_dmamem_alloc(sc->dma_buffer_dma_tag, in ismt_attach()
635 (void **)&sc->dma_buffer, BUS_DMA_WAITOK, in ismt_attach()
636 &sc->dma_buffer_dma_map); in ismt_attach()
638 bus_dmamap_load(sc->desc_dma_tag, in ismt_attach()
639 sc->desc_dma_map, sc->desc, DESC_SIZE, in ismt_attach()
640 ismt_single_map, &sc->desc_bus_addr, 0); in ismt_attach()
641 bus_dmamap_load(sc->dma_buffer_dma_tag, in ismt_attach()
642 sc->dma_buffer_dma_map, sc->dma_buffer, DMA_BUFFER_SIZE, in ismt_attach()
643 ismt_single_map, &sc->dma_buffer_bus_addr, 0); in ismt_attach()
645 bus_write_4(sc->mmio_res, ISMT_MSTR_MDBA, in ismt_attach()
646 (sc->desc_bus_addr & 0xFFFFFFFFLL)); in ismt_attach()
647 bus_write_4(sc->mmio_res, ISMT_MSTR_MDBA + 4, in ismt_attach()
648 (sc->desc_bus_addr >> 32)); in ismt_attach()
651 bus_write_4(sc->mmio_res, ISMT_MSTR_MCTRL, ISMT_MCTRL_MEIE); in ismt_attach()
654 bus_write_4(sc->mmio_res, ISMT_MSTR_MSTS, 0); in ismt_attach()
657 val = bus_read_4(sc->mmio_res, ISMT_MSTR_MDS); in ismt_attach()
659 val |= (ISMT_DESC_ENTRIES - 1); in ismt_attach()
660 bus_write_4(sc->mmio_res, ISMT_MSTR_MDS, val); in ismt_attach()
662 sc->using_msi = 1; in ismt_attach()
664 if (pci_msi_count(dev) == 0) { in ismt_attach()
665 sc->using_msi = 0; in ismt_attach()
670 if (pci_alloc_msi(dev, &num_vectors) != 0) { in ismt_attach()
671 sc->using_msi = 0; in ismt_attach()
675 sc->intr_rid = 1; in ismt_attach()
676 sc->intr_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, in ismt_attach()
677 &sc->intr_rid, RF_ACTIVE); in ismt_attach()
679 if (sc->intr_res == NULL) { in ismt_attach()
680 sc->using_msi = 0; in ismt_attach()
681 pci_release_msi(dev); in ismt_attach()
685 if (sc->using_msi == 0) { in ismt_attach()
686 sc->intr_rid = 0; in ismt_attach()
687 sc->intr_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, in ismt_attach()
688 &sc->intr_rid, RF_SHAREABLE | RF_ACTIVE); in ismt_attach()
689 if (sc->intr_res == NULL) { in ismt_attach()
690 device_printf(dev, "cannot allocate irq\n"); in ismt_attach()
696 ISMT_DEBUG(dev, "using_msi = %d\n", sc->using_msi); in ismt_attach()
698 err = bus_setup_intr(dev, sc->intr_res, in ismt_attach()
700 &sc->intr_handle); in ismt_attach()
702 device_printf(dev, "cannot setup interrupt\n"); in ismt_attach()
710 ismt_detach(dev); in ismt_attach()
720 ismt_probe(device_t dev) in ismt_probe() argument
724 switch (pci_get_devid(dev)) { in ismt_probe()
741 device_set_desc(dev, desc); in ismt_probe()