st_lsm6dsx_spi.c 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. /*
  2. * STMicroelectronics st_lsm6dsx spi driver
  3. *
  4. * Copyright 2016 STMicroelectronics Inc.
  5. *
  6. * Lorenzo Bianconi <lorenzo.bianconi@st.com>
  7. * Denis Ciocca <denis.ciocca@st.com>
  8. *
  9. * Licensed under the GPL-2.
  10. */
  11. #include <linux/kernel.h>
  12. #include <linux/module.h>
  13. #include <linux/spi/spi.h>
  14. #include <linux/slab.h>
  15. #include <linux/of.h>
  16. #include "st_lsm6dsx.h"
  17. #define SENSORS_SPI_READ BIT(7)
  18. static int st_lsm6dsx_spi_read(struct device *dev, u8 addr, int len,
  19. u8 *data)
  20. {
  21. struct spi_device *spi = to_spi_device(dev);
  22. struct st_lsm6dsx_hw *hw = spi_get_drvdata(spi);
  23. int err;
  24. struct spi_transfer xfers[] = {
  25. {
  26. .tx_buf = hw->tb.tx_buf,
  27. .bits_per_word = 8,
  28. .len = 1,
  29. },
  30. {
  31. .rx_buf = hw->tb.rx_buf,
  32. .bits_per_word = 8,
  33. .len = len,
  34. }
  35. };
  36. hw->tb.tx_buf[0] = addr | SENSORS_SPI_READ;
  37. err = spi_sync_transfer(spi, xfers, ARRAY_SIZE(xfers));
  38. if (err < 0)
  39. return err;
  40. memcpy(data, hw->tb.rx_buf, len * sizeof(u8));
  41. return len;
  42. }
  43. static int st_lsm6dsx_spi_write(struct device *dev, u8 addr, int len,
  44. u8 *data)
  45. {
  46. struct st_lsm6dsx_hw *hw;
  47. struct spi_device *spi;
  48. if (len >= ST_LSM6DSX_TX_MAX_LENGTH)
  49. return -ENOMEM;
  50. spi = to_spi_device(dev);
  51. hw = spi_get_drvdata(spi);
  52. hw->tb.tx_buf[0] = addr;
  53. memcpy(&hw->tb.tx_buf[1], data, len);
  54. return spi_write(spi, hw->tb.tx_buf, len + 1);
  55. }
  56. static const struct st_lsm6dsx_transfer_function st_lsm6dsx_transfer_fn = {
  57. .read = st_lsm6dsx_spi_read,
  58. .write = st_lsm6dsx_spi_write,
  59. };
  60. static int st_lsm6dsx_spi_probe(struct spi_device *spi)
  61. {
  62. const struct spi_device_id *id = spi_get_device_id(spi);
  63. return st_lsm6dsx_probe(&spi->dev, spi->irq,
  64. (int)id->driver_data,
  65. &st_lsm6dsx_transfer_fn);
  66. }
  67. static const struct of_device_id st_lsm6dsx_spi_of_match[] = {
  68. {
  69. .compatible = "st,lsm6ds3",
  70. .data = (void *)ST_LSM6DS3_ID,
  71. },
  72. {
  73. .compatible = "st,lsm6dsm",
  74. .data = (void *)ST_LSM6DSM_ID,
  75. },
  76. {},
  77. };
  78. MODULE_DEVICE_TABLE(of, st_lsm6dsx_spi_of_match);
  79. static const struct spi_device_id st_lsm6dsx_spi_id_table[] = {
  80. { ST_LSM6DS3_DEV_NAME, ST_LSM6DS3_ID },
  81. { ST_LSM6DSM_DEV_NAME, ST_LSM6DSM_ID },
  82. {},
  83. };
  84. MODULE_DEVICE_TABLE(spi, st_lsm6dsx_spi_id_table);
  85. static struct spi_driver st_lsm6dsx_driver = {
  86. .driver = {
  87. .name = "st_lsm6dsx_spi",
  88. .of_match_table = of_match_ptr(st_lsm6dsx_spi_of_match),
  89. },
  90. .probe = st_lsm6dsx_spi_probe,
  91. .id_table = st_lsm6dsx_spi_id_table,
  92. };
  93. module_spi_driver(st_lsm6dsx_driver);
  94. MODULE_AUTHOR("Lorenzo Bianconi <lorenzo.bianconi@st.com>");
  95. MODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>");
  96. MODULE_DESCRIPTION("STMicroelectronics st_lsm6dsx spi driver");
  97. MODULE_LICENSE("GPL v2");