diff mbox series

lm75: add lm75b detection

Message ID 20191026081049.GA16839@rainw-fedora28-jabil.corp.JABIL.ORG
State New
Headers show
Series lm75: add lm75b detection | expand

Commit Message

Rain Wang Oct. 26, 2019, 8:10 a.m. UTC
The National Semiconductor LM75B is very similar as the
LM75A, but it has no ID byte register 7, and unused registers
return 0xff rather than the last read value like LM75A.

Signed-off-by: Rain Wang <rain_wang@jabil.com>

---
 drivers/hwmon/lm75.c | 17 +++++++++++++++--
 1 file changed, 15 insertions(+), 2 deletions(-)

-- 
2.21.0

Comments

Guenter Roeck Oct. 27, 2019, 11:03 p.m. UTC | #1
On 10/26/19 1:10 AM, Rain Wang wrote:
> The National Semiconductor LM75B is very similar as the

> LM75A, but it has no ID byte register 7, and unused registers

> return 0xff rather than the last read value like LM75A.

> 

> Signed-off-by: Rain Wang <rain_wang@jabil.com>


I am quite hesitant to touch the detect function for this chip.
Each addition increases the risk for false positives. What is the
use case ?

Thanks,
Guenter

> ---

>   drivers/hwmon/lm75.c | 17 +++++++++++++++--

>   1 file changed, 15 insertions(+), 2 deletions(-)

> 

> diff --git a/drivers/hwmon/lm75.c b/drivers/hwmon/lm75.c

> index 5e6392294c03..a718f9eb4d72 100644

> --- a/drivers/hwmon/lm75.c

> +++ b/drivers/hwmon/lm75.c

> @@ -760,6 +760,7 @@ static int lm75_detect(struct i2c_client *new_client,

>   	int i;

>   	int conf, hyst, os;

>   	bool is_lm75a = 0;

> +	bool is_lm75b = 0;

>   

>   	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA |

>   				     I2C_FUNC_SMBUS_WORD_DATA))

> @@ -780,8 +781,12 @@ static int lm75_detect(struct i2c_client *new_client,

>   	 * register 7, and unused registers return 0xff rather than the

>   	 * last read value.

>   	 *

> +	 * The National Semiconductor LM75B is very similar as the

> +	 * LM75A, but it has no ID byte register 7, and unused registers

> +	 * return 0xff rather than the last read value like LM75A.

> +	 *

>   	 * Note that this function only detects the original National

> -	 * Semiconductor LM75 and the LM75A. Clones from other vendors

> +	 * Semiconductor LM75 and the LM75A/B. Clones from other vendors

>   	 * aren't detected, on purpose, because they are typically never

>   	 * found on PC hardware. They are found on embedded designs where

>   	 * they can be instantiated explicitly so detection is not needed.

> @@ -806,6 +811,13 @@ static int lm75_detect(struct i2c_client *new_client,

>   		is_lm75a = 1;

>   		hyst = i2c_smbus_read_byte_data(new_client, 2);

>   		os = i2c_smbus_read_byte_data(new_client, 3);

> +	} else 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) {

> +		/* LM75B detection */

> +		is_lm75b = 1;

> +		hyst = i2c_smbus_read_byte_data(new_client, 2);

> +		os = i2c_smbus_read_byte_data(new_client, 3);

>   	} else { /* Traditional style LM75 detection */

>   		/* Unused addresses */

>   		hyst = i2c_smbus_read_byte_data(new_client, 2);

> @@ -839,7 +851,8 @@ static int lm75_detect(struct i2c_client *new_client,

>   			return -ENODEV;

>   	}

>   

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

> +	strlcpy(info->type, is_lm75a ?

> +		"lm75a" : (is_lm75b ? "lm75b" : "lm75"), I2C_NAME_SIZE);

>   

>   	return 0;

>   }

>
Jean Delvare Oct. 28, 2019, 9:46 a.m. UTC | #2
On Sun, 27 Oct 2019 16:03:39 -0700, Guenter Roeck wrote:
> On 10/26/19 1:10 AM, Rain Wang wrote:

> > The National Semiconductor LM75B is very similar as the

> > LM75A, but it has no ID byte register 7, and unused registers

> > return 0xff rather than the last read value like LM75A.


Please send hwmon-related patches to the linux-hwmon list.

> > Signed-off-by: Rain Wang <rain_wang@jabil.com>

> 

> I am quite hesitant to touch the detect function for this chip.

> Each addition increases the risk for false positives. What is the

> use case ?


I'm positively certain I don't want this. Ideally there should be no
detection at all for device without ID registers. The only reason there
are some occurrences of that is because there were no way to explicitly
instantiate I2C devices back then, and we have left the detection in
place to avoid perceived regressions. But today there are plenty of
ways to explicitly instantiate your I2C devices so there are no excuses
for more crappy detect functions. Ideally we would even get rid of
existing ones at some point in the future.

This patch is bad anyway as it only changes the device name without
implementing proper support for the LM75B.

-- 
Jean Delvare
SUSE L3 Support
Guenter Roeck Oct. 29, 2019, 2:02 p.m. UTC | #3
On 10/28/19 2:46 AM, Jean Delvare wrote:
> On Sun, 27 Oct 2019 16:03:39 -0700, Guenter Roeck wrote:

