altera-a10sr.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. /*
  2. * Altera Arria10 DevKit System Resource MFD Driver
  3. *
  4. * Author: Thor Thayer <tthayer@opensource.altera.com>
  5. *
  6. * Copyright Intel Corporation (C) 2014-2016. All Rights Reserved
  7. *
  8. * This program is free software; you can redistribute it and/or modify it
  9. * under the terms and conditions of the GNU General Public License,
  10. * version 2, as published by the Free Software Foundation.
  11. *
  12. * This program is distributed in the hope it will be useful, but WITHOUT
  13. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  14. * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  15. * more details.
  16. *
  17. * You should have received a copy of the GNU General Public License along with
  18. * this program. If not, see <http://www.gnu.org/licenses/>.
  19. *
  20. * SPI access for Altera Arria10 MAX5 System Resource Chip
  21. *
  22. * Adapted from DA9052
  23. */
  24. #include <linux/mfd/altera-a10sr.h>
  25. #include <linux/mfd/core.h>
  26. #include <linux/init.h>
  27. #include <linux/of.h>
  28. #include <linux/spi/spi.h>
  29. static const struct mfd_cell altr_a10sr_subdev_info[] = {
  30. {
  31. .name = "altr_a10sr_gpio",
  32. .of_compatible = "altr,a10sr-gpio",
  33. },
  34. };
  35. static bool altr_a10sr_reg_readable(struct device *dev, unsigned int reg)
  36. {
  37. switch (reg) {
  38. case ALTR_A10SR_VERSION_READ:
  39. case ALTR_A10SR_LED_REG:
  40. case ALTR_A10SR_PBDSW_REG:
  41. case ALTR_A10SR_PBDSW_IRQ_REG:
  42. case ALTR_A10SR_PWR_GOOD1_REG:
  43. case ALTR_A10SR_PWR_GOOD2_REG:
  44. case ALTR_A10SR_PWR_GOOD3_REG:
  45. case ALTR_A10SR_FMCAB_REG:
  46. case ALTR_A10SR_HPS_RST_REG:
  47. case ALTR_A10SR_USB_QSPI_REG:
  48. case ALTR_A10SR_SFPA_REG:
  49. case ALTR_A10SR_SFPB_REG:
  50. case ALTR_A10SR_I2C_M_REG:
  51. case ALTR_A10SR_WARM_RST_REG:
  52. case ALTR_A10SR_WR_KEY_REG:
  53. case ALTR_A10SR_PMBUS_REG:
  54. return true;
  55. default:
  56. return false;
  57. }
  58. }
  59. static bool altr_a10sr_reg_writeable(struct device *dev, unsigned int reg)
  60. {
  61. switch (reg) {
  62. case ALTR_A10SR_LED_REG:
  63. case ALTR_A10SR_PBDSW_IRQ_REG:
  64. case ALTR_A10SR_FMCAB_REG:
  65. case ALTR_A10SR_HPS_RST_REG:
  66. case ALTR_A10SR_USB_QSPI_REG:
  67. case ALTR_A10SR_SFPA_REG:
  68. case ALTR_A10SR_SFPB_REG:
  69. case ALTR_A10SR_WARM_RST_REG:
  70. case ALTR_A10SR_WR_KEY_REG:
  71. case ALTR_A10SR_PMBUS_REG:
  72. return true;
  73. default:
  74. return false;
  75. }
  76. }
  77. static bool altr_a10sr_reg_volatile(struct device *dev, unsigned int reg)
  78. {
  79. switch (reg) {
  80. case ALTR_A10SR_PBDSW_REG:
  81. case ALTR_A10SR_PBDSW_IRQ_REG:
  82. case ALTR_A10SR_PWR_GOOD1_REG:
  83. case ALTR_A10SR_PWR_GOOD2_REG:
  84. case ALTR_A10SR_PWR_GOOD3_REG:
  85. case ALTR_A10SR_HPS_RST_REG:
  86. case ALTR_A10SR_I2C_M_REG:
  87. case ALTR_A10SR_WARM_RST_REG:
  88. case ALTR_A10SR_WR_KEY_REG:
  89. case ALTR_A10SR_PMBUS_REG:
  90. return true;
  91. default:
  92. return false;
  93. }
  94. }
  95. static const struct regmap_config altr_a10sr_regmap_config = {
  96. .reg_bits = 8,
  97. .val_bits = 8,
  98. .cache_type = REGCACHE_NONE,
  99. .use_single_rw = true,
  100. .read_flag_mask = 1,
  101. .write_flag_mask = 0,
  102. .max_register = ALTR_A10SR_WR_KEY_REG,
  103. .readable_reg = altr_a10sr_reg_readable,
  104. .writeable_reg = altr_a10sr_reg_writeable,
  105. .volatile_reg = altr_a10sr_reg_volatile,
  106. };
  107. static int altr_a10sr_spi_probe(struct spi_device *spi)
  108. {
  109. int ret;
  110. struct altr_a10sr *a10sr;
  111. a10sr = devm_kzalloc(&spi->dev, sizeof(*a10sr),
  112. GFP_KERNEL);
  113. if (!a10sr)
  114. return -ENOMEM;
  115. spi->mode = SPI_MODE_3;
  116. spi->bits_per_word = 8;
  117. spi_setup(spi);
  118. a10sr->dev = &spi->dev;
  119. spi_set_drvdata(spi, a10sr);
  120. a10sr->regmap = devm_regmap_init_spi(spi, &altr_a10sr_regmap_config);
  121. if (IS_ERR(a10sr->regmap)) {
  122. ret = PTR_ERR(a10sr->regmap);
  123. dev_err(&spi->dev, "Failed to allocate register map: %d\n",
  124. ret);
  125. return ret;
  126. }
  127. ret = devm_mfd_add_devices(a10sr->dev, PLATFORM_DEVID_AUTO,
  128. altr_a10sr_subdev_info,
  129. ARRAY_SIZE(altr_a10sr_subdev_info),
  130. NULL, 0, NULL);
  131. if (ret)
  132. dev_err(a10sr->dev, "Failed to register sub-devices: %d\n",
  133. ret);
  134. return ret;
  135. }
  136. static const struct of_device_id altr_a10sr_spi_of_match[] = {
  137. { .compatible = "altr,a10sr" },
  138. { },
  139. };
  140. static struct spi_driver altr_a10sr_spi_driver = {
  141. .probe = altr_a10sr_spi_probe,
  142. .driver = {
  143. .name = "altr_a10sr",
  144. .of_match_table = of_match_ptr(altr_a10sr_spi_of_match),
  145. },
  146. };
  147. builtin_driver(altr_a10sr_spi_driver, spi_register_driver)