-static SENSOR_DEVICE_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0, 0);
-static SENSOR_DEVICE_ATTR_2(temp1_min, S_IRUGO | S_IWUSR, show_temp, set_temp,
- 0, 1);
-static SENSOR_DEVICE_ATTR_2(temp1_max, S_IRUGO | S_IWUSR, show_temp, set_temp,
- 0, 2);
-static SENSOR_DEVICE_ATTR_2(temp1_offset, S_IRUGO | S_IWUSR, show_temp,
- set_temp, 0, 3);
-static SENSOR_DEVICE_ATTR_2(temp2_input, S_IRUGO, show_temp, NULL, 1, 0);
-static SENSOR_DEVICE_ATTR_2(temp2_min, S_IRUGO | S_IWUSR, show_temp, set_temp,
- 1, 1);
-static SENSOR_DEVICE_ATTR_2(temp2_max, S_IRUGO | S_IWUSR, show_temp, set_temp,
- 1, 2);
-static SENSOR_DEVICE_ATTR_2(temp2_offset, S_IRUGO | S_IWUSR, show_temp,
- set_temp, 1, 3);
-static SENSOR_DEVICE_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, 2, 0);
-static SENSOR_DEVICE_ATTR_2(temp3_min, S_IRUGO | S_IWUSR, show_temp, set_temp,
- 2, 1);
-static SENSOR_DEVICE_ATTR_2(temp3_max, S_IRUGO | S_IWUSR, show_temp, set_temp,
- 2, 2);
-static SENSOR_DEVICE_ATTR_2(temp3_offset, S_IRUGO | S_IWUSR, show_temp,
- set_temp, 2, 3);
-static SENSOR_DEVICE_ATTR_2(temp4_input, S_IRUGO, show_temp, NULL, 3, 0);
-static SENSOR_DEVICE_ATTR_2(temp5_input, S_IRUGO, show_temp, NULL, 4, 0);
-static SENSOR_DEVICE_ATTR_2(temp6_input, S_IRUGO, show_temp, NULL, 5, 0);
+static SENSOR_DEVICE_ATTR_2(temp1_input, 0444, show_temp, NULL, 0, 0);
+static SENSOR_DEVICE_ATTR_2(temp1_min, 0644, show_temp, set_temp, 0, 1);
+static SENSOR_DEVICE_ATTR_2(temp1_max, 0644, show_temp, set_temp, 0, 2);
+static SENSOR_DEVICE_ATTR_2(temp1_offset, 0644, show_temp, set_temp, 0, 3);
+static SENSOR_DEVICE_ATTR_2(temp2_input, 0444, show_temp, NULL, 1, 0);
+static SENSOR_DEVICE_ATTR_2(temp2_min, 0644, show_temp, set_temp, 1, 1);
+static SENSOR_DEVICE_ATTR_2(temp2_max, 0644, show_temp, set_temp, 1, 2);
+static SENSOR_DEVICE_ATTR_2(temp2_offset, 0644, show_temp, set_temp, 1, 3);
+static SENSOR_DEVICE_ATTR_2(temp3_input, 0444, show_temp, NULL, 2, 0);
+static SENSOR_DEVICE_ATTR_2(temp3_min, 0644, show_temp, set_temp, 2, 1);
+static SENSOR_DEVICE_ATTR_2(temp3_max, 0644, show_temp, set_temp, 2, 2);
+static SENSOR_DEVICE_ATTR_2(temp3_offset, 0644, show_temp, set_temp, 2, 3);
+static SENSOR_DEVICE_ATTR_2(temp4_input, 0444, show_temp, NULL, 3, 0);
+static SENSOR_DEVICE_ATTR_2(temp4_min, 0644, show_temp, set_temp, 3, 1);
+static SENSOR_DEVICE_ATTR_2(temp4_max, 0644, show_temp, set_temp, 3, 2);
+static SENSOR_DEVICE_ATTR_2(temp4_offset, 0644, show_temp, set_temp, 3, 3);
+static SENSOR_DEVICE_ATTR_2(temp5_input, 0444, show_temp, NULL, 4, 0);
+static SENSOR_DEVICE_ATTR_2(temp5_min, 0644, show_temp, set_temp, 4, 1);
+static SENSOR_DEVICE_ATTR_2(temp5_max, 0644, show_temp, set_temp, 4, 2);
+static SENSOR_DEVICE_ATTR_2(temp5_offset, 0644, show_temp, set_temp, 4, 3);
+static SENSOR_DEVICE_ATTR_2(temp6_input, 0444, show_temp, NULL, 5, 0);
+static SENSOR_DEVICE_ATTR_2(temp6_min, 0644, show_temp, set_temp, 5, 1);
+static SENSOR_DEVICE_ATTR_2(temp6_max, 0644, show_temp, set_temp, 5, 2);
+static SENSOR_DEVICE_ATTR_2(temp6_offset, 0644, show_temp, set_temp, 5, 3);
+
+static const u8 temp_types_8686[NUM_TEMP][9] = {
+ { 0, 8, 8, 8, 8, 8, 8, 8, 7 },
+ { 0, 6, 8, 8, 6, 0, 0, 0, 7 },
+ { 0, 6, 5, 8, 6, 0, 0, 0, 7 },
+ { 4, 8, 8, 8, 8, 8, 8, 8, 7 },
+ { 4, 6, 8, 8, 6, 0, 0, 0, 7 },
+ { 4, 6, 5, 8, 6, 0, 0, 0, 7 },
+};
+
+static int get_temp_type(struct it87_data *data, int index)
+{
+ u8 reg, extra;
+ int ttype, type = 0;
+
+ if (has_bank_sel(data)) {
+ u8 src1, src2;
+
+ src1 = (data->temp_src[index / 2] >> ((index % 2) * 4)) & 0x0f;
+
+ switch (data->type) {
+ case it8686:
+ if (src1 < 9)
+ type = temp_types_8686[index][src1];
+ break;
+ case it8625:
+ if (index < 3)
+ break;
+ case it8655:
+ case it8665:
+ if (src1 < 3) {
+ index = src1;
+ break;
+ }
+ src2 = data->temp_src[3];
+ switch (src1) {
+ case 3:
+ type = (src2 & BIT(index)) ? 6 : 5;
+ break;
+ case 4 ... 8:
+ type = (src2 & BIT(index)) ? 4 : 6;
+ break;
+ case 9:
+ type = (src2 & BIT(index)) ? 5 : 0;
+ break;
+ default:
+ break;
+ }
+ return type;
+ default:
+ return 0;
+ }
+ }
+ if (type)
+ return type;
+
+ /* Dectect PECI vs. AMDTSI if possible */
+ ttype = 6;
+ if ((has_temp_peci(data, index)) && data->type != it8721) {
+ extra = data->read(data, 0x98); /* PCH/AMDTSI host status */
+ if (extra & BIT(6))
+ ttype = 5;
+ }
+
+ reg = data->read(data, IT87_REG_TEMP_ENABLE);
+
+ /* Per chip special detection */
+ switch (data->type) {
+ case it8622:
+ if (!(reg & 0xc0) && index == 3)
+ type = ttype;
+ break;
+ default:
+ break;
+ }
+
+ if (type || index >= 3)
+ return type;
+
+ extra = data->read(data, IT87_REG_TEMP_EXTRA);
+
+ if ((has_temp_peci(data, index) && (reg >> 6 == index + 1)) ||
+ (has_temp_old_peci(data, index) && (extra & 0x80)))
+ type = ttype; /* Intel PECI or AMDTSI */
+ if (reg & BIT(index))
+ type = 3; /* thermal diode */
+ else if (reg & BIT(index + 3))
+ type = 4; /* thermistor */
+
+ return type;
+}