root/drivers/iio/dac/mcp4725.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. mcp4725_suspend
  2. mcp4725_resume
  3. mcp4725_store_eeprom
  4. mcp4725_get_powerdown_mode
  5. mcp4725_set_powerdown_mode
  6. mcp4725_read_powerdown
  7. mcp4725_write_powerdown
  8. mcp4725_set_value
  9. mcp4726_set_cfg
  10. mcp4725_read_raw
  11. mcp4725_write_raw
  12. mcp4725_probe_dt
  13. mcp4725_probe_dt
  14. mcp4725_probe
  15. mcp4725_remove

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * mcp4725.c - Support for Microchip MCP4725/6
   4  *
   5  * Copyright (C) 2012 Peter Meerwald <pmeerw@pmeerw.net>
   6  *
   7  * Based on max517 by Roland Stigge <stigge@antcom.de>
   8  *
   9  * driver for the Microchip I2C 12-bit digital-to-analog converter (DAC)
  10  * (7-bit I2C slave address 0x60, the three LSBs can be configured in
  11  * hardware)
  12  */
  13 
  14 #include <linux/module.h>
  15 #include <linux/i2c.h>
  16 #include <linux/err.h>
  17 #include <linux/delay.h>
  18 #include <linux/regulator/consumer.h>
  19 #include <linux/of_device.h>
  20 #include <linux/of.h>
  21 
  22 #include <linux/iio/iio.h>
  23 #include <linux/iio/sysfs.h>
  24 
  25 #include <linux/iio/dac/mcp4725.h>
  26 
  27 #define MCP4725_DRV_NAME "mcp4725"
  28 
  29 #define MCP472X_REF_VDD                 0x00
  30 #define MCP472X_REF_VREF_UNBUFFERED     0x02
  31 #define MCP472X_REF_VREF_BUFFERED       0x03
  32 
  33 struct mcp4725_data {
  34         struct i2c_client *client;
  35         int id;
  36         unsigned ref_mode;
  37         bool vref_buffered;
  38         u16 dac_value;
  39         bool powerdown;
  40         unsigned powerdown_mode;
  41         struct regulator *vdd_reg;
  42         struct regulator *vref_reg;
  43 };
  44 
  45 static int __maybe_unused mcp4725_suspend(struct device *dev)
  46 {
  47         struct mcp4725_data *data = iio_priv(i2c_get_clientdata(
  48                 to_i2c_client(dev)));
  49         u8 outbuf[2];
  50 
  51         outbuf[0] = (data->powerdown_mode + 1) << 4;
  52         outbuf[1] = 0;
  53         data->powerdown = true;
  54 
  55         return i2c_master_send(data->client, outbuf, 2);
  56 }
  57 
  58 static int __maybe_unused mcp4725_resume(struct device *dev)
  59 {
  60         struct mcp4725_data *data = iio_priv(i2c_get_clientdata(
  61                 to_i2c_client(dev)));
  62         u8 outbuf[2];
  63 
  64         /* restore previous DAC value */
  65         outbuf[0] = (data->dac_value >> 8) & 0xf;
  66         outbuf[1] = data->dac_value & 0xff;
  67         data->powerdown = false;
  68 
  69         return i2c_master_send(data->client, outbuf, 2);
  70 }
  71 static SIMPLE_DEV_PM_OPS(mcp4725_pm_ops, mcp4725_suspend, mcp4725_resume);
  72 
  73 static ssize_t mcp4725_store_eeprom(struct device *dev,
  74         struct device_attribute *attr, const char *buf, size_t len)
  75 {
  76         struct iio_dev *indio_dev = dev_to_iio_dev(dev);
  77         struct mcp4725_data *data = iio_priv(indio_dev);
  78         int tries = 20;
  79         u8 inoutbuf[3];
  80         bool state;
  81         int ret;
  82 
  83         ret = strtobool(buf, &state);
  84         if (ret < 0)
  85                 return ret;
  86 
  87         if (!state)
  88                 return 0;
  89 
  90         inoutbuf[0] = 0x60; /* write EEPROM */
  91         inoutbuf[0] |= data->ref_mode << 3;
  92         inoutbuf[0] |= data->powerdown ? ((data->powerdown_mode + 1) << 1) : 0;
  93         inoutbuf[1] = data->dac_value >> 4;
  94         inoutbuf[2] = (data->dac_value & 0xf) << 4;
  95 
  96         ret = i2c_master_send(data->client, inoutbuf, 3);
  97         if (ret < 0)
  98                 return ret;
  99         else if (ret != 3)
 100                 return -EIO;
 101 
 102         /* wait for write complete, takes up to 50ms */
 103         while (tries--) {
 104                 msleep(20);
 105                 ret = i2c_master_recv(data->client, inoutbuf, 3);
 106                 if (ret < 0)
 107                         return ret;
 108                 else if (ret != 3)
 109                         return -EIO;
 110 
 111                 if (inoutbuf[0] & 0x80)
 112                         break;
 113         }
 114 
 115         if (tries < 0) {
 116                 dev_err(&data->client->dev,
 117                         "mcp4725_store_eeprom() failed, incomplete\n");
 118                 return -EIO;
 119         }
 120 
 121         return len;
 122 }
 123 
 124 static IIO_DEVICE_ATTR(store_eeprom, S_IWUSR, NULL, mcp4725_store_eeprom, 0);
 125 
 126 static struct attribute *mcp4725_attributes[] = {
 127         &iio_dev_attr_store_eeprom.dev_attr.attr,
 128         NULL,
 129 };
 130 
 131 static const struct attribute_group mcp4725_attribute_group = {
 132         .attrs = mcp4725_attributes,
 133 };
 134 
 135 static const char * const mcp4725_powerdown_modes[] = {
 136         "1kohm_to_gnd",
 137         "100kohm_to_gnd",
 138         "500kohm_to_gnd"
 139 };
 140 
 141 static const char * const mcp4726_powerdown_modes[] = {
 142         "1kohm_to_gnd",
 143         "125kohm_to_gnd",
 144         "640kohm_to_gnd"
 145 };
 146 
 147 static int mcp4725_get_powerdown_mode(struct iio_dev *indio_dev,
 148         const struct iio_chan_spec *chan)
 149 {
 150         struct mcp4725_data *data = iio_priv(indio_dev);
 151 
 152         return data->powerdown_mode;
 153 }
 154 
 155 static int mcp4725_set_powerdown_mode(struct iio_dev *indio_dev,
 156         const struct iio_chan_spec *chan, unsigned mode)
 157 {
 158         struct mcp4725_data *data = iio_priv(indio_dev);
 159 
 160         data->powerdown_mode = mode;
 161 
 162         return 0;
 163 }
 164 
 165 static ssize_t mcp4725_read_powerdown(struct iio_dev *indio_dev,
 166         uintptr_t private, const struct iio_chan_spec *chan, char *buf)
 167 {
 168         struct mcp4725_data *data = iio_priv(indio_dev);
 169 
 170         return sprintf(buf, "%d\n", data->powerdown);
 171 }
 172 
 173 static ssize_t mcp4725_write_powerdown(struct iio_dev *indio_dev,
 174          uintptr_t private, const struct iio_chan_spec *chan,
 175          const char *buf, size_t len)
 176 {
 177         struct mcp4725_data *data = iio_priv(indio_dev);
 178         bool state;
 179         int ret;
 180 
 181         ret = strtobool(buf, &state);
 182         if (ret)
 183                 return ret;
 184 
 185         if (state)
 186                 ret = mcp4725_suspend(&data->client->dev);
 187         else
 188                 ret = mcp4725_resume(&data->client->dev);
 189         if (ret < 0)
 190                 return ret;
 191 
 192         return len;
 193 }
 194 
 195 enum chip_id {
 196         MCP4725,
 197         MCP4726,
 198 };
 199 
 200 static const struct iio_enum mcp472x_powerdown_mode_enum[] = {
 201         [MCP4725] = {
 202                 .items = mcp4725_powerdown_modes,
 203                 .num_items = ARRAY_SIZE(mcp4725_powerdown_modes),
 204                 .get = mcp4725_get_powerdown_mode,
 205                 .set = mcp4725_set_powerdown_mode,
 206         },
 207         [MCP4726] = {
 208                 .items = mcp4726_powerdown_modes,
 209                 .num_items = ARRAY_SIZE(mcp4726_powerdown_modes),
 210                 .get = mcp4725_get_powerdown_mode,
 211                 .set = mcp4725_set_powerdown_mode,
 212         },
 213 };
 214 
 215 static const struct iio_chan_spec_ext_info mcp4725_ext_info[] = {
 216         {
 217                 .name = "powerdown",
 218                 .read = mcp4725_read_powerdown,
 219                 .write = mcp4725_write_powerdown,
 220                 .shared = IIO_SEPARATE,
 221         },
 222         IIO_ENUM("powerdown_mode", IIO_SEPARATE,
 223                         &mcp472x_powerdown_mode_enum[MCP4725]),
 224         IIO_ENUM_AVAILABLE("powerdown_mode",
 225                         &mcp472x_powerdown_mode_enum[MCP4725]),
 226         { },
 227 };
 228 
 229 static const struct iio_chan_spec_ext_info mcp4726_ext_info[] = {
 230         {
 231                 .name = "powerdown",
 232                 .read = mcp4725_read_powerdown,
 233                 .write = mcp4725_write_powerdown,
 234                 .shared = IIO_SEPARATE,
 235         },
 236         IIO_ENUM("powerdown_mode", IIO_SEPARATE,
 237                         &mcp472x_powerdown_mode_enum[MCP4726]),
 238         IIO_ENUM_AVAILABLE("powerdown_mode",
 239                         &mcp472x_powerdown_mode_enum[MCP4726]),
 240         { },
 241 };
 242 
 243 static const struct iio_chan_spec mcp472x_channel[] = {
 244         [MCP4725] = {
 245                 .type           = IIO_VOLTAGE,
 246                 .indexed        = 1,
 247                 .output         = 1,
 248                 .channel        = 0,
 249                 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
 250                 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
 251                 .ext_info       = mcp4725_ext_info,
 252         },
 253         [MCP4726] = {
 254                 .type           = IIO_VOLTAGE,
 255                 .indexed        = 1,
 256                 .output         = 1,
 257                 .channel        = 0,
 258                 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
 259                 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
 260                 .ext_info       = mcp4726_ext_info,
 261         },
 262 };
 263 
 264 static int mcp4725_set_value(struct iio_dev *indio_dev, int val)
 265 {
 266         struct mcp4725_data *data = iio_priv(indio_dev);
 267         u8 outbuf[2];
 268         int ret;
 269 
 270         if (val >= (1 << 12) || val < 0)
 271                 return -EINVAL;
 272 
 273         outbuf[0] = (val >> 8) & 0xf;
 274         outbuf[1] = val & 0xff;
 275 
 276         ret = i2c_master_send(data->client, outbuf, 2);
 277         if (ret < 0)
 278                 return ret;
 279         else if (ret != 2)
 280                 return -EIO;
 281         else
 282                 return 0;
 283 }
 284 
 285 static int mcp4726_set_cfg(struct iio_dev *indio_dev)
 286 {
 287         struct mcp4725_data *data = iio_priv(indio_dev);
 288         u8 outbuf[3];
 289         int ret;
 290 
 291         outbuf[0] = 0x40;
 292         outbuf[0] |= data->ref_mode << 3;
 293         if (data->powerdown)
 294                 outbuf[0] |= data->powerdown << 1;
 295         outbuf[1] = data->dac_value >> 4;
 296         outbuf[2] = (data->dac_value & 0xf) << 4;
 297 
 298         ret = i2c_master_send(data->client, outbuf, 3);
 299         if (ret < 0)
 300                 return ret;
 301         else if (ret != 3)
 302                 return -EIO;
 303         else
 304                 return 0;
 305 }
 306 
 307 static int mcp4725_read_raw(struct iio_dev *indio_dev,
 308                            struct iio_chan_spec const *chan,
 309                            int *val, int *val2, long mask)
 310 {
 311         struct mcp4725_data *data = iio_priv(indio_dev);
 312         int ret;
 313 
 314         switch (mask) {
 315         case IIO_CHAN_INFO_RAW:
 316                 *val = data->dac_value;
 317                 return IIO_VAL_INT;
 318         case IIO_CHAN_INFO_SCALE:
 319                 if (data->ref_mode == MCP472X_REF_VDD)
 320                         ret = regulator_get_voltage(data->vdd_reg);
 321                 else
 322                         ret = regulator_get_voltage(data->vref_reg);
 323 
 324                 if (ret < 0)
 325                         return ret;
 326 
 327                 *val = ret / 1000;
 328                 *val2 = 12;
 329                 return IIO_VAL_FRACTIONAL_LOG2;
 330         }
 331         return -EINVAL;
 332 }
 333 
 334 static int mcp4725_write_raw(struct iio_dev *indio_dev,
 335                                struct iio_chan_spec const *chan,
 336                                int val, int val2, long mask)
 337 {
 338         struct mcp4725_data *data = iio_priv(indio_dev);
 339         int ret;
 340 
 341         switch (mask) {
 342         case IIO_CHAN_INFO_RAW:
 343                 ret = mcp4725_set_value(indio_dev, val);
 344                 data->dac_value = val;
 345                 break;
 346         default:
 347                 ret = -EINVAL;
 348                 break;
 349         }
 350 
 351         return ret;
 352 }
 353 
 354 static const struct iio_info mcp4725_info = {
 355         .read_raw = mcp4725_read_raw,
 356         .write_raw = mcp4725_write_raw,
 357         .attrs = &mcp4725_attribute_group,
 358 };
 359 
 360 #ifdef CONFIG_OF
 361 static int mcp4725_probe_dt(struct device *dev,
 362                             struct mcp4725_platform_data *pdata)
 363 {
 364         struct device_node *np = dev->of_node;
 365 
 366         if (!np)
 367                 return -ENODEV;
 368 
 369         /* check if is the vref-supply defined */
 370         pdata->use_vref = of_property_read_bool(np, "vref-supply");
 371         pdata->vref_buffered =
 372                 of_property_read_bool(np, "microchip,vref-buffered");
 373 
 374         return 0;
 375 }
 376 #else
 377 static int mcp4725_probe_dt(struct device *dev,
 378                             struct mcp4725_platform_data *platform_data)
 379 {
 380         return -ENODEV;
 381 }
 382 #endif
 383 
 384 static int mcp4725_probe(struct i2c_client *client,
 385                          const struct i2c_device_id *id)
 386 {
 387         struct mcp4725_data *data;
 388         struct iio_dev *indio_dev;
 389         struct mcp4725_platform_data *pdata, pdata_dt;
 390         u8 inbuf[4];
 391         u8 pd;
 392         u8 ref;
 393         int err;
 394 
 395         indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
 396         if (indio_dev == NULL)
 397                 return -ENOMEM;
 398         data = iio_priv(indio_dev);
 399         i2c_set_clientdata(client, indio_dev);
 400         data->client = client;
 401         if (client->dev.of_node)
 402                 data->id = (enum chip_id)of_device_get_match_data(&client->dev);
 403         else
 404                 data->id = id->driver_data;
 405         pdata = dev_get_platdata(&client->dev);
 406 
 407         if (!pdata) {
 408                 err = mcp4725_probe_dt(&client->dev, &pdata_dt);
 409                 if (err) {
 410                         dev_err(&client->dev,
 411                                 "invalid platform or devicetree data");
 412                         return err;
 413                 }
 414                 pdata = &pdata_dt;
 415         }
 416 
 417         if (data->id == MCP4725 && pdata->use_vref) {
 418                 dev_err(&client->dev,
 419                         "external reference is unavailable on MCP4725");
 420                 return -EINVAL;
 421         }
 422 
 423         if (!pdata->use_vref && pdata->vref_buffered) {
 424                 dev_err(&client->dev,
 425                         "buffering is unavailable on the internal reference");
 426                 return -EINVAL;
 427         }
 428 
 429         if (!pdata->use_vref)
 430                 data->ref_mode = MCP472X_REF_VDD;
 431         else
 432                 data->ref_mode = pdata->vref_buffered ?
 433                         MCP472X_REF_VREF_BUFFERED :
 434                         MCP472X_REF_VREF_UNBUFFERED;
 435 
 436         data->vdd_reg = devm_regulator_get(&client->dev, "vdd");
 437         if (IS_ERR(data->vdd_reg))
 438                 return PTR_ERR(data->vdd_reg);
 439 
 440         err = regulator_enable(data->vdd_reg);
 441         if (err)
 442                 return err;
 443 
 444         if (pdata->use_vref) {
 445                 data->vref_reg = devm_regulator_get(&client->dev, "vref");
 446                 if (IS_ERR(data->vref_reg)) {
 447                         err = PTR_ERR(data->vref_reg);
 448                         goto err_disable_vdd_reg;
 449                 }
 450 
 451                 err = regulator_enable(data->vref_reg);
 452                 if (err)
 453                         goto err_disable_vdd_reg;
 454         }
 455 
 456         indio_dev->dev.parent = &client->dev;
 457         indio_dev->name = id->name;
 458         indio_dev->info = &mcp4725_info;
 459         indio_dev->channels = &mcp472x_channel[id->driver_data];
 460         indio_dev->num_channels = 1;
 461         indio_dev->modes = INDIO_DIRECT_MODE;
 462 
 463         /* read current DAC value and settings */
 464         err = i2c_master_recv(client, inbuf, data->id == MCP4725 ? 3 : 4);
 465 
 466         if (err < 0) {
 467                 dev_err(&client->dev, "failed to read DAC value");
 468                 goto err_disable_vref_reg;
 469         }
 470         pd = (inbuf[0] >> 1) & 0x3;
 471         data->powerdown = pd > 0;
 472         data->powerdown_mode = pd ? pd - 1 : 2; /* largest resistor to gnd */
 473         data->dac_value = (inbuf[1] << 4) | (inbuf[2] >> 4);
 474         if (data->id == MCP4726)
 475                 ref = (inbuf[3] >> 3) & 0x3;
 476 
 477         if (data->id == MCP4726 && ref != data->ref_mode) {
 478                 dev_info(&client->dev,
 479                         "voltage reference mode differs (conf: %u, eeprom: %u), setting %u",
 480                         data->ref_mode, ref, data->ref_mode);
 481                 err = mcp4726_set_cfg(indio_dev);
 482                 if (err < 0)
 483                         goto err_disable_vref_reg;
 484         }
 485  
 486         err = iio_device_register(indio_dev);
 487         if (err)
 488                 goto err_disable_vref_reg;
 489 
 490         return 0;
 491 
 492 err_disable_vref_reg:
 493         if (data->vref_reg)
 494                 regulator_disable(data->vref_reg);
 495 
 496 err_disable_vdd_reg:
 497         regulator_disable(data->vdd_reg);
 498 
 499         return err;
 500 }
 501 
 502 static int mcp4725_remove(struct i2c_client *client)
 503 {
 504         struct iio_dev *indio_dev = i2c_get_clientdata(client);
 505         struct mcp4725_data *data = iio_priv(indio_dev);
 506 
 507         iio_device_unregister(indio_dev);
 508 
 509         if (data->vref_reg)
 510                 regulator_disable(data->vref_reg);
 511         regulator_disable(data->vdd_reg);
 512 
 513         return 0;
 514 }
 515 
 516 static const struct i2c_device_id mcp4725_id[] = {
 517         { "mcp4725", MCP4725 },
 518         { "mcp4726", MCP4726 },
 519         { }
 520 };
 521 MODULE_DEVICE_TABLE(i2c, mcp4725_id);
 522 
 523 #ifdef CONFIG_OF
 524 static const struct of_device_id mcp4725_of_match[] = {
 525         {
 526                 .compatible = "microchip,mcp4725",
 527                 .data = (void *)MCP4725
 528         },
 529         {
 530                 .compatible = "microchip,mcp4726",
 531                 .data = (void *)MCP4726
 532         },
 533         { }
 534 };
 535 MODULE_DEVICE_TABLE(of, mcp4725_of_match);
 536 #endif
 537 
 538 static struct i2c_driver mcp4725_driver = {
 539         .driver = {
 540                 .name   = MCP4725_DRV_NAME,
 541                 .of_match_table = of_match_ptr(mcp4725_of_match),
 542                 .pm     = &mcp4725_pm_ops,
 543         },
 544         .probe          = mcp4725_probe,
 545         .remove         = mcp4725_remove,
 546         .id_table       = mcp4725_id,
 547 };
 548 module_i2c_driver(mcp4725_driver);
 549 
 550 MODULE_AUTHOR("Peter Meerwald <pmeerw@pmeerw.net>");
 551 MODULE_DESCRIPTION("MCP4725/6 12-bit DAC");
 552 MODULE_LICENSE("GPL");

/* [<][>][^][v][top][bottom][index][help] */