=======================
 
 Supported chips:
-  * Winbond W83627EHF/EHG/DHG (ISA access ONLY)
+  * Winbond W83627EHF/EHG (ISA access ONLY)
     Prefix: 'w83627ehf'
     Addresses scanned: ISA address retrieved from Super I/O registers
     Datasheet:
-        http://www.winbond-usa.com/products/winbond_products/pdfs/PCIC/W83627EHF_%20W83627EHGb.pdf
-        DHG datasheet confidential.
+        http://www.nuvoton.com.tw/NR/rdonlyres/A6A258F0-F0C9-4F97-81C0-C4D29E7E943E/0/W83627EHF.pdf
+  * Winbond W83627DHG
+    Prefix: 'w83627dhg'
+    Addresses scanned: ISA address retrieved from Super I/O registers
+    Datasheet:
+        http://www.nuvoton.com.tw/NR/rdonlyres/7885623D-A487-4CF9-A47F-30C5F73D6FE6/0/W83627DHG.pdf
+  * Winbond W83667HG
+    Prefix: 'w83667hg'
+    Addresses scanned: ISA address retrieved from Super I/O registers
+    Datasheet: not available
 
 Authors:
         Jean Delvare <khali@linux-fr.org>
         Yuan Mu (Winbond)
         Rudolf Marek <r.marek@assembler.cz>
         David Hubbard <david.c.hubbard@gmail.com>
+        Gong Jun <JGong@nuvoton.com>
 
 Description
 -----------
 
-This driver implements support for the Winbond W83627EHF, W83627EHG, and
-W83627DHG super I/O chips. We will refer to them collectively as Winbond chips.
+This driver implements support for the Winbond W83627EHF, W83627EHG,
+W83627DHG and W83667HG super I/O chips. We will refer to them collectively
+as Winbond chips.
 
 The chips implement three temperature sensors, five fan rotation
 speed sensors, ten analog voltage sensors (only nine for the 627DHG), one
-VID (6 pins for the 627EHF/EHG, 8 pins for the 627DHG), alarms with beep
-warnings (control unimplemented), and some automatic fan regulation
-strategies (plus manual fan control mode).
+VID (6 pins for the 627EHF/EHG, 8 pins for the 627DHG and 667HG), alarms
+with beep warnings (control unimplemented), and some automatic fan
+regulation strategies (plus manual fan control mode).
 
 Temperatures are measured in degrees Celsius and measurement resolution is 1
 degC for temp1 and 0.5 degC for temp2 and temp3. An alarm is triggered when
 temp1 -> pwm1
 temp2 -> pwm2
 temp3 -> pwm3
-prog  -> pwm4 (the programmable setting is not supported by the driver)
+prog  -> pwm4 (not on 667HG; the programmable setting is not supported by
+              the driver)
 
 /sys files
 ----------
 
     w83627ehf   10      5       4       3      0x8850 0x88    0x5ca3
                                                0x8860 0xa1
     w83627dhg    9      5       4       3      0xa020 0xc1    0x5ca3
+    w83667hg     9      5       3       3      0xa510 0xc1    0x5ca3
 */
 
 #include <linux/module.h>
 #include <asm/io.h>
 #include "lm75.h"
 
-enum kinds { w83627ehf, w83627dhg };
+enum kinds { w83627ehf, w83627dhg, w83667hg };
 
 /* used to set data->name = w83627ehf_device_names[data->sio_kind] */
 static const char * w83627ehf_device_names[] = {
        "w83627ehf",
        "w83627dhg",
+       "w83667hg",
 };
 
 static unsigned short force_id;
  */
 
 #define W83627EHF_LD_HWM       0x0b
+#define W83667HG_LD_VID        0x0d
 
 #define SIO_REG_LDSEL          0x07    /* Logical device select */
 #define SIO_REG_DEVID          0x20    /* Device ID (2 bytes) */
 #define SIO_W83627EHF_ID       0x8850
 #define SIO_W83627EHG_ID       0x8860
 #define SIO_W83627DHG_ID       0xa020
