diff options
author | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
---|---|---|
committer | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
commit | 8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch) | |
tree | a8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /drivers/hwmon/adt7475.c | |
parent | 406089d01562f1e2bf9f089fd7637009ebaad589 (diff) |
Patched in Tegra support.
Diffstat (limited to 'drivers/hwmon/adt7475.c')
-rw-r--r-- | drivers/hwmon/adt7475.c | 133 |
1 files changed, 60 insertions, 73 deletions
diff --git a/drivers/hwmon/adt7475.c b/drivers/hwmon/adt7475.c index 989e54c3925..b5fcd87931c 100644 --- a/drivers/hwmon/adt7475.c +++ b/drivers/hwmon/adt7475.c | |||
@@ -20,7 +20,6 @@ | |||
20 | #include <linux/hwmon-sysfs.h> | 20 | #include <linux/hwmon-sysfs.h> |
21 | #include <linux/hwmon-vid.h> | 21 | #include <linux/hwmon-vid.h> |
22 | #include <linux/err.h> | 22 | #include <linux/err.h> |
23 | #include <linux/jiffies.h> | ||
24 | 23 | ||
25 | /* Indexes for the sysfs hooks */ | 24 | /* Indexes for the sysfs hooks */ |
26 | 25 | ||
@@ -33,10 +32,9 @@ | |||
33 | #define THERM 5 | 32 | #define THERM 5 |
34 | #define HYSTERSIS 6 | 33 | #define HYSTERSIS 6 |
35 | 34 | ||
36 | /* | 35 | /* These are unique identifiers for the sysfs functions - unlike the |
37 | * These are unique identifiers for the sysfs functions - unlike the | 36 | numbers above, these are not also indexes into an array |
38 | * numbers above, these are not also indexes into an array | 37 | */ |
39 | */ | ||
40 | 38 | ||
41 | #define ALARM 9 | 39 | #define ALARM 9 |
42 | #define FAULT 10 | 40 | #define FAULT 10 |
@@ -290,10 +288,8 @@ static void adt7475_write_word(struct i2c_client *client, int reg, u16 val) | |||
290 | i2c_smbus_write_byte_data(client, reg, val & 0xFF); | 288 | i2c_smbus_write_byte_data(client, reg, val & 0xFF); |
291 | } | 289 | } |
292 | 290 | ||
293 | /* | 291 | /* Find the nearest value in a table - used for pwm frequency and |
294 | * Find the nearest value in a table - used for pwm frequency and | 292 | auto temp range */ |
295 | * auto temp range | ||
296 | */ | ||
297 | static int find_nearest(long val, const int *array, int size) | 293 | static int find_nearest(long val, const int *array, int size) |
298 | { | 294 | { |
299 | int i; | 295 | int i; |
@@ -347,7 +343,7 @@ static ssize_t set_voltage(struct device *dev, struct device_attribute *attr, | |||
347 | unsigned char reg; | 343 | unsigned char reg; |
348 | long val; | 344 | long val; |
349 | 345 | ||
350 | if (kstrtol(buf, 10, &val)) | 346 | if (strict_strtol(buf, 10, &val)) |
351 | return -EINVAL; | 347 | return -EINVAL; |
352 | 348 | ||
353 | mutex_lock(&data->lock); | 349 | mutex_lock(&data->lock); |
@@ -389,20 +385,16 @@ static ssize_t show_temp(struct device *dev, struct device_attribute *attr, | |||
389 | out = (out >> 4) & 0xF; | 385 | out = (out >> 4) & 0xF; |
390 | else | 386 | else |
391 | out = (out & 0xF); | 387 | out = (out & 0xF); |
392 | /* | 388 | /* Show the value as an absolute number tied to |
393 | * Show the value as an absolute number tied to | 389 | * THERM */ |
394 | * THERM | ||
395 | */ | ||
396 | out = reg2temp(data, data->temp[THERM][sattr->index]) - | 390 | out = reg2temp(data, data->temp[THERM][sattr->index]) - |
397 | out * 1000; | 391 | out * 1000; |
398 | mutex_unlock(&data->lock); | 392 | mutex_unlock(&data->lock); |
399 | break; | 393 | break; |
400 | 394 | ||
401 | case OFFSET: | 395 | case OFFSET: |
402 | /* | 396 | /* Offset is always 2's complement, regardless of the |
403 | * Offset is always 2's complement, regardless of the | 397 | * setting in CONFIG5 */ |
404 | * setting in CONFIG5 | ||
405 | */ | ||
406 | mutex_lock(&data->lock); | 398 | mutex_lock(&data->lock); |
407 | out = (s8)data->temp[sattr->nr][sattr->index]; | 399 | out = (s8)data->temp[sattr->nr][sattr->index]; |
408 | if (data->config5 & CONFIG5_TEMPOFFSET) | 400 | if (data->config5 & CONFIG5_TEMPOFFSET) |
@@ -440,7 +432,7 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *attr, | |||
440 | int temp; | 432 | int temp; |
441 | long val; | 433 | long val; |
442 | 434 | ||
443 | if (kstrtol(buf, 10, &val)) | 435 | if (strict_strtol(buf, 10, &val)) |
444 | return -EINVAL; | 436 | return -EINVAL; |
445 | 437 | ||
446 | mutex_lock(&data->lock); | 438 | mutex_lock(&data->lock); |
@@ -460,10 +452,8 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *attr, | |||
460 | break; | 452 | break; |
461 | 453 | ||
462 | case HYSTERSIS: | 454 | case HYSTERSIS: |
463 | /* | 455 | /* The value will be given as an absolute value, turn it |
464 | * The value will be given as an absolute value, turn it | 456 | into an offset based on THERM */ |
465 | * into an offset based on THERM | ||
466 | */ | ||
467 | 457 | ||
468 | /* Read fresh THERM and HYSTERSIS values from the chip */ | 458 | /* Read fresh THERM and HYSTERSIS values from the chip */ |
469 | data->temp[THERM][sattr->index] = | 459 | data->temp[THERM][sattr->index] = |
@@ -488,10 +478,8 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *attr, | |||
488 | default: | 478 | default: |
489 | data->temp[sattr->nr][sattr->index] = temp2reg(data, val); | 479 | data->temp[sattr->nr][sattr->index] = temp2reg(data, val); |
490 | 480 | ||
491 | /* | 481 | /* We maintain an extra 2 digits of precision for simplicity |
492 | * We maintain an extra 2 digits of precision for simplicity | 482 | * - shift those back off before writing the value */ |
493 | * - shift those back off before writing the value | ||
494 | */ | ||
495 | out = (u8) (data->temp[sattr->nr][sattr->index] >> 2); | 483 | out = (u8) (data->temp[sattr->nr][sattr->index] >> 2); |
496 | } | 484 | } |
497 | 485 | ||
@@ -526,10 +514,8 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *attr, | |||
526 | return count; | 514 | return count; |
527 | } | 515 | } |
528 | 516 | ||
529 | /* | 517 | /* Table of autorange values - the user will write the value in millidegrees, |
530 | * Table of autorange values - the user will write the value in millidegrees, | 518 | and we'll convert it */ |
531 | * and we'll convert it | ||
532 | */ | ||
533 | static const int autorange_table[] = { | 519 | static const int autorange_table[] = { |
534 | 2000, 2500, 3330, 4000, 5000, 6670, 8000, | 520 | 2000, 2500, 3330, 4000, 5000, 6670, 8000, |
535 | 10000, 13330, 16000, 20000, 26670, 32000, 40000, | 521 | 10000, 13330, 16000, 20000, 26670, 32000, 40000, |
@@ -560,7 +546,7 @@ static ssize_t set_point2(struct device *dev, struct device_attribute *attr, | |||
560 | int temp; | 546 | int temp; |
561 | long val; | 547 | long val; |
562 | 548 | ||
563 | if (kstrtol(buf, 10, &val)) | 549 | if (strict_strtol(buf, 10, &val)) |
564 | return -EINVAL; | 550 | return -EINVAL; |
565 | 551 | ||
566 | mutex_lock(&data->lock); | 552 | mutex_lock(&data->lock); |
@@ -572,10 +558,8 @@ static ssize_t set_point2(struct device *dev, struct device_attribute *attr, | |||
572 | data->range[sattr->index] = | 558 | data->range[sattr->index] = |
573 | adt7475_read(TEMP_TRANGE_REG(sattr->index)); | 559 | adt7475_read(TEMP_TRANGE_REG(sattr->index)); |
574 | 560 | ||
575 | /* | 561 | /* The user will write an absolute value, so subtract the start point |
576 | * The user will write an absolute value, so subtract the start point | 562 | to figure the range */ |
577 | * to figure the range | ||
578 | */ | ||
579 | temp = reg2temp(data, data->temp[AUTOMIN][sattr->index]); | 563 | temp = reg2temp(data, data->temp[AUTOMIN][sattr->index]); |
580 | val = SENSORS_LIMIT(val, temp + autorange_table[0], | 564 | val = SENSORS_LIMIT(val, temp + autorange_table[0], |
581 | temp + autorange_table[ARRAY_SIZE(autorange_table) - 1]); | 565 | temp + autorange_table[ARRAY_SIZE(autorange_table) - 1]); |
@@ -618,7 +602,7 @@ static ssize_t set_tach(struct device *dev, struct device_attribute *attr, | |||
618 | struct adt7475_data *data = i2c_get_clientdata(client); | 602 | struct adt7475_data *data = i2c_get_clientdata(client); |
619 | unsigned long val; | 603 | unsigned long val; |
620 | 604 | ||
621 | if (kstrtoul(buf, 10, &val)) | 605 | if (strict_strtoul(buf, 10, &val)) |
622 | return -EINVAL; | 606 | return -EINVAL; |
623 | 607 | ||
624 | mutex_lock(&data->lock); | 608 | mutex_lock(&data->lock); |
@@ -669,7 +653,7 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, | |||
669 | unsigned char reg = 0; | 653 | unsigned char reg = 0; |
670 | long val; | 654 | long val; |
671 | 655 | ||
672 | if (kstrtol(buf, 10, &val)) | 656 | if (strict_strtol(buf, 10, &val)) |
673 | return -EINVAL; | 657 | return -EINVAL; |
674 | 658 | ||
675 | mutex_lock(&data->lock); | 659 | mutex_lock(&data->lock); |
@@ -680,10 +664,8 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, | |||
680 | data->pwm[CONTROL][sattr->index] = | 664 | data->pwm[CONTROL][sattr->index] = |
681 | adt7475_read(PWM_CONFIG_REG(sattr->index)); | 665 | adt7475_read(PWM_CONFIG_REG(sattr->index)); |
682 | 666 | ||
683 | /* | 667 | /* If we are not in manual mode, then we shouldn't allow |
684 | * If we are not in manual mode, then we shouldn't allow | 668 | * the user to set the pwm speed */ |
685 | * the user to set the pwm speed | ||
686 | */ | ||
687 | if (((data->pwm[CONTROL][sattr->index] >> 5) & 7) != 7) { | 669 | if (((data->pwm[CONTROL][sattr->index] >> 5) & 7) != 7) { |
688 | mutex_unlock(&data->lock); | 670 | mutex_unlock(&data->lock); |
689 | return count; | 671 | return count; |
@@ -776,7 +758,7 @@ static ssize_t set_pwmchan(struct device *dev, struct device_attribute *attr, | |||
776 | int r; | 758 | int r; |
777 | long val; | 759 | long val; |
778 | 760 | ||
779 | if (kstrtol(buf, 10, &val)) | 761 | if (strict_strtol(buf, 10, &val)) |
780 | return -EINVAL; | 762 | return -EINVAL; |
781 | 763 | ||
782 | mutex_lock(&data->lock); | 764 | mutex_lock(&data->lock); |
@@ -799,7 +781,7 @@ static ssize_t set_pwmctrl(struct device *dev, struct device_attribute *attr, | |||
799 | int r; | 781 | int r; |
800 | long val; | 782 | long val; |
801 | 783 | ||
802 | if (kstrtol(buf, 10, &val)) | 784 | if (strict_strtol(buf, 10, &val)) |
803 | return -EINVAL; | 785 | return -EINVAL; |
804 | 786 | ||
805 | mutex_lock(&data->lock); | 787 | mutex_lock(&data->lock); |
@@ -837,7 +819,7 @@ static ssize_t set_pwmfreq(struct device *dev, struct device_attribute *attr, | |||
837 | int out; | 819 | int out; |
838 | long val; | 820 | long val; |
839 | 821 | ||
840 | if (kstrtol(buf, 10, &val)) | 822 | if (strict_strtol(buf, 10, &val)) |
841 | return -EINVAL; | 823 | return -EINVAL; |
842 | 824 | ||
843 | out = find_nearest(val, pwmfreq_table, ARRAY_SIZE(pwmfreq_table)); | 825 | out = find_nearest(val, pwmfreq_table, ARRAY_SIZE(pwmfreq_table)); |
@@ -871,7 +853,7 @@ static ssize_t set_pwm_at_crit(struct device *dev, | |||
871 | struct adt7475_data *data = i2c_get_clientdata(client); | 853 | struct adt7475_data *data = i2c_get_clientdata(client); |
872 | long val; | 854 | long val; |
873 | 855 | ||
874 | if (kstrtol(buf, 10, &val)) | 856 | if (strict_strtol(buf, 10, &val)) |
875 | return -EINVAL; | 857 | return -EINVAL; |
876 | if (val != 0 && val != 1) | 858 | if (val != 0 && val != 1) |
877 | return -EINVAL; | 859 | return -EINVAL; |
@@ -901,7 +883,7 @@ static ssize_t set_vrm(struct device *dev, struct device_attribute *devattr, | |||
901 | struct adt7475_data *data = dev_get_drvdata(dev); | 883 | struct adt7475_data *data = dev_get_drvdata(dev); |
902 | long val; | 884 | long val; |
903 | 885 | ||
904 | if (kstrtol(buf, 10, &val)) | 886 | if (strict_strtol(buf, 10, &val)) |
905 | return -EINVAL; | 887 | return -EINVAL; |
906 | if (val < 0 || val > 255) | 888 | if (val < 0 || val > 255) |
907 | return -EINVAL; | 889 | return -EINVAL; |
@@ -1250,7 +1232,7 @@ static void adt7475_remove_files(struct i2c_client *client, | |||
1250 | static int adt7475_probe(struct i2c_client *client, | 1232 | static int adt7475_probe(struct i2c_client *client, |
1251 | const struct i2c_device_id *id) | 1233 | const struct i2c_device_id *id) |
1252 | { | 1234 | { |
1253 | static const char * const names[] = { | 1235 | static const char *names[] = { |
1254 | [adt7473] = "ADT7473", | 1236 | [adt7473] = "ADT7473", |
1255 | [adt7475] = "ADT7475", | 1237 | [adt7475] = "ADT7475", |
1256 | [adt7476] = "ADT7476", | 1238 | [adt7476] = "ADT7476", |
@@ -1261,7 +1243,7 @@ static int adt7475_probe(struct i2c_client *client, | |||
1261 | int i, ret = 0, revision; | 1243 | int i, ret = 0, revision; |
1262 | u8 config2, config3; | 1244 | u8 config2, config3; |
1263 | 1245 | ||
1264 | data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL); | 1246 | data = kzalloc(sizeof(*data), GFP_KERNEL); |
1265 | if (data == NULL) | 1247 | if (data == NULL) |
1266 | return -ENOMEM; | 1248 | return -ENOMEM; |
1267 | 1249 | ||
@@ -1298,11 +1280,9 @@ static int adt7475_probe(struct i2c_client *client, | |||
1298 | if ((data->config4 & CONFIG4_PINFUNC) == 0x0) | 1280 | if ((data->config4 & CONFIG4_PINFUNC) == 0x0) |
1299 | data->has_fan4 = 1; | 1281 | data->has_fan4 = 1; |
1300 | 1282 | ||
1301 | /* | 1283 | /* THERM configuration is more complex on the ADT7476 and ADT7490, |
1302 | * THERM configuration is more complex on the ADT7476 and ADT7490, | 1284 | because 2 different pins (TACH4 and +2.5 Vin) can be used for |
1303 | * because 2 different pins (TACH4 and +2.5 Vin) can be used for | 1285 | this function */ |
1304 | * this function | ||
1305 | */ | ||
1306 | if (id->driver_data == adt7490) { | 1286 | if (id->driver_data == adt7490) { |
1307 | if ((data->config4 & CONFIG4_PINFUNC) == 0x1 && | 1287 | if ((data->config4 & CONFIG4_PINFUNC) == 0x1 && |
1308 | !(config3 & CONFIG3_THERM)) | 1288 | !(config3 & CONFIG3_THERM)) |
@@ -1314,10 +1294,8 @@ static int adt7475_probe(struct i2c_client *client, | |||
1314 | data->has_voltage |= (1 << 0); /* in0 */ | 1294 | data->has_voltage |= (1 << 0); /* in0 */ |
1315 | } | 1295 | } |
1316 | 1296 | ||
1317 | /* | 1297 | /* On the ADT7476, the +12V input pin may instead be used as VID5, |
1318 | * On the ADT7476, the +12V input pin may instead be used as VID5, | 1298 | and VID pins may alternatively be used as GPIO */ |
1319 | * and VID pins may alternatively be used as GPIO | ||
1320 | */ | ||
1321 | if (id->driver_data == adt7476) { | 1299 | if (id->driver_data == adt7476) { |
1322 | u8 vid = adt7475_read(REG_VID); | 1300 | u8 vid = adt7475_read(REG_VID); |
1323 | if (!(vid & VID_VIDSEL)) | 1301 | if (!(vid & VID_VIDSEL)) |
@@ -1336,16 +1314,14 @@ static int adt7475_probe(struct i2c_client *client, | |||
1336 | } | 1314 | } |
1337 | data->bypass_attn &= data->has_voltage; | 1315 | data->bypass_attn &= data->has_voltage; |
1338 | 1316 | ||
1339 | /* | 1317 | /* Call adt7475_read_pwm for all pwm's as this will reprogram any |
1340 | * Call adt7475_read_pwm for all pwm's as this will reprogram any | 1318 | pwm's which are disabled to manual mode with 0% duty cycle */ |
1341 | * pwm's which are disabled to manual mode with 0% duty cycle | ||
1342 | */ | ||
1343 | for (i = 0; i < ADT7475_PWM_COUNT; i++) | 1319 | for (i = 0; i < ADT7475_PWM_COUNT; i++) |
1344 | adt7475_read_pwm(client, i); | 1320 | adt7475_read_pwm(client, i); |
1345 | 1321 | ||
1346 | ret = sysfs_create_group(&client->dev.kobj, &adt7475_attr_group); | 1322 | ret = sysfs_create_group(&client->dev.kobj, &adt7475_attr_group); |
1347 | if (ret) | 1323 | if (ret) |
1348 | return ret; | 1324 | goto efree; |
1349 | 1325 | ||
1350 | /* Features that can be disabled individually */ | 1326 | /* Features that can be disabled individually */ |
1351 | if (data->has_fan4) { | 1327 | if (data->has_fan4) { |
@@ -1411,6 +1387,8 @@ static int adt7475_probe(struct i2c_client *client, | |||
1411 | 1387 | ||
1412 | eremove: | 1388 | eremove: |
1413 | adt7475_remove_files(client, data); | 1389 | adt7475_remove_files(client, data); |
1390 | efree: | ||
1391 | kfree(data); | ||
1414 | return ret; | 1392 | return ret; |
1415 | } | 1393 | } |
1416 | 1394 | ||
@@ -1420,6 +1398,7 @@ static int adt7475_remove(struct i2c_client *client) | |||
1420 | 1398 | ||
1421 | hwmon_device_unregister(data->hwmon_dev); | 1399 | hwmon_device_unregister(data->hwmon_dev); |
1422 | adt7475_remove_files(client, data); | 1400 | adt7475_remove_files(client, data); |
1401 | kfree(data); | ||
1423 | 1402 | ||
1424 | return 0; | 1403 | return 0; |
1425 | } | 1404 | } |
@@ -1452,10 +1431,8 @@ static void adt7475_read_pwm(struct i2c_client *client, int index) | |||
1452 | 1431 | ||
1453 | data->pwm[CONTROL][index] = adt7475_read(PWM_CONFIG_REG(index)); | 1432 | data->pwm[CONTROL][index] = adt7475_read(PWM_CONFIG_REG(index)); |
1454 | 1433 | ||
1455 | /* | 1434 | /* Figure out the internal value for pwmctrl and pwmchan |
1456 | * Figure out the internal value for pwmctrl and pwmchan | 1435 | based on the current settings */ |
1457 | * based on the current settings | ||
1458 | */ | ||
1459 | v = (data->pwm[CONTROL][index] >> 5) & 7; | 1436 | v = (data->pwm[CONTROL][index] >> 5) & 7; |
1460 | 1437 | ||
1461 | if (v == 3) | 1438 | if (v == 3) |
@@ -1463,11 +1440,10 @@ static void adt7475_read_pwm(struct i2c_client *client, int index) | |||
1463 | else if (v == 7) | 1440 | else if (v == 7) |
1464 | data->pwmctl[index] = 1; | 1441 | data->pwmctl[index] = 1; |
1465 | else if (v == 4) { | 1442 | else if (v == 4) { |
1466 | /* | 1443 | /* The fan is disabled - we don't want to |
1467 | * The fan is disabled - we don't want to | 1444 | support that, so change to manual mode and |
1468 | * support that, so change to manual mode and | 1445 | set the duty cycle to 0 instead |
1469 | * set the duty cycle to 0 instead | 1446 | */ |
1470 | */ | ||
1471 | data->pwm[INPUT][index] = 0; | 1447 | data->pwm[INPUT][index] = 0; |
1472 | data->pwm[CONTROL][index] &= ~0xE0; | 1448 | data->pwm[CONTROL][index] &= ~0xE0; |
1473 | data->pwm[CONTROL][index] |= (7 << 5); | 1449 | data->pwm[CONTROL][index] |= (7 << 5); |
@@ -1624,8 +1600,19 @@ static struct adt7475_data *adt7475_update_device(struct device *dev) | |||
1624 | return data; | 1600 | return data; |
1625 | } | 1601 | } |
1626 | 1602 | ||
1627 | module_i2c_driver(adt7475_driver); | 1603 | static int __init sensors_adt7475_init(void) |
1604 | { | ||
1605 | return i2c_add_driver(&adt7475_driver); | ||
1606 | } | ||
1607 | |||
1608 | static void __exit sensors_adt7475_exit(void) | ||
1609 | { | ||
1610 | i2c_del_driver(&adt7475_driver); | ||
1611 | } | ||
1628 | 1612 | ||
1629 | MODULE_AUTHOR("Advanced Micro Devices, Inc"); | 1613 | MODULE_AUTHOR("Advanced Micro Devices, Inc"); |
1630 | MODULE_DESCRIPTION("adt7475 driver"); | 1614 | MODULE_DESCRIPTION("adt7475 driver"); |
1631 | MODULE_LICENSE("GPL"); | 1615 | MODULE_LICENSE("GPL"); |
1616 | |||
1617 | module_init(sensors_adt7475_init); | ||
1618 | module_exit(sensors_adt7475_exit); | ||