瀏覽代碼

hwmon: (lm95234) Add support for LM95233

LM95233 is similar to LM95234, but it only supports two
instead of four external temperature sensors.

Reviewed-by: Jean Delvare <jdelvare@suse.de>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Guenter Roeck 11 年之前
父節點
當前提交
dfcd4c53be
共有 3 個文件被更改,包括 78 次插入34 次删除
  1. 10 5
      Documentation/hwmon/lm95234
  2. 3 3
      drivers/hwmon/Kconfig
  3. 65 26
      drivers/hwmon/lm95234.c

+ 10 - 5
Documentation/hwmon/lm95234

@@ -2,6 +2,10 @@ Kernel driver lm95234
 =====================
 =====================
 
 
 Supported chips:
 Supported chips:
+  * National Semiconductor / Texas Instruments LM95233
+    Addresses scanned: I2C 0x18, 0x2a, 0x2b
+    Datasheet: Publicly available at the Texas Instruments website
+               http://www.ti.com/product/lm95233
   * National Semiconductor / Texas Instruments LM95234
   * National Semiconductor / Texas Instruments LM95234
     Addresses scanned: I2C 0x18, 0x4d, 0x4e
     Addresses scanned: I2C 0x18, 0x4d, 0x4e
     Datasheet: Publicly available at the Texas Instruments website
     Datasheet: Publicly available at the Texas Instruments website
@@ -13,11 +17,12 @@ Author: Guenter Roeck <linux@roeck-us.net>
 Description
 Description
 -----------
 -----------
 
 
-LM95234 is an 11-bit digital temperature sensor with a 2-wire System Management
-Bus (SMBus) interface and TrueTherm technology that can very accurately monitor
-the temperature of four remote diodes as well as its own temperature.
-The four remote diodes can be external devices such as microprocessors,
-graphics processors or diode-connected 2N3904s. The LM95234's TruTherm
+LM95233 and LM95234 are 11-bit digital temperature sensors with a 2-wire
+System Management Bus (SMBus) interface and TrueTherm technology
+that can very accurately monitor the temperature of two (LM95233)
+or four (LM95234) remote diodes as well as its own temperature.
+The remote diodes can be external devices such as microprocessors,
+graphics processors or diode-connected 2N3904s. The chip's TruTherm
 beta compensation technology allows sensing of 90 nm or 65 nm process
 beta compensation technology allows sensing of 90 nm or 65 nm process
 thermal diodes accurately.
 thermal diodes accurately.
 
 

+ 3 - 3
drivers/hwmon/Kconfig

@@ -1028,11 +1028,11 @@ config SENSORS_LM93
 	  will be called lm93.
 	  will be called lm93.
 
 
 config SENSORS_LM95234
 config SENSORS_LM95234
-	tristate "National Semiconductor LM95234"
+	tristate "National Semiconductor LM95234 and compatibles"
 	depends on I2C
 	depends on I2C
 	help
 	help
-	  If you say yes here you get support for the LM95234 temperature
-	  sensor.
+	  If you say yes here you get support for the LM95233 and LM95234
+	  temperature sensor chips.
 
 
 	  This driver can also be built as a module.  If so, the module
 	  This driver can also be built as a module.  If so, the module
 	  will be called lm95234.
 	  will be called lm95234.

+ 65 - 26
drivers/hwmon/lm95234.c

@@ -1,7 +1,7 @@
 /*
 /*
  * Driver for Texas Instruments / National Semiconductor LM95234
  * Driver for Texas Instruments / National Semiconductor LM95234
  *
  *
- * Copyright (c) 2013 Guenter Roeck <linux@roeck-us.net>
+ * Copyright (c) 2013, 2014 Guenter Roeck <linux@roeck-us.net>
  *
  *
  * Derived from lm95241.c
  * Derived from lm95241.c
  * Copyright (C) 2008, 2010 Davide Rizzo <elpa.rizzo@gmail.com>
  * Copyright (C) 2008, 2010 Davide Rizzo <elpa.rizzo@gmail.com>
@@ -30,7 +30,10 @@
 
 
 #define DRVNAME "lm95234"
 #define DRVNAME "lm95234"
 
 
-static const unsigned short normal_i2c[] = { 0x18, 0x4d, 0x4e, I2C_CLIENT_END };
+enum chips { lm95233, lm95234 };
+
+static const unsigned short normal_i2c[] = {
+	0x18, 0x2a, 0x2b, 0x4d, 0x4e, I2C_CLIENT_END };
 
 
 /* LM95234 registers */
 /* LM95234 registers */
 #define LM95234_REG_MAN_ID		0xFE
 #define LM95234_REG_MAN_ID		0xFE
