ad5272.c 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Analog Devices AD5272 digital potentiometer driver
  4. * Copyright (C) 2018 Phil Reid <preid@electromag.com.au>
  5. *
  6. * Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/AD5272_5274.pdf
  7. *
  8. * DEVID #Wipers #Positions Resistor Opts (kOhm) i2c address
  9. * ad5272 1 1024 20, 50, 100 01011xx
  10. * ad5274 1 256 20, 100 01011xx
  11. */
  12. #include <linux/delay.h>
  13. #include <linux/gpio/consumer.h>
  14. #include <linux/i2c.h>
  15. #include <linux/iio/iio.h>
  16. #include <linux/module.h>
  17. #include <linux/mod_devicetable.h>
  18. #define AD5272_RDAC_WR 1
  19. #define AD5272_RDAC_RD 2
  20. #define AD5272_RESET 4
  21. #define AD5272_CTL 7
  22. #define AD5272_RDAC_WR_EN BIT(1)
  23. struct ad5272_cfg {
  24. int max_pos;
  25. int kohms;
  26. int shift;
  27. };
  28. enum ad5272_type {
  29. AD5272_020,
  30. AD5272_050,
  31. AD5272_100,
  32. AD5274_020,
  33. AD5274_100,
  34. };
  35. static const struct ad5272_cfg ad5272_cfg[] = {
  36. [AD5272_020] = { .max_pos = 1024, .kohms = 20 },
  37. [AD5272_050] = { .max_pos = 1024, .kohms = 50 },
  38. [AD5272_100] = { .max_pos = 1024, .kohms = 100 },
  39. [AD5274_020] = { .max_pos = 256, .kohms = 20, .shift = 2 },
  40. [AD5274_100] = { .max_pos = 256, .kohms = 100, .shift = 2 },
  41. };
  42. struct ad5272_data {
  43. struct i2c_client *client;
  44. struct mutex lock;
  45. const struct ad5272_cfg *cfg;
  46. u8 buf[2] ____cacheline_aligned;
  47. };
  48. static const struct iio_chan_spec ad5272_channel = {
  49. .type = IIO_RESISTANCE,
  50. .output = 1,
  51. .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
  52. .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
  53. };
  54. static int ad5272_write(struct ad5272_data *data, int reg, int val)
  55. {
  56. int ret;
  57. data->buf[0] = (reg << 2) | ((val >> 8) & 0x3);
  58. data->buf[1] = (u8)val;
  59. mutex_lock(&data->lock);
  60. ret = i2c_master_send(data->client, data->buf, sizeof(data->buf));
  61. mutex_unlock(&data->lock);
  62. return ret < 0 ? ret : 0;
  63. }
  64. static int ad5272_read(struct ad5272_data *data, int reg, int *val)
  65. {
  66. int ret;
  67. data->buf[0] = reg << 2;
  68. data->buf[1] = 0;
  69. mutex_lock(&data->lock);
  70. ret = i2c_master_send(data->client, data->buf, sizeof(data->buf));
  71. if (ret < 0)
  72. goto error;
  73. ret = i2c_master_recv(data->client, data->buf, sizeof(data->buf));
  74. if (ret < 0)
  75. goto error;
  76. *val = ((data->buf[0] & 0x3) << 8) | data->buf[1];
  77. ret = 0;
  78. error:
  79. mutex_unlock(&data->lock);
  80. return ret;
  81. }
  82. static int ad5272_read_raw(struct iio_dev *indio_dev,
  83. struct iio_chan_spec const *chan,
  84. int *val, int *val2, long mask)
  85. {
  86. struct ad5272_data *data = iio_priv(indio_dev);
  87. int ret;
  88. switch (mask) {
  89. case IIO_CHAN_INFO_RAW: {
  90. ret = ad5272_read(data, AD5272_RDAC_RD, val);
  91. *val = *val >> data->cfg->shift;
  92. return ret ? ret : IIO_VAL_INT;
  93. }
  94. case IIO_CHAN_INFO_SCALE:
  95. *val = 1000 * data->cfg->kohms;
  96. *val2 = data->cfg->max_pos;
  97. return IIO_VAL_FRACTIONAL;
  98. }
  99. return -EINVAL;
  100. }
  101. static int ad5272_write_raw(struct iio_dev *indio_dev,
  102. struct iio_chan_spec const *chan,
  103. int val, int val2, long mask)
  104. {
  105. struct ad5272_data *data = iio_priv(indio_dev);
  106. if (mask != IIO_CHAN_INFO_RAW)
  107. return -EINVAL;
  108. if (val >= data->cfg->max_pos || val < 0 || val2)
  109. return -EINVAL;
  110. return ad5272_write(data, AD5272_RDAC_WR, val << data->cfg->shift);
  111. }
  112. static const struct iio_info ad5272_info = {
  113. .read_raw = ad5272_read_raw,
  114. .write_raw = ad5272_write_raw,
  115. };
  116. static int ad5272_reset(struct ad5272_data *data)
  117. {
  118. struct gpio_desc *reset_gpio;
  119. reset_gpio = devm_gpiod_get_optional(&data->client->dev, "reset",
  120. GPIOD_OUT_LOW);
  121. if (IS_ERR(reset_gpio))
  122. return PTR_ERR(reset_gpio);
  123. if (reset_gpio) {
  124. udelay(1);
  125. gpiod_set_value(reset_gpio, 1);
  126. } else {
  127. ad5272_write(data, AD5272_RESET, 0);
  128. }
  129. usleep_range(1000, 2000);
  130. return 0;
  131. }
  132. static int ad5272_probe(struct i2c_client *client,
  133. const struct i2c_device_id *id)
  134. {
  135. struct device *dev = &client->dev;
  136. struct iio_dev *indio_dev;
  137. struct ad5272_data *data;
  138. int ret;
  139. indio_dev = devm_iio_device_alloc(dev, sizeof(*data));
  140. if (!indio_dev)
  141. return -ENOMEM;
  142. i2c_set_clientdata(client, indio_dev);
  143. data = iio_priv(indio_dev);
  144. data->client = client;
  145. mutex_init(&data->lock);
  146. data->cfg = &ad5272_cfg[id->driver_data];
  147. ret = ad5272_reset(data);
  148. if (ret)
  149. return ret;
  150. ret = ad5272_write(data, AD5272_CTL, AD5272_RDAC_WR_EN);
  151. if (ret < 0)
  152. return -ENODEV;
  153. indio_dev->info = &ad5272_info;
  154. indio_dev->channels = &ad5272_channel;
  155. indio_dev->num_channels = 1;
  156. indio_dev->name = client->name;
  157. return devm_iio_device_register(dev, indio_dev);
  158. }
  159. static const struct of_device_id ad5272_dt_ids[] = {
  160. { .compatible = "adi,ad5272-020", .data = (void *)AD5272_020 },
  161. { .compatible = "adi,ad5272-050", .data = (void *)AD5272_050 },
  162. { .compatible = "adi,ad5272-100", .data = (void *)AD5272_100 },
  163. { .compatible = "adi,ad5274-020", .data = (void *)AD5274_020 },
  164. { .compatible = "adi,ad5274-100", .data = (void *)AD5274_100 },
  165. {}
  166. };
  167. MODULE_DEVICE_TABLE(of, ad5272_dt_ids);
  168. static const struct i2c_device_id ad5272_id[] = {
  169. { "ad5272-020", AD5272_020 },
  170. { "ad5272-050", AD5272_050 },
  171. { "ad5272-100", AD5272_100 },
  172. { "ad5274-020", AD5274_020 },
  173. { "ad5274-100", AD5274_100 },
  174. {}
  175. };
  176. MODULE_DEVICE_TABLE(i2c, ad5272_id);
  177. static struct i2c_driver ad5272_driver = {
  178. .driver = {
  179. .name = "ad5272",
  180. .of_match_table = ad5272_dt_ids,
  181. },
  182. .probe = ad5272_probe,
  183. .id_table = ad5272_id,
  184. };
  185. module_i2c_driver(ad5272_driver);
  186. MODULE_AUTHOR("Phil Reid <preid@eletromag.com.au>");
  187. MODULE_DESCRIPTION("AD5272 digital potentiometer");
  188. MODULE_LICENSE("GPL v2");