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
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
31 #include <mach/spi_fpga.h>
\r
33 #if defined(CONFIG_SPI_UART_DEBUG)
\r
34 #define DBG(x...) printk(x)
\r
39 #define SPI_UART_TEST 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
44 static struct tty_driver *spi_uart_tty_driver;
\r
45 /*------------------------ÒÔÏÂÊÇspi2uart±äÁ¿-----------------------*/
\r
47 #define UART_NR 1 /* Number of UARTs this driver can handle */
\r
49 #define UART_XMIT_SIZE PAGE_SIZE
\r
50 #define WAKEUP_CHARS 1024
\r
52 #define circ_empty(circ) ((circ)->head == (circ)->tail)
\r
53 #define circ_clear(circ) ((circ)->head = (circ)->tail = 0)
\r
55 #define circ_chars_pending(circ) \
\r
56 (CIRC_CNT((circ)->head, (circ)->tail, UART_XMIT_SIZE))
\r
58 #define circ_chars_free(circ) \
\r
59 (CIRC_SPACE((circ)->head, (circ)->tail, UART_XMIT_SIZE))
\r
64 static struct spi_uart *spi_uart_table[UART_NR];
\r
65 static DEFINE_SPINLOCK(spi_uart_table_lock);
\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
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
74 unsigned char tx_buf[SPI_UART_FIFO_LEN+2];
\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
81 stat = spi_write(port->spi, tx_buf, len+2);
\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
89 static int spi_uart_read_buf(struct spi_uart *uart, unsigned char *buf, int len)
\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
96 reg = (((reg) | ICE_SEL_UART) | ICE_SEL_READ | ICE_SEL_UART_CH(index));
\r
97 tx_buf[0] = reg & 0xff;
\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
103 printk("%s:spi_write_then_read is error!,err=%d\n\n",__FUNCTION__,stat);
\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
114 static int spi_uart_add_port(struct spi_uart *uart)
\r
116 int index, ret = -EBUSY;
\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
123 spin_lock(&spi_uart_table_lock);
\r
124 for (index = 0; index < UART_NR; index++)
\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
134 spin_unlock(&spi_uart_table_lock);
\r
139 static struct spi_uart *spi_uart_port_get(unsigned index)
\r
141 struct spi_uart *uart;
\r
143 if (index >= UART_NR)
\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
151 kref_get(&uart->kref);
\r
152 spin_unlock(&spi_uart_table_lock);
\r
157 static void spi_uart_port_destroy(struct kref *kref)
\r
159 struct spi_uart *uart =
\r
160 container_of(kref, struct spi_uart, kref);
\r
164 static void spi_uart_port_put(struct spi_uart *uart)
\r
166 kref_put(&uart->kref, spi_uart_port_destroy);
\r
169 static void spi_uart_port_remove(struct spi_uart *uart)
\r
171 struct spi_device *spi;
\r
172 struct spi_fpga_port *port = container_of(uart, struct spi_fpga_port, uart);
\r
174 BUG_ON(spi_uart_table[uart->index] != uart);
\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
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
186 mutex_lock(&uart->open_lock);
\r
187 mutex_lock(&port->spi_lock);
\r
191 mutex_unlock(&port->spi_lock);
\r
193 tty_hangup(uart->tty);
\r
194 mutex_unlock(&uart->open_lock);
\r
196 spi_uart_port_put(uart);
\r
199 static unsigned int spi_uart_get_mctrl(struct spi_uart *uart)
\r
201 unsigned char status;
\r
203 struct spi_fpga_port *port = container_of(uart, struct spi_fpga_port, uart);
\r
205 status = spi_in(port, UART_MSR, SEL_UART);//
\r
208 if (status & UART_MSR_DCD)
\r
210 if (status & UART_MSR_RI)
\r
212 if (status & UART_MSR_DSR)
\r
214 if (status & UART_MSR_CTS)
\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
223 static void spi_uart_write_mctrl(struct spi_uart *uart, unsigned int mctrl)
\r
225 unsigned char mcr = 0;
\r
226 struct spi_fpga_port *port = container_of(uart, struct spi_fpga_port, uart);
\r
228 if (mctrl & TIOCM_RTS)
\r
230 mcr |= UART_MCR_RTS;
\r
231 mcr |= UART_MCR_AFE;
\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
244 DBG("%s:LINE=%d,mcr=0x%x\n",__FUNCTION__,__LINE__,mcr);
\r
245 spi_out(port, UART_MCR, mcr, SEL_UART);
\r
248 static inline void spi_uart_update_mctrl(struct spi_uart *uart,
\r
249 unsigned int set, unsigned int clear)
\r
252 DBG("%s:LINE=%d\n",__FUNCTION__,__LINE__);
\r
254 uart->mctrl = (old & ~clear) | set;
\r
255 if (old != uart->mctrl)
\r
256 spi_uart_write_mctrl(uart, uart->mctrl);
\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
262 static void spi_uart_change_speed(struct spi_uart *uart,
\r
263 struct ktermios *termios,
\r
264 struct ktermios *old)
\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
270 switch (termios->c_cflag & CSIZE) {
\r
272 cval = UART_LCR_WLEN5;
\r
275 cval = UART_LCR_WLEN6;
\r
278 cval = UART_LCR_WLEN7;
\r
282 cval = UART_LCR_WLEN8;
\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
294 baud = tty_termios_baud_rate(termios);
\r
296 baud = 115200; /* Special case: B0 rate. */
\r
297 if (baud <= uart->uartclk)
\r
300 * Oops, the quotient was zero. Try again with the old
\r
301 * baud rate if possible, otherwise default to 115200.
\r
303 termios->c_cflag &= ~CBAUD;
\r
305 termios->c_cflag |= old->c_cflag & CBAUD;
\r
308 termios->c_cflag |= B115200;
\r
310 //quot = (2 * uart->uartclk + baud) / (2 * baud);
\r
311 quot = (uart->uartclk / baud);
\r
313 printk("baud=%d,quot=0x%x\n",baud,quot);
\r
315 fcr = UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_1;
\r
317 fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10;
\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
326 * Characters to ignore
\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
334 * If we're ignoring parity and break indicators,
\r
335 * ignore overruns too (for real raw support).
\r
337 if (termios->c_iflag & IGNPAR)
\r
338 uart->ignore_status_mask |= UART_LSR_OE;
\r
342 * ignore all characters if CREAD is not set
\r
344 if ((termios->c_cflag & CREAD) == 0)
\r
345 uart->ignore_status_mask |= UART_LSR_DR;
\r
348 * CTS flow control flag and modem status interrupts
\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
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
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
368 static void spi_uart_start_tx(struct spi_uart *uart)
\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
377 DBG("%s:UART_IER=0x%x\n",__FUNCTION__,uart->ier);
\r
381 static void spi_uart_stop_tx(struct spi_uart *uart)
\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
388 DBG("%s:UART_IER=0x%x\n",__FUNCTION__,uart->ier);
\r
391 static void spi_uart_stop_rx(struct spi_uart *uart)
\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
399 static void spi_uart_receive_chars(struct spi_uart *uart, unsigned int *status)
\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
406 #if SPI_UART_TXRX_BUF
\r
407 int ret,count,stat = 0,num = 0;
\r
409 unsigned char buf[SPI_UART_FIFO_LEN];
\r
410 while (max_count >0 )
\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
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
422 buf[0] = ret & 0xff;
\r
425 stat = spi_uart_read_buf(uart,buf+1,count-1);
\r
427 printk("err:%s:stat=%d,fail to read uart data because of spi bus error!\n",__FUNCTION__,stat);
\r
429 max_count -= count;
\r
430 for(i=0;i<count;i++)
\r
435 tty_insert_flip_char(tty, ch, flag);
\r
436 //if(gBaud == 1500000)
\r
437 //printk("0x%x,",ch);
\r
442 tty_flip_buffer_push(tty);
\r
443 //if(gBaud == 1500000)
\r
447 while (--max_count >0 )
\r
449 ch = spi_in(port, UART_RX, SEL_UART);//
\r
450 //printk("0x%x,",ch&0xff);
\r
454 if (unlikely(*status & (UART_LSR_BI | UART_LSR_PE |
\r
455 UART_LSR_FE | UART_LSR_OE))) {
\r
457 * For statistics only
\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
470 * Mask off conditions which should be ignored.
\r
472 *status &= uart->read_status_mask;
\r
473 if (*status & UART_LSR_BI) {
\r
475 } else if (*status & UART_LSR_PE)
\r
477 else if (*status & UART_LSR_FE)
\r
481 if ((*status & uart->ignore_status_mask & ~UART_LSR_OE) == 0)
\r
482 tty_insert_flip_char(tty, ch, flag);
\r
485 * Overrun is special. Since it's reported immediately,
\r
486 * it doesn't affect the current character.
\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
495 DBG("%s:LINE=%d,rx_count=%d\n",__FUNCTION__,__LINE__,(1024-max_count));
\r
496 tty_flip_buffer_push(tty);
\r
499 printk("r%d\n",1024-max_count);
\r
503 static void spi_uart_transmit_chars(struct spi_uart *uart)
\r
505 struct circ_buf *xmit = &uart->xmit;
\r
507 #if SPI_UART_TXRX_BUF
\r
508 unsigned char buf[SPI_UART_FIFO_LEN];
\r
510 struct spi_fpga_port *port = container_of(uart, struct spi_fpga_port, uart);
\r
512 if (uart->x_char) {
\r
513 spi_out(port, UART_TX, uart->x_char, SEL_UART);
\r
516 printk("%s:LINE=%d\n",__FUNCTION__,__LINE__);
\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
527 #if SPI_UART_TXRX_BUF
\r
528 //send several bytes one time
\r
529 count = SPI_UART_FIFO_LEN;
\r
532 if (circ_empty(xmit))
\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
542 //if(gBaud == 1500000)
\r
544 if(SPI_UART_FIFO_LEN - count > 0)
\r
545 spi_uart_write_buf(uart,buf,SPI_UART_FIFO_LEN - count);
\r
547 //send one byte one time
\r
548 count = SPI_UART_FIFO_LEN;
\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
556 if (circ_empty(xmit))
\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
564 tty_wakeup(uart->tty);
\r
567 DBG("%s:LINE=%d\n",__FUNCTION__,__LINE__);
\r
568 if (circ_empty(xmit))
\r
570 DBG("circ_empty(xmit)\n");
\r
571 spi_uart_stop_tx(uart);
\r
575 printk("t%d\n",SPI_UART_FIFO_LEN-count);
\r
577 DBG("uart->tty->hw_stopped = %d\n",uart->tty->hw_stopped);
\r
581 static void spi_uart_check_modem_status(struct spi_uart *uart)
\r
584 struct spi_fpga_port *port = container_of(uart, struct spi_fpga_port, uart);
\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
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
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
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
617 DBG("%s:LINE=%d,status=0x%x*******\n",__FUNCTION__,__LINE__,status);
\r
623 #define UART_TEST_LEN 32 //8bit
\r
624 unsigned char buf_test_uart[UART_TEST_LEN+2];
\r
626 void spi_uart_test_init(struct spi_fpga_port *port)
\r
628 unsigned char cval, fcr = 0;
\r
629 unsigned int baud, quot;
\r
630 unsigned char mcr = 0;
\r
633 DBG("%s:LINE=%d,mcr=0x%x\n",__FUNCTION__,__LINE__,mcr);
\r
634 spi_out(port, UART_MCR, mcr, SEL_UART);
\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
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
652 #if SPI_FPGA_TEST_DEBUG
\r
653 spi_test_wrong_handle();
\r
655 printk("%s:quot=0x%x,UART_DLL=0x%x\n",__FUNCTION__,quot,ret);
\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
665 void spi_uart_work_handler(struct work_struct *work)
\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
677 #if SPI_UART_TXRX_BUF
\r
678 spi_uart_write_buf(&port->uart, buf_test_uart, count);
\r
680 spi_uart_read_buf(&port->uart, buf_test_uart, count);
\r
681 for(i=0;i<UART_TEST_LEN;i++)
\r
683 if(buf_test_uart[i] != '0'+i)
\r
685 #if SPI_FPGA_TEST_DEBUG
\r
686 spi_test_wrong_handle();
\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
694 spi_out(port, UART_TX, buf_test_uart[UART_TEST_LEN-count], SEL_UART);
\r
697 printk("%s,line=%d\n",__FUNCTION__,__LINE__);
\r
702 static void spi_testuart_timer(unsigned long data)
\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
714 * This handles the interrupt from one port.
\r
716 void spi_uart_handle_irq(struct spi_device *spi)
\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
722 if (unlikely(uart->in_spi_uart_irq == current))
\r
724 DBG("%s:LINE=%d\n",__FUNCTION__,__LINE__);
\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
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
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
744 if (lsr & UART_LSR_DR)
\r
745 //if (((uart_iir & UART_IIR_RDI) | (uart_iir & UART_IIR_RLSI)) && (lsr & UART_LSR_DR))
\r
747 DBG("%s:LINE=%d,start recieve data!\n",__FUNCTION__,__LINE__);
\r
748 spi_uart_receive_chars(uart, &lsr);
\r
751 spi_uart_check_modem_status(uart);
\r
754 if (lsr & UART_LSR_THRE)
\r
755 //if ((uart_iir & UART_IIR_THRI)&&(lsr & UART_LSR_THRE))
\r
757 DBG("%s:LINE=%d,start send data!\n",__FUNCTION__,__LINE__);
\r
758 spi_uart_transmit_chars(uart);
\r
761 uart->in_spi_uart_irq = NULL;
\r
766 static int spi_uart_startup(struct spi_uart *uart)
\r
768 unsigned long page;
\r
769 struct spi_fpga_port *port = container_of(uart, struct spi_fpga_port, uart);
\r
771 DBG("%s:LINE=%d\n",__FUNCTION__,__LINE__);
\r
773 * Set the TTY IO error marker - we will only clear this
\r
774 * once we have successfully opened the port.
\r
776 set_bit(TTY_IO_ERROR, &uart->tty->flags);
\r
778 /* Initialise and allocate the transmit buffer. */
\r
779 page = __get_free_page(GFP_KERNEL);
\r
783 uart->xmit.buf = (unsigned char *)page;
\r
784 circ_clear(&uart->xmit);
\r
786 mutex_lock(&port->spi_lock);
\r
789 * Clear the FIFO buffers and disable them.
\r
790 * (they will be reenabled in spi_change_speed())
\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
798 * Clear the interrupt registers.
\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
806 * Now, initialize the UART
\r
808 spi_out(port, UART_LCR, UART_LCR_WLEN8, SEL_UART);
\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
814 spi_uart_change_speed(uart, uart->tty->termios, NULL);
\r
816 if (uart->tty->termios->c_cflag & CBAUD)
\r
817 spi_uart_set_mctrl(uart, TIOCM_RTS | TIOCM_DTR);
\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
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
831 //free_page((unsigned long)uart->xmit.buf);
\r
835 static void spi_uart_shutdown(struct spi_uart *uart)
\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
840 mutex_lock(&port->spi_lock);
\r
842 spi_uart_stop_rx(uart);
\r
844 /* TODO: wait here for TX FIFO to drain */
\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
850 /* Disable interrupts from this port */
\r
853 spi_out(port, UART_IER, 0, SEL_UART);
\r
855 spi_uart_clear_mctrl(uart, TIOCM_OUT2);
\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
865 mutex_unlock(&port->spi_lock);
\r
868 /* Free the transmit buffer page. */
\r
869 free_page((unsigned long)uart->xmit.buf);
\r
872 static int spi_uart_open (struct tty_struct *tty, struct file * filp)
\r
874 struct spi_uart *uart;
\r
877 uart = spi_uart_port_get(tty->index);
\r
880 DBG("%s:LINE=%d,!port\n",__FUNCTION__,__LINE__);
\r
883 DBG("%s:LINE=%d,tty->index=%d\n",__FUNCTION__,__LINE__,tty->index);
\r
884 mutex_lock(&uart->open_lock);
\r
887 * Make sure not to mess up with a dead port
\r
888 * which has not been closed yet.
\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
897 if (!uart->opened) {
\r
898 tty->driver_data = uart;
\r
900 ret = spi_uart_startup(uart);
\r
902 tty->driver_data = 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
911 DBG("%s:uart->opened++=%d\n",__FUNCTION__,uart->opened);
\r
912 mutex_unlock(&uart->open_lock);
\r
916 static void spi_uart_close(struct tty_struct *tty, struct file * filp)
\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
923 mutex_lock(&uart->open_lock);
\r
924 BUG_ON(!uart->opened);
\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
931 if (tty->count > uart->opened) {
\r
932 mutex_unlock(&uart->open_lock);
\r
936 if (--uart->opened == 0) {
\r
937 DBG("%s:opened=%d\n",__FUNCTION__,uart->opened);
\r
939 spi_uart_shutdown(uart);
\r
940 tty_ldisc_flush(tty);
\r
942 tty->driver_data = NULL;
\r
945 spi_uart_port_put(uart);
\r
946 mutex_unlock(&uart->open_lock);
\r
950 static int spi_uart_write(struct tty_struct * tty, const unsigned char *buf,
\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
960 printk("spi error!!!!\n");
\r
965 DBG("spi_uart_write 1 circ->head=%d,circ->tail=%d\n",circ->head,circ->tail);
\r
967 spin_lock(&uart->write_lock);
\r
969 c = CIRC_SPACE_TO_END(circ->head, circ->tail, UART_XMIT_SIZE);
\r
974 memcpy(circ->buf + circ->head, buf, c);
\r
975 circ->head = (circ->head + c) & (UART_XMIT_SIZE - 1);
\r
980 spin_unlock(&uart->write_lock);
\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
988 spi_uart_start_tx(uart);
\r
989 //spi_uart_handle_irq(port->spi);
\r
990 mutex_unlock(&port->spi_lock);
\r
994 //printk("w%d\n",ret);
\r
998 static int spi_uart_write_room(struct tty_struct *tty)
\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
1005 static int spi_uart_chars_in_buffer(struct tty_struct *tty)
\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
1012 static void spi_uart_send_xchar(struct tty_struct *tty, char ch)
\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
1027 static void spi_uart_throttle(struct tty_struct *tty)
\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
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
1042 if (tty->termios->c_cflag & CRTSCTS)
\r
1043 spi_uart_clear_mctrl(uart, TIOCM_RTS);
\r
1045 spi_uart_handle_irq(port->spi);
\r
1046 mutex_unlock(&port->spi_lock);
\r
1049 static void spi_uart_unthrottle(struct tty_struct *tty)
\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
1056 mutex_lock(&port->spi_lock);
\r
1057 if (I_IXOFF(tty)) {
\r
1058 if (uart->x_char) {
\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
1067 if (tty->termios->c_cflag & CRTSCTS)
\r
1068 spi_uart_set_mctrl(uart, TIOCM_RTS);
\r
1070 spi_uart_handle_irq(port->spi);
\r
1071 mutex_unlock(&port->spi_lock);
\r
1074 static void spi_uart_set_termios(struct tty_struct *tty, struct ktermios *old_termios)
\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
1082 #define RELEVANT_IFLAG(iflag) ((iflag) & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK))
\r
1084 if ((cflag ^ old_termios->c_cflag) == 0 &&
\r
1085 RELEVANT_IFLAG(tty->termios->c_iflag ^ old_termios->c_iflag) == 0)
\r
1088 mutex_lock(&port->spi_lock);
\r
1089 spi_uart_change_speed(uart, tty->termios, old_termios);
\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
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
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
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
1122 mutex_unlock(&port->spi_lock);
\r
1126 static int spi_uart_break_ctl(struct tty_struct *tty, int break_state)
\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
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
1141 static int spi_uart_tiocmget(struct tty_struct *tty, struct file *file)
\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
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
1153 static int spi_uart_tiocmset(struct tty_struct *tty, struct file *file,
\r
1154 unsigned int set, unsigned int clear)
\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
1166 static int spi_uart_proc_show(struct seq_file *m, void *v)
\r
1170 seq_printf(m, "serinfo:1.0 driver%s%s revision:%s\n",
\r
1172 for (i = 0; i < UART_NR; i++) {
\r
1173 struct spi_uart *port = spi_uart_port_get(i);
\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
1204 spi_uart_port_put(port);
\r
1205 seq_putc(m, '\n');
\r
1211 static int spi_uart_proc_open(struct inode *inode, struct file *file)
\r
1213 return single_open(file, spi_uart_proc_show, NULL);
\r
1216 static const struct file_operations spi_uart_proc_fops = {
\r
1217 .owner = THIS_MODULE,
\r
1218 .open = spi_uart_proc_open,
\r
1220 .llseek = seq_lseek,
\r
1221 .release = single_release,
\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
1241 static struct tty_driver *spi_uart_tty_driver;
\r
1243 int spi_uart_register(struct spi_fpga_port *port)
\r
1246 struct tty_driver *tty_drv;
\r
1247 spi_uart_tty_driver = tty_drv = alloc_tty_driver(UART_NR);
\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
1265 ret = tty_register_driver(tty_drv);
\r
1269 //port->uart.uartclk = 64*115200; //MCLK/4
\r
1270 port->uart.uartclk = 60*100000; //MCLK/4
\r
1272 for(i=0; i<UART_NR; i++)
\r
1274 ret = spi_uart_add_port(&port->uart);
\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
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
1296 INIT_WORK(&port->uart.spi_uart_work, spi_uart_work_handler);
\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
1308 tty_unregister_driver(tty_drv);
\r
1310 put_tty_driver(tty_drv);
\r
1316 int spi_uart_unregister(struct spi_fpga_port *port)
\r
1322 MODULE_DESCRIPTION("Driver for spi2uart.");
\r
1323 MODULE_AUTHOR("luowei <lw@rock-chips.com>");
\r
1324 MODULE_LICENSE("GPL");
\r