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