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

📄 meteor.c

📁 基于组件方式开发操作系统的OSKIT源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
}/* * There is also a problem with range checking on the 7116. * It seems to only work for 22 bits, so the max size we can allocate * is 22 bits long or 4194304 bytes assuming that we put the beginning * of the buffer on a 2^24 bit boundary.  The range registers will use * the top 8 bits of the dma start registers along with the bottom 22 * bits of the range register to determine if we go out of range. * This makes getting memory a real kludge. * */#define RANGE_BOUNDARY	(1<<22)static vm_offset_tget_meteor_mem(int unit, unsigned size){vm_offset_t	addr = 0;	addr = vm_page_alloc_contig(size, 0x100000, 0xffffffff, 1<<24);	if(addr == 0)		addr = vm_page_alloc_contig(size, 0x100000, 0xffffffff,								PAGE_SIZE);	if(addr == 0) {		printf("meteor%d: Unable to allocate %d bytes of memory.\n",			unit, size);	}	return addr;}static voidbt254_write(meteor_reg_t *mtr, u_char addr, u_char data){	addr &= 0x7;						/* sanity? */	mtr->bt254_reg[addr] = data;	PCF8574_DATA_WRITE(mtr, data);				/* set data */	PCF8574_CTRL_WRITE(mtr, (PCF8574_CTRL_REG(mtr) & ~0x7) | addr);	PCF8574_CTRL_WRITE(mtr, PCF8574_CTRL_REG(mtr) & ~0x10);	/* WR/ to 0 */	PCF8574_CTRL_WRITE(mtr, PCF8574_CTRL_REG(mtr) | 0x10);	/* WR to 1 */	PCF8574_DATA_WRITE(mtr, 0xff);				/* clr data */}static voidbt254_init(meteor_reg_t *mtr){int	i;	PCF8574_CTRL_WRITE(mtr, 0x7f);	PCF8574_DATA_WRITE(mtr, 0xff);	/* data port must be 0xff */	PCF8574_CTRL_WRITE(mtr, 0x7f);	/* init RGB module for 24bpp, composite input */	for(i=0; i<NUM_BT254_REGS; i++)		bt254_write(mtr, i, bt254_default[i]);	bt254_write(mtr, BT254_COMMAND, 0x00);	/* 24 bpp */}static voidbt254_ntsc(meteor_reg_t *mtr, int arg){        if (arg){	  /* Set NTSC bit */	  PCF8574_CTRL_WRITE(mtr, PCF8574_CTRL_REG(mtr) | 0x20);	}	else {	  /* reset NTSC bit */	  PCF8574_CTRL_WRITE(mtr, PCF8574_CTRL_REG(mtr) &= ~0x20);	}}static voidselect_bt254(meteor_reg_t *mtr){	/* disable saa7196, saaen = 1 */	PCF8574_CTRL_WRITE(mtr, PCF8574_CTRL_REG(mtr) | 0x80);	/* enable Bt254, bten = 0 */	PCF8574_CTRL_WRITE(mtr, PCF8574_CTRL_REG(mtr) & ~0x40);}static voidselect_saa7196(meteor_reg_t *mtr){	/* disable Bt254, bten = 1 */	PCF8574_CTRL_WRITE(mtr, PCF8574_CTRL_REG(mtr) | 0x40);	/* enable saa7196, saaen = 0 */	PCF8574_CTRL_WRITE(mtr, PCF8574_CTRL_REG(mtr) & ~0x80);}/* * Initialize the 7116, 7196 and the RGB module. */static voidmeteor_init ( meteor_reg_t *mtr ){	mreg_t	*vbase_addr;	int 	i;	/*	 * Initialize the Philips SAA7116	 */	mtr->base->cap_cntl = 0x00000040L;	vbase_addr = &mtr->base->dma1e;	for (i = 0 ; i < (sizeof(struct saa7116_regs)/sizeof(mreg_t)); i++)		*vbase_addr++ = saa7116_pci_default[i];	/*	 * Check for the Philips SAA7196	 */	i2c_print_err = 0;	if(i2c_write(mtr, SAA7196_I2C_ADDR, SAA7116_I2C_WRITE, 0, 0xff) == 0) {		i2c_print_err = 1;		/*		 * Initialize 7196		 */		for (i = 0; i < NUM_SAA7196_I2C_REGS; i++) 			SAA7196_WRITE(mtr, i, saa7196_i2c_default[i]);		/*		 * Get version number.		 */		SAA7196_WRITE(mtr, SAA7196_STDC,			SAA7196_REG(mtr, SAA7196_STDC) & ~0x02);		SAA7196_READ(mtr);		printf("meteor%d: <Philips SAA 7196> rev 0x%x\n",			METEOR_NUM(mtr),			(unsigned)((mtr->base->i2c_read & 0xff000000L) >> 28));	} else {		i2c_print_err = 1;		printf("meteor%d: <Philips SAA 7196 NOT FOUND>\n",			METEOR_NUM(mtr));	}	/*	 * Check for RGB module, initialized if found.	 */	i2c_print_err = 0;	if(i2c_write(mtr,PCF8574_DATA_I2C_ADDR,SAA7116_I2C_WRITE,0,0xff) == 0) {		i2c_print_err = 1;		printf("meteor%d: <Booktree 254 (RGB module)>\n",			METEOR_NUM(mtr));	/* does this have a rev #? */		bt254_init(mtr);	/* Set up RGB module */		mtr->flags = METEOR_RGB;	} else {		i2c_print_err = 1;		mtr->flags = 0;	}	set_fps(mtr, 30);}static	voidmet_attach(pcici_t tag, int unit){#ifdef METEOR_IRQ	u_long old_irq, new_irq;#endif METEOR_IRQ	meteor_reg_t *mtr;	vm_offset_t buf;	u_long latency;	if (unit >= NMETEOR) {		printf("meteor%d: attach: only %d units configured.\n",				unit, NMETEOR);		printf("meteor%d: attach: invalid unit number.\n", unit);        	return ;	}	mtr = &meteor[unit];	mtr->tag = tag;	pci_map_mem(tag, PCI_MAP_REG_START, (vm_offset_t *)&mtr->base,				&mtr->phys_base);#ifdef METEOR_IRQ		/* from the configuration file */	old_irq = pci_conf_read(tag, PCI_INTERRUPT_REG);	pci_conf_write(tag, PCI_INTERRUPT_REG, METEOR_IRQ);	new_irq = pci_conf_read(tag, PCI_INTERRUPT_REG);	printf("meteor%d: attach: irq changed from %d to %d\n",		unit, (old_irq & 0xff), (new_irq & 0xff));#endif METEOR_IRQ				/* setup the interrupt handling routine */	pci_map_int(tag, meteor_intr, (void*) mtr, &net_imask); /* * PCI latency timer.  32 is a good value for 4 bus mastering slots, if * you have more than for, then 16 would probably be a better value. * */#ifndef METEOR_DEF_LATENCY_VALUE#define METEOR_DEF_LATENCY_VALUE	32	#endif	latency = pci_conf_read(tag, PCI_LATENCY_TIMER);	latency = (latency >> 8) & 0xff;	if(bootverbose) {		if(latency)			printf("meteor%d: PCI bus latency is", unit);		else			printf("meteor%d: PCI bus latency was 0 changing to",				unit);	}	if(!latency) {		latency = METEOR_DEF_LATENCY_VALUE;		pci_conf_write(tag, PCI_LATENCY_TIMER,  latency<<8);	}	if(bootverbose) {		printf(" %lu.\n", latency);	}	meteor_init(mtr);	/* set up saa7116, saa7196, and rgb module */	if(METEOR_ALLOC)		buf = get_meteor_mem(unit, METEOR_ALLOC);	else		buf = 0;	if(bootverbose) {		printf("meteor%d: buffer size %d, addr 0x%x\n",			unit, METEOR_ALLOC, vtophys(buf));	}	mtr->bigbuf = buf;	mtr->alloc_pages = METEOR_ALLOC_PAGES;	if(buf != 0) {		bzero((caddr_t) buf, METEOR_ALLOC);		buf = vtophys(buf);					/* 640x480 RGB 16 */		mtr->base->dma1e = buf;		mtr->base->dma1o = buf + 0x500;		mtr->base->dma_end_e = 		mtr->base->dma_end_o = buf + METEOR_ALLOC;	}	/* 1 frame of 640x480 RGB 16 */	mtr->cols = 640;	mtr->rows = 480;	mtr->depth = 2;		/* two bytes per pixel */	mtr->frames = 1;	/* one frame */    	mtr->flags |= METEOR_INITALIZED | METEOR_AUTOMODE | METEOR_DEV0 |		   METEOR_RGB16;#ifdef DEVFS	mtr->devfs_token = devfs_add_devswf(&meteor_cdevsw, unit,						DV_CHR, 0, 0, 0644, "meteor");#endif}#define UNIT(x)	((x) & 0x07)#ifdef unusedstatic intmeteor_reset(dev_t dev){int			unit = UNIT(minor(dev));struct	saa7116_regs	*m;	if(unit >= NMETEOR)		return ENXIO;	m = meteor[unit].base;	m->cap_cntl = 0x0;	tsleep((caddr_t)m, METPRI, "Mreset", hz/50);	m->cap_cntl = 0x8ff0;	m->cap_cntl = 0x80c0;	m->cap_cntl = 0x8040;	tsleep((caddr_t)m, METPRI, "Mreset", hz/10);	m->cap_cntl = 0x80c0;	return 0;}#endif/*---------------------------------------------------------****	Meteor character device driver routines****---------------------------------------------------------*/intmeteor_open(dev_t dev, int flags, int fmt, struct proc *p){	meteor_reg_t *mtr;	int	unit; 	int	i;	unit = UNIT(minor(dev));	if (unit >= NMETEOR)	/* unit out of range */		return(ENXIO);	mtr = &(meteor[unit]);	if (!(mtr->flags & METEOR_INITALIZED))	/* device not found */		return(ENXIO);	if (mtr->flags & METEOR_OPEN)		/* device is busy */		return(EBUSY);	mtr->flags |= METEOR_OPEN;	/*	 * Make sure that the i2c regs are set the same for each open.	 */	for(i=0; i< NUM_SAA7196_I2C_REGS; i++) {		SAA7196_WRITE(mtr, i, saa7196_i2c_default[i]);	}	mtr->fifo_errors = 0;	mtr->dma_errors = 0;	mtr->frames_captured = 0;	mtr->even_fields_captured = 0;	mtr->odd_fields_captured = 0;	mtr->proc = (struct proc *)0;	set_fps(mtr, 30);#ifdef METEOR_TEST_VIDEO	mtr->video.addr = 0;	mtr->video.width = 0;	mtr->video.banksize = 0;	mtr->video.ramsize = 0;#endif	return(0);}intmeteor_close(dev_t dev, int flags, int fmt, struct proc *p){	meteor_reg_t *mtr;	int	unit; #ifdef METEOR_DEALLOC_ABOVE	int	temp;#endif	unit = UNIT(minor(dev));	if (unit >= NMETEOR)	/* unit out of range */		return(ENXIO);	mtr = &(meteor[unit]);	mtr->flags &= ~METEOR_OPEN;	if(mtr->flags & METEOR_SINGLE)				/* this should not happen, the read capture 				  should have completed or in the very least				  recieved a signal before close is called. */		wakeup((caddr_t)mtr);	/* continue read */	/*	 * Turn off capture mode.	 */	mtr->base->cap_cntl = 0x8ff0;	mtr->flags &= ~(METEOR_CAP_MASK|METEOR_WANT_MASK);#ifdef METEOR_DEALLOC_PAGES	if (mtr->bigbuf != NULL) {		kmem_free(kernel_map,mtr->bigbuf,(mtr->alloc_pages*PAGE_SIZE));		mtr->bigbuf = NULL;		mtr->alloc_pages = 0;	}#else#ifdef METEOR_DEALLOC_ABOVE	if (mtr->bigbuf != NULL && mtr->alloc_pages > METEOR_DEALLOC_ABOVE) {		temp = METEOR_DEALLOC_ABOVE - mtr->alloc_pages;		kmem_free(kernel_map,			  mtr->bigbuf+((mtr->alloc_pages - temp) * PAGE_SIZE),			  (temp * PAGE_SIZE));		mtr->alloc_pages = METEOR_DEALLOC_ABOVE;	}#endif#endif	return(0);}static voidstart_capture(meteor_reg_t *mtr, unsigned type){mreg_t *cap = &mtr->base->cap_cntl;	mtr->flags |= type;	switch(mtr->flags & METEOR_ONLY_FIELDS_MASK) {	case METEOR_ONLY_EVEN_FIELDS:		mtr->flags |= METEOR_WANT_EVEN;		if(type == METEOR_SINGLE)			*cap = 0x0ff4 | mtr->range_enable;		else			*cap = 0x0ff1 | mtr->range_enable;		break;	case METEOR_ONLY_ODD_FIELDS:		mtr->flags |= METEOR_WANT_ODD;		if(type == METEOR_SINGLE)			*cap = 0x0ff8 | mtr->range_enable;		else			*cap = 0x0ff2 | mtr->range_enable;		break;	default:		mtr->flags |= METEOR_WANT_MASK;		if(type == METEOR_SINGLE)			*cap = 0x0ffc | mtr->range_enable;		else			*cap = 0x0ff3 | mtr->range_enable;		break;	}}intmeteor_read(dev_t dev, struct uio *uio, int ioflag){	meteor_reg_t *mtr;	int	unit; 	int	status;	int	count;	unit = UNIT(minor(dev));	if (unit >= NMETEOR)	/* unit out of range */		return(ENXIO);	mtr = &(meteor[unit]);	if (mtr->bigbuf == 0)/* no frame buffer allocated (ioctl failed) */		return(ENOMEM);	if (mtr->flags & METEOR_CAP_MASK)

⌨️ 快捷键说明

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