Ejemplo n.º 1
0
/* 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;
}
Ejemplo n.º 2
0
/* 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;
}
Ejemplo n.º 3
0
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;
}
Ejemplo n.º 4
0
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;
}
Ejemplo n.º 5
0
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;
}
Ejemplo n.º 6
0
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;
}
Ejemplo n.º 7
0
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;
}
Ejemplo n.º 8
0
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));
}
Ejemplo n.º 9
0
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));		
}
Ejemplo n.º 10
0
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;
}
Ejemplo n.º 11
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;
}
Ejemplo n.º 12
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;
}
Ejemplo n.º 13
0
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;
}
Ejemplo n.º 14
0
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;
}
Ejemplo n.º 15
0
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;
}
Ejemplo n.º 16
0
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();
}
Ejemplo n.º 17
0
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;
}
Ejemplo n.º 18
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;
}
Ejemplo n.º 19
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();
}
Ejemplo n.º 20
0
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;
}
Ejemplo n.º 21
0
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;
}
Ejemplo n.º 22
0
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;
}
Ejemplo n.º 23
0
/* 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;
}
Ejemplo n.º 24
0
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);

}