ad5592r.c 4.0 KB

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