vserver 1.9.5.x5
[linux-2.6.git] / drivers / i2c / chips / w83627hf.c
index 5c3ade5..697cd43 100644 (file)
@@ -57,9 +57,7 @@ MODULE_PARM_DESC(force_i2c,
 
 /* Addresses to scan */
 static unsigned short normal_i2c[] = { I2C_CLIENT_END };
-static unsigned short normal_i2c_range[] = { I2C_CLIENT_END };
 static unsigned int normal_isa[] = { 0, I2C_CLIENT_ISA_END };
-static unsigned int normal_isa_range[] = { I2C_CLIENT_ISA_END };
 
 /* Insmod parameters */
 SENSORS_INSMOD_4(w83627hf, w83627thf, w83697hf, w83637hf);
@@ -69,9 +67,9 @@ module_param(init, bool, 0);
 MODULE_PARM_DESC(init, "Set to zero to bypass chip initialization");
 
 /* modified from kernel/include/traps.c */
-#define        REG     0x2e    /* The register to read/write */
+static int REG;                /* The register to read/write */
 #define        DEV     0x07    /* Register: Logical device select */
-#define        VAL     0x2f    /* The value to read/write */
+static int VAL;                /* The value to read/write */
 
 /* logical device numbers for superio_select (below) */
 #define W83627HF_LD_FDC                0x00
@@ -92,9 +90,9 @@ MODULE_PARM_DESC(init, "Set to zero to bypass chip initialization");
 
 #define        DEVID   0x20    /* Register: Device ID */
 
+#define W83627THF_GPIO5_EN     0x30 /* w83627thf only */
 #define W83627THF_GPIO5_IOSR   0xf3 /* w83627thf only */
 #define W83627THF_GPIO5_DR     0xf4 /* w83627thf only */
-#define W83627THF_GPIO5_INVR   0xf5 /* w83627thf only */
 
 static inline void
 superio_outb(int reg, int val)
@@ -369,20 +367,20 @@ store_in_reg(MAX, max)
 static ssize_t \
 show_regs_in_##offset (struct device *dev, char *buf) \
 { \
-        return show_in(dev, buf, 0x##offset); \
+        return show_in(dev, buf, offset); \
 } \
 static DEVICE_ATTR(in##offset##_input, S_IRUGO, show_regs_in_##offset, NULL);
 
 #define sysfs_in_reg_offset(reg, offset) \
 static ssize_t show_regs_in_##reg##offset (struct device *dev, char *buf) \
 { \
-       return show_in_##reg (dev, buf, 0x##offset); \
+       return show_in_##reg (dev, buf, offset); \
 } \
 static ssize_t \
 store_regs_in_##reg##offset (struct device *dev, \
                            const char *buf, size_t count) \
 { \
-       return store_in_##reg (dev, buf, count, 0x##offset); \
+       return store_in_##reg (dev, buf, count, offset); \
 } \
 static DEVICE_ATTR(in##offset##_##reg, S_IRUGO| S_IWUSR, \
                  show_regs_in_##reg##offset, store_regs_in_##reg##offset);
@@ -521,19 +519,19 @@ store_fan_min(struct device *dev, const char *buf, size_t count, int nr)
 #define sysfs_fan_offset(offset) \
 static ssize_t show_regs_fan_##offset (struct device *dev, char *buf) \
 { \
-       return show_fan(dev, buf, 0x##offset); \
+       return show_fan(dev, buf, offset); \
 } \
 static DEVICE_ATTR(fan##offset##_input, S_IRUGO, show_regs_fan_##offset, NULL);
 
 #define sysfs_fan_min_offset(offset) \
 static ssize_t show_regs_fan_min##offset (struct device *dev, char *buf) \
 { \
-       return show_fan_min(dev, buf, 0x##offset); \
+       return show_fan_min(dev, buf, offset); \
 } \
 static ssize_t \
 store_regs_fan_min##offset (struct device *dev, const char *buf, size_t count) \
 { \
-       return store_fan_min(dev, buf, count, 0x##offset); \
+       return store_fan_min(dev, buf, count, offset); \
 } \
 static DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \
                  show_regs_fan_min##offset, store_regs_fan_min##offset);
@@ -595,20 +593,20 @@ store_temp_reg(HYST, max_hyst);
 static ssize_t \
 show_regs_temp_##offset (struct device *dev, char *buf) \
 { \
-       return show_temp(dev, buf, 0x##offset); \
+       return show_temp(dev, buf, offset); \
 } \
 static DEVICE_ATTR(temp##offset##_input, S_IRUGO, show_regs_temp_##offset, NULL);
 
 #define sysfs_temp_reg_offset(reg, offset) \
 static ssize_t show_regs_temp_##reg##offset (struct device *dev, char *buf) \
 { \
-       return show_temp_##reg (dev, buf, 0x##offset); \
+       return show_temp_##reg (dev, buf, offset); \
 } \
 static ssize_t \
 store_regs_temp_##reg##offset (struct device *dev, \
                              const char *buf, size_t count) \
 { \
-       return store_temp_##reg (dev, buf, count, 0x##offset); \
+       return store_temp_##reg (dev, buf, count, offset); \
 } \
 static DEVICE_ATTR(temp##offset##_##reg, S_IRUGO| S_IWUSR, \
                  show_regs_temp_##reg##offset, store_regs_temp_##reg##offset);
@@ -845,7 +843,7 @@ store_regs_pwm_##offset (struct device *dev, const char *buf, size_t count) \
 { \
        return store_pwm_reg(dev, buf, count, offset); \
 } \
-static DEVICE_ATTR(fan##offset##_pwm, S_IRUGO | S_IWUSR, \
+static DEVICE_ATTR(pwm##offset, S_IRUGO | S_IWUSR, \
                  show_regs_pwm_##offset, store_regs_pwm_##offset);
 
 sysfs_pwm(1);
@@ -854,7 +852,7 @@ sysfs_pwm(3);
 
 #define device_create_file_pwm(client, offset) \
 do { \
-device_create_file(&client->dev, &dev_attr_fan##offset##_pwm); \
+device_create_file(&client->dev, &dev_attr_pwm##offset); \
 } while (0)
 
 static ssize_t
@@ -940,10 +938,13 @@ static int w83627hf_attach_adapter(struct i2c_adapter *adapter)
        return i2c_detect(adapter, &addr_data, w83627hf_detect);
 }
 
-static int w83627hf_find(int *address)
+static int w83627hf_find(int sioaddr, int *address)
 {
        u16 val;
 
+       REG = sioaddr;
+       VAL = sioaddr + 1;
+
        superio_enter();
        val= superio_inb(DEVID);
        if(val != W627_DEVID &&
@@ -986,7 +987,7 @@ int w83627hf_detect(struct i2c_adapter *adapter, int address,
        if(force_addr)
                address = force_addr & ~(WINB_EXTENT - 1);
 
-       if (!request_region(address, WINB_EXTENT, "w83627hf")) {
+       if (!request_region(address, WINB_EXTENT, w83627hf_driver.name)) {
                err = -EBUSY;
                goto ERROR0;
        }
@@ -1189,16 +1190,31 @@ static int w83627hf_read_value(struct i2c_client *client, u16 reg)
 
 static int w83627thf_read_gpio5(struct i2c_client *client)
 {
-       struct w83627hf_data *data = i2c_get_clientdata(client);
-       int res, inv;
+       int res = 0xff, sel;
 
-       down(&data->lock);
        superio_enter();
        superio_select(W83627HF_LD_GPIO5);
-       res = superio_inb(W83627THF_GPIO5_DR);
-       inv = superio_inb(W83627THF_GPIO5_INVR);
+
+       /* Make sure these GPIO pins are enabled */
+       if (!(superio_inb(W83627THF_GPIO5_EN) & (1<<3))) {
+               dev_dbg(&client->dev, "GPIO5 disabled, no VID function\n");
+               goto exit;
+       }
+
+       /* Make sure the pins are configured for input
+          There must be at least five (VRM 9), and possibly 6 (VRM 10) */
+       sel = superio_inb(W83627THF_GPIO5_IOSR);
+       if ((sel & 0x1f) != 0x1f) {
+               dev_dbg(&client->dev, "GPIO5 not configured for VID "
+                       "function\n");
+               goto exit;
+       }
+
+       dev_info(&client->dev, "Reading VID from GPIO5\n");
+       res = superio_inb(W83627THF_GPIO5_DR) & sel;
+
+exit:
        superio_exit();
-       up(&data->lock);
        return res;
 }
 
@@ -1271,7 +1287,7 @@ static void w83627hf_init_client(struct i2c_client *client)
                int hi = w83627hf_read_value(client, W83781D_REG_CHIPID);
                data->vid = (lo & 0x0f) | ((hi & 0x01) << 4);
        } else if (w83627thf == data->type) {
-               data->vid = w83627thf_read_gpio5(client) & 0x1f;
+               data->vid = w83627thf_read_gpio5(client) & 0x3f;
        }
 
        /* Read VRM & OVT Config only once */
@@ -1424,7 +1440,8 @@ static int __init sensors_w83627hf_init(void)
 {
        int addr;
 
-       if (w83627hf_find(&addr)) {
+       if (w83627hf_find(0x2e, &addr)
+        && w83627hf_find(0x4e, &addr)) {
                return -ENODEV;
        }
        normal_isa[0] = addr;