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

vpfe support component input

add progressive buffer logic to vpfe buffer system,
support dynamic choose the input port,
support ccdc configure for component input port,
add some component standard for v4l2 interface
parent 00d2c3e5
...@@ -27,7 +27,8 @@ void ccdc_reset() ...@@ -27,7 +27,8 @@ void ccdc_reset()
/* disable CCDC */ /* disable CCDC */
ccdc_enable(0); ccdc_enable(0);
/* set all registers to default value */ /* set all registers to default value */
for (i = 0; i <= 0x94; i += 4) { for (i = 0; i <= 0x94; i += 4)
{
regw(0, i); regw(0, i);
} }
regw(0, PCR); regw(0, PCR);
...@@ -60,10 +61,13 @@ void ccdc_setwin(ccdc_params_ycbcr * params) ...@@ -60,10 +61,13 @@ void ccdc_setwin(ccdc_params_ycbcr * params)
vert_start = params->win.top; vert_start = params->win.top;
if (params->frm_fmt == CCDC_FRMFMT_INTERLACED) { if (params->frm_fmt == CCDC_FRMFMT_INTERLACED)
{
vert_nr_lines = (params->win.height >> 1) - 1; vert_nr_lines = (params->win.height >> 1) - 1;
vert_start >>= 1; vert_start >>= 1;
} else { }
else
{
vert_nr_lines = params->win.height - 1; vert_nr_lines = params->win.height - 1;
} }
regw((vert_start << 16) | vert_start, VERT_START); regw((vert_start << 16) | vert_start, VERT_START);
...@@ -79,6 +83,9 @@ void ccdc_config_ycbcr(ccdc_params_ycbcr * params) ...@@ -79,6 +83,9 @@ void ccdc_config_ycbcr(ccdc_params_ycbcr * params)
/* This is important since we assume default values to be set in */ /* This is important since we assume default values to be set in */
/* a lot of registers that we didn't touch */ /* a lot of registers that we didn't touch */
ccdc_reset(); ccdc_reset();
if (params->frm_fmt == CCDC_FRMFMT_INTERLACED)
{
/* configure ccdc register for interlace mode */
/* configure pixel format */ /* configure pixel format */
syn_mode = (params->pix_fmt & 0x3) << 12; syn_mode = (params->pix_fmt & 0x3) << 12;
...@@ -87,13 +94,16 @@ void ccdc_config_ycbcr(ccdc_params_ycbcr * params) ...@@ -87,13 +94,16 @@ void ccdc_config_ycbcr(ccdc_params_ycbcr * params)
syn_mode |= (params->frm_fmt & 0x1) << 7; syn_mode |= (params->frm_fmt & 0x1) << 7;
/* setup BT.656 sync mode */ /* setup BT.656 sync mode */
if (params->bt656_enable) { if (params->bt656_enable)
{
regw(3, REC656IF); regw(3, REC656IF);
/* configure the FID, VD, HD pin polarity */ /* configure the FID, VD, HD pin polarity */
/* fld,hd pol positive, vd negative, 8-bit pack mode */ /* fld,hd pol positive, vd negative, 8-bit pack mode */
syn_mode |= 0x00000F04; syn_mode |= 0x00000F04;
} else {/* y/c external sync mode */ }
else
{/* y/c external sync mode */
syn_mode |= ((params->fid_pol & 0x1) << 4); syn_mode |= ((params->fid_pol & 0x1) << 4);
syn_mode |= ((params->hd_pol & 0x1) << 3); syn_mode |= ((params->hd_pol & 0x1) << 3);
syn_mode |= ((params->vd_pol & 0x1) << 2); syn_mode |= ((params->vd_pol & 0x1) << 2);
...@@ -111,7 +121,8 @@ void ccdc_config_ycbcr(ccdc_params_ycbcr * params) ...@@ -111,7 +121,8 @@ void ccdc_config_ycbcr(ccdc_params_ycbcr * params)
regw(((params->win.width * 2) + 31) & 0xffffffe0, HSIZE_OFF); regw(((params->win.width * 2) + 31) & 0xffffffe0, HSIZE_OFF);
/* configure the memory line offset */ /* configure the memory line offset */
if (params->buf_type == CCDC_BUFTYPE_FLD_INTERLEAVED) { if (params->buf_type == CCDC_BUFTYPE_FLD_INTERLEAVED)
{
/* two fields are interleaved in memory */ /* two fields are interleaved in memory */
regw(0x00000249, SDOFST); regw(0x00000249, SDOFST);
} }
...@@ -121,4 +132,15 @@ void ccdc_config_ycbcr(ccdc_params_ycbcr * params) ...@@ -121,4 +132,15 @@ void ccdc_config_ycbcr(ccdc_params_ycbcr * params)
syn_mode |= (0x1 << 16); syn_mode |= (0x1 << 16);
regw(syn_mode, SYN_MODE); regw(syn_mode, SYN_MODE);
}
else
{
/* configure ccdc register for progressive mode */
regw(0x5a0,HSIZE_OFF);
ccdc_setwin(params);
regw((params->pix_order << 11) | 0x8000, CCDCFG);
regw((0x00031000)|(0x1 << 17)|(0x1 << 16)|(0x1 << 3)|(0x1 << 4), SYN_MODE);
}
} }
...@@ -89,6 +89,9 @@ static struct v4l2_fract ntsc_aspect = VPFE_PIXELASPECT_NTSC; ...@@ -89,6 +89,9 @@ static struct v4l2_fract ntsc_aspect = VPFE_PIXELASPECT_NTSC;
static struct v4l2_fract pal_aspect = VPFE_PIXELASPECT_PAL; static struct v4l2_fract pal_aspect = VPFE_PIXELASPECT_PAL;
static struct v4l2_rect ntscsp_bounds = VPFE_WIN_NTSC_SP; static struct v4l2_rect ntscsp_bounds = VPFE_WIN_NTSC_SP;
static struct v4l2_rect palsp_bounds = VPFE_WIN_PAL_SP; static struct v4l2_rect palsp_bounds = VPFE_WIN_PAL_SP;
static struct v4l2_rect hd_480p_bounds = VPFE_WIN_HD480P;
static struct v4l2_rect hd_720p_bounds = VPFE_WIN_HD720P;
static struct v4l2_rect hd_1080i_bounds = VPFE_WIN_HD1080I;
static struct v4l2_fract sp_aspect = VPFE_PIXELASPECT_NTSC_SP; static struct v4l2_fract sp_aspect = VPFE_PIXELASPECT_NTSC_SP;
#define NTOSD_INPUTS 2 #define NTOSD_INPUTS 2
...@@ -140,6 +143,8 @@ static irqreturn_t vpfe_isr(int irq, void *dev_id) ...@@ -140,6 +143,8 @@ 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
{
/* 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 */
...@@ -187,6 +192,19 @@ static irqreturn_t vpfe_isr(int irq, void *dev_id) ...@@ -187,6 +192,19 @@ static irqreturn_t vpfe_isr(int irq, void *dev_id)
/* go out, but it is not a big deal */ /* go out, but it is not a big deal */
vpfe->field_id = fid; vpfe->field_id = fid;
} }
}
else // progressive mode
{
vpfe->curFrm->state = STATE_DONE;
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"); debug_print(KERN_INFO "interrupt returned.\n");
return IRQ_RETVAL(1); return IRQ_RETVAL(1);
} }
...@@ -332,16 +350,15 @@ static int vpfe_doioctl(struct inode *inode, struct file *file, ...@@ -332,16 +350,15 @@ static int vpfe_doioctl(struct inode *inode, struct file *file,
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_FMT: case VIDIOC_S_FMT:
case VIDIOC_S_STD: case VIDIOC_S_STD:
case VIDIOC_S_CROP:
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; break;
} }
switch (cmd) { switch (cmd) {
case VIDIOC_QUERYCAP: case VIDIOC_QUERYCAP:
{ {
...@@ -483,16 +500,21 @@ static int vpfe_doioctl(struct inode *inode, struct file *file, ...@@ -483,16 +500,21 @@ static int vpfe_doioctl(struct inode *inode, struct file *file,
vpfe->bounds = vpfe->vwin = pal_bounds; vpfe->bounds = vpfe->vwin = pal_bounds;
vpfe->pixelaspect = pal_aspect; vpfe->pixelaspect = pal_aspect;
vpfe->ccdc_params.win = pal_bounds; vpfe->ccdc_params.win = pal_bounds;
vpfe->ccdc_params.frm_fmt = CCDC_FRMFMT_INTERLACED;
vpfe->ccdc_params.pix_fmt = CCDC_PIXFMT_YCBCR_8BIT;
} else if (id & V4L2_STD_525_60) { } else if (id & V4L2_STD_525_60) {
vpfe->std = id; vpfe->std = id;
vpfe->bounds = vpfe->vwin = ntsc_bounds; vpfe->bounds = vpfe->vwin = ntsc_bounds;
vpfe->pixelaspect = ntsc_aspect; vpfe->pixelaspect = ntsc_aspect;
vpfe->ccdc_params.win = ntsc_bounds; vpfe->ccdc_params.win = ntsc_bounds;
vpfe->ccdc_params.frm_fmt = CCDC_FRMFMT_INTERLACED;
vpfe->ccdc_params.pix_fmt = CCDC_PIXFMT_YCBCR_8BIT;
} else if (id & VPFE_STD_625_50_SQP) { } else if (id & VPFE_STD_625_50_SQP) {
vpfe->std = id; vpfe->std = id;
vpfe->bounds = vpfe->vwin = palsp_bounds; vpfe->bounds = vpfe->vwin = palsp_bounds;
vpfe->pixelaspect = sp_aspect; vpfe->pixelaspect = sp_aspect;
vpfe->ccdc_params.frm_fmt = CCDC_FRMFMT_INTERLACED;
vpfe->ccdc_params.pix_fmt = CCDC_PIXFMT_YCBCR_8BIT;
sqp = 1; sqp = 1;
id >>= 32; id >>= 32;
} else if (id & VPFE_STD_525_60_SQP) { } else if (id & VPFE_STD_525_60_SQP) {
...@@ -503,17 +525,29 @@ static int vpfe_doioctl(struct inode *inode, struct file *file, ...@@ -503,17 +525,29 @@ static int vpfe_doioctl(struct inode *inode, struct file *file,
vpfe->bounds = vpfe->vwin = ntscsp_bounds; vpfe->bounds = vpfe->vwin = ntscsp_bounds;
vpfe->pixelaspect = sp_aspect; vpfe->pixelaspect = sp_aspect;
vpfe->ccdc_params.win = ntscsp_bounds; vpfe->ccdc_params.win = ntscsp_bounds;
vpfe->ccdc_params.frm_fmt = CCDC_FRMFMT_INTERLACED;
vpfe->ccdc_params.pix_fmt = CCDC_PIXFMT_YCBCR_8BIT;
} else if (id & VPFE_STD_AUTO) { } else if (id & VPFE_STD_AUTO) {
vpfe->bounds = vpfe->vwin = pal_bounds; vpfe->bounds = vpfe->vwin = pal_bounds;
vpfe->pixelaspect = pal_aspect; vpfe->pixelaspect = pal_aspect;
vpfe->ccdc_params.win = pal_bounds; 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; vpfe->std = id;
} else if (id & VPFE_STD_AUTO_SQP) { } else if (id & VPFE_STD_AUTO_SQP) {
vpfe->std = id; vpfe->std = id;
vpfe->bounds = vpfe->vwin = palsp_bounds; vpfe->bounds = vpfe->vwin = palsp_bounds;
vpfe->pixelaspect = sp_aspect; vpfe->pixelaspect = sp_aspect;
vpfe->ccdc_params.frm_fmt = CCDC_FRMFMT_INTERLACED;
vpfe->ccdc_params.pix_fmt = CCDC_PIXFMT_YCBCR_8BIT;
sqp = 1; sqp = 1;
} else if (id & V4L2_STD_HD_480P) {
vpfe->std = id;
vpfe->bounds = vpfe->vwin = hd_480p_bounds;
vpfe->pixelaspect = sp_aspect; 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 { } else {
ret = -EINVAL; ret = -EINVAL;
} }
...@@ -596,7 +630,6 @@ static int vpfe_doioctl(struct inode *inode, struct file *file, ...@@ -596,7 +630,6 @@ static int vpfe_doioctl(struct inode *inode, struct file *file,
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)
......
...@@ -824,11 +824,11 @@ static int tvp5150_command(struct i2c_client *c, ...@@ -824,11 +824,11 @@ static int tvp5150_command(struct i2c_client *c,
{ {
int input = *(int *)arg; int input = *(int *)arg;
if (input == 0) if (input == 0)
decoder->route.input = TVP5150_COMPOSITE0; decoder->route.input = VPFE_AMUX_COMPOSITE0;
else if (input == 1) else if (input == 1)
decoder->route.input = TVP5150_COMPOSITE1; decoder->route.input = VPFE_AMUX_COMPOSITE1;
else else
decoder->route.input = TVP5150_SVIDEO; return -EINVAL;
tvp5150_selmux(c); tvp5150_selmux(c);
break; break;
} }
...@@ -1156,8 +1156,11 @@ static struct vpfe_capture_device tvp5150_device = { ...@@ -1156,8 +1156,11 @@ static struct vpfe_capture_device tvp5150_device = {
static int __init tvp5150_init(void) static int __init tvp5150_init(void)
{ {
int ret;
i2c_add_driver(&driver); i2c_add_driver(&driver);
return vpfe_capture_device_register(&tvp5150_device); ret = vpfe_capture_device_register(&tvp5150_device);
tvp5150_device_deactive();
return ret;
} }
static void __exit tvp5150_exit(void) static void __exit tvp5150_exit(void)
......
...@@ -723,6 +723,12 @@ typedef __u64 v4l2_std_id; ...@@ -723,6 +723,12 @@ typedef __u64 v4l2_std_id;
#define V4L2_STD_ATSC_8_VSB ((v4l2_std_id)0x01000000) #define V4L2_STD_ATSC_8_VSB ((v4l2_std_id)0x01000000)
#define V4L2_STD_ATSC_16_VSB ((v4l2_std_id)0x02000000) #define V4L2_STD_ATSC_16_VSB ((v4l2_std_id)0x02000000)
/*FOR COMPONENT*/
#define V4L2_STD_HD_480P ((v4l2_std_id)0x04000000)
#define V4L2_STD_HD_576P ((v4l2_std_id)0x08000000)
#define V4L2_STD_HD_720P ((v4l2_std_id)0x10000000)
#define V4L2_STD_HD_1080I ((v4l2_std_id)0x20000000)
/* FIXME: /* FIXME:
Although std_id is 64 bits, there is an issue on PPC32 architecture that Although std_id is 64 bits, there is an issue on PPC32 architecture that
makes switch(__u64) to break. So, there's a hack on v4l2-common.c rounding makes switch(__u64) to break. So, there's a hack on v4l2-common.c rounding
......
...@@ -139,6 +139,12 @@ static inline int ccdc_getfid(void) ...@@ -139,6 +139,12 @@ static inline int ccdc_getfid(void)
int fid = (regr(SYN_MODE) >> 15) & 0x1; int fid = (regr(SYN_MODE) >> 15) & 0x1;
return fid; return fid;
} }
static inline int ccdc_getfidmode(void)
{
int fid = (regr(SYN_MODE) >> 7) & 0x1;
return fid;
}
#endif #endif
#endif /* CCDC_DAVINCI_H */ #endif /* CCDC_DAVINCI_H */
...@@ -53,6 +53,9 @@ ...@@ -53,6 +53,9 @@
#define VPFE_WIN_QCIF {0,0,176,144} #define VPFE_WIN_QCIF {0,0,176,144}
#define VPFE_WIN_QVGA {0,0,320,240} #define VPFE_WIN_QVGA {0,0,320,240}
#define VPFE_WIN_SIF {0,0,352,240} #define VPFE_WIN_SIF {0,0,352,240}
#define VPFE_WIN_HD480P {0,0,720,480}
#define VPFE_WIN_HD720P {0,0,1280,720}
#define VPFE_WIN_HD1080I {0,0,1920,1080}
#define VPFE_CAPTURE_ID_TVP5150 0 #define VPFE_CAPTURE_ID_TVP5150 0
#define VPFE_CAPTURE_ID_TVP7000 1 #define VPFE_CAPTURE_ID_TVP7000 1
......
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