0c2bf93a584db4b5c98815f21ad47409c9326310
[openwrt/openwrt.git] / target / linux / ifxmips / files / drivers / char / ifxmips_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/fcntl.h>
38 #include <linux/ptrace.h>
39 #include <linux/mm.h>
40 #include <linux/ioport.h>
41 #include <linux/init.h>
42 #include <linux/delay.h>
43 #include <linux/spinlock.h>
44 #include <linux/slab.h>
45
46 #include <asm/system.h>
47 #include <asm/io.h>
48 #include <asm/irq.h>
49 #include <asm/uaccess.h>
50 #include <asm/bitops.h>
51
52 #include <linux/types.h>
53 #include <linux/kernel.h>
54 #include <linux/version.h>
55
56 #include <asm/ifxmips/ifxmips.h>
57 #include <asm/ifxmips/ifxmips_irq.h>
58 #include <asm/ifxmips/ifx_ssc_defines.h>
59 #include <asm/ifxmips/ifx_ssc.h>
60
61 /* allow the user to set the major device number */
62 static int maj = 0;
63
64 /*
65 * This is the per-channel data structure containing pointers, flags
66 * and variables for the port. This driver supports a maximum of PORT_CNT.
67 * isp is allocated in ifx_ssc_init() based on the chip version.
68 */
69 static struct ifx_ssc_port *isp;
70
71 /* other forward declarations */
72 static unsigned int ifx_ssc_get_kernel_clk (struct ifx_ssc_port *info);
73 static void tx_int (struct ifx_ssc_port *);
74
75 extern unsigned int ifxmips_get_fpi_hz (void);
76 extern void mask_and_ack_ifxmips_irq (unsigned int irq_nr);
77
78 static inline unsigned int
79 ifx_ssc_get_kernel_clk (struct ifx_ssc_port *info)
80 {
81 unsigned int rmc;
82
83 rmc = (readl(IFXMIPS_SSC_CLC) & IFX_CLC_RUN_DIVIDER_MASK) >> IFX_CLC_RUN_DIVIDER_OFFSET;
84 if (rmc == 0)
85 {
86 printk ("ifx_ssc_get_kernel_clk rmc==0 \n");
87 return 0;
88 }
89 return ifxmips_get_fpi_hz () / rmc;
90 }
91
92 #ifndef not_yet
93 #ifdef IFX_SSC_INT_USE_BH
94 /*
95 * This routine is used by the interrupt handler to schedule
96 * processing in the software interrupt portion of the driver
97 * (also known as the "bottom half"). This can be called any
98 * number of times for any channel without harm.
99 */
100 static inline void
101 ifx_ssc_sched_event (struct ifx_ssc_port *info, int event)
102 {
103 info->event |= 1 << event; /* remember what kind of event and who */
104 queue_task (&info->tqueue, &tq_cyclades); /* it belongs to */
105 mark_bh (CYCLADES_BH); /* then trigger event */
106 }
107
108 static void
109 do_softint (void *private_)
110 {
111 struct ifx_ssc_port *info = (struct ifx_ssc_port *) private_;
112
113 if (test_and_clear_bit (Cy_EVENT_HANGUP, &info->event))
114 {
115 wake_up_interruptible (&info->open_wait);
116 info->flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CALLOUT_ACTIVE);
117 }
118
119 if (test_and_clear_bit (Cy_EVENT_OPEN_WAKEUP, &info->event))
120 wake_up_interruptible (&info->open_wait);
121
122 if (test_and_clear_bit (Cy_EVENT_DELTA_WAKEUP, &info->event))
123 wake_up_interruptible (&info->delta_msr_wait);
124
125 if (test_and_clear_bit (Cy_EVENT_WRITE_WAKEUP, &info->event))
126 wake_up_interruptible (&tty->write_wait);
127 #ifdef Z_WAKE
128 if (test_and_clear_bit (Cy_EVENT_SHUTDOWN_WAKEUP, &info->event))
129 wake_up_interruptible (&info->shutdown_wait);
130 #endif
131 }
132 #endif
133 #endif
134
135 inline static void
136 rx_int (struct ifx_ssc_port *info)
137 {
138 int fifo_fill_lev, bytes_in_buf, i;
139 unsigned long tmp_val;
140 unsigned long *tmp_ptr;
141 unsigned int rx_valid_cnt;
142 /* number of words waiting in the RX FIFO */
143 fifo_fill_lev = (readl(IFXMIPS_SSC_FSTAT) & IFX_SSC_FSTAT_RECEIVED_WORDS_MASK) >> IFX_SSC_FSTAT_RECEIVED_WORDS_OFFSET;
144 bytes_in_buf = info->rxbuf_end - info->rxbuf_ptr;
145 // transfer with 32 bits per entry
146 while ((bytes_in_buf >= 4) && (fifo_fill_lev > 0)) {
147 tmp_ptr = (unsigned long *) info->rxbuf_ptr;
148 *tmp_ptr = readl(IFXMIPS_SSC_RB);
149 info->rxbuf_ptr += 4;
150 info->stats.rxBytes += 4;
151 fifo_fill_lev--;
152 bytes_in_buf -= 4;
153 }
154
155 // now do the rest as mentioned in STATE.RXBV
156 while ((bytes_in_buf > 0) && (fifo_fill_lev > 0)) {
157 rx_valid_cnt = (readl(IFXMIPS_SSC_STATE) & IFX_SSC_STATE_RX_BYTE_VALID_MASK) >> IFX_SSC_STATE_RX_BYTE_VALID_OFFSET;
158 if (rx_valid_cnt == 0)
159 break;
160
161 if (rx_valid_cnt > bytes_in_buf)
162 rx_valid_cnt = bytes_in_buf;
163
164 tmp_val = readl(IFXMIPS_SSC_RB);
165
166 for (i = 0; i < rx_valid_cnt; i++)
167 {
168 *info->rxbuf_ptr = (tmp_val >> (8 * (rx_valid_cnt - i - 1))) & 0xff;
169 bytes_in_buf--;
170 info->rxbuf_ptr++;
171 }
172 info->stats.rxBytes += rx_valid_cnt;
173 }
174
175 // check if transfer is complete
176 if (info->rxbuf_ptr >= info->rxbuf_end)
177 {
178 disable_irq(IFXMIPS_SSC_RIR);
179 wake_up_interruptible (&info->rwait);
180 } else if ((info->opts.modeRxTx == IFX_SSC_MODE_RX) && (readl(IFXMIPS_SSC_RXCNT) == 0))
181 {
182 if (info->rxbuf_end - info->rxbuf_ptr < IFX_SSC_RXREQ_BLOCK_SIZE)
183 writel((info->rxbuf_end - info->rxbuf_ptr) << IFX_SSC_RXREQ_RXCOUNT_OFFSET, IFXMIPS_SSC_RXREQ);
184 else
185 writel(IFX_SSC_RXREQ_BLOCK_SIZE << IFX_SSC_RXREQ_RXCOUNT_OFFSET, IFXMIPS_SSC_RXREQ);
186 }
187 }
188
189 inline static void
190 tx_int (struct ifx_ssc_port *info)
191 {
192
193 int fifo_space, fill, i;
194 fifo_space = ((readl(IFXMIPS_SSC_ID) & IFX_SSC_PERID_TXFS_MASK) >> IFX_SSC_PERID_TXFS_OFFSET)
195 - ((readl(IFXMIPS_SSC_FSTAT) & IFX_SSC_FSTAT_TRANSMIT_WORDS_MASK) >> IFX_SSC_FSTAT_TRANSMIT_WORDS_OFFSET);
196
197 if (fifo_space == 0)
198 return;
199
200 fill = info->txbuf_end - info->txbuf_ptr;
201
202 if (fill > fifo_space * 4)
203 fill = fifo_space * 4;
204
205 for (i = 0; i < fill / 4; i++)
206 {
207 // at first 32 bit access
208 writel(*(UINT32 *) info->txbuf_ptr, IFXMIPS_SSC_TB);
209 info->txbuf_ptr += 4;
210 }
211
212 fifo_space -= fill / 4;
213 info->stats.txBytes += fill & ~0x3;
214 fill &= 0x3;
215 if ((fifo_space > 0) & (fill > 1))
216 {
217 // trailing 16 bit access
218 WRITE_PERIPHERAL_REGISTER_16 (*(UINT16 *) info->txbuf_ptr, info->mapbase + IFX_SSC_TB);
219 info->txbuf_ptr += 2;
220 info->stats.txBytes += 2;
221 fifo_space--;
222 fill -= 2;
223 }
224
225 if ((fifo_space > 0) & (fill > 0))
226 {
227 // trailing 8 bit access
228 WRITE_PERIPHERAL_REGISTER_8 (*(UINT8 *) info->txbuf_ptr, info->mapbase + IFX_SSC_TB);
229 info->txbuf_ptr++;
230 info->stats.txBytes++;
231 }
232
233 // check if transmission complete
234 if (info->txbuf_ptr >= info->txbuf_end)
235 {
236 disable_irq(IFXMIPS_SSC_TIR);
237 kfree (info->txbuf);
238 info->txbuf = NULL;
239 }
240
241 }
242
243 irqreturn_t
244 ifx_ssc_rx_int (int irq, void *dev_id)
245 {
246 struct ifx_ssc_port *info = (struct ifx_ssc_port *) dev_id;
247 rx_int (info);
248
249 return IRQ_HANDLED;
250 }
251
252 irqreturn_t
253 ifx_ssc_tx_int (int irq, void *dev_id)
254 {
255 struct ifx_ssc_port *info = (struct ifx_ssc_port *) dev_id;
256 tx_int (info);
257
258 return IRQ_HANDLED;
259 }
260
261 irqreturn_t
262 ifx_ssc_err_int (int irq, void *dev_id)
263 {
264 struct ifx_ssc_port *info = (struct ifx_ssc_port *) dev_id;
265 unsigned int state;
266 unsigned int write_back = 0;
267 unsigned long flags;
268
269 local_irq_save (flags);
270 state = readl(IFXMIPS_SSC_STATE);
271
272 if ((state & IFX_SSC_STATE_RX_UFL) != 0) {
273 info->stats.rxUnErr++;
274 write_back |= IFX_SSC_WHBSTATE_CLR_RX_UFL_ERROR;
275 }
276
277 if ((state & IFX_SSC_STATE_RX_OFL) != 0) {
278 info->stats.rxOvErr++;
279 write_back |= IFX_SSC_WHBSTATE_CLR_RX_OFL_ERROR;
280 }
281
282 if ((state & IFX_SSC_STATE_TX_OFL) != 0) {
283 info->stats.txOvErr++;
284 write_back |= IFX_SSC_WHBSTATE_CLR_TX_OFL_ERROR;
285 }
286
287 if ((state & IFX_SSC_STATE_TX_UFL) != 0) {
288 info->stats.txUnErr++;
289 write_back |= IFX_SSC_WHBSTATE_CLR_TX_UFL_ERROR;
290 }
291
292 if ((state & IFX_SSC_STATE_MODE_ERR) != 0) {
293 info->stats.modeErr++;
294 write_back |= IFX_SSC_WHBSTATE_CLR_MODE_ERROR;
295 }
296
297 if (write_back)
298 writel(write_back, IFXMIPS_SSC_WHBSTATE);
299
300 local_irq_restore (flags);
301
302 return IRQ_HANDLED;
303 }
304
305 static void
306 ifx_ssc_abort (struct ifx_ssc_port *info)
307 {
308 unsigned long flags;
309 bool enabled;
310
311 local_irq_save (flags);
312
313 disable_irq(IFXMIPS_SSC_RIR);
314 disable_irq(IFXMIPS_SSC_TIR);
315 disable_irq(IFXMIPS_SSC_EIR);
316
317 local_irq_restore (flags);
318
319 // disable SSC (also aborts a receive request!)
320 // ### TO DO: Perhaps it's better to abort after the receiption of a
321 // complete word. The disable cuts the transmission immediatly and
322 // releases the chip selects. This could result in unpredictable
323 // behavior of connected external devices!
324 enabled = (readl(IFXMIPS_SSC_STATE) & IFX_SSC_STATE_IS_ENABLED) != 0;
325 writel(IFX_SSC_WHBSTATE_CLR_ENABLE, IFXMIPS_SSC_WHBSTATE);
326
327 // flush fifos
328 writel(IFX_SSC_XFCON_FIFO_FLUSH, IFXMIPS_SSC_TXFCON);
329 writel(IFX_SSC_XFCON_FIFO_FLUSH, IFXMIPS_SSC_RXFCON);
330
331 // free txbuf
332 if (info->txbuf != NULL)
333 {
334 kfree (info->txbuf);
335 info->txbuf = NULL;
336 }
337
338 // wakeup read process
339 if (info->rxbuf != NULL)
340 wake_up_interruptible (&info->rwait);
341
342 // clear pending int's
343 mask_and_ack_ifxmips_irq(IFXMIPS_SSC_RIR);
344 mask_and_ack_ifxmips_irq(IFXMIPS_SSC_TIR);
345 mask_and_ack_ifxmips_irq(IFXMIPS_SSC_EIR);
346
347 // clear error flags
348 writel(IFX_SSC_WHBSTATE_CLR_ALL_ERROR, IFXMIPS_SSC_WHBSTATE);
349
350 if (enabled)
351 writel(IFX_SSC_WHBSTATE_SET_ENABLE, IFXMIPS_SSC_WHBSTATE);
352
353 }
354
355 /*
356 * This routine is called whenever a port is opened. It enforces
357 * exclusive opening of a port and enables interrupts, etc.
358 */
359 int
360 ifx_ssc_open (struct inode *inode, struct file *filp)
361 {
362 struct ifx_ssc_port *info;
363 int line;
364 int from_kernel = 0;
365
366 if ((inode == (struct inode *) 0) || (inode == (struct inode *) 1)) {
367 from_kernel = 1;
368 line = (int) inode;
369 } else {
370 line = MINOR (filp->f_dentry->d_inode->i_rdev);
371 }
372
373 /* don't open more minor devices than we can support */
374 if (line < 0 || line >= PORT_CNT)
375 return -ENXIO;
376
377 info = &isp[line];
378
379 /* exclusive open */
380 if (info->port_is_open != 0)
381 return -EBUSY;
382 info->port_is_open++;
383
384 disable_irq(IFXMIPS_SSC_RIR);
385 disable_irq(IFXMIPS_SSC_TIR);
386 disable_irq(IFXMIPS_SSC_EIR);
387
388 /* Flush and enable TX/RX FIFO */
389 writel((IFX_SSC_DEF_TXFIFO_FL << IFX_SSC_XFCON_ITL_OFFSET) | IFX_SSC_XFCON_FIFO_FLUSH | IFX_SSC_XFCON_FIFO_ENABLE, IFXMIPS_SSC_TXFCON);
390 writel((IFX_SSC_DEF_RXFIFO_FL << IFX_SSC_XFCON_ITL_OFFSET) | IFX_SSC_XFCON_FIFO_FLUSH | IFX_SSC_XFCON_FIFO_ENABLE, IFXMIPS_SSC_RXFCON);
391
392 /* logically flush the software FIFOs */
393 info->rxbuf_ptr = 0;
394 info->txbuf_ptr = 0;
395
396 /* clear all error bits */
397 writel(IFX_SSC_WHBSTATE_CLR_ALL_ERROR, IFXMIPS_SSC_WHBSTATE);
398
399 // clear pending interrupts
400 mask_and_ack_ifxmips_irq(IFXMIPS_SSC_RIR);
401 mask_and_ack_ifxmips_irq(IFXMIPS_SSC_TIR);
402 mask_and_ack_ifxmips_irq(IFXMIPS_SSC_EIR);
403
404 writel(IFX_SSC_WHBSTATE_SET_ENABLE, IFXMIPS_SSC_WHBSTATE);
405
406 return 0;
407 }
408 EXPORT_SYMBOL(ifx_ssc_open);
409
410 int
411 ifx_ssc_close (struct inode *inode, struct file *filp)
412 {
413 struct ifx_ssc_port *info;
414 int idx;
415
416 if ((inode == (struct inode *) 0) || (inode == (struct inode *) 1))
417 idx = (int) inode;
418 else
419 idx = MINOR (filp->f_dentry->d_inode->i_rdev);
420
421 if (idx < 0 || idx >= PORT_CNT)
422 return -ENXIO;
423
424 info = &isp[idx];
425 if (!info)
426 return -ENXIO;
427
428 writel(IFX_SSC_WHBSTATE_CLR_ENABLE, IFXMIPS_SSC_WHBSTATE);
429
430 ifx_ssc_abort(info);
431
432 info->port_is_open--;
433
434 return 0;
435 }
436 EXPORT_SYMBOL(ifx_ssc_close);
437
438 static ssize_t
439 ifx_ssc_read_helper_poll (struct ifx_ssc_port *info, char *buf, size_t len, int from_kernel)
440 {
441 ssize_t ret_val;
442 unsigned long flags;
443
444 if (info->opts.modeRxTx == IFX_SSC_MODE_TX)
445 return -EFAULT;
446 local_irq_save (flags);
447 info->rxbuf_ptr = info->rxbuf;
448 info->rxbuf_end = info->rxbuf + len;
449 local_irq_restore (flags);
450 /* Vinetic driver always works in IFX_SSC_MODE_RXTX */
451 /* TXRX in poll mode */
452 while (info->rxbuf_ptr < info->rxbuf_end)
453 {
454 if (info->txbuf_ptr < info->txbuf_end)
455 tx_int (info);
456
457 rx_int (info);
458 };
459
460 ret_val = info->rxbuf_ptr - info->rxbuf;
461
462 return ret_val;
463 }
464
465 static ssize_t
466 ifx_ssc_read_helper (struct ifx_ssc_port *info, char *buf, size_t len, int from_kernel)
467 {
468 ssize_t ret_val;
469 unsigned long flags;
470 DECLARE_WAITQUEUE (wait, current);
471
472 if (info->opts.modeRxTx == IFX_SSC_MODE_TX)
473 return -EFAULT;
474
475 local_irq_save (flags);
476 info->rxbuf_ptr = info->rxbuf;
477 info->rxbuf_end = info->rxbuf + len;
478
479 if (info->opts.modeRxTx == IFX_SSC_MODE_RXTX)
480 {
481 if ((info->txbuf == NULL) || (info->txbuf != info->txbuf_ptr) || (info->txbuf_end != len + info->txbuf))
482 {
483 local_irq_restore (flags);
484 printk ("IFX SSC - %s: write must be called before calling " "read in combined RX/TX!\n", __func__);
485 return -EFAULT;
486 }
487
488 local_irq_restore(flags);
489 tx_int (info);
490
491 if (info->txbuf_ptr < info->txbuf_end)
492 enable_irq(IFXMIPS_SSC_TIR);
493
494 enable_irq(IFXMIPS_SSC_RIR);
495 } else {
496 local_irq_restore(flags);
497 if (readl(IFXMIPS_SSC_RXCNT) & IFX_SSC_RXCNT_TODO_MASK)
498 return -EBUSY;
499 enable_irq(IFXMIPS_SSC_RIR);
500 if (len < IFX_SSC_RXREQ_BLOCK_SIZE)
501 writel(len << IFX_SSC_RXREQ_RXCOUNT_OFFSET, IFXMIPS_SSC_RXREQ);
502 else
503 writel(IFX_SSC_RXREQ_BLOCK_SIZE << IFX_SSC_RXREQ_RXCOUNT_OFFSET, IFXMIPS_SSC_RXREQ);
504 }
505
506 __add_wait_queue (&info->rwait, &wait);
507 set_current_state (TASK_INTERRUPTIBLE);
508
509 do {
510 local_irq_save (flags);
511 if (info->rxbuf_ptr >= info->rxbuf_end)
512 break;
513
514 local_irq_restore (flags);
515
516 if (signal_pending (current))
517 {
518 ret_val = -ERESTARTSYS;
519 goto out;
520 }
521 schedule();
522 } while (1);
523
524 ret_val = info->rxbuf_ptr - info->rxbuf;
525 local_irq_restore (flags);
526
527 out:
528 current->state = TASK_RUNNING;
529 __remove_wait_queue (&info->rwait, &wait);
530
531 return (ret_val);
532 }
533
534 static ssize_t
535 ifx_ssc_write_helper (struct ifx_ssc_port *info, const char *buf,
536 size_t len, int from_kernel)
537 {
538 if (info->opts.modeRxTx == IFX_SSC_MODE_RX)
539 return -EFAULT;
540
541 info->txbuf_ptr = info->txbuf;
542 info->txbuf_end = len + info->txbuf;
543 if (info->opts.modeRxTx == IFX_SSC_MODE_TX)
544 {
545 tx_int (info);
546 if (info->txbuf_ptr < info->txbuf_end)
547 {
548 enable_irq(IFXMIPS_SSC_TIR);
549 }
550 }
551
552 return len;
553 }
554
555 ssize_t
556 ifx_ssc_kread (int port, char *kbuf, size_t len)
557 {
558 struct ifx_ssc_port *info;
559 ssize_t ret_val;
560
561 if (port < 0 || port >= PORT_CNT)
562 return -ENXIO;
563
564 if (len == 0)
565 return 0;
566
567 info = &isp[port];
568
569 if (info->rxbuf != NULL)
570 {
571 printk ("SSC device busy\n");
572 return -EBUSY;
573 }
574
575 info->rxbuf = kbuf;
576 if (info->rxbuf == NULL)
577 {
578 printk ("SSC device error\n");
579 return -EINVAL;
580 }
581
582 ret_val = ifx_ssc_read_helper_poll (info, kbuf, len, 1);
583 info->rxbuf = NULL;
584
585 disable_irq(IFXMIPS_SSC_RIR);
586
587 return ret_val;
588 }
589 EXPORT_SYMBOL(ifx_ssc_kread);
590
591 ssize_t
592 ifx_ssc_kwrite (int port, const char *kbuf, size_t len)
593 {
594 struct ifx_ssc_port *info;
595 ssize_t ret_val;
596
597 if (port < 0 || port >= PORT_CNT)
598 return -ENXIO;
599
600 if (len == 0)
601 return 0;
602
603 info = &isp[port];
604
605 // check if transmission in progress
606 if (info->txbuf != NULL)
607 return -EBUSY;
608
609 info->txbuf = (char *) kbuf;
610
611 ret_val = ifx_ssc_write_helper (info, info->txbuf, len, 1);
612
613 if (ret_val < 0)
614 info->txbuf = NULL;
615
616 return ret_val;
617 }
618 EXPORT_SYMBOL(ifx_ssc_kwrite);
619
620 static ssize_t
621 ifx_ssc_read (struct file *filp, char *ubuf, size_t len, loff_t * off)
622 {
623 ssize_t ret_val;
624 int idx;
625 struct ifx_ssc_port *info;
626
627 idx = MINOR (filp->f_dentry->d_inode->i_rdev);
628 info = &isp[idx];
629
630 if (info->rxbuf != NULL)
631 return -EBUSY;
632
633 info->rxbuf = kmalloc (len + 3, GFP_KERNEL);
634 if (info->rxbuf == NULL)
635 return -ENOMEM;
636
637 ret_val = ifx_ssc_read_helper (info, info->rxbuf, len, 0);
638 if (copy_to_user ((void *) ubuf, info->rxbuf, ret_val) != 0)
639 ret_val = -EFAULT;
640
641 disable_irq(IFXMIPS_SSC_RIR);
642
643 kfree (info->rxbuf);
644 info->rxbuf = NULL;
645
646 return (ret_val);
647 }
648
649 static ssize_t
650 ifx_ssc_write (struct file *filp, const char *ubuf, size_t len, loff_t * off)
651 {
652 int idx;
653 struct ifx_ssc_port *info;
654 int ret_val;
655
656 if (len == 0)
657 return (0);
658
659 idx = MINOR (filp->f_dentry->d_inode->i_rdev);
660 info = &isp[idx];
661
662 if (info->txbuf != NULL)
663 return -EBUSY;
664
665 info->txbuf = kmalloc (len + 3, GFP_KERNEL);
666 if (info->txbuf == NULL)
667 return -ENOMEM;
668
669 ret_val = copy_from_user (info->txbuf, ubuf, len);
670 if (ret_val == 0)
671 ret_val = ifx_ssc_write_helper (info, info->txbuf, len, 0);
672 else
673 ret_val = -EFAULT;
674
675 if (ret_val < 0)
676 {
677 kfree (info->txbuf);
678 info->txbuf = NULL;
679 }
680
681 return (ret_val);
682 }
683
684 static struct ifx_ssc_frm_status *
685 ifx_ssc_frm_status_get (struct ifx_ssc_port *info)
686 {
687 unsigned long tmp;
688
689 tmp = readl(IFXMIPS_SSC_SFSTAT);
690 info->frm_status.DataBusy = (tmp & IFX_SSC_SFSTAT_IN_DATA) > 0;
691 info->frm_status.PauseBusy = (tmp & IFX_SSC_SFSTAT_IN_PAUSE) > 0;
692 info->frm_status.DataCount = (tmp & IFX_SSC_SFSTAT_DATA_COUNT_MASK) >> IFX_SSC_SFSTAT_DATA_COUNT_OFFSET;
693 info->frm_status.PauseCount = (tmp & IFX_SSC_SFSTAT_PAUSE_COUNT_MASK) >> IFX_SSC_SFSTAT_PAUSE_COUNT_OFFSET;
694 tmp = readl(IFXMIPS_SSC_SFCON);
695 info->frm_status.EnIntAfterData = (tmp & IFX_SSC_SFCON_FIR_ENABLE_BEFORE_PAUSE) > 0;
696 info->frm_status.EnIntAfterPause = (tmp & IFX_SSC_SFCON_FIR_ENABLE_AFTER_PAUSE) > 0;
697
698 return &info->frm_status;
699 }
700
701
702 static struct ifx_ssc_frm_opts *
703 ifx_ssc_frm_control_get (struct ifx_ssc_port *info)
704 {
705 unsigned long tmp;
706
707 tmp = readl(IFXMIPS_SSC_SFCON);
708 info->frm_opts.FrameEnable = (tmp & IFX_SSC_SFCON_SF_ENABLE) > 0;
709 info->frm_opts.DataLength = (tmp & IFX_SSC_SFCON_DATA_LENGTH_MASK) >> IFX_SSC_SFCON_DATA_LENGTH_OFFSET;
710 info->frm_opts.PauseLength = (tmp & IFX_SSC_SFCON_PAUSE_LENGTH_MASK) >> IFX_SSC_SFCON_PAUSE_LENGTH_OFFSET;
711 info->frm_opts.IdleData = (tmp & IFX_SSC_SFCON_PAUSE_DATA_MASK) >> IFX_SSC_SFCON_PAUSE_DATA_OFFSET;
712 info->frm_opts.IdleClock = (tmp & IFX_SSC_SFCON_PAUSE_CLOCK_MASK) >> IFX_SSC_SFCON_PAUSE_CLOCK_OFFSET;
713 info->frm_opts.StopAfterPause = (tmp & IFX_SSC_SFCON_STOP_AFTER_PAUSE) > 0;
714
715 return &info->frm_opts;
716 }
717
718 static int
719 ifx_ssc_frm_control_set (struct ifx_ssc_port *info)
720 {
721 unsigned long tmp;
722
723 // check parameters
724 if ((info->frm_opts.DataLength > IFX_SSC_SFCON_DATA_LENGTH_MAX)
725 || (info->frm_opts.DataLength < 1)
726 || (info->frm_opts.PauseLength > IFX_SSC_SFCON_PAUSE_LENGTH_MAX)
727 || (info->frm_opts.PauseLength < 1)
728 || (info->frm_opts.IdleData & ~(IFX_SSC_SFCON_PAUSE_DATA_MASK >> IFX_SSC_SFCON_PAUSE_DATA_OFFSET))
729 || (info->frm_opts.IdleClock & ~(IFX_SSC_SFCON_PAUSE_CLOCK_MASK >> IFX_SSC_SFCON_PAUSE_CLOCK_OFFSET)))
730 return -EINVAL;
731
732 // read interrupt bits (they're not changed here)
733 tmp = readl(IFXMIPS_SSC_SFCON) &
734 (IFX_SSC_SFCON_FIR_ENABLE_BEFORE_PAUSE | IFX_SSC_SFCON_FIR_ENABLE_AFTER_PAUSE);
735
736 // set all values with respect to it's bit position (for data and pause
737 // length set N-1)
738 tmp = (info->frm_opts.DataLength - 1) << IFX_SSC_SFCON_DATA_LENGTH_OFFSET;
739 tmp |= (info->frm_opts.PauseLength - 1) << IFX_SSC_SFCON_PAUSE_LENGTH_OFFSET;
740 tmp |= info->frm_opts.IdleData << IFX_SSC_SFCON_PAUSE_DATA_OFFSET;
741 tmp |= info->frm_opts.IdleClock << IFX_SSC_SFCON_PAUSE_CLOCK_OFFSET;
742 tmp |= info->frm_opts.FrameEnable * IFX_SSC_SFCON_SF_ENABLE;
743 tmp |= info->frm_opts.StopAfterPause * IFX_SSC_SFCON_STOP_AFTER_PAUSE;
744
745 writel(tmp, IFXMIPS_SSC_SFCON);
746
747 return 0;
748 }
749
750 static int
751 ifx_ssc_rxtx_mode_set (struct ifx_ssc_port *info, unsigned int val)
752 {
753 unsigned long tmp;
754
755 if (!(info) || (val & ~(IFX_SSC_MODE_MASK)))
756 return -EINVAL;
757
758 if ((readl(IFXMIPS_SSC_STATE) & IFX_SSC_STATE_BUSY)
759 || (readl(IFXMIPS_SSC_RXCNT) & IFX_SSC_RXCNT_TODO_MASK))
760 return -EBUSY;
761
762 tmp = (readl(IFXMIPS_SSC_CON) & ~(IFX_SSC_CON_RX_OFF | IFX_SSC_CON_TX_OFF)) | (val);
763 writel(tmp, IFXMIPS_SSC_SFCON);
764 info->opts.modeRxTx = val;
765
766 return 0;
767 }
768
769 static int
770 ifx_ssc_sethwopts (struct ifx_ssc_port *info)
771 {
772 unsigned long flags, bits;
773 struct ifx_ssc_hwopts *opts = &info->opts;
774
775 if ((opts->dataWidth < IFX_SSC_MIN_DATA_WIDTH)
776 || (opts->dataWidth > IFX_SSC_MAX_DATA_WIDTH))
777 return -EINVAL;
778
779 bits = (opts->dataWidth - 1) << IFX_SSC_CON_DATA_WIDTH_OFFSET;
780 bits |= IFX_SSC_CON_ENABLE_BYTE_VALID;
781
782 if (opts->rxOvErrDetect)
783 bits |= IFX_SSC_CON_RX_OFL_CHECK;
784 if (opts->rxUndErrDetect)
785 bits |= IFX_SSC_CON_RX_UFL_CHECK;
786 if (opts->txOvErrDetect)
787 bits |= IFX_SSC_CON_TX_OFL_CHECK;
788 if (opts->txUndErrDetect)
789 bits |= IFX_SSC_CON_TX_UFL_CHECK;
790 if (opts->loopBack)
791 bits |= IFX_SSC_CON_LOOPBACK_MODE;
792 if (opts->echoMode)
793 bits |= IFX_SSC_CON_ECHO_MODE_ON;
794 if (opts->headingControl)
795 bits |= IFX_SSC_CON_MSB_FIRST;
796 if (opts->clockPhase)
797 bits |= IFX_SSC_CON_LATCH_THEN_SHIFT;
798 if (opts->clockPolarity)
799 bits |= IFX_SSC_CON_CLOCK_FALL;
800
801 switch (opts->modeRxTx)
802 {
803 case IFX_SSC_MODE_TX:
804 bits |= IFX_SSC_CON_RX_OFF;
805 break;
806 case IFX_SSC_MODE_RX:
807 bits |= IFX_SSC_CON_TX_OFF;
808 break;
809 }
810
811 local_irq_save (flags);
812
813 writel(bits, IFXMIPS_SSC_CON);
814 writel((info->opts.gpoCs << IFX_SSC_GPOCON_ISCSB0_POS) |
815 (info->opts.gpoInv << IFX_SSC_GPOCON_INVOUT0_POS), IFXMIPS_SSC_GPOCON);
816
817 writel(info->opts.gpoCs << IFX_SSC_WHBGPOSTAT_SETOUT0_POS, IFXMIPS_SSC_WHBGPOSTAT);
818
819 //master mode
820 if (opts->masterSelect)
821 writel(IFX_SSC_WHBSTATE_SET_MASTER_SELECT, IFXMIPS_SSC_WHBSTATE);
822 else
823 writel(IFX_SSC_WHBSTATE_CLR_MASTER_SELECT, IFXMIPS_SSC_WHBSTATE);
824
825 // init serial framing
826 writel(0, IFXMIPS_SSC_SFCON);
827 /* set up the port pins */
828 //check for general requirements to switch (external) pad/pin characteristics
829 /* TODO: P0.9 SPI_CS4, P0.10 SPI_CS5, P 0.11 SPI_CS6, because of ASC0 */
830 /* p0.15 SPI_CS1(EEPROM), P0.13 SPI_CS3, */
831 /* Set p0.15 to alternative 01, others to 00 (In/OUT) */
832 *(IFXMIPS_GPIO_P0_DIR) = (*IFXMIPS_GPIO_P0_DIR) | (0xA000);
833 *(IFXMIPS_GPIO_P0_ALTSEL0) = (((*IFXMIPS_GPIO_P0_ALTSEL0) | (0x8000)) & (~(0x2000)));
834 *(IFXMIPS_GPIO_P0_ALTSEL1) = (((*IFXMIPS_GPIO_P0_ALTSEL1) & (~0x8000)) & (~(0x2000)));
835 *(IFXMIPS_GPIO_P0_OD) = (*IFXMIPS_GPIO_P0_OD) | 0xA000;
836
837 /* p1.6 SPI_CS2(SFLASH), p1.0 SPI_DIN, p1.1 SPI_DOUT, p1.2 SPI_CLK */
838 *(IFXMIPS_GPIO_P1_DIR) = ((*IFXMIPS_GPIO_P1_DIR) | (0x46)) & (~1);
839 *(IFXMIPS_GPIO_P1_ALTSEL0) = ((*IFXMIPS_GPIO_P1_ALTSEL0) | (0x47));
840 *(IFXMIPS_GPIO_P1_ALTSEL1) = (*IFXMIPS_GPIO_P1_ALTSEL1) & (~0x47);
841 *(IFXMIPS_GPIO_P1_OD) = (*IFXMIPS_GPIO_P1_OD) | 0x0046;
842
843 /*CS3 */
844 /*TODO: CS4 CS5 CS6 */
845 *IFXMIPS_GPIO_P0_OUT = ((*IFXMIPS_GPIO_P0_OUT) | 0x2000);
846
847 local_irq_restore (flags);
848
849 return 0;
850 }
851
852 static int
853 ifx_ssc_set_baud (struct ifx_ssc_port *info, unsigned int baud)
854 {
855 unsigned int ifx_ssc_clock;
856 unsigned int br;
857 unsigned long flags;
858 bool enabled;
859 int retval = 0;
860
861 ifx_ssc_clock = ifx_ssc_get_kernel_clk(info);
862 if (ifx_ssc_clock == 0)
863 {
864 retval = -EINVAL;
865 goto out;
866 }
867
868 local_irq_save (flags);
869
870 enabled = (readl(IFXMIPS_SSC_STATE) & IFX_SSC_STATE_IS_ENABLED);
871 writel(IFX_SSC_WHBSTATE_CLR_ENABLE, IFXMIPS_SSC_WHBSTATE);
872
873 br = (((ifx_ssc_clock >> 1) + baud / 2) / baud) - 1;
874 wmb();
875
876 if (br > 0xffff || ((br == 0) &&
877 ((readl(IFXMIPS_SSC_STATE) & IFX_SSC_STATE_IS_MASTER) == 0))) {
878 local_irq_restore (flags);
879 printk ("%s: invalid baudrate %u\n", __func__, baud);
880 return -EINVAL;
881 }
882
883 writel(br, IFXMIPS_SSC_BR);
884
885 if (enabled)
886 writel(IFX_SSC_WHBSTATE_SET_ENABLE, IFXMIPS_SSC_WHBSTATE);
887
888 local_irq_restore(flags);
889
890 out:
891 return retval;
892 }
893
894 static int
895 ifx_ssc_hwinit (struct ifx_ssc_port *info)
896 {
897 unsigned long flags;
898 bool enabled;
899
900 enabled = (readl(IFXMIPS_SSC_STATE) & IFX_SSC_STATE_IS_ENABLED);
901 writel(IFX_SSC_WHBSTATE_CLR_ENABLE, IFXMIPS_SSC_WHBSTATE);
902
903 if (ifx_ssc_sethwopts (info) < 0)
904 {
905 printk ("%s: setting the hardware options failed\n", __func__);
906 return -EINVAL;
907 }
908
909 if (ifx_ssc_set_baud (info, info->baud) < 0)
910 {
911 printk ("%s: setting the baud rate failed\n", __func__);
912 return -EINVAL;
913 }
914
915 local_irq_save (flags);
916
917 /* TX FIFO */
918 writel((IFX_SSC_DEF_TXFIFO_FL << IFX_SSC_XFCON_ITL_OFFSET) | IFX_SSC_XFCON_FIFO_ENABLE, IFXMIPS_SSC_TXFCON);
919 /* RX FIFO */
920 writel((IFX_SSC_DEF_RXFIFO_FL << IFX_SSC_XFCON_ITL_OFFSET) | IFX_SSC_XFCON_FIFO_ENABLE, IFXMIPS_SSC_RXFCON);
921
922 local_irq_restore (flags);
923
924 if (enabled)
925 writel(IFX_SSC_WHBSTATE_SET_ENABLE, IFXMIPS_SSC_WHBSTATE);
926
927 return 0;
928 }
929
930 int
931 ifx_ssc_ioctl (struct inode *inode, struct file *filp, unsigned int cmd, unsigned long data)
932 {
933 struct ifx_ssc_port *info;
934 int line, ret_val = 0;
935 unsigned long flags;
936 unsigned long tmp;
937 int from_kernel = 0;
938
939 if ((inode == (struct inode *) 0) || (inode == (struct inode *) 1))
940 {
941 from_kernel = 1;
942 line = (int) inode;
943 } else {
944 line = MINOR (filp->f_dentry->d_inode->i_rdev);
945 }
946
947 if (line < 0 || line >= PORT_CNT)
948 return -ENXIO;
949
950 info = &isp[line];
951
952 switch (cmd)
953 {
954 case IFX_SSC_STATS_READ:
955 /* data must be a pointer to a struct ifx_ssc_statistics */
956 if (from_kernel)
957 memcpy ((void *) data, (void *) &info->stats,
958 sizeof (struct ifx_ssc_statistics));
959 else if (copy_to_user ((void *) data,
960 (void *) &info->stats,
961 sizeof (struct ifx_ssc_statistics)))
962 ret_val = -EFAULT;
963 break;
964 case IFX_SSC_STATS_RESET:
965 /* just resets the statistics counters */
966 memset ((void *) &info->stats, 0,
967 sizeof (struct ifx_ssc_statistics));
968 break;
969 case IFX_SSC_BAUD_SET:
970 /* if the buffers are not empty then the port is */
971 /* busy and we shouldn't change things on-the-fly! */
972 if (!info->txbuf || !info->rxbuf ||
973 (readl(IFXMIPS_SSC_STATE) & IFX_SSC_STATE_BUSY)) {
974 ret_val = -EBUSY;
975 break;
976 }
977 /* misuse flags */
978 if (from_kernel)
979 flags = *((unsigned long *) data);
980 else if (copy_from_user ((void *) &flags,
981 (void *) data, sizeof (flags))) {
982 ret_val = -EFAULT;
983 break;
984 }
985 if (flags == 0) {
986 ret_val = -EINVAL;
987 break;
988 }
989 if (ifx_ssc_set_baud (info, flags) < 0) {
990 ret_val = -EINVAL;
991 break;
992 }
993 info->baud = flags;
994 break;
995 case IFX_SSC_BAUD_GET:
996 if (from_kernel)
997 *((unsigned int *) data) = info->baud;
998 else if (copy_to_user ((void *) data,
999 (void *) &info->baud,
1000 sizeof (unsigned long)))
1001 ret_val = -EFAULT;
1002 break;
1003 case IFX_SSC_RXTX_MODE_SET:
1004 if (from_kernel)
1005 tmp = *((unsigned long *) data);
1006 else if (copy_from_user ((void *) &tmp,
1007 (void *) data, sizeof (tmp))) {
1008 ret_val = -EFAULT;
1009 break;
1010 }
1011 ret_val = ifx_ssc_rxtx_mode_set (info, tmp);
1012 break;
1013 case IFX_SSC_RXTX_MODE_GET:
1014 tmp = readl(IFXMIPS_SSC_CON) &
1015 (~(IFX_SSC_CON_RX_OFF | IFX_SSC_CON_TX_OFF));
1016 if (from_kernel)
1017 *((unsigned int *) data) = tmp;
1018 else if (copy_to_user ((void *) data,
1019 (void *) &tmp, sizeof (tmp)))
1020 ret_val = -EFAULT;
1021 break;
1022
1023 case IFX_SSC_ABORT:
1024 ifx_ssc_abort (info);
1025 break;
1026
1027 case IFX_SSC_GPO_OUT_SET:
1028 if (from_kernel)
1029 tmp = *((unsigned long *) data);
1030 else if (copy_from_user ((void *) &tmp,
1031 (void *) data, sizeof (tmp))) {
1032 ret_val = -EFAULT;
1033 break;
1034 }
1035 if (tmp > IFX_SSC_MAX_GPO_OUT)
1036 ret_val = -EINVAL;
1037 else
1038 writel(1 << (tmp + IFX_SSC_WHBGPOSTAT_SETOUT0_POS),
1039 IFXMIPS_SSC_WHBGPOSTAT);
1040 break;
1041 case IFX_SSC_GPO_OUT_CLR:
1042 if (from_kernel)
1043 tmp = *((unsigned long *) data);
1044 else if (copy_from_user ((void *) &tmp, (void *) data, sizeof (tmp))) {
1045 ret_val = -EFAULT;
1046 break;
1047 }
1048 if (tmp > IFX_SSC_MAX_GPO_OUT)
1049 ret_val = -EINVAL;
1050 else {
1051 writel(1 << (tmp + IFX_SSC_WHBGPOSTAT_CLROUT0_POS),
1052 IFXMIPS_SSC_WHBGPOSTAT);
1053 }
1054 break;
1055 case IFX_SSC_GPO_OUT_GET:
1056 tmp = readl(IFXMIPS_SSC_GPOSTAT);
1057 if (from_kernel)
1058 *((unsigned int *) data) = tmp;
1059 else if (copy_to_user ((void *) data,
1060 (void *) &tmp, sizeof (tmp)))
1061 ret_val = -EFAULT;
1062 break;
1063 case IFX_SSC_FRM_STATUS_GET:
1064 ifx_ssc_frm_status_get (info);
1065 if (from_kernel)
1066 memcpy ((void *) data, (void *) &info->frm_status,
1067 sizeof (struct ifx_ssc_frm_status));
1068 else if (copy_to_user ((void *) data,
1069 (void *) &info->frm_status,
1070 sizeof (struct ifx_ssc_frm_status)))
1071 ret_val = -EFAULT;
1072 break;
1073 case IFX_SSC_FRM_CONTROL_GET:
1074 ifx_ssc_frm_control_get (info);
1075 if (from_kernel)
1076 memcpy ((void *) data, (void *) &info->frm_opts,
1077 sizeof (struct ifx_ssc_frm_opts));
1078 else if (copy_to_user ((void *) data,
1079 (void *) &info->frm_opts,
1080 sizeof (struct ifx_ssc_frm_opts)))
1081 ret_val = -EFAULT;
1082 break;
1083 case IFX_SSC_FRM_CONTROL_SET:
1084 if (from_kernel)
1085 memcpy ((void *) &info->frm_opts, (void *) data,
1086 sizeof (struct ifx_ssc_frm_opts));
1087 else if (copy_to_user ((void *) &info->frm_opts,
1088 (void *) data,
1089 sizeof (struct ifx_ssc_frm_opts))) {
1090 ret_val = -EFAULT;
1091 break;
1092 }
1093 ret_val = ifx_ssc_frm_control_set (info);
1094 break;
1095 case IFX_SSC_HWOPTS_SET:
1096 /* data must be a pointer to a struct ifx_ssc_hwopts */
1097 /* if the buffers are not empty then the port is */
1098 /* busy and we shouldn't change things on-the-fly! */
1099 if (!info->txbuf || !info->rxbuf ||
1100 (readl(IFXMIPS_SSC_STATE)
1101 & IFX_SSC_STATE_BUSY)) {
1102 ret_val = -EBUSY;
1103 break;
1104 }
1105 if (from_kernel)
1106 memcpy ((void *) &info->opts, (void *) data,
1107 sizeof (struct ifx_ssc_hwopts));
1108 else if (copy_from_user ((void *) &info->opts,
1109 (void *) data, sizeof(struct ifx_ssc_hwopts))) {
1110 ret_val = -EFAULT;
1111 break;
1112 }
1113 if (ifx_ssc_hwinit (info) < 0) {
1114 ret_val = -EIO;
1115 }
1116 break;
1117 case IFX_SSC_HWOPTS_GET:
1118 /* data must be a pointer to a struct ifx_ssc_hwopts */
1119 if (from_kernel)
1120 memcpy ((void *) data, (void *) &info->opts,
1121 sizeof (struct ifx_ssc_hwopts));
1122 else if (copy_to_user ((void *) data,
1123 (void *) &info->opts,
1124 sizeof (struct ifx_ssc_hwopts)))
1125 ret_val = -EFAULT;
1126 break;
1127 default:
1128 ret_val = -ENOIOCTLCMD;
1129 }
1130
1131 return ret_val;
1132 }
1133 EXPORT_SYMBOL(ifx_ssc_ioctl);
1134
1135 static struct file_operations ifx_ssc_fops = {
1136 .owner = THIS_MODULE,
1137 .read = ifx_ssc_read,
1138 .write = ifx_ssc_write,
1139 .ioctl = ifx_ssc_ioctl,
1140 .open = ifx_ssc_open,
1141 .release = ifx_ssc_close,
1142 };
1143
1144 int __init
1145 ifx_ssc_init (void)
1146 {
1147 struct ifx_ssc_port *info;
1148 int i, nbytes;
1149 unsigned long flags;
1150 int ret_val;
1151
1152 ret_val = -ENOMEM;
1153 nbytes = PORT_CNT * sizeof(struct ifx_ssc_port);
1154 isp = (struct ifx_ssc_port*)kmalloc(nbytes, GFP_KERNEL);
1155
1156 if (isp == NULL)
1157 {
1158 printk("%s: no memory for isp\n", __func__);
1159 return (ret_val);
1160 }
1161 memset(isp, 0, nbytes);
1162
1163 ret_val = -ENXIO;
1164 if ((i = register_chrdev (maj, "ssc", &ifx_ssc_fops)) < 0)
1165 {
1166 printk ("Unable to register major %d for the Infineon SSC\n", maj);
1167 if (maj == 0)
1168 {
1169 goto errout;
1170 } else {
1171 maj = 0;
1172 if ((i = register_chrdev (maj, "ssc", &ifx_ssc_fops)) < 0)
1173 {
1174 printk ("Unable to register major %d for the Infineon SSC\n", maj);
1175 goto errout;
1176 }
1177 }
1178 }
1179
1180 if (maj == 0)
1181 maj = i;
1182
1183 /* set default values in ifx_ssc_port */
1184 for (i = 0; i < PORT_CNT; i++) {
1185 info = &isp[i];
1186 info->port_nr = i;
1187 /* default values for the HwOpts */
1188 info->opts.AbortErrDetect = IFX_SSC_DEF_ABRT_ERR_DETECT;
1189 info->opts.rxOvErrDetect = IFX_SSC_DEF_RO_ERR_DETECT;
1190 info->opts.rxUndErrDetect = IFX_SSC_DEF_RU_ERR_DETECT;
1191 info->opts.txOvErrDetect = IFX_SSC_DEF_TO_ERR_DETECT;
1192 info->opts.txUndErrDetect = IFX_SSC_DEF_TU_ERR_DETECT;
1193 info->opts.loopBack = IFX_SSC_DEF_LOOP_BACK;
1194 info->opts.echoMode = IFX_SSC_DEF_ECHO_MODE;
1195 info->opts.idleValue = IFX_SSC_DEF_IDLE_DATA;
1196 info->opts.clockPolarity = IFX_SSC_DEF_CLOCK_POLARITY;
1197 info->opts.clockPhase = IFX_SSC_DEF_CLOCK_PHASE;
1198 info->opts.headingControl = IFX_SSC_DEF_HEADING_CONTROL;
1199 info->opts.dataWidth = IFX_SSC_DEF_DATA_WIDTH;
1200 info->opts.modeRxTx = IFX_SSC_DEF_MODE_RXTX;
1201 info->opts.gpoCs = IFX_SSC_DEF_GPO_CS;
1202 info->opts.gpoInv = IFX_SSC_DEF_GPO_INV;
1203 info->opts.masterSelect = IFX_SSC_DEF_MASTERSLAVE;
1204 info->baud = IFX_SSC_DEF_BAUDRATE;
1205 info->rxbuf = NULL;
1206 info->txbuf = NULL;
1207 /* values specific to SSC1 */
1208 if (i == 0) {
1209 info->mapbase = IFXMIPS_SSC_BASE_ADDR;
1210 }
1211
1212 writel(IFX_SSC_DEF_RMC << IFX_CLC_RUN_DIVIDER_OFFSET, IFXMIPS_SSC_CLC);
1213
1214 init_waitqueue_head (&info->rwait);
1215
1216 local_irq_save (flags);
1217
1218 // init serial framing register
1219 writel(IFX_SSC_DEF_SFCON, IFXMIPS_SSC_SFCON);
1220
1221 ret_val = request_irq(IFXMIPS_SSC_TIR, ifx_ssc_tx_int, IRQF_DISABLED, "ifx_ssc_tx", info);
1222 if (ret_val)
1223 {
1224 printk("%s: unable to get irq %d\n", __func__, IFXMIPS_SSC_TIR);
1225 local_irq_restore(flags);
1226 goto errout;
1227 }
1228
1229 ret_val = request_irq(IFXMIPS_SSC_RIR, ifx_ssc_rx_int, IRQF_DISABLED, "ifx_ssc_rx", info);
1230 if (ret_val)
1231 {
1232 printk ("%s: unable to get irq %d\n", __func__, IFXMIPS_SSC_RIR);
1233 local_irq_restore (flags);
1234 goto irqerr;
1235 }
1236
1237 ret_val = request_irq(IFXMIPS_SSC_EIR, ifx_ssc_err_int, IRQF_DISABLED, "ifx_ssc_err", info);
1238 if (ret_val)
1239 {
1240 printk ("%s: unable to get irq %d\n", __func__, IFXMIPS_SSC_EIR);
1241 local_irq_restore (flags);
1242 goto irqerr;
1243 }
1244 writel(IFX_SSC_DEF_IRNEN, IFXMIPS_SSC_IRN);
1245
1246 //enable_irq(IFXMIPS_SSC_TIR);
1247 //enable_irq(IFXMIPS_SSC_RIR);
1248 //enable_irq(IFXMIPS_SSC_EIR);
1249
1250 local_irq_restore (flags);
1251 }
1252
1253 for (i = 0; i < PORT_CNT; i++) {
1254 info = &isp[i];
1255 if (ifx_ssc_hwinit (info) < 0)
1256 {
1257 printk ("%s: hardware init failed for port %d\n", __func__, i);
1258 goto irqerr;
1259 }
1260 }
1261
1262
1263 return 0;
1264
1265 irqerr:
1266 free_irq(IFXMIPS_SSC_TIR, &isp[0]);
1267 free_irq(IFXMIPS_SSC_RIR, &isp[0]);
1268 free_irq(IFXMIPS_SSC_EIR, &isp[0]);
1269 errout:
1270 kfree (isp);
1271 return (ret_val);
1272 }
1273
1274 void
1275 ifx_ssc_cleanup_module (void)
1276 {
1277 int i;
1278
1279 for (i = 0; i < PORT_CNT; i++) {
1280 writel(IFX_SSC_WHBSTATE_CLR_ENABLE, IFXMIPS_SSC_WHBSTATE);
1281 free_irq(IFXMIPS_SSC_TIR, &isp[i]);
1282 free_irq(IFXMIPS_SSC_RIR, &isp[i]);
1283 free_irq(IFXMIPS_SSC_EIR, &isp[i]);
1284 }
1285 kfree (isp);
1286 }
1287
1288 module_init(ifx_ssc_init);
1289 module_exit(ifx_ssc_cleanup_module);
1290
1291
1292 inline int
1293 ifx_ssc_cs_low (u32 pin)
1294 {
1295 int ret = 0;
1296 if ((ret = ifx_ssc_ioctl ((struct inode *) 0, NULL, IFX_SSC_GPO_OUT_CLR, (unsigned long) &pin)))
1297 printk ("clear CS %d fails\n", pin);
1298 wmb ();
1299
1300 return ret;
1301 }
1302 EXPORT_SYMBOL(ifx_ssc_cs_low);
1303
1304 inline int
1305 ifx_ssc_cs_high (u32 pin)
1306 {
1307 int ret = 0;
1308 if ((ret = ifx_ssc_ioctl((struct inode *) 0, NULL, IFX_SSC_GPO_OUT_SET, (unsigned long) &pin)))
1309 printk ("set CS %d fails\n", pin);
1310 wmb ();
1311
1312 return ret;
1313 }
1314 EXPORT_SYMBOL(ifx_ssc_cs_high);
1315
1316 static int
1317 ssc_session (char *tx_buf, u32 tx_len, char *rx_buf, u32 rx_len)
1318 {
1319 int ret = 0;
1320
1321 char *ssc_tx_buf = NULL;
1322 char *ssc_rx_buf = NULL;
1323 int eff_size = 0;
1324 u8 mode = 0;
1325
1326 if (tx_buf == NULL && tx_len == 0 && rx_buf == NULL && rx_len == 0) {
1327 printk ("invalid parameters\n");
1328 ret = -EINVAL;
1329 goto ssc_session_exit;
1330 }
1331 else if (tx_buf == NULL || tx_len == 0) {
1332 if (rx_buf != NULL && rx_len != 0) {
1333 mode = IFX_SSC_MODE_RX;
1334 }
1335 else {
1336 printk ("invalid parameters\n");
1337 ret = -EINVAL;
1338 goto ssc_session_exit;
1339 }
1340 }
1341 else if (rx_buf == NULL || rx_len == 0) {
1342 if (tx_buf != NULL && tx_len != 0) {
1343 mode = IFX_SSC_MODE_TX;
1344 }
1345 else {
1346 printk ("invalid parameters\n");
1347 ret = -EINVAL;
1348 goto ssc_session_exit;
1349 }
1350 }
1351 else {
1352 mode = IFX_SSC_MODE_RXTX;
1353 }
1354
1355 if (mode == IFX_SSC_MODE_RXTX) {
1356 eff_size = tx_len + rx_len;
1357 }
1358 else if (mode == IFX_SSC_MODE_RX) {
1359 eff_size = rx_len;
1360 }
1361 else {
1362 eff_size = tx_len;
1363 }
1364
1365 //4 bytes alignment, required by driver
1366 /* change by TaiCheng */
1367 //if (in_irq()){
1368 if (1) {
1369 ssc_tx_buf =
1370 (char *) kmalloc (sizeof (char) *
1371 ((eff_size + 3) & (~3)),
1372 GFP_ATOMIC);
1373 ssc_rx_buf =
1374 (char *) kmalloc (sizeof (char) *
1375 ((eff_size + 3) & (~3)),
1376 GFP_ATOMIC);
1377 }
1378 else {
1379 ssc_tx_buf =
1380 (char *) kmalloc (sizeof (char) *
1381 ((eff_size + 3) & (~3)),
1382 GFP_KERNEL);
1383 ssc_rx_buf =
1384 (char *) kmalloc (sizeof (char) *
1385 ((eff_size + 3) & (~3)),
1386 GFP_KERNEL);
1387 }
1388 if (ssc_tx_buf == NULL || ssc_rx_buf == NULL) {
1389 printk ("no memory for size of %d\n", eff_size);
1390 ret = -ENOMEM;
1391 goto ssc_session_exit;
1392 }
1393 memset ((void *) ssc_tx_buf, 0, eff_size);
1394 memset ((void *) ssc_rx_buf, 0, eff_size);
1395
1396 if (tx_len > 0) {
1397 memcpy (ssc_tx_buf, tx_buf, tx_len);
1398 }
1399
1400 ret = ifx_ssc_kwrite (0, ssc_tx_buf, eff_size);
1401
1402 if (ret > 0) {
1403 ssc_tx_buf = NULL; //should be freed by ifx_ssc_kwrite
1404 }
1405
1406 if (ret != eff_size) {
1407 printk ("ifx_ssc_write return %d\n", ret);
1408 goto ssc_session_exit;
1409 }
1410 ret = ifx_ssc_kread (0, ssc_rx_buf, eff_size);
1411 if (ret != eff_size) {
1412 printk ("ifx_ssc_read return %d\n", ret);
1413 goto ssc_session_exit;
1414 }
1415
1416 memcpy (rx_buf, ssc_rx_buf + tx_len, rx_len);
1417
1418 if (mode == IFX_SSC_MODE_TX) {
1419 ret = tx_len;
1420 }
1421 else {
1422 ret = rx_len;
1423 }
1424 ssc_session_exit:
1425
1426 if (ssc_tx_buf != NULL)
1427 kfree (ssc_tx_buf);
1428 if (ssc_rx_buf != NULL)
1429 kfree (ssc_rx_buf);
1430
1431 if (ret < 0) {
1432 printk ("ssc session fails\n");
1433 }
1434 return ret;
1435 }
1436
1437 int
1438 ifx_ssc_txrx (char *tx_buf, u32 tx_len, char *rx_buf, u32 rx_len)
1439 {
1440 return ssc_session(tx_buf, tx_len, rx_buf, rx_len);
1441 }
1442 EXPORT_SYMBOL(ifx_ssc_txrx);
1443
1444 int
1445 ifx_ssc_tx (char *tx_buf, u32 tx_len)
1446 {
1447 return ssc_session(tx_buf, tx_len, NULL, 0);
1448 }
1449 EXPORT_SYMBOL(ifx_ssc_tx);
1450
1451 int
1452 ifx_ssc_rx (char *rx_buf, u32 rx_len)
1453 {
1454 return ssc_session(NULL, 0, rx_buf, rx_len);
1455 }
1456 EXPORT_SYMBOL(ifx_ssc_rx);
1457
1458 MODULE_LICENSE("GPL");
1459 MODULE_AUTHOR("John Crispin <blogic@openwrt.org>");
1460 MODULE_DESCRIPTION("ifxmips ssc driver");
1461