diff options
Diffstat (limited to 'drivers/hwmon/w83781d.c')
-rw-r--r-- | drivers/hwmon/w83781d.c | 82 |
1 files changed, 51 insertions, 31 deletions
diff --git a/drivers/hwmon/w83781d.c b/drivers/hwmon/w83781d.c index 64c1f8af5bb2..e4c700356c44 100644 --- a/drivers/hwmon/w83781d.c +++ b/drivers/hwmon/w83781d.c | |||
@@ -42,6 +42,7 @@ | |||
42 | #include <linux/hwmon.h> | 42 | #include <linux/hwmon.h> |
43 | #include <linux/hwmon-vid.h> | 43 | #include <linux/hwmon-vid.h> |
44 | #include <linux/err.h> | 44 | #include <linux/err.h> |
45 | #include <linux/mutex.h> | ||
45 | #include <asm/io.h> | 46 | #include <asm/io.h> |
46 | #include "lm75.h" | 47 | #include "lm75.h" |
47 | 48 | ||
@@ -56,6 +57,10 @@ I2C_CLIENT_INSMOD_5(w83781d, w83782d, w83783s, w83627hf, as99127f); | |||
56 | I2C_CLIENT_MODULE_PARM(force_subclients, "List of subclient addresses: " | 57 | I2C_CLIENT_MODULE_PARM(force_subclients, "List of subclient addresses: " |
57 | "{bus, clientaddr, subclientaddr1, subclientaddr2}"); | 58 | "{bus, clientaddr, subclientaddr1, subclientaddr2}"); |
58 | 59 | ||
60 | static int reset; | ||
61 | module_param(reset, bool, 0); | ||
62 | MODULE_PARM_DESC(reset, "Set to one to reset chip on load"); | ||
63 | |||
59 | static int init = 1; | 64 | static int init = 1; |
60 | module_param(init, bool, 0); | 65 | module_param(init, bool, 0); |
61 | MODULE_PARM_DESC(init, "Set to zero to bypass chip initialization"); | 66 | MODULE_PARM_DESC(init, "Set to zero to bypass chip initialization"); |
@@ -226,10 +231,10 @@ DIV_TO_REG(long val, enum chips type) | |||
226 | struct w83781d_data { | 231 | struct w83781d_data { |
227 | struct i2c_client client; | 232 | struct i2c_client client; |
228 | struct class_device *class_dev; | 233 | struct class_device *class_dev; |
229 | struct semaphore lock; | 234 | struct mutex lock; |
230 | enum chips type; | 235 | enum chips type; |
231 | 236 | ||
232 | struct semaphore update_lock; | 237 | struct mutex update_lock; |
233 | char valid; /* !=0 if following fields are valid */ | 238 | char valid; /* !=0 if following fields are valid */ |
234 | unsigned long last_updated; /* In jiffies */ | 239 | unsigned long last_updated; /* In jiffies */ |
235 | 240 | ||
@@ -267,9 +272,8 @@ static int w83781d_isa_attach_adapter(struct i2c_adapter *adapter); | |||
267 | static int w83781d_detect(struct i2c_adapter *adapter, int address, int kind); | 272 | static int w83781d_detect(struct i2c_adapter *adapter, int address, int kind); |
268 | static int w83781d_detach_client(struct i2c_client *client); | 273 | static int w83781d_detach_client(struct i2c_client *client); |
269 | 274 | ||
270 | static int w83781d_read_value(struct i2c_client *client, u16 register); | 275 | static int w83781d_read_value(struct i2c_client *client, u16 reg); |
271 | static int w83781d_write_value(struct i2c_client *client, u16 register, | 276 | static int w83781d_write_value(struct i2c_client *client, u16 reg, u16 value); |
272 | u16 value); | ||
273 | static struct w83781d_data *w83781d_update_device(struct device *dev); | 277 | static struct w83781d_data *w83781d_update_device(struct device *dev); |
274 | static void w83781d_init_client(struct i2c_client *client); | 278 | static void w83781d_init_client(struct i2c_client *client); |
275 | 279 | ||
@@ -311,11 +315,11 @@ static ssize_t store_in_##reg (struct device *dev, const char *buf, size_t count | |||
311 | \ | 315 | \ |
312 | val = simple_strtoul(buf, NULL, 10) / 10; \ | 316 | val = simple_strtoul(buf, NULL, 10) / 10; \ |
313 | \ | 317 | \ |
314 | down(&data->update_lock); \ | 318 | mutex_lock(&data->update_lock); \ |
315 | data->in_##reg[nr] = IN_TO_REG(val); \ | 319 | data->in_##reg[nr] = IN_TO_REG(val); \ |
316 | w83781d_write_value(client, W83781D_REG_IN_##REG(nr), data->in_##reg[nr]); \ | 320 | w83781d_write_value(client, W83781D_REG_IN_##REG(nr), data->in_##reg[nr]); \ |
317 | \ | 321 | \ |
318 | up(&data->update_lock); \ | 322 | mutex_unlock(&data->update_lock); \ |
319 | return count; \ | 323 | return count; \ |
320 | } | 324 | } |
321 | store_in_reg(MIN, min); | 325 | store_in_reg(MIN, min); |
@@ -381,13 +385,13 @@ store_fan_min(struct device *dev, const char *buf, size_t count, int nr) | |||
381 | 385 | ||
382 | val = simple_strtoul(buf, NULL, 10); | 386 | val = simple_strtoul(buf, NULL, 10); |
383 | 387 | ||
384 | down(&data->update_lock); | 388 | mutex_lock(&data->update_lock); |
385 | data->fan_min[nr - 1] = | 389 | data->fan_min[nr - 1] = |
386 | FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr - 1])); | 390 | FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr - 1])); |
387 | w83781d_write_value(client, W83781D_REG_FAN_MIN(nr), | 391 | w83781d_write_value(client, W83781D_REG_FAN_MIN(nr), |
388 | data->fan_min[nr - 1]); | 392 | data->fan_min[nr - 1]); |
389 | 393 | ||
390 | up(&data->update_lock); | 394 | mutex_unlock(&data->update_lock); |
391 | return count; | 395 | return count; |
392 | } | 396 | } |
393 | 397 | ||
@@ -446,7 +450,7 @@ static ssize_t store_temp_##reg (struct device *dev, const char *buf, size_t cou | |||
446 | \ | 450 | \ |
447 | val = simple_strtol(buf, NULL, 10); \ | 451 | val = simple_strtol(buf, NULL, 10); \ |
448 | \ | 452 | \ |
449 | down(&data->update_lock); \ | 453 | mutex_lock(&data->update_lock); \ |
450 | \ | 454 | \ |
451 | if (nr >= 2) { /* TEMP2 and TEMP3 */ \ | 455 | if (nr >= 2) { /* TEMP2 and TEMP3 */ \ |
452 | data->temp_##reg##_add[nr-2] = LM75_TEMP_TO_REG(val); \ | 456 | data->temp_##reg##_add[nr-2] = LM75_TEMP_TO_REG(val); \ |
@@ -458,7 +462,7 @@ static ssize_t store_temp_##reg (struct device *dev, const char *buf, size_t cou | |||
458 | data->temp_##reg); \ | 462 | data->temp_##reg); \ |
459 | } \ | 463 | } \ |
460 | \ | 464 | \ |
461 | up(&data->update_lock); \ | 465 | mutex_unlock(&data->update_lock); \ |
462 | return count; \ | 466 | return count; \ |
463 | } | 467 | } |
464 | store_temp_reg(OVER, max); | 468 | store_temp_reg(OVER, max); |
@@ -571,7 +575,7 @@ store_beep_reg(struct device *dev, const char *buf, size_t count, | |||
571 | 575 | ||
572 | val = simple_strtoul(buf, NULL, 10); | 576 | val = simple_strtoul(buf, NULL, 10); |
573 | 577 | ||
574 | down(&data->update_lock); | 578 | mutex_lock(&data->update_lock); |
575 | 579 | ||
576 | if (update_mask == BEEP_MASK) { /* We are storing beep_mask */ | 580 | if (update_mask == BEEP_MASK) { /* We are storing beep_mask */ |
577 | data->beep_mask = BEEP_MASK_TO_REG(val, data->type); | 581 | data->beep_mask = BEEP_MASK_TO_REG(val, data->type); |
@@ -592,7 +596,7 @@ store_beep_reg(struct device *dev, const char *buf, size_t count, | |||
592 | w83781d_write_value(client, W83781D_REG_BEEP_INTS2, | 596 | w83781d_write_value(client, W83781D_REG_BEEP_INTS2, |
593 | val2 | data->beep_enable << 7); | 597 | val2 | data->beep_enable << 7); |
594 | 598 | ||
595 | up(&data->update_lock); | 599 | mutex_unlock(&data->update_lock); |
596 | return count; | 600 | return count; |
597 | } | 601 | } |
598 | 602 | ||
@@ -637,7 +641,7 @@ store_fan_div_reg(struct device *dev, const char *buf, size_t count, int nr) | |||
637 | u8 reg; | 641 | u8 reg; |
638 | unsigned long val = simple_strtoul(buf, NULL, 10); | 642 | unsigned long val = simple_strtoul(buf, NULL, 10); |
639 | 643 | ||
640 | down(&data->update_lock); | 644 | mutex_lock(&data->update_lock); |
641 | 645 | ||
642 | /* Save fan_min */ | 646 | /* Save fan_min */ |
643 | min = FAN_FROM_REG(data->fan_min[nr], | 647 | min = FAN_FROM_REG(data->fan_min[nr], |
@@ -662,7 +666,7 @@ store_fan_div_reg(struct device *dev, const char *buf, size_t count, int nr) | |||
662 | data->fan_min[nr] = FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr])); | 666 | data->fan_min[nr] = FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr])); |
663 | w83781d_write_value(client, W83781D_REG_FAN_MIN(nr+1), data->fan_min[nr]); | 667 | w83781d_write_value(client, W83781D_REG_FAN_MIN(nr+1), data->fan_min[nr]); |
664 | 668 | ||
665 | up(&data->update_lock); | 669 | mutex_unlock(&data->update_lock); |
666 | return count; | 670 | return count; |
667 | } | 671 | } |
668 | 672 | ||
@@ -709,10 +713,10 @@ store_pwm_reg(struct device *dev, const char *buf, size_t count, int nr) | |||
709 | 713 | ||
710 | val = simple_strtoul(buf, NULL, 10); | 714 | val = simple_strtoul(buf, NULL, 10); |
711 | 715 | ||
712 | down(&data->update_lock); | 716 | mutex_lock(&data->update_lock); |
713 | data->pwm[nr - 1] = PWM_TO_REG(val); | 717 | data->pwm[nr - 1] = PWM_TO_REG(val); |
714 | w83781d_write_value(client, W83781D_REG_PWM(nr), data->pwm[nr - 1]); | 718 | w83781d_write_value(client, W83781D_REG_PWM(nr), data->pwm[nr - 1]); |
715 | up(&data->update_lock); | 719 | mutex_unlock(&data->update_lock); |
716 | return count; | 720 | return count; |
717 | } | 721 | } |
718 | 722 | ||
@@ -725,7 +729,7 @@ store_pwmenable_reg(struct device *dev, const char *buf, size_t count, int nr) | |||
725 | 729 | ||
726 | val = simple_strtoul(buf, NULL, 10); | 730 | val = simple_strtoul(buf, NULL, 10); |
727 | 731 | ||
728 | down(&data->update_lock); | 732 | mutex_lock(&data->update_lock); |
729 | 733 | ||
730 | switch (val) { | 734 | switch (val) { |
731 | case 0: | 735 | case 0: |
@@ -742,11 +746,11 @@ store_pwmenable_reg(struct device *dev, const char *buf, size_t count, int nr) | |||
742 | break; | 746 | break; |
743 | 747 | ||
744 | default: | 748 | default: |
745 | up(&data->update_lock); | 749 | mutex_unlock(&data->update_lock); |
746 | return -EINVAL; | 750 | return -EINVAL; |
747 | } | 751 | } |
748 | 752 | ||
749 | up(&data->update_lock); | 753 | mutex_unlock(&data->update_lock); |
750 | return count; | 754 | return count; |
751 | } | 755 | } |
752 | 756 | ||
@@ -808,7 +812,7 @@ store_sensor_reg(struct device *dev, const char *buf, size_t count, int nr) | |||
808 | 812 | ||
809 | val = simple_strtoul(buf, NULL, 10); | 813 | val = simple_strtoul(buf, NULL, 10); |
810 | 814 | ||
811 | down(&data->update_lock); | 815 | mutex_lock(&data->update_lock); |
812 | 816 | ||
813 | switch (val) { | 817 | switch (val) { |
814 | case 1: /* PII/Celeron diode */ | 818 | case 1: /* PII/Celeron diode */ |
@@ -841,7 +845,7 @@ store_sensor_reg(struct device *dev, const char *buf, size_t count, int nr) | |||
841 | break; | 845 | break; |
842 | } | 846 | } |
843 | 847 | ||
844 | up(&data->update_lock); | 848 | mutex_unlock(&data->update_lock); |
845 | return count; | 849 | return count; |
846 | } | 850 | } |
847 | 851 | ||
@@ -1073,7 +1077,7 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind) | |||
1073 | new_client = &data->client; | 1077 | new_client = &data->client; |
1074 | i2c_set_clientdata(new_client, data); | 1078 | i2c_set_clientdata(new_client, data); |
1075 | new_client->addr = address; | 1079 | new_client->addr = address; |
1076 | init_MUTEX(&data->lock); | 1080 | mutex_init(&data->lock); |
1077 | new_client->adapter = adapter; | 1081 | new_client->adapter = adapter; |
1078 | new_client->driver = is_isa ? &w83781d_isa_driver : &w83781d_driver; | 1082 | new_client->driver = is_isa ? &w83781d_isa_driver : &w83781d_driver; |
1079 | new_client->flags = 0; | 1083 | new_client->flags = 0; |
@@ -1178,7 +1182,7 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind) | |||
1178 | data->type = kind; | 1182 | data->type = kind; |
1179 | 1183 | ||
1180 | data->valid = 0; | 1184 | data->valid = 0; |
1181 | init_MUTEX(&data->update_lock); | 1185 | mutex_init(&data->update_lock); |
1182 | 1186 | ||
1183 | /* Tell the I2C layer a new client has arrived */ | 1187 | /* Tell the I2C layer a new client has arrived */ |
1184 | if ((err = i2c_attach_client(new_client))) | 1188 | if ((err = i2c_attach_client(new_client))) |
@@ -1325,7 +1329,7 @@ w83781d_read_value(struct i2c_client *client, u16 reg) | |||
1325 | int res, word_sized, bank; | 1329 | int res, word_sized, bank; |
1326 | struct i2c_client *cl; | 1330 | struct i2c_client *cl; |
1327 | 1331 | ||
1328 | down(&data->lock); | 1332 | mutex_lock(&data->lock); |
1329 | if (i2c_is_isa_client(client)) { | 1333 | if (i2c_is_isa_client(client)) { |
1330 | word_sized = (((reg & 0xff00) == 0x100) | 1334 | word_sized = (((reg & 0xff00) == 0x100) |
1331 | || ((reg & 0xff00) == 0x200)) | 1335 | || ((reg & 0xff00) == 0x200)) |
@@ -1383,7 +1387,7 @@ w83781d_read_value(struct i2c_client *client, u16 reg) | |||
1383 | if (bank > 2) | 1387 | if (bank > 2) |
1384 | i2c_smbus_write_byte_data(client, W83781D_REG_BANK, 0); | 1388 | i2c_smbus_write_byte_data(client, W83781D_REG_BANK, 0); |
1385 | } | 1389 | } |
1386 | up(&data->lock); | 1390 | mutex_unlock(&data->lock); |
1387 | return res; | 1391 | return res; |
1388 | } | 1392 | } |
1389 | 1393 | ||
@@ -1394,7 +1398,7 @@ w83781d_write_value(struct i2c_client *client, u16 reg, u16 value) | |||
1394 | int word_sized, bank; | 1398 | int word_sized, bank; |
1395 | struct i2c_client *cl; | 1399 | struct i2c_client *cl; |
1396 | 1400 | ||
1397 | down(&data->lock); | 1401 | mutex_lock(&data->lock); |
1398 | if (i2c_is_isa_client(client)) { | 1402 | if (i2c_is_isa_client(client)) { |
1399 | word_sized = (((reg & 0xff00) == 0x100) | 1403 | word_sized = (((reg & 0xff00) == 0x100) |
1400 | || ((reg & 0xff00) == 0x200)) | 1404 | || ((reg & 0xff00) == 0x200)) |
@@ -1447,7 +1451,7 @@ w83781d_write_value(struct i2c_client *client, u16 reg, u16 value) | |||
1447 | if (bank > 2) | 1451 | if (bank > 2) |
1448 | i2c_smbus_write_byte_data(client, W83781D_REG_BANK, 0); | 1452 | i2c_smbus_write_byte_data(client, W83781D_REG_BANK, 0); |
1449 | } | 1453 | } |
1450 | up(&data->lock); | 1454 | mutex_unlock(&data->lock); |
1451 | return 0; | 1455 | return 0; |
1452 | } | 1456 | } |
1453 | 1457 | ||
@@ -1459,8 +1463,17 @@ w83781d_init_client(struct i2c_client *client) | |||
1459 | int type = data->type; | 1463 | int type = data->type; |
1460 | u8 tmp; | 1464 | u8 tmp; |
1461 | 1465 | ||
1462 | if (init && type != as99127f) { /* this resets registers we don't have | 1466 | if (reset && type != as99127f) { /* this resets registers we don't have |
1463 | documentation for on the as99127f */ | 1467 | documentation for on the as99127f */ |
1468 | /* Resetting the chip has been the default for a long time, | ||
1469 | but it causes the BIOS initializations (fan clock dividers, | ||
1470 | thermal sensor types...) to be lost, so it is now optional. | ||
1471 | It might even go away if nobody reports it as being useful, | ||
1472 | as I see very little reason why this would be needed at | ||
1473 | all. */ | ||
1474 | dev_info(&client->dev, "If reset=1 solved a problem you were " | ||
1475 | "having, please report!\n"); | ||
1476 | |||
1464 | /* save these registers */ | 1477 | /* save these registers */ |
1465 | i = w83781d_read_value(client, W83781D_REG_BEEP_CONFIG); | 1478 | i = w83781d_read_value(client, W83781D_REG_BEEP_CONFIG); |
1466 | p = w83781d_read_value(client, W83781D_REG_PWMCLK12); | 1479 | p = w83781d_read_value(client, W83781D_REG_PWMCLK12); |
@@ -1477,6 +1490,13 @@ w83781d_init_client(struct i2c_client *client) | |||
1477 | w83781d_write_value(client, W83781D_REG_BEEP_INTS2, 0); | 1490 | w83781d_write_value(client, W83781D_REG_BEEP_INTS2, 0); |
1478 | } | 1491 | } |
1479 | 1492 | ||
1493 | /* Disable power-on abnormal beep, as advised by the datasheet. | ||
1494 | Already done if reset=1. */ | ||
1495 | if (init && !reset && type != as99127f) { | ||
1496 | i = w83781d_read_value(client, W83781D_REG_BEEP_CONFIG); | ||
1497 | w83781d_write_value(client, W83781D_REG_BEEP_CONFIG, i | 0x80); | ||
1498 | } | ||
1499 | |||
1480 | data->vrm = vid_which_vrm(); | 1500 | data->vrm = vid_which_vrm(); |
1481 | 1501 | ||
1482 | if ((type != w83781d) && (type != as99127f)) { | 1502 | if ((type != w83781d) && (type != as99127f)) { |
@@ -1533,7 +1553,7 @@ static struct w83781d_data *w83781d_update_device(struct device *dev) | |||
1533 | struct w83781d_data *data = i2c_get_clientdata(client); | 1553 | struct w83781d_data *data = i2c_get_clientdata(client); |
1534 | int i; | 1554 | int i; |
1535 | 1555 | ||
1536 | down(&data->update_lock); | 1556 | mutex_lock(&data->update_lock); |
1537 | 1557 | ||
1538 | if (time_after(jiffies, data->last_updated + HZ + HZ / 2) | 1558 | if (time_after(jiffies, data->last_updated + HZ + HZ / 2) |
1539 | || !data->valid) { | 1559 | || !data->valid) { |
@@ -1641,7 +1661,7 @@ static struct w83781d_data *w83781d_update_device(struct device *dev) | |||
1641 | data->valid = 1; | 1661 | data->valid = 1; |
1642 | } | 1662 | } |
1643 | 1663 | ||
1644 | up(&data->update_lock); | 1664 | mutex_unlock(&data->update_lock); |
1645 | 1665 | ||
1646 | return data; | 1666 | return data; |
1647 | } | 1667 | } |