aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/saa7164/saa7164-core.c
diff options
context:
space:
mode:
authorSteven Toth <stoth@kernellabs.com>2010-07-31 13:44:53 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2010-10-21 05:54:34 -0400
commit7615e434aefd95181eae099c4f019e021b024eb6 (patch)
tree22901c7326d8edfe0b8ac1208cb289fcc55241ad /drivers/media/video/saa7164/saa7164-core.c
parentadd3f580a4342b8bca7e0fb4737fe9eeaefa4319 (diff)
[media] saa7164: add various encoder message functions
Signed-off-by: Steven Toth <stoth@kernellabs.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/saa7164/saa7164-core.c')
-rw-r--r--drivers/media/video/saa7164/saa7164-core.c167
1 files changed, 142 insertions, 25 deletions
diff --git a/drivers/media/video/saa7164/saa7164-core.c b/drivers/media/video/saa7164/saa7164-core.c
index 88c36bd2bd1d..b8e56d88743f 100644
--- a/drivers/media/video/saa7164/saa7164-core.c
+++ b/drivers/media/video/saa7164/saa7164-core.c
@@ -82,6 +82,69 @@ static void saa7164_buffer_deliver(struct saa7164_buffer *buf)
82 82
83} 83}
84 84
85static irqreturn_t saa7164_irq_encoder(struct saa7164_port *port)
86{
87 struct saa7164_dev *dev = port->dev;
88 struct saa7164_buffer *buf;
89 struct saa7164_user_buffer *ubuf;
90 struct list_head *c, *n;
91 int wp, i = 0, rp;
92
93 /* Find the current write point from the hardware */
94 wp = saa7164_readl(port->bufcounter);
95 if (wp > (port->hwcfg.buffercount - 1))
96 BUG();
97
98 /* Find the previous buffer to the current write point */
99 if (wp == 0)
100 rp = 7;
101 else
102 rp = wp - 1;
103
104 /* Lookup the WP in the buffer list */
105 /* TODO: turn this into a worker thread */
106 list_for_each_safe(c, n, &port->dmaqueue.list) {
107 buf = list_entry(c, struct saa7164_buffer, list);
108 if (i++ > port->hwcfg.buffercount)
109 BUG();
110
111 if (buf->idx == rp) {
112 /* Found the buffer, deal with it */
113 dprintk(DBGLVL_IRQ, "%s() wp: %d processing: %d\n",
114 __func__, wp, rp);
115
116 /* */
117 /* find a free user buffer and clone to it */
118 if (!list_empty(&port->list_buf_free.list)) {
119
120 /* Pull the first buffer from the used list */
121 ubuf = list_first_entry(&port->list_buf_free.list,
122 struct saa7164_user_buffer, list);
123
124 if (ubuf->actual_size == buf->actual_size)
125 memcpy(ubuf->data, buf->cpu, ubuf->actual_size);
126
127 /* Requeue the buffer on the free list */
128 ubuf->pos = 0;
129
130
131// mutex_lock(&port->dmaqueue_lock);
132 list_move_tail(&ubuf->list, &port->list_buf_used.list);
133// mutex_unlock(&port->dmaqueue_lock);
134
135 /* Flag any userland waiters */
136 wake_up_interruptible(&port->wait_read);
137
138 } else
139 printk(KERN_ERR "encirq no free buffers\n");
140
141 break;
142 }
143
144 }
145 return 0;
146}
147
85static irqreturn_t saa7164_irq_ts(struct saa7164_port *port) 148static irqreturn_t saa7164_irq_ts(struct saa7164_port *port)
86{ 149{
87 struct saa7164_dev *dev = port->dev; 150 struct saa7164_dev *dev = port->dev;
@@ -123,6 +186,11 @@ static irqreturn_t saa7164_irq_ts(struct saa7164_port *port)
123static irqreturn_t saa7164_irq(int irq, void *dev_id) 186static irqreturn_t saa7164_irq(int irq, void *dev_id)
124{ 187{
125 struct saa7164_dev *dev = dev_id; 188 struct saa7164_dev *dev = dev_id;
189 struct saa7164_port *porta = &dev->ports[ SAA7164_PORT_TS1 ];
190 struct saa7164_port *portb = &dev->ports[ SAA7164_PORT_TS2 ];
191 struct saa7164_port *portc = &dev->ports[ SAA7164_PORT_ENC1 ];
192 struct saa7164_port *portd = &dev->ports[ SAA7164_PORT_ENC2 ];
193
126 u32 intid, intstat[INT_SIZE/4]; 194 u32 intid, intstat[INT_SIZE/4];
127 int i, handled = 0, bit; 195 int i, handled = 0, bit;
128 196
@@ -168,17 +236,25 @@ static irqreturn_t saa7164_irq(int irq, void *dev_id)
168 if (intid == dev->intfdesc.bInterruptId) { 236 if (intid == dev->intfdesc.bInterruptId) {
169 /* A response to an cmd/api call */ 237 /* A response to an cmd/api call */
170 schedule_work(&dev->workcmd); 238 schedule_work(&dev->workcmd);
171 } else if (intid == 239 } else if (intid == porta->hwcfg.interruptid) {
172 dev->ts1.hwcfg.interruptid) {
173 240
174 /* Transport path 1 */ 241 /* Transport path 1 */
175 saa7164_irq_ts(&dev->ts1); 242 saa7164_irq_ts(porta);
176 243
177 } else if (intid == 244 } else if (intid == portb->hwcfg.interruptid) {
178 dev->ts2.hwcfg.interruptid) {
179 245
180 /* Transport path 2 */ 246 /* Transport path 2 */
181 saa7164_irq_ts(&dev->ts2); 247 saa7164_irq_ts(portb);
248
249 } else if (intid == portc->hwcfg.interruptid) {
250
251 /* Encoder path 1 */
252 saa7164_irq_encoder(portc);
253
254 } else if (intid == portd->hwcfg.interruptid) {
255
256 /* Encoder path 1 */
257 saa7164_irq_encoder(portd);
182 258
183 } else { 259 } else {
184 /* Find the function */ 260 /* Find the function */
@@ -402,6 +478,37 @@ static int get_resources(struct saa7164_dev *dev)
402 return -EBUSY; 478 return -EBUSY;
403} 479}
404 480
481static int saa7164_port_init(struct saa7164_dev *dev, int portnr)
482{
483 struct saa7164_port *port = 0;
484
485 if ((portnr < 0) || (portnr >= SAA7164_MAX_PORTS))
486 BUG();
487
488 port = &dev->ports[ portnr ];
489
490 port->dev = dev;
491 port->nr = portnr;
492
493 if ((portnr == SAA7164_PORT_TS1) || (portnr == SAA7164_PORT_TS2))
494 port->type = SAA7164_MPEG_DVB;
495 else
496 if ((portnr == SAA7164_PORT_ENC1) || (portnr == SAA7164_PORT_ENC2))
497 port->type = SAA7164_MPEG_ENCODER;
498 else
499 BUG();
500
501 /* Init all the critical resources */
502 mutex_init(&port->dvb.lock);
503 INIT_LIST_HEAD(&port->dmaqueue.list);
504 mutex_init(&port->dmaqueue_lock);
505
506 INIT_LIST_HEAD(&port->list_buf_used.list);
507 INIT_LIST_HEAD(&port->list_buf_free.list);
508 init_waitqueue_head(&port->wait_read);
509 return 0;
510}
511
405static int saa7164_dev_setup(struct saa7164_dev *dev) 512static int saa7164_dev_setup(struct saa7164_dev *dev)
406{ 513{
407 int i; 514 int i;
@@ -443,21 +550,11 @@ static int saa7164_dev_setup(struct saa7164_dev *dev)
443 dev->i2c_bus[2].dev = dev; 550 dev->i2c_bus[2].dev = dev;
444 dev->i2c_bus[2].nr = 2; 551 dev->i2c_bus[2].nr = 2;
445 552
446 /* Transport port A Defaults / setup */ 553 /* Transport + Encoder ports 1, 2, 3, 4 - Defaults / setup */
447 dev->ts1.dev = dev; 554 saa7164_port_init(dev, SAA7164_PORT_TS1);
448 dev->ts1.nr = 0; 555 saa7164_port_init(dev, SAA7164_PORT_TS2);
449 dev->ts1.type = SAA7164_MPEG_UNDEFINED; 556 saa7164_port_init(dev, SAA7164_PORT_ENC1);
450 mutex_init(&dev->ts1.dvb.lock); 557 saa7164_port_init(dev, SAA7164_PORT_ENC2);
451 INIT_LIST_HEAD(&dev->ts1.dmaqueue.list);
452 mutex_init(&dev->ts1.dmaqueue_lock);
453
454 /* Transport port B Defaults / setup */
455 dev->ts2.dev = dev;
456 dev->ts2.nr = 1;
457 dev->ts2.type = SAA7164_MPEG_UNDEFINED;
458 mutex_init(&dev->ts2.dvb.lock);
459 INIT_LIST_HEAD(&dev->ts2.dmaqueue.list);
460 mutex_init(&dev->ts2.dmaqueue_lock);
461 558
462 if (get_resources(dev) < 0) { 559 if (get_resources(dev) < 0) {
463 printk(KERN_ERR "CORE %s No more PCIe resources for " 560 printk(KERN_ERR "CORE %s No more PCIe resources for "
@@ -631,7 +728,7 @@ static int __devinit saa7164_initdev(struct pci_dev *pci_dev,
631 728
632 /* Begin to create the video sub-systems and register funcs */ 729 /* Begin to create the video sub-systems and register funcs */
633 if (saa7164_boards[dev->board].porta == SAA7164_MPEG_DVB) { 730 if (saa7164_boards[dev->board].porta == SAA7164_MPEG_DVB) {
634 if (saa7164_dvb_register(&dev->ts1) < 0) { 731 if (saa7164_dvb_register(&dev->ports[ SAA7164_PORT_TS1 ]) < 0) {
635 printk(KERN_ERR "%s() Failed to register " 732 printk(KERN_ERR "%s() Failed to register "
636 "dvb adapters on porta\n", 733 "dvb adapters on porta\n",
637 __func__); 734 __func__);
@@ -639,13 +736,27 @@ static int __devinit saa7164_initdev(struct pci_dev *pci_dev,
639 } 736 }
640 737
641 if (saa7164_boards[dev->board].portb == SAA7164_MPEG_DVB) { 738 if (saa7164_boards[dev->board].portb == SAA7164_MPEG_DVB) {
642 if (saa7164_dvb_register(&dev->ts2) < 0) { 739 if (saa7164_dvb_register(&dev->ports[ SAA7164_PORT_TS2 ]) < 0) {
643 printk(KERN_ERR"%s() Failed to register " 740 printk(KERN_ERR"%s() Failed to register "
644 "dvb adapters on portb\n", 741 "dvb adapters on portb\n",
645 __func__); 742 __func__);
646 } 743 }
647 } 744 }
648 745
746 if (saa7164_boards[dev->board].portc == SAA7164_MPEG_ENCODER) {
747 if (saa7164_encoder_register(&dev->ports[ SAA7164_PORT_ENC1 ]) < 0) {
748 printk(KERN_ERR"%s() Failed to register "
749 "mpeg encoder\n", __func__);
750 }
751 }
752
753 if (saa7164_boards[dev->board].portd == SAA7164_MPEG_ENCODER) {
754 if (saa7164_encoder_register(&dev->ports[ SAA7164_PORT_ENC2 ]) < 0) {
755 printk(KERN_ERR"%s() Failed to register "
756 "mpeg encoder\n", __func__);
757 }
758 }
759
649 } /* != BOARD_UNKNOWN */ 760 } /* != BOARD_UNKNOWN */
650 else 761 else
651 printk(KERN_ERR "%s() Unsupported board detected, " 762 printk(KERN_ERR "%s() Unsupported board detected, "
@@ -676,10 +787,16 @@ static void __devexit saa7164_finidev(struct pci_dev *pci_dev)
676 saa7164_shutdown(dev); 787 saa7164_shutdown(dev);
677 788
678 if (saa7164_boards[dev->board].porta == SAA7164_MPEG_DVB) 789 if (saa7164_boards[dev->board].porta == SAA7164_MPEG_DVB)
679 saa7164_dvb_unregister(&dev->ts1); 790 saa7164_dvb_unregister(&dev->ports[ SAA7164_PORT_TS1 ]);
680 791
681 if (saa7164_boards[dev->board].portb == SAA7164_MPEG_DVB) 792 if (saa7164_boards[dev->board].portb == SAA7164_MPEG_DVB)
682 saa7164_dvb_unregister(&dev->ts2); 793 saa7164_dvb_unregister(&dev->ports[ SAA7164_PORT_TS2 ]);
794
795 if (saa7164_boards[dev->board].portc == SAA7164_MPEG_ENCODER)
796 saa7164_encoder_unregister(&dev->ports[ SAA7164_PORT_ENC1 ]);
797
798 if (saa7164_boards[dev->board].portd == SAA7164_MPEG_ENCODER)
799 saa7164_encoder_unregister(&dev->ports[ SAA7164_PORT_ENC2 ]);
683 800
684 saa7164_i2c_unregister(&dev->i2c_bus[0]); 801 saa7164_i2c_unregister(&dev->i2c_bus[0]);
685 saa7164_i2c_unregister(&dev->i2c_bus[1]); 802 saa7164_i2c_unregister(&dev->i2c_bus[1]);