Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9908ad4c authored by Jean Delvare's avatar Jean Delvare Committed by Guenter Roeck
Browse files

hwmon: (lm80) Add detection of NatSemi/TI LM96080



Add detection of the National Semiconductor (now Texas Instruments)
LM96080. It is functionally compatible with the LM80 but detection is
completely different.

Signed-off-by: default avatarJean Delvare <khali@linux-fr.org>
Cc: Guenter Roeck <guenter.roeck@ericsson.com>
Cc: Frans Meulenbroeks <fransmeulenbroeks@gmail.com>
Signed-off-by: default avatarGuenter Roeck <guenter.roeck@ericsson.com>
parent 0e190b7f
Loading
Loading
Loading
Loading
+8 −1
Original line number Diff line number Diff line
@@ -7,6 +7,11 @@ Supported chips:
    Addresses scanned: I2C 0x28 - 0x2f
    Datasheet: Publicly available at the National Semiconductor website
               http://www.national.com/
  * National Semiconductor LM96080
    Prefix: 'lm96080'
    Addresses scanned: I2C 0x28 - 0x2f
    Datasheet: Publicly available at the National Semiconductor website
               http://www.national.com/

Authors:
        Frodo Looijaard <frodol@dds.nl>,
@@ -17,7 +22,9 @@ Description

This driver implements support for the National Semiconductor LM80.
It is described as a 'Serial Interface ACPI-Compatible Microprocessor
System Hardware Monitor'.
System Hardware Monitor'. The LM96080 is a more recent incarnation,
it is pin and register compatible, with a few additional features not
yet supported by the driver.

The LM80 implements one temperature sensor, two fan rotation speed sensors,
seven voltage sensors, alarms, and some miscellaneous stuff.
+2 −2
Original line number Diff line number Diff line
@@ -598,11 +598,11 @@ config SENSORS_LM78
	  will be called lm78.

config SENSORS_LM80
	tristate "National Semiconductor LM80"
	tristate "National Semiconductor LM80 and LM96080"
	depends on I2C
	help
	  If you say yes here you get support for National Semiconductor
	  LM80 sensor chips.
	  LM80 and LM96080 sensor chips.

	  This driver can also be built as a module.  If so, the module
	  will be called lm80.
+35 −9
Original line number Diff line number Diff line
@@ -60,6 +60,10 @@ static const unsigned short normal_i2c[] = { 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d,
#define LM80_REG_FANDIV			0x05
#define LM80_REG_RES			0x06

#define LM96080_REG_CONV_RATE		0x07
#define LM96080_REG_MAN_ID		0x3e
#define LM96080_REG_DEV_ID		0x3f


/*
 * Conversions. Rounding and limit checking is only done on the TO_REG
@@ -147,6 +151,7 @@ static int lm80_write_value(struct i2c_client *client, u8 reg, u8 value);

static const struct i2c_device_id lm80_id[] = {
	{ "lm80", 0 },
	{ "lm96080", 1 },
	{ }
};
MODULE_DEVICE_TABLE(i2c, lm80_id);
@@ -490,14 +495,32 @@ static const struct attribute_group lm80_group = {
static int lm80_detect(struct i2c_client *client, struct i2c_board_info *info)
{
	struct i2c_adapter *adapter = client->adapter;
	int i, cur;
	int i, cur, man_id, dev_id;
	const char *name = NULL;

	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
		return -ENODEV;

	/* Now, we do the remaining detection. It is lousy. */
	if (lm80_read_value(client, LM80_REG_ALARM2) & 0xc0)
	/* First check for unused bits, common to both chip types */
	if ((lm80_read_value(client, LM80_REG_ALARM2) & 0xc0)
	 || (lm80_read_value(client, LM80_REG_CONFIG) & 0x80))
		return -ENODEV;

	/*
	 * The LM96080 has manufacturer and stepping/die rev registers so we
	 * can just check that. The LM80 does not have such registers so we
	 * have to use a more expensive trick.
	 */
	man_id = lm80_read_value(client, LM96080_REG_MAN_ID);
	dev_id = lm80_read_value(client, LM96080_REG_DEV_ID);
	if (man_id == 0x01 && dev_id == 0x08) {
		/* Check more unused bits for confirmation */
		if (lm80_read_value(client, LM96080_REG_CONV_RATE) & 0xfe)
			return -ENODEV;

		name = "lm96080";
	} else {
		/* Check 6-bit addressing */
		for (i = 0x2a; i <= 0x3d; i++) {
			cur = i2c_smbus_read_byte_data(client, i);
			if ((i2c_smbus_read_byte_data(client, i + 0x40) != cur)
@@ -506,7 +529,10 @@ static int lm80_detect(struct i2c_client *client, struct i2c_board_info *info)
				return -ENODEV;
		}

	strlcpy(info->type, "lm80", I2C_NAME_SIZE);
		name = "lm80";
	}

	strlcpy(info->type, name, I2C_NAME_SIZE);

	return 0;
}