summaryrefslogtreecommitdiffstats
path: root/sys/dev/bktr
diff options
context:
space:
mode:
authornsouch <nsouch@FreeBSD.org>2002-03-23 15:49:15 +0000
committernsouch <nsouch@FreeBSD.org>2002-03-23 15:49:15 +0000
commit82395b7295123f4d9a786ebd89495ef101103a61 (patch)
treef78e24d69b8d02162ae886a610fb85cac8989741 /sys/dev/bktr
parent0dcefe7b55beecbfaeba7c0b20e4b1277b781733 (diff)
downloadFreeBSD-src-82395b7295123f4d9a786ebd89495ef101103a61.zip
FreeBSD-src-82395b7295123f4d9a786ebd89495ef101103a61.tar.gz
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
Diffstat (limited to 'sys/dev/bktr')
-rw-r--r--sys/dev/bktr/bktr_i2c.c300
-rw-r--r--sys/dev/bktr/bktr_i2c.h17
-rw-r--r--sys/dev/bktr/bktr_os.c38
-rw-r--r--sys/dev/bktr/bktr_reg.h18
4 files changed, 158 insertions, 215 deletions
diff --git a/sys/dev/bktr/bktr_i2c.c b/sys/dev/bktr/bktr_i2c.c
index 4f61e5c..20342d1 100644
--- a/sys/dev/bktr/bktr_i2c.c
+++ b/sys/dev/bktr/bktr_i2c.c
@@ -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
-
- /* 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);
+ if (!sc->iicbb || !sc->smbus)
+ return ENXIO;
- /* 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);
+ bus_generic_attach(dev);
- /* 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");
+ struct bktr_softc *bktr_sc = (struct bktr_softc *)device_get_softc(dev);
+ struct bktr_i2c_softc *sc = &bktr_sc->i2c_sc;
+ int error = 0;
- return (0);
-}
+ if ((error = bus_generic_detach(dev)))
+ goto error;
-static int
-bti2c_attach(device_t dev)
-{
- struct bti2c_softc *sc = (struct bti2c_softc *)device_get_softc(dev);
+ if (sc->iicbb && (error = device_delete_child(dev, sc->iicbb)))
+ goto error;
- /* 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;
+ if (sc->smbus && (error = device_delete_child(dev, sc->smbus)))
+ goto error;
- return (0);
+error:
+ return (error);
}
-static int
-bti2c_smb_callback(device_t dev, int index, caddr_t *data)
+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;
- 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;
+
+ 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);
- return ( INL(sc,BKTR_I2C_DATA_CTL) & 0x1);
+ 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);
diff --git a/sys/dev/bktr/bktr_i2c.h b/sys/dev/bktr/bktr_i2c.h
index f687e4c..a833351 100644
--- a/sys/dev/bktr/bktr_i2c.h
+++ b/sys/dev/bktr/bktr_i2c.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
@@ -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
diff --git a/sys/dev/bktr/bktr_os.c b/sys/dev/bktr/bktr_os.c
index 0de052f..8cc1368 100644
--- a/sys/dev/bktr/bktr_os.c
+++ b/sys/dev/bktr/bktr_os.c
@@ -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,13 +190,16 @@ 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>
+
+#include "iicbb_if.h"
+#include "smbus_if.h"
#endif
#endif
-
/****************************/
/* *** FreeBSD 4.x code *** */
/****************************/
@@ -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.
diff --git a/sys/dev/bktr/bktr_reg.h b/sys/dev/bktr/bktr_reg.h
index ab9bd6e..874a367 100644
--- a/sys/dev/bktr/bktr_reg.h
+++ b/sys/dev/bktr/bktr_reg.h
@@ -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
OpenPOWER on IntegriCloud