193023Snsouch/*- 293023Snsouch * Copyright (c) 2001 Alcove - Nicolas Souchu 393023Snsouch * All rights reserved. 493023Snsouch * 593023Snsouch * Redistribution and use in source and binary forms, with or without 693023Snsouch * modification, are permitted provided that the following conditions 793023Snsouch * are met: 893023Snsouch * 1. Redistributions of source code must retain the above copyright 993023Snsouch * notice, this list of conditions and the following disclaimer. 1093023Snsouch * 2. Redistributions in binary form must reproduce the above copyright 1193023Snsouch * notice, this list of conditions and the following disclaimer in the 1293023Snsouch * documentation and/or other materials provided with the distribution. 1393023Snsouch * 1493023Snsouch * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1593023Snsouch * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1693023Snsouch * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1793023Snsouch * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1893023Snsouch * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1993023Snsouch * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2093023Snsouch * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2193023Snsouch * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2293023Snsouch * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2393023Snsouch * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2493023Snsouch * SUCH DAMAGE. 2593023Snsouch */ 26116192Sobrien 27116192Sobrien#include <sys/cdefs.h> 28116192Sobrien__FBSDID("$FreeBSD$"); 29116192Sobrien 30151900Sjhb#include "opt_isa.h" 31151900Sjhb 3293023Snsouch#include <sys/param.h> 33165951Sjhb#include <sys/bus.h> 3493023Snsouch#include <sys/kernel.h> 35165951Sjhb#include <sys/lock.h> 36165951Sjhb#include <sys/module.h> 37165951Sjhb#include <sys/mutex.h> 3893023Snsouch#include <sys/systm.h> 3993023Snsouch 4093023Snsouch#include <machine/bus.h> 4193023Snsouch#include <machine/resource.h> 4293023Snsouch#include <sys/rman.h> 4393023Snsouch 44151900Sjhb#ifdef DEV_ISA 45151900Sjhb#include <isa/isavar.h> 46151900Sjhb#include <isa/isa_common.h> 47151900Sjhb#endif 48119288Simp#include <dev/pci/pcivar.h> 49119288Simp#include <dev/pci/pcireg.h> 5093023Snsouch 5193023Snsouch#include <dev/iicbus/iiconf.h> 5293023Snsouch 5393023Snsouch#include <dev/smbus/smbconf.h> 5493023Snsouch 5593023Snsouch#include "iicbb_if.h" 5693023Snsouch#include "smbus_if.h" 5793023Snsouch 5893023Snsouch#define VIAPM_DEBUG(x) if (viapm_debug) (x) 5993023Snsouch 6093023Snsouch#ifdef DEBUG 6193023Snsouchstatic int viapm_debug = 1; 6293023Snsouch#else 6393023Snsouchstatic int viapm_debug = 0; 6493023Snsouch#endif 6593023Snsouch 6693023Snsouch#define VIA_586B_PMU_ID 0x30401106 6793023Snsouch#define VIA_596A_PMU_ID 0x30501106 6893023Snsouch#define VIA_596B_PMU_ID 0x30511106 6993023Snsouch#define VIA_686A_PMU_ID 0x30571106 7093023Snsouch#define VIA_8233_PMU_ID 0x30741106 71116671Smdodd#define VIA_8233A_PMU_ID 0x31471106 72151901Sjhb#define VIA_8235_PMU_ID 0x31771106 73179933Sgonzo#define VIA_8237_PMU_ID 0x32271106 74171693Skevlo#define VIA_CX700_PMU_ID 0x83241106 7593023Snsouch 7693023Snsouch#define VIAPM_INB(port) \ 77179622Sjhb ((u_char)bus_read_1(viapm->iores, port)) 7893023Snsouch#define VIAPM_OUTB(port,val) \ 79179622Sjhb (bus_write_1(viapm->iores, port, (u_char)(val))) 8093023Snsouch 8193023Snsouch#define VIAPM_TYP_UNKNOWN 0 8293023Snsouch#define VIAPM_TYP_586B_3040E 1 8393023Snsouch#define VIAPM_TYP_586B_3040F 2 8493023Snsouch#define VIAPM_TYP_596B 3 8593023Snsouch#define VIAPM_TYP_686A 4 8693023Snsouch#define VIAPM_TYP_8233 5 8793023Snsouch 88165951Sjhb#define VIAPM_LOCK(sc) mtx_lock(&(sc)->lock) 89165951Sjhb#define VIAPM_UNLOCK(sc) mtx_unlock(&(sc)->lock) 90165951Sjhb#define VIAPM_LOCK_ASSERT(sc) mtx_assert(&(sc)->lock, MA_OWNED) 91165951Sjhb 9293023Snsouchstruct viapm_softc { 9393023Snsouch int type; 9493023Snsouch u_int32_t base; 9593023Snsouch int iorid; 9693023Snsouch int irqrid; 9793023Snsouch struct resource *iores; 9893023Snsouch struct resource *irqres; 9993023Snsouch void *irqih; 10093023Snsouch device_t iicbb; 10193023Snsouch device_t smbus; 102165951Sjhb struct mtx lock; 10393023Snsouch}; 10493023Snsouch 10593023Snsouchstatic devclass_t viapm_devclass; 10693023Snsouchstatic devclass_t viapropm_devclass; 10793023Snsouch 10893023Snsouch/* 10993023Snsouch * VT82C586B definitions 11093023Snsouch */ 11193023Snsouch 11293023Snsouch#define VIAPM_586B_REVID 0x08 11393023Snsouch 11493023Snsouch#define VIAPM_586B_3040E_BASE 0x20 11593023Snsouch#define VIAPM_586B_3040E_ACTIV 0x4 /* 16 bits */ 11693023Snsouch 11793023Snsouch#define VIAPM_586B_3040F_BASE 0x48 11893023Snsouch#define VIAPM_586B_3040F_ACTIV 0x41 /* 8 bits */ 11993023Snsouch 12093023Snsouch#define VIAPM_586B_OEM_REV_E 0x00 12193023Snsouch#define VIAPM_586B_OEM_REV_F 0x01 12293023Snsouch#define VIAPM_586B_PROD_REV_A 0x10 12393023Snsouch 12493023Snsouch#define VIAPM_586B_BA_MASK 0x0000ff00 12593023Snsouch 12693023Snsouch#define GPIO_DIR 0x40 12793023Snsouch#define GPIO_VAL 0x42 12893023Snsouch#define EXTSMI_VAL 0x44 12993023Snsouch 13093023Snsouch#define VIAPM_SCL 0x02 /* GPIO1_VAL */ 13193023Snsouch#define VIAPM_SDA 0x04 /* GPIO2_VAL */ 13293023Snsouch 13393023Snsouch/* 13493023Snsouch * VIAPRO common definitions 13593023Snsouch */ 13693023Snsouch 13793023Snsouch#define VIAPM_PRO_BA_MASK 0x0000fff0 13893023Snsouch#define VIAPM_PRO_SMBCTRL 0xd2 13993023Snsouch#define VIAPM_PRO_REVID 0xd6 14093023Snsouch 14193023Snsouch/* 14293023Snsouch * VT82C686A definitions 14393023Snsouch */ 14493023Snsouch 14593023Snsouch#define VIAPM_PRO_BASE 0x90 14693023Snsouch 14793023Snsouch#define SMBHST 0x0 14893023Snsouch#define SMBHSL 0x1 14993023Snsouch#define SMBHCTRL 0x2 15093023Snsouch#define SMBHCMD 0x3 15193023Snsouch#define SMBHADDR 0x4 15293023Snsouch#define SMBHDATA0 0x5 15393023Snsouch#define SMBHDATA1 0x6 15493023Snsouch#define SMBHBLOCK 0x7 15593023Snsouch 15693023Snsouch#define SMBSST 0x1 15793023Snsouch#define SMBSCTRL 0x8 15893023Snsouch#define SMBSSDWCMD 0x9 15993023Snsouch#define SMBSEVENT 0xa 16093023Snsouch#define SMBSDATA 0xc 16193023Snsouch 16293023Snsouch#define SMBHST_RESERVED 0xef /* reserved bits */ 16393023Snsouch#define SMBHST_FAILED 0x10 /* failed bus transaction */ 16493023Snsouch#define SMBHST_COLLID 0x08 /* bus collision */ 16593023Snsouch#define SMBHST_ERROR 0x04 /* device error */ 16693023Snsouch#define SMBHST_INTR 0x02 /* command completed */ 16793023Snsouch#define SMBHST_BUSY 0x01 /* host busy */ 16893023Snsouch 16993023Snsouch#define SMBHCTRL_START 0x40 /* start command */ 17093023Snsouch#define SMBHCTRL_PROTO 0x1c /* command protocol mask */ 17193023Snsouch#define SMBHCTRL_QUICK 0x00 17293023Snsouch#define SMBHCTRL_SENDRECV 0x04 17393023Snsouch#define SMBHCTRL_BYTE 0x08 17493023Snsouch#define SMBHCTRL_WORD 0x0c 17593023Snsouch#define SMBHCTRL_BLOCK 0x14 17693023Snsouch#define SMBHCTRL_KILL 0x02 /* stop the current transaction */ 17793023Snsouch#define SMBHCTRL_ENABLE 0x01 /* enable interrupts */ 17893023Snsouch 17993023Snsouch#define SMBSCTRL_ENABLE 0x01 /* enable slave */ 18093023Snsouch 18193023Snsouch 18293023Snsouch/* 18393023Snsouch * VIA8233 definitions 18493023Snsouch */ 18593023Snsouch 18693023Snsouch#define VIAPM_8233_BASE 0xD0 18793023Snsouch 18893023Snsouchstatic int 18993023Snsouchviapm_586b_probe(device_t dev) 19093023Snsouch{ 19193023Snsouch struct viapm_softc *viapm = (struct viapm_softc *)device_get_softc(dev); 19293023Snsouch u_int32_t l; 19393023Snsouch u_int16_t s; 19493023Snsouch u_int8_t c; 19593023Snsouch 19693023Snsouch switch (pci_get_devid(dev)) { 19793023Snsouch case VIA_586B_PMU_ID: 19893023Snsouch 19993023Snsouch bzero(viapm, sizeof(struct viapm_softc)); 20093023Snsouch 20193023Snsouch l = pci_read_config(dev, VIAPM_586B_REVID, 1); 20293023Snsouch switch (l) { 20393023Snsouch case VIAPM_586B_OEM_REV_E: 20493023Snsouch viapm->type = VIAPM_TYP_586B_3040E; 20593023Snsouch viapm->iorid = VIAPM_586B_3040E_BASE; 20693023Snsouch 20793023Snsouch /* Activate IO block access */ 20893023Snsouch s = pci_read_config(dev, VIAPM_586B_3040E_ACTIV, 2); 20993023Snsouch pci_write_config(dev, VIAPM_586B_3040E_ACTIV, s | 0x1, 2); 21093023Snsouch break; 21193023Snsouch 21293023Snsouch case VIAPM_586B_OEM_REV_F: 21393023Snsouch case VIAPM_586B_PROD_REV_A: 21493023Snsouch default: 21593023Snsouch viapm->type = VIAPM_TYP_586B_3040F; 21693023Snsouch viapm->iorid = VIAPM_586B_3040F_BASE; 21793023Snsouch 21893023Snsouch /* Activate IO block access */ 21993023Snsouch c = pci_read_config(dev, VIAPM_586B_3040F_ACTIV, 1); 22093023Snsouch pci_write_config(dev, VIAPM_586B_3040F_ACTIV, c | 0x80, 1); 22193023Snsouch break; 22293023Snsouch } 22393023Snsouch 22493023Snsouch viapm->base = pci_read_config(dev, viapm->iorid, 4) & 22593023Snsouch VIAPM_586B_BA_MASK; 22693023Snsouch 22793023Snsouch /* 22893023Snsouch * We have to set the I/O resources by hand because it is 22993023Snsouch * described outside the viapmope of the traditional maps 23093023Snsouch */ 23193023Snsouch if (bus_set_resource(dev, SYS_RES_IOPORT, viapm->iorid, 23293023Snsouch viapm->base, 256)) { 23393023Snsouch device_printf(dev, "could not set bus resource\n"); 23493023Snsouch return ENXIO; 23593023Snsouch } 23693023Snsouch device_set_desc(dev, "VIA VT82C586B Power Management Unit"); 237142398Simp return (BUS_PROBE_DEFAULT); 23893023Snsouch 23993023Snsouch default: 24093023Snsouch break; 24193023Snsouch } 24293023Snsouch 24393023Snsouch return ENXIO; 24493023Snsouch} 24593023Snsouch 24693023Snsouch 24793023Snsouchstatic int 24893023Snsouchviapm_pro_probe(device_t dev) 24993023Snsouch{ 25093023Snsouch struct viapm_softc *viapm = (struct viapm_softc *)device_get_softc(dev); 25193023Snsouch#ifdef VIAPM_BASE_ADDR 25293023Snsouch u_int32_t l; 25393023Snsouch#endif 25493023Snsouch u_int32_t base_cfgreg; 25593023Snsouch char *desc; 25693023Snsouch 25793023Snsouch switch (pci_get_devid(dev)) { 25893023Snsouch case VIA_596A_PMU_ID: 25993023Snsouch desc = "VIA VT82C596A Power Management Unit"; 26093023Snsouch viapm->type = VIAPM_TYP_596B; 26193023Snsouch base_cfgreg = VIAPM_PRO_BASE; 26293023Snsouch goto viapro; 26393023Snsouch 26493023Snsouch case VIA_596B_PMU_ID: 26593023Snsouch desc = "VIA VT82C596B Power Management Unit"; 26693023Snsouch viapm->type = VIAPM_TYP_596B; 26793023Snsouch base_cfgreg = VIAPM_PRO_BASE; 26893023Snsouch goto viapro; 26993023Snsouch 27093023Snsouch case VIA_686A_PMU_ID: 27193023Snsouch desc = "VIA VT82C686A Power Management Unit"; 27293023Snsouch viapm->type = VIAPM_TYP_686A; 27393023Snsouch base_cfgreg = VIAPM_PRO_BASE; 27493023Snsouch goto viapro; 27593023Snsouch 27693023Snsouch case VIA_8233_PMU_ID: 277116671Smdodd case VIA_8233A_PMU_ID: 27893023Snsouch desc = "VIA VT8233 Power Management Unit"; 27993023Snsouch viapm->type = VIAPM_TYP_UNKNOWN; 28093023Snsouch base_cfgreg = VIAPM_8233_BASE; 28193023Snsouch goto viapro; 28293023Snsouch 283151901Sjhb case VIA_8235_PMU_ID: 284151901Sjhb desc = "VIA VT8235 Power Management Unit"; 285151901Sjhb viapm->type = VIAPM_TYP_UNKNOWN; 286151901Sjhb base_cfgreg = VIAPM_8233_BASE; 287151901Sjhb goto viapro; 288151901Sjhb 289179933Sgonzo case VIA_8237_PMU_ID: 290179933Sgonzo desc = "VIA VT8237 Power Management Unit"; 291179933Sgonzo viapm->type = VIAPM_TYP_UNKNOWN; 292179933Sgonzo base_cfgreg = VIAPM_8233_BASE; 293179933Sgonzo goto viapro; 294179933Sgonzo 295171693Skevlo case VIA_CX700_PMU_ID: 296171693Skevlo desc = "VIA CX700 Power Management Unit"; 297171693Skevlo viapm->type = VIAPM_TYP_UNKNOWN; 298171693Skevlo base_cfgreg = VIAPM_8233_BASE; 299171693Skevlo goto viapro; 300171693Skevlo 30193023Snsouch viapro: 30293023Snsouch 30393023Snsouch#ifdef VIAPM_BASE_ADDR 30493023Snsouch /* force VIAPM I/O base address */ 30593023Snsouch 30693023Snsouch /* enable the SMBus controller function */ 30793023Snsouch l = pci_read_config(dev, VIAPM_PRO_SMBCTRL, 1); 30893023Snsouch pci_write_config(dev, VIAPM_PRO_SMBCTRL, l | 1, 1); 30993023Snsouch 31093023Snsouch /* write the base address */ 31193023Snsouch pci_write_config(dev, base_cfgreg, 31293023Snsouch VIAPM_BASE_ADDR & VIAPM_PRO_BA_MASK, 4); 31393023Snsouch#endif 31493023Snsouch 31593023Snsouch viapm->base = pci_read_config(dev, base_cfgreg, 4) & VIAPM_PRO_BA_MASK; 31693023Snsouch 31793023Snsouch /* 31893023Snsouch * We have to set the I/O resources by hand because it is 31993023Snsouch * described outside the viapmope of the traditional maps 32093023Snsouch */ 32193023Snsouch viapm->iorid = base_cfgreg; 32293023Snsouch if (bus_set_resource(dev, SYS_RES_IOPORT, viapm->iorid, 32393023Snsouch viapm->base, 16)) { 32493023Snsouch device_printf(dev, "could not set bus resource 0x%x\n", 32593023Snsouch viapm->base); 32693023Snsouch return ENXIO; 32793023Snsouch } 32893023Snsouch 329171693Skevlo if (bootverbose) { 33093023Snsouch device_printf(dev, "SMBus I/O base at 0x%x\n", viapm->base); 33193023Snsouch } 33293023Snsouch 33393023Snsouch device_set_desc(dev, desc); 334142398Simp return (BUS_PROBE_DEFAULT); 33593023Snsouch 33693023Snsouch default: 33793023Snsouch break; 33893023Snsouch } 33993023Snsouch 34093023Snsouch return ENXIO; 34193023Snsouch} 34293023Snsouch 34393023Snsouchstatic int 34493023Snsouchviapm_pro_attach(device_t dev) 34593023Snsouch{ 34693023Snsouch struct viapm_softc *viapm = (struct viapm_softc *)device_get_softc(dev); 34793023Snsouch u_int32_t l; 34893023Snsouch 349165951Sjhb mtx_init(&viapm->lock, device_get_nameunit(dev), "viapm", MTX_DEF); 350127135Snjl if (!(viapm->iores = bus_alloc_resource_any(dev, SYS_RES_IOPORT, 351127135Snjl &viapm->iorid, RF_ACTIVE))) { 35293023Snsouch device_printf(dev, "could not allocate bus space\n"); 35393023Snsouch goto error; 35493023Snsouch } 35593023Snsouch 356153084Sru#ifdef notyet 35793023Snsouch /* force irq 9 */ 35893023Snsouch l = pci_read_config(dev, VIAPM_PRO_SMBCTRL, 1); 35993023Snsouch pci_write_config(dev, VIAPM_PRO_SMBCTRL, l | 0x80, 1); 36093023Snsouch 36193023Snsouch viapm->irqrid = 0; 36293023Snsouch if (!(viapm->irqres = bus_alloc_resource(dev, SYS_RES_IRQ, 36393023Snsouch &viapm->irqrid, 9, 9, 1, 36493023Snsouch RF_SHAREABLE | RF_ACTIVE))) { 36593023Snsouch device_printf(dev, "could not allocate irq\n"); 36693023Snsouch goto error; 36793023Snsouch } 36893023Snsouch 369179622Sjhb if (bus_setup_intr(dev, viapm->irqres, INTR_TYPE_MISC | INTR_MPSAFE, 37093023Snsouch (driver_intr_t *) viasmb_intr, viapm, &viapm->irqih)) { 37193023Snsouch device_printf(dev, "could not setup irq\n"); 37293023Snsouch goto error; 37393023Snsouch } 37493023Snsouch#endif 37593023Snsouch 376171693Skevlo if (bootverbose) { 37793023Snsouch l = pci_read_config(dev, VIAPM_PRO_REVID, 1); 37893023Snsouch device_printf(dev, "SMBus revision code 0x%x\n", l); 37993023Snsouch } 38093023Snsouch 38193023Snsouch viapm->smbus = device_add_child(dev, "smbus", -1); 38293023Snsouch 38393023Snsouch /* probe and attach the smbus */ 38493023Snsouch bus_generic_attach(dev); 38593023Snsouch 38693023Snsouch /* disable slave function */ 38793023Snsouch VIAPM_OUTB(SMBSCTRL, VIAPM_INB(SMBSCTRL) & ~SMBSCTRL_ENABLE); 38893023Snsouch 38993023Snsouch /* enable the SMBus controller function */ 39093023Snsouch l = pci_read_config(dev, VIAPM_PRO_SMBCTRL, 1); 39193023Snsouch pci_write_config(dev, VIAPM_PRO_SMBCTRL, l | 1, 1); 39293023Snsouch 393153084Sru#ifdef notyet 39493023Snsouch /* enable interrupts */ 39593023Snsouch VIAPM_OUTB(SMBHCTRL, VIAPM_INB(SMBHCTRL) | SMBHCTRL_ENABLE); 39693023Snsouch#endif 39793023Snsouch 398151900Sjhb#ifdef DEV_ISA 399151900Sjhb /* If this device is a PCI-ISA bridge, then attach an ISA bus. */ 400151900Sjhb if ((pci_get_class(dev) == PCIC_BRIDGE) && 401151900Sjhb (pci_get_subclass(dev) == PCIS_BRIDGE_ISA)) 402151900Sjhb isab_attach(dev); 403151900Sjhb#endif 40493023Snsouch return 0; 40593023Snsouch 40693023Snsoucherror: 40793023Snsouch if (viapm->iores) 40893023Snsouch bus_release_resource(dev, SYS_RES_IOPORT, viapm->iorid, viapm->iores); 409153084Sru#ifdef notyet 41093023Snsouch if (viapm->irqres) 41193023Snsouch bus_release_resource(dev, SYS_RES_IRQ, viapm->irqrid, viapm->irqres); 41293023Snsouch#endif 413165951Sjhb mtx_destroy(&viapm->lock); 41493023Snsouch 41593023Snsouch return ENXIO; 41693023Snsouch} 41793023Snsouch 41893023Snsouchstatic int 41993023Snsouchviapm_586b_attach(device_t dev) 42093023Snsouch{ 42193023Snsouch struct viapm_softc *viapm = (struct viapm_softc *)device_get_softc(dev); 422165951Sjhb 423165951Sjhb mtx_init(&viapm->lock, device_get_nameunit(dev), "viapm", MTX_DEF); 424127135Snjl if (!(viapm->iores = bus_alloc_resource_any(dev, SYS_RES_IOPORT, 425127135Snjl &viapm->iorid, RF_ACTIVE | RF_SHAREABLE))) { 42693023Snsouch device_printf(dev, "could not allocate bus resource\n"); 427165951Sjhb goto error; 42893023Snsouch } 42993023Snsouch 43093023Snsouch VIAPM_OUTB(GPIO_DIR, VIAPM_INB(GPIO_DIR) | VIAPM_SCL | VIAPM_SDA); 43193023Snsouch 43293023Snsouch /* add generic bit-banging code */ 43393023Snsouch if (!(viapm->iicbb = device_add_child(dev, "iicbb", -1))) 43493023Snsouch goto error; 43593023Snsouch 43693023Snsouch bus_generic_attach(dev); 43793023Snsouch 43893023Snsouch return 0; 43993023Snsouch 44093023Snsoucherror: 44193023Snsouch if (viapm->iores) 44293023Snsouch bus_release_resource(dev, SYS_RES_IOPORT, 44393023Snsouch viapm->iorid, viapm->iores); 444165951Sjhb mtx_destroy(&viapm->lock); 44593023Snsouch return ENXIO; 44693023Snsouch} 44793023Snsouch 44893023Snsouchstatic int 44993023Snsouchviapm_586b_detach(device_t dev) 45093023Snsouch{ 45193023Snsouch struct viapm_softc *viapm = (struct viapm_softc *)device_get_softc(dev); 45293023Snsouch 45393023Snsouch bus_generic_detach(dev); 45493023Snsouch if (viapm->iicbb) { 45593023Snsouch device_delete_child(dev, viapm->iicbb); 45693023Snsouch } 45793023Snsouch 458165951Sjhb if (viapm->iores) 459165951Sjhb bus_release_resource(dev, SYS_RES_IOPORT, viapm->iorid, 460165951Sjhb viapm->iores); 461165951Sjhb mtx_destroy(&viapm->lock); 46293023Snsouch 46393023Snsouch return 0; 46493023Snsouch} 46593023Snsouch 46693023Snsouchstatic int 46793023Snsouchviapm_pro_detach(device_t dev) 46893023Snsouch{ 46993023Snsouch struct viapm_softc *viapm = (struct viapm_softc *)device_get_softc(dev); 47093023Snsouch 47193023Snsouch bus_generic_detach(dev); 47293023Snsouch if (viapm->smbus) { 47393023Snsouch device_delete_child(dev, viapm->smbus); 47493023Snsouch } 47593023Snsouch 476165951Sjhb bus_release_resource(dev, SYS_RES_IOPORT, viapm->iorid, viapm->iores); 47793023Snsouch 478153084Sru#ifdef notyet 479165951Sjhb bus_release_resource(dev, SYS_RES_IRQ, viapm->irqrid, viapm->irqres); 48093023Snsouch#endif 481165951Sjhb mtx_destroy(&viapm->lock); 48293023Snsouch 48393023Snsouch return 0; 48493023Snsouch} 48593023Snsouch 48693023Snsouchstatic int 487189317Simpviabb_callback(device_t dev, int index, caddr_t data) 48893023Snsouch{ 48993023Snsouch return 0; 49093023Snsouch} 49193023Snsouch 49293023Snsouchstatic void 49393023Snsouchviabb_setscl(device_t dev, int ctrl) 49493023Snsouch{ 49593023Snsouch struct viapm_softc *viapm = device_get_softc(dev); 49693023Snsouch u_char val; 49793023Snsouch 498165951Sjhb VIAPM_LOCK(viapm); 49993023Snsouch val = VIAPM_INB(GPIO_VAL); 50093023Snsouch 50193023Snsouch if (ctrl) 50293023Snsouch val |= VIAPM_SCL; 50393023Snsouch else 50493023Snsouch val &= ~VIAPM_SCL; 50593023Snsouch 50693023Snsouch VIAPM_OUTB(GPIO_VAL, val); 507165951Sjhb VIAPM_UNLOCK(viapm); 50893023Snsouch 50993023Snsouch return; 51093023Snsouch} 51193023Snsouch 51293023Snsouchstatic void 51393023Snsouchviabb_setsda(device_t dev, int data) 51493023Snsouch{ 51593023Snsouch struct viapm_softc *viapm = device_get_softc(dev); 51693023Snsouch u_char val; 51793023Snsouch 518165951Sjhb VIAPM_LOCK(viapm); 51993023Snsouch val = VIAPM_INB(GPIO_VAL); 52093023Snsouch 52193023Snsouch if (data) 52293023Snsouch val |= VIAPM_SDA; 52393023Snsouch else 52493023Snsouch val &= ~VIAPM_SDA; 52593023Snsouch 52693023Snsouch VIAPM_OUTB(GPIO_VAL, val); 527165951Sjhb VIAPM_UNLOCK(viapm); 52893023Snsouch 52993023Snsouch return; 53093023Snsouch} 53193023Snsouch 53293023Snsouchstatic int 53393023Snsouchviabb_reset(device_t dev, u_char speed, u_char addr, u_char *oldaddr) 53493023Snsouch{ 53593023Snsouch /* reset bus */ 53693023Snsouch viabb_setsda(dev, 1); 53793023Snsouch viabb_setscl(dev, 1); 53893023Snsouch 53993023Snsouch return (IIC_ENOADDR); 54093023Snsouch} 54193023Snsouch 54293023Snsouchstatic int 54393023Snsouchviabb_getscl(device_t dev) 54493023Snsouch{ 54593023Snsouch struct viapm_softc *viapm = device_get_softc(dev); 546165951Sjhb u_char val; 54793023Snsouch 548165951Sjhb VIAPM_LOCK(viapm); 549165951Sjhb val = VIAPM_INB(EXTSMI_VAL); 550165951Sjhb VIAPM_UNLOCK(viapm); 551165951Sjhb return ((val & VIAPM_SCL) != 0); 55293023Snsouch} 55393023Snsouch 55493023Snsouchstatic int 55593023Snsouchviabb_getsda(device_t dev) 55693023Snsouch{ 55793023Snsouch struct viapm_softc *viapm = device_get_softc(dev); 558165951Sjhb u_char val; 55993023Snsouch 560165951Sjhb VIAPM_LOCK(viapm); 561165951Sjhb val = VIAPM_INB(EXTSMI_VAL); 562165951Sjhb VIAPM_UNLOCK(viapm); 563165951Sjhb return ((val & VIAPM_SDA) != 0); 56493023Snsouch} 56593023Snsouch 56693023Snsouchstatic int 56793023Snsouchviapm_abort(struct viapm_softc *viapm) 56893023Snsouch{ 56993023Snsouch VIAPM_OUTB(SMBHCTRL, SMBHCTRL_KILL); 57093023Snsouch DELAY(10); 57193023Snsouch 57293023Snsouch return (0); 57393023Snsouch} 57493023Snsouch 57593023Snsouchstatic int 57693023Snsouchviapm_clear(struct viapm_softc *viapm) 57793023Snsouch{ 57893023Snsouch VIAPM_OUTB(SMBHST, SMBHST_FAILED | SMBHST_COLLID | 57993023Snsouch SMBHST_ERROR | SMBHST_INTR); 58093023Snsouch DELAY(10); 58193023Snsouch 58293023Snsouch return (0); 58393023Snsouch} 58493023Snsouch 58593023Snsouchstatic int 58693023Snsouchviapm_busy(struct viapm_softc *viapm) 58793023Snsouch{ 58893023Snsouch u_char sts; 58993023Snsouch 59093023Snsouch sts = VIAPM_INB(SMBHST); 59193023Snsouch 59293023Snsouch VIAPM_DEBUG(printf("viapm: idle? STS=0x%x\n", sts)); 59393023Snsouch 59493023Snsouch return (sts & SMBHST_BUSY); 59593023Snsouch} 59693023Snsouch 59793023Snsouch/* 59893023Snsouch * Poll the SMBus controller 59993023Snsouch */ 60093023Snsouchstatic int 60193023Snsouchviapm_wait(struct viapm_softc *viapm) 60293023Snsouch{ 60393023Snsouch int count = 10000; 60493023Snsouch u_char sts = 0; 60593023Snsouch int error; 60693023Snsouch 607165951Sjhb VIAPM_LOCK_ASSERT(viapm); 608165951Sjhb 60993023Snsouch /* wait for command to complete and SMBus controller is idle */ 61093023Snsouch while(count--) { 61193023Snsouch DELAY(10); 61293023Snsouch sts = VIAPM_INB(SMBHST); 61393023Snsouch 61493023Snsouch /* check if the controller is processing a command */ 61593023Snsouch if (!(sts & SMBHST_BUSY) && (sts & SMBHST_INTR)) 61693023Snsouch break; 61793023Snsouch } 61893023Snsouch 61993023Snsouch VIAPM_DEBUG(printf("viapm: SMBHST=0x%x\n", sts)); 62093023Snsouch 62193023Snsouch error = SMB_ENOERR; 62293023Snsouch 62393023Snsouch if (!count) 62493023Snsouch error |= SMB_ETIMEOUT; 62593023Snsouch 62693023Snsouch if (sts & SMBHST_FAILED) 62793023Snsouch error |= SMB_EABORT; 62893023Snsouch 62993023Snsouch if (sts & SMBHST_COLLID) 63093023Snsouch error |= SMB_ENOACK; 63193023Snsouch 63293023Snsouch if (sts & SMBHST_ERROR) 63393023Snsouch error |= SMB_EBUSERR; 63493023Snsouch 63593023Snsouch if (error != SMB_ENOERR) 63693023Snsouch viapm_abort(viapm); 63793023Snsouch 63893023Snsouch viapm_clear(viapm); 63993023Snsouch 64093023Snsouch return (error); 64193023Snsouch} 64293023Snsouch 64393023Snsouchstatic int 644189317Simpviasmb_callback(device_t dev, int index, void *data) 64593023Snsouch{ 64693023Snsouch int error = 0; 64793023Snsouch 64893023Snsouch switch (index) { 64993023Snsouch case SMB_REQUEST_BUS: 65093023Snsouch case SMB_RELEASE_BUS: 65193023Snsouch /* ok, bus allocation accepted */ 65293023Snsouch break; 65393023Snsouch default: 65493023Snsouch error = EINVAL; 65593023Snsouch } 65693023Snsouch 65793023Snsouch return (error); 65893023Snsouch} 65993023Snsouch 66093023Snsouchstatic int 66193023Snsouchviasmb_quick(device_t dev, u_char slave, int how) 66293023Snsouch{ 66393023Snsouch struct viapm_softc *viapm = (struct viapm_softc *)device_get_softc(dev); 66493023Snsouch int error; 66593023Snsouch 666165951Sjhb VIAPM_LOCK(viapm); 66793023Snsouch viapm_clear(viapm); 668165951Sjhb if (viapm_busy(viapm)) { 669165951Sjhb VIAPM_UNLOCK(viapm); 670162234Sjhb return (SMB_EBUSY); 671165951Sjhb } 67293023Snsouch 67393023Snsouch switch (how) { 67493023Snsouch case SMB_QWRITE: 67593023Snsouch VIAPM_DEBUG(printf("viapm: QWRITE to 0x%x", slave)); 67693023Snsouch VIAPM_OUTB(SMBHADDR, slave & ~LSB); 67793023Snsouch break; 67893023Snsouch case SMB_QREAD: 67993023Snsouch VIAPM_DEBUG(printf("viapm: QREAD to 0x%x", slave)); 68093023Snsouch VIAPM_OUTB(SMBHADDR, slave | LSB); 68193023Snsouch break; 68293023Snsouch default: 683135577Sstefanf panic("%s: unknown QUICK command (%x)!", __func__, how); 68493023Snsouch } 68593023Snsouch 68693023Snsouch VIAPM_OUTB(SMBHCTRL, SMBHCTRL_START | SMBHCTRL_QUICK); 68793023Snsouch 68893023Snsouch error = viapm_wait(viapm); 689165951Sjhb VIAPM_UNLOCK(viapm); 69093023Snsouch 69193023Snsouch return (error); 69293023Snsouch} 69393023Snsouch 69493023Snsouchstatic int 69593023Snsouchviasmb_sendb(device_t dev, u_char slave, char byte) 69693023Snsouch{ 69793023Snsouch struct viapm_softc *viapm = (struct viapm_softc *)device_get_softc(dev); 69893023Snsouch int error; 69993023Snsouch 700165951Sjhb VIAPM_LOCK(viapm); 70193023Snsouch viapm_clear(viapm); 702165951Sjhb if (viapm_busy(viapm)) { 703165951Sjhb VIAPM_UNLOCK(viapm); 704162234Sjhb return (SMB_EBUSY); 705165951Sjhb } 70693023Snsouch 70793023Snsouch VIAPM_OUTB(SMBHADDR, slave & ~ LSB); 70893023Snsouch VIAPM_OUTB(SMBHCMD, byte); 70993023Snsouch 71093023Snsouch VIAPM_OUTB(SMBHCTRL, SMBHCTRL_START | SMBHCTRL_SENDRECV); 71193023Snsouch 71293023Snsouch error = viapm_wait(viapm); 71393023Snsouch 71493023Snsouch VIAPM_DEBUG(printf("viapm: SENDB to 0x%x, byte=0x%x, error=0x%x\n", slave, byte, error)); 715165951Sjhb VIAPM_UNLOCK(viapm); 71693023Snsouch 71793023Snsouch return (error); 71893023Snsouch} 71993023Snsouch 72093023Snsouchstatic int 72193023Snsouchviasmb_recvb(device_t dev, u_char slave, char *byte) 72293023Snsouch{ 72393023Snsouch struct viapm_softc *viapm = (struct viapm_softc *)device_get_softc(dev); 72493023Snsouch int error; 72593023Snsouch 726165951Sjhb VIAPM_LOCK(viapm); 72793023Snsouch viapm_clear(viapm); 728165951Sjhb if (viapm_busy(viapm)) { 729165951Sjhb VIAPM_UNLOCK(viapm); 730162234Sjhb return (SMB_EBUSY); 731165951Sjhb } 73293023Snsouch 73393023Snsouch VIAPM_OUTB(SMBHADDR, slave | LSB); 73493023Snsouch 73593023Snsouch VIAPM_OUTB(SMBHCTRL, SMBHCTRL_START | SMBHCTRL_SENDRECV); 73693023Snsouch 73793023Snsouch if ((error = viapm_wait(viapm)) == SMB_ENOERR) 73893023Snsouch *byte = VIAPM_INB(SMBHDATA0); 73993023Snsouch 74093023Snsouch VIAPM_DEBUG(printf("viapm: RECVB from 0x%x, byte=0x%x, error=0x%x\n", slave, *byte, error)); 741165951Sjhb VIAPM_UNLOCK(viapm); 74293023Snsouch 74393023Snsouch return (error); 74493023Snsouch} 74593023Snsouch 74693023Snsouchstatic int 74793023Snsouchviasmb_writeb(device_t dev, u_char slave, char cmd, char byte) 74893023Snsouch{ 74993023Snsouch struct viapm_softc *viapm = (struct viapm_softc *)device_get_softc(dev); 75093023Snsouch int error; 75193023Snsouch 752165951Sjhb VIAPM_LOCK(viapm); 75393023Snsouch viapm_clear(viapm); 754165951Sjhb if (viapm_busy(viapm)) { 755165951Sjhb VIAPM_UNLOCK(viapm); 756162234Sjhb return (SMB_EBUSY); 757165951Sjhb } 75893023Snsouch 75993023Snsouch VIAPM_OUTB(SMBHADDR, slave & ~ LSB); 76093023Snsouch VIAPM_OUTB(SMBHCMD, cmd); 76193023Snsouch VIAPM_OUTB(SMBHDATA0, byte); 76293023Snsouch 76393023Snsouch VIAPM_OUTB(SMBHCTRL, SMBHCTRL_START | SMBHCTRL_BYTE); 76493023Snsouch 76593023Snsouch error = viapm_wait(viapm); 76693023Snsouch 76793023Snsouch VIAPM_DEBUG(printf("viapm: WRITEB to 0x%x, cmd=0x%x, byte=0x%x, error=0x%x\n", slave, cmd, byte, error)); 768165951Sjhb VIAPM_UNLOCK(viapm); 76993023Snsouch 77093023Snsouch return (error); 77193023Snsouch} 77293023Snsouch 77393023Snsouchstatic int 77493023Snsouchviasmb_readb(device_t dev, u_char slave, char cmd, char *byte) 77593023Snsouch{ 77693023Snsouch struct viapm_softc *viapm = (struct viapm_softc *)device_get_softc(dev); 77793023Snsouch int error; 77893023Snsouch 779165951Sjhb VIAPM_LOCK(viapm); 78093023Snsouch viapm_clear(viapm); 781165951Sjhb if (viapm_busy(viapm)) { 782165951Sjhb VIAPM_UNLOCK(viapm); 783162234Sjhb return (SMB_EBUSY); 784165951Sjhb } 78593023Snsouch 78693023Snsouch VIAPM_OUTB(SMBHADDR, slave | LSB); 78793023Snsouch VIAPM_OUTB(SMBHCMD, cmd); 78893023Snsouch 78993023Snsouch VIAPM_OUTB(SMBHCTRL, SMBHCTRL_START | SMBHCTRL_BYTE); 79093023Snsouch 79193023Snsouch if ((error = viapm_wait(viapm)) == SMB_ENOERR) 79293023Snsouch *byte = VIAPM_INB(SMBHDATA0); 79393023Snsouch 79493023Snsouch VIAPM_DEBUG(printf("viapm: READB from 0x%x, cmd=0x%x, byte=0x%x, error=0x%x\n", slave, cmd, *byte, error)); 795165951Sjhb VIAPM_UNLOCK(viapm); 79693023Snsouch 79793023Snsouch return (error); 79893023Snsouch} 79993023Snsouch 80093023Snsouchstatic int 80193023Snsouchviasmb_writew(device_t dev, u_char slave, char cmd, short word) 80293023Snsouch{ 80393023Snsouch struct viapm_softc *viapm = (struct viapm_softc *)device_get_softc(dev); 80493023Snsouch int error; 80593023Snsouch 806165951Sjhb VIAPM_LOCK(viapm); 80793023Snsouch viapm_clear(viapm); 808165951Sjhb if (viapm_busy(viapm)) { 809165951Sjhb VIAPM_UNLOCK(viapm); 810162234Sjhb return (SMB_EBUSY); 811165951Sjhb } 81293023Snsouch 81393023Snsouch VIAPM_OUTB(SMBHADDR, slave & ~ LSB); 81493023Snsouch VIAPM_OUTB(SMBHCMD, cmd); 81593023Snsouch VIAPM_OUTB(SMBHDATA0, word & 0x00ff); 81693023Snsouch VIAPM_OUTB(SMBHDATA1, (word & 0xff00) >> 8); 81793023Snsouch 81893023Snsouch VIAPM_OUTB(SMBHCTRL, SMBHCTRL_START | SMBHCTRL_WORD); 81993023Snsouch 82093023Snsouch error = viapm_wait(viapm); 82193023Snsouch 82293023Snsouch VIAPM_DEBUG(printf("viapm: WRITEW to 0x%x, cmd=0x%x, word=0x%x, error=0x%x\n", slave, cmd, word, error)); 823165951Sjhb VIAPM_UNLOCK(viapm); 82493023Snsouch 82593023Snsouch return (error); 82693023Snsouch} 82793023Snsouch 82893023Snsouchstatic int 82993023Snsouchviasmb_readw(device_t dev, u_char slave, char cmd, short *word) 83093023Snsouch{ 83193023Snsouch struct viapm_softc *viapm = (struct viapm_softc *)device_get_softc(dev); 83293023Snsouch int error; 83393023Snsouch u_char high, low; 83493023Snsouch 835165951Sjhb VIAPM_LOCK(viapm); 83693023Snsouch viapm_clear(viapm); 837165951Sjhb if (viapm_busy(viapm)) { 838165951Sjhb VIAPM_UNLOCK(viapm); 839162234Sjhb return (SMB_EBUSY); 840165951Sjhb } 84193023Snsouch 84293023Snsouch VIAPM_OUTB(SMBHADDR, slave | LSB); 84393023Snsouch VIAPM_OUTB(SMBHCMD, cmd); 84493023Snsouch 84593023Snsouch VIAPM_OUTB(SMBHCTRL, SMBHCTRL_START | SMBHCTRL_WORD); 84693023Snsouch 84793023Snsouch if ((error = viapm_wait(viapm)) == SMB_ENOERR) { 84893023Snsouch low = VIAPM_INB(SMBHDATA0); 84993023Snsouch high = VIAPM_INB(SMBHDATA1); 85093023Snsouch 85193023Snsouch *word = ((high & 0xff) << 8) | (low & 0xff); 85293023Snsouch } 85393023Snsouch 85493023Snsouch VIAPM_DEBUG(printf("viapm: READW from 0x%x, cmd=0x%x, word=0x%x, error=0x%x\n", slave, cmd, *word, error)); 855165951Sjhb VIAPM_UNLOCK(viapm); 85693023Snsouch 85793023Snsouch return (error); 85893023Snsouch} 85993023Snsouch 86093023Snsouchstatic int 86193023Snsouchviasmb_bwrite(device_t dev, u_char slave, char cmd, u_char count, char *buf) 86293023Snsouch{ 86393023Snsouch struct viapm_softc *viapm = (struct viapm_softc *)device_get_softc(dev); 864162234Sjhb u_char i; 865162234Sjhb int error; 86693023Snsouch 867162234Sjhb if (count < 1 || count > 32) 868162234Sjhb return (SMB_EINVAL); 869162234Sjhb 870165951Sjhb VIAPM_LOCK(viapm); 87193023Snsouch viapm_clear(viapm); 872165951Sjhb if (viapm_busy(viapm)) { 873165951Sjhb VIAPM_UNLOCK(viapm); 874162234Sjhb return (SMB_EBUSY); 875165951Sjhb } 87693023Snsouch 877162234Sjhb VIAPM_OUTB(SMBHADDR, slave & ~LSB); 878162234Sjhb VIAPM_OUTB(SMBHCMD, cmd); 879162234Sjhb VIAPM_OUTB(SMBHDATA0, count); 880162234Sjhb i = VIAPM_INB(SMBHCTRL); 88193023Snsouch 882162234Sjhb /* fill the 32-byte internal buffer */ 883162234Sjhb for (i = 0; i < count; i++) { 884162234Sjhb VIAPM_OUTB(SMBHBLOCK, buf[i]); 885162234Sjhb DELAY(2); 886162234Sjhb } 887162234Sjhb VIAPM_OUTB(SMBHCMD, cmd); 888162234Sjhb VIAPM_OUTB(SMBHCTRL, SMBHCTRL_START | SMBHCTRL_BLOCK); 88993023Snsouch 890162234Sjhb error = viapm_wait(viapm); 89193023Snsouch 89293023Snsouch VIAPM_DEBUG(printf("viapm: WRITEBLK to 0x%x, count=0x%x, cmd=0x%x, error=0x%x", slave, count, cmd, error)); 893165951Sjhb VIAPM_UNLOCK(viapm); 89493023Snsouch 89593023Snsouch return (error); 89693023Snsouch 89793023Snsouch} 89893023Snsouch 89993023Snsouchstatic int 900162234Sjhbviasmb_bread(device_t dev, u_char slave, char cmd, u_char *count, char *buf) 90193023Snsouch{ 90293023Snsouch struct viapm_softc *viapm = (struct viapm_softc *)device_get_softc(dev); 903162234Sjhb u_char data, len, i; 904162234Sjhb int error; 90593023Snsouch 906162234Sjhb if (*count < 1 || *count > 32) 907162234Sjhb return (SMB_EINVAL); 908162234Sjhb 909165951Sjhb VIAPM_LOCK(viapm); 91093023Snsouch viapm_clear(viapm); 911165951Sjhb if (viapm_busy(viapm)) { 912165951Sjhb VIAPM_UNLOCK(viapm); 913162234Sjhb return (SMB_EBUSY); 914165951Sjhb } 91593023Snsouch 916162234Sjhb VIAPM_OUTB(SMBHADDR, slave | LSB); 917162234Sjhb VIAPM_OUTB(SMBHCMD, cmd); 918162234Sjhb VIAPM_OUTB(SMBHCTRL, SMBHCTRL_START | SMBHCTRL_BLOCK); 91993023Snsouch 920162234Sjhb if ((error = viapm_wait(viapm)) != SMB_ENOERR) 921162234Sjhb goto error; 92293023Snsouch 923162234Sjhb len = VIAPM_INB(SMBHDATA0); 924162234Sjhb i = VIAPM_INB(SMBHCTRL); /* reset counter */ 92593023Snsouch 926162234Sjhb /* read the 32-byte internal buffer */ 927162234Sjhb for (i = 0; i < len; i++) { 928162234Sjhb data = VIAPM_INB(SMBHBLOCK); 929162234Sjhb if (i < *count) 930162234Sjhb buf[i] = data; 931162234Sjhb DELAY(2); 932162234Sjhb } 933162234Sjhb *count = len; 93493023Snsouch 93593023Snsoucherror: 936162234Sjhb VIAPM_DEBUG(printf("viapm: READBLK to 0x%x, count=0x%x, cmd=0x%x, error=0x%x", slave, *count, cmd, error)); 937165951Sjhb VIAPM_UNLOCK(viapm); 93893023Snsouch 93993023Snsouch return (error); 94093023Snsouch} 94193023Snsouch 94293023Snsouchstatic device_method_t viapm_methods[] = { 94393023Snsouch /* device interface */ 94493023Snsouch DEVMETHOD(device_probe, viapm_586b_probe), 94593023Snsouch DEVMETHOD(device_attach, viapm_586b_attach), 94693023Snsouch DEVMETHOD(device_detach, viapm_586b_detach), 94793023Snsouch 94893023Snsouch /* iicbb interface */ 94993023Snsouch DEVMETHOD(iicbb_callback, viabb_callback), 95093023Snsouch DEVMETHOD(iicbb_setscl, viabb_setscl), 95193023Snsouch DEVMETHOD(iicbb_setsda, viabb_setsda), 95293023Snsouch DEVMETHOD(iicbb_getscl, viabb_getscl), 95393023Snsouch DEVMETHOD(iicbb_getsda, viabb_getsda), 95493023Snsouch DEVMETHOD(iicbb_reset, viabb_reset), 95593023Snsouch 956151900Sjhb /* Bus interface */ 957151900Sjhb DEVMETHOD(bus_alloc_resource, bus_generic_alloc_resource), 958151900Sjhb DEVMETHOD(bus_release_resource, bus_generic_release_resource), 959151900Sjhb DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), 960151900Sjhb DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), 961151900Sjhb DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), 962151900Sjhb DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), 963151900Sjhb 964227843Smarius DEVMETHOD_END 96593023Snsouch}; 96693023Snsouch 96793023Snsouchstatic driver_t viapm_driver = { 96893023Snsouch "viapm", 96993023Snsouch viapm_methods, 97093023Snsouch sizeof(struct viapm_softc), 97193023Snsouch}; 97293023Snsouch 97393023Snsouchstatic device_method_t viapropm_methods[] = { 97493023Snsouch /* device interface */ 97593023Snsouch DEVMETHOD(device_probe, viapm_pro_probe), 97693023Snsouch DEVMETHOD(device_attach, viapm_pro_attach), 97793023Snsouch DEVMETHOD(device_detach, viapm_pro_detach), 97893023Snsouch 97993023Snsouch /* smbus interface */ 98093023Snsouch DEVMETHOD(smbus_callback, viasmb_callback), 98193023Snsouch DEVMETHOD(smbus_quick, viasmb_quick), 98293023Snsouch DEVMETHOD(smbus_sendb, viasmb_sendb), 98393023Snsouch DEVMETHOD(smbus_recvb, viasmb_recvb), 98493023Snsouch DEVMETHOD(smbus_writeb, viasmb_writeb), 98593023Snsouch DEVMETHOD(smbus_readb, viasmb_readb), 98693023Snsouch DEVMETHOD(smbus_writew, viasmb_writew), 98793023Snsouch DEVMETHOD(smbus_readw, viasmb_readw), 98893023Snsouch DEVMETHOD(smbus_bwrite, viasmb_bwrite), 98993023Snsouch DEVMETHOD(smbus_bread, viasmb_bread), 99093023Snsouch 991151900Sjhb /* Bus interface */ 992151900Sjhb DEVMETHOD(bus_alloc_resource, bus_generic_alloc_resource), 993151900Sjhb DEVMETHOD(bus_release_resource, bus_generic_release_resource), 994151900Sjhb DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), 995151900Sjhb DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), 996151900Sjhb DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), 997151900Sjhb DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), 998151900Sjhb 999227843Smarius DEVMETHOD_END 100093023Snsouch}; 100193023Snsouch 100293023Snsouchstatic driver_t viapropm_driver = { 100393023Snsouch "viapropm", 100493023Snsouch viapropm_methods, 100593023Snsouch sizeof(struct viapm_softc), 100693023Snsouch}; 100793023Snsouch 100893023SnsouchDRIVER_MODULE(viapm, pci, viapm_driver, viapm_devclass, 0, 0); 100993023SnsouchDRIVER_MODULE(viapropm, pci, viapropm_driver, viapropm_devclass, 0, 0); 1010181303SjhbDRIVER_MODULE(iicbb, viapm, iicbb_driver, iicbb_devclass, 0, 0); 1011162234SjhbDRIVER_MODULE(smbus, viapropm, smbus_driver, smbus_devclass, 0, 0); 101293023Snsouch 1013113506SmdoddMODULE_DEPEND(viapm, pci, 1, 1, 1); 1014151900SjhbMODULE_DEPEND(viapropm, pci, 1, 1, 1); 101593023SnsouchMODULE_DEPEND(viapm, iicbb, IICBB_MINVER, IICBB_PREFVER, IICBB_MAXVER); 101693023SnsouchMODULE_DEPEND(viapropm, smbus, SMBUS_MINVER, SMBUS_PREFVER, SMBUS_MAXVER); 101793023SnsouchMODULE_VERSION(viapm, 1); 1018151900Sjhb 1019151900Sjhb#ifdef DEV_ISA 1020151900SjhbDRIVER_MODULE(isa, viapm, isa_driver, isa_devclass, 0, 0); 1021151900SjhbDRIVER_MODULE(isa, viapropm, isa_driver, isa_devclass, 0, 0); 1022151900SjhbMODULE_DEPEND(viapm, isa, 1, 1, 1); 1023151900SjhbMODULE_DEPEND(viapropm, isa, 1, 1, 1); 1024151900Sjhb#endif 1025