Пример #1
0
/* handle interrupt for specified sub device; DmaMode == DEV_WRITE_S*/
PRIVATE void handle_int_write(int sub_dev_nr) 
{
	sub_dev_t *sub_dev_ptr;
	int r;

	sub_dev_ptr = &sub_dev[sub_dev_nr];

	dprint("Finished playing dma[%d] ", sub_dev_ptr->DmaReadNext);
	sub_dev_ptr->DmaReadNext = 
		(sub_dev_ptr->DmaReadNext + 1) % sub_dev_ptr->NrOfDmaFragments;
	sub_dev_ptr->DmaLength -= 1;

	if (sub_dev_ptr->BufLength != 0) { /* Data in extra buf, copy to Dma buf */

		dprint(" buf[%d] -> dma[%d] ", 
				sub_dev_ptr->BufReadNext, sub_dev_ptr->DmaFillNext);
		memcpy(sub_dev_ptr->DmaPtr + 
				sub_dev_ptr->DmaFillNext * sub_dev_ptr->FragSize, 
				sub_dev_ptr->ExtraBuf + 
				sub_dev_ptr->BufReadNext * sub_dev_ptr->FragSize, 
				sub_dev_ptr->FragSize);

		sub_dev_ptr->BufReadNext = 
			(sub_dev_ptr->BufReadNext + 1) % sub_dev_ptr->NrOfExtraBuffers;
		sub_dev_ptr->DmaFillNext = 
			(sub_dev_ptr->DmaFillNext + 1) % sub_dev_ptr->NrOfDmaFragments;

		sub_dev_ptr->BufLength -= 1;
		sub_dev_ptr->DmaLength += 1;
	} 

	/* space became available, possibly copy new data from user */
	data_from_user(sub_dev_ptr);

	if(sub_dev_ptr->DmaLength == 0) { /* Dma buffer empty, stop Dma transfer */

		sub_dev_ptr->OutOfData = TRUE; /* we're out of data */
		dprint("No more work...!\n");
		if (!sub_dev_ptr->Opened) {
			close_sub_dev(sub_dev_ptr->Nr);
			dprint("Stopping sub device %d\n", sub_dev_ptr->Nr);
			return;
		}
		dprint("Pausing sub device %d\n",sub_dev_ptr->Nr);
		drv_pause(sub_dev_ptr->Nr);
		return;
	}

	dprint("\n");

	/* confirm and reenable interrupt from this sub dev */
	drv_reenable_int(sub_dev_nr);
#if 0
	/* reenable irq_hook*/
	if ((r=sys_irqenable(&irq_hook_id)) != OK) {
		error("%s Couldn't enable IRQ\n", drv.DriverName);
	}
#endif
}
Пример #2
0
/* all IO-ctl's sent to the upper driver are passed to this function */
int drv_io_ctl(int request, void * val, int * len, int sub_dev) {

	int status;

	switch(request) {
		case DSPIORATE:	
			status = set_sample_rate(*((u32_t *) val), sub_dev); break;
		case DSPIOSTEREO:	       
			status = set_stereo(*((u32_t *) val), sub_dev); break;
		case DSPIOBITS:	         
			status = set_bits(*((u32_t *) val), sub_dev); break;
		case DSPIOSIZE:	         
			status = set_frag_size(*((u32_t *) val), sub_dev); break;
		case DSPIOSIGN:	         
			status = set_sign(*((u32_t *) val), sub_dev); break;
		case DSPIOMAX:           
			status = get_max_frag_size(val, len, sub_dev); break;
		case DSPIORESET:         
			status = reset(sub_dev); break;
		case DSPIOFREEBUF:
			status = free_buf(val, len, sub_dev); break;
		case DSPIOSAMPLESINBUF: 
			status = get_samples_in_buf(val, len, sub_dev); break;
		case DSPIOPAUSE:
			status = drv_pause(sub_dev); break;
		case DSPIORESUME:
			status = drv_resume(sub_dev); break;
		case MIXIOGETVOLUME:
			status = get_set_volume(val, len, sub_dev, 0); break;
		case MIXIOSETVOLUME:
			status = get_set_volume(val, len, sub_dev, 1); break;
		default:                 
			status = EINVAL; break;
	}

	return status;
}