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