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

📄 stradis.c

📁 V4l driver for DVB HD
💻 C
📖 第 1 页 / 共 5 页
字号:
static ssize_t saa_write(struct file *file, const char __user * buf,	size_t count, loff_t * ppos){	struct saa7146 *saa = file->private_data;	unsigned long todo = count;	int blocksize, split;	unsigned long flags;	while (todo > 0) {		if (saa->writemode == VID_WRITE_MPEG_AUD) {			spin_lock_irqsave(&saa->lock, flags);			if (saa->audhead <= saa->audtail)				blocksize = 65536 -					(saa->audtail - saa->audhead);			else				blocksize = saa->audhead - saa->audtail;			spin_unlock_irqrestore(&saa->lock, flags);			if (blocksize < 16384) {				saawrite(SAA7146_PSR_DEBI_S |					SAA7146_PSR_PIN1, SAA7146_IER);				saawrite(SAA7146_PSR_PIN1, SAA7146_PSR);				/* wait for buffer space to open */				interruptible_sleep_on(&saa->audq);			}			spin_lock_irqsave(&saa->lock, flags);			if (saa->audhead <= saa->audtail) {				blocksize = 65536 -					(saa->audtail - saa->audhead);				split = 65536 - saa->audtail;			} else {				blocksize = saa->audhead - saa->audtail;				split = 65536;			}			spin_unlock_irqrestore(&saa->lock, flags);			blocksize--;			if (blocksize > todo)				blocksize = todo;			/* double check that we really have space */			if (!blocksize)				return -ENOSPC;			if (split < blocksize) {				if (copy_from_user(saa->audbuf +						saa->audtail, buf, split))					return -EFAULT;				buf += split;				todo -= split;				blocksize -= split;				saa->audtail = 0;			}			if (copy_from_user(saa->audbuf + saa->audtail, buf,					blocksize))				return -EFAULT;			saa->audtail += blocksize;			todo -= blocksize;			buf += blocksize;			saa->audtail &= 0xffff;		} else if (saa->writemode == VID_WRITE_MPEG_VID) {			spin_lock_irqsave(&saa->lock, flags);			if (saa->vidhead <= saa->vidtail)				blocksize = 524288 -					(saa->vidtail - saa->vidhead);			else				blocksize = saa->vidhead - saa->vidtail;			spin_unlock_irqrestore(&saa->lock, flags);			if (blocksize < 65536) {				saawrite(SAA7146_PSR_DEBI_S |					SAA7146_PSR_PIN1, SAA7146_IER);				saawrite(SAA7146_PSR_PIN1, SAA7146_PSR);				/* wait for buffer space to open */				interruptible_sleep_on(&saa->vidq);			}			spin_lock_irqsave(&saa->lock, flags);			if (saa->vidhead <= saa->vidtail) {				blocksize = 524288 -					(saa->vidtail - saa->vidhead);				split = 524288 - saa->vidtail;			} else {				blocksize = saa->vidhead - saa->vidtail;				split = 524288;			}			spin_unlock_irqrestore(&saa->lock, flags);			blocksize--;			if (blocksize > todo)				blocksize = todo;			/* double check that we really have space */			if (!blocksize)				return -ENOSPC;			if (split < blocksize) {				if (copy_from_user(saa->vidbuf +						saa->vidtail, buf, split))					return -EFAULT;				buf += split;				todo -= split;				blocksize -= split;				saa->vidtail = 0;			}			if (copy_from_user(saa->vidbuf + saa->vidtail, buf,					blocksize))				return -EFAULT;			saa->vidtail += blocksize;			todo -= blocksize;			buf += blocksize;			saa->vidtail &= 0x7ffff;		} else if (saa->writemode == VID_WRITE_OSD) {			if (count > 131072)				return -ENOSPC;			if (copy_from_user(saa->osdbuf, buf, count))				return -EFAULT;			buf += count;			saa->osdhead = 0;			saa->osdtail = count;			debiwrite(saa, debNormal, IBM_MP2_OSD_ADDR, 0, 2);			debiwrite(saa, debNormal, IBM_MP2_OSD_LINK_ADDR, 0, 2);			debiwrite(saa, debNormal, IBM_MP2_MASK0, 0xc00d, 2);			debiwrite(saa, debNormal, IBM_MP2_DISP_MODE,				debiread(saa, debNormal,					IBM_MP2_DISP_MODE, 2) | 1, 2);			/* trigger osd data transfer */			saawrite(SAA7146_PSR_DEBI_S |				 SAA7146_PSR_PIN1, SAA7146_IER);			saawrite(SAA7146_PSR_PIN1, SAA7146_PSR);		}	}	return count;}static int saa_open(struct inode *inode, struct file *file){	struct video_device *vdev = video_devdata(file);	struct saa7146 *saa = container_of(vdev, struct saa7146, video_dev);	file->private_data = saa;	saa->user++;	if (saa->user > 1)		return 0;	/* device open already, don't reset */	saa->writemode = VID_WRITE_MPEG_VID;	/* default to video */	return 0;}static int saa_release(struct inode *inode, struct file *file){	struct saa7146 *saa = file->private_data;	saa->user--;	if (saa->user > 0)	/* still someone using device */		return 0;	saawrite(0x007f0000, SAA7146_MC1);	/* stop all overlay dma */	return 0;}static struct file_operations saa_fops = {	.owner = THIS_MODULE,	.open = saa_open,	.release = saa_release,	.ioctl = saa_ioctl,	.compat_ioctl = v4l_compat_ioctl32,	.read = saa_read,	.llseek = no_llseek,	.write = saa_write,	.mmap = saa_mmap,};/* template for video_device-structure */static struct video_device saa_template = {	.name = "SAA7146A",	.type = VID_TYPE_CAPTURE | VID_TYPE_OVERLAY,	.hardware = VID_HARDWARE_SAA7146,	.fops = &saa_fops,	.minor = -1,};static int __devinit configure_saa7146(struct pci_dev *pdev, int num){	int retval;	struct saa7146 *saa = pci_get_drvdata(pdev);	saa->endmarkhead = saa->endmarktail = 0;	saa->win.x = saa->win.y = 0;	saa->win.width = saa->win.cropwidth = 720;	saa->win.height = saa->win.cropheight = 480;	saa->win.cropx = saa->win.cropy = 0;	saa->win.bpp = 2;	saa->win.depth = 16;	saa->win.color_fmt = palette2fmt[VIDEO_PALETTE_RGB565];	saa->win.bpl = 1024 * saa->win.bpp;	saa->win.swidth = 1024;	saa->win.sheight = 768;	saa->picture.brightness = 32768;	saa->picture.contrast = 38768;	saa->picture.colour = 32768;	saa->cap = 0;	saa->nr = num;	saa->playmode = VID_PLAY_NORMAL;	memset(saa->boardcfg, 0, 64);	/* clear board config area */	saa->saa7146_mem = NULL;	saa->dmavid1 = saa->dmavid2 = saa->dmavid3 = saa->dmaa1in =	    saa->dmaa1out = saa->dmaa2in = saa->dmaa2out =	    saa->pagevid1 = saa->pagevid2 = saa->pagevid3 = saa->pagea1in =	    saa->pagea1out = saa->pagea2in = saa->pagea2out =	    saa->pagedebi = saa->dmaRPS1 = saa->dmaRPS2 = saa->pageRPS1 =	    saa->pageRPS2 = NULL;	saa->audbuf = saa->vidbuf = saa->osdbuf = saa->dmadebi = NULL;	saa->audhead = saa->vidtail = 0;	init_waitqueue_head(&saa->i2cq);	init_waitqueue_head(&saa->audq);	init_waitqueue_head(&saa->debiq);	init_waitqueue_head(&saa->vidq);	spin_lock_init(&saa->lock);	retval = pci_enable_device(pdev);	if (retval) {		dev_err(&pdev->dev, "%d: pci_enable_device failed!\n", num);		goto err;	}	saa->id = pdev->device;	saa->irq = pdev->irq;	saa->video_dev.minor = -1;	saa->saa7146_adr = pci_resource_start(pdev, 0);	pci_read_config_byte(pdev, PCI_CLASS_REVISION, &saa->revision);	saa->saa7146_mem = ioremap(saa->saa7146_adr, 0x200);	if (saa->saa7146_mem == NULL) {		dev_err(&pdev->dev, "%d: ioremap failed!\n", num);		retval = -EIO;		goto err;	}	memcpy(&saa->video_dev, &saa_template, sizeof(saa_template));	saawrite(0, SAA7146_IER);	/* turn off all interrupts */	retval = request_irq(saa->irq, saa7146_irq, SA_SHIRQ | SA_INTERRUPT,		"stradis", saa);	if (retval == -EINVAL)		dev_err(&pdev->dev, "%d: Bad irq number or handler\n", num);	else if (retval == -EBUSY)		dev_err(&pdev->dev, "%d: IRQ %ld busy, change your PnP config "			"in BIOS\n", num, saa->irq);	if (retval < 0)		goto errio;	pci_set_master(pdev);	retval = video_register_device(&saa->video_dev, VFL_TYPE_GRABBER,		video_nr);	if (retval < 0) {		dev_err(&pdev->dev, "%d: error in registering video device!\n",			num);		goto errio;	}	return 0;errio:	iounmap(saa->saa7146_mem);err:	return retval;}static int __devinit init_saa7146(struct pci_dev *pdev){	struct saa7146 *saa = pci_get_drvdata(pdev);	saa->user = 0;	/* reset the saa7146 */	saawrite(0xffff0000, SAA7146_MC1);	mdelay(5);	/* enable debi and i2c transfers and pins */	saawrite(((SAA7146_MC1_EDP | SAA7146_MC1_EI2C |		   SAA7146_MC1_TR_E_DEBI) << 16) | 0xffff, SAA7146_MC1);	/* ensure proper state of chip */	saawrite(0x00000000, SAA7146_PAGE1);	saawrite(0x00f302c0, SAA7146_NUM_LINE_BYTE1);	saawrite(0x00000000, SAA7146_PAGE2);	saawrite(0x01400080, SAA7146_NUM_LINE_BYTE2);	saawrite(0x00000000, SAA7146_DD1_INIT);	saawrite(0x00000000, SAA7146_DD1_STREAM_B);	saawrite(0x00000000, SAA7146_DD1_STREAM_A);	saawrite(0x00000000, SAA7146_BRS_CTRL);	saawrite(0x80400040, SAA7146_BCS_CTRL);	saawrite(0x0000e000 /*| (1<<29) */ , SAA7146_HPS_CTRL);	saawrite(0x00000060, SAA7146_CLIP_FORMAT_CTRL);	saawrite(0x00000000, SAA7146_ACON1);	saawrite(0x00000000, SAA7146_ACON2);	saawrite(0x00000600, SAA7146_I2C_STATUS);	saawrite(((SAA7146_MC2_UPLD_D1_B | SAA7146_MC2_UPLD_D1_A |		SAA7146_MC2_UPLD_BRS | SAA7146_MC2_UPLD_HPS_H |		SAA7146_MC2_UPLD_HPS_V | SAA7146_MC2_UPLD_DMA2 |		SAA7146_MC2_UPLD_DMA1 | SAA7146_MC2_UPLD_I2C) << 16) | 0xffff,		SAA7146_MC2);	/* setup arbitration control registers */	saawrite(0x1412121a, SAA7146_PCI_BT_V1);	/* allocate 32k dma buffer + 4k for page table */	if ((saa->dmadebi = kmalloc(32768 + 4096, GFP_KERNEL)) == NULL) {		dev_err(&pdev->dev, "%d: debi kmalloc failed\n", saa->nr);		goto err;	}#if 0 /* keep */	saa->pagedebi = saa->dmadebi + 32768;	/* top 4k is for mmu */	saawrite(virt_to_bus(saa->pagedebi) /*|0x800 */ , SAA7146_DEBI_PAGE);	for (i = 0; i < 12; i++)	/* setup mmu page table */		saa->pagedebi[i] = virt_to_bus((saa->dmadebi + i * 4096));#endif	saa->audhead = saa->vidhead = saa->osdhead = 0;	saa->audtail = saa->vidtail = saa->osdtail = 0;	if (saa->vidbuf == NULL && (saa->vidbuf = vmalloc(524288)) == NULL) {		dev_err(&pdev->dev, "%d: malloc failed\n", saa->nr);		goto err;	}	if (saa->audbuf == NULL && (saa->audbuf = vmalloc(65536)) == NULL) {		dev_err(&pdev->dev, "%d: malloc failed\n", saa->nr);		goto errfree;	}	if (saa->osdbuf == NULL && (saa->osdbuf = vmalloc(131072)) == NULL) {		dev_err(&pdev->dev, "%d: malloc failed\n", saa->nr);		goto errfree;	}	/* allocate 81920 byte buffer for clipping */	if ((saa->dmavid2 = kzalloc(VIDEO_CLIPMAP_SIZE, GFP_KERNEL)) == NULL) {		dev_err(&pdev->dev, "%d: clip kmalloc failed\n", saa->nr);		goto errfree;	}	/* setup clipping registers */	saawrite(virt_to_bus(saa->dmavid2), SAA7146_BASE_EVEN2);	saawrite(virt_to_bus(saa->dmavid2) + 128, SAA7146_BASE_ODD2);	saawrite(virt_to_bus(saa->dmavid2) + VIDEO_CLIPMAP_SIZE,		 SAA7146_PROT_ADDR2);	saawrite(256, SAA7146_PITCH2);	saawrite(4, SAA7146_PAGE2);	/* dma direction: read, no byteswap */	saawrite(((SAA7146_MC2_UPLD_DMA2) << 16) | SAA7146_MC2_UPLD_DMA2,		 SAA7146_MC2);	I2CBusScan(saa);	return 0;errfree:	vfree(saa->osdbuf);	vfree(saa->audbuf);	vfree(saa->vidbuf);	saa->audbuf = saa->osdbuf = saa->vidbuf = NULL;err:	return -ENOMEM;}static void stradis_release_saa(struct pci_dev *pdev){	u8 command;	struct saa7146 *saa = pci_get_drvdata(pdev);	/* turn off all capturing, DMA and IRQs */	saawrite(0xffff0000, SAA7146_MC1);	/* reset chip */	saawrite(0, SAA7146_MC2);	saawrite(0, SAA7146_IER);	saawrite(0xffffffffUL, SAA7146_ISR);	/* disable PCI bus-mastering */	pci_read_config_byte(pdev, PCI_COMMAND, &command);	command &= ~PCI_COMMAND_MASTER;	pci_write_config_byte(pdev, PCI_COMMAND, command);	/* unmap and free memory */	saa->audhead = saa->audtail = saa->osdhead = 0;	saa->vidhead = saa->vidtail = saa->osdtail = 0;	vfree(saa->vidbuf);	vfree(saa->audbuf);	vfree(saa->osdbuf);	kfree(saa->dmavid2);	saa->audbuf = saa->vidbuf = saa->osdbuf = NULL;	saa->dmavid2 = NULL;	kfree(saa->dmadebi);	kfree(saa->dmavid1);	kfree(saa->dmavid3);	kfree(saa->dmaa1in);	kfree(saa->dmaa1out);	kfree(saa->dmaa2in);	kfree(saa->dmaa2out);	kfree(saa->dmaRPS1);	kfree(saa->dmaRPS2);	free_irq(saa->irq, saa);	if (saa->saa7146_mem)		iounmap(saa->saa7146_mem);	if (saa->video_dev.minor != -1)		video_unregister_device(&saa->video_dev);}static int __devinit stradis_probe(struct pci_dev *pdev,	const struct pci_device_id *ent){	int retval = -EINVAL;	if (saa_num >= SAA7146_MAX)		goto err;	if (!pdev->subsystem_vendor)		dev_info(&pdev->dev, "%d: rev1 decoder\n", saa_num);	else		dev_info(&pdev->dev, "%d: SDM2xx found\n", saa_num);	pci_set_drvdata(pdev, &saa7146s[saa_num]);	retval = configure_saa7146(pdev, saa_num);	if (retval) {		dev_err(&pdev->dev, "%d: error in configuring\n", saa_num);		goto err;	}	if (init_saa7146(pdev) < 0) {		dev_err(&pdev->dev, "%d: error in initialization\n", saa_num);		retval = -EIO;		goto errrel;	}	saa_num++;	return 0;errrel:	stradis_release_saa(pdev);err:	return retval;}static void __devexit stradis_remove(struct pci_dev *pdev){	stradis_release_saa(pdev);}static struct pci_device_id stradis_pci_tbl[] = {	{ PCI_DEVICE(PCI_VENDOR_ID_PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7146) },	{ 0 }};MODULE_DEVICE_TABLE(pci, stradis_pci_tbl);static struct pci_driver stradis_driver = {	.name = "stradis",	.i

⌨️ 快捷键说明

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