diff options
-rw-r--r-- | drivers/hwmon/tmp401.c | 205 |
1 files changed, 97 insertions, 108 deletions
diff --git a/drivers/hwmon/tmp401.c b/drivers/hwmon/tmp401.c index d58b40a6613d..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 | { |
@@ -535,6 +577,27 @@ static int tmp401_detect(struct i2c_client *client, | |||
535 | return 0; | 577 | return 0; |
536 | } | 578 | } |
537 | 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 | |||
538 | static int tmp401_probe(struct i2c_client *client, | 601 | static int tmp401_probe(struct i2c_client *client, |
539 | const struct i2c_device_id *id) | 602 | const struct i2c_device_id *id) |
540 | { | 603 | { |
@@ -587,91 +650,17 @@ exit_remove: | |||
587 | return err; | 650 | return err; |
588 | } | 651 | } |
589 | 652 | ||
590 | static int tmp401_remove(struct i2c_client *client) | 653 | static struct i2c_driver tmp401_driver = { |
591 | { | 654 | .class = I2C_CLASS_HWMON, |
592 | struct tmp401_data *data = i2c_get_clientdata(client); | 655 | .driver = { |
593 | int i; | 656 | .name = "tmp401", |
594 | 657 | }, | |
595 | if (data->hwmon_dev) | 658 | .probe = tmp401_probe, |
596 | hwmon_device_unregister(data->hwmon_dev); | 659 | .remove = tmp401_remove, |
597 | 660 | .id_table = tmp401_id, | |
598 | for (i = 0; i < ARRAY_SIZE(tmp401_attr); i++) | 661 | .detect = tmp401_detect, |
599 | device_remove_file(&client->dev, &tmp401_attr[i].dev_attr); | 662 | .address_list = normal_i2c, |
600 | 663 | }; | |
601 | if (data->kind == tmp411) { | ||
602 | for (i = 0; i < ARRAY_SIZE(tmp411_attr); i++) | ||
603 | device_remove_file(&client->dev, | ||
604 | &tmp411_attr[i].dev_attr); | ||
605 | } | ||
606 | |||
607 | kfree(data); | ||
608 | return 0; | ||
609 | } | ||
610 | |||
611 | static struct tmp401_data *tmp401_update_device_reg16( | ||
612 | struct i2c_client *client, struct tmp401_data *data) | ||
613 | { | ||
614 | int i; | ||
615 | |||
616 | for (i = 0; i < 2; i++) { | ||
617 | /* | ||
618 | * High byte must be read first immediately followed | ||
619 | * by the low byte | ||
620 | */ | ||
621 | data->temp[i] = i2c_smbus_read_byte_data(client, | ||
622 | TMP401_TEMP_MSB[i]) << 8; | ||
623 | data->temp[i] |= i2c_smbus_read_byte_data(client, | ||
624 | TMP401_TEMP_LSB[i]); | ||
625 | data->temp_low[i] = i2c_smbus_read_byte_data(client, | ||
626 | TMP401_TEMP_LOW_LIMIT_MSB_READ[i]) << 8; | ||
627 | data->temp_low[i] |= i2c_smbus_read_byte_data(client, | ||
628 | TMP401_TEMP_LOW_LIMIT_LSB[i]); | ||
629 | data->temp_high[i] = i2c_smbus_read_byte_data(client, | ||
630 | TMP401_TEMP_HIGH_LIMIT_MSB_READ[i]) << 8; | ||
631 | data->temp_high[i] |= i2c_smbus_read_byte_data(client, | ||
632 | TMP401_TEMP_HIGH_LIMIT_LSB[i]); | ||
633 | data->temp_crit[i] = i2c_smbus_read_byte_data(client, | ||
634 | TMP401_TEMP_CRIT_LIMIT[i]); | ||
635 | |||
636 | if (data->kind == tmp411) { | ||
637 | data->temp_lowest[i] = i2c_smbus_read_byte_data(client, | ||
638 | TMP411_TEMP_LOWEST_MSB[i]) << 8; | ||
639 | data->temp_lowest[i] |= i2c_smbus_read_byte_data( | ||
640 | client, TMP411_TEMP_LOWEST_LSB[i]); | ||
641 | |||
642 | data->temp_highest[i] = i2c_smbus_read_byte_data( | ||
643 | client, TMP411_TEMP_HIGHEST_MSB[i]) << 8; | ||
644 | data->temp_highest[i] |= i2c_smbus_read_byte_data( | ||
645 | client, TMP411_TEMP_HIGHEST_LSB[i]); | ||
646 | } | ||
647 | } | ||
648 | return data; | ||
649 | } | ||
650 | |||
651 | static struct tmp401_data *tmp401_update_device(struct device *dev) | ||
652 | { | ||
653 | struct i2c_client *client = to_i2c_client(dev); | ||
654 | struct tmp401_data *data = i2c_get_clientdata(client); | ||
655 | |||
656 | mutex_lock(&data->update_lock); | ||
657 | |||
658 | if (time_after(jiffies, data->last_updated + HZ) || !data->valid) { | ||
659 | data->status = i2c_smbus_read_byte_data(client, TMP401_STATUS); | ||
660 | data->config = i2c_smbus_read_byte_data(client, | ||
661 | TMP401_CONFIG_READ); | ||
662 | tmp401_update_device_reg16(client, data); | ||
663 | |||
664 | data->temp_crit_hyst = i2c_smbus_read_byte_data(client, | ||
665 | TMP401_TEMP_CRIT_HYST); | ||
666 | |||
667 | data->last_updated = jiffies; | ||
668 | data->valid = 1; | ||
669 | } | ||
670 | |||
671 | mutex_unlock(&data->update_lock); | ||
672 | |||
673 | return data; | ||
674 | } | ||
675 | 664 | ||
676 | static int __init tmp401_init(void) | 665 | static int __init tmp401_init(void) |
677 | { | 666 | { |