#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
 #include <linux/acpi.h>
-#include <linux/dmi.h>
+#include <linux/delay.h>
 #include <linux/err.h>
 #include <linux/init.h>
 #include <linux/io.h>
 
 static bool force;
 module_param(force, bool, 0);
-MODULE_PARM_DESC(force, "Set to one to enable detection on non-Intel boards");
+MODULE_PARM_DESC(force, "Set to one to enable support for unknown vendors");
 
 static const char * const nct6683_device_names[] = {
        "nct6683",
 #define NCT6683_REG_MON(x)             (0x100 + (x) * 2)
 #define NCT6683_REG_FAN_RPM(x)         (0x140 + (x) * 2)
 #define NCT6683_REG_PWM(x)             (0x160 + (x))
+#define NCT6683_REG_PWM_WRITE(x)       (0xa28 + (x))
 
 #define NCT6683_REG_MON_STS(x)         (0x174 + (x))
 #define NCT6683_REG_IDLE(x)            (0x178 + (x))
 
 #define NCT6683_REG_FAN_MIN(x)         (0x3b8 + (x) * 2)       /* 16 bit */
 
+#define NCT6683_REG_FAN_CFG_CTRL       0xa01
+#define NCT6683_FAN_CFG_REQ            0x80
+#define NCT6683_FAN_CFG_DONE           0x40
+
 #define NCT6683_REG_CUSTOMER_ID                0x602
 #define NCT6683_CUSTOMER_ID_INTEL      0x805
+#define NCT6683_CUSTOMER_ID_MITAC      0xa0e
 
 #define NCT6683_REG_BUILD_YEAR         0x604
 #define NCT6683_REG_BUILD_MONTH                0x605
                        break;
                }
                break;
+       case NCT6683_CUSTOMER_ID_MITAC:
        default:
                switch (nr) {
                default:
        return sprintf(buf, "%d\n", data->pwm[index]);
 }
 
-SENSOR_TEMPLATE(pwm, "pwm%d", S_IRUGO, show_pwm, NULL, 0);
+static ssize_t
+store_pwm(struct device *dev, struct device_attribute *attr, const char *buf,
+         size_t count)
+{
+       struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
+       struct nct6683_data *data = dev_get_drvdata(dev);
+       int index = sattr->index;
+       unsigned long val;
+
+       if (kstrtoul(buf, 10, &val) || val > 255)
+               return -EINVAL;
+
+       mutex_lock(&data->update_lock);
+       nct6683_write(data, NCT6683_REG_FAN_CFG_CTRL, NCT6683_FAN_CFG_REQ);
+       usleep_range(1000, 2000);
+       nct6683_write(data, NCT6683_REG_PWM_WRITE(index), val);
+       nct6683_write(data, NCT6683_REG_FAN_CFG_CTRL, NCT6683_FAN_CFG_DONE);
+       mutex_unlock(&data->update_lock);
+
+       return count;
+}
+
+SENSOR_TEMPLATE(pwm, "pwm%d", S_IRUGO, show_pwm, store_pwm, 0);
 
 static umode_t nct6683_pwm_is_visible(struct kobject *kobj,
                                      struct attribute *attr, int index)
        if (!(data->have_pwm & (1 << pwm)))
                return 0;
 
+       /* Only update pwm values for Mitac boards */
+       if (data->customer_id == NCT6683_CUSTOMER_ID_MITAC)
+               return attr->mode | S_IWUSR;
+
        return attr->mode;
 }
 
        struct device *hwmon_dev;
        struct resource *res;
        int groups = 0;
+       char build[16];
 
        res = platform_get_resource(pdev, IORESOURCE_IO, 0);
        if (!devm_request_region(dev, res->start, IOREGION_LENGTH, DRVNAME))
 
        data->customer_id = nct6683_read16(data, NCT6683_REG_CUSTOMER_ID);
 
+       /* By default only instantiate driver if the customer ID is known */
+       switch (data->customer_id) {
+       case NCT6683_CUSTOMER_ID_INTEL:
+               break;
+       case NCT6683_CUSTOMER_ID_MITAC:
+               break;
+       default:
+               if (!force)
+                       return -ENODEV;
+       }
+
        nct6683_init_device(data);
        nct6683_setup_fans(data);
        nct6683_setup_sensors(data);
        }
        data->groups[groups++] = &nct6683_group_other;
 
-       dev_info(dev, "%s EC firmware version %d.%d build %02x/%02x/%02x\n",
+       if (data->customer_id == NCT6683_CUSTOMER_ID_INTEL)
+               scnprintf(build, sizeof(build), "%02x/%02x/%02x",
+                         nct6683_read(data, NCT6683_REG_BUILD_MONTH),
+                         nct6683_read(data, NCT6683_REG_BUILD_DAY),
+                         nct6683_read(data, NCT6683_REG_BUILD_YEAR));
+       else
+               scnprintf(build, sizeof(build), "%02d/%02d/%02d",
+                         nct6683_read(data, NCT6683_REG_BUILD_MONTH),
+                         nct6683_read(data, NCT6683_REG_BUILD_DAY),
+                         nct6683_read(data, NCT6683_REG_BUILD_YEAR));
+
+       dev_info(dev, "%s EC firmware version %d.%d build %s\n",
                 nct6683_chip_names[data->kind],
                 nct6683_read(data, NCT6683_REG_VERSION_HI),
                 nct6683_read(data, NCT6683_REG_VERSION_LO),
-                nct6683_read(data, NCT6683_REG_BUILD_MONTH),
-                nct6683_read(data, NCT6683_REG_BUILD_DAY),
-                nct6683_read(data, NCT6683_REG_BUILD_YEAR));
+                build);
 
        hwmon_dev = devm_hwmon_device_register_with_groups(dev,
                        nct6683_device_names[data->kind], data, data->groups);
 
 static int __init nct6683_find(int sioaddr, struct nct6683_sio_data *sio_data)
 {
-       const char *board_vendor;
        int addr;
        u16 val;
        int err;
 
-       /*
-        * Only run on Intel boards unless the 'force' module parameter is set
-        */
-       if (!force) {
-               board_vendor = dmi_get_system_info(DMI_BOARD_VENDOR);
-               if (!board_vendor || strcmp(board_vendor, "Intel Corporation"))
-                       return -ENODEV;
-       }
-
        err = superio_enter(sioaddr);
        if (err)
                return err;