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

📄 cx23885-core.c

📁 trident tm5600的linux驱动
💻 C
📖 第 1 页 / 共 4 页
字号:
	}	buf->vb.state = VIDEOBUF_PREPARED;	return 0; fail:	cx23885_free_buffer(q, buf);	return rc;}void cx23885_buf_queue(struct cx23885_tsport *port, struct cx23885_buffer *buf){	struct cx23885_buffer    *prev;	struct cx23885_dev *dev = port->dev;	struct cx23885_dmaqueue  *cx88q = &port->mpegq;	/* add jump to stopper */	buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);	buf->risc.jmp[1] = cpu_to_le32(cx88q->stopper.dma);	buf->risc.jmp[2] = cpu_to_le32(0); /* bits 63-32 */	if (list_empty(&cx88q->active)) {		dprintk(1, "queue is empty - first active\n");		list_add_tail(&buf->vb.queue, &cx88q->active);		cx23885_start_dma(port, cx88q, buf);		buf->vb.state = VIDEOBUF_ACTIVE;		buf->count    = cx88q->count++;		mod_timer(&cx88q->timeout, jiffies + BUFFER_TIMEOUT);		dprintk(1, "[%p/%d] %s - first active\n",			buf, buf->vb.i, __func__);	} else {		dprintk(1, "queue is not empty - append to active\n");		prev = list_entry(cx88q->active.prev, struct cx23885_buffer,				  vb.queue);		list_add_tail(&buf->vb.queue, &cx88q->active);		buf->vb.state = VIDEOBUF_ACTIVE;		buf->count    = cx88q->count++;		prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);		prev->risc.jmp[2] = cpu_to_le32(0); /* 64 bit bits 63-32 */		dprintk(1, "[%p/%d] %s - append to active\n",			 buf, buf->vb.i, __func__);	}}/* ----------------------------------------------------------- */static void do_cancel_buffers(struct cx23885_tsport *port, char *reason,			      int restart){	struct cx23885_dev *dev = port->dev;	struct cx23885_dmaqueue *q = &port->mpegq;	struct cx23885_buffer *buf;	unsigned long flags;	spin_lock_irqsave(&port->slock, flags);	while (!list_empty(&q->active)) {		buf = list_entry(q->active.next, struct cx23885_buffer,				 vb.queue);		list_del(&buf->vb.queue);		buf->vb.state = VIDEOBUF_ERROR;		wake_up(&buf->vb.done);		dprintk(1, "[%p/%d] %s - dma=0x%08lx\n",			buf, buf->vb.i, reason, (unsigned long)buf->risc.dma);	}	if (restart) {		dprintk(1, "restarting queue\n");		cx23885_restart_queue(port, q);	}	spin_unlock_irqrestore(&port->slock, flags);}void cx23885_cancel_buffers(struct cx23885_tsport *port){	struct cx23885_dev *dev = port->dev;	struct cx23885_dmaqueue *q = &port->mpegq;	dprintk(1, "%s()\n", __func__);	del_timer_sync(&q->timeout);	cx23885_stop_dma(port);	do_cancel_buffers(port, "cancel", 0);}static void cx23885_timeout(unsigned long data){	struct cx23885_tsport *port = (struct cx23885_tsport *)data;	struct cx23885_dev *dev = port->dev;	dprintk(1, "%s()\n", __func__);	if (debug > 5)		cx23885_sram_channel_dump(dev,			&dev->sram_channels[port->sram_chno]);	cx23885_stop_dma(port);	do_cancel_buffers(port, "timeout", 1);}int cx23885_irq_417(struct cx23885_dev *dev, u32 status){	/* FIXME: port1 assumption here. */	struct cx23885_tsport *port = &dev->ts1;	int count = 0;	int handled = 0;	if (status == 0)		return handled;	count = cx_read(port->reg_gpcnt);	dprintk(7, "status: 0x%08x  mask: 0x%08x count: 0x%x\n",		status, cx_read(port->reg_ts_int_msk), count);	if ((status & VID_B_MSK_BAD_PKT)         ||		(status & VID_B_MSK_OPC_ERR)     ||		(status & VID_B_MSK_VBI_OPC_ERR) ||		(status & VID_B_MSK_SYNC)        ||		(status & VID_B_MSK_VBI_SYNC)    ||		(status & VID_B_MSK_OF)          ||		(status & VID_B_MSK_VBI_OF)) {		printk(KERN_ERR "%s: V4L mpeg risc op code error, status "			"= 0x%x\n", dev->name, status);		if (status & VID_B_MSK_BAD_PKT)			dprintk(1, "        VID_B_MSK_BAD_PKT\n");		if (status & VID_B_MSK_OPC_ERR)			dprintk(1, "        VID_B_MSK_OPC_ERR\n");		if (status & VID_B_MSK_VBI_OPC_ERR)			dprintk(1, "        VID_B_MSK_VBI_OPC_ERR\n");		if (status & VID_B_MSK_SYNC)			dprintk(1, "        VID_B_MSK_SYNC\n");		if (status & VID_B_MSK_VBI_SYNC)			dprintk(1, "        VID_B_MSK_VBI_SYNC\n");		if (status & VID_B_MSK_OF)			dprintk(1, "        VID_B_MSK_OF\n");		if (status & VID_B_MSK_VBI_OF)			dprintk(1, "        VID_B_MSK_VBI_OF\n");		cx_clear(port->reg_dma_ctl, port->dma_ctl_val);		cx23885_sram_channel_dump(dev,			&dev->sram_channels[port->sram_chno]);		cx23885_417_check_encoder(dev);	} else if (status & VID_B_MSK_RISCI1) {		dprintk(7, "        VID_B_MSK_RISCI1\n");		spin_lock(&port->slock);		cx23885_wakeup(port, &port->mpegq, count);		spin_unlock(&port->slock);	} else if (status & VID_B_MSK_RISCI2) {		dprintk(7, "        VID_B_MSK_RISCI2\n");		spin_lock(&port->slock);		cx23885_restart_queue(port, &port->mpegq);		spin_unlock(&port->slock);	}	if (status) {		cx_write(port->reg_ts_int_stat, status);		handled = 1;	}	return handled;}static int cx23885_irq_ts(struct cx23885_tsport *port, u32 status){	struct cx23885_dev *dev = port->dev;	int handled = 0;	u32 count;	if ((status & VID_BC_MSK_OPC_ERR) ||		(status & VID_BC_MSK_BAD_PKT) ||		(status & VID_BC_MSK_SYNC) ||		(status & VID_BC_MSK_OF)) {		if (status & VID_BC_MSK_OPC_ERR)			dprintk(7, " (VID_BC_MSK_OPC_ERR 0x%08x)\n",				VID_BC_MSK_OPC_ERR);		if (status & VID_BC_MSK_BAD_PKT)			dprintk(7, " (VID_BC_MSK_BAD_PKT 0x%08x)\n",				VID_BC_MSK_BAD_PKT);		if (status & VID_BC_MSK_SYNC)			dprintk(7, " (VID_BC_MSK_SYNC    0x%08x)\n",				VID_BC_MSK_SYNC);		if (status & VID_BC_MSK_OF)			dprintk(7, " (VID_BC_MSK_OF      0x%08x)\n",				VID_BC_MSK_OF);		printk(KERN_ERR "%s: mpeg risc op code error\n", dev->name);		cx_clear(port->reg_dma_ctl, port->dma_ctl_val);		cx23885_sram_channel_dump(dev,			&dev->sram_channels[port->sram_chno]);	} else if (status & VID_BC_MSK_RISCI1) {		dprintk(7, " (RISCI1            0x%08x)\n", VID_BC_MSK_RISCI1);		spin_lock(&port->slock);		count = cx_read(port->reg_gpcnt);		cx23885_wakeup(port, &port->mpegq, count);		spin_unlock(&port->slock);	} else if (status & VID_BC_MSK_RISCI2) {		dprintk(7, " (RISCI2            0x%08x)\n", VID_BC_MSK_RISCI2);		spin_lock(&port->slock);		cx23885_restart_queue(port, &port->mpegq);		spin_unlock(&port->slock);	}	if (status) {		cx_write(port->reg_ts_int_stat, status);		handled = 1;	}	return handled;}#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19)static irqreturn_t cx23885_irq(int irq, void *dev_id, struct pt_regs *regs)#elsestatic irqreturn_t cx23885_irq(int irq, void *dev_id)#endif{	struct cx23885_dev *dev = dev_id;	struct cx23885_tsport *ts1 = &dev->ts1;	struct cx23885_tsport *ts2 = &dev->ts2;	u32 pci_status, pci_mask;	u32 vida_status, vida_mask;	u32 ts1_status, ts1_mask;	u32 ts2_status, ts2_mask;	int vida_count = 0, ts1_count = 0, ts2_count = 0, handled = 0;	pci_status = cx_read(PCI_INT_STAT);	pci_mask = cx_read(PCI_INT_MSK);	vida_status = cx_read(VID_A_INT_STAT);	vida_mask = cx_read(VID_A_INT_MSK);	ts1_status = cx_read(VID_B_INT_STAT);	ts1_mask = cx_read(VID_B_INT_MSK);	ts2_status = cx_read(VID_C_INT_STAT);	ts2_mask = cx_read(VID_C_INT_MSK);	if ((pci_status == 0) && (ts2_status == 0) && (ts1_status == 0))		goto out;	vida_count = cx_read(VID_A_GPCNT);	ts1_count = cx_read(ts1->reg_gpcnt);	ts2_count = cx_read(ts2->reg_gpcnt);	dprintk(7, "pci_status: 0x%08x  pci_mask: 0x%08x\n",		pci_status, pci_mask);	dprintk(7, "vida_status: 0x%08x vida_mask: 0x%08x count: 0x%x\n",		vida_status, vida_mask, vida_count);	dprintk(7, "ts1_status: 0x%08x  ts1_mask: 0x%08x count: 0x%x\n",		ts1_status, ts1_mask, ts1_count);	dprintk(7, "ts2_status: 0x%08x  ts2_mask: 0x%08x count: 0x%x\n",		ts2_status, ts2_mask, ts2_count);	if ((pci_status & PCI_MSK_RISC_RD) ||	    (pci_status & PCI_MSK_RISC_WR) ||	    (pci_status & PCI_MSK_AL_RD) ||	    (pci_status & PCI_MSK_AL_WR) ||	    (pci_status & PCI_MSK_APB_DMA) ||	    (pci_status & PCI_MSK_VID_C) ||	    (pci_status & PCI_MSK_VID_B) ||	    (pci_status & PCI_MSK_VID_A) ||	    (pci_status & PCI_MSK_AUD_INT) ||	    (pci_status & PCI_MSK_AUD_EXT)) {		if (pci_status & PCI_MSK_RISC_RD)			dprintk(7, " (PCI_MSK_RISC_RD   0x%08x)\n",				PCI_MSK_RISC_RD);		if (pci_status & PCI_MSK_RISC_WR)			dprintk(7, " (PCI_MSK_RISC_WR   0x%08x)\n",				PCI_MSK_RISC_WR);		if (pci_status & PCI_MSK_AL_RD)			dprintk(7, " (PCI_MSK_AL_RD     0x%08x)\n",				PCI_MSK_AL_RD);		if (pci_status & PCI_MSK_AL_WR)			dprintk(7, " (PCI_MSK_AL_WR     0x%08x)\n",				PCI_MSK_AL_WR);		if (pci_status & PCI_MSK_APB_DMA)			dprintk(7, " (PCI_MSK_APB_DMA   0x%08x)\n",				PCI_MSK_APB_DMA);		if (pci_status & PCI_MSK_VID_C)			dprintk(7, " (PCI_MSK_VID_C     0x%08x)\n",				PCI_MSK_VID_C);		if (pci_status & PCI_MSK_VID_B)			dprintk(7, " (PCI_MSK_VID_B     0x%08x)\n",				PCI_MSK_VID_B);		if (pci_status & PCI_MSK_VID_A)			dprintk(7, " (PCI_MSK_VID_A     0x%08x)\n",				PCI_MSK_VID_A);		if (pci_status & PCI_MSK_AUD_INT)			dprintk(7, " (PCI_MSK_AUD_INT   0x%08x)\n",				PCI_MSK_AUD_INT);		if (pci_status & PCI_MSK_AUD_EXT)			dprintk(7, " (PCI_MSK_AUD_EXT   0x%08x)\n",				PCI_MSK_AUD_EXT);	}	if (ts1_status) {		if (cx23885_boards[dev->board].portb == CX23885_MPEG_DVB)			handled += cx23885_irq_ts(ts1, ts1_status);		else		if (cx23885_boards[dev->board].portb == CX23885_MPEG_ENCODER)			handled += cx23885_irq_417(dev, ts1_status);	}	if (ts2_status) {		if (cx23885_boards[dev->board].portc == CX23885_MPEG_DVB)			handled += cx23885_irq_ts(ts2, ts2_status);		else		if (cx23885_boards[dev->board].portc == CX23885_MPEG_ENCODER)			handled += cx23885_irq_417(dev, ts2_status);	}	if (vida_status)		handled += cx23885_video_irq(dev, vida_status);	if (handled)		cx_write(PCI_INT_STAT, pci_status);out:	return IRQ_RETVAL(handled);}static int __devinit cx23885_initdev(struct pci_dev *pci_dev,				     const struct pci_device_id *pci_id){	struct cx23885_dev *dev;	int err;	dev = kzalloc(sizeof(*dev), GFP_KERNEL);	if (NULL == dev)		return -ENOMEM;	/* pci init */	dev->pci = pci_dev;	if (pci_enable_device(pci_dev)) {		err = -EIO;		goto fail_free;	}	if (cx23885_dev_setup(dev) < 0) {		err = -EINVAL;		goto fail_free;	}	/* print pci info */	pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &dev->pci_rev);	pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER,  &dev->pci_lat);	printk(KERN_INFO "%s/0: found at %s, rev: %d, irq: %d, "	       "latency: %d, mmio: 0x%llx\n", dev->name,	       pci_name(pci_dev), dev->pci_rev, pci_dev->irq,	       dev->pci_lat,		(unsigned long long)pci_resource_start(pci_dev, 0));	pci_set_master(pci_dev);	if (!pci_dma_supported(pci_dev, 0xffffffff)) {		printk("%s/0: Oops: no 32bit PCI DMA ???\n", dev->name);		err = -EIO;		goto fail_irq;	}	err = request_irq(pci_dev->irq, cx23885_irq,			  IRQF_SHARED | IRQF_DISABLED, dev->name, dev);	if (err < 0) {		printk(KERN_ERR "%s: can't get IRQ %d\n",		       dev->name, pci_dev->irq);		goto fail_irq;	}	pci_set_drvdata(pci_dev, dev);	return 0;fail_irq:	cx23885_dev_unregister(dev);fail_free:	kfree(dev);	return err;}static void __devexit cx23885_finidev(struct pci_dev *pci_dev){	struct cx23885_dev *dev = pci_get_drvdata(pci_dev);	cx23885_shutdown(dev);	pci_disable_device(pci_dev);	/* unregister stuff */	free_irq(pci_dev->irq, dev);	pci_set_drvdata(pci_dev, NULL);	mutex_lock(&devlist);	list_del(&dev->devlist);	mutex_unlock(&devlist);	cx23885_dev_unregister(dev);	kfree(dev);}static struct pci_device_id cx23885_pci_tbl[] = {	{		/* CX23885 */		.vendor       = 0x14f1,		.device       = 0x8852,		.subvendor    = PCI_ANY_ID,		.subdevice    = PCI_ANY_ID,	}, {		/* CX23887 Rev 2 */		.vendor       = 0x14f1,		.device       = 0x8880,		.subvendor    = PCI_ANY_ID,		.subdevice    = PCI_ANY_ID,	}, {		/* --- end of list --- */	}};MODULE_DEVICE_TABLE(pci, cx23885_pci_tbl);static struct pci_driver cx23885_pci_driver = {	.name     = "cx23885",	.id_table = cx23885_pci_tbl,	.probe    = cx23885_initdev,	.remove   = __devexit_p(cx23885_finidev),	/* TODO */	.suspend  = NULL,	.resume   = NULL,};static int cx23885_init(void){	printk(KERN_INFO "cx23885 driver version %d.%d.%d loaded\n",	       (CX23885_VERSION_CODE >> 16) & 0xff,	       (CX23885_VERSION_CODE >>  8) & 0xff,	       CX23885_VERSION_CODE & 0xff);#ifdef SNAPSHOT	printk(KERN_INFO "cx23885: snapshot date %04d-%02d-%02d\n",	       SNAPSHOT/10000, (SNAPSHOT/100)%100, SNAPSHOT%100);#endif	return pci_register_driver(&cx23885_pci_driver);}static void cx23885_fini(void){	pci_unregister_driver(&cx23885_pci_driver);}module_init(cx23885_init);module_exit(cx23885_fini);/* ----------------------------------------------------------- */

⌨️ 快捷键说明

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