summaryrefslogtreecommitdiff
path: root/drivers/media/usb
diff options
context:
space:
mode:
authorAndré Fabian Silva Delgado <emulatorman@parabola.nu>2015-12-15 14:52:16 -0300
committerAndré Fabian Silva Delgado <emulatorman@parabola.nu>2015-12-15 14:52:16 -0300
commit8d91c1e411f55d7ea91b1183a2e9f8088fb4d5be (patch)
treee9891aa6c295060d065adffd610c4f49ecf884f3 /drivers/media/usb
parenta71852147516bc1cb5b0b3cbd13639bfd4022dc8 (diff)
Linux-libre 4.3.2-gnu
Diffstat (limited to 'drivers/media/usb')
-rw-r--r--drivers/media/usb/airspy/airspy.c3
-rw-r--r--drivers/media/usb/cx231xx/cx231xx-video.c4
-rw-r--r--drivers/media/usb/dvb-usb-v2/lmedm04.c21
-rw-r--r--drivers/media/usb/dvb-usb-v2/rtl28xxu.c15
-rw-r--r--drivers/media/usb/dvb-usb-v2/rtl28xxu.h2
-rw-r--r--drivers/media/usb/dvb-usb/pctv452e.c2
-rw-r--r--drivers/media/usb/dvb-usb/technisat-usb2.c2
-rw-r--r--drivers/media/usb/em28xx/em28xx-dvb.c4
-rw-r--r--drivers/media/usb/go7007/s2250-board.c1
-rw-r--r--drivers/media/usb/gspca/m5602/m5602_s5k83a.c2
-rw-r--r--drivers/media/usb/gspca/sn9c2028.c2
-rw-r--r--drivers/media/usb/stk1160/stk1160-core.c5
-rw-r--r--drivers/media/usb/stk1160/stk1160-reg.h34
-rw-r--r--drivers/media/usb/stk1160/stk1160-v4l.c219
-rw-r--r--drivers/media/usb/stk1160/stk1160-video.c4
-rw-r--r--drivers/media/usb/stk1160/stk1160.h4
-rw-r--r--drivers/media/usb/ttusb-dec/ttusb_dec.c9
-rw-r--r--drivers/media/usb/usbvision/usbvision-core.c71
-rw-r--r--drivers/media/usb/usbvision/usbvision-i2c.c2
-rw-r--r--drivers/media/usb/usbvision/usbvision-video.c246
-rw-r--r--drivers/media/usb/usbvision/usbvision.h10
21 files changed, 355 insertions, 307 deletions
diff --git a/drivers/media/usb/airspy/airspy.c b/drivers/media/usb/airspy/airspy.c
index 4069234ab..8f2e1c277 100644
--- a/drivers/media/usb/airspy/airspy.c
+++ b/drivers/media/usb/airspy/airspy.c
@@ -937,9 +937,6 @@ static int airspy_set_if_gain(struct airspy *s)
ret = airspy_ctrl_msg(s, CMD_SET_VGA_GAIN, 0, s->if_gain->val,
&u8tmp, 1);
if (ret)
- goto err;
-err:
- if (ret)
dev_dbg(s->dev, "failed=%d\n", ret);
return ret;
diff --git a/drivers/media/usb/cx231xx/cx231xx-video.c b/drivers/media/usb/cx231xx/cx231xx-video.c
index c6ff89682..979816069 100644
--- a/drivers/media/usb/cx231xx/cx231xx-video.c
+++ b/drivers/media/usb/cx231xx/cx231xx-video.c
@@ -1875,7 +1875,7 @@ static int cx231xx_close(struct file *filp)
v4l2_fh_exit(&fh->fh);
kfree(fh);
dev->users--;
- wake_up_interruptible_nr(&dev->open, 1);
+ wake_up_interruptible(&dev->open);
return 0;
}
@@ -1908,7 +1908,7 @@ static int cx231xx_close(struct file *filp)
}
v4l2_fh_exit(&fh->fh);
kfree(fh);
- wake_up_interruptible_nr(&dev->open, 1);
+ wake_up_interruptible(&dev->open);
return 0;
}
diff --git a/drivers/media/usb/dvb-usb-v2/lmedm04.c b/drivers/media/usb/dvb-usb-v2/lmedm04.c
index a9017bf5a..ccf1876ce 100644
--- a/drivers/media/usb/dvb-usb-v2/lmedm04.c
+++ b/drivers/media/usb/dvb-usb-v2/lmedm04.c
@@ -348,15 +348,16 @@ static void lme2510_int_response(struct urb *lme_urb)
switch (ibuf[0]) {
case 0xaa:
debug_data_snipet(1, "INT Remote data snipet", ibuf);
- if ((ibuf[4] + ibuf[5]) == 0xff) {
- key = RC_SCANCODE_NECX((ibuf[2] ^ 0xff) << 8 |
- (ibuf[3] > 0) ? (ibuf[3] ^ 0xff) : 0,
- ibuf[5]);
- deb_info(1, "INT Key =%08x", key);
- if (adap_to_d(adap)->rc_dev != NULL)
- rc_keydown(adap_to_d(adap)->rc_dev,
- RC_TYPE_NEC, key, 0);
- }
+ if (!adap_to_d(adap)->rc_dev)
+ break;
+
+ key = RC_SCANCODE_NEC32(ibuf[2] << 24 |
+ ibuf[3] << 16 |
+ ibuf[4] << 8 |
+ ibuf[5]);
+
+ deb_info(1, "INT Key = 0x%08x", key);
+ rc_keydown(adap_to_d(adap)->rc_dev, RC_TYPE_NEC, key, 0);
break;
case 0xbb:
switch (st->tuner_config) {
@@ -1344,7 +1345,7 @@ module_usb_driver(lme2510_driver);
MODULE_AUTHOR("Malcolm Priestley <tvboxspy@gmail.com>");
MODULE_DESCRIPTION("LME2510(C) DVB-S USB2.0");
-MODULE_VERSION("2.06");
+MODULE_VERSION("2.07");
MODULE_LICENSE("GPL");
/*(DEBLOBBED)*/
diff --git a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
index c3cac4c12..197a4f2e5 100644
--- a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
+++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
@@ -34,6 +34,14 @@ static int rtl28xxu_ctrl_msg(struct dvb_usb_device *d, struct rtl28xxu_req *req)
unsigned int pipe;
u8 requesttype;
+ mutex_lock(&d->usb_mutex);
+
+ if (req->size > sizeof(dev->buf)) {
+ dev_err(&d->intf->dev, "too large message %u\n", req->size);
+ ret = -EINVAL;
+ goto err_mutex_unlock;
+ }
+
if (req->index & CMD_WR_FLAG) {
/* write */
memcpy(dev->buf, req->data, req->size);
@@ -50,14 +58,17 @@ static int rtl28xxu_ctrl_msg(struct dvb_usb_device *d, struct rtl28xxu_req *req)
dvb_usb_dbg_usb_control_msg(d->udev, 0, requesttype, req->value,
req->index, dev->buf, req->size);
if (ret < 0)
- goto err;
+ goto err_mutex_unlock;
/* read request, copy returned data to return buf */
if (requesttype == (USB_TYPE_VENDOR | USB_DIR_IN))
memcpy(req->data, dev->buf, req->size);
+ mutex_unlock(&d->usb_mutex);
+
return 0;
-err:
+err_mutex_unlock:
+ mutex_unlock(&d->usb_mutex);
dev_dbg(&d->intf->dev, "failed=%d\n", ret);
return ret;
}
diff --git a/drivers/media/usb/dvb-usb-v2/rtl28xxu.h b/drivers/media/usb/dvb-usb-v2/rtl28xxu.h
index 9f6115a2e..138062960 100644
--- a/drivers/media/usb/dvb-usb-v2/rtl28xxu.h
+++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.h
@@ -71,7 +71,7 @@
struct rtl28xxu_dev {
- u8 buf[28];
+ u8 buf[128];
u8 chip_id;
u8 tuner;
char *tuner_name;
diff --git a/drivers/media/usb/dvb-usb/pctv452e.c b/drivers/media/usb/dvb-usb/pctv452e.c
index d17618fe8..ec397c4b7 100644
--- a/drivers/media/usb/dvb-usb/pctv452e.c
+++ b/drivers/media/usb/dvb-usb/pctv452e.c
@@ -611,7 +611,7 @@ static int pctv452e_read_mac_address(struct dvb_usb_device *d, u8 mac[6])
return 0;
failed:
- memset(mac, 0, 6);
+ eth_zero_addr(mac);
return ret;
}
diff --git a/drivers/media/usb/dvb-usb/technisat-usb2.c b/drivers/media/usb/dvb-usb/technisat-usb2.c
index 733a1eaf6..7e99c908e 100644
--- a/drivers/media/usb/dvb-usb/technisat-usb2.c
+++ b/drivers/media/usb/dvb-usb/technisat-usb2.c
@@ -707,7 +707,7 @@ static struct dvb_usb_device_properties technisat_usb2_devices = {
.stream = {
.type = USB_ISOC,
- .count = 8,
+ .count = 4,
.endpoint = 0x2,
.u = {
.isoc = {
diff --git a/drivers/media/usb/em28xx/em28xx-dvb.c b/drivers/media/usb/em28xx/em28xx-dvb.c
index 4e1f81dd2..70b23d987 100644
--- a/drivers/media/usb/em28xx/em28xx-dvb.c
+++ b/drivers/media/usb/em28xx/em28xx-dvb.c
@@ -808,10 +808,6 @@ static struct tda18271_config em28xx_cxd2820r_tda18271_config = {
.gate = TDA18271_GATE_DIGITAL,
};
-static const struct a8293_config em28xx_a8293_config = {
- .i2c_addr = 0x08, /* (0x10 >> 1) */
-};
-
static struct zl10353_config em28xx_zl10353_no_i2c_gate_dev = {
.demod_address = (0x1e >> 1),
.disable_i2c_gate_ctrl = 1,
diff --git a/drivers/media/usb/go7007/s2250-board.c b/drivers/media/usb/go7007/s2250-board.c
index 5c2a49534..1466db150 100644
--- a/drivers/media/usb/go7007/s2250-board.c
+++ b/drivers/media/usb/go7007/s2250-board.c
@@ -629,7 +629,6 @@ MODULE_DEVICE_TABLE(i2c, s2250_id);
static struct i2c_driver s2250_driver = {
.driver = {
- .owner = THIS_MODULE,
.name = "s2250",
},
.probe = s2250_probe,
diff --git a/drivers/media/usb/gspca/m5602/m5602_s5k83a.c b/drivers/media/usb/gspca/m5602/m5602_s5k83a.c
index 7cbc3a00b..bf6b21543 100644
--- a/drivers/media/usb/gspca/m5602/m5602_s5k83a.c
+++ b/drivers/media/usb/gspca/m5602/m5602_s5k83a.c
@@ -177,7 +177,7 @@ static int rotation_thread_function(void *data)
__s32 vflip, hflip;
set_current_state(TASK_INTERRUPTIBLE);
- while (!schedule_timeout(100)) {
+ while (!schedule_timeout(msecs_to_jiffies(100))) {
if (mutex_lock_interruptible(&sd->gspca_dev.usb_lock))
break;
diff --git a/drivers/media/usb/gspca/sn9c2028.c b/drivers/media/usb/gspca/sn9c2028.c
index c75b7388a..4f2050a5e 100644
--- a/drivers/media/usb/gspca/sn9c2028.c
+++ b/drivers/media/usb/gspca/sn9c2028.c
@@ -140,7 +140,7 @@ static int sn9c2028_long_command(struct gspca_dev *gspca_dev, u8 *command)
status = sn9c2028_read1(gspca_dev);
if (status < 0) {
pr_err("long command status read error %d\n", status);
- return (status < 0) ? status : -EIO;
+ return status;
}
memset(reading, 0, 4);
diff --git a/drivers/media/usb/stk1160/stk1160-core.c b/drivers/media/usb/stk1160/stk1160-core.c
index 03504dcf3..1b6836f15 100644
--- a/drivers/media/usb/stk1160/stk1160-core.c
+++ b/drivers/media/usb/stk1160/stk1160-core.c
@@ -162,7 +162,7 @@ static void stk1160_release(struct v4l2_device *v4l2_dev)
{
struct stk1160 *dev = container_of(v4l2_dev, struct stk1160, v4l2_dev);
- stk1160_info("releasing all resources\n");
+ stk1160_dbg("releasing all resources\n");
stk1160_i2c_unregister(dev);
@@ -363,9 +363,6 @@ static int stk1160_probe(struct usb_interface *interface,
dev->sd_saa7115 = v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
"saa7115_auto", 0, saa7113_addrs);
- stk1160_info("driver ver %s successfully loaded\n",
- STK1160_VERSION);
-
/* i2c reset saa711x */
v4l2_device_call_all(&dev->v4l2_dev, 0, core, reset, 0);
v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_stream, 0);
diff --git a/drivers/media/usb/stk1160/stk1160-reg.h b/drivers/media/usb/stk1160/stk1160-reg.h
index 3e49da6e7..81ff3a15d 100644
--- a/drivers/media/usb/stk1160/stk1160-reg.h
+++ b/drivers/media/usb/stk1160/stk1160-reg.h
@@ -33,6 +33,40 @@
*/
#define STK1160_DCTRL 0x100
+/*
+ * Decimation Control Register:
+ * Byte 104: Horizontal Decimation Line Unit Count
+ * Byte 105: Vertical Decimation Line Unit Count
+ * Byte 106: Decimation Control
+ * Bit 0 - Horizontal Decimation Control
+ * 0 Horizontal decimation is disabled.
+ * 1 Horizontal decimation is enabled.
+ * Bit 1 - Decimates Half or More Column
+ * 0 Decimates less than half from original column,
+ * send count unit (0x105) before each unit skipped.
+ * 1 Decimates half or more from original column,
+ * skip count unit (0x105) before each unit sent.
+ * Bit 2 - Vertical Decimation Control
+ * 0 Vertical decimation is disabled.
+ * 1 Vertical decimation is enabled.
+ * Bit 3 - Vertical Greater or Equal to Half
+ * 0 Decimates less than half from original row,
+ * send count unit (0x105) before each unit skipped.
+ * 1 Decimates half or more from original row,
+ * skip count unit (0x105) before each unit sent.
+ * Bit 4 - Decimation Unit
+ * 0 Decimation will work with 2 rows or columns per unit.
+ * 1 Decimation will work with 4 rows or columns per unit.
+ */
+#define STK1160_DMCTRL_H_UNITS 0x104
+#define STK1160_DMCTRL_V_UNITS 0x105
+#define STK1160_DMCTRL 0x106
+#define STK1160_H_DEC_EN BIT(0)
+#define STK1160_H_DEC_MODE BIT(1)
+#define STK1160_V_DEC_EN BIT(2)
+#define STK1160_V_DEC_MODE BIT(3)
+#define STK1160_DEC_UNIT_SIZE BIT(4)
+
/* Capture Frame Start Position */
#define STK116_CFSPO 0x110
#define STK116_CFSPO_STX_L 0x110
diff --git a/drivers/media/usb/stk1160/stk1160-v4l.c b/drivers/media/usb/stk1160/stk1160-v4l.c
index 4d313ed4c..e12b10352 100644
--- a/drivers/media/usb/stk1160/stk1160-v4l.c
+++ b/drivers/media/usb/stk1160/stk1160-v4l.c
@@ -42,6 +42,17 @@ static bool keep_buffers;
module_param(keep_buffers, bool, 0644);
MODULE_PARM_DESC(keep_buffers, "don't release buffers upon stop streaming");
+enum stk1160_decimate_mode {
+ STK1160_DECIMATE_MORE_THAN_HALF,
+ STK1160_DECIMATE_LESS_THAN_HALF,
+};
+
+struct stk1160_decimate_ctrl {
+ bool col_en, row_en;
+ enum stk1160_decimate_mode col_mode, row_mode;
+ unsigned int col_n, row_n;
+};
+
/* supported video standards */
static struct stk1160_fmt format[] = {
{
@@ -51,6 +62,19 @@ static struct stk1160_fmt format[] = {
}
};
+/*
+ * Helper to find the next divisor that results in modulo being zero.
+ * This is required to guarantee valid decimation unit counts.
+ */
+static unsigned int
+div_round_integer(unsigned int x, unsigned int y)
+{
+ for (;; y++) {
+ if (x % y == 0)
+ return x / y;
+ }
+}
+
static void stk1160_set_std(struct stk1160 *dev)
{
int i;
@@ -106,6 +130,41 @@ static void stk1160_set_std(struct stk1160 *dev)
}
+static void stk1160_set_fmt(struct stk1160 *dev,
+ struct stk1160_decimate_ctrl *ctrl)
+{
+ u32 val = 0;
+
+ if (ctrl) {
+ /*
+ * Since the format is UYVY, the device must skip or send
+ * a number of rows/columns multiple of four. This way, the
+ * colour format is preserved. The STK1160_DEC_UNIT_SIZE bit
+ * does exactly this.
+ */
+ val |= STK1160_DEC_UNIT_SIZE;
+ val |= ctrl->col_en ? STK1160_H_DEC_EN : 0;
+ val |= ctrl->row_en ? STK1160_V_DEC_EN : 0;
+ val |= ctrl->col_mode ==
+ STK1160_DECIMATE_MORE_THAN_HALF ?
+ STK1160_H_DEC_MODE : 0;
+ val |= ctrl->row_mode ==
+ STK1160_DECIMATE_MORE_THAN_HALF ?
+ STK1160_V_DEC_MODE : 0;
+
+ /* Horizontal count units */
+ stk1160_write_reg(dev, STK1160_DMCTRL_H_UNITS, ctrl->col_n);
+ /* Vertical count units */
+ stk1160_write_reg(dev, STK1160_DMCTRL_V_UNITS, ctrl->row_n);
+
+ stk1160_dbg("decimate 0x%x, column units %d, row units %d\n",
+ val, ctrl->col_n, ctrl->row_n);
+ }
+
+ /* Decimation control */
+ stk1160_write_reg(dev, STK1160_DMCTRL, val);
+}
+
/*
* Set a new alternate setting.
* Returns true is dev->max_pkt_size has changed, false otherwise.
@@ -136,7 +195,7 @@ static bool stk1160_set_alternate(struct stk1160 *dev)
dev->alt = i;
}
- stk1160_info("setting alternate %d\n", dev->alt);
+ stk1160_dbg("setting alternate %d\n", dev->alt);
if (dev->alt != prev_alt) {
stk1160_dbg("minimum isoc packet size: %u (alt=%d)\n",
@@ -194,6 +253,8 @@ static int stk1160_start_streaming(struct stk1160 *dev)
/* Start saa711x */
v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_stream, 1);
+ dev->sequence = 0;
+
/* Start stk1160 */
stk1160_write_reg(dev, STK1160_DCTRL, 0xb3);
stk1160_write_reg(dev, STK1160_DCTRL+3, 0x00);
@@ -224,7 +285,7 @@ static void stk1160_stop_hw(struct stk1160 *dev)
/* set alternate 0 */
dev->alt = 0;
- stk1160_info("setting alternate %d\n", dev->alt);
+ stk1160_dbg("setting alternate %d\n", dev->alt);
usb_set_interface(dev->udev, 0, 0);
/* Stop stk1160 */
@@ -321,41 +382,134 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
return 0;
}
-static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *f)
+static int stk1160_try_fmt(struct stk1160 *dev, struct v4l2_format *f,
+ struct stk1160_decimate_ctrl *ctrl)
{
- struct stk1160 *dev = video_drvdata(file);
+ unsigned int width, height;
+ unsigned int base_width, base_height;
+ unsigned int col_n, row_n;
+ enum stk1160_decimate_mode col_mode, row_mode;
+ bool col_en, row_en;
+
+ base_width = 720;
+ base_height = (dev->norm & V4L2_STD_525_60) ? 480 : 576;
+
+ /* Minimum width and height is 5% the frame size */
+ width = clamp_t(unsigned int, f->fmt.pix.width,
+ base_width / 20, base_width);
+ height = clamp_t(unsigned int, f->fmt.pix.height,
+ base_height / 20, base_height);
+
+ /* Let's set default no decimation values */
+ col_n = 0;
+ row_n = 0;
+ col_en = false;
+ row_en = false;
+ f->fmt.pix.width = base_width;
+ f->fmt.pix.height = base_height;
+ row_mode = STK1160_DECIMATE_LESS_THAN_HALF;
+ col_mode = STK1160_DECIMATE_LESS_THAN_HALF;
+
+ if (width < base_width && width > base_width / 2) {
+ /*
+ * The device will send count units for each
+ * unit skipped. This means count unit is:
+ *
+ * n = width / (frame width - width)
+ *
+ * And the width is:
+ *
+ * width = (n / n + 1) * frame width
+ */
+ col_n = div_round_integer(width, base_width - width);
+ if (col_n > 0 && col_n <= 255) {
+ col_en = true;
+ col_mode = STK1160_DECIMATE_LESS_THAN_HALF;
+ f->fmt.pix.width = (base_width * col_n) / (col_n + 1);
+ }
- /*
- * User can't choose size at his own will,
- * so we just return him the current size chosen
- * at standard selection.
- * TODO: Implement frame scaling?
- */
+ } else if (width <= base_width / 2) {
+
+ /*
+ * The device will skip count units for each
+ * unit sent. This means count is:
+ *
+ * n = (frame width / width) - 1
+ *
+ * And the width is:
+ *
+ * width = frame width / (n + 1)
+ */
+ col_n = div_round_integer(base_width, width) - 1;
+ if (col_n > 0 && col_n <= 255) {
+ col_en = true;
+ col_mode = STK1160_DECIMATE_MORE_THAN_HALF;
+ f->fmt.pix.width = base_width / (col_n + 1);
+ }
+ }
+
+ if (height < base_height && height > base_height / 2) {
+ row_n = div_round_integer(height, base_height - height);
+ if (row_n > 0 && row_n <= 255) {
+ row_en = true;
+ row_mode = STK1160_DECIMATE_LESS_THAN_HALF;
+ f->fmt.pix.height = (base_height * row_n) / (row_n + 1);
+ }
+
+ } else if (height <= base_height / 2) {
+ row_n = div_round_integer(base_height, height) - 1;
+ if (row_n > 0 && row_n <= 255) {
+ row_en = true;
+ row_mode = STK1160_DECIMATE_MORE_THAN_HALF;
+ f->fmt.pix.height = base_height / (row_n + 1);
+ }
+ }
f->fmt.pix.pixelformat = dev->fmt->fourcc;
- f->fmt.pix.width = dev->width;
- f->fmt.pix.height = dev->height;
f->fmt.pix.field = V4L2_FIELD_INTERLACED;
- f->fmt.pix.bytesperline = dev->width * 2;
- f->fmt.pix.sizeimage = dev->height * f->fmt.pix.bytesperline;
+ f->fmt.pix.bytesperline = f->fmt.pix.width * 2;
+ f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
+ if (ctrl) {
+ ctrl->col_en = col_en;
+ ctrl->col_n = col_n;
+ ctrl->col_mode = col_mode;
+ ctrl->row_en = row_en;
+ ctrl->row_n = row_n;
+ ctrl->row_mode = row_mode;
+ }
+
+ stk1160_dbg("width %d, height %d\n",
+ f->fmt.pix.width, f->fmt.pix.height);
return 0;
}
+static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
+ struct v4l2_format *f)
+{
+ struct stk1160 *dev = video_drvdata(file);
+
+ return stk1160_try_fmt(dev, f, NULL);
+}
+
static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_format *f)
{
struct stk1160 *dev = video_drvdata(file);
struct vb2_queue *q = &dev->vb_vidq;
+ struct stk1160_decimate_ctrl ctrl;
+ int rc;
if (vb2_is_busy(q))
return -EBUSY;
- vidioc_try_fmt_vid_cap(file, priv, f);
-
- /* We don't support any format changes */
+ rc = stk1160_try_fmt(dev, f, &ctrl);
+ if (rc < 0)
+ return rc;
+ dev->width = f->fmt.pix.width;
+ dev->height = f->fmt.pix.height;
+ stk1160_set_fmt(dev, &ctrl);
return 0;
}
@@ -391,22 +545,15 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id norm)
return -ENODEV;
/* We need to set this now, before we call stk1160_set_std */
+ dev->width = 720;
+ dev->height = (norm & V4L2_STD_525_60) ? 480 : 576;
dev->norm = norm;
- /* This is taken from saa7115 video decoder */
- if (dev->norm & V4L2_STD_525_60) {
- dev->width = 720;
- dev->height = 480;
- } else if (dev->norm & V4L2_STD_625_50) {
- dev->width = 720;
- dev->height = 576;
- } else {
- stk1160_err("invalid standard\n");
- return -EINVAL;
- }
-
stk1160_set_std(dev);
+ /* Calling with NULL disables frame decimation */
+ stk1160_set_fmt(dev, NULL);
+
v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_std,
dev->norm);
@@ -538,8 +685,8 @@ static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *v4l_fmt,
sizes[0] = size;
- stk1160_info("%s: buffer count %d, each %ld bytes\n",
- __func__, *nbuffers, size);
+ stk1160_dbg("%s: buffer count %d, each %ld bytes\n",
+ __func__, *nbuffers, size);
return 0;
}
@@ -623,8 +770,8 @@ void stk1160_clear_queue(struct stk1160 *dev)
struct stk1160_buffer, list);
list_del(&buf->list);
vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
- stk1160_info("buffer [%p/%d] aborted\n",
- buf, buf->vb.v4l2_buf.index);
+ stk1160_dbg("buffer [%p/%d] aborted\n",
+ buf, buf->vb.v4l2_buf.index);
}
/* It's important to release the current buffer */
@@ -633,8 +780,8 @@ void stk1160_clear_queue(struct stk1160 *dev)
dev->isoc_ctl.buf = NULL;
vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
- stk1160_info("buffer [%p/%d] aborted\n",
- buf, buf->vb.v4l2_buf.index);
+ stk1160_dbg("buffer [%p/%d] aborted\n",
+ buf, buf->vb.v4l2_buf.index);
}
spin_unlock_irqrestore(&dev->buf_lock, flags);
}
diff --git a/drivers/media/usb/stk1160/stk1160-video.c b/drivers/media/usb/stk1160/stk1160-video.c
index 39f1aae20..940c3eaea 100644
--- a/drivers/media/usb/stk1160/stk1160-video.c
+++ b/drivers/media/usb/stk1160/stk1160-video.c
@@ -96,9 +96,7 @@ void stk1160_buffer_done(struct stk1160 *dev)
{
struct stk1160_buffer *buf = dev->isoc_ctl.buf;
- dev->field_count++;
-
- buf->vb.v4l2_buf.sequence = dev->field_count >> 1;
+ buf->vb.v4l2_buf.sequence = dev->sequence++;
buf->vb.v4l2_buf.field = V4L2_FIELD_INTERLACED;
buf->vb.v4l2_buf.bytesused = buf->bytesused;
v4l2_get_timestamp(&buf->vb.v4l2_buf.timestamp);
diff --git a/drivers/media/usb/stk1160/stk1160.h b/drivers/media/usb/stk1160/stk1160.h
index abdea484c..72cc8e8cb 100644
--- a/drivers/media/usb/stk1160/stk1160.h
+++ b/drivers/media/usb/stk1160/stk1160.h
@@ -58,7 +58,6 @@
* new drivers should use.
*
*/
-#define DEBUG
#ifdef DEBUG
#define stk1160_dbg(fmt, args...) \
printk(KERN_DEBUG "stk1160: " fmt, ## args)
@@ -151,8 +150,7 @@ struct stk1160 {
v4l2_std_id norm; /* current norm */
struct stk1160_fmt *fmt; /* selected format */
- unsigned int field_count; /* not sure ??? */
- enum v4l2_field field; /* also not sure :/ */
+ unsigned int sequence;
/* i2c i/o */
struct i2c_adapter i2c_adap;
diff --git a/drivers/media/usb/ttusb-dec/ttusb_dec.c b/drivers/media/usb/ttusb-dec/ttusb_dec.c
index 0c9943661..a53e94dd2 100644
--- a/drivers/media/usb/ttusb-dec/ttusb_dec.c
+++ b/drivers/media/usb/ttusb-dec/ttusb_dec.c
@@ -593,14 +593,9 @@ static void ttusb_dec_process_packet(struct ttusb_dec *dec)
static void swap_bytes(u8 *b, int length)
{
- u8 c;
-
length -= length % 2;
- for (; length; b += 2, length -= 2) {
- c = *b;
- *b = *(b + 1);
- *(b + 1) = c;
- }
+ for (; length; b += 2, length -= 2)
+ swap(*b, *(b + 1));
}
static void ttusb_dec_process_urb_frame(struct ttusb_dec *dec, u8 *b,
diff --git a/drivers/media/usb/usbvision/usbvision-core.c b/drivers/media/usb/usbvision/usbvision-core.c
index 7c04ef697..dc3b4d515 100644
--- a/drivers/media/usb/usbvision/usbvision-core.c
+++ b/drivers/media/usb/usbvision/usbvision-core.c
@@ -1367,7 +1367,7 @@ static void usbvision_isoc_irq(struct urb *urb)
int usbvision_read_reg(struct usb_usbvision *usbvision, unsigned char reg)
{
int err_code = 0;
- unsigned char buffer[1];
+ unsigned char *buffer = usbvision->ctrl_urb_buffer;
if (!USBVISION_IS_OPERATIONAL(usbvision))
return -1;
@@ -1401,10 +1401,12 @@ int usbvision_write_reg(struct usb_usbvision *usbvision, unsigned char reg,
if (!USBVISION_IS_OPERATIONAL(usbvision))
return 0;
+ usbvision->ctrl_urb_buffer[0] = value;
err_code = usb_control_msg(usbvision->dev, usb_sndctrlpipe(usbvision->dev, 1),
USBVISION_OP_CODE,
USB_DIR_OUT | USB_TYPE_VENDOR |
- USB_RECIP_ENDPOINT, 0, (__u16) reg, &value, 1, HZ);
+ USB_RECIP_ENDPOINT, 0, (__u16) reg,
+ usbvision->ctrl_urb_buffer, 1, HZ);
if (err_code < 0) {
dev_err(&usbvision->dev->dev,
@@ -1596,7 +1598,7 @@ static int usbvision_init_webcam(struct usb_usbvision *usbvision)
{ 0x27, 0x00, 0x00 }, { 0x28, 0x00, 0x00 }, { 0x29, 0x00, 0x00 }, { 0x08, 0x80, 0x60 },
{ 0x0f, 0x2d, 0x24 }, { 0x0c, 0x80, 0x80 }
};
- char value[3];
+ unsigned char *value = usbvision->ctrl_urb_buffer;
/* the only difference between PAL and NTSC init_values */
if (usbvision_device_data[usbvision->dev_model].video_norm == V4L2_STD_NTSC)
@@ -1635,8 +1637,8 @@ static int usbvision_init_webcam(struct usb_usbvision *usbvision)
static int usbvision_set_video_format(struct usb_usbvision *usbvision, int format)
{
static const char proc[] = "usbvision_set_video_format";
+ unsigned char *value = usbvision->ctrl_urb_buffer;
int rc;
- unsigned char value[2];
if (!USBVISION_IS_OPERATIONAL(usbvision))
return 0;
@@ -1677,7 +1679,7 @@ int usbvision_set_output(struct usb_usbvision *usbvision, int width,
int err_code = 0;
int usb_width, usb_height;
unsigned int frame_rate = 0, frame_drop = 0;
- unsigned char value[4];
+ unsigned char *value = usbvision->ctrl_urb_buffer;
if (!USBVISION_IS_OPERATIONAL(usbvision))
return 0;
@@ -1789,10 +1791,6 @@ int usbvision_frames_alloc(struct usb_usbvision *usbvision, int number_of_frames
usbvision->num_frames--;
}
- spin_lock_init(&usbvision->queue_lock);
- init_waitqueue_head(&usbvision->wait_frame);
- init_waitqueue_head(&usbvision->wait_stream);
-
/* Allocate all buffers */
for (i = 0; i < usbvision->num_frames; i++) {
usbvision->frame[i].index = i;
@@ -1872,7 +1870,7 @@ static int usbvision_set_compress_params(struct usb_usbvision *usbvision)
{
static const char proc[] = "usbvision_set_compresion_params: ";
int rc;
- unsigned char value[6];
+ unsigned char *value = usbvision->ctrl_urb_buffer;
value[0] = 0x0F; /* Intra-Compression cycle */
value[1] = 0x01; /* Reg.45 one line per strip */
@@ -1946,7 +1944,7 @@ int usbvision_set_input(struct usb_usbvision *usbvision)
{
static const char proc[] = "usbvision_set_input: ";
int rc;
- unsigned char value[8];
+ unsigned char *value = usbvision->ctrl_urb_buffer;
unsigned char dvi_yuv_value;
if (!USBVISION_IS_OPERATIONAL(usbvision))
@@ -2062,8 +2060,8 @@ int usbvision_set_input(struct usb_usbvision *usbvision)
static int usbvision_set_dram_settings(struct usb_usbvision *usbvision)
{
+ unsigned char *value = usbvision->ctrl_urb_buffer;
int rc;
- unsigned char value[8];
if (usbvision->isoc_mode == ISOC_MODE_COMPRESS) {
value[0] = 0x42;
@@ -2161,55 +2159,6 @@ int usbvision_power_on(struct usb_usbvision *usbvision)
/*
- * usbvision timer stuff
- */
-
-/* to call usbvision_power_off from task queue */
-static void call_usbvision_power_off(struct work_struct *work)
-{
- struct usb_usbvision *usbvision = container_of(work, struct usb_usbvision, power_off_work);
-
- PDEBUG(DBG_FUNC, "");
- if (mutex_lock_interruptible(&usbvision->v4l2_lock))
- return;
-
- if (usbvision->user == 0) {
- usbvision_i2c_unregister(usbvision);
-
- usbvision_power_off(usbvision);
- usbvision->initialized = 0;
- }
- mutex_unlock(&usbvision->v4l2_lock);
-}
-
-static void usbvision_power_off_timer(unsigned long data)
-{
- struct usb_usbvision *usbvision = (void *)data;
-
- PDEBUG(DBG_FUNC, "");
- del_timer(&usbvision->power_off_timer);
- INIT_WORK(&usbvision->power_off_work, call_usbvision_power_off);
- (void) schedule_work(&usbvision->power_off_work);
-}
-
-void usbvision_init_power_off_timer(struct usb_usbvision *usbvision)
-{
- setup_timer(&usbvision->power_off_timer, usbvision_power_off_timer,
- (unsigned long)usbvision);
-}
-
-void usbvision_set_power_off_timer(struct usb_usbvision *usbvision)
-{
- mod_timer(&usbvision->power_off_timer, jiffies + USBVISION_POWEROFF_TIME);
-}
-
-void usbvision_reset_power_off_timer(struct usb_usbvision *usbvision)
-{
- if (timer_pending(&usbvision->power_off_timer))
- del_timer(&usbvision->power_off_timer);
-}
-
-/*
* usbvision_begin_streaming()
* Sure you have to put bit 7 to 0, if not incoming frames are droped, but no
* idea about the rest
diff --git a/drivers/media/usb/usbvision/usbvision-i2c.c b/drivers/media/usb/usbvision/usbvision-i2c.c
index 26dbcb114..120de2e02 100644
--- a/drivers/media/usb/usbvision/usbvision-i2c.c
+++ b/drivers/media/usb/usbvision/usbvision-i2c.c
@@ -343,7 +343,7 @@ static int usbvision_i2c_write_max4(struct usb_usbvision *usbvision,
{
int rc, retries;
int i;
- unsigned char value[6];
+ unsigned char *value = usbvision->ctrl_urb_buffer;
unsigned char ser_cont;
ser_cont = (len & 0x07) | 0x10;
diff --git a/drivers/media/usb/usbvision/usbvision-video.c b/drivers/media/usb/usbvision/usbvision-video.c
index 1c6d31f7c..b693206f6 100644
--- a/drivers/media/usb/usbvision/usbvision-video.c
+++ b/drivers/media/usb/usbvision/usbvision-video.c
@@ -62,6 +62,7 @@
#include <media/saa7115.h>
#include <media/v4l2-common.h>
#include <media/v4l2-ioctl.h>
+#include <media/v4l2-event.h>
#include <media/tuner.h>
#include <linux/workqueue.h>
@@ -122,8 +123,6 @@ static void usbvision_release(struct usb_usbvision *usbvision);
static int isoc_mode = ISOC_MODE_COMPRESS;
/* Set the default Debug Mode of the device driver */
static int video_debug;
-/* Set the default device to power on at startup */
-static int power_on_at_open = 1;
/* Sequential Number of Video Device */
static int video_nr = -1;
/* Sequential Number of Radio Device */
@@ -134,13 +133,11 @@ static int radio_nr = -1;
/* Showing parameters under SYSFS */
module_param(isoc_mode, int, 0444);
module_param(video_debug, int, 0444);
-module_param(power_on_at_open, int, 0444);
module_param(video_nr, int, 0444);
module_param(radio_nr, int, 0444);
MODULE_PARM_DESC(isoc_mode, " Set the default format for ISOC endpoint. Default: 0x60 (Compression On)");
MODULE_PARM_DESC(video_debug, " Set the default Debug Mode of the device driver. Default: 0 (Off)");
-MODULE_PARM_DESC(power_on_at_open, " Set the default device to power on when device is opened. Default: 1 (On)");
MODULE_PARM_DESC(video_nr, "Set video device number (/dev/videoX). Default: -1 (autodetect)");
MODULE_PARM_DESC(radio_nr, "Set radio device number (/dev/radioX). Default: -1 (autodetect)");
@@ -351,11 +348,14 @@ static int usbvision_v4l2_open(struct file *file)
if (mutex_lock_interruptible(&usbvision->v4l2_lock))
return -ERESTARTSYS;
- usbvision_reset_power_off_timer(usbvision);
- if (usbvision->user)
+ if (usbvision->user) {
err_code = -EBUSY;
- else {
+ } else {
+ err_code = v4l2_fh_open(file);
+ if (err_code)
+ goto unlock;
+
/* Allocate memory for the scratch ring buffer */
err_code = usbvision_scratch_alloc(usbvision);
if (isoc_mode == ISOC_MODE_COMPRESS) {
@@ -372,11 +372,6 @@ static int usbvision_v4l2_open(struct file *file)
/* If so far no errors then we shall start the camera */
if (!err_code) {
- if (usbvision->power == 0) {
- usbvision_power_on(usbvision);
- usbvision_i2c_register(usbvision);
- }
-
/* Send init sequence only once, it's large! */
if (!usbvision->initialized) {
int setup_ok = 0;
@@ -392,18 +387,14 @@ static int usbvision_v4l2_open(struct file *file)
err_code = usbvision_init_isoc(usbvision);
/* device must be initialized before isoc transfer */
usbvision_muxsel(usbvision, 0);
+
+ /* prepare queues */
+ usbvision_empty_framequeues(usbvision);
usbvision->user++;
- } else {
- if (power_on_at_open) {
- usbvision_i2c_unregister(usbvision);
- usbvision_power_off(usbvision);
- usbvision->initialized = 0;
- }
}
}
- /* prepare queues */
- usbvision_empty_framequeues(usbvision);
+unlock:
mutex_unlock(&usbvision->v4l2_lock);
PDEBUG(DBG_IO, "success");
@@ -435,23 +426,16 @@ static int usbvision_v4l2_close(struct file *file)
usbvision_scratch_free(usbvision);
usbvision->user--;
-
- if (power_on_at_open) {
- /* power off in a little while
- to avoid off/on every close/open short sequences */
- usbvision_set_power_off_timer(usbvision);
- usbvision->initialized = 0;
- }
+ mutex_unlock(&usbvision->v4l2_lock);
if (usbvision->remove_pending) {
printk(KERN_INFO "%s: Final disconnect\n", __func__);
usbvision_release(usbvision);
return 0;
}
- mutex_unlock(&usbvision->v4l2_lock);
PDEBUG(DBG_IO, "success");
- return 0;
+ return v4l2_fh_release(file);
}
@@ -503,18 +487,24 @@ static int vidioc_querycap(struct file *file, void *priv,
struct v4l2_capability *vc)
{
struct usb_usbvision *usbvision = video_drvdata(file);
+ struct video_device *vdev = video_devdata(file);
strlcpy(vc->driver, "USBVision", sizeof(vc->driver));
strlcpy(vc->card,
usbvision_device_data[usbvision->dev_model].model_string,
sizeof(vc->card));
usb_make_path(usbvision->dev, vc->bus_info, sizeof(vc->bus_info));
- vc->device_caps = V4L2_CAP_VIDEO_CAPTURE |
- V4L2_CAP_AUDIO |
- V4L2_CAP_READWRITE |
- V4L2_CAP_STREAMING |
- (usbvision->have_tuner ? V4L2_CAP_TUNER : 0);
- vc->capabilities = vc->device_caps | V4L2_CAP_DEVICE_CAPS;
+ vc->device_caps = usbvision->have_tuner ? V4L2_CAP_TUNER : 0;
+ if (vdev->vfl_type == VFL_TYPE_GRABBER)
+ vc->device_caps |= V4L2_CAP_VIDEO_CAPTURE |
+ V4L2_CAP_READWRITE | V4L2_CAP_STREAMING;
+ else
+ vc->device_caps |= V4L2_CAP_RADIO;
+
+ vc->capabilities = vc->device_caps | V4L2_CAP_VIDEO_CAPTURE |
+ V4L2_CAP_READWRITE | V4L2_CAP_STREAMING | V4L2_CAP_DEVICE_CAPS;
+ if (usbvision_device_data[usbvision->dev_model].radio)
+ vc->capabilities |= V4L2_CAP_RADIO;
return 0;
}
@@ -540,7 +530,6 @@ static int vidioc_enum_input(struct file *file, void *priv,
} else {
strcpy(vi->name, "Television");
vi->type = V4L2_INPUT_TYPE_TUNER;
- vi->audioset = 1;
vi->tuner = chan;
vi->std = USBVISION_NORMS;
}
@@ -551,7 +540,7 @@ static int vidioc_enum_input(struct file *file, void *priv,
strcpy(vi->name, "Green Video Input");
else
strcpy(vi->name, "Composite Video Input");
- vi->std = V4L2_STD_PAL;
+ vi->std = USBVISION_NORMS;
break;
case 2:
vi->type = V4L2_INPUT_TYPE_CAMERA;
@@ -559,12 +548,12 @@ static int vidioc_enum_input(struct file *file, void *priv,
strcpy(vi->name, "Yellow Video Input");
else
strcpy(vi->name, "S-Video Input");
- vi->std = V4L2_STD_PAL;
+ vi->std = USBVISION_NORMS;
break;
case 3:
vi->type = V4L2_INPUT_TYPE_CAMERA;
strcpy(vi->name, "Red Video Input");
- vi->std = V4L2_STD_PAL;
+ vi->std = USBVISION_NORMS;
break;
}
return 0;
@@ -619,14 +608,13 @@ static int vidioc_g_tuner(struct file *file, void *priv,
{
struct usb_usbvision *usbvision = video_drvdata(file);
- if (!usbvision->have_tuner || vt->index) /* Only tuner 0 */
+ if (vt->index) /* Only tuner 0 */
return -EINVAL;
- if (usbvision->radio) {
+ if (vt->type == V4L2_TUNER_RADIO)
strcpy(vt->name, "Radio");
- vt->type = V4L2_TUNER_RADIO;
- } else {
+ else
strcpy(vt->name, "Television");
- }
+
/* Let clients fill in the remainder of this struct */
call_all(usbvision, tuner, g_tuner, vt);
@@ -638,8 +626,8 @@ static int vidioc_s_tuner(struct file *file, void *priv,
{
struct usb_usbvision *usbvision = video_drvdata(file);
- /* Only no or one tuner for now */
- if (!usbvision->have_tuner || vt->index)
+ /* Only one tuner for now */
+ if (vt->index)
return -EINVAL;
/* let clients handle this */
call_all(usbvision, tuner, s_tuner, vt);
@@ -652,12 +640,13 @@ static int vidioc_g_frequency(struct file *file, void *priv,
{
struct usb_usbvision *usbvision = video_drvdata(file);
- freq->tuner = 0; /* Only one tuner */
- if (usbvision->radio)
- freq->type = V4L2_TUNER_RADIO;
+ /* Only one tuner */
+ if (freq->tuner)
+ return -EINVAL;
+ if (freq->type == V4L2_TUNER_RADIO)
+ freq->frequency = usbvision->radio_freq;
else
- freq->type = V4L2_TUNER_ANALOG_TV;
- freq->frequency = usbvision->freq;
+ freq->frequency = usbvision->tv_freq;
return 0;
}
@@ -666,65 +655,19 @@ static int vidioc_s_frequency(struct file *file, void *priv,
const struct v4l2_frequency *freq)
{
struct usb_usbvision *usbvision = video_drvdata(file);
+ struct v4l2_frequency new_freq = *freq;
- /* Only no or one tuner for now */
- if (!usbvision->have_tuner || freq->tuner)
+ /* Only one tuner for now */
+ if (freq->tuner)
return -EINVAL;
- usbvision->freq = freq->frequency;
call_all(usbvision, tuner, s_frequency, freq);
-
- return 0;
-}
-
-static int vidioc_g_audio(struct file *file, void *priv, struct v4l2_audio *a)
-{
- struct usb_usbvision *usbvision = video_drvdata(file);
-
- if (usbvision->radio)
- strcpy(a->name, "Radio");
+ call_all(usbvision, tuner, g_frequency, &new_freq);
+ if (freq->type == V4L2_TUNER_RADIO)
+ usbvision->radio_freq = new_freq.frequency;
else
- strcpy(a->name, "TV");
-
- return 0;
-}
+ usbvision->tv_freq = new_freq.frequency;
-static int vidioc_s_audio(struct file *file, void *fh,
- const struct v4l2_audio *a)
-{
- if (a->index)
- return -EINVAL;
- return 0;
-}
-
-static int vidioc_queryctrl(struct file *file, void *priv,
- struct v4l2_queryctrl *ctrl)
-{
- struct usb_usbvision *usbvision = video_drvdata(file);
-
- call_all(usbvision, core, queryctrl, ctrl);
-
- if (!ctrl->type)
- return -EINVAL;
-
- return 0;
-}
-
-static int vidioc_g_ctrl(struct file *file, void *priv,
- struct v4l2_control *ctrl)
-{
- struct usb_usbvision *usbvision = video_drvdata(file);
-
- call_all(usbvision, core, g_ctrl, ctrl);
- return 0;
-}
-
-static int vidioc_s_ctrl(struct file *file, void *priv,
- struct v4l2_control *ctrl)
-{
- struct usb_usbvision *usbvision = video_drvdata(file);
-
- call_all(usbvision, core, s_ctrl, ctrl);
return 0;
}
@@ -937,6 +880,8 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
vf->fmt.pix.bytesperline = vf->fmt.pix.width*
usbvision->palette.bytes_per_pixel;
vf->fmt.pix.sizeimage = vf->fmt.pix.bytesperline*vf->fmt.pix.height;
+ vf->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
+ vf->fmt.pix.field = V4L2_FIELD_NONE; /* Always progressive image */
return 0;
}
@@ -1167,20 +1112,15 @@ static int usbvision_radio_open(struct file *file)
if (mutex_lock_interruptible(&usbvision->v4l2_lock))
return -ERESTARTSYS;
+ err_code = v4l2_fh_open(file);
+ if (err_code)
+ goto out;
if (usbvision->user) {
dev_err(&usbvision->rdev.dev,
"%s: Someone tried to open an already opened USBVision Radio!\n",
__func__);
err_code = -EBUSY;
} else {
- if (power_on_at_open) {
- usbvision_reset_power_off_timer(usbvision);
- if (usbvision->power == 0) {
- usbvision_power_on(usbvision);
- usbvision_i2c_register(usbvision);
- }
- }
-
/* Alternate interface 1 is is the biggest frame size */
err_code = usbvision_set_alternate(usbvision);
if (err_code < 0) {
@@ -1195,14 +1135,6 @@ static int usbvision_radio_open(struct file *file)
usbvision_set_audio(usbvision, USBVISION_AUDIO_RADIO);
usbvision->user++;
}
-
- if (err_code) {
- if (power_on_at_open) {
- usbvision_i2c_unregister(usbvision);
- usbvision_power_off(usbvision);
- usbvision->initialized = 0;
- }
- }
out:
mutex_unlock(&usbvision->v4l2_lock);
return err_code;
@@ -1212,34 +1144,29 @@ out:
static int usbvision_radio_close(struct file *file)
{
struct usb_usbvision *usbvision = video_drvdata(file);
- int err_code = 0;
PDEBUG(DBG_IO, "");
mutex_lock(&usbvision->v4l2_lock);
/* Set packet size to 0 */
usbvision->iface_alt = 0;
- err_code = usb_set_interface(usbvision->dev, usbvision->iface,
+ usb_set_interface(usbvision->dev, usbvision->iface,
usbvision->iface_alt);
usbvision_audio_off(usbvision);
usbvision->radio = 0;
usbvision->user--;
- if (power_on_at_open) {
- usbvision_set_power_off_timer(usbvision);
- usbvision->initialized = 0;
- }
-
if (usbvision->remove_pending) {
printk(KERN_INFO "%s: Final disconnect\n", __func__);
+ v4l2_fh_release(file);
usbvision_release(usbvision);
- return err_code;
+ return 0;
}
mutex_unlock(&usbvision->v4l2_lock);
PDEBUG(DBG_IO, "success");
- return err_code;
+ return v4l2_fh_release(file);
}
/* Video registration stuff */
@@ -1252,7 +1179,6 @@ static const struct v4l2_file_operations usbvision_fops = {
.read = usbvision_v4l2_read,
.mmap = usbvision_v4l2_mmap,
.unlocked_ioctl = video_ioctl2,
-/* .poll = video_poll, */
};
static const struct v4l2_ioctl_ops usbvision_ioctl_ops = {
@@ -1270,17 +1196,15 @@ static const struct v4l2_ioctl_ops usbvision_ioctl_ops = {
.vidioc_enum_input = vidioc_enum_input,
.vidioc_g_input = vidioc_g_input,
.vidioc_s_input = vidioc_s_input,
- .vidioc_queryctrl = vidioc_queryctrl,
- .vidioc_g_audio = vidioc_g_audio,
- .vidioc_s_audio = vidioc_s_audio,
- .vidioc_g_ctrl = vidioc_g_ctrl,
- .vidioc_s_ctrl = vidioc_s_ctrl,
.vidioc_streamon = vidioc_streamon,
.vidioc_streamoff = vidioc_streamoff,
.vidioc_g_tuner = vidioc_g_tuner,
.vidioc_s_tuner = vidioc_s_tuner,
.vidioc_g_frequency = vidioc_g_frequency,
.vidioc_s_frequency = vidioc_s_frequency,
+ .vidioc_log_status = v4l2_ctrl_log_status,
+ .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
+ .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
#ifdef CONFIG_VIDEO_ADV_DEBUG
.vidioc_g_register = vidioc_g_register,
.vidioc_s_register = vidioc_s_register,
@@ -1301,23 +1225,19 @@ static const struct v4l2_file_operations usbvision_radio_fops = {
.owner = THIS_MODULE,
.open = usbvision_radio_open,
.release = usbvision_radio_close,
+ .poll = v4l2_ctrl_poll,
.unlocked_ioctl = video_ioctl2,
};
static const struct v4l2_ioctl_ops usbvision_radio_ioctl_ops = {
.vidioc_querycap = vidioc_querycap,
- .vidioc_enum_input = vidioc_enum_input,
- .vidioc_g_input = vidioc_g_input,
- .vidioc_s_input = vidioc_s_input,
- .vidioc_queryctrl = vidioc_queryctrl,
- .vidioc_g_audio = vidioc_g_audio,
- .vidioc_s_audio = vidioc_s_audio,
- .vidioc_g_ctrl = vidioc_g_ctrl,
- .vidioc_s_ctrl = vidioc_s_ctrl,
.vidioc_g_tuner = vidioc_g_tuner,
.vidioc_s_tuner = vidioc_s_tuner,
.vidioc_g_frequency = vidioc_g_frequency,
.vidioc_s_frequency = vidioc_s_frequency,
+ .vidioc_log_status = v4l2_ctrl_log_status,
+ .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
+ .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
};
static struct video_device usbvision_radio_template = {
@@ -1369,9 +1289,17 @@ static void usbvision_unregister_video(struct usb_usbvision *usbvision)
/* register video4linux devices */
static int usbvision_register_video(struct usb_usbvision *usbvision)
{
+ int res = -ENOMEM;
+
/* Video Device: */
usbvision_vdev_init(usbvision, &usbvision->vdev,
&usbvision_video_template, "USBVision Video");
+ if (!usbvision->have_tuner) {
+ v4l2_disable_ioctl(&usbvision->vdev, VIDIOC_G_FREQUENCY);
+ v4l2_disable_ioctl(&usbvision->vdev, VIDIOC_S_TUNER);
+ v4l2_disable_ioctl(&usbvision->vdev, VIDIOC_G_FREQUENCY);
+ v4l2_disable_ioctl(&usbvision->vdev, VIDIOC_S_TUNER);
+ }
if (video_register_device(&usbvision->vdev, VFL_TYPE_GRABBER, video_nr) < 0)
goto err_exit;
printk(KERN_INFO "USBVision[%d]: registered USBVision Video device %s [v4l2]\n",
@@ -1395,7 +1323,7 @@ static int usbvision_register_video(struct usb_usbvision *usbvision)
"USBVision[%d]: video_register_device() failed\n",
usbvision->nr);
usbvision_unregister_video(usbvision);
- return -1;
+ return res;
}
/*
@@ -1420,6 +1348,9 @@ static struct usb_usbvision *usbvision_alloc(struct usb_device *dev,
if (v4l2_device_register(&intf->dev, &usbvision->v4l2_dev))
goto err_free;
+ if (v4l2_ctrl_handler_init(&usbvision->hdl, 4))
+ goto err_unreg;
+ usbvision->v4l2_dev.ctrl_handler = &usbvision->hdl;
mutex_init(&usbvision->v4l2_lock);
/* prepare control urb for control messages during interrupts */
@@ -1428,11 +1359,10 @@ static struct usb_usbvision *usbvision_alloc(struct usb_device *dev,
goto err_unreg;
init_waitqueue_head(&usbvision->ctrl_urb_wq);
- usbvision_init_power_off_timer(usbvision);
-
return usbvision;
err_unreg:
+ v4l2_ctrl_handler_free(&usbvision->hdl);
v4l2_device_unregister(&usbvision->v4l2_dev);
err_free:
kfree(usbvision);
@@ -1450,8 +1380,6 @@ static void usbvision_release(struct usb_usbvision *usbvision)
{
PDEBUG(DBG_PROBE, "");
- usbvision_reset_power_off_timer(usbvision);
-
usbvision->initialized = 0;
usbvision_remove_sysfs(&usbvision->vdev);
@@ -1460,6 +1388,7 @@ static void usbvision_release(struct usb_usbvision *usbvision)
usb_free_urb(usbvision->ctrl_urb);
+ v4l2_ctrl_handler_free(&usbvision->hdl);
v4l2_device_unregister(&usbvision->v4l2_dev);
kfree(usbvision);
@@ -1487,19 +1416,18 @@ static void usbvision_configure_video(struct usb_usbvision *usbvision)
}
usbvision->tvnorm_id = usbvision_device_data[model].video_norm;
-
usbvision->video_inputs = usbvision_device_data[model].video_channels;
usbvision->ctl_input = 0;
+ usbvision->radio_freq = 87.5 * 16000;
+ usbvision->tv_freq = 400 * 16;
/* This should be here to make i2c clients to be able to register */
/* first switch off audio */
if (usbvision_device_data[model].audio_channels > 0)
usbvision_audio_off(usbvision);
- if (!power_on_at_open) {
- /* and then power up the noisy tuner */
- usbvision_power_on(usbvision);
- usbvision_i2c_register(usbvision);
- }
+ /* and then power up the tuner */
+ usbvision_power_on(usbvision);
+ usbvision_i2c_register(usbvision);
}
/*
@@ -1592,6 +1520,10 @@ static int usbvision_probe(struct usb_interface *intf,
usbvision->nr = usbvision_nr++;
+ spin_lock_init(&usbvision->queue_lock);
+ init_waitqueue_head(&usbvision->wait_frame);
+ init_waitqueue_head(&usbvision->wait_stream);
+
usbvision->have_tuner = usbvision_device_data[model].tuner;
if (usbvision->have_tuner)
usbvision->tuner_type = usbvision_device_data[model].tuner_type;
@@ -1646,11 +1578,7 @@ static void usbvision_disconnect(struct usb_interface *intf)
usbvision_stop_isoc(usbvision);
v4l2_device_disconnect(&usbvision->v4l2_dev);
-
- if (usbvision->power) {
- usbvision_i2c_unregister(usbvision);
- usbvision_power_off(usbvision);
- }
+ usbvision_i2c_unregister(usbvision);
usbvision->remove_pending = 1; /* Now all ISO data will be ignored */
usb_put_dev(usbvision->dev);
diff --git a/drivers/media/usb/usbvision/usbvision.h b/drivers/media/usb/usbvision/usbvision.h
index 140a1f675..4f2e4fde3 100644
--- a/drivers/media/usb/usbvision/usbvision.h
+++ b/drivers/media/usb/usbvision/usbvision.h
@@ -36,6 +36,7 @@
#include <linux/i2c.h>
#include <linux/mutex.h>
#include <media/v4l2-device.h>
+#include <media/v4l2-ctrls.h>
#include <media/tuner.h>
#include <linux/videodev2.h>
@@ -357,6 +358,7 @@ extern struct usb_device_id usbvision_table[];
struct usb_usbvision {
struct v4l2_device v4l2_dev;
+ struct v4l2_ctrl_handler hdl;
struct video_device vdev; /* Video Device */
struct video_device rdev; /* Radio Device */
@@ -376,7 +378,8 @@ struct usb_usbvision {
int bridge_type; /* NT1003, NT1004, NT1005 */
int radio;
int video_inputs; /* # of inputs */
- unsigned long freq;
+ unsigned long radio_freq;
+ unsigned long tv_freq;
int audio_mute;
int audio_channel;
int isoc_mode; /* format of video data for the usb isoc-transfer */
@@ -391,8 +394,6 @@ struct usb_usbvision {
unsigned char iface_alt; /* Alt settings */
unsigned char vin_reg2_preset;
struct mutex v4l2_lock;
- struct timer_list power_off_timer;
- struct work_struct power_off_work;
int power; /* is the device powered on? */
int user; /* user count for exclusive use */
int initialized; /* Had we already sent init sequence? */
@@ -510,9 +511,6 @@ int usbvision_muxsel(struct usb_usbvision *usbvision, int channel);
int usbvision_set_input(struct usb_usbvision *usbvision);
int usbvision_set_output(struct usb_usbvision *usbvision, int width, int height);
-void usbvision_init_power_off_timer(struct usb_usbvision *usbvision);
-void usbvision_set_power_off_timer(struct usb_usbvision *usbvision);
-void usbvision_reset_power_off_timer(struct usb_usbvision *usbvision);
int usbvision_power_off(struct usb_usbvision *usbvision);
int usbvision_power_on(struct usb_usbvision *usbvision);