spi-cns3xxx.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448
  1. /*******************************************************************************
  2. *
  3. * CNS3XXX SPI controller driver (master mode only)
  4. *
  5. * Copyright (c) 2008 Cavium Networks
  6. * Copyright 2011 Gateworks Corporation
  7. * Chris Lang <clang@gateworks.com>
  8. *
  9. * This file is free software; you can redistribute it and/or modify
  10. * it under the terms of the GNU General Public License, Version 2, as
  11. * published by the Free Software Foundation.
  12. *
  13. * This file is distributed in the hope that it will be useful,
  14. * but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
  16. * NONINFRINGEMENT. See the GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this file; if not, write to the Free Software
  20. * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or
  21. * visit http://www.gnu.org/licenses/.
  22. *
  23. * This file may also be available under a different license from Cavium.
  24. * Contact Cavium Networks for more information
  25. *
  26. ******************************************************************************/
  27. #include <linux/init.h>
  28. #include <linux/spinlock.h>
  29. #include <linux/workqueue.h>
  30. #include <linux/interrupt.h>
  31. #include <linux/delay.h>
  32. #include <linux/errno.h>
  33. #include <linux/err.h>
  34. #include <linux/clk.h>
  35. #include <linux/platform_device.h>
  36. #include <linux/spi/spi.h>
  37. #include <linux/spi/spi_bitbang.h>
  38. #include <linux/mtd/partitions.h>
  39. #include <linux/dma-mapping.h>
  40. #include <linux/slab.h>
  41. #include <asm/io.h>
  42. #include <asm/memory.h>
  43. #include <asm/dma.h>
  44. #include <asm/delay.h>
  45. #include <linux/module.h>
  46. /*
  47. * define access macros
  48. */
  49. #define SPI_MEM_MAP_VALUE(reg_offset) (*((u32 volatile *)(hw->base + reg_offset)))
  50. #define SPI_CONFIGURATION_REG SPI_MEM_MAP_VALUE(0x00)
  51. #define SPI_SERVICE_STATUS_REG SPI_MEM_MAP_VALUE(0x04)
  52. #define SPI_BIT_RATE_CONTROL_REG SPI_MEM_MAP_VALUE(0x08)
  53. #define SPI_TRANSMIT_CONTROL_REG SPI_MEM_MAP_VALUE(0x0C)
  54. #define SPI_TRANSMIT_BUFFER_REG SPI_MEM_MAP_VALUE(0x10)
  55. #define SPI_RECEIVE_CONTROL_REG SPI_MEM_MAP_VALUE(0x14)
  56. #define SPI_RECEIVE_BUFFER_REG SPI_MEM_MAP_VALUE(0x18)
  57. #define SPI_FIFO_TRANSMIT_CONFIG_REG SPI_MEM_MAP_VALUE(0x1C)
  58. #define SPI_FIFO_TRANSMIT_CONTROL_REG SPI_MEM_MAP_VALUE(0x20)
  59. #define SPI_FIFO_RECEIVE_CONFIG_REG SPI_MEM_MAP_VALUE(0x24)
  60. #define SPI_INTERRUPT_STATUS_REG SPI_MEM_MAP_VALUE(0x28)
  61. #define SPI_INTERRUPT_ENABLE_REG SPI_MEM_MAP_VALUE(0x2C)
  62. #define SPI_TRANSMIT_BUFFER_REG_ADDR (CNS3XXX_SSP_BASE +0x10)
  63. #define SPI_RECEIVE_BUFFER_REG_ADDR (CNS3XXX_SSP_BASE +0x18)
  64. /* Structure for SPI controller of CNS3XXX SOCs */
  65. struct cns3xxx_spi {
  66. /* bitbang has to be first */
  67. struct spi_bitbang bitbang;
  68. struct completion done;
  69. wait_queue_head_t wait;
  70. int len;
  71. int count;
  72. int last_in_message_list;
  73. /* data buffers */
  74. const unsigned char *tx;
  75. unsigned char *rx;
  76. void __iomem *base;
  77. struct spi_master *master;
  78. struct platform_device *pdev;
  79. struct device *dev;
  80. };
  81. static inline u8 cns3xxx_spi_bus_idle(struct cns3xxx_spi *hw)
  82. {
  83. return ((SPI_SERVICE_STATUS_REG & 0x1) ? 0 : 1);
  84. }
  85. static inline u8 cns3xxx_spi_tx_buffer_empty(struct cns3xxx_spi *hw)
  86. {
  87. return ((SPI_INTERRUPT_STATUS_REG & (0x1 << 3)) ? 1 : 0);
  88. }
  89. static inline u8 cns3xxx_spi_rx_buffer_full(struct cns3xxx_spi *hw)
  90. {
  91. return ((SPI_INTERRUPT_STATUS_REG & (0x1 << 2)) ? 1 : 0);
  92. }
  93. u8 cns3xxx_spi_tx_rx(struct cns3xxx_spi *hw, u8 tx_channel, u8 tx_eof,
  94. u32 tx_data, u32 * rx_data)
  95. {
  96. u8 rx_channel;
  97. u8 rx_eof;
  98. while (!cns3xxx_spi_bus_idle(hw)) ; // do nothing
  99. while (!cns3xxx_spi_tx_buffer_empty(hw)) ; // do nothing
  100. SPI_TRANSMIT_CONTROL_REG &= ~(0x7);
  101. SPI_TRANSMIT_CONTROL_REG |= (tx_channel & 0x3) | ((tx_eof & 0x1) << 2);
  102. SPI_TRANSMIT_BUFFER_REG = tx_data;
  103. while (!cns3xxx_spi_rx_buffer_full(hw)) ; // do nothing
  104. rx_channel = SPI_RECEIVE_CONTROL_REG & 0x3;
  105. rx_eof = (SPI_RECEIVE_CONTROL_REG & (0x1 << 2)) ? 1 : 0;
  106. *rx_data = SPI_RECEIVE_BUFFER_REG;
  107. if ((tx_channel != rx_channel) || (tx_eof != rx_eof)) {
  108. return 0;
  109. } else {
  110. return 1;
  111. }
  112. }
  113. u8 cns3xxx_spi_tx(struct cns3xxx_spi *hw, u8 tx_channel, u8 tx_eof, u32 tx_data)
  114. {
  115. while (!cns3xxx_spi_bus_idle(hw)) ; // do nothing
  116. while (!cns3xxx_spi_tx_buffer_empty(hw)) ; // do nothing
  117. SPI_TRANSMIT_CONTROL_REG &= ~(0x7);
  118. SPI_TRANSMIT_CONTROL_REG |= (tx_channel & 0x3) | ((tx_eof & 0x1) << 2);
  119. SPI_TRANSMIT_BUFFER_REG = tx_data;
  120. return 1;
  121. }
  122. static inline struct cns3xxx_spi *to_hw(struct spi_device *sdev)
  123. {
  124. return spi_master_get_devdata(sdev->master);
  125. }
  126. static int cns3xxx_spi_setup_transfer(struct spi_device *spi,
  127. struct spi_transfer *t)
  128. {
  129. return 0;
  130. }
  131. static void cns3xxx_spi_chipselect(struct spi_device *spi, int value)
  132. {
  133. struct cns3xxx_spi *hw = to_hw(spi);
  134. unsigned int spi_config;
  135. switch (value) {
  136. case BITBANG_CS_INACTIVE:
  137. break;
  138. case BITBANG_CS_ACTIVE:
  139. spi_config = SPI_CONFIGURATION_REG;
  140. if (spi->mode & SPI_CPHA)
  141. spi_config |= (0x1 << 13);
  142. else
  143. spi_config &= ~(0x1 << 13);
  144. if (spi->mode & SPI_CPOL)
  145. spi_config |= (0x1 << 14);
  146. else
  147. spi_config &= ~(0x1 << 14);
  148. /* write new configration */
  149. SPI_CONFIGURATION_REG = spi_config;
  150. SPI_TRANSMIT_CONTROL_REG &= ~(0x7);
  151. SPI_TRANSMIT_CONTROL_REG |= (spi->chip_select & 0x3);
  152. break;
  153. }
  154. }
  155. static int cns3xxx_spi_setup(struct spi_device *spi)
  156. {
  157. if (!spi->bits_per_word)
  158. spi->bits_per_word = 8;
  159. return 0;
  160. }
  161. static int cns3xxx_spi_txrx(struct spi_device *spi, struct spi_transfer *t)
  162. {
  163. struct cns3xxx_spi *hw = to_hw(spi);
  164. dev_dbg(&spi->dev, "txrx: tx %p, rx %p, len %d\n", t->tx_buf, t->rx_buf,
  165. t->len);
  166. hw->tx = t->tx_buf;
  167. hw->rx = t->rx_buf;
  168. hw->len = t->len;
  169. hw->count = 0;
  170. hw->last_in_message_list = t->last_in_message_list;
  171. init_completion(&hw->done);
  172. if (hw->tx) {
  173. int i;
  174. u32 rx_data;
  175. for (i = 0; i < (hw->len - 1); i++) {
  176. dev_dbg(&spi->dev,
  177. "[SPI_CNS3XXX_DEBUG] hw->tx[%02d]: 0x%02x\n", i,
  178. hw->tx[i]);
  179. cns3xxx_spi_tx_rx(hw, spi->chip_select, 0, hw->tx[i],
  180. &rx_data);
  181. if (hw->rx) {
  182. hw->rx[i] = rx_data;
  183. dev_dbg(&spi->dev,
  184. "[SPI_CNS3XXX_DEBUG] hw->rx[%02d]: 0x%02x\n",
  185. i, hw->rx[i]);
  186. }
  187. }
  188. if (t->last_in_message_list) {
  189. cns3xxx_spi_tx_rx(hw, spi->chip_select, 1, hw->tx[i],
  190. &rx_data);
  191. if (hw->rx) {
  192. hw->rx[i] = rx_data;
  193. dev_dbg(&spi->dev,
  194. "[SPI_CNS3XXX_DEBUG] hw->rx[%02d]: 0x%02x\n",
  195. i, hw->rx[i]);
  196. }
  197. } else {
  198. cns3xxx_spi_tx_rx(hw, spi->chip_select, 0, hw->tx[i],
  199. &rx_data);
  200. }
  201. goto done;
  202. }
  203. if (hw->rx) {
  204. int i;
  205. u32 rx_data;
  206. for (i = 0; i < (hw->len - 1); i++) {
  207. cns3xxx_spi_tx_rx(hw, spi->chip_select, 0, 0xff, &rx_data);
  208. hw->rx[i] = rx_data;
  209. dev_dbg(&spi->dev,
  210. "[SPI_CNS3XXX_DEBUG] hw->rx[%02d]: 0x%02x\n", i,
  211. hw->rx[i]);
  212. }
  213. if (t->last_in_message_list) {
  214. cns3xxx_spi_tx_rx(hw, spi->chip_select, 1, 0xff, &rx_data);
  215. } else {
  216. cns3xxx_spi_tx_rx(hw, spi->chip_select, 0, 0xff, &rx_data);
  217. }
  218. hw->rx[i] = rx_data;
  219. dev_dbg(&spi->dev, "[SPI_CNS3XXX_DEBUG] hw->rx[%02d]: 0x%02x\n",
  220. i, hw->rx[i]);
  221. }
  222. done:
  223. return hw->len;
  224. }
  225. static void __init cns3xxx_spi_initial(struct cns3xxx_spi *hw)
  226. {
  227. SPI_CONFIGURATION_REG = (((0x0 & 0x3) << 0) | /* 8bits shift length */
  228. (0x0 << 9) | /* SPI mode */
  229. (0x0 << 10) | /* disable FIFO */
  230. (0x1 << 11) | /* SPI master mode */
  231. (0x0 << 12) | /* disable SPI loopback mode */
  232. (0x1 << 13) | /* clock phase */
  233. (0x1 << 14) | /* clock polarity */
  234. (0x0 << 24) | /* disable - SPI data swap */
  235. (0x1 << 29) | /* enable - 2IO Read mode */
  236. (0x0 << 30) | /* disable - SPI high speed read for system boot up */
  237. (0x0 << 31)); /* disable - SPI */
  238. /* Set SPI bit rate PCLK/2 */
  239. SPI_BIT_RATE_CONTROL_REG = 0x1;
  240. /* Set SPI Tx channel 0 */
  241. SPI_TRANSMIT_CONTROL_REG = 0x0;
  242. /* Set Tx FIFO Threshold, Tx FIFO has 2 words */
  243. SPI_FIFO_TRANSMIT_CONFIG_REG &= ~(0x03 << 4);
  244. SPI_FIFO_TRANSMIT_CONFIG_REG |= ((0x0 & 0x03) << 4);
  245. /* Set Rx FIFO Threshold, Rx FIFO has 2 words */
  246. SPI_FIFO_RECEIVE_CONFIG_REG &= ~(0x03 << 4);
  247. SPI_FIFO_RECEIVE_CONFIG_REG |= ((0x0 & 0x03) << 4);
  248. /* Disable all interrupt */
  249. SPI_INTERRUPT_ENABLE_REG = 0x0;
  250. /* Clear spurious interrupt sources */
  251. SPI_INTERRUPT_STATUS_REG = (0x0F << 4);
  252. /* Enable SPI */
  253. SPI_CONFIGURATION_REG |= (0x1 << 31);
  254. return;
  255. }
  256. static int cns3xxx_spi_probe(struct platform_device *pdev)
  257. {
  258. struct spi_master *master;
  259. struct cns3xxx_spi *hw;
  260. struct resource *res;
  261. int err = 0;
  262. printk("%s: setup CNS3XXX SPI Controller\n", __FUNCTION__);
  263. res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  264. if (!res)
  265. return -ENODEV;
  266. /* Allocate master with space for cns3xxx_spi */
  267. master = spi_alloc_master(&pdev->dev, sizeof(struct cns3xxx_spi));
  268. if (master == NULL) {
  269. dev_err(&pdev->dev, "No memory for spi_master\n");
  270. err = -ENOMEM;
  271. goto err_nomem;
  272. }
  273. hw = spi_master_get_devdata(master);
  274. memset(hw, 0, sizeof(struct cns3xxx_spi));
  275. hw->master = spi_master_get(master);
  276. hw->dev = &pdev->dev;
  277. hw->base = devm_ioremap_resource(hw->dev, res);
  278. if (IS_ERR(hw->base)) {
  279. dev_err(hw->dev, "Unable to map registers\n");
  280. err = PTR_ERR(hw->base);
  281. goto err_register;
  282. }
  283. platform_set_drvdata(pdev, hw);
  284. init_completion(&hw->done);
  285. /* setup the master state. */
  286. master->num_chipselect = 4;
  287. master->bus_num = 1;
  288. /* setup the state for the bitbang driver */
  289. hw->bitbang.master = hw->master;
  290. hw->bitbang.setup_transfer = cns3xxx_spi_setup_transfer;
  291. hw->bitbang.chipselect = cns3xxx_spi_chipselect;
  292. hw->bitbang.txrx_bufs = cns3xxx_spi_txrx;
  293. hw->bitbang.master->setup = cns3xxx_spi_setup;
  294. dev_dbg(hw->dev, "bitbang at %p\n", &hw->bitbang);
  295. /* SPI controller initializations */
  296. cns3xxx_spi_initial(hw);
  297. /* register SPI controller */
  298. err = spi_bitbang_start(&hw->bitbang);
  299. if (err) {
  300. dev_err(&pdev->dev, "Failed to register SPI master\n");
  301. goto err_register;
  302. }
  303. return 0;
  304. err_register:
  305. spi_master_put(hw->master);;
  306. err_nomem:
  307. return err;
  308. }
  309. static int cns3xxx_spi_remove(struct platform_device *dev)
  310. {
  311. struct cns3xxx_spi *hw = platform_get_drvdata(dev);
  312. platform_set_drvdata(dev, NULL);
  313. spi_unregister_master(hw->master);
  314. spi_master_put(hw->master);
  315. return 0;
  316. }
  317. #ifdef CONFIG_PM
  318. static int cns3xxx_spi_suspend(struct platform_device *pdev, pm_message_t msg)
  319. {
  320. struct cns3xxx_spi *hw = platform_get_drvdata(pdev);
  321. return 0;
  322. }
  323. static int cns3xxx_spi_resume(struct platform_device *pdev)
  324. {
  325. struct cns3xxx_spi *hw = platform_get_drvdata(pdev);
  326. return 0;
  327. }
  328. #else
  329. #define cns3xxx_spi_suspend NULL
  330. #define cns3xxx_spi_resume NULL
  331. #endif
  332. static struct platform_driver cns3xxx_spi_driver = {
  333. .probe = cns3xxx_spi_probe,
  334. .remove = cns3xxx_spi_remove,
  335. .suspend = cns3xxx_spi_suspend,
  336. .resume = cns3xxx_spi_resume,
  337. .driver = {
  338. .name = "cns3xxx_spi",
  339. .owner = THIS_MODULE,
  340. },
  341. };
  342. static int __init cns3xxx_spi_init(void)
  343. {
  344. return platform_driver_register(&cns3xxx_spi_driver);
  345. }
  346. static void __exit cns3xxx_spi_exit(void)
  347. {
  348. platform_driver_unregister(&cns3xxx_spi_driver);
  349. }
  350. module_init(cns3xxx_spi_init);
  351. module_exit(cns3xxx_spi_exit);
  352. MODULE_AUTHOR("Cavium Networks");
  353. MODULE_DESCRIPTION("CNS3XXX SPI Controller Driver");
  354. MODULE_LICENSE("GPL");
  355. MODULE_ALIAS("platform:cns3xxx_spi");
  356. EXPORT_SYMBOL_GPL(cns3xxx_spi_tx_rx);