diff options
Diffstat (limited to 'drivers/hwmon/tmp401.c')
-rw-r--r-- | drivers/hwmon/tmp401.c | 255 |
1 files changed, 125 insertions, 130 deletions
diff --git a/drivers/hwmon/tmp401.c b/drivers/hwmon/tmp401.c index d14a1af9f550..ad8d535235c5 100644 --- a/drivers/hwmon/tmp401.c +++ b/drivers/hwmon/tmp401.c | |||
@@ -92,17 +92,6 @@ static const u8 TMP411_TEMP_HIGHEST_LSB[2] = { 0x33, 0x37 }; | |||
92 | #define TMP411_DEVICE_ID 0x12 | 92 | #define TMP411_DEVICE_ID 0x12 |
93 | 93 | ||
94 | /* | 94 | /* |
95 | * Functions declarations | ||
96 | */ | ||
97 | |||
98 | static int tmp401_probe(struct i2c_client *client, | ||
99 | const struct i2c_device_id *id); | ||
100 | static int tmp401_detect(struct i2c_client *client, | ||
101 | struct i2c_board_info *info); | ||
102 | static int tmp401_remove(struct i2c_client *client); | ||
103 | static struct tmp401_data *tmp401_update_device(struct device *dev); | ||
104 | |||
105 | /* | ||
106 | * Driver data (common to all clients) | 95 | * Driver data (common to all clients) |
107 | */ | 96 | */ |
108 | 97 | ||
@@ -113,18 +102,6 @@ static const struct i2c_device_id tmp401_id[] = { | |||
113 | }; | 102 | }; |
114 | MODULE_DEVICE_TABLE(i2c, tmp401_id); | 103 | MODULE_DEVICE_TABLE(i2c, tmp401_id); |
115 | 104 | ||
116 | static struct i2c_driver tmp401_driver = { | ||
117 | .class = I2C_CLASS_HWMON, | ||
118 | .driver = { | ||
119 | .name = "tmp401", | ||
120 | }, | ||
121 | .probe = tmp401_probe, | ||
122 | .remove = tmp401_remove, | ||
123 | .id_table = tmp401_id, | ||
124 | .detect = tmp401_detect, | ||
125 | .address_list = normal_i2c, | ||
126 | }; | ||
127 | |||
128 | /* | 105 | /* |
129 | * Client data (each client gets its own) | 106 | * Client data (each client gets its own) |
130 | */ | 107 | */ |
@@ -194,6 +171,71 @@ static u8 tmp401_crit_temp_to_register(long temp, u8 config) | |||
194 | return (temp + 500) / 1000; | 171 | return (temp + 500) / 1000; |
195 | } | 172 | } |
196 | 173 | ||
174 | static struct tmp401_data *tmp401_update_device_reg16( | ||
175 | struct i2c_client *client, struct tmp401_data *data) | ||
176 | { | ||
177 | int i; | ||
178 | |||
179 | for (i = 0; i < 2; i++) { | ||
180 | /* | ||
181 | * High byte must be read first immediately followed | ||
182 | * by the low byte | ||
183 | */ | ||
184 | data->temp[i] = i2c_smbus_read_byte_data(client, | ||
185 | TMP401_TEMP_MSB[i]) << 8; | ||
186 | data->temp[i] |= i2c_smbus_read_byte_data(client, | ||
187 | TMP401_TEMP_LSB[i]); | ||
188 | data->temp_low[i] = i2c_smbus_read_byte_data(client, | ||
189 | TMP401_TEMP_LOW_LIMIT_MSB_READ[i]) << 8; | ||
190 | data->temp_low[i] |= i2c_smbus_read_byte_data(client, | ||
191 | TMP401_TEMP_LOW_LIMIT_LSB[i]); | ||
192 | data->temp_high[i] = i2c_smbus_read_byte_data(client, | ||
193 | TMP401_TEMP_HIGH_LIMIT_MSB_READ[i]) << 8; | ||
194 | data->temp_high[i] |= i2c_smbus_read_byte_data(client, | ||
195 | TMP401_TEMP_HIGH_LIMIT_LSB[i]); | ||
196 | data->temp_crit[i] = i2c_smbus_read_byte_data(client, | ||
197 | TMP401_TEMP_CRIT_LIMIT[i]); | ||
198 | |||
199 | if (data->kind == tmp411) { | ||
200 | data->temp_lowest[i] = i2c_smbus_read_byte_data(client, | ||
201 | TMP411_TEMP_LOWEST_MSB[i]) << 8; | ||
202 | data->temp_lowest[i] |= i2c_smbus_read_byte_data( | ||
203 | client, TMP411_TEMP_LOWEST_LSB[i]); | ||
204 | |||
205 | data->temp_highest[i] = i2c_smbus_read_byte_data( | ||
206 | client, TMP411_TEMP_HIGHEST_MSB[i]) << 8; | ||
207 | data->temp_highest[i] |= i2c_smbus_read_byte_data( | ||
208 | client, TMP411_TEMP_HIGHEST_LSB[i]); | ||
209 | } | ||
210 | } | ||
211 | return data; | ||
212 | } | ||
213 | |||
214 | static struct tmp401_data *tmp401_update_device(struct device *dev) | ||
215 | { | ||
216 | struct i2c_client *client = to_i2c_client(dev); | ||
217 | struct tmp401_data *data = i2c_get_clientdata(client); | ||
218 | |||
219 | mutex_lock(&data->update_lock); | ||
220 | |||
221 | if (time_after(jiffies, data->last_updated + HZ) || !data->valid) { | ||
222 | data->status = i2c_smbus_read_byte_data(client, TMP401_STATUS); | ||
223 | data->config = i2c_smbus_read_byte_data(client, | ||
224 | TMP401_CONFIG_READ); | ||
225 | tmp401_update_device_reg16(client, data); | ||
226 | |||
227 | data->temp_crit_hyst = i2c_smbus_read_byte_data(client, | ||
228 | TMP401_TEMP_CRIT_HYST); | ||
229 | |||
230 | data->last_updated = jiffies; | ||
231 | data->valid = 1; | ||
232 | } | ||
233 | |||
234 | mutex_unlock(&data->update_lock); | ||
235 | |||
236 | return data; | ||
237 | } | ||
238 | |||
197 | static ssize_t show_temp_value(struct device *dev, | 239 | static ssize_t show_temp_value(struct device *dev, |
198 | struct device_attribute *devattr, char *buf) | 240 | struct device_attribute *devattr, char *buf) |
199 | { | 241 | { |
@@ -420,30 +462,36 @@ static ssize_t reset_temp_history(struct device *dev, | |||
420 | } | 462 | } |
421 | 463 | ||
422 | static struct sensor_device_attribute tmp401_attr[] = { | 464 | static struct sensor_device_attribute tmp401_attr[] = { |
423 | SENSOR_ATTR(temp1_input, 0444, show_temp_value, NULL, 0), | 465 | SENSOR_ATTR(temp1_input, S_IRUGO, show_temp_value, NULL, 0), |
424 | SENSOR_ATTR(temp1_min, 0644, show_temp_min, store_temp_min, 0), | 466 | SENSOR_ATTR(temp1_min, S_IWUSR | S_IRUGO, show_temp_min, |
425 | SENSOR_ATTR(temp1_max, 0644, show_temp_max, store_temp_max, 0), | 467 | store_temp_min, 0), |
426 | SENSOR_ATTR(temp1_crit, 0644, show_temp_crit, store_temp_crit, 0), | 468 | SENSOR_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp_max, |
427 | SENSOR_ATTR(temp1_crit_hyst, 0644, show_temp_crit_hyst, | 469 | store_temp_max, 0), |
470 | SENSOR_ATTR(temp1_crit, S_IWUSR | S_IRUGO, show_temp_crit, | ||
471 | store_temp_crit, 0), | ||
472 | SENSOR_ATTR(temp1_crit_hyst, S_IWUSR | S_IRUGO, show_temp_crit_hyst, | ||
428 | store_temp_crit_hyst, 0), | 473 | store_temp_crit_hyst, 0), |
429 | SENSOR_ATTR(temp1_min_alarm, 0444, show_status, NULL, | 474 | SENSOR_ATTR(temp1_min_alarm, S_IRUGO, show_status, NULL, |
430 | TMP401_STATUS_LOCAL_LOW), | 475 | TMP401_STATUS_LOCAL_LOW), |
431 | SENSOR_ATTR(temp1_max_alarm, 0444, show_status, NULL, | 476 | SENSOR_ATTR(temp1_max_alarm, S_IRUGO, show_status, NULL, |
432 | TMP401_STATUS_LOCAL_HIGH), | 477 | TMP401_STATUS_LOCAL_HIGH), |
433 | SENSOR_ATTR(temp1_crit_alarm, 0444, show_status, NULL, | 478 | SENSOR_ATTR(temp1_crit_alarm, S_IRUGO, show_status, NULL, |
434 | TMP401_STATUS_LOCAL_CRIT), | 479 | TMP401_STATUS_LOCAL_CRIT), |
435 | SENSOR_ATTR(temp2_input, 0444, show_temp_value, NULL, 1), | 480 | SENSOR_ATTR(temp2_input, S_IRUGO, show_temp_value, NULL, 1), |
436 | SENSOR_ATTR(temp2_min, 0644, show_temp_min, store_temp_min, 1), | 481 | SENSOR_ATTR(temp2_min, S_IWUSR | S_IRUGO, show_temp_min, |
437 | SENSOR_ATTR(temp2_max, 0644, show_temp_max, store_temp_max, 1), | 482 | store_temp_min, 1), |
438 | SENSOR_ATTR(temp2_crit, 0644, show_temp_crit, store_temp_crit, 1), | 483 | SENSOR_ATTR(temp2_max, S_IWUSR | S_IRUGO, show_temp_max, |
439 | SENSOR_ATTR(temp2_crit_hyst, 0444, show_temp_crit_hyst, NULL, 1), | 484 | store_temp_max, 1), |
440 | SENSOR_ATTR(temp2_fault, 0444, show_status, NULL, | 485 | SENSOR_ATTR(temp2_crit, S_IWUSR | S_IRUGO, show_temp_crit, |
486 | store_temp_crit, 1), | ||
487 | SENSOR_ATTR(temp2_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL, 1), | ||
488 | SENSOR_ATTR(temp2_fault, S_IRUGO, show_status, NULL, | ||
441 | TMP401_STATUS_REMOTE_OPEN), | 489 | TMP401_STATUS_REMOTE_OPEN), |
442 | SENSOR_ATTR(temp2_min_alarm, 0444, show_status, NULL, | 490 | SENSOR_ATTR(temp2_min_alarm, S_IRUGO, show_status, NULL, |
443 | TMP401_STATUS_REMOTE_LOW), | 491 | TMP401_STATUS_REMOTE_LOW), |
444 | SENSOR_ATTR(temp2_max_alarm, 0444, show_status, NULL, | 492 | SENSOR_ATTR(temp2_max_alarm, S_IRUGO, show_status, NULL, |
445 | TMP401_STATUS_REMOTE_HIGH), | 493 | TMP401_STATUS_REMOTE_HIGH), |
446 | SENSOR_ATTR(temp2_crit_alarm, 0444, show_status, NULL, | 494 | SENSOR_ATTR(temp2_crit_alarm, S_IRUGO, show_status, NULL, |
447 | TMP401_STATUS_REMOTE_CRIT), | 495 | TMP401_STATUS_REMOTE_CRIT), |
448 | }; | 496 | }; |
449 | 497 | ||
@@ -455,11 +503,11 @@ static struct sensor_device_attribute tmp401_attr[] = { | |||
455 | * and remote channels. | 503 | * and remote channels. |
456 | */ | 504 | */ |
457 | static struct sensor_device_attribute tmp411_attr[] = { | 505 | static struct sensor_device_attribute tmp411_attr[] = { |
458 | SENSOR_ATTR(temp1_highest, 0444, show_temp_highest, NULL, 0), | 506 | SENSOR_ATTR(temp1_highest, S_IRUGO, show_temp_highest, NULL, 0), |
459 | SENSOR_ATTR(temp1_lowest, 0444, show_temp_lowest, NULL, 0), | 507 | SENSOR_ATTR(temp1_lowest, S_IRUGO, show_temp_lowest, NULL, 0), |
460 | SENSOR_ATTR(temp2_highest, 0444, show_temp_highest, NULL, 1), | 508 | SENSOR_ATTR(temp2_highest, S_IRUGO, show_temp_highest, NULL, 1), |
461 | SENSOR_ATTR(temp2_lowest, 0444, show_temp_lowest, NULL, 1), | 509 | SENSOR_ATTR(temp2_lowest, S_IRUGO, show_temp_lowest, NULL, 1), |
462 | SENSOR_ATTR(temp_reset_history, 0200, NULL, reset_temp_history, 0), | 510 | SENSOR_ATTR(temp_reset_history, S_IWUSR, NULL, reset_temp_history, 0), |
463 | }; | 511 | }; |
464 | 512 | ||
465 | /* | 513 | /* |
@@ -529,6 +577,27 @@ static int tmp401_detect(struct i2c_client *client, | |||
529 | return 0; | 577 | return 0; |
530 | } | 578 | } |
531 | 579 | ||
580 | static int tmp401_remove(struct i2c_client *client) | ||
581 | { | ||
582 | struct tmp401_data *data = i2c_get_clientdata(client); | ||
583 | int i; | ||
584 | |||
585 | if (data->hwmon_dev) | ||
586 | hwmon_device_unregister(data->hwmon_dev); | ||
587 | |||
588 | for (i = 0; i < ARRAY_SIZE(tmp401_attr); i++) | ||
589 | device_remove_file(&client->dev, &tmp401_attr[i].dev_attr); | ||
590 | |||
591 | if (data->kind == tmp411) { | ||
592 | for (i = 0; i < ARRAY_SIZE(tmp411_attr); i++) | ||
593 | device_remove_file(&client->dev, | ||
594 | &tmp411_attr[i].dev_attr); | ||
595 | } | ||
596 | |||
597 | kfree(data); | ||
598 | return 0; | ||
599 | } | ||
600 | |||
532 | static int tmp401_probe(struct i2c_client *client, | 601 | static int tmp401_probe(struct i2c_client *client, |
533 | const struct i2c_device_id *id) | 602 | const struct i2c_device_id *id) |
534 | { | 603 | { |
@@ -581,91 +650,17 @@ exit_remove: | |||
581 | return err; | 650 | return err; |
582 | } | 651 | } |
583 | 652 | ||
584 | static int tmp401_remove(struct i2c_client *client) | 653 | static struct i2c_driver tmp401_driver = { |
585 | { | 654 | .class = I2C_CLASS_HWMON, |
586 | struct tmp401_data *data = i2c_get_clientdata(client); | 655 | .driver = { |
587 | int i; | 656 | .name = "tmp401", |
588 | 657 | }, | |
589 | if (data->hwmon_dev) | 658 | .probe = tmp401_probe, |
590 | hwmon_device_unregister(data->hwmon_dev); | 659 | .remove = tmp401_remove, |
591 | 660 | .id_table = tmp401_id, | |
592 | for (i = 0; i < ARRAY_SIZE(tmp401_attr); i++) | 661 | .detect = tmp401_detect, |
593 | device_remove_file(&client->dev, &tmp401_attr[i].dev_attr); | 662 | .address_list = normal_i2c, |
594 | 663 | }; | |
595 | if (data->kind == tmp411) { | ||
596 | for (i = 0; i < ARRAY_SIZE(tmp411_attr); i++) | ||
597 | device_remove_file(&client->dev, | ||
598 | &tmp411_attr[i].dev_attr); | ||
599 | } | ||
600 | |||
601 | kfree(data); | ||
602 | return 0; | ||
603 | } | ||
604 | |||
605 | static struct tmp401_data *tmp401_update_device_reg16( | ||
606 | struct i2c_client *client, struct tmp401_data *data) | ||
607 | { | ||
608 | int i; | ||
609 | |||
610 | for (i = 0; i < 2; i++) { | ||
611 | /* | ||
612 | * High byte must be read first immediately followed | ||
613 | * by the low byte | ||
614 | */ | ||
615 | data->temp[i] = i2c_smbus_read_byte_data(client, | ||
616 | TMP401_TEMP_MSB[i]) << 8; | ||
617 | data->temp[i] |= i2c_smbus_read_byte_data(client, | ||
618 | TMP401_TEMP_LSB[i]); | ||
619 | data->temp_low[i] = i2c_smbus_read_byte_data(client, | ||
620 | TMP401_TEMP_LOW_LIMIT_MSB_READ[i]) << 8; | ||
621 | data->temp_low[i] |= i2c_smbus_read_byte_data(client, | ||
622 | TMP401_TEMP_LOW_LIMIT_LSB[i]); | ||
623 | data->temp_high[i] = i2c_smbus_read_byte_data(client, | ||
624 | TMP401_TEMP_HIGH_LIMIT_MSB_READ[i]) << 8; | ||
625 | data->temp_high[i] |= i2c_smbus_read_byte_data(client, | ||
626 | TMP401_TEMP_HIGH_LIMIT_LSB[i]); | ||
627 | data->temp_crit[i] = i2c_smbus_read_byte_data(client, | ||
628 | TMP401_TEMP_CRIT_LIMIT[i]); | ||
629 | |||
630 | if (data->kind == tmp411) { | ||
631 | data->temp_lowest[i] = i2c_smbus_read_byte_data(client, | ||
632 | TMP411_TEMP_LOWEST_MSB[i]) << 8; | ||
633 | data->temp_lowest[i] |= i2c_smbus_read_byte_data( | ||
634 | client, TMP411_TEMP_LOWEST_LSB[i]); | ||
635 | |||
636 | data->temp_highest[i] = i2c_smbus_read_byte_data( | ||
637 | client, TMP411_TEMP_HIGHEST_MSB[i]) << 8; | ||
638 | data->temp_highest[i] |= i2c_smbus_read_byte_data( | ||
639 | client, TMP411_TEMP_HIGHEST_LSB[i]); | ||
640 | } | ||
641 | } | ||
642 | return data; | ||
643 | } | ||
644 | |||
645 | static struct tmp401_data *tmp401_update_device(struct device *dev) | ||
646 | { | ||
647 | struct i2c_client *client = to_i2c_client(dev); | ||
648 | struct tmp401_data *data = i2c_get_clientdata(client); | ||
649 | |||
650 | mutex_lock(&data->update_lock); | ||
651 | |||
652 | if (time_after(jiffies, data->last_updated + HZ) || !data->valid) { | ||
653 | data->status = i2c_smbus_read_byte_data(client, TMP401_STATUS); | ||
654 | data->config = i2c_smbus_read_byte_data(client, | ||
655 | TMP401_CONFIG_READ); | ||
656 | tmp401_update_device_reg16(client, data); | ||
657 | |||
658 | data->temp_crit_hyst = i2c_smbus_read_byte_data(client, | ||
659 | TMP401_TEMP_CRIT_HYST); | ||
660 | |||
661 | data->last_updated = jiffies; | ||
662 | data->valid = 1; | ||
663 | } | ||
664 | |||
665 | mutex_unlock(&data->update_lock); | ||
666 | |||
667 | return data; | ||
668 | } | ||
669 | 664 | ||
670 | static int __init tmp401_init(void) | 665 | static int __init tmp401_init(void) |
671 | { | 666 | { |