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

📄 saa7146_core.c

📁 linux环境下的dvb驱动程序
💻 C
📖 第 1 页 / 共 2 页
字号:
	}	if (0 != (isr & (MASK_16|MASK_17))) {		u32 status = saa7146_read(dev, I2C_STATUS);		if( (0x3 == (status & 0x3)) || (0 == (status & 0x1)) ) {			IER_DISABLE(dev, MASK_16|MASK_17);			/* only wake up if we expect something */			if( 0 != dev->i2c_op ) {				u32 psr = (saa7146_read(dev, PSR) >> 16) & 0x2;				u32 ssr = (saa7146_read(dev, SSR) >> 17) & 0x1f;				DEB_I2C(("irq: i2c, status: 0x%08x, psr:0x%02x, ssr:0x%02x).\n",status,psr,ssr));				dev->i2c_op = 0;				wake_up(&dev->i2c_wq);			} else {				DEB_I2C(("unexpected irq: i2c, status: 0x%08x, isr %#x\n",status, isr));			}		} else {			DEB_I2C(("unhandled irq: i2c, status: 0x%08x, isr %#x\n",status, isr));		}		isr &= ~(MASK_16|MASK_17);	}	if( 0 != isr ) {		ERR(("warning: interrupt enabled, but not handled properly.(0x%08x)\n",isr));		ERR(("disabling interrupt source(s)!\n"));		IER_DISABLE(dev,isr);	}	return IRQ_HANDLED;}/*********************************************************************************//* configuration-functions                                                       */static int saa7146_init_one(struct pci_dev *pci, const struct pci_device_id *ent){	unsigned long adr = 0, len = 0;	struct saa7146_dev* dev = kmalloc (sizeof(struct saa7146_dev),GFP_KERNEL);		struct saa7146_pci_extension_data *pci_ext = (struct saa7146_pci_extension_data *)ent->driver_data;	struct saa7146_extension* ext = pci_ext->ext;	int err = 0;		if (!(dev = kmalloc (sizeof(struct saa7146_dev),GFP_KERNEL))) {		ERR(("out of memory.\n"));		return -ENOMEM;	}	/* clear out mem for sure */	memset(dev, 0x0, sizeof(struct saa7146_dev));	DEB_EE(("pci:%p\n",pci));		if (pci_enable_device(pci)) {		ERR(("pci_enable_device() failed.\n"));		err = -EIO;		goto pci_error;	}	/* enable bus-mastering */	pci_set_master(pci);	dev->pci = pci;	/* get chip-revision; this is needed to enable bug-fixes */	if( 0 > pci_read_config_dword(dev->pci, PCI_CLASS_REVISION, &dev->revision)) {		ERR(("pci_read_config_dword() failed.\n"));		err = -ENODEV;		goto pci_error;	}	dev->revision &= 0xf;	/* remap the memory from virtual to physical adress */	adr = pci_resource_start(pci,0);	len = pci_resource_len(pci,0);	if (!request_mem_region(pci_resource_start(pci,0), pci_resource_len(pci,0), "saa7146")) {		ERR(("request_mem_region() failed.\n"));		err = -ENODEV;		goto pci_error;	}	if (!(dev->mem = ioremap(adr,len))) {		ERR(("ioremap() failed.\n"));		err = -ENODEV;		goto ioremap_error;	}	/* we don't do a master reset here anymore, it screws up	   some boards that don't have an i2c-eeprom for configuration	   values *//*	saa7146_write(dev, MC1, MASK_31);*/	/* disable all irqs */	saa7146_write(dev, IER, 0);	/* shut down all dma transfers */	saa7146_write(dev, MC1, 0x00ff0000);	/* clear out any rps-signals pending */	saa7146_write(dev, MC2, 0xf8000000);	/* request an interrupt for the saa7146 */	if (request_irq(dev->pci->irq, interrupt_hw, SA_SHIRQ | SA_INTERRUPT,			dev->name, dev))	{		ERR(("request_irq() failed.\n"));		err = -ENODEV;		goto irq_error;	}	/* get memory for various stuff */	dev->d_rps0.cpu_addr = pci_alloc_consistent(dev->pci, SAA7146_RPS_MEM, &dev->d_rps0.dma_handle);		if( NULL == dev->d_rps0.cpu_addr ) {		err = -ENOMEM;		goto kmalloc_error_1;	}		memset(dev->d_rps0.cpu_addr, 0x0, SAA7146_RPS_MEM);	dev->d_rps1.cpu_addr = pci_alloc_consistent(dev->pci, SAA7146_RPS_MEM, &dev->d_rps1.dma_handle);		if( NULL == dev->d_rps1.cpu_addr ) {		err = -ENOMEM;		goto kmalloc_error_2;	}		memset(dev->d_rps1.cpu_addr, 0x0, SAA7146_RPS_MEM);		dev->d_i2c.cpu_addr = pci_alloc_consistent(dev->pci, SAA7146_RPS_MEM, &dev->d_i2c.dma_handle);		if( NULL == dev->d_i2c.cpu_addr ) {		err = -ENOMEM;		goto kmalloc_error_3;	}		memset(dev->d_i2c.cpu_addr, 0x0, SAA7146_RPS_MEM);	/* the rest + print status message */		/* create a nice device name */	sprintf(&dev->name[0], "saa7146 (%d)",saa7146_num);	INFO(("found saa7146 @ mem %p (revision %d, irq %d) (0x%04x,0x%04x).\n", dev->mem, dev->revision,dev->pci->irq,dev->pci->subsystem_vendor,dev->pci->subsystem_device));	dev->ext = ext;	pci_set_drvdata(pci,dev);        init_MUTEX(&dev->lock);	dev->int_slock = SPIN_LOCK_UNLOCKED;	dev->slock = SPIN_LOCK_UNLOCKED;	init_MUTEX(&dev->i2c_lock);	dev->module = THIS_MODULE;	init_waitqueue_head(&dev->i2c_wq);	/* set some sane pci arbitrition values */	saa7146_write(dev, PCI_BT_V1, 0x1c00101f); 	if( 0 != ext->probe) {		if( 0 != ext->probe(dev) ) {			DEB_D(("ext->probe() failed for %p. skipping device.\n",dev));			err = -ENODEV;			goto probe_error;		}	}	if( 0 != ext->attach(dev,pci_ext) ) {		DEB_D(("ext->attach() failed for %p. skipping device.\n",dev));			err = -ENODEV;			goto attach_error;	}	INIT_LIST_HEAD(&dev->item);	list_add_tail(&dev->item,&saa7146_devices);	saa7146_num++;	err = 0;	goto out;attach_error:probe_error:	pci_set_drvdata(pci,NULL);	pci_free_consistent(dev->pci, SAA7146_RPS_MEM, dev->d_i2c.cpu_addr, dev->d_i2c.dma_handle);kmalloc_error_3:	pci_free_consistent(dev->pci, SAA7146_RPS_MEM, dev->d_rps1.cpu_addr, dev->d_rps1.dma_handle);kmalloc_error_2:	pci_free_consistent(dev->pci, SAA7146_RPS_MEM, dev->d_rps0.cpu_addr, dev->d_rps0.dma_handle);kmalloc_error_1:	free_irq(dev->pci->irq, (void *)dev);irq_error:	iounmap(dev->mem);ioremap_error:        release_mem_region(adr,len);pci_error:	kfree(dev);out:	return err;}static void saa7146_remove_one(struct pci_dev *pdev){	struct saa7146_dev* dev = (struct saa7146_dev*) pci_get_drvdata(pdev);	DEB_EE(("dev:%p\n",dev));	dev->ext->detach(dev);	/* shut down all video dma transfers */	saa7146_write(dev, MC1, 0x00ff0000);	/* disable all irqs, release irq-routine */	saa7146_write(dev, IER, 0);	free_irq(dev->pci->irq, (void *)dev);	/* free kernel memory */	pci_free_consistent(dev->pci, SAA7146_RPS_MEM, dev->d_i2c.cpu_addr, dev->d_i2c.dma_handle);	pci_free_consistent(dev->pci, SAA7146_RPS_MEM, dev->d_rps1.cpu_addr, dev->d_rps1.dma_handle);	pci_free_consistent(dev->pci, SAA7146_RPS_MEM, dev->d_rps0.cpu_addr, dev->d_rps0.dma_handle);	iounmap(dev->mem);	release_mem_region(pci_resource_start(dev->pci,0), pci_resource_len(dev->pci,0));	list_del(&dev->item);	kfree(dev);	saa7146_num--;}/*********************************************************************************//* extension handling functions                                                  */int saa7146_register_extension(struct saa7146_extension* ext){	DEB_EE(("ext:%p\n",ext));	if( 0 == initialized ) {		INIT_LIST_HEAD(&saa7146_devices);		init_MUTEX(&saa7146_devices_lock);		initialized = 1;	}	ext->driver.name = ext->name;	ext->driver.id_table = ext->pci_tbl;	ext->driver.probe = saa7146_init_one;	ext->driver.remove = saa7146_remove_one;	printk("saa7146: register extension '%s'.\n",ext->name);	return pci_module_init(&ext->driver);}int saa7146_unregister_extension(struct saa7146_extension* ext){	DEB_EE(("ext:%p\n",ext));	printk("saa7146: unregister extension '%s'.\n",ext->name);	pci_unregister_driver(&ext->driver);	return 0;}static int __init saa7146_init_module(void){	if( 0 == initialized ) {		INIT_LIST_HEAD(&saa7146_devices);		init_MUTEX(&saa7146_devices_lock);		initialized = 1;	}	return 0;}static void __exit saa7146_cleanup_module(void){}module_init(saa7146_init_module);module_exit(saa7146_cleanup_module);EXPORT_SYMBOL_GPL(saa7146_register_extension);EXPORT_SYMBOL_GPL(saa7146_unregister_extension);/* misc functions used by extension modules */EXPORT_SYMBOL_GPL(saa7146_pgtable_alloc);EXPORT_SYMBOL_GPL(saa7146_pgtable_free);EXPORT_SYMBOL_GPL(saa7146_pgtable_build_single);EXPORT_SYMBOL_GPL(saa7146_vmalloc_build_pgtable);EXPORT_SYMBOL_GPL(saa7146_wait_for_debi_done);EXPORT_SYMBOL_GPL(saa7146_setgpio);EXPORT_SYMBOL_GPL(saa7146_i2c_transfer);EXPORT_SYMBOL_GPL(saa7146_i2c_adapter_prepare);EXPORT_SYMBOL_GPL(saa7146_debug);EXPORT_SYMBOL_GPL(saa7146_devices);EXPORT_SYMBOL_GPL(saa7146_devices_lock);MODULE_AUTHOR("Michael Hunold <michael@mihu.de>");MODULE_DESCRIPTION("driver for generic saa7146-based hardware");MODULE_LICENSE("GPL");

⌨️ 快捷键说明

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