1 /***************************************************************************
2 * Video4Linux driver for W996[87]CF JPEG USB Dual Mode Camera Chip. *
4 * Copyright (C) 2002 2003 by Luca Risolia <luca.risolia@studio.unibo.it> *
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. *
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. *
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. *
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 ***************************************************************************/
28 #include <linux/version.h>
29 #include <linux/module.h>
30 #include <linux/kernel.h>
31 #include <linux/init.h>
33 #include <linux/vmalloc.h>
34 #include <linux/slab.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>
44 #include <asm/uaccess.h>
47 #include "w9968cf_decoder.h"
50 /****************************************************************************
51 * Module macros and paramaters *
52 ****************************************************************************/
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");
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};
89 static u8 debug = W9968CF_DEBUG_LEVEL;
90 static u8 specific_debug = W9968CF_SPECIFIC_DEBUG;
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");
120 MODULE_PARM(debug, "i");
121 MODULE_PARM(specific_debug, "b");
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)"."
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)"."
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)
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."
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)")."
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)")."
165 MODULE_PARM_DESC(double_buffer,
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)
174 MODULE_PARM_DESC(clamping,
175 "\n<0|1[,...]> Video data clamping: 0 disabled, 1 enabled."
176 "\nDefault value is "__MODULE_STRING(W9968CF_CLAMPING)
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)
185 "\nThe filter is used to reduce noise and aliasing artifacts"
186 "\nproduced by the CCD or CMOS sensor, and the scaling"
189 MODULE_PARM_DESC(largeview,
190 "\n<0|1[,...]> Large view: 0 disabled, 1 enabled."
191 "\nDefault value is "__MODULE_STRING(W9968CF_LARGEVIEW)
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"
199 "\nDefault value is "__MODULE_STRING(W9968CF_UPSCALING)
201 "\nIf 'w9968cf-vpp' is not loaded, this paramater is"
204 MODULE_PARM_DESC(decompression,
205 "\n<0|1|2[,...]> Software video decompression:"
206 "\n- 0 disables decompression (doesn't allow formats needing"
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"
213 "\nin any resolutions where both width and height are "
215 "\nDefault value is "__MODULE_STRING(W9968CF_DECOMPRESSION)
217 "\nIf 'w9968cf-vpp' is not loaded, forcing decompression is "
218 "\nnot allowed; in this case this paramater is set to 2."
220 MODULE_PARM_DESC(force_palette,
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)
234 " Force picture palette."
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"
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)
263 MODULE_PARM_DESC(autobright,
264 "\n<0|1[,...]> CMOS sensor automatically changes brightness:"
266 "\nDefault value is "__MODULE_STRING(W9968CF_AUTOBRIGHT)
269 MODULE_PARM_DESC(autoexp,
270 "\n<0|1[,...]> CMOS sensor automatically changes exposure:"
272 "\nDefault value is "__MODULE_STRING(W9968CF_AUTOEXP)
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)
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)"
289 "\nDefault value is "__MODULE_STRING(W9968CF_BANDINGFILTER)
292 MODULE_PARM_DESC(clockdiv,
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)
301 MODULE_PARM_DESC(backlight,
302 "\n<0|1[,...]> Objects are lit from behind:"
304 "\nDefault value is "__MODULE_STRING(W9968CF_BACKLIGHT)
307 MODULE_PARM_DESC(mirror,
308 "\n<0|1[,...]> Reverse image horizontally:"
310 "\nDefault value is "__MODULE_STRING(W9968CF_MIRROR)
313 MODULE_PARM_DESC(monochrome,
314 "\n<0|1[,...]> Use OV CMOS sensor as monochrome sensor:"
316 "\nNot all the sensors support monochrome color."
317 "\nDefault value is "__MODULE_STRING(W9968CF_MONOCHROME)
320 MODULE_PARM_DESC(brightness,
321 "\n<n[,...]> Set picture brightness (0-65535)."
322 "\nDefault value is "__MODULE_STRING(W9968CF_BRIGHTNESS)
324 "\nThis parameter has no effect if 'autobright' is enabled."
326 MODULE_PARM_DESC(hue,
327 "\n<n[,...]> Set picture hue (0-65535)."
328 "\nDefault value is "__MODULE_STRING(W9968CF_HUE)
331 MODULE_PARM_DESC(colour,
332 "\n<n[,...]> Set picture saturation (0-65535)."
333 "\nDefault value is "__MODULE_STRING(W9968CF_COLOUR)
336 MODULE_PARM_DESC(contrast,
337 "\n<n[,...]> Set picture contrast (0-65535)."
338 "\nDefault value is "__MODULE_STRING(W9968CF_CONTRAST)
341 MODULE_PARM_DESC(whiteness,
342 "\n<n[,...]> Set picture whiteness (0-65535)."
343 "\nDefault value is "__MODULE_STRING(W9968CF_WHITENESS)
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"
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)"."
360 MODULE_PARM_DESC(specific_debug,
361 "\n<0|1> Enable or disable specific debugging messages:"
362 "\n0 = print messages concerning every level"
364 "\n1 = print messages concerning the level"
365 " indicated by 'debug'."
366 "\nDefault value is "
367 __MODULE_STRING(W9968CF_SPECIFIC_DEBUG)"."
369 #endif /* W9968CF_DEBUG */
373 /****************************************************************************
375 ****************************************************************************/
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*);
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*);
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*);
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,
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,
435 static void w9968cf_i2c_inc_use(struct i2c_adapter*);
436 static void w9968cf_i2c_dec_use(struct i2c_adapter*);
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*);
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);
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*);
476 /* Intermodule communication */
477 static int w9968cf_vppmod_detect(void);
478 static void w9968cf_vppmod_release(void);
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);
492 /****************************************************************************
494 ****************************************************************************/
496 /* Used to represent a list of values and their respective symbolic names */
497 struct w9968cf_symbolic_list {
502 /*--------------------------------------------------------------------------
503 Returns the name of the matching element in the symbolic_list array. The
504 end of the list must be marked with an element that has a NULL name.
505 --------------------------------------------------------------------------*/
506 static inline const char *
507 symbolic(struct w9968cf_symbolic_list list[], const int num)
511 for (i = 0; list[i].name != NULL; i++)
512 if (list[i].num == num)
513 return (list[i].name);
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" },
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" },
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" },
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" },
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" },
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)" },
597 /****************************************************************************
598 * Memory management functions *
599 ****************************************************************************/
601 /* Here we want the physical address of the memory.
602 This is used when initializing the contents of the area. */
603 static inline unsigned long kvirt_to_pa(unsigned long adr)
605 unsigned long kva, ret;
607 kva = (unsigned long) page_address(vmalloc_to_page((void *)adr));
608 kva |= adr & (PAGE_SIZE-1); /* restore the offset */
614 static void* rvmalloc(unsigned long size)
619 size = PAGE_ALIGN(size);
620 mem = vmalloc_32(size);
624 memset(mem, 0, size); /* Clear the ram out, no junk to the user */
625 adr = (unsigned long) mem;
627 mem_map_reserve(vmalloc_to_page((void *)adr));
636 static void rvfree(void* mem, unsigned long size)
643 adr = (unsigned long) mem;
644 while ((long) size > 0) {
645 mem_map_unreserve(vmalloc_to_page((void *)adr));
653 /*--------------------------------------------------------------------------
654 Return the maximum size (in bytes) of a frame buffer.
655 --------------------------------------------------------------------------*/
656 static inline unsigned long w9968cf_get_max_bufsize(struct w9968cf_device* cam)
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;
664 /*--------------------------------------------------------------------------
665 Deallocate previously allocated memory.
666 --------------------------------------------------------------------------*/
667 static void w9968cf_deallocate_memory(struct w9968cf_device* cam)
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;
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;
683 /* Free helper buffer */
684 if (cam->vpp_buffer) {
685 rvfree(cam->vpp_buffer, w9968cf_get_max_bufsize(cam));
686 cam->vpp_buffer = NULL;
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;
698 DBG(5, "Memory successfully deallocated.")
702 /*--------------------------------------------------------------------------
703 Allocate memory buffers for USB transfers and video frames.
704 This function is called by open() only.
705 Return 0 on success, a negative number otherwise.
706 --------------------------------------------------------------------------*/
707 static int w9968cf_allocate_memory(struct w9968cf_device* cam)
709 const unsigned long bufsize = w9968cf_get_max_bufsize(cam);
710 const u16 p_size = wMaxPacketSize[cam->altsetting-1];
714 /* NOTE: Deallocation is done elsewhere in case of error */
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)
725 memset(cam->transfer_buffer[i], 0, W9968CF_ISO_PACKETS*p_size);
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)
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)
743 cam->vpp_buffer = NULL;
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)))
755 DBG(1, "Couldn't allocate memory for the video frame buffers.")
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)
765 for (i = 0; i < cam->nbuffers; i++) {
766 cam->frame[i].buffer = buff + i*bufsize;
768 if (i != cam->nbuffers-1)
769 cam->frame[i].next = &cam->frame[i+1];
771 cam->frame[i].next = &cam->frame[0];
772 cam->frame[i].status = F_UNUSED;
775 DBG(5, "Memory successfully allocated.")
781 /****************************************************************************
783 ****************************************************************************/
785 #if defined(CONFIG_VIDEO_PROC_FS)
787 static struct proc_dir_entry* w9968cf_proc_entry, * w9968cf_proc_entry_global;
788 extern struct proc_dir_entry* video_proc_entry;
790 #define YES_NO(x) ((x) ? "yes" : "no")
792 /*--------------------------------------------------------------------------
793 Read /proc/video/w9968cf/global
794 --------------------------------------------------------------------------*/
796 w9968cf_proc_read_global(char* page, char** start, off_t offset,
797 int count, int* eof, void* data)
799 struct list_head *list = (struct list_head*)data, *ptr;
800 struct w9968cf_device* cam;
805 if (down_interruptible(&w9968cf_devlist_sem))
808 /* How many connected cameras ? */
809 list_for_each(ptr, list)
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);
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));
827 up(&w9968cf_devlist_sem);
838 *start = page + offset;
844 /*--------------------------------------------------------------------------
845 Read /proc/video/w9968cf/dev<minor#>
846 --------------------------------------------------------------------------*/
848 w9968cf_proc_read_dev(char* page, char** start, off_t offset,
849 int count, int* eof, void* data)
851 struct w9968cf_device* cam = (struct w9968cf_device* )data;
855 if (down_interruptible(&cam->procfs_sem))
859 w9968cf_sensor_get_picture(cam);
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));
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);
915 out += sprintf(out,"debug_level : %d\n",debug);
916 out += sprintf(out,"specific_debug : %s\n",YES_NO(specific_debug));
924 up(&cam->procfs_sem);
930 *start = page + offset;
932 up(&cam->procfs_sem);
937 static void w9968cf_proc_create_dev(struct w9968cf_device* cam)
941 if (!w9968cf_proc_entry)
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,
948 w9968cf_proc_read_dev,
952 cam->proc_dev->owner = THIS_MODULE;
954 DBG(2, "Per-device entry /proc/video/w9968cf/dev%d created.",
959 static void w9968cf_proc_destroy_dev(struct w9968cf_device* cam)
966 sprintf(name, "dev%d", cam->v4ldev->minor);
968 /* Destroy per-device entry */
969 remove_proc_entry(name, w9968cf_proc_entry);
971 DBG(2, "Per-device entry /proc/video/w9968cf/dev%d removed.",
976 static void w9968cf_proc_create(void)
978 if (!video_proc_entry) {
979 DBG(2, "Error: /proc/video/ does not exist.")
983 w9968cf_proc_entry = create_proc_entry("w9968cf", S_IFDIR,
985 if (!w9968cf_proc_entry) {
986 DBG(2, "Unable to create /proc/video/w9968cf/")
989 w9968cf_proc_entry->owner = THIS_MODULE;
991 w9968cf_proc_entry_global = create_proc_read_entry("global",
992 S_IFREG|S_IRUGO|S_IWUSR,
994 w9968cf_proc_read_global,
995 (void*)&w9968cf_dev_list);
996 if (w9968cf_proc_entry_global)
997 w9968cf_proc_entry_global->owner = THIS_MODULE;
999 DBG(2, "Unable to create /proc/video/w9968cf/global")
1001 DBG(2, "Main entry /proc/video/w9968cf/global created.")
1005 static void w9968cf_proc_destroy(void)
1007 if (!w9968cf_proc_entry)
1010 if (w9968cf_proc_entry_global)
1011 remove_proc_entry("global", w9968cf_proc_entry);
1013 remove_proc_entry("w9968cf", video_proc_entry);
1015 DBG(2, "Main entry /proc/video/w9968cf/global removed.")
1018 #endif /* CONFIG_VIDEO_PROC_FS */
1022 /****************************************************************************
1023 * USB-specific functions *
1024 ****************************************************************************/
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
1035 --------------------------------------------------------------------------*/
1036 static void w9968cf_urb_complete(struct urb *urb)
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;
1046 if ((!cam->streaming) || cam->disconnected) {
1047 DBG(4, "Got interrupt, but not streaming.")
1051 maxbufsize = min( (unsigned long)W9968CF_HW_BUF_SIZE,
1052 w9968cf_get_max_bufsize(cam) );
1054 /* "(*f)" will be used instead of "cam->frame_current" */
1055 f = &cam->frame_current;
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,
1066 DBG(6, "Switched from temp. frame to frame #%d",
1067 (*f) - &cam->frame[0])
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;
1076 if (status && len != 0) {
1077 DBG(4, "URB failed, error in data packet "
1079 status, symbolic(urb_errlist, status))
1080 (*f)->status = F_ERROR;
1084 if (len) { /* start of frame */
1086 if ((*f)->status == F_UNUSED) {
1087 (*f)->status = F_GRABBING;
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;
1097 if ((*f)->status == F_GRABBING) {
1098 memcpy((*f)->buffer + (*f)->length, pos, len);
1099 (*f)->length += len;
1102 } else if ((*f)->status == F_GRABBING) { /* end of frame */
1104 DBG(6, "Frame #%d successfully grabbed.",
1105 ((*f)==&cam->frame_tmp ? -1 : (*f)-&cam->frame[0]))
1107 if (cam->vpp_flag & VPP_DECOMPRESSION) {
1108 err=(*w9968cf_vpp_check_headers)((*f)->buffer,
1111 DBG(4, "Skip corrupted frame: %s",
1112 symbolic(decoder_errlist, err))
1113 (*f)->status = F_UNUSED;
1114 continue; /* grab this frame again */
1118 (*f)->status = F_READY;
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);
1126 cam->frame_current = &cam->frame_tmp;
1127 (*f)->status = F_UNUSED;
1130 } else if ((*f)->status == F_ERROR)
1131 (*f)->status = F_UNUSED; /* grab it again */
1133 PDBGG("Frame length %li | pack.#%d | pack.len. %d | state %d",
1134 (unsigned long)(*f)->length, i, len, (*f)->status)
1138 /* Resubmit this URB */
1139 urb->dev = cam->usbdev;
1141 spin_lock(&cam->urb_lock);
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));
1148 spin_unlock(&cam->urb_lock);
1150 /* Wake up the user process */
1151 if (waitqueue_active(&cam->wait_queue))
1152 wake_up_interruptible(&cam->wait_queue);
1156 /*---------------------------------------------------------------------------
1157 Setup the URB structures for the isochronous transfer.
1158 Submit the URBs so that the data transfer begins.
1159 Return 0 on success, a negative number otherwise.
1160 ---------------------------------------------------------------------------*/
1161 static int w9968cf_start_transfer(struct w9968cf_device* cam)
1163 struct usb_device *udev = cam->usbdev;
1165 const u16 p_size = wMaxPacketSize[cam->altsetting-1];
1172 for (i = 0; i < W9968CF_URBS; i++) {
1173 urb = usb_alloc_urb(W9968CF_ISO_PACKETS);
1176 for (j = 0; j < i; j++)
1177 usb_free_urb(cam->urb[j]);
1178 DBG(1, "Couldn't allocate the URB structures.")
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;
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;
1196 /* Transfer size per frame, in WORD ! */
1201 t_size = (w*h*d)/16;
1203 err = w9968cf_write_reg(cam, 0xbf17, 0x00); /* reset everything */
1204 err += w9968cf_write_reg(cam, 0xbf10, 0x00); /* normal operation */
1207 err += w9968cf_write_reg(cam, t_size & 0xffff, 0x3d); /* low bits */
1208 err += w9968cf_write_reg(cam, t_size >> 16, 0x3e); /* high bits */
1210 if (cam->vpp_flag & VPP_DECOMPRESSION)
1211 err += w9968cf_upload_quantizationtables(cam);
1213 vidcapt = w9968cf_read_reg(cam, 0x16); /* read picture settings */
1214 err += w9968cf_write_reg(cam, vidcapt|0x8000, 0x16); /* capt. enable */
1216 err += usb_set_interface(udev, 0, cam->altsetting);
1217 err += w9968cf_write_reg(cam, 0x8a05, 0x3c); /* USB FIFO enable */
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.")
1226 w9968cf_init_framelist(cam);
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;
1233 if (!(cam->vpp_flag & VPP_DECOMPRESSION))
1234 DBG(5, "Isochronous transfer size: %li bytes/frame.",
1235 (unsigned long)t_size*2)
1237 DBG(5, "Starting the isochronous transfer...")
1239 /* Submit the URBs */
1240 for (i = 0; i < W9968CF_URBS; i++) {
1241 err = usb_submit_urb(cam->urb[i]);
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))
1258 /*--------------------------------------------------------------------------
1259 Stop the isochronous transfer and set alternate setting to 0 (0Mb/s).
1260 Return 0 on success, a negative number otherwise.
1261 --------------------------------------------------------------------------*/
1262 static int w9968cf_stop_transfer(struct w9968cf_device* cam)
1264 struct usb_device *udev = cam->usbdev;
1265 unsigned long lock_flags;
1269 /* This avoids race conditions with usb_submit_urb()
1270 in the URB completition handler */
1271 spin_lock_irqsave(&cam->urb_lock, lock_flags);
1273 spin_unlock_irqrestore(&cam->urb_lock, lock_flags);
1275 for (i = W9968CF_URBS-1; i >= 0; i--)
1277 if (!usb_unlink_urb(cam->urb[i])) {
1278 usb_free_urb(cam->urb[i]);
1283 if (cam->disconnected)
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 */
1292 DBG(2, "Failed to tell the camera to stop the isochronous "
1293 "transfer. However this is not a critical error.")
1298 DBG(5, "Isochronous transfer stopped.")
1303 /*--------------------------------------------------------------------------
1304 Write a W9968CF register.
1305 Return 0 on success, -1 otherwise.
1306 --------------------------------------------------------------------------*/
1307 static int w9968cf_write_reg(struct w9968cf_device* cam, u16 value, u16 index)
1309 struct usb_device* udev = cam->usbdev;
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);
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))
1321 return (res >= 0) ? 0 : -1;
1325 /*--------------------------------------------------------------------------
1326 Read a W9968CF register.
1327 Return the register value on success, -1 otherwise.
1328 --------------------------------------------------------------------------*/
1329 static int w9968cf_read_reg(struct w9968cf_device* cam, u16 index)
1331 struct usb_device* udev = cam->usbdev;
1332 u16* buff = cam->control_buffer;
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);
1340 DBG(4, "Failed to read a register "
1341 "(index 0x%02X, error #%d, %s).",
1342 index, res, symbolic(urb_errlist, res))
1344 return (res >= 0) ? (int)(*buff) : -1;
1348 /*--------------------------------------------------------------------------
1349 Write 64-bit data to the fast serial bus registers.
1350 Return 0 on success, -1 otherwise.
1351 --------------------------------------------------------------------------*/
1352 static int w9968cf_write_fsb(struct w9968cf_device* cam, u16* data)
1354 struct usb_device* udev = cam->usbdev;
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);
1365 DBG(4, "Failed to write the FSB registers "
1366 "(error #%d, %s).", res, symbolic(urb_errlist, res))
1368 return (res >= 0) ? 0 : -1;
1372 /*--------------------------------------------------------------------------
1373 Write data to the serial bus control register.
1374 Return 0 on success, a negative number otherwise.
1375 --------------------------------------------------------------------------*/
1376 static int w9968cf_write_sb(struct w9968cf_device* cam, u16 value)
1380 err = w9968cf_write_reg(cam, value, 0x01);
1381 udelay(W9968CF_I2C_BUS_DELAY);
1387 /*--------------------------------------------------------------------------
1388 Read data from the serial bus control register.
1389 Return 0 on success, a negative number otherwise.
1390 --------------------------------------------------------------------------*/
1391 static int w9968cf_read_sb(struct w9968cf_device* cam)
1395 v = w9968cf_read_reg(cam, 0x01);
1396 udelay(W9968CF_I2C_BUS_DELAY);
1402 /*--------------------------------------------------------------------------
1403 Upload quantization tables for the JPEG compression.
1404 This function is called by w9968cf_start_transfer().
1405 Return 0 on success, a negative number otherwise.
1406 --------------------------------------------------------------------------*/
1407 static int w9968cf_upload_quantizationtables(struct w9968cf_device* cam)
1412 err += w9968cf_write_reg(cam, 0x0010, 0x39); /* JPEG clock enable */
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);
1420 err += w9968cf_write_reg(cam, 0x0012, 0x39); /* JPEG encoder enable */
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 ****************************************************************************/
1435 static int w9968cf_smbus_start(struct w9968cf_device* cam)
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 */
1446 static int w9968cf_smbus_stop(struct w9968cf_device* cam)
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 */
1457 static int w9968cf_smbus_write_byte(struct w9968cf_device* cam, u8 v)
1462 for (bit = 0 ; bit < 8 ; bit++) {
1463 sda = (v & 0x80) ? 2 : 0;
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);
1477 static int w9968cf_smbus_read_byte(struct w9968cf_device* cam, u8* v)
1483 for (bit = 0 ; bit < 8 ; bit++) {
1485 err += w9968cf_write_sb(cam, 0x0013);
1486 *v |= (w9968cf_read_sb(cam) & 0x0008) ? 1 : 0;
1487 err += w9968cf_write_sb(cam, 0x0012);
1494 static int w9968cf_smbus_write_ack(struct w9968cf_device* cam)
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 */
1506 static int w9968cf_smbus_read_ack(struct w9968cf_device* cam)
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 */
1516 DBG(6, "Couldn't receive the ACK.")
1524 /* This is seems to refresh the communication through the serial bus */
1525 static int w9968cf_smbus_refresh_bus(struct w9968cf_device* cam)
1529 for (j = 1; j <= 10; j++) {
1530 err = w9968cf_write_reg(cam, 0x0020, 0x01);
1531 err += w9968cf_write_reg(cam, 0x0000, 0x01);
1540 /* SMBus protocol: S Addr Wr [A] Subaddr [A] Value [A] P */
1542 w9968cf_i2c_adap_fastwrite_byte_data(struct w9968cf_device* cam,
1543 u16 address, u8 subaddress,u8 value)
1545 u16* data = cam->data_buffer;
1548 err += w9968cf_smbus_refresh_bus(cam);
1550 /* Enable SBUS outputs */
1551 err += w9968cf_write_sb(cam, 0x0020);
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;
1564 err += w9968cf_write_fsb(cam, data);
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;
1578 err += w9968cf_write_fsb(cam, data);
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;
1592 err += w9968cf_write_fsb(cam, data);
1594 /* Disable SBUS outputs */
1595 err += w9968cf_write_sb(cam, 0x0000);
1598 DBG(5, "I2C write byte data done, addr.0x%04X, subaddr.0x%02X "
1599 "value 0x%02X.", address, subaddress, value)
1601 DBG(5, "I2C write byte data failed, addr.0x%04X, "
1602 "subaddr.0x%02X, value 0x%02X.",
1603 address, subaddress, value)
1609 /* SMBus protocol: S Addr Wr [A] Subaddr [A] P S Addr+1 Rd [A] [Value] NA P */
1611 w9968cf_i2c_adap_read_byte_data(struct w9968cf_device* cam,
1612 u16 address, u8 subaddress,
1617 /* Serial data enable */
1618 err += w9968cf_write_sb(cam, 0x0013); /* don't change ! */
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);
1633 /* Serial data disable */
1634 err += w9968cf_write_sb(cam, 0x0000);
1637 DBG(5, "I2C read byte data done, addr.0x%04X, "
1638 "subaddr.0x%02X, value 0x%02X.",
1639 address, subaddress, *value)
1641 DBG(5, "I2C read byte data failed, addr.0x%04X, "
1642 "subaddr.0x%02X, wrong value 0x%02X.",
1643 address, subaddress, *value)
1649 /* SMBus protocol: S Addr+1 Rd [A] [Value] NA P */
1651 w9968cf_i2c_adap_read_byte(struct w9968cf_device* cam,
1652 u16 address, u8* value)
1656 /* Serial data enable */
1657 err += w9968cf_write_sb(cam, 0x0013);
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);
1666 /* Serial data disable */
1667 err += w9968cf_write_sb(cam, 0x0000);
1670 DBG(5, "I2C read byte done, addr.0x%04X."
1671 "value 0x%02X.", address, *value)
1673 DBG(5, "I2C read byte failed, addr.0x%04X."
1674 "wrong value 0x%02X.", address, *value)
1680 /* SMBus protocol: S Addr Wr [A] Value [A] P */
1682 w9968cf_i2c_adap_write_byte(struct w9968cf_device* cam,
1683 u16 address, u8 value)
1685 DBG(4, "i2c_write_byte() is an unsupported transfer mode.")
1691 /****************************************************************************
1692 * I2C interface to kernel *
1693 ****************************************************************************/
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)
1700 struct w9968cf_device* cam = adapter->data;
1709 DBG(4, "Rejected slave ID 0x%04X", addr)
1713 if (size == I2C_SMBUS_BYTE) {
1714 /* Why addr <<= 1? See OVXXX0_SID defines in ovcamchip.h */
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);
1722 } else if (size == I2C_SMBUS_BYTE_DATA) {
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);
1733 if (w9968cf_smbus_refresh_bus(cam)) {
1745 DBG(4, "Unsupported I2C transfer mode (%d)", size)
1753 static u32 w9968cf_i2c_func(struct i2c_adapter* adap)
1755 return I2C_FUNC_SMBUS_READ_BYTE |
1756 I2C_FUNC_SMBUS_READ_BYTE_DATA |
1757 I2C_FUNC_SMBUS_WRITE_BYTE_DATA;
1761 static int w9968cf_i2c_attach_inform(struct i2c_client* client)
1763 struct w9968cf_device* cam = client->adapter->data;
1764 const char* clientname = client->name;
1765 int id = client->driver->id, err = 0;
1767 if (id == I2C_DRIVERID_OVCAMCHIP) {
1768 cam->sensor_client = client;
1769 err = w9968cf_sensor_init(cam);
1771 cam->sensor_client = NULL;
1775 DBG(4, "Rejected client [%s] with driver [%s]",
1776 clientname, client->driver->name)
1780 DBG(5, "I2C attach client [%s] with driver [%s]",
1781 clientname, client->driver->name)
1787 static int w9968cf_i2c_detach_inform(struct i2c_client* client)
1789 struct w9968cf_device* cam = client->adapter->data;
1790 const char* clientname = client->name;
1792 if (cam->sensor_client == client) {
1793 cam->sensor_client = NULL;
1796 DBG(5, "I2C detach client [%s]", clientname)
1803 w9968cf_i2c_control(struct i2c_adapter* adapter, unsigned int cmd,
1810 static void w9968cf_i2c_inc_use(struct i2c_adapter* adap)
1816 static void w9968cf_i2c_dec_use(struct i2c_adapter* adap)
1822 static int w9968cf_i2c_init(struct w9968cf_device* cam)
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,
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,
1843 memcpy(&cam->i2c_adapter, &adap, sizeof(struct i2c_adapter));
1844 strcpy(cam->i2c_adapter.name, "w9968cf");
1845 cam->i2c_adapter.data = cam;
1847 DBG(6, "Registering I2C adapter with kernel...")
1849 err = i2c_add_adapter(&cam->i2c_adapter);
1851 DBG(1, "Failed to register the I2C adapter.")
1853 DBG(5, "I2C adapter registered.")
1860 /****************************************************************************
1861 * Helper functions *
1862 ****************************************************************************/
1864 /*--------------------------------------------------------------------------
1865 Turn on the LED on some webcams. A beep should be heard too.
1866 Return 0 on success, a negative number otherwise.
1867 --------------------------------------------------------------------------*/
1868 static int w9968cf_turn_on_led(struct w9968cf_device* cam)
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' */
1880 DBG(2, "Couldn't turn on the LED.")
1882 DBG(5, "LED turned on.")
1888 /*--------------------------------------------------------------------------
1889 Write some registers for the device initialization.
1890 This function is called once on open().
1891 Return 0 on success, a negative number otherwise.
1892 --------------------------------------------------------------------------*/
1893 static int w9968cf_init_chip(struct w9968cf_device* cam)
1897 err += w9968cf_write_reg(cam, 0xff00, 0x00); /* power off */
1898 err += w9968cf_write_reg(cam, 0xbf10, 0x00); /* power on */
1900 err += w9968cf_write_reg(cam, 0x405d, 0x03); /* DRAM timings */
1901 err += w9968cf_write_reg(cam, 0x0030, 0x04); /* SDRAM timings */
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 */
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 */
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 */
1926 err += w9968cf_set_picture(cam, cam->picture); /* this before */
1927 err += w9968cf_set_window(cam, cam->window);
1930 DBG(1, "Chip initialization failed.")
1932 DBG(5, "Chip successfully initialized.")
1938 /*--------------------------------------------------------------------------
1939 Change the picture settings of the camera.
1940 Return 0 on success, a negative number otherwise.
1941 --------------------------------------------------------------------------*/
1943 w9968cf_set_picture(struct w9968cf_device* cam, struct video_picture pict)
1945 u16 fmt, hw_depth, hw_palette, reg_v = 0x0000;
1948 /* Make sure we are using a valid depth */
1949 pict.depth = w9968cf_valid_depth(pict.palette);
1953 hw_depth = pict.depth; /* depth used by the winbond chip */
1954 hw_palette = pict.palette; /* palette used by the winbond chip */
1956 /* VS & HS polarities */
1957 reg_v = (cam->vs_polarity << 12) | (cam->hs_polarity << 11);
1961 case VIDEO_PALETTE_UYVY:
1963 cam->vpp_flag = VPP_NONE;
1965 case VIDEO_PALETTE_YUV422P:
1967 cam->vpp_flag = VPP_DECOMPRESSION;
1969 case VIDEO_PALETTE_YUV420:
1970 case VIDEO_PALETTE_YUV420P:
1972 cam->vpp_flag = VPP_DECOMPRESSION;
1974 case VIDEO_PALETTE_YUYV:
1975 case VIDEO_PALETTE_YUV422:
1977 cam->vpp_flag = VPP_SWAP_YUV_BYTES;
1978 hw_palette = VIDEO_PALETTE_UYVY;
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 */
1989 hw_palette = VIDEO_PALETTE_UYVY;
1990 cam->vpp_flag = VPP_UYVY_TO_RGBX;
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))
2002 if (cam->filter_type == 1)
2004 else if (cam->filter_type == 2)
2007 if ((err = w9968cf_write_reg(cam, reg_v, 0x16)))
2010 if ((err = w9968cf_sensor_update_picture(cam, pict)))
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;
2018 /* Settings changed, so we clear the frame buffers */
2019 memset(cam->frame[0].buffer, 0,
2020 cam->nbuffers*w9968cf_get_max_bufsize(cam));
2022 DBG(4, "Palette is %s, depth is %d bpp.",
2023 symbolic(v4l1_plist, pict.palette), pict.depth)
2028 DBG(1, "Failed to change picture settings.")
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 --------------------------------------------------------------------------*/
2039 w9968cf_set_window(struct w9968cf_device* cam, struct video_window win)
2041 u16 x, y, w, h, scx, scy, cw, ch, ax, ay;
2042 unsigned long fw, fh;
2043 struct ovcamchip_window s_win;
2046 /* Work around to avoid FP arithmetics */
2047 #define __SC(x) ((x) << 10)
2048 #define __UNSC(x) ((x) >> 10)
2050 /* Make sure we are using a supported resolution */
2051 if ((err = w9968cf_adjust_window_size(cam, (u16*)&win.width,
2052 (u16*)&win.height)))
2055 /* Scaling factors */
2056 fw = __SC(win.width) / cam->maxwidth;
2057 fh = __SC(win.height) / cam->maxheight;
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 */
2067 if (h < cam->minheight) /* just in case */
2070 cam->vpp_flag &= ~VPP_UPSCALE;
2075 /* x,y offsets of the cropped area */
2076 scx = cam->start_cropx;
2077 scy = cam->start_cropy;
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;
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 */
2095 s_win.x = (s_win.width - cw) / 2;
2096 s_win.y = (s_win.height - ch) / 2;
2099 if (cam->clockdiv >= 0)
2100 s_win.clockdiv = cam->clockdiv; /* manual override */
2102 switch (cam->sensor) {
2115 s_win.clockdiv = W9968CF_DEF_CLOCKDIVISOR;
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;
2128 if ((ax + cw) > cam->maxwidth)
2129 ax = cam->maxwidth - cw;
2131 if ((ay + ch) > cam->maxheight)
2132 ay = cam->maxheight - ch;
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);
2144 /* Offsets used by the chip */
2149 if ((err = w9968cf_sensor_cmd(cam, OVCAMCHIP_CMD_S_MODE, &s_win)))
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);
2159 /* JPEG width & height */
2160 err += w9968cf_write_reg(cam, w, 0x30);
2161 err += w9968cf_write_reg(cam, h, 0x31);
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);
2168 err += w9968cf_write_reg(cam, w, 0x2c);
2173 /* If all went well, update the device data structure */
2174 memcpy(&cam->window, &win, sizeof(win));
2178 /* Settings changed, so we clear the frame buffers */
2179 memset(cam->frame[0].buffer, 0,
2180 cam->nbuffers*w9968cf_get_max_bufsize(cam));
2182 DBG(4, "The capture area is %dx%d, Offset (x,y)=(%d,%d).",
2183 win.width, win.height, win.x, win.y)
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)
2193 DBG(1, "Failed to change the capture area size.")
2198 /*--------------------------------------------------------------------------
2199 Return non-zero if the palette is supported, 0 otherwise.
2200 --------------------------------------------------------------------------*/
2201 static inline u16 w9968cf_valid_palette(u16 palette)
2204 while (w9968cf_formatlist[i].palette != 0) {
2205 if (palette == w9968cf_formatlist[i].palette)
2213 /*--------------------------------------------------------------------------
2214 Return the depth corresponding to the given palette.
2215 Palette _must_ be supported !
2216 --------------------------------------------------------------------------*/
2217 static u16 w9968cf_valid_depth(u16 palette)
2220 while (w9968cf_formatlist[i].palette != palette)
2223 return w9968cf_formatlist[i].depth;
2227 /*--------------------------------------------------------------------------
2228 Return non-zero if the format requires decompression, 0 otherwise.
2229 --------------------------------------------------------------------------*/
2230 static inline u8 w9968cf_need_decompression(u16 palette)
2233 while (w9968cf_formatlist[i].palette != 0) {
2234 if (palette == w9968cf_formatlist[i].palette)
2235 return w9968cf_formatlist[i].compression;
2242 /*--------------------------------------------------------------------------
2243 Adjust the asked values for window width and height.
2244 Return 0 on success, -1 otherwise.
2245 --------------------------------------------------------------------------*/
2247 w9968cf_adjust_window_size(struct w9968cf_device* cam, u16* width, u16* height)
2251 if ((*width < cam->minwidth) || (*height < cam->minheight))
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;
2264 if (cam->vpp_flag & VPP_DECOMPRESSION) {
2265 *width &= ~15L; /* multiple of 16 */
2269 PDBGG("Window size adjusted w=%d, h=%d ", *width, *height)
2275 /*--------------------------------------------------------------------------
2276 Initialize the FIFO list of requested frames.
2277 --------------------------------------------------------------------------*/
2278 static void w9968cf_init_framelist(struct w9968cf_device* cam)
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;
2290 /*--------------------------------------------------------------------------
2291 Add a frame in the FIFO list of requested frames.
2292 This function is called in process context.
2293 --------------------------------------------------------------------------*/
2294 static void w9968cf_push_frame(struct w9968cf_device* cam, u8 f_num)
2297 unsigned long lock_flags;
2299 spin_lock_irqsave(&cam->flist_lock, lock_flags);
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 */
2306 spin_unlock_irqrestore(&cam->flist_lock, lock_flags);
2308 DBG(6, "Frame #%d pushed into the FIFO list. Position %d.", f_num, f)
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 --------------------------------------------------------------------------*/
2317 w9968cf_pop_frame(struct w9968cf_device* cam, struct w9968cf_frame_t** framep)
2321 spin_lock(&cam->flist_lock);
2323 *framep = cam->requested_frame[0];
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;
2330 spin_unlock(&cam->flist_lock);
2332 DBG(6,"Popped frame #%d from the list.",*framep-&cam->frame[0])
2336 /*--------------------------------------------------------------------------
2337 High-level video post-processing routine on grabbed frames.
2338 Return 0 on success, a negative number otherwise.
2339 --------------------------------------------------------------------------*/
2341 w9968cf_postprocess_frame(struct w9968cf_device* cam,
2342 struct w9968cf_frame_t* fr)
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;
2355 #define _PSWAP(pIn, pOut) {tmp = (pIn); (pIn) = (pOut); (pOut) = tmp;}
2357 if (cam->vpp_flag & VPP_DECOMPRESSION) {
2358 memcpy(pOut, pIn, fr->length);
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;
2365 DBG(4, "An error occurred while decoding the frame: "
2366 "%s.", symbolic(decoder_errlist, err))
2369 DBG(6, "Frame decoded")
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.")
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;
2381 DBG(6, "Vertical up-scaling done: %d,%d,%dbpp->%d,%d",
2382 hw_w, hw_h, hw_d, w, h)
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;
2389 DBG(6, "UYVY-16bit to %s conversion done.",
2390 symbolic(v4l1_plist, fmt))
2393 if (pOut == fr->buffer)
2394 memcpy(fr->buffer, cam->vpp_buffer, fr->length);
2401 /****************************************************************************
2402 * CMOS sensor control routines *
2403 ****************************************************************************/
2406 w9968cf_sensor_set_control(struct w9968cf_device* cam, int cid, int val)
2408 struct ovcamchip_control ctl;
2414 err = w9968cf_sensor_cmd(cam, OVCAMCHIP_CMD_S_CTRL, &ctl);
2421 w9968cf_sensor_get_control(struct w9968cf_device* cam, int cid, int* val)
2423 struct ovcamchip_control ctl;
2428 err = w9968cf_sensor_cmd(cam, OVCAMCHIP_CMD_G_CTRL, &ctl);
2437 w9968cf_sensor_cmd(struct w9968cf_device* cam, unsigned int cmd, void* arg)
2439 struct i2c_client* c = cam->sensor_client;
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;
2451 /*--------------------------------------------------------------------------
2452 Update some settings of the CMOS sensor.
2453 Returns: 0 on success, a negative number otherwise.
2454 --------------------------------------------------------------------------*/
2455 static int w9968cf_sensor_update_settings(struct w9968cf_device* cam)
2459 /* Auto brightness */
2460 err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_AUTOBRIGHT,
2466 err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_AUTOEXP,
2471 /* Banding filter */
2472 err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_BANDFILT,
2477 /* Light frequency */
2478 err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_FREQ,
2484 err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_BACKLIGHT,
2490 err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_MIRROR,
2499 /*--------------------------------------------------------------------------
2500 Get some current picture settings from the CMOS sensor and update the
2501 internal 'picture' structure of the camera.
2502 Returns: 0 on success, a negative number otherwise.
2503 --------------------------------------------------------------------------*/
2504 static int w9968cf_sensor_get_picture(struct w9968cf_device* cam)
2508 err = w9968cf_sensor_get_control(cam, OVCAMCHIP_CID_CONT, &v);
2511 cam->picture.contrast = v;
2513 err = w9968cf_sensor_get_control(cam, OVCAMCHIP_CID_BRIGHT, &v);
2516 cam->picture.brightness = v;
2518 err = w9968cf_sensor_get_control(cam, OVCAMCHIP_CID_SAT, &v);
2521 cam->picture.colour = v;
2523 err = w9968cf_sensor_get_control(cam, OVCAMCHIP_CID_HUE, &v);
2526 cam->picture.hue = v;
2528 DBG(5, "Got picture settings from the CMOS sensor.")
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)
2538 /*--------------------------------------------------------------------------
2539 Update picture settings of the CMOS sensor.
2540 Returns: 0 on success, a negative number otherwise.
2541 --------------------------------------------------------------------------*/
2543 w9968cf_sensor_update_picture(struct w9968cf_device* cam,
2544 struct video_picture pict)
2548 if ((!cam->sensor_initialized)
2549 || pict.contrast != cam->picture.contrast) {
2550 err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_CONT,
2554 DBG(4, "Contrast changed from %d to %d.",
2555 cam->picture.contrast, pict.contrast)
2556 cam->picture.contrast = pict.contrast;
2559 if (((!cam->sensor_initialized) ||
2560 pict.brightness != cam->picture.brightness) && (!cam->auto_brt)) {
2561 err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_BRIGHT,
2565 DBG(4, "Brightness changed from %d to %d.",
2566 cam->picture.brightness, pict.brightness)
2567 cam->picture.brightness = pict.brightness;
2570 if ((!cam->sensor_initialized) || pict.colour != cam->picture.colour) {
2571 err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_SAT,
2575 DBG(4, "Colour changed from %d to %d.",
2576 cam->picture.colour, pict.colour)
2577 cam->picture.colour = pict.colour;
2580 if ((!cam->sensor_initialized) || pict.hue != cam->picture.hue) {
2581 err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_HUE,
2585 DBG(4, "Hue changed from %d to %d.",
2586 cam->picture.hue, pict.hue)
2587 cam->picture.hue = pict.hue;
2593 DBG(4, "Failed to change sensor picture setting.")
2599 /****************************************************************************
2600 * Camera configuration *
2601 ****************************************************************************/
2603 /*--------------------------------------------------------------------------
2604 This function is called when a supported CMOS sensor is detected.
2605 Return 0 if the initialization succeeds, a negative number otherwise.
2606 --------------------------------------------------------------------------*/
2607 static int w9968cf_sensor_init(struct w9968cf_device* cam)
2611 if ((err = w9968cf_sensor_cmd(cam, OVCAMCHIP_CMD_INITIALIZE,
2615 if ((err = w9968cf_sensor_cmd(cam, OVCAMCHIP_CMD_Q_SUBTYPE,
2619 /* NOTE: Make sure width and height are a multiple of 16 */
2620 switch (cam->sensor_client->addr) {
2622 cam->maxwidth = 352;
2623 cam->maxheight = 288;
2625 cam->minheight = 48;
2628 cam->maxwidth = 640;
2629 cam->maxheight = 480;
2631 cam->minheight = 48;
2634 DBG(1, "Not supported CMOS sensor detected for %s.",
2635 symbolic(camlist, cam->id))
2639 /* These values depend on the ones in the ovxxx0.c sources */
2640 switch (cam->sensor) {
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;
2649 cam->start_cropx = 320;
2650 cam->start_cropy = 35;
2651 cam->vs_polarity = 1;
2652 cam->hs_polarity = 0;
2655 if ((err = w9968cf_sensor_update_settings(cam)))
2658 if ((err = w9968cf_sensor_update_picture(cam, cam->picture)))
2661 cam->sensor_initialized = 1;
2663 DBG(2, "%s CMOS sensor initialized.", symbolic(senlist, cam->sensor))
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)
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
2680 --------------------------------------------------------------------------*/
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)
2687 #ifdef CONFIG_VIDEO_PROC_FS
2688 init_MUTEX(&cam->procfs_sem);
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);
2696 cam->disconnected = 0;
2699 cam->sensor = CC_UNKNOWN;
2700 cam->sensor_initialized = 0;
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];
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];
2714 cam->double_buffer = (double_buffer[dev_nr] == 0 ||
2715 double_buffer[dev_nr] == 1)
2716 ? (u8)double_buffer[dev_nr]:W9968CF_DOUBLE_BUFFER;
2718 cam->clamping = (clamping[dev_nr] == 0 || clamping[dev_nr] == 1)
2719 ? (u8)clamping[dev_nr] : W9968CF_CLAMPING;
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;
2728 cam->largeview = (largeview[dev_nr] == 0 || largeview[dev_nr] == 1)
2729 ? (u8)largeview[dev_nr] : W9968CF_LARGEVIEW;
2731 cam->decompression = (decompression[dev_nr] == 0 ||
2732 decompression[dev_nr] == 1 ||
2733 decompression[dev_nr] == 2)
2734 ? (u8)decompression[dev_nr]:W9968CF_DECOMPRESSION;
2736 cam->upscaling = (upscaling[dev_nr] == 0 ||
2737 upscaling[dev_nr] == 1)
2738 ? (u8)upscaling[dev_nr] : W9968CF_UPSCALING;
2740 cam->auto_brt = (autobright[dev_nr] == 0 || autobright[dev_nr] == 1)
2741 ? (u8)autobright[dev_nr] : W9968CF_AUTOBRIGHT;
2743 cam->auto_exp = (autoexp[dev_nr] == 0 || autoexp[dev_nr] == 1)
2744 ? (u8)autoexp[dev_nr] : W9968CF_AUTOEXP;
2746 cam->lightfreq = (lightfreq[dev_nr] == 50 || lightfreq[dev_nr] == 60)
2747 ? (u8)lightfreq[dev_nr] : W9968CF_LIGHTFREQ;
2749 cam->bandfilt = (bandingfilter[dev_nr] == 0 ||
2750 bandingfilter[dev_nr] == 1)
2751 ? (u8)bandingfilter[dev_nr] : W9968CF_BANDINGFILTER;
2753 cam->backlight = (backlight[dev_nr] == 0 || backlight[dev_nr] == 1)
2754 ? (u8)backlight[dev_nr] : W9968CF_BACKLIGHT;
2756 cam->clockdiv = (clockdiv[dev_nr] == -1 || clockdiv[dev_nr] >= 0)
2757 ? (s8)clockdiv[dev_nr] : W9968CF_CLOCKDIV;
2759 cam->mirror = (mirror[dev_nr] == 0 || mirror[dev_nr] == 1)
2760 ? (u8)mirror[dev_nr] : W9968CF_MIRROR;
2762 cam->monochrome = (monochrome[dev_nr] == 0 || monochrome[dev_nr] == 1)
2763 ? monochrome[dev_nr] : W9968CF_MONOCHROME;
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;
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;
2780 cam->picture.palette = W9968CF_PALETTE_DECOMP_ON;
2783 cam->force_rgb = (force_rgb[dev_nr] == 0 || force_rgb[dev_nr] == 1)
2784 ? (u8)force_rgb[dev_nr] : W9968CF_FORCE_RGB;
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;
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;
2800 if (cam->picture.palette != VIDEO_PALETTE_UYVY)
2801 cam->force_palette = 0;
2802 cam->picture.palette = VIDEO_PALETTE_UYVY;
2805 cam->picture.depth = w9968cf_valid_depth(cam->picture.palette);
2807 DBG(3, "%s configured with settings #%d:",
2808 symbolic(camlist, cam->id), dev_nr)
2810 DBG(3, "- Data packet size for USB isochrnous transfer: %d bytes.",
2811 wMaxPacketSize[cam->altsetting-1])
2813 DBG(3, "- Number of requested video frame buffers: %d",
2816 if (cam->double_buffer)
2817 DBG(3, "- Hardware double buffering enabled.")
2819 DBG(3, "- Hardware double buffering disabled.")
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.")
2829 DBG(3, "- Video data clamping (CCIR-601 format) enabled.")
2831 DBG(3, "- Video data clamping (CCIR-601 format) disabled.")
2834 DBG(3, "- Large view enabled.")
2836 DBG(3, "- Large view disabled.")
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.")
2846 DBG(3, "- Software image scaling enabled.")
2848 DBG(3, "- Software image scaling disabled.")
2850 if (cam->force_palette)
2851 DBG(3, "- Image palette forced to %s.",
2852 symbolic(v4l1_plist, cam->picture.palette))
2855 DBG(3, "- RGB component ordering will be used instead of BGR.")
2858 DBG(3, "- Auto brightness enabled.")
2860 DBG(3, "- Auto brightness disabled.")
2863 DBG(3, "- Auto exposure enabled.")
2865 DBG(3, "- Auto exposure disabled.")
2868 DBG(3, "- Backlight exposure algorithm enabled.")
2870 DBG(3, "- Backlight exposure algorithm disabled.")
2873 DBG(3, "- Mirror enabled.")
2875 DBG(3, "- Mirror disabled.")
2878 DBG(3, "- Banding filter enabled.")
2880 DBG(3, "- Banding filter disabled.")
2882 DBG(3, "- Power lighting frequency: %d", cam->lightfreq)
2884 if (cam->clockdiv == -1)
2885 DBG(3, "- Automatic clock divisor enabled.")
2887 DBG(3, "- Clock divisor: %d", cam->clockdiv)
2889 if (cam->monochrome)
2890 DBG(3, "- CMOS sensor used as monochrome.")
2892 DBG(3, "- CMOS sensor not used as monochrome.")
2896 /*--------------------------------------------------------------------------
2897 Release the resources used by the driver.
2898 This function is called on disconnect
2899 (or on close if deallocation has been deferred)
2900 --------------------------------------------------------------------------*/
2901 static void w9968cf_release_resources(struct w9968cf_device* cam)
2903 down(&w9968cf_devlist_sem);
2905 DBG(2, "V4L device deregistered: /dev/video%d", cam->v4ldev->minor)
2907 #ifdef CONFIG_VIDEO_PROC_FS
2908 w9968cf_proc_destroy_dev(cam);
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);
2917 up(&w9968cf_devlist_sem);
2919 DBG(5, "Resources released.")
2924 /****************************************************************************
2925 * Video4Linux interface *
2926 ****************************************************************************/
2928 static int w9968cf_open(struct inode* inode, struct file* filp)
2930 struct w9968cf_device* cam;
2933 cam = (struct w9968cf_device*)video_get_drvdata(video_devdata(filp));
2935 down(&cam->dev_sem);
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)
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)) {
2951 return -EWOULDBLOCK;
2954 err = wait_event_interruptible(cam->open, cam->disconnected ||
2958 if (cam->disconnected)
2960 down(&cam->dev_sem);
2963 DBG(5, "Opening the %s, /dev/video%d ...",
2964 symbolic(camlist, cam->id), cam->v4ldev->minor)
2967 cam->misconfigured = 0;
2969 if (!w9968cf_vppmod_present)
2970 w9968cf_vppmod_detect();
2972 if ((err = w9968cf_allocate_memory(cam)))
2973 goto deallocate_memory;
2975 if ((err = w9968cf_init_chip(cam)))
2976 goto deallocate_memory;
2978 if ((err = w9968cf_start_transfer(cam)))
2979 goto deallocate_memory;
2981 filp->private_data = cam;
2984 strcpy(cam->command, current->comm);
2986 init_waitqueue_head(&cam->wait_queue);
2990 DBG(5, "Video device is open.")
2994 w9968cf_deallocate_memory(cam);
2995 DBG(2, "Failed to open the video device.")
3001 static int w9968cf_release(struct inode* inode, struct file* filp)
3003 struct w9968cf_device* cam;
3005 cam = (struct w9968cf_device*)video_get_drvdata(video_devdata(filp));
3007 down(&cam->dev_sem); /* prevent disconnect() to be called */
3009 w9968cf_stop_transfer(cam);
3011 if (cam->disconnected) {
3012 w9968cf_release_resources(cam);
3019 w9968cf_deallocate_memory(cam);
3021 if (waitqueue_active(&cam->open))
3022 wake_up_interruptible(&cam->open);
3024 DBG(5, "Video device closed.")
3031 w9968cf_read(struct file* filp, char* buf, size_t count, loff_t* f_pos)
3033 struct w9968cf_device* cam;
3034 struct w9968cf_frame_t* fr;
3037 cam = (struct w9968cf_device*)video_get_drvdata(video_devdata(filp));
3039 if (filp->f_flags & O_NONBLOCK)
3040 return -EWOULDBLOCK;
3042 if (down_interruptible(&cam->fileop_sem))
3043 return -ERESTARTSYS;
3045 if (cam->disconnected) {
3046 DBG(2, "Device not present.")
3047 up(&cam->fileop_sem);
3051 if (cam->misconfigured) {
3052 DBG(2, "The camera is misconfigured. Close and open it again.")
3053 up(&cam->fileop_sem);
3057 if (!cam->frame[0].queued)
3058 w9968cf_push_frame(cam, 0);
3060 if (!cam->frame[1].queued)
3061 w9968cf_push_frame(cam, 1);
3063 err = wait_event_interruptible(cam->wait_queue,
3064 cam->frame[0].status == F_READY ||
3065 cam->frame[1].status == F_READY ||
3068 up(&cam->fileop_sem);
3071 if (cam->disconnected) {
3072 up(&cam->fileop_sem);
3076 fr = (cam->frame[0].status == F_READY) ? &cam->frame[0]:&cam->frame[1];
3078 if (w9968cf_vppmod_present)
3079 w9968cf_postprocess_frame(cam, fr);
3081 if (count > fr->length)
3084 if (copy_to_user(buf, fr->buffer, count)) {
3085 fr->status = F_UNUSED;
3086 up(&cam->fileop_sem);
3091 fr->status = F_UNUSED;
3093 DBG(5, "%d bytes read.", count)
3095 up(&cam->fileop_sem);
3100 static int w9968cf_mmap(struct file* filp, struct vm_area_struct *vma)
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,
3110 if (cam->disconnected) {
3111 DBG(2, "Device not present.")
3115 if (cam->misconfigured) {
3116 DBG(2, "The camera is misconfigured. Close and open it again.")
3120 PDBGG("mmapping %li bytes...", vsize)
3122 if (vsize > psize - (vma->vm_pgoff << PAGE_SHIFT))
3126 page = kvirt_to_pa(pos) + vma->vm_pgoff;
3127 if(remap_page_range(start, page, PAGE_SIZE, vma->vm_page_prot))
3131 vsize = (vsize > PAGE_SIZE) ? vsize-PAGE_SIZE : 0;
3134 DBG(5, "mmap method successfully called.")
3140 w9968cf_ioctl(struct inode* inode, struct file* filp,
3141 unsigned int cmd, unsigned long arg)
3143 struct w9968cf_device* cam;
3146 cam = (struct w9968cf_device*)video_get_drvdata(video_devdata(filp));
3148 if (down_interruptible(&cam->fileop_sem))
3149 return -ERESTARTSYS;
3151 if (cam->disconnected) {
3152 DBG(2, "Device not present.")
3153 up(&cam->fileop_sem);
3157 if (cam->misconfigured) {
3158 DBG(2, "The camera is misconfigured. Close and open it again.")
3159 up(&cam->fileop_sem);
3163 err = w9968cf_v4l_ioctl(inode, filp, cmd, (void* )arg);
3165 up(&cam->fileop_sem);
3171 w9968cf_v4l_ioctl(struct inode* inode, struct file* filp,
3172 unsigned int cmd, void* arg)
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"
3184 #define V4L1_IOCTL(cmd) \
3185 ((_IOC_NR((cmd)) < sizeof(v4l1_ioctls)/sizeof(char*)) ? \
3186 v4l1_ioctls[_IOC_NR((cmd))] : "?")
3188 cam = (struct w9968cf_device*)video_get_drvdata(video_devdata(filp));
3192 case VIDIOCGCAP: /* get video capability */
3194 struct video_capability cap = {
3195 .type = VID_TYPE_CAPTURE | VID_TYPE_SCALES,
3198 .minwidth = cam->minwidth,
3199 .minheight = cam->minheight,
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;
3208 if (copy_to_user(arg, &cap, sizeof(cap)))
3211 DBG(5, "VIDIOCGCAP successfully called.")
3215 case VIDIOCGCHAN: /* get video channel informations */
3217 struct video_channel chan;
3218 if (copy_from_user(&chan, arg, sizeof(chan)))
3221 if (chan.channel != 0)
3224 strcpy(chan.name, "Camera");
3227 chan.type = VIDEO_TYPE_CAMERA;
3228 chan.norm = VIDEO_MODE_AUTO;
3230 if (copy_to_user(arg, &chan, sizeof(chan)))
3233 DBG(5, "VIDIOCGCHAN successfully called.")
3237 case VIDIOCSCHAN: /* set active channel */
3239 struct video_channel chan;
3241 if (copy_from_user(&chan, arg, sizeof(chan)))
3244 if (chan.channel != 0)
3247 DBG(5, "VIDIOCSCHAN successfully called.")
3251 case VIDIOCGPICT: /* get image properties of the picture */
3253 if (w9968cf_sensor_get_picture(cam))
3256 if (copy_to_user(arg, &cam->picture, sizeof(cam->picture)))
3259 DBG(5, "VIDIOCGPICT successfully called.")
3263 case VIDIOCSPICT: /* change picture settings */
3265 struct video_picture pict;
3268 if (copy_from_user(&pict, arg, sizeof(pict)))
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))
3279 if (!w9968cf_valid_palette(pict.palette)) {
3280 DBG(4, "Palette %s not supported. VIDIOCSPICT failed.",
3281 symbolic(v4l1_plist, pict.palette))
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))
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))
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);
3311 if (pict.palette != cam->picture.palette) {
3312 if(*cam->requested_frame
3313 || cam->frame_current->queued) {
3314 err = wait_event_interruptible
3316 cam->disconnected ||
3317 (!*cam->requested_frame &&
3318 !cam->frame_current->queued) );
3321 if (cam->disconnected)
3325 if (w9968cf_stop_transfer(cam))
3328 if (w9968cf_set_picture(cam, pict))
3331 if (w9968cf_start_transfer(cam))
3334 } else if (w9968cf_sensor_update_picture(cam, pict))
3338 DBG(5, "VIDIOCSPICT successfully called.")
3342 case VIDIOCSWIN: /* set capture area */
3344 struct video_window win;
3347 if (copy_from_user(&win, arg, sizeof(win)))
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)
3354 if (win.clipcount != 0 || win.flags != 0)
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)
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
3372 cam->disconnected ||
3373 (!*cam->requested_frame &&
3374 !cam->frame_current->queued) );
3377 if (cam->disconnected)
3381 if (w9968cf_stop_transfer(cam))
3384 /* This _must_ be called before set_window() */
3385 if (w9968cf_set_picture(cam, cam->picture))
3388 if (w9968cf_set_window(cam, win))
3391 if (w9968cf_start_transfer(cam))
3395 DBG(5, "VIDIOCSWIN successfully called. ")
3399 case VIDIOCGWIN: /* get current window properties */
3401 if (copy_to_user(arg,&cam->window,sizeof(struct video_window)))
3404 DBG(5, "VIDIOCGWIN successfully called.")
3408 case VIDIOCGMBUF: /* request for memory (mapped) buffer */
3410 struct video_mbuf mbuf;
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;
3419 if (copy_to_user(arg, &mbuf, sizeof(mbuf)))
3422 DBG(5, "VIDIOCGMBUF successfully called.")
3426 case VIDIOCMCAPTURE: /* start the capture to a frame */
3428 struct video_mmap mmap;
3429 struct w9968cf_frame_t* fr;
3432 if (copy_from_user(&mmap, arg, sizeof(mmap)))
3435 DBG(6, "VIDIOCMCAPTURE called: frame #%d, format=%s, %dx%d",
3436 mmap.frame, symbolic(v4l1_plist, mmap.format),
3437 mmap.width, mmap.height)
3439 if (mmap.frame >= cam->nbuffers) {
3440 DBG(4, "Invalid frame number (%d). "
3441 "VIDIOCMCAPTURE failed.", mmap.frame)
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))
3453 if (!w9968cf_valid_palette(mmap.format)) {
3454 DBG(4, "Palette %s not supported. "
3455 "VIDIOCMCAPTURE failed.",
3456 symbolic(v4l1_plist, mmap.format))
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))
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))
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)
3486 fr = &cam->frame[mmap.frame];
3488 if (mmap.width != cam->window.width ||
3489 mmap.height != cam->window.height ||
3490 mmap.format != cam->picture.palette) {
3492 struct video_window win;
3493 struct video_picture pict;
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
3503 cam->disconnected ||
3504 (!*cam->requested_frame &&
3505 !cam->frame_current->queued) );
3508 if (cam->disconnected)
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;
3518 if (w9968cf_stop_transfer(cam))
3521 /* This before set_window */
3522 if (w9968cf_set_picture(cam, pict))
3525 if (w9968cf_set_window(cam, win))
3528 if (w9968cf_start_transfer(cam))
3531 } else if (fr->queued) {
3533 DBG(6, "Wait until frame #%d is free.", mmap.frame)
3535 err = wait_event_interruptible(cam->wait_queue,
3536 cam->disconnected ||
3540 if (cam->disconnected)
3544 w9968cf_push_frame(cam, mmap.frame);
3545 DBG(5, "VIDIOCMCAPTURE(%d): successfully called.", mmap.frame)
3549 case VIDIOCSYNC: /* wait until the capture of a frame is finished */
3552 struct w9968cf_frame_t* fr;
3555 if (copy_from_user(&f_num, arg, sizeof(f_num)))
3558 if (f_num >= cam->nbuffers) {
3559 DBG(4, "Invalid frame number (%d). "
3560 "VIDIOCMCAPTURE failed.", f_num)
3564 DBG(6, "VIDIOCSYNC called for frame #%d", f_num)
3566 fr = &cam->frame[f_num];
3568 switch (fr->status) {
3571 DBG(4, "VIDIOSYNC: Frame #%d not requested!",
3577 err = wait_event_interruptible(cam->wait_queue,
3578 (fr->status == F_READY)
3579 || cam->disconnected);
3582 if (cam->disconnected)
3589 if (w9968cf_vppmod_present)
3590 w9968cf_postprocess_frame(cam, fr);
3592 fr->status = F_UNUSED;
3594 DBG(5, "VIDIOCSYNC(%d) successfully called.", f_num)
3598 case VIDIOCGUNIT:/* report the unit numbers of the associated devices*/
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,
3608 if (copy_to_user(arg, &unit, sizeof(unit)))
3611 DBG(5, "VIDIOCGUNIT successfully called.")
3620 struct video_buffer* buffer = (struct video_buffer*)arg;
3622 if (clear_user(buffer, sizeof(struct video_buffer)))
3625 DBG(5, "VIDIOCGFBUF successfully called.")
3631 struct video_tuner tuner;
3632 if (copy_from_user(&tuner, arg, sizeof(tuner)))
3635 if (tuner.tuner != 0)
3638 strcpy(tuner.name, "no_tuner");
3640 tuner.rangehigh = 0;
3641 tuner.flags = VIDEO_TUNER_NORM;
3642 tuner.mode = VIDEO_MODE_AUTO;
3643 tuner.signal = 0xffff;
3645 if (copy_to_user(arg, &tuner, sizeof(tuner)))
3648 DBG(5, "VIDIOCGTUNER successfully called.")
3654 struct video_tuner tuner;
3655 if (copy_from_user(&tuner, arg, sizeof(tuner)))
3658 if (tuner.tuner != 0)
3661 if (tuner.mode != VIDEO_MODE_AUTO)
3664 DBG(5, "VIDIOCSTUNER successfully called.")
3674 case VIDIOCSPLAYMODE:
3675 case VIDIOCSWRITEMODE:
3676 case VIDIOCGPLAYINFO:
3677 case VIDIOCSMICROCODE:
3680 DBG(4, "Unsupported V4L1 IOCtl: VIDIOC%s "
3686 _IOC_TYPE(cmd),_IOC_NR(cmd),_IOC_DIR(cmd),_IOC_SIZE(cmd))
3691 DBG(4, "Invalid V4L1 IOCtl: VIDIOC%s "
3697 _IOC_TYPE(cmd),_IOC_NR(cmd),_IOC_DIR(cmd),_IOC_SIZE(cmd))
3699 return -ENOIOCTLCMD;
3701 } /* end of switch */
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))
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,
3723 /****************************************************************************
3724 * USB probe and V4L registration, disconnect and id_table[] definition *
3725 ****************************************************************************/
3728 w9968cf_usb_probe(struct usb_device* udev,
3729 unsigned int ifnum, const struct usb_device_id* id)
3731 struct w9968cf_device* cam;
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 */
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 */
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 */
3749 /* We don't handle multi-config cameras */
3750 if (udev->descriptor.bNumConfigurations != 1)
3753 DBG(2, "%s detected.", symbolic(camlist, mod_id))
3755 if (simcams > W9968CF_MAX_DEVICES)
3756 simcams = W9968CF_SIMCAMS;
3758 /* How many cameras are connected ? */
3759 down(&w9968cf_devlist_sem);
3760 list_for_each(ptr, &w9968cf_dev_list)
3762 up(&w9968cf_devlist_sem);
3764 if (sc >= simcams) {
3765 DBG(2, "Device rejected: too many connected cameras "
3766 "(max. %d)", simcams)
3770 cam = (struct w9968cf_device*)
3771 kmalloc(sizeof(struct w9968cf_device), GFP_KERNEL);
3774 DBG(1, "Couldn't allocate %d bytes of kernel memory.",
3775 sizeof(struct w9968cf_device))
3779 memset(cam, 0, sizeof(*cam));
3781 init_MUTEX(&cam->dev_sem);
3782 down(&cam->dev_sem);
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.")
3790 memset(cam->control_buffer, 0, 2);
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.")
3799 memset(cam->data_buffer, 0, 8);
3801 /* Register the V4L device */
3802 cam->v4ldev = video_device_alloc();
3804 DBG(1, "Could not allocate memory for a V4L structure.")
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);
3818 err = video_register_device(cam->v4ldev, VFL_TYPE_GRABBER,
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;
3829 DBG(2, "V4L device registered as /dev/video%d", cam->v4ldev->minor)
3831 /* Set some basic constants */
3832 w9968cf_configure_camera(cam, udev, mod_id, dev_nr);
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;
3840 w9968cf_turn_on_led(cam);
3842 w9968cf_i2c_init(cam);
3844 #ifdef CONFIG_VIDEO_PROC_FS
3845 w9968cf_proc_create_dev(cam);
3852 fail: /* Free unused memory */
3854 if (cam->control_buffer)
3855 kfree(cam->control_buffer);
3856 if (cam->data_buffer)
3857 kfree(cam->data_buffer);
3859 video_device_release(cam->v4ldev);
3868 w9968cf_usb_disconnect(struct usb_device* udev, void* drv_context)
3870 struct w9968cf_device* cam = (struct w9968cf_device*)drv_context;
3873 /* Prevent concurrent accesses to data */
3874 down(&cam->dev_sem);
3877 cam->disconnected = 1;
3879 DBG(2, "Disconnecting %s...", symbolic(camlist, cam->id))
3881 if (waitqueue_active(&cam->open))
3882 wake_up_interruptible(&cam->open);
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)
3890 cam->misconfigured = 1;
3892 if (waitqueue_active(&cam->wait_queue))
3893 wake_up_interruptible(&cam->wait_queue);
3895 w9968cf_release_resources(cam);
3905 static struct usb_driver w9968cf_usb_driver = {
3906 .owner = THIS_MODULE,
3908 .id_table = winbond_id_table,
3909 .probe = w9968cf_usb_probe,
3910 .disconnect = w9968cf_usb_disconnect,
3915 /****************************************************************************
3916 * Module init, exit and intermodule communication *
3917 ****************************************************************************/
3919 static int w9968cf_vppmod_detect(void)
3921 w9968cf_vpp_init_decoder = inter_module_get("w9968cf_init_decoder");
3923 if (!w9968cf_vpp_init_decoder) {
3925 w9968cf_vpp_init_decoder = inter_module_get_request
3926 ( "w9968cf_init_decoder",
3928 if (!w9968cf_vpp_init_decoder) {
3929 w9968cf_vppmod_present = 0;
3930 DBG(4, "Video post-processing module not detected.")
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");
3941 w9968cf_vppmod_present = 1;
3943 /* Initialization */
3944 (*w9968cf_vpp_init_decoder)();
3946 DBG(2, "Video post-processing module detected.")
3951 static void w9968cf_vppmod_release(void)
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");
3960 DBG(2, "Video post-processing module released.")
3964 static int __init w9968cf_module_init(void)
3968 DBG(2, W9968CF_MODULE_NAME" "W9968CF_MODULE_VERSION)
3969 DBG(3, W9968CF_MODULE_AUTHOR)
3971 init_MUTEX(&w9968cf_devlist_sem);
3973 #ifdef CONFIG_VIDEO_PROC_FS
3974 w9968cf_proc_create();
3977 w9968cf_vppmod_detect();
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();
3992 static void __exit w9968cf_module_exit(void)
3994 /* w9968cf_usb_disconnect() will be called */
3995 usb_deregister(&w9968cf_usb_driver);
3997 #ifdef CONFIG_VIDEO_PROC_FS
3998 w9968cf_proc_destroy();
4001 if (w9968cf_vppmod_present)
4002 w9968cf_vppmod_release();
4004 DBG(2, W9968CF_MODULE_NAME" deregistered.")
4008 module_init(w9968cf_module_init);
4009 module_exit(w9968cf_module_exit);