3 * mwavedd.c -- mwave device driver
6 * Written By: Mike Sullivan IBM Corporation
8 * Copyright (C) 1999 IBM Corporation
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
21 * THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
22 * CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
23 * LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
24 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
25 * solely responsible for determining the appropriateness of using and
26 * distributing the Program and assumes all risks associated with its
27 * exercise of rights under this Agreement, including but not limited to
28 * the risks and costs of program errors, damage to or loss of data,
29 * programs or equipment, and unavailability or interruption of operations.
31 * DISCLAIMER OF LIABILITY
32 * NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
33 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
34 * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
35 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
36 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
37 * USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
38 * HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
40 * You should have received a copy of the GNU General Public License
41 * along with this program; if not, write to the Free Software
42 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
45 * 10/23/2000 - Alpha Release
46 * First release to the public
49 #include <linux/version.h>
50 #include <linux/module.h>
51 #include <linux/kernel.h>
53 #include <linux/init.h>
54 #include <linux/major.h>
55 #include <linux/miscdevice.h>
56 #include <linux/proc_fs.h>
57 #include <linux/serial.h>
58 #include <linux/sched.h>
59 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
60 #include <linux/spinlock.h>
62 #include <asm/spinlock.h>
64 #include <linux/delay.h>
74 MODULE_DESCRIPTION("3780i Advanced Communications Processor (Mwave) driver");
75 MODULE_AUTHOR("Mike Sullivan and Paul Schroeder");
76 MODULE_LICENSE("GPL");
78 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
79 static int mwave_get_info(char *buf
, char **start
, off_t offset
, int len
);
81 static int mwave_read_proc(char *buf
, char **start
, off_t offset
, int xlen
, int unused
);
82 static struct proc_dir_entry mwave_proc
= {
83 0, /* unsigned short low_ino */
84 5, /* unsigned short namelen */
85 "mwave", /* const char *name */
86 S_IFREG
| S_IRUGO
, /* mode_t mode */
87 1, /* nlink_t nlink */
90 0, /* unsigned long size */
91 NULL
, /* struct inode_operations *ops */
92 &mwave_read_proc
/* int (*get_info) (...) */
97 * These parameters support the setting of MWave resources. Note that no
98 * checks are made against other devices (ie. superio) for conflicts.
99 * We'll depend on users using the tpctl utility to do that for now
102 int mwave_3780i_irq
= 0;
103 int mwave_3780i_io
= 0;
104 int mwave_uart_irq
= 0;
105 int mwave_uart_io
= 0;
106 MODULE_PARM(mwave_debug
, "i");
107 MODULE_PARM(mwave_3780i_irq
, "i");
108 MODULE_PARM(mwave_3780i_io
, "i");
109 MODULE_PARM(mwave_uart_irq
, "i");
110 MODULE_PARM(mwave_uart_io
, "i");
112 static int mwave_open(struct inode
*inode
, struct file
*file
);
113 static int mwave_close(struct inode
*inode
, struct file
*file
);
114 static int mwave_ioctl(struct inode
*inode
, struct file
*filp
,
115 unsigned int iocmd
, unsigned long ioarg
);
117 MWAVE_DEVICE_DATA mwave_s_mdd
;
119 static int mwave_open(struct inode
*inode
, struct file
*file
)
121 unsigned int retval
= 0;
123 PRINTK_3(TRACE_MWAVE
,
124 "mwavedd::mwave_open, entry inode %x file %x\n",
125 (int) inode
, (int) file
);
126 PRINTK_2(TRACE_MWAVE
,
127 "mwavedd::mwave_open, exit return retval %x\n", retval
);
132 static int mwave_close(struct inode
*inode
, struct file
*file
)
134 unsigned int retval
= 0;
136 PRINTK_3(TRACE_MWAVE
,
137 "mwavedd::mwave_close, entry inode %x file %x\n",
138 (int) inode
, (int) file
);
140 PRINTK_2(TRACE_MWAVE
, "mwavedd::mwave_close, exit retval %x\n",
146 static int mwave_ioctl(struct inode
*inode
, struct file
*file
,
147 unsigned int iocmd
, unsigned long ioarg
)
149 unsigned int retval
= 0;
150 pMWAVE_DEVICE_DATA pDrvData
= &mwave_s_mdd
;
152 PRINTK_5(TRACE_MWAVE
,
153 "mwavedd::mwave_ioctl, entry inode %x file %x cmd %x arg %x\n",
154 (int) inode
, (int) file
, iocmd
, (int) ioarg
);
159 PRINTK_1(TRACE_MWAVE
,
160 "mwavedd::mwave_ioctl, IOCTL_MW_RESET calling tp3780I_ResetDSP\n");
161 retval
= tp3780I_ResetDSP(&pDrvData
->rBDData
);
162 PRINTK_2(TRACE_MWAVE
,
163 "mwavedd::mwave_ioctl, IOCTL_MW_RESET retval %x from tp3780I_ResetDSP\n",
168 PRINTK_1(TRACE_MWAVE
,
169 "mwavedd::mwave_ioctl, IOCTL_MW_RUN calling tp3780I_StartDSP\n");
170 retval
= tp3780I_StartDSP(&pDrvData
->rBDData
);
171 PRINTK_2(TRACE_MWAVE
,
172 "mwavedd::mwave_ioctl, IOCTL_MW_RUN retval %x from tp3780I_StartDSP\n",
176 case IOCTL_MW_DSP_ABILITIES
: {
177 MW_ABILITIES rAbilities
;
179 PRINTK_1(TRACE_MWAVE
,
180 "mwavedd::mwave_ioctl, IOCTL_MW_DSP_ABILITIES calling tp3780I_QueryAbilities\n");
181 retval
= tp3780I_QueryAbilities(&pDrvData
->rBDData
, &rAbilities
);
182 PRINTK_2(TRACE_MWAVE
,
183 "mwavedd::mwave_ioctl, IOCTL_MW_DSP_ABILITIES retval %x from tp3780I_QueryAbilities\n",
186 if( copy_to_user((char *) ioarg
, (char *) &rAbilities
, sizeof(MW_ABILITIES
)) )
189 PRINTK_2(TRACE_MWAVE
,
190 "mwavedd::mwave_ioctl, IOCTL_MW_DSP_ABILITIES exit retval %x\n",
195 case IOCTL_MW_READ_DATA
:
196 case IOCTL_MW_READCLEAR_DATA
: {
197 MW_READWRITE rReadData
;
198 unsigned short *pusBuffer
= 0;
200 if( copy_from_user((char *) &rReadData
, (char *) ioarg
, sizeof(MW_READWRITE
)) )
202 pusBuffer
= (unsigned short *) (rReadData
.pBuf
);
204 PRINTK_4(TRACE_MWAVE
,
205 "mwavedd::mwave_ioctl IOCTL_MW_READ_DATA, size %lx, ioarg %lx pusBuffer %p\n",
206 rReadData
.ulDataLength
, ioarg
, pusBuffer
);
207 retval
= tp3780I_ReadWriteDspDStore(&pDrvData
->rBDData
, iocmd
,
208 (void *) pusBuffer
, rReadData
.ulDataLength
, rReadData
.usDspAddress
);
212 case IOCTL_MW_READ_INST
: {
213 MW_READWRITE rReadData
;
214 unsigned short *pusBuffer
= 0;
216 if( copy_from_user((char *) &rReadData
, (char *) ioarg
, sizeof(MW_READWRITE
)) )
218 pusBuffer
= (unsigned short *) (rReadData
.pBuf
);
220 PRINTK_4(TRACE_MWAVE
,
221 "mwavedd::mwave_ioctl IOCTL_MW_READ_INST, size %lx, ioarg %lx pusBuffer %p\n",
222 rReadData
.ulDataLength
/ 2, ioarg
,
224 retval
= tp3780I_ReadWriteDspDStore(&pDrvData
->rBDData
,
226 rReadData
.ulDataLength
/ 2,
227 rReadData
.usDspAddress
);
231 case IOCTL_MW_WRITE_DATA
: {
232 MW_READWRITE rWriteData
;
233 unsigned short *pusBuffer
= 0;
235 if( copy_from_user((char *) &rWriteData
, (char *) ioarg
, sizeof(MW_READWRITE
)) )
237 pusBuffer
= (unsigned short *) (rWriteData
.pBuf
);
239 PRINTK_4(TRACE_MWAVE
,
240 "mwavedd::mwave_ioctl IOCTL_MW_WRITE_DATA, size %lx, ioarg %lx pusBuffer %p\n",
241 rWriteData
.ulDataLength
, ioarg
,
243 retval
= tp3780I_ReadWriteDspDStore(&pDrvData
->rBDData
, iocmd
,
244 pusBuffer
, rWriteData
.ulDataLength
, rWriteData
.usDspAddress
);
248 case IOCTL_MW_WRITE_INST
: {
249 MW_READWRITE rWriteData
;
250 unsigned short *pusBuffer
= 0;
252 if( copy_from_user((char *) &rWriteData
, (char *) ioarg
, sizeof(MW_READWRITE
)) )
254 pusBuffer
= (unsigned short *) (rWriteData
.pBuf
);
256 PRINTK_4(TRACE_MWAVE
,
257 "mwavedd::mwave_ioctl IOCTL_MW_WRITE_INST, size %lx, ioarg %lx pusBuffer %p\n",
258 rWriteData
.ulDataLength
, ioarg
,
260 retval
= tp3780I_ReadWriteDspIStore(&pDrvData
->rBDData
, iocmd
,
261 pusBuffer
, rWriteData
.ulDataLength
, rWriteData
.usDspAddress
);
265 case IOCTL_MW_REGISTER_IPC
: {
266 unsigned int ipcnum
= (unsigned int) ioarg
;
268 PRINTK_3(TRACE_MWAVE
,
269 "mwavedd::mwave_ioctl IOCTL_MW_REGISTER_IPC ipcnum %x entry usIntCount %x\n",
271 pDrvData
->IPCs
[ipcnum
].usIntCount
);
274 PRINTK_ERROR(KERN_ERR_MWAVE
"mwavedd::mwave_ioctl: IOCTL_MW_REGISTER_IPC: Error: Invalid ipcnum %x\n", ipcnum
);
277 pDrvData
->IPCs
[ipcnum
].bIsHere
= FALSE
;
278 pDrvData
->IPCs
[ipcnum
].bIsEnabled
= TRUE
;
279 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
281 current
->priority
= 0x28; /* boost to provide priority timing */
284 PRINTK_2(TRACE_MWAVE
,
285 "mwavedd::mwave_ioctl IOCTL_MW_REGISTER_IPC ipcnum %x exit\n",
290 case IOCTL_MW_GET_IPC
: {
291 unsigned int ipcnum
= (unsigned int) ioarg
;
292 spinlock_t ipc_lock
= SPIN_LOCK_UNLOCKED
;
295 PRINTK_3(TRACE_MWAVE
,
296 "mwavedd::mwave_ioctl IOCTL_MW_GET_IPC ipcnum %x, usIntCount %x\n",
298 pDrvData
->IPCs
[ipcnum
].usIntCount
);
300 PRINTK_ERROR(KERN_ERR_MWAVE
"mwavedd::mwave_ioctl: IOCTL_MW_GET_IPC: Error: Invalid ipcnum %x\n", ipcnum
);
304 if (pDrvData
->IPCs
[ipcnum
].bIsEnabled
== TRUE
) {
305 PRINTK_2(TRACE_MWAVE
,
306 "mwavedd::mwave_ioctl, thread for ipc %x going to sleep\n",
309 spin_lock_irqsave(&ipc_lock
, flags
);
310 /* check whether an event was signalled by */
311 /* the interrupt handler while we were gone */
312 if (pDrvData
->IPCs
[ipcnum
].usIntCount
== 1) { /* first int has occurred (race condition) */
313 pDrvData
->IPCs
[ipcnum
].usIntCount
= 2; /* first int has been handled */
314 spin_unlock_irqrestore(&ipc_lock
, flags
);
315 PRINTK_2(TRACE_MWAVE
,
316 "mwavedd::mwave_ioctl IOCTL_MW_GET_IPC ipcnum %x handling first int\n",
318 } else { /* either 1st int has not yet occurred, or we have already handled the first int */
319 pDrvData
->IPCs
[ipcnum
].bIsHere
= TRUE
;
320 interruptible_sleep_on(&pDrvData
->IPCs
[ipcnum
].ipc_wait_queue
);
321 pDrvData
->IPCs
[ipcnum
].bIsHere
= FALSE
;
322 if (pDrvData
->IPCs
[ipcnum
].usIntCount
== 1) {
323 pDrvData
->IPCs
[ipcnum
].
326 spin_unlock_irqrestore(&ipc_lock
, flags
);
327 PRINTK_2(TRACE_MWAVE
,
328 "mwavedd::mwave_ioctl IOCTL_MW_GET_IPC ipcnum %x woke up and returning to application\n",
331 PRINTK_2(TRACE_MWAVE
,
332 "mwavedd::mwave_ioctl IOCTL_MW_GET_IPC, returning thread for ipc %x processing\n",
338 case IOCTL_MW_UNREGISTER_IPC
: {
339 unsigned int ipcnum
= (unsigned int) ioarg
;
341 PRINTK_2(TRACE_MWAVE
,
342 "mwavedd::mwave_ioctl IOCTL_MW_UNREGISTER_IPC ipcnum %x\n",
345 PRINTK_ERROR(KERN_ERR_MWAVE
"mwavedd::mwave_ioctl: IOCTL_MW_UNREGISTER_IPC: Error: Invalid ipcnum %x\n", ipcnum
);
348 if (pDrvData
->IPCs
[ipcnum
].bIsEnabled
== TRUE
) {
349 pDrvData
->IPCs
[ipcnum
].bIsEnabled
= FALSE
;
350 if (pDrvData
->IPCs
[ipcnum
].bIsHere
== TRUE
) {
351 wake_up_interruptible(&pDrvData
->IPCs
[ipcnum
].ipc_wait_queue
);
358 PRINTK_ERROR(KERN_ERR_MWAVE
"mwavedd::mwave_ioctl: Error: Unrecognized iocmd %x\n", iocmd
);
363 PRINTK_2(TRACE_MWAVE
, "mwavedd::mwave_ioctl, exit retval %x\n", retval
);
369 static ssize_t
mwave_read(struct file
*file
, char *buf
, size_t count
,
372 PRINTK_5(TRACE_MWAVE
,
373 "mwavedd::mwave_read entry file %p, buf %p, count %x ppos %p\n",
374 file
, buf
, count
, ppos
);
380 static ssize_t
mwave_write(struct file
*file
, const char *buf
,
381 size_t count
, loff_t
* ppos
)
383 PRINTK_5(TRACE_MWAVE
,
384 "mwavedd::mwave_write entry file %p, buf %p, count %x ppos %p\n",
385 file
, buf
, count
, ppos
);
391 static int register_serial_portandirq(unsigned int port
, int irq
)
393 struct serial_struct serial
;
403 PRINTK_ERROR(KERN_ERR_MWAVE
"mwavedd::register_serial_portandirq: Error: Illegal port %x\n", port
);
416 PRINTK_ERROR(KERN_ERR_MWAVE
"mwavedd::register_serial_portandirq: Error: Illegal irq %x\n", irq
);
421 memset(&serial
, 0, sizeof(serial
));
424 serial
.flags
= ASYNC_SHARE_IRQ
;
426 return register_serial(&serial
);
430 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
431 static struct file_operations mwave_fops
= {
440 static struct file_operations mwave_fops
= {
442 mwave_read
, /* read */
443 mwave_write
, /* write */
446 mwave_ioctl
, /* ioctl */
448 mwave_open
, /* open */
450 mwave_close
/* release */
454 static struct miscdevice mwave_misc_dev
= { MWAVE_MINOR
, "mwave", &mwave_fops
};
457 * mwave_init is called on module load
459 * mwave_exit is called on module unload
460 * mwave_exit is also used to clean up after an aborted mwave_init
462 static void mwave_exit(void)
464 pMWAVE_DEVICE_DATA pDrvData
= &mwave_s_mdd
;
466 PRINTK_1(TRACE_MWAVE
, "mwavedd::mwave_exit entry\n");
468 if (pDrvData
->bProcEntryCreated
) {
469 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
470 remove_proc_entry("mwave", NULL
);
472 proc_unregister(&proc_root
, mwave_proc
.low_ino
);
475 if ( pDrvData
->sLine
>= 0 ) {
476 unregister_serial(pDrvData
->sLine
);
478 if (pDrvData
->bMwaveDevRegistered
) {
479 misc_deregister(&mwave_misc_dev
);
481 if (pDrvData
->bDSPEnabled
) {
482 tp3780I_DisableDSP(&pDrvData
->rBDData
);
484 if (pDrvData
->bResourcesClaimed
) {
485 tp3780I_ReleaseResources(&pDrvData
->rBDData
);
487 if (pDrvData
->bBDInitialized
) {
488 tp3780I_Cleanup(&pDrvData
->rBDData
);
491 PRINTK_1(TRACE_MWAVE
, "mwavedd::mwave_exit exit\n");
494 module_exit(mwave_exit
);
496 static int __init
mwave_init(void)
500 unsigned int resultMiscRegister
;
501 pMWAVE_DEVICE_DATA pDrvData
= &mwave_s_mdd
;
503 memset(&mwave_s_mdd
, 0, sizeof(MWAVE_DEVICE_DATA
));
505 PRINTK_1(TRACE_MWAVE
, "mwavedd::mwave_init entry\n");
507 pDrvData
->bBDInitialized
= FALSE
;
508 pDrvData
->bResourcesClaimed
= FALSE
;
509 pDrvData
->bDSPEnabled
= FALSE
;
510 pDrvData
->bDSPReset
= FALSE
;
511 pDrvData
->bMwaveDevRegistered
= FALSE
;
512 pDrvData
->sLine
= -1;
513 pDrvData
->bProcEntryCreated
= FALSE
;
515 for (i
= 0; i
< 16; i
++) {
516 pDrvData
->IPCs
[i
].bIsEnabled
= FALSE
;
517 pDrvData
->IPCs
[i
].bIsHere
= FALSE
;
518 pDrvData
->IPCs
[i
].usIntCount
= 0; /* no ints received yet */
519 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
520 init_waitqueue_head(&pDrvData
->IPCs
[i
].ipc_wait_queue
);
524 retval
= tp3780I_InitializeBoardData(&pDrvData
->rBDData
);
525 PRINTK_2(TRACE_MWAVE
,
526 "mwavedd::mwave_init, return from tp3780I_InitializeBoardData retval %x\n",
529 PRINTK_ERROR(KERN_ERR_MWAVE
"mwavedd::mwave_init: Error: Failed to initialize board data\n");
532 pDrvData
->bBDInitialized
= TRUE
;
534 retval
= tp3780I_CalcResources(&pDrvData
->rBDData
);
535 PRINTK_2(TRACE_MWAVE
,
536 "mwavedd::mwave_init, return from tp3780I_CalcResources retval %x\n",
539 PRINTK_ERROR(KERN_ERR_MWAVE
"mwavedd:mwave_init: Error: Failed to calculate resources\n");
543 retval
= tp3780I_ClaimResources(&pDrvData
->rBDData
);
544 PRINTK_2(TRACE_MWAVE
,
545 "mwavedd::mwave_init, return from tp3780I_ClaimResources retval %x\n",
548 PRINTK_ERROR(KERN_ERR_MWAVE
"mwavedd:mwave_init: Error: Failed to claim resources\n");
551 pDrvData
->bResourcesClaimed
= TRUE
;
553 retval
= tp3780I_EnableDSP(&pDrvData
->rBDData
);
554 PRINTK_2(TRACE_MWAVE
,
555 "mwavedd::mwave_init, return from tp3780I_EnableDSP retval %x\n",
558 PRINTK_ERROR(KERN_ERR_MWAVE
"mwavedd:mwave_init: Error: Failed to enable DSP\n");
561 pDrvData
->bDSPEnabled
= TRUE
;
563 resultMiscRegister
= misc_register(&mwave_misc_dev
);
564 if (resultMiscRegister
< 0) {
565 PRINTK_ERROR(KERN_ERR_MWAVE
"mwavedd:mwave_init: Error: Failed to register misc device\n");
568 pDrvData
->bMwaveDevRegistered
= TRUE
;
570 pDrvData
->sLine
= register_serial_portandirq(
571 pDrvData
->rBDData
.rDspSettings
.usUartBaseIO
,
572 pDrvData
->rBDData
.rDspSettings
.usUartIrq
574 if (pDrvData
->sLine
< 0) {
575 PRINTK_ERROR(KERN_ERR_MWAVE
"mwavedd:mwave_init: Error: Failed to register serial driver\n");
578 /* uart is registered */
581 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
582 !create_proc_info_entry("mwave", 0, NULL
, mwave_get_info
)
584 proc_register(&proc_root
, &mwave_proc
)
587 PRINTK_ERROR(KERN_ERR_MWAVE
"mwavedd::mwave_init: Error: Failed to register /proc/mwave\n");
590 pDrvData
->bProcEntryCreated
= TRUE
;
596 PRINTK_ERROR(KERN_ERR_MWAVE
"mwavedd::mwave_init: Error: Failed to initialize\n");
597 mwave_exit(); /* clean up */
602 module_init(mwave_init
);
606 * proc entry stuff added by Ian Pilcher <pilcher@us.ibm.com>
609 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
610 static int mwave_get_info(char *buf
, char **start
, off_t offset
, int len
)
612 DSP_3780I_CONFIG_SETTINGS
*pSettings
= &mwave_s_mdd
.rBDData
.rDspSettings
;
616 out
+= sprintf(out
, "3780i_IRQ %i\n", pSettings
->usDspIrq
);
617 out
+= sprintf(out
, "3780i_DMA %i\n", pSettings
->usDspDma
);
618 out
+= sprintf(out
, "3780i_IO %#.4x\n", pSettings
->usDspBaseIO
);
619 out
+= sprintf(out
, "UART_IRQ %i\n", pSettings
->usUartIrq
);
620 out
+= sprintf(out
, "UART_IO %#.4x\n", pSettings
->usUartBaseIO
);
624 #else /* kernel version < 2.4.0 */
625 static int mwave_read_proc(char *buf
, char **start
, off_t offset
,
626 int xlen
, int unused
)
628 DSP_3780I_CONFIG_SETTINGS
*pSettings
= &mwave_s_mdd
.rBDData
.rDspSettings
;
631 len
= sprintf(buf
, "3780i_IRQ %i\n", pSettings
->usDspIrq
);
632 len
+= sprintf(&buf
[len
], "3780i_DMA %i\n", pSettings
->usDspDma
);
633 len
+= sprintf(&buf
[len
], "3780i_IO %#.4x\n", pSettings
->usDspBaseIO
);
634 len
+= sprintf(&buf
[len
], "UART_IRQ %i\n", pSettings
->usUartIrq
);
635 len
+= sprintf(&buf
[len
], "UART_IO %#.4x\n", pSettings
->usUartBaseIO
);