Example #1
0
static void dsp3780I_WriteGenCfg(unsigned short usDspBaseIO, unsigned uIndex,
                                 unsigned char ucValue)
{
    DSP_ISA_SLAVE_CONTROL rSlaveControl;
    DSP_ISA_SLAVE_CONTROL rSlaveControl_Save;


    PRINTK_4(TRACE_3780I,
             "3780i::dsp3780i_WriteGenCfg entry usDspBaseIO %x uIndex %x ucValue %x\n",
             usDspBaseIO, uIndex, ucValue);

    MKBYTE(rSlaveControl) = InByteDsp(DSP_IsaSlaveControl);

    PRINTK_2(TRACE_3780I,
             "3780i::dsp3780i_WriteGenCfg rSlaveControl %x\n",
             MKBYTE(rSlaveControl));

    rSlaveControl_Save = rSlaveControl;
    rSlaveControl.ConfigMode = TRUE;

    PRINTK_2(TRACE_3780I,
             "3780i::dsp3780i_WriteGenCfg entry rSlaveControl+ConfigMode %x\n",
             MKBYTE(rSlaveControl));

    OutByteDsp(DSP_IsaSlaveControl, MKBYTE(rSlaveControl));
    OutByteDsp(DSP_ConfigAddress, (unsigned char) uIndex);
    OutByteDsp(DSP_ConfigData, ucValue);
    OutByteDsp(DSP_IsaSlaveControl, MKBYTE(rSlaveControl_Save));

    PRINTK_1(TRACE_3780I, "3780i::dsp3780i_WriteGenCfg exit\n");


}
Example #2
0
void dsp3780I_WriteMsaCfg(unsigned short usDspBaseIO,
                          unsigned long ulMsaAddr, unsigned short usValue)
{

    PRINTK_4(TRACE_3780I,
             "3780i::dsp3780i_WriteMsaCfg entry usDspBaseIO %x ulMsaAddr %lx usValue %x\n",
             usDspBaseIO, ulMsaAddr, usValue);

    spin_lock_irqsave(&dsp_lock, flags);
    OutWordDsp(DSP_MsaAddrLow, (unsigned short) ulMsaAddr);
    OutWordDsp(DSP_MsaAddrHigh, (unsigned short) (ulMsaAddr >> 16));
    OutWordDsp(DSP_MsaDataDSISHigh, usValue);
    spin_unlock_irqrestore(&dsp_lock, flags);
}
Example #3
0
int dsp3780I_WriteIStore(unsigned short usDspBaseIO, void __user *pvBuffer,
                         unsigned uCount, unsigned long ulDSPAddr)
{
    unsigned long flags;
    unsigned short __user *pusBuffer = pvBuffer;

    PRINTK_5(TRACE_3780I,
             "3780i::dsp3780I_WriteIStore entry usDspBaseIO %x, pusBuffer %p, uCount %x, ulDSPAddr %lx\n",
             usDspBaseIO, pusBuffer, uCount, ulDSPAddr);


    /*
    * Set the initial MSA address. To convert from an instruction store
    * address to an MSA address
    * shift the address two bits to the left and set bit 22
    */
    ulDSPAddr = (ulDSPAddr << 2) | (1 << 22);
    spin_lock_irqsave(&dsp_lock, flags);
    OutWordDsp(DSP_MsaAddrLow, (unsigned short) ulDSPAddr);
    OutWordDsp(DSP_MsaAddrHigh, (unsigned short) (ulDSPAddr >> 16));
    spin_unlock_irqrestore(&dsp_lock, flags);

    /* Transfer the memory block */
    while (uCount-- != 0) {
        unsigned short val_lo, val_hi;
        if(get_user(val_lo, pusBuffer++))
            return -EFAULT;
        if(get_user(val_hi, pusBuffer++))
            return -EFAULT;
        spin_lock_irqsave(&dsp_lock, flags);
        OutWordDsp(DSP_MsaDataISLow, val_lo);
        OutWordDsp(DSP_MsaDataDSISHigh, val_hi);
        spin_unlock_irqrestore(&dsp_lock, flags);

        PRINTK_4(TRACE_3780I,
                 "3780I::dsp3780I_WriteIStore uCount %x val_lo %x val_hi %x\n",
                 uCount, val_lo, val_hi);

        PaceMsaAccess(usDspBaseIO);

    }

    PRINTK_1(TRACE_3780I,
             "3780I::dsp3780I_WriteIStore exit bRC=TRUE\n");

    return 0;
}
Example #4
0
int dsp3780I_WriteIStore(unsigned short usDspBaseIO, void __user *pvBuffer,
                         unsigned uCount, unsigned long ulDSPAddr)
{
	unsigned long flags;
	unsigned short __user *pusBuffer = pvBuffer;

	PRINTK_5(TRACE_3780I,
		"3780i::dsp3780I_WriteIStore entry usDspBaseIO %x, pusBuffer %p, uCount %x, ulDSPAddr %lx\n",
		usDspBaseIO, pusBuffer, uCount, ulDSPAddr);


	
	ulDSPAddr = (ulDSPAddr << 2) | (1 << 22);
	spin_lock_irqsave(&dsp_lock, flags);
	OutWordDsp(DSP_MsaAddrLow, (unsigned short) ulDSPAddr);
	OutWordDsp(DSP_MsaAddrHigh, (unsigned short) (ulDSPAddr >> 16));
	spin_unlock_irqrestore(&dsp_lock, flags);

	
	while (uCount-- != 0) {
		unsigned short val_lo, val_hi;
		if(get_user(val_lo, pusBuffer++))
			return -EFAULT;
		if(get_user(val_hi, pusBuffer++))
			return -EFAULT;
		spin_lock_irqsave(&dsp_lock, flags);
		OutWordDsp(DSP_MsaDataISLow, val_lo);
		OutWordDsp(DSP_MsaDataDSISHigh, val_hi);
		spin_unlock_irqrestore(&dsp_lock, flags);

		PRINTK_4(TRACE_3780I,
			"3780I::dsp3780I_WriteIStore uCount %x val_lo %x val_hi %x\n",
			uCount, val_lo, val_hi);

		PaceMsaAccess(usDspBaseIO);

	}

	PRINTK_1(TRACE_3780I,
		"3780I::dsp3780I_WriteIStore exit bRC=TRUE\n");

	return 0;
}
Example #5
0
static long mwave_ioctl(struct file *file, unsigned int iocmd,
							unsigned long ioarg)
{
	unsigned int retval = 0;
	pMWAVE_DEVICE_DATA pDrvData = &mwave_s_mdd;
	void __user *arg = (void __user *)ioarg;

	PRINTK_4(TRACE_MWAVE,
		"mwavedd::mwave_ioctl, entry file %p cmd %x arg %x\n",
		file, iocmd, (int) ioarg);

	switch (iocmd) {

		case IOCTL_MW_RESET:
			PRINTK_1(TRACE_MWAVE,
				"mwavedd::mwave_ioctl, IOCTL_MW_RESET"
				" calling tp3780I_ResetDSP\n");
			mutex_lock(&mwave_mutex);
			retval = tp3780I_ResetDSP(&pDrvData->rBDData);
			mutex_unlock(&mwave_mutex);
			PRINTK_2(TRACE_MWAVE,
				"mwavedd::mwave_ioctl, IOCTL_MW_RESET"
				" retval %x from tp3780I_ResetDSP\n",
				retval);
			break;
	
		case IOCTL_MW_RUN:
			PRINTK_1(TRACE_MWAVE,
				"mwavedd::mwave_ioctl, IOCTL_MW_RUN"
				" calling tp3780I_StartDSP\n");
			mutex_lock(&mwave_mutex);
			retval = tp3780I_StartDSP(&pDrvData->rBDData);
			mutex_unlock(&mwave_mutex);
			PRINTK_2(TRACE_MWAVE,
				"mwavedd::mwave_ioctl, IOCTL_MW_RUN"
				" retval %x from tp3780I_StartDSP\n",
				retval);
			break;
	
		case IOCTL_MW_DSP_ABILITIES: {
			MW_ABILITIES rAbilities;
	
			PRINTK_1(TRACE_MWAVE,
				"mwavedd::mwave_ioctl,"
				" IOCTL_MW_DSP_ABILITIES calling"
				" tp3780I_QueryAbilities\n");
			mutex_lock(&mwave_mutex);
			retval = tp3780I_QueryAbilities(&pDrvData->rBDData,
					&rAbilities);
			mutex_unlock(&mwave_mutex);
			PRINTK_2(TRACE_MWAVE,
				"mwavedd::mwave_ioctl, IOCTL_MW_DSP_ABILITIES"
				" retval %x from tp3780I_QueryAbilities\n",
				retval);
			if (retval == 0) {
				if( copy_to_user(arg, &rAbilities,
							sizeof(MW_ABILITIES)) )
					return -EFAULT;
			}
			PRINTK_2(TRACE_MWAVE,
				"mwavedd::mwave_ioctl, IOCTL_MW_DSP_ABILITIES"
				" exit retval %x\n",
				retval);
		}
			break;
	
		case IOCTL_MW_READ_DATA:
		case IOCTL_MW_READCLEAR_DATA: {
			MW_READWRITE rReadData;
			unsigned short __user *pusBuffer = NULL;
	
			if( copy_from_user(&rReadData, arg,
						sizeof(MW_READWRITE)) )
				return -EFAULT;
			pusBuffer = (unsigned short __user *) (rReadData.pBuf);
	
			PRINTK_4(TRACE_MWAVE,
				"mwavedd::mwave_ioctl IOCTL_MW_READ_DATA,"
				" size %lx, ioarg %lx pusBuffer %p\n",
				rReadData.ulDataLength, ioarg, pusBuffer);
			mutex_lock(&mwave_mutex);
			retval = tp3780I_ReadWriteDspDStore(&pDrvData->rBDData,
					iocmd,
					pusBuffer,
					rReadData.ulDataLength,
					rReadData.usDspAddress);
			mutex_unlock(&mwave_mutex);
		}
			break;
	
		case IOCTL_MW_READ_INST: {
			MW_READWRITE rReadData;
			unsigned short __user *pusBuffer = NULL;
	
			if( copy_from_user(&rReadData, arg,
						sizeof(MW_READWRITE)) )
				return -EFAULT;
			pusBuffer = (unsigned short __user *) (rReadData.pBuf);
	
			PRINTK_4(TRACE_MWAVE,
				"mwavedd::mwave_ioctl IOCTL_MW_READ_INST,"
				" size %lx, ioarg %lx pusBuffer %p\n",
				rReadData.ulDataLength / 2, ioarg,
				pusBuffer);
			mutex_lock(&mwave_mutex);
			retval = tp3780I_ReadWriteDspDStore(&pDrvData->rBDData,
				iocmd, pusBuffer,
				rReadData.ulDataLength / 2,
				rReadData.usDspAddress);
			mutex_unlock(&mwave_mutex);
		}
			break;
	
		case IOCTL_MW_WRITE_DATA: {
			MW_READWRITE rWriteData;
			unsigned short __user *pusBuffer = NULL;
	
			if( copy_from_user(&rWriteData, arg,
						sizeof(MW_READWRITE)) )
				return -EFAULT;
			pusBuffer = (unsigned short __user *) (rWriteData.pBuf);
	
			PRINTK_4(TRACE_MWAVE,
				"mwavedd::mwave_ioctl IOCTL_MW_WRITE_DATA,"
				" size %lx, ioarg %lx pusBuffer %p\n",
				rWriteData.ulDataLength, ioarg,
				pusBuffer);
			mutex_lock(&mwave_mutex);
			retval = tp3780I_ReadWriteDspDStore(&pDrvData->rBDData,
					iocmd, pusBuffer,
					rWriteData.ulDataLength,
					rWriteData.usDspAddress);
			mutex_unlock(&mwave_mutex);
		}
			break;
	
		case IOCTL_MW_WRITE_INST: {
			MW_READWRITE rWriteData;
			unsigned short __user *pusBuffer = NULL;
	
			if( copy_from_user(&rWriteData, arg,
						sizeof(MW_READWRITE)) )
				return -EFAULT;
			pusBuffer = (unsigned short __user *)(rWriteData.pBuf);
	
			PRINTK_4(TRACE_MWAVE,
				"mwavedd::mwave_ioctl IOCTL_MW_WRITE_INST,"
				" size %lx, ioarg %lx pusBuffer %p\n",
				rWriteData.ulDataLength, ioarg,
				pusBuffer);
			mutex_lock(&mwave_mutex);
			retval = tp3780I_ReadWriteDspIStore(&pDrvData->rBDData,
					iocmd, pusBuffer,
					rWriteData.ulDataLength,
					rWriteData.usDspAddress);
			mutex_unlock(&mwave_mutex);
		}
			break;
	
		case IOCTL_MW_REGISTER_IPC: {
			unsigned int ipcnum = (unsigned int) ioarg;
	
			if (ipcnum >= ARRAY_SIZE(pDrvData->IPCs)) {
				PRINTK_ERROR(KERN_ERR_MWAVE
						"mwavedd::mwave_ioctl:"
						" IOCTL_MW_REGISTER_IPC:"
						" Error: Invalid ipcnum %x\n",
						ipcnum);
				return -EINVAL;
			}
			PRINTK_3(TRACE_MWAVE,
				"mwavedd::mwave_ioctl IOCTL_MW_REGISTER_IPC"
				" ipcnum %x entry usIntCount %x\n",
				ipcnum,
				pDrvData->IPCs[ipcnum].usIntCount);

			mutex_lock(&mwave_mutex);
			pDrvData->IPCs[ipcnum].bIsHere = FALSE;
			pDrvData->IPCs[ipcnum].bIsEnabled = TRUE;
			mutex_unlock(&mwave_mutex);
	
			PRINTK_2(TRACE_MWAVE,
				"mwavedd::mwave_ioctl IOCTL_MW_REGISTER_IPC"
				" ipcnum %x exit\n",
				ipcnum);
		}
			break;
	
		case IOCTL_MW_GET_IPC: {
			unsigned int ipcnum = (unsigned int) ioarg;
	
			if (ipcnum >= ARRAY_SIZE(pDrvData->IPCs)) {
				PRINTK_ERROR(KERN_ERR_MWAVE
						"mwavedd::mwave_ioctl:"
						" IOCTL_MW_GET_IPC: Error:"
						" Invalid ipcnum %x\n", ipcnum);
				return -EINVAL;
			}
			PRINTK_3(TRACE_MWAVE,
				"mwavedd::mwave_ioctl IOCTL_MW_GET_IPC"
				" ipcnum %x, usIntCount %x\n",
				ipcnum,
				pDrvData->IPCs[ipcnum].usIntCount);
	
			mutex_lock(&mwave_mutex);
			if (pDrvData->IPCs[ipcnum].bIsEnabled == TRUE) {
				DECLARE_WAITQUEUE(wait, current);

				PRINTK_2(TRACE_MWAVE,
					"mwavedd::mwave_ioctl, thread for"
					" ipc %x going to sleep\n",
					ipcnum);
				add_wait_queue(&pDrvData->IPCs[ipcnum].ipc_wait_queue, &wait);
				pDrvData->IPCs[ipcnum].bIsHere = TRUE;
				set_current_state(TASK_INTERRUPTIBLE);
				/* check whether an event was signalled by */
				/* the interrupt handler while we were gone */
				if (pDrvData->IPCs[ipcnum].usIntCount == 1) {	/* first int has occurred (race condition) */
					pDrvData->IPCs[ipcnum].usIntCount = 2;	/* first int has been handled */
					PRINTK_2(TRACE_MWAVE,
						"mwavedd::mwave_ioctl"
						" IOCTL_MW_GET_IPC ipcnum %x"
						" handling first int\n",
						ipcnum);
				} else {	/* either 1st int has not yet occurred, or we have already handled the first int */
					schedule();
					if (pDrvData->IPCs[ipcnum].usIntCount == 1) {
						pDrvData->IPCs[ipcnum].usIntCount = 2;
					}
					PRINTK_2(TRACE_MWAVE,
						"mwavedd::mwave_ioctl"
						" IOCTL_MW_GET_IPC ipcnum %x"
						" woke up and returning to"
						" application\n",
						ipcnum);
				}
				pDrvData->IPCs[ipcnum].bIsHere = FALSE;
				remove_wait_queue(&pDrvData->IPCs[ipcnum].ipc_wait_queue, &wait);
				set_current_state(TASK_RUNNING);
				PRINTK_2(TRACE_MWAVE,
					"mwavedd::mwave_ioctl IOCTL_MW_GET_IPC,"
					" returning thread for ipc %x"
					" processing\n",
					ipcnum);
			}
			mutex_unlock(&mwave_mutex);
		}
			break;
	
		case IOCTL_MW_UNREGISTER_IPC: {
			unsigned int ipcnum = (unsigned int) ioarg;
	
			PRINTK_2(TRACE_MWAVE,
				"mwavedd::mwave_ioctl IOCTL_MW_UNREGISTER_IPC"
				" ipcnum %x\n",
				ipcnum);
			if (ipcnum >= ARRAY_SIZE(pDrvData->IPCs)) {
				PRINTK_ERROR(KERN_ERR_MWAVE
						"mwavedd::mwave_ioctl:"
						" IOCTL_MW_UNREGISTER_IPC:"
						" Error: Invalid ipcnum %x\n",
						ipcnum);
				return -EINVAL;
			}
			mutex_lock(&mwave_mutex);
			if (pDrvData->IPCs[ipcnum].bIsEnabled == TRUE) {
				pDrvData->IPCs[ipcnum].bIsEnabled = FALSE;
				if (pDrvData->IPCs[ipcnum].bIsHere == TRUE) {
					wake_up_interruptible(&pDrvData->IPCs[ipcnum].ipc_wait_queue);
				}
			}
			mutex_unlock(&mwave_mutex);
		}
			break;
	
		default:
			return -ENOTTY;
			break;
	} /* switch */

	PRINTK_2(TRACE_MWAVE, "mwavedd::mwave_ioctl, exit retval %x\n", retval);

	return retval;
}
Example #6
0
int dsp3780I_EnableDSP(DSP_3780I_CONFIG_SETTINGS * pSettings,
                       unsigned short *pIrqMap,
                       unsigned short *pDmaMap)
{
    unsigned long flags;
    unsigned short usDspBaseIO = pSettings->usDspBaseIO;
    int i;
    DSP_UART_CFG_1 rUartCfg1;
    DSP_UART_CFG_2 rUartCfg2;
    DSP_HBRIDGE_CFG_1 rHBridgeCfg1;
    DSP_HBRIDGE_CFG_2 rHBridgeCfg2;
    DSP_BUSMASTER_CFG_1 rBusmasterCfg1;
    DSP_BUSMASTER_CFG_2 rBusmasterCfg2;
    DSP_ISA_PROT_CFG rIsaProtCfg;
    DSP_POWER_MGMT_CFG rPowerMgmtCfg;
    DSP_HBUS_TIMER_CFG rHBusTimerCfg;
    DSP_LBUS_TIMEOUT_DISABLE rLBusTimeoutDisable;
    DSP_CHIP_RESET rChipReset;
    DSP_CLOCK_CONTROL_1 rClockControl1;
    DSP_CLOCK_CONTROL_2 rClockControl2;
    DSP_ISA_SLAVE_CONTROL rSlaveControl;
    DSP_HBRIDGE_CONTROL rHBridgeControl;
    unsigned short ChipID = 0;
    unsigned short tval;


    PRINTK_2(TRACE_3780I,
             "3780i::dsp3780I_EnableDSP entry pSettings->bDSPEnabled %x\n",
             pSettings->bDSPEnabled);


    if (!pSettings->bDSPEnabled) {
        PRINTK_ERROR( KERN_ERR "3780i::dsp3780I_EnableDSP: Error: DSP not enabled. Aborting.\n" );
        return -EIO;
    }


    PRINTK_2(TRACE_3780I,
             "3780i::dsp3780i_EnableDSP entry pSettings->bModemEnabled %x\n",
             pSettings->bModemEnabled);

    if (pSettings->bModemEnabled) {
        rUartCfg1.Reserved = rUartCfg2.Reserved = 0;
        rUartCfg1.IrqActiveLow = pSettings->bUartIrqActiveLow;
        rUartCfg1.IrqPulse = pSettings->bUartIrqPulse;
        rUartCfg1.Irq =
            (unsigned char) pIrqMap[pSettings->usUartIrq];
        switch (pSettings->usUartBaseIO) {
        case 0x03F8:
            rUartCfg1.BaseIO = 0;
            break;
        case 0x02F8:
            rUartCfg1.BaseIO = 1;
            break;
        case 0x03E8:
            rUartCfg1.BaseIO = 2;
            break;
        case 0x02E8:
            rUartCfg1.BaseIO = 3;
            break;
        }
        rUartCfg2.Enable = TRUE;
    }

    rHBridgeCfg1.Reserved = rHBridgeCfg2.Reserved = 0;
    rHBridgeCfg1.IrqActiveLow = pSettings->bDspIrqActiveLow;
    rHBridgeCfg1.IrqPulse = pSettings->bDspIrqPulse;
    rHBridgeCfg1.Irq = (unsigned char) pIrqMap[pSettings->usDspIrq];
    rHBridgeCfg1.AccessMode = 1;
    rHBridgeCfg2.Enable = TRUE;


    rBusmasterCfg2.Reserved = 0;
    rBusmasterCfg1.Dma = (unsigned char) pDmaMap[pSettings->usDspDma];
    rBusmasterCfg1.NumTransfers =
        (unsigned char) pSettings->usNumTransfers;
    rBusmasterCfg1.ReRequest = (unsigned char) pSettings->usReRequest;
    rBusmasterCfg1.MEMCS16 = pSettings->bEnableMEMCS16;
    rBusmasterCfg2.IsaMemCmdWidth =
        (unsigned char) pSettings->usIsaMemCmdWidth;


    rIsaProtCfg.Reserved = 0;
    rIsaProtCfg.GateIOCHRDY = pSettings->bGateIOCHRDY;

    rPowerMgmtCfg.Reserved = 0;
    rPowerMgmtCfg.Enable = pSettings->bEnablePwrMgmt;

    rHBusTimerCfg.LoadValue =
        (unsigned char) pSettings->usHBusTimerLoadValue;

    rLBusTimeoutDisable.Reserved = 0;
    rLBusTimeoutDisable.DisableTimeout =
        pSettings->bDisableLBusTimeout;

    MKWORD(rChipReset) = ~pSettings->usChipletEnable;

    rClockControl1.Reserved1 = rClockControl1.Reserved2 = 0;
    rClockControl1.N_Divisor = pSettings->usN_Divisor;
    rClockControl1.M_Multiplier = pSettings->usM_Multiplier;

    rClockControl2.Reserved = 0;
    rClockControl2.PllBypass = pSettings->bPllBypass;

    /* Issue a soft reset to the chip */
    /* Note: Since we may be coming in with 3780i clocks suspended, we must keep
    * soft-reset active for 10ms.
    */
    rSlaveControl.ClockControl = 0;
    rSlaveControl.SoftReset = TRUE;
    rSlaveControl.ConfigMode = FALSE;
    rSlaveControl.Reserved = 0;

    PRINTK_4(TRACE_3780I,
             "3780i::dsp3780i_EnableDSP usDspBaseIO %x index %x taddr %x\n",
             usDspBaseIO, DSP_IsaSlaveControl,
             usDspBaseIO + DSP_IsaSlaveControl);

    PRINTK_2(TRACE_3780I,
             "3780i::dsp3780i_EnableDSP rSlaveContrl %x\n",
             MKWORD(rSlaveControl));

    spin_lock_irqsave(&dsp_lock, flags);
    OutWordDsp(DSP_IsaSlaveControl, MKWORD(rSlaveControl));
    MKWORD(tval) = InWordDsp(DSP_IsaSlaveControl);

    PRINTK_2(TRACE_3780I,
             "3780i::dsp3780i_EnableDSP rSlaveControl 2 %x\n", tval);


    for (i = 0; i < 11; i++)
        udelay(2000);

    rSlaveControl.SoftReset = FALSE;
    OutWordDsp(DSP_IsaSlaveControl, MKWORD(rSlaveControl));

    MKWORD(tval) = InWordDsp(DSP_IsaSlaveControl);

    PRINTK_2(TRACE_3780I,
             "3780i::dsp3780i_EnableDSP rSlaveControl 3 %x\n", tval);


    /* Program our general configuration registers */
    WriteGenCfg(DSP_HBridgeCfg1Index, MKBYTE(rHBridgeCfg1));
    WriteGenCfg(DSP_HBridgeCfg2Index, MKBYTE(rHBridgeCfg2));
    WriteGenCfg(DSP_BusMasterCfg1Index, MKBYTE(rBusmasterCfg1));
    WriteGenCfg(DSP_BusMasterCfg2Index, MKBYTE(rBusmasterCfg2));
    WriteGenCfg(DSP_IsaProtCfgIndex, MKBYTE(rIsaProtCfg));
    WriteGenCfg(DSP_PowerMgCfgIndex, MKBYTE(rPowerMgmtCfg));
    WriteGenCfg(DSP_HBusTimerCfgIndex, MKBYTE(rHBusTimerCfg));

    if (pSettings->bModemEnabled) {
        WriteGenCfg(DSP_UartCfg1Index, MKBYTE(rUartCfg1));
        WriteGenCfg(DSP_UartCfg2Index, MKBYTE(rUartCfg2));
    }


    rHBridgeControl.EnableDspInt = FALSE;
    rHBridgeControl.MemAutoInc = TRUE;
    rHBridgeControl.IoAutoInc = FALSE;
    rHBridgeControl.DiagnosticMode = FALSE;

    PRINTK_3(TRACE_3780I,
             "3780i::dsp3780i_EnableDSP DSP_HBridgeControl %x rHBridgeControl %x\n",
             DSP_HBridgeControl, MKWORD(rHBridgeControl));

    OutWordDsp(DSP_HBridgeControl, MKWORD(rHBridgeControl));
    spin_unlock_irqrestore(&dsp_lock, flags);
    WriteMsaCfg(DSP_LBusTimeoutDisable, MKWORD(rLBusTimeoutDisable));
    WriteMsaCfg(DSP_ClockControl_1, MKWORD(rClockControl1));
    WriteMsaCfg(DSP_ClockControl_2, MKWORD(rClockControl2));
    WriteMsaCfg(DSP_ChipReset, MKWORD(rChipReset));

    ChipID = ReadMsaCfg(DSP_ChipID);

    PRINTK_2(TRACE_3780I,
             "3780i::dsp3780I_EnableDSP exiting bRC=TRUE, ChipID %x\n",
             ChipID);

    return 0;
}
static int mwave_ioctl(struct inode *inode, struct file *file,
                       unsigned int iocmd, unsigned long ioarg)
{
	unsigned int retval = 0;
	pMWAVE_DEVICE_DATA pDrvData = &mwave_s_mdd;

	PRINTK_5(TRACE_MWAVE,
		"mwavedd::mwave_ioctl, entry inode %x file %x cmd %x arg %x\n",
		(int) inode, (int) file, iocmd, (int) ioarg);

	switch (iocmd) {

		case IOCTL_MW_RESET:
			PRINTK_1(TRACE_MWAVE,
				"mwavedd::mwave_ioctl, IOCTL_MW_RESET calling tp3780I_ResetDSP\n");
			retval = tp3780I_ResetDSP(&pDrvData->rBDData);
			PRINTK_2(TRACE_MWAVE,
				"mwavedd::mwave_ioctl, IOCTL_MW_RESET retval %x from tp3780I_ResetDSP\n",
				retval);
			break;
	
		case IOCTL_MW_RUN:
			PRINTK_1(TRACE_MWAVE,
				"mwavedd::mwave_ioctl, IOCTL_MW_RUN calling tp3780I_StartDSP\n");
			retval = tp3780I_StartDSP(&pDrvData->rBDData);
			PRINTK_2(TRACE_MWAVE,
				"mwavedd::mwave_ioctl, IOCTL_MW_RUN retval %x from tp3780I_StartDSP\n",
				retval);
			break;
	
		case IOCTL_MW_DSP_ABILITIES: {
			MW_ABILITIES rAbilities;
	
			PRINTK_1(TRACE_MWAVE,
				"mwavedd::mwave_ioctl, IOCTL_MW_DSP_ABILITIES calling tp3780I_QueryAbilities\n");
			retval = tp3780I_QueryAbilities(&pDrvData->rBDData, &rAbilities);
			PRINTK_2(TRACE_MWAVE,
				"mwavedd::mwave_ioctl, IOCTL_MW_DSP_ABILITIES retval %x from tp3780I_QueryAbilities\n",
				retval);
			if (retval == 0) {
				if( copy_to_user((char *) ioarg, (char *) &rAbilities, sizeof(MW_ABILITIES)) )
					return -EFAULT;
			}
			PRINTK_2(TRACE_MWAVE,
				"mwavedd::mwave_ioctl, IOCTL_MW_DSP_ABILITIES exit retval %x\n",
				retval);
		}
			break;
	
		case IOCTL_MW_READ_DATA:
		case IOCTL_MW_READCLEAR_DATA: {
			MW_READWRITE rReadData;
			unsigned short *pusBuffer = 0;
	
			if( copy_from_user((char *) &rReadData, (char *) ioarg, sizeof(MW_READWRITE)) )
				return -EFAULT;
			pusBuffer = (unsigned short *) (rReadData.pBuf);
	
			PRINTK_4(TRACE_MWAVE,
				"mwavedd::mwave_ioctl IOCTL_MW_READ_DATA, size %lx, ioarg %lx pusBuffer %p\n",
				rReadData.ulDataLength, ioarg, pusBuffer);
			retval = tp3780I_ReadWriteDspDStore(&pDrvData->rBDData, iocmd,
				(void *) pusBuffer, rReadData.ulDataLength, rReadData.usDspAddress);
		}
			break;
	
		case IOCTL_MW_READ_INST: {
			MW_READWRITE rReadData;
			unsigned short *pusBuffer = 0;
	
			if( copy_from_user((char *) &rReadData, (char *) ioarg, sizeof(MW_READWRITE)) )
				return -EFAULT;
			pusBuffer = (unsigned short *) (rReadData.pBuf);
	
			PRINTK_4(TRACE_MWAVE,
				"mwavedd::mwave_ioctl IOCTL_MW_READ_INST, size %lx, ioarg %lx pusBuffer %p\n",
				rReadData.ulDataLength / 2, ioarg,
				pusBuffer);
			retval = tp3780I_ReadWriteDspDStore(&pDrvData->rBDData,
				iocmd, pusBuffer,
				rReadData.ulDataLength / 2,
				rReadData.usDspAddress);
		}
			break;
	
		case IOCTL_MW_WRITE_DATA: {
			MW_READWRITE rWriteData;
			unsigned short *pusBuffer = 0;
	
			if( copy_from_user((char *) &rWriteData, (char *) ioarg, sizeof(MW_READWRITE)) )
				return -EFAULT;
			pusBuffer = (unsigned short *) (rWriteData.pBuf);
	
			PRINTK_4(TRACE_MWAVE,
				"mwavedd::mwave_ioctl IOCTL_MW_WRITE_DATA, size %lx, ioarg %lx pusBuffer %p\n",
				rWriteData.ulDataLength, ioarg,
				pusBuffer);
			retval = tp3780I_ReadWriteDspDStore(&pDrvData->rBDData, iocmd,
				pusBuffer, rWriteData.ulDataLength, rWriteData.usDspAddress);
		}
			break;
	
		case IOCTL_MW_WRITE_INST: {
			MW_READWRITE rWriteData;
			unsigned short *pusBuffer = 0;
	
			if( copy_from_user((char *) &rWriteData, (char *) ioarg, sizeof(MW_READWRITE)) )
				return -EFAULT;
			pusBuffer = (unsigned short *) (rWriteData.pBuf);
	
			PRINTK_4(TRACE_MWAVE,
				"mwavedd::mwave_ioctl IOCTL_MW_WRITE_INST, size %lx, ioarg %lx pusBuffer %p\n",
				rWriteData.ulDataLength, ioarg,
				pusBuffer);
			retval = tp3780I_ReadWriteDspIStore(&pDrvData->rBDData, iocmd,
					pusBuffer, rWriteData.ulDataLength, rWriteData.usDspAddress);
		}
			break;
	
		case IOCTL_MW_REGISTER_IPC: {
			unsigned int ipcnum = (unsigned int) ioarg;
	
			PRINTK_3(TRACE_MWAVE,
				"mwavedd::mwave_ioctl IOCTL_MW_REGISTER_IPC ipcnum %x entry usIntCount %x\n",
				ipcnum,
				pDrvData->IPCs[ipcnum].usIntCount);
	
			if (ipcnum > 16) {
				PRINTK_ERROR(KERN_ERR_MWAVE "mwavedd::mwave_ioctl: IOCTL_MW_REGISTER_IPC: Error: Invalid ipcnum %x\n", ipcnum);
				return -EINVAL;
			}
			pDrvData->IPCs[ipcnum].bIsHere = FALSE;
			pDrvData->IPCs[ipcnum].bIsEnabled = TRUE;
	#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
	#else
			current->priority = 0x28;	/* boost to provide priority timing */
	#endif
	
			PRINTK_2(TRACE_MWAVE,
				"mwavedd::mwave_ioctl IOCTL_MW_REGISTER_IPC ipcnum %x exit\n",
				ipcnum);
		}
			break;
	
		case IOCTL_MW_GET_IPC: {
			unsigned int ipcnum = (unsigned int) ioarg;
			spinlock_t ipc_lock = SPIN_LOCK_UNLOCKED;
			unsigned long flags;
	
			PRINTK_3(TRACE_MWAVE,
				"mwavedd::mwave_ioctl IOCTL_MW_GET_IPC ipcnum %x, usIntCount %x\n",
				ipcnum,
				pDrvData->IPCs[ipcnum].usIntCount);
			if (ipcnum > 16) {
				PRINTK_ERROR(KERN_ERR_MWAVE "mwavedd::mwave_ioctl: IOCTL_MW_GET_IPC: Error: Invalid ipcnum %x\n", ipcnum);
				return -EINVAL;
			}
	
			if (pDrvData->IPCs[ipcnum].bIsEnabled == TRUE) {
				PRINTK_2(TRACE_MWAVE,
					"mwavedd::mwave_ioctl, thread for ipc %x going to sleep\n",
					ipcnum);
	
				spin_lock_irqsave(&ipc_lock, flags);
				/* check whether an event was signalled by */
				/* the interrupt handler while we were gone */
				if (pDrvData->IPCs[ipcnum].usIntCount == 1) {	/* first int has occurred (race condition) */
					pDrvData->IPCs[ipcnum].usIntCount = 2;	/* first int has been handled */
					spin_unlock_irqrestore(&ipc_lock, flags);
					PRINTK_2(TRACE_MWAVE,
						"mwavedd::mwave_ioctl IOCTL_MW_GET_IPC ipcnum %x handling first int\n",
						ipcnum);
				} else {	/* either 1st int has not yet occurred, or we have already handled the first int */
					pDrvData->IPCs[ipcnum].bIsHere = TRUE;
					interruptible_sleep_on(&pDrvData->IPCs[ipcnum].ipc_wait_queue);
					pDrvData->IPCs[ipcnum].bIsHere = FALSE;
					if (pDrvData->IPCs[ipcnum].usIntCount == 1) {
						pDrvData->IPCs[ipcnum].
						usIntCount = 2;
					}
					spin_unlock_irqrestore(&ipc_lock, flags);
					PRINTK_2(TRACE_MWAVE,
						"mwavedd::mwave_ioctl IOCTL_MW_GET_IPC ipcnum %x woke up and returning to application\n",
						ipcnum);
				}
				PRINTK_2(TRACE_MWAVE,
					"mwavedd::mwave_ioctl IOCTL_MW_GET_IPC, returning thread for ipc %x processing\n",
					ipcnum);
			}
		}
			break;
	
		case IOCTL_MW_UNREGISTER_IPC: {
			unsigned int ipcnum = (unsigned int) ioarg;
	
			PRINTK_2(TRACE_MWAVE,
				"mwavedd::mwave_ioctl IOCTL_MW_UNREGISTER_IPC ipcnum %x\n",
				ipcnum);
			if (ipcnum > 16) {
				PRINTK_ERROR(KERN_ERR_MWAVE "mwavedd::mwave_ioctl: IOCTL_MW_UNREGISTER_IPC: Error: Invalid ipcnum %x\n", ipcnum);
				return -EINVAL;
			}
			if (pDrvData->IPCs[ipcnum].bIsEnabled == TRUE) {
				pDrvData->IPCs[ipcnum].bIsEnabled = FALSE;
				if (pDrvData->IPCs[ipcnum].bIsHere == TRUE) {
					wake_up_interruptible(&pDrvData->IPCs[ipcnum].ipc_wait_queue);
				}
			}
		}
			break;
	
		default:
			PRINTK_ERROR(KERN_ERR_MWAVE "mwavedd::mwave_ioctl: Error: Unrecognized iocmd %x\n", iocmd);
			return -ENOTTY;
			break;
	} /* switch */

	PRINTK_2(TRACE_MWAVE, "mwavedd::mwave_ioctl, exit retval %x\n", retval);

	return retval;
}