+ hwmon-add-support-for-max1618-in-max1619-driver.patch added to -mm tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The patch titled
     hwmon: add support for MAX1618 in MAX1619 driver
has been added to the -mm tree.  Its filename is
     hwmon-add-support-for-max1618-in-max1619-driver.patch

Before you just go and hit "reply", please:
   a) Consider who else should be cc'ed
   b) Prefer to cc a suitable mailing list as well
   c) Ideally: find the original patch on the mailing list and do a
      reply-to-all to that, adding suitable additional cc's

*** Remember to use Documentation/SubmitChecklist when testing your code ***

See http://userweb.kernel.org/~akpm/added-to-mm.txt to find
out what to do about this

The current -mm tree may be found at http://userweb.kernel.org/~akpm/mmotm/

------------------------------------------------------
Subject: hwmon: add support for MAX1618 in MAX1619 driver
From: Tobias Himmer <tobias@xxxxxxxxxxxxxxxx>

The difference between MAX1619 and MAX1618 is that the latter has only one
measurement register.

Tested-by: Sebastian Siewior <bigeasy@xxxxxxxxxxxxx>
Signed-off-by: Tobias Himmer <tobias@xxxxxxxxxxxxxxxx>
Cc: Alexey Fisher <fishor@xxxxxxx>
Cc: Jean Delvare <khali@xxxxxxxxxxxx>
Cc: "Mark M. Hoffman" <mhoffman@xxxxxxxxxxxxx>
Signed-off-by: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx>
---

 drivers/hwmon/Kconfig   |    5 -
 drivers/hwmon/max1619.c |  183 +++++++++++++++++++++++++-------------
 2 files changed, 128 insertions(+), 60 deletions(-)

diff -puN drivers/hwmon/Kconfig~hwmon-add-support-for-max1618-in-max1619-driver drivers/hwmon/Kconfig
--- a/drivers/hwmon/Kconfig~hwmon-add-support-for-max1618-in-max1619-driver
+++ a/drivers/hwmon/Kconfig
@@ -548,10 +548,11 @@ config SENSORS_MAX1111
 	  will be called max1111.
 
 config SENSORS_MAX1619
-	tristate "Maxim MAX1619 sensor chip"
+	tristate "Maxim MAX1619 / MAX1618 sensor chip"
 	depends on I2C
 	help
-	  If you say yes here you get support for MAX1619 sensor chip.
+	  If you say yes here you get support for MAX1619 and MAX1618
+	  sensor chips.
 
 	  This driver can also be built as a module.  If so, the module
 	  will be called max1619.
diff -puN drivers/hwmon/max1619.c~hwmon-add-support-for-max1618-in-max1619-driver drivers/hwmon/max1619.c
--- a/drivers/hwmon/max1619.c~hwmon-add-support-for-max1618-in-max1619-driver
+++ a/drivers/hwmon/max1619.c
@@ -3,12 +3,15 @@
  *             monitoring
  * Copyright (C) 2003-2004 Alexey Fisher <fishor@xxxxxxx>
  *                         Jean Delvare <khali@xxxxxxxxxxxx>
+ *                         Tobias Himmer <tobias@xxxxxxxxxxxxxxxx>
  *
  * Based on the lm90 driver. The MAX1619 is a sensor chip made by Maxim.
- * It reports up to two temperatures (its own plus up to
- * one external one). Complete datasheet can be
- * obtained from Maxim's website at:
+ * It reports up to two temperatures (its own plus up to one external one).
+ * This driver will also work on the MAX1618, a stripped down version with
+ * only one (external) temperature source.
+ * Complete datasheets can be obtained from Maxim's website at:
  *   http://pdfserv.maxim-ic.com/en/ds/MAX1619.pdf
+ *   http://pdfserv.maxim-ic.com/en/ds/MAX1618.pdf
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -44,7 +47,7 @@ static const unsigned short normal_i2c[]
  * Insmod parameters
  */
 