+#define SIO_W83667HG_ID        0xa510
 #define SIO_ID_MASK            0xFFF0
 
 static inline void
        u8 pwm_mode[4]; /* 0->DC variable voltage, 1->PWM variable duty cycle */
        u8 pwm_enable[4]; /* 1->manual
                             2->thermal cruise (also called SmartFan I) */
+       u8 pwm_num;             /* number of pwm */
        u8 pwm[4];
        u8 target_temp[4];
        u8 tolerance[4];
                device_remove_file(dev, &sda_fan_div[i].dev_attr);
                device_remove_file(dev, &sda_fan_min[i].dev_attr);
        }
-       for (i = 0; i < 4; i++) {
+       for (i = 0; i < data->pwm_num; i++) {
                device_remove_file(dev, &sda_pwm[i].dev_attr);
                device_remove_file(dev, &sda_pwm_mode[i].dev_attr);
                device_remove_file(dev, &sda_pwm_enable[i].dev_attr);
        data->name = w83627ehf_device_names[sio_data->kind];
        platform_set_drvdata(pdev, data);
 
-       /* 627EHG and 627EHF have 10 voltage inputs; DHG has 9 */
-       data->in_num = (sio_data->kind == w83627dhg) ? 9 : 10;
+       /* 627EHG and 627EHF have 10 voltage inputs; 627DHG and 667HG have 9 */
+       data->in_num = (sio_data->kind == w83627ehf) ? 10 : 9;
+       /* 667HG has 3 pwms */
+       data->pwm_num = (sio_data->kind == w83667hg) ? 3 : 4;
 
        /* Initialize the chip */
        w83627ehf_init_device(data);
        data->vrm = vid_which_vrm();
        superio_enter(sio_data->sioreg);
        /* Read VID value */
-       superio_select(sio_data->sioreg, W83627EHF_LD_HWM);
-       if (superio_inb(sio_data->sioreg, SIO_REG_VID_CTRL) & 0x80) {
-               /* Set VID input sensibility if needed. In theory the BIOS
-                  should have set it, but in practice it's not always the
-                  case. We only do it for the W83627EHF/EHG because the
-                  W83627DHG is more complex in this respect. */
-               if (sio_data->kind == w83627ehf) {
-                       en_vrm10 = superio_inb(sio_data->sioreg,
-                                              SIO_REG_EN_VRM10);
-                       if ((en_vrm10 & 0x08) && data->vrm == 90) {
-                               dev_warn(dev, "Setting VID input voltage to "
-                                        "TTL\n");
-                               superio_outb(sio_data->sioreg, SIO_REG_EN_VRM10,
-                                            en_vrm10 & ~0x08);
-                       } else if (!(en_vrm10 & 0x08) && data->vrm == 100) {
-                               dev_warn(dev, "Setting VID input voltage to "
-                                        "VRM10\n");
-                               superio_outb(sio_data->sioreg, SIO_REG_EN_VRM10,
-                                            en_vrm10 | 0x08);
-                       }
-               }
-
-               data->vid = superio_inb(sio_data->sioreg, SIO_REG_VID_DATA);
-               if (sio_data->kind == w83627ehf) /* 6 VID pins only */
-                       data->vid &= 0x3f;
-
+       if (sio_data->kind == w83667hg) {
+               /* W83667HG has different pins for VID input and output, so
+               we can get the VID input values directly at logical device D
+               0xe3. */
+               superio_select(sio_data->sioreg, W83667HG_LD_VID);
+               data->vid = superio_inb(sio_data->sioreg, 0xe3);
                err = device_create_file(dev, &dev_attr_cpu0_vid);
                if (err)
                        goto exit_release;
        } else {
-               dev_info(dev, "VID pins in output mode, CPU VID not "
-                        "available\n");
+               superio_select(sio_data->sioreg, W83627EHF_LD_HWM);
+               if (superio_inb(sio_data->sioreg, SIO_REG_VID_CTRL) & 0x80) {
+                       /* Set VID input sensibility if needed. In theory the
+                          BIOS should have set it, but in practice it's not
+                          always the case. We only do it for the W83627EHF/EHG
+                          because the W83627DHG is more complex in this
+                          respect. */
+                       if (sio_data->kind == w83627ehf) {
+                               en_vrm10 = superio_inb(sio_data->sioreg,
+                                                      SIO_REG_EN_VRM10);
+                               if ((en_vrm10 & 0x08) && data->vrm == 90) {
+                                       dev_warn(dev, "Setting VID input "
+                                                "voltage to TTL\n");
+                                       superio_outb(sio_data->sioreg,
+                                                    SIO_REG_EN_VRM10,
+                                                    en_vrm10 & ~0x08);
+                               } else if (!(en_vrm10 & 0x08)
+                                          && data->vrm == 100) {
+                                       dev_warn(dev, "Setting VID input "
+                                                "voltage to VRM10\n");
+                                       superio_outb(sio_data->sioreg,
+                                                    SIO_REG_EN_VRM10,
+                                                    en_vrm10 | 0x08);
+                               }
+                       }
+
+                       data->vid = superio_inb(sio_data->sioreg,
+                                               SIO_REG_VID_DATA);
+                       if (sio_data->kind == w83627ehf) /* 6 VID pins only */
+                               data->vid &= 0x3f;
+
+                       err = device_create_file(dev, &dev_attr_cpu0_vid);
+                       if (err)
+                               goto exit_release;
+               } else {
+                       dev_info(dev, "VID pins in output mode, CPU VID not "
+                                "available\n");
+               }
        }
 
        /* fan4 and fan5 share some pins with the GPIO and serial flash */
-
-       fan5pin = !(superio_inb(sio_data->sioreg, 0x24) & 0x2);
-       fan4pin = !(superio_inb(sio_data->sioreg, 0x29) & 0x6);
+       if (sio_data->kind == w83667hg) {
+               fan5pin = superio_inb(sio_data->sioreg, 0x27) & 0x20;
+               fan4pin = superio_inb(sio_data->sioreg, 0x27) & 0x40;
+       } else {
+               fan5pin = !(superio_inb(sio_data->sioreg, 0x24) & 0x02);
+               fan4pin = !(superio_inb(sio_data->sioreg, 0x29) & 0x06);
+       }
        superio_exit(sio_data->sioreg);
 
        /* It looks like fan4 and fan5 pins can be alternatively used
                        goto exit_remove;
 
        /* if fan4 is enabled create the sf3 files for it */
-       if (data->has_fan & (1 << 3))
+       if ((data->has_fan & (1 << 3)) && data->pwm_num >= 4)
                for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays_fan4); i++) {
                        if ((err = device_create_file(dev,
                                &sda_sf3_arrays_fan4[i].dev_attr)))
                                || (err = device_create_file(dev,
                                        &sda_fan_min[i].dev_attr)))
                                goto exit_remove;
-                       if (i < 4 && /* w83627ehf only has 4 pwm */
+                       if (i < data->pwm_num &&
                                ((err = device_create_file(dev,
                                        &sda_pwm[i].dev_attr))
                                || (err = device_create_file(dev,
        static const char __initdata sio_name_W83627EHF[] = "W83627EHF";
        static const char __initdata sio_name_W83627EHG[] = "W83627EHG";
        static const char __initdata sio_name_W83627DHG[] = "W83627DHG";
+       static const char __initdata sio_name_W83667HG[] = "W83667HG";
 
        u16 val;
        const char *sio_name;
                sio_data->kind = w83627dhg;
                sio_name = sio_name_W83627DHG;
                break;
+       case SIO_W83667HG_ID:
+               sio_data->kind = w83667hg;
+               sio_name = sio_name_W83667HG;
+               break;
        default:
                if (val != 0xffff)
                        pr_debug(DRVNAME ": unsupported chip ID: 0x%04x\n",