diff options
author | Jean Delvare <khali@linux-fr.org> | 2008-07-16 13:30:17 -0400 |
---|---|---|
committer | Jean Delvare <khali@mahadeva.delvare> | 2008-07-16 13:30:17 -0400 |
commit | a7f13a6ec40379fe2116c647ac8e569227ba8d4f (patch) | |
tree | a4f0f7a4b3b23d4ad8eaa032753d1ba2aed79d28 /drivers/hwmon/w83793.c | |
parent | 31d5d275a118527a2b9b0f68613428f176efbb8f (diff) |
hwmon: (w83793) Convert to a new-style i2c driver
The new-style w83793 driver implements the optional detect()
callback to cover the use cases of the legacy driver.
Signed-off-by: Jean Delvare <khali@linux-fr.org>
Diffstat (limited to 'drivers/hwmon/w83793.c')
-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: |