|
@@ -7,46 +7,47 @@
|
|
#include "ureg.h"
|
|
#include "ureg.h"
|
|
#include "../port/error.h"
|
|
#include "../port/error.h"
|
|
|
|
|
|
-// this driver doesn't implement the management interrupts. we
|
|
|
|
-// leave the LM78 interrupts set to whatever the BIOS did. we do
|
|
|
|
-// allow reading and writing the the readouts and alarm values.
|
|
|
|
-// Read(2)ing or write(2)ing at offset 0x0-0x1f, is
|
|
|
|
-// equivalent to reading or writing lm78 registers 0x20-0x3f.
|
|
|
|
|
|
+/* this driver doesn't implement the management interrupts. we
|
|
|
|
+ * leave the LM78 interrupts set to whatever the BIOS did. we do
|
|
|
|
+ * allow reading and writing the the readouts and alarm values.
|
|
|
|
+ * Read(2)ing or write(2)ing at offset 0x0-0x1f, is
|
|
|
|
+ * equivalent to reading or writing lm78 registers 0x20-0x3f.
|
|
|
|
+ */
|
|
enum
|
|
enum
|
|
{
|
|
{
|
|
- // address of chip on serial interface
|
|
|
|
|
|
+ /* address of chip on serial interface */
|
|
Serialaddr= 0x2d,
|
|
Serialaddr= 0x2d,
|
|
|
|
|
|
- // parallel access registers
|
|
|
|
|
|
+ /* parallel access registers */
|
|
Rpaddr= 0x5,
|
|
Rpaddr= 0x5,
|
|
- Bbusy= (1<<7),
|
|
|
|
|
|
+ Bbusy= (1<<7),
|
|
Rpdata= 0x6,
|
|
Rpdata= 0x6,
|
|
|
|
|
|
- // internal register addresses
|
|
|
|
|
|
+ /* internal register addresses */
|
|
Rconfig= 0x40,
|
|
Rconfig= 0x40,
|
|
- Bstart= (1<<0),
|
|
|
|
- Bsmiena= (1<<1),
|
|
|
|
- Birqena= (1<<2),
|
|
|
|
- Bintclr= (1<<3),
|
|
|
|
- Breset= (1<<4),
|
|
|
|
- Bnmi= (1<<5), // if set, use nmi, else irq
|
|
|
|
- Bpowbypass= (1<<6),
|
|
|
|
- Binit= (1<<7),
|
|
|
|
|
|
+ Bstart= (1<<0),
|
|
|
|
+ Bsmiena= (1<<1),
|
|
|
|
+ Birqena= (1<<2),
|
|
|
|
+ Bintclr= (1<<3),
|
|
|
|
+ Breset= (1<<4),
|
|
|
|
+ Bnmi= (1<<5), /* if set, use nmi, else irq */
|
|
|
|
+ Bpowbypass= (1<<6),
|
|
|
|
+ Binit= (1<<7),
|
|
Ristat1= 0x41,
|
|
Ristat1= 0x41,
|
|
Ristat2= 0x42,
|
|
Ristat2= 0x42,
|
|
Rsmimask1= 0x43,
|
|
Rsmimask1= 0x43,
|
|
Rsmimask2= 0x44,
|
|
Rsmimask2= 0x44,
|
|
Rnmimask1= 0x45,
|
|
Rnmimask1= 0x45,
|
|
Rnmimask2= 0x46,
|
|
Rnmimask2= 0x46,
|
|
- Rvidfan= 0x47, // set fan counter, and read voltage level
|
|
|
|
- Mvid= 0x0f,
|
|
|
|
- Mfan= 0xf0,
|
|
|
|
- Raddr= 0x48, // address used on serial bus
|
|
|
|
- Rresetid= 0x49, // chip reset and ID register
|
|
|
|
- Rpost= 0x00, // start of post ram
|
|
|
|
- Rvalue= 0x20, // start of value ram
|
|
|
|
-
|
|
|
|
- VRsize= 0x20, // size of value ram
|
|
|
|
|
|
+ Rvidfan= 0x47, /* set fan counter, and read voltage level */
|
|
|
|
+ Mvid= 0x0f,
|
|
|
|
+ Mfan= 0xf0,
|
|
|
|
+ Raddr= 0x48, /* address used on serial bus */
|
|
|
|
+ Rresetid= 0x49, /* chip reset and ID register */
|
|
|
|
+ Rpost= 0x00, /* start of post ram */
|
|
|
|
+ Rvalue= 0x20, /* start of value ram */
|
|
|
|
+
|
|
|
|
+ VRsize= 0x20, /* size of value ram */
|
|
};
|
|
};
|
|
|
|
|
|
enum
|
|
enum
|
|
@@ -56,10 +57,10 @@ enum
|
|
};
|
|
};
|
|
|
|
|
|
static Dirtab lm78dir[] = {
|
|
static Dirtab lm78dir[] = {
|
|
- "lm78vram", { Qlm78vram, 0 }, 0, 0444,
|
|
|
|
|
|
+ "lm78vram", { Qlm78vram, 0 }, 0, 0444,
|
|
};
|
|
};
|
|
|
|
|
|
-// interface type
|
|
|
|
|
|
+/* interface type */
|
|
enum
|
|
enum
|
|
{
|
|
{
|
|
None= 0,
|
|
None= 0,
|
|
@@ -70,15 +71,15 @@ enum
|
|
static struct {
|
|
static struct {
|
|
QLock;
|
|
QLock;
|
|
int probed;
|
|
int probed;
|
|
- int ifc; // which interface is connected
|
|
|
|
- SMBus *smbus; // serial interface
|
|
|
|
- int port; // parallel interface
|
|
|
|
|
|
+ int ifc; /* which interface is connected */
|
|
|
|
+ SMBus *smbus; /* serial interface */
|
|
|
|
+ int port; /* parallel interface */
|
|
} lm78;
|
|
} lm78;
|
|
|
|
|
|
extern SMBus* piix4smbus(void);
|
|
extern SMBus* piix4smbus(void);
|
|
|
|
|
|
-// wait for device to become quiescent and then set the
|
|
|
|
-// register address
|
|
|
|
|
|
+/* wait for device to become quiescent and then set the */
|
|
|
|
+/* register address */
|
|
static void
|
|
static void
|
|
setreg(int reg)
|
|
setreg(int reg)
|
|
{
|
|
{
|
|
@@ -92,7 +93,7 @@ setreg(int reg)
|
|
error("lm78 broken");
|
|
error("lm78 broken");
|
|
}
|
|
}
|
|
|
|
|
|
-// routines that actually touch the device
|
|
|
|
|
|
+/* routines that actually touch the device */
|
|
static void
|
|
static void
|
|
lm78wrreg(int reg, uchar val)
|
|
lm78wrreg(int reg, uchar val)
|
|
{
|
|
{
|
|
@@ -149,10 +150,10 @@ lm78rdreg(int reg)
|
|
return val;
|
|
return val;
|
|
}
|
|
}
|
|
|
|
|
|
-// start the chip monitoring but don't change any smi
|
|
|
|
-// interrupts and/or alarms that the BIOS may have set up.
|
|
|
|
-//
|
|
|
|
-// this isn't locked because it's thought to be idempotent
|
|
|
|
|
|
+/* start the chip monitoring but don't change any smi
|
|
|
|
+ * interrupts and/or alarms that the BIOS may have set up.
|
|
|
|
+ * this isn't locked because it's thought to be idempotent
|
|
|
|
+ */
|
|
static void
|
|
static void
|
|
lm78enable(void)
|
|
lm78enable(void)
|
|
{
|
|
{
|
|
@@ -162,12 +163,12 @@ lm78enable(void)
|
|
error(Enodev);
|
|
error(Enodev);
|
|
|
|
|
|
if(lm78.probed == 0){
|
|
if(lm78.probed == 0){
|
|
- // make sure its really there
|
|
|
|
|
|
+ /* make sure its really there */
|
|
if(lm78rdreg(Raddr) != Serialaddr){
|
|
if(lm78rdreg(Raddr) != Serialaddr){
|
|
lm78.ifc = None;
|
|
lm78.ifc = None;
|
|
error(Enodev);
|
|
error(Enodev);
|
|
} else {
|
|
} else {
|
|
- // start the sampling
|
|
|
|
|
|
+ /* start the sampling */
|
|
config = lm78rdreg(Rconfig);
|
|
config = lm78rdreg(Rconfig);
|
|
config = (config | Bstart) & ~(Bintclr|Binit);
|
|
config = (config | Bstart) & ~(Bintclr|Binit);
|
|
lm78wrreg(Rconfig, config);
|
|
lm78wrreg(Rconfig, config);
|
|
@@ -183,13 +184,13 @@ enum
|
|
PiixID= 0x122E,
|
|
PiixID= 0x122E,
|
|
Piix3ID= 0x7000,
|
|
Piix3ID= 0x7000,
|
|
|
|
|
|
- Piix4PMID= 0x7113, // PIIX4 power management function
|
|
|
|
|
|
+ Piix4PMID= 0x7113, /* PIIX4 power management function */
|
|
|
|
|
|
- PCSC= 0x78, // programmable chip select control register
|
|
|
|
|
|
+ PCSC= 0x78, /* programmable chip select control register */
|
|
PCSC8bytes= 0x01,
|
|
PCSC8bytes= 0x01,
|
|
};
|
|
};
|
|
|
|
|
|
-// figure out what kind of interface we could have
|
|
|
|
|
|
+/* figure out what kind of interface we could have */
|
|
void
|
|
void
|
|
lm78reset(void)
|
|
lm78reset(void)
|
|
{
|
|
{
|
|
@@ -200,10 +201,10 @@ lm78reset(void)
|
|
p = nil;
|
|
p = nil;
|
|
while((p = pcimatch(p, IntelVendID, 0)) != nil){
|
|
while((p = pcimatch(p, IntelVendID, 0)) != nil){
|
|
switch(p->did){
|
|
switch(p->did){
|
|
- // these bridges use the PCSC to map the lm78 into port space.
|
|
|
|
- // for this case the lm78's CS# select is connected to the PIIX's
|
|
|
|
- // PCS# output and the bottom 3 bits of address are passed to the
|
|
|
|
- // LM78's A0-A2 inputs.
|
|
|
|
|
|
+ /* these bridges use the PCSC to map the lm78 into port space. */
|
|
|
|
+ /* for this case the lm78's CS# select is connected to the PIIX's */
|
|
|
|
+ /* PCS# output and the bottom 3 bits of address are passed to the */
|
|
|
|
+ /* LM78's A0-A2 inputs. */
|
|
case PiixID:
|
|
case PiixID:
|
|
case Piix3ID:
|
|
case Piix3ID:
|
|
pcs = pcicfgr16(p, PCSC);
|
|
pcs = pcicfgr16(p, PCSC);
|
|
@@ -214,14 +215,14 @@ lm78reset(void)
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
- // enable the chip, use default address 0x50
|
|
|
|
|
|
+ /* enable the chip, use default address 0x50 */
|
|
pcicfgw16(p, PCSC, 0x50|PCSC8bytes);
|
|
pcicfgw16(p, PCSC, 0x50|PCSC8bytes);
|
|
pcs = pcicfgr16(p, PCSC);
|
|
pcs = pcicfgr16(p, PCSC);
|
|
lm78.port = pcs & ~3;
|
|
lm78.port = pcs & ~3;
|
|
lm78.ifc = Parallel;
|
|
lm78.ifc = Parallel;
|
|
return;
|
|
return;
|
|
|
|
|
|
- // this bridge puts the lm78's serial interface on the smbus
|
|
|
|
|
|
+ /* this bridge puts the lm78's serial interface on the smbus */
|
|
case Piix4PMID:
|
|
case Piix4PMID:
|
|
lm78.smbus = piix4smbus();
|
|
lm78.smbus = piix4smbus();
|
|
if(lm78.smbus == nil)
|
|
if(lm78.smbus == nil)
|
|
@@ -233,24 +234,16 @@ lm78reset(void)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
-static Chan*
|
|
|
|
-lm78attach(char* spec)
|
|
|
|
|
|
+Walkqid *
|
|
|
|
+lm78walk(Chan* c, Chan *nc, char** name, int nname)
|
|
{
|
|
{
|
|
- lm78enable();
|
|
|
|
-
|
|
|
|
- return devattach('T', spec);
|
|
|
|
|
|
+ return devwalk(c, nc, name, nname, lm78dir, nelem(lm78dir), devgen);
|
|
}
|
|
}
|
|
|
|
|
|
-int
|
|
|
|
-lm78walk(Chan* c, char* name)
|
|
|
|
-{
|
|
|
|
- return devwalk(c, name, lm78dir, nelem(lm78dir), devgen);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-static void
|
|
|
|
-lm78stat(Chan* c, char* dp)
|
|
|
|
|
|
+static int
|
|
|
|
+lm78stat(Chan* c, uchar* dp, int n)
|
|
{
|
|
{
|
|
- devstat(c, dp, lm78dir, nelem(lm78dir), devgen);
|
|
|
|
|
|
+ return devstat(c, dp, n, lm78dir, nelem(lm78dir), devgen);
|
|
}
|
|
}
|
|
|
|
|
|
static Chan*
|
|
static Chan*
|
|
@@ -277,7 +270,7 @@ lm78read(Chan *c, void *a, long n, vlong offset)
|
|
|
|
|
|
off = offset;
|
|
off = offset;
|
|
|
|
|
|
- switch(c->qid.path & ~CHDIR){
|
|
|
|
|
|
+ switch((ulong)c->qid.path){
|
|
case Qdir:
|
|
case Qdir:
|
|
return devdirread(c, a, n, lm78dir, nelem(lm78dir), devgen);
|
|
return devdirread(c, a, n, lm78dir, nelem(lm78dir), devgen);
|
|
|
|
|
|
@@ -289,7 +282,7 @@ lm78read(Chan *c, void *a, long n, vlong offset)
|
|
e = VRsize;
|
|
e = VRsize;
|
|
for(; off < e; off++)
|
|
for(; off < e; off++)
|
|
*va++ = lm78rdreg(Rvalue+off);
|
|
*va++ = lm78rdreg(Rvalue+off);
|
|
- return va - (uchar*)a;
|
|
|
|
|
|
+ return (int)(va - (uchar*)a);
|
|
}
|
|
}
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
@@ -302,7 +295,7 @@ lm78write(Chan *c, void *a, long n, vlong offset)
|
|
|
|
|
|
off = offset;
|
|
off = offset;
|
|
|
|
|
|
- switch(c->qid.path){
|
|
|
|
|
|
+ switch((ulong)c->qid.path){
|
|
default:
|
|
default:
|
|
error(Eperm);
|
|
error(Eperm);
|
|
|
|
|
|
@@ -319,14 +312,24 @@ lm78write(Chan *c, void *a, long n, vlong offset)
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+extern Dev lm78devtab;
|
|
|
|
+
|
|
|
|
+static Chan*
|
|
|
|
+lm78attach(char* spec)
|
|
|
|
+{
|
|
|
|
+ lm78enable();
|
|
|
|
+
|
|
|
|
+ return devattach(lm78devtab.dc, spec);
|
|
|
|
+}
|
|
|
|
+
|
|
Dev lm78devtab = {
|
|
Dev lm78devtab = {
|
|
'T',
|
|
'T',
|
|
"lm78",
|
|
"lm78",
|
|
|
|
|
|
lm78reset,
|
|
lm78reset,
|
|
devinit,
|
|
devinit,
|
|
|
|
+ devshutdown,
|
|
lm78attach,
|
|
lm78attach,
|
|
- devclone,
|
|
|
|
lm78walk,
|
|
lm78walk,
|
|
lm78stat,
|
|
lm78stat,
|
|
lm78open,
|
|
lm78open,
|