Major rework of the iicbus/smbus framework:
- VIA chipset SMBus controllers added - alpm driver updated - Support for dynamic modules added - bktr FreeBSD smbus updated but not tested - cleanup
This commit is contained in:
parent
ed86ca364b
commit
c17d43407f
@ -493,6 +493,19 @@ DRIVER_MODULE(pcib, nexus, nexus_pcib_driver, pcib_devclass, 0, 0);
|
||||
static int
|
||||
pci_hostb_probe(device_t dev)
|
||||
{
|
||||
u_int32_t id;
|
||||
|
||||
id = pci_get_devid(dev);
|
||||
|
||||
switch (id) {
|
||||
|
||||
/* VIA VT82C596 Power Managment Function */
|
||||
case 0x30501106:
|
||||
return ENXIO;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (pci_get_class(dev) == PCIC_BRIDGE &&
|
||||
pci_get_subclass(dev) == PCIS_BRIDGE_HOST) {
|
||||
|
@ -2378,11 +2378,16 @@ device nmdm
|
||||
|
||||
device meteor 1
|
||||
|
||||
#
|
||||
# options BKTR_USE_FREEBSD_SMBUS
|
||||
# Compile with FreeBSD SMBus implementation
|
||||
#
|
||||
# Brooktree driver has been ported to the new I2C framework. Thus,
|
||||
# you'll need to have the following 3 lines in the kernel config.
|
||||
# device smbus
|
||||
# device iicbus
|
||||
# device iicbb
|
||||
# device iicsmb
|
||||
# The iic and smb devices are only needed if you want to control other
|
||||
# I2C slaves connected to the external connector of some cards.
|
||||
#
|
||||
|
@ -1260,6 +1260,7 @@ pci/ncr.c optional ncr
|
||||
pci/ohci_pci.c optional ohci
|
||||
pci/simos.c optional simos
|
||||
pci/uhci_pci.c optional uhci
|
||||
pci/viapm.c optional viapm
|
||||
pci/xrpu.c optional xrpu
|
||||
posix4/ksched.c optional _kposix_priority_scheduling
|
||||
posix4/p1003_1b.c standard
|
||||
|
@ -441,6 +441,7 @@ BKTR_GPIO_ACCESS opt_bktr.h
|
||||
BKTR_NO_MSP_RESET opt_bktr.h
|
||||
BKTR_430_FX_MODE opt_bktr.h
|
||||
BKTR_SIS_VIA_MODE opt_bktr.h
|
||||
BKTR_USE_FREEBSD_SMBUS opt_bktr.h
|
||||
|
||||
# meteor opt_meteor.h
|
||||
METEOR_ALLOC_PAGES opt_meteor.h
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*-
|
||||
* Copyright (c) 1998 Nicolas Souchu
|
||||
* Copyright (c) 1998, 2001 Nicolas Souchu
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -33,10 +33,13 @@
|
||||
* From brooktree848.c <fsmp@freefall.org>
|
||||
*/
|
||||
|
||||
#include "opt_bktr.h"
|
||||
|
||||
#include "bktr.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/bus.h>
|
||||
@ -62,196 +65,91 @@
|
||||
#include <pci/pcireg.h>
|
||||
#include <machine/ioctl_meteor.h>
|
||||
#include <machine/ioctl_bt848.h> /* extensions to ioctl_meteor.h */
|
||||
#include <dev/bktr/bktr_reg.h>
|
||||
|
||||
#include <dev/bktr/bktr_reg.h>
|
||||
#include <dev/bktr/bktr_i2c.h>
|
||||
|
||||
#include <dev/iicbus/iiconf.h>
|
||||
#include <dev/iicbus/iicbus.h>
|
||||
|
||||
#include <dev/smbus/smbconf.h>
|
||||
|
||||
#include "iicbb_if.h"
|
||||
#include "smbus_if.h"
|
||||
|
||||
|
||||
#include <dev/iicbus/iiconf.h>
|
||||
|
||||
#define I2C_DELAY 40
|
||||
|
||||
#define BTI2C_DEBUG(x) if (bti2c_debug) (x)
|
||||
static int bti2c_debug = 0;
|
||||
|
||||
struct bti2c_softc {
|
||||
|
||||
bus_space_tag_t memt; /* Bus space register access */
|
||||
bus_space_handle_t memh; /* Bus space register access */
|
||||
|
||||
int iic_owned; /* 1 if we own the iicbus */
|
||||
int smb_owned; /* 1 if we own the smbbus */
|
||||
|
||||
device_t smbus;
|
||||
device_t iicbus;
|
||||
};
|
||||
|
||||
struct bt_data {
|
||||
bus_space_tag_t memt;
|
||||
bus_space_handle_t memh;
|
||||
};
|
||||
struct bt_data btdata[NBKTR];
|
||||
|
||||
static int bti2c_probe(device_t);
|
||||
static int bti2c_attach(device_t);
|
||||
|
||||
static int bti2c_iic_callback(device_t, int, caddr_t *);
|
||||
static void bti2c_iic_setlines(device_t, int, int);
|
||||
static int bti2c_iic_getdataline(device_t);
|
||||
static int bti2c_iic_reset(device_t, u_char, u_char, u_char *);
|
||||
|
||||
static int bti2c_smb_callback(device_t, int, caddr_t *);
|
||||
static int bti2c_smb_writeb(device_t dev, u_char slave, char cmd, char byte);
|
||||
static int bti2c_smb_writew(device_t dev, u_char slave, char cmd, short word);
|
||||
static int bti2c_smb_readb(device_t dev, u_char slave, char cmd, char *byte);
|
||||
|
||||
static devclass_t bti2c_devclass;
|
||||
|
||||
static device_method_t bti2c_methods[] = {
|
||||
/* device interface */
|
||||
DEVMETHOD(device_probe, bti2c_probe),
|
||||
DEVMETHOD(device_attach, bti2c_attach),
|
||||
|
||||
/* bus interface */
|
||||
DEVMETHOD(bus_print_child, bus_generic_print_child),
|
||||
|
||||
/* iicbb interface */
|
||||
DEVMETHOD(iicbb_callback, bti2c_iic_callback),
|
||||
DEVMETHOD(iicbb_setlines, bti2c_iic_setlines),
|
||||
DEVMETHOD(iicbb_getdataline, bti2c_iic_getdataline),
|
||||
DEVMETHOD(iicbb_reset, bti2c_iic_reset),
|
||||
|
||||
/* smbus interface */
|
||||
DEVMETHOD(smbus_callback, bti2c_smb_callback),
|
||||
DEVMETHOD(smbus_writeb, bti2c_smb_writeb),
|
||||
DEVMETHOD(smbus_writew, bti2c_smb_writew),
|
||||
DEVMETHOD(smbus_readb, bti2c_smb_readb),
|
||||
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
#if (__FreeBSD_version < 400000)
|
||||
/* FreeBSD 3.x needs DRIVER_TYPE_MISC */
|
||||
static driver_t bti2c_driver = {
|
||||
"bti2c",
|
||||
bti2c_methods,
|
||||
DRIVER_TYPE_MISC,
|
||||
sizeof(struct bti2c_softc),
|
||||
};
|
||||
#endif
|
||||
|
||||
#if (__FreeBSD_version >=400000)
|
||||
static driver_t bti2c_driver = {
|
||||
"bti2c",
|
||||
bti2c_methods,
|
||||
sizeof(struct bti2c_softc),
|
||||
};
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Call this to pass the address of the bktr device to the
|
||||
* bti2c_i2c layer and initialize all the I2C bus architecture
|
||||
*/
|
||||
int
|
||||
bt848_i2c_attach(int unit, struct bktr_softc * bktr, struct bktr_i2c_softc *i2c_sc)
|
||||
int bt848_i2c_attach(device_t dev)
|
||||
{
|
||||
device_t interface;
|
||||
device_t bitbang;
|
||||
struct bktr_softc *bktr_sc = (struct bktr_softc *)device_get_softc(dev);
|
||||
struct bktr_i2c_softc *sc = &bktr_sc->i2c_sc;
|
||||
|
||||
btdata[unit].memh = bktr->memh;
|
||||
btdata[unit].memt = bktr->memt;
|
||||
device_t *list;
|
||||
int count;
|
||||
|
||||
/* XXX add the I2C interface to the root_bus until pcibus is ready */
|
||||
#if (__FreeBSD_version < 400000)
|
||||
interface = device_add_child(root_bus, "bti2c", unit, NULL);
|
||||
#else
|
||||
interface = device_add_child(root_bus, "bti2c", unit);
|
||||
#endif
|
||||
sc->smbus = device_add_child(dev, "smbus", -1);
|
||||
sc->iicbb = device_add_child(dev, "iicbb", -1);
|
||||
|
||||
/* add bit-banging generic code onto bti2c interface */
|
||||
#if (__FreeBSD_version < 400000)
|
||||
bitbang = device_add_child(interface, "iicbb", -1, NULL);
|
||||
#else
|
||||
bitbang = device_add_child(interface, "iicbb", -1);
|
||||
#endif
|
||||
if (!sc->iicbb || !sc->smbus)
|
||||
return ENXIO;
|
||||
|
||||
/* probe and attach the interface, we need it NOW
|
||||
* bit-banging code is also probed and attached */
|
||||
device_probe_and_attach(interface);
|
||||
device_probe_and_attach(bitbang);
|
||||
bus_generic_attach(dev);
|
||||
|
||||
/* smb and i2c interfaces are available for the bt848 chip
|
||||
* connect bit-banging generic code to an iicbus */
|
||||
if ((i2c_sc->iicbus = iicbus_alloc_bus(bitbang)))
|
||||
device_probe_and_attach(i2c_sc->iicbus);
|
||||
|
||||
/* hardware i2c is actually smb over the bti2c interface */
|
||||
if ((i2c_sc->smbus = smbus_alloc_bus(interface)))
|
||||
device_probe_and_attach(i2c_sc->smbus);
|
||||
/* the iicbus is the first child of device iicbb */
|
||||
device_get_children(sc->iicbb, &list, &count);
|
||||
if (count) {
|
||||
sc->iicbus = list[0];
|
||||
free(list, M_TEMP);
|
||||
}
|
||||
|
||||
return (0);
|
||||
};
|
||||
|
||||
/*
|
||||
* Not a real probe, we know the device exists since the device has
|
||||
* been added after the successfull pci probe.
|
||||
*/
|
||||
static int
|
||||
bti2c_probe(device_t dev)
|
||||
int bt848_i2c_detach(device_t dev)
|
||||
{
|
||||
device_set_desc(dev, "bt848 Hard/Soft I2C controller");
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
bti2c_attach(device_t dev)
|
||||
{
|
||||
struct bti2c_softc *sc = (struct bti2c_softc *)device_get_softc(dev);
|
||||
|
||||
/* XXX should use ivars with pcibus or pcibus methods to access
|
||||
* onboard memory */
|
||||
sc->memh = btdata[device_get_unit(dev)].memh;
|
||||
sc->memt = btdata[device_get_unit(dev)].memt;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
bti2c_smb_callback(device_t dev, int index, caddr_t *data)
|
||||
{
|
||||
struct bti2c_softc *sc = (struct bti2c_softc *)device_get_softc(dev);
|
||||
struct bktr_softc *bktr_sc = (struct bktr_softc *)device_get_softc(dev);
|
||||
struct bktr_i2c_softc *sc = &bktr_sc->i2c_sc;
|
||||
int error = 0;
|
||||
|
||||
if ((error = bus_generic_detach(dev)))
|
||||
goto error;
|
||||
|
||||
if (sc->iicbb && (error = device_delete_child(dev, sc->iicbb)))
|
||||
goto error;
|
||||
|
||||
if (sc->smbus && (error = device_delete_child(dev, sc->smbus)))
|
||||
goto error;
|
||||
|
||||
error:
|
||||
return (error);
|
||||
}
|
||||
|
||||
int bti2c_smb_callback(device_t dev, int index, caddr_t *data)
|
||||
{
|
||||
struct bktr_softc *bktr_sc = (struct bktr_softc *)device_get_softc(dev);
|
||||
struct bktr_i2c_softc *sc = &bktr_sc->i2c_sc;
|
||||
int error = 0;
|
||||
int how;
|
||||
|
||||
/* test each time if we already have/haven't the iicbus
|
||||
* to avoid deadlocks
|
||||
*/
|
||||
switch (index) {
|
||||
case SMB_REQUEST_BUS:
|
||||
if (!sc->iic_owned) {
|
||||
/* request the iicbus */
|
||||
how = *(int *)data;
|
||||
error = iicbus_request_bus(sc->iicbus, dev, how);
|
||||
if (!error)
|
||||
sc->iic_owned = 1;
|
||||
}
|
||||
/* XXX test & set */
|
||||
if (!sc->bus_owned) {
|
||||
sc->bus_owned = 1;
|
||||
} else
|
||||
error = EWOULDBLOCK;
|
||||
break;
|
||||
|
||||
case SMB_RELEASE_BUS:
|
||||
if (sc->iic_owned) {
|
||||
/* release the iicbus */
|
||||
error = iicbus_release_bus(sc->iicbus, dev);
|
||||
if (!error)
|
||||
sc->iic_owned = 0;
|
||||
}
|
||||
/* XXX test & set */
|
||||
if (sc->bus_owned) {
|
||||
sc->bus_owned = 0;
|
||||
} else
|
||||
error = EINVAL;
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -261,34 +159,30 @@ bti2c_smb_callback(device_t dev, int index, caddr_t *data)
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
bti2c_iic_callback(device_t dev, int index, caddr_t *data)
|
||||
int bti2c_iic_callback(device_t dev, int index, caddr_t *data)
|
||||
{
|
||||
struct bti2c_softc *sc = (struct bti2c_softc *)device_get_softc(dev);
|
||||
struct bktr_softc *bktr_sc = (struct bktr_softc *)device_get_softc(dev);
|
||||
struct bktr_i2c_softc *sc = &bktr_sc->i2c_sc;
|
||||
int error = 0;
|
||||
int how;
|
||||
|
||||
/* test each time if we already have/haven't the smbus
|
||||
* to avoid deadlocks
|
||||
*/
|
||||
switch (index) {
|
||||
case IIC_REQUEST_BUS:
|
||||
if (!sc->smb_owned) {
|
||||
/* request the smbus */
|
||||
how = *(int *)data;
|
||||
error = smbus_request_bus(sc->smbus, dev, how);
|
||||
if (!error)
|
||||
sc->smb_owned = 1;
|
||||
}
|
||||
/* XXX test & set */
|
||||
if (!sc->bus_owned) {
|
||||
sc->bus_owned = 1;
|
||||
} else
|
||||
error = EWOULDBLOCK;
|
||||
break;
|
||||
|
||||
case IIC_RELEASE_BUS:
|
||||
if (sc->smb_owned) {
|
||||
/* release the smbus */
|
||||
error = smbus_release_bus(sc->smbus, dev);
|
||||
if (!error)
|
||||
sc->smb_owned = 0;
|
||||
}
|
||||
/* XXX test & set */
|
||||
if (sc->bus_owned) {
|
||||
sc->bus_owned = 0;
|
||||
} else
|
||||
error = EINVAL;
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -298,8 +192,7 @@ bti2c_iic_callback(device_t dev, int index, caddr_t *data)
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
bti2c_iic_reset(device_t dev, u_char speed, u_char addr, u_char * oldaddr)
|
||||
int bti2c_iic_reset(device_t dev, u_char speed, u_char addr, u_char * oldaddr)
|
||||
{
|
||||
if (oldaddr)
|
||||
*oldaddr = 0; /* XXX */
|
||||
@ -307,48 +200,77 @@ bti2c_iic_reset(device_t dev, u_char speed, u_char addr, u_char * oldaddr)
|
||||
return (IIC_ENOADDR);
|
||||
}
|
||||
|
||||
static void
|
||||
bti2c_iic_setlines(device_t dev, int ctrl, int data)
|
||||
void bti2c_iic_setsda(device_t dev, int val)
|
||||
{
|
||||
struct bti2c_softc *sc = (struct bti2c_softc *)device_get_softc(dev);
|
||||
struct bktr_softc *sc = (struct bktr_softc *)device_get_softc(dev);
|
||||
int clock;
|
||||
|
||||
clock = INL(sc, BKTR_I2C_DATA_CTL) & 0x2;
|
||||
|
||||
if (val)
|
||||
OUTL(sc, BKTR_I2C_DATA_CTL, clock | 1);
|
||||
else
|
||||
OUTL(sc, BKTR_I2C_DATA_CTL, clock);
|
||||
|
||||
OUTL(sc, BKTR_I2C_DATA_CTL, (ctrl << 1) | data);;
|
||||
DELAY(I2C_DELAY);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static int
|
||||
bti2c_iic_getdataline(device_t dev)
|
||||
void bti2c_iic_setscl(device_t dev, int val)
|
||||
{
|
||||
struct bti2c_softc *sc = (struct bti2c_softc *)device_get_softc(dev);
|
||||
struct bktr_softc *sc = (struct bktr_softc *)device_get_softc(dev);
|
||||
int data;
|
||||
|
||||
return ( INL(sc,BKTR_I2C_DATA_CTL) & 0x1);
|
||||
data = INL(sc, BKTR_I2C_DATA_CTL) & 0x1;
|
||||
|
||||
if (val)
|
||||
OUTL(sc, BKTR_I2C_DATA_CTL, 0x2 | data);
|
||||
else
|
||||
OUTL(sc, BKTR_I2C_DATA_CTL, data);
|
||||
|
||||
DELAY(I2C_DELAY);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int
|
||||
bti2c_iic_getsda(device_t dev)
|
||||
{
|
||||
struct bktr_softc *sc = (struct bktr_softc *)device_get_softc(dev);
|
||||
|
||||
return (INL(sc,BKTR_I2C_DATA_CTL) & 0x1);
|
||||
}
|
||||
|
||||
int
|
||||
bti2c_iic_getscl(device_t dev)
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
bti2c_write(struct bti2c_softc* bti2c_sc, u_long data)
|
||||
bti2c_write(struct bktr_softc *sc, u_long data)
|
||||
{
|
||||
u_long x;
|
||||
|
||||
/* clear status bits */
|
||||
OUTL(bti2c_sc, BKTR_INT_STAT, (BT848_INT_RACK | BT848_INT_I2CDONE));
|
||||
OUTL(sc, BKTR_INT_STAT, (BT848_INT_RACK | BT848_INT_I2CDONE));
|
||||
|
||||
BTI2C_DEBUG(printf("w%lx", data));
|
||||
|
||||
/* write the address and data */
|
||||
OUTL(bti2c_sc, BKTR_I2C_DATA_CTL, data);
|
||||
OUTL(sc, BKTR_I2C_DATA_CTL, data);
|
||||
|
||||
/* wait for completion */
|
||||
for ( x = 0x7fffffff; x; --x ) { /* safety valve */
|
||||
if ( INL(bti2c_sc, BKTR_INT_STAT) & BT848_INT_I2CDONE )
|
||||
if ( INL(sc, BKTR_INT_STAT) & BT848_INT_I2CDONE )
|
||||
break;
|
||||
}
|
||||
|
||||
/* check for ACK */
|
||||
if ( !x || !( INL(bti2c_sc, BKTR_INT_STAT) & BT848_INT_RACK) ) {
|
||||
if ( !x || !( INL(sc, BKTR_INT_STAT) & BT848_INT_RACK) ) {
|
||||
BTI2C_DEBUG(printf("%c%c", (!x)?'+':'-',
|
||||
(!( INL(bti2c_sc, BKTR_INT_STAT) & BT848_INT_RACK))?'+':'-'));
|
||||
(!( INL(sc, BKTR_INT_STAT) & BT848_INT_RACK))?'+':'-'));
|
||||
return (SMB_ENOACK);
|
||||
}
|
||||
BTI2C_DEBUG(printf("+"));
|
||||
@ -357,10 +279,10 @@ bti2c_write(struct bti2c_softc* bti2c_sc, u_long data)
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
static int
|
||||
int
|
||||
bti2c_smb_writeb(device_t dev, u_char slave, char cmd, char byte)
|
||||
{
|
||||
struct bti2c_softc *sc = (struct bti2c_softc *)device_get_softc(dev);
|
||||
struct bktr_softc *sc = (struct bktr_softc *)device_get_softc(dev);
|
||||
u_long data;
|
||||
|
||||
data = ((slave & 0xff) << 24) | ((byte & 0xff) << 16) | (u_char)cmd;
|
||||
@ -372,10 +294,10 @@ bti2c_smb_writeb(device_t dev, u_char slave, char cmd, char byte)
|
||||
* byte1 becomes low byte of word
|
||||
* byte2 becomes high byte of word
|
||||
*/
|
||||
static int
|
||||
int
|
||||
bti2c_smb_writew(device_t dev, u_char slave, char cmd, short word)
|
||||
{
|
||||
struct bti2c_softc *sc = (struct bti2c_softc *)device_get_softc(dev);
|
||||
struct bktr_softc *sc = (struct bktr_softc *)device_get_softc(dev);
|
||||
u_long data;
|
||||
char low, high;
|
||||
|
||||
@ -391,10 +313,10 @@ bti2c_smb_writew(device_t dev, u_char slave, char cmd, short word)
|
||||
/*
|
||||
* The Bt878 and Bt879 differed on the treatment of i2c commands
|
||||
*/
|
||||
static int
|
||||
int
|
||||
bti2c_smb_readb(device_t dev, u_char slave, char cmd, char *byte)
|
||||
{
|
||||
struct bti2c_softc *sc = (struct bti2c_softc *)device_get_softc(dev);
|
||||
struct bktr_softc *sc = (struct bktr_softc *)device_get_softc(dev);
|
||||
u_long x;
|
||||
|
||||
/* clear status bits */
|
||||
@ -422,5 +344,3 @@ bti2c_smb_readb(device_t dev, u_char slave, char cmd, char *byte)
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
DRIVER_MODULE(bti2c, root, bti2c_driver, bti2c_devclass, 0, 0);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*-
|
||||
* Copyright (c) 1998 Nicolas Souchu
|
||||
* Copyright (c) 1998, 2001 Nicolas Souchu
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -29,6 +29,19 @@
|
||||
#ifndef _BT848_I2C_H
|
||||
#define _BT848_I2C_H
|
||||
|
||||
extern int bt848_i2c_attach(int, struct bktr_softc *bktr, struct bktr_i2c_softc *);
|
||||
extern int bt848_i2c_attach(device_t);
|
||||
extern int bt848_i2c_detach(device_t);
|
||||
|
||||
extern int bti2c_iic_callback(device_t, int, caddr_t *);
|
||||
extern void bti2c_iic_setsda(device_t, int);
|
||||
extern void bti2c_iic_setscl(device_t, int);
|
||||
extern int bti2c_iic_getsda(device_t);
|
||||
extern int bti2c_iic_getscl(device_t);
|
||||
extern int bti2c_iic_reset(device_t, u_char, u_char, u_char *);
|
||||
|
||||
extern int bti2c_smb_callback(device_t, int, caddr_t *);
|
||||
extern int bti2c_smb_writeb(device_t dev, u_char slave, char cmd, char byte);
|
||||
extern int bti2c_smb_writew(device_t dev, u_char slave, char cmd, short word);
|
||||
extern int bti2c_smb_readb(device_t dev, u_char slave, char cmd, char *byte);
|
||||
|
||||
#endif
|
||||
|
@ -83,7 +83,7 @@
|
||||
#include <vm/pmap.h>
|
||||
#include <vm/vm_extern.h>
|
||||
|
||||
#if (__FreeBSD_version >=400000) || (NSMBUS > 0)
|
||||
#if (__FreeBSD_version >=400000)
|
||||
#include <sys/bus.h> /* used by smbus and newbus */
|
||||
#endif
|
||||
|
||||
@ -190,11 +190,14 @@ int bktr_debug = 0;
|
||||
#include <dev/bktr/bktr_audio.h>
|
||||
#include <dev/bktr/bktr_core.h>
|
||||
#include <dev/bktr/bktr_os.h>
|
||||
|
||||
#if defined(BKTR_USE_FREEBSD_SMBUS)
|
||||
#include <dev/bktr/bktr_i2c.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "iicbb_if.h"
|
||||
#include "smbus_if.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/****************************/
|
||||
@ -215,6 +218,22 @@ static device_method_t bktr_methods[] = {
|
||||
DEVMETHOD(device_detach, bktr_detach),
|
||||
DEVMETHOD(device_shutdown, bktr_shutdown),
|
||||
|
||||
#if defined(BKTR_USE_FREEBSD_SMBUS)
|
||||
/* iicbb interface */
|
||||
DEVMETHOD(iicbb_callback, bti2c_iic_callback),
|
||||
DEVMETHOD(iicbb_setsda, bti2c_iic_setsda),
|
||||
DEVMETHOD(iicbb_setscl, bti2c_iic_setscl),
|
||||
DEVMETHOD(iicbb_getsda, bti2c_iic_getsda),
|
||||
DEVMETHOD(iicbb_getscl, bti2c_iic_getscl),
|
||||
DEVMETHOD(iicbb_reset, bti2c_iic_reset),
|
||||
|
||||
/* smbus interface */
|
||||
DEVMETHOD(smbus_callback, bti2c_smb_callback),
|
||||
DEVMETHOD(smbus_writeb, bti2c_smb_writeb),
|
||||
DEVMETHOD(smbus_writew, bti2c_smb_writew),
|
||||
DEVMETHOD(smbus_readb, bti2c_smb_readb),
|
||||
#endif
|
||||
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
@ -392,14 +411,11 @@ bktr_attach( device_t dev )
|
||||
#endif
|
||||
pci_write_config(dev, 0x40, fun, 2);
|
||||
|
||||
|
||||
/* XXX call bt848_i2c dependent attach() routine */
|
||||
#if defined(BKTR_USE_FREEBSD_SMBUS)
|
||||
if (bt848_i2c_attach(unit, bktr, &bktr->i2c_sc))
|
||||
if (bt848_i2c_attach(dev))
|
||||
printf("bktr%d: i2c_attach: can't attach\n", unit);
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* PCI latency timer. 32 is a good value for 4 bus mastering slots, if
|
||||
* you have more than four, then 16 would probably be a better value.
|
||||
@ -477,6 +493,11 @@ bktr_detach( device_t dev )
|
||||
OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
|
||||
OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
|
||||
|
||||
#if defined(BKTR_USE_FREEBSD_SMBUS)
|
||||
if (bt848_i2c_detach(dev))
|
||||
printf("bktr%d: i2c_attach: can't attach\n", unit);
|
||||
#endif
|
||||
|
||||
/* Note: We do not free memory for RISC programs, grab buffer, vbi buffers */
|
||||
/* The memory is retained by the bktr_mem module so we can unload and */
|
||||
/* then reload the main bktr driver module */
|
||||
@ -965,14 +986,11 @@ bktr_attach( pcici_t tag, int unit )
|
||||
#endif
|
||||
pci_conf_write(tag, 0x40, fun);
|
||||
|
||||
|
||||
/* XXX call bt848_i2c dependent attach() routine */
|
||||
#if defined(BKTR_USE_FREEBSD_SMBUS)
|
||||
if (bt848_i2c_attach(unit, bktr, &bktr->i2c_sc))
|
||||
if (bt848_i2c_attach(dev))
|
||||
printf("bktr%d: i2c_attach: can't attach\n", unit);
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* PCI latency timer. 32 is a good value for 4 bus mastering slots, if
|
||||
* you have more than four, then 16 would probably be a better value.
|
||||
|
@ -34,17 +34,6 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
# if (__FreeBSD_version >= 310000)
|
||||
# include "smbus.h"
|
||||
# else
|
||||
# define NSMBUS 0 /* FreeBSD before 3.1 does not have SMBUS */
|
||||
# endif
|
||||
# if (NSMBUS > 0)
|
||||
# define BKTR_USE_FREEBSD_SMBUS
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef __NetBSD__
|
||||
#include <machine/bus.h> /* struct device */
|
||||
#include <sys/device.h>
|
||||
@ -457,6 +446,9 @@ struct format_params {
|
||||
|
||||
#if defined(BKTR_USE_FREEBSD_SMBUS)
|
||||
struct bktr_i2c_softc {
|
||||
int bus_owned;
|
||||
|
||||
device_t iicbb;
|
||||
device_t iicbus;
|
||||
device_t smbus;
|
||||
};
|
||||
@ -556,9 +548,9 @@ struct bktr_softc {
|
||||
bus_space_handle_t memh; /* Bus space register access functions */
|
||||
bus_size_t obmemsz;/* Size of card (bytes) */
|
||||
#endif
|
||||
#if (NSMBUS > 0)
|
||||
#if defined(BKTR_USE_FREEBSD_SMBUS)
|
||||
struct bktr_i2c_softc i2c_sc; /* bt848_i2c device */
|
||||
#endif
|
||||
#endif
|
||||
char bktr_xname[7]; /* device name and unit number */
|
||||
#endif
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*-
|
||||
* Copyright (c) 1998 Nicolas Souchu
|
||||
* Copyright (c) 1998, 2001 Nicolas Souchu
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -30,7 +30,6 @@
|
||||
* I2C bus IP driver
|
||||
*/
|
||||
|
||||
#ifdef _KERNEL
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/mbuf.h>
|
||||
@ -47,7 +46,6 @@
|
||||
#include <net/if_types.h>
|
||||
#include <net/netisr.h>
|
||||
|
||||
#endif
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/socket.h>
|
||||
#include <net/netisr.h>
|
||||
@ -65,6 +63,8 @@
|
||||
|
||||
#include "iicbus_if.h"
|
||||
|
||||
#define PCF_MASTER_ADDRESS 0xaa
|
||||
|
||||
#define ICHDRLEN sizeof(u_int)
|
||||
#define ICMTU 1500 /* default mtu */
|
||||
|
||||
@ -130,7 +130,7 @@ icattach(device_t dev)
|
||||
struct ic_softc *sc = (struct ic_softc *)device_get_softc(dev);
|
||||
struct ifnet *ifp = &sc->ic_if;
|
||||
|
||||
sc->ic_addr = iicbus_get_addr(dev);
|
||||
sc->ic_addr = PCF_MASTER_ADDRESS; /* XXX only PCF masters */
|
||||
|
||||
ifp->if_softc = sc;
|
||||
ifp->if_name = "ic";
|
||||
@ -448,3 +448,5 @@ error:
|
||||
}
|
||||
|
||||
DRIVER_MODULE(ic, iicbus, ic_driver, ic_devclass, 0, 0);
|
||||
MODULE_DEPEND(ic, iicbus, IICBUS_MINVER, IICBUS_PREFVER, IICBUS_MAXVER);
|
||||
MODULE_VERSION(ic, 1);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*-
|
||||
* Copyright (c) 1998 Nicolas Souchu
|
||||
* Copyright (c) 1998, 2001 Nicolas Souchu
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -47,11 +47,13 @@
|
||||
|
||||
struct iic_softc {
|
||||
|
||||
u_char sc_addr; /* address on iicbus */
|
||||
u_char sc_addr; /* 7 bit address on iicbus */
|
||||
int sc_count; /* >0 if device opened */
|
||||
|
||||
char sc_buffer[BUFSIZE]; /* output buffer */
|
||||
char sc_inbuf[BUFSIZE]; /* input buffer */
|
||||
|
||||
dev_t sc_devnode;
|
||||
};
|
||||
|
||||
#define IIC_SOFTC(unit) \
|
||||
@ -62,13 +64,17 @@ struct iic_softc {
|
||||
|
||||
static int iic_probe(device_t);
|
||||
static int iic_attach(device_t);
|
||||
static int iic_detach(device_t);
|
||||
static void iic_identify(driver_t *driver, device_t parent);
|
||||
|
||||
static devclass_t iic_devclass;
|
||||
|
||||
static device_method_t iic_methods[] = {
|
||||
/* device interface */
|
||||
DEVMETHOD(device_identify, iic_identify),
|
||||
DEVMETHOD(device_probe, iic_probe),
|
||||
DEVMETHOD(device_attach, iic_attach),
|
||||
DEVMETHOD(device_detach, iic_detach),
|
||||
|
||||
/* iicbus interface */
|
||||
DEVMETHOD(iicbus_intr, iicbus_generic_intr),
|
||||
@ -105,30 +111,44 @@ static struct cdevsw iic_cdevsw = {
|
||||
/* flags */ 0,
|
||||
};
|
||||
|
||||
/*
|
||||
* iicprobe()
|
||||
*/
|
||||
static void
|
||||
iic_identify(driver_t *driver, device_t parent)
|
||||
{
|
||||
BUS_ADD_CHILD(parent, 0, "iic", 0);
|
||||
}
|
||||
|
||||
static int
|
||||
iic_probe(device_t dev)
|
||||
{
|
||||
struct iic_softc *sc = (struct iic_softc *)device_get_softc(dev);
|
||||
|
||||
sc->sc_addr = iicbus_get_addr(dev);
|
||||
|
||||
/* XXX detect chip with start/stop conditions */
|
||||
|
||||
device_set_desc(dev, "I2C generic I/O");
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* iicattach()
|
||||
*/
|
||||
static int
|
||||
iic_attach(device_t dev)
|
||||
{
|
||||
make_dev(&iic_cdevsw, device_get_unit(dev), /* XXX cleanup */
|
||||
struct iic_softc *sc = (struct iic_softc *)device_get_softc(dev);
|
||||
|
||||
if (!sc)
|
||||
return (ENOMEM);
|
||||
|
||||
bzero(sc, sizeof(struct iic_softc));
|
||||
|
||||
sc->sc_devnode = make_dev(&iic_cdevsw, device_get_unit(dev),
|
||||
UID_ROOT, GID_WHEEL,
|
||||
0600, "iic%d", device_get_unit(dev));
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
iic_detach(device_t dev)
|
||||
{
|
||||
struct iic_softc *sc = (struct iic_softc *)device_get_softc(dev);
|
||||
|
||||
if (sc->sc_devnode)
|
||||
destroy_dev(sc->sc_devnode);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -174,7 +194,7 @@ iicwrite(dev_t dev, struct uio * uio, int ioflag)
|
||||
struct iic_softc *sc = IIC_SOFTC(minor(dev));
|
||||
int sent, error, count;
|
||||
|
||||
if (!sc || !iicdev)
|
||||
if (!sc || !iicdev || !sc->sc_addr)
|
||||
return (EINVAL);
|
||||
|
||||
if (sc->sc_count == 0)
|
||||
@ -202,7 +222,7 @@ iicread(dev_t dev, struct uio * uio, int ioflag)
|
||||
int len, error = 0;
|
||||
int bufsize;
|
||||
|
||||
if (!sc || !iicdev)
|
||||
if (!sc || !iicdev || !sc->sc_addr)
|
||||
return (EINVAL);
|
||||
|
||||
if (sc->sc_count == 0)
|
||||
@ -246,6 +266,15 @@ iicioctl(dev_t dev, u_long cmd, caddr_t data, int flags, struct thread *td)
|
||||
switch (cmd) {
|
||||
case I2CSTART:
|
||||
error = iicbus_start(parent, s->slave, 0);
|
||||
|
||||
/*
|
||||
* Implicitly set the chip addr to the slave addr passed as
|
||||
* parameter. Consequently, start/stop shall be called before
|
||||
* the read or the write of a block.
|
||||
*/
|
||||
if (!error)
|
||||
sc->sc_addr = s->slave;
|
||||
|
||||
break;
|
||||
|
||||
case I2CSTOP:
|
||||
@ -257,11 +286,11 @@ iicioctl(dev_t dev, u_long cmd, caddr_t data, int flags, struct thread *td)
|
||||
break;
|
||||
|
||||
case I2CWRITE:
|
||||
error = iicbus_write(parent, s->buf, s->count, &count, 0);
|
||||
error = iicbus_write(parent, s->buf, s->count, &count, 10);
|
||||
break;
|
||||
|
||||
case I2CREAD:
|
||||
error = iicbus_read(parent, s->buf, s->count, &count, s->last, 0);
|
||||
error = iicbus_read(parent, s->buf, s->count, &count, s->last, 10);
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -274,3 +303,5 @@ iicioctl(dev_t dev, u_long cmd, caddr_t data, int flags, struct thread *td)
|
||||
}
|
||||
|
||||
DRIVER_MODULE(iic, iicbus, iic_driver, iic_devclass, 0, 0);
|
||||
MODULE_DEPEND(iic, iicbus, IICBUS_MINVER, IICBUS_PREFVER, IICBUS_MAXVER);
|
||||
MODULE_VERSION(iic, 1);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*-
|
||||
* Copyright (c) 1998 Nicolas Souchu
|
||||
* Copyright (c) 1998, 2001 Nicolas Souchu
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -41,7 +41,6 @@
|
||||
* From Linux I2C generic interface
|
||||
* (c) 1998 Gerd Knorr <kraxel@cs.tu-berlin.de>
|
||||
*
|
||||
* TODO: port Peter's generic bit-banging code <dufault@hda.com>
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
@ -61,11 +60,12 @@
|
||||
#include "iicbb_if.h"
|
||||
|
||||
struct iicbb_softc {
|
||||
int dummy;
|
||||
device_t iicbus;
|
||||
};
|
||||
|
||||
static int iicbb_probe(device_t);
|
||||
static int iicbb_attach(device_t);
|
||||
static int iicbb_detach(device_t);
|
||||
static int iicbb_print_child(device_t, device_t);
|
||||
|
||||
static int iicbb_callback(device_t, int, caddr_t);
|
||||
@ -79,7 +79,7 @@ static device_method_t iicbb_methods[] = {
|
||||
/* device interface */
|
||||
DEVMETHOD(device_probe, iicbb_probe),
|
||||
DEVMETHOD(device_attach, iicbb_attach),
|
||||
DEVMETHOD(device_detach, bus_generic_detach),
|
||||
DEVMETHOD(device_detach, iicbb_detach),
|
||||
|
||||
/* bus interface */
|
||||
DEVMETHOD(bus_print_child, iicbb_print_child),
|
||||
@ -106,13 +106,36 @@ static devclass_t iicbb_devclass;
|
||||
|
||||
static int iicbb_probe(device_t dev)
|
||||
{
|
||||
device_set_desc(dev, "I2C generic bit-banging driver");
|
||||
device_set_desc(dev, "I2C bit-banging driver");
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int iicbb_attach(device_t dev)
|
||||
{
|
||||
struct iicbb_softc *sc = (struct iicbb_softc *)device_get_softc(dev);
|
||||
|
||||
bzero(sc, sizeof(struct iicbb_softc));
|
||||
|
||||
sc->iicbus = device_add_child(dev, "iicbus", -1);
|
||||
|
||||
if (!sc->iicbus)
|
||||
return (ENXIO);
|
||||
|
||||
bus_generic_attach(dev);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int iicbb_detach(device_t dev)
|
||||
{
|
||||
struct iicbb_softc *sc = (struct iicbb_softc *)device_get_softc(dev);
|
||||
|
||||
if (sc->iicbus) {
|
||||
bus_generic_detach(dev);
|
||||
device_delete_child(dev, sc->iicbus);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -140,15 +163,51 @@ iicbb_print_child(device_t bus, device_t dev)
|
||||
return (retval);
|
||||
}
|
||||
|
||||
#define I2C_SET(dev,ctrl,data) \
|
||||
IICBB_SETLINES(device_get_parent(dev), ctrl, data)
|
||||
#define IIC_DELAY 10
|
||||
|
||||
#define I2C_GET(dev) (IICBB_GETDATALINE(device_get_parent(dev)))
|
||||
#define I2C_SETSDA(dev,val) do { \
|
||||
IICBB_SETSDA(device_get_parent(dev), val); \
|
||||
DELAY(IIC_DELAY); \
|
||||
} while (0)
|
||||
|
||||
#define I2C_SETSCL(dev,val) do { \
|
||||
iicbb_setscl(dev, val, 100); \
|
||||
} while (0)
|
||||
|
||||
#define I2C_SET(dev,ctrl,data) do { \
|
||||
I2C_SETSCL(dev, ctrl); \
|
||||
I2C_SETSDA(dev, data); \
|
||||
} while (0)
|
||||
|
||||
#define I2C_GETSDA(dev) (IICBB_GETSDA(device_get_parent(dev)))
|
||||
|
||||
#define I2C_GETSCL(dev) (IICBB_GETSCL(device_get_parent(dev)))
|
||||
|
||||
static int i2c_debug = 0;
|
||||
#define I2C_DEBUG(x) if (i2c_debug) (x)
|
||||
#define I2C_DEBUG(x) do { \
|
||||
if (i2c_debug) (x); \
|
||||
} while (0)
|
||||
|
||||
static void iicbb_one(device_t dev)
|
||||
#define I2C_LOG(format,args...) do { \
|
||||
printf(format, args); \
|
||||
} while (0)
|
||||
|
||||
static void iicbb_setscl(device_t dev, int val, int timeout)
|
||||
{
|
||||
int k = 0;
|
||||
|
||||
IICBB_SETSCL(device_get_parent(dev), val);
|
||||
DELAY(IIC_DELAY);
|
||||
|
||||
while (val && !I2C_GETSCL(dev) && k++ < timeout) {
|
||||
IICBB_SETSCL(device_get_parent(dev), val);
|
||||
DELAY(IIC_DELAY);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void iicbb_one(device_t dev, int timeout)
|
||||
{
|
||||
I2C_SET(dev,0,1);
|
||||
I2C_SET(dev,1,1);
|
||||
@ -156,7 +215,7 @@ static void iicbb_one(device_t dev)
|
||||
return;
|
||||
}
|
||||
|
||||
static void iicbb_zero(device_t dev)
|
||||
static void iicbb_zero(device_t dev, int timeout)
|
||||
{
|
||||
I2C_SET(dev,0,0);
|
||||
I2C_SET(dev,1,0);
|
||||
@ -181,17 +240,17 @@ static void iicbb_zero(device_t dev)
|
||||
static int iicbb_ack(device_t dev, int timeout)
|
||||
{
|
||||
int noack;
|
||||
int k = timeout/10;
|
||||
int k = 0;
|
||||
|
||||
I2C_SET(dev,0,1);
|
||||
I2C_SET(dev,1,1);
|
||||
|
||||
do {
|
||||
noack = I2C_GET(dev);
|
||||
noack = I2C_GETSDA(dev);
|
||||
if (!noack)
|
||||
break;
|
||||
DELAY(10); /* XXX wait 10us */
|
||||
} while (k--);
|
||||
DELAY(10);
|
||||
k += 10;
|
||||
} while (k < timeout);
|
||||
|
||||
I2C_SET(dev,0,1);
|
||||
I2C_DEBUG(printf("%c ",noack?'-':'+'));
|
||||
@ -199,18 +258,22 @@ static int iicbb_ack(device_t dev, int timeout)
|
||||
return (noack);
|
||||
}
|
||||
|
||||
static void iicbb_sendbyte(device_t dev, u_char data)
|
||||
static void iicbb_sendbyte(device_t dev, u_char data, int timeout)
|
||||
{
|
||||
int i;
|
||||
|
||||
I2C_SET(dev,0,0);
|
||||
for (i=7; i>=0; i--)
|
||||
(data&(1<<i)) ? iicbb_one(dev) : iicbb_zero(dev);
|
||||
for (i=7; i>=0; i--) {
|
||||
if (data&(1<<i)) {
|
||||
iicbb_one(dev, timeout);
|
||||
} else {
|
||||
iicbb_zero(dev, timeout);
|
||||
}
|
||||
}
|
||||
I2C_DEBUG(printf("w%02x",(int)data));
|
||||
return;
|
||||
}
|
||||
|
||||
static u_char iicbb_readbyte(device_t dev, int last)
|
||||
static u_char iicbb_readbyte(device_t dev, int last, int timeout)
|
||||
{
|
||||
int i;
|
||||
unsigned char data=0;
|
||||
@ -219,11 +282,15 @@ static u_char iicbb_readbyte(device_t dev, int last)
|
||||
for (i=7; i>=0; i--)
|
||||
{
|
||||
I2C_SET(dev,1,1);
|
||||
if (I2C_GET(dev))
|
||||
if (I2C_GETSDA(dev))
|
||||
data |= (1<<i);
|
||||
I2C_SET(dev,0,1);
|
||||
}
|
||||
last ? iicbb_one(dev) : iicbb_zero(dev);
|
||||
if (last) {
|
||||
iicbb_one(dev, timeout);
|
||||
} else {
|
||||
iicbb_zero(dev, timeout);
|
||||
}
|
||||
I2C_DEBUG(printf("r%02x%c ",(int)data,last?'-':'+'));
|
||||
return data;
|
||||
}
|
||||
@ -244,13 +311,12 @@ static int iicbb_start(device_t dev, u_char slave, int timeout)
|
||||
|
||||
I2C_DEBUG(printf("<"));
|
||||
|
||||
I2C_SET(dev,0,1);
|
||||
I2C_SET(dev,1,1);
|
||||
I2C_SET(dev,1,0);
|
||||
I2C_SET(dev,0,0);
|
||||
|
||||
/* send address */
|
||||
iicbb_sendbyte(dev, slave);
|
||||
iicbb_sendbyte(dev, slave, timeout);
|
||||
|
||||
/* check for ack */
|
||||
if (iicbb_ack(dev, timeout)) {
|
||||
@ -282,7 +348,7 @@ static int iicbb_write(device_t dev, char * buf, int len, int *sent,
|
||||
bytes = 0;
|
||||
while (len) {
|
||||
/* send byte */
|
||||
iicbb_sendbyte(dev,(u_char)*buf++);
|
||||
iicbb_sendbyte(dev,(u_char)*buf++, timeout);
|
||||
|
||||
/* check for ack */
|
||||
if (iicbb_ack(dev, timeout)) {
|
||||
@ -306,7 +372,7 @@ static int iicbb_read(device_t dev, char * buf, int len, int *read,
|
||||
bytes = 0;
|
||||
while (len) {
|
||||
/* XXX should insert delay here */
|
||||
*buf++ = (char)iicbb_readbyte(dev, (len == 1) ? last : 0);
|
||||
*buf++ = (char)iicbb_readbyte(dev, (len == 1) ? last : 0, delay);
|
||||
|
||||
bytes ++;
|
||||
len --;
|
||||
@ -316,5 +382,9 @@ static int iicbb_read(device_t dev, char * buf, int len, int *read,
|
||||
return (0);
|
||||
}
|
||||
|
||||
DRIVER_MODULE(iicbb, bti2c, iicbb_driver, iicbb_devclass, 0, 0);
|
||||
DRIVER_MODULE(iicbb, bktr, iicbb_driver, iicbb_devclass, 0, 0);
|
||||
DRIVER_MODULE(iicbb, lpbb, iicbb_driver, iicbb_devclass, 0, 0);
|
||||
DRIVER_MODULE(iicbb, viapm, iicbb_driver, iicbb_devclass, 0, 0);
|
||||
|
||||
MODULE_DEPEND(iicbb, iicbus, IICBUS_MINVER, IICBUS_PREFVER, IICBUS_MAXVER);
|
||||
MODULE_VERSION(iicbb, IICBB_MODVER);
|
||||
|
@ -40,19 +40,34 @@ METHOD int callback {
|
||||
};
|
||||
|
||||
#
|
||||
# Set I2C bus lines
|
||||
# Set I2C bus data line
|
||||
#
|
||||
METHOD void setlines {
|
||||
METHOD void setsda {
|
||||
device_t dev;
|
||||
int ctrl;
|
||||
int data;
|
||||
int val;
|
||||
};
|
||||
|
||||
#
|
||||
# Get I2C bus lines
|
||||
# Set I2C bus clock line
|
||||
#
|
||||
METHOD void setscl {
|
||||
device_t dev;
|
||||
int val;
|
||||
};
|
||||
|
||||
#
|
||||
# Get I2C bus data line
|
||||
#
|
||||
#
|
||||
METHOD int getdataline {
|
||||
METHOD int getsda {
|
||||
device_t dev;
|
||||
};
|
||||
|
||||
#
|
||||
# Get I2C bus clock line
|
||||
#
|
||||
#
|
||||
METHOD int getscl {
|
||||
device_t dev;
|
||||
};
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*-
|
||||
* Copyright (c) 1998 Nicolas Souchu
|
||||
* Copyright (c) 1998, 2001 Nicolas Souchu
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -45,45 +45,6 @@
|
||||
|
||||
#define DEVTOIICBUS(dev) ((struct iicbus_device*)device_get_ivars(dev))
|
||||
|
||||
/*
|
||||
* structure used to attach devices to the I2C bus
|
||||
*/
|
||||
struct iicbus_device {
|
||||
const char *iicd_name; /* device name */
|
||||
int iicd_class; /* driver or slave device class */
|
||||
const char *iicd_desc; /* device descriptor */
|
||||
u_char iicd_addr; /* address of the device */
|
||||
int iicd_waitack; /* wait for ack timeout or delay */
|
||||
int iicd_alive; /* 1 if device found */
|
||||
};
|
||||
|
||||
/*
|
||||
* Common I2C addresses
|
||||
*/
|
||||
#define I2C_GENERAL_CALL 0x0
|
||||
#define PCF_MASTER_ADDRESS 0xaa
|
||||
#define FIRST_SLAVE_ADDR 0x2
|
||||
|
||||
#define LAST_SLAVE_ADDR 255
|
||||
|
||||
#define IICBUS_UNKNOWN_CLASS 0
|
||||
#define IICBUS_DEVICE_CLASS 1
|
||||
#define IICBUS_DRIVER_CLASS 2
|
||||
|
||||
/*
|
||||
* list of known devices
|
||||
*
|
||||
* XXX only one smb driver should exist for each I2C interface
|
||||
*/
|
||||
static struct iicbus_device iicbus_children[] = {
|
||||
{ "iicsmb", IICBUS_DRIVER_CLASS, "I2C to SMB bridge" },
|
||||
{ "iic", IICBUS_DRIVER_CLASS, "I2C general purpose I/O" },
|
||||
#if 0
|
||||
{ "ic", IICBUS_DEVICE_CLASS, "network interface", PCF_MASTER_ADDRESS },
|
||||
#endif
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
static devclass_t iicbus_devclass;
|
||||
|
||||
/*
|
||||
@ -91,21 +52,19 @@ static devclass_t iicbus_devclass;
|
||||
*/
|
||||
static int iicbus_probe(device_t);
|
||||
static int iicbus_attach(device_t);
|
||||
static int iicbus_print_child(device_t, device_t);
|
||||
static int iicbus_read_ivar(device_t , device_t, int, u_long *);
|
||||
static int iicbus_write_ivar(device_t , device_t, int, u_long);
|
||||
static int iicbus_detach(device_t);
|
||||
static int iicbus_add_child(device_t dev, int order, const char *name, int unit);
|
||||
|
||||
static device_method_t iicbus_methods[] = {
|
||||
/* device interface */
|
||||
DEVMETHOD(device_probe, iicbus_probe),
|
||||
DEVMETHOD(device_attach, iicbus_attach),
|
||||
DEVMETHOD(device_detach, bus_generic_detach),
|
||||
DEVMETHOD(device_shutdown, bus_generic_shutdown),
|
||||
DEVMETHOD(device_detach, iicbus_detach),
|
||||
|
||||
/* bus interface */
|
||||
DEVMETHOD(bus_print_child, iicbus_print_child),
|
||||
DEVMETHOD(bus_read_ivar, iicbus_read_ivar),
|
||||
DEVMETHOD(bus_write_ivar, iicbus_write_ivar),
|
||||
DEVMETHOD(bus_add_child, iicbus_add_child),
|
||||
DEVMETHOD(bus_driver_added, bus_generic_driver_added),
|
||||
DEVMETHOD(bus_print_child, bus_generic_print_child),
|
||||
|
||||
{ 0, 0 }
|
||||
};
|
||||
@ -154,9 +113,6 @@ iic_probe_device(device_t dev, u_char addr)
|
||||
static int
|
||||
iicbus_attach(device_t dev)
|
||||
{
|
||||
struct iicbus_device *iicdev;
|
||||
device_t child;
|
||||
|
||||
iicbus_reset(dev, IIC_FASTEST, 0, NULL);
|
||||
|
||||
/* device probing is meaningless since the bus is supposed to be
|
||||
@ -175,42 +131,34 @@ iicbus_attach(device_t dev)
|
||||
}
|
||||
printf("\n");
|
||||
#endif
|
||||
|
||||
/* attach any known device */
|
||||
device_add_child(dev, NULL, -1);
|
||||
|
||||
/* attach known devices */
|
||||
for (iicdev = iicbus_children; iicdev->iicd_name; iicdev++) {
|
||||
switch (iicdev->iicd_class) {
|
||||
case IICBUS_DEVICE_CLASS:
|
||||
/* check if the devclass exists */
|
||||
if (devclass_find(iicdev->iicd_name))
|
||||
iicdev->iicd_alive = 1;
|
||||
else if (bootverbose)
|
||||
printf("iicbus: %s devclass not found\n",
|
||||
iicdev->iicd_name);
|
||||
break;
|
||||
|
||||
case IICBUS_DRIVER_CLASS:
|
||||
/* check if the devclass exists */
|
||||
if (devclass_find(iicdev->iicd_name))
|
||||
iicdev->iicd_alive = 1;
|
||||
else if (bootverbose)
|
||||
printf("iicbus: %s devclass not found\n",
|
||||
iicdev->iicd_name);
|
||||
break;
|
||||
|
||||
default:
|
||||
panic("%s: unknown class!", __func__);
|
||||
}
|
||||
|
||||
if (iicdev->iicd_alive) {
|
||||
child = device_add_child(dev, iicdev->iicd_name, -1);
|
||||
device_set_ivars(child, iicdev);
|
||||
device_set_desc(child, iicdev->iicd_desc);
|
||||
}
|
||||
}
|
||||
bus_generic_attach(dev);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
iicbus_detach(device_t dev)
|
||||
{
|
||||
iicbus_reset(dev, IIC_FASTEST, 0, NULL);
|
||||
|
||||
bus_generic_detach(dev);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
iicbus_add_child(device_t dev, int order, const char *name, int unit)
|
||||
{
|
||||
device_add_child_ordered(dev, order, name, unit);
|
||||
|
||||
bus_generic_attach(dev);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
iicbus_generic_intr(device_t dev, int event, char *buf)
|
||||
@ -230,59 +178,7 @@ iicbus_null_repeated_start(device_t dev, u_char addr)
|
||||
return (IIC_ENOTSUPP);
|
||||
}
|
||||
|
||||
static int
|
||||
iicbus_print_child(device_t bus, device_t dev)
|
||||
{
|
||||
struct iicbus_device* iicdev = DEVTOIICBUS(dev);
|
||||
int retval = 0;
|
||||
|
||||
retval += bus_print_child_header(bus, dev);
|
||||
|
||||
switch (iicdev->iicd_class) {
|
||||
case IICBUS_DEVICE_CLASS:
|
||||
retval += printf(" on %s addr 0x%x\n",
|
||||
device_get_nameunit(bus), iicdev->iicd_addr);
|
||||
break;
|
||||
|
||||
case IICBUS_DRIVER_CLASS:
|
||||
retval += bus_print_child_footer(bus, dev);
|
||||
break;
|
||||
|
||||
default:
|
||||
panic("%s: unknown class!", __func__);
|
||||
}
|
||||
|
||||
return (retval);
|
||||
}
|
||||
|
||||
static int
|
||||
iicbus_read_ivar(device_t bus, device_t dev, int index, u_long* result)
|
||||
{
|
||||
struct iicbus_device* iicdev = DEVTOIICBUS(dev);
|
||||
|
||||
switch (index) {
|
||||
case IICBUS_IVAR_ADDR:
|
||||
*result = (u_long)iicdev->iicd_addr;
|
||||
break;
|
||||
|
||||
default:
|
||||
return (ENOENT);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
iicbus_write_ivar(device_t bus, device_t dev, int index, u_long val)
|
||||
{
|
||||
switch (index) {
|
||||
default:
|
||||
return (ENOENT);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
DRIVER_MODULE(iicbus, pcf, iicbus_driver, iicbus_devclass, 0, 0);
|
||||
DRIVER_MODULE(iicbus, iicbb, iicbus_driver, iicbus_devclass, 0, 0);
|
||||
DRIVER_MODULE(iicbus, bti2c, iicbus_driver, iicbus_devclass, 0, 0);
|
||||
MODULE_VERSION(iicbus, IICBUS_MODVER);
|
||||
|
@ -50,22 +50,6 @@ iicbus_intr(device_t bus, int event, char *buf)
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* iicbus_alloc_bus()
|
||||
*
|
||||
* Allocate a new bus connected to the given parent device
|
||||
*/
|
||||
device_t
|
||||
iicbus_alloc_bus(device_t parent)
|
||||
{
|
||||
device_t child;
|
||||
|
||||
/* add the bus to the parent */
|
||||
child = device_add_child(parent, "iicbus", -1);
|
||||
|
||||
return (child);
|
||||
}
|
||||
|
||||
static int
|
||||
iicbus_poll(struct iicbus_softc *sc, int how)
|
||||
{
|
||||
@ -346,20 +330,3 @@ iicbus_block_read(device_t bus, u_char slave, char *buf, int len, int *read)
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
* iicbus_get_addr()
|
||||
*
|
||||
* Get the I2C 7 bits address of the device
|
||||
*/
|
||||
u_char
|
||||
iicbus_get_addr(device_t dev)
|
||||
{
|
||||
uintptr_t addr;
|
||||
device_t parent = device_get_parent(dev);
|
||||
|
||||
BUS_READ_IVAR(parent, dev, IICBUS_IVAR_ADDR, &addr);
|
||||
|
||||
return ((u_char)addr);
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*-
|
||||
* Copyright (c) 1998 Nicolas Souchu
|
||||
* Copyright (c) 1998, 2001 Nicolas Souchu
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -127,4 +127,14 @@ extern int iicbus_block_read(device_t, u_char, char *, int, int *);
|
||||
|
||||
extern u_char iicbus_get_addr(device_t);
|
||||
|
||||
#define IICBUS_MODVER 1
|
||||
#define IICBUS_MINVER 1
|
||||
#define IICBUS_MAXVER 1
|
||||
#define IICBUS_PREFVER IICBUS_MODVER
|
||||
|
||||
#define IICBB_MODVER 1
|
||||
#define IICBB_MINVER 1
|
||||
#define IICBB_MAXVER 1
|
||||
#define IICBB_PREFVER IICBB_MODVER
|
||||
|
||||
#endif
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*-
|
||||
* Copyright (c) 1998 Nicolas Souchu
|
||||
* Copyright (c) 1998, 2001 Nicolas Souchu
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -79,6 +79,8 @@ struct iicsmb_softc {
|
||||
|
||||
static int iicsmb_probe(device_t);
|
||||
static int iicsmb_attach(device_t);
|
||||
static int iicsmb_detach(device_t);
|
||||
static void iicsmb_identify(driver_t *driver, device_t parent);
|
||||
|
||||
static void iicsmb_intr(device_t dev, int event, char *buf);
|
||||
static int iicsmb_callback(device_t dev, int index, caddr_t data);
|
||||
@ -97,11 +99,13 @@ static devclass_t iicsmb_devclass;
|
||||
|
||||
static device_method_t iicsmb_methods[] = {
|
||||
/* device interface */
|
||||
DEVMETHOD(device_identify, iicsmb_identify),
|
||||
DEVMETHOD(device_probe, iicsmb_probe),
|
||||
DEVMETHOD(device_attach, iicsmb_attach),
|
||||
DEVMETHOD(device_detach, bus_generic_detach),
|
||||
DEVMETHOD(device_detach, iicsmb_detach),
|
||||
|
||||
/* bus interface */
|
||||
DEVMETHOD(bus_driver_added, bus_generic_driver_added),
|
||||
DEVMETHOD(bus_print_child, bus_generic_print_child),
|
||||
|
||||
/* iicbus interface */
|
||||
@ -129,16 +133,18 @@ static driver_t iicsmb_driver = {
|
||||
sizeof(struct iicsmb_softc),
|
||||
};
|
||||
|
||||
#define IICBUS_TIMEOUT 100 /* us */
|
||||
|
||||
static void
|
||||
iicsmb_identify(driver_t *driver, device_t parent)
|
||||
{
|
||||
BUS_ADD_CHILD(parent, 0, "iicsmb", 0);
|
||||
}
|
||||
|
||||
static int
|
||||
iicsmb_probe(device_t dev)
|
||||
{
|
||||
struct iicsmb_softc *sc = (struct iicsmb_softc *)device_get_softc(dev);
|
||||
|
||||
sc->smbus = smbus_alloc_bus(dev);
|
||||
|
||||
if (!sc->smbus)
|
||||
return (EINVAL); /* XXX don't know what to return else */
|
||||
|
||||
device_set_desc(dev, "SMBus over I2C bridge");
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -147,8 +153,25 @@ iicsmb_attach(device_t dev)
|
||||
{
|
||||
struct iicsmb_softc *sc = (struct iicsmb_softc *)device_get_softc(dev);
|
||||
|
||||
bzero(sc, sizeof(*sc));
|
||||
|
||||
sc->smbus = device_add_child(dev, "smbus", -1);
|
||||
|
||||
/* probe and attach the smbus */
|
||||
device_probe_and_attach(sc->smbus);
|
||||
bus_generic_attach(dev);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
iicsmb_detach(device_t dev)
|
||||
{
|
||||
struct iicsmb_softc *sc = (struct iicsmb_softc *)device_get_softc(dev);
|
||||
|
||||
bus_generic_detach(dev);
|
||||
if (sc->smbus) {
|
||||
device_delete_child(dev, sc->smbus);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
@ -259,11 +282,11 @@ iicsmb_quick(device_t dev, u_char slave, int how)
|
||||
|
||||
switch (how) {
|
||||
case SMB_QWRITE:
|
||||
error = iicbus_start(parent, slave & ~LSB, 0);
|
||||
error = iicbus_start(parent, slave & ~LSB, IICBUS_TIMEOUT);
|
||||
break;
|
||||
|
||||
case SMB_QREAD:
|
||||
error = iicbus_start(parent, slave | LSB, 0);
|
||||
error = iicbus_start(parent, slave | LSB, IICBUS_TIMEOUT);
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -283,10 +306,10 @@ iicsmb_sendb(device_t dev, u_char slave, char byte)
|
||||
device_t parent = device_get_parent(dev);
|
||||
int error, sent;
|
||||
|
||||
error = iicbus_start(parent, slave & ~LSB, 0);
|
||||
error = iicbus_start(parent, slave & ~LSB, IICBUS_TIMEOUT);
|
||||
|
||||
if (!error) {
|
||||
error = iicbus_write(parent, &byte, 1, &sent, 0);
|
||||
error = iicbus_write(parent, &byte, 1, &sent, IICBUS_TIMEOUT);
|
||||
|
||||
iicbus_stop(parent);
|
||||
}
|
||||
@ -303,7 +326,7 @@ iicsmb_recvb(device_t dev, u_char slave, char *byte)
|
||||
error = iicbus_start(parent, slave | LSB, 0);
|
||||
|
||||
if (!error) {
|
||||
error = iicbus_read(parent, byte, 1, &read, IIC_LAST_READ, 0);
|
||||
error = iicbus_read(parent, byte, 1, &read, IIC_LAST_READ, IICBUS_TIMEOUT);
|
||||
|
||||
iicbus_stop(parent);
|
||||
}
|
||||
@ -320,8 +343,8 @@ iicsmb_writeb(device_t dev, u_char slave, char cmd, char byte)
|
||||
error = iicbus_start(parent, slave & ~LSB, 0);
|
||||
|
||||
if (!error) {
|
||||
if (!(error = iicbus_write(parent, &cmd, 1, &sent, 0)))
|
||||
error = iicbus_write(parent, &byte, 1, &sent, 0);
|
||||
if (!(error = iicbus_write(parent, &cmd, 1, &sent, IICBUS_TIMEOUT)))
|
||||
error = iicbus_write(parent, &byte, 1, &sent, IICBUS_TIMEOUT);
|
||||
|
||||
iicbus_stop(parent);
|
||||
}
|
||||
@ -341,9 +364,9 @@ iicsmb_writew(device_t dev, u_char slave, char cmd, short word)
|
||||
error = iicbus_start(parent, slave & ~LSB, 0);
|
||||
|
||||
if (!error) {
|
||||
if (!(error = iicbus_write(parent, &cmd, 1, &sent, 0)))
|
||||
if (!(error = iicbus_write(parent, &low, 1, &sent, 0)))
|
||||
error = iicbus_write(parent, &high, 1, &sent, 0);
|
||||
if (!(error = iicbus_write(parent, &cmd, 1, &sent, IICBUS_TIMEOUT)))
|
||||
if (!(error = iicbus_write(parent, &low, 1, &sent, IICBUS_TIMEOUT)))
|
||||
error = iicbus_write(parent, &high, 1, &sent, IICBUS_TIMEOUT);
|
||||
|
||||
iicbus_stop(parent);
|
||||
}
|
||||
@ -357,16 +380,16 @@ iicsmb_readb(device_t dev, u_char slave, char cmd, char *byte)
|
||||
device_t parent = device_get_parent(dev);
|
||||
int error, sent, read;
|
||||
|
||||
if ((error = iicbus_start(parent, slave & ~LSB, 0)))
|
||||
if ((error = iicbus_start(parent, slave & ~LSB, IICBUS_TIMEOUT)))
|
||||
return (error);
|
||||
|
||||
if ((error = iicbus_write(parent, &cmd, 1, &sent, 0)))
|
||||
if ((error = iicbus_write(parent, &cmd, 1, &sent, IICBUS_TIMEOUT)))
|
||||
goto error;
|
||||
|
||||
if ((error = iicbus_repeated_start(parent, slave | LSB, 0)))
|
||||
if ((error = iicbus_repeated_start(parent, slave | LSB, IICBUS_TIMEOUT)))
|
||||
goto error;
|
||||
|
||||
if ((error = iicbus_read(parent, byte, 1, &read, IIC_LAST_READ, 0)))
|
||||
if ((error = iicbus_read(parent, byte, 1, &read, IIC_LAST_READ, IICBUS_TIMEOUT)))
|
||||
goto error;
|
||||
|
||||
error:
|
||||
@ -384,16 +407,16 @@ iicsmb_readw(device_t dev, u_char slave, char cmd, short *word)
|
||||
int error, sent, read;
|
||||
char buf[2];
|
||||
|
||||
if ((error = iicbus_start(parent, slave & ~LSB, 0)))
|
||||
if ((error = iicbus_start(parent, slave & ~LSB, IICBUS_TIMEOUT)))
|
||||
return (error);
|
||||
|
||||
if ((error = iicbus_write(parent, &cmd, 1, &sent, 0)))
|
||||
if ((error = iicbus_write(parent, &cmd, 1, &sent, IICBUS_TIMEOUT)))
|
||||
goto error;
|
||||
|
||||
if ((error = iicbus_repeated_start(parent, slave | LSB, 0)))
|
||||
if ((error = iicbus_repeated_start(parent, slave | LSB, IICBUS_TIMEOUT)))
|
||||
goto error;
|
||||
|
||||
if ((error = iicbus_read(parent, buf, 2, &read, IIC_LAST_READ, 0)))
|
||||
if ((error = iicbus_read(parent, buf, 2, &read, IIC_LAST_READ, IICBUS_TIMEOUT)))
|
||||
goto error;
|
||||
|
||||
/* first, receive low, then high byte */
|
||||
@ -411,23 +434,23 @@ iicsmb_pcall(device_t dev, u_char slave, char cmd, short sdata, short *rdata)
|
||||
int error, sent, read;
|
||||
char buf[2];
|
||||
|
||||
if ((error = iicbus_start(parent, slave & ~LSB, 0)))
|
||||
if ((error = iicbus_start(parent, slave & ~LSB, IICBUS_TIMEOUT)))
|
||||
return (error);
|
||||
|
||||
if ((error = iicbus_write(parent, &cmd, 1, &sent, 0)))
|
||||
if ((error = iicbus_write(parent, &cmd, 1, &sent, IICBUS_TIMEOUT)))
|
||||
goto error;
|
||||
|
||||
/* first, send low, then high byte */
|
||||
buf[0] = (char)(sdata & 0xff);
|
||||
buf[1] = (char)((sdata & 0xff00) >> 8);
|
||||
|
||||
if ((error = iicbus_write(parent, buf, 2, &sent, 0)))
|
||||
if ((error = iicbus_write(parent, buf, 2, &sent, IICBUS_TIMEOUT)))
|
||||
goto error;
|
||||
|
||||
if ((error = iicbus_repeated_start(parent, slave | LSB, 0)))
|
||||
if ((error = iicbus_repeated_start(parent, slave | LSB, IICBUS_TIMEOUT)))
|
||||
goto error;
|
||||
|
||||
if ((error = iicbus_read(parent, buf, 2, &read, IIC_LAST_READ, 0)))
|
||||
if ((error = iicbus_read(parent, buf, 2, &read, IIC_LAST_READ, IICBUS_TIMEOUT)))
|
||||
goto error;
|
||||
|
||||
/* first, receive low, then high byte */
|
||||
@ -444,13 +467,13 @@ iicsmb_bwrite(device_t dev, u_char slave, char cmd, u_char count, char *buf)
|
||||
device_t parent = device_get_parent(dev);
|
||||
int error, sent;
|
||||
|
||||
if ((error = iicbus_start(parent, slave & ~LSB, 0)))
|
||||
if ((error = iicbus_start(parent, slave & ~LSB, IICBUS_TIMEOUT)))
|
||||
goto error;
|
||||
|
||||
if ((error = iicbus_write(parent, &cmd, 1, &sent, 0)))
|
||||
if ((error = iicbus_write(parent, &cmd, 1, &sent, IICBUS_TIMEOUT)))
|
||||
goto error;
|
||||
|
||||
if ((error = iicbus_write(parent, buf, (int)count, &sent, 0)))
|
||||
if ((error = iicbus_write(parent, buf, (int)count, &sent, IICBUS_TIMEOUT)))
|
||||
goto error;
|
||||
|
||||
if ((error = iicbus_stop(parent)))
|
||||
@ -466,17 +489,17 @@ iicsmb_bread(device_t dev, u_char slave, char cmd, u_char count, char *buf)
|
||||
device_t parent = device_get_parent(dev);
|
||||
int error, sent, read;
|
||||
|
||||
if ((error = iicbus_start(parent, slave & ~LSB, 0)))
|
||||
if ((error = iicbus_start(parent, slave & ~LSB, IICBUS_TIMEOUT)))
|
||||
return (error);
|
||||
|
||||
if ((error = iicbus_write(parent, &cmd, 1, &sent, 0)))
|
||||
if ((error = iicbus_write(parent, &cmd, 1, &sent, IICBUS_TIMEOUT)))
|
||||
goto error;
|
||||
|
||||
if ((error = iicbus_repeated_start(parent, slave | LSB, 0)))
|
||||
if ((error = iicbus_repeated_start(parent, slave | LSB, IICBUS_TIMEOUT)))
|
||||
goto error;
|
||||
|
||||
if ((error = iicbus_read(parent, buf, (int)count, &read,
|
||||
IIC_LAST_READ, 0)))
|
||||
IIC_LAST_READ, IICBUS_TIMEOUT)))
|
||||
goto error;
|
||||
|
||||
error:
|
||||
@ -485,3 +508,6 @@ error:
|
||||
}
|
||||
|
||||
DRIVER_MODULE(iicsmb, iicbus, iicsmb_driver, iicsmb_devclass, 0, 0);
|
||||
MODULE_DEPEND(iicsmb, iicbus, IICBUS_MINVER, IICBUS_PREFVER, IICBUS_MAXVER);
|
||||
MODULE_DEPEND(iicsmb, smbus, SMBUS_MINVER, SMBUS_PREFVER, SMBUS_MAXVER);
|
||||
MODULE_VERSION(iicsmb, 1);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*-
|
||||
* Copyright (c) 1998 Nicolas Souchu, Marc Bouget
|
||||
* Copyright (c) 1998, 2001 Nicolas Souchu, Marc Bouget
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -75,19 +75,12 @@ lpbb_probe(device_t dev)
|
||||
static int
|
||||
lpbb_attach(device_t dev)
|
||||
{
|
||||
device_t bitbang, iicbus;
|
||||
device_t bitbang;
|
||||
|
||||
/* add generic bit-banging code */
|
||||
bitbang = device_add_child(dev, "iicbb", -1);
|
||||
|
||||
/* add the iicbus to the tree */
|
||||
iicbus = iicbus_alloc_bus(bitbang);
|
||||
|
||||
device_probe_and_attach(bitbang);
|
||||
|
||||
/* XXX should be in iicbb_attach! */
|
||||
device_probe_and_attach(iicbus);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -124,24 +117,30 @@ lpbb_callback(device_t dev, int index, caddr_t *data)
|
||||
#define ALIM 0x20
|
||||
#define I2CKEY 0x50
|
||||
|
||||
static int getSDA(device_t ppbus)
|
||||
static int lpbb_getscl(device_t dev)
|
||||
{
|
||||
if((ppb_rstr(ppbus)&SDA_in)==SDA_in)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
return ((ppb_rstr(device_get_parent(dev)) & SCL_in) == SCL_in);
|
||||
}
|
||||
|
||||
static void setSDA(device_t ppbus, char val)
|
||||
static int lpbb_getsda(device_t dev)
|
||||
{
|
||||
return ((ppb_rstr(device_get_parent(dev)) & SDA_in) == SDA_in);
|
||||
}
|
||||
|
||||
static void lpbb_setsda(device_t dev, char val)
|
||||
{
|
||||
device_t ppbus = device_get_parent(dev);
|
||||
|
||||
if(val==0)
|
||||
ppb_wdtr(ppbus, (u_char)SDA_out);
|
||||
else
|
||||
ppb_wdtr(ppbus, (u_char)~SDA_out);
|
||||
}
|
||||
|
||||
static void setSCL(device_t ppbus, unsigned char val)
|
||||
static void lpbb_setscl(device_t dev, unsigned char val)
|
||||
{
|
||||
device_t ppbus = device_get_parent(dev);
|
||||
|
||||
if(val==0)
|
||||
ppb_wctr(ppbus, (u_char)(ppb_rctr(ppbus)&~SCL_out));
|
||||
else
|
||||
@ -158,8 +157,8 @@ static int lpbb_detect(device_t dev)
|
||||
}
|
||||
|
||||
/* reset bus */
|
||||
setSDA(ppbus, 1);
|
||||
setSCL(ppbus, 1);
|
||||
lpbb_setsda(dev, 1);
|
||||
lpbb_setscl(dev, 1);
|
||||
|
||||
if ((ppb_rstr(ppbus) & I2CKEY) ||
|
||||
((ppb_rstr(ppbus) & ALIM) != ALIM)) {
|
||||
@ -178,30 +177,20 @@ lpbb_reset(device_t dev, u_char speed, u_char addr, u_char * oldaddr)
|
||||
{
|
||||
device_t ppbus = device_get_parent(dev);
|
||||
|
||||
if (ppb_request_bus(ppbus, dev, PPB_DONTWAIT)) {
|
||||
device_printf(dev, "can't allocate ppbus\n");
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* reset bus */
|
||||
setSDA(ppbus, 1);
|
||||
setSCL(ppbus, 1);
|
||||
lpbb_setsda(dev, 1);
|
||||
lpbb_setscl(dev, 1);
|
||||
|
||||
ppb_release_bus(ppbus, dev);
|
||||
|
||||
return (IIC_ENOADDR);
|
||||
}
|
||||
|
||||
static void
|
||||
lpbb_setlines(device_t dev, int ctrl, int data)
|
||||
{
|
||||
device_t ppbus = device_get_parent(dev);
|
||||
|
||||
setSCL(ppbus, ctrl);
|
||||
setSDA(ppbus, data);
|
||||
}
|
||||
|
||||
static int
|
||||
lpbb_getdataline(device_t dev)
|
||||
{
|
||||
device_t ppbus = device_get_parent(dev);
|
||||
|
||||
return (getSDA(ppbus));
|
||||
}
|
||||
|
||||
static devclass_t lpbb_devclass;
|
||||
|
||||
static device_method_t lpbb_methods[] = {
|
||||
@ -215,8 +204,10 @@ static device_method_t lpbb_methods[] = {
|
||||
|
||||
/* iicbb interface */
|
||||
DEVMETHOD(iicbb_callback, lpbb_callback),
|
||||
DEVMETHOD(iicbb_setlines, lpbb_setlines),
|
||||
DEVMETHOD(iicbb_getdataline, lpbb_getdataline),
|
||||
DEVMETHOD(iicbb_setsda, lpbb_setsda),
|
||||
DEVMETHOD(iicbb_setscl, lpbb_setscl),
|
||||
DEVMETHOD(iicbb_getsda, lpbb_getsda),
|
||||
DEVMETHOD(iicbb_getscl, lpbb_getscl),
|
||||
DEVMETHOD(iicbb_reset, lpbb_reset),
|
||||
|
||||
{ 0, 0 }
|
||||
@ -229,3 +220,5 @@ static driver_t lpbb_driver = {
|
||||
};
|
||||
|
||||
DRIVER_MODULE(lpbb, ppbus, lpbb_driver, lpbb_devclass, 0, 0);
|
||||
MODULE_DEPEND(lpbb, iicbb, IICBB_MINVER, IICBB_PREFVER, IICBB_MAXVER);
|
||||
MODULE_VERSION(lpbb, 1);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*-
|
||||
* Copyright (c) 1998 Nicolas Souchu
|
||||
* Copyright (c) 1998, 2001 Nicolas Souchu
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -46,13 +46,8 @@
|
||||
|
||||
struct smb_softc {
|
||||
|
||||
int sc_addr; /* address on smbus */
|
||||
int sc_count; /* >0 if device opened */
|
||||
|
||||
char *sc_cp; /* output buffer pointer */
|
||||
|
||||
char sc_buffer[BUFSIZE]; /* output buffer */
|
||||
char sc_inbuf[BUFSIZE]; /* input buffer */
|
||||
dev_t sc_devnode;
|
||||
};
|
||||
|
||||
#define IIC_SOFTC(unit) \
|
||||
@ -63,13 +58,17 @@ struct smb_softc {
|
||||
|
||||
static int smb_probe(device_t);
|
||||
static int smb_attach(device_t);
|
||||
static int smb_detach(device_t);
|
||||
static void smb_identify(driver_t *driver, device_t parent);
|
||||
|
||||
static devclass_t smb_devclass;
|
||||
|
||||
static device_method_t smb_methods[] = {
|
||||
/* device interface */
|
||||
DEVMETHOD(device_identify, smb_identify),
|
||||
DEVMETHOD(device_probe, smb_probe),
|
||||
DEVMETHOD(device_attach, smb_attach),
|
||||
DEVMETHOD(device_detach, smb_detach),
|
||||
|
||||
/* smbus interface */
|
||||
DEVMETHOD(smbus_intr, smbus_generic_intr),
|
||||
@ -106,30 +105,45 @@ static struct cdevsw smb_cdevsw = {
|
||||
/* flags */ 0,
|
||||
};
|
||||
|
||||
/*
|
||||
* smbprobe()
|
||||
*/
|
||||
static void
|
||||
smb_identify(driver_t *driver, device_t parent)
|
||||
{
|
||||
BUS_ADD_CHILD(parent, 0, "smb", 0);
|
||||
}
|
||||
|
||||
static int
|
||||
smb_probe(device_t dev)
|
||||
{
|
||||
struct smb_softc *sc = (struct smb_softc *)device_get_softc(dev);
|
||||
|
||||
sc->sc_addr = smbus_get_addr(dev);
|
||||
|
||||
/* XXX detect chip with start/stop conditions */
|
||||
device_set_desc(dev, "SMBus generic I/O");
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* smbattach()
|
||||
*/
|
||||
static int
|
||||
smb_attach(device_t dev)
|
||||
{
|
||||
make_dev(&smb_cdevsw, device_get_unit(dev), /* XXX cleanup */
|
||||
struct smb_softc *sc = (struct smb_softc *)device_get_softc(dev);
|
||||
|
||||
if (!sc)
|
||||
return (ENOMEM);
|
||||
|
||||
bzero(sc, sizeof(struct smb_softc *));
|
||||
|
||||
sc->sc_devnode = make_dev(&smb_cdevsw, device_get_unit(dev),
|
||||
UID_ROOT, GID_WHEEL,
|
||||
0600, "smb%d", device_get_unit(dev));
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
smb_detach(device_t dev)
|
||||
{
|
||||
struct smb_softc *sc = (struct smb_softc *)device_get_softc(dev);
|
||||
|
||||
if (sc->sc_devnode)
|
||||
destroy_dev(sc->sc_devnode);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -267,3 +281,5 @@ smbioctl(dev_t dev, u_long cmd, caddr_t data, int flags, struct thread *td)
|
||||
}
|
||||
|
||||
DRIVER_MODULE(smb, smbus, smb_driver, smb_devclass, 0, 0);
|
||||
MODULE_DEPEND(smb, smbus, SMBUS_MINVER, SMBUS_PREFVER, SMBUS_MAXVER);
|
||||
MODULE_VERSION(smb, 1);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*-
|
||||
* Copyright (c) 1998 Nicolas Souchu
|
||||
* Copyright (c) 1998, 2001 Nicolas Souchu
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -78,22 +78,6 @@ smbus_error(int smb_error)
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
* smbus_alloc_bus()
|
||||
*
|
||||
* Allocate a new bus connected to the given parent device
|
||||
*/
|
||||
device_t
|
||||
smbus_alloc_bus(device_t parent)
|
||||
{
|
||||
device_t child;
|
||||
|
||||
/* add the bus to the parent */
|
||||
child = device_add_child(parent, "smbus", -1);
|
||||
|
||||
return (child);
|
||||
}
|
||||
|
||||
static int
|
||||
smbus_poll(struct smbus_softc *sc, int how)
|
||||
{
|
||||
@ -190,19 +174,3 @@ smbus_release_bus(device_t bus, device_t dev)
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* smbus_get_addr()
|
||||
*
|
||||
* Get the I2C 7 bits address of the device
|
||||
*/
|
||||
u_char
|
||||
smbus_get_addr(device_t dev)
|
||||
{
|
||||
uintptr_t addr;
|
||||
device_t parent = device_get_parent(dev);
|
||||
|
||||
BUS_READ_IVAR(parent, dev, SMBUS_IVAR_ADDR, &addr);
|
||||
|
||||
return ((u_char)addr);
|
||||
}
|
||||
|
@ -101,4 +101,9 @@ extern u_char smbus_get_addr(device_t);
|
||||
#define smbus_bread(bus,slave,cmd,count,buf) \
|
||||
(SMBUS_BREAD(device_get_parent(bus), slave, cmd, count, buf))
|
||||
|
||||
#define SMBUS_MODVER 1
|
||||
#define SMBUS_MINVER 1
|
||||
#define SMBUS_MAXVER 1
|
||||
#define SMBUS_PREFVER SMBUS_MODVER
|
||||
|
||||
#endif
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*-
|
||||
* Copyright (c) 1998 Nicolas Souchu
|
||||
* Copyright (c) 1998, 2001 Nicolas Souchu
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -41,22 +41,6 @@
|
||||
|
||||
#define DEVTOSMBUS(dev) ((struct smbus_device*)device_get_ivars(dev))
|
||||
|
||||
/*
|
||||
* structure used to attach devices to the I2C bus
|
||||
*/
|
||||
struct smbus_device {
|
||||
const char *smbd_name; /* device name */
|
||||
const char *smbd_desc; /* device descriptor */
|
||||
};
|
||||
|
||||
/*
|
||||
* list of known devices
|
||||
*/
|
||||
struct smbus_device smbus_children[] = {
|
||||
{ "smb", "SMBus general purpose I/O" },
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
static devclass_t smbus_devclass;
|
||||
|
||||
/*
|
||||
@ -64,22 +48,17 @@ static devclass_t smbus_devclass;
|
||||
*/
|
||||
static int smbus_probe(device_t);
|
||||
static int smbus_attach(device_t);
|
||||
|
||||
#if 0
|
||||
static int smbus_read_ivar(device_t , device_t, int, u_long *);
|
||||
#endif
|
||||
static int smbus_add_child(device_t dev, int order, const char *name, int unit);
|
||||
|
||||
static device_method_t smbus_methods[] = {
|
||||
/* device interface */
|
||||
DEVMETHOD(device_probe, smbus_probe),
|
||||
DEVMETHOD(device_attach, smbus_attach),
|
||||
DEVMETHOD(device_detach, bus_generic_detach),
|
||||
DEVMETHOD(device_shutdown, bus_generic_shutdown),
|
||||
|
||||
/* bus interface */
|
||||
DEVMETHOD(bus_add_child, smbus_add_child),
|
||||
DEVMETHOD(bus_print_child, bus_generic_print_child),
|
||||
DEVMETHOD(bus_read_ivar, bus_generic_read_ivar),
|
||||
DEVMETHOD(bus_write_ivar, bus_generic_write_ivar),
|
||||
|
||||
{ 0, 0 }
|
||||
};
|
||||
@ -106,48 +85,33 @@ smbus_probe(device_t dev)
|
||||
static int
|
||||
smbus_attach(device_t dev)
|
||||
{
|
||||
struct smbus_device *smbdev;
|
||||
|
||||
/* add known devices */
|
||||
for (smbdev = smbus_children; smbdev->smbd_name; smbdev++) {
|
||||
device_t child;
|
||||
|
||||
if (devclass_find(smbdev->smbd_name)) {
|
||||
child = device_add_child(dev, smbdev->smbd_name, -1);
|
||||
device_set_ivars(child, smbdev);
|
||||
device_set_desc(child, smbdev->smbd_desc);
|
||||
} else if (bootverbose)
|
||||
printf("smbus: %s devclass not found\n",
|
||||
smbdev->smbd_name);
|
||||
}
|
||||
device_add_child(dev, NULL, -1);
|
||||
bus_generic_attach(dev);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
smbus_add_child(device_t dev, int order, const char *name, int unit)
|
||||
{
|
||||
device_add_child_ordered(dev, order, name, unit);
|
||||
|
||||
bus_generic_attach(dev);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
smbus_generic_intr(device_t dev, u_char devaddr, char low, char high)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static int
|
||||
smbus_read_ivar(device_t bus, device_t dev, int index, u_long* result)
|
||||
{
|
||||
struct smbus_device* smbdev = DEVTOSMBUS(dev);
|
||||
|
||||
switch (index) {
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return (ENOENT);
|
||||
}
|
||||
#endif
|
||||
|
||||
DRIVER_MODULE(smbus, iicsmb, smbus_driver, smbus_devclass, 0, 0);
|
||||
DRIVER_MODULE(smbus, bti2c, smbus_driver, smbus_devclass, 0, 0);
|
||||
DRIVER_MODULE(smbus, bktr, smbus_driver, smbus_devclass, 0, 0);
|
||||
DRIVER_MODULE(smbus, intsmb, smbus_driver, smbus_devclass, 0, 0);
|
||||
DRIVER_MODULE(smbus, alsmb, smbus_driver, smbus_devclass, 0, 0);
|
||||
DRIVER_MODULE(smbus, alpm, smbus_driver, smbus_devclass, 0, 0);
|
||||
DRIVER_MODULE(smbus, ichsmb, smbus_driver, smbus_devclass, 0, 0);
|
||||
DRIVER_MODULE(smbus, amdsmb, smbus_driver, smbus_devclass, 0, 0);
|
||||
DRIVER_MODULE(smbus, amdpm, smbus_driver, smbus_devclass, 0, 0);
|
||||
DRIVER_MODULE(smbus, viapropm, smbus_driver, smbus_devclass, 0, 0);
|
||||
MODULE_VERSION(smbus, SMBUS_MODVER);
|
||||
|
@ -2378,11 +2378,16 @@ device nmdm
|
||||
|
||||
device meteor 1
|
||||
|
||||
#
|
||||
# options BKTR_USE_FREEBSD_SMBUS
|
||||
# Compile with FreeBSD SMBus implementation
|
||||
#
|
||||
# Brooktree driver has been ported to the new I2C framework. Thus,
|
||||
# you'll need to have the following 3 lines in the kernel config.
|
||||
# device smbus
|
||||
# device iicbus
|
||||
# device iicbb
|
||||
# device iicsmb
|
||||
# The iic and smb devices are only needed if you want to control other
|
||||
# I2C slaves connected to the external connector of some cards.
|
||||
#
|
||||
|
@ -493,6 +493,19 @@ DRIVER_MODULE(pcib, nexus, nexus_pcib_driver, pcib_devclass, 0, 0);
|
||||
static int
|
||||
pci_hostb_probe(device_t dev)
|
||||
{
|
||||
u_int32_t id;
|
||||
|
||||
id = pci_get_devid(dev);
|
||||
|
||||
switch (id) {
|
||||
|
||||
/* VIA VT82C596 Power Managment Function */
|
||||
case 0x30501106:
|
||||
return ENXIO;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (pci_get_class(dev) == PCIC_BRIDGE &&
|
||||
pci_get_subclass(dev) == PCIS_BRIDGE_HOST) {
|
||||
|
@ -8,15 +8,10 @@ KMOD= bktr
|
||||
SRCS= bktr_core.c bktr_os.c bktr_audio.c bktr_tuner.c bktr_card.c \
|
||||
bktr.h opt_devfs.h opt_bktr.h smbus.h bus_if.h device_if.h \
|
||||
pci_if.h vnode_if.h
|
||||
CLEANFILES= bktr.h smbus.h
|
||||
CLEANFILES= bktr.h
|
||||
|
||||
bktr.h:
|
||||
echo "#define NBKTR 1" > bktr.h
|
||||
echo "#define BKTR_FREEBSD_MODULE 1" >> bktr.h
|
||||
|
||||
# Does not use SMBUS/IICBUS. Uses the old i2c code self contained in
|
||||
# the bt848 driver.
|
||||
smbus.h:
|
||||
echo "#define NSMBUS 0" > smbus.h
|
||||
|
||||
.include <bsd.kmod.mk>
|
||||
|
6
sys/modules/i2c/Makefile
Normal file
6
sys/modules/i2c/Makefile
Normal file
@ -0,0 +1,6 @@
|
||||
# $FreeBSD$
|
||||
|
||||
SUBDIR =
|
||||
SUBDIR += controllers if_ic smbus iicbus iicbb iicsmb iic smb
|
||||
|
||||
.include <bsd.subdir.mk>
|
5
sys/modules/i2c/controllers/Makefile
Normal file
5
sys/modules/i2c/controllers/Makefile
Normal file
@ -0,0 +1,5 @@
|
||||
# $FreeBSD$
|
||||
|
||||
SUBDIR = alpm intpm viapm lpbb pcf
|
||||
|
||||
.include <bsd.subdir.mk>
|
9
sys/modules/i2c/controllers/alpm/Makefile
Normal file
9
sys/modules/i2c/controllers/alpm/Makefile
Normal file
@ -0,0 +1,9 @@
|
||||
# $FreeBSD$
|
||||
|
||||
.PATH: ${.CURDIR}/../../../../pci
|
||||
KMOD = alpm
|
||||
CFLAGS += -DALPM_SMBIO_BASE_ADDR=0xbc00
|
||||
SRCS = device_if.h bus_if.h iicbus_if.h smbus_if.h pci_if.h \
|
||||
alpm.c
|
||||
|
||||
.include <bsd.kmod.mk>
|
8
sys/modules/i2c/controllers/amdpm/Makefile
Normal file
8
sys/modules/i2c/controllers/amdpm/Makefile
Normal file
@ -0,0 +1,8 @@
|
||||
# $FreeBSD$
|
||||
|
||||
.PATH: ${.CURDIR}/../../../../pci
|
||||
KMOD = amdpm
|
||||
SRCS = device_if.h bus_if.h pci_if.h smbus_if.h \
|
||||
amdpm.c
|
||||
|
||||
.include <bsd.kmod.mk>
|
8
sys/modules/i2c/controllers/intpm/Makefile
Normal file
8
sys/modules/i2c/controllers/intpm/Makefile
Normal file
@ -0,0 +1,8 @@
|
||||
# $FreeBSD$
|
||||
|
||||
.PATH: ${.CURDIR}/../../../../pci
|
||||
KMOD = intpm
|
||||
SRCS = device_if.h bus_if.h iicbus_if.h smbus_if.h pci_if.h \
|
||||
opt_intpm.h intpmreg.h intpm.c
|
||||
|
||||
.include <bsd.kmod.mk>
|
8
sys/modules/i2c/controllers/lpbb/Makefile
Normal file
8
sys/modules/i2c/controllers/lpbb/Makefile
Normal file
@ -0,0 +1,8 @@
|
||||
# $FreeBSD$
|
||||
|
||||
.PATH: ${.CURDIR}/../../../../dev/ppbus
|
||||
KMOD = pcf
|
||||
SRCS = device_if.h bus_if.h iicbb_if.h ppbus_if.h \
|
||||
lpbb.c
|
||||
|
||||
.include <bsd.kmod.mk>
|
8
sys/modules/i2c/controllers/pcf/Makefile
Normal file
8
sys/modules/i2c/controllers/pcf/Makefile
Normal file
@ -0,0 +1,8 @@
|
||||
# $FreeBSD$
|
||||
|
||||
.PATH: ${.CURDIR}/../../../../i386/isa
|
||||
KMOD = pcf
|
||||
SRCS = device_if.h bus_if.h iicbus_if.h isa_if.h \
|
||||
opt_compat_oldisa.h pcf.c
|
||||
|
||||
.include <bsd.kmod.mk>
|
9
sys/modules/i2c/controllers/viapm/Makefile
Normal file
9
sys/modules/i2c/controllers/viapm/Makefile
Normal file
@ -0,0 +1,9 @@
|
||||
# $FreeBSD$
|
||||
|
||||
.PATH: ${.CURDIR}/../../../../pci
|
||||
KMOD = viapm
|
||||
SRCS = device_if.h bus_if.h iicbb_if.h pci_if.h smbus_if.h \
|
||||
viapm.c
|
||||
CFLAGS += -DVIAPM_BASE_ADDR=0x6000
|
||||
|
||||
.include <bsd.kmod.mk>
|
8
sys/modules/i2c/if_ic/Makefile
Normal file
8
sys/modules/i2c/if_ic/Makefile
Normal file
@ -0,0 +1,8 @@
|
||||
# $FreeBSD$
|
||||
|
||||
.PATH: ${.CURDIR}/../../../dev/iicbus
|
||||
KMOD = if_ic
|
||||
SRCS = device_if.h bus_if.h iicbus_if.h \
|
||||
if_ic.c
|
||||
|
||||
.include <bsd.kmod.mk>
|
8
sys/modules/i2c/iic/Makefile
Normal file
8
sys/modules/i2c/iic/Makefile
Normal file
@ -0,0 +1,8 @@
|
||||
# $FreeBSD$
|
||||
|
||||
.PATH: ${.CURDIR}/../../../dev/iicbus
|
||||
KMOD = iic
|
||||
SRCS = device_if.h bus_if.h iicbus_if.h \
|
||||
iic.c
|
||||
|
||||
.include <bsd.kmod.mk>
|
8
sys/modules/i2c/iicbb/Makefile
Normal file
8
sys/modules/i2c/iicbb/Makefile
Normal file
@ -0,0 +1,8 @@
|
||||
# $FreeBSD$
|
||||
|
||||
.PATH: ${.CURDIR}/../../../dev/iicbus
|
||||
KMOD = iicbb
|
||||
SRCS = device_if.h bus_if.h iicbus_if.h \
|
||||
iicbb_if.h iicbb_if.c iicbb.c
|
||||
|
||||
.include <bsd.kmod.mk>
|
8
sys/modules/i2c/iicbus/Makefile
Normal file
8
sys/modules/i2c/iicbus/Makefile
Normal file
@ -0,0 +1,8 @@
|
||||
# $FreeBSD$
|
||||
|
||||
.PATH: ${.CURDIR}/../../../dev/iicbus
|
||||
KMOD = iicbus
|
||||
SRCS = device_if.h bus_if.h iicbus_if.h iicbus_if.c \
|
||||
iiconf.h iiconf.c iicbus.h iicbus.c
|
||||
|
||||
.include <bsd.kmod.mk>
|
8
sys/modules/i2c/iicsmb/Makefile
Normal file
8
sys/modules/i2c/iicsmb/Makefile
Normal file
@ -0,0 +1,8 @@
|
||||
# $FreeBSD$
|
||||
|
||||
.PATH: ${.CURDIR}/../../../dev/iicbus
|
||||
KMOD = iicsmb
|
||||
SRCS = device_if.h bus_if.h iicbus_if.h \
|
||||
smbus_if.h iicsmb.c
|
||||
|
||||
.include <bsd.kmod.mk>
|
8
sys/modules/i2c/smb/Makefile
Normal file
8
sys/modules/i2c/smb/Makefile
Normal file
@ -0,0 +1,8 @@
|
||||
# $FreeBSD$
|
||||
|
||||
.PATH: ${.CURDIR}/../../../dev/smbus
|
||||
KMOD = smb
|
||||
SRCS = device_if.h bus_if.h smbus_if.h \
|
||||
smb.c
|
||||
|
||||
.include <bsd.kmod.mk>
|
8
sys/modules/i2c/smbus/Makefile
Normal file
8
sys/modules/i2c/smbus/Makefile
Normal file
@ -0,0 +1,8 @@
|
||||
# $FreeBSD$
|
||||
|
||||
.PATH: ${.CURDIR}/../../../dev/smbus
|
||||
KMOD = smbus
|
||||
SRCS = device_if.h bus_if.h smbus_if.h smbus_if.c \
|
||||
smbconf.h smbconf.c smbus.h smbus.c
|
||||
|
||||
.include <bsd.kmod.mk>
|
335
sys/pci/alpm.c
335
sys/pci/alpm.c
@ -37,7 +37,6 @@
|
||||
#include <sys/bus.h>
|
||||
#include <sys/uio.h>
|
||||
|
||||
|
||||
#include <machine/bus_pio.h>
|
||||
#include <machine/bus_memio.h>
|
||||
#include <machine/bus.h>
|
||||
@ -122,107 +121,62 @@ static int alpm_debug = 0;
|
||||
#define SMBCLOCK_111K 0xa0
|
||||
#define SMBCLOCK_55K 0xc0
|
||||
|
||||
struct alpm_data {
|
||||
struct alpm_softc {
|
||||
int base;
|
||||
struct resource *res;
|
||||
bus_space_tag_t smbst;
|
||||
bus_space_handle_t smbsh;
|
||||
};
|
||||
|
||||
struct alsmb_softc {
|
||||
int base;
|
||||
device_t smbus;
|
||||
struct alpm_data *alpm;
|
||||
};
|
||||
|
||||
#define ALPM_SMBINB(alsmb,register) \
|
||||
(bus_space_read_1(alsmb->alpm->smbst, alsmb->alpm->smbsh, register))
|
||||
#define ALPM_SMBOUTB(alsmb,register,value) \
|
||||
(bus_space_write_1(alsmb->alpm->smbst, alsmb->alpm->smbsh, register, value))
|
||||
|
||||
static int alsmb_probe(device_t);
|
||||
static int alsmb_attach(device_t);
|
||||
static int alsmb_smb_callback(device_t, int, caddr_t *);
|
||||
static int alsmb_smb_quick(device_t dev, u_char slave, int how);
|
||||
static int alsmb_smb_sendb(device_t dev, u_char slave, char byte);
|
||||
static int alsmb_smb_recvb(device_t dev, u_char slave, char *byte);
|
||||
static int alsmb_smb_writeb(device_t dev, u_char slave, char cmd, char byte);
|
||||
static int alsmb_smb_readb(device_t dev, u_char slave, char cmd, char *byte);
|
||||
static int alsmb_smb_writew(device_t dev, u_char slave, char cmd, short word);
|
||||
static int alsmb_smb_readw(device_t dev, u_char slave, char cmd, short *word);
|
||||
static int alsmb_smb_bwrite(device_t dev, u_char slave, char cmd, u_char count, char *buf);
|
||||
static int alsmb_smb_bread(device_t dev, u_char slave, char cmd, u_char count, char *byte);
|
||||
|
||||
static devclass_t alsmb_devclass;
|
||||
|
||||
static device_method_t alsmb_methods[] = {
|
||||
/* device interface */
|
||||
DEVMETHOD(device_probe, alsmb_probe),
|
||||
DEVMETHOD(device_attach, alsmb_attach),
|
||||
|
||||
/* bus interface */
|
||||
DEVMETHOD(bus_print_child, bus_generic_print_child),
|
||||
|
||||
/* smbus interface */
|
||||
DEVMETHOD(smbus_callback, alsmb_smb_callback),
|
||||
DEVMETHOD(smbus_quick, alsmb_smb_quick),
|
||||
DEVMETHOD(smbus_sendb, alsmb_smb_sendb),
|
||||
DEVMETHOD(smbus_recvb, alsmb_smb_recvb),
|
||||
DEVMETHOD(smbus_writeb, alsmb_smb_writeb),
|
||||
DEVMETHOD(smbus_readb, alsmb_smb_readb),
|
||||
DEVMETHOD(smbus_writew, alsmb_smb_writew),
|
||||
DEVMETHOD(smbus_readw, alsmb_smb_readw),
|
||||
DEVMETHOD(smbus_bwrite, alsmb_smb_bwrite),
|
||||
DEVMETHOD(smbus_bread, alsmb_smb_bread),
|
||||
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
static driver_t alsmb_driver = {
|
||||
"alsmb",
|
||||
alsmb_methods,
|
||||
sizeof(struct alsmb_softc),
|
||||
};
|
||||
|
||||
static int alpm_pci_probe(device_t dev);
|
||||
static int alpm_pci_attach(device_t dev);
|
||||
|
||||
static devclass_t alpm_devclass;
|
||||
|
||||
static device_method_t alpm_pci_methods[] = {
|
||||
/* device interface */
|
||||
DEVMETHOD(device_probe, alpm_pci_probe),
|
||||
DEVMETHOD(device_attach, alpm_pci_attach),
|
||||
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
static driver_t alpm_pci_driver = {
|
||||
"alpm",
|
||||
alpm_pci_methods,
|
||||
sizeof(struct alpm_data)
|
||||
};
|
||||
|
||||
#define ALPM_SMBINB(alpm,register) \
|
||||
(bus_space_read_1(alpm->smbst, alpm->smbsh, register))
|
||||
#define ALPM_SMBOUTB(alpm,register,value) \
|
||||
(bus_space_write_1(alpm->smbst, alpm->smbsh, register, value))
|
||||
|
||||
static int
|
||||
alpm_pci_probe(device_t dev)
|
||||
alpm_probe(device_t dev)
|
||||
{
|
||||
#ifdef ALPM_SMBIO_BASE_ADDR
|
||||
u_int32_t l;
|
||||
#endif
|
||||
|
||||
if (pci_get_devid(dev) == ACER_M1543_PMU_ID) {
|
||||
device_set_desc(dev,
|
||||
"AcerLabs M15x3 Power Management Unit");
|
||||
return 0;
|
||||
} else {
|
||||
return ENXIO;
|
||||
device_set_desc(dev, "AcerLabs M15x3 Power Management Unit");
|
||||
|
||||
#ifdef ALPM_SMBIO_BASE_ADDR
|
||||
if (bootverbose || alpm_debug)
|
||||
device_printf(dev, "forcing base I/O at 0x%x\n",
|
||||
ALPM_SMBIO_BASE_ADDR);
|
||||
|
||||
/* disable I/O */
|
||||
l = pci_read_config(dev, COM, 2);
|
||||
pci_write_config(dev, COM, l & ~COM_ENABLE_IO, 2);
|
||||
|
||||
/* set the I/O base address */
|
||||
pci_write_config(dev, SMBBA, ALPM_SMBIO_BASE_ADDR | 0x1, 4);
|
||||
|
||||
/* enable I/O */
|
||||
pci_write_config(dev, COM, l | COM_ENABLE_IO, 2);
|
||||
|
||||
if (bus_set_resource(dev, SYS_RES_IOPORT, SMBBA,
|
||||
ALPM_SMBIO_BASE_ADDR, 256)) {
|
||||
device_printf(dev, "could not set bus resource\n");
|
||||
return (ENXIO);
|
||||
}
|
||||
#endif
|
||||
return (0);
|
||||
}
|
||||
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
static int
|
||||
alpm_pci_attach(device_t dev)
|
||||
alpm_attach(device_t dev)
|
||||
{
|
||||
int rid, unit;
|
||||
u_int32_t l;
|
||||
struct alpm_data *alpm;
|
||||
struct resource *res;
|
||||
device_t smbinterface;
|
||||
struct alpm_softc *alpm;
|
||||
|
||||
alpm = device_get_softc(dev);
|
||||
unit = device_get_unit(dev);
|
||||
@ -239,9 +193,9 @@ alpm_pci_attach(device_t dev)
|
||||
pci_write_config(dev, SMBHCBC, l, 1);
|
||||
*/
|
||||
|
||||
if (bootverbose) {
|
||||
if (bootverbose || alpm_debug) {
|
||||
l = pci_read_config(dev, SMBHSI, 1);
|
||||
printf("alsmb%d: %s/%s", unit,
|
||||
device_printf(dev, "%s/%s",
|
||||
(l & SMBHSI_HOST) ? "host":"nohost",
|
||||
(l & SMBHSI_SLAVE) ? "slave":"noslave");
|
||||
|
||||
@ -265,76 +219,49 @@ alpm_pci_attach(device_t dev)
|
||||
case SMBCLOCK_55K:
|
||||
printf(" 55K");
|
||||
break;
|
||||
default:
|
||||
printf("unkown");
|
||||
break;
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
#ifdef ALPM_SMBIO_BASE_ADDR
|
||||
/* XX will this even work anymore? */
|
||||
/* disable I/O */
|
||||
l = pci_read_config(dev, COM, 2);
|
||||
pci_write_config(dev, COM, l & ~COM_ENABLE_IO, 2);
|
||||
|
||||
/* set the I/O base address */
|
||||
pci_write_config(dev, SMBBA, ALPM_SMBIO_BASE_ADDR | 0x1, 4);
|
||||
|
||||
/* enable I/O */
|
||||
pci_write_config(dev, COM, l | COM_ENABLE_IO, 2);
|
||||
|
||||
#endif
|
||||
rid = SMBBA;
|
||||
res = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid,
|
||||
0,~0,1,RF_ACTIVE);
|
||||
if (res == NULL) {
|
||||
alpm->res = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid,
|
||||
0, ~0, 1, RF_ACTIVE);
|
||||
|
||||
if (alpm->res == NULL) {
|
||||
device_printf(dev,"Could not allocate Bus space\n");
|
||||
return ENXIO;
|
||||
return (ENXIO);
|
||||
}
|
||||
alpm->smbst = rman_get_bustag(res);
|
||||
alpm->smbsh = rman_get_bushandle(res);
|
||||
alpm->smbst = rman_get_bustag(alpm->res);
|
||||
alpm->smbsh = rman_get_bushandle(alpm->res);
|
||||
|
||||
if (bootverbose)
|
||||
printf(" at 0x%x\n", alpm->smbsh);
|
||||
|
||||
smbinterface = device_add_child(dev, "alsmb", unit);
|
||||
if (!smbinterface)
|
||||
device_printf(dev, "could not add SMBus device\n");
|
||||
else
|
||||
device_probe_and_attach(smbinterface);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Not a real probe, we know the device exists since the device has
|
||||
* been added after the successfull pci probe.
|
||||
*/
|
||||
static int
|
||||
alsmb_probe(device_t dev)
|
||||
{
|
||||
struct alsmb_softc *sc = (struct alsmb_softc *)device_get_softc(dev);
|
||||
|
||||
/* allocate a new smbus device */
|
||||
sc->smbus = smbus_alloc_bus(dev);
|
||||
if (!sc->smbus)
|
||||
return (EINVAL);
|
||||
device_set_desc(dev, "Aladdin IV/V/Pro2 SMBus controller");
|
||||
/* attach the smbus */
|
||||
alpm->smbus = device_add_child(dev, "smbus", -1);
|
||||
bus_generic_attach(dev);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
alsmb_attach(device_t dev)
|
||||
alpm_detach(device_t dev)
|
||||
{
|
||||
struct alsmb_softc *sc = (struct alsmb_softc *)device_get_softc(dev);
|
||||
struct alpm_softc *alpm = device_get_softc(dev);
|
||||
|
||||
sc->alpm = device_get_softc(device_get_parent(dev));
|
||||
if (alpm->smbus) {
|
||||
device_delete_child(dev, alpm->smbus);
|
||||
alpm->smbus = NULL;
|
||||
}
|
||||
|
||||
/* probe and attach the smbus */
|
||||
device_probe_and_attach(sc->smbus);
|
||||
if (alpm->res)
|
||||
bus_release_resource(dev, SYS_RES_IOPORT, SMBBA, alpm->res);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
alsmb_smb_callback(device_t dev, int index, caddr_t *data)
|
||||
alpm_callback(device_t dev, int index, caddr_t *data)
|
||||
{
|
||||
int error = 0;
|
||||
|
||||
@ -351,7 +278,7 @@ alsmb_smb_callback(device_t dev, int index, caddr_t *data)
|
||||
}
|
||||
|
||||
static int
|
||||
alsmb_clear(struct alsmb_softc *sc)
|
||||
alpm_clear(struct alpm_softc *sc)
|
||||
{
|
||||
ALPM_SMBOUTB(sc, SMBSTS, 0xff);
|
||||
DELAY(10);
|
||||
@ -361,7 +288,7 @@ alsmb_clear(struct alsmb_softc *sc)
|
||||
|
||||
#if 0
|
||||
static int
|
||||
alsmb_abort(struct alsmb_softc *sc)
|
||||
alpm_abort(struct alpm_softc *sc)
|
||||
{
|
||||
ALPM_SMBOUTB(sc, SMBCMD, T_OUT_CMD | ABORT_HOST);
|
||||
|
||||
@ -370,7 +297,7 @@ alsmb_abort(struct alsmb_softc *sc)
|
||||
#endif
|
||||
|
||||
static int
|
||||
alsmb_idle(struct alsmb_softc *sc)
|
||||
alpm_idle(struct alpm_softc *sc)
|
||||
{
|
||||
u_char sts;
|
||||
|
||||
@ -385,7 +312,7 @@ alsmb_idle(struct alsmb_softc *sc)
|
||||
* Poll the SMBus controller
|
||||
*/
|
||||
static int
|
||||
alsmb_wait(struct alsmb_softc *sc)
|
||||
alpm_wait(struct alpm_softc *sc)
|
||||
{
|
||||
int count = 10000;
|
||||
u_char sts = 0;
|
||||
@ -416,19 +343,19 @@ alsmb_wait(struct alsmb_softc *sc)
|
||||
error |= SMB_EBUSERR;
|
||||
|
||||
if (error != SMB_ENOERR)
|
||||
alsmb_clear(sc);
|
||||
alpm_clear(sc);
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
alsmb_smb_quick(device_t dev, u_char slave, int how)
|
||||
alpm_quick(device_t dev, u_char slave, int how)
|
||||
{
|
||||
struct alsmb_softc *sc = (struct alsmb_softc *)device_get_softc(dev);
|
||||
struct alpm_softc *sc = (struct alpm_softc *)device_get_softc(dev);
|
||||
int error;
|
||||
|
||||
alsmb_clear(sc);
|
||||
if (!alsmb_idle(sc))
|
||||
alpm_clear(sc);
|
||||
if (!alpm_idle(sc))
|
||||
return (EBUSY);
|
||||
|
||||
switch (how) {
|
||||
@ -447,7 +374,7 @@ alsmb_smb_quick(device_t dev, u_char slave, int how)
|
||||
ALPM_SMBOUTB(sc, SMBCMD, SMBQUICK);
|
||||
ALPM_SMBOUTB(sc, SMBSTART, 0xff);
|
||||
|
||||
error = alsmb_wait(sc);
|
||||
error = alpm_wait(sc);
|
||||
|
||||
ALPM_DEBUG(printf(", error=0x%x\n", error));
|
||||
|
||||
@ -455,13 +382,13 @@ alsmb_smb_quick(device_t dev, u_char slave, int how)
|
||||
}
|
||||
|
||||
static int
|
||||
alsmb_smb_sendb(device_t dev, u_char slave, char byte)
|
||||
alpm_sendb(device_t dev, u_char slave, char byte)
|
||||
{
|
||||
struct alsmb_softc *sc = (struct alsmb_softc *)device_get_softc(dev);
|
||||
struct alpm_softc *sc = (struct alpm_softc *)device_get_softc(dev);
|
||||
int error;
|
||||
|
||||
alsmb_clear(sc);
|
||||
if (!alsmb_idle(sc))
|
||||
alpm_clear(sc);
|
||||
if (!alpm_idle(sc))
|
||||
return (SMB_EBUSY);
|
||||
|
||||
ALPM_SMBOUTB(sc, SMBHADDR, slave & ~LSB);
|
||||
@ -469,7 +396,7 @@ alsmb_smb_sendb(device_t dev, u_char slave, char byte)
|
||||
ALPM_SMBOUTB(sc, SMBHDATA, byte);
|
||||
ALPM_SMBOUTB(sc, SMBSTART, 0xff);
|
||||
|
||||
error = alsmb_wait(sc);
|
||||
error = alpm_wait(sc);
|
||||
|
||||
ALPM_DEBUG(printf("alpm: SENDB to 0x%x, byte=0x%x, error=0x%x\n", slave, byte, error));
|
||||
|
||||
@ -477,20 +404,20 @@ alsmb_smb_sendb(device_t dev, u_char slave, char byte)
|
||||
}
|
||||
|
||||
static int
|
||||
alsmb_smb_recvb(device_t dev, u_char slave, char *byte)
|
||||
alpm_recvb(device_t dev, u_char slave, char *byte)
|
||||
{
|
||||
struct alsmb_softc *sc = (struct alsmb_softc *)device_get_softc(dev);
|
||||
struct alpm_softc *sc = (struct alpm_softc *)device_get_softc(dev);
|
||||
int error;
|
||||
|
||||
alsmb_clear(sc);
|
||||
if (!alsmb_idle(sc))
|
||||
alpm_clear(sc);
|
||||
if (!alpm_idle(sc))
|
||||
return (SMB_EBUSY);
|
||||
|
||||
ALPM_SMBOUTB(sc, SMBHADDR, slave | LSB);
|
||||
ALPM_SMBOUTB(sc, SMBCMD, SMBSRBYTE);
|
||||
ALPM_SMBOUTB(sc, SMBSTART, 0xff);
|
||||
|
||||
if ((error = alsmb_wait(sc)) == SMB_ENOERR)
|
||||
if ((error = alpm_wait(sc)) == SMB_ENOERR)
|
||||
*byte = ALPM_SMBINB(sc, SMBHDATA);
|
||||
|
||||
ALPM_DEBUG(printf("alpm: RECVB from 0x%x, byte=0x%x, error=0x%x\n", slave, *byte, error));
|
||||
@ -499,13 +426,13 @@ alsmb_smb_recvb(device_t dev, u_char slave, char *byte)
|
||||
}
|
||||
|
||||
static int
|
||||
alsmb_smb_writeb(device_t dev, u_char slave, char cmd, char byte)
|
||||
alpm_writeb(device_t dev, u_char slave, char cmd, char byte)
|
||||
{
|
||||
struct alsmb_softc *sc = (struct alsmb_softc *)device_get_softc(dev);
|
||||
struct alpm_softc *sc = (struct alpm_softc *)device_get_softc(dev);
|
||||
int error;
|
||||
|
||||
alsmb_clear(sc);
|
||||
if (!alsmb_idle(sc))
|
||||
alpm_clear(sc);
|
||||
if (!alpm_idle(sc))
|
||||
return (SMB_EBUSY);
|
||||
|
||||
ALPM_SMBOUTB(sc, SMBHADDR, slave & ~LSB);
|
||||
@ -514,7 +441,7 @@ alsmb_smb_writeb(device_t dev, u_char slave, char cmd, char byte)
|
||||
ALPM_SMBOUTB(sc, SMBHCMD, cmd);
|
||||
ALPM_SMBOUTB(sc, SMBSTART, 0xff);
|
||||
|
||||
error = alsmb_wait(sc);
|
||||
error = alpm_wait(sc);
|
||||
|
||||
ALPM_DEBUG(printf("alpm: WRITEB to 0x%x, cmd=0x%x, byte=0x%x, error=0x%x\n", slave, cmd, byte, error));
|
||||
|
||||
@ -522,13 +449,13 @@ alsmb_smb_writeb(device_t dev, u_char slave, char cmd, char byte)
|
||||
}
|
||||
|
||||
static int
|
||||
alsmb_smb_readb(device_t dev, u_char slave, char cmd, char *byte)
|
||||
alpm_readb(device_t dev, u_char slave, char cmd, char *byte)
|
||||
{
|
||||
struct alsmb_softc *sc = (struct alsmb_softc *)device_get_softc(dev);
|
||||
struct alpm_softc *sc = (struct alpm_softc *)device_get_softc(dev);
|
||||
int error;
|
||||
|
||||
alsmb_clear(sc);
|
||||
if (!alsmb_idle(sc))
|
||||
alpm_clear(sc);
|
||||
if (!alpm_idle(sc))
|
||||
return (SMB_EBUSY);
|
||||
|
||||
ALPM_SMBOUTB(sc, SMBHADDR, slave | LSB);
|
||||
@ -536,7 +463,7 @@ alsmb_smb_readb(device_t dev, u_char slave, char cmd, char *byte)
|
||||
ALPM_SMBOUTB(sc, SMBHCMD, cmd);
|
||||
ALPM_SMBOUTB(sc, SMBSTART, 0xff);
|
||||
|
||||
if ((error = alsmb_wait(sc)) == SMB_ENOERR)
|
||||
if ((error = alpm_wait(sc)) == SMB_ENOERR)
|
||||
*byte = ALPM_SMBINB(sc, SMBHDATA);
|
||||
|
||||
ALPM_DEBUG(printf("alpm: READB from 0x%x, cmd=0x%x, byte=0x%x, error=0x%x\n", slave, cmd, *byte, error));
|
||||
@ -545,13 +472,13 @@ alsmb_smb_readb(device_t dev, u_char slave, char cmd, char *byte)
|
||||
}
|
||||
|
||||
static int
|
||||
alsmb_smb_writew(device_t dev, u_char slave, char cmd, short word)
|
||||
alpm_writew(device_t dev, u_char slave, char cmd, short word)
|
||||
{
|
||||
struct alsmb_softc *sc = (struct alsmb_softc *)device_get_softc(dev);
|
||||
struct alpm_softc *sc = (struct alpm_softc *)device_get_softc(dev);
|
||||
int error;
|
||||
|
||||
alsmb_clear(sc);
|
||||
if (!alsmb_idle(sc))
|
||||
alpm_clear(sc);
|
||||
if (!alpm_idle(sc))
|
||||
return (SMB_EBUSY);
|
||||
|
||||
ALPM_SMBOUTB(sc, SMBHADDR, slave & ~LSB);
|
||||
@ -561,7 +488,7 @@ alsmb_smb_writew(device_t dev, u_char slave, char cmd, short word)
|
||||
ALPM_SMBOUTB(sc, SMBHCMD, cmd);
|
||||
ALPM_SMBOUTB(sc, SMBSTART, 0xff);
|
||||
|
||||
error = alsmb_wait(sc);
|
||||
error = alpm_wait(sc);
|
||||
|
||||
ALPM_DEBUG(printf("alpm: WRITEW to 0x%x, cmd=0x%x, word=0x%x, error=0x%x\n", slave, cmd, word, error));
|
||||
|
||||
@ -569,14 +496,14 @@ alsmb_smb_writew(device_t dev, u_char slave, char cmd, short word)
|
||||
}
|
||||
|
||||
static int
|
||||
alsmb_smb_readw(device_t dev, u_char slave, char cmd, short *word)
|
||||
alpm_readw(device_t dev, u_char slave, char cmd, short *word)
|
||||
{
|
||||
struct alsmb_softc *sc = (struct alsmb_softc *)device_get_softc(dev);
|
||||
struct alpm_softc *sc = (struct alpm_softc *)device_get_softc(dev);
|
||||
int error;
|
||||
u_char high, low;
|
||||
|
||||
alsmb_clear(sc);
|
||||
if (!alsmb_idle(sc))
|
||||
alpm_clear(sc);
|
||||
if (!alpm_idle(sc))
|
||||
return (SMB_EBUSY);
|
||||
|
||||
ALPM_SMBOUTB(sc, SMBHADDR, slave | LSB);
|
||||
@ -584,7 +511,7 @@ alsmb_smb_readw(device_t dev, u_char slave, char cmd, short *word)
|
||||
ALPM_SMBOUTB(sc, SMBHCMD, cmd);
|
||||
ALPM_SMBOUTB(sc, SMBSTART, 0xff);
|
||||
|
||||
if ((error = alsmb_wait(sc)) == SMB_ENOERR) {
|
||||
if ((error = alpm_wait(sc)) == SMB_ENOERR) {
|
||||
low = ALPM_SMBINB(sc, SMBHDATA);
|
||||
high = ALPM_SMBINB(sc, SMBHDATB);
|
||||
|
||||
@ -597,14 +524,14 @@ alsmb_smb_readw(device_t dev, u_char slave, char cmd, short *word)
|
||||
}
|
||||
|
||||
static int
|
||||
alsmb_smb_bwrite(device_t dev, u_char slave, char cmd, u_char count, char *buf)
|
||||
alpm_bwrite(device_t dev, u_char slave, char cmd, u_char count, char *buf)
|
||||
{
|
||||
struct alsmb_softc *sc = (struct alsmb_softc *)device_get_softc(dev);
|
||||
struct alpm_softc *sc = (struct alpm_softc *)device_get_softc(dev);
|
||||
u_char remain, len, i;
|
||||
int error = SMB_ENOERR;
|
||||
|
||||
alsmb_clear(sc);
|
||||
if(!alsmb_idle(sc))
|
||||
alpm_clear(sc);
|
||||
if(!alpm_idle(sc))
|
||||
return (SMB_EBUSY);
|
||||
|
||||
remain = count;
|
||||
@ -627,7 +554,7 @@ alsmb_smb_bwrite(device_t dev, u_char slave, char cmd, u_char count, char *buf)
|
||||
ALPM_SMBOUTB(sc, SMBHCMD, cmd);
|
||||
ALPM_SMBOUTB(sc, SMBSTART, 0xff);
|
||||
|
||||
if ((error = alsmb_wait(sc)) != SMB_ENOERR)
|
||||
if ((error = alpm_wait(sc)) != SMB_ENOERR)
|
||||
goto error;
|
||||
|
||||
remain -= len;
|
||||
@ -640,14 +567,14 @@ error:
|
||||
}
|
||||
|
||||
static int
|
||||
alsmb_smb_bread(device_t dev, u_char slave, char cmd, u_char count, char *buf)
|
||||
alpm_bread(device_t dev, u_char slave, char cmd, u_char count, char *buf)
|
||||
{
|
||||
struct alsmb_softc *sc = (struct alsmb_softc *)device_get_softc(dev);
|
||||
struct alpm_softc *sc = (struct alpm_softc *)device_get_softc(dev);
|
||||
u_char remain, len, i;
|
||||
int error = SMB_ENOERR;
|
||||
|
||||
alsmb_clear(sc);
|
||||
if (!alsmb_idle(sc))
|
||||
alpm_clear(sc);
|
||||
if (!alpm_idle(sc))
|
||||
return (SMB_EBUSY);
|
||||
|
||||
remain = count;
|
||||
@ -661,7 +588,7 @@ alsmb_smb_bread(device_t dev, u_char slave, char cmd, u_char count, char *buf)
|
||||
ALPM_SMBOUTB(sc, SMBHCMD, cmd);
|
||||
ALPM_SMBOUTB(sc, SMBSTART, 0xff);
|
||||
|
||||
if ((error = alsmb_wait(sc)) != SMB_ENOERR)
|
||||
if ((error = alpm_wait(sc)) != SMB_ENOERR)
|
||||
goto error;
|
||||
|
||||
len = ALPM_SMBINB(sc, SMBHDATA);
|
||||
@ -680,5 +607,35 @@ error:
|
||||
return (error);
|
||||
}
|
||||
|
||||
DRIVER_MODULE(alpm, pci, alpm_pci_driver, alpm_devclass, 0, 0);
|
||||
DRIVER_MODULE(alsmb, alpm, alsmb_driver, alsmb_devclass, 0, 0);
|
||||
static devclass_t alpm_devclass;
|
||||
|
||||
static device_method_t alpm_methods[] = {
|
||||
/* device interface */
|
||||
DEVMETHOD(device_probe, alpm_probe),
|
||||
DEVMETHOD(device_attach, alpm_attach),
|
||||
DEVMETHOD(device_detach, alpm_detach),
|
||||
|
||||
/* smbus interface */
|
||||
DEVMETHOD(smbus_callback, alpm_callback),
|
||||
DEVMETHOD(smbus_quick, alpm_quick),
|
||||
DEVMETHOD(smbus_sendb, alpm_sendb),
|
||||
DEVMETHOD(smbus_recvb, alpm_recvb),
|
||||
DEVMETHOD(smbus_writeb, alpm_writeb),
|
||||
DEVMETHOD(smbus_readb, alpm_readb),
|
||||
DEVMETHOD(smbus_writew, alpm_writew),
|
||||
DEVMETHOD(smbus_readw, alpm_readw),
|
||||
DEVMETHOD(smbus_bwrite, alpm_bwrite),
|
||||
DEVMETHOD(smbus_bread, alpm_bread),
|
||||
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
static driver_t alpm_driver = {
|
||||
"alpm",
|
||||
alpm_methods,
|
||||
sizeof(struct alpm_softc)
|
||||
};
|
||||
|
||||
DRIVER_MODULE(alpm, pci, alpm_driver, alpm_devclass, 0, 0);
|
||||
MODULE_DEPEND(alpm, smbus, SMBUS_MINVER, SMBUS_PREFVER, SMBUS_MAXVER);
|
||||
MODULE_VERSION(alpm, 1);
|
||||
|
@ -150,7 +150,7 @@ static int
|
||||
intsmb_probe(device_t dev)
|
||||
{
|
||||
struct intsmb_softc *sc =(struct intsmb_softc *) device_get_softc(dev);
|
||||
sc->smbus=smbus_alloc_bus(dev);
|
||||
sc->smbus=device_add_child(dev, "smbus", -1);
|
||||
if (!sc->smbus)
|
||||
return (EINVAL); /* XXX don't know what to return else */
|
||||
device_set_desc(dev,"Intel PIIX4 SMBUS Interface");
|
||||
@ -739,6 +739,8 @@ intpm_probe(device_t dev)
|
||||
}
|
||||
}
|
||||
DRIVER_MODULE(intpm, pci , intpm_pci_driver, intpm_devclass, 0, 0);
|
||||
MODULE_DEPEND(intpm, smbus, SMBUS_MINVER, SMBUS_PREFVER, SMBUS_MAXVER);
|
||||
MODULE_VERSION(intpm, 1);
|
||||
|
||||
static void intpm_intr(void *arg)
|
||||
{
|
||||
|
924
sys/pci/viapm.c
Normal file
924
sys/pci/viapm.c
Normal file
@ -0,0 +1,924 @@
|
||||
/*-
|
||||
* Copyright (c) 2001 Alcove - Nicolas Souchu
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*
|
||||
*/
|
||||
#include <sys/param.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/uio.h>
|
||||
|
||||
#include <machine/bus_pio.h>
|
||||
#include <machine/bus_memio.h>
|
||||
#include <machine/bus.h>
|
||||
#include <machine/clock.h> /* for DELAY */
|
||||
#include <machine/resource.h>
|
||||
#include <sys/rman.h>
|
||||
|
||||
#include <pci/pcivar.h>
|
||||
#include <pci/pcireg.h>
|
||||
|
||||
#include <dev/iicbus/iiconf.h>
|
||||
#include <dev/iicbus/iicbus.h>
|
||||
|
||||
#include <dev/smbus/smbconf.h>
|
||||
#include <dev/smbus/smbus.h>
|
||||
|
||||
#include "iicbb_if.h"
|
||||
#include "smbus_if.h"
|
||||
|
||||
#define VIAPM_DEBUG(x) if (viapm_debug) (x)
|
||||
|
||||
#ifdef DEBUG
|
||||
static int viapm_debug = 1;
|
||||
#else
|
||||
static int viapm_debug = 0;
|
||||
#endif
|
||||
|
||||
#define VIA_586B_PMU_ID 0x30401106
|
||||
#define VIA_596A_PMU_ID 0x30501106
|
||||
#define VIA_596B_PMU_ID 0x30511106
|
||||
#define VIA_686A_PMU_ID 0x30571106
|
||||
#define VIA_8233_PMU_ID 0x30741106
|
||||
|
||||
#define VIAPM_INB(port) \
|
||||
((u_char)bus_space_read_1(viapm->st, viapm->sh, port))
|
||||
#define VIAPM_OUTB(port,val) \
|
||||
(bus_space_write_1(viapm->st, viapm->sh, port, (u_char)val))
|
||||
|
||||
#define VIAPM_TYP_UNKNOWN 0
|
||||
#define VIAPM_TYP_586B_3040E 1
|
||||
#define VIAPM_TYP_586B_3040F 2
|
||||
#define VIAPM_TYP_596B 3
|
||||
#define VIAPM_TYP_686A 4
|
||||
#define VIAPM_TYP_8233 5
|
||||
|
||||
struct viapm_softc {
|
||||
int type;
|
||||
u_int32_t base;
|
||||
bus_space_tag_t st;
|
||||
bus_space_handle_t sh;
|
||||
int iorid;
|
||||
int irqrid;
|
||||
struct resource *iores;
|
||||
struct resource *irqres;
|
||||
void *irqih;
|
||||
|
||||
device_t iicbb;
|
||||
device_t smbus;
|
||||
};
|
||||
|
||||
static devclass_t viapm_devclass;
|
||||
static devclass_t viapropm_devclass;
|
||||
|
||||
/*
|
||||
* VT82C586B definitions
|
||||
*/
|
||||
|
||||
#define VIAPM_586B_REVID 0x08
|
||||
|
||||
#define VIAPM_586B_3040E_BASE 0x20
|
||||
#define VIAPM_586B_3040E_ACTIV 0x4 /* 16 bits */
|
||||
|
||||
#define VIAPM_586B_3040F_BASE 0x48
|
||||
#define VIAPM_586B_3040F_ACTIV 0x41 /* 8 bits */
|
||||
|
||||
#define VIAPM_586B_OEM_REV_E 0x00
|
||||
#define VIAPM_586B_OEM_REV_F 0x01
|
||||
#define VIAPM_586B_PROD_REV_A 0x10
|
||||
|
||||
#define VIAPM_586B_BA_MASK 0x0000ff00
|
||||
|
||||
#define GPIO_DIR 0x40
|
||||
#define GPIO_VAL 0x42
|
||||
#define EXTSMI_VAL 0x44
|
||||
|
||||
#define VIAPM_SCL 0x02 /* GPIO1_VAL */
|
||||
#define VIAPM_SDA 0x04 /* GPIO2_VAL */
|
||||
|
||||
/*
|
||||
* VIAPRO common definitions
|
||||
*/
|
||||
|
||||
#define VIAPM_PRO_BA_MASK 0x0000fff0
|
||||
#define VIAPM_PRO_SMBCTRL 0xd2
|
||||
#define VIAPM_PRO_REVID 0xd6
|
||||
|
||||
/*
|
||||
* VT82C686A definitions
|
||||
*/
|
||||
|
||||
#define VIAPM_PRO_BASE 0x90
|
||||
|
||||
#define SMBHST 0x0
|
||||
#define SMBHSL 0x1
|
||||
#define SMBHCTRL 0x2
|
||||
#define SMBHCMD 0x3
|
||||
#define SMBHADDR 0x4
|
||||
#define SMBHDATA0 0x5
|
||||
#define SMBHDATA1 0x6
|
||||
#define SMBHBLOCK 0x7
|
||||
|
||||
#define SMBSST 0x1
|
||||
#define SMBSCTRL 0x8
|
||||
#define SMBSSDWCMD 0x9
|
||||
#define SMBSEVENT 0xa
|
||||
#define SMBSDATA 0xc
|
||||
|
||||
#define SMBHST_RESERVED 0xef /* reserved bits */
|
||||
#define SMBHST_FAILED 0x10 /* failed bus transaction */
|
||||
#define SMBHST_COLLID 0x08 /* bus collision */
|
||||
#define SMBHST_ERROR 0x04 /* device error */
|
||||
#define SMBHST_INTR 0x02 /* command completed */
|
||||
#define SMBHST_BUSY 0x01 /* host busy */
|
||||
|
||||
#define SMBHCTRL_START 0x40 /* start command */
|
||||
#define SMBHCTRL_PROTO 0x1c /* command protocol mask */
|
||||
#define SMBHCTRL_QUICK 0x00
|
||||
#define SMBHCTRL_SENDRECV 0x04
|
||||
#define SMBHCTRL_BYTE 0x08
|
||||
#define SMBHCTRL_WORD 0x0c
|
||||
#define SMBHCTRL_BLOCK 0x14
|
||||
#define SMBHCTRL_KILL 0x02 /* stop the current transaction */
|
||||
#define SMBHCTRL_ENABLE 0x01 /* enable interrupts */
|
||||
|
||||
#define SMBSCTRL_ENABLE 0x01 /* enable slave */
|
||||
|
||||
|
||||
/*
|
||||
* VIA8233 definitions
|
||||
*/
|
||||
|
||||
#define VIAPM_8233_BASE 0xD0
|
||||
|
||||
static int
|
||||
viapm_586b_probe(device_t dev)
|
||||
{
|
||||
struct viapm_softc *viapm = (struct viapm_softc *)device_get_softc(dev);
|
||||
u_int32_t l;
|
||||
u_int16_t s;
|
||||
u_int8_t c;
|
||||
|
||||
switch (pci_get_devid(dev)) {
|
||||
case VIA_586B_PMU_ID:
|
||||
|
||||
bzero(viapm, sizeof(struct viapm_softc));
|
||||
|
||||
l = pci_read_config(dev, VIAPM_586B_REVID, 1);
|
||||
switch (l) {
|
||||
case VIAPM_586B_OEM_REV_E:
|
||||
viapm->type = VIAPM_TYP_586B_3040E;
|
||||
viapm->iorid = VIAPM_586B_3040E_BASE;
|
||||
|
||||
/* Activate IO block access */
|
||||
s = pci_read_config(dev, VIAPM_586B_3040E_ACTIV, 2);
|
||||
pci_write_config(dev, VIAPM_586B_3040E_ACTIV, s | 0x1, 2);
|
||||
break;
|
||||
|
||||
case VIAPM_586B_OEM_REV_F:
|
||||
case VIAPM_586B_PROD_REV_A:
|
||||
default:
|
||||
viapm->type = VIAPM_TYP_586B_3040F;
|
||||
viapm->iorid = VIAPM_586B_3040F_BASE;
|
||||
|
||||
/* Activate IO block access */
|
||||
c = pci_read_config(dev, VIAPM_586B_3040F_ACTIV, 1);
|
||||
pci_write_config(dev, VIAPM_586B_3040F_ACTIV, c | 0x80, 1);
|
||||
break;
|
||||
}
|
||||
|
||||
viapm->base = pci_read_config(dev, viapm->iorid, 4) &
|
||||
VIAPM_586B_BA_MASK;
|
||||
|
||||
/*
|
||||
* We have to set the I/O resources by hand because it is
|
||||
* described outside the viapmope of the traditional maps
|
||||
*/
|
||||
if (bus_set_resource(dev, SYS_RES_IOPORT, viapm->iorid,
|
||||
viapm->base, 256)) {
|
||||
device_printf(dev, "could not set bus resource\n");
|
||||
return ENXIO;
|
||||
}
|
||||
device_set_desc(dev, "VIA VT82C586B Power Management Unit");
|
||||
return 0;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return ENXIO;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
viapm_pro_probe(device_t dev)
|
||||
{
|
||||
struct viapm_softc *viapm = (struct viapm_softc *)device_get_softc(dev);
|
||||
#ifdef VIAPM_BASE_ADDR
|
||||
u_int32_t l;
|
||||
#endif
|
||||
u_int32_t base_cfgreg;
|
||||
char *desc;
|
||||
|
||||
switch (pci_get_devid(dev)) {
|
||||
case VIA_596A_PMU_ID:
|
||||
desc = "VIA VT82C596A Power Management Unit";
|
||||
viapm->type = VIAPM_TYP_596B;
|
||||
base_cfgreg = VIAPM_PRO_BASE;
|
||||
goto viapro;
|
||||
|
||||
case VIA_596B_PMU_ID:
|
||||
desc = "VIA VT82C596B Power Management Unit";
|
||||
viapm->type = VIAPM_TYP_596B;
|
||||
base_cfgreg = VIAPM_PRO_BASE;
|
||||
goto viapro;
|
||||
|
||||
case VIA_686A_PMU_ID:
|
||||
desc = "VIA VT82C686A Power Management Unit";
|
||||
viapm->type = VIAPM_TYP_686A;
|
||||
base_cfgreg = VIAPM_PRO_BASE;
|
||||
goto viapro;
|
||||
|
||||
case VIA_8233_PMU_ID:
|
||||
desc = "VIA VT8233 Power Management Unit";
|
||||
viapm->type = VIAPM_TYP_UNKNOWN;
|
||||
base_cfgreg = VIAPM_8233_BASE;
|
||||
goto viapro;
|
||||
|
||||
viapro:
|
||||
|
||||
#ifdef VIAPM_BASE_ADDR
|
||||
/* force VIAPM I/O base address */
|
||||
|
||||
/* enable the SMBus controller function */
|
||||
l = pci_read_config(dev, VIAPM_PRO_SMBCTRL, 1);
|
||||
pci_write_config(dev, VIAPM_PRO_SMBCTRL, l | 1, 1);
|
||||
|
||||
/* write the base address */
|
||||
pci_write_config(dev, base_cfgreg,
|
||||
VIAPM_BASE_ADDR & VIAPM_PRO_BA_MASK, 4);
|
||||
#endif
|
||||
|
||||
viapm->base = pci_read_config(dev, base_cfgreg, 4) & VIAPM_PRO_BA_MASK;
|
||||
|
||||
/*
|
||||
* We have to set the I/O resources by hand because it is
|
||||
* described outside the viapmope of the traditional maps
|
||||
*/
|
||||
viapm->iorid = base_cfgreg;
|
||||
if (bus_set_resource(dev, SYS_RES_IOPORT, viapm->iorid,
|
||||
viapm->base, 16)) {
|
||||
device_printf(dev, "could not set bus resource 0x%x\n",
|
||||
viapm->base);
|
||||
return ENXIO;
|
||||
}
|
||||
|
||||
if (1 || bootverbose) {
|
||||
device_printf(dev, "SMBus I/O base at 0x%x\n", viapm->base);
|
||||
}
|
||||
|
||||
device_set_desc(dev, desc);
|
||||
return 0;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return ENXIO;
|
||||
}
|
||||
|
||||
static int
|
||||
viapm_pro_attach(device_t dev)
|
||||
{
|
||||
struct viapm_softc *viapm = (struct viapm_softc *)device_get_softc(dev);
|
||||
u_int32_t l;
|
||||
|
||||
if (!(viapm->iores = bus_alloc_resource(dev, SYS_RES_IOPORT,
|
||||
&viapm->iorid, 0l, ~0l, 1, RF_ACTIVE))) {
|
||||
device_printf(dev, "could not allocate bus space\n");
|
||||
goto error;
|
||||
}
|
||||
viapm->st = rman_get_bustag(viapm->iores);
|
||||
viapm->sh = rman_get_bushandle(viapm->iores);
|
||||
|
||||
#if notyet
|
||||
/* force irq 9 */
|
||||
l = pci_read_config(dev, VIAPM_PRO_SMBCTRL, 1);
|
||||
pci_write_config(dev, VIAPM_PRO_SMBCTRL, l | 0x80, 1);
|
||||
|
||||
viapm->irqrid = 0;
|
||||
if (!(viapm->irqres = bus_alloc_resource(dev, SYS_RES_IRQ,
|
||||
&viapm->irqrid, 9, 9, 1,
|
||||
RF_SHAREABLE | RF_ACTIVE))) {
|
||||
device_printf(dev, "could not allocate irq\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (bus_setup_intr(dev, viapm->irqres, INTR_TYPE_MISC,
|
||||
(driver_intr_t *) viasmb_intr, viapm, &viapm->irqih)) {
|
||||
device_printf(dev, "could not setup irq\n");
|
||||
goto error;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (1 | bootverbose) {
|
||||
l = pci_read_config(dev, VIAPM_PRO_REVID, 1);
|
||||
device_printf(dev, "SMBus revision code 0x%x\n", l);
|
||||
}
|
||||
|
||||
viapm->smbus = device_add_child(dev, "smbus", -1);
|
||||
|
||||
/* probe and attach the smbus */
|
||||
bus_generic_attach(dev);
|
||||
|
||||
/* disable slave function */
|
||||
VIAPM_OUTB(SMBSCTRL, VIAPM_INB(SMBSCTRL) & ~SMBSCTRL_ENABLE);
|
||||
|
||||
/* enable the SMBus controller function */
|
||||
l = pci_read_config(dev, VIAPM_PRO_SMBCTRL, 1);
|
||||
pci_write_config(dev, VIAPM_PRO_SMBCTRL, l | 1, 1);
|
||||
|
||||
#if notyet
|
||||
/* enable interrupts */
|
||||
VIAPM_OUTB(SMBHCTRL, VIAPM_INB(SMBHCTRL) | SMBHCTRL_ENABLE);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
if (viapm->iores)
|
||||
bus_release_resource(dev, SYS_RES_IOPORT, viapm->iorid, viapm->iores);
|
||||
#if notyet
|
||||
if (viapm->irqres)
|
||||
bus_release_resource(dev, SYS_RES_IRQ, viapm->irqrid, viapm->irqres);
|
||||
#endif
|
||||
|
||||
return ENXIO;
|
||||
}
|
||||
|
||||
static int
|
||||
viapm_586b_attach(device_t dev)
|
||||
{
|
||||
struct viapm_softc *viapm = (struct viapm_softc *)device_get_softc(dev);
|
||||
|
||||
if (!(viapm->iores = bus_alloc_resource(dev, SYS_RES_IOPORT,
|
||||
&viapm->iorid, 0ul, ~0ul, 1, RF_ACTIVE | RF_SHAREABLE))) {
|
||||
device_printf(dev, "could not allocate bus resource\n");
|
||||
return ENXIO;
|
||||
}
|
||||
viapm->st = rman_get_bustag(viapm->iores);
|
||||
viapm->sh = rman_get_bushandle(viapm->iores);
|
||||
|
||||
VIAPM_OUTB(GPIO_DIR, VIAPM_INB(GPIO_DIR) | VIAPM_SCL | VIAPM_SDA);
|
||||
|
||||
/* add generic bit-banging code */
|
||||
if (!(viapm->iicbb = device_add_child(dev, "iicbb", -1)))
|
||||
goto error;
|
||||
|
||||
bus_generic_attach(dev);
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
if (viapm->iores)
|
||||
bus_release_resource(dev, SYS_RES_IOPORT,
|
||||
viapm->iorid, viapm->iores);
|
||||
return ENXIO;
|
||||
}
|
||||
|
||||
static int
|
||||
viapm_586b_detach(device_t dev)
|
||||
{
|
||||
struct viapm_softc *viapm = (struct viapm_softc *)device_get_softc(dev);
|
||||
int error;
|
||||
|
||||
bus_generic_detach(dev);
|
||||
if (viapm->iicbb) {
|
||||
device_delete_child(dev, viapm->iicbb);
|
||||
}
|
||||
|
||||
if (viapm->iores && (error = bus_release_resource(dev, SYS_RES_IOPORT,
|
||||
viapm->iorid, viapm->iores)))
|
||||
return (error);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
viapm_pro_detach(device_t dev)
|
||||
{
|
||||
struct viapm_softc *viapm = (struct viapm_softc *)device_get_softc(dev);
|
||||
int error;
|
||||
|
||||
bus_generic_detach(dev);
|
||||
if (viapm->smbus) {
|
||||
device_delete_child(dev, viapm->smbus);
|
||||
}
|
||||
|
||||
if ((error = bus_release_resource(dev, SYS_RES_IOPORT,
|
||||
viapm->iorid, viapm->iores)))
|
||||
return (error);
|
||||
|
||||
#if notyet
|
||||
if ((error = bus_release_resource(dev, SYS_RES_IRQ,
|
||||
viapm->irqrid, viapm->irqres))
|
||||
return (error);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
viabb_callback(device_t dev, int index, caddr_t *data)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
viabb_setscl(device_t dev, int ctrl)
|
||||
{
|
||||
struct viapm_softc *viapm = device_get_softc(dev);
|
||||
u_char val;
|
||||
|
||||
val = VIAPM_INB(GPIO_VAL);
|
||||
|
||||
if (ctrl)
|
||||
val |= VIAPM_SCL;
|
||||
else
|
||||
val &= ~VIAPM_SCL;
|
||||
|
||||
VIAPM_OUTB(GPIO_VAL, val);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
viabb_setsda(device_t dev, int data)
|
||||
{
|
||||
struct viapm_softc *viapm = device_get_softc(dev);
|
||||
u_char val;
|
||||
|
||||
val = VIAPM_INB(GPIO_VAL);
|
||||
|
||||
if (data)
|
||||
val |= VIAPM_SDA;
|
||||
else
|
||||
val &= ~VIAPM_SDA;
|
||||
|
||||
VIAPM_OUTB(GPIO_VAL, val);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static int
|
||||
viabb_reset(device_t dev, u_char speed, u_char addr, u_char *oldaddr)
|
||||
{
|
||||
/* reset bus */
|
||||
viabb_setsda(dev, 1);
|
||||
viabb_setscl(dev, 1);
|
||||
|
||||
return (IIC_ENOADDR);
|
||||
}
|
||||
|
||||
static int
|
||||
viabb_getscl(device_t dev)
|
||||
{
|
||||
struct viapm_softc *viapm = device_get_softc(dev);
|
||||
|
||||
return ((VIAPM_INB(EXTSMI_VAL) & VIAPM_SCL) != 0);
|
||||
}
|
||||
|
||||
static int
|
||||
viabb_getsda(device_t dev)
|
||||
{
|
||||
struct viapm_softc *viapm = device_get_softc(dev);
|
||||
|
||||
return ((VIAPM_INB(EXTSMI_VAL) & VIAPM_SDA) != 0);
|
||||
}
|
||||
|
||||
static int
|
||||
viapm_abort(struct viapm_softc *viapm)
|
||||
{
|
||||
VIAPM_OUTB(SMBHCTRL, SMBHCTRL_KILL);
|
||||
DELAY(10);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
viapm_clear(struct viapm_softc *viapm)
|
||||
{
|
||||
VIAPM_OUTB(SMBHST, SMBHST_FAILED | SMBHST_COLLID |
|
||||
SMBHST_ERROR | SMBHST_INTR);
|
||||
DELAY(10);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
viapm_busy(struct viapm_softc *viapm)
|
||||
{
|
||||
u_char sts;
|
||||
|
||||
sts = VIAPM_INB(SMBHST);
|
||||
|
||||
VIAPM_DEBUG(printf("viapm: idle? STS=0x%x\n", sts));
|
||||
|
||||
return (sts & SMBHST_BUSY);
|
||||
}
|
||||
|
||||
/*
|
||||
* Poll the SMBus controller
|
||||
*/
|
||||
static int
|
||||
viapm_wait(struct viapm_softc *viapm)
|
||||
{
|
||||
int count = 10000;
|
||||
u_char sts = 0;
|
||||
int error;
|
||||
|
||||
/* wait for command to complete and SMBus controller is idle */
|
||||
while(count--) {
|
||||
DELAY(10);
|
||||
sts = VIAPM_INB(SMBHST);
|
||||
|
||||
/* check if the controller is processing a command */
|
||||
if (!(sts & SMBHST_BUSY) && (sts & SMBHST_INTR))
|
||||
break;
|
||||
}
|
||||
|
||||
VIAPM_DEBUG(printf("viapm: SMBHST=0x%x\n", sts));
|
||||
|
||||
error = SMB_ENOERR;
|
||||
|
||||
if (!count)
|
||||
error |= SMB_ETIMEOUT;
|
||||
|
||||
if (sts & SMBHST_FAILED)
|
||||
error |= SMB_EABORT;
|
||||
|
||||
if (sts & SMBHST_COLLID)
|
||||
error |= SMB_ENOACK;
|
||||
|
||||
if (sts & SMBHST_ERROR)
|
||||
error |= SMB_EBUSERR;
|
||||
|
||||
if (error != SMB_ENOERR)
|
||||
viapm_abort(viapm);
|
||||
|
||||
viapm_clear(viapm);
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
viasmb_callback(device_t dev, int index, caddr_t *data)
|
||||
{
|
||||
int error = 0;
|
||||
|
||||
switch (index) {
|
||||
case SMB_REQUEST_BUS:
|
||||
case SMB_RELEASE_BUS:
|
||||
/* ok, bus allocation accepted */
|
||||
break;
|
||||
default:
|
||||
error = EINVAL;
|
||||
}
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
viasmb_quick(device_t dev, u_char slave, int how)
|
||||
{
|
||||
struct viapm_softc *viapm = (struct viapm_softc *)device_get_softc(dev);
|
||||
int error;
|
||||
|
||||
viapm_clear(viapm);
|
||||
if (viapm_busy(viapm))
|
||||
return (EBUSY);
|
||||
|
||||
switch (how) {
|
||||
case SMB_QWRITE:
|
||||
VIAPM_DEBUG(printf("viapm: QWRITE to 0x%x", slave));
|
||||
VIAPM_OUTB(SMBHADDR, slave & ~LSB);
|
||||
break;
|
||||
case SMB_QREAD:
|
||||
VIAPM_DEBUG(printf("viapm: QREAD to 0x%x", slave));
|
||||
VIAPM_OUTB(SMBHADDR, slave | LSB);
|
||||
break;
|
||||
default:
|
||||
panic("%s: unknown QUICK command (%x)!", __FUNCTION__,
|
||||
how);
|
||||
}
|
||||
|
||||
VIAPM_OUTB(SMBHCTRL, SMBHCTRL_START | SMBHCTRL_QUICK);
|
||||
|
||||
error = viapm_wait(viapm);
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
viasmb_sendb(device_t dev, u_char slave, char byte)
|
||||
{
|
||||
struct viapm_softc *viapm = (struct viapm_softc *)device_get_softc(dev);
|
||||
int error;
|
||||
|
||||
viapm_clear(viapm);
|
||||
if (viapm_busy(viapm))
|
||||
return (EBUSY);
|
||||
|
||||
VIAPM_OUTB(SMBHADDR, slave & ~ LSB);
|
||||
VIAPM_OUTB(SMBHCMD, byte);
|
||||
|
||||
VIAPM_OUTB(SMBHCTRL, SMBHCTRL_START | SMBHCTRL_SENDRECV);
|
||||
|
||||
error = viapm_wait(viapm);
|
||||
|
||||
VIAPM_DEBUG(printf("viapm: SENDB to 0x%x, byte=0x%x, error=0x%x\n", slave, byte, error));
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
viasmb_recvb(device_t dev, u_char slave, char *byte)
|
||||
{
|
||||
struct viapm_softc *viapm = (struct viapm_softc *)device_get_softc(dev);
|
||||
int error;
|
||||
|
||||
viapm_clear(viapm);
|
||||
if (viapm_busy(viapm))
|
||||
return (EBUSY);
|
||||
|
||||
VIAPM_OUTB(SMBHADDR, slave | LSB);
|
||||
|
||||
VIAPM_OUTB(SMBHCTRL, SMBHCTRL_START | SMBHCTRL_SENDRECV);
|
||||
|
||||
if ((error = viapm_wait(viapm)) == SMB_ENOERR)
|
||||
*byte = VIAPM_INB(SMBHDATA0);
|
||||
|
||||
VIAPM_DEBUG(printf("viapm: RECVB from 0x%x, byte=0x%x, error=0x%x\n", slave, *byte, error));
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
viasmb_writeb(device_t dev, u_char slave, char cmd, char byte)
|
||||
{
|
||||
struct viapm_softc *viapm = (struct viapm_softc *)device_get_softc(dev);
|
||||
int error;
|
||||
|
||||
viapm_clear(viapm);
|
||||
if (viapm_busy(viapm))
|
||||
return (EBUSY);
|
||||
|
||||
VIAPM_OUTB(SMBHADDR, slave & ~ LSB);
|
||||
VIAPM_OUTB(SMBHCMD, cmd);
|
||||
VIAPM_OUTB(SMBHDATA0, byte);
|
||||
|
||||
VIAPM_OUTB(SMBHCTRL, SMBHCTRL_START | SMBHCTRL_BYTE);
|
||||
|
||||
error = viapm_wait(viapm);
|
||||
|
||||
VIAPM_DEBUG(printf("viapm: WRITEB to 0x%x, cmd=0x%x, byte=0x%x, error=0x%x\n", slave, cmd, byte, error));
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
viasmb_readb(device_t dev, u_char slave, char cmd, char *byte)
|
||||
{
|
||||
struct viapm_softc *viapm = (struct viapm_softc *)device_get_softc(dev);
|
||||
int error;
|
||||
|
||||
viapm_clear(viapm);
|
||||
if (viapm_busy(viapm))
|
||||
return (EBUSY);
|
||||
|
||||
VIAPM_OUTB(SMBHADDR, slave | LSB);
|
||||
VIAPM_OUTB(SMBHCMD, cmd);
|
||||
|
||||
VIAPM_OUTB(SMBHCTRL, SMBHCTRL_START | SMBHCTRL_BYTE);
|
||||
|
||||
if ((error = viapm_wait(viapm)) == SMB_ENOERR)
|
||||
*byte = VIAPM_INB(SMBHDATA0);
|
||||
|
||||
VIAPM_DEBUG(printf("viapm: READB from 0x%x, cmd=0x%x, byte=0x%x, error=0x%x\n", slave, cmd, *byte, error));
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
viasmb_writew(device_t dev, u_char slave, char cmd, short word)
|
||||
{
|
||||
struct viapm_softc *viapm = (struct viapm_softc *)device_get_softc(dev);
|
||||
int error;
|
||||
|
||||
viapm_clear(viapm);
|
||||
if (viapm_busy(viapm))
|
||||
return (EBUSY);
|
||||
|
||||
VIAPM_OUTB(SMBHADDR, slave & ~ LSB);
|
||||
VIAPM_OUTB(SMBHCMD, cmd);
|
||||
VIAPM_OUTB(SMBHDATA0, word & 0x00ff);
|
||||
VIAPM_OUTB(SMBHDATA1, (word & 0xff00) >> 8);
|
||||
|
||||
VIAPM_OUTB(SMBHCTRL, SMBHCTRL_START | SMBHCTRL_WORD);
|
||||
|
||||
error = viapm_wait(viapm);
|
||||
|
||||
VIAPM_DEBUG(printf("viapm: WRITEW to 0x%x, cmd=0x%x, word=0x%x, error=0x%x\n", slave, cmd, word, error));
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
viasmb_readw(device_t dev, u_char slave, char cmd, short *word)
|
||||
{
|
||||
struct viapm_softc *viapm = (struct viapm_softc *)device_get_softc(dev);
|
||||
int error;
|
||||
u_char high, low;
|
||||
|
||||
viapm_clear(viapm);
|
||||
if (viapm_busy(viapm))
|
||||
return (EBUSY);
|
||||
|
||||
VIAPM_OUTB(SMBHADDR, slave | LSB);
|
||||
VIAPM_OUTB(SMBHCMD, cmd);
|
||||
|
||||
VIAPM_OUTB(SMBHCTRL, SMBHCTRL_START | SMBHCTRL_WORD);
|
||||
|
||||
if ((error = viapm_wait(viapm)) == SMB_ENOERR) {
|
||||
low = VIAPM_INB(SMBHDATA0);
|
||||
high = VIAPM_INB(SMBHDATA1);
|
||||
|
||||
*word = ((high & 0xff) << 8) | (low & 0xff);
|
||||
}
|
||||
|
||||
VIAPM_DEBUG(printf("viapm: READW from 0x%x, cmd=0x%x, word=0x%x, error=0x%x\n", slave, cmd, *word, error));
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
viasmb_bwrite(device_t dev, u_char slave, char cmd, u_char count, char *buf)
|
||||
{
|
||||
struct viapm_softc *viapm = (struct viapm_softc *)device_get_softc(dev);
|
||||
u_char remain, len, i;
|
||||
int error = SMB_ENOERR;
|
||||
|
||||
viapm_clear(viapm);
|
||||
if (viapm_busy(viapm))
|
||||
return (EBUSY);
|
||||
|
||||
remain = count;
|
||||
while (remain) {
|
||||
len = min(remain, 32);
|
||||
|
||||
VIAPM_OUTB(SMBHADDR, slave & ~LSB);
|
||||
VIAPM_OUTB(SMBHCMD, cmd);
|
||||
VIAPM_OUTB(SMBHDATA0, len);
|
||||
i = VIAPM_INB(SMBHCTRL);
|
||||
|
||||
/* fill the 32-byte internal buffer */
|
||||
for (i=0; i<len; i++) {
|
||||
VIAPM_OUTB(SMBHBLOCK, buf[count-remain+i]);
|
||||
DELAY(2);
|
||||
}
|
||||
VIAPM_OUTB(SMBHCMD, cmd);
|
||||
VIAPM_OUTB(SMBHCTRL, SMBHCTRL_START | SMBHCTRL_BLOCK);
|
||||
|
||||
if ((error = viapm_wait(viapm)) != SMB_ENOERR)
|
||||
goto error;
|
||||
|
||||
remain -= len;
|
||||
}
|
||||
|
||||
error:
|
||||
VIAPM_DEBUG(printf("viapm: WRITEBLK to 0x%x, count=0x%x, cmd=0x%x, error=0x%x", slave, count, cmd, error));
|
||||
|
||||
return (error);
|
||||
|
||||
}
|
||||
|
||||
static int
|
||||
viasmb_bread(device_t dev, u_char slave, char cmd, u_char count, char *buf)
|
||||
{
|
||||
struct viapm_softc *viapm = (struct viapm_softc *)device_get_softc(dev);
|
||||
u_char remain, len, i;
|
||||
int error = SMB_ENOERR;
|
||||
|
||||
viapm_clear(viapm);
|
||||
if (viapm_busy(viapm))
|
||||
return (EBUSY);
|
||||
|
||||
remain = count;
|
||||
while (remain) {
|
||||
VIAPM_OUTB(SMBHADDR, slave | LSB);
|
||||
VIAPM_OUTB(SMBHCMD, cmd);
|
||||
VIAPM_OUTB(SMBHCTRL, SMBHCTRL_START | SMBHCTRL_BLOCK);
|
||||
|
||||
if ((error = viapm_wait(viapm)) != SMB_ENOERR)
|
||||
goto error;
|
||||
|
||||
len = VIAPM_INB(SMBHDATA0);
|
||||
i = VIAPM_INB(SMBHCTRL); /* reset counter */
|
||||
|
||||
len = min(len, remain);
|
||||
|
||||
/* read the 32-byte internal buffer */
|
||||
for (i=0; i<len; i++) {
|
||||
buf[count-remain+i] = VIAPM_INB(SMBHBLOCK);
|
||||
DELAY(2);
|
||||
}
|
||||
|
||||
remain -= len;
|
||||
}
|
||||
error:
|
||||
VIAPM_DEBUG(printf("viapm: READBLK to 0x%x, count=0x%x, cmd=0x%x, error=0x%x", slave, count, cmd, error));
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
static device_method_t viapm_methods[] = {
|
||||
/* device interface */
|
||||
DEVMETHOD(device_probe, viapm_586b_probe),
|
||||
DEVMETHOD(device_attach, viapm_586b_attach),
|
||||
DEVMETHOD(device_detach, viapm_586b_detach),
|
||||
|
||||
/* iicbb interface */
|
||||
DEVMETHOD(iicbb_callback, viabb_callback),
|
||||
DEVMETHOD(iicbb_setscl, viabb_setscl),
|
||||
DEVMETHOD(iicbb_setsda, viabb_setsda),
|
||||
DEVMETHOD(iicbb_getscl, viabb_getscl),
|
||||
DEVMETHOD(iicbb_getsda, viabb_getsda),
|
||||
DEVMETHOD(iicbb_reset, viabb_reset),
|
||||
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
static driver_t viapm_driver = {
|
||||
"viapm",
|
||||
viapm_methods,
|
||||
sizeof(struct viapm_softc),
|
||||
};
|
||||
|
||||
static device_method_t viapropm_methods[] = {
|
||||
/* device interface */
|
||||
DEVMETHOD(device_probe, viapm_pro_probe),
|
||||
DEVMETHOD(device_attach, viapm_pro_attach),
|
||||
DEVMETHOD(device_detach, viapm_pro_detach),
|
||||
|
||||
/* smbus interface */
|
||||
DEVMETHOD(smbus_callback, viasmb_callback),
|
||||
DEVMETHOD(smbus_quick, viasmb_quick),
|
||||
DEVMETHOD(smbus_sendb, viasmb_sendb),
|
||||
DEVMETHOD(smbus_recvb, viasmb_recvb),
|
||||
DEVMETHOD(smbus_writeb, viasmb_writeb),
|
||||
DEVMETHOD(smbus_readb, viasmb_readb),
|
||||
DEVMETHOD(smbus_writew, viasmb_writew),
|
||||
DEVMETHOD(smbus_readw, viasmb_readw),
|
||||
DEVMETHOD(smbus_bwrite, viasmb_bwrite),
|
||||
DEVMETHOD(smbus_bread, viasmb_bread),
|
||||
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
static driver_t viapropm_driver = {
|
||||
"viapropm",
|
||||
viapropm_methods,
|
||||
sizeof(struct viapm_softc),
|
||||
};
|
||||
|
||||
DRIVER_MODULE(viapm, pci, viapm_driver, viapm_devclass, 0, 0);
|
||||
DRIVER_MODULE(viapropm, pci, viapropm_driver, viapropm_devclass, 0, 0);
|
||||
|
||||
MODULE_DEPEND(viapm, iicbb, IICBB_MINVER, IICBB_PREFVER, IICBB_MAXVER);
|
||||
MODULE_DEPEND(viapropm, smbus, SMBUS_MINVER, SMBUS_PREFVER, SMBUS_MAXVER);
|
||||
MODULE_VERSION(viapm, 1);
|
Loading…
x
Reference in New Issue
Block a user