diff options
author | Jacob Meuser <jakemsr@cvs.openbsd.org> | 2010-09-26 23:44:52 +0000 |
---|---|---|
committer | Jacob Meuser <jakemsr@cvs.openbsd.org> | 2010-09-26 23:44:52 +0000 |
commit | c0968cd27b0f51555b3c12e31e6a8148ae9a73f8 (patch) | |
tree | 2ab6a20cd5131c42fb01bbcf0636705d99ca1889 /sys/dev/usb | |
parent | 04b5d95bf058c195eb3989b58656d38cdfeb4967 (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.c | 31 | ||||
-rw-r--r-- | sys/dev/usb/uvideo.h | 125 |
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 } }; |