📄 pwc-ctrl.c
字号:
if (value < 0) value = 0; if (value > 0xffff) value = 0xffff; buf = (value >> 9) & 0x7f; return usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0), SET_LUM_CTL, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, BRIGHTNESS_FORMATTER, pdev->vcinterface, &buf, 1, HZ / 2);}/* CONTRAST */int pwc_get_contrast(struct pwc_device *pdev){ char buf; int ret; ret = usb_control_msg(pdev->udev, usb_rcvctrlpipe(pdev->udev, 0), GET_LUM_CTL, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, CONTRAST_FORMATTER, pdev->vcinterface, &buf, 1, HZ / 2); if (ret < 0) return ret; return buf << 10;}int pwc_set_contrast(struct pwc_device *pdev, int value){ char buf; if (value < 0) value = 0; if (value > 0xffff) value = 0xffff; buf = (value >> 10) & 0x3f; return usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0), SET_LUM_CTL, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, CONTRAST_FORMATTER, pdev->vcinterface, &buf, 1, HZ / 2);}/* GAMMA */int pwc_get_gamma(struct pwc_device *pdev){ char buf; int ret; ret = usb_control_msg(pdev->udev, usb_rcvctrlpipe(pdev->udev, 0), GET_LUM_CTL, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, GAMMA_FORMATTER, pdev->vcinterface, &buf, 1, HZ / 2); if (ret < 0) return ret; return buf << 11;}int pwc_set_gamma(struct pwc_device *pdev, int value){ char buf; if (value < 0) value = 0; if (value > 0xffff) value = 0xffff; buf = (value >> 11) & 0x1f; return usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0), SET_LUM_CTL, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, GAMMA_FORMATTER, pdev->vcinterface, &buf, 1, HZ / 2);}/* SATURATION */int pwc_get_saturation(struct pwc_device *pdev){ char buf; int ret; if (pdev->type < 675) return -1; ret = usb_control_msg(pdev->udev, usb_rcvctrlpipe(pdev->udev, 0), GET_CHROM_CTL, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, pdev->type < 730 ? SATURATION_MODE_FORMATTER2 : SATURATION_MODE_FORMATTER1, pdev->vcinterface, &buf, 1, HZ / 2); if (ret < 0) return ret; return 32768 + buf * 327;}int pwc_set_saturation(struct pwc_device *pdev, int value){ char buf; if (pdev->type < 675) return -EINVAL; if (value < 0) value = 0; if (value > 0xffff) value = 0xffff; /* saturation ranges from -100 to +100 */ buf = (value - 32768) / 327; return usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0), SET_CHROM_CTL, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, pdev->type < 730 ? SATURATION_MODE_FORMATTER2 : SATURATION_MODE_FORMATTER1, pdev->vcinterface, &buf, 1, HZ / 2);}/* AGC */static inline int pwc_set_agc(struct pwc_device *pdev, int mode, int value){ char buf; int ret; if (mode) buf = 0x0; /* auto */ else buf = 0xff; /* fixed */ ret = usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0), SET_LUM_CTL, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, AGC_MODE_FORMATTER, pdev->vcinterface, &buf, 1, HZ / 2); if (!mode && ret >= 0) { if (value < 0) value = 0; if (value > 0xffff) value = 0xffff; buf = (value >> 10) & 0x3F; ret = usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0), SET_LUM_CTL, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, PRESET_AGC_FORMATTER, pdev->vcinterface, &buf, 1, HZ / 2); } if (ret < 0) return ret; return 0;}static inline int pwc_get_agc(struct pwc_device *pdev, int *value){ unsigned char buf; int ret; ret = usb_control_msg(pdev->udev, usb_rcvctrlpipe(pdev->udev, 0), GET_LUM_CTL, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, AGC_MODE_FORMATTER, pdev->vcinterface, &buf, 1, HZ / 2); if (ret < 0) return ret; if (buf != 0) { /* fixed */ ret = usb_control_msg(pdev->udev, usb_rcvctrlpipe(pdev->udev, 0), GET_LUM_CTL, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, PRESET_AGC_FORMATTER, pdev->vcinterface, &buf, 1, HZ / 2); if (ret < 0) return ret; if (buf > 0x3F) buf = 0x3F; *value = (buf << 10); } else { /* auto */ ret = usb_control_msg(pdev->udev, usb_rcvctrlpipe(pdev->udev, 0), GET_STATUS_CTL, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, READ_AGC_FORMATTER, pdev->vcinterface, &buf, 1, HZ / 2); if (ret < 0) return ret; /* Gah... this value ranges from 0x00 ... 0x9F */ if (buf > 0x9F) buf = 0x9F; *value = -(48 + buf * 409); } return 0;}static inline int pwc_set_shutter_speed(struct pwc_device *pdev, int mode, int value){ char buf[2]; int speed, ret; if (mode) buf[0] = 0x0; /* auto */ else buf[0] = 0xff; /* fixed */ ret = usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0), SET_LUM_CTL, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, SHUTTER_MODE_FORMATTER, pdev->vcinterface, buf, 1, HZ / 2); if (!mode && ret >= 0) { if (value < 0) value = 0; if (value > 0xffff) value = 0xffff; switch(pdev->type) { case 675: case 680: case 690: /* speed ranges from 0x0 to 0x290 (656) */ speed = (value / 100); buf[1] = speed >> 8; buf[0] = speed & 0xff; break; case 730: case 740: case 750: /* speed seems to range from 0x0 to 0xff */ buf[1] = 0; buf[0] = value >> 8; break; } ret = usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0), SET_LUM_CTL, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, PRESET_SHUTTER_FORMATTER, pdev->vcinterface, &buf, 2, HZ / 2); } return ret;} /* POWER */int pwc_camera_power(struct pwc_device *pdev, int power){ char buf; if (pdev->type < 675 || (pdev->type < 730 && pdev->release < 6)) return 0; /* Not supported by Nala or Timon < release 6 */ if (power) buf = 0x00; /* active */ else buf = 0xFF; /* power save */ return usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0), SET_STATUS_CTL, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, SET_POWER_SAVE_MODE_FORMATTER, pdev->vcinterface, &buf, 1, HZ / 2);}/* private calls */static inline int pwc_restore_user(struct pwc_device *pdev){ return usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0), SET_STATUS_CTL, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, RESTORE_USER_DEFAULTS_FORMATTER, pdev->vcinterface, NULL, 0, HZ / 2);}static inline int pwc_save_user(struct pwc_device *pdev){ return usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0), SET_STATUS_CTL, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, SAVE_USER_DEFAULTS_FORMATTER, pdev->vcinterface, NULL, 0, HZ / 2);}static inline int pwc_restore_factory(struct pwc_device *pdev){ return usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0), SET_STATUS_CTL, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, RESTORE_FACTORY_DEFAULTS_FORMATTER, pdev->vcinterface, NULL, 0, HZ / 2);} /* ************************************************* */ /* Patch by Alvarado: (not in the original version */ /* * the camera recognizes modes from 0 to 4: * * 00: indoor (incandescant lighting) * 01: outdoor (sunlight) * 02: fluorescent lighting * 03: manual * 04: auto */ static inline int pwc_set_awb(struct pwc_device *pdev, int mode){ char buf; int ret; if (mode < 0) mode = 0; if (mode > 4) mode = 4; buf = mode & 0x07; /* just the lowest three bits */ ret = usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0), SET_CHROM_CTL, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, WB_MODE_FORMATTER, pdev->vcinterface, &buf, 1, HZ / 2); if (ret < 0) return ret; return 0;}static inline int pwc_get_awb(struct pwc_device *pdev){ unsigned char buf; int ret; ret = usb_control_msg(pdev->udev, usb_rcvctrlpipe(pdev->udev, 0), GET_CHROM_CTL, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, WB_MODE_FORMATTER, pdev->vcinterface, &buf, 1, HZ / 2); if (ret < 0) return ret; return buf;}static inline int pwc_set_red_gain(struct pwc_device *pdev, int value){ unsigned char buf; if (value < 0) value = 0; if (value > 0xffff) value = 0xffff; /* only the msb are considered */ buf = value >> 8; return usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0), SET_CHROM_CTL, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, PRESET_MANUAL_RED_GAIN_FORMATTER, pdev->vcinterface, &buf, 1, HZ / 2);}static inline int pwc_get_red_gain(struct pwc_device *pdev){ unsigned char buf; int ret; ret = usb_control_msg(pdev->udev, usb_rcvctrlpipe(pdev->udev, 0), GET_CHROM_CTL, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, PRESET_MANUAL_RED_GAIN_FORMATTER, pdev->vcinterface, &buf, 1, HZ / 2); if (ret < 0) return ret; return (buf << 8);}static inline int pwc_set_blue_gain(struct pwc_device *pdev, int value){ unsigned char buf; if (value < 0) value = 0; if (value > 0xffff) value = 0xffff; /* linear mapping of 0..0xffff to -0x80..0x7f */ buf = (value >> 8); return usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0), SET_CHROM_CTL, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, PRESET_MANUAL_BLUE_GAIN_FORMATTER, pdev->vcinterface, &buf, 1, HZ / 2);}static inline int pwc_get_blue_gain(struct pwc_device *pdev){ unsigned char buf; int ret; ret = usb_control_msg(pdev->udev, usb_rcvctrlpipe(pdev->udev, 0), GET_CHROM_CTL, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, PRESET_MANUAL_BLUE_GAIN_FORMATTER, pdev->vcinterface, &buf, 1, HZ / 2); if (ret < 0) return ret; return (buf << 8);}/* The following two functions are different, since they only read the internal red/blue gains, which may be different from the manual gains set or read above. */ static inline int pwc_read_red_gain(struct pwc_device *pdev){ unsigned char buf; int ret; ret = usb_control_msg(pdev->udev, usb_rcvctrlpipe(pdev->udev, 0), GET_STATUS_CTL, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, READ_RED_GAIN_FORMATTER, pdev->vcinterface, &buf, 1, HZ / 2); if (ret < 0) return ret; return (buf << 8);}static inline int pwc_read_blue_gain(struct pwc_device *pdev){ unsigned char buf; int ret; ret = usb_control_msg(pdev->udev, usb_rcvctrlpipe(pdev->udev, 0), GET_STATUS_CTL, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, READ_BLUE_GAIN_FORMATTER, pdev->vcinterface, &buf, 1, HZ / 2); if (ret < 0) return ret; return (buf << 8);}static inline int pwc_set_wb_speed(struct pwc_device *pdev, int speed){ unsigned char buf; /* useful range is 0x01..0x20 */ buf = speed / 0x7f0; return usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0), SET_CHROM_CTL, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, AWB_CONTROL_SPEED_FORMATTER, pdev->vcinterface, &buf, 1, HZ / 2);}static inline int pwc_get_wb_speed(struct pwc_device *pdev){ unsigned char buf; int ret; ret = usb_control_msg(pdev->udev, usb_rcvctrlpipe(pdev->udev, 0), GET_CHROM_CTL, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, AWB_CONTROL_SPEED_FORMATTER, pdev->vcinterface, &buf, 1, HZ / 2); if (ret < 0) return ret; return (buf * 0x7f0);}static inline int pwc_set_wb_delay(struct pwc_device *pdev, int delay){ unsigned char buf; /* useful range is 0x01..0x3F */ buf = (delay >> 10); return usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0), SET_CHROM_CTL, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, AWB_CONTROL_DELAY_FORMATTER, pdev->vcinterface, &buf, 1, HZ / 2);}static inline int pwc_get_wb_delay(struct pwc_device *pdev){ unsigned char buf; int ret; ret = usb_control_msg(pdev->udev, usb_rcvctrlpipe(pdev->udev, 0),
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -