diff options
| -rw-r--r-- | drivers/hwmon/w83793.c | 227 |
1 files changed, 90 insertions, 137 deletions
diff --git a/drivers/hwmon/w83793.c b/drivers/hwmon/w83793.c index ed3c019b78c7..0a739f1c69be 100644 --- a/drivers/hwmon/w83793.c +++ b/drivers/hwmon/w83793.c | |||
| @@ -179,7 +179,6 @@ static inline s8 TEMP_TO_REG(long val, s8 min, s8 max) | |||
| 179 | } | 179 | } |
| 180 | 180 | ||
| 181 | struct w83793_data { | 181 | struct w83793_data { |
| 182 | struct i2c_client client; | ||
| 183 | struct i2c_client *lm75[2]; | 182 | struct i2c_client *lm75[2]; |
| 184 | struct device *hwmon_dev; | 183 | struct device *hwmon_dev; |
| 185 | struct mutex update_lock; | 184 | struct mutex update_lock; |
| @@ -226,19 +225,31 @@ struct w83793_data { | |||
| 226 | 225 | ||
| 227 | static u8 w83793_read_value(struct i2c_client *client, u16 reg); | 226 | static u8 w83793_read_value(struct i2c_client *client, u16 reg); |
| 228 | static int w83793_write_value(struct i2c_client *client, u16 reg, u8 value); | 227 | static int w83793_write_value(struct i2c_client *client, u16 reg, u8 value); |
| 229 | static int w83793_attach_adapter(struct i2c_adapter *adapter); | 228 | static int w83793_probe(struct i2c_client *client, |
| 230 | static int w83793_detect(struct i2c_adapter *adapter, int address, int kind); | 229 | const struct i2c_device_id *id); |
| 231 | static int w83793_detach_client(struct i2c_client *client); | 230 | static int w83793_detect(struct i2c_client *client, int kind, |
| 231 | struct i2c_board_info *info); | ||
| 232 | static int w83793_remove(struct i2c_client *client); | ||
| 232 | static void w83793_init_client(struct i2c_client *client); | 233 | static void w83793_init_client(struct i2c_client *client); |
| 233 | static void w83793_update_nonvolatile(struct device *dev); | 234 | static void w83793_update_nonvolatile(struct device *dev); |
| 234 | static struct w83793_data *w83793_update_device(struct device *dev); | 235 | static struct w83793_data *w83793_update_device(struct device *dev); |
| 235 | 236 | ||
| 237 | static const struct i2c_device_id w83793_id[] = { | ||
| 238 | { "w83793", w83793 }, | ||
| 239 | { } | ||
| 240 | }; | ||
| 241 | MODULE_DEVICE_TABLE(i2c, w83793_id); | ||
| 242 | |||
| 236 | static struct i2c_driver w83793_driver = { | 243 | static struct i2c_driver w83793_driver = { |
| 244 | .class = I2C_CLASS_HWMON, | ||
| 237 | .driver = { | 245 | .driver = { |
| 238 | .name = "w83793", | 246 | .name = "w83793", |
| 239 | }, | 247 | }, |
| 240 | .attach_adapter = w83793_attach_adapter, | 248 | .probe = w83793_probe, |
| 241 | .detach_client = w83793_detach_client, | 249 | .remove = w83793_remove, |
| 250 | .id_table = w83793_id, | ||
| 251 | .detect = w83793_detect, | ||
| 252 | .address_data = &addr_data, | ||
| 242 | }; | 253 | }; |
| 243 | 254 | ||
| 244 | static ssize_t | 255 | static ssize_t |
| @@ -1053,89 +1064,51 @@ static void w83793_init_client(struct i2c_client *client) | |||
| 1053 | 1064 | ||
| 1054 | } | 1065 | } |
| 1055 | 1066 | ||
| 1056 | static int w83793_attach_adapter(struct i2c_adapter *adapter) | 1067 | static int w83793_remove(struct i2c_client *client) |
| 1057 | { | ||
| 1058 | if (!(adapter->class & I2C_CLASS_HWMON)) | ||
| 1059 | return 0; | ||
| 1060 | return i2c_probe(adapter, &addr_data, w83793_detect); | ||
| 1061 | } | ||
| 1062 | |||
| 1063 | static int w83793_detach_client(struct i2c_client *client) | ||
| 1064 | { | 1068 | { |
| 1065 | struct w83793_data *data = i2c_get_clientdata(client); | 1069 | struct w83793_data *data = i2c_get_clientdata(client); |
| 1066 | struct device *dev = &client->dev; | 1070 | struct device *dev = &client->dev; |
| 1067 | int err, i; | 1071 | int i; |
| 1068 | 1072 | ||
| 1069 | /* main client */ | 1073 | hwmon_device_unregister(data->hwmon_dev); |
| 1070 | if (data) { | ||
| 1071 | hwmon_device_unregister(data->hwmon_dev); | ||
| 1072 | 1074 | ||
| 1073 | for (i = 0; i < ARRAY_SIZE(w83793_sensor_attr_2); i++) | 1075 | for (i = 0; i < ARRAY_SIZE(w83793_sensor_attr_2); i++) |
| 1074 | device_remove_file(dev, | 1076 | device_remove_file(dev, |
| 1075 | &w83793_sensor_attr_2[i].dev_attr); | 1077 | &w83793_sensor_attr_2[i].dev_attr); |
| 1076 | 1078 | ||
| 1077 | for (i = 0; i < ARRAY_SIZE(sda_single_files); i++) | 1079 | for (i = 0; i < ARRAY_SIZE(sda_single_files); i++) |
| 1078 | device_remove_file(dev, &sda_single_files[i].dev_attr); | 1080 | device_remove_file(dev, &sda_single_files[i].dev_attr); |
| 1079 | 1081 | ||
| 1080 | for (i = 0; i < ARRAY_SIZE(w83793_vid); i++) | 1082 | for (i = 0; i < ARRAY_SIZE(w83793_vid); i++) |
| 1081 | device_remove_file(dev, &w83793_vid[i].dev_attr); | 1083 | device_remove_file(dev, &w83793_vid[i].dev_attr); |
| 1082 | device_remove_file(dev, &dev_attr_vrm); | 1084 | device_remove_file(dev, &dev_attr_vrm); |
| 1083 | 1085 | ||
| 1084 | for (i = 0; i < ARRAY_SIZE(w83793_left_fan); i++) | 1086 | for (i = 0; i < ARRAY_SIZE(w83793_left_fan); i++) |
| 1085 | device_remove_file(dev, &w83793_left_fan[i].dev_attr); | 1087 | device_remove_file(dev, &w83793_left_fan[i].dev_attr); |
| 1086 | 1088 | ||
| 1087 | for (i = 0; i < ARRAY_SIZE(w83793_left_pwm); i++) | 1089 | for (i = 0; i < ARRAY_SIZE(w83793_left_pwm); i++) |
| 1088 | device_remove_file(dev, &w83793_left_pwm[i].dev_attr); | 1090 | device_remove_file(dev, &w83793_left_pwm[i].dev_attr); |
| 1089 | 1091 | ||
| 1090 | for (i = 0; i < ARRAY_SIZE(w83793_temp); i++) | 1092 | for (i = 0; i < ARRAY_SIZE(w83793_temp); i++) |
| 1091 | device_remove_file(dev, &w83793_temp[i].dev_attr); | 1093 | device_remove_file(dev, &w83793_temp[i].dev_attr); |
| 1092 | } | ||
| 1093 | 1094 | ||
| 1094 | if ((err = i2c_detach_client(client))) | 1095 | if (data->lm75[0] != NULL) |
| 1095 | return err; | 1096 | i2c_unregister_device(data->lm75[0]); |
| 1097 | if (data->lm75[1] != NULL) | ||
| 1098 | i2c_unregister_device(data->lm75[1]); | ||
| 1096 | 1099 | ||
| 1097 | /* main client */ | 1100 | kfree(data); |
| 1098 | if (data) | ||
| 1099 | kfree(data); | ||
| 1100 | /* subclient */ | ||
| 1101 | else | ||
| 1102 | kfree(client); | ||
| 1103 | 1101 | ||
| 1104 | return 0; | 1102 | return 0; |
| 1105 | } | 1103 | } |
| 1106 | 1104 | ||
| 1107 | static int | 1105 | static int |
| 1108 | w83793_create_subclient(struct i2c_adapter *adapter, | 1106 | w83793_detect_subclients(struct i2c_client *client) |
| 1109 | struct i2c_client *client, int addr, | ||
| 1110 | struct i2c_client **sub_cli) | ||
| 1111 | { | ||
| 1112 | int err = 0; | ||
| 1113 | struct i2c_client *sub_client; | ||
| 1114 | |||
| 1115 | (*sub_cli) = sub_client = | ||
| 1116 | kzalloc(sizeof(struct i2c_client), GFP_KERNEL); | ||
| 1117 | if (!(sub_client)) { | ||
| 1118 | return -ENOMEM; | ||
| 1119 | } | ||
| 1120 | sub_client->addr = 0x48 + addr; | ||
| 1121 | i2c_set_clientdata(sub_client, NULL); | ||
| 1122 | sub_client->adapter = adapter; | ||
| 1123 | sub_client->driver = &w83793_driver; | ||
| 1124 | strlcpy(sub_client->name, "w83793 subclient", I2C_NAME_SIZE); | ||
| 1125 | if ((err = i2c_attach_client(sub_client))) { | ||
| 1126 | dev_err(&client->dev, "subclient registration " | ||
| 1127 | "at address 0x%x failed\n", sub_client->addr); | ||
| 1128 | kfree(sub_client); | ||
| 1129 | } | ||
| 1130 | return err; | ||
| 1131 | } | ||
| 1132 | |||
| 1133 | static int | ||
| 1134 | w83793_detect_subclients(struct i2c_adapter *adapter, int address, | ||
| 1135 | int kind, struct i2c_client *client) | ||
| 1136 | { | 1107 | { |
| 1137 | int i, id, err; | 1108 | int i, id, err; |
| 1109 | int address = client->addr; | ||
| 1138 | u8 tmp; | 1110 | u8 tmp; |
| 1111 | struct i2c_adapter *adapter = client->adapter; | ||
| 1139 | struct w83793_data *data = i2c_get_clientdata(client); | 1112 | struct w83793_data *data = i2c_get_clientdata(client); |
| 1140 | 1113 | ||
| 1141 | id = i2c_adapter_id(adapter); | 1114 | id = i2c_adapter_id(adapter); |
| @@ -1158,11 +1131,7 @@ w83793_detect_subclients(struct i2c_adapter *adapter, int address, | |||
| 1158 | 1131 | ||
| 1159 | tmp = w83793_read_value(client, W83793_REG_I2C_SUBADDR); | 1132 | tmp = w83793_read_value(client, W83793_REG_I2C_SUBADDR); |
| 1160 | if (!(tmp & 0x08)) { | 1133 | if (!(tmp & 0x08)) { |
| 1161 | err = | 1134 | data->lm75[0] = i2c_new_dummy(adapter, 0x48 + (tmp & 0x7)); |
| 1162 | w83793_create_subclient(adapter, client, tmp & 0x7, | ||
| 1163 | &data->lm75[0]); | ||
| 1164 | if (err < 0) | ||
| 1165 | goto ERROR_SC_0; | ||
| 1166 | } | 1135 | } |
| 1167 | if (!(tmp & 0x80)) { | 1136 | if (!(tmp & 0x80)) { |
| 1168 | if ((data->lm75[0] != NULL) | 1137 | if ((data->lm75[0] != NULL) |
| @@ -1173,10 +1142,8 @@ w83793_detect_subclients(struct i2c_adapter *adapter, int address, | |||
| 1173 | err = -ENODEV; | 1142 | err = -ENODEV; |
| 1174 | goto ERROR_SC_1; | 1143 | goto ERROR_SC_1; |
| 1175 | } | 1144 | } |
| 1176 | err = w83793_create_subclient(adapter, client, | 1145 | data->lm75[1] = i2c_new_dummy(adapter, |
| 1177 | (tmp >> 4) & 0x7, &data->lm75[1]); | 1146 | 0x48 + ((tmp >> 4) & 0x7)); |
| 1178 | if (err < 0) | ||
| 1179 | goto ERROR_SC_1; | ||
| 1180 | } | 1147 | } |
| 1181 | 1148 | ||
| 1182 | return 0; | 1149 | return 0; |
| @@ -1184,69 +1151,44 @@ w83793_detect_subclients(struct i2c_adapter *adapter, int address, | |||
| 1184 | /* Undo inits in case of errors */ | 1151 | /* Undo inits in case of errors */ |
| 1185 | 1152 | ||
| 1186 | ERROR_SC_1: | 1153 | ERROR_SC_1: |
| 1187 | if (data->lm75[0] != NULL) { | 1154 | if (data->lm75[0] != NULL) |
| 1188 | i2c_detach_client(data->lm75[0]); | 1155 | i2c_unregister_device(data->lm75[0]); |
| 1189 | kfree(data->lm75[0]); | ||
| 1190 | } | ||
| 1191 | ERROR_SC_0: | 1156 | ERROR_SC_0: |
| 1192 | return err; | 1157 | return err; |
| 1193 | } | 1158 | } |
| 1194 | 1159 | ||
| 1195 | static int w83793_detect(struct i2c_adapter *adapter, int address, int kind) | 1160 | /* Return 0 if detection is successful, -ENODEV otherwise */ |
| 1161 | static int w83793_detect(struct i2c_client *client, int kind, | ||
| 1162 | struct i2c_board_info *info) | ||
| 1196 | { | 1163 | { |
| 1197 | int i; | 1164 | u8 tmp, bank; |
| 1198 | u8 tmp, val; | 1165 | struct i2c_adapter *adapter = client->adapter; |
| 1199 | struct i2c_client *client; | 1166 | unsigned short address = client->addr; |
| 1200 | struct device *dev; | ||
| 1201 | struct w83793_data *data; | ||
| 1202 | int files_fan = ARRAY_SIZE(w83793_left_fan) / 7; | ||
| 1203 | int files_pwm = ARRAY_SIZE(w83793_left_pwm) / 5; | ||
| 1204 | int files_temp = ARRAY_SIZE(w83793_temp) / 6; | ||
| 1205 | int err = 0; | ||
| 1206 | 1167 | ||
| 1207 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { | 1168 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { |
| 1208 | goto exit; | 1169 | return -ENODEV; |
| 1209 | } | 1170 | } |
| 1210 | 1171 | ||
| 1211 | /* OK. For now, we presume we have a valid client. We now create the | 1172 | bank = i2c_smbus_read_byte_data(client, W83793_REG_BANKSEL); |
| 1212 | client structure, even though we cannot fill it completely yet. | ||
| 1213 | But it allows us to access w83793_{read,write}_value. */ | ||
| 1214 | |||
| 1215 | if (!(data = kzalloc(sizeof(struct w83793_data), GFP_KERNEL))) { | ||
| 1216 | err = -ENOMEM; | ||
| 1217 | goto exit; | ||
| 1218 | } | ||
| 1219 | |||
| 1220 | client = &data->client; | ||
| 1221 | dev = &client->dev; | ||
| 1222 | i2c_set_clientdata(client, data); | ||
| 1223 | client->addr = address; | ||
| 1224 | client->adapter = adapter; | ||
| 1225 | client->driver = &w83793_driver; | ||
| 1226 | 1173 | ||
| 1227 | data->bank = i2c_smbus_read_byte_data(client, W83793_REG_BANKSEL); | ||
| 1228 | |||
| 1229 | /* Now, we do the remaining detection. */ | ||
| 1230 | if (kind < 0) { | 1174 | if (kind < 0) { |
| 1231 | tmp = data->bank & 0x80 ? 0x5c : 0xa3; | 1175 | tmp = bank & 0x80 ? 0x5c : 0xa3; |
| 1232 | /* Check Winbond vendor ID */ | 1176 | /* Check Winbond vendor ID */ |
| 1233 | if (tmp != i2c_smbus_read_byte_data(client, | 1177 | if (tmp != i2c_smbus_read_byte_data(client, |
| 1234 | W83793_REG_VENDORID)) { | 1178 | W83793_REG_VENDORID)) { |
| 1235 | pr_debug("w83793: Detection failed at check " | 1179 | pr_debug("w83793: Detection failed at check " |
| 1236 | "vendor id\n"); | 1180 | "vendor id\n"); |
| 1237 | err = -ENODEV; | 1181 | return -ENODEV; |
| 1238 | goto free_mem; | ||
| 1239 | } | 1182 | } |
| 1240 | 1183 | ||
| 1241 | /* If Winbond chip, address of chip and W83793_REG_I2C_ADDR | 1184 | /* If Winbond chip, address of chip and W83793_REG_I2C_ADDR |
| 1242 | should match */ | 1185 | should match */ |
| 1243 | if ((data->bank & 0x07) == 0 | 1186 | if ((bank & 0x07) == 0 |
| 1244 | && i2c_smbus_read_byte_data(client, W83793_REG_I2C_ADDR) != | 1187 | && i2c_smbus_read_byte_data(client, W83793_REG_I2C_ADDR) != |
| 1245 | (address << 1)) { | 1188 | (address << 1)) { |
| 1246 | pr_debug("w83793: Detection failed at check " | 1189 | pr_debug("w83793: Detection failed at check " |
| 1247 | "i2c addr\n"); | 1190 | "i2c addr\n"); |
| 1248 | err = -ENODEV; | 1191 | return -ENODEV; |
| 1249 | goto free_mem; | ||
| 1250 | } | 1192 | } |
| 1251 | 1193 | ||
| 1252 | } | 1194 | } |
| @@ -1255,30 +1197,47 @@ static int w83793_detect(struct i2c_adapter *adapter, int address, int kind) | |||
| 1255 | Winbond. Determine the chip type now */ | 1197 | Winbond. Determine the chip type now */ |
| 1256 | 1198 | ||
| 1257 | if (kind <= 0) { | 1199 | if (kind <= 0) { |
| 1258 | if (0x7b == w83793_read_value(client, W83793_REG_CHIPID)) { | 1200 | if (0x7b == i2c_smbus_read_byte_data(client, |
| 1201 | W83793_REG_CHIPID)) { | ||
| 1259 | kind = w83793; | 1202 | kind = w83793; |
| 1260 | } else { | 1203 | } else { |
| 1261 | if (kind == 0) | 1204 | if (kind == 0) |
| 1262 | dev_warn(&adapter->dev, "w83793: Ignoring " | 1205 | dev_warn(&adapter->dev, "w83793: Ignoring " |
| 1263 | "'force' parameter for unknown chip " | 1206 | "'force' parameter for unknown chip " |
| 1264 | "at address 0x%02x\n", address); | 1207 | "at address 0x%02x\n", address); |
| 1265 | err = -ENODEV; | 1208 | return -ENODEV; |
| 1266 | goto free_mem; | ||
| 1267 | } | 1209 | } |
| 1268 | } | 1210 | } |
| 1269 | 1211 | ||
| 1270 | /* Fill in the remaining client fields and put into the global list */ | 1212 | strlcpy(info->type, "w83793", I2C_NAME_SIZE); |
| 1271 | strlcpy(client->name, "w83793", I2C_NAME_SIZE); | 1213 | |
| 1214 | return 0; | ||
| 1215 | } | ||
| 1272 | 1216 | ||
| 1217 | static int w83793_probe(struct i2c_client *client, | ||
| 1218 | const struct i2c_device_id *id) | ||
| 1219 | { | ||
| 1220 | struct device *dev = &client->dev; | ||
| 1221 | struct w83793_data *data; | ||
| 1222 | int i, tmp, val, err; | ||
| 1223 | int files_fan = ARRAY_SIZE(w83793_left_fan) / 7; | ||
| 1224 | int files_pwm = ARRAY_SIZE(w83793_left_pwm) / 5; | ||
| 1225 | int files_temp = ARRAY_SIZE(w83793_temp) / 6; | ||
| 1226 | |||
| 1227 | data = kzalloc(sizeof(struct w83793_data), GFP_KERNEL); | ||
| 1228 | if (!data) { | ||
| 1229 | err = -ENOMEM; | ||
| 1230 | goto exit; | ||
| 1231 | } | ||
| 1232 | |||
| 1233 | i2c_set_clientdata(client, data); | ||
| 1234 | data->bank = i2c_smbus_read_byte_data(client, W83793_REG_BANKSEL); | ||
| 1273 | mutex_init(&data->update_lock); | 1235 | mutex_init(&data->update_lock); |
| 1274 | 1236 | ||
| 1275 | /* Tell the I2C layer a new client has arrived */ | 1237 | err = w83793_detect_subclients(client); |
| 1276 | if ((err = i2c_attach_client(client))) | 1238 | if (err) |
| 1277 | goto free_mem; | 1239 | goto free_mem; |
| 1278 | 1240 | ||
| 1279 | if ((err = w83793_detect_subclients(adapter, address, kind, client))) | ||
| 1280 | goto detach_client; | ||
| 1281 | |||
| 1282 | /* Initialize the chip */ | 1241 | /* Initialize the chip */ |
| 1283 | w83793_init_client(client); | 1242 | w83793_init_client(client); |
| 1284 | 1243 | ||
| @@ -1459,16 +1418,10 @@ exit_remove: | |||
| 1459 | for (i = 0; i < ARRAY_SIZE(w83793_temp); i++) | 1418 | for (i = 0; i < ARRAY_SIZE(w83793_temp); i++) |
| 1460 | device_remove_file(dev, &w83793_temp[i].dev_attr); | 1419 | device_remove_file(dev, &w83793_temp[i].dev_attr); |
| 1461 | 1420 | ||
| 1462 | if (data->lm75[0] != NULL) { | 1421 | if (data->lm75[0] != NULL) |
| 1463 | i2c_detach_client(data->lm75[0]); | 1422 | i2c_unregister_device(data->lm75[0]); |
| 1464 | kfree(data->lm75[0]); | 1423 | if (data->lm75[1] != NULL) |
| 1465 | } | 1424 | i2c_unregister_device(data->lm75[1]); |
| 1466 | if (data->lm75[1] != NULL) { | ||
| 1467 | i2c_detach_client(data->lm75[1]); | ||
| 1468 | kfree(data->lm75[1]); | ||
| 1469 | } | ||
| 1470 | detach_client: | ||
| 1471 | i2c_detach_client(client); | ||
| 1472 | free_mem: | 1425 | free_mem: |
| 1473 | kfree(data); | 1426 | kfree(data); |
| 1474 | exit: | 1427 | exit: |
