From 29e66a6ce84abe04bc809ddb35634752881dec79 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Thu, 4 Sep 2008 17:24:51 -0300 Subject: V4L/DVB: follow lspci device/vendor style Use "[%04x:%04x]" for PCI vendor/device IDs to follow the format used by lspci(8). Signed-off-by: Bjorn Helgaas Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/ivtv/ivtv-driver.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/media/video/ivtv') diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c index 4afc7ea07e8..6b04930d127 100644 --- a/drivers/media/video/ivtv/ivtv-driver.c +++ b/drivers/media/video/ivtv/ivtv-driver.c @@ -655,9 +655,9 @@ done: if (itv->card == NULL) { itv->card = ivtv_get_card(IVTV_CARD_PVR_150); - IVTV_ERR("Unknown card: vendor/device: %04x/%04x\n", + IVTV_ERR("Unknown card: vendor/device: [%04x:%04x]\n", itv->dev->vendor, itv->dev->device); - IVTV_ERR(" subsystem vendor/device: %04x/%04x\n", + IVTV_ERR(" subsystem vendor/device: [%04x:%04x]\n", itv->dev->subsystem_vendor, itv->dev->subsystem_device); IVTV_ERR(" %s based\n", chipname); IVTV_ERR("Defaulting to %s card\n", itv->card->name); -- cgit v1.2.3-70-g09d2 From 95f73c5b57990c97047c200b8746ab62a360c5bc Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Tue, 22 Jul 2008 14:20:12 -0300 Subject: V4L/DVB (8561): make ivtv_claim_stream() static ivtv_claim_stream() can now become static. Signed-off-by: Adrian Bunk Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/ivtv/ivtv-fileops.c | 2 +- drivers/media/video/ivtv/ivtv-fileops.h | 5 ----- 2 files changed, 1 insertion(+), 6 deletions(-) (limited to 'drivers/media/video/ivtv') diff --git a/drivers/media/video/ivtv/ivtv-fileops.c b/drivers/media/video/ivtv/ivtv-fileops.c index 7ec5c99f9ad..304261efc53 100644 --- a/drivers/media/video/ivtv/ivtv-fileops.c +++ b/drivers/media/video/ivtv/ivtv-fileops.c @@ -39,7 +39,7 @@ associated VBI streams are also automatically claimed. Possible error returns: -EBUSY if someone else has claimed the stream or 0 on success. */ -int ivtv_claim_stream(struct ivtv_open_id *id, int type) +static int ivtv_claim_stream(struct ivtv_open_id *id, int type) { struct ivtv *itv = id->itv; struct ivtv_stream *s = &itv->streams[type]; diff --git a/drivers/media/video/ivtv/ivtv-fileops.h b/drivers/media/video/ivtv/ivtv-fileops.h index 2c8d5186c9c..df81e790147 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); /* Utilities */ -/* Try to claim a stream for the filehandle. Return 0 on success, - -EBUSY if stream already claimed. Once a stream is claimed, it - remains claimed until the associated filehandle is closed. */ -int ivtv_claim_stream(struct ivtv_open_id *id, int type); - /* Release a previously claimed stream. */ void ivtv_release_stream(struct ivtv_stream *s); -- cgit v1.2.3-70-g09d2 From 20c104d0a4d055cfa3df4fcbae818f8e10bd541a Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 30 Aug 2008 08:21:13 -0300 Subject: V4L/DVB (8856): v4l: fix assorted compile warnings/errors BIT define conflicts on kernels < 2.6.24, byteorder/swab.h doesn't need to be included at all. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx18/cx18-driver.h | 1 - drivers/media/video/cx18/cx18-i2c.c | 2 -- drivers/media/video/ivtv/ivtv-driver.h | 1 - drivers/media/video/ivtv/ivtv-i2c.c | 2 -- drivers/media/video/vpx3220.c | 2 -- 5 files changed, 8 deletions(-) (limited to 'drivers/media/video/ivtv') diff --git a/drivers/media/video/cx18/cx18-driver.h b/drivers/media/video/cx18/cx18-driver.h index 26359897d14..7bdd2fcdf20 100644 --- a/drivers/media/video/cx18/cx18-driver.h +++ b/drivers/media/video/cx18/cx18-driver.h @@ -38,7 +38,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/media/video/cx18/cx18-i2c.c b/drivers/media/video/cx18/cx18-i2c.c index 6023ba3bd3a..7d8fb25baae 100644 --- a/drivers/media/video/cx18/cx18-i2c.c +++ b/drivers/media/video/cx18/cx18-i2c.c @@ -27,8 +27,6 @@ #include "cx18-av-core.h" #include "cx18-i2c.h" -#include - #define CX18_REG_I2C_1_WR 0xf15000 #define CX18_REG_I2C_1_RD 0xf15008 #define CX18_REG_I2C_2_WR 0xf25100 diff --git a/drivers/media/video/ivtv/ivtv-driver.h b/drivers/media/video/ivtv/ivtv-driver.h index 2ceb5227637..b76a1226863 100644 --- a/drivers/media/video/ivtv/ivtv-driver.h +++ b/drivers/media/video/ivtv/ivtv-driver.h @@ -49,7 +49,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/media/video/ivtv/ivtv-i2c.c b/drivers/media/video/ivtv/ivtv-i2c.c index af154238fb9..24700c211d5 100644 --- a/drivers/media/video/ivtv/ivtv-i2c.c +++ b/drivers/media/video/ivtv/ivtv-i2c.c @@ -64,8 +64,6 @@ #include "ivtv-gpio.h" #include "ivtv-i2c.h" -#include - /* i2c implementation for cx23415/6 chip, ivtv project. * Author: Kevin Thayer (nufan_wfk at yahoo.com) */ diff --git a/drivers/media/video/vpx3220.c b/drivers/media/video/vpx3220.c index 35293029da0..45be9ec8edc 100644 --- a/drivers/media/video/vpx3220.c +++ b/drivers/media/video/vpx3220.c @@ -24,8 +24,6 @@ #include #include -#include - #include #include -- cgit v1.2.3-70-g09d2 From effc3466d32108bec7da19aa23c1fddee9cafbab Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 6 Sep 2008 08:24:37 -0300 Subject: V4L/DVB (8920): cx18/ivtv: fix check of window boundaries for VIDIOC_S_FMT It was possible to set out-of-bounds windows sizes, this is now fixed. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx18/cx18-ioctl.c | 6 +++--- drivers/media/video/ivtv/ivtv-ioctl.c | 29 +++++++++++------------------ 2 files changed, 14 insertions(+), 21 deletions(-) (limited to 'drivers/media/video/ivtv') diff --git a/drivers/media/video/cx18/cx18-ioctl.c b/drivers/media/video/cx18/cx18-ioctl.c index 8b26b3fefb1..4a47f61d948 100644 --- a/drivers/media/video/cx18/cx18-ioctl.c +++ b/drivers/media/video/cx18/cx18-ioctl.c @@ -171,7 +171,6 @@ static int cx18_try_fmt_vid_cap(struct file *file, void *fh, { struct cx18_open_id *id = fh; struct cx18 *cx = id->cx; - int w = fmt->fmt.pix.width; int h = fmt->fmt.pix.height; @@ -203,8 +202,7 @@ static int cx18_s_fmt_vid_cap(struct file *file, void *fh, struct cx18_open_id *id = fh; struct cx18 *cx = id->cx; int ret; - int w = fmt->fmt.pix.width; - int h = fmt->fmt.pix.height; + int w, h; ret = v4l2_prio_check(&cx->prio, &id->prio); if (ret) @@ -213,6 +211,8 @@ static int cx18_s_fmt_vid_cap(struct file *file, void *fh, ret = cx18_try_fmt_vid_cap(file, fh, fmt); if (ret) return ret; + w = fmt->fmt.pix.width; + h = fmt->fmt.pix.height; if (cx->params.width == w && cx->params.height == h) return 0; diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c index 61030309d0a..e67bf1b15cf 100644 --- a/drivers/media/video/ivtv/ivtv-ioctl.c +++ b/drivers/media/video/ivtv/ivtv-ioctl.c @@ -512,27 +512,20 @@ static int ivtv_try_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_ static int ivtv_try_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *fmt) { struct ivtv_open_id *id = fh; - s32 w, h; - int field; - int ret; + s32 w = fmt->fmt.pix.width; + s32 h = fmt->fmt.pix.height; + int field = fmt->fmt.pix.field; + int ret = ivtv_g_fmt_vid_out(file, fh, fmt); - w = fmt->fmt.pix.width; - h = fmt->fmt.pix.height; - field = fmt->fmt.pix.field; - ret = ivtv_g_fmt_vid_out(file, fh, fmt); - fmt->fmt.pix.width = w; - fmt->fmt.pix.height = h; if (!ret && id->type == IVTV_DEC_STREAM_TYPE_YUV) { fmt->fmt.pix.field = field; - if (fmt->fmt.pix.width < 2) - fmt->fmt.pix.width = 2; - if (fmt->fmt.pix.width > 720) - fmt->fmt.pix.width = 720; - if (fmt->fmt.pix.height < 2) - fmt->fmt.pix.height = 2; - if (fmt->fmt.pix.height > 576) - fmt->fmt.pix.height = 576; + w = min(w, 720); + w = max(w, 2); + h = min(h, 576); + h = max(h, 2); } + fmt->fmt.pix.width = w; + fmt->fmt.pix.height = h; return ret; } @@ -560,9 +553,9 @@ static int ivtv_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f struct ivtv_open_id *id = fh; struct ivtv *itv = id->itv; struct cx2341x_mpeg_params *p = &itv->params; + int ret = ivtv_try_fmt_vid_cap(file, fh, fmt); int w = fmt->fmt.pix.width; int h = fmt->fmt.pix.height; - int ret = ivtv_try_fmt_vid_cap(file, fh, fmt); if (ret) return ret; -- cgit v1.2.3-70-g09d2 From 854ad9abcc7c1aa143d1a18409d4f366d4326a80 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 6 Sep 2008 09:56:17 -0300 Subject: V4L/DVB (8921): ivtv: fix incorrect capability and assorted sliced vbi and video out fmt fixes - V4L2_CAP_VBI_OUTPUT is not supported by ivtv, remove it. - ivtv_try_fmt_vid_out also needed to constrain the width/height of MPEG decoder window sizes. - allow empty sliced services. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/ivtv/ivtv-cards.h | 2 +- drivers/media/video/ivtv/ivtv-ioctl.c | 22 +++++++++------------- 2 files changed, 10 insertions(+), 14 deletions(-) (limited to 'drivers/media/video/ivtv') diff --git a/drivers/media/video/ivtv/ivtv-cards.h b/drivers/media/video/ivtv/ivtv-cards.h index 381af1bceef..0b8fe85fb69 100644 --- a/drivers/media/video/ivtv/ivtv-cards.h +++ b/drivers/media/video/ivtv/ivtv-cards.h @@ -154,7 +154,7 @@ #define IVTV_CAP_ENCODER (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_TUNER | \ V4L2_CAP_AUDIO | V4L2_CAP_READWRITE | V4L2_CAP_VBI_CAPTURE | \ V4L2_CAP_SLICED_VBI_CAPTURE) -#define IVTV_CAP_DECODER (V4L2_CAP_VBI_OUTPUT | V4L2_CAP_VIDEO_OUTPUT | \ +#define IVTV_CAP_DECODER (V4L2_CAP_VIDEO_OUTPUT | \ V4L2_CAP_SLICED_VBI_OUTPUT | V4L2_CAP_VIDEO_OUTPUT_OVERLAY) struct ivtv_card_video_input { diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c index e67bf1b15cf..f00854ad64e 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) } } -static int check_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal) +static void check_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal) { int f, l; - u16 set = 0; for (f = 0; f < 2; f++) { for (l = 0; l < 24; l++) { fmt->service_lines[f][l] = select_service_from_set(f, l, fmt->service_lines[f][l], is_pal); - set |= fmt->service_lines[f][l]; } } - return set != 0; } u16 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 int h = fmt->fmt.pix.height; w = min(w, 720); - w = max(w, 1); + w = max(w, 2); h = min(h, itv->is_50hz ? 576 : 480); h = max(h, 2); ivtv_g_fmt_vid_cap(file, fh, fmt); @@ -512,18 +509,18 @@ static int ivtv_try_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_ static int ivtv_try_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *fmt) { struct ivtv_open_id *id = fh; + struct ivtv *itv = id->itv; s32 w = fmt->fmt.pix.width; s32 h = fmt->fmt.pix.height; int field = fmt->fmt.pix.field; int ret = ivtv_g_fmt_vid_out(file, fh, fmt); - if (!ret && id->type == IVTV_DEC_STREAM_TYPE_YUV) { + w = min(w, 720); + w = max(w, 2); + h = min(h, itv->is_out_50hz ? 576 : 480); + h = max(h, 2); + if (id->type == IVTV_DEC_STREAM_TYPE_YUV) fmt->fmt.pix.field = field; - w = min(w, 720); - w = max(w, 2); - h = min(h, 576); - h = max(h, 2); - } fmt->fmt.pix.width = w; fmt->fmt.pix.height = h; return ret; @@ -593,8 +590,7 @@ static int ivtv_s_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_fo if (ret || id->type == IVTV_DEC_STREAM_TYPE_VBI) return ret; - if (check_service_set(vbifmt, itv->is_50hz) == 0) - return -EINVAL; + check_service_set(vbifmt, itv->is_50hz); if (atomic_read(&itv->capturing) > 0) return -EBUSY; itv->video_dec_func(itv, VIDIOC_S_FMT, fmt); -- cgit v1.2.3-70-g09d2 From d7cba043d7ec840d67bd5143779d1febe7d83407 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Fri, 12 Sep 2008 13:31:45 -0300 Subject: V4L/DVB (9049): convert tuner drivers to use dvb_frontend->callback Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/tuners/tda827x.c | 12 +++++---- drivers/media/common/tuners/tda827x.h | 1 - drivers/media/common/tuners/tda8290.c | 4 +-- drivers/media/common/tuners/tda8290.h | 1 - drivers/media/common/tuners/tuner-xc2028.c | 41 +++++++++++++++-------------- drivers/media/common/tuners/tuner-xc2028.h | 2 -- drivers/media/common/tuners/xc5000.c | 8 +++--- drivers/media/common/tuners/xc5000.h | 2 -- drivers/media/dvb/dvb-usb/cxusb.c | 7 +++-- drivers/media/dvb/dvb-usb/dib0700_devices.c | 8 +++--- drivers/media/video/au0828/au0828-cards.c | 2 +- drivers/media/video/au0828/au0828-dvb.c | 3 ++- drivers/media/video/au0828/au0828.h | 3 ++- drivers/media/video/cx18/cx18-gpio.c | 2 +- drivers/media/video/cx18/cx18-gpio.h | 2 +- drivers/media/video/cx23885/cx23885-cards.c | 2 +- drivers/media/video/cx23885/cx23885-dvb.c | 12 ++------- drivers/media/video/cx23885/cx23885.h | 2 +- drivers/media/video/cx88/cx88-cards.c | 24 ++++++++++++++--- drivers/media/video/cx88/cx88-dvb.c | 40 ++-------------------------- drivers/media/video/cx88/cx88.h | 2 +- drivers/media/video/em28xx/em28xx-cards.c | 2 +- drivers/media/video/em28xx/em28xx-dvb.c | 3 ++- drivers/media/video/em28xx/em28xx.h | 2 +- drivers/media/video/ivtv/ivtv-gpio.c | 2 +- drivers/media/video/ivtv/ivtv-gpio.h | 2 +- drivers/media/video/saa7134/saa7134-cards.c | 2 +- drivers/media/video/saa7134/saa7134-dvb.c | 7 ++--- drivers/media/video/saa7134/saa7134.h | 2 +- drivers/media/video/tuner-core.c | 10 +++---- include/media/tuner.h | 2 +- 31 files changed, 90 insertions(+), 124 deletions(-) (limited to 'drivers/media/video/ivtv') diff --git a/drivers/media/common/tuners/tda827x.c b/drivers/media/common/tuners/tda827x.c index 8555d9cf905..4a74f65e759 100644 --- a/drivers/media/common/tuners/tda827x.c +++ b/drivers/media/common/tuners/tda827x.c @@ -447,17 +447,19 @@ static void tda827xa_lna_gain(struct dvb_frontend *fe, int high, else arg = 0; } - if (priv->cfg->tuner_callback) - priv->cfg->tuner_callback(priv->i2c_adap->algo_data, - gp_func, arg); + if (fe->callback) + fe->callback(priv->i2c_adap->algo_data, + DVB_FRONTEND_COMPONENT_TUNER, + gp_func, arg); buf[1] = high ? 0 : 1; if (priv->cfg->config == 2) buf[1] = high ? 1 : 0; i2c_transfer(priv->i2c_adap, &msg, 1); break; case 3: /* switch with GPIO of saa713x */ - if (priv->cfg->tuner_callback) - priv->cfg->tuner_callback(priv->i2c_adap->algo_data, 0, high); + if (fe->callback) + fe->callback(priv->i2c_adap->algo_data, + DVB_FRONTEND_COMPONENT_TUNER, 0, high); break; } } diff --git a/drivers/media/common/tuners/tda827x.h b/drivers/media/common/tuners/tda827x.h index 7850a9a1dc8..7d72ce0a0c2 100644 --- a/drivers/media/common/tuners/tda827x.h +++ b/drivers/media/common/tuners/tda827x.h @@ -36,7 +36,6 @@ struct tda827x_config /* interface to tda829x driver */ unsigned int config; int switch_addr; - int (*tuner_callback) (void *dev, int command, int arg); void (*agcf)(struct dvb_frontend *fe); }; diff --git a/drivers/media/common/tuners/tda8290.c b/drivers/media/common/tuners/tda8290.c index 91204d3f282..c112bdd4e0f 100644 --- a/drivers/media/common/tuners/tda8290.c +++ b/drivers/media/common/tuners/tda8290.c @@ -672,10 +672,8 @@ struct dvb_frontend *tda829x_attach(struct dvb_frontend *fe, priv->i2c_props.addr = i2c_addr; priv->i2c_props.adap = i2c_adap; priv->i2c_props.name = "tda829x"; - if (cfg) { + if (cfg) priv->cfg.config = cfg->lna_cfg; - priv->cfg.tuner_callback = cfg->tuner_callback; - } if (tda8290_probe(&priv->i2c_props) == 0) { priv->ver = TDA8290; diff --git a/drivers/media/common/tuners/tda8290.h b/drivers/media/common/tuners/tda8290.h index aa074f3f0c0..7e288b26fcc 100644 --- a/drivers/media/common/tuners/tda8290.h +++ b/drivers/media/common/tuners/tda8290.h @@ -22,7 +22,6 @@ struct tda829x_config { unsigned int lna_cfg; - int (*tuner_callback) (void *dev, int command, int arg); unsigned int probe_tuner:1; #define TDA829X_PROBE_TUNER 0 diff --git a/drivers/media/common/tuners/tuner-xc2028.c b/drivers/media/common/tuners/tuner-xc2028.c index 4dd1d2421cc..fc82d154c8c 100644 --- a/drivers/media/common/tuners/tuner-xc2028.c +++ b/drivers/media/common/tuners/tuner-xc2028.c @@ -71,9 +71,6 @@ struct firmware_properties { struct xc2028_data { struct list_head hybrid_tuner_instance_list; struct tuner_i2c_props i2c_props; - int (*tuner_callback) (void *dev, - int command, int arg); - void *video_dev; __u32 frequency; struct firmware_description *firm; @@ -492,6 +489,23 @@ ret: return i; } +static inline int do_tuner_callback(struct dvb_frontend *fe, int cmd, int arg) +{ + struct xc2028_data *priv = fe->tuner_priv; + + /* analog side (tuner-core) uses i2c_adap->algo_data. + * digital side is not guaranteed to have algo_data defined. + * + * digital side will always have fe->dvb defined. + * analog side (tuner-core) doesn't (yet) define fe->dvb. + */ + + return (!fe->callback) ? -EINVAL : + fe->callback(((fe->dvb) && (fe->dvb->priv)) ? + fe->dvb->priv : priv->i2c_props.adap->algo_data, + DVB_FRONTEND_COMPONENT_TUNER, cmd, arg); +} + static int load_firmware(struct dvb_frontend *fe, unsigned int type, v4l2_std_id *id) { @@ -530,8 +544,7 @@ static int load_firmware(struct dvb_frontend *fe, unsigned int type, if (!size) { /* Special callback command received */ - rc = priv->tuner_callback(priv->video_dev, - XC2028_TUNER_RESET, 0); + rc = do_tuner_callback(fe, XC2028_TUNER_RESET, 0); if (rc < 0) { tuner_err("Error at RESET code %d\n", (*p) & 0x7f); @@ -542,8 +555,7 @@ static int load_firmware(struct dvb_frontend *fe, unsigned int type, if (size >= 0xff00) { switch (size) { case 0xff00: - rc = priv->tuner_callback(priv->video_dev, - XC2028_RESET_CLK, 0); + rc = do_tuner_callback(fe, XC2028_RESET_CLK, 0); if (rc < 0) { tuner_err("Error at RESET code %d\n", (*p) & 0x7f); @@ -715,8 +727,7 @@ retry: memset(&priv->cur_fw, 0, sizeof(priv->cur_fw)); /* Reset is needed before loading firmware */ - rc = priv->tuner_callback(priv->video_dev, - XC2028_TUNER_RESET, 0); + rc = do_tuner_callback(fe, XC2028_TUNER_RESET, 0); if (rc < 0) goto fail; @@ -933,7 +944,7 @@ static int generic_set_freq(struct dvb_frontend *fe, u32 freq /* in HZ */, The reset CLK is needed only with tm6000. Driver should work fine even if this fails. */ - priv->tuner_callback(priv->video_dev, XC2028_RESET_CLK, 1); + do_tuner_callback(fe, XC2028_RESET_CLK, 1); msleep(10); @@ -1177,20 +1188,10 @@ struct dvb_frontend *xc2028_attach(struct dvb_frontend *fe, break; case 1: /* new tuner instance */ - priv->tuner_callback = cfg->callback; priv->ctrl.max_len = 13; mutex_init(&priv->lock); - /* analog side (tuner-core) uses i2c_adap->algo_data. - * digital side is not guaranteed to have algo_data defined. - * - * digital side will always have fe->dvb defined. - * analog side (tuner-core) doesn't (yet) define fe->dvb. - */ - priv->video_dev = ((fe->dvb) && (fe->dvb->priv)) ? - fe->dvb->priv : cfg->i2c_adap->algo_data; - fe->tuner_priv = priv; break; case 2: diff --git a/drivers/media/common/tuners/tuner-xc2028.h b/drivers/media/common/tuners/tuner-xc2028.h index 2c5b6282b56..1af69f49f8e 100644 --- a/drivers/media/common/tuners/tuner-xc2028.h +++ b/drivers/media/common/tuners/tuner-xc2028.h @@ -39,9 +39,7 @@ struct xc2028_ctrl { struct xc2028_config { struct i2c_adapter *i2c_adap; u8 i2c_addr; - void *video_dev; struct xc2028_ctrl *ctrl; - int (*callback) (void *dev, int command, int arg); }; /* xc2028 commands for callback */ diff --git a/drivers/media/common/tuners/xc5000.c b/drivers/media/common/tuners/xc5000.c index ccc4dae4126..f9c2bb917f5 100644 --- a/drivers/media/common/tuners/xc5000.c +++ b/drivers/media/common/tuners/xc5000.c @@ -58,8 +58,6 @@ struct xc5000_priv { u32 bandwidth; u8 video_standard; u8 rf_mode; - - int (*tuner_callback) (void *priv, int command, int arg); }; /* Misc Defines */ @@ -232,10 +230,11 @@ static void xc5000_TunerReset(struct dvb_frontend *fe) dprintk(1, "%s()\n", __func__); - if (priv->tuner_callback) { - ret = priv->tuner_callback(((fe->dvb) && (fe->dvb->priv)) ? + if (fe->callback) { + ret = fe->callback(((fe->dvb) && (fe->dvb->priv)) ? fe->dvb->priv : priv->i2c_props.adap->algo_data, + DVB_FRONTEND_COMPONENT_TUNER, XC5000_TUNER_RESET, 0); if (ret) printk(KERN_ERR "xc5000: reset failed\n"); @@ -975,7 +974,6 @@ struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe, /* new tuner instance */ priv->bandwidth = BANDWIDTH_6_MHZ; priv->if_khz = cfg->if_khz; - priv->tuner_callback = cfg->tuner_callback; fe->tuner_priv = priv; break; diff --git a/drivers/media/common/tuners/xc5000.h b/drivers/media/common/tuners/xc5000.h index fa0321cfd17..cf1a558e0e7 100644 --- a/drivers/media/common/tuners/xc5000.h +++ b/drivers/media/common/tuners/xc5000.h @@ -30,8 +30,6 @@ struct i2c_adapter; struct xc5000_config { u8 i2c_address; u32 if_khz; - - int (*tuner_callback) (void *priv, int command, int arg); }; /* xc5000 callback command */ diff --git a/drivers/media/dvb/dvb-usb/cxusb.c b/drivers/media/dvb/dvb-usb/cxusb.c index 1a746127cbd..406d7fba369 100644 --- a/drivers/media/dvb/dvb-usb/cxusb.c +++ b/drivers/media/dvb/dvb-usb/cxusb.c @@ -742,7 +742,8 @@ static int cxusb_lgh064f_tuner_attach(struct dvb_usb_adapter *adap) return 0; } -static int dvico_bluebird_xc2028_callback(void *ptr, int command, int arg) +static int dvico_bluebird_xc2028_callback(void *ptr, int component, + int command, int arg) { struct dvb_usb_adapter *adap = ptr; struct dvb_usb_device *d = adap->dev; @@ -770,7 +771,6 @@ static int cxusb_dvico_xc3028_tuner_attach(struct dvb_usb_adapter *adap) struct xc2028_config cfg = { .i2c_adap = &adap->dev->i2c_adap, .i2c_addr = 0x61, - .callback = dvico_bluebird_xc2028_callback, }; static struct xc2028_ctrl ctl = { .fname = XC2028_DEFAULT_FIRMWARE, @@ -778,6 +778,9 @@ static int cxusb_dvico_xc3028_tuner_attach(struct dvb_usb_adapter *adap) .demod = XC3028_FE_ZARLINK456, }; + /* FIXME: generalize & move to common area */ + adap->fe->callback = dvico_bluebird_xc2028_callback; + fe = dvb_attach(xc2028_attach, adap->fe, &cfg); if (fe == NULL || fe->ops.tuner_ops.set_config == NULL) return -EIO; diff --git a/drivers/media/dvb/dvb-usb/dib0700_devices.c b/drivers/media/dvb/dvb-usb/dib0700_devices.c index 565563e6810..8b74e13a646 100644 --- a/drivers/media/dvb/dvb-usb/dib0700_devices.c +++ b/drivers/media/dvb/dvb-usb/dib0700_devices.c @@ -368,7 +368,8 @@ static struct dib7000p_config stk7700ph_dib7700_xc3028_config = { .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS, }; -static int stk7700ph_xc3028_callback(void *ptr, int command, int arg) +static int stk7700ph_xc3028_callback(void *ptr, int component, + int command, int arg) { struct dvb_usb_adapter *adap = ptr; @@ -396,7 +397,6 @@ static struct xc2028_ctrl stk7700ph_xc3028_ctrl = { static struct xc2028_config stk7700ph_xc3028_config = { .i2c_addr = 0x61, - .callback = stk7700ph_xc3028_callback, .ctrl = &stk7700ph_xc3028_ctrl, }; @@ -437,7 +437,9 @@ static int stk7700ph_tuner_attach(struct dvb_usb_adapter *adap) DIBX000_I2C_INTERFACE_TUNER, 1); stk7700ph_xc3028_config.i2c_adap = tun_i2c; - stk7700ph_xc3028_config.video_dev = adap; + + /* FIXME: generalize & move to common area */ + adap->fe->callback = stk7700ph_xc3028_callback; return dvb_attach(xc2028_attach, adap->fe, &stk7700ph_xc3028_config) == NULL ? -ENODEV : 0; diff --git a/drivers/media/video/au0828/au0828-cards.c b/drivers/media/video/au0828/au0828-cards.c index ed48908a903..5f07a8a072b 100644 --- a/drivers/media/video/au0828/au0828-cards.c +++ b/drivers/media/video/au0828/au0828-cards.c @@ -46,7 +46,7 @@ struct au0828_board au0828_boards[] = { /* Tuner callback function for au0828 boards. Currently only needed * for HVR1500Q, which has an xc5000 tuner. */ -int au0828_tuner_callback(void *priv, int command, int arg) +int au0828_tuner_callback(void *priv, int component, int command, int arg) { struct au0828_dev *dev = priv; diff --git a/drivers/media/video/au0828/au0828-dvb.c b/drivers/media/video/au0828/au0828-dvb.c index 96246959dce..a52abce16e1 100644 --- a/drivers/media/video/au0828/au0828-dvb.c +++ b/drivers/media/video/au0828/au0828-dvb.c @@ -53,7 +53,6 @@ static struct au8522_config hauppauge_woodbury_config = { static struct xc5000_config hauppauge_hvr950q_tunerconfig = { .i2c_address = 0x61, .if_khz = 6000, - .tuner_callback = au0828_tuner_callback }; static struct mxl5007t_config mxl5007t_hvr950q_config = { @@ -389,6 +388,8 @@ int au0828_dvb_register(struct au0828_dev *dev) __func__); return -1; } + /* define general-purpose callback pointer */ + dvb->frontend->callback = au0828_tuner_callback; /* register everything */ ret = dvb_register(dev); diff --git a/drivers/media/video/au0828/au0828.h b/drivers/media/video/au0828/au0828.h index 4f10ff30013..9d6a1161dc9 100644 --- a/drivers/media/video/au0828/au0828.h +++ b/drivers/media/video/au0828/au0828.h @@ -103,7 +103,8 @@ extern int au0828_debug; extern struct au0828_board au0828_boards[]; extern struct usb_device_id au0828_usb_id_table[]; extern void au0828_gpio_setup(struct au0828_dev *dev); -extern int au0828_tuner_callback(void *priv, int command, int arg); +extern int au0828_tuner_callback(void *priv, int component, + int command, int arg); extern void au0828_card_setup(struct au0828_dev *dev); /* ----------------------------------------------------------- */ diff --git a/drivers/media/video/cx18/cx18-gpio.c b/drivers/media/video/cx18/cx18-gpio.c index 3bdffbf7a96..0e560421989 100644 --- a/drivers/media/video/cx18/cx18-gpio.c +++ b/drivers/media/video/cx18/cx18-gpio.c @@ -152,7 +152,7 @@ void cx18_gpio_init(struct cx18 *cx) } /* Xceive tuner reset function */ -int cx18_reset_tuner_gpio(void *dev, int cmd, int value) +int cx18_reset_tuner_gpio(void *dev, int component, int cmd, int value) { struct i2c_algo_bit_data *algo = dev; struct cx18_i2c_algo_callback_data *cb_data = algo->data; diff --git a/drivers/media/video/cx18/cx18-gpio.h b/drivers/media/video/cx18/cx18-gpio.h index 22cd7ddf855..beb7424b994 100644 --- a/drivers/media/video/cx18/cx18-gpio.h +++ b/drivers/media/video/cx18/cx18-gpio.h @@ -23,5 +23,5 @@ void cx18_gpio_init(struct cx18 *cx); void cx18_reset_i2c_slaves_gpio(struct cx18 *cx); void cx18_reset_ir_gpio(void *data); -int cx18_reset_tuner_gpio(void *dev, int cmd, int value); +int cx18_reset_tuner_gpio(void *dev, int component, int cmd, int value); int cx18_gpio(struct cx18 *cx, unsigned int command, void *arg); diff --git a/drivers/media/video/cx23885/cx23885-cards.c b/drivers/media/video/cx23885/cx23885-cards.c index ccea8de7c7d..2cda15f829f 100644 --- a/drivers/media/video/cx23885/cx23885-cards.c +++ b/drivers/media/video/cx23885/cx23885-cards.c @@ -337,7 +337,7 @@ static void hauppauge_eeprom(struct cx23885_dev *dev, u8 *eeprom_data) dev->name, tv.model); } -int cx23885_tuner_callback(void *priv, int command, int arg) +int cx23885_tuner_callback(void *priv, int component, int command, int arg) { struct cx23885_tsport *port = priv; struct cx23885_dev *dev = port->dev; diff --git a/drivers/media/video/cx23885/cx23885-dvb.c b/drivers/media/video/cx23885/cx23885-dvb.c index 3b54f139180..6c5475d7d32 100644 --- a/drivers/media/video/cx23885/cx23885-dvb.c +++ b/drivers/media/video/cx23885/cx23885-dvb.c @@ -189,13 +189,11 @@ static struct s5h1411_config dvico_s5h1411_config = { static struct xc5000_config hauppauge_hvr1500q_tunerconfig = { .i2c_address = 0x61, .if_khz = 5380, - .tuner_callback = cx23885_tuner_callback, }; static struct xc5000_config dvico_xc5000_tunerconfig = { .i2c_address = 0x64, .if_khz = 5380, - .tuner_callback = cx23885_tuner_callback, }; static struct tda829x_config tda829x_no_probe = { @@ -403,8 +401,6 @@ static int dvb_register(struct cx23885_tsport *port) struct xc2028_config cfg = { .i2c_adap = &i2c_bus->i2c_adap, .i2c_addr = 0x61, - .video_dev = port, - .callback = cx23885_tuner_callback, }; static struct xc2028_ctrl ctl = { .fname = XC2028_DEFAULT_FIRMWARE, @@ -443,8 +439,6 @@ static int dvb_register(struct cx23885_tsport *port) struct xc2028_config cfg = { .i2c_adap = &dev->i2c_bus[1].i2c_adap, .i2c_addr = 0x64, - .video_dev = port, - .callback = cx23885_tuner_callback, }; static struct xc2028_ctrl ctl = { .fname = XC3028L_DEFAULT_FIRMWARE, @@ -485,8 +479,6 @@ static int dvb_register(struct cx23885_tsport *port) struct xc2028_config cfg = { .i2c_adap = &i2c_bus->i2c_adap, .i2c_addr = 0x61, - .video_dev = port, - .callback = cx23885_tuner_callback, }; static struct xc2028_ctrl ctl = { .fname = XC2028_DEFAULT_FIRMWARE, @@ -512,8 +504,6 @@ static int dvb_register(struct cx23885_tsport *port) struct xc2028_config cfg = { .i2c_adap = &dev->i2c_bus[1].i2c_adap, .i2c_addr = 0x61, - .video_dev = port, - .callback = cx23885_tuner_callback, }; static struct xc2028_ctrl ctl = { .fname = XC2028_DEFAULT_FIRMWARE, @@ -536,6 +526,8 @@ static int dvb_register(struct cx23885_tsport *port) printk("%s: frontend initialization failed\n", dev->name); return -1; } + /* define general-purpose callback pointer */ + port->dvb.frontend->callback = cx23885_tuner_callback; /* Put the analog decoder in standby to keep it quiet */ cx23885_call_i2c_clients(i2c_bus, TUNER_SET_STANDBY, NULL); diff --git a/drivers/media/video/cx23885/cx23885.h b/drivers/media/video/cx23885/cx23885.h index 4e0fcb3f7fc..ba4e0aaed46 100644 --- a/drivers/media/video/cx23885/cx23885.h +++ b/drivers/media/video/cx23885/cx23885.h @@ -411,7 +411,7 @@ extern const unsigned int cx23885_bcount; extern struct cx23885_subid cx23885_subids[]; extern const unsigned int cx23885_idcount; -extern int cx23885_tuner_callback(void *priv, int command, int arg); +extern int cx23885_tuner_callback(void *priv, int component, int command, int arg); extern void cx23885_card_list(struct cx23885_dev *dev); extern int cx23885_ir_init(struct cx23885_dev *dev); extern void cx23885_gpio_setup(struct cx23885_dev *dev); diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c index 16bb9c35fc7..b5a25094c9e 100644 --- a/drivers/media/video/cx88/cx88-cards.c +++ b/drivers/media/video/cx88/cx88-cards.c @@ -2308,9 +2308,21 @@ static int cx88_dvico_xc2028_callback(struct cx88_core *core, { switch (command) { case XC2028_TUNER_RESET: - cx_write(MO_GP0_IO, 0x101000); - mdelay(5); - cx_set(MO_GP0_IO, 0x101010); + switch (core->boardnr) { + case CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO: + /* GPIO-4 xc3028 tuner */ + + cx_set(MO_GP0_IO, 0x00001000); + cx_clear(MO_GP0_IO, 0x00000010); + msleep(100); + cx_set(MO_GP0_IO, 0x00000010); + msleep(100); + break; + default: + cx_write(MO_GP0_IO, 0x101000); + mdelay(5); + cx_set(MO_GP0_IO, 0x101010); + } break; default: return -EINVAL; @@ -2419,6 +2431,7 @@ static int cx88_xc2028_tuner_callback(struct cx88_core *core, case CX88_BOARD_PROLINK_PV_8000GT: return cx88_pv_8000gt_callback(core, command, arg); case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PRO: + case CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO: return cx88_dvico_xc2028_callback(core, command, arg); } @@ -2486,7 +2499,7 @@ static int cx88_xc5000_tuner_callback(struct cx88_core *core, return 0; /* Should never be here */ } -int cx88_tuner_callback(void *priv, int command, int arg) +int cx88_tuner_callback(void *priv, int component, int command, int arg) { struct i2c_algo_bit_data *i2c_algo = priv; struct cx88_core *core; @@ -2503,6 +2516,9 @@ int cx88_tuner_callback(void *priv, int command, int arg) return -EINVAL; } + if (component != DVB_FRONTEND_COMPONENT_TUNER) + return -EINVAL; + switch (core->board.tuner_type) { case TUNER_XC2028: info_printk(core, "Calling XC2028/3028 callback\n"); diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c index cd368b512d1..6751f36e061 100644 --- a/drivers/media/video/cx88/cx88-dvb.c +++ b/drivers/media/video/cx88/cx88-dvb.c @@ -405,40 +405,6 @@ static int tevii_dvbs_set_voltage(struct dvb_frontend *fe, return 0; } -static int cx88_pci_nano_callback(void *ptr, int command, int arg) -{ - struct cx88_core *core = ptr; - - switch (command) { - case XC2028_TUNER_RESET: - /* Send the tuner in then out of reset */ - dprintk(1, "%s: XC2028_TUNER_RESET %d\n", __func__, arg); - - switch (core->boardnr) { - case CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO: - /* GPIO-4 xc3028 tuner */ - - cx_set(MO_GP0_IO, 0x00001000); - cx_clear(MO_GP0_IO, 0x00000010); - msleep(100); - cx_set(MO_GP0_IO, 0x00000010); - msleep(100); - break; - } - - break; - case XC2028_RESET_CLK: - dprintk(1, "%s: XC2028_RESET_CLK %d\n", __func__, arg); - break; - default: - dprintk(1, "%s: unknown command %d, arg %d\n", __func__, - command, arg); - return -EINVAL; - } - - return 0; -} - static struct cx24123_config geniatech_dvbs_config = { .demod_address = 0x55, .set_ts_params = cx24123_set_ts_param, @@ -486,7 +452,6 @@ static struct s5h1409_config kworld_atsc_120_config = { static struct xc5000_config pinnacle_pctv_hd_800i_tuner_config = { .i2c_address = 0x64, .if_khz = 5380, - .tuner_callback = cx88_tuner_callback, }; static struct zl10353_config cx88_geniatech_x8000_mt = { @@ -507,7 +472,6 @@ static struct s5h1411_config dvico_fusionhdtv7_config = { static struct xc5000_config dvico_fusionhdtv7_tuner_config = { .i2c_address = 0xc2 >> 1, .if_khz = 5380, - .tuner_callback = cx88_tuner_callback, }; static int attach_xc3028(u8 addr, struct cx8802_dev *dev) @@ -518,7 +482,6 @@ static int attach_xc3028(u8 addr, struct cx8802_dev *dev) .i2c_adap = &dev->core->i2c_adap, .i2c_addr = addr, .ctrl = &ctl, - .callback = cx88_tuner_callback, }; if (!dev->dvb.frontend) { @@ -912,7 +875,6 @@ static int dvb_register(struct cx8802_dev *dev) struct xc2028_config cfg = { .i2c_adap = &core->i2c_adap, .i2c_addr = 0x61, - .callback = cx88_pci_nano_callback, }; static struct xc2028_ctrl ctl = { .fname = XC2028_DEFAULT_FIRMWARE, @@ -1035,6 +997,8 @@ static int dvb_register(struct cx8802_dev *dev) core->name); return -EINVAL; } + /* define general-purpose callback pointer */ + dev->dvb.frontend->callback = cx88_tuner_callback; /* Ensure all frontends negotiate bus access */ dev->dvb.frontend->ops.ts_bus_ctrl = cx88_dvb_bus_ctrl; diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h index e17bd513b58..30b750ee856 100644 --- a/drivers/media/video/cx88/cx88.h +++ b/drivers/media/video/cx88/cx88.h @@ -607,7 +607,7 @@ extern void cx88_call_i2c_clients(struct cx88_core *core, /* ----------------------------------------------------------- */ /* cx88-cards.c */ -extern int cx88_tuner_callback(void *dev, int command, int arg); +extern int cx88_tuner_callback(void *dev, int component, int command, int arg); extern int cx88_get_resources(const struct cx88_core *core, struct pci_dev *pci); extern struct cx88_core *cx88_core_create(struct pci_dev *pci, int nr); diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c index 01804fac6aa..d65d0572403 100644 --- a/drivers/media/video/em28xx/em28xx-cards.c +++ b/drivers/media/video/em28xx/em28xx-cards.c @@ -1271,7 +1271,7 @@ static struct em28xx_hash_table em28xx_i2c_hash[] = { {0x1ba50080, EM2860_BOARD_POINTNIX_INTRAORAL_CAMERA, TUNER_ABSENT}, }; -int em28xx_tuner_callback(void *ptr, int command, int arg) +int em28xx_tuner_callback(void *ptr, int component, int command, int arg) { int rc = 0; struct em28xx *dev = ptr; diff --git a/drivers/media/video/em28xx/em28xx-dvb.c b/drivers/media/video/em28xx/em28xx-dvb.c index ea4f2a97bd2..855ad3940b2 100644 --- a/drivers/media/video/em28xx/em28xx-dvb.c +++ b/drivers/media/video/em28xx/em28xx-dvb.c @@ -249,7 +249,6 @@ static int attach_xc3028(u8 addr, struct em28xx *dev) memset(&cfg, 0, sizeof(cfg)); cfg.i2c_adap = &dev->i2c_adap; cfg.i2c_addr = addr; - cfg.callback = em28xx_tuner_callback; if (!dev->dvb->frontend) { printk(KERN_ERR "%s/2: dvb frontend not attached. " @@ -474,6 +473,8 @@ static int dvb_init(struct em28xx *dev) result = -EINVAL; goto out_free; } + /* define general-purpose callback pointer */ + dvb->frontend->callback = em28xx_tuner_callback; /* register everything */ result = register_dvb(dvb, THIS_MODULE, dev, &dev->udev->dev); diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h index d992280613b..82781178e0a 100644 --- a/drivers/media/video/em28xx/em28xx.h +++ b/drivers/media/video/em28xx/em28xx.h @@ -528,7 +528,7 @@ extern struct em28xx_board em28xx_boards[]; extern struct usb_device_id em28xx_id_table[]; extern const unsigned int em28xx_bcount; void em28xx_set_ir(struct em28xx *dev, struct IR_i2c *ir); -int em28xx_tuner_callback(void *ptr, int command, int arg); +int em28xx_tuner_callback(void *ptr, int component, int command, int arg); /* Provided by em28xx-input.c */ /* TODO: Check if the standard get_key handlers on ir-common can be used */ diff --git a/drivers/media/video/ivtv/ivtv-gpio.c b/drivers/media/video/ivtv/ivtv-gpio.c index bc22905ea20..74a44844cca 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) } /* Xceive tuner reset function */ -int ivtv_reset_tuner_gpio(void *dev, int cmd, int value) +int ivtv_reset_tuner_gpio(void *dev, int component, int cmd, int value) { struct i2c_algo_bit_data *algo = dev; struct ivtv *itv = algo->data; diff --git a/drivers/media/video/ivtv/ivtv-gpio.h b/drivers/media/video/ivtv/ivtv-gpio.h index 964a265d91a..48b6291613a 100644 --- a/drivers/media/video/ivtv/ivtv-gpio.h +++ b/drivers/media/video/ivtv/ivtv-gpio.h @@ -24,7 +24,7 @@ /* GPIO stuff */ void ivtv_gpio_init(struct ivtv *itv); void ivtv_reset_ir_gpio(struct ivtv *itv); -int ivtv_reset_tuner_gpio(void *dev, int cmd, int value); +int ivtv_reset_tuner_gpio(void *dev, int component, int cmd, int value); int ivtv_gpio(struct ivtv *itv, unsigned int command, void *arg); #endif diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c index 3c2f09fb044..622d3ba5a1e 100644 --- a/drivers/media/video/saa7134/saa7134-cards.c +++ b/drivers/media/video/saa7134/saa7134-cards.c @@ -5576,7 +5576,7 @@ static int saa7134_tda8290_callback(struct saa7134_dev *dev, return 0; } -int saa7134_tuner_callback(void *priv, int command, int arg) +int saa7134_tuner_callback(void *priv, int component, int command, int arg) { struct saa7134_dev *dev = priv; if (dev != NULL) { diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/video/saa7134/saa7134-dvb.c index 7fa6ce76642..0dd6b988820 100644 --- a/drivers/media/video/saa7134/saa7134-dvb.c +++ b/drivers/media/video/saa7134/saa7134-dvb.c @@ -553,7 +553,6 @@ static int configure_tda827x_fe(struct saa7134_dev *dev, /* ------------------------------------------------------------------ */ static struct tda827x_config tda827x_cfg_0 = { - .tuner_callback = saa7134_tuner_callback, .init = philips_tda827x_tuner_init, .sleep = philips_tda827x_tuner_sleep, .config = 0, @@ -561,7 +560,6 @@ static struct tda827x_config tda827x_cfg_0 = { }; static struct tda827x_config tda827x_cfg_1 = { - .tuner_callback = saa7134_tuner_callback, .init = philips_tda827x_tuner_init, .sleep = philips_tda827x_tuner_sleep, .config = 1, @@ -569,7 +567,6 @@ static struct tda827x_config tda827x_cfg_1 = { }; static struct tda827x_config tda827x_cfg_2 = { - .tuner_callback = saa7134_tuner_callback, .init = philips_tda827x_tuner_init, .sleep = philips_tda827x_tuner_sleep, .config = 2, @@ -577,7 +574,6 @@ static struct tda827x_config tda827x_cfg_2 = { }; static struct tda827x_config tda827x_cfg_2_sw42 = { - .tuner_callback = saa7134_tuner_callback, .init = philips_tda827x_tuner_init, .sleep = philips_tda827x_tuner_sleep, .config = 2, @@ -836,7 +832,6 @@ static int ads_duo_tuner_sleep(struct dvb_frontend *fe) } static struct tda827x_config ads_duo_cfg = { - .tuner_callback = saa7134_tuner_callback, .init = ads_duo_tuner_init, .sleep = ads_duo_tuner_sleep, .config = 0 @@ -1366,6 +1361,8 @@ static int dvb_init(struct saa7134_dev *dev) printk(KERN_ERR "%s/dvb: frontend initialization failed\n", dev->name); return -1; } + /* define general-purpose callback pointer */ + dev->dvb.frontend->callback = saa7134_tuner_callback; /* register everything else */ ret = videobuf_dvb_register(&dev->dvb, THIS_MODULE, dev, &dev->pci->dev, diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h index cbfdac27b69..4005335c4f5 100644 --- a/drivers/media/video/saa7134/saa7134.h +++ b/drivers/media/video/saa7134/saa7134.h @@ -653,7 +653,7 @@ extern struct pci_device_id __devinitdata saa7134_pci_tbl[]; extern int saa7134_board_init1(struct saa7134_dev *dev); extern int saa7134_board_init2(struct saa7134_dev *dev); -int saa7134_tuner_callback(void *priv, int command, int arg); +int saa7134_tuner_callback(void *priv, int component, int command, int arg); /* ----------------------------------------------------------- */ diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c index 39c7b9b835a..4a7735c6c1a 100644 --- a/drivers/media/video/tuner-core.c +++ b/drivers/media/video/tuner-core.c @@ -92,7 +92,6 @@ struct tuner { unsigned int type; /* chip type id */ unsigned int config; - int (*tuner_callback) (void *dev, int command, int arg); const char *name; }; @@ -346,7 +345,7 @@ static struct xc5000_config xc5000_cfg; static void set_type(struct i2c_client *c, unsigned int type, unsigned int new_mode_mask, unsigned int new_config, - int (*tuner_callback) (void *dev, int command,int arg)) + int (*tuner_callback) (void *dev, int component, int cmd, int arg)) { struct tuner *t = i2c_get_clientdata(c); struct dvb_tuner_ops *fe_tuner_ops = &t->fe.ops.tuner_ops; @@ -362,7 +361,7 @@ static void set_type(struct i2c_client *c, unsigned int type, t->config = new_config; if (tuner_callback != NULL) { tuner_dbg("defining GPIO callback\n"); - t->tuner_callback = tuner_callback; + t->fe.callback = tuner_callback; } if (t->mode == T_UNINITIALIZED) { @@ -385,7 +384,6 @@ static void set_type(struct i2c_client *c, unsigned int type, { struct tda829x_config cfg = { .lna_cfg = t->config, - .tuner_callback = t->tuner_callback, }; if (!dvb_attach(tda829x_attach, &t->fe, t->i2c->adapter, t->i2c->addr, &cfg)) @@ -433,7 +431,6 @@ static void set_type(struct i2c_client *c, unsigned int type, struct xc2028_config cfg = { .i2c_adap = t->i2c->adapter, .i2c_addr = t->i2c->addr, - .callback = t->tuner_callback, }; if (!dvb_attach(xc2028_attach, &t->fe, &cfg)) goto attach_failed; @@ -450,7 +447,6 @@ static void set_type(struct i2c_client *c, unsigned int type, xc5000_cfg.i2c_address = t->i2c->addr; xc5000_cfg.if_khz = 5380; - xc5000_cfg.tuner_callback = t->tuner_callback; if (!dvb_attach(xc5000_attach, &t->fe, t->i2c->adapter, &xc5000_cfg)) goto attach_failed; @@ -1224,7 +1220,7 @@ register_client: } else { t->mode = V4L2_TUNER_DIGITAL_TV; } - set_type(client, t->type, t->mode_mask, t->config, t->tuner_callback); + set_type(client, t->type, t->mode_mask, t->config, t->fe.callback); list_add_tail(&t->list, &tuner_list); return 0; } diff --git a/include/media/tuner.h b/include/media/tuner.h index ba818985cc8..67c1f514d0e 100644 --- a/include/media/tuner.h +++ b/include/media/tuner.h @@ -179,7 +179,7 @@ struct tuner_setup { unsigned int type; /* Tuner type */ unsigned int mode_mask; /* Allowed tuner modes */ unsigned int config; /* configuraion for more complex tuners */ - int (*tuner_callback) (void *dev, int command,int arg); + int (*tuner_callback) (void *dev, int component, int cmd, int arg); }; #endif /* __KERNEL__ */ -- cgit v1.2.3-70-g09d2 From dd89601d47e2eeab7c17b25f2549444751bcffe4 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 4 Oct 2008 08:36:54 -0300 Subject: V4L/DVB (9133): v4l: disconnect kernel number from minor The v4l core creates four different video devices (video, vbi, radio, vtx) and each has its own range of minor numbers. However, modern devices keep increasing the number of devices that they need so a maximum of 64 video devices will not be enough in the future. In addition this scheme makes it very hard to add new device types. This patch disconnects the kernel number allocation (e.g. video0, video1, etc.) from the actual minor number (just pick the first free minor). This allows for much more flexibility in the future. However, it does require the use of udev. For those who cannot use udev a new CONFIG option was created that changes the allocation scheme back to the old behavior. Thanks to Greg KH for suggesting this approach during the 2008 LPC. In addition, several bugs were fixed in the ivtv and cx18 drivers: these drivers try to allocate specific kernel numbers but that scheme contained a bug which caused what should have been e.g. video17 to appear as e.g. video2. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/Kconfig | 9 +++ drivers/media/video/cx18/cx18-driver.c | 4 +- drivers/media/video/cx18/cx18-streams.c | 41 +++++++------ drivers/media/video/em28xx/em28xx-video.c | 8 +-- drivers/media/video/ivtv/ivtv-driver.c | 6 +- drivers/media/video/ivtv/ivtv-streams.c | 40 +++++++------ drivers/media/video/v4l2-dev.c | 96 +++++++++++++++++++++---------- include/media/v4l2-dev.h | 12 +--- 8 files changed, 128 insertions(+), 88 deletions(-) (limited to 'drivers/media/video/ivtv') diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig index e28e292fe20..2dce16f863b 100644 --- a/drivers/media/video/Kconfig +++ b/drivers/media/video/Kconfig @@ -72,6 +72,15 @@ config VIDEO_ADV_DEBUG V4L devices. In doubt, say N. +config VIDEO_FIXED_MINOR_RANGES + bool "Enable old-style fixed minor ranges for video devices" + default n + ---help--- + Say Y here to enable the old-style fixed-range minor assignments. + Only useful if you rely on the old behavior and use mknod instead of udev. + + When in doubt, say N. + config VIDEO_HELPER_CHIPS_AUTO bool "Autoselect pertinent encoders/decoders and other helper chips" default y diff --git a/drivers/media/video/cx18/cx18-driver.c b/drivers/media/video/cx18/cx18-driver.c index 6bf9ac8c4e7..085121c2b47 100644 --- a/drivers/media/video/cx18/cx18-driver.c +++ b/drivers/media/video/cx18/cx18-driver.c @@ -175,7 +175,7 @@ MODULE_PARM_DESC(enc_pcm_buffers, "Encoder PCM buffers (in MB)\n" "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_PCM_BUFFERS)); -MODULE_PARM_DESC(cx18_first_minor, "Set minor assigned to first card"); +MODULE_PARM_DESC(cx18_first_minor, "Set kernel number assigned to first card"); MODULE_AUTHOR("Hans Verkuil"); MODULE_DESCRIPTION("CX23418 driver"); @@ -959,7 +959,7 @@ static int module_start(void) /* Validate parameters */ if (cx18_first_minor < 0 || cx18_first_minor >= CX18_MAX_CARDS) { - printk(KERN_ERR "cx18: Exiting, ivtv_first_minor must be between 0 and %d\n", + printk(KERN_ERR "cx18: Exiting, cx18_first_minor must be between 0 and %d\n", CX18_MAX_CARDS - 1); return -1; } diff --git a/drivers/media/video/cx18/cx18-streams.c b/drivers/media/video/cx18/cx18-streams.c index c752a6a4dbd..0c8e7542cf6 100644 --- a/drivers/media/video/cx18/cx18-streams.c +++ b/drivers/media/video/cx18/cx18-streams.c @@ -57,7 +57,7 @@ static struct file_operations cx18_v4l2_enc_fops = { static struct { const char *name; int vfl_type; - int minor_offset; + int num_offset; int dma; enum v4l2_buf_type buf_type; struct file_operations *fops; @@ -144,8 +144,8 @@ static int cx18_prep_dev(struct cx18 *cx, int type) { struct cx18_stream *s = &cx->streams[type]; u32 cap = cx->v4l2_cap; - int minor_offset = cx18_stream_info[type].minor_offset; - int minor; + int num_offset = cx18_stream_info[type].num_offset; + int num = cx->num + cx18_first_minor + num_offset; /* These four fields are always initialized. If v4l2dev == NULL, then this stream is not in use. In that case no other fields but these @@ -164,9 +164,6 @@ static int cx18_prep_dev(struct cx18 *cx, int type) !(cap & (V4L2_CAP_VBI_CAPTURE | V4L2_CAP_SLICED_VBI_CAPTURE))) return 0; - /* card number + user defined offset + device offset */ - minor = cx->num + cx18_first_minor + minor_offset; - /* User explicitly selected 0 buffers for these streams, so don't create them. */ if (cx18_stream_info[type].dma != PCI_DMA_NONE && @@ -177,7 +174,7 @@ static int cx18_prep_dev(struct cx18 *cx, int type) cx18_stream_init(cx, type); - if (minor_offset == -1) + if (num_offset == -1) return 0; /* allocate and initialize the v4l2 video device structure */ @@ -191,7 +188,7 @@ static int cx18_prep_dev(struct cx18 *cx, int type) snprintf(s->v4l2dev->name, sizeof(s->v4l2dev->name), "cx18-%d", cx->num); - s->v4l2dev->minor = minor; + s->v4l2dev->num = num; s->v4l2dev->parent = &cx->dev->dev; s->v4l2dev->fops = cx18_stream_info[type].fops; s->v4l2dev->release = video_device_release; @@ -227,7 +224,7 @@ static int cx18_reg_dev(struct cx18 *cx, int type) { struct cx18_stream *s = &cx->streams[type]; int vfl_type = cx18_stream_info[type].vfl_type; - int minor; + int num; /* TODO: Shouldn't this be a VFL_TYPE_TRANSPORT or something? * We need a VFL_TYPE_TS defined. @@ -245,38 +242,44 @@ static int cx18_reg_dev(struct cx18 *cx, int type) if (s->v4l2dev == NULL) return 0; - minor = s->v4l2dev->minor; + num = s->v4l2dev->num; + /* card number + user defined offset + device offset */ + if (type != CX18_ENC_STREAM_TYPE_MPG) { + struct cx18_stream *s_mpg = &cx->streams[CX18_ENC_STREAM_TYPE_MPG]; + + if (s_mpg->v4l2dev) + num = s_mpg->v4l2dev->num + cx18_stream_info[type].num_offset; + } /* Register device. First try the desired minor, then any free one. */ - if (video_register_device(s->v4l2dev, vfl_type, minor) && - video_register_device(s->v4l2dev, vfl_type, -1)) { - CX18_ERR("Couldn't register v4l2 device for %s minor %d\n", - s->name, minor); + if (video_register_device(s->v4l2dev, vfl_type, num)) { + CX18_ERR("Couldn't register v4l2 device for %s kernel number %d\n", + s->name, num); video_device_release(s->v4l2dev); s->v4l2dev = NULL; return -ENOMEM; } - minor = s->v4l2dev->minor; + num = s->v4l2dev->num; switch (vfl_type) { case VFL_TYPE_GRABBER: CX18_INFO("Registered device video%d for %s (%d MB)\n", - minor, s->name, cx->options.megabytes[type]); + num, s->name, cx->options.megabytes[type]); break; case VFL_TYPE_RADIO: CX18_INFO("Registered device radio%d for %s\n", - minor - MINOR_VFL_TYPE_RADIO_MIN, s->name); + num, s->name); break; case VFL_TYPE_VBI: if (cx->options.megabytes[type]) CX18_INFO("Registered device vbi%d for %s (%d MB)\n", - minor - MINOR_VFL_TYPE_VBI_MIN, + num, s->name, cx->options.megabytes[type]); else CX18_INFO("Registered device vbi%d for %s\n", - minor - MINOR_VFL_TYPE_VBI_MIN, s->name); + num, s->name); break; } diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c index 50d2c7a9b3c..c53649e5315 100644 --- a/drivers/media/video/em28xx/em28xx-video.c +++ b/drivers/media/video/em28xx/em28xx-video.c @@ -1600,8 +1600,7 @@ static void em28xx_release_resources(struct em28xx *dev) /*FIXME: I2C IR should be disconnected */ em28xx_info("V4L2 devices /dev/video%d and /dev/vbi%d deregistered\n", - dev->vdev->minor-MINOR_VFL_TYPE_GRABBER_MIN, - dev->vbi_dev->minor-MINOR_VFL_TYPE_VBI_MIN); + dev->vdev->num, dev->vbi_dev->num); list_del(&dev->devlist); if (dev->sbutton_input_dev) em28xx_deregister_snapshot_button(dev); @@ -2073,8 +2072,7 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev, video_mux(dev, 0); em28xx_info("V4L2 device registered as /dev/video%d and /dev/vbi%d\n", - dev->vdev->minor-MINOR_VFL_TYPE_GRABBER_MIN, - dev->vbi_dev->minor-MINOR_VFL_TYPE_VBI_MIN); + dev->vdev->num, dev->vbi_dev->num); mutex_lock(&em28xx_extension_devlist_lock); if (!list_empty(&em28xx_extension_devlist)) { @@ -2274,7 +2272,7 @@ static void em28xx_usb_disconnect(struct usb_interface *interface) em28xx_warn ("device /dev/video%d is open! Deregistration and memory " "deallocation are deferred on close.\n", - dev->vdev->minor-MINOR_VFL_TYPE_GRABBER_MIN); + dev->vdev->num); dev->state |= DEV_MISCONFIGURED; em28xx_uninit_isoc(dev); diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c index 6b04930d127..7aa61b61749 100644 --- a/drivers/media/video/ivtv/ivtv-driver.c +++ b/drivers/media/video/ivtv/ivtv-driver.c @@ -61,14 +61,14 @@ #include "tuner-xc2028.h" /* var to keep track of the number of array elements in use */ -int ivtv_cards_active = 0; +int ivtv_cards_active; /* If you have already X v4l cards, then set this to X. This way the device numbers stay matched. Example: you have a WinTV card without radio and a PVR-350 with. Normally this would give a video1 device together with a radio0 device for the PVR. By setting this to 1 you ensure that radio0 is now also radio1. */ -int ivtv_first_minor = 0; +int ivtv_first_minor; /* Master variable for all ivtv info */ struct ivtv *ivtv_cards[IVTV_MAX_CARDS]; @@ -251,7 +251,7 @@ MODULE_PARM_DESC(newi2c, "\t\t\t-1 is autodetect, 0 is off, 1 is on\n" "\t\t\tDefault is autodetect"); -MODULE_PARM_DESC(ivtv_first_minor, "Set minor assigned to first card"); +MODULE_PARM_DESC(ivtv_first_minor, "Set kernel number assigned to first card"); MODULE_AUTHOR("Kevin Thayer, Chris Kennedy, Hans Verkuil"); MODULE_DESCRIPTION("CX23415/CX23416 driver"); diff --git a/drivers/media/video/ivtv/ivtv-streams.c b/drivers/media/video/ivtv/ivtv-streams.c index 730e85d86fc..24273fbea47 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 = { static struct { const char *name; int vfl_type; - int minor_offset; + int num_offset; int dma, pio; enum v4l2_buf_type buf_type; const struct file_operations *fops; @@ -171,8 +171,8 @@ static void ivtv_stream_init(struct ivtv *itv, int type) static int ivtv_prep_dev(struct ivtv *itv, int type) { struct ivtv_stream *s = &itv->streams[type]; - int minor_offset = ivtv_stream_info[type].minor_offset; - int minor; + int num_offset = ivtv_stream_info[type].num_offset; + int num = itv->num + ivtv_first_minor + num_offset; /* These four fields are always initialized. If v4l2dev == NULL, then 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) if (type >= IVTV_DEC_STREAM_TYPE_MPG && !(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) return 0; - /* card number + user defined offset + device offset */ - minor = itv->num + ivtv_first_minor + minor_offset; - /* User explicitly selected 0 buffers for these streams, so don't create them. */ if (ivtv_stream_info[type].dma != PCI_DMA_NONE && @@ -211,7 +208,7 @@ static int ivtv_prep_dev(struct ivtv *itv, int type) snprintf(s->v4l2dev->name, sizeof(s->v4l2dev->name), "ivtv%d %s", itv->num, s->name); - s->v4l2dev->minor = minor; + s->v4l2dev->num = num; s->v4l2dev->parent = &itv->dev->dev; s->v4l2dev->fops = ivtv_stream_info[type].fops; s->v4l2dev->release = video_device_release; @@ -250,39 +247,46 @@ static int ivtv_reg_dev(struct ivtv *itv, int type) { struct ivtv_stream *s = &itv->streams[type]; int vfl_type = ivtv_stream_info[type].vfl_type; - int minor; + int num; if (s->v4l2dev == NULL) return 0; - minor = s->v4l2dev->minor; + num = s->v4l2dev->num; + /* card number + user defined offset + device offset */ + if (type != IVTV_ENC_STREAM_TYPE_MPG) { + struct ivtv_stream *s_mpg = &itv->streams[IVTV_ENC_STREAM_TYPE_MPG]; + + if (s_mpg->v4l2dev) + num = s_mpg->v4l2dev->num + ivtv_stream_info[type].num_offset; + } + /* Register device. First try the desired minor, then any free one. */ - if (video_register_device(s->v4l2dev, vfl_type, minor) && - video_register_device(s->v4l2dev, vfl_type, -1)) { - IVTV_ERR("Couldn't register v4l2 device for %s minor %d\n", - s->name, minor); + if (video_register_device(s->v4l2dev, vfl_type, num)) { + IVTV_ERR("Couldn't register v4l2 device for %s kernel number %d\n", + s->name, num); video_device_release(s->v4l2dev); s->v4l2dev = NULL; return -ENOMEM; } + num = s->v4l2dev->num; switch (vfl_type) { case VFL_TYPE_GRABBER: IVTV_INFO("Registered device video%d for %s (%d kB)\n", - s->v4l2dev->minor, s->name, itv->options.kilobytes[type]); + num, s->name, itv->options.kilobytes[type]); break; case VFL_TYPE_RADIO: IVTV_INFO("Registered device radio%d for %s\n", - s->v4l2dev->minor - MINOR_VFL_TYPE_RADIO_MIN, s->name); + num, s->name); break; case VFL_TYPE_VBI: if (itv->options.kilobytes[type]) IVTV_INFO("Registered device vbi%d for %s (%d kB)\n", - s->v4l2dev->minor - MINOR_VFL_TYPE_VBI_MIN, - s->name, itv->options.kilobytes[type]); + num, s->name, itv->options.kilobytes[type]); else IVTV_INFO("Registered device vbi%d for %s\n", - s->v4l2dev->minor - MINOR_VFL_TYPE_VBI_MIN, s->name); + num, s->name); break; } return 0; diff --git a/drivers/media/video/v4l2-dev.c b/drivers/media/video/v4l2-dev.c index 7addf2fd55d..ccd6566a515 100644 --- a/drivers/media/video/v4l2-dev.c +++ b/drivers/media/video/v4l2-dev.c @@ -65,6 +65,7 @@ static struct device_attribute video_device_attrs[] = { */ static struct video_device *video_device[VIDEO_NUM_DEVICES]; static DEFINE_MUTEX(videodev_lock); +static DECLARE_BITMAP(video_nums[VFL_TYPE_MAX], VIDEO_NUM_DEVICES); struct video_device *video_device_alloc(void) { @@ -99,6 +100,7 @@ static void v4l2_chardev_release(struct kobject *kobj) /* Free up this device for reuse */ video_device[vfd->minor] = NULL; + clear_bit(vfd->num, video_nums[vfd->vfl_type]); mutex_unlock(&videodev_lock); /* Release the character device */ @@ -217,10 +219,10 @@ int video_register_device_index(struct video_device *vfd, int type, int nr, int index) { int i = 0; - int base; - int end; int ret; - char *name_base; + int minor_offset = 0; + int minor_cnt = VIDEO_NUM_DEVICES; + const char *name_base; void *priv = video_get_drvdata(vfd); /* the release callback MUST be present */ @@ -231,23 +233,15 @@ int video_register_device_index(struct video_device *vfd, int type, int nr, switch (type) { case VFL_TYPE_GRABBER: - base = MINOR_VFL_TYPE_GRABBER_MIN; - end = MINOR_VFL_TYPE_GRABBER_MAX+1; name_base = "video"; break; case VFL_TYPE_VTX: - base = MINOR_VFL_TYPE_VTX_MIN; - end = MINOR_VFL_TYPE_VTX_MAX+1; name_base = "vtx"; break; case VFL_TYPE_VBI: - base = MINOR_VFL_TYPE_VBI_MIN; - end = MINOR_VFL_TYPE_VBI_MAX+1; name_base = "vbi"; break; case VFL_TYPE_RADIO: - base = MINOR_VFL_TYPE_RADIO_MIN; - end = MINOR_VFL_TYPE_RADIO_MAX+1; name_base = "radio"; break; default: @@ -256,31 +250,70 @@ int video_register_device_index(struct video_device *vfd, int type, int nr, return -EINVAL; } + vfd->vfl_type = type; + +#ifdef CONFIG_VIDEO_FIXED_MINOR_RANGES + /* Keep the ranges for the first four types for historical + * reasons. + * Newer devices (not yet in place) should use the range + * of 128-191 and just pick the first free minor there + * (new style). */ + switch (type) { + case VFL_TYPE_GRABBER: + minor_offset = 0; + minor_cnt = 64; + break; + case VFL_TYPE_RADIO: + minor_offset = 64; + minor_cnt = 64; + break; + case VFL_TYPE_VTX: + minor_offset = 192; + minor_cnt = 32; + break; + case VFL_TYPE_VBI: + minor_offset = 224; + minor_cnt = 32; + break; + default: + minor_offset = 128; + minor_cnt = 64; + break; + } +#endif + /* Initialize the character device */ cdev_init(&vfd->cdev, vfd->fops); vfd->cdev.owner = vfd->fops->owner; /* pick a minor number */ mutex_lock(&videodev_lock); - if (nr >= 0 && nr < end-base) { - /* use the one the driver asked for */ - i = base + nr; - if (NULL != video_device[i]) { - mutex_unlock(&videodev_lock); - return -ENFILE; - } - } else { - /* use first free */ - for (i = base; i < end; i++) - if (NULL == video_device[i]) - break; - if (i == end) { - mutex_unlock(&videodev_lock); - return -ENFILE; - } + nr = find_next_zero_bit(video_nums[type], minor_cnt, nr == -1 ? 0 : nr); + if (nr == minor_cnt) + nr = find_first_zero_bit(video_nums[type], minor_cnt); + if (nr == minor_cnt) { + printk(KERN_ERR "could not get a free kernel number\n"); + mutex_unlock(&videodev_lock); + return -ENFILE; } - video_device[i] = vfd; - vfd->vfl_type = type; - vfd->minor = i; +#ifdef CONFIG_VIDEO_FIXED_MINOR_RANGES + /* 1-on-1 mapping of kernel number to minor number */ + i = nr; +#else + /* The kernel number and minor numbers are independent */ + for (i = 0; i < VIDEO_NUM_DEVICES; i++) + if (video_device[i] == NULL) + break; + if (i == VIDEO_NUM_DEVICES) { + mutex_unlock(&videodev_lock); + printk(KERN_ERR "could not get a free minor\n"); + return -ENFILE; + } +#endif + vfd->minor = i + minor_offset; + vfd->num = nr; + set_bit(nr, video_nums[type]); + BUG_ON(video_device[vfd->minor]); + video_device[vfd->minor] = vfd; ret = get_index(vfd, index); vfd->index = ret; @@ -306,7 +339,7 @@ int video_register_device_index(struct video_device *vfd, int type, int nr, vfd->dev.devt = MKDEV(VIDEO_MAJOR, vfd->minor); if (vfd->parent) vfd->dev.parent = vfd->parent; - sprintf(vfd->dev.bus_id, "%s%d", name_base, i - base); + sprintf(vfd->dev.bus_id, "%s%d", name_base, nr); ret = device_register(&vfd->dev); if (ret < 0) { printk(KERN_ERR "%s: device_register failed\n", __func__); @@ -324,6 +357,7 @@ del_cdev: fail_minor: mutex_lock(&videodev_lock); video_device[vfd->minor] = NULL; + clear_bit(vfd->num, video_nums[type]); mutex_unlock(&videodev_lock); vfd->minor = -1; return ret; diff --git a/include/media/v4l2-dev.h b/include/media/v4l2-dev.h index d129b56e1a9..a0a6b41c5e0 100644 --- a/include/media/v4l2-dev.h +++ b/include/media/v4l2-dev.h @@ -18,20 +18,11 @@ #define VIDEO_MAJOR 81 -/* Minor device allocation */ -#define MINOR_VFL_TYPE_GRABBER_MIN 0 -#define MINOR_VFL_TYPE_GRABBER_MAX 63 -#define MINOR_VFL_TYPE_RADIO_MIN 64 -#define MINOR_VFL_TYPE_RADIO_MAX 127 -#define MINOR_VFL_TYPE_VTX_MIN 192 -#define MINOR_VFL_TYPE_VTX_MAX 223 -#define MINOR_VFL_TYPE_VBI_MIN 224 -#define MINOR_VFL_TYPE_VBI_MAX 255 - #define VFL_TYPE_GRABBER 0 #define VFL_TYPE_VBI 1 #define VFL_TYPE_RADIO 2 #define VFL_TYPE_VTX 3 +#define VFL_TYPE_MAX 4 struct v4l2_ioctl_callbacks; @@ -56,6 +47,7 @@ struct video_device char name[32]; int vfl_type; int minor; + u16 num; /* attribute to differentiate multiple indices on one physical device */ int index; -- cgit v1.2.3-70-g09d2 From 741e1f3b81c22c81f4ef401856cd22cad0bbd554 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 8 Sep 2008 16:59:02 -0300 Subject: V4L/DVB (9157): cx18/ivtv: add 'PCI:' prefix to bus_info. Suggested by Martin Dauskardt. This is conform what the other drivers do. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx18/cx18-ioctl.c | 2 +- drivers/media/video/ivtv/ivtv-ioctl.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/media/video/ivtv') diff --git a/drivers/media/video/cx18/cx18-ioctl.c b/drivers/media/video/cx18/cx18-ioctl.c index 83aa9cb02e0..f0ca50f5fdd 100644 --- a/drivers/media/video/cx18/cx18-ioctl.c +++ b/drivers/media/video/cx18/cx18-ioctl.c @@ -346,7 +346,7 @@ static int cx18_querycap(struct file *file, void *fh, strlcpy(vcap->driver, CX18_DRIVER_NAME, sizeof(vcap->driver)); strlcpy(vcap->card, cx->card_name, sizeof(vcap->card)); - strlcpy(vcap->bus_info, pci_name(cx->dev), sizeof(vcap->bus_info)); + snprintf(vcap->bus_info, sizeof(vcap->bus_info), "PCI:%s", pci_name(cx->dev)); vcap->version = CX18_DRIVER_VERSION; /* version */ vcap->capabilities = cx->v4l2_cap; /* capabilities */ return 0; diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c index f00854ad64e..f5b289ef410 100644 --- a/drivers/media/video/ivtv/ivtv-ioctl.c +++ b/drivers/media/video/ivtv/ivtv-ioctl.c @@ -750,7 +750,7 @@ static int ivtv_querycap(struct file *file, void *fh, struct v4l2_capability *vc strlcpy(vcap->driver, IVTV_DRIVER_NAME, sizeof(vcap->driver)); strlcpy(vcap->card, itv->card_name, sizeof(vcap->card)); - strlcpy(vcap->bus_info, pci_name(itv->dev), sizeof(vcap->bus_info)); + snprintf(vcap->bus_info, sizeof(vcap->bus_info), "PCI:%s", pci_name(itv->dev)); vcap->version = IVTV_DRIVER_VERSION; /* version */ vcap->capabilities = itv->v4l2_cap; /* capabilities */ return 0; -- cgit v1.2.3-70-g09d2 From a8b864354e060dda1000e62d1fea7c1274581caf Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 4 Oct 2008 08:05:30 -0300 Subject: V4L/DVB (9162): ivtv: fix raw/sliced VBI mixup The service_set field was used in saa7115 and cx25840 to determine whether raw or sliced VBI was desired. This is incorrect since it is perfectly valid to select sliced VBI with a service_set of 0. Instead these drivers should checked on VIDIOC_S_FMT whether the type field matches the raw or sliced VBI type. Updated ivtv accordingly. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx25840/cx25840-vbi.c | 5 +++-- drivers/media/video/ivtv/ivtv-driver.c | 2 +- drivers/media/video/ivtv/ivtv-driver.h | 6 ++++++ drivers/media/video/ivtv/ivtv-fileops.c | 6 +++--- drivers/media/video/ivtv/ivtv-ioctl.c | 8 ++++++-- drivers/media/video/ivtv/ivtv-streams.c | 2 +- drivers/media/video/ivtv/ivtv-vbi.c | 2 +- drivers/media/video/saa7115.c | 8 ++++++-- 8 files changed, 27 insertions(+), 12 deletions(-) (limited to 'drivers/media/video/ivtv') diff --git a/drivers/media/video/cx25840/cx25840-vbi.c b/drivers/media/video/cx25840/cx25840-vbi.c index 69f2bbdbb92..58e6ef1c28a 100644 --- a/drivers/media/video/cx25840/cx25840-vbi.c +++ b/drivers/media/video/cx25840/cx25840-vbi.c @@ -141,10 +141,11 @@ int cx25840_vbi(struct i2c_client *client, unsigned int cmd, void *arg) u8 lcr[24]; fmt = arg; - if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) + if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE && + fmt->type != V4L2_BUF_TYPE_VBI_CAPTURE) return -EINVAL; svbi = &fmt->fmt.sliced; - if (svbi->service_set == 0) { + if (fmt->type == V4L2_BUF_TYPE_VBI_CAPTURE) { /* raw VBI */ memset(svbi, 0, sizeof(*svbi)); diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c index 7aa61b61749..aeaa13f6cb3 100644 --- a/drivers/media/video/ivtv/ivtv-driver.c +++ b/drivers/media/video/ivtv/ivtv-driver.c @@ -720,7 +720,7 @@ static int __devinit ivtv_init_struct1(struct ivtv *itv) itv->speed = 1000; /* VBI */ - itv->vbi.in.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE; + itv->vbi.in.type = V4L2_BUF_TYPE_VBI_CAPTURE; itv->vbi.sliced_in = &itv->vbi.in.fmt.sliced; /* 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 b76a1226863..be2d779dba1 100644 --- a/drivers/media/video/ivtv/ivtv-driver.h +++ b/drivers/media/video/ivtv/ivtv-driver.h @@ -750,6 +750,12 @@ void ivtv_read_eeprom(struct ivtv *itv, struct tveeprom *tv); /* First-open initialization: load firmware, init cx25840, etc. */ int ivtv_init_on_first_open(struct ivtv *itv); +/* Test if the current VBI mode is raw (1) or sliced (0) */ +static inline int ivtv_raw_vbi(const struct ivtv *itv) +{ + return itv->vbi.in.type == V4L2_BUF_TYPE_VBI_CAPTURE; +} + /* This is a PCI post thing, where if the pci register is not read, then the write doesn't always take effect right away. By reading back the 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 304261efc53..b7457fc60ba 100644 --- a/drivers/media/video/ivtv/ivtv-fileops.c +++ b/drivers/media/video/ivtv/ivtv-fileops.c @@ -78,7 +78,7 @@ static int ivtv_claim_stream(struct ivtv_open_id *id, int type) if (type == IVTV_DEC_STREAM_TYPE_MPG) { vbi_type = IVTV_DEC_STREAM_TYPE_VBI; } else if (type == IVTV_ENC_STREAM_TYPE_MPG && - itv->vbi.insert_mpeg && itv->vbi.sliced_in->service_set) { + itv->vbi.insert_mpeg && !ivtv_raw_vbi(itv)) { vbi_type = IVTV_ENC_STREAM_TYPE_VBI; } else { return 0; @@ -305,7 +305,7 @@ static size_t ivtv_copy_buf_to_user(struct ivtv_stream *s, struct ivtv_buffer *b if (len > ucount) len = ucount; if (itv->vbi.insert_mpeg && s->type == IVTV_ENC_STREAM_TYPE_MPG && - itv->vbi.sliced_in->service_set && buf != &itv->vbi.sliced_mpeg_buf) { + !ivtv_raw_vbi(itv) && buf != &itv->vbi.sliced_mpeg_buf) { const char *start = buf->buf + buf->readpos; const char *p = start + 1; const u8 *q; @@ -372,7 +372,7 @@ static ssize_t ivtv_read(struct ivtv_stream *s, char __user *ubuf, size_t tot_co /* Each VBI buffer is one frame, the v4l2 API says that for VBI the frames should arrive one-by-one, so make sure we never output more than one VBI frame at a time */ if (s->type == IVTV_DEC_STREAM_TYPE_VBI || - (s->type == IVTV_ENC_STREAM_TYPE_VBI && itv->vbi.sliced_in->service_set)) + (s->type == IVTV_ENC_STREAM_TYPE_VBI && !ivtv_raw_vbi(itv))) single_frame = 1; for (;;) { diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c index f5b289ef410..3d0013bdd1f 100644 --- a/drivers/media/video/ivtv/ivtv-ioctl.c +++ b/drivers/media/video/ivtv/ivtv-ioctl.c @@ -575,8 +575,11 @@ static int ivtv_s_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *f { struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; + if (!ivtv_raw_vbi(itv) && atomic_read(&itv->capturing) > 0) + return -EBUSY; itv->vbi.sliced_in->service_set = 0; - itv->video_dec_func(itv, VIDIOC_S_FMT, &itv->vbi.in); + itv->vbi.in.type = V4L2_BUF_TYPE_VBI_CAPTURE; + itv->video_dec_func(itv, VIDIOC_S_FMT, fmt); return ivtv_g_fmt_vbi_cap(file, fh, fmt); } @@ -591,8 +594,9 @@ static int ivtv_s_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_fo return ret; check_service_set(vbifmt, itv->is_50hz); - if (atomic_read(&itv->capturing) > 0) + if (ivtv_raw_vbi(itv) && atomic_read(&itv->capturing) > 0) return -EBUSY; + itv->vbi.in.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE; itv->video_dec_func(itv, VIDIOC_S_FMT, fmt); memcpy(itv->vbi.sliced_in, vbifmt, sizeof(*itv->vbi.sliced_in)); return 0; diff --git a/drivers/media/video/ivtv/ivtv-streams.c b/drivers/media/video/ivtv/ivtv-streams.c index 24273fbea47..5bbf31e3930 100644 --- a/drivers/media/video/ivtv/ivtv-streams.c +++ b/drivers/media/video/ivtv/ivtv-streams.c @@ -334,7 +334,7 @@ void ivtv_streams_cleanup(struct ivtv *itv, int unregister) static void ivtv_vbi_setup(struct ivtv *itv) { - int raw = itv->vbi.sliced_in->service_set == 0; + int raw = ivtv_raw_vbi(itv); u32 data[CX2341X_MBOX_MAX_DATA]; int lines; int i; diff --git a/drivers/media/video/ivtv/ivtv-vbi.c b/drivers/media/video/ivtv/ivtv-vbi.c index 1ce9deb1104..4a37a7d2e69 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, int y; /* Raw VBI data */ - if (streamtype == IVTV_ENC_STREAM_TYPE_VBI && itv->vbi.sliced_in->service_set == 0) { + if (streamtype == IVTV_ENC_STREAM_TYPE_VBI && ivtv_raw_vbi(itv)) { u8 type; ivtv_buf_swap(buf); diff --git a/drivers/media/video/saa7115.c b/drivers/media/video/saa7115.c index 4ed7d65dd63..c8e9cb3db30 100644 --- a/drivers/media/video/saa7115.c +++ b/drivers/media/video/saa7115.c @@ -1057,7 +1057,7 @@ static void saa711x_set_lcr(struct i2c_client *client, struct v4l2_sliced_vbi_fo for (i = 0; i <= 23; i++) lcr[i] = 0xff; - if (fmt->service_set == 0) { + if (fmt == NULL) { /* raw VBI */ if (is_50hz) for (i = 6; i <= 23; i++) @@ -1113,7 +1113,7 @@ static void saa711x_set_lcr(struct i2c_client *client, struct v4l2_sliced_vbi_fo } /* enable/disable raw VBI capturing */ - saa711x_writeregs(client, fmt->service_set == 0 ? + saa711x_writeregs(client, fmt == NULL ? saa7115_cfg_vbi_on : saa7115_cfg_vbi_off); } @@ -1153,6 +1153,10 @@ static int saa711x_set_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt saa711x_set_lcr(client, &fmt->fmt.sliced); return 0; } + if (fmt->type == V4L2_BUF_TYPE_VBI_CAPTURE) { + saa711x_set_lcr(client, NULL); + return 0; + } if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; -- cgit v1.2.3-70-g09d2 From c777549fc9c5c704707394b0235a9a6794247b83 Mon Sep 17 00:00:00 2001 From: Ian Armstrong Date: Sat, 4 Oct 2008 10:28:24 -0300 Subject: V4L/DVB (9163): ivtvfb: fix sparse warnings and improve write function Signed-off-by: Ian Armstrong Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/ivtv/ivtvfb.c | 76 +++++++++++++++++++-------------------- 1 file changed, 37 insertions(+), 39 deletions(-) (limited to 'drivers/media/video/ivtv') diff --git a/drivers/media/video/ivtv/ivtvfb.c b/drivers/media/video/ivtv/ivtvfb.c index bdfda48e56b..249758e53f5 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, int size_in_bytes) { DEFINE_WAIT(wait); - int ret = 0; int got_sig = 0; mutex_lock(&itv->udma.lock); @@ -316,7 +315,7 @@ static int ivtvfb_prep_dec_dma_to_device(struct ivtv *itv, return -EINTR; } - return ret; + return 0; } static int ivtvfb_prep_frame(struct ivtv *itv, int cmd, void __user *source, @@ -373,6 +372,7 @@ static ssize_t ivtvfb_write(struct fb_info *info, const char __user *buf, unsigned long p = *ppos; void *dst; int err = 0; + int dma_err; unsigned long total_size; struct ivtv *itv = (struct ivtv *) info->par; unsigned long dma_offset = @@ -399,7 +399,6 @@ static ssize_t ivtvfb_write(struct fb_info *info, const char __user *buf, if (count + p > total_size) { if (!err) err = -ENOSPC; - count = total_size - p; } @@ -408,39 +407,34 @@ static ssize_t ivtvfb_write(struct fb_info *info, const char __user *buf, if (info->fbops->fb_sync) info->fbops->fb_sync(info); - if (!access_ok(VERIFY_READ, buf, count)) { - IVTVFB_WARN("Invalid userspace pointer 0x%08lx\n", - (unsigned long)buf); - err = -EFAULT; - } - - if (!err) { - /* If transfer size > threshold and both src/dst - addresses are aligned, use DMA */ - if (count >= 4096 && - ((unsigned long)buf & 3) == ((unsigned long)dst & 3)) { - /* Odd address = can't DMA. Align */ - if ((unsigned long)dst & 3) { - lead = 4 - ((unsigned long)dst & 3); - memcpy(dst, buf, lead); - buf += lead; - dst += lead; - } - /* DMA resolution is 32 bits */ - if ((count - lead) & 3) - tail = (count - lead) & 3; - /* DMA the data */ - dma_size = count - lead - tail; - err = ivtvfb_prep_dec_dma_to_device(itv, - p + lead + dma_offset, (void *)buf, dma_size); - dst += dma_size; - buf += dma_size; - /* Copy any leftover data */ - if (tail) - memcpy(dst, buf, tail); - } else { - memcpy(dst, buf, count); + /* If transfer size > threshold and both src/dst + addresses are aligned, use DMA */ + if (count >= 4096 && + ((unsigned long)buf & 3) == ((unsigned long)dst & 3)) { + /* Odd address = can't DMA. Align */ + if ((unsigned long)dst & 3) { + lead = 4 - ((unsigned long)dst & 3); + if (copy_from_user(dst, buf, lead)) + return -EFAULT; + buf += lead; + dst += lead; } + /* DMA resolution is 32 bits */ + if ((count - lead) & 3) + tail = (count - lead) & 3; + /* DMA the data */ + dma_size = count - lead - tail; + dma_err = ivtvfb_prep_dec_dma_to_device(itv, + p + lead + dma_offset, (void __user *)buf, dma_size); + if (dma_err) + return dma_err; + dst += dma_size; + buf += dma_size; + /* Copy any leftover data */ + if (tail && copy_from_user(dst, buf, tail)) + return -EFAULT; + } else if (copy_from_user(dst, buf, count)) { + return -EFAULT; } if (!err) @@ -463,9 +457,12 @@ static int ivtvfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long ar vblank.flags = FB_VBLANK_HAVE_COUNT |FB_VBLANK_HAVE_VCOUNT | FB_VBLANK_HAVE_VSYNC; trace = read_reg(0x028c0) >> 16; - if (itv->is_50hz && trace > 312) trace -= 312; - else if (itv->is_60hz && trace > 262) trace -= 262; - if (trace == 1) vblank.flags |= FB_VBLANK_VSYNCING; + if (itv->is_50hz && trace > 312) + trace -= 312; + else if (itv->is_60hz && trace > 262) + trace -= 262; + if (trace == 1) + vblank.flags |= FB_VBLANK_VSYNCING; vblank.count = itv->last_vsync_field; vblank.vcount = trace; vblank.hcount = 0; @@ -476,7 +473,8 @@ static int ivtvfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long ar case FBIO_WAITFORVSYNC: prepare_to_wait(&itv->vsync_waitq, &wait, TASK_INTERRUPTIBLE); - if (!schedule_timeout(msecs_to_jiffies(50))) rc = -ETIMEDOUT; + if (!schedule_timeout(msecs_to_jiffies(50))) + rc = -ETIMEDOUT; finish_wait(&itv->vsync_waitq, &wait); return rc; -- cgit v1.2.3-70-g09d2 From 4ee0e42b31b282d0d0bb11effbbeb0610ee76d09 Mon Sep 17 00:00:00 2001 From: Ian Armstrong Date: Mon, 6 Oct 2008 03:03:18 -0300 Subject: V4L/DVB (9164): ivtvfb: a small cosmetic change Signed-off-by: Ian Armstrong Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/ivtv/ivtvfb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media/video/ivtv') diff --git a/drivers/media/video/ivtv/ivtvfb.c b/drivers/media/video/ivtv/ivtvfb.c index 249758e53f5..8a4a150b12f 100644 --- a/drivers/media/video/ivtv/ivtvfb.c +++ b/drivers/media/video/ivtv/ivtvfb.c @@ -367,7 +367,7 @@ static int ivtvfb_prep_frame(struct ivtv *itv, int cmd, void __user *source, } static ssize_t ivtvfb_write(struct fb_info *info, const char __user *buf, - size_t count, loff_t *ppos) + size_t count, loff_t *ppos) { unsigned long p = *ppos; void *dst; -- cgit v1.2.3-70-g09d2 From ec9faa1cfac1dd64a2a865dc7c577f3d483656bd Mon Sep 17 00:00:00 2001 From: Ian Armstrong Date: Mon, 6 Oct 2008 03:06:08 -0300 Subject: V4L/DVB (9165): ivtv: V4L2_FBUF_FLAG_OVERLAY status fix When the framebuffer format was queried via VIDIOC_G_FBUF, V4L2_FBUF_FLAG_OVERLAY would only be correctly returned for certain screen depths. Signed-off-by: Ian Armstrong Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/ivtv/ivtv-ioctl.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers/media/video/ivtv') diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c index 3d0013bdd1f..3c2628a6301 100644 --- a/drivers/media/video/ivtv/ivtv-ioctl.c +++ b/drivers/media/video/ivtv/ivtv-ioctl.c @@ -1363,6 +1363,9 @@ static int ivtv_g_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb) if (itv->osd_global_alpha_state) fb->flags |= V4L2_FBUF_FLAG_GLOBAL_ALPHA; + if (yi->track_osd) + fb->flags |= V4L2_FBUF_FLAG_OVERLAY; + pixfmt &= 7; /* no local alpha for RGB565 or unknown formats */ @@ -1382,8 +1385,6 @@ static int ivtv_g_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb) else fb->flags |= V4L2_FBUF_FLAG_LOCAL_ALPHA; } - if (yi->track_osd) - fb->flags |= V4L2_FBUF_FLAG_OVERLAY; return 0; } -- cgit v1.2.3-70-g09d2 From 2bd7ac55c31cb4f42e331d69dde9fc034a68944f Mon Sep 17 00:00:00 2001 From: Ian Armstrong Date: Thu, 9 Oct 2008 12:04:23 -0300 Subject: V4L/DVB (9166): ivtv - Fix potential race condition in yuv handler Modified yuv register update handling to remove a potential race condition which could occur with the first video frame. Also removed a forced yuv position update, since changing the source video dimensions or interlace settings doesn't affect the frame already being displayed. Signed-off-by: Ian Armstrong Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/ivtv/ivtv-driver.h | 2 ++ drivers/media/video/ivtv/ivtv-ioctl.c | 2 -- drivers/media/video/ivtv/ivtv-irq.c | 9 ++++++--- drivers/media/video/ivtv/ivtv-yuv.c | 1 + 4 files changed, 9 insertions(+), 5 deletions(-) (limited to 'drivers/media/video/ivtv') diff --git a/drivers/media/video/ivtv/ivtv-driver.h b/drivers/media/video/ivtv/ivtv-driver.h index be2d779dba1..bc29436e8a3 100644 --- a/drivers/media/video/ivtv/ivtv-driver.h +++ b/drivers/media/video/ivtv/ivtv-driver.h @@ -506,6 +506,8 @@ struct yuv_playback_info struct v4l2_rect main_rect; u32 v4l2_src_w; u32 v4l2_src_h; + + u8 running; /* Have any frames been displayed */ }; #define IVTV_VBI_FRAMES 32 diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c index 3c2628a6301..8696527ab13 100644 --- a/drivers/media/video/ivtv/ivtv-ioctl.c +++ b/drivers/media/video/ivtv/ivtv-ioctl.c @@ -644,8 +644,6 @@ static int ivtv_s_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *f itv->dma_data_req_size = 1080 * ((yi->v4l2_src_h + 31) & ~31); - /* Force update of yuv registers */ - yi->yuv_forced_update = 1; return 0; } diff --git a/drivers/media/video/ivtv/ivtv-irq.c b/drivers/media/video/ivtv/ivtv-irq.c index 34f3ab82785..f5d00ec5da7 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) */ unsigned int frame = read_reg(0x28c0) & 1; struct yuv_playback_info *yi = &itv->yuv_info; - int last_dma_frame = atomic_read(&itv->yuv_info.next_dma_frame); + int last_dma_frame = atomic_read(&yi->next_dma_frame); struct yuv_frame_info *f = &yi->new_frame_info[last_dma_frame]; if (0) IVTV_DEBUG_IRQ("DEC VSYNC\n"); @@ -772,6 +772,7 @@ static void ivtv_irq_vsync(struct ivtv *itv) next_dma_frame = (next_dma_frame + 1) % IVTV_YUV_BUFFERS; atomic_set(&yi->next_dma_frame, next_dma_frame); yi->fields_lapsed = -1; + yi->running = 1; } } } @@ -804,9 +805,11 @@ static void ivtv_irq_vsync(struct ivtv *itv) } /* Check if we need to update the yuv registers */ - if ((yi->yuv_forced_update || f->update) && last_dma_frame != -1) { + if (yi->running && (yi->yuv_forced_update || f->update)) { if (!f->update) { - last_dma_frame = (u8)(last_dma_frame - 1) % IVTV_YUV_BUFFERS; + last_dma_frame = + (u8)(atomic_read(&yi->next_dma_frame) - + 1) % IVTV_YUV_BUFFERS; f = &yi->new_frame_info[last_dma_frame]; } diff --git a/drivers/media/video/ivtv/ivtv-yuv.c b/drivers/media/video/ivtv/ivtv-yuv.c index 3092ff1d00a..ee91107376c 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) IVTV_DEBUG_YUV("ivtv_yuv_close\n"); ivtv_waitq(&itv->vsync_waitq); + yi->running = 0; atomic_set(&yi->next_dma_frame, -1); atomic_set(&yi->next_fill_frame, 0); -- cgit v1.2.3-70-g09d2 From 2e668962a54b64f3daffb8eef3ca538e25324d1a Mon Sep 17 00:00:00 2001 From: Ian Armstrong Date: Sat, 11 Oct 2008 06:39:05 -0300 Subject: V4L/DVB (9190): ivtv: yuv write() error handling tweak Modifies behaviour of a failed dma write() operation for the yuv device. If the dma transfer for the yuv device fails, the write() operation will now exit immediately. Signed-off-by: Ian Armstrong Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/ivtv/ivtv-fileops.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'drivers/media/video/ivtv') diff --git a/drivers/media/video/ivtv/ivtv-fileops.c b/drivers/media/video/ivtv/ivtv-fileops.c index b7457fc60ba..1c404e454a3 100644 --- a/drivers/media/video/ivtv/ivtv-fileops.c +++ b/drivers/media/video/ivtv/ivtv-fileops.c @@ -600,13 +600,14 @@ retry: since we may get here before the stream has been fully set-up */ if (mode == OUT_YUV && s->q_full.length == 0 && itv->dma_data_req_size) { while (count >= itv->dma_data_req_size) { - if (!ivtv_yuv_udma_stream_frame (itv, (void __user *)user_buf)) { - bytes_written += itv->dma_data_req_size; - user_buf += itv->dma_data_req_size; - count -= itv->dma_data_req_size; - } else { - break; - } + rc = ivtv_yuv_udma_stream_frame(itv, (void __user *)user_buf); + + if (rc < 0) + return rc; + + bytes_written += itv->dma_data_req_size; + user_buf += itv->dma_data_req_size; + count -= itv->dma_data_req_size; } if (count == 0) { IVTV_DEBUG_HI_FILE("Wrote %d bytes to %s (%d)\n", bytes_written, s->name, s->q_full.bytesused); -- cgit v1.2.3-70-g09d2 From 962d699e5d12952c43d7316bc72a527a8aa134b7 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 11 Oct 2008 09:00:39 -0300 Subject: V4L/DVB (9191): ivtv: partially revert an earlier patch that checks the max image height Ian Armstrong pointed out to me that it is perfectly valid to have a 576 lines YUV video with NTSC output in this particular case. In fact, without this the X driver for ivtv does not function properly. Reverted my earlier change that restrictred the height to 480 for NTSC and add the comments provided by Ian to explain what is happening here. Thanks-to: Ian Armstrong Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/ivtv/ivtv-ioctl.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) (limited to 'drivers/media/video/ivtv') diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c index 8696527ab13..208fb54842f 100644 --- a/drivers/media/video/ivtv/ivtv-ioctl.c +++ b/drivers/media/video/ivtv/ivtv-ioctl.c @@ -509,7 +509,6 @@ static int ivtv_try_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_ static int ivtv_try_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *fmt) { struct ivtv_open_id *id = fh; - struct ivtv *itv = id->itv; s32 w = fmt->fmt.pix.width; s32 h = fmt->fmt.pix.height; int field = fmt->fmt.pix.field; @@ -517,7 +516,22 @@ static int ivtv_try_fmt_vid_out(struct file *file, void *fh, struct v4l2_format w = min(w, 720); w = max(w, 2); - h = min(h, itv->is_out_50hz ? 576 : 480); + /* Why can the height be 576 even when the output is NTSC? + + Internally the buffers of the PVR350 are always set to 720x576. The + decoded video frame will always be placed in the top left corner of + this buffer. For any video which is not 720x576, the buffer will + then be cropped to remove the unused right and lower areas, with + the remaining image being scaled by the hardware to fit the display + area. The video can be scaled both up and down, so a 720x480 video + can be displayed full-screen on PAL and a 720x576 video can be + displayed without cropping on NTSC. + + Note that the scaling only occurs on the video stream, the osd + resolution is locked to the broadcast standard and not scaled. + + Thanks to Ian Armstrong for this explanation. */ + h = min(h, 576); h = max(h, 2); if (id->type == IVTV_DEC_STREAM_TYPE_YUV) fmt->fmt.pix.field = field; -- cgit v1.2.3-70-g09d2 From 1a651a00e20fd4997f0b91258f6f95b7d96edcd9 Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Sat, 18 Oct 2008 20:28:37 -0700 Subject: byteorder: remove direct includes of linux/byteorder/swab[b].h A consolidated implementation will provide this generically through asm/byteorder, remove direct includes to avoid breakage when the changeover to the new implementation occurs. Signed-off-by: Harvey Harrison Acked-by: Mauro Carvalho Chehab Acked-by: "Paul E. McKenney" Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/media/dvb/ttpci/av7110.c | 2 +- drivers/media/video/cx18/cx18-driver.h | 1 + drivers/media/video/ivtv/ivtv-driver.h | 1 + kernel/rcupreempt.c | 2 +- 4 files changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers/media/video/ivtv') diff --git a/drivers/media/dvb/ttpci/av7110.c b/drivers/media/dvb/ttpci/av7110.c index c7c770c2898..aa1ff524256 100644 --- a/drivers/media/dvb/ttpci/av7110.c +++ b/drivers/media/dvb/ttpci/av7110.c @@ -36,7 +36,6 @@ #include #include #include -#include #include #include @@ -52,6 +51,7 @@ #include #include #include +#include #include diff --git a/drivers/media/video/cx18/cx18-driver.h b/drivers/media/video/cx18/cx18-driver.h index fa8be0731a3..a4b1708fafe 100644 --- a/drivers/media/video/cx18/cx18-driver.h +++ b/drivers/media/video/cx18/cx18-driver.h @@ -41,6 +41,7 @@ #include #include #include +#include #include #include diff --git a/drivers/media/video/ivtv/ivtv-driver.h b/drivers/media/video/ivtv/ivtv-driver.h index bc29436e8a3..3733b2afec5 100644 --- a/drivers/media/video/ivtv/ivtv-driver.h +++ b/drivers/media/video/ivtv/ivtv-driver.h @@ -55,6 +55,7 @@ #include #include #include +#include #include #include diff --git a/kernel/rcupreempt.c b/kernel/rcupreempt.c index ca4bbbe04aa..59236e8b9da 100644 --- a/kernel/rcupreempt.c +++ b/kernel/rcupreempt.c @@ -54,9 +54,9 @@ #include #include #include -#include #include #include +#include /* * PREEMPT_RCU data structures. -- cgit v1.2.3-70-g09d2