aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon/max6650.c
diff options
context:
space:
mode:
authorGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
committerGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
commitc71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch)
treeecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /drivers/hwmon/max6650.c
parentea53c912f8a86a8567697115b6a0d8152beee5c8 (diff)
parent6a00f206debf8a5c8899055726ad127dbeeed098 (diff)
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts: litmus/sched_cedf.c
Diffstat (limited to 'drivers/hwmon/max6650.c')
-rw-r--r--drivers/hwmon/max6650.c80
1 files changed, 29 insertions, 51 deletions
diff --git a/drivers/hwmon/max6650.c b/drivers/hwmon/max6650.c
index a0160ee5caef..ece3aafa54b3 100644
--- a/drivers/hwmon/max6650.c
+++ b/drivers/hwmon/max6650.c
@@ -2,7 +2,7 @@
2 * max6650.c - Part of lm_sensors, Linux kernel modules for hardware 2 * max6650.c - Part of lm_sensors, Linux kernel modules for hardware
3 * monitoring. 3 * monitoring.
4 * 4 *
5 * (C) 2007 by Hans J. Koch <hjk@linutronix.de> 5 * (C) 2007 by Hans J. Koch <hjk@hansjkoch.de>
6 * 6 *
7 * based on code written by John Morris <john.morris@spirentcom.com> 7 * based on code written by John Morris <john.morris@spirentcom.com>
8 * Copyright (c) 2003 Spirent Communications 8 * Copyright (c) 2003 Spirent Communications
@@ -41,13 +41,6 @@
41#include <linux/err.h> 41#include <linux/err.h>
42 42
43/* 43/*
44 * Addresses to scan. There are four disjoint possibilities, by pin config.
45 */
46
47static const unsigned short normal_i2c[] = {0x1b, 0x1f, 0x48, 0x4b,
48 I2C_CLIENT_END};
49
50/*
51 * Insmod parameters 44 * Insmod parameters
52 */ 45 */
53 46
@@ -114,8 +107,6 @@ module_param(clock, int, S_IRUGO);
114 107
115static int max6650_probe(struct i2c_client *client, 108static int max6650_probe(struct i2c_client *client,
116 const struct i2c_device_id *id); 109 const struct i2c_device_id *id);
117static int max6650_detect(struct i2c_client *client,
118 struct i2c_board_info *info);
119static int max6650_init_client(struct i2c_client *client); 110static int max6650_init_client(struct i2c_client *client);
120static int max6650_remove(struct i2c_client *client); 111static int max6650_remove(struct i2c_client *client);
121static struct max6650_data *max6650_update_device(struct device *dev); 112static struct max6650_data *max6650_update_device(struct device *dev);
@@ -125,21 +116,19 @@ static struct max6650_data *max6650_update_device(struct device *dev);
125 */ 116 */
126 117
127static const struct i2c_device_id max6650_id[] = { 118static const struct i2c_device_id max6650_id[] = {
128 { "max6650", 0 }, 119 { "max6650", 1 },
120 { "max6651", 4 },
129 { } 121 { }
130}; 122};
131MODULE_DEVICE_TABLE(i2c, max6650_id); 123MODULE_DEVICE_TABLE(i2c, max6650_id);
132 124
133static struct i2c_driver max6650_driver = { 125static struct i2c_driver max6650_driver = {
134 .class = I2C_CLASS_HWMON,
135 .driver = { 126 .driver = {
136 .name = "max6650", 127 .name = "max6650",
137 }, 128 },
138 .probe = max6650_probe, 129 .probe = max6650_probe,
139 .remove = max6650_remove, 130 .remove = max6650_remove,
140 .id_table = max6650_id, 131 .id_table = max6650_id,
141 .detect = max6650_detect,
142 .address_list = normal_i2c,
143}; 132};
144 133
145/* 134/*
@@ -150,6 +139,7 @@ struct max6650_data
150{ 139{
151 struct device *hwmon_dev; 140 struct device *hwmon_dev;
152 struct mutex update_lock; 141 struct mutex update_lock;
142 int nr_fans;
153 char valid; /* zero until following fields are valid */ 143 char valid; /* zero until following fields are valid */
154 unsigned long last_updated; /* in jiffies */ 144 unsigned long last_updated; /* in jiffies */
155 145
@@ -501,9 +491,6 @@ static mode_t max6650_attrs_visible(struct kobject *kobj, struct attribute *a,
501 491
502static struct attribute *max6650_attrs[] = { 492static struct attribute *max6650_attrs[] = {
503 &sensor_dev_attr_fan1_input.dev_attr.attr, 493 &sensor_dev_attr_fan1_input.dev_attr.attr,
504 &sensor_dev_attr_fan2_input.dev_attr.attr,
505 &sensor_dev_attr_fan3_input.dev_attr.attr,
506 &sensor_dev_attr_fan4_input.dev_attr.attr,
507 &dev_attr_fan1_target.attr, 494 &dev_attr_fan1_target.attr,
508 &dev_attr_fan1_div.attr, 495 &dev_attr_fan1_div.attr,
509 &dev_attr_pwm1_enable.attr, 496 &dev_attr_pwm1_enable.attr,
@@ -521,42 +508,21 @@ static struct attribute_group max6650_attr_grp = {
521 .is_visible = max6650_attrs_visible, 508 .is_visible = max6650_attrs_visible,
522}; 509};
523 510
511static struct attribute *max6651_attrs[] = {
512 &sensor_dev_attr_fan2_input.dev_attr.attr,
513 &sensor_dev_attr_fan3_input.dev_attr.attr,
514 &sensor_dev_attr_fan4_input.dev_attr.attr,
515 NULL
516};
517
518static const struct attribute_group max6651_attr_grp = {
519 .attrs = max6651_attrs,
520};
521
524/* 522/*
525 * Real code 523 * Real code
526 */ 524 */
527 525
528/* Return 0 if detection is successful, -ENODEV otherwise */
529static int max6650_detect(struct i2c_client *client,
530 struct i2c_board_info *info)
531{
532 struct i2c_adapter *adapter = client->adapter;
533 int address = client->addr;
534
535 dev_dbg(&adapter->dev, "max6650_detect called\n");
536
537 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
538 dev_dbg(&adapter->dev, "max6650: I2C bus doesn't support "
539 "byte read mode, skipping.\n");
540 return -ENODEV;
541 }
542
543 if (((i2c_smbus_read_byte_data(client, MAX6650_REG_CONFIG) & 0xC0)
544 ||(i2c_smbus_read_byte_data(client, MAX6650_REG_GPIO_STAT) & 0xE0)
545 ||(i2c_smbus_read_byte_data(client, MAX6650_REG_ALARM_EN) & 0xE0)
546 ||(i2c_smbus_read_byte_data(client, MAX6650_REG_ALARM) & 0xE0)
547 ||(i2c_smbus_read_byte_data(client, MAX6650_REG_COUNT) & 0xFC))) {
548 dev_dbg(&adapter->dev,
549 "max6650: detection failed at 0x%02x.\n", address);
550 return -ENODEV;
551 }
552
553 dev_info(&adapter->dev, "max6650: chip found at 0x%02x.\n", address);
554
555 strlcpy(info->type, "max6650", I2C_NAME_SIZE);
556
557 return 0;
558}
559
560static int max6650_probe(struct i2c_client *client, 526static int max6650_probe(struct i2c_client *client,
561 const struct i2c_device_id *id) 527 const struct i2c_device_id *id)
562{ 528{
@@ -570,6 +536,7 @@ static int max6650_probe(struct i2c_client *client,
570 536
571 i2c_set_clientdata(client, data); 537 i2c_set_clientdata(client, data);
572 mutex_init(&data->update_lock); 538 mutex_init(&data->update_lock);
539 data->nr_fans = id->driver_data;
573 540
574 /* 541 /*
575 * Initialize the max6650 chip 542 * Initialize the max6650 chip
@@ -581,6 +548,12 @@ static int max6650_probe(struct i2c_client *client,
581 err = sysfs_create_group(&client->dev.kobj, &max6650_attr_grp); 548 err = sysfs_create_group(&client->dev.kobj, &max6650_attr_grp);
582 if (err) 549 if (err)
583 goto err_free; 550 goto err_free;
551 /* 3 additional fan inputs for the MAX6651 */
552 if (data->nr_fans == 4) {
553 err = sysfs_create_group(&client->dev.kobj, &max6651_attr_grp);
554 if (err)
555 goto err_remove;
556 }
584 557
585 data->hwmon_dev = hwmon_device_register(&client->dev); 558 data->hwmon_dev = hwmon_device_register(&client->dev);
586 if (!IS_ERR(data->hwmon_dev)) 559 if (!IS_ERR(data->hwmon_dev))
@@ -588,6 +561,9 @@ static int max6650_probe(struct i2c_client *client,
588 561
589 err = PTR_ERR(data->hwmon_dev); 562 err = PTR_ERR(data->hwmon_dev);
590 dev_err(&client->dev, "error registering hwmon device.\n"); 563 dev_err(&client->dev, "error registering hwmon device.\n");
564 if (data->nr_fans == 4)
565 sysfs_remove_group(&client->dev.kobj, &max6651_attr_grp);
566err_remove:
591 sysfs_remove_group(&client->dev.kobj, &max6650_attr_grp); 567 sysfs_remove_group(&client->dev.kobj, &max6650_attr_grp);
592err_free: 568err_free:
593 kfree(data); 569 kfree(data);
@@ -598,8 +574,10 @@ static int max6650_remove(struct i2c_client *client)
598{ 574{
599 struct max6650_data *data = i2c_get_clientdata(client); 575 struct max6650_data *data = i2c_get_clientdata(client);
600 576
601 sysfs_remove_group(&client->dev.kobj, &max6650_attr_grp);
602 hwmon_device_unregister(data->hwmon_dev); 577 hwmon_device_unregister(data->hwmon_dev);
578 if (data->nr_fans == 4)
579 sysfs_remove_group(&client->dev.kobj, &max6651_attr_grp);
580 sysfs_remove_group(&client->dev.kobj, &max6650_attr_grp);
603 kfree(data); 581 kfree(data);
604 return 0; 582 return 0;
605} 583}
@@ -712,7 +690,7 @@ static struct max6650_data *max6650_update_device(struct device *dev)
712 MAX6650_REG_SPEED); 690 MAX6650_REG_SPEED);
713 data->config = i2c_smbus_read_byte_data(client, 691 data->config = i2c_smbus_read_byte_data(client,
714 MAX6650_REG_CONFIG); 692 MAX6650_REG_CONFIG);
715 for (i = 0; i < 4; i++) { 693 for (i = 0; i < data->nr_fans; i++) {
716 data->tach[i] = i2c_smbus_read_byte_data(client, 694 data->tach[i] = i2c_smbus_read_byte_data(client,
717 tach_reg[i]); 695 tach_reg[i]);
718 } 696 }