aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon/thmc50.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hwmon/thmc50.c')
-rw-r--r--drivers/hwmon/thmc50.c45
1 files changed, 17 insertions, 28 deletions
diff --git a/drivers/hwmon/thmc50.c b/drivers/hwmon/thmc50.c
index 7d97431e132f..7dfb4dec4c5f 100644
--- a/drivers/hwmon/thmc50.c
+++ b/drivers/hwmon/thmc50.c
@@ -35,8 +35,12 @@ MODULE_LICENSE("GPL");
35static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END }; 35static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END };
36 36
37/* Insmod parameters */ 37/* Insmod parameters */
38I2C_CLIENT_INSMOD_2(thmc50, adm1022); 38enum chips { thmc50, adm1022 };
39I2C_CLIENT_MODULE_PARM(adm1022_temp3, "List of adapter,address pairs " 39
40static unsigned short adm1022_temp3[16];
41static unsigned int adm1022_temp3_num;
42module_param_array(adm1022_temp3, ushort, &adm1022_temp3_num, 0);
43MODULE_PARM_DESC(adm1022_temp3, "List of adapter,address pairs "
40 "to enable 3rd temperature (ADM1022 only)"); 44 "to enable 3rd temperature (ADM1022 only)");
41 45
42/* Many THMC50 constants specified below */ 46/* Many THMC50 constants specified below */
@@ -80,7 +84,7 @@ struct thmc50_data {
80 u8 alarms; 84 u8 alarms;
81}; 85};
82 86
83static int thmc50_detect(struct i2c_client *client, int kind, 87static int thmc50_detect(struct i2c_client *client,
84 struct i2c_board_info *info); 88 struct i2c_board_info *info);
85static int thmc50_probe(struct i2c_client *client, 89static int thmc50_probe(struct i2c_client *client,
86 const struct i2c_device_id *id); 90 const struct i2c_device_id *id);
@@ -104,7 +108,7 @@ static struct i2c_driver thmc50_driver = {
104 .remove = thmc50_remove, 108 .remove = thmc50_remove,
105 .id_table = thmc50_id, 109 .id_table = thmc50_id,
106 .detect = thmc50_detect, 110 .detect = thmc50_detect,
107 .address_data = &addr_data, 111 .address_list = normal_i2c,
108}; 112};
109 113
110static ssize_t show_analog_out(struct device *dev, 114static ssize_t show_analog_out(struct device *dev,
@@ -282,14 +286,13 @@ static const struct attribute_group temp3_group = {
282}; 286};
283 287
284/* Return 0 if detection is successful, -ENODEV otherwise */ 288/* Return 0 if detection is successful, -ENODEV otherwise */
285static int thmc50_detect(struct i2c_client *client, int kind, 289static int thmc50_detect(struct i2c_client *client,
286 struct i2c_board_info *info) 290 struct i2c_board_info *info)
287{ 291{
288 unsigned company; 292 unsigned company;
289 unsigned revision; 293 unsigned revision;
290 unsigned config; 294 unsigned config;
291 struct i2c_adapter *adapter = client->adapter; 295 struct i2c_adapter *adapter = client->adapter;
292 int err = 0;
293 const char *type_name; 296 const char *type_name;
294 297
295 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { 298 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
@@ -301,31 +304,13 @@ static int thmc50_detect(struct i2c_client *client, int kind,
301 pr_debug("thmc50: Probing for THMC50 at 0x%2X on bus %d\n", 304 pr_debug("thmc50: Probing for THMC50 at 0x%2X on bus %d\n",
302 client->addr, i2c_adapter_id(client->adapter)); 305 client->addr, i2c_adapter_id(client->adapter));
303 306
304 /* Now, we do the remaining detection. */
305 company = i2c_smbus_read_byte_data(client, THMC50_REG_COMPANY_ID); 307 company = i2c_smbus_read_byte_data(client, THMC50_REG_COMPANY_ID);
306 revision = i2c_smbus_read_byte_data(client, THMC50_REG_DIE_CODE); 308 revision = i2c_smbus_read_byte_data(client, THMC50_REG_DIE_CODE);
307 config = i2c_smbus_read_byte_data(client, THMC50_REG_CONF); 309 config = i2c_smbus_read_byte_data(client, THMC50_REG_CONF);
310 if (revision < 0xc0 || (config & 0x10))
311 return -ENODEV;
308 312
309 if (kind == 0) 313 if (company == 0x41) {
310 kind = thmc50;
311 else if (kind < 0) {
312 err = -ENODEV;
313 if (revision >= 0xc0 && ((config & 0x10) == 0)) {
314 if (company == 0x49) {
315 kind = thmc50;
316 err = 0;
317 } else if (company == 0x41) {
318 kind = adm1022;
319 err = 0;
320 }
321 }
322 }
323 if (err == -ENODEV) {
324 pr_debug("thmc50: Detection of THMC50/ADM1022 failed\n");
325 return err;
326 }
327
328 if (kind == adm1022) {
329 int id = i2c_adapter_id(client->adapter); 314 int id = i2c_adapter_id(client->adapter);
330 int i; 315 int i;
331 316
@@ -340,9 +325,13 @@ static int thmc50_detect(struct i2c_client *client, int kind,
340 config); 325 config);
341 break; 326 break;
342 } 327 }
343 } else { 328 } else if (company == 0x49) {
344 type_name = "thmc50"; 329 type_name = "thmc50";
330 } else {
331 pr_debug("thmc50: Detection of THMC50/ADM1022 failed\n");
332 return -ENODEV;
345 } 333 }
334
346 pr_debug("thmc50: Detected %s (version %x, revision %x)\n", 335 pr_debug("thmc50: Detected %s (version %x, revision %x)\n",
347 type_name, (revision >> 4) - 0xc, revision & 0xf); 336 type_name, (revision >> 4) - 0xc, revision & 0xf);
348 337