static void setup_dma_dsp(struct net_device *dev, struct sm_state *sm, int send) { unsigned long flags; static const unsigned char sbcmode[2][2] = { { SBC_LO_INPUT_AUTOINIT, SBC_LO_OUTPUT_AUTOINIT }, { SBC_HI_INPUT_AUTOINIT, SBC_HI_OUTPUT_AUTOINIT } }; static const unsigned char sbc4mode[2] = { SBC4_IN8_AI, SBC4_OUT8_AI }; static const unsigned char sbcskr[2] = { SBC_SPEAKER_OFF, SBC_SPEAKER_ON }; unsigned int nsamps; send = !!send; if (!reset_dsp(dev)) { printk(KERN_ERR "%s: sbc: cannot reset sb dsp\n", sm_drvname); return; } save_flags(flags); cli(); sbc_int_ack_8bit(dev); write_dsp(dev, SBC_SAMPLE_RATE); /* set sampling rate */ write_dsp(dev, SCSTATE->fmt[send]); write_dsp(dev, sbcskr[send]); nsamps = dma_setup(sm, send, dev->dma) - 1; sbc_int_ack_8bit(dev); if (SCSTATE->revhi >= 4) { write_dsp(dev, sbc4mode[send]); write_dsp(dev, SBC4_MODE_UNS_MONO); write_dsp(dev, nsamps & 0xff); write_dsp(dev, nsamps >> 8); } else {
int dsp_start( struct audiodsp_priv *priv, struct audiodsp_microcode *mcode) { int i; int res; mutex_lock(&priv->dsp_mutex); halt_dsp(priv); if(priv->stream_fmt!=priv->last_stream_fmt) // remove the trick, bug fixed on dsp side { if(audiodsp_microcode_load(audiodsp_privdata(),mcode)!=0) { printk("load microcode error\n"); res=-1; goto exit; } priv->last_stream_fmt=priv->stream_fmt; } if((res=dsp_set_stack(priv))) goto exit; if((res=dsp_set_heap(priv))) goto exit; if((res=dsp_set_stream_buffer(priv))) goto exit; if(!priv->dsp_is_started) reset_dsp(priv); else{ dsp_mailbox_send(priv,1,M2B_IRQ0_DSP_WAKEUP,0,0,0); msleep(1);/*waiting arc625 run again */ } priv->dsp_start_time=jiffies; for(i=0;i<1000;i++) { if(DSP_RD(DSP_STATUS)==DSP_STATUS_RUNING) break; msleep(1); } if(i>=1000) { DSP_PRNT("dsp not running \n"); res=-1; } else { DSP_PRNT("dsp status=%lx\n",DSP_RD(DSP_STATUS)); priv->dsp_is_started=1; res=0; } exit: mutex_unlock(&priv->dsp_mutex); return res; }
static NTSTATUS NTAPI Dispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp) /* * FUNCTION: Handles user mode requests * ARGUMENTS: * DeviceObject = Device for request * Irp = I/O request packet describing request * RETURNS: Success or failure */ { PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp); NTSTATUS status; switch (Stack->MajorFunction) { case IRP_MJ_CREATE: DPRINT1("(SoundBlaster 16 Driver WaveOut) Creating\n"); reset_dsp(sb16.base); status = STATUS_SUCCESS; break; case IRP_MJ_CLOSE: status = STATUS_SUCCESS; break; case IRP_MJ_WRITE: DPRINT1("(SoundBlaster 16 Driver) Writing %d bytes\n",Stack->Parameters.Write.Length); sb16_play((WAVE_HDR*)Irp->UserBuffer); status = STATUS_SUCCESS; break; default: status = STATUS_NOT_IMPLEMENTED; break; } Irp->IoStatus.Status = status; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT); return(status); }
/*! * this function sends a jump vector to DSP * in order to resume execution of a previously * downloaded executable image. * * @return Returns -1 if it is not possible to allocate * channel 0 or channel 1, both required by boot * protocol to issue a start_application request. * Returns request's result otherwise. */ void dsp_startapp_request(void) { unsigned long *virtual_addr = NULL; unsigned long physical_addr = 0; /* disable security mode */ disable_security_mode(); /*execute a dsp hardware reset */ reset_dsp(); /* Get a chunk of virtual memory to hold DSP image start address */ virtual_addr = (unsigned long *)kmalloc(sizeof(unsigned long), GFP_KERNEL); *virtual_addr = IMAGE_START_ADDRESS; physical_addr = __pa((volatile void *)virtual_addr); /* Send a start application request to the DSP */ *mcu_mtr0_register = STARTAPP_REQUEST; /* Send the start physical address to the DSP */ *mcu_mtr1_register = physical_addr; /* Wait for the DSP response */ while (!(*mcu_msr_register & 0x08000000)) ; /*check if DSP has acknowledged our request */ if ((*mcu_mrr0_register & 0x000000FF) != STARTAPP_RESPONSE) printk ("STARCORE: DSP core DOES NOT acknowledged STARTAPP request!!\n"); else printk("STARCORE: DSP core acknowledged STARTAPP request\n"); kfree(virtual_addr); }