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

Commit 05e82fe4 authored by Len Sorensen's avatar Len Sorensen Committed by Jean Delvare
Browse files

hwmon: (lm75) Add detection of the National Semiconductor LM75A



Add support for detection of the National Semiconductor LM75A using the ID
register value.

Signed-off-by: default avatarLen Sorensen <lsorense@csclub.uwaterloo.ca>
Signed-off-by: default avatarJean Delvare <khali@linux-fr.org>
parent 96b4b9bf
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -7,6 +7,11 @@ Supported chips:
    Addresses scanned: I2C 0x48 - 0x4f
    Datasheet: Publicly available at the National Semiconductor website
               http://www.national.com/
  * National Semiconductor LM75A
    Prefix: 'lm75a'
    Addresses scanned: I2C 0x48 - 0x4f
    Datasheet: Publicly available at the National Semiconductor website
               http://www.national.com/
  * Dallas Semiconductor DS75
    Prefix: 'lm75'
    Addresses scanned: I2C 0x48 - 0x4f
+1 −1
Original line number Diff line number Diff line
@@ -521,7 +521,7 @@ config SENSORS_LM75
		- Dallas Semiconductor DS75 and DS1775
		- Maxim MAX6625 and MAX6626
		- Microchip MCP980x
		- National Semiconductor LM75
		- National Semiconductor LM75, LM75A
		- NXP's LM75A
		- ST Microelectronics STDS75
		- TelCom (now Microchip) TCN75
+41 −15
Original line number Diff line number Diff line
@@ -232,6 +232,8 @@ static const struct i2c_device_id lm75_ids[] = {
};
MODULE_DEVICE_TABLE(i2c, lm75_ids);

#define LM75A_ID 0xA1

/* Return 0 if detection is successful, -ENODEV otherwise */
static int lm75_detect(struct i2c_client *new_client,
		       struct i2c_board_info *info)
@@ -239,6 +241,7 @@ static int lm75_detect(struct i2c_client *new_client,
	struct i2c_adapter *adapter = new_client->adapter;
	int i;
	int cur, conf, hyst, os;
	bool is_lm75a = 0;

	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA |
				     I2C_FUNC_SMBUS_WORD_DATA))
@@ -250,11 +253,30 @@ static int lm75_detect(struct i2c_client *new_client,
	   addresses 0x04-0x07 returning the last read value.
	   The cycling+unused addresses combination is not tested,
	   since it would significantly slow the detection down and would
	   hardly add any value. */
	   hardly add any value.

	   The National Semiconductor LM75A is different than earlier
	   LM75s.  It has an ID byte of 0xaX (where X is the chip
	   revision, with 1 being the only revision in existence) in
	   register 7, and unused registers return 0xff rather than the
	   last read value. */

	/* Unused addresses */
	cur = i2c_smbus_read_word_data(new_client, 0);
	conf = i2c_smbus_read_byte_data(new_client, 1);

	/* First check for LM75A */
	if (i2c_smbus_read_byte_data(new_client, 7) == LM75A_ID) {
		/* LM75A returns 0xff on unused registers so
		   just to be sure we check for that too. */
		if (i2c_smbus_read_byte_data(new_client, 4) != 0xff
		 || i2c_smbus_read_byte_data(new_client, 5) != 0xff
		 || i2c_smbus_read_byte_data(new_client, 6) != 0xff)
			return -ENODEV;
		is_lm75a = 1;
		hyst = i2c_smbus_read_word_data(new_client, 2);
		os = i2c_smbus_read_word_data(new_client, 3);
	} else { /* Traditional style LM75 detection */
		/* Unused addresses */
		hyst = i2c_smbus_read_word_data(new_client, 2);
		if (i2c_smbus_read_word_data(new_client, 4) != hyst
		 || i2c_smbus_read_word_data(new_client, 5) != hyst
@@ -267,6 +289,7 @@ static int lm75_detect(struct i2c_client *new_client,
		 || i2c_smbus_read_word_data(new_client, 6) != os
		 || i2c_smbus_read_word_data(new_client, 7) != os)
			return -ENODEV;
	}

	/* Unused bits */
	if (conf & 0xe0)
@@ -278,9 +301,12 @@ static int lm75_detect(struct i2c_client *new_client,
		 || i2c_smbus_read_word_data(new_client, i + 2) != hyst
		 || i2c_smbus_read_word_data(new_client, i + 3) != os)
			return -ENODEV;
		if (is_lm75a && i2c_smbus_read_byte_data(new_client, i + 7)
				!= LM75A_ID)
			return -ENODEV;
	}

	strlcpy(info->type, "lm75", I2C_NAME_SIZE);
	strlcpy(info->type, is_lm75a ? "lm75a" : "lm75", I2C_NAME_SIZE);

	return 0;
}