1/* 2 * konicawc.c - konica webcam driver 3 * 4 * Author: Simon Evans <spse@secret.org.uk> 5 * 6 * Copyright (C) 2002 Simon Evans 7 * 8 * Licence: GPL 9 * 10 * Driver for USB webcams based on Konica chipset. This 11 * chipset is used in Intel YC76 camera. 12 * 13 */ 14 15#include <linux/kernel.h> 16#include <linux/module.h> 17#include <linux/init.h> 18#include <linux/usb/input.h> 19#include <linux/gfp.h> 20 21#include "usbvideo.h" 22 23#define MAX_BRIGHTNESS 108 24#define MAX_CONTRAST 108 25#define MAX_SATURATION 108 26#define MAX_SHARPNESS 108 27#define MAX_WHITEBAL 372 28#define MAX_SPEED 6 29 30 31#define MAX_CAMERAS 1 32 33#define DRIVER_VERSION "v1.4" 34#define DRIVER_DESC "Konica Webcam driver" 35 36enum ctrl_req { 37 SetWhitebal = 0x01, 38 SetBrightness = 0x02, 39 SetSharpness = 0x03, 40 SetContrast = 0x04, 41 SetSaturation = 0x05, 42}; 43 44 45enum frame_sizes { 46 SIZE_160X120 = 0, 47 SIZE_160X136 = 1, 48 SIZE_176X144 = 2, 49 SIZE_320X240 = 3, 50 51}; 52 53#define MAX_FRAME_SIZE SIZE_320X240 54 55static struct usbvideo *cams; 56 57#ifdef CONFIG_USB_DEBUG 58static int debug; 59#define DEBUG(n, format, arg...) \ 60 if (n <= debug) { \ 61 printk(KERN_DEBUG __FILE__ ":%s(): " format "\n", __func__ , ## arg); \ 62 } 63#else 64#define DEBUG(n, arg...) 65static const int debug; 66#endif 67 68 69/* Some default values for initial camera settings, 70 can be set by modprobe */ 71 72static int size; 73static int speed = 6; /* Speed (fps) 0 (slowest) to 6 (fastest) */ 74static int brightness = MAX_BRIGHTNESS/2; 75static int contrast = MAX_CONTRAST/2; 76static int saturation = MAX_SATURATION/2; 77static int sharpness = MAX_SHARPNESS/2; 78static int whitebal = 3*(MAX_WHITEBAL/4); 79 80static const int spd_to_iface[] = { 1, 0, 3, 2, 4, 5, 6 }; 81 82/* These FPS speeds are from the windows config box. They are 83 * indexed on size (0-2) and speed (0-6). Divide by 3 to get the 84 * real fps. 85 */ 86 87static const int spd_to_fps[][7] = { { 24, 40, 48, 60, 72, 80, 100 }, 88 { 24, 40, 48, 60, 72, 80, 100 }, 89 { 18, 30, 36, 45, 54, 60, 75 }, 90 { 6, 10, 12, 15, 18, 21, 25 } }; 91 92struct cam_size { 93 u16 width; 94 u16 height; 95 u8 cmd; 96}; 97 98static const struct cam_size camera_sizes[] = { { 160, 120, 0x7 }, 99 { 160, 136, 0xa }, 100 { 176, 144, 0x4 }, 101 { 320, 240, 0x5 } }; 102 103struct konicawc { 104 u8 brightness; /* camera uses 0 - 9, x11 for real value */ 105 u8 contrast; /* as above */ 106 u8 saturation; /* as above */ 107 u8 sharpness; /* as above */ 108 u8 white_bal; /* 0 - 33, x11 for real value */ 109 u8 speed; /* Stored as 0 - 6, used as index in spd_to_* (above) */ 110 u8 size; /* Frame Size */ 111 int height; 112 int width; 113 struct urb *sts_urb[USBVIDEO_NUMSBUF]; 114 u8 sts_buf[USBVIDEO_NUMSBUF][FRAMES_PER_DESC]; 115 struct urb *last_data_urb; 116 int lastframe; 117 int cur_frame_size; /* number of bytes in current frame size */ 118 int maxline; /* number of lines per frame */ 119 int yplanesz; /* Number of bytes in the Y plane */ 120 unsigned int buttonsts:1; 121#ifdef CONFIG_INPUT 122 struct input_dev *input; 123 char input_physname[64]; 124#endif 125}; 126 127 128#define konicawc_set_misc(uvd, req, value, index) konicawc_ctrl_msg(uvd, USB_DIR_OUT, req, value, index, NULL, 0) 129#define konicawc_get_misc(uvd, req, value, index, buf, sz) konicawc_ctrl_msg(uvd, USB_DIR_IN, req, value, index, buf, sz) 130#define konicawc_set_value(uvd, value, index) konicawc_ctrl_msg(uvd, USB_DIR_OUT, 2, value, index, NULL, 0) 131 132 133static int konicawc_ctrl_msg(struct uvd *uvd, u8 dir, u8 request, u16 value, u16 index, void *buf, int len) 134{ 135 int retval = usb_control_msg(uvd->dev, 136 dir ? usb_rcvctrlpipe(uvd->dev, 0) : usb_sndctrlpipe(uvd->dev, 0), 137 request, 0x40 | dir, value, index, buf, len, 1000); 138 return retval < 0 ? retval : 0; 139} 140 141 142static inline void konicawc_camera_on(struct uvd *uvd) 143{ 144 DEBUG(0, "camera on"); 145 konicawc_set_misc(uvd, 0x2, 1, 0x0b); 146} 147 148 149static inline void konicawc_camera_off(struct uvd *uvd) 150{ 151 DEBUG(0, "camera off"); 152 konicawc_set_misc(uvd, 0x2, 0, 0x0b); 153} 154 155 156static void konicawc_set_camera_size(struct uvd *uvd) 157{ 158 struct konicawc *cam = (struct konicawc *)uvd->user_data; 159 160 konicawc_set_misc(uvd, 0x2, camera_sizes[cam->size].cmd, 0x08); 161 cam->width = camera_sizes[cam->size].width; 162 cam->height = camera_sizes[cam->size].height; 163 cam->yplanesz = cam->height * cam->width; 164 cam->cur_frame_size = (cam->yplanesz * 3) / 2; 165 cam->maxline = cam->yplanesz / 256; 166 uvd->videosize = VIDEOSIZE(cam->width, cam->height); 167} 168 169 170static int konicawc_setup_on_open(struct uvd *uvd) 171{ 172 struct konicawc *cam = (struct konicawc *)uvd->user_data; 173 174 DEBUG(1, "setting brightness to %d (%d)", cam->brightness, 175 cam->brightness * 11); 176 konicawc_set_value(uvd, cam->brightness, SetBrightness); 177 DEBUG(1, "setting white balance to %d (%d)", cam->white_bal, 178 cam->white_bal * 11); 179 konicawc_set_value(uvd, cam->white_bal, SetWhitebal); 180 DEBUG(1, "setting contrast to %d (%d)", cam->contrast, 181 cam->contrast * 11); 182 konicawc_set_value(uvd, cam->contrast, SetContrast); 183 DEBUG(1, "setting saturation to %d (%d)", cam->saturation, 184 cam->saturation * 11); 185 konicawc_set_value(uvd, cam->saturation, SetSaturation); 186 DEBUG(1, "setting sharpness to %d (%d)", cam->sharpness, 187 cam->sharpness * 11); 188 konicawc_set_value(uvd, cam->sharpness, SetSharpness); 189 konicawc_set_camera_size(uvd); 190 cam->lastframe = -2; 191 cam->buttonsts = 0; 192 return 0; 193} 194 195 196static void konicawc_adjust_picture(struct uvd *uvd) 197{ 198 struct konicawc *cam = (struct konicawc *)uvd->user_data; 199 200 konicawc_camera_off(uvd); 201 DEBUG(1, "new brightness: %d", uvd->vpic.brightness); 202 uvd->vpic.brightness = (uvd->vpic.brightness > MAX_BRIGHTNESS) ? MAX_BRIGHTNESS : uvd->vpic.brightness; 203 if(cam->brightness != uvd->vpic.brightness / 11) { 204 cam->brightness = uvd->vpic.brightness / 11; 205 DEBUG(1, "setting brightness to %d (%d)", cam->brightness, 206 cam->brightness * 11); 207 konicawc_set_value(uvd, cam->brightness, SetBrightness); 208 } 209 210 DEBUG(1, "new contrast: %d", uvd->vpic.contrast); 211 uvd->vpic.contrast = (uvd->vpic.contrast > MAX_CONTRAST) ? MAX_CONTRAST : uvd->vpic.contrast; 212 if(cam->contrast != uvd->vpic.contrast / 11) { 213 cam->contrast = uvd->vpic.contrast / 11; 214 DEBUG(1, "setting contrast to %d (%d)", cam->contrast, 215 cam->contrast * 11); 216 konicawc_set_value(uvd, cam->contrast, SetContrast); 217 } 218 konicawc_camera_on(uvd); 219} 220 221#ifdef CONFIG_INPUT 222 223static void konicawc_register_input(struct konicawc *cam, struct usb_device *dev) 224{ 225 struct input_dev *input_dev; 226 int error; 227 228 usb_make_path(dev, cam->input_physname, sizeof(cam->input_physname)); 229 strlcat(cam->input_physname, "/input0", sizeof(cam->input_physname)); 230 231 cam->input = input_dev = input_allocate_device(); 232 if (!input_dev) { 233 dev_warn(&dev->dev, 234 "Not enough memory for camera's input device\n"); 235 return; 236 } 237 238 input_dev->name = "Konicawc snapshot button"; 239 input_dev->phys = cam->input_physname; 240 usb_to_input_id(dev, &input_dev->id); 241 input_dev->dev.parent = &dev->dev; 242 243 input_dev->evbit[0] = BIT_MASK(EV_KEY); 244 input_dev->keybit[BIT_WORD(KEY_CAMERA)] = BIT_MASK(KEY_CAMERA); 245 246 error = input_register_device(cam->input); 247 if (error) { 248 dev_warn(&dev->dev, 249 "Failed to register camera's input device, err: %d\n", 250 error); 251 input_free_device(cam->input); 252 cam->input = NULL; 253 } 254} 255 256static void konicawc_unregister_input(struct konicawc *cam) 257{ 258 if (cam->input) { 259 input_unregister_device(cam->input); 260 cam->input = NULL; 261 } 262} 263 264static void konicawc_report_buttonstat(struct konicawc *cam) 265{ 266 if (cam->input) { 267 input_report_key(cam->input, KEY_CAMERA, cam->buttonsts); 268 input_sync(cam->input); 269 } 270} 271 272#else 273 274static inline void konicawc_register_input(struct konicawc *cam, struct usb_device *dev) { } 275static inline void konicawc_unregister_input(struct konicawc *cam) { } 276static inline void konicawc_report_buttonstat(struct konicawc *cam) { } 277 278#endif /* CONFIG_INPUT */ 279 280static int konicawc_compress_iso(struct uvd *uvd, struct urb *dataurb, struct urb *stsurb) 281{ 282 char *cdata; 283 int i, totlen = 0; 284 unsigned char *status = stsurb->transfer_buffer; 285 int keep = 0, discard = 0, bad = 0; 286 struct konicawc *cam = (struct konicawc *)uvd->user_data; 287 288 for (i = 0; i < dataurb->number_of_packets; i++) { 289 int button = cam->buttonsts; 290 unsigned char sts; 291 int n = dataurb->iso_frame_desc[i].actual_length; 292 int st = dataurb->iso_frame_desc[i].status; 293 cdata = dataurb->transfer_buffer + 294 dataurb->iso_frame_desc[i].offset; 295 296 /* Detect and ignore errored packets */ 297 if (st < 0) { 298 DEBUG(1, "Data error: packet=%d. len=%d. status=%d.", 299 i, n, st); 300 uvd->stats.iso_err_count++; 301 continue; 302 } 303 304 /* Detect and ignore empty packets */ 305 if (n <= 0) { 306 uvd->stats.iso_skip_count++; 307 continue; 308 } 309 310 /* See what the status data said about the packet */ 311 sts = *(status+stsurb->iso_frame_desc[i].offset); 312 313 /* sts: 0x80-0xff: frame start with frame number (ie 0-7f) 314 * otherwise: 315 * bit 0 0: keep packet 316 * 1: drop packet (padding data) 317 * 318 * bit 4 0 button not clicked 319 * 1 button clicked 320 * button is used to `take a picture' (in software) 321 */ 322 323 if(sts < 0x80) { 324 button = !!(sts & 0x40); 325 sts &= ~0x40; 326 } 327 328 /* work out the button status, but don't do 329 anything with it for now */ 330 331 if(button != cam->buttonsts) { 332 DEBUG(2, "button: %sclicked", button ? "" : "un"); 333 cam->buttonsts = button; 334 konicawc_report_buttonstat(cam); 335 } 336 337 if(sts == 0x01) { /* drop frame */ 338 discard++; 339 continue; 340 } 341 342 if((sts > 0x01) && (sts < 0x80)) { 343 dev_info(&uvd->dev->dev, "unknown status %2.2x\n", 344 sts); 345 bad++; 346 continue; 347 } 348 if(!sts && cam->lastframe == -2) { 349 DEBUG(2, "dropping frame looking for image start"); 350 continue; 351 } 352 353 keep++; 354 if(sts & 0x80) { /* frame start */ 355 unsigned char marker[] = { 0, 0xff, 0, 0x00 }; 356 357 if(cam->lastframe == -2) { 358 DEBUG(2, "found initial image"); 359 cam->lastframe = -1; 360 } 361 362 marker[3] = sts & 0x7F; 363 RingQueue_Enqueue(&uvd->dp, marker, 4); 364 totlen += 4; 365 } 366 367 totlen += n; /* Little local accounting */ 368 RingQueue_Enqueue(&uvd->dp, cdata, n); 369 } 370 DEBUG(8, "finished: keep = %d discard = %d bad = %d added %d bytes", 371 keep, discard, bad, totlen); 372 return totlen; 373} 374 375 376static void resubmit_urb(struct uvd *uvd, struct urb *urb) 377{ 378 int i, ret; 379 for (i = 0; i < FRAMES_PER_DESC; i++) { 380 urb->iso_frame_desc[i].status = 0; 381 } 382 urb->dev = uvd->dev; 383 urb->status = 0; 384 ret = usb_submit_urb(urb, GFP_ATOMIC); 385 DEBUG(3, "submitting urb of length %d", urb->transfer_buffer_length); 386 if(ret) 387 err("usb_submit_urb error (%d)", ret); 388 389} 390 391 392static void konicawc_isoc_irq(struct urb *urb) 393{ 394 struct uvd *uvd = urb->context; 395 struct konicawc *cam = (struct konicawc *)uvd->user_data; 396 397 /* We don't want to do anything if we are about to be removed! */ 398 if (!CAMERA_IS_OPERATIONAL(uvd)) 399 return; 400 401 if (!uvd->streaming) { 402 DEBUG(1, "Not streaming, but interrupt!"); 403 return; 404 } 405 406 DEBUG(3, "got frame %d len = %d buflen =%d", urb->start_frame, urb->actual_length, urb->transfer_buffer_length); 407 408 uvd->stats.urb_count++; 409 410 if (urb->transfer_buffer_length > 32) { 411 cam->last_data_urb = urb; 412 return; 413 } 414 /* Copy the data received into ring queue */ 415 if(cam->last_data_urb) { 416 int len = 0; 417 if(urb->start_frame != cam->last_data_urb->start_frame) 418 err("Lost sync on frames"); 419 else if (!urb->status && !cam->last_data_urb->status) 420 len = konicawc_compress_iso(uvd, cam->last_data_urb, urb); 421 422 resubmit_urb(uvd, cam->last_data_urb); 423 resubmit_urb(uvd, urb); 424 cam->last_data_urb = NULL; 425 uvd->stats.urb_length = len; 426 uvd->stats.data_count += len; 427 if(len) 428 RingQueue_WakeUpInterruptible(&uvd->dp); 429 return; 430 } 431 return; 432} 433 434 435static int konicawc_start_data(struct uvd *uvd) 436{ 437 struct usb_device *dev = uvd->dev; 438 int i, errFlag; 439 struct konicawc *cam = (struct konicawc *)uvd->user_data; 440 int pktsz; 441 struct usb_interface *intf; 442 struct usb_host_interface *interface = NULL; 443 444 intf = usb_ifnum_to_if(dev, uvd->iface); 445 if (intf) 446 interface = usb_altnum_to_altsetting(intf, 447 spd_to_iface[cam->speed]); 448 if (!interface) 449 return -ENXIO; 450 pktsz = le16_to_cpu(interface->endpoint[1].desc.wMaxPacketSize); 451 DEBUG(1, "pktsz = %d", pktsz); 452 if (!CAMERA_IS_OPERATIONAL(uvd)) { 453 err("Camera is not operational"); 454 return -EFAULT; 455 } 456 uvd->curframe = -1; 457 konicawc_camera_on(uvd); 458 /* Alternate interface 1 is is the biggest frame size */ 459 i = usb_set_interface(dev, uvd->iface, uvd->ifaceAltActive); 460 if (i < 0) { 461 err("usb_set_interface error"); 462 uvd->last_error = i; 463 return -EBUSY; 464 } 465 466 /* We double buffer the Iso lists */ 467 for (i=0; i < USBVIDEO_NUMSBUF; i++) { 468 int j, k; 469 struct urb *urb = uvd->sbuf[i].urb; 470 urb->dev = dev; 471 urb->context = uvd; 472 urb->pipe = usb_rcvisocpipe(dev, uvd->video_endp); 473 urb->interval = 1; 474 urb->transfer_flags = URB_ISO_ASAP; 475 urb->transfer_buffer = uvd->sbuf[i].data; 476 urb->complete = konicawc_isoc_irq; 477 urb->number_of_packets = FRAMES_PER_DESC; 478 urb->transfer_buffer_length = pktsz * FRAMES_PER_DESC; 479 for (j=k=0; j < FRAMES_PER_DESC; j++, k += pktsz) { 480 urb->iso_frame_desc[j].offset = k; 481 urb->iso_frame_desc[j].length = pktsz; 482 } 483 484 urb = cam->sts_urb[i]; 485 urb->dev = dev; 486 urb->context = uvd; 487 urb->pipe = usb_rcvisocpipe(dev, uvd->video_endp-1); 488 urb->interval = 1; 489 urb->transfer_flags = URB_ISO_ASAP; 490 urb->transfer_buffer = cam->sts_buf[i]; 491 urb->complete = konicawc_isoc_irq; 492 urb->number_of_packets = FRAMES_PER_DESC; 493 urb->transfer_buffer_length = FRAMES_PER_DESC; 494 for (j=0; j < FRAMES_PER_DESC; j++) { 495 urb->iso_frame_desc[j].offset = j; 496 urb->iso_frame_desc[j].length = 1; 497 } 498 } 499 500 cam->last_data_urb = NULL; 501 502 /* Submit all URBs */ 503 for (i=0; i < USBVIDEO_NUMSBUF; i++) { 504 errFlag = usb_submit_urb(cam->sts_urb[i], GFP_KERNEL); 505 if (errFlag) 506 err("usb_submit_isoc(%d) ret %d", i, errFlag); 507 508 errFlag = usb_submit_urb(uvd->sbuf[i].urb, GFP_KERNEL); 509 if (errFlag) 510 err ("usb_submit_isoc(%d) ret %d", i, errFlag); 511 } 512 513 uvd->streaming = 1; 514 DEBUG(1, "streaming=1 video_endp=$%02x", uvd->video_endp); 515 return 0; 516} 517 518 519static void konicawc_stop_data(struct uvd *uvd) 520{ 521 int i, j; 522 struct konicawc *cam; 523 524 if ((uvd == NULL) || (!uvd->streaming) || (uvd->dev == NULL)) 525 return; 526 527 konicawc_camera_off(uvd); 528 uvd->streaming = 0; 529 cam = (struct konicawc *)uvd->user_data; 530 cam->last_data_urb = NULL; 531 532 /* Unschedule all of the iso td's */ 533 for (i=0; i < USBVIDEO_NUMSBUF; i++) { 534 usb_kill_urb(uvd->sbuf[i].urb); 535 usb_kill_urb(cam->sts_urb[i]); 536 } 537 538 if (!uvd->remove_pending) { 539 /* Set packet size to 0 */ 540 j = usb_set_interface(uvd->dev, uvd->iface, uvd->ifaceAltInactive); 541 if (j < 0) { 542 err("usb_set_interface() error %d.", j); 543 uvd->last_error = j; 544 } 545 } 546} 547 548 549static void konicawc_process_isoc(struct uvd *uvd, struct usbvideo_frame *frame) 550{ 551 struct konicawc *cam = (struct konicawc *)uvd->user_data; 552 int maxline = cam->maxline; 553 int yplanesz = cam->yplanesz; 554 555 assert(frame != NULL); 556 557 DEBUG(5, "maxline = %d yplanesz = %d", maxline, yplanesz); 558 DEBUG(3, "Frame state = %d", frame->scanstate); 559 560 if(frame->scanstate == ScanState_Scanning) { 561 int drop = 0; 562 int curframe; 563 int fdrops = 0; 564 DEBUG(3, "Searching for marker, queue len = %d", RingQueue_GetLength(&uvd->dp)); 565 while(RingQueue_GetLength(&uvd->dp) >= 4) { 566 if ((RING_QUEUE_PEEK(&uvd->dp, 0) == 0x00) && 567 (RING_QUEUE_PEEK(&uvd->dp, 1) == 0xff) && 568 (RING_QUEUE_PEEK(&uvd->dp, 2) == 0x00) && 569 (RING_QUEUE_PEEK(&uvd->dp, 3) < 0x80)) { 570 curframe = RING_QUEUE_PEEK(&uvd->dp, 3); 571 if(cam->lastframe >= 0) { 572 fdrops = (0x80 + curframe - cam->lastframe) & 0x7F; 573 fdrops--; 574 if(fdrops) { 575 dev_info(&uvd->dev->dev, 576 "Dropped %d frames " 577 "(%d -> %d)\n", 578 fdrops, 579 cam->lastframe, 580 curframe); 581 } 582 } 583 cam->lastframe = curframe; 584 frame->curline = 0; 585 frame->scanstate = ScanState_Lines; 586 RING_QUEUE_DEQUEUE_BYTES(&uvd->dp, 4); 587 break; 588 } 589 RING_QUEUE_DEQUEUE_BYTES(&uvd->dp, 1); 590 drop++; 591 } 592 if(drop) 593 DEBUG(2, "dropped %d bytes looking for new frame", drop); 594 } 595 596 if(frame->scanstate == ScanState_Scanning) 597 return; 598 599 /* Try to move data from queue into frame buffer 600 * We get data in blocks of 384 bytes made up of: 601 * 256 Y, 64 U, 64 V. 602 * This needs to be written out as a Y plane, a U plane and a V plane. 603 */ 604 605 while ( frame->curline < maxline && (RingQueue_GetLength(&uvd->dp) >= 384)) { 606 /* Y */ 607 RingQueue_Dequeue(&uvd->dp, frame->data + (frame->curline * 256), 256); 608 /* U */ 609 RingQueue_Dequeue(&uvd->dp, frame->data + yplanesz + (frame->curline * 64), 64); 610 /* V */ 611 RingQueue_Dequeue(&uvd->dp, frame->data + (5 * yplanesz)/4 + (frame->curline * 64), 64); 612 frame->seqRead_Length += 384; 613 frame->curline++; 614 } 615 /* See if we filled the frame */ 616 if (frame->curline == maxline) { 617 DEBUG(5, "got whole frame"); 618 619 frame->frameState = FrameState_Done_Hold; 620 frame->curline = 0; 621 uvd->curframe = -1; 622 uvd->stats.frame_num++; 623 } 624} 625 626 627static int konicawc_find_fps(int size, int fps) 628{ 629 int i; 630 631 fps *= 3; 632 DEBUG(1, "konica_find_fps: size = %d fps = %d", size, fps); 633 if(fps <= spd_to_fps[size][0]) 634 return 0; 635 636 if(fps >= spd_to_fps[size][MAX_SPEED]) 637 return MAX_SPEED; 638 639 for(i = 0; i < MAX_SPEED; i++) { 640 if((fps >= spd_to_fps[size][i]) && (fps <= spd_to_fps[size][i+1])) { 641 DEBUG(2, "fps %d between %d and %d", fps, i, i+1); 642 if( (fps - spd_to_fps[size][i]) < (spd_to_fps[size][i+1] - fps)) 643 return i; 644 else 645 return i+1; 646 } 647 } 648 return MAX_SPEED+1; 649} 650 651 652static int konicawc_set_video_mode(struct uvd *uvd, struct video_window *vw) 653{ 654 struct konicawc *cam = (struct konicawc *)uvd->user_data; 655 int newspeed = cam->speed; 656 int newsize; 657 int x = vw->width; 658 int y = vw->height; 659 int fps = vw->flags; 660 661 if(x > 0 && y > 0) { 662 DEBUG(2, "trying to find size %d,%d", x, y); 663 for(newsize = 0; newsize <= MAX_FRAME_SIZE; newsize++) { 664 if((camera_sizes[newsize].width == x) && (camera_sizes[newsize].height == y)) 665 break; 666 } 667 } else { 668 newsize = cam->size; 669 } 670 671 if(newsize > MAX_FRAME_SIZE) { 672 DEBUG(1, "couldn't find size %d,%d", x, y); 673 return -EINVAL; 674 } 675 676 if(fps > 0) { 677 DEBUG(1, "trying to set fps to %d", fps); 678 newspeed = konicawc_find_fps(newsize, fps); 679 DEBUG(1, "find_fps returned %d (%d)", newspeed, spd_to_fps[newsize][newspeed]); 680 } 681 682 if(newspeed > MAX_SPEED) 683 return -EINVAL; 684 685 DEBUG(1, "setting size to %d speed to %d", newsize, newspeed); 686 if((newsize == cam->size) && (newspeed == cam->speed)) { 687 DEBUG(1, "Nothing to do"); 688 return 0; 689 } 690 DEBUG(0, "setting to %dx%d @ %d fps", camera_sizes[newsize].width, 691 camera_sizes[newsize].height, spd_to_fps[newsize][newspeed]/3); 692 693 konicawc_stop_data(uvd); 694 uvd->ifaceAltActive = spd_to_iface[newspeed]; 695 DEBUG(1, "new interface = %d", uvd->ifaceAltActive); 696 cam->speed = newspeed; 697 698 if(cam->size != newsize) { 699 cam->size = newsize; 700 konicawc_set_camera_size(uvd); 701 } 702 703 /* Flush the input queue and clear any current frame in progress */ 704 705 RingQueue_Flush(&uvd->dp); 706 cam->lastframe = -2; 707 if(uvd->curframe != -1) { 708 uvd->frame[uvd->curframe].curline = 0; 709 uvd->frame[uvd->curframe].seqRead_Length = 0; 710 uvd->frame[uvd->curframe].seqRead_Index = 0; 711 } 712 713 konicawc_start_data(uvd); 714 return 0; 715} 716 717 718static int konicawc_calculate_fps(struct uvd *uvd) 719{ 720 struct konicawc *cam = uvd->user_data; 721 return spd_to_fps[cam->size][cam->speed]/3; 722} 723 724 725static void konicawc_configure_video(struct uvd *uvd) 726{ 727 struct konicawc *cam = (struct konicawc *)uvd->user_data; 728 u8 buf[2]; 729 730 memset(&uvd->vpic, 0, sizeof(uvd->vpic)); 731 memset(&uvd->vpic_old, 0x55, sizeof(uvd->vpic_old)); 732 733 RESTRICT_TO_RANGE(brightness, 0, MAX_BRIGHTNESS); 734 RESTRICT_TO_RANGE(contrast, 0, MAX_CONTRAST); 735 RESTRICT_TO_RANGE(saturation, 0, MAX_SATURATION); 736 RESTRICT_TO_RANGE(sharpness, 0, MAX_SHARPNESS); 737 RESTRICT_TO_RANGE(whitebal, 0, MAX_WHITEBAL); 738 739 cam->brightness = brightness / 11; 740 cam->contrast = contrast / 11; 741 cam->saturation = saturation / 11; 742 cam->sharpness = sharpness / 11; 743 cam->white_bal = whitebal / 11; 744 745 uvd->vpic.colour = 108; 746 uvd->vpic.hue = 108; 747 uvd->vpic.brightness = brightness; 748 uvd->vpic.contrast = contrast; 749 uvd->vpic.whiteness = whitebal; 750 uvd->vpic.depth = 6; 751 uvd->vpic.palette = VIDEO_PALETTE_YUV420P; 752 753 memset(&uvd->vcap, 0, sizeof(uvd->vcap)); 754 strcpy(uvd->vcap.name, "Konica Webcam"); 755 uvd->vcap.type = VID_TYPE_CAPTURE; 756 uvd->vcap.channels = 1; 757 uvd->vcap.audios = 0; 758 uvd->vcap.minwidth = camera_sizes[SIZE_160X120].width; 759 uvd->vcap.minheight = camera_sizes[SIZE_160X120].height; 760 uvd->vcap.maxwidth = camera_sizes[SIZE_320X240].width; 761 uvd->vcap.maxheight = camera_sizes[SIZE_320X240].height; 762 763 memset(&uvd->vchan, 0, sizeof(uvd->vchan)); 764 uvd->vchan.flags = 0 ; 765 uvd->vchan.tuners = 0; 766 uvd->vchan.channel = 0; 767 uvd->vchan.type = VIDEO_TYPE_CAMERA; 768 strcpy(uvd->vchan.name, "Camera"); 769 770 /* Talk to device */ 771 DEBUG(1, "device init"); 772 if(!konicawc_get_misc(uvd, 0x3, 0, 0x10, buf, 2)) 773 DEBUG(2, "3,10 -> %2.2x %2.2x", buf[0], buf[1]); 774 if(!konicawc_get_misc(uvd, 0x3, 0, 0x10, buf, 2)) 775 DEBUG(2, "3,10 -> %2.2x %2.2x", buf[0], buf[1]); 776 if(konicawc_set_misc(uvd, 0x2, 0, 0xd)) 777 DEBUG(2, "2,0,d failed"); 778 DEBUG(1, "setting initial values"); 779} 780 781static int konicawc_probe(struct usb_interface *intf, const struct usb_device_id *devid) 782{ 783 struct usb_device *dev = interface_to_usbdev(intf); 784 struct uvd *uvd = NULL; 785 int ix, i, nas; 786 int actInterface=-1, inactInterface=-1, maxPS=0; 787 unsigned char video_ep = 0; 788 789 DEBUG(1, "konicawc_probe(%p)", intf); 790 791 /* We don't handle multi-config cameras */ 792 if (dev->descriptor.bNumConfigurations != 1) 793 return -ENODEV; 794 795 dev_info(&intf->dev, "Konica Webcam (rev. 0x%04x)\n", 796 le16_to_cpu(dev->descriptor.bcdDevice)); 797 RESTRICT_TO_RANGE(speed, 0, MAX_SPEED); 798 799 /* Validate found interface: must have one ISO endpoint */ 800 nas = intf->num_altsetting; 801 if (nas != 8) { 802 err("Incorrect number of alternate settings (%d) for this camera!", nas); 803 return -ENODEV; 804 } 805 /* Validate all alternate settings */ 806 for (ix=0; ix < nas; ix++) { 807 const struct usb_host_interface *interface; 808 const struct usb_endpoint_descriptor *endpoint; 809 810 interface = &intf->altsetting[ix]; 811 i = interface->desc.bAlternateSetting; 812 if (interface->desc.bNumEndpoints != 2) { 813 err("Interface %d. has %u. endpoints!", 814 interface->desc.bInterfaceNumber, 815 (unsigned)(interface->desc.bNumEndpoints)); 816 return -ENODEV; 817 } 818 endpoint = &interface->endpoint[1].desc; 819 DEBUG(1, "found endpoint: addr: 0x%2.2x maxps = 0x%4.4x", 820 endpoint->bEndpointAddress, le16_to_cpu(endpoint->wMaxPacketSize)); 821 if (video_ep == 0) 822 video_ep = endpoint->bEndpointAddress; 823 else if (video_ep != endpoint->bEndpointAddress) { 824 err("Alternate settings have different endpoint addresses!"); 825 return -ENODEV; 826 } 827 if (!usb_endpoint_xfer_isoc(endpoint)) { 828 err("Interface %d. has non-ISO endpoint!", 829 interface->desc.bInterfaceNumber); 830 return -ENODEV; 831 } 832 if (usb_endpoint_dir_out(endpoint)) { 833 err("Interface %d. has ISO OUT endpoint!", 834 interface->desc.bInterfaceNumber); 835 return -ENODEV; 836 } 837 if (le16_to_cpu(endpoint->wMaxPacketSize) == 0) { 838 if (inactInterface < 0) 839 inactInterface = i; 840 else { 841 err("More than one inactive alt. setting!"); 842 return -ENODEV; 843 } 844 } else { 845 if (i == spd_to_iface[speed]) { 846 /* This one is the requested one */ 847 actInterface = i; 848 } 849 } 850 if (le16_to_cpu(endpoint->wMaxPacketSize) > maxPS) 851 maxPS = le16_to_cpu(endpoint->wMaxPacketSize); 852 } 853 if(actInterface == -1) { 854 err("Cant find required endpoint"); 855 return -ENODEV; 856 } 857 858 DEBUG(1, "Selecting requested active setting=%d. maxPS=%d.", actInterface, maxPS); 859 860 uvd = usbvideo_AllocateDevice(cams); 861 if (uvd != NULL) { 862 struct konicawc *cam = (struct konicawc *)(uvd->user_data); 863 /* Here uvd is a fully allocated uvd object */ 864 for(i = 0; i < USBVIDEO_NUMSBUF; i++) { 865 cam->sts_urb[i] = usb_alloc_urb(FRAMES_PER_DESC, GFP_KERNEL); 866 if(cam->sts_urb[i] == NULL) { 867 while(i--) { 868 usb_free_urb(cam->sts_urb[i]); 869 } 870 err("can't allocate urbs"); 871 return -ENOMEM; 872 } 873 } 874 cam->speed = speed; 875 RESTRICT_TO_RANGE(size, SIZE_160X120, SIZE_320X240); 876 cam->width = camera_sizes[size].width; 877 cam->height = camera_sizes[size].height; 878 cam->size = size; 879 880 uvd->flags = 0; 881 uvd->debug = debug; 882 uvd->dev = dev; 883 uvd->iface = intf->altsetting->desc.bInterfaceNumber; 884 uvd->ifaceAltInactive = inactInterface; 885 uvd->ifaceAltActive = actInterface; 886 uvd->video_endp = video_ep; 887 uvd->iso_packet_len = maxPS; 888 uvd->paletteBits = 1L << VIDEO_PALETTE_YUV420P; 889 uvd->defaultPalette = VIDEO_PALETTE_YUV420P; 890 uvd->canvas = VIDEOSIZE(320, 240); 891 uvd->videosize = VIDEOSIZE(cam->width, cam->height); 892 893 /* Initialize konicawc specific data */ 894 konicawc_configure_video(uvd); 895 896 i = usbvideo_RegisterVideoDevice(uvd); 897 uvd->max_frame_size = (320 * 240 * 3)/2; 898 if (i != 0) { 899 err("usbvideo_RegisterVideoDevice() failed."); 900 uvd = NULL; 901 } 902 903 konicawc_register_input(cam, dev); 904 } 905 906 if (uvd) { 907 usb_set_intfdata (intf, uvd); 908 return 0; 909 } 910 return -EIO; 911} 912 913 914static void konicawc_free_uvd(struct uvd *uvd) 915{ 916 int i; 917 struct konicawc *cam = (struct konicawc *)uvd->user_data; 918 919 konicawc_unregister_input(cam); 920 921 for (i = 0; i < USBVIDEO_NUMSBUF; i++) { 922 usb_free_urb(cam->sts_urb[i]); 923 cam->sts_urb[i] = NULL; 924 } 925} 926 927 928static struct usb_device_id id_table[] = { 929 { USB_DEVICE(0x04c8, 0x0720) }, /* Intel YC 76 */ 930 { } /* Terminating entry */ 931}; 932 933 934static int __init konicawc_init(void) 935{ 936 struct usbvideo_cb cbTbl; 937 printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":" 938 DRIVER_DESC "\n"); 939 memset(&cbTbl, 0, sizeof(cbTbl)); 940 cbTbl.probe = konicawc_probe; 941 cbTbl.setupOnOpen = konicawc_setup_on_open; 942 cbTbl.processData = konicawc_process_isoc; 943 cbTbl.getFPS = konicawc_calculate_fps; 944 cbTbl.setVideoMode = konicawc_set_video_mode; 945 cbTbl.startDataPump = konicawc_start_data; 946 cbTbl.stopDataPump = konicawc_stop_data; 947 cbTbl.adjustPicture = konicawc_adjust_picture; 948 cbTbl.userFree = konicawc_free_uvd; 949 return usbvideo_register( 950 &cams, 951 MAX_CAMERAS, 952 sizeof(struct konicawc), 953 "konicawc", 954 &cbTbl, 955 THIS_MODULE, 956 id_table); 957} 958 959 960static void __exit konicawc_cleanup(void) 961{ 962 usbvideo_Deregister(&cams); 963} 964 965 966MODULE_DEVICE_TABLE(usb, id_table); 967 968MODULE_LICENSE("GPL"); 969MODULE_AUTHOR("Simon Evans <spse@secret.org.uk>"); 970MODULE_DESCRIPTION(DRIVER_DESC); 971module_param(speed, int, 0); 972MODULE_PARM_DESC(speed, "Initial speed: 0 (slowest) - 6 (fastest)"); 973module_param(size, int, 0); 974MODULE_PARM_DESC(size, "Initial Size 0: 160x120 1: 160x136 2: 176x144 3: 320x240"); 975module_param(brightness, int, 0); 976MODULE_PARM_DESC(brightness, "Initial brightness 0 - 108"); 977module_param(contrast, int, 0); 978MODULE_PARM_DESC(contrast, "Initial contrast 0 - 108"); 979module_param(saturation, int, 0); 980MODULE_PARM_DESC(saturation, "Initial saturation 0 - 108"); 981module_param(sharpness, int, 0); 982MODULE_PARM_DESC(sharpness, "Initial brightness 0 - 108"); 983module_param(whitebal, int, 0); 984MODULE_PARM_DESC(whitebal, "Initial white balance 0 - 363"); 985 986#ifdef CONFIG_USB_DEBUG 987module_param(debug, int, S_IRUGO | S_IWUSR); 988MODULE_PARM_DESC(debug, "Debug level: 0-9 (default=0)"); 989#endif 990 991module_init(konicawc_init); 992module_exit(konicawc_cleanup); 993