omap3_spi.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440
  1. /*
  2. * Copyright (C) 2010 Dirk Behme <dirk.behme@googlemail.com>
  3. *
  4. * Driver for McSPI controller on OMAP3. Based on davinci_spi.c
  5. * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/
  6. *
  7. * Copyright (C) 2007 Atmel Corporation
  8. *
  9. * Parts taken from linux/drivers/spi/omap2_mcspi.c
  10. * Copyright (C) 2005, 2006 Nokia Corporation
  11. *
  12. * Modified by Ruslan Araslanov <ruslan.araslanov@vitecmm.com>
  13. *
  14. * See file CREDITS for list of people who contributed to this
  15. * project.
  16. *
  17. * This program is free software; you can redistribute it and/or
  18. * modify it under the terms of the GNU General Public License as
  19. * published by the Free Software Foundation; either version 2 of
  20. * the License, or (at your option) any later version.
  21. *
  22. * This program is distributed in the hope that it will be useful,
  23. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  24. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  25. * GNU General Public License for more details.
  26. *
  27. * You should have received a copy of the GNU General Public License
  28. * along with this program; if not, write to the Free Software
  29. * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  30. * MA 02111-1307 USA
  31. *
  32. */
  33. #include <common.h>
  34. #include <spi.h>
  35. #include <malloc.h>
  36. #include <asm/io.h>
  37. #include "omap3_spi.h"
  38. #define WORD_LEN 8
  39. #define SPI_WAIT_TIMEOUT 3000000;
  40. static void spi_reset(struct omap3_spi_slave *ds)
  41. {
  42. unsigned int tmp;
  43. writel(OMAP3_MCSPI_SYSCONFIG_SOFTRESET, &ds->regs->sysconfig);
  44. do {
  45. tmp = readl(&ds->regs->sysstatus);
  46. } while (!(tmp & OMAP3_MCSPI_SYSSTATUS_RESETDONE));
  47. writel(OMAP3_MCSPI_SYSCONFIG_AUTOIDLE |
  48. OMAP3_MCSPI_SYSCONFIG_ENAWAKEUP |
  49. OMAP3_MCSPI_SYSCONFIG_SMARTIDLE,
  50. &ds->regs->sysconfig);
  51. writel(OMAP3_MCSPI_WAKEUPENABLE_WKEN, &ds->regs->wakeupenable);
  52. }
  53. static void omap3_spi_write_chconf(struct omap3_spi_slave *ds, int val)
  54. {
  55. writel(val, &ds->regs->channel[ds->slave.cs].chconf);
  56. /* Flash post writes to make immediate effect */
  57. readl(&ds->regs->channel[ds->slave.cs].chconf);
  58. }
  59. static void omap3_spi_set_enable(struct omap3_spi_slave *ds, int enable)
  60. {
  61. writel(enable, &ds->regs->channel[ds->slave.cs].chctrl);
  62. /* Flash post writes to make immediate effect */
  63. readl(&ds->regs->channel[ds->slave.cs].chctrl);
  64. }
  65. void spi_init()
  66. {
  67. /* do nothing */
  68. }
  69. struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
  70. unsigned int max_hz, unsigned int mode)
  71. {
  72. struct omap3_spi_slave *ds;
  73. struct mcspi *regs;
  74. /*
  75. * OMAP3 McSPI (MultiChannel SPI) has 4 busses (modules)
  76. * with different number of chip selects (CS, channels):
  77. * McSPI1 has 4 CS (bus 0, cs 0 - 3)
  78. * McSPI2 has 2 CS (bus 1, cs 0 - 1)
  79. * McSPI3 has 2 CS (bus 2, cs 0 - 1)
  80. * McSPI4 has 1 CS (bus 3, cs 0)
  81. */
  82. switch (bus) {
  83. case 0:
  84. regs = (struct mcspi *)OMAP3_MCSPI1_BASE;
  85. break;
  86. #ifdef OMAP3_MCSPI2_BASE
  87. case 1:
  88. regs = (struct mcspi *)OMAP3_MCSPI2_BASE;
  89. break;
  90. #endif
  91. #ifdef OMAP3_MCSPI3_BASE
  92. case 2:
  93. regs = (struct mcspi *)OMAP3_MCSPI3_BASE;
  94. break;
  95. #endif
  96. #ifdef OMAP3_MCSPI4_BASE
  97. case 3:
  98. regs = (struct mcspi *)OMAP3_MCSPI4_BASE;
  99. break;
  100. #endif
  101. default:
  102. printf("SPI error: unsupported bus %i. \
  103. Supported busses 0 - 3\n", bus);
  104. return NULL;
  105. }
  106. if (((bus == 0) && (cs > 3)) ||
  107. ((bus == 1) && (cs > 1)) ||
  108. ((bus == 2) && (cs > 1)) ||
  109. ((bus == 3) && (cs > 0))) {
  110. printf("SPI error: unsupported chip select %i \
  111. on bus %i\n", cs, bus);
  112. return NULL;
  113. }
  114. if (max_hz > OMAP3_MCSPI_MAX_FREQ) {
  115. printf("SPI error: unsupported frequency %i Hz. \
  116. Max frequency is 48 Mhz\n", max_hz);
  117. return NULL;
  118. }
  119. if (mode > SPI_MODE_3) {
  120. printf("SPI error: unsupported SPI mode %i\n", mode);
  121. return NULL;
  122. }
  123. ds = spi_alloc_slave(struct omap3_spi_slave, bus, cs);
  124. if (!ds) {
  125. printf("SPI error: malloc of SPI structure failed\n");
  126. return NULL;
  127. }
  128. ds->regs = regs;
  129. ds->freq = max_hz;
  130. ds->mode = mode;
  131. return &ds->slave;
  132. }
  133. void spi_free_slave(struct spi_slave *slave)
  134. {
  135. struct omap3_spi_slave *ds = to_omap3_spi(slave);
  136. free(ds);
  137. }
  138. int spi_claim_bus(struct spi_slave *slave)
  139. {
  140. struct omap3_spi_slave *ds = to_omap3_spi(slave);
  141. unsigned int conf, div = 0;
  142. /* McSPI global module configuration */
  143. /*
  144. * setup when switching from (reset default) slave mode
  145. * to single-channel master mode
  146. */
  147. spi_reset(ds);
  148. conf = readl(&ds->regs->modulctrl);
  149. conf &= ~(OMAP3_MCSPI_MODULCTRL_STEST | OMAP3_MCSPI_MODULCTRL_MS);
  150. conf |= OMAP3_MCSPI_MODULCTRL_SINGLE;
  151. writel(conf, &ds->regs->modulctrl);
  152. /* McSPI individual channel configuration */
  153. /* Calculate clock divisor. Valid range: 0x0 - 0xC ( /1 - /4096 ) */
  154. if (ds->freq) {
  155. while (div <= 0xC && (OMAP3_MCSPI_MAX_FREQ / (1 << div))
  156. > ds->freq)
  157. div++;
  158. } else
  159. div = 0xC;
  160. conf = readl(&ds->regs->channel[ds->slave.cs].chconf);
  161. /* standard 4-wire master mode: SCK, MOSI/out, MISO/in, nCS
  162. * REVISIT: this controller could support SPI_3WIRE mode.
  163. */
  164. #ifdef CONFIG_OMAP3_SPI_D0_D1_SWAPPED
  165. /*
  166. * Some boards have D0 wired as MOSI / D1 as MISO instead of
  167. * The normal D0 as MISO / D1 as MOSI.
  168. */
  169. conf &= ~OMAP3_MCSPI_CHCONF_DPE0;
  170. conf |= OMAP3_MCSPI_CHCONF_IS|OMAP3_MCSPI_CHCONF_DPE1;
  171. #else
  172. conf &= ~(OMAP3_MCSPI_CHCONF_IS|OMAP3_MCSPI_CHCONF_DPE1);
  173. conf |= OMAP3_MCSPI_CHCONF_DPE0;
  174. #endif
  175. /* wordlength */
  176. conf &= ~OMAP3_MCSPI_CHCONF_WL_MASK;
  177. conf |= (WORD_LEN - 1) << 7;
  178. /* set chipselect polarity; manage with FORCE */
  179. if (!(ds->mode & SPI_CS_HIGH))
  180. conf |= OMAP3_MCSPI_CHCONF_EPOL; /* active-low; normal */
  181. else
  182. conf &= ~OMAP3_MCSPI_CHCONF_EPOL;
  183. /* set clock divisor */
  184. conf &= ~OMAP3_MCSPI_CHCONF_CLKD_MASK;
  185. conf |= div << 2;
  186. /* set SPI mode 0..3 */
  187. if (ds->mode & SPI_CPOL)
  188. conf |= OMAP3_MCSPI_CHCONF_POL;
  189. else
  190. conf &= ~OMAP3_MCSPI_CHCONF_POL;
  191. if (ds->mode & SPI_CPHA)
  192. conf |= OMAP3_MCSPI_CHCONF_PHA;
  193. else
  194. conf &= ~OMAP3_MCSPI_CHCONF_PHA;
  195. /* Transmit & receive mode */
  196. conf &= ~OMAP3_MCSPI_CHCONF_TRM_MASK;
  197. omap3_spi_write_chconf(ds,conf);
  198. return 0;
  199. }
  200. void spi_release_bus(struct spi_slave *slave)
  201. {
  202. struct omap3_spi_slave *ds = to_omap3_spi(slave);
  203. /* Reset the SPI hardware */
  204. spi_reset(ds);
  205. }
  206. int omap3_spi_write(struct spi_slave *slave, unsigned int len, const u8 *txp,
  207. unsigned long flags)
  208. {
  209. struct omap3_spi_slave *ds = to_omap3_spi(slave);
  210. int i;
  211. int timeout = SPI_WAIT_TIMEOUT;
  212. int chconf = readl(&ds->regs->channel[ds->slave.cs].chconf);
  213. /* Enable the channel */
  214. omap3_spi_set_enable(ds,OMAP3_MCSPI_CHCTRL_EN);
  215. chconf &= ~OMAP3_MCSPI_CHCONF_TRM_MASK;
  216. chconf |= OMAP3_MCSPI_CHCONF_TRM_TX_ONLY;
  217. chconf |= OMAP3_MCSPI_CHCONF_FORCE;
  218. omap3_spi_write_chconf(ds,chconf);
  219. for (i = 0; i < len; i++) {
  220. /* wait till TX register is empty (TXS == 1) */
  221. while (!(readl(&ds->regs->channel[ds->slave.cs].chstat) &
  222. OMAP3_MCSPI_CHSTAT_TXS)) {
  223. if (--timeout <= 0) {
  224. printf("SPI TXS timed out, status=0x%08x\n",
  225. readl(&ds->regs->channel[ds->slave.cs].chstat));
  226. return -1;
  227. }
  228. }
  229. /* Write the data */
  230. writel(txp[i], &ds->regs->channel[ds->slave.cs].tx);
  231. }
  232. /* wait to finish of transfer */
  233. while (!(readl(&ds->regs->channel[ds->slave.cs].chstat) &
  234. OMAP3_MCSPI_CHSTAT_EOT));
  235. /* Disable the channel otherwise the next immediate RX will get affected */
  236. omap3_spi_set_enable(ds,OMAP3_MCSPI_CHCTRL_DIS);
  237. if (flags & SPI_XFER_END) {
  238. chconf &= ~OMAP3_MCSPI_CHCONF_FORCE;
  239. omap3_spi_write_chconf(ds,chconf);
  240. }
  241. return 0;
  242. }
  243. int omap3_spi_read(struct spi_slave *slave, unsigned int len, u8 *rxp,
  244. unsigned long flags)
  245. {
  246. struct omap3_spi_slave *ds = to_omap3_spi(slave);
  247. int i;
  248. int timeout = SPI_WAIT_TIMEOUT;
  249. int chconf = readl(&ds->regs->channel[ds->slave.cs].chconf);
  250. /* Enable the channel */
  251. omap3_spi_set_enable(ds,OMAP3_MCSPI_CHCTRL_EN);
  252. chconf &= ~OMAP3_MCSPI_CHCONF_TRM_MASK;
  253. chconf |= OMAP3_MCSPI_CHCONF_TRM_RX_ONLY;
  254. chconf |= OMAP3_MCSPI_CHCONF_FORCE;
  255. omap3_spi_write_chconf(ds,chconf);
  256. writel(0, &ds->regs->channel[ds->slave.cs].tx);
  257. for (i = 0; i < len; i++) {
  258. /* Wait till RX register contains data (RXS == 1) */
  259. while (!(readl(&ds->regs->channel[ds->slave.cs].chstat) &
  260. OMAP3_MCSPI_CHSTAT_RXS)) {
  261. if (--timeout <= 0) {
  262. printf("SPI RXS timed out, status=0x%08x\n",
  263. readl(&ds->regs->channel[ds->slave.cs].chstat));
  264. return -1;
  265. }
  266. }
  267. /* Disable the channel to prevent furher receiving */
  268. if(i == (len - 1))
  269. omap3_spi_set_enable(ds,OMAP3_MCSPI_CHCTRL_DIS);
  270. /* Read the data */
  271. rxp[i] = readl(&ds->regs->channel[ds->slave.cs].rx);
  272. }
  273. if (flags & SPI_XFER_END) {
  274. chconf &= ~OMAP3_MCSPI_CHCONF_FORCE;
  275. omap3_spi_write_chconf(ds,chconf);
  276. }
  277. return 0;
  278. }
  279. /*McSPI Transmit Receive Mode*/
  280. int omap3_spi_txrx(struct spi_slave *slave,
  281. unsigned int len, const u8 *txp, u8 *rxp, unsigned long flags)
  282. {
  283. struct omap3_spi_slave *ds = to_omap3_spi(slave);
  284. int timeout = SPI_WAIT_TIMEOUT;
  285. int chconf = readl(&ds->regs->channel[ds->slave.cs].chconf);
  286. int irqstatus = readl(&ds->regs->irqstatus);
  287. int i=0;
  288. /*Enable SPI channel*/
  289. omap3_spi_set_enable(ds,OMAP3_MCSPI_CHCTRL_EN);
  290. /*set TRANSMIT-RECEIVE Mode*/
  291. chconf &= ~OMAP3_MCSPI_CHCONF_TRM_MASK;
  292. chconf |= OMAP3_MCSPI_CHCONF_FORCE;
  293. omap3_spi_write_chconf(ds,chconf);
  294. /*Shift in and out 1 byte at time*/
  295. for (i=0; i < len; i++){
  296. /* Write: wait for TX empty (TXS == 1)*/
  297. irqstatus |= (1<< (4*(ds->slave.bus)));
  298. while (!(readl(&ds->regs->channel[ds->slave.cs].chstat) &
  299. OMAP3_MCSPI_CHSTAT_TXS)) {
  300. if (--timeout <= 0) {
  301. printf("SPI TXS timed out, status=0x%08x\n",
  302. readl(&ds->regs->channel[ds->slave.cs].chstat));
  303. return -1;
  304. }
  305. }
  306. /* Write the data */
  307. writel(txp[i], &ds->regs->channel[ds->slave.cs].tx);
  308. /*Read: wait for RX containing data (RXS == 1)*/
  309. while (!(readl(&ds->regs->channel[ds->slave.cs].chstat) &
  310. OMAP3_MCSPI_CHSTAT_RXS)) {
  311. if (--timeout <= 0) {
  312. printf("SPI RXS timed out, status=0x%08x\n",
  313. readl(&ds->regs->channel[ds->slave.cs].chstat));
  314. return -1;
  315. }
  316. }
  317. /* Read the data */
  318. rxp[i] = readl(&ds->regs->channel[ds->slave.cs].rx);
  319. }
  320. /* Disable the channel */
  321. omap3_spi_set_enable(ds,OMAP3_MCSPI_CHCTRL_DIS);
  322. /*if transfer must be terminated disable the channel*/
  323. if (flags & SPI_XFER_END) {
  324. chconf &= ~OMAP3_MCSPI_CHCONF_FORCE;
  325. omap3_spi_write_chconf(ds,chconf);
  326. }
  327. return 0;
  328. }
  329. int spi_xfer(struct spi_slave *slave, unsigned int bitlen,
  330. const void *dout, void *din, unsigned long flags)
  331. {
  332. struct omap3_spi_slave *ds = to_omap3_spi(slave);
  333. unsigned int len;
  334. const u8 *txp = dout;
  335. u8 *rxp = din;
  336. int ret = -1;
  337. if (bitlen % 8)
  338. return -1;
  339. len = bitlen / 8;
  340. if (bitlen == 0) { /* only change CS */
  341. int chconf = readl(&ds->regs->channel[ds->slave.cs].chconf);
  342. if (flags & SPI_XFER_BEGIN) {
  343. omap3_spi_set_enable(ds,OMAP3_MCSPI_CHCTRL_EN);
  344. chconf |= OMAP3_MCSPI_CHCONF_FORCE;
  345. omap3_spi_write_chconf(ds,chconf);
  346. }
  347. if (flags & SPI_XFER_END) {
  348. chconf &= ~OMAP3_MCSPI_CHCONF_FORCE;
  349. omap3_spi_write_chconf(ds,chconf);
  350. omap3_spi_set_enable(ds,OMAP3_MCSPI_CHCTRL_DIS);
  351. }
  352. ret = 0;
  353. } else {
  354. if (dout != NULL && din != NULL)
  355. ret = omap3_spi_txrx(slave, len, txp, rxp, flags);
  356. else if (dout != NULL)
  357. ret = omap3_spi_write(slave, len, txp, flags);
  358. else if (din != NULL)
  359. ret = omap3_spi_read(slave, len, rxp, flags);
  360. }
  361. return ret;
  362. }
  363. int spi_cs_is_valid(unsigned int bus, unsigned int cs)
  364. {
  365. return 1;
  366. }
  367. void spi_cs_activate(struct spi_slave *slave)
  368. {
  369. }
  370. void spi_cs_deactivate(struct spi_slave *slave)
  371. {
  372. }