hwmon/w83793: Hide invalid VID readings

Ignore the VID readings when the motherboard has not designed
the function.  

Signed-off-by: Gong Jun <jgong@winbond.com>
Signed-off-by: Rudolf Marek <r.marek@assembler.cz>
Signed-off-by: Jean Delvare <khali@linux-fr.org>
diff --git a/drivers/hwmon/w83793.c b/drivers/hwmon/w83793.c
index 7cadef8..253ffaf 100644
--- a/drivers/hwmon/w83793.c
+++ b/drivers/hwmon/w83793.c
@@ -205,6 +205,7 @@
 
 	u8 has_pwm;
 	u8 has_temp;
+	u8 has_vid;
 	u8 pwm_enable;		/* Register value, each Temp has 1 bit */
 	u8 pwm_uptime;		/* Register value */
 	u8 pwm_downtime;	/* Register value */
@@ -1025,9 +1026,12 @@
 	SENSOR_ATTR_PWM(8),
 };
 
-static struct sensor_device_attribute_2 sda_single_files[] = {
+static struct sensor_device_attribute_2 w83793_vid[] = {
 	SENSOR_ATTR_2(cpu0_vid, S_IRUGO, show_vid, NULL, NOT_USED, 0),
 	SENSOR_ATTR_2(cpu1_vid, S_IRUGO, show_vid, NULL, NOT_USED, 1),
+};
+
+static struct sensor_device_attribute_2 sda_single_files[] = {
 	SENSOR_ATTR_2(vrm, S_IWUSR | S_IRUGO, show_vrm, store_vrm,
 		      NOT_USED, NOT_USED),
 	SENSOR_ATTR_2(chassis, S_IWUSR | S_IRUGO, show_alarm_beep,
@@ -1080,6 +1084,9 @@
 		for (i = 0; i < ARRAY_SIZE(sda_single_files); i++)
 			device_remove_file(dev, &sda_single_files[i].dev_attr);
 
+		for (i = 0; i < ARRAY_SIZE(w83793_vid); i++)
+			device_remove_file(dev, &w83793_vid[i].dev_attr);
+
 		for (i = 0; i < ARRAY_SIZE(w83793_left_fan); i++)
 			device_remove_file(dev, &w83793_left_fan[i].dev_attr);
 
@@ -1358,6 +1365,13 @@
 	if (tmp & 0x02)
 		data->has_temp |= 0x20;
 
+	/* Detect the VID usage and ignore unused input */
+	tmp = w83793_read_value(client, W83793_REG_MFC);
+	if (!(tmp & 0x29))
+		data->has_vid |= 0x1;	/* has VIDA */
+	if (tmp & 0x80)
+		data->has_vid |= 0x2;	/* has VIDB */
+
 	/* Register sysfs hooks */
 	for (i = 0; i < ARRAY_SIZE(w83793_sensor_attr_2); i++) {
 		err = device_create_file(dev,
@@ -1366,6 +1380,14 @@
 			goto exit_remove;
 	}
 
+	for (i = 0; i < ARRAY_SIZE(w83793_vid); i++) {
+		if (!(data->has_vid & (1 << i)))
+			continue;
+		err = device_create_file(dev, &w83793_vid[i].dev_attr);
+		if (err)
+			goto exit_remove;
+	}
+
 	for (i = 0; i < ARRAY_SIZE(sda_single_files); i++) {
 		err = device_create_file(dev, &sda_single_files[i].dev_attr);
 		if (err)
@@ -1429,6 +1451,9 @@
 	for (i = 0; i < ARRAY_SIZE(sda_single_files); i++)
 		device_remove_file(dev, &sda_single_files[i].dev_attr);
 
+	for (i = 0; i < ARRAY_SIZE(w83793_vid); i++)
+		device_remove_file(dev, &w83793_vid[i].dev_attr);
+
 	for (i = 0; i < ARRAY_SIZE(w83793_left_fan); i++)
 		device_remove_file(dev, &w83793_left_fan[i].dev_attr);
 
@@ -1593,8 +1618,10 @@
 	for (i = 0; i < ARRAY_SIZE(data->alarms); i++)
 		data->alarms[i] =
 		    w83793_read_value(client, W83793_REG_ALARM(i));
-	data->vid[0] = w83793_read_value(client, W83793_REG_VID_INA);
-	data->vid[1] = w83793_read_value(client, W83793_REG_VID_INB);
+	if (data->has_vid & 0x01)
+		data->vid[0] = w83793_read_value(client, W83793_REG_VID_INA);
+	if (data->has_vid & 0x02)
+		data->vid[1] = w83793_read_value(client, W83793_REG_VID_INB);
 	w83793_update_nonvolatile(dev);
 	data->last_updated = jiffies;
 	data->valid = 1;