-I2C_CLIENT_INSMOD_1(max1619);
+I2C_CLIENT_INSMOD_2(max1619, max1618);
 
 /*
  * The MAX1619 registers
@@ -93,6 +96,7 @@ static struct max1619_data *max1619_upda
 
 static const struct i2c_device_id max1619_id[] = {
 	{ "max1619", max1619 },
+	{ "max1618", max1618 },
 	{ }
 };
 MODULE_DEVICE_TABLE(i2c, max1619_id);
@@ -116,35 +120,50 @@ static struct i2c_driver max1619_driver 
 struct max1619_data {
 	struct device *hwmon_dev;
 	struct mutex update_lock;
+	const struct attribute_group *group;
+	kernel_ulong_t kind; /* max1619 or max1618 */
 	char valid; /* zero until following fields are valid */
 	unsigned long last_updated; /* in jiffies */
 
 	/* registers values */
-	u8 temp_input1; /* local */
-	u8 temp_input2, temp_low2, temp_high2; /* remote */
-	u8 temp_crit2;
-	u8 temp_hyst2;
-	u8 alarms; 
+	u8 local;
+	u8 remote;
+	u8 remote_low, remote_high;
+	u8 remote_crit, remote_hyst;
+	u8 alarms;
 };
 
 /*
  * Sysfs stuff
  */
 
+static ssize_t show_temp1_input(struct device *dev,
+				struct device_attribute *attr, char *buf)
+{
+	struct max1619_data *data = max1619_update_device(dev);
+	return sprintf(buf, "%d\n", TEMP_FROM_REG((data->kind == max1618) ?
+						data->remote : data->local));
+}
+
+static ssize_t show_temp2_input(struct device *dev,
+				struct device_attribute *attr, char *buf)
+{
+	struct max1619_data *data = max1619_update_device(dev);
+	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->remote));
+}
+
 #define show_temp(value) \
 static ssize_t show_##value(struct device *dev, struct device_attribute *attr, char *buf) \
 { \
 	struct max1619_data *data = max1619_update_device(dev); \
 	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->value)); \
 }
-show_temp(temp_input1);
-show_temp(temp_input2);
-show_temp(temp_low2);
-show_temp(temp_high2);
-show_temp(temp_crit2);
-show_temp(temp_hyst2);
+show_temp(remote_low);
+show_temp(remote_high);
+show_temp(remote_crit);
+show_temp(remote_hyst);
 
-#define set_temp2(value, reg) \
+#define set_temp(value, reg) \
 static ssize_t set_##value(struct device *dev, struct device_attribute *attr, const char *buf, \
 	size_t count) \
 { \
@@ -158,11 +177,10 @@ static ssize_t set_##value(struct device
 	mutex_unlock(&data->update_lock); \
 	return count; \
 }
-
-set_temp2(temp_low2, MAX1619_REG_W_REMOTE_LOW);
-set_temp2(temp_high2, MAX1619_REG_W_REMOTE_HIGH);
-set_temp2(temp_crit2, MAX1619_REG_W_REMOTE_CRIT);
-set_temp2(temp_hyst2, MAX1619_REG_W_TCRIT_HYST);
+set_temp(remote_low, MAX1619_REG_W_REMOTE_LOW);
+set_temp(remote_high, MAX1619_REG_W_REMOTE_HIGH);
+set_temp(remote_crit, MAX1619_REG_W_REMOTE_CRIT);
+set_temp(remote_hyst, MAX1619_REG_W_TCRIT_HYST);
 
 static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, char *buf)
 {
@@ -178,22 +196,50 @@ static ssize_t show_alarm(struct device 
 	return sprintf(buf, "%d\n", (data->alarms >> bitnr) & 1);
 }
 
-static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp_input1, NULL);
-static DEVICE_ATTR(temp2_input, S_IRUGO, show_temp_input2, NULL);
-static DEVICE_ATTR(temp2_min, S_IWUSR | S_IRUGO, show_temp_low2,
-	set_temp_low2);
-static DEVICE_ATTR(temp2_max, S_IWUSR | S_IRUGO, show_temp_high2,
-	set_temp_high2);
-static DEVICE_ATTR(temp2_crit, S_IWUSR | S_IRUGO, show_temp_crit2,
-	set_temp_crit2);
-static DEVICE_ATTR(temp2_crit_hyst, S_IWUSR | S_IRUGO, show_temp_hyst2,
-	set_temp_hyst2);
+/* These are for both - MAX1619 and MAX1618 */
+static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp1_input, NULL);
 static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
