From c0362ee9ab5b0412d626ae535cf394f4d709fb40 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Fri, 2 Feb 2007 13:15:06 +0000 Subject: [PATCH] [V4L] Support digital tvnorms in bttv for external ADC Signed-off-by: David Woodhouse --- drivers/media/video/bt8xx/bttv-cards.c | 4 +- drivers/media/video/bt8xx/bttv-driver.c | 114 +++++++++++++++++------- drivers/media/video/bt8xx/bttv-risc.c | 4 +- drivers/media/video/bt8xx/bttv-vbi.c | 4 +- drivers/media/video/bt8xx/bttvp.h | 6 +- 5 files changed, 94 insertions(+), 38 deletions(-) diff --git a/drivers/media/video/bt8xx/bttv-cards.c b/drivers/media/video/bt8xx/bttv-cards.c index 7bce216e4930..6d14fdf49686 100644 --- a/drivers/media/video/bt8xx/bttv-cards.c +++ b/drivers/media/video/bt8xx/bttv-cards.c @@ -5133,7 +5133,7 @@ void sweetspot_setnorm(struct bttv *btv, int norm) dprintk("Sweetspot_setnorm %d\n", norm); - switch (bttv_tvnorms[norm].v4l2_id) { + switch (btv->tvnorms[norm].v4l2_id) { case V4L2_STD_PAL: decoder_norm = VIDEO_MODE_PAL; break; @@ -5144,7 +5144,7 @@ void sweetspot_setnorm(struct bttv *btv, int norm) decoder_norm = VIDEO_MODE_SECAM; break; default: - printk(KERN_INFO "Decoder API doesn't allow setting tvnorm %s\n", bttv_tvnorms[norm].name); + printk(KERN_INFO "Decoder API doesn't allow setting tvnorm %s\n", btv->tvnorms[norm].name); return /* -EINVAL */; } diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c index 9c435c63aced..601dba9bff26 100644 --- a/drivers/media/video/bt8xx/bttv-driver.c +++ b/drivers/media/video/bt8xx/bttv-driver.c @@ -192,7 +192,7 @@ static u8 SRAM_Table[][60] = } }; -const struct bttv_tvnorm bttv_tvnorms[] = { +const struct bttv_tvnorm bttv_tvnorms_analogue[] = { /* PAL-BDGHI */ /* max. active video is actually 922, but 924 is divisible by 4 and 3! */ /* actually, max active PAL with HSCALE=0 is 948, NTSC is 768 - nil */ @@ -340,7 +340,49 @@ const struct bttv_tvnorm bttv_tvnorms[] = { .vbistart = { 10, 273 }, } }; -static const unsigned int BTTV_TVNORMS = ARRAY_SIZE(bttv_tvnorms); + +const struct bttv_tvnorm bttv_tvnorms_digital[] = { + /* PAL-BDGHI */ + /* max. active video is actually 922, but 924 is divisible by 4 and 3! */ + /* actually, max active PAL with HSCALE=0 is 948, NTSC is 768 - nil */ + { + .v4l2_id = V4L2_STD_PAL, + .name = "PAL", + .Fsc = 35468950, + .swidth = 720, + .sheight = 576, + .totalwidth = 720, + .adelay = 0x7f, + .bdelay = 0x72, + .iform = (BT848_IFORM_PAL_BDGHI|BT848_IFORM_XT1), + .scaledtwidth = 720, + .hdelayx1 = 128, + .hactivex1 = 720, + .vdelay = 0x14, + .vbipack = 255, + .sram = 0, + /* ITU-R frame line number of the first VBI line + we can capture, of the first and second field. */ + .vbistart = { 7,320 }, + },{ + .v4l2_id = V4L2_STD_NTSC_M | V4L2_STD_NTSC_M_KR, + .name = "NTSC", + .Fsc = 28636363, + .swidth = 720, + .sheight = 480, + .totalwidth = 720, + .adelay = 0x68, + .bdelay = 0x5d, + .iform = (BT848_IFORM_NTSC|BT848_IFORM_XT0), + .scaledtwidth = 720, + .hdelayx1 = 128, + .hactivex1 = 720, + .vdelay = 0x1a, + .vbipack = 144, + .sram = 1, + .vbistart = { 10, 273 }, + } +}; /* ----------------------------------------------------------------------- */ /* bttv format list @@ -810,8 +852,8 @@ static void set_pll(struct bttv *btv) static void bt848A_set_timing(struct bttv *btv) { int i, len; - int table_idx = bttv_tvnorms[btv->tvnorm].sram; - int fsc = bttv_tvnorms[btv->tvnorm].Fsc; + int table_idx = btv->tvnorms[btv->tvnorm].sram; + int fsc = btv->tvnorms[btv->tvnorm].Fsc; if (UNSET == bttv_tvcards[btv->c.type].muxsel[btv->input]) { dprintk("bttv%d: load digital timing table (table_idx=%d)\n", @@ -1042,7 +1084,7 @@ audio_input(struct bttv *btv, int input) static void i2c_vidiocschan(struct bttv *btv) { - v4l2_std_id std = bttv_tvnorms[btv->tvnorm].v4l2_id; + v4l2_std_id std = btv->tvnorms[btv->tvnorm].v4l2_id; bttv_call_i2c_clients(btv, VIDIOC_S_STD, &std); if (btv->c.type == BTTV_BOARD_VOODOOTV_FM) @@ -1056,11 +1098,11 @@ set_tvnorm(struct bttv *btv, unsigned int norm) { const struct bttv_tvnorm *tvnorm; - if (norm < 0 || norm >= BTTV_TVNORMS) + if (norm < 0 || norm >= btv->nr_tvnorms) return -EINVAL; btv->tvnorm = norm; - tvnorm = &bttv_tvnorms[norm]; + tvnorm = &btv->tvnorms[norm]; btwrite(tvnorm->adelay, BT848_ADELAY); btwrite(tvnorm->bdelay, BT848_BDELAY); @@ -1518,8 +1560,8 @@ static int bttv_prepare_buffer(struct videobuf_queue *q,struct bttv *btv, } else { if (width < 48 || height < 32 || - width > bttv_tvnorms[btv->tvnorm].swidth || - height > bttv_tvnorms[btv->tvnorm].sheight) + width > btv->tvnorms[btv->tvnorm].swidth || + height > btv->tvnorms[btv->tvnorm].sheight) return -EINVAL; buf->vb.size = (width * height * fmt->depth) >> 3; if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size) @@ -1663,7 +1705,7 @@ static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg) if (v->tuner) /* Only tuner 0 */ return -EINVAL; - if (v->mode >= BTTV_TVNORMS) + if (v->mode >= btv->nr_tvnorms) return -EINVAL; mutex_lock(&btv->lock); @@ -1705,7 +1747,7 @@ static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg) if (channel >= bttv_tvcards[btv->c.type].video_inputs) return -EINVAL; - if (v->norm >= BTTV_TVNORMS) + if (v->norm >= btv->nr_tvnorms) return -EINVAL; mutex_lock(&btv->lock); @@ -1767,17 +1809,17 @@ static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg) struct v4l2_standard *e = arg; unsigned int index = e->index; - if (index >= BTTV_TVNORMS) + if (index >= btv->nr_tvnorms) return -EINVAL; - v4l2_video_std_construct(e, bttv_tvnorms[e->index].v4l2_id, - bttv_tvnorms[e->index].name); + v4l2_video_std_construct(e, btv->tvnorms[e->index].v4l2_id, + btv->tvnorms[e->index].name); e->index = index; return 0; } case VIDIOC_G_STD: { v4l2_std_id *id = arg; - *id = bttv_tvnorms[btv->tvnorm].v4l2_id; + *id = btv->tvnorms[btv->tvnorm].v4l2_id; return 0; } case VIDIOC_S_STD: @@ -1785,10 +1827,10 @@ static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg) v4l2_std_id *id = arg; unsigned int i; - for (i = 0; i < BTTV_TVNORMS; i++) - if (*id & bttv_tvnorms[i].v4l2_id) + for (i = 0; i < btv->nr_tvnorms; i++) + if (*id & btv->tvnorms[i].v4l2_id) break; - if (i == BTTV_TVNORMS) + if (i == btv->nr_tvnorms) return -EINVAL; mutex_lock(&btv->lock); @@ -1836,8 +1878,8 @@ static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg) if (0 == (dstatus & BT848_DSTATUS_HLOC)) i->status |= V4L2_IN_ST_NO_H_LOCK; } - for (n = 0; n < BTTV_TVNORMS; n++) - i->std |= bttv_tvnorms[n].v4l2_id; + for (n = 0; n < btv->nr_tvnorms; n++) + i->std |= btv->tvnorms[n].v4l2_id; return 0; } case VIDIOC_G_INPUT: @@ -2017,7 +2059,7 @@ static int setup_window(struct bttv_fh *fh, struct bttv *btv, return -EINVAL; if (!(fh->ovfmt->flags & FORMAT_FLAGS_PACKED)) return -EINVAL; - retval = verify_window(&bttv_tvnorms[btv->tvnorm],win,fixup); + retval = verify_window(&btv->tvnorms[btv->tvnorm],win,fixup); if (0 != retval) return retval; @@ -2186,8 +2228,8 @@ static int bttv_try_fmt(struct bttv_fh *fh, struct bttv *btv, return -EINVAL; /* fixup format */ - maxw = bttv_tvnorms[btv->tvnorm].swidth; - maxh = bttv_tvnorms[btv->tvnorm].sheight; + maxw = btv->tvnorms[btv->tvnorm].swidth; + maxh = btv->tvnorms[btv->tvnorm].sheight; field = f->fmt.pix.field; if (V4L2_FIELD_ANY == field) field = (f->fmt.pix.height > maxh/2) @@ -2228,7 +2270,7 @@ static int bttv_try_fmt(struct bttv_fh *fh, struct bttv *btv, return 0; } case V4L2_BUF_TYPE_VIDEO_OVERLAY: - return verify_window(&bttv_tvnorms[btv->tvnorm], + return verify_window(&btv->tvnorms[btv->tvnorm], &f->fmt.win, 1); case V4L2_BUF_TYPE_VBI_CAPTURE: bttv_vbi_try_fmt(fh,f); @@ -2340,8 +2382,8 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file, if (no_overlay <= 0) cap->type |= VID_TYPE_OVERLAY; - cap->maxwidth = bttv_tvnorms[btv->tvnorm].swidth; - cap->maxheight = bttv_tvnorms[btv->tvnorm].sheight; + cap->maxwidth = btv->tvnorms[btv->tvnorm].swidth; + cap->maxheight = btv->tvnorms[btv->tvnorm].sheight; cap->minwidth = 48; cap->minheight = 32; } @@ -2592,7 +2634,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file, buf->vb.state == STATE_ACTIVE) goto fh_unlock_and_return; - field = (vm->height > bttv_tvnorms[btv->tvnorm].sheight/2) + field = (vm->height > btv->tvnorms[btv->tvnorm].sheight/2) ? V4L2_FIELD_INTERLACED : V4L2_FIELD_BOTTOM; retval = bttv_prepare_buffer(&fh->cap,btv,buf, @@ -2821,9 +2863,9 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file, mutex_lock(&fh->cap.lock); retval = -EINVAL; if (fb->flags & V4L2_FBUF_FLAG_OVERLAY) { - if (fb->fmt.width > bttv_tvnorms[btv->tvnorm].swidth) + if (fb->fmt.width > btv->tvnorms[btv->tvnorm].swidth) goto fh_unlock_and_return; - if (fb->fmt.height > bttv_tvnorms[btv->tvnorm].sheight) + if (fb->fmt.height > btv->tvnorms[btv->tvnorm].sheight) goto fh_unlock_and_return; } @@ -2948,8 +2990,8 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file, if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; memset(parm,0,sizeof(*parm)); - v4l2_video_std_construct(&s, bttv_tvnorms[btv->tvnorm].v4l2_id, - bttv_tvnorms[btv->tvnorm].name); + v4l2_video_std_construct(&s, btv->tvnorms[btv->tvnorm].v4l2_id, + btv->tvnorms[btv->tvnorm].name); parm->parm.capture.timeperframe = s.frameperiod; return 0; } @@ -4042,6 +4084,16 @@ static int __devinit bttv_probe(struct pci_dev *dev, btv->new_input = UNSET; btv->has_radio=radio[btv->c.nr]; + if (!btv->tvnorms) { + if (bttv_tvcards[btv->c.type].digital_mode == DIGITAL_MODE_VIDEO) { + btv->tvnorms = bttv_tvnorms_digital; + btv->nr_tvnorms = ARRAY_SIZE(bttv_tvnorms_digital); + } else { + btv->tvnorms = bttv_tvnorms_analogue; + btv->nr_tvnorms = ARRAY_SIZE(bttv_tvnorms_analogue); + } + } + /* pci stuff (init, get irq/mmio, ... */ btv->c.pci = dev; btv->id = dev->device; diff --git a/drivers/media/video/bt8xx/bttv-risc.c b/drivers/media/video/bt8xx/bttv-risc.c index afcfe71e3792..1a3c65153209 100644 --- a/drivers/media/video/bt8xx/bttv-risc.c +++ b/drivers/media/video/bt8xx/bttv-risc.c @@ -320,7 +320,7 @@ static void bttv_calc_geo(struct bttv *btv, struct bttv_geometry *geo, int width, int height, int interleaved, int norm) { - const struct bttv_tvnorm *tvnorm = &bttv_tvnorms[norm]; + const struct bttv_tvnorm *tvnorm = &btv->tvnorms[norm]; u32 xsf, sr; int vdelay; @@ -598,7 +598,7 @@ bttv_buffer_activate_video(struct bttv *btv, int bttv_buffer_risc(struct bttv *btv, struct bttv_buffer *buf) { - const struct bttv_tvnorm *tvnorm = bttv_tvnorms + buf->tvnorm; + const struct bttv_tvnorm *tvnorm = btv->tvnorms + buf->tvnorm; dprintk(KERN_DEBUG "bttv%d: buffer field: %s format: %s size: %dx%d\n", diff --git a/drivers/media/video/bt8xx/bttv-vbi.c b/drivers/media/video/bt8xx/bttv-vbi.c index 63676e7bd635..22cc624e14f1 100644 --- a/drivers/media/video/bt8xx/bttv-vbi.c +++ b/drivers/media/video/bt8xx/bttv-vbi.c @@ -176,7 +176,7 @@ void bttv_vbi_try_fmt(struct bttv_fh *fh, struct v4l2_format *f) const struct bttv_tvnorm *tvnorm; s64 count0,count1,count; - tvnorm = &bttv_tvnorms[fh->btv->tvnorm]; + tvnorm = &fh->btv->tvnorms[fh->btv->tvnorm]; f->type = V4L2_BUF_TYPE_VBI_CAPTURE; f->fmt.vbi.sampling_rate = tvnorm->Fsc; f->fmt.vbi.samples_per_line = 2048; @@ -204,7 +204,7 @@ void bttv_vbi_get_fmt(struct bttv_fh *fh, struct v4l2_format *f) { const struct bttv_tvnorm *tvnorm; - tvnorm = &bttv_tvnorms[fh->btv->tvnorm]; + tvnorm = &fh->btv->tvnorms[fh->btv->tvnorm]; memset(f,0,sizeof(*f)); f->type = V4L2_BUF_TYPE_VBI_CAPTURE; f->fmt.vbi.sampling_rate = tvnorm->Fsc; diff --git a/drivers/media/video/bt8xx/bttvp.h b/drivers/media/video/bt8xx/bttvp.h index 311c4c541e01..942ead1540a7 100644 --- a/drivers/media/video/bt8xx/bttvp.h +++ b/drivers/media/video/bt8xx/bttvp.h @@ -95,7 +95,6 @@ struct bttv_tvnorm { capture, of the first and second field. */ u16 vbistart[2]; }; -extern const struct bttv_tvnorm bttv_tvnorms[]; struct bttv_format { char *name; @@ -328,6 +327,11 @@ struct bttv { struct v4l2_framebuffer fbuf; unsigned int field_count; + /* tvnorms */ + const struct bttv_tvnorm *tvnorms; + unsigned int nr_tvnorms; + + /* various options */ int opt_combfilter; int opt_lumafilter; -- 2.49.0