mcp4821.c 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * Copyright (C) 2023 Anshul Dalal <anshulusr@gmail.com>
  4. *
  5. * Driver for Microchip MCP4801, MCP4802, MCP4811, MCP4812, MCP4821 and MCP4822
  6. *
  7. * Based on the work of:
  8. * Michael Welling (MCP4922 Driver)
  9. *
  10. * Datasheet:
  11. * MCP48x1: https://ww1.microchip.com/downloads/en/DeviceDoc/22244B.pdf
  12. * MCP48x2: https://ww1.microchip.com/downloads/en/DeviceDoc/20002249B.pdf
  13. *
  14. * TODO:
  15. * - Configurable gain
  16. * - Regulator control
  17. */
  18. #include <linux/module.h>
  19. #include <linux/mod_devicetable.h>
  20. #include <linux/spi/spi.h>
  21. #include <linux/iio/iio.h>
  22. #include <linux/iio/types.h>
  23. #include <linux/unaligned.h>
  24. #define MCP4821_ACTIVE_MODE BIT(12)
  25. #define MCP4802_SECOND_CHAN BIT(15)
  26. /* DAC uses an internal Voltage reference of 4.096V at a gain of 2x */
  27. #define MCP4821_2X_GAIN_VREF_MV 4096
  28. enum mcp4821_supported_drvice_ids {
  29. ID_MCP4801,
  30. ID_MCP4802,
  31. ID_MCP4811,
  32. ID_MCP4812,
  33. ID_MCP4821,
  34. ID_MCP4822,
  35. };
  36. struct mcp4821_state {
  37. struct spi_device *spi;
  38. u16 dac_value[2];
  39. };
  40. struct mcp4821_chip_info {
  41. const char *name;
  42. int num_channels;
  43. const struct iio_chan_spec channels[2];
  44. };
  45. #define MCP4821_CHAN(channel_id, resolution) \
  46. { \
  47. .type = IIO_VOLTAGE, .output = 1, .indexed = 1, \
  48. .channel = (channel_id), \
  49. .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
  50. .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
  51. .scan_type = { \
  52. .realbits = (resolution), \
  53. .shift = 12 - (resolution), \
  54. }, \
  55. }
  56. static const struct mcp4821_chip_info mcp4821_chip_info_table[6] = {
  57. [ID_MCP4801] = {
  58. .name = "mcp4801",
  59. .num_channels = 1,
  60. .channels = {
  61. MCP4821_CHAN(0, 8),
  62. },
  63. },
  64. [ID_MCP4802] = {
  65. .name = "mcp4802",
  66. .num_channels = 2,
  67. .channels = {
  68. MCP4821_CHAN(0, 8),
  69. MCP4821_CHAN(1, 8),
  70. },
  71. },
  72. [ID_MCP4811] = {
  73. .name = "mcp4811",
  74. .num_channels = 1,
  75. .channels = {
  76. MCP4821_CHAN(0, 10),
  77. },
  78. },
  79. [ID_MCP4812] = {
  80. .name = "mcp4812",
  81. .num_channels = 2,
  82. .channels = {
  83. MCP4821_CHAN(0, 10),
  84. MCP4821_CHAN(1, 10),
  85. },
  86. },
  87. [ID_MCP4821] = {
  88. .name = "mcp4821",
  89. .num_channels = 1,
  90. .channels = {
  91. MCP4821_CHAN(0, 12),
  92. },
  93. },
  94. [ID_MCP4822] = {
  95. .name = "mcp4822",
  96. .num_channels = 2,
  97. .channels = {
  98. MCP4821_CHAN(0, 12),
  99. MCP4821_CHAN(1, 12),
  100. },
  101. },
  102. };
  103. static int mcp4821_read_raw(struct iio_dev *indio_dev,
  104. struct iio_chan_spec const *chan, int *val,
  105. int *val2, long mask)
  106. {
  107. struct mcp4821_state *state;
  108. switch (mask) {
  109. case IIO_CHAN_INFO_RAW:
  110. state = iio_priv(indio_dev);
  111. *val = state->dac_value[chan->channel];
  112. return IIO_VAL_INT;
  113. case IIO_CHAN_INFO_SCALE:
  114. *val = MCP4821_2X_GAIN_VREF_MV;
  115. *val2 = chan->scan_type.realbits;
  116. return IIO_VAL_FRACTIONAL_LOG2;
  117. default:
  118. return -EINVAL;
  119. }
  120. }
  121. static int mcp4821_write_raw(struct iio_dev *indio_dev,
  122. struct iio_chan_spec const *chan, int val,
  123. int val2, long mask)
  124. {
  125. struct mcp4821_state *state = iio_priv(indio_dev);
  126. u16 write_val;
  127. __be16 write_buffer;
  128. int ret;
  129. if (val2 != 0)
  130. return -EINVAL;
  131. if (val < 0 || val >= BIT(chan->scan_type.realbits))
  132. return -EINVAL;
  133. if (mask != IIO_CHAN_INFO_RAW)
  134. return -EINVAL;
  135. write_val = MCP4821_ACTIVE_MODE | val << chan->scan_type.shift;
  136. if (chan->channel)
  137. write_val |= MCP4802_SECOND_CHAN;
  138. write_buffer = cpu_to_be16(write_val);
  139. ret = spi_write(state->spi, &write_buffer, sizeof(write_buffer));
  140. if (ret) {
  141. dev_err(&state->spi->dev, "Failed to write to device: %d", ret);
  142. return ret;
  143. }
  144. state->dac_value[chan->channel] = val;
  145. return 0;
  146. }
  147. static const struct iio_info mcp4821_info = {
  148. .read_raw = &mcp4821_read_raw,
  149. .write_raw = &mcp4821_write_raw,
  150. };
  151. static int mcp4821_probe(struct spi_device *spi)
  152. {
  153. struct iio_dev *indio_dev;
  154. struct mcp4821_state *state;
  155. const struct mcp4821_chip_info *info;
  156. indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*state));
  157. if (indio_dev == NULL)
  158. return -ENOMEM;
  159. state = iio_priv(indio_dev);
  160. state->spi = spi;
  161. info = spi_get_device_match_data(spi);
  162. indio_dev->name = info->name;
  163. indio_dev->info = &mcp4821_info;
  164. indio_dev->modes = INDIO_DIRECT_MODE;
  165. indio_dev->channels = info->channels;
  166. indio_dev->num_channels = info->num_channels;
  167. return devm_iio_device_register(&spi->dev, indio_dev);
  168. }
  169. #define MCP4821_COMPATIBLE(of_compatible, id) \
  170. { \
  171. .compatible = of_compatible, \
  172. .data = &mcp4821_chip_info_table[id] \
  173. }
  174. static const struct of_device_id mcp4821_of_table[] = {
  175. MCP4821_COMPATIBLE("microchip,mcp4801", ID_MCP4801),
  176. MCP4821_COMPATIBLE("microchip,mcp4802", ID_MCP4802),
  177. MCP4821_COMPATIBLE("microchip,mcp4811", ID_MCP4811),
  178. MCP4821_COMPATIBLE("microchip,mcp4812", ID_MCP4812),
  179. MCP4821_COMPATIBLE("microchip,mcp4821", ID_MCP4821),
  180. MCP4821_COMPATIBLE("microchip,mcp4822", ID_MCP4822),
  181. { /* Sentinel */ }
  182. };
  183. MODULE_DEVICE_TABLE(of, mcp4821_of_table);
  184. static const struct spi_device_id mcp4821_id_table[] = {
  185. { "mcp4801", (kernel_ulong_t)&mcp4821_chip_info_table[ID_MCP4801]},
  186. { "mcp4802", (kernel_ulong_t)&mcp4821_chip_info_table[ID_MCP4802]},
  187. { "mcp4811", (kernel_ulong_t)&mcp4821_chip_info_table[ID_MCP4811]},
  188. { "mcp4812", (kernel_ulong_t)&mcp4821_chip_info_table[ID_MCP4812]},
  189. { "mcp4821", (kernel_ulong_t)&mcp4821_chip_info_table[ID_MCP4821]},
  190. { "mcp4822", (kernel_ulong_t)&mcp4821_chip_info_table[ID_MCP4822]},
  191. { /* Sentinel */ }
  192. };
  193. MODULE_DEVICE_TABLE(spi, mcp4821_id_table);
  194. static struct spi_driver mcp4821_driver = {
  195. .driver = {
  196. .name = "mcp4821",
  197. .of_match_table = mcp4821_of_table,
  198. },
  199. .probe = mcp4821_probe,
  200. .id_table = mcp4821_id_table,
  201. };
  202. module_spi_driver(mcp4821_driver);
  203. MODULE_AUTHOR("Anshul Dalal <anshulusr@gmail.com>");
  204. MODULE_DESCRIPTION("Microchip MCP4821 DAC Driver");
  205. MODULE_LICENSE("GPL");