adxl313_spi.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * ADXL313 3-Axis Digital Accelerometer
  4. *
  5. * Copyright (c) 2021 Lucas Stankus <[email protected]>
  6. *
  7. * Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/ADXL313.pdf
  8. */
  9. #include <linux/mod_devicetable.h>
  10. #include <linux/module.h>
  11. #include <linux/regmap.h>
  12. #include <linux/spi/spi.h>
  13. #include <linux/property.h>
  14. #include "adxl313.h"
  15. static const struct regmap_config adxl31x_spi_regmap_config[] = {
  16. [ADXL312] = {
  17. .reg_bits = 8,
  18. .val_bits = 8,
  19. .rd_table = &adxl312_readable_regs_table,
  20. .wr_table = &adxl312_writable_regs_table,
  21. .max_register = 0x39,
  22. /* Setting bits 7 and 6 enables multiple-byte read */
  23. .read_flag_mask = BIT(7) | BIT(6),
  24. },
  25. [ADXL313] = {
  26. .reg_bits = 8,
  27. .val_bits = 8,
  28. .rd_table = &adxl313_readable_regs_table,
  29. .wr_table = &adxl313_writable_regs_table,
  30. .max_register = 0x39,
  31. /* Setting bits 7 and 6 enables multiple-byte read */
  32. .read_flag_mask = BIT(7) | BIT(6),
  33. },
  34. [ADXL314] = {
  35. .reg_bits = 8,
  36. .val_bits = 8,
  37. .rd_table = &adxl314_readable_regs_table,
  38. .wr_table = &adxl314_writable_regs_table,
  39. .max_register = 0x39,
  40. /* Setting bits 7 and 6 enables multiple-byte read */
  41. .read_flag_mask = BIT(7) | BIT(6),
  42. },
  43. };
  44. static int adxl313_spi_setup(struct device *dev, struct regmap *regmap)
  45. {
  46. struct spi_device *spi = container_of(dev, struct spi_device, dev);
  47. int ret;
  48. if (spi->mode & SPI_3WIRE) {
  49. ret = regmap_write(regmap, ADXL313_REG_DATA_FORMAT,
  50. ADXL313_SPI_3WIRE);
  51. if (ret)
  52. return ret;
  53. }
  54. return regmap_update_bits(regmap, ADXL313_REG_POWER_CTL,
  55. ADXL313_I2C_DISABLE, ADXL313_I2C_DISABLE);
  56. }
  57. static int adxl313_spi_probe(struct spi_device *spi)
  58. {
  59. const struct adxl313_chip_info *chip_data;
  60. struct regmap *regmap;
  61. int ret;
  62. spi->mode |= SPI_MODE_3;
  63. ret = spi_setup(spi);
  64. if (ret)
  65. return ret;
  66. /*
  67. * Retrieves device specific data as a pointer to a
  68. * adxl313_chip_info structure
  69. */
  70. chip_data = device_get_match_data(&spi->dev);
  71. if (!chip_data)
  72. chip_data = (const struct adxl313_chip_info *)spi_get_device_id(spi)->driver_data;
  73. regmap = devm_regmap_init_spi(spi,
  74. &adxl31x_spi_regmap_config[chip_data->type]);
  75. if (IS_ERR(regmap)) {
  76. dev_err(&spi->dev, "Error initializing spi regmap: %ld\n",
  77. PTR_ERR(regmap));
  78. return PTR_ERR(regmap);
  79. }
  80. return adxl313_core_probe(&spi->dev, regmap,
  81. chip_data, &adxl313_spi_setup);
  82. }
  83. static const struct spi_device_id adxl313_spi_id[] = {
  84. { .name = "adxl312", .driver_data = (kernel_ulong_t)&adxl31x_chip_info[ADXL312] },
  85. { .name = "adxl313", .driver_data = (kernel_ulong_t)&adxl31x_chip_info[ADXL313] },
  86. { .name = "adxl314", .driver_data = (kernel_ulong_t)&adxl31x_chip_info[ADXL314] },
  87. { }
  88. };
  89. MODULE_DEVICE_TABLE(spi, adxl313_spi_id);
  90. static const struct of_device_id adxl313_of_match[] = {
  91. { .compatible = "adi,adxl312", .data = &adxl31x_chip_info[ADXL312] },
  92. { .compatible = "adi,adxl313", .data = &adxl31x_chip_info[ADXL313] },
  93. { .compatible = "adi,adxl314", .data = &adxl31x_chip_info[ADXL314] },
  94. { }
  95. };
  96. MODULE_DEVICE_TABLE(of, adxl313_of_match);
  97. static struct spi_driver adxl313_spi_driver = {
  98. .driver = {
  99. .name = "adxl313_spi",
  100. .of_match_table = adxl313_of_match,
  101. },
  102. .probe = adxl313_spi_probe,
  103. .id_table = adxl313_spi_id,
  104. };
  105. module_spi_driver(adxl313_spi_driver);
  106. MODULE_AUTHOR("Lucas Stankus <[email protected]>");
  107. MODULE_DESCRIPTION("ADXL313 3-Axis Digital Accelerometer SPI driver");
  108. MODULE_LICENSE("GPL v2");
  109. MODULE_IMPORT_NS(IIO_ADXL313);