/* Rx tasklet */ static void tdm_if_pcm_rx_process(unsigned long arg) #endif { TRC_REC("->%s\n",__FUNCTION__); if(pcm_enable) { if(rxBuff == NULL) { TRC_REC("%s: Error, empty Rx processing\n",__FUNCTION__); return; } /* Fill TDM Rx aggregated buffer */ #ifdef CONFIG_MV_TDM_SUPPORT if(mvTdmRx(rxBuff) == MV_OK) tdm_if_register_ops->tdm_if_pcm_ops.pcm_rx_callback(rxBuff, buff_size); /* Dispatch Rx handler */ #else if(mvCommUnitRx(rxBuff) == MV_OK) { tdm_if_register_ops->tdm_if_pcm_ops.pcm_rx_callback(rxBuff, buff_size); /* Dispatch Rx handler */ /* Since data buffer is shared among MCDMA and CPU, need to invalidate before it accessed by MCDMA */ mvOsCacheInvalidate(NULL, rxBuff, buff_size); } #endif else printk("%s: could not fill Rx buffer\n",__FUNCTION__); } /* Clear rxBuff for next iteration */ rxBuff = NULL; TRC_REC("<-%s\n",__FUNCTION__); return; }
/* Tx tasklet */ static void tdm_if_pcm_tx_process(unsigned long arg) #endif { TRC_REC("->%s\n",__FUNCTION__); if(pcm_enable) { if(txBuff == NULL) { TRC_REC("%s: Error, empty Tx processing\n",__FUNCTION__); return; } /* Dispatch Tx handler */ tdm_if_register_ops->tdm_if_pcm_ops.pcm_tx_callback(txBuff, buff_size); if(test_enable == 0) { /* Fill Tx aggregated buffer */ #ifdef CONFIG_MV_TDM_SUPPORT if(mvTdmTx(txBuff) != MV_OK) #else if(mvCommUnitTx(txBuff) != MV_OK) #endif /* CONFIG_MV_TDM_SUPPORT */ printk("%s: could not fill Tx buffer\n",__FUNCTION__); } } /* Clear txBuff for next iteration */ txBuff = NULL; TRC_REC("<-%s\n",__FUNCTION__); return; }
static ssize_t mp_write(struct file *file_p, const char __user *buf, size_t length, loff_t * ppos) { MV_PHONE *mp = file_p->private_data; MV_STATUS status; unsigned long count = 0; int err = 0; TRC_REC("->%s ch%d\n",__FUNCTION__,mp->ch); count = min(length, (size_t)MV_TDM_BUFF_SIZE); status = mvTdmChTx(mp->ch_info, (MV_U8 *)buf, count); if(status == MV_NOT_READY) { TRC_REC("write not ready, try again\n"); err = -EAGAIN; } else if(status == MV_FAIL) { TRC_REC("copy from user failed\n"); printk("%s: copy from user failed\n",__FUNCTION__); err = -EFAULT; } else { TRC_REC("copy from user ok\n"); err = 0; } TRC_REC("<-%s\n",__FUNCTION__); return (err)?err:count; }
static unsigned int mp_poll(struct file *file_p, poll_table * wait) { MV_PHONE *mp = file_p->private_data; unsigned int mask = 0; TRC_REC("->%s ch%d\n",__FUNCTION__,mp->ch); poll_wait(file_p, &(mp->poll_q), wait); if(mvTdmChRxReady(mp->ch_info)) { mask |= POLLIN | POLLRDNORM; /* readable */ TRC_REC("poll can read\n"); } if(mvTdmChTxReady(mp->ch_info)) { mask |= POLLOUT | POLLWRNORM; /* writable */ TRC_REC("poll can write\n"); } if(mvTdmChExceptionReady(mp->ch_info)) { mask |= POLLPRI; /* events */ TRC_REC("poll can get event\n"); } TRC_REC("<-%s\n",__FUNCTION__); return mask; }
static ssize_t tdm_dev_write(struct file *file_p, const char __user *buf, size_t size, loff_t * ppos) { unsigned long flags = 0; MV_STATUS status; size_t ret = size; TRC_REC("->%s\n",__FUNCTION__); if(tx_buff_p != NULL) { if (copy_from_user(tx_buff_p, buf, size)) ret = -EFAULT; atomic_set(&tx_ready, DISABLE); spin_lock_irqsave(&tdm_dev_lock, flags); #ifdef CONFIG_MV_TDM_SUPPORT status = mvTdmTx(tx_buff_p); #else status = mvCommUnitTx(tx_buff_p); #endif spin_unlock_irqrestore(&tdm_dev_lock, flags); tx_buff_p = NULL; if(status != MV_OK) printk("%s: could not fill Tx buffer\n",__FUNCTION__); } else { ret = 0; TRC_REC("%s: missed Tx buffer\n",__FUNCTION__); } TRC_REC("<-%s\n",__FUNCTION__); return ret; }
void tdm_dev_tx_callback(unsigned char* tx_buff, int size) { TRC_REC("->%s\n",__FUNCTION__); tx_buff_p = tx_buff; atomic_set(&tx_ready, ENABLE); wake_up_interruptible(&tdm_dev_wait); TRC_REC("<-%s\n",__FUNCTION__); return; }
void tdm_dev_rx_callback(unsigned char* rx_buff, int size) { TRC_REC("->%s\n",__FUNCTION__); rx_buff_p = rx_temp_buff; memcpy(rx_buff_p, rx_buff, size); atomic_set(&rx_ready, ENABLE); wake_up_interruptible(&tdm_dev_wait); TRC_REC("<-%s\n",__FUNCTION__); return; }
void dumpDaaRegs(unsigned int daa_dev) { int i; for(i=1; i < NUM_OF_REGS; i++) TRC_REC("Register %d: 0x%x\n",i, readDaaDirectReg(daa_dev, i)); }
void enableDaaInterrupts(unsigned int daa_dev) { TRC_REC("enable daa-%d interrupts\n",((MV_DAA_DEV*)(daa_dev))->ch); /* first, clear source register */ writeDaaDirectReg(daa_dev, DAA_INTERRUPT_SOURCE_REG, 0); /* enable interrupts in mask register */ writeDaaDirectReg(daa_dev, DAA_INTERRUPT_MASK_REG, (DAA_DODM | DAA_RDTM)); }
int checkDaaInterrupts(unsigned int daa_dev) { unsigned char cause , mask, control, cause_and_mask; MV_DAA_DEV *pDaaDev = (MV_DAA_DEV *)daa_dev; cause = readDaaDirectReg(daa_dev, DAA_INTERRUPT_SOURCE_REG); mask = readDaaDirectReg(daa_dev, DAA_INTERRUPT_MASK_REG); cause_and_mask = cause & mask; /* check ring */ if(cause_and_mask & DAA_RDTI) { TRC_REC("*** Ring Detected ***\n"); pDaaDev->ring = 1; writeDaaDirectReg(daa_dev, DAA_INTERRUPT_MASK_REG, (mask & ~DAA_POLM)); control = readDaaDirectReg(daa_dev, DAA_DAA_CONTROL_2); writeDaaDirectReg(daa_dev, DAA_DAA_CONTROL_2, (control & (~DAA_PDL))); } /* check parallel phone detection */ if(cause_and_mask & DAA_DODI) { TRC_REC("*** Drop Out Detected ***\n"); pDaaDev->drop_out = 1; } /* check reverse polarity */ if(cause_and_mask & DAA_POLI) { TRC_REC("*** Reverse Polarity Detected ***\n"); pDaaDev->reverse_polarity = 1; } /* clear interrupts */ writeDaaDirectReg(daa_dev, DAA_INTERRUPT_SOURCE_REG, 0); if(cause_and_mask) return 1; else return 0; }
static int mp_open(struct phone_device *p, struct file *file_p) { MV_PHONE *mp = get_mp(p->board); file_p->private_data = mp; printk("Opening phone channel %d - \n",mp->ch); TRC_REC("->%s ch%d\n",__FUNCTION__,mp->ch); if (file_p->f_mode & FMODE_READ) { if(!mp->readers) { mp->readers++; } else { printk("device is busy (read)\n"); return -EBUSY; } } if (file_p->f_mode & FMODE_WRITE) { if(!mp->writers) { mp->writers++; } else { if (file_p->f_mode & FMODE_READ) { mp->readers--; } printk("device is busy (write)\n"); return -EBUSY; } } if(request_irq(mp->irq, mp_int_handler, SA_SHIRQ | SA_INTERRUPT, "MP", mp ) ) { printk("Failed to connect IRQ %d\n", mp->irq); mp->irq = 0; return -EIO; } mvTdmChStart(mp->ch_info); TRC_REC("<-%s\n",__FUNCTION__); return 0; }
/* ** Two types of interrupts exists: ** (1) Slic async event (e.g. on/off-hook). ** (2) FPGA sync 10ms event (data is ready for read+write) */ static irqreturn_t mp_int_handler(int irq, void *dev_id, struct pt_regs *regs) { MV_PHONE *mp = dev_id; irqreturn_t ret; TRC_REC("->->->%s\n",__FUNCTION__); if(mvTdmIsr() == MV_OK) { TRC_REC("wake up poll\n"); wake_up_interruptible(&mp->poll_q); ret = IRQ_HANDLED; } else { TRC_REC("bogus isr\n"); ret = IRQ_NONE; } TRC_REC("<-%s\n",__FUNCTION__); return ret; }
static ssize_t tdm_dev_read(struct file *file_p, char __user *buf, size_t size, loff_t * ppos) { size_t ret = size; TRC_REC("->%s\n",__FUNCTION__); if(rx_buff_p != NULL) { if (copy_to_user(buf, rx_buff_p, size)) ret = -EFAULT; rx_buff_p = NULL; atomic_set(&rx_ready, DISABLE); } else { ret = 0; TRC_REC("%s: missed Rx buffer\n",__FUNCTION__); } TRC_REC("<-%s\n",__FUNCTION__); return ret; }
static unsigned int tdm_dev_poll(struct file *file_p, poll_table *poll_table_p) { int mask = 0; TRC_REC("->%s\n",__FUNCTION__); poll_wait(file_p, &tdm_dev_wait, poll_table_p); if(atomic_read(&rx_ready)) { mask |= POLLIN | POLLRDNORM; /* readable */ TRC_REC("poll can read\n"); } if(atomic_read(&tx_ready)) { mask |= POLLOUT | POLLWRNORM; /* writable */ TRC_REC("poll can write\n"); } TRC_REC("<-%s\n",__FUNCTION__); return mask; }
static void tdm_if_pcm_stop(void) { unsigned long flags; TRC_REC("->%s\n",__FUNCTION__); spin_lock_irqsave(&tdm_if_lock, flags); if(pcm_enable) { pcm_enable = 0; rxBuff = txBuff = NULL; #ifdef CONFIG_MV_TDM_SUPPORT mvTdmPcmStop(); #else mvCommUnitPcmStop(); #endif } spin_unlock_irqrestore(&tdm_if_lock, flags); TRC_REC("<-%s\n",__FUNCTION__); return; }
void tdm_if_exit(void) { /* Check if already stopped */ if(!irq_init && !pcm_enable && !tdm_init) return; TRC_REC("->%s\n",__FUNCTION__); if(irq_init) { /* Release IRQ */ free_irq(irqnr, NULL); irq_init = 0; } /* Stop PCM data sampling */ if(pcm_enable) tdm_if_pcm_stop(); if(tdm_init) { #ifdef CONFIG_MV_TDM_SUPPORT mvTdmRelease(); #else mvCommUnitRelease(); #endif tdm_init = 0; } /* Remove proc directory & entries */ remove_proc_entry("tdm_init", tdm_stats); remove_proc_entry("rx_miss", tdm_stats); remove_proc_entry("tx_miss", tdm_stats); remove_proc_entry("rx_over", tdm_stats); remove_proc_entry("tx_under", tdm_stats); remove_proc_entry("tdm", NULL); TRC_REC("<-%s\n",__FUNCTION__); TRC_OUTPUT(); TRC_RELEASE(); }
static int mp_close(struct inode *inode, struct file *file_p) { MV_PHONE *mp = file_p->private_data; printk("Closing Marvell phone%d device\n",mp->ch); TRC_REC("->%s ch%d\n",__FUNCTION__,mp->ch); mvTdmChStop(mp->ch_info); free_irq(mp->irq, mp); if (file_p->f_mode & FMODE_READ) mp->readers--; if (file_p->f_mode & FMODE_WRITE) mp->writers--; file_p->private_data = NULL; TRC_REC("<-%s\n",__FUNCTION__); TRC_OUTPUT(); return 0; }
static int __init mp_init(void) { MV_PHONE *mp; int i; printk("%s, %s\n", MP_NAME, MP_VER); TRC_INIT(); TRC_REC("->%s\n",__FUNCTION__); /* General TDM and SLIC init */ TRC_REC("tdm init\n"); mvTdmInit(); mvTdmShowProperties(); /* per channel init */ for(i=0; i<MV_TDM_MAX_CHANNELS; i++) { printk("Initializing channel %d\n",i); TRC_REC("ch%d init\n",i); mp = get_mp(i); mp->p.board = mp->ch = i; mp->p.f_op = &mp_fops; mp->p.open = mp_open; mp->irq = MP_IRQ; init_waitqueue_head(&mp->poll_q); if(mvTdmChInit(&mp->p, i, &(mp->ch_info)) == MV_OK) { /*mvTdmChShowProperties(mp->ch_info);*/ phone_register_device(&mp->p, PHONE_UNIT_ANY); printk("phone%d registered\n",i); } else { printk("%s: error, failed to init ch%d\n",__FUNCTION__,i); } } TRC_REC("<-%s\n",__FUNCTION__); return 0; }
static void __exit mp_exit(void) { MV_PHONE *mp; int i; TRC_REC("->%s\n",__FUNCTION__); for(i=0; i<MV_TDM_MAX_CHANNELS; i++) { TRC_REC("ch%d remove\n",i); mp = get_mp(i); mvTdmChRemove(mp->ch_info); mp->irq = 0; mp->p.f_op = NULL; mp->p.open = NULL; mp->p.board = 0; phone_unregister_device(&mp->p); printk("phone%d removed\n",i); } TRC_REC("<-%s\n",__FUNCTION__); TRC_OUTPUT(); TRC_RELEASE(); }
static int mp_ioctl(struct inode *inode, struct file *file_p, unsigned int cmd, unsigned long arg) { MV_PHONE *mp = get_mp(iminor(inode) & 0xf); int retval = 0; TRC_REC("->%s ch%d\n",__FUNCTION__,mp->ch); /* check ioctls only root can use */ if (!capable(CAP_SYS_ADMIN)) { return -EPERM; } disable_irq(mp->irq); switch (cmd) { #ifdef MV_88F5181L case PHONE_REC_START: TRC_REC("PHONE_REC_START\n"); mvTdmChRxEnable(mp->ch_info); break; case PHONE_REC_STOP: TRC_REC("PHONE_REC_STOP\n"); mvTdmChRxDisable(mp->ch_info); break; case PHONE_PLAY_START: TRC_REC("PHONE_PLAY_START\n"); mvTdmChTxEnable(mp->ch_info); break; case PHONE_PLAY_STOP: TRC_REC("PHONE_PLAY_STOP\n"); mvTdmChTxDisable(mp->ch_info); break; #else case PHONE_REC_START: case PHONE_PLAY_START: TRC_REC("PHONE_REC/PLAY_START\n"); mvTdmChEnable(mp->ch_info); break; case PHONE_REC_STOP: case PHONE_PLAY_STOP: TRC_REC("PHONE_REC/PLAY_STOP\n"); mvTdmChDisable(mp->ch_info); break; #endif case PHONE_DIALTONE: TRC_REC("PHONE_DIALTONE\n"); mvTdmChDialTone(mp->ch_info); break; case PHONE_BUSY: TRC_REC("PHONE_BUSY\n"); mvTdmChBusyTone(mp->ch_info); break; case PHONE_CPT_STOP: TRC_REC("PHONE_CPT_STOP\n"); mvTdmChStopTone(mp->ch_info); break; case PHONE_RING_START: TRC_REC("PHONE_RING_START\n"); mvTdmChStartRing(mp->ch_info); break; case PHONE_RING_STOP: TRC_REC("PHONE_RING_STOP\n"); mvTdmChStopRing(mp->ch_info); break; case PHONE_EXCEPTION: { MV_U8 offhook; union telephony_exception ex; TRC_REC("PHONE_EXCEPTION\n"); ex.bytes = 0; mvTdmChEventGet(mp->ch_info, &offhook); if(offhook) { TRC_REC("off hook\n"); ex.bits.hookstate = 1; } else { TRC_REC("on hook\n"); } retval = ex.bytes; } break; case PHONE_RINGBACK: TRC_REC("PHONE_RINGBACK\n"); mvTdmChRingBackTone(mp->ch_info); break; case PHONE_MV_READ_SLIC_REG: #ifdef MV_IOCTL mvTdmSpiRead(arg, (MV_U8*)&retval); #else printk("Driver is not configured to support this IOCTL\n"); retval = -1; #endif break; case PHONE_MV_WRITE_SLIC_REG: #ifdef MV_IOCTL mvTdmSpiWrite((arg>>16)&0xff,arg&0xff); #else printk("Driver is not configured to support this IOCTL\n"); retval = -1; #endif break; case PHONE_MV_READ_REG: #ifdef MV_IOCTL retval = *((unsigned int*)(0xf1000000|arg)); #else printk("Driver is not configured to support this IOCTL\n"); retval = -1; #endif break; case PHONE_MV_WRITE_REG: #ifdef MV_IOCTL printk("not implemented yet\n"); #else printk("Driver is not configured to support this IOCTL\n"); retval = -1; #endif break; case PHONE_MV_SPI_TEST: #ifdef MV_IOCTL mvTdmChSpiTest(10000); #else printk("Driver is not configured to support this IOCTL\n"); retval = -1; #endif break; default: printk("%s: Unsupported IOCTL\n",__FUNCTION__); } TRC_REC("<-%s\n",__FUNCTION__); enable_irq(mp->irq); return retval; }
MV_STATUS tdm_if_init(tdm_if_register_ops_t* register_ops, tdm_if_params_t* tdm_if_params) { MV_TDM_PARAMS tdm_params; printk("Loading Marvell Telephony Driver\n"); /* Check if any SLIC module exists */ if(mvBoardTdmDevicesCountGet() == 0) { mvCtrlPwrClckSet(TDM_2CH_UNIT_ID, 0, MV_FALSE); printk("%s: Warning, no SLIC module is connected\n",__FUNCTION__); return MV_OK; } /* Check that selected TDM unit is active */ if (MV_FALSE == mvCtrlPwrClckGet(mvCtrlTdmUnitTypeGet(), 0)) { printk("%s: Warning, TDM is powered off\n",__FUNCTION__); return MV_OK; } if((register_ops == NULL) || (tdm_if_params == NULL)) { printk("%s: bad parameters\n",__FUNCTION__); return MV_ERROR; } /* Check callbacks */ if(register_ops->tdm_if_pcm_ops.pcm_tx_callback == NULL || register_ops->tdm_if_pcm_ops.pcm_rx_callback == NULL ) { printk("%s: missing parameters\n",__FUNCTION__); return MV_ERROR; } /* Reset globals */ rxBuff = txBuff = NULL; #ifdef CONFIG_MV_TDM_SUPPORT pcm_enable = 0; #else pcm_enable = 1; #endif irq_init = 0; tdm_init = 0; /* Extract test enable */ test_enable = tdm_if_params->test_enable; /* Calculate Rx/Tx buffer size(use in callbacks) */ buff_size = (tdm_if_params->pcm_format * tdm_if_params->total_lines * 80 * (tdm_if_params->sampling_period/MV_TDM_BASE_SAMPLING_PERIOD)); /* Extract TDM irq number */ irqnr = mvCtrlTdmUnitIrqGet(); /* Start Marvell trace */ TRC_START(); TRC_INIT(NULL, NULL, 0, 0); TRC_REC("->%s\n",__FUNCTION__); /* Assign TDM parameters */ memcpy(&tdm_params, tdm_if_params, sizeof(MV_TDM_PARAMS)); /* Assign control callbacks */ tdm_if_register_ops = register_ops; tdm_if_register_ops->tdm_if_ctl_ops.ctl_pcm_start = tdm_if_pcm_start; tdm_if_register_ops->tdm_if_ctl_ops.ctl_pcm_stop = tdm_if_pcm_stop; /* TDM init */ if(mvSysTdmInit(&tdm_params) != MV_OK) { printk("%s: Error, TDM initialization failed !!!\n",__FUNCTION__); return MV_ERROR; } tdm_init = 1; /* Register TDM interrupt */ if (request_irq(irqnr, tdm_if_isr, IRQF_DISABLED, "tdm", NULL)) { printk("%s: Failed to connect irq(%d)\n", __FUNCTION__, irqnr); return MV_ERROR; } irq_init = 1; /* Create TDM procFS statistics */ tdm_stats = proc_mkdir("tdm", NULL); create_proc_read_entry("tdm_init", 0, tdm_stats, proc_tdm_init_read, NULL); create_proc_read_entry("rx_miss", 0, tdm_stats, proc_rx_miss_read, NULL); create_proc_read_entry("tx_miss", 0, tdm_stats, proc_tx_miss_read, NULL); create_proc_read_entry("rx_over", 0, tdm_stats, proc_rx_over_read, NULL); create_proc_read_entry("tx_under", 0, tdm_stats, proc_tx_under_read, NULL); TRC_REC("Marvell Telephony Driver Loaded Successfully\n"); #ifdef CONFIG_MV_COMM_UNIT_SUPPORT /* WA to stop the MCDMA gracefully after commUnit initialization */ tdm_if_pcm_stop(); #endif TRC_REC("<-%s\n",__FUNCTION__); return MV_OK; }
static irqreturn_t tdm_if_isr(int irq, void* dev_id) { MV_TDM_INT_INFO tdm_int_info; unsigned int int_type; TRC_REC("->%s\n",__FUNCTION__); /* Extract interrupt information from low level ISR */ #ifdef CONFIG_MV_TDM_SUPPORT mvTdmIntLow(&tdm_int_info); #else mvCommUnitIntLow(&tdm_int_info); #endif int_type = tdm_int_info.intType; /*device_id = tdm_int_info.cs;*/ /* Nothing to do - return */ if(int_type == MV_EMPTY_INT) goto out; /* Support multiple interrupt handling */ /* RX interrupt */ if(int_type & MV_RX_INT) { if(rxBuff != NULL) { rx_miss++; TRC_REC("%s: Warning, missed Rx buffer processing !!!\n",__FUNCTION__); } else { rxBuff = tdm_int_info.tdmRxBuff; #ifdef CONFIG_MV_PHONE_USE_IRQ_PROCESSING TRC_REC("%s: running Rx in ISR\n", __FUNCTION__); tdm_if_pcm_rx_process(); #else /* Schedule Rx processing within SOFT_IRQ context */ TRC_REC("%s: schedule Rx tasklet\n", __FUNCTION__); tasklet_hi_schedule(&tdm_if_rx_tasklet); #endif } } /* TX interrupt */ if(int_type & MV_TX_INT) { if(txBuff != NULL) { tx_miss++; TRC_REC("%s: Warning, missed Tx buffer processing !!!\n",__FUNCTION__); } else { txBuff = tdm_int_info.tdmTxBuff; #ifdef CONFIG_MV_PHONE_USE_IRQ_PROCESSING TRC_REC("%s: running Tx in ISR\n", __FUNCTION__); tdm_if_pcm_tx_process(); #else /* Schedule Tx processing within SOFT_IRQ context */ TRC_REC("%s: schedule Tx tasklet\n", __FUNCTION__); tasklet_hi_schedule(&tdm_if_tx_tasklet); #endif } } /* PHONE interrupt */ if(int_type & MV_PHONE_INT) { /* TBD */ } /* ERROR interrupt */ if(int_type & MV_ERROR_INT) { if(int_type & MV_RX_ERROR_INT) rx_over++; if(int_type & MV_TX_ERROR_INT) tx_under++; } out: TRC_REC("<-%s\n",__FUNCTION__); return IRQ_HANDLED; }
/* Low level TDM interrupt service routine */ MV_VOID mvTdmIntLow(mv_tdm_int_info_t* tdmIntInfo) { MV_U32 statusReg, maskReg, statusAndMask; MV_U8 ch; MV_TRC_REC("->%s\n",__FUNCTION__); /* Read Status & mask registers */ statusReg = MV_REG_READ(INT_STATUS_REG); maskReg = MV_REG_READ(INT_EVENT_MASK_REG); MV_TRC_REC("CAUSE(0x%x), MASK(0x%x)\n", statusReg, maskReg); /* Refer only to unmasked bits */ statusAndMask = statusReg & maskReg; /* Reset params */ tdmIntInfo->tdmRxBuff = NULL; tdmIntInfo->tdmTxBuff = NULL; tdmIntInfo->intType = MV_EMPTY_INT; /* Handle SLIC/DAA int */ if(statusAndMask & SLIC_INT_BIT) { MV_TRC_REC("Phone interrupt !!!\n"); tdmIntInfo->intType |= MV_PHONE_INT; } /* Return in case TDM is disabled */ if(!tdmEnable) { MV_TRC_REC("TDM is disabled - quit low level ISR\n"); MV_REG_WRITE(INT_STATUS_REG, ~statusReg); return; } if(statusAndMask & DMA_ABORT_BIT) { mvOsPrintf("DMA data abort. Address: 0x%08x, Info: 0x%08x\n", MV_REG_READ(DMA_ABORT_ADDR_REG), MV_REG_READ(DMA_ABORT_INFO_REG)); tdmIntInfo->intType |= MV_ERROR_INT; } for(ch = 0; ch < MV_TDM_TOTAL_CHANNELS; ch++) { if (statusAndMask & TDM_INT_TX(ch)) { /* Give next buff to TDM and set curr buff as empty */ if (statusAndMask & TX_BIT(ch)) { MV_TRC_REC("Tx interrupt(ch%d) !!!\n", ch); /* MV_OK -> Tx is done for both channels */ if(mvTdmChTxLow(ch) == MV_OK) { MV_TRC_REC("Assign Tx aggregate buffer for further processing\n"); tdmIntInfo->tdmTxBuff = txAggrBuffVirt; tdmIntInfo->intType |= MV_TX_INT; } } if(statusAndMask & TX_UNDERFLOW_BIT(ch)) { mvOsPrintf("Tx underflow, disable interrupts for channel %d !!!\n", ch); tdmIntInfo->intType |= MV_ERROR_INT; MV_REG_WRITE(INT_EVENT_MASK_REG, (maskReg & (~(TDM_INT_TX(ch))))); } } if (statusAndMask & TDM_INT_RX(ch)) { if (statusAndMask & RX_BIT(ch)) { MV_TRC_REC("Rx interrupt(ch%d) !!!\n", ch); /* MV_OK -> Tx is done for both channels */ if(mvTdmChRxLow(ch) == MV_OK) { MV_TRC_REC("Assign Rx aggregate buffer for further processing\n"); tdmIntInfo->tdmRxBuff = rxAggrBuffVirt; tdmIntInfo->intType |= MV_RX_INT; } } if (statusAndMask & RX_OVERFLOW_BIT(ch)) { mvOsPrintf("Rx overflow, disable interrupts for channel %d !!!\n", ch); tdmIntInfo->intType |= MV_ERROR_INT; MV_REG_WRITE(INT_EVENT_MASK_REG, (maskReg & (~(TDM_INT_RX(ch))))); } } } /* clear TDM interrupts */ MV_REG_WRITE(INT_STATUS_REG, ~statusReg); TRC_REC("<-%s\n",__FUNCTION__); return; }
void disableDaaInterrupts(unsigned int daa_dev) { TRC_REC("disable daa-%d interrupts\n",((MV_DAA_DEV*)(daa_dev))->ch); writeDaaDirectReg(daa_dev, DAA_INTERRUPT_MASK_REG, 0); }