#define YAS530_DATA_BITS               12
 #define YAS530_DATA_CENTER             BIT(YAS530_DATA_BITS - 1)
 #define YAS530_DATA_OVERFLOW           (BIT(YAS530_DATA_BITS) - 1)
+#define YAS530_20DEGREES               182 /* Counts starting at -62 °C */
 
 #define YAS532_DEVICE_ID               0x02 /* YAS532/YAS533 (MS-3R/F) */
 #define YAS532_VERSION_AB              0 /* YAS532/533 AB (MS-3R/F AB) */
 #define YAS532_DATA_BITS               13
 #define YAS532_DATA_CENTER             BIT(YAS532_DATA_BITS - 1)
 #define YAS532_DATA_OVERFLOW           (BIT(YAS532_DATA_BITS) - 1)
-#define YAS532_20DEGREES               390 /* Looks like Kelvin */
+#define YAS532_20DEGREES               390 /* Counts starting at -50 °C */
 
 /* These variant IDs are known from code dumps */
 #define YAS537_DEVICE_ID               0x07 /* YAS537 (MS-3T) */
 static int yas5xx_get_measure(struct yas5xx *yas5xx, s32 *to, s32 *xo, s32 *yo, s32 *zo)
 {
        struct yas5xx_calibration *c = &yas5xx->calibration;
-       u16 t, x, y1, y2;
+       u16 t_ref, t, x, y1, y2;
        /* These are "signed x, signed y1 etc */
        s32 sx, sy1, sy2, sy, sz;
        int ret;
        sy1 = yas5xx_linearize(yas5xx, y1, 1);
        sy2 = yas5xx_linearize(yas5xx, y2, 2);
 
-       /*
-        * Temperature compensation for x, y1, y2 respectively:
-        *
-        *          Cx * t
-        * x' = x - ------
-        *           100
-        */
-       sx = sx - (c->Cx * t) / 100;
-       sy1 = sy1 - (c->Cy1 * t) / 100;
-       sy2 = sy2 - (c->Cy2 * t) / 100;
+       /* Set the temperature reference value (unit: counts) */
+       switch (yas5xx->devid) {
+       case YAS530_DEVICE_ID:
+               t_ref = YAS530_20DEGREES;
+               break;
+       case YAS532_DEVICE_ID:
+               t_ref = YAS532_20DEGREES;
+               break;
+       default:
+               dev_err(yas5xx->dev, "unknown device type\n");
+               return -EINVAL;
+       }
+
+       /* Temperature compensation for x, y1, y2 respectively */
+       if (yas5xx->devid == YAS532_DEVICE_ID &&
+           yas5xx->version == YAS532_VERSION_AC) {
+               /*
+                * YAS532 version AC uses the temperature deviation as a
+                * multiplier.
+                *
+                *          Cx * (t - t_ref)
+                * x' = x - ----------------
+                *                100
+                */
+               sx = sx - (c->Cx * (t - t_ref)) / 100;
+               sy1 = sy1 - (c->Cy1 * (t - t_ref)) / 100;
+               sy2 = sy2 - (c->Cy2 * (t - t_ref)) / 100;
+       } else {
+               /*
+                * YAS530 and YAS532 version AB use solely the t value as a
+                * multiplier.
+                *
+                *          Cx * t
+                * x' = x - ------
+                *           100
+                */
+               sx = sx - (c->Cx * t) / 100;
+               sy1 = sy1 - (c->Cy1 * t) / 100;
+               sy2 = sy2 - (c->Cy2 * t) / 100;
+       }
 
        /*
         * Break y1 and y2 into y and z, y1 and y2 are apparently encoding
        sy = sy1 - sy2;
        sz = -sy1 - sy2;
 
-       /*
-        * FIXME: convert to Celsius? Just guessing this is given
-        * as 1/10:s of degrees so multiply by 100 to get millicentigrades.
-        */
-       *to = t * 100;
+       /* Process temperature readout */
+       switch (yas5xx->devid) {
+       case YAS530_DEVICE_ID:
+               /*
+                * Raw temperature value t is the number of counts starting
+                * at -62 °C. Reference value t_ref is the number of counts
+                * between -62 °C and 20 °C (82 °C range).
+                *
+                * Temperature in °C would be (82 / t_ref * t) - 62.
+                *
+                * Contrary to this, perform multiplication first and division
+                * second due to calculating with integers.
+                *
+                * To get a nicer result, calculate with 1/10:s degrees Celsius
+                * and finally multiply by 100 to return millidegrees Celsius.
+                */
+               *to = ((820 * t / t_ref) - 620) * 100;
+               break;
+       case YAS532_DEVICE_ID:
+               /*
+                * Actually same procedure for YAS532 but the starting point is
+                * at -50 °C. Reference value t_ref is the number of counts
+                * between -50 °C and 20 °C (70 °C range).
+                */
+               *to = ((700 * t / t_ref) - 500) * 100;
+               break;
+       default:
+               dev_err(yas5xx->dev, "unknown device type\n");
+               return -EINVAL;
+       }
+
        /*
         * Calibrate [x,y,z] with some formulas like this:
         *
        int ret;
 
        switch (mask) {
+       case IIO_CHAN_INFO_PROCESSED:
        case IIO_CHAN_INFO_RAW:
                pm_runtime_get_sync(yas5xx->dev);
                ret = yas5xx_get_measure(yas5xx, &t, &x, &y, &z);
                }
                return IIO_VAL_INT;
        case IIO_CHAN_INFO_SCALE:
-               if (chan->address == 0) {
-                       /* Temperature is unscaled */
-                       *val = 1;
-                       return IIO_VAL_INT;
-               }
                switch (yas5xx->devid) {
                case YAS530_DEVICE_ID:
                        /*
                .address = 0,
                .scan_index = 0,
                .scan_type = {
-                       .sign = 'u',
+                       .sign = 's',
                        .realbits = 32,
                        .storagebits = 32,
                        .endianness = IIO_CPU,