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*, 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 inline 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 inline 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 inline 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* 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 static const char* v4l1_ioctls[] = {
2919 "?", "CGAP", "GCHAN", "SCHAN", "GTUNER", "STUNER",
2920 "GPICT", "SPICT", "CCAPTURE", "GWIN", "SWIN", "GFBUF",
2921 "SFBUF", "KEY", "GFREQ", "SFREQ", "GAUDIO", "SAUDIO",
2922 "SYNC", "MCAPTURE", "GMBUF", "GUNIT", "GCAPTURE", "SCAPTURE",
2923 "SPLAYMODE", "SWRITEMODE", "GPLAYINFO", "SMICROCODE",
2924 "GVBIFMT", "SVBIFMT"
2926 struct video_tuner tuner;
2927 struct video_channel chan;
2929 #define V4L1_IOCTL(cmd) \
2930 ((_IOC_NR((cmd)) < sizeof(v4l1_ioctls)/sizeof(char*)) ? \
2931 v4l1_ioctls[_IOC_NR((cmd))] : "?")
2933 cam = (struct w9968cf_device*)video_get_drvdata(video_devdata(filp));
2937 case VIDIOCGCAP: /* get video capability */
2939 struct video_capability cap = {
2940 .type = VID_TYPE_CAPTURE | VID_TYPE_SCALES,
2943 .minwidth = cam->minwidth,
2944 .minheight = cam->minheight,
2946 sprintf(cap.name, "W996[87]CF USB Camera #%d",
2947 cam->v4ldev->minor);
2948 cap.maxwidth = (cam->upscaling && w9968cf_vppmod_present)
2949 ? W9968CF_MAX_WIDTH : cam->maxwidth;
2950 cap.maxheight = (cam->upscaling && w9968cf_vppmod_present)
2951 ? W9968CF_MAX_HEIGHT : cam->maxheight;
2953 if (copy_to_user(arg, &cap, sizeof(cap)))
2956 DBG(5, "VIDIOCGCAP successfully called.")
2960 case VIDIOCGCHAN: /* get video channel informations */
2962 if (copy_from_user(&chan, 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(arg, &chan, sizeof(chan)))
2977 DBG(5, "VIDIOCGCHAN successfully called.")
2981 case VIDIOCSCHAN: /* set active channel */
2983 if (copy_from_user(&chan, arg, sizeof(chan)))
2986 if (chan.channel != 0)
2989 DBG(5, "VIDIOCSCHAN successfully called.")
2993 case VIDIOCGPICT: /* get image properties of the picture */
2995 if (w9968cf_sensor_get_picture(cam))
2998 if (copy_to_user(arg, &cam->picture, sizeof(cam->picture)))
3001 DBG(5, "VIDIOCGPICT successfully called.")
3005 case VIDIOCSPICT: /* change picture settings */
3007 struct video_picture pict;
3010 if (copy_from_user(&pict, arg, sizeof(pict)))
3013 if ( (cam->force_palette || !w9968cf_vppmod_present)
3014 && pict.palette != cam->picture.palette ) {
3015 DBG(4, "Palette %s rejected. Only %s is allowed.",
3016 symbolic(v4l1_plist, pict.palette),
3017 symbolic(v4l1_plist, cam->picture.palette))
3021 if (!w9968cf_valid_palette(pict.palette)) {
3022 DBG(4, "Palette %s not supported. VIDIOCSPICT failed.",
3023 symbolic(v4l1_plist, pict.palette))
3027 if (!cam->force_palette) {
3028 if (cam->decompression == 0) {
3029 if (w9968cf_need_decompression(pict.palette)) {
3030 DBG(4, "Decompression disabled: palette %s is not "
3031 "allowed. VIDIOCSPICT failed.",
3032 symbolic(v4l1_plist, pict.palette))
3035 } else if (cam->decompression == 1) {
3036 if (!w9968cf_need_decompression(pict.palette)) {
3037 DBG(4, "Decompression forced: palette %s is not "
3038 "allowed. VIDIOCSPICT failed.",
3039 symbolic(v4l1_plist, pict.palette))
3045 if (pict.depth != w9968cf_valid_depth(pict.palette)) {
3046 DBG(4, "Requested depth %d bpp is not valid for %s "
3047 "palette: ignored and changed to %d bpp.",
3048 pict.depth, symbolic(v4l1_plist, pict.palette),
3049 w9968cf_valid_depth(pict.palette))
3050 pict.depth = w9968cf_valid_depth(pict.palette);
3053 if (pict.palette != cam->picture.palette) {
3054 if(*cam->requested_frame
3055 || cam->frame_current->queued) {
3056 err = wait_event_interruptible
3058 cam->disconnected ||
3059 (!*cam->requested_frame &&
3060 !cam->frame_current->queued) );
3063 if (cam->disconnected)
3067 if (w9968cf_stop_transfer(cam))
3070 if (w9968cf_set_picture(cam, pict))
3073 if (w9968cf_start_transfer(cam))
3076 } else if (w9968cf_sensor_update_picture(cam, pict))
3080 DBG(5, "VIDIOCSPICT successfully called.")
3084 case VIDIOCSWIN: /* set capture area */
3086 struct video_window win;
3089 if (copy_from_user(&win, arg, sizeof(win)))
3092 DBG(6, "VIDIOCSWIN called: clipcount=%d, flags=%d, "
3093 "x=%d, y=%d, %dx%d", win.clipcount, win.flags,
3094 win.x, win.y, win.width, win.height)
3096 if (win.clipcount != 0 || win.flags != 0)
3099 if ((err = w9968cf_adjust_window_size(cam, (u16*)&win.width,
3100 (u16*)&win.height))) {
3101 DBG(4, "Resolution not supported (%dx%d)."
3102 "VIDIOCSWIN failed.", win.width, win.height)
3106 if (win.x != cam->window.x ||
3107 win.y != cam->window.y ||
3108 win.width != cam->window.width ||
3109 win.height != cam->window.height) {
3110 if(*cam->requested_frame
3111 || cam->frame_current->queued) {
3112 err = wait_event_interruptible
3114 cam->disconnected ||
3115 (!*cam->requested_frame &&
3116 !cam->frame_current->queued) );
3119 if (cam->disconnected)
3123 if (w9968cf_stop_transfer(cam))
3126 /* This _must_ be called before set_window() */
3127 if (w9968cf_set_picture(cam, cam->picture))
3130 if (w9968cf_set_window(cam, win))
3133 if (w9968cf_start_transfer(cam))
3137 DBG(5, "VIDIOCSWIN successfully called. ")
3141 case VIDIOCGWIN: /* get current window properties */
3143 if (copy_to_user(arg,&cam->window,sizeof(struct video_window)))
3146 DBG(5, "VIDIOCGWIN successfully called.")
3150 case VIDIOCGMBUF: /* request for memory (mapped) buffer */
3152 struct video_mbuf mbuf;
3155 mbuf.size = cam->nbuffers * w9968cf_get_max_bufsize(cam);
3156 mbuf.frames = cam->nbuffers;
3157 for (i = 0; i < cam->nbuffers; i++)
3158 mbuf.offsets[i] = (unsigned long)cam->frame[i].buffer -
3159 (unsigned long)cam->frame[0].buffer;
3161 if (copy_to_user(arg, &mbuf, sizeof(mbuf)))
3164 DBG(5, "VIDIOCGMBUF successfully called.")
3168 case VIDIOCMCAPTURE: /* start the capture to a frame */
3170 struct video_mmap mmap;
3171 struct w9968cf_frame_t* fr;
3174 if (copy_from_user(&mmap, arg, sizeof(mmap)))
3177 DBG(6, "VIDIOCMCAPTURE called: frame #%d, format=%s, %dx%d",
3178 mmap.frame, symbolic(v4l1_plist, mmap.format),
3179 mmap.width, mmap.height)
3181 if (mmap.frame >= cam->nbuffers) {
3182 DBG(4, "Invalid frame number (%d). "
3183 "VIDIOCMCAPTURE failed.", mmap.frame)
3187 if (mmap.format!=cam->picture.palette &&
3188 (cam->force_palette || !w9968cf_vppmod_present)) {
3189 DBG(4, "Palette %s rejected. Only %s is allowed.",
3190 symbolic(v4l1_plist, mmap.format),
3191 symbolic(v4l1_plist, cam->picture.palette))
3195 if (!w9968cf_valid_palette(mmap.format)) {
3196 DBG(4, "Palette %s not supported. "
3197 "VIDIOCMCAPTURE failed.",
3198 symbolic(v4l1_plist, mmap.format))
3202 if (!cam->force_palette) {
3203 if (cam->decompression == 0) {
3204 if (w9968cf_need_decompression(mmap.format)) {
3205 DBG(4, "Decompression disabled: palette %s is not "
3206 "allowed. VIDIOCSPICT failed.",
3207 symbolic(v4l1_plist, mmap.format))
3210 } else if (cam->decompression == 1) {
3211 if (!w9968cf_need_decompression(mmap.format)) {
3212 DBG(4, "Decompression forced: palette %s is not "
3213 "allowed. VIDIOCSPICT failed.",
3214 symbolic(v4l1_plist, mmap.format))
3220 if ((err = w9968cf_adjust_window_size(cam, (u16*)&mmap.width,
3221 (u16*)&mmap.height))) {
3222 DBG(4, "Resolution not supported (%dx%d). "
3223 "VIDIOCMCAPTURE failed.",
3224 mmap.width, mmap.height)
3228 fr = &cam->frame[mmap.frame];
3230 if (mmap.width != cam->window.width ||
3231 mmap.height != cam->window.height ||
3232 mmap.format != cam->picture.palette) {
3234 struct video_window win;
3235 struct video_picture pict;
3237 if(*cam->requested_frame
3238 || cam->frame_current->queued) {
3239 DBG(6, "VIDIOCMCAPTURE. Change settings for "
3240 "frame #%d: %dx%d, format %s. Wait...",
3241 mmap.frame, mmap.width, mmap.height,
3242 symbolic(v4l1_plist, mmap.format))
3243 err = wait_event_interruptible
3245 cam->disconnected ||
3246 (!*cam->requested_frame &&
3247 !cam->frame_current->queued) );
3250 if (cam->disconnected)
3254 memcpy(&win, &cam->window, sizeof(win));
3255 memcpy(&pict, &cam->picture, sizeof(pict));
3256 win.width = mmap.width;
3257 win.height = mmap.height;
3258 pict.palette = mmap.format;
3260 if (w9968cf_stop_transfer(cam))
3263 /* This before set_window */
3264 if (w9968cf_set_picture(cam, pict))
3267 if (w9968cf_set_window(cam, win))
3270 if (w9968cf_start_transfer(cam))
3273 } else if (fr->queued) {
3275 DBG(6, "Wait until frame #%d is free.", mmap.frame)
3277 err = wait_event_interruptible(cam->wait_queue,
3278 cam->disconnected ||
3282 if (cam->disconnected)
3286 w9968cf_push_frame(cam, mmap.frame);
3287 DBG(5, "VIDIOCMCAPTURE(%d): successfully called.", mmap.frame)
3291 case VIDIOCSYNC: /* wait until the capture of a frame is finished */
3294 struct w9968cf_frame_t* fr;
3297 if (copy_from_user(&f_num, arg, sizeof(f_num)))
3300 if (f_num >= cam->nbuffers) {
3301 DBG(4, "Invalid frame number (%d). "
3302 "VIDIOCMCAPTURE failed.", f_num)
3306 DBG(6, "VIDIOCSYNC called for frame #%d", f_num)
3308 fr = &cam->frame[f_num];
3310 switch (fr->status) {
3313 DBG(4, "VIDIOSYNC: Frame #%d not requested!",
3319 err = wait_event_interruptible(cam->wait_queue,
3320 (fr->status == F_READY)
3321 || cam->disconnected);
3324 if (cam->disconnected)
3331 if (w9968cf_vppmod_present)
3332 w9968cf_postprocess_frame(cam, fr);
3334 fr->status = F_UNUSED;
3336 DBG(5, "VIDIOCSYNC(%d) successfully called.", f_num)
3340 case VIDIOCGUNIT:/* report the unit numbers of the associated devices*/
3342 struct video_unit unit = {
3343 .video = cam->v4ldev->minor,
3344 .vbi = VIDEO_NO_UNIT,
3345 .radio = VIDEO_NO_UNIT,
3346 .audio = VIDEO_NO_UNIT,
3347 .teletext = VIDEO_NO_UNIT,
3350 if (copy_to_user(arg, &unit, sizeof(unit)))
3353 DBG(5, "VIDIOCGUNIT successfully called.")
3362 if (clear_user(arg, sizeof(struct video_buffer)))
3365 DBG(5, "VIDIOCGFBUF successfully called.")
3371 if (copy_from_user(&tuner, arg, sizeof(tuner)))
3374 if (tuner.tuner != 0)
3377 strcpy(tuner.name, "no_tuner");
3379 tuner.rangehigh = 0;
3380 tuner.flags = VIDEO_TUNER_NORM;
3381 tuner.mode = VIDEO_MODE_AUTO;
3382 tuner.signal = 0xffff;
3384 if (copy_to_user(arg, &tuner, sizeof(tuner)))
3387 DBG(5, "VIDIOCGTUNER successfully called.")
3393 if (copy_from_user(&tuner, arg, sizeof(tuner)))
3396 if (tuner.tuner != 0)
3399 if (tuner.mode != VIDEO_MODE_AUTO)
3402 DBG(5, "VIDIOCSTUNER successfully called.")
3412 case VIDIOCSPLAYMODE:
3413 case VIDIOCSWRITEMODE:
3414 case VIDIOCGPLAYINFO:
3415 case VIDIOCSMICROCODE:
3418 DBG(4, "Unsupported V4L1 IOCtl: VIDIOC%s "
3424 _IOC_TYPE(cmd),_IOC_NR(cmd),_IOC_DIR(cmd),_IOC_SIZE(cmd))
3429 DBG(4, "Invalid V4L1 IOCtl: VIDIOC%s "
3435 _IOC_TYPE(cmd),_IOC_NR(cmd),_IOC_DIR(cmd),_IOC_SIZE(cmd))
3437 return -ENOIOCTLCMD;
3439 } /* end of switch */
3442 cam->misconfigured = 1;
3443 DBG(1, "VIDIOC%s failed because of hardware problems. "
3444 "To use the camera, close and open it again.", V4L1_IOCTL(cmd))
3449 static struct file_operations w9968cf_fops = {
3450 .owner = THIS_MODULE,
3451 .open = w9968cf_open,
3452 .release = w9968cf_release,
3453 .read = w9968cf_read,
3454 .ioctl = w9968cf_ioctl,
3455 .mmap = w9968cf_mmap,
3456 .llseek = no_llseek,
3461 /****************************************************************************
3462 * USB probe and V4L registration, disconnect and id_table[] definition *
3463 ****************************************************************************/
3466 w9968cf_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
3468 struct usb_device *udev = interface_to_usbdev(intf);
3469 struct w9968cf_device* cam;
3471 enum w9968cf_model_id mod_id;
3472 struct list_head* ptr;
3473 u8 sc = 0; /* number of simultaneous cameras */
3474 static unsigned short dev_nr = 0; /* we are handling device number n */
3476 if (udev->descriptor.idVendor == winbond_id_table[0].idVendor &&
3477 udev->descriptor.idProduct == winbond_id_table[0].idProduct)
3478 mod_id = W9968CF_MOD_CLVBWGP; /* see camlist[] table */
3480 else if (udev->descriptor.idVendor == winbond_id_table[1].idVendor &&
3481 udev->descriptor.idProduct == winbond_id_table[1].idProduct)
3482 mod_id = W9968CF_MOD_GENERIC; /* see camlist[] table */
3487 DBG(2, "%s detected.", symbolic(camlist, mod_id))
3489 if (simcams > W9968CF_MAX_DEVICES)
3490 simcams = W9968CF_SIMCAMS;
3492 /* How many cameras are connected ? */
3493 down(&w9968cf_devlist_sem);
3494 list_for_each(ptr, &w9968cf_dev_list)
3496 up(&w9968cf_devlist_sem);
3498 if (sc >= simcams) {
3499 DBG(2, "Device rejected: too many connected cameras "
3500 "(max. %d)", simcams)
3504 cam = (struct w9968cf_device*)
3505 kmalloc(sizeof(struct w9968cf_device), GFP_KERNEL);
3508 DBG(1, "Couldn't allocate %zd bytes of kernel memory.",
3509 sizeof(struct w9968cf_device))
3513 memset(cam, 0, sizeof(*cam));
3515 init_MUTEX(&cam->dev_sem);
3516 down(&cam->dev_sem);
3518 /* Allocate 2 bytes of memory for camera control USB transfers */
3519 if (!(cam->control_buffer = (u16*)kmalloc(2, GFP_KERNEL))) {
3520 DBG(1,"Couldn't allocate memory for camera control transfers.")
3524 memset(cam->control_buffer, 0, 2);
3526 /* Allocate 8 bytes of memory for USB data transfers to the FSB */
3527 if (!(cam->data_buffer = (u16*)kmalloc(8, GFP_KERNEL))) {
3528 DBG(1, "Couldn't allocate memory for data "
3529 "transfers to the FSB.")
3533 memset(cam->data_buffer, 0, 8);
3535 /* Register the V4L device */
3536 cam->v4ldev = video_device_alloc();
3538 DBG(1, "Could not allocate memory for a V4L structure.")
3543 strcpy(cam->v4ldev->name, symbolic(camlist, mod_id));
3544 cam->v4ldev->owner = THIS_MODULE;
3545 cam->v4ldev->type = VID_TYPE_CAPTURE | VID_TYPE_SCALES;
3546 cam->v4ldev->hardware = VID_HARDWARE_W9968CF;
3547 cam->v4ldev->fops = &w9968cf_fops;
3548 cam->v4ldev->minor = video_nr[dev_nr];
3549 cam->v4ldev->release = video_device_release;
3550 video_set_drvdata(cam->v4ldev, cam);
3552 err = video_register_device(cam->v4ldev, VFL_TYPE_GRABBER,
3555 DBG(1, "V4L device registration failed.")
3556 if (err == -ENFILE && video_nr[dev_nr] == -1)
3557 DBG(2, "Couldn't find a free /dev/videoX node.")
3558 video_nr[dev_nr] = -1;
3559 dev_nr = (dev_nr < W9968CF_MAX_DEVICES-1) ? dev_nr+1 : 0;
3563 DBG(2, "V4L device registered as /dev/video%d.", cam->v4ldev->minor)
3565 /* Set some basic constants */
3566 w9968cf_configure_camera(cam, udev, mod_id, dev_nr);
3568 /* Add a new entry into the list of V4L registered devices */
3569 down(&w9968cf_devlist_sem);
3570 list_add(&cam->v4llist, &w9968cf_dev_list);
3571 up(&w9968cf_devlist_sem);
3572 dev_nr = (dev_nr < W9968CF_MAX_DEVICES-1) ? dev_nr+1 : 0;
3574 w9968cf_turn_on_led(cam);
3576 w9968cf_i2c_init(cam);
3580 usb_set_intfdata(intf, cam);
3583 fail: /* Free unused memory */
3585 if (cam->control_buffer)
3586 kfree(cam->control_buffer);
3587 if (cam->data_buffer)
3588 kfree(cam->data_buffer);
3590 video_device_release(cam->v4ldev);
3598 static void w9968cf_usb_disconnect(struct usb_interface* intf)
3600 struct w9968cf_device* cam =
3601 (struct w9968cf_device*)usb_get_intfdata(intf);
3604 /* Prevent concurrent accesses to data */
3605 down(&cam->dev_sem);
3608 cam->disconnected = 1;
3610 DBG(2, "Disconnecting %s...", symbolic(camlist, cam->id))
3612 if (waitqueue_active(&cam->open))
3613 wake_up_interruptible(&cam->open);
3616 DBG(2, "The device is open (/dev/video%d)! "
3617 "Process name: %s. Deregistration and memory "
3618 "deallocation are deferred on close.",
3619 cam->v4ldev->minor, cam->command)
3621 cam->misconfigured = 1;
3623 if (waitqueue_active(&cam->wait_queue))
3624 wake_up_interruptible(&cam->wait_queue);
3626 w9968cf_release_resources(cam);
3634 usb_set_intfdata(intf, NULL);
3638 static struct usb_driver w9968cf_usb_driver = {
3639 .owner = THIS_MODULE,
3641 .id_table = winbond_id_table,
3642 .probe = w9968cf_usb_probe,
3643 .disconnect = w9968cf_usb_disconnect,
3648 /****************************************************************************
3649 * Module init, exit and intermodule communication *
3650 ****************************************************************************/
3652 static int w9968cf_vppmod_detect(void)
3654 w9968cf_vpp_init_decoder = inter_module_get("w9968cf_init_decoder");
3656 if (!w9968cf_vpp_init_decoder) {
3658 w9968cf_vpp_init_decoder = inter_module_get_request
3659 ( "w9968cf_init_decoder",
3661 if (!w9968cf_vpp_init_decoder) {
3662 w9968cf_vppmod_present = 0;
3663 DBG(4, "Video post-processing module not detected.")
3668 w9968cf_vpp_check_headers = inter_module_get("w9968cf_check_headers");
3669 w9968cf_vpp_decode = inter_module_get("w9968cf_decode");
3670 w9968cf_vpp_swap_yuvbytes = inter_module_get("w9968cf_swap_yuvbytes");
3671 w9968cf_vpp_uyvy_to_rgbx = inter_module_get("w9968cf_uyvy_to_rgbx");
3672 w9968cf_vpp_scale_up = inter_module_get("w9968cf_scale_up");
3674 w9968cf_vppmod_present = 1;
3676 /* Initialization */
3677 (*w9968cf_vpp_init_decoder)();
3679 DBG(2, "Video post-processing module detected.")
3684 static void w9968cf_vppmod_release(void)
3686 inter_module_put("w9968cf_init_decoder");
3687 inter_module_put("w9968cf_check_headers");
3688 inter_module_put("w9968cf_decode");
3689 inter_module_put("w9968cf_swap_yuvbytes");
3690 inter_module_put("w9968cf_uyvy_to_rgbx");
3691 inter_module_put("w9968cf_scale_up");
3693 DBG(2, "Video post-processing module released.")
3697 static int __init w9968cf_module_init(void)
3701 DBG(2, W9968CF_MODULE_NAME" "W9968CF_MODULE_VERSION)
3702 DBG(3, W9968CF_MODULE_AUTHOR)
3704 init_MUTEX(&w9968cf_devlist_sem);
3706 w9968cf_vppmod_detect();
3708 if ((err = usb_register(&w9968cf_usb_driver))) {
3709 if (w9968cf_vppmod_present)
3710 w9968cf_vppmod_release();
3718 static void __exit w9968cf_module_exit(void)
3720 /* w9968cf_usb_disconnect() will be called */
3721 usb_deregister(&w9968cf_usb_driver);
3723 if (w9968cf_vppmod_present)
3724 w9968cf_vppmod_release();
3726 DBG(2, W9968CF_MODULE_NAME" deregistered.")
3730 module_init(w9968cf_module_init);
3731 module_exit(w9968cf_module_exit);