2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
16 * Copyright (C) 2006 infineon
17 * Copyright (C) 2007 John Crispin <blogic@openwrt.org>
21 // ### TO DO: general issues:
23 // - interrupt handling (direct/indirect)
24 // - pin/mux-handling (just overall concept due to project dependency)
25 // - multiple instances capability
26 // - slave functionality
28 #include <linux/module.h>
29 #include <linux/errno.h>
30 #include <linux/signal.h>
31 #include <linux/sched.h>
32 #include <linux/timer.h>
33 #include <linux/interrupt.h>
34 #include <linux/major.h>
35 #include <linux/string.h>
37 #include <linux/proc_fs.h>
38 #include <linux/fcntl.h>
39 #include <linux/ptrace.h>
41 #include <linux/ioport.h>
42 #include <linux/init.h>
43 #include <linux/delay.h>
44 #include <linux/spinlock.h>
45 #include <linux/slab.h>
47 #include <asm/system.h>
50 #include <asm/uaccess.h>
51 #include <asm/bitops.h>
53 #include <linux/types.h>
54 #include <linux/kernel.h>
55 #include <linux/version.h>
57 #include <asm/danube/danube.h>
58 #include <asm/danube/danube_irq.h>
59 #include <asm/danube/ifx_ssc_defines.h>
60 #include <asm/danube/ifx_ssc.h>
62 #ifdef SSC_FRAME_INT_ENABLE
63 #undef SSC_FRAME_INT_ENABLE
72 /* allow the user to set the major device number */
76 * This is the per-channel data structure containing pointers, flags
77 * and variables for the port. This driver supports a maximum of PORT_CNT.
78 * isp is allocated in ifx_ssc_init() based on the chip version.
80 static struct ifx_ssc_port
*isp
;
82 /* prototypes for fops */
83 static ssize_t
ifx_ssc_read (struct file
*, char *, size_t, loff_t
*);
84 static ssize_t
ifx_ssc_write (struct file
*, const char *, size_t, loff_t
*);
85 //static unsigned int ifx_ssc_poll(struct file *, struct poll_table_struct *);
86 int ifx_ssc_ioctl (struct inode
*, struct file
*, unsigned int,
88 int ifx_ssc_open (struct inode
*, struct file
*);
89 int ifx_ssc_close (struct inode
*, struct file
*);
91 /* other forward declarations */
92 static unsigned int ifx_ssc_get_kernel_clk (struct ifx_ssc_port
*info
);
93 static void ifx_ssc_rx_int (int, void *, struct pt_regs
*);
94 static void ifx_ssc_tx_int (int, void *, struct pt_regs
*);
95 static void ifx_ssc_err_int (int, void *, struct pt_regs
*);
96 #ifdef SSC_FRAME_INT_ENABLE
97 static void ifx_ssc_frm_int (int, void *, struct pt_regs
*);
99 static void tx_int (struct ifx_ssc_port
*);
100 static int ifx_ssc1_read_proc (char *, char **, off_t
, int, int *, void *);
101 static void ifx_gpio_init (void);
102 /************************************************************************
103 * Function declaration
104 ************************************************************************/
106 extern unsigned int danube_get_fpi_hz (void);
107 extern void disable_danube_irq (unsigned int irq_nr
);
108 extern void enable_danube_irq (unsigned int irq_nr
);
109 extern void mask_and_ack_danube_irq (unsigned int irq_nr
);
111 /*****************************************************************/
113 int (*request
) (unsigned int, irq_handler_t handler
,
114 unsigned long, const char *, void *);
115 void (*free
) (unsigned int irq
, void *dev_id
);
116 void (*enable
) (unsigned int irq
);
117 void (*disable
) (unsigned int irq
);
118 void (*clear
) (unsigned int irq
);
121 static ifx_int_wrapper_t ifx_int_wrapper
= {
122 request
:request_irq
, // IM action: enable int
123 free
:free_irq
, // IM action: disable int
124 enable
:enable_danube_irq
,
125 disable
:disable_danube_irq
,
126 clear
:mask_and_ack_danube_irq
,
131 static struct file_operations ifx_ssc_fops
= {
133 read
:ifx_ssc_read
, /* read */
134 write
:ifx_ssc_write
, /* write */
135 // poll: ifx_ssc_poll, /* poll */
136 ioctl
:ifx_ssc_ioctl
, /* ioctl */
137 open
:ifx_ssc_open
, /* open */
138 release
:ifx_ssc_close
, /* release */
141 static inline unsigned int
142 ifx_ssc_get_kernel_clk (struct ifx_ssc_port
*info
)
143 { // ATTENTION: This function assumes that the CLC register is set with the
144 // appropriate value for RMC.
147 rmc
= (READ_PERIPHERAL_REGISTER (info
->mapbase
+ IFX_SSC_CLC
) &
148 IFX_CLC_RUN_DIVIDER_MASK
) >> IFX_CLC_RUN_DIVIDER_OFFSET
;
150 printk ("ifx_ssc_get_kernel_clk rmc==0 \n");
153 return (danube_get_fpi_hz () / rmc
);
157 #ifdef IFX_SSC_INT_USE_BH
159 * This routine is used by the interrupt handler to schedule
160 * processing in the software interrupt portion of the driver
161 * (also known as the "bottom half"). This can be called any
162 * number of times for any channel without harm.
165 ifx_ssc_sched_event (struct ifx_ssc_port
*info
, int event
)
167 info
->event
|= 1 << event
; /* remember what kind of event and who */
168 queue_task (&info
->tqueue
, &tq_cyclades
); /* it belongs to */
169 mark_bh (CYCLADES_BH
); /* then trigger event */
170 } /* ifx_ssc_sched_event */
173 * This routine is used to handle the "bottom half" processing for the
174 * serial driver, known also the "software interrupt" processing.
175 * This processing is done at the kernel interrupt level, after the
176 * cy#/_interrupt() has returned, BUT WITH INTERRUPTS TURNED ON. This
177 * is where time-consuming activities which can not be done in the
178 * interrupt driver proper are done; the interrupt driver schedules
179 * them using ifx_ssc_sched_event(), and they get done here.
181 * This is done through one level of indirection--the task queue.
182 * When a hardware interrupt service routine wants service by the
183 * driver's bottom half, it enqueues the appropriate tq_struct (one
184 * per port) to the tq_cyclades work queue and sets a request flag
185 * via mark_bh for processing that queue. When the time is right,
186 * do_ifx_ssc_bh is called (because of the mark_bh) and it requests
187 * that the work queue be processed.
189 * Although this may seem unwieldy, it gives the system a way to
190 * pass an argument (in this case the pointer to the ifx_ssc_port
191 * structure) to the bottom half of the driver. Previous kernels
192 * had to poll every port to see if that port needed servicing.
197 run_task_queue (&tq_cyclades
);
198 } /* do_ifx_ssc_bh */
201 do_softint (void *private_
)
203 struct ifx_ssc_port
*info
= (struct ifx_ssc_port
*) private_
;
205 if (test_and_clear_bit (Cy_EVENT_HANGUP
, &info
->event
)) {
206 wake_up_interruptible (&info
->open_wait
);
207 info
->flags
&= ~(ASYNC_NORMAL_ACTIVE
| ASYNC_CALLOUT_ACTIVE
);
209 if (test_and_clear_bit (Cy_EVENT_OPEN_WAKEUP
, &info
->event
)) {
210 wake_up_interruptible (&info
->open_wait
);
212 if (test_and_clear_bit (Cy_EVENT_DELTA_WAKEUP
, &info
->event
)) {
213 wake_up_interruptible (&info
->delta_msr_wait
);
215 if (test_and_clear_bit (Cy_EVENT_WRITE_WAKEUP
, &info
->event
)) {
216 wake_up_interruptible (&tty
->write_wait
);
219 if (test_and_clear_bit (Cy_EVENT_SHUTDOWN_WAKEUP
, &info
->event
)) {
220 wake_up_interruptible (&info
->shutdown_wait
);
224 #endif /* IFX_SSC_INT_USE_BH */
228 rx_int (struct ifx_ssc_port
*info
)
230 int fifo_fill_lev
, bytes_in_buf
, i
;
231 unsigned long tmp_val
;
232 unsigned long *tmp_ptr
;
233 unsigned int rx_valid_cnt
;
234 /* number of words waiting in the RX FIFO */
235 fifo_fill_lev
= (READ_PERIPHERAL_REGISTER (info
->mapbase
+
237 IFX_SSC_FSTAT_RECEIVED_WORDS_MASK
) >>
238 IFX_SSC_FSTAT_RECEIVED_WORDS_OFFSET
;
239 // Note: There are always 32 bits in a fifo-entry except for the last
240 // word of a contigous transfer block and except for not in rx-only
241 // mode and CON.ENBV set. But for this case it should be a convention
242 // in software which helps:
243 // In tx or rx/tx mode all transfers from the buffer to the FIFO are
244 // 32-bit wide, except for the last three bytes, which could be a
245 // combination of 16- and 8-bit access.
246 // => The whole block is received as 32-bit words as a contigous stream,
247 // even if there was a gap in tx which has the fifo run out of data!
248 // Just the last fifo entry *may* be partially filled (0, 1, 2 or 3 bytes)!
250 /* free space in the RX buffer */
251 bytes_in_buf
= info
->rxbuf_end
- info
->rxbuf_ptr
;
252 // transfer with 32 bits per entry
253 while ((bytes_in_buf
>= 4) && (fifo_fill_lev
> 0)) {
254 tmp_ptr
= (unsigned long *) info
->rxbuf_ptr
;
256 READ_PERIPHERAL_REGISTER (info
->mapbase
+ IFX_SSC_RB
);
257 info
->rxbuf_ptr
+= 4;
258 info
->stats
.rxBytes
+= 4;
261 } // while ((bytes_in_buf >= 4) && (fifo_fill_lev > 0))
262 // now do the rest as mentioned in STATE.RXBV
263 while ((bytes_in_buf
> 0) && (fifo_fill_lev
> 0)) {
265 (READ_PERIPHERAL_REGISTER
267 IFX_SSC_STATE
) & IFX_SSC_STATE_RX_BYTE_VALID_MASK
)
268 >> IFX_SSC_STATE_RX_BYTE_VALID_OFFSET
;
269 if (rx_valid_cnt
== 0)
271 if (rx_valid_cnt
> bytes_in_buf
) {
272 // ### TO DO: warning message: not block aligned data, other data
273 // in this entry will be lost
274 rx_valid_cnt
= bytes_in_buf
;
277 READ_PERIPHERAL_REGISTER (info
->mapbase
+ IFX_SSC_RB
);
279 for (i
= 0; i
< rx_valid_cnt
; i
++) {
281 (tmp_val
>> (8 * (rx_valid_cnt
- i
- 1))) &
284 *info->rxbuf_ptr = tmp_val & 0xff;
291 info
->stats
.rxBytes
+= rx_valid_cnt
;
292 } // while ((bytes_in_buf > 0) && (fifo_fill_lev > 0))
294 // check if transfer is complete
295 if (info
->rxbuf_ptr
>= info
->rxbuf_end
) {
296 ifx_int_wrapper
.disable (info
->rxirq
);
297 /* wakeup any processes waiting in read() */
298 wake_up_interruptible (&info
->rwait
);
300 //wake_up_interruptible(&info->pwait);
302 else if ((info
->opts
.modeRxTx
== IFX_SSC_MODE_RX
) &&
303 (READ_PERIPHERAL_REGISTER (info
->mapbase
+ IFX_SSC_RXCNT
) ==
305 // if buffer not filled completely and rx request done initiate new transfer
307 if (info->rxbuf_end - info->rxbuf_ptr < 65536)
309 if (info
->rxbuf_end
- info
->rxbuf_ptr
<
310 IFX_SSC_RXREQ_BLOCK_SIZE
)
311 WRITE_PERIPHERAL_REGISTER ((info
->rxbuf_end
-
314 IFX_SSC_RXREQ_RXCOUNT_OFFSET
,
318 WRITE_PERIPHERAL_REGISTER (IFX_SSC_RXREQ_BLOCK_SIZE
<<
319 IFX_SSC_RXREQ_RXCOUNT_OFFSET
,
326 tx_int (struct ifx_ssc_port
*info
)
329 int fifo_space
, fill
, i
;
330 fifo_space
= ((READ_PERIPHERAL_REGISTER (info
->mapbase
+ IFX_SSC_ID
) &
331 IFX_SSC_PERID_TXFS_MASK
) >> IFX_SSC_PERID_TXFS_OFFSET
)
333 ((READ_PERIPHERAL_REGISTER (info
->mapbase
+ IFX_SSC_FSTAT
) &
334 IFX_SSC_FSTAT_TRANSMIT_WORDS_MASK
) >>
335 IFX_SSC_FSTAT_TRANSMIT_WORDS_OFFSET
);
340 fill
= info
->txbuf_end
- info
->txbuf_ptr
;
342 if (fill
> fifo_space
* 4)
343 fill
= fifo_space
* 4;
345 for (i
= 0; i
< fill
/ 4; i
++) {
346 // at first 32 bit access
347 WRITE_PERIPHERAL_REGISTER (*(UINT32
*) info
->txbuf_ptr
,
348 info
->mapbase
+ IFX_SSC_TB
);
349 info
->txbuf_ptr
+= 4;
352 fifo_space
-= fill
/ 4;
353 info
->stats
.txBytes
+= fill
& ~0x3;
355 if ((fifo_space
> 0) & (fill
> 1)) {
356 // trailing 16 bit access
357 WRITE_PERIPHERAL_REGISTER_16 (*(UINT16
*) info
->txbuf_ptr
,
358 info
->mapbase
+ IFX_SSC_TB
);
359 info
->txbuf_ptr
+= 2;
360 info
->stats
.txBytes
+= 2;
362 /* added by bingtao */
365 if ((fifo_space
> 0) & (fill
> 0)) {
366 // trailing 8 bit access
367 WRITE_PERIPHERAL_REGISTER_8 (*(UINT8
*) info
->txbuf_ptr
,
368 info
->mapbase
+ IFX_SSC_TB
);
370 info
->stats
.txBytes
++;
376 // check if transmission complete
377 if (info
->txbuf_ptr
>= info
->txbuf_end
) {
378 ifx_int_wrapper
.disable (info
->txirq
);
381 /* wake up any process waiting in poll() */
382 //wake_up_interruptible(&info->pwait);
388 ifx_ssc_rx_int (int irq
, void *dev_id
, struct pt_regs
*regs
)
390 struct ifx_ssc_port
*info
= (struct ifx_ssc_port
*) dev_id
;
391 //WRITE_PERIPHERAL_REGISTER(IFX_SSC_R_BIT, info->mapbase + IFX_SSC_IRN_CR);
396 ifx_ssc_tx_int (int irq
, void *dev_id
, struct pt_regs
*regs
)
398 struct ifx_ssc_port
*info
= (struct ifx_ssc_port
*) dev_id
;
399 //WRITE_PERIPHERAL_REGISTER(IFX_SSC_T_BIT, info->mapbase + IFX_SSC_IRN_CR);
404 ifx_ssc_err_int (int irq
, void *dev_id
, struct pt_regs
*regs
)
406 struct ifx_ssc_port
*info
= (struct ifx_ssc_port
*) dev_id
;
408 unsigned int write_back
= 0;
411 local_irq_save (flags
);
412 state
= READ_PERIPHERAL_REGISTER (info
->mapbase
+ IFX_SSC_STATE
);
414 if ((state
& IFX_SSC_STATE_RX_UFL
) != 0) {
415 info
->stats
.rxUnErr
++;
416 write_back
|= IFX_SSC_WHBSTATE_CLR_RX_UFL_ERROR
;
418 if ((state
& IFX_SSC_STATE_RX_OFL
) != 0) {
419 info
->stats
.rxOvErr
++;
420 write_back
|= IFX_SSC_WHBSTATE_CLR_RX_OFL_ERROR
;
422 if ((state
& IFX_SSC_STATE_TX_OFL
) != 0) {
423 info
->stats
.txOvErr
++;
424 write_back
|= IFX_SSC_WHBSTATE_CLR_TX_OFL_ERROR
;
426 if ((state
& IFX_SSC_STATE_TX_UFL
) != 0) {
427 info
->stats
.txUnErr
++;
428 write_back
|= IFX_SSC_WHBSTATE_CLR_TX_UFL_ERROR
;
430 // if ((state & IFX_SSC_STATE_ABORT_ERR) != 0) {
431 // info->stats.abortErr++;
432 // write_back |= IFX_SSC_WHBSTATE_CLR_ABORT_ERROR;
434 if ((state
& IFX_SSC_STATE_MODE_ERR
) != 0) {
435 info
->stats
.modeErr
++;
436 write_back
|= IFX_SSC_WHBSTATE_CLR_MODE_ERROR
;
440 WRITE_PERIPHERAL_REGISTER (write_back
,
441 info
->mapbase
+ IFX_SSC_WHBSTATE
);
443 local_irq_restore (flags
);
446 #ifdef SSC_FRAME_INT_ENABLE
448 ifx_ssc_frm_int (int irq
, void *dev_id
, struct pt_regs
*regs
)
450 // ### TO DO: wake up framing wait-queue in conjunction with batch execution
455 ifx_ssc_abort (struct ifx_ssc_port
*info
)
460 local_irq_save (flags
);
463 ifx_int_wrapper
.disable (info
->rxirq
);
464 ifx_int_wrapper
.disable (info
->txirq
);
465 ifx_int_wrapper
.disable (info
->errirq
);
467 ifx_int_wrapper.disable(info->frmirq);
469 local_irq_restore (flags
);
471 // disable SSC (also aborts a receive request!)
472 // ### TO DO: Perhaps it's better to abort after the receiption of a
473 // complete word. The disable cuts the transmission immediatly and
474 // releases the chip selects. This could result in unpredictable
475 // behavior of connected external devices!
476 enabled
= (READ_PERIPHERAL_REGISTER (info
->mapbase
+ IFX_SSC_STATE
)
477 & IFX_SSC_STATE_IS_ENABLED
) != 0;
478 WRITE_PERIPHERAL_REGISTER (IFX_SSC_WHBSTATE_CLR_ENABLE
,
479 info
->mapbase
+ IFX_SSC_WHBSTATE
);
482 WRITE_PERIPHERAL_REGISTER (IFX_SSC_XFCON_FIFO_FLUSH
,
483 info
->mapbase
+ IFX_SSC_TXFCON
);
484 WRITE_PERIPHERAL_REGISTER (IFX_SSC_XFCON_FIFO_FLUSH
,
485 info
->mapbase
+ IFX_SSC_RXFCON
);
488 if (info
->txbuf
!= NULL
) {
493 // wakeup read process
494 if (info
->rxbuf
!= NULL
)
495 wake_up_interruptible (&info
->rwait
);
497 // clear pending int's
498 ifx_int_wrapper
.clear (info
->rxirq
);
499 ifx_int_wrapper
.clear (info
->txirq
);
500 ifx_int_wrapper
.clear (info
->errirq
);
502 ifx_int_wrapper.clear(info->frmirq);
506 WRITE_PERIPHERAL_REGISTER (IFX_SSC_WHBSTATE_CLR_ALL_ERROR
,
507 info
->mapbase
+ IFX_SSC_WHBSTATE
);
509 //printk("IFX SSC%d: Transmission aborted\n", info->port_nr);
512 WRITE_PERIPHERAL_REGISTER (IFX_SSC_WHBSTATE_SET_ENABLE
,
513 info
->mapbase
+ IFX_SSC_WHBSTATE
);
518 * This routine is called whenever a port is opened. It enforces
519 * exclusive opening of a port and enables interrupts, etc.
522 ifx_ssc_open (struct inode
*inode
, struct file
*filp
)
524 struct ifx_ssc_port
*info
;
528 if ((inode
== (struct inode
*) 0) || (inode
== (struct inode
*) 1)) {
533 line
= MINOR (filp
->f_dentry
->d_inode
->i_rdev
);
534 filp
->f_op
= &ifx_ssc_fops
;
537 /* don't open more minor devices than we can support */
538 if (line
< 0 || line
>= PORT_CNT
)
544 if (info
->port_is_open
!= 0)
546 info
->port_is_open
++;
548 ifx_int_wrapper
.disable (info
->rxirq
);
549 ifx_int_wrapper
.disable (info
->txirq
);
550 ifx_int_wrapper
.disable (info
->errirq
);
552 ifx_int_wrapper.disable(info->frmirq);
555 /* Flush and enable TX/RX FIFO */
556 WRITE_PERIPHERAL_REGISTER ((IFX_SSC_DEF_TXFIFO_FL
<<
557 IFX_SSC_XFCON_ITL_OFFSET
) |
558 IFX_SSC_XFCON_FIFO_FLUSH
|
559 IFX_SSC_XFCON_FIFO_ENABLE
,
560 info
->mapbase
+ IFX_SSC_TXFCON
);
561 WRITE_PERIPHERAL_REGISTER ((IFX_SSC_DEF_RXFIFO_FL
<<
562 IFX_SSC_XFCON_ITL_OFFSET
) |
563 IFX_SSC_XFCON_FIFO_FLUSH
|
564 IFX_SSC_XFCON_FIFO_ENABLE
,
565 info
->mapbase
+ IFX_SSC_RXFCON
);
567 /* logically flush the software FIFOs */
571 /* clear all error bits */
572 WRITE_PERIPHERAL_REGISTER (IFX_SSC_WHBSTATE_CLR_ALL_ERROR
,
573 info
->mapbase
+ IFX_SSC_WHBSTATE
);
575 // clear pending interrupts
576 ifx_int_wrapper
.clear (info
->rxirq
);
577 ifx_int_wrapper
.clear (info
->txirq
);
578 ifx_int_wrapper
.clear (info
->errirq
);
580 ifx_int_wrapper.clear(info->frmirq);
584 WRITE_PERIPHERAL_REGISTER (IFX_SSC_WHBSTATE_SET_ENABLE
,
585 info
->mapbase
+ IFX_SSC_WHBSTATE
);
590 EXPORT_SYMBOL (ifx_ssc_open
);
593 * This routine is called when a particular device is closed.
596 ifx_ssc_close (struct inode
*inode
, struct file
*filp
)
598 struct ifx_ssc_port
*info
;
601 if ((inode
== (struct inode
*) 0) || (inode
== (struct inode
*) 1))
604 idx
= MINOR (filp
->f_dentry
->d_inode
->i_rdev
);
606 if (idx
< 0 || idx
>= PORT_CNT
)
614 WRITE_PERIPHERAL_REGISTER (IFX_SSC_WHBSTATE_CLR_ENABLE
,
615 info
->mapbase
+ IFX_SSC_WHBSTATE
);
617 // call abort function to disable int's, flush fifos...
618 ifx_ssc_abort (info
);
620 info
->port_is_open
--;
623 } /* ifx_ssc_close */
625 EXPORT_SYMBOL (ifx_ssc_close
);
627 /* added by bingtao */
628 /* helper routine to handle reads from the kernel or user-space */
629 /* info->rxbuf : never kfree and contains valid data */
630 /* should be points to NULL after copying data !!! */
632 ifx_ssc_read_helper_poll (struct ifx_ssc_port
*info
, char *buf
, size_t len
,
638 if (info
->opts
.modeRxTx
== IFX_SSC_MODE_TX
)
640 local_irq_save (flags
);
641 info
->rxbuf_ptr
= info
->rxbuf
;
642 info
->rxbuf_end
= info
->rxbuf
+ len
;
643 local_irq_restore (flags
);
644 /* Vinetic driver always works in IFX_SSC_MODE_RXTX */
645 /* TXRX in poll mode */
646 while (info
->rxbuf_ptr
< info
->rxbuf_end
) {
647 /* This is the key point, if you don't check this condition
648 kfree (NULL) will happen
649 because tx only need write into FIFO, it's much fast than rx
650 So when rx still waiting , tx already finish and release buf
652 if (info
->txbuf_ptr
< info
->txbuf_end
) {
659 ret_val
= info
->rxbuf_ptr
- info
->rxbuf
;
661 } // ifx_ssc_read_helper_poll
663 /* helper routine to handle reads from the kernel or user-space */
664 /* info->rx_buf : never kfree and contains valid data */
665 /* should be points to NULL after copying data !!! */
667 ifx_ssc_read_helper (struct ifx_ssc_port
*info
, char *buf
, size_t len
,
672 DECLARE_WAITQUEUE (wait
, current
);
674 if (info
->opts
.modeRxTx
== IFX_SSC_MODE_TX
)
676 local_irq_save (flags
);
677 info
->rxbuf_ptr
= info
->rxbuf
;
678 info
->rxbuf_end
= info
->rxbuf
+ len
;
679 if (info
->opts
.modeRxTx
== IFX_SSC_MODE_RXTX
) {
680 if ((info
->txbuf
== NULL
) ||
681 (info
->txbuf
!= info
->txbuf_ptr
) ||
682 (info
->txbuf_end
!= len
+ info
->txbuf
)) {
683 local_irq_restore (flags
);
684 printk ("IFX SSC - %s: write must be called before calling " "read in combined RX/TX!\n", __FUNCTION__
);
687 local_irq_restore (flags
);
688 /* should enable tx, right? */
690 if (info
->txbuf_ptr
< info
->txbuf_end
) {
691 ifx_int_wrapper
.enable (info
->txirq
);
694 ifx_int_wrapper
.enable (info
->rxirq
);
697 local_irq_restore (flags
);
698 if (READ_PERIPHERAL_REGISTER (info
->mapbase
+ IFX_SSC_RXCNT
) &
699 IFX_SSC_RXCNT_TODO_MASK
)
701 ifx_int_wrapper
.enable (info
->rxirq
);
702 // rx request limited to ' bytes
706 if (len
< IFX_SSC_RXREQ_BLOCK_SIZE
)
707 WRITE_PERIPHERAL_REGISTER (len
<<
708 IFX_SSC_RXREQ_RXCOUNT_OFFSET
,
712 WRITE_PERIPHERAL_REGISTER (IFX_SSC_RXREQ_BLOCK_SIZE
<<
713 IFX_SSC_RXREQ_RXCOUNT_OFFSET
,
718 __add_wait_queue (&info
->rwait
, &wait
);
719 set_current_state (TASK_INTERRUPTIBLE
);
720 // wakeup done in rx_int
723 local_irq_save (flags
);
724 if (info
->rxbuf_ptr
>= info
->rxbuf_end
)
726 local_irq_restore (flags
);
728 // if (filp->f_flags & O_NONBLOCK)
733 if (signal_pending (current
)) {
734 ret_val
= -ERESTARTSYS
;
740 ret_val
= info
->rxbuf_ptr
- info
->rxbuf
; // should be equal to len
741 local_irq_restore (flags
);
744 current
->state
= TASK_RUNNING
;
745 __remove_wait_queue (&info
->rwait
, &wait
);
747 } // ifx_ssc_read_helper
750 /* helper routine to handle reads from the kernel or user-space */
751 /* appropriate in interrupt context */
753 ifx_ssc_read_helper (struct ifx_ssc_port
*info
, char *buf
, size_t len
,
758 DECLARE_WAITQUEUE (wait
, current
);
760 if (info
->opts
.modeRxTx
== IFX_SSC_MODE_TX
)
762 local_irq_save (flags
);
763 info
->rxbuf_ptr
= info
->rxbuf
;
764 info
->rxbuf_end
= info
->rxbuf
+ len
;
765 if (info
->opts
.modeRxTx
== IFX_SSC_MODE_RXTX
) {
766 if ((info
->txbuf
== NULL
) ||
767 (info
->txbuf
!= info
->txbuf_ptr
) ||
768 (info
->txbuf_end
!= len
+ info
->txbuf
)) {
769 local_irq_restore (flags
);
770 printk ("IFX SSC - %s: write must be called before calling " "read in combined RX/TX!\n", __FUNCTION__
);
773 local_irq_restore (flags
);
774 /* should enable tx, right? */
777 if (info
->txbuf_ptr
< info
->txbuf_end
) {
778 ifx_int_wrapper
.enable (info
->txirq
);
780 ifx_int_wrapper
.enable (info
->rxirq
);
784 local_irq_restore (flags
);
785 if (READ_PERIPHERAL_REGISTER (info
->mapbase
+ IFX_SSC_RXCNT
) &
786 IFX_SSC_RXCNT_TODO_MASK
)
789 ifx_int_wrapper
.enable (info
->rxirq
);
792 if (len
< IFX_SSC_RXREQ_BLOCK_SIZE
)
793 WRITE_PERIPHERAL_REGISTER (len
<<
794 IFX_SSC_RXREQ_RXCOUNT_OFFSET
,
798 WRITE_PERIPHERAL_REGISTER (IFX_SSC_RXREQ_BLOCK_SIZE
<<
799 IFX_SSC_RXREQ_RXCOUNT_OFFSET
,
806 if (info
->opts
.modeRxTx
== IFX_SSC_MODE_RXTX
) {
810 if (info
->rxbuf_ptr
>= info
->rxbuf_end
)
813 ret_val
= info
->rxbuf_ptr
- info
->rxbuf
;
816 __add_wait_queue (&info
->rwait
, &wait
);
817 set_current_state (TASK_INTERRUPTIBLE
);
818 // wakeup done in rx_int
821 local_irq_save (flags
);
822 if (info
->rxbuf_ptr
>= info
->rxbuf_end
)
824 local_irq_restore (flags
);
826 if (signal_pending (current
)) {
827 ret_val
= -ERESTARTSYS
;
833 ret_val
= info
->rxbuf_ptr
- info
->rxbuf
; // should be equal to len
834 local_irq_restore (flags
);
837 current
->state
= TASK_RUNNING
;
838 __remove_wait_queue (&info
->rwait
, &wait
);
841 } // ifx_ssc_read_helper
844 /* helper routine to handle writes to the kernel or user-space */
845 /* info->txbuf has two cases:
846 * 1) return value < 0 (-EFAULT), not touched at all
847 * 2) kfree and points to NULL in interrupt routine (but maybe later )
850 ifx_ssc_write_helper (struct ifx_ssc_port
*info
, const char *buf
,
851 size_t len
, int from_kernel
)
853 // check if in tx or tx/rx mode
854 if (info
->opts
.modeRxTx
== IFX_SSC_MODE_RX
)
857 info
->txbuf_ptr
= info
->txbuf
;
858 info
->txbuf_end
= len
+ info
->txbuf
;
859 /* start the transmission (not in rx/tx, see read helper) */
860 if (info
->opts
.modeRxTx
== IFX_SSC_MODE_TX
) {
862 if (info
->txbuf_ptr
< info
->txbuf_end
) {
863 ifx_int_wrapper
.enable (info
->txirq
);
866 //local_irq_restore(flags);
871 * kernel interfaces for read and write.
872 * The caller must set port to: n for SSC<m> with n=m-1 (e.g. n=0 for SSC1)
875 ifx_ssc_kread (int port
, char *kbuf
, size_t len
)
877 struct ifx_ssc_port
*info
;
880 if (port
< 0 || port
>= PORT_CNT
)
888 // check if reception in progress
889 if (info
->rxbuf
!= NULL
) {
890 printk ("SSC device busy\n");
895 if (info
->rxbuf
== NULL
) {
896 printk ("SSC device error\n");
900 /* changed by bingtao */
901 /* change by TaiCheng */
904 ret_val
= ifx_ssc_read_helper (info
, kbuf
, len
, 1);
907 ret_val
= ifx_ssc_read_helper_poll (info
, kbuf
, len
, 1);
911 // ### TO DO: perhaps warn if ret_val != len
912 ifx_int_wrapper
.disable (info
->rxirq
);
917 EXPORT_SYMBOL (ifx_ssc_kread
);
920 ifx_ssc_kwrite (int port
, const char *kbuf
, size_t len
)
922 struct ifx_ssc_port
*info
;
925 if (port
< 0 || port
>= PORT_CNT
)
933 // check if transmission in progress
934 if (info
->txbuf
!= NULL
)
936 info
->txbuf
= (char *) kbuf
;
938 ret_val
= ifx_ssc_write_helper (info
, info
->txbuf
, len
, 1);
945 EXPORT_SYMBOL (ifx_ssc_kwrite
);
948 * user interfaces to read and write
951 ifx_ssc_read (struct file
*filp
, char *ubuf
, size_t len
, loff_t
* off
)
955 struct ifx_ssc_port
*info
;
961 idx
= MINOR (filp
->f_dentry
->d_inode
->i_rdev
);
964 // check if reception in progress
965 if (info
->rxbuf
!= NULL
)
968 info
->rxbuf
= kmalloc (len
+ 3, GFP_KERNEL
);
969 if (info
->rxbuf
== NULL
)
972 ret_val
= ifx_ssc_read_helper (info
, info
->rxbuf
, len
, 0);
973 // ### TO DO: perhaps warn if ret_val != len
974 if (copy_to_user ((void *) ubuf
, info
->rxbuf
, ret_val
) != 0)
977 ifx_int_wrapper
.disable (info
->rxirq
);
985 * As many bytes as we have free space for are copied from the user
986 * into txbuf and the actual byte count is returned. The transmission is
987 * always kicked off by calling the appropriate TX routine.
990 ifx_ssc_write (struct file
*filp
, const char *ubuf
, size_t len
, loff_t
* off
)
993 struct ifx_ssc_port
*info
;
999 idx
= MINOR (filp
->f_dentry
->d_inode
->i_rdev
);
1002 // check if transmission in progress
1003 if (info
->txbuf
!= NULL
)
1006 info
->txbuf
= kmalloc (len
+ 3, GFP_KERNEL
);
1007 if (info
->txbuf
== NULL
)
1010 ret_val
= copy_from_user (info
->txbuf
, ubuf
, len
);
1012 ret_val
= ifx_ssc_write_helper (info
, info
->txbuf
, len
, 0);
1016 kfree (info
->txbuf
); // otherwise will be done in ISR
1020 } /* ifx_ssc_write */
1023 * ------------------------------------------------------------
1024 * ifx_ssc_ioctl() and friends
1025 * ------------------------------------------------------------
1028 /*-----------------------------------------------------------------------------
1029 FUNC-NAME : ifx_ssc_frm_status_get
1030 LONG-NAME : framing status get
1031 PURPOSE : Get the actual status of the framing.
1033 PARAMETER : *info pointer to the port-specific structure ifx_ssc_port.
1035 RESULT : pointer to a structure ifx_ssc_frm_status which holds busy and
1038 REMARKS : Returns a register value independent of framing is enabled or
1039 not! Changes structure inside of info, so the return value isn't
1040 needed at all, but could be used for simple access.
1041 -----------------------------------------------------------------------------*/
1042 static struct ifx_ssc_frm_status
*
1043 ifx_ssc_frm_status_get (struct ifx_ssc_port
*info
)
1047 tmp
= READ_PERIPHERAL_REGISTER (info
->mapbase
+ IFX_SSC_SFSTAT
);
1048 info
->frm_status
.DataBusy
= (tmp
& IFX_SSC_SFSTAT_IN_DATA
) > 0;
1049 info
->frm_status
.PauseBusy
= (tmp
& IFX_SSC_SFSTAT_IN_PAUSE
) > 0;
1050 info
->frm_status
.DataCount
= (tmp
& IFX_SSC_SFSTAT_DATA_COUNT_MASK
)
1051 >> IFX_SSC_SFSTAT_DATA_COUNT_OFFSET
;
1052 info
->frm_status
.PauseCount
= (tmp
& IFX_SSC_SFSTAT_PAUSE_COUNT_MASK
)
1053 >> IFX_SSC_SFSTAT_PAUSE_COUNT_OFFSET
;
1054 tmp
= READ_PERIPHERAL_REGISTER (info
->mapbase
+ IFX_SSC_SFCON
);
1055 info
->frm_status
.EnIntAfterData
=
1056 (tmp
& IFX_SSC_SFCON_FIR_ENABLE_BEFORE_PAUSE
) > 0;
1057 info
->frm_status
.EnIntAfterPause
=
1058 (tmp
& IFX_SSC_SFCON_FIR_ENABLE_AFTER_PAUSE
) > 0;
1059 return (&info
->frm_status
);
1060 } // ifx_ssc_frm_status_get
1062 /*-----------------------------------------------------------------------------
1063 FUNC-NAME : ifx_ssc_frm_control_get
1064 LONG-NAME : framing control get
1065 PURPOSE : Get the actual control values of the framing.
1067 PARAMETER : *info pointer to the port-specific structure ifx_ssc_port.
1069 RESULT : pointer to a structure ifx_ssc_frm_opts which holds control bits
1070 and count reload values.
1072 REMARKS : Changes structure inside of info, so the return value isn't
1073 needed at all, but could be used for simple access.
1074 -----------------------------------------------------------------------------*/
1075 static struct ifx_ssc_frm_opts
*
1076 ifx_ssc_frm_control_get (struct ifx_ssc_port
*info
)
1080 tmp
= READ_PERIPHERAL_REGISTER (info
->mapbase
+ IFX_SSC_SFCON
);
1081 info
->frm_opts
.FrameEnable
= (tmp
& IFX_SSC_SFCON_SF_ENABLE
) > 0;
1082 info
->frm_opts
.DataLength
= (tmp
& IFX_SSC_SFCON_DATA_LENGTH_MASK
)
1083 >> IFX_SSC_SFCON_DATA_LENGTH_OFFSET
;
1084 info
->frm_opts
.PauseLength
= (tmp
& IFX_SSC_SFCON_PAUSE_LENGTH_MASK
)
1085 >> IFX_SSC_SFCON_PAUSE_LENGTH_OFFSET
;
1086 info
->frm_opts
.IdleData
= (tmp
& IFX_SSC_SFCON_PAUSE_DATA_MASK
)
1087 >> IFX_SSC_SFCON_PAUSE_DATA_OFFSET
;
1088 info
->frm_opts
.IdleClock
= (tmp
& IFX_SSC_SFCON_PAUSE_CLOCK_MASK
)
1089 >> IFX_SSC_SFCON_PAUSE_CLOCK_OFFSET
;
1090 info
->frm_opts
.StopAfterPause
=
1091 (tmp
& IFX_SSC_SFCON_STOP_AFTER_PAUSE
) > 0;
1092 return (&info
->frm_opts
);
1093 } // ifx_ssc_frm_control_get
1095 /*-----------------------------------------------------------------------------
1096 FUNC-NAME : ifx_ssc_frm_control_set
1097 LONG-NAME : framing control set
1098 PURPOSE : Set the actual control values of the framing.
1100 PARAMETER : *info pointer to the port-specific structure ifx_ssc_port.
1102 RESULT : pointer to a structure ifx_ssc_frm_opts which holds control bits
1103 and count reload values.
1106 -----------------------------------------------------------------------------*/
1108 ifx_ssc_frm_control_set (struct ifx_ssc_port
*info
)
1113 if ((info
->frm_opts
.DataLength
> IFX_SSC_SFCON_DATA_LENGTH_MAX
) ||
1114 (info
->frm_opts
.DataLength
< 1) ||
1115 (info
->frm_opts
.PauseLength
> IFX_SSC_SFCON_PAUSE_LENGTH_MAX
) ||
1116 (info
->frm_opts
.PauseLength
< 1) ||
1117 ((info
->frm_opts
.IdleData
& ~(IFX_SSC_SFCON_PAUSE_DATA_MASK
>>
1118 IFX_SSC_SFCON_PAUSE_DATA_OFFSET
)) !=
1122 IdleClock
& ~(IFX_SSC_SFCON_PAUSE_CLOCK_MASK
>>
1123 IFX_SSC_SFCON_PAUSE_CLOCK_OFFSET
)) != 0))
1126 // read interrupt bits (they're not changed here)
1127 tmp
= READ_PERIPHERAL_REGISTER (info
->mapbase
+ IFX_SSC_SFCON
) &
1128 (IFX_SSC_SFCON_FIR_ENABLE_BEFORE_PAUSE
|
1129 IFX_SSC_SFCON_FIR_ENABLE_AFTER_PAUSE
);
1131 // set all values with respect to it's bit position (for data and pause
1133 tmp
= (info
->frm_opts
.DataLength
-
1134 1) << IFX_SSC_SFCON_DATA_LENGTH_OFFSET
;
1135 tmp
|= (info
->frm_opts
.PauseLength
-
1136 1) << IFX_SSC_SFCON_PAUSE_LENGTH_OFFSET
;
1137 tmp
|= info
->frm_opts
.IdleData
<< IFX_SSC_SFCON_PAUSE_DATA_OFFSET
;
1138 tmp
|= info
->frm_opts
.IdleClock
<< IFX_SSC_SFCON_PAUSE_CLOCK_OFFSET
;
1139 tmp
|= info
->frm_opts
.FrameEnable
* IFX_SSC_SFCON_SF_ENABLE
;
1140 tmp
|= info
->frm_opts
.StopAfterPause
* IFX_SSC_SFCON_STOP_AFTER_PAUSE
;
1142 WRITE_PERIPHERAL_REGISTER (tmp
, info
->mapbase
+ IFX_SSC_SFCON
);
1145 } // ifx_ssc_frm_control_set
1147 /*-----------------------------------------------------------------------------
1148 FUNC-NAME : ifx_ssc_rxtx_mode_set
1149 LONG-NAME : rxtx mode set
1150 PURPOSE : Set the transmission mode.
1152 PARAMETER : *info pointer to the port-specific structure ifx_ssc_port.
1154 RESULT : Returns error code
1156 REMARKS : Assumes that SSC not used (SSC disabled, device not opened yet
1158 -----------------------------------------------------------------------------*/
1160 ifx_ssc_rxtx_mode_set (struct ifx_ssc_port
*info
, unsigned int val
)
1165 if (!(info
) || (val
& ~(IFX_SSC_MODE_MASK
)))
1167 /*check BUSY and RXCNT */
1168 if (READ_PERIPHERAL_REGISTER (info
->mapbase
+ IFX_SSC_STATE
) &
1170 || READ_PERIPHERAL_REGISTER (info
->mapbase
+
1172 IFX_SSC_RXCNT_TODO_MASK
)
1175 tmp
= (READ_PERIPHERAL_REGISTER (info
->mapbase
+ IFX_SSC_CON
) &
1176 ~(IFX_SSC_CON_RX_OFF
| IFX_SSC_CON_TX_OFF
)) | (val
);
1177 WRITE_PERIPHERAL_REGISTER (tmp
, info
->mapbase
+ IFX_SSC_CON
);
1178 info
->opts
.modeRxTx
= val
;
1180 printk(KERN_DEBUG "IFX SSC%d: Setting mode to %s%s\n",
1182 ((val & IFX_SSC_CON_RX_OFF) == 0) ? "rx ":"",
1183 ((val & IFX_SSC_CON_TX_OFF) == 0) ? "tx":"");
1186 } // ifx_ssc_rxtx_mode_set
1189 ifx_gpio_init (void)
1191 /* TODO: P0.9 SPI_CS4, P0.10 SPI_CS5, P 0.11 SPI_CS6, because of ASC0 */
1192 /* p0.15 SPI_CS1(EEPROM), P0.13 SPI_CS3, */
1193 /* Set p0.15 to alternative 01, others to 00 (In/OUT) */
1194 *(DANUBE_GPIO_P0_DIR
) = (*DANUBE_GPIO_P0_DIR
) | (0xA000);
1195 *(DANUBE_GPIO_P0_ALTSEL0
) =
1196 (((*DANUBE_GPIO_P0_ALTSEL0
) | (0x8000)) & (~(0x2000)));
1197 *(DANUBE_GPIO_P0_ALTSEL1
) =
1198 (((*DANUBE_GPIO_P0_ALTSEL1
) & (~0x8000)) & (~(0x2000)));
1199 *(DANUBE_GPIO_P0_OD
) = (*DANUBE_GPIO_P0_OD
) | 0xA000;
1201 /* p1.6 SPI_CS2(SFLASH), p1.0 SPI_DIN, p1.1 SPI_DOUT, p1.2 SPI_CLK */
1202 *(DANUBE_GPIO_P1_DIR
) = ((*DANUBE_GPIO_P1_DIR
) | (0x46)) & (~1);
1203 *(DANUBE_GPIO_P1_ALTSEL0
) = ((*DANUBE_GPIO_P1_ALTSEL0
) | (0x47));
1204 *(DANUBE_GPIO_P1_ALTSEL1
) = (*DANUBE_GPIO_P1_ALTSEL1
) & (~0x47);
1205 *(DANUBE_GPIO_P1_OD
) = (*DANUBE_GPIO_P1_OD
) | 0x0046;
1208 /*TODO: CS4 CS5 CS6 */
1209 *DANUBE_GPIO_P0_OUT
= ((*DANUBE_GPIO_P0_OUT
) | 0x2000);
1214 * This routine intializes the SSC appropriately depending
1215 * on slave/master and full-/half-duplex mode.
1216 * It assumes that the SSC is disabled and the fifo's and buffers
1217 * are flushes later on.
1220 ifx_ssc_sethwopts (struct ifx_ssc_port
*info
)
1222 unsigned long flags
, bits
;
1223 struct ifx_ssc_hwopts
*opts
= &info
->opts
;
1226 if ((opts
->dataWidth
< IFX_SSC_MIN_DATA_WIDTH
) ||
1227 (opts
->dataWidth
> IFX_SSC_MAX_DATA_WIDTH
)) {
1228 printk ("%s: sanity check failed\n", __FUNCTION__
);
1231 bits
= (opts
->dataWidth
- 1) << IFX_SSC_CON_DATA_WIDTH_OFFSET
;
1232 bits
|= IFX_SSC_CON_ENABLE_BYTE_VALID
;
1233 // if (opts->abortErrDetect)
1234 // bits |= IFX_SSC_CON_ABORT_ERR_CHECK;
1235 if (opts
->rxOvErrDetect
)
1236 bits
|= IFX_SSC_CON_RX_OFL_CHECK
;
1237 if (opts
->rxUndErrDetect
)
1238 bits
|= IFX_SSC_CON_RX_UFL_CHECK
;
1239 if (opts
->txOvErrDetect
)
1240 bits
|= IFX_SSC_CON_TX_OFL_CHECK
;
1241 if (opts
->txUndErrDetect
)
1242 bits
|= IFX_SSC_CON_TX_UFL_CHECK
;
1244 bits
|= IFX_SSC_CON_LOOPBACK_MODE
;
1246 bits
|= IFX_SSC_CON_ECHO_MODE_ON
;
1247 if (opts
->headingControl
)
1248 bits
|= IFX_SSC_CON_MSB_FIRST
;
1249 if (opts
->clockPhase
)
1250 bits
|= IFX_SSC_CON_LATCH_THEN_SHIFT
;
1251 if (opts
->clockPolarity
)
1252 bits
|= IFX_SSC_CON_CLOCK_FALL
;
1253 switch (opts
->modeRxTx
) {
1254 case IFX_SSC_MODE_TX
:
1255 bits
|= IFX_SSC_CON_RX_OFF
;
1257 case IFX_SSC_MODE_RX
:
1258 bits
|= IFX_SSC_CON_TX_OFF
;
1260 } // switch (opts->modeRxT)
1261 local_irq_save (flags
);
1262 WRITE_PERIPHERAL_REGISTER (bits
, info
->mapbase
+ IFX_SSC_CON
);
1263 WRITE_PERIPHERAL_REGISTER ((info
->opts
.
1264 gpoCs
<< IFX_SSC_GPOCON_ISCSB0_POS
) |
1266 gpoInv
<< IFX_SSC_GPOCON_INVOUT0_POS
),
1267 info
->mapbase
+ IFX_SSC_GPOCON
);
1268 /*TODO: disable cs */
1269 WRITE_PERIPHERAL_REGISTER (info
->opts
.
1270 gpoCs
<< IFX_SSC_WHBGPOSTAT_SETOUT0_POS
,
1271 info
->mapbase
+ IFX_SSC_WHBGPOSTAT
);
1274 if (opts
->masterSelect
) {
1275 WRITE_PERIPHERAL_REGISTER (IFX_SSC_WHBSTATE_SET_MASTER_SELECT
,
1276 info
->mapbase
+ IFX_SSC_WHBSTATE
);
1279 WRITE_PERIPHERAL_REGISTER (IFX_SSC_WHBSTATE_CLR_MASTER_SELECT
,
1280 info
->mapbase
+ IFX_SSC_WHBSTATE
);
1282 // init serial framing
1283 WRITE_PERIPHERAL_REGISTER (0, info
->mapbase
+ IFX_SSC_SFCON
);
1284 /* set up the port pins */
1285 //check for general requirements to switch (external) pad/pin characteristics
1287 local_irq_restore (flags
);
1290 } // ifx_ssc_sethwopts
1293 ifx_ssc_set_baud (struct ifx_ssc_port
*info
, unsigned int baud
)
1295 unsigned int ifx_ssc_clock
;
1297 unsigned long flags
;
1300 ifx_ssc_clock
= ifx_ssc_get_kernel_clk (info
);
1301 if (ifx_ssc_clock
== 0)
1303 local_irq_save (flags
);
1304 /* have to disable the SSC to set the baudrate */
1305 enabled
= (READ_PERIPHERAL_REGISTER (info
->mapbase
+ IFX_SSC_STATE
)
1306 & IFX_SSC_STATE_IS_ENABLED
) != 0;
1307 WRITE_PERIPHERAL_REGISTER (IFX_SSC_WHBSTATE_CLR_ENABLE
,
1308 info
->mapbase
+ IFX_SSC_WHBSTATE
);
1311 br
= (((ifx_ssc_clock
>> 1) + baud
/ 2) / baud
) - 1;
1315 ((READ_PERIPHERAL_REGISTER (info
->mapbase
+ IFX_SSC_STATE
) &
1316 IFX_SSC_STATE_IS_MASTER
) == 0))) {
1317 local_irq_restore (flags
);
1318 printk ("%s: illegal baudrate %u\n", __FUNCTION__
, baud
);
1321 WRITE_PERIPHERAL_REGISTER (br
, info
->mapbase
+ IFX_SSC_BR
);
1323 WRITE_PERIPHERAL_REGISTER (IFX_SSC_WHBSTATE_SET_ENABLE
,
1324 info
->mapbase
+ IFX_SSC_WHBSTATE
);
1326 local_irq_restore (flags
);
1328 } // ifx_ssc_set_baud
1331 ifx_ssc_hwinit (struct ifx_ssc_port
*info
)
1333 unsigned long flags
;
1336 /* have to disable the SSC */
1337 enabled
= (READ_PERIPHERAL_REGISTER (info
->mapbase
+ IFX_SSC_STATE
)
1338 & IFX_SSC_STATE_IS_ENABLED
) != 0;
1339 WRITE_PERIPHERAL_REGISTER (IFX_SSC_WHBSTATE_CLR_ENABLE
,
1340 info
->mapbase
+ IFX_SSC_WHBSTATE
);
1342 if (ifx_ssc_sethwopts (info
) < 0) {
1343 printk ("%s: setting the hardware options failed\n",
1348 if (ifx_ssc_set_baud (info
, info
->baud
) < 0) {
1349 printk ("%s: setting the baud rate failed\n", __FUNCTION__
);
1352 local_irq_save (flags
);
1354 WRITE_PERIPHERAL_REGISTER ((IFX_SSC_DEF_TXFIFO_FL
<<
1355 IFX_SSC_XFCON_ITL_OFFSET
) |
1356 IFX_SSC_XFCON_FIFO_ENABLE
,
1357 info
->mapbase
+ IFX_SSC_TXFCON
);
1359 WRITE_PERIPHERAL_REGISTER ((IFX_SSC_DEF_RXFIFO_FL
<<
1360 IFX_SSC_XFCON_ITL_OFFSET
) |
1361 IFX_SSC_XFCON_FIFO_ENABLE
,
1362 info
->mapbase
+ IFX_SSC_RXFCON
);
1363 local_irq_restore (flags
);
1365 WRITE_PERIPHERAL_REGISTER (IFX_SSC_WHBSTATE_SET_ENABLE
,
1366 info
->mapbase
+ IFX_SSC_WHBSTATE
);
1370 /*-----------------------------------------------------------------------------
1371 FUNC-NAME : ifx_ssc_batch_exec
1375 PARAMETER : *info pointer to the port-specific structure ifx_ssc_port.
1377 RESULT : Returns error code
1380 -----------------------------------------------------------------------------*/
1382 ifx_ssc_batch_exec (struct ifx_ssc_port
*info
,
1383 struct ifx_ssc_batch_list
*batch_anchor
)
1385 // ### TO DO: implement user space batch execution
1386 // first, copy the whole linked list from user to kernel space
1387 // save some hardware options
1389 // restore hardware options if selected
1391 } // ifx_ssc_batch_exec
1394 * This routine allows the driver to implement device-
1395 * specific ioctl's. If the ioctl number passed in cmd is
1396 * not recognized by the driver, it should return ENOIOCTLCMD.
1399 ifx_ssc_ioctl (struct inode
*inode
, struct file
*filp
, unsigned int cmd
,
1402 struct ifx_ssc_port
*info
;
1403 int line
, ret_val
= 0;
1404 unsigned long flags
;
1406 int from_kernel
= 0;
1408 if ((inode
== (struct inode
*) 0) || (inode
== (struct inode
*) 1)) {
1413 line
= MINOR (filp
->f_dentry
->d_inode
->i_rdev
);
1415 /* don't use more minor devices than we can support */
1416 if (line
< 0 || line
>= PORT_CNT
)
1422 case IFX_SSC_STATS_READ
:
1423 /* data must be a pointer to a struct ifx_ssc_statistics */
1425 memcpy ((void *) data
, (void *) &info
->stats
,
1426 sizeof (struct ifx_ssc_statistics
));
1427 else if (copy_to_user ((void *) data
,
1428 (void *) &info
->stats
,
1429 sizeof (struct ifx_ssc_statistics
)))
1432 case IFX_SSC_STATS_RESET
:
1433 /* just resets the statistics counters */
1434 memset ((void *) &info
->stats
, 0,
1435 sizeof (struct ifx_ssc_statistics
));
1437 case IFX_SSC_BAUD_SET
:
1438 /* if the buffers are not empty then the port is */
1439 /* busy and we shouldn't change things on-the-fly! */
1440 if (!info
->txbuf
|| !info
->rxbuf
||
1441 (READ_PERIPHERAL_REGISTER (info
->mapbase
+ IFX_SSC_STATE
)
1442 & IFX_SSC_STATE_BUSY
)) {
1448 flags
= *((unsigned long *) data
);
1449 else if (copy_from_user ((void *) &flags
,
1450 (void *) data
, sizeof (flags
))) {
1458 if (ifx_ssc_set_baud (info
, flags
) < 0) {
1464 case IFX_SSC_BAUD_GET
:
1466 *((unsigned int *) data
) = info
->baud
;
1467 else if (copy_to_user ((void *) data
,
1468 (void *) &info
->baud
,
1469 sizeof (unsigned long)))
1472 case IFX_SSC_RXTX_MODE_SET
:
1474 tmp
= *((unsigned long *) data
);
1475 else if (copy_from_user ((void *) &tmp
,
1476 (void *) data
, sizeof (tmp
))) {
1480 ret_val
= ifx_ssc_rxtx_mode_set (info
, tmp
);
1482 case IFX_SSC_RXTX_MODE_GET
:
1483 tmp
= READ_PERIPHERAL_REGISTER (info
->mapbase
+ IFX_SSC_CON
) &
1484 (~(IFX_SSC_CON_RX_OFF
| IFX_SSC_CON_TX_OFF
));
1486 *((unsigned int *) data
) = tmp
;
1487 else if (copy_to_user ((void *) data
,
1488 (void *) &tmp
, sizeof (tmp
)))
1493 ifx_ssc_abort (info
);
1496 case IFX_SSC_GPO_OUT_SET
:
1498 tmp
= *((unsigned long *) data
);
1499 else if (copy_from_user ((void *) &tmp
,
1500 (void *) data
, sizeof (tmp
))) {
1504 if (tmp
> IFX_SSC_MAX_GPO_OUT
)
1507 WRITE_PERIPHERAL_REGISTER
1508 (1 << (tmp
+ IFX_SSC_WHBGPOSTAT_SETOUT0_POS
),
1509 info
->mapbase
+ IFX_SSC_WHBGPOSTAT
);
1511 case IFX_SSC_GPO_OUT_CLR
:
1513 tmp
= *((unsigned long *) data
);
1514 else if (copy_from_user ((void *) &tmp
,
1515 (void *) data
, sizeof (tmp
))) {
1519 if (tmp
> IFX_SSC_MAX_GPO_OUT
)
1522 WRITE_PERIPHERAL_REGISTER
1523 (1 << (tmp
+ IFX_SSC_WHBGPOSTAT_CLROUT0_POS
),
1524 info
->mapbase
+ IFX_SSC_WHBGPOSTAT
);
1527 case IFX_SSC_GPO_OUT_GET
:
1528 tmp
= READ_PERIPHERAL_REGISTER
1529 (info
->mapbase
+ IFX_SSC_GPOSTAT
);
1531 *((unsigned int *) data
) = tmp
;
1532 else if (copy_to_user ((void *) data
,
1533 (void *) &tmp
, sizeof (tmp
)))
1536 case IFX_SSC_FRM_STATUS_GET
:
1537 ifx_ssc_frm_status_get (info
);
1539 memcpy ((void *) data
, (void *) &info
->frm_status
,
1540 sizeof (struct ifx_ssc_frm_status
));
1541 else if (copy_to_user ((void *) data
,
1542 (void *) &info
->frm_status
,
1543 sizeof (struct ifx_ssc_frm_status
)))
1546 case IFX_SSC_FRM_CONTROL_GET
:
1547 ifx_ssc_frm_control_get (info
);
1549 memcpy ((void *) data
, (void *) &info
->frm_opts
,
1550 sizeof (struct ifx_ssc_frm_opts
));
1551 else if (copy_to_user ((void *) data
,
1552 (void *) &info
->frm_opts
,
1553 sizeof (struct ifx_ssc_frm_opts
)))
1556 case IFX_SSC_FRM_CONTROL_SET
:
1558 memcpy ((void *) &info
->frm_opts
, (void *) data
,
1559 sizeof (struct ifx_ssc_frm_opts
));
1560 else if (copy_to_user ((void *) &info
->frm_opts
,
1562 sizeof (struct ifx_ssc_frm_opts
))) {
1566 ret_val
= ifx_ssc_frm_control_set (info
);
1568 case IFX_SSC_HWOPTS_SET
:
1569 /* data must be a pointer to a struct ifx_ssc_hwopts */
1570 /* if the buffers are not empty then the port is */
1571 /* busy and we shouldn't change things on-the-fly! */
1572 if (!info
->txbuf
|| !info
->rxbuf
||
1573 (READ_PERIPHERAL_REGISTER (info
->mapbase
+ IFX_SSC_STATE
)
1574 & IFX_SSC_STATE_BUSY
)) {
1579 memcpy ((void *) &info
->opts
, (void *) data
,
1580 sizeof (struct ifx_ssc_hwopts
));
1581 else if (copy_from_user ((void *) &info
->opts
,
1583 sizeof (struct ifx_ssc_hwopts
))) {
1587 if (ifx_ssc_hwinit (info
) < 0) {
1591 case IFX_SSC_HWOPTS_GET
:
1592 /* data must be a pointer to a struct ifx_ssc_hwopts */
1594 memcpy ((void *) data
, (void *) &info
->opts
,
1595 sizeof (struct ifx_ssc_hwopts
));
1596 else if (copy_to_user ((void *) data
,
1597 (void *) &info
->opts
,
1598 sizeof (struct ifx_ssc_hwopts
)))
1602 ret_val
= -ENOIOCTLCMD
;
1606 } /* ifx_ssc_ioctl */
1608 EXPORT_SYMBOL (ifx_ssc_ioctl
);
1610 ///* the poll routine */
1611 //static unsigned int
1612 //ifx_ssc_poll(struct file *filp, struct poll_table_struct *pts)
1614 // int unit = MINOR(filp->f_dentry->d_inode->i_rdev);
1615 // struct ifx_ssc_port *info;
1616 // unsigned int mask = 0;
1619 // info = &isp[unit];
1621 // /* add event to the wait queues */
1622 // /* DO NOT FORGET TO DO A WAKEUP ON THESE !!!! */
1623 // poll_wait(filp, &info->pwait, pts);
1625 // /* are there bytes in the RX SW-FIFO? */
1626 // if (info->rxrp != info->rxwp)
1627 // mask |= POLLIN | POLLRDNORM;
1629 // /* free space in the TX SW-FIFO */
1630 // spc = info->txrp - info->txwp - 1;
1632 // spc += TX_BUFSIZE;
1633 //#ifdef IFX_SSC_USEDMA
1634 // /* writing always works, except in the DMA case when all descriptors */
1635 // /* are used up */
1636 // if (unit == 1 && info->dma_freecnt == 0)
1640 // mask |= POLLOUT | POLLWRNORM;
1646 ifx_ssc1_read_proc (char *page
, char **start
, off_t offset
, int count
,
1647 int *eof
, void *data
)
1650 unsigned long flags
;
1652 /* don't want any interrupts here */
1653 local_save_flags(flags
);
1654 local_irq_disable();
1656 /* print statistics */
1657 off
+= sprintf (page
+ off
,
1658 "Statistics for Infineon Synchronous Serial Controller SSC1\n");
1659 off
+= sprintf (page
+ off
, "RX overflow errors %d\n",
1660 isp
[0].stats
.rxOvErr
);
1661 off
+= sprintf (page
+ off
, "RX underflow errors %d\n",
1662 isp
[0].stats
.rxUnErr
);
1663 off
+= sprintf (page
+ off
, "TX overflow errors %d\n",
1664 isp
[0].stats
.txOvErr
);
1665 off
+= sprintf (page
+ off
, "TX underflow errors %d\n",
1666 isp
[0].stats
.txUnErr
);
1667 off
+= sprintf (page
+ off
, "Abort errors %d\n",
1668 isp
[0].stats
.abortErr
);
1669 off
+= sprintf (page
+ off
, "Mode errors %d\n", isp
[0].stats
.modeErr
);
1670 off
+= sprintf (page
+ off
, "RX Bytes %d\n", isp
[0].stats
.rxBytes
);
1671 off
+= sprintf (page
+ off
, "TX Bytes %d\n", isp
[0].stats
.txBytes
);
1673 local_irq_restore(flags
); /* XXXXX */
1679 * This routine prints out the appropriate serial driver version number
1685 printk ("Infineon Technologies Synchronous Serial Controller (SSC) driver\n" " version %s - built %s %s\n", IFX_SSC_DRV_VERSION
, __DATE__
, __TIME__
);
1687 } /* show_version */
1690 * Due to the fact that a port can be dynamically switched between slave
1691 * and master mode using an IOCTL the hardware is not initialized here,
1692 * but in ifx_ssc_hwinit() as a result of an IOCTL.
1697 struct ifx_ssc_port
*info
;
1699 unsigned long flags
;
1702 // ### TO DO: dynamic port count evaluation due to pin multiplexing
1705 nbytes
= PORT_CNT
* sizeof (struct ifx_ssc_port
);
1706 isp
= (struct ifx_ssc_port
*) kmalloc (nbytes
, GFP_KERNEL
);
1708 printk ("%s: no memory for isp\n", __FUNCTION__
);
1711 memset (isp
, 0, nbytes
);
1715 /* register the device */
1720 if ((i
= register_chrdev (maj
, "ssc", &ifx_ssc_fops
)) < 0) {
1721 printk ("Unable to register major %d for the Infineon SSC\n",
1729 register_chrdev (maj
, "ssc",
1730 &ifx_ssc_fops
)) < 0) {
1731 printk ("Unable to register major %d for the Infineon SSC\n", maj
);
1738 //printk("registered major %d for Infineon SSC\n", maj);
1740 /* set default values in ifx_ssc_port */
1741 for (i
= 0; i
< PORT_CNT
; i
++) {
1744 /* default values for the HwOpts */
1745 info
->opts
.AbortErrDetect
= IFX_SSC_DEF_ABRT_ERR_DETECT
;
1746 info
->opts
.rxOvErrDetect
= IFX_SSC_DEF_RO_ERR_DETECT
;
1747 info
->opts
.rxUndErrDetect
= IFX_SSC_DEF_RU_ERR_DETECT
;
1748 info
->opts
.txOvErrDetect
= IFX_SSC_DEF_TO_ERR_DETECT
;
1749 info
->opts
.txUndErrDetect
= IFX_SSC_DEF_TU_ERR_DETECT
;
1750 info
->opts
.loopBack
= IFX_SSC_DEF_LOOP_BACK
;
1751 info
->opts
.echoMode
= IFX_SSC_DEF_ECHO_MODE
;
1752 info
->opts
.idleValue
= IFX_SSC_DEF_IDLE_DATA
;
1753 info
->opts
.clockPolarity
= IFX_SSC_DEF_CLOCK_POLARITY
;
1754 info
->opts
.clockPhase
= IFX_SSC_DEF_CLOCK_PHASE
;
1755 info
->opts
.headingControl
= IFX_SSC_DEF_HEADING_CONTROL
;
1756 info
->opts
.dataWidth
= IFX_SSC_DEF_DATA_WIDTH
;
1757 info
->opts
.modeRxTx
= IFX_SSC_DEF_MODE_RXTX
;
1758 info
->opts
.gpoCs
= IFX_SSC_DEF_GPO_CS
;
1759 info
->opts
.gpoInv
= IFX_SSC_DEF_GPO_INV
;
1760 info
->opts
.masterSelect
= IFX_SSC_DEF_MASTERSLAVE
;
1761 info
->baud
= IFX_SSC_DEF_BAUDRATE
;
1764 /* values specific to SSC1 */
1766 info
->mapbase
= DANUBE_SSC1_BASE_ADDR
;
1767 // ### TO DO: power management
1769 // setting interrupt vectors
1770 info
->txirq
= DANUBE_SSC_TIR
;
1771 info
->rxirq
= DANUBE_SSC_RIR
;
1772 info
->errirq
= DANUBE_SSC_EIR
;
1774 info->frmirq = IFX_SSC_FIR;
1779 WRITE_PERIPHERAL_REGISTER (IFX_SSC_DEF_RMC
<<
1780 IFX_CLC_RUN_DIVIDER_OFFSET
,
1781 info
->mapbase
+ IFX_SSC_CLC
);
1783 // ### TO DO: multiple instances
1785 init_waitqueue_head (&info
->rwait
);
1786 //init_waitqueue_head(&info->pwait);
1788 local_irq_save (flags
);
1790 // init serial framing register
1791 WRITE_PERIPHERAL_REGISTER (IFX_SSC_DEF_SFCON
,
1792 info
->mapbase
+ IFX_SSC_SFCON
);
1794 /* try to get the interrupts */
1795 // ### TO DO: interrupt handling with multiple instances
1797 ifx_int_wrapper
.request (info
->txirq
, ifx_ssc_tx_int
, SA_INTERRUPT
, "ifx_ssc_tx", info
);
1799 printk ("%s: unable to get irq %d\n", __FUNCTION__
,
1801 local_irq_restore (flags
);
1805 ifx_int_wrapper
.request (info
->rxirq
, ifx_ssc_rx_int
, SA_INTERRUPT
, "ifx_ssc_rx", info
);
1807 printk ("%s: unable to get irq %d\n", __FUNCTION__
,
1809 local_irq_restore (flags
);
1813 ifx_int_wrapper
.request (info
->errirq
, ifx_ssc_err_int
, SA_INTERRUPT
,"ifx_ssc_err", info
);
1815 printk ("%s: unable to get irq %d\n", __FUNCTION__
,
1817 local_irq_restore (flags
);
1821 ret_val = ifx_int_wrapper.request(info->frmirq, ifx_ssc_frm_int,
1822 0, "ifx_ssc_frm", info);
1824 printk("%s: unable to get irq %d\n", __FUNCTION__,
1826 local_irq_restore(flags);
1831 WRITE_PERIPHERAL_REGISTER (IFX_SSC_DEF_IRNEN
,
1832 info
->mapbase
+ IFX_SSC_IRN_EN
);
1833 ifx_int_wrapper
.enable (info
->txirq
);
1834 ifx_int_wrapper
.enable (info
->rxirq
);
1835 ifx_int_wrapper
.enable (info
->errirq
);
1837 local_irq_restore (flags
);
1838 } // for (i = 0; i < PORT_CNT; i++)
1840 /* init the SSCs with default values */
1841 for (i
= 0; i
< PORT_CNT
; i
++) {
1843 if (ifx_ssc_hwinit (info
) < 0) {
1844 printk ("%s: hardware init failed for port %d\n",
1850 /* register /proc read handler */
1851 // ### TO DO: multiple instances
1852 /* for SSC1, which is always present */
1853 create_proc_read_entry ("driver/ssc1", 0, NULL
, ifx_ssc1_read_proc
,
1858 // ### TO DO: multiple instances
1859 ifx_int_wrapper
.free (isp
[0].txirq
, &isp
[0]);
1860 ifx_int_wrapper
.free (isp
[0].rxirq
, &isp
[0]);
1861 ifx_int_wrapper
.free (isp
[0].errirq
, &isp
[0]);
1863 ifx_int_wrapper.free(isp[0].frmirq, &isp[0]);
1866 /* free up any allocated memory in the error case */
1869 } /* ifx_ssc_init */
1872 ifx_ssc_cleanup_module (void)
1876 /* free up any allocated memory */
1877 for (i
= 0; i
< PORT_CNT
; i
++) {
1878 /* disable the SSC */
1879 WRITE_PERIPHERAL_REGISTER (IFX_SSC_WHBSTATE_CLR_ENABLE
,
1880 isp
[i
].mapbase
+ IFX_SSC_WHBSTATE
);
1881 /* free the interrupts */
1882 ifx_int_wrapper
.free (isp
[i
].txirq
, &isp
[i
]);
1883 ifx_int_wrapper
.free (isp
[i
].rxirq
, &isp
[i
]);
1884 ifx_int_wrapper
.free (isp
[i
].errirq
, &isp
[i
]);
1886 ifx_int_wrapper.free(isp[i].frmirq, &isp[i]);
1888 if (isp[i].rxbuf != NULL)
1889 kfree(isp[i].rxbuf);
1890 if (isp[i].txbuf != NULL)
1891 kfree(isp[i].txbuf);
1895 /* unregister the device */
1896 // if (unregister_chrdev (maj, "ssc")) {
1897 // printk ("Unable to unregister major %d for the SSC\n", maj);
1899 /* delete /proc read handler */
1900 remove_proc_entry ("driver/ssc1", NULL
);
1901 remove_proc_entry ("driver/ssc2", NULL
);
1902 } /* ifx_ssc_cleanup_module */
1904 module_exit (ifx_ssc_cleanup_module
);
1906 /* Module entry-points */
1907 module_init (ifx_ssc_init
);
1911 ifx_ssc_set_maj (char *str
)
1913 maj
= simple_strtol (str
, NULL
, 0);
1917 __setup ("ssc_maj=", ifx_ssc_set_maj
);
1918 #endif /* !MODULE */
1920 #define DANUBE_SSC_EMSG(fmt,arg...) printk("%s: "fmt,__FUNCTION__, ##arg)
1921 /* Brief: chip select enable
1924 ifx_ssc_cs_low (u32 pin
)
1928 ifx_ssc_ioctl ((struct inode
*) 0, NULL
, IFX_SSC_GPO_OUT_CLR
,
1929 (unsigned long) &pin
))) {
1930 DANUBE_SSC_EMSG ("clear CS %d fails\n", pin
);
1936 EXPORT_SYMBOL (ifx_ssc_cs_low
);
1937 /* Brief: chip select disable
1940 ifx_ssc_cs_high (u32 pin
)
1944 ifx_ssc_ioctl ((struct inode
*) 0, NULL
, IFX_SSC_GPO_OUT_SET
,
1945 (unsigned long) &pin
))) {
1946 DANUBE_SSC_EMSG ("set CS %d fails\n", pin
);
1952 EXPORT_SYMBOL (ifx_ssc_cs_high
);
1953 /* Brief: one SSC session
1959 * session_mode: IFX_SSC_MODE_RXTX or IFX_SSC_MODE_TX
1960 * Return: >=0 number of bytes received (if rx_buf != 0) or transmitted
1963 * 0. copy data to internal buffer
1965 * 2a. If SSC_SESSION_MODE_TXONLY, read tx_len data
1966 * 2b. If not Read back (tx_len + rx_len) data
1967 * 3. copy internal buffer to rx buf if necessary
1970 ssc_session (char *tx_buf
, u32 tx_len
, char *rx_buf
, u32 rx_len
)
1974 char *ssc_tx_buf
= NULL
;
1975 char *ssc_rx_buf
= NULL
;
1977 // volatile char ssc_tx_buf[128]={0};
1978 // volatile char ssc_rx_buf[128]={0};
1983 if (tx_buf
== NULL
&& tx_len
== 0 && rx_buf
== NULL
&& rx_len
== 0) {
1984 DANUBE_SSC_EMSG ("invalid parameters\n");
1986 goto ssc_session_exit
;
1988 else if (tx_buf
== NULL
|| tx_len
== 0) {
1989 if (rx_buf
!= NULL
&& rx_len
!= 0) {
1990 mode
= IFX_SSC_MODE_RX
;
1993 DANUBE_SSC_EMSG ("invalid parameters\n");
1995 goto ssc_session_exit
;
1998 else if (rx_buf
== NULL
|| rx_len
== 0) {
1999 if (tx_buf
!= NULL
&& tx_len
!= 0) {
2000 mode
= IFX_SSC_MODE_TX
;
2003 DANUBE_SSC_EMSG ("invalid parameters\n");
2005 goto ssc_session_exit
;
2009 mode
= IFX_SSC_MODE_RXTX
;
2012 if (mode
== IFX_SSC_MODE_RXTX
) {
2013 eff_size
= tx_len
+ rx_len
;
2015 else if (mode
== IFX_SSC_MODE_RX
) {
2022 //4 bytes alignment, required by driver
2023 /* change by TaiCheng */
2027 (char *) kmalloc (sizeof (char) *
2028 ((eff_size
+ 3) & (~3)),
2031 (char *) kmalloc (sizeof (char) *
2032 ((eff_size
+ 3) & (~3)),
2037 (char *) kmalloc (sizeof (char) *
2038 ((eff_size
+ 3) & (~3)),
2041 (char *) kmalloc (sizeof (char) *
2042 ((eff_size
+ 3) & (~3)),
2045 if (ssc_tx_buf
== NULL
|| ssc_rx_buf
== NULL
) {
2046 DANUBE_SSC_EMSG ("no memory for size of %d\n", eff_size
);
2048 goto ssc_session_exit
;
2050 memset ((void *) ssc_tx_buf
, 0, eff_size
);
2051 memset ((void *) ssc_rx_buf
, 0, eff_size
);
2054 memcpy (ssc_tx_buf
, tx_buf
, tx_len
);
2057 ret
= ifx_ssc_kwrite (0, ssc_tx_buf
, eff_size
);
2060 ssc_tx_buf
= NULL
; //should be freed by ifx_ssc_kwrite
2063 if (ret
!= eff_size
) {
2064 DANUBE_SSC_EMSG ("ifx_ssc_write return %d\n", ret
);
2065 goto ssc_session_exit
;
2067 ret
= ifx_ssc_kread (0, ssc_rx_buf
, eff_size
);
2068 if (ret
!= eff_size
) {
2069 DANUBE_SSC_EMSG ("ifx_ssc_read return %d\n", ret
);
2070 goto ssc_session_exit
;
2073 memcpy (rx_buf
, ssc_rx_buf
+ tx_len
, rx_len
);
2075 if (mode
== IFX_SSC_MODE_TX
) {
2083 if (ssc_tx_buf
!= NULL
)
2085 if (ssc_rx_buf
!= NULL
)
2089 printk ("ssc session fails\n");
2094 /* Brief: TX-RX session
2100 * Return: >=0 number of bytes received
2107 ifx_ssc_txrx (char *tx_buf
, u32 tx_len
, char *rx_buf
, u32 rx_len
)
2109 return ssc_session (tx_buf
, tx_len
, rx_buf
, rx_len
);
2112 EXPORT_SYMBOL (ifx_ssc_txrx
);
2113 /* Brief: TX only session
2117 * Return: >=0 number of bytes transmitted
2121 ifx_ssc_tx (char *tx_buf
, u32 tx_len
)
2123 return ssc_session (tx_buf
, tx_len
, NULL
, 0);
2126 EXPORT_SYMBOL (ifx_ssc_tx
);
2127 /* Brief: RX only session
2131 * Return: >=0 number of bytes received
2135 ifx_ssc_rx (char *rx_buf
, u32 rx_len
)
2137 return ssc_session (NULL
, 0, rx_buf
, rx_len
);
2140 EXPORT_SYMBOL (ifx_ssc_rx
);
2142 MODULE_LICENSE("GPL");
2143 MODULE_AUTHOR("John Crispin <blogic@openwrt.org>");
2144 MODULE_DESCRIPTION("danube ssc driver");