From 63ab1bdc3b98b804f69bd345b1e3a491804c12de Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 20 Jan 2007 13:58:33 -0300 Subject: [PATCH] V4L/DVB (5102): make videodev to auto-generate standards v4l2_tvnorm were meant to describe video standards and its names to V4L2 API. However, this were doing by some static structures at the driver. This patch changes the internals in a way that, at the driver, only a v4l2_tvnorm (a 64 bit integer) should be filled, with all supported tvnorms. videodev will dynamically generate the proper API array based on supported standards. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx88/cx88-core.c | 75 ++++++++++++++------------- drivers/media/video/cx88/cx88-vbi.c | 4 +- drivers/media/video/cx88/cx88-video.c | 71 ++++--------------------- drivers/media/video/cx88/cx88.h | 21 +++++--- 4 files changed, 63 insertions(+), 108 deletions(-) diff --git a/drivers/media/video/cx88/cx88-core.c b/drivers/media/video/cx88/cx88-core.c index a51a3b76b1..d86813be56 100644 --- a/drivers/media/video/cx88/cx88-core.c +++ b/drivers/media/video/cx88/cx88-core.c @@ -636,30 +636,30 @@ int cx88_reset(struct cx88_core *core) /* ------------------------------------------------------------------ */ -static unsigned int inline norm_swidth(struct v4l2_tvnorm *norm) +static unsigned int inline norm_swidth(v4l2_std_id norm) { - return (norm->id & (V4L2_STD_MN & ~V4L2_STD_PAL_Nc)) ? 754 : 922; + return (norm & (V4L2_STD_MN & ~V4L2_STD_PAL_Nc)) ? 754 : 922; } -static unsigned int inline norm_hdelay(struct v4l2_tvnorm *norm) +static unsigned int inline norm_hdelay(v4l2_std_id norm) { - return (norm->id & (V4L2_STD_MN & ~V4L2_STD_PAL_Nc)) ? 135 : 186; + return (norm & (V4L2_STD_MN & ~V4L2_STD_PAL_Nc)) ? 135 : 186; } -static unsigned int inline norm_vdelay(struct v4l2_tvnorm *norm) +static unsigned int inline norm_vdelay(v4l2_std_id norm) { - return (norm->id & V4L2_STD_625_50) ? 0x24 : 0x18; + return (norm & V4L2_STD_625_50) ? 0x24 : 0x18; } -static unsigned int inline norm_fsc8(struct v4l2_tvnorm *norm) +static unsigned int inline norm_fsc8(v4l2_std_id norm) { - if (norm->id & V4L2_STD_PAL_M) + if (norm & V4L2_STD_PAL_M) return 28604892; // 3.575611 MHz - if (norm->id & (V4L2_STD_PAL_Nc)) + if (norm & (V4L2_STD_PAL_Nc)) return 28656448; // 3.582056 MHz - if (norm->id & V4L2_STD_NTSC) // All NTSC/M and variants + if (norm & V4L2_STD_NTSC) // All NTSC/M and variants return 28636360; // 3.57954545 MHz +/- 10 Hz /* SECAM have also different sub carrier for chroma, @@ -671,20 +671,20 @@ static unsigned int inline norm_fsc8(struct v4l2_tvnorm *norm) return 35468950; // 4.43361875 MHz +/- 5 Hz } -static unsigned int inline norm_htotal(struct v4l2_tvnorm *norm) +static unsigned int inline norm_htotal(v4l2_std_id norm) { unsigned int fsc4=norm_fsc8(norm)/2; /* returns 4*FSC / vtotal / frames per seconds */ - return (norm->id & V4L2_STD_625_50) ? + return (norm & V4L2_STD_625_50) ? ((fsc4+312)/625+12)/25 : ((fsc4+262)/525*1001+15000)/30000; } -static unsigned int inline norm_vbipack(struct v4l2_tvnorm *norm) +static unsigned int inline norm_vbipack(v4l2_std_id norm) { - return (norm->id & V4L2_STD_625_50) ? 511 : 400; + return (norm & V4L2_STD_625_50) ? 511 : 400; } int cx88_set_scale(struct cx88_core *core, unsigned int width, unsigned int height, @@ -697,7 +697,7 @@ int cx88_set_scale(struct cx88_core *core, unsigned int width, unsigned int heig dprintk(1,"set_scale: %dx%d [%s%s,%s]\n", width, height, V4L2_FIELD_HAS_TOP(field) ? "T" : "", V4L2_FIELD_HAS_BOTTOM(field) ? "B" : "", - core->tvnorm->name); + v4l2_norm_to_name(core->tvnorm)); if (!V4L2_FIELD_HAS_BOTH(field)) height *= 2; @@ -734,7 +734,7 @@ int cx88_set_scale(struct cx88_core *core, unsigned int width, unsigned int heig // setup filters value = 0; value |= (1 << 19); // CFILT (default) - if (core->tvnorm->id & V4L2_STD_SECAM) { + if (core->tvnorm & V4L2_STD_SECAM) { value |= (1 << 15); value |= (1 << 16); } @@ -831,36 +831,36 @@ int cx88_stop_audio_dma(struct cx88_core *core) static int set_tvaudio(struct cx88_core *core) { - struct v4l2_tvnorm *norm = core->tvnorm; + v4l2_std_id norm = core->tvnorm; if (CX88_VMUX_TELEVISION != INPUT(core->input)->type) return 0; - if (V4L2_STD_PAL_BG & norm->id) { + if (V4L2_STD_PAL_BG & norm) { core->tvaudio = WW_BG; - } else if (V4L2_STD_PAL_DK & norm->id) { + } else if (V4L2_STD_PAL_DK & norm) { core->tvaudio = WW_DK; - } else if (V4L2_STD_PAL_I & norm->id) { + } else if (V4L2_STD_PAL_I & norm) { core->tvaudio = WW_I; - } else if (V4L2_STD_SECAM_L & norm->id) { + } else if (V4L2_STD_SECAM_L & norm) { core->tvaudio = WW_L; - } else if (V4L2_STD_SECAM_DK & norm->id) { + } else if (V4L2_STD_SECAM_DK & norm) { core->tvaudio = WW_DK; - } else if ((V4L2_STD_NTSC_M & norm->id) || - (V4L2_STD_PAL_M & norm->id)) { + } else if ((V4L2_STD_NTSC_M & norm) || + (V4L2_STD_PAL_M & norm)) { core->tvaudio = WW_BTSC; - } else if (V4L2_STD_NTSC_M_JP & norm->id) { + } else if (V4L2_STD_NTSC_M_JP & norm) { core->tvaudio = WW_EIAJ; } else { printk("%s/0: tvaudio support needs work for this tv norm [%s], sorry\n", - core->name, norm->name); + core->name, v4l2_norm_to_name(core->tvnorm)); core->tvaudio = 0; return 0; } @@ -879,7 +879,7 @@ static int set_tvaudio(struct cx88_core *core) -int cx88_set_tvnorm(struct cx88_core *core, struct v4l2_tvnorm *norm) +int cx88_set_tvnorm(struct cx88_core *core, v4l2_std_id norm) { u32 fsc8; u32 adc_clock; @@ -896,28 +896,28 @@ int cx88_set_tvnorm(struct cx88_core *core, struct v4l2_tvnorm *norm) step_db = fsc8; step_dr = fsc8; - if (norm->id & V4L2_STD_NTSC_M_JP) { + if (norm & V4L2_STD_NTSC_M_JP) { cxiformat = VideoFormatNTSCJapan; cxoformat = 0x181f0008; - } else if (norm->id & V4L2_STD_NTSC_443) { + } else if (norm & V4L2_STD_NTSC_443) { cxiformat = VideoFormatNTSC443; cxoformat = 0x181f0008; - } else if (norm->id & V4L2_STD_PAL_M) { + } else if (norm & V4L2_STD_PAL_M) { cxiformat = VideoFormatPALM; cxoformat = 0x1c1f0008; - } else if (norm->id & V4L2_STD_PAL_N) { + } else if (norm & V4L2_STD_PAL_N) { cxiformat = VideoFormatPALN; cxoformat = 0x1c1f0008; - } else if (norm->id & V4L2_STD_PAL_Nc) { + } else if (norm & V4L2_STD_PAL_Nc) { cxiformat = VideoFormatPALNC; cxoformat = 0x1c1f0008; - } else if (norm->id & V4L2_STD_PAL_60) { + } else if (norm & V4L2_STD_PAL_60) { cxiformat = VideoFormatPAL60; cxoformat = 0x181f0008; - } else if (norm->id & V4L2_STD_NTSC) { + } else if (norm & V4L2_STD_NTSC) { cxiformat = VideoFormatNTSC; cxoformat = 0x181f0008; - } else if (norm->id & V4L2_STD_SECAM) { + } else if (norm & V4L2_STD_SECAM) { step_db = 4250000 * 8; step_dr = 4406250 * 8; @@ -929,7 +929,8 @@ int cx88_set_tvnorm(struct cx88_core *core, struct v4l2_tvnorm *norm) } dprintk(1,"set_tvnorm: \"%s\" fsc8=%d adc=%d vdec=%d db/dr=%d/%d\n", - norm->name, fsc8, adc_clock, vdec_clock, step_db, step_dr); + v4l2_norm_to_name(core->tvnorm), fsc8, adc_clock, vdec_clock, + step_db, step_dr); set_pll(core,2,vdec_clock); dprintk(1,"set_tvnorm: MO_INPUT_FORMAT 0x%08x [old=0x%08x]\n", @@ -988,7 +989,7 @@ int cx88_set_tvnorm(struct cx88_core *core, struct v4l2_tvnorm *norm) set_tvaudio(core); // tell i2c chips - cx88_call_i2c_clients(core,VIDIOC_S_STD,&norm->id); + cx88_call_i2c_clients(core,VIDIOC_S_STD,&norm); // done return 0; diff --git a/drivers/media/video/cx88/cx88-vbi.c b/drivers/media/video/cx88/cx88-vbi.c index b6b968851d..86c1cf8334 100644 --- a/drivers/media/video/cx88/cx88-vbi.c +++ b/drivers/media/video/cx88/cx88-vbi.c @@ -33,13 +33,13 @@ int cx8800_vbi_fmt (struct file *file, void *priv, f->fmt.vbi.count[0] = VBI_LINE_COUNT; f->fmt.vbi.count[1] = VBI_LINE_COUNT; - if (dev->core->tvnorm->id & V4L2_STD_525_60) { + if (dev->core->tvnorm & V4L2_STD_525_60) { /* ntsc */ f->fmt.vbi.sampling_rate = 28636363; f->fmt.vbi.start[0] = 10; f->fmt.vbi.start[1] = 273; - } else if (dev->core->tvnorm->id & V4L2_STD_625_50) { + } else if (dev->core->tvnorm & V4L2_STD_625_50) { /* pal */ f->fmt.vbi.sampling_rate = 35468950; f->fmt.vbi.start[0] = 7 -1; diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c index 85e51831e7..8ba9942732 100644 --- a/drivers/media/video/cx88/cx88-video.c +++ b/drivers/media/video/cx88/cx88-video.c @@ -86,56 +86,7 @@ static LIST_HEAD(cx8800_devlist); /* ------------------------------------------------------------------- */ /* static data */ -struct v4l2_tvnorm cx88_tvnorms[] = { - { - .name = "NTSC-M", - .id = V4L2_STD_NTSC_M, - },{ - .name = "NTSC-JP", - .id = V4L2_STD_NTSC_M_JP, - },{ - .name = "NTSC-4.43", - .id = V4L2_STD_NTSC_443, - },{ - .name = "PAL-BG", - .id = V4L2_STD_PAL_BG, - },{ - .name = "PAL-DK", - .id = V4L2_STD_PAL_DK, - },{ - .name = "PAL-I", - .id = V4L2_STD_PAL_I, - },{ - .name = "PAL-M", - .id = V4L2_STD_PAL_M, - },{ - .name = "PAL-N", - .id = V4L2_STD_PAL_N, - },{ - .name = "PAL-Nc", - .id = V4L2_STD_PAL_Nc, - },{ - .name = "PAL-60", - .id = V4L2_STD_PAL_60, - },{ - .name = "SECAM-L", - .id = V4L2_STD_SECAM_L, - },{ - .name = "SECAM-DK", - .id = V4L2_STD_SECAM_DK, - } -}; -EXPORT_SYMBOL(cx88_tvnorms); - -unsigned int cx88_tvnormsize=ARRAY_SIZE(cx88_tvnorms); -EXPORT_SYMBOL(cx88_tvnormsize); - -static struct v4l2_tvnorm radionorms[] = { - { - .name = "RADIO", - .id = 0, - } -}; +v4l2_std_id radionorms[] = { 0 }; static struct cx8800_fmt formats[] = { { @@ -999,7 +950,7 @@ int cx88_set_control(struct cx88_core *core, struct v4l2_control *ctl) value = ((ctl->value - c->off) << c->shift) & c->mask; - if (core->tvnorm->id & V4L2_STD_SECAM) { + if (core->tvnorm & V4L2_STD_SECAM) { /* For SECAM, both U and V sat should be equal */ value=value<<8|value; } else { @@ -1242,13 +1193,14 @@ static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i) return 0; } -static int vidioc_s_std (struct file *file, void *priv, unsigned int i) +static int vidioc_s_std (struct file *file, void *priv, v4l2_std_id *tvnorms) { struct cx88_core *core = ((struct cx8800_fh *)priv)->dev->core; mutex_lock(&core->lock); - cx88_set_tvnorm(core,&cx88_tvnorms[i]); + cx88_set_tvnorm(core,*tvnorms); mutex_unlock(&core->lock); + return 0; } @@ -1280,8 +1232,7 @@ int cx88_enum_input (struct cx88_core *core,struct v4l2_input *i) if ((CX88_VMUX_TELEVISION == INPUT(n)->type) || (CX88_VMUX_CABLE == INPUT(n)->type)) i->type = V4L2_INPUT_TYPE_TUNER; - for (n = 0; n < ARRAY_SIZE(cx88_tvnorms); n++) - i->std |= cx88_tvnorms[n].id; + i->std = CX88_NORMS; return 0; } EXPORT_SYMBOL(cx88_enum_input); @@ -1703,8 +1654,8 @@ static struct video_device cx8800_video_template = .vidioc_s_tuner = vidioc_s_tuner, .vidioc_g_frequency = vidioc_g_frequency, .vidioc_s_frequency = vidioc_s_frequency, - .tvnorms = cx88_tvnorms, - .tvnormsize = ARRAY_SIZE(cx88_tvnorms), + .tvnorms = CX88_NORMS, + .current_norm = V4L2_STD_PAL_BG, }; static const struct file_operations radio_fops = @@ -1736,8 +1687,6 @@ static struct video_device cx8800_radio_template = .vidioc_s_ctrl = vidioc_s_ctrl, .vidioc_g_frequency = vidioc_g_frequency, .vidioc_s_frequency = vidioc_s_frequency, - .tvnorms = radionorms, - .tvnormsize = ARRAY_SIZE(radionorms), }; /* ----------------------------------------------------------- */ @@ -1815,7 +1764,7 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev, /* initialize driver struct */ spin_lock_init(&dev->slock); - core->tvnorm = cx88_tvnorms; + core->tvnorm = cx8800_video_template.current_norm; /* init video dma queues */ INIT_LIST_HEAD(&dev->vidq.active); @@ -1896,7 +1845,7 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev, /* initial device configuration */ mutex_lock(&core->lock); - cx88_set_tvnorm(core,cx88_tvnorms); + cx88_set_tvnorm(core,core->tvnorm); init_controls(core); cx88_video_mux(core,0); mutex_unlock(&core->lock); diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h index 5d2f40fe5b..a4f4958699 100644 --- a/drivers/media/video/cx88/cx88.h +++ b/drivers/media/video/cx88/cx88.h @@ -50,6 +50,13 @@ /* ----------------------------------------------------------- */ /* defines and enums */ +/* Currently unsupported by the driver: PAL/H, NTSC/Kr, SECAM B/G/H/LC */ +#define CX88_NORMS (\ + V4L2_STD_NTSC_M| V4L2_STD_NTSC_M_JP| V4L2_STD_NTSC_443 | \ + V4L2_STD_PAL_BG| V4L2_STD_PAL_DK | V4L2_STD_PAL_I | \ + V4L2_STD_PAL_M | V4L2_STD_PAL_N | V4L2_STD_PAL_Nc | \ + V4L2_STD_PAL_60| V4L2_STD_SECAM_L | V4L2_STD_SECAM_DK ) + #define FORMAT_FLAGS_PACKED 0x01 #define FORMAT_FLAGS_PLANAR 0x02 @@ -82,15 +89,15 @@ enum cx8802_board_access { /* ----------------------------------------------------------- */ /* tv norms */ -static unsigned int inline norm_maxw(struct v4l2_tvnorm *norm) +static unsigned int inline norm_maxw(v4l2_std_id norm) { - return (norm->id & (V4L2_STD_MN & ~V4L2_STD_PAL_Nc)) ? 720 : 768; + return (norm & (V4L2_STD_MN & ~V4L2_STD_PAL_Nc)) ? 720 : 768; } -static unsigned int inline norm_maxh(struct v4l2_tvnorm *norm) +static unsigned int inline norm_maxh(v4l2_std_id norm) { - return (norm->id & V4L2_STD_625_50) ? 576 : 480; + return (norm & V4L2_STD_625_50) ? 576 : 480; } /* ----------------------------------------------------------- */ @@ -312,7 +319,7 @@ struct cx88_core { /* state info */ struct task_struct *kthread; - struct v4l2_tvnorm *tvnorm; + v4l2_std_id tvnorm; u32 tvaudio; u32 audiomode_manual; u32 audiomode_current; @@ -529,7 +536,7 @@ extern void cx88_sram_channel_dump(struct cx88_core *core, extern int cx88_set_scale(struct cx88_core *core, unsigned int width, unsigned int height, enum v4l2_field field); -extern int cx88_set_tvnorm(struct cx88_core *core, struct v4l2_tvnorm *norm); +extern int cx88_set_tvnorm(struct cx88_core *core, v4l2_std_id norm); extern struct video_device *cx88_vdev_init(struct cx88_core *core, struct pci_dev *pci, @@ -630,8 +637,6 @@ int cx8802_resume_common(struct pci_dev *pci_dev); /* ----------------------------------------------------------- */ /* cx88-video.c*/ -extern unsigned int cx88_tvnormsize; -extern struct v4l2_tvnorm cx88_tvnorms[]; extern const u32 cx88_user_ctrls[]; extern int cx8800_ctrl_query(struct v4l2_queryctrl *qctrl); int cx88_enum_input (struct cx88_core *core,struct v4l2_input *i); -- 2.39.5