LMS 2012
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
lego_ti_omapl_pru_suart.c
Go to the documentation of this file.
1 /*
2  * TI OMAPL PRU SUART Emulation device driver
3  * Author: subhasish@mistralsolutions.com
4  *
5  * This driver supports TI's PRU SUART Emulation and the
6  * specs for the same is available at <http://www.ti.com>
7  *
8  * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/
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 version 2.
13  *
14  * This program is distributed as is WITHOUT ANY WARRANTY of any
15  * kind, whether express or implied; . even the implied warranty
16  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  */
19 
20 #include <linux/kernel.h>
21 #include <linux/errno.h>
22 #include <linux/init.h>
23 #include <linux/slab.h>
24 /*#include <linux/tty.h>
25  #include <linux/tty_flip.h> */
26 #include <linux/serial.h>
27 #include <linux/serial_core.h>
28 #include <linux/module.h>
29 #include <mach/da8xx.h>
30 #include <linux/platform_device.h>
31 #include <linux/firmware.h>
32 #include <linux/clk.h>
33 #include <linux/serial_reg.h>
34 #include <linux/delay.h>
35 #include <linux/ti_omapl_pru_suart.h>
36 #include "omapl_suart_board.h"
37 #include "suart_api.h"
38 #include "suart_utils.h"
39 #include "suart_err.h"
40 #include "pru.h"
42 
43 #define NR_SUART 2 //8
44 #define DRV_NAME "ti_omapl_pru_suart"
45 #define DRV_DESC "TI PRU SUART Controller Driver v0.1"
46 #define MAX_SUART_RETRIES 100
47 #define SUART_CNTX_SZ 512
48 #define PLATFORM_SUART_RES_SZ 5
49 #define SUART_FIFO_TIMEOUT_DFLT 10 //5
50 #define SUART_FIFO_TIMEOUT_MIN 4
51 #define SUART_FIFO_TIMEOUT_MAX 500
52 
53 //#define __SUART_DEBUG 1
54 #ifdef __SUART_DEBUG
55 #define __suart_debug(fmt, args...) printk(KERN_ERR "suart_debug: " fmt, ## args)
56 #else
57 #define __suart_debug(fmt, args...)
58 #endif
59 
60 //#define __SSC_DEBUG 1
61 #ifdef __SSC_DEBUG
62 #define __ssc_debug(fmt, args...) printk(fmt, ## args)
63 #else
64 #define __ssc_debug(fmt, args...)
65 #endif
66 
67 #define __suart_err(fmt, args...) printk(KERN_ERR "suart_err: " fmt, ## args)
68 
69 #if defined(CONFIG_SERIAL_SUART_OMAPL_PRU) && defined(CONFIG_MAGIC_SYSRQ)
70 #define SUPPORT_SYSRQ
71 #endif
72 
73 /* Default timeout set to 5ms */
74 static int suart_timeout = SUART_FIFO_TIMEOUT_DFLT;
75 module_param(suart_timeout, int, S_IRUGO);
76 MODULE_PARM_DESC(suart_timeout, "fifo timeout in milli seconds (min: 4; max: 500)");
77 
78 struct suart_dma {
81  dma_addr_t dma_phys_addr_tx;
82  dma_addr_t dma_phys_addr_rx;
83 };
84 
85 static dma_addr_t dma_phys_addr;
86 static void *dma_vaddr_buff;
87 
89 
90 
91 #define BUFFER_SIZE 1024 /* Needs to be a 2 size */
92 #define BUFFER_MASK (BUFFER_SIZE-1)
93 
95  struct uart_port port[NR_SUART];
97  struct semaphore port_sem[NR_SUART];
98  struct clk *clk_pru;
99  struct clk *clk_mcasp;
100  const struct firmware *fw;
104  struct circ_buf read_buf[NR_SUART];
105  struct circ_buf write_buf[NR_SUART];
115 };
116 
117 void pru_suart_stop_rx(struct uart_port *port);
118 
119 
120 static u32 suart_get_duplex(struct omapl_pru_suart *soft_uart, u32 uart_no)
121 {
122  return (soft_uart->suart_hdl[uart_no].uartType);
123 }
124 
125 static inline void __stop_tx(struct omapl_pru_suart *soft_uart, u32 uart_no)
126 {
127  u16 txready;
128  u32 i;
129 
130  /* Check if any TX in progress */
131  for (i = 0, txready = 1; (i < 10000) && txready; i++) {
132  txready =
133  (pru_softuart_getTxStatus(&soft_uart->suart_hdl[uart_no])
135  }
136  /* To stop tx, disable the TX interrupt */
137  suart_intr_clrmask(soft_uart->suart_hdl[uart_no].uartNum, PRU_TX_INTR,
139  pru_softuart_clrTxStatus(&soft_uart->suart_hdl[uart_no]);
140 }
141 
142 
143 void pru_suart_stop_tx(struct uart_port *port)
144 {
145  struct omapl_pru_suart *soft_uart =
146  container_of(port, struct omapl_pru_suart, port[port->line]);
147  __suart_debug("Enter pru_suart_stop_tx (%x)\n", port->line);
148 
149  __stop_tx(soft_uart, port->line);
150 
151 }
152 
153 static void omapl_pru_tx_chars(struct omapl_pru_suart *soft_uart, u32 uart_no)
154 {
155  struct circ_buf *xmit = &soft_uart->write_buf[uart_no];
156  int count = 0;
157  __ssc_debug("T");
158 
159  if (!(suart_get_duplex(soft_uart, uart_no) & ePRU_SUART_HALF_TX)) {
160  return;
161  }
162 
163  if (down_trylock(&soft_uart->port_sem[uart_no]))
164  return;
165 
166  if (uart_circ_empty(xmit) /*|| uart_tx_stopped(&soft_uart->port[uart_no])*/) {
167  pru_suart_stop_tx(&soft_uart->port[uart_no]);
168  up(&soft_uart->port_sem[uart_no]);
169  return;
170  }
171 
172  for (count = 0; count <= soft_uart->tx_loadsz; count++) {
173  *((char *)soft_uart->suart_dma_addr[uart_no].dma_vaddr_buff_tx +
174  count) = xmit->buf[xmit->tail];
175  xmit->tail = (xmit->tail + 1) & (BUFFER_MASK); /* limit to PAGE_SIZE */
176  soft_uart->port[uart_no].icount.tx++;
177  if (uart_circ_empty(xmit)) {
178  break;
179  }
180  }
181 
182  if (count == (SUART_FIFO_LEN + 1))
183  count = SUART_FIFO_LEN;
184 
185  /* Write the character to the data port */
186  if (SUART_SUCCESS != pru_softuart_write(&soft_uart->suart_hdl[uart_no],
187  (unsigned int *)
188  &soft_uart->suart_dma_addr
189  [uart_no].dma_phys_addr_tx,
190  count)) {
191  __suart_err("failed to tx data\n");
192  }
193 
194 // SSC - Hvad gør dette præcist?
195 // if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
196 // uart_write_wakeup(&soft_uart->port[uart_no]);
197 
198 #if 0
199  if (uart_circ_empty(xmit)){
200  __stop_tx(soft_uart, uart_no);
201  }
202 #endif
203 }
204 
205 static void omapl_pru_rx_chars(struct omapl_pru_suart *soft_uart, u32 uart_no)
206 {
207  // struct tty_struct *tty = soft_uart->port[uart_no].state->port.tty;
208  // char tty_flg[SUART_FIFO_LEN + 1] = {[0 ... SUART_FIFO_LEN] = TTY_NORMAL};
209  u16 rx_status, data_len = SUART_FIFO_LEN;
210  unsigned int data_len_read = 0;
211  unsigned char suart_data[SUART_FIFO_LEN + 1];
212  struct circ_buf *buf;
213  int index, space;
214  //int data_buffer_size;
215 
216  if (!(suart_get_duplex(soft_uart, uart_no) & ePRU_SUART_HALF_RX))
217  return;
218  /* read the status */
219  rx_status = pru_softuart_getRxStatus(&soft_uart->suart_hdl[uart_no]);
220  pru_softuart_read_data (&soft_uart->suart_hdl[uart_no], suart_data,
221  data_len + 1 , &data_len_read);
222 
223  if ((rx_status != 0x01) && (rx_status != 0x03)) __ssc_debug("R%02x ",rx_status);
224  __suart_debug("rx_status=0x%x ", rx_status);
225 
226  /* check for errors */
227  if (rx_status & CHN_TXRX_STATUS_ERR) {
228 
229  if (soft_uart->sensor_inited[uart_no])
230  pru_suart_stop_rx(&soft_uart->port[uart_no]);
231 
232  if (rx_status & CHN_TXRX_STATUS_FE)
233  soft_uart->port[uart_no].icount.frame++;
234 
235  if (rx_status & CHN_TXRX_STATUS_OVRNERR)
236  soft_uart->port[uart_no].icount.overrun++;
237 
238  if (rx_status & CHN_TXRX_STATUS_BI) {
239  soft_uart->port[uart_no].icount.brk++;
240  soft_uart->break_rcvt[uart_no] = 1;
241  __ssc_debug("BI");
242  }
243 
244  rx_status &= (~soft_uart->port[uart_no].ignore_status_mask
245  & soft_uart->port[uart_no].read_status_mask);
246 
247  }
248  else
249  {
250  buf = &soft_uart->read_buf[uart_no];
251  //data_buffer_size = CIRC_CNT(buf->head, buf->tail, BUFFER_SIZE);
252  //if (data_buffer_size != 1023) __ssc_debug("r%i-%i", data_len_read, data_buffer_size);
253 
254  // Receive data into ring buffer
255  space = CIRC_SPACE(buf->head, buf->tail, BUFFER_SIZE);
256 
257  if (space < data_len_read)
258  {
259  __suart_debug("Overflow in input read buffer");
260  data_len_read = space;
261  pru_suart_stop_rx(&soft_uart->port[uart_no]);
262  }
263 
264  for(index = 0; index < data_len_read; index++)
265  {
266  buf->buf[buf->head] = suart_data[index];
267  buf->head = (buf->head + 1) & BUFFER_MASK;
268  }
269  }
270 
271  pru_softuart_clrRxStatus(&soft_uart->suart_hdl[uart_no]);
272 
273 }
274 
275 static irqreturn_t omapl_pru_suart_interrupt(int irq, void *dev_id)
276 {
277  struct uart_port *port = dev_id;
278  struct omapl_pru_suart *soft_uart =
279  container_of(port, struct omapl_pru_suart, port[port->line]);
280  u16 txrx_flag;
281  u32 ret;
282  unsigned long flags = 0;
283  u16 uartNum = port->line + 1;
284 
285  spin_lock_irqsave(&soft_uart->port[port->line].lock, flags);
286 
287  __suart_debug("Enter omapl_suart_int (%x) ", port->line);
288  //__ssc_debug("I");
289 
290  do {
291  ret = pru_softuart_get_isrstatus(uartNum, &txrx_flag);
292  if (PRU_SUART_SUCCESS != ret) {
294  ("suart%d: failed to get interrupt, ret: 0x%X txrx_flag 0x%X\n",
295  port->line, ret, txrx_flag);
296  spin_unlock_irqrestore(&soft_uart->port[port->line].lock, flags);
297  return IRQ_NONE;
298  }
299  if ((PRU_RX_INTR & txrx_flag) == PRU_RX_INTR) {
300  __suart_debug("RX int\n");
302  if ((soft_uart->port[port->line].ignore_status_mask &
304  pru_softuart_clrRxStatus(&soft_uart->suart_hdl[port->line]);
305  } else {
306  omapl_pru_rx_chars(soft_uart, port->line);
307  }
308  }
309 
310  if ((PRU_TX_INTR & txrx_flag) == PRU_TX_INTR) {
311  __suart_debug("TX int\n");
313  pru_softuart_clrTxStatus(&soft_uart->suart_hdl[port->line]);
314  up(&soft_uart->port_sem[port->line]);
315  omapl_pru_tx_chars(soft_uart, port->line);
316  }
317  } while (txrx_flag & (PRU_RX_INTR | PRU_TX_INTR));
318 
319  __suart_debug("Exit omapl_suart_int (%x) ", port->line);
320 
321  spin_unlock_irqrestore(&soft_uart->port[port->line].lock, flags);
322  return IRQ_HANDLED;
323 }
324 
325 void pru_suart_stop_rx(struct uart_port *port)
326 {
327  struct omapl_pru_suart *soft_uart =
328  container_of(port, struct omapl_pru_suart, port[port->line]);
329 
330  __suart_debug("Enter pru_suart_stop_rx (%x)\n", port->line);
331 
332  // Stop PRU reception of data and clear FIFO
333  pru_softuart_stopReceive(&soft_uart->suart_hdl[port->line]);
334 
335  /* disable rx interrupt */
336  suart_intr_clrmask(soft_uart->suart_hdl[port->line].uartNum,
340 
341  pru_softuart_clrRxFifo(&soft_uart->suart_hdl[port->line]);
342  pru_softuart_clrRxStatus(&soft_uart->suart_hdl[port->line]);
343 
344 }
345 
346 void pru_suart_enable_ms(struct uart_port *port)
347 {
348  __suart_debug("Enter pru_enable_ms (%x)\n", port->line);
349  __suart_err("modem control timer not supported\n");
350 }
351 
352 void pru_suart_start_tx(struct uart_port *port)
353 {
354  struct omapl_pru_suart *soft_uart =
355  container_of(port, struct omapl_pru_suart, port[port->line]);
356  /* unmask the tx interrupts */
357 
358  __suart_debug("Enter pru_suart_start_tx (%x)\n", port->line);
359 
360  suart_intr_setmask(soft_uart->suart_hdl[port->line].uartNum,
362  omapl_pru_tx_chars(soft_uart, port->line);
363 }
364 
365 unsigned int pru_suart_tx_empty(struct uart_port *port)
366 {
367  struct omapl_pru_suart *soft_uart =
368  container_of(port, struct omapl_pru_suart, port[port->line]);
369 
370  __suart_debug("Enter pru_suart_tx_empty (%x)\n", port->line);
371 
372  return(pru_softuart_getTxStatus(&soft_uart->suart_hdl[port->line])
373  & CHN_TXRX_STATUS_RDY) ? 0 : TIOCSER_TEMT;
374 }
375 
376 unsigned int pru_suart_get_mctrl(struct uart_port *port)
377 {
378  __suart_debug("Enter pru_suart_get_mctrl (%x)\n", port->line);
379  return -ENOTSUPP;
380 }
381 
382 void pru_suart_set_mctrl(struct uart_port *port, unsigned int mctrl)
383 {
384  __suart_debug("Enter pru_suart_set_mctrl (%x)\n", port->line);
385  __suart_debug("modem control not supported\n");
386 }
387 
388 void pru_suart_break_ctl(struct uart_port *port, int break_state)
389 {
390  struct omapl_pru_suart *soft_uart =
391  container_of(port, struct omapl_pru_suart, port[port->line]);
392  unsigned long flags = 0;
393  __suart_debug("Enter pru_suart_break_ctl (%x)\n", port->line);
394 
395  spin_lock_irqsave(&port->lock, flags);
396 
397  if (break_state == -1)
398  suart_intr_clrmask(soft_uart->suart_hdl[port->line].uartNum,
400  else
401  suart_intr_setmask(soft_uart->suart_hdl[port->line].uartNum,
403 
404  spin_unlock_irqrestore(&port->lock, flags);
405 }
406 
407 void pru_suart_set_termios(struct uart_port *port,
408  struct ktermios *termios,
409  struct ktermios *old, unsigned int baud)
410 {
411  struct omapl_pru_suart *soft_uart =
412  container_of(port, struct omapl_pru_suart, port[port->line]);
413  unsigned char cval = 0;
414  unsigned long flags = 0;
415 // unsigned int baud = 0;
416  unsigned int old_csize = old ? old->c_cflag & CSIZE : CS8;
417 
418  __suart_debug("Enter pru_suart_set_termios (%x)\n", port->line);
419 
420 /*
421  * Do not allow unsupported configurations to be set
422  */
423  if (1) {
424  termios->c_cflag &= ~(HUPCL | CRTSCTS | CMSPAR | CSTOPB
425  | PARENB | PARODD | CMSPAR);
426  termios->c_cflag |= CLOCAL;
427  }
428 
429  __suart_debug("cflag=0x%x\n", termios->c_cflag);
430  __suart_debug("iflag=0x%x\n", termios->c_iflag);
431  __suart_debug("oflag=0x%x\n", termios->c_oflag);
432  __suart_debug("lflag=0x%x\n", termios->c_lflag);
433 
434 
435  switch (termios->c_cflag & CSIZE) {
436  case CS6:
437  cval = ePRU_SUART_DATA_BITS6;
438  break;
439  case CS7:
440  cval = ePRU_SUART_DATA_BITS7;
441  break;
442  default:
443  case CS8:
444  cval = ePRU_SUART_DATA_BITS8;
445  break;
446  }
447  /*
448  * We do not support CS5.
449  */
450  if ((termios->c_cflag & CSIZE) == CS5) {
451  termios->c_cflag &= ~CSIZE;
452  termios->c_cflag |= old_csize;
453  }
454 
455  if (SUART_SUCCESS !=
456  pru_softuart_setdatabits(&soft_uart->suart_hdl[port->line], cval,
457  cval))
458  __suart_err("failed to set data bits to: %d\n", cval);
459 
460 /*
461  * Ask the core to calculate the divisor for us.
462  */
463  /* DOn't do this as we know out baudrate ourselves
464  baud = uart_get_baud_rate(port, termios, old,
465  port->uartclk / 16 / 0xffff,
466  port->uartclk / 16);
467 */
468 
469  /*
470  * Ok, we're now changing the port state. Do it with
471  * interrupts disabled.
472  */
473  spin_lock_irqsave(&port->lock, flags);
474 
475  /* Set the baud */
476  if (SUART_SUCCESS !=
477  pru_softuart_setbaud(&soft_uart->suart_hdl[port->line],
478  SUART_DEFAULT_BAUD / baud,
479  SUART_DEFAULT_BAUD / baud))
480  __suart_err("failed to set baud to: %d\n", baud);
481 
482 /*
483  * update port->read_config_mask and port->ignore_config_mask
484  * to indicate the events we are interested in receiving
485  */
486  port->read_status_mask = CHN_TXRX_STATUS_OVRNERR | CHN_TXRX_STATUS_ERR;
487  if (termios->c_iflag & INPCK) { /* Input parity check not supported, just enabled FE */
488  port->read_status_mask |= CHN_TXRX_STATUS_FE;
489  suart_intr_setmask(soft_uart->suart_hdl[port->line].uartNum,
491  }
492  if (termios->c_iflag & (BRKINT | PARMRK)) {
493  port->read_status_mask |= CHN_TXRX_STATUS_BI;
494  suart_intr_setmask(soft_uart->suart_hdl[port->line].uartNum,
496  }
497 /*
498  * Characteres to ignore
499  */
500  port->ignore_status_mask = 0;
501  if (termios->c_iflag & IGNPAR)
502  port->ignore_status_mask |= CHN_TXRX_STATUS_FE;
503  if (termios->c_iflag & IGNBRK) {
504  port->ignore_status_mask |= CHN_TXRX_STATUS_BI;
505  /*
506  * If we're ignoring parity and break indicators,
507  * ignore overruns too (for real raw support).
508  */
509  if (termios->c_iflag & IGNPAR)
510  port->ignore_status_mask |= CHN_TXRX_STATUS_OVRNERR;
511  }
512 /*
513  * ignore all characters if CREAD is not set
514  */
515  if ((termios->c_cflag & CREAD) == 0) {
516  port->ignore_status_mask |= CHN_TXRX_STATUS_RDY;
517  pru_suart_stop_rx(port);
518  }
519  /*
520  * update the per port timeout
521  */
522  uart_update_timeout(port,termios->c_cflag,baud);
523 
524  spin_unlock_irqrestore(&port->lock, flags);
525  /* Don't rewrite B0 */
526  //if (tty_termios_baud_rate(termios))
527  // tty_termios_encode_baud_rate(termios, baud, baud);
528 }
529 
530 
531 /*
532  * Grab any interrupt resources and initialise any low level driver
533  * state. Enable the port for reception. It should not activate
534  * RTS nor DTR; this will be done via a separate call to set_mctrl.
535  *
536  * This method will only be called when the port is initially opened.
537  *
538  * Locking: port_sem taken.
539  * Interrupts: globally disabled.
540  */
541 int pru_suart_startup(struct uart_port *port, int init)
542 {
543  struct omapl_pru_suart *soft_uart =
544  container_of(port, struct omapl_pru_suart, port[port->line]);
545  int retval = 0;
546 
547  __suart_debug("Enter pru_suart_startup (%x)\n", port->line);
548 
549  /*
550  * Disable interrupts from this port
551  */
552  suart_intr_clrmask(soft_uart->suart_hdl[port->line].uartNum,
554  suart_intr_clrmask(soft_uart->suart_hdl[port->line].uartNum,
558 
559  if (init)
560  {
561  retval = request_irq(port->irq, omapl_pru_suart_interrupt,
562  port->irqflags, "suart_irq", port);
563  if (retval) {
564  free_irq(port->irq, port); /* should we free this if err */
565  goto out;
566  }
567  }
568 
569  /*
570  * enable interrupts from this port
571  */
572  suart_intr_setmask(soft_uart->suart_hdl[port->line].uartNum,
574 
575  suart_intr_setmask(soft_uart->suart_hdl[port->line].uartNum,
577 
578  suart_intr_setmask(soft_uart->suart_hdl[port->line].uartNum,
580 
581  suart_intr_setmask(soft_uart->suart_hdl[port->line].uartNum,
583 
584  if ((suart_get_duplex(soft_uart, port->line) & ePRU_SUART_HALF_TX)
585  == ePRU_SUART_HALF_TX) {
586  suart_pru_to_host_intr_enable(soft_uart->suart_hdl[port->line].uartNum,
587  PRU_TX_INTR, true);
588  }
589  /* Seed RX if port is half-rx or full-duplex */
590  if ((suart_get_duplex(soft_uart, port->line) & ePRU_SUART_HALF_RX)
591  == ePRU_SUART_HALF_RX) {
592  suart_pru_to_host_intr_enable(soft_uart->suart_hdl[port->line].uartNum,
593  PRU_RX_INTR , true);
594  pru_softuart_read(&soft_uart->suart_hdl[port->line],
595  (unsigned int *)
596  &soft_uart->suart_dma_addr[port->line].
597  dma_phys_addr_rx, SUART_FIFO_LEN);
598  }
599 
600 out:
601  return retval;
602 }
603 
604 /*
605  * Disable the port, disable any break condition that may be in
606  * effect, and free any interrupt resources. It should not disable
607  * RTS nor DTR; this will have already been done via a separate
608  * call to set_mctrl.
609  *
610  * Drivers must not access port->info once this call has completed.
611  *
612  * This method will only be called when there are no more users of
613  * this port.
614  *
615  * Locking: port_sem taken.
616  * Interrupts: caller dependent.
617  */
618 
619 void pru_suart_shutdown(struct uart_port *port, int exit)
620 {
621  struct omapl_pru_suart *soft_uart =
622  container_of(port, struct omapl_pru_suart, port[port->line]);
623 
624  __suart_debug("Enter pru_suart_shutdown (%x)\n", port->line);
625 
626  /*
627  * Disable interrupts from this port
628  */
629  /* Disable BI and FE intr */
630  suart_intr_clrmask(soft_uart->suart_hdl[port->line].uartNum,
632  suart_intr_clrmask(soft_uart->suart_hdl[port->line].uartNum,
636 
637  if (exit)
638  {
639  /* free interrupts */
640  free_irq(port->irq, port);
641  }
642 }
643 
644 
645 /*
646  * Release any memory and IO region resources currently in use by
647  * the port.
648  *
649  * Locking: none.
650  * Interrupts: caller dependent.
651  */
652 
653 void pru_suart_release_port(struct uart_port *port)
654 {
655  struct omapl_pru_suart *soft_uart =
656  container_of(port, struct omapl_pru_suart, port[port->line]);
657  struct platform_device *pdev = to_platform_device(port->dev);
658 
659  __suart_debug("Enter pru_suart_release_port (%x)\n", port->line);
660 
661  if (0 != pru_softuart_close(&soft_uart->suart_hdl[port->line])) {
662  dev_err(&pdev->dev, "failed to close suart\n");
663  }
664  return;
665 }
666 
667 /*
668  * Request any memory and IO region resources required by the port.
669  * If any fail, no resources should be registered when this function
670  * returns, and it should return -EBUSY on failure.
671  *
672  * Locking: none.
673  * Interrupts: caller dependent.
674  *
675  * We need to d/l the f/w in probe and since this api is called per uart, the
676  * request_mem_region should be called in probe itself.
677  * We call the pru_open routein only here. not sure if aesthetically correct.
678  */
679 int pru_suart_request_port(struct uart_port *port)
680 {
681  struct omapl_pru_suart *soft_uart =
682  container_of(port, struct omapl_pru_suart, port[port->line]);
683  struct platform_device *pdev = to_platform_device(port->dev);
684  suart_config pru_suart_config;
685  u32 timeout = 0;
686  u32 err = 0;
687 
688  __suart_debug("Enter pru_suart_request_port (%x)\n", port->line);
689 
690  if (soft_uart == NULL) {
691  __suart_err("soft_uart ptr failed\n");
692  return -ENODEV;
693  }
694  err = pru_softuart_open(&soft_uart->suart_hdl[port->line]);
695  if (PRU_SUART_SUCCESS != err) {
696  dev_err(&pdev->dev, "failed to open suart: %d\n", err);
697  err = -ENODEV;
698  goto exit;
699  }
700 
701  /* set fifo timeout */
702  if (SUART_FIFO_TIMEOUT_MIN > suart_timeout){
703  __suart_err("fifo timeout less than %d ms not supported\n", SUART_FIFO_TIMEOUT_MIN);
704  suart_timeout = SUART_FIFO_TIMEOUT_MIN;
705  } else if (SUART_FIFO_TIMEOUT_MAX < suart_timeout){
706  __suart_err("fifo timeout more than %d ms not supported\n", SUART_FIFO_TIMEOUT_MAX);
707  suart_timeout = SUART_FIFO_TIMEOUT_MAX;
708  }
709 
710  /* This is only for x8 */
711  timeout = (SUART_DEFAULT_BAUD * suart_timeout) / 1000;
712  pru_set_fifo_timeout(timeout);
713 
714  if (soft_uart->suart_hdl[port->line].uartNum == PRU_SUART_UART1) {
715  pru_suart_config.TXSerializer = PRU_SUART1_CONFIG_TX_SER;
716  pru_suart_config.RXSerializer = PRU_SUART1_CONFIG_RX_SER;
717  } else if (soft_uart->suart_hdl[port->line].uartNum == PRU_SUART_UART2) {
718  pru_suart_config.TXSerializer = PRU_SUART2_CONFIG_TX_SER;
719  pru_suart_config.RXSerializer = PRU_SUART2_CONFIG_RX_SER;
720  } else if (soft_uart->suart_hdl[port->line].uartNum == PRU_SUART_UART3) {
721  pru_suart_config.TXSerializer = PRU_SUART3_CONFIG_TX_SER;
722  pru_suart_config.RXSerializer = PRU_SUART3_CONFIG_RX_SER;
723  } else if (soft_uart->suart_hdl[port->line].uartNum == PRU_SUART_UART4) {
724  pru_suart_config.TXSerializer = PRU_SUART4_CONFIG_TX_SER;
725  pru_suart_config.RXSerializer = PRU_SUART4_CONFIG_RX_SER;
726  } else if (soft_uart->suart_hdl[port->line].uartNum == PRU_SUART_UART5) {
727  pru_suart_config.TXSerializer = PRU_SUART5_CONFIG_TX_SER;
728  pru_suart_config.RXSerializer = PRU_SUART5_CONFIG_RX_SER;
729  } else if (soft_uart->suart_hdl[port->line].uartNum == PRU_SUART_UART6) {
730  pru_suart_config.TXSerializer = PRU_SUART6_CONFIG_TX_SER;
731  pru_suart_config.RXSerializer = PRU_SUART6_CONFIG_RX_SER;
732  } else if (soft_uart->suart_hdl[port->line].uartNum == PRU_SUART_UART7) {
733  pru_suart_config.TXSerializer = PRU_SUART7_CONFIG_TX_SER;
734  pru_suart_config.RXSerializer = PRU_SUART7_CONFIG_RX_SER;
735  } else if (soft_uart->suart_hdl[port->line].uartNum == PRU_SUART_UART8) {
736  pru_suart_config.TXSerializer = PRU_SUART8_CONFIG_TX_SER;
737  pru_suart_config.RXSerializer = PRU_SUART8_CONFIG_RX_SER;
738  } else {
739  return -ENOTSUPP;
740  }
741 
742  /* Some defaults to startup. reconfigured by terimos later */
743  pru_suart_config.txClkDivisor = 1;
744  pru_suart_config.rxClkDivisor = 1;
745  pru_suart_config.txBitsPerChar = ePRU_SUART_DATA_BITS8;
746  pru_suart_config.rxBitsPerChar = ePRU_SUART_DATA_BITS8; /* including start and stop bit 8 + 2 */
747  pru_suart_config.Oversampling = SUART_DEFAULT_OVRSMPL;
748 
749  if (PRU_SUART_SUCCESS !=
750  pru_softuart_setconfig(&soft_uart->suart_hdl[port->line],
751  &pru_suart_config)) {
752  dev_err(&pdev->dev,
753  "pru_softuart_setconfig: failed to set config: %X\n",
754  err);
755  }
756 exit:
757  return err;
758 }
759 
760 /*
761  * Perform any autoconfiguration steps required for the port. `flag`
762  * contains a bit mask of the required configuration. UART_CONFIG_TYPE
763  * indicates that the port requires detection and identification.
764  * port->type should be set to the type found, or PORT_UNKNOWN if
765  * no port was detected.
766  *
767  * UART_CONFIG_IRQ indicates autoconfiguration of the interrupt signal,
768  * which should be probed using standard kernel autoprobing techniques.
769  * This is not necessary on platforms where ports have interrupts
770  * internally hard wired (eg, system on a chip implementations).
771  *
772  * Locking: none.
773  * Interrupts: caller dependent.
774  *
775  */
776 
777 void pru_suart_config_port(struct uart_port *port, int flags)
778 {
779  __suart_debug("Enter pru_suart_config_port (%x)\n", port->line);
780 
781  if (flags & UART_CONFIG_TYPE && pru_suart_request_port(port) == 0)
782  port->type = OMAPL_PRU_SUART;
783 }
784 
785 /*
786  * Verify the new serial port information contained within serinfo is
787  * suitable for this port type.
788  *
789  * Locking: none.
790  * Interrupts: caller dependent.
791  */
792 int pru_suart_verify_port(struct uart_port *port,
793  struct serial_struct *ser)
794 {
795  struct omapl_pru_suart *soft_uart =
796  container_of(port, struct omapl_pru_suart, port[port->line]);
797  int ret = 0;
798 
799  __suart_debug("Enter pru_suart_verify_port (%x)\n", port->line);
800 
801  if (ser->type != PORT_UNKNOWN && ser->type != OMAPL_PRU_SUART)
802  ret = -EINVAL;
803  if (soft_uart->port[port->line].irq != ser->irq)
804  ret = -EINVAL;
805  if (ser->io_type != UPIO_MEM)
806  ret = -EINVAL;
807  if (soft_uart->port[port->line].uartclk / 16 != ser->baud_base)
808  ret = -EINVAL;
809  if ((void *)soft_uart->port[port->line].mapbase != ser->iomem_base)
810  ret = -EINVAL;
811  if (soft_uart->port[port->line].iobase != ser->port)
812  ret = -EINVAL;
813  return ret;
814 }
815 
816 
817 /* SSC
818 static struct uart_ops pru_suart_ops = {
819  .tx_empty = pru_suart_tx_empty,
820  .set_mctrl = pru_suart_set_mctrl,
821  .get_mctrl = pru_suart_get_mctrl,
822  .stop_tx = pru_suart_stop_tx,
823  .start_tx = pru_suart_start_tx,
824  .stop_rx = pru_suart_stop_rx,
825  .enable_ms = pru_suart_enable_ms,
826  .break_ctl = pru_suart_break_ctl,
827  .startup = pru_suart_startup,
828  .shutdown = pru_suart_shutdown,
829  .set_termios = pru_suart_set_termios,
830  .type = pru_suart_type,
831  .release_port = pru_suart_release_port,
832  .request_port = pru_suart_request_port,
833  .config_port = pru_suart_config_port,
834  .verify_port = pru_suart_verify_port,
835 };
836 
837 
838 static struct uart_driver pru_suart_reg = {
839  .owner = THIS_MODULE,
840  .driver_name = DRV_NAME,
841  .dev_name = "ttySU",
842  .major = 0,
843  .minor = 16,
844  .nr = NR_SUART,
845 };
846 */
847 
848 int __devinit omapl_pru_suart_probe(struct platform_device *pdev)
849 {
850  //struct omapl_pru_suart *soft_uart;
851  struct ti_pru_suart_platform_data *pdata;
852  struct resource *res_mem[PLATFORM_SUART_RES_SZ];
853  int err, i;
854  unsigned char *fw_data = NULL;
855 
856  __suart_debug("Enter omapl_pru_suart_probe\n");
857 
858  pdata = pdev->dev.platform_data;
859  if (!pdata) {
860  dev_err(&pdev->dev, "no platform data provided for pru!\n");
861  return -ENODEV;
862  }
863 
864  soft_uart = kzalloc(sizeof(struct omapl_pru_suart), GFP_KERNEL);
865  if (!soft_uart)
866  return -ENOMEM;
867 
868  for (i = 0; i < PLATFORM_SUART_RES_SZ; i++) {
869  res_mem[i] = platform_get_resource(pdev, IORESOURCE_MEM, i);
870  if (!res_mem[i]) {
871  dev_err(&pdev->dev,
872  "unable to get pru memory resources!\n");
873  err = -ENODEV;
874  goto probe_exit;
875  }
876  }
877 
878  if (!request_mem_region(res_mem[0]->start, resource_size(res_mem[0]),
879  dev_name(&pdev->dev))) {
880  dev_err(&pdev->dev, "pru memory region already claimed!\n");
881  err = -EBUSY;
882  goto probe_exit;
883  }
884  if (!request_mem_region(res_mem[1]->start, resource_size(res_mem[1]),
885  dev_name(&pdev->dev))) {
886  dev_err(&pdev->dev, "mcasp memory region already claimed!\n");
887  err = -EBUSY;
888  goto probe_exit_1;
889  }
890  if (!request_mem_region(res_mem[2]->start, resource_size(res_mem[2]),
891  dev_name(&pdev->dev))) {
892  dev_err(&pdev->dev, "psc0 memory region already claimed!\n");
893  err = -EBUSY;
894  goto probe_exit_2;
895  }
896  if (!request_mem_region(res_mem[3]->start, resource_size(res_mem[3]),
897  dev_name(&pdev->dev))) {
898  dev_err(&pdev->dev, "psc1 memory region already claimed!\n");
899  err = -EBUSY;
900  goto probe_exit_3;
901  }
902 
903  soft_uart->pru_arm_iomap.pru_io_addr = ioremap(res_mem[0]->start,
904  resource_size(res_mem
905  [0]));
906  if (!soft_uart->pru_arm_iomap.pru_io_addr) {
907  dev_err(&pdev->dev, "ioremap failed\n");
908  err = -ENOMEM;
909  goto probe_exit_free_region;
910  }
911  soft_uart->pru_arm_iomap.mcasp_io_addr = ioremap(res_mem[1]->start,
912  resource_size(res_mem
913  [1]));
914  if (!soft_uart->pru_arm_iomap.mcasp_io_addr) {
915  dev_err(&pdev->dev, "ioremap failed\n");
916  err = -ENOMEM;
917  goto probe_exit_iounmap_1;
918  }
919  soft_uart->pru_arm_iomap.psc0_io_addr = ioremap(res_mem[2]->start,
920  resource_size(res_mem
921  [2]));
922  if (!soft_uart->pru_arm_iomap.psc0_io_addr) {
923  dev_err(&pdev->dev, "ioremap failed\n");
924  err = -ENOMEM;
925  goto probe_exit_iounmap_2;
926  }
927  soft_uart->pru_arm_iomap.psc1_io_addr = ioremap(res_mem[3]->start,
928  resource_size(res_mem
929  [3]));
930  if (!soft_uart->pru_arm_iomap.psc1_io_addr) {
931  dev_err(&pdev->dev, "ioremap failed\n");
932  err = -ENOMEM;
933  goto probe_exit_iounmap_3;
934  }
935  soft_uart->pru_arm_iomap.syscfg_io_addr =
936  IO_ADDRESS(DA8XX_SYSCFG0_BASE);
937  if (!soft_uart->pru_arm_iomap.syscfg_io_addr) {
938  dev_err(&pdev->dev, "ioremap failed\n");
939  err = -ENOMEM;
940  goto probe_exit_iounmap_4;
941  }
942 
943  soft_uart->clk_pru = clk_get(&pdev->dev, "pru_ck");
944  if (IS_ERR(soft_uart->clk_pru)) {
945  dev_err(&pdev->dev, "no clock available: pru_ck\n");
946  err = PTR_ERR(soft_uart->clk_pru);
947  soft_uart->clk_pru = NULL;
948  goto probe_exit_iounmap_2;
949  }
950  soft_uart->clk_freq_pru = clk_get_rate(soft_uart->clk_pru);
951 
952  soft_uart->clk_mcasp = clk_get(NULL, "mcasp_pru");
953  if (IS_ERR(soft_uart->clk_mcasp)) {
954  dev_err(&pdev->dev, "no clock available: mcasp\n");
955  err = PTR_ERR(soft_uart->clk_mcasp);
956  soft_uart->clk_mcasp = NULL;
957  goto probe_exit_clk_pru;
958  }
959  soft_uart->clk_freq_mcasp = clk_get_rate(soft_uart->clk_mcasp);
960  clk_enable(soft_uart->clk_mcasp);
961  clk_enable(soft_uart->clk_pru);
962  err = request_firmware(&soft_uart->fw, "PRU_SUART.bin",
963  &pdev->dev);
964  if (err) {
965  dev_err(&pdev->dev, "can't load firmware\n");
966  err = -ENODEV;
967  goto probe_exit_clk;
968  }
969  /*
970  dev_info(&pdev->dev, "fw size %td. downloading...\n",
971  soft_uart->fw->size);
972 */
973 
974  /* download firmware into pru & init */
975  fw_data = kmalloc(soft_uart->fw->size, GFP_KERNEL);
976  memcpy((void *)fw_data, (const void *)soft_uart->fw->data,
977  soft_uart->fw->size);
978 
979  dma_phys_addr = res_mem[4]->start;
980  dma_vaddr_buff = ioremap(res_mem[4]->start, resource_size(res_mem[4]));
981  if (!dma_vaddr_buff) {
982  __suart_err("Failed to allocate shared ram.\n");
983  err = -EFAULT;
984  goto probe_exit_clk;
985  }
986 
987  soft_uart->pru_arm_iomap.pFifoBufferPhysBase = (void *)dma_phys_addr;
988  soft_uart->pru_arm_iomap.pFifoBufferVirtBase = (void *)dma_vaddr_buff;
989  soft_uart->pru_arm_iomap.pru_clk_freq = (soft_uart->clk_freq_pru / 1000000);
990 
992  SUART_DEFAULT_OVRSMPL, fw_data,
993  soft_uart->fw->size, &soft_uart->pru_arm_iomap);
994  if (err) {
995  dev_err(&pdev->dev, "pru init error\n");
996  err = -ENODEV;
997  kfree((const void *)fw_data);
998  goto probe_release_fw;
999  }
1000  kfree((const void *)fw_data);
1001 
1002  for (i = 0; i < NR_SUART; i++) {
1003  /* SSC soft_uart->port[i].ops = &pru_suart_ops; */
1004  soft_uart->port[i].iotype = UPIO_MEM; /* user conf parallel io */
1005  soft_uart->port[i].flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP;
1006  soft_uart->port[i].mapbase = res_mem[1]->start;
1007  soft_uart->port[i].membase =
1008  (unsigned char *)&soft_uart->pru_arm_iomap;
1009  soft_uart->port[i].type = OMAPL_PRU_SUART;
1010  soft_uart->port[i].irq = platform_get_irq(pdev, i);
1011  soft_uart->port[i].dev = &pdev->dev;
1012  soft_uart->port[i].irqflags = IRQF_SHARED;
1013  soft_uart->port[i].uartclk = soft_uart->clk_freq_mcasp; /* 24MHz */
1014  soft_uart->port[i].fifosize = SUART_FIFO_LEN;
1015  soft_uart->tx_loadsz = SUART_FIFO_LEN;
1016  soft_uart->port[i].custom_divisor = 1;
1017  soft_uart->port[i].line = i; /* need the id/line from pdev */
1018  soft_uart->suart_hdl[i].uartNum = i + 1;
1019  spin_lock_init(&soft_uart->port[i].lock);
1020  soft_uart->port[i].serial_in = NULL;
1021  soft_uart->break_rcvt[i] = 0;
1022  soft_uart->baud[i] = 0;
1023  soft_uart->read_buf[i].buf = &soft_uart->read_data[i][0];
1024  soft_uart->write_buf[i].buf = &soft_uart->write_data[i][0];
1025 
1026  soft_uart->suart_dma_addr[i].dma_vaddr_buff_tx =
1027  dma_vaddr_buff + (2 * SUART_CNTX_SZ * i);
1028 
1029  soft_uart->suart_dma_addr[i].dma_vaddr_buff_rx =
1030  dma_vaddr_buff + ((2 * SUART_CNTX_SZ * i) + SUART_CNTX_SZ);
1031 
1032  soft_uart->suart_dma_addr[i].dma_phys_addr_tx =
1033  dma_phys_addr + (2 * SUART_CNTX_SZ * i);
1034 
1035  soft_uart->suart_dma_addr[i].dma_phys_addr_rx =
1036  dma_phys_addr + ((2 * SUART_CNTX_SZ * i) + SUART_CNTX_SZ);
1037 
1038  soft_uart->port[i].serial_out = NULL;
1039  /* SSC uart_add_one_port(&pru_suart_reg, &soft_uart->port[i]); */
1040 
1041  init_MUTEX(&soft_uart->port_sem[i]);
1042  }
1043  platform_set_drvdata(pdev, &soft_uart->port[0]);
1044 
1045 /*
1046  dev_info(&pdev->dev,
1047  "%s device registered"
1048  "(pru_clk=%d, asp_clk=%d)\n",
1049  DRV_NAME, soft_uart->clk_freq_pru, soft_uart->clk_freq_mcasp);
1050 */
1051  return 0;
1052 
1053 probe_release_fw:
1054  release_firmware(soft_uart->fw);
1055 probe_exit_clk:
1056  clk_put(soft_uart->clk_mcasp);
1057 probe_exit_clk_pru:
1058  clk_put(soft_uart->clk_pru);
1059 probe_exit_iounmap_4:
1060  iounmap(soft_uart->pru_arm_iomap.psc1_io_addr);
1061 probe_exit_iounmap_3:
1062  iounmap(soft_uart->pru_arm_iomap.psc0_io_addr);
1063 probe_exit_iounmap_2:
1064  iounmap(soft_uart->pru_arm_iomap.mcasp_io_addr);
1065 probe_exit_iounmap_1:
1066  iounmap(soft_uart->pru_arm_iomap.pru_io_addr);
1067 probe_exit_free_region:
1068  release_mem_region(res_mem[3]->start, resource_size(res_mem[3]));
1069 probe_exit_3:
1070  release_mem_region(res_mem[2]->start, resource_size(res_mem[2]));
1071 probe_exit_2:
1072  release_mem_region(res_mem[1]->start, resource_size(res_mem[1]));
1073 probe_exit_1:
1074  release_mem_region(res_mem[0]->start, resource_size(res_mem[0]));
1075 probe_exit:
1076  kfree(soft_uart);
1077  return err;
1078 }
1079 
1080 int __devexit omapl_pru_suart_remove(struct platform_device *pdev)
1081 {
1082  struct ti_pru_suart_platform_data *pdata;
1083  struct omapl_pru_suart *soft_uart = platform_get_drvdata(pdev);
1084  struct resource *res_mem[4];
1085  int i;
1086  u32 err = 0;
1087 
1088  __suart_debug("Enter omapl_pru_suart_remove\n");
1089 
1090  pdata = pdev->dev.platform_data;
1091  if (!pdata) {
1092  dev_err(&pdev->dev, "no platform data provided for pru!\n");
1093  return -ENODEV;
1094  }
1095  platform_set_drvdata(pdev, NULL);
1096 
1097  for (i = 0; i < 4; i++) {
1098  res_mem[i] = platform_get_resource(pdev, IORESOURCE_MEM, i);
1099  if (!res_mem[i]) {
1100  dev_err(&pdev->dev,
1101  "unable to get pru memory resources!\n");
1102  err = -ENODEV;
1103  }
1104  }
1105 
1106  /* SSC if (soft_uart) {
1107  for (i = 0; i < NR_SUART; i++) {
1108  uart_remove_one_port(&pru_suart_reg,
1109  &soft_uart->port[i]);
1110  }
1111  } */
1112 
1113  release_firmware(soft_uart->fw);
1114  clk_put(soft_uart->clk_mcasp);
1115  clk_put(soft_uart->clk_pru);
1116  pru_mcasp_deinit ();
1117  clk_disable(soft_uart->clk_mcasp);
1119  clk_disable(soft_uart->clk_pru);
1120  iounmap(soft_uart->pru_arm_iomap.mcasp_io_addr);
1121  iounmap(soft_uart->pru_arm_iomap.pru_io_addr);
1122  iounmap(soft_uart->pru_arm_iomap.psc0_io_addr);
1123  iounmap(soft_uart->pru_arm_iomap.psc1_io_addr);
1124  release_mem_region(res_mem[0]->start, resource_size(res_mem[0]));
1125  release_mem_region(res_mem[1]->start, resource_size(res_mem[1]));
1126  release_mem_region(res_mem[2]->start, resource_size(res_mem[2]));
1127  release_mem_region(res_mem[3]->start, resource_size(res_mem[3]));
1128  kfree(soft_uart);
1129  return err;
1130 }
1131 
1132 
1133 #define omapl_pru_suart_suspend NULL
1134 #define omapl_pru__suart_resume NULL
1135 
1136 
1137 static struct platform_driver serial_omapl_pru_driver = {
1138  .probe = omapl_pru_suart_probe,
1139  .remove = __devexit_p(omapl_pru_suart_remove),
1140  .suspend = omapl_pru_suart_suspend,
1141  .resume = omapl_pru__suart_resume,
1142  .driver = {
1143  .name = DRV_NAME,
1144  .owner = THIS_MODULE,
1145  },
1146 };
1147 
1148 
1149 
1151 {
1152  int ret;
1153 
1154  __suart_debug("SUART serial driver - integrated with d_uart - loaded\n");
1155 
1156  //pru_suart_reg.nr = NR_SUART;
1157  //ret = uart_register_driver(&pru_suart_reg);
1158  //if (ret)
1159  // return ret;
1160  ret = platform_driver_register(&serial_omapl_pru_driver);
1161  if (ret)
1162  goto out;
1163 
1164  return ret;
1165 out:
1166  //uart_unregister_driver(&pru_suart_reg);
1167  return ret;
1168 }
1169 
1170 
1171 // SSC module_init(pru_suart_init);
1172 
1174 {
1175 
1176  platform_driver_unregister(&serial_omapl_pru_driver);
1177  //uart_unregister_driver(&pru_suart_reg);
1178  iounmap(dma_vaddr_buff);
1179 
1180  __suart_debug("SUART serial driver unloaded\n");
1181 }
1182 
1183 // SSC module_exit(omapl_pru_suart_exit);
1184 
1185 
1187 {
1188  int retval = 0;
1189  struct circ_buf *buf;
1190  buf = &soft_uart->read_buf[port];
1191 
1192  if (!soft_uart->port_activated[port])
1193  {
1194  __ssc_debug("\n\n%i A: ", times++);
1195  retval = pru_suart_startup(&soft_uart->port[port],0);
1196  soft_uart->port_activated[port] = 1;
1197  soft_uart->search_for_first_byte[port] = 1;
1198  soft_uart->break_rcvt[port] = 0;
1199  soft_uart->sensor_inited[port] = 0;
1200 
1201  // When activating port flush buffer
1202  pru_softuart_clrRxFifo(soft_uart->suart_hdl);
1203  buf->head = 0;
1204  buf->tail = 0;
1205  }
1206 
1207  return retval;
1208 }
1209 
1210 
1212 {
1213  if (soft_uart->port_activated[port])
1214  {
1215  __ssc_debug("D");
1216  // Simulate calls from TTY implementation
1217  pru_suart_stop_tx(&soft_uart->port[port]);
1218  while (pru_suart_tx_empty(&soft_uart->port[port]) == 0);
1219 
1220  pru_suart_stop_rx(&soft_uart->port[port]);
1221 
1222  pru_suart_shutdown(&soft_uart->port[port],0);
1223  soft_uart->port_activated[port] = 0;
1224  }
1225 }
1226 
1227 
1228 int lego_pru_uart_init(int port)
1229 {
1230  soft_uart->port_activated[port] = 1;
1231 
1232  // Simulate calls from TTY implementation
1233  pru_suart_config_port(&soft_uart->port[port], UART_CONFIG_TYPE);
1234  // Call to pru_suart_type() omitted , since it doesn't do anything in this setup
1235  // Call to pru_suart_set_mctrl() omitted, since it doesn't do anything in this setup
1236 
1237  return pru_suart_startup(&soft_uart->port[port], 1);
1238 }
1239 
1240 void lego_pru_uart_exit(int port)
1241 {
1242  // Simulate calls from TTY implementation
1243  pru_suart_stop_tx(&soft_uart->port[port]);
1244  while (pru_suart_tx_empty(&soft_uart->port[port]) == 0);
1245  pru_suart_stop_rx(&soft_uart->port[port]);
1246  while (pru_suart_tx_empty(&soft_uart->port[port]) == 0);
1247  pru_suart_shutdown(&soft_uart->port[port],1);
1248 }
1249 
1250 void lego_pru_set_baudrate(int port, unsigned int baud)
1251 {
1252  struct ktermios config;
1253 
1254  if (baud != soft_uart->baud[port]) {
1255  soft_uart->baud[port] = baud;
1256 
1257  // http://www.delorie.com/gnu/docs/glibc/libc_362.html
1258  config.c_cflag = CS8 | CREAD;
1259 //TCP config.c_iflag = BRKINT;
1260  config.c_iflag = 0;
1261  config.c_oflag = 0;
1262  config.c_lflag = 0;
1263 
1264 /* From similar settings, but in TTY
1265  suart_debug: cflag=0x8bb
1266  suart_debug: iflag=0x0
1267  suart_debug: oflag=0x0
1268  suart_debug: lflag=0x80 */
1269 
1270  //__ssc_debug("BAUD %i", baud);
1271  pru_suart_set_termios(&soft_uart->port[port], &config, NULL, baud);
1272  }
1273 }
1274 
1276 {
1277  // Check if we have receive a break since last call
1278  if (soft_uart->break_rcvt[port])
1279  {
1280 // __ssc_debug("BR");
1281  soft_uart->break_rcvt[port] = 0;
1282  return 1;
1283  }
1284  else
1285  return 0;
1286 }
1287 
1288 int lego_pru_write_bytes(int port, unsigned char *pdata, int size)
1289 {
1290  struct circ_buf *buf;
1291  int space, index;
1292 
1293  buf = &soft_uart->write_buf[port];
1294 
1295  // Save data into transmit ring buffer
1296  space = CIRC_SPACE(buf->head, buf->tail, BUFFER_SIZE);
1297 
1298  if (space < size) size = space;
1299 
1300  for(index = 0; index < size; index++)
1301  {
1302  buf->buf[buf->head] = pdata[index];
1303  buf->head = (buf->head + 1) & BUFFER_MASK;
1304  }
1305 
1306  pru_suart_start_tx(&soft_uart->port[port]);
1307  soft_uart->sensor_inited[port] = 1;
1308  return size;
1309 }
1310 
1311 int lego_pru_read_bytes(int port, unsigned char *pdata, int size)
1312 {
1313  struct circ_buf *buf;
1314  int space, index;
1315 
1316  buf = &soft_uart->read_buf[port];
1317 
1318  // Deliver data from ring buffer
1319  space = CIRC_CNT(buf->head, buf->tail, BUFFER_SIZE);
1320 
1321  // Hack to avoid giving data until first 0x40 after activation of port
1322  // to upper layer SW. It seems like we can risk receiving a random number of
1323  // bytes initally. Most likely a number less that 16, which kind of fit the
1324  // buffer size used for communication with PRU. Why we receive this is however
1325  // a good question...
1326  //
1327  // Calling StopReceive in the stop_rx function above however minimizes/removes
1328  // this problem down to only and rather consistently receiving zero to two bytes
1329  //
1330  // Secondly it's not always the case that we receive a Break indication when a
1331  // sensor is inserted. Actually in like 9 out of 10 times we don't
1332  while (soft_uart->search_for_first_byte[port] && space) {
1333  if (buf->buf[buf->tail] == 0x40) {
1334  soft_uart->search_for_first_byte[port] = 0;
1335  } else {
1336  buf->tail = (buf->tail + 1) & BUFFER_MASK;
1337  space--;
1338  }
1339  }
1340 
1341  if (size > space) size = space;
1342 
1343  for(index = 0; index < size; index++)
1344  {
1345  pdata[index] = buf->buf[buf->tail];
1346  buf->tail = (buf->tail + 1) & BUFFER_MASK;
1347  }
1348 
1349  return size;
1350 }
1351 
1353 {
1354  struct circ_buf *buf;
1355  buf = &soft_uart->read_buf[port];
1356 
1357  return CIRC_CNT(buf->head, buf->tail, BUFFER_SIZE);
1358 }
1359 
1360 
1362 {
1363  // Just loop call direct to original PRU function
1364  return pru_suart_init();
1365 }
1366 
1368 {
1369  // Just loop call direct to original PRU function
1371 }
1372 
1373 // TODO: Interrupts keep comming when sensor is removed since break condition interrupt is enabled
#define PRU_SUART_UART1
Definition: suart_api.h:125
u8 write_data[NR_SUART][BUFFER_SIZE]
#define CHN_TXRX_IE_MASK_TIMEOUT
Definition: suart_api.h:70
#define PRU_SUART8_CONFIG_RX_SER
#define PRU_SUART3_CONFIG_TX_SER
#define PRU_SUART6_CONFIG_TX_SER
#define SUART_FIFO_TIMEOUT_MIN
arm_pru_iomap pru_arm_iomap
void pru_suart_set_mctrl(struct uart_port *port, unsigned int mctrl)
short pru_softuart_setdatabits(suart_handle hUart, unsigned short txDataBits, unsigned short rxDataBits)
Definition: suart_api.c:1005
#define CHN_TXRX_STATUS_RDY
Definition: suart_api.h:67
int lego_pru_uart_init(int port)
unsigned int pru_suart_tx_empty(struct uart_port *port)
#define SUART_GBL_INTR_ERR_MASK
Definition: suart_api.h:75
struct uart_port port[NR_SUART]
#define PRU_SUART_UART8
Definition: suart_api.h:140
uint8_t u8
Definition: common.h:160
short pru_softuart_init(unsigned int txBaudValue, unsigned int rxBaudValue, unsigned int oversampling, unsigned char *pru_suart_emu_code, unsigned int fw_size, arm_pru_iomap *pru_arm_iomap1)
Definition: suart_api.c:530
void pru_suart_stop_tx(struct uart_port *port)
#define PRU_SUART3_CONFIG_RX_SER
#define SUART_SUCCESS
Definition: suart_api.h:51
const struct firmware * fw
int __devinit omapl_pru_suart_probe(struct platform_device *pdev)
void * mcasp_io_addr
Definition: pru.h:112
void pru_set_fifo_timeout(Uint32 timeout)
Definition: suart_api.c:644
unsigned char Oversampling
Definition: suart_api.h:384
unsigned int pru_clk_freq
Definition: pru.h:118
void * pFifoBufferPhysBase
Definition: pru.h:116
int lego_pru_write_bytes(int port, unsigned char *pdata, int size)
unsigned char rxBitsPerChar
Definition: suart_api.h:383
int suart_pru_to_host_intr_enable(unsigned short uartNum, unsigned int txrxmode, int s32Flag)
Definition: suart_api.c:2772
#define PLATFORM_SUART_RES_SZ
u32 port_activated[NR_SUART]
#define omapl_pru_suart_suspend
#define PRU_SUART_UART6
Definition: suart_api.h:136
#define PRU_SUART1_CONFIG_RX_SER
int lego_pru_size_data_rx_buffer(int port)
short pru_softuart_close(suart_handle hUart)
Definition: suart_api.c:875
short pru_softuart_clrRxFifo(suart_handle hUart)
Definition: suart_api.c:2123
unsigned short rxClkDivisor
Definition: suart_api.h:381
#define PRU_SUART6_CONFIG_RX_SER
void lego_pru_uart_exit(int port)
struct suart_dma suart_dma_addr[NR_SUART]
void pru_suart_start_tx(struct uart_port *port)
#define PRU_SUART_UART5
Definition: suart_api.h:134
int pru_suart_verify_port(struct uart_port *port, struct serial_struct *ser)
short pru_softuart_getRxStatus(suart_handle hUart)
Definition: suart_api.c:2074
unsigned char RXSerializer
Definition: suart_api.h:378
#define CHN_TXRX_STATUS_FE
Definition: suart_api.h:62
#define __suart_debug(fmt, args...)
#define PRU_RX_INTR
Definition: suart_api.h:58
unsigned short txClkDivisor
Definition: suart_api.h:380
#define PRU_SUART2_CONFIG_RX_SER
int pru_intr_clr_isrstatus(unsigned short uartNum, unsigned int txrxmode)
Definition: suart_api.c:2352
void pru_suart_config_port(struct uart_port *port, int flags)
#define NR_SUART
int lego_pru_uart_get_break_state(int port)
void * psc0_io_addr
Definition: pru.h:113
#define CHN_TXRX_IE_MASK_CMPLT
Definition: suart_api.h:73
unsigned short uartNum
Definition: suart_api.h:395
void lego_pru_suart_exit(void)
dma_addr_t dma_phys_addr_tx
void pru_suart_release_port(struct uart_port *port)
int suart_intr_setmask(unsigned short uartNum, unsigned int txrxmode, unsigned int intrmask)
Definition: suart_api.c:2824
#define CHN_TXRX_STATUS_OVRNERR
Definition: suart_api.h:64
unsigned short uartType
Definition: suart_api.h:396
#define PRU_SUART4_CONFIG_RX_SER
#define PRU_SUART_UART3
Definition: suart_api.h:129
#define SUART_CNTX_SZ
void pru_suart_shutdown(struct uart_port *port, int exit)
void omapl_pru_suart_exit(void)
#define CHN_TXRX_IE_MASK_BI
Definition: suart_api.h:71
void * psc1_io_addr
Definition: pru.h:114
int lego_pru_uart_activate(int port)
short pru_softuart_open(suart_handle hSuart)
Definition: suart_api.c:722
uint16_t u16
Definition: common.h:159
struct omapl_pru_suart * soft_uart
#define BUFFER_SIZE
#define PRU_SUART_UART4
Definition: suart_api.h:132
#define PRU_SUART5_CONFIG_RX_SER
void pru_suart_set_termios(struct uart_port *port, struct ktermios *termios, struct ktermios *old, unsigned int baud)
#define CHN_TXRX_STATUS_BI
Definition: suart_api.h:61
#define omapl_pru__suart_resume
int __devexit omapl_pru_suart_remove(struct platform_device *pdev)
One line description of the structure.
Definition: suart_api.h:394
#define PRU_SUART2_CONFIG_TX_SER
#define SUART_FIFO_TIMEOUT_MAX
#define CHN_RX_IE_MASK_OVRN
Definition: suart_api.h:69
u8 read_data[NR_SUART][BUFFER_SIZE]
void lego_pru_uart_deactivate(int port)
#define PRU_SUART1_CONFIG_TX_SER
#define PRU_SUART_UART2
Definition: suart_api.h:127
MODULE_PARM_DESC(suart_timeout,"fifo timeout in milli seconds (min: 4; max: 500)")
module_param(suart_timeout, int, S_IRUGO)
void pru_suart_enable_ms(struct uart_port *port)
#define DRV_NAME
#define SUART_DEFAULT_BAUD
Definition: suart_api.h:87
short pru_softuart_getTxStatus(suart_handle hUart)
Definition: suart_api.c:1969
int pru_suart_init(void)
#define __suart_err(fmt, args...)
suart_struct_handle suart_hdl[NR_SUART]
#define PRU_SUART4_CONFIG_TX_SER
#define CHN_TXRX_STATUS_ERR
Definition: suart_api.h:65
int lego_pru_read_bytes(int port, unsigned char *pdata, int size)
struct circ_buf write_buf[NR_SUART]
#define PRU_SUART8_CONFIG_TX_SER
#define PRU_TX_INTR
Definition: suart_api.h:57
#define BUFFER_MASK
dma_addr_t dma_phys_addr_rx
short pru_softuart_read_data(suart_handle hUart, Uint8 *pDataBuffer, Int32 s32MaxLen, Uint32 *pu32DataRead)
Definition: suart_api.c:1753
#define SUART_DEFAULT_OVRSMPL
Definition: suart_api.h:82
void * syscfg_io_addr
Definition: pru.h:115
#define PRU_SUART7_CONFIG_RX_SER
int pru_suart_startup(struct uart_port *port, int init)
short pru_softuart_clrRxStatus(suart_handle hUart)
Definition: suart_api.c:2203
int suart_intr_clrmask(unsigned short uartNum, unsigned int txrxmode, unsigned int intrmask)
Definition: suart_api.c:2953
#define CHN_TXRX_IE_MASK_FE
Definition: suart_api.h:72
One line description of the structure.
Definition: suart_api.h:375
short pru_softuart_setconfig(suart_handle hUart, suart_config *configUart)
Definition: suart_api.c:1112
short pru_softuart_deinit(void)
Definition: suart_api.c:689
void * pru_io_addr
Definition: pru.h:111
short pru_softuart_get_isrstatus(unsigned short uartNum, unsigned short *txrxFlag)
Definition: suart_api.c:2262
#define PRU_SUART_SUCCESS
Definition: suart_err.h:26
uint32_t u32
Definition: common.h:158
#define PRU_SUART5_CONFIG_TX_SER
void pru_suart_break_ctl(struct uart_port *port, int break_state)
u8 search_for_first_byte[NR_SUART]
struct semaphore port_sem[NR_SUART]
#define PRU_SUART7_CONFIG_TX_SER
short pru_softuart_setbaud(suart_handle hUart, unsigned short txClkDivisor, unsigned short rxClkDivisor)
Definition: suart_api.c:894
short pru_softuart_read(suart_handle hUart, unsigned int *ptDataBuf, unsigned short dataLen)
Definition: suart_api.c:1664
unsigned char txBitsPerChar
Definition: suart_api.h:382
unsigned char TXSerializer
Definition: suart_api.h:376
void * pFifoBufferVirtBase
Definition: pru.h:117
short pru_softuart_stopReceive(suart_handle hUart)
Definition: suart_api.c:1899
void lego_pru_set_baudrate(int port, unsigned int baud)
#define PRU_SUART_UART7
Definition: suart_api.h:138
unsigned int pru_suart_get_mctrl(struct uart_port *port)
#define SUART_FIFO_LEN
Definition: suart_api.h:78
int pru_suart_request_port(struct uart_port *port)
#define __ssc_debug(fmt, args...)
#define SUART_FIFO_TIMEOUT_DFLT
void pru_mcasp_deinit(void)
Definition: suart_api.c:684
short pru_softuart_clrTxStatus(suart_handle hUart)
Definition: suart_api.c:2018
short pru_softuart_write(suart_handle hUart, unsigned int *ptTxDataBuf, unsigned short dataLen)
Definition: suart_api.c:1577
void pru_suart_stop_rx(struct uart_port *port)
int lego_pru_suart_init(void)
#define NULL
struct circ_buf read_buf[NR_SUART]