summaryrefslogtreecommitdiff
path: root/sys/dev/usb
diff options
context:
space:
mode:
authorJacob Meuser <jakemsr@cvs.openbsd.org>2010-09-26 23:44:52 +0000
committerJacob Meuser <jakemsr@cvs.openbsd.org>2010-09-26 23:44:52 +0000
commitc0968cd27b0f51555b3c12e31e6a8148ae9a73f8 (patch)
tree2ab6a20cd5131c42fb01bbcf0636705d99ca1889 /sys/dev/usb
parent04b5d95bf058c195eb3989b58656d38cdfeb4967 (diff)
support variable sized (bControlSize != 2) processing unit bmControls,
and add support for more processing unit controls. from Martin Pieuchot, thanks!
Diffstat (limited to 'sys/dev/usb')
-rw-r--r--sys/dev/usb/uvideo.c31
-rw-r--r--sys/dev/usb/uvideo.h125
2 files changed, 135 insertions, 21 deletions
diff --git a/sys/dev/usb/uvideo.c b/sys/dev/usb/uvideo.c
index 7c332030edd..c1d6ef4abdc 100644
--- a/sys/dev/usb/uvideo.c
+++ b/sys/dev/usb/uvideo.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uvideo.c,v 1.137 2010/09/12 22:27:52 jakemsr Exp $ */
+/* $OpenBSD: uvideo.c,v 1.138 2010/09/26 23:44:51 jakemsr Exp $ */
/*
* Copyright (c) 2008 Robert Nagy <robert@openbsd.org>
@@ -57,6 +57,9 @@ int uvideo_debug = 1;
#define DEVNAME(_s) ((_s)->sc_dev.dv_xname)
+#define byteof(x) ((x) >> 3)
+#define bitof(x) (1L << ((x) & 0x7))
+
int uvideo_enable(void *);
void uvideo_disable(void *);
int uvideo_open(void *, int, int *, uint8_t *, void (*)(void *),
@@ -78,6 +81,7 @@ usbd_status uvideo_vc_get_ctrl(struct uvideo_softc *, uint8_t *, uint8_t,
usbd_status uvideo_vc_set_ctrl(struct uvideo_softc *, uint8_t *, uint8_t,
uint8_t, uint16_t, uint16_t);
int uvideo_find_ctrl(struct uvideo_softc *, int);
+int uvideo_has_ctrl(struct usb_video_vc_processing_desc *, int);
usbd_status uvideo_vs_parse_desc(struct uvideo_softc *,
usb_config_descriptor_t *);
@@ -671,19 +675,14 @@ uvideo_vc_parse_desc_pu(struct uvideo_softc *sc,
struct usb_video_vc_processing_desc *d;
d = (struct usb_video_vc_processing_desc *)(uint8_t *)desc;
+ d->iProcessing = d->bmControls[d->bControlSize];
+ d->bmVideoStandards = d->bmControls[d->bControlSize + 1];
if (sc->sc_desc_vc_pu_num == UVIDEO_MAX_PU) {
printf("%s: too many PU descriptors found!\n", DEVNAME(sc));
return (USBD_INVAL);
}
- /* XXX support variable bmControls fields */
- if (d->bControlSize != 2) {
- printf("%s: video control not supported for this device.\n",
- DEVNAME(sc));
- return (USBD_INVAL);
- }
-
sc->sc_desc_vc_pu[sc->sc_desc_vc_pu_num] = d;
sc->sc_desc_vc_pu_num++;
@@ -763,8 +762,8 @@ uvideo_find_ctrl(struct uvideo_softc *sc, int id)
/* does the device support this control? */
for (found = 0, j = 0; j < sc->sc_desc_vc_pu_num; j++) {
- if (UGETW(sc->sc_desc_vc_pu[j]->bmControls) &
- uvideo_ctrls[i].ctrl_bitmap) {
+ if (uvideo_has_ctrl(sc->sc_desc_vc_pu[j],
+ uvideo_ctrls[i].ctrl_bit) != 0) {
found = 1;
break;
}
@@ -779,6 +778,15 @@ uvideo_find_ctrl(struct uvideo_softc *sc, int id)
return (i);
}
+int
+uvideo_has_ctrl(struct usb_video_vc_processing_desc *desc, int ctrl_bit)
+{
+ if (desc->bControlSize * 8 <= ctrl_bit)
+ return (0);
+
+ return (desc->bmControls[byteof(ctrl_bit)] & bitof(ctrl_bit));
+}
+
usbd_status
uvideo_vs_parse_desc(struct uvideo_softc *sc, usb_config_descriptor_t *cdesc)
{
@@ -2570,7 +2578,8 @@ uvideo_dump_desc_processing(struct uvideo_softc *sc,
printf("bSourceID=0x%02x\n", d->bSourceID);
printf("wMaxMultiplier=%d\n", UGETW(d->wMaxMultiplier));
printf("bControlSize=%d\n", d->bControlSize);
- printf("bmControls=0x%02x\n", UGETW(d->bmControls));
+ printf("bmControls=0x");
+ uvideo_hexdump(d->bmControls, d->bControlSize, 1);
printf("iProcessing=0x%02x\n", d->iProcessing);
printf("bmVideoStandards=0x%02x\n", d->bmVideoStandards);
}
diff --git a/sys/dev/usb/uvideo.h b/sys/dev/usb/uvideo.h
index 2f85c1a8ed8..5e12a702e28 100644
--- a/sys/dev/usb/uvideo.h
+++ b/sys/dev/usb/uvideo.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: uvideo.h,v 1.46 2010/04/27 11:58:14 marco Exp $ */
+/* $OpenBSD: uvideo.h,v 1.47 2010/09/26 23:44:51 jakemsr Exp $ */
/*
* Copyright (c) 2007 Robert Nagy <robert@openbsd.org>
@@ -217,9 +217,10 @@ struct usb_video_vc_processing_desc {
uByte bSourceID;
uWord wMaxMultiplier;
uByte bControlSize;
- uWord bmControls; /* XXX must be variable size of bControlSize */
+ uByte bmControls[255]; /* [bControlSize] */
uByte iProcessing;
uByte bmVideoStandards;
+
} __packed;
/* Table 3-9: VC Extension Unit Descriptor */
@@ -496,16 +497,18 @@ struct uvideo_controls {
int cid;
int type;
char name[32];
- uint16_t ctrl_bitmap;
+ uint8_t ctrl_bit;
uint16_t ctrl_selector;
uint16_t ctrl_len;
} uvideo_ctrls[] = {
- /* TODO complete control list */
+ /*
+ * Processing Unit Controls
+ */
{
V4L2_CID_BRIGHTNESS,
V4L2_CTRL_TYPE_INTEGER,
"Brightness",
- (1 << 0),
+ 0,
PU_BRIGHTNESS_CONTROL,
2
},
@@ -513,7 +516,7 @@ struct uvideo_controls {
V4L2_CID_CONTRAST,
V4L2_CTRL_TYPE_INTEGER,
"Contrast",
- (1 << 1),
+ 1,
PU_CONTRAST_CONTROL,
2
},
@@ -521,7 +524,7 @@ struct uvideo_controls {
V4L2_CID_HUE,
V4L2_CTRL_TYPE_INTEGER,
"Hue",
- (1 << 2),
+ 2,
PU_HUE_CONTROL,
2
},
@@ -529,26 +532,128 @@ struct uvideo_controls {
V4L2_CID_SATURATION,
V4L2_CTRL_TYPE_INTEGER,
"Saturation",
- (1 << 3),
+ 3,
PU_SATURATION_CONTROL,
2
},
{
+ V4L2_CID_SHARPNESS,
+ V4L2_CTRL_TYPE_INTEGER,
+ "Sharpness",
+ 4,
+ PU_SHARPNESS_CONTROL,
+ 2
+ },
+ {
V4L2_CID_GAMMA,
V4L2_CTRL_TYPE_INTEGER,
"Gamma",
- (1 << 5),
+ 5,
PU_GAMMA_CONTROL,
2
},
{
+ V4L2_CID_WHITE_BALANCE_TEMPERATURE,
+ V4L2_CTRL_TYPE_INTEGER,
+ "White Balance Temperature",
+ 6,
+ PU_WHITE_BALANCE_TEMPERATURE_CONTROL,
+ 2
+ },
+#if 0
+ /* XXX Two V4L2 ids mapping one UVC control */
+ {
+ V4L2_CID_RED_BALANCE, /* V4L2_CID_BLUE_BALANCE */
+ V4L2_CTRL_TYPE_INTEGER,
+ "White Balance Red Component", /* Blue Component */
+ 7,
+ PU_WHITE_BALANCE_COMPONENT_CONTROL,
+ 4
+ },
+#endif
+ {
+ V4L2_CID_BACKLIGHT_COMPENSATION,
+ V4L2_CTRL_TYPE_INTEGER,
+ "Backlight Compensation",
+ 8,
+ PU_BACKLIGHT_COMPENSATION_CONTROL,
+ 2,
+ },
+ {
V4L2_CID_GAIN,
V4L2_CTRL_TYPE_INTEGER,
"Gain",
- (1 << 9),
+ 9,
PU_GAIN_CONTROL,
2,
},
+ {
+ V4L2_CID_POWER_LINE_FREQUENCY,
+ V4L2_CTRL_TYPE_MENU,
+ "Power Line Frequency",
+ 10,
+ PU_POWER_LINE_FREQUENCY_CONTROL,
+ 1,
+ },
+ {
+ V4L2_CID_HUE_AUTO,
+ V4L2_CTRL_TYPE_BOOLEAN,
+ "Hue Auto",
+ 11,
+ PU_HUE_AUTO_CONTROL,
+ 1,
+ },
+ {
+ V4L2_CID_AUTO_WHITE_BALANCE,
+ V4L2_CTRL_TYPE_BOOLEAN,
+ "White Balance Temperature Auto",
+ 12,
+ PU_WHITE_BALANCE_TEMPERATURE_AUTO_CONTROL,
+ 1,
+ },
+ {
+ V4L2_CID_AUTO_WHITE_BALANCE,
+ V4L2_CTRL_TYPE_BOOLEAN,
+ "White Balance Component Auto",
+ 13,
+ PU_WHITE_BALANCE_COMPONENT_AUTO_CONTROL,
+ 1,
+ },
+#if 0
+ /* XXX No V4L2 CID for these controls? */
+ {
+ V4L2_CID_XXX,
+ V4L2_CTRL_TYPE_INTEGER,
+ "Digital Multiplier",
+ 14,
+ PU_DIGITAL_MULTIPLIER_CONTROL,
+ 2,
+ },
+ {
+ V4L2_CID_XXX,
+ V4L2_CTRL_TYPE_INTEGER,
+ "Digital Multiplier Limit",
+ 15,
+ PU_DIGITAL_MULTIPLIER_LIMIT_CONTROL,
+ 2,
+ },
+ {
+ V4L2_CID_XXX,
+ V4L2_CTRL_TYPE_INTEGER,
+ "Analog Video Standard",
+ 16,
+ PU_ANALOG_VIDEO_STANDARD_CONTROL,
+ 1,
+ },
+ {
+ V4L2_CID_XXX,
+ V4L2_CTRL_TYPE_INTEGER,
+ "Analog Lock Status",
+ 17,
+ PU_ANALOG_LOCK_STATUS_CONTROL,
+ 1,
+ },
+#endif
{ 0, 0, "", 0, 0, 0 }
};