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 image 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/module.h>
29 #include <linux/kernel.h>
30 #include <linux/kmod.h>
31 #include <linux/init.h>
33 #include <linux/vmalloc.h>
34 #include <linux/slab.h>
36 #include <linux/string.h>
37 #include <linux/errno.h>
38 #include <linux/sched.h>
39 #include <linux/ioctl.h>
40 #include <linux/delay.h>
41 #include <linux/stddef.h>
43 #include <asm/uaccess.h>
44 #include <linux/page-flags.h>
45 #include <linux/moduleparam.h>
48 #include "w9968cf_decoder.h"
52 /****************************************************************************
53 * Module macros and parameters *
54 ****************************************************************************/
56 MODULE_DEVICE_TABLE(usb, winbond_id_table);
58 MODULE_AUTHOR(W9968CF_MODULE_AUTHOR" "W9968CF_AUTHOR_EMAIL);
59 MODULE_DESCRIPTION(W9968CF_MODULE_NAME);
60 MODULE_VERSION(W9968CF_MODULE_VERSION);
61 MODULE_LICENSE(W9968CF_MODULE_LICENSE);
62 MODULE_SUPPORTED_DEVICE("Video");
64 static int ovmod_load = W9968CF_OVMOD_LOAD;
65 static unsigned short simcams = W9968CF_SIMCAMS;
66 static short video_nr[]={[0 ... W9968CF_MAX_DEVICES-1] = -1}; /*-1=first free*/
67 static unsigned int packet_size[] = {[0 ... W9968CF_MAX_DEVICES-1] =
69 static unsigned short max_buffers[] = {[0 ... W9968CF_MAX_DEVICES-1] =
71 static int double_buffer[] = {[0 ... W9968CF_MAX_DEVICES-1] =
72 W9968CF_DOUBLE_BUFFER};
73 static int clamping[] = {[0 ... W9968CF_MAX_DEVICES-1] = W9968CF_CLAMPING};
74 static unsigned short filter_type[]= {[0 ... W9968CF_MAX_DEVICES-1] =
76 static int largeview[]= {[0 ... W9968CF_MAX_DEVICES-1] = W9968CF_LARGEVIEW};
77 static unsigned short decompression[] = {[0 ... W9968CF_MAX_DEVICES-1] =
78 W9968CF_DECOMPRESSION};
79 static int upscaling[]= {[0 ... W9968CF_MAX_DEVICES-1] = W9968CF_UPSCALING};
80 static unsigned short force_palette[] = {[0 ... W9968CF_MAX_DEVICES-1] = 0};
81 static int force_rgb[] = {[0 ... W9968CF_MAX_DEVICES-1] = W9968CF_FORCE_RGB};
82 static int autobright[] = {[0 ... W9968CF_MAX_DEVICES-1] = W9968CF_AUTOBRIGHT};
83 static int autoexp[] = {[0 ... W9968CF_MAX_DEVICES-1] = W9968CF_AUTOEXP};
84 static unsigned short lightfreq[] = {[0 ... W9968CF_MAX_DEVICES-1] =
86 static int bandingfilter[] = {[0 ... W9968CF_MAX_DEVICES-1]=
87 W9968CF_BANDINGFILTER};
88 static short clockdiv[] = {[0 ... W9968CF_MAX_DEVICES-1] = W9968CF_CLOCKDIV};
89 static int backlight[] = {[0 ... W9968CF_MAX_DEVICES-1] = W9968CF_BACKLIGHT};
90 static int mirror[] = {[0 ... W9968CF_MAX_DEVICES-1] = W9968CF_MIRROR};
91 static int monochrome[] = {[0 ... W9968CF_MAX_DEVICES-1]=W9968CF_MONOCHROME};
92 static unsigned int brightness[] = {[0 ... W9968CF_MAX_DEVICES-1] =
94 static unsigned int hue[] = {[0 ... W9968CF_MAX_DEVICES-1] = W9968CF_HUE};
95 static unsigned int colour[]={[0 ... W9968CF_MAX_DEVICES-1] = W9968CF_COLOUR};
96 static unsigned int contrast[] = {[0 ... W9968CF_MAX_DEVICES-1] =
98 static unsigned int whiteness[] = {[0 ... W9968CF_MAX_DEVICES-1] =
101 static unsigned short debug = W9968CF_DEBUG_LEVEL;
102 static int specific_debug = W9968CF_SPECIFIC_DEBUG;
105 static unsigned int param_nv[24]; /* number of values per parameter */
108 module_param(ovmod_load, bool, 0644);
110 module_param(simcams, ushort, 0644);
111 module_param_array(video_nr, short, ¶m_nv[0], 0444);
112 module_param_array(packet_size, uint, ¶m_nv[1], 0444);
113 module_param_array(max_buffers, ushort, ¶m_nv[2], 0444);
114 module_param_array(double_buffer, bool, ¶m_nv[3], 0444);
115 module_param_array(clamping, bool, ¶m_nv[4], 0444);
116 module_param_array(filter_type, ushort, ¶m_nv[5], 0444);
117 module_param_array(largeview, bool, ¶m_nv[6], 0444);
118 module_param_array(decompression, ushort, ¶m_nv[7], 0444);
119 module_param_array(upscaling, bool, ¶m_nv[8], 0444);
120 module_param_array(force_palette, ushort, ¶m_nv[9], 0444);
121 module_param_array(force_rgb, ushort, ¶m_nv[10], 0444);
122 module_param_array(autobright, bool, ¶m_nv[11], 0444);
123 module_param_array(autoexp, bool, ¶m_nv[12], 0444);
124 module_param_array(lightfreq, ushort, ¶m_nv[13], 0444);
125 module_param_array(bandingfilter, bool, ¶m_nv[14], 0444);
126 module_param_array(clockdiv, short, ¶m_nv[15], 0444);
127 module_param_array(backlight, bool, ¶m_nv[16], 0444);
128 module_param_array(mirror, bool, ¶m_nv[17], 0444);
129 module_param_array(monochrome, bool, ¶m_nv[18], 0444);
130 module_param_array(brightness, uint, ¶m_nv[19], 0444);
131 module_param_array(hue, uint, ¶m_nv[20], 0444);
132 module_param_array(colour, uint, ¶m_nv[21], 0444);
133 module_param_array(contrast, uint, ¶m_nv[22], 0444);
134 module_param_array(whiteness, uint, ¶m_nv[23], 0444);
136 module_param(debug, ushort, 0644);
137 module_param(specific_debug, bool, 0644);
141 MODULE_PARM_DESC(ovmod_load,
142 "\n<0|1> Automatic 'ovcamchip' module loading."
143 "\n0 disabled, 1 enabled."
144 "\nIf enabled,'insmod' searches for the required 'ovcamchip'"
145 "\nmodule in the system, according to its configuration, and"
146 "\nattempts to load that module automatically. This action is"
147 "\nperformed once as soon as the 'w9968cf' module is loaded"
149 "\nDefault value is "__MODULE_STRING(W9968CF_OVMOD_LOAD)"."
152 MODULE_PARM_DESC(simcams,
153 "\n<n> Number of cameras allowed to stream simultaneously."
154 "\nn may vary from 0 to "
155 __MODULE_STRING(W9968CF_MAX_DEVICES)"."
156 "\nDefault value is "__MODULE_STRING(W9968CF_SIMCAMS)"."
158 MODULE_PARM_DESC(video_nr,
159 "\n<-1|n[,...]> Specify V4L minor mode number."
160 "\n -1 = use next available (default)"
161 "\n n = use minor number n (integer >= 0)"
162 "\nYou can specify up to "__MODULE_STRING(W9968CF_MAX_DEVICES)
165 "\nvideo_nr=-1,2,-1 would assign minor number 2 to"
166 "\nthe second camera and use auto for the first"
167 "\none and for every other camera."
169 MODULE_PARM_DESC(packet_size,
170 "\n<n[,...]> Specify the maximum data payload"
171 "\nsize in bytes for alternate settings, for each device."
172 "\nn is scaled between 63 and 1023 "
173 "(default is "__MODULE_STRING(W9968CF_PACKET_SIZE)")."
175 MODULE_PARM_DESC(max_buffers,
176 "\n<n[,...]> For advanced users."
177 "\nSpecify the maximum number of video frame buffers"
178 "\nto allocate for each device, from 2 to "
179 __MODULE_STRING(W9968CF_MAX_BUFFERS)
180 ". (default is "__MODULE_STRING(W9968CF_BUFFERS)")."
182 MODULE_PARM_DESC(double_buffer,
184 "Hardware double buffering: 0 disabled, 1 enabled."
185 "\nIt should be enabled if you want smooth video output: if"
186 "\nyou obtain out of sync. video, disable it, or try to"
187 "\ndecrease the 'clockdiv' module parameter value."
188 "\nDefault value is "__MODULE_STRING(W9968CF_DOUBLE_BUFFER)
191 MODULE_PARM_DESC(clamping,
192 "\n<0|1[,...]> Video data clamping: 0 disabled, 1 enabled."
193 "\nDefault value is "__MODULE_STRING(W9968CF_CLAMPING)
196 MODULE_PARM_DESC(filter_type,
197 "\n<0|1|2[,...]> Video filter type."
198 "\n0 none, 1 (1-2-1) 3-tap filter, "
199 "2 (2-3-6-3-2) 5-tap filter."
200 "\nDefault value is "__MODULE_STRING(W9968CF_FILTER_TYPE)
202 "\nThe filter is used to reduce noise and aliasing artifacts"
203 "\nproduced by the CCD or CMOS image sensor, and the scaling"
206 MODULE_PARM_DESC(largeview,
207 "\n<0|1[,...]> Large view: 0 disabled, 1 enabled."
208 "\nDefault value is "__MODULE_STRING(W9968CF_LARGEVIEW)
211 MODULE_PARM_DESC(upscaling,
212 "\n<0|1[,...]> Software scaling (for non-compressed video):"
213 "\n0 disabled, 1 enabled."
214 "\nDisable it if you have a slow CPU or you don't have"
216 "\nDefault value is "__MODULE_STRING(W9968CF_UPSCALING)
218 "\nIf 'w9968cf-vpp' is not present, this parameter is"
221 MODULE_PARM_DESC(decompression,
222 "\n<0|1|2[,...]> Software video decompression:"
223 "\n- 0 disables decompression (doesn't allow formats needing"
225 "\n- 1 forces decompression (allows formats needing"
226 " decompression only);"
227 "\n- 2 allows any permitted formats."
228 "\nFormats supporting compressed video are YUV422P and"
230 "\nin any resolutions where both width and height are "
232 "\nDefault value is "__MODULE_STRING(W9968CF_DECOMPRESSION)
234 "\nIf 'w9968cf-vpp' is not present, forcing decompression is "
235 "\nnot allowed; in this case this parameter is set to 2."
237 MODULE_PARM_DESC(force_palette,
239 "|" __MODULE_STRING(VIDEO_PALETTE_UYVY)
240 "|" __MODULE_STRING(VIDEO_PALETTE_YUV420)
241 "|" __MODULE_STRING(VIDEO_PALETTE_YUV422P)
242 "|" __MODULE_STRING(VIDEO_PALETTE_YUV420P)
243 "|" __MODULE_STRING(VIDEO_PALETTE_YUYV)
244 "|" __MODULE_STRING(VIDEO_PALETTE_YUV422)
245 "|" __MODULE_STRING(VIDEO_PALETTE_GREY)
246 "|" __MODULE_STRING(VIDEO_PALETTE_RGB555)
247 "|" __MODULE_STRING(VIDEO_PALETTE_RGB565)
248 "|" __MODULE_STRING(VIDEO_PALETTE_RGB24)
249 "|" __MODULE_STRING(VIDEO_PALETTE_RGB32)
251 " Force picture palette."
253 "\n- 0 allows any of the following formats:"
254 "\n- UYVY 16 bpp - Original video, compression disabled"
255 "\n- YUV420 12 bpp - Original video, compression enabled"
256 "\n- YUV422P 16 bpp - Original video, compression enabled"
257 "\n- YUV420P 12 bpp - Original video, compression enabled"
258 "\n- YUVY 16 bpp - Software conversion from UYVY"
259 "\n- YUV422 16 bpp - Software conversion from UYVY"
260 "\n- GREY 8 bpp - Software conversion from UYVY"
261 "\n- RGB555 16 bpp - Software conversion from UYVY"
262 "\n- RGB565 16 bpp - Software conversion from UYVY"
263 "\n- RGB24 24 bpp - Software conversion from UYVY"
264 "\n- RGB32 32 bpp - Software conversion from UYVY"
265 "\nWhen not 0, this parameter will override 'decompression'."
266 "\nDefault value is 0 for every device."
267 "\nInitial palette is "
268 __MODULE_STRING(W9968CF_PALETTE_DECOMP_ON)"."
269 "\nIf 'w9968cf-vpp' is not present, this parameter is"
272 MODULE_PARM_DESC(force_rgb,
273 "\n<0|1[,...]> Read RGB video data instead of BGR:"
274 "\n 1 = use RGB component ordering."
275 "\n 0 = use BGR component ordering."
276 "\nThis parameter has effect when using RGBX palettes only."
277 "\nDefault value is "__MODULE_STRING(W9968CF_FORCE_RGB)
280 MODULE_PARM_DESC(autobright,
281 "\n<0|1[,...]> Image sensor automatically changes brightness:"
283 "\nDefault value is "__MODULE_STRING(W9968CF_AUTOBRIGHT)
286 MODULE_PARM_DESC(autoexp,
287 "\n<0|1[,...]> Image sensor automatically changes exposure:"
289 "\nDefault value is "__MODULE_STRING(W9968CF_AUTOEXP)
292 MODULE_PARM_DESC(lightfreq,
293 "\n<50|60[,...]> Light frequency in Hz:"
294 "\n 50 for European and Asian lighting,"
295 " 60 for American lighting."
296 "\nDefault value is "__MODULE_STRING(W9968CF_LIGHTFREQ)
299 MODULE_PARM_DESC(bandingfilter,
300 "\n<0|1[,...]> Banding filter to reduce effects of"
301 " fluorescent lighting:"
302 "\n 0 disabled, 1 enabled."
303 "\nThis filter tries to reduce the pattern of horizontal"
304 "\nlight/dark bands caused by some (usually fluorescent)"
306 "\nDefault value is "__MODULE_STRING(W9968CF_BANDINGFILTER)
309 MODULE_PARM_DESC(clockdiv,
311 "Force pixel clock divisor to a specific value (for experts):"
312 "\n n may vary from 0 to 127."
313 "\n -1 for automatic value."
314 "\nSee also the 'double_buffer' module parameter."
315 "\nDefault value is "__MODULE_STRING(W9968CF_CLOCKDIV)
318 MODULE_PARM_DESC(backlight,
319 "\n<0|1[,...]> Objects are lit from behind:"
321 "\nDefault value is "__MODULE_STRING(W9968CF_BACKLIGHT)
324 MODULE_PARM_DESC(mirror,
325 "\n<0|1[,...]> Reverse image horizontally:"
327 "\nDefault value is "__MODULE_STRING(W9968CF_MIRROR)
330 MODULE_PARM_DESC(monochrome,
331 "\n<0|1[,...]> Use image sensor as monochrome sensor:"
333 "\nNot all the sensors support monochrome color."
334 "\nDefault value is "__MODULE_STRING(W9968CF_MONOCHROME)
337 MODULE_PARM_DESC(brightness,
338 "\n<n[,...]> Set picture brightness (0-65535)."
339 "\nDefault value is "__MODULE_STRING(W9968CF_BRIGHTNESS)
341 "\nThis parameter has no effect if 'autobright' is enabled."
343 MODULE_PARM_DESC(hue,
344 "\n<n[,...]> Set picture hue (0-65535)."
345 "\nDefault value is "__MODULE_STRING(W9968CF_HUE)
348 MODULE_PARM_DESC(colour,
349 "\n<n[,...]> Set picture saturation (0-65535)."
350 "\nDefault value is "__MODULE_STRING(W9968CF_COLOUR)
353 MODULE_PARM_DESC(contrast,
354 "\n<n[,...]> Set picture contrast (0-65535)."
355 "\nDefault value is "__MODULE_STRING(W9968CF_CONTRAST)
358 MODULE_PARM_DESC(whiteness,
359 "\n<n[,...]> Set picture whiteness (0-65535)."
360 "\nDefault value is "__MODULE_STRING(W9968CF_WHITENESS)
364 MODULE_PARM_DESC(debug,
365 "\n<n> Debugging information level, from 0 to 6:"
366 "\n0 = none (use carefully)"
367 "\n1 = critical errors"
368 "\n2 = significant informations"
369 "\n3 = configuration or general messages"
371 "\n5 = called functions"
372 "\n6 = function internals"
373 "\nLevel 5 and 6 are useful for testing only, when only "
374 "one device is used."
375 "\nDefault value is "__MODULE_STRING(W9968CF_DEBUG_LEVEL)"."
377 MODULE_PARM_DESC(specific_debug,
378 "\n<0|1> Enable or disable specific debugging messages:"
379 "\n0 = print messages concerning every level"
381 "\n1 = print messages concerning the level"
382 " indicated by 'debug'."
383 "\nDefault value is "
384 __MODULE_STRING(W9968CF_SPECIFIC_DEBUG)"."
386 #endif /* W9968CF_DEBUG */
390 /****************************************************************************
392 ****************************************************************************/
394 /* Video4linux interface */
395 static struct file_operations w9968cf_fops;
396 static int w9968cf_open(struct inode*, struct file*);
397 static int w9968cf_release(struct inode*, struct file*);
398 static int w9968cf_mmap(struct file*, struct vm_area_struct*);
399 static int w9968cf_ioctl(struct inode*, struct file*, unsigned, unsigned long);
400 static ssize_t w9968cf_read(struct file*, char __user *, size_t, loff_t*);
401 static int w9968cf_v4l_ioctl(struct inode*, struct file*, unsigned int,
405 static int w9968cf_start_transfer(struct w9968cf_device*);
406 static int w9968cf_stop_transfer(struct w9968cf_device*);
407 static int w9968cf_write_reg(struct w9968cf_device*, u16 value, u16 index);
408 static int w9968cf_read_reg(struct w9968cf_device*, u16 index);
409 static int w9968cf_write_fsb(struct w9968cf_device*, u16* data);
410 static int w9968cf_write_sb(struct w9968cf_device*, u16 value);
411 static int w9968cf_read_sb(struct w9968cf_device*);
412 static int w9968cf_upload_quantizationtables(struct w9968cf_device*);
413 static void w9968cf_urb_complete(struct urb *urb, struct pt_regs *regs);
415 /* Low-level I2C (SMBus) I/O */
416 static int w9968cf_smbus_start(struct w9968cf_device*);
417 static int w9968cf_smbus_stop(struct w9968cf_device*);
418 static int w9968cf_smbus_write_byte(struct w9968cf_device*, u8 v);
419 static int w9968cf_smbus_read_byte(struct w9968cf_device*, u8* v);
420 static int w9968cf_smbus_write_ack(struct w9968cf_device*);
421 static int w9968cf_smbus_read_ack(struct w9968cf_device*);
422 static int w9968cf_smbus_refresh_bus(struct w9968cf_device*);
423 static int w9968cf_i2c_adap_read_byte(struct w9968cf_device* cam,
424 u16 address, u8* value);
425 static int w9968cf_i2c_adap_read_byte_data(struct w9968cf_device*, u16 address,
426 u8 subaddress, u8* value);
427 static int w9968cf_i2c_adap_write_byte(struct w9968cf_device*,
428 u16 address, u8 subaddress);
429 static int w9968cf_i2c_adap_fastwrite_byte_data(struct w9968cf_device*,
430 u16 address, u8 subaddress,
433 /* I2C interface to kernel */
434 static int w9968cf_i2c_init(struct w9968cf_device*);
435 static int w9968cf_i2c_smbus_xfer(struct i2c_adapter*, u16 addr,
436 unsigned short flags, char read_write,
437 u8 command, int size, union i2c_smbus_data*);
438 static u32 w9968cf_i2c_func(struct i2c_adapter*);
439 static int w9968cf_i2c_attach_inform(struct i2c_client*);
440 static int w9968cf_i2c_detach_inform(struct i2c_client*);
441 static int w9968cf_i2c_control(struct i2c_adapter*, unsigned int cmd,
444 /* Memory management */
445 static void* rvmalloc(unsigned long size);
446 static void rvfree(void *mem, unsigned long size);
447 static void w9968cf_deallocate_memory(struct w9968cf_device*);
448 static int w9968cf_allocate_memory(struct w9968cf_device*);
450 /* High-level image sensor control functions */
451 static int w9968cf_sensor_set_control(struct w9968cf_device*,int cid,int val);
452 static int w9968cf_sensor_get_control(struct w9968cf_device*,int cid,int *val);
453 static int w9968cf_sensor_cmd(struct w9968cf_device*,
454 unsigned int cmd, void *arg);
455 static int w9968cf_sensor_init(struct w9968cf_device*);
456 static int w9968cf_sensor_update_settings(struct w9968cf_device*);
457 static int w9968cf_sensor_get_picture(struct w9968cf_device*);
458 static int w9968cf_sensor_update_picture(struct w9968cf_device*,
459 struct video_picture pict);
461 /* Other helper functions */
462 static void w9968cf_configure_camera(struct w9968cf_device*,struct usb_device*,
463 enum w9968cf_model_id,
464 const unsigned short dev_nr);
465 static void w9968cf_adjust_configuration(struct w9968cf_device*);
466 static int w9968cf_turn_on_led(struct w9968cf_device*);
467 static int w9968cf_init_chip(struct w9968cf_device*);
468 static inline u16 w9968cf_valid_palette(u16 palette);
469 static inline u16 w9968cf_valid_depth(u16 palette);
470 static inline u8 w9968cf_need_decompression(u16 palette);
471 static int w9968cf_set_picture(struct w9968cf_device*, struct video_picture);
472 static int w9968cf_set_window(struct w9968cf_device*, struct video_window);
473 static int w9968cf_postprocess_frame(struct w9968cf_device*,
474 struct w9968cf_frame_t*);
475 static int w9968cf_adjust_window_size(struct w9968cf_device*, u16* w, u16* h);
476 static void w9968cf_init_framelist(struct w9968cf_device*);
477 static void w9968cf_push_frame(struct w9968cf_device*, u8 f_num);
478 static void w9968cf_pop_frame(struct w9968cf_device*,struct w9968cf_frame_t**);
479 static void w9968cf_release_resources(struct w9968cf_device*);
483 /****************************************************************************
485 ****************************************************************************/
487 /* Used to represent a list of values and their respective symbolic names */
488 struct w9968cf_symbolic_list {
493 /*--------------------------------------------------------------------------
494 Returns the name of the matching element in the symbolic_list array. The
495 end of the list must be marked with an element that has a NULL name.
496 --------------------------------------------------------------------------*/
497 static inline const char *
498 symbolic(struct w9968cf_symbolic_list list[], const int num)
502 for (i = 0; list[i].name != NULL; i++)
503 if (list[i].num == num)
504 return (list[i].name);
509 static struct w9968cf_symbolic_list camlist[] = {
510 { W9968CF_MOD_GENERIC, "W996[87]CF JPEG USB Dual Mode Camera" },
511 { W9968CF_MOD_CLVBWGP, "Creative Labs Video Blaster WebCam Go Plus" },
513 /* Other cameras (having the same descriptors as Generic W996[87]CF) */
514 { W9968CF_MOD_ADPVDMA, "Aroma Digi Pen VGA Dual Mode ADG-5000" },
515 { W9986CF_MOD_AAU, "AVerMedia AVerTV USB" },
516 { W9968CF_MOD_CLVBWG, "Creative Labs Video Blaster WebCam Go" },
517 { W9968CF_MOD_LL, "Lebon LDC-035A" },
518 { W9968CF_MOD_EEEMC, "Ezonics EZ-802 EZMega Cam" },
519 { W9968CF_MOD_OOE, "OmniVision OV8610-EDE" },
520 { W9968CF_MOD_ODPVDMPC, "OPCOM Digi Pen VGA Dual Mode Pen Camera" },
521 { W9968CF_MOD_PDPII, "Pretec Digi Pen-II" },
522 { W9968CF_MOD_PDP480, "Pretec DigiPen-480" },
527 static struct w9968cf_symbolic_list senlist[] = {
528 { CC_OV76BE, "OV76BE" },
529 { CC_OV7610, "OV7610" },
530 { CC_OV7620, "OV7620" },
531 { CC_OV7620AE, "OV7620AE" },
532 { CC_OV6620, "OV6620" },
533 { CC_OV6630, "OV6630" },
534 { CC_OV6630AE, "OV6630AE" },
535 { CC_OV6630AF, "OV6630AF" },
539 /* Video4Linux1 palettes */
540 static struct w9968cf_symbolic_list v4l1_plist[] = {
541 { VIDEO_PALETTE_GREY, "GREY" },
542 { VIDEO_PALETTE_HI240, "HI240" },
543 { VIDEO_PALETTE_RGB565, "RGB565" },
544 { VIDEO_PALETTE_RGB24, "RGB24" },
545 { VIDEO_PALETTE_RGB32, "RGB32" },
546 { VIDEO_PALETTE_RGB555, "RGB555" },
547 { VIDEO_PALETTE_YUV422, "YUV422" },
548 { VIDEO_PALETTE_YUYV, "YUYV" },
549 { VIDEO_PALETTE_UYVY, "UYVY" },
550 { VIDEO_PALETTE_YUV420, "YUV420" },
551 { VIDEO_PALETTE_YUV411, "YUV411" },
552 { VIDEO_PALETTE_RAW, "RAW" },
553 { VIDEO_PALETTE_YUV422P, "YUV422P" },
554 { VIDEO_PALETTE_YUV411P, "YUV411P" },
555 { VIDEO_PALETTE_YUV420P, "YUV420P" },
556 { VIDEO_PALETTE_YUV410P, "YUV410P" },
560 /* Decoder error codes: */
561 static struct w9968cf_symbolic_list decoder_errlist[] = {
562 { W9968CF_DEC_ERR_CORRUPTED_DATA, "Corrupted data" },
563 { W9968CF_DEC_ERR_BUF_OVERFLOW, "Buffer overflow" },
564 { W9968CF_DEC_ERR_NO_SOI, "SOI marker not found" },
565 { W9968CF_DEC_ERR_NO_SOF0, "SOF0 marker not found" },
566 { W9968CF_DEC_ERR_NO_SOS, "SOS marker not found" },
567 { W9968CF_DEC_ERR_NO_EOI, "EOI marker not found" },
571 /* URB error codes: */
572 static struct w9968cf_symbolic_list urb_errlist[] = {
573 { -ENOMEM, "No memory for allocation of internal structures" },
574 { -ENOSPC, "The host controller's bandwidth is already consumed" },
575 { -ENOENT, "URB was canceled by unlink_urb" },
576 { -EXDEV, "ISO transfer only partially completed" },
577 { -EAGAIN, "Too match scheduled for the future" },
578 { -ENXIO, "URB already queued" },
579 { -EFBIG, "Too much ISO frames requested" },
580 { -ENOSR, "Buffer error (overrun)" },
581 { -EPIPE, "Specified endpoint is stalled (device not responding)"},
582 { -EOVERFLOW, "Babble (bad cable?)" },
583 { -EPROTO, "Bit-stuff error (bad cable?)" },
584 { -EILSEQ, "CRC/Timeout" },
585 { -ETIMEDOUT, "NAK (device does not respond)" },
591 /****************************************************************************
592 * Memory management functions *
593 ****************************************************************************/
594 static void* rvmalloc(unsigned long size)
599 size = PAGE_ALIGN(size);
600 mem = vmalloc_32(size);
604 memset(mem, 0, size); /* Clear the ram out, no junk to the user */
605 adr = (unsigned long) mem;
607 SetPageReserved(vmalloc_to_page((void *)adr));
616 static void rvfree(void* mem, unsigned long size)
623 adr = (unsigned long) mem;
624 while ((long) size > 0) {
625 ClearPageReserved(vmalloc_to_page((void *)adr));
633 /*--------------------------------------------------------------------------
634 Deallocate previously allocated memory.
635 --------------------------------------------------------------------------*/
636 static void w9968cf_deallocate_memory(struct w9968cf_device* cam)
640 /* Free the isochronous transfer buffers */
641 for (i = 0; i < W9968CF_URBS; i++) {
642 kfree(cam->transfer_buffer[i]);
643 cam->transfer_buffer[i] = NULL;
646 /* Free temporary frame buffer */
647 if (cam->frame_tmp.buffer) {
648 rvfree(cam->frame_tmp.buffer, cam->frame_tmp.size);
649 cam->frame_tmp.buffer = NULL;
652 /* Free helper buffer */
653 if (cam->frame_vpp.buffer) {
654 rvfree(cam->frame_vpp.buffer, cam->frame_vpp.size);
655 cam->frame_vpp.buffer = NULL;
658 /* Free video frame buffers */
659 if (cam->frame[0].buffer) {
660 rvfree(cam->frame[0].buffer, cam->nbuffers*cam->frame[0].size);
661 cam->frame[0].buffer = NULL;
666 DBG(5, "Memory successfully deallocated")
670 /*--------------------------------------------------------------------------
671 Allocate memory buffers for USB transfers and video frames.
672 This function is called by open() only.
673 Return 0 on success, a negative number otherwise.
674 --------------------------------------------------------------------------*/
675 static int w9968cf_allocate_memory(struct w9968cf_device* cam)
677 const u16 p_size = wMaxPacketSize[cam->altsetting-1];
679 unsigned long hw_bufsize, vpp_bufsize;
682 /* NOTE: Deallocation is done elsewhere in case of error */
684 /* Calculate the max amount of raw data per frame from the device */
685 hw_bufsize = cam->maxwidth*cam->maxheight*2;
687 /* Calculate the max buf. size needed for post-processing routines */
688 bpp = (w9968cf_vpp) ? 4 : 2;
690 vpp_bufsize = max(W9968CF_MAX_WIDTH*W9968CF_MAX_HEIGHT*bpp,
691 cam->maxwidth*cam->maxheight*bpp);
693 vpp_bufsize = cam->maxwidth*cam->maxheight*bpp;
695 /* Allocate memory for the isochronous transfer buffers */
696 for (i = 0; i < W9968CF_URBS; i++) {
697 if (!(cam->transfer_buffer[i] =
698 kzalloc(W9968CF_ISO_PACKETS*p_size, GFP_KERNEL))) {
699 DBG(1, "Couldn't allocate memory for the isochronous "
700 "transfer buffers (%u bytes)",
701 p_size * W9968CF_ISO_PACKETS)
706 /* Allocate memory for the temporary frame buffer */
707 if (!(cam->frame_tmp.buffer = rvmalloc(hw_bufsize))) {
708 DBG(1, "Couldn't allocate memory for the temporary "
709 "video frame buffer (%lu bytes)", hw_bufsize)
712 cam->frame_tmp.size = hw_bufsize;
713 cam->frame_tmp.number = -1;
715 /* Allocate memory for the helper buffer */
717 if (!(cam->frame_vpp.buffer = rvmalloc(vpp_bufsize))) {
718 DBG(1, "Couldn't allocate memory for the helper buffer"
719 " (%lu bytes)", vpp_bufsize)
722 cam->frame_vpp.size = vpp_bufsize;
724 cam->frame_vpp.buffer = NULL;
726 /* Allocate memory for video frame buffers */
727 cam->nbuffers = cam->max_buffers;
728 while (cam->nbuffers >= 2) {
729 if ((buff = rvmalloc(cam->nbuffers * vpp_bufsize)))
736 DBG(1, "Couldn't allocate memory for the video frame buffers")
741 if (cam->nbuffers != cam->max_buffers)
742 DBG(2, "Couldn't allocate memory for %u video frame buffers. "
743 "Only memory for %u buffers has been allocated",
744 cam->max_buffers, cam->nbuffers)
746 for (i = 0; i < cam->nbuffers; i++) {
747 cam->frame[i].buffer = buff + i*vpp_bufsize;
748 cam->frame[i].size = vpp_bufsize;
749 cam->frame[i].number = i;
751 if (i != cam->nbuffers-1)
752 cam->frame[i].next = &cam->frame[i+1];
754 cam->frame[i].next = &cam->frame[0];
755 cam->frame[i].status = F_UNUSED;
758 DBG(5, "Memory successfully allocated")
764 /****************************************************************************
765 * USB-specific functions *
766 ****************************************************************************/
768 /*--------------------------------------------------------------------------
769 This is an handler function which is called after the URBs are completed.
770 It collects multiple data packets coming from the camera by putting them
771 into frame buffers: one or more zero data length data packets are used to
772 mark the end of a video frame; the first non-zero data packet is the start
773 of the next video frame; if an error is encountered in a packet, the entire
774 video frame is discarded and grabbed again.
775 If there are no requested frames in the FIFO list, packets are collected into
777 --------------------------------------------------------------------------*/
778 static void w9968cf_urb_complete(struct urb *urb, struct pt_regs *regs)
780 struct w9968cf_device* cam = (struct w9968cf_device*)urb->context;
781 struct w9968cf_frame_t** f;
782 unsigned int len, status;
787 if ((!cam->streaming) || cam->disconnected) {
788 DBG(4, "Got interrupt, but not streaming")
792 /* "(*f)" will be used instead of "cam->frame_current" */
793 f = &cam->frame_current;
795 /* If a frame has been requested and we are grabbing into
796 the temporary frame, we'll switch to that requested frame */
797 if ((*f) == &cam->frame_tmp && *cam->requested_frame) {
798 if (cam->frame_tmp.status == F_GRABBING) {
799 w9968cf_pop_frame(cam, &cam->frame_current);
800 (*f)->status = F_GRABBING;
801 (*f)->length = cam->frame_tmp.length;
802 memcpy((*f)->buffer, cam->frame_tmp.buffer,
804 DBG(6, "Switched from temp. frame to frame #%d",
809 for (i = 0; i < urb->number_of_packets; i++) {
810 len = urb->iso_frame_desc[i].actual_length;
811 status = urb->iso_frame_desc[i].status;
812 pos = urb->iso_frame_desc[i].offset + urb->transfer_buffer;
814 if (status && len != 0) {
815 DBG(4, "URB failed, error in data packet "
817 status, symbolic(urb_errlist, status))
818 (*f)->status = F_ERROR;
822 if (len) { /* start of frame */
824 if ((*f)->status == F_UNUSED) {
825 (*f)->status = F_GRABBING;
829 /* Buffer overflows shouldn't happen, however...*/
830 if ((*f)->length + len > (*f)->size) {
831 DBG(4, "Buffer overflow: bad data packets")
832 (*f)->status = F_ERROR;
835 if ((*f)->status == F_GRABBING) {
836 memcpy((*f)->buffer + (*f)->length, pos, len);
840 } else if ((*f)->status == F_GRABBING) { /* end of frame */
842 DBG(6, "Frame #%d successfully grabbed", (*f)->number)
844 if (cam->vpp_flag & VPP_DECOMPRESSION) {
845 err = w9968cf_vpp->check_headers((*f)->buffer,
848 DBG(4, "Skip corrupted frame: %s",
849 symbolic(decoder_errlist, err))
850 (*f)->status = F_UNUSED;
851 continue; /* grab this frame again */
855 (*f)->status = F_READY;
858 /* Take a pointer to the new frame from the FIFO list.
859 If the list is empty,we'll use the temporary frame*/
860 if (*cam->requested_frame)
861 w9968cf_pop_frame(cam, &cam->frame_current);
863 cam->frame_current = &cam->frame_tmp;
864 (*f)->status = F_UNUSED;
867 } else if ((*f)->status == F_ERROR)
868 (*f)->status = F_UNUSED; /* grab it again */
870 PDBGG("Frame length %lu | pack.#%u | pack.len. %u | state %d",
871 (unsigned long)(*f)->length, i, len, (*f)->status)
875 /* Resubmit this URB */
876 urb->dev = cam->usbdev;
878 spin_lock(&cam->urb_lock);
880 if ((err = usb_submit_urb(urb, GFP_ATOMIC))) {
881 cam->misconfigured = 1;
882 DBG(1, "Couldn't resubmit the URB: error %d, %s",
883 err, symbolic(urb_errlist, err))
885 spin_unlock(&cam->urb_lock);
887 /* Wake up the user process */
888 wake_up_interruptible(&cam->wait_queue);
892 /*---------------------------------------------------------------------------
893 Setup the URB structures for the isochronous transfer.
894 Submit the URBs so that the data transfer begins.
895 Return 0 on success, a negative number otherwise.
896 ---------------------------------------------------------------------------*/
897 static int w9968cf_start_transfer(struct w9968cf_device* cam)
899 struct usb_device *udev = cam->usbdev;
901 const u16 p_size = wMaxPacketSize[cam->altsetting-1];
908 for (i = 0; i < W9968CF_URBS; i++) {
909 urb = usb_alloc_urb(W9968CF_ISO_PACKETS, GFP_KERNEL);
912 for (j = 0; j < i; j++)
913 usb_free_urb(cam->urb[j]);
914 DBG(1, "Couldn't allocate the URB structures")
919 urb->context = (void*)cam;
920 urb->pipe = usb_rcvisocpipe(udev, 1);
921 urb->transfer_flags = URB_ISO_ASAP;
922 urb->number_of_packets = W9968CF_ISO_PACKETS;
923 urb->complete = w9968cf_urb_complete;
924 urb->transfer_buffer = cam->transfer_buffer[i];
925 urb->transfer_buffer_length = p_size*W9968CF_ISO_PACKETS;
927 for (j = 0; j < W9968CF_ISO_PACKETS; j++) {
928 urb->iso_frame_desc[j].offset = p_size*j;
929 urb->iso_frame_desc[j].length = p_size;
933 /* Transfer size per frame, in WORD ! */
940 err = w9968cf_write_reg(cam, 0xbf17, 0x00); /* reset everything */
941 err += w9968cf_write_reg(cam, 0xbf10, 0x00); /* normal operation */
944 err += w9968cf_write_reg(cam, t_size & 0xffff, 0x3d); /* low bits */
945 err += w9968cf_write_reg(cam, t_size >> 16, 0x3e); /* high bits */
947 if (cam->vpp_flag & VPP_DECOMPRESSION)
948 err += w9968cf_upload_quantizationtables(cam);
950 vidcapt = w9968cf_read_reg(cam, 0x16); /* read picture settings */
951 err += w9968cf_write_reg(cam, vidcapt|0x8000, 0x16); /* capt. enable */
953 err += usb_set_interface(udev, 0, cam->altsetting);
954 err += w9968cf_write_reg(cam, 0x8a05, 0x3c); /* USB FIFO enable */
956 if (err || (vidcapt < 0)) {
957 for (i = 0; i < W9968CF_URBS; i++)
958 usb_free_urb(cam->urb[i]);
959 DBG(1, "Couldn't tell the camera to start the data transfer")
963 w9968cf_init_framelist(cam);
965 /* Begin to grab into the temporary buffer */
966 cam->frame_tmp.status = F_UNUSED;
967 cam->frame_tmp.queued = 0;
968 cam->frame_current = &cam->frame_tmp;
970 if (!(cam->vpp_flag & VPP_DECOMPRESSION))
971 DBG(5, "Isochronous transfer size: %lu bytes/frame",
972 (unsigned long)t_size*2)
974 DBG(5, "Starting the isochronous transfer...")
978 /* Submit the URBs */
979 for (i = 0; i < W9968CF_URBS; i++) {
980 err = usb_submit_urb(cam->urb[i], GFP_KERNEL);
983 for (j = i-1; j >= 0; j--) {
984 usb_kill_urb(cam->urb[j]);
985 usb_free_urb(cam->urb[j]);
987 DBG(1, "Couldn't send a transfer request to the "
988 "USB core (error #%d, %s)", err,
989 symbolic(urb_errlist, err))
998 /*--------------------------------------------------------------------------
999 Stop the isochronous transfer and set alternate setting to 0 (0Mb/s).
1000 Return 0 on success, a negative number otherwise.
1001 --------------------------------------------------------------------------*/
1002 static int w9968cf_stop_transfer(struct w9968cf_device* cam)
1004 struct usb_device *udev = cam->usbdev;
1005 unsigned long lock_flags;
1009 if (!cam->streaming)
1012 /* This avoids race conditions with usb_submit_urb()
1013 in the URB completition handler */
1014 spin_lock_irqsave(&cam->urb_lock, lock_flags);
1016 spin_unlock_irqrestore(&cam->urb_lock, lock_flags);
1018 for (i = W9968CF_URBS-1; i >= 0; i--)
1020 usb_kill_urb(cam->urb[i]);
1021 usb_free_urb(cam->urb[i]);
1025 if (cam->disconnected)
1028 err = w9968cf_write_reg(cam, 0x0a05, 0x3c); /* stop USB transfer */
1029 err += usb_set_interface(udev, 0, 0); /* 0 Mb/s */
1030 err += w9968cf_write_reg(cam, 0x0000, 0x39); /* disable JPEG encoder */
1031 err += w9968cf_write_reg(cam, 0x0000, 0x16); /* stop video capture */
1034 DBG(2, "Failed to tell the camera to stop the isochronous "
1035 "transfer. However this is not a critical error.")
1040 DBG(5, "Isochronous transfer stopped")
1045 /*--------------------------------------------------------------------------
1046 Write a W9968CF register.
1047 Return 0 on success, -1 otherwise.
1048 --------------------------------------------------------------------------*/
1049 static int w9968cf_write_reg(struct w9968cf_device* cam, u16 value, u16 index)
1051 struct usb_device* udev = cam->usbdev;
1054 res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0,
1055 USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE,
1056 value, index, NULL, 0, W9968CF_USB_CTRL_TIMEOUT);
1059 DBG(4, "Failed to write a register "
1060 "(value 0x%04X, index 0x%02X, error #%d, %s)",
1061 value, index, res, symbolic(urb_errlist, res))
1063 return (res >= 0) ? 0 : -1;
1067 /*--------------------------------------------------------------------------
1068 Read a W9968CF register.
1069 Return the register value on success, -1 otherwise.
1070 --------------------------------------------------------------------------*/
1071 static int w9968cf_read_reg(struct w9968cf_device* cam, u16 index)
1073 struct usb_device* udev = cam->usbdev;
1074 u16* buff = cam->control_buffer;
1077 res = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 1,
1078 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
1079 0, index, buff, 2, W9968CF_USB_CTRL_TIMEOUT);
1082 DBG(4, "Failed to read a register "
1083 "(index 0x%02X, error #%d, %s)",
1084 index, res, symbolic(urb_errlist, res))
1086 return (res >= 0) ? (int)(*buff) : -1;
1090 /*--------------------------------------------------------------------------
1091 Write 64-bit data to the fast serial bus registers.
1092 Return 0 on success, -1 otherwise.
1093 --------------------------------------------------------------------------*/
1094 static int w9968cf_write_fsb(struct w9968cf_device* cam, u16* data)
1096 struct usb_device* udev = cam->usbdev;
1102 res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0,
1103 USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE,
1104 value, 0x06, data, 6, W9968CF_USB_CTRL_TIMEOUT);
1107 DBG(4, "Failed to write the FSB registers "
1108 "(error #%d, %s)", res, symbolic(urb_errlist, res))
1110 return (res >= 0) ? 0 : -1;
1114 /*--------------------------------------------------------------------------
1115 Write data to the serial bus control register.
1116 Return 0 on success, a negative number otherwise.
1117 --------------------------------------------------------------------------*/
1118 static int w9968cf_write_sb(struct w9968cf_device* cam, u16 value)
1122 err = w9968cf_write_reg(cam, value, 0x01);
1123 udelay(W9968CF_I2C_BUS_DELAY);
1129 /*--------------------------------------------------------------------------
1130 Read data from the serial bus control register.
1131 Return 0 on success, a negative number otherwise.
1132 --------------------------------------------------------------------------*/
1133 static int w9968cf_read_sb(struct w9968cf_device* cam)
1137 v = w9968cf_read_reg(cam, 0x01);
1138 udelay(W9968CF_I2C_BUS_DELAY);
1144 /*--------------------------------------------------------------------------
1145 Upload quantization tables for the JPEG compression.
1146 This function is called by w9968cf_start_transfer().
1147 Return 0 on success, a negative number otherwise.
1148 --------------------------------------------------------------------------*/
1149 static int w9968cf_upload_quantizationtables(struct w9968cf_device* cam)
1154 err += w9968cf_write_reg(cam, 0x0010, 0x39); /* JPEG clock enable */
1156 for (i = 0, j = 0; i < 32; i++, j += 2) {
1157 a = Y_QUANTABLE[j] | ((unsigned)(Y_QUANTABLE[j+1]) << 8);
1158 b = UV_QUANTABLE[j] | ((unsigned)(UV_QUANTABLE[j+1]) << 8);
1159 err += w9968cf_write_reg(cam, a, 0x40+i);
1160 err += w9968cf_write_reg(cam, b, 0x60+i);
1162 err += w9968cf_write_reg(cam, 0x0012, 0x39); /* JPEG encoder enable */
1169 /****************************************************************************
1170 * Low-level I2C I/O functions. *
1171 * The adapter supports the following I2C transfer functions: *
1172 * i2c_adap_fastwrite_byte_data() (at 400 kHz bit frequency only) *
1173 * i2c_adap_read_byte_data() *
1174 * i2c_adap_read_byte() *
1175 ****************************************************************************/
1177 static int w9968cf_smbus_start(struct w9968cf_device* cam)
1181 err += w9968cf_write_sb(cam, 0x0011); /* SDE=1, SDA=0, SCL=1 */
1182 err += w9968cf_write_sb(cam, 0x0010); /* SDE=1, SDA=0, SCL=0 */
1188 static int w9968cf_smbus_stop(struct w9968cf_device* cam)
1192 err += w9968cf_write_sb(cam, 0x0011); /* SDE=1, SDA=0, SCL=1 */
1193 err += w9968cf_write_sb(cam, 0x0013); /* SDE=1, SDA=1, SCL=1 */
1199 static int w9968cf_smbus_write_byte(struct w9968cf_device* cam, u8 v)
1204 for (bit = 0 ; bit < 8 ; bit++) {
1205 sda = (v & 0x80) ? 2 : 0;
1207 /* SDE=1, SDA=sda, SCL=0 */
1208 err += w9968cf_write_sb(cam, 0x10 | sda);
1209 /* SDE=1, SDA=sda, SCL=1 */
1210 err += w9968cf_write_sb(cam, 0x11 | sda);
1211 /* SDE=1, SDA=sda, SCL=0 */
1212 err += w9968cf_write_sb(cam, 0x10 | sda);
1219 static int w9968cf_smbus_read_byte(struct w9968cf_device* cam, u8* v)
1225 for (bit = 0 ; bit < 8 ; bit++) {
1227 err += w9968cf_write_sb(cam, 0x0013);
1228 *v |= (w9968cf_read_sb(cam) & 0x0008) ? 1 : 0;
1229 err += w9968cf_write_sb(cam, 0x0012);
1236 static int w9968cf_smbus_write_ack(struct w9968cf_device* cam)
1240 err += w9968cf_write_sb(cam, 0x0010); /* SDE=1, SDA=0, SCL=0 */
1241 err += w9968cf_write_sb(cam, 0x0011); /* SDE=1, SDA=0, SCL=1 */
1242 err += w9968cf_write_sb(cam, 0x0010); /* SDE=1, SDA=0, SCL=0 */
1248 static int w9968cf_smbus_read_ack(struct w9968cf_device* cam)
1252 err += w9968cf_write_sb(cam, 0x0013); /* SDE=1, SDA=1, SCL=1 */
1253 sda = (w9968cf_read_sb(cam) & 0x08) ? 1 : 0; /* sda = SDA */
1254 err += w9968cf_write_sb(cam, 0x0012); /* SDE=1, SDA=1, SCL=0 */
1258 DBG(6, "Couldn't receive the ACK")
1266 /* This seems to refresh the communication through the serial bus */
1267 static int w9968cf_smbus_refresh_bus(struct w9968cf_device* cam)
1271 for (j = 1; j <= 10; j++) {
1272 err = w9968cf_write_reg(cam, 0x0020, 0x01);
1273 err += w9968cf_write_reg(cam, 0x0000, 0x01);
1282 /* SMBus protocol: S Addr Wr [A] Subaddr [A] Value [A] P */
1284 w9968cf_i2c_adap_fastwrite_byte_data(struct w9968cf_device* cam,
1285 u16 address, u8 subaddress,u8 value)
1287 u16* data = cam->data_buffer;
1290 err += w9968cf_smbus_refresh_bus(cam);
1292 /* Enable SBUS outputs */
1293 err += w9968cf_write_sb(cam, 0x0020);
1295 data[0] = 0x082f | ((address & 0x80) ? 0x1500 : 0x0);
1296 data[0] |= (address & 0x40) ? 0x4000 : 0x0;
1297 data[1] = 0x2082 | ((address & 0x40) ? 0x0005 : 0x0);
1298 data[1] |= (address & 0x20) ? 0x0150 : 0x0;
1299 data[1] |= (address & 0x10) ? 0x5400 : 0x0;
1300 data[2] = 0x8208 | ((address & 0x08) ? 0x0015 : 0x0);
1301 data[2] |= (address & 0x04) ? 0x0540 : 0x0;
1302 data[2] |= (address & 0x02) ? 0x5000 : 0x0;
1303 data[3] = 0x1d20 | ((address & 0x02) ? 0x0001 : 0x0);
1304 data[3] |= (address & 0x01) ? 0x0054 : 0x0;
1306 err += w9968cf_write_fsb(cam, data);
1308 data[0] = 0x8208 | ((subaddress & 0x80) ? 0x0015 : 0x0);
1309 data[0] |= (subaddress & 0x40) ? 0x0540 : 0x0;
1310 data[0] |= (subaddress & 0x20) ? 0x5000 : 0x0;
1311 data[1] = 0x0820 | ((subaddress & 0x20) ? 0x0001 : 0x0);
1312 data[1] |= (subaddress & 0x10) ? 0x0054 : 0x0;
1313 data[1] |= (subaddress & 0x08) ? 0x1500 : 0x0;
1314 data[1] |= (subaddress & 0x04) ? 0x4000 : 0x0;
1315 data[2] = 0x2082 | ((subaddress & 0x04) ? 0x0005 : 0x0);
1316 data[2] |= (subaddress & 0x02) ? 0x0150 : 0x0;
1317 data[2] |= (subaddress & 0x01) ? 0x5400 : 0x0;
1320 err += w9968cf_write_fsb(cam, data);
1322 data[0] = 0x8208 | ((value & 0x80) ? 0x0015 : 0x0);
1323 data[0] |= (value & 0x40) ? 0x0540 : 0x0;
1324 data[0] |= (value & 0x20) ? 0x5000 : 0x0;
1325 data[1] = 0x0820 | ((value & 0x20) ? 0x0001 : 0x0);
1326 data[1] |= (value & 0x10) ? 0x0054 : 0x0;
1327 data[1] |= (value & 0x08) ? 0x1500 : 0x0;
1328 data[1] |= (value & 0x04) ? 0x4000 : 0x0;
1329 data[2] = 0x2082 | ((value & 0x04) ? 0x0005 : 0x0);
1330 data[2] |= (value & 0x02) ? 0x0150 : 0x0;
1331 data[2] |= (value & 0x01) ? 0x5400 : 0x0;
1334 err += w9968cf_write_fsb(cam, data);
1336 /* Disable SBUS outputs */
1337 err += w9968cf_write_sb(cam, 0x0000);
1340 DBG(5, "I2C write byte data done, addr.0x%04X, subaddr.0x%02X "
1341 "value 0x%02X", address, subaddress, value)
1343 DBG(5, "I2C write byte data failed, addr.0x%04X, "
1344 "subaddr.0x%02X, value 0x%02X",
1345 address, subaddress, value)
1351 /* SMBus protocol: S Addr Wr [A] Subaddr [A] P S Addr+1 Rd [A] [Value] NA P */
1353 w9968cf_i2c_adap_read_byte_data(struct w9968cf_device* cam,
1354 u16 address, u8 subaddress,
1359 /* Serial data enable */
1360 err += w9968cf_write_sb(cam, 0x0013); /* don't change ! */
1362 err += w9968cf_smbus_start(cam);
1363 err += w9968cf_smbus_write_byte(cam, address);
1364 err += w9968cf_smbus_read_ack(cam);
1365 err += w9968cf_smbus_write_byte(cam, subaddress);
1366 err += w9968cf_smbus_read_ack(cam);
1367 err += w9968cf_smbus_stop(cam);
1368 err += w9968cf_smbus_start(cam);
1369 err += w9968cf_smbus_write_byte(cam, address + 1);
1370 err += w9968cf_smbus_read_ack(cam);
1371 err += w9968cf_smbus_read_byte(cam, value);
1372 err += w9968cf_smbus_write_ack(cam);
1373 err += w9968cf_smbus_stop(cam);
1375 /* Serial data disable */
1376 err += w9968cf_write_sb(cam, 0x0000);
1379 DBG(5, "I2C read byte data done, addr.0x%04X, "
1380 "subaddr.0x%02X, value 0x%02X",
1381 address, subaddress, *value)
1383 DBG(5, "I2C read byte data failed, addr.0x%04X, "
1384 "subaddr.0x%02X, wrong value 0x%02X",
1385 address, subaddress, *value)
1391 /* SMBus protocol: S Addr+1 Rd [A] [Value] NA P */
1393 w9968cf_i2c_adap_read_byte(struct w9968cf_device* cam,
1394 u16 address, u8* value)
1398 /* Serial data enable */
1399 err += w9968cf_write_sb(cam, 0x0013);
1401 err += w9968cf_smbus_start(cam);
1402 err += w9968cf_smbus_write_byte(cam, address + 1);
1403 err += w9968cf_smbus_read_ack(cam);
1404 err += w9968cf_smbus_read_byte(cam, value);
1405 err += w9968cf_smbus_write_ack(cam);
1406 err += w9968cf_smbus_stop(cam);
1408 /* Serial data disable */
1409 err += w9968cf_write_sb(cam, 0x0000);
1412 DBG(5, "I2C read byte done, addr.0x%04X, "
1413 "value 0x%02X", address, *value)
1415 DBG(5, "I2C read byte failed, addr.0x%04X, "
1416 "wrong value 0x%02X", address, *value)
1422 /* SMBus protocol: S Addr Wr [A] Value [A] P */
1424 w9968cf_i2c_adap_write_byte(struct w9968cf_device* cam,
1425 u16 address, u8 value)
1427 DBG(4, "i2c_write_byte() is an unsupported transfer mode")
1433 /****************************************************************************
1434 * I2C interface to kernel *
1435 ****************************************************************************/
1438 w9968cf_i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr,
1439 unsigned short flags, char read_write, u8 command,
1440 int size, union i2c_smbus_data *data)
1442 struct w9968cf_device* cam = i2c_get_adapdata(adapter);
1451 DBG(4, "Rejected slave ID 0x%04X", addr)
1455 if (size == I2C_SMBUS_BYTE) {
1456 /* Why addr <<= 1? See OVXXX0_SID defines in ovcamchip.h */
1459 if (read_write == I2C_SMBUS_WRITE)
1460 err = w9968cf_i2c_adap_write_byte(cam, addr, command);
1461 else if (read_write == I2C_SMBUS_READ)
1462 err = w9968cf_i2c_adap_read_byte(cam,addr,&data->byte);
1464 } else if (size == I2C_SMBUS_BYTE_DATA) {
1467 if (read_write == I2C_SMBUS_WRITE)
1468 err = w9968cf_i2c_adap_fastwrite_byte_data(cam, addr,
1469 command, data->byte);
1470 else if (read_write == I2C_SMBUS_READ) {
1471 for (i = 1; i <= W9968CF_I2C_RW_RETRIES; i++) {
1472 err = w9968cf_i2c_adap_read_byte_data(cam,addr,
1473 command, &data->byte);
1475 if (w9968cf_smbus_refresh_bus(cam)) {
1487 DBG(4, "Unsupported I2C transfer mode (%d)", size)
1495 static u32 w9968cf_i2c_func(struct i2c_adapter* adap)
1497 return I2C_FUNC_SMBUS_READ_BYTE |
1498 I2C_FUNC_SMBUS_READ_BYTE_DATA |
1499 I2C_FUNC_SMBUS_WRITE_BYTE_DATA;
1503 static int w9968cf_i2c_attach_inform(struct i2c_client* client)
1505 struct w9968cf_device* cam = i2c_get_adapdata(client->adapter);
1506 int id = client->driver->id, err = 0;
1508 if (id == I2C_DRIVERID_OVCAMCHIP) {
1509 cam->sensor_client = client;
1510 err = w9968cf_sensor_init(cam);
1512 cam->sensor_client = NULL;
1516 DBG(4, "Rejected client [%s] with driver [%s]",
1517 client->name, client->driver->driver.name)
1521 DBG(5, "I2C attach client [%s] with driver [%s]",
1522 client->name, client->driver->driver.name)
1528 static int w9968cf_i2c_detach_inform(struct i2c_client* client)
1530 struct w9968cf_device* cam = i2c_get_adapdata(client->adapter);
1532 if (cam->sensor_client == client)
1533 cam->sensor_client = NULL;
1535 DBG(5, "I2C detach client [%s]", client->name)
1542 w9968cf_i2c_control(struct i2c_adapter* adapter, unsigned int cmd,
1549 static int w9968cf_i2c_init(struct w9968cf_device* cam)
1553 static struct i2c_algorithm algo = {
1554 .smbus_xfer = w9968cf_i2c_smbus_xfer,
1555 .algo_control = w9968cf_i2c_control,
1556 .functionality = w9968cf_i2c_func,
1559 static struct i2c_adapter adap = {
1560 .id = I2C_HW_SMBUS_W9968CF,
1561 .class = I2C_CLASS_CAM_DIGITAL,
1562 .owner = THIS_MODULE,
1563 .client_register = w9968cf_i2c_attach_inform,
1564 .client_unregister = w9968cf_i2c_detach_inform,
1568 memcpy(&cam->i2c_adapter, &adap, sizeof(struct i2c_adapter));
1569 strcpy(cam->i2c_adapter.name, "w9968cf");
1570 i2c_set_adapdata(&cam->i2c_adapter, cam);
1572 DBG(6, "Registering I2C adapter with kernel...")
1574 err = i2c_add_adapter(&cam->i2c_adapter);
1576 DBG(1, "Failed to register the I2C adapter")
1578 DBG(5, "I2C adapter registered")
1585 /****************************************************************************
1586 * Helper functions *
1587 ****************************************************************************/
1589 /*--------------------------------------------------------------------------
1590 Turn on the LED on some webcams. A beep should be heard too.
1591 Return 0 on success, a negative number otherwise.
1592 --------------------------------------------------------------------------*/
1593 static int w9968cf_turn_on_led(struct w9968cf_device* cam)
1597 err += w9968cf_write_reg(cam, 0xff00, 0x00); /* power-down */
1598 err += w9968cf_write_reg(cam, 0xbf17, 0x00); /* reset everything */
1599 err += w9968cf_write_reg(cam, 0xbf10, 0x00); /* normal operation */
1600 err += w9968cf_write_reg(cam, 0x0010, 0x01); /* serial bus, SDS high */
1601 err += w9968cf_write_reg(cam, 0x0000, 0x01); /* serial bus, SDS low */
1602 err += w9968cf_write_reg(cam, 0x0010, 0x01); /* ..high 'beep-beep' */
1605 DBG(2, "Couldn't turn on the LED")
1607 DBG(5, "LED turned on")
1613 /*--------------------------------------------------------------------------
1614 Write some registers for the device initialization.
1615 This function is called once on open().
1616 Return 0 on success, a negative number otherwise.
1617 --------------------------------------------------------------------------*/
1618 static int w9968cf_init_chip(struct w9968cf_device* cam)
1620 unsigned long hw_bufsize = cam->maxwidth*cam->maxheight*2,
1622 u0 = y0 + hw_bufsize/2,
1623 v0 = u0 + hw_bufsize/4,
1624 y1 = v0 + hw_bufsize/4,
1625 u1 = y1 + hw_bufsize/2,
1626 v1 = u1 + hw_bufsize/4;
1629 err += w9968cf_write_reg(cam, 0xff00, 0x00); /* power off */
1630 err += w9968cf_write_reg(cam, 0xbf10, 0x00); /* power on */
1632 err += w9968cf_write_reg(cam, 0x405d, 0x03); /* DRAM timings */
1633 err += w9968cf_write_reg(cam, 0x0030, 0x04); /* SDRAM timings */
1635 err += w9968cf_write_reg(cam, y0 & 0xffff, 0x20); /* Y buf.0, low */
1636 err += w9968cf_write_reg(cam, y0 >> 16, 0x21); /* Y buf.0, high */
1637 err += w9968cf_write_reg(cam, u0 & 0xffff, 0x24); /* U buf.0, low */
1638 err += w9968cf_write_reg(cam, u0 >> 16, 0x25); /* U buf.0, high */
1639 err += w9968cf_write_reg(cam, v0 & 0xffff, 0x28); /* V buf.0, low */
1640 err += w9968cf_write_reg(cam, v0 >> 16, 0x29); /* V buf.0, high */
1642 err += w9968cf_write_reg(cam, y1 & 0xffff, 0x22); /* Y buf.1, low */
1643 err += w9968cf_write_reg(cam, y1 >> 16, 0x23); /* Y buf.1, high */
1644 err += w9968cf_write_reg(cam, u1 & 0xffff, 0x26); /* U buf.1, low */
1645 err += w9968cf_write_reg(cam, u1 >> 16, 0x27); /* U buf.1, high */
1646 err += w9968cf_write_reg(cam, v1 & 0xffff, 0x2a); /* V buf.1, low */
1647 err += w9968cf_write_reg(cam, v1 >> 16, 0x2b); /* V buf.1, high */
1649 err += w9968cf_write_reg(cam, y1 & 0xffff, 0x32); /* JPEG buf 0 low */
1650 err += w9968cf_write_reg(cam, y1 >> 16, 0x33); /* JPEG buf 0 high */
1652 err += w9968cf_write_reg(cam, y1 & 0xffff, 0x34); /* JPEG buf 1 low */
1653 err += w9968cf_write_reg(cam, y1 >> 16, 0x35); /* JPEG bug 1 high */
1655 err += w9968cf_write_reg(cam, 0x0000, 0x36);/* JPEG restart interval */
1656 err += w9968cf_write_reg(cam, 0x0804, 0x37);/*JPEG VLE FIFO threshold*/
1657 err += w9968cf_write_reg(cam, 0x0000, 0x38);/* disable hw up-scaling */
1658 err += w9968cf_write_reg(cam, 0x0000, 0x3f); /* JPEG/MCTL test data */
1660 err += w9968cf_set_picture(cam, cam->picture); /* this before */
1661 err += w9968cf_set_window(cam, cam->window);
1664 DBG(1, "Chip initialization failed")
1666 DBG(5, "Chip successfully initialized")
1672 /*--------------------------------------------------------------------------
1673 Return non-zero if the palette is supported, 0 otherwise.
1674 --------------------------------------------------------------------------*/
1675 static inline u16 w9968cf_valid_palette(u16 palette)
1678 while (w9968cf_formatlist[i].palette != 0) {
1679 if (palette == w9968cf_formatlist[i].palette)
1687 /*--------------------------------------------------------------------------
1688 Return the depth corresponding to the given palette.
1689 Palette _must_ be supported !
1690 --------------------------------------------------------------------------*/
1691 static inline u16 w9968cf_valid_depth(u16 palette)
1694 while (w9968cf_formatlist[i].palette != palette)
1697 return w9968cf_formatlist[i].depth;
1701 /*--------------------------------------------------------------------------
1702 Return non-zero if the format requires decompression, 0 otherwise.
1703 --------------------------------------------------------------------------*/
1704 static inline u8 w9968cf_need_decompression(u16 palette)
1707 while (w9968cf_formatlist[i].palette != 0) {
1708 if (palette == w9968cf_formatlist[i].palette)
1709 return w9968cf_formatlist[i].compression;
1716 /*--------------------------------------------------------------------------
1717 Change the picture settings of the camera.
1718 Return 0 on success, a negative number otherwise.
1719 --------------------------------------------------------------------------*/
1721 w9968cf_set_picture(struct w9968cf_device* cam, struct video_picture pict)
1723 u16 fmt, hw_depth, hw_palette, reg_v = 0x0000;
1726 /* Make sure we are using a valid depth */
1727 pict.depth = w9968cf_valid_depth(pict.palette);
1731 hw_depth = pict.depth; /* depth used by the winbond chip */
1732 hw_palette = pict.palette; /* palette used by the winbond chip */
1734 /* VS & HS polarities */
1735 reg_v = (cam->vs_polarity << 12) | (cam->hs_polarity << 11);
1739 case VIDEO_PALETTE_UYVY:
1741 cam->vpp_flag = VPP_NONE;
1743 case VIDEO_PALETTE_YUV422P:
1745 cam->vpp_flag = VPP_DECOMPRESSION;
1747 case VIDEO_PALETTE_YUV420:
1748 case VIDEO_PALETTE_YUV420P:
1750 cam->vpp_flag = VPP_DECOMPRESSION;
1752 case VIDEO_PALETTE_YUYV:
1753 case VIDEO_PALETTE_YUV422:
1755 cam->vpp_flag = VPP_SWAP_YUV_BYTES;
1756 hw_palette = VIDEO_PALETTE_UYVY;
1758 /* Original video is used instead of RGBX palettes.
1759 Software conversion later. */
1760 case VIDEO_PALETTE_GREY:
1761 case VIDEO_PALETTE_RGB555:
1762 case VIDEO_PALETTE_RGB565:
1763 case VIDEO_PALETTE_RGB24:
1764 case VIDEO_PALETTE_RGB32:
1765 reg_v |= 0x0000; /* UYVY 16 bit is used */
1767 hw_palette = VIDEO_PALETTE_UYVY;
1768 cam->vpp_flag = VPP_UYVY_TO_RGBX;
1772 /* NOTE: due to memory issues, it is better to disable the hardware
1773 double buffering during compression */
1774 if (cam->double_buffer && !(cam->vpp_flag & VPP_DECOMPRESSION))
1780 if (cam->filter_type == 1)
1782 else if (cam->filter_type == 2)
1785 if ((err = w9968cf_write_reg(cam, reg_v, 0x16)))
1788 if ((err = w9968cf_sensor_update_picture(cam, pict)))
1791 /* If all went well, update the device data structure */
1792 memcpy(&cam->picture, &pict, sizeof(pict));
1793 cam->hw_depth = hw_depth;
1794 cam->hw_palette = hw_palette;
1796 /* Settings changed, so we clear the frame buffers */
1797 memset(cam->frame[0].buffer, 0, cam->nbuffers*cam->frame[0].size);
1799 DBG(4, "Palette is %s, depth is %u bpp",
1800 symbolic(v4l1_plist, pict.palette), pict.depth)
1805 DBG(1, "Failed to change picture settings")
1810 /*--------------------------------------------------------------------------
1811 Change the capture area size of the camera.
1812 This function _must_ be called _after_ w9968cf_set_picture().
1813 Return 0 on success, a negative number otherwise.
1814 --------------------------------------------------------------------------*/
1816 w9968cf_set_window(struct w9968cf_device* cam, struct video_window win)
1818 u16 x, y, w, h, scx, scy, cw, ch, ax, ay;
1819 unsigned long fw, fh;
1820 struct ovcamchip_window s_win;
1823 /* Work around to avoid FP arithmetics */
1824 #define __SC(x) ((x) << 10)
1825 #define __UNSC(x) ((x) >> 10)
1827 /* Make sure we are using a supported resolution */
1828 if ((err = w9968cf_adjust_window_size(cam, (u16*)&win.width,
1829 (u16*)&win.height)))
1832 /* Scaling factors */
1833 fw = __SC(win.width) / cam->maxwidth;
1834 fh = __SC(win.height) / cam->maxheight;
1836 /* Set up the width and height values used by the chip */
1837 if ((win.width > cam->maxwidth) || (win.height > cam->maxheight)) {
1838 cam->vpp_flag |= VPP_UPSCALE;
1839 /* Calculate largest w,h mantaining the same w/h ratio */
1840 w = (fw >= fh) ? cam->maxwidth : __SC(win.width)/fh;
1841 h = (fw >= fh) ? __SC(win.height)/fw : cam->maxheight;
1842 if (w < cam->minwidth) /* just in case */
1844 if (h < cam->minheight) /* just in case */
1847 cam->vpp_flag &= ~VPP_UPSCALE;
1852 /* x,y offsets of the cropped area */
1853 scx = cam->start_cropx;
1854 scy = cam->start_cropy;
1856 /* Calculate cropped area manteining the right w/h ratio */
1857 if (cam->largeview && !(cam->vpp_flag & VPP_UPSCALE)) {
1858 cw = (fw >= fh) ? cam->maxwidth : __SC(win.width)/fh;
1859 ch = (fw >= fh) ? __SC(win.height)/fw : cam->maxheight;
1865 /* Setup the window of the sensor */
1866 s_win.format = VIDEO_PALETTE_UYVY;
1867 s_win.width = cam->maxwidth;
1868 s_win.height = cam->maxheight;
1869 s_win.quarter = 0; /* full progressive video */
1872 s_win.x = (s_win.width - cw) / 2;
1873 s_win.y = (s_win.height - ch) / 2;
1876 if (cam->clockdiv >= 0)
1877 s_win.clockdiv = cam->clockdiv; /* manual override */
1879 switch (cam->sensor) {
1892 s_win.clockdiv = W9968CF_DEF_CLOCKDIVISOR;
1895 /* We have to scale win.x and win.y offsets */
1896 if ( (cam->largeview && !(cam->vpp_flag & VPP_UPSCALE))
1897 || (cam->vpp_flag & VPP_UPSCALE) ) {
1898 ax = __SC(win.x)/fw;
1899 ay = __SC(win.y)/fh;
1905 if ((ax + cw) > cam->maxwidth)
1906 ax = cam->maxwidth - cw;
1908 if ((ay + ch) > cam->maxheight)
1909 ay = cam->maxheight - ch;
1911 /* Adjust win.x, win.y */
1912 if ( (cam->largeview && !(cam->vpp_flag & VPP_UPSCALE))
1913 || (cam->vpp_flag & VPP_UPSCALE) ) {
1914 win.x = __UNSC(ax*fw);
1915 win.y = __UNSC(ay*fh);
1921 /* Offsets used by the chip */
1926 if ((err = w9968cf_sensor_cmd(cam, OVCAMCHIP_CMD_S_MODE, &s_win)))
1929 err += w9968cf_write_reg(cam, scx + x, 0x10);
1930 err += w9968cf_write_reg(cam, scy + y, 0x11);
1931 err += w9968cf_write_reg(cam, scx + x + cw, 0x12);
1932 err += w9968cf_write_reg(cam, scy + y + ch, 0x13);
1933 err += w9968cf_write_reg(cam, w, 0x14);
1934 err += w9968cf_write_reg(cam, h, 0x15);
1936 /* JPEG width & height */
1937 err += w9968cf_write_reg(cam, w, 0x30);
1938 err += w9968cf_write_reg(cam, h, 0x31);
1940 /* Y & UV frame buffer strides (in WORD) */
1941 if (cam->vpp_flag & VPP_DECOMPRESSION) {
1942 err += w9968cf_write_reg(cam, w/2, 0x2c);
1943 err += w9968cf_write_reg(cam, w/4, 0x2d);
1945 err += w9968cf_write_reg(cam, w, 0x2c);
1950 /* If all went well, update the device data structure */
1951 memcpy(&cam->window, &win, sizeof(win));
1955 /* Settings changed, so we clear the frame buffers */
1956 memset(cam->frame[0].buffer, 0, cam->nbuffers*cam->frame[0].size);
1958 DBG(4, "The capture area is %dx%d, Offset (x,y)=(%u,%u)",
1959 win.width, win.height, win.x, win.y)
1961 PDBGG("x=%u ,y=%u, w=%u, h=%u, ax=%u, ay=%u, s_win.x=%u, s_win.y=%u, "
1962 "cw=%u, ch=%u, win.x=%u, win.y=%u, win.width=%u, win.height=%u",
1963 x, y, w, h, ax, ay, s_win.x, s_win.y, cw, ch, win.x, win.y,
1964 win.width, win.height)
1969 DBG(1, "Failed to change the capture area size")
1974 /*--------------------------------------------------------------------------
1975 Adjust the asked values for window width and height.
1976 Return 0 on success, -1 otherwise.
1977 --------------------------------------------------------------------------*/
1979 w9968cf_adjust_window_size(struct w9968cf_device* cam, u16* width, u16* height)
1983 if ((*width < cam->minwidth) || (*height < cam->minheight))
1986 maxw = cam->upscaling && !(cam->vpp_flag & VPP_DECOMPRESSION) &&
1987 w9968cf_vpp ? max((u16)W9968CF_MAX_WIDTH, cam->maxwidth)
1989 maxh = cam->upscaling && !(cam->vpp_flag & VPP_DECOMPRESSION) &&
1990 w9968cf_vpp ? max((u16)W9968CF_MAX_HEIGHT, cam->maxheight)
1998 if (cam->vpp_flag & VPP_DECOMPRESSION) {
1999 *width &= ~15L; /* multiple of 16 */
2003 PDBGG("Window size adjusted w=%u, h=%u ", *width, *height)
2009 /*--------------------------------------------------------------------------
2010 Initialize the FIFO list of requested frames.
2011 --------------------------------------------------------------------------*/
2012 static void w9968cf_init_framelist(struct w9968cf_device* cam)
2016 for (i = 0; i < cam->nbuffers; i++) {
2017 cam->requested_frame[i] = NULL;
2018 cam->frame[i].queued = 0;
2019 cam->frame[i].status = F_UNUSED;
2024 /*--------------------------------------------------------------------------
2025 Add a frame in the FIFO list of requested frames.
2026 This function is called in process context.
2027 --------------------------------------------------------------------------*/
2028 static void w9968cf_push_frame(struct w9968cf_device* cam, u8 f_num)
2031 unsigned long lock_flags;
2033 spin_lock_irqsave(&cam->flist_lock, lock_flags);
2035 for (f=0; cam->requested_frame[f] != NULL; f++);
2036 cam->requested_frame[f] = &cam->frame[f_num];
2037 cam->frame[f_num].queued = 1;
2038 cam->frame[f_num].status = F_UNUSED; /* clear the status */
2040 spin_unlock_irqrestore(&cam->flist_lock, lock_flags);
2042 DBG(6, "Frame #%u pushed into the FIFO list. Position %u", f_num, f)
2046 /*--------------------------------------------------------------------------
2047 Read, store and remove the first pointer in the FIFO list of requested
2048 frames. This function is called in interrupt context.
2049 --------------------------------------------------------------------------*/
2051 w9968cf_pop_frame(struct w9968cf_device* cam, struct w9968cf_frame_t** framep)
2055 spin_lock(&cam->flist_lock);
2057 *framep = cam->requested_frame[0];
2059 /* Shift the list of pointers */
2060 for (i = 0; i < cam->nbuffers-1; i++)
2061 cam->requested_frame[i] = cam->requested_frame[i+1];
2062 cam->requested_frame[i] = NULL;
2064 spin_unlock(&cam->flist_lock);
2066 DBG(6,"Popped frame #%d from the list", (*framep)->number)
2070 /*--------------------------------------------------------------------------
2071 High-level video post-processing routine on grabbed frames.
2072 Return 0 on success, a negative number otherwise.
2073 --------------------------------------------------------------------------*/
2075 w9968cf_postprocess_frame(struct w9968cf_device* cam,
2076 struct w9968cf_frame_t* fr)
2078 void *pIn = fr->buffer, *pOut = cam->frame_vpp.buffer, *tmp;
2079 u16 w = cam->window.width,
2080 h = cam->window.height,
2081 d = cam->picture.depth,
2082 fmt = cam->picture.palette,
2083 rgb = cam->force_rgb,
2084 hw_w = cam->hw_width,
2085 hw_h = cam->hw_height,
2086 hw_d = cam->hw_depth;
2089 #define _PSWAP(pIn, pOut) {tmp = (pIn); (pIn) = (pOut); (pOut) = tmp;}
2091 if (cam->vpp_flag & VPP_DECOMPRESSION) {
2092 memcpy(pOut, pIn, fr->length);
2094 err = w9968cf_vpp->decode(pIn, fr->length, hw_w, hw_h, pOut);
2095 PDBGG("Compressed frame length: %lu",(unsigned long)fr->length)
2096 fr->length = (hw_w*hw_h*hw_d)/8;
2099 DBG(4, "An error occurred while decoding the frame: "
2100 "%s", symbolic(decoder_errlist, err))
2103 DBG(6, "Frame decoded")
2106 if (cam->vpp_flag & VPP_SWAP_YUV_BYTES) {
2107 w9968cf_vpp->swap_yuvbytes(pIn, fr->length);
2108 DBG(6, "Original UYVY component ordering changed")
2111 if (cam->vpp_flag & VPP_UPSCALE) {
2112 w9968cf_vpp->scale_up(pIn, pOut, hw_w, hw_h, hw_d, w, h);
2113 fr->length = (w*h*hw_d)/8;
2115 DBG(6, "Vertical up-scaling done: %u,%u,%ubpp->%u,%u",
2116 hw_w, hw_h, hw_d, w, h)
2119 if (cam->vpp_flag & VPP_UYVY_TO_RGBX) {
2120 w9968cf_vpp->uyvy_to_rgbx(pIn, fr->length, pOut, fmt, rgb);
2121 fr->length = (w*h*d)/8;
2123 DBG(6, "UYVY-16bit to %s conversion done",
2124 symbolic(v4l1_plist, fmt))
2127 if (pOut == fr->buffer)
2128 memcpy(fr->buffer, cam->frame_vpp.buffer, fr->length);
2135 /****************************************************************************
2136 * Image sensor control routines *
2137 ****************************************************************************/
2140 w9968cf_sensor_set_control(struct w9968cf_device* cam, int cid, int val)
2142 struct ovcamchip_control ctl;
2148 err = w9968cf_sensor_cmd(cam, OVCAMCHIP_CMD_S_CTRL, &ctl);
2155 w9968cf_sensor_get_control(struct w9968cf_device* cam, int cid, int* val)
2157 struct ovcamchip_control ctl;
2162 err = w9968cf_sensor_cmd(cam, OVCAMCHIP_CMD_G_CTRL, &ctl);
2171 w9968cf_sensor_cmd(struct w9968cf_device* cam, unsigned int cmd, void* arg)
2173 struct i2c_client* c = cam->sensor_client;
2176 if (!c || !c->driver || !c->driver->command)
2179 rc = c->driver->command(c, cmd, arg);
2180 /* The I2C driver returns -EPERM on non-supported controls */
2181 return (rc < 0 && rc != -EPERM) ? rc : 0;
2185 /*--------------------------------------------------------------------------
2186 Update some settings of the image sensor.
2187 Returns: 0 on success, a negative number otherwise.
2188 --------------------------------------------------------------------------*/
2189 static int w9968cf_sensor_update_settings(struct w9968cf_device* cam)
2193 /* Auto brightness */
2194 err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_AUTOBRIGHT,
2200 err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_AUTOEXP,
2205 /* Banding filter */
2206 err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_BANDFILT,
2211 /* Light frequency */
2212 err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_FREQ,
2218 err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_BACKLIGHT,
2224 err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_MIRROR,
2233 /*--------------------------------------------------------------------------
2234 Get some current picture settings from the image sensor and update the
2235 internal 'picture' structure of the camera.
2236 Returns: 0 on success, a negative number otherwise.
2237 --------------------------------------------------------------------------*/
2238 static int w9968cf_sensor_get_picture(struct w9968cf_device* cam)
2242 err = w9968cf_sensor_get_control(cam, OVCAMCHIP_CID_CONT, &v);
2245 cam->picture.contrast = v;
2247 err = w9968cf_sensor_get_control(cam, OVCAMCHIP_CID_BRIGHT, &v);
2250 cam->picture.brightness = v;
2252 err = w9968cf_sensor_get_control(cam, OVCAMCHIP_CID_SAT, &v);
2255 cam->picture.colour = v;
2257 err = w9968cf_sensor_get_control(cam, OVCAMCHIP_CID_HUE, &v);
2260 cam->picture.hue = v;
2262 DBG(5, "Got picture settings from the image sensor")
2264 PDBGG("Brightness, contrast, hue, colour, whiteness are "
2265 "%u,%u,%u,%u,%u", cam->picture.brightness,cam->picture.contrast,
2266 cam->picture.hue, cam->picture.colour, cam->picture.whiteness)
2272 /*--------------------------------------------------------------------------
2273 Update picture settings of the image sensor.
2274 Returns: 0 on success, a negative number otherwise.
2275 --------------------------------------------------------------------------*/
2277 w9968cf_sensor_update_picture(struct w9968cf_device* cam,
2278 struct video_picture pict)
2282 if ((!cam->sensor_initialized)
2283 || pict.contrast != cam->picture.contrast) {
2284 err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_CONT,
2288 DBG(4, "Contrast changed from %u to %u",
2289 cam->picture.contrast, pict.contrast)
2290 cam->picture.contrast = pict.contrast;
2293 if (((!cam->sensor_initialized) ||
2294 pict.brightness != cam->picture.brightness) && (!cam->auto_brt)) {
2295 err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_BRIGHT,
2299 DBG(4, "Brightness changed from %u to %u",
2300 cam->picture.brightness, pict.brightness)
2301 cam->picture.brightness = pict.brightness;
2304 if ((!cam->sensor_initialized) || pict.colour != cam->picture.colour) {
2305 err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_SAT,
2309 DBG(4, "Colour changed from %u to %u",
2310 cam->picture.colour, pict.colour)
2311 cam->picture.colour = pict.colour;
2314 if ((!cam->sensor_initialized) || pict.hue != cam->picture.hue) {
2315 err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_HUE,
2319 DBG(4, "Hue changed from %u to %u",
2320 cam->picture.hue, pict.hue)
2321 cam->picture.hue = pict.hue;
2327 DBG(4, "Failed to change sensor picture setting")
2333 /****************************************************************************
2334 * Camera configuration *
2335 ****************************************************************************/
2337 /*--------------------------------------------------------------------------
2338 This function is called when a supported image sensor is detected.
2339 Return 0 if the initialization succeeds, a negative number otherwise.
2340 --------------------------------------------------------------------------*/
2341 static int w9968cf_sensor_init(struct w9968cf_device* cam)
2345 if ((err = w9968cf_sensor_cmd(cam, OVCAMCHIP_CMD_INITIALIZE,
2349 if ((err = w9968cf_sensor_cmd(cam, OVCAMCHIP_CMD_Q_SUBTYPE,
2353 /* NOTE: Make sure width and height are a multiple of 16 */
2354 switch (cam->sensor_client->addr) {
2356 cam->maxwidth = 352;
2357 cam->maxheight = 288;
2359 cam->minheight = 48;
2362 cam->maxwidth = 640;
2363 cam->maxheight = 480;
2365 cam->minheight = 48;
2368 DBG(1, "Not supported image sensor detected for %s",
2369 symbolic(camlist, cam->id))
2373 /* These values depend on the ones in the ovxxx0.c sources */
2374 switch (cam->sensor) {
2376 cam->start_cropx = 287;
2377 cam->start_cropy = 35;
2378 /* Seems to work around a bug in the image sensor */
2379 cam->vs_polarity = 1;
2380 cam->hs_polarity = 1;
2383 cam->start_cropx = 320;
2384 cam->start_cropy = 35;
2385 cam->vs_polarity = 1;
2386 cam->hs_polarity = 0;
2389 if ((err = w9968cf_sensor_update_settings(cam)))
2392 if ((err = w9968cf_sensor_update_picture(cam, cam->picture)))
2395 cam->sensor_initialized = 1;
2397 DBG(2, "%s image sensor initialized", symbolic(senlist, cam->sensor))
2401 cam->sensor_initialized = 0;
2402 cam->sensor = CC_UNKNOWN;
2403 DBG(1, "Image sensor initialization failed for %s (/dev/video%d). "
2404 "Try to detach and attach this device again",
2405 symbolic(camlist, cam->id), cam->v4ldev->minor)
2410 /*--------------------------------------------------------------------------
2411 Fill some basic fields in the main device data structure.
2412 This function is called once on w9968cf_usb_probe() for each recognized
2414 --------------------------------------------------------------------------*/
2416 w9968cf_configure_camera(struct w9968cf_device* cam,
2417 struct usb_device* udev,
2418 enum w9968cf_model_id mod_id,
2419 const unsigned short dev_nr)
2421 init_MUTEX(&cam->fileop_sem);
2422 init_waitqueue_head(&cam->open);
2423 spin_lock_init(&cam->urb_lock);
2424 spin_lock_init(&cam->flist_lock);
2427 cam->disconnected = 0;
2429 cam->sensor = CC_UNKNOWN;
2430 cam->sensor_initialized = 0;
2432 /* Calculate the alternate setting number (from 1 to 16)
2433 according to the 'packet_size' module parameter */
2434 if (packet_size[dev_nr] < W9968CF_MIN_PACKET_SIZE)
2435 packet_size[dev_nr] = W9968CF_MIN_PACKET_SIZE;
2436 for (cam->altsetting = 1;
2437 packet_size[dev_nr] < wMaxPacketSize[cam->altsetting-1];
2440 cam->max_buffers = (max_buffers[dev_nr] < 2 ||
2441 max_buffers[dev_nr] > W9968CF_MAX_BUFFERS)
2442 ? W9968CF_BUFFERS : (u8)max_buffers[dev_nr];
2444 cam->double_buffer = (double_buffer[dev_nr] == 0 ||
2445 double_buffer[dev_nr] == 1)
2446 ? (u8)double_buffer[dev_nr]:W9968CF_DOUBLE_BUFFER;
2448 cam->clamping = (clamping[dev_nr] == 0 || clamping[dev_nr] == 1)
2449 ? (u8)clamping[dev_nr] : W9968CF_CLAMPING;
2451 cam->filter_type = (filter_type[dev_nr] == 0 ||
2452 filter_type[dev_nr] == 1 ||
2453 filter_type[dev_nr] == 2)
2454 ? (u8)filter_type[dev_nr] : W9968CF_FILTER_TYPE;
2458 cam->largeview = (largeview[dev_nr] == 0 || largeview[dev_nr] == 1)
2459 ? (u8)largeview[dev_nr] : W9968CF_LARGEVIEW;
2461 cam->decompression = (decompression[dev_nr] == 0 ||
2462 decompression[dev_nr] == 1 ||
2463 decompression[dev_nr] == 2)
2464 ? (u8)decompression[dev_nr]:W9968CF_DECOMPRESSION;
2466 cam->upscaling = (upscaling[dev_nr] == 0 ||
2467 upscaling[dev_nr] == 1)
2468 ? (u8)upscaling[dev_nr] : W9968CF_UPSCALING;
2470 cam->auto_brt = (autobright[dev_nr] == 0 || autobright[dev_nr] == 1)
2471 ? (u8)autobright[dev_nr] : W9968CF_AUTOBRIGHT;
2473 cam->auto_exp = (autoexp[dev_nr] == 0 || autoexp[dev_nr] == 1)
2474 ? (u8)autoexp[dev_nr] : W9968CF_AUTOEXP;
2476 cam->lightfreq = (lightfreq[dev_nr] == 50 || lightfreq[dev_nr] == 60)
2477 ? (u8)lightfreq[dev_nr] : W9968CF_LIGHTFREQ;
2479 cam->bandfilt = (bandingfilter[dev_nr] == 0 ||
2480 bandingfilter[dev_nr] == 1)
2481 ? (u8)bandingfilter[dev_nr] : W9968CF_BANDINGFILTER;
2483 cam->backlight = (backlight[dev_nr] == 0 || backlight[dev_nr] == 1)
2484 ? (u8)backlight[dev_nr] : W9968CF_BACKLIGHT;
2486 cam->clockdiv = (clockdiv[dev_nr] == -1 || clockdiv[dev_nr] >= 0)
2487 ? (s8)clockdiv[dev_nr] : W9968CF_CLOCKDIV;
2489 cam->mirror = (mirror[dev_nr] == 0 || mirror[dev_nr] == 1)
2490 ? (u8)mirror[dev_nr] : W9968CF_MIRROR;
2492 cam->monochrome = (monochrome[dev_nr] == 0 || monochrome[dev_nr] == 1)
2493 ? monochrome[dev_nr] : W9968CF_MONOCHROME;
2495 cam->picture.brightness = (u16)brightness[dev_nr];
2496 cam->picture.hue = (u16)hue[dev_nr];
2497 cam->picture.colour = (u16)colour[dev_nr];
2498 cam->picture.contrast = (u16)contrast[dev_nr];
2499 cam->picture.whiteness = (u16)whiteness[dev_nr];
2500 if (w9968cf_valid_palette((u16)force_palette[dev_nr])) {
2501 cam->picture.palette = (u16)force_palette[dev_nr];
2502 cam->force_palette = 1;
2504 cam->force_palette = 0;
2505 if (cam->decompression == 0)
2506 cam->picture.palette = W9968CF_PALETTE_DECOMP_OFF;
2507 else if (cam->decompression == 1)
2508 cam->picture.palette = W9968CF_PALETTE_DECOMP_FORCE;
2510 cam->picture.palette = W9968CF_PALETTE_DECOMP_ON;
2512 cam->picture.depth = w9968cf_valid_depth(cam->picture.palette);
2514 cam->force_rgb = (force_rgb[dev_nr] == 0 || force_rgb[dev_nr] == 1)
2515 ? (u8)force_rgb[dev_nr] : W9968CF_FORCE_RGB;
2519 cam->window.width = W9968CF_WIDTH;
2520 cam->window.height = W9968CF_HEIGHT;
2521 cam->window.chromakey = 0;
2522 cam->window.clipcount = 0;
2523 cam->window.flags = 0;
2525 DBG(3, "%s configured with settings #%u:",
2526 symbolic(camlist, cam->id), dev_nr)
2528 DBG(3, "- Data packet size for USB isochrnous transfer: %u bytes",
2529 wMaxPacketSize[cam->altsetting-1])
2531 DBG(3, "- Number of requested video frame buffers: %u",
2534 if (cam->double_buffer)
2535 DBG(3, "- Hardware double buffering enabled")
2537 DBG(3, "- Hardware double buffering disabled")
2539 if (cam->filter_type == 0)
2540 DBG(3, "- Video filtering disabled")
2541 else if (cam->filter_type == 1)
2542 DBG(3, "- Video filtering enabled: type 1-2-1")
2543 else if (cam->filter_type == 2)
2544 DBG(3, "- Video filtering enabled: type 2-3-6-3-2")
2547 DBG(3, "- Video data clamping (CCIR-601 format) enabled")
2549 DBG(3, "- Video data clamping (CCIR-601 format) disabled")
2552 DBG(3, "- Large view enabled")
2554 DBG(3, "- Large view disabled")
2556 if ((cam->decompression) == 0 && (!cam->force_palette))
2557 DBG(3, "- Decompression disabled")
2558 else if ((cam->decompression) == 1 && (!cam->force_palette))
2559 DBG(3, "- Decompression forced")
2560 else if ((cam->decompression) == 2 && (!cam->force_palette))
2561 DBG(3, "- Decompression allowed")
2564 DBG(3, "- Software image scaling enabled")
2566 DBG(3, "- Software image scaling disabled")
2568 if (cam->force_palette)
2569 DBG(3, "- Image palette forced to %s",
2570 symbolic(v4l1_plist, cam->picture.palette))
2573 DBG(3, "- RGB component ordering will be used instead of BGR")
2576 DBG(3, "- Auto brightness enabled")
2578 DBG(3, "- Auto brightness disabled")
2581 DBG(3, "- Auto exposure enabled")
2583 DBG(3, "- Auto exposure disabled")
2586 DBG(3, "- Backlight exposure algorithm enabled")
2588 DBG(3, "- Backlight exposure algorithm disabled")
2591 DBG(3, "- Mirror enabled")
2593 DBG(3, "- Mirror disabled")
2596 DBG(3, "- Banding filter enabled")
2598 DBG(3, "- Banding filter disabled")
2600 DBG(3, "- Power lighting frequency: %u", cam->lightfreq)
2602 if (cam->clockdiv == -1)
2603 DBG(3, "- Automatic clock divisor enabled")
2605 DBG(3, "- Clock divisor: %d", cam->clockdiv)
2607 if (cam->monochrome)
2608 DBG(3, "- Image sensor used as monochrome")
2610 DBG(3, "- Image sensor not used as monochrome")
2614 /*--------------------------------------------------------------------------
2615 If the video post-processing module is not loaded, some parameters
2617 --------------------------------------------------------------------------*/
2618 static void w9968cf_adjust_configuration(struct w9968cf_device* cam)
2621 if (cam->decompression == 1) {
2622 cam->decompression = 2;
2623 DBG(2, "Video post-processing module not found: "
2624 "'decompression' parameter forced to 2")
2626 if (cam->upscaling) {
2628 DBG(2, "Video post-processing module not found: "
2629 "'upscaling' parameter forced to 0")
2631 if (cam->picture.palette != VIDEO_PALETTE_UYVY) {
2632 cam->force_palette = 0;
2633 DBG(2, "Video post-processing module not found: "
2634 "'force_palette' parameter forced to 0")
2636 cam->picture.palette = VIDEO_PALETTE_UYVY;
2637 cam->picture.depth = w9968cf_valid_depth(cam->picture.palette);
2642 /*--------------------------------------------------------------------------
2643 Release the resources used by the driver.
2644 This function is called on disconnect
2645 (or on close if deallocation has been deferred)
2646 --------------------------------------------------------------------------*/
2647 static void w9968cf_release_resources(struct w9968cf_device* cam)
2649 down(&w9968cf_devlist_sem);
2651 DBG(2, "V4L device deregistered: /dev/video%d", cam->v4ldev->minor)
2653 video_unregister_device(cam->v4ldev);
2654 list_del(&cam->v4llist);
2655 i2c_del_adapter(&cam->i2c_adapter);
2656 w9968cf_deallocate_memory(cam);
2657 kfree(cam->control_buffer);
2658 kfree(cam->data_buffer);
2660 up(&w9968cf_devlist_sem);
2665 /****************************************************************************
2666 * Video4Linux interface *
2667 ****************************************************************************/
2669 static int w9968cf_open(struct inode* inode, struct file* filp)
2671 struct w9968cf_device* cam;
2674 /* This the only safe way to prevent race conditions with disconnect */
2675 if (!down_read_trylock(&w9968cf_disconnect))
2676 return -ERESTARTSYS;
2678 cam = (struct w9968cf_device*)video_get_drvdata(video_devdata(filp));
2680 down(&cam->dev_sem);
2682 if (cam->sensor == CC_UNKNOWN) {
2683 DBG(2, "No supported image sensor has been detected by the "
2684 "'ovcamchip' module for the %s (/dev/video%d). Make "
2685 "sure it is loaded *before* (re)connecting the camera.",
2686 symbolic(camlist, cam->id), cam->v4ldev->minor)
2688 up_read(&w9968cf_disconnect);
2693 DBG(2, "%s (/dev/video%d) has been already occupied by '%s'",
2694 symbolic(camlist, cam->id),cam->v4ldev->minor,cam->command)
2695 if ((filp->f_flags & O_NONBLOCK)||(filp->f_flags & O_NDELAY)) {
2697 up_read(&w9968cf_disconnect);
2698 return -EWOULDBLOCK;
2701 err = wait_event_interruptible_exclusive(cam->open,
2702 cam->disconnected ||
2705 up_read(&w9968cf_disconnect);
2708 if (cam->disconnected) {
2709 up_read(&w9968cf_disconnect);
2712 down(&cam->dev_sem);
2715 DBG(5, "Opening '%s', /dev/video%d ...",
2716 symbolic(camlist, cam->id), cam->v4ldev->minor)
2719 cam->misconfigured = 0;
2721 w9968cf_adjust_configuration(cam);
2723 if ((err = w9968cf_allocate_memory(cam)))
2724 goto deallocate_memory;
2726 if ((err = w9968cf_init_chip(cam)))
2727 goto deallocate_memory;
2729 if ((err = w9968cf_start_transfer(cam)))
2730 goto deallocate_memory;
2732 filp->private_data = cam;
2735 strcpy(cam->command, current->comm);
2737 init_waitqueue_head(&cam->wait_queue);
2739 DBG(5, "Video device is open")
2742 up_read(&w9968cf_disconnect);
2747 w9968cf_deallocate_memory(cam);
2748 DBG(2, "Failed to open the video device")
2750 up_read(&w9968cf_disconnect);
2755 static int w9968cf_release(struct inode* inode, struct file* filp)
2757 struct w9968cf_device* cam;
2759 cam = (struct w9968cf_device*)video_get_drvdata(video_devdata(filp));
2761 down(&cam->dev_sem); /* prevent disconnect() to be called */
2763 w9968cf_stop_transfer(cam);
2765 if (cam->disconnected) {
2766 w9968cf_release_resources(cam);
2773 w9968cf_deallocate_memory(cam);
2774 wake_up_interruptible_nr(&cam->open, 1);
2776 DBG(5, "Video device closed")
2783 w9968cf_read(struct file* filp, char __user * buf, size_t count, loff_t* f_pos)
2785 struct w9968cf_device* cam;
2786 struct w9968cf_frame_t* fr;
2789 cam = (struct w9968cf_device*)video_get_drvdata(video_devdata(filp));
2791 if (filp->f_flags & O_NONBLOCK)
2792 return -EWOULDBLOCK;
2794 if (down_interruptible(&cam->fileop_sem))
2795 return -ERESTARTSYS;
2797 if (cam->disconnected) {
2798 DBG(2, "Device not present")
2799 up(&cam->fileop_sem);
2803 if (cam->misconfigured) {
2804 DBG(2, "The camera is misconfigured. Close and open it again.")
2805 up(&cam->fileop_sem);
2809 if (!cam->frame[0].queued)
2810 w9968cf_push_frame(cam, 0);
2812 if (!cam->frame[1].queued)
2813 w9968cf_push_frame(cam, 1);
2815 err = wait_event_interruptible(cam->wait_queue,
2816 cam->frame[0].status == F_READY ||
2817 cam->frame[1].status == F_READY ||
2820 up(&cam->fileop_sem);
2823 if (cam->disconnected) {
2824 up(&cam->fileop_sem);
2828 fr = (cam->frame[0].status == F_READY) ? &cam->frame[0]:&cam->frame[1];
2831 w9968cf_postprocess_frame(cam, fr);
2833 if (count > fr->length)
2836 if (copy_to_user(buf, fr->buffer, count)) {
2837 fr->status = F_UNUSED;
2838 up(&cam->fileop_sem);
2843 fr->status = F_UNUSED;
2845 DBG(5, "%zu bytes read", count)
2847 up(&cam->fileop_sem);
2852 static int w9968cf_mmap(struct file* filp, struct vm_area_struct *vma)
2854 struct w9968cf_device* cam = (struct w9968cf_device*)
2855 video_get_drvdata(video_devdata(filp));
2856 unsigned long vsize = vma->vm_end - vma->vm_start,
2857 psize = cam->nbuffers * cam->frame[0].size,
2858 start = vma->vm_start,
2859 pos = (unsigned long)cam->frame[0].buffer,
2862 if (cam->disconnected) {
2863 DBG(2, "Device not present")
2867 if (cam->misconfigured) {
2868 DBG(2, "The camera is misconfigured. Close and open it again")
2872 PDBGG("mmapping %lu bytes...", vsize)
2874 if (vsize > psize - (vma->vm_pgoff << PAGE_SHIFT))
2878 page = vmalloc_to_pfn((void *)pos);
2879 if (remap_pfn_range(vma, start, page + vma->vm_pgoff,
2880 PAGE_SIZE, vma->vm_page_prot))
2887 DBG(5, "mmap method successfully called")
2893 w9968cf_ioctl(struct inode* inode, struct file* filp,
2894 unsigned int cmd, unsigned long arg)
2896 struct w9968cf_device* cam;
2899 cam = (struct w9968cf_device*)video_get_drvdata(video_devdata(filp));
2901 if (down_interruptible(&cam->fileop_sem))
2902 return -ERESTARTSYS;
2904 if (cam->disconnected) {
2905 DBG(2, "Device not present")
2906 up(&cam->fileop_sem);
2910 if (cam->misconfigured) {
2911 DBG(2, "The camera is misconfigured. Close and open it again.")
2912 up(&cam->fileop_sem);
2916 err = w9968cf_v4l_ioctl(inode, filp, cmd, (void __user *)arg);
2918 up(&cam->fileop_sem);
2923 static int w9968cf_v4l_ioctl(struct inode* inode, struct file* filp,
2924 unsigned int cmd, void __user * arg)
2926 struct w9968cf_device* cam;
2927 const char* v4l1_ioctls[] = {
2928 "?", "CGAP", "GCHAN", "SCHAN", "GTUNER", "STUNER",
2929 "GPICT", "SPICT", "CCAPTURE", "GWIN", "SWIN", "GFBUF",
2930 "SFBUF", "KEY", "GFREQ", "SFREQ", "GAUDIO", "SAUDIO",
2931 "SYNC", "MCAPTURE", "GMBUF", "GUNIT", "GCAPTURE", "SCAPTURE",
2932 "SPLAYMODE", "SWRITEMODE", "GPLAYINFO", "SMICROCODE",
2933 "GVBIFMT", "SVBIFMT"
2936 #define V4L1_IOCTL(cmd) \
2937 ((_IOC_NR((cmd)) < ARRAY_SIZE(v4l1_ioctls)) ? \
2938 v4l1_ioctls[_IOC_NR((cmd))] : "?")
2940 cam = (struct w9968cf_device*)video_get_drvdata(video_devdata(filp));
2944 case VIDIOCGCAP: /* get video capability */
2946 struct video_capability cap = {
2947 .type = VID_TYPE_CAPTURE | VID_TYPE_SCALES,
2950 .minwidth = cam->minwidth,
2951 .minheight = cam->minheight,
2953 sprintf(cap.name, "W996[87]CF USB Camera #%d",
2954 cam->v4ldev->minor);
2955 cap.maxwidth = (cam->upscaling && w9968cf_vpp)
2956 ? max((u16)W9968CF_MAX_WIDTH, cam->maxwidth)
2958 cap.maxheight = (cam->upscaling && w9968cf_vpp)
2959 ? max((u16)W9968CF_MAX_HEIGHT, cam->maxheight)
2962 if (copy_to_user(arg, &cap, sizeof(cap)))
2965 DBG(5, "VIDIOCGCAP successfully called")
2969 case VIDIOCGCHAN: /* get video channel informations */
2971 struct video_channel chan;
2972 if (copy_from_user(&chan, arg, sizeof(chan)))
2975 if (chan.channel != 0)
2978 strcpy(chan.name, "Camera");
2981 chan.type = VIDEO_TYPE_CAMERA;
2982 chan.norm = VIDEO_MODE_AUTO;
2984 if (copy_to_user(arg, &chan, sizeof(chan)))
2987 DBG(5, "VIDIOCGCHAN successfully called")
2991 case VIDIOCSCHAN: /* set active channel */
2993 struct video_channel chan;
2995 if (copy_from_user(&chan, arg, sizeof(chan)))
2998 if (chan.channel != 0)
3001 DBG(5, "VIDIOCSCHAN successfully called")
3005 case VIDIOCGPICT: /* get image properties of the picture */
3007 if (w9968cf_sensor_get_picture(cam))
3010 if (copy_to_user(arg, &cam->picture, sizeof(cam->picture)))
3013 DBG(5, "VIDIOCGPICT successfully called")
3017 case VIDIOCSPICT: /* change picture settings */
3019 struct video_picture pict;
3022 if (copy_from_user(&pict, arg, sizeof(pict)))
3025 if ( (cam->force_palette || !w9968cf_vpp)
3026 && pict.palette != cam->picture.palette ) {
3027 DBG(4, "Palette %s rejected: only %s is allowed",
3028 symbolic(v4l1_plist, pict.palette),
3029 symbolic(v4l1_plist, cam->picture.palette))
3033 if (!w9968cf_valid_palette(pict.palette)) {
3034 DBG(4, "Palette %s not supported. VIDIOCSPICT failed",
3035 symbolic(v4l1_plist, pict.palette))
3039 if (!cam->force_palette) {
3040 if (cam->decompression == 0) {
3041 if (w9968cf_need_decompression(pict.palette)) {
3042 DBG(4, "Decompression disabled: palette %s is not "
3043 "allowed. VIDIOCSPICT failed",
3044 symbolic(v4l1_plist, pict.palette))
3047 } else if (cam->decompression == 1) {
3048 if (!w9968cf_need_decompression(pict.palette)) {
3049 DBG(4, "Decompression forced: palette %s is not "
3050 "allowed. VIDIOCSPICT failed",
3051 symbolic(v4l1_plist, pict.palette))
3057 if (pict.depth != w9968cf_valid_depth(pict.palette)) {
3058 DBG(4, "Requested depth %u bpp is not valid for %s "
3059 "palette: ignored and changed to %u bpp",
3060 pict.depth, symbolic(v4l1_plist, pict.palette),
3061 w9968cf_valid_depth(pict.palette))
3062 pict.depth = w9968cf_valid_depth(pict.palette);
3065 if (pict.palette != cam->picture.palette) {
3066 if(*cam->requested_frame
3067 || cam->frame_current->queued) {
3068 err = wait_event_interruptible
3070 cam->disconnected ||
3071 (!*cam->requested_frame &&
3072 !cam->frame_current->queued) );
3075 if (cam->disconnected)
3079 if (w9968cf_stop_transfer(cam))
3082 if (w9968cf_set_picture(cam, pict))
3085 if (w9968cf_start_transfer(cam))
3088 } else if (w9968cf_sensor_update_picture(cam, pict))
3092 DBG(5, "VIDIOCSPICT successfully called")
3096 case VIDIOCSWIN: /* set capture area */
3098 struct video_window win;
3101 if (copy_from_user(&win, arg, sizeof(win)))
3104 DBG(6, "VIDIOCSWIN called: clipcount=%d, flags=%u, "
3105 "x=%u, y=%u, %ux%u", win.clipcount, win.flags,
3106 win.x, win.y, win.width, win.height)
3108 if (win.clipcount != 0 || win.flags != 0)
3111 if ((err = w9968cf_adjust_window_size(cam, (u16*)&win.width,
3112 (u16*)&win.height))) {
3113 DBG(4, "Resolution not supported (%ux%u). "
3114 "VIDIOCSWIN failed", win.width, win.height)
3118 if (win.x != cam->window.x ||
3119 win.y != cam->window.y ||
3120 win.width != cam->window.width ||
3121 win.height != cam->window.height) {
3122 if(*cam->requested_frame
3123 || cam->frame_current->queued) {
3124 err = wait_event_interruptible
3126 cam->disconnected ||
3127 (!*cam->requested_frame &&
3128 !cam->frame_current->queued) );
3131 if (cam->disconnected)
3135 if (w9968cf_stop_transfer(cam))
3138 /* This _must_ be called before set_window() */
3139 if (w9968cf_set_picture(cam, cam->picture))
3142 if (w9968cf_set_window(cam, win))
3145 if (w9968cf_start_transfer(cam))
3149 DBG(5, "VIDIOCSWIN successfully called. ")
3153 case VIDIOCGWIN: /* get current window properties */
3155 if (copy_to_user(arg,&cam->window,sizeof(struct video_window)))
3158 DBG(5, "VIDIOCGWIN successfully called")
3162 case VIDIOCGMBUF: /* request for memory (mapped) buffer */
3164 struct video_mbuf mbuf;
3167 mbuf.size = cam->nbuffers * cam->frame[0].size;
3168 mbuf.frames = cam->nbuffers;
3169 for (i = 0; i < cam->nbuffers; i++)
3170 mbuf.offsets[i] = (unsigned long)cam->frame[i].buffer -
3171 (unsigned long)cam->frame[0].buffer;
3173 if (copy_to_user(arg, &mbuf, sizeof(mbuf)))
3176 DBG(5, "VIDIOCGMBUF successfully called")
3180 case VIDIOCMCAPTURE: /* start the capture to a frame */
3182 struct video_mmap mmap;
3183 struct w9968cf_frame_t* fr;
3186 if (copy_from_user(&mmap, arg, sizeof(mmap)))
3189 DBG(6, "VIDIOCMCAPTURE called: frame #%u, format=%s, %dx%d",
3190 mmap.frame, symbolic(v4l1_plist, mmap.format),
3191 mmap.width, mmap.height)
3193 if (mmap.frame >= cam->nbuffers) {
3194 DBG(4, "Invalid frame number (%u). "
3195 "VIDIOCMCAPTURE failed", mmap.frame)
3199 if (mmap.format!=cam->picture.palette &&
3200 (cam->force_palette || !w9968cf_vpp)) {
3201 DBG(4, "Palette %s rejected: only %s is allowed",
3202 symbolic(v4l1_plist, mmap.format),
3203 symbolic(v4l1_plist, cam->picture.palette))
3207 if (!w9968cf_valid_palette(mmap.format)) {
3208 DBG(4, "Palette %s not supported. "
3209 "VIDIOCMCAPTURE failed",
3210 symbolic(v4l1_plist, mmap.format))
3214 if (!cam->force_palette) {
3215 if (cam->decompression == 0) {
3216 if (w9968cf_need_decompression(mmap.format)) {
3217 DBG(4, "Decompression disabled: palette %s is not "
3218 "allowed. VIDIOCSPICT failed",
3219 symbolic(v4l1_plist, mmap.format))
3222 } else if (cam->decompression == 1) {
3223 if (!w9968cf_need_decompression(mmap.format)) {
3224 DBG(4, "Decompression forced: palette %s is not "
3225 "allowed. VIDIOCSPICT failed",
3226 symbolic(v4l1_plist, mmap.format))
3232 if ((err = w9968cf_adjust_window_size(cam, (u16*)&mmap.width,
3233 (u16*)&mmap.height))) {
3234 DBG(4, "Resolution not supported (%dx%d). "
3235 "VIDIOCMCAPTURE failed",
3236 mmap.width, mmap.height)
3240 fr = &cam->frame[mmap.frame];
3242 if (mmap.width != cam->window.width ||
3243 mmap.height != cam->window.height ||
3244 mmap.format != cam->picture.palette) {
3246 struct video_window win;
3247 struct video_picture pict;
3249 if(*cam->requested_frame
3250 || cam->frame_current->queued) {
3251 DBG(6, "VIDIOCMCAPTURE. Change settings for "
3252 "frame #%u: %dx%d, format %s. Wait...",
3253 mmap.frame, mmap.width, mmap.height,
3254 symbolic(v4l1_plist, mmap.format))
3255 err = wait_event_interruptible
3257 cam->disconnected ||
3258 (!*cam->requested_frame &&
3259 !cam->frame_current->queued) );
3262 if (cam->disconnected)
3266 memcpy(&win, &cam->window, sizeof(win));
3267 memcpy(&pict, &cam->picture, sizeof(pict));
3268 win.width = mmap.width;
3269 win.height = mmap.height;
3270 pict.palette = mmap.format;
3272 if (w9968cf_stop_transfer(cam))
3275 /* This before set_window */
3276 if (w9968cf_set_picture(cam, pict))
3279 if (w9968cf_set_window(cam, win))
3282 if (w9968cf_start_transfer(cam))
3285 } else if (fr->queued) {
3287 DBG(6, "Wait until frame #%u is free", mmap.frame)
3289 err = wait_event_interruptible(cam->wait_queue,
3290 cam->disconnected ||
3294 if (cam->disconnected)
3298 w9968cf_push_frame(cam, mmap.frame);
3299 DBG(5, "VIDIOCMCAPTURE(%u): successfully called", mmap.frame)
3303 case VIDIOCSYNC: /* wait until the capture of a frame is finished */
3306 struct w9968cf_frame_t* fr;
3309 if (copy_from_user(&f_num, arg, sizeof(f_num)))
3312 if (f_num >= cam->nbuffers) {
3313 DBG(4, "Invalid frame number (%u). "
3314 "VIDIOCMCAPTURE failed", f_num)
3318 DBG(6, "VIDIOCSYNC called for frame #%u", f_num)
3320 fr = &cam->frame[f_num];
3322 switch (fr->status) {
3325 DBG(4, "VIDIOSYNC: Frame #%u not requested!",
3331 err = wait_event_interruptible(cam->wait_queue,
3332 (fr->status == F_READY)
3333 || cam->disconnected);
3336 if (cam->disconnected)
3344 w9968cf_postprocess_frame(cam, fr);
3346 fr->status = F_UNUSED;
3348 DBG(5, "VIDIOCSYNC(%u) successfully called", f_num)
3352 case VIDIOCGUNIT:/* report the unit numbers of the associated devices*/
3354 struct video_unit unit = {
3355 .video = cam->v4ldev->minor,
3356 .vbi = VIDEO_NO_UNIT,
3357 .radio = VIDEO_NO_UNIT,
3358 .audio = VIDEO_NO_UNIT,
3359 .teletext = VIDEO_NO_UNIT,
3362 if (copy_to_user(arg, &unit, sizeof(unit)))
3365 DBG(5, "VIDIOCGUNIT successfully called")
3374 if (clear_user(arg, sizeof(struct video_buffer)))
3377 DBG(5, "VIDIOCGFBUF successfully called")
3383 struct video_tuner tuner;
3384 if (copy_from_user(&tuner, arg, sizeof(tuner)))
3387 if (tuner.tuner != 0)
3390 strcpy(tuner.name, "no_tuner");
3392 tuner.rangehigh = 0;
3393 tuner.flags = VIDEO_TUNER_NORM;
3394 tuner.mode = VIDEO_MODE_AUTO;
3395 tuner.signal = 0xffff;
3397 if (copy_to_user(arg, &tuner, sizeof(tuner)))
3400 DBG(5, "VIDIOCGTUNER successfully called")
3406 struct video_tuner tuner;
3407 if (copy_from_user(&tuner, arg, sizeof(tuner)))
3410 if (tuner.tuner != 0)
3413 if (tuner.mode != VIDEO_MODE_AUTO)
3416 DBG(5, "VIDIOCSTUNER successfully called")
3426 case VIDIOCSPLAYMODE:
3427 case VIDIOCSWRITEMODE:
3428 case VIDIOCGPLAYINFO:
3429 case VIDIOCSMICROCODE:
3432 DBG(4, "Unsupported V4L1 IOCtl: VIDIOC%s "
3438 _IOC_TYPE(cmd),_IOC_NR(cmd),_IOC_DIR(cmd),_IOC_SIZE(cmd))
3443 DBG(4, "Invalid V4L1 IOCtl: VIDIOC%s "
3449 _IOC_TYPE(cmd),_IOC_NR(cmd),_IOC_DIR(cmd),_IOC_SIZE(cmd))
3451 return -ENOIOCTLCMD;
3453 } /* end of switch */
3456 cam->misconfigured = 1;
3457 DBG(1, "VIDIOC%s failed because of hardware problems. "
3458 "To use the camera, close and open it again.", V4L1_IOCTL(cmd))
3463 static struct file_operations w9968cf_fops = {
3464 .owner = THIS_MODULE,
3465 .open = w9968cf_open,
3466 .release = w9968cf_release,
3467 .read = w9968cf_read,
3468 .ioctl = w9968cf_ioctl,
3469 .compat_ioctl = v4l_compat_ioctl32,
3470 .mmap = w9968cf_mmap,
3471 .llseek = no_llseek,
3476 /****************************************************************************
3477 * USB probe and V4L registration, disconnect and id_table[] definition *
3478 ****************************************************************************/
3481 w9968cf_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
3483 struct usb_device *udev = interface_to_usbdev(intf);
3484 struct w9968cf_device* cam;
3486 enum w9968cf_model_id mod_id;
3487 struct list_head* ptr;
3488 u8 sc = 0; /* number of simultaneous cameras */
3489 static unsigned short dev_nr = 0; /* we are handling device number n */
3491 if (le16_to_cpu(udev->descriptor.idVendor) == winbond_id_table[0].idVendor &&
3492 le16_to_cpu(udev->descriptor.idProduct) == winbond_id_table[0].idProduct)
3493 mod_id = W9968CF_MOD_CLVBWGP; /* see camlist[] table */
3494 else if (le16_to_cpu(udev->descriptor.idVendor) == winbond_id_table[1].idVendor &&
3495 le16_to_cpu(udev->descriptor.idProduct) == winbond_id_table[1].idProduct)
3496 mod_id = W9968CF_MOD_GENERIC; /* see camlist[] table */
3500 cam = (struct w9968cf_device*)
3501 kzalloc(sizeof(struct w9968cf_device), GFP_KERNEL);
3505 init_MUTEX(&cam->dev_sem);
3506 down(&cam->dev_sem);
3509 /* NOTE: a local copy is used to avoid possible race conditions */
3510 memcpy(&cam->dev, &udev->dev, sizeof(struct device));
3512 DBG(2, "%s detected", symbolic(camlist, mod_id))
3514 if (simcams > W9968CF_MAX_DEVICES)
3515 simcams = W9968CF_SIMCAMS;
3517 /* How many cameras are connected ? */
3518 down(&w9968cf_devlist_sem);
3519 list_for_each(ptr, &w9968cf_dev_list)
3521 up(&w9968cf_devlist_sem);
3523 if (sc >= simcams) {
3524 DBG(2, "Device rejected: too many connected cameras "
3525 "(max. %u)", simcams)
3531 /* Allocate 2 bytes of memory for camera control USB transfers */
3532 if (!(cam->control_buffer = kzalloc(2, GFP_KERNEL))) {
3533 DBG(1,"Couldn't allocate memory for camera control transfers")
3538 /* Allocate 8 bytes of memory for USB data transfers to the FSB */
3539 if (!(cam->data_buffer = kzalloc(8, GFP_KERNEL))) {
3540 DBG(1, "Couldn't allocate memory for data "
3541 "transfers to the FSB")
3546 /* Register the V4L device */
3547 cam->v4ldev = video_device_alloc();
3549 DBG(1, "Could not allocate memory for a V4L structure")
3554 strcpy(cam->v4ldev->name, symbolic(camlist, mod_id));
3555 cam->v4ldev->owner = THIS_MODULE;
3556 cam->v4ldev->type = VID_TYPE_CAPTURE | VID_TYPE_SCALES;
3557 cam->v4ldev->hardware = VID_HARDWARE_W9968CF;
3558 cam->v4ldev->fops = &w9968cf_fops;
3559 cam->v4ldev->minor = video_nr[dev_nr];
3560 cam->v4ldev->release = video_device_release;
3561 video_set_drvdata(cam->v4ldev, cam);
3562 cam->v4ldev->dev = &cam->dev;
3564 err = video_register_device(cam->v4ldev, VFL_TYPE_GRABBER,
3567 DBG(1, "V4L device registration failed")
3568 if (err == -ENFILE && video_nr[dev_nr] == -1)
3569 DBG(2, "Couldn't find a free /dev/videoX node")
3570 video_nr[dev_nr] = -1;
3571 dev_nr = (dev_nr < W9968CF_MAX_DEVICES-1) ? dev_nr+1 : 0;
3575 DBG(2, "V4L device registered as /dev/video%d", cam->v4ldev->minor)
3577 /* Set some basic constants */
3578 w9968cf_configure_camera(cam, udev, mod_id, dev_nr);
3580 /* Add a new entry into the list of V4L registered devices */
3581 down(&w9968cf_devlist_sem);
3582 list_add(&cam->v4llist, &w9968cf_dev_list);
3583 up(&w9968cf_devlist_sem);
3584 dev_nr = (dev_nr < W9968CF_MAX_DEVICES-1) ? dev_nr+1 : 0;
3586 w9968cf_turn_on_led(cam);
3588 w9968cf_i2c_init(cam);
3590 usb_set_intfdata(intf, cam);
3594 fail: /* Free unused memory */
3595 kfree(cam->control_buffer);
3596 kfree(cam->data_buffer);
3598 video_device_release(cam->v4ldev);
3605 static void w9968cf_usb_disconnect(struct usb_interface* intf)
3607 struct w9968cf_device* cam =
3608 (struct w9968cf_device*)usb_get_intfdata(intf);
3610 down_write(&w9968cf_disconnect);
3613 /* Prevent concurrent accesses to data */
3614 down(&cam->dev_sem);
3616 cam->disconnected = 1;
3618 DBG(2, "Disconnecting %s...", symbolic(camlist, cam->id))
3620 wake_up_interruptible_all(&cam->open);
3623 DBG(2, "The device is open (/dev/video%d)! "
3624 "Process name: %s. Deregistration and memory "
3625 "deallocation are deferred on close.",
3626 cam->v4ldev->minor, cam->command)
3627 cam->misconfigured = 1;
3628 w9968cf_stop_transfer(cam);
3629 wake_up_interruptible(&cam->wait_queue);
3631 w9968cf_release_resources(cam);
3639 up_write(&w9968cf_disconnect);
3643 static struct usb_driver w9968cf_usb_driver = {
3645 .id_table = winbond_id_table,
3646 .probe = w9968cf_usb_probe,
3647 .disconnect = w9968cf_usb_disconnect,
3652 /****************************************************************************
3653 * Module init, exit and intermodule communication *
3654 ****************************************************************************/
3656 static int __init w9968cf_module_init(void)
3660 KDBG(2, W9968CF_MODULE_NAME" "W9968CF_MODULE_VERSION)
3661 KDBG(3, W9968CF_MODULE_AUTHOR)
3664 request_module("ovcamchip");
3666 if ((err = usb_register(&w9968cf_usb_driver)))
3673 static void __exit w9968cf_module_exit(void)
3675 /* w9968cf_usb_disconnect() will be called */
3676 usb_deregister(&w9968cf_usb_driver);
3678 KDBG(2, W9968CF_MODULE_NAME" deregistered")
3682 module_init(w9968cf_module_init);
3683 module_exit(w9968cf_module_exit);