+
+/* These are just for MAX1619 */
+static DEVICE_ATTR(temp2_input, S_IRUGO, show_temp2_input, NULL);
+static DEVICE_ATTR(temp2_min, S_IWUSR | S_IRUGO, show_remote_low,
+		   set_remote_low);
+static DEVICE_ATTR(temp2_max, S_IWUSR | S_IRUGO, show_remote_high,
+		   set_remote_high);
+static DEVICE_ATTR(temp2_crit, S_IWUSR | S_IRUGO, show_remote_crit,
+		   set_remote_crit);
+static DEVICE_ATTR(temp2_crit_hyst, S_IWUSR | S_IRUGO, show_remote_hyst,
+		   set_remote_hyst);
 static SENSOR_DEVICE_ATTR(temp2_crit_alarm, S_IRUGO, show_alarm, NULL, 1);
 static SENSOR_DEVICE_ATTR(temp2_fault, S_IRUGO, show_alarm, NULL, 2);
 static SENSOR_DEVICE_ATTR(temp2_min_alarm, S_IRUGO, show_alarm, NULL, 3);
 static SENSOR_DEVICE_ATTR(temp2_max_alarm, S_IRUGO, show_alarm, NULL, 4);
 
+/* These are just for MAX1618 */
+static DEVICE_ATTR(temp1_min, S_IWUSR | S_IRUGO, show_remote_low,
+		   set_remote_low);
+static DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_remote_high,
+		   set_remote_high);
+static SENSOR_DEVICE_ATTR(temp1_fault, S_IRUGO, show_alarm, NULL, 2);
+static SENSOR_DEVICE_ATTR(temp1_min_alarm, S_IRUGO, show_alarm, NULL, 3);
+static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO, show_alarm, NULL, 4);
+
+static struct attribute *max1618_attributes[] = {
+	&dev_attr_temp1_input.attr,
+	&dev_attr_temp1_min.attr,
+	&dev_attr_temp1_max.attr,
+
+	&dev_attr_alarms.attr,
+	&sensor_dev_attr_temp1_fault.dev_attr.attr,
+	&sensor_dev_attr_temp1_min_alarm.dev_attr.attr,
+	&sensor_dev_attr_temp1_max_alarm.dev_attr.attr,
+	NULL
+};
+
+static const struct attribute_group max1618_group = {
+	.attrs = max1618_attributes,
+};
+
 static struct attribute *max1619_attributes[] = {
 	&dev_attr_temp1_input.attr,
 	&dev_attr_temp2_input.attr,
@@ -256,14 +302,24 @@ static int max1619_detect(struct i2c_cli
 
 	if (kind <= 0) { /* identification */
 		u8 man_id, chip_id;
-	
+
 		man_id = i2c_smbus_read_byte_data(new_client,
 			 MAX1619_REG_R_MAN_ID);
 		chip_id = i2c_smbus_read_byte_data(new_client,
 			  MAX1619_REG_R_CHIP_ID);
-		
-		if ((man_id == 0x4D) && (chip_id == 0x04))
-			kind = max1619;
+
+		if (man_id == 0x4D) {
+			switch (chip_id) {
+			case 0x04:
+				kind = max1619;
+				strlcpy(info->type, "max1619", I2C_NAME_SIZE);
+				break;
+			case 0x02:
+				kind = max1618;
+				strlcpy(info->type, "max1618", I2C_NAME_SIZE);
+				break;
+			}
+		}
 
 		if (kind <= 0) { /* identification failed */
 			dev_info(&adapter->dev,
@@ -273,8 +329,6 @@ static int max1619_detect(struct i2c_cli
 		}
 	}
 
-	strlcpy(info->type, "max1619", I2C_NAME_SIZE);
-
 	return 0;
 }
 
@@ -298,7 +352,15 @@ static int max1619_probe(struct i2c_clie
 	max1619_init_client(new_client);
 
 	/* Register sysfs hooks */
-	if ((err = sysfs_create_group(&new_client->dev.kobj, &max1619_group)))
+	if (id->driver_data == max1618) {
+		data->group = &max1618_group;
+		data->kind = max1618;
+	} else {
+		data->group = &max1619_group;
+		data->kind = max1619;
+	}
+	err = sysfs_create_group(&new_client->dev.kobj, data->group);
+	if (err)
 		goto exit_free;
 
 	data->hwmon_dev = hwmon_device_register(&new_client->dev);
@@ -310,7 +372,7 @@ static int max1619_probe(struct i2c_clie
 	return 0;
 
 exit_remove_files:
-	sysfs_remove_group(&new_client->dev.kobj, &max1619_group);
+	sysfs_remove_group(&new_client->dev.kobj, data->group);
 exit_free:
 	kfree(data);
 exit:
@@ -337,7 +399,7 @@ static int max1619_remove(struct i2c_cli
 	struct max1619_data *data = i2c_get_clientdata(client);
 
 	hwmon_device_unregister(data->hwmon_dev);
-	sysfs_remove_group(&client->dev.kobj, &max1619_group);
+	sysfs_remove_group(&client->dev.kobj, data->group);
 
 	kfree(data);
 	return 0;
@@ -352,21 +414,25 @@ static struct max1619_data *max1619_upda
 
 	if (time_after(jiffies, data->last_updated + HZ * 2) || !data->valid) {
 		dev_dbg(&client->dev, "Updating max1619 data.\n");
-		data->temp_input1 = i2c_smbus_read_byte_data(client,
-					MAX1619_REG_R_LOCAL_TEMP);
-		data->temp_input2 = i2c_smbus_read_byte_data(client,
-					MAX1619_REG_R_REMOTE_TEMP);
-		data->temp_high2 = i2c_smbus_read_byte_data(client,
-					MAX1619_REG_R_REMOTE_HIGH);
-		data->temp_low2 = i2c_smbus_read_byte_data(client,
-					MAX1619_REG_R_REMOTE_LOW);
-		data->temp_crit2 = i2c_smbus_read_byte_data(client,
-					MAX1619_REG_R_REMOTE_CRIT);
-		data->temp_hyst2 = i2c_smbus_read_byte_data(client,
-					MAX1619_REG_R_TCRIT_HYST);
-		data->alarms = i2c_smbus_read_byte_data(client,
-					MAX1619_REG_R_STATUS);
-
+		switch (data->kind) {
+		default:
+			data->local = i2c_smbus_read_byte_data(
+				client, MAX1619_REG_R_LOCAL_TEMP);
+			data->remote_crit = i2c_smbus_read_byte_data(
+				client, MAX1619_REG_R_REMOTE_CRIT);
+			data->remote_hyst = i2c_smbus_read_byte_data(
+				client, MAX1619_REG_R_TCRIT_HYST);
+		/* fallthrough */
+		case max1618:
+			data->remote = i2c_smbus_read_byte_data(
+				client, MAX1619_REG_R_REMOTE_TEMP);
+			data->remote_high = i2c_smbus_read_byte_data(
+				client, MAX1619_REG_R_REMOTE_HIGH);
+			data->remote_low = i2c_smbus_read_byte_data(
+				client, MAX1619_REG_R_REMOTE_LOW);
+			data->alarms = i2c_smbus_read_byte_data(
+				client, MAX1619_REG_R_STATUS);
+		}
 		data->last_updated = jiffies;
 		data->valid = 1;
 	}
@@ -386,9 +452,10 @@ static void __exit sensors_max1619_exit(
 	i2c_del_driver(&max1619_driver);
 }
 
-MODULE_AUTHOR("Alexey Fisher <fishor@xxxxxxx> and "
-	"Jean Delvare <khali@xxxxxxxxxxxx>");
-MODULE_DESCRIPTION("MAX1619 sensor driver");
+MODULE_AUTHOR("Alexey Fisher <fishor@xxxxxxx>, "
+	"Jean Delvare <khali@xxxxxxxxxxxx>, "
+	"Tobias Himmer <tobias@xxxxxxxxxxxxxxxx>");
+MODULE_DESCRIPTION("MAX1619 / MAX1618 sensor driver");
 MODULE_LICENSE("GPL");
 
 module_init(sensors_max1619_init);
_

Patches currently in -mm which might be from tobias@xxxxxxxxxxxxxxxx are

hwmon-add-support-for-max1618-in-max1619-driver.patch

--
To unsubscribe from this list: send the line "unsubscribe mm-commits" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Kernel Newbies FAQ]     [Kernel Archive]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [Bugtraq]     [Photo]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]

  Powered by Linux