Esempio n. 1
0
static int wss_set_codec_fmt(struct net_device *dev, struct sm_state *sm, unsigned char fmt, 
			     unsigned char fmt2, char fdx, char fullcalib)
{
	unsigned long time;
	unsigned long flags;

	save_flags(flags);
	cli();
	/* Clock and data format register */
	write_codec(dev, 0x48, fmt);
	if (SCSTATE->crystal) {
		write_codec(dev, 0x5c, fmt2 & 0xf0);
		/* MCE and interface config reg */	
		write_codec(dev, 0x49, (fdx ? 0 : 0x4) | (fullcalib ? 0x18 : 0));
	} else 
		/* MCE and interface config reg */
		write_codec(dev, 0x49, fdx ? 0x8 : 0xc);
	outb(0xb, WSS_CODEC_IA(dev->base_addr)); /* leave MCE */
	if (SCSTATE->crystal && !fullcalib) {
		restore_flags(flags);
		return 0;
	}
	/*
	 * wait for ACI start
	 */
	time = 1000;
	while (!(read_codec(dev, 0x0b) & 0x20))
		if (!(--time)) {
			printk(KERN_WARNING "%s: ad1848 auto calibration timed out (1)\n", 
			       sm_drvname);
			restore_flags(flags);
			return -1;
		}
	/*
	 * wait for ACI end
	 */
	sti();
	time = jiffies + HZ/4;
	while ((read_codec(dev, 0x0b) & 0x20) && ((signed)(jiffies - time) < 0));
	restore_flags(flags);
	if ((signed)(jiffies - time) >= 0) {
		printk(KERN_WARNING "%s: ad1848 auto calibration timed out (2)\n", 
		       sm_drvname);
		return -1;
	}
	return 0;
}
Esempio n. 2
0
static int wss_init_codec(struct device *dev, struct sm_state *sm, char fdx, 
			  unsigned char src_l, unsigned char src_r, 
			  int igain_l, int igain_r,
			  int ogain_l, int ogain_r)
{
	unsigned char tmp, reg0, reg1, reg6, reg7;
	static const signed char irqtab[16] = 
	{ -1, -1, 0x10, -1, -1, -1, -1, 0x08, -1, 0x10, 0x18, 0x20, -1, -1,
		  -1, -1 };
	static const signed char dmatab[4] = { 1, 2, -1, 3 };
	
	tmp = inb(WSS_STATUS(dev->base_addr));
	if ((tmp & 0x3f) != 0x04 && (tmp & 0x3f) != 0x00 && 
	    (tmp & 0x3f) != 0x0f) {
		printk(KERN_WARNING "sm: WSS card id register not found, "
		       "address 0x%lx, ID register 0x%02x\n", 
		       dev->base_addr, (int)tmp);
		/* return -1; */
		SCSTATE->revwss = 0;
	} else {
		if ((tmp & 0x80) && ((dev->dma == 0) || 
				     ((dev->irq >= 8) && (dev->irq != 9)))) {
			printk(KERN_ERR "%s: WSS: DMA0 and/or IRQ8..IRQ15 "
			       "(except IRQ9) cannot be used on an 8bit "
			       "card\n", sm_drvname);
			return -1;
		}		
		if (dev->irq > 15 || irqtab[dev->irq] == -1) {
			printk(KERN_ERR "%s: WSS: invalid interrupt %d\n", 
			       sm_drvname, (int)dev->irq);
			return -1;
		}
		if (dev->dma > 3 || dmatab[dev->dma] == -1) {
			printk(KERN_ERR "%s: WSS: invalid dma channel %d\n", 
			       sm_drvname, (int)dev->dma);
			return -1;
		}
		tmp = irqtab[dev->irq] | dmatab[dev->dma];
		/* irq probe */
		outb((tmp & 0x38) | 0x40, WSS_CONFIG(dev->base_addr));
		if (!(inb(WSS_STATUS(dev->base_addr)) & 0x40)) {
			outb(0, WSS_CONFIG(dev->base_addr));
			printk(KERN_ERR "%s: WSS: IRQ%d is not free!\n", 
			       sm_drvname, dev->irq);
		}
		outb(tmp, WSS_CONFIG(dev->base_addr));
		SCSTATE->revwss = inb(WSS_STATUS(dev->base_addr)) & 0x3f;
	}
	/*
	 * initialize the codec
	 */
	if (igain_l < 0)
		igain_l = 0;
	if (igain_r < 0)
		igain_r = 0;
	if (ogain_l > 0)
		ogain_l = 0;
	if (ogain_r > 0)
		ogain_r = 0;
	reg0 = (src_l << 6) & 0xc0;
	reg1 = (src_r << 6) & 0xc0;
	if (reg0 == 0x80 && igain_l >= 20) {
		reg0 |= 0x20;
		igain_l -= 20;
	}
	if (reg1 == 0x80 && igain_r >= 20) {
		reg1 |= 0x20;
		igain_r -= 20;
	}
	if (igain_l > 23)
		igain_l = 23;
	if (igain_r > 23)
		igain_r = 23;
	reg0 |= igain_l * 2 / 3;
	reg1 |= igain_r * 2 / 3;
	reg6 = (ogain_l < -95) ? 0x80 : (ogain_l * (-2) / 3);
	reg7 = (ogain_r < -95) ? 0x80 : (ogain_r * (-2) / 3);
	write_codec(dev, 9, 0);
	write_codec(dev, 0, 0x45);
	if (read_codec(dev, 0) != 0x45)
		goto codec_err;
	write_codec(dev, 0, 0xaa);
	if (read_codec(dev, 0) != 0xaa)
		goto codec_err;
	write_codec(dev, 12, 0x40); /* enable MODE2 */
	write_codec(dev, 16, 0);
	write_codec(dev, 0, 0x45);
	SCSTATE->crystal = (read_codec(dev, 16) != 0x45);
	write_codec(dev, 0, 0xaa);
	SCSTATE->crystal &= (read_codec(dev, 16) != 0xaa);
	if (SCSTATE->crystal) {
		SCSTATE->revcid = read_codec(dev, 0x19);
		SCSTATE->revv = (SCSTATE->revcid >> 5) & 7;
		SCSTATE->revcid &= 7;
		write_codec(dev, 0x10, 0x80); /* maximum output level */
		write_codec(dev, 0x11, 0x02); /* xtal enable and no HPF */
		write_codec(dev, 0x12, 0x80); /* left line input control */
		write_codec(dev, 0x13, 0x80); /* right line input control */
		write_codec(dev, 0x16, 0); /* disable alternative freq sel */
		write_codec(dev, 0x1a, 0xe0); /* mono IO disable */
		write_codec(dev, 0x1b, 0x00); /* left out no att */
		write_codec(dev, 0x1d, 0x00); /* right out no att */
	}