#define MCP4725_DRV_NAME "mcp4725"
 
+#define MCP472X_REF_VDD                        0x00
+#define MCP472X_REF_VREF_UNBUFFERED    0x02
+#define MCP472X_REF_VREF_BUFFERED      0x03
+
 struct mcp4725_data {
        struct i2c_client *client;
+       int id;
+       unsigned ref_mode;
+       bool vref_buffered;
        u16 dac_value;
        bool powerdown;
        unsigned powerdown_mode;
        struct regulator *vdd_reg;
+       struct regulator *vref_reg;
 };
 
 static int mcp4725_suspend(struct device *dev)
                return 0;
 
        inoutbuf[0] = 0x60; /* write EEPROM */
+       inoutbuf[0] |= data->ref_mode << 3;
        inoutbuf[1] = data->dac_value >> 4;
        inoutbuf[2] = (data->dac_value & 0xf) << 4;
 
                return 0;
 }
 
+static int mcp4726_set_cfg(struct iio_dev *indio_dev)
+{
+       struct mcp4725_data *data = iio_priv(indio_dev);
+       u8 outbuf[3];
+       int ret;
+
+       outbuf[0] = 0x40;
+       outbuf[0] |= data->ref_mode << 3;
+       if (data->powerdown)
+               outbuf[0] |= data->powerdown << 1;
+       outbuf[1] = data->dac_value >> 4;
+       outbuf[2] = (data->dac_value & 0xf) << 4;
+
+       ret = i2c_master_send(data->client, outbuf, 3);
+       if (ret < 0)
+               return ret;
+       else if (ret != 3)
+               return -EIO;
+       else
+               return 0;
+}
+
 static int mcp4725_read_raw(struct iio_dev *indio_dev,
                           struct iio_chan_spec const *chan,
                           int *val, int *val2, long mask)
                *val = data->dac_value;
                return IIO_VAL_INT;
        case IIO_CHAN_INFO_SCALE:
-               ret = regulator_get_voltage(data->vdd_reg);
+               if (data->ref_mode == MCP472X_REF_VDD)
+                       ret = regulator_get_voltage(data->vdd_reg);
+               else
+                       ret = regulator_get_voltage(data->vref_reg);
+
                if (ret < 0)
                        return ret;
 
        struct mcp4725_data *data;
        struct iio_dev *indio_dev;
        struct mcp4725_platform_data *pdata = dev_get_platdata(&client->dev);
-       u8 inbuf[3];
+       u8 inbuf[4];
        u8 pd;
+       u8 ref;
        int err;
 
        if (!pdata) {
        data = iio_priv(indio_dev);
        i2c_set_clientdata(client, indio_dev);
        data->client = client;
+       data->id = id->driver_data;
+
+       if (data->id == MCP4725 && pdata->use_vref) {
+               dev_err(&client->dev,
+                       "external reference is unavailable on MCP4725");
+               return -EINVAL;
+       }
+
+       if (!pdata->use_vref && pdata->vref_buffered) {
+               dev_err(&client->dev,
+                       "buffering is unavailable on the internal reference");
+               return -EINVAL;
+       }
+
+       if (!pdata->use_vref)
+               data->ref_mode = MCP472X_REF_VDD;
+       else
+               data->ref_mode = pdata->vref_buffered ?
+                       MCP472X_REF_VREF_BUFFERED :
+                       MCP472X_REF_VREF_UNBUFFERED;
 
        data->vdd_reg = devm_regulator_get(&client->dev, "vdd");
        if (IS_ERR(data->vdd_reg))
        if (err)
                return err;
 
+       if (pdata->use_vref) {
+               data->vref_reg = devm_regulator_get(&client->dev, "vref");
+               if (IS_ERR(data->vref_reg)) {
+                       err = PTR_ERR(data->vdd_reg);
+                       goto err_disable_vdd_reg;
+               }
+
+               err = regulator_enable(data->vref_reg);
+               if (err)
+                       goto err_disable_vdd_reg;
+       }
+
        indio_dev->dev.parent = &client->dev;
        indio_dev->name = id->name;
        indio_dev->info = &mcp4725_info;
        indio_dev->num_channels = 1;
        indio_dev->modes = INDIO_DIRECT_MODE;
 
-       /* read current DAC value */
-       err = i2c_master_recv(client, inbuf, 3);
+       /* read current DAC value and settings */
+       err = i2c_master_recv(client, inbuf, data->id == MCP4725 ? 3 : 4);
+
        if (err < 0) {
                dev_err(&client->dev, "failed to read DAC value");
-               goto err_disable_vdd_reg;
+               goto err_disable_vref_reg;
        }
        pd = (inbuf[0] >> 1) & 0x3;
        data->powerdown = pd > 0 ? true : false;
        data->powerdown_mode = pd ? pd - 1 : 2; /* largest resistor to gnd */
        data->dac_value = (inbuf[1] << 4) | (inbuf[2] >> 4);
-
+       if (data->id == MCP4726)
+               ref = (inbuf[3] >> 3) & 0x3;
+
+       if (data->id == MCP4726 && ref != data->ref_mode) {
+               dev_info(&client->dev,
+                       "voltage reference mode differs (conf: %u, eeprom: %u), setting %u",
+                       data->ref_mode, ref, data->ref_mode);
+               err = mcp4726_set_cfg(indio_dev);
+               if (err < 0)
+                       goto err_disable_vref_reg;
+       }
+ 
        err = iio_device_register(indio_dev);
        if (err)
-               goto err_disable_vdd_reg;
+               goto err_disable_vref_reg;
 
        return 0;
 
+err_disable_vref_reg:
+       if (data->vref_reg)
+               regulator_disable(data->vref_reg);
 
 err_disable_vdd_reg:
        regulator_disable(data->vdd_reg);
 
        iio_device_unregister(indio_dev);
 
+       if (data->vref_reg)
+               regulator_disable(data->vref_reg);
        regulator_disable(data->vdd_reg);
 
        return 0;