*=============================================================================
  */
 
+/*
+ * idt_get_deg() - convert millidegree Celsius value to just degree
+ * @mdegC:     IN - millidegree Celsius value
+ *
+ * Return: Degree corresponding to the passed millidegree value
+ */
+static inline s8 idt_get_deg(long mdegC)
+{
+       return mdegC / 1000;
+}
+
+/*
+ * idt_get_frac() - retrieve 0/0.5 fraction of the millidegree Celsius value
+ * @mdegC:     IN - millidegree Celsius value
+ *
+ * Return: 0/0.5 degree fraction of the passed millidegree value
+ */
+static inline u8 idt_get_deg_frac(long mdegC)
+{
+       return (mdegC % 1000) >= 500 ? 5 : 0;
+}
+
+/*
+ * idt_get_temp_fmt() - convert millidegree Celsius value to 0:7:1 format
+ * @mdegC:     IN - millidegree Celsius value
+ *
+ * Return: 0:7:1 format acceptable by the IDT temperature sensor
+ */
+static inline u8 idt_temp_get_fmt(long mdegC)
+{
+       return (idt_get_deg(mdegC) << 1) | (idt_get_deg_frac(mdegC) ? 1 : 0);
+}
+
+/*
+ * idt_get_temp_sval() - convert temp sample to signed millidegree Celsius
+ * @data:      IN - shifted to LSB 8-bits temperature sample
+ *
+ * Return: signed millidegree Celsius
+ */
+static inline long idt_get_temp_sval(u32 data)
+{
+       return ((s8)data / 2) * 1000 + (data & 0x1 ? 500 : 0);
+}
+
+/*
+ * idt_get_temp_sval() - convert temp sample to unsigned millidegree Celsius
+ * @data:      IN - shifted to LSB 8-bits temperature sample
+ *
+ * Return: unsigned millidegree Celsius
+ */
+static inline long idt_get_temp_uval(u32 data)
+{
+       return (data / 2) * 1000 + (data & 0x1 ? 500 : 0);
+}
+
 /*
  * idt_read_temp() - read temperature from chip sensor
  * @ntb:       NTB device context.
- * @val:       OUT - integer value of temperature
- * @frac:      OUT - fraction
+ * @type:      IN - type of the temperature value to read
+ * @val:       OUT - integer value of temperature in millidegree Celsius
  */
-static void idt_read_temp(struct idt_ntb_dev *ndev, unsigned char *val,
-                         unsigned char *frac)
+static void idt_read_temp(struct idt_ntb_dev *ndev,
+                         const enum idt_temp_val type, long *val)
 {
        u32 data;
 
-       /* Read the data from TEMP field of the TMPSTS register */
-       data = idt_sw_read(ndev, IDT_SW_TMPSTS);
-       data = GET_FIELD(TMPSTS_TEMP, data);
-       /* TEMP field has one fractional bit and seven integer bits */
-       *val = data >> 1;
-       *frac = ((data & 0x1) ? 5 : 0);
+       /* Alter the temperature field in accordance with the passed type */
+       switch (type) {
+       case IDT_TEMP_CUR:
+               data = GET_FIELD(TMPSTS_TEMP,
+                                idt_sw_read(ndev, IDT_SW_TMPSTS));
+               break;
+       case IDT_TEMP_LOW:
+               data = GET_FIELD(TMPSTS_LTEMP,
+                                idt_sw_read(ndev, IDT_SW_TMPSTS));
+               break;
+       case IDT_TEMP_HIGH:
+               data = GET_FIELD(TMPSTS_HTEMP,
+                                idt_sw_read(ndev, IDT_SW_TMPSTS));
+               break;
+       case IDT_TEMP_OFFSET:
+               /* This is the only field with signed 0:7:1 format */
+               data = GET_FIELD(TMPADJ_OFFSET,
+                                idt_sw_read(ndev, IDT_SW_TMPADJ));
+               *val = idt_get_temp_sval(data);
+               return;
+       default:
+               data = GET_FIELD(TMPSTS_TEMP,
+                                idt_sw_read(ndev, IDT_SW_TMPSTS));
+               break;
+       }
+
+       /* The rest of the fields accept unsigned 0:7:1 format */
+       *val = idt_get_temp_uval(data);
 }
 
 /*
  */
 static void idt_temp_isr(struct idt_ntb_dev *ndev, u32 ntint_sts)
 {
-       unsigned char val, frac;
+       unsigned long mdeg;
 
        /* Read the current temperature value */
-       idt_read_temp(ndev, &val, &frac);
+       idt_read_temp(ndev, IDT_TEMP_CUR, &mdeg);
 
        /* Read the temperature alarm to clean the alarm status out */
        /*(void)idt_sw_read(ndev, IDT_SW_TMPALARM);*/
                "Temp sensor IRQ detected %#08x", ntint_sts);
 
        /* Print temperature value to log */
