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 tx_int (struct ifx_ssc_port
*);
94 static int ifx_ssc1_read_proc (char *, char **, off_t
, int, int *, void *);
96 extern unsigned int danube_get_fpi_hz (void);
97 extern void mask_and_ack_danube_irq (unsigned int irq_nr
);
99 static struct file_operations ifx_ssc_fops
= {
100 .owner
= THIS_MODULE
,
101 .read
= ifx_ssc_read
,
102 .write
= ifx_ssc_write
,
103 .ioctl
= ifx_ssc_ioctl
,
104 .open
= ifx_ssc_open
,
105 .release
= ifx_ssc_close
,
108 static inline unsigned int
109 ifx_ssc_get_kernel_clk (struct ifx_ssc_port
*info
)
110 { // ATTENTION: This function assumes that the CLC register is set with the
111 // appropriate value for RMC.
114 rmc
= (READ_PERIPHERAL_REGISTER (info
->mapbase
+ IFX_SSC_CLC
) &
115 IFX_CLC_RUN_DIVIDER_MASK
) >> IFX_CLC_RUN_DIVIDER_OFFSET
;
117 printk ("ifx_ssc_get_kernel_clk rmc==0 \n");
120 return (danube_get_fpi_hz () / rmc
);
124 #ifdef IFX_SSC_INT_USE_BH
126 * This routine is used by the interrupt handler to schedule
127 * processing in the software interrupt portion of the driver
128 * (also known as the "bottom half"). This can be called any
129 * number of times for any channel without harm.
132 ifx_ssc_sched_event (struct ifx_ssc_port
*info
, int event
)
134 info
->event
|= 1 << event
; /* remember what kind of event and who */
135 queue_task (&info
->tqueue
, &tq_cyclades
); /* it belongs to */
136 mark_bh (CYCLADES_BH
); /* then trigger event */
140 do_softint (void *private_
)
142 struct ifx_ssc_port
*info
= (struct ifx_ssc_port
*) private_
;
144 if (test_and_clear_bit (Cy_EVENT_HANGUP
, &info
->event
)) {
145 wake_up_interruptible (&info
->open_wait
);
146 info
->flags
&= ~(ASYNC_NORMAL_ACTIVE
| ASYNC_CALLOUT_ACTIVE
);
148 if (test_and_clear_bit (Cy_EVENT_OPEN_WAKEUP
, &info
->event
)) {
149 wake_up_interruptible (&info
->open_wait
);
151 if (test_and_clear_bit (Cy_EVENT_DELTA_WAKEUP
, &info
->event
)) {
152 wake_up_interruptible (&info
->delta_msr_wait
);
154 if (test_and_clear_bit (Cy_EVENT_WRITE_WAKEUP
, &info
->event
)) {
155 wake_up_interruptible (&tty
->write_wait
);
158 if (test_and_clear_bit (Cy_EVENT_SHUTDOWN_WAKEUP
, &info
->event
)) {
159 wake_up_interruptible (&info
->shutdown_wait
);
163 #endif /* IFX_SSC_INT_USE_BH */
167 rx_int (struct ifx_ssc_port
*info
)
169 int fifo_fill_lev
, bytes_in_buf
, i
;
170 unsigned long tmp_val
;
171 unsigned long *tmp_ptr
;
172 unsigned int rx_valid_cnt
;
173 /* number of words waiting in the RX FIFO */
174 fifo_fill_lev
= (READ_PERIPHERAL_REGISTER (info
->mapbase
+
176 IFX_SSC_FSTAT_RECEIVED_WORDS_MASK
) >>
177 IFX_SSC_FSTAT_RECEIVED_WORDS_OFFSET
;
178 // Note: There are always 32 bits in a fifo-entry except for the last
179 // word of a contigous transfer block and except for not in rx-only
180 // mode and CON.ENBV set. But for this case it should be a convention
181 // in software which helps:
182 // In tx or rx/tx mode all transfers from the buffer to the FIFO are
183 // 32-bit wide, except for the last three bytes, which could be a
184 // combination of 16- and 8-bit access.
185 // => The whole block is received as 32-bit words as a contigous stream,
186 // even if there was a gap in tx which has the fifo run out of data!
187 // Just the last fifo entry *may* be partially filled (0, 1, 2 or 3 bytes)!
189 /* free space in the RX buffer */
190 bytes_in_buf
= info
->rxbuf_end
- info
->rxbuf_ptr
;
191 // transfer with 32 bits per entry
192 while ((bytes_in_buf
>= 4) && (fifo_fill_lev
> 0)) {
193 tmp_ptr
= (unsigned long *) info
->rxbuf_ptr
;
195 READ_PERIPHERAL_REGISTER (info
->mapbase
+ IFX_SSC_RB
);
196 info
->rxbuf_ptr
+= 4;
197 info
->stats
.rxBytes
+= 4;
200 } // while ((bytes_in_buf >= 4) && (fifo_fill_lev > 0))
201 // now do the rest as mentioned in STATE.RXBV
202 while ((bytes_in_buf
> 0) && (fifo_fill_lev
> 0)) {
204 (READ_PERIPHERAL_REGISTER
206 IFX_SSC_STATE
) & IFX_SSC_STATE_RX_BYTE_VALID_MASK
)
207 >> IFX_SSC_STATE_RX_BYTE_VALID_OFFSET
;
208 if (rx_valid_cnt
== 0)
210 if (rx_valid_cnt
> bytes_in_buf
) {
211 // ### TO DO: warning message: not block aligned data, other data
212 // in this entry will be lost
213 rx_valid_cnt
= bytes_in_buf
;
216 READ_PERIPHERAL_REGISTER (info
->mapbase
+ IFX_SSC_RB
);
218 for (i
= 0; i
< rx_valid_cnt
; i
++) {
220 (tmp_val
>> (8 * (rx_valid_cnt
- i
- 1))) &
223 *info->rxbuf_ptr = tmp_val & 0xff;
230 info
->stats
.rxBytes
+= rx_valid_cnt
;
231 } // while ((bytes_in_buf > 0) && (fifo_fill_lev > 0))
233 // check if transfer is complete
234 if (info
->rxbuf_ptr
>= info
->rxbuf_end
) {
235 disable_irq(info
->rxirq
);
236 /* wakeup any processes waiting in read() */
237 wake_up_interruptible (&info
->rwait
);
239 //wake_up_interruptible(&info->pwait);
241 else if ((info
->opts
.modeRxTx
== IFX_SSC_MODE_RX
) &&
242 (READ_PERIPHERAL_REGISTER (info
->mapbase
+ IFX_SSC_RXCNT
) ==
244 // if buffer not filled completely and rx request done initiate new transfer
246 if (info->rxbuf_end - info->rxbuf_ptr < 65536)
248 if (info
->rxbuf_end
- info
->rxbuf_ptr
<
249 IFX_SSC_RXREQ_BLOCK_SIZE
)
250 WRITE_PERIPHERAL_REGISTER ((info
->rxbuf_end
-
253 IFX_SSC_RXREQ_RXCOUNT_OFFSET
,
257 WRITE_PERIPHERAL_REGISTER (IFX_SSC_RXREQ_BLOCK_SIZE
<<
258 IFX_SSC_RXREQ_RXCOUNT_OFFSET
,
265 tx_int (struct ifx_ssc_port
*info
)
268 int fifo_space
, fill
, i
;
269 fifo_space
= ((READ_PERIPHERAL_REGISTER (info
->mapbase
+ IFX_SSC_ID
) &
270 IFX_SSC_PERID_TXFS_MASK
) >> IFX_SSC_PERID_TXFS_OFFSET
)
272 ((READ_PERIPHERAL_REGISTER (info
->mapbase
+ IFX_SSC_FSTAT
) &
273 IFX_SSC_FSTAT_TRANSMIT_WORDS_MASK
) >>
274 IFX_SSC_FSTAT_TRANSMIT_WORDS_OFFSET
);
279 fill
= info
->txbuf_end
- info
->txbuf_ptr
;
281 if (fill
> fifo_space
* 4)
282 fill
= fifo_space
* 4;
284 for (i
= 0; i
< fill
/ 4; i
++) {
285 // at first 32 bit access
286 WRITE_PERIPHERAL_REGISTER (*(UINT32
*) info
->txbuf_ptr
,
287 info
->mapbase
+ IFX_SSC_TB
);
288 info
->txbuf_ptr
+= 4;
291 fifo_space
-= fill
/ 4;
292 info
->stats
.txBytes
+= fill
& ~0x3;
294 if ((fifo_space
> 0) & (fill
> 1)) {
295 // trailing 16 bit access
296 WRITE_PERIPHERAL_REGISTER_16 (*(UINT16
*) info
->txbuf_ptr
,
297 info
->mapbase
+ IFX_SSC_TB
);
298 info
->txbuf_ptr
+= 2;
299 info
->stats
.txBytes
+= 2;
301 /* added by bingtao */
304 if ((fifo_space
> 0) & (fill
> 0)) {
305 // trailing 8 bit access
306 WRITE_PERIPHERAL_REGISTER_8 (*(UINT8
*) info
->txbuf_ptr
,
307 info
->mapbase
+ IFX_SSC_TB
);
309 info
->stats
.txBytes
++;
315 // check if transmission complete
316 if (info
->txbuf_ptr
>= info
->txbuf_end
) {
317 disable_irq(info
->txirq
);
320 /* wake up any process waiting in poll() */
321 //wake_up_interruptible(&info->pwait);
327 ifx_ssc_rx_int (int irq
, void *dev_id
)
329 struct ifx_ssc_port
*info
= (struct ifx_ssc_port
*) dev_id
;
336 ifx_ssc_tx_int (int irq
, void *dev_id
)
338 struct ifx_ssc_port
*info
= (struct ifx_ssc_port
*) dev_id
;
345 ifx_ssc_err_int (int irq
, void *dev_id
)
347 struct ifx_ssc_port
*info
= (struct ifx_ssc_port
*) dev_id
;
349 unsigned int write_back
= 0;
352 local_irq_save (flags
);
353 state
= READ_PERIPHERAL_REGISTER (info
->mapbase
+ IFX_SSC_STATE
);
355 if ((state
& IFX_SSC_STATE_RX_UFL
) != 0) {
356 info
->stats
.rxUnErr
++;
357 write_back
|= IFX_SSC_WHBSTATE_CLR_RX_UFL_ERROR
;
359 if ((state
& IFX_SSC_STATE_RX_OFL
) != 0) {
360 info
->stats
.rxOvErr
++;
361 write_back
|= IFX_SSC_WHBSTATE_CLR_RX_OFL_ERROR
;
363 if ((state
& IFX_SSC_STATE_TX_OFL
) != 0) {
364 info
->stats
.txOvErr
++;
365 write_back
|= IFX_SSC_WHBSTATE_CLR_TX_OFL_ERROR
;
367 if ((state
& IFX_SSC_STATE_TX_UFL
) != 0) {
368 info
->stats
.txUnErr
++;
369 write_back
|= IFX_SSC_WHBSTATE_CLR_TX_UFL_ERROR
;
371 // if ((state & IFX_SSC_STATE_ABORT_ERR) != 0) {
372 // info->stats.abortErr++;
373 // write_back |= IFX_SSC_WHBSTATE_CLR_ABORT_ERROR;
375 if ((state
& IFX_SSC_STATE_MODE_ERR
) != 0) {
376 info
->stats
.modeErr
++;
377 write_back
|= IFX_SSC_WHBSTATE_CLR_MODE_ERROR
;
381 WRITE_PERIPHERAL_REGISTER (write_back
,
382 info
->mapbase
+ IFX_SSC_WHBSTATE
);
384 local_irq_restore (flags
);
390 ifx_ssc_abort (struct ifx_ssc_port
*info
)
395 local_irq_save (flags
);
397 disable_irq(info
->rxirq
);
398 disable_irq(info
->txirq
);
399 disable_irq(info
->errirq
);
401 local_irq_restore (flags
);
403 // disable SSC (also aborts a receive request!)
404 // ### TO DO: Perhaps it's better to abort after the receiption of a
405 // complete word. The disable cuts the transmission immediatly and
406 // releases the chip selects. This could result in unpredictable
407 // behavior of connected external devices!
408 enabled
= (READ_PERIPHERAL_REGISTER (info
->mapbase
+ IFX_SSC_STATE
)
409 & IFX_SSC_STATE_IS_ENABLED
) != 0;
410 WRITE_PERIPHERAL_REGISTER (IFX_SSC_WHBSTATE_CLR_ENABLE
,
411 info
->mapbase
+ IFX_SSC_WHBSTATE
);
414 WRITE_PERIPHERAL_REGISTER (IFX_SSC_XFCON_FIFO_FLUSH
,
415 info
->mapbase
+ IFX_SSC_TXFCON
);
416 WRITE_PERIPHERAL_REGISTER (IFX_SSC_XFCON_FIFO_FLUSH
,
417 info
->mapbase
+ IFX_SSC_RXFCON
);
420 if (info
->txbuf
!= NULL
) {
425 // wakeup read process
426 if (info
->rxbuf
!= NULL
)
427 wake_up_interruptible (&info
->rwait
);
429 // clear pending int's
430 mask_and_ack_danube_irq(info
->rxirq
);
431 mask_and_ack_danube_irq(info
->txirq
);
432 mask_and_ack_danube_irq(info
->errirq
);
435 WRITE_PERIPHERAL_REGISTER (IFX_SSC_WHBSTATE_CLR_ALL_ERROR
,
436 info
->mapbase
+ IFX_SSC_WHBSTATE
);
439 WRITE_PERIPHERAL_REGISTER (IFX_SSC_WHBSTATE_SET_ENABLE
,
440 info
->mapbase
+ IFX_SSC_WHBSTATE
);
445 * This routine is called whenever a port is opened. It enforces
446 * exclusive opening of a port and enables interrupts, etc.
449 ifx_ssc_open (struct inode
*inode
, struct file
*filp
)
451 struct ifx_ssc_port
*info
;
455 if ((inode
== (struct inode
*) 0) || (inode
== (struct inode
*) 1)) {
460 line
= MINOR (filp
->f_dentry
->d_inode
->i_rdev
);
461 filp
->f_op
= &ifx_ssc_fops
;
464 /* don't open more minor devices than we can support */
465 if (line
< 0 || line
>= PORT_CNT
)
471 if (info
->port_is_open
!= 0)
473 info
->port_is_open
++;
475 disable_irq(info
->rxirq
);
476 disable_irq(info
->txirq
);
477 disable_irq(info
->errirq
);
479 /* Flush and enable TX/RX FIFO */
480 WRITE_PERIPHERAL_REGISTER ((IFX_SSC_DEF_TXFIFO_FL
<<
481 IFX_SSC_XFCON_ITL_OFFSET
) |
482 IFX_SSC_XFCON_FIFO_FLUSH
|
483 IFX_SSC_XFCON_FIFO_ENABLE
,
484 info
->mapbase
+ IFX_SSC_TXFCON
);
485 WRITE_PERIPHERAL_REGISTER ((IFX_SSC_DEF_RXFIFO_FL
<<
486 IFX_SSC_XFCON_ITL_OFFSET
) |
487 IFX_SSC_XFCON_FIFO_FLUSH
|
488 IFX_SSC_XFCON_FIFO_ENABLE
,
489 info
->mapbase
+ IFX_SSC_RXFCON
);
491 /* logically flush the software FIFOs */
495 /* clear all error bits */
496 WRITE_PERIPHERAL_REGISTER (IFX_SSC_WHBSTATE_CLR_ALL_ERROR
,
497 info
->mapbase
+ IFX_SSC_WHBSTATE
);
499 // clear pending interrupts
500 mask_and_ack_danube_irq(info
->rxirq
);
501 mask_and_ack_danube_irq(info
->txirq
);
502 mask_and_ack_danube_irq(info
->errirq
);
504 WRITE_PERIPHERAL_REGISTER (IFX_SSC_WHBSTATE_SET_ENABLE
,
505 info
->mapbase
+ IFX_SSC_WHBSTATE
);
509 EXPORT_SYMBOL (ifx_ssc_open
);
512 * This routine is called when a particular device is closed.
515 ifx_ssc_close (struct inode
*inode
, struct file
*filp
)
517 struct ifx_ssc_port
*info
;
520 if ((inode
== (struct inode
*) 0) || (inode
== (struct inode
*) 1))
523 idx
= MINOR (filp
->f_dentry
->d_inode
->i_rdev
);
525 if (idx
< 0 || idx
>= PORT_CNT
)
533 WRITE_PERIPHERAL_REGISTER (IFX_SSC_WHBSTATE_CLR_ENABLE
,
534 info
->mapbase
+ IFX_SSC_WHBSTATE
);
536 // call abort function to disable int's, flush fifos...
537 ifx_ssc_abort (info
);
539 info
->port_is_open
--;
543 EXPORT_SYMBOL (ifx_ssc_close
);
545 /* added by bingtao */
546 /* helper routine to handle reads from the kernel or user-space */
547 /* info->rxbuf : never kfree and contains valid data */
548 /* should be points to NULL after copying data !!! */
550 ifx_ssc_read_helper_poll (struct ifx_ssc_port
*info
, char *buf
, size_t len
,
556 if (info
->opts
.modeRxTx
== IFX_SSC_MODE_TX
)
558 local_irq_save (flags
);
559 info
->rxbuf_ptr
= info
->rxbuf
;
560 info
->rxbuf_end
= info
->rxbuf
+ len
;
561 local_irq_restore (flags
);
562 /* Vinetic driver always works in IFX_SSC_MODE_RXTX */
563 /* TXRX in poll mode */
564 while (info
->rxbuf_ptr
< info
->rxbuf_end
) {
565 /* This is the key point, if you don't check this condition
566 kfree (NULL) will happen
567 because tx only need write into FIFO, it's much fast than rx
568 So when rx still waiting , tx already finish and release buf
570 if (info
->txbuf_ptr
< info
->txbuf_end
) {
577 ret_val
= info
->rxbuf_ptr
- info
->rxbuf
;
581 /* helper routine to handle reads from the kernel or user-space */
582 /* info->rx_buf : never kfree and contains valid data */
583 /* should be points to NULL after copying data !!! */
585 ifx_ssc_read_helper (struct ifx_ssc_port
*info
, char *buf
, size_t len
,
590 DECLARE_WAITQUEUE (wait
, current
);
592 if (info
->opts
.modeRxTx
== IFX_SSC_MODE_TX
)
594 local_irq_save (flags
);
595 info
->rxbuf_ptr
= info
->rxbuf
;
596 info
->rxbuf_end
= info
->rxbuf
+ len
;
597 if (info
->opts
.modeRxTx
== IFX_SSC_MODE_RXTX
) {
598 if ((info
->txbuf
== NULL
) ||
599 (info
->txbuf
!= info
->txbuf_ptr
) ||
600 (info
->txbuf_end
!= len
+ info
->txbuf
)) {
601 local_irq_restore (flags
);
602 printk ("IFX SSC - %s: write must be called before calling " "read in combined RX/TX!\n", __func__
);
605 local_irq_restore (flags
);
606 /* should enable tx, right? */
608 if (info
->txbuf_ptr
< info
->txbuf_end
)
609 enable_irq(info
->txirq
);
611 enable_irq(info
->rxirq
);
614 local_irq_restore (flags
);
615 if (READ_PERIPHERAL_REGISTER (info
->mapbase
+ IFX_SSC_RXCNT
) &
616 IFX_SSC_RXCNT_TODO_MASK
)
618 enable_irq(info
->rxirq
);
619 // rx request limited to ' bytes
623 if (len
< IFX_SSC_RXREQ_BLOCK_SIZE
)
624 WRITE_PERIPHERAL_REGISTER (len
<<
625 IFX_SSC_RXREQ_RXCOUNT_OFFSET
,
629 WRITE_PERIPHERAL_REGISTER (IFX_SSC_RXREQ_BLOCK_SIZE
<<
630 IFX_SSC_RXREQ_RXCOUNT_OFFSET
,
635 __add_wait_queue (&info
->rwait
, &wait
);
636 set_current_state (TASK_INTERRUPTIBLE
);
637 // wakeup done in rx_int
640 local_irq_save (flags
);
641 if (info
->rxbuf_ptr
>= info
->rxbuf_end
)
643 local_irq_restore (flags
);
645 if (signal_pending (current
)) {
646 ret_val
= -ERESTARTSYS
;
652 ret_val
= info
->rxbuf_ptr
- info
->rxbuf
;
653 local_irq_restore (flags
);
656 current
->state
= TASK_RUNNING
;
657 __remove_wait_queue (&info
->rwait
, &wait
);
662 /* helper routine to handle writes to the kernel or user-space */
663 /* info->txbuf has two cases:
664 * 1) return value < 0 (-EFAULT), not touched at all
665 * 2) kfree and points to NULL in interrupt routine (but maybe later )
668 ifx_ssc_write_helper (struct ifx_ssc_port
*info
, const char *buf
,
669 size_t len
, int from_kernel
)
671 // check if in tx or tx/rx mode
672 if (info
->opts
.modeRxTx
== IFX_SSC_MODE_RX
)
675 info
->txbuf_ptr
= info
->txbuf
;
676 info
->txbuf_end
= len
+ info
->txbuf
;
677 /* start the transmission (not in rx/tx, see read helper) */
678 if (info
->opts
.modeRxTx
== IFX_SSC_MODE_TX
) {
680 if (info
->txbuf_ptr
< info
->txbuf_end
) {
681 enable_irq(info
->txirq
);
684 //local_irq_restore(flags);
689 * kernel interfaces for read and write.
690 * The caller must set port to: n for SSC<m> with n=m-1 (e.g. n=0 for SSC1)
693 ifx_ssc_kread (int port
, char *kbuf
, size_t len
)
695 struct ifx_ssc_port
*info
;
698 if (port
< 0 || port
>= PORT_CNT
)
706 // check if reception in progress
707 if (info
->rxbuf
!= NULL
) {
708 printk ("SSC device busy\n");
713 if (info
->rxbuf
== NULL
) {
714 printk ("SSC device error\n");
718 /* changed by bingtao */
719 /* change by TaiCheng */
722 ret_val
= ifx_ssc_read_helper (info
, kbuf
, len
, 1);
725 ret_val
= ifx_ssc_read_helper_poll (info
, kbuf
, len
, 1);
729 // ### TO DO: perhaps warn if ret_val != len
730 disable_irq(info
->rxirq
);
735 EXPORT_SYMBOL (ifx_ssc_kread
);
738 ifx_ssc_kwrite (int port
, const char *kbuf
, size_t len
)
740 struct ifx_ssc_port
*info
;
743 if (port
< 0 || port
>= PORT_CNT
)
751 // check if transmission in progress
752 if (info
->txbuf
!= NULL
)
754 info
->txbuf
= (char *) kbuf
;
756 ret_val
= ifx_ssc_write_helper (info
, info
->txbuf
, len
, 1);
763 EXPORT_SYMBOL (ifx_ssc_kwrite
);
766 * user interfaces to read and write
769 ifx_ssc_read (struct file
*filp
, char *ubuf
, size_t len
, loff_t
* off
)
773 struct ifx_ssc_port
*info
;
775 idx
= MINOR (filp
->f_dentry
->d_inode
->i_rdev
);
778 // check if reception in progress
779 if (info
->rxbuf
!= NULL
)
782 info
->rxbuf
= kmalloc (len
+ 3, GFP_KERNEL
);
783 if (info
->rxbuf
== NULL
)
786 ret_val
= ifx_ssc_read_helper (info
, info
->rxbuf
, len
, 0);
787 // ### TO DO: perhaps warn if ret_val != len
788 if (copy_to_user ((void *) ubuf
, info
->rxbuf
, ret_val
) != 0)
791 disable_irq(info
->rxirq
);
799 * As many bytes as we have free space for are copied from the user
800 * into txbuf and the actual byte count is returned. The transmission is
801 * always kicked off by calling the appropriate TX routine.
804 ifx_ssc_write (struct file
*filp
, const char *ubuf
, size_t len
, loff_t
* off
)
807 struct ifx_ssc_port
*info
;
813 idx
= MINOR (filp
->f_dentry
->d_inode
->i_rdev
);
816 // check if transmission in progress
817 if (info
->txbuf
!= NULL
)
820 info
->txbuf
= kmalloc (len
+ 3, GFP_KERNEL
);
821 if (info
->txbuf
== NULL
)
824 ret_val
= copy_from_user (info
->txbuf
, ubuf
, len
);
826 ret_val
= ifx_ssc_write_helper (info
, info
->txbuf
, len
, 0);
830 kfree (info
->txbuf
); // otherwise will be done in ISR
836 static struct ifx_ssc_frm_status
*
837 ifx_ssc_frm_status_get (struct ifx_ssc_port
*info
)
841 tmp
= READ_PERIPHERAL_REGISTER (info
->mapbase
+ IFX_SSC_SFSTAT
);
842 info
->frm_status
.DataBusy
= (tmp
& IFX_SSC_SFSTAT_IN_DATA
) > 0;
843 info
->frm_status
.PauseBusy
= (tmp
& IFX_SSC_SFSTAT_IN_PAUSE
) > 0;
844 info
->frm_status
.DataCount
= (tmp
& IFX_SSC_SFSTAT_DATA_COUNT_MASK
)
845 >> IFX_SSC_SFSTAT_DATA_COUNT_OFFSET
;
846 info
->frm_status
.PauseCount
= (tmp
& IFX_SSC_SFSTAT_PAUSE_COUNT_MASK
)
847 >> IFX_SSC_SFSTAT_PAUSE_COUNT_OFFSET
;
848 tmp
= READ_PERIPHERAL_REGISTER (info
->mapbase
+ IFX_SSC_SFCON
);
849 info
->frm_status
.EnIntAfterData
=
850 (tmp
& IFX_SSC_SFCON_FIR_ENABLE_BEFORE_PAUSE
) > 0;
851 info
->frm_status
.EnIntAfterPause
=
852 (tmp
& IFX_SSC_SFCON_FIR_ENABLE_AFTER_PAUSE
) > 0;
853 return (&info
->frm_status
);
857 static struct ifx_ssc_frm_opts
*
858 ifx_ssc_frm_control_get (struct ifx_ssc_port
*info
)
862 tmp
= READ_PERIPHERAL_REGISTER (info
->mapbase
+ IFX_SSC_SFCON
);
863 info
->frm_opts
.FrameEnable
= (tmp
& IFX_SSC_SFCON_SF_ENABLE
) > 0;
864 info
->frm_opts
.DataLength
= (tmp
& IFX_SSC_SFCON_DATA_LENGTH_MASK
)
865 >> IFX_SSC_SFCON_DATA_LENGTH_OFFSET
;
866 info
->frm_opts
.PauseLength
= (tmp
& IFX_SSC_SFCON_PAUSE_LENGTH_MASK
)
867 >> IFX_SSC_SFCON_PAUSE_LENGTH_OFFSET
;
868 info
->frm_opts
.IdleData
= (tmp
& IFX_SSC_SFCON_PAUSE_DATA_MASK
)
869 >> IFX_SSC_SFCON_PAUSE_DATA_OFFSET
;
870 info
->frm_opts
.IdleClock
= (tmp
& IFX_SSC_SFCON_PAUSE_CLOCK_MASK
)
871 >> IFX_SSC_SFCON_PAUSE_CLOCK_OFFSET
;
872 info
->frm_opts
.StopAfterPause
=
873 (tmp
& IFX_SSC_SFCON_STOP_AFTER_PAUSE
) > 0;
874 return (&info
->frm_opts
);
878 ifx_ssc_frm_control_set (struct ifx_ssc_port
*info
)
883 if ((info
->frm_opts
.DataLength
> IFX_SSC_SFCON_DATA_LENGTH_MAX
)
884 || (info
->frm_opts
.DataLength
< 1)
885 || (info
->frm_opts
.PauseLength
> IFX_SSC_SFCON_PAUSE_LENGTH_MAX
)
886 || (info
->frm_opts
.PauseLength
< 1)
887 || (info
->frm_opts
.IdleData
& ~(IFX_SSC_SFCON_PAUSE_DATA_MASK
>> IFX_SSC_SFCON_PAUSE_DATA_OFFSET
))
888 || (info
->frm_opts
.IdleClock
& ~(IFX_SSC_SFCON_PAUSE_CLOCK_MASK
>> IFX_SSC_SFCON_PAUSE_CLOCK_OFFSET
)))
891 // read interrupt bits (they're not changed here)
892 tmp
= READ_PERIPHERAL_REGISTER (info
->mapbase
+ IFX_SSC_SFCON
) &
893 (IFX_SSC_SFCON_FIR_ENABLE_BEFORE_PAUSE
| IFX_SSC_SFCON_FIR_ENABLE_AFTER_PAUSE
);
895 // set all values with respect to it's bit position (for data and pause
897 tmp
= (info
->frm_opts
.DataLength
- 1) << IFX_SSC_SFCON_DATA_LENGTH_OFFSET
;
898 tmp
|= (info
->frm_opts
.PauseLength
- 1) << IFX_SSC_SFCON_PAUSE_LENGTH_OFFSET
;
899 tmp
|= info
->frm_opts
.IdleData
<< IFX_SSC_SFCON_PAUSE_DATA_OFFSET
;
900 tmp
|= info
->frm_opts
.IdleClock
<< IFX_SSC_SFCON_PAUSE_CLOCK_OFFSET
;
901 tmp
|= info
->frm_opts
.FrameEnable
* IFX_SSC_SFCON_SF_ENABLE
;
902 tmp
|= info
->frm_opts
.StopAfterPause
* IFX_SSC_SFCON_STOP_AFTER_PAUSE
;
904 WRITE_PERIPHERAL_REGISTER(tmp
, info
->mapbase
+ IFX_SSC_SFCON
);
910 ifx_ssc_rxtx_mode_set (struct ifx_ssc_port
*info
, unsigned int val
)
914 if (!(info
) || (val
& ~(IFX_SSC_MODE_MASK
)))
917 if ((READ_PERIPHERAL_REGISTER (info
->mapbase
+ IFX_SSC_STATE
) & IFX_SSC_STATE_BUSY
)
918 || (READ_PERIPHERAL_REGISTER (info
->mapbase
+ IFX_SSC_RXCNT
) & IFX_SSC_RXCNT_TODO_MASK
))
921 tmp
= (READ_PERIPHERAL_REGISTER (info
->mapbase
+ IFX_SSC_CON
) & ~(IFX_SSC_CON_RX_OFF
| IFX_SSC_CON_TX_OFF
)) | (val
);
922 WRITE_PERIPHERAL_REGISTER (tmp
, info
->mapbase
+ IFX_SSC_CON
);
923 info
->opts
.modeRxTx
= val
;
929 ifx_ssc_sethwopts (struct ifx_ssc_port
*info
)
931 unsigned long flags
, bits
;
932 struct ifx_ssc_hwopts
*opts
= &info
->opts
;
934 if ((opts
->dataWidth
< IFX_SSC_MIN_DATA_WIDTH
)
935 || (opts
->dataWidth
> IFX_SSC_MAX_DATA_WIDTH
))
938 bits
= (opts
->dataWidth
- 1) << IFX_SSC_CON_DATA_WIDTH_OFFSET
;
939 bits
|= IFX_SSC_CON_ENABLE_BYTE_VALID
;
941 if (opts
->rxOvErrDetect
)
942 bits
|= IFX_SSC_CON_RX_OFL_CHECK
;
943 if (opts
->rxUndErrDetect
)
944 bits
|= IFX_SSC_CON_RX_UFL_CHECK
;
945 if (opts
->txOvErrDetect
)
946 bits
|= IFX_SSC_CON_TX_OFL_CHECK
;
947 if (opts
->txUndErrDetect
)
948 bits
|= IFX_SSC_CON_TX_UFL_CHECK
;
950 bits
|= IFX_SSC_CON_LOOPBACK_MODE
;
952 bits
|= IFX_SSC_CON_ECHO_MODE_ON
;
953 if (opts
->headingControl
)
954 bits
|= IFX_SSC_CON_MSB_FIRST
;
955 if (opts
->clockPhase
)
956 bits
|= IFX_SSC_CON_LATCH_THEN_SHIFT
;
957 if (opts
->clockPolarity
)
958 bits
|= IFX_SSC_CON_CLOCK_FALL
;
960 switch (opts
->modeRxTx
)
962 case IFX_SSC_MODE_TX
:
963 bits
|= IFX_SSC_CON_RX_OFF
;
965 case IFX_SSC_MODE_RX
:
966 bits
|= IFX_SSC_CON_TX_OFF
;
970 local_irq_save (flags
);
972 WRITE_PERIPHERAL_REGISTER (bits
, info
->mapbase
+ IFX_SSC_CON
);
973 WRITE_PERIPHERAL_REGISTER ((info
->opts
.gpoCs
<< IFX_SSC_GPOCON_ISCSB0_POS
) |
974 (info
->opts
.gpoInv
<< IFX_SSC_GPOCON_INVOUT0_POS
), info
->mapbase
+ IFX_SSC_GPOCON
);
976 WRITE_PERIPHERAL_REGISTER (info
->opts
.gpoCs
<< IFX_SSC_WHBGPOSTAT_SETOUT0_POS
, info
->mapbase
+ IFX_SSC_WHBGPOSTAT
);
979 if (opts
->masterSelect
)
980 WRITE_PERIPHERAL_REGISTER (IFX_SSC_WHBSTATE_SET_MASTER_SELECT
, info
->mapbase
+ IFX_SSC_WHBSTATE
);
982 WRITE_PERIPHERAL_REGISTER (IFX_SSC_WHBSTATE_CLR_MASTER_SELECT
, info
->mapbase
+ IFX_SSC_WHBSTATE
);
984 // init serial framing
985 WRITE_PERIPHERAL_REGISTER (0, info
->mapbase
+ IFX_SSC_SFCON
);
986 /* set up the port pins */
987 //check for general requirements to switch (external) pad/pin characteristics
988 /* TODO: P0.9 SPI_CS4, P0.10 SPI_CS5, P 0.11 SPI_CS6, because of ASC0 */
989 /* p0.15 SPI_CS1(EEPROM), P0.13 SPI_CS3, */
990 /* Set p0.15 to alternative 01, others to 00 (In/OUT) */
991 *(DANUBE_GPIO_P0_DIR
) = (*DANUBE_GPIO_P0_DIR
) | (0xA000);
992 *(DANUBE_GPIO_P0_ALTSEL0
) = (((*DANUBE_GPIO_P0_ALTSEL0
) | (0x8000)) & (~(0x2000)));
993 *(DANUBE_GPIO_P0_ALTSEL1
) = (((*DANUBE_GPIO_P0_ALTSEL1
) & (~0x8000)) & (~(0x2000)));
994 *(DANUBE_GPIO_P0_OD
) = (*DANUBE_GPIO_P0_OD
) | 0xA000;
996 /* p1.6 SPI_CS2(SFLASH), p1.0 SPI_DIN, p1.1 SPI_DOUT, p1.2 SPI_CLK */
997 *(DANUBE_GPIO_P1_DIR
) = ((*DANUBE_GPIO_P1_DIR
) | (0x46)) & (~1);
998 *(DANUBE_GPIO_P1_ALTSEL0
) = ((*DANUBE_GPIO_P1_ALTSEL0
) | (0x47));
999 *(DANUBE_GPIO_P1_ALTSEL1
) = (*DANUBE_GPIO_P1_ALTSEL1
) & (~0x47);
1000 *(DANUBE_GPIO_P1_OD
) = (*DANUBE_GPIO_P1_OD
) | 0x0046;
1003 /*TODO: CS4 CS5 CS6 */
1004 *DANUBE_GPIO_P0_OUT
= ((*DANUBE_GPIO_P0_OUT
) | 0x2000);
1006 local_irq_restore (flags
);
1012 ifx_ssc_set_baud (struct ifx_ssc_port
*info
, unsigned int baud
)
1014 unsigned int ifx_ssc_clock
;
1016 unsigned long flags
;
1020 ifx_ssc_clock
= ifx_ssc_get_kernel_clk(info
);
1021 if (ifx_ssc_clock
== 0)
1027 local_irq_save (flags
);
1029 enabled
= (READ_PERIPHERAL_REGISTER (info
->mapbase
+ IFX_SSC_STATE
) & IFX_SSC_STATE_IS_ENABLED
);
1030 WRITE_PERIPHERAL_REGISTER (IFX_SSC_WHBSTATE_CLR_ENABLE
, info
->mapbase
+ IFX_SSC_WHBSTATE
);
1032 br
= (((ifx_ssc_clock
>> 1) + baud
/ 2) / baud
) - 1;
1035 if (br
> 0xffff || ((br
== 0) &&
1036 ((READ_PERIPHERAL_REGISTER (info
->mapbase
+ IFX_SSC_STATE
) & IFX_SSC_STATE_IS_MASTER
) == 0))) {
1037 local_irq_restore (flags
);
1038 printk ("%s: invalid baudrate %u\n", __func__
, baud
);
1042 WRITE_PERIPHERAL_REGISTER (br
, info
->mapbase
+ IFX_SSC_BR
);
1045 WRITE_PERIPHERAL_REGISTER (IFX_SSC_WHBSTATE_SET_ENABLE
, info
->mapbase
+ IFX_SSC_WHBSTATE
);
1047 local_irq_restore(flags
);
1054 ifx_ssc_hwinit (struct ifx_ssc_port
*info
)
1056 unsigned long flags
;
1059 enabled
= (READ_PERIPHERAL_REGISTER (info
->mapbase
+ IFX_SSC_STATE
) & IFX_SSC_STATE_IS_ENABLED
);
1060 WRITE_PERIPHERAL_REGISTER (IFX_SSC_WHBSTATE_CLR_ENABLE
, info
->mapbase
+ IFX_SSC_WHBSTATE
);
1062 if (ifx_ssc_sethwopts (info
) < 0)
1064 printk ("%s: setting the hardware options failed\n", __func__
);
1068 if (ifx_ssc_set_baud (info
, info
->baud
) < 0)
1070 printk ("%s: setting the baud rate failed\n", __func__
);
1074 local_irq_save (flags
);
1077 WRITE_PERIPHERAL_REGISTER ((IFX_SSC_DEF_TXFIFO_FL
<< IFX_SSC_XFCON_ITL_OFFSET
) | IFX_SSC_XFCON_FIFO_ENABLE
,
1078 info
->mapbase
+ IFX_SSC_TXFCON
);
1080 WRITE_PERIPHERAL_REGISTER ((IFX_SSC_DEF_RXFIFO_FL
<< IFX_SSC_XFCON_ITL_OFFSET
) | IFX_SSC_XFCON_FIFO_ENABLE
,
1081 info
->mapbase
+ IFX_SSC_RXFCON
);
1083 local_irq_restore (flags
);
1086 WRITE_PERIPHERAL_REGISTER (IFX_SSC_WHBSTATE_SET_ENABLE
, info
->mapbase
+ IFX_SSC_WHBSTATE
);
1092 ifx_ssc_ioctl (struct inode
*inode
, struct file
*filp
, unsigned int cmd
, unsigned long data
)
1094 struct ifx_ssc_port
*info
;
1095 int line
, ret_val
= 0;
1096 unsigned long flags
;
1098 int from_kernel
= 0;
1100 if ((inode
== (struct inode
*) 0) || (inode
== (struct inode
*) 1))
1105 line
= MINOR (filp
->f_dentry
->d_inode
->i_rdev
);
1108 if (line
< 0 || line
>= PORT_CNT
)
1115 case IFX_SSC_STATS_READ
:
1116 /* data must be a pointer to a struct ifx_ssc_statistics */
1118 memcpy ((void *) data
, (void *) &info
->stats
,
1119 sizeof (struct ifx_ssc_statistics
));
1120 else if (copy_to_user ((void *) data
,
1121 (void *) &info
->stats
,
1122 sizeof (struct ifx_ssc_statistics
)))
1125 case IFX_SSC_STATS_RESET
:
1126 /* just resets the statistics counters */
1127 memset ((void *) &info
->stats
, 0,
1128 sizeof (struct ifx_ssc_statistics
));
1130 case IFX_SSC_BAUD_SET
:
1131 /* if the buffers are not empty then the port is */
1132 /* busy and we shouldn't change things on-the-fly! */
1133 if (!info
->txbuf
|| !info
->rxbuf
||
1134 (READ_PERIPHERAL_REGISTER (info
->mapbase
+ IFX_SSC_STATE
)
1135 & IFX_SSC_STATE_BUSY
)) {
1141 flags
= *((unsigned long *) data
);
1142 else if (copy_from_user ((void *) &flags
,
1143 (void *) data
, sizeof (flags
))) {
1151 if (ifx_ssc_set_baud (info
, flags
) < 0) {
1157 case IFX_SSC_BAUD_GET
:
1159 *((unsigned int *) data
) = info
->baud
;
1160 else if (copy_to_user ((void *) data
,
1161 (void *) &info
->baud
,
1162 sizeof (unsigned long)))
1165 case IFX_SSC_RXTX_MODE_SET
:
1167 tmp
= *((unsigned long *) data
);
1168 else if (copy_from_user ((void *) &tmp
,
1169 (void *) data
, sizeof (tmp
))) {
1173 ret_val
= ifx_ssc_rxtx_mode_set (info
, tmp
);
1175 case IFX_SSC_RXTX_MODE_GET
:
1176 tmp
= READ_PERIPHERAL_REGISTER (info
->mapbase
+ IFX_SSC_CON
) &
1177 (~(IFX_SSC_CON_RX_OFF
| IFX_SSC_CON_TX_OFF
));
1179 *((unsigned int *) data
) = tmp
;
1180 else if (copy_to_user ((void *) data
,
1181 (void *) &tmp
, sizeof (tmp
)))
1186 ifx_ssc_abort (info
);
1189 case IFX_SSC_GPO_OUT_SET
:
1191 tmp
= *((unsigned long *) data
);
1192 else if (copy_from_user ((void *) &tmp
,
1193 (void *) data
, sizeof (tmp
))) {
1197 if (tmp
> IFX_SSC_MAX_GPO_OUT
)
1200 WRITE_PERIPHERAL_REGISTER
1201 (1 << (tmp
+ IFX_SSC_WHBGPOSTAT_SETOUT0_POS
),
1202 info
->mapbase
+ IFX_SSC_WHBGPOSTAT
);
1204 case IFX_SSC_GPO_OUT_CLR
:
1206 tmp
= *((unsigned long *) data
);
1207 else if (copy_from_user ((void *) &tmp
,
1208 (void *) data
, sizeof (tmp
))) {
1212 if (tmp
> IFX_SSC_MAX_GPO_OUT
)
1215 WRITE_PERIPHERAL_REGISTER
1216 (1 << (tmp
+ IFX_SSC_WHBGPOSTAT_CLROUT0_POS
),
1217 info
->mapbase
+ IFX_SSC_WHBGPOSTAT
);
1220 case IFX_SSC_GPO_OUT_GET
:
1221 tmp
= READ_PERIPHERAL_REGISTER
1222 (info
->mapbase
+ IFX_SSC_GPOSTAT
);
1224 *((unsigned int *) data
) = tmp
;
1225 else if (copy_to_user ((void *) data
,
1226 (void *) &tmp
, sizeof (tmp
)))
1229 case IFX_SSC_FRM_STATUS_GET
:
1230 ifx_ssc_frm_status_get (info
);
1232 memcpy ((void *) data
, (void *) &info
->frm_status
,
1233 sizeof (struct ifx_ssc_frm_status
));
1234 else if (copy_to_user ((void *) data
,
1235 (void *) &info
->frm_status
,
1236 sizeof (struct ifx_ssc_frm_status
)))
1239 case IFX_SSC_FRM_CONTROL_GET
:
1240 ifx_ssc_frm_control_get (info
);
1242 memcpy ((void *) data
, (void *) &info
->frm_opts
,
1243 sizeof (struct ifx_ssc_frm_opts
));
1244 else if (copy_to_user ((void *) data
,
1245 (void *) &info
->frm_opts
,
1246 sizeof (struct ifx_ssc_frm_opts
)))
1249 case IFX_SSC_FRM_CONTROL_SET
:
1251 memcpy ((void *) &info
->frm_opts
, (void *) data
,
1252 sizeof (struct ifx_ssc_frm_opts
));
1253 else if (copy_to_user ((void *) &info
->frm_opts
,
1255 sizeof (struct ifx_ssc_frm_opts
))) {
1259 ret_val
= ifx_ssc_frm_control_set (info
);
1261 case IFX_SSC_HWOPTS_SET
:
1262 /* data must be a pointer to a struct ifx_ssc_hwopts */
1263 /* if the buffers are not empty then the port is */
1264 /* busy and we shouldn't change things on-the-fly! */
1265 if (!info
->txbuf
|| !info
->rxbuf
||
1266 (READ_PERIPHERAL_REGISTER (info
->mapbase
+ IFX_SSC_STATE
)
1267 & IFX_SSC_STATE_BUSY
)) {
1272 memcpy ((void *) &info
->opts
, (void *) data
,
1273 sizeof (struct ifx_ssc_hwopts
));
1274 else if (copy_from_user ((void *) &info
->opts
,
1276 sizeof (struct ifx_ssc_hwopts
))) {
1280 if (ifx_ssc_hwinit (info
) < 0) {
1284 case IFX_SSC_HWOPTS_GET
:
1285 /* data must be a pointer to a struct ifx_ssc_hwopts */
1287 memcpy ((void *) data
, (void *) &info
->opts
,
1288 sizeof (struct ifx_ssc_hwopts
));
1289 else if (copy_to_user ((void *) data
,
1290 (void *) &info
->opts
,
1291 sizeof (struct ifx_ssc_hwopts
)))
1295 ret_val
= -ENOIOCTLCMD
;
1301 EXPORT_SYMBOL (ifx_ssc_ioctl
);
1304 ifx_ssc1_read_proc (char *page
, char **start
, off_t offset
, int count
,
1305 int *eof
, void *data
)
1308 unsigned long flags
;
1310 /* don't want any interrupts here */
1311 local_save_flags(flags
);
1312 local_irq_disable();
1314 /* print statistics */
1315 off
+= sprintf (page
+ off
,
1316 "Statistics for Infineon Synchronous Serial Controller SSC1\n");
1317 off
+= sprintf (page
+ off
, "RX overflow errors %d\n",
1318 isp
[0].stats
.rxOvErr
);
1319 off
+= sprintf (page
+ off
, "RX underflow errors %d\n",
1320 isp
[0].stats
.rxUnErr
);
1321 off
+= sprintf (page
+ off
, "TX overflow errors %d\n",
1322 isp
[0].stats
.txOvErr
);
1323 off
+= sprintf (page
+ off
, "TX underflow errors %d\n",
1324 isp
[0].stats
.txUnErr
);
1325 off
+= sprintf (page
+ off
, "Abort errors %d\n",
1326 isp
[0].stats
.abortErr
);
1327 off
+= sprintf (page
+ off
, "Mode errors %d\n", isp
[0].stats
.modeErr
);
1328 off
+= sprintf (page
+ off
, "RX Bytes %d\n", isp
[0].stats
.rxBytes
);
1329 off
+= sprintf (page
+ off
, "TX Bytes %d\n", isp
[0].stats
.txBytes
);
1331 local_irq_restore(flags
);
1337 * Due to the fact that a port can be dynamically switched between slave
1338 * and master mode using an IOCTL the hardware is not initialized here,
1339 * but in ifx_ssc_hwinit() as a result of an IOCTL.
1344 struct ifx_ssc_port
*info
;
1346 unsigned long flags
;
1349 // ### TO DO: dynamic port count evaluation due to pin multiplexing
1352 nbytes
= PORT_CNT
* sizeof (struct ifx_ssc_port
);
1353 isp
= (struct ifx_ssc_port
*) kmalloc (nbytes
, GFP_KERNEL
);
1355 printk ("%s: no memory for isp\n", __func__
);
1358 memset (isp
, 0, nbytes
);
1360 /* register the device */
1365 if ((i
= register_chrdev (maj
, "ssc", &ifx_ssc_fops
)) < 0) {
1366 printk ("Unable to register major %d for the Infineon SSC\n",
1374 register_chrdev (maj
, "ssc",
1375 &ifx_ssc_fops
)) < 0) {
1376 printk ("Unable to register major %d for the Infineon SSC\n", maj
);
1383 //printk("registered major %d for Infineon SSC\n", maj);
1385 /* set default values in ifx_ssc_port */
1386 for (i
= 0; i
< PORT_CNT
; i
++) {
1389 /* default values for the HwOpts */
1390 info
->opts
.AbortErrDetect
= IFX_SSC_DEF_ABRT_ERR_DETECT
;
1391 info
->opts
.rxOvErrDetect
= IFX_SSC_DEF_RO_ERR_DETECT
;
1392 info
->opts
.rxUndErrDetect
= IFX_SSC_DEF_RU_ERR_DETECT
;
1393 info
->opts
.txOvErrDetect
= IFX_SSC_DEF_TO_ERR_DETECT
;
1394 info
->opts
.txUndErrDetect
= IFX_SSC_DEF_TU_ERR_DETECT
;
1395 info
->opts
.loopBack
= IFX_SSC_DEF_LOOP_BACK
;
1396 info
->opts
.echoMode
= IFX_SSC_DEF_ECHO_MODE
;
1397 info
->opts
.idleValue
= IFX_SSC_DEF_IDLE_DATA
;
1398 info
->opts
.clockPolarity
= IFX_SSC_DEF_CLOCK_POLARITY
;
1399 info
->opts
.clockPhase
= IFX_SSC_DEF_CLOCK_PHASE
;
1400 info
->opts
.headingControl
= IFX_SSC_DEF_HEADING_CONTROL
;
1401 info
->opts
.dataWidth
= IFX_SSC_DEF_DATA_WIDTH
;
1402 info
->opts
.modeRxTx
= IFX_SSC_DEF_MODE_RXTX
;
1403 info
->opts
.gpoCs
= IFX_SSC_DEF_GPO_CS
;
1404 info
->opts
.gpoInv
= IFX_SSC_DEF_GPO_INV
;
1405 info
->opts
.masterSelect
= IFX_SSC_DEF_MASTERSLAVE
;
1406 info
->baud
= IFX_SSC_DEF_BAUDRATE
;
1409 /* values specific to SSC1 */
1411 info
->mapbase
= DANUBE_SSC1_BASE_ADDR
;
1412 // ### TO DO: power management
1414 // setting interrupt vectors
1415 info
->txirq
= DANUBE_SSC_TIR
;
1416 info
->rxirq
= DANUBE_SSC_RIR
;
1417 info
->errirq
= DANUBE_SSC_EIR
;
1419 info->frmirq = IFX_SSC_FIR;
1424 WRITE_PERIPHERAL_REGISTER (IFX_SSC_DEF_RMC
<<
1425 IFX_CLC_RUN_DIVIDER_OFFSET
,
1426 info
->mapbase
+ IFX_SSC_CLC
);
1428 // ### TO DO: multiple instances
1430 init_waitqueue_head (&info
->rwait
);
1431 //init_waitqueue_head(&info->pwait);
1433 local_irq_save (flags
);
1435 // init serial framing register
1436 WRITE_PERIPHERAL_REGISTER (IFX_SSC_DEF_SFCON
,
1437 info
->mapbase
+ IFX_SSC_SFCON
);
1439 /* try to get the interrupts */
1440 // ### TO DO: interrupt handling with multiple instances
1442 request_irq(info
->txirq
, ifx_ssc_tx_int
, SA_INTERRUPT
, "ifx_ssc_tx", info
);
1444 printk ("%s: unable to get irq %d\n", __func__
,
1446 local_irq_restore (flags
);
1450 request_irq(info
->rxirq
, ifx_ssc_rx_int
, SA_INTERRUPT
, "ifx_ssc_rx", info
);
1452 printk ("%s: unable to get irq %d\n", __func__
,
1454 local_irq_restore (flags
);
1458 request_irq(info
->errirq
, ifx_ssc_err_int
, SA_INTERRUPT
,"ifx_ssc_err", info
);
1460 printk ("%s: unable to get irq %d\n", __func__
,
1462 local_irq_restore (flags
);
1465 WRITE_PERIPHERAL_REGISTER (IFX_SSC_DEF_IRNEN
,
1466 info
->mapbase
+ IFX_SSC_IRN_EN
);
1467 enable_irq(info
->txirq
);
1468 enable_irq(info
->rxirq
);
1469 enable_irq(info
->errirq
);
1471 local_irq_restore (flags
);
1474 /* init the SSCs with default values */
1475 for (i
= 0; i
< PORT_CNT
; i
++) {
1477 if (ifx_ssc_hwinit (info
) < 0) {
1478 printk ("%s: hardware init failed for port %d\n",
1484 /* register /proc read handler */
1485 // ### TO DO: multiple instances
1486 /* for SSC1, which is always present */
1487 create_proc_read_entry ("driver/ssc1", 0, NULL
, ifx_ssc1_read_proc
,
1492 // ### TO DO: multiple instances
1493 free_irq(isp
[0].txirq
, &isp
[0]);
1494 free_irq(isp
[0].rxirq
, &isp
[0]);
1495 free_irq(isp
[0].errirq
, &isp
[0]);
1497 /* free up any allocated memory in the error case */
1500 } /* ifx_ssc_init */
1503 ifx_ssc_cleanup_module (void)
1507 /* free up any allocated memory */
1508 for (i
= 0; i
< PORT_CNT
; i
++) {
1509 /* disable the SSC */
1510 WRITE_PERIPHERAL_REGISTER (IFX_SSC_WHBSTATE_CLR_ENABLE
,
1511 isp
[i
].mapbase
+ IFX_SSC_WHBSTATE
);
1512 /* free the interrupts */
1513 free_irq(isp
[i
].txirq
, &isp
[i
]);
1514 free_irq(isp
[i
].rxirq
, &isp
[i
]);
1515 free_irq(isp
[i
].errirq
, &isp
[i
]);
1518 /* delete /proc read handler */
1519 remove_proc_entry ("driver/ssc1", NULL
);
1520 remove_proc_entry ("driver/ssc2", NULL
);
1523 module_init(ifx_ssc_init
);
1524 module_exit(ifx_ssc_cleanup_module
);
1528 ifx_ssc_cs_low (u32 pin
)
1531 if ((ret
= ifx_ssc_ioctl ((struct inode
*) 0, NULL
, IFX_SSC_GPO_OUT_CLR
, (unsigned long) &pin
)))
1532 printk ("clear CS %d fails\n", pin
);
1537 EXPORT_SYMBOL(ifx_ssc_cs_low
);
1540 ifx_ssc_cs_high (u32 pin
)
1543 if ((ret
= ifx_ssc_ioctl((struct inode
*) 0, NULL
, IFX_SSC_GPO_OUT_SET
, (unsigned long) &pin
)))
1544 printk ("set CS %d fails\n", pin
);
1549 EXPORT_SYMBOL(ifx_ssc_cs_high
);
1552 ssc_session (char *tx_buf
, u32 tx_len
, char *rx_buf
, u32 rx_len
)
1556 char *ssc_tx_buf
= NULL
;
1557 char *ssc_rx_buf
= NULL
;
1561 if (tx_buf
== NULL
&& tx_len
== 0 && rx_buf
== NULL
&& rx_len
== 0) {
1562 printk ("invalid parameters\n");
1564 goto ssc_session_exit
;
1566 else if (tx_buf
== NULL
|| tx_len
== 0) {
1567 if (rx_buf
!= NULL
&& rx_len
!= 0) {
1568 mode
= IFX_SSC_MODE_RX
;
1571 printk ("invalid parameters\n");
1573 goto ssc_session_exit
;
1576 else if (rx_buf
== NULL
|| rx_len
== 0) {
1577 if (tx_buf
!= NULL
&& tx_len
!= 0) {
1578 mode
= IFX_SSC_MODE_TX
;
1581 printk ("invalid parameters\n");
1583 goto ssc_session_exit
;
1587 mode
= IFX_SSC_MODE_RXTX
;
1590 if (mode
== IFX_SSC_MODE_RXTX
) {
1591 eff_size
= tx_len
+ rx_len
;
1593 else if (mode
== IFX_SSC_MODE_RX
) {
1600 //4 bytes alignment, required by driver
1601 /* change by TaiCheng */
1605 (char *) kmalloc (sizeof (char) *
1606 ((eff_size
+ 3) & (~3)),
1609 (char *) kmalloc (sizeof (char) *
1610 ((eff_size
+ 3) & (~3)),
1615 (char *) kmalloc (sizeof (char) *
1616 ((eff_size
+ 3) & (~3)),
1619 (char *) kmalloc (sizeof (char) *
1620 ((eff_size
+ 3) & (~3)),
1623 if (ssc_tx_buf
== NULL
|| ssc_rx_buf
== NULL
) {
1624 printk ("no memory for size of %d\n", eff_size
);
1626 goto ssc_session_exit
;
1628 memset ((void *) ssc_tx_buf
, 0, eff_size
);
1629 memset ((void *) ssc_rx_buf
, 0, eff_size
);
1632 memcpy (ssc_tx_buf
, tx_buf
, tx_len
);
1635 ret
= ifx_ssc_kwrite (0, ssc_tx_buf
, eff_size
);
1638 ssc_tx_buf
= NULL
; //should be freed by ifx_ssc_kwrite
1641 if (ret
!= eff_size
) {
1642 printk ("ifx_ssc_write return %d\n", ret
);
1643 goto ssc_session_exit
;
1645 ret
= ifx_ssc_kread (0, ssc_rx_buf
, eff_size
);
1646 if (ret
!= eff_size
) {
1647 printk ("ifx_ssc_read return %d\n", ret
);
1648 goto ssc_session_exit
;
1651 memcpy (rx_buf
, ssc_rx_buf
+ tx_len
, rx_len
);
1653 if (mode
== IFX_SSC_MODE_TX
) {
1661 if (ssc_tx_buf
!= NULL
)
1663 if (ssc_rx_buf
!= NULL
)
1667 printk ("ssc session fails\n");
1673 ifx_ssc_txrx (char *tx_buf
, u32 tx_len
, char *rx_buf
, u32 rx_len
)
1675 return ssc_session(tx_buf
, tx_len
, rx_buf
, rx_len
);
1677 EXPORT_SYMBOL(ifx_ssc_txrx
);
1680 ifx_ssc_tx (char *tx_buf
, u32 tx_len
)
1682 return ssc_session(tx_buf
, tx_len
, NULL
, 0);
1684 EXPORT_SYMBOL(ifx_ssc_tx
);
1687 ifx_ssc_rx (char *rx_buf
, u32 rx_len
)
1689 return ssc_session(NULL
, 0, rx_buf
, rx_len
);
1691 EXPORT_SYMBOL(ifx_ssc_rx
);
1693 MODULE_LICENSE("GPL");
1694 MODULE_AUTHOR("John Crispin <blogic@openwrt.org>");
1695 MODULE_DESCRIPTION("danube ssc driver");