aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon/smsc47m1.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hwmon/smsc47m1.c')
-rw-r--r--drivers/hwmon/smsc47m1.c198
1 files changed, 95 insertions, 103 deletions
diff --git a/drivers/hwmon/smsc47m1.c b/drivers/hwmon/smsc47m1.c
index 7c16c1c80ef1..1e21c8cc948f 100644
--- a/drivers/hwmon/smsc47m1.c
+++ b/drivers/hwmon/smsc47m1.c
@@ -32,6 +32,7 @@
32#include <linux/jiffies.h> 32#include <linux/jiffies.h>
33#include <linux/platform_device.h> 33#include <linux/platform_device.h>
34#include <linux/hwmon.h> 34#include <linux/hwmon.h>
35#include <linux/hwmon-sysfs.h>
35#include <linux/err.h> 36#include <linux/err.h>
36#include <linux/init.h> 37#include <linux/init.h>
37#include <linux/mutex.h> 38#include <linux/mutex.h>
@@ -157,11 +158,12 @@ static struct platform_driver smsc47m1_driver = {
157 .remove = __devexit_p(smsc47m1_remove), 158 .remove = __devexit_p(smsc47m1_remove),
158}; 159};
159 160
160/* nr is 0 or 1 in the callback functions below */ 161static ssize_t get_fan(struct device *dev, struct device_attribute
161 162 *devattr, char *buf)
162static ssize_t get_fan(struct device *dev, char *buf, int nr)
163{ 163{
164 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
164 struct smsc47m1_data *data = smsc47m1_update_device(dev, 0); 165 struct smsc47m1_data *data = smsc47m1_update_device(dev, 0);
166 int nr = attr->index;
165 /* This chip (stupidly) stops monitoring fan speed if PWM is 167 /* This chip (stupidly) stops monitoring fan speed if PWM is
166 enabled and duty cycle is 0%. This is fine if the monitoring 168 enabled and duty cycle is 0%. This is fine if the monitoring
167 and control concern the same fan, but troublesome if they are 169 and control concern the same fan, but troublesome if they are
@@ -173,42 +175,54 @@ static ssize_t get_fan(struct device *dev, char *buf, int nr)
173 return sprintf(buf, "%d\n", rpm); 175 return sprintf(buf, "%d\n", rpm);
174} 176}
175 177
176static ssize_t get_fan_min(struct device *dev, char *buf, int nr) 178static ssize_t get_fan_min(struct device *dev, struct device_attribute
179 *devattr, char *buf)
177{ 180{
181 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
178 struct smsc47m1_data *data = smsc47m1_update_device(dev, 0); 182 struct smsc47m1_data *data = smsc47m1_update_device(dev, 0);
183 int nr = attr->index;
179 int rpm = MIN_FROM_REG(data->fan_preload[nr], 184 int rpm = MIN_FROM_REG(data->fan_preload[nr],
180 DIV_FROM_REG(data->fan_div[nr])); 185 DIV_FROM_REG(data->fan_div[nr]));
181 return sprintf(buf, "%d\n", rpm); 186 return sprintf(buf, "%d\n", rpm);
182} 187}
183 188
184static ssize_t get_fan_div(struct device *dev, char *buf, int nr) 189static ssize_t get_fan_div(struct device *dev, struct device_attribute
190 *devattr, char *buf)
185{ 191{
192 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
186 struct smsc47m1_data *data = smsc47m1_update_device(dev, 0); 193 struct smsc47m1_data *data = smsc47m1_update_device(dev, 0);
187 return sprintf(buf, "%d\n", DIV_FROM_REG(data->fan_div[nr])); 194 return sprintf(buf, "%d\n", DIV_FROM_REG(data->fan_div[attr->index]));
188} 195}
189 196
190static ssize_t get_pwm(struct device *dev, char *buf, int nr) 197static ssize_t get_pwm(struct device *dev, struct device_attribute
198 *devattr, char *buf)
191{ 199{
200 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
192 struct smsc47m1_data *data = smsc47m1_update_device(dev, 0); 201 struct smsc47m1_data *data = smsc47m1_update_device(dev, 0);
193 return sprintf(buf, "%d\n", PWM_FROM_REG(data->pwm[nr])); 202 return sprintf(buf, "%d\n", PWM_FROM_REG(data->pwm[attr->index]));
194} 203}
195 204
196static ssize_t get_pwm_en(struct device *dev, char *buf, int nr) 205static ssize_t get_pwm_en(struct device *dev, struct device_attribute
206 *devattr, char *buf)
197{ 207{
208 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
198 struct smsc47m1_data *data = smsc47m1_update_device(dev, 0); 209 struct smsc47m1_data *data = smsc47m1_update_device(dev, 0);
199 return sprintf(buf, "%d\n", PWM_EN_FROM_REG(data->pwm[nr])); 210 return sprintf(buf, "%d\n", PWM_EN_FROM_REG(data->pwm[attr->index]));
200} 211}
201 212
202static ssize_t get_alarms(struct device *dev, struct device_attribute *attr, char *buf) 213static ssize_t get_alarms(struct device *dev, struct device_attribute
214 *devattr, char *buf)
203{ 215{
204 struct smsc47m1_data *data = smsc47m1_update_device(dev, 0); 216 struct smsc47m1_data *data = smsc47m1_update_device(dev, 0);
205 return sprintf(buf, "%d\n", data->alarms); 217 return sprintf(buf, "%d\n", data->alarms);
206} 218}
207 219
208static ssize_t set_fan_min(struct device *dev, const char *buf, 220static ssize_t set_fan_min(struct device *dev, struct device_attribute
209 size_t count, int nr) 221 *devattr, const char *buf, size_t count)
210{ 222{
223 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
211 struct smsc47m1_data *data = dev_get_drvdata(dev); 224 struct smsc47m1_data *data = dev_get_drvdata(dev);
225 int nr = attr->index;
212 long rpmdiv, val = simple_strtol(buf, NULL, 10); 226 long rpmdiv, val = simple_strtol(buf, NULL, 10);
213 227
214 mutex_lock(&data->update_lock); 228 mutex_lock(&data->update_lock);
@@ -231,11 +245,12 @@ static ssize_t set_fan_min(struct device *dev, const char *buf,
231 determined in part by the fan clock divider. This follows the principle 245 determined in part by the fan clock divider. This follows the principle
232 of least surprise; the user doesn't expect the fan minimum to change just 246 of least surprise; the user doesn't expect the fan minimum to change just
233 because the divider changed. */ 247 because the divider changed. */
234static ssize_t set_fan_div(struct device *dev, const char *buf, 248static ssize_t set_fan_div(struct device *dev, struct device_attribute
235 size_t count, int nr) 249 *devattr, const char *buf, size_t count)
236{ 250{
251 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
237 struct smsc47m1_data *data = dev_get_drvdata(dev); 252 struct smsc47m1_data *data = dev_get_drvdata(dev);
238 253 int nr = attr->index;
239 long new_div = simple_strtol(buf, NULL, 10), tmp; 254 long new_div = simple_strtol(buf, NULL, 10), tmp;
240 u8 old_div = DIV_FROM_REG(data->fan_div[nr]); 255 u8 old_div = DIV_FROM_REG(data->fan_div[nr]);
241 256
@@ -279,11 +294,12 @@ static ssize_t set_fan_div(struct device *dev, const char *buf,
279 return count; 294 return count;
280} 295}
281 296
282static ssize_t set_pwm(struct device *dev, const char *buf, 297static ssize_t set_pwm(struct device *dev, struct device_attribute
283 size_t count, int nr) 298 *devattr, const char *buf, size_t count)
284{ 299{
300 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
285 struct smsc47m1_data *data = dev_get_drvdata(dev); 301 struct smsc47m1_data *data = dev_get_drvdata(dev);
286 302 int nr = attr->index;
287 long val = simple_strtol(buf, NULL, 10); 303 long val = simple_strtol(buf, NULL, 10);
288 304
289 if (val < 0 || val > 255) 305 if (val < 0 || val > 255)
@@ -299,11 +315,12 @@ static ssize_t set_pwm(struct device *dev, const char *buf,
299 return count; 315 return count;
300} 316}
301 317
302static ssize_t set_pwm_en(struct device *dev, const char *buf, 318static ssize_t set_pwm_en(struct device *dev, struct device_attribute
303 size_t count, int nr) 319 *devattr, const char *buf, size_t count)
304{ 320{
321 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
305 struct smsc47m1_data *data = dev_get_drvdata(dev); 322 struct smsc47m1_data *data = dev_get_drvdata(dev);
306 323 int nr = attr->index;
307 long val = simple_strtol(buf, NULL, 10); 324 long val = simple_strtol(buf, NULL, 10);
308 325
309 if (val != 0 && val != 1) 326 if (val != 0 && val != 1)
@@ -320,56 +337,16 @@ static ssize_t set_pwm_en(struct device *dev, const char *buf,
320} 337}
321 338
322#define fan_present(offset) \ 339#define fan_present(offset) \
323static ssize_t get_fan##offset (struct device *dev, struct device_attribute *attr, char *buf) \ 340static SENSOR_DEVICE_ATTR(fan##offset##_input, S_IRUGO, get_fan, \
324{ \ 341 NULL, offset - 1); \
325 return get_fan(dev, buf, offset - 1); \ 342static SENSOR_DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \
326} \ 343 get_fan_min, set_fan_min, offset - 1); \
327static ssize_t get_fan##offset##_min (struct device *dev, struct device_attribute *attr, char *buf) \ 344static SENSOR_DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR, \
328{ \ 345 get_fan_div, set_fan_div, offset - 1); \
329 return get_fan_min(dev, buf, offset - 1); \ 346static SENSOR_DEVICE_ATTR(pwm##offset, S_IRUGO | S_IWUSR, \
330} \ 347 get_pwm, set_pwm, offset - 1); \
331static ssize_t set_fan##offset##_min (struct device *dev, struct device_attribute *attr, \ 348static SENSOR_DEVICE_ATTR(pwm##offset##_enable, S_IRUGO | S_IWUSR, \
332 const char *buf, size_t count) \ 349 get_pwm_en, set_pwm_en, offset - 1)
333{ \
334 return set_fan_min(dev, buf, count, offset - 1); \
335} \
336static ssize_t get_fan##offset##_div (struct device *dev, struct device_attribute *attr, char *buf) \
337{ \
338 return get_fan_div(dev, buf, offset - 1); \
339} \
340static ssize_t set_fan##offset##_div (struct device *dev, struct device_attribute *attr, \
341 const char *buf, size_t count) \
342{ \
343 return set_fan_div(dev, buf, count, offset - 1); \
344} \
345static ssize_t get_pwm##offset (struct device *dev, struct device_attribute *attr, char *buf) \
346{ \
347 return get_pwm(dev, buf, offset - 1); \
348} \
349static ssize_t set_pwm##offset (struct device *dev, struct device_attribute *attr, \
350 const char *buf, size_t count) \
351{ \
352 return set_pwm(dev, buf, count, offset - 1); \
353} \
354static ssize_t get_pwm##offset##_en (struct device *dev, struct device_attribute *attr, char *buf) \
355{ \
356 return get_pwm_en(dev, buf, offset - 1); \
357} \
358static ssize_t set_pwm##offset##_en (struct device *dev, struct device_attribute *attr, \
359 const char *buf, size_t count) \
360{ \
361 return set_pwm_en(dev, buf, count, offset - 1); \
362} \
363static DEVICE_ATTR(fan##offset##_input, S_IRUGO, get_fan##offset, \
364 NULL); \
365static DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \
366 get_fan##offset##_min, set_fan##offset##_min); \
367static DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR, \
368 get_fan##offset##_div, set_fan##offset##_div); \
369static DEVICE_ATTR(pwm##offset, S_IRUGO | S_IWUSR, \
370 get_pwm##offset, set_pwm##offset); \
371static DEVICE_ATTR(pwm##offset##_enable, S_IRUGO | S_IWUSR, \
372 get_pwm##offset##_en, set_pwm##offset##_en);
373 350
374fan_present(1); 351fan_present(1);
375fan_present(2); 352fan_present(2);
@@ -390,22 +367,22 @@ static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
390 setup so we create them individually. It is still convenient to define a 367 setup so we create them individually. It is still convenient to define a
391 group to remove them all at once. */ 368 group to remove them all at once. */
392static struct attribute *smsc47m1_attributes[] = { 369static struct attribute *smsc47m1_attributes[] = {
393 &dev_attr_fan1_input.attr, 370 &sensor_dev_attr_fan1_input.dev_attr.attr,
394 &dev_attr_fan1_min.attr, 371 &sensor_dev_attr_fan1_min.dev_attr.attr,
395 &dev_attr_fan1_div.attr, 372 &sensor_dev_attr_fan1_div.dev_attr.attr,
396 &dev_attr_fan2_input.attr, 373 &sensor_dev_attr_fan2_input.dev_attr.attr,
397 &dev_attr_fan2_min.attr, 374 &sensor_dev_attr_fan2_min.dev_attr.attr,
398 &dev_attr_fan2_div.attr, 375 &sensor_dev_attr_fan2_div.dev_attr.attr,
399 &dev_attr_fan3_input.attr, 376 &sensor_dev_attr_fan3_input.dev_attr.attr,
400 &dev_attr_fan3_min.attr, 377 &sensor_dev_attr_fan3_min.dev_attr.attr,
401 &dev_attr_fan3_div.attr, 378 &sensor_dev_attr_fan3_div.dev_attr.attr,
402 379
403 &dev_attr_pwm1.attr, 380 &sensor_dev_attr_pwm1.dev_attr.attr,
404 &dev_attr_pwm1_enable.attr, 381 &sensor_dev_attr_pwm1_enable.dev_attr.attr,
405 &dev_attr_pwm2.attr, 382 &sensor_dev_attr_pwm2.dev_attr.attr,
406 &dev_attr_pwm2_enable.attr, 383 &sensor_dev_attr_pwm2_enable.dev_attr.attr,
407 &dev_attr_pwm3.attr, 384 &sensor_dev_attr_pwm3.dev_attr.attr,
408 &dev_attr_pwm3_enable.attr, 385 &sensor_dev_attr_pwm3_enable.dev_attr.attr,
409 386
410 &dev_attr_alarms.attr, 387 &dev_attr_alarms.attr,
411 &dev_attr_name.attr, 388 &dev_attr_name.attr,
@@ -547,46 +524,61 @@ static int __devinit smsc47m1_probe(struct platform_device *pdev)
547 524
548 /* Register sysfs hooks */ 525 /* Register sysfs hooks */
549 if (fan1) { 526 if (fan1) {
550 if ((err = device_create_file(dev, &dev_attr_fan1_input)) 527 if ((err = device_create_file(dev,
551 || (err = device_create_file(dev, &dev_attr_fan1_min)) 528 &sensor_dev_attr_fan1_input.dev_attr))
552 || (err = device_create_file(dev, &dev_attr_fan1_div))) 529 || (err = device_create_file(dev,
530 &sensor_dev_attr_fan1_min.dev_attr))
531 || (err = device_create_file(dev,
532 &sensor_dev_attr_fan1_div.dev_attr)))
553 goto error_remove_files; 533 goto error_remove_files;
554 } else 534 } else
555 dev_dbg(dev, "Fan 1 not enabled by hardware, skipping\n"); 535 dev_dbg(dev, "Fan 1 not enabled by hardware, skipping\n");
556 536
557 if (fan2) { 537 if (fan2) {
558 if ((err = device_create_file(dev, &dev_attr_fan2_input)) 538 if ((err = device_create_file(dev,
559 || (err = device_create_file(dev, &dev_attr_fan2_min)) 539 &sensor_dev_attr_fan2_input.dev_attr))
560 || (err = device_create_file(dev, &dev_attr_fan2_div))) 540 || (err = device_create_file(dev,
541 &sensor_dev_attr_fan2_min.dev_attr))
542 || (err = device_create_file(dev,
543 &sensor_dev_attr_fan2_div.dev_attr)))
561 goto error_remove_files; 544 goto error_remove_files;
562 } else 545 } else
563 dev_dbg(dev, "Fan 2 not enabled by hardware, skipping\n"); 546 dev_dbg(dev, "Fan 2 not enabled by hardware, skipping\n");
564 547
565 if (fan3) { 548 if (fan3) {
566 if ((err = device_create_file(dev, &dev_attr_fan3_input)) 549 if ((err = device_create_file(dev,
567 || (err = device_create_file(dev, &dev_attr_fan3_min)) 550 &sensor_dev_attr_fan3_input.dev_attr))
568 || (err = device_create_file(dev, &dev_attr_fan3_div))) 551 || (err = device_create_file(dev,
552 &sensor_dev_attr_fan3_min.dev_attr))
553 || (err = device_create_file(dev,
554 &sensor_dev_attr_fan3_div.dev_attr)))
569 goto error_remove_files; 555 goto error_remove_files;
570 } else 556 } else
571 dev_dbg(dev, "Fan 3 not enabled by hardware, skipping\n"); 557 dev_dbg(dev, "Fan 3 not enabled by hardware, skipping\n");
572 558
573 if (pwm1) { 559 if (pwm1) {
574 if ((err = device_create_file(dev, &dev_attr_pwm1)) 560 if ((err = device_create_file(dev,
575 || (err = device_create_file(dev, &dev_attr_pwm1_enable))) 561 &sensor_dev_attr_pwm1.dev_attr))
562 || (err = device_create_file(dev,
563 &sensor_dev_attr_pwm1_enable.dev_attr)))
576 goto error_remove_files; 564 goto error_remove_files;
577 } else 565 } else
578 dev_dbg(dev, "PWM 1 not enabled by hardware, skipping\n"); 566 dev_dbg(dev, "PWM 1 not enabled by hardware, skipping\n");
579 567
580 if (pwm2) { 568 if (pwm2) {
581 if ((err = device_create_file(dev, &dev_attr_pwm2)) 569 if ((err = device_create_file(dev,
582 || (err = device_create_file(dev, &dev_attr_pwm2_enable))) 570 &sensor_dev_attr_pwm2.dev_attr))
571 || (err = device_create_file(dev,
572 &sensor_dev_attr_pwm2_enable.dev_attr)))
583 goto error_remove_files; 573 goto error_remove_files;
584 } else 574 } else
585 dev_dbg(dev, "PWM 2 not enabled by hardware, skipping\n"); 575 dev_dbg(dev, "PWM 2 not enabled by hardware, skipping\n");
586 576
587 if (pwm3) { 577 if (pwm3) {
588 if ((err = device_create_file(dev, &dev_attr_pwm3)) 578 if ((err = device_create_file(dev,
589 || (err = device_create_file(dev, &dev_attr_pwm3_enable))) 579 &sensor_dev_attr_pwm3.dev_attr))
580 || (err = device_create_file(dev,
581 &sensor_dev_attr_pwm3_enable.dev_attr)))
590 goto error_remove_files; 582 goto error_remove_files;
591 } else 583 } else
592 dev_dbg(dev, "PWM 3 not enabled by hardware, skipping\n"); 584 dev_dbg(dev, "PWM 3 not enabled by hardware, skipping\n");