hwmon: (nct6775) Fix IN scaling factors for 6798/6799
authorAhmad Khalifa <ahmad@khalifa.ws>
Wed, 19 Jul 2023 19:28:48 +0000 (20:28 +0100)
committerGuenter Roeck <linux@roeck-us.net>
Wed, 19 Jul 2023 19:56:12 +0000 (12:56 -0700)
Scaling for VTT/VIN5/VIN6 registers were based on prior chips
* Split scaling factors for 6798/6799 and assign at probe()
* Pass them through driver data to sysfs functions

Tested on nct6799 with old/new input/min/max

Fixes: 0599682b826f ("hwmon: (nct6775) Add support for NCT6798D")
Signed-off-by: Ahmad Khalifa <ahmad@khalifa.ws>
Link: https://lore.kernel.org/r/20230719192848.337508-1-ahmad@khalifa.ws
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
drivers/hwmon/nct6775-core.c
drivers/hwmon/nct6775.h

index 236dc97..08ce498 100644 (file)
@@ -955,14 +955,25 @@ static const u16 scale_in[15] = {
        800, 800
 };
 
-static inline long in_from_reg(u8 reg, u8 nr)
+/*
+ * NCT6798 scaling:
+ *    CPUVC, IN1, AVSB, 3VCC, IN0, IN8, IN4, 3VSB, VBAT,  VTT,  IN5,  IN6, IN2,
+ *      IN3, IN7
+ * Additional scales to be added later: IN9 (800), VHIF (1600)
+ */
+static const u16 scale_in_6798[15] = {
+       800, 800, 1600, 1600, 800, 800, 800, 1600, 1600, 1600, 1600, 1600, 800,
+       800, 800
+};
+
+static inline long in_from_reg(u8 reg, u8 nr, const u16 *scales)
 {
-       return DIV_ROUND_CLOSEST(reg * scale_in[nr], 100);
+       return DIV_ROUND_CLOSEST(reg * scales[nr], 100);
 }
 
-static inline u8 in_to_reg(u32 val, u8 nr)
+static inline u8 in_to_reg(u32 val, u8 nr, const u16 *scales)
 {
-       return clamp_val(DIV_ROUND_CLOSEST(val * 100, scale_in[nr]), 0, 255);
+       return clamp_val(DIV_ROUND_CLOSEST(val * 100, scales[nr]), 0, 255);
 }
 
 /* TSI temperatures are in 8.3 format */
@@ -1673,7 +1684,8 @@ show_in_reg(struct device *dev, struct device_attribute *attr, char *buf)
        if (IS_ERR(data))
                return PTR_ERR(data);
 
-       return sprintf(buf, "%ld\n", in_from_reg(data->in[nr][index], nr));
+       return sprintf(buf, "%ld\n",
+                      in_from_reg(data->in[nr][index], nr, data->scale_in));
 }
 
 static ssize_t
@@ -1691,7 +1703,7 @@ store_in_reg(struct device *dev, struct device_attribute *attr, const char *buf,
        if (err < 0)
                return err;
        mutex_lock(&data->update_lock);
-       data->in[nr][index] = in_to_reg(val, nr);
+       data->in[nr][index] = in_to_reg(val, nr, data->scale_in);
        err = nct6775_write_value(data, data->REG_IN_MINMAX[index - 1][nr], data->in[nr][index]);
        mutex_unlock(&data->update_lock);
        return err ? : count;
@@ -3462,6 +3474,7 @@ int nct6775_probe(struct device *dev, struct nct6775_data *data,
        mutex_init(&data->update_lock);
        data->name = nct6775_device_names[data->kind];
        data->bank = 0xff;              /* Force initial bank selection */
+       data->scale_in = scale_in;
 
        switch (data->kind) {
        case nct6106:
@@ -3977,6 +3990,9 @@ int nct6775_probe(struct device *dev, struct nct6775_data *data,
                        break;
                }
 
+               if (data->kind == nct6798 || data->kind == nct6799)
+                       data->scale_in = scale_in_6798;
+
                reg_temp = NCT6779_REG_TEMP;
                num_reg_temp = ARRAY_SIZE(NCT6779_REG_TEMP);
                if (data->kind == nct6791) {
index 44f79c5..a84c6ce 100644 (file)
@@ -98,6 +98,7 @@ struct nct6775_data {
        u8 bank;                /* current register bank */
        u8 in_num;              /* number of in inputs we have */
        u8 in[15][3];           /* [0]=in, [1]=in_max, [2]=in_min */
+       const u16 *scale_in;    /* internal scaling factors */
        unsigned int rpm[NUM_FAN];
        u16 fan_min[NUM_FAN];
        u8 fan_pulses[NUM_FAN];