[PATCH] I2C: Improve it87 super-i/o detection

From: Greg KH
Date: Mon Jan 17 2005 - 18:53:04 EST


ChangeSet 1.2329.2.9, 2005/01/14 14:44:10-08:00, khali@xxxxxxxxxxxx

[PATCH] I2C: Improve it87 super-i/o detection

This patch improves the detection of Super-I/O it87 chips (IT8712F,
IT8705F).

* Find the IT8712F and IT8705F address through Super-I/O (as opposed to
IT8712F only so far).

* Verify that the device is activated. Print info lines if a
disactivated or unconfigured chip is found.

* Print an info line when finding either chip, with device name,
address and revision.

* Rearrange code in it87_find() (error path).

* (bonus) Get rid of the useless i2c_client id.

Successfully tested on two IT8712F and one IT8705F, thanks to Jonas
Munsin, Rudolf Marek and Karine Proot.

Signed-off-by: Jean Delvare <khali@xxxxxxxxxxxx>
Signed-off-by: Greg Kroah-Hartman <greg@xxxxxxxxx>


drivers/i2c/chips/it87.c | 53 +++++++++++++++++++++++++++++------------------
1 files changed, 33 insertions(+), 20 deletions(-)


diff -Nru a/drivers/i2c/chips/it87.c b/drivers/i2c/chips/it87.c
--- a/drivers/i2c/chips/it87.c 2005-01-17 13:20:06 -08:00
+++ b/drivers/i2c/chips/it87.c 2005-01-17 13:20:06 -08:00
@@ -56,6 +56,7 @@
#define VAL 0x2f /* The value to read/write */
#define PME 0x04 /* The device with the fan registers in it */
#define DEVID 0x20 /* Register: Device ID */
+#define DEVREV 0x22 /* Register: Device Revision */

static inline int
superio_inb(int reg)
@@ -64,6 +65,16 @@
return inb(VAL);
}

+static int superio_inw(int reg)
+{
+ int val;
+ outb(reg++, REG);
+ val = inb(VAL) << 8;
+ outb(reg, REG);
+ val |= inb(VAL);
+ return val;
+}
+
static inline void
superio_select(void)
{
@@ -87,9 +98,8 @@
outb(0x02, VAL);
}

-/* just IT8712F for now - this should be extended to support the other
- chips as well */
#define IT8712F_DEVID 0x8712
+#define IT8705F_DEVID 0x8705
#define IT87_ACT_REG 0x30
#define IT87_BASE_REG 0x60

@@ -228,8 +238,6 @@
.detach_client = it87_detach_client,
};

-static int it87_id;
-
static ssize_t show_in(struct device *dev, char *buf, int nr)
{
struct it87_data *data = it87_update_device(dev);
@@ -673,25 +681,33 @@
/* SuperIO detection - will change normal_isa[0] if a chip is found */
static int it87_find(int *address)
{
- u16 val;
+ int err = -ENODEV;

superio_enter();
- chip_type = (superio_inb(DEVID) << 8) |
- superio_inb(DEVID + 1);
- if (chip_type != IT8712F_DEVID) {
- superio_exit();
- return -ENODEV;
- }
+ chip_type = superio_inw(DEVID);
+ if (chip_type != IT8712F_DEVID
+ && chip_type != IT8705F_DEVID)
+ goto exit;

superio_select();
- val = (superio_inb(IT87_BASE_REG) << 8) |
- superio_inb(IT87_BASE_REG + 1);
- superio_exit();
- *address = val & ~(IT87_EXTENT - 1);
+ if (!(superio_inb(IT87_ACT_REG) & 0x01)) {
+ pr_info("it87: Device not activated, skipping\n");
+ goto exit;
+ }
+
+ *address = superio_inw(IT87_BASE_REG) & ~(IT87_EXTENT - 1);
if (*address == 0) {
- return -ENODEV;
+ pr_info("it87: Base address not set, skipping\n");
+ goto exit;
}
- return 0;
+
+ err = 0;
+ pr_info("it87: Found IT%04xF chip at 0x%x, revision %d\n",
+ chip_type, *address, superio_inb(DEVREV) & 0x0f);
+
+exit:
+ superio_exit();
+ return err;
}

/* This function is called by i2c_detect */
@@ -800,10 +816,7 @@

/* Fill in the remaining client fields and put it into the global list */
strlcpy(new_client->name, name, I2C_NAME_SIZE);
-
data->type = kind;
-
- new_client->id = it87_id++;
data->valid = 0;
init_MUTEX(&data->update_lock);


-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/