diff -Nudr -U3 -x pwc-if.c pwc-10.0.7a/pwc-ctrl.c pwc-10.0.7a-mod/pwc-ctrl.c --- pwc-10.0.7a/pwc-ctrl.c 2005-04-10 07:05:20.000000000 +0100 +++ pwc-10.0.7a-mod/pwc-ctrl.c 2005-09-01 13:38:04.548611032 +0100 @@ -628,7 +628,7 @@ /* AGC */ -static inline int pwc_set_agc(struct pwc_device *pdev, int mode, int value) +int pwc_set_agc(struct pwc_device *pdev, int mode, int value) { char buf; int ret; @@ -653,7 +653,7 @@ return 0; } -static inline int pwc_get_agc(struct pwc_device *pdev, int *value) +int pwc_get_agc(struct pwc_device *pdev, int *value) { unsigned char buf; int ret; @@ -683,7 +683,7 @@ return 0; } -static inline int pwc_set_shutter_speed(struct pwc_device *pdev, int mode, int value) +int pwc_set_shutter_speed(struct pwc_device *pdev, int mode, int value) { char buf[2]; int speed, ret; @@ -776,7 +776,7 @@ * 03: manual * 04: auto */ -static inline int pwc_set_awb(struct pwc_device *pdev, int mode) +int pwc_set_awb(struct pwc_device *pdev, int mode) { char buf; int ret; @@ -796,7 +796,7 @@ return 0; } -static inline int pwc_get_awb(struct pwc_device *pdev) +int pwc_get_awb(struct pwc_device *pdev) { unsigned char buf; int ret; diff -Nudr -U3 -x pwc-if.c pwc-10.0.7a/pwc.h pwc-10.0.7a-mod/pwc.h --- pwc-10.0.7a/pwc.h 2005-04-10 07:30:09.000000000 +0100 +++ pwc-10.0.7a-mod/pwc.h 2005-09-01 13:37:40.677240032 +0100 @@ -96,7 +96,9 @@ /* Absolute maximum number of buffers available for mmap() */ #define MAX_IMAGES 10 +#ifndef V4L2_PIX_FMT_PWC1 #define V4L2_PIX_FMT_PWC1 v4l2_fourcc('P','W','C',1) +#endif #define V4L2_PIX_FMT_PWC23 v4l2_fourcc('P','W','C',23) /* The following structures were based on cpia.h. Why reinvent the wheel? :-) */ @@ -272,6 +274,17 @@ extern int pwc_save_user(struct pwc_device *pdev); extern int pwc_restore_factory(struct pwc_device *pdev); +/* exported for use by v4l2 controls */ +extern int pwc_get_red_gain(struct pwc_device *pdev, int *value); +extern int pwc_set_red_gain(struct pwc_device *pdev, int value); +extern int pwc_get_blue_gain(struct pwc_device *pdev, int *value); +extern int pwc_set_blue_gain(struct pwc_device *pdev, int value); +extern int pwc_get_awb(struct pwc_device *pdev); +extern int pwc_set_awb(struct pwc_device *pdev, int mode); +extern int pwc_set_agc(struct pwc_device *pdev, int mode, int value); +extern int pwc_get_agc(struct pwc_device *pdev, int *value); +extern int pwc_set_shutter_speed(struct pwc_device *pdev, int mode, int value); + /* Power down or up the camera; not supported by all models */ extern int pwc_camera_power(struct pwc_device *pdev, int power); diff -Nudr -U3 -x pwc-if.c pwc-10.0.7a/pwc-v4l.c pwc-10.0.7a-mod/pwc-v4l.c --- pwc-10.0.7a/pwc-v4l.c 2005-04-10 07:04:59.000000000 +0100 +++ pwc-10.0.7a-mod/pwc-v4l.c 2005-09-01 13:36:47.455330992 +0100 @@ -74,7 +74,6 @@ .step = 1, .default_value = 0, }, -#if 0 { .id = V4L2_CID_RED_BALANCE, .type = V4L2_CTRL_TYPE_INTEGER, @@ -102,7 +101,33 @@ .step = 1, .default_value = 0, }, -#endif + { + .id = V4L2_CID_EXPOSURE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Shutter Speed (Exposure)", + .minimum = 1, + .maximum = 256, + .step = 1, + .default_value = 200, + }, + { + .id = V4L2_CID_AUTOGAIN, + .type = V4L2_CTRL_TYPE_BOOLEAN, + .name = "Auto Gain Enabled", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 1, + }, + { + .id = V4L2_CID_GAIN, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Gain Level", + .minimum = 0, + .maximum = 256, + .step = 1, + .default_value = 0, + }, #if XAWTV_HAS_BEEN_FIXED { .id = V4L2_CID_PRIVATE_SAVE_USER, @@ -563,6 +588,7 @@ case VIDIOC_G_CTRL: { struct v4l2_control *c = arg; + int ret; switch (c->id) { @@ -591,16 +617,15 @@ if (c->value<0) return -EINVAL; return 0; -#if 0 case V4L2_CID_RED_BALANCE: - ret = pwc_get_red_gain(pdev, c->value); + ret = pwc_get_red_gain(pdev, &c->value); printk("pwc: V4L2_CID_RED_BALANCE()=%d\n",c->value); if (ret<0) return -EINVAL; c->value >>= 8; return 0; case V4L2_CID_BLUE_BALANCE: - ret = pwc_get_blue_gain(pdev, c->value); + ret = pwc_get_blue_gain(pdev, &c->value); printk("pwc: V4L2_CID_BLUE_BALANCE()=%d\n",c->value); if (ret<0) return -EINVAL; @@ -613,7 +638,15 @@ return -EINVAL; c->value = (ret == PWC_WB_MANUAL)?0:1; return 0; -#endif + case V4L2_CID_GAIN: + ret = pwc_get_agc(pdev, &c->value); + printk("pwc: V4L2_CID_GAIN()=%d\n",c->value); + if (ret<0) + return -EINVAL; + c->value >>= 8; + return 0; + case V4L2_CID_AUTOGAIN: + case V4L2_CID_EXPOSURE: case V4L2_CID_PRIVATE_SAVE_USER: case V4L2_CID_PRIVATE_RESTORE_USER: case V4L2_CID_PRIVATE_RESTORE_FACTORY: @@ -623,22 +656,79 @@ } case VIDIOC_S_CTRL: { - struct v4l2_queryctrl *c = arg; + struct v4l2_control *c = arg; + int ret; switch (c->id) { + case V4L2_CID_BRIGHTNESS: + c->value <<= 8; + ret = pwc_set_brightness(pdev, c->value); + if (ret<0) + return -EINVAL; + return 0; + case V4L2_CID_CONTRAST: + c->value <<= 8; + ret = pwc_set_contrast(pdev, c->value); + if (ret<0) + return -EINVAL; + return 0; + case V4L2_CID_GAMMA: + c->value <<= 8; + ret = pwc_set_gamma(pdev, c->value); + if (ret<0) + return -EINVAL; + return 0; + case V4L2_CID_RED_BALANCE: + c->value <<= 8; + ret = pwc_set_red_gain(pdev, c->value); + if (ret<0) + return -EINVAL; + return 0; + case V4L2_CID_BLUE_BALANCE: + c->value <<= 8; + ret = pwc_set_blue_gain(pdev, c->value); + if (ret<0) + return -EINVAL; + return 0; + case V4L2_CID_AUTO_WHITE_BALANCE: + c->value = (c->value == 0)?PWC_WB_MANUAL:PWC_WB_AUTO; + ret = pwc_set_awb(pdev, c->value); + if (ret<0) + return -EINVAL; + return 0; + case V4L2_CID_EXPOSURE: + c->value <<= 8; + ret = pwc_set_shutter_speed(pdev, 0, c->value); + if (ret<0) + return -EINVAL; + return 0; + case V4L2_CID_AUTOGAIN: + /* autogain off means nothing without a gain */ + if (c->value == 0) + return 0; + ret = pwc_set_agc(pdev, c->value, 0); + if (ret<0) + return -EINVAL; + return 0; + case V4L2_CID_GAIN: + c->value <<= 8; + ret = pwc_set_agc(pdev, 0, c->value); + if (ret<0) + return -EINVAL; + return 0; case V4L2_CID_PRIVATE_SAVE_USER: if (pwc_save_user(pdev)) - return -EINVAL; + return -EINVAL; return 0; case V4L2_CID_PRIVATE_RESTORE_USER: if (pwc_restore_user(pdev)) - return -EINVAL; + return -EINVAL; return 0; case V4L2_CID_PRIVATE_RESTORE_FACTORY: if (pwc_restore_factory(pdev)) - return -EINVAL; - return 0; + return -EINVAL; + return 0; } return -EINVAL; }