ad5686-spi.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * AD5672R, AD5674R, AD5676, AD5676R, AD5679R,
  4. * AD5681R, AD5682R, AD5683, AD5683R, AD5684,
  5. * AD5684R, AD5685R, AD5686, AD5686R
  6. * Digital to analog converters driver
  7. *
  8. * Copyright 2018 Analog Devices Inc.
  9. */
  10. #include "ad5686.h"
  11. #include <linux/module.h>
  12. #include <linux/spi/spi.h>
  13. static int ad5686_spi_write(struct ad5686_state *st,
  14. u8 cmd, u8 addr, u16 val)
  15. {
  16. struct spi_device *spi = to_spi_device(st->dev);
  17. u8 tx_len, *buf;
  18. switch (st->chip_info->regmap_type) {
  19. case AD5310_REGMAP:
  20. st->data[0].d16 = cpu_to_be16(AD5310_CMD(cmd) |
  21. val);
  22. buf = &st->data[0].d8[0];
  23. tx_len = 2;
  24. break;
  25. case AD5683_REGMAP:
  26. st->data[0].d32 = cpu_to_be32(AD5686_CMD(cmd) |
  27. AD5683_DATA(val));
  28. buf = &st->data[0].d8[1];
  29. tx_len = 3;
  30. break;
  31. case AD5686_REGMAP:
  32. st->data[0].d32 = cpu_to_be32(AD5686_CMD(cmd) |
  33. AD5686_ADDR(addr) |
  34. val);
  35. buf = &st->data[0].d8[1];
  36. tx_len = 3;
  37. break;
  38. default:
  39. return -EINVAL;
  40. }
  41. return spi_write(spi, buf, tx_len);
  42. }
  43. static int ad5686_spi_read(struct ad5686_state *st, u8 addr)
  44. {
  45. struct spi_transfer t[] = {
  46. {
  47. .tx_buf = &st->data[0].d8[1],
  48. .len = 3,
  49. .cs_change = 1,
  50. }, {
  51. .tx_buf = &st->data[1].d8[1],
  52. .rx_buf = &st->data[2].d8[1],
  53. .len = 3,
  54. },
  55. };
  56. struct spi_device *spi = to_spi_device(st->dev);
  57. u8 cmd = 0;
  58. int ret;
  59. switch (st->chip_info->regmap_type) {
  60. case AD5310_REGMAP:
  61. return -ENOTSUPP;
  62. case AD5683_REGMAP:
  63. cmd = AD5686_CMD_READBACK_ENABLE_V2;
  64. break;
  65. case AD5686_REGMAP:
  66. cmd = AD5686_CMD_READBACK_ENABLE;
  67. break;
  68. default:
  69. return -EINVAL;
  70. }
  71. st->data[0].d32 = cpu_to_be32(AD5686_CMD(cmd) |
  72. AD5686_ADDR(addr));
  73. st->data[1].d32 = cpu_to_be32(AD5686_CMD(AD5686_CMD_NOOP));
  74. ret = spi_sync_transfer(spi, t, ARRAY_SIZE(t));
  75. if (ret < 0)
  76. return ret;
  77. return be32_to_cpu(st->data[2].d32);
  78. }
  79. static int ad5686_spi_probe(struct spi_device *spi)
  80. {
  81. const struct spi_device_id *id = spi_get_device_id(spi);
  82. return ad5686_probe(&spi->dev, id->driver_data, id->name,
  83. ad5686_spi_write, ad5686_spi_read);
  84. }
  85. static int ad5686_spi_remove(struct spi_device *spi)
  86. {
  87. return ad5686_remove(&spi->dev);
  88. }
  89. static const struct spi_device_id ad5686_spi_id[] = {
  90. {"ad5310r", ID_AD5310R},
  91. {"ad5672r", ID_AD5672R},
  92. {"ad5674r", ID_AD5674R},
  93. {"ad5676", ID_AD5676},
  94. {"ad5676r", ID_AD5676R},
  95. {"ad5679r", ID_AD5679R},
  96. {"ad5681r", ID_AD5681R},
  97. {"ad5682r", ID_AD5682R},
  98. {"ad5683", ID_AD5683},
  99. {"ad5683r", ID_AD5683R},
  100. {"ad5684", ID_AD5684},
  101. {"ad5684r", ID_AD5684R},
  102. {"ad5685", ID_AD5685R}, /* Does not exist */
  103. {"ad5685r", ID_AD5685R},
  104. {"ad5686", ID_AD5686},
  105. {"ad5686r", ID_AD5686R},
  106. {}
  107. };
  108. MODULE_DEVICE_TABLE(spi, ad5686_spi_id);
  109. static struct spi_driver ad5686_spi_driver = {
  110. .driver = {
  111. .name = "ad5686",
  112. },
  113. .probe = ad5686_spi_probe,
  114. .remove = ad5686_spi_remove,
  115. .id_table = ad5686_spi_id,
  116. };
  117. module_spi_driver(ad5686_spi_driver);
  118. MODULE_AUTHOR("Stefan Popa <stefan.popa@analog.com>");
  119. MODULE_DESCRIPTION("Analog Devices AD5686 and similar multi-channel DACs");
  120. MODULE_LICENSE("GPL v2");