saa7146_fops.c revision 03b1930efd3c2320b1dcba76c8af15f7e454919d
1#include <media/saa7146_vv.h> 2 3/****************************************************************************/ 4/* resource management functions, shamelessly stolen from saa7134 driver */ 5 6int saa7146_res_get(struct saa7146_fh *fh, unsigned int bit) 7{ 8 struct saa7146_dev *dev = fh->dev; 9 struct saa7146_vv *vv = dev->vv_data; 10 11 if (fh->resources & bit) { 12 DEB_D(("already allocated! want: 0x%02x, cur:0x%02x\n",bit,vv->resources)); 13 /* have it already allocated */ 14 return 1; 15 } 16 17 /* is it free? */ 18 mutex_lock(&dev->lock); 19 if (vv->resources & bit) { 20 DEB_D(("locked! vv->resources:0x%02x, we want:0x%02x\n",vv->resources,bit)); 21 /* no, someone else uses it */ 22 mutex_unlock(&dev->lock); 23 return 0; 24 } 25 /* it's free, grab it */ 26 fh->resources |= bit; 27 vv->resources |= bit; 28 DEB_D(("res: get 0x%02x, cur:0x%02x\n",bit,vv->resources)); 29 mutex_unlock(&dev->lock); 30 return 1; 31} 32 33void saa7146_res_free(struct saa7146_fh *fh, unsigned int bits) 34{ 35 struct saa7146_dev *dev = fh->dev; 36 struct saa7146_vv *vv = dev->vv_data; 37 38 BUG_ON((fh->resources & bits) != bits); 39 40 mutex_lock(&dev->lock); 41 fh->resources &= ~bits; 42 vv->resources &= ~bits; 43 DEB_D(("res: put 0x%02x, cur:0x%02x\n",bits,vv->resources)); 44 mutex_unlock(&dev->lock); 45} 46 47 48/********************************************************************************/ 49/* common dma functions */ 50 51void saa7146_dma_free(struct saa7146_dev *dev,struct videobuf_queue *q, 52 struct saa7146_buf *buf) 53{ 54 struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb); 55 DEB_EE(("dev:%p, buf:%p\n",dev,buf)); 56 57 BUG_ON(in_interrupt()); 58 59 videobuf_waiton(&buf->vb,0,0); 60 videobuf_dma_unmap(q, dma); 61 videobuf_dma_free(dma); 62 buf->vb.state = VIDEOBUF_NEEDS_INIT; 63} 64 65 66/********************************************************************************/ 67/* common buffer functions */ 68 69int saa7146_buffer_queue(struct saa7146_dev *dev, 70 struct saa7146_dmaqueue *q, 71 struct saa7146_buf *buf) 72{ 73 assert_spin_locked(&dev->slock); 74 DEB_EE(("dev:%p, dmaq:%p, buf:%p\n", dev, q, buf)); 75 76 BUG_ON(!q); 77 78 if (NULL == q->curr) { 79 q->curr = buf; 80 DEB_D(("immediately activating buffer %p\n", buf)); 81 buf->activate(dev,buf,NULL); 82 } else { 83 list_add_tail(&buf->vb.queue,&q->queue); 84 buf->vb.state = VIDEOBUF_QUEUED; 85 DEB_D(("adding buffer %p to queue. (active buffer present)\n", buf)); 86 } 87 return 0; 88} 89 90void saa7146_buffer_finish(struct saa7146_dev *dev, 91 struct saa7146_dmaqueue *q, 92 int state) 93{ 94 assert_spin_locked(&dev->slock); 95 DEB_EE(("dev:%p, dmaq:%p, state:%d\n", dev, q, state)); 96 DEB_EE(("q->curr:%p\n",q->curr)); 97 98 BUG_ON(!q->curr); 99 100 /* finish current buffer */ 101 if (NULL == q->curr) { 102 DEB_D(("aiii. no current buffer\n")); 103 return; 104 } 105 106 q->curr->vb.state = state; 107 do_gettimeofday(&q->curr->vb.ts); 108 wake_up(&q->curr->vb.done); 109 110 q->curr = NULL; 111} 112 113void saa7146_buffer_next(struct saa7146_dev *dev, 114 struct saa7146_dmaqueue *q, int vbi) 115{ 116 struct saa7146_buf *buf,*next = NULL; 117 118 BUG_ON(!q); 119 120 DEB_INT(("dev:%p, dmaq:%p, vbi:%d\n", dev, q, vbi)); 121 122 assert_spin_locked(&dev->slock); 123 if (!list_empty(&q->queue)) { 124 /* activate next one from queue */ 125 buf = list_entry(q->queue.next,struct saa7146_buf,vb.queue); 126 list_del(&buf->vb.queue); 127 if (!list_empty(&q->queue)) 128 next = list_entry(q->queue.next,struct saa7146_buf, vb.queue); 129 q->curr = buf; 130 DEB_INT(("next buffer: buf:%p, prev:%p, next:%p\n", buf, q->queue.prev,q->queue.next)); 131 buf->activate(dev,buf,next); 132 } else { 133 DEB_INT(("no next buffer. stopping.\n")); 134 if( 0 != vbi ) { 135 /* turn off video-dma3 */ 136 saa7146_write(dev,MC1, MASK_20); 137 } else { 138 /* nothing to do -- just prevent next video-dma1 transfer 139 by lowering the protection address */ 140 141 // fixme: fix this for vflip != 0 142 143 saa7146_write(dev, PROT_ADDR1, 0); 144 saa7146_write(dev, MC2, (MASK_02|MASK_18)); 145 146 /* write the address of the rps-program */ 147 saa7146_write(dev, RPS_ADDR0, dev->d_rps0.dma_handle); 148 /* turn on rps */ 149 saa7146_write(dev, MC1, (MASK_12 | MASK_28)); 150 151/* 152 printk("vdma%d.base_even: 0x%08x\n", 1,saa7146_read(dev,BASE_EVEN1)); 153 printk("vdma%d.base_odd: 0x%08x\n", 1,saa7146_read(dev,BASE_ODD1)); 154 printk("vdma%d.prot_addr: 0x%08x\n", 1,saa7146_read(dev,PROT_ADDR1)); 155 printk("vdma%d.base_page: 0x%08x\n", 1,saa7146_read(dev,BASE_PAGE1)); 156 printk("vdma%d.pitch: 0x%08x\n", 1,saa7146_read(dev,PITCH1)); 157 printk("vdma%d.num_line_byte: 0x%08x\n", 1,saa7146_read(dev,NUM_LINE_BYTE1)); 158*/ 159 } 160 del_timer(&q->timeout); 161 } 162} 163 164void saa7146_buffer_timeout(unsigned long data) 165{ 166 struct saa7146_dmaqueue *q = (struct saa7146_dmaqueue*)data; 167 struct saa7146_dev *dev = q->dev; 168 unsigned long flags; 169 170 DEB_EE(("dev:%p, dmaq:%p\n", dev, q)); 171 172 spin_lock_irqsave(&dev->slock,flags); 173 if (q->curr) { 174 DEB_D(("timeout on %p\n", q->curr)); 175 saa7146_buffer_finish(dev,q,VIDEOBUF_ERROR); 176 } 177 178 /* we don't restart the transfer here like other drivers do. when 179 a streaming capture is disabled, the timeout function will be 180 called for the current buffer. if we activate the next buffer now, 181 we mess up our capture logic. if a timeout occurs on another buffer, 182 then something is seriously broken before, so no need to buffer the 183 next capture IMHO... */ 184/* 185 saa7146_buffer_next(dev,q); 186*/ 187 spin_unlock_irqrestore(&dev->slock,flags); 188} 189 190/********************************************************************************/ 191/* file operations */ 192 193static int fops_open(struct file *file) 194{ 195 struct video_device *vdev = video_devdata(file); 196 struct saa7146_dev *dev = video_drvdata(file); 197 struct saa7146_fh *fh = NULL; 198 int result = 0; 199 200 enum v4l2_buf_type type; 201 202 DEB_EE(("file:%p, dev:%s\n", file, video_device_node_name(vdev))); 203 204 if (mutex_lock_interruptible(&saa7146_devices_lock)) 205 return -ERESTARTSYS; 206 207 DEB_D(("using: %p\n",dev)); 208 209 type = vdev->vfl_type == VFL_TYPE_GRABBER 210 ? V4L2_BUF_TYPE_VIDEO_CAPTURE 211 : V4L2_BUF_TYPE_VBI_CAPTURE; 212 213 /* check if an extension is registered */ 214 if( NULL == dev->ext ) { 215 DEB_S(("no extension registered for this device.\n")); 216 result = -ENODEV; 217 goto out; 218 } 219 220 /* allocate per open data */ 221 fh = kzalloc(sizeof(*fh),GFP_KERNEL); 222 if (NULL == fh) { 223 DEB_S(("cannot allocate memory for per open data.\n")); 224 result = -ENOMEM; 225 goto out; 226 } 227 228 file->private_data = fh; 229 fh->dev = dev; 230 fh->type = type; 231 232 if( fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) { 233 DEB_S(("initializing vbi...\n")); 234 if (dev->ext_vv_data->capabilities & V4L2_CAP_VBI_CAPTURE) 235 result = saa7146_vbi_uops.open(dev,file); 236 if (dev->ext_vv_data->vbi_fops.open) 237 dev->ext_vv_data->vbi_fops.open(file); 238 } else { 239 DEB_S(("initializing video...\n")); 240 result = saa7146_video_uops.open(dev,file); 241 } 242 243 if (0 != result) { 244 goto out; 245 } 246 247 if( 0 == try_module_get(dev->ext->module)) { 248 result = -EINVAL; 249 goto out; 250 } 251 252 result = 0; 253out: 254 if (fh && result != 0) { 255 kfree(fh); 256 file->private_data = NULL; 257 } 258 mutex_unlock(&saa7146_devices_lock); 259 return result; 260} 261 262static int fops_release(struct file *file) 263{ 264 struct saa7146_fh *fh = file->private_data; 265 struct saa7146_dev *dev = fh->dev; 266 267 DEB_EE(("file:%p\n", file)); 268 269 if (mutex_lock_interruptible(&saa7146_devices_lock)) 270 return -ERESTARTSYS; 271 272 if( fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) { 273 if (dev->ext_vv_data->capabilities & V4L2_CAP_VBI_CAPTURE) 274 saa7146_vbi_uops.release(dev,file); 275 if (dev->ext_vv_data->vbi_fops.release) 276 dev->ext_vv_data->vbi_fops.release(file); 277 } else { 278 saa7146_video_uops.release(dev,file); 279 } 280 281 module_put(dev->ext->module); 282 file->private_data = NULL; 283 kfree(fh); 284 285 mutex_unlock(&saa7146_devices_lock); 286 287 return 0; 288} 289 290static int fops_mmap(struct file *file, struct vm_area_struct * vma) 291{ 292 struct saa7146_fh *fh = file->private_data; 293 struct videobuf_queue *q; 294 295 switch (fh->type) { 296 case V4L2_BUF_TYPE_VIDEO_CAPTURE: { 297 DEB_EE(("V4L2_BUF_TYPE_VIDEO_CAPTURE: file:%p, vma:%p\n",file, vma)); 298 q = &fh->video_q; 299 break; 300 } 301 case V4L2_BUF_TYPE_VBI_CAPTURE: { 302 DEB_EE(("V4L2_BUF_TYPE_VBI_CAPTURE: file:%p, vma:%p\n",file, vma)); 303 q = &fh->vbi_q; 304 break; 305 } 306 default: 307 BUG(); 308 return 0; 309 } 310 311 return videobuf_mmap_mapper(q,vma); 312} 313 314static unsigned int fops_poll(struct file *file, struct poll_table_struct *wait) 315{ 316 struct saa7146_fh *fh = file->private_data; 317 struct videobuf_buffer *buf = NULL; 318 struct videobuf_queue *q; 319 320 DEB_EE(("file:%p, poll:%p\n",file, wait)); 321 322 if (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type) { 323 if( 0 == fh->vbi_q.streaming ) 324 return videobuf_poll_stream(file, &fh->vbi_q, wait); 325 q = &fh->vbi_q; 326 } else { 327 DEB_D(("using video queue.\n")); 328 q = &fh->video_q; 329 } 330 331 if (!list_empty(&q->stream)) 332 buf = list_entry(q->stream.next, struct videobuf_buffer, stream); 333 334 if (!buf) { 335 DEB_D(("buf == NULL!\n")); 336 return POLLERR; 337 } 338 339 poll_wait(file, &buf->done, wait); 340 if (buf->state == VIDEOBUF_DONE || buf->state == VIDEOBUF_ERROR) { 341 DEB_D(("poll succeeded!\n")); 342 return POLLIN|POLLRDNORM; 343 } 344 345 DEB_D(("nothing to poll for, buf->state:%d\n",buf->state)); 346 return 0; 347} 348 349static ssize_t fops_read(struct file *file, char __user *data, size_t count, loff_t *ppos) 350{ 351 struct saa7146_fh *fh = file->private_data; 352 353 switch (fh->type) { 354 case V4L2_BUF_TYPE_VIDEO_CAPTURE: { 355// DEB_EE(("V4L2_BUF_TYPE_VIDEO_CAPTURE: file:%p, data:%p, count:%lun", file, data, (unsigned long)count)); 356 return saa7146_video_uops.read(file,data,count,ppos); 357 } 358 case V4L2_BUF_TYPE_VBI_CAPTURE: { 359// DEB_EE(("V4L2_BUF_TYPE_VBI_CAPTURE: file:%p, data:%p, count:%lu\n", file, data, (unsigned long)count)); 360 if (fh->dev->ext_vv_data->capabilities & V4L2_CAP_VBI_CAPTURE) 361 return saa7146_vbi_uops.read(file,data,count,ppos); 362 else 363 return -EINVAL; 364 } 365 break; 366 default: 367 BUG(); 368 return 0; 369 } 370} 371 372static ssize_t fops_write(struct file *file, const char __user *data, size_t count, loff_t *ppos) 373{ 374 struct saa7146_fh *fh = file->private_data; 375 376 switch (fh->type) { 377 case V4L2_BUF_TYPE_VIDEO_CAPTURE: 378 return -EINVAL; 379 case V4L2_BUF_TYPE_VBI_CAPTURE: 380 if (fh->dev->ext_vv_data->vbi_fops.write) 381 return fh->dev->ext_vv_data->vbi_fops.write(file, data, count, ppos); 382 else 383 return -EINVAL; 384 default: 385 BUG(); 386 return -EINVAL; 387 } 388} 389 390static const struct v4l2_file_operations video_fops = 391{ 392 .owner = THIS_MODULE, 393 .open = fops_open, 394 .release = fops_release, 395 .read = fops_read, 396 .write = fops_write, 397 .poll = fops_poll, 398 .mmap = fops_mmap, 399 .ioctl = video_ioctl2, 400}; 401 402static void vv_callback(struct saa7146_dev *dev, unsigned long status) 403{ 404 u32 isr = status; 405 406 DEB_INT(("dev:%p, isr:0x%08x\n",dev,(u32)status)); 407 408 if (0 != (isr & (MASK_27))) { 409 DEB_INT(("irq: RPS0 (0x%08x).\n",isr)); 410 saa7146_video_uops.irq_done(dev,isr); 411 } 412 413 if (0 != (isr & (MASK_28))) { 414 u32 mc2 = saa7146_read(dev, MC2); 415 if( 0 != (mc2 & MASK_15)) { 416 DEB_INT(("irq: RPS1 vbi workaround (0x%08x).\n",isr)); 417 wake_up(&dev->vv_data->vbi_wq); 418 saa7146_write(dev,MC2, MASK_31); 419 return; 420 } 421 DEB_INT(("irq: RPS1 (0x%08x).\n",isr)); 422 saa7146_vbi_uops.irq_done(dev,isr); 423 } 424} 425 426int saa7146_vv_init(struct saa7146_dev* dev, struct saa7146_ext_vv *ext_vv) 427{ 428 struct saa7146_vv *vv; 429 int err; 430 431 err = v4l2_device_register(&dev->pci->dev, &dev->v4l2_dev); 432 if (err) 433 return err; 434 435 vv = kzalloc(sizeof(struct saa7146_vv), GFP_KERNEL); 436 if (vv == NULL) { 437 ERR(("out of memory. aborting.\n")); 438 return -ENOMEM; 439 } 440 ext_vv->ops = saa7146_video_ioctl_ops; 441 ext_vv->core_ops = &saa7146_video_ioctl_ops; 442 443 DEB_EE(("dev:%p\n",dev)); 444 445 /* set default values for video parts of the saa7146 */ 446 saa7146_write(dev, BCS_CTRL, 0x80400040); 447 448 /* enable video-port pins */ 449 saa7146_write(dev, MC1, (MASK_10 | MASK_26)); 450 451 /* save per-device extension data (one extension can 452 handle different devices that might need different 453 configuration data) */ 454 dev->ext_vv_data = ext_vv; 455 456 vv->d_clipping.cpu_addr = pci_alloc_consistent(dev->pci, SAA7146_CLIPPING_MEM, &vv->d_clipping.dma_handle); 457 if( NULL == vv->d_clipping.cpu_addr ) { 458 ERR(("out of memory. aborting.\n")); 459 kfree(vv); 460 return -1; 461 } 462 memset(vv->d_clipping.cpu_addr, 0x0, SAA7146_CLIPPING_MEM); 463 464 saa7146_video_uops.init(dev,vv); 465 if (dev->ext_vv_data->capabilities & V4L2_CAP_VBI_CAPTURE) 466 saa7146_vbi_uops.init(dev,vv); 467 468 dev->vv_data = vv; 469 dev->vv_callback = &vv_callback; 470 471 return 0; 472} 473EXPORT_SYMBOL_GPL(saa7146_vv_init); 474 475int saa7146_vv_release(struct saa7146_dev* dev) 476{ 477 struct saa7146_vv *vv = dev->vv_data; 478 479 DEB_EE(("dev:%p\n",dev)); 480 481 v4l2_device_unregister(&dev->v4l2_dev); 482 pci_free_consistent(dev->pci, SAA7146_CLIPPING_MEM, vv->d_clipping.cpu_addr, vv->d_clipping.dma_handle); 483 kfree(vv); 484 dev->vv_data = NULL; 485 dev->vv_callback = NULL; 486 487 return 0; 488} 489EXPORT_SYMBOL_GPL(saa7146_vv_release); 490 491int saa7146_register_device(struct video_device **vid, struct saa7146_dev* dev, 492 char *name, int type) 493{ 494 struct video_device *vfd; 495 int err; 496 int i; 497 498 DEB_EE(("dev:%p, name:'%s', type:%d\n",dev,name,type)); 499 500 // released by vfd->release 501 vfd = video_device_alloc(); 502 if (vfd == NULL) 503 return -ENOMEM; 504 505 vfd->fops = &video_fops; 506 vfd->ioctl_ops = &dev->ext_vv_data->ops; 507 vfd->release = video_device_release; 508 vfd->tvnorms = 0; 509 for (i = 0; i < dev->ext_vv_data->num_stds; i++) 510 vfd->tvnorms |= dev->ext_vv_data->stds[i].id; 511 strlcpy(vfd->name, name, sizeof(vfd->name)); 512 video_set_drvdata(vfd, dev); 513 514 err = video_register_device(vfd, type, -1); 515 if (err < 0) { 516 ERR(("cannot register v4l2 device. skipping.\n")); 517 video_device_release(vfd); 518 return err; 519 } 520 521 INFO(("%s: registered device %s [v4l2]\n", 522 dev->name, video_device_node_name(vfd))); 523 524 *vid = vfd; 525 return 0; 526} 527EXPORT_SYMBOL_GPL(saa7146_register_device); 528 529int saa7146_unregister_device(struct video_device **vid, struct saa7146_dev* dev) 530{ 531 DEB_EE(("dev:%p\n",dev)); 532 533 video_unregister_device(*vid); 534 *vid = NULL; 535 536 return 0; 537} 538EXPORT_SYMBOL_GPL(saa7146_unregister_device); 539 540static int __init saa7146_vv_init_module(void) 541{ 542 return 0; 543} 544 545 546static void __exit saa7146_vv_cleanup_module(void) 547{ 548} 549 550module_init(saa7146_vv_init_module); 551module_exit(saa7146_vv_cleanup_module); 552 553MODULE_AUTHOR("Michael Hunold <michael@mihu.de>"); 554MODULE_DESCRIPTION("video4linux driver for saa7146-based hardware"); 555MODULE_LICENSE("GPL"); 556