diff options
author | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
---|---|---|
committer | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
commit | 8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch) | |
tree | a8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /drivers/hwmon/max6639.c | |
parent | 406089d01562f1e2bf9f089fd7637009ebaad589 (diff) |
Patched in Tegra support.
Diffstat (limited to 'drivers/hwmon/max6639.c')
-rw-r--r-- | drivers/hwmon/max6639.c | 75 |
1 files changed, 41 insertions, 34 deletions
diff --git a/drivers/hwmon/max6639.c b/drivers/hwmon/max6639.c index 6e60036abfa..f20d9978ee7 100644 --- a/drivers/hwmon/max6639.c +++ b/drivers/hwmon/max6639.c | |||
@@ -72,8 +72,8 @@ static unsigned short normal_i2c[] = { 0x2c, 0x2e, 0x2f, I2C_CLIENT_END }; | |||
72 | 72 | ||
73 | static const int rpm_ranges[] = { 2000, 4000, 8000, 16000 }; | 73 | static const int rpm_ranges[] = { 2000, 4000, 8000, 16000 }; |
74 | 74 | ||
75 | #define FAN_FROM_REG(val, rpm_range) ((val) == 0 || (val) == 255 ? \ | 75 | #define FAN_FROM_REG(val, div, rpm_range) ((val) == 0 ? -1 : \ |
76 | 0 : (rpm_ranges[rpm_range] * 30) / (val)) | 76 | (val) == 255 ? 0 : (rpm_ranges[rpm_range] * 30) / ((div + 1) * (val))) |
77 | #define TEMP_LIMIT_TO_REG(val) SENSORS_LIMIT((val) / 1000, 0, 255) | 77 | #define TEMP_LIMIT_TO_REG(val) SENSORS_LIMIT((val) / 1000, 0, 255) |
78 | 78 | ||
79 | /* | 79 | /* |
@@ -208,7 +208,7 @@ static ssize_t set_temp_max(struct device *dev, | |||
208 | unsigned long val; | 208 | unsigned long val; |
209 | int res; | 209 | int res; |
210 | 210 | ||
211 | res = kstrtoul(buf, 10, &val); | 211 | res = strict_strtoul(buf, 10, &val); |
212 | if (res) | 212 | if (res) |
213 | return res; | 213 | return res; |
214 | 214 | ||
@@ -241,7 +241,7 @@ static ssize_t set_temp_crit(struct device *dev, | |||
241 | unsigned long val; | 241 | unsigned long val; |
242 | int res; | 242 | int res; |
243 | 243 | ||
244 | res = kstrtoul(buf, 10, &val); | 244 | res = strict_strtoul(buf, 10, &val); |
245 | if (res) | 245 | if (res) |
246 | return res; | 246 | return res; |
247 | 247 | ||
@@ -275,7 +275,7 @@ static ssize_t set_temp_emergency(struct device *dev, | |||
275 | unsigned long val; | 275 | unsigned long val; |
276 | int res; | 276 | int res; |
277 | 277 | ||
278 | res = kstrtoul(buf, 10, &val); | 278 | res = strict_strtoul(buf, 10, &val); |
279 | if (res) | 279 | if (res) |
280 | return res; | 280 | return res; |
281 | 281 | ||
@@ -308,7 +308,7 @@ static ssize_t set_pwm(struct device *dev, | |||
308 | unsigned long val; | 308 | unsigned long val; |
309 | int res; | 309 | int res; |
310 | 310 | ||
311 | res = kstrtoul(buf, 10, &val); | 311 | res = strict_strtoul(buf, 10, &val); |
312 | if (res) | 312 | if (res) |
313 | return res; | 313 | return res; |
314 | 314 | ||
@@ -333,7 +333,7 @@ static ssize_t show_fan_input(struct device *dev, | |||
333 | return PTR_ERR(data); | 333 | return PTR_ERR(data); |
334 | 334 | ||
335 | return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan[attr->index], | 335 | return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan[attr->index], |
336 | data->rpm_range)); | 336 | data->ppr, data->rpm_range)); |
337 | } | 337 | } |
338 | 338 | ||
339 | static ssize_t show_alarm(struct device *dev, | 339 | static ssize_t show_alarm(struct device *dev, |
@@ -429,9 +429,9 @@ static int max6639_init_client(struct i2c_client *client) | |||
429 | struct max6639_data *data = i2c_get_clientdata(client); | 429 | struct max6639_data *data = i2c_get_clientdata(client); |
430 | struct max6639_platform_data *max6639_info = | 430 | struct max6639_platform_data *max6639_info = |
431 | client->dev.platform_data; | 431 | client->dev.platform_data; |
432 | int i; | 432 | int i = 0; |
433 | int rpm_range = 1; /* default: 4000 RPM */ | 433 | int rpm_range = 1; /* default: 4000 RPM */ |
434 | int err; | 434 | int err = 0; |
435 | 435 | ||
436 | /* Reset chip to default values, see below for GCONFIG setup */ | 436 | /* Reset chip to default values, see below for GCONFIG setup */ |
437 | err = i2c_smbus_write_byte_data(client, MAX6639_REG_GCONFIG, | 437 | err = i2c_smbus_write_byte_data(client, MAX6639_REG_GCONFIG, |
@@ -446,6 +446,11 @@ static int max6639_init_client(struct i2c_client *client) | |||
446 | else | 446 | else |
447 | data->ppr = 2; | 447 | data->ppr = 2; |
448 | data->ppr -= 1; | 448 | data->ppr -= 1; |
449 | err = i2c_smbus_write_byte_data(client, | ||
450 | MAX6639_REG_FAN_PPR(i), | ||
451 | data->ppr << 5); | ||
452 | if (err) | ||
453 | goto exit; | ||
449 | 454 | ||
450 | if (max6639_info) | 455 | if (max6639_info) |
451 | rpm_range = rpm_range_to_reg(max6639_info->rpm_range); | 456 | rpm_range = rpm_range_to_reg(max6639_info->rpm_range); |
@@ -453,13 +458,6 @@ static int max6639_init_client(struct i2c_client *client) | |||
453 | 458 | ||
454 | for (i = 0; i < 2; i++) { | 459 | for (i = 0; i < 2; i++) { |
455 | 460 | ||
456 | /* Set Fan pulse per revolution */ | ||
457 | err = i2c_smbus_write_byte_data(client, | ||
458 | MAX6639_REG_FAN_PPR(i), | ||
459 | data->ppr << 6); | ||
460 | if (err) | ||
461 | goto exit; | ||
462 | |||
463 | /* Fans config PWM, RPM */ | 461 | /* Fans config PWM, RPM */ |
464 | err = i2c_smbus_write_byte_data(client, | 462 | err = i2c_smbus_write_byte_data(client, |
465 | MAX6639_REG_FAN_CONFIG1(i), | 463 | MAX6639_REG_FAN_CONFIG1(i), |
@@ -548,10 +546,11 @@ static int max6639_probe(struct i2c_client *client, | |||
548 | struct max6639_data *data; | 546 | struct max6639_data *data; |
549 | int err; | 547 | int err; |
550 | 548 | ||
551 | data = devm_kzalloc(&client->dev, sizeof(struct max6639_data), | 549 | data = kzalloc(sizeof(struct max6639_data), GFP_KERNEL); |
552 | GFP_KERNEL); | 550 | if (!data) { |
553 | if (!data) | 551 | err = -ENOMEM; |
554 | return -ENOMEM; | 552 | goto exit; |
553 | } | ||
555 | 554 | ||
556 | i2c_set_clientdata(client, data); | 555 | i2c_set_clientdata(client, data); |
557 | mutex_init(&data->update_lock); | 556 | mutex_init(&data->update_lock); |
@@ -559,12 +558,12 @@ static int max6639_probe(struct i2c_client *client, | |||
559 | /* Initialize the max6639 chip */ | 558 | /* Initialize the max6639 chip */ |
560 | err = max6639_init_client(client); | 559 | err = max6639_init_client(client); |
561 | if (err < 0) | 560 | if (err < 0) |
562 | return err; | 561 | goto error_free; |
563 | 562 | ||
564 | /* Register sysfs hooks */ | 563 | /* Register sysfs hooks */ |
565 | err = sysfs_create_group(&client->dev.kobj, &max6639_group); | 564 | err = sysfs_create_group(&client->dev.kobj, &max6639_group); |
566 | if (err) | 565 | if (err) |
567 | return err; | 566 | goto error_free; |
568 | 567 | ||
569 | data->hwmon_dev = hwmon_device_register(&client->dev); | 568 | data->hwmon_dev = hwmon_device_register(&client->dev); |
570 | if (IS_ERR(data->hwmon_dev)) { | 569 | if (IS_ERR(data->hwmon_dev)) { |
@@ -578,6 +577,9 @@ static int max6639_probe(struct i2c_client *client, | |||
578 | 577 | ||
579 | error_remove: | 578 | error_remove: |
580 | sysfs_remove_group(&client->dev.kobj, &max6639_group); | 579 | sysfs_remove_group(&client->dev.kobj, &max6639_group); |
580 | error_free: | ||
581 | kfree(data); | ||
582 | exit: | ||
581 | return err; | 583 | return err; |
582 | } | 584 | } |
583 | 585 | ||
@@ -588,13 +590,12 @@ static int max6639_remove(struct i2c_client *client) | |||
588 | hwmon_device_unregister(data->hwmon_dev); | 590 | hwmon_device_unregister(data->hwmon_dev); |
589 | sysfs_remove_group(&client->dev.kobj, &max6639_group); | 591 | sysfs_remove_group(&client->dev.kobj, &max6639_group); |
590 | 592 | ||
593 | kfree(data); | ||
591 | return 0; | 594 | return 0; |
592 | } | 595 | } |
593 | 596 | ||
594 | #ifdef CONFIG_PM_SLEEP | 597 | static int max6639_suspend(struct i2c_client *client, pm_message_t mesg) |
595 | static int max6639_suspend(struct device *dev) | ||
596 | { | 598 | { |
597 | struct i2c_client *client = to_i2c_client(dev); | ||
598 | int data = i2c_smbus_read_byte_data(client, MAX6639_REG_GCONFIG); | 599 | int data = i2c_smbus_read_byte_data(client, MAX6639_REG_GCONFIG); |
599 | if (data < 0) | 600 | if (data < 0) |
600 | return data; | 601 | return data; |
@@ -603,9 +604,8 @@ static int max6639_suspend(struct device *dev) | |||
603 | MAX6639_REG_GCONFIG, data | MAX6639_GCONFIG_STANDBY); | 604 | MAX6639_REG_GCONFIG, data | MAX6639_GCONFIG_STANDBY); |
604 | } | 605 | } |
605 | 606 | ||
606 | static int max6639_resume(struct device *dev) | 607 | static int max6639_resume(struct i2c_client *client) |
607 | { | 608 | { |
608 | struct i2c_client *client = to_i2c_client(dev); | ||
609 | int data = i2c_smbus_read_byte_data(client, MAX6639_REG_GCONFIG); | 609 | int data = i2c_smbus_read_byte_data(client, MAX6639_REG_GCONFIG); |
610 | if (data < 0) | 610 | if (data < 0) |
611 | return data; | 611 | return data; |
@@ -613,7 +613,6 @@ static int max6639_resume(struct device *dev) | |||
613 | return i2c_smbus_write_byte_data(client, | 613 | return i2c_smbus_write_byte_data(client, |
614 | MAX6639_REG_GCONFIG, data & ~MAX6639_GCONFIG_STANDBY); | 614 | MAX6639_REG_GCONFIG, data & ~MAX6639_GCONFIG_STANDBY); |
615 | } | 615 | } |
616 | #endif /* CONFIG_PM_SLEEP */ | ||
617 | 616 | ||
618 | static const struct i2c_device_id max6639_id[] = { | 617 | static const struct i2c_device_id max6639_id[] = { |
619 | {"max6639", 0}, | 618 | {"max6639", 0}, |
@@ -622,25 +621,33 @@ static const struct i2c_device_id max6639_id[] = { | |||
622 | 621 | ||
623 | MODULE_DEVICE_TABLE(i2c, max6639_id); | 622 | MODULE_DEVICE_TABLE(i2c, max6639_id); |
624 | 623 | ||
625 | static const struct dev_pm_ops max6639_pm_ops = { | ||
626 | SET_SYSTEM_SLEEP_PM_OPS(max6639_suspend, max6639_resume) | ||
627 | }; | ||
628 | |||
629 | static struct i2c_driver max6639_driver = { | 624 | static struct i2c_driver max6639_driver = { |
630 | .class = I2C_CLASS_HWMON, | 625 | .class = I2C_CLASS_HWMON, |
631 | .driver = { | 626 | .driver = { |
632 | .name = "max6639", | 627 | .name = "max6639", |
633 | .pm = &max6639_pm_ops, | ||
634 | }, | 628 | }, |
635 | .probe = max6639_probe, | 629 | .probe = max6639_probe, |
636 | .remove = max6639_remove, | 630 | .remove = max6639_remove, |
631 | .suspend = max6639_suspend, | ||
632 | .resume = max6639_resume, | ||
637 | .id_table = max6639_id, | 633 | .id_table = max6639_id, |
638 | .detect = max6639_detect, | 634 | .detect = max6639_detect, |
639 | .address_list = normal_i2c, | 635 | .address_list = normal_i2c, |
640 | }; | 636 | }; |
641 | 637 | ||
642 | module_i2c_driver(max6639_driver); | 638 | static int __init max6639_init(void) |
639 | { | ||
640 | return i2c_add_driver(&max6639_driver); | ||
641 | } | ||
642 | |||
643 | static void __exit max6639_exit(void) | ||
644 | { | ||
645 | i2c_del_driver(&max6639_driver); | ||
646 | } | ||
643 | 647 | ||
644 | MODULE_AUTHOR("Roland Stigge <stigge@antcom.de>"); | 648 | MODULE_AUTHOR("Roland Stigge <stigge@antcom.de>"); |
645 | MODULE_DESCRIPTION("max6639 driver"); | 649 | MODULE_DESCRIPTION("max6639 driver"); |
646 | MODULE_LICENSE("GPL"); | 650 | MODULE_LICENSE("GPL"); |
651 | |||
652 | module_init(max6639_init); | ||
653 | module_exit(max6639_exit); | ||