Commit f2e1491e authored by Jean Delvare's avatar Jean Delvare Committed by Greg Kroah-Hartman

[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: default avatarJean Delvare <khali@linux-fr.org>
Signed-off-by: default avatarGreg Kroah-Hartman <greg@kroah.com>
parent f4511def
...@@ -56,6 +56,7 @@ SENSORS_INSMOD_2(it87, it8712); ...@@ -56,6 +56,7 @@ SENSORS_INSMOD_2(it87, it8712);
#define VAL 0x2f /* The value to read/write */ #define VAL 0x2f /* The value to read/write */
#define PME 0x04 /* The device with the fan registers in it */ #define PME 0x04 /* The device with the fan registers in it */
#define DEVID 0x20 /* Register: Device ID */ #define DEVID 0x20 /* Register: Device ID */
#define DEVREV 0x22 /* Register: Device Revision */
static inline int static inline int
superio_inb(int reg) superio_inb(int reg)
...@@ -64,6 +65,16 @@ superio_inb(int reg) ...@@ -64,6 +65,16 @@ superio_inb(int reg)
return inb(VAL); 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 static inline void
superio_select(void) superio_select(void)
{ {
...@@ -87,9 +98,8 @@ superio_exit(void) ...@@ -87,9 +98,8 @@ superio_exit(void)
outb(0x02, VAL); outb(0x02, VAL);
} }
/* just IT8712F for now - this should be extended to support the other
chips as well */
#define IT8712F_DEVID 0x8712 #define IT8712F_DEVID 0x8712
#define IT8705F_DEVID 0x8705
#define IT87_ACT_REG 0x30 #define IT87_ACT_REG 0x30
#define IT87_BASE_REG 0x60 #define IT87_BASE_REG 0x60
...@@ -228,8 +238,6 @@ static struct i2c_driver it87_driver = { ...@@ -228,8 +238,6 @@ static struct i2c_driver it87_driver = {
.detach_client = it87_detach_client, .detach_client = it87_detach_client,
}; };
static int it87_id;
static ssize_t show_in(struct device *dev, char *buf, int nr) static ssize_t show_in(struct device *dev, char *buf, int nr)
{ {
struct it87_data *data = it87_update_device(dev); struct it87_data *data = it87_update_device(dev);
...@@ -673,25 +681,33 @@ static int it87_attach_adapter(struct i2c_adapter *adapter) ...@@ -673,25 +681,33 @@ static int it87_attach_adapter(struct i2c_adapter *adapter)
/* SuperIO detection - will change normal_isa[0] if a chip is found */ /* SuperIO detection - will change normal_isa[0] if a chip is found */
static int it87_find(int *address) static int it87_find(int *address)
{ {
u16 val; int err = -ENODEV;
superio_enter(); superio_enter();
chip_type = (superio_inb(DEVID) << 8) | chip_type = superio_inw(DEVID);
superio_inb(DEVID + 1); if (chip_type != IT8712F_DEVID
if (chip_type != IT8712F_DEVID) { && chip_type != IT8705F_DEVID)
superio_exit(); goto exit;
return -ENODEV;
}
superio_select(); superio_select();
val = (superio_inb(IT87_BASE_REG) << 8) | if (!(superio_inb(IT87_ACT_REG) & 0x01)) {
superio_inb(IT87_BASE_REG + 1); pr_info("it87: Device not activated, skipping\n");
superio_exit(); goto exit;
*address = val & ~(IT87_EXTENT - 1); }
*address = superio_inw(IT87_BASE_REG) & ~(IT87_EXTENT - 1);
if (*address == 0) { 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 */ /* This function is called by i2c_detect */
...@@ -800,10 +816,7 @@ int it87_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -800,10 +816,7 @@ int it87_detect(struct i2c_adapter *adapter, int address, int kind)
/* Fill in the remaining client fields and put it into the global list */ /* Fill in the remaining client fields and put it into the global list */
strlcpy(new_client->name, name, I2C_NAME_SIZE); strlcpy(new_client->name, name, I2C_NAME_SIZE);
data->type = kind; data->type = kind;
new_client->id = it87_id++;
data->valid = 0; data->valid = 0;
init_MUTEX(&data->update_lock); init_MUTEX(&data->update_lock);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment