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