improve spi_uart.c for bt
[firefly-linux-kernel-4.4.55.git] / drivers / fpga / spi_uart.c
1 #include <linux/module.h>\r
2 #include <linux/init.h>\r
3 #include <linux/kernel.h>\r
4 #include <linux/mutex.h>\r
5 #include <linux/seq_file.h>\r
6 #include <linux/serial_reg.h>\r
7 #include <linux/circ_buf.h>\r
8 #include <linux/gfp.h>\r
9 #include <linux/tty.h>\r
10 #include <linux/tty_flip.h>\r
11 #include <linux/interrupt.h>\r
12 #include <linux/platform_device.h>\r
13 #include <linux/spi/spi.h>\r
14 #include <linux/delay.h>\r
15 #include <linux/module.h>\r
16 #include <linux/ioport.h>\r
17 #include <linux/console.h>\r
18 #include <linux/sysrq.h>\r
19 #include <mach/gpio.h>\r
20 #include <mach/iomux.h>\r
21 #include <asm/io.h>\r
22 #include <asm/irq.h>\r
23 #include <linux/miscdevice.h>\r
24 #include <linux/poll.h>\r
25 #include <linux/sched.h>\r
26 #include <linux/kthread.h>\r
27 #include <linux/jiffies.h>\r
28 #include <linux/i2c.h>\r
29 #include <mach/rk2818_iomap.h>\r
30 \r
31 #include <mach/spi_fpga.h>\r
32 \r
33 #if defined(CONFIG_SPI_UART_DEBUG)\r
34 #define DBG(x...)   printk(x)\r
35 #else\r
36 #define DBG(x...)\r
37 #endif\r
38 \r
39 #define SPI_UART_TEST 0\r
40 int gBaud = 0;\r
41 #define SPI_UART_FIFO_LEN       32\r
42 #define SPI_UART_TXRX_BUF       1               //send or recieve several bytes one time\r
43 \r
44 static struct tty_driver *spi_uart_tty_driver;\r
45 /*------------------------ÒÔÏÂÊÇspi2uart±äÁ¿-----------------------*/\r
46 \r
47 #define UART_NR         1       /* Number of UARTs this driver can handle */\r
48 \r
49 #define UART_XMIT_SIZE  PAGE_SIZE\r
50 #define WAKEUP_CHARS    1024\r
51 \r
52 #define circ_empty(circ)        ((circ)->head == (circ)->tail)\r
53 #define circ_clear(circ)        ((circ)->head = (circ)->tail = 0)\r
54 \r
55 #define circ_chars_pending(circ) \\r
56                 (CIRC_CNT((circ)->head, (circ)->tail, UART_XMIT_SIZE))\r
57 \r
58 #define circ_chars_free(circ) \\r
59                 (CIRC_SPACE((circ)->head, (circ)->tail, UART_XMIT_SIZE))\r
60 \r
61 \r
62 \r
63 \r
64 static struct spi_uart *spi_uart_table[UART_NR];\r
65 static DEFINE_SPINLOCK(spi_uart_table_lock);\r
66 \r
67 #if SPI_UART_TXRX_BUF\r
68 static int spi_uart_write_buf(struct spi_uart *uart, unsigned char *buf, int len)\r
69 {\r
70         struct spi_fpga_port *port = container_of(uart, struct spi_fpga_port, uart);\r
71         int index = port->uart.index;\r
72         int reg = 0, stat = 0;\r
73         int i;\r
74         unsigned char tx_buf[SPI_UART_FIFO_LEN+2];\r
75         \r
76         memcpy(tx_buf + 2, buf, len);\r
77         reg = ((((reg) | ICE_SEL_UART) & ICE_SEL_WRITE) | ICE_SEL_UART_CH(index));\r
78         tx_buf[0] = reg & 0xff;\r
79         tx_buf[1] = 0;\r
80 \r
81         stat = spi_write(port->spi, tx_buf, len+2);\r
82         if(stat)\r
83         printk("%s:spi_write err!!!\n\n\n",__FUNCTION__);                       \r
84         DBG("%s:reg=0x%x,buf=0x%x,len=0x%x\n",__FUNCTION__,reg&0xff,(int)tx_buf,len);\r
85         return 0;\r
86 }\r
87 \r
88 \r
89 static int spi_uart_read_buf(struct spi_uart *uart, unsigned char *buf, int len)\r
90 {\r
91         struct spi_fpga_port *port = container_of(uart, struct spi_fpga_port, uart);\r
92         int index = port->uart.index;\r
93         int reg = 0,stat = 0;\r
94         unsigned char tx_buf[2],rx_buf[SPI_UART_FIFO_LEN+1];\r
95         \r
96         reg = (((reg) | ICE_SEL_UART) | ICE_SEL_READ | ICE_SEL_UART_CH(index));\r
97         tx_buf[0] = reg & 0xff;\r
98         tx_buf[1] = len;\r
99         //give fpga 8 clks for reading data\r
100         stat = spi_write_then_read(port->spi, tx_buf, sizeof(tx_buf), rx_buf, len+1);   \r
101         if(stat)\r
102         {\r
103                 printk("%s:spi_write_then_read is error!,err=%d\n\n",__FUNCTION__,stat);\r
104                 return -1;\r
105         }\r
106         \r
107         memcpy(buf, rx_buf+1, len);\r
108         DBG("%s:reg=0x%x,buf=0x%x,len=0x%x\n",__FUNCTION__,reg&0xff,(int)buf,len);\r
109         return stat;\r
110 }\r
111 \r
112 #endif\r
113 \r
114 static int spi_uart_add_port(struct spi_uart *uart)\r
115 {\r
116         int index, ret = -EBUSY;\r
117 \r
118         kref_init(&uart->kref);\r
119         mutex_init(&uart->open_lock);\r
120         spin_lock_init(&uart->write_lock);\r
121         spin_lock_init(&uart->irq_lock);\r
122         \r
123         spin_lock(&spi_uart_table_lock);\r
124         for (index = 0; index < UART_NR; index++) \r
125         {\r
126                 if (!spi_uart_table[index]) {\r
127                         uart->index = index;\r
128                         //printk("index=%d\n\n",index);\r
129                         spi_uart_table[index] = uart;\r
130                         ret = 0;\r
131                         break;\r
132                 }\r
133         }\r
134         spin_unlock(&spi_uart_table_lock);\r
135 \r
136         return ret;\r
137 }\r
138 \r
139 static struct spi_uart *spi_uart_port_get(unsigned index)\r
140 {\r
141         struct spi_uart *uart;\r
142 \r
143         if (index >= UART_NR)\r
144                 return NULL;\r
145 \r
146         spin_lock(&spi_uart_table_lock);\r
147         uart = spi_uart_table[index];\r
148         uart->index = index;\r
149         printk("uart->index=%d\n",uart->index);\r
150         if (uart)\r
151                 kref_get(&uart->kref);\r
152         spin_unlock(&spi_uart_table_lock);\r
153 \r
154         return uart;\r
155 }\r
156 \r
157 static void spi_uart_port_destroy(struct kref *kref)\r
158 {\r
159         struct spi_uart *uart =\r
160                 container_of(kref, struct spi_uart, kref);\r
161         kfree(uart);\r
162 }\r
163 \r
164 static void spi_uart_port_put(struct spi_uart *uart)\r
165 {\r
166         kref_put(&uart->kref, spi_uart_port_destroy);\r
167 }\r
168 \r
169 static void spi_uart_port_remove(struct spi_uart *uart)\r
170 {\r
171         struct spi_device *spi;\r
172         struct spi_fpga_port *port = container_of(uart, struct spi_fpga_port, uart);\r
173         \r
174         BUG_ON(spi_uart_table[uart->index] != uart);\r
175 \r
176         spin_lock(&spi_uart_table_lock);\r
177         spi_uart_table[uart->index] = NULL;\r
178         spin_unlock(&spi_uart_table_lock);\r
179 \r
180         /*\r
181          * We're killing a port that potentially still is in use by\r
182          * the tty layer. Be careful to arrange for the tty layer to\r
183          * give up on that port ASAP.\r
184          * Beware: the lock ordering is critical.\r
185          */\r
186         mutex_lock(&uart->open_lock);\r
187         mutex_lock(&port->spi_lock);\r
188         spi = port->spi;\r
189 \r
190         port->spi = NULL;\r
191         mutex_unlock(&port->spi_lock);\r
192         if (uart->opened)\r
193                 tty_hangup(uart->tty);\r
194         mutex_unlock(&uart->open_lock);\r
195 \r
196         spi_uart_port_put(uart);\r
197 }\r
198 \r
199 static unsigned int spi_uart_get_mctrl(struct spi_uart *uart)\r
200 {\r
201         unsigned char status;\r
202         unsigned int ret;\r
203         struct spi_fpga_port *port = container_of(uart, struct spi_fpga_port, uart);\r
204         \r
205         status = spi_in(port, UART_MSR, SEL_UART);//\r
206         ret = 0;\r
207 #if 0\r
208         if (status & UART_MSR_DCD)\r
209                 ret |= TIOCM_CAR;\r
210         if (status & UART_MSR_RI)\r
211                 ret |= TIOCM_RNG;\r
212         if (status & UART_MSR_DSR)\r
213                 ret |= TIOCM_DSR;       \r
214         if (status & UART_MSR_CTS)\r
215                 ret |= TIOCM_CTS;\r
216 #endif\r
217         if (status & UART_MSR_CTS)\r
218                 ret = TIOCM_CAR | TIOCM_DSR | TIOCM_CTS;\r
219         DBG("%s:LINE=%d,ret=0x%x\n",__FUNCTION__,__LINE__,ret);\r
220         return ret;\r
221 }\r
222 \r
223 static void spi_uart_write_mctrl(struct spi_uart *uart, unsigned int mctrl)\r
224 {\r
225         unsigned char mcr = 0;\r
226         struct spi_fpga_port *port = container_of(uart, struct spi_fpga_port, uart);\r
227 #if 1\r
228         if (mctrl & TIOCM_RTS)\r
229         {\r
230                 mcr |= UART_MCR_RTS;\r
231                 mcr |= UART_MCR_AFE;\r
232         }\r
233         //if (mctrl & TIOCM_DTR)\r
234         //      mcr |= UART_MCR_DTR;\r
235         //if (mctrl & TIOCM_OUT1)\r
236         //      mcr |= UART_MCR_OUT1;\r
237         //if (mctrl & TIOCM_OUT2)\r
238         //      mcr |= UART_MCR_OUT2;\r
239         //if (mctrl & TIOCM_LOOP)\r
240         //      mcr |= UART_MCR_LOOP;\r
241         \r
242 #endif\r
243         \r
244         DBG("%s:LINE=%d,mcr=0x%x\n",__FUNCTION__,__LINE__,mcr);\r
245         spi_out(port, UART_MCR, mcr, SEL_UART);\r
246 }\r
247 \r
248 static inline void spi_uart_update_mctrl(struct spi_uart *uart,\r
249                                           unsigned int set, unsigned int clear)\r
250 {\r
251         unsigned int old;\r
252         DBG("%s:LINE=%d\n",__FUNCTION__,__LINE__);\r
253         old = uart->mctrl;\r
254         uart->mctrl = (old & ~clear) | set;\r
255         if (old != uart->mctrl)\r
256                 spi_uart_write_mctrl(uart, uart->mctrl);\r
257 }\r
258 \r
259 #define spi_uart_set_mctrl(uart, x)     spi_uart_update_mctrl(uart, x, 0)\r
260 #define spi_uart_clear_mctrl(uart, x)   spi_uart_update_mctrl(uart, 0, x)\r
261 \r
262 static void spi_uart_change_speed(struct spi_uart *uart,\r
263                                    struct ktermios *termios,\r
264                                    struct ktermios *old)\r
265 {\r
266         unsigned char cval, fcr = 0;\r
267         unsigned int baud, quot;\r
268         struct spi_fpga_port *port = container_of(uart, struct spi_fpga_port, uart);\r
269         \r
270         switch (termios->c_cflag & CSIZE) {\r
271         case CS5:\r
272                 cval = UART_LCR_WLEN5;\r
273                 break;\r
274         case CS6:\r
275                 cval = UART_LCR_WLEN6;\r
276                 break;\r
277         case CS7:\r
278                 cval = UART_LCR_WLEN7;\r
279                 break;\r
280         default:\r
281         case CS8:\r
282                 cval = UART_LCR_WLEN8;\r
283                 break;\r
284         }\r
285 \r
286         if (termios->c_cflag & CSTOPB)\r
287                 cval |= UART_LCR_STOP;\r
288         if (termios->c_cflag & PARENB)\r
289                 cval |= UART_LCR_PARITY;\r
290         if (!(termios->c_cflag & PARODD))\r
291                 cval |= UART_LCR_EPAR;\r
292 \r
293         for (;;) {\r
294                 baud = tty_termios_baud_rate(termios);\r
295                 if (baud == 0)\r
296                         baud = 115200;  /* Special case: B0 rate. */\r
297                 if (baud <= uart->uartclk)\r
298                         break;\r
299                 /*\r
300                  * Oops, the quotient was zero.  Try again with the old\r
301                  * baud rate if possible, otherwise default to 115200.\r
302                  */\r
303                 termios->c_cflag &= ~CBAUD;\r
304                 if (old) {\r
305                         termios->c_cflag |= old->c_cflag & CBAUD;\r
306                         old = NULL;\r
307                 } else\r
308                         termios->c_cflag |= B115200;\r
309         }\r
310         //quot = (2 * uart->uartclk + baud) / (2 * baud);\r
311         quot = (uart->uartclk / baud);\r
312         //gBaud = baud;\r
313         printk("baud=%d,quot=0x%x\n",baud,quot);\r
314         if (baud < 2400)\r
315                 fcr = UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_1;\r
316         else\r
317                 fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10;\r
318 \r
319         uart->read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR;\r
320         if (termios->c_iflag & INPCK)\r
321                 uart->read_status_mask |= UART_LSR_FE | UART_LSR_PE;\r
322         if (termios->c_iflag & (BRKINT | PARMRK))\r
323                 uart->read_status_mask |= UART_LSR_BI;\r
324 \r
325         /*\r
326          * Characters to ignore\r
327          */\r
328         uart->ignore_status_mask = 0;\r
329         if (termios->c_iflag & IGNPAR)\r
330                 uart->ignore_status_mask |= UART_LSR_PE | UART_LSR_FE;\r
331         if (termios->c_iflag & IGNBRK) {\r
332                 uart->ignore_status_mask |= UART_LSR_BI;\r
333                 /*\r
334                  * If we're ignoring parity and break indicators,\r
335                  * ignore overruns too (for real raw support).\r
336                  */\r
337                 if (termios->c_iflag & IGNPAR)\r
338                         uart->ignore_status_mask |= UART_LSR_OE;\r
339         }\r
340 \r
341         /*\r
342          * ignore all characters if CREAD is not set\r
343          */\r
344         if ((termios->c_cflag & CREAD) == 0)\r
345                 uart->ignore_status_mask |= UART_LSR_DR;\r
346 \r
347         /*\r
348          * CTS flow control flag and modem status interrupts\r
349          */\r
350         uart->ier &= ~UART_IER_MSI;\r
351         if ((termios->c_cflag & CRTSCTS) || !(termios->c_cflag & CLOCAL))\r
352                 uart->ier |= UART_IER_MSI;\r
353 \r
354         uart->lcr = cval;\r
355         \r
356         spi_out(port, UART_LCR, cval | UART_LCR_DLAB, SEL_UART);\r
357         spi_out(port, UART_DLL, quot & 0xff, SEL_UART);\r
358         spi_out(port, UART_DLM, quot >> 8, SEL_UART);\r
359         spi_out(port, UART_LCR, cval, SEL_UART);\r
360         spi_out(port, UART_FCR, fcr, SEL_UART);\r
361         spi_out(port, UART_IER, uart->ier, SEL_UART);//slow\r
362 \r
363         DBG("%s:LINE=%d,baud=%d,uart->ier=0x%x,cval=0x%x,fcr=0x%x,quot=0x%x\n",\r
364                 __FUNCTION__,__LINE__,baud,uart->ier,cval,fcr,quot);\r
365         spi_uart_write_mctrl(uart, uart->mctrl);\r
366 }\r
367 \r
368 static void spi_uart_start_tx(struct spi_uart *uart)\r
369 {\r
370         struct spi_fpga_port *port = container_of(uart, struct spi_fpga_port, uart);\r
371         if (!(uart->ier & UART_IER_THRI)) {\r
372                 uart->ier |= UART_IER_THRI;\r
373                 spi_out(port, UART_IER, uart->ier, SEL_UART);\r
374                 printk("t,");\r
375         }       \r
376         \r
377         DBG("%s:UART_IER=0x%x\n",__FUNCTION__,uart->ier);\r
378 \r
379 }\r
380 \r
381 static void spi_uart_stop_tx(struct spi_uart *uart)\r
382 {\r
383         struct spi_fpga_port *port = container_of(uart, struct spi_fpga_port, uart);\r
384         if (uart->ier & UART_IER_THRI) {\r
385                 uart->ier &= ~UART_IER_THRI;\r
386                 spi_out(port, UART_IER, uart->ier, SEL_UART);\r
387         }\r
388         DBG("%s:UART_IER=0x%x\n",__FUNCTION__,uart->ier);\r
389 }\r
390 \r
391 static void spi_uart_stop_rx(struct spi_uart *uart)\r
392 {\r
393         struct spi_fpga_port *port = container_of(uart, struct spi_fpga_port, uart);\r
394         uart->ier &= ~UART_IER_RLSI;\r
395         uart->read_status_mask &= ~UART_LSR_DR;\r
396         spi_out(port, UART_IER, uart->ier, SEL_UART);\r
397 }\r
398 \r
399 static void spi_uart_receive_chars(struct spi_uart *uart, unsigned int *status)\r
400 {\r
401         struct tty_struct *tty = uart->tty;\r
402         struct spi_fpga_port *port = container_of(uart, struct spi_fpga_port, uart);\r
403         unsigned int ch, flag;\r
404         int max_count = 1024;\r
405         //printk("rx:");\r
406 #if SPI_UART_TXRX_BUF\r
407         int ret,count,stat = 0,num = 0;\r
408         int i;\r
409         unsigned char buf[SPI_UART_FIFO_LEN];\r
410         while (max_count >0 )\r
411         {\r
412                 stat = spi_in(port, UART_LSR, SEL_UART);\r
413                 if((((stat >> 8) & 0x3f) != 0) && (!(stat & UART_LSR_DR)))\r
414                 printk("%s:warning:no receive data but count =%d \n",__FUNCTION__,((stat >> 8) & 0x3f));\r
415                 if(!(stat & UART_LSR_DR))\r
416                         break;\r
417                 ret = spi_in(port, UART_RX, SEL_UART);\r
418                 count = (ret >> 8) & 0x3f;      \r
419                 DBG("%s:count=%d\n",__FUNCTION__,count);\r
420                 if(count == 0)\r
421                 break;\r
422                 buf[0] = ret & 0xff;\r
423                 if(count > 1)\r
424                 {\r
425                         stat = spi_uart_read_buf(uart,buf+1,count-1);\r
426                         if(stat)\r
427                         printk("err:%s:stat=%d,fail to read uart data because of spi bus error!\n",__FUNCTION__,stat);  \r
428                 }\r
429                 max_count -= count;\r
430                 for(i=0;i<count;i++)\r
431                 {\r
432                         flag = TTY_NORMAL;\r
433                         uart->icount.rx++;\r
434                         ch = buf[num++];\r
435                         tty_insert_flip_char(tty, ch, flag);\r
436                         //if(gBaud == 1500000)\r
437                         //printk("0x%x,",ch);\r
438                 }\r
439                 //printk("\n");\r
440         }       \r
441 \r
442         tty_flip_buffer_push(tty); \r
443         //if(gBaud == 1500000)\r
444         //printk("\n");\r
445         \r
446 #else   \r
447         while (--max_count >0 )\r
448         {\r
449                 ch = spi_in(port, UART_RX, SEL_UART);//\r
450                 //printk("0x%x,",ch&0xff);\r
451                 flag = TTY_NORMAL;\r
452                 uart->icount.rx++;\r
453                 //--max_count;\r
454                 if (unlikely(*status & (UART_LSR_BI | UART_LSR_PE |\r
455                                         UART_LSR_FE | UART_LSR_OE))) {\r
456                         /*\r
457                          * For statistics only\r
458                          */\r
459                         if (*status & UART_LSR_BI) {\r
460                                 *status &= ~(UART_LSR_FE | UART_LSR_PE);\r
461                                 uart->icount.brk++;\r
462                         } else if (*status & UART_LSR_PE)\r
463                                 uart->icount.parity++;\r
464                         else if (*status & UART_LSR_FE)\r
465                                 uart->icount.frame++;\r
466                         if (*status & UART_LSR_OE)\r
467                                 uart->icount.overrun++;\r
468 \r
469                         /*\r
470                          * Mask off conditions which should be ignored.\r
471                          */\r
472                         *status &= uart->read_status_mask;\r
473                         if (*status & UART_LSR_BI) {\r
474                                 flag = TTY_BREAK;\r
475                         } else if (*status & UART_LSR_PE)\r
476                                 flag = TTY_PARITY;\r
477                         else if (*status & UART_LSR_FE)\r
478                                 flag = TTY_FRAME;\r
479                 }\r
480 \r
481                 if ((*status & uart->ignore_status_mask & ~UART_LSR_OE) == 0)\r
482                         tty_insert_flip_char(tty, ch, flag);\r
483 \r
484                 /*\r
485                  * Overrun is special.  Since it's reported immediately,\r
486                  * it doesn't affect the current character.\r
487                  */\r
488                 if (*status & ~uart->ignore_status_mask & UART_LSR_OE)\r
489                         tty_insert_flip_char(tty, 0, TTY_OVERRUN);\r
490                 *status = spi_in(port, UART_LSR, SEL_UART);\r
491                 if(!(*status & UART_LSR_DR))\r
492                         break;\r
493         } \r
494         //printk("\n");\r
495         DBG("%s:LINE=%d,rx_count=%d\n",__FUNCTION__,__LINE__,(1024-max_count));\r
496         tty_flip_buffer_push(tty);\r
497 \r
498 #endif\r
499         printk("r%d\n",1024-max_count);\r
500         \r
501 }\r
502 \r
503 static void spi_uart_transmit_chars(struct spi_uart *uart)\r
504 {\r
505         struct circ_buf *xmit = &uart->xmit;\r
506         int count;\r
507 #if SPI_UART_TXRX_BUF   \r
508         unsigned char buf[SPI_UART_FIFO_LEN];\r
509 #endif\r
510         struct spi_fpga_port *port = container_of(uart, struct spi_fpga_port, uart);\r
511         \r
512         if (uart->x_char) {\r
513                 spi_out(port, UART_TX, uart->x_char, SEL_UART);\r
514                 uart->icount.tx++;\r
515                 uart->x_char = 0;\r
516                 printk("%s:LINE=%d\n",__FUNCTION__,__LINE__);\r
517                 return;\r
518         }\r
519         if (circ_empty(xmit) || uart->tty->stopped || uart->tty->hw_stopped) {\r
520                 spi_uart_stop_tx(uart);\r
521                 DBG("%s:LINE=%d\n",__FUNCTION__,__LINE__);\r
522                 //printk("circ_empty()\n");\r
523                 return;\r
524         }\r
525         //printk("tx:");\r
526 \r
527 #if SPI_UART_TXRX_BUF\r
528         //send several bytes one time\r
529         count = SPI_UART_FIFO_LEN;\r
530         while(count > 0)\r
531         {\r
532                 if (circ_empty(xmit))\r
533                 break;\r
534                 buf[SPI_UART_FIFO_LEN - count] = xmit->buf[xmit->tail];\r
535                 //if(gBaud == 1500000)\r
536                 //printk("0x%x,",buf[SPI_UART_FIFO_LEN - count]&0xff);\r
537                 xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);\r
538                 uart->icount.tx++;\r
539                 --count;\r
540 \r
541         }\r
542         //if(gBaud == 1500000)\r
543         //printk("\n");\r
544         if(SPI_UART_FIFO_LEN - count > 0)\r
545         spi_uart_write_buf(uart,buf,SPI_UART_FIFO_LEN - count);\r
546 #else\r
547         //send one byte one time\r
548         count = SPI_UART_FIFO_LEN;\r
549         while(count > 0)\r
550         {\r
551                 spi_out(port, UART_TX, xmit->buf[xmit->tail], SEL_UART);\r
552                 //printk("0x%x,",xmit->buf[xmit->tail]);\r
553                 xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);\r
554                 uart->icount.tx++;\r
555                 --count;\r
556                 if (circ_empty(xmit))\r
557                 break;  \r
558         }\r
559 #endif\r
560         //printk("\n");\r
561         DBG("%s:LINE=%d,tx_count=%d\n",__FUNCTION__,__LINE__,(SPI_UART_FIFO_LEN-count));\r
562         if (circ_chars_pending(xmit) < WAKEUP_CHARS)\r
563         {       \r
564                 tty_wakeup(uart->tty);\r
565                 //printk("k,");\r
566         }\r
567         DBG("%s:LINE=%d\n",__FUNCTION__,__LINE__);\r
568         if (circ_empty(xmit))\r
569         {\r
570                 DBG("circ_empty(xmit)\n");\r
571                 spi_uart_stop_tx(uart);\r
572                 //printk("e,");\r
573         }\r
574         \r
575         printk("t%d\n",SPI_UART_FIFO_LEN-count);\r
576 \r
577         DBG("uart->tty->hw_stopped = %d\n",uart->tty->hw_stopped);\r
578 }\r
579 \r
580 #if 1\r
581 static void spi_uart_check_modem_status(struct spi_uart *uart)\r
582 {\r
583         int status;\r
584         struct spi_fpga_port *port = container_of(uart, struct spi_fpga_port, uart);\r
585         \r
586         status = spi_in(port, UART_MSR, SEL_UART);//\r
587         DBG("%s:LINE=%d,status=0x%x*******\n",__FUNCTION__,__LINE__,status);\r
588         if ((status & UART_MSR_ANY_DELTA) == 0)\r
589                 return;\r
590 \r
591         if (status & UART_MSR_TERI)\r
592                 uart->icount.rng++;\r
593         if (status & UART_MSR_DDSR)\r
594                 uart->icount.dsr++;\r
595         if (status & UART_MSR_DDCD)\r
596                 uart->icount.dcd++;\r
597         if (status & UART_MSR_DCTS) {\r
598                 uart->icount.cts++;\r
599                 if (uart->tty->termios->c_cflag & CRTSCTS) {\r
600                         int cts = (status & UART_MSR_CTS);\r
601                         if (uart->tty->hw_stopped) {\r
602                                 if (cts) {\r
603                                         uart->tty->hw_stopped = 0;\r
604                                         spi_uart_start_tx(uart);\r
605                                         DBG("%s:UART_IER=0x%x\n",__FUNCTION__,uart->ier);\r
606                                         tty_wakeup(uart->tty);\r
607                                 }\r
608                         } else {\r
609                                 if (!cts) {\r
610                                         uart->tty->hw_stopped = 1;\r
611                                         DBG("%s:UART_IER=0x%x\n",__FUNCTION__,uart->ier);\r
612                                         spi_uart_stop_tx(uart);\r
613                                 }\r
614                         }\r
615                 }\r
616         }\r
617         DBG("%s:LINE=%d,status=0x%x*******\n",__FUNCTION__,__LINE__,status);\r
618 }\r
619 #endif\r
620 \r
621 \r
622 #if SPI_UART_TEST\r
623 #define UART_TEST_LEN 32        //8bit\r
624 unsigned char buf_test_uart[UART_TEST_LEN+2];\r
625 \r
626 void spi_uart_test_init(struct spi_fpga_port *port)\r
627 {\r
628         unsigned char cval, fcr = 0;\r
629         unsigned int baud, quot;\r
630         unsigned char mcr = 0;\r
631         int ret;\r
632         \r
633         DBG("%s:LINE=%d,mcr=0x%x\n",__FUNCTION__,__LINE__,mcr);\r
634         spi_out(port, UART_MCR, mcr, SEL_UART);\r
635         baud = 1500000;\r
636         cval = UART_LCR_WLEN8;\r
637         fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10;\r
638         quot = 6000000 / baud;\r
639         mcr |= UART_MCR_RTS;\r
640         mcr |= UART_MCR_AFE;\r
641         \r
642         spi_out(port, UART_FCR, UART_FCR_ENABLE_FIFO, SEL_UART);\r
643         spi_out(port, UART_FCR, UART_FCR_ENABLE_FIFO |\r
644                         UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT, SEL_UART);\r
645         spi_out(port, UART_FCR, 0, SEL_UART);\r
646         spi_out(port, UART_LCR, UART_LCR_WLEN8, SEL_UART);\r
647         spi_out(port, UART_LCR, cval | UART_LCR_DLAB, SEL_UART);\r
648         spi_out(port, UART_DLL, quot & 0xff, SEL_UART); \r
649         ret = spi_in(port, UART_DLL, SEL_UART)&0xff;\r
650         if(ret != quot)\r
651         {\r
652                 #if SPI_FPGA_TEST_DEBUG\r
653                 spi_test_wrong_handle();\r
654                 #endif\r
655                 printk("%s:quot=0x%x,UART_DLL=0x%x\n",__FUNCTION__,quot,ret);\r
656         }\r
657         spi_out(port, UART_DLM, quot >> 8, SEL_UART);   \r
658         spi_out(port, UART_LCR, cval, SEL_UART);\r
659         spi_out(port, UART_FCR, fcr, SEL_UART);\r
660         spi_out(port, UART_MCR, mcr, SEL_UART);\r
661 \r
662 \r
663 }\r
664 \r
665 void spi_uart_work_handler(struct work_struct *work)\r
666 {\r
667         int i;\r
668         int count;\r
669         struct spi_fpga_port *port =\r
670                 container_of(work, struct spi_fpga_port, uart.spi_uart_work);\r
671         printk("*************test spi_uart now***************\n");\r
672         spi_uart_test_init(port);\r
673         for(i=0;i<UART_TEST_LEN;i++)\r
674         buf_test_uart[i] = '0'+i;               \r
675         count = UART_TEST_LEN;\r
676 \r
677 #if SPI_UART_TXRX_BUF\r
678         spi_uart_write_buf(&port->uart, buf_test_uart, count);\r
679         mdelay(5);\r
680         spi_uart_read_buf(&port->uart, buf_test_uart, count);\r
681         for(i=0;i<UART_TEST_LEN;i++)\r
682         {\r
683                 if(buf_test_uart[i] != '0'+i)\r
684                 {\r
685                         #if SPI_FPGA_TEST_DEBUG\r
686                         spi_test_wrong_handle();\r
687                         #endif\r
688                         printk("err:%s:buf_t[%d]=0x%x,buf_r[%d]=0x%x\n",__FUNCTION__,i,'0'+i,i,buf_test_uart[i]);\r
689                 }\r
690         }\r
691 #else\r
692         while(count > 0)\r
693         {\r
694                 spi_out(port, UART_TX, buf_test_uart[UART_TEST_LEN-count], SEL_UART);\r
695                 --count;\r
696         }\r
697         printk("%s,line=%d\n",__FUNCTION__,__LINE__);\r
698 #endif\r
699 \r
700 }\r
701 \r
702 static void spi_testuart_timer(unsigned long data)\r
703 {\r
704         struct spi_fpga_port *port = (struct spi_fpga_port *)data;\r
705         port->uart.uart_timer.expires  = jiffies + msecs_to_jiffies(300);\r
706         add_timer(&port->uart.uart_timer);\r
707         //schedule_work(&port->gpio.spi_gpio_work);\r
708         queue_work(port->uart.spi_uart_workqueue, &port->uart.spi_uart_work);\r
709 }\r
710 \r
711 #endif\r
712 \r
713 /*\r
714  * This handles the interrupt from one port.\r
715  */\r
716 void spi_uart_handle_irq(struct spi_device *spi)\r
717 {\r
718         struct spi_fpga_port *port = spi_get_drvdata(spi);\r
719         struct spi_uart *uart = &port->uart;\r
720         unsigned int uart_iir, lsr;\r
721 \r
722         if (unlikely(uart->in_spi_uart_irq == current))\r
723                 return;\r
724         DBG("%s:LINE=%d\n",__FUNCTION__,__LINE__);\r
725 \r
726         /*\r
727          * In a few places spi_uart_handle_irq() is called directly instead of\r
728          * waiting for the actual interrupt to be raised and the SPI IRQ\r
729          * thread scheduled in order to reduce latency.  However, some\r
730          * interaction with the tty core may end up calling us back\r
731          * (serial echo, flow control, etc.) through those same places\r
732          * causing undesirable effects.  Let's stop the recursion here.\r
733          */\r
734          \r
735         uart_iir = spi_in(port, UART_IIR, SEL_UART);//  \r
736         DBG("%s:iir=0x%x\n",__FUNCTION__,uart_iir);     \r
737         if (uart_iir & UART_IIR_NO_INT)\r
738                 return;\r
739                 \r
740         uart->in_spi_uart_irq = current;\r
741         lsr = spi_in(port, UART_LSR, SEL_UART);//\r
742         DBG("%s:lsr=0x%x\n",__FUNCTION__,lsr);\r
743 \r
744         if (lsr & UART_LSR_DR)\r
745         //if (((uart_iir & UART_IIR_RDI) | (uart_iir & UART_IIR_RLSI)) &&  (lsr & UART_LSR_DR))\r
746         {\r
747                 DBG("%s:LINE=%d,start recieve data!\n",__FUNCTION__,__LINE__);\r
748                 spi_uart_receive_chars(uart, &lsr);     \r
749         }\r
750 \r
751         spi_uart_check_modem_status(uart);\r
752         \r
753         \r
754         if (lsr & UART_LSR_THRE)\r
755         //if ((uart_iir & UART_IIR_THRI)&&(lsr & UART_LSR_THRE))\r
756         {\r
757                 DBG("%s:LINE=%d,start send data!\n",__FUNCTION__,__LINE__);\r
758                 spi_uart_transmit_chars(uart);\r
759         }\r
760 \r
761         uart->in_spi_uart_irq = NULL;\r
762 \r
763         \r
764 }\r
765 \r
766 static int spi_uart_startup(struct spi_uart *uart)\r
767 {\r
768         unsigned long page;\r
769         struct spi_fpga_port *port = container_of(uart, struct spi_fpga_port, uart);\r
770         \r
771         DBG("%s:LINE=%d\n",__FUNCTION__,__LINE__);\r
772         /*\r
773          * Set the TTY IO error marker - we will only clear this\r
774          * once we have successfully opened the port.\r
775          */\r
776         set_bit(TTY_IO_ERROR, &uart->tty->flags);\r
777 \r
778         /* Initialise and allocate the transmit buffer. */\r
779         page = __get_free_page(GFP_KERNEL);\r
780         if (!page)\r
781                 return -ENOMEM;\r
782 \r
783         uart->xmit.buf = (unsigned char *)page;\r
784         circ_clear(&uart->xmit);\r
785 \r
786         mutex_lock(&port->spi_lock);\r
787 \r
788         /*\r
789          * Clear the FIFO buffers and disable them.\r
790          * (they will be reenabled in spi_change_speed())\r
791          */\r
792         spi_out(port, UART_FCR, UART_FCR_ENABLE_FIFO, SEL_UART);\r
793         spi_out(port, UART_FCR, UART_FCR_ENABLE_FIFO |\r
794                         UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT, SEL_UART);\r
795         spi_out(port, UART_FCR, 0, SEL_UART);\r
796 \r
797         /*\r
798          * Clear the interrupt registers.\r
799          */\r
800         (void) spi_in(port, UART_LSR, SEL_UART);//\r
801         (void) spi_in(port, UART_RX, SEL_UART);//\r
802         (void) spi_in(port, UART_IIR, SEL_UART);//\r
803         (void) spi_in(port, UART_MSR, SEL_UART);//\r
804 \r
805         /*\r
806          * Now, initialize the UART\r
807          */\r
808         spi_out(port, UART_LCR, UART_LCR_WLEN8, SEL_UART);\r
809 \r
810         uart->ier = UART_IER_RLSI | UART_IER_RDI;\r
811         //uart->ier = UART_IER_RLSI | UART_IER_RDI | UART_IER_RTOIE | UART_IER_UUE;\r
812         uart->mctrl = TIOCM_OUT2;\r
813 \r
814         spi_uart_change_speed(uart, uart->tty->termios, NULL);\r
815 \r
816         if (uart->tty->termios->c_cflag & CBAUD)\r
817                 spi_uart_set_mctrl(uart, TIOCM_RTS | TIOCM_DTR);\r
818 \r
819         if (uart->tty->termios->c_cflag & CRTSCTS)\r
820                 if (!(spi_uart_get_mctrl(uart) & TIOCM_CTS))\r
821                         uart->tty->hw_stopped = 1;\r
822 \r
823         clear_bit(TTY_IO_ERROR, &uart->tty->flags);\r
824         DBG("%s:LINE=%d,uart->ier=0x%x\n",__FUNCTION__,__LINE__,uart->ier);\r
825         /* Kick the IRQ handler once while we're still holding the host lock */\r
826         //spi_uart_handle_irq(port->spi);\r
827         mutex_unlock(&port->spi_lock);\r
828         return 0;\r
829 \r
830 //err1:\r
831         //free_page((unsigned long)uart->xmit.buf);\r
832         //return ret;\r
833 }\r
834 \r
835 static void spi_uart_shutdown(struct spi_uart *uart)\r
836 {\r
837         struct spi_fpga_port *port = container_of(uart, struct spi_fpga_port, uart);\r
838         DBG("%s:LINE=%d\n",__FUNCTION__,__LINE__);\r
839 \r
840         mutex_lock(&port->spi_lock);\r
841 #if 1\r
842         spi_uart_stop_rx(uart);\r
843 \r
844         /* TODO: wait here for TX FIFO to drain */\r
845 \r
846         /* Turn off DTR and RTS early. */\r
847         if (uart->tty->termios->c_cflag & HUPCL)\r
848                 spi_uart_clear_mctrl(uart, TIOCM_DTR | TIOCM_RTS);\r
849 \r
850          /* Disable interrupts from this port */\r
851 \r
852         uart->ier = 0;\r
853         spi_out(port, UART_IER, 0, SEL_UART);\r
854 \r
855         spi_uart_clear_mctrl(uart, TIOCM_OUT2);\r
856 \r
857         /* Disable break condition and FIFOs. */\r
858         uart->lcr &= ~UART_LCR_SBC;\r
859         spi_out(port, UART_LCR, uart->lcr, SEL_UART);\r
860         spi_out(port, UART_FCR, UART_FCR_ENABLE_FIFO |\r
861                                  UART_FCR_CLEAR_RCVR |\r
862                                  UART_FCR_CLEAR_XMIT, SEL_UART);\r
863         spi_out(port, UART_FCR, 0, SEL_UART);\r
864 #endif\r
865         mutex_unlock(&port->spi_lock);\r
866 \r
867 //skip:\r
868         /* Free the transmit buffer page. */\r
869         free_page((unsigned long)uart->xmit.buf);\r
870 }\r
871 \r
872 static int spi_uart_open (struct tty_struct *tty, struct file * filp)\r
873 {\r
874         struct spi_uart *uart;\r
875         int ret;\r
876         \r
877         uart = spi_uart_port_get(tty->index);\r
878         if (!uart)\r
879         {\r
880                 DBG("%s:LINE=%d,!port\n",__FUNCTION__,__LINE__);\r
881                 return -ENODEV;\r
882         }\r
883         DBG("%s:LINE=%d,tty->index=%d\n",__FUNCTION__,__LINE__,tty->index);\r
884         mutex_lock(&uart->open_lock);\r
885 \r
886         /*\r
887          * Make sure not to mess up with a dead port\r
888          * which has not been closed yet.\r
889          */\r
890         if (tty->driver_data && tty->driver_data != uart) {\r
891                 mutex_unlock(&uart->open_lock);\r
892                 spi_uart_port_put(uart);\r
893                 DBG("%s:LINE=%d,!= uart\n",__FUNCTION__,__LINE__);\r
894                 return -EBUSY;\r
895         }\r
896 \r
897         if (!uart->opened) {\r
898                 tty->driver_data = uart;\r
899                 uart->tty = tty;\r
900                 ret = spi_uart_startup(uart);\r
901                 if (ret) {\r
902                         tty->driver_data = NULL;\r
903                         uart->tty = NULL;\r
904                         mutex_unlock(&uart->open_lock);\r
905                         spi_uart_port_put(uart);\r
906                         DBG("%s:LINE=%d,ret=%d\n",__FUNCTION__,__LINE__,ret);\r
907                         return ret;\r
908                 }\r
909         }\r
910         uart->opened++;\r
911         DBG("%s:uart->opened++=%d\n",__FUNCTION__,uart->opened);\r
912         mutex_unlock(&uart->open_lock);\r
913         return 0;\r
914 }\r
915 \r
916 static void spi_uart_close(struct tty_struct *tty, struct file * filp)\r
917 {\r
918         struct spi_uart *uart = tty->driver_data;\r
919         printk("%s:LINE=%d,tty->hw_stopped=%d\n",__FUNCTION__,__LINE__,tty->hw_stopped);\r
920         if (!uart)\r
921                 return;\r
922 \r
923         mutex_lock(&uart->open_lock);\r
924         BUG_ON(!uart->opened);\r
925 \r
926         /*\r
927          * This is messy.  The tty layer calls us even when open()\r
928          * returned an error.  Ignore this close request if tty->count\r
929          * is larger than uart->count.\r
930          */\r
931         if (tty->count > uart->opened) {\r
932                 mutex_unlock(&uart->open_lock);\r
933                 return;\r
934         }\r
935 \r
936         if (--uart->opened == 0) {\r
937                 DBG("%s:opened=%d\n",__FUNCTION__,uart->opened);\r
938                 tty->closing = 1;\r
939                 spi_uart_shutdown(uart);\r
940                 tty_ldisc_flush(tty);\r
941                 uart->tty = NULL;\r
942                 tty->driver_data = NULL;\r
943                 tty->closing = 0;\r
944         }\r
945         spi_uart_port_put(uart);\r
946         mutex_unlock(&uart->open_lock);\r
947 \r
948 }\r
949 \r
950 static int spi_uart_write(struct tty_struct * tty, const unsigned char *buf,\r
951                            int count)\r
952 {\r
953         struct spi_uart *uart = tty->driver_data;\r
954         struct circ_buf *circ = &uart->xmit;\r
955         struct spi_fpga_port *port = container_of(uart, struct spi_fpga_port, uart);\r
956         int c, ret = 0;\r
957 \r
958         if (!port->spi)\r
959         {\r
960                 printk("spi error!!!!\n");\r
961                 return -ENODEV;\r
962         }\r
963 \r
964         \r
965         DBG("spi_uart_write 1 circ->head=%d,circ->tail=%d\n",circ->head,circ->tail);\r
966 \r
967         spin_lock(&uart->write_lock);\r
968         while (1) {\r
969                 c = CIRC_SPACE_TO_END(circ->head, circ->tail, UART_XMIT_SIZE);\r
970                 if (count < c)\r
971                         c = count;\r
972                 if (c <= 0)\r
973                         break;\r
974                 memcpy(circ->buf + circ->head, buf, c);\r
975                 circ->head = (circ->head + c) & (UART_XMIT_SIZE - 1);\r
976                 buf += c;\r
977                 count -= c;\r
978                 ret += c;\r
979         }\r
980         spin_unlock(&uart->write_lock);\r
981         \r
982 #if 1\r
983         if ( !(uart->ier & UART_IER_THRI)) {\r
984                 mutex_lock(&port->spi_lock);\r
985                         DBG("%s:LINE=%d\n",__FUNCTION__,__LINE__);\r
986                         /*Note:ICE65L08 output a 'Transmitter holding register interrupt' after 1us*/\r
987                         printk("s,");\r
988                         spi_uart_start_tx(uart);\r
989                         //spi_uart_handle_irq(port->spi);\r
990                 mutex_unlock(&port->spi_lock);  \r
991         }       \r
992 #endif  \r
993 \r
994         //printk("w%d\n",ret);\r
995         return ret;\r
996 }\r
997 \r
998 static int spi_uart_write_room(struct tty_struct *tty)\r
999 {\r
1000         struct spi_uart *uart = tty->driver_data;\r
1001         DBG("%s:LINE=%d\n",__FUNCTION__,__LINE__);\r
1002         return uart ? circ_chars_free(&uart->xmit) : 0;\r
1003 }\r
1004 \r
1005 static int spi_uart_chars_in_buffer(struct tty_struct *tty)\r
1006 {\r
1007         struct spi_uart *uart = tty->driver_data;\r
1008         printk("%s:LINE=%d,circ=%ld\n",__FUNCTION__,__LINE__,circ_chars_pending(&uart->xmit));  \r
1009         return uart ? circ_chars_pending(&uart->xmit) : 0;\r
1010 }\r
1011 \r
1012 static void spi_uart_send_xchar(struct tty_struct *tty, char ch)\r
1013 {\r
1014         struct spi_uart *uart = tty->driver_data;\r
1015         struct spi_fpga_port *port = container_of(uart, struct spi_fpga_port, uart);\r
1016         printk("%s:LINE=%d\n",__FUNCTION__,__LINE__);\r
1017         uart->x_char = ch;\r
1018         if (ch && !(uart->ier & UART_IER_THRI)) {\r
1019                 mutex_lock(&port->spi_lock);\r
1020                 spi_uart_start_tx(uart);\r
1021                 printk("%s:UART_IER=0x%x\n",__FUNCTION__,uart->ier);\r
1022                 spi_uart_handle_irq(port->spi);\r
1023                 mutex_unlock(&port->spi_lock);          \r
1024         }\r
1025 }\r
1026 \r
1027 static void spi_uart_throttle(struct tty_struct *tty)\r
1028 {\r
1029         struct spi_uart *uart = tty->driver_data;\r
1030         struct spi_fpga_port *port = container_of(uart, struct spi_fpga_port, uart);\r
1031         printk("%s:LINE=%d\n",__FUNCTION__,__LINE__);\r
1032         if (!I_IXOFF(tty) && !(tty->termios->c_cflag & CRTSCTS))\r
1033                 return;\r
1034         printk("%s:LINE=%d\n",__FUNCTION__,__LINE__);\r
1035         mutex_lock(&port->spi_lock);\r
1036         if (I_IXOFF(tty)) {\r
1037                 uart->x_char = STOP_CHAR(tty);\r
1038                 spi_uart_start_tx(uart);\r
1039                 DBG("%s:UART_IER=0x%x\n",__FUNCTION__,uart->ier);\r
1040         }\r
1041 \r
1042         if (tty->termios->c_cflag & CRTSCTS)\r
1043                 spi_uart_clear_mctrl(uart, TIOCM_RTS);\r
1044 \r
1045         spi_uart_handle_irq(port->spi);\r
1046         mutex_unlock(&port->spi_lock);\r
1047 }\r
1048 \r
1049 static void spi_uart_unthrottle(struct tty_struct *tty)\r
1050 {\r
1051         struct spi_uart *uart = tty->driver_data;\r
1052         struct spi_fpga_port *port = container_of(uart, struct spi_fpga_port, uart);\r
1053         printk("%s:LINE=%d\n",__FUNCTION__,__LINE__);\r
1054         if (!I_IXOFF(tty) && !(tty->termios->c_cflag & CRTSCTS))\r
1055                 return;\r
1056         mutex_lock(&port->spi_lock);\r
1057         if (I_IXOFF(tty)) {\r
1058                 if (uart->x_char) {\r
1059                         uart->x_char = 0;\r
1060                 } else {\r
1061                         uart->x_char = START_CHAR(tty);\r
1062                         spi_uart_start_tx(uart);\r
1063                         DBG("%s:UART_IER=0x%x\n",__FUNCTION__,uart->ier);\r
1064                 }\r
1065         }\r
1066 \r
1067         if (tty->termios->c_cflag & CRTSCTS)\r
1068                 spi_uart_set_mctrl(uart, TIOCM_RTS);\r
1069 \r
1070         spi_uart_handle_irq(port->spi);\r
1071         mutex_unlock(&port->spi_lock);\r
1072 }\r
1073 \r
1074 static void spi_uart_set_termios(struct tty_struct *tty, struct ktermios *old_termios)\r
1075 {\r
1076         struct spi_uart *uart = tty->driver_data;\r
1077         struct spi_fpga_port *port = container_of(uart, struct spi_fpga_port, uart);\r
1078         unsigned int cflag = tty->termios->c_cflag;\r
1079         unsigned int mask = TIOCM_DTR;\r
1080         DBG("%s:LINE=%d\n",__FUNCTION__,__LINE__);\r
1081         \r
1082 #define RELEVANT_IFLAG(iflag)   ((iflag) & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK))\r
1083 \r
1084         if ((cflag ^ old_termios->c_cflag) == 0 &&\r
1085             RELEVANT_IFLAG(tty->termios->c_iflag ^ old_termios->c_iflag) == 0)\r
1086                 return;\r
1087 \r
1088         mutex_lock(&port->spi_lock);\r
1089         spi_uart_change_speed(uart, tty->termios, old_termios);\r
1090 \r
1091         /* Handle transition to B0 status */\r
1092         if ((old_termios->c_cflag & CBAUD) && !(cflag & CBAUD)){\r
1093                 DBG("%s:LINE=%d\n",__FUNCTION__,__LINE__);\r
1094                 spi_uart_clear_mctrl(uart, TIOCM_RTS | TIOCM_DTR);\r
1095                 //spi_uart_clear_mctrl(uart, TIOCM_RTS);\r
1096                 }\r
1097         \r
1098         /* Handle transition away from B0 status */\r
1099         if (!(old_termios->c_cflag & CBAUD) && (cflag & CBAUD)) {\r
1100                 DBG("%s:LINE=%d\n",__FUNCTION__,__LINE__);\r
1101                 if (!(cflag & CRTSCTS) || !test_bit(TTY_THROTTLED, &tty->flags))\r
1102                         mask |= TIOCM_RTS;\r
1103                 spi_uart_set_mctrl(uart, mask);\r
1104         }\r
1105 \r
1106         /* Handle turning off CRTSCTS */\r
1107         if ((old_termios->c_cflag & CRTSCTS) && !(cflag & CRTSCTS)) {\r
1108                 tty->hw_stopped = 0;\r
1109                 spi_uart_start_tx(uart);\r
1110                 DBG("%s:UART_IER=0x%x\n",__FUNCTION__,uart->ier);\r
1111         }\r
1112 \r
1113         /* Handle turning on CRTSCTS */\r
1114         if (!(old_termios->c_cflag & CRTSCTS) && (cflag & CRTSCTS)) {\r
1115                 //spi_uart_set_mctrl(uart, TIOCM_RTS);\r
1116                 if (!(spi_uart_get_mctrl(uart) & TIOCM_CTS)) {\r
1117                         DBG("%s:LINE=%d,tty->hw_stopped = 1\n",__FUNCTION__,__LINE__);\r
1118                         tty->hw_stopped = 1;\r
1119                         spi_uart_stop_tx(uart);\r
1120                 }\r
1121         }\r
1122         mutex_unlock(&port->spi_lock);\r
1123 \r
1124 }\r
1125 \r
1126 static int spi_uart_break_ctl(struct tty_struct *tty, int break_state)\r
1127 {\r
1128         struct spi_uart *uart = tty->driver_data;\r
1129         struct spi_fpga_port *port = container_of(uart, struct spi_fpga_port, uart); \r
1130         DBG("%s:LINE=%d\n",__FUNCTION__,__LINE__);\r
1131         mutex_lock(&port->spi_lock);\r
1132         if (break_state == -1)\r
1133                 uart->lcr |= UART_LCR_SBC;\r
1134         else\r
1135                 uart->lcr &= ~UART_LCR_SBC;\r
1136         spi_out(port, UART_LCR, uart->lcr, SEL_UART);\r
1137         mutex_unlock(&port->spi_lock);\r
1138         return 0;\r
1139 }\r
1140 \r
1141 static int spi_uart_tiocmget(struct tty_struct *tty, struct file *file)\r
1142 {\r
1143         struct spi_uart *uart = tty->driver_data;\r
1144         struct spi_fpga_port *port = container_of(uart, struct spi_fpga_port, uart);\r
1145         int result;\r
1146         DBG("%s:LINE=%d\n",__FUNCTION__,__LINE__);\r
1147         mutex_lock(&port->spi_lock);\r
1148         result = uart->mctrl | spi_uart_get_mctrl(uart);\r
1149         mutex_unlock(&port->spi_lock);\r
1150         return result;\r
1151 }\r
1152 \r
1153 static int spi_uart_tiocmset(struct tty_struct *tty, struct file *file,\r
1154                               unsigned int set, unsigned int clear)\r
1155 {\r
1156         struct spi_uart *uart = tty->driver_data;\r
1157         struct spi_fpga_port *port = container_of(uart, struct spi_fpga_port, uart);\r
1158         DBG("%s:LINE=%d\n",__FUNCTION__,__LINE__);\r
1159         mutex_lock(&port->spi_lock);\r
1160         spi_uart_update_mctrl(uart, set, clear);\r
1161         mutex_unlock(&port->spi_lock);\r
1162 \r
1163         return 0;\r
1164 }\r
1165 \r
1166 static int spi_uart_proc_show(struct seq_file *m, void *v)\r
1167 {\r
1168         int i;\r
1169 \r
1170         seq_printf(m, "serinfo:1.0 driver%s%s revision:%s\n",\r
1171                        "", "", "");\r
1172         for (i = 0; i < UART_NR; i++) {\r
1173                 struct spi_uart *port = spi_uart_port_get(i);\r
1174                 if (port) {\r
1175                         seq_printf(m, "%d: uart:SPI", i);\r
1176                         if(capable(CAP_SYS_ADMIN)) {\r
1177                                 seq_printf(m, " tx:%d rx:%d",\r
1178                                                port->icount.tx, port->icount.rx);\r
1179                                 if (port->icount.frame)\r
1180                                         seq_printf(m, " fe:%d",\r
1181                                                        port->icount.frame);\r
1182                                 if (port->icount.parity)\r
1183                                         seq_printf(m, " pe:%d",\r
1184                                                        port->icount.parity);\r
1185                                 if (port->icount.brk)\r
1186                                         seq_printf(m, " brk:%d",\r
1187                                                        port->icount.brk);\r
1188                                 if (port->icount.overrun)\r
1189                                         seq_printf(m, " oe:%d",\r
1190                                                        port->icount.overrun);\r
1191                                 if (port->icount.cts)\r
1192                                         seq_printf(m, " cts:%d",\r
1193                                                        port->icount.cts);\r
1194                                 if (port->icount.dsr)\r
1195                                         seq_printf(m, " dsr:%d",\r
1196                                                        port->icount.dsr);\r
1197                                 if (port->icount.rng)\r
1198                                         seq_printf(m, " rng:%d",\r
1199                                                        port->icount.rng);\r
1200                                 if (port->icount.dcd)\r
1201                                         seq_printf(m, " dcd:%d",\r
1202                                                        port->icount.dcd);\r
1203                         }\r
1204                         spi_uart_port_put(port);\r
1205                         seq_putc(m, '\n');\r
1206                 }\r
1207         }\r
1208         return 0;\r
1209 }\r
1210 \r
1211 static int spi_uart_proc_open(struct inode *inode, struct file *file)\r
1212 {\r
1213         return single_open(file, spi_uart_proc_show, NULL);\r
1214 }\r
1215 \r
1216 static const struct file_operations spi_uart_proc_fops = {\r
1217         .owner          = THIS_MODULE,\r
1218         .open           = spi_uart_proc_open,\r
1219         .read           = seq_read,\r
1220         .llseek         = seq_lseek,\r
1221         .release        = single_release,\r
1222 };\r
1223 \r
1224 static const struct tty_operations spi_uart_ops = {\r
1225         .open                   = spi_uart_open,\r
1226         .close                  = spi_uart_close,\r
1227         .write                  = spi_uart_write,\r
1228         .write_room             = spi_uart_write_room,\r
1229         .chars_in_buffer        = spi_uart_chars_in_buffer,\r
1230         .send_xchar             = spi_uart_send_xchar,\r
1231         .throttle               = spi_uart_throttle,\r
1232         .unthrottle             = spi_uart_unthrottle,\r
1233         .set_termios            = spi_uart_set_termios,\r
1234         .break_ctl              = spi_uart_break_ctl,\r
1235         .tiocmget               = spi_uart_tiocmget,\r
1236         .tiocmset               = spi_uart_tiocmset,\r
1237         .proc_fops              = &spi_uart_proc_fops,\r
1238 };\r
1239 \r
1240 \r
1241 static struct tty_driver *spi_uart_tty_driver;\r
1242 \r
1243 int spi_uart_register(struct spi_fpga_port *port)\r
1244 {\r
1245         int i,ret;\r
1246         struct tty_driver *tty_drv;\r
1247         spi_uart_tty_driver = tty_drv = alloc_tty_driver(UART_NR);\r
1248         if (!tty_drv)\r
1249                 return -ENOMEM;\r
1250         tty_drv->owner = THIS_MODULE;\r
1251         tty_drv->driver_name = "spi_uart";\r
1252         tty_drv->name =   "ttySPI";\r
1253         tty_drv->major = 0;  /* dynamically allocated */\r
1254         tty_drv->minor_start = 0;\r
1255         //tty_drv->num = UART_NR;\r
1256         tty_drv->type = TTY_DRIVER_TYPE_SERIAL;\r
1257         tty_drv->subtype = SERIAL_TYPE_NORMAL;\r
1258         tty_drv->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;\r
1259         tty_drv->init_termios = tty_std_termios;\r
1260         tty_drv->init_termios.c_cflag = B115200 | CS8 | CREAD | HUPCL | CLOCAL;\r
1261         tty_drv->init_termios.c_ispeed = 115200;\r
1262         tty_drv->init_termios.c_ospeed = 115200;\r
1263         tty_set_operations(tty_drv, &spi_uart_ops);\r
1264 \r
1265         ret = tty_register_driver(tty_drv);\r
1266         if (ret)\r
1267         goto err1;\r
1268 \r
1269         //port->uart.uartclk = 64*115200;       //MCLK/4\r
1270         port->uart.uartclk = 60*100000; //MCLK/4\r
1271 \r
1272         for(i=0; i<UART_NR; i++)\r
1273         {\r
1274                 ret = spi_uart_add_port(&port->uart);\r
1275                 if (ret) {\r
1276                         goto err2;\r
1277                 } else {\r
1278                         struct device *dev;\r
1279                         dev = tty_register_device(spi_uart_tty_driver, port->uart.index, &port->spi->dev);\r
1280                         if (IS_ERR(dev)) {\r
1281                                 spi_uart_port_remove(&port->uart);\r
1282                                 ret = PTR_ERR(dev);\r
1283                                 goto err2;\r
1284                         }\r
1285                 }\r
1286         }\r
1287 \r
1288 #if SPI_UART_TEST\r
1289         char b[20];\r
1290         sprintf(b, "spi_uart_workqueue");\r
1291         port->uart.spi_uart_workqueue = create_freezeable_workqueue(b);\r
1292         if (!port->uart.spi_uart_workqueue) {\r
1293                 printk("cannot create workqueue\n");\r
1294                 return -EBUSY;\r
1295         }\r
1296         INIT_WORK(&port->uart.spi_uart_work, spi_uart_work_handler);\r
1297 \r
1298         setup_timer(&port->uart.uart_timer, spi_testuart_timer, (unsigned long)port);\r
1299         port->uart.uart_timer.expires  = jiffies+2000;\r
1300         add_timer(&port->uart.uart_timer);\r
1301 \r
1302 #endif\r
1303 \r
1304 \r
1305         return 0;\r
1306 \r
1307 err2:\r
1308         tty_unregister_driver(tty_drv);\r
1309 err1:\r
1310         put_tty_driver(tty_drv);\r
1311         \r
1312         return ret;\r
1313         \r
1314         \r
1315 }\r
1316 int spi_uart_unregister(struct spi_fpga_port *port)\r
1317 {\r
1318 \r
1319         return 0;\r
1320 }\r
1321 \r
1322 MODULE_DESCRIPTION("Driver for spi2uart.");\r
1323 MODULE_AUTHOR("luowei <lw@rock-chips.com>");\r
1324 MODULE_LICENSE("GPL");\r