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

📄 ad1848.c

📁 freebsd v4.4内核源码
💻 C
📖 第 1 页 / 共 4 页
字号:
    snd_set_blocksize(d); /* update blocksize if user did not force it */}/* * here we have support for PnP cards * */#if NPNP > 0static char * cs423x_probe(u_long csn, u_long vend_id);static void cs423x_attach(u_long csn, u_long vend_id, char *name,	struct isa_device *dev);static struct pnp_device cs423x = {	"CS423x/Yamaha",	cs423x_probe,	cs423x_attach,	&nsnd,	/* use this for all sound cards */	&tty_imask	/* imask */};DATA_SET (pnpdevice_set, cs423x);static char *cs423x_probe(u_long csn, u_long vend_id){    char *s = NULL ;    u_long id = vend_id & 0xff00ffff;    if ( id == 0x3700630e )	s = "CS4237" ;    else if ( id == 0x2500630e)	s = "CS4235" ;    else if ( id == 0x3500630e || id == 0x3600630e )	s = "CS4236" ;    else if ( id == 0x3200630e)	s = "CS4232" ;    else if ( id == 0x2000a865)	s = "Yamaha SA2";    else if ( id == 0x3000a865)	s = "Yamaha SA3";    else if (vend_id == 0x0000a865)	s = "Yamaha YMF719 OPL-SA3";    else if (vend_id == 0x8140d315)	s = "SoundscapeVIVO";    if (s) {	struct pnp_cinfo d;	read_pnp_parms(&d, 0);	if (d.enable == 0) {	    printf("This is a %s, but LDN 0 is disabled\n", s);	    return NULL ;	}	return s;    }    return NULL ;}extern snddev_info sb_op_desc;static voidcs423x_attach(u_long csn, u_long vend_id, char *name,	struct isa_device *dev){    struct pnp_cinfo d ;    snddev_info tmp_d ; /* patched copy of the basic snddev_info */    int ldn = 0 ;    if (read_pnp_parms ( &d , ldn ) == 0 ) {	printf("failed to read pnp parms\n");	return ;    }    snddev_last_probed = &tmp_d;    if (d.flags & DV_PNP_SBCODEC) {	/*** use sb-compatible codec ***/	dev->id_alive = 16 ; /* number of io ports ? */	tmp_d = sb_op_desc ;	if (vend_id==0x2000a865 || vend_id==0x3000a865 ||	    vend_id==0x0008a865 || vend_id==0x8140d315) {	    /* Yamaha SA2/SA3 or ENSONIQ SoundscapeVIVO ENS4081 */	    dev->id_iobase = d.port[0] ;	    tmp_d.alt_base = d.port[1] ;	    d.irq[1] = 0 ; /* only needed for the VIVO */	} else {	    dev->id_iobase = d.port[2] ;	    tmp_d.alt_base = d.port[0] - 4;	}	d.drq[1] = 4 ; /* disable, it is not used ... */    } else {			/* mss-compatible codec */	dev->id_alive = 8 ; /* number of io ports ? */	tmp_d = mss_op_desc ;	dev->id_iobase = d.port[0] -4 ; /* XXX old mss have 4 bytes before... */	tmp_d.alt_base = d.port[2];	switch (vend_id & 0xff00ffff) {	case 0x2000a865:	/* Yamaha SA2 */	case 0x3000a865:	/* Yamaha SA3 */	case 0x0000a865:	/* Yamaha TMF719 SA3 */	    dev->id_iobase = d.port[1];	    tmp_d.alt_base = d.port[0];	    tmp_d.conf_base = d.port[4];	    tmp_d.bd_id = MD_YM0020 ;	    break;	case 0x8100d315:	/* ENSONIQ SoundscapeVIVO */	    dev->id_iobase = d.port[1];	    tmp_d.alt_base = d.port[0];	    tmp_d.bd_id = MD_VIVO ;	    d.irq[1] = 0 ;	    break;	case 0x3700630e:        /* CS4237 */	    tmp_d.bd_id = MD_CS4237 ;	    break;	case 0x2500630e:	/* AOpen AW37 */	    tmp_d.bd_id = MD_CS4237 ;	    break ;	case 0x3500630e:        /* CS4236 */	case 0x3600630e:        /* CS4236 */	    tmp_d.bd_id = MD_CS4236 ;	    break;        default:	    tmp_d.bd_id = MD_CS4232 ; /* to short-circuit the detect routine */	    break;	}	strcpy(tmp_d.name, name);	tmp_d.audio_fmt |= AFMT_FULLDUPLEX ;    }    write_pnp_parms( &d, ldn );    enable_pnp_card();    if ( (vend_id & 0x0000ffff) == 0x0000a865 ) {	/* special volume setting for the Yamaha... */	outb(tmp_d.conf_base, 7 /* volume, left */);	outb(tmp_d.conf_base+1, 0 );	outb(tmp_d.conf_base, 8 /* volume, right */);	outb(tmp_d.conf_base+1, 0 );    }    dev->id_drq = d.drq[0] ; /* primary dma */    dev->id_irq = (1 << d.irq[0] ) ;    dev->id_intr = pcmintr ;    dev->id_flags = DV_F_DUAL_DMA | (d.drq[1] ) ;    tmp_d.synth_base = d.port[1]; /* XXX check this for yamaha */    pcmattach(dev);}static char *opti931_probe(u_long csn, u_long vend_id);static void opti931_attach(u_long csn, u_long vend_id, char *name,	struct isa_device *dev);static struct pnp_device opti931 = {	"OPTi931",	opti931_probe,	opti931_attach,	&nsnd,	/* use this for all sound cards */	&tty_imask	/* imask */};DATA_SET (pnpdevice_set, opti931);static char *opti931_probe(u_long csn, u_long vend_id){    if (vend_id == 0x3109143e) {	struct pnp_cinfo d;	read_pnp_parms(&d, 1);	if (d.enable == 0) {	    printf("This is an OPTi931, but LDN 1 is disabled\n");	    return NULL ;	}	return "OPTi931" ;    }    return NULL ;}static voidopti931_attach(u_long csn, u_long vend_id, char *name,	struct isa_device *dev){    struct pnp_cinfo d ;    snddev_info tmp_d ; /* patched copy of the basic snddev_info */    int p;    read_pnp_parms ( &d , 3 ); /* free resources taken by LDN 3 */    d.irq[0]=0; /* free irq... */    d.port[0]=0; /* free address... */    d.enable = 0 ;    write_pnp_parms ( &d , 3 );    read_pnp_parms ( &d , 2 ); /* disable LDN 2 */    d.enable = 0 ;    write_pnp_parms ( &d , 2 );    read_pnp_parms ( &d , 1 ) ;    write_pnp_parms( &d, 1 );    enable_pnp_card();    snddev_last_probed = &tmp_d;    tmp_d =  d.flags & DV_PNP_SBCODEC ? sb_op_desc : mss_op_desc ;    strcpy(tmp_d.name, name);    /*     * My MED3931 v.1.0 allocates 3 bytes for the config space,     * whereas v.2.0 allocates 4 bytes. What I know for sure is that the     * upper two ports must be used, and they should end on a boundary     * of 4 bytes. So I need the following trick...     */    p = tmp_d.conf_base = (d.port[3] & ~3) + 2; /* config port */    /*     * now set default values for both modes.     */    dev->id_iobase = d.port[0] - 4 ; /* old mss have 4 bytes before... */    tmp_d.io_base = dev->id_iobase; /* needed for ad_write to work... */    tmp_d.alt_base = d.port[2];    tmp_d.synth_base = d.port[1];    DEB(printf("opti_attach: selecting mode\n");)    opti_write(p, 4, 0xd6 /* fifo empty, OPL3, audio enable, SB3.2 */ );    DELAY(1000*300);    ad_write (&tmp_d, 10, 2); /* enable interrupts */    DEB(printf("opti_attach: int enabled\n");)    if (d.flags & DV_PNP_SBCODEC) { /* sb-compatible codec */	/*	 * the 931 is not a real SB, it has important pieces of	 * hardware controlled by both the MSS and the SB port...	 */	printf("--- opti931 in sb mode ---\n");	opti_write(p, 6, 1); /* MCIR6 mss disable, sb enable */	/*	 * swap the main and alternate iobase address since we want	 * to work in sb mode.	 */	dev->id_iobase = d.port[2] ;	tmp_d.alt_base = d.port[0] - 4;	dev->id_flags = DV_F_DUAL_DMA | d.drq[1] ;    } else { /* mss-compatible codec */	tmp_d.bd_id = MD_OPTI931 ; /* to short-circuit the detect routine */	opti_write(p, 6 , 2);  /* MCIR6: mss enable, sb disable */	opti_write(p, 5, 0x28);  /* MCIR5: codec in exp. mode,fifo */	dev->id_flags = DV_F_DUAL_DMA | d.drq[1] ;	tmp_d.audio_fmt |= AFMT_FULLDUPLEX ; /* not really well... */	tmp_d.isr = opti931_intr;    }    dev->id_drq = d.drq[0] ; /* primary dma */    dev->id_irq = (1 << d.irq[0] ) ;    dev->id_intr = pcmintr ;    pcmattach(dev);}static char *opti925_probe(u_long csn, u_long vend_id);static void opti925_attach(u_long csn, u_long vend_id, char *name,        struct isa_device *dev);    static struct pnp_device opti925 = {        "opti925",        opti925_probe,        opti925_attach,        &nsnd,  /* use this for all sound cards */        &tty_imask      /* imask */ };  DATA_SET (pnpdevice_set, opti925);    static char *opti925_probe(u_long csn, u_long vend_id){    if (vend_id == 0x2509143e) {        struct pnp_cinfo d ;        read_pnp_parms ( &d , 1 ) ;        if (d.enable == 0) {            printf("This is an OPTi925, but LDN 1 is disabled\n");            return NULL;        }        return "OPTi925" ;    }    return NULL ;}  static void opti925_attach(u_long csn, u_long vend_id, char *name,         struct isa_device *dev) {    struct pnp_cinfo d ;     snddev_info tmp_d ; /* patched copy of the basic snddev_info */    int the_irq = 0 ;     tmp_d = mss_op_desc;    snddev_last_probed = &tmp_d;       read_pnp_parms ( &d , 3 );  /* disable LDN 3 */    the_irq = d.irq[0];    d.port[0] = 0 ;    d.enable = 0 ;    write_pnp_parms ( &d , 3 );    read_pnp_parms ( &d , 2 ); /* disable LDN 2 */    d.port[0] = 0 ;    d.enable = 0 ;     write_pnp_parms ( &d , 2 );    read_pnp_parms ( &d , 1 ) ;    d.irq[0] = the_irq ;    dev->id_iobase = d.port[1];    tmp_d.alt_base = d.port[0];      write_pnp_parms ( &d , 1 );    enable_pnp_card();    tmp_d.conf_base = d.port[3];    dev->id_drq = d.drq[0] ; /* primary dma */    dev->id_irq = (1 << d.irq[0] ) ;    dev->id_intr = pcmintr ;    dev->id_flags = DV_F_DUAL_DMA | d.drq[1] ;    tmp_d.audio_fmt |= AFMT_FULLDUPLEX ;    snddev_last_probed->probe(dev); /* not really necessary but doesn't harm */     pcmattach(dev);}static void gus_mem_cfg(snddev_info *tmp);static char *guspnp_probe(u_long csn, u_long vend_id);static void guspnp_attach(u_long csn, u_long vend_id, char *name,	struct isa_device *dev);static struct pnp_device guspnp = {	"GusPnP",	guspnp_probe,	guspnp_attach,	&nsnd,	/* use this for all sound cards */	&tty_imask	/* imask */};DATA_SET (pnpdevice_set, guspnp);static char *guspnp_probe(u_long csn, u_long vend_id){    if (vend_id == 0x0100561e) {	struct pnp_cinfo d;	read_pnp_parms(&d, 0);	if (d.enable == 0) {	    printf("This is a GusPnP, but LDN 0 is disabled\n");	    return NULL ;	}	return "GusPnP" ;    }    return NULL ;}static voidguspnp_attach(u_long csn, u_long vend_id, char *name,	struct isa_device *dev){    struct pnp_cinfo d ;    snddev_info tmp_d ; /* patched copy of the basic snddev_info */    u_char tmp;    read_pnp_parms ( &d , 0 ) ;    /* d.irq[1] = d.irq[0] ; */    pnp_write ( 0xf2, 0xff ); /* enable power on the guspnp */    write_pnp_parms ( &d , 0 );    enable_pnp_card();    tmp_d = mss_op_desc ;    snddev_last_probed = &tmp_d;    dev->id_iobase = d.port[2] - 4 ; /* room for 4 mss registers */    dev->id_drq = d.drq[1] ; /* XXX PLAY dma */    dev->id_irq = (1 << d.irq[0] ) ;    dev->id_intr = pcmintr ;    dev->id_flags = DV_F_DUAL_DMA | d.drq[0]  ; /* REC dma */    tmp_d.io_base = d.port[2] - 4;    tmp_d.alt_base = d.port[0]; /* 0x220 */    tmp_d.conf_base = d.port[1];  /* gus control block... */    tmp_d.bd_id = MD_GUSPNP ;    /* reset */    gus_write(tmp_d.conf_base, 0x4c /* _URSTI */, 0 );/* Pull reset */    DELAY(1000 * 30);    /* release reset  and enable DAC */    gus_write(tmp_d.conf_base, 0x4c /* _URSTI */, 3 );    DELAY(1000 * 30);    /* end of reset */    outb( tmp_d.alt_base, 0xC ); /* enable int and dma */    /*     * unmute left & right line. Need to go in mode3, unmute,     * and back to mode 2     */    tmp = ad_read(&tmp_d, 0x0c);    ad_write(&tmp_d, 0x0c, 0x6c ); /* special value to enter mode 3 */    ad_write(&tmp_d, 0x19, 0 ); /* unmute left */    ad_write(&tmp_d, 0x1b, 0 ); /* unmute right */    ad_write(&tmp_d, 0x0c, tmp ); /* restore old mode */    /* send codec interrupts on irq1 and only use that one */    gus_write(tmp_d.conf_base, 0x5a , 0x4f );    /* enable access to hidden regs */    tmp = gus_read(tmp_d.conf_base, 0x5b /* IVERI */ );    gus_write(tmp_d.conf_base, 0x5b , tmp | 1 );    BVDDB(printf("GUS: silicon rev %c\n", 'A' + ( ( tmp & 0xf ) >> 4) );)    strcpy(tmp_d.name, name);    pcmattach(dev);}#if 0intgus_mem_write(snddev_info *d, int addr, u_char data){    gus_writew(d->conf_base, 0x43 , addr & 0xffff );    gus_write(d->conf_base, 0x44 , (addr>>16) & 0xff );    outb(d->conf_base + 7, data);}u_chargus_mem_read(snddev_info *d, int addr){    gus_writew(d->conf_base, 0x43 , addr & 0xffff );    gus_write(d->conf_base, 0x44 , (addr>>16) & 0xff );    return inb(d->conf_base + 7);}voidgus_mem_cfg(snddev_info *d){    int base;    u_char old;    u_char a, b;    printf("configuring gus memory...\n");    gus_writew(d->conf_base, 0x52 /* LMCFI */, 1 /* 512K*/);    old = gus_read(d->conf_base, 0x19);    gus_write(d->conf_base, 0x19, old | 1); /* enable enhaced mode */    for (base = 0; base < 1024; base++) {	a=gus_mem_read(d, base*1024);	a = ~a ;	gus_mem_write(d, base*1024, a);	b=gus_mem_read(d, base*1024);	if ( b != a )		break ;    }    printf("Have found %d KB ( 0x%x != 0x%x)\n", base, a, b);}#endif /* gus mem cfg... */#endif	/* NPNP > 0 */#endif /* NPCM > 0 */

⌨️ 快捷键说明

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