hwmon: (nct6755) Add support for NCT6799D
NCT6799D is mostly compatible to NCT6798D, with minor variations. Note that NCT6798D and NCT6799D have a new means to select temperature sources, and to report temperatures from those sources. This is not currently implemented, meaning that most likely not all temperatures are reported. Cc: Sebastian Arnhold <sebastian.arnhold@posteo.de> Cc: Ahmad Khalifa <ahmad@khalifa.ws> Signed-off-by: Guenter Roeck <linux@roeck-us.net> Tested-by: Sebastian Arnhold <sebastian.arnhold@posteo.de> Tested-by: Corentin Labbe <clabbe.montjoie@gmail.com> Link: https://lore.kernel.org/r/20221228135744.281752-1-linux@roeck-us.net
This commit is contained in:
parent
be144ee491
commit
aee395bb19
@ -33,6 +33,7 @@
|
|||||||
* (0xd451)
|
* (0xd451)
|
||||||
* nct6798d 14 7 7 2+6 0xd428 0xc1 0x5ca3
|
* nct6798d 14 7 7 2+6 0xd428 0xc1 0x5ca3
|
||||||
* (0xd429)
|
* (0xd429)
|
||||||
|
* nct6799d 14 7 7 2+6 0xd802 0xc1 0x5ca3
|
||||||
*
|
*
|
||||||
* #temp lists the number of monitored temperature sources (first value) plus
|
* #temp lists the number of monitored temperature sources (first value) plus
|
||||||
* the number of directly connectable temperature sensors (second value).
|
* the number of directly connectable temperature sensors (second value).
|
||||||
@ -73,6 +74,7 @@ static const char * const nct6775_device_names[] = {
|
|||||||
"nct6796",
|
"nct6796",
|
||||||
"nct6797",
|
"nct6797",
|
||||||
"nct6798",
|
"nct6798",
|
||||||
|
"nct6799",
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Common and NCT6775 specific data */
|
/* Common and NCT6775 specific data */
|
||||||
@ -381,7 +383,7 @@ static const u16 NCT6779_REG_TEMP_OVER[ARRAY_SIZE(NCT6779_REG_TEMP)] = {
|
|||||||
0x39, 0x155 };
|
0x39, 0x155 };
|
||||||
|
|
||||||
static const u16 NCT6779_REG_TEMP_OFFSET[] = {
|
static const u16 NCT6779_REG_TEMP_OFFSET[] = {
|
||||||
0x454, 0x455, 0x456, 0x44a, 0x44b, 0x44c };
|
0x454, 0x455, 0x456, 0x44a, 0x44b, 0x44c, 0x44d, 0x449 };
|
||||||
|
|
||||||
static const char *const nct6779_temp_label[] = {
|
static const char *const nct6779_temp_label[] = {
|
||||||
"",
|
"",
|
||||||
@ -654,6 +656,44 @@ static const char *const nct6798_temp_label[] = {
|
|||||||
#define NCT6798_TEMP_MASK 0xbfff0ffe
|
#define NCT6798_TEMP_MASK 0xbfff0ffe
|
||||||
#define NCT6798_VIRT_TEMP_MASK 0x80000c00
|
#define NCT6798_VIRT_TEMP_MASK 0x80000c00
|
||||||
|
|
||||||
|
static const char *const nct6799_temp_label[] = {
|
||||||
|
"",
|
||||||
|
"SYSTIN",
|
||||||
|
"CPUTIN",
|
||||||
|
"AUXTIN0",
|
||||||
|
"AUXTIN1",
|
||||||
|
"AUXTIN2",
|
||||||
|
"AUXTIN3",
|
||||||
|
"AUXTIN4",
|
||||||
|
"SMBUSMASTER 0",
|
||||||
|
"SMBUSMASTER 1",
|
||||||
|
"Virtual_TEMP",
|
||||||
|
"Virtual_TEMP",
|
||||||
|
"",
|
||||||
|
"AUXTIN5",
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
"PECI Agent 0",
|
||||||
|
"PECI Agent 1",
|
||||||
|
"PCH_CHIP_CPU_MAX_TEMP",
|
||||||
|
"PCH_CHIP_TEMP",
|
||||||
|
"PCH_CPU_TEMP",
|
||||||
|
"PCH_MCH_TEMP",
|
||||||
|
"Agent0 Dimm0",
|
||||||
|
"Agent0 Dimm1",
|
||||||
|
"Agent1 Dimm0",
|
||||||
|
"Agent1 Dimm1",
|
||||||
|
"BYTE_TEMP0",
|
||||||
|
"BYTE_TEMP1",
|
||||||
|
"PECI Agent 0 Calibration", /* undocumented */
|
||||||
|
"PECI Agent 1 Calibration", /* undocumented */
|
||||||
|
"",
|
||||||
|
"Virtual_TEMP"
|
||||||
|
};
|
||||||
|
|
||||||
|
#define NCT6799_TEMP_MASK 0xbfff2ffe
|
||||||
|
#define NCT6799_VIRT_TEMP_MASK 0x80000c00
|
||||||
|
|
||||||
/* NCT6102D/NCT6106D specific data */
|
/* NCT6102D/NCT6106D specific data */
|
||||||
|
|
||||||
#define NCT6106_REG_VBAT 0x318
|
#define NCT6106_REG_VBAT 0x318
|
||||||
@ -1109,6 +1149,7 @@ bool nct6775_reg_is_word_sized(struct nct6775_data *data, u16 reg)
|
|||||||
case nct6796:
|
case nct6796:
|
||||||
case nct6797:
|
case nct6797:
|
||||||
case nct6798:
|
case nct6798:
|
||||||
|
case nct6799:
|
||||||
return reg == 0x150 || reg == 0x153 || reg == 0x155 ||
|
return reg == 0x150 || reg == 0x153 || reg == 0x155 ||
|
||||||
(reg & 0xfff0) == 0x4c0 ||
|
(reg & 0xfff0) == 0x4c0 ||
|
||||||
reg == 0x402 ||
|
reg == 0x402 ||
|
||||||
@ -1462,6 +1503,7 @@ static int nct6775_update_pwm_limits(struct device *dev)
|
|||||||
case nct6796:
|
case nct6796:
|
||||||
case nct6797:
|
case nct6797:
|
||||||
case nct6798:
|
case nct6798:
|
||||||
|
case nct6799:
|
||||||
err = nct6775_read_value(data, data->REG_CRITICAL_PWM_ENABLE[i], ®);
|
err = nct6775_read_value(data, data->REG_CRITICAL_PWM_ENABLE[i], ®);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
@ -3109,6 +3151,7 @@ store_auto_pwm(struct device *dev, struct device_attribute *attr,
|
|||||||
case nct6796:
|
case nct6796:
|
||||||
case nct6797:
|
case nct6797:
|
||||||
case nct6798:
|
case nct6798:
|
||||||
|
case nct6799:
|
||||||
err = nct6775_write_value(data, data->REG_CRITICAL_PWM[nr], val);
|
err = nct6775_write_value(data, data->REG_CRITICAL_PWM[nr], val);
|
||||||
if (err)
|
if (err)
|
||||||
break;
|
break;
|
||||||
@ -3807,10 +3850,12 @@ int nct6775_probe(struct device *dev, struct nct6775_data *data,
|
|||||||
case nct6796:
|
case nct6796:
|
||||||
case nct6797:
|
case nct6797:
|
||||||
case nct6798:
|
case nct6798:
|
||||||
|
case nct6799:
|
||||||
data->in_num = 15;
|
data->in_num = 15;
|
||||||
data->pwm_num = (data->kind == nct6796 ||
|
data->pwm_num = (data->kind == nct6796 ||
|
||||||
data->kind == nct6797 ||
|
data->kind == nct6797 ||
|
||||||
data->kind == nct6798) ? 7 : 6;
|
data->kind == nct6798 ||
|
||||||
|
data->kind == nct6799) ? 7 : 6;
|
||||||
data->auto_pwm_num = 4;
|
data->auto_pwm_num = 4;
|
||||||
data->has_fan_div = false;
|
data->has_fan_div = false;
|
||||||
data->temp_fixed_num = 6;
|
data->temp_fixed_num = 6;
|
||||||
@ -3859,6 +3904,11 @@ int nct6775_probe(struct device *dev, struct nct6775_data *data,
|
|||||||
data->temp_mask = NCT6798_TEMP_MASK;
|
data->temp_mask = NCT6798_TEMP_MASK;
|
||||||
data->virt_temp_mask = NCT6798_VIRT_TEMP_MASK;
|
data->virt_temp_mask = NCT6798_VIRT_TEMP_MASK;
|
||||||
break;
|
break;
|
||||||
|
case nct6799:
|
||||||
|
data->temp_label = nct6799_temp_label;
|
||||||
|
data->temp_mask = NCT6799_TEMP_MASK;
|
||||||
|
data->virt_temp_mask = NCT6799_VIRT_TEMP_MASK;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
data->REG_CONFIG = NCT6775_REG_CONFIG;
|
data->REG_CONFIG = NCT6775_REG_CONFIG;
|
||||||
@ -3918,6 +3968,7 @@ int nct6775_probe(struct device *dev, struct nct6775_data *data,
|
|||||||
case nct6796:
|
case nct6796:
|
||||||
case nct6797:
|
case nct6797:
|
||||||
case nct6798:
|
case nct6798:
|
||||||
|
case nct6799:
|
||||||
data->REG_TSI_TEMP = NCT6796_REG_TSI_TEMP;
|
data->REG_TSI_TEMP = NCT6796_REG_TSI_TEMP;
|
||||||
num_reg_tsi_temp = ARRAY_SIZE(NCT6796_REG_TSI_TEMP);
|
num_reg_tsi_temp = ARRAY_SIZE(NCT6796_REG_TSI_TEMP);
|
||||||
break;
|
break;
|
||||||
|
@ -87,6 +87,7 @@ static const struct of_device_id __maybe_unused nct6775_i2c_of_match[] = {
|
|||||||
{ .compatible = "nuvoton,nct6796", .data = (void *)nct6796, },
|
{ .compatible = "nuvoton,nct6796", .data = (void *)nct6796, },
|
||||||
{ .compatible = "nuvoton,nct6797", .data = (void *)nct6797, },
|
{ .compatible = "nuvoton,nct6797", .data = (void *)nct6797, },
|
||||||
{ .compatible = "nuvoton,nct6798", .data = (void *)nct6798, },
|
{ .compatible = "nuvoton,nct6798", .data = (void *)nct6798, },
|
||||||
|
{ .compatible = "nuvoton,nct6799", .data = (void *)nct6799, },
|
||||||
{ },
|
{ },
|
||||||
};
|
};
|
||||||
MODULE_DEVICE_TABLE(of, nct6775_i2c_of_match);
|
MODULE_DEVICE_TABLE(of, nct6775_i2c_of_match);
|
||||||
@ -104,6 +105,7 @@ static const struct i2c_device_id nct6775_i2c_id[] = {
|
|||||||
{ "nct6796", nct6796 },
|
{ "nct6796", nct6796 },
|
||||||
{ "nct6797", nct6797 },
|
{ "nct6797", nct6797 },
|
||||||
{ "nct6798", nct6798 },
|
{ "nct6798", nct6798 },
|
||||||
|
{ "nct6799", nct6799 },
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
MODULE_DEVICE_TABLE(i2c, nct6775_i2c_id);
|
MODULE_DEVICE_TABLE(i2c, nct6775_i2c_id);
|
||||||
|
@ -35,6 +35,7 @@ static const char * const nct6775_sio_names[] __initconst = {
|
|||||||
"NCT6796D",
|
"NCT6796D",
|
||||||
"NCT6797D",
|
"NCT6797D",
|
||||||
"NCT6798D",
|
"NCT6798D",
|
||||||
|
"NCT6799D",
|
||||||
};
|
};
|
||||||
|
|
||||||
static unsigned short force_id;
|
static unsigned short force_id;
|
||||||
@ -85,6 +86,7 @@ MODULE_PARM_DESC(fan_debounce, "Enable debouncing for fan RPM signal");
|
|||||||
#define SIO_NCT6796_ID 0xd420
|
#define SIO_NCT6796_ID 0xd420
|
||||||
#define SIO_NCT6797_ID 0xd450
|
#define SIO_NCT6797_ID 0xd450
|
||||||
#define SIO_NCT6798_ID 0xd428
|
#define SIO_NCT6798_ID 0xd428
|
||||||
|
#define SIO_NCT6799_ID 0xd800
|
||||||
#define SIO_ID_MASK 0xFFF8
|
#define SIO_ID_MASK 0xFFF8
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -418,7 +420,7 @@ static int nct6775_resume(struct device *dev)
|
|||||||
if (data->kind == nct6791 || data->kind == nct6792 ||
|
if (data->kind == nct6791 || data->kind == nct6792 ||
|
||||||
data->kind == nct6793 || data->kind == nct6795 ||
|
data->kind == nct6793 || data->kind == nct6795 ||
|
||||||
data->kind == nct6796 || data->kind == nct6797 ||
|
data->kind == nct6796 || data->kind == nct6797 ||
|
||||||
data->kind == nct6798)
|
data->kind == nct6798 || data->kind == nct6799)
|
||||||
nct6791_enable_io_mapping(sio_data);
|
nct6791_enable_io_mapping(sio_data);
|
||||||
|
|
||||||
sio_data->sio_exit(sio_data);
|
sio_data->sio_exit(sio_data);
|
||||||
@ -565,7 +567,7 @@ nct6775_check_fan_inputs(struct nct6775_data *data, struct nct6775_sio_data *sio
|
|||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
* NCT6779D, NCT6791D, NCT6792D, NCT6793D, NCT6795D, NCT6796D,
|
* NCT6779D, NCT6791D, NCT6792D, NCT6793D, NCT6795D, NCT6796D,
|
||||||
* NCT6797D, NCT6798D
|
* NCT6797D, NCT6798D, NCT6799D
|
||||||
*/
|
*/
|
||||||
int cr1a = sio_data->sio_inb(sio_data, 0x1a);
|
int cr1a = sio_data->sio_inb(sio_data, 0x1a);
|
||||||
int cr1b = sio_data->sio_inb(sio_data, 0x1b);
|
int cr1b = sio_data->sio_inb(sio_data, 0x1b);
|
||||||
@ -575,12 +577,17 @@ nct6775_check_fan_inputs(struct nct6775_data *data, struct nct6775_sio_data *sio
|
|||||||
int cr2b = sio_data->sio_inb(sio_data, 0x2b);
|
int cr2b = sio_data->sio_inb(sio_data, 0x2b);
|
||||||
int cr2d = sio_data->sio_inb(sio_data, 0x2d);
|
int cr2d = sio_data->sio_inb(sio_data, 0x2d);
|
||||||
int cr2f = sio_data->sio_inb(sio_data, 0x2f);
|
int cr2f = sio_data->sio_inb(sio_data, 0x2f);
|
||||||
|
bool vsb_ctl_en = cr2f & BIT(0);
|
||||||
bool dsw_en = cr2f & BIT(3);
|
bool dsw_en = cr2f & BIT(3);
|
||||||
bool ddr4_en = cr2f & BIT(4);
|
bool ddr4_en = cr2f & BIT(4);
|
||||||
|
bool as_seq1_en = cr2f & BIT(7);
|
||||||
int cre0;
|
int cre0;
|
||||||
|
int cre6;
|
||||||
int creb;
|
int creb;
|
||||||
int cred;
|
int cred;
|
||||||
|
|
||||||
|
cre6 = sio_data->sio_inb(sio_data, 0xe0);
|
||||||
|
|
||||||
sio_data->sio_select(sio_data, NCT6775_LD_12);
|
sio_data->sio_select(sio_data, NCT6775_LD_12);
|
||||||
cre0 = sio_data->sio_inb(sio_data, 0xe0);
|
cre0 = sio_data->sio_inb(sio_data, 0xe0);
|
||||||
creb = sio_data->sio_inb(sio_data, 0xeb);
|
creb = sio_data->sio_inb(sio_data, 0xeb);
|
||||||
@ -683,6 +690,29 @@ nct6775_check_fan_inputs(struct nct6775_data *data, struct nct6775_sio_data *sio
|
|||||||
pwm7pin = !(cr1d & (BIT(2) | BIT(3)));
|
pwm7pin = !(cr1d & (BIT(2) | BIT(3)));
|
||||||
pwm7pin |= cr2d & BIT(7);
|
pwm7pin |= cr2d & BIT(7);
|
||||||
pwm7pin |= creb & BIT(2);
|
pwm7pin |= creb & BIT(2);
|
||||||
|
break;
|
||||||
|
case nct6799:
|
||||||
|
fan4pin = cr1c & BIT(6);
|
||||||
|
fan5pin = cr1c & BIT(7);
|
||||||
|
|
||||||
|
fan6pin = !(cr1b & BIT(0)) && (cre0 & BIT(3));
|
||||||
|
fan6pin |= cre6 & BIT(5);
|
||||||
|
fan6pin |= creb & BIT(5);
|
||||||
|
fan6pin |= !as_seq1_en && (cr2a & BIT(4));
|
||||||
|
|
||||||
|
fan7pin = cr1b & BIT(5);
|
||||||
|
fan7pin |= !vsb_ctl_en && !(cr2b & BIT(2));
|
||||||
|
fan7pin |= creb & BIT(3);
|
||||||
|
|
||||||
|
pwm6pin = !(cr1b & BIT(0)) && (cre0 & BIT(4));
|
||||||
|
pwm6pin |= !as_seq1_en && !(cred & BIT(2)) && (cr2a & BIT(3));
|
||||||
|
pwm6pin |= (creb & BIT(4)) && !(cr2a & BIT(0));
|
||||||
|
pwm6pin |= cre6 & BIT(3);
|
||||||
|
|
||||||
|
pwm7pin = !vsb_ctl_en && !(cr1d & (BIT(2) | BIT(3)));
|
||||||
|
pwm7pin |= creb & BIT(2);
|
||||||
|
pwm7pin |= cr2d & BIT(7);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
default: /* NCT6779D */
|
default: /* NCT6779D */
|
||||||
break;
|
break;
|
||||||
@ -838,6 +868,7 @@ static int nct6775_platform_probe_init(struct nct6775_data *data)
|
|||||||
case nct6796:
|
case nct6796:
|
||||||
case nct6797:
|
case nct6797:
|
||||||
case nct6798:
|
case nct6798:
|
||||||
|
case nct6799:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -876,6 +907,7 @@ static int nct6775_platform_probe_init(struct nct6775_data *data)
|
|||||||
case nct6796:
|
case nct6796:
|
||||||
case nct6797:
|
case nct6797:
|
||||||
case nct6798:
|
case nct6798:
|
||||||
|
case nct6799:
|
||||||
tmp |= 0x7e;
|
tmp |= 0x7e;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1005,6 +1037,9 @@ static int __init nct6775_find(int sioaddr, struct nct6775_sio_data *sio_data)
|
|||||||
case SIO_NCT6798_ID:
|
case SIO_NCT6798_ID:
|
||||||
sio_data->kind = nct6798;
|
sio_data->kind = nct6798;
|
||||||
break;
|
break;
|
||||||
|
case SIO_NCT6799_ID:
|
||||||
|
sio_data->kind = nct6799;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
if (val != 0xffff)
|
if (val != 0xffff)
|
||||||
pr_debug("unsupported chip ID: 0x%04x\n", val);
|
pr_debug("unsupported chip ID: 0x%04x\n", val);
|
||||||
@ -1033,7 +1068,7 @@ static int __init nct6775_find(int sioaddr, struct nct6775_sio_data *sio_data)
|
|||||||
if (sio_data->kind == nct6791 || sio_data->kind == nct6792 ||
|
if (sio_data->kind == nct6791 || sio_data->kind == nct6792 ||
|
||||||
sio_data->kind == nct6793 || sio_data->kind == nct6795 ||
|
sio_data->kind == nct6793 || sio_data->kind == nct6795 ||
|
||||||
sio_data->kind == nct6796 || sio_data->kind == nct6797 ||
|
sio_data->kind == nct6796 || sio_data->kind == nct6797 ||
|
||||||
sio_data->kind == nct6798)
|
sio_data->kind == nct6798 || sio_data->kind == nct6799)
|
||||||
nct6791_enable_io_mapping(sio_data);
|
nct6791_enable_io_mapping(sio_data);
|
||||||
|
|
||||||
sio_data->sio_exit(sio_data);
|
sio_data->sio_exit(sio_data);
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
|
|
||||||
enum kinds { nct6106, nct6116, nct6775, nct6776, nct6779, nct6791, nct6792,
|
enum kinds { nct6106, nct6116, nct6775, nct6776, nct6779, nct6791, nct6792,
|
||||||
nct6793, nct6795, nct6796, nct6797, nct6798 };
|
nct6793, nct6795, nct6796, nct6797, nct6798, nct6799 };
|
||||||
enum pwm_enable { off, manual, thermal_cruise, speed_cruise, sf3, sf4 };
|
enum pwm_enable { off, manual, thermal_cruise, speed_cruise, sf3, sf4 };
|
||||||
|
|
||||||
#define NUM_TEMP 10 /* Max number of temp attribute sets w/ limits*/
|
#define NUM_TEMP 10 /* Max number of temp attribute sets w/ limits*/
|
||||||
|
Loading…
Reference in New Issue
Block a user