diff options
author | Jean Delvare <khali@linux-fr.org> | 2009-12-09 14:35:54 -0500 |
---|---|---|
committer | Jean Delvare <khali@linux-fr.org> | 2009-12-09 14:35:54 -0500 |
commit | bab2bf44f80a5749fdf69f854247e912353142b2 (patch) | |
tree | bed366085a0e6f5a1cd1404107697b30978e2fb5 /drivers/hwmon/w83781d.c | |
parent | dbe73c8f454a40de06039ec97bc0272f41f1d3c7 (diff) |
hwmon: (w83781d) Clean up detect function
As kind is now hard-coded to -1, there is room for code clean-ups.
Signed-off-by: Jean Delvare <khali@linux-fr.org>
Diffstat (limited to 'drivers/hwmon/w83781d.c')
-rw-r--r-- | drivers/hwmon/w83781d.c | 131 |
1 files changed, 53 insertions, 78 deletions
diff --git a/drivers/hwmon/w83781d.c b/drivers/hwmon/w83781d.c index d27ed1bac002..7ab7967da0a0 100644 --- a/drivers/hwmon/w83781d.c +++ b/drivers/hwmon/w83781d.c | |||
@@ -1054,11 +1054,11 @@ static int | |||
1054 | w83781d_detect(struct i2c_client *client, int kind, | 1054 | w83781d_detect(struct i2c_client *client, int kind, |
1055 | struct i2c_board_info *info) | 1055 | struct i2c_board_info *info) |
1056 | { | 1056 | { |
1057 | int val1 = 0, val2; | 1057 | int val1, val2; |
1058 | struct w83781d_data *isa = w83781d_data_if_isa(); | 1058 | struct w83781d_data *isa = w83781d_data_if_isa(); |
1059 | struct i2c_adapter *adapter = client->adapter; | 1059 | struct i2c_adapter *adapter = client->adapter; |
1060 | int address = client->addr; | 1060 | int address = client->addr; |
1061 | const char *client_name = ""; | 1061 | const char *client_name; |
1062 | enum vendor { winbond, asus } vendid; | 1062 | enum vendor { winbond, asus } vendid; |
1063 | 1063 | ||
1064 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) | 1064 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) |
@@ -1070,98 +1070,73 @@ w83781d_detect(struct i2c_client *client, int kind, | |||
1070 | if (isa) | 1070 | if (isa) |
1071 | mutex_lock(&isa->update_lock); | 1071 | mutex_lock(&isa->update_lock); |
1072 | 1072 | ||
1073 | /* The w8378?d may be stuck in some other bank than bank 0. This may | 1073 | if (i2c_smbus_read_byte_data(client, W83781D_REG_CONFIG) & 0x80) { |
1074 | make reading other information impossible. Specify a force=... or | 1074 | dev_dbg(&adapter->dev, |
1075 | force_*=... parameter, and the Winbond will be reset to the right | 1075 | "Detection of w83781d chip failed at step 3\n"); |
1076 | bank. */ | 1076 | goto err_nodev; |
1077 | if (kind < 0) { | 1077 | } |
1078 | if (i2c_smbus_read_byte_data | 1078 | |
1079 | (client, W83781D_REG_CONFIG) & 0x80) { | 1079 | val1 = i2c_smbus_read_byte_data(client, W83781D_REG_BANK); |
1080 | dev_dbg(&adapter->dev, "Detection of w83781d chip " | 1080 | val2 = i2c_smbus_read_byte_data(client, W83781D_REG_CHIPMAN); |
1081 | "failed at step 3\n"); | 1081 | /* Check for Winbond or Asus ID if in bank 0 */ |
1082 | goto err_nodev; | 1082 | if (!(val1 & 0x07) && |
1083 | } | 1083 | ((!(val1 & 0x80) && val2 != 0xa3 && val2 != 0xc3) || |
1084 | val1 = i2c_smbus_read_byte_data(client, W83781D_REG_BANK); | 1084 | ( (val1 & 0x80) && val2 != 0x5c && val2 != 0x12))) { |
1085 | val2 = i2c_smbus_read_byte_data(client, W83781D_REG_CHIPMAN); | 1085 | dev_dbg(&adapter->dev, |
1086 | /* Check for Winbond or Asus ID if in bank 0 */ | 1086 | "Detection of w83781d chip failed at step 4\n"); |
1087 | if ((!(val1 & 0x07)) && | 1087 | goto err_nodev; |
1088 | (((!(val1 & 0x80)) && (val2 != 0xa3) && (val2 != 0xc3)) | 1088 | } |
1089 | || ((val1 & 0x80) && (val2 != 0x5c) && (val2 != 0x12)))) { | 1089 | /* If Winbond SMBus, check address at 0x48. |
1090 | dev_dbg(&adapter->dev, "Detection of w83781d chip " | 1090 | Asus doesn't support, except for as99127f rev.2 */ |
1091 | "failed at step 4\n"); | 1091 | if ((!(val1 & 0x80) && val2 == 0xa3) || |
1092 | ( (val1 & 0x80) && val2 == 0x5c)) { | ||
1093 | if (i2c_smbus_read_byte_data(client, W83781D_REG_I2C_ADDR) | ||
1094 | != address) { | ||
1095 | dev_dbg(&adapter->dev, | ||
1096 | "Detection of w83781d chip failed at step 5\n"); | ||
1092 | goto err_nodev; | 1097 | goto err_nodev; |
1093 | } | 1098 | } |
1094 | /* If Winbond SMBus, check address at 0x48. | ||
1095 | Asus doesn't support, except for as99127f rev.2 */ | ||
1096 | if ((!(val1 & 0x80) && (val2 == 0xa3)) || | ||
1097 | ((val1 & 0x80) && (val2 == 0x5c))) { | ||
1098 | if (i2c_smbus_read_byte_data | ||
1099 | (client, W83781D_REG_I2C_ADDR) != address) { | ||
1100 | dev_dbg(&adapter->dev, "Detection of w83781d " | ||
1101 | "chip failed at step 5\n"); | ||
1102 | goto err_nodev; | ||
1103 | } | ||
1104 | } | ||
1105 | } | 1099 | } |
1106 | 1100 | ||
1107 | /* We have either had a force parameter, or we have already detected the | 1101 | /* Put it now into bank 0 and Vendor ID High Byte */ |
1108 | Winbond. Put it now into bank 0 and Vendor ID High Byte */ | ||
1109 | i2c_smbus_write_byte_data(client, W83781D_REG_BANK, | 1102 | i2c_smbus_write_byte_data(client, W83781D_REG_BANK, |
1110 | (i2c_smbus_read_byte_data(client, W83781D_REG_BANK) | 1103 | (i2c_smbus_read_byte_data(client, W83781D_REG_BANK) |
1111 | & 0x78) | 0x80); | 1104 | & 0x78) | 0x80); |
1112 | 1105 | ||
1113 | /* Determine the chip type. */ | 1106 | /* Get the vendor ID */ |
1114 | if (kind <= 0) { | 1107 | val2 = i2c_smbus_read_byte_data(client, W83781D_REG_CHIPMAN); |
1115 | /* get vendor ID */ | 1108 | if (val2 == 0x5c) |
1116 | val2 = i2c_smbus_read_byte_data(client, W83781D_REG_CHIPMAN); | 1109 | vendid = winbond; |
1117 | if (val2 == 0x5c) | 1110 | else if (val2 == 0x12) |
1118 | vendid = winbond; | 1111 | vendid = asus; |
1119 | else if (val2 == 0x12) | 1112 | else { |
1120 | vendid = asus; | 1113 | dev_dbg(&adapter->dev, |
1121 | else { | 1114 | "w83781d chip vendor is neither Winbond nor Asus\n"); |
1122 | dev_dbg(&adapter->dev, "w83781d chip vendor is " | 1115 | goto err_nodev; |
1123 | "neither Winbond nor Asus\n"); | ||
1124 | goto err_nodev; | ||
1125 | } | ||
1126 | |||
1127 | val1 = i2c_smbus_read_byte_data(client, W83781D_REG_WCHIPID); | ||
1128 | if ((val1 == 0x10 || val1 == 0x11) && vendid == winbond) | ||
1129 | kind = w83781d; | ||
1130 | else if (val1 == 0x30 && vendid == winbond) | ||
1131 | kind = w83782d; | ||
1132 | else if (val1 == 0x40 && vendid == winbond && address == 0x2d) | ||
1133 | kind = w83783s; | ||
1134 | else if (val1 == 0x31) | ||
1135 | kind = as99127f; | ||
1136 | else { | ||
1137 | if (kind == 0) | ||
1138 | dev_warn(&adapter->dev, "Ignoring 'force' " | ||
1139 | "parameter for unknown chip at " | ||
1140 | "address 0x%02x\n", address); | ||
1141 | goto err_nodev; | ||
1142 | } | ||
1143 | |||
1144 | if ((kind == w83781d || kind == w83782d) | ||
1145 | && w83781d_alias_detect(client, val1)) { | ||
1146 | dev_dbg(&adapter->dev, "Device at 0x%02x appears to " | ||
1147 | "be the same as ISA device\n", address); | ||
1148 | goto err_nodev; | ||
1149 | } | ||
1150 | } | 1116 | } |
1151 | 1117 | ||
1152 | if (isa) | 1118 | /* Determine the chip type. */ |
1153 | mutex_unlock(&isa->update_lock); | 1119 | val1 = i2c_smbus_read_byte_data(client, W83781D_REG_WCHIPID); |
1154 | 1120 | if ((val1 == 0x10 || val1 == 0x11) && vendid == winbond) | |
1155 | if (kind == w83781d) { | ||
1156 | client_name = "w83781d"; | 1121 | client_name = "w83781d"; |
1157 | } else if (kind == w83782d) { | 1122 | else if (val1 == 0x30 && vendid == winbond) |
1158 | client_name = "w83782d"; | 1123 | client_name = "w83782d"; |
1159 | } else if (kind == w83783s) { | 1124 | else if (val1 == 0x40 && vendid == winbond && address == 0x2d) |
1160 | client_name = "w83783s"; | 1125 | client_name = "w83783s"; |
1161 | } else if (kind == as99127f) { | 1126 | else if (val1 == 0x31) |
1162 | client_name = "as99127f"; | 1127 | client_name = "as99127f"; |
1128 | else | ||
1129 | goto err_nodev; | ||
1130 | |||
1131 | if (val1 <= 0x30 && w83781d_alias_detect(client, val1)) { | ||
1132 | dev_dbg(&adapter->dev, "Device at 0x%02x appears to " | ||
1133 | "be the same as ISA device\n", address); | ||
1134 | goto err_nodev; | ||
1163 | } | 1135 | } |
1164 | 1136 | ||
1137 | if (isa) | ||
1138 | mutex_unlock(&isa->update_lock); | ||
1139 | |||
1165 | strlcpy(info->type, client_name, I2C_NAME_SIZE); | 1140 | strlcpy(info->type, client_name, I2C_NAME_SIZE); |
1166 | 1141 | ||
1167 | return 0; | 1142 | return 0; |