hts221_spi.c 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. /*
  2. * STMicroelectronics hts221 spi driver
  3. *
  4. * Copyright 2016 STMicroelectronics Inc.
  5. *
  6. * Lorenzo Bianconi <lorenzo.bianconi@st.com>
  7. *
  8. * Licensed under the GPL-2.
  9. */
  10. #include <linux/kernel.h>
  11. #include <linux/module.h>
  12. #include <linux/spi/spi.h>
  13. #include <linux/slab.h>
  14. #include "hts221.h"
  15. #define SENSORS_SPI_READ 0x80
  16. #define SPI_AUTO_INCREMENT 0x40
  17. static int hts221_spi_read(struct device *dev, u8 addr, int len, u8 *data)
  18. {
  19. int err;
  20. struct spi_device *spi = to_spi_device(dev);
  21. struct iio_dev *iio_dev = spi_get_drvdata(spi);
  22. struct hts221_hw *hw = iio_priv(iio_dev);
  23. struct spi_transfer xfers[] = {
  24. {
  25. .tx_buf = hw->tb.tx_buf,
  26. .bits_per_word = 8,
  27. .len = 1,
  28. },
  29. {
  30. .rx_buf = hw->tb.rx_buf,
  31. .bits_per_word = 8,
  32. .len = len,
  33. }
  34. };
  35. if (len > 1)
  36. addr |= SPI_AUTO_INCREMENT;
  37. hw->tb.tx_buf[0] = addr | SENSORS_SPI_READ;
  38. err = spi_sync_transfer(spi, xfers, ARRAY_SIZE(xfers));
  39. if (err < 0)
  40. return err;
  41. memcpy(data, hw->tb.rx_buf, len * sizeof(u8));
  42. return len;
  43. }
  44. static int hts221_spi_write(struct device *dev, u8 addr, int len, u8 *data)
  45. {
  46. struct spi_device *spi = to_spi_device(dev);
  47. struct iio_dev *iio_dev = spi_get_drvdata(spi);
  48. struct hts221_hw *hw = iio_priv(iio_dev);
  49. struct spi_transfer xfers = {
  50. .tx_buf = hw->tb.tx_buf,
  51. .bits_per_word = 8,
  52. .len = len + 1,
  53. };
  54. if (len >= HTS221_TX_MAX_LENGTH)
  55. return -ENOMEM;
  56. if (len > 1)
  57. addr |= SPI_AUTO_INCREMENT;
  58. hw->tb.tx_buf[0] = addr;
  59. memcpy(&hw->tb.tx_buf[1], data, len);
  60. return spi_sync_transfer(spi, &xfers, 1);
  61. }
  62. static const struct hts221_transfer_function hts221_transfer_fn = {
  63. .read = hts221_spi_read,
  64. .write = hts221_spi_write,
  65. };
  66. static int hts221_spi_probe(struct spi_device *spi)
  67. {
  68. struct hts221_hw *hw;
  69. struct iio_dev *iio_dev;
  70. iio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*hw));
  71. if (!iio_dev)
  72. return -ENOMEM;
  73. spi_set_drvdata(spi, iio_dev);
  74. hw = iio_priv(iio_dev);
  75. hw->name = spi->modalias;
  76. hw->dev = &spi->dev;
  77. hw->irq = spi->irq;
  78. hw->tf = &hts221_transfer_fn;
  79. return hts221_probe(iio_dev);
  80. }
  81. static const struct of_device_id hts221_spi_of_match[] = {
  82. { .compatible = "st,hts221", },
  83. {},
  84. };
  85. MODULE_DEVICE_TABLE(of, hts221_spi_of_match);
  86. static const struct spi_device_id hts221_spi_id_table[] = {
  87. { HTS221_DEV_NAME },
  88. {},
  89. };
  90. MODULE_DEVICE_TABLE(spi, hts221_spi_id_table);
  91. static struct spi_driver hts221_driver = {
  92. .driver = {
  93. .name = "hts221_spi",
  94. .pm = &hts221_pm_ops,
  95. .of_match_table = of_match_ptr(hts221_spi_of_match),
  96. },
  97. .probe = hts221_spi_probe,
  98. .id_table = hts221_spi_id_table,
  99. };
  100. module_spi_driver(hts221_driver);
  101. MODULE_AUTHOR("Lorenzo Bianconi <lorenzo.bianconi@st.com>");
  102. MODULE_DESCRIPTION("STMicroelectronics hts221 spi driver");
  103. MODULE_LICENSE("GPL v2");