[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: rtl-digest V1 #101



echo "unsubscribe rtl <Your_email>" | mail majordomo@rtlinux.org
unsubscribe rtl tomochika@sunplus.com
end
exit
bye


> 		if(copy_to_user(arg,&v,sizeof(v)))
> 			return -EFAULT;
> 		return 0;
> 	}
> 	case VIDIOCSFREQ:
> 	{
> 		unsigned long v;
> 		if(copy_from_user(&v, arg, sizeof(v)))
> 			return -EFAULT;
> 		btv->win.freq=v;
> 		bttv_call_i2c_clients(btv,cmd,&v);
> #if 1
> 		if (btv->radio && btv->has_matchbox)
> 			tea5757_set_freq(btv,v);
> #endif
> 		return 0;
> 	}
> 	
> 	case VIDIOCGAUDIO:
> 	{
> 		struct video_audio v;
> 
> 		v=btv->audio_dev;
> 		v.flags&=~(VIDEO_AUDIO_MUTE|VIDEO_AUDIO_MUTABLE);
> 		v.flags|=VIDEO_AUDIO_MUTABLE;
> 		strcpy(v.name,"TV");
> 
> 		v.mode = VIDEO_SOUND_MONO;
> 		bttv_call_i2c_clients(btv,cmd,&v);
> 
> 		/* card specific hooks */
> 		if (bttv_tvcards[btv->type].audio_hook)
> 			bttv_tvcards[btv->type].audio_hook(btv,&v,0);
> 
> 		if(copy_to_user(arg,&v,sizeof(v)))
> 			return -EFAULT;
> 		return 0;
> 	}
> 	case VIDIOCSAUDIO:
> 	{
> 		struct video_audio v;
> 
> 		if(copy_from_user(&v,arg, sizeof(v)))
> 			return -EFAULT;
> 		down(&btv->lock);
> 		if(v.flags&VIDEO_AUDIO_MUTE)
> 			audio(btv, AUDIO_MUTE, 1);
> 		/* One audio source per tuner -- huh? <GA> */
> 		if(v.audio<0 || v.audio >= bttv_tvcards[btv->type].audio_inputs) {
> 			up(&btv->lock);
> 			return -EINVAL;
> 		}
> 		/* bt848_muxsel(btv,v.audio); */
> 		if(!(v.flags&VIDEO_AUDIO_MUTE))
> 			audio(btv, AUDIO_UNMUTE, 1);
> 
> 		bttv_call_i2c_clients(btv,cmd,&v);
> 		
> 		/* card specific hooks */
> 		if (bttv_tvcards[btv->type].audio_hook)
> 			bttv_tvcards[btv->type].audio_hook(btv,&v,1);
> 
> 		btv->audio_dev=v;
> 		up(&btv->lock);
> 		return 0;
> 	}
> 
> 	case VIDIOCSYNC:
> 	{
> 		DECLARE_WAITQUEUE(wait, current);
> 
> 		if(copy_from_user((void *)&i,arg,sizeof(int)))
> 			return -EFAULT;
> 		if (i < 0 || i >= gbuffers)
> 			return -EINVAL;
> 		switch (btv->gbuf[i].stat) {
> 		case GBUFFER_UNUSED:
> 			ret = -EINVAL;
> 			break;
> 		case GBUFFER_GRABBING:
> 			add_wait_queue(&btv->capq, &wait);
> 			current->state = TASK_INTERRUPTIBLE;
> 			while(btv->gbuf[i].stat==GBUFFER_GRABBING) {
> 				if (bttv_debug)
> 					printk("bttv%d: cap sync: sleep on %d\n",btv->nr,i);
> 				schedule();
> 				if(signal_pending(current)) {
> 					remove_wait_queue(&btv->capq, &wait);
> 					current->state = TASK_RUNNING;
> 					return -EINTR;
> 				}
> 			}
> 			remove_wait_queue(&btv->capq, &wait);
> 			current->state = TASK_RUNNING;
> 			/* fall throuth */
> 		case GBUFFER_DONE:
> 		case GBUFFER_ERROR:
> 			ret = (btv->gbuf[i].stat == GBUFFER_ERROR) ? -EIO : 0;
> 			if (bttv_debug)
> 				printk("bttv%d: cap sync: buffer %d, retval %d\n",btv->nr,i,ret);
> 			btv->gbuf[i].stat = GBUFFER_UNUSED;
> 		}
> 		if (btv->needs_restart) {
> 			down(&btv->lock);
> 			bt848_restart(btv);
> 			up(&btv->lock);
> 		}
> 		return ret;
> 	}
> 
> 	case BTTV_FIELDNR: 
> 		if(copy_to_user((void *) arg, (void *) &btv->last_field, 
> 				sizeof(btv->last_field)))
> 			return -EFAULT;
> 		break;
>       
> 	case BTTV_PLLSET: {
> 		struct bttv_pll_info p;
> 		if(!capable(CAP_SYS_ADMIN))
> 			return -EPERM;
> 		if(copy_from_user(&p , (void *) arg, sizeof(btv->pll)))
> 			return -EFAULT;
> 		down(&btv->lock);
> 		btv->pll.pll_ifreq = p.pll_ifreq;
> 		btv->pll.pll_ofreq = p.pll_ofreq;
> 		btv->pll.pll_crystal = p.pll_crystal;
> 		up(&btv->lock);
> 		break;
> 	}
> 
> 	case VIDIOCMCAPTURE:
> 	{
> 		struct video_mmap vm;
> 		int ret;
> 		if(copy_from_user((void *) &vm, (void *) arg, sizeof(vm)))
> 			return -EFAULT;
> 		down(&btv->lock);
> 		ret = vgrab(btv, &vm);
> 		up(&btv->lock);
> 		return ret;
> 	}
> 		
> 	case VIDIOCGMBUF:
> 	{
> 		struct video_mbuf vm;
> 		memset(&vm, 0 , sizeof(vm));
> 		vm.size=gbufsize*gbuffers;
> 		vm.frames=gbuffers;
> 		for (i = 0; i < gbuffers; i++)
> 			vm.offsets[i]=i*gbufsize;
> 		if(copy_to_user((void *)arg, (void *)&vm, sizeof(vm)))
> 			return -EFAULT;
> 		return 0;
> 	}
> 		
> 	case VIDIOCGUNIT:
> 	{
> 		struct video_unit vu;
> 		vu.video=btv->video_dev.minor;
> 		vu.vbi=btv->vbi_dev.minor;
> 		if(btv->radio_dev.minor!=-1)
> 			vu.radio=btv->radio_dev.minor;
> 		else
> 			vu.radio=VIDEO_NO_UNIT;
> 		vu.audio=VIDEO_NO_UNIT;
> 		vu.teletext=VIDEO_NO_UNIT;
> 		if(copy_to_user((void *)arg, (void *)&vu, sizeof(vu)))
> 			return -EFAULT;
> 		return 0;
> 	}
> 		
> 	case BTTV_BURST_ON:
> 	{
> 		burst(1);
> 		return 0;
> 	}
> 
> 	case BTTV_BURST_OFF:
> 	{
> 		burst(0);
> 		return 0;
> 	}
> 
> 	case BTTV_VERSION:
> 	{
> 		return BTTV_VERSION_CODE;
> 	}
>                         
> 	case BTTV_PICNR:
> 	{
> 		/* return picture;*/
> 		return  0;
> 	}
> 
> 	default:
> 		return -ENOIOCTLCMD;
> 	}
> 	return 0;
> }
> 
> /*
>  *	This maps the vmalloced and reserved fbuffer to user space.
>  *
>  *  FIXME: 
>  *  - PAGE_READONLY should suffice!?
>  *  - remap_page_range is kind of inefficient for page by page remapping.
>  *    But e.g. pte_alloc() does not work in modules ... :-(
>  */
> 
> static int do_bttv_mmap(struct bttv *btv, const char *adr, unsigned long size)
> {
>         unsigned long start=(unsigned long) adr;
>         unsigned long page,pos;
> 
>         if (size>gbuffers*gbufsize)
>                 return -EINVAL;
>         if (!btv->fbuffer) {
>                 if(fbuffer_alloc(btv))
>                         return -EINVAL;
>         }
>         pos=(unsigned long) btv->fbuffer;
>         while (size > 0) {
>                 page = kvirt_to_pa(pos);
>                 if (remap_page_range(start, page, PAGE_SIZE, PAGE_SHARED))
>                         return -EAGAIN;
>                 start+=PAGE_SIZE;
>                 pos+=PAGE_SIZE;
>                 size-=PAGE_SIZE;
>         }
>         return 0;
> }
> 
> static int bttv_mmap(struct video_device *dev, const char *adr, unsigned long size)
> {
>         struct bttv *btv=(struct bttv *)dev;
>         int r;
> 
>         down(&btv->lock);
>         r=do_bttv_mmap(btv, adr, size);
>         up(&btv->lock);
>         return r;
> }
> 
> 
> static struct video_device bttv_template=
> {
> #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,3)
> 	owner:		THIS_MODULE,
> #endif
> 	name:		"UNSET",
> 	type:		VID_TYPE_TUNER|VID_TYPE_CAPTURE|VID_TYPE_OVERLAY|VID_TYPE_TELETEXT,
> 	hardware:	VID_HARDWARE_BT848,
> 	open:		bttv_open,
> 	close:		bttv_close,
> 	read:		bttv_read,
> 	write:		bttv_write,
> 	ioctl:		bttv_ioctl,
> 	mmap:		bttv_mmap,
> 	minor:		-1,
> };
> 
> 
> static long vbi_read(struct video_device *v, char *buf, unsigned long count,
> 		     int nonblock)
> {
> 	struct bttv *btv=(struct bttv *)(v-2);
> 	int q,todo;
> 	DECLARE_WAITQUEUE(wait, current);
> 
> 	todo=count;
> 	while (todo && todo>(q=VBIBUF_SIZE-btv->vbip)) 
> 	{
> 		if (btv->needs_restart) {
> 			down(&btv->lock);
> 			bt848_restart(btv);
> 			up(&btv->lock);
> 		}
> 		if(copy_to_user((void *) buf, (void *) btv->vbibuf+btv->vbip, q))
> 			return -EFAULT;
> 		todo-=q;
> 		buf+=q;
> 
> 		add_wait_queue(&btv->vbiq, &wait);
> 		current->state = TASK_INTERRUPTIBLE;
> 		if (todo && q==VBIBUF_SIZE-btv->vbip) 
> 		{
> 			if(nonblock)
> 			{
> 				remove_wait_queue(&btv->vbiq, &wait);
> 				current->state = TASK_RUNNING;
> 				if(count==todo)
> 					return -EWOULDBLOCK;
> 				return count-todo;
> 			}
> 			schedule();
> 			if(signal_pending(current))
> 			{
> 				remove_wait_queue(&btv->vbiq, &wait);
>                                 current->state = TASK_RUNNING;
> 				if(todo==count)
> 					return -EINTR;
> 				else
> 					return count-todo;
> 			}
> 		}
> 		remove_wait_queue(&btv->vbiq, &wait);
> 		current->state = TASK_RUNNING;
> 	}
> 	if (todo) 
> 	{
> 		if(copy_to_user((void *) buf, (void *) btv->vbibuf+btv->vbip, todo))
> 			return -EFAULT;
> 		btv->vbip+=todo;
> 	}
> 	return count;
> }
> 
> static unsigned int vbi_poll(struct video_device *dev, struct file *file,
> 	poll_table *wait)
> {
> 	struct bttv *btv=(struct bttv *)(dev-2);
> 	unsigned int mask = 0;
> 
> 	poll_wait(file, &btv->vbiq, wait);
> 
> 	if (btv->vbip < VBIBUF_SIZE)
> 		mask |= (POLLIN | POLLRDNORM);
> 
> 	return mask;
> }
> 
> static int vbi_open(struct video_device *dev, int flags)
> {
> 	struct bttv *btv=(struct bttv *)(dev-2);
>  	unsigned long irq_flags;
> 
> #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,3)
> 	MOD_INC_USE_COUNT;
> #endif
>         down(&btv->lock);
> 	if (btv->needs_restart)
> 		bt848_restart(btv);
> 	set_pll(btv);
> 	btv->vbip=VBIBUF_SIZE;
> 	spin_lock_irqsave(&btv->s_lock, irq_flags);
> 	btv->vbi_on = 1;
> 	bt848_set_risc_jmps(btv,-1);
> 	spin_unlock_irqrestore(&btv->s_lock, irq_flags);
> 	up(&btv->lock);
> 
> 	return 0;   
> }
> 
> static void vbi_close(struct video_device *dev)
> {
> 	struct bttv *btv=(struct bttv *)(dev-2);
>  	unsigned long irq_flags;
> 
> 	spin_lock_irqsave(&btv->s_lock, irq_flags);
> 	btv->vbi_on = 0;
> 	bt848_set_risc_jmps(btv,-1);
> 	spin_unlock_irqrestore(&btv->s_lock, irq_flags);
> #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,3)
> 	MOD_DEC_USE_COUNT;  
> #endif
> }
> 
> static int vbi_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
> {
> 	struct bttv *btv=(struct bttv *)(dev-2);
> 
> 	switch (cmd) {	
> 	case VIDIOCGCAP:
> 	{
> 		struct video_capability b;
> 		strcpy(b.name,btv->vbi_dev.name);
> 		b.type = ((bttv_tvcards[btv->type].tuner != -1) ? VID_TYPE_TUNER : 0) |
> 			VID_TYPE_TELETEXT;
> 		b.channels = 0;
> 		b.audios = 0;
> 		b.maxwidth = 0;
> 		b.maxheight = 0;
> 		b.minwidth = 0;
> 		b.minheight = 0;
> 		if(copy_to_user(arg,&b,sizeof(b)))
> 			return -EFAULT;
> 		return 0;
> 	}
> 	case VIDIOCGFREQ:
> 	case VIDIOCSFREQ:
> 	case VIDIOCGTUNER:
> 	case VIDIOCSTUNER:
> 	case VIDIOCGCHAN:
> 	case VIDIOCSCHAN:
> 	case BTTV_VERSION:
> 		return bttv_ioctl(dev-2,cmd,arg);
> 	case BTTV_VBISIZE:
> 		/* make alevt happy :-) */
> 		return VBIBUF_SIZE;
> 	default:
> 		return -EINVAL;
> 	}
> }
> 
> static struct video_device vbi_template=
> {
> #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,3)
> 	owner:		THIS_MODULE,
> #endif
> 	name:		"bttv vbi",
> 	type:		VID_TYPE_CAPTURE|VID_TYPE_TELETEXT,
> 	hardware:	VID_HARDWARE_BT848,
> 	open:		vbi_open,
> 	close:		vbi_close,
> 	read:		vbi_read,
> 	write:		bttv_write,
> 	poll:		vbi_poll,
> 	ioctl:		vbi_ioctl,
> 	minor:		-1,
> };
> 
> 
> static int radio_open(struct video_device *dev, int flags)
> {
> 	struct bttv *btv = (struct bttv *)(dev-1);
> 	unsigned long v;
> 
> #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,3)
> 	MOD_INC_USE_COUNT;
> #endif
>         down(&btv->lock);
> 	if (btv->user)
> 		goto busy_unlock;
> 	btv->user++;
> 
> 	btv->radio = 1;
> 	v = 400*16;
> 	bttv_call_i2c_clients(btv,VIDIOCSFREQ,&v);
> 	bttv_call_i2c_clients(btv,AUDC_SET_RADIO,&btv->tuner_type);
> 	bt848_muxsel(btv,0);
> 	up(&btv->lock);
> 
> 	return 0;   
> 
>  busy_unlock:
> 	up(&btv->lock);
> #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,3)
> 	MOD_DEC_USE_COUNT;
> #endif
> 	return -EBUSY;
> }
> 
> static void radio_close(struct video_device *dev)
> {
> 	struct bttv *btv=(struct bttv *)(dev-1);
> 
> 	down(&btv->lock);
> 	btv->user--;
> 	btv->radio = 0;
> 	up(&btv->lock);
> #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,3)
> 	MOD_DEC_USE_COUNT;  
> #endif
> }
> 
> static long radio_read(struct video_device *v, char *buf, unsigned long count, int nonblock)
> {
> 	return -EINVAL;
> }
> 
> static int radio_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
> {
>         struct bttv *btv=(struct bttv *)(dev-1);
> 	switch (cmd) {	
> 	case VIDIOCGCAP:
> 	{
> 		struct video_capability v;
> 		strcpy(v.name,btv->video_dev.name);
> 		v.type = VID_TYPE_TUNER;
> 		v.channels = 1;
> 		v.audios = 1;
> 		/* No we don't do pictures */
> 		v.maxwidth = 0;
> 		v.maxheight = 0;
> 		v.minwidth = 0;
> 		v.minheight = 0;
> 		if (copy_to_user(arg, &v, sizeof(v)))
> 			return -EFAULT;
> 		return 0;
> 		break;
> 	}
> 	case VIDIOCGTUNER:
> 	{
> 		struct video_tuner v;
> 		if(copy_from_user(&v,arg,sizeof(v))!=0)
> 			return -EFAULT;
> 		if(v.tuner||btv->channel)	/* Only tuner 0 */
> 			return -EINVAL;
> 		strcpy(v.name, "Radio");
> 		/* japan:          76.0 MHz -  89.9 MHz
> 		   western europe: 87.5 MHz - 108.0 MHz
> 		   russia:         65.0 MHz - 108.0 MHz */
> 		v.rangelow=(int)(65*16);
> 		v.rangehigh=(int)(108*16);
> 		v.flags= 0; /* XXX */
> 		v.mode = 0; /* XXX */
> 		bttv_call_i2c_clients(btv,cmd,&v);
> 		if(copy_to_user(arg,&v,sizeof(v)))
> 			return -EFAULT;
> 		return 0;
> 	}
> 	case VIDIOCSTUNER:
> 	{
> 		struct video_tuner v;
> 		if(copy_from_user(&v, arg, sizeof(v)))
> 			return -EFAULT;
> 		/* Only channel 0 has a tuner */
> 		if(v.tuner!=0 || btv->channel)
> 			return -EINVAL;
> 		/* XXX anything to do ??? */
> 		return 0;
> 	}
> 	case VIDIOCGFREQ:
> 	case VIDIOCSFREQ:
> 	case VIDIOCGAUDIO:
> 	case VIDIOCSAUDIO:
> 		bttv_ioctl((struct video_device *)btv,cmd,arg);
> 		break;
> 	default:
> 		return -ENOIOCTLCMD;
> 	}
> 	return 0;
> }
> 
> static struct video_device radio_template=
> {
> #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,3)
> 	owner:		THIS_MODULE,
> #endif
> 	name:		"bttv radio",
> 	type:		VID_TYPE_TUNER,
> 	hardware:	VID_HARDWARE_BT848,
> 	open:		radio_open,
> 	close:		radio_close,
> 	read:		radio_read,          /* just returns -EINVAL */
> 	write:		bttv_write,          /* just returns -EINVAL */
> 	ioctl:		radio_ioctl,
> 	minor:		-1,
> };
> 
> 
> static void bt848_set_risc_jmps(struct bttv *btv, int flags)
> {
> 	if (-1 == flags) {
> 		/* defaults */
> 		flags = 0;
> 		if (btv->scr_on)
> 			flags |= 0x03;
> 		if (btv->vbi_on)
> 			flags |= 0x0c;
> 	}
> 
> 	if (bttv_debug > 1)
> 		printk("bttv%d: set_risc_jmp %08lx:",
> 		       btv->nr,virt_to_bus(btv->risc_jmp));
> 
> 	/* Sync to start of odd field */
> 	btv->risc_jmp[0]=cpu_to_le32(BT848_RISC_SYNC|BT848_RISC_RESYNC
>                                 |BT848_FIFO_STATUS_VRE);
> 	btv->risc_jmp[1]=cpu_to_le32(0);
> 
> 	/* Jump to odd vbi sub */
> 	btv->risc_jmp[2]=cpu_to_le32(BT848_RISC_JUMP|(0xd<<20));
> 	if (flags&8) {
> 		if (bttv_debug > 1)
> 			printk(" ev=%08lx",virt_to_bus(btv->vbi_odd));
> 		btv->risc_jmp[3]=cpu_to_le32(virt_to_bus(btv->vbi_odd));
> 	} else {
> 		if (bttv_debug > 1)
> 			printk(" -----------");
> 		btv->risc_jmp[3]=cpu_to_le32(virt_to_bus(btv->risc_jmp+4));
> 	}
> 
>         /* Jump to odd sub */
> 	btv->risc_jmp[4]=cpu_to_le32(BT848_RISC_JUMP|(0xe<<20));
> 	if (0 != btv->risc_cap_odd) {
> 		if (bttv_debug > 1)
> 			printk(" e%d=%08x",btv->gq_grab,btv->risc_cap_odd);
> 		flags |= 3;
> 		btv->risc_jmp[5]=cpu_to_le32(btv->risc_cap_odd);
> 	} else if ((flags&2) &&
> 		   (!btv->win.interlace || 0 == btv->risc_cap_even)) {
> 		if (bttv_debug > 1)
> 			printk(" eo=%08lx",virt_to_bus(btv->risc_scr_odd));
> 		btv->risc_jmp[5]=cpu_to_le32(virt_to_bus(btv->risc_scr_odd));
> 	} else {
> 		if (bttv_debug > 1)
> 			printk(" -----------");
> 		btv->risc_jmp[5]=cpu_to_le32(virt_to_bus(btv->risc_jmp+6));
> 	}
> 
> 
> 	/* Sync to start of even field */
> 	btv->risc_jmp[6]=cpu_to_le32(BT848_RISC_SYNC|BT848_RISC_RESYNC
>                                 |BT848_FIFO_STATUS_VRO);
> 	btv->risc_jmp[7]=cpu_to_le32(0);
> 
> 	/* Jump to even vbi sub */
> 	btv->risc_jmp[8]=cpu_to_le32(BT848_RISC_JUMP);
> 	if (flags&4) {
> 		if (bttv_debug > 1)
> 			printk(" ov=%08lx",virt_to_bus(btv->vbi_even));
> 		btv->risc_jmp[9]=cpu_to_le32(virt_to_bus(btv->vbi_even));
> 	} else {
> 		if (bttv_debug > 1)
> 			printk(" -----------");
> 		btv->risc_jmp[9]=cpu_to_le32(virt_to_bus(btv->risc_jmp+10));
> 	}
> 
> 	/* Jump to even sub */
> 	btv->risc_jmp[10]=cpu_to_le32(BT848_RISC_JUMP|(8<<20));
> 	if (0 != btv->risc_cap_even) {
> 		if (bttv_debug > 1)
> 			printk(" o%d=%08x",btv->gq_grab,btv->risc_cap_even);
> 		flags |= 3;
> 		btv->risc_jmp[11]=cpu_to_le32(btv->risc_cap_even);
> 	} else if ((flags&1) &&
> 		   btv->win.interlace) {
> 		if (bttv_debug > 1)
> 			printk(" oo=%08lx",virt_to_bus(btv->risc_scr_even));
> 		btv->risc_jmp[11]=cpu_to_le32(virt_to_bus(btv->risc_scr_even));
> 	} else {
> 		if (bttv_debug > 1)
> 			printk(" -----------");
> 		btv->risc_jmp[11]=cpu_to_le32(virt_to_bus(btv->risc_jmp+12));
> 	}
> 
> 	if (btv->gq_start) {
> 		btv->risc_jmp[12]=cpu_to_le32(BT848_RISC_JUMP|(0x8<<16)|BT848_RISC_IRQ);
> 	} else {
> 		btv->risc_jmp[12]=cpu_to_le32(BT848_RISC_JUMP);
> 	}
> 	btv->risc_jmp[13]=cpu_to_le32(virt_to_bus(btv->risc_jmp));
> 
> 	/* enable cpaturing and DMA */
> 	if (bttv_debug > 1)
> 		printk(" flags=0x%x dma=%s\n",
> 		       flags,(flags&0x0f) ? "on" : "off");
> 	btaor(flags, ~0x0f, BT848_CAP_CTL);
> 	if (flags&0x0f)
> 		bt848_dma(btv, 3);
> 	else
> 		bt848_dma(btv, 0);
> }
> 
> #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,5)
> # define do_video_register(dev,type,nr) video_register_device(dev,type)
> #else
> # define do_video_register(dev,type,nr) video_register_device(dev,type,nr)
> #endif
> 
> static int __devinit init_video_dev(struct bttv *btv)
> {
> 	audio(btv, AUDIO_MUTE, 1);
>         
> 	if(do_video_register(&btv->video_dev,VFL_TYPE_GRABBER,video_nr)<0)
> 		return -1;
> 	if(do_video_register(&btv->vbi_dev,VFL_TYPE_VBI,vbi_nr)<0) 
>         {
> 	        video_unregister_device(&btv->video_dev);
> 		return -1;
> 	}
> 	if (btv->has_radio)
> 	{
> 		if(do_video_register(&btv->radio_dev, VFL_TYPE_RADIO, radio_nr)<0) 
>                 {
> 		        video_unregister_device(&btv->vbi_dev);
> 		        video_unregister_device(&btv->video_dev);
> 			return -1;
> 		}
> 	}
>         return 1;
> }
> 
> static int __devinit init_bt848(struct bttv *btv)
> {
> 	int j;
>  	unsigned long irq_flags;
> 
> 	btv->user=0; 
>         init_MUTEX(&btv->lock);
> 
> 	/* dump current state of the gpio registers before changing them,
> 	 * might help to make a new card work */
> 	if (bttv_gpio)
> 		bttv_gpio_tracking(btv,"init #1");
> 
> 	/* reset the bt848 */
> 	btwrite(0, BT848_SRESET);
> 	DEBUG(printk(KERN_DEBUG "bttv%d: bt848_mem: 0x%lx\n", btv->nr, (unsigned long) btv->bt848_mem));
> 
> 	/* not registered yet */
> 	btv->video_dev.minor = -1;
> 	btv->radio_dev.minor = -1;
> 	btv->vbi_dev.minor = -1;
> 
> 	/* default setup for max. PAL size in a 1024xXXX hicolor framebuffer */
> 	btv->win.norm=0; /* change this to 1 for NTSC, 2 for SECAM */
> 	btv->win.interlace=1;
> 	btv->win.x=0;
> 	btv->win.y=0;
> 	btv->win.width=320;
> 	btv->win.height=240;
> 	btv->win.bpp=2;
> 	btv->win.depth=16;
> 	btv->win.color_fmt=BT848_COLOR_FMT_RGB16;
> 	btv->win.bpl=1024*btv->win.bpp;
> 	btv->win.swidth=1024;
> 	btv->win.sheight=768;
> 	btv->win.vidadr=0;
> 	btv->vbi_on=0;
> 	btv->scr_on=0;
> 
> 	btv->risc_scr_odd=0;
> 	btv->risc_scr_even=0;
> 	btv->risc_cap_odd=0;
> 	btv->risc_cap_even=0;
> 	btv->risc_jmp=0;
> 	btv->vbibuf=0;
>         btv->field=btv->last_field=0;
> 
> 	btv->errors=0;
> 	btv->needs_restart=0;
> 	btv->has_radio=radio[btv->nr];
> 
> 	if (!(btv->risc_scr_odd=(unsigned int *) kmalloc(RISCMEM_LEN/2, GFP_KERNEL)))
> 		return -1;
> 	if (!(btv->risc_scr_even=(unsigned int *) kmalloc(RISCMEM_LEN/2, GFP_KERNEL)))
> 		return -1;
> 	if (!(btv->risc_jmp =(unsigned int *) kmalloc(2048, GFP_KERNEL)))
> 		return -1;
> 	btv->vbi_odd=btv->risc_jmp+16;
> 	btv->vbi_even=btv->vbi_odd+256;
> 	btv->bus_vbi_odd=virt_to_bus(btv->risc_jmp+12);
> 	btv->bus_vbi_even=virt_to_bus(btv->risc_jmp+6);
> 
> 	btwrite(virt_to_bus(btv->risc_jmp+2), BT848_RISC_STRT_ADD);
> 	btv->vbibuf=(unsigned char *) vmalloc_32(VBIBUF_SIZE);
> 	if (!btv->vbibuf) 
> 		return -1;
> 	if (!(btv->gbuf = kmalloc(sizeof(struct bttv_gbuf)*gbuffers,GFP_KERNEL)))
> 		return -1;
> 	for (j = 0; j < gbuffers; j++) {
> 		if (!(btv->gbuf[j].risc = kmalloc(16384,GFP_KERNEL)))
> 			return -1;
> 	}
> 	
> 	memset(btv->vbibuf, 0, VBIBUF_SIZE); /* We don't want to return random
> 	                                        memory to the user */
> 
> 	btv->fbuffer=NULL;
> 
> /*	btwrite(0, BT848_TDEC); */
>         btwrite(0x10, BT848_COLOR_CTL);
> 	btwrite(0x00, BT848_CAP_CTL);
> 	/* set planar and packed mode trigger points and         */
> 	/* set rising edge of inverted GPINTR pin as irq trigger */
> 	btwrite(BT848_GPIO_DMA_CTL_PKTP_32|
> 		BT848_GPIO_DMA_CTL_PLTP1_16|
> 		BT848_GPIO_DMA_CTL_PLTP23_16|
> 		BT848_GPIO_DMA_CTL_GPINTC|
> 		BT848_GPIO_DMA_CTL_GPINTI, 
> 		BT848_GPIO_DMA_CTL);
> 
>         /* select direct input */
> 	btwrite(0x00, BT848_GPIO_REG_INP);
> 	btwrite(0x00, BT848_GPIO_OUT_EN);
> 	if (bttv_gpio)
> 		bttv_gpio_tracking(btv,"init #2");
> 
> 	btwrite(BT848_IFORM_MUX1 | BT848_IFORM_XTAUTO | BT848_IFORM_AUTO,
> 		BT848_IFORM);
> 
> 	btwrite(0xd8, BT848_CONTRAST_LO);
> 	bt848_bright(btv, 0x10);
> 
> 	btwrite(0x20, BT848_E_VSCALE_HI);
> 	btwrite(0x20, BT848_O_VSCALE_HI);
> 	btwrite(/*BT848_ADC_SYNC_T|*/
> 		BT848_ADC_RESERVED|BT848_ADC_CRUSH, BT848_ADC);
> 
> 	if (lumafilter) {
> 		btwrite(0, BT848_E_CONTROL);
> 		btwrite(0, BT848_O_CONTROL);
> 	} else {
> 		btwrite(BT848_CONTROL_LDEC, BT848_E_CONTROL);
> 		btwrite(BT848_CONTROL_LDEC, BT848_O_CONTROL);
> 	}
> 
> 	btv->picture.colour=254<<7;
> 	btv->picture.brightness=128<<8;
> 	btv->picture.hue=128<<8;
> 	btv->picture.contrast=0xd8<<7;
> 
> 	btwrite(0x00, BT848_E_SCLOOP);
> 	btwrite(0x00, BT848_O_SCLOOP);
> 
> 	/* clear interrupt status */
> 	btwrite(0xfffffUL, BT848_INT_STAT);
>         
> 	/* set interrupt mask */
> 	btwrite(btv->triton1|
>                 /*BT848_INT_PABORT|BT848_INT_RIPERR|BT848_INT_PPERR|
>                   BT848_INT_FDSR|BT848_INT_FTRGT|BT848_INT_FBUS|*/
>                 (fieldnr ? BT848_INT_VSYNC : 0)|
> 		BT848_INT_GPINT|
> 		BT848_INT_SCERR|
> 		BT848_INT_RISCI|BT848_INT_OCERR|BT848_INT_VPRES|
> 		BT848_INT_FMTCHG|BT848_INT_HLOCK,
> 		BT848_INT_MASK);
> 
> 	bt848_muxsel(btv, 1);
> 	bt848_set_winsize(btv);
> 	make_vbitab(btv);
> 	spin_lock_irqsave(&btv->s_lock, irq_flags);
> 	bt848_set_risc_jmps(btv,-1);
> 	spin_unlock_irqrestore(&btv->s_lock, irq_flags);
> 
> 	/* needs to be done before i2c is registered */
>         if (btv->type == BTTV_HAUPPAUGE || btv->type == BTTV_HAUPPAUGE878)
>                 bttv_boot_msp34xx(btv,5);
> 	if (btv->type == BTTV_VOODOOTV_FM)
> 		bttv_boot_msp34xx(btv,20);
> 
> 	/* register i2c */
>         btv->tuner_type=-1;
>         init_bttv_i2c(btv);
> 
> 	/* some card-specific stuff (needs working i2c) */
> 	bttv_init_card(btv);
> 
> 	/*
> 	 *	Now add the template and register the device unit.
> 	 */
>         init_video_dev(btv);
> 
> 	return 0;
> }
> 
> /* ----------------------------------------------------------------------- */
> 
> static char *irq_name[] = { "FMTCHG", "VSYNC", "HSYNC", "OFLOW", "HLOCK",
> 			    "VPRES", "6", "7", "I2CDONE", "GPINT", "10",
> 			    "RISCI", "FBUS", "FTRGT", "FDSR", "PPERR",
> 			    "RIPERR", "PABORT", "OCERR", "SCERR" };
> 
> //static void bttv_irq(int irq, void *dev_id, struct pt_regs * regs)
> //unsigned int bttv_irq(unsigned int irq, struct pt_regs * regs)
> 
> unsigned int intr_handler(unsigned int irq, struct pt_regs *regs) 
> {
> 	u32 stat,astat;
> 	u32 dstat;
> 	int count;
> 	unsigned long timestamp;
> 	struct bttv *btv;
> 
> 	// the following line assumes we have one and only one card 
> 	btv = bttvs;
> 	count=0;
>         
> 	printk("In bttv ISR\n");
> 	while (1) {
> 		/* get/clear interrupt status bits */
> 		stat=btread(BT848_INT_STAT);
> 		astat=stat&btread(BT848_INT_MASK);
> 		if (!astat)
> 			return -1;
> 		btwrite(stat,BT848_INT_STAT);
> 
> 		/* get device status bits */
> 		dstat=btread(BT848_DSTATUS);
> 
> 		if (irq_debug) {
> 			int i;
> 			printk(KERN_DEBUG "bttv%d: irq loop=%d risc=%x, bits:",
> 			       btv->nr, count, stat>>28);
> 			for (i = 0; i < (sizeof(irq_name)/sizeof(char*)); i++) {
> 				if (stat & (1 << i))
> 					printk(" %s",irq_name[i]);
> 				if (astat & (1 << i))
> 					printk("*");
> 			}
> 			if (stat & BT848_INT_HLOCK)
> 				printk("   HLOC => %s", (dstat & BT848_DSTATUS_HLOC)
> 				       ? "yes" : "no");
> 			if (stat & BT848_INT_VPRES)
> 				printk("   PRES => %s", (dstat & BT848_DSTATUS_PRES)
> 				       ? "yes" : "no");
> 			if (stat & BT848_INT_FMTCHG)
> 				printk("   NUML => %s", (dstat & BT848_DSTATUS_PRES)
> 				       ? "625" : "525");
> 			printk("\n");
> 		}
> 
> 		if (astat&BT848_INT_GPINT)
> 			wake_up_interruptible(&btv->gpioq);
> 
> 		if (astat&BT848_INT_VSYNC) 
>                         btv->field++;
> 
> 		if (astat&(BT848_INT_SCERR|BT848_INT_OCERR)) {
> 			if (bttv_verbose)
> 				printk("bttv%d: irq:%s%s risc_count=%08x\n",
> 				       btv->nr,
> 				       (astat&BT848_INT_SCERR) ? " SCERR" : "",
> 				       (astat&BT848_INT_OCERR) ? " OCERR" : "",
> 				       btread(BT848_RISC_COUNT));
> 			btv->errors++;
> 			if (btv->errors < BTTV_ERRORS) {
> 				spin_lock(&btv->s_lock);
> 				btand(~15, BT848_GPIO_DMA_CTL);
> 				btwrite(virt_to_bus(btv->risc_jmp+2),
> 					BT848_RISC_STRT_ADD);
> 				bt848_set_geo(btv,0);
> 				bt848_set_risc_jmps(btv,-1);
> 				spin_unlock(&btv->s_lock);
> 			} else {
> 				if (bttv_verbose)
> 					printk("bttv%d: aiee: error loops\n",btv->nr);
> 				bt848_offline(btv);
> 			}
> 		}
> 		if (astat&BT848_INT_RISCI) 
> 		{
> 			if (bttv_debug > 1)
> 				printk("bttv%d: IRQ_RISCI\n",btv->nr);
> 
> 			/* captured VBI frame */
> 			if (stat&(1<<28)) 
> 			{
> 				btv->vbip=0;
> 				/* inc vbi frame count for detecting drops */
> 				(*(u32 *)&(btv->vbibuf[VBIBUF_SIZE - 4]))++;
> 				wake_up_interruptible(&btv->vbiq);
> 			}
> 
> 			/* captured full frame */
> 			if (stat&(2<<28) && btv->gq_grab != -1) 
> 			{
> 			        /* get a time stamp and write it out to the FIFO */
> 			        timestamp = 1;
> 				rtf_put(SPIKE_BTTV_OUTPUT_FIFO, &timestamp, sizeof(unsigned long));     
>                                 btv->last_field=btv->field;
> 				if (bttv_debug)
> 					printk("bttv%d: cap irq: done %d\n",btv->nr,btv->gq_grab);
> 				do_gettimeofday(&btv->gbuf[btv->gq_grab].tv);
> 				spin_lock(&btv->s_lock);
> 				btv->gbuf[btv->gq_grab].stat = GBUFFER_DONE;
> 				btv->gq_grab = -1;
> 			        if (btv->gq_in != btv->gq_out)
> 				{
> 					btv->gq_grab = btv->gqueue[btv->gq_out++];
> 					btv->gq_out  = btv->gq_out % MAX_GBUFFERS;
> 					if (bttv_debug)
> 						printk("bttv%d: cap irq: capture %d\n",btv->nr,btv->gq_grab);
>                                         btv->risc_cap_odd  = btv->gbuf[btv->gq_grab].ro;
> 					btv->risc_cap_even = btv->gbuf[btv->gq_grab].re;
> 					bt848_set_risc_jmps(btv,-1);
> 					bt848_set_geo(btv,0);
> 					btwrite(BT848_COLOR_CTL_GAMMA,
> 						BT848_COLOR_CTL);
> 				} else {
>                                         btv->risc_cap_odd  = 0;
> 					btv->risc_cap_even = 0;
> 					bt848_set_risc_jmps(btv,-1);
>                                         bt848_set_geo(btv,0);
> 					btwrite(btv->fb_color_ctl | BT848_COLOR_CTL_GAMMA,
> 						BT848_COLOR_CTL);
> 				}
> 				spin_unlock(&btv->s_lock);
> 				wake_up_interruptible(&btv->capq);
> 				break;
> 			}
> 			if (stat&(8<<28) && btv->gq_start) 
> 			{
> 				spin_lock(&btv->s_lock);
> 				btv->gq_start = 0;
> 				btv->gq_grab = btv->gqueue[btv->gq_out++];
> 				btv->gq_out  = btv->gq_out % MAX_GBUFFERS;
> 				if (bttv_debug)
> 					printk("bttv%d: cap irq: capture %d [start]\n",btv->nr,btv->gq_grab);
> 				btv->risc_cap_odd  = btv->gbuf[btv->gq_grab].ro;
> 				btv->risc_cap_even = btv->gbuf[btv->gq_grab].re;
> 				bt848_set_risc_jmps(btv,-1);
> 				bt848_set_geo(btv,0);
> 				btwrite(BT848_COLOR_CTL_GAMMA,
> 					BT848_COLOR_CTL);
> 				spin_unlock(&btv->s_lock);
> 			}
> 		}
> 
> 		if (astat&BT848_INT_HLOCK) {
> 			if ((dstat&BT848_DSTATUS_HLOC) || (btv->radio))
> 				audio(btv, AUDIO_ON,0);
> 			else
> 				audio(btv, AUDIO_OFF,0);
> 		}
>     
> 		count++;
> 		if (count > 20) {
> 			btwrite(0, BT848_INT_MASK);
> 			printk(KERN_ERR 
> 			       "bttv%d: IRQ lockup, cleared int mask\n", btv->nr);
> 			bt848_offline(btv);
> 		}
> 	}
> 	rtl_hard_enable_irq (irq);
> 	printk("Leaving bttv ISR\n");
> 
> 	return 1;
> }
> 
> 
> 
> /*
>  *	Scan for a Bt848 card, request the irq and map the io memory 
>  */
> 
> static void __devexit bttv_remove(struct pci_dev *pci_dev)
> {
>         u8 command;
>         int j;
>         struct bttv *btv = pci_get_drvdata(pci_dev);
> 
> 	if (bttv_verbose)
> 		printk("bttv%d: unloading\n",btv->nr);
> 
>         /* unregister i2c_bus */
> 	if (0 == btv->i2c_rc)
> 		i2c_bit_del_bus(&btv->i2c_adap);
> 
>         /* turn off all capturing, DMA and IRQs */
>         btand(~15, BT848_GPIO_DMA_CTL);
> 
>         /* first disable interrupts before unmapping the memory! */
>         btwrite(0, BT848_INT_MASK);
>         btwrite(~0x0UL,BT848_INT_STAT);
>         btwrite(0x0, BT848_GPIO_OUT_EN);
> 	if (bttv_gpio)
> 		bttv_gpio_tracking(btv,"cleanup");
> 
>         /* disable PCI bus-mastering */
>         pci_read_config_byte(btv->dev, PCI_COMMAND, &command);
>         command &= ~PCI_COMMAND_MASTER;
>         pci_write_config_byte(btv->dev, PCI_COMMAND, command);
> 
>         /* unmap and free memory */
>         for (j = 0; j < gbuffers; j++)
>                 if (btv->gbuf[j].risc)
>                         kfree(btv->gbuf[j].risc);
>         if (btv->gbuf)
>                 kfree((void *) btv->gbuf);
> 
>         if (btv->risc_scr_odd)
>                 kfree((void *) btv->risc_scr_odd);
> 
>         if (btv->risc_scr_even)
>                 kfree((void *) btv->risc_scr_even);
> 
>         DEBUG(printk(KERN_DEBUG "free: risc_jmp: 0x%p.\n", btv->risc_jmp));
>         if (btv->risc_jmp)
>                 kfree((void *) btv->risc_jmp);
> 
>         DEBUG(printk(KERN_DEBUG "bt848_vbibuf: 0x%p.\n", btv->vbibuf));
>         if (btv->vbibuf)
>                 vfree((void *) btv->vbibuf);
> 
>         free_irq(btv->irq,btv);
>         DEBUG(printk(KERN_DEBUG "bt848_mem: 0x%p.\n", btv->bt848_mem));
>         if (btv->bt848_mem)
>                 iounmap(btv->bt848_mem);
> 
>         if (btv->video_dev.minor!=-1)
>                 video_unregister_device(&btv->video_dev);
>         if (btv->vbi_dev.minor!=-1)
>                 video_unregister_device(&btv->vbi_dev);
>         if (btv->radio_dev.minor != -1)
>                 video_unregister_device(&btv->radio_dev);
> 
>         release_mem_region(pci_resource_start(btv->dev,0),
>                            pci_resource_len(btv->dev,0));
>         /* wake up any waiting processes
>            because shutdown flag is set, no new processes (in this queue)
>            are expected
>         */
>         btv->shutdown=1;
>         wake_up(&btv->gpioq);
> 
> 	pci_set_drvdata(pci_dev, NULL);
>         return;
> }
> 
> 
> static int __devinit bttv_probe(struct pci_dev *dev, const struct pci_device_id *pci_id)
> {
> 	int result;
> 	unsigned char lat;
> 	struct bttv *btv;
> #if defined(__powerpc__)
>         unsigned int cmd;
> #endif
> 
> 	printk(KERN_INFO "bttv: Bt8xx card found (%d).\n", bttv_num);
> 
>         btv=&bttvs[bttv_num];
>         btv->dev=dev;
>         btv->nr = bttv_num;
>         btv->bt848_mem=NULL;
>         btv->vbibuf=NULL;
>         btv->risc_jmp=NULL;
>         btv->vbi_odd=NULL;
>         btv->vbi_even=NULL;
>         init_waitqueue_head(&btv->vbiq);
>         init_waitqueue_head(&btv->capq);
>         btv->vbip=VBIBUF_SIZE;
> 	btv->s_lock = SPIN_LOCK_UNLOCKED;
> 	init_waitqueue_head(&btv->gpioq);
> 	btv->shutdown=0;
> 	
> 	memcpy(&btv->video_dev,&bttv_template, sizeof(bttv_template));
> 	memcpy(&btv->vbi_dev,&vbi_template, sizeof(vbi_template));
> 	memcpy(&btv->radio_dev,&radio_template,sizeof(radio_template));
> 	
>         btv->id=dev->device;
>         btv->irq=dev->irq;
> 	btv->bt848_adr=pci_resource_start(dev,0);
> 	if (pci_enable_device(dev))
> 		return -EIO;
> 	if (!request_mem_region(pci_resource_start(dev,0),
> 				pci_resource_len(dev,0),
> 				"bttv")) {
> 		return -EBUSY;
> 	}
>         if (btv->id >= 878)
>                 btv->i2c_command = 0x83;                   
>         else
>                 btv->i2c_command=(I2C_TIMING | BT848_I2C_SCL | BT848_I2C_SDA);
> 
>         pci_read_config_byte(dev, PCI_CLASS_REVISION, &btv->revision);
>         pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
>         printk(KERN_INFO "bttv%d: Bt%d (rev %d) at %02x:%02x.%x, ",
>                bttv_num,btv->id, btv->revision, dev->bus->number,
> 	       PCI_SLOT(dev->devfn),PCI_FUNC(dev->devfn));
>         printk("irq: %d, latency: %d, memory: 0x%lx\n",
> 	       btv->irq, lat, btv->bt848_adr);
> 	
> 	bttv_idcard(btv);
> 
> #if defined(__powerpc__)
>         /* on OpenFirmware machines (PowerMac at least), PCI memory cycle */
>         /* response on cards with no firmware is not enabled by OF */
>         pci_read_config_dword(dev, PCI_COMMAND, &cmd);
>         cmd = (cmd | PCI_COMMAND_MEMORY ); 
>         pci_write_config_dword(dev, PCI_COMMAND, cmd);
> #endif
> 
> #ifdef __sparc__
> 	btv->bt848_mem=(unsigned char *)btv->bt848_adr;
> #else
> 	btv->bt848_mem=ioremap(btv->bt848_adr, 0x1000);
> #endif
>         
>         /* clear interrupt mask */
> 	btwrite(0, BT848_INT_MASK);
> 
>         //result = request_irq(btv->irq, bttv_irq,
>         //                     SA_SHIRQ | SA_INTERRUPT,"bttv",(void *)btv);
>         result = rtl_request_irq(btv->irq, intr_handler);
>         if (result==-EINVAL) 
>         {
>                 printk(KERN_ERR "bttv%d: Bad irq number or handler\n",
>                        bttv_num);
> 		goto fail1;
>         }
>         if (result==-EBUSY)
>         {
>                 printk(KERN_ERR "bttv%d: IRQ %d busy, change your PnP config in BIOS\n",bttv_num,btv->irq);
> 		goto fail1;
>         }
>         if (result < 0) 
> 		goto fail1;
>         
> 	if (0 != bttv_handle_chipset(btv)) {
> 		result = -1;
> 		goto fail2;
> 	}
> 	
>         pci_set_master(dev);
> 	pci_set_drvdata(dev,btv);
> 
> 	if(init_bt848(btv) < 0) {
> 		bttv_remove(dev);
> 		return -EIO;
> 	}
> 	rtl_hard_enable_irq(btv->irq);
> 	bttv_num++;
> 
>         return 0;
> 
>  fail2:
>         free_irq(btv->irq,btv);
>  fail1:
> 	release_mem_region(pci_resource_start(btv->dev,0),
> 			   pci_resource_len(btv->dev,0));
> 	return result;
> }
> 
> static struct pci_device_id bttv_pci_tbl[] __devinitdata = {
>         {PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT848,
>          PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
> 	{PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT849,
>          PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
> 	{PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT878,
>          PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
> 	{PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT879,
>          PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
>         {0,}
> };
> 
> MODULE_DEVICE_TABLE(pci, bttv_pci_tbl);
> 
> static struct pci_driver bttv_pci_driver = {
>         name:     "bttv",
>         id_table: bttv_pci_tbl,
>         probe:    bttv_probe,
>         remove:   bttv_remove,
> };
> 
> int bttv_init_module(void)
> {
> 	bttv_num = 0;
> 
> 	printk(KERN_INFO "bttv: driver version %d.%d.%d loaded\n",
> 	       (BTTV_VERSION_CODE >> 16) & 0xff,
> 	       (BTTV_VERSION_CODE >> 8) & 0xff,
> 	       BTTV_VERSION_CODE & 0xff);
> 	if (gbuffers < 2 || gbuffers > MAX_GBUFFERS)
> 		gbuffers = 2;
> 	if (gbufsize < 0 || gbufsize > BTTV_MAX_FBUF)
> 		gbufsize = BTTV_MAX_FBUF;
> 	if (bttv_verbose)
> 		printk(KERN_INFO "bttv: using %d buffers with %dk (%dk total) for capture\n",
> 		       gbuffers,gbufsize/1024,gbuffers*gbufsize/1024);
> 
> 	bttv_check_chipset();
> 
> 	/* set up the FIFO for timestamps */
> 	rtf_destroy(SPIKE_BTTV_OUTPUT_FIFO);     // free up the resource, just in case
>         rtf_create(SPIKE_BTTV_OUTPUT_FIFO, SPIKE_FIFO_SIZE);  // fifo from which rt task talks to device
>         
> 
> 
> 	return pci_module_init(&bttv_pci_driver);
> }
> 
> void bttv_cleanup_module(void)
> {
>         rtl_free_irq(bttvs[0].irq);
> 	pci_unregister_driver(&bttv_pci_driver);
> 	return;
> }
> 
> module_init(bttv_init_module);
> module_exit(bttv_cleanup_module);
> 
> /*
>  * Local variables:
>  * c-basic-offset: 8
>  * End:
>  */
> 
> - -- [rtl] ---
> To unsubscribe:
> echo "unsubscribe rtl" | mail majordomo@rtlinux.org OR
> echo "unsubscribe rtl <Your_email>" | mail majordomo@rtlinux.org
> - --
> For more information on Real-Time Linux see:
> http://www.rtlinux.org/
> 
> ------------------------------
> 
> End of rtl-digest V1 #101
> *************************
> 

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
有限会社 サンプラス  国際部部長  友近昭博  email: tomochika@sunplus.com
〒411-0832
静岡県三島市南二日町25−12ブンカビジネスビル1階101
Tel:0559-91-1440  Fax:0559-91-1441
E-Mail: sunplus@sunplus.com    HomePage: http://www.sunplus.com/