serial_max3100.c 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342
  1. /*
  2. * (C) Copyright 2003
  3. *
  4. * Pantelis Antoniou <panto@intracom.gr>
  5. * Intracom S.A.
  6. *
  7. * See file CREDITS for list of people who contributed to this
  8. * project.
  9. *
  10. * This program is free software; you can redistribute it and/or
  11. * modify it under the terms of the GNU General Public License as
  12. * published by the Free Software Foundation; either version 2 of
  13. * the License, or (at your option) any later version.
  14. *
  15. * This program is distributed in the hope that it will be useful,
  16. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18. * GNU General Public License for more details.
  19. *
  20. * You should have received a copy of the GNU General Public License
  21. * along with this program; if not, write to the Free Software
  22. * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  23. * MA 02111-1307 USA
  24. */
  25. #include <common.h>
  26. #include <watchdog.h>
  27. #include <serial.h>
  28. #include <linux/compiler.h>
  29. DECLARE_GLOBAL_DATA_PTR;
  30. /**************************************************************/
  31. /* convienient macros */
  32. #define MAX3100_SPI_RXD() (MAX3100_SPI_RXD_PORT & MAX3100_SPI_RXD_BIT)
  33. #define MAX3100_SPI_TXD(x) \
  34. do { \
  35. if (x) \
  36. MAX3100_SPI_TXD_PORT |= MAX3100_SPI_TXD_BIT; \
  37. else \
  38. MAX3100_SPI_TXD_PORT &= ~MAX3100_SPI_TXD_BIT; \
  39. } while(0)
  40. #define MAX3100_SPI_CLK(x) \
  41. do { \
  42. if (x) \
  43. MAX3100_SPI_CLK_PORT |= MAX3100_SPI_CLK_BIT; \
  44. else \
  45. MAX3100_SPI_CLK_PORT &= ~MAX3100_SPI_CLK_BIT; \
  46. } while(0)
  47. #define MAX3100_SPI_CLK_TOGGLE() (MAX3100_SPI_CLK_PORT ^= MAX3100_SPI_CLK_BIT)
  48. #define MAX3100_CS(x) \
  49. do { \
  50. if (x) \
  51. MAX3100_CS_PORT |= MAX3100_CS_BIT; \
  52. else \
  53. MAX3100_CS_PORT &= ~MAX3100_CS_BIT; \
  54. } while(0)
  55. /**************************************************************/
  56. /* MAX3100 definitions */
  57. #define MAX3100_WC (3 << 14) /* write configuration */
  58. #define MAX3100_RC (1 << 14) /* read configuration */
  59. #define MAX3100_WD (2 << 14) /* write data */
  60. #define MAX3100_RD (0 << 14) /* read data */
  61. /* configuration register bits */
  62. #define MAX3100_FEN (1 << 13) /* FIFO enable */
  63. #define MAX3100_SHDN (1 << 12) /* shutdown bit */
  64. #define MAX3100_TM (1 << 11) /* T bit irq mask */
  65. #define MAX3100_RM (1 << 10) /* R bit irq mask */
  66. #define MAX3100_PM (1 << 9) /* P bit irq mask */
  67. #define MAX3100_RAM (1 << 8) /* mask for RA/FE bit */
  68. #define MAX3100_IR (1 << 7) /* IRDA timing mode */
  69. #define MAX3100_ST (1 << 6) /* transmit stop bit */
  70. #define MAX3100_PE (1 << 5) /* parity enable bit */
  71. #define MAX3100_L (1 << 4) /* Length bit */
  72. #define MAX3100_B_MASK (0x000F) /* baud rate bits mask */
  73. #define MAX3100_B(x) ((x) & 0x000F) /* baud rate select bits */
  74. /* data register bits (write) */
  75. #define MAX3100_TE (1 << 10) /* transmit enable bit (active low) */
  76. #define MAX3100_RTS (1 << 9) /* request-to-send bit (inverted ~RTS pin) */
  77. /* data register bits (read) */
  78. #define MAX3100_RA (1 << 10) /* receiver activity when in shutdown mode */
  79. #define MAX3100_FE (1 << 10) /* framing error when in normal mode */
  80. #define MAX3100_CTS (1 << 9) /* clear-to-send bit (inverted ~CTS pin) */
  81. /* data register bits (both directions) */
  82. #define MAX3100_R (1 << 15) /* receive bit */
  83. #define MAX3100_T (1 << 14) /* transmit bit */
  84. #define MAX3100_P (1 << 8) /* parity bit */
  85. #define MAX3100_D_MASK 0x00FF /* data bits mask */
  86. #define MAX3100_D(x) ((x) & 0x00FF) /* data bits */
  87. /* these definitions are valid only for fOSC = 3.6864MHz */
  88. #define MAX3100_B_230400 MAX3100_B(0)
  89. #define MAX3100_B_115200 MAX3100_B(1)
  90. #define MAX3100_B_57600 MAX3100_B(2)
  91. #define MAX3100_B_38400 MAX3100_B(9)
  92. #define MAX3100_B_19200 MAX3100_B(10)
  93. #define MAX3100_B_9600 MAX3100_B(11)
  94. #define MAX3100_B_4800 MAX3100_B(12)
  95. #define MAX3100_B_2400 MAX3100_B(13)
  96. #define MAX3100_B_1200 MAX3100_B(14)
  97. #define MAX3100_B_600 MAX3100_B(15)
  98. /**************************************************************/
  99. static inline unsigned int max3100_transfer(unsigned int val)
  100. {
  101. unsigned int rx;
  102. int b;
  103. MAX3100_SPI_CLK(0);
  104. MAX3100_CS(0);
  105. rx = 0; b = 16;
  106. while (--b >= 0) {
  107. MAX3100_SPI_TXD(val & 0x8000);
  108. val <<= 1;
  109. MAX3100_SPI_CLK_TOGGLE();
  110. udelay(1);
  111. rx <<= 1;
  112. if (MAX3100_SPI_RXD())
  113. rx |= 1;
  114. MAX3100_SPI_CLK_TOGGLE();
  115. udelay(1);
  116. }
  117. MAX3100_SPI_CLK(1);
  118. MAX3100_CS(1);
  119. return rx;
  120. }
  121. /**************************************************************/
  122. /* must be power of 2 */
  123. #define RXFIFO_SZ 16
  124. static int rxfifo_cnt;
  125. static int rxfifo_in;
  126. static int rxfifo_out;
  127. static unsigned char rxfifo_buf[16];
  128. static void max3100_serial_putc_raw(int c)
  129. {
  130. unsigned int rx;
  131. while (((rx = max3100_transfer(MAX3100_RC)) & MAX3100_T) == 0)
  132. WATCHDOG_RESET();
  133. rx = max3100_transfer(MAX3100_WD | (c & 0xff));
  134. if ((rx & MAX3100_RD) != 0 && rxfifo_cnt < RXFIFO_SZ) {
  135. rxfifo_cnt++;
  136. rxfifo_buf[rxfifo_in++] = rx & 0xff;
  137. rxfifo_in &= RXFIFO_SZ - 1;
  138. }
  139. }
  140. static int max3100_serial_getc(void)
  141. {
  142. int c;
  143. unsigned int rx;
  144. while (rxfifo_cnt == 0) {
  145. rx = max3100_transfer(MAX3100_RD);
  146. if ((rx & MAX3100_R) != 0) {
  147. do {
  148. rxfifo_cnt++;
  149. rxfifo_buf[rxfifo_in++] = rx & 0xff;
  150. rxfifo_in &= RXFIFO_SZ - 1;
  151. if (rxfifo_cnt >= RXFIFO_SZ)
  152. break;
  153. } while (((rx = max3100_transfer(MAX3100_RD)) & MAX3100_R) != 0);
  154. }
  155. WATCHDOG_RESET();
  156. }
  157. rxfifo_cnt--;
  158. c = rxfifo_buf[rxfifo_out++];
  159. rxfifo_out &= RXFIFO_SZ - 1;
  160. return c;
  161. }
  162. static int max3100_serial_tstc(void)
  163. {
  164. unsigned int rx;
  165. if (rxfifo_cnt > 0)
  166. return 1;
  167. rx = max3100_transfer(MAX3100_RD);
  168. if ((rx & MAX3100_R) == 0)
  169. return 0;
  170. do {
  171. rxfifo_cnt++;
  172. rxfifo_buf[rxfifo_in++] = rx & 0xff;
  173. rxfifo_in &= RXFIFO_SZ - 1;
  174. if (rxfifo_cnt >= RXFIFO_SZ)
  175. break;
  176. } while (((rx = max3100_transfer(MAX3100_RD)) & MAX3100_R) != 0);
  177. return 1;
  178. }
  179. static int max3100_serial_init(void)
  180. {
  181. unsigned int wconf, rconf;
  182. int i;
  183. wconf = 0;
  184. /* Set baud rate */
  185. switch (gd->baudrate) {
  186. case 1200:
  187. wconf = MAX3100_B_1200;
  188. break;
  189. case 2400:
  190. wconf = MAX3100_B_2400;
  191. break;
  192. case 4800:
  193. wconf = MAX3100_B_4800;
  194. break;
  195. case 9600:
  196. wconf = MAX3100_B_9600;
  197. break;
  198. case 19200:
  199. wconf = MAX3100_B_19200;
  200. break;
  201. case 38400:
  202. wconf = MAX3100_B_38400;
  203. break;
  204. case 57600:
  205. wconf = MAX3100_B_57600;
  206. break;
  207. default:
  208. case 115200:
  209. wconf = MAX3100_B_115200;
  210. break;
  211. case 230400:
  212. wconf = MAX3100_B_230400;
  213. break;
  214. }
  215. /* try for 10ms, with a 100us gap */
  216. for (i = 0; i < 10000; i += 100) {
  217. max3100_transfer(MAX3100_WC | wconf);
  218. rconf = max3100_transfer(MAX3100_RC) & 0x3fff;
  219. if (rconf == wconf)
  220. break;
  221. udelay(100);
  222. }
  223. rxfifo_in = rxfifo_out = rxfifo_cnt = 0;
  224. return (0);
  225. }
  226. static void max3100_serial_putc(const char c)
  227. {
  228. if (c == '\n')
  229. max3100_serial_putc_raw('\r');
  230. max3100_serial_putc_raw(c);
  231. }
  232. static void max3100_serial_puts(const char *s)
  233. {
  234. while (*s)
  235. max3100_serial_putc_raw(*s++);
  236. }
  237. static void max3100_serial_setbrg(void)
  238. {
  239. }
  240. #ifdef CONFIG_SERIAL_MULTI
  241. static struct serial_device max3100_serial_drv = {
  242. .name = "max3100_serial",
  243. .start = max3100_serial_init,
  244. .stop = NULL,
  245. .setbrg = max3100_serial_setbrg,
  246. .putc = max3100_serial_putc,
  247. .puts = max3100_serial_puts,
  248. .getc = max3100_serial_getc,
  249. .tstc = max3100_serial_tstc,
  250. };
  251. void max3100_serial_initialize(void)
  252. {
  253. serial_register(&max3100_serial_drv);
  254. }
  255. __weak struct serial_device *default_serial_console(void)
  256. {
  257. return &max3100_serial_drv;
  258. }
  259. #else
  260. int serial_init(void)
  261. {
  262. return max3100_serial_init();
  263. }
  264. void serial_setbrg(void)
  265. {
  266. max3100_serial_setbrg();
  267. }
  268. void serial_putc(const char c)
  269. {
  270. max3100_serial_putc(c);
  271. }
  272. void serial_puts(const char *s)
  273. {
  274. max3100_serial_puts(s);
  275. }
  276. int serial_getc(void)
  277. {
  278. return max3100_serial_getc();
  279. }
  280. int serial_tstc(void)
  281. {
  282. return max3100_serial_tstc();
  283. }
  284. #endif