Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]
  1 #include <media/saa7146_vv.h>
  2 
  3 static int vbi_pixel_to_capture = 720 * 2;
  4 
  5 static int vbi_workaround(struct saa7146_dev *dev)
  6 {
  7         struct saa7146_vv *vv = dev->vv_data;
  8 
  9         u32          *cpu;
 10         dma_addr_t   dma_addr;
 11 
 12         int count = 0;
 13         int i;
 14 
 15         DECLARE_WAITQUEUE(wait, current);
 16 
 17         DEB_VBI(("dev:%p\n",dev));
 18 
 19         /* once again, a bug in the saa7146: the brs acquisition
 20            is buggy and especially the BXO-counter does not work
 21            as specified. there is this workaround, but please
 22            don't let me explain it. ;-) */
 23 
 24         cpu = pci_alloc_consistent(dev->pci, 4096, &dma_addr);
 25         if (NULL == cpu)
 26                 return -ENOMEM;
 27 
 28         /* setup some basic programming, just for the workaround */
 29         saa7146_write(dev, BASE_EVEN3,  dma_addr);
 30         saa7146_write(dev, BASE_ODD3,   dma_addr+vbi_pixel_to_capture);
 31         saa7146_write(dev, PROT_ADDR3,  dma_addr+4096);
 32         saa7146_write(dev, PITCH3,      vbi_pixel_to_capture);
 33         saa7146_write(dev, BASE_PAGE3,  0x0);
 34         saa7146_write(dev, NUM_LINE_BYTE3, (2<<16)|((vbi_pixel_to_capture)<<0));
 35         saa7146_write(dev, MC2, MASK_04|MASK_20);
 36 
 37         /* load brs-control register */
 38         WRITE_RPS1(CMD_WR_REG | (1 << 8) | (BRS_CTRL/4));
 39         /* BXO = 1h, BRS to outbound */
 40         WRITE_RPS1(0xc000008c);
 41         /* wait for vbi_a or vbi_b*/
 42         if ( 0 != (SAA7146_USE_PORT_B_FOR_VBI & dev->ext_vv_data->flags)) {
 43                 DEB_D(("...using port b\n"));
 44                 WRITE_RPS1(CMD_PAUSE | CMD_OAN | CMD_SIG1 | CMD_E_FID_B);
 45                 WRITE_RPS1(CMD_PAUSE | CMD_OAN | CMD_SIG1 | CMD_O_FID_B);
 46 /*
 47                 WRITE_RPS1(CMD_PAUSE | MASK_09);
 48 */
 49         } else {
 50                 DEB_D(("...using port a\n"));
 51                 WRITE_RPS1(CMD_PAUSE | MASK_10);
 52         }
 53         /* upload brs */
 54         WRITE_RPS1(CMD_UPLOAD | MASK_08);
 55         /* load brs-control register */
 56         WRITE_RPS1(CMD_WR_REG | (1 << 8) | (BRS_CTRL/4));
 57         /* BYO = 1, BXO = NQBIL (=1728 for PAL, for NTSC this is 858*2) - NumByte3 (=1440) = 288 */
 58         WRITE_RPS1(((1728-(vbi_pixel_to_capture)) << 7) | MASK_19);
 59         /* wait for brs_done */
 60         WRITE_RPS1(CMD_PAUSE | MASK_08);
 61         /* upload brs */
 62         WRITE_RPS1(CMD_UPLOAD | MASK_08);
 63         /* load video-dma3 NumLines3 and NumBytes3 */
 64         WRITE_RPS1(CMD_WR_REG | (1 << 8) | (NUM_LINE_BYTE3/4));
 65         /* dev->vbi_count*2 lines, 720 pixel (= 1440 Bytes) */
 66         WRITE_RPS1((2 << 16) | (vbi_pixel_to_capture));
 67         /* load brs-control register */
 68         WRITE_RPS1(CMD_WR_REG | (1 << 8) | (BRS_CTRL/4));
 69         /* Set BRS right: note: this is an experimental value for BXO (=> PAL!) */
 70         WRITE_RPS1((540 << 7) | (5 << 19));  // 5 == vbi_start
 71         /* wait for brs_done */
 72         WRITE_RPS1(CMD_PAUSE | MASK_08);
 73         /* upload brs and video-dma3*/
 74         WRITE_RPS1(CMD_UPLOAD | MASK_08 | MASK_04);
 75         /* load mc2 register: enable dma3 */
 76         WRITE_RPS1(CMD_WR_REG | (1 << 8) | (MC1/4));
 77         WRITE_RPS1(MASK_20 | MASK_04);
 78         /* generate interrupt */
 79         WRITE_RPS1(CMD_INTERRUPT);
 80         /* stop rps1 */
 81         WRITE_RPS1(CMD_STOP);
 82 
 83         /* we have to do the workaround twice to be sure that
 84            everything is ok */
 85         for(i = 0; i < 2; i++) {
 86 
 87                 /* indicate to the irq handler that we do the workaround */
 88                 saa7146_write(dev, MC2, MASK_31|MASK_15);
 89 
 90                 saa7146_write(dev, NUM_LINE_BYTE3, (1<<16)|(2<<0));
 91                 saa7146_write(dev, MC2, MASK_04|MASK_20);
 92 
 93                 /* enable rps1 irqs */
 94                 SAA7146_IER_ENABLE(dev,MASK_28);
 95 
 96                 /* prepare to wait to be woken up by the irq-handler */
 97                 add_wait_queue(&vv->vbi_wq, &wait);
 98                 current->state = TASK_INTERRUPTIBLE;
 99 
100                 /* start rps1 to enable workaround */
101                 saa7146_write(dev, RPS_ADDR1, dev->d_rps1.dma_handle);
102                 saa7146_write(dev, MC1, (MASK_13 | MASK_29));
103 
104                 schedule();
105 
106                 DEB_VBI(("brs bug workaround %d/1.\n",i));
107 
108                 remove_wait_queue(&vv->vbi_wq, &wait);
109                 current->state = TASK_RUNNING;
110 
111                 /* disable rps1 irqs */
112                 SAA7146_IER_DISABLE(dev,MASK_28);
113 
114                 /* stop video-dma3 */
115                 saa7146_write(dev, MC1, MASK_20);
116 
117                 if(signal_pending(current)) {
118 
119                         DEB_VBI(("aborted (rps:0x%08x).\n",saa7146_read(dev,RPS_ADDR1)));
120 
121                         /* stop rps1 for sure */
122                         saa7146_write(dev, MC1, MASK_29);
123 
124                         pci_free_consistent(dev->pci, 4096, cpu, dma_addr);
125                         return -EINTR;
126                 }
127         }
128 
129         pci_free_consistent(dev->pci, 4096, cpu, dma_addr);
130         return 0;
131 }
132 
133 static void saa7146_set_vbi_capture(struct saa7146_dev *dev, struct saa7146_buf *buf, struct saa7146_buf *next)
134 {
135         struct saa7146_vv *vv = dev->vv_data;
136 
137         struct saa7146_video_dma vdma3;
138 
139         int count = 0;
140         unsigned long e_wait = vv->current_hps_sync == SAA7146_HPS_SYNC_PORT_A ? CMD_E_FID_A : CMD_E_FID_B;
141         unsigned long o_wait = vv->current_hps_sync == SAA7146_HPS_SYNC_PORT_A ? CMD_O_FID_A : CMD_O_FID_B;
142 
143 /*
144         vdma3.base_even = 0xc8000000+2560*70;
145         vdma3.base_odd  = 0xc8000000;
146         vdma3.prot_addr = 0xc8000000+2560*164;
147         vdma3.pitch     = 2560;
148         vdma3.base_page = 0;
149         vdma3.num_line_byte = (64<<16)|((vbi_pixel_to_capture)<<0); // set above!
150 */
151         vdma3.base_even = buf->pt[2].offset;
152         vdma3.base_odd  = buf->pt[2].offset + 16 * vbi_pixel_to_capture;
153         vdma3.prot_addr = buf->pt[2].offset + 16 * 2 * vbi_pixel_to_capture;
154         vdma3.pitch     = vbi_pixel_to_capture;
155         vdma3.base_page = buf->pt[2].dma | ME1;
156         vdma3.num_line_byte = (16 << 16) | vbi_pixel_to_capture;
157 
158         saa7146_write_out_dma(dev, 3, &vdma3);
159 
160         /* write beginning of rps-program */
161         count = 0;
162 
163         /* wait for o_fid_a/b / e_fid_a/b toggle only if bit 1 is not set */
164 
165         /* we don't wait here for the first field anymore. this is different from the video
166            capture and might cause that the first buffer is only half filled (with only
167            one field). but since this is some sort of streaming data, this is not that negative.
168            but by doing this, we can use the whole engine from videobuf-dma-sg.c... */
169 
170 /*
171         WRITE_RPS1(CMD_PAUSE | CMD_OAN | CMD_SIG1 | e_wait);
172         WRITE_RPS1(CMD_PAUSE | CMD_OAN | CMD_SIG1 | o_wait);
173 */
174         /* set bit 1 */
175         WRITE_RPS1(CMD_WR_REG | (1 << 8) | (MC2/4));
176         WRITE_RPS1(MASK_28 | MASK_12);
177 
178         /* turn on video-dma3 */
179         WRITE_RPS1(CMD_WR_REG_MASK | (MC1/4));
180         WRITE_RPS1(MASK_04 | MASK_20);                  /* => mask */
181         WRITE_RPS1(MASK_04 | MASK_20);                  /* => values */
182 
183         /* wait for o_fid_a/b / e_fid_a/b toggle */
184         WRITE_RPS1(CMD_PAUSE | o_wait);
185         WRITE_RPS1(CMD_PAUSE | e_wait);
186 
187         /* generate interrupt */
188         WRITE_RPS1(CMD_INTERRUPT);
189 
190         /* stop */
191         WRITE_RPS1(CMD_STOP);
192 
193         /* enable rps1 irqs */
194         SAA7146_IER_ENABLE(dev, MASK_28);
195 
196         /* write the address of the rps-program */
197         saa7146_write(dev, RPS_ADDR1, dev->d_rps1.dma_handle);
198 
199         /* turn on rps */
200         saa7146_write(dev, MC1, (MASK_13 | MASK_29));
201 }
202 
203 static int buffer_activate(struct saa7146_dev *dev,
204                            struct saa7146_buf *buf,
205                            struct saa7146_buf *next)
206 {
207         struct saa7146_vv *vv = dev->vv_data;
208         buf->vb.state = VIDEOBUF_ACTIVE;
209 
210         DEB_VBI(("dev:%p, buf:%p, next:%p\n",dev,buf,next));
211         saa7146_set_vbi_capture(dev,buf,next);
212 
213         mod_timer(&vv->vbi_q.timeout, jiffies+BUFFER_TIMEOUT);
214         return 0;
215 }
216 
217 static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,enum v4l2_field field)
218 {
219         struct file *file = q->priv_data;
220         struct saa7146_fh *fh = file->private_data;
221         struct saa7146_dev *dev = fh->dev;
222         struct saa7146_buf *buf = (struct saa7146_buf *)vb;
223 
224         int err = 0;
225         int lines, llength, size;
226 
227         lines   = 16 * 2 ; /* 2 fields */
228         llength = vbi_pixel_to_capture;
229         size = lines * llength;
230 
231         DEB_VBI(("vb:%p\n",vb));
232 
233         if (0 != buf->vb.baddr  &&  buf->vb.bsize < size) {
234                 DEB_VBI(("size mismatch.\n"));
235                 return -EINVAL;
236         }
237 
238         if (buf->vb.size != size)
239                 saa7146_dma_free(dev,q,buf);
240 
241         if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
242                 struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
243 
244                 buf->vb.width  = llength;
245                 buf->vb.height = lines;
246                 buf->vb.size   = size;
247                 buf->vb.field  = field; // FIXME: check this
248 
249                 saa7146_pgtable_free(dev->pci, &buf->pt[2]);
250                 saa7146_pgtable_alloc(dev->pci, &buf->pt[2]);
251 
252                 err = videobuf_iolock(q,&buf->vb, NULL);
253                 if (err)
254                         goto oops;
255                 err = saa7146_pgtable_build_single(dev->pci, &buf->pt[2],
256                                                  dma->sglist, dma->sglen);
257                 if (0 != err)
258                         return err;
259         }
260         buf->vb.state = VIDEOBUF_PREPARED;
261         buf->activate = buffer_activate;
262 
263         return 0;
264 
265  oops:
266         DEB_VBI(("error out.\n"));
267         saa7146_dma_free(dev,q,buf);
268 
269         return err;
270 }
271 
272 static int buffer_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size)
273 {
274         int llength,lines;
275 
276         lines   = 16 * 2 ; /* 2 fields */
277         llength = vbi_pixel_to_capture;
278 
279         *size = lines * llength;
280         *count = 2;
281 
282         DEB_VBI(("count:%d, size:%d\n",*count,*size));
283 
284         return 0;
285 }
286 
287 static void buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
288 {
289         struct file *file = q->priv_data;
290         struct saa7146_fh *fh = file->private_data;
291         struct saa7146_dev *dev = fh->dev;
292         struct saa7146_vv *vv = dev->vv_data;
293         struct saa7146_buf *buf = (struct saa7146_buf *)vb;
294 
295         DEB_VBI(("vb:%p\n",vb));
296         saa7146_buffer_queue(dev,&vv->vbi_q,buf);
297 }
298 
299 static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
300 {
301         struct file *file = q->priv_data;
302         struct saa7146_fh *fh   = file->private_data;
303         struct saa7146_dev *dev = fh->dev;
304         struct saa7146_buf *buf = (struct saa7146_buf *)vb;
305 
306         DEB_VBI(("vb:%p\n",vb));
307         saa7146_dma_free(dev,q,buf);
308 }
309 
310 static struct videobuf_queue_ops vbi_qops = {
311         .buf_setup    = buffer_setup,
312         .buf_prepare  = buffer_prepare,
313         .buf_queue    = buffer_queue,
314         .buf_release  = buffer_release,
315 };
316 
317 /* ------------------------------------------------------------------ */
318 
319 static void vbi_stop(struct saa7146_fh *fh, struct file *file)
320 {
321         struct saa7146_dev *dev = fh->dev;
322         struct saa7146_vv *vv = dev->vv_data;
323         unsigned long flags;
324         DEB_VBI(("dev:%p, fh:%p\n",dev, fh));
325 
326         spin_lock_irqsave(&dev->slock,flags);
327 
328         /* disable rps1  */
329         saa7146_write(dev, MC1, MASK_29);
330 
331         /* disable rps1 irqs */
332         SAA7146_IER_DISABLE(dev, MASK_28);
333 
334         /* shut down dma 3 transfers */
335         saa7146_write(dev, MC1, MASK_20);
336 
337         if (vv->vbi_q.curr) {
338                 saa7146_buffer_finish(dev,&vv->vbi_q,VIDEOBUF_DONE);
339         }
340 
341         videobuf_queue_cancel(&fh->vbi_q);
342 
343         vv->vbi_streaming = NULL;
344 
345         del_timer(&vv->vbi_q.timeout);
346         del_timer(&fh->vbi_read_timeout);
347 
348         spin_unlock_irqrestore(&dev->slock, flags);
349 }
350 
351 static void vbi_read_timeout(unsigned long data)
352 {
353         struct file *file = (struct file*)data;
354         struct saa7146_fh *fh = file->private_data;
355         struct saa7146_dev *dev = fh->dev;
356 
357         DEB_VBI(("dev:%p, fh:%p\n",dev, fh));
358 
359         vbi_stop(fh, file);
360 }
361 
362 static void vbi_init(struct saa7146_dev *dev, struct saa7146_vv *vv)
363 {
364         DEB_VBI(("dev:%p\n",dev));
365 
366         INIT_LIST_HEAD(&vv->vbi_q.queue);
367 
368         init_timer(&vv->vbi_q.timeout);
369         vv->vbi_q.timeout.function = saa7146_buffer_timeout;
370         vv->vbi_q.timeout.data     = (unsigned long)(&vv->vbi_q);
371         vv->vbi_q.dev              = dev;
372 
373         init_waitqueue_head(&vv->vbi_wq);
374 }
375 
376 static int vbi_open(struct saa7146_dev *dev, struct file *file)
377 {
378         struct saa7146_fh *fh = (struct saa7146_fh *)file->private_data;
379 
380         u32 arbtr_ctrl  = saa7146_read(dev, PCI_BT_V1);
381         int ret = 0;
382 
383         DEB_VBI(("dev:%p, fh:%p\n",dev,fh));
384 
385         ret = saa7146_res_get(fh, RESOURCE_DMA3_BRS);
386         if (0 == ret) {
387                 DEB_S(("cannot get vbi RESOURCE_DMA3_BRS resource\n"));
388                 return -EBUSY;
389         }
390 
391         /* adjust arbitrition control for video dma 3 */
392         arbtr_ctrl &= ~0x1f0000;
393         arbtr_ctrl |=  0x1d0000;
394         saa7146_write(dev, PCI_BT_V1, arbtr_ctrl);
395         saa7146_write(dev, MC2, (MASK_04|MASK_20));
396 
397         memset(&fh->vbi_fmt,0,sizeof(fh->vbi_fmt));
398 
399         fh->vbi_fmt.sampling_rate       = 27000000;
400         fh->vbi_fmt.offset              = 248; /* todo */
401         fh->vbi_fmt.samples_per_line    = vbi_pixel_to_capture;
402         fh->vbi_fmt.sample_format       = V4L2_PIX_FMT_GREY;
403 
404         /* fixme: this only works for PAL */
405         fh->vbi_fmt.start[0] = 5;
406         fh->vbi_fmt.count[0] = 16;
407         fh->vbi_fmt.start[1] = 312;
408         fh->vbi_fmt.count[1] = 16;
409 
410         videobuf_queue_pci_init(&fh->vbi_q, &vbi_qops,
411                             dev->pci, &dev->slock,
412                             V4L2_BUF_TYPE_VBI_CAPTURE,
413                             V4L2_FIELD_SEQ_TB, // FIXME: does this really work?
414                             sizeof(struct saa7146_buf),
415                             file);
416 
417         init_timer(&fh->vbi_read_timeout);
418         fh->vbi_read_timeout.function = vbi_read_timeout;
419         fh->vbi_read_timeout.data = (unsigned long)file;
420 
421         /* initialize the brs */
422         if ( 0 != (SAA7146_USE_PORT_B_FOR_VBI & dev->ext_vv_data->flags)) {
423                 saa7146_write(dev, BRS_CTRL, MASK_30|MASK_29 | (7 << 19));
424         } else {
425                 saa7146_write(dev, BRS_CTRL, 0x00000001);
426 
427                 if (0 != (ret = vbi_workaround(dev))) {
428                         DEB_VBI(("vbi workaround failed!\n"));
429                         /* return ret;*/
430                 }
431         }
432 
433         /* upload brs register */
434         saa7146_write(dev, MC2, (MASK_08|MASK_24));
435         return 0;
436 }
437 
438 static void vbi_close(struct saa7146_dev *dev, struct file *file)
439 {
440         struct saa7146_fh *fh = (struct saa7146_fh *)file->private_data;
441         struct saa7146_vv *vv = dev->vv_data;
442         DEB_VBI(("dev:%p, fh:%p\n",dev,fh));
443 
444         if( fh == vv->vbi_streaming ) {
445                 vbi_stop(fh, file);
446         }
447         saa7146_res_free(fh, RESOURCE_DMA3_BRS);
448 }
449 
450 static void vbi_irq_done(struct saa7146_dev *dev, unsigned long status)
451 {
452         struct saa7146_vv *vv = dev->vv_data;
453         spin_lock(&dev->slock);
454 
455         if (vv->vbi_q.curr) {
456                 DEB_VBI(("dev:%p, curr:%p\n",dev,vv->vbi_q.curr));
457                 /* this must be += 2, one count for each field */
458                 vv->vbi_fieldcount+=2;
459                 vv->vbi_q.curr->vb.field_count = vv->vbi_fieldcount;
460                 saa7146_buffer_finish(dev,&vv->vbi_q,VIDEOBUF_DONE);
461         } else {
462                 DEB_VBI(("dev:%p\n",dev));
463         }
464         saa7146_buffer_next(dev,&vv->vbi_q,1);
465 
466         spin_unlock(&dev->slock);
467 }
468 
469 static ssize_t vbi_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
470 {
471         struct saa7146_fh *fh = file->private_data;
472         struct saa7146_dev *dev = fh->dev;
473         struct saa7146_vv *vv = dev->vv_data;
474         ssize_t ret = 0;
475 
476         DEB_VBI(("dev:%p, fh:%p\n",dev,fh));
477 
478         if( NULL == vv->vbi_streaming ) {
479                 // fixme: check if dma3 is available
480                 // fixme: activate vbi engine here if necessary. (really?)
481                 vv->vbi_streaming = fh;
482         }
483 
484         if( fh != vv->vbi_streaming ) {
485                 DEB_VBI(("open %p is already using vbi capture.",vv->vbi_streaming));
486                 return -EBUSY;
487         }
488 
489         mod_timer(&fh->vbi_read_timeout, jiffies+BUFFER_TIMEOUT);
490         ret = videobuf_read_stream(&fh->vbi_q, data, count, ppos, 1,
491                                    file->f_flags & O_NONBLOCK);
492 /*
493         printk("BASE_ODD3:      0x%08x\n", saa7146_read(dev, BASE_ODD3));
494         printk("BASE_EVEN3:     0x%08x\n", saa7146_read(dev, BASE_EVEN3));
495         printk("PROT_ADDR3:     0x%08x\n", saa7146_read(dev, PROT_ADDR3));
496         printk("PITCH3:         0x%08x\n", saa7146_read(dev, PITCH3));
497         printk("BASE_PAGE3:     0x%08x\n", saa7146_read(dev, BASE_PAGE3));
498         printk("NUM_LINE_BYTE3: 0x%08x\n", saa7146_read(dev, NUM_LINE_BYTE3));
499         printk("BRS_CTRL:       0x%08x\n", saa7146_read(dev, BRS_CTRL));
500 */
501         return ret;
502 }
503 
504 struct saa7146_use_ops saa7146_vbi_uops = {
505         .init           = vbi_init,
506         .open           = vbi_open,
507         .release        = vbi_close,
508         .irq_done       = vbi_irq_done,
509         .read           = vbi_read,
510 };
511 
  This page was automatically generated by the LXR engine.