83e8dd62715463d436ce04323ca5a3b10180efda
[linux-2.6.git] / drivers / usb / media / w9968cf.c
1 /***************************************************************************
2  * Video4Linux driver for W996[87]CF JPEG USB Dual Mode Camera Chip.       *
3  *                                                                         *
4  * Copyright (C) 2002-2004 by Luca Risolia <luca.risolia@studio.unibo.it>  *
5  *                                                                         *
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.                      *
12  *                                                                         *
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.                                     *
17  *                                                                         *
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.                            *
22  *                                                                         *
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  ***************************************************************************/
27
28 #include <linux/version.h>
29 #include <linux/module.h>
30 #include <linux/kernel.h>
31 #include <linux/kmod.h>
32 #include <linux/init.h>
33 #include <linux/fs.h>
34 #include <linux/vmalloc.h>
35 #include <linux/slab.h>
36 #include <linux/mm.h>
37 #include <linux/string.h>
38 #include <linux/errno.h>
39 #include <linux/sched.h>
40 #include <linux/ioctl.h>
41 #include <linux/delay.h>
42 #include <linux/stddef.h>
43 #include <asm/page.h>
44 #include <asm/uaccess.h>
45 #include <linux/page-flags.h>
46 #include <linux/moduleparam.h>
47
48 #include "w9968cf.h"
49 #include "w9968cf_decoder.h"
50
51
52
53 /****************************************************************************
54  * Module macros and parameters                                             *
55  ****************************************************************************/
56
57 MODULE_DEVICE_TABLE(usb, winbond_id_table);
58
59 MODULE_AUTHOR(W9968CF_MODULE_AUTHOR" "W9968CF_AUTHOR_EMAIL);
60 MODULE_DESCRIPTION(W9968CF_MODULE_NAME);
61 MODULE_VERSION(W9968CF_MODULE_VERSION);
62 MODULE_LICENSE(W9968CF_MODULE_LICENSE);
63 MODULE_SUPPORTED_DEVICE("Video");
64
65 static int ovmod_load = W9968CF_OVMOD_LOAD;
66 static int vppmod_load = W9968CF_VPPMOD_LOAD;
67 static unsigned short simcams = W9968CF_SIMCAMS;
68 static short video_nr[]={[0 ... W9968CF_MAX_DEVICES-1] = -1}; /*-1=first free*/
69 static unsigned int packet_size[] = {[0 ... W9968CF_MAX_DEVICES-1] = 
70                                      W9968CF_PACKET_SIZE};
71 static unsigned short max_buffers[] = {[0 ... W9968CF_MAX_DEVICES-1] = 
72                                        W9968CF_BUFFERS};
73 static int double_buffer[] = {[0 ... W9968CF_MAX_DEVICES-1] = 
74                               W9968CF_DOUBLE_BUFFER};
75 static int clamping[] = {[0 ... W9968CF_MAX_DEVICES-1] = W9968CF_CLAMPING};
76 static unsigned short filter_type[]= {[0 ... W9968CF_MAX_DEVICES-1] = 
77                                       W9968CF_FILTER_TYPE};
78 static int largeview[]= {[0 ... W9968CF_MAX_DEVICES-1] = W9968CF_LARGEVIEW};
79 static unsigned short decompression[] = {[0 ... W9968CF_MAX_DEVICES-1] = 
80                                          W9968CF_DECOMPRESSION};
81 static int upscaling[]= {[0 ... W9968CF_MAX_DEVICES-1] = W9968CF_UPSCALING};
82 static unsigned short force_palette[] = {[0 ... W9968CF_MAX_DEVICES-1] = 0};
83 static int force_rgb[] = {[0 ... W9968CF_MAX_DEVICES-1] = W9968CF_FORCE_RGB};
84 static int autobright[] = {[0 ... W9968CF_MAX_DEVICES-1] = W9968CF_AUTOBRIGHT};
85 static int autoexp[] = {[0 ... W9968CF_MAX_DEVICES-1] = W9968CF_AUTOEXP};
86 static unsigned short lightfreq[] = {[0 ... W9968CF_MAX_DEVICES-1] = 
87                                      W9968CF_LIGHTFREQ};
88 static int bandingfilter[] = {[0 ... W9968CF_MAX_DEVICES-1]=
89                               W9968CF_BANDINGFILTER};
90 static short clockdiv[] = {[0 ... W9968CF_MAX_DEVICES-1] = W9968CF_CLOCKDIV};
91 static int backlight[] = {[0 ... W9968CF_MAX_DEVICES-1] = W9968CF_BACKLIGHT};
92 static int mirror[] = {[0 ... W9968CF_MAX_DEVICES-1] = W9968CF_MIRROR};
93 static int monochrome[] = {[0 ... W9968CF_MAX_DEVICES-1]=W9968CF_MONOCHROME};
94 static unsigned int brightness[] = {[0 ... W9968CF_MAX_DEVICES-1] = 
95                                     W9968CF_BRIGHTNESS};
96 static unsigned int hue[] = {[0 ... W9968CF_MAX_DEVICES-1] = W9968CF_HUE};
97 static unsigned int colour[]={[0 ... W9968CF_MAX_DEVICES-1] = W9968CF_COLOUR};
98 static unsigned int contrast[] = {[0 ... W9968CF_MAX_DEVICES-1] = 
99                                   W9968CF_CONTRAST};
100 static unsigned int whiteness[] = {[0 ... W9968CF_MAX_DEVICES-1] = 
101                                    W9968CF_WHITENESS};
102 #ifdef W9968CF_DEBUG
103 static unsigned short debug = W9968CF_DEBUG_LEVEL;
104 static int specific_debug = W9968CF_SPECIFIC_DEBUG;
105 #endif
106
107 static unsigned int param_nv[24]; /* number of values per parameter */
108
109 #ifdef CONFIG_KMOD
110 module_param(ovmod_load, bool, 0644);
111 module_param(vppmod_load, bool, 0444);
112 #endif
113 module_param(simcams, ushort, 0644);
114 module_param_array(video_nr, short, &param_nv[0], 0444);
115 module_param_array(packet_size, uint, &param_nv[1], 0444);
116 module_param_array(max_buffers, ushort, &param_nv[2], 0444);
117 module_param_array(double_buffer, bool, &param_nv[3], 0444);
118 module_param_array(clamping, bool, &param_nv[4], 0444);
119 module_param_array(filter_type, ushort, &param_nv[5], 0444);
120 module_param_array(largeview, bool, &param_nv[6], 0444);
121 module_param_array(decompression, ushort, &param_nv[7], 0444);
122 module_param_array(upscaling, bool, &param_nv[8], 0444);
123 module_param_array(force_palette, ushort, &param_nv[9], 0444);
124 module_param_array(force_rgb, ushort, &param_nv[10], 0444);
125 module_param_array(autobright, bool, &param_nv[11], 0444);
126 module_param_array(autoexp, bool, &param_nv[12], 0444);
127 module_param_array(lightfreq, ushort, &param_nv[13], 0444);
128 module_param_array(bandingfilter, bool, &param_nv[14], 0444);
129 module_param_array(clockdiv, short, &param_nv[15], 0444);
130 module_param_array(backlight, bool, &param_nv[16], 0444);
131 module_param_array(mirror, bool, &param_nv[17], 0444);
132 module_param_array(monochrome, bool, &param_nv[18], 0444);
133 module_param_array(brightness, uint, &param_nv[19], 0444);
134 module_param_array(hue, uint, &param_nv[20], 0444);
135 module_param_array(colour, uint, &param_nv[21], 0444);
136 module_param_array(contrast, uint, &param_nv[22], 0444);
137 module_param_array(whiteness, uint, &param_nv[23], 0444);
138 #ifdef W9968CF_DEBUG
139 module_param(debug, ushort, 0644);
140 module_param(specific_debug, bool, 0644);
141 #endif
142
143 #ifdef CONFIG_KMOD
144 MODULE_PARM_DESC(ovmod_load, 
145                  "\n<0|1> Automatic 'ovcamchip' module loading."
146                  "\n0 disabled, 1 enabled."
147                  "\nIf enabled,'insmod' searches for the required 'ovcamchip'"
148                  "\nmodule in the system, according to its configuration, and"
149                  "\nattempts to load that module automatically. This action is"
150                  "\nperformed once as soon as the 'w9968cf' module is loaded"
151                  "\ninto memory."
152                  "\nDefault value is "__MODULE_STRING(W9968CF_OVMOD_LOAD)"."
153                  "\n");
154 MODULE_PARM_DESC(vppmod_load, 
155                  "\n<0|1> Automatic 'w9968cf-vpp' module loading."
156                  "\n0 disabled, 1 enabled."
157                  "\nIf enabled, every time an application attempts to open a"
158                  "\ncamera, 'insmod' searches for the video post-processing"
159                  "\nmodule in the system and loads it automatically (if"
160                  "\npresent). The optional 'w9968cf-vpp' module adds extra"
161                  "\n image manipulation functions to the 'w9968cf' module,like"
162                  "\nsoftware up-scaling,colour conversions and video decoding"
163                  "\nfor very high frame rates."
164                  "\nDefault value is "__MODULE_STRING(W9968CF_VPPMOD_LOAD)"."
165                  "\n");
166 #endif
167 MODULE_PARM_DESC(simcams, 
168                  "\n<n> Number of cameras allowed to stream simultaneously."
169                  "\nn may vary from 0 to "
170                  __MODULE_STRING(W9968CF_MAX_DEVICES)"."
171                  "\nDefault value is "__MODULE_STRING(W9968CF_SIMCAMS)"."
172                  "\n");
173 MODULE_PARM_DESC(video_nr,
174                  "\n<-1|n[,...]> Specify V4L minor mode number."
175                  "\n -1 = use next available (default)"
176                  "\n  n = use minor number n (integer >= 0)"
177                  "\nYou can specify up to "__MODULE_STRING(W9968CF_MAX_DEVICES)
178                  " cameras this way."
179                  "\nFor example:"
180                  "\nvideo_nr=-1,2,-1 would assign minor number 2 to"
181                  "\nthe second camera and use auto for the first"
182                  "\none and for every other camera."
183                  "\n");
184 MODULE_PARM_DESC(packet_size,
185                  "\n<n[,...]> Specify the maximum data payload"
186                  "\nsize in bytes for alternate settings, for each device."
187                  "\nn is scaled between 63 and 1023 "
188                  "(default is "__MODULE_STRING(W9968CF_PACKET_SIZE)")."
189                  "\n");
190 MODULE_PARM_DESC(max_buffers,
191                  "\n<n[,...]> For advanced users."
192                  "\nSpecify the maximum number of video frame buffers"
193                  "\nto allocate for each device, from 2 to "
194                  __MODULE_STRING(W9968CF_MAX_BUFFERS)
195                  ". (default is "__MODULE_STRING(W9968CF_BUFFERS)")."
196                  "\n");
197 MODULE_PARM_DESC(double_buffer, 
198                  "\n<0|1[,...]> "
199                  "Hardware double buffering: 0 disabled, 1 enabled."
200                  "\nIt should be enabled if you want smooth video output: if"
201                  "\nyou obtain out of sync. video, disable it, or try to"
202                  "\ndecrease the 'clockdiv' module parameter value."
203                  "\nDefault value is "__MODULE_STRING(W9968CF_DOUBLE_BUFFER)
204                  " for every device."
205                  "\n");
206 MODULE_PARM_DESC(clamping, 
207                  "\n<0|1[,...]> Video data clamping: 0 disabled, 1 enabled."
208                  "\nDefault value is "__MODULE_STRING(W9968CF_CLAMPING)
209                  " for every device."
210                  "\n");
211 MODULE_PARM_DESC(filter_type, 
212                  "\n<0|1|2[,...]> Video filter type."
213                  "\n0 none, 1 (1-2-1) 3-tap filter, "
214                  "2 (2-3-6-3-2) 5-tap filter."
215                  "\nDefault value is "__MODULE_STRING(W9968CF_FILTER_TYPE)
216                  " for every device."
217                  "\nThe filter is used to reduce noise and aliasing artifacts"
218                  "\nproduced by the CCD or CMOS image sensor, and the scaling"
219                  " process."
220                  "\n");
221 MODULE_PARM_DESC(largeview, 
222                  "\n<0|1[,...]> Large view: 0 disabled, 1 enabled."
223                  "\nDefault value is "__MODULE_STRING(W9968CF_LARGEVIEW)
224                  " for every device."
225                  "\n");
226 MODULE_PARM_DESC(upscaling, 
227                  "\n<0|1[,...]> Software scaling (for non-compressed video):"
228                  "\n0 disabled, 1 enabled."
229                  "\nDisable it if you have a slow CPU or you don't have"
230                  " enough memory."
231                  "\nDefault value is "__MODULE_STRING(W9968CF_UPSCALING)
232                  " for every device."
233                  "\nIf 'w9968cf-vpp' is not present, this parameter is"
234                  " set to 0."
235                  "\n");
236 MODULE_PARM_DESC(decompression,
237                  "\n<0|1|2[,...]> Software video decompression:"
238                  "\n- 0 disables decompression (doesn't allow formats needing"
239                  " decompression)"
240                  "\n- 1 forces decompression (allows formats needing"
241                  " decompression only);"
242                  "\n- 2 allows any permitted formats."
243                  "\nFormats supporting compressed video are YUV422P and"
244                  " YUV420P/YUV420 "
245                  "\nin any resolutions where both width and height are "
246                  "a multiple of 16."
247                  "\nDefault value is "__MODULE_STRING(W9968CF_DECOMPRESSION)
248                  " for every device."
249                  "\nIf 'w9968cf-vpp' is not present, forcing decompression is "
250                  "\nnot allowed; in this case this parameter is set to 2."
251                  "\n");
252 MODULE_PARM_DESC(force_palette,
253                  "\n<0"
254                  "|" __MODULE_STRING(VIDEO_PALETTE_UYVY)
255                  "|" __MODULE_STRING(VIDEO_PALETTE_YUV420)
256                  "|" __MODULE_STRING(VIDEO_PALETTE_YUV422P)
257                  "|" __MODULE_STRING(VIDEO_PALETTE_YUV420P)
258                  "|" __MODULE_STRING(VIDEO_PALETTE_YUYV)
259                  "|" __MODULE_STRING(VIDEO_PALETTE_YUV422)
260                  "|" __MODULE_STRING(VIDEO_PALETTE_GREY)
261                  "|" __MODULE_STRING(VIDEO_PALETTE_RGB555)
262                  "|" __MODULE_STRING(VIDEO_PALETTE_RGB565)
263                  "|" __MODULE_STRING(VIDEO_PALETTE_RGB24)
264                  "|" __MODULE_STRING(VIDEO_PALETTE_RGB32)
265                  "[,...]>"
266                  " Force picture palette."
267                  "\nIn order:"
268                  "\n- 0 allows any of the following formats:"
269                  "\n- UYVY    16 bpp - Original video, compression disabled"
270                  "\n- YUV420  12 bpp - Original video, compression enabled"
271                  "\n- YUV422P 16 bpp - Original video, compression enabled"
272                  "\n- YUV420P 12 bpp - Original video, compression enabled"
273                  "\n- YUVY    16 bpp - Software conversion from UYVY"
274                  "\n- YUV422  16 bpp - Software conversion from UYVY"
275                  "\n- GREY     8 bpp - Software conversion from UYVY"
276                  "\n- RGB555  16 bpp - Software conversion from UYVY"
277                  "\n- RGB565  16 bpp - Software conversion from UYVY"
278                  "\n- RGB24   24 bpp - Software conversion from UYVY"
279                  "\n- RGB32   32 bpp - Software conversion from UYVY"
280                  "\nWhen not 0, this parameter will override 'decompression'."
281                  "\nDefault value is 0 for every device."
282                  "\nInitial palette is "
283                  __MODULE_STRING(W9968CF_PALETTE_DECOMP_ON)"."
284                  "\nIf 'w9968cf-vpp' is not present, this parameter is"
285                  " set to 9 (UYVY)."
286                  "\n");
287 MODULE_PARM_DESC(force_rgb, 
288                  "\n<0|1[,...]> Read RGB video data instead of BGR:"
289                  "\n 1 = use RGB component ordering."
290                  "\n 0 = use BGR component ordering."
291                  "\nThis parameter has effect when using RGBX palettes only."
292                  "\nDefault value is "__MODULE_STRING(W9968CF_FORCE_RGB)
293                  " for every device."
294                  "\n");
295 MODULE_PARM_DESC(autobright,
296                  "\n<0|1[,...]> Image sensor automatically changes brightness:"
297                  "\n 0 = no, 1 = yes"
298                  "\nDefault value is "__MODULE_STRING(W9968CF_AUTOBRIGHT)
299                  " for every device."
300                  "\n");
301 MODULE_PARM_DESC(autoexp,
302                  "\n<0|1[,...]> Image sensor automatically changes exposure:"
303                  "\n 0 = no, 1 = yes"
304                  "\nDefault value is "__MODULE_STRING(W9968CF_AUTOEXP)
305                  " for every device."
306                  "\n");
307 MODULE_PARM_DESC(lightfreq,
308                  "\n<50|60[,...]> Light frequency in Hz:"
309                  "\n 50 for European and Asian lighting,"
310                  " 60 for American lighting."
311                  "\nDefault value is "__MODULE_STRING(W9968CF_LIGHTFREQ)
312                  " for every device."
313                  "\n");
314 MODULE_PARM_DESC(bandingfilter,
315                  "\n<0|1[,...]> Banding filter to reduce effects of"
316                  " fluorescent lighting:"
317                  "\n 0 disabled, 1 enabled."
318                  "\nThis filter tries to reduce the pattern of horizontal"
319                  "\nlight/dark bands caused by some (usually fluorescent)"
320                  " lighting."
321                  "\nDefault value is "__MODULE_STRING(W9968CF_BANDINGFILTER)
322                  " for every device."
323                  "\n");
324 MODULE_PARM_DESC(clockdiv,
325                  "\n<-1|n[,...]> "
326                  "Force pixel clock divisor to a specific value (for experts):"
327                  "\n  n may vary from 0 to 127."
328                  "\n -1 for automatic value."
329                  "\nSee also the 'double_buffer' module parameter."
330                  "\nDefault value is "__MODULE_STRING(W9968CF_CLOCKDIV)
331                  " for every device."
332                  "\n");
333 MODULE_PARM_DESC(backlight,
334                  "\n<0|1[,...]> Objects are lit from behind:"
335                  "\n 0 = no, 1 = yes"
336                  "\nDefault value is "__MODULE_STRING(W9968CF_BACKLIGHT)
337                  " for every device."
338                  "\n");
339 MODULE_PARM_DESC(mirror,
340                  "\n<0|1[,...]> Reverse image horizontally:"
341                  "\n 0 = no, 1 = yes"
342                  "\nDefault value is "__MODULE_STRING(W9968CF_MIRROR)
343                  " for every device."
344                  "\n");
345 MODULE_PARM_DESC(monochrome,
346                  "\n<0|1[,...]> Use image sensor as monochrome sensor:"
347                  "\n 0 = no, 1 = yes"
348                  "\nNot all the sensors support monochrome color."
349                  "\nDefault value is "__MODULE_STRING(W9968CF_MONOCHROME)
350                  " for every device."
351                  "\n");
352 MODULE_PARM_DESC(brightness, 
353                  "\n<n[,...]> Set picture brightness (0-65535)."
354                  "\nDefault value is "__MODULE_STRING(W9968CF_BRIGHTNESS)
355                  " for every device."
356                  "\nThis parameter has no effect if 'autobright' is enabled."
357                  "\n");
358 MODULE_PARM_DESC(hue, 
359                  "\n<n[,...]> Set picture hue (0-65535)."
360                  "\nDefault value is "__MODULE_STRING(W9968CF_HUE)
361                  " for every device."
362                  "\n");
363 MODULE_PARM_DESC(colour, 
364                  "\n<n[,...]> Set picture saturation (0-65535)."
365                  "\nDefault value is "__MODULE_STRING(W9968CF_COLOUR)
366                  " for every device."
367                  "\n");
368 MODULE_PARM_DESC(contrast, 
369                  "\n<n[,...]> Set picture contrast (0-65535)."
370                  "\nDefault value is "__MODULE_STRING(W9968CF_CONTRAST)
371                  " for every device."
372                  "\n");
373 MODULE_PARM_DESC(whiteness, 
374                  "\n<n[,...]> Set picture whiteness (0-65535)."
375                  "\nDefault value is "__MODULE_STRING(W9968CF_WHITENESS)
376                  " for every device."
377                  "\n");
378 #ifdef W9968CF_DEBUG
379 MODULE_PARM_DESC(debug,
380                  "\n<n> Debugging information level, from 0 to 6:"
381                  "\n0 = none (use carefully)"
382                  "\n1 = critical errors"
383                  "\n2 = significant informations"
384                  "\n3 = configuration or general messages"
385                  "\n4 = warnings"
386                  "\n5 = called functions"
387                  "\n6 = function internals"
388                  "\nLevel 5 and 6 are useful for testing only, when only "
389                  "one device is used."
390                  "\nDefault value is "__MODULE_STRING(W9968CF_DEBUG_LEVEL)"."
391                  "\n");
392 MODULE_PARM_DESC(specific_debug,
393                  "\n<0|1> Enable or disable specific debugging messages:"
394                  "\n0 = print messages concerning every level"
395                  " <= 'debug' level."
396                  "\n1 = print messages concerning the level"
397                  " indicated by 'debug'."
398                  "\nDefault value is "
399                  __MODULE_STRING(W9968CF_SPECIFIC_DEBUG)"."
400                  "\n");
401 #endif /* W9968CF_DEBUG */
402
403
404
405 /****************************************************************************
406  * Some prototypes                                                          *
407  ****************************************************************************/
408
409 /* Video4linux interface */
410 static struct file_operations w9968cf_fops;
411 static int w9968cf_open(struct inode*, struct file*);
412 static int w9968cf_release(struct inode*, struct file*);
413 static int w9968cf_mmap(struct file*, struct vm_area_struct*);
414 static int w9968cf_ioctl(struct inode*, struct file*, unsigned, unsigned long);
415 static ssize_t w9968cf_read(struct file*, char __user *, size_t, loff_t*);
416 static int w9968cf_v4l_ioctl(struct inode*, struct file*, unsigned int,
417                              void __user *);
418
419 /* USB-specific */
420 static int w9968cf_start_transfer(struct w9968cf_device*);
421 static int w9968cf_stop_transfer(struct w9968cf_device*);
422 static int w9968cf_write_reg(struct w9968cf_device*, u16 value, u16 index);
423 static int w9968cf_read_reg(struct w9968cf_device*, u16 index);
424 static int w9968cf_write_fsb(struct w9968cf_device*, u16* data);
425 static int w9968cf_write_sb(struct w9968cf_device*, u16 value);
426 static int w9968cf_read_sb(struct w9968cf_device*);
427 static int w9968cf_upload_quantizationtables(struct w9968cf_device*);
428 static void w9968cf_urb_complete(struct urb *urb, struct pt_regs *regs);
429
430 /* Low-level I2C (SMBus) I/O */
431 static int w9968cf_smbus_start(struct w9968cf_device*);
432 static int w9968cf_smbus_stop(struct w9968cf_device*);
433 static int w9968cf_smbus_write_byte(struct w9968cf_device*, u8 v);
434 static int w9968cf_smbus_read_byte(struct w9968cf_device*, u8* v);
435 static int w9968cf_smbus_write_ack(struct w9968cf_device*);
436 static int w9968cf_smbus_read_ack(struct w9968cf_device*);
437 static int w9968cf_smbus_refresh_bus(struct w9968cf_device*);
438 static int w9968cf_i2c_adap_read_byte(struct w9968cf_device* cam,
439                                       u16 address, u8* value);
440 static int w9968cf_i2c_adap_read_byte_data(struct w9968cf_device*, u16 address, 
441                                            u8 subaddress, u8* value);
442 static int w9968cf_i2c_adap_write_byte(struct w9968cf_device*,
443                                        u16 address, u8 subaddress);
444 static int w9968cf_i2c_adap_fastwrite_byte_data(struct w9968cf_device*,
445                                                 u16 address, u8 subaddress,
446                                                 u8 value);
447
448 /* I2C interface to kernel */
449 static int w9968cf_i2c_init(struct w9968cf_device*);
450 static int w9968cf_i2c_smbus_xfer(struct i2c_adapter*, u16 addr, 
451                                   unsigned short flags, char read_write, 
452                                   u8 command, int size, union i2c_smbus_data*);
453 static u32 w9968cf_i2c_func(struct i2c_adapter*);
454 static int w9968cf_i2c_attach_inform(struct i2c_client*);
455 static int w9968cf_i2c_detach_inform(struct i2c_client*);
456 static int w9968cf_i2c_control(struct i2c_adapter*, unsigned int cmd,
457                                unsigned long arg);
458
459 /* Memory management */
460 static void* rvmalloc(unsigned long size);
461 static void rvfree(void *mem, unsigned long size);
462 static void w9968cf_deallocate_memory(struct w9968cf_device*);
463 static int  w9968cf_allocate_memory(struct w9968cf_device*);
464
465 /* High-level image sensor control functions */
466 static int w9968cf_sensor_set_control(struct w9968cf_device*,int cid,int val);
467 static int w9968cf_sensor_get_control(struct w9968cf_device*,int cid,int *val);
468 static int w9968cf_sensor_cmd(struct w9968cf_device*,
469                               unsigned int cmd, void *arg);
470 static int w9968cf_sensor_init(struct w9968cf_device*);
471 static int w9968cf_sensor_update_settings(struct w9968cf_device*);
472 static int w9968cf_sensor_get_picture(struct w9968cf_device*);
473 static int w9968cf_sensor_update_picture(struct w9968cf_device*, 
474                                          struct video_picture pict);
475
476 /* Other helper functions */
477 static void w9968cf_configure_camera(struct w9968cf_device*,struct usb_device*,
478                                      enum w9968cf_model_id, 
479                                      const unsigned short dev_nr);
480 static void w9968cf_adjust_configuration(struct w9968cf_device*);
481 static int w9968cf_turn_on_led(struct w9968cf_device*);
482 static int w9968cf_init_chip(struct w9968cf_device*);
483 static inline u16 w9968cf_valid_palette(u16 palette);
484 static inline u16 w9968cf_valid_depth(u16 palette);
485 static inline u8 w9968cf_need_decompression(u16 palette);
486 static int w9968cf_set_picture(struct w9968cf_device*, struct video_picture);
487 static int w9968cf_set_window(struct w9968cf_device*, struct video_window);
488 static int w9968cf_postprocess_frame(struct w9968cf_device*, 
489                                      struct w9968cf_frame_t*);
490 static int w9968cf_adjust_window_size(struct w9968cf_device*, u16* w, u16* h);
491 static void w9968cf_init_framelist(struct w9968cf_device*);
492 static void w9968cf_push_frame(struct w9968cf_device*, u8 f_num);
493 static void w9968cf_pop_frame(struct w9968cf_device*,struct w9968cf_frame_t**);
494 static void w9968cf_release_resources(struct w9968cf_device*);
495
496 /* Intermodule communication */
497 static int w9968cf_vppmod_detect(struct w9968cf_device*);
498 static void w9968cf_vppmod_release(struct w9968cf_device*);
499
500
501
502 /****************************************************************************
503  * Symbolic names                                                           *
504  ****************************************************************************/
505
506 /* Used to represent a list of values and their respective symbolic names */
507 struct w9968cf_symbolic_list {
508         const int num;
509         const char *name;
510 };
511
512 /*-------------------------------------------------------------------------- 
513   Returns the name of the matching element in the symbolic_list array. The
514   end of the list must be marked with an element that has a NULL name.
515   --------------------------------------------------------------------------*/
516 static inline const char * 
517 symbolic(struct w9968cf_symbolic_list list[], const int num)
518 {
519         int i;
520
521         for (i = 0; list[i].name != NULL; i++)
522                 if (list[i].num == num)
523                         return (list[i].name);
524
525         return "Unknown";
526 }
527
528 static struct w9968cf_symbolic_list camlist[] = {
529         { W9968CF_MOD_GENERIC, "W996[87]CF JPEG USB Dual Mode Camera" },
530         { W9968CF_MOD_CLVBWGP, "Creative Labs Video Blaster WebCam Go Plus" },
531
532         /* Other cameras (having the same descriptors as Generic W996[87]CF) */
533         { W9968CF_MOD_ADPVDMA, "Aroma Digi Pen VGA Dual Mode ADG-5000" },
534         { W9986CF_MOD_AAU, "AVerMedia AVerTV USB" },
535         { W9968CF_MOD_CLVBWG, "Creative Labs Video Blaster WebCam Go" },
536         { W9968CF_MOD_LL, "Lebon LDC-035A" },
537         { W9968CF_MOD_EEEMC, "Ezonics EZ-802 EZMega Cam" },
538         { W9968CF_MOD_OOE, "OmniVision OV8610-EDE" },
539         { W9968CF_MOD_ODPVDMPC, "OPCOM Digi Pen VGA Dual Mode Pen Camera" },
540         { W9968CF_MOD_PDPII, "Pretec Digi Pen-II" },
541         { W9968CF_MOD_PDP480, "Pretec DigiPen-480" },
542
543         {  -1, NULL }
544 };
545
546 static struct w9968cf_symbolic_list senlist[] = {
547         { CC_OV76BE,   "OV76BE" },
548         { CC_OV7610,   "OV7610" },
549         { CC_OV7620,   "OV7620" },
550         { CC_OV7620AE, "OV7620AE" },
551         { CC_OV6620,   "OV6620" },
552         { CC_OV6630,   "OV6630" },
553         { CC_OV6630AE, "OV6630AE" },
554         { CC_OV6630AF, "OV6630AF" },
555         { -1, NULL }
556 };
557
558 /* Video4Linux1 palettes */
559 static struct w9968cf_symbolic_list v4l1_plist[] = {
560         { VIDEO_PALETTE_GREY,    "GREY" },
561         { VIDEO_PALETTE_HI240,   "HI240" },
562         { VIDEO_PALETTE_RGB565,  "RGB565" },
563         { VIDEO_PALETTE_RGB24,   "RGB24" },
564         { VIDEO_PALETTE_RGB32,   "RGB32" },
565         { VIDEO_PALETTE_RGB555,  "RGB555" },
566         { VIDEO_PALETTE_YUV422,  "YUV422" },
567         { VIDEO_PALETTE_YUYV,    "YUYV" },
568         { VIDEO_PALETTE_UYVY,    "UYVY" },
569         { VIDEO_PALETTE_YUV420,  "YUV420" },
570         { VIDEO_PALETTE_YUV411,  "YUV411" },
571         { VIDEO_PALETTE_RAW,     "RAW" },
572         { VIDEO_PALETTE_YUV422P, "YUV422P" },
573         { VIDEO_PALETTE_YUV411P, "YUV411P" },
574         { VIDEO_PALETTE_YUV420P, "YUV420P" },
575         { VIDEO_PALETTE_YUV410P, "YUV410P" },
576         { -1, NULL }
577 };
578
579 /* Decoder error codes: */
580 static struct w9968cf_symbolic_list decoder_errlist[] = {
581         { W9968CF_DEC_ERR_CORRUPTED_DATA, "Corrupted data" },
582         { W9968CF_DEC_ERR_BUF_OVERFLOW,   "Buffer overflow" },
583         { W9968CF_DEC_ERR_NO_SOI,         "SOI marker not found" },     
584         { W9968CF_DEC_ERR_NO_SOF0,        "SOF0 marker not found" },
585         { W9968CF_DEC_ERR_NO_SOS,         "SOS marker not found" },
586         { W9968CF_DEC_ERR_NO_EOI,         "EOI marker not found" },
587         { -1, NULL }
588 };
589
590 /* URB error codes: */
591 static struct w9968cf_symbolic_list urb_errlist[] = {
592         { -ENOMEM,    "No memory for allocation of internal structures" },
593         { -ENOSPC,    "The host controller's bandwidth is already consumed" },
594         { -ENOENT,    "URB was canceled by unlink_urb" },
595         { -EXDEV,     "ISO transfer only partially completed" },
596         { -EAGAIN,    "Too match scheduled for the future" },
597         { -ENXIO,     "URB already queued" },
598         { -EFBIG,     "Too much ISO frames requested" },
599         { -ENOSR,     "Buffer error (overrun)" },
600         { -EPIPE,     "Specified endpoint is stalled (device not responding)"},
601         { -EOVERFLOW, "Babble (bad cable?)" },
602         { -EPROTO,    "Bit-stuff error (bad cable?)" },
603         { -EILSEQ,    "CRC/Timeout" },
604         { -ETIMEDOUT, "NAK (device does not respond)" },
605         { -1, NULL }
606 };
607
608
609
610 /****************************************************************************
611  * Memory management functions                                              *
612  ****************************************************************************/
613 static void* rvmalloc(unsigned long size)
614 {
615         void* mem;
616         unsigned long adr;
617
618         size = PAGE_ALIGN(size);
619         mem = vmalloc_32(size);
620         if (!mem)
621                 return NULL;
622
623         memset(mem, 0, size); /* Clear the ram out, no junk to the user */
624         adr = (unsigned long) mem;
625         while (size > 0) {
626                 SetPageReserved(vmalloc_to_page((void *)adr));
627                 adr += PAGE_SIZE;
628                 size -= PAGE_SIZE;
629         }
630
631         return mem;
632 }
633
634
635 static void rvfree(void* mem, unsigned long size)
636 {
637         unsigned long adr;
638
639         if (!mem)
640                 return;
641
642         adr = (unsigned long) mem;
643         while ((long) size > 0) {
644                 ClearPageReserved(vmalloc_to_page((void *)adr));
645                 adr += PAGE_SIZE;
646                 size -= PAGE_SIZE;
647         }
648         vfree(mem);
649 }
650
651
652 /*--------------------------------------------------------------------------
653   Deallocate previously allocated memory.
654   --------------------------------------------------------------------------*/
655 static void w9968cf_deallocate_memory(struct w9968cf_device* cam)
656 {
657         u8 i;
658
659         /* Free the isochronous transfer buffers */
660         for (i = 0; i < W9968CF_URBS; i++) {
661                 kfree(cam->transfer_buffer[i]);
662                 cam->transfer_buffer[i] = NULL;
663         }
664
665         /* Free temporary frame buffer */
666         if (cam->frame_tmp.buffer) {
667                 rvfree(cam->frame_tmp.buffer, cam->frame_tmp.size);
668                 cam->frame_tmp.buffer = NULL;
669         }
670
671         /* Free helper buffer */
672         if (cam->frame_vpp.buffer) {
673                 rvfree(cam->frame_vpp.buffer, cam->frame_vpp.size);
674                 cam->frame_vpp.buffer = NULL;
675         }
676
677         /* Free video frame buffers */
678         if (cam->frame[0].buffer) {
679                 rvfree(cam->frame[0].buffer, cam->nbuffers*cam->frame[0].size);
680                 cam->frame[0].buffer = NULL;
681         }
682
683         cam->nbuffers = 0;
684
685         DBG(5, "Memory successfully deallocated")
686 }
687
688
689 /*--------------------------------------------------------------------------
690   Allocate memory buffers for USB transfers and video frames.
691   This function is called by open() only.
692   Return 0 on success, a negative number otherwise.
693   --------------------------------------------------------------------------*/
694 static int w9968cf_allocate_memory(struct w9968cf_device* cam)
695 {
696         const u16 p_size = wMaxPacketSize[cam->altsetting-1];
697         void* buff = NULL;
698         unsigned long hw_bufsize, vpp_bufsize;
699         u8 i, bpp;
700
701         /* NOTE: Deallocation is done elsewhere in case of error */
702
703         /* Calculate the max amount of raw data per frame from the device */
704         hw_bufsize = cam->maxwidth*cam->maxheight*2;
705
706         /* Calculate the max buf. size needed for post-processing routines */
707         bpp = (w9968cf_vpp) ? 4 : 2;
708         if (cam->upscaling)
709                 vpp_bufsize = max(W9968CF_MAX_WIDTH*W9968CF_MAX_HEIGHT*bpp,
710                                   cam->maxwidth*cam->maxheight*bpp);
711         else
712                 vpp_bufsize = cam->maxwidth*cam->maxheight*bpp;
713
714         /* Allocate memory for the isochronous transfer buffers */
715         for (i = 0; i < W9968CF_URBS; i++) {
716                 if (!(cam->transfer_buffer[i] =
717                       kmalloc(W9968CF_ISO_PACKETS*p_size, GFP_KERNEL))) {
718                         DBG(1, "Couldn't allocate memory for the isochronous "
719                                "transfer buffers (%u bytes)", 
720                             p_size * W9968CF_ISO_PACKETS)
721                         return -ENOMEM;
722                 }
723                 memset(cam->transfer_buffer[i], 0, W9968CF_ISO_PACKETS*p_size);
724         }
725
726         /* Allocate memory for the temporary frame buffer */
727         if (!(cam->frame_tmp.buffer = rvmalloc(hw_bufsize))) {
728                 DBG(1, "Couldn't allocate memory for the temporary "
729                        "video frame buffer (%lu bytes)", hw_bufsize)
730                 return -ENOMEM;
731         }
732         cam->frame_tmp.size = hw_bufsize;
733         cam->frame_tmp.number = -1;
734
735         /* Allocate memory for the helper buffer */
736         if (w9968cf_vpp) {
737                 if (!(cam->frame_vpp.buffer = rvmalloc(vpp_bufsize))) {
738                         DBG(1, "Couldn't allocate memory for the helper buffer"
739                                " (%lu bytes)", vpp_bufsize)
740                         return -ENOMEM;
741                 }
742                 cam->frame_vpp.size = vpp_bufsize;
743         } else
744                 cam->frame_vpp.buffer = NULL;
745
746         /* Allocate memory for video frame buffers */
747         cam->nbuffers = cam->max_buffers;
748         while (cam->nbuffers >= 2) {
749                 if ((buff = rvmalloc(cam->nbuffers * vpp_bufsize)))
750                         break;
751                 else
752                         cam->nbuffers--;
753         }
754
755         if (!buff) {
756                 DBG(1, "Couldn't allocate memory for the video frame buffers")
757                 cam->nbuffers = 0;
758                 return -ENOMEM;
759         }
760
761         if (cam->nbuffers != cam->max_buffers)
762                 DBG(2, "Couldn't allocate memory for %u video frame buffers. "
763                        "Only memory for %u buffers has been allocated",
764                     cam->max_buffers, cam->nbuffers)
765
766         for (i = 0; i < cam->nbuffers; i++) {
767                 cam->frame[i].buffer = buff + i*vpp_bufsize;
768                 cam->frame[i].size = vpp_bufsize;
769                 cam->frame[i].number = i;
770                 /* Circular list */
771                 if (i != cam->nbuffers-1)
772                         cam->frame[i].next = &cam->frame[i+1];
773                 else
774                         cam->frame[i].next = &cam->frame[0];
775                 cam->frame[i].status = F_UNUSED;
776         }
777
778         DBG(5, "Memory successfully allocated")
779         return 0;
780 }
781
782
783
784 /****************************************************************************
785  * USB-specific functions                                                   *
786  ****************************************************************************/
787
788 /*--------------------------------------------------------------------------
789   This is an handler function which is called after the URBs are completed.
790   It collects multiple data packets coming from the camera by putting them
791   into frame buffers: one or more zero data length data packets are used to
792   mark the end of a video frame; the first non-zero data packet is the start
793   of the next video frame; if an error is encountered in a packet, the entire
794   video frame is discarded and grabbed again.
795   If there are no requested frames in the FIFO list, packets are collected into
796   a temporary buffer. 
797   --------------------------------------------------------------------------*/
798 static void w9968cf_urb_complete(struct urb *urb, struct pt_regs *regs)
799 {
800         struct w9968cf_device* cam = (struct w9968cf_device*)urb->context;
801         struct w9968cf_frame_t** f;
802         unsigned int len, status;
803         void* pos;
804         u8 i;
805         int err = 0;
806
807         if ((!cam->streaming) || cam->disconnected) {
808                 DBG(4, "Got interrupt, but not streaming")
809                 return;
810         }
811
812         /* "(*f)" will be used instead of "cam->frame_current" */
813         f = &cam->frame_current;
814
815         /* If a frame has been requested and we are grabbing into  
816            the temporary frame, we'll switch to that requested frame */
817         if ((*f) == &cam->frame_tmp && *cam->requested_frame) {
818                 if (cam->frame_tmp.status == F_GRABBING) {
819                         w9968cf_pop_frame(cam, &cam->frame_current);
820                         (*f)->status = F_GRABBING;
821                         (*f)->length = cam->frame_tmp.length;
822                         memcpy((*f)->buffer, cam->frame_tmp.buffer,
823                                (*f)->length);
824                         DBG(6, "Switched from temp. frame to frame #%d", 
825                             (*f)->number)
826                 }
827         }
828
829         for (i = 0; i < urb->number_of_packets; i++) {
830                 len = urb->iso_frame_desc[i].actual_length;
831                 status = urb->iso_frame_desc[i].status;
832                 pos = urb->iso_frame_desc[i].offset + urb->transfer_buffer;
833
834                 if (status && len != 0) {
835                         DBG(4, "URB failed, error in data packet "
836                                "(error #%u, %s)",
837                             status, symbolic(urb_errlist, status))
838                         (*f)->status = F_ERROR;
839                         continue;
840                 }
841
842                 if (len) { /* start of frame */
843
844                         if ((*f)->status == F_UNUSED) {
845                                 (*f)->status = F_GRABBING;
846                                 (*f)->length = 0;
847                         }
848
849                         /* Buffer overflows shouldn't happen, however...*/
850                         if ((*f)->length + len > (*f)->size) {
851                                 DBG(4, "Buffer overflow: bad data packets")
852                                 (*f)->status = F_ERROR;
853                         }
854
855                         if ((*f)->status == F_GRABBING) {
856                                 memcpy((*f)->buffer + (*f)->length, pos, len);
857                                 (*f)->length += len;
858                         }
859
860                 } else if ((*f)->status == F_GRABBING) { /* end of frame */
861
862                         DBG(6, "Frame #%d successfully grabbed", (*f)->number)
863
864                         if (cam->vpp_flag & VPP_DECOMPRESSION) {
865                                 err = w9968cf_vpp->check_headers((*f)->buffer,
866                                                                  (*f)->length);
867                                 if (err) {
868                                         DBG(4, "Skip corrupted frame: %s",
869                                             symbolic(decoder_errlist, err))
870                                         (*f)->status = F_UNUSED;
871                                         continue; /* grab this frame again */
872                                 }
873                         }
874
875                         (*f)->status = F_READY;
876                         (*f)->queued = 0;
877
878                         /* Take a pointer to the new frame from the FIFO list.
879                            If the list is empty,we'll use the temporary frame*/
880                         if (*cam->requested_frame)
881                                 w9968cf_pop_frame(cam, &cam->frame_current);
882                         else {
883                                 cam->frame_current = &cam->frame_tmp;
884                                 (*f)->status = F_UNUSED;
885                         }
886
887                 } else if ((*f)->status == F_ERROR)
888                         (*f)->status = F_UNUSED; /* grab it again */
889
890                 PDBGG("Frame length %lu | pack.#%u | pack.len. %u | state %d",
891                       (unsigned long)(*f)->length, i, len, (*f)->status)
892
893         } /* end for */
894
895         /* Resubmit this URB */
896         urb->dev = cam->usbdev;
897         urb->status = 0;
898         spin_lock(&cam->urb_lock);
899         if (cam->streaming)
900                 if ((err = usb_submit_urb(urb, GFP_ATOMIC))) {
901                         cam->misconfigured = 1;
902                         DBG(1, "Couldn't resubmit the URB: error %d, %s",
903                             err, symbolic(urb_errlist, err))
904                 }
905         spin_unlock(&cam->urb_lock);
906
907         /* Wake up the user process */
908         wake_up_interruptible(&cam->wait_queue);
909 }
910
911
912 /*---------------------------------------------------------------------------
913   Setup the URB structures for the isochronous transfer.
914   Submit the URBs so that the data transfer begins.
915   Return 0 on success, a negative number otherwise.
916   ---------------------------------------------------------------------------*/
917 static int w9968cf_start_transfer(struct w9968cf_device* cam)
918 {
919         struct usb_device *udev = cam->usbdev;
920         struct urb* urb;
921         const u16 p_size = wMaxPacketSize[cam->altsetting-1];
922         u16 w, h, d;
923         int vidcapt;
924         u32 t_size;
925         int err = 0;
926         s8 i, j;
927
928         for (i = 0; i < W9968CF_URBS; i++) {
929                 urb = usb_alloc_urb(W9968CF_ISO_PACKETS, GFP_KERNEL);
930                 cam->urb[i] = urb;
931                 if (!urb) {
932                         for (j = 0; j < i; j++)
933                                 usb_free_urb(cam->urb[j]);
934                         DBG(1, "Couldn't allocate the URB structures")
935                         return -ENOMEM;
936                 }
937
938                 urb->dev = udev;
939                 urb->context = (void*)cam;
940                 urb->pipe = usb_rcvisocpipe(udev, 1);
941                 urb->transfer_flags = URB_ISO_ASAP;
942                 urb->number_of_packets = W9968CF_ISO_PACKETS;
943                 urb->complete = w9968cf_urb_complete;
944                 urb->transfer_buffer = cam->transfer_buffer[i];
945                 urb->transfer_buffer_length = p_size*W9968CF_ISO_PACKETS;
946                 urb->interval = 1;
947                 for (j = 0; j < W9968CF_ISO_PACKETS; j++) {
948                         urb->iso_frame_desc[j].offset = p_size*j;
949                         urb->iso_frame_desc[j].length = p_size;
950                 }
951         }
952
953         /* Transfer size per frame, in WORD ! */
954         d = cam->hw_depth;
955         w = cam->hw_width;
956         h = cam->hw_height;
957
958         t_size = (w*h*d)/16;
959
960         err = w9968cf_write_reg(cam, 0xbf17, 0x00); /* reset everything */
961         err += w9968cf_write_reg(cam, 0xbf10, 0x00); /* normal operation */
962
963         /* Transfer size */
964         err += w9968cf_write_reg(cam, t_size & 0xffff, 0x3d); /* low bits */
965         err += w9968cf_write_reg(cam, t_size >> 16, 0x3e);    /* high bits */
966
967         if (cam->vpp_flag & VPP_DECOMPRESSION)
968                 err += w9968cf_upload_quantizationtables(cam);
969
970         vidcapt = w9968cf_read_reg(cam, 0x16); /* read picture settings */
971         err += w9968cf_write_reg(cam, vidcapt|0x8000, 0x16); /* capt. enable */
972
973         err += usb_set_interface(udev, 0, cam->altsetting);
974         err += w9968cf_write_reg(cam, 0x8a05, 0x3c); /* USB FIFO enable */
975
976         if (err || (vidcapt < 0)) {
977                 for (i = 0; i < W9968CF_URBS; i++)
978                         usb_free_urb(cam->urb[i]);
979                 DBG(1, "Couldn't tell the camera to start the data transfer")
980                 return err;
981         }
982
983         w9968cf_init_framelist(cam);
984
985         /* Begin to grab into the temporary buffer */
986         cam->frame_tmp.status = F_UNUSED;
987         cam->frame_tmp.queued = 0;
988         cam->frame_current = &cam->frame_tmp;
989
990         if (!(cam->vpp_flag & VPP_DECOMPRESSION))
991                 DBG(5, "Isochronous transfer size: %lu bytes/frame", 
992                     (unsigned long)t_size*2)
993
994         DBG(5, "Starting the isochronous transfer...")
995
996         cam->streaming = 1;
997
998         /* Submit the URBs */
999         for (i = 0; i < W9968CF_URBS; i++) {
1000                 err = usb_submit_urb(cam->urb[i], GFP_KERNEL);
1001                 if (err) {
1002                         cam->streaming = 0;
1003                         for (j = i-1; j >= 0; j--) {
1004                                 usb_kill_urb(cam->urb[j]);
1005                                 usb_free_urb(cam->urb[j]);
1006                         }
1007                         DBG(1, "Couldn't send a transfer request to the "
1008                                "USB core (error #%d, %s)", err, 
1009                             symbolic(urb_errlist, err))
1010                         return err;
1011                 }
1012         }
1013
1014         return 0;
1015 }
1016
1017
1018 /*--------------------------------------------------------------------------
1019   Stop the isochronous transfer and set alternate setting to 0 (0Mb/s).
1020   Return 0 on success, a negative number otherwise.
1021   --------------------------------------------------------------------------*/
1022 static int w9968cf_stop_transfer(struct w9968cf_device* cam)
1023 {
1024         struct usb_device *udev = cam->usbdev;
1025         unsigned long lock_flags;
1026         int err = 0;
1027         s8 i;
1028
1029         if (!cam->streaming)
1030                 return 0;
1031
1032         /* This avoids race conditions with usb_submit_urb() 
1033            in the URB completition handler */
1034         spin_lock_irqsave(&cam->urb_lock, lock_flags);
1035         cam->streaming = 0;
1036         spin_unlock_irqrestore(&cam->urb_lock, lock_flags);
1037
1038         for (i = W9968CF_URBS-1; i >= 0; i--)
1039                 if (cam->urb[i]) {
1040                         usb_kill_urb(cam->urb[i]);
1041                         usb_free_urb(cam->urb[i]);
1042                         cam->urb[i] = NULL;
1043                 }
1044
1045         if (cam->disconnected)
1046                 goto exit;
1047
1048         err = w9968cf_write_reg(cam, 0x0a05, 0x3c); /* stop USB transfer */
1049         err += usb_set_interface(udev, 0, 0); /* 0 Mb/s */
1050         err += w9968cf_write_reg(cam, 0x0000, 0x39); /* disable JPEG encoder */
1051         err += w9968cf_write_reg(cam, 0x0000, 0x16); /* stop video capture */
1052
1053         if (err) {
1054                 DBG(2, "Failed to tell the camera to stop the isochronous "
1055                        "transfer. However this is not a critical error.")
1056                 return -EIO;
1057         }
1058
1059 exit:
1060         DBG(5, "Isochronous transfer stopped")
1061         return 0;
1062 }
1063
1064
1065 /*--------------------------------------------------------------------------
1066   Write a W9968CF register. 
1067   Return 0 on success, -1 otherwise.
1068   --------------------------------------------------------------------------*/
1069 static int w9968cf_write_reg(struct w9968cf_device* cam, u16 value, u16 index)
1070 {
1071         struct usb_device* udev = cam->usbdev;
1072         int res;
1073
1074         res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0,
1075                               USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE,
1076                               value, index, NULL, 0, W9968CF_USB_CTRL_TIMEOUT);
1077
1078         if (res < 0)
1079                 DBG(4, "Failed to write a register "
1080                        "(value 0x%04X, index 0x%02X, error #%d, %s)",
1081                     value, index, res, symbolic(urb_errlist, res))
1082
1083         return (res >= 0) ? 0 : -1;
1084 }
1085
1086
1087 /*--------------------------------------------------------------------------
1088   Read a W9968CF register. 
1089   Return the register value on success, -1 otherwise.
1090   --------------------------------------------------------------------------*/
1091 static int w9968cf_read_reg(struct w9968cf_device* cam, u16 index)
1092 {
1093         struct usb_device* udev = cam->usbdev;
1094         u16* buff = cam->control_buffer;
1095         int res;
1096
1097         res = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 1,
1098                               USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
1099                               0, index, buff, 2, W9968CF_USB_CTRL_TIMEOUT);
1100
1101         if (res < 0)
1102                 DBG(4, "Failed to read a register "
1103                        "(index 0x%02X, error #%d, %s)",
1104                     index, res, symbolic(urb_errlist, res))
1105
1106         return (res >= 0) ? (int)(*buff) : -1;
1107 }
1108
1109
1110 /*--------------------------------------------------------------------------
1111   Write 64-bit data to the fast serial bus registers.
1112   Return 0 on success, -1 otherwise.
1113   --------------------------------------------------------------------------*/
1114 static int w9968cf_write_fsb(struct w9968cf_device* cam, u16* data)
1115 {
1116         struct usb_device* udev = cam->usbdev;
1117         u16 value;
1118         int res;
1119
1120         value = *data++;
1121
1122         res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0,
1123                               USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE,
1124                               value, 0x06, data, 6, W9968CF_USB_CTRL_TIMEOUT);
1125
1126         if (res < 0)
1127                 DBG(4, "Failed to write the FSB registers "
1128                        "(error #%d, %s)", res, symbolic(urb_errlist, res))
1129
1130         return (res >= 0) ? 0 : -1;
1131 }
1132
1133
1134 /*--------------------------------------------------------------------------
1135   Write data to the serial bus control register.
1136   Return 0 on success, a negative number otherwise.
1137   --------------------------------------------------------------------------*/
1138 static int w9968cf_write_sb(struct w9968cf_device* cam, u16 value)
1139 {
1140         int err = 0;
1141
1142         err = w9968cf_write_reg(cam, value, 0x01);
1143         udelay(W9968CF_I2C_BUS_DELAY);
1144
1145         return err;
1146 }
1147
1148
1149 /*--------------------------------------------------------------------------
1150   Read data from the serial bus control register.
1151   Return 0 on success, a negative number otherwise.
1152   --------------------------------------------------------------------------*/
1153 static int w9968cf_read_sb(struct w9968cf_device* cam)
1154 {
1155         int v = 0;
1156
1157         v = w9968cf_read_reg(cam, 0x01);
1158         udelay(W9968CF_I2C_BUS_DELAY);
1159
1160         return v;
1161 }
1162
1163
1164 /*--------------------------------------------------------------------------
1165   Upload quantization tables for the JPEG compression.
1166   This function is called by w9968cf_start_transfer().
1167   Return 0 on success, a negative number otherwise.
1168   --------------------------------------------------------------------------*/
1169 static int w9968cf_upload_quantizationtables(struct w9968cf_device* cam)
1170 {
1171         u16 a, b;
1172         int err = 0, i, j;
1173
1174         err += w9968cf_write_reg(cam, 0x0010, 0x39); /* JPEG clock enable */
1175
1176         for (i = 0, j = 0; i < 32; i++, j += 2) {
1177                 a = Y_QUANTABLE[j] | ((unsigned)(Y_QUANTABLE[j+1]) << 8);
1178                 b = UV_QUANTABLE[j] | ((unsigned)(UV_QUANTABLE[j+1]) << 8);
1179                 err += w9968cf_write_reg(cam, a, 0x40+i);
1180                 err += w9968cf_write_reg(cam, b, 0x60+i);
1181         }
1182         err += w9968cf_write_reg(cam, 0x0012, 0x39); /* JPEG encoder enable */
1183
1184         return err;
1185 }
1186
1187
1188
1189 /****************************************************************************
1190  * Low-level I2C I/O functions.                                             *
1191  * The adapter supports the following I2C transfer functions:               *
1192  * i2c_adap_fastwrite_byte_data() (at 400 kHz bit frequency only)           *
1193  * i2c_adap_read_byte_data()                                                *
1194  * i2c_adap_read_byte()                                                     *
1195  ****************************************************************************/
1196
1197 static int w9968cf_smbus_start(struct w9968cf_device* cam)
1198 {
1199         int err = 0;
1200
1201         err += w9968cf_write_sb(cam, 0x0011); /* SDE=1, SDA=0, SCL=1 */
1202         err += w9968cf_write_sb(cam, 0x0010); /* SDE=1, SDA=0, SCL=0 */
1203
1204         return err;
1205 }
1206
1207
1208 static int w9968cf_smbus_stop(struct w9968cf_device* cam)
1209 {
1210         int err = 0;
1211
1212         err += w9968cf_write_sb(cam, 0x0011); /* SDE=1, SDA=0, SCL=1 */
1213         err += w9968cf_write_sb(cam, 0x0013); /* SDE=1, SDA=1, SCL=1 */
1214
1215         return err;
1216 }
1217
1218
1219 static int w9968cf_smbus_write_byte(struct w9968cf_device* cam, u8 v)
1220 {
1221         u8 bit;
1222         int err = 0, sda;
1223
1224         for (bit = 0 ; bit < 8 ; bit++) {
1225                 sda = (v & 0x80) ? 2 : 0;
1226                 v <<= 1;
1227                 /* SDE=1, SDA=sda, SCL=0 */
1228                 err += w9968cf_write_sb(cam, 0x10 | sda);
1229                 /* SDE=1, SDA=sda, SCL=1 */
1230                 err += w9968cf_write_sb(cam, 0x11 | sda);
1231                 /* SDE=1, SDA=sda, SCL=0 */
1232                 err += w9968cf_write_sb(cam, 0x10 | sda);
1233         }
1234
1235         return err;
1236 }
1237
1238
1239 static int w9968cf_smbus_read_byte(struct w9968cf_device* cam, u8* v)
1240 {
1241         u8 bit;
1242         int err = 0;
1243
1244         *v = 0;
1245         for (bit = 0 ; bit < 8 ; bit++) {
1246                 *v <<= 1;
1247                 err += w9968cf_write_sb(cam, 0x0013);
1248                 *v |= (w9968cf_read_sb(cam) & 0x0008) ? 1 : 0;
1249                 err += w9968cf_write_sb(cam, 0x0012);
1250         }
1251
1252         return err;
1253 }
1254
1255
1256 static int w9968cf_smbus_write_ack(struct w9968cf_device* cam)
1257 {
1258         int err = 0;
1259
1260         err += w9968cf_write_sb(cam, 0x0010); /* SDE=1, SDA=0, SCL=0 */
1261         err += w9968cf_write_sb(cam, 0x0011); /* SDE=1, SDA=0, SCL=1 */
1262         err += w9968cf_write_sb(cam, 0x0010); /* SDE=1, SDA=0, SCL=0 */
1263
1264         return err;
1265 }
1266
1267
1268 static int w9968cf_smbus_read_ack(struct w9968cf_device* cam)
1269 {
1270         int err = 0, sda;
1271
1272         err += w9968cf_write_sb(cam, 0x0013); /* SDE=1, SDA=1, SCL=1 */
1273         sda = (w9968cf_read_sb(cam) & 0x08) ? 1 : 0; /* sda = SDA */
1274         err += w9968cf_write_sb(cam, 0x0012); /* SDE=1, SDA=1, SCL=0 */
1275         if (sda < 0)
1276                 err += sda;
1277         if (sda == 1) {
1278                 DBG(6, "Couldn't receive the ACK")
1279                 err += -1;
1280         }
1281
1282         return err;
1283 }
1284
1285
1286 /* This seems to refresh the communication through the serial bus */
1287 static int w9968cf_smbus_refresh_bus(struct w9968cf_device* cam)
1288 {
1289         int err = 0, j;
1290
1291         for (j = 1; j <= 10; j++) {
1292                 err = w9968cf_write_reg(cam, 0x0020, 0x01);
1293                 err += w9968cf_write_reg(cam, 0x0000, 0x01);
1294                 if (err)
1295                         break;
1296         }
1297
1298         return err;
1299 }
1300
1301
1302 /* SMBus protocol: S Addr Wr [A] Subaddr [A] Value [A] P */
1303 static int 
1304 w9968cf_i2c_adap_fastwrite_byte_data(struct w9968cf_device* cam, 
1305                                      u16 address, u8 subaddress,u8 value)
1306 {
1307         u16* data = cam->data_buffer;
1308         int err = 0;
1309
1310         err += w9968cf_smbus_refresh_bus(cam);
1311
1312         /* Enable SBUS outputs */
1313         err += w9968cf_write_sb(cam, 0x0020);
1314
1315         data[0] = 0x082f | ((address & 0x80) ? 0x1500 : 0x0);
1316         data[0] |= (address & 0x40) ? 0x4000 : 0x0;
1317         data[1] = 0x2082 | ((address & 0x40) ? 0x0005 : 0x0);
1318         data[1] |= (address & 0x20) ? 0x0150 : 0x0;
1319         data[1] |= (address & 0x10) ? 0x5400 : 0x0;
1320         data[2] = 0x8208 | ((address & 0x08) ? 0x0015 : 0x0);
1321         data[2] |= (address & 0x04) ? 0x0540 : 0x0;
1322         data[2] |= (address & 0x02) ? 0x5000 : 0x0;
1323         data[3] = 0x1d20 | ((address & 0x02) ? 0x0001 : 0x0);
1324         data[3] |= (address & 0x01) ? 0x0054 : 0x0;
1325
1326         err += w9968cf_write_fsb(cam, data);
1327
1328         data[0] = 0x8208 | ((subaddress & 0x80) ? 0x0015 : 0x0);
1329         data[0] |= (subaddress & 0x40) ? 0x0540 : 0x0;
1330         data[0] |= (subaddress & 0x20) ? 0x5000 : 0x0;
1331         data[1] = 0x0820 | ((subaddress & 0x20) ? 0x0001 : 0x0);
1332         data[1] |= (subaddress & 0x10) ? 0x0054 : 0x0;
1333         data[1] |= (subaddress & 0x08) ? 0x1500 : 0x0;
1334         data[1] |= (subaddress & 0x04) ? 0x4000 : 0x0;
1335         data[2] = 0x2082 | ((subaddress & 0x04) ? 0x0005 : 0x0);
1336         data[2] |= (subaddress & 0x02) ? 0x0150 : 0x0;
1337         data[2] |= (subaddress & 0x01) ? 0x5400 : 0x0;
1338         data[3] = 0x001d;
1339
1340         err += w9968cf_write_fsb(cam, data);
1341
1342         data[0] = 0x8208 | ((value & 0x80) ? 0x0015 : 0x0);
1343         data[0] |= (value & 0x40) ? 0x0540 : 0x0;
1344         data[0] |= (value & 0x20) ? 0x5000 : 0x0;
1345         data[1] = 0x0820 | ((value & 0x20) ? 0x0001 : 0x0);
1346         data[1] |= (value & 0x10) ? 0x0054 : 0x0;
1347         data[1] |= (value & 0x08) ? 0x1500 : 0x0;
1348         data[1] |= (value & 0x04) ? 0x4000 : 0x0;
1349         data[2] = 0x2082 | ((value & 0x04) ? 0x0005 : 0x0);
1350         data[2] |= (value & 0x02) ? 0x0150 : 0x0;
1351         data[2] |= (value & 0x01) ? 0x5400 : 0x0;
1352         data[3] = 0xfe1d;
1353
1354         err += w9968cf_write_fsb(cam, data);
1355
1356         /* Disable SBUS outputs */
1357         err += w9968cf_write_sb(cam, 0x0000);
1358
1359         if (!err)
1360                 DBG(5, "I2C write byte data done, addr.0x%04X, subaddr.0x%02X "
1361                        "value 0x%02X", address, subaddress, value)
1362         else
1363                 DBG(5, "I2C write byte data failed, addr.0x%04X, "
1364                        "subaddr.0x%02X, value 0x%02X", 
1365                     address, subaddress, value)
1366
1367         return err;
1368 }
1369
1370
1371 /* SMBus protocol: S Addr Wr [A] Subaddr [A] P S Addr+1 Rd [A] [Value] NA P */
1372 static int 
1373 w9968cf_i2c_adap_read_byte_data(struct w9968cf_device* cam, 
1374                                 u16 address, u8 subaddress, 
1375                                 u8* value)
1376 {
1377         int err = 0;
1378
1379         /* Serial data enable */
1380         err += w9968cf_write_sb(cam, 0x0013); /* don't change ! */
1381
1382         err += w9968cf_smbus_start(cam);
1383         err += w9968cf_smbus_write_byte(cam, address);
1384         err += w9968cf_smbus_read_ack(cam);
1385         err += w9968cf_smbus_write_byte(cam, subaddress);
1386         err += w9968cf_smbus_read_ack(cam);
1387         err += w9968cf_smbus_stop(cam);
1388         err += w9968cf_smbus_start(cam);
1389         err += w9968cf_smbus_write_byte(cam, address + 1);
1390         err += w9968cf_smbus_read_ack(cam);
1391         err += w9968cf_smbus_read_byte(cam, value);
1392         err += w9968cf_smbus_write_ack(cam);
1393         err += w9968cf_smbus_stop(cam);
1394
1395         /* Serial data disable */
1396         err += w9968cf_write_sb(cam, 0x0000);
1397
1398         if (!err)
1399                 DBG(5, "I2C read byte data done, addr.0x%04X, "
1400                        "subaddr.0x%02X, value 0x%02X", 
1401                     address, subaddress, *value)
1402         else
1403                 DBG(5, "I2C read byte data failed, addr.0x%04X, "
1404                        "subaddr.0x%02X, wrong value 0x%02X",
1405                     address, subaddress, *value)
1406
1407         return err;
1408 }
1409
1410
1411 /* SMBus protocol: S Addr+1 Rd [A] [Value] NA P */
1412 static int 
1413 w9968cf_i2c_adap_read_byte(struct w9968cf_device* cam,
1414                            u16 address, u8* value)
1415 {
1416         int err = 0;
1417
1418         /* Serial data enable */
1419         err += w9968cf_write_sb(cam, 0x0013);
1420
1421         err += w9968cf_smbus_start(cam);
1422         err += w9968cf_smbus_write_byte(cam, address + 1);
1423         err += w9968cf_smbus_read_ack(cam);
1424         err += w9968cf_smbus_read_byte(cam, value);
1425         err += w9968cf_smbus_write_ack(cam);
1426         err += w9968cf_smbus_stop(cam);
1427  
1428         /* Serial data disable */
1429         err += w9968cf_write_sb(cam, 0x0000);
1430
1431         if (!err)
1432                 DBG(5, "I2C read byte done, addr.0x%04X, "
1433                        "value 0x%02X", address, *value)
1434         else
1435                 DBG(5, "I2C read byte failed, addr.0x%04X, "
1436                        "wrong value 0x%02X", address, *value)
1437
1438         return err;
1439 }
1440
1441
1442 /* SMBus protocol: S Addr Wr [A] Value [A] P */
1443 static int 
1444 w9968cf_i2c_adap_write_byte(struct w9968cf_device* cam,
1445                             u16 address, u8 value)
1446 {
1447         DBG(4, "i2c_write_byte() is an unsupported transfer mode")
1448         return -EINVAL;
1449 }
1450
1451
1452
1453 /****************************************************************************
1454  * I2C interface to kernel                                                  *
1455  ****************************************************************************/
1456
1457 static int
1458 w9968cf_i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr, 
1459                        unsigned short flags, char read_write, u8 command,
1460                        int size, union i2c_smbus_data *data)
1461 {
1462         struct w9968cf_device* cam = i2c_get_adapdata(adapter);
1463         u8 i;
1464         int err = 0; 
1465
1466         switch (addr) {
1467                 case OV6xx0_SID:
1468                 case OV7xx0_SID:
1469                         break;
1470                 default:
1471                         DBG(4, "Rejected slave ID 0x%04X", addr)
1472                         return -EINVAL;
1473         }
1474
1475         if (size == I2C_SMBUS_BYTE) {
1476                 /* Why addr <<= 1? See OVXXX0_SID defines in ovcamchip.h */
1477                 addr <<= 1;
1478
1479                 if (read_write == I2C_SMBUS_WRITE)
1480                         err = w9968cf_i2c_adap_write_byte(cam, addr, command);
1481                 else if (read_write == I2C_SMBUS_READ) 
1482                         err = w9968cf_i2c_adap_read_byte(cam,addr,&data->byte);
1483
1484         } else if (size == I2C_SMBUS_BYTE_DATA) {
1485                 addr <<= 1;
1486
1487                 if (read_write == I2C_SMBUS_WRITE)
1488                         err = w9968cf_i2c_adap_fastwrite_byte_data(cam, addr,
1489                                                           command, data->byte);
1490                 else if (read_write == I2C_SMBUS_READ) {
1491                         for (i = 1; i <= W9968CF_I2C_RW_RETRIES; i++) {
1492                                 err = w9968cf_i2c_adap_read_byte_data(cam,addr,
1493                                                          command, &data->byte);
1494                                 if (err) {
1495                                         if (w9968cf_smbus_refresh_bus(cam)) {
1496                                                 err = -EIO;
1497                                                 break;
1498                                         }
1499                                 } else
1500                                         break;
1501                         }
1502
1503                 } else
1504                         return -EINVAL;
1505
1506         } else {
1507                 DBG(4, "Unsupported I2C transfer mode (%d)", size)
1508                 return -EINVAL;
1509         }
1510
1511         return err;
1512 }
1513
1514
1515 static u32 w9968cf_i2c_func(struct i2c_adapter* adap)
1516 {
1517         return I2C_FUNC_SMBUS_READ_BYTE |
1518                I2C_FUNC_SMBUS_READ_BYTE_DATA  |
1519                I2C_FUNC_SMBUS_WRITE_BYTE_DATA;
1520 }
1521
1522
1523 static int w9968cf_i2c_attach_inform(struct i2c_client* client)
1524 {
1525         struct w9968cf_device* cam = i2c_get_adapdata(client->adapter);
1526         const char* clientname = i2c_clientname(client);
1527         int id = client->driver->id, err = 0;
1528
1529         if (id == I2C_DRIVERID_OVCAMCHIP) {
1530                 cam->sensor_client = client;
1531                 err = w9968cf_sensor_init(cam);
1532                 if (err) {
1533                         cam->sensor_client = NULL;
1534                         return err;
1535                 }
1536         } else {
1537                 DBG(4, "Rejected client [%s] with driver [%s]", 
1538                     clientname, client->driver->name)
1539                 return -EINVAL;
1540         }
1541
1542         DBG(5, "I2C attach client [%s] with driver [%s]",
1543             clientname, client->driver->name)
1544
1545         return 0;
1546 }
1547
1548
1549 static int w9968cf_i2c_detach_inform(struct i2c_client* client)
1550 {
1551         struct w9968cf_device* cam = i2c_get_adapdata(client->adapter);
1552         const char* clientname = i2c_clientname(client);
1553
1554         if (cam->sensor_client == client)
1555                 cam->sensor_client = NULL;
1556
1557         DBG(5, "I2C detach client [%s]", clientname)
1558
1559         return 0;
1560 }
1561
1562
1563 static int 
1564 w9968cf_i2c_control(struct i2c_adapter* adapter, unsigned int cmd,
1565                     unsigned long arg)
1566 {
1567         return 0;
1568 }
1569
1570
1571 static int w9968cf_i2c_init(struct w9968cf_device* cam)
1572 {
1573         int err = 0;
1574
1575         static struct i2c_algorithm algo = {
1576                 .smbus_xfer =    w9968cf_i2c_smbus_xfer,
1577                 .algo_control =  w9968cf_i2c_control,
1578                 .functionality = w9968cf_i2c_func,
1579         };
1580
1581         static struct i2c_adapter adap = {
1582                 .id =                I2C_HW_SMBUS_W9968CF,
1583                 .class =             I2C_CLASS_CAM_DIGITAL,
1584                 .owner =             THIS_MODULE,
1585                 .client_register =   w9968cf_i2c_attach_inform,
1586                 .client_unregister = w9968cf_i2c_detach_inform,
1587                 .algo =              &algo,
1588         };
1589
1590         memcpy(&cam->i2c_adapter, &adap, sizeof(struct i2c_adapter));
1591         strcpy(cam->i2c_adapter.name, "w9968cf");
1592         i2c_set_adapdata(&cam->i2c_adapter, cam);
1593
1594         DBG(6, "Registering I2C adapter with kernel...")
1595
1596         err = i2c_add_adapter(&cam->i2c_adapter);
1597         if (err)
1598                 DBG(1, "Failed to register the I2C adapter")
1599         else
1600                 DBG(5, "I2C adapter registered")
1601
1602         return err;
1603 }
1604
1605
1606
1607 /****************************************************************************
1608  * Helper functions                                                         *
1609  ****************************************************************************/
1610
1611 /*--------------------------------------------------------------------------
1612   Turn on the LED on some webcams. A beep should be heard too.
1613   Return 0 on success, a negative number otherwise.
1614   --------------------------------------------------------------------------*/
1615 static int w9968cf_turn_on_led(struct w9968cf_device* cam)
1616 {
1617         int err = 0;
1618
1619         err += w9968cf_write_reg(cam, 0xff00, 0x00); /* power-down */
1620         err += w9968cf_write_reg(cam, 0xbf17, 0x00); /* reset everything */
1621         err += w9968cf_write_reg(cam, 0xbf10, 0x00); /* normal operation */
1622         err += w9968cf_write_reg(cam, 0x0010, 0x01); /* serial bus, SDS high */
1623         err += w9968cf_write_reg(cam, 0x0000, 0x01); /* serial bus, SDS low */
1624         err += w9968cf_write_reg(cam, 0x0010, 0x01); /* ..high 'beep-beep' */
1625
1626         if (err)
1627                 DBG(2, "Couldn't turn on the LED")
1628
1629         DBG(5, "LED turned on")
1630
1631         return err;
1632 }
1633
1634
1635 /*--------------------------------------------------------------------------
1636   Write some registers for the device initialization.
1637   This function is called once on open().
1638   Return 0 on success, a negative number otherwise.
1639   --------------------------------------------------------------------------*/
1640 static int w9968cf_init_chip(struct w9968cf_device* cam)
1641 {
1642         unsigned long hw_bufsize = cam->maxwidth*cam->maxheight*2,
1643                       y0 = 0x0000,
1644                       u0 = y0 + hw_bufsize/2,
1645                       v0 = u0 + hw_bufsize/4,
1646                       y1 = v0 + hw_bufsize/4,
1647                       u1 = y1 + hw_bufsize/2,
1648                       v1 = u1 + hw_bufsize/4;
1649         int err = 0;
1650
1651         err += w9968cf_write_reg(cam, 0xff00, 0x00); /* power off */
1652         err += w9968cf_write_reg(cam, 0xbf10, 0x00); /* power on */
1653
1654         err += w9968cf_write_reg(cam, 0x405d, 0x03); /* DRAM timings */
1655         err += w9968cf_write_reg(cam, 0x0030, 0x04); /* SDRAM timings */
1656
1657         err += w9968cf_write_reg(cam, y0 & 0xffff, 0x20); /* Y buf.0, low */
1658         err += w9968cf_write_reg(cam, y0 >> 16, 0x21);    /* Y buf.0, high */
1659         err += w9968cf_write_reg(cam, u0 & 0xffff, 0x24); /* U buf.0, low */
1660         err += w9968cf_write_reg(cam, u0 >> 16, 0x25);    /* U buf.0, high */
1661         err += w9968cf_write_reg(cam, v0 & 0xffff, 0x28); /* V buf.0, low */
1662         err += w9968cf_write_reg(cam, v0 >> 16, 0x29);    /* V buf.0, high */
1663
1664         err += w9968cf_write_reg(cam, y1 & 0xffff, 0x22); /* Y buf.1, low */
1665         err += w9968cf_write_reg(cam, y1 >> 16, 0x23);    /* Y buf.1, high */
1666         err += w9968cf_write_reg(cam, u1 & 0xffff, 0x26); /* U buf.1, low */
1667         err += w9968cf_write_reg(cam, u1 >> 16, 0x27);    /* U buf.1, high */
1668         err += w9968cf_write_reg(cam, v1 & 0xffff, 0x2a); /* V buf.1, low */
1669         err += w9968cf_write_reg(cam, v1 >> 16, 0x2b);    /* V buf.1, high */
1670
1671         err += w9968cf_write_reg(cam, y1 & 0xffff, 0x32); /* JPEG buf 0 low */
1672         err += w9968cf_write_reg(cam, y1 >> 16, 0x33);    /* JPEG buf 0 high */
1673
1674         err += w9968cf_write_reg(cam, y1 & 0xffff, 0x34); /* JPEG buf 1 low */
1675         err += w9968cf_write_reg(cam, y1 >> 16, 0x35);    /* JPEG bug 1 high */
1676
1677         err += w9968cf_write_reg(cam, 0x0000, 0x36);/* JPEG restart interval */
1678         err += w9968cf_write_reg(cam, 0x0804, 0x37);/*JPEG VLE FIFO threshold*/
1679         err += w9968cf_write_reg(cam, 0x0000, 0x38);/* disable hw up-scaling */
1680         err += w9968cf_write_reg(cam, 0x0000, 0x3f); /* JPEG/MCTL test data */
1681
1682         err += w9968cf_set_picture(cam, cam->picture); /* this before */
1683         err += w9968cf_set_window(cam, cam->window);
1684
1685         if (err)
1686                 DBG(1, "Chip initialization failed")
1687         else
1688                 DBG(5, "Chip successfully initialized")
1689
1690         return err;
1691 }
1692
1693
1694 /*--------------------------------------------------------------------------
1695   Return non-zero if the palette is supported, 0 otherwise.
1696   --------------------------------------------------------------------------*/
1697 static inline u16 w9968cf_valid_palette(u16 palette)
1698 {
1699         u8 i = 0;
1700         while (w9968cf_formatlist[i].palette != 0) {
1701                 if (palette == w9968cf_formatlist[i].palette)
1702                         return palette;
1703                 i++;
1704         }
1705         return 0;
1706 }
1707
1708
1709 /*--------------------------------------------------------------------------
1710   Return the depth corresponding to the given palette.
1711   Palette _must_ be supported !
1712   --------------------------------------------------------------------------*/
1713 static inline u16 w9968cf_valid_depth(u16 palette)
1714 {
1715         u8 i=0;
1716         while (w9968cf_formatlist[i].palette != palette)
1717                 i++;
1718
1719         return w9968cf_formatlist[i].depth;
1720 }
1721
1722
1723 /*--------------------------------------------------------------------------
1724   Return non-zero if the format requires decompression, 0 otherwise.
1725   --------------------------------------------------------------------------*/
1726 static inline u8 w9968cf_need_decompression(u16 palette)
1727 {
1728         u8 i = 0;
1729         while (w9968cf_formatlist[i].palette != 0) {
1730                 if (palette == w9968cf_formatlist[i].palette)
1731                         return w9968cf_formatlist[i].compression;
1732                 i++;
1733         }
1734         return 0;
1735 }
1736
1737
1738 /*--------------------------------------------------------------------------
1739   Change the picture settings of the camera.
1740   Return 0 on success, a negative number otherwise.
1741   --------------------------------------------------------------------------*/
1742 static int
1743 w9968cf_set_picture(struct w9968cf_device* cam, struct video_picture pict)
1744 {
1745         u16 fmt, hw_depth, hw_palette, reg_v = 0x0000;
1746         int err = 0;
1747
1748         /* Make sure we are using a valid depth */
1749         pict.depth = w9968cf_valid_depth(pict.palette);
1750
1751         fmt = pict.palette;
1752
1753         hw_depth = pict.depth; /* depth used by the winbond chip */
1754         hw_palette = pict.palette; /* palette used by the winbond chip */
1755
1756         /* VS & HS polarities */
1757         reg_v = (cam->vs_polarity << 12) | (cam->hs_polarity << 11);
1758
1759         switch (fmt)
1760         {
1761                 case VIDEO_PALETTE_UYVY:
1762                         reg_v |= 0x0000;
1763                         cam->vpp_flag = VPP_NONE;
1764                         break;
1765                 case VIDEO_PALETTE_YUV422P:
1766                         reg_v |= 0x0002;
1767                         cam->vpp_flag = VPP_DECOMPRESSION;
1768                         break;
1769                 case VIDEO_PALETTE_YUV420:
1770                 case VIDEO_PALETTE_YUV420P:
1771                         reg_v |= 0x0003;
1772                         cam->vpp_flag = VPP_DECOMPRESSION;
1773                         break;
1774                 case VIDEO_PALETTE_YUYV:
1775                 case VIDEO_PALETTE_YUV422:
1776                         reg_v |= 0x0000;
1777                         cam->vpp_flag = VPP_SWAP_YUV_BYTES;
1778                         hw_palette = VIDEO_PALETTE_UYVY;
1779                         break;
1780                 /* Original video is used instead of RGBX palettes. 
1781                    Software conversion later. */
1782                 case VIDEO_PALETTE_GREY:
1783                 case VIDEO_PALETTE_RGB555:
1784                 case VIDEO_PALETTE_RGB565:
1785                 case VIDEO_PALETTE_RGB24:
1786                 case VIDEO_PALETTE_RGB32:
1787                         reg_v |= 0x0000; /* UYVY 16 bit is used */
1788                         hw_depth = 16;
1789                         hw_palette = VIDEO_PALETTE_UYVY;
1790                         cam->vpp_flag = VPP_UYVY_TO_RGBX;
1791                         break;
1792         }
1793
1794         /* NOTE: due to memory issues, it is better to disable the hardware
1795                  double buffering during compression */
1796         if (cam->double_buffer && !(cam->vpp_flag & VPP_DECOMPRESSION))
1797                 reg_v |= 0x0080;
1798
1799         if (cam->clamping)
1800                 reg_v |= 0x0020;
1801
1802         if (cam->filter_type == 1)
1803                 reg_v |= 0x0008;
1804         else if (cam->filter_type == 2)
1805                 reg_v |= 0x000c;
1806
1807         if ((err = w9968cf_write_reg(cam, reg_v, 0x16)))
1808                 goto error;
1809
1810         if ((err = w9968cf_sensor_update_picture(cam, pict)))
1811                 goto error;
1812
1813         /* If all went well, update the device data structure */
1814         memcpy(&cam->picture, &pict, sizeof(pict));
1815         cam->hw_depth = hw_depth;
1816         cam->hw_palette = hw_palette;
1817
1818         /* Settings changed, so we clear the frame buffers */
1819         memset(cam->frame[0].buffer, 0, cam->nbuffers*cam->frame[0].size);
1820
1821         DBG(4, "Palette is %s, depth is %u bpp",
1822             symbolic(v4l1_plist, pict.palette), pict.depth)
1823
1824         return 0;
1825
1826 error:
1827         DBG(1, "Failed to change picture settings")
1828         return err;
1829 }
1830
1831
1832 /*--------------------------------------------------------------------------
1833   Change the capture area size of the camera.
1834   This function _must_ be called _after_ w9968cf_set_picture().
1835   Return 0 on success, a negative number otherwise.
1836   --------------------------------------------------------------------------*/
1837 static int
1838 w9968cf_set_window(struct w9968cf_device* cam, struct video_window win)
1839 {
1840         u16 x, y, w, h, scx, scy, cw, ch, ax, ay;
1841         unsigned long fw, fh;
1842         struct ovcamchip_window s_win;
1843         int err = 0;
1844
1845         /* Work around to avoid FP arithmetics */
1846         #define __SC(x) ((x) << 10)
1847         #define __UNSC(x) ((x) >> 10)
1848
1849         /* Make sure we are using a supported resolution */
1850         if ((err = w9968cf_adjust_window_size(cam, (u16*)&win.width, 
1851                                               (u16*)&win.height)))
1852                 goto error;
1853
1854         /* Scaling factors */
1855         fw = __SC(win.width) / cam->maxwidth;
1856         fh = __SC(win.height) / cam->maxheight;
1857
1858         /* Set up the width and height values used by the chip */
1859         if ((win.width > cam->maxwidth) || (win.height > cam->maxheight)) {
1860                 cam->vpp_flag |= VPP_UPSCALE;
1861                 /* Calculate largest w,h mantaining the same w/h ratio */
1862                 w = (fw >= fh) ? cam->maxwidth : __SC(win.width)/fh;
1863                 h = (fw >= fh) ? __SC(win.height)/fw : cam->maxheight;
1864                 if (w < cam->minwidth) /* just in case */
1865                         w = cam->minwidth;
1866                 if (h < cam->minheight) /* just in case */
1867                         h = cam->minheight;
1868         } else {
1869                 cam->vpp_flag &= ~VPP_UPSCALE;
1870                 w = win.width;
1871                 h = win.height;
1872         }
1873
1874         /* x,y offsets of the cropped area */
1875         scx = cam->start_cropx;
1876         scy = cam->start_cropy;
1877
1878         /* Calculate cropped area manteining the right w/h ratio */
1879         if (cam->largeview && !(cam->vpp_flag & VPP_UPSCALE)) {
1880                 cw = (fw >= fh) ? cam->maxwidth : __SC(win.width)/fh;
1881                 ch = (fw >= fh) ? __SC(win.height)/fw : cam->maxheight;
1882         } else {
1883                 cw = w;
1884                 ch = h;
1885         }
1886
1887         /* Setup the window of the sensor */
1888         s_win.format = VIDEO_PALETTE_UYVY;
1889         s_win.width = cam->maxwidth;
1890         s_win.height = cam->maxheight;
1891         s_win.quarter = 0; /* full progressive video */
1892
1893         /* Center it */
1894         s_win.x = (s_win.width - cw) / 2;
1895         s_win.y = (s_win.height - ch) / 2;
1896
1897         /* Clock divisor */
1898         if (cam->clockdiv >= 0)
1899                 s_win.clockdiv = cam->clockdiv; /* manual override */
1900         else
1901                 switch (cam->sensor) {
1902                         case CC_OV6620:
1903                                 s_win.clockdiv = 0;
1904                                 break;
1905                         case CC_OV6630:
1906                                 s_win.clockdiv = 0;
1907                                 break;
1908                         case CC_OV76BE:
1909                         case CC_OV7610:
1910                         case CC_OV7620:
1911                                 s_win.clockdiv = 0;
1912                                 break;
1913                         default:
1914                                 s_win.clockdiv = W9968CF_DEF_CLOCKDIVISOR;
1915                 }
1916
1917         /* We have to scale win.x and win.y offsets */
1918         if ( (cam->largeview && !(cam->vpp_flag & VPP_UPSCALE))
1919              || (cam->vpp_flag & VPP_UPSCALE) ) {
1920                 ax = __SC(win.x)/fw;
1921                 ay = __SC(win.y)/fh;
1922         } else {
1923                 ax = win.x;
1924                 ay = win.y;
1925         }
1926
1927         if ((ax + cw) > cam->maxwidth)
1928                 ax = cam->maxwidth - cw;
1929
1930         if ((ay + ch) > cam->maxheight)
1931                 ay = cam->maxheight - ch;
1932
1933         /* Adjust win.x, win.y */
1934         if ( (cam->largeview && !(cam->vpp_flag & VPP_UPSCALE))
1935              || (cam->vpp_flag & VPP_UPSCALE) ) {
1936                 win.x = __UNSC(ax*fw);
1937                 win.y = __UNSC(ay*fh);
1938         } else {
1939                 win.x = ax;
1940                 win.y = ay;
1941         }
1942
1943         /* Offsets used by the chip */
1944         x = ax + s_win.x;
1945         y = ay + s_win.y;
1946
1947         /* Go ! */
1948         if ((err = w9968cf_sensor_cmd(cam, OVCAMCHIP_CMD_S_MODE, &s_win)))
1949                 goto error;
1950
1951         err += w9968cf_write_reg(cam, scx + x, 0x10);
1952         err += w9968cf_write_reg(cam, scy + y, 0x11);
1953         err += w9968cf_write_reg(cam, scx + x + cw, 0x12);
1954         err += w9968cf_write_reg(cam, scy + y + ch, 0x13);
1955         err += w9968cf_write_reg(cam, w, 0x14);
1956         err += w9968cf_write_reg(cam, h, 0x15);
1957
1958         /* JPEG width & height */
1959         err += w9968cf_write_reg(cam, w, 0x30);
1960         err += w9968cf_write_reg(cam, h, 0x31);
1961
1962         /* Y & UV frame buffer strides (in WORD) */
1963         if (cam->vpp_flag & VPP_DECOMPRESSION) {
1964                 err += w9968cf_write_reg(cam, w/2, 0x2c);
1965                 err += w9968cf_write_reg(cam, w/4, 0x2d);
1966         } else
1967                 err += w9968cf_write_reg(cam, w, 0x2c);
1968
1969         if (err)
1970                 goto error;
1971
1972         /* If all went well, update the device data structure */
1973         memcpy(&cam->window, &win, sizeof(win));
1974         cam->hw_width = w;
1975         cam->hw_height = h;
1976
1977         /* Settings changed, so we clear the frame buffers */
1978         memset(cam->frame[0].buffer, 0, cam->nbuffers*cam->frame[0].size);
1979
1980         DBG(4, "The capture area is %dx%d, Offset (x,y)=(%u,%u)", 
1981             win.width, win.height, win.x, win.y)
1982
1983         PDBGG("x=%u ,y=%u, w=%u, h=%u, ax=%u, ay=%u, s_win.x=%u, s_win.y=%u, "
1984               "cw=%u, ch=%u, win.x=%u, win.y=%u, win.width=%u, win.height=%u",
1985               x, y, w, h, ax, ay, s_win.x, s_win.y, cw, ch, win.x, win.y,
1986               win.width, win.height)
1987
1988         return 0;
1989
1990 error:
1991         DBG(1, "Failed to change the capture area size")
1992         return err;
1993 }
1994
1995
1996 /*-------------------------------------------------------------------------- 
1997   Adjust the asked values for window width and height.
1998   Return 0 on success, -1 otherwise.
1999   --------------------------------------------------------------------------*/
2000 static int 
2001 w9968cf_adjust_window_size(struct w9968cf_device* cam, u16* width, u16* height)
2002 {
2003         u16 maxw, maxh;
2004
2005         if ((*width < cam->minwidth) || (*height < cam->minheight))
2006                 return -ERANGE;
2007
2008         maxw = cam->upscaling && !(cam->vpp_flag & VPP_DECOMPRESSION) &&
2009                w9968cf_vpp ? max((u16)W9968CF_MAX_WIDTH, cam->maxwidth)
2010                            : cam->maxwidth;
2011         maxh = cam->upscaling && !(cam->vpp_flag & VPP_DECOMPRESSION) &&
2012                w9968cf_vpp ? max((u16)W9968CF_MAX_HEIGHT, cam->maxheight)
2013                            : cam->maxheight;
2014
2015         if (*width > maxw)
2016                 *width = maxw;
2017         if (*height > maxh)
2018                 *height = maxh;
2019
2020         if (cam->vpp_flag & VPP_DECOMPRESSION) {
2021                 *width  &= ~15L; /* multiple of 16 */
2022                 *height &= ~15L;
2023         }
2024
2025         PDBGG("Window size adjusted w=%u, h=%u ", *width, *height)
2026
2027         return 0;
2028 }
2029
2030
2031 /*--------------------------------------------------------------------------
2032   Initialize the FIFO list of requested frames.
2033   --------------------------------------------------------------------------*/
2034 static void w9968cf_init_framelist(struct w9968cf_device* cam)
2035 {
2036         u8 i;
2037
2038         for (i = 0; i < cam->nbuffers; i++) {
2039                 cam->requested_frame[i] = NULL;
2040                 cam->frame[i].queued = 0;
2041                 cam->frame[i].status = F_UNUSED;
2042         }
2043 }
2044
2045
2046 /*--------------------------------------------------------------------------
2047   Add a frame in the FIFO list of requested frames.
2048   This function is called in process context.
2049   --------------------------------------------------------------------------*/
2050 static void w9968cf_push_frame(struct w9968cf_device* cam, u8 f_num)
2051 {
2052         u8 f;
2053         unsigned long lock_flags;
2054
2055         spin_lock_irqsave(&cam->flist_lock, lock_flags);
2056
2057         for (f=0; cam->requested_frame[f] != NULL; f++);
2058         cam->requested_frame[f] = &cam->frame[f_num];
2059         cam->frame[f_num].queued = 1;
2060         cam->frame[f_num].status = F_UNUSED; /* clear the status */
2061
2062         spin_unlock_irqrestore(&cam->flist_lock, lock_flags);
2063
2064         DBG(6, "Frame #%u pushed into the FIFO list. Position %u", f_num, f)
2065 }
2066
2067
2068 /*--------------------------------------------------------------------------
2069   Read, store and remove the first pointer in the FIFO list of requested
2070   frames. This function is called in interrupt context.
2071   --------------------------------------------------------------------------*/
2072 static void 
2073 w9968cf_pop_frame(struct w9968cf_device* cam, struct w9968cf_frame_t** framep)
2074 {
2075         u8 i;
2076
2077         spin_lock(&cam->flist_lock);
2078
2079         *framep = cam->requested_frame[0];
2080
2081         /* Shift the list of pointers */
2082         for (i = 0; i < cam->nbuffers-1; i++)
2083                 cam->requested_frame[i] = cam->requested_frame[i+1];
2084         cam->requested_frame[i] = NULL;
2085
2086         spin_unlock(&cam->flist_lock);
2087
2088         DBG(6,"Popped frame #%d from the list", (*framep)->number)
2089 }
2090
2091
2092 /*--------------------------------------------------------------------------
2093   High-level video post-processing routine on grabbed frames.
2094   Return 0 on success, a negative number otherwise.
2095   --------------------------------------------------------------------------*/
2096 static int 
2097 w9968cf_postprocess_frame(struct w9968cf_device* cam, 
2098                           struct w9968cf_frame_t* fr)
2099 {
2100         void *pIn = fr->buffer, *pOut = cam->frame_vpp.buffer, *tmp;
2101         u16 w = cam->window.width,
2102             h = cam->window.height,
2103             d = cam->picture.depth,
2104             fmt = cam->picture.palette,
2105             rgb = cam->force_rgb,
2106             hw_w = cam->hw_width,
2107             hw_h = cam->hw_height,
2108             hw_d = cam->hw_depth;
2109         int err = 0;
2110
2111         #define _PSWAP(pIn, pOut) {tmp = (pIn); (pIn) = (pOut); (pOut) = tmp;}
2112
2113         if (cam->vpp_flag & VPP_DECOMPRESSION) {
2114                 memcpy(pOut, pIn, fr->length);
2115                 _PSWAP(pIn, pOut)
2116                 err = w9968cf_vpp->decode(pIn, fr->length, hw_w, hw_h, pOut);
2117                 PDBGG("Compressed frame length: %lu",(unsigned long)fr->length)
2118                 fr->length = (hw_w*hw_h*hw_d)/8;
2119                 _PSWAP(pIn, pOut)
2120                 if (err) {
2121                         DBG(4, "An error occurred while decoding the frame: "
2122                                "%s", symbolic(decoder_errlist, err))
2123                         return err;
2124                 } else
2125                         DBG(6, "Frame decoded")
2126         }
2127
2128         if (cam->vpp_flag & VPP_SWAP_YUV_BYTES) {
2129                 w9968cf_vpp->swap_yuvbytes(pIn, fr->length);
2130                 DBG(6, "Original UYVY component ordering changed")
2131         }
2132
2133         if (cam->vpp_flag & VPP_UPSCALE) {
2134                 w9968cf_vpp->scale_up(pIn, pOut, hw_w, hw_h, hw_d, w, h);
2135                 fr->length = (w*h*hw_d)/8;
2136                 _PSWAP(pIn, pOut)
2137                 DBG(6, "Vertical up-scaling done: %u,%u,%ubpp->%u,%u",
2138                     hw_w, hw_h, hw_d, w, h)
2139         }
2140
2141         if (cam->vpp_flag & VPP_UYVY_TO_RGBX) {
2142                 w9968cf_vpp->uyvy_to_rgbx(pIn, fr->length, pOut, fmt, rgb);
2143                 fr->length = (w*h*d)/8;
2144                 _PSWAP(pIn, pOut)
2145                 DBG(6, "UYVY-16bit to %s conversion done", 
2146                     symbolic(v4l1_plist, fmt))
2147         }
2148
2149         if (pOut == fr->buffer)
2150                 memcpy(fr->buffer, cam->frame_vpp.buffer, fr->length);
2151
2152         return 0;
2153 }
2154
2155
2156
2157 /****************************************************************************
2158  * Image sensor control routines                                            *
2159  ****************************************************************************/
2160
2161 static int 
2162 w9968cf_sensor_set_control(struct w9968cf_device* cam, int cid, int val)
2163 {
2164         struct ovcamchip_control ctl;
2165         int err;
2166
2167         ctl.id = cid;
2168         ctl.value = val;
2169
2170         err = w9968cf_sensor_cmd(cam, OVCAMCHIP_CMD_S_CTRL, &ctl);
2171
2172         return err;
2173 }
2174
2175
2176 static int 
2177 w9968cf_sensor_get_control(struct w9968cf_device* cam, int cid, int* val)
2178 {
2179         struct ovcamchip_control ctl;
2180         int err;
2181
2182         ctl.id = cid;
2183
2184         err = w9968cf_sensor_cmd(cam, OVCAMCHIP_CMD_G_CTRL, &ctl);
2185         if (!err)
2186                 *val = ctl.value;
2187
2188         return err;
2189 }
2190
2191
2192 static int
2193 w9968cf_sensor_cmd(struct w9968cf_device* cam, unsigned int cmd, void* arg)
2194 {
2195         struct i2c_client* c = cam->sensor_client;
2196         int rc = 0;
2197
2198         if (!c || !c->driver || !c->driver->command)
2199                 return -EINVAL;
2200
2201         rc = c->driver->command(c, cmd, arg);
2202         /* The I2C driver returns -EPERM on non-supported controls */
2203         return (rc < 0 && rc != -EPERM) ? rc : 0;
2204 }
2205
2206
2207 /*--------------------------------------------------------------------------
2208   Update some settings of the image sensor.
2209   Returns: 0 on success, a negative number otherwise.
2210   --------------------------------------------------------------------------*/
2211 static int w9968cf_sensor_update_settings(struct w9968cf_device* cam)
2212 {
2213         int err = 0;
2214
2215         /* Auto brightness */
2216         err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_AUTOBRIGHT, 
2217                                          cam->auto_brt);
2218         if (err)
2219                 return err;
2220
2221         /* Auto exposure */
2222         err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_AUTOEXP, 
2223                                          cam->auto_exp);
2224         if (err)
2225                 return err;
2226
2227         /* Banding filter */
2228         err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_BANDFILT, 
2229                                          cam->bandfilt);
2230         if (err)
2231                 return err;
2232
2233         /* Light frequency */
2234         err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_FREQ,
2235                                          cam->lightfreq);
2236         if (err)
2237                 return err;
2238
2239         /* Back light */
2240         err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_BACKLIGHT,
2241                                          cam->backlight);
2242         if (err)
2243                 return err;
2244
2245         /* Mirror */
2246         err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_MIRROR,
2247                                          cam->mirror);
2248         if (err)
2249                 return err;
2250
2251         return 0;
2252 }
2253
2254
2255 /*--------------------------------------------------------------------------
2256   Get some current picture settings from the image sensor and update the
2257   internal 'picture' structure of the camera.
2258   Returns: 0 on success, a negative number otherwise.
2259   --------------------------------------------------------------------------*/
2260 static int w9968cf_sensor_get_picture(struct w9968cf_device* cam)
2261 {
2262         int err, v;
2263
2264         err = w9968cf_sensor_get_control(cam, OVCAMCHIP_CID_CONT, &v);
2265         if (err)
2266                 return err;
2267         cam->picture.contrast = v;
2268
2269         err = w9968cf_sensor_get_control(cam, OVCAMCHIP_CID_BRIGHT, &v);
2270         if (err)
2271                 return err;
2272         cam->picture.brightness = v;
2273
2274         err = w9968cf_sensor_get_control(cam, OVCAMCHIP_CID_SAT, &v);
2275         if (err)
2276                 return err;
2277         cam->picture.colour = v;
2278
2279         err = w9968cf_sensor_get_control(cam, OVCAMCHIP_CID_HUE, &v);
2280         if (err)
2281                 return err;
2282         cam->picture.hue = v;
2283
2284         DBG(5, "Got picture settings from the image sensor")
2285
2286         PDBGG("Brightness, contrast, hue, colour, whiteness are "
2287               "%u,%u,%u,%u,%u", cam->picture.brightness,cam->picture.contrast,
2288               cam->picture.hue, cam->picture.colour, cam->picture.whiteness)
2289
2290         return 0;
2291 }
2292
2293
2294 /*--------------------------------------------------------------------------
2295   Update picture settings of the image sensor.
2296   Returns: 0 on success, a negative number otherwise.
2297   --------------------------------------------------------------------------*/
2298 static int
2299 w9968cf_sensor_update_picture(struct w9968cf_device* cam, 
2300                               struct video_picture pict)
2301 {
2302         int err = 0;
2303
2304         if ((!cam->sensor_initialized)
2305             || pict.contrast != cam->picture.contrast) {
2306                 err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_CONT,
2307                                                  pict.contrast);
2308                 if (err)
2309                         goto fail;
2310                 DBG(4, "Contrast changed from %u to %u",
2311                     cam->picture.contrast, pict.contrast)
2312                 cam->picture.contrast = pict.contrast;
2313         }
2314
2315         if (((!cam->sensor_initialized) || 
2316             pict.brightness != cam->picture.brightness) && (!cam->auto_brt)) {
2317                 err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_BRIGHT, 
2318                                                  pict.brightness);
2319                 if (err)
2320                         goto fail;
2321                 DBG(4, "Brightness changed from %u to %u",
2322                     cam->picture.brightness, pict.brightness)
2323                 cam->picture.brightness = pict.brightness;
2324         }
2325
2326         if ((!cam->sensor_initialized) || pict.colour != cam->picture.colour) {
2327                 err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_SAT, 
2328                                                  pict.colour);
2329                 if (err)
2330                         goto fail;
2331                 DBG(4, "Colour changed from %u to %u",
2332                     cam->picture.colour, pict.colour)
2333                 cam->picture.colour = pict.colour;
2334         }
2335
2336         if ((!cam->sensor_initialized) || pict.hue != cam->picture.hue) {
2337                 err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_HUE, 
2338                                                  pict.hue);
2339                 if (err)
2340                         goto fail;
2341                 DBG(4, "Hue changed from %u to %u",
2342                     cam->picture.hue, pict.hue)
2343                 cam->picture.hue = pict.hue;
2344         }
2345
2346         return 0;
2347
2348 fail:
2349         DBG(4, "Failed to change sensor picture setting")
2350         return err;
2351 }
2352
2353
2354
2355 /****************************************************************************
2356  * Camera configuration                                                     *
2357  ****************************************************************************/
2358
2359 /*--------------------------------------------------------------------------
2360   This function is called when a supported image sensor is detected.
2361   Return 0 if the initialization succeeds, a negative number otherwise.
2362   --------------------------------------------------------------------------*/
2363 static int w9968cf_sensor_init(struct w9968cf_device* cam)
2364 {
2365         int err = 0;
2366
2367         if ((err = w9968cf_sensor_cmd(cam, OVCAMCHIP_CMD_INITIALIZE, 
2368                                       &cam->monochrome)))
2369                 goto error;
2370
2371         if ((err = w9968cf_sensor_cmd(cam, OVCAMCHIP_CMD_Q_SUBTYPE, 
2372                                       &cam->sensor)))
2373                 goto error;
2374
2375         /* NOTE: Make sure width and height are a multiple of 16 */
2376         switch (cam->sensor_client->addr) {
2377                 case OV6xx0_SID:
2378                         cam->maxwidth = 352;
2379                         cam->maxheight = 288;
2380                         cam->minwidth = 64;
2381                         cam->minheight = 48;
2382                         break;
2383                 case OV7xx0_SID:
2384                         cam->maxwidth = 640;
2385                         cam->maxheight = 480;
2386                         cam->minwidth = 64;
2387                         cam->minheight = 48;
2388                         break;
2389                 default:
2390                         DBG(1, "Not supported image sensor detected for %s",
2391                             symbolic(camlist, cam->id))
2392                         return -EINVAL;
2393         }
2394
2395         /* These values depend on the ones in the ovxxx0.c sources */
2396         switch (cam->sensor) {
2397                 case CC_OV7620:
2398                         cam->start_cropx = 287;
2399                         cam->start_cropy = 35;
2400                         /* Seems to work around a bug in the image sensor */
2401                         cam->vs_polarity = 1;
2402                         cam->hs_polarity = 1;
2403                         break;
2404                 default:
2405                         cam->start_cropx = 320;
2406                         cam->start_cropy = 35;
2407                         cam->vs_polarity = 1;
2408                         cam->hs_polarity = 0;
2409         }
2410
2411         if ((err = w9968cf_sensor_update_settings(cam)))
2412                 goto error;
2413
2414         if ((err = w9968cf_sensor_update_picture(cam, cam->picture)))
2415                 goto error;
2416
2417         cam->sensor_initialized = 1;
2418
2419         DBG(2, "%s image sensor initialized", symbolic(senlist, cam->sensor))
2420         return 0;
2421
2422 error:
2423         cam->sensor_initialized = 0;
2424         cam->sensor = CC_UNKNOWN;
2425         DBG(1, "Image sensor initialization failed for %s (/dev/video%d). "
2426                "Try to detach and attach this device again",
2427             symbolic(camlist, cam->id), cam->v4ldev->minor)
2428         return err;
2429 }
2430
2431
2432 /*--------------------------------------------------------------------------
2433   Fill some basic fields in the main device data structure.
2434   This function is called once on w9968cf_usb_probe() for each recognized 
2435   camera.
2436   --------------------------------------------------------------------------*/
2437 static void
2438 w9968cf_configure_camera(struct w9968cf_device* cam,
2439                          struct usb_device* udev,
2440                          enum w9968cf_model_id mod_id,
2441                          const unsigned short dev_nr)
2442 {
2443         init_MUTEX(&cam->fileop_sem);
2444         init_waitqueue_head(&cam->open);
2445         spin_lock_init(&cam->urb_lock);
2446         spin_lock_init(&cam->flist_lock);
2447
2448         cam->users = 0;
2449         cam->disconnected = 0;
2450         cam->id = mod_id;
2451         cam->sensor = CC_UNKNOWN;
2452         cam->sensor_initialized = 0;
2453
2454         /* Calculate the alternate setting number (from 1 to 16)
2455            according to the 'packet_size' module parameter */
2456         if (packet_size[dev_nr] < W9968CF_MIN_PACKET_SIZE)
2457                 packet_size[dev_nr] = W9968CF_MIN_PACKET_SIZE;
2458         for (cam->altsetting = 1;
2459              packet_size[dev_nr] < wMaxPacketSize[cam->altsetting-1];
2460              cam->altsetting++);
2461
2462         cam->max_buffers = (max_buffers[dev_nr] < 2 || 
2463                             max_buffers[dev_nr] > W9968CF_MAX_BUFFERS)
2464                            ? W9968CF_BUFFERS : (u8)max_buffers[dev_nr];
2465
2466         cam->double_buffer = (double_buffer[dev_nr] == 0 || 
2467                               double_buffer[dev_nr] == 1)
2468                              ? (u8)double_buffer[dev_nr]:W9968CF_DOUBLE_BUFFER;
2469
2470         cam->clamping = (clamping[dev_nr] == 0 || clamping[dev_nr] == 1)
2471                         ? (u8)clamping[dev_nr] : W9968CF_CLAMPING;
2472         
2473         cam->filter_type = (filter_type[dev_nr] == 0 ||
2474                             filter_type[dev_nr] == 1 ||
2475                             filter_type[dev_nr] == 2)
2476                            ? (u8)filter_type[dev_nr] : W9968CF_FILTER_TYPE;
2477
2478         cam->capture = 1;
2479
2480         cam->largeview = (largeview[dev_nr] == 0 || largeview[dev_nr] == 1)
2481                          ? (u8)largeview[dev_nr] : W9968CF_LARGEVIEW;
2482
2483         cam->decompression = (decompression[dev_nr] == 0 || 
2484                               decompression[dev_nr] == 1 ||
2485                               decompression[dev_nr] == 2)
2486                              ? (u8)decompression[dev_nr]:W9968CF_DECOMPRESSION;
2487
2488         cam->upscaling = (upscaling[dev_nr] == 0 || 
2489                           upscaling[dev_nr] == 1)
2490                          ? (u8)upscaling[dev_nr] : W9968CF_UPSCALING;
2491
2492         cam->auto_brt = (autobright[dev_nr] == 0 || autobright[dev_nr] == 1)
2493                         ? (u8)autobright[dev_nr] : W9968CF_AUTOBRIGHT;
2494
2495         cam->auto_exp = (autoexp[dev_nr] == 0 || autoexp[dev_nr] == 1)
2496                         ? (u8)autoexp[dev_nr] : W9968CF_AUTOEXP;
2497
2498         cam->lightfreq = (lightfreq[dev_nr] == 50 || lightfreq[dev_nr] == 60)
2499                          ? (u8)lightfreq[dev_nr] : W9968CF_LIGHTFREQ;
2500
2501         cam->bandfilt = (bandingfilter[dev_nr] == 0 || 
2502                          bandingfilter[dev_nr] == 1)
2503                         ? (u8)bandingfilter[dev_nr] : W9968CF_BANDINGFILTER;
2504
2505         cam->backlight = (backlight[dev_nr] == 0 || backlight[dev_nr] == 1)
2506                          ? (u8)backlight[dev_nr] : W9968CF_BACKLIGHT;
2507
2508         cam->clockdiv = (clockdiv[dev_nr] == -1 || clockdiv[dev_nr] >= 0)
2509                         ? (s8)clockdiv[dev_nr] : W9968CF_CLOCKDIV;
2510
2511         cam->mirror = (mirror[dev_nr] == 0 || mirror[dev_nr] == 1)
2512                       ? (u8)mirror[dev_nr] : W9968CF_MIRROR;
2513
2514         cam->monochrome = (monochrome[dev_nr] == 0 || monochrome[dev_nr] == 1)
2515                           ? monochrome[dev_nr] : W9968CF_MONOCHROME;
2516
2517         cam->picture.brightness = (u16)brightness[dev_nr];
2518         cam->picture.hue = (u16)hue[dev_nr];
2519         cam->picture.colour = (u16)colour[dev_nr];
2520         cam->picture.contrast = (u16)contrast[dev_nr];
2521         cam->picture.whiteness = (u16)whiteness[dev_nr];
2522         if (w9968cf_valid_palette((u16)force_palette[dev_nr])) {
2523                 cam->picture.palette = (u16)force_palette[dev_nr];
2524                 cam->force_palette = 1;
2525         } else {
2526                 cam->force_palette = 0;
2527                 if (cam->decompression == 0)
2528                         cam->picture.palette = W9968CF_PALETTE_DECOMP_OFF;
2529                 else if (cam->decompression == 1)
2530                         cam->picture.palette = W9968CF_PALETTE_DECOMP_FORCE;
2531                 else
2532                         cam->picture.palette = W9968CF_PALETTE_DECOMP_ON;
2533         }
2534         cam->picture.depth = w9968cf_valid_depth(cam->picture.palette);
2535
2536         cam->force_rgb = (force_rgb[dev_nr] == 0 || force_rgb[dev_nr] == 1)
2537                          ? (u8)force_rgb[dev_nr] : W9968CF_FORCE_RGB;
2538
2539         cam->window.x = 0;
2540         cam->window.y = 0;
2541         cam->window.width = W9968CF_WIDTH;
2542         cam->window.height = W9968CF_HEIGHT;
2543         cam->window.chromakey = 0;
2544         cam->window.clipcount = 0;
2545         cam->window.flags = 0;
2546
2547         DBG(3, "%s configured with settings #%u:",
2548             symbolic(camlist, cam->id), dev_nr)
2549         
2550         DBG(3, "- Data packet size for USB isochrnous transfer: %u bytes",
2551             wMaxPacketSize[cam->altsetting-1])
2552         
2553         DBG(3, "- Number of requested video frame buffers: %u",
2554             cam->max_buffers)
2555
2556         if (cam->double_buffer)
2557                 DBG(3, "- Hardware double buffering enabled")
2558         else 
2559                 DBG(3, "- Hardware double buffering disabled")
2560
2561         if (cam->filter_type == 0)
2562                 DBG(3, "- Video filtering disabled")
2563         else if (cam->filter_type == 1)
2564                 DBG(3, "- Video filtering enabled: type 1-2-1")
2565         else if (cam->filter_type == 2)
2566                 DBG(3, "- Video filtering enabled: type 2-3-6-3-2")
2567
2568         if (cam->clamping)
2569                 DBG(3, "- Video data clamping (CCIR-601 format) enabled")
2570         else
2571                 DBG(3, "- Video data clamping (CCIR-601 format) disabled")
2572
2573         if (cam->largeview)
2574                 DBG(3, "- Large view enabled")
2575         else
2576                 DBG(3, "- Large view disabled")
2577
2578         if ((cam->decompression) == 0 && (!cam->force_palette))
2579                 DBG(3, "- Decompression disabled")
2580         else if ((cam->decompression) == 1 && (!cam->force_palette))
2581                 DBG(3, "- Decompression forced")
2582         else if ((cam->decompression) == 2 && (!cam->force_palette))
2583                 DBG(3, "- Decompression allowed")
2584
2585         if (cam->upscaling)
2586                 DBG(3, "- Software image scaling enabled")
2587         else
2588                 DBG(3, "- Software image scaling disabled")
2589
2590         if (cam->force_palette)
2591                 DBG(3, "- Image palette forced to %s",
2592                     symbolic(v4l1_plist, cam->picture.palette))
2593
2594         if (cam->force_rgb)
2595                 DBG(3, "- RGB component ordering will be used instead of BGR")
2596
2597         if (cam->auto_brt)
2598                 DBG(3, "- Auto brightness enabled")
2599         else
2600                 DBG(3, "- Auto brightness disabled")
2601
2602         if (cam->auto_exp)
2603                 DBG(3, "- Auto exposure enabled")
2604         else
2605                 DBG(3, "- Auto exposure disabled")
2606
2607         if (cam->backlight)
2608                 DBG(3, "- Backlight exposure algorithm enabled")
2609         else
2610                 DBG(3, "- Backlight exposure algorithm disabled")
2611
2612         if (cam->mirror)
2613                 DBG(3, "- Mirror enabled")
2614         else
2615                 DBG(3, "- Mirror disabled")
2616
2617         if (cam->bandfilt)
2618                 DBG(3, "- Banding filter enabled")
2619         else
2620                 DBG(3, "- Banding filter disabled")
2621
2622         DBG(3, "- Power lighting frequency: %u", cam->lightfreq)
2623
2624         if (cam->clockdiv == -1)
2625                 DBG(3, "- Automatic clock divisor enabled")
2626         else
2627                 DBG(3, "- Clock divisor: %d", cam->clockdiv)
2628
2629         if (cam->monochrome)
2630                 DBG(3, "- Image sensor used as monochrome")
2631         else
2632                 DBG(3, "- Image sensor not used as monochrome")
2633 }
2634
2635
2636 /*--------------------------------------------------------------------------
2637   If the video post-processing module is not loaded, some parameters
2638   must be overridden.
2639   --------------------------------------------------------------------------*/
2640 static void w9968cf_adjust_configuration(struct w9968cf_device* cam)
2641 {
2642         if (!w9968cf_vpp) {
2643                 if (cam->decompression == 1) {
2644                         cam->decompression = 2;
2645                         DBG(2, "Video post-processing module not found: "
2646                                "'decompression' parameter forced to 2")
2647                 }
2648                 if (cam->upscaling) {
2649                         cam->upscaling = 0;
2650                         DBG(2, "Video post-processing module not found: "
2651                                "'upscaling' parameter forced to 0")
2652                 }
2653                 if (cam->picture.palette != VIDEO_PALETTE_UYVY) {
2654                         cam->force_palette = 0;
2655                         DBG(2, "Video post-processing module not found: "
2656                                "'force_palette' parameter forced to 0")
2657                 }
2658                 cam->picture.palette = VIDEO_PALETTE_UYVY;
2659                 cam->picture.depth = w9968cf_valid_depth(cam->picture.palette);
2660         }
2661 }
2662
2663
2664 /*--------------------------------------------------------------------------
2665   Release the resources used by the driver.
2666   This function is called on disconnect 
2667   (or on close if deallocation has been deferred)
2668   --------------------------------------------------------------------------*/
2669 static void w9968cf_release_resources(struct w9968cf_device* cam)
2670 {
2671         down(&w9968cf_devlist_sem);
2672
2673         DBG(2, "V4L device deregistered: /dev/video%d", cam->v4ldev->minor)
2674
2675         video_unregister_device(cam->v4ldev);
2676         list_del(&cam->v4llist);
2677         i2c_del_adapter(&cam->i2c_adapter);
2678         w9968cf_deallocate_memory(cam);
2679         kfree(cam->control_buffer);
2680         kfree(cam->data_buffer);
2681
2682         up(&w9968cf_devlist_sem);
2683 }
2684
2685
2686
2687 /****************************************************************************
2688  * Video4Linux interface                                                    *
2689  ****************************************************************************/
2690
2691 static int w9968cf_open(struct inode* inode, struct file* filp)
2692 {
2693         struct w9968cf_device* cam;
2694         int err;
2695
2696         /* This the only safe way to prevent race conditions with disconnect */
2697         if (!down_read_trylock(&w9968cf_disconnect))
2698                 return -ERESTARTSYS;
2699
2700         cam = (struct w9968cf_device*)video_get_drvdata(video_devdata(filp));
2701
2702         down(&cam->dev_sem);
2703
2704         if (cam->sensor == CC_UNKNOWN) {
2705                 DBG(2, "No supported image sensor has been detected by the "
2706                        "'ovcamchip' module for the %s (/dev/video%d). Make "
2707                        "sure it is loaded *before* (re)connecting the camera.",
2708                     symbolic(camlist, cam->id), cam->v4ldev->minor)
2709                 up(&cam->dev_sem);
2710                 up_read(&w9968cf_disconnect);
2711                 return -ENODEV;
2712         }
2713
2714         if (cam->users) {
2715                 DBG(2, "%s (/dev/video%d) has been already occupied by '%s'",
2716                     symbolic(camlist, cam->id),cam->v4ldev->minor,cam->command)
2717                 if ((filp->f_flags & O_NONBLOCK)||(filp->f_flags & O_NDELAY)) {
2718                         up(&cam->dev_sem);
2719                         up_read(&w9968cf_disconnect);
2720                         return -EWOULDBLOCK;
2721                 }
2722                 up(&cam->dev_sem);
2723                 err = wait_event_interruptible_exclusive(cam->open,
2724                                                          cam->disconnected ||
2725                                                          !cam->users);
2726                 if (err) {
2727                         up_read(&w9968cf_disconnect);
2728                         return err;
2729                 }
2730                 if (cam->disconnected) {
2731                         up_read(&w9968cf_disconnect);
2732                         return -ENODEV;
2733                 }
2734                 down(&cam->dev_sem);
2735         }
2736
2737         DBG(5, "Opening '%s', /dev/video%d ...",
2738             symbolic(camlist, cam->id), cam->v4ldev->minor)
2739
2740         cam->streaming = 0;
2741         cam->misconfigured = 0;
2742
2743         if (!w9968cf_vpp)
2744                 if ((err = w9968cf_vppmod_detect(cam)))
2745                         goto out;
2746
2747         if ((err = w9968cf_allocate_memory(cam)))
2748                 goto deallocate_memory;
2749
2750         if ((err = w9968cf_init_chip(cam)))
2751                 goto deallocate_memory;
2752
2753         if ((err = w9968cf_start_transfer(cam)))
2754                 goto deallocate_memory;
2755
2756         filp->private_data = cam;
2757
2758         cam->users++;
2759         strcpy(cam->command, current->comm);
2760
2761         init_waitqueue_head(&cam->wait_queue);
2762
2763         DBG(5, "Video device is open")
2764
2765         up(&cam->dev_sem);
2766         up_read(&w9968cf_disconnect);
2767
2768         return 0;
2769
2770 deallocate_memory:
2771         w9968cf_deallocate_memory(cam);
2772 out:
2773         DBG(2, "Failed to open the video device")
2774         up(&cam->dev_sem);
2775         up_read(&w9968cf_disconnect);
2776         return err;
2777 }
2778
2779
2780 static int w9968cf_release(struct inode* inode, struct file* filp)
2781 {
2782         struct w9968cf_device* cam;
2783
2784         cam = (struct w9968cf_device*)video_get_drvdata(video_devdata(filp));
2785
2786         down(&cam->dev_sem); /* prevent disconnect() to be called */
2787
2788         w9968cf_stop_transfer(cam);
2789
2790         w9968cf_vppmod_release(cam);
2791
2792         if (cam->disconnected) {
2793                 w9968cf_release_resources(cam);
2794                 up(&cam->dev_sem);
2795                 kfree(cam);
2796                 return 0;
2797         }
2798
2799         cam->users--;
2800         w9968cf_deallocate_memory(cam);
2801         wake_up_interruptible_nr(&cam->open, 1);
2802
2803         DBG(5, "Video device closed")
2804         up(&cam->dev_sem);
2805         return 0;
2806 }
2807
2808
2809 static ssize_t
2810 w9968cf_read(struct file* filp, char __user * buf, size_t count, loff_t* f_pos)
2811 {
2812         struct w9968cf_device* cam;
2813         struct w9968cf_frame_t* fr;
2814         int err = 0;
2815
2816         cam = (struct w9968cf_device*)video_get_drvdata(video_devdata(filp));
2817
2818         if (filp->f_flags & O_NONBLOCK)
2819                 return -EWOULDBLOCK;
2820
2821         if (down_interruptible(&cam->fileop_sem))
2822                 return -ERESTARTSYS;
2823
2824         if (cam->disconnected) {
2825                 DBG(2, "Device not present")
2826                 up(&cam->fileop_sem);
2827                 return -ENODEV;
2828         }
2829
2830         if (cam->misconfigured) {
2831                 DBG(2, "The camera is misconfigured. Close and open it again.")
2832                 up(&cam->fileop_sem);
2833                 return -EIO;
2834         }
2835
2836         if (!cam->frame[0].queued)
2837                 w9968cf_push_frame(cam, 0);
2838
2839         if (!cam->frame[1].queued)
2840                 w9968cf_push_frame(cam, 1);
2841
2842         err = wait_event_interruptible(cam->wait_queue,
2843                                        cam->frame[0].status == F_READY ||
2844                                        cam->frame[1].status == F_READY ||
2845                                        cam->disconnected);
2846         if (err) {
2847                 up(&cam->fileop_sem);
2848                 return err;
2849         }
2850         if (cam->disconnected) {
2851                 up(&cam->fileop_sem);
2852                 return -ENODEV;
2853         }
2854
2855         fr = (cam->frame[0].status == F_READY) ? &cam->frame[0]:&cam->frame[1];
2856
2857         if (w9968cf_vpp)
2858                 w9968cf_postprocess_frame(cam, fr);
2859
2860         if (count > fr->length)
2861                 count = fr->length;
2862
2863         if (copy_to_user(buf, fr->buffer, count)) {
2864                 fr->status = F_UNUSED;
2865                 up(&cam->fileop_sem);
2866                 return -EFAULT;
2867         }
2868         *f_pos += count;
2869
2870         fr->status = F_UNUSED;
2871
2872         DBG(5, "%zu bytes read", count)
2873
2874         up(&cam->fileop_sem);
2875         return count;
2876 }
2877
2878
2879 static int w9968cf_mmap(struct file* filp, struct vm_area_struct *vma)
2880 {
2881         struct w9968cf_device* cam = (struct w9968cf_device*)
2882                                      video_get_drvdata(video_devdata(filp));
2883         unsigned long vsize = vma->vm_end - vma->vm_start,
2884                       psize = cam->nbuffers * cam->frame[0].size,
2885                       start = vma->vm_start,
2886                       pos = (unsigned long)cam->frame[0].buffer,
2887                       page;
2888
2889         if (cam->disconnected) {
2890                 DBG(2, "Device not present")
2891                 return -ENODEV;
2892         }
2893
2894         if (cam->misconfigured) {
2895                 DBG(2, "The camera is misconfigured. Close and open it again")
2896                 return -EIO;
2897         }
2898
2899         PDBGG("mmapping %lu bytes...", vsize)
2900
2901         if (vsize > psize - (vma->vm_pgoff << PAGE_SHIFT))
2902                 return -EINVAL;
2903
2904         while (vsize > 0) {
2905                 page = vmalloc_to_pfn((void *)pos);
2906                 if (remap_pfn_range(vma, start, page + vma->vm_pgoff,
2907                                                 PAGE_SIZE, vma->vm_page_prot))
2908                         return -EAGAIN;
2909                 start += PAGE_SIZE;
2910                 pos += PAGE_SIZE;
2911                 vsize -= PAGE_SIZE;
2912         }
2913
2914         DBG(5, "mmap method successfully called")
2915         return 0;
2916 }
2917
2918
2919 static int
2920 w9968cf_ioctl(struct inode* inode, struct file* filp,
2921               unsigned int cmd, unsigned long arg)
2922 {
2923         struct w9968cf_device* cam;
2924         int err;
2925
2926         cam = (struct w9968cf_device*)video_get_drvdata(video_devdata(filp));
2927
2928         if (down_interruptible(&cam->fileop_sem))
2929                 return -ERESTARTSYS;
2930
2931         if (cam->disconnected) {
2932                 DBG(2, "Device not present")
2933                 up(&cam->fileop_sem);
2934                 return -ENODEV;
2935         }
2936
2937         if (cam->misconfigured) {
2938                 DBG(2, "The camera is misconfigured. Close and open it again.")
2939                 up(&cam->fileop_sem);
2940                 return -EIO;
2941         }
2942
2943         err = w9968cf_v4l_ioctl(inode, filp, cmd, (void __user *)arg);
2944
2945         up(&cam->fileop_sem);
2946         return err;
2947 }
2948
2949
2950 static int w9968cf_v4l_ioctl(struct inode* inode, struct file* filp,
2951                              unsigned int cmd, void __user * arg)
2952 {
2953         struct w9968cf_device* cam;
2954         const char* v4l1_ioctls[] = {
2955                 "?", "CGAP", "GCHAN", "SCHAN", "GTUNER", "STUNER", 
2956                 "GPICT", "SPICT", "CCAPTURE", "GWIN", "SWIN", "GFBUF",
2957                 "SFBUF", "KEY", "GFREQ", "SFREQ", "GAUDIO", "SAUDIO",
2958                 "SYNC", "MCAPTURE", "GMBUF", "GUNIT", "GCAPTURE", "SCAPTURE",
2959                 "SPLAYMODE", "SWRITEMODE", "GPLAYINFO", "SMICROCODE", 
2960                 "GVBIFMT", "SVBIFMT" 
2961         };
2962
2963         #define V4L1_IOCTL(cmd) \
2964                 ((_IOC_NR((cmd)) < sizeof(v4l1_ioctls)/sizeof(char*)) ? \
2965                 v4l1_ioctls[_IOC_NR((cmd))] : "?")
2966
2967         cam = (struct w9968cf_device*)video_get_drvdata(video_devdata(filp));
2968
2969         switch (cmd) {
2970
2971         case VIDIOCGCAP: /* get video capability */
2972         {
2973                 struct video_capability cap = {
2974                         .type = VID_TYPE_CAPTURE | VID_TYPE_SCALES,
2975                         .channels = 1,
2976                         .audios = 0,
2977                         .minwidth = cam->minwidth,
2978                         .minheight = cam->minheight,
2979                 };
2980                 sprintf(cap.name, "W996[87]CF USB Camera #%d", 
2981                         cam->v4ldev->minor);
2982                 cap.maxwidth = (cam->upscaling && w9968cf_vpp)
2983                                ? max((u16)W9968CF_MAX_WIDTH, cam->maxwidth) 
2984                                  : cam->maxwidth;
2985                 cap.maxheight = (cam->upscaling && w9968cf_vpp)
2986                                 ? max((u16)W9968CF_MAX_HEIGHT, cam->maxheight)
2987                                   : cam->maxheight;
2988
2989                 if (copy_to_user(arg, &cap, sizeof(cap)))
2990                         return -EFAULT;
2991
2992                 DBG(5, "VIDIOCGCAP successfully called")
2993                 return 0;
2994         }
2995
2996         case VIDIOCGCHAN: /* get video channel informations */
2997         {
2998                 struct video_channel chan;
2999                 if (copy_from_user(&chan, arg, sizeof(chan)))
3000                         return -EFAULT;
3001
3002                 if (chan.channel != 0)
3003                         return -EINVAL;
3004
3005                 strcpy(chan.name, "Camera");
3006                 chan.tuners = 0;
3007                 chan.flags = 0;
3008                 chan.type = VIDEO_TYPE_CAMERA;
3009                 chan.norm = VIDEO_MODE_AUTO;
3010
3011                 if (copy_to_user(arg, &chan, sizeof(chan)))
3012                         return -EFAULT;
3013
3014                 DBG(5, "VIDIOCGCHAN successfully called")
3015                 return 0;
3016         }
3017
3018         case VIDIOCSCHAN: /* set active channel */
3019         {
3020                 struct video_channel chan;
3021
3022                 if (copy_from_user(&chan, arg, sizeof(chan)))
3023                         return -EFAULT;
3024
3025                 if (chan.channel != 0)
3026                         return -EINVAL;
3027
3028                 DBG(5, "VIDIOCSCHAN successfully called")
3029                 return 0;
3030         }
3031
3032         case VIDIOCGPICT: /* get image properties of the picture */
3033         {
3034                 if (w9968cf_sensor_get_picture(cam))
3035                         return -EIO;
3036
3037                 if (copy_to_user(arg, &cam->picture, sizeof(cam->picture)))
3038                         return -EFAULT;
3039
3040                 DBG(5, "VIDIOCGPICT successfully called")
3041                 return 0;
3042         }
3043
3044         case VIDIOCSPICT: /* change picture settings */
3045         {
3046                 struct video_picture pict;
3047                 int err = 0;
3048
3049                 if (copy_from_user(&pict, arg, sizeof(pict)))
3050                         return -EFAULT;
3051
3052                 if ( (cam->force_palette || !w9968cf_vpp) 
3053                      && pict.palette != cam->picture.palette ) {
3054                         DBG(4, "Palette %s rejected: only %s is allowed",
3055                             symbolic(v4l1_plist, pict.palette),
3056                             symbolic(v4l1_plist, cam->picture.palette))
3057                         return -EINVAL;
3058                 }
3059
3060                 if (!w9968cf_valid_palette(pict.palette)) {
3061                         DBG(4, "Palette %s not supported. VIDIOCSPICT failed",
3062                             symbolic(v4l1_plist, pict.palette))
3063                         return -EINVAL;
3064                 }
3065
3066                 if (!cam->force_palette) {
3067                    if (cam->decompression == 0) {
3068                       if (w9968cf_need_decompression(pict.palette)) {
3069                          DBG(4, "Decompression disabled: palette %s is not "
3070                                 "allowed. VIDIOCSPICT failed",
3071                              symbolic(v4l1_plist, pict.palette))
3072                          return -EINVAL;
3073                       }
3074                    } else if (cam->decompression == 1) {
3075                       if (!w9968cf_need_decompression(pict.palette)) {
3076                          DBG(4, "Decompression forced: palette %s is not "
3077                                 "allowed. VIDIOCSPICT failed",
3078                              symbolic(v4l1_plist, pict.palette))
3079                          return -EINVAL;
3080                       }
3081                    }
3082                 }
3083
3084                 if (pict.depth != w9968cf_valid_depth(pict.palette)) {
3085                         DBG(4, "Requested depth %u bpp is not valid for %s "
3086                                "palette: ignored and changed to %u bpp", 
3087                             pict.depth, symbolic(v4l1_plist, pict.palette),
3088                             w9968cf_valid_depth(pict.palette))
3089                         pict.depth = w9968cf_valid_depth(pict.palette);
3090                 }
3091
3092                 if (pict.palette != cam->picture.palette) {
3093                         if(*cam->requested_frame
3094                            || cam->frame_current->queued) {
3095                                 err = wait_event_interruptible
3096                                       ( cam->wait_queue,
3097                                         cam->disconnected ||
3098                                         (!*cam->requested_frame &&
3099                                          !cam->frame_current->queued) );
3100                                 if (err)
3101                                         return err;
3102                                 if (cam->disconnected)
3103                                         return -ENODEV;
3104                         }
3105
3106                         if (w9968cf_stop_transfer(cam))
3107                                 goto ioctl_fail;
3108
3109                         if (w9968cf_set_picture(cam, pict))
3110                                 goto ioctl_fail;
3111
3112                         if (w9968cf_start_transfer(cam))
3113                                 goto ioctl_fail;
3114
3115                 } else if (w9968cf_sensor_update_picture(cam, pict))
3116                         return -EIO;
3117
3118
3119                 DBG(5, "VIDIOCSPICT successfully called")
3120                 return 0;
3121         }
3122
3123         case VIDIOCSWIN: /* set capture area */
3124         {
3125                 struct video_window win;
3126                 int err = 0;
3127
3128                 if (copy_from_user(&win, arg, sizeof(win)))
3129                         return -EFAULT;
3130
3131                 DBG(6, "VIDIOCSWIN called: clipcount=%d, flags=%u, "
3132                        "x=%u, y=%u, %ux%u", win.clipcount, win.flags,
3133                     win.x, win.y, win.width, win.height)
3134
3135                 if (win.clipcount != 0 || win.flags != 0)
3136                         return -EINVAL;
3137
3138                 if ((err = w9968cf_adjust_window_size(cam, (u16*)&win.width,
3139                                                       (u16*)&win.height))) {
3140                         DBG(4, "Resolution not supported (%ux%u). "
3141                                "VIDIOCSWIN failed", win.width, win.height)
3142                         return err;
3143                 }
3144
3145                 if (win.x != cam->window.x ||
3146                     win.y != cam->window.y ||
3147                     win.width != cam->window.width ||
3148                     win.height != cam->window.height) {
3149                         if(*cam->requested_frame
3150                            || cam->frame_current->queued) {
3151                                 err = wait_event_interruptible
3152                                       ( cam->wait_queue,
3153                                         cam->disconnected ||
3154                                         (!*cam->requested_frame &&
3155                                          !cam->frame_current->queued) );
3156                                 if (err)
3157                                         return err;
3158                                 if (cam->disconnected)
3159                                         return -ENODEV;
3160                         }
3161
3162                         if (w9968cf_stop_transfer(cam))
3163                                 goto ioctl_fail;
3164
3165                         /* This _must_ be called before set_window() */
3166                         if (w9968cf_set_picture(cam, cam->picture))
3167                                 goto ioctl_fail;
3168
3169                         if (w9968cf_set_window(cam, win))
3170                                 goto ioctl_fail;
3171
3172                         if (w9968cf_start_transfer(cam))
3173                                 goto ioctl_fail;
3174                 }
3175
3176                 DBG(5, "VIDIOCSWIN successfully called. ")
3177                 return 0;
3178         }
3179
3180         case VIDIOCGWIN: /* get current window properties */
3181         {
3182                 if (copy_to_user(arg,&cam->window,sizeof(struct video_window)))
3183                         return -EFAULT;
3184
3185                 DBG(5, "VIDIOCGWIN successfully called")
3186                 return 0;
3187         }
3188
3189         case VIDIOCGMBUF: /* request for memory (mapped) buffer */
3190         {
3191                 struct video_mbuf mbuf;
3192                 u8 i;
3193
3194                 mbuf.size = cam->nbuffers * cam->frame[0].size;
3195                 mbuf.frames = cam->nbuffers;
3196                 for (i = 0; i < cam->nbuffers; i++)
3197                         mbuf.offsets[i] = (unsigned long)cam->frame[i].buffer -
3198                                           (unsigned long)cam->frame[0].buffer;
3199
3200                 if (copy_to_user(arg, &mbuf, sizeof(mbuf)))
3201                         return -EFAULT;
3202
3203                 DBG(5, "VIDIOCGMBUF successfully called")
3204                 return 0;
3205         }
3206
3207         case VIDIOCMCAPTURE: /* start the capture to a frame */
3208         {
3209                 struct video_mmap mmap;
3210                 struct w9968cf_frame_t* fr;
3211                 int err = 0;
3212
3213                 if (copy_from_user(&mmap, arg, sizeof(mmap)))
3214                         return -EFAULT;
3215
3216                 DBG(6, "VIDIOCMCAPTURE called: frame #%u, format=%s, %dx%d",
3217                     mmap.frame, symbolic(v4l1_plist, mmap.format), 
3218                     mmap.width, mmap.height)
3219
3220                 if (mmap.frame >= cam->nbuffers) {
3221                         DBG(4, "Invalid frame number (%u). "
3222                                "VIDIOCMCAPTURE failed", mmap.frame)
3223                         return -EINVAL;
3224                 }
3225
3226                 if (mmap.format!=cam->picture.palette && 
3227                     (cam->force_palette || !w9968cf_vpp)) {
3228                         DBG(4, "Palette %s rejected: only %s is allowed",
3229                             symbolic(v4l1_plist, mmap.format),
3230                             symbolic(v4l1_plist, cam->picture.palette))
3231                         return -EINVAL;
3232                 }
3233
3234                 if (!w9968cf_valid_palette(mmap.format)) {
3235                         DBG(4, "Palette %s not supported. "
3236                                "VIDIOCMCAPTURE failed", 
3237                             symbolic(v4l1_plist, mmap.format))
3238                         return -EINVAL;
3239                 }
3240
3241                 if (!cam->force_palette) {
3242                    if (cam->decompression == 0) {
3243                       if (w9968cf_need_decompression(mmap.format)) {
3244                          DBG(4, "Decompression disabled: palette %s is not "
3245                                 "allowed. VIDIOCSPICT failed",
3246                              symbolic(v4l1_plist, mmap.format))
3247                          return -EINVAL;
3248                       }
3249                    } else if (cam->decompression == 1) {
3250                       if (!w9968cf_need_decompression(mmap.format)) {
3251                          DBG(4, "Decompression forced: palette %s is not "
3252                                 "allowed. VIDIOCSPICT failed",
3253                              symbolic(v4l1_plist, mmap.format))
3254                          return -EINVAL;
3255                       }
3256                    }
3257                 }
3258
3259                 if ((err = w9968cf_adjust_window_size(cam, (u16*)&mmap.width, 
3260                                                       (u16*)&mmap.height))) {
3261                         DBG(4, "Resolution not supported (%dx%d). "
3262                                "VIDIOCMCAPTURE failed",
3263                             mmap.width, mmap.height)
3264                         return err;
3265                 }
3266
3267                 fr = &cam->frame[mmap.frame];
3268
3269                 if (mmap.width  != cam->window.width ||
3270                     mmap.height != cam->window.height ||
3271                     mmap.format != cam->picture.palette) {
3272
3273                         struct video_window win;
3274                         struct video_picture pict;
3275
3276                         if(*cam->requested_frame
3277                            || cam->frame_current->queued) {
3278                                 DBG(6, "VIDIOCMCAPTURE. Change settings for "
3279                                        "frame #%u: %dx%d, format %s. Wait...",
3280                                     mmap.frame, mmap.width, mmap.height,
3281                                     symbolic(v4l1_plist, mmap.format))
3282                                 err = wait_event_interruptible
3283                                       ( cam->wait_queue,
3284                                         cam->disconnected ||
3285                                         (!*cam->requested_frame &&
3286                                          !cam->frame_current->queued) );
3287                                 if (err)
3288                                         return err;
3289                                 if (cam->disconnected)
3290                                         return -ENODEV;
3291                         }
3292
3293                         memcpy(&win, &cam->window, sizeof(win));
3294                         memcpy(&pict, &cam->picture, sizeof(pict));
3295                         win.width = mmap.width;
3296                         win.height = mmap.height;
3297                         pict.palette = mmap.format;
3298
3299                         if (w9968cf_stop_transfer(cam))
3300                                 goto ioctl_fail;
3301
3302                         /* This before set_window */
3303                         if (w9968cf_set_picture(cam, pict)) 
3304                                 goto ioctl_fail;
3305
3306                         if (w9968cf_set_window(cam, win))
3307                                 goto ioctl_fail;
3308
3309                         if (w9968cf_start_transfer(cam))
3310                                 goto ioctl_fail;
3311
3312                 } else  if (fr->queued) {
3313
3314                         DBG(6, "Wait until frame #%u is free", mmap.frame)
3315                         
3316                         err = wait_event_interruptible(cam->wait_queue, 
3317                                                        cam->disconnected ||
3318                                                        (!fr->queued));
3319                         if (err)
3320                                 return err;
3321                         if (cam->disconnected)
3322                                 return -ENODEV;
3323                 }
3324
3325                 w9968cf_push_frame(cam, mmap.frame);
3326                 DBG(5, "VIDIOCMCAPTURE(%u): successfully called", mmap.frame)
3327                 return 0;
3328         }
3329
3330         case VIDIOCSYNC: /* wait until the capture of a frame is finished */
3331         {
3332                 unsigned int f_num;
3333                 struct w9968cf_frame_t* fr;
3334                 int err = 0;
3335
3336                 if (copy_from_user(&f_num, arg, sizeof(f_num)))
3337                         return -EFAULT;
3338
3339                 if (f_num >= cam->nbuffers) {
3340                         DBG(4, "Invalid frame number (%u). "
3341                                "VIDIOCMCAPTURE failed", f_num)
3342                         return -EINVAL;
3343                 }
3344
3345                 DBG(6, "VIDIOCSYNC called for frame #%u", f_num)
3346
3347                 fr = &cam->frame[f_num];
3348
3349                 switch (fr->status) {
3350                 case F_UNUSED:
3351                         if (!fr->queued) {
3352                                 DBG(4, "VIDIOSYNC: Frame #%u not requested!",
3353                                     f_num)
3354                                 return -EFAULT;
3355                         }
3356                 case F_ERROR:
3357                 case F_GRABBING:
3358                         err = wait_event_interruptible(cam->wait_queue, 
3359                                                        (fr->status == F_READY)
3360                                                        || cam->disconnected);
3361                         if (err)
3362                                 return err;
3363                         if (cam->disconnected)
3364                                 return -ENODEV;
3365                         break;
3366                 case F_READY:
3367                         break;
3368                 }
3369
3370                 if (w9968cf_vpp)
3371                         w9968cf_postprocess_frame(cam, fr);
3372
3373                 fr->status = F_UNUSED;
3374
3375                 DBG(5, "VIDIOCSYNC(%u) successfully called", f_num)
3376                 return 0;
3377         }
3378
3379         case VIDIOCGUNIT:/* report the unit numbers of the associated devices*/
3380         {
3381                 struct video_unit unit = {
3382                         .video = cam->v4ldev->minor,
3383                         .vbi = VIDEO_NO_UNIT,
3384                         .radio = VIDEO_NO_UNIT,
3385                         .audio = VIDEO_NO_UNIT,
3386                         .teletext = VIDEO_NO_UNIT,
3387                 };
3388
3389                 if (copy_to_user(arg, &unit, sizeof(unit)))
3390                         return -EFAULT;
3391
3392                 DBG(5, "VIDIOCGUNIT successfully called")
3393                 return 0;
3394         }
3395
3396         case VIDIOCKEY:
3397                 return 0;
3398
3399         case VIDIOCGFBUF:
3400         {
3401                 if (clear_user(arg, sizeof(struct video_buffer)))
3402                         return -EFAULT;
3403
3404                 DBG(5, "VIDIOCGFBUF successfully called")
3405                 return 0;
3406         }
3407
3408         case VIDIOCGTUNER:
3409         {
3410                 struct video_tuner tuner;
3411                 if (copy_from_user(&tuner, arg, sizeof(tuner)))
3412                         return -EFAULT;
3413
3414                 if (tuner.tuner != 0)
3415                         return -EINVAL;
3416
3417                 strcpy(tuner.name, "no_tuner");
3418                 tuner.rangelow = 0;
3419                 tuner.rangehigh = 0;
3420                 tuner.flags = VIDEO_TUNER_NORM;
3421                 tuner.mode = VIDEO_MODE_AUTO;
3422                 tuner.signal = 0xffff;
3423
3424                 if (copy_to_user(arg, &tuner, sizeof(tuner)))
3425                         return -EFAULT;
3426
3427                 DBG(5, "VIDIOCGTUNER successfully called")
3428                 return 0;
3429         }
3430
3431         case VIDIOCSTUNER:
3432         {
3433                 struct video_tuner tuner;
3434                 if (copy_from_user(&tuner, arg, sizeof(tuner)))
3435                         return -EFAULT;
3436
3437                 if (tuner.tuner != 0)
3438                         return -EINVAL;
3439
3440                 if (tuner.mode != VIDEO_MODE_AUTO)
3441                         return -EINVAL;
3442
3443                 DBG(5, "VIDIOCSTUNER successfully called")
3444                 return 0;
3445         }
3446
3447         case VIDIOCSFBUF:
3448         case VIDIOCCAPTURE:
3449         case VIDIOCGFREQ:
3450         case VIDIOCSFREQ:
3451         case VIDIOCGAUDIO:
3452         case VIDIOCSAUDIO:
3453         case VIDIOCSPLAYMODE:
3454         case VIDIOCSWRITEMODE:
3455         case VIDIOCGPLAYINFO:
3456         case VIDIOCSMICROCODE:
3457         case VIDIOCGVBIFMT:
3458         case VIDIOCSVBIFMT:
3459                 DBG(4, "Unsupported V4L1 IOCtl: VIDIOC%s "
3460                        "(type 0x%01X, "
3461                        "n. 0x%01X, "
3462                        "dir. 0x%01X, " 
3463                        "size 0x%02X)",
3464                     V4L1_IOCTL(cmd),
3465                     _IOC_TYPE(cmd),_IOC_NR(cmd),_IOC_DIR(cmd),_IOC_SIZE(cmd))
3466
3467                 return -EINVAL;
3468
3469         default:
3470                 DBG(4, "Invalid V4L1 IOCtl: VIDIOC%s "
3471                        "type 0x%01X, "
3472                        "n. 0x%01X, "
3473                        "dir. 0x%01X, "
3474                        "size 0x%02X",
3475                     V4L1_IOCTL(cmd),
3476                     _IOC_TYPE(cmd),_IOC_NR(cmd),_IOC_DIR(cmd),_IOC_SIZE(cmd))
3477
3478                 return -ENOIOCTLCMD;
3479
3480         } /* end of switch */
3481
3482 ioctl_fail:
3483         cam->misconfigured = 1;
3484         DBG(1, "VIDIOC%s failed because of hardware problems. "
3485                "To use the camera, close and open it again.", V4L1_IOCTL(cmd))
3486         return -EFAULT;
3487 }
3488
3489
3490 static struct file_operations w9968cf_fops = {
3491         .owner =   THIS_MODULE,
3492         .open =    w9968cf_open,
3493         .release = w9968cf_release,
3494         .read =    w9968cf_read,
3495         .ioctl =   w9968cf_ioctl,
3496         .mmap =    w9968cf_mmap,
3497         .llseek =  no_llseek,
3498 };
3499
3500
3501
3502 /****************************************************************************
3503  * USB probe and V4L registration, disconnect and id_table[] definition     *
3504  ****************************************************************************/
3505
3506 static int
3507 w9968cf_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
3508 {
3509         struct usb_device *udev = interface_to_usbdev(intf);
3510         struct w9968cf_device* cam;
3511         int err = 0;
3512         enum w9968cf_model_id mod_id;
3513         struct list_head* ptr;
3514         u8 sc = 0; /* number of simultaneous cameras */
3515         static unsigned short dev_nr = 0; /* we are handling device number n */
3516
3517         if (le16_to_cpu(udev->descriptor.idVendor)  == winbond_id_table[0].idVendor &&
3518             le16_to_cpu(udev->descriptor.idProduct) == winbond_id_table[0].idProduct)
3519                 mod_id = W9968CF_MOD_CLVBWGP; /* see camlist[] table */
3520         else if (le16_to_cpu(udev->descriptor.idVendor)  == winbond_id_table[1].idVendor &&
3521                  le16_to_cpu(udev->descriptor.idProduct) == winbond_id_table[1].idProduct)
3522                 mod_id = W9968CF_MOD_GENERIC; /* see camlist[] table */
3523         else
3524                 return -ENODEV;
3525
3526         cam = (struct w9968cf_device*)
3527                   kmalloc(sizeof(struct w9968cf_device), GFP_KERNEL);
3528         if (!cam)
3529                 return -ENOMEM;
3530
3531         memset(cam, 0, sizeof(*cam));
3532
3533         init_MUTEX(&cam->dev_sem);
3534         down(&cam->dev_sem);
3535
3536         cam->usbdev = udev;
3537         /* NOTE: a local copy is used to avoid possible race conditions */
3538         memcpy(&cam->dev, &udev->dev, sizeof(struct device));
3539
3540         DBG(2, "%s detected", symbolic(camlist, mod_id))
3541
3542         if (simcams > W9968CF_MAX_DEVICES)
3543                 simcams = W9968CF_SIMCAMS;
3544
3545         /* How many cameras are connected ? */
3546         down(&w9968cf_devlist_sem);
3547         list_for_each(ptr, &w9968cf_dev_list)
3548                 sc++;
3549         up(&w9968cf_devlist_sem);
3550
3551         if (sc >= simcams) {
3552                 DBG(2, "Device rejected: too many connected cameras "
3553                        "(max. %u)", simcams)
3554                 err = -EPERM;
3555                 goto fail;
3556         }
3557
3558
3559         /* Allocate 2 bytes of memory for camera control USB transfers */
3560         if (!(cam->control_buffer = (u16*)kmalloc(2, GFP_KERNEL))) {
3561                 DBG(1,"Couldn't allocate memory for camera control transfers")
3562                 err = -ENOMEM;
3563                 goto fail;
3564         }
3565         memset(cam->control_buffer, 0, 2);
3566
3567         /* Allocate 8 bytes of memory for USB data transfers to the FSB */
3568         if (!(cam->data_buffer = (u16*)kmalloc(8, GFP_KERNEL))) {
3569                 DBG(1, "Couldn't allocate memory for data "
3570                        "transfers to the FSB")
3571                 err = -ENOMEM;
3572                 goto fail;
3573         }
3574         memset(cam->data_buffer, 0, 8);
3575
3576         /* Register the V4L device */
3577         cam->v4ldev = video_device_alloc();
3578         if (!cam->v4ldev) {
3579                 DBG(1, "Could not allocate memory for a V4L structure")
3580                 err = -ENOMEM;
3581                 goto fail;
3582         }
3583
3584         strcpy(cam->v4ldev->name, symbolic(camlist, mod_id));
3585         cam->v4ldev->owner = THIS_MODULE;
3586         cam->v4ldev->type = VID_TYPE_CAPTURE | VID_TYPE_SCALES;
3587         cam->v4ldev->hardware = VID_HARDWARE_W9968CF;
3588         cam->v4ldev->fops = &w9968cf_fops;
3589         cam->v4ldev->minor = video_nr[dev_nr];
3590         cam->v4ldev->release = video_device_release;
3591         video_set_drvdata(cam->v4ldev, cam);
3592         cam->v4ldev->dev = &cam->dev;
3593
3594         err = video_register_device(cam->v4ldev, VFL_TYPE_GRABBER,
3595                                     video_nr[dev_nr]);
3596         if (err) {
3597                 DBG(1, "V4L device registration failed")
3598                 if (err == -ENFILE && video_nr[dev_nr] == -1)
3599                         DBG(2, "Couldn't find a free /dev/videoX node")
3600                 video_nr[dev_nr] = -1;
3601                 dev_nr = (dev_nr < W9968CF_MAX_DEVICES-1) ? dev_nr+1 : 0;
3602                 goto fail;
3603         }
3604
3605         DBG(2, "V4L device registered as /dev/video%d", cam->v4ldev->minor)
3606
3607         /* Set some basic constants */
3608         w9968cf_configure_camera(cam, udev, mod_id, dev_nr);
3609
3610         /* Add a new entry into the list of V4L registered devices */
3611         down(&w9968cf_devlist_sem);
3612         list_add(&cam->v4llist, &w9968cf_dev_list);
3613         up(&w9968cf_devlist_sem);
3614         dev_nr = (dev_nr < W9968CF_MAX_DEVICES-1) ? dev_nr+1 : 0;
3615
3616         w9968cf_turn_on_led(cam);
3617
3618         w9968cf_i2c_init(cam);
3619
3620         usb_set_intfdata(intf, cam);
3621         up(&cam->dev_sem);
3622         return 0;
3623
3624 fail: /* Free unused memory */
3625         kfree(cam->control_buffer);
3626         kfree(cam->data_buffer);
3627         if (cam->v4ldev)
3628                 video_device_release(cam->v4ldev);
3629         up(&cam->dev_sem);
3630         kfree(cam);
3631         return err;
3632 }
3633
3634
3635 static void w9968cf_usb_disconnect(struct usb_interface* intf)
3636 {
3637         struct w9968cf_device* cam = 
3638            (struct w9968cf_device*)usb_get_intfdata(intf);
3639
3640         down_write(&w9968cf_disconnect);
3641
3642         if (cam) {
3643                 /* Prevent concurrent accesses to data */
3644                 down(&cam->dev_sem); 
3645
3646                 cam->disconnected = 1;
3647
3648                 DBG(2, "Disconnecting %s...", symbolic(camlist, cam->id))
3649
3650                 wake_up_interruptible_all(&cam->open);
3651
3652                 if (cam->users) {
3653                         DBG(2, "The device is open (/dev/video%d)! "
3654                                "Process name: %s. Deregistration and memory "
3655                                "deallocation are deferred on close.",
3656                             cam->v4ldev->minor, cam->command)
3657                         cam->misconfigured = 1;
3658                         w9968cf_stop_transfer(cam);
3659