0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049 #include <linux/module.h>
0050 #include <linux/kernel.h>
0051 #include <linux/fs.h>
0052 #include <linux/init.h>
0053 #include <linux/major.h>
0054 #include <linux/miscdevice.h>
0055 #include <linux/device.h>
0056 #include <linux/serial.h>
0057 #include <linux/sched.h>
0058 #include <linux/spinlock.h>
0059 #include <linux/mutex.h>
0060 #include <linux/delay.h>
0061 #include <linux/serial_8250.h>
0062 #include <linux/nospec.h>
0063 #include "smapi.h"
0064 #include "mwavedd.h"
0065 #include "3780i.h"
0066 #include "tp3780i.h"
0067
0068 MODULE_DESCRIPTION("3780i Advanced Communications Processor (Mwave) driver");
0069 MODULE_AUTHOR("Mike Sullivan and Paul Schroeder");
0070 MODULE_LICENSE("GPL");
0071
0072
0073
0074
0075
0076
0077 static DEFINE_MUTEX(mwave_mutex);
0078 int mwave_debug = 0;
0079 int mwave_3780i_irq = 0;
0080 int mwave_3780i_io = 0;
0081 int mwave_uart_irq = 0;
0082 int mwave_uart_io = 0;
0083 module_param(mwave_debug, int, 0);
0084 module_param_hw(mwave_3780i_irq, int, irq, 0);
0085 module_param_hw(mwave_3780i_io, int, ioport, 0);
0086 module_param_hw(mwave_uart_irq, int, irq, 0);
0087 module_param_hw(mwave_uart_io, int, ioport, 0);
0088
0089 static int mwave_open(struct inode *inode, struct file *file);
0090 static int mwave_close(struct inode *inode, struct file *file);
0091 static long mwave_ioctl(struct file *filp, unsigned int iocmd,
0092 unsigned long ioarg);
0093
0094 MWAVE_DEVICE_DATA mwave_s_mdd;
0095
0096 static int mwave_open(struct inode *inode, struct file *file)
0097 {
0098 unsigned int retval = 0;
0099
0100 PRINTK_3(TRACE_MWAVE,
0101 "mwavedd::mwave_open, entry inode %p file %p\n",
0102 inode, file);
0103 PRINTK_2(TRACE_MWAVE,
0104 "mwavedd::mwave_open, exit return retval %x\n", retval);
0105
0106 return retval;
0107 }
0108
0109 static int mwave_close(struct inode *inode, struct file *file)
0110 {
0111 unsigned int retval = 0;
0112
0113 PRINTK_3(TRACE_MWAVE,
0114 "mwavedd::mwave_close, entry inode %p file %p\n",
0115 inode, file);
0116
0117 PRINTK_2(TRACE_MWAVE, "mwavedd::mwave_close, exit retval %x\n",
0118 retval);
0119
0120 return retval;
0121 }
0122
0123 static long mwave_ioctl(struct file *file, unsigned int iocmd,
0124 unsigned long ioarg)
0125 {
0126 unsigned int retval = 0;
0127 pMWAVE_DEVICE_DATA pDrvData = &mwave_s_mdd;
0128 void __user *arg = (void __user *)ioarg;
0129
0130 PRINTK_4(TRACE_MWAVE,
0131 "mwavedd::mwave_ioctl, entry file %p cmd %x arg %x\n",
0132 file, iocmd, (int) ioarg);
0133
0134 switch (iocmd) {
0135
0136 case IOCTL_MW_RESET:
0137 PRINTK_1(TRACE_MWAVE,
0138 "mwavedd::mwave_ioctl, IOCTL_MW_RESET"
0139 " calling tp3780I_ResetDSP\n");
0140 mutex_lock(&mwave_mutex);
0141 retval = tp3780I_ResetDSP(&pDrvData->rBDData);
0142 mutex_unlock(&mwave_mutex);
0143 PRINTK_2(TRACE_MWAVE,
0144 "mwavedd::mwave_ioctl, IOCTL_MW_RESET"
0145 " retval %x from tp3780I_ResetDSP\n",
0146 retval);
0147 break;
0148
0149 case IOCTL_MW_RUN:
0150 PRINTK_1(TRACE_MWAVE,
0151 "mwavedd::mwave_ioctl, IOCTL_MW_RUN"
0152 " calling tp3780I_StartDSP\n");
0153 mutex_lock(&mwave_mutex);
0154 retval = tp3780I_StartDSP(&pDrvData->rBDData);
0155 mutex_unlock(&mwave_mutex);
0156 PRINTK_2(TRACE_MWAVE,
0157 "mwavedd::mwave_ioctl, IOCTL_MW_RUN"
0158 " retval %x from tp3780I_StartDSP\n",
0159 retval);
0160 break;
0161
0162 case IOCTL_MW_DSP_ABILITIES: {
0163 MW_ABILITIES rAbilities;
0164
0165 PRINTK_1(TRACE_MWAVE,
0166 "mwavedd::mwave_ioctl,"
0167 " IOCTL_MW_DSP_ABILITIES calling"
0168 " tp3780I_QueryAbilities\n");
0169 mutex_lock(&mwave_mutex);
0170 retval = tp3780I_QueryAbilities(&pDrvData->rBDData,
0171 &rAbilities);
0172 mutex_unlock(&mwave_mutex);
0173 PRINTK_2(TRACE_MWAVE,
0174 "mwavedd::mwave_ioctl, IOCTL_MW_DSP_ABILITIES"
0175 " retval %x from tp3780I_QueryAbilities\n",
0176 retval);
0177 if (retval == 0) {
0178 if( copy_to_user(arg, &rAbilities,
0179 sizeof(MW_ABILITIES)) )
0180 return -EFAULT;
0181 }
0182 PRINTK_2(TRACE_MWAVE,
0183 "mwavedd::mwave_ioctl, IOCTL_MW_DSP_ABILITIES"
0184 " exit retval %x\n",
0185 retval);
0186 }
0187 break;
0188
0189 case IOCTL_MW_READ_DATA:
0190 case IOCTL_MW_READCLEAR_DATA: {
0191 MW_READWRITE rReadData;
0192 unsigned short __user *pusBuffer = NULL;
0193
0194 if( copy_from_user(&rReadData, arg,
0195 sizeof(MW_READWRITE)) )
0196 return -EFAULT;
0197 pusBuffer = (unsigned short __user *) (rReadData.pBuf);
0198
0199 PRINTK_4(TRACE_MWAVE,
0200 "mwavedd::mwave_ioctl IOCTL_MW_READ_DATA,"
0201 " size %lx, ioarg %lx pusBuffer %p\n",
0202 rReadData.ulDataLength, ioarg, pusBuffer);
0203 mutex_lock(&mwave_mutex);
0204 retval = tp3780I_ReadWriteDspDStore(&pDrvData->rBDData,
0205 iocmd,
0206 pusBuffer,
0207 rReadData.ulDataLength,
0208 rReadData.usDspAddress);
0209 mutex_unlock(&mwave_mutex);
0210 }
0211 break;
0212
0213 case IOCTL_MW_READ_INST: {
0214 MW_READWRITE rReadData;
0215 unsigned short __user *pusBuffer = NULL;
0216
0217 if( copy_from_user(&rReadData, arg,
0218 sizeof(MW_READWRITE)) )
0219 return -EFAULT;
0220 pusBuffer = (unsigned short __user *) (rReadData.pBuf);
0221
0222 PRINTK_4(TRACE_MWAVE,
0223 "mwavedd::mwave_ioctl IOCTL_MW_READ_INST,"
0224 " size %lx, ioarg %lx pusBuffer %p\n",
0225 rReadData.ulDataLength / 2, ioarg,
0226 pusBuffer);
0227 mutex_lock(&mwave_mutex);
0228 retval = tp3780I_ReadWriteDspDStore(&pDrvData->rBDData,
0229 iocmd, pusBuffer,
0230 rReadData.ulDataLength / 2,
0231 rReadData.usDspAddress);
0232 mutex_unlock(&mwave_mutex);
0233 }
0234 break;
0235
0236 case IOCTL_MW_WRITE_DATA: {
0237 MW_READWRITE rWriteData;
0238 unsigned short __user *pusBuffer = NULL;
0239
0240 if( copy_from_user(&rWriteData, arg,
0241 sizeof(MW_READWRITE)) )
0242 return -EFAULT;
0243 pusBuffer = (unsigned short __user *) (rWriteData.pBuf);
0244
0245 PRINTK_4(TRACE_MWAVE,
0246 "mwavedd::mwave_ioctl IOCTL_MW_WRITE_DATA,"
0247 " size %lx, ioarg %lx pusBuffer %p\n",
0248 rWriteData.ulDataLength, ioarg,
0249 pusBuffer);
0250 mutex_lock(&mwave_mutex);
0251 retval = tp3780I_ReadWriteDspDStore(&pDrvData->rBDData,
0252 iocmd, pusBuffer,
0253 rWriteData.ulDataLength,
0254 rWriteData.usDspAddress);
0255 mutex_unlock(&mwave_mutex);
0256 }
0257 break;
0258
0259 case IOCTL_MW_WRITE_INST: {
0260 MW_READWRITE rWriteData;
0261 unsigned short __user *pusBuffer = NULL;
0262
0263 if( copy_from_user(&rWriteData, arg,
0264 sizeof(MW_READWRITE)) )
0265 return -EFAULT;
0266 pusBuffer = (unsigned short __user *)(rWriteData.pBuf);
0267
0268 PRINTK_4(TRACE_MWAVE,
0269 "mwavedd::mwave_ioctl IOCTL_MW_WRITE_INST,"
0270 " size %lx, ioarg %lx pusBuffer %p\n",
0271 rWriteData.ulDataLength, ioarg,
0272 pusBuffer);
0273 mutex_lock(&mwave_mutex);
0274 retval = tp3780I_ReadWriteDspIStore(&pDrvData->rBDData,
0275 iocmd, pusBuffer,
0276 rWriteData.ulDataLength,
0277 rWriteData.usDspAddress);
0278 mutex_unlock(&mwave_mutex);
0279 }
0280 break;
0281
0282 case IOCTL_MW_REGISTER_IPC: {
0283 unsigned int ipcnum = (unsigned int) ioarg;
0284
0285 if (ipcnum >= ARRAY_SIZE(pDrvData->IPCs)) {
0286 PRINTK_ERROR(KERN_ERR_MWAVE
0287 "mwavedd::mwave_ioctl:"
0288 " IOCTL_MW_REGISTER_IPC:"
0289 " Error: Invalid ipcnum %x\n",
0290 ipcnum);
0291 return -EINVAL;
0292 }
0293 ipcnum = array_index_nospec(ipcnum,
0294 ARRAY_SIZE(pDrvData->IPCs));
0295 PRINTK_3(TRACE_MWAVE,
0296 "mwavedd::mwave_ioctl IOCTL_MW_REGISTER_IPC"
0297 " ipcnum %x entry usIntCount %x\n",
0298 ipcnum,
0299 pDrvData->IPCs[ipcnum].usIntCount);
0300
0301 mutex_lock(&mwave_mutex);
0302 pDrvData->IPCs[ipcnum].bIsHere = false;
0303 pDrvData->IPCs[ipcnum].bIsEnabled = true;
0304 mutex_unlock(&mwave_mutex);
0305
0306 PRINTK_2(TRACE_MWAVE,
0307 "mwavedd::mwave_ioctl IOCTL_MW_REGISTER_IPC"
0308 " ipcnum %x exit\n",
0309 ipcnum);
0310 }
0311 break;
0312
0313 case IOCTL_MW_GET_IPC: {
0314 unsigned int ipcnum = (unsigned int) ioarg;
0315
0316 if (ipcnum >= ARRAY_SIZE(pDrvData->IPCs)) {
0317 PRINTK_ERROR(KERN_ERR_MWAVE
0318 "mwavedd::mwave_ioctl:"
0319 " IOCTL_MW_GET_IPC: Error:"
0320 " Invalid ipcnum %x\n", ipcnum);
0321 return -EINVAL;
0322 }
0323 ipcnum = array_index_nospec(ipcnum,
0324 ARRAY_SIZE(pDrvData->IPCs));
0325 PRINTK_3(TRACE_MWAVE,
0326 "mwavedd::mwave_ioctl IOCTL_MW_GET_IPC"
0327 " ipcnum %x, usIntCount %x\n",
0328 ipcnum,
0329 pDrvData->IPCs[ipcnum].usIntCount);
0330
0331 mutex_lock(&mwave_mutex);
0332 if (pDrvData->IPCs[ipcnum].bIsEnabled == true) {
0333 DECLARE_WAITQUEUE(wait, current);
0334
0335 PRINTK_2(TRACE_MWAVE,
0336 "mwavedd::mwave_ioctl, thread for"
0337 " ipc %x going to sleep\n",
0338 ipcnum);
0339 add_wait_queue(&pDrvData->IPCs[ipcnum].ipc_wait_queue, &wait);
0340 pDrvData->IPCs[ipcnum].bIsHere = true;
0341 set_current_state(TASK_INTERRUPTIBLE);
0342
0343
0344 if (pDrvData->IPCs[ipcnum].usIntCount == 1) {
0345 pDrvData->IPCs[ipcnum].usIntCount = 2;
0346 PRINTK_2(TRACE_MWAVE,
0347 "mwavedd::mwave_ioctl"
0348 " IOCTL_MW_GET_IPC ipcnum %x"
0349 " handling first int\n",
0350 ipcnum);
0351 } else {
0352 schedule();
0353 if (pDrvData->IPCs[ipcnum].usIntCount == 1) {
0354 pDrvData->IPCs[ipcnum].usIntCount = 2;
0355 }
0356 PRINTK_2(TRACE_MWAVE,
0357 "mwavedd::mwave_ioctl"
0358 " IOCTL_MW_GET_IPC ipcnum %x"
0359 " woke up and returning to"
0360 " application\n",
0361 ipcnum);
0362 }
0363 pDrvData->IPCs[ipcnum].bIsHere = false;
0364 remove_wait_queue(&pDrvData->IPCs[ipcnum].ipc_wait_queue, &wait);
0365 set_current_state(TASK_RUNNING);
0366 PRINTK_2(TRACE_MWAVE,
0367 "mwavedd::mwave_ioctl IOCTL_MW_GET_IPC,"
0368 " returning thread for ipc %x"
0369 " processing\n",
0370 ipcnum);
0371 }
0372 mutex_unlock(&mwave_mutex);
0373 }
0374 break;
0375
0376 case IOCTL_MW_UNREGISTER_IPC: {
0377 unsigned int ipcnum = (unsigned int) ioarg;
0378
0379 PRINTK_2(TRACE_MWAVE,
0380 "mwavedd::mwave_ioctl IOCTL_MW_UNREGISTER_IPC"
0381 " ipcnum %x\n",
0382 ipcnum);
0383 if (ipcnum >= ARRAY_SIZE(pDrvData->IPCs)) {
0384 PRINTK_ERROR(KERN_ERR_MWAVE
0385 "mwavedd::mwave_ioctl:"
0386 " IOCTL_MW_UNREGISTER_IPC:"
0387 " Error: Invalid ipcnum %x\n",
0388 ipcnum);
0389 return -EINVAL;
0390 }
0391 ipcnum = array_index_nospec(ipcnum,
0392 ARRAY_SIZE(pDrvData->IPCs));
0393 mutex_lock(&mwave_mutex);
0394 if (pDrvData->IPCs[ipcnum].bIsEnabled == true) {
0395 pDrvData->IPCs[ipcnum].bIsEnabled = false;
0396 if (pDrvData->IPCs[ipcnum].bIsHere == true) {
0397 wake_up_interruptible(&pDrvData->IPCs[ipcnum].ipc_wait_queue);
0398 }
0399 }
0400 mutex_unlock(&mwave_mutex);
0401 }
0402 break;
0403
0404 default:
0405 return -ENOTTY;
0406 }
0407
0408 PRINTK_2(TRACE_MWAVE, "mwavedd::mwave_ioctl, exit retval %x\n", retval);
0409
0410 return retval;
0411 }
0412
0413
0414 static ssize_t mwave_read(struct file *file, char __user *buf, size_t count,
0415 loff_t * ppos)
0416 {
0417 PRINTK_5(TRACE_MWAVE,
0418 "mwavedd::mwave_read entry file %p, buf %p, count %zx ppos %p\n",
0419 file, buf, count, ppos);
0420
0421 return -EINVAL;
0422 }
0423
0424
0425 static ssize_t mwave_write(struct file *file, const char __user *buf,
0426 size_t count, loff_t * ppos)
0427 {
0428 PRINTK_5(TRACE_MWAVE,
0429 "mwavedd::mwave_write entry file %p, buf %p,"
0430 " count %zx ppos %p\n",
0431 file, buf, count, ppos);
0432
0433 return -EINVAL;
0434 }
0435
0436
0437 static int register_serial_portandirq(unsigned int port, int irq)
0438 {
0439 struct uart_8250_port uart;
0440
0441 switch ( port ) {
0442 case 0x3f8:
0443 case 0x2f8:
0444 case 0x3e8:
0445 case 0x2e8:
0446
0447 break;
0448 default:
0449 PRINTK_ERROR(KERN_ERR_MWAVE
0450 "mwavedd::register_serial_portandirq:"
0451 " Error: Illegal port %x\n", port );
0452 return -1;
0453 }
0454
0455
0456 switch ( irq ) {
0457 case 3:
0458 case 4:
0459 case 5:
0460 case 7:
0461
0462 break;
0463 default:
0464 PRINTK_ERROR(KERN_ERR_MWAVE
0465 "mwavedd::register_serial_portandirq:"
0466 " Error: Illegal irq %x\n", irq );
0467 return -1;
0468 }
0469
0470
0471 memset(&uart, 0, sizeof(uart));
0472
0473 uart.port.uartclk = 1843200;
0474 uart.port.iobase = port;
0475 uart.port.irq = irq;
0476 uart.port.iotype = UPIO_PORT;
0477 uart.port.flags = UPF_SHARE_IRQ;
0478 return serial8250_register_8250_port(&uart);
0479 }
0480
0481
0482 static const struct file_operations mwave_fops = {
0483 .owner = THIS_MODULE,
0484 .read = mwave_read,
0485 .write = mwave_write,
0486 .unlocked_ioctl = mwave_ioctl,
0487 .open = mwave_open,
0488 .release = mwave_close,
0489 .llseek = default_llseek,
0490 };
0491
0492
0493 static struct miscdevice mwave_misc_dev = { MWAVE_MINOR, "mwave", &mwave_fops };
0494
0495 #if 0
0496
0497
0498
0499
0500 struct device mwave_device;
0501
0502
0503 #define mwave_show_function(attr_name, format_string, field) \
0504 static ssize_t mwave_show_##attr_name(struct device *dev, struct device_attribute *attr, char *buf) \
0505 { \
0506 DSP_3780I_CONFIG_SETTINGS *pSettings = \
0507 &mwave_s_mdd.rBDData.rDspSettings; \
0508 return sprintf(buf, format_string, pSettings->field); \
0509 }
0510
0511
0512 #define mwave_dev_rd_attr(attr_name, format_string, field) \
0513 mwave_show_function(attr_name, format_string, field) \
0514 static DEVICE_ATTR(attr_name, S_IRUGO, mwave_show_##attr_name, NULL)
0515
0516 mwave_dev_rd_attr (3780i_dma, "%i\n", usDspDma);
0517 mwave_dev_rd_attr (3780i_irq, "%i\n", usDspIrq);
0518 mwave_dev_rd_attr (3780i_io, "%#.4x\n", usDspBaseIO);
0519 mwave_dev_rd_attr (uart_irq, "%i\n", usUartIrq);
0520 mwave_dev_rd_attr (uart_io, "%#.4x\n", usUartBaseIO);
0521
0522 static struct device_attribute * const mwave_dev_attrs[] = {
0523 &dev_attr_3780i_dma,
0524 &dev_attr_3780i_irq,
0525 &dev_attr_3780i_io,
0526 &dev_attr_uart_irq,
0527 &dev_attr_uart_io,
0528 };
0529 #endif
0530
0531
0532
0533
0534
0535
0536
0537 static void mwave_exit(void)
0538 {
0539 pMWAVE_DEVICE_DATA pDrvData = &mwave_s_mdd;
0540
0541 PRINTK_1(TRACE_MWAVE, "mwavedd::mwave_exit entry\n");
0542
0543 #if 0
0544 for (i = 0; i < pDrvData->nr_registered_attrs; i++)
0545 device_remove_file(&mwave_device, mwave_dev_attrs[i]);
0546 pDrvData->nr_registered_attrs = 0;
0547
0548 if (pDrvData->device_registered) {
0549 device_unregister(&mwave_device);
0550 pDrvData->device_registered = false;
0551 }
0552 #endif
0553
0554 if ( pDrvData->sLine >= 0 ) {
0555 serial8250_unregister_port(pDrvData->sLine);
0556 }
0557 if (pDrvData->bMwaveDevRegistered) {
0558 misc_deregister(&mwave_misc_dev);
0559 }
0560 if (pDrvData->bDSPEnabled) {
0561 tp3780I_DisableDSP(&pDrvData->rBDData);
0562 }
0563 if (pDrvData->bResourcesClaimed) {
0564 tp3780I_ReleaseResources(&pDrvData->rBDData);
0565 }
0566 if (pDrvData->bBDInitialized) {
0567 tp3780I_Cleanup(&pDrvData->rBDData);
0568 }
0569
0570 PRINTK_1(TRACE_MWAVE, "mwavedd::mwave_exit exit\n");
0571 }
0572
0573 module_exit(mwave_exit);
0574
0575 static int __init mwave_init(void)
0576 {
0577 int i;
0578 int retval = 0;
0579 pMWAVE_DEVICE_DATA pDrvData = &mwave_s_mdd;
0580
0581 PRINTK_1(TRACE_MWAVE, "mwavedd::mwave_init entry\n");
0582
0583 memset(&mwave_s_mdd, 0, sizeof(MWAVE_DEVICE_DATA));
0584
0585 pDrvData->bBDInitialized = false;
0586 pDrvData->bResourcesClaimed = false;
0587 pDrvData->bDSPEnabled = false;
0588 pDrvData->bDSPReset = false;
0589 pDrvData->bMwaveDevRegistered = false;
0590 pDrvData->sLine = -1;
0591
0592 for (i = 0; i < ARRAY_SIZE(pDrvData->IPCs); i++) {
0593 pDrvData->IPCs[i].bIsEnabled = false;
0594 pDrvData->IPCs[i].bIsHere = false;
0595 pDrvData->IPCs[i].usIntCount = 0;
0596 init_waitqueue_head(&pDrvData->IPCs[i].ipc_wait_queue);
0597 }
0598
0599 retval = tp3780I_InitializeBoardData(&pDrvData->rBDData);
0600 PRINTK_2(TRACE_MWAVE,
0601 "mwavedd::mwave_init, return from tp3780I_InitializeBoardData"
0602 " retval %x\n",
0603 retval);
0604 if (retval) {
0605 PRINTK_ERROR(KERN_ERR_MWAVE
0606 "mwavedd::mwave_init: Error:"
0607 " Failed to initialize board data\n");
0608 goto cleanup_error;
0609 }
0610 pDrvData->bBDInitialized = true;
0611
0612 retval = tp3780I_CalcResources(&pDrvData->rBDData);
0613 PRINTK_2(TRACE_MWAVE,
0614 "mwavedd::mwave_init, return from tp3780I_CalcResources"
0615 " retval %x\n",
0616 retval);
0617 if (retval) {
0618 PRINTK_ERROR(KERN_ERR_MWAVE
0619 "mwavedd:mwave_init: Error:"
0620 " Failed to calculate resources\n");
0621 goto cleanup_error;
0622 }
0623
0624 retval = tp3780I_ClaimResources(&pDrvData->rBDData);
0625 PRINTK_2(TRACE_MWAVE,
0626 "mwavedd::mwave_init, return from tp3780I_ClaimResources"
0627 " retval %x\n",
0628 retval);
0629 if (retval) {
0630 PRINTK_ERROR(KERN_ERR_MWAVE
0631 "mwavedd:mwave_init: Error:"
0632 " Failed to claim resources\n");
0633 goto cleanup_error;
0634 }
0635 pDrvData->bResourcesClaimed = true;
0636
0637 retval = tp3780I_EnableDSP(&pDrvData->rBDData);
0638 PRINTK_2(TRACE_MWAVE,
0639 "mwavedd::mwave_init, return from tp3780I_EnableDSP"
0640 " retval %x\n",
0641 retval);
0642 if (retval) {
0643 PRINTK_ERROR(KERN_ERR_MWAVE
0644 "mwavedd:mwave_init: Error:"
0645 " Failed to enable DSP\n");
0646 goto cleanup_error;
0647 }
0648 pDrvData->bDSPEnabled = true;
0649
0650 if (misc_register(&mwave_misc_dev) < 0) {
0651 PRINTK_ERROR(KERN_ERR_MWAVE
0652 "mwavedd:mwave_init: Error:"
0653 " Failed to register misc device\n");
0654 goto cleanup_error;
0655 }
0656 pDrvData->bMwaveDevRegistered = true;
0657
0658 pDrvData->sLine = register_serial_portandirq(
0659 pDrvData->rBDData.rDspSettings.usUartBaseIO,
0660 pDrvData->rBDData.rDspSettings.usUartIrq
0661 );
0662 if (pDrvData->sLine < 0) {
0663 PRINTK_ERROR(KERN_ERR_MWAVE
0664 "mwavedd:mwave_init: Error:"
0665 " Failed to register serial driver\n");
0666 goto cleanup_error;
0667 }
0668
0669
0670 #if 0
0671
0672 memset(&mwave_device, 0, sizeof (struct device));
0673 dev_set_name(&mwave_device, "mwave");
0674
0675 if (device_register(&mwave_device))
0676 goto cleanup_error;
0677 pDrvData->device_registered = true;
0678 for (i = 0; i < ARRAY_SIZE(mwave_dev_attrs); i++) {
0679 if(device_create_file(&mwave_device, mwave_dev_attrs[i])) {
0680 PRINTK_ERROR(KERN_ERR_MWAVE
0681 "mwavedd:mwave_init: Error:"
0682 " Failed to create sysfs file %s\n",
0683 mwave_dev_attrs[i]->attr.name);
0684 goto cleanup_error;
0685 }
0686 pDrvData->nr_registered_attrs++;
0687 }
0688 #endif
0689
0690
0691 return 0;
0692
0693 cleanup_error:
0694 PRINTK_ERROR(KERN_ERR_MWAVE
0695 "mwavedd::mwave_init: Error:"
0696 " Failed to initialize\n");
0697 mwave_exit();
0698
0699 return -EIO;
0700 }
0701
0702 module_init(mwave_init);
0703