hwmon: (it87) Report thermal sensor type as Intel PECI if appropriate
[deliverable/linux.git] / drivers / hwmon / it87.c
index e8fdc438df0a5ff5eb555f8824f68796180878f4..3827aa9aa11e64c0a469e8317788e2f3d8750917 100644 (file)
@@ -231,6 +231,7 @@ static const u8 IT87_REG_TEMP_OFFSET[]      = { 0x56, 0x57, 0x59 };
 struct it87_devices {
        const char *name;
        u16 features;
+       u16 peci_mask;
 };
 
 #define FEAT_12MV_ADC          (1 << 0)
@@ -238,6 +239,7 @@ struct it87_devices {
 #define FEAT_OLD_AUTOPWM       (1 << 2)
 #define FEAT_16BIT_FANS                (1 << 3)
 #define FEAT_TEMP_OFFSET       (1 << 4)
+#define FEAT_TEMP_PECI         (1 << 5)
 
 static const struct it87_devices it87_devices[] = {
        [it87] = {
@@ -263,12 +265,14 @@ static const struct it87_devices it87_devices[] = {
        [it8721] = {
                .name = "it8721",
                .features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS
-                 | FEAT_TEMP_OFFSET,
+                 | FEAT_TEMP_OFFSET | FEAT_TEMP_PECI,
+               .peci_mask = 0x05,
        },
        [it8728] = {
                .name = "it8728",
                .features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS
-                 | FEAT_TEMP_OFFSET,
+                 | FEAT_TEMP_OFFSET | FEAT_TEMP_PECI,
+               .peci_mask = 0x07,
        },
        [it8782] = {
                .name = "it8782",
@@ -285,6 +289,8 @@ static const struct it87_devices it87_devices[] = {
 #define has_newer_autopwm(data)        ((data)->features & FEAT_NEWER_AUTOPWM)
 #define has_old_autopwm(data)  ((data)->features & FEAT_OLD_AUTOPWM)
 #define has_temp_offset(data)  ((data)->features & FEAT_TEMP_OFFSET)
+#define has_temp_peci(data, nr)        (((data)->features & FEAT_TEMP_PECI) && \
+                                ((data)->peci_mask & (1 << nr)))
 
 struct it87_sio_data {
        enum chips type;
@@ -309,6 +315,7 @@ struct it87_data {
        struct device *hwmon_dev;
        enum chips type;
        u16 features;
+       u16 peci_mask;
 
        unsigned short addr;
        const char *name;
@@ -617,6 +624,8 @@ static ssize_t show_temp_type(struct device *dev, struct device_attribute *attr,
        struct it87_data *data = it87_update_device(dev);
        u8 reg = data->sensor;      /* In case value is updated while used */
 
+       if (has_temp_peci(data, nr) && (reg >> 6 == nr + 1))
+               return sprintf(buf, "6\n");  /* Intel PECI */
        if (reg & (1 << nr))
                return sprintf(buf, "3\n");  /* thermal diode */
        if (reg & (8 << nr))
@@ -640,16 +649,20 @@ static ssize_t set_temp_type(struct device *dev, struct device_attribute *attr,
        reg = it87_read_value(data, IT87_REG_TEMP_ENABLE);
        reg &= ~(1 << nr);
        reg &= ~(8 << nr);
+       if (has_temp_peci(data, nr) && (reg >> 6 == nr + 1 || val == 6))
+               reg &= 0x3f;
        if (val == 2) { /* backwards compatibility */
                dev_warn(dev,
                         "Sensor type 2 is deprecated, please use 4 instead\n");
                val = 4;
        }
-       /* 3 = thermal diode; 4 = thermistor; 0 = disabled */
+       /* 3 = thermal diode; 4 = thermistor; 6 = Intel PECI; 0 = disabled */
        if (val == 3)
                reg |= 1 << nr;
        else if (val == 4)
                reg |= 8 << nr;
+       else if (has_temp_peci(data, nr) && val == 6)
+               reg |= (nr + 1) << 6;
        else if (val != 0)
                return -EINVAL;
 
@@ -1966,6 +1979,7 @@ static int it87_probe(struct platform_device *pdev)
        data->addr = res->start;
        data->type = sio_data->type;
        data->features = it87_devices[sio_data->type].features;
+       data->peci_mask = it87_devices[sio_data->type].peci_mask;
        data->name = it87_devices[sio_data->type].name;
        /*
         * IT8705F Datasheet 0.4.1, 3h == Version G.
This page took 0.025341 seconds and 5 git commands to generate.