⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nm256_audio.c

📁 linux和2410结合开发 用他可以生成2410所需的zImage文件
💻 C
📖 第 1 页 / 共 3 页
字号:
    else	nm256_peek_for_sig (card);    card->port[0].start_offset = card->port[0].end_offset - 98304;    printk (KERN_INFO "NM256: Mapping port 1 from 0x%x - 0x%x\n",	    card->port[0].start_offset, card->port[0].end_offset);    if (nm256_remap_ports (card)) {	kfree (card);	return 0;    }    /* See if we can get the interrupt. */    card->irq = pcidev->irq;    card->has_irq = 0;    if (nm256_grabInterrupt (card) != 0) {	nm256_release_ports (card);	kfree (card);	return 0;    }    nm256_releaseInterrupt (card);    /*     *	Init the board.     */    card->playbackBufferSize = 16384;    card->recordBufferSize = 16384;    card->coeffBuf = card->port[0].end_offset - NM_MAX_COEFFICIENT;    card->abuf2 = card->coeffBuf - card->recordBufferSize;    card->abuf1 = card->abuf2 - card->playbackBufferSize;    card->allCoeffBuf = card->abuf2 - (NM_TOTAL_COEFF_COUNT * 4);    /* Fixed setting. */    card->mixer = NM_MIXER_OFFSET;    card->mixer_values_init = 0;    card->is_open_play = 0;    card->is_open_record = 0;    card->coeffsCurrent = 0;    card->opencnt[0] = 0; card->opencnt[1] = 0;    /* Reasonable default settings, but largely unnecessary. */    for (x = 0; x < 2; x++) {	card->sinfo[x].bits = 8;	card->sinfo[x].stereo = 0;	card->sinfo[x].samplerate = 8000;    }    nm256_initHw (card);    for (x = 0; x < 2; x++) {	if ((card->dev[x] =	     sound_install_audiodrv(AUDIO_DRIVER_VERSION,				    "NM256", &nm256_audio_driver,				    sizeof(struct audio_driver),				    DMA_NODMA, AFMT_U8 | AFMT_S16_LE,				    NULL, -1, -1)) >= 0) {	    /* 1K minimum buffer size. */	    audio_devs[card->dev[x]]->min_fragment = 10;	    /* Maximum of 8K buffer size. */	    audio_devs[card->dev[x]]->max_fragment = 13;	}	else {	    printk(KERN_ERR "NM256: Too many PCM devices available\n");	    nm256_release_ports (card);	    kfree (card);	    return 0;	}    }    pci_set_drvdata(pcidev,card);    /* Insert the card in the list.  */    card->next_card = nmcard_list;    nmcard_list = card;    printk(KERN_INFO "Initialized NeoMagic %s audio in PCI native mode\n",	   verstr);    /*      * And our mixer.  (We should allow support for other mixers, maybe.)     */    nm256_install_mixer (card);    pmdev = pm_register(PM_PCI_DEV, PM_PCI_ID(pcidev), handle_pm_event);    if (pmdev)        pmdev->data = card;    return 1;}/* * PM event handler, so the card is properly reinitialized after a power * event. */static inthandle_pm_event (struct pm_dev *dev, pm_request_t rqst, void *data){    struct nm256_info *crd = (struct nm256_info*) dev->data;    if (crd) {        switch (rqst) {	case PM_SUSPEND:	    break;	case PM_RESUME:            {                int playing = crd->playing;                nm256_full_reset (crd);                /*                 * A little ugly, but that's ok; pretend the                 * block we were playing is done.                  */                if (playing)                    DMAbuf_outputintr (crd->dev_for_play, 1);            }	    break;	}    }    return 0;}static int __devinitnm256_probe(struct pci_dev *pcidev,const struct pci_device_id *pciid){    if (pcidev->device == PCI_DEVICE_ID_NEOMAGIC_NM256AV_AUDIO)	return nm256_install(pcidev, REV_NM256AV, "256AV");    if (pcidev->device == PCI_DEVICE_ID_NEOMAGIC_NM256ZX_AUDIO)	return nm256_install(pcidev, REV_NM256ZX, "256ZX");    return -1; /* should not come here ... */}static void __devinitnm256_remove(struct pci_dev *pcidev) {    struct nm256_info *xcard = pci_get_drvdata(pcidev);    struct nm256_info *card,*next_card = NULL;    for (card = nmcard_list; card != NULL; card = next_card) {	next_card = card->next_card;	if (card == xcard) {	    stopPlay (card);	    stopRecord (card);	    if (card->has_irq)		free_irq (card->irq, card);	    nm256_release_ports (card);	    sound_unload_mixerdev (card->mixer_oss_dev);	    sound_unload_audiodev (card->dev[0]);	    sound_unload_audiodev (card->dev[1]);	    kfree (card);	    break;	}    }    if (nmcard_list == card)    	nmcard_list = next_card;}/* * Open the device * * DEV  - device * MODE - mode to open device (logical OR of OPEN_READ and OPEN_WRITE) * * Called when opening the DMAbuf               (dmabuf.c:259) */static intnm256_audio_open(int dev, int mode){    struct nm256_info *card = nm256_find_card (dev);    int w;	    if (card == NULL)	return -ENODEV;    if (card->dev[0] == dev)	w = 0;    else if (card->dev[1] == dev)	w = 1;    else	return -ENODEV;    if (card->opencnt[w] > 0)	return -EBUSY;    /* No bits set? Huh? */    if (! ((mode & OPEN_READ) || (mode & OPEN_WRITE)))	return -EIO;    /*     * If it's open for both read and write, and the card's currently     * being read or written to, then do the opposite of what has     * already been done.  Otherwise, don't specify any mode until the     * user actually tries to do I/O.  (Some programs open the device     * for both read and write, but only actually do reading or writing.)     */    if ((mode & OPEN_WRITE) && (mode & OPEN_READ)) {	if (card->is_open_play)	    mode = OPEN_WRITE;	else if (card->is_open_record)	    mode = OPEN_READ;	else mode = 0;    }	    if (mode & OPEN_WRITE) {	if (card->is_open_play == 0) {	    card->dev_for_play = dev;	    card->is_open_play = 1;	}	else	    return -EBUSY;    }    if (mode & OPEN_READ) {	if (card->is_open_record == 0) {	    card->dev_for_record = dev;	    card->is_open_record = 1;	}	else	    return -EBUSY;    }    card->opencnt[w]++;    return 0;}/* * Close the device * * DEV  - device * * Called when closing the DMAbuf               (dmabuf.c:477) *      after halt_xfer */static voidnm256_audio_close(int dev){    struct nm256_info *card = nm256_find_card (dev);	    if (card != NULL) {	int w;	if (card->dev[0] == dev)	    w = 0;	else if (card->dev[1] == dev)	    w = 1;	else	    return;	card->opencnt[w]--;	if (card->opencnt[w] <= 0) {	    card->opencnt[w] = 0;	    if (card->dev_for_play == dev) {		stopPlay (card);		card->is_open_play = 0;		card->dev_for_play = -1;	    }	    if (card->dev_for_record == dev) {		stopRecord (card);		card->is_open_record = 0;		card->dev_for_record = -1;	    }	}    }}/* Standard ioctl handler. */static intnm256_audio_ioctl(int dev, unsigned int cmd, caddr_t arg){    int ret;    u32 oldinfo;    int w;    struct nm256_info *card = nm256_find_card (dev);    if (card == NULL)	return -ENODEV;    if (dev == card->dev[0])	w = 0;    else	w = 1;    /*      * The code here is messy.  There are probably better ways to do     * it.  (It should be possible to handle it the same way the AC97 mixer      * is done.)     */    switch (cmd)	{	case SOUND_PCM_WRITE_RATE:	    if (get_user(ret, (int *) arg))		return -EFAULT;	    if (ret != 0) {		oldinfo = card->sinfo[w].samplerate;		card->sinfo[w].samplerate = ret;		ret = nm256_setInfo(dev, card);		if (ret != 0)		    card->sinfo[w].samplerate = oldinfo;	    }	    if (ret == 0)		ret = card->sinfo[w].samplerate;	    break;	case SOUND_PCM_READ_RATE:	    ret = card->sinfo[w].samplerate;	    break;	case SNDCTL_DSP_STEREO:	    if (get_user(ret, (int *) arg))		return -EFAULT;	    card->sinfo[w].stereo = ret ? 1 : 0;	    ret = nm256_setInfo (dev, card);	    if (ret == 0)		ret = card->sinfo[w].stereo;	    break;	case SOUND_PCM_WRITE_CHANNELS:	    if (get_user(ret, (int *) arg))		return -EFAULT;	    if (ret < 1 || ret > 3)		ret = card->sinfo[w].stereo + 1;	    else {		card->sinfo[w].stereo = ret - 1;		ret = nm256_setInfo (dev, card);		if (ret == 0)		    ret = card->sinfo[w].stereo + 1;	    }	    break;	case SOUND_PCM_READ_CHANNELS:	    ret = card->sinfo[w].stereo + 1;	    break;	case SNDCTL_DSP_SETFMT:	    if (get_user(ret, (int *) arg))		return -EFAULT;	    if (ret != 0) {		oldinfo = card->sinfo[w].bits;		card->sinfo[w].bits = ret;		ret = nm256_setInfo (dev, card);		if (ret != 0)		    card->sinfo[w].bits = oldinfo;	    }	    if (ret == 0)		ret = card->sinfo[w].bits;	    break;	case SOUND_PCM_READ_BITS:	    ret = card->sinfo[w].bits;	    break;	default:	    return -EINVAL;	}    return put_user(ret, (int *) arg);}/* * Given the sound device DEV and an associated physical buffer PHYSBUF,  * return a pointer to the actual buffer in kernel space.  * * This routine should exist as part of the soundcore routines. */static char *nm256_getDMAbuffer (int dev, unsigned long physbuf){    struct audio_operations *adev = audio_devs[dev];    struct dma_buffparms *dmap = adev->dmap_out;    char *dma_start =	(char *)(physbuf - (unsigned long)dmap->raw_buf_phys 		 + (unsigned long)dmap->raw_buf);    return dma_start;}/* * Output a block to sound device * * dev          - device number * buf          - physical address of buffer * total_count  - total byte count in buffer * intrflag     - set if this has been called from an interrupt  *				  (via DMAbuf_outputintr) * restart_dma  - set if engine needs to be re-initialised * * Called when: *  1. Starting output                                  (dmabuf.c:1327) *  2.                                                  (dmabuf.c:1504) *  3. A new buffer needs to be sent to the device      (dmabuf.c:1579) */static voidnm256_audio_output_block(int dev, unsigned long physbuf,				       int total_count, int intrflag){    struct nm256_info *card = nm256_find_card (dev);    if (card != NULL) {	char *dma_buf = nm256_getDMAbuffer (dev, physbuf);	card->is_open_play = 1;	card->dev_for_play = dev;	nm256_write_block (card, dma_buf, total_count);    }}/* Ditto, but do recording instead.  */static voidnm256_audio_start_input(int dev, unsigned long physbuf, int count,			int intrflag){    struct nm256_info *card = nm256_find_card (dev);    if (card != NULL) {	char *dma_buf = nm256_getDMAbuffer (dev, physbuf);	card->is_open_record = 1;	card->dev_for_record = dev;	nm256_startRecording (card, dma_buf, count);    }}/*  * Prepare for inputting samples to DEV.  * Each requested buffer will be BSIZE byes long, with a total of * BCOUNT buffers.  */static intnm256_audio_prepare_for_input(int dev, int bsize, int bcount){    struct nm256_info *card = nm256_find_card (dev);    if (card == NULL) 	return -ENODEV;    if (card->is_open_record && card->dev_for_record != dev)	return -EBUSY;    audio_devs[dev]->dmap_in->flags |= DMA_NODMA;    return 0;}/* * Prepare for outputting samples to `dev' * * Each buffer that will be passed will be `bsize' bytes long, * with a total of `bcount' buffers. * * Called when: *  1. A trigger enables audio output                   (dmabuf.c:978) *  2. We get a write buffer without dma_mode setup     (dmabuf.c:1152) *  3. We restart a transfer                            (dmabuf.c:1324) */static intnm256_audio_prepare_for_output(int dev, int bsize, int bcount){    struct nm256_info *card = nm256_find_card (dev);    if (card == NULL)	return -ENODEV;    if (card->is_open_play && card->dev_for_play != dev)	return -EBUSY;    audio_devs[dev]->dmap_out->flags |= DMA_NODMA;    return 0;}/* Stop the current operations associated with DEV.  */static voidnm256_audio_reset(int dev){    struct nm256_info *card = nm256_find_card (dev);    if (card != NULL) {	if (card->dev_for_play == dev)	    stopPlay (card);	if (card->dev_for_record == dev)	    stopRecord (card);    }}static intnm256_audio_local_qlen(int dev){    return 0;}static struct audio_driver nm256_audio_driver ={    owner:		THIS_MODULE,    open:		nm256_audio_open,    close:		nm256_audio_close,    output_block:	nm256_audio_output_block,    start_input:	nm256_audio_start_input,    ioctl:		nm256_audio_ioctl,    prepare_for_input:	nm256_audio_prepare_for_input,    prepare_for_output:nm256_audio_prepare_for_output,    halt_io:		nm256_audio_reset,    local_qlen:		nm256_audio_local_qlen,};static struct pci_device_id nm256_pci_tbl[] __devinitdata = {	{PCI_VENDOR_ID_NEOMAGIC, PCI_DEVICE_ID_NEOMAGIC_NM256AV_AUDIO,	PCI_ANY_ID, PCI_ANY_ID, 0, 0},	{PCI_VENDOR_ID_NEOMAGIC, PCI_DEVICE_ID_NEOMAGIC_NM256ZX_AUDIO,	PCI_ANY_ID, PCI_ANY_ID, 0, 0},	{0,}};MODULE_DEVICE_TABLE(pci, nm256_pci_tbl);MODULE_LICENSE("GPL");struct pci_driver nm256_pci_driver = {	name:"nm256_audio",	id_table:nm256_pci_tbl,	probe:nm256_probe,	remove:nm256_remove,};MODULE_PARM (usecache, "i");MODULE_PARM (buffertop, "i");MODULE_PARM (nm256_debug, "i");MODULE_PARM (force_load, "i");static int __init do_init_nm256(void){    printk (KERN_INFO "NeoMagic 256AV/256ZX audio driver, version 1.1p\n");    return pci_module_init(&nm256_pci_driver);}static void __exit cleanup_nm256 (void){    pci_unregister_driver(&nm256_pci_driver);    pm_unregister_all (&handle_pm_event);}module_init(do_init_nm256);module_exit(cleanup_nm256);/* * Local variables: *  c-basic-offset: 4 * End: */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -