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 *);
95 static void ifx_gpio_init (void);
97 extern unsigned int danube_get_fpi_hz (void);
98 extern void mask_and_ack_danube_irq (unsigned int irq_nr
);
100 static struct file_operations ifx_ssc_fops
= {
101 .owner
= THIS_MODULE
,
102 .read
= ifx_ssc_read
,
103 .write
= ifx_ssc_write
,
104 .ioctl
= ifx_ssc_ioctl
,
105 .open
= ifx_ssc_open
,
106 .release
= ifx_ssc_close
,
109 static inline unsigned int
110 ifx_ssc_get_kernel_clk (struct ifx_ssc_port
*info
)
111 { // ATTENTION: This function assumes that the CLC register is set with the
112 // appropriate value for RMC.
115 rmc
= (READ_PERIPHERAL_REGISTER (info
->mapbase
+ IFX_SSC_CLC
) &
116 IFX_CLC_RUN_DIVIDER_MASK
) >> IFX_CLC_RUN_DIVIDER_OFFSET
;
118 printk ("ifx_ssc_get_kernel_clk rmc==0 \n");
121 return (danube_get_fpi_hz () / rmc
);
125 #ifdef IFX_SSC_INT_USE_BH
127 * This routine is used by the interrupt handler to schedule
128 * processing in the software interrupt portion of the driver
129 * (also known as the "bottom half"). This can be called any
130 * number of times for any channel without harm.
133 ifx_ssc_sched_event (struct ifx_ssc_port
*info
, int event
)
135 info
->event
|= 1 << event
; /* remember what kind of event and who */
136 queue_task (&info
->tqueue
, &tq_cyclades
); /* it belongs to */
137 mark_bh (CYCLADES_BH
); /* then trigger event */
141 do_softint (void *private_
)
143 struct ifx_ssc_port
*info
= (struct ifx_ssc_port
*) private_
;
145 if (test_and_clear_bit (Cy_EVENT_HANGUP
, &info
->event
)) {
146 wake_up_interruptible (&info
->open_wait
);
147 info
->flags
&= ~(ASYNC_NORMAL_ACTIVE
| ASYNC_CALLOUT_ACTIVE
);
149 if (test_and_clear_bit (Cy_EVENT_OPEN_WAKEUP
, &info
->event
)) {
150 wake_up_interruptible (&info
->open_wait
);
152 if (test_and_clear_bit (Cy_EVENT_DELTA_WAKEUP
, &info
->event
)) {
153 wake_up_interruptible (&info
->delta_msr_wait
);
155 if (test_and_clear_bit (Cy_EVENT_WRITE_WAKEUP
, &info
->event
)) {
156 wake_up_interruptible (&tty
->write_wait
);
159 if (test_and_clear_bit (Cy_EVENT_SHUTDOWN_WAKEUP
, &info
->event
)) {
160 wake_up_interruptible (&info
->shutdown_wait
);
164 #endif /* IFX_SSC_INT_USE_BH */
168 rx_int (struct ifx_ssc_port
*info
)
170 int fifo_fill_lev
, bytes_in_buf
, i
;
171 unsigned long tmp_val
;
172 unsigned long *tmp_ptr
;
173 unsigned int rx_valid_cnt
;
174 /* number of words waiting in the RX FIFO */
175 fifo_fill_lev
= (READ_PERIPHERAL_REGISTER (info
->mapbase
+
177 IFX_SSC_FSTAT_RECEIVED_WORDS_MASK
) >>
178 IFX_SSC_FSTAT_RECEIVED_WORDS_OFFSET
;
179 // Note: There are always 32 bits in a fifo-entry except for the last
180 // word of a contigous transfer block and except for not in rx-only
181 // mode and CON.ENBV set. But for this case it should be a convention
182 // in software which helps:
183 // In tx or rx/tx mode all transfers from the buffer to the FIFO are
184 // 32-bit wide, except for the last three bytes, which could be a
185 // combination of 16- and 8-bit access.
186 // => The whole block is received as 32-bit words as a contigous stream,
187 // even if there was a gap in tx which has the fifo run out of data!
188 // Just the last fifo entry *may* be partially filled (0, 1, 2 or 3 bytes)!
190 /* free space in the RX buffer */
191 bytes_in_buf
= info
->rxbuf_end
- info
->rxbuf_ptr
;
192 // transfer with 32 bits per entry
193 while ((bytes_in_buf
>= 4) && (fifo_fill_lev
> 0)) {
194 tmp_ptr
= (unsigned long *) info
->rxbuf_ptr
;
196 READ_PERIPHERAL_REGISTER (info
->mapbase
+ IFX_SSC_RB
);
197 info
->rxbuf_ptr
+= 4;
198 info
->stats
.rxBytes
+= 4;
201 } // while ((bytes_in_buf >= 4) && (fifo_fill_lev > 0))
202 // now do the rest as mentioned in STATE.RXBV
203 while ((bytes_in_buf
> 0) && (fifo_fill_lev
> 0)) {
205 (READ_PERIPHERAL_REGISTER
207 IFX_SSC_STATE
) & IFX_SSC_STATE_RX_BYTE_VALID_MASK
)
208 >> IFX_SSC_STATE_RX_BYTE_VALID_OFFSET
;
209 if (rx_valid_cnt
== 0)
211 if (rx_valid_cnt
> bytes_in_buf
) {
212 // ### TO DO: warning message: not block aligned data, other data
213 // in this entry will be lost
214 rx_valid_cnt
= bytes_in_buf
;
217 READ_PERIPHERAL_REGISTER (info
->mapbase
+ IFX_SSC_RB
);
219 for (i
= 0; i
< rx_valid_cnt
; i
++) {
221 (tmp_val
>> (8 * (rx_valid_cnt
- i
- 1))) &
224 *info->rxbuf_ptr = tmp_val & 0xff;
231 info
->stats
.rxBytes
+= rx_valid_cnt
;
232 } // while ((bytes_in_buf > 0) && (fifo_fill_lev > 0))
234 // check if transfer is complete
235 if (info
->rxbuf_ptr
>= info
->rxbuf_end
) {
236 disable_irq(info
->rxirq
);
237 /* wakeup any processes waiting in read() */
238 wake_up_interruptible (&info
->rwait
);
240 //wake_up_interruptible(&info->pwait);
242 else if ((info
->opts
.modeRxTx
== IFX_SSC_MODE_RX
) &&
243 (READ_PERIPHERAL_REGISTER (info
->mapbase
+ IFX_SSC_RXCNT
) ==
245 // if buffer not filled completely and rx request done initiate new transfer
247 if (info->rxbuf_end - info->rxbuf_ptr < 65536)
249 if (info
->rxbuf_end
- info
->rxbuf_ptr
<
250 IFX_SSC_RXREQ_BLOCK_SIZE
)
251 WRITE_PERIPHERAL_REGISTER ((info
->rxbuf_end
-
254 IFX_SSC_RXREQ_RXCOUNT_OFFSET
,
258 WRITE_PERIPHERAL_REGISTER (IFX_SSC_RXREQ_BLOCK_SIZE
<<
259 IFX_SSC_RXREQ_RXCOUNT_OFFSET
,
266 tx_int (struct ifx_ssc_port
*info
)
269 int fifo_space
, fill
, i
;
270 fifo_space
= ((READ_PERIPHERAL_REGISTER (info
->mapbase
+ IFX_SSC_ID
) &
271 IFX_SSC_PERID_TXFS_MASK
) >> IFX_SSC_PERID_TXFS_OFFSET
)
273 ((READ_PERIPHERAL_REGISTER (info
->mapbase
+ IFX_SSC_FSTAT
) &
274 IFX_SSC_FSTAT_TRANSMIT_WORDS_MASK
) >>
275 IFX_SSC_FSTAT_TRANSMIT_WORDS_OFFSET
);
280 fill
= info
->txbuf_end
- info
->txbuf_ptr
;
282 if (fill
> fifo_space
* 4)
283 fill
= fifo_space
* 4;
285 for (i
= 0; i
< fill
/ 4; i
++) {
286 // at first 32 bit access
287 WRITE_PERIPHERAL_REGISTER (*(UINT32
*) info
->txbuf_ptr
,
288 info
->mapbase
+ IFX_SSC_TB
);
289 info
->txbuf_ptr
+= 4;
292 fifo_space
-= fill
/ 4;
293 info
->stats
.txBytes
+= fill
& ~0x3;
295 if ((fifo_space
> 0) & (fill
> 1)) {
296 // trailing 16 bit access
297 WRITE_PERIPHERAL_REGISTER_16 (*(UINT16
*) info
->txbuf_ptr
,
298 info
->mapbase
+ IFX_SSC_TB
);
299 info
->txbuf_ptr
+= 2;
300 info
->stats
.txBytes
+= 2;
302 /* added by bingtao */
305 if ((fifo_space
> 0) & (fill
> 0)) {
306 // trailing 8 bit access
307 WRITE_PERIPHERAL_REGISTER_8 (*(UINT8
*) info
->txbuf_ptr
,
308 info
->mapbase
+ IFX_SSC_TB
);
310 info
->stats
.txBytes
++;
316 // check if transmission complete
317 if (info
->txbuf_ptr
>= info
->txbuf_end
) {
318 disable_irq(info
->txirq
);
321 /* wake up any process waiting in poll() */
322 //wake_up_interruptible(&info->pwait);
328 ifx_ssc_rx_int (int irq
, void *dev_id
)
330 struct ifx_ssc_port
*info
= (struct ifx_ssc_port
*) dev_id
;
337 ifx_ssc_tx_int (int irq
, void *dev_id
)
339 struct ifx_ssc_port
*info
= (struct ifx_ssc_port
*) dev_id
;
346 ifx_ssc_err_int (int irq
, void *dev_id
)
348 struct ifx_ssc_port
*info
= (struct ifx_ssc_port
*) dev_id
;
350 unsigned int write_back
= 0;
353 local_irq_save (flags
);
354 state
= READ_PERIPHERAL_REGISTER (info
->mapbase
+ IFX_SSC_STATE
);
356 if ((state
& IFX_SSC_STATE_RX_UFL
) != 0) {
357 info
->stats
.rxUnErr
++;
358 write_back
|= IFX_SSC_WHBSTATE_CLR_RX_UFL_ERROR
;
360 if ((state
& IFX_SSC_STATE_RX_OFL
) != 0) {
361 info
->stats
.rxOvErr
++;
362 write_back
|= IFX_SSC_WHBSTATE_CLR_RX_OFL_ERROR
;
364 if ((state
& IFX_SSC_STATE_TX_OFL
) != 0) {
365 info
->stats
.txOvErr
++;
366 write_back
|= IFX_SSC_WHBSTATE_CLR_TX_OFL_ERROR
;
368 if ((state
& IFX_SSC_STATE_TX_UFL
) != 0) {
369 info
->stats
.txUnErr
++;
370 write_back
|= IFX_SSC_WHBSTATE_CLR_TX_UFL_ERROR
;
372 // if ((state & IFX_SSC_STATE_ABORT_ERR) != 0) {
373 // info->stats.abortErr++;
374 // write_back |= IFX_SSC_WHBSTATE_CLR_ABORT_ERROR;
376 if ((state
& IFX_SSC_STATE_MODE_ERR
) != 0) {
377 info
->stats
.modeErr
++;
378 write_back
|= IFX_SSC_WHBSTATE_CLR_MODE_ERROR
;
382 WRITE_PERIPHERAL_REGISTER (write_back
,
383 info
->mapbase
+ IFX_SSC_WHBSTATE
);
385 local_irq_restore (flags
);
391 ifx_ssc_abort (struct ifx_ssc_port
*info
)
396 local_irq_save (flags
);
398 disable_irq(info
->rxirq
);
399 disable_irq(info
->txirq
);
400 disable_irq(info
->errirq
);
402 local_irq_restore (flags
);
404 // disable SSC (also aborts a receive request!)
405 // ### TO DO: Perhaps it's better to abort after the receiption of a
406 // complete word. The disable cuts the transmission immediatly and
407 // releases the chip selects. This could result in unpredictable
408 // behavior of connected external devices!
409 enabled
= (READ_PERIPHERAL_REGISTER (info
->mapbase
+ IFX_SSC_STATE
)
410 & IFX_SSC_STATE_IS_ENABLED
) != 0;
411 WRITE_PERIPHERAL_REGISTER (IFX_SSC_WHBSTATE_CLR_ENABLE
,
412 info
->mapbase
+ IFX_SSC_WHBSTATE
);
415 WRITE_PERIPHERAL_REGISTER (IFX_SSC_XFCON_FIFO_FLUSH
,
416 info
->mapbase
+ IFX_SSC_TXFCON
);
417 WRITE_PERIPHERAL_REGISTER (IFX_SSC_XFCON_FIFO_FLUSH
,
418 info
->mapbase
+ IFX_SSC_RXFCON
);
421 if (info
->txbuf
!= NULL
) {
426 // wakeup read process
427 if (info
->rxbuf
!= NULL
)
428 wake_up_interruptible (&info
->rwait
);
430 // clear pending int's
431 mask_and_ack_danube_irq(info
->rxirq
);
432 mask_and_ack_danube_irq(info
->txirq
);
433 mask_and_ack_danube_irq(info
->errirq
);
436 WRITE_PERIPHERAL_REGISTER (IFX_SSC_WHBSTATE_CLR_ALL_ERROR
,
437 info
->mapbase
+ IFX_SSC_WHBSTATE
);
440 WRITE_PERIPHERAL_REGISTER (IFX_SSC_WHBSTATE_SET_ENABLE
,
441 info
->mapbase
+ IFX_SSC_WHBSTATE
);
446 * This routine is called whenever a port is opened. It enforces
447 * exclusive opening of a port and enables interrupts, etc.
450 ifx_ssc_open (struct inode
*inode
, struct file
*filp
)
452 struct ifx_ssc_port
*info
;
456 if ((inode
== (struct inode
*) 0) || (inode
== (struct inode
*) 1)) {
461 line
= MINOR (filp
->f_dentry
->d_inode
->i_rdev
);
462 filp
->f_op
= &ifx_ssc_fops
;
465 /* don't open more minor devices than we can support */
466 if (line
< 0 || line
>= PORT_CNT
)
472 if (info
->port_is_open
!= 0)
474 info
->port_is_open
++;
476 disable_irq(info
->rxirq
);
477 disable_irq(info
->txirq
);
478 disable_irq(info
->errirq
);
480 /* Flush and enable TX/RX FIFO */
481 WRITE_PERIPHERAL_REGISTER ((IFX_SSC_DEF_TXFIFO_FL
<<
482 IFX_SSC_XFCON_ITL_OFFSET
) |
483 IFX_SSC_XFCON_FIFO_FLUSH
|
484 IFX_SSC_XFCON_FIFO_ENABLE
,
485 info
->mapbase
+ IFX_SSC_TXFCON
);
486 WRITE_PERIPHERAL_REGISTER ((IFX_SSC_DEF_RXFIFO_FL
<<
487 IFX_SSC_XFCON_ITL_OFFSET
) |
488 IFX_SSC_XFCON_FIFO_FLUSH
|
489 IFX_SSC_XFCON_FIFO_ENABLE
,
490 info
->mapbase
+ IFX_SSC_RXFCON
);
492 /* logically flush the software FIFOs */
496 /* clear all error bits */
497 WRITE_PERIPHERAL_REGISTER (IFX_SSC_WHBSTATE_CLR_ALL_ERROR
,
498 info
->mapbase
+ IFX_SSC_WHBSTATE
);
500 // clear pending interrupts
501 mask_and_ack_danube_irq(info
->rxirq
);
502 mask_and_ack_danube_irq(info
->txirq
);
503 mask_and_ack_danube_irq(info
->errirq
);
505 WRITE_PERIPHERAL_REGISTER (IFX_SSC_WHBSTATE_SET_ENABLE
,
506 info
->mapbase
+ IFX_SSC_WHBSTATE
);
510 EXPORT_SYMBOL (ifx_ssc_open
);
513 * This routine is called when a particular device is closed.
516 ifx_ssc_close (struct inode
*inode
, struct file
*filp
)
518 struct ifx_ssc_port
*info
;
521 if ((inode
== (struct inode
*) 0) || (inode
== (struct inode
*) 1))
524 idx
= MINOR (filp
->f_dentry
->d_inode
->i_rdev
);
526 if (idx
< 0 || idx
>= PORT_CNT
)
534 WRITE_PERIPHERAL_REGISTER (IFX_SSC_WHBSTATE_CLR_ENABLE
,
535 info
->mapbase
+ IFX_SSC_WHBSTATE
);
537 // call abort function to disable int's, flush fifos...
538 ifx_ssc_abort (info
);
540 info
->port_is_open
--;
544 EXPORT_SYMBOL (ifx_ssc_close
);
546 /* added by bingtao */
547 /* helper routine to handle reads from the kernel or user-space */
548 /* info->rxbuf : never kfree and contains valid data */
549 /* should be points to NULL after copying data !!! */
551 ifx_ssc_read_helper_poll (struct ifx_ssc_port
*info
, char *buf
, size_t len
,
557 if (info
->opts
.modeRxTx
== IFX_SSC_MODE_TX
)
559 local_irq_save (flags
);
560 info
->rxbuf_ptr
= info
->rxbuf
;
561 info
->rxbuf_end
= info
->rxbuf
+ len
;
562 local_irq_restore (flags
);
563 /* Vinetic driver always works in IFX_SSC_MODE_RXTX */
564 /* TXRX in poll mode */
565 while (info
->rxbuf_ptr
< info
->rxbuf_end
) {
566 /* This is the key point, if you don't check this condition
567 kfree (NULL) will happen
568 because tx only need write into FIFO, it's much fast than rx
569 So when rx still waiting , tx already finish and release buf
571 if (info
->txbuf_ptr
< info
->txbuf_end
) {
578 ret_val
= info
->rxbuf_ptr
- info
->rxbuf
;
582 /* helper routine to handle reads from the kernel or user-space */
583 /* info->rx_buf : never kfree and contains valid data */
584 /* should be points to NULL after copying data !!! */
586 ifx_ssc_read_helper (struct ifx_ssc_port
*info
, char *buf
, size_t len
,
591 DECLARE_WAITQUEUE (wait
, current
);
593 if (info
->opts
.modeRxTx
== IFX_SSC_MODE_TX
)
595 local_irq_save (flags
);
596 info
->rxbuf_ptr
= info
->rxbuf
;
597 info
->rxbuf_end
= info
->rxbuf
+ len
;
598 if (info
->opts
.modeRxTx
== IFX_SSC_MODE_RXTX
) {
599 if ((info
->txbuf
== NULL
) ||
600 (info
->txbuf
!= info
->txbuf_ptr
) ||
601 (info
->txbuf_end
!= len
+ info
->txbuf
)) {
602 local_irq_restore (flags
);
603 printk ("IFX SSC - %s: write must be called before calling " "read in combined RX/TX!\n", __FUNCTION__
);
606 local_irq_restore (flags
);
607 /* should enable tx, right? */
609 if (info
->txbuf_ptr
< info
->txbuf_end
)
610 enable_irq(info
->txirq
);
612 enable_irq(info
->rxirq
);
615 local_irq_restore (flags
);
616 if (READ_PERIPHERAL_REGISTER (info
->mapbase
+ IFX_SSC_RXCNT
) &
617 IFX_SSC_RXCNT_TODO_MASK
)
619 enable_irq(info
->rxirq
);
620 // rx request limited to ' bytes
624 if (len
< IFX_SSC_RXREQ_BLOCK_SIZE
)
625 WRITE_PERIPHERAL_REGISTER (len
<<
626 IFX_SSC_RXREQ_RXCOUNT_OFFSET
,
630 WRITE_PERIPHERAL_REGISTER (IFX_SSC_RXREQ_BLOCK_SIZE
<<
631 IFX_SSC_RXREQ_RXCOUNT_OFFSET
,
636 __add_wait_queue (&info
->rwait
, &wait
);
637 set_current_state (TASK_INTERRUPTIBLE
);
638 // wakeup done in rx_int
641 local_irq_save (flags
);
642 if (info
->rxbuf_ptr
>= info
->rxbuf_end
)
644 local_irq_restore (flags
);
646 if (signal_pending (current
)) {
647 ret_val
= -ERESTARTSYS
;
653 ret_val
= info
->rxbuf_ptr
- info
->rxbuf
;
654 local_irq_restore (flags
);
657 current
->state
= TASK_RUNNING
;
658 __remove_wait_queue (&info
->rwait
, &wait
);
663 /* helper routine to handle writes to the kernel or user-space */
664 /* info->txbuf has two cases:
665 * 1) return value < 0 (-EFAULT), not touched at all
666 * 2) kfree and points to NULL in interrupt routine (but maybe later )
669 ifx_ssc_write_helper (struct ifx_ssc_port
*info
, const char *buf
,
670 size_t len
, int from_kernel
)
672 // check if in tx or tx/rx mode
673 if (info
->opts
.modeRxTx
== IFX_SSC_MODE_RX
)
676 info
->txbuf_ptr
= info
->txbuf
;
677 info
->txbuf_end
= len
+ info
->txbuf
;
678 /* start the transmission (not in rx/tx, see read helper) */
679 if (info
->opts
.modeRxTx
== IFX_SSC_MODE_TX
) {
681 if (info
->txbuf_ptr
< info
->txbuf_end
) {
682 enable_irq(info
->txirq
);
685 //local_irq_restore(flags);
690 * kernel interfaces for read and write.
691 * The caller must set port to: n for SSC<m> with n=m-1 (e.g. n=0 for SSC1)
694 ifx_ssc_kread (int port
, char *kbuf
, size_t len
)
696 struct ifx_ssc_port
*info
;
699 if (port
< 0 || port
>= PORT_CNT
)
707 // check if reception in progress
708 if (info
->rxbuf
!= NULL
) {
709 printk ("SSC device busy\n");
714 if (info
->rxbuf
== NULL
) {
715 printk ("SSC device error\n");
719 /* changed by bingtao */
720 /* change by TaiCheng */
723 ret_val
= ifx_ssc_read_helper (info
, kbuf
, len
, 1);
726 ret_val
= ifx_ssc_read_helper_poll (info
, kbuf
, len
, 1);
730 // ### TO DO: perhaps warn if ret_val != len
731 disable_irq(info
->rxirq
);
736 EXPORT_SYMBOL (ifx_ssc_kread
);
739 ifx_ssc_kwrite (int port
, const char *kbuf
, size_t len
)
741 struct ifx_ssc_port
*info
;
744 if (port
< 0 || port
>= PORT_CNT
)
752 // check if transmission in progress
753 if (info
->txbuf
!= NULL
)
755 info
->txbuf
= (char *) kbuf
;
757 ret_val
= ifx_ssc_write_helper (info
, info
->txbuf
, len
, 1);
764 EXPORT_SYMBOL (ifx_ssc_kwrite
);
767 * user interfaces to read and write
770 ifx_ssc_read (struct file
*filp
, char *ubuf
, size_t len
, loff_t
* off
)
774 struct ifx_ssc_port
*info
;
780 idx
= MINOR (filp
->f_dentry
->d_inode
->i_rdev
);
783 // check if reception in progress
784 if (info
->rxbuf
!= NULL
)
787 info
->rxbuf
= kmalloc (len
+ 3, GFP_KERNEL
);
788 if (info
->rxbuf
== NULL
)
791 ret_val
= ifx_ssc_read_helper (info
, info
->rxbuf
, len
, 0);
792 // ### TO DO: perhaps warn if ret_val != len
793 if (copy_to_user ((void *) ubuf
, info
->rxbuf
, ret_val
) != 0)
796 disable_irq(info
->rxirq
);
804 * As many bytes as we have free space for are copied from the user
805 * into txbuf and the actual byte count is returned. The transmission is
806 * always kicked off by calling the appropriate TX routine.
809 ifx_ssc_write (struct file
*filp
, const char *ubuf
, size_t len
, loff_t
* off
)
812 struct ifx_ssc_port
*info
;
818 idx
= MINOR (filp
->f_dentry
->d_inode
->i_rdev
);
821 // check if transmission in progress
822 if (info
->txbuf
!= NULL
)
825 info
->txbuf
= kmalloc (len
+ 3, GFP_KERNEL
);
826 if (info
->txbuf
== NULL
)
829 ret_val
= copy_from_user (info
->txbuf
, ubuf
, len
);
831 ret_val
= ifx_ssc_write_helper (info
, info
->txbuf
, len
, 0);
835 kfree (info
->txbuf
); // otherwise will be done in ISR
841 static struct ifx_ssc_frm_status
*
842 ifx_ssc_frm_status_get (struct ifx_ssc_port
*info
)
846 tmp
= READ_PERIPHERAL_REGISTER (info
->mapbase
+ IFX_SSC_SFSTAT
);
847 info
->frm_status
.DataBusy
= (tmp
& IFX_SSC_SFSTAT_IN_DATA
) > 0;
848 info
->frm_status
.PauseBusy
= (tmp
& IFX_SSC_SFSTAT_IN_PAUSE
) > 0;
849 info
->frm_status
.DataCount
= (tmp
& IFX_SSC_SFSTAT_DATA_COUNT_MASK
)
850 >> IFX_SSC_SFSTAT_DATA_COUNT_OFFSET
;
851 info
->frm_status
.PauseCount
= (tmp
& IFX_SSC_SFSTAT_PAUSE_COUNT_MASK
)
852 >> IFX_SSC_SFSTAT_PAUSE_COUNT_OFFSET
;
853 tmp
= READ_PERIPHERAL_REGISTER (info
->mapbase
+ IFX_SSC_SFCON
);
854 info
->frm_status
.EnIntAfterData
=
855 (tmp
& IFX_SSC_SFCON_FIR_ENABLE_BEFORE_PAUSE
) > 0;
856 info
->frm_status
.EnIntAfterPause
=
857 (tmp
& IFX_SSC_SFCON_FIR_ENABLE_AFTER_PAUSE
) > 0;
858 return (&info
->frm_status
);
862 static struct ifx_ssc_frm_opts
*
863 ifx_ssc_frm_control_get (struct ifx_ssc_port
*info
)
867 tmp
= READ_PERIPHERAL_REGISTER (info
->mapbase
+ IFX_SSC_SFCON
);
868 info
->frm_opts
.FrameEnable
= (tmp
& IFX_SSC_SFCON_SF_ENABLE
) > 0;
869 info
->frm_opts
.DataLength
= (tmp
& IFX_SSC_SFCON_DATA_LENGTH_MASK
)
870 >> IFX_SSC_SFCON_DATA_LENGTH_OFFSET
;
871 info
->frm_opts
.PauseLength
= (tmp
& IFX_SSC_SFCON_PAUSE_LENGTH_MASK
)
872 >> IFX_SSC_SFCON_PAUSE_LENGTH_OFFSET
;
873 info
->frm_opts
.IdleData
= (tmp
& IFX_SSC_SFCON_PAUSE_DATA_MASK
)
874 >> IFX_SSC_SFCON_PAUSE_DATA_OFFSET
;
875 info
->frm_opts
.IdleClock
= (tmp
& IFX_SSC_SFCON_PAUSE_CLOCK_MASK
)
876 >> IFX_SSC_SFCON_PAUSE_CLOCK_OFFSET
;
877 info
->frm_opts
.StopAfterPause
=
878 (tmp
& IFX_SSC_SFCON_STOP_AFTER_PAUSE
) > 0;
879 return (&info
->frm_opts
);
883 ifx_ssc_frm_control_set (struct ifx_ssc_port
*info
)
888 if ((info
->frm_opts
.DataLength
> IFX_SSC_SFCON_DATA_LENGTH_MAX
) ||
889 (info
->frm_opts
.DataLength
< 1) ||
890 (info
->frm_opts
.PauseLength
> IFX_SSC_SFCON_PAUSE_LENGTH_MAX
) ||
891 (info
->frm_opts
.PauseLength
< 1) ||
892 ((info
->frm_opts
.IdleData
& ~(IFX_SSC_SFCON_PAUSE_DATA_MASK
>>
893 IFX_SSC_SFCON_PAUSE_DATA_OFFSET
)) !=
897 IdleClock
& ~(IFX_SSC_SFCON_PAUSE_CLOCK_MASK
>>
898 IFX_SSC_SFCON_PAUSE_CLOCK_OFFSET
)) != 0))
901 // read interrupt bits (they're not changed here)
902 tmp
= READ_PERIPHERAL_REGISTER (info
->mapbase
+ IFX_SSC_SFCON
) &
903 (IFX_SSC_SFCON_FIR_ENABLE_BEFORE_PAUSE
|
904 IFX_SSC_SFCON_FIR_ENABLE_AFTER_PAUSE
);
906 // set all values with respect to it's bit position (for data and pause
908 tmp
= (info
->frm_opts
.DataLength
-
909 1) << IFX_SSC_SFCON_DATA_LENGTH_OFFSET
;
910 tmp
|= (info
->frm_opts
.PauseLength
-
911 1) << IFX_SSC_SFCON_PAUSE_LENGTH_OFFSET
;
912 tmp
|= info
->frm_opts
.IdleData
<< IFX_SSC_SFCON_PAUSE_DATA_OFFSET
;
913 tmp
|= info
->frm_opts
.IdleClock
<< IFX_SSC_SFCON_PAUSE_CLOCK_OFFSET
;
914 tmp
|= info
->frm_opts
.FrameEnable
* IFX_SSC_SFCON_SF_ENABLE
;
915 tmp
|= info
->frm_opts
.StopAfterPause
* IFX_SSC_SFCON_STOP_AFTER_PAUSE
;
917 WRITE_PERIPHERAL_REGISTER (tmp
, info
->mapbase
+ IFX_SSC_SFCON
);
923 ifx_ssc_rxtx_mode_set (struct ifx_ssc_port
*info
, unsigned int val
)
928 if (!(info
) || (val
& ~(IFX_SSC_MODE_MASK
)))
930 /*check BUSY and RXCNT */
931 if (READ_PERIPHERAL_REGISTER (info
->mapbase
+ IFX_SSC_STATE
) &
933 || READ_PERIPHERAL_REGISTER (info
->mapbase
+
935 IFX_SSC_RXCNT_TODO_MASK
)
938 tmp
= (READ_PERIPHERAL_REGISTER (info
->mapbase
+ IFX_SSC_CON
) &
939 ~(IFX_SSC_CON_RX_OFF
| IFX_SSC_CON_TX_OFF
)) | (val
);
940 WRITE_PERIPHERAL_REGISTER (tmp
, info
->mapbase
+ IFX_SSC_CON
);
941 info
->opts
.modeRxTx
= val
;
948 /* TODO: P0.9 SPI_CS4, P0.10 SPI_CS5, P 0.11 SPI_CS6, because of ASC0 */
949 /* p0.15 SPI_CS1(EEPROM), P0.13 SPI_CS3, */
950 /* Set p0.15 to alternative 01, others to 00 (In/OUT) */
951 *(DANUBE_GPIO_P0_DIR
) = (*DANUBE_GPIO_P0_DIR
) | (0xA000);
952 *(DANUBE_GPIO_P0_ALTSEL0
) =
953 (((*DANUBE_GPIO_P0_ALTSEL0
) | (0x8000)) & (~(0x2000)));
954 *(DANUBE_GPIO_P0_ALTSEL1
) =
955 (((*DANUBE_GPIO_P0_ALTSEL1
) & (~0x8000)) & (~(0x2000)));
956 *(DANUBE_GPIO_P0_OD
) = (*DANUBE_GPIO_P0_OD
) | 0xA000;
958 /* p1.6 SPI_CS2(SFLASH), p1.0 SPI_DIN, p1.1 SPI_DOUT, p1.2 SPI_CLK */
959 *(DANUBE_GPIO_P1_DIR
) = ((*DANUBE_GPIO_P1_DIR
) | (0x46)) & (~1);
960 *(DANUBE_GPIO_P1_ALTSEL0
) = ((*DANUBE_GPIO_P1_ALTSEL0
) | (0x47));
961 *(DANUBE_GPIO_P1_ALTSEL1
) = (*DANUBE_GPIO_P1_ALTSEL1
) & (~0x47);
962 *(DANUBE_GPIO_P1_OD
) = (*DANUBE_GPIO_P1_OD
) | 0x0046;
965 /*TODO: CS4 CS5 CS6 */
966 *DANUBE_GPIO_P0_OUT
= ((*DANUBE_GPIO_P0_OUT
) | 0x2000);
971 ifx_ssc_sethwopts (struct ifx_ssc_port
*info
)
973 unsigned long flags
, bits
;
974 struct ifx_ssc_hwopts
*opts
= &info
->opts
;
977 if ((opts
->dataWidth
< IFX_SSC_MIN_DATA_WIDTH
) ||
978 (opts
->dataWidth
> IFX_SSC_MAX_DATA_WIDTH
)) {
979 printk ("%s: sanity check failed\n", __FUNCTION__
);
982 bits
= (opts
->dataWidth
- 1) << IFX_SSC_CON_DATA_WIDTH_OFFSET
;
983 bits
|= IFX_SSC_CON_ENABLE_BYTE_VALID
;
984 // if (opts->abortErrDetect)
985 // bits |= IFX_SSC_CON_ABORT_ERR_CHECK;
986 if (opts
->rxOvErrDetect
)
987 bits
|= IFX_SSC_CON_RX_OFL_CHECK
;
988 if (opts
->rxUndErrDetect
)
989 bits
|= IFX_SSC_CON_RX_UFL_CHECK
;
990 if (opts
->txOvErrDetect
)
991 bits
|= IFX_SSC_CON_TX_OFL_CHECK
;
992 if (opts
->txUndErrDetect
)
993 bits
|= IFX_SSC_CON_TX_UFL_CHECK
;
995 bits
|= IFX_SSC_CON_LOOPBACK_MODE
;
997 bits
|= IFX_SSC_CON_ECHO_MODE_ON
;
998 if (opts
->headingControl
)
999 bits
|= IFX_SSC_CON_MSB_FIRST
;
1000 if (opts
->clockPhase
)
1001 bits
|= IFX_SSC_CON_LATCH_THEN_SHIFT
;
1002 if (opts
->clockPolarity
)
1003 bits
|= IFX_SSC_CON_CLOCK_FALL
;
1004 switch (opts
->modeRxTx
) {
1005 case IFX_SSC_MODE_TX
:
1006 bits
|= IFX_SSC_CON_RX_OFF
;
1008 case IFX_SSC_MODE_RX
:
1009 bits
|= IFX_SSC_CON_TX_OFF
;
1011 } // switch (opts->modeRxT)
1012 local_irq_save (flags
);
1013 WRITE_PERIPHERAL_REGISTER (bits
, info
->mapbase
+ IFX_SSC_CON
);
1014 WRITE_PERIPHERAL_REGISTER ((info
->opts
.
1015 gpoCs
<< IFX_SSC_GPOCON_ISCSB0_POS
) |
1017 gpoInv
<< IFX_SSC_GPOCON_INVOUT0_POS
),
1018 info
->mapbase
+ IFX_SSC_GPOCON
);
1019 /*TODO: disable cs */
1020 WRITE_PERIPHERAL_REGISTER (info
->opts
.
1021 gpoCs
<< IFX_SSC_WHBGPOSTAT_SETOUT0_POS
,
1022 info
->mapbase
+ IFX_SSC_WHBGPOSTAT
);
1025 if (opts
->masterSelect
) {
1026 WRITE_PERIPHERAL_REGISTER (IFX_SSC_WHBSTATE_SET_MASTER_SELECT
,
1027 info
->mapbase
+ IFX_SSC_WHBSTATE
);
1030 WRITE_PERIPHERAL_REGISTER (IFX_SSC_WHBSTATE_CLR_MASTER_SELECT
,
1031 info
->mapbase
+ IFX_SSC_WHBSTATE
);
1033 // init serial framing
1034 WRITE_PERIPHERAL_REGISTER (0, info
->mapbase
+ IFX_SSC_SFCON
);
1035 /* set up the port pins */
1036 //check for general requirements to switch (external) pad/pin characteristics
1038 local_irq_restore (flags
);
1044 ifx_ssc_set_baud (struct ifx_ssc_port
*info
, unsigned int baud
)
1046 unsigned int ifx_ssc_clock
;
1048 unsigned long flags
;
1051 ifx_ssc_clock
= ifx_ssc_get_kernel_clk (info
);
1052 if (ifx_ssc_clock
== 0)
1054 local_irq_save (flags
);
1055 /* have to disable the SSC to set the baudrate */
1056 enabled
= (READ_PERIPHERAL_REGISTER (info
->mapbase
+ IFX_SSC_STATE
)
1057 & IFX_SSC_STATE_IS_ENABLED
) != 0;
1058 WRITE_PERIPHERAL_REGISTER (IFX_SSC_WHBSTATE_CLR_ENABLE
,
1059 info
->mapbase
+ IFX_SSC_WHBSTATE
);
1062 br
= (((ifx_ssc_clock
>> 1) + baud
/ 2) / baud
) - 1;
1066 ((READ_PERIPHERAL_REGISTER (info
->mapbase
+ IFX_SSC_STATE
) &
1067 IFX_SSC_STATE_IS_MASTER
) == 0))) {
1068 local_irq_restore (flags
);
1069 printk ("%s: illegal baudrate %u\n", __FUNCTION__
, baud
);
1072 WRITE_PERIPHERAL_REGISTER (br
, info
->mapbase
+ IFX_SSC_BR
);
1074 WRITE_PERIPHERAL_REGISTER (IFX_SSC_WHBSTATE_SET_ENABLE
,
1075 info
->mapbase
+ IFX_SSC_WHBSTATE
);
1077 local_irq_restore (flags
);
1082 ifx_ssc_hwinit (struct ifx_ssc_port
*info
)
1084 unsigned long flags
;
1087 /* have to disable the SSC */
1088 enabled
= (READ_PERIPHERAL_REGISTER (info
->mapbase
+ IFX_SSC_STATE
)
1089 & IFX_SSC_STATE_IS_ENABLED
) != 0;
1090 WRITE_PERIPHERAL_REGISTER (IFX_SSC_WHBSTATE_CLR_ENABLE
,
1091 info
->mapbase
+ IFX_SSC_WHBSTATE
);
1093 if (ifx_ssc_sethwopts (info
) < 0) {
1094 printk ("%s: setting the hardware options failed\n",
1099 if (ifx_ssc_set_baud (info
, info
->baud
) < 0) {
1100 printk ("%s: setting the baud rate failed\n", __FUNCTION__
);
1103 local_irq_save (flags
);
1105 WRITE_PERIPHERAL_REGISTER ((IFX_SSC_DEF_TXFIFO_FL
<<
1106 IFX_SSC_XFCON_ITL_OFFSET
) |
1107 IFX_SSC_XFCON_FIFO_ENABLE
,
1108 info
->mapbase
+ IFX_SSC_TXFCON
);
1110 WRITE_PERIPHERAL_REGISTER ((IFX_SSC_DEF_RXFIFO_FL
<<
1111 IFX_SSC_XFCON_ITL_OFFSET
) |
1112 IFX_SSC_XFCON_FIFO_ENABLE
,
1113 info
->mapbase
+ IFX_SSC_RXFCON
);
1114 local_irq_restore (flags
);
1116 WRITE_PERIPHERAL_REGISTER (IFX_SSC_WHBSTATE_SET_ENABLE
,
1117 info
->mapbase
+ IFX_SSC_WHBSTATE
);
1122 ifx_ssc_ioctl (struct inode
*inode
, struct file
*filp
, unsigned int cmd
,
1125 struct ifx_ssc_port
*info
;
1126 int line
, ret_val
= 0;
1127 unsigned long flags
;
1129 int from_kernel
= 0;
1131 if ((inode
== (struct inode
*) 0) || (inode
== (struct inode
*) 1)) {
1136 line
= MINOR (filp
->f_dentry
->d_inode
->i_rdev
);
1138 /* don't use more minor devices than we can support */
1139 if (line
< 0 || line
>= PORT_CNT
)
1145 case IFX_SSC_STATS_READ
:
1146 /* data must be a pointer to a struct ifx_ssc_statistics */
1148 memcpy ((void *) data
, (void *) &info
->stats
,
1149 sizeof (struct ifx_ssc_statistics
));
1150 else if (copy_to_user ((void *) data
,
1151 (void *) &info
->stats
,
1152 sizeof (struct ifx_ssc_statistics
)))
1155 case IFX_SSC_STATS_RESET
:
1156 /* just resets the statistics counters */
1157 memset ((void *) &info
->stats
, 0,
1158 sizeof (struct ifx_ssc_statistics
));
1160 case IFX_SSC_BAUD_SET
:
1161 /* if the buffers are not empty then the port is */
1162 /* busy and we shouldn't change things on-the-fly! */
1163 if (!info
->txbuf
|| !info
->rxbuf
||
1164 (READ_PERIPHERAL_REGISTER (info
->mapbase
+ IFX_SSC_STATE
)
1165 & IFX_SSC_STATE_BUSY
)) {
1171 flags
= *((unsigned long *) data
);
1172 else if (copy_from_user ((void *) &flags
,
1173 (void *) data
, sizeof (flags
))) {
1181 if (ifx_ssc_set_baud (info
, flags
) < 0) {
1187 case IFX_SSC_BAUD_GET
:
1189 *((unsigned int *) data
) = info
->baud
;
1190 else if (copy_to_user ((void *) data
,
1191 (void *) &info
->baud
,
1192 sizeof (unsigned long)))
1195 case IFX_SSC_RXTX_MODE_SET
:
1197 tmp
= *((unsigned long *) data
);
1198 else if (copy_from_user ((void *) &tmp
,
1199 (void *) data
, sizeof (tmp
))) {
1203 ret_val
= ifx_ssc_rxtx_mode_set (info
, tmp
);
1205 case IFX_SSC_RXTX_MODE_GET
:
1206 tmp
= READ_PERIPHERAL_REGISTER (info
->mapbase
+ IFX_SSC_CON
) &
1207 (~(IFX_SSC_CON_RX_OFF
| IFX_SSC_CON_TX_OFF
));
1209 *((unsigned int *) data
) = tmp
;
1210 else if (copy_to_user ((void *) data
,
1211 (void *) &tmp
, sizeof (tmp
)))
1216 ifx_ssc_abort (info
);
1219 case IFX_SSC_GPO_OUT_SET
:
1221 tmp
= *((unsigned long *) data
);
1222 else if (copy_from_user ((void *) &tmp
,
1223 (void *) data
, sizeof (tmp
))) {
1227 if (tmp
> IFX_SSC_MAX_GPO_OUT
)
1230 WRITE_PERIPHERAL_REGISTER
1231 (1 << (tmp
+ IFX_SSC_WHBGPOSTAT_SETOUT0_POS
),
1232 info
->mapbase
+ IFX_SSC_WHBGPOSTAT
);
1234 case IFX_SSC_GPO_OUT_CLR
:
1236 tmp
= *((unsigned long *) data
);
1237 else if (copy_from_user ((void *) &tmp
,
1238 (void *) data
, sizeof (tmp
))) {
1242 if (tmp
> IFX_SSC_MAX_GPO_OUT
)
1245 WRITE_PERIPHERAL_REGISTER
1246 (1 << (tmp
+ IFX_SSC_WHBGPOSTAT_CLROUT0_POS
),
1247 info
->mapbase
+ IFX_SSC_WHBGPOSTAT
);
1250 case IFX_SSC_GPO_OUT_GET
:
1251 tmp
= READ_PERIPHERAL_REGISTER
1252 (info
->mapbase
+ IFX_SSC_GPOSTAT
);
1254 *((unsigned int *) data
) = tmp
;
1255 else if (copy_to_user ((void *) data
,
1256 (void *) &tmp
, sizeof (tmp
)))
1259 case IFX_SSC_FRM_STATUS_GET
:
1260 ifx_ssc_frm_status_get (info
);
1262 memcpy ((void *) data
, (void *) &info
->frm_status
,
1263 sizeof (struct ifx_ssc_frm_status
));
1264 else if (copy_to_user ((void *) data
,
1265 (void *) &info
->frm_status
,
1266 sizeof (struct ifx_ssc_frm_status
)))
1269 case IFX_SSC_FRM_CONTROL_GET
:
1270 ifx_ssc_frm_control_get (info
);
1272 memcpy ((void *) data
, (void *) &info
->frm_opts
,
1273 sizeof (struct ifx_ssc_frm_opts
));
1274 else if (copy_to_user ((void *) data
,
1275 (void *) &info
->frm_opts
,
1276 sizeof (struct ifx_ssc_frm_opts
)))
1279 case IFX_SSC_FRM_CONTROL_SET
:
1281 memcpy ((void *) &info
->frm_opts
, (void *) data
,
1282 sizeof (struct ifx_ssc_frm_opts
));
1283 else if (copy_to_user ((void *) &info
->frm_opts
,
1285 sizeof (struct ifx_ssc_frm_opts
))) {
1289 ret_val
= ifx_ssc_frm_control_set (info
);
1291 case IFX_SSC_HWOPTS_SET
:
1292 /* data must be a pointer to a struct ifx_ssc_hwopts */
1293 /* if the buffers are not empty then the port is */
1294 /* busy and we shouldn't change things on-the-fly! */
1295 if (!info
->txbuf
|| !info
->rxbuf
||
1296 (READ_PERIPHERAL_REGISTER (info
->mapbase
+ IFX_SSC_STATE
)
1297 & IFX_SSC_STATE_BUSY
)) {
1302 memcpy ((void *) &info
->opts
, (void *) data
,
1303 sizeof (struct ifx_ssc_hwopts
));
1304 else if (copy_from_user ((void *) &info
->opts
,
1306 sizeof (struct ifx_ssc_hwopts
))) {
1310 if (ifx_ssc_hwinit (info
) < 0) {
1314 case IFX_SSC_HWOPTS_GET
:
1315 /* data must be a pointer to a struct ifx_ssc_hwopts */
1317 memcpy ((void *) data
, (void *) &info
->opts
,
1318 sizeof (struct ifx_ssc_hwopts
));
1319 else if (copy_to_user ((void *) data
,
1320 (void *) &info
->opts
,
1321 sizeof (struct ifx_ssc_hwopts
)))
1325 ret_val
= -ENOIOCTLCMD
;
1331 EXPORT_SYMBOL (ifx_ssc_ioctl
);
1334 ifx_ssc1_read_proc (char *page
, char **start
, off_t offset
, int count
,
1335 int *eof
, void *data
)
1338 unsigned long flags
;
1340 /* don't want any interrupts here */
1341 local_save_flags(flags
);
1342 local_irq_disable();
1344 /* print statistics */
1345 off
+= sprintf (page
+ off
,
1346 "Statistics for Infineon Synchronous Serial Controller SSC1\n");
1347 off
+= sprintf (page
+ off
, "RX overflow errors %d\n",
1348 isp
[0].stats
.rxOvErr
);
1349 off
+= sprintf (page
+ off
, "RX underflow errors %d\n",
1350 isp
[0].stats
.rxUnErr
);
1351 off
+= sprintf (page
+ off
, "TX overflow errors %d\n",
1352 isp
[0].stats
.txOvErr
);
1353 off
+= sprintf (page
+ off
, "TX underflow errors %d\n",
1354 isp
[0].stats
.txUnErr
);
1355 off
+= sprintf (page
+ off
, "Abort errors %d\n",
1356 isp
[0].stats
.abortErr
);
1357 off
+= sprintf (page
+ off
, "Mode errors %d\n", isp
[0].stats
.modeErr
);
1358 off
+= sprintf (page
+ off
, "RX Bytes %d\n", isp
[0].stats
.rxBytes
);
1359 off
+= sprintf (page
+ off
, "TX Bytes %d\n", isp
[0].stats
.txBytes
);
1361 local_irq_restore(flags
);
1367 * Due to the fact that a port can be dynamically switched between slave
1368 * and master mode using an IOCTL the hardware is not initialized here,
1369 * but in ifx_ssc_hwinit() as a result of an IOCTL.
1374 struct ifx_ssc_port
*info
;
1376 unsigned long flags
;
1379 // ### TO DO: dynamic port count evaluation due to pin multiplexing
1382 nbytes
= PORT_CNT
* sizeof (struct ifx_ssc_port
);
1383 isp
= (struct ifx_ssc_port
*) kmalloc (nbytes
, GFP_KERNEL
);
1385 printk ("%s: no memory for isp\n", __FUNCTION__
);
1388 memset (isp
, 0, nbytes
);
1390 /* register the device */
1395 if ((i
= register_chrdev (maj
, "ssc", &ifx_ssc_fops
)) < 0) {
1396 printk ("Unable to register major %d for the Infineon SSC\n",
1404 register_chrdev (maj
, "ssc",
1405 &ifx_ssc_fops
)) < 0) {
1406 printk ("Unable to register major %d for the Infineon SSC\n", maj
);
1413 //printk("registered major %d for Infineon SSC\n", maj);
1415 /* set default values in ifx_ssc_port */
1416 for (i
= 0; i
< PORT_CNT
; i
++) {
1419 /* default values for the HwOpts */
1420 info
->opts
.AbortErrDetect
= IFX_SSC_DEF_ABRT_ERR_DETECT
;
1421 info
->opts
.rxOvErrDetect
= IFX_SSC_DEF_RO_ERR_DETECT
;
1422 info
->opts
.rxUndErrDetect
= IFX_SSC_DEF_RU_ERR_DETECT
;
1423 info
->opts
.txOvErrDetect
= IFX_SSC_DEF_TO_ERR_DETECT
;
1424 info
->opts
.txUndErrDetect
= IFX_SSC_DEF_TU_ERR_DETECT
;
1425 info
->opts
.loopBack
= IFX_SSC_DEF_LOOP_BACK
;
1426 info
->opts
.echoMode
= IFX_SSC_DEF_ECHO_MODE
;
1427 info
->opts
.idleValue
= IFX_SSC_DEF_IDLE_DATA
;
1428 info
->opts
.clockPolarity
= IFX_SSC_DEF_CLOCK_POLARITY
;
1429 info
->opts
.clockPhase
= IFX_SSC_DEF_CLOCK_PHASE
;
1430 info
->opts
.headingControl
= IFX_SSC_DEF_HEADING_CONTROL
;
1431 info
->opts
.dataWidth
= IFX_SSC_DEF_DATA_WIDTH
;
1432 info
->opts
.modeRxTx
= IFX_SSC_DEF_MODE_RXTX
;
1433 info
->opts
.gpoCs
= IFX_SSC_DEF_GPO_CS
;
1434 info
->opts
.gpoInv
= IFX_SSC_DEF_GPO_INV
;
1435 info
->opts
.masterSelect
= IFX_SSC_DEF_MASTERSLAVE
;
1436 info
->baud
= IFX_SSC_DEF_BAUDRATE
;
1439 /* values specific to SSC1 */
1441 info
->mapbase
= DANUBE_SSC1_BASE_ADDR
;
1442 // ### TO DO: power management
1444 // setting interrupt vectors
1445 info
->txirq
= DANUBE_SSC_TIR
;
1446 info
->rxirq
= DANUBE_SSC_RIR
;
1447 info
->errirq
= DANUBE_SSC_EIR
;
1449 info->frmirq = IFX_SSC_FIR;
1454 WRITE_PERIPHERAL_REGISTER (IFX_SSC_DEF_RMC
<<
1455 IFX_CLC_RUN_DIVIDER_OFFSET
,
1456 info
->mapbase
+ IFX_SSC_CLC
);
1458 // ### TO DO: multiple instances
1460 init_waitqueue_head (&info
->rwait
);
1461 //init_waitqueue_head(&info->pwait);
1463 local_irq_save (flags
);
1465 // init serial framing register
1466 WRITE_PERIPHERAL_REGISTER (IFX_SSC_DEF_SFCON
,
1467 info
->mapbase
+ IFX_SSC_SFCON
);
1469 /* try to get the interrupts */
1470 // ### TO DO: interrupt handling with multiple instances
1472 request_irq(info
->txirq
, ifx_ssc_tx_int
, SA_INTERRUPT
, "ifx_ssc_tx", info
);
1474 printk ("%s: unable to get irq %d\n", __FUNCTION__
,
1476 local_irq_restore (flags
);
1480 request_irq(info
->rxirq
, ifx_ssc_rx_int
, SA_INTERRUPT
, "ifx_ssc_rx", info
);
1482 printk ("%s: unable to get irq %d\n", __FUNCTION__
,
1484 local_irq_restore (flags
);
1488 request_irq(info
->errirq
, ifx_ssc_err_int
, SA_INTERRUPT
,"ifx_ssc_err", info
);
1490 printk ("%s: unable to get irq %d\n", __FUNCTION__
,
1492 local_irq_restore (flags
);
1495 WRITE_PERIPHERAL_REGISTER (IFX_SSC_DEF_IRNEN
,
1496 info
->mapbase
+ IFX_SSC_IRN_EN
);
1497 enable_irq(info
->txirq
);
1498 enable_irq(info
->rxirq
);
1499 enable_irq(info
->errirq
);
1501 local_irq_restore (flags
);
1504 /* init the SSCs with default values */
1505 for (i
= 0; i
< PORT_CNT
; i
++) {
1507 if (ifx_ssc_hwinit (info
) < 0) {
1508 printk ("%s: hardware init failed for port %d\n",
1514 /* register /proc read handler */
1515 // ### TO DO: multiple instances
1516 /* for SSC1, which is always present */
1517 create_proc_read_entry ("driver/ssc1", 0, NULL
, ifx_ssc1_read_proc
,
1522 // ### TO DO: multiple instances
1523 free_irq(isp
[0].txirq
, &isp
[0]);
1524 free_irq(isp
[0].rxirq
, &isp
[0]);
1525 free_irq(isp
[0].errirq
, &isp
[0]);
1527 /* free up any allocated memory in the error case */
1530 } /* ifx_ssc_init */
1533 ifx_ssc_cleanup_module (void)
1537 /* free up any allocated memory */
1538 for (i
= 0; i
< PORT_CNT
; i
++) {
1539 /* disable the SSC */
1540 WRITE_PERIPHERAL_REGISTER (IFX_SSC_WHBSTATE_CLR_ENABLE
,
1541 isp
[i
].mapbase
+ IFX_SSC_WHBSTATE
);
1542 /* free the interrupts */
1543 free_irq(isp
[i
].txirq
, &isp
[i
]);
1544 free_irq(isp
[i
].rxirq
, &isp
[i
]);
1545 free_irq(isp
[i
].errirq
, &isp
[i
]);
1548 /* delete /proc read handler */
1549 remove_proc_entry ("driver/ssc1", NULL
);
1550 remove_proc_entry ("driver/ssc2", NULL
);
1553 module_exit (ifx_ssc_cleanup_module
);
1555 /* Module entry-points */
1556 module_init (ifx_ssc_init
);
1560 ifx_ssc_set_maj (char *str
)
1562 maj
= simple_strtol (str
, NULL
, 0);
1566 __setup ("ssc_maj=", ifx_ssc_set_maj
);
1567 #endif /* !MODULE */
1569 #define DANUBE_SSC_EMSG(fmt,arg...) printk("%s: "fmt,__FUNCTION__, ##arg)
1570 /* Brief: chip select enable
1573 ifx_ssc_cs_low (u32 pin
)
1577 ifx_ssc_ioctl ((struct inode
*) 0, NULL
, IFX_SSC_GPO_OUT_CLR
,
1578 (unsigned long) &pin
))) {
1579 DANUBE_SSC_EMSG ("clear CS %d fails\n", pin
);
1585 EXPORT_SYMBOL (ifx_ssc_cs_low
);
1586 /* Brief: chip select disable
1589 ifx_ssc_cs_high (u32 pin
)
1593 ifx_ssc_ioctl ((struct inode
*) 0, NULL
, IFX_SSC_GPO_OUT_SET
,
1594 (unsigned long) &pin
))) {
1595 DANUBE_SSC_EMSG ("set CS %d fails\n", pin
);
1601 EXPORT_SYMBOL (ifx_ssc_cs_high
);
1602 /* Brief: one SSC session
1608 * session_mode: IFX_SSC_MODE_RXTX or IFX_SSC_MODE_TX
1609 * Return: >=0 number of bytes received (if rx_buf != 0) or transmitted
1612 * 0. copy data to internal buffer
1614 * 2a. If SSC_SESSION_MODE_TXONLY, read tx_len data
1615 * 2b. If not Read back (tx_len + rx_len) data
1616 * 3. copy internal buffer to rx buf if necessary
1619 ssc_session (char *tx_buf
, u32 tx_len
, char *rx_buf
, u32 rx_len
)
1623 char *ssc_tx_buf
= NULL
;
1624 char *ssc_rx_buf
= NULL
;
1626 // volatile char ssc_tx_buf[128]={0};
1627 // volatile char ssc_rx_buf[128]={0};
1632 if (tx_buf
== NULL
&& tx_len
== 0 && rx_buf
== NULL
&& rx_len
== 0) {
1633 DANUBE_SSC_EMSG ("invalid parameters\n");
1635 goto ssc_session_exit
;
1637 else if (tx_buf
== NULL
|| tx_len
== 0) {
1638 if (rx_buf
!= NULL
&& rx_len
!= 0) {
1639 mode
= IFX_SSC_MODE_RX
;
1642 DANUBE_SSC_EMSG ("invalid parameters\n");
1644 goto ssc_session_exit
;
1647 else if (rx_buf
== NULL
|| rx_len
== 0) {
1648 if (tx_buf
!= NULL
&& tx_len
!= 0) {
1649 mode
= IFX_SSC_MODE_TX
;
1652 DANUBE_SSC_EMSG ("invalid parameters\n");
1654 goto ssc_session_exit
;
1658 mode
= IFX_SSC_MODE_RXTX
;
1661 if (mode
== IFX_SSC_MODE_RXTX
) {
1662 eff_size
= tx_len
+ rx_len
;
1664 else if (mode
== IFX_SSC_MODE_RX
) {
1671 //4 bytes alignment, required by driver
1672 /* change by TaiCheng */
1676 (char *) kmalloc (sizeof (char) *
1677 ((eff_size
+ 3) & (~3)),
1680 (char *) kmalloc (sizeof (char) *
1681 ((eff_size
+ 3) & (~3)),
1686 (char *) kmalloc (sizeof (char) *
1687 ((eff_size
+ 3) & (~3)),
1690 (char *) kmalloc (sizeof (char) *
1691 ((eff_size
+ 3) & (~3)),
1694 if (ssc_tx_buf
== NULL
|| ssc_rx_buf
== NULL
) {
1695 DANUBE_SSC_EMSG ("no memory for size of %d\n", eff_size
);
1697 goto ssc_session_exit
;
1699 memset ((void *) ssc_tx_buf
, 0, eff_size
);
1700 memset ((void *) ssc_rx_buf
, 0, eff_size
);
1703 memcpy (ssc_tx_buf
, tx_buf
, tx_len
);
1706 ret
= ifx_ssc_kwrite (0, ssc_tx_buf
, eff_size
);
1709 ssc_tx_buf
= NULL
; //should be freed by ifx_ssc_kwrite
1712 if (ret
!= eff_size
) {
1713 DANUBE_SSC_EMSG ("ifx_ssc_write return %d\n", ret
);
1714 goto ssc_session_exit
;
1716 ret
= ifx_ssc_kread (0, ssc_rx_buf
, eff_size
);
1717 if (ret
!= eff_size
) {
1718 DANUBE_SSC_EMSG ("ifx_ssc_read return %d\n", ret
);
1719 goto ssc_session_exit
;
1722 memcpy (rx_buf
, ssc_rx_buf
+ tx_len
, rx_len
);
1724 if (mode
== IFX_SSC_MODE_TX
) {
1732 if (ssc_tx_buf
!= NULL
)
1734 if (ssc_rx_buf
!= NULL
)
1738 printk ("ssc session fails\n");
1743 /* Brief: TX-RX session
1749 * Return: >=0 number of bytes received
1756 ifx_ssc_txrx (char *tx_buf
, u32 tx_len
, char *rx_buf
, u32 rx_len
)
1758 return ssc_session (tx_buf
, tx_len
, rx_buf
, rx_len
);
1761 EXPORT_SYMBOL (ifx_ssc_txrx
);
1762 /* Brief: TX only session
1766 * Return: >=0 number of bytes transmitted
1770 ifx_ssc_tx (char *tx_buf
, u32 tx_len
)
1772 return ssc_session (tx_buf
, tx_len
, NULL
, 0);
1775 EXPORT_SYMBOL (ifx_ssc_tx
);
1776 /* Brief: RX only session
1780 * Return: >=0 number of bytes received
1784 ifx_ssc_rx (char *rx_buf
, u32 rx_len
)
1786 return ssc_session (NULL
, 0, rx_buf
, rx_len
);
1789 EXPORT_SYMBOL (ifx_ssc_rx
);
1791 MODULE_LICENSE("GPL");
1792 MODULE_AUTHOR("John Crispin <blogic@openwrt.org>");
1793 MODULE_DESCRIPTION("danube ssc driver");