>> On 10/26/19 1:10 AM, Rain Wang wrote:

>>> The National Semiconductor LM75B is very similar as the

>>> LM75A, but it has no ID byte register 7, and unused registers

>>> return 0xff rather than the last read value like LM75A.

> 

> Please send hwmon-related patches to the linux-hwmon list.

> 

>>> Signed-off-by: Rain Wang <rain_wang@jabil.com>

>>

>> I am quite hesitant to touch the detect function for this chip.

>> Each addition increases the risk for false positives. What is the

>> use case ?

> 

> I'm positively certain I don't want this. Ideally there should be no

> detection at all for device without ID registers. The only reason there

> are some occurrences of that is because there were no way to explicitly

> instantiate I2C devices back then, and we have left the detection in

> place to avoid perceived regressions. But today there are plenty of

> ways to explicitly instantiate your I2C devices so there are no excuses

> for more crappy detect functions. Ideally we would even get rid of

> existing ones at some point in the future.

> 

> This patch is bad anyway as it only changes the device name without

> implementing proper support for the LM75B.

> 

FWIW, I don't think there is anything to implement; I don't see any
differences in functionality.

I am much more concerned about weakening the already weak detection even further:
As written, each chip with register 0x07 != 0xa1 will be identified as LM75B.
Even if that was strengthened to actually check if the register value is 0xff,
we have no idea what other vendors might implement in those registers. it would
most certainly mis-identify LM75C as LM75B. Not that it really matters if
the chip _is_ a LM75C, but who knows if other chips fit that identification
pattern.

Overall, my suggestion is to add a small startup script to affected systems
to instantiate the chip directly, and avoid weakening the detect function.

Guenter
Rain Wang Nov. 7, 2019, 6:18 a.m. UTC | #4
Sorry for my late reply, 

>FWIW, I don't think there is anything to implement; I don't see any
>differences in functionality.
Yes, no functional difference but the detection

>I am much more concerned about weakening the already weak detection even further:
>As written, each chip with register 0x07 != 0xa1 will be identified as LM75B.
>Even if that was strengthened to actually check if the register value is 0xff,
>we have no idea what other vendors might implement in those registers. it would
>most certainly mis-identify LM75C as LM75B. Not that it really matters if
>the chip _is_ a LM75C, but who knows if other chips fit that identification
>pattern.
Yes, that's also my concern on the code of detection. I don't have any other sensors as
LM75C to try, so thinking maybe some other guys can help extend it if needed in future.

>Overall, my suggestion is to add a small startup script to affected systems
>to instantiate the chip directly, and avoid weakening the detect function.
Understood, we can have the instantiating script but just don't want limit the detection.
Thanks!
diff mbox series

Patch

diff --git a/drivers/hwmon/lm75.c b/drivers/hwmon/lm75.c
index 5e6392294c03..a718f9eb4d72 100644
--- a/drivers/hwmon/lm75.c
+++ b/drivers/hwmon/lm75.c
@@ -760,6 +760,7 @@  static int lm75_detect(struct i2c_client *new_client,
 	int i;
 	int conf, hyst, os;
 	bool is_lm75a = 0;
+	bool is_lm75b = 0;
 
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA |
 				     I2C_FUNC_SMBUS_WORD_DATA))
@@ -780,8 +781,12 @@  static int lm75_detect(struct i2c_client *new_client,
 	 * register 7, and unused registers return 0xff rather than the
 	 * last read value.
 	 *
+	 * The National Semiconductor LM75B is very similar as the
+	 * LM75A, but it has no ID byte register 7, and unused registers 
+	 * return 0xff rather than the last read value like LM75A.
+	 *
 	 * Note that this function only detects the original National
-	 * Semiconductor LM75 and the LM75A. Clones from other vendors
+	 * Semiconductor LM75 and the LM75A/B. Clones from other vendors
 	 * aren't detected, on purpose, because they are typically never
 	 * found on PC hardware. They are found on embedded designs where
 	 * they can be instantiated explicitly so detection is not needed.
@@ -806,6 +811,13 @@  static int lm75_detect(struct i2c_client *new_client,
 		is_lm75a = 1;
 		hyst = i2c_smbus_read_byte_data(new_client, 2);
 		os = i2c_smbus_read_byte_data(new_client, 3);
+	} else 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) {
+		/* LM75B detection */
+		is_lm75b = 1;
+		hyst = i2c_smbus_read_byte_data(new_client, 2);
+		os = i2c_smbus_read_byte_data(new_client, 3);
 	} else { /* Traditional style LM75 detection */
 		/* Unused addresses */
 		hyst = i2c_smbus_read_byte_data(new_client, 2);
@@ -839,7 +851,8 @@  static int lm75_detect(struct i2c_client *new_client,
 			return -ENODEV;
 	}
 
-	strlcpy(info->type, is_lm75a ? "lm75a" : "lm75", I2C_NAME_SIZE);
+	strlcpy(info->type, is_lm75a ? 
+		"lm75a" : (is_lm75b ? "lm75b" : "lm75"), I2C_NAME_SIZE);
 
 	return 0;
 }