summaryrefslogtreecommitdiff
path: root/drivers/media/usb
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/usb')
-rw-r--r--drivers/media/usb/au0828/au0828-dvb.c4
-rw-r--r--drivers/media/usb/au0828/au0828-video.c12
-rw-r--r--drivers/media/usb/cx231xx/cx231xx-417.c17
-rw-r--r--drivers/media/usb/cx231xx/cx231xx-pcb-cfg.h18
-rw-r--r--drivers/media/usb/dvb-usb-v2/af9015.c2
-rw-r--r--drivers/media/usb/dvb-usb-v2/af9035.c2
-rw-r--r--drivers/media/usb/dvb-usb-v2/anysee.c2
-rw-r--r--drivers/media/usb/dvb-usb-v2/au6610.c2
-rw-r--r--drivers/media/usb/dvb-usb-v2/az6007.c2
-rw-r--r--drivers/media/usb/dvb-usb-v2/ce6230.c2
-rw-r--r--drivers/media/usb/dvb-usb-v2/dvb_usb.h2
-rw-r--r--drivers/media/usb/dvb-usb-v2/dvbsky.c2
-rw-r--r--drivers/media/usb/dvb-usb-v2/ec168.c2
-rw-r--r--drivers/media/usb/dvb-usb-v2/gl861.c2
-rw-r--r--drivers/media/usb/dvb-usb-v2/lmedm04.c2
-rw-r--r--drivers/media/usb/dvb-usb-v2/mxl111sf.c2
-rw-r--r--drivers/media/usb/dvb-usb-v2/rtl28xxu.c2
-rw-r--r--drivers/media/usb/dvb-usb/a800.c2
-rw-r--r--drivers/media/usb/dvb-usb/af9005.c4
-rw-r--r--drivers/media/usb/dvb-usb/az6027.c4
-rw-r--r--drivers/media/usb/dvb-usb/cinergyT2-core.c2
-rw-r--r--drivers/media/usb/dvb-usb/cxusb-analog.c4
-rw-r--r--drivers/media/usb/dvb-usb/cxusb.c6
-rw-r--r--drivers/media/usb/dvb-usb/dibusb-mb.c2
-rw-r--r--drivers/media/usb/dvb-usb/dibusb-mc.c2
-rw-r--r--drivers/media/usb/dvb-usb/digitv.c4
-rw-r--r--drivers/media/usb/dvb-usb/dtt200u.c2
-rw-r--r--drivers/media/usb/dvb-usb/dtv5100.c4
-rw-r--r--drivers/media/usb/dvb-usb/dvb-usb.h6
-rw-r--r--drivers/media/usb/dvb-usb/dw2102.c16
-rw-r--r--drivers/media/usb/dvb-usb/gp8psk.c2
-rw-r--r--drivers/media/usb/dvb-usb/m920x.c4
-rw-r--r--drivers/media/usb/dvb-usb/nova-t-usb2.c2
-rw-r--r--drivers/media/usb/dvb-usb/opera1.c4
-rw-r--r--drivers/media/usb/dvb-usb/pctv452e.c6
-rw-r--r--drivers/media/usb/dvb-usb/technisat-usb2.c4
-rw-r--r--drivers/media/usb/dvb-usb/ttusb2.c4
-rw-r--r--drivers/media/usb/dvb-usb/umt-010.c2
-rw-r--r--drivers/media/usb/dvb-usb/vp702x.c2
-rw-r--r--drivers/media/usb/dvb-usb/vp7045.c2
-rw-r--r--drivers/media/usb/pvrusb2/pvrusb2-encoder.c2
-rw-r--r--drivers/media/usb/pvrusb2/pvrusb2-hdw.c16
-rw-r--r--drivers/media/usb/pvrusb2/pvrusb2-v4l2.c40
-rw-r--r--drivers/media/usb/pwc/pwc-if.c1
-rw-r--r--drivers/media/usb/uvc/uvc_ctrl.c799
-rw-r--r--drivers/media/usb/uvc/uvc_driver.c44
-rw-r--r--drivers/media/usb/uvc/uvc_v4l2.c74
-rw-r--r--drivers/media/usb/uvc/uvcvideo.h32
48 files changed, 766 insertions, 409 deletions
diff --git a/drivers/media/usb/au0828/au0828-dvb.c b/drivers/media/usb/au0828/au0828-dvb.c
index 09f9948c6f8e..3666f4452d11 100644
--- a/drivers/media/usb/au0828/au0828-dvb.c
+++ b/drivers/media/usb/au0828/au0828-dvb.c
@@ -143,7 +143,7 @@ static void urb_completion(struct urb *purb)
*/
dprintk(1, "%s cancelling bulk timeout\n", __func__);
dev->bulk_timeout_running = 0;
- del_timer(&dev->bulk_timeout);
+ timer_delete(&dev->bulk_timeout);
}
/* Feed the transport payload into the kernel demux */
@@ -168,7 +168,7 @@ static int stop_urb_transfer(struct au0828_dev *dev)
if (dev->bulk_timeout_running == 1) {
dev->bulk_timeout_running = 0;
- del_timer(&dev->bulk_timeout);
+ timer_delete(&dev->bulk_timeout);
}
dev->urb_streaming = false;
diff --git a/drivers/media/usb/au0828/au0828-video.c b/drivers/media/usb/au0828/au0828-video.c
index e9cd2a335f7f..33d1fad0f7b8 100644
--- a/drivers/media/usb/au0828/au0828-video.c
+++ b/drivers/media/usb/au0828/au0828-video.c
@@ -857,7 +857,7 @@ static void au0828_stop_streaming(struct vb2_queue *vq)
}
dev->vid_timeout_running = 0;
- del_timer_sync(&dev->vid_timeout);
+ timer_delete_sync(&dev->vid_timeout);
spin_lock_irqsave(&dev->slock, flags);
if (dev->isoc_ctl.buf != NULL) {
@@ -905,7 +905,7 @@ void au0828_stop_vbi_streaming(struct vb2_queue *vq)
spin_unlock_irqrestore(&dev->slock, flags);
dev->vbi_timeout_running = 0;
- del_timer_sync(&dev->vbi_timeout);
+ timer_delete_sync(&dev->vbi_timeout);
}
static const struct vb2_ops au0828_video_qops = {
@@ -1040,12 +1040,12 @@ static int au0828_v4l2_close(struct file *filp)
if (vdev->vfl_type == VFL_TYPE_VIDEO && dev->vid_timeout_running) {
/* Cancel timeout thread in case they didn't call streamoff */
dev->vid_timeout_running = 0;
- del_timer_sync(&dev->vid_timeout);
+ timer_delete_sync(&dev->vid_timeout);
} else if (vdev->vfl_type == VFL_TYPE_VBI &&
dev->vbi_timeout_running) {
/* Cancel timeout thread in case they didn't call streamoff */
dev->vbi_timeout_running = 0;
- del_timer_sync(&dev->vbi_timeout);
+ timer_delete_sync(&dev->vbi_timeout);
}
if (test_bit(DEV_DISCONNECTED, &dev->dev_state))
@@ -1694,9 +1694,9 @@ void au0828_v4l2_suspend(struct au0828_dev *dev)
}
if (dev->vid_timeout_running)
- del_timer_sync(&dev->vid_timeout);
+ timer_delete_sync(&dev->vid_timeout);
if (dev->vbi_timeout_running)
- del_timer_sync(&dev->vbi_timeout);
+ timer_delete_sync(&dev->vbi_timeout);
}
void au0828_v4l2_resume(struct au0828_dev *dev)
diff --git a/drivers/media/usb/cx231xx/cx231xx-417.c b/drivers/media/usb/cx231xx/cx231xx-417.c
index a4a9781328c5..e585c8f6e4c5 100644
--- a/drivers/media/usb/cx231xx/cx231xx-417.c
+++ b/drivers/media/usb/cx231xx/cx231xx-417.c
@@ -1538,20 +1538,6 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id id)
return 0;
}
-static int vidioc_s_ctrl(struct file *file, void *priv,
- struct v4l2_control *ctl)
-{
- struct cx231xx *dev = video_drvdata(file);
- struct v4l2_subdev *sd;
-
- dprintk(3, "enter vidioc_s_ctrl()\n");
- /* Update the A/V core */
- v4l2_device_for_each_subdev(sd, &dev->v4l2_dev)
- v4l2_s_ctrl(NULL, sd->ctrl_handler, ctl);
- dprintk(3, "exit vidioc_s_ctrl()\n");
- return 0;
-}
-
static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_fmtdesc *f)
{
@@ -1627,7 +1613,6 @@ static const struct v4l2_ioctl_ops mpeg_ioctl_ops = {
.vidioc_enum_input = cx231xx_enum_input,
.vidioc_g_input = cx231xx_g_input,
.vidioc_s_input = cx231xx_s_input,
- .vidioc_s_ctrl = vidioc_s_ctrl,
.vidioc_g_pixelaspect = vidioc_g_pixelaspect,
.vidioc_g_selection = vidioc_g_selection,
.vidioc_querycap = cx231xx_querycap,
@@ -1720,6 +1705,8 @@ static void cx231xx_video_dev_init(
vfd->lock = &dev->lock;
vfd->release = video_device_release_empty;
vfd->ctrl_handler = &dev->mpeg_ctrl_handler.hdl;
+ vfd->device_caps = V4L2_CAP_READWRITE | V4L2_CAP_STREAMING |
+ V4L2_CAP_VIDEO_CAPTURE;
video_set_drvdata(vfd, dev);
if (dev->tuner_type == TUNER_ABSENT) {
v4l2_disable_ioctl(vfd, VIDIOC_G_FREQUENCY);
diff --git a/drivers/media/usb/cx231xx/cx231xx-pcb-cfg.h b/drivers/media/usb/cx231xx/cx231xx-pcb-cfg.h
index 5bc44f194d0a..62ffa16bb82c 100644
--- a/drivers/media/usb/cx231xx/cx231xx-pcb-cfg.h
+++ b/drivers/media/usb/cx231xx/cx231xx-pcb-cfg.h
@@ -57,19 +57,17 @@ enum USB_SPEED{
};
#define TS_MASK 0x6
-enum TS_PORT{
- NO_TS_PORT = 0x0, /* 2'b00: Neither port used. PCB not a Hybrid,
+#define NO_TS_PORT 0x0 /* 2'b00: Neither port used. PCB not a Hybrid,
only offers Analog TV or Video */
- TS1_PORT = 0x4, /* 2'b10: TS1 Input (Hybrid mode :
+#define TS1_PORT 0x4 /* 2'b10: TS1 Input (Hybrid mode :
Digital or External Analog/Compressed source) */
- TS1_TS2_PORT = 0x6, /* 2'b11: TS1 & TS2 Inputs
+#define TS1_TS2_PORT 0x6 /* 2'b11: TS1 & TS2 Inputs
(Dual inputs from Digital and/or
External Analog/Compressed sources) */
- TS1_EXT_CLOCK = 0x6, /* 2'b11: TS1 & TS2 as selector
+#define TS1_EXT_CLOCK 0x6 /* 2'b11: TS1 & TS2 as selector
to external clock */
- TS1VIP_TS2_PORT = 0x2 /* 2'b01: TS1 used as 656/VIP Output,
+#define TS1VIP_TS2_PORT 0x2 /* 2'b01: TS1 used as 656/VIP Output,
TS2 Input (from Compressor) */
-};
#define EAVP_MASK 0x8
enum EAV_PRESENT{
@@ -89,10 +87,8 @@ enum AT_MODE{
};
#define PWR_SEL_MASK 0x40
-enum POWE_TYPE{
- SELF_POWER = 0x0, /* 0: self power */
- BUS_POWER = 0x40 /* 1: bus power */
-};
+#define SELF_POWER 0x0 /* 0: self power */
+#define BUS_POWER 0x40 /* 1: bus power */
enum USB_POWE_TYPE{
USB_SELF_POWER = 0,
diff --git a/drivers/media/usb/dvb-usb-v2/af9015.c b/drivers/media/usb/dvb-usb-v2/af9015.c
index 4014f7d07330..3eddc40377bf 100644
--- a/drivers/media/usb/dvb-usb-v2/af9015.c
+++ b/drivers/media/usb/dvb-usb-v2/af9015.c
@@ -260,7 +260,7 @@ static u32 af9015_i2c_func(struct i2c_adapter *adapter)
return I2C_FUNC_I2C;
}
-static struct i2c_algorithm af9015_i2c_algo = {
+static const struct i2c_algorithm af9015_i2c_algo = {
.master_xfer = af9015_i2c_xfer,
.functionality = af9015_i2c_func,
};
diff --git a/drivers/media/usb/dvb-usb-v2/af9035.c b/drivers/media/usb/dvb-usb-v2/af9035.c
index 218f712f56b1..17062672ea06 100644
--- a/drivers/media/usb/dvb-usb-v2/af9035.c
+++ b/drivers/media/usb/dvb-usb-v2/af9035.c
@@ -483,7 +483,7 @@ static u32 af9035_i2c_functionality(struct i2c_adapter *adapter)
return I2C_FUNC_I2C;
}
-static struct i2c_algorithm af9035_i2c_algo = {
+static const struct i2c_algorithm af9035_i2c_algo = {
.master_xfer = af9035_i2c_master_xfer,
.functionality = af9035_i2c_functionality,
};
diff --git a/drivers/media/usb/dvb-usb-v2/anysee.c b/drivers/media/usb/dvb-usb-v2/anysee.c
index bea12cdc85e8..64bddca5303c 100644
--- a/drivers/media/usb/dvb-usb-v2/anysee.c
+++ b/drivers/media/usb/dvb-usb-v2/anysee.c
@@ -235,7 +235,7 @@ static u32 anysee_i2c_func(struct i2c_adapter *adapter)
return I2C_FUNC_I2C;
}
-static struct i2c_algorithm anysee_i2c_algo = {
+static const struct i2c_algorithm anysee_i2c_algo = {
.master_xfer = anysee_master_xfer,
.functionality = anysee_i2c_func,
};
diff --git a/drivers/media/usb/dvb-usb-v2/au6610.c b/drivers/media/usb/dvb-usb-v2/au6610.c
index be223fc8aa14..c20a9469f564 100644
--- a/drivers/media/usb/dvb-usb-v2/au6610.c
+++ b/drivers/media/usb/dvb-usb-v2/au6610.c
@@ -115,7 +115,7 @@ static u32 au6610_i2c_func(struct i2c_adapter *adapter)
return I2C_FUNC_I2C;
}
-static struct i2c_algorithm au6610_i2c_algo = {
+static const struct i2c_algorithm au6610_i2c_algo = {
.master_xfer = au6610_i2c_xfer,
.functionality = au6610_i2c_func,
};
diff --git a/drivers/media/usb/dvb-usb-v2/az6007.c b/drivers/media/usb/dvb-usb-v2/az6007.c
index 2410054ddb2c..65ef045b74ca 100644
--- a/drivers/media/usb/dvb-usb-v2/az6007.c
+++ b/drivers/media/usb/dvb-usb-v2/az6007.c
@@ -838,7 +838,7 @@ static u32 az6007_i2c_func(struct i2c_adapter *adapter)
return I2C_FUNC_I2C;
}
-static struct i2c_algorithm az6007_i2c_algo = {
+static const struct i2c_algorithm az6007_i2c_algo = {
.master_xfer = az6007_i2c_xfer,
.functionality = az6007_i2c_func,
};
diff --git a/drivers/media/usb/dvb-usb-v2/ce6230.c b/drivers/media/usb/dvb-usb-v2/ce6230.c
index d3b5cb4a24da..7ebaf3ee4491 100644
--- a/drivers/media/usb/dvb-usb-v2/ce6230.c
+++ b/drivers/media/usb/dvb-usb-v2/ce6230.c
@@ -154,7 +154,7 @@ static u32 ce6230_i2c_functionality(struct i2c_adapter *adapter)
return I2C_FUNC_I2C;
}
-static struct i2c_algorithm ce6230_i2c_algorithm = {
+static const struct i2c_algorithm ce6230_i2c_algorithm = {
.master_xfer = ce6230_i2c_master_xfer,
.functionality = ce6230_i2c_functionality,
};
diff --git a/drivers/media/usb/dvb-usb-v2/dvb_usb.h b/drivers/media/usb/dvb-usb-v2/dvb_usb.h
index 288c15a7d72b..ecdc20d45132 100644
--- a/drivers/media/usb/dvb-usb-v2/dvb_usb.h
+++ b/drivers/media/usb/dvb-usb-v2/dvb_usb.h
@@ -243,7 +243,7 @@ struct dvb_usb_device_properties {
int (*download_firmware) (struct dvb_usb_device *,
const struct firmware *);
- struct i2c_algorithm *i2c_algo;
+ const struct i2c_algorithm *i2c_algo;
unsigned int num_adapters;
int (*get_adapter_count) (struct dvb_usb_device *);
diff --git a/drivers/media/usb/dvb-usb-v2/dvbsky.c b/drivers/media/usb/dvb-usb-v2/dvbsky.c
index 1221c924312a..ceac0ea21dab 100644
--- a/drivers/media/usb/dvb-usb-v2/dvbsky.c
+++ b/drivers/media/usb/dvb-usb-v2/dvbsky.c
@@ -169,7 +169,7 @@ static u32 dvbsky_i2c_func(struct i2c_adapter *adapter)
return I2C_FUNC_I2C;
}
-static struct i2c_algorithm dvbsky_i2c_algo = {
+static const struct i2c_algorithm dvbsky_i2c_algo = {
.master_xfer = dvbsky_i2c_xfer,
.functionality = dvbsky_i2c_func,
};
diff --git a/drivers/media/usb/dvb-usb-v2/ec168.c b/drivers/media/usb/dvb-usb-v2/ec168.c
index 0e4773fc025c..973b32356b17 100644
--- a/drivers/media/usb/dvb-usb-v2/ec168.c
+++ b/drivers/media/usb/dvb-usb-v2/ec168.c
@@ -176,7 +176,7 @@ static u32 ec168_i2c_func(struct i2c_adapter *adapter)
return I2C_FUNC_I2C;
}
-static struct i2c_algorithm ec168_i2c_algo = {
+static const struct i2c_algorithm ec168_i2c_algo = {
.master_xfer = ec168_i2c_xfer,
.functionality = ec168_i2c_func,
};
diff --git a/drivers/media/usb/dvb-usb-v2/gl861.c b/drivers/media/usb/dvb-usb-v2/gl861.c
index c71e7b93476d..0538170ccf29 100644
--- a/drivers/media/usb/dvb-usb-v2/gl861.c
+++ b/drivers/media/usb/dvb-usb-v2/gl861.c
@@ -162,7 +162,7 @@ static u32 gl861_i2c_functionality(struct i2c_adapter *adapter)
return I2C_FUNC_I2C;
}
-static struct i2c_algorithm gl861_i2c_algo = {
+static const struct i2c_algorithm gl861_i2c_algo = {
.master_xfer = gl861_i2c_master_xfer,
.functionality = gl861_i2c_functionality,
};
diff --git a/drivers/media/usb/dvb-usb-v2/lmedm04.c b/drivers/media/usb/dvb-usb-v2/lmedm04.c
index f0537b741d13..0c510035805b 100644
--- a/drivers/media/usb/dvb-usb-v2/lmedm04.c
+++ b/drivers/media/usb/dvb-usb-v2/lmedm04.c
@@ -559,7 +559,7 @@ static u32 lme2510_i2c_func(struct i2c_adapter *adapter)
return I2C_FUNC_I2C;
}
-static struct i2c_algorithm lme2510_i2c_algo = {
+static const struct i2c_algorithm lme2510_i2c_algo = {
.master_xfer = lme2510_i2c_xfer,
.functionality = lme2510_i2c_func,
};
diff --git a/drivers/media/usb/dvb-usb-v2/mxl111sf.c b/drivers/media/usb/dvb-usb-v2/mxl111sf.c
index cd5861a30b6f..870ac3c8b085 100644
--- a/drivers/media/usb/dvb-usb-v2/mxl111sf.c
+++ b/drivers/media/usb/dvb-usb-v2/mxl111sf.c
@@ -911,7 +911,7 @@ static u32 mxl111sf_i2c_func(struct i2c_adapter *adapter)
return I2C_FUNC_I2C;
}
-static struct i2c_algorithm mxl111sf_i2c_algo = {
+static const struct i2c_algorithm mxl111sf_i2c_algo = {
.master_xfer = mxl111sf_i2c_xfer,
.functionality = mxl111sf_i2c_func,
#ifdef NEED_ALGO_CONTROL
diff --git a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
index f7884bb56fcc..487c6ab784ab 100644
--- a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
+++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
@@ -290,7 +290,7 @@ static u32 rtl28xxu_i2c_func(struct i2c_adapter *adapter)
return I2C_FUNC_I2C;
}
-static struct i2c_algorithm rtl28xxu_i2c_algo = {
+static const struct i2c_algorithm rtl28xxu_i2c_algo = {
.master_xfer = rtl28xxu_i2c_xfer,
.functionality = rtl28xxu_i2c_func,
};
diff --git a/drivers/media/usb/dvb-usb/a800.c b/drivers/media/usb/dvb-usb/a800.c
index 5f294784923c..c5f95e48f1d5 100644
--- a/drivers/media/usb/dvb-usb/a800.c
+++ b/drivers/media/usb/dvb-usb/a800.c
@@ -77,7 +77,7 @@ enum {
AVERMEDIA_DVBT_USB2_WARM,
};
-static struct usb_device_id a800_table[] = {
+static const struct usb_device_id a800_table[] = {
DVB_USB_DEV(AVERMEDIA, AVERMEDIA_DVBT_USB2_COLD),
DVB_USB_DEV(AVERMEDIA, AVERMEDIA_DVBT_USB2_WARM),
{ }
diff --git a/drivers/media/usb/dvb-usb/af9005.c b/drivers/media/usb/dvb-usb/af9005.c
index 13604e6acdb8..a4bede7e8a1d 100644
--- a/drivers/media/usb/dvb-usb/af9005.c
+++ b/drivers/media/usb/dvb-usb/af9005.c
@@ -445,7 +445,7 @@ static u32 af9005_i2c_func(struct i2c_adapter *adapter)
return I2C_FUNC_I2C;
}
-static struct i2c_algorithm af9005_i2c_algo = {
+static const struct i2c_algorithm af9005_i2c_algo = {
.master_xfer = af9005_i2c_xfer,
.functionality = af9005_i2c_func,
};
@@ -1005,7 +1005,7 @@ enum {
ANSONIC_DVBT_USB,
};
-static struct usb_device_id af9005_usb_table[] = {
+static const struct usb_device_id af9005_usb_table[] = {
DVB_USB_DEV(AFATECH, AFATECH_AF9005),
DVB_USB_DEV(TERRATEC, TERRATEC_CINERGY_T_USB_XE),
DVB_USB_DEV(ANSONIC, ANSONIC_DVBT_USB),
diff --git a/drivers/media/usb/dvb-usb/az6027.c b/drivers/media/usb/dvb-usb/az6027.c
index 2bc27710427d..056935d3cbd6 100644
--- a/drivers/media/usb/dvb-usb/az6027.c
+++ b/drivers/media/usb/dvb-usb/az6027.c
@@ -1062,7 +1062,7 @@ static u32 az6027_i2c_func(struct i2c_adapter *adapter)
return I2C_FUNC_I2C;
}
-static struct i2c_algorithm az6027_i2c_algo = {
+static const struct i2c_algorithm az6027_i2c_algo = {
.master_xfer = az6027_i2c_xfer,
.functionality = az6027_i2c_func,
};
@@ -1107,7 +1107,7 @@ enum {
ELGATO_EYETV_SAT_V3,
};
-static struct usb_device_id az6027_usb_table[] = {
+static const struct usb_device_id az6027_usb_table[] = {
DVB_USB_DEV(AZUREWAVE, AZUREWAVE_AZ6027),
DVB_USB_DEV(TERRATEC, TERRATEC_DVBS2CI_V1),
DVB_USB_DEV(TERRATEC, TERRATEC_DVBS2CI_V2),
diff --git a/drivers/media/usb/dvb-usb/cinergyT2-core.c b/drivers/media/usb/dvb-usb/cinergyT2-core.c
index 4926c954e29a..d86c279e2dce 100644
--- a/drivers/media/usb/dvb-usb/cinergyT2-core.c
+++ b/drivers/media/usb/dvb-usb/cinergyT2-core.c
@@ -197,7 +197,7 @@ enum {
TERRATEC_CINERGY_T2,
};
-static struct usb_device_id cinergyt2_usb_table[] = {
+static const struct usb_device_id cinergyt2_usb_table[] = {
DVB_USB_DEV(TERRATEC, TERRATEC_CINERGY_T2),
{ }
};
diff --git a/drivers/media/usb/dvb-usb/cxusb-analog.c b/drivers/media/usb/dvb-usb/cxusb-analog.c
index 8253046cd6e6..3bbee1fcbc8d 100644
--- a/drivers/media/usb/dvb-usb/cxusb-analog.c
+++ b/drivers/media/usb/dvb-usb/cxusb-analog.c
@@ -817,8 +817,8 @@ static int cxusb_medion_v_start_streaming(struct vb2_queue *q,
* doing a large continuous allocation when (if)
* s-g isochronous USB transfers are supported
*/
- streambuf = kmalloc(npackets * CXUSB_VIDEO_PKT_SIZE,
- GFP_KERNEL);
+ streambuf = kmalloc_array(npackets, CXUSB_VIDEO_PKT_SIZE,
+ GFP_KERNEL);
if (!streambuf) {
if (i < 2) {
ret = -ENOMEM;
diff --git a/drivers/media/usb/dvb-usb/cxusb.c b/drivers/media/usb/dvb-usb/cxusb.c
index 1d98d3465e28..f44529b40989 100644
--- a/drivers/media/usb/dvb-usb/cxusb.c
+++ b/drivers/media/usb/dvb-usb/cxusb.c
@@ -78,7 +78,7 @@ enum cxusb_table_index {
NR__cxusb_table_index
};
-static struct usb_device_id cxusb_table[];
+static const struct usb_device_id cxusb_table[];
int cxusb_ctrl_msg(struct dvb_usb_device *d,
u8 cmd, const u8 *wbuf, int wlen, u8 *rbuf, int rlen)
@@ -287,7 +287,7 @@ static u32 cxusb_i2c_func(struct i2c_adapter *adapter)
return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
}
-static struct i2c_algorithm cxusb_i2c_algo = {
+static const struct i2c_algorithm cxusb_i2c_algo = {
.master_xfer = cxusb_i2c_xfer,
.functionality = cxusb_i2c_func,
};
@@ -1692,7 +1692,7 @@ static void cxusb_disconnect(struct usb_interface *intf)
dvb_usb_device_exit(intf);
}
-static struct usb_device_id cxusb_table[] = {
+static const struct usb_device_id cxusb_table[] = {
DVB_USB_DEV(MEDION, MEDION_MD95700),
DVB_USB_DEV(DVICO, DVICO_BLUEBIRD_LG064F_COLD),
DVB_USB_DEV(DVICO, DVICO_BLUEBIRD_LG064F_WARM),
diff --git a/drivers/media/usb/dvb-usb/dibusb-mb.c b/drivers/media/usb/dvb-usb/dibusb-mb.c
index 2cd88cab4c98..431766f19931 100644
--- a/drivers/media/usb/dvb-usb/dibusb-mb.c
+++ b/drivers/media/usb/dvb-usb/dibusb-mb.c
@@ -155,7 +155,7 @@ enum {
ULTIMA_TVBOX_ANCHOR_COLD,
};
-static struct usb_device_id dibusb_dib3000mb_table[] = {
+static const struct usb_device_id dibusb_dib3000mb_table[] = {
DVB_USB_DEV(WIDEVIEW, WIDEVIEW_DVBT_USB_COLD),
DVB_USB_DEV(WIDEVIEW, WIDEVIEW_DVBT_USB_WARM),
DVB_USB_DEV(COMPRO, COMPRO_DVBU2000_COLD),
diff --git a/drivers/media/usb/dvb-usb/dibusb-mc.c b/drivers/media/usb/dvb-usb/dibusb-mc.c
index 00cb016f6266..01eece2687d6 100644
--- a/drivers/media/usb/dvb-usb/dibusb-mc.c
+++ b/drivers/media/usb/dvb-usb/dibusb-mc.c
@@ -43,7 +43,7 @@ enum {
HUMAX_DVB_T_STICK_HIGH_SPEED_WARM,
};
-static struct usb_device_id dibusb_dib3000mc_table[] = {
+static const struct usb_device_id dibusb_dib3000mc_table[] = {
DVB_USB_DEV(DIBCOM, DIBCOM_MOD3001_COLD),
DVB_USB_DEV(DIBCOM, DIBCOM_MOD3001_WARM),
DVB_USB_DEV(ULTIMA_ELECTRONIC, ULTIMA_TVBOX_USB2_COLD),
diff --git a/drivers/media/usb/dvb-usb/digitv.c b/drivers/media/usb/dvb-usb/digitv.c
index 32134be16914..ab229ab1a858 100644
--- a/drivers/media/usb/dvb-usb/digitv.c
+++ b/drivers/media/usb/dvb-usb/digitv.c
@@ -88,7 +88,7 @@ static u32 digitv_i2c_func(struct i2c_adapter *adapter)
return I2C_FUNC_I2C;
}
-static struct i2c_algorithm digitv_i2c_algo = {
+static const struct i2c_algorithm digitv_i2c_algo = {
.master_xfer = digitv_i2c_xfer,
.functionality = digitv_i2c_func,
};
@@ -299,7 +299,7 @@ enum {
ANCHOR_NEBULA_DIGITV,
};
-static struct usb_device_id digitv_table[] = {
+static const struct usb_device_id digitv_table[] = {
DVB_USB_DEV(ANCHOR, ANCHOR_NEBULA_DIGITV),
{ }
};
diff --git a/drivers/media/usb/dvb-usb/dtt200u.c b/drivers/media/usb/dvb-usb/dtt200u.c
index e6ee56b3a9dd..83a69df384f2 100644
--- a/drivers/media/usb/dvb-usb/dtt200u.c
+++ b/drivers/media/usb/dvb-usb/dtt200u.c
@@ -171,7 +171,7 @@ enum {
MIGLIA_WT220U_ZAP250_COLD,
};
-static struct usb_device_id dtt200u_usb_table[] = {
+static const struct usb_device_id dtt200u_usb_table[] = {
DVB_USB_DEV(WIDEVIEW, WIDEVIEW_DTT200U_COLD),
DVB_USB_DEV(WIDEVIEW, WIDEVIEW_DTT200U_WARM),
DVB_USB_DEV(WIDEVIEW, WIDEVIEW_WT220U_COLD),
diff --git a/drivers/media/usb/dvb-usb/dtv5100.c b/drivers/media/usb/dvb-usb/dtv5100.c
index 56c9d521a34a..3d85c6f7f6ec 100644
--- a/drivers/media/usb/dvb-usb/dtv5100.c
+++ b/drivers/media/usb/dvb-usb/dtv5100.c
@@ -97,7 +97,7 @@ static u32 dtv5100_i2c_func(struct i2c_adapter *adapter)
return I2C_FUNC_I2C;
}
-static struct i2c_algorithm dtv5100_i2c_algo = {
+static const struct i2c_algorithm dtv5100_i2c_algo = {
.master_xfer = dtv5100_i2c_xfer,
.functionality = dtv5100_i2c_func,
};
@@ -166,7 +166,7 @@ enum {
AME_DTV5100,
};
-static struct usb_device_id dtv5100_table[] = {
+static const struct usb_device_id dtv5100_table[] = {
DVB_USB_DEV(AME, AME_DTV5100),
{ }
};
diff --git a/drivers/media/usb/dvb-usb/dvb-usb.h b/drivers/media/usb/dvb-usb/dvb-usb.h
index cbb0541d4dc1..550006a8d86f 100644
--- a/drivers/media/usb/dvb-usb/dvb-usb.h
+++ b/drivers/media/usb/dvb-usb/dvb-usb.h
@@ -73,8 +73,8 @@ struct dvb_usb_device_description {
const char *name;
#define DVB_USB_ID_MAX_NUM 15
- struct usb_device_id *cold_ids[DVB_USB_ID_MAX_NUM];
- struct usb_device_id *warm_ids[DVB_USB_ID_MAX_NUM];
+ const struct usb_device_id *cold_ids[DVB_USB_ID_MAX_NUM];
+ const struct usb_device_id *warm_ids[DVB_USB_ID_MAX_NUM];
};
static inline u8 rc5_custom(struct rc_map_table *key)
@@ -309,7 +309,7 @@ struct dvb_usb_device_properties {
struct dvb_rc core;
} rc;
- struct i2c_algorithm *i2c_algo;
+ const struct i2c_algorithm *i2c_algo;
int generic_bulk_ctrl_endpoint;
int generic_bulk_ctrl_endpoint_response;
diff --git a/drivers/media/usb/dvb-usb/dw2102.c b/drivers/media/usb/dvb-usb/dw2102.c
index 79e2ccf974c9..4fecf2f965e9 100644
--- a/drivers/media/usb/dvb-usb/dw2102.c
+++ b/drivers/media/usb/dvb-usb/dw2102.c
@@ -839,37 +839,37 @@ static u32 dw210x_i2c_func(struct i2c_adapter *adapter)
return I2C_FUNC_I2C;
}
-static struct i2c_algorithm dw2102_i2c_algo = {
+static const struct i2c_algorithm dw2102_i2c_algo = {
.master_xfer = dw2102_i2c_transfer,
.functionality = dw210x_i2c_func,
};
-static struct i2c_algorithm dw2102_serit_i2c_algo = {
+static const struct i2c_algorithm dw2102_serit_i2c_algo = {
.master_xfer = dw2102_serit_i2c_transfer,
.functionality = dw210x_i2c_func,
};
-static struct i2c_algorithm dw2102_earda_i2c_algo = {
+static const struct i2c_algorithm dw2102_earda_i2c_algo = {
.master_xfer = dw2102_earda_i2c_transfer,
.functionality = dw210x_i2c_func,
};
-static struct i2c_algorithm dw2104_i2c_algo = {
+static const struct i2c_algorithm dw2104_i2c_algo = {
.master_xfer = dw2104_i2c_transfer,
.functionality = dw210x_i2c_func,
};
-static struct i2c_algorithm dw3101_i2c_algo = {
+static const struct i2c_algorithm dw3101_i2c_algo = {
.master_xfer = dw3101_i2c_transfer,
.functionality = dw210x_i2c_func,
};
-static struct i2c_algorithm s6x0_i2c_algo = {
+static const struct i2c_algorithm s6x0_i2c_algo = {
.master_xfer = s6x0_i2c_transfer,
.functionality = dw210x_i2c_func,
};
-static struct i2c_algorithm su3000_i2c_algo = {
+static const struct i2c_algorithm su3000_i2c_algo = {
.master_xfer = su3000_i2c_transfer,
.functionality = dw210x_i2c_func,
};
@@ -1836,7 +1836,7 @@ enum dw2102_table_entry {
TEVII_S662
};
-static struct usb_device_id dw2102_table[] = {
+static const struct usb_device_id dw2102_table[] = {
DVB_USB_DEV(CYPRESS, CYPRESS_DW2102),
DVB_USB_DEV(CYPRESS, CYPRESS_DW2101),
DVB_USB_DEV(CYPRESS, CYPRESS_DW2104),
diff --git a/drivers/media/usb/dvb-usb/gp8psk.c b/drivers/media/usb/dvb-usb/gp8psk.c
index 4cd21bb8805e..96a255500b38 100644
--- a/drivers/media/usb/dvb-usb/gp8psk.c
+++ b/drivers/media/usb/dvb-usb/gp8psk.c
@@ -319,7 +319,7 @@ enum {
GENPIX_SKYWALKER_CW3K,
};
-static struct usb_device_id gp8psk_usb_table[] = {
+static const struct usb_device_id gp8psk_usb_table[] = {
DVB_USB_DEV(GENPIX, GENPIX_8PSK_REV_1_COLD),
DVB_USB_DEV(GENPIX, GENPIX_8PSK_REV_1_WARM),
DVB_USB_DEV(GENPIX, GENPIX_8PSK_REV_2),
diff --git a/drivers/media/usb/dvb-usb/m920x.c b/drivers/media/usb/dvb-usb/m920x.c
index a2054b1b100f..45337ba0a0a3 100644
--- a/drivers/media/usb/dvb-usb/m920x.c
+++ b/drivers/media/usb/dvb-usb/m920x.c
@@ -319,7 +319,7 @@ static u32 m920x_i2c_func(struct i2c_adapter *adapter)
return I2C_FUNC_I2C;
}
-static struct i2c_algorithm m920x_i2c_algo = {
+static const struct i2c_algorithm m920x_i2c_algo = {
.master_xfer = m920x_i2c_xfer,
.functionality = m920x_i2c_func,
};
@@ -909,7 +909,7 @@ enum {
AZUREWAVE_TWINHAN_VP7049,
};
-static struct usb_device_id m920x_table[] = {
+static const struct usb_device_id m920x_table[] = {
DVB_USB_DEV(MSI, MSI_MEGASKY580),
DVB_USB_DEV(ANUBIS_ELECTRONIC, ANUBIS_MSI_DIGI_VOX_MINI_II),
DVB_USB_DEV(ANUBIS_ELECTRONIC, ANUBIS_LIFEVIEW_TV_WALKER_TWIN_COLD),
diff --git a/drivers/media/usb/dvb-usb/nova-t-usb2.c b/drivers/media/usb/dvb-usb/nova-t-usb2.c
index 4782d0780913..2e5cbfacbeed 100644
--- a/drivers/media/usb/dvb-usb/nova-t-usb2.c
+++ b/drivers/media/usb/dvb-usb/nova-t-usb2.c
@@ -165,7 +165,7 @@ enum {
HAUPPAUGE_WINTV_NOVA_T_USB2_WARM,
};
-static struct usb_device_id nova_t_table[] = {
+static const struct usb_device_id nova_t_table[] = {
DVB_USB_DEV(HAUPPAUGE, HAUPPAUGE_WINTV_NOVA_T_USB2_COLD),
DVB_USB_DEV(HAUPPAUGE, HAUPPAUGE_WINTV_NOVA_T_USB2_WARM),
{ }
diff --git a/drivers/media/usb/dvb-usb/opera1.c b/drivers/media/usb/dvb-usb/opera1.c
index 268f05fc8691..3c79cc6848b4 100644
--- a/drivers/media/usb/dvb-usb/opera1.c
+++ b/drivers/media/usb/dvb-usb/opera1.c
@@ -155,7 +155,7 @@ static u32 opera1_i2c_func(struct i2c_adapter *adapter)
return I2C_FUNC_I2C;
}
-static struct i2c_algorithm opera1_i2c_algo = {
+static const struct i2c_algorithm opera1_i2c_algo = {
.master_xfer = opera1_i2c_xfer,
.functionality = opera1_i2c_func,
};
@@ -425,7 +425,7 @@ enum {
OPERA1_WARM,
};
-static struct usb_device_id opera1_table[] = {
+static const struct usb_device_id opera1_table[] = {
DVB_USB_DEV(CYPRESS, CYPRESS_OPERA1_COLD),
DVB_USB_DEV(OPERA1, OPERA1_WARM),
{ }
diff --git a/drivers/media/usb/dvb-usb/pctv452e.c b/drivers/media/usb/dvb-usb/pctv452e.c
index 2aab49003493..5094de9a312e 100644
--- a/drivers/media/usb/dvb-usb/pctv452e.c
+++ b/drivers/media/usb/dvb-usb/pctv452e.c
@@ -906,14 +906,14 @@ static struct stb6100_config stb6100_config = {
};
-static struct i2c_algorithm pctv452e_i2c_algo = {
+static const struct i2c_algorithm pctv452e_i2c_algo = {
.master_xfer = pctv452e_i2c_xfer,
.functionality = pctv452e_i2c_func
};
static int pctv452e_frontend_attach(struct dvb_usb_adapter *a)
{
- struct usb_device_id *id;
+ const struct usb_device_id *id;
a->fe_adap[0].fe = dvb_attach(stb0899_attach, &stb0899_config,
&a->dev->i2c_adap);
@@ -959,7 +959,7 @@ enum {
TECHNOTREND_CONNECT_S2_3650_CI,
};
-static struct usb_device_id pctv452e_usb_table[] = {
+static const struct usb_device_id pctv452e_usb_table[] = {
DVB_USB_DEV(PINNACLE, PINNACLE_PCTV_452E),
DVB_USB_DEV(TECHNOTREND, TECHNOTREND_CONNECT_S2_3600),
DVB_USB_DEV(TECHNOTREND, TECHNOTREND_CONNECT_S2_3650_CI),
diff --git a/drivers/media/usb/dvb-usb/technisat-usb2.c b/drivers/media/usb/dvb-usb/technisat-usb2.c
index df90c6c5f3b9..1e43aab2bc27 100644
--- a/drivers/media/usb/dvb-usb/technisat-usb2.c
+++ b/drivers/media/usb/dvb-usb/technisat-usb2.c
@@ -199,7 +199,7 @@ static u32 technisat_usb2_i2c_func(struct i2c_adapter *adapter)
return I2C_FUNC_I2C;
}
-static struct i2c_algorithm technisat_usb2_i2c_algo = {
+static const struct i2c_algorithm technisat_usb2_i2c_algo = {
.master_xfer = technisat_usb2_i2c_xfer,
.functionality = technisat_usb2_i2c_func,
};
@@ -693,7 +693,7 @@ enum {
TECHNISAT_USB2_DVB_S2,
};
-static struct usb_device_id technisat_usb2_id_table[] = {
+static const struct usb_device_id technisat_usb2_id_table[] = {
DVB_USB_DEV(TECHNISAT, TECHNISAT_USB2_DVB_S2),
{ }
};
diff --git a/drivers/media/usb/dvb-usb/ttusb2.c b/drivers/media/usb/dvb-usb/ttusb2.c
index 373ffa7f641e..acde6149d278 100644
--- a/drivers/media/usb/dvb-usb/ttusb2.c
+++ b/drivers/media/usb/dvb-usb/ttusb2.c
@@ -434,7 +434,7 @@ static u32 ttusb2_i2c_func(struct i2c_adapter *adapter)
return I2C_FUNC_I2C;
}
-static struct i2c_algorithm ttusb2_i2c_algo = {
+static const struct i2c_algorithm ttusb2_i2c_algo = {
.master_xfer = ttusb2_i2c_xfer,
.functionality = ttusb2_i2c_func,
};
@@ -638,7 +638,7 @@ enum {
TECHNOTREND_CONNECT_S2400_8KEEPROM,
};
-static struct usb_device_id ttusb2_table[] = {
+static const struct usb_device_id ttusb2_table[] = {
DVB_USB_DEV(PINNACLE, PINNACLE_PCTV_400E),
DVB_USB_DEV(PINNACLE, PINNACLE_PCTV_450E),
DVB_USB_DEV(TECHNOTREND, TECHNOTREND_CONNECT_S2400),
diff --git a/drivers/media/usb/dvb-usb/umt-010.c b/drivers/media/usb/dvb-usb/umt-010.c
index 464699b0b75b..8f23f92946d4 100644
--- a/drivers/media/usb/dvb-usb/umt-010.c
+++ b/drivers/media/usb/dvb-usb/umt-010.c
@@ -86,7 +86,7 @@ enum {
HANFTEK_UMT_010_WARM,
};
-static struct usb_device_id umt_table[] = {
+static const struct usb_device_id umt_table[] = {
DVB_USB_DEV(HANFTEK, HANFTEK_UMT_010_COLD),
DVB_USB_DEV(HANFTEK, HANFTEK_UMT_010_WARM),
{ }
diff --git a/drivers/media/usb/dvb-usb/vp702x.c b/drivers/media/usb/dvb-usb/vp702x.c
index 5b6740cbd1d1..034b0652b9a1 100644
--- a/drivers/media/usb/dvb-usb/vp702x.c
+++ b/drivers/media/usb/dvb-usb/vp702x.c
@@ -375,7 +375,7 @@ enum {
VISIONPLUS_VP7020_WARM,
};
-static struct usb_device_id vp702x_usb_table[] = {
+static const struct usb_device_id vp702x_usb_table[] = {
DVB_USB_DEV(VISIONPLUS, VISIONPLUS_VP7021_COLD),
// DVB_USB_DEV(VISIONPLUS, VISIONPLUS_VP7020_COLD),
// DVB_USB_DEV(VISIONPLUS, VISIONPLUS_VP7020_WARM),
diff --git a/drivers/media/usb/dvb-usb/vp7045.c b/drivers/media/usb/dvb-usb/vp7045.c
index 1dc2b18d44d8..5224c3233f8c 100644
--- a/drivers/media/usb/dvb-usb/vp7045.c
+++ b/drivers/media/usb/dvb-usb/vp7045.c
@@ -179,7 +179,7 @@ enum {
VISIONPLUS_TINYUSB2_WARM,
};
-static struct usb_device_id vp7045_usb_table[] = {
+static const struct usb_device_id vp7045_usb_table[] = {
DVB_USB_DEV(VISIONPLUS, VISIONPLUS_VP7045_COLD),
DVB_USB_DEV(VISIONPLUS, VISIONPLUS_VP7045_WARM),
DVB_USB_DEV(VISIONPLUS, VISIONPLUS_TINYUSB2_COLD),
diff --git a/drivers/media/usb/pvrusb2/pvrusb2-encoder.c b/drivers/media/usb/pvrusb2/pvrusb2-encoder.c
index c8102772344b..a5eabac1ec6e 100644
--- a/drivers/media/usb/pvrusb2/pvrusb2-encoder.c
+++ b/drivers/media/usb/pvrusb2/pvrusb2-encoder.c
@@ -257,7 +257,7 @@ rdData[0]);
ret = -EBUSY;
}
if (ret) {
- del_timer_sync(&hdw->encoder_run_timer);
+ timer_delete_sync(&hdw->encoder_run_timer);
hdw->state_encoder_ok = 0;
pvr2_trace(PVR2_TRACE_STBITS,
"State bit %s <-- %s",
diff --git a/drivers/media/usb/pvrusb2/pvrusb2-hdw.c b/drivers/media/usb/pvrusb2/pvrusb2-hdw.c
index 29cc207194b9..9a583eeaa329 100644
--- a/drivers/media/usb/pvrusb2/pvrusb2-hdw.c
+++ b/drivers/media/usb/pvrusb2/pvrusb2-hdw.c
@@ -1527,7 +1527,7 @@ int pvr2_upload_firmware2(struct pvr2_hdw *hdw)
/* Encoder is about to be reset so note that as far as we're
concerned now, the encoder has never been run. */
- del_timer_sync(&hdw->encoder_run_timer);
+ timer_delete_sync(&hdw->encoder_run_timer);
if (hdw->state_encoder_runok) {
hdw->state_encoder_runok = 0;
trace_stbit("state_encoder_runok",hdw->state_encoder_runok);
@@ -3724,7 +3724,7 @@ status);
hdw->cmd_debug_state = 5;
/* Stop timer */
- del_timer_sync(&timer.timer);
+ timer_delete_sync(&timer.timer);
hdw->cmd_debug_state = 6;
status = 0;
@@ -4248,7 +4248,7 @@ static int state_eval_encoder_config(struct pvr2_hdw *hdw)
hdw->state_encoder_waitok = 0;
trace_stbit("state_encoder_waitok",hdw->state_encoder_waitok);
/* paranoia - solve race if timer just completed */
- del_timer_sync(&hdw->encoder_wait_timer);
+ timer_delete_sync(&hdw->encoder_wait_timer);
} else {
if (!hdw->state_pathway_ok ||
(hdw->pathway_state != PVR2_PATHWAY_ANALOG) ||
@@ -4261,7 +4261,7 @@ static int state_eval_encoder_config(struct pvr2_hdw *hdw)
anything has happened that might have disturbed
the encoder. This should be a rare case. */
if (timer_pending(&hdw->encoder_wait_timer)) {
- del_timer_sync(&hdw->encoder_wait_timer);
+ timer_delete_sync(&hdw->encoder_wait_timer);
}
if (hdw->state_encoder_waitok) {
/* Must clear the state - therefore we did
@@ -4399,7 +4399,7 @@ static int state_eval_encoder_run(struct pvr2_hdw *hdw)
if (hdw->state_encoder_run) {
if (!state_check_disable_encoder_run(hdw)) return 0;
if (hdw->state_encoder_ok) {
- del_timer_sync(&hdw->encoder_run_timer);
+ timer_delete_sync(&hdw->encoder_run_timer);
if (pvr2_encoder_stop(hdw) < 0) return !0;
}
hdw->state_encoder_run = 0;
@@ -4479,11 +4479,11 @@ static int state_eval_decoder_run(struct pvr2_hdw *hdw)
hdw->state_decoder_quiescent = 0;
hdw->state_decoder_run = 0;
/* paranoia - solve race if timer(s) just completed */
- del_timer_sync(&hdw->quiescent_timer);
+ timer_delete_sync(&hdw->quiescent_timer);
/* Kill the stabilization timer, in case we're killing the
encoder before the previous stabilization interval has
been properly timed. */
- del_timer_sync(&hdw->decoder_stabilization_timer);
+ timer_delete_sync(&hdw->decoder_stabilization_timer);
hdw->state_decoder_ready = 0;
} else {
if (!hdw->state_decoder_quiescent) {
@@ -4517,7 +4517,7 @@ static int state_eval_decoder_run(struct pvr2_hdw *hdw)
!hdw->state_pipeline_config ||
!hdw->state_encoder_config ||
!hdw->state_encoder_ok) return 0;
- del_timer_sync(&hdw->quiescent_timer);
+ timer_delete_sync(&hdw->quiescent_timer);
if (hdw->flag_decoder_missed) return 0;
if (pvr2_decoder_enable(hdw,!0) < 0) return 0;
hdw->state_decoder_quiescent = 0;
diff --git a/drivers/media/usb/pvrusb2/pvrusb2-v4l2.c b/drivers/media/usb/pvrusb2/pvrusb2-v4l2.c
index d608b793fa84..ad38e1240541 100644
--- a/drivers/media/usb/pvrusb2/pvrusb2-v4l2.c
+++ b/drivers/media/usb/pvrusb2/pvrusb2-v4l2.c
@@ -497,8 +497,8 @@ static int pvr2_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
return pvr2_hdw_set_streaming(hdw, 0);
}
-static int pvr2_queryctrl(struct file *file, void *priv,
- struct v4l2_queryctrl *vc)
+static int pvr2_query_ext_ctrl(struct file *file, void *priv,
+ struct v4l2_query_ext_ctrl *vc)
{
struct pvr2_v4l2_fh *fh = file->private_data;
struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
@@ -521,13 +521,16 @@ static int pvr2_queryctrl(struct file *file, void *priv,
}
pvr2_trace(PVR2_TRACE_V4LIOCTL,
- "QUERYCTRL id=0x%x mapping name=%s (%s)",
+ "QUERYEXTCTRL id=0x%x mapping name=%s (%s)",
vc->id, pvr2_ctrl_get_name(cptr),
pvr2_ctrl_get_desc(cptr));
strscpy(vc->name, pvr2_ctrl_get_desc(cptr), sizeof(vc->name));
vc->flags = pvr2_ctrl_get_v4lflags(cptr);
pvr2_ctrl_get_def(cptr, &val);
vc->default_value = val;
+ vc->nr_of_dims = 0;
+ vc->elems = 1;
+ vc->elem_size = 4;
switch (pvr2_ctrl_get_type(cptr)) {
case pvr2_ctl_enum:
vc->type = V4L2_CTRL_TYPE_MENU;
@@ -549,7 +552,7 @@ static int pvr2_queryctrl(struct file *file, void *priv,
break;
default:
pvr2_trace(PVR2_TRACE_V4LIOCTL,
- "QUERYCTRL id=0x%x name=%s not mappable",
+ "QUERYEXTCTRL id=0x%x name=%s not mappable",
vc->id, pvr2_ctrl_get_name(cptr));
return -EINVAL;
}
@@ -571,31 +574,6 @@ static int pvr2_querymenu(struct file *file, void *priv, struct v4l2_querymenu *
return ret;
}
-static int pvr2_g_ctrl(struct file *file, void *priv, struct v4l2_control *vc)
-{
- struct pvr2_v4l2_fh *fh = file->private_data;
- struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
- int val = 0;
- int ret;
-
- ret = pvr2_ctrl_get_value(pvr2_hdw_get_ctrl_v4l(hdw, vc->id),
- &val);
- vc->value = val;
- return ret;
-}
-
-static int pvr2_s_ctrl(struct file *file, void *priv, struct v4l2_control *vc)
-{
- struct pvr2_v4l2_fh *fh = file->private_data;
- struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
- int ret;
-
- ret = pvr2_ctrl_set_value(pvr2_hdw_get_ctrl_v4l(hdw, vc->id),
- vc->value);
- pvr2_hdw_commit_ctl(hdw);
- return ret;
-}
-
static int pvr2_g_ext_ctrls(struct file *file, void *priv,
struct v4l2_ext_controls *ctls)
{
@@ -812,10 +790,8 @@ static const struct v4l2_ioctl_ops pvr2_ioctl_ops = {
.vidioc_try_fmt_vid_cap = pvr2_try_fmt_vid_cap,
.vidioc_streamon = pvr2_streamon,
.vidioc_streamoff = pvr2_streamoff,
- .vidioc_queryctrl = pvr2_queryctrl,
+ .vidioc_query_ext_ctrl = pvr2_query_ext_ctrl,
.vidioc_querymenu = pvr2_querymenu,
- .vidioc_g_ctrl = pvr2_g_ctrl,
- .vidioc_s_ctrl = pvr2_s_ctrl,
.vidioc_g_ext_ctrls = pvr2_g_ext_ctrls,
.vidioc_s_ext_ctrls = pvr2_s_ext_ctrls,
.vidioc_try_ext_ctrls = pvr2_try_ext_ctrls,
diff --git a/drivers/media/usb/pwc/pwc-if.c b/drivers/media/usb/pwc/pwc-if.c
index 3ec9eb5956ed..c6e5d031f068 100644
--- a/drivers/media/usb/pwc/pwc-if.c
+++ b/drivers/media/usb/pwc/pwc-if.c
@@ -56,7 +56,6 @@
#endif
#include <linux/vmalloc.h>
#include <asm/io.h>
-#include <linux/kernel.h> /* simple_strtol() */
#include "pwc.h"
#include "pwc-kiara.h"
diff --git a/drivers/media/usb/uvc/uvc_ctrl.c b/drivers/media/usb/uvc/uvc_ctrl.c
index 4e58476d305e..cbf19aa1d823 100644
--- a/drivers/media/usb/uvc/uvc_ctrl.c
+++ b/drivers/media/usb/uvc/uvc_ctrl.c
@@ -358,6 +358,24 @@ static const struct uvc_control_info uvc_ctrls[] = {
.flags = UVC_CTRL_FLAG_GET_CUR
| UVC_CTRL_FLAG_AUTO_UPDATE,
},
+ /*
+ * UVC_CTRL_FLAG_AUTO_UPDATE is needed because the RoI may get updated
+ * by sensors.
+ * "This RoI should be the same as specified in most recent SET_CUR
+ * except in the case where the ‘Auto Detect and Track’ and/or
+ * ‘Image Stabilization’ bit have been set."
+ * 4.2.2.1.20 Digital Region of Interest (ROI) Control
+ */
+ {
+ .entity = UVC_GUID_UVC_CAMERA,
+ .selector = UVC_CT_REGION_OF_INTEREST_CONTROL,
+ .index = 21,
+ .size = 10,
+ .flags = UVC_CTRL_FLAG_SET_CUR | UVC_CTRL_FLAG_GET_CUR
+ | UVC_CTRL_FLAG_GET_MIN | UVC_CTRL_FLAG_GET_MAX
+ | UVC_CTRL_FLAG_GET_DEF
+ | UVC_CTRL_FLAG_AUTO_UPDATE,
+ },
};
static const u32 uvc_control_classes[] = {
@@ -367,6 +385,27 @@ static const u32 uvc_control_classes[] = {
static const int exposure_auto_mapping[] = { 2, 1, 4, 8 };
+static bool uvc_ctrl_mapping_is_compound(struct uvc_control_mapping *mapping)
+{
+ return mapping->v4l2_type >= V4L2_CTRL_COMPOUND_TYPES;
+}
+
+static s32 uvc_mapping_get_s32(struct uvc_control_mapping *mapping,
+ u8 query, const void *data_in)
+{
+ s32 data_out = 0;
+
+ mapping->get(mapping, query, data_in, sizeof(data_out), &data_out);
+
+ return data_out;
+}
+
+static void uvc_mapping_set_s32(struct uvc_control_mapping *mapping,
+ s32 data_in, void *data_out)
+{
+ mapping->set(mapping, sizeof(data_in), &data_in, data_out);
+}
+
/*
* This function translates the V4L2 menu index @idx, as exposed to userspace as
* the V4L2 control value, to the corresponding UVC control value used by the
@@ -405,58 +444,93 @@ uvc_mapping_get_menu_name(const struct uvc_control_mapping *mapping, u32 idx)
return v4l2_ctrl_get_menu(mapping->id)[idx];
}
-static s32 uvc_ctrl_get_zoom(struct uvc_control_mapping *mapping,
- u8 query, const u8 *data)
+static int uvc_ctrl_get_zoom(struct uvc_control_mapping *mapping, u8 query,
+ const void *uvc_in, size_t v4l2_size,
+ void *v4l2_out)
{
- s8 zoom = (s8)data[0];
+ u8 value = ((u8 *)uvc_in)[2];
+ s8 sign = ((s8 *)uvc_in)[0];
+ s32 *out = v4l2_out;
+
+ if (WARN_ON(v4l2_size != sizeof(s32)))
+ return -EINVAL;
switch (query) {
case UVC_GET_CUR:
- return (zoom == 0) ? 0 : (zoom > 0 ? data[2] : -data[2]);
+ *out = (sign == 0) ? 0 : (sign > 0 ? value : -value);
+ return 0;
case UVC_GET_MIN:
case UVC_GET_MAX:
case UVC_GET_RES:
case UVC_GET_DEF:
default:
- return data[2];
+ *out = value;
+ return 0;
}
}
-static void uvc_ctrl_set_zoom(struct uvc_control_mapping *mapping,
- s32 value, u8 *data)
+static int uvc_ctrl_set_zoom(struct uvc_control_mapping *mapping,
+ size_t v4l2_size, const void *v4l2_in,
+ void *uvc_out)
{
- data[0] = value == 0 ? 0 : (value > 0) ? 1 : 0xff;
- data[2] = min((int)abs(value), 0xff);
+ u8 *out = uvc_out;
+ s32 value;
+
+ if (WARN_ON(v4l2_size != sizeof(s32)))
+ return -EINVAL;
+
+ value = *(u32 *)v4l2_in;
+ out[0] = value == 0 ? 0 : (value > 0) ? 1 : 0xff;
+ out[2] = min_t(int, abs(value), 0xff);
+
+ return 0;
}
-static s32 uvc_ctrl_get_rel_speed(struct uvc_control_mapping *mapping,
- u8 query, const u8 *data)
+static int uvc_ctrl_get_rel_speed(struct uvc_control_mapping *mapping,
+ u8 query, const void *uvc_in,
+ size_t v4l2_size, void *v4l2_out)
{
unsigned int first = mapping->offset / 8;
- s8 rel = (s8)data[first];
+ u8 value = ((u8 *)uvc_in)[first + 1];
+ s8 sign = ((s8 *)uvc_in)[first];
+ s32 *out = v4l2_out;
+
+ if (WARN_ON(v4l2_size != sizeof(s32)))
+ return -EINVAL;
switch (query) {
case UVC_GET_CUR:
- return (rel == 0) ? 0 : (rel > 0 ? data[first+1]
- : -data[first+1]);
+ *out = (sign == 0) ? 0 : (sign > 0 ? value : -value);
+ return 0;
case UVC_GET_MIN:
- return -data[first+1];
+ *out = -value;
+ return 0;
case UVC_GET_MAX:
case UVC_GET_RES:
case UVC_GET_DEF:
default:
- return data[first+1];
+ *out = value;
+ return 0;
}
}
-static void uvc_ctrl_set_rel_speed(struct uvc_control_mapping *mapping,
- s32 value, u8 *data)
+static int uvc_ctrl_set_rel_speed(struct uvc_control_mapping *mapping,
+ size_t v4l2_size, const void *v4l2_in,
+ void *uvc_out)
{
unsigned int first = mapping->offset / 8;
+ u8 *out = uvc_out;
+ s32 value;
+
+ if (WARN_ON(v4l2_size != sizeof(s32)))
+ return -EINVAL;
- data[first] = value == 0 ? 0 : (value > 0) ? 1 : 0xff;
- data[first+1] = min_t(int, abs(value), 0xff);
+ value = *(u32 *)v4l2_in;
+ out[first] = value == 0 ? 0 : (value > 0) ? 1 : 0xff;
+ out[first + 1] = min_t(int, abs(value), 0xff);
+
+ return 0;
}
static const struct uvc_control_mapping uvc_ctrl_power_line_mapping_limited = {
@@ -547,6 +621,44 @@ end:
return out_mapping;
}
+static int uvc_get_rect(struct uvc_control_mapping *mapping, u8 query,
+ const void *uvc_in, size_t v4l2_size, void *v4l2_out)
+{
+ const struct uvc_rect *uvc_rect = uvc_in;
+ struct v4l2_rect *v4l2_rect = v4l2_out;
+
+ if (WARN_ON(v4l2_size != sizeof(struct v4l2_rect)))
+ return -EINVAL;
+
+ if (uvc_rect->left > uvc_rect->right ||
+ uvc_rect->top > uvc_rect->bottom)
+ return -EIO;
+
+ v4l2_rect->top = uvc_rect->top;
+ v4l2_rect->left = uvc_rect->left;
+ v4l2_rect->height = uvc_rect->bottom - uvc_rect->top + 1;
+ v4l2_rect->width = uvc_rect->right - uvc_rect->left + 1;
+
+ return 0;
+}
+
+static int uvc_set_rect(struct uvc_control_mapping *mapping, size_t v4l2_size,
+ const void *v4l2_in, void *uvc_out)
+{
+ struct uvc_rect *uvc_rect = uvc_out;
+ const struct v4l2_rect *v4l2_rect = v4l2_in;
+
+ if (WARN_ON(v4l2_size != sizeof(struct v4l2_rect)))
+ return -EINVAL;
+
+ uvc_rect->top = min(0xffff, v4l2_rect->top);
+ uvc_rect->left = min(0xffff, v4l2_rect->left);
+ uvc_rect->bottom = min(0xffff, v4l2_rect->top + v4l2_rect->height - 1);
+ uvc_rect->right = min(0xffff, v4l2_rect->left + v4l2_rect->width - 1);
+
+ return 0;
+}
+
static const struct uvc_control_mapping uvc_ctrl_mappings[] = {
{
.id = V4L2_CID_BRIGHTNESS,
@@ -841,6 +953,28 @@ static const struct uvc_control_mapping uvc_ctrl_mappings[] = {
.selector = UVC_PU_POWER_LINE_FREQUENCY_CONTROL,
.filter_mapping = uvc_ctrl_filter_plf_mapping,
},
+ {
+ .id = V4L2_CID_UVC_REGION_OF_INTEREST_RECT,
+ .entity = UVC_GUID_UVC_CAMERA,
+ .selector = UVC_CT_REGION_OF_INTEREST_CONTROL,
+ .size = sizeof(struct uvc_rect) * 8,
+ .offset = 0,
+ .v4l2_type = V4L2_CTRL_TYPE_RECT,
+ .data_type = UVC_CTRL_DATA_TYPE_RECT,
+ .get = uvc_get_rect,
+ .set = uvc_set_rect,
+ .name = "Region of Interest Rectangle",
+ },
+ {
+ .id = V4L2_CID_UVC_REGION_OF_INTEREST_AUTO,
+ .entity = UVC_GUID_UVC_CAMERA,
+ .selector = UVC_CT_REGION_OF_INTEREST_CONTROL,
+ .size = 16,
+ .offset = 64,
+ .v4l2_type = V4L2_CTRL_TYPE_BITMASK,
+ .data_type = UVC_CTRL_DATA_TYPE_BITMASK,
+ .name = "Region of Interest Auto Ctrls",
+ },
};
/* ------------------------------------------------------------------------
@@ -862,20 +996,45 @@ static inline void uvc_clear_bit(u8 *data, int bit)
data[bit >> 3] &= ~(1 << (bit & 7));
}
+static s32 uvc_menu_to_v4l2_menu(struct uvc_control_mapping *mapping, s32 val)
+{
+ unsigned int i;
+
+ for (i = 0; BIT(i) <= mapping->menu_mask; ++i) {
+ u32 menu_value;
+
+ if (!test_bit(i, &mapping->menu_mask))
+ continue;
+
+ menu_value = uvc_mapping_get_menu_value(mapping, i);
+
+ if (menu_value == val)
+ return i;
+ }
+
+ return val;
+}
+
/*
* Extract the bit string specified by mapping->offset and mapping->size
* from the little-endian data stored at 'data' and return the result as
* a signed 32bit integer. Sign extension will be performed if the mapping
* references a signed data type.
*/
-static s32 uvc_get_le_value(struct uvc_control_mapping *mapping,
- u8 query, const u8 *data)
+static int uvc_get_le_value(struct uvc_control_mapping *mapping,
+ u8 query, const void *uvc_in, size_t v4l2_size,
+ void *v4l2_out)
{
- int bits = mapping->size;
int offset = mapping->offset;
+ int bits = mapping->size;
+ const u8 *data = uvc_in;
+ s32 *out = v4l2_out;
s32 value = 0;
u8 mask;
+ if (WARN_ON(v4l2_size != sizeof(s32)))
+ return -EINVAL;
+
data += offset / 8;
offset &= 7;
mask = ((1LL << bits) - 1) << offset;
@@ -896,28 +1055,58 @@ static s32 uvc_get_le_value(struct uvc_control_mapping *mapping,
if (mapping->data_type == UVC_CTRL_DATA_TYPE_SIGNED)
value |= -(value & (1 << (mapping->size - 1)));
- return value;
+ /* If it is a menu, convert from uvc to v4l2. */
+ if (mapping->v4l2_type != V4L2_CTRL_TYPE_MENU) {
+ *out = value;
+ return 0;
+ }
+
+ switch (query) {
+ case UVC_GET_CUR:
+ case UVC_GET_DEF:
+ *out = uvc_menu_to_v4l2_menu(mapping, value);
+ return 0;
+ }
+
+ *out = value;
+ return 0;
}
/*
* Set the bit string specified by mapping->offset and mapping->size
* in the little-endian data stored at 'data' to the value 'value'.
*/
-static void uvc_set_le_value(struct uvc_control_mapping *mapping,
- s32 value, u8 *data)
+static int uvc_set_le_value(struct uvc_control_mapping *mapping,
+ size_t v4l2_size, const void *v4l2_in,
+ void *uvc_out)
{
- int bits = mapping->size;
int offset = mapping->offset;
+ int bits = mapping->size;
+ u8 *data = uvc_out;
+ s32 value;
u8 mask;
- /*
- * According to the v4l2 spec, writing any value to a button control
- * should result in the action belonging to the button control being
- * triggered. UVC devices however want to see a 1 written -> override
- * value.
- */
- if (mapping->v4l2_type == V4L2_CTRL_TYPE_BUTTON)
+ if (WARN_ON(v4l2_size != sizeof(s32)))
+ return -EINVAL;
+
+ value = *(s32 *)v4l2_in;
+
+ switch (mapping->v4l2_type) {
+ case V4L2_CTRL_TYPE_MENU:
+ value = uvc_mapping_get_menu_value(mapping, value);
+ break;
+ case V4L2_CTRL_TYPE_BUTTON:
+ /*
+ * According to the v4l2 spec, writing any value to a button
+ * control should result in the action belonging to the button
+ * control being triggered. UVC devices however want to see a 1
+ * written -> override value.
+ */
value = -1;
+ break;
+ default:
+ break;
+ }
data += offset / 8;
offset &= 7;
@@ -929,6 +1118,8 @@ static void uvc_set_le_value(struct uvc_control_mapping *mapping,
bits -= 8 - offset;
offset = 0;
}
+
+ return 0;
}
/* ------------------------------------------------------------------------
@@ -947,7 +1138,7 @@ static int uvc_entity_match_guid(const struct uvc_entity *entity,
static void __uvc_find_control(struct uvc_entity *entity, u32 v4l2_id,
struct uvc_control_mapping **mapping, struct uvc_control **control,
- int next)
+ int next, int next_compound)
{
struct uvc_control *ctrl;
struct uvc_control_mapping *map;
@@ -962,14 +1153,16 @@ static void __uvc_find_control(struct uvc_entity *entity, u32 v4l2_id,
continue;
list_for_each_entry(map, &ctrl->info.mappings, list) {
- if ((map->id == v4l2_id) && !next) {
+ if (map->id == v4l2_id && !next && !next_compound) {
*control = ctrl;
*mapping = map;
return;
}
if ((*mapping == NULL || (*mapping)->id > map->id) &&
- (map->id > v4l2_id) && next) {
+ (map->id > v4l2_id) &&
+ (uvc_ctrl_mapping_is_compound(map) ?
+ next_compound : next)) {
*control = ctrl;
*mapping = map;
}
@@ -983,6 +1176,7 @@ static struct uvc_control *uvc_find_control(struct uvc_video_chain *chain,
struct uvc_control *ctrl = NULL;
struct uvc_entity *entity;
int next = v4l2_id & V4L2_CTRL_FLAG_NEXT_CTRL;
+ int next_compound = v4l2_id & V4L2_CTRL_FLAG_NEXT_COMPOUND;
*mapping = NULL;
@@ -991,12 +1185,13 @@ static struct uvc_control *uvc_find_control(struct uvc_video_chain *chain,
/* Find the control. */
list_for_each_entry(entity, &chain->entities, chain) {
- __uvc_find_control(entity, v4l2_id, mapping, &ctrl, next);
- if (ctrl && !next)
+ __uvc_find_control(entity, v4l2_id, mapping, &ctrl, next,
+ next_compound);
+ if (ctrl && !next && !next_compound)
return ctrl;
}
- if (ctrl == NULL && !next)
+ if (!ctrl && !next && !next_compound)
uvc_dbg(chain->dev, CONTROL, "Control 0x%08x not found\n",
v4l2_id);
@@ -1060,32 +1255,6 @@ static int uvc_ctrl_populate_cache(struct uvc_video_chain *chain,
return 0;
}
-static s32 __uvc_ctrl_get_value(struct uvc_control_mapping *mapping,
- const u8 *data)
-{
- s32 value = mapping->get(mapping, UVC_GET_CUR, data);
-
- if (mapping->v4l2_type == V4L2_CTRL_TYPE_MENU) {
- unsigned int i;
-
- for (i = 0; BIT(i) <= mapping->menu_mask; ++i) {
- u32 menu_value;
-
- if (!test_bit(i, &mapping->menu_mask))
- continue;
-
- menu_value = uvc_mapping_get_menu_value(mapping, i);
-
- if (menu_value == value) {
- value = i;
- break;
- }
- }
- }
-
- return value;
-}
-
static int __uvc_ctrl_load_cur(struct uvc_video_chain *chain,
struct uvc_control *ctrl)
{
@@ -1136,8 +1305,8 @@ static int __uvc_ctrl_get(struct uvc_video_chain *chain,
if (ret < 0)
return ret;
- *value = __uvc_ctrl_get_value(mapping,
- uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT));
+ *value = uvc_mapping_get_s32(mapping, UVC_GET_CUR,
+ uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT));
return 0;
}
@@ -1145,7 +1314,8 @@ static int __uvc_ctrl_get(struct uvc_video_chain *chain,
static int __uvc_query_v4l2_class(struct uvc_video_chain *chain, u32 req_id,
u32 found_id)
{
- bool find_next = req_id & V4L2_CTRL_FLAG_NEXT_CTRL;
+ bool find_next = req_id &
+ (V4L2_CTRL_FLAG_NEXT_CTRL | V4L2_CTRL_FLAG_NEXT_COMPOUND);
unsigned int i;
req_id &= V4L2_CTRL_ID_MASK;
@@ -1167,7 +1337,8 @@ static int __uvc_query_v4l2_class(struct uvc_video_chain *chain, u32 req_id,
}
static int uvc_query_v4l2_class(struct uvc_video_chain *chain, u32 req_id,
- u32 found_id, struct v4l2_queryctrl *v4l2_ctrl)
+ u32 found_id,
+ struct v4l2_query_ext_ctrl *v4l2_ctrl)
{
int idx;
@@ -1185,6 +1356,37 @@ static int uvc_query_v4l2_class(struct uvc_video_chain *chain, u32 req_id,
return 0;
}
+static bool uvc_ctrl_is_readable(u32 which, struct uvc_control *ctrl,
+ struct uvc_control_mapping *mapping)
+{
+ if (which == V4L2_CTRL_WHICH_CUR_VAL)
+ return !!(ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR);
+
+ if (which == V4L2_CTRL_WHICH_DEF_VAL)
+ return !!(ctrl->info.flags & UVC_CTRL_FLAG_GET_DEF);
+
+ /* Types with implicit boundaries. */
+ switch (mapping->v4l2_type) {
+ case V4L2_CTRL_TYPE_MENU:
+ case V4L2_CTRL_TYPE_BOOLEAN:
+ case V4L2_CTRL_TYPE_BUTTON:
+ return true;
+ case V4L2_CTRL_TYPE_BITMASK:
+ return (ctrl->info.flags & UVC_CTRL_FLAG_GET_RES) ||
+ (ctrl->info.flags & UVC_CTRL_FLAG_GET_MAX);
+ default:
+ break;
+ }
+
+ if (which == V4L2_CTRL_WHICH_MIN_VAL)
+ return !!(ctrl->info.flags & UVC_CTRL_FLAG_GET_MIN);
+
+ if (which == V4L2_CTRL_WHICH_MAX_VAL)
+ return !!(ctrl->info.flags & UVC_CTRL_FLAG_GET_MAX);
+
+ return false;
+}
+
/*
* Check if control @v4l2_id can be accessed by the given control @ioctl
* (VIDIOC_G_EXT_CTRLS, VIDIOC_TRY_EXT_CTRLS or VIDIOC_S_EXT_CTRLS).
@@ -1203,7 +1405,6 @@ int uvc_ctrl_is_accessible(struct uvc_video_chain *chain, u32 v4l2_id,
struct uvc_control *master_ctrl = NULL;
struct uvc_control_mapping *mapping;
struct uvc_control *ctrl;
- bool read = ioctl == VIDIOC_G_EXT_CTRLS;
s32 val;
int ret;
int i;
@@ -1215,10 +1416,10 @@ int uvc_ctrl_is_accessible(struct uvc_video_chain *chain, u32 v4l2_id,
if (!ctrl)
return -EINVAL;
- if (!(ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR) && read)
- return -EACCES;
+ if (ioctl == VIDIOC_G_EXT_CTRLS)
+ return uvc_ctrl_is_readable(ctrls->which, ctrl, mapping);
- if (!(ctrl->info.flags & UVC_CTRL_FLAG_SET_CUR) && !read)
+ if (!(ctrl->info.flags & UVC_CTRL_FLAG_SET_CUR))
return -EACCES;
if (ioctl != VIDIOC_S_EXT_CTRLS || !mapping->master_id)
@@ -1235,10 +1436,12 @@ int uvc_ctrl_is_accessible(struct uvc_video_chain *chain, u32 v4l2_id,
}
__uvc_find_control(ctrl->entity, mapping->master_id, &master_map,
- &master_ctrl, 0);
+ &master_ctrl, 0, 0);
if (!master_ctrl || !(master_ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR))
return 0;
+ if (WARN_ON(uvc_ctrl_mapping_is_compound(master_map)))
+ return -EIO;
ret = __uvc_ctrl_get(chain, master_ctrl, master_map, &val);
if (ret >= 0 && val != mapping->master_manual)
@@ -1270,50 +1473,21 @@ static u32 uvc_get_ctrl_bitmap(struct uvc_control *ctrl,
* as supported.
*/
if (ctrl->info.flags & UVC_CTRL_FLAG_GET_RES)
- return mapping->get(mapping, UVC_GET_RES,
- uvc_ctrl_data(ctrl, UVC_CTRL_DATA_RES));
+ return uvc_mapping_get_s32(mapping, UVC_GET_RES,
+ uvc_ctrl_data(ctrl, UVC_CTRL_DATA_RES));
if (ctrl->info.flags & UVC_CTRL_FLAG_GET_MAX)
- return mapping->get(mapping, UVC_GET_MAX,
- uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MAX));
+ return uvc_mapping_get_s32(mapping, UVC_GET_MAX,
+ uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MAX));
return ~0;
}
-static int __uvc_query_v4l2_ctrl(struct uvc_video_chain *chain,
- struct uvc_control *ctrl,
- struct uvc_control_mapping *mapping,
- struct v4l2_queryctrl *v4l2_ctrl)
+static int __uvc_queryctrl_boundaries(struct uvc_video_chain *chain,
+ struct uvc_control *ctrl,
+ struct uvc_control_mapping *mapping,
+ struct v4l2_query_ext_ctrl *v4l2_ctrl)
{
- struct uvc_control_mapping *master_map = NULL;
- struct uvc_control *master_ctrl = NULL;
- unsigned int i;
-
- memset(v4l2_ctrl, 0, sizeof(*v4l2_ctrl));
- v4l2_ctrl->id = mapping->id;
- v4l2_ctrl->type = mapping->v4l2_type;
- strscpy(v4l2_ctrl->name, uvc_map_get_name(mapping),
- sizeof(v4l2_ctrl->name));
- v4l2_ctrl->flags = 0;
-
- if (!(ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR))
- v4l2_ctrl->flags |= V4L2_CTRL_FLAG_WRITE_ONLY;
- if (!(ctrl->info.flags & UVC_CTRL_FLAG_SET_CUR))
- v4l2_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
-
- if (mapping->master_id)
- __uvc_find_control(ctrl->entity, mapping->master_id,
- &master_map, &master_ctrl, 0);
- if (master_ctrl && (master_ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR)) {
- s32 val;
- int ret = __uvc_ctrl_get(chain, master_ctrl, master_map, &val);
- if (ret < 0)
- return ret;
-
- if (val != mapping->master_manual)
- v4l2_ctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
- }
-
if (!ctrl->cached) {
int ret = uvc_ctrl_populate_cache(chain, ctrl);
if (ret < 0)
@@ -1321,8 +1495,8 @@ static int __uvc_query_v4l2_ctrl(struct uvc_video_chain *chain,
}
if (ctrl->info.flags & UVC_CTRL_FLAG_GET_DEF) {
- v4l2_ctrl->default_value = mapping->get(mapping, UVC_GET_DEF,
- uvc_ctrl_data(ctrl, UVC_CTRL_DATA_DEF));
+ v4l2_ctrl->default_value = uvc_mapping_get_s32(mapping,
+ UVC_GET_DEF, uvc_ctrl_data(ctrl, UVC_CTRL_DATA_DEF));
}
switch (mapping->v4l2_type) {
@@ -1330,21 +1504,6 @@ static int __uvc_query_v4l2_ctrl(struct uvc_video_chain *chain,
v4l2_ctrl->minimum = ffs(mapping->menu_mask) - 1;
v4l2_ctrl->maximum = fls(mapping->menu_mask) - 1;
v4l2_ctrl->step = 1;
-
- for (i = 0; BIT(i) <= mapping->menu_mask; ++i) {
- u32 menu_value;
-
- if (!test_bit(i, &mapping->menu_mask))
- continue;
-
- menu_value = uvc_mapping_get_menu_value(mapping, i);
-
- if (menu_value == v4l2_ctrl->default_value) {
- v4l2_ctrl->default_value = i;
- break;
- }
- }
-
return 0;
case V4L2_CTRL_TYPE_BOOLEAN:
@@ -1370,22 +1529,95 @@ static int __uvc_query_v4l2_ctrl(struct uvc_video_chain *chain,
}
if (ctrl->info.flags & UVC_CTRL_FLAG_GET_MIN)
- v4l2_ctrl->minimum = mapping->get(mapping, UVC_GET_MIN,
- uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MIN));
+ v4l2_ctrl->minimum = uvc_mapping_get_s32(mapping, UVC_GET_MIN,
+ uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MIN));
+ else
+ v4l2_ctrl->minimum = 0;
if (ctrl->info.flags & UVC_CTRL_FLAG_GET_MAX)
- v4l2_ctrl->maximum = mapping->get(mapping, UVC_GET_MAX,
- uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MAX));
+ v4l2_ctrl->maximum = uvc_mapping_get_s32(mapping, UVC_GET_MAX,
+ uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MAX));
+ else
+ v4l2_ctrl->maximum = 0;
if (ctrl->info.flags & UVC_CTRL_FLAG_GET_RES)
- v4l2_ctrl->step = mapping->get(mapping, UVC_GET_RES,
- uvc_ctrl_data(ctrl, UVC_CTRL_DATA_RES));
+ v4l2_ctrl->step = uvc_mapping_get_s32(mapping, UVC_GET_RES,
+ uvc_ctrl_data(ctrl, UVC_CTRL_DATA_RES));
+ else
+ v4l2_ctrl->step = 0;
return 0;
}
+static size_t uvc_mapping_v4l2_size(struct uvc_control_mapping *mapping)
+{
+ if (mapping->v4l2_type == V4L2_CTRL_TYPE_RECT)
+ return sizeof(struct v4l2_rect);
+
+ if (uvc_ctrl_mapping_is_compound(mapping))
+ return DIV_ROUND_UP(mapping->size, 8);
+
+ return sizeof(s32);
+}
+
+static int __uvc_query_v4l2_ctrl(struct uvc_video_chain *chain,
+ struct uvc_control *ctrl,
+ struct uvc_control_mapping *mapping,
+ struct v4l2_query_ext_ctrl *v4l2_ctrl)
+{
+ struct uvc_control_mapping *master_map = NULL;
+ struct uvc_control *master_ctrl = NULL;
+
+ memset(v4l2_ctrl, 0, sizeof(*v4l2_ctrl));
+ v4l2_ctrl->id = mapping->id;
+ v4l2_ctrl->type = mapping->v4l2_type;
+ strscpy(v4l2_ctrl->name, uvc_map_get_name(mapping),
+ sizeof(v4l2_ctrl->name));
+ v4l2_ctrl->flags = 0;
+
+ if (!(ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR))
+ v4l2_ctrl->flags |= V4L2_CTRL_FLAG_WRITE_ONLY;
+ if (!(ctrl->info.flags & UVC_CTRL_FLAG_SET_CUR))
+ v4l2_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
+ if ((ctrl->info.flags & UVC_CTRL_FLAG_GET_MAX) &&
+ (ctrl->info.flags & UVC_CTRL_FLAG_GET_MIN))
+ v4l2_ctrl->flags |= V4L2_CTRL_FLAG_HAS_WHICH_MIN_MAX;
+
+ if (mapping->master_id)
+ __uvc_find_control(ctrl->entity, mapping->master_id,
+ &master_map, &master_ctrl, 0, 0);
+ if (master_ctrl && (master_ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR)) {
+ s32 val;
+ int ret;
+
+ if (WARN_ON(uvc_ctrl_mapping_is_compound(master_map)))
+ return -EIO;
+
+ ret = __uvc_ctrl_get(chain, master_ctrl, master_map, &val);
+ if (ret < 0)
+ return ret;
+
+ if (val != mapping->master_manual)
+ v4l2_ctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
+ }
+
+ v4l2_ctrl->elem_size = uvc_mapping_v4l2_size(mapping);
+ v4l2_ctrl->elems = 1;
+
+ if (v4l2_ctrl->type >= V4L2_CTRL_COMPOUND_TYPES) {
+ v4l2_ctrl->flags |= V4L2_CTRL_FLAG_HAS_PAYLOAD;
+ v4l2_ctrl->default_value = 0;
+ v4l2_ctrl->minimum = 0;
+ v4l2_ctrl->maximum = 0;
+ v4l2_ctrl->step = 0;
+ return 0;
+ }
+
+ return __uvc_queryctrl_boundaries(chain, ctrl, mapping, v4l2_ctrl);
+}
+
int uvc_query_v4l2_ctrl(struct uvc_video_chain *chain,
- struct v4l2_queryctrl *v4l2_ctrl)
+ struct v4l2_query_ext_ctrl *v4l2_ctrl)
{
struct uvc_control *ctrl;
struct uvc_control_mapping *mapping;
@@ -1511,7 +1743,7 @@ static void uvc_ctrl_fill_event(struct uvc_video_chain *chain,
struct uvc_control_mapping *mapping,
s32 value, u32 changes)
{
- struct v4l2_queryctrl v4l2_ctrl;
+ struct v4l2_query_ext_ctrl v4l2_ctrl;
__uvc_query_v4l2_ctrl(chain, ctrl, mapping, &v4l2_ctrl);
@@ -1569,11 +1801,12 @@ static void uvc_ctrl_send_slave_event(struct uvc_video_chain *chain,
u32 changes = V4L2_EVENT_CTRL_CH_FLAGS;
s32 val = 0;
- __uvc_find_control(master->entity, slave_id, &mapping, &ctrl, 0);
+ __uvc_find_control(master->entity, slave_id, &mapping, &ctrl, 0, 0);
if (ctrl == NULL)
return;
- if (__uvc_ctrl_get(chain, ctrl, mapping, &val) == 0)
+ if (uvc_ctrl_mapping_is_compound(mapping) ||
+ __uvc_ctrl_get(chain, ctrl, mapping, &val) == 0)
changes |= V4L2_EVENT_CTRL_CH_VALUE;
uvc_ctrl_send_event(chain, handle, ctrl, mapping, val, changes);
@@ -1630,7 +1863,12 @@ void uvc_ctrl_status_event(struct uvc_video_chain *chain,
uvc_ctrl_set_handle(handle, ctrl, NULL);
list_for_each_entry(mapping, &ctrl->info.mappings, list) {
- s32 value = __uvc_ctrl_get_value(mapping, data);
+ s32 value;
+
+ if (uvc_ctrl_mapping_is_compound(mapping))
+ value = 0;
+ else
+ value = uvc_mapping_get_s32(mapping, UVC_GET_CUR, data);
/*
* handle may be NULL here if the device sends auto-update
@@ -1714,6 +1952,7 @@ static void uvc_ctrl_send_events(struct uvc_fh *handle,
for (i = 0; i < xctrls_count; ++i) {
u32 changes = V4L2_EVENT_CTRL_CH_VALUE;
+ s32 value;
ctrl = uvc_find_control(handle->chain, xctrls[i].id, &mapping);
if (ctrl->info.flags & UVC_CTRL_FLAG_ASYNCHRONOUS)
@@ -1738,6 +1977,10 @@ static void uvc_ctrl_send_events(struct uvc_fh *handle,
slave_id);
}
+ if (uvc_ctrl_mapping_is_compound(mapping))
+ value = 0;
+ else
+ value = xctrls[i].value;
/*
* If the master is being modified in the same transaction
* flags may change too.
@@ -1748,7 +1991,7 @@ static void uvc_ctrl_send_events(struct uvc_fh *handle,
changes |= V4L2_EVENT_CTRL_CH_FLAGS;
uvc_ctrl_send_event(handle->chain, handle, ctrl, mapping,
- xctrls[i].value, changes);
+ value, changes);
}
}
@@ -1780,7 +2023,8 @@ static int uvc_ctrl_add_event(struct v4l2_subscribed_event *sev, unsigned elems)
u32 changes = V4L2_EVENT_CTRL_CH_FLAGS;
s32 val = 0;
- if (__uvc_ctrl_get(handle->chain, ctrl, mapping, &val) == 0)
+ if (uvc_ctrl_mapping_is_compound(mapping) ||
+ __uvc_ctrl_get(handle->chain, ctrl, mapping, &val) == 0)
changes |= V4L2_EVENT_CTRL_CH_VALUE;
uvc_ctrl_fill_event(handle->chain, &ev, ctrl, mapping, val,
@@ -1920,7 +2164,7 @@ static int uvc_ctrl_find_ctrl_idx(struct uvc_entity *entity,
for (i = 0; i < ctrls->count; i++) {
__uvc_find_control(entity, ctrls->controls[i].id, &mapping,
- &ctrl_found, 0);
+ &ctrl_found, 0, 0);
if (uvc_control == ctrl_found)
return i;
}
@@ -1956,8 +2200,120 @@ done:
return ret;
}
-int uvc_ctrl_get(struct uvc_video_chain *chain,
- struct v4l2_ext_control *xctrl)
+static int uvc_mapping_get_xctrl_compound(struct uvc_video_chain *chain,
+ struct uvc_control *ctrl,
+ struct uvc_control_mapping *mapping,
+ u32 which,
+ struct v4l2_ext_control *xctrl)
+{
+ u8 *data __free(kfree) = NULL;
+ size_t size;
+ u8 query;
+ int ret;
+ int id;
+
+ switch (which) {
+ case V4L2_CTRL_WHICH_CUR_VAL:
+ id = UVC_CTRL_DATA_CURRENT;
+ query = UVC_GET_CUR;
+ break;
+ case V4L2_CTRL_WHICH_MIN_VAL:
+ id = UVC_CTRL_DATA_MIN;
+ query = UVC_GET_MIN;
+ break;
+ case V4L2_CTRL_WHICH_MAX_VAL:
+ id = UVC_CTRL_DATA_MAX;
+ query = UVC_GET_MAX;
+ break;
+ case V4L2_CTRL_WHICH_DEF_VAL:
+ id = UVC_CTRL_DATA_DEF;
+ query = UVC_GET_DEF;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ size = uvc_mapping_v4l2_size(mapping);
+ if (xctrl->size < size) {
+ xctrl->size = size;
+ return -ENOSPC;
+ }
+
+ data = kmalloc(size, GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+
+ if (which == V4L2_CTRL_WHICH_CUR_VAL)
+ ret = __uvc_ctrl_load_cur(chain, ctrl);
+ else
+ ret = uvc_ctrl_populate_cache(chain, ctrl);
+
+ if (ret < 0)
+ return ret;
+
+ ret = mapping->get(mapping, query, uvc_ctrl_data(ctrl, id), size, data);
+ if (ret < 0)
+ return ret;
+
+ /*
+ * v4l2_ext_control does not have enough room to fit a compound control.
+ * Instead, the value is in the user memory at xctrl->ptr. The v4l2
+ * ioctl helper does not copy it for us.
+ */
+ return copy_to_user(xctrl->ptr, data, size) ? -EFAULT : 0;
+}
+
+static int uvc_mapping_get_xctrl_std(struct uvc_video_chain *chain,
+ struct uvc_control *ctrl,
+ struct uvc_control_mapping *mapping,
+ u32 which, struct v4l2_ext_control *xctrl)
+{
+ struct v4l2_query_ext_ctrl qec;
+ int ret;
+
+ switch (which) {
+ case V4L2_CTRL_WHICH_CUR_VAL:
+ return __uvc_ctrl_get(chain, ctrl, mapping, &xctrl->value);
+ case V4L2_CTRL_WHICH_DEF_VAL:
+ case V4L2_CTRL_WHICH_MIN_VAL:
+ case V4L2_CTRL_WHICH_MAX_VAL:
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ ret = __uvc_queryctrl_boundaries(chain, ctrl, mapping, &qec);
+ if (ret < 0)
+ return ret;
+
+ switch (which) {
+ case V4L2_CTRL_WHICH_DEF_VAL:
+ xctrl->value = qec.default_value;
+ break;
+ case V4L2_CTRL_WHICH_MIN_VAL:
+ xctrl->value = qec.minimum;
+ break;
+ case V4L2_CTRL_WHICH_MAX_VAL:
+ xctrl->value = qec.maximum;
+ break;
+ }
+
+ return 0;
+}
+
+static int uvc_mapping_get_xctrl(struct uvc_video_chain *chain,
+ struct uvc_control *ctrl,
+ struct uvc_control_mapping *mapping,
+ u32 which, struct v4l2_ext_control *xctrl)
+{
+ if (uvc_ctrl_mapping_is_compound(mapping))
+ return uvc_mapping_get_xctrl_compound(chain, ctrl, mapping,
+ which, xctrl);
+ return uvc_mapping_get_xctrl_std(chain, ctrl, mapping, which, xctrl);
+}
+
+int uvc_ctrl_get(struct uvc_video_chain *chain, u32 which,
+ struct v4l2_ext_control *xctrl)
{
struct uvc_control *ctrl;
struct uvc_control_mapping *mapping;
@@ -1966,36 +2322,23 @@ int uvc_ctrl_get(struct uvc_video_chain *chain,
return -EACCES;
ctrl = uvc_find_control(chain, xctrl->id, &mapping);
- if (ctrl == NULL)
+ if (!ctrl)
return -EINVAL;
- return __uvc_ctrl_get(chain, ctrl, mapping, &xctrl->value);
+ return uvc_mapping_get_xctrl(chain, ctrl, mapping, which, xctrl);
}
-int uvc_ctrl_set(struct uvc_fh *handle,
- struct v4l2_ext_control *xctrl)
+static int uvc_ctrl_clamp(struct uvc_video_chain *chain,
+ struct uvc_control *ctrl,
+ struct uvc_control_mapping *mapping,
+ s32 *value_in_out)
{
- struct uvc_video_chain *chain = handle->chain;
- struct uvc_control *ctrl;
- struct uvc_control_mapping *mapping;
- s32 value;
+ s32 value = *value_in_out;
u32 step;
s32 min;
s32 max;
int ret;
- lockdep_assert_held(&chain->ctrl_mutex);
-
- if (__uvc_query_v4l2_class(chain, xctrl->id, 0) >= 0)
- return -EACCES;
-
- ctrl = uvc_find_control(chain, xctrl->id, &mapping);
- if (ctrl == NULL)
- return -EINVAL;
- if (!(ctrl->info.flags & UVC_CTRL_FLAG_SET_CUR))
- return -EACCES;
-
- /* Clamp out of range values. */
switch (mapping->v4l2_type) {
case V4L2_CTRL_TYPE_INTEGER:
if (!ctrl->cached) {
@@ -2004,23 +2347,22 @@ int uvc_ctrl_set(struct uvc_fh *handle,
return ret;
}
- min = mapping->get(mapping, UVC_GET_MIN,
- uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MIN));
- max = mapping->get(mapping, UVC_GET_MAX,
- uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MAX));
- step = mapping->get(mapping, UVC_GET_RES,
- uvc_ctrl_data(ctrl, UVC_CTRL_DATA_RES));
+ min = uvc_mapping_get_s32(mapping, UVC_GET_MIN,
+ uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MIN));
+ max = uvc_mapping_get_s32(mapping, UVC_GET_MAX,
+ uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MAX));
+ step = uvc_mapping_get_s32(mapping, UVC_GET_RES,
+ uvc_ctrl_data(ctrl, UVC_CTRL_DATA_RES));
if (step == 0)
step = 1;
- xctrl->value = min + DIV_ROUND_CLOSEST((u32)(xctrl->value - min),
- step) * step;
+ value = min + DIV_ROUND_CLOSEST((u32)(value - min), step) * step;
if (mapping->data_type == UVC_CTRL_DATA_TYPE_SIGNED)
- xctrl->value = clamp(xctrl->value, min, max);
+ value = clamp(value, min, max);
else
- xctrl->value = clamp_t(u32, xctrl->value, min, max);
- value = xctrl->value;
- break;
+ value = clamp_t(u32, value, min, max);
+ *value_in_out = value;
+ return 0;
case V4L2_CTRL_TYPE_BITMASK:
if (!ctrl->cached) {
@@ -2029,47 +2371,102 @@ int uvc_ctrl_set(struct uvc_fh *handle,
return ret;
}
- xctrl->value &= uvc_get_ctrl_bitmap(ctrl, mapping);
- value = xctrl->value;
- break;
+ value &= uvc_get_ctrl_bitmap(ctrl, mapping);
+ *value_in_out = value;
+ return 0;
case V4L2_CTRL_TYPE_BOOLEAN:
- xctrl->value = clamp(xctrl->value, 0, 1);
- value = xctrl->value;
- break;
+ *value_in_out = clamp(value, 0, 1);
+ return 0;
case V4L2_CTRL_TYPE_MENU:
- if (xctrl->value < (ffs(mapping->menu_mask) - 1) ||
- xctrl->value > (fls(mapping->menu_mask) - 1))
+ if (value < (ffs(mapping->menu_mask) - 1) ||
+ value > (fls(mapping->menu_mask) - 1))
return -ERANGE;
- if (!test_bit(xctrl->value, &mapping->menu_mask))
+ if (!test_bit(value, &mapping->menu_mask))
return -EINVAL;
- value = uvc_mapping_get_menu_value(mapping, xctrl->value);
-
/*
* Valid menu indices are reported by the GET_RES request for
* UVC controls that support it.
*/
if (mapping->data_type == UVC_CTRL_DATA_TYPE_BITMASK) {
+ int val = uvc_mapping_get_menu_value(mapping, value);
if (!ctrl->cached) {
ret = uvc_ctrl_populate_cache(chain, ctrl);
if (ret < 0)
return ret;
}
- if (!(uvc_get_ctrl_bitmap(ctrl, mapping) & value))
+ if (!(uvc_get_ctrl_bitmap(ctrl, mapping) & val))
return -EINVAL;
}
-
- break;
+ return 0;
default:
- value = xctrl->value;
- break;
+ return 0;
}
+ return 0;
+}
+
+static int uvc_mapping_set_xctrl_compound(struct uvc_control *ctrl,
+ struct uvc_control_mapping *mapping,
+ struct v4l2_ext_control *xctrl)
+{
+ u8 *data __free(kfree) = NULL;
+ size_t size = uvc_mapping_v4l2_size(mapping);
+
+ if (xctrl->size != size)
+ return -EINVAL;
+
+ /*
+ * v4l2_ext_control does not have enough room to fit a compound control.
+ * Instead, the value is in the user memory at xctrl->ptr. The v4l2
+ * ioctl helper does not copy it for us.
+ */
+ data = memdup_user(xctrl->ptr, size);
+ if (IS_ERR(data))
+ return PTR_ERR(data);
+
+ return mapping->set(mapping, size, data,
+ uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT));
+}
+
+static int uvc_mapping_set_xctrl(struct uvc_control *ctrl,
+ struct uvc_control_mapping *mapping,
+ struct v4l2_ext_control *xctrl)
+{
+ if (uvc_ctrl_mapping_is_compound(mapping))
+ return uvc_mapping_set_xctrl_compound(ctrl, mapping, xctrl);
+
+ uvc_mapping_set_s32(mapping, xctrl->value,
+ uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT));
+ return 0;
+}
+
+int uvc_ctrl_set(struct uvc_fh *handle, struct v4l2_ext_control *xctrl)
+{
+ struct uvc_video_chain *chain = handle->chain;
+ struct uvc_control_mapping *mapping;
+ struct uvc_control *ctrl;
+ int ret;
+
+ lockdep_assert_held(&chain->ctrl_mutex);
+
+ if (__uvc_query_v4l2_class(chain, xctrl->id, 0) >= 0)
+ return -EACCES;
+
+ ctrl = uvc_find_control(chain, xctrl->id, &mapping);
+ if (!ctrl)
+ return -EINVAL;
+ if (!(ctrl->info.flags & UVC_CTRL_FLAG_SET_CUR))
+ return -EACCES;
+
+ ret = uvc_ctrl_clamp(chain, ctrl, mapping, &xctrl->value);
+ if (ret)
+ return ret;
/*
* If the mapping doesn't span the whole UVC control, the current value
* needs to be loaded from the device to perform the read-modify-write
@@ -2088,8 +2485,9 @@ int uvc_ctrl_set(struct uvc_fh *handle,
ctrl->info.size);
}
- mapping->set(mapping, value,
- uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT));
+ ret = uvc_mapping_set_xctrl(ctrl, mapping, xctrl);
+ if (ret)
+ return ret;
ctrl->dirty = 1;
ctrl->modified = 1;
@@ -2464,6 +2862,7 @@ static int __uvc_ctrl_add_mapping(struct uvc_video_chain *chain,
struct uvc_control_mapping *map;
unsigned int size;
unsigned int i;
+ int ret;
/*
* Most mappings come from static kernel data, and need to be duplicated.
@@ -2504,6 +2903,12 @@ static int __uvc_ctrl_add_mapping(struct uvc_video_chain *chain,
goto err_nomem;
}
+ if (uvc_ctrl_mapping_is_compound(map))
+ if (WARN_ON(!map->set || !map->get)) {
+ ret = -EIO;
+ goto free_mem;
+ }
+
if (map->get == NULL)
map->get = uvc_get_le_value;
if (map->set == NULL)
@@ -2525,11 +2930,13 @@ static int __uvc_ctrl_add_mapping(struct uvc_video_chain *chain,
return 0;
err_nomem:
+ ret = -ENOMEM;
+free_mem:
kfree(map->menu_names);
kfree(map->menu_mapping);
kfree(map->name);
kfree(map);
- return -ENOMEM;
+ return ret;
}
int uvc_ctrl_add_mapping(struct uvc_video_chain *chain,
diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c
index deadbcea5e22..107e0fafd80f 100644
--- a/drivers/media/usb/uvc/uvc_driver.c
+++ b/drivers/media/usb/uvc/uvc_driver.c
@@ -37,6 +37,8 @@ static unsigned int uvc_quirks_param = -1;
unsigned int uvc_dbg_param;
unsigned int uvc_timeout_param = UVC_CTRL_STREAMING_TIMEOUT;
+static struct usb_driver uvc_driver;
+
/* ------------------------------------------------------------------------
* Utility functions
*/
@@ -546,7 +548,7 @@ static int uvc_parse_streaming(struct uvc_device *dev,
return -EINVAL;
}
- if (usb_driver_claim_interface(&uvc_driver.driver, intf, dev)) {
+ if (usb_driver_claim_interface(&uvc_driver, intf, dev)) {
uvc_dbg(dev, DESCR,
"device %d interface %d is already claimed\n",
dev->udev->devnum,
@@ -556,7 +558,7 @@ static int uvc_parse_streaming(struct uvc_device *dev,
streaming = uvc_stream_new(dev, intf);
if (streaming == NULL) {
- usb_driver_release_interface(&uvc_driver.driver, intf);
+ usb_driver_release_interface(&uvc_driver, intf);
return -ENOMEM;
}
@@ -779,7 +781,7 @@ static int uvc_parse_streaming(struct uvc_device *dev,
return 0;
error:
- usb_driver_release_interface(&uvc_driver.driver, intf);
+ usb_driver_release_interface(&uvc_driver, intf);
uvc_stream_delete(streaming);
return ret;
}
@@ -1922,8 +1924,7 @@ static void uvc_delete(struct kref *kref)
struct uvc_streaming *streaming;
streaming = list_entry(p, struct uvc_streaming, list);
- usb_driver_release_interface(&uvc_driver.driver,
- streaming->intf);
+ usb_driver_release_interface(&uvc_driver, streaming->intf);
uvc_stream_delete(streaming);
}
@@ -3062,6 +3063,15 @@ static const struct usb_device_id uvc_ids[] = {
.bInterfaceProtocol = 0,
.driver_info = UVC_INFO_QUIRK(UVC_QUIRK_PROBE_MINMAX
| UVC_QUIRK_IGNORE_SELECTOR_UNIT) },
+ /* Actions Microelectronics Co. Display capture-UVC05 */
+ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
+ | USB_DEVICE_ID_MATCH_INT_INFO,
+ .idVendor = 0x1de1,
+ .idProduct = 0xf105,
+ .bInterfaceClass = USB_CLASS_VIDEO,
+ .bInterfaceSubClass = 1,
+ .bInterfaceProtocol = 0,
+ .driver_info = UVC_INFO_QUIRK(UVC_QUIRK_DISABLE_AUTOSUSPEND) },
/* NXP Semiconductors IR VIDEO */
{ .match_flags = USB_DEVICE_ID_MATCH_DEVICE
| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -3196,17 +3206,15 @@ static const struct usb_device_id uvc_ids[] = {
MODULE_DEVICE_TABLE(usb, uvc_ids);
-struct uvc_driver uvc_driver = {
- .driver = {
- .name = "uvcvideo",
- .probe = uvc_probe,
- .disconnect = uvc_disconnect,
- .suspend = uvc_suspend,
- .resume = uvc_resume,
- .reset_resume = uvc_reset_resume,
- .id_table = uvc_ids,
- .supports_autosuspend = 1,
- },
+static struct usb_driver uvc_driver = {
+ .name = "uvcvideo",
+ .probe = uvc_probe,
+ .disconnect = uvc_disconnect,
+ .suspend = uvc_suspend,
+ .resume = uvc_resume,
+ .reset_resume = uvc_reset_resume,
+ .id_table = uvc_ids,
+ .supports_autosuspend = 1,
};
static int __init uvc_init(void)
@@ -3215,7 +3223,7 @@ static int __init uvc_init(void)
uvc_debugfs_init();
- ret = usb_register(&uvc_driver.driver);
+ ret = usb_register(&uvc_driver);
if (ret < 0) {
uvc_debugfs_cleanup();
return ret;
@@ -3226,7 +3234,7 @@ static int __init uvc_init(void)
static void __exit uvc_cleanup(void)
{
- usb_deregister(&uvc_driver.driver);
+ usb_deregister(&uvc_driver);
uvc_debugfs_cleanup();
}
diff --git a/drivers/media/usb/uvc/uvc_v4l2.c b/drivers/media/usb/uvc/uvc_v4l2.c
index 93c6cdb23881..39065db44e86 100644
--- a/drivers/media/usb/uvc/uvc_v4l2.c
+++ b/drivers/media/usb/uvc/uvc_v4l2.c
@@ -108,6 +108,12 @@ static int uvc_ioctl_xu_ctrl_map(struct uvc_video_chain *chain,
struct uvc_control_mapping *map;
int ret;
+ if (xmap->data_type > UVC_CTRL_DATA_TYPE_BITMASK) {
+ uvc_dbg(chain->dev, CONTROL,
+ "Unsupported UVC data type %u\n", xmap->data_type);
+ return -EINVAL;
+ }
+
map = kzalloc(sizeof(*map), GFP_KERNEL);
if (map == NULL)
return -ENOMEM;
@@ -963,42 +969,13 @@ static int uvc_ioctl_s_input(struct file *file, void *fh, unsigned int input)
return ret;
}
-static int uvc_ioctl_queryctrl(struct file *file, void *fh,
- struct v4l2_queryctrl *qc)
-{
- struct uvc_fh *handle = fh;
- struct uvc_video_chain *chain = handle->chain;
-
- return uvc_query_v4l2_ctrl(chain, qc);
-}
-
static int uvc_ioctl_query_ext_ctrl(struct file *file, void *fh,
struct v4l2_query_ext_ctrl *qec)
{
struct uvc_fh *handle = fh;
struct uvc_video_chain *chain = handle->chain;
- struct v4l2_queryctrl qc = { qec->id };
- int ret;
-
- ret = uvc_query_v4l2_ctrl(chain, &qc);
- if (ret)
- return ret;
-
- qec->id = qc.id;
- qec->type = qc.type;
- strscpy(qec->name, qc.name, sizeof(qec->name));
- qec->minimum = qc.minimum;
- qec->maximum = qc.maximum;
- qec->step = qc.step;
- qec->default_value = qc.default_value;
- qec->flags = qc.flags;
- qec->elem_size = 4;
- qec->elems = 1;
- qec->nr_of_dims = 0;
- memset(qec->dims, 0, sizeof(qec->dims));
- memset(qec->reserved, 0, sizeof(qec->reserved));
- return 0;
+ return uvc_query_v4l2_ctrl(chain, qec);
}
static int uvc_ctrl_check_access(struct uvc_video_chain *chain,
@@ -1027,34 +1004,33 @@ static int uvc_ioctl_g_ext_ctrls(struct file *file, void *fh,
struct uvc_video_chain *chain = handle->chain;
struct v4l2_ext_control *ctrl = ctrls->controls;
unsigned int i;
+ u32 which;
int ret;
+ if (!ctrls->count)
+ return 0;
+
+ switch (ctrls->which) {
+ case V4L2_CTRL_WHICH_DEF_VAL:
+ case V4L2_CTRL_WHICH_CUR_VAL:
+ case V4L2_CTRL_WHICH_MAX_VAL:
+ case V4L2_CTRL_WHICH_MIN_VAL:
+ which = ctrls->which;
+ break;
+ default:
+ which = V4L2_CTRL_WHICH_CUR_VAL;
+ }
+
ret = uvc_ctrl_check_access(chain, ctrls, VIDIOC_G_EXT_CTRLS);
if (ret < 0)
return ret;
- if (ctrls->which == V4L2_CTRL_WHICH_DEF_VAL) {
- for (i = 0; i < ctrls->count; ++ctrl, ++i) {
- struct v4l2_queryctrl qc = { .id = ctrl->id };
-
- ret = uvc_query_v4l2_ctrl(chain, &qc);
- if (ret < 0) {
- ctrls->error_idx = i;
- return ret;
- }
-
- ctrl->value = qc.default_value;
- }
-
- return 0;
- }
-
ret = uvc_ctrl_begin(chain);
if (ret < 0)
return ret;
for (i = 0; i < ctrls->count; ++ctrl, ++i) {
- ret = uvc_ctrl_get(chain, ctrl);
+ ret = uvc_ctrl_get(chain, which, ctrl);
if (ret < 0) {
uvc_ctrl_rollback(handle);
ctrls->error_idx = i;
@@ -1076,6 +1052,9 @@ static int uvc_ioctl_s_try_ext_ctrls(struct uvc_fh *handle,
unsigned int i;
int ret;
+ if (!ctrls->count)
+ return 0;
+
ret = uvc_ctrl_check_access(chain, ctrls, ioctl);
if (ret < 0)
return ret;
@@ -1491,7 +1470,6 @@ const struct v4l2_ioctl_ops uvc_ioctl_ops = {
.vidioc_enum_input = uvc_ioctl_enum_input,
.vidioc_g_input = uvc_ioctl_g_input,
.vidioc_s_input = uvc_ioctl_s_input,
- .vidioc_queryctrl = uvc_ioctl_queryctrl,
.vidioc_query_ext_ctrl = uvc_ioctl_query_ext_ctrl,
.vidioc_g_ext_ctrls = uvc_ioctl_g_ext_ctrls,
.vidioc_s_ext_ctrls = uvc_ioctl_s_ext_ctrls,
diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h
index 5e388f05f3fc..b4ee701835fc 100644
--- a/drivers/media/usb/uvc/uvcvideo.h
+++ b/drivers/media/usb/uvc/uvcvideo.h
@@ -116,7 +116,12 @@ struct uvc_control_mapping {
u8 entity[16];
u8 selector;
+ /*
+ * Size of the control data in the payload of the UVC control GET and
+ * SET requests, expressed in bits.
+ */
u8 size;
+
u8 offset;
enum v4l2_ctrl_type v4l2_type;
u32 data_type;
@@ -132,10 +137,10 @@ struct uvc_control_mapping {
const struct uvc_control_mapping *(*filter_mapping)
(struct uvc_video_chain *chain,
struct uvc_control *ctrl);
- s32 (*get)(struct uvc_control_mapping *mapping, u8 query,
- const u8 *data);
- void (*set)(struct uvc_control_mapping *mapping, s32 value,
- u8 *data);
+ int (*get)(struct uvc_control_mapping *mapping, u8 query,
+ const void *uvc_in, size_t v4l2_size, void *v4l2_out);
+ int (*set)(struct uvc_control_mapping *mapping, size_t v4l2_size,
+ const void *v4l2_in, void *uvc_out);
};
struct uvc_control {
@@ -538,6 +543,13 @@ struct uvc_device_info {
u16 uvc_version;
};
+struct uvc_rect {
+ u16 top;
+ u16 left;
+ u16 bottom;
+ u16 right;
+} __packed;
+
struct uvc_status_streaming {
u8 button;
} __packed;
@@ -620,10 +632,6 @@ struct uvc_fh {
unsigned int pending_async_ctrls;
};
-struct uvc_driver {
- struct usb_driver driver;
-};
-
/* ------------------------------------------------------------------------
* Debugging, printing and logging
*/
@@ -674,9 +682,6 @@ do { \
* Internal functions.
*/
-/* Core driver */
-extern struct uvc_driver uvc_driver;
-
struct uvc_entity *uvc_entity_by_id(struct uvc_device *dev, int id);
/* Video buffers queue management. */
@@ -766,7 +771,7 @@ void uvc_status_put(struct uvc_device *dev);
extern const struct v4l2_subscribed_event_ops uvc_ctrl_sub_ev_ops;
int uvc_query_v4l2_ctrl(struct uvc_video_chain *chain,
- struct v4l2_queryctrl *v4l2_ctrl);
+ struct v4l2_query_ext_ctrl *v4l2_ctrl);
int uvc_query_v4l2_menu(struct uvc_video_chain *chain,
struct v4l2_querymenu *query_menu);
@@ -793,7 +798,8 @@ static inline int uvc_ctrl_rollback(struct uvc_fh *handle)
return __uvc_ctrl_commit(handle, 1, NULL);
}
-int uvc_ctrl_get(struct uvc_video_chain *chain, struct v4l2_ext_control *xctrl);
+int uvc_ctrl_get(struct uvc_video_chain *chain, u32 which,
+ struct v4l2_ext_control *xctrl);
int uvc_ctrl_set(struct uvc_fh *handle, struct v4l2_ext_control *xctrl);
int uvc_ctrl_is_accessible(struct uvc_video_chain *chain, u32 v4l2_id,
const struct v4l2_ext_controls *ctrls,