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         saa7146_write_out_dma(dev, 3, &vdma3);
158 
159         /* write beginning of rps-program */
160         count = 0;
161 
162         /* wait for o_fid_a/b / e_fid_a/b toggle only if bit 1 is not set */
163 
164         /* we don't wait here for the first field anymore. this is different from the video
165            capture and might cause that the first buffer is only half filled (with only
166            one field). but since this is some sort of streaming data, this is not that negative.
167            but by doing this, we can use the whole engine from video-buf.c... */
168         
169 /*
170         WRITE_RPS1(CMD_PAUSE | CMD_OAN | CMD_SIG1 | e_wait);
171         WRITE_RPS1(CMD_PAUSE | CMD_OAN | CMD_SIG1 | o_wait);
172 */
173         /* set bit 1 */
174         WRITE_RPS1(CMD_WR_REG | (1 << 8) | (MC2/4));    
175         WRITE_RPS1(MASK_28 | MASK_12);
176         
177         /* turn on video-dma3 */
178         WRITE_RPS1(CMD_WR_REG_MASK | (MC1/4));          
179         WRITE_RPS1(MASK_04 | MASK_20);                  /* => mask */
180         WRITE_RPS1(MASK_04 | MASK_20);                  /* => values */
181         
182         /* wait for o_fid_a/b / e_fid_a/b toggle */
183         WRITE_RPS1(CMD_PAUSE | o_wait);
184         WRITE_RPS1(CMD_PAUSE | e_wait);
185 
186         /* generate interrupt */
187         WRITE_RPS1(CMD_INTERRUPT);                                      
188 
189         /* stop */
190         WRITE_RPS1(CMD_STOP);                                   
191 
192         /* enable rps1 irqs */
193         SAA7146_IER_ENABLE(dev, MASK_28);
194 
195         /* write the address of the rps-program */
196         saa7146_write(dev, RPS_ADDR1, dev->d_rps1.dma_handle);
197 
198         /* turn on rps */
199         saa7146_write(dev, MC1, (MASK_13 | MASK_29));   
200 }
201 
202 static int buffer_activate(struct saa7146_dev *dev,
203                            struct saa7146_buf *buf,
204                            struct saa7146_buf *next)
205 {
206         struct saa7146_vv *vv = dev->vv_data;
207         buf->vb.state = STATE_ACTIVE;
208 
209         DEB_VBI(("dev:%p, buf:%p, next:%p\n",dev,buf,next));
210         saa7146_set_vbi_capture(dev,buf,next);
211 
212         mod_timer(&vv->vbi_q.timeout, jiffies+BUFFER_TIMEOUT);
213         return 0;
214 }
215 
216 static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,enum v4l2_field field)
217 {
218         struct file *file = q->priv_data;
219         struct saa7146_fh *fh = file->private_data;
220         struct saa7146_dev *dev = fh->dev;
221         struct saa7146_buf *buf = (struct saa7146_buf *)vb;
222 
223         int err = 0;
224         int lines, llength, size;
225 
226         lines   = 16 * 2 ; /* 2 fields */
227         llength = vbi_pixel_to_capture;
228         size = lines * llength;
229 
230         DEB_VBI(("vb:%p\n",vb));
231         
232         if (0 != buf->vb.baddr  &&  buf->vb.bsize < size) {
233                 DEB_VBI(("size mismatch.\n"));
234                 return -EINVAL;
235         }
236         
237         if (buf->vb.size != size)
238                 saa7146_dma_free(dev,buf);
239 
240         if (STATE_NEEDS_INIT == buf->vb.state) {
241                 buf->vb.width  = llength;
242                 buf->vb.height = lines;
243                 buf->vb.size   = size;
244                 buf->vb.field  = field; // FIXME: check this
245 
246                 saa7146_pgtable_free(dev->pci, &buf->pt[2]);
247                 saa7146_pgtable_alloc(dev->pci, &buf->pt[2]);
248 
249                 err = videobuf_iolock(dev->pci,&buf->vb,NULL);
250                 if (err)
251                         goto oops;
252                 err = saa7146_pgtable_build_single(dev->pci, &buf->pt[2], buf->vb.dma.sglist, buf->vb.dma.sglen);
253                 if (0 != err)
254                         return err;
255         }
256         buf->vb.state = STATE_PREPARED;
257         buf->activate = buffer_activate;
258 
259         return 0;
260 
261  oops:
262         DEB_VBI(("error out.\n"));
263         saa7146_dma_free(dev,buf);
264 
265         return err;
266 }
267 
268 static int buffer_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size)
269 {
270         int llength,lines;
271         
272         lines   = 16 * 2 ; /* 2 fields */
273         llength = vbi_pixel_to_capture;
274 
275         *size = lines * llength;
276         *count = 2;
277 
278         DEB_VBI(("count:%d, size:%d\n",*count,*size));
279 
280         return 0;
281 }
282 
283 static void buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
284 {
285         struct file *file = q->priv_data;
286         struct saa7146_fh *fh = file->private_data;
287         struct saa7146_dev *dev = fh->dev;
288         struct saa7146_vv *vv = dev->vv_data;
289         struct saa7146_buf *buf = (struct saa7146_buf *)vb;
290         
291         DEB_VBI(("vb:%p\n",vb));
292         saa7146_buffer_queue(dev,&vv->vbi_q,buf);
293 }
294 
295 static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
296 {
297         struct file *file = q->priv_data;
298         struct saa7146_fh *fh   = file->private_data;
299         struct saa7146_dev *dev = fh->dev;
300         struct saa7146_buf *buf = (struct saa7146_buf *)vb;
301         
302         DEB_VBI(("vb:%p\n",vb));
303         saa7146_dma_free(dev,buf);
304 }
305 
306 static struct videobuf_queue_ops vbi_qops = {
307         .buf_setup    = buffer_setup,
308         .buf_prepare  = buffer_prepare,
309         .buf_queue    = buffer_queue,
310         .buf_release  = buffer_release,
311 };
312 
313 /* ------------------------------------------------------------------ */
314 
315 static void vbi_stop(struct saa7146_fh *fh, struct file *file)
316 {
317         struct saa7146_dev *dev = fh->dev;
318         struct saa7146_vv *vv = dev->vv_data;
319         unsigned long flags;
320         DEB_VBI(("dev:%p, fh:%p\n",dev, fh));
321         
322         spin_lock_irqsave(&dev->slock,flags);
323 
324         /* disable rps1  */
325         saa7146_write(dev, MC1, MASK_29);
326 
327         /* disable rps1 irqs */
328         SAA7146_IER_DISABLE(dev, MASK_28);
329 
330         /* shut down dma 3 transfers */
331         saa7146_write(dev, MC1, MASK_20);
332 
333         if (vv->vbi_q.curr) {
334                 saa7146_buffer_finish(dev,&vv->vbi_q,STATE_DONE);
335         }
336 
337         videobuf_queue_cancel(&fh->vbi_q);
338 
339         vv->vbi_streaming = NULL;
340 
341         del_timer(&vv->vbi_q.timeout);
342         del_timer(&fh->vbi_read_timeout);
343 
344         spin_unlock_irqrestore(&dev->slock, flags);
345 }
346 
347 static void vbi_read_timeout(unsigned long data)
348 {
349         struct file *file = (struct file*)data;
350         struct saa7146_fh *fh = file->private_data;
351         struct saa7146_dev *dev = fh->dev;
352         
353         DEB_VBI(("dev:%p, fh:%p\n",dev, fh));
354 
355         vbi_stop(fh, file);
356 }
357 
358 static void vbi_init(struct saa7146_dev *dev, struct saa7146_vv *vv)
359 {
360         DEB_VBI(("dev:%p\n",dev));
361 
362         INIT_LIST_HEAD(&vv->vbi_q.queue);
363 
364         init_timer(&vv->vbi_q.timeout);
365         vv->vbi_q.timeout.function = saa7146_buffer_timeout;
366         vv->vbi_q.timeout.data     = (unsigned long)(&vv->vbi_q);
367         vv->vbi_q.dev              = dev;
368 
369         init_waitqueue_head(&vv->vbi_wq);
370 }
371 
372 static int vbi_open(struct saa7146_dev *dev, struct file *file)
373 {
374         struct saa7146_fh *fh = (struct saa7146_fh *)file->private_data;
375         
376         u32 arbtr_ctrl  = saa7146_read(dev, PCI_BT_V1);
377         int ret = 0;
378         
379         DEB_VBI(("dev:%p, fh:%p\n",dev,fh));
380 
381         ret = saa7146_res_get(fh, RESOURCE_DMA3_BRS);
382         if (0 == ret) {
383                 DEB_S(("cannot get vbi RESOURCE_DMA3_BRS resource\n"));
384                 return -EBUSY;
385         }
386 
387         /* adjust arbitrition control for video dma 3 */
388         arbtr_ctrl &= ~0x1f0000;
389         arbtr_ctrl |=  0x1d0000;
390         saa7146_write(dev, PCI_BT_V1, arbtr_ctrl);
391         saa7146_write(dev, MC2, (MASK_04|MASK_20));             
392         
393         memset(&fh->vbi_fmt,0,sizeof(fh->vbi_fmt));
394 
395         fh->vbi_fmt.sampling_rate       = 27000000;
396         fh->vbi_fmt.offset              = 248; /* todo */ 
397         fh->vbi_fmt.samples_per_line    = vbi_pixel_to_capture;
398         fh->vbi_fmt.sample_format       = V4L2_PIX_FMT_GREY;
399 
400         /* fixme: this only works for PAL */
401         fh->vbi_fmt.start[0] = 5;
402         fh->vbi_fmt.count[0] = 16;
403         fh->vbi_fmt.start[1] = 312;
404         fh->vbi_fmt.count[1] = 16;
405 
406         videobuf_queue_init(&fh->vbi_q, &vbi_qops,
407                             dev->pci, &dev->slock,
408                             V4L2_BUF_TYPE_VBI_CAPTURE,
409                             V4L2_FIELD_SEQ_TB, // FIXME: does this really work?
410                             sizeof(struct saa7146_buf),
411                             file);
412         init_MUTEX(&fh->vbi_q.lock);
413 
414         init_timer(&fh->vbi_read_timeout);
415         fh->vbi_read_timeout.function = vbi_read_timeout;
416         fh->vbi_read_timeout.data = (unsigned long)file;
417 
418         /* initialize the brs */
419         if ( 0 != (SAA7146_USE_PORT_B_FOR_VBI & dev->ext_vv_data->flags)) {
420                 saa7146_write(dev, BRS_CTRL, MASK_30|MASK_29 | (7 << 19));
421         } else {
422                 saa7146_write(dev, BRS_CTRL, 0x00000001);
423 
424                 if (0 != (ret = vbi_workaround(dev))) {
425                         DEB_VBI(("vbi workaround failed!\n"));
426                         /* return ret;*/
427                 }
428         }
429 
430         /* upload brs register */
431         saa7146_write(dev, MC2, (MASK_08|MASK_24));             
432         return 0;
433 }
434 
435 static void vbi_close(struct saa7146_dev *dev, struct file *file)
436 {
437         struct saa7146_fh *fh = (struct saa7146_fh *)file->private_data;
438         struct saa7146_vv *vv = dev->vv_data;
439         DEB_VBI(("dev:%p, fh:%p\n",dev,fh));
440 
441         if( fh == vv->vbi_streaming ) {
442                 vbi_stop(fh, file);
443         }
444         saa7146_res_free(fh, RESOURCE_DMA3_BRS);
445 }
446 
447 static void vbi_irq_done(struct saa7146_dev *dev, unsigned long status)
448 {
449         struct saa7146_vv *vv = dev->vv_data;
450         spin_lock(&dev->slock);
451 
452         if (vv->vbi_q.curr) {
453                 DEB_VBI(("dev:%p, curr:%p\n",dev,vv->vbi_q.curr));
454                 /* this must be += 2, one count for each field */
455                 vv->vbi_fieldcount+=2;
456                 vv->vbi_q.curr->vb.field_count = vv->vbi_fieldcount;
457                 saa7146_buffer_finish(dev,&vv->vbi_q,STATE_DONE);
458         } else {
459                 DEB_VBI(("dev:%p\n",dev));
460         }
461         saa7146_buffer_next(dev,&vv->vbi_q,1);
462 
463         spin_unlock(&dev->slock);
464 }
465 
466 static ssize_t vbi_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
467 {
468         struct saa7146_fh *fh = file->private_data;
469         struct saa7146_dev *dev = fh->dev;
470         struct saa7146_vv *vv = dev->vv_data;
471         ssize_t ret = 0;
472 
473         DEB_VBI(("dev:%p, fh:%p\n",dev,fh));
474         
475         if( NULL == vv->vbi_streaming ) {
476                 // fixme: check if dma3 is available
477                 // fixme: activate vbi engine here if necessary. (really?)
478                 vv->vbi_streaming = fh;
479         }
480 
481         if( fh != vv->vbi_streaming ) {
482                 DEB_VBI(("open %p is already using vbi capture.",vv->vbi_streaming));
483                 return -EBUSY;
484         }
485 
486         mod_timer(&fh->vbi_read_timeout, jiffies+BUFFER_TIMEOUT);
487         ret = videobuf_read_stream(&fh->vbi_q, data, count, ppos, 1,
488                                    file->f_flags & O_NONBLOCK);
489 /*
490         printk("BASE_ODD3:      0x%08x\n", saa7146_read(dev, BASE_ODD3));
491         printk("BASE_EVEN3:     0x%08x\n", saa7146_read(dev, BASE_EVEN3));
492         printk("PROT_ADDR3:     0x%08x\n", saa7146_read(dev, PROT_ADDR3));
493         printk("PITCH3:         0x%08x\n", saa7146_read(dev, PITCH3));
494         printk("BASE_PAGE3:     0x%08x\n", saa7146_read(dev, BASE_PAGE3));
495         printk("NUM_LINE_BYTE3: 0x%08x\n", saa7146_read(dev, NUM_LINE_BYTE3));
496         printk("BRS_CTRL:       0x%08x\n", saa7146_read(dev, BRS_CTRL));
497 */
498         return ret;
499 }
500 
501 struct saa7146_use_ops saa7146_vbi_uops = {
502         .init           = vbi_init,
503         .open           = vbi_open,
504         .release        = vbi_close,
505         .irq_done       = vbi_irq_done,
506         .read           = vbi_read,
507 };
508 
  This page was automatically generated by the LXR engine.