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