ad5592r.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. /*
  2. * AD5592R Digital <-> Analog converters driver
  3. *
  4. * Copyright 2015-2016 Analog Devices Inc.
  5. * Author: Paul Cercueil <paul.cercueil@analog.com>
  6. *
  7. * Licensed under the GPL-2.
  8. */
  9. #include "ad5592r-base.h"
  10. #include <linux/bitops.h>
  11. #include <linux/module.h>
  12. #include <linux/of.h>
  13. #include <linux/spi/spi.h>
  14. #define AD5592R_GPIO_READBACK_EN BIT(10)
  15. #define AD5592R_LDAC_READBACK_EN BIT(6)
  16. static int ad5592r_spi_wnop_r16(struct ad5592r_state *st, u16 *buf)
  17. {
  18. struct spi_device *spi = container_of(st->dev, struct spi_device, dev);
  19. struct spi_transfer t = {
  20. .tx_buf = &st->spi_msg_nop,
  21. .rx_buf = buf,
  22. .len = 2
  23. };
  24. st->spi_msg_nop = 0; /* NOP */
  25. return spi_sync_transfer(spi, &t, 1);
  26. }
  27. static int ad5592r_write_dac(struct ad5592r_state *st, unsigned chan, u16 value)
  28. {
  29. struct spi_device *spi = container_of(st->dev, struct spi_device, dev);
  30. st->spi_msg = cpu_to_be16(BIT(15) | (chan << 12) | value);
  31. return spi_write(spi, &st->spi_msg, sizeof(st->spi_msg));
  32. }
  33. static int ad5592r_read_adc(struct ad5592r_state *st, unsigned chan, u16 *value)
  34. {
  35. struct spi_device *spi = container_of(st->dev, struct spi_device, dev);
  36. int ret;
  37. st->spi_msg = cpu_to_be16((AD5592R_REG_ADC_SEQ << 11) | BIT(chan));
  38. ret = spi_write(spi, &st->spi_msg, sizeof(st->spi_msg));
  39. if (ret)
  40. return ret;
  41. /*
  42. * Invalid data:
  43. * See Figure 40. Single-Channel ADC Conversion Sequence
  44. */
  45. ret = ad5592r_spi_wnop_r16(st, &st->spi_msg);
  46. if (ret)
  47. return ret;
  48. ret = ad5592r_spi_wnop_r16(st, &st->spi_msg);
  49. if (ret)
  50. return ret;
  51. *value = be16_to_cpu(st->spi_msg);
  52. return 0;
  53. }
  54. static int ad5592r_reg_write(struct ad5592r_state *st, u8 reg, u16 value)
  55. {
  56. struct spi_device *spi = container_of(st->dev, struct spi_device, dev);
  57. st->spi_msg = cpu_to_be16((reg << 11) | value);
  58. return spi_write(spi, &st->spi_msg, sizeof(st->spi_msg));
  59. }
  60. static int ad5592r_reg_read(struct ad5592r_state *st, u8 reg, u16 *value)
  61. {
  62. struct spi_device *spi = container_of(st->dev, struct spi_device, dev);
  63. int ret;
  64. st->spi_msg = cpu_to_be16((AD5592R_REG_LDAC << 11) |
  65. AD5592R_LDAC_READBACK_EN | (reg << 2));
  66. ret = spi_write(spi, &st->spi_msg, sizeof(st->spi_msg));
  67. if (ret)
  68. return ret;
  69. ret = ad5592r_spi_wnop_r16(st, &st->spi_msg);
  70. if (ret)
  71. return ret;
  72. *value = be16_to_cpu(st->spi_msg);
  73. return 0;
  74. }
  75. static int ad5593r_gpio_read(struct ad5592r_state *st, u8 *value)
  76. {
  77. int ret;
  78. ret = ad5592r_reg_write(st, AD5592R_REG_GPIO_IN_EN,
  79. AD5592R_GPIO_READBACK_EN | st->gpio_in);
  80. if (ret)
  81. return ret;
  82. ret = ad5592r_spi_wnop_r16(st, &st->spi_msg);
  83. if (ret)
  84. return ret;
  85. *value = (u8) be16_to_cpu(st->spi_msg);
  86. return 0;
  87. }
  88. static const struct ad5592r_rw_ops ad5592r_rw_ops = {
  89. .write_dac = ad5592r_write_dac,
  90. .read_adc = ad5592r_read_adc,
  91. .reg_write = ad5592r_reg_write,
  92. .reg_read = ad5592r_reg_read,
  93. .gpio_read = ad5593r_gpio_read,
  94. };
  95. static int ad5592r_spi_probe(struct spi_device *spi)
  96. {
  97. const struct spi_device_id *id = spi_get_device_id(spi);
  98. return ad5592r_probe(&spi->dev, id->name, &ad5592r_rw_ops);
  99. }
  100. static int ad5592r_spi_remove(struct spi_device *spi)
  101. {
  102. return ad5592r_remove(&spi->dev);
  103. }
  104. static const struct spi_device_id ad5592r_spi_ids[] = {
  105. { .name = "ad5592r", },
  106. {}
  107. };
  108. MODULE_DEVICE_TABLE(spi, ad5592r_spi_ids);
  109. static const struct of_device_id ad5592r_of_match[] = {
  110. { .compatible = "adi,ad5592r", },
  111. {},
  112. };
  113. MODULE_DEVICE_TABLE(of, ad5592r_of_match);
  114. static struct spi_driver ad5592r_spi_driver = {
  115. .driver = {
  116. .name = "ad5592r",
  117. .of_match_table = of_match_ptr(ad5592r_of_match),
  118. },
  119. .probe = ad5592r_spi_probe,
  120. .remove = ad5592r_spi_remove,
  121. .id_table = ad5592r_spi_ids,
  122. };
  123. module_spi_driver(ad5592r_spi_driver);
  124. MODULE_AUTHOR("Paul Cercueil <paul.cercueil@analog.com>");
  125. MODULE_DESCRIPTION("Analog Devices AD5592R multi-channel converters");
  126. MODULE_LICENSE("GPL v2");