/* 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);
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
#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)
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);
#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);
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);
{ \
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);
#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
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 &&
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;
}
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;
}
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 */
{
int addr;
- if (w83627hf_find(&addr)) {
+ if (w83627hf_find(0x2e, &addr)
+ && w83627hf_find(0x4e, &addr)) {
return -ENODEV;
}
normal_isa[0] = addr;