// SPDX-License-Identifier: GPL-2.0-or-later /* * sbtsi_temp.c - hwmon driver for a SBI Temperature Sensor Interface (SB-TSI) * compliant AMD SoC temperature device. * * Copyright (c) 2020, Google Inc. * Copyright (c) 2020, Kun Yi <kunyi@google.com>
*/
/* * SB-TSI registers only support SMBus byte data access. "_INT" registers are * the integer part of a temperature value or limit, and "_DEC" registers are * corresponding decimal parts.
*/ #define SBTSI_REG_TEMP_INT 0x01 /* RO */ #define SBTSI_REG_STATUS 0x02 /* RO */ #define SBTSI_REG_CONFIG 0x03 /* RO */ #define SBTSI_REG_TEMP_HIGH_INT 0x07 /* RW */ #define SBTSI_REG_TEMP_LOW_INT 0x08 /* RW */ #define SBTSI_REG_TEMP_DEC 0x10 /* RW */ #define SBTSI_REG_TEMP_HIGH_DEC 0x13 /* RW */ #define SBTSI_REG_TEMP_LOW_DEC 0x14 /* RW */
/* * Bit for reporting value with temperature measurement range. * bit == 0: Use default temperature range (0C to 255.875C). * bit == 1: Use extended temperature range (-49C to +206.875C).
*/ #define SBTSI_CONFIG_EXT_RANGE_SHIFT 2 /* * ReadOrder bit specifies the reading order of integer and decimal part of * CPU temperature for atomic reads. If bit == 0, reading integer part triggers * latching of the decimal part, so integer part should be read first. * If bit == 1, read order should be reversed.
*/ #define SBTSI_CONFIG_READ_ORDER_SHIFT 5
/* Each client has this additional data */ struct sbtsi_data { struct i2c_client *client; struct mutex lock; bool ext_range_mode; bool read_order;
};
/* * From SB-TSI spec: CPU temperature readings and limit registers encode the * temperature in increments of 0.125 from 0 to 255.875. The "high byte" * register encodes the base-2 of the integer portion, and the upper 3 bits of * the "low byte" encode in base-2 the decimal portion. * * e.g. INT=0x19, DEC=0x20 represents 25.125 degrees Celsius * * Therefore temperature in millidegree Celsius = * (INT + DEC / 256) * 1000 = (INT * 8 + DEC / 32) * 125
*/ staticinlineint sbtsi_reg_to_mc(s32 integer, s32 decimal)
{ return ((integer << 3) + (decimal >> 5)) * 125;
}
/* * Inversely, given temperature in millidegree Celsius * INT = (TEMP / 125) / 8 * DEC = ((TEMP / 125) % 8) * 32 * Caller have to make sure temp doesn't exceed 255875, the max valid value.
*/ staticinlinevoid sbtsi_mc_to_reg(s32 temp, u8 *integer, u8 *decimal)
{
temp /= 125;
*integer = temp >> 3;
*decimal = (temp & 0x7) << 5;
}
if (data->ext_range_mode)
val += SBTSI_TEMP_EXT_RANGE_ADJ;
val = clamp_val(val, SBTSI_TEMP_MIN, SBTSI_TEMP_MAX);
sbtsi_mc_to_reg(val, &temp_int, &temp_dec);
mutex_lock(&data->lock);
err = i2c_smbus_write_byte_data(data->client, reg_int, temp_int); if (err) gotoexit;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.