altera-a10sr.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Altera Arria10 DevKit System Resource MFD Driver
  4. *
  5. * Author: Thor Thayer <[email protected]>
  6. *
  7. * Copyright Intel Corporation (C) 2014-2016. All Rights Reserved
  8. *
  9. * SPI access for Altera Arria10 MAX5 System Resource Chip
  10. *
  11. * Adapted from DA9052
  12. */
  13. #include <linux/mfd/altera-a10sr.h>
  14. #include <linux/mfd/core.h>
  15. #include <linux/init.h>
  16. #include <linux/module.h>
  17. #include <linux/of.h>
  18. #include <linux/spi/spi.h>
  19. static const struct mfd_cell altr_a10sr_subdev_info[] = {
  20. {
  21. .name = "altr_a10sr_gpio",
  22. .of_compatible = "altr,a10sr-gpio",
  23. },
  24. {
  25. .name = "altr_a10sr_reset",
  26. .of_compatible = "altr,a10sr-reset",
  27. },
  28. };
  29. static bool altr_a10sr_reg_readable(struct device *dev, unsigned int reg)
  30. {
  31. switch (reg) {
  32. case ALTR_A10SR_VERSION_READ:
  33. case ALTR_A10SR_LED_REG:
  34. case ALTR_A10SR_PBDSW_REG:
  35. case ALTR_A10SR_PBDSW_IRQ_REG:
  36. case ALTR_A10SR_PWR_GOOD1_REG:
  37. case ALTR_A10SR_PWR_GOOD2_REG:
  38. case ALTR_A10SR_PWR_GOOD3_REG:
  39. case ALTR_A10SR_FMCAB_REG:
  40. case ALTR_A10SR_HPS_RST_REG:
  41. case ALTR_A10SR_USB_QSPI_REG:
  42. case ALTR_A10SR_SFPA_REG:
  43. case ALTR_A10SR_SFPB_REG:
  44. case ALTR_A10SR_I2C_M_REG:
  45. case ALTR_A10SR_WARM_RST_REG:
  46. case ALTR_A10SR_WR_KEY_REG:
  47. case ALTR_A10SR_PMBUS_REG:
  48. return true;
  49. default:
  50. return false;
  51. }
  52. }
  53. static bool altr_a10sr_reg_writeable(struct device *dev, unsigned int reg)
  54. {
  55. switch (reg) {
  56. case ALTR_A10SR_LED_REG:
  57. case ALTR_A10SR_PBDSW_IRQ_REG:
  58. case ALTR_A10SR_FMCAB_REG:
  59. case ALTR_A10SR_HPS_RST_REG:
  60. case ALTR_A10SR_USB_QSPI_REG:
  61. case ALTR_A10SR_SFPA_REG:
  62. case ALTR_A10SR_SFPB_REG:
  63. case ALTR_A10SR_WARM_RST_REG:
  64. case ALTR_A10SR_WR_KEY_REG:
  65. case ALTR_A10SR_PMBUS_REG:
  66. return true;
  67. default:
  68. return false;
  69. }
  70. }
  71. static bool altr_a10sr_reg_volatile(struct device *dev, unsigned int reg)
  72. {
  73. switch (reg) {
  74. case ALTR_A10SR_PBDSW_REG:
  75. case ALTR_A10SR_PBDSW_IRQ_REG:
  76. case ALTR_A10SR_PWR_GOOD1_REG:
  77. case ALTR_A10SR_PWR_GOOD2_REG:
  78. case ALTR_A10SR_PWR_GOOD3_REG:
  79. case ALTR_A10SR_HPS_RST_REG:
  80. case ALTR_A10SR_I2C_M_REG:
  81. case ALTR_A10SR_WARM_RST_REG:
  82. case ALTR_A10SR_WR_KEY_REG:
  83. case ALTR_A10SR_PMBUS_REG:
  84. return true;
  85. default:
  86. return false;
  87. }
  88. }
  89. static const struct regmap_config altr_a10sr_regmap_config = {
  90. .reg_bits = 8,
  91. .val_bits = 8,
  92. .cache_type = REGCACHE_NONE,
  93. .use_single_read = true,
  94. .use_single_write = true,
  95. .read_flag_mask = 1,
  96. .write_flag_mask = 0,
  97. .max_register = ALTR_A10SR_WR_KEY_REG,
  98. .readable_reg = altr_a10sr_reg_readable,
  99. .writeable_reg = altr_a10sr_reg_writeable,
  100. .volatile_reg = altr_a10sr_reg_volatile,
  101. };
  102. static int altr_a10sr_spi_probe(struct spi_device *spi)
  103. {
  104. int ret;
  105. struct altr_a10sr *a10sr;
  106. a10sr = devm_kzalloc(&spi->dev, sizeof(*a10sr),
  107. GFP_KERNEL);
  108. if (!a10sr)
  109. return -ENOMEM;
  110. spi->mode = SPI_MODE_3;
  111. spi->bits_per_word = 8;
  112. spi_setup(spi);
  113. a10sr->dev = &spi->dev;
  114. spi_set_drvdata(spi, a10sr);
  115. a10sr->regmap = devm_regmap_init_spi(spi, &altr_a10sr_regmap_config);
  116. if (IS_ERR(a10sr->regmap)) {
  117. ret = PTR_ERR(a10sr->regmap);
  118. dev_err(&spi->dev, "Failed to allocate register map: %d\n",
  119. ret);
  120. return ret;
  121. }
  122. ret = devm_mfd_add_devices(a10sr->dev, PLATFORM_DEVID_AUTO,
  123. altr_a10sr_subdev_info,
  124. ARRAY_SIZE(altr_a10sr_subdev_info),
  125. NULL, 0, NULL);
  126. if (ret)
  127. dev_err(a10sr->dev, "Failed to register sub-devices: %d\n",
  128. ret);
  129. return ret;
  130. }
  131. static const struct of_device_id altr_a10sr_spi_of_match[] = {
  132. { .compatible = "altr,a10sr" },
  133. { },
  134. };
  135. MODULE_DEVICE_TABLE(of, altr_a10sr_spi_of_match);
  136. static const struct spi_device_id altr_a10sr_spi_ids[] = {
  137. { .name = "a10sr" },
  138. { },
  139. };
  140. MODULE_DEVICE_TABLE(spi, altr_a10sr_spi_ids);
  141. static struct spi_driver altr_a10sr_spi_driver = {
  142. .probe = altr_a10sr_spi_probe,
  143. .driver = {
  144. .name = "altr_a10sr",
  145. .of_match_table = of_match_ptr(altr_a10sr_spi_of_match),
  146. },
  147. .id_table = altr_a10sr_spi_ids,
  148. };
  149. builtin_driver(altr_a10sr_spi_driver, spi_register_driver)