aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon/adm9240.c
diff options
context:
space:
mode:
authorAxel Lin <axel.lin@ingics.com>2014-07-03 09:59:49 -0400
committerGuenter Roeck <linux@roeck-us.net>2014-08-04 10:01:37 -0400
commit4341fc3f32b278d136179772338ccaa31f222c99 (patch)
tree066177fd4444e84290e3ef8cb4cc336e1d58da4e /drivers/hwmon/adm9240.c
parentb060f3c4ac99b050b990b316637f7fd9898b9fd7 (diff)
hwmon: (adm9240) Avoid forward declaration
Reorder functions to avoid forward declaration. Signed-off-by: Axel Lin <axel.lin@ingics.com> Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Diffstat (limited to 'drivers/hwmon/adm9240.c')
-rw-r--r--drivers/hwmon/adm9240.c315
1 files changed, 153 insertions, 162 deletions
diff --git a/drivers/hwmon/adm9240.c b/drivers/hwmon/adm9240.c
index 086d02a9ecdc..8235ae4cbeb5 100644
--- a/drivers/hwmon/adm9240.c
+++ b/drivers/hwmon/adm9240.c
@@ -130,35 +130,6 @@ static inline unsigned int AOUT_FROM_REG(u8 reg)
130 return SCALE(reg, 1250, 255); 130 return SCALE(reg, 1250, 255);
131} 131}
132 132
133static int adm9240_probe(struct i2c_client *client,
134 const struct i2c_device_id *id);
135static int adm9240_detect(struct i2c_client *client,
136 struct i2c_board_info *info);
137static void adm9240_init_client(struct i2c_client *client);
138static int adm9240_remove(struct i2c_client *client);
139static struct adm9240_data *adm9240_update_device(struct device *dev);
140
141/* driver data */
142static const struct i2c_device_id adm9240_id[] = {
143 { "adm9240", adm9240 },
144 { "ds1780", ds1780 },
145 { "lm81", lm81 },
146 { }
147};
148MODULE_DEVICE_TABLE(i2c, adm9240_id);
149
150static struct i2c_driver adm9240_driver = {
151 .class = I2C_CLASS_HWMON,
152 .driver = {
153 .name = "adm9240",
154 },
155 .probe = adm9240_probe,
156 .remove = adm9240_remove,
157 .id_table = adm9240_id,
158 .detect = adm9240_detect,
159 .address_list = normal_i2c,
160};
161
162/* per client data */ 133/* per client data */
163struct adm9240_data { 134struct adm9240_data {
164 struct device *hwmon_dev; 135 struct device *hwmon_dev;
@@ -181,6 +152,110 @@ struct adm9240_data {
181 u8 vrm; /* -- vrm set on startup, no accessor */ 152 u8 vrm; /* -- vrm set on startup, no accessor */
182}; 153};
183 154
155/* write new fan div, callers must hold data->update_lock */
156static void adm9240_write_fan_div(struct i2c_client *client, int nr,
157 u8 fan_div)
158{
159 u8 reg, old, shift = (nr + 2) * 2;
160
161 reg = i2c_smbus_read_byte_data(client, ADM9240_REG_VID_FAN_DIV);
162 old = (reg >> shift) & 3;
163 reg &= ~(3 << shift);
164 reg |= (fan_div << shift);
165 i2c_smbus_write_byte_data(client, ADM9240_REG_VID_FAN_DIV, reg);
166 dev_dbg(&client->dev,
167 "fan%d clock divider changed from %u to %u\n",
168 nr + 1, 1 << old, 1 << fan_div);
169}
170
171static struct adm9240_data *adm9240_update_device(struct device *dev)
172{
173 struct i2c_client *client = to_i2c_client(dev);
174 struct adm9240_data *data = i2c_get_clientdata(client);
175 int i;
176
177 mutex_lock(&data->update_lock);
178
179 /* minimum measurement cycle: 1.75 seconds */
180 if (time_after(jiffies, data->last_updated_measure + (HZ * 7 / 4))
181 || !data->valid) {
182
183 for (i = 0; i < 6; i++) { /* read voltages */
184 data->in[i] = i2c_smbus_read_byte_data(client,
185 ADM9240_REG_IN(i));
186 }
187 data->alarms = i2c_smbus_read_byte_data(client,
188 ADM9240_REG_INT(0)) |
189 i2c_smbus_read_byte_data(client,
190 ADM9240_REG_INT(1)) << 8;
191
192 /*
193 * read temperature: assume temperature changes less than
194 * 0.5'C per two measurement cycles thus ignore possible
195 * but unlikely aliasing error on lsb reading. --Grant
196 */
197 data->temp = ((i2c_smbus_read_byte_data(client,
198 ADM9240_REG_TEMP) << 8) |
199 i2c_smbus_read_byte_data(client,
200 ADM9240_REG_TEMP_CONF)) / 128;
201
202 for (i = 0; i < 2; i++) { /* read fans */
203 data->fan[i] = i2c_smbus_read_byte_data(client,
204 ADM9240_REG_FAN(i));
205
206 /* adjust fan clock divider on overflow */
207 if (data->valid && data->fan[i] == 255 &&
208 data->fan_div[i] < 3) {
209
210 adm9240_write_fan_div(client, i,
211 ++data->fan_div[i]);
212
213 /* adjust fan_min if active, but not to 0 */
214 if (data->fan_min[i] < 255 &&
215 data->fan_min[i] >= 2)
216 data->fan_min[i] /= 2;
217 }
218 }
219 data->last_updated_measure = jiffies;
220 }
221
222 /* minimum config reading cycle: 300 seconds */
223 if (time_after(jiffies, data->last_updated_config + (HZ * 300))
224 || !data->valid) {
225
226 for (i = 0; i < 6; i++) {
227 data->in_min[i] = i2c_smbus_read_byte_data(client,
228 ADM9240_REG_IN_MIN(i));
229 data->in_max[i] = i2c_smbus_read_byte_data(client,
230 ADM9240_REG_IN_MAX(i));
231 }
232 for (i = 0; i < 2; i++) {
233 data->fan_min[i] = i2c_smbus_read_byte_data(client,
234 ADM9240_REG_FAN_MIN(i));
235 }
236 data->temp_max[0] = i2c_smbus_read_byte_data(client,
237 ADM9240_REG_TEMP_MAX(0));
238 data->temp_max[1] = i2c_smbus_read_byte_data(client,
239 ADM9240_REG_TEMP_MAX(1));
240
241 /* read fan divs and 5-bit VID */
242 i = i2c_smbus_read_byte_data(client, ADM9240_REG_VID_FAN_DIV);
243 data->fan_div[0] = (i >> 4) & 3;
244 data->fan_div[1] = (i >> 6) & 3;
245 data->vid = i & 0x0f;
246 data->vid |= (i2c_smbus_read_byte_data(client,
247 ADM9240_REG_VID4) & 1) << 4;
248 /* read analog out */
249 data->aout = i2c_smbus_read_byte_data(client,
250 ADM9240_REG_ANALOG_OUT);
251
252 data->last_updated_config = jiffies;
253 data->valid = 1;
254 }
255 mutex_unlock(&data->update_lock);
256 return data;
257}
258
184/*** sysfs accessors ***/ 259/*** sysfs accessors ***/
185 260
186/* temperature */ 261/* temperature */
@@ -340,22 +415,6 @@ static ssize_t show_fan_div(struct device *dev,
340 return sprintf(buf, "%d\n", 1 << data->fan_div[attr->index]); 415 return sprintf(buf, "%d\n", 1 << data->fan_div[attr->index]);
341} 416}
342 417
343/* write new fan div, callers must hold data->update_lock */
344static void adm9240_write_fan_div(struct i2c_client *client, int nr,
345 u8 fan_div)
346{
347 u8 reg, old, shift = (nr + 2) * 2;
348
349 reg = i2c_smbus_read_byte_data(client, ADM9240_REG_VID_FAN_DIV);
350 old = (reg >> shift) & 3;
351 reg &= ~(3 << shift);
352 reg |= (fan_div << shift);
353 i2c_smbus_write_byte_data(client, ADM9240_REG_VID_FAN_DIV, reg);
354 dev_dbg(&client->dev,
355 "fan%d clock divider changed from %u to %u\n",
356 nr + 1, 1 << old, 1 << fan_div);
357}
358
359/* 418/*
360 * set fan speed low limit: 419 * set fan speed low limit:
361 * 420 *
@@ -620,49 +679,6 @@ static int adm9240_detect(struct i2c_client *new_client,
620 return 0; 679 return 0;
621} 680}
622 681
623static int adm9240_probe(struct i2c_client *new_client,
624 const struct i2c_device_id *id)
625{
626 struct adm9240_data *data;
627 int err;
628
629 data = devm_kzalloc(&new_client->dev, sizeof(*data), GFP_KERNEL);
630 if (!data)
631 return -ENOMEM;
632
633 i2c_set_clientdata(new_client, data);
634 mutex_init(&data->update_lock);
635
636 adm9240_init_client(new_client);
637
638 /* populate sysfs filesystem */
639 err = sysfs_create_group(&new_client->dev.kobj, &adm9240_group);
640 if (err)
641 return err;
642
643 data->hwmon_dev = hwmon_device_register(&new_client->dev);
644 if (IS_ERR(data->hwmon_dev)) {
645 err = PTR_ERR(data->hwmon_dev);
646 goto exit_remove;
647 }
648
649 return 0;
650
651exit_remove:
652 sysfs_remove_group(&new_client->dev.kobj, &adm9240_group);
653 return err;
654}
655
656static int adm9240_remove(struct i2c_client *client)
657{
658 struct adm9240_data *data = i2c_get_clientdata(client);
659
660 hwmon_device_unregister(data->hwmon_dev);
661 sysfs_remove_group(&client->dev.kobj, &adm9240_group);
662
663 return 0;
664}
665
666static void adm9240_init_client(struct i2c_client *client) 682static void adm9240_init_client(struct i2c_client *client)
667{ 683{
668 struct adm9240_data *data = i2c_get_clientdata(client); 684 struct adm9240_data *data = i2c_get_clientdata(client);
@@ -705,93 +721,68 @@ static void adm9240_init_client(struct i2c_client *client)
705 } 721 }
706} 722}
707 723
708static struct adm9240_data *adm9240_update_device(struct device *dev) 724static int adm9240_probe(struct i2c_client *new_client,
725 const struct i2c_device_id *id)
709{ 726{
710 struct i2c_client *client = to_i2c_client(dev); 727 struct adm9240_data *data;
711 struct adm9240_data *data = i2c_get_clientdata(client); 728 int err;
712 int i;
713 729
714 mutex_lock(&data->update_lock); 730 data = devm_kzalloc(&new_client->dev, sizeof(*data), GFP_KERNEL);
731 if (!data)
732 return -ENOMEM;
715 733
716 /* minimum measurement cycle: 1.75 seconds */ 734 i2c_set_clientdata(new_client, data);
717 if (time_after(jiffies, data->last_updated_measure + (HZ * 7 / 4)) 735 mutex_init(&data->update_lock);
718 || !data->valid) {
719 736
720 for (i = 0; i < 6; i++) { /* read voltages */ 737 adm9240_init_client(new_client);
721 data->in[i] = i2c_smbus_read_byte_data(client,
722 ADM9240_REG_IN(i));
723 }
724 data->alarms = i2c_smbus_read_byte_data(client,
725 ADM9240_REG_INT(0)) |
726 i2c_smbus_read_byte_data(client,
727 ADM9240_REG_INT(1)) << 8;
728 738
729 /* 739 /* populate sysfs filesystem */
730 * read temperature: assume temperature changes less than 740 err = sysfs_create_group(&new_client->dev.kobj, &adm9240_group);
731 * 0.5'C per two measurement cycles thus ignore possible 741 if (err)
732 * but unlikely aliasing error on lsb reading. --Grant 742 return err;
733 */
734 data->temp = ((i2c_smbus_read_byte_data(client,
735 ADM9240_REG_TEMP) << 8) |
736 i2c_smbus_read_byte_data(client,
737 ADM9240_REG_TEMP_CONF)) / 128;
738 743
739 for (i = 0; i < 2; i++) { /* read fans */ 744 data->hwmon_dev = hwmon_device_register(&new_client->dev);
740 data->fan[i] = i2c_smbus_read_byte_data(client, 745 if (IS_ERR(data->hwmon_dev)) {
741 ADM9240_REG_FAN(i)); 746 err = PTR_ERR(data->hwmon_dev);
747 goto exit_remove;
748 }
742 749
743 /* adjust fan clock divider on overflow */ 750 return 0;
744 if (data->valid && data->fan[i] == 255 &&
745 data->fan_div[i] < 3) {
746 751
747 adm9240_write_fan_div(client, i, 752exit_remove:
748 ++data->fan_div[i]); 753 sysfs_remove_group(&new_client->dev.kobj, &adm9240_group);
754 return err;
755}
749 756
750 /* adjust fan_min if active, but not to 0 */ 757static int adm9240_remove(struct i2c_client *client)
751 if (data->fan_min[i] < 255 && 758{
752 data->fan_min[i] >= 2) 759 struct adm9240_data *data = i2c_get_clientdata(client);
753 data->fan_min[i] /= 2;
754 }
755 }
756 data->last_updated_measure = jiffies;
757 }
758 760
759 /* minimum config reading cycle: 300 seconds */ 761 hwmon_device_unregister(data->hwmon_dev);
760 if (time_after(jiffies, data->last_updated_config + (HZ * 300)) 762 sysfs_remove_group(&client->dev.kobj, &adm9240_group);
761 || !data->valid) {
762 763
763 for (i = 0; i < 6; i++) { 764 return 0;
764 data->in_min[i] = i2c_smbus_read_byte_data(client, 765}
765 ADM9240_REG_IN_MIN(i));
766 data->in_max[i] = i2c_smbus_read_byte_data(client,
767 ADM9240_REG_IN_MAX(i));
768 }
769 for (i = 0; i < 2; i++) {
770 data->fan_min[i] = i2c_smbus_read_byte_data(client,
771 ADM9240_REG_FAN_MIN(i));
772 }
773 data->temp_max[0] = i2c_smbus_read_byte_data(client,
774 ADM9240_REG_TEMP_MAX(0));
775 data->temp_max[1] = i2c_smbus_read_byte_data(client,
776 ADM9240_REG_TEMP_MAX(1));
777 766
778 /* read fan divs and 5-bit VID */ 767static const struct i2c_device_id adm9240_id[] = {
779 i = i2c_smbus_read_byte_data(client, ADM9240_REG_VID_FAN_DIV); 768 { "adm9240", adm9240 },
780 data->fan_div[0] = (i >> 4) & 3; 769 { "ds1780", ds1780 },
781 data->fan_div[1] = (i >> 6) & 3; 770 { "lm81", lm81 },
782 data->vid = i & 0x0f; 771 { }
783 data->vid |= (i2c_smbus_read_byte_data(client, 772};
784 ADM9240_REG_VID4) & 1) << 4; 773MODULE_DEVICE_TABLE(i2c, adm9240_id);
785 /* read analog out */
786 data->aout = i2c_smbus_read_byte_data(client,
787 ADM9240_REG_ANALOG_OUT);
788 774
789 data->last_updated_config = jiffies; 775static struct i2c_driver adm9240_driver = {
790 data->valid = 1; 776 .class = I2C_CLASS_HWMON,
791 } 777 .driver = {
792 mutex_unlock(&data->update_lock); 778 .name = "adm9240",
793 return data; 779 },
794} 780 .probe = adm9240_probe,
781 .remove = adm9240_remove,
782 .id_table = adm9240_id,
783 .detect = adm9240_detect,
784 .address_list = normal_i2c,
785};
795 786
796module_i2c_driver(adm9240_driver); 787module_i2c_driver(adm9240_driver);
797 788