ksz_spi.c 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * Microchip ksz series register access through SPI
  4. *
  5. * Copyright (C) 2017-2024 Microchip Technology Inc.
  6. * Tristram Ha <Tristram.Ha@microchip.com>
  7. */
  8. #include <linux/unaligned.h>
  9. #include <linux/delay.h>
  10. #include <linux/kernel.h>
  11. #include <linux/module.h>
  12. #include <linux/regmap.h>
  13. #include <linux/spi/spi.h>
  14. #include "ksz_common.h"
  15. #define KSZ8795_SPI_ADDR_SHIFT 12
  16. #define KSZ8795_SPI_ADDR_ALIGN 3
  17. #define KSZ8795_SPI_TURNAROUND_SHIFT 1
  18. #define KSZ8863_SPI_ADDR_SHIFT 8
  19. #define KSZ8863_SPI_ADDR_ALIGN 8
  20. #define KSZ8863_SPI_TURNAROUND_SHIFT 0
  21. #define KSZ9477_SPI_ADDR_SHIFT 24
  22. #define KSZ9477_SPI_ADDR_ALIGN 3
  23. #define KSZ9477_SPI_TURNAROUND_SHIFT 5
  24. KSZ_REGMAP_TABLE(ksz8795, 16, KSZ8795_SPI_ADDR_SHIFT,
  25. KSZ8795_SPI_TURNAROUND_SHIFT, KSZ8795_SPI_ADDR_ALIGN);
  26. KSZ_REGMAP_TABLE(ksz8863, 16, KSZ8863_SPI_ADDR_SHIFT,
  27. KSZ8863_SPI_TURNAROUND_SHIFT, KSZ8863_SPI_ADDR_ALIGN);
  28. KSZ_REGMAP_TABLE(ksz9477, 32, KSZ9477_SPI_ADDR_SHIFT,
  29. KSZ9477_SPI_TURNAROUND_SHIFT, KSZ9477_SPI_ADDR_ALIGN);
  30. static int ksz_spi_probe(struct spi_device *spi)
  31. {
  32. const struct regmap_config *regmap_config;
  33. const struct ksz_chip_data *chip;
  34. struct device *ddev = &spi->dev;
  35. struct regmap_config rc;
  36. struct ksz_device *dev;
  37. int i, ret = 0;
  38. dev = ksz_switch_alloc(&spi->dev, spi);
  39. if (!dev)
  40. return -ENOMEM;
  41. chip = device_get_match_data(ddev);
  42. if (!chip)
  43. return -EINVAL;
  44. if (chip->chip_id == KSZ88X3_CHIP_ID)
  45. regmap_config = ksz8863_regmap_config;
  46. else if (chip->chip_id == KSZ8795_CHIP_ID ||
  47. chip->chip_id == KSZ8794_CHIP_ID ||
  48. chip->chip_id == KSZ8765_CHIP_ID)
  49. regmap_config = ksz8795_regmap_config;
  50. else if (chip->chip_id == KSZ8895_CHIP_ID ||
  51. chip->chip_id == KSZ8864_CHIP_ID)
  52. regmap_config = ksz8863_regmap_config;
  53. else
  54. regmap_config = ksz9477_regmap_config;
  55. for (i = 0; i < __KSZ_NUM_REGMAPS; i++) {
  56. rc = regmap_config[i];
  57. rc.lock_arg = &dev->regmap_mutex;
  58. rc.wr_table = chip->wr_table;
  59. rc.rd_table = chip->rd_table;
  60. dev->regmap[i] = devm_regmap_init_spi(spi, &rc);
  61. if (IS_ERR(dev->regmap[i])) {
  62. return dev_err_probe(&spi->dev, PTR_ERR(dev->regmap[i]),
  63. "Failed to initialize regmap%i\n",
  64. regmap_config[i].val_bits);
  65. }
  66. }
  67. if (spi->dev.platform_data)
  68. dev->pdata = spi->dev.platform_data;
  69. /* setup spi */
  70. spi->mode = SPI_MODE_3;
  71. ret = spi_setup(spi);
  72. if (ret)
  73. return ret;
  74. dev->irq = spi->irq;
  75. ret = ksz_switch_register(dev);
  76. /* Main DSA driver may not be started yet. */
  77. if (ret)
  78. return ret;
  79. spi_set_drvdata(spi, dev);
  80. return 0;
  81. }
  82. static void ksz_spi_remove(struct spi_device *spi)
  83. {
  84. struct ksz_device *dev = spi_get_drvdata(spi);
  85. if (dev)
  86. ksz_switch_remove(dev);
  87. }
  88. static void ksz_spi_shutdown(struct spi_device *spi)
  89. {
  90. struct ksz_device *dev = spi_get_drvdata(spi);
  91. if (!dev)
  92. return;
  93. ksz_switch_shutdown(dev);
  94. spi_set_drvdata(spi, NULL);
  95. }
  96. static const struct of_device_id ksz_dt_ids[] = {
  97. {
  98. .compatible = "microchip,ksz8765",
  99. .data = &ksz_switch_chips[KSZ8765]
  100. },
  101. {
  102. .compatible = "microchip,ksz8794",
  103. .data = &ksz_switch_chips[KSZ8794]
  104. },
  105. {
  106. .compatible = "microchip,ksz8795",
  107. .data = &ksz_switch_chips[KSZ8795]
  108. },
  109. {
  110. .compatible = "microchip,ksz8863",
  111. .data = &ksz_switch_chips[KSZ88X3]
  112. },
  113. {
  114. .compatible = "microchip,ksz8864",
  115. .data = &ksz_switch_chips[KSZ8864]
  116. },
  117. {
  118. .compatible = "microchip,ksz8873",
  119. .data = &ksz_switch_chips[KSZ88X3]
  120. },
  121. {
  122. .compatible = "microchip,ksz8895",
  123. .data = &ksz_switch_chips[KSZ8895]
  124. },
  125. {
  126. .compatible = "microchip,ksz9477",
  127. .data = &ksz_switch_chips[KSZ9477]
  128. },
  129. {
  130. .compatible = "microchip,ksz9896",
  131. .data = &ksz_switch_chips[KSZ9896]
  132. },
  133. {
  134. .compatible = "microchip,ksz9897",
  135. .data = &ksz_switch_chips[KSZ9897]
  136. },
  137. {
  138. .compatible = "microchip,ksz9893",
  139. .data = &ksz_switch_chips[KSZ9893]
  140. },
  141. {
  142. .compatible = "microchip,ksz9563",
  143. .data = &ksz_switch_chips[KSZ9563]
  144. },
  145. {
  146. .compatible = "microchip,ksz8563",
  147. .data = &ksz_switch_chips[KSZ8563]
  148. },
  149. {
  150. .compatible = "microchip,ksz8567",
  151. .data = &ksz_switch_chips[KSZ8567]
  152. },
  153. {
  154. .compatible = "microchip,ksz9567",
  155. .data = &ksz_switch_chips[KSZ9567]
  156. },
  157. {
  158. .compatible = "microchip,lan9370",
  159. .data = &ksz_switch_chips[LAN9370]
  160. },
  161. {
  162. .compatible = "microchip,lan9371",
  163. .data = &ksz_switch_chips[LAN9371]
  164. },
  165. {
  166. .compatible = "microchip,lan9372",
  167. .data = &ksz_switch_chips[LAN9372]
  168. },
  169. {
  170. .compatible = "microchip,lan9373",
  171. .data = &ksz_switch_chips[LAN9373]
  172. },
  173. {
  174. .compatible = "microchip,lan9374",
  175. .data = &ksz_switch_chips[LAN9374]
  176. },
  177. {},
  178. };
  179. MODULE_DEVICE_TABLE(of, ksz_dt_ids);
  180. static const struct spi_device_id ksz_spi_ids[] = {
  181. { "ksz8765" },
  182. { "ksz8794" },
  183. { "ksz8795" },
  184. { "ksz8863" },
  185. { "ksz8864" },
  186. { "ksz8873" },
  187. { "ksz8895" },
  188. { "ksz9477" },
  189. { "ksz9896" },
  190. { "ksz9897" },
  191. { "ksz9893" },
  192. { "ksz9563" },
  193. { "ksz8563" },
  194. { "ksz8567" },
  195. { "ksz9567" },
  196. { "lan9370" },
  197. { "lan9371" },
  198. { "lan9372" },
  199. { "lan9373" },
  200. { "lan9374" },
  201. { },
  202. };
  203. MODULE_DEVICE_TABLE(spi, ksz_spi_ids);
  204. static struct spi_driver ksz_spi_driver = {
  205. .driver = {
  206. .name = "ksz-switch",
  207. .of_match_table = ksz_dt_ids,
  208. },
  209. .id_table = ksz_spi_ids,
  210. .probe = ksz_spi_probe,
  211. .remove = ksz_spi_remove,
  212. .shutdown = ksz_spi_shutdown,
  213. };
  214. module_spi_driver(ksz_spi_driver);
  215. MODULE_ALIAS("spi:lan937x");
  216. MODULE_AUTHOR("Tristram Ha <Tristram.Ha@microchip.com>");
  217. MODULE_DESCRIPTION("Microchip ksz Series Switch SPI Driver");
  218. MODULE_LICENSE("GPL");