The patch allows to configure sensors with a remote diode connected and a on-chip local temperature sensor from the devicetree for the board that uses this HWM. According to the documentation [1], this is done by setting the corresponding bits in the Mode Selection Register (22h). It is necessary for some Intel processors (Apollo Lake SoC) that do not support PECI and the CPU temperature is taken from the thermistor. TEST = After loading the nct7802 module on the Kontron mAL-10 [2] with Linux OS, we can see configuration of the HWM with one sensor in the thermistor mode: user@user-apl:~$ sensors coretemp-isa-0000 Adapter: ISA adapter Package id 0: +41.0°C (high = +110.0°C, crit = +110.0°C) Core 0: +40.0°C (high = +110.0°C, crit = +110.0°C) Core 1: +40.0°C (high = +110.0°C, crit = +110.0°C) Core 2: +41.0°C (high = +110.0°C, crit = +110.0°C) Core 3: +41.0°C (high = +110.0°C, crit = +110.0°C) nct7802-i2c-0-2e Adapter: SMBus CMI adapter cmi in0: +3.35 V (min = +0.00 V, max = +4.09 V) in1: +1.92 V in3: +1.21 V (min = +0.00 V, max = +2.05 V) in4: +1.68 V (min = +0.00 V, max = +2.05 V) fan1: 0 RPM (min = 0 RPM) fan2: 868 RPM (min = 0 RPM) fan3: 0 RPM (min = 0 RPM) temp1: +42.5°C (low = +0.0°C, high = +85.0°C) (crit = +100.0°C) sensor = thermistor temp4: +44.0°C (low = +0.0°C, high = +85.0°C) (crit = +100.0°C) temp6: +0.0°C [1] page 30, section 7.2.32, Nuvoton Hardware Monitoring IC NCT7802Y with PECI 3.0 interface, datasheet, revision 1.2, february 2012 [2] https://review.coreboot.org/c/coreboot/+/39133 Change-Id: I28cc4e5cae76cf0bcdad26a50ee6cd43a201d31e Signed-off-by: Maxim Polyakov <max.senia.poliak@gmail.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/39766 Reviewed-by: Werner Zeh <werner.zeh@siemens.com> Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
95 lines
2.8 KiB
C
95 lines
2.8 KiB
C
/* SPDX-License-Identifier: GPL-2.0-only */
|
|
|
|
#ifndef DRIVERS_I2C_NCT7802Y_H
|
|
#define DRIVERS_I2C_NCT7802Y_H
|
|
|
|
#include <types.h>
|
|
#include <console/console.h>
|
|
#include <device/device.h>
|
|
#include <device/i2c_bus.h>
|
|
|
|
#define BANK_SELECT 0x00
|
|
|
|
/* Bank 0 */
|
|
#define MODE_SELECTION 0x22
|
|
#define MODE_SELECTION_LTD_EN (1 << 6)
|
|
#define MODE_SELECTION_RTDx(x, val) ((val) << (x) * 2)
|
|
|
|
#define PECI_ENABLE 0x23
|
|
#define PECI_ENABLE_AGENTx(x) (1 << (x))
|
|
|
|
#define FAN_ENABLE 0x24
|
|
#define FANx_ENABLE(fan) (1 << (fan))
|
|
|
|
#define FAN_CTRL(fan) (0x60 + (fan))
|
|
|
|
#define CLOSE_LOOP_FAN_RPM_CTRL 0x63
|
|
#define CLOSE_LOOP_FANx_EN(fan) (1 << ((fan) + 5))
|
|
#define CLOSE_LOOP_FANx_HIGH_RPM(fan) (1 << ((fan) + 2))
|
|
#define CLOSE_LOOP_FAN_PECI_ERR_MASK (3 << 0)
|
|
#define CLOSE_LOOP_FAN_PECI_ERR_CURR (0 << 0)
|
|
#define CLOSE_LOOP_FAN_PECI_ERR_VALUE (1 << 0)
|
|
#define CLOSE_LOOP_FAN_PECI_ERR_MAX (2 << 0)
|
|
|
|
#define TEMP_SHIFT(temp) (((temp) % 2) * 4)
|
|
#define TEMP_TO_FAN_MAP(temp) (0x64 + (temp) / 2)
|
|
#define TEMPx_TO_FAN_MAP_MASK(temp) (7 << TEMP_SHIFT(temp))
|
|
#define TEMPx_TO_FANy_MAP(temp, fan) (1 << (TEMP_SHIFT(temp) + (fan)))
|
|
|
|
#define FAN_CTRL_TEMP_SRC(temp) (0x68 + (temp) / 2)
|
|
#define FAN_CTRL_TEMPx_SRC_MASK(temp) (7 << TEMP_SHIFT(temp))
|
|
#define FAN_CTRL_TEMPx_SRCy(temp, src) ((src) << TEMP_SHIFT(temp))
|
|
|
|
#define FAN_DUTY_ON_PECI_ERROR 0x7a
|
|
|
|
#define TABLEx_TEMP_POINTy(fan, pt) (0x80 + (0x10 * (fan)) + (pt))
|
|
#define TABLEx_TARGET_POINTy(fan, pt) (0x85 + (0x10 * (fan)) + (pt))
|
|
|
|
/* Bank 1 */
|
|
|
|
#define PECI_CTRL_1 0x01
|
|
#define PECI_CTRL_1_EN (1 << 7)
|
|
#define PECI_CTRL_1_MANUAL_EN (1 << 1)
|
|
#define PECI_CTRL_1_ROUTINE_EN (1 << 0)
|
|
|
|
#define PECI_CTRL_3 0x03
|
|
#define PECI_CTRL_3_EN_AGENTx(x) (1 << ((x) + 4))
|
|
#define PECI_CTRL_3_HAS_DOM1_AGENTx(x) (1 << (x))
|
|
|
|
#define PECI_REPORT_TEMP_STYLE 0x04
|
|
#define PECI_TEMP_STYLE_DOM0_AGENTx(x) (0 << ((x) + 1))
|
|
#define PECI_TEMP_STYLE_DOM1_AGENTx(x) (1 << ((x) + 1))
|
|
#define PECI_TEMP_STYLE_SINGLE (0 << 0)
|
|
#define PECI_TEMP_STYLE_HIGHEST (1 << 0)
|
|
|
|
#define PECI_BASE_TEMP_AGENT(x) (0x09 + (x))
|
|
#define PECI_BASE_TEMP_MAX (0x7f << 0)
|
|
|
|
static inline int nct7802y_select_bank(struct device *const dev, const u8 bank)
|
|
{
|
|
const int ret = i2c_dev_writeb_at(dev, BANK_SELECT, bank);
|
|
if (ret != CB_SUCCESS)
|
|
printk(BIOS_NOTICE, "nct7802y: Select bank failed: %d\n", ret);
|
|
return ret;
|
|
}
|
|
|
|
static inline int nct7802y_write(struct device *const dev,
|
|
const u8 reg, const u8 value)
|
|
{
|
|
return i2c_dev_writeb_at(dev, reg, value);
|
|
}
|
|
|
|
static inline int nct7802y_update(struct device *const dev, const u8 reg,
|
|
const u8 clear_mask, const u8 set_mask)
|
|
{
|
|
const int val = i2c_dev_readb_at(dev, reg);
|
|
if (val < 0)
|
|
return val;
|
|
return i2c_dev_writeb_at(dev, reg, (val & ~clear_mask) | set_mask);
|
|
}
|
|
|
|
void nct7802y_init_fan(struct device *dev);
|
|
void nct7802y_init_peci(struct device *dev);
|
|
|
|
#endif /* DRIVERS_I2C_NCT7802Y_H */
|