mcp320x.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. /*
  2. * Copyright (C) 2013 Oskar Andero <oskar.andero@gmail.com>
  3. *
  4. * Driver for Microchip Technology's MCP3204 and MCP3208 ADC chips.
  5. * Datasheet can be found here:
  6. * http://ww1.microchip.com/downloads/en/devicedoc/21298c.pdf
  7. *
  8. * This program is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License version 2 as
  10. * published by the Free Software Foundation.
  11. */
  12. #include <linux/err.h>
  13. #include <linux/spi/spi.h>
  14. #include <linux/module.h>
  15. #include <linux/iio/iio.h>
  16. #include <linux/regulator/consumer.h>
  17. #define MCP_SINGLE_ENDED (1 << 3)
  18. #define MCP_START_BIT (1 << 4)
  19. enum {
  20. mcp3204,
  21. mcp3208,
  22. };
  23. struct mcp320x {
  24. struct spi_device *spi;
  25. struct spi_message msg;
  26. struct spi_transfer transfer[2];
  27. u8 tx_buf;
  28. u8 rx_buf[2];
  29. struct regulator *reg;
  30. struct mutex lock;
  31. };
  32. static int mcp320x_adc_conversion(struct mcp320x *adc, u8 msg)
  33. {
  34. int ret;
  35. adc->tx_buf = msg;
  36. ret = spi_sync(adc->spi, &adc->msg);
  37. if (ret < 0)
  38. return ret;
  39. return ((adc->rx_buf[0] & 0x3f) << 6) |
  40. (adc->rx_buf[1] >> 2);
  41. }
  42. static int mcp320x_read_raw(struct iio_dev *indio_dev,
  43. struct iio_chan_spec const *channel, int *val,
  44. int *val2, long mask)
  45. {
  46. struct mcp320x *adc = iio_priv(indio_dev);
  47. int ret = -EINVAL;
  48. mutex_lock(&adc->lock);
  49. switch (mask) {
  50. case IIO_CHAN_INFO_RAW:
  51. if (channel->differential)
  52. ret = mcp320x_adc_conversion(adc,
  53. MCP_START_BIT | channel->address);
  54. else
  55. ret = mcp320x_adc_conversion(adc,
  56. MCP_START_BIT | MCP_SINGLE_ENDED |
  57. channel->address);
  58. if (ret < 0)
  59. goto out;
  60. *val = ret;
  61. ret = IIO_VAL_INT;
  62. break;
  63. case IIO_CHAN_INFO_SCALE:
  64. /* Digital output code = (4096 * Vin) / Vref */
  65. ret = regulator_get_voltage(adc->reg);
  66. if (ret < 0)
  67. goto out;
  68. *val = ret / 1000;
  69. *val2 = 12;
  70. ret = IIO_VAL_FRACTIONAL_LOG2;
  71. break;
  72. default:
  73. break;
  74. }
  75. out:
  76. mutex_unlock(&adc->lock);
  77. return ret;
  78. }
  79. #define MCP320X_VOLTAGE_CHANNEL(num) \
  80. { \
  81. .type = IIO_VOLTAGE, \
  82. .indexed = 1, \
  83. .channel = (num), \
  84. .address = (num), \
  85. .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
  86. .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) \
  87. }
  88. #define MCP320X_VOLTAGE_CHANNEL_DIFF(num) \
  89. { \
  90. .type = IIO_VOLTAGE, \
  91. .indexed = 1, \
  92. .channel = (num * 2), \
  93. .channel2 = (num * 2 + 1), \
  94. .address = (num * 2), \
  95. .differential = 1, \
  96. .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
  97. .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) \
  98. }
  99. static const struct iio_chan_spec mcp3204_channels[] = {
  100. MCP320X_VOLTAGE_CHANNEL(0),
  101. MCP320X_VOLTAGE_CHANNEL(1),
  102. MCP320X_VOLTAGE_CHANNEL(2),
  103. MCP320X_VOLTAGE_CHANNEL(3),
  104. MCP320X_VOLTAGE_CHANNEL_DIFF(0),
  105. MCP320X_VOLTAGE_CHANNEL_DIFF(1),
  106. };
  107. static const struct iio_chan_spec mcp3208_channels[] = {
  108. MCP320X_VOLTAGE_CHANNEL(0),
  109. MCP320X_VOLTAGE_CHANNEL(1),
  110. MCP320X_VOLTAGE_CHANNEL(2),
  111. MCP320X_VOLTAGE_CHANNEL(3),
  112. MCP320X_VOLTAGE_CHANNEL(4),
  113. MCP320X_VOLTAGE_CHANNEL(5),
  114. MCP320X_VOLTAGE_CHANNEL(6),
  115. MCP320X_VOLTAGE_CHANNEL(7),
  116. MCP320X_VOLTAGE_CHANNEL_DIFF(0),
  117. MCP320X_VOLTAGE_CHANNEL_DIFF(1),
  118. MCP320X_VOLTAGE_CHANNEL_DIFF(2),
  119. MCP320X_VOLTAGE_CHANNEL_DIFF(3),
  120. };
  121. static const struct iio_info mcp320x_info = {
  122. .read_raw = mcp320x_read_raw,
  123. .driver_module = THIS_MODULE,
  124. };
  125. struct mcp3208_chip_info {
  126. const struct iio_chan_spec *channels;
  127. unsigned int num_channels;
  128. };
  129. static const struct mcp3208_chip_info mcp3208_chip_infos[] = {
  130. [mcp3204] = {
  131. .channels = mcp3204_channels,
  132. .num_channels = ARRAY_SIZE(mcp3204_channels)
  133. },
  134. [mcp3208] = {
  135. .channels = mcp3208_channels,
  136. .num_channels = ARRAY_SIZE(mcp3208_channels)
  137. },
  138. };
  139. static int mcp320x_probe(struct spi_device *spi)
  140. {
  141. struct iio_dev *indio_dev;
  142. struct mcp320x *adc;
  143. const struct mcp3208_chip_info *chip_info;
  144. int ret;
  145. indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*adc));
  146. if (!indio_dev)
  147. return -ENOMEM;
  148. adc = iio_priv(indio_dev);
  149. adc->spi = spi;
  150. indio_dev->dev.parent = &spi->dev;
  151. indio_dev->name = spi_get_device_id(spi)->name;
  152. indio_dev->modes = INDIO_DIRECT_MODE;
  153. indio_dev->info = &mcp320x_info;
  154. chip_info = &mcp3208_chip_infos[spi_get_device_id(spi)->driver_data];
  155. indio_dev->channels = chip_info->channels;
  156. indio_dev->num_channels = chip_info->num_channels;
  157. adc->transfer[0].tx_buf = &adc->tx_buf;
  158. adc->transfer[0].len = sizeof(adc->tx_buf);
  159. adc->transfer[1].rx_buf = adc->rx_buf;
  160. adc->transfer[1].len = sizeof(adc->rx_buf);
  161. spi_message_init_with_transfers(&adc->msg, adc->transfer,
  162. ARRAY_SIZE(adc->transfer));
  163. adc->reg = devm_regulator_get(&spi->dev, "vref");
  164. if (IS_ERR(adc->reg))
  165. return PTR_ERR(adc->reg);
  166. ret = regulator_enable(adc->reg);
  167. if (ret < 0)
  168. return ret;
  169. mutex_init(&adc->lock);
  170. ret = iio_device_register(indio_dev);
  171. if (ret < 0)
  172. goto reg_disable;
  173. return 0;
  174. reg_disable:
  175. regulator_disable(adc->reg);
  176. return ret;
  177. }
  178. static int mcp320x_remove(struct spi_device *spi)
  179. {
  180. struct iio_dev *indio_dev = spi_get_drvdata(spi);
  181. struct mcp320x *adc = iio_priv(indio_dev);
  182. iio_device_unregister(indio_dev);
  183. regulator_disable(adc->reg);
  184. return 0;
  185. }
  186. static const struct spi_device_id mcp320x_id[] = {
  187. { "mcp3204", mcp3204 },
  188. { "mcp3208", mcp3208 },
  189. { }
  190. };
  191. MODULE_DEVICE_TABLE(spi, mcp320x_id);
  192. static struct spi_driver mcp320x_driver = {
  193. .driver = {
  194. .name = "mcp320x",
  195. .owner = THIS_MODULE,
  196. },
  197. .probe = mcp320x_probe,
  198. .remove = mcp320x_remove,
  199. .id_table = mcp320x_id,
  200. };
  201. module_spi_driver(mcp320x_driver);
  202. MODULE_AUTHOR("Oskar Andero <oskar.andero@gmail.com>");
  203. MODULE_DESCRIPTION("Microchip Technology MCP3204/08");
  204. MODULE_LICENSE("GPL v2");