#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include struct xkodi_softc { bus_space_tag_t bst; bus_space_handle_t bsh; device_t dev; struct resource *res; int rid; }; static u_int32_t xrd(struct xkodi_softc *sc, int reg, int size) { switch (size) { case 1: return bus_space_read_1(sc->bst, sc->bsh, reg); case 2: return bus_space_read_2(sc->bst, sc->bsh, reg); case 3: return bus_space_read_4(sc->bst, sc->bsh, reg); default: return 0xffffffff; } } static void xwr(struct xkodi_softc *sc, int reg, u_int32_t data, int size) { switch (size) { case 1: bus_space_write_1(sc->bst, sc->bsh, reg, data); break; case 2: bus_space_write_2(sc->bst, sc->bsh, reg, data); break; case 4: bus_space_write_4(sc->bst, sc->bsh, reg, data); break; } } static int xkodi_rdi2c(struct xkodi_softc *sc, u_int32_t dev, u_int32_t addr) { u_int32_t data; int i; for (i = 0; i < 1000; i++) { data = xrd(sc, ENVY24_CCS13, 1); if ((data & 0x01) == 0) break; DELAY(32); /* 31.25kHz */ } if (i == 1000) { return -1; } xwr(sc, ENVY24_CCS11, addr, 1); xwr(sc, ENVY24_CCS10, (dev & 0xfe) | 0x00, 1); for (i = 0; i < 1000; i++) { data = xrd(sc, ENVY24_CCS13, 1); if ((data & 0x01) == 0) break; DELAY(32); /* 31.25kHz */ } if (i == 1000) { return -1; } data = xrd(sc, ENVY24_CCS12, 1); return (int) data; } static int xkodi_probe(device_t dev) { char *s = NULL; if (pci_get_device(dev) == ENVY24_PCI_ID) s = "ENVY24"; if (s) device_set_desc(dev, s); return s? 0 : ENXIO; } static int xkodi_attach(device_t dev) { struct xkodi_softc *sc; u_int32_t data; u_int32_t e2prom; int k; sc = (struct xkodi_softc *) device_get_softc(dev); /*if ((sc = malloc(sizeof(*sc), M_DEVBUF, M_WAITOK | M_ZERO)) == NULL) { device_printf(dev, "cannot allocate softc\n"); return ENXIO; }*/ sc->dev = dev; /* initialize PCI interface */ data = pci_read_config(dev, PCIR_COMMAND, 2); data |= (PCIM_CMD_PORTEN | PCIM_CMD_BUSMASTEREN); pci_write_config(dev, PCIR_COMMAND, data, 2); sc->rid = PCIR_CCS; sc->res = bus_alloc_resource(dev, SYS_RES_IOPORT, &sc->rid, 0, ~0, 1, RF_ACTIVE); if (sc->res == NULL) return ENXIO; sc->bst = rman_get_bustag(sc->res); sc->bsh = rman_get_bushandle(sc->res); e2prom = xrd(sc, ENVY24_CCS13, 1); if ((e2prom & 0x80) == 0) { device_printf(sc->dev, "E2PROM not presented\n"); } else { device_printf(sc->dev, "E2PROM DUMP:\n"); printf(" | 00 01 02 03 04 05 06 07 08 09 0A 0B 0C OD 0E 0F \n"); printf("----+-------------------------------------------------\n"); for (k = 0; k < 256; k++) { e2prom = xkodi_rdi2c(sc, 0xa0, k); if ((k % 16) == 0) { if (k==0) printf(" %02d |", (k/16)); else printf("\n %02d |", (k/16)); } printf(" %02x", e2prom); } } return 0; } static int xkodi_detach(device_t dev) { struct xkodi_softc *sc; sc = (struct xkodi_softc *) device_get_softc(dev); bus_release_resource(dev, SYS_RES_IOPORT, sc->rid, sc->res); return 0; } static device_method_t xkodi_methods[] = { /* Device interface */ DEVMETHOD(device_probe, xkodi_probe), DEVMETHOD(device_attach, xkodi_attach), DEVMETHOD(device_detach, xkodi_detach), {0,0} }; static driver_t xkodi_driver = { "xkodi", xkodi_methods, sizeof(struct xkodi_softc), }; static devclass_t xkodi_devclass; DRIVER_MODULE(xkodi, pci, xkodi_driver, xkodi_devclass, 0, 0);