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