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