Commit 3560f6dc authored by 吴智聪(John Wu)'s avatar 吴智聪(John Wu)

clean up code and fix some typo in vpfe and tvp7000 code

parent a5555708
...@@ -96,8 +96,8 @@ static struct v4l2_fract sp_aspect = VPFE_PIXELASPECT_NTSC_SP; ...@@ -96,8 +96,8 @@ static struct v4l2_fract sp_aspect = VPFE_PIXELASPECT_NTSC_SP;
#define NTOSD_INPUTS 2 #define NTOSD_INPUTS 2
static struct v4l2_input ntosd_inputs[NTOSD_INPUTS] = { static struct v4l2_input ntosd_inputs[NTOSD_INPUTS] = {
{ 0, "COMPOSITE", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_ALL, 0 }, { 0, "COMPOSITE", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_ALL, 0},
{ 1, "COMPONENT", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_ALL, 0 }, { 1, "COMPONENT", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_ALL, 0},
}; };
static vpfe_obj vpfe_device = { /* the default format is NTSC */ static vpfe_obj vpfe_device = { /* the default format is NTSC */
...@@ -127,7 +127,7 @@ static vpfe_obj vpfe_device = { /* the default format is NTSC */ ...@@ -127,7 +127,7 @@ static vpfe_obj vpfe_device = { /* the default format is NTSC */
.enablebt656sync = TRUE, .enablebt656sync = TRUE,
.squarepixel = FALSE, .squarepixel = FALSE,
}, },
.irqlock = SPIN_LOCK_UNLOCKED .irqlock = SPIN_LOCK_UNLOCKED
}; };
struct v4l2_capability vpfe_drvcap = { struct v4l2_capability vpfe_drvcap = {
...@@ -138,86 +138,98 @@ struct v4l2_capability vpfe_drvcap = { ...@@ -138,86 +138,98 @@ struct v4l2_capability vpfe_drvcap = {
.capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING .capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING
}; };
static irqreturn_t vpfe_isr(int irq, void *dev_id) static irqreturn_t vpfe_isr(int irq, void *dev_id)
{ {
vpfe_obj *vpfe = &vpfe_device; vpfe_obj *vpfe = &vpfe_device;
int fid; int fid;
if (ccdc_getfidmode()) // interlace mode if (ccdc_getfidmode()) // interlace mode
{ {
/* check which field we are in hardware */ /* check which field we are in hardware */
fid = ccdc_getfid(); fid = ccdc_getfid();
vpfe->field_id ^= 1; /* switch the software maintained field id */ vpfe->field_id ^= 1; /* switch the software maintained field id */
debug_print(KERN_INFO "field id = %x:%x.\n", fid, vpfe->field_id); debug_print(KERN_INFO "field id = %x:%x.\n", fid, vpfe->field_id);
if (fid == vpfe->field_id) { /* we are in-sync here, continue */ if (fid == vpfe->field_id)
if (fid == 0) { { /* we are in-sync here, continue */
/* One frame is just being captured. If the next frame if (fid == 0)
is available, release the current frame and move on */ {
if (vpfe->curFrm != vpfe->nextFrm) { /* One frame is just being captured. If the next frame
vpfe->curFrm->state = STATE_DONE; is available, release the current frame and move on */
wake_up_interruptible(&vpfe->curFrm->done); if (vpfe->curFrm != vpfe->nextFrm)
vpfe->curFrm = vpfe->nextFrm; {
} vpfe->curFrm->state = STATE_DONE;
/* based on whether the two fields are stored interleavely */ wake_up_interruptible(&vpfe->curFrm->done);
/* or separately in memory, reconfigure the CCDC memory address */ vpfe->curFrm = vpfe->nextFrm;
if (vpfe->field == V4L2_FIELD_SEQ_TB) { }
u32 addr = vpfe->curFrm->boff + vpfe->field_offset; /* based on whether the two fields are stored interleavely */
ccdc_setfbaddr((unsigned long)addr); /* or separately in memory, reconfigure the CCDC memory address */
} if (vpfe->field == V4L2_FIELD_SEQ_TB)
} else if (fid == 1) { {
/* if one field is just being captured */ u32 addr = vpfe->curFrm->boff + vpfe->field_offset;
/* configure the next frame */ ccdc_setfbaddr((unsigned long)addr);
/* get the next frame from the empty queue */ }
/* if no frame is available, hold on to the current buffer */ }
if (!list_empty(&vpfe->dma_queue) else if (fid == 1)
&& vpfe->curFrm == vpfe->nextFrm) { {
vpfe->nextFrm = list_entry(vpfe->dma_queue.next, /* if one field is just being captured */
struct videobuf_buffer, queue); /* configure the next frame */
list_del(&vpfe->nextFrm->queue); /* get the next frame from the empty queue */
vpfe->nextFrm->state = STATE_ACTIVE; /* if no frame is available, hold on to the current buffer */
ccdc_setfbaddr((unsigned long)vpfe->nextFrm->boff); if (!list_empty(&vpfe->dma_queue)
} && vpfe->curFrm == vpfe->nextFrm)
if (vpfe->mode_changed) { {
ccdc_setwin(&vpfe->ccdc_params); vpfe->nextFrm = list_entry(vpfe->dma_queue.next,
/* update the field offset */ struct videobuf_buffer, queue);
vpfe->field_offset = (vpfe->vwin.height - 2) * vpfe->vwin.width; list_del(&vpfe->nextFrm->queue);
vpfe->mode_changed = FALSE; vpfe->nextFrm->state = STATE_ACTIVE;
} ccdc_setfbaddr((unsigned long)vpfe->nextFrm->boff);
} }
} else if (fid == 0) { if (vpfe->mode_changed)
/* recover from any hardware out-of-sync due to */ {
/* possible switch of video source */ ccdc_setwin(&vpfe->ccdc_params);
/* for fid == 0, sync up the two fids */ /* update the field offset */
/* for fid == 1, no action, one bad frame will */ vpfe->field_offset = (vpfe->vwin.height - 2) * vpfe->vwin.width;
/* go out, but it is not a big deal */ vpfe->mode_changed = FALSE;
vpfe->field_id = fid; }
} }
} }
else // progressive mode else if (fid == 0)
{ {
vpfe->curFrm->state = STATE_DONE; /* recover from any hardware out-of-sync due to */
wake_up_interruptible(&vpfe->curFrm->done); /* possible switch of video source */
if (!list_empty(&vpfe->dma_queue)) /* for fid == 0, sync up the two fids */
{ /* for fid == 1, no action, one bad frame will */
vpfe->curFrm = list_entry(vpfe->dma_queue.next, struct videobuf_buffer, queue); /* go out, but it is not a big deal */
list_del(&vpfe->curFrm->queue); vpfe->field_id = fid;
vpfe->curFrm->state = STATE_ACTIVE; }
ccdc_setfbaddr((unsigned long)vpfe->curFrm->boff); }
} else // progressive mode
} {
debug_print(KERN_INFO "interrupt returned.\n"); vpfe->curFrm->state = STATE_DONE;
return IRQ_RETVAL(1); wake_up_interruptible(&vpfe->curFrm->done);
if (!list_empty(&vpfe->dma_queue))
{
vpfe->curFrm = list_entry(vpfe->dma_queue.next, struct videobuf_buffer, queue);
list_del(&vpfe->curFrm->queue);
vpfe->curFrm->state = STATE_ACTIVE;
ccdc_setfbaddr((unsigned long)vpfe->curFrm->boff);
}
}
debug_print(KERN_INFO "interrupt returned.\n");
return IRQ_RETVAL(1);
} }
/* this is the callback function called from videobuf_qbuf() function */ /* this is the callback function called from videobuf_qbuf() function */
/* the buffer is prepared and queued into the dma queue */ /* the buffer is prepared and queued into the dma queue */
static int buffer_prepare(struct videobuf_queue *q, static int buffer_prepare(struct videobuf_queue *q,
struct videobuf_buffer *vb, struct videobuf_buffer *vb,
enum v4l2_field field) enum v4l2_field field)
{ {
vpfe_obj *vpfe = &vpfe_device; vpfe_obj *vpfe = &vpfe_device;
if (vb->state == STATE_NEEDS_INIT) { if (vb->state == STATE_NEEDS_INIT)
{
vb->width = vpfe->vwin.width; vb->width = vpfe->vwin.width;
vb->height = vpfe->vwin.height; vb->height = vpfe->vwin.height;
vb->size = VPFE_MAX_FBUF_SIZE; vb->size = VPFE_MAX_FBUF_SIZE;
...@@ -235,7 +247,8 @@ buffer_config(struct videobuf_queue *q, unsigned int count) ...@@ -235,7 +247,8 @@ buffer_config(struct videobuf_queue *q, unsigned int count)
vpfe_obj *vpfe = &vpfe_device; vpfe_obj *vpfe = &vpfe_device;
int i; int i;
for(i = 0; i < count; i++) { for (i = 0; i < count; i++)
{
q->bufs[i]->boff = virt_to_phys(vpfe->fbuffers[i]); q->bufs[i]->boff = virt_to_phys(vpfe->fbuffers[i]);
debug_print(KERN_INFO "buffer address: %x\n", q->bufs[i]->boff); debug_print(KERN_INFO "buffer address: %x\n", q->bufs[i]->boff);
} }
...@@ -248,13 +261,16 @@ buffer_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size) ...@@ -248,13 +261,16 @@ buffer_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size)
int i; int i;
*size = VPFE_MAX_FBUF_SIZE; *size = VPFE_MAX_FBUF_SIZE;
for (i = VPFE_DEFNUM_FBUFS; i < *count; i++) { for (i = VPFE_DEFNUM_FBUFS; i < *count; i++)
{
u32 size = PAGE_SIZE << VPFE_MAX_FBUF_ORDER; u32 size = PAGE_SIZE << VPFE_MAX_FBUF_ORDER;
void *mem = (void *)__get_free_pages(GFP_KERNEL |GFP_DMA, void *mem = (void *)__get_free_pages(GFP_KERNEL |GFP_DMA,
VPFE_MAX_FBUF_ORDER); VPFE_MAX_FBUF_ORDER);
if (mem) { if (mem)
{
unsigned long adr = (unsigned long)mem; unsigned long adr = (unsigned long)mem;
while (size > 0) { while (size > 0)
{
/* make sure the frame buffers are never /* make sure the frame buffers are never
swapped out of memory */ swapped out of memory */
SetPageReserved(virt_to_page(adr)); SetPageReserved(virt_to_page(adr));
...@@ -262,7 +278,9 @@ buffer_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size) ...@@ -262,7 +278,9 @@ buffer_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size)
size -= PAGE_SIZE; size -= PAGE_SIZE;
} }
vpfe->fbuffers[i] = mem; vpfe->fbuffers[i] = mem;
} else { }
else
{
break; break;
} }
} }
...@@ -275,7 +293,7 @@ static void buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb) ...@@ -275,7 +293,7 @@ static void buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
{ {
vpfe_obj *vpfe = &vpfe_device; vpfe_obj *vpfe = &vpfe_device;
/* add the buffer to the DMA queue */ /* add the buffer to the DMA queue */
list_add_tail(&vb->queue, &vpfe->dma_queue); list_add_tail(&vb->queue, &vpfe->dma_queue);
vb->state = STATE_QUEUED; vb->state = STATE_QUEUED;
} }
...@@ -283,11 +301,12 @@ static void buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb) ...@@ -283,11 +301,12 @@ static void buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb) static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
{ {
/* free the buffer if it is not one of the 3 allocated at initializaiton time */ /* free the buffer if it is not one of the 3 allocated at initializaiton time */
if(vb->i < vpfe_device.numbuffers if (vb->i < vpfe_device.numbuffers
&& vb->i >= VPFE_DEFNUM_FBUFS && vb->i >= VPFE_DEFNUM_FBUFS
&& vpfe_device.fbuffers[vb->i]){ && vpfe_device.fbuffers[vb->i])
{
free_pages((unsigned long)vpfe_device.fbuffers[vb->i], free_pages((unsigned long)vpfe_device.fbuffers[vb->i],
VPFE_MAX_FBUF_ORDER); VPFE_MAX_FBUF_ORDER);
vpfe_device.fbuffers[vb->i] = NULL; vpfe_device.fbuffers[vb->i] = NULL;
} }
} }
...@@ -329,8 +348,9 @@ static int vpfe_select_capture_device(int id) ...@@ -329,8 +348,9 @@ static int vpfe_select_capture_device(int id)
down_interruptible(&vpfe_device.device_list_lock); down_interruptible(&vpfe_device.device_list_lock);
list_for_each_entry(device, &vpfe_device.capture_device_list, list_for_each_entry(device, &vpfe_device.capture_device_list,
device_list){ device_list){
if (device->id == id) { if (device->id == id)
{
err = vpfe_capture_device_active(device); err = vpfe_capture_device_active(device);
up(&vpfe_device.device_list_lock); up(&vpfe_device.device_list_lock);
return err; return err;
...@@ -342,339 +362,404 @@ static int vpfe_select_capture_device(int id) ...@@ -342,339 +362,404 @@ static int vpfe_select_capture_device(int id)
} }
static int vpfe_doioctl(struct inode *inode, struct file *file, static int vpfe_doioctl(struct inode *inode, struct file *file,
unsigned int cmd, void *arg) unsigned int cmd, void *arg)
{ {
vpfe_obj *vpfe = &vpfe_device; vpfe_obj *vpfe = &vpfe_device;
vpfe_fh *fh = file->private_data; vpfe_fh *fh = file->private_data;
int ret = 0; int ret = 0;
switch (cmd) { switch (cmd)
{
case VIDIOC_S_CTRL: case VIDIOC_S_CTRL:
case VIDIOC_S_CROP: case VIDIOC_S_CROP:
case VIDIOC_S_FMT: case VIDIOC_S_FMT:
case VIDIOC_S_STD: case VIDIOC_S_STD:
ret = v4l2_prio_check(&vpfe->prio, &fh->prio); ret = v4l2_prio_check(&vpfe->prio, &fh->prio);
if (0 != ret) { if (0 != ret)
{
return ret; return ret;
}
break;
}
switch (cmd) {
case VIDIOC_QUERYCAP:
{
struct v4l2_capability *cap = (struct v4l2_capability *)arg;
memset(cap, 0, sizeof(*cap));
*cap = vpfe_drvcap;
break;
}
case VIDIOC_ENUM_FMT:
{
struct v4l2_fmtdesc *fmt = (struct v4l2_fmtdesc *)arg;
u32 index = fmt->index;
memset(fmt, 0, sizeof(*fmt));
fmt->index = index;
if (index == 0) {
/* only yuv4:2:2 format is supported at this point */
fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
strcpy(fmt->description, "YCbCr4:2:2 Interleaved UYUV");
fmt->pixelformat = V4L2_PIX_FMT_UYVY;
} else if (index == 1) {
fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
strcpy(fmt->description, "YCbCr4:2:2 Interleaved YUYV");
fmt->pixelformat = V4L2_PIX_FMT_YUYV;
} else {
ret = -EINVAL;
}
break;
}
case VIDIOC_G_FMT:
{
struct v4l2_format *fmt = (struct v4l2_format *)arg;
if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
ret = -EINVAL;
} else {
struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;
down_interruptible(&vpfe->lock);
pixfmt->width = vpfe->vwin.width;
pixfmt->height = vpfe->vwin.height;
pixfmt->field = vpfe->field;
pixfmt->pixelformat = vpfe->pixelfmt;
pixfmt->bytesperline = pixfmt->width * 2;
pixfmt->sizeimage = pixfmt->bytesperline * pixfmt->height;
pixfmt->colorspace = V4L2_COLORSPACE_SMPTE170M;
up(&vpfe->lock);
} }
break; break;
} }
case VIDIOC_S_FMT: switch (cmd)
{ {
struct v4l2_format *fmt = (struct v4l2_format *)arg; case VIDIOC_QUERYCAP:
struct v4l2_pix_format *pixfmt = &fmt->fmt.pix; {
ccdc_params_ycbcr *params = &vpfe->ccdc_params; struct v4l2_capability *cap = (struct v4l2_capability *)arg;
if (vpfe->started) { /* make sure streaming is not started */ memset(cap, 0, sizeof(*cap));
ret = -EBUSY; *cap = vpfe_drvcap;
break; break;
} }
case VIDIOC_ENUM_FMT:
down_interruptible(&vpfe->lock); {
if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { struct v4l2_fmtdesc *fmt = (struct v4l2_fmtdesc *)arg;
ret = -EINVAL; u32 index = fmt->index;
up(&vpfe->lock); memset(fmt, 0, sizeof(*fmt));
fmt->index = index;
if (index == 0)
{
/* only yuv4:2:2 format is supported at this point */
fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
strcpy(fmt->description, "YCbCr4:2:2 Interleaved UYUV");
fmt->pixelformat = V4L2_PIX_FMT_UYVY;
}
else if (index == 1)
{
fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
strcpy(fmt->description, "YCbCr4:2:2 Interleaved YUYV");
fmt->pixelformat = V4L2_PIX_FMT_YUYV;
}
else
{
ret = -EINVAL;
}
break; break;
} }
if ((pixfmt->width + vpfe->vwin.left <= vpfe->bounds.width) & case VIDIOC_G_FMT:
(pixfmt->height + vpfe->vwin.top <= vpfe->bounds.height)) { {
/* this is the case when no scaling is supported */ struct v4l2_format *fmt = (struct v4l2_format *)arg;
/* crop window is directed modified */ if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
vpfe->vwin.height = pixfmt->height; {
vpfe->vwin.width = pixfmt->width; ret = -EINVAL;
params->win.width = pixfmt->width; }
params->win.height = pixfmt->height; else
} else { {
ret = -EINVAL; struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;
up(&vpfe->lock); down_interruptible(&vpfe->lock);
pixfmt->width = vpfe->vwin.width;
pixfmt->height = vpfe->vwin.height;
pixfmt->field = vpfe->field;
pixfmt->pixelformat = vpfe->pixelfmt;
pixfmt->bytesperline = pixfmt->width * 2;
pixfmt->sizeimage = pixfmt->bytesperline * pixfmt->height;
pixfmt->colorspace = V4L2_COLORSPACE_SMPTE170M;
up(&vpfe->lock);
}
break; break;
} }
/* setup the CCDC parameters accordingly */ case VIDIOC_S_FMT:
if (pixfmt->pixelformat == V4L2_PIX_FMT_YUYV) { {
params->pix_order = CCDC_PIXORDER_YCBYCR; struct v4l2_format *fmt = (struct v4l2_format *)arg;
vpfe->pixelfmt = pixfmt->pixelformat; struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;
} else if (pixfmt->pixelformat == V4L2_PIX_FMT_UYVY) { ccdc_params_ycbcr *params = &vpfe->ccdc_params;
params->pix_order = CCDC_PIXORDER_CBYCRY; if (vpfe->started)
vpfe->pixelfmt = pixfmt->pixelformat; { /* make sure streaming is not started */
} else { ret = -EBUSY;
ret = -EINVAL; /* not supported format */ break;
}
down_interruptible(&vpfe->lock);
if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
{
ret = -EINVAL;
up(&vpfe->lock);
break;
}
if ((pixfmt->width + vpfe->vwin.left <= vpfe->bounds.width) &
(pixfmt->height + vpfe->vwin.top <= vpfe->bounds.height))
{
/* this is the case when no scaling is supported */
/* crop window is directed modified */
vpfe->vwin.height = pixfmt->height;
vpfe->vwin.width = pixfmt->width;
params->win.width = pixfmt->width;
params->win.height = pixfmt->height;
}
else
{
ret = -EINVAL;
up(&vpfe->lock);
break;
}
/* setup the CCDC parameters accordingly */
if (pixfmt->pixelformat == V4L2_PIX_FMT_YUYV)
{
params->pix_order = CCDC_PIXORDER_YCBYCR;
vpfe->pixelfmt = pixfmt->pixelformat;
}
else if (pixfmt->pixelformat == V4L2_PIX_FMT_UYVY)
{
params->pix_order = CCDC_PIXORDER_CBYCRY;
vpfe->pixelfmt = pixfmt->pixelformat;
}
else
{
ret = -EINVAL; /* not supported format */
up(&vpfe->lock);
break;
}
if (pixfmt->field == V4L2_FIELD_NONE ||
pixfmt->field == V4L2_FIELD_INTERLACED)
{
params->buf_type = CCDC_BUFTYPE_FLD_INTERLEAVED;
vpfe->field = pixfmt->field;
}
else if (pixfmt->field == V4L2_FIELD_SEQ_TB)
{
params->buf_type = CCDC_BUFTYPE_FLD_SEPARATED;
vpfe->field = pixfmt->field;
}
else
{
ret = -EINVAL;
}
ret = DEVICE_CMD(ACTIVE_DEVICE(), VIDIOC_S_FMT, arg);
up(&vpfe->lock); up(&vpfe->lock);
break; break;
} }
if (pixfmt->field == V4L2_FIELD_NONE ||
pixfmt->field == V4L2_FIELD_INTERLACED) {
params->buf_type = CCDC_BUFTYPE_FLD_INTERLEAVED;
vpfe->field = pixfmt->field;
} else if (pixfmt->field == V4L2_FIELD_SEQ_TB) {
params->buf_type = CCDC_BUFTYPE_FLD_SEPARATED;
vpfe->field = pixfmt->field;
} else {
ret = -EINVAL;
}
ret = DEVICE_CMD(ACTIVE_DEVICE(), VIDIOC_S_FMT, arg);
up(&vpfe->lock);
break;
}
case VIDIOC_TRY_FMT: case VIDIOC_TRY_FMT:
{ {
struct v4l2_format *fmt = (struct v4l2_format *)arg; struct v4l2_format *fmt = (struct v4l2_format *)arg;
if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
ret = -EINVAL; {
} else {
struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;
if (pixfmt->width > vpfe->bounds.width ||
pixfmt->height > vpfe->bounds.height ||
(pixfmt->pixelformat != V4L2_PIX_FMT_UYVY &&
pixfmt->pixelformat != V4L2_PIX_FMT_YUYV)) {
ret = -EINVAL; ret = -EINVAL;
} }
else
{
struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;
if (pixfmt->width > vpfe->bounds.width ||
pixfmt->height > vpfe->bounds.height ||
(pixfmt->pixelformat != V4L2_PIX_FMT_UYVY &&
pixfmt->pixelformat != V4L2_PIX_FMT_YUYV))
{
ret = -EINVAL;
}
}
break;
} }
break;
}
case VIDIOC_G_STD: case VIDIOC_G_STD:
{ {
v4l2_std_id *id = (v4l2_std_id *) arg; v4l2_std_id *id = (v4l2_std_id *) arg;
*id = vpfe->std; *id = vpfe->std;
break;
}
case VIDIOC_S_STD:
{
v4l2_std_id id = *(v4l2_std_id *) arg;
int sqp = 0;
if (vpfe->started) { /* make sure streaming is not started */
ret = -EBUSY;
break; break;
} }
down_interruptible(&vpfe->lock); case VIDIOC_S_STD:
if (id & V4L2_STD_625_50) { {
vpfe->std = id; v4l2_std_id id = *(v4l2_std_id *) arg;
vpfe->bounds = vpfe->vwin = pal_bounds; int sqp = 0;
vpfe->pixelaspect = pal_aspect;
vpfe->ccdc_params.win = pal_bounds; if (vpfe->started)
vpfe->ccdc_params.frm_fmt = CCDC_FRMFMT_INTERLACED; { /* make sure streaming is not started */
vpfe->ccdc_params.pix_fmt = CCDC_PIXFMT_YCBCR_8BIT; ret = -EBUSY;
} else if (id & V4L2_STD_525_60) { break;
vpfe->std = id; }
vpfe->bounds = vpfe->vwin = ntsc_bounds; down_interruptible(&vpfe->lock);
vpfe->pixelaspect = ntsc_aspect; if (id & V4L2_STD_625_50)
vpfe->ccdc_params.win = ntsc_bounds; {
vpfe->ccdc_params.frm_fmt = CCDC_FRMFMT_INTERLACED; vpfe->std = id;
vpfe->ccdc_params.pix_fmt = CCDC_PIXFMT_YCBCR_8BIT; vpfe->bounds = vpfe->vwin = pal_bounds;
} else if (id & VPFE_STD_625_50_SQP) { vpfe->pixelaspect = pal_aspect;
vpfe->std = id; vpfe->ccdc_params.win = pal_bounds;
vpfe->bounds = vpfe->vwin = palsp_bounds; vpfe->ccdc_params.frm_fmt = CCDC_FRMFMT_INTERLACED;
vpfe->pixelaspect = sp_aspect; vpfe->ccdc_params.pix_fmt = CCDC_PIXFMT_YCBCR_8BIT;
vpfe->ccdc_params.frm_fmt = CCDC_FRMFMT_INTERLACED; }
vpfe->ccdc_params.pix_fmt = CCDC_PIXFMT_YCBCR_8BIT; else if (id & V4L2_STD_525_60)
sqp = 1; {
id >>= 32; vpfe->std = id;
} else if (id & VPFE_STD_525_60_SQP) { vpfe->bounds = vpfe->vwin = ntsc_bounds;
vpfe->std = id; vpfe->pixelaspect = ntsc_aspect;
sqp = 1; vpfe->ccdc_params.win = ntsc_bounds;
vpfe->std = id; vpfe->ccdc_params.frm_fmt = CCDC_FRMFMT_INTERLACED;
id >>= 32; vpfe->ccdc_params.pix_fmt = CCDC_PIXFMT_YCBCR_8BIT;
vpfe->bounds = vpfe->vwin = ntscsp_bounds; }
vpfe->pixelaspect = sp_aspect; else if (id & VPFE_STD_625_50_SQP)
vpfe->ccdc_params.win = ntscsp_bounds; {
vpfe->ccdc_params.frm_fmt = CCDC_FRMFMT_INTERLACED; vpfe->std = id;
vpfe->ccdc_params.pix_fmt = CCDC_PIXFMT_YCBCR_8BIT; vpfe->bounds = vpfe->vwin = palsp_bounds;
} else if (id & VPFE_STD_AUTO) { vpfe->pixelaspect = sp_aspect;
vpfe->bounds = vpfe->vwin = pal_bounds; vpfe->ccdc_params.frm_fmt = CCDC_FRMFMT_INTERLACED;
vpfe->pixelaspect = pal_aspect; vpfe->ccdc_params.pix_fmt = CCDC_PIXFMT_YCBCR_8BIT;
vpfe->ccdc_params.win = pal_bounds; sqp = 1;
vpfe->ccdc_params.frm_fmt = CCDC_FRMFMT_INTERLACED; id >>= 32;
vpfe->ccdc_params.pix_fmt = CCDC_PIXFMT_YCBCR_8BIT; }
vpfe->std = id; else if (id & VPFE_STD_525_60_SQP)
} else if (id & VPFE_STD_AUTO_SQP) { {
vpfe->std = id; vpfe->std = id;
vpfe->bounds = vpfe->vwin = palsp_bounds; sqp = 1;
vpfe->pixelaspect = sp_aspect; vpfe->std = id;
vpfe->ccdc_params.frm_fmt = CCDC_FRMFMT_INTERLACED; id >>= 32;
vpfe->ccdc_params.pix_fmt = CCDC_PIXFMT_YCBCR_8BIT; vpfe->bounds = vpfe->vwin = ntscsp_bounds;
sqp = 1; vpfe->pixelaspect = sp_aspect;
} else if (id & V4L2_STD_HD_480P) { vpfe->ccdc_params.win = ntscsp_bounds;
vpfe->std = id; vpfe->ccdc_params.frm_fmt = CCDC_FRMFMT_INTERLACED;
vpfe->bounds = vpfe->vwin = hd_480p_bounds; vpfe->ccdc_params.pix_fmt = CCDC_PIXFMT_YCBCR_8BIT;
vpfe->pixelaspect = sp_aspect; }
vpfe->ccdc_params.win = hd_480p_bounds; else if (id & VPFE_STD_AUTO)
vpfe->ccdc_params.frm_fmt = CCDC_FRMFMT_PROGRESSIVE; {
vpfe->ccdc_params.pix_fmt = CCDC_PIXFMT_YCBCR_16BIT; vpfe->bounds = vpfe->vwin = pal_bounds;
} else { vpfe->pixelaspect = pal_aspect;
ret = -EINVAL; vpfe->ccdc_params.win = pal_bounds;
} vpfe->ccdc_params.frm_fmt = CCDC_FRMFMT_INTERLACED;
vpfe->ccdc_params.pix_fmt = CCDC_PIXFMT_YCBCR_8BIT;
vpfe->std = id;
}
else if (id & VPFE_STD_AUTO_SQP)
{
vpfe->std = id;
vpfe->bounds = vpfe->vwin = palsp_bounds;
vpfe->pixelaspect = sp_aspect;
vpfe->ccdc_params.frm_fmt = CCDC_FRMFMT_INTERLACED;
vpfe->ccdc_params.pix_fmt = CCDC_PIXFMT_YCBCR_8BIT;
sqp = 1;
}
else if (id & V4L2_STD_HD_480P)
{
vpfe->std = id;
vpfe->bounds = vpfe->vwin = hd_480p_bounds;
vpfe->pixelaspect = sp_aspect;
vpfe->ccdc_params.win = hd_480p_bounds;
vpfe->ccdc_params.frm_fmt = CCDC_FRMFMT_PROGRESSIVE;
vpfe->ccdc_params.pix_fmt = CCDC_PIXFMT_YCBCR_16BIT;
}
else
{
ret = -EINVAL;
}
vpfe->capture_params.mode = id; vpfe->capture_params.mode = id;
vpfe->capture_params.squarepixel = sqp; vpfe->capture_params.squarepixel = sqp;
ret = DEVICE_CMD(ACTIVE_DEVICE(), VPFE_CMD_CONFIG_CAPTURE, &vpfe->capture_params); ret = DEVICE_CMD(ACTIVE_DEVICE(), VPFE_CMD_CONFIG_CAPTURE, &vpfe->capture_params);
up(&vpfe->lock); up(&vpfe->lock);
break; break;
} }
case VIDIOC_ENUMSTD: case VIDIOC_ENUMSTD:
{ {
struct v4l2_standard *std = (struct v4l2_standard *)arg; struct v4l2_standard *std = (struct v4l2_standard *)arg;
u32 index = std->index; u32 index = std->index;
memset(std, 0, sizeof(*std)); memset(std, 0, sizeof(*std));
std->index = index; std->index = index;
if (index == 0) { if (index == 0)
std->id = V4L2_STD_525_60; {
strcpy(std->name, "SD-525line-30fps"); std->id = V4L2_STD_525_60;
std->framelines = 525; strcpy(std->name, "SD-525line-30fps");
std->frameperiod.numerator = 1001; std->framelines = 525;
std->frameperiod.denominator = 30000; std->frameperiod.numerator = 1001;
} else if (index == 1) { std->frameperiod.denominator = 30000;
std->id = V4L2_STD_625_50; }
strcpy(std->name, "SD-625line-25fps"); else if (index == 1)
std->framelines = 625; {
std->frameperiod.numerator = 1; std->id = V4L2_STD_625_50;
std->frameperiod.denominator = 25; strcpy(std->name, "SD-625line-25fps");
} else if (index == 2) { std->framelines = 625;
std->id = VPFE_STD_625_50_SQP; std->frameperiod.numerator = 1;
strcpy(std->name, std->frameperiod.denominator = 25;
"SD-625line-25fps square pixel"); }
std->framelines = 625; else if (index == 2)
std->frameperiod.numerator = 1; {
std->frameperiod.denominator = 25; std->id = VPFE_STD_625_50_SQP;
} else if (index == 3) { strcpy(std->name,
std->id = VPFE_STD_525_60_SQP; "SD-625line-25fps square pixel");
strcpy(std->name, std->framelines = 625;
"SD-525line-25fps square pixel"); std->frameperiod.numerator = 1;
std->framelines = 525; std->frameperiod.denominator = 25;
std->frameperiod.numerator = 1001; }
std->frameperiod.denominator = 30000; else if (index == 3)
} else if (index == 4) { {
std->id = VPFE_STD_AUTO; std->id = VPFE_STD_525_60_SQP;
strcpy(std->name, "automatic detect"); strcpy(std->name,
std->framelines = 625; "SD-525line-25fps square pixel");
std->frameperiod.numerator = 1; std->framelines = 525;
std->frameperiod.denominator = 1; std->frameperiod.numerator = 1001;
} else if (index == 5) { std->frameperiod.denominator = 30000;
std->id = VPFE_STD_AUTO_SQP; }
strcpy(std->name, else if (index == 4)
"automatic detect square pixel"); {
std->framelines = 625; std->id = VPFE_STD_AUTO;
std->frameperiod.numerator = 1; strcpy(std->name, "automatic detect");
std->frameperiod.denominator = 1; std->framelines = 625;
} else { std->frameperiod.numerator = 1;
ret = -EINVAL; std->frameperiod.denominator = 1;
}
else if (index == 5)
{
std->id = VPFE_STD_AUTO_SQP;
strcpy(std->name,
"automatic detect square pixel");
std->framelines = 625;
std->frameperiod.numerator = 1;
std->frameperiod.denominator = 1;
}
else
{
ret = -EINVAL;
}
break;
} }
break;
}
case VIDIOC_ENUMINPUT: case VIDIOC_ENUMINPUT:
{ {
struct v4l2_input *input = (struct v4l2_input *)arg; struct v4l2_input *input = (struct v4l2_input *)arg;
if( input->index < 0 || input->index >= NTOSD_INPUTS) if ( input->index < 0 || input->index >= NTOSD_INPUTS)
ret = -EINVAL; ret = -EINVAL;
memcpy(input, &ntosd_inputs[input->index], sizeof(struct v4l2_input)); memcpy(input, &ntosd_inputs[input->index], sizeof(struct v4l2_input));
break; break;
} }
case VIDIOC_G_INPUT: case VIDIOC_G_INPUT:
{ {
int *index = (int *)arg; int *index = (int *)arg;
*index = vpfe->capture_params.amuxmode; *index = vpfe->capture_params.amuxmode;
break; break;
} }
case VIDIOC_S_INPUT: case VIDIOC_S_INPUT:
{ {
int *index = (int *)arg; int *index = (int *)arg;
if (*index == VPFE_AMUX_COMPOSITE0 || *index == VPFE_AMUX_COMPOSITE1) if (*index == VPFE_AMUX_COMPOSITE0 || *index == VPFE_AMUX_COMPOSITE1)
vpfe_select_capture_device(VPFE_CAPTURE_ID_TVP5150); vpfe_select_capture_device(VPFE_CAPTURE_ID_TVP5150);
else if (*index == VPFE_AMUX_COMPONENT) else if (*index == VPFE_AMUX_COMPONENT)
vpfe_select_capture_device(VPFE_CAPTURE_ID_TVP7000); vpfe_select_capture_device(VPFE_CAPTURE_ID_TVP7000);
else else
return -EINVAL; return -EINVAL;
vpfe->capture_params.amuxmode = *index; vpfe->capture_params.amuxmode = *index;
ret = DEVICE_CMD(ACTIVE_DEVICE(), VIDIOC_S_INPUT, index); ret = DEVICE_CMD(ACTIVE_DEVICE(), VIDIOC_S_INPUT, index);
break; break;
} }
case VIDIOC_CROPCAP: case VIDIOC_CROPCAP:
{ {
struct v4l2_cropcap *cropcap = (struct v4l2_cropcap *)arg; struct v4l2_cropcap *cropcap = (struct v4l2_cropcap *)arg;
cropcap->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; cropcap->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
down_interruptible(&vpfe->lock);
cropcap->bounds = cropcap->defrect = vpfe->vwin;
cropcap->pixelaspect = vpfe->pixelaspect;
up(&vpfe->lock);
break;
}
case VIDIOC_G_PARM:
{
struct v4l2_streamparm *parm = (struct v4l2_streamparm *)arg;
if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
/* only capture is supported */
ret = -EINVAL;
} else {
struct v4l2_captureparm *capparm = &parm->parm.capture;
memset(capparm, 0, sizeof(struct v4l2_captureparm));
down_interruptible(&vpfe->lock); down_interruptible(&vpfe->lock);
if (vpfe->std & V4L2_STD_625_50) { cropcap->bounds = cropcap->defrect = vpfe->vwin;
capparm->timeperframe.numerator = 1; cropcap->pixelaspect = vpfe->pixelaspect;
capparm->timeperframe.denominator = 25; /* PAL 25fps */
} else {
capparm->timeperframe.numerator = 1001;
capparm->timeperframe.denominator = 30000; /*NTSC 29.97fps */
}
capparm->readbuffers = vpfe->numbuffers;
up(&vpfe->lock); up(&vpfe->lock);
break;
}
case VIDIOC_G_PARM:
{
struct v4l2_streamparm *parm = (struct v4l2_streamparm *)arg;
if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
{
/* only capture is supported */
ret = -EINVAL;
}
else
{
struct v4l2_captureparm *capparm = &parm->parm.capture;
memset(capparm, 0, sizeof(struct v4l2_captureparm));
down_interruptible(&vpfe->lock);
if (vpfe->std & V4L2_STD_625_50)
{
capparm->timeperframe.numerator = 1;
capparm->timeperframe.denominator = 25; /* PAL 25fps */
}
else
{
capparm->timeperframe.numerator = 1001;
capparm->timeperframe.denominator = 30000; /*NTSC 29.97fps */
}
capparm->readbuffers = vpfe->numbuffers;
up(&vpfe->lock);
}
break;
} }
break;
}
case VIDIOC_G_CTRL: case VIDIOC_G_CTRL:
down_interruptible(&vpfe->lock); down_interruptible(&vpfe->lock);
...@@ -697,72 +782,80 @@ static int vpfe_doioctl(struct inode *inode, struct file *file, ...@@ -697,72 +782,80 @@ static int vpfe_doioctl(struct inode *inode, struct file *file,
up(&vpfe->lock); up(&vpfe->lock);
break; break;
case VIDIOC_G_CROP: case VIDIOC_G_CROP:
{ {
struct v4l2_crop *crop = arg; struct v4l2_crop *crop = arg;
if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
ret = -EINVAL; {
} else { ret = -EINVAL;
crop->c = vpfe->vwin; }
else
{
crop->c = vpfe->vwin;
}
break;
} }
break;
}
case VIDIOC_S_CROP: case VIDIOC_S_CROP:
{ {
struct v4l2_crop *crop = arg; struct v4l2_crop *crop = arg;
ccdc_params_ycbcr *params = &vpfe->ccdc_params; ccdc_params_ycbcr *params = &vpfe->ccdc_params;
if (vpfe->started) { /* make sure streaming is not started */ if (vpfe->started)
ret = -EBUSY; { /* make sure streaming is not started */
ret = -EBUSY;
break;
}
/*adjust the width to 16 pixel boundry */
crop->c.width = ((crop->c.width + 15 )/16 ) * 16;
/* make sure parameters are valid */
if (crop->type == V4L2_BUF_TYPE_VIDEO_CAPTURE &&
(crop->c.left + crop->c.width <= vpfe->bounds.left + vpfe->bounds.width) &&
(crop->c.top + crop->c.height <= vpfe->bounds.top + vpfe->bounds.height))
{
down_interruptible(&vpfe->lock);
vpfe->vwin = crop->c;
params->win = vpfe->vwin;
up(&vpfe->lock);
}
else
{
ret = -EINVAL;
}
break; break;
} }
/*adjust the width to 16 pixel boundry */ case VIDIOC_QUERYSTD:
crop->c.width = ((crop->c.width + 15 )/16 ) * 16; {
v4l2_std_id *id = (v4l2_std_id *) arg;
down_interruptible(&vpfe->lock);
/* make sure parameters are valid */ ret = DEVICE_CMD(ACTIVE_DEVICE(), VIDIOC_QUERYSTD, id);
if (crop->type == V4L2_BUF_TYPE_VIDEO_CAPTURE &&
(crop->c.left + crop->c.width <= vpfe->bounds.left + vpfe->bounds.width) &&
(crop->c.top + crop->c.height <= vpfe->bounds.top + vpfe->bounds.height)) {
down_interruptible(&vpfe->lock);
vpfe->vwin = crop->c;
params->win = vpfe->vwin;
up(&vpfe->lock); up(&vpfe->lock);
} else { break;
ret = -EINVAL;
} }
break;
}
case VIDIOC_QUERYSTD:
{
v4l2_std_id *id = (v4l2_std_id *) arg;
down_interruptible(&vpfe->lock);
ret = DEVICE_CMD(ACTIVE_DEVICE(), VIDIOC_QUERYSTD, id);
up(&vpfe->lock);
break;
}
case VIDIOC_G_PRIORITY: case VIDIOC_G_PRIORITY:
{ {
enum v4l2_priority *p = arg; enum v4l2_priority *p = arg;
*p = v4l2_prio_max(&vpfe->prio); *p = v4l2_prio_max(&vpfe->prio);
break; break;
} }
case VIDIOC_S_PRIORITY: case VIDIOC_S_PRIORITY:
{ {
enum v4l2_priority *p = arg; enum v4l2_priority *p = arg;
ret = v4l2_prio_change(&vpfe->prio, &fh->prio, *p); ret = v4l2_prio_change(&vpfe->prio, &fh->prio, *p);
break; break;
} }
case VIDIOC_REQBUFS: case VIDIOC_REQBUFS:
if (vpfe->io_usrs != 0) { if (vpfe->io_usrs != 0)
{
ret = -EBUSY; ret = -EBUSY;
break; break;
} }
down_interruptible(&vpfe->lock); down_interruptible(&vpfe->lock);
videobuf_queue_init(&vpfe->bufqueue, &video_qops, NULL, videobuf_queue_init(&vpfe->bufqueue, &video_qops, NULL,
&vpfe->irqlock, V4L2_BUF_TYPE_VIDEO_CAPTURE, vpfe->field, &vpfe->irqlock, V4L2_BUF_TYPE_VIDEO_CAPTURE, vpfe->field,
sizeof(struct videobuf_buffer), fh); sizeof(struct videobuf_buffer), fh);
videobuf_set_buftype(&vpfe->bufqueue, VIDEOBUF_BUF_LINEAR); videobuf_set_buftype(&vpfe->bufqueue, VIDEOBUF_BUF_LINEAR);
...@@ -775,24 +868,26 @@ static int vpfe_doioctl(struct inode *inode, struct file *file, ...@@ -775,24 +868,26 @@ static int vpfe_doioctl(struct inode *inode, struct file *file,
case VIDIOC_QUERYBUF: case VIDIOC_QUERYBUF:
ret = videobuf_querybuf(&vpfe->bufqueue, arg); ret = videobuf_querybuf(&vpfe->bufqueue, arg);
break; break;
case VIDIOC_QBUF: case VIDIOC_QBUF:
if (!fh->io_allowed) if (!fh->io_allowed)
ret = -EACCES; ret = -EACCES;
else else
ret = videobuf_qbuf(&vpfe->bufqueue, arg); ret = videobuf_qbuf(&vpfe->bufqueue, arg);
break; break;
case VIDIOC_DQBUF: case VIDIOC_DQBUF:
if (!fh->io_allowed) if (!fh->io_allowed)
ret = -EACCES; ret = -EACCES;
else else
ret = videobuf_dqbuf(&vpfe->bufqueue, arg, 0); ret = videobuf_dqbuf(&vpfe->bufqueue, arg, 0);
break; break;
case VIDIOC_STREAMON: case VIDIOC_STREAMON:
if (!fh->io_allowed) { if (!fh->io_allowed)
{
ret = -EACCES; ret = -EACCES;
break; break;
} }
if (vpfe->started){ if (vpfe->started)
{
ret = -EBUSY; ret = -EBUSY;
break; break;
} }
...@@ -803,14 +898,15 @@ static int vpfe_doioctl(struct inode *inode, struct file *file, ...@@ -803,14 +898,15 @@ static int vpfe_doioctl(struct inode *inode, struct file *file,
/* get the current and next frame buffers */ /* get the current and next frame buffers */
/* we expect at least one buffer is in driver at this point */ /* we expect at least one buffer is in driver at this point */
/* if not, error is returned */ /* if not, error is returned */
if (list_empty(&vpfe->dma_queue)) { if (list_empty(&vpfe->dma_queue))
{
ret = -EIO; ret = -EIO;
break; break;
} }
debug_print(KERN_INFO "cur frame %x.\n", debug_print(KERN_INFO "cur frame %x.\n",
vpfe->dma_queue.next); vpfe->dma_queue.next);
vpfe->nextFrm = vpfe->curFrm = list_entry(vpfe->dma_queue.next, vpfe->nextFrm = vpfe->curFrm = list_entry(vpfe->dma_queue.next,
struct videobuf_buffer, queue); struct videobuf_buffer, queue);
/* remove the buffer from the queue */ /* remove the buffer from the queue */
list_del(&vpfe->curFrm->queue); list_del(&vpfe->curFrm->queue);
vpfe->curFrm->state = STATE_ACTIVE; vpfe->curFrm->state = STATE_ACTIVE;
...@@ -834,88 +930,106 @@ static int vpfe_doioctl(struct inode *inode, struct file *file, ...@@ -834,88 +930,106 @@ static int vpfe_doioctl(struct inode *inode, struct file *file,
debug_print(KERN_INFO "started video streaming.\n"); debug_print(KERN_INFO "started video streaming.\n");
break; break;
case VIDIOC_STREAMOFF: case VIDIOC_STREAMOFF:
{ {
if (!fh->io_allowed) { if (!fh->io_allowed)
ret = -EACCES; {
break; ret = -EACCES;
} break;
if(!vpfe->started){ }
ret = -EINVAL; if (!vpfe->started)
{
ret = -EINVAL;
break;
}
/* disable CCDC */
down_interruptible(&vpfe->lock);
ccdc_enable(FALSE);
vpfe->started = FALSE;
up(&vpfe->lock);
ret = videobuf_streamoff(&vpfe->bufqueue);
break; break;
} }
/* disable CCDC */
down_interruptible(&vpfe->lock);
ccdc_enable(FALSE);
vpfe->started = FALSE;
up(&vpfe->lock);
ret = videobuf_streamoff(&vpfe->bufqueue);
break;
}
case VPFE_CMD_CONFIG_CCDC: case VPFE_CMD_CONFIG_CCDC:
{ {
/* this can be used directly and bypass the V4L2 APIs */ /* this can be used directly and bypass the V4L2 APIs */
ccdc_params_ycbcr *params = &vpfe->ccdc_params; ccdc_params_ycbcr *params = &vpfe->ccdc_params;
if(vpfe->started){ if (vpfe->started)
/* only allowed if streaming is not started */ {
ret = -EBUSY; /* only allowed if streaming is not started */
ret = -EBUSY;
break;
}
down_interruptible(&vpfe->lock);
/* make sure the other v4l2 related fields
have consistant settings */
*params = (*(ccdc_params_ycbcr *) arg);
vpfe->vwin = params->win;
if (params->buf_type == CCDC_BUFTYPE_FLD_INTERLEAVED)
{
vpfe->field = V4L2_FIELD_INTERLACED;
}
else if (params->buf_type == CCDC_BUFTYPE_FLD_SEPARATED)
{
vpfe->field = V4L2_FIELD_SEQ_TB;
}
if (params->pix_order == CCDC_PIXORDER_YCBYCR)
{
vpfe->pixelfmt = V4L2_PIX_FMT_YUYV;
}
else if (params->pix_order == CCDC_PIXORDER_CBYCRY)
{
vpfe->pixelfmt = V4L2_PIX_FMT_UYVY;
}
up(&vpfe->lock);
break; break;
} }
down_interruptible(&vpfe->lock);
/* make sure the other v4l2 related fields
have consistant settings */
*params = (*(ccdc_params_ycbcr *) arg);
vpfe->vwin = params->win;
if (params->buf_type == CCDC_BUFTYPE_FLD_INTERLEAVED) {
vpfe->field = V4L2_FIELD_INTERLACED;
} else if (params->buf_type == CCDC_BUFTYPE_FLD_SEPARATED) {
vpfe->field = V4L2_FIELD_SEQ_TB;
}
if (params->pix_order == CCDC_PIXORDER_YCBYCR) {
vpfe->pixelfmt = V4L2_PIX_FMT_YUYV;
} else if (params->pix_order == CCDC_PIXORDER_CBYCRY) {
vpfe->pixelfmt = V4L2_PIX_FMT_UYVY;
}
up(&vpfe->lock);
break;
}
case VPFE_CMD_CONFIG_CAPTURE: case VPFE_CMD_CONFIG_CAPTURE:
/* this can be used directly and bypass the V4L2 APIs */ /* this can be used directly and bypass the V4L2 APIs */
{ {
/* the settings here must be consistant with that of the CCDC's, /* the settings here must be consistant with that of the CCDC's,
driver does not check the consistancy */ driver does not check the consistancy */
struct vpfe_capture_params *params = (struct vpfe_capture_param *) arg; struct vpfe_capture_params *params = (struct vpfe_capture_param *) arg;
v4l2_std_id std = 0; v4l2_std_id std = 0;
if(vpfe->started){ if (vpfe->started)
/* only allowed if streaming is not started */ {
ret = -EBUSY; /* only allowed if streaming is not started */
break; ret = -EBUSY;
} break;
down_interruptible(&vpfe->lock); }
down_interruptible(&vpfe->lock);
std = params->mode; std = params->mode;
if (params->squarepixel) { /* square pixel mode */ if (params->squarepixel)
std <<= 32; { /* square pixel mode */
} std <<= 32;
}
if (std & V4L2_STD_625_50) { if (std & V4L2_STD_625_50)
vpfe->bounds = pal_bounds; {
vpfe->pixelaspect = pal_aspect; vpfe->bounds = pal_bounds;
} else if (std & V4L2_STD_525_60) { vpfe->pixelaspect = pal_aspect;
vpfe->bounds = ntsc_bounds; }
vpfe->pixelaspect = ntsc_aspect; else if (std & V4L2_STD_525_60)
} else if (std & VPFE_STD_625_50_SQP) { {
vpfe->bounds = palsp_bounds; vpfe->bounds = ntsc_bounds;
vpfe->pixelaspect = sp_aspect; vpfe->pixelaspect = ntsc_aspect;
} else if (std & VPFE_STD_525_60_SQP) { }
vpfe->bounds = ntscsp_bounds; else if (std & VPFE_STD_625_50_SQP)
vpfe->pixelaspect = sp_aspect; {
vpfe->bounds = palsp_bounds;
vpfe->pixelaspect = sp_aspect;
}
else if (std & VPFE_STD_525_60_SQP)
{
vpfe->bounds = ntscsp_bounds;
vpfe->pixelaspect = sp_aspect;
}
vpfe->std = std;
ret = DEVICE_CMD(ACTIVE_DEVICE(), VPFE_CMD_CONFIG_CAPTURE, params);
vpfe->capture_params = *params;
up(&vpfe->lock);
break;
} }
vpfe->std = std;
ret = DEVICE_CMD(ACTIVE_DEVICE(), VPFE_CMD_CONFIG_CAPTURE, params);
vpfe->capture_params = *params;
up(&vpfe->lock);
break;
}
default: default:
ret = -ENOIOCTLCMD; ret = -ENOIOCTLCMD;
break; break;
...@@ -924,13 +1038,14 @@ static int vpfe_doioctl(struct inode *inode, struct file *file, ...@@ -924,13 +1038,14 @@ static int vpfe_doioctl(struct inode *inode, struct file *file,
} }
static int vpfe_ioctl(struct inode *inode, struct file *file, static int vpfe_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg) unsigned int cmd, unsigned long arg)
{ {
int ret; int ret;
ret = video_usercopy(inode, file, cmd, arg, vpfe_doioctl); ret = video_usercopy(inode, file, cmd, arg, vpfe_doioctl);
if( cmd == VIDIOC_S_FMT || cmd == VIDIOC_TRY_FMT ){ if ( cmd == VIDIOC_S_FMT || cmd == VIDIOC_TRY_FMT )
{
ret = video_usercopy(inode, file, VIDIOC_G_FMT, ret = video_usercopy(inode, file, VIDIOC_G_FMT,
arg, vpfe_doioctl); arg, vpfe_doioctl);
} }
return ret; return ret;
} }
...@@ -949,14 +1064,18 @@ static int vpfe_open(struct inode *inode, struct file *filep) ...@@ -949,14 +1064,18 @@ static int vpfe_open(struct inode *inode, struct file *filep)
debug_print(KERN_INFO "vpfe: open minor=%d\n", minor); debug_print(KERN_INFO "vpfe: open minor=%d\n", minor);
/* check to make sure the minor numbers match */ /* check to make sure the minor numbers match */
if (vpfe_device.video_dev && vpfe_device.video_dev->minor == minor) { if (vpfe_device.video_dev && vpfe_device.video_dev->minor == minor)
{
vpfe = &vpfe_device; vpfe = &vpfe_device;
} else { /* device not found here */ }
else
{ /* device not found here */
return -ENODEV; return -ENODEV;
} }
/* allocate per filehandle data */ /* allocate per filehandle data */
if ((fh = kmalloc(sizeof(*fh), GFP_KERNEL)) == NULL) { if ((fh = kmalloc(sizeof(*fh), GFP_KERNEL)) == NULL)
{
return -ENOMEM; return -ENOMEM;
} }
filep->private_data = fh; filep->private_data = fh;
...@@ -979,7 +1098,8 @@ static int vpfe_release(struct inode *inode, struct file *filep) ...@@ -979,7 +1098,8 @@ static int vpfe_release(struct inode *inode, struct file *filep)
vpfe_obj *vpfe = fh->dev; vpfe_obj *vpfe = fh->dev;
down_interruptible(&vpfe->lock); down_interruptible(&vpfe->lock);
if (fh->io_allowed) { if (fh->io_allowed)
{
vpfe->io_usrs = 0; vpfe->io_usrs = 0;
ccdc_enable(FALSE); ccdc_enable(FALSE);
vpfe->started = FALSE; vpfe->started = FALSE;
...@@ -1022,15 +1142,16 @@ static int __init vpfe_probe(struct device *device) ...@@ -1022,15 +1142,16 @@ static int __init vpfe_probe(struct device *device)
vpfe_obj *vpfe = &vpfe_device; vpfe_obj *vpfe = &vpfe_device;
/* alloc video device */ /* alloc video device */
if ((vfd = video_device_alloc()) == NULL) { if ((vfd = video_device_alloc()) == NULL)
{
return -ENOMEM; return -ENOMEM;
} }
*vfd = vpfe_video_template; *vfd = vpfe_video_template;
vfd->dev = device; vfd->dev = device;
vfd->release = video_device_release; vfd->release = video_device_release;
snprintf(vfd->name, sizeof(vfd->name), "DM644X_VPFE_DRIVER_V%d.%d.%d", snprintf(vfd->name, sizeof(vfd->name), "DM644X_VPFE_DRIVER_V%d.%d.%d",
(VPFE_VERSION_CODE >> 16) & 0xff, (VPFE_VERSION_CODE >> 16) & 0xff,
(VPFE_VERSION_CODE >> 8) & 0xff, (VPFE_VERSION_CODE) & 0xff); (VPFE_VERSION_CODE >> 8) & 0xff, (VPFE_VERSION_CODE) & 0xff);
vpfe->video_dev = vfd; vpfe->video_dev = vfd;
vpfe->usrs = 0; vpfe->usrs = 0;
...@@ -1047,20 +1168,21 @@ static int __init vpfe_probe(struct device *device) ...@@ -1047,20 +1168,21 @@ static int __init vpfe_probe(struct device *device)
/* register video device */ /* register video device */
debug_print(KERN_INFO "trying to register vpfe device.\n"); debug_print(KERN_INFO "trying to register vpfe device.\n");
debug_print(KERN_INFO "vpfe=%x,vpfe->video_dev=%x\n", (int)vpfe, debug_print(KERN_INFO "vpfe=%x,vpfe->video_dev=%x\n", (int)vpfe,
(int)&vpfe->video_dev); (int)&vpfe->video_dev);
if (video_register_device(vpfe->video_dev, VFL_TYPE_GRABBER, -1) < 0) { if (video_register_device(vpfe->video_dev, VFL_TYPE_GRABBER, -1) < 0)
{
video_device_release(vpfe->video_dev); video_device_release(vpfe->video_dev);
vpfe->video_dev = NULL; vpfe->video_dev = NULL;
return -1; return -1;
} }
debug_print(KERN_INFO "DM644X vpfe: driver version V%d.%d.%d loaded\n", debug_print(KERN_INFO "DM644X vpfe: driver version V%d.%d.%d loaded\n",
(VPFE_VERSION_CODE >> 16) & 0xff, (VPFE_VERSION_CODE >> 16) & 0xff,
(VPFE_VERSION_CODE >> 8) & 0xff, (VPFE_VERSION_CODE >> 8) & 0xff,
(VPFE_VERSION_CODE) & 0xff); (VPFE_VERSION_CODE) & 0xff);
debug_print(KERN_INFO "vpfe: registered device video%d\n", debug_print(KERN_INFO "vpfe: registered device video%d\n",
vpfe->video_dev->minor & 0x1f); vpfe->video_dev->minor & 0x1f);
/* all done */ /* all done */
return 0; return 0;
...@@ -1082,7 +1204,7 @@ int vpfe_capture_device_register(struct vpfe_capture_device *device) ...@@ -1082,7 +1204,7 @@ int vpfe_capture_device_register(struct vpfe_capture_device *device)
up(&vpfe_device.lock); up(&vpfe_device.lock);
debug_print(KERN_INFO "VPFE Capture device %s registered, id = %d.\n", debug_print(KERN_INFO "VPFE Capture device %s registered, id = %d.\n",
device->name, device->id); device->name, device->id);
return 0; return 0;
} }
EXPORT_SYMBOL(vpfe_capture_device_register); EXPORT_SYMBOL(vpfe_capture_device_register);
...@@ -1100,7 +1222,8 @@ int vpfe_capture_device_unregister(struct vpfe_capture_device *device) ...@@ -1100,7 +1222,8 @@ int vpfe_capture_device_unregister(struct vpfe_capture_device *device)
down_interruptible(&vpfe_device.lock); down_interruptible(&vpfe_device.lock);
/* if the device to be unregistered is active, /* if the device to be unregistered is active,
deactivate it! */ deactivate it! */
if (IS_ACTIVE(device)) { if (IS_ACTIVE(device))
{
DEVICE_DEACTIVATE(device); DEVICE_DEACTIVATE(device);
SET_ACTIVE_DEVICE(NULL); SET_ACTIVE_DEVICE(NULL);
} }
...@@ -1109,7 +1232,7 @@ int vpfe_capture_device_unregister(struct vpfe_capture_device *device) ...@@ -1109,7 +1232,7 @@ int vpfe_capture_device_unregister(struct vpfe_capture_device *device)
up(&vpfe_device.lock); up(&vpfe_device.lock);
debug_print(KERN_INFO "VPFE Capture device %s unregistered, id = %d\n", debug_print(KERN_INFO "VPFE Capture device %s unregistered, id = %d\n",
device->name, device->id); device->name, device->id);
return 0; return 0;
} }
EXPORT_SYMBOL(vpfe_capture_device_unregister); EXPORT_SYMBOL(vpfe_capture_device_unregister);
...@@ -1121,7 +1244,7 @@ static int capture_device_all_unregister(void) ...@@ -1121,7 +1244,7 @@ static int capture_device_all_unregister(void)
down_interruptible(&vpfe_device.lock); down_interruptible(&vpfe_device.lock);
list_for_each_entry(device, &vpfe_device.capture_device_list, list_for_each_entry(device, &vpfe_device.capture_device_list,
device_list){ device_list){
ret = vpfe_capture_device_unregister(device); ret = vpfe_capture_device_unregister(device);
} }
up(&vpfe_device.lock); up(&vpfe_device.lock);
...@@ -1140,11 +1263,11 @@ static int vpfe_remove(struct device *device) ...@@ -1140,11 +1263,11 @@ static int vpfe_remove(struct device *device)
#ifdef NEW #ifdef NEW
static struct platform_driver vpfe_driver = { static struct platform_driver vpfe_driver = {
.driver = { .driver = {
.name = "VPFE", .name = "VPFE",
.owner = THIS_MODULE, .owner = THIS_MODULE,
}, },
.probe = vpfe_probe, .probe = vpfe_probe,
.remove = vpfe_remove, .remove = vpfe_remove,
}; };
#else #else
...@@ -1170,12 +1293,15 @@ static int vpfe_init(void) ...@@ -1170,12 +1293,15 @@ static int vpfe_init(void)
int result = 0; int result = 0;
void *mem; void *mem;
/* allocate memory at initialization time to guarentee availability */ /* allocate memory at initialization time to guarentee availability */
for (i = 0; i < VPFE_DEFNUM_FBUFS; i++) { for (i = 0; i < VPFE_DEFNUM_FBUFS; i++)
{
mem = (void *)__get_free_pages(GFP_KERNEL | GFP_DMA, VPFE_MAX_FBUF_ORDER); mem = (void *)__get_free_pages(GFP_KERNEL | GFP_DMA, VPFE_MAX_FBUF_ORDER);
if (mem) { if (mem)
{
unsigned long adr = (unsigned long)mem; unsigned long adr = (unsigned long)mem;
u32 size = PAGE_SIZE << VPFE_MAX_FBUF_ORDER; u32 size = PAGE_SIZE << VPFE_MAX_FBUF_ORDER;
while (size > 0) { while (size > 0)
{
/* make sure the frame buffers /* make sure the frame buffers
are never swapped out of memory */ are never swapped out of memory */
SetPageReserved(virt_to_page(adr)); SetPageReserved(virt_to_page(adr));
...@@ -1184,20 +1310,25 @@ static int vpfe_init(void) ...@@ -1184,20 +1310,25 @@ static int vpfe_init(void)
} }
vpfe_device.fbuffers[i] = (u8 *) mem; vpfe_device.fbuffers[i] = (u8 *) mem;
debug_print(KERN_INFO "memory address %d\t%x\n", i, mem); debug_print(KERN_INFO "memory address %d\t%x\n", i, mem);
} else { }
while (--i >= 0) { else
{
while (--i >= 0)
{
free_pages((unsigned long)vpfe_device.fbuffers[i], free_pages((unsigned long)vpfe_device.fbuffers[i],
VPFE_MAX_FBUF_ORDER); VPFE_MAX_FBUF_ORDER);
} }
debug_print(KERN_INFO "frame buffer memory allocation failed.\n"); debug_print(KERN_INFO "frame buffer memory allocation failed.\n");
return -ENOMEM; return -ENOMEM;
} }
} }
if (driver_register(&vpfe_driver) != 0) { if (driver_register(&vpfe_driver) != 0)
{
debug_print(KERN_INFO "driver registration failed\n"); debug_print(KERN_INFO "driver registration failed\n");
return -1; return -1;
} }
if (platform_device_register(&_vpfe_device) != 0) { if (platform_device_register(&_vpfe_device) != 0)
{
driver_unregister(&vpfe_driver); driver_unregister(&vpfe_driver);
debug_print(KERN_INFO "device registration failed\n"); debug_print(KERN_INFO "device registration failed\n");
return -1; return -1;
...@@ -1206,8 +1337,9 @@ static int vpfe_init(void) ...@@ -1206,8 +1337,9 @@ static int vpfe_init(void)
ccdc_reset(); ccdc_reset();
/* setup interrupt handling */ /* setup interrupt handling */
result = request_irq(IRQ_VDINT0, vpfe_isr, IRQF_DISABLED, result = request_irq(IRQ_VDINT0, vpfe_isr, IRQF_DISABLED,
"dm644xv4l2", (void *)&vpfe_device); "dm644xv4l2", (void *)&vpfe_device);
if (result < 0) { if (result < 0)
{
printk(KERN_ERR "DaVinci v4l2 capture driver: cannot initialize IRQ\n"); printk(KERN_ERR "DaVinci v4l2 capture driver: cannot initialize IRQ\n");
return result; return result;
} }
...@@ -1227,9 +1359,10 @@ static void vpfe_cleanup(void) ...@@ -1227,9 +1359,10 @@ static void vpfe_cleanup(void)
/* disable interrupt */ /* disable interrupt */
free_irq(IRQ_VDINT0, &vpfe_device); free_irq(IRQ_VDINT0, &vpfe_device);
while (--i >= 0) { while (--i >= 0)
{
free_pages((unsigned long)vpfe_device.fbuffers[i], free_pages((unsigned long)vpfe_device.fbuffers[i],
VPFE_MAX_FBUF_ORDER); VPFE_MAX_FBUF_ORDER);
} }
debug_print(KERN_INFO "vpfe: un-registered device video.\n"); debug_print(KERN_INFO "vpfe: un-registered device video.\n");
} }
......
...@@ -330,7 +330,7 @@ static const struct tvp7000_video_std video_std[] = { ...@@ -330,7 +330,7 @@ static const struct tvp7000_video_std video_std[] = {
.plldiv_lsb = 0x00, .plldiv_lsb = 0x00,
.pll_ctrl = 0x68, .pll_ctrl = 0x68,
.phase_select_bit0 = 0x01, .phase_select_bit0 = 0x01,
}, },
{ /* VGA standard: 640*480 resolution,72HZ refresh rate, { /* VGA standard: 640*480 resolution,72HZ refresh rate,
37.9kHZ Horizontal frequency,31.5MHZ pixel rate, 37.9kHZ Horizontal frequency,31.5MHZ pixel rate,
*/ */
...@@ -521,7 +521,7 @@ static int tvp7000_detect_client(struct i2c_adapter *adapter, ...@@ -521,7 +521,7 @@ static int tvp7000_detect_client(struct i2c_adapter *adapter,
static inline int tvp7000_read_reg(u8 reg); static inline int tvp7000_read_reg(u8 reg);
static inline int tvp7000_write_reg(u8 reg, u8 value); static inline int tvp7000_write_reg(u8 reg, u8 value);
static int tvp7000_setup_video_stardard(const struct tvp7000_video_std *std); static int tvp7000_setup_video_standard(const struct tvp7000_video_std *std);
static int tvp7000_device_init(struct vpfe_capture_params *params); static int tvp7000_device_init(struct vpfe_capture_params *params);
static int tvp7000_device_cmd(u32 cmd, void *arg); static int tvp7000_device_cmd(u32 cmd, void *arg);
...@@ -545,7 +545,7 @@ static inline int tvp7000_write_reg(u8 reg, u8 value) ...@@ -545,7 +545,7 @@ static inline int tvp7000_write_reg(u8 reg, u8 value)
int ret; int ret;
ret = i2c_smbus_write_byte_data(tvp7000_client, ret = i2c_smbus_write_byte_data(tvp7000_client,
reg, value); reg, value);
if (ret != 0) if (ret != 0)
DPRINTK("Write Error Address = %x\n", reg); DPRINTK("Write Error Address = %x\n", reg);
...@@ -562,7 +562,7 @@ static int tvp7000_write_inittab(const struct i2c_reg_value *regs, int num) ...@@ -562,7 +562,7 @@ static int tvp7000_write_inittab(const struct i2c_reg_value *regs, int num)
for (i=0; i<num; i++) for (i=0; i<num; i++)
err |= tvp7000_write_reg(regs[i].reg, regs[i].value); err |= tvp7000_write_reg(regs[i].reg, regs[i].value);
return err; return err;
} }
...@@ -576,7 +576,8 @@ static int tvp7000_detect_client(struct i2c_adapter *adapter, ...@@ -576,7 +576,8 @@ static int tvp7000_detect_client(struct i2c_adapter *adapter,
FN_IN; FN_IN;
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA |
I2C_FUNC_SMBUS_WRITE_BYTE)) { I2C_FUNC_SMBUS_WRITE_BYTE))
{
DPRINTK("Functionality check failed for %s\n", DPRINTK("Functionality check failed for %s\n",
client_name); client_name);
return err; return err;
...@@ -584,7 +585,8 @@ static int tvp7000_detect_client(struct i2c_adapter *adapter, ...@@ -584,7 +585,8 @@ static int tvp7000_detect_client(struct i2c_adapter *adapter,
tvp7000_client = kmalloc(sizeof(struct i2c_client), tvp7000_client = kmalloc(sizeof(struct i2c_client),
GFP_KERNEL); GFP_KERNEL);
if (tvp7000_client == NULL) { if (tvp7000_client == NULL)
{
err = -ENOMEM; err = -ENOMEM;
DPRINTK("Couldn't allocate memory for %s\n", DPRINTK("Couldn't allocate memory for %s\n",
client_name); client_name);
...@@ -599,7 +601,8 @@ static int tvp7000_detect_client(struct i2c_adapter *adapter, ...@@ -599,7 +601,8 @@ static int tvp7000_detect_client(struct i2c_adapter *adapter,
strlcpy(tvp7000_client->name, client_name, I2C_NAME_SIZE); strlcpy(tvp7000_client->name, client_name, I2C_NAME_SIZE);
err = i2c_attach_client(tvp7000_client); err = i2c_attach_client(tvp7000_client);
if (err) { if (err)
{
DPRINTK("Couldn't attach %s\n", client_name); DPRINTK("Couldn't attach %s\n", client_name);
kfree(tvp7000_client); kfree(tvp7000_client);
return err; return err;
...@@ -622,7 +625,8 @@ static int tvp7000_detach_client(struct i2c_client *client) ...@@ -622,7 +625,8 @@ static int tvp7000_detach_client(struct i2c_client *client)
FN_IN; FN_IN;
err = i2c_detach_client(client); err = i2c_detach_client(client);
if (err) { if (err)
{
DPRINTK("Client deregistration failed, \ DPRINTK("Client deregistration failed, \
client not detached.\n"); client not detached.\n");
return err; return err;
...@@ -638,7 +642,7 @@ static void tvp7000_device_power_on(bool on) ...@@ -638,7 +642,7 @@ static void tvp7000_device_power_on(bool on)
/* enable the GPIO(39) direction mode as output */ /* enable the GPIO(39) direction mode as output */
gpio_direction_output(HD_CAP_GPIO, level); gpio_direction_output(HD_CAP_GPIO, level);
/* when on == true */ /* when on == true */
/* set the Reset pin level as High for 5ms */ /* set the Reset pin level as High for 5ms */
gpio_set_value(HD_CAP_GPIO, level); gpio_set_value(HD_CAP_GPIO, level);
mdelay(5); mdelay(5);
/* pull down the Reset pin level for 5us, /* pull down the Reset pin level for 5us,
...@@ -651,95 +655,91 @@ static void tvp7000_device_power_on(bool on) ...@@ -651,95 +655,91 @@ static void tvp7000_device_power_on(bool on)
udelay(5); udelay(5);
} }
static int tvp7000_setup_video_stardard( static int tvp7000_setup_video_standard(const struct tvp7000_video_std *std)
const struct tvp7000_video_std *std)
{ {
int err = 0; int err = 0;
int val; int val;
if (std == NULL) if (std == NULL)
return -EINVAL; return -EINVAL;
err |= tvp7000_write_reg(TVP7000_PLL_DIVIDE_MSB, err |= tvp7000_write_reg(TVP7000_PLL_DIVIDE_MSB, std->plldiv_msb);
std->plldiv_msb); err |= tvp7000_write_reg(TVP7000_PLL_DIVIDE_LSB, std->plldiv_lsb);
err |= tvp7000_write_reg(TVP7000_PLL_DIVIDE_LSB, err |= tvp7000_write_reg(TVP7000_PLL_CTRL, std->pll_ctrl);
std->plldiv_lsb);
err |= tvp7000_write_reg(TVP7000_PLL_CTRL,
std->pll_ctrl);
val = tvp7000_read_reg(TVP7000_PHASE_SELECT); val = tvp7000_read_reg(TVP7000_PHASE_SELECT);
val &= ~0x01; val &= ~0x01;
err |= tvp7000_write_reg(TVP7000_PHASE_SELECT, err |= tvp7000_write_reg(TVP7000_PHASE_SELECT, (std->phase_select_bit0 & 0x01) | val);
(std->phase_select_bit0 & 0x01) | val);
return err; return err;
} }
static int tvp7000_selmux(void) static int tvp7000_selmux(void)
{ {
if(tvp7000_write_reg(TVP7000_INPUT_MUX_1, 0)) // set channel 1 if (tvp7000_write_reg(TVP7000_INPUT_MUX_1, 0)) // set channel 1
return -1; return -1;
return 0; return 0;
} }
static int input_signal_exist(void) static int input_signal_exist(void)
{ {
int val; int val;
val = tvp7000_read_reg(TVP7000_SYNC_DETECT_STATUS); val = tvp7000_read_reg(TVP7000_SYNC_DETECT_STATUS);
if((val & 0x80) && (val & 0x10)) if ((val & 0x80) && (val & 0x10))
{ {
return 0; return 0;
} }
return -1; return -1;
} }
static int tvp7000_device_cmd(u32 cmd, void *arg) static int tvp7000_device_cmd(u32 cmd, void *arg)
{ {
int ret = 0; int ret = 0;
switch (cmd) { switch (cmd)
{
case 0: case 0:
case VIDIOC_INT_RESET: case VIDIOC_INT_RESET:
tvp7000_device_init(NULL); tvp7000_device_init(NULL);
break; break;
case VIDIOC_G_INPUT: case VIDIOC_G_INPUT:
{ {
if (!input_signal_exist()) if (!input_signal_exist())
*(int *)arg = VPFE_AMUX_COMPONENT; *(int *)arg = VPFE_AMUX_COMPONENT;
else else
ret = -EINVAL; ret = -EINVAL;
break; break;
} }
case VIDIOC_S_INPUT: case VIDIOC_S_INPUT:
{ {
int input = *(int *)arg; int input = *(int *)arg;
if (input == VPFE_AMUX_COMPONENT) if (input == VPFE_AMUX_COMPONENT)
{ {
if(tvp7000_device_init(NULL)) if (tvp7000_device_init(NULL))
ret = -EBUSY; ret = -EBUSY;
} }
else else
ret = -EINVAL; ret = -EINVAL;
break; break;
} }
case VPFE_CMD_CONFIG_CAPTURE: case VPFE_CMD_CONFIG_CAPTURE:
{ {
struct vpfe_capture_params *params = struct vpfe_capture_params *params =
(struct vpfe_capture_params *)arg; (struct vpfe_capture_params *)arg;
if (params->amuxmode == VPFE_AMUX_COMPONENT) if (params->amuxmode == VPFE_AMUX_COMPONENT)
{ {
ret = tvp7000_setup_video_stardard(STD(VIDEO480P60HZ)); ret = tvp7000_setup_video_standard(STD(VIDEO480P60HZ));
} }
else else
ret = -1; ret = -1;
break; break;
} }
default: default:
break; break;
} }
return ret; return ret;
} }
static int tvp7000_device_init(struct vpfe_capture_params *params) static int tvp7000_device_init(struct vpfe_capture_params *params)
...@@ -753,20 +753,20 @@ static int tvp7000_device_init(struct vpfe_capture_params *params) ...@@ -753,20 +753,20 @@ static int tvp7000_device_init(struct vpfe_capture_params *params)
/* initialize TVP7000 as its default values */ /* initialize TVP7000 as its default values */
tvp7000_write_inittab(tvp7000_init_default, NUM_OF_REGS(tvp7000_init_default)); tvp7000_write_inittab(tvp7000_init_default, NUM_OF_REGS(tvp7000_init_default));
tvp7000_write_inittab(tvp7000_init_component, NUM_OF_REGS(tvp7000_init_component)); tvp7000_write_inittab(tvp7000_init_component, NUM_OF_REGS(tvp7000_init_component));
if(tvp7000_selmux()) if (tvp7000_selmux())
return -1; return -1;
return 0; return 0;
} }
static int tvp7000_device_active(void) static int tvp7000_device_active(void)
{ {
tvp7000_device_power_on(true); tvp7000_device_power_on(true);
return 0; return 0;
} }
static int tvp7000_device_deactive(void) static int tvp7000_device_deactive(void)
{ {
tvp7000_device_power_on(false); tvp7000_device_power_on(false);
return 0; return 0;
} }
...@@ -776,11 +776,11 @@ static int tvp7000_device_cleanup(void) ...@@ -776,11 +776,11 @@ static int tvp7000_device_cleanup(void)
return 0; return 0;
} }
static struct vpfe_capture_device tvp7000_capture_device = { static struct vpfe_capture_device tvp7000_capture_device = {
.name = "TVP7000", .name = "TVP7000",
.id = VPFE_CAPTURE_ID_TVP7000, .id = VPFE_CAPTURE_ID_TVP7000,
.capture_device_init = tvp7000_device_init, .capture_device_init = tvp7000_device_init,
.capture_device_cmd = tvp7000_device_cmd, .capture_device_cmd = tvp7000_device_cmd,
.capture_device_active = tvp7000_device_active, .capture_device_active = tvp7000_device_active,
.capture_device_deactive = tvp7000_device_deactive, .capture_device_deactive = tvp7000_device_deactive,
.capture_device_cleanup = tvp7000_device_cleanup, .capture_device_cleanup = tvp7000_device_cleanup,
...@@ -788,30 +788,32 @@ static struct vpfe_capture_device tvp7000_capture_device = { ...@@ -788,30 +788,32 @@ static struct vpfe_capture_device tvp7000_capture_device = {
static __init int tvp7000_init(void) static __init int tvp7000_init(void)
{ {
int i; int i;
int err = 0; int err = 0;
FN_IN; FN_IN;
/* power on the tvp7000 Video decoder*/ /* power on the tvp7000 Video decoder*/
tvp7000_device_power_on(true); tvp7000_device_power_on(true);
mdelay(500); mdelay(500);
for (i = 0; i < TVP7000_I2C_RETRY; i++) for (i = 0; i < TVP7000_I2C_RETRY; i++)
{ {
err = i2c_add_driver(&tvp7000_driver); err = i2c_add_driver(&tvp7000_driver);
if (!err) if (!err)
{ {
break; break;
} }
} }
if (err) { if (err)
DPRINTK("I2C driver %s add failed\n", {
tvp7000_driver.driver.name); DPRINTK("I2C driver %s add failed\n",
return err; tvp7000_driver.driver.name);
} return err;
}
err = vpfe_capture_device_register(&tvp7000_capture_device); err = vpfe_capture_device_register(&tvp7000_capture_device);
if (err) { if (err)
{
DPRINTK("VPFE Capture Device %s register failed\n", DPRINTK("VPFE Capture Device %s register failed\n",
tvp7000_capture_device.name); tvp7000_capture_device.name);
return err; return err;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment