# This is a BitKeeper generated patch for the following project: # Project Name: Linux kernel tree # This patch format is intended for GNU patch command version 2.5 or higher. # This patch includes the following deltas: # ChangeSet 1.511 -> 1.512 # drivers/usb/media/konicawc.c 1.8 -> 1.9 # # The following is the BitKeeper ChangeSet Log # -------------------------------------------- # 02/08/21 spse@secret.org.uk 1.512 # [PATCH] add VIDIOCSWIN support to konicawc driver # # This patch uses the setVideoMode callback in usbvideo to allow # the VIDIOCSWIN ioctl() to set the size and speed of the camera. # -------------------------------------------- # diff -Nru a/drivers/usb/media/konicawc.c b/drivers/usb/media/konicawc.c --- a/drivers/usb/media/konicawc.c Wed Aug 21 15:45:36 2002 +++ b/drivers/usb/media/konicawc.c Wed Aug 21 15:45:36 2002 @@ -29,7 +29,7 @@ #define MAX_CAMERAS 1 -#define DRIVER_VERSION "v1.3" +#define DRIVER_VERSION "v1.4" #define DRIVER_DESC "Konica Webcam driver" enum ctrl_req { @@ -562,6 +562,97 @@ } +static int konicawc_find_fps(int size, int fps) +{ + int i; + + fps *= 3; + DEBUG(1, "konica_find_fps: size = %d fps = %d", size, fps); + if(fps <= spd_to_fps[size][0]) + return 0; + + if(fps >= spd_to_fps[size][MAX_SPEED]) + return MAX_SPEED; + + for(i = 0; i < MAX_SPEED; i++) { + if((fps >= spd_to_fps[size][i]) && (fps <= spd_to_fps[size][i+1])) { + DEBUG(2, "fps %d between %d and %d", fps, i, i+1); + if( (fps - spd_to_fps[size][i]) < (spd_to_fps[size][i+1] - fps)) + return i; + else + return i+1; + } + } + return MAX_SPEED+1; +} + + +static int konicawc_set_video_mode(uvd_t *uvd, struct video_window *vw) +{ + struct konicawc *cam = (struct konicawc *)uvd->user_data; + int newspeed = cam->speed; + int newsize; + int x = vw->width; + int y = vw->height; + int fps = vw->flags; + + if(x > 0 && y > 0) { + DEBUG(2, "trying to find size %d,%d", x, y); + for(newsize = 0; newsize <= MAX_FRAME_SIZE; newsize++) { + if((camera_sizes[newsize].width == x) && (camera_sizes[newsize].height == y)) + break; + } + } else { + newsize = cam->size; + } + + if(newsize > MAX_FRAME_SIZE) { + DEBUG(1, "couldnt find size %d,%d", x, y); + return -EINVAL; + } + + if(fps > 0) { + DEBUG(1, "trying to set fps to %d", fps); + newspeed = konicawc_find_fps(newsize, fps); + DEBUG(1, "find_fps returned %d (%d)", newspeed, spd_to_fps[newsize][newspeed]); + } + + if(newspeed > MAX_SPEED) + return -EINVAL; + + DEBUG(1, "setting size to %d speed to %d", newsize, newspeed); + if((newsize == cam->size) && (newspeed == cam->speed)) { + DEBUG(1, "Nothing to do"); + return 0; + } + DEBUG(0, "setting to %dx%d @ %d fps", camera_sizes[newsize].width, + camera_sizes[newsize].height, spd_to_fps[newsize][newspeed]/3); + + konicawc_stop_data(uvd); + uvd->ifaceAltActive = spd_to_iface[newspeed]; + DEBUG(1, "new interface = %d", uvd->ifaceAltActive); + cam->speed = newspeed; + + if(cam->size != newsize) { + cam->size = newsize; + konicawc_set_camera_size(uvd); + } + + /* Flush the input queue and clear any current frame in progress */ + + RingQueue_Flush(&uvd->dp); + cam->lastframe = -2; + if(uvd->curframe != -1) { + uvd->frame[uvd->curframe].curline = 0; + uvd->frame[uvd->curframe].seqRead_Length = 0; + uvd->frame[uvd->curframe].seqRead_Index = 0; + } + + konicawc_start_data(uvd); + return 0; +} + + static int konicawc_calculate_fps(uvd_t *uvd) { struct konicawc *cam = uvd->user_data; @@ -602,10 +693,10 @@ uvd->vcap.type = VID_TYPE_CAPTURE; uvd->vcap.channels = 1; uvd->vcap.audios = 0; - uvd->vcap.minwidth = camera_sizes[cam->size].width; - uvd->vcap.minheight = camera_sizes[cam->size].height; - uvd->vcap.maxwidth = camera_sizes[cam->size].width; - uvd->vcap.maxheight = camera_sizes[cam->size].height; + uvd->vcap.minwidth = camera_sizes[SIZE_160X120].width; + uvd->vcap.minheight = camera_sizes[SIZE_160X120].height; + uvd->vcap.maxwidth = camera_sizes[SIZE_320X240].width; + uvd->vcap.maxheight = camera_sizes[SIZE_320X240].height; memset(&uvd->vchan, 0, sizeof(uvd->vchan)); uvd->vchan.flags = 0 ; @@ -731,14 +822,14 @@ uvd->iso_packet_len = maxPS; uvd->paletteBits = 1L << VIDEO_PALETTE_YUV420P; uvd->defaultPalette = VIDEO_PALETTE_YUV420P; - uvd->canvas = VIDEOSIZE(cam->width, cam->height); - uvd->videosize = uvd->canvas; + uvd->canvas = VIDEOSIZE(320, 240); + uvd->videosize = VIDEOSIZE(cam->width, cam->height); /* Initialize konicawc specific data */ konicawc_configure_video(uvd); i = usbvideo_RegisterVideoDevice(uvd); - uvd->max_frame_size = (cam->width * cam->height * 3)/2; + uvd->max_frame_size = (320 * 240 * 3)/2; if (i != 0) { err("usbvideo_RegisterVideoDevice() failed."); uvd = NULL; @@ -797,6 +888,7 @@ cbTbl.setupOnOpen = konicawc_setup_on_open; cbTbl.processData = konicawc_process_isoc; cbTbl.getFPS = konicawc_calculate_fps; + cbTbl.setVideoMode = konicawc_set_video_mode; cbTbl.startDataPump = konicawc_start_data; cbTbl.stopDataPump = konicawc_stop_data; cbTbl.adjustPicture = konicawc_adjust_picture;