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

📄 budget-ci.c

📁 优龙2410linux2.6.8内核源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
static int ciintf_write_cam_control(struct dvb_ca_en50221* ca, int slot, u8 address, u8 value) {	struct budget_ci* budget_ci = (struct budget_ci*) ca->data;	if (slot != 0) return -EINVAL;	return budget_debiwrite(budget_ci, DEBICICAM, DEBIADDR_IO | (address & 3), 1, value);}static int ciintf_slot_reset(struct dvb_ca_en50221* ca, int slot) {	struct budget_ci* budget_ci = (struct budget_ci*) ca->data;	struct saa7146_dev *saa = budget_ci->budget.dev;	if (slot != 0) return -EINVAL;	// trigger on RISING edge during reset so we know when READY is re-asserted	saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQHI);	budget_ci->slot_status = SLOTSTATUS_RESET;	budget_debiwrite(budget_ci, DEBICICTL, DEBIADDR_CICONTROL, 1, 0);	dvb_delay(1);	budget_debiwrite(budget_ci, DEBICICTL, DEBIADDR_CICONTROL, 1, CICONTROL_RESET);	saa7146_setgpio(saa, 1, SAA7146_GPIO_OUTHI);   	ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTB);	return 0;}static int ciintf_slot_shutdown(struct dvb_ca_en50221* ca, int slot) {   	struct budget_ci* budget_ci = (struct budget_ci*) ca->data;	struct saa7146_dev *saa = budget_ci->budget.dev;	if (slot != 0) return -EINVAL;	saa7146_setgpio(saa, 1, SAA7146_GPIO_OUTHI);	ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTB);	return 0;}static int ciintf_slot_ts_enable(struct dvb_ca_en50221* ca, int slot) {	struct budget_ci* budget_ci = (struct budget_ci*) ca->data;	struct saa7146_dev *saa = budget_ci->budget.dev;	int tmp;	if (slot != 0) return -EINVAL;	saa7146_setgpio(saa, 1, SAA7146_GPIO_OUTLO);	tmp = budget_debiread(budget_ci, DEBICICTL, DEBIADDR_CICONTROL, 1);	budget_debiwrite(budget_ci, DEBICICTL, DEBIADDR_CICONTROL, 1, tmp | CICONTROL_ENABLETS);   	ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTA);	return 0;}static void ciintf_interrupt (unsigned long data){	struct budget_ci *budget_ci = (struct budget_ci*) data;	struct saa7146_dev *saa = budget_ci->budget.dev;	unsigned int flags;	// ensure we don't get spurious IRQs during initialisation	if (!budget_ci->budget.ci_present) return;	flags = budget_debiread(budget_ci, DEBICICTL, DEBIADDR_CICONTROL, 1);	// always set the GPIO mode back to "normal", in case the card is	// yanked at an inopportune moment	saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQLO);	if (flags & CICONTROL_CAMDETECT) {		if (budget_ci->slot_status & SLOTSTATUS_NONE) {			// CAM insertion IRQ			budget_ci->slot_status = SLOTSTATUS_PRESENT;			dvb_ca_en50221_camchange_irq(&budget_ci->ca, 0, DVB_CA_EN50221_CAMCHANGE_INSERTED);		} else if (budget_ci->slot_status & SLOTSTATUS_RESET) {			// CAM ready (reset completed)			budget_ci->slot_status = SLOTSTATUS_READY;			dvb_ca_en50221_camready_irq(&budget_ci->ca, 0);		} else if (budget_ci->slot_status & SLOTSTATUS_READY) {			// FR/DA IRQ			dvb_ca_en50221_frda_irq(&budget_ci->ca, 0);		}	} else {		if (budget_ci->slot_status & SLOTSTATUS_OCCUPIED) {			budget_ci->slot_status = SLOTSTATUS_NONE;			dvb_ca_en50221_camchange_irq(&budget_ci->ca, 0, DVB_CA_EN50221_CAMCHANGE_REMOVED);		}	}}static int ciintf_init(struct budget_ci* budget_ci){	struct saa7146_dev *saa = budget_ci->budget.dev;	int flags;	int result;	memset(&budget_ci->ca, 0, sizeof(struct dvb_ca_en50221));	// enable DEBI pins	saa7146_write(saa, MC1, saa7146_read(saa, MC1) | (0x800 << 16) | 0x800);	// test if it is there	if ((budget_debiread(budget_ci, DEBICICTL, DEBIADDR_CIVERSION, 1) & 0xa0) != 0xa0) {		result = -ENODEV;		goto error;	}	// determine whether a CAM is present or not	flags = budget_debiread(budget_ci, DEBICICTL, DEBIADDR_CICONTROL, 1);	budget_ci->slot_status = SLOTSTATUS_NONE;	if (flags & CICONTROL_CAMDETECT) budget_ci->slot_status = SLOTSTATUS_PRESENT;	// register CI interface	budget_ci->ca.read_attribute_mem = ciintf_read_attribute_mem;	budget_ci->ca.write_attribute_mem = ciintf_write_attribute_mem;	budget_ci->ca.read_cam_control = ciintf_read_cam_control;	budget_ci->ca.write_cam_control = ciintf_write_cam_control;	budget_ci->ca.slot_reset = ciintf_slot_reset;	budget_ci->ca.slot_shutdown = ciintf_slot_shutdown;	budget_ci->ca.slot_ts_enable = ciintf_slot_ts_enable;	budget_ci->ca.data = budget_ci;	if ((result = dvb_ca_en50221_init(budget_ci->budget.dvb_adapter,					  &budget_ci->ca,					  DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE |					  DVB_CA_EN50221_FLAG_IRQ_FR |					  DVB_CA_EN50221_FLAG_IRQ_DA,				  1)) != 0) {		printk("budget_ci: CI interface detected, but initialisation failed.\n");		goto error;	}	// Setup CI slot IRQ	tasklet_init (&budget_ci->ciintf_irq_tasklet, ciintf_interrupt, (unsigned long) budget_ci);	saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQLO);	saa7146_write(saa, IER, saa7146_read(saa, IER) | MASK_03);	budget_debiwrite(budget_ci, DEBICICTL, DEBIADDR_CICONTROL, 1, CICONTROL_RESET);	// success!	printk("budget_ci: CI interface initialised\n");	budget_ci->budget.ci_present = 1;	// forge a fake CI IRQ so the CAM state is setup correctly	flags = DVB_CA_EN50221_CAMCHANGE_REMOVED;	if (budget_ci->slot_status != SLOTSTATUS_NONE) flags = DVB_CA_EN50221_CAMCHANGE_INSERTED;	dvb_ca_en50221_camchange_irq(&budget_ci->ca, 0, flags);	return 0;error:	saa7146_write(saa, MC1, saa7146_read(saa, MC1) | (0x800 << 16));	return result;}static void ciintf_deinit(struct budget_ci* budget_ci){	struct saa7146_dev *saa = budget_ci->budget.dev;	// disable CI interrupts	saa7146_write(saa, IER, saa7146_read(saa, IER) & ~MASK_03);	saa7146_setgpio(saa, 0, SAA7146_GPIO_INPUT);	tasklet_kill(&budget_ci->ciintf_irq_tasklet);	budget_debiwrite(budget_ci, DEBICICTL, DEBIADDR_CICONTROL, 1, 0);	dvb_delay(1);	budget_debiwrite(budget_ci, DEBICICTL, DEBIADDR_CICONTROL, 1, CICONTROL_RESET);	// disable TS data stream to CI interface	saa7146_setgpio(saa, 1, SAA7146_GPIO_INPUT);	// release the CA device	dvb_ca_en50221_release(&budget_ci->ca);	// disable DEBI pins	saa7146_write(saa, MC1, saa7146_read(saa, MC1) | (0x800 << 16));}static void budget_ci_irq (struct saa7146_dev *dev, u32 *isr){        struct budget_ci *budget_ci = (struct budget_ci*) dev->ext_priv;        DEB_EE(("dev: %p, budget_ci: %p\n", dev, budget_ci));        if (*isr & MASK_06)                tasklet_schedule (&budget_ci->msp430_irq_tasklet);        if (*isr & MASK_10)		ttpci_budget_irq10_handler (dev, isr);	if ((*isr & MASK_03) && (budget_ci->budget.ci_present))		tasklet_schedule (&budget_ci->ciintf_irq_tasklet);}static int budget_ci_attach (struct saa7146_dev* dev,		      struct saa7146_pci_extension_data *info){	struct budget_ci *budget_ci;	int err;	if (!(budget_ci = kmalloc (sizeof(struct budget_ci), GFP_KERNEL)))		return -ENOMEM;	DEB_EE(("budget_ci: %p\n", budget_ci));	spin_lock_init(&budget_ci->debilock);	budget_ci->budget.ci_present = 0;	if ((err = ttpci_budget_init (&budget_ci->budget, dev, info))) {		kfree (budget_ci);		return err;	}	dev->ext_priv = budget_ci;	tasklet_init (&budget_ci->msp430_irq_tasklet, msp430_ir_interrupt,		      (unsigned long) budget_ci);	msp430_ir_init (budget_ci);	// UNCOMMENT TO TEST CI INTERFACE//	ciintf_init(budget_ci);	return 0;}static int budget_ci_detach (struct saa7146_dev* dev){	struct budget_ci *budget_ci = (struct budget_ci*) dev->ext_priv;	struct saa7146_dev *saa = budget_ci->budget.dev;	int err;	if (budget_ci->budget.ci_present) ciintf_deinit(budget_ci);	err = ttpci_budget_deinit (&budget_ci->budget);	tasklet_kill (&budget_ci->msp430_irq_tasklet);	msp430_ir_deinit (budget_ci);	// disable frontend and CI interface	saa7146_setgpio(saa, 2, SAA7146_GPIO_INPUT);	kfree (budget_ci);	return err;}static struct saa7146_extension budget_extension; MAKE_BUDGET_INFO(ttbci,	"TT-Budget/WinTV-NOVA-CI PCI",	BUDGET_TT_HW_DISEQC);MAKE_BUDGET_INFO(ttbt2,	"TT-Budget/WinTV-NOVA-T  PCI",	BUDGET_TT);static struct pci_device_id pci_tbl[] = {	MAKE_EXTENSION_PCI(ttbci, 0x13c2, 0x100c),	MAKE_EXTENSION_PCI(ttbci, 0x13c2, 0x100f),	MAKE_EXTENSION_PCI(ttbt2,  0x13c2, 0x1011),	{		.vendor    = 0,	}};MODULE_DEVICE_TABLE(pci, pci_tbl);static struct saa7146_extension budget_extension = {	.name		= "budget_ci dvb\0",	.flags	 	= 0,	.module		= THIS_MODULE,	.pci_tbl	= &pci_tbl[0],	.attach		= budget_ci_attach,	.detach		= budget_ci_detach,	.irq_mask	= MASK_03 | MASK_06 | MASK_10,	.irq_func	= budget_ci_irq,};	static int __init budget_ci_init(void) {	return saa7146_register_extension(&budget_extension);}static void __exit budget_ci_exit(void){	DEB_EE((".\n"));	saa7146_unregister_extension(&budget_extension); }module_init(budget_ci_init);module_exit(budget_ci_exit);MODULE_LICENSE("GPL");MODULE_AUTHOR("Michael Hunold, Jack Thomasson, Andrew de Quincey, others");MODULE_DESCRIPTION("driver for the SAA7146 based so-called "		   "budget PCI DVB cards w/ CI-module produced by "		   "Siemens, Technotrend, Hauppauge");

⌨️ 快捷键说明

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