X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fi2c%2Fchips%2Fw83627hf.c;h=697cd438237749e26235daeadd7ef1b2bd0c482c;hb=6a77f38946aaee1cd85eeec6cf4229b204c15071;hp=5c3ade5b6498d4fdcdd1c41918253f2167afacff;hpb=87fc8d1bb10cd459024a742c6a10961fefcef18f;p=linux-2.6.git diff --git a/drivers/i2c/chips/w83627hf.c b/drivers/i2c/chips/w83627hf.c index 5c3ade5b6..697cd4382 100644 --- a/drivers/i2c/chips/w83627hf.c +++ b/drivers/i2c/chips/w83627hf.c @@ -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;