summaryrefslogtreecommitdiffstats
path: root/sys/dev/ppbus/lpbb.c
diff options
context:
space:
mode:
authornsouch <nsouch@FreeBSD.org>2000-01-14 00:18:06 +0000
committernsouch <nsouch@FreeBSD.org>2000-01-14 00:18:06 +0000
commit59fc142474158cbbfbae06872a4e3efaa40e777f (patch)
tree3dd5303c8a8a1e20337965402c872462f141a217 /sys/dev/ppbus/lpbb.c
parent83719ce7419aa6d99e02f397ba20a42d7406963b (diff)
downloadFreeBSD-src-59fc142474158cbbfbae06872a4e3efaa40e777f.zip
FreeBSD-src-59fc142474158cbbfbae06872a4e3efaa40e777f.tar.gz
Port of ppbus standalone framework to the newbus system.
Note1: the correct interrupt level is invoked correctly for each driver. For this purpose, drivers request the bus before being able to call BUS_SETUP_INTR and BUS_TEARDOWN_INTR call is forced by the ppbus core when drivers release it. Thus, when BUS_SETUP_INTR is called at ppbus driver level, ppbus checks that the caller owns the bus and stores the interrupt handler cookie (in order to unregister it later). Printing is impossible while plip link is up is still TRUE. vpo (ZIP driver) and lpt are make in such a way that using the ZIP and printing concurrently is permitted is also TRUE. Note2: specific chipset detection is not done by default. PPC_PROBE_CHIPSET is now needed to force chipset detection. If set, the flags 0x40 still avoid detection at boot. Port of the pcf(4) driver to the newbus system (was previously directly connected to the rootbus and attached by a bogus pcf_isa_probe function).
Diffstat (limited to 'sys/dev/ppbus/lpbb.c')
-rw-r--r--sys/dev/ppbus/lpbb.c162
1 files changed, 45 insertions, 117 deletions
diff --git a/sys/dev/ppbus/lpbb.c b/sys/dev/ppbus/lpbb.c
index b98f80e2..5b0c75e 100644
--- a/sys/dev/ppbus/lpbb.c
+++ b/sys/dev/ppbus/lpbb.c
@@ -46,19 +46,19 @@
#include <machine/clock.h>
#include <dev/ppbus/ppbconf.h>
+#include "ppbus_if.h"
+#include <dev/ppbus/ppbio.h>
#include <dev/iicbus/iiconf.h>
#include <dev/iicbus/iicbus.h>
#include "iicbb_if.h"
-/* iicbus softc */
struct lpbb_softc {
-
- struct ppb_device lpbb_dev;
+ int dummy;
};
-static int lpbb_detect(struct lpbb_softc *);
+static int lpbb_detect(device_t dev);
static int lpbb_probe(device_t);
static int lpbb_attach(device_t);
@@ -93,38 +93,14 @@ static driver_t lpbb_driver = {
sizeof(struct lpbb_softc),
};
-/*
- * Make ourselves visible as a ppbus driver
- */
-static struct ppb_device *lpbb_ppb_probe(struct ppb_data *ppb);
-static int lpbb_ppb_attach(struct ppb_device *dev);
-
-#define MAXLPBB 8 /* XXX not much better! */
-static struct lpbb_softc *lpbbdata[MAXLPBB];
-static int nlpbb = 0;
-
-#ifdef _KERNEL
-
-static struct ppb_driver lpbbdriver = {
- lpbb_ppb_probe, lpbb_ppb_attach, "lpbb"
-};
-DATA_SET(ppbdriver_set, lpbbdriver);
-
-#endif
-
static int
lpbb_probe(device_t dev)
{
- struct lpbb_softc *sc = lpbbdata[device_get_unit(dev)];
- struct lpbb_softc *scdst = (struct lpbb_softc *)device_get_softc(dev);
-
- /* XXX copy softc. Yet, ppbus device is sc->lpbb_dev, but will be
- * dev->parent when ppbus will be ported to the new bus architecture */
- bcopy(sc, scdst, sizeof(struct lpbb_softc));
+ device_set_desc(dev, "Parallel I2C bit-banging interface");
- device_set_desc(dev, "parallel I2C bit-banging interface");
+ if (!lpbb_detect(dev))
+ return (ENXIO);
- /* probe done by ppbus initialization */
return (0);
}
@@ -147,60 +123,10 @@ lpbb_attach(device_t dev)
return (0);
}
-/*
- * lppbb_ppb_probe()
- */
-static struct ppb_device *
-lpbb_ppb_probe(struct ppb_data *ppb)
-{
- struct lpbb_softc *sc;
-
- sc = (struct lpbb_softc *) malloc(sizeof(struct lpbb_softc),
- M_TEMP, M_NOWAIT);
- if (!sc) {
- printf("lpbb: cannot malloc!\n");
- return (0);
- }
- bzero(sc, sizeof(struct lpbb_softc));
-
- lpbbdata[nlpbb] = sc;
-
- /*
- * ppbus dependent initialisation.
- */
- sc->lpbb_dev.id_unit = nlpbb;
- sc->lpbb_dev.name = lpbbdriver.name;
- sc->lpbb_dev.ppb = ppb;
- sc->lpbb_dev.intr = 0;
-
- if (!lpbb_detect(sc)) {
- free(sc, M_TEMP);
- return (NULL);
- }
-
- /* Ok, go to next device on next probe */
- nlpbb ++;
-
- /* XXX wrong according to new bus architecture. ppbus needs to be
- * ported
- */
- return (&sc->lpbb_dev);
-}
-
-static int
-lpbb_ppb_attach(struct ppb_device *dev)
-{
- /* add the parallel port I2C interface to the bus tree */
- if (!device_add_child(root_bus, "lpbb", dev->id_unit))
- return (0);
-
- return (1);
-}
-
static int
lpbb_callback(device_t dev, int index, caddr_t *data)
{
- struct lpbb_softc *sc = (struct lpbb_softc *)device_get_softc(dev);
+ device_t ppbus = device_get_parent(dev);
int error = 0;
int how;
@@ -208,12 +134,12 @@ lpbb_callback(device_t dev, int index, caddr_t *data)
case IIC_REQUEST_BUS:
/* request the ppbus */
how = *(int *)data;
- error = ppb_request_bus(&sc->lpbb_dev, how);
+ error = ppb_request_bus(ppbus, dev, how);
break;
case IIC_RELEASE_BUS:
/* release the ppbus */
- error = ppb_release_bus(&sc->lpbb_dev);
+ error = ppb_release_bus(ppbus, dev);
break;
default:
@@ -230,49 +156,51 @@ lpbb_callback(device_t dev, int index, caddr_t *data)
#define ALIM 0x20
#define I2CKEY 0x50
-static int getSDA(struct lpbb_softc *sc)
+static int getSDA(device_t ppbus)
{
-if((ppb_rstr(&sc->lpbb_dev)&SDA_in)==SDA_in)
- return 1;
-else
- return 0;
+ if((ppb_rstr(ppbus)&SDA_in)==SDA_in)
+ return 1;
+ else
+ return 0;
}
-static void setSDA(struct lpbb_softc *sc, char val)
+static void setSDA(device_t ppbus, char val)
{
-if(val==0)
- ppb_wdtr(&sc->lpbb_dev, (u_char)SDA_out);
-else
- ppb_wdtr(&sc->lpbb_dev, (u_char)~SDA_out);
+ if(val==0)
+ ppb_wdtr(ppbus, (u_char)SDA_out);
+ else
+ ppb_wdtr(ppbus, (u_char)~SDA_out);
}
-static void setSCL(struct lpbb_softc *sc, unsigned char val)
+static void setSCL(device_t ppbus, unsigned char val)
{
-if(val==0)
- ppb_wctr(&sc->lpbb_dev, (u_char)(ppb_rctr(&sc->lpbb_dev)&~SCL_out));
-else
- ppb_wctr(&sc->lpbb_dev, (u_char)(ppb_rctr(&sc->lpbb_dev)|SCL_out));
+ if(val==0)
+ ppb_wctr(ppbus, (u_char)(ppb_rctr(ppbus)&~SCL_out));
+ else
+ ppb_wctr(ppbus, (u_char)(ppb_rctr(ppbus)|SCL_out));
}
-static int lpbb_detect(struct lpbb_softc *sc)
+static int lpbb_detect(device_t dev)
{
- if (ppb_request_bus(&sc->lpbb_dev, PPB_DONTWAIT)) {
- printf("lpbb: can't allocate ppbus\n");
+ 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(sc, 1);
- setSCL(sc, 1);
+ setSDA(ppbus, 1);
+ setSCL(ppbus, 1);
- if ((ppb_rstr(&sc->lpbb_dev) & I2CKEY) ||
- ((ppb_rstr(&sc->lpbb_dev) & ALIM) != ALIM)) {
+ if ((ppb_rstr(ppbus) & I2CKEY) ||
+ ((ppb_rstr(ppbus) & ALIM) != ALIM)) {
- ppb_release_bus(&sc->lpbb_dev);
+ ppb_release_bus(ppbus, dev);
return (0);
}
- ppb_release_bus(&sc->lpbb_dev);
+ ppb_release_bus(ppbus, dev);
return (1);
}
@@ -280,11 +208,11 @@ static int lpbb_detect(struct lpbb_softc *sc)
static int
lpbb_reset(device_t dev, u_char speed, u_char addr, u_char * oldaddr)
{
- struct lpbb_softc *sc = (struct lpbb_softc *)device_get_softc(dev);
+ device_t ppbus = device_get_parent(dev);
/* reset bus */
- setSDA(sc, 1);
- setSCL(sc, 1);
+ setSDA(ppbus, 1);
+ setSCL(ppbus, 1);
return (IIC_ENOADDR);
}
@@ -292,18 +220,18 @@ lpbb_reset(device_t dev, u_char speed, u_char addr, u_char * oldaddr)
static void
lpbb_setlines(device_t dev, int ctrl, int data)
{
- struct lpbb_softc *sc = (struct lpbb_softc *)device_get_softc(dev);
+ device_t ppbus = device_get_parent(dev);
- setSCL(sc, ctrl);
- setSDA(sc, data);
+ setSCL(ppbus, ctrl);
+ setSDA(ppbus, data);
}
static int
lpbb_getdataline(device_t dev)
{
- struct lpbb_softc *sc = (struct lpbb_softc *)device_get_softc(dev);
+ device_t ppbus = device_get_parent(dev);
- return (getSDA(sc));
+ return (getSDA(ppbus));
}
-DRIVER_MODULE(lpbb, root, lpbb_driver, lpbb_devclass, 0, 0);
+DRIVER_MODULE(lpbb, ppbus, lpbb_driver, lpbb_devclass, 0, 0);
OpenPOWER on IntegriCloud