@@ -53,11 +56,13 @@ static const unsigned short normal_i2c[] = { 0x18, 0x4d, 0x4e, I2C_CLIENT_END };
 #define LM95234_REG_TCRIT_HYST		0x5a
 #define LM95234_REG_TCRIT_HYST		0x5a
 
 
 #define NATSEMI_MAN_ID			0x01
 #define NATSEMI_MAN_ID			0x01
+#define LM95233_CHIP_ID			0x89
 #define LM95234_CHIP_ID			0x79
 #define LM95234_CHIP_ID			0x79
 
 
 /* Client data (each client gets its own) */
 /* Client data (each client gets its own) */
 struct lm95234_data {
 struct lm95234_data {
 	struct i2c_client *client;
 	struct i2c_client *client;
+	const struct attribute_group *groups[3];
 	struct mutex update_lock;
 	struct mutex update_lock;
 	unsigned long last_updated, interval;	/* in jiffies */
 	unsigned long last_updated, interval;	/* in jiffies */
 	bool valid;		/* false until following fields are valid */
 	bool valid;		/* false until following fields are valid */
@@ -564,35 +569,23 @@ static SENSOR_DEVICE_ATTR(temp5_offset, S_IWUSR | S_IRUGO, show_offset,
 static DEVICE_ATTR(update_interval, S_IWUSR | S_IRUGO, show_interval,
 static DEVICE_ATTR(update_interval, S_IWUSR | S_IRUGO, show_interval,
 		   set_interval);
 		   set_interval);
 
 
-static struct attribute *lm95234_attrs[] = {
+static struct attribute *lm95234_common_attrs[] = {
 	&sensor_dev_attr_temp1_input.dev_attr.attr,
 	&sensor_dev_attr_temp1_input.dev_attr.attr,
 	&sensor_dev_attr_temp2_input.dev_attr.attr,
 	&sensor_dev_attr_temp2_input.dev_attr.attr,
 	&sensor_dev_attr_temp3_input.dev_attr.attr,
 	&sensor_dev_attr_temp3_input.dev_attr.attr,
-	&sensor_dev_attr_temp4_input.dev_attr.attr,
-	&sensor_dev_attr_temp5_input.dev_attr.attr,
 	&sensor_dev_attr_temp2_fault.dev_attr.attr,
 	&sensor_dev_attr_temp2_fault.dev_attr.attr,
 	&sensor_dev_attr_temp3_fault.dev_attr.attr,
 	&sensor_dev_attr_temp3_fault.dev_attr.attr,
-	&sensor_dev_attr_temp4_fault.dev_attr.attr,
-	&sensor_dev_attr_temp5_fault.dev_attr.attr,
 	&sensor_dev_attr_temp2_type.dev_attr.attr,
 	&sensor_dev_attr_temp2_type.dev_attr.attr,
 	&sensor_dev_attr_temp3_type.dev_attr.attr,
 	&sensor_dev_attr_temp3_type.dev_attr.attr,
-	&sensor_dev_attr_temp4_type.dev_attr.attr,
-	&sensor_dev_attr_temp5_type.dev_attr.attr,
 	&sensor_dev_attr_temp1_max.dev_attr.attr,
 	&sensor_dev_attr_temp1_max.dev_attr.attr,
 	&sensor_dev_attr_temp2_max.dev_attr.attr,
 	&sensor_dev_attr_temp2_max.dev_attr.attr,
 	&sensor_dev_attr_temp3_max.dev_attr.attr,
 	&sensor_dev_attr_temp3_max.dev_attr.attr,
-	&sensor_dev_attr_temp4_max.dev_attr.attr,
-	&sensor_dev_attr_temp5_max.dev_attr.attr,
 	&sensor_dev_attr_temp1_max_hyst.dev_attr.attr,
 	&sensor_dev_attr_temp1_max_hyst.dev_attr.attr,
 	&sensor_dev_attr_temp2_max_hyst.dev_attr.attr,
 	&sensor_dev_attr_temp2_max_hyst.dev_attr.attr,
 	&sensor_dev_attr_temp3_max_hyst.dev_attr.attr,
 	&sensor_dev_attr_temp3_max_hyst.dev_attr.attr,
-	&sensor_dev_attr_temp4_max_hyst.dev_attr.attr,
-	&sensor_dev_attr_temp5_max_hyst.dev_attr.attr,
 	&sensor_dev_attr_temp1_max_alarm.dev_attr.attr,
 	&sensor_dev_attr_temp1_max_alarm.dev_attr.attr,
 	&sensor_dev_attr_temp2_max_alarm.dev_attr.attr,
 	&sensor_dev_attr_temp2_max_alarm.dev_attr.attr,
 	&sensor_dev_attr_temp3_max_alarm.dev_attr.attr,
 	&sensor_dev_attr_temp3_max_alarm.dev_attr.attr,
-	&sensor_dev_attr_temp4_max_alarm.dev_attr.attr,
-	&sensor_dev_attr_temp5_max_alarm.dev_attr.attr,
 	&sensor_dev_attr_temp2_crit.dev_attr.attr,
 	&sensor_dev_attr_temp2_crit.dev_attr.attr,
 	&sensor_dev_attr_temp3_crit.dev_attr.attr,
 	&sensor_dev_attr_temp3_crit.dev_attr.attr,
 	&sensor_dev_attr_temp2_crit_hyst.dev_attr.attr,
 	&sensor_dev_attr_temp2_crit_hyst.dev_attr.attr,
@@ -601,18 +594,44 @@ static struct attribute *lm95234_attrs[] = {
 	&sensor_dev_attr_temp3_crit_alarm.dev_attr.attr,
 	&sensor_dev_attr_temp3_crit_alarm.dev_attr.attr,
 	&sensor_dev_attr_temp2_offset.dev_attr.attr,
 	&sensor_dev_attr_temp2_offset.dev_attr.attr,
 	&sensor_dev_attr_temp3_offset.dev_attr.attr,
 	&sensor_dev_attr_temp3_offset.dev_attr.attr,
+	&dev_attr_update_interval.attr,
+	NULL
+};
+
+static const struct attribute_group lm95234_common_group = {
+	.attrs = lm95234_common_attrs,
+};
+
+static struct attribute *lm95234_attrs[] = {
+	&sensor_dev_attr_temp4_input.dev_attr.attr,
+	&sensor_dev_attr_temp5_input.dev_attr.attr,
+	&sensor_dev_attr_temp4_fault.dev_attr.attr,
+	&sensor_dev_attr_temp5_fault.dev_attr.attr,
+	&sensor_dev_attr_temp4_type.dev_attr.attr,
+	&sensor_dev_attr_temp5_type.dev_attr.attr,
+	&sensor_dev_attr_temp4_max.dev_attr.attr,
+	&sensor_dev_attr_temp5_max.dev_attr.attr,
+	&sensor_dev_attr_temp4_max_hyst.dev_attr.attr,
+	&sensor_dev_attr_temp5_max_hyst.dev_attr.attr,
+	&sensor_dev_attr_temp4_max_alarm.dev_attr.attr,
+	&sensor_dev_attr_temp5_max_alarm.dev_attr.attr,
 	&sensor_dev_attr_temp4_offset.dev_attr.attr,
 	&sensor_dev_attr_temp4_offset.dev_attr.attr,
 	&sensor_dev_attr_temp5_offset.dev_attr.attr,
 	&sensor_dev_attr_temp5_offset.dev_attr.attr,
-	&dev_attr_update_interval.attr,
 	NULL
 	NULL
 };
 };
-ATTRIBUTE_GROUPS(lm95234);
+
+static const struct attribute_group lm95234_group = {
+	.attrs = lm95234_attrs,
+};
 
 
 static int lm95234_detect(struct i2c_client *client,
 static int lm95234_detect(struct i2c_client *client,
 			  struct i2c_board_info *info)
 			  struct i2c_board_info *info)
 {
 {
 	struct i2c_adapter *adapter = client->adapter;
 	struct i2c_adapter *adapter = client->adapter;
+	int address = client->addr;
+	u8 config_mask, model_mask;
 	int mfg_id, chip_id, val;
 	int mfg_id, chip_id, val;
+	const char *name;
 
 
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
 		return -ENODEV;
 		return -ENODEV;
@@ -622,15 +641,31 @@ static int lm95234_detect(struct i2c_client *client,
 		return -ENODEV;
 		return -ENODEV;
 
 
 	chip_id = i2c_smbus_read_byte_data(client, LM95234_REG_CHIP_ID);
 	chip_id = i2c_smbus_read_byte_data(client, LM95234_REG_CHIP_ID);
-	if (chip_id != LM95234_CHIP_ID)
+	switch (chip_id) {
+	case LM95233_CHIP_ID:
+		if (address != 0x18 && address != 0x2a && address != 0x2b)
+			return -ENODEV;
+		config_mask = 0xbf;
+		model_mask = 0xf9;
+		name = "lm95233";
+		break;
+	case LM95234_CHIP_ID:
+		if (address != 0x18 && address != 0x4d && address != 0x4e)
+			return -ENODEV;
+		config_mask = 0xbc;
+		model_mask = 0xe1;
+		name = "lm95234";
+		break;
+	default:
 		return -ENODEV;
 		return -ENODEV;
+	}
 
 
 	val = i2c_smbus_read_byte_data(client, LM95234_REG_STATUS);
 	val = i2c_smbus_read_byte_data(client, LM95234_REG_STATUS);
 	if (val & 0x30)
 	if (val & 0x30)
 		return -ENODEV;
 		return -ENODEV;
 
 
 	val = i2c_smbus_read_byte_data(client, LM95234_REG_CONFIG);
 	val = i2c_smbus_read_byte_data(client, LM95234_REG_CONFIG);
-	if (val & 0xbc)
+	if (val & config_mask)
 		return -ENODEV;
 		return -ENODEV;
 
 
 	val = i2c_smbus_read_byte_data(client, LM95234_REG_CONVRATE);
 	val = i2c_smbus_read_byte_data(client, LM95234_REG_CONVRATE);
@@ -638,14 +673,14 @@ static int lm95234_detect(struct i2c_client *client,
 		return -ENODEV;
 		return -ENODEV;
 
 
 	val = i2c_smbus_read_byte_data(client, LM95234_REG_REM_MODEL);
 	val = i2c_smbus_read_byte_data(client, LM95234_REG_REM_MODEL);
-	if (val & 0xe1)
+	if (val & model_mask)
 		return -ENODEV;
 		return -ENODEV;
 
 
 	val = i2c_smbus_read_byte_data(client, LM95234_REG_REM_MODEL_STS);
 	val = i2c_smbus_read_byte_data(client, LM95234_REG_REM_MODEL_STS);
-	if (val & 0xe1)
+	if (val & model_mask)
 		return -ENODEV;
 		return -ENODEV;
 
 
-	strlcpy(info->type, "lm95234", I2C_NAME_SIZE);
+	strlcpy(info->type, name, I2C_NAME_SIZE);
 	return 0;
 	return 0;
 }
 }
 
 
@@ -698,15 +733,19 @@ static int lm95234_probe(struct i2c_client *client,
 	if (err < 0)
 	if (err < 0)
 		return err;
 		return err;
 
 
+	data->groups[0] = &lm95234_common_group;
+	if (id->driver_data == lm95234)
+		data->groups[1] = &lm95234_group;
+
 	hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name,
 	hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name,
-							   data,
-							   lm95234_groups);
+							   data, data->groups);
 	return PTR_ERR_OR_ZERO(hwmon_dev);
 	return PTR_ERR_OR_ZERO(hwmon_dev);
 }
 }
 
 
 /* Driver data (common to all clients) */
 /* Driver data (common to all clients) */
 static const struct i2c_device_id lm95234_id[] = {
 static const struct i2c_device_id lm95234_id[] = {
-	{ "lm95234", 0 },
+	{ "lm95233", lm95233 },
+	{ "lm95234", lm95234 },
 	{ }
 	{ }
 };
 };
 MODULE_DEVICE_TABLE(i2c, lm95234_id);
 MODULE_DEVICE_TABLE(i2c, lm95234_id);
@@ -725,5 +764,5 @@ static struct i2c_driver lm95234_driver = {
 module_i2c_driver(lm95234_driver);
 module_i2c_driver(lm95234_driver);
 
 
 MODULE_AUTHOR("Guenter Roeck <linux@roeck-us.net>");
 MODULE_AUTHOR("Guenter Roeck <linux@roeck-us.net>");
-MODULE_DESCRIPTION("LM95234 sensor driver");
+MODULE_DESCRIPTION("LM95233/LM95234 sensor driver");
 MODULE_LICENSE("GPL");
 MODULE_LICENSE("GPL");