#include <linux/hwmon.h>
 #include <linux/hwmon-sysfs.h>
 #include <linux/err.h>
+#include <linux/of_device.h>
 
 /*
  * Insmod parameters
 static int fan_voltage;
 /* prescaler: Possible values are 1, 2, 4, 8, 16 or 0 for don't change */
 static int prescaler;
-/* clock: The clock frequency of the chip the driver should assume */
+/* clock: The clock frequency of the chip (max6651 can be clocked externally) */
 static int clock = 254000;
 
 module_param(fan_voltage, int, S_IRUGO);
        MAX6650_REG_TACH3,
 };
 
+static const struct of_device_id max6650_dt_match[] = {
+       {
+               .compatible = "maxim,max6650",
+               .data = (void *)1
+       },
+       {
+               .compatible = "maxim,max6651",
+               .data = (void *)4
+       },
+       { },
+};
+MODULE_DEVICE_TABLE(of, max6650_dt_match);
+
 static struct max6650_data *max6650_update_device(struct device *dev)
 {
        struct max6650_data *data = dev_get_drvdata(dev);
        struct device *dev = &client->dev;
        int config;
        int err = -EIO;
+       u32 voltage;
+       u32 prescale;
+
+       if (of_property_read_u32(dev->of_node, "maxim,fan-microvolt",
+                                &voltage))
+               voltage = fan_voltage;
+       else
+               voltage /= 1000000; /* Microvolts to volts */
+       if (of_property_read_u32(dev->of_node, "maxim,fan-prescale",
+                                &prescale))
+               prescale = prescaler;
 
        config = i2c_smbus_read_byte_data(client, MAX6650_REG_CONFIG);
 
                return err;
        }
 
-       switch (fan_voltage) {
+       switch (voltage) {
        case 0:
                break;
        case 5:
                config |= MAX6650_CFG_V12;
                break;
        default:
-               dev_err(dev, "illegal value for fan_voltage (%d)\n",
-                       fan_voltage);
+               dev_err(dev, "illegal value for fan_voltage (%d)\n", voltage);
        }
 
-       dev_info(dev, "Fan voltage is set to %dV.\n",
-                (config & MAX6650_CFG_V12) ? 12 : 5);
-
-       switch (prescaler) {
+       switch (prescale) {
        case 0:
                break;
        case 1:
                         | MAX6650_CFG_PRESCALER_16;
                break;
        default:
-               dev_err(dev, "illegal value for prescaler (%d)\n", prescaler);
+               dev_err(dev, "illegal value for prescaler (%d)\n", prescale);
        }
 
-       dev_info(dev, "Prescaler is set to %d.\n",
+       dev_info(dev, "Fan voltage: %dV, prescaler: %d.\n",
+                (config & MAX6650_CFG_V12) ? 12 : 5,
                 1 << (config & MAX6650_CFG_PRESCALER_MASK));
 
        /*
                         const struct i2c_device_id *id)
 {
        struct device *dev = &client->dev;
+       const struct of_device_id *of_id =
+               of_match_device(of_match_ptr(max6650_dt_match), dev);
        struct max6650_data *data;
        struct device *hwmon_dev;
        int err;
 
        data->client = client;
        mutex_init(&data->update_lock);
-       data->nr_fans = id->driver_data;
+       data->nr_fans = of_id ? (int)(uintptr_t)of_id->data : id->driver_data;
 
        /*
         * Initialize the max6650 chip
 static struct i2c_driver max6650_driver = {
        .driver = {
                .name   = "max6650",
+               .of_match_table = of_match_ptr(max6650_dt_match),
        },
        .probe          = max6650_probe,
        .id_table       = max6650_id,