📄 pwc-ctrl.c
字号:
GET_CHROM_CTL, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, AWB_CONTROL_DELAY_FORMATTER, pdev->vcinterface, &buf, 1, HZ / 2); if (ret < 0) return ret; return (buf << 10);}int pwc_set_leds(struct pwc_device *pdev, int on_value, int off_value){ unsigned char buf[2]; if (pdev->type < 730) return 0; on_value /= 100; off_value /= 100; if (on_value < 0) on_value = 0; if (on_value > 0xff) on_value = 0xff; if (off_value < 0) off_value = 0; if (off_value > 0xff) off_value = 0xff; buf[0] = on_value; buf[1] = off_value; return usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0), SET_STATUS_CTL, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, LED_FORMATTER, pdev->vcinterface, &buf, 2, HZ / 2);}int pwc_get_leds(struct pwc_device *pdev, int *on_value, int *off_value){ unsigned char buf[2]; int ret; if (pdev->type < 730) { *on_value = -1; *off_value = -1; return 0; } ret = usb_control_msg(pdev->udev, usb_rcvctrlpipe(pdev->udev, 0), GET_STATUS_CTL, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, LED_FORMATTER, pdev->vcinterface, &buf, 2, HZ / 2); if (ret < 0) return ret; *on_value = buf[0] * 100; *off_value = buf[1] * 100; return 0;}static inline int pwc_set_contour(struct pwc_device *pdev, int contour){ unsigned char buf; int ret; if (contour < 0) buf = 0xff; /* auto contour on */ else buf = 0x0; /* auto contour off */ ret = usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0), SET_LUM_CTL, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, AUTO_CONTOUR_FORMATTER, pdev->vcinterface, &buf, 1, HZ / 2); if (ret < 0) return ret; if (contour < 0) return 0; if (contour > 0xffff) contour = 0xffff; buf = (contour >> 10); /* contour preset is [0..3f] */ ret = usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0), SET_LUM_CTL, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, PRESET_CONTOUR_FORMATTER, pdev->vcinterface, &buf, 1, HZ / 2); if (ret < 0) return ret; return 0;}static inline int pwc_get_contour(struct pwc_device *pdev, int *contour){ 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, AUTO_CONTOUR_FORMATTER, pdev->vcinterface, &buf, 1, HZ / 2); if (ret < 0) return ret; if (buf == 0) { /* auto mode off, query current preset value */ ret = usb_control_msg(pdev->udev, usb_rcvctrlpipe(pdev->udev, 0), GET_LUM_CTL, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, PRESET_CONTOUR_FORMATTER, pdev->vcinterface, &buf, 1, HZ / 2); if (ret < 0) return ret; *contour = (buf << 10); } else *contour = -1; return 0;}static inline int pwc_set_backlight(struct pwc_device *pdev, int backlight){ unsigned char buf; if (backlight) buf = 0xff; else buf = 0x0; return usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0), SET_LUM_CTL, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, BACK_LIGHT_COMPENSATION_FORMATTER, pdev->vcinterface, &buf, 1, HZ / 2);}static inline int pwc_get_backlight(struct pwc_device *pdev){ int ret; unsigned char buf; ret = usb_control_msg(pdev->udev, usb_rcvctrlpipe(pdev->udev, 0), GET_LUM_CTL, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, BACK_LIGHT_COMPENSATION_FORMATTER, pdev->vcinterface, &buf, 1, HZ / 2); if (ret < 0) return ret; return buf;}static inline int pwc_set_flicker(struct pwc_device *pdev, int flicker){ unsigned char buf; if (flicker) buf = 0xff; else buf = 0x0; return SendControlMsg(SET_LUM_CTL, FLICKERLESS_MODE_FORMATTER, 1);}static inline int pwc_get_flicker(struct pwc_device *pdev){ int ret; unsigned char buf; ret = RecvControlMsg(SET_LUM_CTL, FLICKERLESS_MODE_FORMATTER, 1); if (ret < 0) return ret; return buf;}static inline int pwc_set_dynamic_noise(struct pwc_device *pdev, int noise){ unsigned char buf; if (noise < 0) noise = 0; if (noise > 3) noise = 3; buf = noise; return SendControlMsg(SET_LUM_CTL, DYNAMIC_NOISE_CONTROL_FORMATTER, 1);}static inline int pwc_get_dynamic_noise(struct pwc_device *pdev){ int ret; unsigned char buf; ret = RecvControlMsg(SET_LUM_CTL, DYNAMIC_NOISE_CONTROL_FORMATTER, 1); if (ret < 0) return ret;Debug("pwc_get_dynamic_noise = %d\n", buf); return buf;}int pwc_get_cmos_sensor(struct pwc_device *pdev){ unsigned char buf; int ret = -1, request; if (pdev->type < 675) request = SENSOR_TYPE_FORMATTER1; else if (pdev->type < 730) return -1; /* The Vesta series doesn't have this call */ else request = SENSOR_TYPE_FORMATTER2; ret = usb_control_msg(pdev->udev, usb_rcvctrlpipe(pdev->udev, 0), GET_STATUS_CTL, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, request, pdev->vcinterface, &buf, 1, HZ / 2); if (ret < 0) return ret; if (pdev->type < 675) return buf | 0x100; else return buf;} /* End of Add-Ons */ /* ************************************************* */int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg){ int ret = 0; switch(cmd) { case VIDIOCPWCRUSER: { if (pwc_restore_user(pdev)) ret = -EINVAL; break; } case VIDIOCPWCSUSER: { if (pwc_save_user(pdev)) ret = -EINVAL; break; } case VIDIOCPWCFACTORY: { if (pwc_restore_factory(pdev)) ret = -EINVAL; break; } case VIDIOCPWCSCQUAL: { int qual; if (copy_from_user(&qual, arg, sizeof(int))) ret = -EFAULT; else { if (qual < 0 || qual > 3) ret = -EINVAL; else ret = pwc_try_video_mode(pdev, pdev->view.x, pdev->view.y, pdev->vframes, qual, pdev->vsnapshot); if (ret >= 0) pdev->vcompression = qual; } break; } case VIDIOCPWCGCQUAL: { if (copy_to_user(arg, &pdev->vcompression, sizeof(int))) ret = -EFAULT; break; } case VIDIOCPWCPROBE: { struct pwc_probe probe; strcpy(probe.name, pdev->vdev->name); probe.type = pdev->type; if (copy_to_user(arg, &probe, sizeof(probe))) ret = -EFAULT; break; } case VIDIOCPWCSAGC: { int agc; if (copy_from_user(&agc, arg, sizeof(agc))) ret = -EFAULT; else { if (pwc_set_agc(pdev, agc < 0 ? 1 : 0, agc)) ret = -EINVAL; } break; } case VIDIOCPWCGAGC: { int agc; if (pwc_get_agc(pdev, &agc)) ret = -EINVAL; else if (copy_to_user(arg, &agc, sizeof(agc))) ret = -EFAULT; break; } case VIDIOCPWCSSHUTTER: { int shutter_speed; if (copy_from_user(&shutter_speed, arg, sizeof(shutter_speed))) ret = -EFAULT; else ret = pwc_set_shutter_speed(pdev, shutter_speed < 0 ? 1 : 0, shutter_speed); break; } case VIDIOCPWCSAWB: { struct pwc_whitebalance wb; if (copy_from_user(&wb, arg, sizeof(wb))) ret = -EFAULT; else { ret = pwc_set_awb(pdev, wb.mode); if (ret >= 0 && wb.mode == PWC_WB_MANUAL) { pwc_set_red_gain(pdev, wb.manual_red); pwc_set_blue_gain(pdev, wb.manual_blue); } } break; } case VIDIOCPWCGAWB: { struct pwc_whitebalance wb; memset(&wb, 0, sizeof(wb)); wb.mode = pwc_get_awb(pdev); if (wb.mode < 0) ret = -EINVAL; else { if (wb.mode == PWC_WB_MANUAL) { wb.manual_red = pwc_get_red_gain(pdev); wb.manual_blue = pwc_get_blue_gain(pdev); } if (wb.mode == PWC_WB_AUTO) { wb.read_red = pwc_read_red_gain(pdev); wb.read_blue = pwc_read_blue_gain(pdev); } if (copy_to_user(arg, &wb, sizeof(wb))) ret= -EFAULT; } break; } case VIDIOCPWCSAWBSPEED: { struct pwc_wb_speed wbs; if (copy_from_user(&wbs, arg, sizeof(wbs))) ret = -EFAULT; else { if (wbs.control_speed > 0) { ret = pwc_set_wb_speed(pdev, wbs.control_speed); } if (wbs.control_delay > 0) { ret = pwc_set_wb_delay(pdev, wbs.control_delay); } } break; } case VIDIOCPWCGAWBSPEED: { struct pwc_wb_speed wbs; ret = pwc_get_wb_speed(pdev); if (ret < 0) break; wbs.control_speed = ret; ret = pwc_get_wb_delay(pdev); if (ret < 0) break; wbs.control_delay = ret; if (copy_to_user(arg, &wbs, sizeof(wbs))) ret = -EFAULT; break; } case VIDIOCPWCSLED: { struct pwc_leds leds; if (copy_from_user(&leds, arg, sizeof(leds))) ret = -EFAULT; else ret = pwc_set_leds(pdev, leds.led_on, leds.led_off); break; } case VIDIOCPWCGLED: { struct pwc_leds leds; ret = pwc_get_leds(pdev, &leds.led_on, &leds.led_off); if (ret < 0) break; if (copy_to_user(arg, &leds, sizeof(leds))) ret = -EFAULT; break; } case VIDIOCPWCSCONTOUR: { int contour; if (copy_from_user(&contour, arg, sizeof(contour))) ret = -EFAULT; else ret = pwc_set_contour(pdev, contour); break; } case VIDIOCPWCGCONTOUR: { int contour; ret = pwc_get_contour(pdev, &contour); if (ret < 0) break; if (copy_to_user(arg, &contour, sizeof(contour))) ret = -EFAULT; break; } case VIDIOCPWCSBACKLIGHT: { int backlight; if (copy_from_user(&backlight, arg, sizeof(backlight))) ret = -EFAULT; else ret = pwc_set_backlight(pdev, backlight); break; } case VIDIOCPWCGBACKLIGHT: { ret = pwc_get_backlight(pdev); if (ret < 0) break; if (copy_to_user(arg, &ret, sizeof(ret))) ret = -EFAULT; break; } case VIDIOCPWCSFLICKER: { int flicker; if (copy_from_user(&flicker, arg, sizeof(flicker))) ret = -EFAULT; else ret = pwc_set_flicker(pdev, flicker); break; } case VIDIOCPWCGFLICKER: { ret = pwc_get_flicker(pdev); if (ret < 0) break; if (copy_to_user(arg, &ret, sizeof(ret))) ret = -EFAULT; break; } case VIDIOCPWCSDYNNOISE: { int dynnoise; if (copy_from_user(&dynnoise, arg, sizeof(dynnoise))) ret = -EFAULT; else ret = pwc_set_dynamic_noise(pdev, dynnoise); break; } case VIDIOCPWCGDYNNOISE: { ret = pwc_get_dynamic_noise(pdev); if (ret < 0) break; if (copy_to_user(arg, &ret, sizeof(ret))) ret = -EFAULT; break; } default: ret = -ENOIOCTLCMD; break; } if (ret > 0) return 0; return ret;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -