PRIVATE void data_from_user(sub_dev_t *subdev) {

  if (subdev->DmaLength == subdev->NrOfDmaFragments &&
      subdev->BufLength == subdev->NrOfExtraBuffers) return; /* no space */
  
  if (!subdev->RevivePending) return; /* no new data waiting to be copied */
  
  if (subdev->RevivePending && 
      subdev->ReadyToRevive) return; /* we already got this data */
  
  
  if (subdev->DmaLength < subdev->NrOfDmaFragments) { /* room in dma buf */
    
      sys_datacopy(subdev->ReviveProcNr, 
      (vir_bytes)subdev->UserBuf, 
      SELF, 
      (vir_bytes)subdev->DmaPtr + subdev->DmaFillNext * subdev->FragSize, 
      (phys_bytes)subdev->FragSize);
  
    dprint(" user -> dma[%d]\n", subdev->DmaFillNext);
    subdev->DmaLength += 1;
    subdev->DmaFillNext = (subdev->DmaFillNext + 1) % subdev->NrOfDmaFragments;
    
  } else { /* room in extra buf */ 

		sys_datacopy(subdev->ReviveProcNr, 
      (vir_bytes)subdev->UserBuf, 
      SELF, 
      (vir_bytes)subdev->ExtraBuf + subdev->BufFillNext * subdev->FragSize, 
      (phys_bytes)subdev->FragSize);
      
		dprint(" user -> buf[%d]\n", subdev->BufFillNext);
		subdev->BufLength += 1;
		
		subdev->BufFillNext = (subdev->BufFillNext + 1) % subdev->NrOfExtraBuffers;

	}
	if(subdev->OutOfData) { /* if device paused (because of lack of data) */
    subdev->OutOfData = FALSE;
    drv_reenable_int(subdev->Nr);
    /* reenable irq_hook*/
  	if ((sys_irqenable(&irq_hook_id)) != OK) {
      error("%s: Couldn't enable IRQ", drv.DriverName);
    }
    drv_resume(subdev->Nr);  /* resume resume the sub device */
    
  }
  
	subdev->ReviveStatus = subdev->FragSize;
	subdev->ReadyToRevive = TRUE;
	notify(subdev->NotifyProcNr);
}
Exemple #2
0
int drv_start(int sub_dev, int UNUSED(DmaMode)) {
	u32_t enable_bit, result = 0;

	/* Write default values to device in case user failed to configure.
	   If user did configure properly, everything is written twice.
	   please raise your hand if you object against to this strategy...*/
	result |= set_sample_rate(aud_conf[sub_dev].sample_rate, sub_dev);
	result |= set_stereo(aud_conf[sub_dev].stereo, sub_dev);
	result |= set_bits(aud_conf[sub_dev].nr_of_bits, sub_dev);
	result |= set_sign(aud_conf[sub_dev].sign, sub_dev);

	/* set the interrupt count */
	result |= set_int_cnt(sub_dev);

	if (result) {
		return EIO;
	}

	/* if device currently paused, resume */
	drv_resume(sub_dev);

	switch(sub_dev) {
		case ADC1_CHAN: enable_bit = ADC1_EN;break;
		case DAC1_CHAN: enable_bit = DAC1_EN;break;
		case DAC2_CHAN: enable_bit = DAC2_EN;break;    
		default: return EINVAL;
	}

	/* enable interrupts from 'sub device' */
	drv_reenable_int(sub_dev);

	/* this means play!!! */
	pci_outw(reg(CHIP_SEL_CTRL), pci_inw(reg(CHIP_SEL_CTRL)) | enable_bit);

	aud_conf[sub_dev].busy = 1;

	return OK;
}
Exemple #3
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;
}
Exemple #4
0
PRIVATE void data_from_user(sub_dev_t *subdev)
{
	int r;
	message m;

	if (subdev->DmaLength == subdev->NrOfDmaFragments &&
			subdev->BufLength == subdev->NrOfExtraBuffers) return;/* no space */

	if (!subdev->RevivePending) return; /* no new data waiting to be copied */

	if (subdev->RevivePending && 
			subdev->ReadyToRevive) return; /* we already got this data */

	if (subdev->DmaLength < subdev->NrOfDmaFragments) { /* room in dma buf */

		sys_safecopyfrom(subdev->ReviveProcNr, 
				(vir_bytes)subdev->ReviveGrant, 0, 
				(vir_bytes)subdev->DmaPtr + 
				subdev->DmaFillNext * subdev->FragSize,
				(phys_bytes)subdev->FragSize, D);


		dprint(" user -> dma[%d]\n", subdev->DmaFillNext);
		subdev->DmaLength += 1;
		subdev->DmaFillNext = 
			(subdev->DmaFillNext + 1) % subdev->NrOfDmaFragments;

	} else { /* room in extra buf */ 

		sys_safecopyfrom(subdev->ReviveProcNr, 
				(vir_bytes)subdev->ReviveGrant, 0,
				(vir_bytes)subdev->ExtraBuf + 
				subdev->BufFillNext * subdev->FragSize, 
				(phys_bytes)subdev->FragSize, D);

		dprint(" user -> buf[%d]\n", subdev->BufFillNext);
		subdev->BufLength += 1;

		subdev->BufFillNext = 
			(subdev->BufFillNext + 1) % subdev->NrOfExtraBuffers;

	}
	if(subdev->OutOfData) { /* if device paused (because of lack of data) */
		subdev->OutOfData = FALSE;
		drv_reenable_int(subdev->Nr);
		/* reenable irq_hook*/
		if ((sys_irqenable(&irq_hook_id)) != OK) {
			error("%s: Couldn't enable IRQ", drv.DriverName);
		}
		drv_resume(subdev->Nr);  /* resume resume the sub device */
	}

	subdev->ReviveStatus = subdev->FragSize;
	subdev->ReadyToRevive = TRUE;

	m.m_type = DEV_REVIVE;			/* build message */
	m.REP_ENDPT = subdev->ReviveProcNr;
	m.REP_IO_GRANT = subdev->ReviveGrant;
	m.REP_STATUS = subdev->ReviveStatus;
	r= send(subdev->NotifyProcNr, &m);		/* send the message */
	if (r != OK)
	{
		printf("audio_fw: send to %d failed: %d\n",
			subdev->NotifyProcNr, r);
	}

	/* reset variables */
	subdev->ReadyToRevive = FALSE;
	subdev->RevivePending = 0;
}