summaryrefslogtreecommitdiffstats
path: root/sys/dev
diff options
context:
space:
mode:
authornsouch <nsouch@FreeBSD.org>1998-10-31 11:37:09 +0000
committernsouch <nsouch@FreeBSD.org>1998-10-31 11:37:09 +0000
commit2ae8dc409583e4ed96ca74b7f4817f015685e45f (patch)
tree6c1dd20e560277a32eb4ff159dc40b87e98b90cc /sys/dev
parent3b006890f16badfe89b25127eb04b14cfc373659 (diff)
downloadFreeBSD-src-2ae8dc409583e4ed96ca74b7f4817f015685e45f.zip
FreeBSD-src-2ae8dc409583e4ed96ca74b7f4817f015685e45f.tar.gz
pcf.c: timeout management added
ppc.c: nsc code improved. Actually, a complete rewrite.
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/pcf/pcf.c137
-rw-r--r--sys/dev/ppc/ppc.c291
-rw-r--r--sys/dev/ppc/ppcreg.h28
3 files changed, 309 insertions, 147 deletions
diff --git a/sys/dev/pcf/pcf.c b/sys/dev/pcf/pcf.c
index bee0e15..771dd30 100644
--- a/sys/dev/pcf/pcf.c
+++ b/sys/dev/pcf/pcf.c
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: pcf.c,v 1.1 1998/09/03 21:01:22 nsouch Exp $
+ * $Id: pcf.c,v 1.2 1998/10/22 05:58:40 bde Exp $
*
*/
#include <sys/param.h>
@@ -41,7 +41,7 @@
#include <dev/iicbus/iiconf.h>
#include "iicbus_if.h"
-#define TIMEOUT 99999 /* XXX */
+#define TIMEOUT 9999 /* XXX */
/* Status bits of S1 register (read only) */
#define nBB 0x01 /* busy when low set/reset by STOP/START*/
@@ -67,13 +67,15 @@
#define SLAVE_TRANSMITTER 0x1
#define SLAVE_RECEIVER 0x2
+#define PCF_DEFAULT_ADDR 0xaa
+
struct pcf_softc {
int pcf_base; /* isa port */
+ u_char pcf_addr; /* interface I2C address */
- int pcf_count;
- int pcf_own_address; /* own address */
int pcf_slave_mode; /* receiver or transmitter */
+ int pcf_started; /* 1 if start condition sent */
device_t iicbus; /* the corresponding iicbus */
};
@@ -103,8 +105,8 @@ static int pcf_probe(device_t);
static int pcf_attach(device_t);
static void pcf_print_child(device_t, device_t);
-static int pcf_repeated_start(device_t, u_char);
-static int pcf_start(device_t, u_char);
+static int pcf_repeated_start(device_t, u_char, int);
+static int pcf_start(device_t, u_char, int);
static int pcf_stop(device_t);
static int pcf_write(device_t, char *, int, int *);
static int pcf_read(device_t, char *, int, int *);
@@ -120,6 +122,7 @@ static device_method_t pcf_methods[] = {
DEVMETHOD(bus_print_child, pcf_print_child),
/* iicbus interface */
+ DEVMETHOD(iicbus_callback, iicbus_null_callback),
DEVMETHOD(iicbus_repeated_start, pcf_repeated_start),
DEVMETHOD(iicbus_start, pcf_start),
DEVMETHOD(iicbus_stop, pcf_stop),
@@ -165,6 +168,7 @@ pcfprobe_isa(struct isa_device *dvp)
/* XXX add the pcf device to the root_bus until isa bus exists */
pcfdev = device_add_child(root_bus, "pcf", pcf->pcf_unit, NULL);
+ device_probe_and_attach(pcfdev);
if (!pcfdev)
goto error;
@@ -188,15 +192,20 @@ static int
pcf_probe(device_t pcfdev)
{
struct pcf_softc *pcf = (struct pcf_softc *)device_get_softc(pcfdev);
+ int unit = device_get_unit(pcfdev);
- /* XXX try do detect chipset */
+ /* retrieve base address from isa initialization
+ *
+ * XXX should use ivars with isabus
+ */
+ pcf->pcf_base = pcfdata[unit]->pcf_base;
- device_set_desc(pcfdev, "PCF8584 I2C bus controller");
+ /* reset the chip */
+ pcf_rst_card(pcfdev, IIC_FASTEST, PCF_DEFAULT_ADDR, NULL);
- pcf->iicbus = iicbus_alloc_bus(pcfdev);
+ /* XXX try do detect chipset */
- if (!pcf->iicbus)
- return (EINVAL);
+ device_set_desc(pcfdev, "PCF8584 I2C bus controller");
return (0);
}
@@ -205,13 +214,11 @@ static int
pcf_attach(device_t pcfdev)
{
struct pcf_softc *pcf = (struct pcf_softc *)device_get_softc(pcfdev);
- int unit = device_get_unit(pcfdev);
- /* retrieve base address from isa initialization
- *
- * XXX should use ivars with isabus
- */
- pcf->pcf_base = pcfdata[unit]->pcf_base;
+ pcf->iicbus = iicbus_alloc_bus(pcfdev);
+
+ if (!pcf->iicbus)
+ return (EINVAL);
/* probe and attach the iicbus */
device_probe_and_attach(pcf->iicbus);
@@ -222,8 +229,10 @@ pcf_attach(device_t pcfdev)
static void
pcf_print_child(device_t bus, device_t dev)
{
+ struct pcf_softc *pcf = (struct pcf_softc *)device_get_softc(bus);
+
printf(" on %s%d addr 0x%x", device_get_name(bus),
- device_get_unit(bus), iicbus_get_own_address(dev));
+ device_get_unit(bus), (int)pcf->pcf_addr);
return;
}
@@ -293,13 +302,39 @@ static int pcf_stop(device_t pcfdev)
{
struct pcf_softc *pcf = DEVTOSOFTC(pcfdev);
- /* set stop condition and enable IT */
- PCF_SET_S1(pcf, PIN|ES0|ENI|STO|ACK);
+ /*
+ * Send STOP condition iff the START condition was previously sent.
+ * STOP is sent only once even if a iicbus_stop() is called after
+ * an iicbus_read()... see pcf_read(): the pcf needs to send the stop
+ * before the last char is read.
+ */
+ if (pcf->pcf_started) {
+ /* set stop condition and enable IT */
+ PCF_SET_S1(pcf, PIN|ES0|ENI|STO|ACK);
+
+ pcf->pcf_started = 0;
+ }
return (0);
}
-static int pcf_repeated_start(device_t pcfdev, u_char slave)
+
+static int pcf_noack(struct pcf_softc *pcf, int timeout)
+{
+ int noack;
+ int k = timeout/10;
+
+ do {
+ noack = PCF_GET_S1(pcf) & LRB;
+ if (!noack)
+ break;
+ DELAY(10); /* XXX wait 10 us */
+ } while (k--);
+
+ return (noack);
+}
+
+static int pcf_repeated_start(device_t pcfdev, u_char slave, int timeout)
{
struct pcf_softc *pcf = DEVTOSOFTC(pcfdev);
int error = 0;
@@ -315,8 +350,8 @@ static int pcf_repeated_start(device_t pcfdev, u_char slave)
if ((error = pcf_wait_byte(pcf)))
goto error;
- /* check ACK */
- if (PCF_GET_S1(pcf) & LRB) {
+ /* check for ack */
+ if (pcf_noack(pcf, timeout)) {
error = IIC_ENOACK;
goto error;
}
@@ -328,7 +363,7 @@ error:
return (error);
}
-static int pcf_start(device_t pcfdev, u_char slave)
+static int pcf_start(device_t pcfdev, u_char slave, int timeout)
{
struct pcf_softc *pcf = DEVTOSOFTC(pcfdev);
int error = 0;
@@ -343,12 +378,14 @@ static int pcf_start(device_t pcfdev, u_char slave)
/* START only */
PCF_SET_S1(pcf, PIN|ES0|STA|ACK);
+ pcf->pcf_started = 1;
+
/* wait for address sent, polling */
if ((error = pcf_wait_byte(pcf)))
goto error;
- /* check ACK */
- if (PCF_GET_S1(pcf) & LRB) {
+ /* check for ACK */
+ if (pcf_noack(pcf, timeout)) {
error = IIC_ENOACK;
goto error;
}
@@ -468,19 +505,23 @@ error:
return;
}
-static int pcf_rst_card(device_t pcfdev, u_char speed)
+static int pcf_rst_card(device_t pcfdev, u_char speed, u_char addr, u_char *oldaddr)
{
struct pcf_softc *pcf = DEVTOSOFTC(pcfdev);
- u_char ownaddr;
+
+ if (oldaddr)
+ *oldaddr = pcf->pcf_addr;
/* retrieve own address from bus level */
- if ((ownaddr = iicbus_get_own_address(pcf->iicbus)) == 0)
- ownaddr = 0xaa;
+ if (!addr)
+ pcf->pcf_addr = PCF_DEFAULT_ADDR;
+ else
+ pcf->pcf_addr = addr;
PCF_SET_S1(pcf, PIN); /* initialize S1 */
/* own address S'O<>0 */
- PCF_SET_S0(pcf, ownaddr >> 1);
+ PCF_SET_S0(pcf, pcf->pcf_addr >> 1);
/* select clock register */
PCF_SET_S1(pcf, PIN|ES1);
@@ -511,7 +552,7 @@ static int pcf_rst_card(device_t pcfdev, u_char speed)
}
static int
-pcf_write(device_t pcfdev, char *buf, int len, int *sent)
+pcf_write(device_t pcfdev, char *buf, int len, int *sent, int timeout /* us */)
{
struct pcf_softc *pcf = DEVTOSOFTC(pcfdev);
int bytes, error = 0;
@@ -525,10 +566,12 @@ pcf_write(device_t pcfdev, char *buf, int len, int *sent)
PCF_SET_S0(pcf, *buf++);
+ /* wait for the byte to be send */
if ((error = pcf_wait_byte(pcf)))
goto error;
- if (PCF_GET_S1(pcf) & LRB) {
+ /* check if ack received */
+ if (pcf_noack(pcf, timeout)) {
error = IIC_ENOACK;
goto error;
}
@@ -549,7 +592,8 @@ error:
}
static int
-pcf_read(device_t pcfdev, char *buf, int len, int *read)
+pcf_read(device_t pcfdev, char *buf, int len, int *read, int last,
+ int delay /* us */)
{
struct pcf_softc *pcf = DEVTOSOFTC(pcfdev);
int bytes, error = 0;
@@ -560,7 +604,7 @@ pcf_read(device_t pcfdev, char *buf, int len, int *read)
/* trig the bus to get the first data byte in S0 */
if (len) {
- if (len == 1)
+ if (len == 1 && last)
/* just one byte to read */
PCF_SET_S1(pcf, ES0); /* no ack */
@@ -570,26 +614,25 @@ pcf_read(device_t pcfdev, char *buf, int len, int *read)
bytes = 0;
while (len) {
+ /* XXX delay needed here */
+
+ /* wait for trigged byte */
if ((error = pcf_wait_byte(pcf))) {
pcf_stop(pcfdev);
goto error;
}
- if (len == 1) {
-
- /* ok, last data byte already in S0 */
+ if (len == 1 && last)
+ /* ok, last data byte already in S0, no I2C activity
+ * on next PCF_GET_S0() */
pcf_stop(pcfdev);
- *buf = PCF_GET_S0(pcf);
+ else if (len == 2 && last)
+ /* next trigged byte with no ack */
+ PCF_SET_S1(pcf, ES0);
- } else {
- if (len == 2)
- /* next trigged byte with no ack */
- PCF_SET_S1(pcf, ES0);
-
- /* read last data byte, trig for next data byte */
- *buf++ = PCF_GET_S0(pcf);
- }
+ /* receive byte, trig next byte */
+ *buf++ = PCF_GET_S0(pcf);
len --;
bytes ++;
diff --git a/sys/dev/ppc/ppc.c b/sys/dev/ppc/ppc.c
index 39f4b4e..a22dfb0 100644
--- a/sys/dev/ppc/ppc.c
+++ b/sys/dev/ppc/ppc.c
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: ppc.c,v 1.9 1998/09/20 14:47:01 nsouch Exp $
+ * $Id: ppc.c,v 1.10 1998/10/22 05:58:40 bde Exp $
*
*/
#include "ppc.h"
@@ -61,7 +61,7 @@ static int nppc = 0;
static char *ppc_types[] = {
"SMC-like", "SMC FDC37C665GT", "SMC FDC37C666GT", "PC87332", "PC87306",
- "82091AA", "Generic", "W83877F", "W83877AF", "Winbond", 0
+ "82091AA", "Generic", "W83877F", "W83877AF", "Winbond", "PC87334", 0
};
/* list of available modes */
@@ -221,27 +221,44 @@ ppc_detect_port(struct ppc_data *ppc)
*/
static int pc873xx_basetab[] = {0x0398, 0x026e, 0x015c, 0x002e, 0};
static int pc873xx_porttab[] = {0x0378, 0x03bc, 0x0278, 0};
+static int pc873xx_irqtab[] = {5, 7, 5, 0};
+
+static int pc873xx_regstab[] = {
+ PC873_FER, PC873_FAR, PC873_PTR,
+ PC873_FCR, PC873_PCR, PC873_PMC,
+ PC873_TUP, PC873_SID, PC873_PNP0,
+ PC873_PNP1, PC873_LPTBA, -1
+};
+
+static char *pc873xx_rnametab[] = {
+ "FER", "FAR", "PTR", "FCR", "PCR",
+ "PMC", "TUP", "SID", "PNP0", "PNP1",
+ "LPTBA", NULL
+};
static int
ppc_pc873xx_detect(struct ppc_data *ppc, int chipset_mode) /* XXX mode never forced */
{
static int index = 0;
- int base, idport;
- int val;
+ int base, idport, irq;
+ int ptr, pcr, val, i;
while ((idport = pc873xx_basetab[index++])) {
/* XXX should check first to see if this location is already claimed */
/*
- * Pull the 873xx through the power-on ID cycle (2.2,1.). We can't use this
- * to locate the chip as it may already have been used by the BIOS.
+ * Pull the 873xx through the power-on ID cycle (2.2,1.).
+ * We can't use this to locate the chip as it may already have
+ * been used by the BIOS.
*/
- (void)inb(idport); (void)inb(idport); (void)inb(idport); (void)inb(idport);
+ (void)inb(idport); (void)inb(idport);
+ (void)inb(idport); (void)inb(idport);
/*
* Read the SID byte. Possible values are :
*
+ * 01010xxx PC87334
* 0001xxxx PC87332
* 01110xxx PC87306
*/
@@ -251,14 +268,27 @@ ppc_pc873xx_detect(struct ppc_data *ppc, int chipset_mode) /* XXX mode never for
ppc->ppc_type = NS_PC87332;
} else if ((val & 0xf8) == 0x70) {
ppc->ppc_type = NS_PC87306;
+ } else if ((val & 0xf8) == 0x50) {
+ ppc->ppc_type = NS_PC87334;
} else {
if (bootverbose && (val != 0xff))
printf("PC873xx probe at 0x%x got unknown ID 0x%x\n", idport, val);
continue ; /* not recognised */
}
+
+ /* print registers */
+ if (bootverbose) {
+ printf("PC873xx");
+ for (i=0; pc873xx_regstab[i] != -1; i++) {
+ outb(idport, pc873xx_regstab[i]);
+ printf(" %s=0x%x", pc873xx_rnametab[i],
+ inb(idport + 1) & 0xff);
+ }
+ printf("\n");
+ }
/*
- * We think we have one. Is it enabled and where we want it to be?
+ * We think we have one. Is it enabled and where we want it to be?
*/
outb(idport, PC873_FER);
val = inb(idport + 1);
@@ -276,96 +306,168 @@ ppc_pc873xx_detect(struct ppc_data *ppc, int chipset_mode) /* XXX mode never for
pc873xx_porttab[val], ppc->ppc_base);
continue;
}
+
+ outb(idport, PC873_PTR);
+ ptr = inb(idport + 1);
+
+ /* get irq settings */
+ if (ppc->ppc_base == 0x378)
+ irq = (ptr & PC873_LPTBIRQ7) ? 7 : 5;
+ else
+ irq = pc873xx_irqtab[val];
+
+ if (bootverbose)
+ printf("PC873xx irq %d at 0x%x\n", irq, ppc->ppc_base);
- /*
- * This is the port we want. Can we dink with it to improve
- * our chances?
+ /*
+ * Check if irq settings are correct
*/
- outb(idport, PC873_PTR);
- val = inb(idport + 1);
- if (val & PC873_CFGLOCK) {
- if (bootverbose)
- printf("PC873xx locked\n");
-
- /* work out what mode we're in */
- ppc->ppc_avm |= PPB_NIBBLE; /* worst case */
-
- outb(idport, PC873_PCR);
- val = inb(idport + 1);
- if ((val & PC873_EPPEN) && (val & PC873_EPP19)) {
- outb(idport, PC873_PTR);
- val = inb(idport + 1);
- if (!(val & PC873_EPPRDIR)) {
- ppc->ppc_avm |= PPB_EPP; /* As we would have done it anwyay */
+ if (irq != ppc->ppc_irq) {
+ /*
+ * If the chipset is not locked and base address is 0x378,
+ * we have another chance
+ */
+ if (ppc->ppc_base == 0x378 && !(ptr & PC873_CFGLOCK)) {
+ if (ppc->ppc_irq == 7) {
+ outb(idport + 1, (ptr | PC873_LPTBIRQ7));
+ outb(idport + 1, (ptr | PC873_LPTBIRQ7));
+ } else {
+ outb(idport + 1, (ptr & ~PC873_LPTBIRQ7));
+ outb(idport + 1, (ptr & ~PC873_LPTBIRQ7));
+ }
+ if (bootverbose)
+ printf("PC873xx irq set to %d\n", ppc->ppc_irq);
+ } else {
+ if (bootverbose)
+ printf("PC873xx sorry, can't change irq setting\n");
}
- } else if ((val & PC873_ECPEN) && (val & PC873_ECPCLK)) {
- ppc->ppc_avm |= PPB_PS2; /* tolerable alternative */
- }
} else {
- if (bootverbose)
- printf("PC873xx unlocked, ");
-
-#if 0 /* broken */
- /*
- * Frob the zero-wait-state option if possible; it causes
- * unreliable operation.
- */
- outb(idport, PC873_FCR);
- val = inb(idport + 1);
- if ((ppc->ppc_type == NS_PC87306) || /* we are a '306 */
- !(val & PC873_ZWSPWDN)) { /* or pin _is_ ZWS */
- val &= ~PC873_ZWS;
- outb(idport + 1, val); /* must disable ZWS */
- outb(idport + 1, val);
-
if (bootverbose)
- printf("ZWS %s, ", (val & PC873_ZWS) ? "enabled" : "disabled");
- }
+ printf("PC873xx irq settings are correct\n");
+ }
-#endif
+ outb(idport, PC873_PCR);
+ pcr = inb(idport + 1);
+
+ if ((ptr & PC873_CFGLOCK) || !chipset_mode) {
+ if (bootverbose)
+ printf("PC873xx %s", (ptr & PC873_CFGLOCK)?"locked":"unlocked");
+
+ ppc->ppc_avm |= PPB_NIBBLE;
if (bootverbose)
- printf("reconfiguring for ");
-
- /*
- * if the chip is at 0x3bc, we can't use EPP as there's no room
- * for the extra registers.
- *
- * XXX should we use ECP mode always and use the EPP submode?
- */
- if (ppc->ppc_base != 0x3bc) {
+ printf(", NIBBLE");
+
+ if (pcr & PC873_EPPEN) {
+ ppc->ppc_avm |= PPB_EPP;
+
if (bootverbose)
- printf("EPP 1.9\n");
-
- /* configure for EPP 1.9 operation XXX should be configurable */
- outb(idport, PC873_PCR);
- val = inb(idport + 1);
- val &= ~(PC873_ECPEN | PC873_ECPCLK); /* disable ECP */
- val |= (PC873_EPPEN | PC873_EPP19); /* enable EPP */
- outb(idport + 1, val);
- outb(idport + 1, val);
-
- /* enable automatic direction turnover */
- outb(idport, PC873_PTR);
- val = inb(idport + 1);
- val &= ~PC873_EPPRDIR; /* disable "regular" direction change */
- outb(idport + 1, val);
- outb(idport + 1, val);
+ printf(", EPP");
- /* we are an EPP-32 port */
- ppc->ppc_avm |= PPB_EPP;
- } else {
+ if (pcr & PC873_EPP19)
+ ppc->ppc_epp = EPP_1_9;
+ else
+ ppc->ppc_epp = EPP_1_7;
+
+ if ((ppc->ppc_type == NS_PC87332) && bootverbose) {
+ outb(idport, PC873_PTR);
+ ptr = inb(idport + 1);
+ if (ptr & PC873_EPPRDIR)
+ printf(", Regular mode");
+ else
+ printf(", Automatic mode");
+ }
+ } else if (pcr & PC873_ECPEN) {
+ ppc->ppc_avm |= PPB_ECP;
if (bootverbose)
- printf("ECP\n");
-
- /* configure as an ECP port to get bidirectional operation for now */
- outb(idport, PC873_PCR);
- outb(idport + 1, inb(idport + 1) | PC873_ECPEN | PC873_ECPCLK);
+ printf(", ECP");
- /* we look like a PS/2 port */
- ppc->ppc_avm |= PPB_PS2;
+ if (pcr & PC873_ECPCLK) { /* XXX */
+ ppc->ppc_avm |= PPB_PS2;
+ if (bootverbose)
+ printf(", PS/2");
+ }
+ } else {
+ outb(idport, PC873_PTR);
+ ptr = inb(idport + 1);
+ if (ptr & PC873_EXTENDED) {
+ ppc->ppc_avm |= PPB_SPP;
+ if (bootverbose)
+ printf(", SPP");
+ }
}
+ } else {
+ if (bootverbose)
+ printf("PC873xx unlocked");
+
+ if (chipset_mode & PPB_ECP) {
+ if ((chipset_mode & PPB_EPP) && bootverbose)
+ printf(", ECP+EPP not supported");
+
+ pcr &= ~PC873_EPPEN;
+ pcr |= (PC873_ECPEN | PC873_ECPCLK); /* XXX */
+ outb(idport + 1, pcr);
+ outb(idport + 1, pcr);
+
+ if (bootverbose)
+ printf(", ECP");
+
+ } else if (chipset_mode & PPB_EPP) {
+ pcr &= ~(PC873_ECPEN | PC873_ECPCLK);
+ pcr |= (PC873_EPPEN | PC873_EPP19);
+ outb(idport + 1, pcr);
+ outb(idport + 1, pcr);
+
+ ppc->ppc_epp = EPP_1_9; /* XXX */
+
+ if (bootverbose)
+ printf(", EPP1.9");
+
+ /* enable automatic direction turnover */
+ if (ppc->ppc_type == NS_PC87332) {
+ outb(idport, PC873_PTR);
+ ptr = inb(idport + 1);
+ ptr &= ~PC873_EPPRDIR;
+ outb(idport + 1, ptr);
+ outb(idport + 1, ptr);
+
+ if (bootverbose)
+ printf(", Automatic mode");
+ }
+ } else {
+ pcr &= ~(PC873_ECPEN | PC873_ECPCLK | PC873_EPPEN);
+ outb(idport + 1, pcr);
+ outb(idport + 1, pcr);
+
+ /* configure extended bit in PTR */
+ outb(idport, PC873_PTR);
+ ptr = inb(idport + 1);
+
+ if (chipset_mode & PPB_PS2) {
+ ptr |= PC873_EXTENDED;
+
+ if (bootverbose)
+ printf(", PS/2");
+
+ } else {
+ /* default to NIBBLE mode */
+ ptr &= ~PC873_EXTENDED;
+
+ if (bootverbose)
+ printf(", NIBBLE");
+ }
+ outb(idport + 1, ptr);
+ outb(idport + 1, ptr);
+ }
+
+ ppc->ppc_avm = chipset_mode;
}
+ if (bootverbose)
+ printf("\n");
+
+ ppc->ppc_link.adapter = &ppc_generic_adapter;
+ ppc_generic_setmode(ppc->ppc_unit, chipset_mode);
+
return(chipset_mode);
}
return(-1);
@@ -863,10 +965,18 @@ ppc_detect(struct ppc_data *ppc, int chipset_mode) {
*
* after detection, the port must support running in compatible mode
*/
- for (i=0; chipset_detect[i] != NULL; i++) {
- if ((mode = chipset_detect[i](ppc, chipset_mode)) != -1) {
- ppc->ppc_mode = mode;
- break;
+ if (ppc->ppc_flags & 0x40) {
+ if (bootverbose)
+ printf("ppc: chipset forced to generic\n");
+
+ ppc->ppc_mode = ppc_generic_detect(ppc, chipset_mode);
+
+ } else {
+ for (i=0; chipset_detect[i] != NULL; i++) {
+ if ((mode = chipset_detect[i](ppc, chipset_mode)) != -1) {
+ ppc->ppc_mode = mode;
+ break;
+ }
}
}
@@ -1232,6 +1342,9 @@ ppcprobe(struct isa_device *dvp)
ppc->ppc_unit = dvp->id_unit;
ppc->ppc_type = GENERIC;
+ /* store boot flags */
+ ppc->ppc_flags = dvp->id_flags;
+
ppc->ppc_mode = PPB_COMPATIBLE;
ppc->ppc_epp = (dvp->id_flags & 0x10) >> 4;
@@ -1239,7 +1352,7 @@ ppcprobe(struct isa_device *dvp)
* XXX Try and detect if interrupts are working
*/
if (!(dvp->id_flags & 0x20))
- ppc->ppc_irq = (dvp->id_irq);
+ ppc->ppc_irq = ffs(dvp->id_irq) - 1;
ppcdata[ppc->ppc_unit] = ppc;
nppc ++;
diff --git a/sys/dev/ppc/ppcreg.h b/sys/dev/ppc/ppcreg.h
index fe7e724..af8c9db 100644
--- a/sys/dev/ppc/ppcreg.h
+++ b/sys/dev/ppc/ppcreg.h
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: ppcreg.h,v 1.3 1998/08/03 19:14:33 msmith Exp $
+ * $Id: ppcreg.h,v 1.4 1998/09/13 18:26:44 nsouch Exp $
*
*/
#ifndef __PPCREG_H
@@ -32,16 +32,17 @@
/*
* Parallel Port Chipset type.
*/
-#define SMC_LIKE 0x0
-#define SMC_37C665GT 0x1
-#define SMC_37C666GT 0x2
-#define NS_PC87332 0x3
-#define NS_PC87306 0x4
-#define INTEL_820191AA 0x5 /* XXX not implemented */
-#define GENERIC 0x6
-#define WINB_W83877F 0x7
-#define WINB_W83877AF 0x8
-#define WINB_UNKNOWN 0x9
+#define SMC_LIKE 0
+#define SMC_37C665GT 1
+#define SMC_37C666GT 2
+#define NS_PC87332 3
+#define NS_PC87306 4
+#define INTEL_820191AA 5 /* XXX not implemented */
+#define GENERIC 6
+#define WINB_W83877F 7
+#define WINB_W83877AF 8
+#define WINB_UNKNOWN 9
+#define NS_PC87334 10
/*
* Generic structure to hold parallel port chipset info.
@@ -100,6 +101,8 @@ struct ppc_data {
#define PC873_PTR 0x02
#define PC873_CFGLOCK (1<<6)
#define PC873_EPPRDIR (1<<7)
+#define PC873_EXTENDED (1<<7)
+#define PC873_LPTBIRQ7 (1<<3)
#define PC873_FCR 0x03
#define PC873_ZWS (1<<5)
#define PC873_ZWSPWDN (1<<6)
@@ -111,6 +114,9 @@ struct ppc_data {
#define PC873_PMC 0x06
#define PC873_TUP 0x07
#define PC873_SID 0x08
+#define PC873_PNP0 0x1b
+#define PC873_PNP1 0x1c
+#define PC873_LPTBA 0x19
/*
* Register defines for the SMC FDC37C66xGT parts
OpenPOWER on IntegriCloud