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