diff options
Diffstat (limited to 'drivers/hwmon')
-rw-r--r-- | drivers/hwmon/w83627hf.c | 76 |
1 files changed, 36 insertions, 40 deletions
diff --git a/drivers/hwmon/w83627hf.c b/drivers/hwmon/w83627hf.c index 3ed67a5cd53c..7738d30a11b8 100644 --- a/drivers/hwmon/w83627hf.c +++ b/drivers/hwmon/w83627hf.c | |||
@@ -48,9 +48,16 @@ | |||
48 | #include <linux/hwmon-vid.h> | 48 | #include <linux/hwmon-vid.h> |
49 | #include <linux/err.h> | 49 | #include <linux/err.h> |
50 | #include <linux/mutex.h> | 50 | #include <linux/mutex.h> |
51 | #include <linux/ioport.h> | ||
51 | #include <asm/io.h> | 52 | #include <asm/io.h> |
52 | #include "lm75.h" | 53 | #include "lm75.h" |
53 | 54 | ||
55 | /* The actual ISA address is read from Super-I/O configuration space */ | ||
56 | static unsigned short address; | ||
57 | |||
58 | #define DRVNAME "w83627hf" | ||
59 | enum chips { w83627hf, w83627thf, w83697hf, w83637hf, w83687thf }; | ||
60 | |||
54 | static u16 force_addr; | 61 | static u16 force_addr; |
55 | module_param(force_addr, ushort, 0); | 62 | module_param(force_addr, ushort, 0); |
56 | MODULE_PARM_DESC(force_addr, | 63 | MODULE_PARM_DESC(force_addr, |
@@ -60,12 +67,6 @@ module_param(force_i2c, byte, 0); | |||
60 | MODULE_PARM_DESC(force_i2c, | 67 | MODULE_PARM_DESC(force_i2c, |
61 | "Initialize the i2c address of the sensors"); | 68 | "Initialize the i2c address of the sensors"); |
62 | 69 | ||
63 | /* The actual ISA address is read from Super-I/O configuration space */ | ||
64 | static unsigned short address; | ||
65 | |||
66 | /* Insmod parameters */ | ||
67 | enum chips { any_chip, w83627hf, w83627thf, w83697hf, w83637hf, w83687thf }; | ||
68 | |||
69 | static int reset; | 70 | static int reset; |
70 | module_param(reset, bool, 0); | 71 | module_param(reset, bool, 0); |
71 | MODULE_PARM_DESC(reset, "Set to one to reset chip on load"); | 72 | MODULE_PARM_DESC(reset, "Set to one to reset chip on load"); |
@@ -298,9 +299,6 @@ struct w83627hf_data { | |||
298 | char valid; /* !=0 if following fields are valid */ | 299 | char valid; /* !=0 if following fields are valid */ |
299 | unsigned long last_updated; /* In jiffies */ | 300 | unsigned long last_updated; /* In jiffies */ |
300 | 301 | ||
301 | struct i2c_client *lm75; /* for secondary I2C addresses */ | ||
302 | /* pointer to array of 2 subclients */ | ||
303 | |||
304 | u8 in[9]; /* Register value */ | 302 | u8 in[9]; /* Register value */ |
305 | u8 in_max[9]; /* Register value */ | 303 | u8 in_max[9]; /* Register value */ |
306 | u8 in_min[9]; /* Register value */ | 304 | u8 in_min[9]; /* Register value */ |
@@ -339,7 +337,7 @@ static void w83627hf_init_client(struct i2c_client *client); | |||
339 | static struct i2c_driver w83627hf_driver = { | 337 | static struct i2c_driver w83627hf_driver = { |
340 | .driver = { | 338 | .driver = { |
341 | .owner = THIS_MODULE, | 339 | .owner = THIS_MODULE, |
342 | .name = "w83627hf", | 340 | .name = DRVNAME, |
343 | }, | 341 | }, |
344 | .attach_adapter = w83627hf_detect, | 342 | .attach_adapter = w83627hf_detect, |
345 | .detach_client = w83627hf_detach_client, | 343 | .detach_client = w83627hf_detach_client, |
@@ -931,6 +929,7 @@ sysfs_sensor(3); | |||
931 | 929 | ||
932 | static int __init w83627hf_find(int sioaddr, unsigned short *addr) | 930 | static int __init w83627hf_find(int sioaddr, unsigned short *addr) |
933 | { | 931 | { |
932 | int err = -ENODEV; | ||
934 | u16 val; | 933 | u16 val; |
935 | 934 | ||
936 | REG = sioaddr; | 935 | REG = sioaddr; |
@@ -943,21 +942,37 @@ static int __init w83627hf_find(int sioaddr, unsigned short *addr) | |||
943 | val != W697_DEVID && | 942 | val != W697_DEVID && |
944 | val != W637_DEVID && | 943 | val != W637_DEVID && |
945 | val != W687THF_DEVID) { | 944 | val != W687THF_DEVID) { |
946 | superio_exit(); | 945 | goto exit; |
947 | return -ENODEV; | ||
948 | } | 946 | } |
949 | 947 | ||
950 | superio_select(W83627HF_LD_HWM); | 948 | superio_select(W83627HF_LD_HWM); |
949 | force_addr &= WINB_ALIGNMENT; | ||
950 | if (force_addr) { | ||
951 | printk(KERN_WARNING DRVNAME ": Forcing address 0x%x\n", | ||
952 | force_addr); | ||
953 | superio_outb(WINB_BASE_REG, force_addr >> 8); | ||
954 | superio_outb(WINB_BASE_REG + 1, force_addr & 0xff); | ||
955 | } | ||
951 | val = (superio_inb(WINB_BASE_REG) << 8) | | 956 | val = (superio_inb(WINB_BASE_REG) << 8) | |
952 | superio_inb(WINB_BASE_REG + 1); | 957 | superio_inb(WINB_BASE_REG + 1); |
953 | *addr = val & WINB_ALIGNMENT; | 958 | *addr = val & WINB_ALIGNMENT; |
954 | if (*addr == 0 && force_addr == 0) { | 959 | if (*addr == 0) { |
955 | superio_exit(); | 960 | printk(KERN_WARNING DRVNAME ": Base address not set, " |
956 | return -ENODEV; | 961 | "skipping\n"); |
962 | goto exit; | ||
963 | } | ||
964 | |||
965 | val = superio_inb(WINB_ACT_REG); | ||
966 | if (!(val & 0x01)) { | ||
967 | printk(KERN_WARNING DRVNAME ": Enabling HWM logical device\n"); | ||
968 | superio_outb(WINB_ACT_REG, val | 0x01); | ||
957 | } | 969 | } |
958 | 970 | ||
971 | err = 0; | ||
972 | |||
973 | exit: | ||
959 | superio_exit(); | 974 | superio_exit(); |
960 | return 0; | 975 | return err; |
961 | } | 976 | } |
962 | 977 | ||
963 | static struct attribute *w83627hf_attributes[] = { | 978 | static struct attribute *w83627hf_attributes[] = { |
@@ -1047,24 +1062,12 @@ static int w83627hf_detect(struct i2c_adapter *adapter) | |||
1047 | int err = 0; | 1062 | int err = 0; |
1048 | const char *client_name = ""; | 1063 | const char *client_name = ""; |
1049 | 1064 | ||
1050 | if(force_addr) | ||
1051 | address = force_addr & WINB_ALIGNMENT; | ||
1052 | |||
1053 | if (!request_region(address + WINB_REGION_OFFSET, WINB_REGION_SIZE, | 1065 | if (!request_region(address + WINB_REGION_OFFSET, WINB_REGION_SIZE, |
1054 | w83627hf_driver.driver.name)) { | 1066 | w83627hf_driver.driver.name)) { |
1055 | err = -EBUSY; | 1067 | err = -EBUSY; |
1056 | goto ERROR0; | 1068 | goto ERROR0; |
1057 | } | 1069 | } |
1058 | 1070 | ||
1059 | if(force_addr) { | ||
1060 | printk("w83627hf.o: forcing ISA address 0x%04X\n", address); | ||
1061 | superio_enter(); | ||
1062 | superio_select(W83627HF_LD_HWM); | ||
1063 | superio_outb(WINB_BASE_REG, address >> 8); | ||
1064 | superio_outb(WINB_BASE_REG+1, address & 0xff); | ||
1065 | superio_exit(); | ||
1066 | } | ||
1067 | |||
1068 | superio_enter(); | 1071 | superio_enter(); |
1069 | val= superio_inb(DEVID); | 1072 | val= superio_inb(DEVID); |
1070 | if(val == W627_DEVID) | 1073 | if(val == W627_DEVID) |
@@ -1082,10 +1085,6 @@ static int w83627hf_detect(struct i2c_adapter *adapter) | |||
1082 | "Unsupported chip (dev_id=0x%02X).\n", val); | 1085 | "Unsupported chip (dev_id=0x%02X).\n", val); |
1083 | goto ERROR1; | 1086 | goto ERROR1; |
1084 | } | 1087 | } |
1085 | |||
1086 | superio_select(W83627HF_LD_HWM); | ||
1087 | if((val = 0x01 & superio_inb(WINB_ACT_REG)) == 0) | ||
1088 | superio_outb(WINB_ACT_REG, 1); | ||
1089 | superio_exit(); | 1088 | superio_exit(); |
1090 | 1089 | ||
1091 | /* OK. For now, we presume we have a valid client. We now create the | 1090 | /* OK. For now, we presume we have a valid client. We now create the |
@@ -1128,8 +1127,6 @@ static int w83627hf_detect(struct i2c_adapter *adapter) | |||
1128 | if ((err = i2c_attach_client(new_client))) | 1127 | if ((err = i2c_attach_client(new_client))) |
1129 | goto ERROR2; | 1128 | goto ERROR2; |
1130 | 1129 | ||
1131 | data->lm75 = NULL; | ||
1132 | |||
1133 | /* Initialize the chip */ | 1130 | /* Initialize the chip */ |
1134 | w83627hf_init_client(new_client); | 1131 | w83627hf_init_client(new_client); |
1135 | 1132 | ||
@@ -1374,7 +1371,7 @@ static void w83627hf_init_client(struct i2c_client *client) | |||
1374 | { | 1371 | { |
1375 | struct w83627hf_data *data = i2c_get_clientdata(client); | 1372 | struct w83627hf_data *data = i2c_get_clientdata(client); |
1376 | int i; | 1373 | int i; |
1377 | int type = data->type; | 1374 | enum chips type = data->type; |
1378 | u8 tmp; | 1375 | u8 tmp; |
1379 | 1376 | ||
1380 | if (reset) { | 1377 | if (reset) { |
@@ -1407,19 +1404,18 @@ static void w83627hf_init_client(struct i2c_client *client) | |||
1407 | w83627hf_write_value(client, W83781D_REG_I2C_ADDR, force_i2c); | 1404 | w83627hf_write_value(client, W83781D_REG_I2C_ADDR, force_i2c); |
1408 | 1405 | ||
1409 | /* Read VID only once */ | 1406 | /* Read VID only once */ |
1410 | if (w83627hf == data->type || w83637hf == data->type) { | 1407 | if (type == w83627hf || type == w83637hf) { |
1411 | int lo = w83627hf_read_value(client, W83781D_REG_VID_FANDIV); | 1408 | int lo = w83627hf_read_value(client, W83781D_REG_VID_FANDIV); |
1412 | int hi = w83627hf_read_value(client, W83781D_REG_CHIPID); | 1409 | int hi = w83627hf_read_value(client, W83781D_REG_CHIPID); |
1413 | data->vid = (lo & 0x0f) | ((hi & 0x01) << 4); | 1410 | data->vid = (lo & 0x0f) | ((hi & 0x01) << 4); |
1414 | } else if (w83627thf == data->type) { | 1411 | } else if (type == w83627thf) { |
1415 | data->vid = w83627thf_read_gpio5(client); | 1412 | data->vid = w83627thf_read_gpio5(client); |
1416 | } else if (w83687thf == data->type) { | 1413 | } else if (type == w83687thf) { |
1417 | data->vid = w83687thf_read_vid(client); | 1414 | data->vid = w83687thf_read_vid(client); |
1418 | } | 1415 | } |
1419 | 1416 | ||
1420 | /* Read VRM & OVT Config only once */ | 1417 | /* Read VRM & OVT Config only once */ |
1421 | if (w83627thf == data->type || w83637hf == data->type | 1418 | if (type == w83627thf || type == w83637hf || type == w83687thf) { |
1422 | || w83687thf == data->type) { | ||
1423 | data->vrm_ovt = | 1419 | data->vrm_ovt = |
1424 | w83627hf_read_value(client, W83627THF_REG_VRM_OVT_CFG); | 1420 | w83627hf_read_value(client, W83627THF_REG_VRM_OVT_CFG); |
1425 | } | 1421 | } |