]> Pileus Git - ~andy/linux/blobdiff - drivers/hwmon/it87.c
hwmon: (it87) Move conversion functions
[~andy/linux] / drivers / hwmon / it87.c
index 25763d2223b664aeb16af5e3d2c43592265cff68..7a3616ccbf05798637991c25bf326f9e1e9899e7 100644 (file)
@@ -202,56 +202,6 @@ static const u8 IT87_REG_FANX_MIN[]        = { 0x1b, 0x1c, 0x1d, 0x85, 0x87 };
 #define IT87_REG_AUTO_TEMP(nr, i) (0x60 + (nr) * 8 + (i))
 #define IT87_REG_AUTO_PWM(nr, i)  (0x65 + (nr) * 8 + (i))
 
-#define IN_TO_REG(val)  (SENSORS_LIMIT((((val) + 8)/16),0,255))
-#define IN_FROM_REG(val) ((val) * 16)
-
-static inline u8 FAN_TO_REG(long rpm, int div)
-{
-       if (rpm == 0)
-               return 255;
-       rpm = SENSORS_LIMIT(rpm, 1, 1000000);
-       return SENSORS_LIMIT((1350000 + rpm * div / 2) / (rpm * div), 1,
-                            254);
-}
-
-static inline u16 FAN16_TO_REG(long rpm)
-{
-       if (rpm == 0)
-               return 0xffff;
-       return SENSORS_LIMIT((1350000 + rpm) / (rpm * 2), 1, 0xfffe);
-}
-
-#define FAN_FROM_REG(val,div) ((val)==0?-1:(val)==255?0:1350000/((val)*(div)))
-/* The divider is fixed to 2 in 16-bit mode */
-#define FAN16_FROM_REG(val) ((val)==0?-1:(val)==0xffff?0:1350000/((val)*2))
-
-#define TEMP_TO_REG(val) (SENSORS_LIMIT(((val)<0?(((val)-500)/1000):\
-                                       ((val)+500)/1000),-128,127))
-#define TEMP_FROM_REG(val) ((val) * 1000)
-
-#define PWM_TO_REG(val)   ((val) >> 1)
-#define PWM_FROM_REG(val) (((val)&0x7f) << 1)
-
-static int DIV_TO_REG(int val)
-{
-       int answer = 0;
-       while (answer < 7 && (val >>= 1))
-               answer++;
-       return answer;
-}
-#define DIV_FROM_REG(val) (1 << (val))
-
-static const unsigned int pwm_freq[8] = {
-       48000000 / 128,
-       24000000 / 128,
-       12000000 / 128,
-       8000000 / 128,
-       6000000 / 128,
-       3000000 / 128,
-       1500000 / 128,
-       750000 / 128,
-};
-
 
 struct it87_sio_data {
        enum chips type;
@@ -259,6 +209,7 @@ struct it87_sio_data {
        u8 revision;
        u8 vid_value;
        u8 beep_pin;
+       u8 internal;    /* Internal sensors can be labeled */
        /* Features skipped based on config or DMI */
        u8 skip_vid;
        u8 skip_fan;
@@ -309,6 +260,58 @@ struct it87_data {
        s8 auto_temp[3][5];     /* [nr][0] is point1_temp_hyst */
 };
 
+#define IN_TO_REG(val)  (SENSORS_LIMIT((((val) + 8) / 16), 0, 255))
+#define IN_FROM_REG(val) ((val) * 16)
+
+static inline u8 FAN_TO_REG(long rpm, int div)
+{
+       if (rpm == 0)
+               return 255;
+       rpm = SENSORS_LIMIT(rpm, 1, 1000000);
+       return SENSORS_LIMIT((1350000 + rpm * div / 2) / (rpm * div), 1,
+                            254);
+}
+
+static inline u16 FAN16_TO_REG(long rpm)
+{
+       if (rpm == 0)
+               return 0xffff;
+       return SENSORS_LIMIT((1350000 + rpm) / (rpm * 2), 1, 0xfffe);
+}
+
+#define FAN_FROM_REG(val, div) ((val) == 0 ? -1 : (val) == 255 ? 0 : \
+                               1350000 / ((val) * (div)))
+/* The divider is fixed to 2 in 16-bit mode */
+#define FAN16_FROM_REG(val) ((val) == 0 ? -1 : (val) == 0xffff ? 0 : \
+                            1350000 / ((val) * 2))
+
+#define TEMP_TO_REG(val) (SENSORS_LIMIT(((val) < 0 ? (((val) - 500) / 1000) : \
+                                       ((val) + 500) / 1000), -128, 127))
+#define TEMP_FROM_REG(val) ((val) * 1000)
+
+#define PWM_TO_REG(val)   ((val) >> 1)
+#define PWM_FROM_REG(val) (((val) & 0x7f) << 1)
+
+static int DIV_TO_REG(int val)
+{
+       int answer = 0;
+       while (answer < 7 && (val >>= 1))
+               answer++;
+       return answer;
+}
+#define DIV_FROM_REG(val) (1 << (val))
+
+static const unsigned int pwm_freq[8] = {
+       48000000 / 128,
+       24000000 / 128,
+       12000000 / 128,
+       8000000 / 128,
+       6000000 / 128,
+       3000000 / 128,
+       1500000 / 128,
+       750000 / 128,
+};
+
 static inline int has_16bit_fans(const struct it87_data *data)
 {
        /* IT8705F Datasheet 0.4.1, 3h == Version G.
@@ -1194,6 +1197,22 @@ static ssize_t show_vid_reg(struct device *dev, struct device_attribute *attr,
 }
 static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid_reg, NULL);
 
+static ssize_t show_label(struct device *dev, struct device_attribute *attr,
+               char *buf)
+{
+       static const char *labels[] = {
+               "+5V",
+               "5VSB",
+               "Vbat",
+       };
+       int nr = to_sensor_dev_attr(attr)->index;
+
+       return sprintf(buf, "%s\n", labels[nr]);
+}
+static SENSOR_DEVICE_ATTR(in3_label, S_IRUGO, show_label, NULL, 0);
+static SENSOR_DEVICE_ATTR(in7_label, S_IRUGO, show_label, NULL, 1);
+static SENSOR_DEVICE_ATTR(in8_label, S_IRUGO, show_label, NULL, 2);
+
 static ssize_t show_name(struct device *dev, struct device_attribute
                         *devattr, char *buf)
 {
@@ -1434,6 +1453,17 @@ static const struct attribute_group it87_group_vid = {
        .attrs = it87_attributes_vid,
 };
 
+static struct attribute *it87_attributes_label[] = {
+       &sensor_dev_attr_in3_label.dev_attr.attr,
+       &sensor_dev_attr_in7_label.dev_attr.attr,
+       &sensor_dev_attr_in8_label.dev_attr.attr,
+       NULL
+};
+
+static const struct attribute_group it87_group_label = {
+       .attrs = it87_attributes_vid,
+};
+
 /* SuperIO detection - will change isa_address if a chip is found */
 static int __init it87_find(unsigned short *address,
        struct it87_sio_data *sio_data)
@@ -1487,6 +1517,9 @@ static int __init it87_find(unsigned short *address,
        pr_info("it87: Found IT%04xF chip at 0x%x, revision %d\n",
                chip_type, *address, sio_data->revision);
 
+       /* in8 (Vbat) is always internal */
+       sio_data->internal = (1 << 2);
+
        /* Read GPIO config and VID value from LDN 7 (GPIO) */
        if (sio_data->type == it87) {
                /* The IT8705F doesn't have VID pins at all */
@@ -1540,9 +1573,9 @@ static int __init it87_find(unsigned short *address,
                        pr_notice("it87: Routing internal VCCH to in7\n");
                }
                if (reg & (1 << 0))
-                       pr_info("it87: in3 is VCC (+5V)\n");
+                       sio_data->internal |= (1 << 0);
                if (reg & (1 << 1))
-                       pr_info("it87: in7 is VCCH (+5V Stand-By)\n");
+                       sio_data->internal |= (1 << 1);
 
                sio_data->beep_pin = superio_inb(IT87_SIO_BEEP_PIN_REG) & 0x3f;
        }
@@ -1600,6 +1633,7 @@ static void it87_remove_files(struct device *dev)
        }
        if (!sio_data->skip_vid)
                sysfs_remove_group(&dev->kobj, &it87_group_vid);
+       sysfs_remove_group(&dev->kobj, &it87_group_label);
 }
 
 static int __devinit it87_probe(struct platform_device *pdev)
@@ -1725,6 +1759,16 @@ static int __devinit it87_probe(struct platform_device *pdev)
                        goto ERROR4;
        }
 
+       /* Export labels for internal sensors */
+       for (i = 0; i < 3; i++) {
+               if (!(sio_data->internal & (1 << i)))
+                       continue;
+               err = sysfs_create_file(&dev->kobj,
+                                       it87_attributes_label[i]);
+               if (err)
+                       goto ERROR4;
+       }
+
        data->hwmon_dev = hwmon_device_register(dev);
        if (IS_ERR(data->hwmon_dev)) {
                err = PTR_ERR(data->hwmon_dev);