Commit 2f6055c2 authored by Ivan Zaentsev's avatar Ivan Zaentsev Committed by Greg Kroah-Hartman
Browse files

w1: w1_therm: Fix conversion result for negative temperatures



DS18B20 device driver returns an incorrect value for negative temperatures
due to a missing sign-extension in w1_DS18B20_convert_temp().

Fix by using s16 temperature value when converting to int.

Fixes: 9ace0b4d (w1: w1_therm: Add support for GXCAS GX20MH01 device.)
Cc: stable <stable@vger.kernel.org>
Reported-by: default avatarPaweł Marciniak <sunwire@gmail.com>
Signed-off-by: default avatarIvan Zaentsev <ivan.zaentsev@wirenboard.ru>
Link: https://lore.kernel.org/r/20210121093021.224764-1-ivan.zaentsev@wirenboard.ru


Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 2c104a46
Loading
Loading
Loading
Loading
+9 −13
Original line number Diff line number Diff line
@@ -667,28 +667,24 @@ static inline int w1_DS18B20_get_resolution(struct w1_slave *sl)
 */
static inline int w1_DS18B20_convert_temp(u8 rom[9])
{
	int t;
	u32 bv;
	u16 bv;
	s16 t;

	/* Config register bit R2 = 1 - GX20MH01 in 13 or 14 bit resolution mode */
	if (rom[4] & 0x80) {
	/* Signed 16-bit value to unsigned, cpu order */
	bv = le16_to_cpup((__le16 *)rom);

	/* Config register bit R2 = 1 - GX20MH01 in 13 or 14 bit resolution mode */
	if (rom[4] & 0x80) {
		/* Insert two temperature bits from config register */
		/* Avoid arithmetic shift of signed value */
		bv = (bv << 2) | (rom[4] & 3);

		t = (int) sign_extend32(bv, 17); /* Degrees, lowest bit is 2^-6 */
		return (t*1000)/64;  /* Millidegrees */
		t = (s16) bv;	/* Degrees, lowest bit is 2^-6 */
		return (int)t * 1000 / 64;	/* Sign-extend to int; millidegrees */
	}

	t = (int)le16_to_cpup((__le16 *)rom);
	return t*1000/16;
	t = (s16)bv;	/* Degrees, lowest bit is 2^-4 */
	return (int)t * 1000 / 16;	/* Sign-extend to int; millidegrees */
}



/**
 * w1_DS18S20_convert_temp() - temperature computation for DS18S20
 * @rom: data read from device RAM (8 data bytes + 1 CRC byte)