(val) >= 127000 ? 127 : \
                                 (val) < 0 ? ((val) - 500) / 1000 : \
                                 ((val) + 500) / 1000)
+#define TEMP8U_TO_REG(val)     ((val) <= 0 ? 0 : \
+                                (val) >= 255000 ? 255 : \
+                                ((val) + 500) / 1000)
 #define TEMP11_FROM_REG(reg)   ((reg) / 32 * 125)
 #define TEMP11_TO_REG(val)     ((val) <= -128000 ? 0x8000 : \
                                 (val) >= 127875 ? 0x7FE0 : \
                       + data->temp2_offset);
 }
 
-static ssize_t set_local_temp8(struct device *dev,
-                              struct device_attribute *dummy,
-                              const char *buf, size_t count)
+static ssize_t set_temp8(struct device *dev, struct device_attribute *devattr,
+                        const char *buf, size_t count)
 {
+       struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
        struct i2c_client *client = to_i2c_client(dev);
        struct lm63_data *data = i2c_get_clientdata(client);
+       int nr = attr->index;
+       int reg = nr == 2 ? LM63_REG_REMOTE_TCRIT : LM63_REG_LOCAL_HIGH;
        long val;
        int err;
+       int temp;
 
        err = kstrtol(buf, 10, &val);
        if (err)
                return err;
 
        mutex_lock(&data->update_lock);
-       data->temp8[1] = TEMP8_TO_REG(val);
-       i2c_smbus_write_byte_data(client, LM63_REG_LOCAL_HIGH, data->temp8[1]);
+       if (nr == 2) {
+               if (data->remote_unsigned)
+                       temp = TEMP8U_TO_REG(val - data->temp2_offset);
+               else
+                       temp = TEMP8_TO_REG(val - data->temp2_offset);
+       } else {
+               temp = TEMP8_TO_REG(val);
+       }
+       data->temp8[nr] = temp;
+       i2c_smbus_write_byte_data(client, reg, temp);
        mutex_unlock(&data->update_lock);
        return count;
 }
 
 static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_local_temp8, NULL, 0);
 static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_local_temp8,
-       set_local_temp8, 1);
+       set_temp8, 1);
 
 static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp11, NULL, 0);
 static SENSOR_DEVICE_ATTR(temp2_min, S_IWUSR | S_IRUGO, show_temp11,
        set_temp11, 2);
 static SENSOR_DEVICE_ATTR(temp2_offset, S_IWUSR | S_IRUGO, show_temp11,
        set_temp11, 3);
-/*
- * On LM63, temp2_crit can be set only once, which should be job
- * of the bootloader.
- */
 static SENSOR_DEVICE_ATTR(temp2_crit, S_IRUGO, show_remote_temp8,
-       NULL, 2);
+       set_temp8, 2);
 static DEVICE_ATTR(temp2_crit_hyst, S_IWUSR | S_IRUGO, show_temp2_crit_hyst,
        set_temp2_crit_hyst);
 
        NULL
 };
 
+/*
+ * On LM63, temp2_crit can be set only once, which should be job
+ * of the bootloader.
+ * On LM64, temp2_crit can always be set.
+ * On LM96163, temp2_crit can be set if bit 1 of the configuration
+ * register is true.
+ */
+static umode_t lm63_attribute_mode(struct kobject *kobj,
+                                  struct attribute *attr, int index)
+{
+       struct device *dev = container_of(kobj, struct device, kobj);
+       struct i2c_client *client = to_i2c_client(dev);
+       struct lm63_data *data = i2c_get_clientdata(client);
+
+       if (attr == &sensor_dev_attr_temp2_crit.dev_attr.attr
+           && (data->kind == lm64 ||
+               (data->kind == lm96163 && (data->config & 0x02))))
+               return attr->mode | S_IWUSR;
+
+       return attr->mode;
+}
+
 static const struct attribute_group lm63_group = {
+       .is_visible = lm63_attribute_mode,
        .attrs = lm63_attributes,
 };