MOXA linux-2.6.x / linux-2.6.19-uc1 from UC-7110-LX-BOOTLOADER-1.9_VERSION-4.2.tgz
[linux-2.6.19-moxart.git] / drivers / char / mcf_qspi.c
blob52e159ee8b3ce6ec2c5c2f1038badb20ccb7117d
1 /************************************************************************/
2 /* */
3 /* mcf_qspi.c - QSPI driver for MCF5272, MCF5235, MCF5282 */
4 /* */
5 /* (C) Copyright 2001, Wayne Roberts (wroberts1@home.com) */
6 /* */
7 /* Driver has an 8bit mode, and a 16bit mode. */
8 /* Transfer size QMR[BITS] is set thru QSPIIOCS_BITS. */
9 /* When size is 8, driver works normally: */
10 /* a char is sent for every transfer */
11 /* When size is 9 to 16bits, driver reads & writes the QDRs with */
12 /* the buffer cast to unsigned shorts. The QTR & QRR registers can */
13 /* be filled with up to 16bits. The length passed to read/write must */
14 /* be of the number of chars (2x number of shorts). This has been */
15 /* tested with 10bit a/d and d/a converters. */
16 /* */
17 /* * QSPIIOCS_READDATA: */
18 /* data to send out during read */
19 /* * all other ioctls are global */
20 /* -------------------------------------------------------------------- */
21 /* Ported to linux-2.4.x by Ron Fial (ron@fial.com) August 26,2002 */
22 /* */
23 /* Added new include files */
24 /* Added module_init(),exit(), */
25 /* qspi_read(),qspi_write(): Revised qspi_read & write argument */
26 /* processing to handle new *filep argument. Changed i_rdev access */
27 /* to use filep->f_dentry->d_inode->i_rdev Changed memcpy_fromfs() */
28 /* to memcpy(). */
29 /* Added '__init' to compiled-in init routine for memory recovery */
30 /* Added '__exit' for loadable-driver module cleanup routine */
31 /* changed register_chrdev to devfs_register_chrdev */
32 /* changed unregister_chrdev to devfs_unregister_chrdev */
33 /* Changed various declarations from int to ssize_t or loff_t */
34 /* -------------------------------------------------------------------- */
35 /* Changed interruptible_sleep_on to sleep_on so the driver has */
36 /* chance to finish the current transfer before application */
37 /* quits when typing '^C'. Otherwise a write collision will */
38 /* most likely occur. */
39 /* Added safe_flags(); cli; and frestore_flags() according to */
40 /* gerg@snapgear.com. Otherwise in some cases (higher clock */
41 /* rates) the transfer is finished before the current process */
42 /* is put to sleep and therefore never wakes up again. */
43 /* 09/12/2002 richard@opentcp.org */
44 /* -------------------------------------------------------------------- */
45 /* 02/06/2003 josef.baumgartner@telex.de */
46 /* */
47 /* Renamed cleanup_module() to qspi_exit() to be able to */
48 /* compile as module. */
49 /* Removed init_module() because module_init(qspi_init) does all */
50 /* we need. */
51 /* Changed */
52 /* SPI register settings will be saved for each instance to be able */
53 /* to use different communication settings for different tasks. */
54 /* An ioctl() does not longer write directly to the SPI registers. */
55 /* It saves the settings which will be copied into the SPI */
56 /* registers on every read()/write(). */
57 /* Added MODULE_LICENSE("GPL") to avoid tainted kernel message. */
58 /* I think it is GPL?? There's no comment about this?? */
59 /* Added polling mode */
60 /* Increases performance for small data transfers. */
61 /* Added odd mode */
62 /* If an odd number of bytes is transfered and 16bit transfers are */
63 /* used, the last byte is transfered in byte mode. */
64 /* Added dsp mode */
65 /* If dsp mode is set, transfers will be limited to 15 bytes */
66 /* instead of 16. This ensures that DSPs with 24bit words get */
67 /* whole words within one transfer. */
68 /* -------------------------------------------------------------------- */
69 /* 16/09/2003 ivan.zanin@bluewin.ch */
70 /* */
71 /* Changed init and exit code to support the MCF5249 */
72 /* -------------------------------------------------------------------- */
73 /* Oct 19, 2004 jsujjavanich@syntech-fuelmaster.com */
74 /* */
75 /* Adjusted minor number detection to work with one dev per QSPI_CS */
76 /* -------------------------------------------------------------------- */
77 /* 17/11/2004 chris_jones_oz@yahoo.com.au */
78 /* */
79 /* Changed init and exit code to support the MCF5282 */
80 /* -------------------------------------------------------------------- */
81 /* 050712 jherrero@hvsistemas.es */
82 /* */
83 /* Ported to kernel 2.6.x, tested only write on MCF5272 */
84 /* -------------------------------------------------------------------- */
85 /************************************************************************/
87 /* **********************************************************************
88 Chapter 14. (excerpt) Queued Serial Peripheral Interface (QSPI) Module
89 From: http://e-www.motorola.com/brdata/PDFDB/docs/MCF5272UM.pdf
91 The following steps are necessary to set up the QSPI 12-bit data transfers
92 and a QSPI_CLK of 4.125 MHz. The QSPI RAM is set up for a queue of 16
93 transfers. All four QSPI_CS signals are used in this example.
95 1. Enable all QSPI_CS pins on the MCF5272. Write PACNT with 0x0080_4000 to
96 enable QSPI_CS1 and QSPI_CS3.Write PDCNT with 0x0000_0030 to enable QSPI_CS2.
98 2. Write the QMR with 0xB308 to set up 12-bit data words with the data
99 shifted on the falling clock edge, and a clock frequency of 4.125 MHz
100 (assuming a 66-MHz CLKIN).
102 3. Write QDLYR with the desired delays.
104 4. Write QIR with 0xD00F to enable write collision, abort bus errors, and
105 clear any interrupts.
107 5. Write QAR with 0x0020 to select the first command RAM entry.
109 6. Write QDR with 0x7E00, 0x7E00, 0x7E00, 0x7E00, 0x7D00, 0x7D00, 0x7D00,
110 0x7D00, 0x7B00, 0x7B00, 0x7B00, 0x7B00, 0x7700, 0x7700, 0x7700, and 0x7700
111 to set up four transfers for each chip select. The chip selects are active
112 low in this example. NOTE: QDR value auto-increments after each write.
114 7. Write QAR with 0x0000 to select the first transmit RAM entry.
116 8. Write QDR with sixteen 12-bit words of data.
118 9. Write QWR with 0x0F00 to set up a queue beginning at entry 0 and ending
119 at entry 15.
121 10. Set QDLYR[SPE] to enable the transfers.
123 11.Wait until the transfers are complete. QIR[SPIF] is set when the
124 transfers are complete.
126 12. Write QAR with 0x0010 to select the first receive RAM entry.
128 13. Read QDR to get the received data for each transfer. NOTE: QDR
129 auto-increments.
131 14. Repeat steps 5 through 13 to do another transfer.
133 ************************************************************************* */
134 #include <asm/coldfire.h> /* gets us MCF_MBAR value */
135 #include <asm/mcfsim.h> /* MCFSIM offsets */
136 #include <asm/semaphore.h>
137 #include <asm/system.h> /* cli() and friends */
138 #include <asm/uaccess.h>
139 #include <linux/devfs_fs_kernel.h>
140 #include <linux/errno.h>
141 #include <linux/fs.h>
142 #include <linux/init.h>
143 #include <linux/kernel.h>
144 #include <linux/module.h>
145 #include <linux/sched.h>
146 #include <linux/slab.h>
147 #include <linux/types.h>
148 #include <linux/version.h>
149 #include <linux/wait.h>
150 #include <linux/interrupt.h>
152 /* Include versioning info, if needed */
153 #if (defined(MODULE) && defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS))
154 #define MODVERSIONS
155 #endif
157 #if defined(MODVERSIONS)
158 #include <linux/modversions.h>
159 #endif
161 #include "mcf_qspi.h"
164 #define DEVICE_NAME "qspi"
166 int __init qspi_init(void);
167 static int init(void);
168 void __exit qspi_exit(void);
171 /* struct wait_queue *wqueue; */
172 static DECLARE_WAIT_QUEUE_HEAD(wqueue); /* use ver 2.4 static declaration - ron */
173 /* or should we use wait_queue_heat_t *wqueue ?? see page 141 */
175 static unsigned char dbuf[1024];
177 /* static struct semaphore sem = MUTEX; */
180 #if LINUX_VERSION_CODE < 0x020100
181 static struct semaphore sem = MUTEX;
182 #else
183 static DECLARE_MUTEX(sem);
184 #endif
187 irqreturn_t qspi_interrupt(int irq, void *dev_id, struct pt_regs *regs)
189 u16 qir = (QIR & (QIR_WCEF | QIR_ABRT | QIR_SPIF));
191 /* Check write collision and transfer abort flags. Report any
192 * goofiness. */
193 if (qir & QIR_WCEF)
194 printk(KERN_INFO "%s: WCEF\n", __FILE__);
196 if (qir & QIR_ABRT)
197 printk(KERN_INFO "%s: ABRT\n", __FILE__);
199 /* Check for completed transfer. Wake any tasks sleeping on our
200 * global wait queue. */
201 if (qir & QIR_SPIF)
202 wake_up(&wqueue);
204 /* Clear any set flags. */
205 QIR |= qir;
206 return IRQ_HANDLED;
210 static int qspi_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
211 unsigned long arg)
213 int ret = 0;
214 struct qspi_dev *dev = filp->private_data;
215 struct qspi_read_data *read_data;
216 int error;
218 down(&sem);
220 switch (cmd) {
221 /* Set QMR[DOHIE] (high-z Dout between transfers) */
222 case QSPIIOCS_DOUT_HIZ:
223 dev->dohie = (arg ? 1 : 0);
224 break;
226 /* Set QMR[BITS] */
227 case QSPIIOCS_BITS:
228 if (((arg > 0) && (arg < 8)) || (arg > 16)) {
229 ret = -EINVAL;
230 break;
233 dev->bits = (u8)arg;
234 break;
236 /* Get QMR[BITS] */
237 case QSPIIOCG_BITS:
238 *((int *)arg) = dev->bits;
239 break;
241 /* Set QMR[CPOL] (QSPI_CLK inactive state) */
242 case QSPIIOCS_CPOL:
243 dev->cpol = (arg ? 1 : 0);
244 break;
246 /* Set QMR[CPHA] (QSPI_CLK phase, 1 = rising edge) */
247 case QSPIIOCS_CPHA:
248 dev->cpha = (arg ? 1 : 0);
249 break;
251 /* Set QMR[BAUD] (QSPI_CLK baud rate divisor) */
252 case QSPIIOCS_BAUD:
253 if (arg > 255) {
254 ret = -EINVAL;
255 break;
258 dev->baud = (u8)arg;
259 break;
261 /* Set QDR[QCD] (QSPI_CS to QSPI_CLK setup) */
262 case QSPIIOCS_QCD:
263 if (arg > 127) {
264 ret = -EINVAL;
265 break;
268 dev->qcd = (u8)arg;
269 break;
271 /* Set QDR[DTL] (QSPI_CLK to QSPI_CS hold) */
272 case QSPIIOCS_DTL:
273 if (arg > 255) {
274 ret = -EINVAL;
275 break;
278 dev->dtl = (u8)arg;
279 break;
281 /* Set QCRn[CONT] (QSPI_CS continuous mode, 1 = remain
282 * asserted after transfer of 16 data words) */
283 case QSPIIOCS_CONT:
284 dev->qcr_cont = (arg ? 1 : 0);
285 break;
287 /* Set DSP mode, used to limit transfers to 15 bytes for
288 * 24-bit DSPs */
289 case QSPIIOCS_DSP_MOD:
290 dev->dsp_mod = (arg ? 1 : 0);
291 break;
293 /* If an odd count of bytes is transferred, force the transfer
294 * of the last byte to byte mode, even if word mode is used */
295 case QSPIIOCS_ODD_MOD:
296 dev->odd_mod = (arg ? 1 : 0);
297 break;
299 /* Set data buffer to be used as "send data" during reads */
300 case QSPIIOCS_READDATA:
301 read_data = (struct qspi_read_data *)arg;
302 error = !access_ok(VERIFY_READ, read_data,
303 sizeof(struct qspi_read_data));
304 if (error) {
305 ret = -EFAULT;
306 break;
309 if (read_data->length > sizeof(read_data->buf)) {
310 // possible bug here when want length > 4
311 ret = -EINVAL;
312 break;
315 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
316 memcpy_fromfs(&dev->read_data, read_data,
317 sizeof(struct qspi_read_data));
318 #else
319 copy_from_user(&dev->read_data, read_data,
320 sizeof(struct qspi_read_data));
321 #endif
322 break;
324 /* Set driver to use polling mode, which may increase
325 * performance for small transfers */
326 case QSPIIOCS_POLL_MOD:
327 dev->poll_mod = (arg ? 1 : 0);
328 break;
330 default:
331 ret = -EINVAL;
332 break;
335 up(&sem);
336 return(ret);
340 static int qspi_open(struct inode *inode, struct file *file)
342 qspi_dev *dev;
344 /* #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
345 MOD_INC_USE_COUNT;
346 #endif */
348 if ((dev = kmalloc(sizeof(qspi_dev), GFP_KERNEL)) == NULL) {
349 /* #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
350 MOD_DEC_USE_COUNT;
351 #endif */
352 return(-ENOMEM);
355 /* set default values */
356 dev->read_data.length = 0;
357 dev->read_data.buf = 0;
358 dev->read_data.loop = 0;
359 dev->poll_mod = 0; /* interrupt mode */
360 dev->bits = 8;
361 dev->cpol = 0;
362 dev->cpha = 0;
363 dev->qcr_cont = 1;
364 dev->dsp_mod = 0; /* no DSP mode */
365 dev->odd_mod = 0; /* no ODD mode */
366 dev->qcd = 17;
367 dev->dtl = 1;
369 file->private_data = dev;
371 return(0);
375 static int qspi_release(struct inode *inode, struct file *file)
377 kfree(file->private_data);
379 /* #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
380 MOD_DEC_USE_COUNT;
381 #endif */
383 return(0);
387 // basic 2.4 kernel function format
388 // ssize_t qspi_read(struct file* w12f, char * w12c, size_t w12d, loff_t * w12e) { ; }
391 static ssize_t qspi_read(struct file *filep, char *buffer, size_t length,
392 loff_t *off)
393 /******** older 2.0 kernel format **********
394 static int qspi_read(
395 struct inode *inode,
396 struct file *filep,
397 char *buffer,
398 int length)
399 ********************************************/
401 int qcr_cs;
402 int total = 0;
403 int i = 0;
404 int max_trans;
405 unsigned char bits;
406 unsigned char word = 0;
407 unsigned long flag;
408 qspi_dev *dev;
409 int rdi = 0;
411 down(&sem);
413 dev = filep->private_data;
415 /* set the register with default values */
416 QMR = QMR_MSTR |
417 (dev->dohie << 14) |
418 (dev->bits << 10) |
419 (dev->cpol << 9) |
420 (dev->cpha << 8) |
421 (dev->baud);
423 QDLYR = (dev->qcd << 8) | dev->dtl;
425 if (dev->dsp_mod)
426 max_trans = 15;
427 else
428 max_trans = 16;
430 //qcr_cs = (~MINOR(filep->f_dentry->d_inode->i_rdev) << 8) & 0xf00; /* CS for QCR */
431 qcr_cs = 0xf00 & ~(1 << (8 + MINOR(filep->f_dentry->d_inode->i_rdev)));
433 bits = dev->bits % 0x10;
434 if (bits == 0 || bits > 0x08)
435 word = 1; /* 9 to 16bit transfers */
437 // printk("\n READ driver -- ioctl xmit data fm dev->read_data.buf array %x %x %x %x \n",dev->read_data.buf[0],dev->read_data.buf[1],dev->read_data.buf[2],dev->read_data.buf[3]);
439 while (i < length) {
440 unsigned short *sp = (unsigned short *)&buffer[i];
441 unsigned char *cp = &buffer[i];
442 unsigned short *rd_sp = (unsigned short *)dev->read_data.buf;
443 int x;
444 int n;
446 QAR = TX_RAM_START; /* address first QTR */
447 for (n = 0; n < max_trans; n++) {
448 if (rdi != -1) {
449 if (word) {
450 if (rd_sp)
451 QDR = rd_sp[rdi++];
452 else
453 QDR = 0;
454 if (rdi == dev->read_data.length >> 1)
455 rdi = dev->read_data.loop ? 0 : -1;
456 } else {
457 if (dev->read_data.buf)
458 QDR = dev->read_data.buf[rdi++];
459 else
460 QDR = 0;
461 if (rdi == dev->read_data.length)
462 rdi = dev->read_data.loop ? 0 : -1;
464 } else
465 QDR = 0;
467 i++;
468 if (word)
469 i++;
470 if (i > length)
471 break;
474 QAR = COMMAND_RAM_START; /* address first QCR */
475 for (x = 0; x < n; x++) {
476 /* QCR write */
477 if (dev->qcr_cont) {
478 if (x == n - 1 && i == length)
479 QDR = QCR_SETUP | qcr_cs; /* last transfer */
480 else
481 QDR = QCR_CONT | QCR_SETUP | qcr_cs;
482 } else
483 QDR = QCR_SETUP | qcr_cs;
486 QWR = QWR_CSIV | ((n - 1) << 8);
488 /* check if we are using polling mode. Polling increases
489 * performance for samll data transfers but is dangerous
490 * if we stay too long here, locking other tasks!!
492 if (dev->poll_mod) {
493 QIR = QIR_SETUP_POLL;
494 QDLYR |= QDLYR_SPE;
496 while ((QIR & QIR_SPIF) != QIR_SPIF)
498 QIR = QIR | QIR_SPIF;
499 } else {
500 QIR = QIR_SETUP;
501 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
502 save_flags(flag); cli(); // like in write function
503 #else
504 local_irq_save(flag);
505 #endif
507 QDLYR |= QDLYR_SPE;
508 // interruptible_sleep_on(&wqueue);
509 sleep_on(&wqueue); // changed richard@opentcp.org
510 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
511 restore_flags(flag); // like in write function
512 #else
513 local_irq_restore(flag);
514 #endif
517 QAR = RX_RAM_START; /* address: first QRR */
518 if (word) {
519 /* 9 to 16bit transfers */
520 for (x = 0; x < n; x++) {
521 put_user(*(volatile unsigned short *)(MCF_MBAR + MCFSIM_QDR), sp++);
523 } else {
524 /* 8bit transfers */
525 for (x = 0; x < n; x++)
526 put_user(*(volatile unsigned short *)(MCF_MBAR + MCFSIM_QDR), cp++);
529 if (word)
530 n <<= 1;
532 total += n;
535 up(&sem);
536 return(total);
541 static ssize_t qspi_write(struct file *filep, const char *buffer, size_t length,
542 loff_t *off)
544 int qcr_cs;
545 int i = 0;
546 int total = 0;
547 int z;
548 int max_trans;
549 unsigned char bits;
550 unsigned char word = 0;
551 unsigned long flag;
552 qspi_dev *dev;
554 down(&sem);
556 dev = filep->private_data;
558 QMR = QMR_MSTR |
559 (dev->dohie << 14) |
560 (dev->bits << 10) |
561 (dev->cpol << 9) |
562 (dev->cpha << 8) |
563 (dev->baud);
565 QDLYR = (dev->qcd << 8) | dev->dtl;
567 bits = (QMR >> 10) % 0x10;
568 if (bits == 0 || bits > 0x08)
569 word = 1; /* 9 to 16 bit transfers */
571 //qcr_cs = (~MINOR(filep->f_dentry->d_inode->i_rdev) << 8) & 0xf00; /* CS for QCR */
572 qcr_cs = 0xf00 & ~(1 << (8 + MINOR(filep->f_dentry->d_inode->i_rdev)));
574 /* next line was memcpy_fromfs() */
575 copy_from_user (dbuf, buffer, length);
577 // printk("data to write is %x %x %x %X \n",dbuf[0],dbuf[1],dbuf[2],dbuf[3]);
579 if (dev->odd_mod)
580 z = QCR_SETUP8;
581 else
582 z = QCR_SETUP;
584 if (dev->dsp_mod)
585 max_trans = 15;
586 else
587 max_trans = 16;
589 while (i < length) {
590 int x;
591 int n;
593 QAR = TX_RAM_START; /* address: first QTR */
594 if (word) {
595 for (n = 0; n < max_trans; ) {
596 /* in odd mode last byte will be transfered in byte mode */
597 if (dev->odd_mod && (i + 1 == length)) {
598 QDR = dbuf[i]; /* tx data: QDR write */
599 // printk("0x%X ", dbuf[i]);
600 n++;
601 i++;
602 break;
604 else {
605 QDR = (dbuf[i] << 8) + dbuf[i+1]; /* tx data: QDR write */
606 //printk("0x%X 0x%X ", dbuf[i], dbuf[i+1]);
607 n++;
608 i += 2;
609 if (i >= length)
610 break;
613 } else {
614 /* 8bit transfers */
615 for (n = 0; n < max_trans; ) {
616 QDR = dbuf[i]; /* tx data: QTR write */
617 n++;
618 i++;
619 if (i == length)
620 break;
624 QAR = COMMAND_RAM_START; /* address: first QCR */
625 for (x = 0; x < n; x++) {
626 /* QCR write */
627 if (dev->qcr_cont) {
628 if (x == n-1 && i == length)
629 if ((i % 2)!= 0)
630 QDR = z | qcr_cs; /* last transfer and odd number of chars */
631 else
632 QDR = QCR_SETUP | qcr_cs; /* last transfer */
633 else
634 QDR = QCR_CONT | QCR_SETUP | qcr_cs;
635 } else {
636 if (x == n - 1 && i == length)
637 QDR = z | qcr_cs; /* last transfer */
638 else
639 QDR = QCR_SETUP | qcr_cs;
643 QWR = QWR_CSIV | ((n - 1) << 8); /* QWR[ENDQP] = n << 8 */
645 /* check if we are using polling mode. Polling increases
646 * performance for samll data transfers but is dangerous
647 * if we stay too long here, locking other tasks!!
649 if (dev->poll_mod) {
650 QIR = QIR_SETUP_POLL;
651 QDLYR |= QDLYR_SPE;
653 while ((QIR & QIR_SPIF) != QIR_SPIF)
655 QIR = QIR | QIR_SPIF;
656 } else {
657 QIR = QIR_SETUP;
658 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
659 save_flags(flag); cli(); // added according to gerg@snapgear.com
660 #else
661 local_irq_save(flag);
662 #endif
663 QDLYR |= QDLYR_SPE;
665 // interruptible_sleep_on(&wqueue);
666 sleep_on(&wqueue); // changed richard@opentcp.org
668 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
669 restore_flags(flag); // added according to gerg@snapgear.com
670 #else
671 local_irq_restore(flag);
672 #endif
676 if (word)
677 n <<= 1;
679 total += n;
682 up(&sem);
683 return(total);
687 /* fixed for 2.4 kernel, owner was ifdef'ed out for 2.0 kernel */
688 static struct file_operations Fops = {
689 owner: THIS_MODULE,
690 read: qspi_read,
691 write: qspi_write,
692 ioctl: qspi_ioctl,
693 open: qspi_open,
694 release: qspi_release /* a.k.a. close */
698 static int init(void)
700 volatile u32 *lp;
701 volatile u8 *cp;
703 /* common init: driver or module: */
705 if (request_irq(MCFQSPI_IRQ_VECTOR, qspi_interrupt, SA_INTERRUPT, "ColdFire QSPI", NULL)) {
706 printk("QSPI: Unable to attach ColdFire QSPI interrupt "
707 "vector=%d\n", MCFQSPI_IRQ_VECTOR);
708 return(-EINVAL);
711 #if defined(CONFIG_M5249)
712 cp = (volatile u8 *)(MCF_MBAR + MCFSIM_ICR10);
713 *cp = 0x8f; /* autovector on, il=3, ip=3 */
715 lp = (volatile u32 *)(MCF_MBAR2 + 0x180);
716 *lp |= 0x00000800; /* activate qspi_in and qspi_clk */
718 lp = (volatile u32 *)(MCF_MBAR2 + MCFSIM2_GPIOFUNC);
719 *lp &= 0xdc9FFFFF; /* activate qspi_cs0 .. 3, qspi_dout */
721 lp = (volatile u32 *)(MCF_MBAR + MCFSIM_IMR);
722 *lp &= 0xFFFbFFFF; /* enable qspi interrupt */
723 #elif defined(CONFIG_M523x)
724 // interrupts mask here
725 cp = (volatile unsigned char *)(MCF_MBAR + MCF5235ICM_INTC0 + MCFINTC0_ICR);
726 cp[IRQ_SOURCE] = (( 3/*IL*/ & 0x3 ) << 3 ) | (3 /*IP*/ & 0x3);
728 lp = (volatile u32 *)(MCF_MBAR + MCFICM_INTC0 + MCFINTC_IMRL);
729 *lp &= ~((1 << MCFINT_QSPI) | 1); // cannot set bit 0
730 // GPIO here
732 volatile unsigned char *parp;
733 parp = (volatile unsigned char *)(MCF_MBAR + 0x10004A);
734 *parp = 0xFF;
736 #elif (defined(CONFIG_M5282) || defined(CONFIG_M5280))
737 cp = (volatile u8 *) (MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_ICR0 +
738 MCFINT_QSPI);
739 *cp = (5 << 3) + 3; /* level 5, priority 3 */
741 cp = (volatile u8 *) (MCF_IPSBAR + MCF5282_GPIO_PQSPAR);
742 *cp = 0x7f; /* activate din, dout, clk and cs[0..3] */
744 lp = (volatile u32 *) (MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRL);
745 *lp &= ~(1 + (1 << MCFINT_QSPI)); /* enable qspi interrupt */
746 #else
747 /* set our IPL */
748 lp = (volatile u32 *)(MCF_MBAR + MCFSIM_ICR4);
749 *lp = (*lp & 0x07777777) | 0xd0000000;
751 /* 1) CS pin setup 17.2.x
752 * Dout, clk, cs0 always enabled. Din, cs[3:1] must be enabled.
753 * CS1: PACNT[23:22] = 10
754 * CS1: PBCNT[23:22] = 10 ?
755 * CS2: PDCNT[05:04] = 11
756 * CS3: PACNT[15:14] = 01
758 lp = (volatile u32 *)(MCF_MBAR + MCFSIM_PACNT);
759 *lp = (*lp & 0xFF3F3FFF) | 0x00804000; /* 17.2.1 QSPI CS1 & CS3 */
760 lp = (volatile u32 *)(MCF_MBAR + MCFSIM_PDCNT);
761 *lp = (*lp & 0xFFFFFFCF) | 0x00000030; /* QSPI_CS2 */
762 #endif
765 * These values have to be setup according to the applications
766 * using the qspi driver. Maybe some #defines at the beginning
767 * would be more appropriate. Especially the transfer size
768 * and speed settings
770 QMR = 0xA1A2; // default mode setup: 8 bits, baud, 160kHz clk.
771 // QMR = 0x81A2; // default mode setup: 16 bits, baud, 160kHz clk.
772 QDLYR = 0x0202; // default start & end delays
774 init_waitqueue_head(&wqueue); /* was init_waitqueue() --Ron */
776 #if defined(CONFIG_M5249)
777 printk("MCF5249 QSPI driver ok\n");
778 #elif defined(CONFIG_M523x)
779 printk("MCF5235 QSPI driver ok\n");
780 #elif (defined(CONFIG_M5282) || defined(CONFIG_M5280))
781 printk("MCF5282 QSPI driver ok\n");
782 #else
783 printk("MCF5272 QSPI driver ok\n");
784 #endif
786 return(0);
789 /* init for compiled-in driver: call from mem.c */
790 int __init qspi_init(void) /* the __init added by ron */
792 int ret;
794 if ((ret = register_chrdev(QSPI_MAJOR, DEVICE_NAME, &Fops) < 0)) {
796 printk ("%s device failed with %d\n",
797 "Sorry, registering the character", ret);
798 return(ret);
801 printk ("QSPI device driver installed OK\n");
802 return(init());
805 /* Cleanup - undid whatever init_module did */
806 void __exit qspi_exit(void) /* the __exit added by ron */
808 int ret;
810 free_irq(MCFQSPI_IRQ_VECTOR, NULL);
812 #if defined(CONFIG_M5249)
813 /* autovector on, il=0, ip=0 */
814 *(volatile u8 *)(MCF_MBAR + MCFSIM_ICR10) = 0x80;
815 /* disable qspi interrupt */
816 *(volatile u32 *)(MCF_MBAR + MCFSIM_IMR) |= 0x00040000;
817 #elif defined(CONFIG_M523x)
819 volatile unsigned char *icrp;
820 icrp = (volatile unsigned char *)(MCF_MBAR + MCF5235ICM_INTC0 + MCFINTC0_ICR);
821 icrp[IRQ_SOURCE] = 0;
824 volatile unsigned long *imrl;
825 imrl = (volatile unsigned long *)(MCF_MBAR + MCFICM_INTC0 + MCFINTC_IMRL);
826 *imrl |= (1 << MCFINT_QSPI);
828 // GPIO here
830 volatile unsigned char *parp;
831 parp = (volatile unsigned char *)(MCF_MBAR + 0x10004A);
832 *parp = 0x00;
834 #elif (defined(CONFIG_M5282) || defined(CONFIG_M5280))
835 /* interrupt level 0, priority 0 */
836 *(volatile u8 *) (MCF_IPSBAR + MCFICM_INTC0 +
837 MCFINTC_ICR0 + MCFINT_QSPI) = 0;
838 /* disable qspi interrupt */
839 *(volatile u32 *) (MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRL)
840 |= (1 << MCFINT_QSPI);
841 #else
842 /* zero our IPL */
843 *((volatile u32 *)(MCF_MBAR + MCFSIM_ICR4)) = 0x80000000;
844 #endif
846 /* Unregister the device */
847 if ((ret = unregister_chrdev(QSPI_MAJOR, DEVICE_NAME)) < 0)
849 printk("Error in unregister_chrdev: %d\n", ret);
853 module_init(qspi_init); /* added by ron so driver can compile directly into kernel */
854 module_exit(qspi_exit); /* added by ron so driver can compile directly into kernel */
856 MODULE_LICENSE("GPL");