spi-altera.c 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Altera SPI driver
  4. *
  5. * Copyright (C) 2008 Thomas Chou <thomas@wytron.com.tw>
  6. *
  7. * Based on spi_s3c24xx.c, which is:
  8. * Copyright (c) 2006 Ben Dooks
  9. * Copyright (c) 2006 Simtec Electronics
  10. * Ben Dooks <ben@simtec.co.uk>
  11. */
  12. #include <linux/interrupt.h>
  13. #include <linux/errno.h>
  14. #include <linux/module.h>
  15. #include <linux/platform_device.h>
  16. #include <linux/spi/altera.h>
  17. #include <linux/spi/spi.h>
  18. #include <linux/io.h>
  19. #include <linux/of.h>
  20. #define DRV_NAME "spi_altera"
  21. #define ALTERA_SPI_RXDATA 0
  22. #define ALTERA_SPI_TXDATA 4
  23. #define ALTERA_SPI_STATUS 8
  24. #define ALTERA_SPI_CONTROL 12
  25. #define ALTERA_SPI_SLAVE_SEL 20
  26. #define ALTERA_SPI_STATUS_ROE_MSK 0x8
  27. #define ALTERA_SPI_STATUS_TOE_MSK 0x10
  28. #define ALTERA_SPI_STATUS_TMT_MSK 0x20
  29. #define ALTERA_SPI_STATUS_TRDY_MSK 0x40
  30. #define ALTERA_SPI_STATUS_RRDY_MSK 0x80
  31. #define ALTERA_SPI_STATUS_E_MSK 0x100
  32. #define ALTERA_SPI_CONTROL_IROE_MSK 0x8
  33. #define ALTERA_SPI_CONTROL_ITOE_MSK 0x10
  34. #define ALTERA_SPI_CONTROL_ITRDY_MSK 0x40
  35. #define ALTERA_SPI_CONTROL_IRRDY_MSK 0x80
  36. #define ALTERA_SPI_CONTROL_IE_MSK 0x100
  37. #define ALTERA_SPI_CONTROL_SSO_MSK 0x400
  38. #define ALTERA_SPI_MAX_CS 32
  39. enum altera_spi_type {
  40. ALTERA_SPI_TYPE_UNKNOWN,
  41. ALTERA_SPI_TYPE_SUBDEV,
  42. };
  43. struct altera_spi {
  44. int irq;
  45. int len;
  46. int count;
  47. int bytes_per_word;
  48. u32 imr;
  49. /* data buffers */
  50. const unsigned char *tx;
  51. unsigned char *rx;
  52. struct regmap *regmap;
  53. u32 regoff;
  54. struct device *dev;
  55. };
  56. static const struct regmap_config spi_altera_config = {
  57. .reg_bits = 32,
  58. .reg_stride = 4,
  59. .val_bits = 32,
  60. .fast_io = true,
  61. };
  62. static int altr_spi_writel(struct altera_spi *hw, unsigned int reg,
  63. unsigned int val)
  64. {
  65. int ret;
  66. ret = regmap_write(hw->regmap, hw->regoff + reg, val);
  67. if (ret)
  68. dev_err(hw->dev, "fail to write reg 0x%x val 0x%x: %d\n",
  69. reg, val, ret);
  70. return ret;
  71. }
  72. static int altr_spi_readl(struct altera_spi *hw, unsigned int reg,
  73. unsigned int *val)
  74. {
  75. int ret;
  76. ret = regmap_read(hw->regmap, hw->regoff + reg, val);
  77. if (ret)
  78. dev_err(hw->dev, "fail to read reg 0x%x: %d\n", reg, ret);
  79. return ret;
  80. }
  81. static inline struct altera_spi *altera_spi_to_hw(struct spi_device *sdev)
  82. {
  83. return spi_master_get_devdata(sdev->master);
  84. }
  85. static void altera_spi_set_cs(struct spi_device *spi, bool is_high)
  86. {
  87. struct altera_spi *hw = altera_spi_to_hw(spi);
  88. if (is_high) {
  89. hw->imr &= ~ALTERA_SPI_CONTROL_SSO_MSK;
  90. altr_spi_writel(hw, ALTERA_SPI_CONTROL, hw->imr);
  91. altr_spi_writel(hw, ALTERA_SPI_SLAVE_SEL, 0);
  92. } else {
  93. altr_spi_writel(hw, ALTERA_SPI_SLAVE_SEL,
  94. BIT(spi->chip_select));
  95. hw->imr |= ALTERA_SPI_CONTROL_SSO_MSK;
  96. altr_spi_writel(hw, ALTERA_SPI_CONTROL, hw->imr);
  97. }
  98. }
  99. static void altera_spi_tx_word(struct altera_spi *hw)
  100. {
  101. unsigned int txd = 0;
  102. if (hw->tx) {
  103. switch (hw->bytes_per_word) {
  104. case 1:
  105. txd = hw->tx[hw->count];
  106. break;
  107. case 2:
  108. txd = (hw->tx[hw->count * 2]
  109. | (hw->tx[hw->count * 2 + 1] << 8));
  110. break;
  111. case 4:
  112. txd = (hw->tx[hw->count * 4]
  113. | (hw->tx[hw->count * 4 + 1] << 8)
  114. | (hw->tx[hw->count * 4 + 2] << 16)
  115. | (hw->tx[hw->count * 4 + 3] << 24));
  116. break;
  117. }
  118. }
  119. altr_spi_writel(hw, ALTERA_SPI_TXDATA, txd);
  120. }
  121. static void altera_spi_rx_word(struct altera_spi *hw)
  122. {
  123. unsigned int rxd;
  124. altr_spi_readl(hw, ALTERA_SPI_RXDATA, &rxd);
  125. if (hw->rx) {
  126. switch (hw->bytes_per_word) {
  127. case 1:
  128. hw->rx[hw->count] = rxd;
  129. break;
  130. case 2:
  131. hw->rx[hw->count * 2] = rxd;
  132. hw->rx[hw->count * 2 + 1] = rxd >> 8;
  133. break;
  134. case 4:
  135. hw->rx[hw->count * 4] = rxd;
  136. hw->rx[hw->count * 4 + 1] = rxd >> 8;
  137. hw->rx[hw->count * 4 + 2] = rxd >> 16;
  138. hw->rx[hw->count * 4 + 3] = rxd >> 24;
  139. break;
  140. }
  141. }
  142. hw->count++;
  143. }
  144. static int altera_spi_txrx(struct spi_master *master,
  145. struct spi_device *spi, struct spi_transfer *t)
  146. {
  147. struct altera_spi *hw = spi_master_get_devdata(master);
  148. u32 val;
  149. hw->tx = t->tx_buf;
  150. hw->rx = t->rx_buf;
  151. hw->count = 0;
  152. hw->bytes_per_word = DIV_ROUND_UP(t->bits_per_word, 8);
  153. hw->len = t->len / hw->bytes_per_word;
  154. if (hw->irq >= 0) {
  155. /* enable receive interrupt */
  156. hw->imr |= ALTERA_SPI_CONTROL_IRRDY_MSK;
  157. altr_spi_writel(hw, ALTERA_SPI_CONTROL, hw->imr);
  158. /* send the first byte */
  159. altera_spi_tx_word(hw);
  160. return 1;
  161. }
  162. while (hw->count < hw->len) {
  163. altera_spi_tx_word(hw);
  164. for (;;) {
  165. altr_spi_readl(hw, ALTERA_SPI_STATUS, &val);
  166. if (val & ALTERA_SPI_STATUS_RRDY_MSK)
  167. break;
  168. cpu_relax();
  169. }
  170. altera_spi_rx_word(hw);
  171. }
  172. spi_finalize_current_transfer(master);
  173. return 0;
  174. }
  175. static irqreturn_t altera_spi_irq(int irq, void *dev)
  176. {
  177. struct spi_master *master = dev;
  178. struct altera_spi *hw = spi_master_get_devdata(master);
  179. altera_spi_rx_word(hw);
  180. if (hw->count < hw->len) {
  181. altera_spi_tx_word(hw);
  182. } else {
  183. /* disable receive interrupt */
  184. hw->imr &= ~ALTERA_SPI_CONTROL_IRRDY_MSK;
  185. altr_spi_writel(hw, ALTERA_SPI_CONTROL, hw->imr);
  186. spi_finalize_current_transfer(master);
  187. }
  188. return IRQ_HANDLED;
  189. }
  190. static int altera_spi_probe(struct platform_device *pdev)
  191. {
  192. const struct platform_device_id *platid = platform_get_device_id(pdev);
  193. struct altera_spi_platform_data *pdata = dev_get_platdata(&pdev->dev);
  194. enum altera_spi_type type = ALTERA_SPI_TYPE_UNKNOWN;
  195. struct altera_spi *hw;
  196. struct spi_master *master;
  197. int err = -ENODEV;
  198. u32 val;
  199. u16 i;
  200. master = spi_alloc_master(&pdev->dev, sizeof(struct altera_spi));
  201. if (!master)
  202. return err;
  203. /* setup the master state. */
  204. master->bus_num = pdev->id;
  205. if (pdata) {
  206. if (pdata->num_chipselect > ALTERA_SPI_MAX_CS) {
  207. dev_err(&pdev->dev,
  208. "Invalid number of chipselect: %hu\n",
  209. pdata->num_chipselect);
  210. err = -EINVAL;
  211. goto exit;
  212. }
  213. master->num_chipselect = pdata->num_chipselect;
  214. master->mode_bits = pdata->mode_bits;
  215. master->bits_per_word_mask = pdata->bits_per_word_mask;
  216. } else {
  217. master->num_chipselect = 16;
  218. master->mode_bits = SPI_CS_HIGH;
  219. master->bits_per_word_mask = SPI_BPW_RANGE_MASK(1, 16);
  220. }
  221. master->dev.of_node = pdev->dev.of_node;
  222. master->transfer_one = altera_spi_txrx;
  223. master->set_cs = altera_spi_set_cs;
  224. hw = spi_master_get_devdata(master);
  225. hw->dev = &pdev->dev;
  226. if (platid)
  227. type = platid->driver_data;
  228. /* find and map our resources */
  229. if (type == ALTERA_SPI_TYPE_SUBDEV) {
  230. struct resource *regoff;
  231. hw->regmap = dev_get_regmap(pdev->dev.parent, NULL);
  232. if (!hw->regmap) {
  233. dev_err(&pdev->dev, "get regmap failed\n");
  234. goto exit;
  235. }
  236. regoff = platform_get_resource(pdev, IORESOURCE_REG, 0);
  237. if (regoff)
  238. hw->regoff = regoff->start;
  239. } else {
  240. void __iomem *res;
  241. res = devm_platform_ioremap_resource(pdev, 0);
  242. if (IS_ERR(res)) {
  243. err = PTR_ERR(res);
  244. goto exit;
  245. }
  246. hw->regmap = devm_regmap_init_mmio(&pdev->dev, res,
  247. &spi_altera_config);
  248. if (IS_ERR(hw->regmap)) {
  249. dev_err(&pdev->dev, "regmap mmio init failed\n");
  250. err = PTR_ERR(hw->regmap);
  251. goto exit;
  252. }
  253. }
  254. /* program defaults into the registers */
  255. hw->imr = 0; /* disable spi interrupts */
  256. altr_spi_writel(hw, ALTERA_SPI_CONTROL, hw->imr);
  257. altr_spi_writel(hw, ALTERA_SPI_STATUS, 0); /* clear status reg */
  258. altr_spi_readl(hw, ALTERA_SPI_STATUS, &val);
  259. if (val & ALTERA_SPI_STATUS_RRDY_MSK)
  260. altr_spi_readl(hw, ALTERA_SPI_RXDATA, &val); /* flush rxdata */
  261. /* irq is optional */
  262. hw->irq = platform_get_irq(pdev, 0);
  263. if (hw->irq >= 0) {
  264. err = devm_request_irq(&pdev->dev, hw->irq, altera_spi_irq, 0,
  265. pdev->name, master);
  266. if (err)
  267. goto exit;
  268. }
  269. err = devm_spi_register_master(&pdev->dev, master);
  270. if (err)
  271. goto exit;
  272. if (pdata) {
  273. for (i = 0; i < pdata->num_devices; i++) {
  274. if (!spi_new_device(master, pdata->devices + i))
  275. dev_warn(&pdev->dev,
  276. "unable to create SPI device: %s\n",
  277. pdata->devices[i].modalias);
  278. }
  279. }
  280. dev_info(&pdev->dev, "regoff %u, irq %d\n", hw->regoff, hw->irq);
  281. return 0;
  282. exit:
  283. spi_master_put(master);
  284. return err;
  285. }
  286. #ifdef CONFIG_OF
  287. static const struct of_device_id altera_spi_match[] = {
  288. { .compatible = "ALTR,spi-1.0", },
  289. { .compatible = "altr,spi-1.0", },
  290. {},
  291. };
  292. MODULE_DEVICE_TABLE(of, altera_spi_match);
  293. #endif /* CONFIG_OF */
  294. static const struct platform_device_id altera_spi_ids[] = {
  295. { DRV_NAME, ALTERA_SPI_TYPE_UNKNOWN },
  296. { "subdev_spi_altera", ALTERA_SPI_TYPE_SUBDEV },
  297. { }
  298. };
  299. MODULE_DEVICE_TABLE(platform, altera_spi_ids);
  300. static struct platform_driver altera_spi_driver = {
  301. .probe = altera_spi_probe,
  302. .driver = {
  303. .name = DRV_NAME,
  304. .pm = NULL,
  305. .of_match_table = of_match_ptr(altera_spi_match),
  306. },
  307. .id_table = altera_spi_ids,
  308. };
  309. module_platform_driver(altera_spi_driver);
  310. MODULE_DESCRIPTION("Altera SPI driver");
  311. MODULE_AUTHOR("Thomas Chou <thomas@wytron.com.tw>");
  312. MODULE_LICENSE("GPL");
  313. MODULE_ALIAS("platform:" DRV_NAME);