enable start-stop-daemon by default, i want to use this to clean up a few init script...
[15.05/openwrt.git] / target / linux / amazon-2.6 / files / drivers / char / ifx_ssc.c
1 /**************************************************
2  *
3  * drivers/ifx/serial/ifx_ssc.c
4  *
5  * Driver for IFX_SSC serial ports
6  *
7  * Copyright (C) 2004 Infineon Technologies AG
8  * Author Michael Schoenenborn (IFX COM TI BT)
9  *
10  */
11 #define IFX_SSC_DRV_VERSION "0.2.1"
12 /*
13  **************************************************
14  *
15  * This driver was originally based on the INCA-IP driver, but due to 
16  * fundamental conceptual drawbacks there has been changed a lot.
17  *
18  * Based on INCA-IP driver Copyright (c) 2003 Gary Jennejohn <gj@denx.de>
19  * Based on the VxWorks drivers Copyright (c) 2002, Infineon Technologies.
20  *
21  * This program is free software; you can redistribute it and/or modify
22  * it under the terms of the GNU General Public License as published by
23  * the Free Software Foundation; either version 2 of the License, or
24  * (at your option) any later version.
25  *
26  * This program is distributed in the hope that it will be useful,
27  * but WITHOUT ANY WARRANTY; without even the implied warranty of
28  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
29  * GNU General Public License for more details.
30  *
31  * You should have received a copy of the GNU General Public License
32  * along with this program; if not, write to the Free Software
33  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
34  *
35  */
36
37 // ### TO DO: general issues:
38 //            - power management
39 //            - interrupt handling (direct/indirect)
40 //            - pin/mux-handling (just overall concept due to project dependency)
41 //            - multiple instances capability
42 //            - slave functionality
43
44 /*
45  * Include section 
46  */
47 #ifndef EXPORT_SYMTAB
48 #define EXPORT_SYMTAB
49 #endif
50
51 #include <linux/config.h>
52 #include <linux/module.h>
53 #include <linux/errno.h>
54 #include <linux/signal.h>
55 #include <linux/sched.h>
56 #include <linux/timer.h>
57 #include <linux/interrupt.h>
58 #include <linux/major.h>
59 #include <linux/string.h>
60 #include <linux/fs.h>
61 #include <linux/proc_fs.h>
62 #include <linux/fcntl.h>
63 #include <linux/ptrace.h>
64 #include <linux/mm.h>
65 #include <linux/ioport.h>
66 #include <linux/init.h>
67 #include <linux/delay.h>
68 #include <linux/spinlock.h>
69 #include <linux/slab.h>
70 //#include <linux/poll.h>
71
72 #include <asm/system.h>
73 #include <asm/io.h>
74 #include <asm/irq.h>
75 #include <asm/uaccess.h>
76 #include <asm/bitops.h>
77
78 #include <linux/types.h>
79 #include <linux/kernel.h>
80 #include <linux/version.h>
81
82 #include <asm/amazon/amazon.h>
83 #include <asm/amazon/irq.h>
84 #include <asm/amazon/ifx_ssc_defines.h>
85 #include <asm/amazon/ifx_ssc.h>
86
87 #ifdef SSC_FRAME_INT_ENABLE
88 #undef SSC_FRAME_INT_ENABLE
89 #endif
90
91 #define not_yet
92
93 #define SPI_VINETIC
94
95 /*
96  * Deal with CONFIG_MODVERSIONS
97  */
98 #if CONFIG_MODVERSIONS==1
99 # include <linux/modversions.h>
100 #endif
101
102 MODULE_LICENSE("GPL");
103 MODULE_AUTHOR("Michael Schoenenborn");
104 MODULE_DESCRIPTION("IFX SSC driver");
105 MODULE_SUPPORTED_DEVICE("ifx_ssc");
106 MODULE_PARM(maj, "i");
107 MODULE_PARM_DESC(maj, "Major device number");
108
109 /* allow the user to set the major device number */
110 static int maj = 0;
111
112
113 /*
114  * This is the per-channel data structure containing pointers, flags
115  * and variables for the port. This driver supports a maximum of PORT_CNT.
116  * isp is allocated in ifx_ssc_init() based on the chip version.
117  */
118 static struct ifx_ssc_port *isp;
119
120 /* prototypes for fops */
121 static ssize_t ifx_ssc_read(struct file *, char *, size_t, loff_t *);
122 static ssize_t ifx_ssc_write(struct file *, const char *, size_t, loff_t *);
123 //static unsigned int ifx_ssc_poll(struct file *, struct poll_table_struct *);
124 int ifx_ssc_ioctl(struct inode *, struct file *, unsigned int, unsigned long);
125 int ifx_ssc_open(struct inode *, struct file *);
126 int ifx_ssc_close(struct inode *, struct file *);
127
128 /* other forward declarations */
129 static unsigned int ifx_ssc_get_kernel_clk(struct ifx_ssc_port *info);
130 static void ifx_ssc_rx_int(int, void *, struct pt_regs *);
131 static void ifx_ssc_tx_int(int, void *, struct pt_regs *);
132 static void ifx_ssc_err_int(int, void *, struct pt_regs *);
133 #ifdef SSC_FRAME_INT_ENABLE
134 static void ifx_ssc_frm_int(int, void *, struct pt_regs *);
135 #endif
136 static void tx_int(struct ifx_ssc_port *);
137 static int ifx_ssc1_read_proc(char *, char **, off_t, int, int *, void *);
138 static void ifx_gpio_init(void);
139 /************************************************************************
140  *  Function declaration
141  ************************************************************************/
142 //interrupt.c
143 extern unsigned int amazon_get_fpi_hz(void);
144 extern void disable_amazon_irq(unsigned int irq_nr);
145 extern void enable_amazon_irq(unsigned int irq_nr);
146 extern void mask_and_ack_amazon_irq(unsigned int irq_nr);
147
148
149 /*****************************************************************/
150 typedef struct {
151         int (*request)(unsigned int irq, 
152                        void (*handler)(int, void *, struct pt_regs *), 
153                        unsigned long irqflags,
154                        const char * devname, 
155                        void *dev_id);
156         void (*free)(unsigned int irq, void *dev_id);
157         void (*enable)(unsigned int irq);
158         void (*disable)(unsigned int irq);
159         void (*clear)(unsigned int irq);
160 } ifx_int_wrapper_t;
161
162 static ifx_int_wrapper_t ifx_int_wrapper = {
163         request:        request_irq,    // IM action: enable int
164         free:           free_irq,       // IM action: disable int
165         enable:         enable_amazon_irq,
166         disable:        disable_amazon_irq,
167         clear:          mask_and_ack_amazon_irq,
168         //end:          
169 };
170
171 /* Fops-struct */
172 static struct file_operations ifx_ssc_fops = {
173         owner:          THIS_MODULE,
174         read:           ifx_ssc_read,    /* read */
175         write:          ifx_ssc_write,   /* write */
176 //        poll:         ifx_ssc_poll,    /* poll */
177         ioctl:          ifx_ssc_ioctl,   /* ioctl */
178         open:           ifx_ssc_open,    /* open */
179         release:        ifx_ssc_close,   /* release */
180 };
181
182
183 static inline unsigned int ifx_ssc_get_kernel_clk(struct ifx_ssc_port *info)
184 { // ATTENTION: This function assumes that the CLC register is set with the 
185   // appropriate value for RMC.
186         unsigned int rmc;
187
188         rmc = (READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_CLC) & 
189                IFX_CLC_RUN_DIVIDER_MASK) >> IFX_CLC_RUN_DIVIDER_OFFSET;
190         if (rmc == 0){
191                 printk("ifx_ssc_get_kernel_clk rmc==0 \n");
192                 return (0);
193         }
194         return (amazon_get_fpi_hz() / rmc);
195 }
196
197 #ifndef not_yet
198 #ifdef IFX_SSC_INT_USE_BH
199 /*
200  * This routine is used by the interrupt handler to schedule
201  * processing in the software interrupt portion of the driver
202  * (also known as the "bottom half").  This can be called any
203  * number of times for any channel without harm.
204  */
205 static inline void
206 ifx_ssc_sched_event(struct ifx_ssc_port *info, int event)
207 {
208     info->event |= 1 << event; /* remember what kind of event and who */
209     queue_task(&info->tqueue, &tq_cyclades); /* it belongs to */
210     mark_bh(CYCLADES_BH);                       /* then trigger event */
211 } /* ifx_ssc_sched_event */
212
213
214 /*
215  * This routine is used to handle the "bottom half" processing for the
216  * serial driver, known also the "software interrupt" processing.
217  * This processing is done at the kernel interrupt level, after the
218  * cy#/_interrupt() has returned, BUT WITH INTERRUPTS TURNED ON.  This
219  * is where time-consuming activities which can not be done in the
220  * interrupt driver proper are done; the interrupt driver schedules
221  * them using ifx_ssc_sched_event(), and they get done here.
222  *
223  * This is done through one level of indirection--the task queue.
224  * When a hardware interrupt service routine wants service by the
225  * driver's bottom half, it enqueues the appropriate tq_struct (one
226  * per port) to the tq_cyclades work queue and sets a request flag
227  * via mark_bh for processing that queue.  When the time is right,
228  * do_ifx_ssc_bh is called (because of the mark_bh) and it requests
229  * that the work queue be processed.
230  *
231  * Although this may seem unwieldy, it gives the system a way to
232  * pass an argument (in this case the pointer to the ifx_ssc_port
233  * structure) to the bottom half of the driver.  Previous kernels
234  * had to poll every port to see if that port needed servicing.
235  */
236 static void
237 do_ifx_ssc_bh(void)
238 {
239     run_task_queue(&tq_cyclades);
240 } /* do_ifx_ssc_bh */
241
242 static void
243 do_softint(void *private_)
244 {
245   struct ifx_ssc_port *info = (struct ifx_ssc_port *) private_;
246
247     if (test_and_clear_bit(Cy_EVENT_HANGUP, &info->event)) {
248         wake_up_interruptible(&info->open_wait);
249         info->flags &= ~(ASYNC_NORMAL_ACTIVE|
250                              ASYNC_CALLOUT_ACTIVE);
251     }
252     if (test_and_clear_bit(Cy_EVENT_OPEN_WAKEUP, &info->event)) {
253         wake_up_interruptible(&info->open_wait);
254     }
255     if (test_and_clear_bit(Cy_EVENT_DELTA_WAKEUP, &info->event)) {
256         wake_up_interruptible(&info->delta_msr_wait);
257     }
258     if (test_and_clear_bit(Cy_EVENT_WRITE_WAKEUP, &info->event)) {
259         wake_up_interruptible(&tty->write_wait);
260     }
261 #ifdef Z_WAKE
262     if (test_and_clear_bit(Cy_EVENT_SHUTDOWN_WAKEUP, &info->event)) {
263         wake_up_interruptible(&info->shutdown_wait);
264     }
265 #endif
266 } /* do_softint */
267 #endif /* IFX_SSC_INT_USE_BH */
268 #endif // not_yet
269
270 inline static void
271 rx_int(struct ifx_ssc_port *info)
272 {
273         int             fifo_fill_lev, bytes_in_buf, i;
274         unsigned long   tmp_val;
275         unsigned long   *tmp_ptr;
276         unsigned int    rx_valid_cnt;
277         /* number of words waiting in the RX FIFO */
278         fifo_fill_lev = (READ_PERIPHERAL_REGISTER(info->mapbase + 
279                                                   IFX_SSC_FSTAT) & 
280                          IFX_SSC_FSTAT_RECEIVED_WORDS_MASK) >>
281                          IFX_SSC_FSTAT_RECEIVED_WORDS_OFFSET;
282         // Note: There are always 32 bits in a fifo-entry except for the last 
283         // word of a contigous transfer block and except for not in rx-only 
284         // mode and CON.ENBV set. But for this case it should be a convention 
285         // in software which helps:
286         // In tx or rx/tx mode all transfers from the buffer to the FIFO are 
287         // 32-bit wide, except for the last three bytes, which could be a 
288         // combination of 16- and 8-bit access.
289         // => The whole block is received as 32-bit words as a contigous stream, 
290         // even if there was a gap in tx which has the fifo run out of data! 
291         // Just the last fifo entry *may* be partially filled (0, 1, 2 or 3 bytes)!
292
293         /* free space in the RX buffer */
294         bytes_in_buf = info->rxbuf_end - info->rxbuf_ptr;
295         // transfer with 32 bits per entry
296         while ((bytes_in_buf >= 4) && (fifo_fill_lev > 0)) {
297                 tmp_ptr = (unsigned long *)info->rxbuf_ptr;
298                 *tmp_ptr = READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_RB);
299                 info->rxbuf_ptr += 4;
300                 info->stats.rxBytes += 4;
301                 fifo_fill_lev --;
302                 bytes_in_buf -= 4;
303         } // while ((bytes_in_buf >= 4) && (fifo_fill_lev > 0))
304         // now do the rest as mentioned in STATE.RXBV
305         while ((bytes_in_buf > 0) && (fifo_fill_lev > 0)) {
306                 rx_valid_cnt = (READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_STATE) & 
307                                 IFX_SSC_STATE_RX_BYTE_VALID_MASK) >> 
308                         IFX_SSC_STATE_RX_BYTE_VALID_OFFSET;
309                 if (rx_valid_cnt == 0) break;
310                 if (rx_valid_cnt > bytes_in_buf) {
311                         // ### TO DO: warning message: not block aligned data, other data 
312                         //                             in this entry will be lost
313                         rx_valid_cnt = bytes_in_buf;
314                 }
315                 tmp_val = READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_RB);
316                 
317                 for (i=0; i<rx_valid_cnt; i++) {                
318                         *info->rxbuf_ptr = (tmp_val >> ( 8 * (rx_valid_cnt - i-1))) & 0xff;
319 /*                      
320                         *info->rxbuf_ptr = tmp_val & 0xff;
321                         tmp_val >>= 8;
322 */                      
323                         bytes_in_buf--;
324
325                         
326                         info->rxbuf_ptr++;
327                 }
328                 info->stats.rxBytes += rx_valid_cnt;
329         }  // while ((bytes_in_buf > 0) && (fifo_fill_lev > 0))
330
331         // check if transfer is complete
332         if (info->rxbuf_ptr >= info->rxbuf_end) {
333                 ifx_int_wrapper.disable(info->rxirq);
334                 /* wakeup any processes waiting in read() */
335                 wake_up_interruptible(&info->rwait);
336                 /* and in poll() */
337                 //wake_up_interruptible(&info->pwait);
338         } else if ((info->opts.modeRxTx == IFX_SSC_MODE_RX) && 
339                    (READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_RXCNT) == 0)) {
340                 // if buffer not filled completely and rx request done initiate new transfer
341 /*
342                 if  (info->rxbuf_end - info->rxbuf_ptr < 65536)
343 */
344                 if  (info->rxbuf_end - info->rxbuf_ptr < IFX_SSC_RXREQ_BLOCK_SIZE)
345                         WRITE_PERIPHERAL_REGISTER((info->rxbuf_end - info->rxbuf_ptr) << 
346                                                   IFX_SSC_RXREQ_RXCOUNT_OFFSET, 
347                                                   info->mapbase + IFX_SSC_RXREQ);
348                 else 
349                         WRITE_PERIPHERAL_REGISTER(IFX_SSC_RXREQ_BLOCK_SIZE << IFX_SSC_RXREQ_RXCOUNT_OFFSET, 
350                                                   info->mapbase + IFX_SSC_RXREQ);
351         }
352 } // rx_int
353
354 inline static void
355 tx_int(struct ifx_ssc_port *info)
356 {
357         
358         int fifo_space, fill, i;
359         fifo_space = ((READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_ID) & 
360                        IFX_SSC_PERID_TXFS_MASK) >> IFX_SSC_PERID_TXFS_OFFSET) - 
361                 ((READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_FSTAT) & 
362                   IFX_SSC_FSTAT_TRANSMIT_WORDS_MASK) >> 
363                  IFX_SSC_FSTAT_TRANSMIT_WORDS_OFFSET);
364
365         if (fifo_space == 0)
366                 return;
367
368         fill = info->txbuf_end - info->txbuf_ptr;
369
370         if (fill > fifo_space * 4)
371                 fill = fifo_space * 4;
372
373         for (i = 0; i < fill / 4; i++) {
374                 // at first 32 bit access
375                 WRITE_PERIPHERAL_REGISTER(*(UINT32 *)info->txbuf_ptr, info->mapbase + IFX_SSC_TB);
376                 info->txbuf_ptr += 4;
377         }
378
379         fifo_space -= fill / 4;
380         info->stats.txBytes += fill & ~0x3;
381         fill &= 0x3;
382         if ((fifo_space > 0) & (fill > 1)) {
383                 // trailing 16 bit access
384                 WRITE_PERIPHERAL_REGISTER_16(*(UINT16 *)info->txbuf_ptr, info->mapbase + IFX_SSC_TB);
385                 info->txbuf_ptr += 2;
386                 info->stats.txBytes += 2;
387                 fifo_space --;
388 /* added by bingtao */
389                 fill -=2;
390         }
391         if ((fifo_space > 0) & (fill > 0)) {
392                 // trailing 8 bit access
393                 WRITE_PERIPHERAL_REGISTER_8(*(UINT8 *)info->txbuf_ptr, info->mapbase + IFX_SSC_TB);
394                 info->txbuf_ptr ++;
395                 info->stats.txBytes ++;
396 /*
397                 fifo_space --;
398 */
399         }
400
401         // check if transmission complete
402         if (info->txbuf_ptr >= info->txbuf_end) {
403                 ifx_int_wrapper.disable(info->txirq);
404                 kfree(info->txbuf);
405                 info->txbuf = NULL;
406                 /* wake up any process waiting in poll() */
407                 //wake_up_interruptible(&info->pwait);
408         }       
409
410 } // tx_int
411
412 static void
413 ifx_ssc_rx_int(int irq, void *dev_id, struct pt_regs *regs)
414 {
415         struct ifx_ssc_port *info = (struct ifx_ssc_port *)dev_id;
416         //WRITE_PERIPHERAL_REGISTER(IFX_SSC_R_BIT, info->mapbase + IFX_SSC_IRN_CR);
417         rx_int(info);
418 }
419
420 static void
421 ifx_ssc_tx_int(int irq, void *dev_id, struct pt_regs *regs)
422 {
423         struct ifx_ssc_port *info = (struct ifx_ssc_port *)dev_id;
424         //WRITE_PERIPHERAL_REGISTER(IFX_SSC_T_BIT, info->mapbase + IFX_SSC_IRN_CR);
425         tx_int(info);
426 }
427
428 static void
429 ifx_ssc_err_int(int irq, void *dev_id, struct pt_regs *regs)
430 {
431         struct ifx_ssc_port *info = (struct ifx_ssc_port *)dev_id;
432         unsigned int state;
433         unsigned int write_back = 0;
434         unsigned long flags;
435
436
437         local_irq_save(flags);
438         state = READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_STATE); 
439
440         if ((state & IFX_SSC_STATE_RX_UFL) != 0) {
441                 info->stats.rxUnErr++;
442                 write_back |= IFX_SSC_WHBSTATE_CLR_RX_UFL_ERROR;
443         }
444         if ((state & IFX_SSC_STATE_RX_OFL) != 0) {
445                 info->stats.rxOvErr++;
446                 write_back |= IFX_SSC_WHBSTATE_CLR_RX_OFL_ERROR;
447         }
448         if ((state & IFX_SSC_STATE_TX_OFL) != 0) {
449                 info->stats.txOvErr++;
450                 write_back |= IFX_SSC_WHBSTATE_CLR_TX_OFL_ERROR;
451         }
452         if ((state & IFX_SSC_STATE_TX_UFL) != 0) {
453                 info->stats.txUnErr++;
454                 write_back |= IFX_SSC_WHBSTATE_CLR_TX_UFL_ERROR;
455         }
456 //      if ((state & IFX_SSC_STATE_ABORT_ERR) != 0) {
457 //              info->stats.abortErr++;
458 //              write_back |= IFX_SSC_WHBSTATE_CLR_ABORT_ERROR;
459 //      }
460         if ((state & IFX_SSC_STATE_MODE_ERR) != 0) {
461                 info->stats.modeErr++;
462                 write_back |= IFX_SSC_WHBSTATE_CLR_MODE_ERROR;
463         }
464
465         if (write_back)
466                 WRITE_PERIPHERAL_REGISTER(write_back, 
467                                           info->mapbase + IFX_SSC_WHBSTATE);
468
469         local_irq_restore(flags);
470 }
471
472 #ifdef SSC_FRAME_INT_ENABLE
473 static void
474 ifx_ssc_frm_int(int irq, void *dev_id, struct pt_regs *regs)
475 {
476         // ### TO DO: wake up framing wait-queue in conjunction with batch execution
477 }
478 #endif
479
480 static void
481 ifx_ssc_abort(struct ifx_ssc_port *info)
482 {
483         unsigned long flags;
484         bool enabled;
485
486         local_irq_save(flags);
487
488         // disable all int's
489         ifx_int_wrapper.disable(info->rxirq);
490         ifx_int_wrapper.disable(info->txirq);
491         ifx_int_wrapper.disable(info->errirq);
492 /*
493         ifx_int_wrapper.disable(info->frmirq);
494 */
495         local_irq_restore(flags);
496
497         // disable SSC (also aborts a receive request!)
498         // ### TO DO: Perhaps it's better to abort after the receiption of a 
499         // complete word. The disable cuts the transmission immediatly and 
500         // releases the chip selects. This could result in unpredictable 
501         // behavior of connected external devices!
502         enabled = (READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_STATE) 
503                    & IFX_SSC_STATE_IS_ENABLED) != 0;
504         WRITE_PERIPHERAL_REGISTER(IFX_SSC_WHBSTATE_CLR_ENABLE, 
505                                   info->mapbase + IFX_SSC_WHBSTATE);
506
507
508         // flush fifos
509         WRITE_PERIPHERAL_REGISTER(IFX_SSC_XFCON_FIFO_FLUSH, 
510                                   info->mapbase + IFX_SSC_TXFCON);
511         WRITE_PERIPHERAL_REGISTER(IFX_SSC_XFCON_FIFO_FLUSH, 
512                                   info->mapbase + IFX_SSC_RXFCON);
513
514         // free txbuf
515         if (info->txbuf != NULL) {
516                 kfree(info->txbuf);
517                 info->txbuf = NULL;
518         }
519
520         // wakeup read process
521         if (info->rxbuf != NULL)
522                 wake_up_interruptible(&info->rwait);
523
524         // clear pending int's 
525         ifx_int_wrapper.clear(info->rxirq);
526         ifx_int_wrapper.clear(info->txirq);
527         ifx_int_wrapper.clear(info->errirq);
528 /*
529         ifx_int_wrapper.clear(info->frmirq);
530 */
531
532         // clear error flags
533         WRITE_PERIPHERAL_REGISTER(IFX_SSC_WHBSTATE_CLR_ALL_ERROR,
534                                   info->mapbase + IFX_SSC_WHBSTATE);
535
536         //printk("IFX SSC%d: Transmission aborted\n", info->port_nr);
537         // enable SSC
538         if (enabled)
539                 WRITE_PERIPHERAL_REGISTER(IFX_SSC_WHBSTATE_SET_ENABLE, 
540                                           info->mapbase + IFX_SSC_WHBSTATE);
541
542 } // ifx_ssc_abort
543
544
545 /*
546  * This routine is called whenever a port is opened.  It enforces
547  * exclusive opening of a port and enables interrupts, etc.
548  */
549 int
550 ifx_ssc_open(struct inode *inode, struct file * filp)
551 {
552         struct ifx_ssc_port  *info;
553         int line;
554         int from_kernel = 0;
555
556         if ((inode == (struct inode *)0) || (inode == (struct inode *)1)) {
557                 from_kernel = 1;
558                 line = (int)inode;
559         }
560         else {
561                 line = MINOR(filp->f_dentry->d_inode->i_rdev);
562                 filp->f_op = &ifx_ssc_fops;
563         }
564
565         /* don't open more minor devices than we can support */
566         if (line < 0 || line >= PORT_CNT)
567                 return -ENXIO;
568
569         info = &isp[line];
570
571         /* exclusive open */
572         if (info->port_is_open != 0)
573                 return -EBUSY;
574         info->port_is_open++;
575
576         ifx_int_wrapper.disable(info->rxirq);
577         ifx_int_wrapper.disable(info->txirq);
578         ifx_int_wrapper.disable(info->errirq);
579 /*
580         ifx_int_wrapper.disable(info->frmirq);
581 */
582
583         /* Flush and enable TX/RX FIFO */
584         WRITE_PERIPHERAL_REGISTER((IFX_SSC_DEF_TXFIFO_FL << 
585                                    IFX_SSC_XFCON_ITL_OFFSET) | 
586                                   IFX_SSC_XFCON_FIFO_FLUSH   |
587                                   IFX_SSC_XFCON_FIFO_ENABLE, 
588                                   info->mapbase + IFX_SSC_TXFCON);
589         WRITE_PERIPHERAL_REGISTER((IFX_SSC_DEF_RXFIFO_FL << 
590                                    IFX_SSC_XFCON_ITL_OFFSET) |
591                                   IFX_SSC_XFCON_FIFO_FLUSH   | 
592                                   IFX_SSC_XFCON_FIFO_ENABLE, 
593                                   info->mapbase + IFX_SSC_RXFCON);
594
595
596         /* logically flush the software FIFOs */
597         info->rxbuf_ptr = 0;
598         info->txbuf_ptr = 0;
599
600         /* clear all error bits */
601         WRITE_PERIPHERAL_REGISTER(IFX_SSC_WHBSTATE_CLR_ALL_ERROR,
602                                   info->mapbase + IFX_SSC_WHBSTATE);
603
604         // clear pending interrupts
605         ifx_int_wrapper.clear(info->rxirq);
606         ifx_int_wrapper.clear(info->txirq);
607         ifx_int_wrapper.clear(info->errirq);
608 /*
609         ifx_int_wrapper.clear(info->frmirq);
610 */
611
612         // enable SSC
613         WRITE_PERIPHERAL_REGISTER(IFX_SSC_WHBSTATE_SET_ENABLE, 
614                                   info->mapbase + IFX_SSC_WHBSTATE);
615
616         MOD_INC_USE_COUNT;
617
618         return 0;
619 } /* ifx_ssc_open */
620 EXPORT_SYMBOL(ifx_ssc_open);
621
622 /*
623  * This routine is called when a particular device is closed.
624  */
625 int
626 ifx_ssc_close(struct inode *inode, struct file *filp)
627 {
628         struct ifx_ssc_port *info;
629         int idx;
630
631         if ((inode == (struct inode *)0) || (inode == (struct inode *)1))
632                 idx = (int)inode;
633         else
634                 idx = MINOR(filp->f_dentry->d_inode->i_rdev);
635
636         if (idx < 0 || idx >= PORT_CNT)
637                 return -ENXIO;
638
639         info = &isp[idx];
640         if (!info)
641                 return -ENXIO;
642
643         // disable SSC
644         WRITE_PERIPHERAL_REGISTER(IFX_SSC_WHBSTATE_CLR_ENABLE, 
645                                   info->mapbase + IFX_SSC_WHBSTATE);
646
647         // call abort function to disable int's, flush fifos...
648         ifx_ssc_abort(info);
649
650         info->port_is_open --;
651         MOD_DEC_USE_COUNT;
652
653         return 0;
654 } /* ifx_ssc_close */
655 EXPORT_SYMBOL(ifx_ssc_close);
656
657 /* added by bingtao */
658 /* helper routine to handle reads from the kernel or user-space */
659 /* info->rxbuf : never kfree and contains valid data */
660 /* should be points to NULL after copying data !!! */
661 static ssize_t
662 ifx_ssc_read_helper_poll(struct ifx_ssc_port *info, char *buf, size_t len,
663                     int from_kernel)
664 {
665         ssize_t         ret_val;
666         unsigned long   flags;
667
668         if (info->opts.modeRxTx == IFX_SSC_MODE_TX) 
669                 return -EFAULT;
670         local_irq_save(flags);
671         info->rxbuf_ptr = info->rxbuf;
672         info->rxbuf_end = info->rxbuf + len;
673         local_irq_restore(flags);
674 /* Vinetic driver always works in IFX_SSC_MODE_RXTX */ 
675 /* TXRX in poll mode */
676         while (info->rxbuf_ptr < info->rxbuf_end){
677 /* This is the key point, if you don't check this condition 
678    kfree (NULL) will happen 
679    because tx only need write into FIFO, it's much fast than rx
680    So when rx still waiting , tx already finish and release buf 
681 */      
682                 if (info->txbuf_ptr < info->txbuf_end) {
683                         tx_int(info);
684                 }
685                 
686                 rx_int(info);
687         };
688
689         ret_val = info->rxbuf_ptr - info->rxbuf; 
690         return (ret_val);
691 } // ifx_ssc_read_helper_poll
692
693 /* helper routine to handle reads from the kernel or user-space */
694 /* info->rx_buf : never kfree and contains valid data */
695 /* should be points to NULL after copying data !!! */
696 static ssize_t
697 ifx_ssc_read_helper(struct ifx_ssc_port *info, char *buf, size_t len,
698                     int from_kernel)
699 {
700         ssize_t         ret_val;
701         unsigned long   flags;
702         DECLARE_WAITQUEUE(wait, current);
703
704         if (info->opts.modeRxTx == IFX_SSC_MODE_TX) 
705                 return -EFAULT;
706         local_irq_save(flags);
707         info->rxbuf_ptr = info->rxbuf;
708         info->rxbuf_end = info->rxbuf + len;
709         if (info->opts.modeRxTx == IFX_SSC_MODE_RXTX) {
710                 if ((info->txbuf == NULL) ||
711                     (info->txbuf != info->txbuf_ptr) ||
712                     (info->txbuf_end != len + info->txbuf)) {
713                         local_irq_restore(flags);
714                         printk("IFX SSC - %s: write must be called before calling "
715                                "read in combined RX/TX!\n", __FUNCTION__);
716                         return -EFAULT;
717                 }
718                 local_irq_restore(flags);
719                 /* should enable tx, right?*/
720                 tx_int(info);
721                 if (info->txbuf_ptr < info->txbuf_end){
722                         ifx_int_wrapper.enable(info->txirq);
723                 }
724                 
725                 ifx_int_wrapper.enable(info->rxirq);
726         } else { // rx mode
727                 local_irq_restore(flags);
728                 if (READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_RXCNT) &
729                     IFX_SSC_RXCNT_TODO_MASK)
730                         return -EBUSY;
731                 ifx_int_wrapper.enable(info->rxirq);
732                 // rx request limited to ' bytes
733 /*
734                 if (len < 65536)
735 */
736                 if (len < IFX_SSC_RXREQ_BLOCK_SIZE)
737                         WRITE_PERIPHERAL_REGISTER(len << IFX_SSC_RXREQ_RXCOUNT_OFFSET, 
738                                                   info->mapbase + IFX_SSC_RXREQ);
739                 else 
740                         WRITE_PERIPHERAL_REGISTER(IFX_SSC_RXREQ_BLOCK_SIZE << IFX_SSC_RXREQ_RXCOUNT_OFFSET, 
741                                                   info->mapbase + IFX_SSC_RXREQ);
742         }
743
744         __add_wait_queue(&info->rwait, &wait);
745         set_current_state(TASK_INTERRUPTIBLE);
746         // wakeup done in rx_int
747  
748         do {
749                 local_irq_save(flags);
750                 if (info->rxbuf_ptr >= info->rxbuf_end)
751                         break;
752                 local_irq_restore(flags);
753
754 //                if (filp->f_flags & O_NONBLOCK)
755 //                {
756 //                        N = -EAGAIN;
757 //                        goto out;
758 //                }
759                 if (signal_pending(current)) {
760                         ret_val = -ERESTARTSYS;
761                         goto out;
762                 }
763                 schedule();
764         } while (1);
765
766         ret_val = info->rxbuf_ptr - info->rxbuf; // should be equal to len
767         local_irq_restore(flags);
768
769   out:
770         current->state = TASK_RUNNING;
771         __remove_wait_queue(&info->rwait, &wait);
772         return (ret_val);
773 } // ifx_ssc_read_helper
774
775
776 #if 0
777 /* helper routine to handle reads from the kernel or user-space */
778 /* appropriate in interrupt context */
779 static ssize_t
780 ifx_ssc_read_helper(struct ifx_ssc_port *info, char *buf, size_t len,
781                     int from_kernel)
782 {
783         ssize_t         ret_val;
784         unsigned long   flags;
785         DECLARE_WAITQUEUE(wait, current);
786         
787         if (info->opts.modeRxTx == IFX_SSC_MODE_TX) 
788                 return -EFAULT;
789         local_irq_save(flags);
790         info->rxbuf_ptr = info->rxbuf;
791         info->rxbuf_end = info->rxbuf + len;
792         if (info->opts.modeRxTx == IFX_SSC_MODE_RXTX) {
793                 if ((info->txbuf == NULL) ||
794                     (info->txbuf != info->txbuf_ptr) ||
795                     (info->txbuf_end != len + info->txbuf)) {
796                         local_irq_restore(flags);
797                         printk("IFX SSC - %s: write must be called before calling "
798                                "read in combined RX/TX!\n", __FUNCTION__);
799                         return -EFAULT;
800                 }
801                 local_irq_restore(flags);
802                 /* should enable tx, right?*/
803                 tx_int(info);
804                 if (!in_irq()){
805                         if (info->txbuf_ptr < info->txbuf_end){
806                                 ifx_int_wrapper.enable(info->txirq);
807                         }
808                         ifx_int_wrapper.enable(info->rxirq);
809                 }
810         } else { // rx mode
811                 local_irq_restore(flags);
812                 if (READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_RXCNT) &
813                     IFX_SSC_RXCNT_TODO_MASK)
814                         return -EBUSY;
815                 if (!in_irq()){
816                         ifx_int_wrapper.enable(info->rxirq);
817                 }
818
819                 if (len < IFX_SSC_RXREQ_BLOCK_SIZE)
820                         WRITE_PERIPHERAL_REGISTER(len << IFX_SSC_RXREQ_RXCOUNT_OFFSET, 
821                                                   info->mapbase + IFX_SSC_RXREQ);
822                 else 
823                         WRITE_PERIPHERAL_REGISTER(IFX_SSC_RXREQ_BLOCK_SIZE << IFX_SSC_RXREQ_RXCOUNT_OFFSET, 
824                                                   info->mapbase + IFX_SSC_RXREQ);
825         }
826         if (in_irq()){
827                 do {
828                         rx_int(info);
829                         if (info->opts.modeRxTx == IFX_SSC_MODE_RXTX) {
830                                 tx_int(info);
831                         }
832                         
833                         if (info->rxbuf_ptr >= info->rxbuf_end)
834                                 break;
835                 } while (1);
836                 ret_val = info->rxbuf_ptr - info->rxbuf;
837         }else{
838                 __add_wait_queue(&info->rwait, &wait);
839                 set_current_state(TASK_INTERRUPTIBLE);
840                 // wakeup done in rx_int
841         
842                 do {
843                         local_irq_save(flags);
844                         if (info->rxbuf_ptr >= info->rxbuf_end)
845                                 break;
846                         local_irq_restore(flags);
847
848                         if (signal_pending(current)) {
849                                 ret_val = -ERESTARTSYS;
850                                 goto out;
851                         }
852                         schedule();
853                 } while (1);
854
855                 ret_val = info->rxbuf_ptr - info->rxbuf; // should be equal to len
856                 local_irq_restore(flags);
857
858   out:
859                 current->state = TASK_RUNNING;
860                 __remove_wait_queue(&info->rwait, &wait);
861         }
862         return (ret_val);
863 } // ifx_ssc_read_helper
864 #endif
865
866 /* helper routine to handle writes to the kernel or user-space */
867 /* info->txbuf has two cases:
868  *      1) return value < 0 (-EFAULT), not touched at all
869  *      2) kfree and points to NULL in interrupt routine (but maybe later )
870  */
871 static ssize_t
872 ifx_ssc_write_helper(struct ifx_ssc_port *info, const char *buf,
873                 size_t len, int from_kernel)
874 {
875         // check if in tx or tx/rx mode
876         if (info->opts.modeRxTx == IFX_SSC_MODE_RX)
877                 return -EFAULT;
878
879         info->txbuf_ptr = info->txbuf;
880         info->txbuf_end = len + info->txbuf;
881         /* start the transmission (not in rx/tx, see read helper) */
882         if (info->opts.modeRxTx == IFX_SSC_MODE_TX) {
883                 tx_int(info);
884                 if (info->txbuf_ptr < info->txbuf_end){
885                         ifx_int_wrapper.enable(info->txirq);
886                 }
887         }
888         //local_irq_restore(flags);
889         return len;
890 }
891
892 /*
893  * kernel interfaces for read and write.
894  * The caller must set port to: n for SSC<m> with n=m-1 (e.g. n=0 for SSC1)
895  */
896 ssize_t
897 ifx_ssc_kread(int port, char *kbuf, size_t len)
898 {
899         struct ifx_ssc_port *info;
900         ssize_t ret_val;
901
902         if (port < 0 || port >= PORT_CNT)
903                 return -ENXIO;
904
905         if (len == 0)
906                 return 0;
907
908         info = &isp[port];
909
910         // check if reception in progress
911         if (info->rxbuf != NULL){
912                 printk("SSC device busy\n");
913                 return -EBUSY;
914         }
915
916         info->rxbuf = kbuf;
917         if (info->rxbuf == NULL){
918                 printk("SSC device error\n");
919                 return -EINVAL;
920         }
921
922 /* changed by bingtao */
923         /* change by TaiCheng */
924         //if (!in_irq()){
925         if (0){
926                 ret_val = ifx_ssc_read_helper(info, kbuf, len, 1);
927         }else{
928                 ret_val = ifx_ssc_read_helper_poll(info, kbuf, len, 1);
929         };              
930         info->rxbuf = NULL;
931
932         // ### TO DO: perhaps warn if ret_val != len
933         ifx_int_wrapper.disable(info->rxirq);
934
935         return (ret_val);
936 } // ifx_ssc_kread
937 EXPORT_SYMBOL(ifx_ssc_kread);
938
939 ssize_t
940 ifx_ssc_kwrite(int port, const char *kbuf, size_t len)
941 {
942         struct ifx_ssc_port *info;
943         ssize_t ret_val;
944
945         if (port < 0 || port >= PORT_CNT)
946                 return -ENXIO;
947
948         if (len == 0)
949                 return 0;
950
951         info = &isp[port];
952
953         // check if transmission in progress
954         if (info->txbuf != NULL)
955                 return -EBUSY;
956         info->txbuf = (char *)kbuf;
957
958         ret_val = ifx_ssc_write_helper(info, info->txbuf, len, 1);
959         if (ret_val < 0){
960                 info->txbuf = NULL;
961         }
962         return ret_val;
963 }
964 EXPORT_SYMBOL(ifx_ssc_kwrite);
965
966
967 /* 
968  * user interfaces to read and write
969  */
970 static ssize_t
971 ifx_ssc_read(struct file *filp, char *ubuf, size_t len, loff_t *off)
972 {
973         ssize_t ret_val;
974         int idx;
975         struct ifx_ssc_port *info;
976
977 /*
978         if (len == 0)
979                 return (0);
980 */
981         idx = MINOR(filp->f_dentry->d_inode->i_rdev);
982         info = &isp[idx];
983
984         // check if reception in progress
985         if (info->rxbuf != NULL)
986                 return -EBUSY;
987
988         info->rxbuf = kmalloc(len+ 3, GFP_KERNEL);
989         if (info->rxbuf == NULL)
990                 return -ENOMEM;
991
992         ret_val = ifx_ssc_read_helper(info, info->rxbuf, len, 0);
993         // ### TO DO: perhaps warn if ret_val != len
994         if (copy_to_user((void*)ubuf, info->rxbuf, ret_val) != 0)
995                 ret_val = -EFAULT;
996
997         ifx_int_wrapper.disable(info->rxirq);
998
999         kfree(info->rxbuf);
1000         info->rxbuf = NULL;
1001         return (ret_val);
1002 } // ifx_ssc_read
1003
1004 /*
1005  * As many bytes as we have free space for are copied from the user
1006  * into txbuf and the actual byte count is returned. The transmission is
1007  * always kicked off by calling the appropriate TX routine.
1008  */
1009 static ssize_t
1010 ifx_ssc_write(struct file *filp, const char *ubuf, size_t len, loff_t *off)
1011 {
1012         int idx;
1013         struct ifx_ssc_port *info;
1014         int ret_val;
1015
1016         if (len == 0)
1017                 return (0);
1018
1019         idx = MINOR(filp->f_dentry->d_inode->i_rdev);
1020         info = &isp[idx];
1021
1022         // check if transmission in progress
1023         if (info->txbuf != NULL)
1024                 return -EBUSY;
1025
1026         info->txbuf = kmalloc(len+ 3, GFP_KERNEL);
1027         if (info->txbuf == NULL)
1028                 return -ENOMEM;
1029
1030         ret_val = copy_from_user(info->txbuf, ubuf, len);
1031         if (ret_val == 0)
1032                 ret_val = ifx_ssc_write_helper(info, info->txbuf, len, 0);
1033         else
1034                 ret_val = -EFAULT;
1035         if (ret_val < 0) {
1036                 kfree(info->txbuf); // otherwise will be done in ISR
1037                 info->txbuf = NULL;
1038         }
1039         return (ret_val);
1040 } /* ifx_ssc_write */
1041
1042
1043 /*
1044  * ------------------------------------------------------------
1045  * ifx_ssc_ioctl() and friends
1046  * ------------------------------------------------------------
1047  */
1048
1049 /*-----------------------------------------------------------------------------
1050  FUNC-NAME  : ifx_ssc_frm_status_get
1051  LONG-NAME  : framing status get
1052  PURPOSE    : Get the actual status of the framing.
1053
1054  PARAMETER  : *info     pointer to the port-specific structure ifx_ssc_port.
1055
1056  RESULT     : pointer to a structure ifx_ssc_frm_status which holds busy and 
1057               count values.
1058
1059  REMARKS    : Returns a register value independent of framing is enabled or 
1060               not! Changes structure inside of info, so the return value isn't 
1061               needed at all, but could be used for simple access.
1062 -----------------------------------------------------------------------------*/
1063 static struct ifx_ssc_frm_status *
1064 ifx_ssc_frm_status_get(struct ifx_ssc_port *info)
1065 {
1066         unsigned long tmp;
1067         
1068         tmp = READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_SFSTAT);
1069         info->frm_status.DataBusy = (tmp & IFX_SSC_SFSTAT_IN_DATA) > 0;
1070         info->frm_status.PauseBusy = (tmp & IFX_SSC_SFSTAT_IN_PAUSE) > 0;
1071         info->frm_status.DataCount = (tmp & IFX_SSC_SFSTAT_DATA_COUNT_MASK) 
1072                 >> IFX_SSC_SFSTAT_DATA_COUNT_OFFSET;
1073         info->frm_status.PauseCount = (tmp & IFX_SSC_SFSTAT_PAUSE_COUNT_MASK) 
1074                 >> IFX_SSC_SFSTAT_PAUSE_COUNT_OFFSET;
1075         tmp = READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_SFCON);
1076         info->frm_status.EnIntAfterData = 
1077                 (tmp & IFX_SSC_SFCON_FIR_ENABLE_BEFORE_PAUSE) > 0;
1078         info->frm_status.EnIntAfterPause = 
1079                 (tmp & IFX_SSC_SFCON_FIR_ENABLE_AFTER_PAUSE) > 0;
1080         return (&info->frm_status);
1081 } // ifx_ssc_frm_status_get
1082
1083
1084 /*-----------------------------------------------------------------------------
1085  FUNC-NAME  : ifx_ssc_frm_control_get
1086  LONG-NAME  : framing control get
1087  PURPOSE    : Get the actual control values of the framing.
1088
1089  PARAMETER  : *info     pointer to the port-specific structure ifx_ssc_port.
1090
1091  RESULT     : pointer to a structure ifx_ssc_frm_opts which holds control bits  
1092               and count reload values.
1093
1094  REMARKS    : Changes structure inside of info, so the return value isn't 
1095               needed at all, but could be used for simple access.
1096 -----------------------------------------------------------------------------*/
1097 static struct ifx_ssc_frm_opts *
1098 ifx_ssc_frm_control_get(struct ifx_ssc_port *info)
1099 {
1100         unsigned long tmp;
1101         
1102         tmp = READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_SFCON);
1103         info->frm_opts.FrameEnable = (tmp & IFX_SSC_SFCON_SF_ENABLE) > 0;
1104         info->frm_opts.DataLength = (tmp & IFX_SSC_SFCON_DATA_LENGTH_MASK) 
1105                 >> IFX_SSC_SFCON_DATA_LENGTH_OFFSET;
1106         info->frm_opts.PauseLength = (tmp & IFX_SSC_SFCON_PAUSE_LENGTH_MASK) 
1107                 >> IFX_SSC_SFCON_PAUSE_LENGTH_OFFSET;
1108         info->frm_opts.IdleData = (tmp & IFX_SSC_SFCON_PAUSE_DATA_MASK) 
1109                 >> IFX_SSC_SFCON_PAUSE_DATA_OFFSET;
1110         info->frm_opts.IdleClock = (tmp & IFX_SSC_SFCON_PAUSE_CLOCK_MASK) 
1111                 >> IFX_SSC_SFCON_PAUSE_CLOCK_OFFSET;
1112         info->frm_opts.StopAfterPause = 
1113                 (tmp & IFX_SSC_SFCON_STOP_AFTER_PAUSE) > 0;
1114         return (&info->frm_opts);
1115 } // ifx_ssc_frm_control_get
1116
1117
1118 /*-----------------------------------------------------------------------------
1119  FUNC-NAME  : ifx_ssc_frm_control_set
1120  LONG-NAME  : framing control set
1121  PURPOSE    : Set the actual control values of the framing.
1122
1123  PARAMETER  : *info     pointer to the port-specific structure ifx_ssc_port.
1124
1125  RESULT     : pointer to a structure ifx_ssc_frm_opts which holds control bits  
1126               and count reload values.
1127
1128  REMARKS    : 
1129 -----------------------------------------------------------------------------*/
1130 static int
1131 ifx_ssc_frm_control_set(struct ifx_ssc_port *info)
1132 {
1133         unsigned long tmp;
1134
1135         // check parameters
1136         if ((info->frm_opts.DataLength > IFX_SSC_SFCON_DATA_LENGTH_MAX) || 
1137             (info->frm_opts.DataLength < 1) ||
1138             (info->frm_opts.PauseLength > IFX_SSC_SFCON_PAUSE_LENGTH_MAX) || 
1139             (info->frm_opts.PauseLength < 1) ||
1140             ((info->frm_opts.IdleData & ~(IFX_SSC_SFCON_PAUSE_DATA_MASK >> 
1141                                           IFX_SSC_SFCON_PAUSE_DATA_OFFSET)) != 0 ) || 
1142             ((info->frm_opts.IdleClock & ~(IFX_SSC_SFCON_PAUSE_CLOCK_MASK >> 
1143                                            IFX_SSC_SFCON_PAUSE_CLOCK_OFFSET)) != 0 ))
1144                 return -EINVAL;
1145
1146         // read interrupt bits (they're not changed here)
1147         tmp = READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_SFCON) &
1148                 (IFX_SSC_SFCON_FIR_ENABLE_BEFORE_PAUSE | 
1149                  IFX_SSC_SFCON_FIR_ENABLE_AFTER_PAUSE);
1150
1151         // set all values with respect to it's bit position (for data and pause 
1152         // length set N-1)
1153         tmp = (info->frm_opts.DataLength - 1) << IFX_SSC_SFCON_DATA_LENGTH_OFFSET;
1154         tmp |= (info->frm_opts.PauseLength - 1) << IFX_SSC_SFCON_PAUSE_LENGTH_OFFSET;
1155         tmp |= info->frm_opts.IdleData << IFX_SSC_SFCON_PAUSE_DATA_OFFSET;
1156         tmp |= info->frm_opts.IdleClock << IFX_SSC_SFCON_PAUSE_CLOCK_OFFSET;
1157         tmp |= info->frm_opts.FrameEnable * IFX_SSC_SFCON_SF_ENABLE;
1158         tmp |= info->frm_opts.StopAfterPause * IFX_SSC_SFCON_STOP_AFTER_PAUSE;
1159
1160         WRITE_PERIPHERAL_REGISTER(tmp, info->mapbase + IFX_SSC_SFCON);
1161
1162         return 0;
1163 } // ifx_ssc_frm_control_set
1164
1165
1166 /*-----------------------------------------------------------------------------
1167  FUNC-NAME  : ifx_ssc_rxtx_mode_set
1168  LONG-NAME  : rxtx mode set
1169  PURPOSE    : Set the transmission mode.
1170
1171  PARAMETER  : *info     pointer to the port-specific structure ifx_ssc_port.
1172
1173  RESULT     : Returns error code
1174
1175  REMARKS    : Assumes that SSC not used (SSC disabled, device not opened yet 
1176               or just closed) 
1177 -----------------------------------------------------------------------------*/
1178 static int
1179 ifx_ssc_rxtx_mode_set(struct ifx_ssc_port *info, unsigned int val)
1180 {
1181         unsigned long tmp;
1182
1183         // check parameters
1184         if (!(info) || (val & ~(IFX_SSC_MODE_MASK)))
1185                 return -EINVAL;
1186         /*check BUSY and RXCNT*/        
1187         if (  READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_STATE) & IFX_SSC_STATE_BUSY
1188             ||READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_RXCNT) & IFX_SSC_RXCNT_TODO_MASK)
1189                 return -EBUSY;
1190         // modify 
1191         tmp = (READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_CON) &
1192                 ~(IFX_SSC_CON_RX_OFF | IFX_SSC_CON_TX_OFF)) | (val);
1193         WRITE_PERIPHERAL_REGISTER(tmp, info->mapbase + IFX_SSC_CON);
1194         info->opts.modeRxTx = val;
1195 /*      
1196         printk(KERN_DEBUG "IFX SSC%d: Setting mode to %s%s\n", 
1197                info->port_nr,
1198                ((val & IFX_SSC_CON_RX_OFF) == 0) ? "rx ":"", 
1199                ((val & IFX_SSC_CON_TX_OFF) == 0) ? "tx":"");
1200 */
1201         return 0;
1202 } // ifx_ssc_rxtx_mode_set
1203
1204 void ifx_gpio_init(void) 
1205 {
1206         u32     temp;
1207 /* set gpio pin p0.10(SPI_DIN) p0.11(SPI_DOUT) p0.12(SPI_CLK) p0.13(SPI_CS2) direction */
1208         temp = *(AMAZON_GPIO_P0_DIR) ;
1209         temp &= 0xFFFFFBFF;
1210         temp |= 0x3800;
1211         *(AMAZON_GPIO_P0_DIR) = temp;
1212 /* set port 0 alternate select register 0 */
1213         temp = *(AMAZON_GPIO_P0_ALTSEL0) ;
1214         temp &= 0xFFFFC3FF;
1215         temp |= 0x00001c00;
1216         *(AMAZON_GPIO_P0_ALTSEL0) = temp;
1217
1218 /* set port 0 alternate select register 1 */
1219         temp = *(AMAZON_GPIO_P0_ALTSEL1) ;
1220         temp &= 0xFFFFC3FF;
1221         temp |= 0x00002000;
1222         *(AMAZON_GPIO_P0_ALTSEL1) = temp;
1223
1224 /* set port 0 open drain mode register */
1225         temp = *(AMAZON_GPIO_P0_OD);
1226         temp |= 0x00003800;     /* set output pin normal mode */
1227         *(AMAZON_GPIO_P0_OD)= temp;
1228 }
1229
1230 /*
1231  * This routine intializes the SSC appropriately depending
1232  * on slave/master and full-/half-duplex mode.
1233  * It assumes that the SSC is disabled and the fifo's and buffers 
1234  * are flushes later on.
1235  */
1236 static int
1237 ifx_ssc_sethwopts(struct ifx_ssc_port *info)
1238 {
1239         unsigned long flags, bits;
1240         struct ifx_ssc_hwopts *opts = &info->opts;
1241
1242         /* sanity checks */
1243         if ((opts->dataWidth < IFX_SSC_MIN_DATA_WIDTH) ||
1244             (opts->dataWidth > IFX_SSC_MAX_DATA_WIDTH)) {
1245                 printk("%s: sanity check failed\n", __FUNCTION__);
1246                 return -EINVAL;
1247         }
1248         bits = (opts->dataWidth - 1) << IFX_SSC_CON_DATA_WIDTH_OFFSET;
1249         bits |= IFX_SSC_CON_ENABLE_BYTE_VALID;
1250 //      if (opts->abortErrDetect)
1251 //              bits |= IFX_SSC_CON_ABORT_ERR_CHECK;
1252         if (opts->rxOvErrDetect)
1253                 bits |= IFX_SSC_CON_RX_OFL_CHECK;
1254         if (opts->rxUndErrDetect)
1255                 bits |= IFX_SSC_CON_RX_UFL_CHECK;
1256         if (opts->txOvErrDetect)
1257                 bits |= IFX_SSC_CON_TX_OFL_CHECK;
1258         if (opts->txUndErrDetect)
1259                 bits |= IFX_SSC_CON_TX_UFL_CHECK;
1260         if (opts->loopBack)
1261                 bits |= IFX_SSC_CON_LOOPBACK_MODE;
1262         if (opts->echoMode)
1263                 bits |= IFX_SSC_CON_ECHO_MODE_ON;
1264         if (opts->headingControl)
1265                 bits |= IFX_SSC_CON_MSB_FIRST;
1266         if (opts->clockPhase)
1267                 bits |= IFX_SSC_CON_LATCH_THEN_SHIFT;
1268         if (opts->clockPolarity)
1269                 bits |= IFX_SSC_CON_CLOCK_FALL;
1270         switch (opts->modeRxTx) {
1271         case IFX_SSC_MODE_TX:
1272                 bits |= IFX_SSC_CON_RX_OFF;
1273                 break;
1274         case IFX_SSC_MODE_RX:
1275                 bits |= IFX_SSC_CON_TX_OFF;
1276                 break;
1277         } // switch (opts->modeRxT)
1278         local_irq_save(flags);
1279         WRITE_PERIPHERAL_REGISTER(bits, info->mapbase + IFX_SSC_CON);
1280         WRITE_PERIPHERAL_REGISTER((info->opts.gpoCs << IFX_SSC_GPOCON_ISCSB0_POS) | 
1281                                   (info->opts.gpoInv << IFX_SSC_GPOCON_INVOUT0_POS), 
1282                                   info->mapbase + IFX_SSC_GPOCON);
1283         //master mode
1284         if (opts->masterSelect){
1285                 WRITE_PERIPHERAL_REGISTER(IFX_SSC_WHBSTATE_SET_MASTER_SELECT,info->mapbase + IFX_SSC_WHBSTATE);
1286         }else{
1287                 WRITE_PERIPHERAL_REGISTER(IFX_SSC_WHBSTATE_CLR_MASTER_SELECT,info->mapbase + IFX_SSC_WHBSTATE);
1288         }
1289         // init serial framing
1290         WRITE_PERIPHERAL_REGISTER(0, info->mapbase + IFX_SSC_SFCON);
1291         /* set up the port pins */
1292         //check for general requirements to switch (external) pad/pin characteristics
1293         ifx_gpio_init();
1294         local_irq_restore(flags);
1295
1296         return 0;
1297 } // ifx_ssc_sethwopts
1298
1299 static int
1300 ifx_ssc_set_baud(struct ifx_ssc_port *info, unsigned int baud)
1301 {
1302         unsigned int ifx_ssc_clock;
1303         unsigned int br;
1304         unsigned long flags;
1305         bool enabled;
1306
1307         ifx_ssc_clock = ifx_ssc_get_kernel_clk(info);
1308         if (ifx_ssc_clock ==0)
1309                 return -EINVAL;
1310
1311         local_irq_save(flags);
1312         /* have to disable the SSC to set the baudrate */
1313         enabled = (READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_STATE) 
1314                    & IFX_SSC_STATE_IS_ENABLED) != 0;
1315         WRITE_PERIPHERAL_REGISTER(IFX_SSC_WHBSTATE_CLR_ENABLE, 
1316                                   info->mapbase + IFX_SSC_WHBSTATE);
1317
1318         // compute divider
1319         br = ((ifx_ssc_clock >> 1)/baud) - 1;
1320         asm("SYNC"); 
1321         if (br > 0xffff || 
1322             ((br == 0) && 
1323              ((READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_STATE) & 
1324                IFX_SSC_STATE_IS_MASTER) == 0))){
1325                 local_irq_restore(flags);
1326                 printk("%s: illegal baudrate %u\n", __FUNCTION__, baud);
1327                 return -EINVAL;
1328         }
1329         WRITE_PERIPHERAL_REGISTER(br, info->mapbase + IFX_SSC_BR);
1330         if (enabled)
1331                 WRITE_PERIPHERAL_REGISTER(IFX_SSC_WHBSTATE_SET_ENABLE, 
1332                                           info->mapbase + IFX_SSC_WHBSTATE);
1333
1334         local_irq_restore(flags);
1335         return 0;
1336 } // ifx_ssc_set_baud
1337
1338 static int
1339 ifx_ssc_hwinit(struct ifx_ssc_port *info)
1340 {
1341         unsigned long flags;
1342         bool enabled;
1343
1344         /* have to disable the SSC */
1345         enabled = (READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_STATE) 
1346                    & IFX_SSC_STATE_IS_ENABLED) != 0;
1347         WRITE_PERIPHERAL_REGISTER(IFX_SSC_WHBSTATE_CLR_ENABLE, 
1348                                   info->mapbase + IFX_SSC_WHBSTATE);
1349
1350         if (ifx_ssc_sethwopts(info) < 0)
1351         {
1352                 printk("%s: setting the hardware options failed\n",
1353                        __FUNCTION__);
1354                 return -EINVAL;
1355         }
1356
1357         if (ifx_ssc_set_baud(info, info->baud) < 0) {
1358                 printk("%s: setting the baud rate failed\n", __FUNCTION__);
1359                 return -EINVAL;
1360         }
1361         local_irq_save(flags);
1362         /* TX FIFO */
1363         WRITE_PERIPHERAL_REGISTER((IFX_SSC_DEF_TXFIFO_FL << 
1364                                    IFX_SSC_XFCON_ITL_OFFSET) | 
1365                                   IFX_SSC_XFCON_FIFO_ENABLE, 
1366                                   info->mapbase + IFX_SSC_TXFCON);
1367         /* RX FIFO */
1368         WRITE_PERIPHERAL_REGISTER((IFX_SSC_DEF_RXFIFO_FL << 
1369                                    IFX_SSC_XFCON_ITL_OFFSET) | 
1370                                   IFX_SSC_XFCON_FIFO_ENABLE, 
1371                                   info->mapbase + IFX_SSC_RXFCON);
1372         local_irq_restore(flags);
1373         if (enabled)
1374                 WRITE_PERIPHERAL_REGISTER(IFX_SSC_WHBSTATE_SET_ENABLE, 
1375                                           info->mapbase + IFX_SSC_WHBSTATE);
1376         return 0;
1377 } // ifx_ssc_hwinit
1378
1379 /*-----------------------------------------------------------------------------
1380  FUNC-NAME  : ifx_ssc_batch_exec
1381  LONG-NAME  : 
1382  PURPOSE    : 
1383
1384  PARAMETER  : *info     pointer to the port-specific structure ifx_ssc_port.
1385
1386  RESULT     : Returns error code
1387
1388  REMARKS    : 
1389 -----------------------------------------------------------------------------*/
1390 static int
1391 ifx_ssc_batch_exec(struct ifx_ssc_port *info, struct ifx_ssc_batch_list *batch_anchor)
1392 {
1393         // ### TO DO: implement user space batch execution
1394         // first, copy the whole linked list from user to kernel space
1395         // save some hardware options
1396         // execute list
1397         // restore hardware options if selected
1398         return -EFAULT;
1399 } // ifx_ssc_batch_exec
1400
1401
1402 /*
1403  * This routine allows the driver to implement device-
1404  * specific ioctl's.  If the ioctl number passed in cmd is
1405  * not recognized by the driver, it should return ENOIOCTLCMD.
1406  */
1407 int
1408 ifx_ssc_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
1409               unsigned long data)
1410 {
1411         struct ifx_ssc_port *info;
1412         int line, ret_val = 0;
1413         unsigned long flags;
1414         unsigned long tmp;
1415         int from_kernel = 0;
1416
1417         if ((inode == (struct inode *)0) || (inode == (struct inode *)1))
1418         {
1419                 from_kernel = 1;
1420                 line = (int)inode;
1421         }
1422         else
1423                 line = MINOR(filp->f_dentry->d_inode->i_rdev);
1424
1425         /* don't use more minor devices than we can support */
1426         if (line < 0 || line >= PORT_CNT)
1427                 return -ENXIO;
1428
1429         info = &isp[line];
1430
1431         switch (cmd) {
1432         case IFX_SSC_STATS_READ:
1433                 /* data must be a pointer to a struct ifx_ssc_statistics */
1434                 if (from_kernel)
1435                         memcpy((void *)data, (void *)&info->stats,
1436                                sizeof(struct ifx_ssc_statistics));
1437                 else
1438                         if (copy_to_user((void *)data,
1439                                          (void *)&info->stats,
1440                                          sizeof(struct ifx_ssc_statistics)))
1441                                 ret_val = -EFAULT;
1442                 break;
1443         case IFX_SSC_STATS_RESET:
1444                 /* just resets the statistics counters */
1445                 memset((void *)&info->stats, 0, sizeof(struct ifx_ssc_statistics));
1446                 break;
1447         case IFX_SSC_BAUD_SET:
1448                 /* if the buffers are not empty then the port is */
1449                 /* busy and we shouldn't change things on-the-fly! */
1450                 if (!info->txbuf || !info->rxbuf || 
1451                     (READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_STATE) 
1452                      & IFX_SSC_STATE_BUSY)) {
1453                         ret_val = -EBUSY;
1454                         break;
1455                 }
1456                 /* misuse flags */
1457                 if (from_kernel)
1458                         flags = *((unsigned long *)data);
1459                 else
1460                         if (copy_from_user((void *)&flags,
1461                                            (void *)data, sizeof(flags)))
1462                         {
1463                                 ret_val = -EFAULT;
1464                                 break;
1465                         }
1466                 if (flags == 0)
1467                 {
1468                         ret_val = -EINVAL;
1469                         break;
1470                 }
1471                 if (ifx_ssc_set_baud(info, flags) < 0)
1472                 {
1473                         ret_val = -EINVAL;
1474                         break;
1475                 }
1476                 info->baud = flags;
1477                 break;
1478         case IFX_SSC_BAUD_GET:
1479                 if (from_kernel)
1480                         *((unsigned int *)data) = info->baud;
1481                 else
1482                         if (copy_to_user((void *)data,
1483                                          (void *)&info->baud,
1484                                          sizeof(unsigned long)))
1485                                 ret_val = -EFAULT;
1486                 break;
1487         case IFX_SSC_RXTX_MODE_SET:
1488                 if (from_kernel)
1489                         tmp = *((unsigned long *)data);
1490                 else
1491                         if (copy_from_user((void *)&tmp,
1492                                            (void *)data, sizeof(tmp))) {
1493                                 ret_val = -EFAULT;
1494                                 break;
1495                         }
1496                 ret_val = ifx_ssc_rxtx_mode_set(info, tmp);
1497                 break;
1498         case IFX_SSC_RXTX_MODE_GET:
1499                 tmp = READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_CON) &
1500                         (~(IFX_SSC_CON_RX_OFF | IFX_SSC_CON_TX_OFF));
1501                 if (from_kernel)
1502                         *((unsigned int *)data) = tmp;
1503                 else
1504                         if (copy_to_user((void *)data,
1505                                          (void *)&tmp,
1506                                          sizeof(tmp)))
1507                                 ret_val = -EFAULT;
1508                 break;
1509
1510         case IFX_SSC_ABORT:
1511                 ifx_ssc_abort(info);
1512                 break;
1513
1514         case IFX_SSC_GPO_OUT_SET:
1515                 if (from_kernel)
1516                         tmp = *((unsigned long *)data);
1517                 else
1518                         if (copy_from_user((void *)&tmp,
1519                                            (void *)data, sizeof(tmp))) {
1520                                 ret_val = -EFAULT;
1521                                 break;
1522                         }
1523                 if (tmp > IFX_SSC_MAX_GPO_OUT)
1524                         ret_val = -EINVAL;
1525                 else
1526                         WRITE_PERIPHERAL_REGISTER
1527                                 (1<<(tmp + IFX_SSC_WHBGPOSTAT_SETOUT0_POS), 
1528                                  info->mapbase + IFX_SSC_WHBGPOSTAT);
1529                 break;
1530         case IFX_SSC_GPO_OUT_CLR:
1531                 if (from_kernel)
1532                         tmp = *((unsigned long *)data);
1533                 else
1534                         if (copy_from_user((void *)&tmp,
1535                                            (void *)data, sizeof(tmp))) {
1536                                 ret_val = -EFAULT;
1537                                 break;
1538                         }
1539                 if (tmp > IFX_SSC_MAX_GPO_OUT)
1540                         ret_val = -EINVAL;
1541                 else {
1542                         WRITE_PERIPHERAL_REGISTER
1543                                 (1<<(tmp + IFX_SSC_WHBGPOSTAT_CLROUT0_POS), 
1544                                  info->mapbase + IFX_SSC_WHBGPOSTAT);
1545                 }
1546                 break;
1547         case IFX_SSC_GPO_OUT_GET:
1548                 tmp = READ_PERIPHERAL_REGISTER
1549                         (info->mapbase + IFX_SSC_GPOSTAT);
1550                 if (from_kernel)
1551                         *((unsigned int *)data) = tmp;
1552                 else
1553                         if (copy_to_user((void *)data,
1554                                          (void *)&tmp,
1555                                          sizeof(tmp)))
1556                                 ret_val = -EFAULT;
1557                 break;
1558         case IFX_SSC_FRM_STATUS_GET:
1559                 ifx_ssc_frm_status_get(info);
1560                 if (from_kernel)
1561                         memcpy((void *)data, (void *)&info->frm_status,
1562                                sizeof(struct ifx_ssc_frm_status));
1563                 else
1564                         if (copy_to_user((void *)data,
1565                                          (void *)&info->frm_status,
1566                                          sizeof(struct ifx_ssc_frm_status)))
1567                                 ret_val = -EFAULT;
1568                 break;
1569         case IFX_SSC_FRM_CONTROL_GET:
1570                 ifx_ssc_frm_control_get(info);
1571                 if (from_kernel)
1572                         memcpy((void *)data, (void *)&info->frm_opts,
1573                                sizeof(struct ifx_ssc_frm_opts));
1574                 else
1575                         if (copy_to_user((void *)data,
1576                                          (void *)&info->frm_opts,
1577                                          sizeof(struct ifx_ssc_frm_opts)))
1578                                 ret_val = -EFAULT;
1579                 break;
1580         case IFX_SSC_FRM_CONTROL_SET:
1581                 if (from_kernel)
1582                         memcpy((void *)&info->frm_opts, (void *)data, 
1583                                sizeof(struct ifx_ssc_frm_opts));
1584                 else
1585                         if (copy_to_user((void *)&info->frm_opts,
1586                                          (void *)data,
1587                                          sizeof(struct ifx_ssc_frm_opts))){
1588                                 ret_val = -EFAULT;
1589                                 break;
1590                         }
1591                 ret_val = ifx_ssc_frm_control_set(info);
1592                 break;
1593         case IFX_SSC_HWOPTS_SET:
1594                 /* data must be a pointer to a struct ifx_ssc_hwopts */
1595                 /* if the buffers are not empty then the port is */
1596                 /* busy and we shouldn't change things on-the-fly! */
1597                 if (!info->txbuf || !info->rxbuf || 
1598                     (READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_STATE) 
1599                      & IFX_SSC_STATE_BUSY)) {
1600                         ret_val = -EBUSY;
1601                         break;
1602                 }
1603                 if (from_kernel)
1604                         memcpy((void *)&info->opts, (void *)data,
1605                                sizeof(struct ifx_ssc_hwopts));
1606                 else
1607                         if (copy_from_user((void *)&info->opts,
1608                                            (void *)data,
1609                                            sizeof(struct ifx_ssc_hwopts)))
1610                         {
1611                                 ret_val = -EFAULT;
1612                                 break;
1613                         }
1614                 if (ifx_ssc_hwinit(info) < 0)
1615                 {
1616                         ret_val = -EIO;
1617                 }
1618                 break;
1619         case IFX_SSC_HWOPTS_GET:
1620                 /* data must be a pointer to a struct ifx_ssc_hwopts */
1621                 if (from_kernel)
1622                         memcpy((void *)data, (void *)&info->opts,
1623                                sizeof(struct ifx_ssc_hwopts));
1624                 else
1625                         if (copy_to_user((void *)data,
1626                                          (void *)&info->opts,
1627                                          sizeof(struct ifx_ssc_hwopts)))
1628                                 ret_val = -EFAULT;
1629                 break;
1630         default:
1631                 ret_val = -ENOIOCTLCMD;
1632         }
1633
1634         return ret_val;
1635 } /* ifx_ssc_ioctl */
1636 EXPORT_SYMBOL(ifx_ssc_ioctl);
1637
1638 ///* the poll routine */
1639 //static unsigned int
1640 //ifx_ssc_poll(struct file *filp, struct poll_table_struct *pts)
1641 //{
1642 //        int unit = MINOR(filp->f_dentry->d_inode->i_rdev);
1643 //      struct ifx_ssc_port *info;
1644 //        unsigned int mask = 0; 
1645 //      int spc;
1646 //
1647 //      info = &isp[unit];
1648 //
1649 //        /* add event to the wait queues */
1650 //        /* DO NOT FORGET TO DO A WAKEUP ON THESE !!!! */
1651 //        poll_wait(filp, &info->pwait, pts);
1652 //
1653 //      /* are there bytes in the RX SW-FIFO? */
1654 //        if (info->rxrp != info->rxwp)
1655 //                mask |= POLLIN | POLLRDNORM;
1656 //
1657 //      /* free space in the TX SW-FIFO */
1658 //      spc = info->txrp - info->txwp - 1;
1659 //      if (spc < 0)
1660 //              spc += TX_BUFSIZE;
1661 //#ifdef IFX_SSC_USEDMA
1662 //      /* writing always works, except in the DMA case when all descriptors */
1663 //      /* are used up */
1664 //      if (unit == 1 && info->dma_freecnt == 0)
1665 //              spc = 0;
1666 //#endif
1667 //      if (spc > 0)
1668 //              mask |= POLLOUT | POLLWRNORM;
1669 //
1670 //        return (mask);
1671 //}
1672
1673 static int
1674 ifx_ssc1_read_proc(char *page, char **start, off_t offset, int count, int *eof, void *data)
1675 {
1676         int off = 0;
1677         unsigned long flags;
1678
1679         /* don't want any interrupts here */
1680         save_flags(flags);
1681         cli();
1682
1683
1684         /* print statistics */
1685         off += sprintf(page+off, "Statistics for Infineon Synchronous Serial Controller SSC1\n");
1686         off += sprintf(page+off, "RX overflow errors %d\n", isp[0].stats.rxOvErr);
1687         off += sprintf(page+off, "RX underflow errors %d\n", isp[0].stats.rxUnErr);
1688         off += sprintf(page+off, "TX overflow errors %d\n", isp[0].stats.txOvErr);
1689         off += sprintf(page+off, "TX underflow errors %d\n", isp[0].stats.txUnErr);
1690         off += sprintf(page+off, "Abort errors %d\n", isp[0].stats.abortErr);
1691         off += sprintf(page+off, "Mode errors %d\n", isp[0].stats.modeErr);
1692         off += sprintf(page+off, "RX Bytes %d\n", isp[0].stats.rxBytes);
1693         off += sprintf(page+off, "TX Bytes %d\n", isp[0].stats.txBytes);
1694
1695         restore_flags (flags); /* XXXXX */
1696         *eof = 1;
1697         return (off);
1698 }
1699
1700
1701 /*
1702  * This routine prints out the appropriate serial driver version number
1703  */
1704 static inline void
1705 show_version(void)
1706 {
1707 #if 0
1708     printk("Infineon Technologies Synchronous Serial Controller (SSC) driver\n"
1709            "  version %s - built %s %s\n", IFX_SSC_DRV_VERSION, __DATE__, __TIME__);
1710 #endif   
1711 } /* show_version */
1712
1713
1714 /*
1715  * Due to the fact that a port can be dynamically switched between slave
1716  * and master mode using an IOCTL the hardware is not initialized here,
1717  * but in ifx_ssc_hwinit() as a result of an IOCTL.
1718  */
1719 int __init
1720 ifx_ssc_init(void)
1721 {
1722         struct ifx_ssc_port  *info;
1723         int i, nbytes;
1724         unsigned long flags;
1725         int ret_val;
1726
1727         // ### TO DO: dynamic port count evaluation due to pin multiplexing
1728
1729         ret_val = -ENOMEM;
1730         nbytes = PORT_CNT * sizeof(struct ifx_ssc_port);
1731         isp = (struct ifx_ssc_port *)kmalloc(nbytes, GFP_KERNEL);
1732         if (isp == NULL)
1733         {
1734                 printk("%s: no memory for isp\n", __FUNCTION__);
1735                 return (ret_val);
1736         }
1737         memset(isp, 0, nbytes);
1738
1739         show_version();
1740
1741         /* register the device */
1742         ret_val = -ENXIO;
1743 /*
1744         i = maj;
1745 */
1746         if ((i = register_chrdev(maj, "ssc", &ifx_ssc_fops)) < 0)
1747         {
1748                 printk("Unable to register major %d for the Infineon SSC\n", maj);
1749                 if (maj == 0){
1750                         goto errout;
1751                 }
1752                 else{
1753                         maj = 0;
1754                         if ((i = register_chrdev(maj, "ssc", &ifx_ssc_fops)) < 0)
1755                         {
1756                                 printk("Unable to register major %d for the Infineon SSC\n", maj);
1757                                 goto errout;
1758                         }
1759                 }
1760         }
1761         if (maj == 0) maj = i;
1762         //printk("registered major %d for Infineon SSC\n", maj);
1763
1764         /* set default values in ifx_ssc_port */
1765         for (i = 0; i < PORT_CNT; i++) {
1766                 info = &isp[i];
1767                 info->port_nr = i;
1768                 /* default values for the HwOpts */
1769                 info->opts.AbortErrDetect = IFX_SSC_DEF_ABRT_ERR_DETECT;
1770                 info->opts.rxOvErrDetect = IFX_SSC_DEF_RO_ERR_DETECT;
1771                 info->opts.rxUndErrDetect = IFX_SSC_DEF_RU_ERR_DETECT;
1772                 info->opts.txOvErrDetect = IFX_SSC_DEF_TO_ERR_DETECT;
1773                 info->opts.txUndErrDetect = IFX_SSC_DEF_TU_ERR_DETECT;
1774                 info->opts.loopBack = IFX_SSC_DEF_LOOP_BACK;
1775                 info->opts.echoMode = IFX_SSC_DEF_ECHO_MODE;
1776                 info->opts.idleValue = IFX_SSC_DEF_IDLE_DATA;
1777                 info->opts.clockPolarity = IFX_SSC_DEF_CLOCK_POLARITY;
1778                 info->opts.clockPhase = IFX_SSC_DEF_CLOCK_PHASE;
1779                 info->opts.headingControl = IFX_SSC_DEF_HEADING_CONTROL;
1780                 info->opts.dataWidth = IFX_SSC_DEF_DATA_WIDTH;
1781                 info->opts.modeRxTx = IFX_SSC_DEF_MODE_RXTX;
1782                 info->opts.gpoCs = IFX_SSC_DEF_GPO_CS;
1783                 info->opts.gpoInv = IFX_SSC_DEF_GPO_INV;
1784                 info->opts.masterSelect = IFX_SSC_DEF_MASTERSLAVE;
1785                 info->baud = IFX_SSC_DEF_BAUDRATE;
1786                 info->rxbuf = NULL;
1787                 info->txbuf = NULL;
1788                 /* values specific to SSC1 */
1789                 if (i == 0) {
1790                         info->mapbase = AMAZON_SSC_BASE_ADD_0;
1791                         // ### TO DO: power management
1792
1793                         // setting interrupt vectors
1794                         info->txirq = IFX_SSC_TIR;
1795                         info->rxirq = IFX_SSC_RIR;
1796                         info->errirq = IFX_SSC_EIR;
1797 /*
1798                         info->frmirq = IFX_SSC_FIR;
1799 */
1800                 }
1801                 /* activate SSC */
1802                 /* CLC.DISS = 0 */
1803                 WRITE_PERIPHERAL_REGISTER(IFX_SSC_DEF_RMC << IFX_CLC_RUN_DIVIDER_OFFSET, info->mapbase + IFX_SSC_CLC);
1804
1805 // ### TO DO: multiple instances
1806
1807                 init_waitqueue_head(&info->rwait);
1808                 //init_waitqueue_head(&info->pwait);
1809
1810                 local_irq_save(flags);
1811
1812                 // init serial framing register
1813                 WRITE_PERIPHERAL_REGISTER(IFX_SSC_DEF_SFCON, info->mapbase + IFX_SSC_SFCON);
1814
1815                 /* try to get the interrupts */
1816                 // ### TO DO: interrupt handling with multiple instances
1817                 ret_val = ifx_int_wrapper.request(info->txirq, ifx_ssc_tx_int, 
1818                                                   0, "ifx_ssc_tx", info);
1819                 if (ret_val){
1820                         printk("%s: unable to get irq %d\n", __FUNCTION__,
1821                                         info->txirq);
1822                         local_irq_restore(flags);
1823                         goto errout;
1824                 }
1825                 ret_val = ifx_int_wrapper.request(info->rxirq, ifx_ssc_rx_int, 
1826                                                   0, "ifx_ssc_rx", info);
1827                 if (ret_val){
1828                         printk("%s: unable to get irq %d\n", __FUNCTION__,
1829                                         info->rxirq);
1830                         local_irq_restore(flags);
1831                         goto irqerr;
1832                 }
1833                 ret_val = ifx_int_wrapper.request(info->errirq, ifx_ssc_err_int, 
1834                                                   0, "ifx_ssc_err", info);
1835                 if (ret_val){
1836                         printk("%s: unable to get irq %d\n", __FUNCTION__,
1837                                         info->errirq);
1838                         local_irq_restore(flags);
1839                         goto irqerr;
1840                 }
1841 /*
1842                 ret_val = ifx_int_wrapper.request(info->frmirq, ifx_ssc_frm_int, 
1843                                                   0, "ifx_ssc_frm", info);
1844                 if (ret_val){
1845                         printk("%s: unable to get irq %d\n", __FUNCTION__,
1846                                         info->frmirq);
1847                         local_irq_restore(flags);
1848                         goto irqerr;
1849                 }
1850
1851 */
1852                 WRITE_PERIPHERAL_REGISTER(IFX_SSC_DEF_IRNEN, info->mapbase + IFX_SSC_IRN_EN);
1853
1854                 local_irq_restore(flags);
1855         } // for (i = 0; i < PORT_CNT; i++)
1856
1857         /* init the SSCs with default values */
1858         for (i = 0; i < PORT_CNT; i++)
1859         {
1860                 info = &isp[i];
1861                 if (ifx_ssc_hwinit(info) < 0)
1862                 {
1863                         printk("%s: hardware init failed for port %d\n",
1864                                 __FUNCTION__, i);
1865                         goto irqerr;
1866                 }
1867         }
1868
1869         /* register /proc read handler */
1870         // ### TO DO: multiple instances
1871         /* for SSC1, which is always present */
1872         create_proc_read_entry("driver/ssc1", 0, NULL, ifx_ssc1_read_proc, NULL);
1873         return 0;
1874
1875 irqerr:
1876         // ### TO DO: multiple instances
1877         ifx_int_wrapper.free(isp[0].txirq,&isp[0]);
1878         ifx_int_wrapper.free(isp[0].rxirq,&isp[0]);
1879         ifx_int_wrapper.free(isp[0].errirq,&isp[0]);
1880 /*
1881         ifx_int_wrapper.free(isp[0].frmirq, &isp[0]);
1882 */
1883 errout:
1884         /* free up any allocated memory in the error case */
1885         kfree(isp);
1886         return (ret_val);
1887 } /* ifx_ssc_init */
1888
1889
1890 void
1891 ifx_ssc_cleanup_module(void)
1892 {
1893         int i;
1894
1895         /* free up any allocated memory */
1896         for (i = 0; i < PORT_CNT; i++)
1897         {
1898                 /* disable the SSC */
1899                 WRITE_PERIPHERAL_REGISTER(IFX_SSC_WHBSTATE_CLR_ENABLE,isp[i].mapbase + IFX_SSC_WHBSTATE);
1900                 /* free the interrupts */
1901                 ifx_int_wrapper.free(isp[i].txirq, &isp[i]);
1902                 ifx_int_wrapper.free(isp[i].rxirq, &isp[i]);
1903                 ifx_int_wrapper.free(isp[i].errirq, &isp[i]);
1904 /*
1905                 ifx_int_wrapper.free(isp[i].frmirq, &isp[i]);
1906
1907                 if (isp[i].rxbuf != NULL)
1908                         kfree(isp[i].rxbuf);
1909                 if (isp[i].txbuf != NULL)
1910                         kfree(isp[i].txbuf);
1911 */
1912         }
1913         kfree(isp);
1914         /* unregister the device */
1915         if (unregister_chrdev(maj, "ssc"))
1916         {
1917                 printk("Unable to unregister major %d for the SSC\n", maj);
1918         }
1919         /* delete /proc read handler */
1920         remove_proc_entry("driver/ssc1", NULL);
1921         remove_proc_entry("driver/ssc2", NULL);
1922 } /* ifx_ssc_cleanup_module */
1923
1924 module_exit(ifx_ssc_cleanup_module);
1925
1926 /* Module entry-points */
1927 module_init(ifx_ssc_init);
1928
1929 #ifndef MODULE
1930 static int __init
1931 ifx_ssc_set_maj(char *str)
1932 {
1933         maj = simple_strtol(str, NULL, 0);
1934         return 1;
1935 }
1936 __setup("ssc_maj=", ifx_ssc_set_maj);
1937 #endif /* !MODULE */
1938
1939 #define AMAZON_SSC_EMSG(fmt,arg...) printk("%s: "fmt,__FUNCTION__, ##arg)
1940 /* Brief:       chip select enable
1941  */
1942 inline int amazon_ssc_cs_low(u32 pin)
1943 {
1944         int ret=0;
1945         if ((ret=ifx_ssc_ioctl((struct inode *)0, NULL,IFX_SSC_GPO_OUT_CLR, (unsigned long)&pin))){
1946                 AMAZON_SSC_EMSG("clear CS %d fails\n",pin);
1947         }
1948         wmb();
1949         return ret;
1950 }
1951 EXPORT_SYMBOL(amazon_ssc_cs_low);
1952 /* Brief:       chip select disable
1953  */
1954 inline int amazon_ssc_cs_high(u32 pin)
1955 {
1956         int ret=0;
1957         if ((ret=ifx_ssc_ioctl((struct inode *)0, NULL,IFX_SSC_GPO_OUT_SET, (unsigned long)&pin))){
1958                 AMAZON_SSC_EMSG("set CS %d fails\n", pin);
1959         }
1960         wmb();
1961         return ret;
1962 }
1963 EXPORT_SYMBOL(amazon_ssc_cs_high);
1964 /* Brief:       one SSC session
1965  * Parameter:   
1966  *      tx_buf
1967  *      tx_len
1968  *      rx_buf
1969  *      rx_len
1970  *      session_mode: IFX_SSC_MODE_RXTX or IFX_SSC_MODE_TX
1971  * Return:      >=0 number of bytes received (if rx_buf != 0) or transmitted
1972  *              <0 error code
1973  * Description:
1974  *      0. copy data to internal buffer 
1975  *      1. Write command
1976  *      2a. If SSC_SESSION_MODE_TXONLY, read tx_len data
1977  *      2b. If not Read back (tx_len + rx_len) data
1978  *      3. copy internal buffer to rx buf if necessary
1979  */
1980 static int ssc_session(char * tx_buf, u32 tx_len, char * rx_buf, u32 rx_len)
1981 {
1982         int ret=0;
1983
1984         char * ssc_tx_buf=NULL;
1985         char * ssc_rx_buf=NULL;
1986
1987 //      volatile char ssc_tx_buf[128]={0};
1988 //      volatile char ssc_rx_buf[128]={0};
1989
1990         int eff_size=0;
1991         u8 mode=0;
1992         
1993         if (tx_buf == NULL && tx_len ==0 && rx_buf == NULL && rx_len == 0){
1994                 AMAZON_SSC_EMSG("invalid parameters\n");
1995                 ret=-EINVAL;
1996                 goto ssc_session_exit;
1997         }else if (tx_buf == NULL || tx_len == 0){
1998                 if (rx_buf != NULL && rx_len != 0){
1999                         mode = IFX_SSC_MODE_RX;
2000                 }else{
2001                         AMAZON_SSC_EMSG("invalid parameters\n");
2002                         ret=-EINVAL;
2003                         goto ssc_session_exit;
2004                 }
2005         }else if (rx_buf == NULL || rx_len ==0){
2006                 if (tx_buf != NULL && tx_len != 0){
2007                         mode = IFX_SSC_MODE_TX;
2008                 }else{
2009                         AMAZON_SSC_EMSG("invalid parameters\n");
2010                         ret=-EINVAL;
2011                         goto ssc_session_exit;
2012                 }
2013         }else{
2014                 mode = IFX_SSC_MODE_RXTX;
2015         }
2016         
2017         if (mode == IFX_SSC_MODE_RXTX){
2018                 eff_size = tx_len + rx_len;
2019         }else if (mode == IFX_SSC_MODE_RX){
2020                 eff_size = rx_len;
2021         }else{
2022                 eff_size = tx_len;
2023         }
2024
2025         //4 bytes alignment,  required by driver
2026         /* change by TaiCheng */
2027         //if (in_irq()){
2028         if (1){
2029                 ssc_tx_buf = (char*) kmalloc(sizeof(char) *  ((eff_size + 3) & (~3)), GFP_ATOMIC);
2030                 ssc_rx_buf = (char*) kmalloc(sizeof(char) *  ((eff_size + 3) & (~3)), GFP_ATOMIC);
2031         }else{
2032                 ssc_tx_buf = (char*) kmalloc(sizeof(char) *  ((eff_size + 3) & (~3)), GFP_KERNEL);
2033                 ssc_rx_buf = (char*) kmalloc(sizeof(char) *  ((eff_size + 3) & (~3)), GFP_KERNEL);
2034         }
2035         if (ssc_tx_buf == NULL || ssc_rx_buf == NULL){
2036                 AMAZON_SSC_EMSG("no memory for size of %d\n", eff_size);
2037                 ret = -ENOMEM;
2038                 goto ssc_session_exit;
2039         }
2040         memset((void*)ssc_tx_buf, 0, eff_size);
2041         memset((void*)ssc_rx_buf, 0, eff_size);
2042
2043         if (tx_len>0){
2044                 memcpy(ssc_tx_buf, tx_buf, tx_len);
2045         }
2046         
2047         ret=ifx_ssc_kwrite(0, ssc_tx_buf, eff_size);
2048
2049         if (ret > 0) {
2050                 ssc_tx_buf = NULL; //should be freed by ifx_ssc_kwrite
2051         }
2052                 
2053         if (  ret != eff_size ){
2054                 AMAZON_SSC_EMSG("ifx_ssc_write return %d\n",ret); 
2055                 goto ssc_session_exit;
2056         }
2057         ret=ifx_ssc_kread(0, ssc_rx_buf,eff_size);
2058         if (  ret != eff_size ){
2059                 AMAZON_SSC_EMSG("ifx_ssc_read return %d\n",ret); 
2060                 goto ssc_session_exit;
2061         }
2062         
2063         memcpy(rx_buf, ssc_rx_buf+tx_len, rx_len);
2064         
2065         if (mode == IFX_SSC_MODE_TX) {
2066                 ret = tx_len;
2067         }else{
2068                 ret = rx_len;
2069         }
2070 ssc_session_exit:
2071
2072         if (ssc_tx_buf != NULL) kfree(ssc_tx_buf);
2073         if (ssc_rx_buf != NULL) kfree(ssc_rx_buf);
2074
2075         if (ret<0) {
2076                 printk("ssc session fails\n");
2077         }
2078         return ret;
2079 }
2080 /* Brief:       TX-RX session
2081  * Parameter:   
2082  *      tx_buf
2083  *      tx_len
2084  *      rx_buf
2085  *      rx_len
2086  * Return:      >=0 number of bytes received
2087  *              <0 error code
2088  * Description: 
2089  *      1. TX session
2090  *      2. RX session
2091  */
2092 int amazon_ssc_txrx(char * tx_buf, u32 tx_len, char * rx_buf, u32 rx_len)
2093 {
2094         return ssc_session(tx_buf,tx_len,rx_buf,rx_len);
2095 }
2096 EXPORT_SYMBOL(amazon_ssc_txrx);
2097 /* Brief:       TX only session
2098  * Parameter:
2099  *      tx_buf
2100  *      tx_len
2101  * Return:      >=0 number of bytes transmitted
2102  *              <0 error code
2103  */
2104 int amazon_ssc_tx(char * tx_buf, u32 tx_len)
2105 {
2106         return ssc_session(tx_buf,tx_len,NULL,0);
2107 }
2108 EXPORT_SYMBOL(amazon_ssc_tx);
2109 /* Brief:       RX only session
2110  * Parameter:
2111  *      rx_buf
2112  *      rx_len
2113  * Return:      >=0 number of bytes received
2114  *              <0 error code
2115  */
2116 int amazon_ssc_rx(char * rx_buf, u32 rx_len)
2117 {
2118         return ssc_session(NULL,0,rx_buf,rx_len);
2119 }
2120 EXPORT_SYMBOL(amazon_ssc_rx);
2121