------main.c------- 15d14 < 17a17,26 > /* > * Macros used for "locking" (using spin locks) when code enters critical section > */ > #define BEGIN_CRITICAL_SECTION do{unsigned long flags;spin_lock_irqsave(&ps_lock,flags) > #define END_CRITICAL_SECTION spin_unlock_irqrestore(&ps_lock,flags);}while(0) > > /* > * The timer structure. This is global at present, it can be taken into the device > * structure "pixelsmart" but care must be taken to initialize it to 0. > */ 19d27 < struct pixelsmart *psmart; 21c29 < unsigned long capture_w=0,capture_h=0; --- > struct pixelsmart *psmart; 32a40,42 > extern int > pixelsmart_begin(struct pixelsmart *dev); > 40c50 < unsigned char startup_data[] = { --- > const unsigned char startup_data[] = { 54a65,80 > /* > * Function declarations for the external functions used for mmap and streaming > * The function definitions can be found in mmap.c and stream.c respectively > */ > extern int > pixelsmart_streamon(struct pixelsmart *pstv, __u32 type); > extern void > pixelsmart_streamoff(struct pixelsmart *pstv, __u32 type); > > extern int pixelsmart_mmap(void *id, struct vm_area_struct *vma); > > extern int > mmap_request_buffers(struct pixelsmart *dev, struct v4l2_requestbuffers *req); > extern void mmap_unrequest_buffers(struct pixelsmart *dev); > extern int pixelsmart_dequeuebuffer(struct pixelsmart *pstv,struct v4l2_buffer *buf); > extern int pixelsmart_queuebuffer(struct pixelsmart *pstv,struct v4l2_buffer *vidbuf); 56,57c82 < extern int pixelsmart_mmap(struct file *file, struct vm_area_struct *vma); < --- > /* the unique I2C buss address of the SAA7110 (A/D) device */ 60,61c85,87 < /*the unique I2C bus address of the SAA7110 (A/D) device */ < --- > /* > * More card specific details > */ 69a95 > unsigned long HRT_base ; 71d96 < unsigned long HRT_base ; //= 0xdc00 ; 91a118,120 > /* This is just a hack to make the probe work for plug and play > * option (PCI address). TODO: remove temporary hack and find better solution > */ 167a194 > #ifdef DEBUG 168a196 > #endif 223,225d250 < /* Initialize semaphore here, needed hence forth */ < sema_init(&pstv->sem,1); < 231c256,257 < } --- > > 238,239c264 < < static int pixelsmart_open(struct inode *inode, struct file *file) --- > int pixelsmart_open(struct v4l2_device *v, int flags, void **idptr) 241,245c266,274 < struct video_device *dev = video_devdata(file); < struct pixelsmart *pstv = dev->priv; < pstv->capture_completed = 0; < pstv->grabber_enabled = 0; < pstv->grab_in_progress = 0; --- > struct pixelsmart *pstv = v->priv; > *idptr = v; > > /* > * Initilization of queues for captured buffer. pstv->stream_q_capture > * contain data for mapped buffers. The rest are stored in stream_q_done > */ > v4l2_q_init(&pstv->stream_q_capture); > v4l2_q_init(&pstv->stream_q_done); 256,257c286 < < static int pixelsmart_release(struct inode *inode, struct file *file) --- > void pixelsmart_close(void *id) 260c289 < return 0; --- > return ; 271c300,306 < int current_row =pstv->field; --- > int field, current_row; > field = current_row = pstv->field; > > > if(pstv->frame_buffer == NULL){ > return -EFAULT; > } 273,275d307 < #ifdef DEBUG < printk("virtual address of frame being filled = %p\n",pstv->frame_buffer); < #endif 282a315 > BEGIN_CRITICAL_SECTION; 288,292c321,324 < //read the buffer < if(pstv->frame_buffer == NULL){ < printk("<1> NULL\n"); < return -EFAULT; < } --- > > #ifdef DEBUG > printk("virtual address of frame being filled = %p\n",pstv->frame_buffer); > #endif 295c327,329 < current_row += 2; --- > > END_CRITICAL_SECTION; > 300c334 < --- > current_row += 2; 305,307d338 < pstv->capture_completed = 1; < pstv->grab_in_progress = 0; < 312c343 < * Captures one frame. --- > * Captures one frame. Moves a fraame from the capture queue to the done queue. 317d346 < 319a349 > struct stream_buffer *buf=NULL; 330,332d358 < #ifdef DEBUG < printk ("Task added to queue\n"); < #endif 335,336d360 < pstv->field = field; < fill_buffer(pstv); 338,339c362,367 < // Wake up poll/read < wake_up_interruptible(&pstv->queue); --- > if (!pstv->q_cap_count){ > queue_task(&ps_task,&tq_timer); > return; > } > > buf = v4l2_q_del_head(&pstv->stream_q_capture); 340a369,370 > if (buf != NULL){ > pstv->frame_buffer = buf->vaddress; 342c372 < printk ("One frame has been captured. Returning... \n"); --- > printk("virtual address in capture frame = %p\n",pstv->frame_buffer); 344d373 < return; 347,354c376,379 < /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ < * This is the read system call. If grabbing was not started with the poll < * system call, it is started here and acts as a busy read. If a frame was ready < * before the read was called, it will immediately return a frame. < * TODO: Implement frame age. This call will currently return an old frame is poll < * was called long before read. The frame should contain a timestamp and old frames < * shoudl be discarded. < * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ --- > if (pstv->frame_buffer == NULL){ > printk("frame_buff =null\n"); > return; > } 356,359c381,384 < static int pixelsmart_read(struct file *file, char *data, size_t count, loff_t *f_pos) < { < struct video_device *dev = video_devdata(file); < struct pixelsmart *pstv = dev->priv; --- > /* Fill in the buffer information fields */ > buf->vidbuf.flags |= V4L2_BUF_FLAG_DONE | V4L2_BUF_FLAG_KEYFRAME; > /* Move buffer to done queue */ > pstv->q_cap_count--; 361,362c386,390 < pstv->field = readb(pstv->pixelsmart_mem +PIXELSMART_CONTROL_REG) & PIXELSMART_FIELD_MASK; < rmb(); --- > v4l2_q_add_tail(&pstv->stream_q_done, &buf->qnode); > #ifdef DEBUG > printk ("Node added to tail \n"); > #endif > fill_buffer(pstv); 364,381c392,394 < /* < * Read the field opposite to the one that the device is writing to. < */ < pstv->field = (pstv->field == 0) ? 1 : 0; < if (down_interruptible(&pstv->sem)) < return -ERESTARTSYS; < /* < * Check if a frame is ready, if not check if capture was already started by poll. If not, < * Then start the grabber by adding grab routine to the timer queue. Else skip over all these < * and simply copy the available frame to the user. < * TODO: Check for age of frame and reject old frame. < */ < if(!pstv->capture_completed) < { < if(!pstv->grab_in_progress) < { < pixelsmart_init_timer(pstv); < pstv->grab_in_progress = 1; --- > //wake up the poll > wake_up_interruptible(&psmart->queue); > if(pstv->getmoreframes){ 383,386d395 < interruptible_sleep_on(&pstv->queue); < if (signal_pending (current)) /* a signal arrived */ < return -ERESTARTSYS; < } 388,390d396 < pstv->capture_completed = 0; < copy_to_user(data, (char *)pstv->frame_buffer,512 * 512 ); < up(&pstv->sem); 392c398 < printk("Read returned frame successfully\n"); --- > printk ("One frame has been captured. Returning... \n"); 394,395c400 < return (512 * 512); < --- > return; 399,400c404,405 < * Used by the select and poll system calls. Starts the grabbing process < * if capture has not already been started. --- > * Used by the select and poll system calls. Returns a frame from the > * done queue, if it exists. 403c408 < unsigned int pixelsmart_poll(struct file *file, poll_table *table) --- > int pixelsmart_poll(void *id, struct file *file, poll_table *table) 405,406c410 < < struct video_device *dev = video_devdata(file); --- > struct v4l2_device *dev = (struct v4l2_device *)id; 407a412 > void *node; 409,414c414,418 < /* Capture is through read() call */ < < printk ("poll 6\n"); < if (pstv->capture_completed)/* data is ready now */ < { < return (POLLIN | POLLRDNORM); --- > printk ("poll 1\n"); > node = v4l2_q_peek_head(&pstv->stream_q_done); > if (node != NULL){ > printk ("poll 2\n"); > return (POLLIN | POLLRDNORM);/* data is ready now */ 416,423d419 < else < { < if(!pstv->grab_in_progress) < { < pixelsmart_init_timer(pstv); < pstv->grab_in_progress = 1; < printk(" in poll\n"); < queue_task(&ps_task,&tq_timer); 425c421,425 < } --- > node = v4l2_q_peek_head(&pstv->stream_q_capture); > printk ("poll 3\n"); > if (node == NULL){ > return POLLERR; /* no frames queued */ > printk ("poll 4\n"); 428a429 > printk ("poll 5\n"); 449,451c448,453 < { < 0, V4L2_BUF_TYPE_VIDEO_CAPTURE, < V4L2_PIX_FMT_GREY, {0}, 8, {0}, --- > {4, > {"Greyscale-8"}, > V4L2_PIX_FMT_GREY, > V4L2_FMT_CS_601YUV, > 8, > {0, 0} 453d454 < 458c459,464 < const int NUM_CAPFMT = ARRAY_SIZE(capfmt); --- > #define NUM_CAPFMT (sizeof(capfmt)/sizeof(capfmt[0])) > > static const struct v4l2_queryctrl no_ctl = { > .name = "42", > .flags = V4L2_CTRL_FLAG_DISABLED, > }; 467,471d472 < static const struct v4l2_queryctrl no_ctl = { < .name = "42", < .flags = V4L2_CTRL_FLAG_DISABLED, < }; < 502c503 < .maximum = 0xff, --- > .maximum = 0x00, 504c505 < .default_value = 0x01, --- > .default_value = 0x00, 509,511d509 < /* < * Pixelsmart control structure array size. < */ 518c516 < static int set_control(struct pixelsmart *pstv, unsigned long a) --- > static int set_control(struct pixelsmart *btv, struct v4l2_control *c) 520,524c518,525 < struct v4l2_control *c = (struct v4l2_control *)a; < int val,reg; < #ifdef DEBUG < printk("Trying to set value %d in reg %x\n",val,reg); < #endif --- > int i,val,reg; > > for (i = 0; i < PSMART_CTLS; i++) > if (psmart_ctls[i].id == c->id) > break; > if (i == PSMART_CTLS) > return -EINVAL; > 542c543,546 < I2C_stop(); --- > > /* > * Send the new values to the device. > */ 548c552,553 < startup_data[reg] = val; --- > > psmart_ctls[c->id].default_value = val; 557c562,563 < static int pixelsmart_new_format(struct pixelsmart *pstv) --- > static int > pixelsmart_new_format(struct pixelsmart *pstv) 561a568 > 562a570,572 > pstv->clientfmt.width = pstv->swidth = 512; > pstv->clientfmt.height= pstv->sheight = 512; > pstv->clientfmt.flags = 0; //V4L2_PIX_FMT_GREY; 564,567c574 < pstv->clientfmt.fmt.pix.width = pstv->swidth = 512; < pstv->clientfmt.fmt.pix.height= pstv->sheight = 512; < switch (pstv->clientfmt.fmt.pix.pixelformat) < { --- > switch (pstv->clientfmt.pixelformat){ 569c576 < pstv->clientfmt.fmt.pix.pixelformat = V4L2_PIX_FMT_GREY; --- > pstv->clientfmt.depth = 8; 573,574c580,583 < (char *)&pstv->clientfmt.fmt.pix.pixelformat); < pstv->clientfmt.fmt.pix.pixelformat = V4L2_PIX_FMT_GREY; --- > (char *)&pstv->clientfmt.pixelformat); > pstv->clientfmt.depth = 8; > pstv->clientfmt.pixelformat = V4L2_PIX_FMT_GREY; > pstv->clientfmt.flags = 0; 576a586 > 578,581c588,591 < if (pstv->clientfmt.fmt.pix.width < MIN_WIDTH) < pstv->clientfmt.fmt.pix.width = MIN_WIDTH; < if (pstv->clientfmt.fmt.pix.height < MIN_HEIGHT) < pstv->clientfmt.fmt.pix.height = MIN_HEIGHT; --- > if (pstv->clientfmt.width < MIN_WIDTH) > pstv->clientfmt.width = MIN_WIDTH; > if (pstv->clientfmt.height < MIN_HEIGHT) > pstv->clientfmt.height = MIN_HEIGHT; 587,589c596,602 < pstv->clientfmt.fmt.pix.sizeimage = (pstv->clientfmt.fmt.pix.width * pstv->clientfmt.fmt.pix.height); < pstv->capture_size = pstv->clientfmt.fmt.pix.width < * pstv->clientfmt.fmt.pix.height --- > > pstv->clientfmt.sizeimage = (pstv->clientfmt.width > * pstv->clientfmt.height > * pstv->clientfmt.depth)/ 8; > > pstv->capture_size = pstv->clientfmt.width > * pstv->clientfmt.height 591,593d603 < #ifdef DEBUG < printk("image size = %d , capture size = %lX\n", pstv->clientfmt.fmt.pix.sizeimage,pstv->capture_size); < #endif 599d608 < 605,606c614 < < static int pixelsmart_ioctl(struct inode *inode, struct file *file,unsigned int cmd, unsigned long arg) --- > static int pixelsmart_ioctl(void *id, unsigned int cmd,void *arg) 608c616 < struct video_device *dev = video_devdata(file); --- > struct v4l2_device *dev = (struct v4l2_device *)id; 614,618c622,636 < struct v4l2_capability *b = ( struct v4l2_capability * )arg; < strcpy(b->card,"Hrt"); < strcpy(b->driver,"Pixelsmart"); < strncpy(b->card,pstv->video_dev.name,sizeof(b->card)); < b->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE; --- > { > struct v4l2_capability *b = arg; > strcpy(b->name, dev->name); > b->type = V4L2_TYPE_CAPTURE; > b->flags = V4L2_FLAG_READ | > V4L2_FLAG_STREAMING | > V4L2_FLAG_SELECT|V4L2_FLAG_MONOCHROME; > b->inputs = 1; > b->outputs = 0; > b->audios = 0; > b->maxwidth = MAX_WIDTH; > b->maxheight = MAX_HEIGHT; > b->minwidth = MIN_WIDTH; > b->minheight = MIN_HEIGHT; > b->maxframerate = 30; 619a638,639 > } > 621,622d640 < struct v4l2_format *f = (struct v4l2_format *)arg; < if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 624c642,645 < printk("G_FMT wrong buffer type %d\n",f->type); --- > struct v4l2_format *fmt = arg; > if (fmt->type != V4L2_BUF_TYPE_CAPTURE) > { > printk("G_FMT wrong buffer type %d\n",fmt->type); 627,629c648,651 < memset(&f->fmt.pix,0,sizeof(struct v4l2_pix_format)); < f->fmt.pix = pstv->clientfmt.fmt.pix; < break; --- > printk ("w = %d , h = %d d = %d\n",pstv->clientfmt.width, pstv->clientfmt.height,pstv->clientfmt.depth); > fmt->fmt.pix = pstv->clientfmt; > return 0; > } 631,633c653,655 < struct v4l2_format *fmt = (struct v4l2_format *)arg; < < if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) --- > { > struct v4l2_format *fmt = arg; > if (fmt->type != V4L2_BUF_TYPE_CAPTURE) 638c660 < pstv->clientfmt = *fmt; --- > pstv->clientfmt = fmt->fmt.pix; 640a663,667 > if (pstv->streaming) > capture_frame(pstv); > fmt->fmt.pix = pstv->clientfmt; > return 0; > } 642,643c669,670 < fmt->fmt.pix = pstv->clientfmt.fmt.pix; < break; --- > case VIDIOC_G_COMP: return -EINVAL; > case VIDIOC_S_COMP: return -EINVAL; 645,646c672,674 < struct v4l2_streamparm *sp = (struct v4l2_streamparm *)arg; < if (sp->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) --- > { > struct v4l2_streamparm *sp = arg; > if (sp->type != V4L2_BUF_TYPE_CAPTURE) 648d675 < memset (sp,0,sizeof(sp)); 650c677,678 < break; --- > return 0; > } 652,653c680,809 < // Not required!! < break; --- > { > struct v4l2_streamparm *sp = arg; > struct v4l2_captureparm *vp = &sp->parm.capture; > > if (vp->capturemode & ~pstv->capture.capability) > { > printk("PARM unsupported capture capability %08X\n", > vp->capturemode); > return -EINVAL; > } > if ((pstv->capture.capability & V4L2_CAP_TIMEPERFRAME) && > vp->timeperframe < 10000) > { > printk("PARM time per frame out of range %ld\n", > vp->timeperframe); > return -EINVAL; > } > if (vp->capturemode != pstv->capture.capturemode && > pstv->streaming) > return -EINVAL; > > if (vp->capturemode != pstv->capture.capturemode) > { > pstv->capture.capturemode = vp->capturemode; > pixelsmart_new_format(pstv); > } > > /* > * Parameter set but not used at present. > */ > if ((vp->capturemode & V4L2_CAP_TIMEPERFRAME)) > pstv->capture.timeperframe = vp->timeperframe; > else > pstv->capture.timeperframe = vp->timeperframe; > return 0; > } > > case VIDIOC_REQBUFS: > { > struct v4l2_requestbuffers *req = arg; > > if (pstv->stream_buffers_mapped) > { > printk("Can't request buffers if buffers are already mapped\n"); > return -EPERM; > } > > mmap_unrequest_buffers(pstv); > pixelsmart_begin(pstv); > if (!mmap_request_buffers(pstv, req)) > return -EINVAL; > return 0; > } > case VIDIOC_QUERYBUF: > { > struct v4l2_buffer *buf = arg; > int i; > > i = buf->index; > if (i < 0 || i >= MAX_CAPTURE_BUFFERS || > !pstv->stream_buf[i].requested || > (buf->type & V4L2_BUF_TYPE_field) != > (pstv->stream_buf[i].vidbuf.type & V4L2_BUF_TYPE_field)) > { > printk("QUERYBUF bad parameter\n"); > return -EINVAL; > } > *buf = pstv->stream_buf[i].vidbuf; > return 0; > } > case VIDIOC_QBUF: > { > struct v4l2_buffer *buf = arg; > > if (!pstv->stream_buffers_mapped) > { > printk("QBUF no buffers are mapped\n"); > return -EINVAL; > } > > if (!pixelsmart_queuebuffer(pstv, buf)) > return -EINVAL; > return 0; > } > > case VIDIOC_DQBUF: > { > struct v4l2_buffer *buf = arg; > > if (!pixelsmart_dequeuebuffer(pstv, buf)){ > printk("returns invalid in DQ\n"); > return -EINVAL; > } > printk("return 0 in DQ\n"); > return 0; > } > > case VIDIOC_STREAMON: > { > __u32 *type = arg; > > pixelsmart_init_timer(pstv); > if (!pixelsmart_streamon(pstv, *type)) > return -EINVAL; > return 0; > } > > case VIDIOC_STREAMOFF: > { > __u32 *type = arg; > pixelsmart_streamoff(pstv, *type); > return 0; > } > > case VIDIOC_ENUM_FBUFFMT: > return -EINVAL; > case VIDIOCGFBUF: > case VIDIOC_G_FBUF: > return 0; > case VIDIOC_S_FBUF: > return -EINVAL; > > case VIDIOC_G_WIN: > return -EINVAL; > > case VIDIOC_S_WIN: > return -EINVAL; > > case VIDIOC_PREVIEW: > return -EINVAL; 655,657c811,815 < int *i = (int *)arg; < *i = pstv->input; < break; --- > { > memcpy(arg, &pstv->input, sizeof(pstv->input)); > return 0; > } > 659,660d816 < int input = *(int *)arg; < if (input < 0 || input > pstv->input) 661a818,819 > int input = *(int *)arg; > if (input < 0 || input >= pstv->input){ 665c823 < if (input != pstv->input) --- > if (input != pstv->input){ 667c825,828 < break; --- > } > return 0; > } > 669,670c830,835 < struct v4l2_input *vi = (struct v4l2_input *)arg; < memset(vi,0,sizeof(*vi)); --- > { > struct v4l2_input *vi = arg; > if (vi->index < 0 || vi->index > pstv->input){ > printk ("vi->index = %d\n", vi->index); > return -EINVAL; > } 673,686c838,843 < break; < case VIDIOC_G_STD: < v4l2_std_id *id = (v4l2_std_id *)arg; < *id = V4L2_STD_NTSC; // M or no M?? < break; < case VIDIOC_S_STD: < break; < case VIDIOC_ENUM_FMT: < struct v4l2_fmtdesc *f = (struct v4l2_fmtdesc *)arg; < enum v4l2_buf_type type; < int index; < type = f->type; < /* video capture */ < if(f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { --- > return 0; > } > case VIDIOC_ENUM_PIXFMT: > { > struct v4l2_fmtdesc *f = arg; > if (f->index < 0 || f->index >= NUM_CAPFMT) 687a845,853 > *f = capfmt[f->index]; > return 0; > } > > case VIDIOC_G_STD: > { > struct v4l2_standard *std = arg; > strcpy(std->name,"NTSC"); > return 0; 689,695d854 < index = f->index; < memset(f,0,sizeof(*f)); < f->index = index; < f->type = type; < f->pixelformat = V4L2_PIX_FMT_GREY; < strncpy(f->description,"8 bpp, gray",sizeof("8 bpp, gray")); < break; 697,699c856,859 < struct v4l2_standard *estd = (struct v4l2_standard *)arg; < unsigned int index = estd->index; < if (index < 0 || index > 30) --- > { > struct v4l2_enumstd *estd = arg; > __u32 b, i; > if (estd->index < 0 || estd->index > 30) 701,702c861,875 < estd->index = index; < break; --- > for (b = 1, i = 0; b < 32; ++b) > { > if (((1 << b) & V4L2_STD_NTSC) == 0) > continue; > if (i == estd->index) > { > v4l2_video_std_construct(&estd->std, b, 0); > estd->inputs = (__u32)-1; /* all inputs */ > estd->outputs = 0; > return 0; > } > ++i; > } > return -EINVAL; > } 704c877,878 < struct v4l2_queryctrl *c = (struct v4l2_queryctrl*)arg; --- > { > struct v4l2_queryctrl *c = arg; 705a880 > 716a892 > } 717a894 > { 719,735c896,897 < switch(c->id){ < case V4L2_CID_BRIGHTNESS: < c->value = startup_data[25]; < break; < case V4L2_CID_CONTRAST: < c->value = startup_data[19]; < break; < case V4L2_CID_SATURATION: < c->value = startup_data[18]; < break; < case V4L2_CID_HUE: < c->value = startup_data[7]; < break; < default: < return -EINVAL; < }; < break; --- > return psmart_ctls[c->id].default_value; > } 737,738c899,900 < set_control(pstv,arg); < break; --- > return set_control(pstv,arg); > 747,752c909 < unsigned int data ; < if (down_interruptible(&pstv->sem)) < return -ERESTARTSYS; < data = readb(pstv->pixelsmart_mem + *(char *)arg); < up(&pstv->sem); < return data; --- > return readb(pstv->pixelsmart_mem + *(char *)arg); 753a911 > { 755,756d912 < if (down_interruptible(&pstv->sem)) < return -ERESTARTSYS; 759d914 < up(&pstv->sem); 760a916 > } 762c918,919 < arg = (unsigned long)pstv->pixelsmart_mem; --- > { > arg = (void *)pstv->pixelsmart_mem; 763a921 > } 765,766c923 < if (down_interruptible(&pstv->sem)) < return -ERESTARTSYS; --- > { 768d924 < up(&pstv->sem); 769a926 > } 771,772c928 < if (down_interruptible(&pstv->sem)) < return -ERESTARTSYS; --- > { 776d931 < up(&pstv->sem); 777a933 > } 779,780c935 < if (down_interruptible(&pstv->sem)) < return -ERESTARTSYS; --- > { 784d938 < up(&pstv->sem); 785a940 > } 787,789c942 < if (down_interruptible(&pstv->sem)) < return -ERESTARTSYS; < //set the video in live mode --- > { //set the video in live mode 792d944 < up(&pstv->sem); 793a946 > } 795,797c948 < unsigned int data; < if (down_interruptible(&pstv->sem)) < return -ERESTARTSYS; --- > { 800,802c951,952 < data = (pstv->frame_buffer[p->x * 512 + p->y]); < up(&pstv->sem); < return data; --- > return (pstv->frame_buffer[p->x * 512 + p->y]); > } 804,806c954,955 < if (down_interruptible(&pstv->sem)) < return -ERESTARTSYS; < char **temp = (char **)arg; --- > { > char **temp = arg; 808d956 < up(&pstv->sem); 809a958 > } 816,817c965,966 < /* video device template */ < static struct file_operations ps_fops = --- > > struct v4l2_device pixelsmart_template= 819,820c968,969 < .owner = THIS_MODULE, < .release = pixelsmart_release, --- > .name = "HRT", > .type = V4L2_TYPE_CAPTURE, 822c971 < .read = pixelsmart_read, --- > .close = pixelsmart_close, 828,836d976 < struct video_device pixelsmart_template= < { < .owner = THIS_MODULE, < .name = "HRT", < .type = VID_TYPE_CAPTURE | VID_TYPE_MONOCHROME, < .hardware = VID_HARDWARE_BT848, //TODO change... < .fops = &ps_fops, < }; < 870a1012,1013 > //wait for some time so that it becomes live... if its a valid address!!! > 932c1074 < return 0;//-EBUSY; --- > return 0; 941d1083 < printk ("<1> In If\n"); 945c1087 < //release mem and unmap --- > //release memory and unmap 948d1089 < printk ("<1> In Else\n"); 959a1101 > 964a1107 > 971,972d1113 < printk ("<1> Gone for PCI\n"); < printk ("<1> _mem = %lX len = %lu\n",pstv->pixelsmart_mem,pstv->pixelsmart_len); 979d1120 < 980a1122 > 991d1132 < pstv->depth = 8; 993a1135,1136 > pstv->fbuffer = 0; > pstv->running = 0; 994a1138 > //Initialize the timer 1000,1001d1143 < < //pstv->frame_buffer = (char *)__get_free_pages(GFP_KERNEL,order); 1012,1013c1154,1155 < pstv->capture.timeperframe.numerator = 1001; < pstv->capture.timeperframe.denominator = 30000; --- > pstv->capture.timeperframe = 333667; // Check on this > 1015,1020c1157,1164 < pstv->clientfmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; < pstv->clientfmt.fmt.pix.width = 512; < pstv->clientfmt.fmt.pix.height = 512; < pstv->clientfmt.fmt.pix.pixelformat = V4L2_PIX_FMT_GREY; < pstv->clientfmt.fmt.pix.bytesperline = 0; // 0 or 1???or do i even need it?? < pstv->clientfmt.fmt.pix.sizeimage = 0; --- > pstv->clientfmt.width = 512; > pstv->clientfmt.height = 512; > pstv->clientfmt.depth = 8; > pstv->clientfmt.pixelformat = V4L2_PIX_FMT_GREY; > pstv->clientfmt.flags = 0; > pstv->clientfmt.bytesperline = 0; // 0 or 1???or do i even need it?? > pstv->clientfmt.sizeimage = 0; > pstv->streaming = 0; 1021a1166,1176 > pstv->stream_buffers_mapped = 0; > > > /* Other parameters! */ > pstv->ready_to_capture = 0; > v4l2_q_init(&pstv->stream_q_capture); > v4l2_q_init(&pstv->stream_q_done); > pstv->q_cap_count = 0; > ps_task.routine = capture_frame; > ps_task.data = (void*)pstv; > 1026,1028c1181 < < if (video_register_device(&pstv->video_dev, VFL_TYPE_GRABBER, 0) < 0) < { /* handle error */ --- > if (v4l2_register_device(&pstv->video_dev)){ /* handle error */ 1038c1193 < * Set the routine and data for the timer queue. --- > * Initilize spin locks 1040,1041c1195 < ps_task.routine = capture_frame; < ps_task.data = (void*)pstv; --- > spin_lock_init(&ps_lock); 1056c1212,1214 < pstv->capture_completed = 1; --- > //some time for the timer to stop > mdelay(1000); > 1060a1219,1221 > > > 1063c1224,1225 < video_unregister_device(&pstv->video_dev); --- > > v4l2_unregister_device(&pstv->video_dev); ------Makefile------- 24c24 < SRC = main.c mmap.c --- > SRC = main.c mmap.c stream.c ------mmap.c------- 3a4 > * Also functions used internally for mmap are defined here. 12a14,38 > extern int > pixelsmart_streamon(struct pixelsmart *pstv, > __u32 type); > extern void > pixelsmart_streamoff(struct pixelsmart *pstv, > __u32 type); > > /* > * Get a buffer with the specified offset. > */ > static struct stream_buffer * > mmap_stream_buffer_from_offset(struct pixelsmart *dev, > unsigned long offset) > { > int i; > > offset = offset * PAGE_SIZE; > printk("ofset = %lu dev = %p\n",offset,dev); > for (i = 0; i < MAX_CAPTURE_BUFFERS; ++i) > if (offset == dev->stream_buf[i].vidbuf.offset) > return &dev->stream_buf[i]; > printk("returns NULL\n"); > return NULL; > } > 15a42,57 > static void > pixelsmart_vma_open(struct vm_area_struct *vma) > { > struct v4l2_device *dev = v4l2_device_from_file(vma->vm_file); > struct pixelsmart *pstv = (struct pixelsmart*) dev->priv; > struct stream_buffer *buf; > > if (pstv == NULL) > return; > buf = mmap_stream_buffer_from_offset(pstv, vma->vm_pgoff); > printk("bufferaddress in open = %p !shld be same as in mmap\n",buf); > if(buf == NULL) > return; > ++buf->vma_refcount; > printk("vma_open called\n"); > } 17c59,64 < extern struct pixelsmart *psmart; --- > static void > pixelsmart_vma_close(struct vm_area_struct *vma) > { > struct v4l2_device *dev = v4l2_device_from_file(vma->vm_file); > struct pixelsmart *pstv = (struct pixelsmart*) dev->priv; > struct stream_buffer *buf; 19,20c66,91 < void pixelsmart_vma_open(struct vm_area_struct *vma) < { MOD_INC_USE_COUNT; } --- > printk("vma_close called\n"); > > if (pstv == NULL) > return; > > buf = mmap_stream_buffer_from_offset(pstv, vma->vm_pgoff); > --buf->vma_refcount; > if (buf->vma_refcount > 0) > return; > > if (pstv->streaming) > { > printk("Warning- munmap() called while streaming\n"); > pixelsmart_streamoff(pstv, buf->vidbuf.type); > } > v4l2_q_yank_node(&pstv->stream_q_capture, &buf->qnode); > v4l2_q_yank_node(&pstv->stream_q_done, &buf->qnode); > > if (buf->vaddress != NULL) > vfree(buf->vaddress); > buf->vaddress = NULL; > buf->vidbuf.flags = 0; > > if (pstv->stream_buffers_mapped > 0) > --pstv->stream_buffers_mapped; > } 22,23d92 < void pixelsmart_vma_close(struct vm_area_struct *vma) < { MOD_DEC_USE_COUNT; } 25,28d93 < /* < * To prevent extension of the mapping, cause a bus signal to be sent to the < * faulting process. < */ 30c95,96 < unsigned long address, int write_access) --- > unsigned long address, int write_access)/* Streaming data buffer */ > 32c98,132 < return NOPAGE_SIGBUS; --- > > struct v4l2_device *dev; > struct pixelsmart *pstv; > struct stream_buffer *buf; > unsigned long offset_into_buffer; > struct page *page; > > printk("nopage called \n"); > > dev = v4l2_device_from_file(vma->vm_file); > if (dev == NULL) > return 0; > > pstv = dev->priv; > if (pstv == NULL) > return 0; > > buf = mmap_stream_buffer_from_offset(pstv, vma->vm_pgoff); > > if (buf == NULL) > return 0; > offset_into_buffer = address - vma->vm_start; > if (offset_into_buffer >= buf->vidbuf.length) > { > printk("Attempt to read past end of mmap() buffer\n"); > return 0; > } > page = v4l2_vmalloc_to_page(buf->vaddress + offset_into_buffer); > if (page == 0) > return 0; > > atomic_inc(&page->count); > printk("returned valid page\n"); > return page; > 36c136 < static struct vm_operations_struct pixelsmart_vm_ops = { --- > struct vm_operations_struct pixelsmart_vm_ops = { 44c145 < * Called by the memory map system call --- > * Called by the ioctl REQBUF to request for buffers. 46c147,171 < int pixelsmart_mmap(struct file *filp, struct vm_area_struct *vma) --- > int > mmap_request_buffers(struct pixelsmart *dev, > struct v4l2_requestbuffers *req) > { > int i; > u32 buflen; > u32 type; > > if (dev->stream_buffers_mapped) > return 0;/* can't make requests if buffers are mapped */ > if (req->count < 1) > req->count = 1; > if (req->count > MAX_CAPTURE_BUFFERS) > req->count = MAX_CAPTURE_BUFFERS; > type = V4L2_BUF_TYPE_CAPTURE; > > /* The buffer length needs to be a multiple of the page size */ > buflen = (dev->clientfmt.sizeimage + PAGE_SIZE - 1) > & ~(PAGE_SIZE - 1); > > printk("Granting %d buffers\n",req->count); > > /* Now initialize the buffer structures. Don't allocate the */ > /* buffers until they're mapped. */ > for (i = 0; i < req->count; ++i) 48,49c173,244 < struct video_device *dev = video_devdata(filp); < struct pixelsmart *pstv = dev->priv; --- > dev->stream_buf[i].requested = 1; > dev->stream_buf[i].vidbuf.index = i; > dev->stream_buf[i].vidbuf.type = type; > /* offset must be unique for each buffer, and a multiple */ > /* of PAGE_SIZE on 2.4.x */ > dev->stream_buf[i].vidbuf.offset = PAGE_SIZE * (i+1); > dev->stream_buf[i].vidbuf.length = buflen; > dev->stream_buf[i].vidbuf.bytesused = 0; > dev->stream_buf[i].vidbuf.flags = 0; > dev->stream_buf[i].vidbuf.timestamp = 0; > dev->stream_buf[i].vidbuf.sequence = 0; > memset(&dev->stream_buf[i].vidbuf.timecode, 0, > sizeof(struct v4l2_timecode)); > } > for (i = req->count; i < MAX_CAPTURE_BUFFERS; ++i) > dev->stream_buf[i].requested = 0; > dev->stream_buffers_requested = req->count; > > printk("returning from req_buffer\n"); > return 1; > } > > > /* > * Called by the ioctl REQBUF to request for buffers. > */ > void mmap_unrequest_buffers(struct pixelsmart *dev){ > int i; > > if (dev->stream_buffers_requested == 0 || > dev->stream_buffers_mapped) > return; > for (i = 0; i < MAX_CAPTURE_BUFFERS; ++i) > dev->stream_buf[i].requested = 0; > dev->stream_buffers_requested = 0; > } > > /* > * Called by the memory map system call > */ > int pixelsmart_mmap(void *id, struct vm_area_struct *vma){ > > struct v4l2_device *vdev = (struct v4l2_device *)id; > struct pixelsmart *dev = vdev->priv; > struct stream_buffer *buf = NULL; > int i,offset; > > offset = vma->vm_pgoff * PAGE_SIZE; > printk("<1>mmap 1 ofset = %d vam->start = %lu\n", offset,vma->vm_start); > > for (i = 0; i < MAX_CAPTURE_BUFFERS; ++i) > if (offset == dev->stream_buf[i].vidbuf.offset){ > buf = &dev->stream_buf[i]; > printk("gets a valid offset buf = %p\n",buf); > break; > } > > if (buf == NULL){ > printk("mmap() Invalid offset parameter\n"); > return -EINVAL; //no such buffer > } > > if (buf->vidbuf.length != vma->vm_end - vma->vm_start){ > printk("mmap() Wrong length parameter\n"); > return -EINVAL; //wrong length > } > > if (!buf->requested){ > printk("mmap() Buffer is not available for" > " mapping\n"); > return -EINVAL; //not requested > } 51,71c246,248 < unsigned long off ; < unsigned long physical; < unsigned long vsize; < unsigned long psize; < < if (down_interruptible(&pstv->sem)) < return -ERESTARTSYS; < off = vma->vm_pgoff << PAGE_SHIFT; < physical = psmart->pixelsmart_adr + off; < vsize = vma->vm_end - vma->vm_start; < #ifdef DEBUG < printk("<1>mmap 4 vsize= %ld\n, vm_end = %ld, vm_start = %ld, vm_pgoff=%ld",vsize,vma->vm_end,vma->vm_start,vma->vm_pgoff); < #endif < psize = 0x4000 - off; < if(vsize > psize){ < up(&pstv->sem); < return -EINVAL; < } < if(remap_page_range(vma->vm_start, physical , vsize, vma->vm_page_prot)){ < up(&pstv->sem); < return -EAGAIN; --- > if (buf->vidbuf.flags & V4L2_BUF_FLAG_MAPPED){ > printk("mmap() Buffer is already mapped\n"); > return -EINVAL; //already mapped 72a250,266 > > if (buf->vaddress != NULL) > vfree(buf->vaddress); > > /* > *Allocate virtual memory. This memory is mapped to the buffer in user space. > */ > buf->vaddress = vmalloc(buf->vidbuf.length); > printk("virtual address of buffer = %p and sz = %d\n",buf->vaddress,buf->vidbuf.length); > > if (buf->vaddress == NULL){ > printk("Could not allocate mmap() buffer\n"); > return -ENODEV; > } > > buf->vidbuf.flags |= V4L2_BUF_FLAG_MAPPED; > ++dev->stream_buffers_mapped; 74,75c268,271 < pixelsmart_vma_open(vma); < up(&pstv->sem); --- > if (vma->vm_ops->open) > vma->vm_ops->open(vma); > > //Note: vma->vm_file will be set up by V4L2 ------pixelsmart.h------- 24c24,28 < #include --- > /* > *Uncomment if the printk statements used for debugging purpose are requrired > */ > //#define DEBUG > 26,27d29 < #include < #include 35a38 > #include 42a46 > #include 44,47c48 < #include < #include < #include /* everything... */ < #include --- > #include 50,53d50 < /* < *Uncomment if the printk statements used for debugging purpose are requrired < */ < //#define DEBUG 74c71,74 < struct pixelsmart --- > spinlock_t ps_lock; > > /* Streaming data buffer */ > struct stream_buffer 76c76,88 < struct semaphore sem; /* mutual exclusion semaphore */ --- > struct v4l2_q_node qnode; > struct v4l2_buffer vidbuf; > int requested; > __u8 *vaddress; /* vmalloc() */ > int vma_refcount; > }; > /* > * The maximum number of buffers that can be speicifed by the application > * for streaming. > */ > #define MAX_CAPTURE_BUFFERS 5 // Can be increased to 30 if needed. > > struct pixelsmart{ 78c90 < struct video_device video_dev; --- > struct v4l2_device video_dev; 89d100 < uint depth; /* depth in bits */ 94c104 < struct v4l2_format clientfmt; --- > struct v4l2_pix_format clientfmt; 98a109 > int ready_to_capture; 99a111,118 > int streaming; > struct stream_buffer stream_buf[MAX_CAPTURE_BUFFERS]; > int stream_buffers_requested; > int stream_buffers_mapped; > struct v4l2_queue stream_q_capture; > struct v4l2_queue stream_q_done; > int q_cap_count; > int getmoreframes; 102d120 < unsigned int grab_in_progress; ------README------- 13,14c13,14 < into it or as a module. Also, the videodev module has to be downloaded < and installed from the website: www.bytesex.org --- > into it or as a module. Also, the videodevX module has to be downloaded > and installed from the website: www.thedirks.org/v4l2. 17,20c17,21 < driver. This is the custom version which is V4l2 compatible, except for < the mmap, which is a direct memory mapping of the entire device memory. < This cannot be used for streamnig video by V4l2 test programs, though < read is supported here. --- > driver. This is old V4l2 compatible. > This device can be used for streamnig video by V4l2 test programs. > Streaming has been tested using the xcaptest.c test program available at the > same website as above. > ------Rules.make------- files Rules.make and ../v4l2drivers/Rules.make are the same ------sysdep.h------- files sysdep.h and ../v4l2drivers/sysdep.h are the same ------vidioctl.h------- files vidioctl.h and ../v4l2drivers/vidioctl.h are the same