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
102MODULE_LICENSE("GPL");
103MODULE_AUTHOR("Michael Schoenenborn");
104MODULE_DESCRIPTION("IFX SSC driver");
105MODULE_SUPPORTED_DEVICE("ifx_ssc");
106MODULE_PARM(maj, "i");
107MODULE_PARM_DESC(maj, "Major device number");
108
109/* allow the user to set the major device number */
110static 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 */
118static struct ifx_ssc_port *isp;
119
120/* prototypes for fops */
121static ssize_t ifx_ssc_read(struct file *, char *, size_t, loff_t *);
122static 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 *);
124int ifx_ssc_ioctl(struct inode *, struct file *, unsigned int, unsigned long);
125int ifx_ssc_open(struct inode *, struct file *);
126int ifx_ssc_close(struct inode *, struct file *);
127
128/* other forward declarations */
129static unsigned int ifx_ssc_get_kernel_clk(struct ifx_ssc_port *info);
130static void ifx_ssc_rx_int(int, void *, struct pt_regs *);
131static void ifx_ssc_tx_int(int, void *, struct pt_regs *);
132static void ifx_ssc_err_int(int, void *, struct pt_regs *);
133#ifdef SSC_FRAME_INT_ENABLE
134static void ifx_ssc_frm_int(int, void *, struct pt_regs *);
135#endif
136static void tx_int(struct ifx_ssc_port *);
137static int ifx_ssc1_read_proc(char *, char **, off_t, int, int *, void *);
138static void ifx_gpio_init(void);
139/************************************************************************
140 *  Function declaration
141 ************************************************************************/
142//interrupt.c
143extern unsigned int amazon_get_fpi_hz(void);
144extern void disable_amazon_irq(unsigned int irq_nr);
145extern void enable_amazon_irq(unsigned int irq_nr);
146extern void mask_and_ack_amazon_irq(unsigned int irq_nr);
147
148
149/*****************************************************************/
150typedef 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
162static 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 */
172static 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
183static 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 */
205static inline void
206ifx_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 */
236static void
237do_ifx_ssc_bh(void)
238{
239    run_task_queue(&tq_cyclades);
240} /* do_ifx_ssc_bh */
241
242static void
243do_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
270inline static void
271rx_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
354inline static void
355tx_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
412static void
413ifx_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
420static void
421ifx_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
428static void
429ifx_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
473static void
474ifx_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
480static void
481ifx_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 */
549int
550ifx_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 */
620EXPORT_SYMBOL(ifx_ssc_open);
621
622/*
623 * This routine is called when a particular device is closed.
624 */
625int
626ifx_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 */
655EXPORT_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 !!! */
661static ssize_t
662ifx_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 !!! */
696static ssize_t
697ifx_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 */
779static ssize_t
780ifx_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 */
871static ssize_t
872ifx_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 */
896ssize_t
897ifx_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
937EXPORT_SYMBOL(ifx_ssc_kread);
938
939ssize_t
940ifx_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}
964EXPORT_SYMBOL(ifx_ssc_kwrite);
965
966
967/*
968 * user interfaces to read and write
969 */
970static ssize_t
971ifx_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 */
1009static ssize_t
1010ifx_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-----------------------------------------------------------------------------*/
1063static struct ifx_ssc_frm_status *
1064ifx_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-----------------------------------------------------------------------------*/
1097static struct ifx_ssc_frm_opts *
1098ifx_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-----------------------------------------------------------------------------*/
1130static int
1131ifx_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-----------------------------------------------------------------------------*/
1178static int
1179ifx_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
1204void 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 */
1236static int
1237ifx_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
1299static int
1300ifx_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
1338static int
1339ifx_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-----------------------------------------------------------------------------*/
1390static int
1391ifx_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 */
1407int
1408ifx_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 */
1636EXPORT_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
1673static int
1674ifx_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 */
1704static inline void
1705show_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 */
1719int __init
1720ifx_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
1875irqerr:
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*/
1883errout:
1884	/* free up any allocated memory in the error case */
1885	kfree(isp);
1886	return (ret_val);
1887} /* ifx_ssc_init */
1888
1889
1890void
1891ifx_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
1924module_exit(ifx_ssc_cleanup_module);
1925
1926/* Module entry-points */
1927module_init(ifx_ssc_init);
1928
1929#ifndef MODULE
1930static int __init
1931ifx_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 */
1942inline 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}
1951EXPORT_SYMBOL(amazon_ssc_cs_low);
1952/* Brief:	chip select disable
1953 */
1954inline 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}
1963EXPORT_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 */
1980static 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	}
2070ssc_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 */
2092int 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}
2096EXPORT_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 */
2104int amazon_ssc_tx(char * tx_buf, u32 tx_len)
2105{
2106	return ssc_session(tx_buf,tx_len,NULL,0);
2107}
2108EXPORT_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 */
2116int amazon_ssc_rx(char * rx_buf, u32 rx_len)
2117{
2118	return ssc_session(NULL,0,rx_buf,rx_len);
2119}
2120EXPORT_SYMBOL(amazon_ssc_rx);
2121
2122