diff options
author | Mauro Carvalho Chehab <mchehab@infradead.org> | 2007-10-30 01:08:11 -0200 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2007-10-30 01:08:11 -0200 |
commit | 47c9bdaf6e07f0a4b5ccaec663d41aec4bf62e63 (patch) | |
tree | 40c30a3a55122a33867122d2e2937ceb20af95ff /linux/drivers/media/video/bt8xx/bttv-driver.c | |
parent | ee189d9d96dcebde4ec27edbda3f1582949ca8a4 (diff) | |
parent | db7fcfc5c5821ff5568dd32c567e0c42488c503f (diff) | |
download | mediapointer-dvb-s2-47c9bdaf6e07f0a4b5ccaec663d41aec4bf62e63.tar.gz mediapointer-dvb-s2-47c9bdaf6e07f0a4b5ccaec663d41aec4bf62e63.tar.bz2 |
merge: http://linuxtv.org/hg/~dougsland/v4l-dvb
From: Mauro Carvalho Chehab <mchehab@infradead.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'linux/drivers/media/video/bt8xx/bttv-driver.c')
-rw-r--r-- | linux/drivers/media/video/bt8xx/bttv-driver.c | 863 |
1 files changed, 127 insertions, 736 deletions
diff --git a/linux/drivers/media/video/bt8xx/bttv-driver.c b/linux/drivers/media/video/bt8xx/bttv-driver.c index 37db47ecc..2aaa88dd6 100644 --- a/linux/drivers/media/video/bt8xx/bttv-driver.c +++ b/linux/drivers/media/video/bt8xx/bttv-driver.c @@ -9,6 +9,12 @@ some v4l2 code lines are taken from Justin's bttv2 driver which is (c) 2000 Justin Schoeman <justin@suntiger.ee.up.ac.za> + V4L1 removal from: + (c) 2005-2006 Nickolay V. Shmyrev <nshmyrev@yandex.ru> + + Fixes to be fully V4L2 compliant by + (c) 2006 Mauro Carvalho Chehab <mchehab@infradead.org> + Cropping and overscan support Copyright (C) 2005, 2006 Michael H. Schimek <mschimek@gmx.at> Sponsored by OPQ Systems AB @@ -173,7 +179,7 @@ static ssize_t show_card(struct device *cd, static ssize_t show_card(struct class_device *cd, char *buf) #endif { - struct video_device *vfd = to_video_device(cd); + struct video_device *vfd = container_of(cd, struct video_device, class_dev); struct bttv *btv = dev_get_drvdata(vfd->dev); return sprintf(buf, "%d\n", btv ? btv->c.type : UNSET); } @@ -502,28 +508,24 @@ static const unsigned int BTTV_TVNORMS = ARRAY_SIZE(bttv_tvnorms); static const struct bttv_format bttv_formats[] = { { .name = "8 bpp, gray", - .palette = VIDEO_PALETTE_GREY, .fourcc = V4L2_PIX_FMT_GREY, .btformat = BT848_COLOR_FMT_Y8, .depth = 8, .flags = FORMAT_FLAGS_PACKED, },{ .name = "8 bpp, dithered color", - .palette = VIDEO_PALETTE_HI240, .fourcc = V4L2_PIX_FMT_HI240, .btformat = BT848_COLOR_FMT_RGB8, .depth = 8, .flags = FORMAT_FLAGS_PACKED | FORMAT_FLAGS_DITHER, },{ .name = "15 bpp RGB, le", - .palette = VIDEO_PALETTE_RGB555, .fourcc = V4L2_PIX_FMT_RGB555, .btformat = BT848_COLOR_FMT_RGB15, .depth = 16, .flags = FORMAT_FLAGS_PACKED, },{ .name = "15 bpp RGB, be", - .palette = -1, .fourcc = V4L2_PIX_FMT_RGB555X, .btformat = BT848_COLOR_FMT_RGB15, .btswap = 0x03, /* byteswap */ @@ -531,14 +533,12 @@ static const struct bttv_format bttv_formats[] = { .flags = FORMAT_FLAGS_PACKED, },{ .name = "16 bpp RGB, le", - .palette = VIDEO_PALETTE_RGB565, .fourcc = V4L2_PIX_FMT_RGB565, .btformat = BT848_COLOR_FMT_RGB16, .depth = 16, .flags = FORMAT_FLAGS_PACKED, },{ .name = "16 bpp RGB, be", - .palette = -1, .fourcc = V4L2_PIX_FMT_RGB565X, .btformat = BT848_COLOR_FMT_RGB16, .btswap = 0x03, /* byteswap */ @@ -546,21 +546,18 @@ static const struct bttv_format bttv_formats[] = { .flags = FORMAT_FLAGS_PACKED, },{ .name = "24 bpp RGB, le", - .palette = VIDEO_PALETTE_RGB24, .fourcc = V4L2_PIX_FMT_BGR24, .btformat = BT848_COLOR_FMT_RGB24, .depth = 24, .flags = FORMAT_FLAGS_PACKED, },{ .name = "32 bpp RGB, le", - .palette = VIDEO_PALETTE_RGB32, .fourcc = V4L2_PIX_FMT_BGR32, .btformat = BT848_COLOR_FMT_RGB32, .depth = 32, .flags = FORMAT_FLAGS_PACKED, },{ .name = "32 bpp RGB, be", - .palette = -1, .fourcc = V4L2_PIX_FMT_RGB32, .btformat = BT848_COLOR_FMT_RGB32, .btswap = 0x0f, /* byte+word swap */ @@ -568,21 +565,18 @@ static const struct bttv_format bttv_formats[] = { .flags = FORMAT_FLAGS_PACKED, },{ .name = "4:2:2, packed, YUYV", - .palette = VIDEO_PALETTE_YUV422, .fourcc = V4L2_PIX_FMT_YUYV, .btformat = BT848_COLOR_FMT_YUY2, .depth = 16, .flags = FORMAT_FLAGS_PACKED, },{ .name = "4:2:2, packed, YUYV", - .palette = VIDEO_PALETTE_YUYV, .fourcc = V4L2_PIX_FMT_YUYV, .btformat = BT848_COLOR_FMT_YUY2, .depth = 16, .flags = FORMAT_FLAGS_PACKED, },{ .name = "4:2:2, packed, UYVY", - .palette = VIDEO_PALETTE_UYVY, .fourcc = V4L2_PIX_FMT_UYVY, .btformat = BT848_COLOR_FMT_YUY2, .btswap = 0x03, /* byteswap */ @@ -590,7 +584,6 @@ static const struct bttv_format bttv_formats[] = { .flags = FORMAT_FLAGS_PACKED, },{ .name = "4:2:2, planar, Y-Cb-Cr", - .palette = VIDEO_PALETTE_YUV422P, .fourcc = V4L2_PIX_FMT_YUV422P, .btformat = BT848_COLOR_FMT_YCrCb422, .depth = 16, @@ -599,7 +592,6 @@ static const struct bttv_format bttv_formats[] = { .vshift = 0, },{ .name = "4:2:0, planar, Y-Cb-Cr", - .palette = VIDEO_PALETTE_YUV420P, .fourcc = V4L2_PIX_FMT_YUV420, .btformat = BT848_COLOR_FMT_YCrCb422, .depth = 12, @@ -608,7 +600,6 @@ static const struct bttv_format bttv_formats[] = { .vshift = 1, },{ .name = "4:2:0, planar, Y-Cr-Cb", - .palette = -1, .fourcc = V4L2_PIX_FMT_YVU420, .btformat = BT848_COLOR_FMT_YCrCb422, .depth = 12, @@ -617,7 +608,6 @@ static const struct bttv_format bttv_formats[] = { .vshift = 1, },{ .name = "4:1:1, planar, Y-Cb-Cr", - .palette = VIDEO_PALETTE_YUV411P, .fourcc = V4L2_PIX_FMT_YUV411P, .btformat = BT848_COLOR_FMT_YCrCb411, .depth = 12, @@ -626,7 +616,6 @@ static const struct bttv_format bttv_formats[] = { .vshift = 0, },{ .name = "4:1:0, planar, Y-Cb-Cr", - .palette = VIDEO_PALETTE_YUV410P, .fourcc = V4L2_PIX_FMT_YUV410, .btformat = BT848_COLOR_FMT_YCrCb411, .depth = 9, @@ -635,7 +624,6 @@ static const struct bttv_format bttv_formats[] = { .vshift = 2, },{ .name = "4:1:0, planar, Y-Cr-Cb", - .palette = -1, .fourcc = V4L2_PIX_FMT_YVU410, .btformat = BT848_COLOR_FMT_YCrCb411, .depth = 9, @@ -644,7 +632,6 @@ static const struct bttv_format bttv_formats[] = { .vshift = 2, },{ .name = "raw scanlines", - .palette = VIDEO_PALETTE_RAW, .fourcc = -1, .btformat = BT848_COLOR_FMT_RAW, .depth = 8, @@ -1291,16 +1278,6 @@ audio_input(struct bttv *btv, int input) } static void -i2c_vidiocschan(struct bttv *btv) -{ - v4l2_std_id std = bttv_tvnorms[btv->tvnorm].v4l2_id; - - bttv_call_i2c_clients(btv, VIDIOC_S_STD, &std); - if (btv->c.type == BTTV_BOARD_VOODOOTV_FM || btv->c.type == BTTV_BOARD_VOODOOTV_200) - bttv_tda9880_setnorm(btv,btv->tvnorm); -} - -static void bttv_crop_calc_limits(struct bttv_crop *c) { /* Scale factor min. 1:1, max. 16:1. Min. image size @@ -1334,6 +1311,7 @@ static int set_tvnorm(struct bttv *btv, unsigned int norm) { const struct bttv_tvnorm *tvnorm; + v4l2_std_id id; if (norm < 0 || norm >= BTTV_TVNORMS) return -EINVAL; @@ -1375,6 +1353,9 @@ set_tvnorm(struct bttv *btv, unsigned int norm) break; #endif } + id = tvnorm->v4l2_id; + bttv_call_i2c_clients(btv, VIDIOC_S_STD, &id); + return 0; } @@ -1400,7 +1381,6 @@ set_input(struct bttv *btv, unsigned int input, unsigned int norm) audio_input(btv,(input == bttv_tvcards[btv->c.type].tuner ? TVAUDIO_INPUT_TUNER : TVAUDIO_INPUT_EXTERN)); set_tvnorm(btv, norm); - i2c_vidiocschan(btv); } static void init_irqreg(struct bttv *btv) @@ -1495,36 +1475,6 @@ static void bttv_reinit_bt848(struct bttv *btv) static int get_control(struct bttv *btv, struct v4l2_control *c) { - struct video_audio va; - int i; - - for (i = 0; i < BTTV_CTLS; i++) - if (bttv_ctls[i].id == c->id) - break; - if (i == BTTV_CTLS) - return -EINVAL; - if (btv->audio_hook && i >= 4 && i <= 8) { - memset(&va,0,sizeof(va)); - btv->audio_hook(btv,&va,0); - switch (c->id) { - case V4L2_CID_AUDIO_MUTE: - c->value = (VIDEO_AUDIO_MUTE & va.flags) ? 1 : 0; - break; - case V4L2_CID_AUDIO_VOLUME: - c->value = va.volume; - break; - case V4L2_CID_AUDIO_BALANCE: - c->value = va.balance; - break; - case V4L2_CID_AUDIO_BASS: - c->value = va.bass; - break; - case V4L2_CID_AUDIO_TREBLE: - c->value = va.treble; - break; - } - return 0; - } switch (c->id) { case V4L2_CID_BRIGHTNESS: c->value = btv->bright; @@ -1588,44 +1538,8 @@ static int get_control(struct bttv *btv, struct v4l2_control *c) static int set_control(struct bttv *btv, struct v4l2_control *c) { - struct video_audio va; - int i,val; - - for (i = 0; i < BTTV_CTLS; i++) - if (bttv_ctls[i].id == c->id) - break; - if (i == BTTV_CTLS) - return -EINVAL; - if (btv->audio_hook && i >= 4 && i <= 8) { - memset(&va,0,sizeof(va)); - btv->audio_hook(btv,&va,0); - switch (c->id) { - case V4L2_CID_AUDIO_MUTE: - if (c->value) { - va.flags |= VIDEO_AUDIO_MUTE; - audio_mute(btv, 1); - } else { - va.flags &= ~VIDEO_AUDIO_MUTE; - audio_mute(btv, 0); - } - break; + int val; - case V4L2_CID_AUDIO_VOLUME: - va.volume = c->value; - break; - case V4L2_CID_AUDIO_BALANCE: - va.balance = c->value; - break; - case V4L2_CID_AUDIO_BASS: - va.bass = c->value; - break; - case V4L2_CID_AUDIO_TREBLE: - va.treble = c->value; - break; - } - btv->audio_hook(btv,&va,1); - return 0; - } switch (c->id) { case V4L2_CID_BRIGHTNESS: bt848_bright(btv,c->value); @@ -1643,6 +1557,11 @@ static int set_control(struct bttv *btv, struct v4l2_control *c) audio_mute(btv, c->value); /* fall through */ case V4L2_CID_AUDIO_VOLUME: + if (btv->volume_gpio) { + btv->volume_gpio (btv, c->value); + } + bttv_call_i2c_clients(btv,VIDIOC_S_CTRL,c); + break; case V4L2_CID_AUDIO_BALANCE: case V4L2_CID_AUDIO_BASS: case V4L2_CID_AUDIO_TREBLE: @@ -1734,20 +1653,6 @@ static void bttv_field_count(struct bttv *btv) } static const struct bttv_format* -format_by_palette(int palette) -{ - unsigned int i; - - for (i = 0; i < BTTV_FORMATS; i++) { - if (-1 == bttv_formats[i].palette) - continue; - if (bttv_formats[i].palette == palette) - return bttv_formats+i; - } - return NULL; -} - -static const struct bttv_format* format_by_fourcc(int fourcc) { unsigned int i; @@ -1960,151 +1865,6 @@ static struct videobuf_queue_ops bttv_video_qops = { static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg) { switch (cmd) { - case BTTV_VERSION: - return BTTV_VERSION_CODE; - - /* *** v4l1 *** ************************************************ */ - case VIDIOCGFREQ: - { - unsigned long *freq = arg; - *freq = btv->freq; - return 0; - } - case VIDIOCSFREQ: - { - struct v4l2_frequency freq; - - memset(&freq, 0, sizeof(freq)); - freq.frequency = *(unsigned long *)arg; - mutex_lock(&btv->lock); - freq.type = btv->radio_user ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; - btv->freq = *(unsigned long *)arg; - bttv_call_i2c_clients(btv,VIDIOC_S_FREQUENCY,&freq); - if (btv->has_matchbox && btv->radio_user) - tea5757_set_freq(btv,*(unsigned long *)arg); - mutex_unlock(&btv->lock); - return 0; - } - - case VIDIOCGTUNER: - { - struct video_tuner *v = arg; - - if (UNSET == bttv_tvcards[btv->c.type].tuner) - return -EINVAL; - if (v->tuner) /* Only tuner 0 */ - return -EINVAL; - strcpy(v->name, "Television"); - v->rangelow = 0; - v->rangehigh = 0x7FFFFFFF; - v->flags = VIDEO_TUNER_PAL|VIDEO_TUNER_NTSC|VIDEO_TUNER_SECAM; - v->mode = btv->tvnorm; - v->signal = (btread(BT848_DSTATUS)&BT848_DSTATUS_HLOC) ? 0xFFFF : 0; - bttv_call_i2c_clients(btv,cmd,v); - return 0; - } - case VIDIOCSTUNER: - { - struct video_tuner *v = arg; - - if (v->tuner) /* Only tuner 0 */ - return -EINVAL; - if (v->mode >= BTTV_TVNORMS) - return -EINVAL; - - mutex_lock(&btv->lock); - set_tvnorm(btv,v->mode); - bttv_call_i2c_clients(btv,cmd,v); - mutex_unlock(&btv->lock); - return 0; - } - - case VIDIOCGCHAN: - { - struct video_channel *v = arg; - unsigned int channel = v->channel; - - if (channel >= bttv_tvcards[btv->c.type].video_inputs) - return -EINVAL; - v->tuners=0; - v->flags = VIDEO_VC_AUDIO; - v->type = VIDEO_TYPE_CAMERA; - v->norm = btv->tvnorm; - if (channel == bttv_tvcards[btv->c.type].tuner) { - strcpy(v->name,"Television"); - v->flags|=VIDEO_VC_TUNER; - v->type=VIDEO_TYPE_TV; - v->tuners=1; - } else if (channel == btv->svhs) { - strcpy(v->name,"S-Video"); - } else { - sprintf(v->name,"Composite%d",channel); - } - return 0; - } - case VIDIOCSCHAN: - { - struct video_channel *v = arg; - unsigned int channel = v->channel; - - if (channel >= bttv_tvcards[btv->c.type].video_inputs) - return -EINVAL; - if (v->norm >= BTTV_TVNORMS) - return -EINVAL; - - mutex_lock(&btv->lock); - if (channel == btv->input && - v->norm == btv->tvnorm) { - /* nothing to do */ - mutex_unlock(&btv->lock); - return 0; - } - - set_input(btv, v->channel, v->norm); - mutex_unlock(&btv->lock); - return 0; - } - - case VIDIOCGAUDIO: - { - struct video_audio *v = arg; - - memset(v,0,sizeof(*v)); - strcpy(v->name,"Television"); - v->flags |= VIDEO_AUDIO_MUTABLE; - v->mode = VIDEO_SOUND_MONO; - - mutex_lock(&btv->lock); - bttv_call_i2c_clients(btv,cmd,v); - - /* card specific hooks */ - if (btv->audio_hook) - btv->audio_hook(btv,v,0); - - mutex_unlock(&btv->lock); - return 0; - } - case VIDIOCSAUDIO: - { - struct video_audio *v = arg; - unsigned int audio = v->audio; - - if (audio >= bttv_tvcards[btv->c.type].audio_inputs) - return -EINVAL; - - mutex_lock(&btv->lock); - audio_mute(btv, (v->flags&VIDEO_AUDIO_MUTE) ? 1 : 0); - bttv_call_i2c_clients(btv,cmd,v); - - /* card specific hooks */ - if (btv->audio_hook) - btv->audio_hook(btv,v,1); - - mutex_unlock(&btv->lock); - return 0; - } - - /* *** v4l2 *** ************************************************ */ case VIDIOC_ENUMSTD: { struct v4l2_standard *e = arg; @@ -2136,7 +1896,6 @@ static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg) mutex_lock(&btv->lock); set_tvnorm(btv,i); - i2c_vidiocschan(btv); mutex_unlock(&btv->lock); return 0; } @@ -2201,45 +1960,6 @@ static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg) return 0; } - case VIDIOC_G_TUNER: - { - struct v4l2_tuner *t = arg; - - if (UNSET == bttv_tvcards[btv->c.type].tuner) - return -EINVAL; - if (0 != t->index) - return -EINVAL; - mutex_lock(&btv->lock); - memset(t,0,sizeof(*t)); - t->rxsubchans = V4L2_TUNER_SUB_MONO; - bttv_call_i2c_clients(btv, VIDIOC_G_TUNER, t); - strcpy(t->name, "Television"); - t->capability = V4L2_TUNER_CAP_NORM; - t->type = V4L2_TUNER_ANALOG_TV; - if (btread(BT848_DSTATUS)&BT848_DSTATUS_HLOC) - t->signal = 0xffff; - - if (btv->audio_hook) { - /* Hmmm ... */ - struct video_audio va; - memset(&va, 0, sizeof(struct video_audio)); - btv->audio_hook(btv,&va,0); - t->audmode = V4L2_TUNER_MODE_MONO; - t->rxsubchans = V4L2_TUNER_SUB_MONO; - if(va.mode & VIDEO_SOUND_STEREO) { - t->audmode = V4L2_TUNER_MODE_STEREO; - t->rxsubchans = V4L2_TUNER_SUB_STEREO; - } - if(va.mode & VIDEO_SOUND_LANG2) { - t->audmode = V4L2_TUNER_MODE_LANG1; - t->rxsubchans = V4L2_TUNER_SUB_LANG1 - | V4L2_TUNER_SUB_LANG2; - } - } - /* FIXME: fill capability+audmode */ - mutex_unlock(&btv->lock); - return 0; - } case VIDIOC_S_TUNER: { struct v4l2_tuner *t = arg; @@ -2250,19 +1970,9 @@ static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg) return -EINVAL; mutex_lock(&btv->lock); bttv_call_i2c_clients(btv, VIDIOC_S_TUNER, t); - if (btv->audio_hook) { - struct video_audio va; - memset(&va, 0, sizeof(struct video_audio)); - if (t->audmode == V4L2_TUNER_MODE_MONO) - va.mode = VIDEO_SOUND_MONO; - else if (t->audmode == V4L2_TUNER_MODE_STEREO || - t->audmode == V4L2_TUNER_MODE_LANG1_LANG2) - va.mode = VIDEO_SOUND_STEREO; - else if (t->audmode == V4L2_TUNER_MODE_LANG1) - va.mode = VIDEO_SOUND_LANG1; - else if (t->audmode == V4L2_TUNER_MODE_LANG2) - va.mode = VIDEO_SOUND_LANG2; - btv->audio_hook(btv,&va,1); + + if (btv->audio_mode_gpio) { + btv->audio_mode_gpio (btv,t,1); } mutex_unlock(&btv->lock); return 0; @@ -2300,6 +2010,10 @@ static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg) printk(KERN_INFO "bttv%d: ================== END STATUS CARD #%d ==================\n", btv->c.nr, btv->c.nr); return 0; } + case VIDIOC_G_CTRL: + return get_control(btv,arg); + case VIDIOC_S_CTRL: + return set_control(btv,arg); #ifdef CONFIG_VIDEO_ADV_DEBUG case VIDIOC_DBG_G_REGISTER: case VIDIOC_DBG_S_REGISTER: @@ -2844,7 +2558,6 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file, { struct bttv_fh *fh = file->private_data; struct bttv *btv = fh->btv; - unsigned long flags; int retval = 0; if (bttv_debug > 1) @@ -2854,9 +2567,6 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file, bttv_reinit_bt848(btv); switch (cmd) { - case VIDIOCSFREQ: - case VIDIOCSTUNER: - case VIDIOCSCHAN: case VIDIOC_S_CTRL: case VIDIOC_S_STD: case VIDIOC_S_INPUT: @@ -2868,237 +2578,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file, }; switch (cmd) { - - /* *** v4l1 *** ************************************************ */ - case VIDIOCGCAP: - { - struct video_capability *cap = arg; - - memset(cap,0,sizeof(*cap)); - strcpy(cap->name,btv->video_dev->name); - if (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type) { - /* vbi */ - cap->type = VID_TYPE_TUNER|VID_TYPE_TELETEXT; - } else { - /* others */ - cap->type = VID_TYPE_CAPTURE| - VID_TYPE_TUNER| - VID_TYPE_CLIPPING| - VID_TYPE_SCALES; - if (no_overlay <= 0) - cap->type |= VID_TYPE_OVERLAY; - - cap->maxwidth = bttv_tvnorms[btv->tvnorm].swidth; - cap->maxheight = bttv_tvnorms[btv->tvnorm].sheight; - cap->minwidth = 48; - cap->minheight = 32; - } - cap->channels = bttv_tvcards[btv->c.type].video_inputs; - cap->audios = bttv_tvcards[btv->c.type].audio_inputs; - return 0; - } - - case VIDIOCGPICT: - { - struct video_picture *pic = arg; - - memset(pic,0,sizeof(*pic)); - pic->brightness = btv->bright; - pic->contrast = btv->contrast; - pic->hue = btv->hue; - pic->colour = btv->saturation; - if (fh->fmt) { - pic->depth = fh->fmt->depth; - pic->palette = fh->fmt->palette; - } - return 0; - } - case VIDIOCSPICT: - { - struct video_picture *pic = arg; - const struct bttv_format *fmt; - - fmt = format_by_palette(pic->palette); - if (NULL == fmt) - return -EINVAL; - mutex_lock(&fh->cap.lock); - if (fmt->flags & FORMAT_FLAGS_RAW) { - /* VIDIOCMCAPTURE uses gbufsize, not RAW_BPL * - RAW_LINES * 2. F1 is stored at offset 0, F2 - at buffer size / 2. */ - fh->width = RAW_BPL; - fh->height = gbufsize / RAW_BPL; - btv->init.width = RAW_BPL; - btv->init.height = gbufsize / RAW_BPL; - } - fh->ovfmt = fmt; - fh->fmt = fmt; - btv->init.ovfmt = fmt; - btv->init.fmt = fmt; - if (bigendian) { - /* dirty hack time: swap bytes for overlay if the - display adaptor is big endian (insmod option) */ - if (fmt->palette == VIDEO_PALETTE_RGB555 || - fmt->palette == VIDEO_PALETTE_RGB565 || - fmt->palette == VIDEO_PALETTE_RGB32) { - fh->ovfmt = fmt+1; - } - } - bt848_bright(btv,pic->brightness); - bt848_contrast(btv,pic->contrast); - bt848_hue(btv,pic->hue); - bt848_sat(btv,pic->colour); - mutex_unlock(&fh->cap.lock); - return 0; - } - - case VIDIOCGWIN: - { - struct video_window *win = arg; - - memset(win,0,sizeof(*win)); - win->x = fh->ov.w.left; - win->y = fh->ov.w.top; - win->width = fh->ov.w.width; - win->height = fh->ov.w.height; - return 0; - } - case VIDIOCSWIN: - { - struct video_window *win = arg; - struct v4l2_window w2; - - if (no_overlay > 0) { - printk ("VIDIOCSWIN: no_overlay\n"); - return -EINVAL; - } - - w2.field = V4L2_FIELD_ANY; - w2.w.left = win->x; - w2.w.top = win->y; - w2.w.width = win->width; - w2.w.height = win->height; - w2.clipcount = win->clipcount; - w2.clips = (struct v4l2_clip __user *)win->clips; - retval = setup_window(fh, btv, &w2, 0); - if (0 == retval) { - /* on v4l1 this ioctl affects the read() size too */ - fh->width = fh->ov.w.width; - fh->height = fh->ov.w.height; - btv->init.width = fh->ov.w.width; - btv->init.height = fh->ov.w.height; - } - return retval; - } - - case VIDIOCGFBUF: - { - struct video_buffer *fbuf = arg; - - fbuf->base = btv->fbuf.base; - fbuf->width = btv->fbuf.fmt.width; - fbuf->height = btv->fbuf.fmt.height; - fbuf->bytesperline = btv->fbuf.fmt.bytesperline; - if (fh->ovfmt) - fbuf->depth = fh->ovfmt->depth; - else { - if (fbuf->width) - fbuf->depth = ((fbuf->bytesperline<<3) - + (fbuf->width-1) ) - /fbuf->width; - else - fbuf->depth = 0; - } - return 0; - } - case VIDIOCSFBUF: - { - struct video_buffer *fbuf = arg; - const struct bttv_format *fmt; - unsigned long end; - - if(!capable(CAP_SYS_ADMIN) && - !capable(CAP_SYS_RAWIO)) - return -EPERM; - end = (unsigned long)fbuf->base + - fbuf->height * fbuf->bytesperline; - mutex_lock(&fh->cap.lock); - retval = -EINVAL; - - switch (fbuf->depth) { - case 8: - fmt = format_by_palette(VIDEO_PALETTE_HI240); - break; - case 16: - fmt = format_by_palette(VIDEO_PALETTE_RGB565); - break; - case 24: - fmt = format_by_palette(VIDEO_PALETTE_RGB24); - break; - case 32: - fmt = format_by_palette(VIDEO_PALETTE_RGB32); - break; - case 15: - fbuf->depth = 16; - fmt = format_by_palette(VIDEO_PALETTE_RGB555); - break; - default: - fmt = NULL; - break; - } - if (NULL == fmt) - goto fh_unlock_and_return; - - fh->ovfmt = fmt; - fh->fmt = fmt; - btv->init.ovfmt = fmt; - btv->init.fmt = fmt; - btv->fbuf.base = fbuf->base; - btv->fbuf.fmt.width = fbuf->width; - btv->fbuf.fmt.height = fbuf->height; - if (fbuf->bytesperline) - btv->fbuf.fmt.bytesperline = fbuf->bytesperline; - else - btv->fbuf.fmt.bytesperline = btv->fbuf.fmt.width*fbuf->depth/8; - mutex_unlock(&fh->cap.lock); - return 0; - } - - case VIDIOCCAPTURE: - case VIDIOC_OVERLAY: - { - struct bttv_buffer *new; - int *on = arg; - - if (*on) { - /* verify args */ - if (NULL == btv->fbuf.base) - return -EINVAL; - if (!fh->ov.setup_ok) { - dprintk("bttv%d: overlay: !setup_ok\n",btv->c.nr); - return -EINVAL; - } - } - - if (!check_alloc_btres(btv,fh,RESOURCE_OVERLAY)) - return -EBUSY; - - mutex_lock(&fh->cap.lock); - if (*on) { - fh->ov.tvnorm = btv->tvnorm; - new = videobuf_pci_alloc(sizeof(*new)); - new->crop = btv->crop[!!fh->do_crop].rect; - bttv_overlay_risc(btv, &fh->ov, fh->ovfmt, new); - } else { - new = NULL; - } - - /* switch over */ - retval = bttv_switch_overlay(btv,fh,new); - mutex_unlock(&fh->cap.lock); - return retval; - } - +#ifdef CONFIG_VIDEO_V4L1_COMPAT case VIDIOCGMBUF: { struct video_mbuf *mbuf = arg; @@ -3119,107 +2599,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file, mutex_unlock(&fh->cap.lock); return 0; } - case VIDIOCMCAPTURE: - { - struct video_mmap *vm = arg; - struct bttv_buffer *buf; - enum v4l2_field field; - __s32 height2; - int res; - - if (vm->frame >= VIDEO_MAX_FRAME) - return -EINVAL; - - res = bttv_resource(fh); - if (!check_alloc_btres(btv, fh, res)) - return -EBUSY; - - mutex_lock(&fh->cap.lock); - retval = -EINVAL; - buf = (struct bttv_buffer *)fh->cap.bufs[vm->frame]; - if (NULL == buf) - goto fh_unlock_and_return; - if (0 == buf->vb.baddr) - goto fh_unlock_and_return; - if (buf->vb.state == STATE_QUEUED || - buf->vb.state == STATE_ACTIVE) - goto fh_unlock_and_return; - - height2 = btv->crop[!!fh->do_crop].rect.height >> 1; - field = (vm->height > height2) - ? V4L2_FIELD_INTERLACED - : V4L2_FIELD_BOTTOM; - retval = bttv_prepare_buffer(&fh->cap,btv,buf, - format_by_palette(vm->format), - vm->width,vm->height,field); - if (0 != retval) - goto fh_unlock_and_return; - btv->init.width = vm->width; - btv->init.height = vm->height; - spin_lock_irqsave(&btv->s_lock,flags); - buffer_queue(&fh->cap,&buf->vb); - spin_unlock_irqrestore(&btv->s_lock,flags); - mutex_unlock(&fh->cap.lock); - return 0; - } - case VIDIOCSYNC: - { - int *frame = arg; - struct bttv_buffer *buf; - - if (*frame >= VIDEO_MAX_FRAME) - return -EINVAL; - - mutex_lock(&fh->cap.lock); - retval = -EINVAL; - buf = (struct bttv_buffer *)fh->cap.bufs[*frame]; - if (NULL == buf) - goto fh_unlock_and_return; - retval = videobuf_waiton(&buf->vb,0,1); - if (0 != retval) - goto fh_unlock_and_return; - switch (buf->vb.state) { - case STATE_ERROR: - retval = -EIO; - /* fall through */ - case STATE_DONE: - { - struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb); - videobuf_dma_sync(&fh->cap,dma); - bttv_dma_free(&fh->cap,btv,buf); - break; - } - default: - retval = -EINVAL; - break; - } - mutex_unlock(&fh->cap.lock); - return retval; - } - - case VIDIOCGVBIFMT: - if (fh->type != V4L2_BUF_TYPE_VBI_CAPTURE) { - retval = bttv_switch_type(fh,V4L2_BUF_TYPE_VBI_CAPTURE); - if (0 != retval) - return retval; - } - - /* fall through */ - - case VIDIOCSVBIFMT: - return v4l_compat_translate_ioctl(inode, file, cmd, - arg, bttv_do_ioctl); - - case BTTV_VERSION: - case VIDIOCGFREQ: - case VIDIOCSFREQ: - case VIDIOCGTUNER: - case VIDIOCSTUNER: - case VIDIOCGCHAN: - case VIDIOCSCHAN: - case VIDIOCGAUDIO: - case VIDIOCSAUDIO: - return bttv_common_ioctls(btv,cmd,arg); +#endif /* *** v4l2 *** ************************************************ */ case VIDIOC_QUERYCAP: @@ -3247,7 +2627,6 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file, cap->capabilities |= V4L2_CAP_TUNER; return 0; } - case VIDIOC_ENUM_FMT: { struct v4l2_fmtdesc *f = arg; @@ -3297,7 +2676,6 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file, strlcpy(f->description,bttv_formats[i].name,sizeof(f->description)); return 0; } - case VIDIOC_TRY_FMT: { struct v4l2_format *f = arg; @@ -3324,6 +2702,38 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file, fb->fmt.pixelformat = fh->ovfmt->fourcc; return 0; } + case VIDIOC_OVERLAY: + { + struct bttv_buffer *new; + int *on = arg; + + if (*on) { + /* verify args */ + if (NULL == btv->fbuf.base) + return -EINVAL; + if (!fh->ov.setup_ok) { + dprintk("bttv%d: overlay: !setup_ok\n",btv->c.nr); + return -EINVAL; + } + } + + if (!check_alloc_btres(btv,fh,RESOURCE_OVERLAY)) + return -EBUSY; + + mutex_lock(&fh->cap.lock); + if (*on) { + fh->ov.tvnorm = btv->tvnorm; + new = videobuf_pci_alloc(sizeof(*new)); + bttv_overlay_risc(btv, &fh->ov, fh->ovfmt, new); + } else { + new = NULL; + } + + /* switch over */ + retval = bttv_switch_overlay(btv,fh,new); + mutex_unlock(&fh->cap.lock); + return retval; + } case VIDIOC_S_FBUF: { struct v4l2_framebuffer *fb = arg; @@ -3391,13 +2801,10 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file, mutex_unlock(&fh->cap.lock); return retval; } - case VIDIOC_REQBUFS: return videobuf_reqbufs(bttv_queue(fh),arg); - case VIDIOC_QUERYBUF: return videobuf_querybuf(bttv_queue(fh),arg); - case VIDIOC_QBUF: { int res = bttv_resource(fh); @@ -3406,11 +2813,9 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file, return -EBUSY; return videobuf_qbuf(bttv_queue(fh),arg); } - case VIDIOC_DQBUF: return videobuf_dqbuf(bttv_queue(fh),arg, file->f_flags & O_NONBLOCK); - case VIDIOC_STREAMON: { int res = bttv_resource(fh); @@ -3448,35 +2853,13 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file, return 0; } *c = bttv_ctls[i]; - if (btv->audio_hook && i >= 4 && i <= 8) { - struct video_audio va; - memset(&va,0,sizeof(va)); - btv->audio_hook(btv,&va,0); - switch (bttv_ctls[i].id) { - case V4L2_CID_AUDIO_VOLUME: - if (!(va.flags & VIDEO_AUDIO_VOLUME)) - *c = no_ctl; - break; - case V4L2_CID_AUDIO_BALANCE: - if (!(va.flags & VIDEO_AUDIO_BALANCE)) - *c = no_ctl; - break; - case V4L2_CID_AUDIO_BASS: - if (!(va.flags & VIDEO_AUDIO_BASS)) - *c = no_ctl; - break; - case V4L2_CID_AUDIO_TREBLE: - if (!(va.flags & VIDEO_AUDIO_TREBLE)) - *c = no_ctl; - break; - } - } + + if (!btv->volume_gpio && + (bttv_ctls[i].id == V4L2_CID_AUDIO_VOLUME)) + *c = no_ctl; + return 0; } - case VIDIOC_G_CTRL: - return get_control(btv,arg); - case VIDIOC_S_CTRL: - return set_control(btv,arg); case VIDIOC_G_PARM: { struct v4l2_streamparm *parm = arg; @@ -3489,6 +2872,31 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file, parm->parm.capture.timeperframe = s.frameperiod; return 0; } + case VIDIOC_G_TUNER: + { + struct v4l2_tuner *t = arg; + + if (UNSET == bttv_tvcards[btv->c.type].tuner) + return -EINVAL; + if (0 != t->index) + return -EINVAL; + mutex_lock(&btv->lock); + memset(t,0,sizeof(*t)); + t->rxsubchans = V4L2_TUNER_SUB_MONO; + bttv_call_i2c_clients(btv, VIDIOC_G_TUNER, t); + strcpy(t->name, "Television"); + t->capability = V4L2_TUNER_CAP_NORM; + t->type = V4L2_TUNER_ANALOG_TV; + if (btread(BT848_DSTATUS)&BT848_DSTATUS_HLOC) + t->signal = 0xffff; + + if (btv->audio_mode_gpio) { + btv->audio_mode_gpio (btv,t,0); + } + + mutex_unlock(&btv->lock); + return 0; + } case VIDIOC_G_PRIORITY: { @@ -3626,17 +3034,18 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file, case VIDIOC_ENUMINPUT: case VIDIOC_G_INPUT: case VIDIOC_S_INPUT: - case VIDIOC_G_TUNER: case VIDIOC_S_TUNER: case VIDIOC_G_FREQUENCY: case VIDIOC_S_FREQUENCY: case VIDIOC_LOG_STATUS: + case VIDIOC_G_CTRL: + case VIDIOC_S_CTRL: case VIDIOC_DBG_G_REGISTER: case VIDIOC_DBG_S_REGISTER: return bttv_common_ioctls(btv,cmd,arg); - default: - return -ENOIOCTLCMD; + return v4l_compat_translate_ioctl(inode,file,cmd,arg, + bttv_do_ioctl); } return 0; @@ -3652,33 +3061,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file, static int bttv_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { - struct bttv_fh *fh = file->private_data; - - switch (cmd) { - case BTTV_VBISIZE: - { - const struct bttv_tvnorm *tvnorm; - - tvnorm = fh->vbi_fmt.tvnorm; - - if (fh->vbi_fmt.fmt.start[0] != tvnorm->vbistart[0] || - fh->vbi_fmt.fmt.start[1] != tvnorm->vbistart[1] || - fh->vbi_fmt.fmt.count[0] != fh->vbi_fmt.fmt.count[1]) { - /* BTTV_VBISIZE cannot express these parameters, - however open() resets the paramters to defaults - and apps shouldn't call BTTV_VBISIZE after - VIDIOC_S_FMT. */ - return -EINVAL; - } - - bttv_switch_type(fh,V4L2_BUF_TYPE_VBI_CAPTURE); - return (fh->vbi_fmt.fmt.count[0] * 2 - * fh->vbi_fmt.fmt.samples_per_line); - } - - default: - return video_usercopy(inode, file, cmd, arg, bttv_do_ioctl); - } + return video_usercopy(inode, file, cmd, arg, bttv_do_ioctl); } static ssize_t bttv_read(struct file *file, char __user *data, @@ -3820,7 +3203,7 @@ static int bttv_open(struct inode *inode, struct file *file) V4L2_FIELD_SEQ_TB, sizeof(struct bttv_buffer), fh); - i2c_vidiocschan(btv); + set_tvnorm(btv,btv->tvnorm); btv->users++; @@ -3982,45 +3365,53 @@ static int radio_do_ioctl(struct inode *inode, struct file *file, struct bttv *btv = file->private_data; switch (cmd) { - case VIDIOCGCAP: + case VIDIOC_QUERYCAP: { - struct video_capability *cap = arg; + struct v4l2_capability *cap = arg; memset(cap,0,sizeof(*cap)); - strcpy(cap->name,btv->radio_dev->name); - cap->type = VID_TYPE_TUNER; - cap->channels = 1; - cap->audios = 1; + strcpy(cap->driver, "bttv"); + strlcpy(cap->card, btv->radio_dev->name,sizeof(cap->card)); + sprintf(cap->bus_info,"PCI:%s",pci_name(btv->c.pci)); + cap->version = BTTV_VERSION_CODE; + cap->capabilities = V4L2_CAP_TUNER; return 0; } - - case VIDIOCGTUNER: + case VIDIOC_G_TUNER: { - struct video_tuner *v = arg; + struct v4l2_tuner *t = arg; - if(v->tuner) + if (UNSET == bttv_tvcards[btv->c.type].tuner) return -EINVAL; - memset(v,0,sizeof(*v)); - strcpy(v->name, "Radio"); - bttv_call_i2c_clients(btv,cmd,v); + if (0 != t->index) + return -EINVAL; + mutex_lock(&btv->lock); + memset(t,0,sizeof(*t)); + strcpy(t->name, "Radio"); + t->type = V4L2_TUNER_RADIO; + + bttv_call_i2c_clients(btv, VIDIOC_G_TUNER, t); + + if (btv->audio_mode_gpio) { + btv->audio_mode_gpio (btv,t,0); + } + + mutex_unlock(&btv->lock); + return 0; } - case VIDIOCSTUNER: - /* nothing to do */ - return 0; - - case BTTV_VERSION: - case VIDIOCGFREQ: - case VIDIOCSFREQ: - case VIDIOCGAUDIO: - case VIDIOCSAUDIO: + case VIDIOC_S_TUNER: + case VIDIOC_G_FREQUENCY: + case VIDIOC_S_FREQUENCY: + case VIDIOC_G_CTRL: + case VIDIOC_S_CTRL: case VIDIOC_LOG_STATUS: case VIDIOC_DBG_G_REGISTER: case VIDIOC_DBG_S_REGISTER: return bttv_common_ioctls(btv,cmd,arg); - default: - return -ENOIOCTLCMD; + return v4l_compat_translate_ioctl(inode,file,cmd,arg, + radio_do_ioctl); } return 0; } @@ -4830,7 +4221,7 @@ static int __devinit bttv_probe(struct pci_dev *dev, btv->init.btv = btv; btv->init.ov.w.width = 320; btv->init.ov.w.height = 240; - btv->init.fmt = format_by_palette(VIDEO_PALETTE_RGB24); + btv->init.fmt = format_by_fourcc(V4L2_PIX_FMT_BGR24); btv->init.width = 320; btv->init.height = 240; btv->input = 0; |