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