mcp4922.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * mcp4922.c
  4. *
  5. * Driver for Microchip Digital to Analog Converters.
  6. * Supports MCP4902, MCP4912, and MCP4922.
  7. *
  8. * Copyright (c) 2014 EMAC Inc.
  9. */
  10. #include <linux/module.h>
  11. #include <linux/init.h>
  12. #include <linux/spi/spi.h>
  13. #include <linux/iio/iio.h>
  14. #include <linux/iio/sysfs.h>
  15. #include <linux/regulator/consumer.h>
  16. #include <linux/bitops.h>
  17. #define MCP4922_NUM_CHANNELS 2
  18. #define MCP4921_NUM_CHANNELS 1
  19. enum mcp4922_supported_device_ids {
  20. ID_MCP4902,
  21. ID_MCP4912,
  22. ID_MCP4921,
  23. ID_MCP4922,
  24. };
  25. struct mcp4922_state {
  26. struct spi_device *spi;
  27. unsigned int value[MCP4922_NUM_CHANNELS];
  28. unsigned int vref_mv;
  29. struct regulator *vref_reg;
  30. u8 mosi[2] __aligned(IIO_DMA_MINALIGN);
  31. };
  32. #define MCP4922_CHAN(chan, bits) { \
  33. .type = IIO_VOLTAGE, \
  34. .output = 1, \
  35. .indexed = 1, \
  36. .channel = chan, \
  37. .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
  38. .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
  39. .scan_type = { \
  40. .sign = 'u', \
  41. .realbits = (bits), \
  42. .storagebits = 16, \
  43. .shift = 12 - (bits), \
  44. }, \
  45. }
  46. static int mcp4922_spi_write(struct mcp4922_state *state, u8 addr, u32 val)
  47. {
  48. state->mosi[1] = val & 0xff;
  49. state->mosi[0] = (addr == 0) ? 0x00 : 0x80;
  50. state->mosi[0] |= 0x30 | ((val >> 8) & 0x0f);
  51. return spi_write(state->spi, state->mosi, 2);
  52. }
  53. static int mcp4922_read_raw(struct iio_dev *indio_dev,
  54. struct iio_chan_spec const *chan,
  55. int *val,
  56. int *val2,
  57. long mask)
  58. {
  59. struct mcp4922_state *state = iio_priv(indio_dev);
  60. switch (mask) {
  61. case IIO_CHAN_INFO_RAW:
  62. *val = state->value[chan->channel];
  63. return IIO_VAL_INT;
  64. case IIO_CHAN_INFO_SCALE:
  65. *val = state->vref_mv;
  66. *val2 = chan->scan_type.realbits;
  67. return IIO_VAL_FRACTIONAL_LOG2;
  68. default:
  69. return -EINVAL;
  70. }
  71. }
  72. static int mcp4922_write_raw(struct iio_dev *indio_dev,
  73. struct iio_chan_spec const *chan,
  74. int val,
  75. int val2,
  76. long mask)
  77. {
  78. struct mcp4922_state *state = iio_priv(indio_dev);
  79. int ret;
  80. if (val2 != 0)
  81. return -EINVAL;
  82. switch (mask) {
  83. case IIO_CHAN_INFO_RAW:
  84. if (val < 0 || val > GENMASK(chan->scan_type.realbits - 1, 0))
  85. return -EINVAL;
  86. val <<= chan->scan_type.shift;
  87. ret = mcp4922_spi_write(state, chan->channel, val);
  88. if (!ret)
  89. state->value[chan->channel] = val;
  90. return ret;
  91. default:
  92. return -EINVAL;
  93. }
  94. }
  95. static const struct iio_chan_spec mcp4922_channels[4][MCP4922_NUM_CHANNELS] = {
  96. [ID_MCP4902] = { MCP4922_CHAN(0, 8), MCP4922_CHAN(1, 8) },
  97. [ID_MCP4912] = { MCP4922_CHAN(0, 10), MCP4922_CHAN(1, 10) },
  98. [ID_MCP4921] = { MCP4922_CHAN(0, 12), {} },
  99. [ID_MCP4922] = { MCP4922_CHAN(0, 12), MCP4922_CHAN(1, 12) },
  100. };
  101. static const struct iio_info mcp4922_info = {
  102. .read_raw = &mcp4922_read_raw,
  103. .write_raw = &mcp4922_write_raw,
  104. };
  105. static int mcp4922_probe(struct spi_device *spi)
  106. {
  107. struct iio_dev *indio_dev;
  108. struct mcp4922_state *state;
  109. const struct spi_device_id *id;
  110. int ret;
  111. indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*state));
  112. if (indio_dev == NULL)
  113. return -ENOMEM;
  114. state = iio_priv(indio_dev);
  115. state->spi = spi;
  116. state->vref_reg = devm_regulator_get(&spi->dev, "vref");
  117. if (IS_ERR(state->vref_reg))
  118. return dev_err_probe(&spi->dev, PTR_ERR(state->vref_reg),
  119. "Vref regulator not specified\n");
  120. ret = regulator_enable(state->vref_reg);
  121. if (ret) {
  122. dev_err(&spi->dev, "Failed to enable vref regulator: %d\n",
  123. ret);
  124. return ret;
  125. }
  126. ret = regulator_get_voltage(state->vref_reg);
  127. if (ret < 0) {
  128. dev_err(&spi->dev, "Failed to read vref regulator: %d\n",
  129. ret);
  130. goto error_disable_reg;
  131. }
  132. state->vref_mv = ret / 1000;
  133. spi_set_drvdata(spi, indio_dev);
  134. id = spi_get_device_id(spi);
  135. indio_dev->info = &mcp4922_info;
  136. indio_dev->modes = INDIO_DIRECT_MODE;
  137. indio_dev->channels = mcp4922_channels[id->driver_data];
  138. if (id->driver_data == ID_MCP4921)
  139. indio_dev->num_channels = MCP4921_NUM_CHANNELS;
  140. else
  141. indio_dev->num_channels = MCP4922_NUM_CHANNELS;
  142. indio_dev->name = id->name;
  143. ret = iio_device_register(indio_dev);
  144. if (ret) {
  145. dev_err(&spi->dev, "Failed to register iio device: %d\n",
  146. ret);
  147. goto error_disable_reg;
  148. }
  149. return 0;
  150. error_disable_reg:
  151. regulator_disable(state->vref_reg);
  152. return ret;
  153. }
  154. static void mcp4922_remove(struct spi_device *spi)
  155. {
  156. struct iio_dev *indio_dev = spi_get_drvdata(spi);
  157. struct mcp4922_state *state;
  158. iio_device_unregister(indio_dev);
  159. state = iio_priv(indio_dev);
  160. regulator_disable(state->vref_reg);
  161. }
  162. static const struct spi_device_id mcp4922_id[] = {
  163. {"mcp4902", ID_MCP4902},
  164. {"mcp4912", ID_MCP4912},
  165. {"mcp4921", ID_MCP4921},
  166. {"mcp4922", ID_MCP4922},
  167. {}
  168. };
  169. MODULE_DEVICE_TABLE(spi, mcp4922_id);
  170. static struct spi_driver mcp4922_driver = {
  171. .driver = {
  172. .name = "mcp4922",
  173. },
  174. .probe = mcp4922_probe,
  175. .remove = mcp4922_remove,
  176. .id_table = mcp4922_id,
  177. };
  178. module_spi_driver(mcp4922_driver);
  179. MODULE_AUTHOR("Michael Welling <[email protected]>");
  180. MODULE_DESCRIPTION("Microchip MCP4902, MCP4912, MCP4922 DAC");
  181. MODULE_LICENSE("GPL v2");