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->dev, 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 142 saa7146_write(dev, PROT_ADDR1, 0); 143 saa7146_write(dev, MC2, (MASK_02|MASK_18)); 144 145 /* write the address of the rps-program */ 146 saa7146_write(dev, RPS_ADDR0, dev->d_rps0.dma_handle); 147 /* turn on rps */ 148 saa7146_write(dev, MC1, (MASK_12 | MASK_28)); 149 150/* 151 printk("vdma%d.base_even: 0x%08x\n", 1,saa7146_read(dev,BASE_EVEN1)); 152 printk("vdma%d.base_odd: 0x%08x\n", 1,saa7146_read(dev,BASE_ODD1)); 153 printk("vdma%d.prot_addr: 0x%08x\n", 1,saa7146_read(dev,PROT_ADDR1)); 154 printk("vdma%d.base_page: 0x%08x\n", 1,saa7146_read(dev,BASE_PAGE1)); 155 printk("vdma%d.pitch: 0x%08x\n", 1,saa7146_read(dev,PITCH1)); 156 printk("vdma%d.num_line_byte: 0x%08x\n", 1,saa7146_read(dev,NUM_LINE_BYTE1)); 157*/ 158 } 159 del_timer(&q->timeout); 160 } 161} 162 163void saa7146_buffer_timeout(unsigned long data) 164{ 165 struct saa7146_dmaqueue *q = (struct saa7146_dmaqueue*)data; 166 struct saa7146_dev *dev = q->dev; 167 unsigned long flags; 168 169 DEB_EE(("dev:%p, dmaq:%p\n", dev, q)); 170 171 spin_lock_irqsave(&dev->slock,flags); 172 if (q->curr) { 173 DEB_D(("timeout on %p\n", q->curr)); 174 saa7146_buffer_finish(dev,q,VIDEOBUF_ERROR); 175 } 176 177 /* we don't restart the transfer here like other drivers do. when 178 a streaming capture is disabled, the timeout function will be 179 called for the current buffer. if we activate the next buffer now, 180 we mess up our capture logic. if a timeout occurs on another buffer, 181 then something is seriously broken before, so no need to buffer the 182 next capture IMHO... */ 183/* 184 saa7146_buffer_next(dev,q); 185*/ 186 spin_unlock_irqrestore(&dev->slock,flags); 187} 188 189/********************************************************************************/ 190/* file operations */ 191 192static int fops_open(struct file *file) 193{ 194 struct video_device *vdev = video_devdata(file); 195 struct saa7146_dev *dev = video_drvdata(file); 196 struct saa7146_fh *fh = NULL; 197 int result = 0; 198 199 enum v4l2_buf_type type; 200 201 DEB_EE(("file:%p, dev:%s\n", file, video_device_node_name(vdev))); 202 203 if (mutex_lock_interruptible(&saa7146_devices_lock)) 204 return -ERESTARTSYS; 205 206 DEB_D(("using: %p\n",dev)); 207 208 type = vdev->vfl_type == VFL_TYPE_GRABBER 209 ? V4L2_BUF_TYPE_VIDEO_CAPTURE 210 : V4L2_BUF_TYPE_VBI_CAPTURE; 211 212 /* check if an extension is registered */ 213 if( NULL == dev->ext ) { 214 DEB_S(("no extension registered for this device.\n")); 215 result = -ENODEV; 216 goto out; 217 } 218 219 /* allocate per open data */ 220 fh = kzalloc(sizeof(*fh),GFP_KERNEL); 221 if (NULL == fh) { 222 DEB_S(("cannot allocate memory for per open data.\n")); 223 result = -ENOMEM; 224 goto out; 225 } 226 227 file->private_data = fh; 228 fh->dev = dev; 229 fh->type = type; 230 231 if( fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) { 232 DEB_S(("initializing vbi...\n")); 233 if (dev->ext_vv_data->capabilities & V4L2_CAP_VBI_CAPTURE) 234 result = saa7146_vbi_uops.open(dev,file); 235 if (dev->ext_vv_data->vbi_fops.open) 236 dev->ext_vv_data->vbi_fops.open(file); 237 } else { 238 DEB_S(("initializing video...\n")); 239 result = saa7146_video_uops.open(dev,file); 240 } 241 242 if (0 != result) { 243 goto out; 244 } 245 246 if( 0 == try_module_get(dev->ext->module)) { 247 result = -EINVAL; 248 goto out; 249 } 250 251 result = 0; 252out: 253 if (fh && result != 0) { 254 kfree(fh); 255 file->private_data = NULL; 256 } 257 mutex_unlock(&saa7146_devices_lock); 258 return result; 259} 260 261static int fops_release(struct file *file) 262{ 263 struct saa7146_fh *fh = file->private_data; 264 struct saa7146_dev *dev = fh->dev; 265 266 DEB_EE(("file:%p\n", file)); 267 268 if (mutex_lock_interruptible(&saa7146_devices_lock)) 269 return -ERESTARTSYS; 270 271 if( fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) { 272 if (dev->ext_vv_data->capabilities & V4L2_CAP_VBI_CAPTURE) 273 saa7146_vbi_uops.release(dev,file); 274 if (dev->ext_vv_data->vbi_fops.release) 275 dev->ext_vv_data->vbi_fops.release(file); 276 } else { 277 saa7146_video_uops.release(dev,file); 278 } 279 280 module_put(dev->ext->module); 281 file->private_data = NULL; 282 kfree(fh); 283 284 mutex_unlock(&saa7146_devices_lock); 285 286 return 0; 287} 288 289static int fops_mmap(struct file *file, struct vm_area_struct * vma) 290{ 291 struct saa7146_fh *fh = file->private_data; 292 struct videobuf_queue *q; 293 294 switch (fh->type) { 295 case V4L2_BUF_TYPE_VIDEO_CAPTURE: { 296 DEB_EE(("V4L2_BUF_TYPE_VIDEO_CAPTURE: file:%p, vma:%p\n",file, vma)); 297 q = &fh->video_q; 298 break; 299 } 300 case V4L2_BUF_TYPE_VBI_CAPTURE: { 301 DEB_EE(("V4L2_BUF_TYPE_VBI_CAPTURE: file:%p, vma:%p\n",file, vma)); 302 q = &fh->vbi_q; 303 break; 304 } 305 default: 306 BUG(); 307 return 0; 308 } 309 310 return videobuf_mmap_mapper(q,vma); 311} 312 313static unsigned int fops_poll(struct file *file, struct poll_table_struct *wait) 314{ 315 struct saa7146_fh *fh = file->private_data; 316 struct videobuf_buffer *buf = NULL; 317 struct videobuf_queue *q; 318 319 DEB_EE(("file:%p, poll:%p\n",file, wait)); 320 321 if (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type) { 322 if( 0 == fh->vbi_q.streaming ) 323 return videobuf_poll_stream(file, &fh->vbi_q, wait); 324 q = &fh->vbi_q; 325 } else { 326 DEB_D(("using video queue.\n")); 327 q = &fh->video_q; 328 } 329 330 if (!list_empty(&q->stream)) 331 buf = list_entry(q->stream.next, struct videobuf_buffer, stream); 332 333 if (!buf) { 334 DEB_D(("buf == NULL!\n")); 335 return POLLERR; 336 } 337 338 poll_wait(file, &buf->done, wait); 339 if (buf->state == VIDEOBUF_DONE || buf->state == VIDEOBUF_ERROR) { 340 DEB_D(("poll succeeded!\n")); 341 return POLLIN|POLLRDNORM; 342 } 343 344 DEB_D(("nothing to poll for, buf->state:%d\n",buf->state)); 345 return 0; 346} 347 348static ssize_t fops_read(struct file *file, char __user *data, size_t count, loff_t *ppos) 349{ 350 struct saa7146_fh *fh = file->private_data; 351 352 switch (fh->type) { 353 case V4L2_BUF_TYPE_VIDEO_CAPTURE: { 354// DEB_EE(("V4L2_BUF_TYPE_VIDEO_CAPTURE: file:%p, data:%p, count:%lun", file, data, (unsigned long)count)); 355 return saa7146_video_uops.read(file,data,count,ppos); 356 } 357 case V4L2_BUF_TYPE_VBI_CAPTURE: { 358// DEB_EE(("V4L2_BUF_TYPE_VBI_CAPTURE: file:%p, data:%p, count:%lu\n", file, data, (unsigned long)count)); 359 if (fh->dev->ext_vv_data->capabilities & V4L2_CAP_VBI_CAPTURE) 360 return saa7146_vbi_uops.read(file,data,count,ppos); 361 else 362 return -EINVAL; 363 } 364 break; 365 default: 366 BUG(); 367 return 0; 368 } 369} 370 371static ssize_t fops_write(struct file *file, const char __user *data, size_t count, loff_t *ppos) 372{ 373 struct saa7146_fh *fh = file->private_data; 374 375 switch (fh->type) { 376 case V4L2_BUF_TYPE_VIDEO_CAPTURE: 377 return -EINVAL; 378 case V4L2_BUF_TYPE_VBI_CAPTURE: 379 if (fh->dev->ext_vv_data->vbi_fops.write) 380 return fh->dev->ext_vv_data->vbi_fops.write(file, data, count, ppos); 381 else 382 return -EINVAL; 383 default: 384 BUG(); 385 return -EINVAL; 386 } 387} 388 389static const struct v4l2_file_operations video_fops = 390{ 391 .owner = THIS_MODULE, 392 .open = fops_open, 393 .release = fops_release, 394 .read = fops_read, 395 .write = fops_write, 396 .poll = fops_poll, 397 .mmap = fops_mmap, 398 .ioctl = video_ioctl2, 399}; 400 401static void vv_callback(struct saa7146_dev *dev, unsigned long status) 402{ 403 u32 isr = status; 404 405 DEB_INT(("dev:%p, isr:0x%08x\n",dev,(u32)status)); 406 407 if (0 != (isr & (MASK_27))) { 408 DEB_INT(("irq: RPS0 (0x%08x).\n",isr)); 409 saa7146_video_uops.irq_done(dev,isr); 410 } 411 412 if (0 != (isr & (MASK_28))) { 413 u32 mc2 = saa7146_read(dev, MC2); 414 if( 0 != (mc2 & MASK_15)) { 415 DEB_INT(("irq: RPS1 vbi workaround (0x%08x).\n",isr)); 416 wake_up(&dev->vv_data->vbi_wq); 417 saa7146_write(dev,MC2, MASK_31); 418 return; 419 } 420 DEB_INT(("irq: RPS1 (0x%08x).\n",isr)); 421 saa7146_vbi_uops.irq_done(dev,isr); 422 } 423} 424 425int saa7146_vv_init(struct saa7146_dev* dev, struct saa7146_ext_vv *ext_vv) 426{ 427 struct saa7146_vv *vv; 428 int err; 429 430 err = v4l2_device_register(&dev->pci->dev, &dev->v4l2_dev); 431 if (err) 432 return err; 433 434 vv = kzalloc(sizeof(struct saa7146_vv), GFP_KERNEL); 435 if (vv == NULL) { 436 ERR(("out of memory. aborting.\n")); 437 return -ENOMEM; 438 } 439 ext_vv->ops = saa7146_video_ioctl_ops; 440 ext_vv->core_ops = &saa7146_video_ioctl_ops; 441 442 DEB_EE(("dev:%p\n",dev)); 443 444 /* set default values for video parts of the saa7146 */ 445 saa7146_write(dev, BCS_CTRL, 0x80400040); 446 447 /* enable video-port pins */ 448 saa7146_write(dev, MC1, (MASK_10 | MASK_26)); 449 450 /* save per-device extension data (one extension can 451 handle different devices that might need different 452 configuration data) */ 453 dev->ext_vv_data = ext_vv; 454 455 vv->d_clipping.cpu_addr = pci_alloc_consistent(dev->pci, SAA7146_CLIPPING_MEM, &vv->d_clipping.dma_handle); 456 if( NULL == vv->d_clipping.cpu_addr ) { 457 ERR(("out of memory. aborting.\n")); 458 kfree(vv); 459 return -1; 460 } 461 memset(vv->d_clipping.cpu_addr, 0x0, SAA7146_CLIPPING_MEM); 462 463 saa7146_video_uops.init(dev,vv); 464 if (dev->ext_vv_data->capabilities & V4L2_CAP_VBI_CAPTURE) 465 saa7146_vbi_uops.init(dev,vv); 466 467 dev->vv_data = vv; 468 dev->vv_callback = &vv_callback; 469 470 return 0; 471} 472EXPORT_SYMBOL_GPL(saa7146_vv_init); 473 474int saa7146_vv_release(struct saa7146_dev* dev) 475{ 476 struct saa7146_vv *vv = dev->vv_data; 477 478 DEB_EE(("dev:%p\n",dev)); 479 480 v4l2_device_unregister(&dev->v4l2_dev); 481 pci_free_consistent(dev->pci, SAA7146_CLIPPING_MEM, vv->d_clipping.cpu_addr, vv->d_clipping.dma_handle); 482 kfree(vv); 483 dev->vv_data = NULL; 484 dev->vv_callback = NULL; 485 486 return 0; 487} 488EXPORT_SYMBOL_GPL(saa7146_vv_release); 489 490int saa7146_register_device(struct video_device **vid, struct saa7146_dev* dev, 491 char *name, int type) 492{ 493 struct video_device *vfd; 494 int err; 495 int i; 496 497 DEB_EE(("dev:%p, name:'%s', type:%d\n",dev,name,type)); 498 499 // released by vfd->release 500 vfd = video_device_alloc(); 501 if (vfd == NULL) 502 return -ENOMEM; 503 504 vfd->fops = &video_fops; 505 vfd->ioctl_ops = &dev->ext_vv_data->ops; 506 vfd->release = video_device_release; 507 vfd->tvnorms = 0; 508 for (i = 0; i < dev->ext_vv_data->num_stds; i++) 509 vfd->tvnorms |= dev->ext_vv_data->stds[i].id; 510 strlcpy(vfd->name, name, sizeof(vfd->name)); 511 video_set_drvdata(vfd, dev); 512 513 err = video_register_device(vfd, type, -1); 514 if (err < 0) { 515 ERR(("cannot register v4l2 device. skipping.\n")); 516 video_device_release(vfd); 517 return err; 518 } 519 520 INFO(("%s: registered device %s [v4l2]\n", 521 dev->name, video_device_node_name(vfd))); 522 523 *vid = vfd; 524 return 0; 525} 526EXPORT_SYMBOL_GPL(saa7146_register_device); 527 528int saa7146_unregister_device(struct video_device **vid, struct saa7146_dev* dev) 529{ 530 DEB_EE(("dev:%p\n",dev)); 531 532 video_unregister_device(*vid); 533 *vid = NULL; 534 535 return 0; 536} 537EXPORT_SYMBOL_GPL(saa7146_unregister_device); 538 539static int __init saa7146_vv_init_module(void) 540{ 541 return 0; 542} 543 544 545static void __exit saa7146_vv_cleanup_module(void) 546{ 547} 548 549module_init(saa7146_vv_init_module); 550module_exit(saa7146_vv_cleanup_module); 551 552MODULE_AUTHOR("Michael Hunold <michael@mihu.de>"); 553MODULE_DESCRIPTION("video4linux driver for saa7146-based hardware"); 554MODULE_LICENSE("GPL"); 555