-       dev_warn(&ndev->ntb.pdev->dev, "Temperature %hhu.%hhu", val, frac);
+       dev_warn(&ndev->ntb.pdev->dev, "Temperature %hhd.%hhuC",
+               idt_get_deg(mdeg), idt_get_deg_frac(mdeg));
 }
 
 /*=============================================================================
                                   size_t count, loff_t *offp)
 {
        struct idt_ntb_dev *ndev = filp->private_data;
-       unsigned char temp, frac, idx, pidx, cnt;
+       unsigned char idx, pidx, cnt;
+       unsigned long irqflags, mdeg;
        ssize_t ret = 0, off = 0;
-       unsigned long irqflags;
        enum ntb_speed speed;
        enum ntb_width width;
        char *strbuf;
        off += scnprintf(strbuf + off, size - off, "\n");
 
        /* Current temperature */
-       idt_read_temp(ndev, &temp, &frac);
+       idt_read_temp(ndev, IDT_TEMP_CUR, &mdeg);
        off += scnprintf(strbuf + off, size - off,
-               "Switch temperature\t\t- %hhu.%hhuC\n", temp, frac);
+               "Switch temperature\t\t- %hhd.%hhuC\n",
+               idt_get_deg(mdeg), idt_get_deg_frac(mdeg));
 
        /* Copy the buffer to the User Space */
        ret = simple_read_from_buffer(ubuf, count, offp, strbuf, off);
 
 #define IDT_SWPxMSGCTL_PART_MASK       0x00000070U
 #define IDT_SWPxMSGCTL_PART_FLD                4
 
+/*
+ * TMPCTL register fields related constants
+ * @IDT_TMPCTL_LTH_MASK:       Low temperature threshold field mask
+ * @IDT_TMPCTL_LTH_FLD:                Low temperature threshold field offset
+ * @IDT_TMPCTL_MTH_MASK:       Middle temperature threshold field mask
+ * @IDT_TMPCTL_MTH_FLD:                Middle temperature threshold field offset
+ * @IDT_TMPCTL_HTH_MASK:       High temperature threshold field mask
+ * @IDT_TMPCTL_HTH_FLD:                High temperature threshold field offset
+ * @IDT_TMPCTL_PDOWN:          Temperature sensor power down
+ */
+#define IDT_TMPCTL_LTH_MASK            0x000000FFU
+#define IDT_TMPCTL_LTH_FLD             0
+#define IDT_TMPCTL_MTH_MASK            0x0000FF00U
+#define IDT_TMPCTL_MTH_FLD             8
+#define IDT_TMPCTL_HTH_MASK            0x00FF0000U
+#define IDT_TMPCTL_HTH_FLD             16
+#define IDT_TMPCTL_PDOWN               0x80000000U
+
 /*
  * TMPSTS register fields related constants
  * @IDT_TMPSTS_TEMP_MASK:      Current temperature field mask
  */
 #define IDT_TMPSTS_TEMP_MASK           0x000000FFU
 #define IDT_TMPSTS_TEMP_FLD            0
+#define IDT_TMPSTS_LTEMP_MASK          0x0000FF00U
+#define IDT_TMPSTS_LTEMP_FLD           8
+#define IDT_TMPSTS_HTEMP_MASK          0x00FF0000U
+#define IDT_TMPSTS_HTEMP_FLD           16
+
+/*
+ * TMPADJ register fields related constants
+ * @IDT_TMPADJ_OFFSET_MASK:    Temperature value offset field mask
+ * @IDT_TMPADJ_OFFSET_FLD:     Temperature value offset field offset
+ */
+#define IDT_TMPADJ_OFFSET_MASK         0x000000FFU
+#define IDT_TMPADJ_OFFSET_FLD          0
 
 /*
  * Helper macro to get/set the corresponding field value
 #define IDT_TRANS_ALIGN                4
 #define IDT_DIR_SIZE_ALIGN     1
 
+/*
+ * IDT PCIe-switch temperature sensor value limits
+ * @IDT_TEMP_MIN_MDEG: Minimal integer value of temperature
+ * @IDT_TEMP_MAX_MDEG: Maximal integer value of temperature
+ * @IDT_TEMP_MIN_OFFSET:Minimal integer value of temperature offset
+ * @IDT_TEMP_MAX_OFFSET:Maximal integer value of temperature offset
+ */
+#define IDT_TEMP_MIN_MDEG      0
+#define IDT_TEMP_MAX_MDEG      127500
+#define IDT_TEMP_MIN_OFFSET    -64000
+#define IDT_TEMP_MAX_OFFSET    63500
+
+/*
+ * Temperature sensor values enumeration
+ * @IDT_TEMP_CUR:      Current temperature
+ * @IDT_TEMP_LOW:      Lowest historical temperature
+ * @IDT_TEMP_HIGH:     Highest historical temperature
+ * @IDT_TEMP_OFFSET:   Current temperature offset
+ */
+enum idt_temp_val {
+       IDT_TEMP_CUR,
+       IDT_TEMP_LOW,
+       IDT_TEMP_HIGH,
+       IDT_TEMP_OFFSET
+};
+
 /*
  * IDT Memory Windows type. Depending on the device settings, IDT supports
  * Direct Address Translation MW registers and Lookup Table registers