From 1516524ff299d803ff530495fd66b514ec962f75 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sat, 31 Dec 2011 08:14:20 -0300 Subject: [media] pwc: Remove driver specific sysfs interface Setting pan/tilt should be done with v4l2 controls, like with other cams. The button is available as a standard input device Signed-off-by: Hans de Goede Signed-off-by: Mauro Carvalho Chehab --- Documentation/feature-removal-schedule.txt | 8 -------- 1 file changed, 8 deletions(-) (limited to 'Documentation/feature-removal-schedule.txt') diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt index 3d849122b5b1..11b925ca52eb 100644 --- a/Documentation/feature-removal-schedule.txt +++ b/Documentation/feature-removal-schedule.txt @@ -469,14 +469,6 @@ Who: Hans de Goede ---------------------------- -What: Driver specific sysfs API in the pwc driver -When: 3.3 -Why: Setting pan/tilt should be done with v4l2 controls, like with other - cams. The button is available as a standard input device -Who: Hans de Goede - ----------------------------- - What: Driver specific use of pixfmt.priv in the pwc driver When: 3.3 Why: The .priv field never was intended for this, setting a framerate is -- cgit v1.2.3 From 115f418bfa7575fbd1422d7fd274a2425260beb2 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sat, 31 Dec 2011 08:47:07 -0300 Subject: [media] pwc: Remove driver specific use of pixfmt.priv in the pwc driver The .priv field never was intended for this, setting a framerate is support using the standardized S_PARM ioctl. Signed-off-by: Hans de Goede Signed-off-by: Mauro Carvalho Chehab --- Documentation/feature-removal-schedule.txt | 8 -------- drivers/media/video/pwc/pwc-v4l.c | 23 ++++++----------------- 2 files changed, 6 insertions(+), 25 deletions(-) (limited to 'Documentation/feature-removal-schedule.txt') diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt index 11b925ca52eb..b7d96e148393 100644 --- a/Documentation/feature-removal-schedule.txt +++ b/Documentation/feature-removal-schedule.txt @@ -469,14 +469,6 @@ Who: Hans de Goede ---------------------------- -What: Driver specific use of pixfmt.priv in the pwc driver -When: 3.3 -Why: The .priv field never was intended for this, setting a framerate is - support using the standardized S_PARM ioctl -Who: Hans de Goede - ----------------------------- - What: Software emulation of arbritary resolutions in the pwc driver When: 3.3 Why: The pwc driver claims to support any resolution between 160x120 diff --git a/drivers/media/video/pwc/pwc-v4l.c b/drivers/media/video/pwc/pwc-v4l.c index 566b09c79802..8b862b6916f6 100644 --- a/drivers/media/video/pwc/pwc-v4l.c +++ b/drivers/media/video/pwc/pwc-v4l.c @@ -473,7 +473,7 @@ static int pwc_vidioc_try_fmt(struct pwc_device *pdev, struct v4l2_format *f) static int pwc_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f) { struct pwc_device *pdev = video_drvdata(file); - int ret, fps, snapshot, compression, pixelformat; + int ret, pixelformat; if (pwc_test_n_set_capt_file(pdev, file)) return -EBUSY; @@ -483,16 +483,6 @@ static int pwc_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f) return ret; pixelformat = f->fmt.pix.pixelformat; - compression = pdev->vcompression; - snapshot = 0; - fps = pdev->vframes; - if (f->fmt.pix.priv) { - compression = (f->fmt.pix.priv & PWC_QLT_MASK) >> PWC_QLT_SHIFT; - snapshot = !!(f->fmt.pix.priv & PWC_FPS_SNAPSHOT); - fps = (f->fmt.pix.priv & PWC_FPS_FRMASK) >> PWC_FPS_SHIFT; - if (fps == 0) - fps = pdev->vframes; - } if (pixelformat != V4L2_PIX_FMT_YUV420 && pixelformat != V4L2_PIX_FMT_PWC1 && @@ -511,9 +501,9 @@ static int pwc_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f) } PWC_DEBUG_IOCTL("Trying to set format to: width=%d height=%d fps=%d " - "compression=%d snapshot=%d format=%c%c%c%c\n", - f->fmt.pix.width, f->fmt.pix.height, fps, - compression, snapshot, + "compression=%d format=%c%c%c%c\n", + f->fmt.pix.width, f->fmt.pix.height, pdev->vframes, + pdev->vcompression, (pixelformat)&255, (pixelformat>>8)&255, (pixelformat>>16)&255, @@ -522,9 +512,8 @@ static int pwc_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f) ret = pwc_set_video_mode(pdev, f->fmt.pix.width, f->fmt.pix.height, - fps, - compression, - snapshot); + pdev->vframes, + pdev->vcompression, 0); PWC_DEBUG_IOCTL("pwc_set_video_mode(), return=%d\n", ret); -- cgit v1.2.3 From a08d2c727153dc6cea1d5d54a43fd7d69c1467c3 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sat, 31 Dec 2011 07:45:39 -0300 Subject: [media] pwc: Remove driver specific ioctls This stems from the v4l1 era, with v4l2 everything can be done with standardized v4l2 API calls. Signed-off-by: Hans de Goede Signed-off-by: Mauro Carvalho Chehab --- Documentation/feature-removal-schedule.txt | 9 - drivers/media/video/pwc/pwc-ctrl.c | 571 ----------------------------- drivers/media/video/pwc/pwc-dec23.c | 1 - drivers/media/video/pwc/pwc-if.c | 10 - drivers/media/video/pwc/pwc-kiara.h | 2 +- drivers/media/video/pwc/pwc-timon.h | 2 +- drivers/media/video/pwc/pwc-v4l.c | 12 - drivers/media/video/pwc/pwc.h | 36 +- include/media/pwc-ioctl.h | 323 ---------------- 9 files changed, 26 insertions(+), 940 deletions(-) delete mode 100644 include/media/pwc-ioctl.h (limited to 'Documentation/feature-removal-schedule.txt') diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt index b7d96e148393..821e3c29ec83 100644 --- a/Documentation/feature-removal-schedule.txt +++ b/Documentation/feature-removal-schedule.txt @@ -460,15 +460,6 @@ Who: Jean Delvare ---------------------------- -What: Support for driver specific ioctls in the pwc driver (everything - defined in media/pwc-ioctl.h) -When: 3.3 -Why: This stems from the v4l1 era, with v4l2 everything can be done with - standardized v4l2 API calls -Who: Hans de Goede - ----------------------------- - What: Software emulation of arbritary resolutions in the pwc driver When: 3.3 Why: The pwc driver claims to support any resolution between 160x120 diff --git a/drivers/media/video/pwc/pwc-ctrl.c b/drivers/media/video/pwc/pwc-ctrl.c index 2cf77001804d..684b7c50eea9 100644 --- a/drivers/media/video/pwc/pwc-ctrl.c +++ b/drivers/media/video/pwc/pwc-ctrl.c @@ -604,136 +604,6 @@ int pwc_set_leds(struct pwc_device *pdev, int on_value, int off_value) return r; } -static 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 = recv_control_msg(pdev, - GET_STATUS_CTL, LED_FORMATTER, &buf, sizeof(buf)); - if (ret < 0) - return ret; - *on_value = buf[0] * 100; - *off_value = buf[1] * 100; - return 0; -} - -static int _pwc_mpt_reset(struct pwc_device *pdev, int flags) -{ - unsigned char buf; - int r; - - mutex_lock(&pdev->udevlock); - if (!pdev->udev) { - r = -ENODEV; - goto leave; - } - - buf = flags & 0x03; // only lower two bits are currently used - r = send_control_msg(pdev, - SET_MPT_CTL, PT_RESET_CONTROL_FORMATTER, &buf, sizeof(buf)); -leave: - mutex_unlock(&pdev->udevlock); - return r; -} - -int pwc_mpt_reset(struct pwc_device *pdev, int flags) -{ - int ret; - ret = _pwc_mpt_reset(pdev, flags); - if (ret >= 0) { - pdev->pan_angle = 0; - pdev->tilt_angle = 0; - } - return ret; -} - -static int _pwc_mpt_set_angle(struct pwc_device *pdev, int pan, int tilt) -{ - unsigned char buf[4]; - int r; - - mutex_lock(&pdev->udevlock); - if (!pdev->udev) { - r = -ENODEV; - goto leave; - } - - /* set new relative angle; angles are expressed in degrees * 100, - but cam as .5 degree resolution, hence divide by 200. Also - the angle must be multiplied by 64 before it's send to - the cam (??) - */ - pan = 64 * pan / 100; - tilt = -64 * tilt / 100; /* positive tilt is down, which is not what the user would expect */ - buf[0] = pan & 0xFF; - buf[1] = (pan >> 8) & 0xFF; - buf[2] = tilt & 0xFF; - buf[3] = (tilt >> 8) & 0xFF; - r = send_control_msg(pdev, - SET_MPT_CTL, PT_RELATIVE_CONTROL_FORMATTER, &buf, sizeof(buf)); -leave: - mutex_unlock(&pdev->udevlock); - return r; -} - -int pwc_mpt_set_angle(struct pwc_device *pdev, int pan, int tilt) -{ - int ret; - - /* check absolute ranges */ - if (pan < pdev->angle_range.pan_min || - pan > pdev->angle_range.pan_max || - tilt < pdev->angle_range.tilt_min || - tilt > pdev->angle_range.tilt_max) - return -ERANGE; - - /* go to relative range, check again */ - pan -= pdev->pan_angle; - tilt -= pdev->tilt_angle; - /* angles are specified in degrees * 100, thus the limit = 36000 */ - if (pan < -36000 || pan > 36000 || tilt < -36000 || tilt > 36000) - return -ERANGE; - - ret = _pwc_mpt_set_angle(pdev, pan, tilt); - if (ret >= 0) { - pdev->pan_angle += pan; - pdev->tilt_angle += tilt; - } - if (ret == -EPIPE) /* stall -> out of range */ - ret = -ERANGE; - return ret; -} - -static int pwc_mpt_get_status(struct pwc_device *pdev, struct pwc_mpt_status *status) -{ - int ret; - unsigned char buf[5]; - - mutex_lock(&pdev->udevlock); - if (!pdev->udev) { - ret = -ENODEV; - goto leave; - } - - ret = recv_control_msg(pdev, - GET_MPT_CTL, PT_STATUS_FORMATTER, &buf, sizeof(buf)); - if (ret < 0) - goto leave; - status->status = buf[0] & 0x7; // 3 bits are used for reporting - status->time_pan = (buf[1] << 8) + buf[2]; - status->time_tilt = (buf[3] << 8) + buf[4]; -leave: - mutex_unlock(&pdev->udevlock); - return ret; -} - #ifdef CONFIG_USB_PWC_DEBUG int pwc_get_cmos_sensor(struct pwc_device *pdev, int *sensor) { @@ -758,444 +628,3 @@ int pwc_get_cmos_sensor(struct pwc_device *pdev, int *sensor) return 0; } #endif - - /* End of Add-Ons */ - /* ************************************************* */ - -/* Linux 2.5.something and 2.6 pass direct pointers to arguments of - ioctl() calls. With 2.4, you have to do tedious copy_from_user() - and copy_to_user() calls. With these macros we circumvent this, - and let me maintain only one source file. The functionality is - exactly the same otherwise. - */ - -/* define local variable for arg */ -#define ARG_DEF(ARG_type, ARG_name)\ - ARG_type *ARG_name = arg; -/* copy arg to local variable */ -#define ARG_IN(ARG_name) /* nothing */ -/* argument itself (referenced) */ -#define ARGR(ARG_name) (*ARG_name) -/* argument address */ -#define ARGA(ARG_name) ARG_name -/* copy local variable to arg */ -#define ARG_OUT(ARG_name) /* nothing */ - -/* - * Our ctrls use native values, but the old custom pwc ioctl interface expects - * values from 0 - 65535, define 2 helper functions to scale things. */ -static int pwc_ioctl_g_ctrl(struct v4l2_ctrl *ctrl) -{ - return v4l2_ctrl_g_ctrl(ctrl) * 65535 / ctrl->maximum; -} - -static int pwc_ioctl_s_ctrl(struct v4l2_ctrl *ctrl, int val) -{ - return v4l2_ctrl_s_ctrl(ctrl, val * ctrl->maximum / 65535); -} - -long pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg) -{ - long ret = 0; - - switch(cmd) { - case VIDIOCPWCRUSER: - ret = v4l2_ctrl_s_ctrl(pdev->restore_user, 0); - break; - - case VIDIOCPWCSUSER: - ret = v4l2_ctrl_s_ctrl(pdev->save_user, 0); - break; - - case VIDIOCPWCFACTORY: - ret = v4l2_ctrl_s_ctrl(pdev->restore_factory, 0); - break; - - case VIDIOCPWCSCQUAL: - { - ARG_DEF(int, qual) - - mutex_lock(&pdev->udevlock); - if (!pdev->udev) { - ret = -ENODEV; - goto leave; - } - - if (pdev->iso_init) { - ret = -EBUSY; - goto leave; - } - - ARG_IN(qual) - if (ARGR(qual) < 0 || ARGR(qual) > 3) - ret = -EINVAL; - else - ret = pwc_set_video_mode(pdev, - pdev->view.x, pdev->view.y, - pdev->vframes, ARGR(qual)); -leave: - mutex_unlock(&pdev->udevlock); - break; - } - - case VIDIOCPWCGCQUAL: - { - ARG_DEF(int, qual) - - ARGR(qual) = pdev->vcompression; - ARG_OUT(qual) - break; - } - - case VIDIOCPWCPROBE: - { - ARG_DEF(struct pwc_probe, probe) - - strcpy(ARGR(probe).name, pdev->vdev.name); - ARGR(probe).type = pdev->type; - ARG_OUT(probe) - break; - } - - case VIDIOCPWCGSERIAL: - { - ARG_DEF(struct pwc_serial, serial) - - strcpy(ARGR(serial).serial, pdev->serial); - ARG_OUT(serial) - break; - } - - case VIDIOCPWCSAGC: - { - ARG_DEF(int, agc) - ARG_IN(agc) - ret = v4l2_ctrl_s_ctrl(pdev->autogain, ARGR(agc) < 0); - if (ret == 0 && ARGR(agc) >= 0) - ret = pwc_ioctl_s_ctrl(pdev->gain, ARGR(agc)); - break; - } - - case VIDIOCPWCGAGC: - { - ARG_DEF(int, agc) - if (v4l2_ctrl_g_ctrl(pdev->autogain)) - ARGR(agc) = -1; - else - ARGR(agc) = pwc_ioctl_g_ctrl(pdev->gain); - ARG_OUT(agc) - break; - } - - case VIDIOCPWCSSHUTTER: - { - ARG_DEF(int, shutter) - ARG_IN(shutter) - ret = v4l2_ctrl_s_ctrl(pdev->exposure_auto, - /* Menu idx 0 = auto, idx 1 = manual */ - ARGR(shutter) >= 0); - if (ret == 0 && ARGR(shutter) >= 0) - ret = pwc_ioctl_s_ctrl(pdev->exposure, ARGR(shutter)); - break; - } - - case VIDIOCPWCSAWB: - { - ARG_DEF(struct pwc_whitebalance, wb) - ARG_IN(wb) - ret = v4l2_ctrl_s_ctrl(pdev->auto_white_balance, - ARGR(wb).mode); - if (ret == 0 && ARGR(wb).mode == PWC_WB_MANUAL) - ret = pwc_ioctl_s_ctrl(pdev->red_balance, - ARGR(wb).manual_red); - if (ret == 0 && ARGR(wb).mode == PWC_WB_MANUAL) - ret = pwc_ioctl_s_ctrl(pdev->blue_balance, - ARGR(wb).manual_blue); - break; - } - - case VIDIOCPWCGAWB: - { - ARG_DEF(struct pwc_whitebalance, wb) - ARGR(wb).mode = v4l2_ctrl_g_ctrl(pdev->auto_white_balance); - ARGR(wb).manual_red = ARGR(wb).read_red = - pwc_ioctl_g_ctrl(pdev->red_balance); - ARGR(wb).manual_blue = ARGR(wb).read_blue = - pwc_ioctl_g_ctrl(pdev->blue_balance); - ARG_OUT(wb) - break; - } - - case VIDIOCPWCSAWBSPEED: - { - ARG_DEF(struct pwc_wb_speed, wbs) - - if (ARGR(wbs).control_speed > 0) { - ret = pwc_ioctl_s_ctrl(pdev->awb_speed, - ARGR(wbs).control_speed); - } - if (ret == 0 && ARGR(wbs).control_delay > 0) { - ret = pwc_ioctl_s_ctrl(pdev->awb_delay, - ARGR(wbs).control_delay); - } - break; - } - - case VIDIOCPWCGAWBSPEED: - { - ARG_DEF(struct pwc_wb_speed, wbs) - - ARGR(wbs).control_speed = v4l2_ctrl_g_ctrl(pdev->awb_speed); - ARGR(wbs).control_delay = v4l2_ctrl_g_ctrl(pdev->awb_delay); - ARG_OUT(wbs) - break; - } - - case VIDIOCPWCSLED: - { - ARG_DEF(struct pwc_leds, leds) - - mutex_lock(&pdev->udevlock); - if (!pdev->udev) { - ret = -ENODEV; - break; - } - - ARG_IN(leds) - ret = pwc_set_leds(pdev, ARGR(leds).led_on, ARGR(leds).led_off); - - mutex_unlock(&pdev->udevlock); - break; - } - - - case VIDIOCPWCGLED: - { - ARG_DEF(struct pwc_leds, leds) - - mutex_lock(&pdev->udevlock); - if (!pdev->udev) { - ret = -ENODEV; - break; - } - - ret = pwc_get_leds(pdev, &ARGR(leds).led_on, &ARGR(leds).led_off); - ARG_OUT(leds) - - mutex_unlock(&pdev->udevlock); - break; - } - - case VIDIOCPWCSCONTOUR: - { - ARG_DEF(int, contour) - ARG_IN(contour) - ret = v4l2_ctrl_s_ctrl(pdev->autocontour, ARGR(contour) < 0); - if (ret == 0 && ARGR(contour) >= 0) - ret = pwc_ioctl_s_ctrl(pdev->contour, ARGR(contour)); - break; - } - - case VIDIOCPWCGCONTOUR: - { - ARG_DEF(int, contour) - if (v4l2_ctrl_g_ctrl(pdev->autocontour)) - ARGR(contour) = -1; - else - ARGR(contour) = pwc_ioctl_g_ctrl(pdev->contour); - ARG_OUT(contour) - break; - } - - case VIDIOCPWCSBACKLIGHT: - { - ARG_DEF(int, backlight) - ARG_IN(backlight) - ret = v4l2_ctrl_s_ctrl(pdev->backlight, ARGR(backlight)); - break; - } - - case VIDIOCPWCGBACKLIGHT: - { - ARG_DEF(int, backlight) - ARGR(backlight) = v4l2_ctrl_g_ctrl(pdev->backlight); - ARG_OUT(backlight) - break; - } - - case VIDIOCPWCSFLICKER: - { - ARG_DEF(int, flicker) - ARG_IN(flicker) - ret = v4l2_ctrl_s_ctrl(pdev->flicker, ARGR(flicker)); - break; - } - - case VIDIOCPWCGFLICKER: - { - ARG_DEF(int, flicker) - ARGR(flicker) = v4l2_ctrl_g_ctrl(pdev->flicker); - ARG_OUT(flicker) - break; - } - - case VIDIOCPWCSDYNNOISE: - { - ARG_DEF(int, dynnoise) - ARG_IN(dynnoise) - ret = v4l2_ctrl_s_ctrl(pdev->noise_reduction, ARGR(dynnoise)); - break; - } - - case VIDIOCPWCGDYNNOISE: - { - ARG_DEF(int, dynnoise) - ARGR(dynnoise) = v4l2_ctrl_g_ctrl(pdev->noise_reduction); - ARG_OUT(dynnoise); - break; - } - - case VIDIOCPWCGREALSIZE: - { - ARG_DEF(struct pwc_imagesize, size) - - ARGR(size).width = pdev->image.x; - ARGR(size).height = pdev->image.y; - ARG_OUT(size) - break; - } - - case VIDIOCPWCMPTRESET: - { - if (pdev->features & FEATURE_MOTOR_PANTILT) - { - ARG_DEF(int, flags) - - ARG_IN(flags) - ret = pwc_mpt_reset(pdev, ARGR(flags)); - } - else - { - ret = -ENXIO; - } - break; - } - - case VIDIOCPWCMPTGRANGE: - { - if (pdev->features & FEATURE_MOTOR_PANTILT) - { - ARG_DEF(struct pwc_mpt_range, range) - - ARGR(range) = pdev->angle_range; - ARG_OUT(range) - } - else - { - ret = -ENXIO; - } - break; - } - - case VIDIOCPWCMPTSANGLE: - { - int new_pan, new_tilt; - - if (pdev->features & FEATURE_MOTOR_PANTILT) - { - ARG_DEF(struct pwc_mpt_angles, angles) - - ARG_IN(angles) - /* The camera can only set relative angles, so - do some calculations when getting an absolute angle . - */ - if (ARGR(angles).absolute) - { - new_pan = ARGR(angles).pan; - new_tilt = ARGR(angles).tilt; - } - else - { - new_pan = pdev->pan_angle + ARGR(angles).pan; - new_tilt = pdev->tilt_angle + ARGR(angles).tilt; - } - ret = pwc_mpt_set_angle(pdev, new_pan, new_tilt); - } - else - { - ret = -ENXIO; - } - break; - } - - case VIDIOCPWCMPTGANGLE: - { - - if (pdev->features & FEATURE_MOTOR_PANTILT) - { - ARG_DEF(struct pwc_mpt_angles, angles) - - ARGR(angles).absolute = 1; - ARGR(angles).pan = pdev->pan_angle; - ARGR(angles).tilt = pdev->tilt_angle; - ARG_OUT(angles) - } - else - { - ret = -ENXIO; - } - break; - } - - case VIDIOCPWCMPTSTATUS: - { - if (pdev->features & FEATURE_MOTOR_PANTILT) - { - ARG_DEF(struct pwc_mpt_status, status) - - ret = pwc_mpt_get_status(pdev, ARGA(status)); - ARG_OUT(status) - } - else - { - ret = -ENXIO; - } - break; - } - - case VIDIOCPWCGVIDCMD: - { - ARG_DEF(struct pwc_video_command, vcmd); - - ARGR(vcmd).type = pdev->type; - ARGR(vcmd).release = pdev->release; - ARGR(vcmd).command_len = pdev->cmd_len; - memcpy(&ARGR(vcmd).command_buf, pdev->cmd_buf, pdev->cmd_len); - ARGR(vcmd).bandlength = pdev->vbandlength; - ARGR(vcmd).frame_size = pdev->frame_size; - ARG_OUT(vcmd) - break; - } - /* - case VIDIOCPWCGVIDTABLE: - { - ARG_DEF(struct pwc_table_init_buffer, table); - ARGR(table).len = pdev->cmd_len; - memcpy(&ARGR(table).buffer, pdev->decompress_data, pdev->decompressor->table_size); - ARG_OUT(table) - break; - } - */ - - default: - ret = -ENOIOCTLCMD; - break; - } - - if (ret > 0) - return 0; - return ret; -} - - -/* vim: set cinoptions= formatoptions=croql cindent shiftwidth=8 tabstop=8: */ diff --git a/drivers/media/video/pwc/pwc-dec23.c b/drivers/media/video/pwc/pwc-dec23.c index bce3d9bfd035..e531f85460c1 100644 --- a/drivers/media/video/pwc/pwc-dec23.c +++ b/drivers/media/video/pwc/pwc-dec23.c @@ -27,7 +27,6 @@ #include "pwc-timon.h" #include "pwc-kiara.h" #include "pwc-dec23.h" -#include #include #include diff --git a/drivers/media/video/pwc/pwc-if.c b/drivers/media/video/pwc/pwc-if.c index a66f60cb8c3b..963b4a55ec75 100644 --- a/drivers/media/video/pwc/pwc-if.c +++ b/drivers/media/video/pwc/pwc-if.c @@ -1058,16 +1058,6 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id pdev->vframes = default_fps; strcpy(pdev->serial, serial_number); pdev->features = features; - if (vendor_id == 0x046D && product_id == 0x08B5) { - /* Logitech QuickCam Orbit - The ranges have been determined experimentally; they may differ from cam to cam. - Also, the exact ranges left-right and up-down are different for my cam - */ - pdev->angle_range.pan_min = -7000; - pdev->angle_range.pan_max = 7000; - pdev->angle_range.tilt_min = -3000; - pdev->angle_range.tilt_max = 2500; - } pwc_construct(pdev); /* set min/max sizes correct */ mutex_init(&pdev->capt_file_lock); diff --git a/drivers/media/video/pwc/pwc-kiara.h b/drivers/media/video/pwc/pwc-kiara.h index 047dad8c15f7..8e02b7ac2139 100644 --- a/drivers/media/video/pwc/pwc-kiara.h +++ b/drivers/media/video/pwc/pwc-kiara.h @@ -27,7 +27,7 @@ #ifndef PWC_KIARA_H #define PWC_KIARA_H -#include +#include "pwc.h" #define PWC_FPS_MAX_KIARA 6 diff --git a/drivers/media/video/pwc/pwc-timon.h b/drivers/media/video/pwc/pwc-timon.h index a6e22224c95f..270c5b9010f6 100644 --- a/drivers/media/video/pwc/pwc-timon.h +++ b/drivers/media/video/pwc/pwc-timon.h @@ -42,7 +42,7 @@ #ifndef PWC_TIMON_H #define PWC_TIMON_H -#include +#include "pwc.h" #define PWC_FPS_MAX_TIMON 6 diff --git a/drivers/media/video/pwc/pwc-v4l.c b/drivers/media/video/pwc/pwc-v4l.c index c4dc820b9dd7..87457b53f495 100644 --- a/drivers/media/video/pwc/pwc-v4l.c +++ b/drivers/media/video/pwc/pwc-v4l.c @@ -1122,14 +1122,6 @@ static int pwc_log_status(struct file *file, void *priv) return 0; } -static long pwc_default(struct file *file, void *fh, bool valid_prio, - int cmd, void *arg) -{ - struct pwc_device *pdev = video_drvdata(file); - - return pwc_ioctl(pdev, cmd, arg); -} - const struct v4l2_ioctl_ops pwc_ioctl_ops = { .vidioc_querycap = pwc_querycap, .vidioc_enum_input = pwc_enum_input, @@ -1148,8 +1140,4 @@ const struct v4l2_ioctl_ops pwc_ioctl_ops = { .vidioc_log_status = pwc_log_status, .vidioc_enum_framesizes = pwc_enum_framesizes, .vidioc_enum_frameintervals = pwc_enum_frameintervals, - .vidioc_default = pwc_default, }; - - -/* vim: set cino= formatoptions=croql cindent shiftwidth=8 tabstop=8: */ diff --git a/drivers/media/video/pwc/pwc.h b/drivers/media/video/pwc/pwc.h index ae0b7bf12e07..19c692c186fe 100644 --- a/drivers/media/video/pwc/pwc.h +++ b/drivers/media/video/pwc/pwc.h @@ -45,8 +45,6 @@ #include #endif -#include - /* Version block */ #define PWC_VERSION "10.0.15" #define PWC_NAME "pwc" @@ -189,6 +187,30 @@ #define PT_RESET_CONTROL_FORMATTER 0x02 #define PT_STATUS_FORMATTER 0x03 +/* Enumeration of image sizes */ +#define PSZ_SQCIF 0x00 +#define PSZ_QSIF 0x01 +#define PSZ_QCIF 0x02 +#define PSZ_SIF 0x03 +#define PSZ_CIF 0x04 +#define PSZ_VGA 0x05 +#define PSZ_MAX 6 + +struct pwc_raw_frame { + __le16 type; /* type of the webcam */ + __le16 vbandlength; /* Size of 4 lines compressed (used by the + decompressor) */ + __u8 cmd[4]; /* the four byte of the command (in case of + nala, only the first 3 bytes is filled) */ + __u8 rawframe[0]; /* frame_size = H / 4 * vbandlength */ +} __packed; + +/* structure for transferring x & y coordinates */ +struct pwc_coord { + int x, y; /* guess what */ + int size; /* size, or offset */ +}; + /* intermediate buffers with raw data from the USB cam */ struct pwc_frame_buf { @@ -269,11 +291,6 @@ struct pwc_device struct pwc_coord image, view; /* image and viewport size */ struct pwc_coord offset; /* offset of the viewport */ - /*** motorized pan/tilt feature */ - struct pwc_mpt_range angle_range; - int pan_angle; /* in degrees * 100 */ - int tilt_angle; /* absolute angle; 0,0 is home */ - #ifdef CONFIG_USB_PWC_INPUT_EVDEV struct input_dev *button_dev; /* webcam snapshot button input */ char button_phys[64]; @@ -357,8 +374,6 @@ void pwc_construct(struct pwc_device *pdev); extern int pwc_set_video_mode(struct pwc_device *pdev, int width, int height, int frames, int compression); extern unsigned int pwc_get_fps(struct pwc_device *pdev, unsigned int index, unsigned int size); -extern int pwc_mpt_reset(struct pwc_device *pdev, int flags); -extern int pwc_mpt_set_angle(struct pwc_device *pdev, int pan, int tilt); extern int pwc_set_leds(struct pwc_device *pdev, int on_value, int off_value); extern int pwc_get_cmos_sensor(struct pwc_device *pdev, int *sensor); extern int send_control_msg(struct pwc_device *pdev, @@ -377,9 +392,6 @@ int pwc_init_controls(struct pwc_device *pdev); /* Power down or up the camera; not supported by all models */ extern void pwc_camera_power(struct pwc_device *pdev, int power); -/* Private ioctl()s; see pwc-ioctl.h */ -extern long pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg); - extern const struct v4l2_ioctl_ops pwc_ioctl_ops; /** pwc-uncompress.c */ diff --git a/include/media/pwc-ioctl.h b/include/media/pwc-ioctl.h deleted file mode 100644 index 1ed1e616fe33..000000000000 --- a/include/media/pwc-ioctl.h +++ /dev/null @@ -1,323 +0,0 @@ -#ifndef PWC_IOCTL_H -#define PWC_IOCTL_H - -/* (C) 2001-2004 Nemosoft Unv. - (C) 2004-2006 Luc Saillard (luc@saillard.org) - - NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx - driver and thus may have bugs that are not present in the original version. - Please send bug reports and support requests to . - The decompression routines have been implemented by reverse-engineering the - Nemosoft binary pwcx module. Caveat emptor. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -/* This is pwc-ioctl.h belonging to PWC 10.0.10 - It contains structures and defines to communicate from user space - directly to the driver. - */ - -/* - Changes - 2001/08/03 Alvarado Added ioctl constants to access methods for - changing white balance and red/blue gains - 2002/12/15 G. H. Fernandez-Toribio VIDIOCGREALSIZE - 2003/12/13 Nemosft Unv. Some modifications to make interfacing to - PWCX easier - 2006/01/01 Luc Saillard Add raw format definition - */ - -/* These are private ioctl() commands, specific for the Philips webcams. - They contain functions not found in other webcams, and settings not - specified in the Video4Linux API. - - The #define names are built up like follows: - VIDIOC VIDeo IOCtl prefix - PWC Philps WebCam - G optional: Get - S optional: Set - ... the function - */ - -#include - -/* Enumeration of image sizes */ -#define PSZ_SQCIF 0x00 -#define PSZ_QSIF 0x01 -#define PSZ_QCIF 0x02 -#define PSZ_SIF 0x03 -#define PSZ_CIF 0x04 -#define PSZ_VGA 0x05 -#define PSZ_MAX 6 - - -/* The frame rate is encoded in the video_window.flags parameter using - the upper 16 bits, since some flags are defined nowadays. The following - defines provide a mask and shift to filter out this value. - This value can also be passing using the private flag when using v4l2 and - VIDIOC_S_FMT ioctl. - - In 'Snapshot' mode the camera freezes its automatic exposure and colour - balance controls. - */ -#define PWC_FPS_SHIFT 16 -#define PWC_FPS_MASK 0x00FF0000 -#define PWC_FPS_FRMASK 0x003F0000 -#define PWC_FPS_SNAPSHOT 0x00400000 -#define PWC_QLT_MASK 0x03000000 -#define PWC_QLT_SHIFT 24 - - -/* structure for transferring x & y coordinates */ -struct pwc_coord -{ - int x, y; /* guess what */ - int size; /* size, or offset */ -}; - - -/* Used with VIDIOCPWCPROBE */ -struct pwc_probe -{ - char name[32]; - int type; -}; - -struct pwc_serial -{ - char serial[30]; /* String with serial number. Contains terminating 0 */ -}; - -/* pwc_whitebalance.mode values */ -#define PWC_WB_INDOOR 0 -#define PWC_WB_OUTDOOR 1 -#define PWC_WB_FL 2 -#define PWC_WB_MANUAL 3 -#define PWC_WB_AUTO 4 - -/* Used with VIDIOCPWC[SG]AWB (Auto White Balance). - Set mode to one of the PWC_WB_* values above. - *red and *blue are the respective gains of these colour components inside - the camera; range 0..65535 - When 'mode' == PWC_WB_MANUAL, 'manual_red' and 'manual_blue' are set or read; - otherwise undefined. - 'read_red' and 'read_blue' are read-only. -*/ -struct pwc_whitebalance -{ - int mode; - int manual_red, manual_blue; /* R/W */ - int read_red, read_blue; /* R/O */ -}; - -/* - 'control_speed' and 'control_delay' are used in automatic whitebalance mode, - and tell the camera how fast it should react to changes in lighting, and - with how much delay. Valid values are 0..65535. -*/ -struct pwc_wb_speed -{ - int control_speed; - int control_delay; - -}; - -/* Used with VIDIOCPWC[SG]LED */ -struct pwc_leds -{ - int led_on; /* Led on-time; range = 0..25000 */ - int led_off; /* Led off-time; range = 0..25000 */ -}; - -/* Image size (used with GREALSIZE) */ -struct pwc_imagesize -{ - int width; - int height; -}; - -/* Defines and structures for Motorized Pan & Tilt */ -#define PWC_MPT_PAN 0x01 -#define PWC_MPT_TILT 0x02 -#define PWC_MPT_TIMEOUT 0x04 /* for status */ - -/* Set angles; when absolute != 0, the angle is absolute and the - driver calculates the relative offset for you. This can only - be used with VIDIOCPWCSANGLE; VIDIOCPWCGANGLE always returns - absolute angles. - */ -struct pwc_mpt_angles -{ - int absolute; /* write-only */ - int pan; /* degrees * 100 */ - int tilt; /* degress * 100 */ -}; - -/* Range of angles of the camera, both horizontally and vertically. - */ -struct pwc_mpt_range -{ - int pan_min, pan_max; /* degrees * 100 */ - int tilt_min, tilt_max; -}; - -struct pwc_mpt_status -{ - int status; - int time_pan; - int time_tilt; -}; - - -/* This is used for out-of-kernel decompression. With it, you can get - all the necessary information to initialize and use the decompressor - routines in standalone applications. - */ -struct pwc_video_command -{ - int type; /* camera type (645, 675, 730, etc.) */ - int release; /* release number */ - - int size; /* one of PSZ_* */ - int alternate; - int command_len; /* length of USB video command */ - unsigned char command_buf[13]; /* Actual USB video command */ - int bandlength; /* >0 = compressed */ - int frame_size; /* Size of one (un)compressed frame */ -}; - -/* Flags for PWCX subroutines. Not all modules honour all flags. */ -#define PWCX_FLAG_PLANAR 0x0001 -#define PWCX_FLAG_BAYER 0x0008 - - -/* IOCTL definitions */ - - /* Restore user settings */ -#define VIDIOCPWCRUSER _IO('v', 192) - /* Save user settings */ -#define VIDIOCPWCSUSER _IO('v', 193) - /* Restore factory settings */ -#define VIDIOCPWCFACTORY _IO('v', 194) - - /* You can manipulate the compression factor. A compression preference of 0 - means use uncompressed modes when available; 1 is low compression, 2 is - medium and 3 is high compression preferred. Of course, the higher the - compression, the lower the bandwidth used but more chance of artefacts - in the image. The driver automatically chooses a higher compression when - the preferred mode is not available. - */ - /* Set preferred compression quality (0 = uncompressed, 3 = highest compression) */ -#define VIDIOCPWCSCQUAL _IOW('v', 195, int) - /* Get preferred compression quality */ -#define VIDIOCPWCGCQUAL _IOR('v', 195, int) - - -/* Retrieve serial number of camera */ -#define VIDIOCPWCGSERIAL _IOR('v', 198, struct pwc_serial) - - /* This is a probe function; since so many devices are supported, it - becomes difficult to include all the names in programs that want to - check for the enhanced Philips stuff. So in stead, try this PROBE; - it returns a structure with the original name, and the corresponding - Philips type. - To use, fill the structure with zeroes, call PROBE and if that succeeds, - compare the name with that returned from VIDIOCGCAP; they should be the - same. If so, you can be assured it is a Philips (OEM) cam and the type - is valid. - */ -#define VIDIOCPWCPROBE _IOR('v', 199, struct pwc_probe) - - /* Set AGC (Automatic Gain Control); int < 0 = auto, 0..65535 = fixed */ -#define VIDIOCPWCSAGC _IOW('v', 200, int) - /* Get AGC; int < 0 = auto; >= 0 = fixed, range 0..65535 */ -#define VIDIOCPWCGAGC _IOR('v', 200, int) - /* Set shutter speed; int < 0 = auto; >= 0 = fixed, range 0..65535 */ -#define VIDIOCPWCSSHUTTER _IOW('v', 201, int) - - /* Color compensation (Auto White Balance) */ -#define VIDIOCPWCSAWB _IOW('v', 202, struct pwc_whitebalance) -#define VIDIOCPWCGAWB _IOR('v', 202, struct pwc_whitebalance) - - /* Auto WB speed */ -#define VIDIOCPWCSAWBSPEED _IOW('v', 203, struct pwc_wb_speed) -#define VIDIOCPWCGAWBSPEED _IOR('v', 203, struct pwc_wb_speed) - - /* LEDs on/off/blink; int range 0..65535 */ -#define VIDIOCPWCSLED _IOW('v', 205, struct pwc_leds) -#define VIDIOCPWCGLED _IOR('v', 205, struct pwc_leds) - - /* Contour (sharpness); int < 0 = auto, 0..65536 = fixed */ -#define VIDIOCPWCSCONTOUR _IOW('v', 206, int) -#define VIDIOCPWCGCONTOUR _IOR('v', 206, int) - - /* Backlight compensation; 0 = off, otherwise on */ -#define VIDIOCPWCSBACKLIGHT _IOW('v', 207, int) -#define VIDIOCPWCGBACKLIGHT _IOR('v', 207, int) - - /* Flickerless mode; = 0 off, otherwise on */ -#define VIDIOCPWCSFLICKER _IOW('v', 208, int) -#define VIDIOCPWCGFLICKER _IOR('v', 208, int) - - /* Dynamic noise reduction; 0 off, 3 = high noise reduction */ -#define VIDIOCPWCSDYNNOISE _IOW('v', 209, int) -#define VIDIOCPWCGDYNNOISE _IOR('v', 209, int) - - /* Real image size as used by the camera; tells you whether or not there's a gray border around the image */ -#define VIDIOCPWCGREALSIZE _IOR('v', 210, struct pwc_imagesize) - - /* Motorized pan & tilt functions */ -#define VIDIOCPWCMPTRESET _IOW('v', 211, int) -#define VIDIOCPWCMPTGRANGE _IOR('v', 211, struct pwc_mpt_range) -#define VIDIOCPWCMPTSANGLE _IOW('v', 212, struct pwc_mpt_angles) -#define VIDIOCPWCMPTGANGLE _IOR('v', 212, struct pwc_mpt_angles) -#define VIDIOCPWCMPTSTATUS _IOR('v', 213, struct pwc_mpt_status) - - /* Get the USB set-video command; needed for initializing libpwcx */ -#define VIDIOCPWCGVIDCMD _IOR('v', 215, struct pwc_video_command) -struct pwc_table_init_buffer { - int len; - char *buffer; - -}; -#define VIDIOCPWCGVIDTABLE _IOR('v', 216, struct pwc_table_init_buffer) - -/* - * This is private command used when communicating with v4l2. - * In the future all private ioctl will be remove/replace to - * use interface offer by v4l2. - */ - -#define V4L2_CID_PRIVATE_SAVE_USER (V4L2_CID_PRIVATE_BASE + 0) -#define V4L2_CID_PRIVATE_RESTORE_USER (V4L2_CID_PRIVATE_BASE + 1) -#define V4L2_CID_PRIVATE_RESTORE_FACTORY (V4L2_CID_PRIVATE_BASE + 2) -#define V4L2_CID_PRIVATE_COLOUR_MODE (V4L2_CID_PRIVATE_BASE + 3) -#define V4L2_CID_PRIVATE_AUTOCONTOUR (V4L2_CID_PRIVATE_BASE + 4) -#define V4L2_CID_PRIVATE_CONTOUR (V4L2_CID_PRIVATE_BASE + 5) -#define V4L2_CID_PRIVATE_BACKLIGHT (V4L2_CID_PRIVATE_BASE + 6) -#define V4L2_CID_PRIVATE_FLICKERLESS (V4L2_CID_PRIVATE_BASE + 7) -#define V4L2_CID_PRIVATE_NOISE_REDUCTION (V4L2_CID_PRIVATE_BASE + 8) - -struct pwc_raw_frame { - __le16 type; /* type of the webcam */ - __le16 vbandlength; /* Size of 4lines compressed (used by the decompressor) */ - __u8 cmd[4]; /* the four byte of the command (in case of nala, - only the first 3 bytes is filled) */ - __u8 rawframe[0]; /* frame_size = H/4*vbandlength */ -} __attribute__ ((packed)); - - -#endif -- cgit v1.2.3 From 795e6eb3262d3b7247ce450835eea6df6571d103 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Wed, 4 Jan 2012 16:58:44 -0300 Subject: [media] pwc: Remove software emulation of arbritary resolutions The pwc driver claims to support any resolution between 160x120 and 640x480, but emulates this by simply drawing a black border around the image. Userspace can draw its own black border if it really wants one. Signed-off-by: Hans de Goede Signed-off-by: Mauro Carvalho Chehab --- Documentation/feature-removal-schedule.txt | 10 ---- drivers/media/video/pwc/pwc-ctrl.c | 69 +++++------------------- drivers/media/video/pwc/pwc-dec23.c | 29 ++++------ drivers/media/video/pwc/pwc-if.c | 10 ++-- drivers/media/video/pwc/pwc-misc.c | 87 +++++++++--------------------- drivers/media/video/pwc/pwc-uncompress.c | 38 ++++--------- drivers/media/video/pwc/pwc-v4l.c | 52 ++++++++---------- drivers/media/video/pwc/pwc.h | 19 +++---- 8 files changed, 92 insertions(+), 222 deletions(-) (limited to 'Documentation/feature-removal-schedule.txt') diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt index 821e3c29ec83..c4362ef3a793 100644 --- a/Documentation/feature-removal-schedule.txt +++ b/Documentation/feature-removal-schedule.txt @@ -460,16 +460,6 @@ Who: Jean Delvare ---------------------------- -What: Software emulation of arbritary resolutions in the pwc driver -When: 3.3 -Why: The pwc driver claims to support any resolution between 160x120 - and 640x480, but emulates this by simply drawing a black border - around the image. Userspace can draw its own black border if it - really wants one. -Who: Hans de Goede - ----------------------------- - What: For VIDIOC_S_FREQUENCY the type field must match the device node's type. If not, return -EINVAL. When: 3.2 diff --git a/drivers/media/video/pwc/pwc-ctrl.c b/drivers/media/video/pwc/pwc-ctrl.c index 684b7c50eea9..6b9c97fff277 100644 --- a/drivers/media/video/pwc/pwc-ctrl.c +++ b/drivers/media/video/pwc/pwc-ctrl.c @@ -102,8 +102,6 @@ static struct Nala_table_entry Nala_table[PSZ_MAX][PWC_FPS_MAX_NALA] = #include "pwc-nala.h" }; -static void pwc_set_image_buffer_size(struct pwc_device *pdev); - /****************************************************************************/ static int _send_control_msg(struct pwc_device *pdev, @@ -221,8 +219,9 @@ static int set_video_mode_Nala(struct pwc_device *pdev, int size, int frames) /* Set various parameters */ pdev->vframes = frames; pdev->valternate = pEntry->alternate; - pdev->image = pwc_image_sizes[size]; - pdev->frame_size = (pdev->image.x * pdev->image.y * 3) / 2; + pdev->width = pwc_image_sizes[size][0]; + pdev->height = pwc_image_sizes[size][1]; + pdev->frame_size = (pdev->width * pdev->height * 3) / 2; if (pEntry->compressed) { if (pdev->release < 5) { /* 4 fold compression */ pdev->vbandlength = 528; @@ -282,12 +281,13 @@ static int set_video_mode_Timon(struct pwc_device *pdev, int size, int frames, /* Set various parameters */ pdev->vframes = frames; pdev->valternate = pChoose->alternate; - pdev->image = pwc_image_sizes[size]; + pdev->width = pwc_image_sizes[size][0]; + pdev->height = pwc_image_sizes[size][1]; pdev->vbandlength = pChoose->bandlength; if (pChoose->bandlength > 0) - pdev->frame_size = (pChoose->bandlength * pdev->image.y) / 4; + pdev->frame_size = (pChoose->bandlength * pdev->height) / 4; else - pdev->frame_size = (pdev->image.x * pdev->image.y * 12) / 8; + pdev->frame_size = (pdev->width * pdev->height * 12) / 8; return 0; } @@ -339,37 +339,25 @@ static int set_video_mode_Kiara(struct pwc_device *pdev, int size, int frames, /* All set and go */ pdev->vframes = frames; pdev->valternate = pChoose->alternate; - pdev->image = pwc_image_sizes[size]; + pdev->width = pwc_image_sizes[size][0]; + pdev->height = pwc_image_sizes[size][1]; pdev->vbandlength = pChoose->bandlength; if (pdev->vbandlength > 0) - pdev->frame_size = (pdev->vbandlength * pdev->image.y) / 4; + pdev->frame_size = (pdev->vbandlength * pdev->height) / 4; else - pdev->frame_size = (pdev->image.x * pdev->image.y * 12) / 8; + pdev->frame_size = (pdev->width * pdev->height * 12) / 8; PWC_TRACE("frame_size=%d, vframes=%d, vsize=%d, vbandlength=%d\n", pdev->frame_size, pdev->vframes, size, pdev->vbandlength); return 0; } - - -/** - @pdev: device structure - @width: viewport width - @height: viewport height - @frame: framerate, in fps - @compression: preferred compression ratio - */ int pwc_set_video_mode(struct pwc_device *pdev, int width, int height, int frames, int compression) { int ret, size; PWC_DEBUG_FLOW("set_video_mode(%dx%d @ %d, pixfmt %08x).\n", width, height, frames, pdev->pixfmt); - size = pwc_decode_size(pdev, width, height); - if (size < 0) { - PWC_DEBUG_MODULE("Could not find suitable size.\n"); - return -ERANGE; - } + size = pwc_get_size(pdev, width, height); PWC_TRACE("decode_size = %d.\n", size); if (DEVICE_USE_CODEC1(pdev->type)) { @@ -385,12 +373,9 @@ int pwc_set_video_mode(struct pwc_device *pdev, int width, int height, PWC_ERROR("Failed to set video mode %s@%d fps; return code = %d\n", size2name[size], frames, ret); return ret; } - pdev->view.x = width; - pdev->view.y = height; pdev->vcompression = compression; pdev->frame_total_size = pdev->frame_size + pdev->frame_header_size + pdev->frame_trailer_size; - pwc_set_image_buffer_size(pdev); - PWC_DEBUG_SIZE("Set viewport to %dx%d, image size is %dx%d.\n", width, height, pwc_image_sizes[size].x, pwc_image_sizes[size].y); + PWC_DEBUG_SIZE("Set resolution to %dx%d\n", pdev->width, pdev->height); return 0; } @@ -447,34 +432,6 @@ unsigned int pwc_get_fps(struct pwc_device *pdev, unsigned int index, unsigned i return ret; } -static void pwc_set_image_buffer_size(struct pwc_device *pdev) -{ - int factor = 0; - - /* for V4L2_PIX_FMT_YUV420 */ - switch (pdev->pixfmt) { - case V4L2_PIX_FMT_YUV420: - factor = 6; - break; - case V4L2_PIX_FMT_PWC1: - case V4L2_PIX_FMT_PWC2: - factor = 6; /* can be uncompressed YUV420P */ - break; - } - - /* Set sizes in bytes */ - pdev->image.size = pdev->image.x * pdev->image.y * factor / 4; - pdev->view.size = pdev->view.x * pdev->view.y * factor / 4; - - /* Align offset, or you'll get some very weird results in - YUV420 mode... x must be multiple of 4 (to get the Y's in - place), and y even (or you'll mixup U & V). This is less of a - problem for YUV420P. - */ - pdev->offset.x = ((pdev->view.x - pdev->image.x) / 2) & 0xFFFC; - pdev->offset.y = ((pdev->view.y - pdev->image.y) / 2) & 0xFFFE; -} - int pwc_get_u8_ctrl(struct pwc_device *pdev, u8 request, u16 value, int *data) { int ret; diff --git a/drivers/media/video/pwc/pwc-dec23.c b/drivers/media/video/pwc/pwc-dec23.c index e531f85460c1..2c6709112b2f 100644 --- a/drivers/media/video/pwc/pwc-dec23.c +++ b/drivers/media/video/pwc/pwc-dec23.c @@ -656,10 +656,6 @@ static void DecompressBand23(struct pwc_dec23_private *pdec, * * Uncompress a pwc23 buffer. * - * pwc.view: size of the image wanted - * pwc.image: size of the image returned by the camera - * pwc.offset: (x,y) to displayer image in the view - * * src: raw data * dst: image output */ @@ -667,7 +663,7 @@ void pwc_dec23_decompress(const struct pwc_device *pwc, const void *src, void *dst) { - int bandlines_left, stride, bytes_per_block; + int bandlines_left, bytes_per_block; struct pwc_dec23_private *pdec = pwc->decompress_data; /* YUV420P image format */ @@ -678,28 +674,23 @@ void pwc_dec23_decompress(const struct pwc_device *pwc, mutex_lock(&pdec->lock); - bandlines_left = pwc->image.y / 4; - bytes_per_block = pwc->view.x * 4; - plane_size = pwc->view.x * pwc->view.y; - - /* offset in Y plane */ - stride = pwc->view.x * pwc->offset.y; - pout_planar_y = dst + stride + pwc->offset.x; + bandlines_left = pwc->height / 4; + bytes_per_block = pwc->width * 4; + plane_size = pwc->height * pwc->width; - /* offsets in U/V planes */ - stride = (pwc->view.x * pwc->offset.y) / 4 + pwc->offset.x / 2; - pout_planar_u = dst + plane_size + stride; - pout_planar_v = dst + plane_size + plane_size / 4 + stride; + pout_planar_y = dst; + pout_planar_u = dst + plane_size; + pout_planar_v = dst + plane_size + plane_size / 4; while (bandlines_left--) { DecompressBand23(pwc->decompress_data, src, pout_planar_y, pout_planar_u, pout_planar_v, - pwc->image.x, pwc->view.x); + pwc->width, pwc->width); src += pwc->vbandlength; pout_planar_y += bytes_per_block; - pout_planar_u += pwc->view.x; - pout_planar_v += pwc->view.x; + pout_planar_u += pwc->width; + pout_planar_v += pwc->width; } mutex_unlock(&pdec->lock); } diff --git a/drivers/media/video/pwc/pwc-if.c b/drivers/media/video/pwc/pwc-if.c index 963b4a55ec75..be4406a7c80a 100644 --- a/drivers/media/video/pwc/pwc-if.c +++ b/drivers/media/video/pwc/pwc-if.c @@ -656,6 +656,7 @@ static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt, unsigned int sizes[], void *alloc_ctxs[]) { struct pwc_device *pdev = vb2_get_drv_priv(vq); + int size; if (*nbuffers < MIN_FRAMES) *nbuffers = MIN_FRAMES; @@ -664,7 +665,9 @@ static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt, *nplanes = 1; - sizes[0] = PAGE_ALIGN((pdev->abs_max.x * pdev->abs_max.y * 3) / 2); + size = pwc_get_size(pdev, MAX_WIDTH, MAX_HEIGHT); + sizes[0] = PAGE_ALIGN(pwc_image_sizes[size][0] * + pwc_image_sizes[size][1] * 3 / 2); return 0; } @@ -742,7 +745,7 @@ static int start_streaming(struct vb2_queue *vq, unsigned int count) pwc_camera_power(pdev, 1); if (pdev->power_save) { /* Restore video mode */ - pwc_set_video_mode(pdev, pdev->view.x, pdev->view.y, + pwc_set_video_mode(pdev, pdev->width, pdev->height, pdev->vframes, pdev->vcompression); } pwc_set_leds(pdev, led_on, led_off); @@ -1056,7 +1059,6 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id } pdev->type = type_id; pdev->vframes = default_fps; - strcpy(pdev->serial, serial_number); pdev->features = features; pwc_construct(pdev); /* set min/max sizes correct */ @@ -1119,7 +1121,7 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id pwc_set_leds(pdev, 0, 0); /* Setup intial videomode */ - rc = pwc_set_video_mode(pdev, pdev->view_max.x, pdev->view_max.y, + rc = pwc_set_video_mode(pdev, MAX_WIDTH, MAX_HEIGHT, pdev->vframes, pdev->vcompression); if (rc) goto err_free_mem; diff --git a/drivers/media/video/pwc/pwc-misc.c b/drivers/media/video/pwc/pwc-misc.c index 0b031336eab8..23a55b5814fc 100644 --- a/drivers/media/video/pwc/pwc-misc.c +++ b/drivers/media/video/pwc/pwc-misc.c @@ -27,67 +27,47 @@ #include "pwc.h" -const struct pwc_coord pwc_image_sizes[PSZ_MAX] = +const int pwc_image_sizes[PSZ_MAX][2] = { - { 128, 96, 0 }, /* sqcif */ - { 160, 120, 0 }, /* qsif */ - { 176, 144, 0 }, /* qcif */ - { 320, 240, 0 }, /* sif */ - { 352, 288, 0 }, /* cif */ - { 640, 480, 0 }, /* vga */ + { 128, 96 }, /* sqcif */ + { 160, 120 }, /* qsif */ + { 176, 144 }, /* qcif */ + { 320, 240 }, /* sif */ + { 352, 288 }, /* cif */ + { 640, 480 }, /* vga */ }; /* x,y -> PSZ_ */ -int pwc_decode_size(struct pwc_device *pdev, int width, int height) +int pwc_get_size(struct pwc_device *pdev, int width, int height) { - int i, find; - - /* Make sure we don't go beyond our max size. - NB: we have different limits for RAW and normal modes. In case - you don't have the decompressor loaded or use RAW mode, - the maximum viewable size is smaller. - */ - if (pdev->pixfmt != V4L2_PIX_FMT_YUV420) - { - if (width > pdev->abs_max.x || height > pdev->abs_max.y) - { - PWC_DEBUG_SIZE("VIDEO_PALETTE_RAW: going beyond abs_max.\n"); - return -1; - } - } - else - { - if (width > pdev->view_max.x || height > pdev->view_max.y) - { - PWC_DEBUG_SIZE("VIDEO_PALETTE_not RAW: going beyond view_max.\n"); - return -1; - } - } + int i; /* Find the largest size supported by the camera that fits into the - requested size. - */ - find = -1; + requested size. */ + for (i = PSZ_MAX - 1; i >= 0; i--) { + if (!(pdev->image_mask & (1 << i))) + continue; + + if (pwc_image_sizes[i][0] <= width && + pwc_image_sizes[i][1] <= height) + return i; + } + + /* No mode found, return the smallest mode we have */ for (i = 0; i < PSZ_MAX; i++) { - if (pdev->image_mask & (1 << i)) { - if (pwc_image_sizes[i].x <= width && pwc_image_sizes[i].y <= height) - find = i; - } + if (pdev->image_mask & (1 << i)) + return i; } - return find; + + /* Never reached there always is atleast one supported mode */ + return 0; } -/* initialize variables depending on type and decompressor*/ +/* initialize variables depending on type and decompressor */ void pwc_construct(struct pwc_device *pdev) { if (DEVICE_USE_CODEC1(pdev->type)) { - pdev->view_min.x = 128; - pdev->view_min.y = 96; - pdev->view_max.x = 352; - pdev->view_max.y = 288; - pdev->abs_max.x = 352; - pdev->abs_max.y = 288; pdev->image_mask = 1 << PSZ_SQCIF | 1 << PSZ_QCIF | 1 << PSZ_CIF; pdev->vcinterface = 2; pdev->vendpoint = 4; @@ -96,13 +76,7 @@ void pwc_construct(struct pwc_device *pdev) } else if (DEVICE_USE_CODEC3(pdev->type)) { - pdev->view_min.x = 160; - pdev->view_min.y = 120; - pdev->view_max.x = 640; - pdev->view_max.y = 480; pdev->image_mask = 1 << PSZ_QSIF | 1 << PSZ_SIF | 1 << PSZ_VGA; - pdev->abs_max.x = 640; - pdev->abs_max.y = 480; pdev->vcinterface = 3; pdev->vendpoint = 5; pdev->frame_header_size = TOUCAM_HEADER_SIZE; @@ -110,20 +84,11 @@ void pwc_construct(struct pwc_device *pdev) } else /* if (DEVICE_USE_CODEC2(pdev->type)) */ { - pdev->view_min.x = 128; - pdev->view_min.y = 96; - /* Anthill bug #38: PWC always reports max size, even without PWCX */ - pdev->view_max.x = 640; - pdev->view_max.y = 480; pdev->image_mask = 1 << PSZ_SQCIF | 1 << PSZ_QSIF | 1 << PSZ_QCIF | 1 << PSZ_SIF | 1 << PSZ_CIF | 1 << PSZ_VGA; - pdev->abs_max.x = 640; - pdev->abs_max.y = 480; pdev->vcinterface = 3; pdev->vendpoint = 4; pdev->frame_header_size = 0; pdev->frame_trailer_size = 0; } pdev->pixfmt = V4L2_PIX_FMT_YUV420; /* default */ - pdev->view_min.size = pdev->view_min.x * pdev->view_min.y; - pdev->view_max.size = pdev->view_max.x * pdev->view_max.y; } diff --git a/drivers/media/video/pwc/pwc-uncompress.c b/drivers/media/video/pwc/pwc-uncompress.c index e55b568cbf3d..b65903fbcf0d 100644 --- a/drivers/media/video/pwc/pwc-uncompress.c +++ b/drivers/media/video/pwc/pwc-uncompress.c @@ -35,7 +35,7 @@ int pwc_decompress(struct pwc_device *pdev, struct pwc_frame_buf *fbuf) { - int n, line, col, stride; + int n, line, col; void *yuv, *image; u16 *src; u16 *dsty, *dstu, *dstv; @@ -60,35 +60,23 @@ int pwc_decompress(struct pwc_device *pdev, struct pwc_frame_buf *fbuf) return 0; } - vb2_set_plane_payload(&fbuf->vb, 0, pdev->view.size); + vb2_set_plane_payload(&fbuf->vb, 0, + pdev->width * pdev->height * 3 / 2); if (pdev->vbandlength == 0) { /* Uncompressed mode. - * We copy the data into the output buffer, using the viewport - * size (which may be larger than the image size). - * Unfortunately we have to do a bit of byte stuffing to get - * the desired output format/size. * * We do some byte shuffling here to go from the * native format to YUV420P. */ src = (u16 *)yuv; - n = pdev->view.x * pdev->view.y; + n = pdev->width * pdev->height; + dsty = (u16 *)(image); + dstu = (u16 *)(image + n); + dstv = (u16 *)(image + n + n / 4); - /* offset in Y plane */ - stride = pdev->view.x * pdev->offset.y + pdev->offset.x; - dsty = (u16 *)(image + stride); - - /* offsets in U/V planes */ - stride = pdev->view.x * pdev->offset.y / 4 + pdev->offset.x / 2; - dstu = (u16 *)(image + n + stride); - dstv = (u16 *)(image + n + n / 4 + stride); - - /* increment after each line */ - stride = (pdev->view.x - pdev->image.x) / 2; /* u16 is 2 bytes */ - - for (line = 0; line < pdev->image.y; line++) { - for (col = 0; col < pdev->image.x; col += 4) { + for (line = 0; line < pdev->height; line++) { + for (col = 0; col < pdev->width; col += 4) { *dsty++ = *src++; *dsty++ = *src++; if (line & 1) @@ -96,11 +84,6 @@ int pwc_decompress(struct pwc_device *pdev, struct pwc_frame_buf *fbuf) else *dstu++ = *src++; } - dsty += stride; - if (line & 1) - dstv += (stride >> 1); - else - dstu += (stride >> 1); } return 0; @@ -122,6 +105,3 @@ int pwc_decompress(struct pwc_device *pdev, struct pwc_frame_buf *fbuf) } return 0; } - - -/* vim: set cino= formatoptions=croql cindent shiftwidth=8 tabstop=8: */ diff --git a/drivers/media/video/pwc/pwc-v4l.c b/drivers/media/video/pwc/pwc-v4l.c index 87457b53f495..097ec582ee66 100644 --- a/drivers/media/video/pwc/pwc-v4l.c +++ b/drivers/media/video/pwc/pwc-v4l.c @@ -398,8 +398,8 @@ int pwc_init_controls(struct pwc_device *pdev) static void pwc_vidioc_fill_fmt(const struct pwc_device *pdev, struct v4l2_format *f) { memset(&f->fmt.pix, 0, sizeof(struct v4l2_pix_format)); - f->fmt.pix.width = pdev->view.x; - f->fmt.pix.height = pdev->view.y; + f->fmt.pix.width = pdev->width; + f->fmt.pix.height = pdev->height; f->fmt.pix.field = V4L2_FIELD_NONE; if (pdev->pixfmt == V4L2_PIX_FMT_YUV420) { f->fmt.pix.pixelformat = V4L2_PIX_FMT_YUV420; @@ -429,6 +429,8 @@ static void pwc_vidioc_fill_fmt(const struct pwc_device *pdev, struct v4l2_forma /* ioctl(VIDIOC_TRY_FMT) */ static int pwc_vidioc_try_fmt(struct pwc_device *pdev, struct v4l2_format *f) { + int size; + if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { PWC_DEBUG_IOCTL("Bad video type must be V4L2_BUF_TYPE_VIDEO_CAPTURE\n"); return -EINVAL; @@ -455,15 +457,9 @@ static int pwc_vidioc_try_fmt(struct pwc_device *pdev, struct v4l2_format *f) } - if (f->fmt.pix.width > pdev->view_max.x) - f->fmt.pix.width = pdev->view_max.x; - else if (f->fmt.pix.width < pdev->view_min.x) - f->fmt.pix.width = pdev->view_min.x; - - if (f->fmt.pix.height > pdev->view_max.y) - f->fmt.pix.height = pdev->view_max.y; - else if (f->fmt.pix.height < pdev->view_min.y) - f->fmt.pix.height = pdev->view_min.y; + size = pwc_get_size(pdev, f->fmt.pix.width, f->fmt.pix.height); + f->fmt.pix.width = pwc_image_sizes[size][0]; + f->fmt.pix.height = pwc_image_sizes[size][1]; return 0; } @@ -972,7 +968,7 @@ static int pwc_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f) mutex_lock(&pdev->udevlock); /* To avoid race with s_fmt */ PWC_DEBUG_IOCTL("ioctl(VIDIOC_G_FMT) return size %dx%d\n", - pdev->image.x, pdev->image.y); + pdev->width, pdev->height); pwc_vidioc_fill_fmt(pdev, f); mutex_unlock(&pdev->udevlock); return 0; @@ -1061,25 +1057,21 @@ static int pwc_enum_framesizes(struct file *file, void *fh, struct pwc_device *pdev = video_drvdata(file); unsigned int i = 0, index = fsize->index; - if (fsize->pixel_format == V4L2_PIX_FMT_YUV420) { + if (fsize->pixel_format == V4L2_PIX_FMT_YUV420 || + (fsize->pixel_format == V4L2_PIX_FMT_PWC1 && + DEVICE_USE_CODEC1(pdev->type)) || + (fsize->pixel_format == V4L2_PIX_FMT_PWC2 && + DEVICE_USE_CODEC23(pdev->type))) { for (i = 0; i < PSZ_MAX; i++) { - if (pdev->image_mask & (1UL << i)) { - if (!index--) { - fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE; - fsize->discrete.width = pwc_image_sizes[i].x; - fsize->discrete.height = pwc_image_sizes[i].y; - return 0; - } + if (!(pdev->image_mask & (1UL << i))) + continue; + if (!index--) { + fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE; + fsize->discrete.width = pwc_image_sizes[i][0]; + fsize->discrete.height = pwc_image_sizes[i][1]; + return 0; } } - } else if (fsize->index == 0 && - ((fsize->pixel_format == V4L2_PIX_FMT_PWC1 && DEVICE_USE_CODEC1(pdev->type)) || - (fsize->pixel_format == V4L2_PIX_FMT_PWC2 && DEVICE_USE_CODEC23(pdev->type)))) { - - fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE; - fsize->discrete.width = pdev->abs_max.x; - fsize->discrete.height = pdev->abs_max.y; - return 0; } return -EINVAL; } @@ -1092,8 +1084,8 @@ static int pwc_enum_frameintervals(struct file *file, void *fh, unsigned int i; for (i = 0; i < PSZ_MAX; i++) { - if (pwc_image_sizes[i].x == fival->width && - pwc_image_sizes[i].y == fival->height) { + if (pwc_image_sizes[i][0] == fival->width && + pwc_image_sizes[i][1] == fival->height) { size = i; break; } diff --git a/drivers/media/video/pwc/pwc.h b/drivers/media/video/pwc/pwc.h index 19c692c186fe..5d013851ed2a 100644 --- a/drivers/media/video/pwc/pwc.h +++ b/drivers/media/video/pwc/pwc.h @@ -107,6 +107,9 @@ #define FEATURE_CODEC1 0x0002 #define FEATURE_CODEC2 0x0004 +#define MAX_WIDTH 640 +#define MAX_HEIGHT 480 + /* Ignore errors in the first N frames, to allow for startup delays */ #define FRAME_LOWMARK 5 @@ -205,12 +208,6 @@ struct pwc_raw_frame { __u8 rawframe[0]; /* frame_size = H / 4 * vbandlength */ } __packed; -/* structure for transferring x & y coordinates */ -struct pwc_coord { - int x, y; /* guess what */ - int size; /* size, or offset */ -}; - /* intermediate buffers with raw data from the USB cam */ struct pwc_frame_buf { @@ -233,7 +230,6 @@ struct pwc_device int type; int release; /* release number */ int features; /* feature bits */ - char serial[30]; /* serial number (string) */ /*** Video data ***/ struct file *capt_file; /* file doing video capture */ @@ -286,10 +282,7 @@ struct pwc_device * a gray or black border. view_min <= image <= view <= view_max; */ int image_mask; /* supported sizes */ - struct pwc_coord view_min, view_max; /* minimum and maximum view */ - struct pwc_coord abs_max; /* maximum supported size */ - struct pwc_coord image, view; /* image and viewport size */ - struct pwc_coord offset; /* offset of the viewport */ + int width, height; /* current resolution */ #ifdef CONFIG_USB_PWC_INPUT_EVDEV struct input_dev *button_dev; /* webcam snapshot button input */ @@ -364,9 +357,9 @@ int pwc_test_n_set_capt_file(struct pwc_device *pdev, struct file *file); /** Functions in pwc-misc.c */ /* sizes in pixels */ -extern const struct pwc_coord pwc_image_sizes[PSZ_MAX]; +extern const int pwc_image_sizes[PSZ_MAX][2]; -int pwc_decode_size(struct pwc_device *pdev, int width, int height); +int pwc_get_size(struct pwc_device *pdev, int width, int height); void pwc_construct(struct pwc_device *pdev); /** Functions in pwc-ctrl.c */ -- cgit v1.2.3