aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/cx88/cx88-mpeg.c
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@brturbo.com.br>2005-06-24 01:05:03 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-06-24 03:06:39 -0400
commitb45009b0288a96a3458f4f8e93cb776678d41875 (patch)
treec912e8d3dcc625fe92cdd1bac97bab7539fce4d7 /drivers/media/video/cx88/cx88-mpeg.c
parent2d03e289ea4b13d78ce55f1ea0b0d45b8f1b34c3 (diff)
[PATCH] v4l: CX88 cards update
This patch adds support for various CX88 cards and allows specifying card addresses. Signed-off-by: Mauro Carvalho Chehab <mchehab@brturbo.com.br> Signed-off-by: Michael Krufky <mkrufky@m1k.net> Signed-off-by: cybercide@f2s.com <cybercide@f2s.com> Signed-off-by: Catalin Climov <catalin@climov.com> Signed-off-by: Nickolay V Shmyrev <nshmyrev@yandex.ru> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/media/video/cx88/cx88-mpeg.c')
-rw-r--r--drivers/media/video/cx88/cx88-mpeg.c52
1 files changed, 42 insertions, 10 deletions
diff --git a/drivers/media/video/cx88/cx88-mpeg.c b/drivers/media/video/cx88/cx88-mpeg.c
index 07aae1899e17..9ade2ae91e9b 100644
--- a/drivers/media/video/cx88/cx88-mpeg.c
+++ b/drivers/media/video/cx88/cx88-mpeg.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: cx88-mpeg.c,v 1.25 2005/03/07 14:18:00 kraxel Exp $ 2 * $Id: cx88-mpeg.c,v 1.26 2005/06/03 13:31:51 mchehab Exp $
3 * 3 *
4 * Support for the mpeg transport stream transfers 4 * Support for the mpeg transport stream transfers
5 * PCI function #2 of the cx2388x. 5 * PCI function #2 of the cx2388x.
@@ -55,7 +55,7 @@ static int cx8802_start_dma(struct cx8802_dev *dev,
55{ 55{
56 struct cx88_core *core = dev->core; 56 struct cx88_core *core = dev->core;
57 57
58 dprintk(1, "cx8802_start_mpegport_dma %d\n", buf->vb.width); 58 dprintk(0, "cx8802_start_dma %d\n", buf->vb.width);
59 59
60 /* setup fifo + format */ 60 /* setup fifo + format */
61 cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH28], 61 cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH28],
@@ -100,18 +100,21 @@ static int cx8802_start_dma(struct cx8802_dev *dev,
100 q->count = 1; 100 q->count = 1;
101 101
102 /* enable irqs */ 102 /* enable irqs */
103 dprintk( 0, "setting the interrupt mask\n" );
103 cx_set(MO_PCI_INTMSK, core->pci_irqmask | 0x04); 104 cx_set(MO_PCI_INTMSK, core->pci_irqmask | 0x04);
104 cx_write(MO_TS_INTMSK, 0x1f0011); 105 cx_set(MO_TS_INTMSK, 0x1f0011);
106 //cx_write(MO_TS_INTMSK, 0x0f0011);
105 107
106 /* start dma */ 108 /* start dma */
107 cx_write(MO_DEV_CNTRL2, (1<<5)); /* FIXME: s/write/set/ ??? */ 109 cx_set(MO_DEV_CNTRL2, (1<<5));
108 cx_write(MO_TS_DMACNTRL, 0x11); 110 cx_set(MO_TS_DMACNTRL, 0x11);
109 return 0; 111 return 0;
110} 112}
111 113
112static int cx8802_stop_dma(struct cx8802_dev *dev) 114static int cx8802_stop_dma(struct cx8802_dev *dev)
113{ 115{
114 struct cx88_core *core = dev->core; 116 struct cx88_core *core = dev->core;
117 dprintk( 0, "cx8802_stop_dma\n" );
115 118
116 /* stop dma */ 119 /* stop dma */
117 cx_clear(MO_TS_DMACNTRL, 0x11); 120 cx_clear(MO_TS_DMACNTRL, 0x11);
@@ -131,8 +134,12 @@ static int cx8802_restart_queue(struct cx8802_dev *dev,
131 struct cx88_buffer *buf; 134 struct cx88_buffer *buf;
132 struct list_head *item; 135 struct list_head *item;
133 136
137 dprintk( 0, "cx8802_restart_queue\n" );
134 if (list_empty(&q->active)) 138 if (list_empty(&q->active))
139 {
140 dprintk( 0, "cx8802_restart_queue: queue is empty\n" );
135 return 0; 141 return 0;
142 }
136 143
137 buf = list_entry(q->active.next, struct cx88_buffer, vb.queue); 144 buf = list_entry(q->active.next, struct cx88_buffer, vb.queue);
138 dprintk(2,"restart_queue [%p/%d]: restart dma\n", 145 dprintk(2,"restart_queue [%p/%d]: restart dma\n",
@@ -182,27 +189,32 @@ void cx8802_buf_queue(struct cx8802_dev *dev, struct cx88_buffer *buf)
182 struct cx88_buffer *prev; 189 struct cx88_buffer *prev;
183 struct cx88_dmaqueue *q = &dev->mpegq; 190 struct cx88_dmaqueue *q = &dev->mpegq;
184 191
192 dprintk( 1, "cx8802_buf_queue\n" );
185 /* add jump to stopper */ 193 /* add jump to stopper */
186 buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC); 194 buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
187 buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma); 195 buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma);
188 196
189 if (list_empty(&q->active)) { 197 if (list_empty(&q->active)) {
198 dprintk( 0, "queue is empty - first active\n" );
190 list_add_tail(&buf->vb.queue,&q->active); 199 list_add_tail(&buf->vb.queue,&q->active);
191 cx8802_start_dma(dev, q, buf); 200 cx8802_start_dma(dev, q, buf);
192 buf->vb.state = STATE_ACTIVE; 201 buf->vb.state = STATE_ACTIVE;
193 buf->count = q->count++; 202 buf->count = q->count++;
194 mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT); 203 mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
195 dprintk(2,"[%p/%d] %s - first active\n", 204 dprintk(0,"[%p/%d] %s - first active\n",
196 buf, buf->vb.i, __FUNCTION__); 205 buf, buf->vb.i, __FUNCTION__);
206 //udelay(100);
197 207
198 } else { 208 } else {
209 dprintk( 1, "queue is not empty - append to active\n" );
199 prev = list_entry(q->active.prev, struct cx88_buffer, vb.queue); 210 prev = list_entry(q->active.prev, struct cx88_buffer, vb.queue);
200 list_add_tail(&buf->vb.queue,&q->active); 211 list_add_tail(&buf->vb.queue,&q->active);
201 buf->vb.state = STATE_ACTIVE; 212 buf->vb.state = STATE_ACTIVE;
202 buf->count = q->count++; 213 buf->count = q->count++;
203 prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma); 214 prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
204 dprintk(2,"[%p/%d] %s - append to active\n", 215 dprintk( 1, "[%p/%d] %s - append to active\n",
205 buf, buf->vb.i, __FUNCTION__); 216 buf, buf->vb.i, __FUNCTION__);
217 //udelay(100);
206 } 218 }
207} 219}
208 220
@@ -224,7 +236,10 @@ static void do_cancel_buffers(struct cx8802_dev *dev, char *reason, int restart)
224 buf, buf->vb.i, reason, (unsigned long)buf->risc.dma); 236 buf, buf->vb.i, reason, (unsigned long)buf->risc.dma);
225 } 237 }
226 if (restart) 238 if (restart)
239 {
240 dprintk(0, "restarting queue\n" );
227 cx8802_restart_queue(dev,q); 241 cx8802_restart_queue(dev,q);
242 }
228 spin_unlock_irqrestore(&dev->slock,flags); 243 spin_unlock_irqrestore(&dev->slock,flags);
229} 244}
230 245
@@ -232,6 +247,7 @@ void cx8802_cancel_buffers(struct cx8802_dev *dev)
232{ 247{
233 struct cx88_dmaqueue *q = &dev->mpegq; 248 struct cx88_dmaqueue *q = &dev->mpegq;
234 249
250 dprintk( 1, "cx8802_cancel_buffers" );
235 del_timer_sync(&q->timeout); 251 del_timer_sync(&q->timeout);
236 cx8802_stop_dma(dev); 252 cx8802_stop_dma(dev);
237 do_cancel_buffers(dev,"cancel",0); 253 do_cancel_buffers(dev,"cancel",0);
@@ -241,7 +257,7 @@ static void cx8802_timeout(unsigned long data)
241{ 257{
242 struct cx8802_dev *dev = (struct cx8802_dev*)data; 258 struct cx8802_dev *dev = (struct cx8802_dev*)data;
243 259
244 dprintk(1, "%s\n",__FUNCTION__); 260 dprintk(0, "%s\n",__FUNCTION__);
245 261
246 if (debug) 262 if (debug)
247 cx88_sram_channel_dump(dev->core, &cx88_sram_channels[SRAM_CH28]); 263 cx88_sram_channel_dump(dev->core, &cx88_sram_channels[SRAM_CH28]);
@@ -254,12 +270,17 @@ static void cx8802_mpeg_irq(struct cx8802_dev *dev)
254 struct cx88_core *core = dev->core; 270 struct cx88_core *core = dev->core;
255 u32 status, mask, count; 271 u32 status, mask, count;
256 272
273 dprintk( 1, "cx8802_mpeg_irq\n" );
257 status = cx_read(MO_TS_INTSTAT); 274 status = cx_read(MO_TS_INTSTAT);
258 mask = cx_read(MO_TS_INTMSK); 275 mask = cx_read(MO_TS_INTMSK);
259 if (0 == (status & mask)) 276 if (0 == (status & mask))
260 return; 277 return;
261 278
262 cx_write(MO_TS_INTSTAT, status); 279 cx_write(MO_TS_INTSTAT, status);
280#if 0
281 cx88_print_irqbits(core->name, "irq mpeg ",
282 cx88_mpeg_irqs, status, mask);
283#endif
263 if (debug || (status & mask & ~0xff)) 284 if (debug || (status & mask & ~0xff))
264 cx88_print_irqbits(core->name, "irq mpeg ", 285 cx88_print_irqbits(core->name, "irq mpeg ",
265 cx88_mpeg_irqs, status, mask); 286 cx88_mpeg_irqs, status, mask);
@@ -273,6 +294,7 @@ static void cx8802_mpeg_irq(struct cx8802_dev *dev)
273 294
274 /* risc1 y */ 295 /* risc1 y */
275 if (status & 0x01) { 296 if (status & 0x01) {
297 dprintk( 1, "wake up\n" );
276 spin_lock(&dev->slock); 298 spin_lock(&dev->slock);
277 count = cx_read(MO_TS_GPCNT); 299 count = cx_read(MO_TS_GPCNT);
278 cx88_wakeup(dev->core, &dev->mpegq, count); 300 cx88_wakeup(dev->core, &dev->mpegq, count);
@@ -288,6 +310,7 @@ static void cx8802_mpeg_irq(struct cx8802_dev *dev)
288 310
289 /* other general errors */ 311 /* other general errors */
290 if (status & 0x1f0100) { 312 if (status & 0x1f0100) {
313 dprintk( 0, "general errors: 0x%08x\n", status & 0x1f0100 );
291 spin_lock(&dev->slock); 314 spin_lock(&dev->slock);
292 cx8802_stop_dma(dev); 315 cx8802_stop_dma(dev);
293 cx8802_restart_queue(dev,&dev->mpegq); 316 cx8802_restart_queue(dev,&dev->mpegq);
@@ -295,6 +318,8 @@ static void cx8802_mpeg_irq(struct cx8802_dev *dev)
295 } 318 }
296} 319}
297 320
321#define MAX_IRQ_LOOP 10
322
298static irqreturn_t cx8802_irq(int irq, void *dev_id, struct pt_regs *regs) 323static irqreturn_t cx8802_irq(int irq, void *dev_id, struct pt_regs *regs)
299{ 324{
300 struct cx8802_dev *dev = dev_id; 325 struct cx8802_dev *dev = dev_id;
@@ -302,10 +327,13 @@ static irqreturn_t cx8802_irq(int irq, void *dev_id, struct pt_regs *regs)
302 u32 status; 327 u32 status;
303 int loop, handled = 0; 328 int loop, handled = 0;
304 329
305 for (loop = 0; loop < 10; loop++) { 330 for (loop = 0; loop < MAX_IRQ_LOOP; loop++) {
306 status = cx_read(MO_PCI_INTSTAT) & (core->pci_irqmask | 0x04); 331 status = cx_read(MO_PCI_INTSTAT) & (core->pci_irqmask | 0x04);
307 if (0 == status) 332 if (0 == status)
308 goto out; 333 goto out;
334 dprintk( 1, "cx8802_irq\n" );
335 dprintk( 1, " loop: %d/%d\n", loop, MAX_IRQ_LOOP );
336 dprintk( 1, " status: %d\n", status );
309 handled = 1; 337 handled = 1;
310 cx_write(MO_PCI_INTSTAT, status); 338 cx_write(MO_PCI_INTSTAT, status);
311 339
@@ -314,7 +342,8 @@ static irqreturn_t cx8802_irq(int irq, void *dev_id, struct pt_regs *regs)
314 if (status & 0x04) 342 if (status & 0x04)
315 cx8802_mpeg_irq(dev); 343 cx8802_mpeg_irq(dev);
316 }; 344 };
317 if (10 == loop) { 345 if (MAX_IRQ_LOOP == loop) {
346 dprintk( 0, "clearing mask\n" );
318 printk(KERN_WARNING "%s/0: irq loop -- clearing mask\n", 347 printk(KERN_WARNING "%s/0: irq loop -- clearing mask\n",
319 core->name); 348 core->name);
320 cx_write(MO_PCI_INTMSK,0); 349 cx_write(MO_PCI_INTMSK,0);
@@ -378,6 +407,7 @@ int cx8802_init_common(struct cx8802_dev *dev)
378 407
379void cx8802_fini_common(struct cx8802_dev *dev) 408void cx8802_fini_common(struct cx8802_dev *dev)
380{ 409{
410 dprintk( 2, "cx8802_fini_common\n" );
381 cx8802_stop_dma(dev); 411 cx8802_stop_dma(dev);
382 pci_disable_device(dev->pci); 412 pci_disable_device(dev->pci);
383 413
@@ -399,6 +429,7 @@ int cx8802_suspend_common(struct pci_dev *pci_dev, pm_message_t state)
399 /* stop mpeg dma */ 429 /* stop mpeg dma */
400 spin_lock(&dev->slock); 430 spin_lock(&dev->slock);
401 if (!list_empty(&dev->mpegq.active)) { 431 if (!list_empty(&dev->mpegq.active)) {
432 dprintk( 2, "suspend\n" );
402 printk("%s: suspend mpeg\n", core->name); 433 printk("%s: suspend mpeg\n", core->name);
403 cx8802_stop_dma(dev); 434 cx8802_stop_dma(dev);
404 del_timer(&dev->mpegq.timeout); 435 del_timer(&dev->mpegq.timeout);
@@ -463,4 +494,5 @@ EXPORT_SYMBOL(cx8802_resume_common);
463 * Local variables: 494 * Local variables:
464 * c-basic-offset: 8 495 * c-basic-offset: 8
465 * End: 496 * End:
497 * kate: eol "unix"; indent-width 3; remove-trailing-space on; replace-trailing-space-save on; tab-width 8; replace-tabs off; space-indent off; mixed-indent off
466 */ 498 */