1 /***************************************************************************
2 * Video4Linux driver for W996[87]CF JPEG USB Dual Mode Camera Chip. *
4 * Copyright (C) 2002-2004 by Luca Risolia <luca.risolia@studio.unibo.it> *
6 * - Memory management code from bttv driver by Ralph Metzler, *
7 * Marcus Metzler and Gerd Knorr. *
8 * - I2C interface to kernel, high-level CMOS sensor control routines and *
9 * some symbolic names from OV511 driver by Mark W. McClelland. *
10 * - Low-level I2C fast write function by Piotr Czerczak. *
11 * - Low-level I2C read function by Frederic Jouault. *
13 * This program is free software; you can redistribute it and/or modify *
14 * it under the terms of the GNU General Public License as published by *
15 * the Free Software Foundation; either version 2 of the License, or *
16 * (at your option) any later version. *
18 * This program is distributed in the hope that it will be useful, *
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
21 * GNU General Public License for more details. *
23 * You should have received a copy of the GNU General Public License *
24 * along with this program; if not, write to the Free Software *
25 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
26 ***************************************************************************/
28 #include <linux/version.h>
29 #include <linux/module.h>
30 #include <linux/moduleparam.h>
31 #include <linux/kernel.h>
32 #include <linux/init.h>
34 #include <linux/vmalloc.h>
35 #include <linux/slab.h>
37 #include <linux/string.h>
38 #include <linux/ctype.h>
39 #include <linux/errno.h>
40 #include <linux/sched.h>
41 #include <linux/ioctl.h>
42 #include <linux/delay.h>
44 #include <asm/uaccess.h>
47 #include "w9968cf_decoder.h"
51 /****************************************************************************
52 * Module macros and paramaters *
53 ****************************************************************************/
55 MODULE_AUTHOR(W9968CF_MODULE_AUTHOR" "W9968CF_AUTHOR_EMAIL);
56 MODULE_DESCRIPTION(W9968CF_MODULE_NAME" "W9968CF_MODULE_VERSION);
57 MODULE_LICENSE(W9968CF_MODULE_LICENSE);
58 MODULE_SUPPORTED_DEVICE("Video");
60 static int vppmod_load = W9968CF_VPPMOD_LOAD;
61 static unsigned short simcams = W9968CF_SIMCAMS;
62 static short video_nr[]={[0 ... W9968CF_MAX_DEVICES-1] = -1}; /*-1=first free*/
63 static unsigned int packet_size[] = {[0 ... W9968CF_MAX_DEVICES-1] =
65 static unsigned short max_buffers[] = {[0 ... W9968CF_MAX_DEVICES-1] =
67 static int double_buffer[] = {[0 ... W9968CF_MAX_DEVICES-1] =
68 W9968CF_DOUBLE_BUFFER};
69 static int clamping[] = {[0 ... W9968CF_MAX_DEVICES-1] = W9968CF_CLAMPING};
70 static unsigned short filter_type[]= {[0 ... W9968CF_MAX_DEVICES-1] =
72 static int largeview[]= {[0 ... W9968CF_MAX_DEVICES-1] = W9968CF_LARGEVIEW};
73 static unsigned short decompression[] = {[0 ... W9968CF_MAX_DEVICES-1] =
74 W9968CF_DECOMPRESSION};
75 static int upscaling[]= {[0 ... W9968CF_MAX_DEVICES-1] = W9968CF_UPSCALING};
76 static unsigned short force_palette[] = {[0 ... W9968CF_MAX_DEVICES-1] = 0};
77 static int force_rgb[] = {[0 ... W9968CF_MAX_DEVICES-1] = W9968CF_FORCE_RGB};
78 static int autobright[] = {[0 ... W9968CF_MAX_DEVICES-1] = W9968CF_AUTOBRIGHT};
79 static int autoexp[] = {[0 ... W9968CF_MAX_DEVICES-1] = W9968CF_AUTOEXP};
80 static unsigned short lightfreq[] = {[0 ... W9968CF_MAX_DEVICES-1] =
82 static int bandingfilter[] = {[0 ... W9968CF_MAX_DEVICES-1]=
83 W9968CF_BANDINGFILTER};
84 static short clockdiv[] = {[0 ... W9968CF_MAX_DEVICES-1] = W9968CF_CLOCKDIV};
85 static int backlight[] = {[0 ... W9968CF_MAX_DEVICES-1] = W9968CF_BACKLIGHT};
86 static int mirror[] = {[0 ... W9968CF_MAX_DEVICES-1] = W9968CF_MIRROR};
87 static int monochrome[] = {[0 ... W9968CF_MAX_DEVICES-1]=W9968CF_MONOCHROME};
88 static unsigned int brightness[] = {[0 ... W9968CF_MAX_DEVICES-1] =
90 static unsigned int hue[] = {[0 ... W9968CF_MAX_DEVICES-1] = W9968CF_HUE};
91 static unsigned int colour[]={[0 ... W9968CF_MAX_DEVICES-1] = W9968CF_COLOUR};
92 static unsigned int contrast[] = {[0 ... W9968CF_MAX_DEVICES-1] =
94 static unsigned int whiteness[] = {[0 ... W9968CF_MAX_DEVICES-1] =
97 static unsigned short debug = W9968CF_DEBUG_LEVEL;
98 static int specific_debug = W9968CF_SPECIFIC_DEBUG;
101 static unsigned int param_nv[24]; /* number of values per parameter */
103 module_param(vppmod_load, bool, 0444);
104 module_param(simcams, ushort, 0444);
105 module_param_array(video_nr, short, param_nv[0], 0444);
106 module_param_array(packet_size, uint, param_nv[1], 0444);
107 module_param_array(max_buffers, ushort, param_nv[2], 0444);
108 module_param_array(double_buffer, bool, param_nv[3], 0444);
109 module_param_array(clamping, bool, param_nv[4], 0444);
110 module_param_array(filter_type, ushort, param_nv[5], 0444);
111 module_param_array(largeview, bool, param_nv[6], 0444);
112 module_param_array(decompression, ushort, param_nv[7], 0444);
113 module_param_array(upscaling, bool, param_nv[8], 0444);
114 module_param_array(force_palette, ushort, param_nv[9], 0444);
115 module_param_array(force_rgb, ushort, param_nv[10], 0444);
116 module_param_array(autobright, bool, param_nv[11], 0444);
117 module_param_array(autoexp, bool, param_nv[12], 0444);
118 module_param_array(lightfreq, ushort, param_nv[13], 0444);
119 module_param_array(bandingfilter, bool, param_nv[14], 0444);
120 module_param_array(clockdiv, short, param_nv[15], 0444);
121 module_param_array(backlight, bool, param_nv[16], 0444);
122 module_param_array(mirror, bool, param_nv[17], 0444);
123 module_param_array(monochrome, bool, param_nv[18], 0444);
124 module_param_array(brightness, uint, param_nv[19], 0444);
125 module_param_array(hue, uint, param_nv[20], 0444);
126 module_param_array(colour, uint, param_nv[21], 0444);
127 module_param_array(contrast, uint, param_nv[22], 0444);
128 module_param_array(whiteness, uint, param_nv[23], 0444);
130 module_param(debug, ushort, 0444);
131 module_param(specific_debug, bool, 0444);
134 MODULE_PARM_DESC(vppmod_load,
135 "\n<0|1> Automatic 'w9968cf-vpp' module loading."
136 "\n0 disable, 1 enable."
137 "\nIf enabled, every time an application attempts to open a"
138 "\ncamera, 'insmod' searches for the video post-processing"
139 "\nmodule in the system and loads it automatically (if"
140 "\npresent). The 'w9968cf-vpp' module adds extra image"
141 "\nmanipulation functions to the 'w9968cf' module, like"
142 "\nsoftware up-scaling,colour conversions and video decoding."
143 "\nDefault value is "__MODULE_STRING(W9968CF_VPPMOD_LOAD)"."
145 MODULE_PARM_DESC(simcams,
146 "\n<n> Number of cameras allowed to stream simultaneously."
147 "\nn may vary from 0 to "
148 __MODULE_STRING(W9968CF_MAX_DEVICES)"."
149 "\nDefault value is "__MODULE_STRING(W9968CF_SIMCAMS)"."
151 MODULE_PARM_DESC(video_nr,
152 "\n<-1|n[,...]> Specify V4L minor mode number."
153 "\n -1 = use next available (default)"
154 "\n n = use minor number n (integer >= 0)"
155 "\nYou can specify up to "__MODULE_STRING(W9968CF_MAX_DEVICES)
158 "\nvideo_nr=-1,2,-1 would assign minor number 2 to"
159 "\nthe second camera and use auto for the first"
160 "\none and for every other camera."
162 MODULE_PARM_DESC(packet_size,
163 "\n<n[,...]> Specify the maximum data payload"
164 "\nsize in bytes for alternate settings, for each device."
165 "\nn is scaled between 63 and 1023 "
166 "(default is "__MODULE_STRING(W9968CF_PACKET_SIZE)")."
168 MODULE_PARM_DESC(max_buffers,
169 "\n<n[,...]> For advanced users."
170 "\nSpecify the maximum number of video frame buffers"
171 "\nto allocate for each device, from 2 to "
172 __MODULE_STRING(W9968CF_MAX_BUFFERS)
173 ". (default is "__MODULE_STRING(W9968CF_BUFFERS)")."
175 MODULE_PARM_DESC(double_buffer,
177 "Hardware double buffering: 0 disabled, 1 enabled."
178 "\nIt should be enabled if you want smooth video output: if"
179 "\nyou obtain out of sync. video, disable it at all, or try"
180 "\nto decrease the 'clockdiv' module paramater value."
181 "\nDefault value is "__MODULE_STRING(W9968CF_DOUBLE_BUFFER)
184 MODULE_PARM_DESC(clamping,
185 "\n<0|1[,...]> Video data clamping: 0 disabled, 1 enabled."
186 "\nDefault value is "__MODULE_STRING(W9968CF_CLAMPING)
189 MODULE_PARM_DESC(filter_type,
190 "\n<0|1|2[,...]> Video filter type."
191 "\n0 none, 1 (1-2-1) 3-tap filter, "
192 "2 (2-3-6-3-2) 5-tap filter."
193 "\nDefault value is "__MODULE_STRING(W9968CF_FILTER_TYPE)
195 "\nThe filter is used to reduce noise and aliasing artifacts"
196 "\nproduced by the CCD or CMOS sensor, and the scaling"
199 MODULE_PARM_DESC(largeview,
200 "\n<0|1[,...]> Large view: 0 disabled, 1 enabled."
201 "\nDefault value is "__MODULE_STRING(W9968CF_LARGEVIEW)
204 MODULE_PARM_DESC(upscaling,
205 "\n<0|1[,...]> Software scaling (for non-compressed video):"
206 "\n0 disabled, 1 enabled."
207 "\nDisable it if you have a slow CPU or you don't have"
209 "\nDefault value is "__MODULE_STRING(W9968CF_UPSCALING)
211 "\nIf 'w9968cf-vpp' is not loaded, this paramater is"
214 MODULE_PARM_DESC(decompression,
215 "\n<0|1|2[,...]> Software video decompression:"
216 "\n- 0 disables decompression (doesn't allow formats needing"
218 "\n- 1 forces decompression (allows formats needing"
219 " decompression only);"
220 "\n- 2 allows any permitted formats."
221 "\nFormats supporting compressed video are YUV422P and"
223 "\nin any resolutions where both width and height are "
225 "\nDefault value is "__MODULE_STRING(W9968CF_DECOMPRESSION)
227 "\nIf 'w9968cf-vpp' is not loaded, forcing decompression is "
228 "\nnot allowed; in this case this paramater is set to 2."
230 MODULE_PARM_DESC(force_palette,
232 "|" __MODULE_STRING(VIDEO_PALETTE_UYVY)
233 "|" __MODULE_STRING(VIDEO_PALETTE_YUV420)
234 "|" __MODULE_STRING(VIDEO_PALETTE_YUV422P)
235 "|" __MODULE_STRING(VIDEO_PALETTE_YUV420P)
236 "|" __MODULE_STRING(VIDEO_PALETTE_YUYV)
237 "|" __MODULE_STRING(VIDEO_PALETTE_YUV422)
238 "|" __MODULE_STRING(VIDEO_PALETTE_GREY)
239 "|" __MODULE_STRING(VIDEO_PALETTE_RGB555)
240 "|" __MODULE_STRING(VIDEO_PALETTE_RGB565)
241 "|" __MODULE_STRING(VIDEO_PALETTE_RGB24)
242 "|" __MODULE_STRING(VIDEO_PALETTE_RGB32)
244 " Force picture palette."
246 "\n- 0 allows any of the following formats:"
247 "\n- UYVY 16 bpp - Original video, compression disabled"
248 "\n- YUV420 12 bpp - Original video, compression enabled"
249 "\n- YUV422P 16 bpp - Original video, compression enabled"
250 "\n- YUV420P 12 bpp - Original video, compression enabled"
251 "\n- YUVY 16 bpp - Software conversion from UYVY"
252 "\n- YUV422 16 bpp - Software conversion from UYVY"
253 "\n- GREY 8 bpp - Software conversion from UYVY"
254 "\n- RGB555 16 bpp - Software conversion from UYVY"
255 "\n- RGB565 16 bpp - Software conversion from UYVY"
256 "\n- RGB24 24 bpp - Software conversion from UYVY"
257 "\n- RGB32 32 bpp - Software conversion from UYVY"
258 "\nWhen not 0, this paramater will override 'decompression'."
259 "\nDefault value is 0 for every device."
260 "\nInitial palette is "
261 __MODULE_STRING(W9968CF_PALETTE_DECOMP_ON)"."
262 "\nIf 'w9968cf-vpp' is not loaded, this paramater is"
265 MODULE_PARM_DESC(force_rgb,
266 "\n<0|1[,...]> Read RGB video data instead of BGR:"
267 "\n 1 = use RGB component ordering."
268 "\n 0 = use BGR component ordering."
269 "\nThis parameter has effect when using RGBX palettes only."
270 "\nDefault value is "__MODULE_STRING(W9968CF_FORCE_RGB)
273 MODULE_PARM_DESC(autobright,
274 "\n<0|1[,...]> CMOS sensor automatically changes brightness:"
276 "\nDefault value is "__MODULE_STRING(W9968CF_AUTOBRIGHT)
279 MODULE_PARM_DESC(autoexp,
280 "\n<0|1[,...]> CMOS sensor automatically changes exposure:"
282 "\nDefault value is "__MODULE_STRING(W9968CF_AUTOEXP)
285 MODULE_PARM_DESC(lightfreq,
286 "\n<50|60[,...]> Light frequency in Hz:"
287 "\n 50 for European and Asian lighting,"
288 " 60 for American lighting."
289 "\nDefault value is "__MODULE_STRING(W9968CF_LIGHTFREQ)
292 MODULE_PARM_DESC(bandingfilter,
293 "\n<0|1[,...]> Banding filter to reduce effects of"
294 " fluorescent lighting:"
295 "\n 0 disabled, 1 enabled."
296 "\nThis filter tries to reduce the pattern of horizontal"
297 "\nlight/dark bands caused by some (usually fluorescent)"
299 "\nDefault value is "__MODULE_STRING(W9968CF_BANDINGFILTER)
302 MODULE_PARM_DESC(clockdiv,
304 "Force pixel clock divisor to a specific value (for experts):"
305 "\n n may vary from 0 to 127."
306 "\n -1 for automatic value."
307 "\nSee also the 'double_buffer' module paramater."
308 "\nDefault value is "__MODULE_STRING(W9968CF_CLOCKDIV)
311 MODULE_PARM_DESC(backlight,
312 "\n<0|1[,...]> Objects are lit from behind:"
314 "\nDefault value is "__MODULE_STRING(W9968CF_BACKLIGHT)
317 MODULE_PARM_DESC(mirror,
318 "\n<0|1[,...]> Reverse image horizontally:"
320 "\nDefault value is "__MODULE_STRING(W9968CF_MIRROR)
323 MODULE_PARM_DESC(monochrome,
324 "\n<0|1[,...]> Use OV CMOS sensor as monochrome sensor:"
326 "\nNot all the sensors support monochrome color."
327 "\nDefault value is "__MODULE_STRING(W9968CF_MONOCHROME)
330 MODULE_PARM_DESC(brightness,
331 "\n<n[,...]> Set picture brightness (0-65535)."
332 "\nDefault value is "__MODULE_STRING(W9968CF_BRIGHTNESS)
334 "\nThis parameter has no effect if 'autobright' is enabled."
336 MODULE_PARM_DESC(hue,
337 "\n<n[,...]> Set picture hue (0-65535)."
338 "\nDefault value is "__MODULE_STRING(W9968CF_HUE)
341 MODULE_PARM_DESC(colour,
342 "\n<n[,...]> Set picture saturation (0-65535)."
343 "\nDefault value is "__MODULE_STRING(W9968CF_COLOUR)
346 MODULE_PARM_DESC(contrast,
347 "\n<n[,...]> Set picture contrast (0-65535)."
348 "\nDefault value is "__MODULE_STRING(W9968CF_CONTRAST)
351 MODULE_PARM_DESC(whiteness,
352 "\n<n[,...]> Set picture whiteness (0-65535)."
353 "\nDefault value is "__MODULE_STRING(W9968CF_WHITENESS)
357 MODULE_PARM_DESC(debug,
358 "\n<n> Debugging information level, from 0 to 6:"
359 "\n0 = none (use carefully)"
360 "\n1 = critical errors"
361 "\n2 = significant informations"
362 "\n3 = configuration or general messages"
364 "\n5 = called functions"
365 "\n6 = function internals"
366 "\nLevel 5 and 6 are useful for testing only, when just "
367 "one device is used."
368 "\nDefault value is "__MODULE_STRING(W9968CF_DEBUG_LEVEL)"."
370 MODULE_PARM_DESC(specific_debug,
371 "\n<0|1> Enable or disable specific debugging messages:"
372 "\n0 = print messages concerning every level"
374 "\n1 = print messages concerning the level"
375 " indicated by 'debug'."
376 "\nDefault value is "
377 __MODULE_STRING(W9968CF_SPECIFIC_DEBUG)"."
379 #endif /* W9968CF_DEBUG */
383 /****************************************************************************
385 ****************************************************************************/
387 /* Video4linux interface */
388 static struct file_operations w9968cf_fops;
389 static int w9968cf_open(struct inode*, struct file*);
390 static int w9968cf_release(struct inode*, struct file*);
391 static ssize_t w9968cf_read(struct file*, char __user *, size_t, loff_t*);
392 static int w9968cf_mmap(struct file*, struct vm_area_struct*);
393 static int w9968cf_ioctl(struct inode*, struct file*, unsigned, unsigned long);
394 static int w9968cf_v4l_ioctl(struct inode*, struct file*, unsigned int, void*);
397 static int w9968cf_start_transfer(struct w9968cf_device*);
398 static void w9968cf_urb_complete(struct urb *urb, struct pt_regs *regs);
399 static int w9968cf_stop_transfer(struct w9968cf_device*);
400 static int w9968cf_write_reg(struct w9968cf_device*, u16 value, u16 index);
401 static int w9968cf_read_reg(struct w9968cf_device*, u16 index);
402 static int w9968cf_write_fsb(struct w9968cf_device*, u16* data);
403 static int w9968cf_write_sb(struct w9968cf_device*, u16 value);
404 static int w9968cf_read_sb(struct w9968cf_device*);
405 static int w9968cf_upload_quantizationtables(struct w9968cf_device*);
407 /* Low-level I2C (SMBus) I/O */
408 static int w9968cf_smbus_start(struct w9968cf_device*);
409 static int w9968cf_smbus_stop(struct w9968cf_device*);
410 static int w9968cf_smbus_write_byte(struct w9968cf_device*, u8 v);
411 static int w9968cf_smbus_read_byte(struct w9968cf_device*, u8* v);
412 static int w9968cf_smbus_write_ack(struct w9968cf_device*);
413 static int w9968cf_smbus_read_ack(struct w9968cf_device*);
414 static int w9968cf_smbus_refresh_bus(struct w9968cf_device*);
415 static int w9968cf_i2c_adap_read_byte(struct w9968cf_device* cam,
416 u16 address, u8* value);
417 static int w9968cf_i2c_adap_read_byte_data(struct w9968cf_device*, u16 address,
418 u8 subaddress, u8* value);
419 static int w9968cf_i2c_adap_write_byte(struct w9968cf_device*,
420 u16 address, u8 subaddress);
421 static int w9968cf_i2c_adap_fastwrite_byte_data(struct w9968cf_device*,
422 u16 address, u8 subaddress,
425 /* I2C interface to kernel */
426 static int w9968cf_i2c_init(struct w9968cf_device*);
427 static int w9968cf_i2c_smbus_xfer(struct i2c_adapter*, u16 addr,
428 unsigned short flags, char read_write,
429 u8 command, int size, union i2c_smbus_data*);
430 static u32 w9968cf_i2c_func(struct i2c_adapter*);
431 static int w9968cf_i2c_attach_inform(struct i2c_client*);
432 static int w9968cf_i2c_detach_inform(struct i2c_client*);
433 static int w9968cf_i2c_control(struct i2c_adapter*, unsigned int cmd,
436 /* Memory management */
437 static inline unsigned long kvirt_to_pa(unsigned long adr);
438 static void* rvmalloc(unsigned long size);
439 static void rvfree(void *mem, unsigned long size);
440 static void w9968cf_deallocate_memory(struct w9968cf_device*);
441 static int w9968cf_allocate_memory(struct w9968cf_device*);
442 static inline unsigned long w9968cf_get_max_bufsize(struct w9968cf_device*);
444 /* High-level CMOS sensor control functions */
445 static int w9968cf_sensor_set_control(struct w9968cf_device*,int cid,int val);
446 static int w9968cf_sensor_get_control(struct w9968cf_device*,int cid,int *val);
447 static int w9968cf_sensor_cmd(struct w9968cf_device*,
448 unsigned int cmd, void *arg);
449 static int w9968cf_sensor_init(struct w9968cf_device*);
450 static int w9968cf_sensor_update_settings(struct w9968cf_device*);
451 static int w9968cf_sensor_get_picture(struct w9968cf_device*);
452 static int w9968cf_sensor_update_picture(struct w9968cf_device*,
453 struct video_picture pict);
455 /* Other helper functions */
456 static void w9968cf_configure_camera(struct w9968cf_device*,struct usb_device*,
457 enum w9968cf_model_id,
458 const unsigned short dev_nr);
459 static int w9968cf_turn_on_led(struct w9968cf_device*);
460 static int w9968cf_init_chip(struct w9968cf_device*);
461 static int w9968cf_set_picture(struct w9968cf_device*, struct video_picture);
462 static int w9968cf_set_window(struct w9968cf_device*, struct video_window);
463 static inline u16 w9968cf_valid_palette(u16 palette);
464 static u16 w9968cf_valid_depth(u16 palette);
465 static inline u8 w9968cf_need_decompression(u16 palette);
466 static int w9968cf_postprocess_frame(struct w9968cf_device*,
467 struct w9968cf_frame_t*);
468 static int w9968cf_adjust_window_size(struct w9968cf_device*, u16* w, u16* h);
469 static void w9968cf_init_framelist(struct w9968cf_device*);
470 static void w9968cf_push_frame(struct w9968cf_device*, u8 f_num);
471 static void w9968cf_pop_frame(struct w9968cf_device*,struct w9968cf_frame_t**);
472 static void w9968cf_release_resources(struct w9968cf_device*);
474 /* Intermodule communication */
475 static int w9968cf_vppmod_detect(void);
476 static void w9968cf_vppmod_release(void);
478 /* Pointers to registered video post-processing functions */
479 static void (*w9968cf_vpp_init_decoder)(void);
480 static int (*w9968cf_vpp_check_headers)(const unsigned char*,
481 const unsigned long);
482 static int (*w9968cf_vpp_decode)(const char*, const unsigned,
483 const unsigned, const unsigned, char*);
484 static void (*w9968cf_vpp_swap_yuvbytes)(void*, unsigned long);
485 static void (*w9968cf_vpp_uyvy_to_rgbx)(u8*, unsigned long, u8*, u16, u8);
486 static void (*w9968cf_vpp_scale_up)(u8*, u8*, u16, u16, u16, u16, u16);
490 /****************************************************************************
492 ****************************************************************************/
494 /* Used to represent a list of values and their respective symbolic names */
495 struct w9968cf_symbolic_list {
500 /*--------------------------------------------------------------------------
501 Returns the name of the matching element in the symbolic_list array. The
502 end of the list must be marked with an element that has a NULL name.
503 --------------------------------------------------------------------------*/
504 static inline const char *
505 symbolic(struct w9968cf_symbolic_list list[], const int num)
509 for (i = 0; list[i].name != NULL; i++)
510 if (list[i].num == num)
511 return (list[i].name);
516 static struct w9968cf_symbolic_list camlist[] = {
517 { W9968CF_MOD_GENERIC, "W996[87]CF JPEG USB Dual Mode Camera" },
518 { W9968CF_MOD_CLVBWGP, "Creative Labs Video Blaster WebCam Go Plus" },
520 /* Other cameras (having the same descriptors as Generic W996[87]CF) */
521 { W9968CF_MOD_ADPA5R, "Aroma Digi Pen ADG-5000 Refurbished" },
522 { W9986CF_MOD_AU, "AVerTV USB" },
523 { W9968CF_MOD_CLVBWG, "Creative Labs Video Blaster WebCam Go" },
524 { W9968CF_MOD_DLLDK, "Die Lebon LDC-D35A Digital Kamera" },
525 { W9968CF_MOD_EEEMC, "Ezonics EZ-802 EZMega Cam" },
526 { W9968CF_MOD_ODPVDMPC, "OPCOM Digi Pen VGA Dual Mode Pen Camera" },
531 static struct w9968cf_symbolic_list senlist[] = {
532 { CC_OV76BE, "OV76BE" },
533 { CC_OV7610, "OV7610" },
534 { CC_OV7620, "OV7620" },
535 { CC_OV7620AE, "OV7620AE" },
536 { CC_OV6620, "OV6620" },
537 { CC_OV6630, "OV6630" },
538 { CC_OV6630AE, "OV6630AE" },
539 { CC_OV6630AF, "OV6630AF" },
543 /* Video4Linux1 palettes */
544 static struct w9968cf_symbolic_list v4l1_plist[] = {
545 { VIDEO_PALETTE_GREY, "GREY" },
546 { VIDEO_PALETTE_HI240, "HI240" },
547 { VIDEO_PALETTE_RGB565, "RGB565" },
548 { VIDEO_PALETTE_RGB24, "RGB24" },
549 { VIDEO_PALETTE_RGB32, "RGB32" },
550 { VIDEO_PALETTE_RGB555, "RGB555" },
551 { VIDEO_PALETTE_YUV422, "YUV422" },
552 { VIDEO_PALETTE_YUYV, "YUYV" },
553 { VIDEO_PALETTE_UYVY, "UYVY" },
554 { VIDEO_PALETTE_YUV420, "YUV420" },
555 { VIDEO_PALETTE_YUV411, "YUV411" },
556 { VIDEO_PALETTE_RAW, "RAW" },
557 { VIDEO_PALETTE_YUV422P, "YUV422P" },
558 { VIDEO_PALETTE_YUV411P, "YUV411P" },
559 { VIDEO_PALETTE_YUV420P, "YUV420P" },
560 { VIDEO_PALETTE_YUV410P, "YUV410P" },
564 /* Decoder error codes: */
565 static struct w9968cf_symbolic_list decoder_errlist[] = {
566 { W9968CF_DEC_ERR_CORRUPTED_DATA, "Corrupted data" },
567 { W9968CF_DEC_ERR_BUF_OVERFLOW, "Buffer overflow" },
568 { W9968CF_DEC_ERR_NO_SOI, "SOI marker not found" },
569 { W9968CF_DEC_ERR_NO_SOF0, "SOF0 marker not found" },
570 { W9968CF_DEC_ERR_NO_SOS, "SOS marker not found" },
571 { W9968CF_DEC_ERR_NO_EOI, "EOI marker not found" },
575 /* URB error codes: */
576 static struct w9968cf_symbolic_list urb_errlist[] = {
577 { -ENOMEM, "No memory for allocation of internal structures" },
578 { -ENOSPC, "The host controller's bandwidth is already consumed" },
579 { -ENOENT, "URB was canceled by unlink_urb" },
580 { -EXDEV, "ISO transfer only partially completed" },
581 { -EAGAIN, "Too match scheduled for the future" },
582 { -ENXIO, "URB already queued" },
583 { -EFBIG, "Too much ISO frames requested" },
584 { -ENOSR, "Buffer error (overrun)" },
585 { -EPIPE, "Specified endpoint is stalled (device not responding)"},
586 { -EOVERFLOW, "Babble (bad cable?)" },
587 { -EPROTO, "Bit-stuff error (bad cable?)" },
588 { -EILSEQ, "CRC/Timeout" },
589 { -ETIMEDOUT, "NAK (device does not respond)" },
595 /****************************************************************************
596 * Memory management functions *
597 ****************************************************************************/
599 /* Here we want the physical address of the memory.
600 This is used when initializing the contents of the area. */
601 static inline unsigned long kvirt_to_pa(unsigned long adr)
603 unsigned long kva, ret;
605 kva = (unsigned long) page_address(vmalloc_to_page((void *)adr));
606 kva |= adr & (PAGE_SIZE-1); /* restore the offset */
612 static void* rvmalloc(unsigned long size)
617 size = PAGE_ALIGN(size);
618 mem = vmalloc_32(size);
622 memset(mem, 0, size); /* Clear the ram out, no junk to the user */
623 adr = (unsigned long) mem;
625 SetPageReserved(vmalloc_to_page((void *)adr));
634 static void rvfree(void* mem, unsigned long size)
641 adr = (unsigned long) mem;
642 while ((long) size > 0) {
643 ClearPageReserved(vmalloc_to_page((void *)adr));
651 /*--------------------------------------------------------------------------
652 Return the maximum size (in bytes) of a frame buffer.
653 --------------------------------------------------------------------------*/
654 static inline unsigned long w9968cf_get_max_bufsize(struct w9968cf_device* cam)
656 u8 bpp = (w9968cf_vppmod_present) ? 4 : 2;
657 return (cam->upscaling) ? W9968CF_MAX_WIDTH*W9968CF_MAX_HEIGHT*bpp :
658 cam->maxwidth*cam->maxheight*bpp;
662 /*--------------------------------------------------------------------------
663 Deallocate previously allocated memory.
664 --------------------------------------------------------------------------*/
665 static void w9968cf_deallocate_memory(struct w9968cf_device* cam)
669 /* Free the isochronous transfer buffers */
670 for (i = 0; i < W9968CF_URBS; i++) {
671 kfree(cam->transfer_buffer[i]);
672 cam->transfer_buffer[i] = NULL;
675 /* Free temporary frame buffer */
676 if (cam->frame_tmp.buffer) {
677 rvfree(cam->frame_tmp.buffer, W9968CF_HW_BUF_SIZE);
678 cam->frame_tmp.buffer = NULL;
681 /* Free helper buffer */
682 if (cam->vpp_buffer) {
683 rvfree(cam->vpp_buffer, w9968cf_get_max_bufsize(cam));
684 cam->vpp_buffer = NULL;
687 /* Free video frame buffers */
688 if (cam->frame[0].buffer) {
689 rvfree(cam->frame[0].buffer,
690 cam->nbuffers * w9968cf_get_max_bufsize(cam));
691 cam->frame[0].buffer = NULL;
696 DBG(5, "Memory successfully deallocated.")
700 /*--------------------------------------------------------------------------
701 Allocate memory buffers for USB transfers and video frames.
702 This function is called by open() only.
703 Return 0 on success, a negative number otherwise.
704 --------------------------------------------------------------------------*/
705 static int w9968cf_allocate_memory(struct w9968cf_device* cam)
707 const unsigned long bufsize = w9968cf_get_max_bufsize(cam);
708 const u16 p_size = wMaxPacketSize[cam->altsetting-1];
712 /* NOTE: Deallocation is done elsewhere in case of error */
714 /* Allocate memory for the isochronous transfer buffers */
715 for (i = 0; i < W9968CF_URBS; i++) {
716 if (!(cam->transfer_buffer[i] =
717 kmalloc(W9968CF_ISO_PACKETS*p_size, GFP_KERNEL))) {
718 DBG(1, "Couldn't allocate memory for the isochronous "
719 "transfer buffers (%d bytes).",
720 p_size * W9968CF_ISO_PACKETS)
723 memset(cam->transfer_buffer[i], 0, W9968CF_ISO_PACKETS*p_size);
726 /* Allocate memory for the temporary frame buffer */
727 if (!(cam->frame_tmp.buffer = rvmalloc(W9968CF_HW_BUF_SIZE))) {
728 DBG(1, "Couldn't allocate memory for the temporary "
729 "video frame buffer (%i bytes).", W9968CF_HW_BUF_SIZE)
733 /* Allocate memory for the helper buffer */
734 if (w9968cf_vppmod_present) {
735 if (!(cam->vpp_buffer = rvmalloc(bufsize))) {
736 DBG(1, "Couldn't allocate memory for the helper buffer"
737 " (%li bytes).", bufsize)
741 cam->vpp_buffer = NULL;
743 /* Allocate memory for video frame buffers */
744 cam->nbuffers = cam->max_buffers;
745 while (cam->nbuffers >= 2) {
746 if ((buff = rvmalloc(cam->nbuffers * bufsize)))
753 DBG(1, "Couldn't allocate memory for the video frame buffers.")
758 if (cam->nbuffers != cam->max_buffers)
759 DBG(2, "Couldn't allocate memory for %d video frame buffers. "
760 "Only memory for %d buffers has been allocated.",
761 cam->max_buffers, cam->nbuffers)
763 for (i = 0; i < cam->nbuffers; i++) {
764 cam->frame[i].buffer = buff + i*bufsize;
766 if (i != cam->nbuffers-1)
767 cam->frame[i].next = &cam->frame[i+1];
769 cam->frame[i].next = &cam->frame[0];
770 cam->frame[i].status = F_UNUSED;
773 DBG(5, "Memory successfully allocated.")
779 /****************************************************************************
780 * USB-specific functions *
781 ****************************************************************************/
783 /*--------------------------------------------------------------------------
784 This is an handler function which is called after the URBs are completed.
785 It collects multiple data packets coming from the camera by putting them
786 into frame buffers: one or more zero data length data packets are used to
787 mark the end of a video frame; the first non-zero data packet is the start
788 of the next video frame; if an error is encountered in a packet, the entire
789 video frame is discarded and grabbed again.
790 If there are no requested frames in the FIFO list, packets are collected into
792 --------------------------------------------------------------------------*/
793 static void w9968cf_urb_complete(struct urb *urb, struct pt_regs *regs)
795 struct w9968cf_device* cam = (struct w9968cf_device*)urb->context;
796 struct w9968cf_frame_t** f;
797 unsigned long maxbufsize;
798 unsigned int len, status;
803 if ((!cam->streaming) || cam->disconnected) {
804 DBG(4, "Got interrupt, but not streaming.")
808 maxbufsize = min( (unsigned long)W9968CF_HW_BUF_SIZE,
809 w9968cf_get_max_bufsize(cam) );
811 /* "(*f)" will be used instead of "cam->frame_current" */
812 f = &cam->frame_current;
814 /* If a frame has been requested and we are grabbing into
815 the temporary frame, we'll switch to that requested frame */
816 if ((*f) == &cam->frame_tmp && *cam->requested_frame) {
817 if (cam->frame_tmp.status == F_GRABBING) {
818 w9968cf_pop_frame(cam, &cam->frame_current);
819 (*f)->status = F_GRABBING;
820 (*f)->length = cam->frame_tmp.length;
821 memcpy((*f)->buffer, cam->frame_tmp.buffer,
823 DBG(6, "Switched from temp. frame to frame #%zd",
824 (*f) - &cam->frame[0])
828 for (i = 0; i < urb->number_of_packets; i++) {
829 len = urb->iso_frame_desc[i].actual_length;
830 status = urb->iso_frame_desc[i].status;
831 pos = urb->iso_frame_desc[i].offset + urb->transfer_buffer;
833 if (status && len != 0) {
834 DBG(4, "URB failed, error in data packet "
836 status, symbolic(urb_errlist, status))
837 (*f)->status = F_ERROR;
841 if (len) { /* start of frame */
843 if ((*f)->status == F_UNUSED) {
844 (*f)->status = F_GRABBING;
848 /* Buffer overflows shouldn't happen, however...*/
849 if ((*f)->length + len > maxbufsize) {
850 DBG(4, "Buffer overflow: bad data packets.")
851 (*f)->status = F_ERROR;
854 if ((*f)->status == F_GRABBING) {
855 memcpy((*f)->buffer + (*f)->length, pos, len);
859 } else if ((*f)->status == F_GRABBING) { /* end of frame */
861 DBG(6, "Frame #%zd successfully grabbed.",
862 ((*f)==&cam->frame_tmp ? -1 : (*f)-&cam->frame[0]))
864 if (cam->vpp_flag & VPP_DECOMPRESSION) {
865 err=(*w9968cf_vpp_check_headers)((*f)->buffer,
868 DBG(4, "Skip corrupted frame: %s",
869 symbolic(decoder_errlist, err))
870 (*f)->status = F_UNUSED;
871 continue; /* grab this frame again */
875 (*f)->status = F_READY;
878 /* Take a pointer to the new frame from the FIFO list.
879 If the list is empty,we'll use the temporary frame*/
880 if (*cam->requested_frame)
881 w9968cf_pop_frame(cam, &cam->frame_current);
883 cam->frame_current = &cam->frame_tmp;
884 (*f)->status = F_UNUSED;
887 } else if ((*f)->status == F_ERROR)
888 (*f)->status = F_UNUSED; /* grab it again */
890 PDBGG("Frame length %li | pack.#%d | pack.len. %d | state %d",
891 (unsigned long)(*f)->length, i, len, (*f)->status)
895 /* Resubmit this URB */
896 urb->dev = cam->usbdev;
898 spin_lock(&cam->urb_lock);
900 if ((err = usb_submit_urb(urb, GFP_ATOMIC))) {
901 cam->misconfigured = 1;
902 DBG(1, "Couldn't resubmit the URB: error %d, %s",
903 err, symbolic(urb_errlist, err));
905 spin_unlock(&cam->urb_lock);
907 /* Wake up the user process */
908 wake_up_interruptible(&cam->wait_queue);
912 /*---------------------------------------------------------------------------
913 Setup the URB structures for the isochronous transfer.
914 Submit the URBs so that the data transfer begins.
915 Return 0 on success, a negative number otherwise.
916 ---------------------------------------------------------------------------*/
917 static int w9968cf_start_transfer(struct w9968cf_device* cam)
919 struct usb_device *udev = cam->usbdev;
921 const u16 p_size = wMaxPacketSize[cam->altsetting-1];
928 for (i = 0; i < W9968CF_URBS; i++) {
929 urb = usb_alloc_urb(W9968CF_ISO_PACKETS, GFP_KERNEL);
932 for (j = 0; j < i; j++)
933 usb_free_urb(cam->urb[j]);
934 DBG(1, "Couldn't allocate the URB structures.")
939 urb->context = (void*)cam;
940 urb->pipe = usb_rcvisocpipe(udev, 1);
941 urb->transfer_flags = URB_ISO_ASAP;
942 urb->number_of_packets = W9968CF_ISO_PACKETS;
943 urb->complete = w9968cf_urb_complete;
944 urb->transfer_buffer = cam->transfer_buffer[i];
945 urb->transfer_buffer_length = p_size*W9968CF_ISO_PACKETS;
947 for (j = 0; j < W9968CF_ISO_PACKETS; j++) {
948 urb->iso_frame_desc[j].offset = p_size*j;
949 urb->iso_frame_desc[j].length = p_size;
953 /* Transfer size per frame, in WORD ! */
960 err = w9968cf_write_reg(cam, 0xbf17, 0x00); /* reset everything */
961 err += w9968cf_write_reg(cam, 0xbf10, 0x00); /* normal operation */
964 err += w9968cf_write_reg(cam, t_size & 0xffff, 0x3d); /* low bits */
965 err += w9968cf_write_reg(cam, t_size >> 16, 0x3e); /* high bits */
967 if (cam->vpp_flag & VPP_DECOMPRESSION)
968 err += w9968cf_upload_quantizationtables(cam);
970 vidcapt = w9968cf_read_reg(cam, 0x16); /* read picture settings */
971 err += w9968cf_write_reg(cam, vidcapt|0x8000, 0x16); /* capt. enable */
973 err += usb_set_interface(udev, 0, cam->altsetting);
974 err += w9968cf_write_reg(cam, 0x8a05, 0x3c); /* USB FIFO enable */
976 if (err || (vidcapt < 0)) {
977 for (i = 0; i < W9968CF_URBS; i++)
978 usb_free_urb(cam->urb[i]);
979 DBG(1, "Couldn't tell the camera to start the data transfer.")
983 w9968cf_init_framelist(cam);
985 /* Begin to grab into the temporary buffer */
986 cam->frame_tmp.status = F_UNUSED;
987 cam->frame_tmp.queued = 0;
988 cam->frame_current = &cam->frame_tmp;
990 if (!(cam->vpp_flag & VPP_DECOMPRESSION))
991 DBG(5, "Isochronous transfer size: %li bytes/frame.",
992 (unsigned long)t_size*2)
994 DBG(5, "Starting the isochronous transfer...")
996 /* Submit the URBs */
997 for (i = 0; i < W9968CF_URBS; i++) {
998 err = usb_submit_urb(cam->urb[i], GFP_KERNEL);
1000 for (j = i-1; j >= 0; j--)
1001 if (!usb_unlink_urb(cam->urb[j]))
1002 usb_free_urb(cam->urb[j]);
1003 DBG(1, "Couldn't send a transfer request to the "
1004 "USB core (error #%d, %s).", err,
1005 symbolic(urb_errlist, err))
1015 /*--------------------------------------------------------------------------
1016 Stop the isochronous transfer and set alternate setting to 0 (0Mb/s).
1017 Return 0 on success, a negative number otherwise.
1018 --------------------------------------------------------------------------*/
1019 static int w9968cf_stop_transfer(struct w9968cf_device* cam)
1021 struct usb_device *udev = cam->usbdev;
1022 unsigned long lock_flags;
1026 /* This avoids race conditions with usb_submit_urb()
1027 in the URB completition handler */
1028 spin_lock_irqsave(&cam->urb_lock, lock_flags);
1030 spin_unlock_irqrestore(&cam->urb_lock, lock_flags);
1032 for (i = W9968CF_URBS-1; i >= 0; i--)
1034 if (!usb_unlink_urb(cam->urb[i])) {
1035 usb_free_urb(cam->urb[i]);
1040 if (cam->disconnected)
1043 err = w9968cf_write_reg(cam, 0x0a05, 0x3c); /* stop USB transfer */
1044 err += usb_set_interface(udev, 0, 0); /* 0 Mb/s */
1045 err += w9968cf_write_reg(cam, 0x0000, 0x39); /* disable JPEG encoder */
1046 err += w9968cf_write_reg(cam, 0x0000, 0x16); /* stop video capture */
1049 DBG(2, "Failed to tell the camera to stop the isochronous "
1050 "transfer. However this is not a critical error.")
1055 DBG(5, "Isochronous transfer stopped.")
1060 /*--------------------------------------------------------------------------
1061 Write a W9968CF register.
1062 Return 0 on success, -1 otherwise.
1063 --------------------------------------------------------------------------*/
1064 static int w9968cf_write_reg(struct w9968cf_device* cam, u16 value, u16 index)
1066 struct usb_device* udev = cam->usbdev;
1069 res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0,
1070 USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE,
1071 value, index, NULL, 0, W9968CF_USB_CTRL_TIMEOUT);
1074 DBG(4, "Failed to write a register "
1075 "(value 0x%04X, index 0x%02X, error #%d, %s).",
1076 value, index, res, symbolic(urb_errlist, res))
1078 return (res >= 0) ? 0 : -1;
1082 /*--------------------------------------------------------------------------
1083 Read a W9968CF register.
1084 Return the register value on success, -1 otherwise.
1085 --------------------------------------------------------------------------*/
1086 static int w9968cf_read_reg(struct w9968cf_device* cam, u16 index)
1088 struct usb_device* udev = cam->usbdev;
1089 u16* buff = cam->control_buffer;
1092 res = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 1,
1093 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
1094 0, index, buff, 2, W9968CF_USB_CTRL_TIMEOUT);
1097 DBG(4, "Failed to read a register "
1098 "(index 0x%02X, error #%d, %s).",
1099 index, res, symbolic(urb_errlist, res))
1101 return (res >= 0) ? (int)(*buff) : -1;
1105 /*--------------------------------------------------------------------------
1106 Write 64-bit data to the fast serial bus registers.
1107 Return 0 on success, -1 otherwise.
1108 --------------------------------------------------------------------------*/
1109 static int w9968cf_write_fsb(struct w9968cf_device* cam, u16* data)
1111 struct usb_device* udev = cam->usbdev;
1117 res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0,
1118 USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE,
1119 value, 0x06, data, 6, W9968CF_USB_CTRL_TIMEOUT);
1122 DBG(4, "Failed to write the FSB registers "
1123 "(error #%d, %s).", res, symbolic(urb_errlist, res))
1125 return (res >= 0) ? 0 : -1;
1129 /*--------------------------------------------------------------------------
1130 Write data to the serial bus control register.
1131 Return 0 on success, a negative number otherwise.
1132 --------------------------------------------------------------------------*/
1133 static int w9968cf_write_sb(struct w9968cf_device* cam, u16 value)
1137 err = w9968cf_write_reg(cam, value, 0x01);
1138 udelay(W9968CF_I2C_BUS_DELAY);
1144 /*--------------------------------------------------------------------------
1145 Read data from the serial bus control register.
1146 Return 0 on success, a negative number otherwise.
1147 --------------------------------------------------------------------------*/
1148 static int w9968cf_read_sb(struct w9968cf_device* cam)
1152 v = w9968cf_read_reg(cam, 0x01);
1153 udelay(W9968CF_I2C_BUS_DELAY);
1159 /*--------------------------------------------------------------------------
1160 Upload quantization tables for the JPEG compression.
1161 This function is called by w9968cf_start_transfer().
1162 Return 0 on success, a negative number otherwise.
1163 --------------------------------------------------------------------------*/
1164 static int w9968cf_upload_quantizationtables(struct w9968cf_device* cam)
1169 err += w9968cf_write_reg(cam, 0x0010, 0x39); /* JPEG clock enable */
1171 for (i = 0, j = 0; i < 32; i++, j += 2) {
1172 a = Y_QUANTABLE[j] | ((unsigned)(Y_QUANTABLE[j+1]) << 8);
1173 b = UV_QUANTABLE[j] | ((unsigned)(UV_QUANTABLE[j+1]) << 8);
1174 err += w9968cf_write_reg(cam, a, 0x40+i);
1175 err += w9968cf_write_reg(cam, b, 0x60+i);
1177 err += w9968cf_write_reg(cam, 0x0012, 0x39); /* JPEG encoder enable */
1184 /****************************************************************************
1185 * Low-level I2C I/O functions. *
1186 * The adapter supports the following I2C transfer functions: *
1187 * i2c_adap_fastwrite_byte_data() (at 400 kHz bit frequency only) *
1188 * i2c_adap_read_byte_data() *
1189 * i2c_adap_read_byte() *
1190 ****************************************************************************/
1192 static int w9968cf_smbus_start(struct w9968cf_device* cam)
1196 err += w9968cf_write_sb(cam, 0x0011); /* SDE=1, SDA=0, SCL=1 */
1197 err += w9968cf_write_sb(cam, 0x0010); /* SDE=1, SDA=0, SCL=0 */
1203 static int w9968cf_smbus_stop(struct w9968cf_device* cam)
1207 err += w9968cf_write_sb(cam, 0x0011); /* SDE=1, SDA=0, SCL=1 */
1208 err += w9968cf_write_sb(cam, 0x0013); /* SDE=1, SDA=1, SCL=1 */
1214 static int w9968cf_smbus_write_byte(struct w9968cf_device* cam, u8 v)
1219 for (bit = 0 ; bit < 8 ; bit++) {
1220 sda = (v & 0x80) ? 2 : 0;
1222 /* SDE=1, SDA=sda, SCL=0 */
1223 err += w9968cf_write_sb(cam, 0x10 | sda);
1224 /* SDE=1, SDA=sda, SCL=1 */
1225 err += w9968cf_write_sb(cam, 0x11 | sda);
1226 /* SDE=1, SDA=sda, SCL=0 */
1227 err += w9968cf_write_sb(cam, 0x10 | sda);
1234 static int w9968cf_smbus_read_byte(struct w9968cf_device* cam, u8* v)
1240 for (bit = 0 ; bit < 8 ; bit++) {
1242 err += w9968cf_write_sb(cam, 0x0013);
1243 *v |= (w9968cf_read_sb(cam) & 0x0008) ? 1 : 0;
1244 err += w9968cf_write_sb(cam, 0x0012);
1251 static int w9968cf_smbus_write_ack(struct w9968cf_device* cam)
1255 err += w9968cf_write_sb(cam, 0x0010); /* SDE=1, SDA=0, SCL=0 */
1256 err += w9968cf_write_sb(cam, 0x0011); /* SDE=1, SDA=0, SCL=1 */
1257 err += w9968cf_write_sb(cam, 0x0010); /* SDE=1, SDA=0, SCL=0 */
1263 static int w9968cf_smbus_read_ack(struct w9968cf_device* cam)
1267 err += w9968cf_write_sb(cam, 0x0013); /* SDE=1, SDA=1, SCL=1 */
1268 sda = (w9968cf_read_sb(cam) & 0x08) ? 1 : 0; /* sda = SDA */
1269 err += w9968cf_write_sb(cam, 0x0012); /* SDE=1, SDA=1, SCL=0 */
1273 DBG(6, "Couldn't receive the ACK.")
1281 /* This seems to refresh the communication through the serial bus */
1282 static int w9968cf_smbus_refresh_bus(struct w9968cf_device* cam)
1286 for (j = 1; j <= 10; j++) {
1287 err = w9968cf_write_reg(cam, 0x0020, 0x01);
1288 err += w9968cf_write_reg(cam, 0x0000, 0x01);
1297 /* SMBus protocol: S Addr Wr [A] Subaddr [A] Value [A] P */
1299 w9968cf_i2c_adap_fastwrite_byte_data(struct w9968cf_device* cam,
1300 u16 address, u8 subaddress,u8 value)
1302 u16* data = cam->data_buffer;
1305 err += w9968cf_smbus_refresh_bus(cam);
1307 /* Enable SBUS outputs */
1308 err += w9968cf_write_sb(cam, 0x0020);
1310 data[0] = 0x082f | ((address & 0x80) ? 0x1500 : 0x0);
1311 data[0] |= (address & 0x40) ? 0x4000 : 0x0;
1312 data[1] = 0x2082 | ((address & 0x40) ? 0x0005 : 0x0);
1313 data[1] |= (address & 0x20) ? 0x0150 : 0x0;
1314 data[1] |= (address & 0x10) ? 0x5400 : 0x0;
1315 data[2] = 0x8208 | ((address & 0x08) ? 0x0015 : 0x0);
1316 data[2] |= (address & 0x04) ? 0x0540 : 0x0;
1317 data[2] |= (address & 0x02) ? 0x5000 : 0x0;
1318 data[3] = 0x1d20 | ((address & 0x02) ? 0x0001 : 0x0);
1319 data[3] |= (address & 0x01) ? 0x0054 : 0x0;
1321 err += w9968cf_write_fsb(cam, data);
1323 data[0] = 0x8208 | ((subaddress & 0x80) ? 0x0015 : 0x0);
1324 data[0] |= (subaddress & 0x40) ? 0x0540 : 0x0;
1325 data[0] |= (subaddress & 0x20) ? 0x5000 : 0x0;
1326 data[1] = 0x0820 | ((subaddress & 0x20) ? 0x0001 : 0x0);
1327 data[1] |= (subaddress & 0x10) ? 0x0054 : 0x0;
1328 data[1] |= (subaddress & 0x08) ? 0x1500 : 0x0;
1329 data[1] |= (subaddress & 0x04) ? 0x4000 : 0x0;
1330 data[2] = 0x2082 | ((subaddress & 0x04) ? 0x0005 : 0x0);
1331 data[2] |= (subaddress & 0x02) ? 0x0150 : 0x0;
1332 data[2] |= (subaddress & 0x01) ? 0x5400 : 0x0;
1335 err += w9968cf_write_fsb(cam, data);
1337 data[0] = 0x8208 | ((value & 0x80) ? 0x0015 : 0x0);
1338 data[0] |= (value & 0x40) ? 0x0540 : 0x0;
1339 data[0] |= (value & 0x20) ? 0x5000 : 0x0;
1340 data[1] = 0x0820 | ((value & 0x20) ? 0x0001 : 0x0);
1341 data[1] |= (value & 0x10) ? 0x0054 : 0x0;
1342 data[1] |= (value & 0x08) ? 0x1500 : 0x0;
1343 data[1] |= (value & 0x04) ? 0x4000 : 0x0;
1344 data[2] = 0x2082 | ((value & 0x04) ? 0x0005 : 0x0);
1345 data[2] |= (value & 0x02) ? 0x0150 : 0x0;
1346 data[2] |= (value & 0x01) ? 0x5400 : 0x0;
1349 err += w9968cf_write_fsb(cam, data);
1351 /* Disable SBUS outputs */
1352 err += w9968cf_write_sb(cam, 0x0000);
1355 DBG(5, "I2C write byte data done, addr.0x%04X, subaddr.0x%02X "
1356 "value 0x%02X.", address, subaddress, value)
1358 DBG(5, "I2C write byte data failed, addr.0x%04X, "
1359 "subaddr.0x%02X, value 0x%02X.",
1360 address, subaddress, value)
1366 /* SMBus protocol: S Addr Wr [A] Subaddr [A] P S Addr+1 Rd [A] [Value] NA P */
1368 w9968cf_i2c_adap_read_byte_data(struct w9968cf_device* cam,
1369 u16 address, u8 subaddress,
1374 /* Serial data enable */
1375 err += w9968cf_write_sb(cam, 0x0013); /* don't change ! */
1377 err += w9968cf_smbus_start(cam);
1378 err += w9968cf_smbus_write_byte(cam, address);
1379 err += w9968cf_smbus_read_ack(cam);
1380 err += w9968cf_smbus_write_byte(cam, subaddress);
1381 err += w9968cf_smbus_read_ack(cam);
1382 err += w9968cf_smbus_stop(cam);
1383 err += w9968cf_smbus_start(cam);
1384 err += w9968cf_smbus_write_byte(cam, address + 1);
1385 err += w9968cf_smbus_read_ack(cam);
1386 err += w9968cf_smbus_read_byte(cam, value);
1387 err += w9968cf_smbus_write_ack(cam);
1388 err += w9968cf_smbus_stop(cam);
1390 /* Serial data disable */
1391 err += w9968cf_write_sb(cam, 0x0000);
1394 DBG(5, "I2C read byte data done, addr.0x%04X, "
1395 "subaddr.0x%02X, value 0x%02X.",
1396 address, subaddress, *value)
1398 DBG(5, "I2C read byte data failed, addr.0x%04X, "
1399 "subaddr.0x%02X, wrong value 0x%02X.",
1400 address, subaddress, *value)
1406 /* SMBus protocol: S Addr+1 Rd [A] [Value] NA P */
1408 w9968cf_i2c_adap_read_byte(struct w9968cf_device* cam,
1409 u16 address, u8* value)
1413 /* Serial data enable */
1414 err += w9968cf_write_sb(cam, 0x0013);
1416 err += w9968cf_smbus_start(cam);
1417 err += w9968cf_smbus_write_byte(cam, address + 1);
1418 err += w9968cf_smbus_read_ack(cam);
1419 err += w9968cf_smbus_read_byte(cam, value);
1420 err += w9968cf_smbus_write_ack(cam);
1421 err += w9968cf_smbus_stop(cam);
1423 /* Serial data disable */
1424 err += w9968cf_write_sb(cam, 0x0000);
1427 DBG(5, "I2C read byte done, addr.0x%04X."
1428 "value 0x%02X.", address, *value)
1430 DBG(5, "I2C read byte failed, addr.0x%04X."
1431 "wrong value 0x%02X.", address, *value)
1437 /* SMBus protocol: S Addr Wr [A] Value [A] P */
1439 w9968cf_i2c_adap_write_byte(struct w9968cf_device* cam,
1440 u16 address, u8 value)
1442 DBG(4, "i2c_write_byte() is an unsupported transfer mode.")
1448 /****************************************************************************
1449 * I2C interface to kernel *
1450 ****************************************************************************/
1453 w9968cf_i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr,
1454 unsigned short flags, char read_write, u8 command,
1455 int size, union i2c_smbus_data *data)
1457 struct w9968cf_device* cam = i2c_get_adapdata(adapter);
1466 DBG(4, "Rejected slave ID 0x%04X", addr)
1470 if (size == I2C_SMBUS_BYTE) {
1471 /* Why addr <<= 1? See OVXXX0_SID defines in ovcamchip.h */
1474 if (read_write == I2C_SMBUS_WRITE)
1475 err = w9968cf_i2c_adap_write_byte(cam, addr, command);
1476 else if (read_write == I2C_SMBUS_READ)
1477 err = w9968cf_i2c_adap_read_byte(cam,addr,&data->byte);
1479 } else if (size == I2C_SMBUS_BYTE_DATA) {
1482 if (read_write == I2C_SMBUS_WRITE)
1483 err = w9968cf_i2c_adap_fastwrite_byte_data(cam, addr,
1484 command, data->byte);
1485 else if (read_write == I2C_SMBUS_READ) {
1486 for (i = 1; i <= W9968CF_I2C_RW_RETRIES; i++) {
1487 err = w9968cf_i2c_adap_read_byte_data(cam,addr,
1488 command, &data->byte);
1490 if (w9968cf_smbus_refresh_bus(cam)) {
1502 DBG(4, "Unsupported I2C transfer mode (%d)", size)
1510 static u32 w9968cf_i2c_func(struct i2c_adapter* adap)
1512 return I2C_FUNC_SMBUS_READ_BYTE |
1513 I2C_FUNC_SMBUS_READ_BYTE_DATA |
1514 I2C_FUNC_SMBUS_WRITE_BYTE_DATA;
1518 static int w9968cf_i2c_attach_inform(struct i2c_client* client)
1520 struct w9968cf_device* cam = i2c_get_adapdata(client->adapter);
1521 const char* clientname = i2c_clientname(client);
1522 int id = client->driver->id, err = 0;
1524 if (id == I2C_DRIVERID_OVCAMCHIP) {
1525 cam->sensor_client = client;
1526 err = w9968cf_sensor_init(cam);
1528 cam->sensor_client = NULL;
1532 DBG(4, "Rejected client [%s] with driver [%s]",
1533 clientname, client->driver->name)
1537 DBG(5, "I2C attach client [%s] with driver [%s]",
1538 clientname, client->driver->name)
1544 static int w9968cf_i2c_detach_inform(struct i2c_client* client)
1546 struct w9968cf_device* cam = i2c_get_adapdata(client->adapter);
1547 const char* clientname = i2c_clientname(client);
1549 if (cam->sensor_client == client) {
1550 cam->sensor_client = NULL;
1553 DBG(5, "I2C detach client [%s]", clientname)
1560 w9968cf_i2c_control(struct i2c_adapter* adapter, unsigned int cmd,
1567 static int w9968cf_i2c_init(struct w9968cf_device* cam)
1571 static struct i2c_algorithm algo = {
1572 .name = "W996[87]CF algorithm",
1573 .id = I2C_ALGO_SMBUS,
1574 .smbus_xfer = w9968cf_i2c_smbus_xfer,
1575 .algo_control = w9968cf_i2c_control,
1576 .functionality = w9968cf_i2c_func,
1579 static struct i2c_adapter adap = {
1580 .id = I2C_ALGO_SMBUS | I2C_HW_SMBUS_W9968CF,
1581 .class = I2C_CLASS_CAM_DIGITAL,
1582 .owner = THIS_MODULE,
1583 .client_register = w9968cf_i2c_attach_inform,
1584 .client_unregister = w9968cf_i2c_detach_inform,
1588 memcpy(&cam->i2c_adapter, &adap, sizeof(struct i2c_adapter));
1589 strcpy(cam->i2c_adapter.name, "w9968cf");
1590 i2c_set_adapdata(&cam->i2c_adapter, cam);
1592 DBG(6, "Registering I2C adapter with kernel...")
1594 err = i2c_add_adapter(&cam->i2c_adapter);
1596 DBG(1, "Failed to register the I2C adapter.")
1598 DBG(5, "I2C adapter registered.")
1605 /****************************************************************************
1606 * Helper functions *
1607 ****************************************************************************/
1609 /*--------------------------------------------------------------------------
1610 Turn on the LED on some webcams. A beep should be heard too.
1611 Return 0 on success, a negative number otherwise.
1612 --------------------------------------------------------------------------*/
1613 static int w9968cf_turn_on_led(struct w9968cf_device* cam)
1617 err += w9968cf_write_reg(cam, 0xff00, 0x00); /* power-down */
1618 err += w9968cf_write_reg(cam, 0xbf17, 0x00); /* reset everything */
1619 err += w9968cf_write_reg(cam, 0xbf10, 0x00); /* normal operation */
1620 err += w9968cf_write_reg(cam, 0x0010, 0x01); /* serial bus, SDS high */
1621 err += w9968cf_write_reg(cam, 0x0000, 0x01); /* serial bus, SDS low */
1622 err += w9968cf_write_reg(cam, 0x0010, 0x01); /* ..high 'beep-beep' */
1625 DBG(2, "Couldn't turn on the LED.")
1627 DBG(5, "LED turned on.")
1633 /*--------------------------------------------------------------------------
1634 Write some registers for the device initialization.
1635 This function is called once on open().
1636 Return 0 on success, a negative number otherwise.
1637 --------------------------------------------------------------------------*/
1638 static int w9968cf_init_chip(struct w9968cf_device* cam)
1642 err += w9968cf_write_reg(cam, 0xff00, 0x00); /* power off */
1643 err += w9968cf_write_reg(cam, 0xbf10, 0x00); /* power on */
1645 err += w9968cf_write_reg(cam, 0x405d, 0x03); /* DRAM timings */
1646 err += w9968cf_write_reg(cam, 0x0030, 0x04); /* SDRAM timings */
1648 err += w9968cf_write_reg(cam, 0x0000, 0x20); /* Y frame buf.0, low */
1649 err += w9968cf_write_reg(cam, 0x0000, 0x21); /* Y frame buf.0, high */
1650 err += w9968cf_write_reg(cam, 0xb000, 0x22); /* Y frame buf.1, low */
1651 err += w9968cf_write_reg(cam, 0x0004, 0x23); /* Y frame buf.1, high */
1652 err += w9968cf_write_reg(cam, 0x5800, 0x24); /* U frame buf.0, low */
1653 err += w9968cf_write_reg(cam, 0x0002, 0x25); /* U frame buf.0, high */
1654 err += w9968cf_write_reg(cam, 0x0800, 0x26); /* U frame buf.1, low */
1655 err += w9968cf_write_reg(cam, 0x0007, 0x27); /* U frame buf.1, high */
1656 err += w9968cf_write_reg(cam, 0x8400, 0x28); /* V frame buf.0, low */
1657 err += w9968cf_write_reg(cam, 0x0003, 0x29); /* V frame buf.0, high */
1658 err += w9968cf_write_reg(cam, 0x3400, 0x2a); /* V frame buf.1, low */
1659 err += w9968cf_write_reg(cam, 0x0008, 0x2b); /* V frame buf.1, high */
1661 err += w9968cf_write_reg(cam, 0x6000, 0x32); /* JPEG bitstream buf 0 */
1662 err += w9968cf_write_reg(cam, 0x0009, 0x33); /* JPEG bitstream buf 0 */
1663 err += w9968cf_write_reg(cam, 0x2000, 0x34); /* JPEG bitstream buf 1 */
1664 err += w9968cf_write_reg(cam, 0x000d, 0x35); /* JPEG bitstream buf 1 */
1666 err += w9968cf_write_reg(cam, 0x0000, 0x36);/* JPEG restart interval */
1667 err += w9968cf_write_reg(cam, 0x0804, 0x37);/*JPEG VLE FIFO threshold*/
1668 err += w9968cf_write_reg(cam, 0x0000, 0x38);/* disable hw up-scaling */
1669 err += w9968cf_write_reg(cam, 0x0000, 0x3f); /* JPEG/MCTL test data */
1671 err += w9968cf_set_picture(cam, cam->picture); /* this before */
1672 err += w9968cf_set_window(cam, cam->window);
1675 DBG(1, "Chip initialization failed.")
1677 DBG(5, "Chip successfully initialized.")
1683 /*--------------------------------------------------------------------------
1684 Change the picture settings of the camera.
1685 Return 0 on success, a negative number otherwise.
1686 --------------------------------------------------------------------------*/
1688 w9968cf_set_picture(struct w9968cf_device* cam, struct video_picture pict)
1690 u16 fmt, hw_depth, hw_palette, reg_v = 0x0000;
1693 /* Make sure we are using a valid depth */
1694 pict.depth = w9968cf_valid_depth(pict.palette);
1698 hw_depth = pict.depth; /* depth used by the winbond chip */
1699 hw_palette = pict.palette; /* palette used by the winbond chip */
1701 /* VS & HS polarities */
1702 reg_v = (cam->vs_polarity << 12) | (cam->hs_polarity << 11);
1706 case VIDEO_PALETTE_UYVY:
1708 cam->vpp_flag = VPP_NONE;
1710 case VIDEO_PALETTE_YUV422P:
1712 cam->vpp_flag = VPP_DECOMPRESSION;
1714 case VIDEO_PALETTE_YUV420:
1715 case VIDEO_PALETTE_YUV420P:
1717 cam->vpp_flag = VPP_DECOMPRESSION;
1719 case VIDEO_PALETTE_YUYV:
1720 case VIDEO_PALETTE_YUV422:
1722 cam->vpp_flag = VPP_SWAP_YUV_BYTES;
1723 hw_palette = VIDEO_PALETTE_UYVY;
1725 /* Original video is used instead of RGBX palettes.
1726 Software conversion later. */
1727 case VIDEO_PALETTE_GREY:
1728 case VIDEO_PALETTE_RGB555:
1729 case VIDEO_PALETTE_RGB565:
1730 case VIDEO_PALETTE_RGB24:
1731 case VIDEO_PALETTE_RGB32:
1732 reg_v |= 0x0000; /* UYVY 16 bit is used */
1734 hw_palette = VIDEO_PALETTE_UYVY;
1735 cam->vpp_flag = VPP_UYVY_TO_RGBX;
1739 /* FIXME: 'hardware double buffer' doesn't work when compressed video
1740 is enabled (corrupted frames). */
1741 if (cam->double_buffer && !(cam->vpp_flag & VPP_DECOMPRESSION))
1747 if (cam->filter_type == 1)
1749 else if (cam->filter_type == 2)
1752 if ((err = w9968cf_write_reg(cam, reg_v, 0x16)))
1755 if ((err = w9968cf_sensor_update_picture(cam, pict)))
1758 /* If all went well, update the device data structure */
1759 memcpy(&cam->picture, &pict, sizeof(pict));
1760 cam->hw_depth = hw_depth;
1761 cam->hw_palette = hw_palette;
1763 /* Settings changed, so we clear the frame buffers */
1764 memset(cam->frame[0].buffer, 0,
1765 cam->nbuffers*w9968cf_get_max_bufsize(cam));
1767 DBG(4, "Palette is %s, depth is %d bpp.",
1768 symbolic(v4l1_plist, pict.palette), pict.depth)
1773 DBG(1, "Failed to change picture settings.")
1778 /*--------------------------------------------------------------------------
1779 Change the capture area size of the camera.
1780 This function _must_ be called _after_ w9968cf_set_picture().
1781 Return 0 on success, a negative number otherwise.
1782 --------------------------------------------------------------------------*/
1784 w9968cf_set_window(struct w9968cf_device* cam, struct video_window win)
1786 u16 x, y, w, h, scx, scy, cw, ch, ax, ay;
1787 unsigned long fw, fh;
1788 struct ovcamchip_window s_win;
1791 /* Work around to avoid FP arithmetics */
1792 #define __SC(x) ((x) << 10)
1793 #define __UNSC(x) ((x) >> 10)
1795 /* Make sure we are using a supported resolution */
1796 if ((err = w9968cf_adjust_window_size(cam, (u16*)&win.width,
1797 (u16*)&win.height)))
1800 /* Scaling factors */
1801 fw = __SC(win.width) / cam->maxwidth;
1802 fh = __SC(win.height) / cam->maxheight;
1804 /* Set up the width and height values used by the chip */
1805 if ((win.width > cam->maxwidth) || (win.height > cam->maxheight)) {
1806 cam->vpp_flag |= VPP_UPSCALE;
1807 /* Calculate largest w,h mantaining the same w/h ratio */
1808 w = (fw >= fh) ? cam->maxwidth : __SC(win.width)/fh;
1809 h = (fw >= fh) ? __SC(win.height)/fw : cam->maxheight;
1810 if (w < cam->minwidth) /* just in case */
1812 if (h < cam->minheight) /* just in case */
1815 cam->vpp_flag &= ~VPP_UPSCALE;
1820 /* x,y offsets of the cropped area */
1821 scx = cam->start_cropx;
1822 scy = cam->start_cropy;
1824 /* Calculate cropped area manteining the right w/h ratio */
1825 if (cam->largeview && !(cam->vpp_flag & VPP_UPSCALE)) {
1826 cw = (fw >= fh) ? cam->maxwidth : __SC(win.width)/fh;
1827 ch = (fw >= fh) ? __SC(win.height)/fw : cam->maxheight;
1833 /* Setup the window of the sensor */
1834 s_win.format = VIDEO_PALETTE_UYVY;
1835 s_win.width = cam->maxwidth;
1836 s_win.height = cam->maxheight;
1837 s_win.quarter = 0; /* full progressive video */
1840 s_win.x = (s_win.width - cw) / 2;
1841 s_win.y = (s_win.height - ch) / 2;
1844 if (cam->clockdiv >= 0)
1845 s_win.clockdiv = cam->clockdiv; /* manual override */
1847 switch (cam->sensor) {
1860 s_win.clockdiv = W9968CF_DEF_CLOCKDIVISOR;
1863 /* We have to scale win.x and win.y offsets */
1864 if ( (cam->largeview && !(cam->vpp_flag & VPP_UPSCALE))
1865 || (cam->vpp_flag & VPP_UPSCALE) ) {
1866 ax = __SC(win.x)/fw;
1867 ay = __SC(win.y)/fh;
1873 if ((ax + cw) > cam->maxwidth)
1874 ax = cam->maxwidth - cw;
1876 if ((ay + ch) > cam->maxheight)
1877 ay = cam->maxheight - ch;
1879 /* Adjust win.x, win.y */
1880 if ( (cam->largeview && !(cam->vpp_flag & VPP_UPSCALE))
1881 || (cam->vpp_flag & VPP_UPSCALE) ) {
1882 win.x = __UNSC(ax*fw);
1883 win.y = __UNSC(ay*fh);
1889 /* Offsets used by the chip */
1894 if ((err = w9968cf_sensor_cmd(cam, OVCAMCHIP_CMD_S_MODE, &s_win)))
1897 err += w9968cf_write_reg(cam, scx + x, 0x10);
1898 err += w9968cf_write_reg(cam, scy + y, 0x11);
1899 err += w9968cf_write_reg(cam, scx + x + cw, 0x12);
1900 err += w9968cf_write_reg(cam, scy + y + ch, 0x13);
1901 err += w9968cf_write_reg(cam, w, 0x14);
1902 err += w9968cf_write_reg(cam, h, 0x15);
1904 /* JPEG width & height */
1905 err += w9968cf_write_reg(cam, w, 0x30);
1906 err += w9968cf_write_reg(cam, h, 0x31);
1908 /* Y & UV frame buffer strides (in WORD) */
1909 if (cam->vpp_flag & VPP_DECOMPRESSION) {
1910 err += w9968cf_write_reg(cam, w/2, 0x2c);
1911 err += w9968cf_write_reg(cam, w/4, 0x2d);
1913 err += w9968cf_write_reg(cam, w, 0x2c);
1918 /* If all went well, update the device data structure */
1919 memcpy(&cam->window, &win, sizeof(win));
1923 /* Settings changed, so we clear the frame buffers */
1924 memset(cam->frame[0].buffer, 0,
1925 cam->nbuffers*w9968cf_get_max_bufsize(cam));
1927 DBG(4, "The capture area is %dx%d, Offset (x,y)=(%d,%d).",
1928 win.width, win.height, win.x, win.y)
1930 PDBGG("x=%d ,y=%d, w=%d, h=%d, ax=%d, ay=%d, s_win.x=%d, s_win.y=%d, "
1931 "cw=%d, ch=%d, win.x=%d ,win.y=%d, win.width=%d, win.height=%d",
1932 x, y, w, h, ax, ay, s_win.x, s_win.y, cw, ch, win.x, win.y,
1933 win.width, win.height)
1938 DBG(1, "Failed to change the capture area size.")
1943 /*--------------------------------------------------------------------------
1944 Return non-zero if the palette is supported, 0 otherwise.
1945 --------------------------------------------------------------------------*/
1946 static inline u16 w9968cf_valid_palette(u16 palette)
1949 while (w9968cf_formatlist[i].palette != 0) {
1950 if (palette == w9968cf_formatlist[i].palette)
1958 /*--------------------------------------------------------------------------
1959 Return the depth corresponding to the given palette.
1960 Palette _must_ be supported !
1961 --------------------------------------------------------------------------*/
1962 static u16 w9968cf_valid_depth(u16 palette)
1965 while (w9968cf_formatlist[i].palette != palette)
1968 return w9968cf_formatlist[i].depth;
1972 /*--------------------------------------------------------------------------
1973 Return non-zero if the format requires decompression, 0 otherwise.
1974 --------------------------------------------------------------------------*/
1975 static inline u8 w9968cf_need_decompression(u16 palette)
1978 while (w9968cf_formatlist[i].palette != 0) {
1979 if (palette == w9968cf_formatlist[i].palette)
1980 return w9968cf_formatlist[i].compression;
1987 /*--------------------------------------------------------------------------
1988 Adjust the asked values for window width and height.
1989 Return 0 on success, -1 otherwise.
1990 --------------------------------------------------------------------------*/
1992 w9968cf_adjust_window_size(struct w9968cf_device* cam, u16* width, u16* height)
1996 if ((*width < cam->minwidth) || (*height < cam->minheight))
1999 maxw = cam->upscaling && !(cam->vpp_flag & VPP_DECOMPRESSION)
2000 && w9968cf_vppmod_present ? W9968CF_MAX_WIDTH : cam->maxwidth;
2001 maxh = cam->upscaling && !(cam->vpp_flag & VPP_DECOMPRESSION)
2002 && w9968cf_vppmod_present ? W9968CF_MAX_HEIGHT : cam->maxheight;
2009 if (cam->vpp_flag & VPP_DECOMPRESSION) {
2010 *width &= ~15L; /* multiple of 16 */
2014 PDBGG("Window size adjusted w=%d, h=%d ", *width, *height)
2020 /*--------------------------------------------------------------------------
2021 Initialize the FIFO list of requested frames.
2022 --------------------------------------------------------------------------*/
2023 static void w9968cf_init_framelist(struct w9968cf_device* cam)
2027 for (i = 0; i < cam->nbuffers; i++) {
2028 cam->requested_frame[i] = NULL;
2029 cam->frame[i].queued = 0;
2030 cam->frame[i].status = F_UNUSED;
2035 /*--------------------------------------------------------------------------
2036 Add a frame in the FIFO list of requested frames.
2037 This function is called in process context.
2038 --------------------------------------------------------------------------*/
2039 static void w9968cf_push_frame(struct w9968cf_device* cam, u8 f_num)
2042 unsigned long lock_flags;
2044 spin_lock_irqsave(&cam->flist_lock, lock_flags);
2046 for (f=0; cam->requested_frame[f] != NULL; f++);
2047 cam->requested_frame[f] = &cam->frame[f_num];
2048 cam->frame[f_num].queued = 1;
2049 cam->frame[f_num].status = F_UNUSED; /* clear the status */
2051 spin_unlock_irqrestore(&cam->flist_lock, lock_flags);
2053 DBG(6, "Frame #%d pushed into the FIFO list. Position %d.", f_num, f)
2057 /*--------------------------------------------------------------------------
2058 Read, store and remove the first pointer in the FIFO list of requested
2059 frames. This function is called in interrupt context.
2060 --------------------------------------------------------------------------*/
2062 w9968cf_pop_frame(struct w9968cf_device* cam, struct w9968cf_frame_t** framep)
2066 spin_lock(&cam->flist_lock);
2068 *framep = cam->requested_frame[0];
2070 /* Shift the list of pointers */
2071 for (i = 0; i < cam->nbuffers-1; i++)
2072 cam->requested_frame[i] = cam->requested_frame[i+1];
2073 cam->requested_frame[i] = NULL;
2075 spin_unlock(&cam->flist_lock);
2077 DBG(6,"Popped frame #%zd from the list.",*framep-&cam->frame[0])
2081 /*--------------------------------------------------------------------------
2082 High-level video post-processing routine on grabbed frames.
2083 Return 0 on success, a negative number otherwise.
2084 --------------------------------------------------------------------------*/
2086 w9968cf_postprocess_frame(struct w9968cf_device* cam,
2087 struct w9968cf_frame_t* fr)
2089 void *pIn = fr->buffer, *pOut = cam->vpp_buffer, *tmp;
2090 u16 w = cam->window.width,
2091 h = cam->window.height,
2092 d = cam->picture.depth,
2093 fmt = cam->picture.palette,
2094 rgb = cam->force_rgb,
2095 hw_w = cam->hw_width,
2096 hw_h = cam->hw_height,
2097 hw_d = cam->hw_depth;
2100 #define _PSWAP(pIn, pOut) {tmp = (pIn); (pIn) = (pOut); (pOut) = tmp;}
2102 if (cam->vpp_flag & VPP_DECOMPRESSION) {
2103 memcpy(pOut, pIn, fr->length);
2105 err = (*w9968cf_vpp_decode)(pIn, fr->length, hw_w, hw_h, pOut);
2106 PDBGG("Compressed frame length: %li",(unsigned long)fr->length)
2107 fr->length = (hw_w*hw_h*hw_d)/8;
2110 DBG(4, "An error occurred while decoding the frame: "
2111 "%s.", symbolic(decoder_errlist, err))
2114 DBG(6, "Frame decoded")
2117 if (cam->vpp_flag & VPP_SWAP_YUV_BYTES) {
2118 (*w9968cf_vpp_swap_yuvbytes)(pIn, fr->length);
2119 DBG(6, "Original UYVY component ordering changed.")
2122 if (cam->vpp_flag & VPP_UPSCALE) {
2123 (*w9968cf_vpp_scale_up)(pIn, pOut, hw_w, hw_h, hw_d, w, h);
2124 fr->length = (w*h*hw_d)/8;
2126 DBG(6, "Vertical up-scaling done: %d,%d,%dbpp->%d,%d",
2127 hw_w, hw_h, hw_d, w, h)
2130 if (cam->vpp_flag & VPP_UYVY_TO_RGBX) {
2131 (*w9968cf_vpp_uyvy_to_rgbx)(pIn, fr->length, pOut, fmt, rgb);
2132 fr->length = (w*h*d)/8;
2134 DBG(6, "UYVY-16bit to %s conversion done.",
2135 symbolic(v4l1_plist, fmt))
2138 if (pOut == fr->buffer)
2139 memcpy(fr->buffer, cam->vpp_buffer, fr->length);
2146 /****************************************************************************
2147 * CMOS sensor control routines *
2148 ****************************************************************************/
2151 w9968cf_sensor_set_control(struct w9968cf_device* cam, int cid, int val)
2153 struct ovcamchip_control ctl;
2159 err = w9968cf_sensor_cmd(cam, OVCAMCHIP_CMD_S_CTRL, &ctl);
2166 w9968cf_sensor_get_control(struct w9968cf_device* cam, int cid, int* val)
2168 struct ovcamchip_control ctl;
2173 err = w9968cf_sensor_cmd(cam, OVCAMCHIP_CMD_G_CTRL, &ctl);
2182 w9968cf_sensor_cmd(struct w9968cf_device* cam, unsigned int cmd, void* arg)
2184 struct i2c_client* c = cam->sensor_client;
2187 if (c->driver->command) {
2188 rc = c->driver->command(cam->sensor_client, cmd, arg);
2189 /* The I2C driver returns -EPERM on non-supported controls */
2190 return (rc < 0 && rc != -EPERM) ? rc : 0;
2196 /*--------------------------------------------------------------------------
2197 Update some settings of the CMOS sensor.
2198 Returns: 0 on success, a negative number otherwise.
2199 --------------------------------------------------------------------------*/
2200 static int w9968cf_sensor_update_settings(struct w9968cf_device* cam)
2204 /* Auto brightness */
2205 err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_AUTOBRIGHT,
2211 err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_AUTOEXP,
2216 /* Banding filter */
2217 err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_BANDFILT,
2222 /* Light frequency */
2223 err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_FREQ,
2229 err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_BACKLIGHT,
2235 err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_MIRROR,
2244 /*--------------------------------------------------------------------------
2245 Get some current picture settings from the CMOS sensor and update the
2246 internal 'picture' structure of the camera.
2247 Returns: 0 on success, a negative number otherwise.
2248 --------------------------------------------------------------------------*/
2249 static int w9968cf_sensor_get_picture(struct w9968cf_device* cam)
2253 err = w9968cf_sensor_get_control(cam, OVCAMCHIP_CID_CONT, &v);
2256 cam->picture.contrast = v;
2258 err = w9968cf_sensor_get_control(cam, OVCAMCHIP_CID_BRIGHT, &v);
2261 cam->picture.brightness = v;
2263 err = w9968cf_sensor_get_control(cam, OVCAMCHIP_CID_SAT, &v);
2266 cam->picture.colour = v;
2268 err = w9968cf_sensor_get_control(cam, OVCAMCHIP_CID_HUE, &v);
2271 cam->picture.hue = v;
2273 DBG(5, "Got picture settings from the CMOS sensor.")
2275 PDBGG("Brightness, contrast, hue, colour, whiteness are "
2276 "%d,%d,%d,%d,%d.", cam->picture.brightness,cam->picture.contrast,
2277 cam->picture.hue, cam->picture.colour, cam->picture.whiteness)
2283 /*--------------------------------------------------------------------------
2284 Update picture settings of the CMOS sensor.
2285 Returns: 0 on success, a negative number otherwise.
2286 --------------------------------------------------------------------------*/
2288 w9968cf_sensor_update_picture(struct w9968cf_device* cam,
2289 struct video_picture pict)
2293 if ((!cam->sensor_initialized)
2294 || pict.contrast != cam->picture.contrast) {
2295 err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_CONT,
2299 DBG(4, "Contrast changed from %d to %d.",
2300 cam->picture.contrast, pict.contrast)
2301 cam->picture.contrast = pict.contrast;
2304 if (((!cam->sensor_initialized) ||
2305 pict.brightness != cam->picture.brightness) && (!cam->auto_brt)) {
2306 err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_BRIGHT,
2310 DBG(4, "Brightness changed from %d to %d.",
2311 cam->picture.brightness, pict.brightness)
2312 cam->picture.brightness = pict.brightness;
2315 if ((!cam->sensor_initialized) || pict.colour != cam->picture.colour) {
2316 err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_SAT,
2320 DBG(4, "Colour changed from %d to %d.",
2321 cam->picture.colour, pict.colour)
2322 cam->picture.colour = pict.colour;
2325 if ((!cam->sensor_initialized) || pict.hue != cam->picture.hue) {
2326 err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_HUE,
2330 DBG(4, "Hue changed from %d to %d.",
2331 cam->picture.hue, pict.hue)
2332 cam->picture.hue = pict.hue;
2338 DBG(4, "Failed to change sensor picture setting.")
2344 /****************************************************************************
2345 * Camera configuration *
2346 ****************************************************************************/
2348 /*--------------------------------------------------------------------------
2349 This function is called when a supported CMOS sensor is detected.
2350 Return 0 if the initialization succeeds, a negative number otherwise.
2351 --------------------------------------------------------------------------*/
2352 static int w9968cf_sensor_init(struct w9968cf_device* cam)
2356 if ((err = w9968cf_sensor_cmd(cam, OVCAMCHIP_CMD_INITIALIZE,
2360 if ((err = w9968cf_sensor_cmd(cam, OVCAMCHIP_CMD_Q_SUBTYPE,
2364 /* NOTE: Make sure width and height are a multiple of 16 */
2365 switch (cam->sensor_client->addr) {
2367 cam->maxwidth = 352;
2368 cam->maxheight = 288;
2370 cam->minheight = 48;
2373 cam->maxwidth = 640;
2374 cam->maxheight = 480;
2376 cam->minheight = 48;
2379 DBG(1, "Not supported CMOS sensor detected for %s.",
2380 symbolic(camlist, cam->id))
2384 /* These values depend on the ones in the ovxxx0.c sources */
2385 switch (cam->sensor) {
2387 cam->start_cropx = 287;
2388 cam->start_cropy = 35;
2389 /* Seems to work around a bug in the CMOS sensor */
2390 cam->vs_polarity = 1;
2391 cam->hs_polarity = 1;
2394 cam->start_cropx = 320;
2395 cam->start_cropy = 35;
2396 cam->vs_polarity = 1;
2397 cam->hs_polarity = 0;
2400 if ((err = w9968cf_sensor_update_settings(cam)))
2403 if ((err = w9968cf_sensor_update_picture(cam, cam->picture)))
2406 cam->sensor_initialized = 1;
2408 DBG(2, "%s CMOS sensor initialized.", symbolic(senlist, cam->sensor))
2412 cam->sensor_initialized = 0;
2413 cam->sensor = CC_UNKNOWN;
2414 DBG(1, "CMOS sensor initialization failed for %s (/dev/video%d). "
2415 "Try to detach and attach this device again.",
2416 symbolic(camlist, cam->id), cam->v4ldev->minor)
2421 /*--------------------------------------------------------------------------
2422 Fill some basic fields in the main device data structure.
2423 This function is called once on w9968cf_usb_probe() for each recognized
2425 --------------------------------------------------------------------------*/
2427 w9968cf_configure_camera(struct w9968cf_device* cam,
2428 struct usb_device* udev,
2429 enum w9968cf_model_id mod_id,
2430 const unsigned short dev_nr)
2432 init_MUTEX(&cam->fileop_sem);
2433 init_waitqueue_head(&cam->open);
2434 spin_lock_init(&cam->urb_lock);
2435 spin_lock_init(&cam->flist_lock);
2438 cam->disconnected = 0;
2441 cam->sensor = CC_UNKNOWN;
2442 cam->sensor_initialized = 0;
2444 /* Calculate the alternate setting number (from 1 to 16)
2445 according to the 'packet_size' module parameter */
2446 if (packet_size[dev_nr] < W9968CF_MIN_PACKET_SIZE)
2447 packet_size[dev_nr] = W9968CF_MIN_PACKET_SIZE;
2448 for (cam->altsetting = 1;
2449 packet_size[dev_nr] < wMaxPacketSize[cam->altsetting-1];
2452 cam->max_buffers = (max_buffers[dev_nr] < 2 ||
2453 max_buffers[dev_nr] > W9968CF_MAX_BUFFERS)
2454 ? W9968CF_BUFFERS : (u8)max_buffers[dev_nr];
2456 cam->double_buffer = (double_buffer[dev_nr] == 0 ||
2457 double_buffer[dev_nr] == 1)
2458 ? (u8)double_buffer[dev_nr]:W9968CF_DOUBLE_BUFFER;
2460 cam->clamping = (clamping[dev_nr] == 0 || clamping[dev_nr] == 1)
2461 ? (u8)clamping[dev_nr] : W9968CF_CLAMPING;
2463 cam->filter_type = (filter_type[dev_nr] == 0 ||
2464 filter_type[dev_nr] == 1 ||
2465 filter_type[dev_nr] == 2)
2466 ? (u8)filter_type[dev_nr] : W9968CF_FILTER_TYPE;
2470 cam->largeview = (largeview[dev_nr] == 0 || largeview[dev_nr] == 1)
2471 ? (u8)largeview[dev_nr] : W9968CF_LARGEVIEW;
2473 cam->decompression = (decompression[dev_nr] == 0 ||
2474 decompression[dev_nr] == 1 ||
2475 decompression[dev_nr] == 2)
2476 ? (u8)decompression[dev_nr]:W9968CF_DECOMPRESSION;
2478 cam->upscaling = (upscaling[dev_nr] == 0 ||
2479 upscaling[dev_nr] == 1)
2480 ? (u8)upscaling[dev_nr] : W9968CF_UPSCALING;
2482 cam->auto_brt = (autobright[dev_nr] == 0 || autobright[dev_nr] == 1)
2483 ? (u8)autobright[dev_nr] : W9968CF_AUTOBRIGHT;
2485 cam->auto_exp = (autoexp[dev_nr] == 0 || autoexp[dev_nr] == 1)
2486 ? (u8)autoexp[dev_nr] : W9968CF_AUTOEXP;
2488 cam->lightfreq = (lightfreq[dev_nr] == 50 || lightfreq[dev_nr] == 60)
2489 ? (u8)lightfreq[dev_nr] : W9968CF_LIGHTFREQ;
2491 cam->bandfilt = (bandingfilter[dev_nr] == 0 ||
2492 bandingfilter[dev_nr] == 1)
2493 ? (u8)bandingfilter[dev_nr] : W9968CF_BANDINGFILTER;
2495 cam->backlight = (backlight[dev_nr] == 0 || backlight[dev_nr] == 1)
2496 ? (u8)backlight[dev_nr] : W9968CF_BACKLIGHT;
2498 cam->clockdiv = (clockdiv[dev_nr] == -1 || clockdiv[dev_nr] >= 0)
2499 ? (s8)clockdiv[dev_nr] : W9968CF_CLOCKDIV;
2501 cam->mirror = (mirror[dev_nr] == 0 || mirror[dev_nr] == 1)
2502 ? (u8)mirror[dev_nr] : W9968CF_MIRROR;
2504 cam->monochrome = (monochrome[dev_nr] == 0 || monochrome[dev_nr] == 1)
2505 ? monochrome[dev_nr] : W9968CF_MONOCHROME;
2507 cam->picture.brightness = (u16)brightness[dev_nr];
2508 cam->picture.hue = (u16)hue[dev_nr];
2509 cam->picture.colour = (u16)colour[dev_nr];
2510 cam->picture.contrast = (u16)contrast[dev_nr];
2511 cam->picture.whiteness = (u16)whiteness[dev_nr];
2512 if (w9968cf_valid_palette((u16)force_palette[dev_nr])) {
2513 cam->picture.palette = (u16)force_palette[dev_nr];
2514 cam->force_palette = 1;
2516 cam->force_palette = 0;
2517 if (cam->decompression == 0)
2518 cam->picture.palette = W9968CF_PALETTE_DECOMP_OFF;
2519 else if (cam->decompression == 1)
2520 cam->picture.palette = W9968CF_PALETTE_DECOMP_FORCE;
2522 cam->picture.palette = W9968CF_PALETTE_DECOMP_ON;
2525 cam->force_rgb = (force_rgb[dev_nr] == 0 || force_rgb[dev_nr] == 1)
2526 ? (u8)force_rgb[dev_nr] : W9968CF_FORCE_RGB;
2530 cam->window.width = W9968CF_WIDTH;
2531 cam->window.height = W9968CF_HEIGHT;
2532 cam->window.chromakey = 0;
2533 cam->window.clipcount = 0;
2534 cam->window.flags = 0;
2536 /* If the video post-processing module is not present, some paramaters
2537 must be overridden: */
2538 if (!w9968cf_vppmod_present) {
2539 if (cam->decompression == 1)
2540 cam->decompression = 2;
2542 if (cam->picture.palette != VIDEO_PALETTE_UYVY)
2543 cam->force_palette = 0;
2544 cam->picture.palette = VIDEO_PALETTE_UYVY;
2547 cam->picture.depth = w9968cf_valid_depth(cam->picture.palette);
2549 DBG(3, "%s configured with settings #%d:",
2550 symbolic(camlist, cam->id), dev_nr)
2552 DBG(3, "- Data packet size for USB isochrnous transfer: %d bytes.",
2553 wMaxPacketSize[cam->altsetting-1])
2555 DBG(3, "- Number of requested video frame buffers: %d",
2558 if (cam->double_buffer)
2559 DBG(3, "- Hardware double buffering enabled.")
2561 DBG(3, "- Hardware double buffering disabled.")
2563 if (cam->filter_type == 0)
2564 DBG(3, "- Video filtering disabled.")
2565 else if (cam->filter_type == 1)
2566 DBG(3, "- Video filtering enabled: type 1-2-1.")
2567 else if (cam->filter_type == 2)
2568 DBG(3, "- Video filtering enabled: type 2-3-6-3-2.")
2571 DBG(3, "- Video data clamping (CCIR-601 format) enabled.")
2573 DBG(3, "- Video data clamping (CCIR-601 format) disabled.")
2576 DBG(3, "- Large view enabled.")
2578 DBG(3, "- Large view disabled.")
2580 if ((cam->decompression) == 0 && (!cam->force_palette))
2581 DBG(3, "- Decompression disabled.")
2582 else if ((cam->decompression) == 1 && (!cam->force_palette))
2583 DBG(3, "- Decompression forced.")
2584 else if ((cam->decompression) == 2 && (!cam->force_palette))
2585 DBG(3, "- Decompression allowed.")
2588 DBG(3, "- Software image scaling enabled.")
2590 DBG(3, "- Software image scaling disabled.")
2592 if (cam->force_palette)
2593 DBG(3, "- Image palette forced to %s.",
2594 symbolic(v4l1_plist, cam->picture.palette))
2597 DBG(3, "- RGB component ordering will be used instead of BGR.")
2600 DBG(3, "- Auto brightness enabled.")
2602 DBG(3, "- Auto brightness disabled.")
2605 DBG(3, "- Auto exposure enabled.")
2607 DBG(3, "- Auto exposure disabled.")
2610 DBG(3, "- Backlight exposure algorithm enabled.")
2612 DBG(3, "- Backlight exposure algorithm disabled.")
2615 DBG(3, "- Mirror enabled.")
2617 DBG(3, "- Mirror disabled.")
2620 DBG(3, "- Banding filter enabled.")
2622 DBG(3, "- Banding filter disabled.")
2624 DBG(3, "- Power lighting frequency: %d", cam->lightfreq)
2626 if (cam->clockdiv == -1)
2627 DBG(3, "- Automatic clock divisor enabled.")
2629 DBG(3, "- Clock divisor: %d", cam->clockdiv)
2631 if (cam->monochrome)
2632 DBG(3, "- CMOS sensor used as monochrome.")
2634 DBG(3, "- CMOS sensor not used as monochrome.")
2638 /*--------------------------------------------------------------------------
2639 Release the resources used by the driver.
2640 This function is called on disconnect
2641 (or on close if deallocation has been deferred)
2642 --------------------------------------------------------------------------*/
2643 static void w9968cf_release_resources(struct w9968cf_device* cam)
2645 down(&w9968cf_devlist_sem);
2647 DBG(2, "V4L device deregistered: /dev/video%d", cam->v4ldev->minor)
2649 video_unregister_device(cam->v4ldev);
2650 list_del(&cam->v4llist);
2651 i2c_del_adapter(&cam->i2c_adapter);
2652 w9968cf_deallocate_memory(cam);
2653 kfree(cam->control_buffer);
2654 kfree(cam->data_buffer);
2656 up(&w9968cf_devlist_sem);
2658 DBG(5, "Resources released.")
2663 /****************************************************************************
2664 * Video4Linux interface *
2665 ****************************************************************************/
2667 static int w9968cf_open(struct inode* inode, struct file* filp)
2669 struct w9968cf_device* cam;
2672 cam = (struct w9968cf_device*)video_get_drvdata(video_devdata(filp));
2674 down(&cam->dev_sem);
2676 if (cam->sensor == CC_UNKNOWN) {
2677 DBG(2, "No supported CMOS sensor has been detected by the "
2678 "'ovcamchip' module for the %s (/dev/video%d). Make "
2679 "sure it is loaded *before* the 'w9968cf' module.",
2680 symbolic(camlist, cam->id), cam->v4ldev->minor)
2686 DBG(2, "%s (/dev/video%d) has been already occupied by '%s'.",
2687 symbolic(camlist, cam->id),cam->v4ldev->minor,cam->command)
2688 if ((filp->f_flags & O_NONBLOCK)||(filp->f_flags & O_NDELAY)) {
2690 return -EWOULDBLOCK;
2694 err = wait_event_interruptible(cam->open, cam->disconnected ||
2698 if (cam->disconnected)
2700 down(&cam->dev_sem);
2701 /*recheck - there may be several waiters */
2706 DBG(5, "Opening '%s', /dev/video%d ...",
2707 symbolic(camlist, cam->id), cam->v4ldev->minor)
2710 cam->misconfigured = 0;
2712 if (!w9968cf_vppmod_present)
2713 w9968cf_vppmod_detect();
2715 if ((err = w9968cf_allocate_memory(cam)))
2716 goto deallocate_memory;
2718 if ((err = w9968cf_init_chip(cam)))
2719 goto deallocate_memory;
2721 if ((err = w9968cf_start_transfer(cam)))
2722 goto deallocate_memory;
2724 filp->private_data = cam;
2727 strcpy(cam->command, current->comm);
2729 init_waitqueue_head(&cam->wait_queue);
2733 DBG(5, "Video device is open.")
2737 w9968cf_deallocate_memory(cam);
2738 DBG(2, "Failed to open the video device.")
2744 static int w9968cf_release(struct inode* inode, struct file* filp)
2746 struct w9968cf_device* cam;
2748 cam = (struct w9968cf_device*)video_get_drvdata(video_devdata(filp));
2750 down(&cam->dev_sem); /* prevent disconnect() to be called */
2752 w9968cf_stop_transfer(cam);
2754 if (cam->disconnected) {
2755 w9968cf_release_resources(cam);
2762 w9968cf_deallocate_memory(cam);
2764 wake_up_interruptible(&cam->open);
2766 DBG(5, "Video device closed.")
2773 w9968cf_read(struct file* filp, char __user * buf, size_t count, loff_t* f_pos)
2775 struct w9968cf_device* cam;
2776 struct w9968cf_frame_t* fr;
2779 cam = (struct w9968cf_device*)video_get_drvdata(video_devdata(filp));
2781 if (filp->f_flags & O_NONBLOCK)
2782 return -EWOULDBLOCK;
2784 if (down_interruptible(&cam->fileop_sem))
2785 return -ERESTARTSYS;
2787 if (cam->disconnected) {
2788 DBG(2, "Device not present.")
2789 up(&cam->fileop_sem);
2793 if (cam->misconfigured) {
2794 DBG(2, "The camera is misconfigured. Close and open it again.")
2795 up(&cam->fileop_sem);
2799 if (!cam->frame[0].queued)
2800 w9968cf_push_frame(cam, 0);
2802 if (!cam->frame[1].queued)
2803 w9968cf_push_frame(cam, 1);
2805 err = wait_event_interruptible(cam->wait_queue,
2806 cam->frame[0].status == F_READY ||
2807 cam->frame[1].status == F_READY ||
2810 up(&cam->fileop_sem);
2813 if (cam->disconnected) {
2814 up(&cam->fileop_sem);
2818 fr = (cam->frame[0].status == F_READY) ? &cam->frame[0]:&cam->frame[1];
2820 if (w9968cf_vppmod_present)
2821 w9968cf_postprocess_frame(cam, fr);
2823 if (count > fr->length)
2826 if (copy_to_user(buf, fr->buffer, count)) {
2827 fr->status = F_UNUSED;
2828 up(&cam->fileop_sem);
2833 fr->status = F_UNUSED;
2835 DBG(5, "%zd bytes read.", count)
2837 up(&cam->fileop_sem);
2842 static int w9968cf_mmap(struct file* filp, struct vm_area_struct *vma)
2844 struct w9968cf_device* cam = (struct w9968cf_device*)
2845 video_get_drvdata(video_devdata(filp));
2846 unsigned long vsize = vma->vm_end - vma->vm_start,
2847 psize = cam->nbuffers * w9968cf_get_max_bufsize(cam),
2848 start = vma->vm_start,
2849 pos = (unsigned long)cam->frame[0].buffer,
2852 if (cam->disconnected) {
2853 DBG(2, "Device not present.")
2857 if (cam->misconfigured) {
2858 DBG(2, "The camera is misconfigured. Close and open it again.")
2862 PDBGG("mmapping %li bytes...", vsize)
2864 if (vsize > psize - (vma->vm_pgoff << PAGE_SHIFT))
2868 page = kvirt_to_pa(pos) + vma->vm_pgoff;
2869 if (remap_page_range(vma, start, page, PAGE_SIZE,
2874 vsize = (vsize > PAGE_SIZE) ? vsize-PAGE_SIZE : 0;
2877 DBG(5, "mmap method successfully called.")
2883 w9968cf_ioctl(struct inode* inode, struct file* filp,
2884 unsigned int cmd, unsigned long arg)
2886 struct w9968cf_device* cam;
2889 cam = (struct w9968cf_device*)video_get_drvdata(video_devdata(filp));
2891 if (down_interruptible(&cam->fileop_sem))
2892 return -ERESTARTSYS;
2894 if (cam->disconnected) {
2895 DBG(2, "Device not present.")
2896 up(&cam->fileop_sem);
2900 if (cam->misconfigured) {
2901 DBG(2, "The camera is misconfigured. Close and open it again.")
2902 up(&cam->fileop_sem);
2906 err = w9968cf_v4l_ioctl(inode, filp, cmd, (void* )arg);
2908 up(&cam->fileop_sem);
2914 w9968cf_v4l_ioctl(struct inode* inode, struct file* filp,
2915 unsigned int cmd, void* arg)
2917 struct w9968cf_device* cam;
2918 void __user *user_arg = (void __user *)arg;
2919 const char* v4l1_ioctls[] = {
2920 "?", "CGAP", "GCHAN", "SCHAN", "GTUNER", "STUNER",
2921 "GPICT", "SPICT", "CCAPTURE", "GWIN", "SWIN", "GFBUF",
2922 "SFBUF", "KEY", "GFREQ", "SFREQ", "GAUDIO", "SAUDIO",
2923 "SYNC", "MCAPTURE", "GMBUF", "GUNIT", "GCAPTURE", "SCAPTURE",
2924 "SPLAYMODE", "SWRITEMODE", "GPLAYINFO", "SMICROCODE",
2925 "GVBIFMT", "SVBIFMT"
2928 #define V4L1_IOCTL(cmd) \
2929 ((_IOC_NR((cmd)) < sizeof(v4l1_ioctls)/sizeof(char*)) ? \
2930 v4l1_ioctls[_IOC_NR((cmd))] : "?")
2932 cam = (struct w9968cf_device*)video_get_drvdata(video_devdata(filp));
2936 case VIDIOCGCAP: /* get video capability */
2938 struct video_capability cap = {
2939 .type = VID_TYPE_CAPTURE | VID_TYPE_SCALES,
2942 .minwidth = cam->minwidth,
2943 .minheight = cam->minheight,
2945 sprintf(cap.name, "W996[87]CF USB Camera #%d",
2946 cam->v4ldev->minor);
2947 cap.maxwidth = (cam->upscaling && w9968cf_vppmod_present)
2948 ? W9968CF_MAX_WIDTH : cam->maxwidth;
2949 cap.maxheight = (cam->upscaling && w9968cf_vppmod_present)
2950 ? W9968CF_MAX_HEIGHT : cam->maxheight;
2952 if (copy_to_user(user_arg, &cap, sizeof(cap)))
2955 DBG(5, "VIDIOCGCAP successfully called.")
2959 case VIDIOCGCHAN: /* get video channel informations */
2961 struct video_channel chan;
2962 if (copy_from_user(&chan, user_arg, sizeof(chan)))
2965 if (chan.channel != 0)
2968 strcpy(chan.name, "Camera");
2971 chan.type = VIDEO_TYPE_CAMERA;
2972 chan.norm = VIDEO_MODE_AUTO;
2974 if (copy_to_user(user_arg, &chan, sizeof(chan)))
2977 DBG(5, "VIDIOCGCHAN successfully called.")
2981 case VIDIOCSCHAN: /* set active channel */
2983 struct video_channel chan;
2985 if (copy_from_user(&chan, user_arg, sizeof(chan)))
2988 if (chan.channel != 0)
2991 DBG(5, "VIDIOCSCHAN successfully called.")
2995 case VIDIOCGPICT: /* get image properties of the picture */
2997 if (w9968cf_sensor_get_picture(cam))
3000 if (copy_to_user(user_arg, &cam->picture, sizeof(cam->picture)))
3003 DBG(5, "VIDIOCGPICT successfully called.")
3007 case VIDIOCSPICT: /* change picture settings */
3009 struct video_picture pict;
3012 if (copy_from_user(&pict, user_arg, sizeof(pict)))
3015 if ( (cam->force_palette || !w9968cf_vppmod_present)
3016 && pict.palette != cam->picture.palette ) {
3017 DBG(4, "Palette %s rejected. Only %s is allowed.",
3018 symbolic(v4l1_plist, pict.palette),
3019 symbolic(v4l1_plist, cam->picture.palette))
3023 if (!w9968cf_valid_palette(pict.palette)) {
3024 DBG(4, "Palette %s not supported. VIDIOCSPICT failed.",
3025 symbolic(v4l1_plist, pict.palette))
3029 if (!cam->force_palette) {
3030 if (cam->decompression == 0) {
3031 if (w9968cf_need_decompression(pict.palette)) {
3032 DBG(4, "Decompression disabled: palette %s is not "
3033 "allowed. VIDIOCSPICT failed.",
3034 symbolic(v4l1_plist, pict.palette))
3037 } else if (cam->decompression == 1) {
3038 if (!w9968cf_need_decompression(pict.palette)) {
3039 DBG(4, "Decompression forced: palette %s is not "
3040 "allowed. VIDIOCSPICT failed.",
3041 symbolic(v4l1_plist, pict.palette))
3047 if (pict.depth != w9968cf_valid_depth(pict.palette)) {
3048 DBG(4, "Requested depth %d bpp is not valid for %s "
3049 "palette: ignored and changed to %d bpp.",
3050 pict.depth, symbolic(v4l1_plist, pict.palette),
3051 w9968cf_valid_depth(pict.palette))
3052 pict.depth = w9968cf_valid_depth(pict.palette);
3055 if (pict.palette != cam->picture.palette) {
3056 if(*cam->requested_frame
3057 || cam->frame_current->queued) {
3058 err = wait_event_interruptible
3060 cam->disconnected ||
3061 (!*cam->requested_frame &&
3062 !cam->frame_current->queued) );
3065 if (cam->disconnected)
3069 if (w9968cf_stop_transfer(cam))
3072 if (w9968cf_set_picture(cam, pict))
3075 if (w9968cf_start_transfer(cam))
3078 } else if (w9968cf_sensor_update_picture(cam, pict))
3082 DBG(5, "VIDIOCSPICT successfully called.")
3086 case VIDIOCSWIN: /* set capture area */
3088 struct video_window win;
3091 if (copy_from_user(&win, user_arg, sizeof(win)))
3094 DBG(6, "VIDIOCSWIN called: clipcount=%d, flags=%d, "
3095 "x=%d, y=%d, %dx%d", win.clipcount, win.flags,
3096 win.x, win.y, win.width, win.height)
3098 if (win.clipcount != 0 || win.flags != 0)
3101 if ((err = w9968cf_adjust_window_size(cam, (u16*)&win.width,
3102 (u16*)&win.height))) {
3103 DBG(4, "Resolution not supported (%dx%d)."
3104 "VIDIOCSWIN failed.", win.width, win.height)
3108 if (win.x != cam->window.x ||
3109 win.y != cam->window.y ||
3110 win.width != cam->window.width ||
3111 win.height != cam->window.height) {
3112 if(*cam->requested_frame
3113 || cam->frame_current->queued) {
3114 err = wait_event_interruptible
3116 cam->disconnected ||
3117 (!*cam->requested_frame &&
3118 !cam->frame_current->queued) );
3121 if (cam->disconnected)
3125 if (w9968cf_stop_transfer(cam))
3128 /* This _must_ be called before set_window() */
3129 if (w9968cf_set_picture(cam, cam->picture))
3132 if (w9968cf_set_window(cam, win))
3135 if (w9968cf_start_transfer(cam))
3139 DBG(5, "VIDIOCSWIN successfully called. ")
3143 case VIDIOCGWIN: /* get current window properties */
3145 if (copy_to_user(user_arg, &cam->window, sizeof(struct video_window)))
3148 DBG(5, "VIDIOCGWIN successfully called.")
3152 case VIDIOCGMBUF: /* request for memory (mapped) buffer */
3154 struct video_mbuf mbuf;
3157 mbuf.size = cam->nbuffers * w9968cf_get_max_bufsize(cam);
3158 mbuf.frames = cam->nbuffers;
3159 for (i = 0; i < cam->nbuffers; i++)
3160 mbuf.offsets[i] = (unsigned long)cam->frame[i].buffer -
3161 (unsigned long)cam->frame[0].buffer;
3163 if (copy_to_user(user_arg, &mbuf, sizeof(mbuf)))
3166 DBG(5, "VIDIOCGMBUF successfully called.")
3170 case VIDIOCMCAPTURE: /* start the capture to a frame */
3172 struct video_mmap mmap;
3173 struct w9968cf_frame_t* fr;
3176 if (copy_from_user(&mmap, user_arg, sizeof(mmap)))
3179 DBG(6, "VIDIOCMCAPTURE called: frame #%d, format=%s, %dx%d",
3180 mmap.frame, symbolic(v4l1_plist, mmap.format),
3181 mmap.width, mmap.height)
3183 if (mmap.frame >= cam->nbuffers) {
3184 DBG(4, "Invalid frame number (%d). "
3185 "VIDIOCMCAPTURE failed.", mmap.frame)
3189 if (mmap.format!=cam->picture.palette &&
3190 (cam->force_palette || !w9968cf_vppmod_present)) {
3191 DBG(4, "Palette %s rejected. Only %s is allowed.",
3192 symbolic(v4l1_plist, mmap.format),
3193 symbolic(v4l1_plist, cam->picture.palette))
3197 if (!w9968cf_valid_palette(mmap.format)) {
3198 DBG(4, "Palette %s not supported. "
3199 "VIDIOCMCAPTURE failed.",
3200 symbolic(v4l1_plist, mmap.format))
3204 if (!cam->force_palette) {
3205 if (cam->decompression == 0) {
3206 if (w9968cf_need_decompression(mmap.format)) {
3207 DBG(4, "Decompression disabled: palette %s is not "
3208 "allowed. VIDIOCSPICT failed.",
3209 symbolic(v4l1_plist, mmap.format))
3212 } else if (cam->decompression == 1) {
3213 if (!w9968cf_need_decompression(mmap.format)) {
3214 DBG(4, "Decompression forced: palette %s is not "
3215 "allowed. VIDIOCSPICT failed.",
3216 symbolic(v4l1_plist, mmap.format))
3222 if ((err = w9968cf_adjust_window_size(cam, (u16*)&mmap.width,
3223 (u16*)&mmap.height))) {
3224 DBG(4, "Resolution not supported (%dx%d). "
3225 "VIDIOCMCAPTURE failed.",
3226 mmap.width, mmap.height)
3230 fr = &cam->frame[mmap.frame];
3232 if (mmap.width != cam->window.width ||
3233 mmap.height != cam->window.height ||
3234 mmap.format != cam->picture.palette) {
3236 struct video_window win;
3237 struct video_picture pict;
3239 if(*cam->requested_frame
3240 || cam->frame_current->queued) {
3241 DBG(6, "VIDIOCMCAPTURE. Change settings for "
3242 "frame #%d: %dx%d, format %s. Wait...",
3243 mmap.frame, mmap.width, mmap.height,
3244 symbolic(v4l1_plist, mmap.format))
3245 err = wait_event_interruptible
3247 cam->disconnected ||
3248 (!*cam->requested_frame &&
3249 !cam->frame_current->queued) );
3252 if (cam->disconnected)
3256 memcpy(&win, &cam->window, sizeof(win));
3257 memcpy(&pict, &cam->picture, sizeof(pict));
3258 win.width = mmap.width;
3259 win.height = mmap.height;
3260 pict.palette = mmap.format;
3262 if (w9968cf_stop_transfer(cam))
3265 /* This before set_window */
3266 if (w9968cf_set_picture(cam, pict))
3269 if (w9968cf_set_window(cam, win))
3272 if (w9968cf_start_transfer(cam))
3275 } else if (fr->queued) {
3277 DBG(6, "Wait until frame #%d is free.", mmap.frame)
3279 err = wait_event_interruptible(cam->wait_queue,
3280 cam->disconnected ||
3284 if (cam->disconnected)
3288 w9968cf_push_frame(cam, mmap.frame);
3289 DBG(5, "VIDIOCMCAPTURE(%d): successfully called.", mmap.frame)
3293 case VIDIOCSYNC: /* wait until the capture of a frame is finished */
3296 struct w9968cf_frame_t* fr;
3299 if (copy_from_user(&f_num, user_arg, sizeof(f_num)))
3302 if (f_num >= cam->nbuffers) {
3303 DBG(4, "Invalid frame number (%d). "
3304 "VIDIOCMCAPTURE failed.", f_num)
3308 DBG(6, "VIDIOCSYNC called for frame #%d", f_num)
3310 fr = &cam->frame[f_num];
3312 switch (fr->status) {
3315 DBG(4, "VIDIOSYNC: Frame #%d not requested!",
3321 err = wait_event_interruptible(cam->wait_queue,
3322 (fr->status == F_READY)
3323 || cam->disconnected);
3326 if (cam->disconnected)
3333 if (w9968cf_vppmod_present)
3334 w9968cf_postprocess_frame(cam, fr);
3336 fr->status = F_UNUSED;
3338 DBG(5, "VIDIOCSYNC(%d) successfully called.", f_num)
3342 case VIDIOCGUNIT:/* report the unit numbers of the associated devices*/
3344 struct video_unit unit = {
3345 .video = cam->v4ldev->minor,
3346 .vbi = VIDEO_NO_UNIT,
3347 .radio = VIDEO_NO_UNIT,
3348 .audio = VIDEO_NO_UNIT,
3349 .teletext = VIDEO_NO_UNIT,
3352 if (copy_to_user(user_arg, &unit, sizeof(unit)))
3355 DBG(5, "VIDIOCGUNIT successfully called.")
3364 if (clear_user(user_arg, sizeof(struct video_buffer)))
3367 DBG(5, "VIDIOCGFBUF successfully called.")
3373 struct video_tuner tuner;
3374 if (copy_from_user(&tuner, user_arg, sizeof(tuner)))
3377 if (tuner.tuner != 0)
3380 strcpy(tuner.name, "no_tuner");
3382 tuner.rangehigh = 0;
3383 tuner.flags = VIDEO_TUNER_NORM;
3384 tuner.mode = VIDEO_MODE_AUTO;
3385 tuner.signal = 0xffff;
3387 if (copy_to_user(user_arg, &tuner, sizeof(tuner)))
3390 DBG(5, "VIDIOCGTUNER successfully called.")
3396 struct video_tuner tuner;
3397 if (copy_from_user(&tuner, user_arg, sizeof(tuner)))
3400 if (tuner.tuner != 0)
3403 if (tuner.mode != VIDEO_MODE_AUTO)
3406 DBG(5, "VIDIOCSTUNER successfully called.")
3416 case VIDIOCSPLAYMODE:
3417 case VIDIOCSWRITEMODE:
3418 case VIDIOCGPLAYINFO:
3419 case VIDIOCSMICROCODE:
3422 DBG(4, "Unsupported V4L1 IOCtl: VIDIOC%s "
3428 _IOC_TYPE(cmd),_IOC_NR(cmd),_IOC_DIR(cmd),_IOC_SIZE(cmd))
3433 DBG(4, "Invalid V4L1 IOCtl: VIDIOC%s "
3439 _IOC_TYPE(cmd),_IOC_NR(cmd),_IOC_DIR(cmd),_IOC_SIZE(cmd))
3441 return -ENOIOCTLCMD;
3443 } /* end of switch */
3446 cam->misconfigured = 1;
3447 DBG(1, "VIDIOC%s failed because of hardware problems. "
3448 "To use the camera, close and open it again.", V4L1_IOCTL(cmd))
3453 static struct file_operations w9968cf_fops = {
3454 .owner = THIS_MODULE,
3455 .open = w9968cf_open,
3456 .release = w9968cf_release,
3457 .read = w9968cf_read,
3458 .ioctl = w9968cf_ioctl,
3459 .mmap = w9968cf_mmap,
3460 .llseek = no_llseek,
3465 /****************************************************************************
3466 * USB probe and V4L registration, disconnect and id_table[] definition *
3467 ****************************************************************************/
3470 w9968cf_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
3472 struct usb_device *udev = interface_to_usbdev(intf);
3473 struct w9968cf_device* cam;
3475 enum w9968cf_model_id mod_id;
3476 struct list_head* ptr;
3477 u8 sc = 0; /* number of simultaneous cameras */
3478 static unsigned short dev_nr = 0; /* we are handling device number n */
3480 if (udev->descriptor.idVendor == winbond_id_table[0].idVendor &&
3481 udev->descriptor.idProduct == winbond_id_table[0].idProduct)
3482 mod_id = W9968CF_MOD_CLVBWGP; /* see camlist[] table */
3484 else if (udev->descriptor.idVendor == winbond_id_table[1].idVendor &&
3485 udev->descriptor.idProduct == winbond_id_table[1].idProduct)
3486 mod_id = W9968CF_MOD_GENERIC; /* see camlist[] table */
3491 DBG(2, "%s detected.", symbolic(camlist, mod_id))
3493 if (simcams > W9968CF_MAX_DEVICES)
3494 simcams = W9968CF_SIMCAMS;
3496 /* How many cameras are connected ? */
3497 down(&w9968cf_devlist_sem);
3498 list_for_each(ptr, &w9968cf_dev_list)
3500 up(&w9968cf_devlist_sem);
3502 if (sc >= simcams) {
3503 DBG(2, "Device rejected: too many connected cameras "
3504 "(max. %d)", simcams)
3508 cam = (struct w9968cf_device*)
3509 kmalloc(sizeof(struct w9968cf_device), GFP_KERNEL);
3512 DBG(1, "Couldn't allocate %zd bytes of kernel memory.",
3513 sizeof(struct w9968cf_device))
3517 memset(cam, 0, sizeof(*cam));
3519 init_MUTEX(&cam->dev_sem);
3520 down(&cam->dev_sem);
3522 /* Allocate 2 bytes of memory for camera control USB transfers */
3523 if (!(cam->control_buffer = (u16*)kmalloc(2, GFP_KERNEL))) {
3524 DBG(1,"Couldn't allocate memory for camera control transfers.")
3528 memset(cam->control_buffer, 0, 2);
3530 /* Allocate 8 bytes of memory for USB data transfers to the FSB */
3531 if (!(cam->data_buffer = (u16*)kmalloc(8, GFP_KERNEL))) {
3532 DBG(1, "Couldn't allocate memory for data "
3533 "transfers to the FSB.")
3537 memset(cam->data_buffer, 0, 8);
3539 /* Register the V4L device */
3540 cam->v4ldev = video_device_alloc();
3542 DBG(1, "Could not allocate memory for a V4L structure.")
3547 strcpy(cam->v4ldev->name, symbolic(camlist, mod_id));
3548 cam->v4ldev->owner = THIS_MODULE;
3549 cam->v4ldev->type = VID_TYPE_CAPTURE | VID_TYPE_SCALES;
3550 cam->v4ldev->hardware = VID_HARDWARE_W9968CF;
3551 cam->v4ldev->fops = &w9968cf_fops;
3552 cam->v4ldev->minor = video_nr[dev_nr];
3553 cam->v4ldev->release = video_device_release;
3554 video_set_drvdata(cam->v4ldev, cam);
3556 err = video_register_device(cam->v4ldev, VFL_TYPE_GRABBER,
3559 DBG(1, "V4L device registration failed.")
3560 if (err == -ENFILE && video_nr[dev_nr] == -1)
3561 DBG(2, "Couldn't find a free /dev/videoX node.")
3562 video_nr[dev_nr] = -1;
3563 dev_nr = (dev_nr < W9968CF_MAX_DEVICES-1) ? dev_nr+1 : 0;
3567 DBG(2, "V4L device registered as /dev/video%d.", cam->v4ldev->minor)
3569 /* Set some basic constants */
3570 w9968cf_configure_camera(cam, udev, mod_id, dev_nr);
3572 /* Add a new entry into the list of V4L registered devices */
3573 down(&w9968cf_devlist_sem);
3574 list_add(&cam->v4llist, &w9968cf_dev_list);
3575 up(&w9968cf_devlist_sem);
3576 dev_nr = (dev_nr < W9968CF_MAX_DEVICES-1) ? dev_nr+1 : 0;
3578 w9968cf_turn_on_led(cam);
3580 w9968cf_i2c_init(cam);
3584 usb_set_intfdata(intf, cam);
3587 fail: /* Free unused memory */
3589 if (cam->control_buffer)
3590 kfree(cam->control_buffer);
3591 if (cam->data_buffer)
3592 kfree(cam->data_buffer);
3594 video_device_release(cam->v4ldev);
3602 static void w9968cf_usb_disconnect(struct usb_interface* intf)
3604 struct w9968cf_device* cam =
3605 (struct w9968cf_device*)usb_get_intfdata(intf);
3608 /* Prevent concurrent accesses to data */
3609 down(&cam->dev_sem);
3612 cam->disconnected = 1;
3614 DBG(2, "Disconnecting %s...", symbolic(camlist, cam->id))
3616 if (waitqueue_active(&cam->open))
3617 wake_up_interruptible(&cam->open);
3620 DBG(2, "The device is open (/dev/video%d)! "
3621 "Process name: %s. Deregistration and memory "
3622 "deallocation are deferred on close.",
3623 cam->v4ldev->minor, cam->command)
3625 cam->misconfigured = 1;
3627 if (waitqueue_active(&cam->wait_queue))
3628 wake_up_interruptible(&cam->wait_queue);
3630 w9968cf_release_resources(cam);
3638 usb_set_intfdata(intf, NULL);
3642 static struct usb_driver w9968cf_usb_driver = {
3643 .owner = THIS_MODULE,
3645 .id_table = winbond_id_table,
3646 .probe = w9968cf_usb_probe,
3647 .disconnect = w9968cf_usb_disconnect,
3652 /****************************************************************************
3653 * Module init, exit and intermodule communication *
3654 ****************************************************************************/
3656 static int w9968cf_vppmod_detect(void)
3658 w9968cf_vpp_init_decoder = inter_module_get("w9968cf_init_decoder");
3660 if (!w9968cf_vpp_init_decoder) {
3662 w9968cf_vpp_init_decoder = inter_module_get_request
3663 ( "w9968cf_init_decoder",
3665 if (!w9968cf_vpp_init_decoder) {
3666 w9968cf_vppmod_present = 0;
3667 DBG(4, "Video post-processing module not detected.")
3672 w9968cf_vpp_check_headers = inter_module_get("w9968cf_check_headers");
3673 w9968cf_vpp_decode = inter_module_get("w9968cf_decode");
3674 w9968cf_vpp_swap_yuvbytes = inter_module_get("w9968cf_swap_yuvbytes");
3675 w9968cf_vpp_uyvy_to_rgbx = inter_module_get("w9968cf_uyvy_to_rgbx");
3676 w9968cf_vpp_scale_up = inter_module_get("w9968cf_scale_up");
3678 w9968cf_vppmod_present = 1;
3680 /* Initialization */
3681 (*w9968cf_vpp_init_decoder)();
3683 DBG(2, "Video post-processing module detected.")
3688 static void w9968cf_vppmod_release(void)
3690 inter_module_put("w9968cf_init_decoder");
3691 inter_module_put("w9968cf_check_headers");
3692 inter_module_put("w9968cf_decode");
3693 inter_module_put("w9968cf_swap_yuvbytes");
3694 inter_module_put("w9968cf_uyvy_to_rgbx");
3695 inter_module_put("w9968cf_scale_up");
3697 DBG(2, "Video post-processing module released.")
3701 static int __init w9968cf_module_init(void)
3705 DBG(2, W9968CF_MODULE_NAME" "W9968CF_MODULE_VERSION)
3706 DBG(3, W9968CF_MODULE_AUTHOR)
3708 init_MUTEX(&w9968cf_devlist_sem);
3710 w9968cf_vppmod_detect();
3712 if ((err = usb_register(&w9968cf_usb_driver))) {
3713 if (w9968cf_vppmod_present)
3714 w9968cf_vppmod_release();
3722 static void __exit w9968cf_module_exit(void)
3724 /* w9968cf_usb_disconnect() will be called */
3725 usb_deregister(&w9968cf_usb_driver);
3727 if (w9968cf_vppmod_present)
3728 w9968cf_vppmod_release();
3730 DBG(2, W9968CF_MODULE_NAME" deregistered.")
3734 module_init(w9968cf_module_init);
3735 module_exit(w9968cf_module_exit);