aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/ivtv
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-10-13 17:03:59 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-10-13 17:03:59 -0400
commitcf2fa66055d718ae13e62451bb546505f63906a2 (patch)
treee206d3f04e74a34e9aa88d21af6c26eea21d4121 /drivers/media/video/ivtv
parent4501a466f28788485604ee42641d7a5fe7258d16 (diff)
parent57f51dbc45f65f7ee1e8c8f77200bb8000e3e271 (diff)
Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6
* 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6: (313 commits) V4L/DVB (9186): Added support for Prof 7300 DVB-S/S2 cards V4L/DVB (9185): S2API: Ensure we have a reasonable ROLLOFF default V4L/DVB (9184): cx24116: Change the default SNR units back to percentage by default. V4L/DVB (9183): S2API: Return error of the caller provides 0 commands. V4L/DVB (9182): S2API: Added support for DTV_HIERARCHY V4L/DVB (9181): S2API: Add support fot DTV_GUARD_INTERVAL and DTV_TRANSMISSION_MODE V4L/DVB (9180): S2API: Added support for DTV_CODE_RATE_HP/LP V4L/DVB (9179): S2API: frontend.h cleanup V4L/DVB (9178): cx24116: Add module parameter to return SNR as ESNO. V4L/DVB (9177): S2API: Change _8PSK / _16APSK to PSK_8 and APSK_16 V4L/DVB (9176): Add support for DvbWorld USB cards with STV0288 demodulator. V4L/DVB (9175): Remove NULL pointer in stb6000 driver. V4L/DVB (9174): Allow custom inittab for ST STV0288 demodulator. V4L/DVB (9173): S2API: Remove the hardcoded command limit during validation V4L/DVB (9172): S2API: Bugfix related to DVB-S / DVB-S2 tuning for the legacy API. V4L/DVB (9171): S2API: Stop an OOPS if illegal commands are dumped in S2API. V4L/DVB (9170): cx24116: Sanity checking to data input via S2API to the cx24116 demod. V4L/DVB (9169): uvcvideo: Support two new Bison Electronics webcams. V4L/DVB (9168): Add support for MSI TV@nywhere Plus remote V4L/DVB: v4l2-dev: remove duplicated #include ...
Diffstat (limited to 'drivers/media/video/ivtv')
-rw-r--r--drivers/media/video/ivtv/ivtv-cards.h2
-rw-r--r--drivers/media/video/ivtv/ivtv-driver.c12
-rw-r--r--drivers/media/video/ivtv/ivtv-driver.h9
-rw-r--r--drivers/media/video/ivtv/ivtv-fileops.c8
-rw-r--r--drivers/media/video/ivtv/ivtv-fileops.h5
-rw-r--r--drivers/media/video/ivtv/ivtv-gpio.c2
-rw-r--r--drivers/media/video/ivtv/ivtv-gpio.h2
-rw-r--r--drivers/media/video/ivtv/ivtv-i2c.c2
-rw-r--r--drivers/media/video/ivtv/ivtv-ioctl.c58
-rw-r--r--drivers/media/video/ivtv/ivtv-irq.c9
-rw-r--r--drivers/media/video/ivtv/ivtv-streams.c42
-rw-r--r--drivers/media/video/ivtv/ivtv-vbi.c2
-rw-r--r--drivers/media/video/ivtv/ivtv-yuv.c1
-rw-r--r--drivers/media/video/ivtv/ivtvfb.c78
14 files changed, 115 insertions, 117 deletions
diff --git a/drivers/media/video/ivtv/ivtv-cards.h b/drivers/media/video/ivtv/ivtv-cards.h
index 381af1bceef8..0b8fe85fb697 100644
--- a/drivers/media/video/ivtv/ivtv-cards.h
+++ b/drivers/media/video/ivtv/ivtv-cards.h
@@ -154,7 +154,7 @@
154#define IVTV_CAP_ENCODER (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_TUNER | \ 154#define IVTV_CAP_ENCODER (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_TUNER | \
155 V4L2_CAP_AUDIO | V4L2_CAP_READWRITE | V4L2_CAP_VBI_CAPTURE | \ 155 V4L2_CAP_AUDIO | V4L2_CAP_READWRITE | V4L2_CAP_VBI_CAPTURE | \
156 V4L2_CAP_SLICED_VBI_CAPTURE) 156 V4L2_CAP_SLICED_VBI_CAPTURE)
157#define IVTV_CAP_DECODER (V4L2_CAP_VBI_OUTPUT | V4L2_CAP_VIDEO_OUTPUT | \ 157#define IVTV_CAP_DECODER (V4L2_CAP_VIDEO_OUTPUT | \
158 V4L2_CAP_SLICED_VBI_OUTPUT | V4L2_CAP_VIDEO_OUTPUT_OVERLAY) 158 V4L2_CAP_SLICED_VBI_OUTPUT | V4L2_CAP_VIDEO_OUTPUT_OVERLAY)
159 159
160struct ivtv_card_video_input { 160struct ivtv_card_video_input {
diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c
index 4afc7ea07e86..aeaa13f6cb36 100644
--- a/drivers/media/video/ivtv/ivtv-driver.c
+++ b/drivers/media/video/ivtv/ivtv-driver.c
@@ -61,14 +61,14 @@
61#include "tuner-xc2028.h" 61#include "tuner-xc2028.h"
62 62
63/* var to keep track of the number of array elements in use */ 63/* var to keep track of the number of array elements in use */
64int ivtv_cards_active = 0; 64int ivtv_cards_active;
65 65
66/* If you have already X v4l cards, then set this to X. This way 66/* If you have already X v4l cards, then set this to X. This way
67 the device numbers stay matched. Example: you have a WinTV card 67 the device numbers stay matched. Example: you have a WinTV card
68 without radio and a PVR-350 with. Normally this would give a 68 without radio and a PVR-350 with. Normally this would give a
69 video1 device together with a radio0 device for the PVR. By 69 video1 device together with a radio0 device for the PVR. By
70 setting this to 1 you ensure that radio0 is now also radio1. */ 70 setting this to 1 you ensure that radio0 is now also radio1. */
71int ivtv_first_minor = 0; 71int ivtv_first_minor;
72 72
73/* Master variable for all ivtv info */ 73/* Master variable for all ivtv info */
74struct ivtv *ivtv_cards[IVTV_MAX_CARDS]; 74struct ivtv *ivtv_cards[IVTV_MAX_CARDS];
@@ -251,7 +251,7 @@ MODULE_PARM_DESC(newi2c,
251 "\t\t\t-1 is autodetect, 0 is off, 1 is on\n" 251 "\t\t\t-1 is autodetect, 0 is off, 1 is on\n"
252 "\t\t\tDefault is autodetect"); 252 "\t\t\tDefault is autodetect");
253 253
254MODULE_PARM_DESC(ivtv_first_minor, "Set minor assigned to first card"); 254MODULE_PARM_DESC(ivtv_first_minor, "Set kernel number assigned to first card");
255 255
256MODULE_AUTHOR("Kevin Thayer, Chris Kennedy, Hans Verkuil"); 256MODULE_AUTHOR("Kevin Thayer, Chris Kennedy, Hans Verkuil");
257MODULE_DESCRIPTION("CX23415/CX23416 driver"); 257MODULE_DESCRIPTION("CX23415/CX23416 driver");
@@ -655,9 +655,9 @@ done:
655 655
656 if (itv->card == NULL) { 656 if (itv->card == NULL) {
657 itv->card = ivtv_get_card(IVTV_CARD_PVR_150); 657 itv->card = ivtv_get_card(IVTV_CARD_PVR_150);
658 IVTV_ERR("Unknown card: vendor/device: %04x/%04x\n", 658 IVTV_ERR("Unknown card: vendor/device: [%04x:%04x]\n",
659 itv->dev->vendor, itv->dev->device); 659 itv->dev->vendor, itv->dev->device);
660 IVTV_ERR(" subsystem vendor/device: %04x/%04x\n", 660 IVTV_ERR(" subsystem vendor/device: [%04x:%04x]\n",
661 itv->dev->subsystem_vendor, itv->dev->subsystem_device); 661 itv->dev->subsystem_vendor, itv->dev->subsystem_device);
662 IVTV_ERR(" %s based\n", chipname); 662 IVTV_ERR(" %s based\n", chipname);
663 IVTV_ERR("Defaulting to %s card\n", itv->card->name); 663 IVTV_ERR("Defaulting to %s card\n", itv->card->name);
@@ -720,7 +720,7 @@ static int __devinit ivtv_init_struct1(struct ivtv *itv)
720 itv->speed = 1000; 720 itv->speed = 1000;
721 721
722 /* VBI */ 722 /* VBI */
723 itv->vbi.in.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE; 723 itv->vbi.in.type = V4L2_BUF_TYPE_VBI_CAPTURE;
724 itv->vbi.sliced_in = &itv->vbi.in.fmt.sliced; 724 itv->vbi.sliced_in = &itv->vbi.in.fmt.sliced;
725 725
726 /* Init the sg table for osd/yuv output */ 726 /* Init the sg table for osd/yuv output */
diff --git a/drivers/media/video/ivtv/ivtv-driver.h b/drivers/media/video/ivtv/ivtv-driver.h
index 2ceb5227637c..bc29436e8a3c 100644
--- a/drivers/media/video/ivtv/ivtv-driver.h
+++ b/drivers/media/video/ivtv/ivtv-driver.h
@@ -49,7 +49,6 @@
49#include <linux/i2c-algo-bit.h> 49#include <linux/i2c-algo-bit.h>
50#include <linux/list.h> 50#include <linux/list.h>
51#include <linux/unistd.h> 51#include <linux/unistd.h>
52#include <linux/byteorder/swab.h>
53#include <linux/pagemap.h> 52#include <linux/pagemap.h>
54#include <linux/scatterlist.h> 53#include <linux/scatterlist.h>
55#include <linux/workqueue.h> 54#include <linux/workqueue.h>
@@ -507,6 +506,8 @@ struct yuv_playback_info
507 struct v4l2_rect main_rect; 506 struct v4l2_rect main_rect;
508 u32 v4l2_src_w; 507 u32 v4l2_src_w;
509 u32 v4l2_src_h; 508 u32 v4l2_src_h;
509
510 u8 running; /* Have any frames been displayed */
510}; 511};
511 512
512#define IVTV_VBI_FRAMES 32 513#define IVTV_VBI_FRAMES 32
@@ -751,6 +752,12 @@ void ivtv_read_eeprom(struct ivtv *itv, struct tveeprom *tv);
751/* First-open initialization: load firmware, init cx25840, etc. */ 752/* First-open initialization: load firmware, init cx25840, etc. */
752int ivtv_init_on_first_open(struct ivtv *itv); 753int ivtv_init_on_first_open(struct ivtv *itv);
753 754
755/* Test if the current VBI mode is raw (1) or sliced (0) */
756static inline int ivtv_raw_vbi(const struct ivtv *itv)
757{
758 return itv->vbi.in.type == V4L2_BUF_TYPE_VBI_CAPTURE;
759}
760
754/* This is a PCI post thing, where if the pci register is not read, then 761/* This is a PCI post thing, where if the pci register is not read, then
755 the write doesn't always take effect right away. By reading back the 762 the write doesn't always take effect right away. By reading back the
756 register any pending PCI writes will be performed (in order), and so 763 register any pending PCI writes will be performed (in order), and so
diff --git a/drivers/media/video/ivtv/ivtv-fileops.c b/drivers/media/video/ivtv/ivtv-fileops.c
index 7ec5c99f9ad1..b7457fc60ba5 100644
--- a/drivers/media/video/ivtv/ivtv-fileops.c
+++ b/drivers/media/video/ivtv/ivtv-fileops.c
@@ -39,7 +39,7 @@
39 associated VBI streams are also automatically claimed. 39 associated VBI streams are also automatically claimed.
40 Possible error returns: -EBUSY if someone else has claimed 40 Possible error returns: -EBUSY if someone else has claimed
41 the stream or 0 on success. */ 41 the stream or 0 on success. */
42int ivtv_claim_stream(struct ivtv_open_id *id, int type) 42static int ivtv_claim_stream(struct ivtv_open_id *id, int type)
43{ 43{
44 struct ivtv *itv = id->itv; 44 struct ivtv *itv = id->itv;
45 struct ivtv_stream *s = &itv->streams[type]; 45 struct ivtv_stream *s = &itv->streams[type];
@@ -78,7 +78,7 @@ int ivtv_claim_stream(struct ivtv_open_id *id, int type)
78 if (type == IVTV_DEC_STREAM_TYPE_MPG) { 78 if (type == IVTV_DEC_STREAM_TYPE_MPG) {
79 vbi_type = IVTV_DEC_STREAM_TYPE_VBI; 79 vbi_type = IVTV_DEC_STREAM_TYPE_VBI;
80 } else if (type == IVTV_ENC_STREAM_TYPE_MPG && 80 } else if (type == IVTV_ENC_STREAM_TYPE_MPG &&
81 itv->vbi.insert_mpeg && itv->vbi.sliced_in->service_set) { 81 itv->vbi.insert_mpeg && !ivtv_raw_vbi(itv)) {
82 vbi_type = IVTV_ENC_STREAM_TYPE_VBI; 82 vbi_type = IVTV_ENC_STREAM_TYPE_VBI;
83 } else { 83 } else {
84 return 0; 84 return 0;
@@ -305,7 +305,7 @@ static size_t ivtv_copy_buf_to_user(struct ivtv_stream *s, struct ivtv_buffer *b
305 305
306 if (len > ucount) len = ucount; 306 if (len > ucount) len = ucount;
307 if (itv->vbi.insert_mpeg && s->type == IVTV_ENC_STREAM_TYPE_MPG && 307 if (itv->vbi.insert_mpeg && s->type == IVTV_ENC_STREAM_TYPE_MPG &&
308 itv->vbi.sliced_in->service_set && buf != &itv->vbi.sliced_mpeg_buf) { 308 !ivtv_raw_vbi(itv) && buf != &itv->vbi.sliced_mpeg_buf) {
309 const char *start = buf->buf + buf->readpos; 309 const char *start = buf->buf + buf->readpos;
310 const char *p = start + 1; 310 const char *p = start + 1;
311 const u8 *q; 311 const u8 *q;
@@ -372,7 +372,7 @@ static ssize_t ivtv_read(struct ivtv_stream *s, char __user *ubuf, size_t tot_co
372 /* Each VBI buffer is one frame, the v4l2 API says that for VBI the frames should 372 /* Each VBI buffer is one frame, the v4l2 API says that for VBI the frames should
373 arrive one-by-one, so make sure we never output more than one VBI frame at a time */ 373 arrive one-by-one, so make sure we never output more than one VBI frame at a time */
374 if (s->type == IVTV_DEC_STREAM_TYPE_VBI || 374 if (s->type == IVTV_DEC_STREAM_TYPE_VBI ||
375 (s->type == IVTV_ENC_STREAM_TYPE_VBI && itv->vbi.sliced_in->service_set)) 375 (s->type == IVTV_ENC_STREAM_TYPE_VBI && !ivtv_raw_vbi(itv)))
376 single_frame = 1; 376 single_frame = 1;
377 377
378 for (;;) { 378 for (;;) {
diff --git a/drivers/media/video/ivtv/ivtv-fileops.h b/drivers/media/video/ivtv/ivtv-fileops.h
index 2c8d5186c9c3..df81e790147f 100644
--- a/drivers/media/video/ivtv/ivtv-fileops.h
+++ b/drivers/media/video/ivtv/ivtv-fileops.h
@@ -38,11 +38,6 @@ void ivtv_unmute(struct ivtv *itv);
38 38
39/* Utilities */ 39/* Utilities */
40 40
41/* Try to claim a stream for the filehandle. Return 0 on success,
42 -EBUSY if stream already claimed. Once a stream is claimed, it
43 remains claimed until the associated filehandle is closed. */
44int ivtv_claim_stream(struct ivtv_open_id *id, int type);
45
46/* Release a previously claimed stream. */ 41/* Release a previously claimed stream. */
47void ivtv_release_stream(struct ivtv_stream *s); 42void ivtv_release_stream(struct ivtv_stream *s);
48 43
diff --git a/drivers/media/video/ivtv/ivtv-gpio.c b/drivers/media/video/ivtv/ivtv-gpio.c
index bc22905ea20f..74a44844ccaf 100644
--- a/drivers/media/video/ivtv/ivtv-gpio.c
+++ b/drivers/media/video/ivtv/ivtv-gpio.c
@@ -124,7 +124,7 @@ void ivtv_reset_ir_gpio(struct ivtv *itv)
124} 124}
125 125
126/* Xceive tuner reset function */ 126/* Xceive tuner reset function */
127int ivtv_reset_tuner_gpio(void *dev, int cmd, int value) 127int ivtv_reset_tuner_gpio(void *dev, int component, int cmd, int value)
128{ 128{
129 struct i2c_algo_bit_data *algo = dev; 129 struct i2c_algo_bit_data *algo = dev;
130 struct ivtv *itv = algo->data; 130 struct ivtv *itv = algo->data;
diff --git a/drivers/media/video/ivtv/ivtv-gpio.h b/drivers/media/video/ivtv/ivtv-gpio.h
index 964a265d91a9..48b6291613a2 100644
--- a/drivers/media/video/ivtv/ivtv-gpio.h
+++ b/drivers/media/video/ivtv/ivtv-gpio.h
@@ -24,7 +24,7 @@
24/* GPIO stuff */ 24/* GPIO stuff */
25void ivtv_gpio_init(struct ivtv *itv); 25void ivtv_gpio_init(struct ivtv *itv);
26void ivtv_reset_ir_gpio(struct ivtv *itv); 26void ivtv_reset_ir_gpio(struct ivtv *itv);
27int ivtv_reset_tuner_gpio(void *dev, int cmd, int value); 27int ivtv_reset_tuner_gpio(void *dev, int component, int cmd, int value);
28int ivtv_gpio(struct ivtv *itv, unsigned int command, void *arg); 28int ivtv_gpio(struct ivtv *itv, unsigned int command, void *arg);
29 29
30#endif 30#endif
diff --git a/drivers/media/video/ivtv/ivtv-i2c.c b/drivers/media/video/ivtv/ivtv-i2c.c
index af154238fb9a..24700c211d52 100644
--- a/drivers/media/video/ivtv/ivtv-i2c.c
+++ b/drivers/media/video/ivtv/ivtv-i2c.c
@@ -64,8 +64,6 @@
64#include "ivtv-gpio.h" 64#include "ivtv-gpio.h"
65#include "ivtv-i2c.h" 65#include "ivtv-i2c.h"
66 66
67#include <media/ir-kbd-i2c.h>
68
69/* i2c implementation for cx23415/6 chip, ivtv project. 67/* i2c implementation for cx23415/6 chip, ivtv project.
70 * Author: Kevin Thayer (nufan_wfk at yahoo.com) 68 * Author: Kevin Thayer (nufan_wfk at yahoo.com)
71 */ 69 */
diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c
index 61030309d0ad..8696527ab134 100644
--- a/drivers/media/video/ivtv/ivtv-ioctl.c
+++ b/drivers/media/video/ivtv/ivtv-ioctl.c
@@ -101,18 +101,15 @@ void ivtv_expand_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal)
101 } 101 }
102} 102}
103 103
104static int check_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal) 104static void check_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal)
105{ 105{
106 int f, l; 106 int f, l;
107 u16 set = 0;
108 107
109 for (f = 0; f < 2; f++) { 108 for (f = 0; f < 2; f++) {
110 for (l = 0; l < 24; l++) { 109 for (l = 0; l < 24; l++) {
111 fmt->service_lines[f][l] = select_service_from_set(f, l, fmt->service_lines[f][l], is_pal); 110 fmt->service_lines[f][l] = select_service_from_set(f, l, fmt->service_lines[f][l], is_pal);
112 set |= fmt->service_lines[f][l];
113 } 111 }
114 } 112 }
115 return set != 0;
116} 113}
117 114
118u16 ivtv_get_service_set(struct v4l2_sliced_vbi_format *fmt) 115u16 ivtv_get_service_set(struct v4l2_sliced_vbi_format *fmt)
@@ -474,7 +471,7 @@ static int ivtv_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format
474 int h = fmt->fmt.pix.height; 471 int h = fmt->fmt.pix.height;
475 472
476 w = min(w, 720); 473 w = min(w, 720);
477 w = max(w, 1); 474 w = max(w, 2);
478 h = min(h, itv->is_50hz ? 576 : 480); 475 h = min(h, itv->is_50hz ? 576 : 480);
479 h = max(h, 2); 476 h = max(h, 2);
480 ivtv_g_fmt_vid_cap(file, fh, fmt); 477 ivtv_g_fmt_vid_cap(file, fh, fmt);
@@ -512,27 +509,20 @@ static int ivtv_try_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_
512static int ivtv_try_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *fmt) 509static int ivtv_try_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *fmt)
513{ 510{
514 struct ivtv_open_id *id = fh; 511 struct ivtv_open_id *id = fh;
515 s32 w, h; 512 struct ivtv *itv = id->itv;
516 int field; 513 s32 w = fmt->fmt.pix.width;
517 int ret; 514 s32 h = fmt->fmt.pix.height;
515 int field = fmt->fmt.pix.field;
516 int ret = ivtv_g_fmt_vid_out(file, fh, fmt);
518 517
519 w = fmt->fmt.pix.width; 518 w = min(w, 720);
520 h = fmt->fmt.pix.height; 519 w = max(w, 2);
521 field = fmt->fmt.pix.field; 520 h = min(h, itv->is_out_50hz ? 576 : 480);
522 ret = ivtv_g_fmt_vid_out(file, fh, fmt); 521 h = max(h, 2);
522 if (id->type == IVTV_DEC_STREAM_TYPE_YUV)
523 fmt->fmt.pix.field = field;
523 fmt->fmt.pix.width = w; 524 fmt->fmt.pix.width = w;
524 fmt->fmt.pix.height = h; 525 fmt->fmt.pix.height = h;
525 if (!ret && id->type == IVTV_DEC_STREAM_TYPE_YUV) {
526 fmt->fmt.pix.field = field;
527 if (fmt->fmt.pix.width < 2)
528 fmt->fmt.pix.width = 2;
529 if (fmt->fmt.pix.width > 720)
530 fmt->fmt.pix.width = 720;
531 if (fmt->fmt.pix.height < 2)
532 fmt->fmt.pix.height = 2;
533 if (fmt->fmt.pix.height > 576)
534 fmt->fmt.pix.height = 576;
535 }
536 return ret; 526 return ret;
537} 527}
538 528
@@ -560,9 +550,9 @@ static int ivtv_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f
560 struct ivtv_open_id *id = fh; 550 struct ivtv_open_id *id = fh;
561 struct ivtv *itv = id->itv; 551 struct ivtv *itv = id->itv;
562 struct cx2341x_mpeg_params *p = &itv->params; 552 struct cx2341x_mpeg_params *p = &itv->params;
553 int ret = ivtv_try_fmt_vid_cap(file, fh, fmt);
563 int w = fmt->fmt.pix.width; 554 int w = fmt->fmt.pix.width;
564 int h = fmt->fmt.pix.height; 555 int h = fmt->fmt.pix.height;
565 int ret = ivtv_try_fmt_vid_cap(file, fh, fmt);
566 556
567 if (ret) 557 if (ret)
568 return ret; 558 return ret;
@@ -585,8 +575,11 @@ static int ivtv_s_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *f
585{ 575{
586 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; 576 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
587 577
578 if (!ivtv_raw_vbi(itv) && atomic_read(&itv->capturing) > 0)
579 return -EBUSY;
588 itv->vbi.sliced_in->service_set = 0; 580 itv->vbi.sliced_in->service_set = 0;
589 itv->video_dec_func(itv, VIDIOC_S_FMT, &itv->vbi.in); 581 itv->vbi.in.type = V4L2_BUF_TYPE_VBI_CAPTURE;
582 itv->video_dec_func(itv, VIDIOC_S_FMT, fmt);
590 return ivtv_g_fmt_vbi_cap(file, fh, fmt); 583 return ivtv_g_fmt_vbi_cap(file, fh, fmt);
591} 584}
592 585
@@ -600,10 +593,10 @@ static int ivtv_s_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_fo
600 if (ret || id->type == IVTV_DEC_STREAM_TYPE_VBI) 593 if (ret || id->type == IVTV_DEC_STREAM_TYPE_VBI)
601 return ret; 594 return ret;
602 595
603 if (check_service_set(vbifmt, itv->is_50hz) == 0) 596 check_service_set(vbifmt, itv->is_50hz);
604 return -EINVAL; 597 if (ivtv_raw_vbi(itv) && atomic_read(&itv->capturing) > 0)
605 if (atomic_read(&itv->capturing) > 0)
606 return -EBUSY; 598 return -EBUSY;
599 itv->vbi.in.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE;
607 itv->video_dec_func(itv, VIDIOC_S_FMT, fmt); 600 itv->video_dec_func(itv, VIDIOC_S_FMT, fmt);
608 memcpy(itv->vbi.sliced_in, vbifmt, sizeof(*itv->vbi.sliced_in)); 601 memcpy(itv->vbi.sliced_in, vbifmt, sizeof(*itv->vbi.sliced_in));
609 return 0; 602 return 0;
@@ -651,8 +644,6 @@ static int ivtv_s_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *f
651 itv->dma_data_req_size = 644 itv->dma_data_req_size =
652 1080 * ((yi->v4l2_src_h + 31) & ~31); 645 1080 * ((yi->v4l2_src_h + 31) & ~31);
653 646
654 /* Force update of yuv registers */
655 yi->yuv_forced_update = 1;
656 return 0; 647 return 0;
657} 648}
658 649
@@ -761,7 +752,7 @@ static int ivtv_querycap(struct file *file, void *fh, struct v4l2_capability *vc
761 752
762 strlcpy(vcap->driver, IVTV_DRIVER_NAME, sizeof(vcap->driver)); 753 strlcpy(vcap->driver, IVTV_DRIVER_NAME, sizeof(vcap->driver));
763 strlcpy(vcap->card, itv->card_name, sizeof(vcap->card)); 754 strlcpy(vcap->card, itv->card_name, sizeof(vcap->card));
764 strlcpy(vcap->bus_info, pci_name(itv->dev), sizeof(vcap->bus_info)); 755 snprintf(vcap->bus_info, sizeof(vcap->bus_info), "PCI:%s", pci_name(itv->dev));
765 vcap->version = IVTV_DRIVER_VERSION; /* version */ 756 vcap->version = IVTV_DRIVER_VERSION; /* version */
766 vcap->capabilities = itv->v4l2_cap; /* capabilities */ 757 vcap->capabilities = itv->v4l2_cap; /* capabilities */
767 return 0; 758 return 0;
@@ -1370,6 +1361,9 @@ static int ivtv_g_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb)
1370 if (itv->osd_global_alpha_state) 1361 if (itv->osd_global_alpha_state)
1371 fb->flags |= V4L2_FBUF_FLAG_GLOBAL_ALPHA; 1362 fb->flags |= V4L2_FBUF_FLAG_GLOBAL_ALPHA;
1372 1363
1364 if (yi->track_osd)
1365 fb->flags |= V4L2_FBUF_FLAG_OVERLAY;
1366
1373 pixfmt &= 7; 1367 pixfmt &= 7;
1374 1368
1375 /* no local alpha for RGB565 or unknown formats */ 1369 /* no local alpha for RGB565 or unknown formats */
@@ -1389,8 +1383,6 @@ static int ivtv_g_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb)
1389 else 1383 else
1390 fb->flags |= V4L2_FBUF_FLAG_LOCAL_ALPHA; 1384 fb->flags |= V4L2_FBUF_FLAG_LOCAL_ALPHA;
1391 } 1385 }
1392 if (yi->track_osd)
1393 fb->flags |= V4L2_FBUF_FLAG_OVERLAY;
1394 1386
1395 return 0; 1387 return 0;
1396} 1388}
diff --git a/drivers/media/video/ivtv/ivtv-irq.c b/drivers/media/video/ivtv/ivtv-irq.c
index 34f3ab827858..f5d00ec5da73 100644
--- a/drivers/media/video/ivtv/ivtv-irq.c
+++ b/drivers/media/video/ivtv/ivtv-irq.c
@@ -753,7 +753,7 @@ static void ivtv_irq_vsync(struct ivtv *itv)
753 */ 753 */
754 unsigned int frame = read_reg(0x28c0) & 1; 754 unsigned int frame = read_reg(0x28c0) & 1;
755 struct yuv_playback_info *yi = &itv->yuv_info; 755 struct yuv_playback_info *yi = &itv->yuv_info;
756 int last_dma_frame = atomic_read(&itv->yuv_info.next_dma_frame); 756 int last_dma_frame = atomic_read(&yi->next_dma_frame);
757 struct yuv_frame_info *f = &yi->new_frame_info[last_dma_frame]; 757 struct yuv_frame_info *f = &yi->new_frame_info[last_dma_frame];
758 758
759 if (0) IVTV_DEBUG_IRQ("DEC VSYNC\n"); 759 if (0) IVTV_DEBUG_IRQ("DEC VSYNC\n");
@@ -772,6 +772,7 @@ static void ivtv_irq_vsync(struct ivtv *itv)
772 next_dma_frame = (next_dma_frame + 1) % IVTV_YUV_BUFFERS; 772 next_dma_frame = (next_dma_frame + 1) % IVTV_YUV_BUFFERS;
773 atomic_set(&yi->next_dma_frame, next_dma_frame); 773 atomic_set(&yi->next_dma_frame, next_dma_frame);
774 yi->fields_lapsed = -1; 774 yi->fields_lapsed = -1;
775 yi->running = 1;
775 } 776 }
776 } 777 }
777 } 778 }
@@ -804,9 +805,11 @@ static void ivtv_irq_vsync(struct ivtv *itv)
804 } 805 }
805 806
806 /* Check if we need to update the yuv registers */ 807 /* Check if we need to update the yuv registers */
807 if ((yi->yuv_forced_update || f->update) && last_dma_frame != -1) { 808 if (yi->running && (yi->yuv_forced_update || f->update)) {
808 if (!f->update) { 809 if (!f->update) {
809 last_dma_frame = (u8)(last_dma_frame - 1) % IVTV_YUV_BUFFERS; 810 last_dma_frame =
811 (u8)(atomic_read(&yi->next_dma_frame) -
812 1) % IVTV_YUV_BUFFERS;
810 f = &yi->new_frame_info[last_dma_frame]; 813 f = &yi->new_frame_info[last_dma_frame];
811 } 814 }
812 815
diff --git a/drivers/media/video/ivtv/ivtv-streams.c b/drivers/media/video/ivtv/ivtv-streams.c
index 730e85d86fc8..5bbf31e39304 100644
--- a/drivers/media/video/ivtv/ivtv-streams.c
+++ b/drivers/media/video/ivtv/ivtv-streams.c
@@ -75,7 +75,7 @@ static const struct file_operations ivtv_v4l2_dec_fops = {
75static struct { 75static struct {
76 const char *name; 76 const char *name;
77 int vfl_type; 77 int vfl_type;
78 int minor_offset; 78 int num_offset;
79 int dma, pio; 79 int dma, pio;
80 enum v4l2_buf_type buf_type; 80 enum v4l2_buf_type buf_type;
81 const struct file_operations *fops; 81 const struct file_operations *fops;
@@ -171,8 +171,8 @@ static void ivtv_stream_init(struct ivtv *itv, int type)
171static int ivtv_prep_dev(struct ivtv *itv, int type) 171static int ivtv_prep_dev(struct ivtv *itv, int type)
172{ 172{
173 struct ivtv_stream *s = &itv->streams[type]; 173 struct ivtv_stream *s = &itv->streams[type];
174 int minor_offset = ivtv_stream_info[type].minor_offset; 174 int num_offset = ivtv_stream_info[type].num_offset;
175 int minor; 175 int num = itv->num + ivtv_first_minor + num_offset;
176 176
177 /* These four fields are always initialized. If v4l2dev == NULL, then 177 /* These four fields are always initialized. If v4l2dev == NULL, then
178 this stream is not in use. In that case no other fields but these 178 this stream is not in use. In that case no other fields but these
@@ -188,9 +188,6 @@ static int ivtv_prep_dev(struct ivtv *itv, int type)
188 if (type >= IVTV_DEC_STREAM_TYPE_MPG && !(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) 188 if (type >= IVTV_DEC_STREAM_TYPE_MPG && !(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
189 return 0; 189 return 0;
190 190
191 /* card number + user defined offset + device offset */
192 minor = itv->num + ivtv_first_minor + minor_offset;
193
194 /* User explicitly selected 0 buffers for these streams, so don't 191 /* User explicitly selected 0 buffers for these streams, so don't
195 create them. */ 192 create them. */
196 if (ivtv_stream_info[type].dma != PCI_DMA_NONE && 193 if (ivtv_stream_info[type].dma != PCI_DMA_NONE &&
@@ -211,7 +208,7 @@ static int ivtv_prep_dev(struct ivtv *itv, int type)
211 snprintf(s->v4l2dev->name, sizeof(s->v4l2dev->name), "ivtv%d %s", 208 snprintf(s->v4l2dev->name, sizeof(s->v4l2dev->name), "ivtv%d %s",
212 itv->num, s->name); 209 itv->num, s->name);
213 210
214 s->v4l2dev->minor = minor; 211 s->v4l2dev->num = num;
215 s->v4l2dev->parent = &itv->dev->dev; 212 s->v4l2dev->parent = &itv->dev->dev;
216 s->v4l2dev->fops = ivtv_stream_info[type].fops; 213 s->v4l2dev->fops = ivtv_stream_info[type].fops;
217 s->v4l2dev->release = video_device_release; 214 s->v4l2dev->release = video_device_release;
@@ -250,39 +247,46 @@ static int ivtv_reg_dev(struct ivtv *itv, int type)
250{ 247{
251 struct ivtv_stream *s = &itv->streams[type]; 248 struct ivtv_stream *s = &itv->streams[type];
252 int vfl_type = ivtv_stream_info[type].vfl_type; 249 int vfl_type = ivtv_stream_info[type].vfl_type;
253 int minor; 250 int num;
254 251
255 if (s->v4l2dev == NULL) 252 if (s->v4l2dev == NULL)
256 return 0; 253 return 0;
257 254
258 minor = s->v4l2dev->minor; 255 num = s->v4l2dev->num;
256 /* card number + user defined offset + device offset */
257 if (type != IVTV_ENC_STREAM_TYPE_MPG) {
258 struct ivtv_stream *s_mpg = &itv->streams[IVTV_ENC_STREAM_TYPE_MPG];
259
260 if (s_mpg->v4l2dev)
261 num = s_mpg->v4l2dev->num + ivtv_stream_info[type].num_offset;
262 }
263
259 /* Register device. First try the desired minor, then any free one. */ 264 /* Register device. First try the desired minor, then any free one. */
260 if (video_register_device(s->v4l2dev, vfl_type, minor) && 265 if (video_register_device(s->v4l2dev, vfl_type, num)) {
261 video_register_device(s->v4l2dev, vfl_type, -1)) { 266 IVTV_ERR("Couldn't register v4l2 device for %s kernel number %d\n",
262 IVTV_ERR("Couldn't register v4l2 device for %s minor %d\n", 267 s->name, num);
263 s->name, minor);
264 video_device_release(s->v4l2dev); 268 video_device_release(s->v4l2dev);
265 s->v4l2dev = NULL; 269 s->v4l2dev = NULL;
266 return -ENOMEM; 270 return -ENOMEM;
267 } 271 }
272 num = s->v4l2dev->num;
268 273
269 switch (vfl_type) { 274 switch (vfl_type) {
270 case VFL_TYPE_GRABBER: 275 case VFL_TYPE_GRABBER:
271 IVTV_INFO("Registered device video%d for %s (%d kB)\n", 276 IVTV_INFO("Registered device video%d for %s (%d kB)\n",
272 s->v4l2dev->minor, s->name, itv->options.kilobytes[type]); 277 num, s->name, itv->options.kilobytes[type]);
273 break; 278 break;
274 case VFL_TYPE_RADIO: 279 case VFL_TYPE_RADIO:
275 IVTV_INFO("Registered device radio%d for %s\n", 280 IVTV_INFO("Registered device radio%d for %s\n",
276 s->v4l2dev->minor - MINOR_VFL_TYPE_RADIO_MIN, s->name); 281 num, s->name);
277 break; 282 break;
278 case VFL_TYPE_VBI: 283 case VFL_TYPE_VBI:
279 if (itv->options.kilobytes[type]) 284 if (itv->options.kilobytes[type])
280 IVTV_INFO("Registered device vbi%d for %s (%d kB)\n", 285 IVTV_INFO("Registered device vbi%d for %s (%d kB)\n",
281 s->v4l2dev->minor - MINOR_VFL_TYPE_VBI_MIN, 286 num, s->name, itv->options.kilobytes[type]);
282 s->name, itv->options.kilobytes[type]);
283 else 287 else
284 IVTV_INFO("Registered device vbi%d for %s\n", 288 IVTV_INFO("Registered device vbi%d for %s\n",
285 s->v4l2dev->minor - MINOR_VFL_TYPE_VBI_MIN, s->name); 289 num, s->name);
286 break; 290 break;
287 } 291 }
288 return 0; 292 return 0;
@@ -330,7 +334,7 @@ void ivtv_streams_cleanup(struct ivtv *itv, int unregister)
330 334
331static void ivtv_vbi_setup(struct ivtv *itv) 335static void ivtv_vbi_setup(struct ivtv *itv)
332{ 336{
333 int raw = itv->vbi.sliced_in->service_set == 0; 337 int raw = ivtv_raw_vbi(itv);
334 u32 data[CX2341X_MBOX_MAX_DATA]; 338 u32 data[CX2341X_MBOX_MAX_DATA];
335 int lines; 339 int lines;
336 int i; 340 int i;
diff --git a/drivers/media/video/ivtv/ivtv-vbi.c b/drivers/media/video/ivtv/ivtv-vbi.c
index 1ce9deb1104f..4a37a7d2e69d 100644
--- a/drivers/media/video/ivtv/ivtv-vbi.c
+++ b/drivers/media/video/ivtv/ivtv-vbi.c
@@ -334,7 +334,7 @@ void ivtv_process_vbi_data(struct ivtv *itv, struct ivtv_buffer *buf,
334 int y; 334 int y;
335 335
336 /* Raw VBI data */ 336 /* Raw VBI data */
337 if (streamtype == IVTV_ENC_STREAM_TYPE_VBI && itv->vbi.sliced_in->service_set == 0) { 337 if (streamtype == IVTV_ENC_STREAM_TYPE_VBI && ivtv_raw_vbi(itv)) {
338 u8 type; 338 u8 type;
339 339
340 ivtv_buf_swap(buf); 340 ivtv_buf_swap(buf);
diff --git a/drivers/media/video/ivtv/ivtv-yuv.c b/drivers/media/video/ivtv/ivtv-yuv.c
index 3092ff1d00a0..ee91107376c7 100644
--- a/drivers/media/video/ivtv/ivtv-yuv.c
+++ b/drivers/media/video/ivtv/ivtv-yuv.c
@@ -1147,6 +1147,7 @@ void ivtv_yuv_close(struct ivtv *itv)
1147 IVTV_DEBUG_YUV("ivtv_yuv_close\n"); 1147 IVTV_DEBUG_YUV("ivtv_yuv_close\n");
1148 ivtv_waitq(&itv->vsync_waitq); 1148 ivtv_waitq(&itv->vsync_waitq);
1149 1149
1150 yi->running = 0;
1150 atomic_set(&yi->next_dma_frame, -1); 1151 atomic_set(&yi->next_dma_frame, -1);
1151 atomic_set(&yi->next_fill_frame, 0); 1152 atomic_set(&yi->next_fill_frame, 0);
1152 1153
diff --git a/drivers/media/video/ivtv/ivtvfb.c b/drivers/media/video/ivtv/ivtvfb.c
index bdfda48e56bf..8a4a150b12fb 100644
--- a/drivers/media/video/ivtv/ivtvfb.c
+++ b/drivers/media/video/ivtv/ivtvfb.c
@@ -275,7 +275,6 @@ static int ivtvfb_prep_dec_dma_to_device(struct ivtv *itv,
275 int size_in_bytes) 275 int size_in_bytes)
276{ 276{
277 DEFINE_WAIT(wait); 277 DEFINE_WAIT(wait);
278 int ret = 0;
279 int got_sig = 0; 278 int got_sig = 0;
280 279
281 mutex_lock(&itv->udma.lock); 280 mutex_lock(&itv->udma.lock);
@@ -316,7 +315,7 @@ static int ivtvfb_prep_dec_dma_to_device(struct ivtv *itv,
316 return -EINTR; 315 return -EINTR;
317 } 316 }
318 317
319 return ret; 318 return 0;
320} 319}
321 320
322static int ivtvfb_prep_frame(struct ivtv *itv, int cmd, void __user *source, 321static int ivtvfb_prep_frame(struct ivtv *itv, int cmd, void __user *source,
@@ -368,11 +367,12 @@ static int ivtvfb_prep_frame(struct ivtv *itv, int cmd, void __user *source,
368} 367}
369 368
370static ssize_t ivtvfb_write(struct fb_info *info, const char __user *buf, 369static ssize_t ivtvfb_write(struct fb_info *info, const char __user *buf,
371 size_t count, loff_t *ppos) 370 size_t count, loff_t *ppos)
372{ 371{
373 unsigned long p = *ppos; 372 unsigned long p = *ppos;
374 void *dst; 373 void *dst;
375 int err = 0; 374 int err = 0;
375 int dma_err;
376 unsigned long total_size; 376 unsigned long total_size;
377 struct ivtv *itv = (struct ivtv *) info->par; 377 struct ivtv *itv = (struct ivtv *) info->par;
378 unsigned long dma_offset = 378 unsigned long dma_offset =
@@ -399,7 +399,6 @@ static ssize_t ivtvfb_write(struct fb_info *info, const char __user *buf,
399 if (count + p > total_size) { 399 if (count + p > total_size) {
400 if (!err) 400 if (!err)
401 err = -ENOSPC; 401 err = -ENOSPC;
402
403 count = total_size - p; 402 count = total_size - p;
404 } 403 }
405 404
@@ -408,39 +407,34 @@ static ssize_t ivtvfb_write(struct fb_info *info, const char __user *buf,
408 if (info->fbops->fb_sync) 407 if (info->fbops->fb_sync)
409 info->fbops->fb_sync(info); 408 info->fbops->fb_sync(info);
410 409
411 if (!access_ok(VERIFY_READ, buf, count)) { 410 /* If transfer size > threshold and both src/dst
412 IVTVFB_WARN("Invalid userspace pointer 0x%08lx\n", 411 addresses are aligned, use DMA */
413 (unsigned long)buf); 412 if (count >= 4096 &&
414 err = -EFAULT; 413 ((unsigned long)buf & 3) == ((unsigned long)dst & 3)) {
415 } 414 /* Odd address = can't DMA. Align */
416 415 if ((unsigned long)dst & 3) {
417 if (!err) { 416 lead = 4 - ((unsigned long)dst & 3);
418 /* If transfer size > threshold and both src/dst 417 if (copy_from_user(dst, buf, lead))
419 addresses are aligned, use DMA */ 418 return -EFAULT;
420 if (count >= 4096 && 419 buf += lead;
421 ((unsigned long)buf & 3) == ((unsigned long)dst & 3)) { 420 dst += lead;
422 /* Odd address = can't DMA. Align */
423 if ((unsigned long)dst & 3) {
424 lead = 4 - ((unsigned long)dst & 3);
425 memcpy(dst, buf, lead);
426 buf += lead;
427 dst += lead;
428 }
429 /* DMA resolution is 32 bits */
430 if ((count - lead) & 3)
431 tail = (count - lead) & 3;
432 /* DMA the data */
433 dma_size = count - lead - tail;
434 err = ivtvfb_prep_dec_dma_to_device(itv,
435 p + lead + dma_offset, (void *)buf, dma_size);
436 dst += dma_size;
437 buf += dma_size;
438 /* Copy any leftover data */
439 if (tail)
440 memcpy(dst, buf, tail);
441 } else {
442 memcpy(dst, buf, count);
443 } 421 }
422 /* DMA resolution is 32 bits */
423 if ((count - lead) & 3)
424 tail = (count - lead) & 3;
425 /* DMA the data */
426 dma_size = count - lead - tail;
427 dma_err = ivtvfb_prep_dec_dma_to_device(itv,
428 p + lead + dma_offset, (void __user *)buf, dma_size);
429 if (dma_err)
430 return dma_err;
431 dst += dma_size;
432 buf += dma_size;
433 /* Copy any leftover data */
434 if (tail && copy_from_user(dst, buf, tail))
435 return -EFAULT;
436 } else if (copy_from_user(dst, buf, count)) {
437 return -EFAULT;
444 } 438 }
445 439
446 if (!err) 440 if (!err)
@@ -463,9 +457,12 @@ static int ivtvfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long ar
463 vblank.flags = FB_VBLANK_HAVE_COUNT |FB_VBLANK_HAVE_VCOUNT | 457 vblank.flags = FB_VBLANK_HAVE_COUNT |FB_VBLANK_HAVE_VCOUNT |
464 FB_VBLANK_HAVE_VSYNC; 458 FB_VBLANK_HAVE_VSYNC;
465 trace = read_reg(0x028c0) >> 16; 459 trace = read_reg(0x028c0) >> 16;
466 if (itv->is_50hz && trace > 312) trace -= 312; 460 if (itv->is_50hz && trace > 312)
467 else if (itv->is_60hz && trace > 262) trace -= 262; 461 trace -= 312;
468 if (trace == 1) vblank.flags |= FB_VBLANK_VSYNCING; 462 else if (itv->is_60hz && trace > 262)
463 trace -= 262;
464 if (trace == 1)
465 vblank.flags |= FB_VBLANK_VSYNCING;
469 vblank.count = itv->last_vsync_field; 466 vblank.count = itv->last_vsync_field;
470 vblank.vcount = trace; 467 vblank.vcount = trace;
471 vblank.hcount = 0; 468 vblank.hcount = 0;
@@ -476,7 +473,8 @@ static int ivtvfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long ar
476 473
477 case FBIO_WAITFORVSYNC: 474 case FBIO_WAITFORVSYNC:
478 prepare_to_wait(&itv->vsync_waitq, &wait, TASK_INTERRUPTIBLE); 475 prepare_to_wait(&itv->vsync_waitq, &wait, TASK_INTERRUPTIBLE);
479 if (!schedule_timeout(msecs_to_jiffies(50))) rc = -ETIMEDOUT; 476 if (!schedule_timeout(msecs_to_jiffies(50)))
477 rc = -ETIMEDOUT;
480 finish_wait(&itv->vsync_waitq, &wait); 478 finish_wait(&itv->vsync_waitq, &wait);
481 return rc; 479 return rc;
482 480