[PATCH] USB: drivers/usb/media/w9968cf.c: remove hooks for the vpp module
[linux-2.6/btrfs-unstable.git] / drivers / usb / media / w9968cf.c
blob9937fc64c8bf3c34a3e7a31b1cedaf0ee22065b3
1 /***************************************************************************
2 * Video4Linux driver for W996[87]CF JPEG USB Dual Mode Camera Chip. *
3 * *
4 * Copyright (C) 2002-2004 by Luca Risolia <luca.risolia@studio.unibo.it> *
5 * *
6 * - Memory management code from bttv driver by Ralph Metzler, *
7 * Marcus Metzler and Gerd Knorr. *
8 * - I2C interface to kernel, high-level image sensor control routines and *
9 * some symbolic names from OV511 driver by Mark W. McClelland. *
10 * - Low-level I2C fast write function by Piotr Czerczak. *
11 * - Low-level I2C read function by Frederic Jouault. *
12 * *
13 * This program is free software; you can redistribute it and/or modify *
14 * it under the terms of the GNU General Public License as published by *
15 * the Free Software Foundation; either version 2 of the License, or *
16 * (at your option) any later version. *
17 * *
18 * This program is distributed in the hope that it will be useful, *
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
21 * GNU General Public License for more details. *
22 * *
23 * You should have received a copy of the GNU General Public License *
24 * along with this program; if not, write to the Free Software *
25 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
26 ***************************************************************************/
28 #include <linux/module.h>
29 #include <linux/kernel.h>
30 #include <linux/kmod.h>
31 #include <linux/init.h>
32 #include <linux/fs.h>
33 #include <linux/vmalloc.h>
34 #include <linux/slab.h>
35 #include <linux/mm.h>
36 #include <linux/string.h>
37 #include <linux/errno.h>
38 #include <linux/sched.h>
39 #include <linux/ioctl.h>
40 #include <linux/delay.h>
41 #include <linux/stddef.h>
42 #include <asm/page.h>
43 #include <asm/uaccess.h>
44 #include <linux/page-flags.h>
45 #include <linux/moduleparam.h>
47 #include "w9968cf.h"
48 #include "w9968cf_decoder.h"
52 /****************************************************************************
53 * Module macros and parameters *
54 ****************************************************************************/
56 MODULE_DEVICE_TABLE(usb, winbond_id_table);
58 MODULE_AUTHOR(W9968CF_MODULE_AUTHOR" "W9968CF_AUTHOR_EMAIL);
59 MODULE_DESCRIPTION(W9968CF_MODULE_NAME);
60 MODULE_VERSION(W9968CF_MODULE_VERSION);
61 MODULE_LICENSE(W9968CF_MODULE_LICENSE);
62 MODULE_SUPPORTED_DEVICE("Video");
64 static int ovmod_load = W9968CF_OVMOD_LOAD;
65 static unsigned short simcams = W9968CF_SIMCAMS;
66 static short video_nr[]={[0 ... W9968CF_MAX_DEVICES-1] = -1}; /*-1=first free*/
67 static unsigned int packet_size[] = {[0 ... W9968CF_MAX_DEVICES-1] =
68 W9968CF_PACKET_SIZE};
69 static unsigned short max_buffers[] = {[0 ... W9968CF_MAX_DEVICES-1] =
70 W9968CF_BUFFERS};
71 static int double_buffer[] = {[0 ... W9968CF_MAX_DEVICES-1] =
72 W9968CF_DOUBLE_BUFFER};
73 static int clamping[] = {[0 ... W9968CF_MAX_DEVICES-1] = W9968CF_CLAMPING};
74 static unsigned short filter_type[]= {[0 ... W9968CF_MAX_DEVICES-1] =
75 W9968CF_FILTER_TYPE};
76 static int largeview[]= {[0 ... W9968CF_MAX_DEVICES-1] = W9968CF_LARGEVIEW};
77 static unsigned short decompression[] = {[0 ... W9968CF_MAX_DEVICES-1] =
78 W9968CF_DECOMPRESSION};
79 static int upscaling[]= {[0 ... W9968CF_MAX_DEVICES-1] = W9968CF_UPSCALING};
80 static unsigned short force_palette[] = {[0 ... W9968CF_MAX_DEVICES-1] = 0};
81 static int force_rgb[] = {[0 ... W9968CF_MAX_DEVICES-1] = W9968CF_FORCE_RGB};
82 static int autobright[] = {[0 ... W9968CF_MAX_DEVICES-1] = W9968CF_AUTOBRIGHT};
83 static int autoexp[] = {[0 ... W9968CF_MAX_DEVICES-1] = W9968CF_AUTOEXP};
84 static unsigned short lightfreq[] = {[0 ... W9968CF_MAX_DEVICES-1] =
85 W9968CF_LIGHTFREQ};
86 static int bandingfilter[] = {[0 ... W9968CF_MAX_DEVICES-1]=
87 W9968CF_BANDINGFILTER};
88 static short clockdiv[] = {[0 ... W9968CF_MAX_DEVICES-1] = W9968CF_CLOCKDIV};
89 static int backlight[] = {[0 ... W9968CF_MAX_DEVICES-1] = W9968CF_BACKLIGHT};
90 static int mirror[] = {[0 ... W9968CF_MAX_DEVICES-1] = W9968CF_MIRROR};
91 static int monochrome[] = {[0 ... W9968CF_MAX_DEVICES-1]=W9968CF_MONOCHROME};
92 static unsigned int brightness[] = {[0 ... W9968CF_MAX_DEVICES-1] =
93 W9968CF_BRIGHTNESS};
94 static unsigned int hue[] = {[0 ... W9968CF_MAX_DEVICES-1] = W9968CF_HUE};
95 static unsigned int colour[]={[0 ... W9968CF_MAX_DEVICES-1] = W9968CF_COLOUR};
96 static unsigned int contrast[] = {[0 ... W9968CF_MAX_DEVICES-1] =
97 W9968CF_CONTRAST};
98 static unsigned int whiteness[] = {[0 ... W9968CF_MAX_DEVICES-1] =
99 W9968CF_WHITENESS};
100 #ifdef W9968CF_DEBUG
101 static unsigned short debug = W9968CF_DEBUG_LEVEL;
102 static int specific_debug = W9968CF_SPECIFIC_DEBUG;
103 #endif
105 static unsigned int param_nv[24]; /* number of values per parameter */
107 #ifdef CONFIG_KMOD
108 module_param(ovmod_load, bool, 0644);
109 #endif
110 module_param(simcams, ushort, 0644);
111 module_param_array(video_nr, short, &param_nv[0], 0444);
112 module_param_array(packet_size, uint, &param_nv[1], 0444);
113 module_param_array(max_buffers, ushort, &param_nv[2], 0444);
114 module_param_array(double_buffer, bool, &param_nv[3], 0444);
115 module_param_array(clamping, bool, &param_nv[4], 0444);
116 module_param_array(filter_type, ushort, &param_nv[5], 0444);
117 module_param_array(largeview, bool, &param_nv[6], 0444);
118 module_param_array(decompression, ushort, &param_nv[7], 0444);
119 module_param_array(upscaling, bool, &param_nv[8], 0444);
120 module_param_array(force_palette, ushort, &param_nv[9], 0444);
121 module_param_array(force_rgb, ushort, &param_nv[10], 0444);
122 module_param_array(autobright, bool, &param_nv[11], 0444);
123 module_param_array(autoexp, bool, &param_nv[12], 0444);
124 module_param_array(lightfreq, ushort, &param_nv[13], 0444);
125 module_param_array(bandingfilter, bool, &param_nv[14], 0444);
126 module_param_array(clockdiv, short, &param_nv[15], 0444);
127 module_param_array(backlight, bool, &param_nv[16], 0444);
128 module_param_array(mirror, bool, &param_nv[17], 0444);
129 module_param_array(monochrome, bool, &param_nv[18], 0444);
130 module_param_array(brightness, uint, &param_nv[19], 0444);
131 module_param_array(hue, uint, &param_nv[20], 0444);
132 module_param_array(colour, uint, &param_nv[21], 0444);
133 module_param_array(contrast, uint, &param_nv[22], 0444);
134 module_param_array(whiteness, uint, &param_nv[23], 0444);
135 #ifdef W9968CF_DEBUG
136 module_param(debug, ushort, 0644);
137 module_param(specific_debug, bool, 0644);
138 #endif
140 #ifdef CONFIG_KMOD
141 MODULE_PARM_DESC(ovmod_load,
142 "\n<0|1> Automatic 'ovcamchip' module loading."
143 "\n0 disabled, 1 enabled."
144 "\nIf enabled,'insmod' searches for the required 'ovcamchip'"
145 "\nmodule in the system, according to its configuration, and"
146 "\nattempts to load that module automatically. This action is"
147 "\nperformed once as soon as the 'w9968cf' module is loaded"
148 "\ninto memory."
149 "\nDefault value is "__MODULE_STRING(W9968CF_OVMOD_LOAD)"."
150 "\n");
151 #endif
152 MODULE_PARM_DESC(simcams,
153 "\n<n> Number of cameras allowed to stream simultaneously."
154 "\nn may vary from 0 to "
155 __MODULE_STRING(W9968CF_MAX_DEVICES)"."
156 "\nDefault value is "__MODULE_STRING(W9968CF_SIMCAMS)"."
157 "\n");
158 MODULE_PARM_DESC(video_nr,
159 "\n<-1|n[,...]> Specify V4L minor mode number."
160 "\n -1 = use next available (default)"
161 "\n n = use minor number n (integer >= 0)"
162 "\nYou can specify up to "__MODULE_STRING(W9968CF_MAX_DEVICES)
163 " cameras this way."
164 "\nFor example:"
165 "\nvideo_nr=-1,2,-1 would assign minor number 2 to"
166 "\nthe second camera and use auto for the first"
167 "\none and for every other camera."
168 "\n");
169 MODULE_PARM_DESC(packet_size,
170 "\n<n[,...]> Specify the maximum data payload"
171 "\nsize in bytes for alternate settings, for each device."
172 "\nn is scaled between 63 and 1023 "
173 "(default is "__MODULE_STRING(W9968CF_PACKET_SIZE)")."
174 "\n");
175 MODULE_PARM_DESC(max_buffers,
176 "\n<n[,...]> For advanced users."
177 "\nSpecify the maximum number of video frame buffers"
178 "\nto allocate for each device, from 2 to "
179 __MODULE_STRING(W9968CF_MAX_BUFFERS)
180 ". (default is "__MODULE_STRING(W9968CF_BUFFERS)")."
181 "\n");
182 MODULE_PARM_DESC(double_buffer,
183 "\n<0|1[,...]> "
184 "Hardware double buffering: 0 disabled, 1 enabled."
185 "\nIt should be enabled if you want smooth video output: if"
186 "\nyou obtain out of sync. video, disable it, or try to"
187 "\ndecrease the 'clockdiv' module parameter value."
188 "\nDefault value is "__MODULE_STRING(W9968CF_DOUBLE_BUFFER)
189 " for every device."
190 "\n");
191 MODULE_PARM_DESC(clamping,
192 "\n<0|1[,...]> Video data clamping: 0 disabled, 1 enabled."
193 "\nDefault value is "__MODULE_STRING(W9968CF_CLAMPING)
194 " for every device."
195 "\n");
196 MODULE_PARM_DESC(filter_type,
197 "\n<0|1|2[,...]> Video filter type."
198 "\n0 none, 1 (1-2-1) 3-tap filter, "
199 "2 (2-3-6-3-2) 5-tap filter."
200 "\nDefault value is "__MODULE_STRING(W9968CF_FILTER_TYPE)
201 " for every device."
202 "\nThe filter is used to reduce noise and aliasing artifacts"
203 "\nproduced by the CCD or CMOS image sensor, and the scaling"
204 " process."
205 "\n");
206 MODULE_PARM_DESC(largeview,
207 "\n<0|1[,...]> Large view: 0 disabled, 1 enabled."
208 "\nDefault value is "__MODULE_STRING(W9968CF_LARGEVIEW)
209 " for every device."
210 "\n");
211 MODULE_PARM_DESC(upscaling,
212 "\n<0|1[,...]> Software scaling (for non-compressed video):"
213 "\n0 disabled, 1 enabled."
214 "\nDisable it if you have a slow CPU or you don't have"
215 " enough memory."
216 "\nDefault value is "__MODULE_STRING(W9968CF_UPSCALING)
217 " for every device."
218 "\nIf 'w9968cf-vpp' is not present, this parameter is"
219 " set to 0."
220 "\n");
221 MODULE_PARM_DESC(decompression,
222 "\n<0|1|2[,...]> Software video decompression:"
223 "\n- 0 disables decompression (doesn't allow formats needing"
224 " decompression)"
225 "\n- 1 forces decompression (allows formats needing"
226 " decompression only);"
227 "\n- 2 allows any permitted formats."
228 "\nFormats supporting compressed video are YUV422P and"
229 " YUV420P/YUV420 "
230 "\nin any resolutions where both width and height are "
231 "a multiple of 16."
232 "\nDefault value is "__MODULE_STRING(W9968CF_DECOMPRESSION)
233 " for every device."
234 "\nIf 'w9968cf-vpp' is not present, forcing decompression is "
235 "\nnot allowed; in this case this parameter is set to 2."
236 "\n");
237 MODULE_PARM_DESC(force_palette,
238 "\n<0"
239 "|" __MODULE_STRING(VIDEO_PALETTE_UYVY)
240 "|" __MODULE_STRING(VIDEO_PALETTE_YUV420)
241 "|" __MODULE_STRING(VIDEO_PALETTE_YUV422P)
242 "|" __MODULE_STRING(VIDEO_PALETTE_YUV420P)
243 "|" __MODULE_STRING(VIDEO_PALETTE_YUYV)
244 "|" __MODULE_STRING(VIDEO_PALETTE_YUV422)
245 "|" __MODULE_STRING(VIDEO_PALETTE_GREY)
246 "|" __MODULE_STRING(VIDEO_PALETTE_RGB555)
247 "|" __MODULE_STRING(VIDEO_PALETTE_RGB565)
248 "|" __MODULE_STRING(VIDEO_PALETTE_RGB24)
249 "|" __MODULE_STRING(VIDEO_PALETTE_RGB32)
250 "[,...]>"
251 " Force picture palette."
252 "\nIn order:"
253 "\n- 0 allows any of the following formats:"
254 "\n- UYVY 16 bpp - Original video, compression disabled"
255 "\n- YUV420 12 bpp - Original video, compression enabled"
256 "\n- YUV422P 16 bpp - Original video, compression enabled"
257 "\n- YUV420P 12 bpp - Original video, compression enabled"
258 "\n- YUVY 16 bpp - Software conversion from UYVY"
259 "\n- YUV422 16 bpp - Software conversion from UYVY"
260 "\n- GREY 8 bpp - Software conversion from UYVY"
261 "\n- RGB555 16 bpp - Software conversion from UYVY"
262 "\n- RGB565 16 bpp - Software conversion from UYVY"
263 "\n- RGB24 24 bpp - Software conversion from UYVY"
264 "\n- RGB32 32 bpp - Software conversion from UYVY"
265 "\nWhen not 0, this parameter will override 'decompression'."
266 "\nDefault value is 0 for every device."
267 "\nInitial palette is "
268 __MODULE_STRING(W9968CF_PALETTE_DECOMP_ON)"."
269 "\nIf 'w9968cf-vpp' is not present, this parameter is"
270 " set to 9 (UYVY)."
271 "\n");
272 MODULE_PARM_DESC(force_rgb,
273 "\n<0|1[,...]> Read RGB video data instead of BGR:"
274 "\n 1 = use RGB component ordering."
275 "\n 0 = use BGR component ordering."
276 "\nThis parameter has effect when using RGBX palettes only."
277 "\nDefault value is "__MODULE_STRING(W9968CF_FORCE_RGB)
278 " for every device."
279 "\n");
280 MODULE_PARM_DESC(autobright,
281 "\n<0|1[,...]> Image sensor automatically changes brightness:"
282 "\n 0 = no, 1 = yes"
283 "\nDefault value is "__MODULE_STRING(W9968CF_AUTOBRIGHT)
284 " for every device."
285 "\n");
286 MODULE_PARM_DESC(autoexp,
287 "\n<0|1[,...]> Image sensor automatically changes exposure:"
288 "\n 0 = no, 1 = yes"
289 "\nDefault value is "__MODULE_STRING(W9968CF_AUTOEXP)
290 " for every device."
291 "\n");
292 MODULE_PARM_DESC(lightfreq,
293 "\n<50|60[,...]> Light frequency in Hz:"
294 "\n 50 for European and Asian lighting,"
295 " 60 for American lighting."
296 "\nDefault value is "__MODULE_STRING(W9968CF_LIGHTFREQ)
297 " for every device."
298 "\n");
299 MODULE_PARM_DESC(bandingfilter,
300 "\n<0|1[,...]> Banding filter to reduce effects of"
301 " fluorescent lighting:"
302 "\n 0 disabled, 1 enabled."
303 "\nThis filter tries to reduce the pattern of horizontal"
304 "\nlight/dark bands caused by some (usually fluorescent)"
305 " lighting."
306 "\nDefault value is "__MODULE_STRING(W9968CF_BANDINGFILTER)
307 " for every device."
308 "\n");
309 MODULE_PARM_DESC(clockdiv,
310 "\n<-1|n[,...]> "
311 "Force pixel clock divisor to a specific value (for experts):"
312 "\n n may vary from 0 to 127."
313 "\n -1 for automatic value."
314 "\nSee also the 'double_buffer' module parameter."
315 "\nDefault value is "__MODULE_STRING(W9968CF_CLOCKDIV)
316 " for every device."
317 "\n");
318 MODULE_PARM_DESC(backlight,
319 "\n<0|1[,...]> Objects are lit from behind:"
320 "\n 0 = no, 1 = yes"
321 "\nDefault value is "__MODULE_STRING(W9968CF_BACKLIGHT)
322 " for every device."
323 "\n");
324 MODULE_PARM_DESC(mirror,
325 "\n<0|1[,...]> Reverse image horizontally:"
326 "\n 0 = no, 1 = yes"
327 "\nDefault value is "__MODULE_STRING(W9968CF_MIRROR)
328 " for every device."
329 "\n");
330 MODULE_PARM_DESC(monochrome,
331 "\n<0|1[,...]> Use image sensor as monochrome sensor:"
332 "\n 0 = no, 1 = yes"
333 "\nNot all the sensors support monochrome color."
334 "\nDefault value is "__MODULE_STRING(W9968CF_MONOCHROME)
335 " for every device."
336 "\n");
337 MODULE_PARM_DESC(brightness,
338 "\n<n[,...]> Set picture brightness (0-65535)."
339 "\nDefault value is "__MODULE_STRING(W9968CF_BRIGHTNESS)
340 " for every device."
341 "\nThis parameter has no effect if 'autobright' is enabled."
342 "\n");
343 MODULE_PARM_DESC(hue,
344 "\n<n[,...]> Set picture hue (0-65535)."
345 "\nDefault value is "__MODULE_STRING(W9968CF_HUE)
346 " for every device."
347 "\n");
348 MODULE_PARM_DESC(colour,
349 "\n<n[,...]> Set picture saturation (0-65535)."
350 "\nDefault value is "__MODULE_STRING(W9968CF_COLOUR)
351 " for every device."
352 "\n");
353 MODULE_PARM_DESC(contrast,
354 "\n<n[,...]> Set picture contrast (0-65535)."
355 "\nDefault value is "__MODULE_STRING(W9968CF_CONTRAST)
356 " for every device."
357 "\n");
358 MODULE_PARM_DESC(whiteness,
359 "\n<n[,...]> Set picture whiteness (0-65535)."
360 "\nDefault value is "__MODULE_STRING(W9968CF_WHITENESS)
361 " for every device."
362 "\n");
363 #ifdef W9968CF_DEBUG
364 MODULE_PARM_DESC(debug,
365 "\n<n> Debugging information level, from 0 to 6:"
366 "\n0 = none (use carefully)"
367 "\n1 = critical errors"
368 "\n2 = significant informations"
369 "\n3 = configuration or general messages"
370 "\n4 = warnings"
371 "\n5 = called functions"
372 "\n6 = function internals"
373 "\nLevel 5 and 6 are useful for testing only, when only "
374 "one device is used."
375 "\nDefault value is "__MODULE_STRING(W9968CF_DEBUG_LEVEL)"."
376 "\n");
377 MODULE_PARM_DESC(specific_debug,
378 "\n<0|1> Enable or disable specific debugging messages:"
379 "\n0 = print messages concerning every level"
380 " <= 'debug' level."
381 "\n1 = print messages concerning the level"
382 " indicated by 'debug'."
383 "\nDefault value is "
384 __MODULE_STRING(W9968CF_SPECIFIC_DEBUG)"."
385 "\n");
386 #endif /* W9968CF_DEBUG */
390 /****************************************************************************
391 * Some prototypes *
392 ****************************************************************************/
394 /* Video4linux interface */
395 static struct file_operations w9968cf_fops;
396 static int w9968cf_open(struct inode*, struct file*);
397 static int w9968cf_release(struct inode*, struct file*);
398 static int w9968cf_mmap(struct file*, struct vm_area_struct*);
399 static int w9968cf_ioctl(struct inode*, struct file*, unsigned, unsigned long);
400 static ssize_t w9968cf_read(struct file*, char __user *, size_t, loff_t*);
401 static int w9968cf_v4l_ioctl(struct inode*, struct file*, unsigned int,
402 void __user *);
404 /* USB-specific */
405 static int w9968cf_start_transfer(struct w9968cf_device*);
406 static int w9968cf_stop_transfer(struct w9968cf_device*);
407 static int w9968cf_write_reg(struct w9968cf_device*, u16 value, u16 index);
408 static int w9968cf_read_reg(struct w9968cf_device*, u16 index);
409 static int w9968cf_write_fsb(struct w9968cf_device*, u16* data);
410 static int w9968cf_write_sb(struct w9968cf_device*, u16 value);
411 static int w9968cf_read_sb(struct w9968cf_device*);
412 static int w9968cf_upload_quantizationtables(struct w9968cf_device*);
413 static void w9968cf_urb_complete(struct urb *urb, struct pt_regs *regs);
415 /* Low-level I2C (SMBus) I/O */
416 static int w9968cf_smbus_start(struct w9968cf_device*);
417 static int w9968cf_smbus_stop(struct w9968cf_device*);
418 static int w9968cf_smbus_write_byte(struct w9968cf_device*, u8 v);
419 static int w9968cf_smbus_read_byte(struct w9968cf_device*, u8* v);
420 static int w9968cf_smbus_write_ack(struct w9968cf_device*);
421 static int w9968cf_smbus_read_ack(struct w9968cf_device*);
422 static int w9968cf_smbus_refresh_bus(struct w9968cf_device*);
423 static int w9968cf_i2c_adap_read_byte(struct w9968cf_device* cam,
424 u16 address, u8* value);
425 static int w9968cf_i2c_adap_read_byte_data(struct w9968cf_device*, u16 address,
426 u8 subaddress, u8* value);
427 static int w9968cf_i2c_adap_write_byte(struct w9968cf_device*,
428 u16 address, u8 subaddress);
429 static int w9968cf_i2c_adap_fastwrite_byte_data(struct w9968cf_device*,
430 u16 address, u8 subaddress,
431 u8 value);
433 /* I2C interface to kernel */
434 static int w9968cf_i2c_init(struct w9968cf_device*);
435 static int w9968cf_i2c_smbus_xfer(struct i2c_adapter*, u16 addr,
436 unsigned short flags, char read_write,
437 u8 command, int size, union i2c_smbus_data*);
438 static u32 w9968cf_i2c_func(struct i2c_adapter*);
439 static int w9968cf_i2c_attach_inform(struct i2c_client*);
440 static int w9968cf_i2c_detach_inform(struct i2c_client*);
441 static int w9968cf_i2c_control(struct i2c_adapter*, unsigned int cmd,
442 unsigned long arg);
444 /* Memory management */
445 static void* rvmalloc(unsigned long size);
446 static void rvfree(void *mem, unsigned long size);
447 static void w9968cf_deallocate_memory(struct w9968cf_device*);
448 static int w9968cf_allocate_memory(struct w9968cf_device*);
450 /* High-level image sensor control functions */
451 static int w9968cf_sensor_set_control(struct w9968cf_device*,int cid,int val);
452 static int w9968cf_sensor_get_control(struct w9968cf_device*,int cid,int *val);
453 static int w9968cf_sensor_cmd(struct w9968cf_device*,
454 unsigned int cmd, void *arg);
455 static int w9968cf_sensor_init(struct w9968cf_device*);
456 static int w9968cf_sensor_update_settings(struct w9968cf_device*);
457 static int w9968cf_sensor_get_picture(struct w9968cf_device*);
458 static int w9968cf_sensor_update_picture(struct w9968cf_device*,
459 struct video_picture pict);
461 /* Other helper functions */
462 static void w9968cf_configure_camera(struct w9968cf_device*,struct usb_device*,
463 enum w9968cf_model_id,
464 const unsigned short dev_nr);
465 static void w9968cf_adjust_configuration(struct w9968cf_device*);
466 static int w9968cf_turn_on_led(struct w9968cf_device*);
467 static int w9968cf_init_chip(struct w9968cf_device*);
468 static inline u16 w9968cf_valid_palette(u16 palette);
469 static inline u16 w9968cf_valid_depth(u16 palette);
470 static inline u8 w9968cf_need_decompression(u16 palette);
471 static int w9968cf_set_picture(struct w9968cf_device*, struct video_picture);
472 static int w9968cf_set_window(struct w9968cf_device*, struct video_window);
473 static int w9968cf_postprocess_frame(struct w9968cf_device*,
474 struct w9968cf_frame_t*);
475 static int w9968cf_adjust_window_size(struct w9968cf_device*, u16* w, u16* h);
476 static void w9968cf_init_framelist(struct w9968cf_device*);
477 static void w9968cf_push_frame(struct w9968cf_device*, u8 f_num);
478 static void w9968cf_pop_frame(struct w9968cf_device*,struct w9968cf_frame_t**);
479 static void w9968cf_release_resources(struct w9968cf_device*);
483 /****************************************************************************
484 * Symbolic names *
485 ****************************************************************************/
487 /* Used to represent a list of values and their respective symbolic names */
488 struct w9968cf_symbolic_list {
489 const int num;
490 const char *name;
493 /*--------------------------------------------------------------------------
494 Returns the name of the matching element in the symbolic_list array. The
495 end of the list must be marked with an element that has a NULL name.
496 --------------------------------------------------------------------------*/
497 static inline const char *
498 symbolic(struct w9968cf_symbolic_list list[], const int num)
500 int i;
502 for (i = 0; list[i].name != NULL; i++)
503 if (list[i].num == num)
504 return (list[i].name);
506 return "Unknown";
509 static struct w9968cf_symbolic_list camlist[] = {
510 { W9968CF_MOD_GENERIC, "W996[87]CF JPEG USB Dual Mode Camera" },
511 { W9968CF_MOD_CLVBWGP, "Creative Labs Video Blaster WebCam Go Plus" },
513 /* Other cameras (having the same descriptors as Generic W996[87]CF) */
514 { W9968CF_MOD_ADPVDMA, "Aroma Digi Pen VGA Dual Mode ADG-5000" },
515 { W9986CF_MOD_AAU, "AVerMedia AVerTV USB" },
516 { W9968CF_MOD_CLVBWG, "Creative Labs Video Blaster WebCam Go" },
517 { W9968CF_MOD_LL, "Lebon LDC-035A" },
518 { W9968CF_MOD_EEEMC, "Ezonics EZ-802 EZMega Cam" },
519 { W9968CF_MOD_OOE, "OmniVision OV8610-EDE" },
520 { W9968CF_MOD_ODPVDMPC, "OPCOM Digi Pen VGA Dual Mode Pen Camera" },
521 { W9968CF_MOD_PDPII, "Pretec Digi Pen-II" },
522 { W9968CF_MOD_PDP480, "Pretec DigiPen-480" },
524 { -1, NULL }
527 static struct w9968cf_symbolic_list senlist[] = {
528 { CC_OV76BE, "OV76BE" },
529 { CC_OV7610, "OV7610" },
530 { CC_OV7620, "OV7620" },
531 { CC_OV7620AE, "OV7620AE" },
532 { CC_OV6620, "OV6620" },
533 { CC_OV6630, "OV6630" },
534 { CC_OV6630AE, "OV6630AE" },
535 { CC_OV6630AF, "OV6630AF" },
536 { -1, NULL }
539 /* Video4Linux1 palettes */
540 static struct w9968cf_symbolic_list v4l1_plist[] = {
541 { VIDEO_PALETTE_GREY, "GREY" },
542 { VIDEO_PALETTE_HI240, "HI240" },
543 { VIDEO_PALETTE_RGB565, "RGB565" },
544 { VIDEO_PALETTE_RGB24, "RGB24" },
545 { VIDEO_PALETTE_RGB32, "RGB32" },
546 { VIDEO_PALETTE_RGB555, "RGB555" },
547 { VIDEO_PALETTE_YUV422, "YUV422" },
548 { VIDEO_PALETTE_YUYV, "YUYV" },
549 { VIDEO_PALETTE_UYVY, "UYVY" },
550 { VIDEO_PALETTE_YUV420, "YUV420" },
551 { VIDEO_PALETTE_YUV411, "YUV411" },
552 { VIDEO_PALETTE_RAW, "RAW" },
553 { VIDEO_PALETTE_YUV422P, "YUV422P" },
554 { VIDEO_PALETTE_YUV411P, "YUV411P" },
555 { VIDEO_PALETTE_YUV420P, "YUV420P" },
556 { VIDEO_PALETTE_YUV410P, "YUV410P" },
557 { -1, NULL }
560 /* Decoder error codes: */
561 static struct w9968cf_symbolic_list decoder_errlist[] = {
562 { W9968CF_DEC_ERR_CORRUPTED_DATA, "Corrupted data" },
563 { W9968CF_DEC_ERR_BUF_OVERFLOW, "Buffer overflow" },
564 { W9968CF_DEC_ERR_NO_SOI, "SOI marker not found" },
565 { W9968CF_DEC_ERR_NO_SOF0, "SOF0 marker not found" },
566 { W9968CF_DEC_ERR_NO_SOS, "SOS marker not found" },
567 { W9968CF_DEC_ERR_NO_EOI, "EOI marker not found" },
568 { -1, NULL }
571 /* URB error codes: */
572 static struct w9968cf_symbolic_list urb_errlist[] = {
573 { -ENOMEM, "No memory for allocation of internal structures" },
574 { -ENOSPC, "The host controller's bandwidth is already consumed" },
575 { -ENOENT, "URB was canceled by unlink_urb" },
576 { -EXDEV, "ISO transfer only partially completed" },
577 { -EAGAIN, "Too match scheduled for the future" },
578 { -ENXIO, "URB already queued" },
579 { -EFBIG, "Too much ISO frames requested" },
580 { -ENOSR, "Buffer error (overrun)" },
581 { -EPIPE, "Specified endpoint is stalled (device not responding)"},
582 { -EOVERFLOW, "Babble (bad cable?)" },
583 { -EPROTO, "Bit-stuff error (bad cable?)" },
584 { -EILSEQ, "CRC/Timeout" },
585 { -ETIMEDOUT, "NAK (device does not respond)" },
586 { -1, NULL }
591 /****************************************************************************
592 * Memory management functions *
593 ****************************************************************************/
594 static void* rvmalloc(unsigned long size)
596 void* mem;
597 unsigned long adr;
599 size = PAGE_ALIGN(size);
600 mem = vmalloc_32(size);
601 if (!mem)
602 return NULL;
604 memset(mem, 0, size); /* Clear the ram out, no junk to the user */
605 adr = (unsigned long) mem;
606 while (size > 0) {
607 SetPageReserved(vmalloc_to_page((void *)adr));
608 adr += PAGE_SIZE;
609 size -= PAGE_SIZE;
612 return mem;
616 static void rvfree(void* mem, unsigned long size)
618 unsigned long adr;
620 if (!mem)
621 return;
623 adr = (unsigned long) mem;
624 while ((long) size > 0) {
625 ClearPageReserved(vmalloc_to_page((void *)adr));
626 adr += PAGE_SIZE;
627 size -= PAGE_SIZE;
629 vfree(mem);
633 /*--------------------------------------------------------------------------
634 Deallocate previously allocated memory.
635 --------------------------------------------------------------------------*/
636 static void w9968cf_deallocate_memory(struct w9968cf_device* cam)
638 u8 i;
640 /* Free the isochronous transfer buffers */
641 for (i = 0; i < W9968CF_URBS; i++) {
642 kfree(cam->transfer_buffer[i]);
643 cam->transfer_buffer[i] = NULL;
646 /* Free temporary frame buffer */
647 if (cam->frame_tmp.buffer) {
648 rvfree(cam->frame_tmp.buffer, cam->frame_tmp.size);
649 cam->frame_tmp.buffer = NULL;
652 /* Free helper buffer */
653 if (cam->frame_vpp.buffer) {
654 rvfree(cam->frame_vpp.buffer, cam->frame_vpp.size);
655 cam->frame_vpp.buffer = NULL;
658 /* Free video frame buffers */
659 if (cam->frame[0].buffer) {
660 rvfree(cam->frame[0].buffer, cam->nbuffers*cam->frame[0].size);
661 cam->frame[0].buffer = NULL;
664 cam->nbuffers = 0;
666 DBG(5, "Memory successfully deallocated")
670 /*--------------------------------------------------------------------------
671 Allocate memory buffers for USB transfers and video frames.
672 This function is called by open() only.
673 Return 0 on success, a negative number otherwise.
674 --------------------------------------------------------------------------*/
675 static int w9968cf_allocate_memory(struct w9968cf_device* cam)
677 const u16 p_size = wMaxPacketSize[cam->altsetting-1];
678 void* buff = NULL;
679 unsigned long hw_bufsize, vpp_bufsize;
680 u8 i, bpp;
682 /* NOTE: Deallocation is done elsewhere in case of error */
684 /* Calculate the max amount of raw data per frame from the device */
685 hw_bufsize = cam->maxwidth*cam->maxheight*2;
687 /* Calculate the max buf. size needed for post-processing routines */
688 bpp = (w9968cf_vpp) ? 4 : 2;
689 if (cam->upscaling)
690 vpp_bufsize = max(W9968CF_MAX_WIDTH*W9968CF_MAX_HEIGHT*bpp,
691 cam->maxwidth*cam->maxheight*bpp);
692 else
693 vpp_bufsize = cam->maxwidth*cam->maxheight*bpp;
695 /* Allocate memory for the isochronous transfer buffers */
696 for (i = 0; i < W9968CF_URBS; i++) {
697 if (!(cam->transfer_buffer[i] =
698 kmalloc(W9968CF_ISO_PACKETS*p_size, GFP_KERNEL))) {
699 DBG(1, "Couldn't allocate memory for the isochronous "
700 "transfer buffers (%u bytes)",
701 p_size * W9968CF_ISO_PACKETS)
702 return -ENOMEM;
704 memset(cam->transfer_buffer[i], 0, W9968CF_ISO_PACKETS*p_size);
707 /* Allocate memory for the temporary frame buffer */
708 if (!(cam->frame_tmp.buffer = rvmalloc(hw_bufsize))) {
709 DBG(1, "Couldn't allocate memory for the temporary "
710 "video frame buffer (%lu bytes)", hw_bufsize)
711 return -ENOMEM;
713 cam->frame_tmp.size = hw_bufsize;
714 cam->frame_tmp.number = -1;
716 /* Allocate memory for the helper buffer */
717 if (w9968cf_vpp) {
718 if (!(cam->frame_vpp.buffer = rvmalloc(vpp_bufsize))) {
719 DBG(1, "Couldn't allocate memory for the helper buffer"
720 " (%lu bytes)", vpp_bufsize)
721 return -ENOMEM;
723 cam->frame_vpp.size = vpp_bufsize;
724 } else
725 cam->frame_vpp.buffer = NULL;
727 /* Allocate memory for video frame buffers */
728 cam->nbuffers = cam->max_buffers;
729 while (cam->nbuffers >= 2) {
730 if ((buff = rvmalloc(cam->nbuffers * vpp_bufsize)))
731 break;
732 else
733 cam->nbuffers--;
736 if (!buff) {
737 DBG(1, "Couldn't allocate memory for the video frame buffers")
738 cam->nbuffers = 0;
739 return -ENOMEM;
742 if (cam->nbuffers != cam->max_buffers)
743 DBG(2, "Couldn't allocate memory for %u video frame buffers. "
744 "Only memory for %u buffers has been allocated",
745 cam->max_buffers, cam->nbuffers)
747 for (i = 0; i < cam->nbuffers; i++) {
748 cam->frame[i].buffer = buff + i*vpp_bufsize;
749 cam->frame[i].size = vpp_bufsize;
750 cam->frame[i].number = i;
751 /* Circular list */
752 if (i != cam->nbuffers-1)
753 cam->frame[i].next = &cam->frame[i+1];
754 else
755 cam->frame[i].next = &cam->frame[0];
756 cam->frame[i].status = F_UNUSED;
759 DBG(5, "Memory successfully allocated")
760 return 0;
765 /****************************************************************************
766 * USB-specific functions *
767 ****************************************************************************/
769 /*--------------------------------------------------------------------------
770 This is an handler function which is called after the URBs are completed.
771 It collects multiple data packets coming from the camera by putting them
772 into frame buffers: one or more zero data length data packets are used to
773 mark the end of a video frame; the first non-zero data packet is the start
774 of the next video frame; if an error is encountered in a packet, the entire
775 video frame is discarded and grabbed again.
776 If there are no requested frames in the FIFO list, packets are collected into
777 a temporary buffer.
778 --------------------------------------------------------------------------*/
779 static void w9968cf_urb_complete(struct urb *urb, struct pt_regs *regs)
781 struct w9968cf_device* cam = (struct w9968cf_device*)urb->context;
782 struct w9968cf_frame_t** f;
783 unsigned int len, status;
784 void* pos;
785 u8 i;
786 int err = 0;
788 if ((!cam->streaming) || cam->disconnected) {
789 DBG(4, "Got interrupt, but not streaming")
790 return;
793 /* "(*f)" will be used instead of "cam->frame_current" */
794 f = &cam->frame_current;
796 /* If a frame has been requested and we are grabbing into
797 the temporary frame, we'll switch to that requested frame */
798 if ((*f) == &cam->frame_tmp && *cam->requested_frame) {
799 if (cam->frame_tmp.status == F_GRABBING) {
800 w9968cf_pop_frame(cam, &cam->frame_current);
801 (*f)->status = F_GRABBING;
802 (*f)->length = cam->frame_tmp.length;
803 memcpy((*f)->buffer, cam->frame_tmp.buffer,
804 (*f)->length);
805 DBG(6, "Switched from temp. frame to frame #%d",
806 (*f)->number)
810 for (i = 0; i < urb->number_of_packets; i++) {
811 len = urb->iso_frame_desc[i].actual_length;
812 status = urb->iso_frame_desc[i].status;
813 pos = urb->iso_frame_desc[i].offset + urb->transfer_buffer;
815 if (status && len != 0) {
816 DBG(4, "URB failed, error in data packet "
817 "(error #%u, %s)",
818 status, symbolic(urb_errlist, status))
819 (*f)->status = F_ERROR;
820 continue;
823 if (len) { /* start of frame */
825 if ((*f)->status == F_UNUSED) {
826 (*f)->status = F_GRABBING;
827 (*f)->length = 0;
830 /* Buffer overflows shouldn't happen, however...*/
831 if ((*f)->length + len > (*f)->size) {
832 DBG(4, "Buffer overflow: bad data packets")
833 (*f)->status = F_ERROR;
836 if ((*f)->status == F_GRABBING) {
837 memcpy((*f)->buffer + (*f)->length, pos, len);
838 (*f)->length += len;
841 } else if ((*f)->status == F_GRABBING) { /* end of frame */
843 DBG(6, "Frame #%d successfully grabbed", (*f)->number)
845 if (cam->vpp_flag & VPP_DECOMPRESSION) {
846 err = w9968cf_vpp->check_headers((*f)->buffer,
847 (*f)->length);
848 if (err) {
849 DBG(4, "Skip corrupted frame: %s",
850 symbolic(decoder_errlist, err))
851 (*f)->status = F_UNUSED;
852 continue; /* grab this frame again */
856 (*f)->status = F_READY;
857 (*f)->queued = 0;
859 /* Take a pointer to the new frame from the FIFO list.
860 If the list is empty,we'll use the temporary frame*/
861 if (*cam->requested_frame)
862 w9968cf_pop_frame(cam, &cam->frame_current);
863 else {
864 cam->frame_current = &cam->frame_tmp;
865 (*f)->status = F_UNUSED;
868 } else if ((*f)->status == F_ERROR)
869 (*f)->status = F_UNUSED; /* grab it again */
871 PDBGG("Frame length %lu | pack.#%u | pack.len. %u | state %d",
872 (unsigned long)(*f)->length, i, len, (*f)->status)
874 } /* end for */
876 /* Resubmit this URB */
877 urb->dev = cam->usbdev;
878 urb->status = 0;
879 spin_lock(&cam->urb_lock);
880 if (cam->streaming)
881 if ((err = usb_submit_urb(urb, GFP_ATOMIC))) {
882 cam->misconfigured = 1;
883 DBG(1, "Couldn't resubmit the URB: error %d, %s",
884 err, symbolic(urb_errlist, err))
886 spin_unlock(&cam->urb_lock);
888 /* Wake up the user process */
889 wake_up_interruptible(&cam->wait_queue);
893 /*---------------------------------------------------------------------------
894 Setup the URB structures for the isochronous transfer.
895 Submit the URBs so that the data transfer begins.
896 Return 0 on success, a negative number otherwise.
897 ---------------------------------------------------------------------------*/
898 static int w9968cf_start_transfer(struct w9968cf_device* cam)
900 struct usb_device *udev = cam->usbdev;
901 struct urb* urb;
902 const u16 p_size = wMaxPacketSize[cam->altsetting-1];
903 u16 w, h, d;
904 int vidcapt;
905 u32 t_size;
906 int err = 0;
907 s8 i, j;
909 for (i = 0; i < W9968CF_URBS; i++) {
910 urb = usb_alloc_urb(W9968CF_ISO_PACKETS, GFP_KERNEL);
911 cam->urb[i] = urb;
912 if (!urb) {
913 for (j = 0; j < i; j++)
914 usb_free_urb(cam->urb[j]);
915 DBG(1, "Couldn't allocate the URB structures")
916 return -ENOMEM;
919 urb->dev = udev;
920 urb->context = (void*)cam;
921 urb->pipe = usb_rcvisocpipe(udev, 1);
922 urb->transfer_flags = URB_ISO_ASAP;
923 urb->number_of_packets = W9968CF_ISO_PACKETS;
924 urb->complete = w9968cf_urb_complete;
925 urb->transfer_buffer = cam->transfer_buffer[i];
926 urb->transfer_buffer_length = p_size*W9968CF_ISO_PACKETS;
927 urb->interval = 1;
928 for (j = 0; j < W9968CF_ISO_PACKETS; j++) {
929 urb->iso_frame_desc[j].offset = p_size*j;
930 urb->iso_frame_desc[j].length = p_size;
934 /* Transfer size per frame, in WORD ! */
935 d = cam->hw_depth;
936 w = cam->hw_width;
937 h = cam->hw_height;
939 t_size = (w*h*d)/16;
941 err = w9968cf_write_reg(cam, 0xbf17, 0x00); /* reset everything */
942 err += w9968cf_write_reg(cam, 0xbf10, 0x00); /* normal operation */
944 /* Transfer size */
945 err += w9968cf_write_reg(cam, t_size & 0xffff, 0x3d); /* low bits */
946 err += w9968cf_write_reg(cam, t_size >> 16, 0x3e); /* high bits */
948 if (cam->vpp_flag & VPP_DECOMPRESSION)
949 err += w9968cf_upload_quantizationtables(cam);
951 vidcapt = w9968cf_read_reg(cam, 0x16); /* read picture settings */
952 err += w9968cf_write_reg(cam, vidcapt|0x8000, 0x16); /* capt. enable */
954 err += usb_set_interface(udev, 0, cam->altsetting);
955 err += w9968cf_write_reg(cam, 0x8a05, 0x3c); /* USB FIFO enable */
957 if (err || (vidcapt < 0)) {
958 for (i = 0; i < W9968CF_URBS; i++)
959 usb_free_urb(cam->urb[i]);
960 DBG(1, "Couldn't tell the camera to start the data transfer")
961 return err;
964 w9968cf_init_framelist(cam);
966 /* Begin to grab into the temporary buffer */
967 cam->frame_tmp.status = F_UNUSED;
968 cam->frame_tmp.queued = 0;
969 cam->frame_current = &cam->frame_tmp;
971 if (!(cam->vpp_flag & VPP_DECOMPRESSION))
972 DBG(5, "Isochronous transfer size: %lu bytes/frame",
973 (unsigned long)t_size*2)
975 DBG(5, "Starting the isochronous transfer...")
977 cam->streaming = 1;
979 /* Submit the URBs */
980 for (i = 0; i < W9968CF_URBS; i++) {
981 err = usb_submit_urb(cam->urb[i], GFP_KERNEL);
982 if (err) {
983 cam->streaming = 0;
984 for (j = i-1; j >= 0; j--) {
985 usb_kill_urb(cam->urb[j]);
986 usb_free_urb(cam->urb[j]);
988 DBG(1, "Couldn't send a transfer request to the "
989 "USB core (error #%d, %s)", err,
990 symbolic(urb_errlist, err))
991 return err;
995 return 0;
999 /*--------------------------------------------------------------------------
1000 Stop the isochronous transfer and set alternate setting to 0 (0Mb/s).
1001 Return 0 on success, a negative number otherwise.
1002 --------------------------------------------------------------------------*/
1003 static int w9968cf_stop_transfer(struct w9968cf_device* cam)
1005 struct usb_device *udev = cam->usbdev;
1006 unsigned long lock_flags;
1007 int err = 0;
1008 s8 i;
1010 if (!cam->streaming)
1011 return 0;
1013 /* This avoids race conditions with usb_submit_urb()
1014 in the URB completition handler */
1015 spin_lock_irqsave(&cam->urb_lock, lock_flags);
1016 cam->streaming = 0;
1017 spin_unlock_irqrestore(&cam->urb_lock, lock_flags);
1019 for (i = W9968CF_URBS-1; i >= 0; i--)
1020 if (cam->urb[i]) {
1021 usb_kill_urb(cam->urb[i]);
1022 usb_free_urb(cam->urb[i]);
1023 cam->urb[i] = NULL;
1026 if (cam->disconnected)
1027 goto exit;
1029 err = w9968cf_write_reg(cam, 0x0a05, 0x3c); /* stop USB transfer */
1030 err += usb_set_interface(udev, 0, 0); /* 0 Mb/s */
1031 err += w9968cf_write_reg(cam, 0x0000, 0x39); /* disable JPEG encoder */
1032 err += w9968cf_write_reg(cam, 0x0000, 0x16); /* stop video capture */
1034 if (err) {
1035 DBG(2, "Failed to tell the camera to stop the isochronous "
1036 "transfer. However this is not a critical error.")
1037 return -EIO;
1040 exit:
1041 DBG(5, "Isochronous transfer stopped")
1042 return 0;
1046 /*--------------------------------------------------------------------------
1047 Write a W9968CF register.
1048 Return 0 on success, -1 otherwise.
1049 --------------------------------------------------------------------------*/
1050 static int w9968cf_write_reg(struct w9968cf_device* cam, u16 value, u16 index)
1052 struct usb_device* udev = cam->usbdev;
1053 int res;
1055 res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0,
1056 USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE,
1057 value, index, NULL, 0, W9968CF_USB_CTRL_TIMEOUT);
1059 if (res < 0)
1060 DBG(4, "Failed to write a register "
1061 "(value 0x%04X, index 0x%02X, error #%d, %s)",
1062 value, index, res, symbolic(urb_errlist, res))
1064 return (res >= 0) ? 0 : -1;
1068 /*--------------------------------------------------------------------------
1069 Read a W9968CF register.
1070 Return the register value on success, -1 otherwise.
1071 --------------------------------------------------------------------------*/
1072 static int w9968cf_read_reg(struct w9968cf_device* cam, u16 index)
1074 struct usb_device* udev = cam->usbdev;
1075 u16* buff = cam->control_buffer;
1076 int res;
1078 res = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 1,
1079 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
1080 0, index, buff, 2, W9968CF_USB_CTRL_TIMEOUT);
1082 if (res < 0)
1083 DBG(4, "Failed to read a register "
1084 "(index 0x%02X, error #%d, %s)",
1085 index, res, symbolic(urb_errlist, res))
1087 return (res >= 0) ? (int)(*buff) : -1;
1091 /*--------------------------------------------------------------------------
1092 Write 64-bit data to the fast serial bus registers.
1093 Return 0 on success, -1 otherwise.
1094 --------------------------------------------------------------------------*/
1095 static int w9968cf_write_fsb(struct w9968cf_device* cam, u16* data)
1097 struct usb_device* udev = cam->usbdev;
1098 u16 value;
1099 int res;
1101 value = *data++;
1103 res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0,
1104 USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE,
1105 value, 0x06, data, 6, W9968CF_USB_CTRL_TIMEOUT);
1107 if (res < 0)
1108 DBG(4, "Failed to write the FSB registers "
1109 "(error #%d, %s)", res, symbolic(urb_errlist, res))
1111 return (res >= 0) ? 0 : -1;
1115 /*--------------------------------------------------------------------------
1116 Write data to the serial bus control register.
1117 Return 0 on success, a negative number otherwise.
1118 --------------------------------------------------------------------------*/
1119 static int w9968cf_write_sb(struct w9968cf_device* cam, u16 value)
1121 int err = 0;
1123 err = w9968cf_write_reg(cam, value, 0x01);
1124 udelay(W9968CF_I2C_BUS_DELAY);
1126 return err;
1130 /*--------------------------------------------------------------------------
1131 Read data from the serial bus control register.
1132 Return 0 on success, a negative number otherwise.
1133 --------------------------------------------------------------------------*/
1134 static int w9968cf_read_sb(struct w9968cf_device* cam)
1136 int v = 0;
1138 v = w9968cf_read_reg(cam, 0x01);
1139 udelay(W9968CF_I2C_BUS_DELAY);
1141 return v;
1145 /*--------------------------------------------------------------------------
1146 Upload quantization tables for the JPEG compression.
1147 This function is called by w9968cf_start_transfer().
1148 Return 0 on success, a negative number otherwise.
1149 --------------------------------------------------------------------------*/
1150 static int w9968cf_upload_quantizationtables(struct w9968cf_device* cam)
1152 u16 a, b;
1153 int err = 0, i, j;
1155 err += w9968cf_write_reg(cam, 0x0010, 0x39); /* JPEG clock enable */
1157 for (i = 0, j = 0; i < 32; i++, j += 2) {
1158 a = Y_QUANTABLE[j] | ((unsigned)(Y_QUANTABLE[j+1]) << 8);
1159 b = UV_QUANTABLE[j] | ((unsigned)(UV_QUANTABLE[j+1]) << 8);
1160 err += w9968cf_write_reg(cam, a, 0x40+i);
1161 err += w9968cf_write_reg(cam, b, 0x60+i);
1163 err += w9968cf_write_reg(cam, 0x0012, 0x39); /* JPEG encoder enable */
1165 return err;
1170 /****************************************************************************
1171 * Low-level I2C I/O functions. *
1172 * The adapter supports the following I2C transfer functions: *
1173 * i2c_adap_fastwrite_byte_data() (at 400 kHz bit frequency only) *
1174 * i2c_adap_read_byte_data() *
1175 * i2c_adap_read_byte() *
1176 ****************************************************************************/
1178 static int w9968cf_smbus_start(struct w9968cf_device* cam)
1180 int err = 0;
1182 err += w9968cf_write_sb(cam, 0x0011); /* SDE=1, SDA=0, SCL=1 */
1183 err += w9968cf_write_sb(cam, 0x0010); /* SDE=1, SDA=0, SCL=0 */
1185 return err;
1189 static int w9968cf_smbus_stop(struct w9968cf_device* cam)
1191 int err = 0;
1193 err += w9968cf_write_sb(cam, 0x0011); /* SDE=1, SDA=0, SCL=1 */
1194 err += w9968cf_write_sb(cam, 0x0013); /* SDE=1, SDA=1, SCL=1 */
1196 return err;
1200 static int w9968cf_smbus_write_byte(struct w9968cf_device* cam, u8 v)
1202 u8 bit;
1203 int err = 0, sda;
1205 for (bit = 0 ; bit < 8 ; bit++) {
1206 sda = (v & 0x80) ? 2 : 0;
1207 v <<= 1;
1208 /* SDE=1, SDA=sda, SCL=0 */
1209 err += w9968cf_write_sb(cam, 0x10 | sda);
1210 /* SDE=1, SDA=sda, SCL=1 */
1211 err += w9968cf_write_sb(cam, 0x11 | sda);
1212 /* SDE=1, SDA=sda, SCL=0 */
1213 err += w9968cf_write_sb(cam, 0x10 | sda);
1216 return err;
1220 static int w9968cf_smbus_read_byte(struct w9968cf_device* cam, u8* v)
1222 u8 bit;
1223 int err = 0;
1225 *v = 0;
1226 for (bit = 0 ; bit < 8 ; bit++) {
1227 *v <<= 1;
1228 err += w9968cf_write_sb(cam, 0x0013);
1229 *v |= (w9968cf_read_sb(cam) & 0x0008) ? 1 : 0;
1230 err += w9968cf_write_sb(cam, 0x0012);
1233 return err;
1237 static int w9968cf_smbus_write_ack(struct w9968cf_device* cam)
1239 int err = 0;
1241 err += w9968cf_write_sb(cam, 0x0010); /* SDE=1, SDA=0, SCL=0 */
1242 err += w9968cf_write_sb(cam, 0x0011); /* SDE=1, SDA=0, SCL=1 */
1243 err += w9968cf_write_sb(cam, 0x0010); /* SDE=1, SDA=0, SCL=0 */
1245 return err;
1249 static int w9968cf_smbus_read_ack(struct w9968cf_device* cam)
1251 int err = 0, sda;
1253 err += w9968cf_write_sb(cam, 0x0013); /* SDE=1, SDA=1, SCL=1 */
1254 sda = (w9968cf_read_sb(cam) & 0x08) ? 1 : 0; /* sda = SDA */
1255 err += w9968cf_write_sb(cam, 0x0012); /* SDE=1, SDA=1, SCL=0 */
1256 if (sda < 0)
1257 err += sda;
1258 if (sda == 1) {
1259 DBG(6, "Couldn't receive the ACK")
1260 err += -1;
1263 return err;
1267 /* This seems to refresh the communication through the serial bus */
1268 static int w9968cf_smbus_refresh_bus(struct w9968cf_device* cam)
1270 int err = 0, j;
1272 for (j = 1; j <= 10; j++) {
1273 err = w9968cf_write_reg(cam, 0x0020, 0x01);
1274 err += w9968cf_write_reg(cam, 0x0000, 0x01);
1275 if (err)
1276 break;
1279 return err;
1283 /* SMBus protocol: S Addr Wr [A] Subaddr [A] Value [A] P */
1284 static int
1285 w9968cf_i2c_adap_fastwrite_byte_data(struct w9968cf_device* cam,
1286 u16 address, u8 subaddress,u8 value)
1288 u16* data = cam->data_buffer;
1289 int err = 0;
1291 err += w9968cf_smbus_refresh_bus(cam);
1293 /* Enable SBUS outputs */
1294 err += w9968cf_write_sb(cam, 0x0020);
1296 data[0] = 0x082f | ((address & 0x80) ? 0x1500 : 0x0);
1297 data[0] |= (address & 0x40) ? 0x4000 : 0x0;
1298 data[1] = 0x2082 | ((address & 0x40) ? 0x0005 : 0x0);
1299 data[1] |= (address & 0x20) ? 0x0150 : 0x0;
1300 data[1] |= (address & 0x10) ? 0x5400 : 0x0;
1301 data[2] = 0x8208 | ((address & 0x08) ? 0x0015 : 0x0);
1302 data[2] |= (address & 0x04) ? 0x0540 : 0x0;
1303 data[2] |= (address & 0x02) ? 0x5000 : 0x0;
1304 data[3] = 0x1d20 | ((address & 0x02) ? 0x0001 : 0x0);
1305 data[3] |= (address & 0x01) ? 0x0054 : 0x0;
1307 err += w9968cf_write_fsb(cam, data);
1309 data[0] = 0x8208 | ((subaddress & 0x80) ? 0x0015 : 0x0);
1310 data[0] |= (subaddress & 0x40) ? 0x0540 : 0x0;
1311 data[0] |= (subaddress & 0x20) ? 0x5000 : 0x0;
1312 data[1] = 0x0820 | ((subaddress & 0x20) ? 0x0001 : 0x0);
1313 data[1] |= (subaddress & 0x10) ? 0x0054 : 0x0;
1314 data[1] |= (subaddress & 0x08) ? 0x1500 : 0x0;
1315 data[1] |= (subaddress & 0x04) ? 0x4000 : 0x0;
1316 data[2] = 0x2082 | ((subaddress & 0x04) ? 0x0005 : 0x0);
1317 data[2] |= (subaddress & 0x02) ? 0x0150 : 0x0;
1318 data[2] |= (subaddress & 0x01) ? 0x5400 : 0x0;
1319 data[3] = 0x001d;
1321 err += w9968cf_write_fsb(cam, data);
1323 data[0] = 0x8208 | ((value & 0x80) ? 0x0015 : 0x0);
1324 data[0] |= (value & 0x40) ? 0x0540 : 0x0;
1325 data[0] |= (value & 0x20) ? 0x5000 : 0x0;
1326 data[1] = 0x0820 | ((value & 0x20) ? 0x0001 : 0x0);
1327 data[1] |= (value & 0x10) ? 0x0054 : 0x0;
1328 data[1] |= (value & 0x08) ? 0x1500 : 0x0;
1329 data[1] |= (value & 0x04) ? 0x4000 : 0x0;
1330 data[2] = 0x2082 | ((value & 0x04) ? 0x0005 : 0x0);
1331 data[2] |= (value & 0x02) ? 0x0150 : 0x0;
1332 data[2] |= (value & 0x01) ? 0x5400 : 0x0;
1333 data[3] = 0xfe1d;
1335 err += w9968cf_write_fsb(cam, data);
1337 /* Disable SBUS outputs */
1338 err += w9968cf_write_sb(cam, 0x0000);
1340 if (!err)
1341 DBG(5, "I2C write byte data done, addr.0x%04X, subaddr.0x%02X "
1342 "value 0x%02X", address, subaddress, value)
1343 else
1344 DBG(5, "I2C write byte data failed, addr.0x%04X, "
1345 "subaddr.0x%02X, value 0x%02X",
1346 address, subaddress, value)
1348 return err;
1352 /* SMBus protocol: S Addr Wr [A] Subaddr [A] P S Addr+1 Rd [A] [Value] NA P */
1353 static int
1354 w9968cf_i2c_adap_read_byte_data(struct w9968cf_device* cam,
1355 u16 address, u8 subaddress,
1356 u8* value)
1358 int err = 0;
1360 /* Serial data enable */
1361 err += w9968cf_write_sb(cam, 0x0013); /* don't change ! */
1363 err += w9968cf_smbus_start(cam);
1364 err += w9968cf_smbus_write_byte(cam, address);
1365 err += w9968cf_smbus_read_ack(cam);
1366 err += w9968cf_smbus_write_byte(cam, subaddress);
1367 err += w9968cf_smbus_read_ack(cam);
1368 err += w9968cf_smbus_stop(cam);
1369 err += w9968cf_smbus_start(cam);
1370 err += w9968cf_smbus_write_byte(cam, address + 1);
1371 err += w9968cf_smbus_read_ack(cam);
1372 err += w9968cf_smbus_read_byte(cam, value);
1373 err += w9968cf_smbus_write_ack(cam);
1374 err += w9968cf_smbus_stop(cam);
1376 /* Serial data disable */
1377 err += w9968cf_write_sb(cam, 0x0000);
1379 if (!err)
1380 DBG(5, "I2C read byte data done, addr.0x%04X, "
1381 "subaddr.0x%02X, value 0x%02X",
1382 address, subaddress, *value)
1383 else
1384 DBG(5, "I2C read byte data failed, addr.0x%04X, "
1385 "subaddr.0x%02X, wrong value 0x%02X",
1386 address, subaddress, *value)
1388 return err;
1392 /* SMBus protocol: S Addr+1 Rd [A] [Value] NA P */
1393 static int
1394 w9968cf_i2c_adap_read_byte(struct w9968cf_device* cam,
1395 u16 address, u8* value)
1397 int err = 0;
1399 /* Serial data enable */
1400 err += w9968cf_write_sb(cam, 0x0013);
1402 err += w9968cf_smbus_start(cam);
1403 err += w9968cf_smbus_write_byte(cam, address + 1);
1404 err += w9968cf_smbus_read_ack(cam);
1405 err += w9968cf_smbus_read_byte(cam, value);
1406 err += w9968cf_smbus_write_ack(cam);
1407 err += w9968cf_smbus_stop(cam);
1409 /* Serial data disable */
1410 err += w9968cf_write_sb(cam, 0x0000);
1412 if (!err)
1413 DBG(5, "I2C read byte done, addr.0x%04X, "
1414 "value 0x%02X", address, *value)
1415 else
1416 DBG(5, "I2C read byte failed, addr.0x%04X, "
1417 "wrong value 0x%02X", address, *value)
1419 return err;
1423 /* SMBus protocol: S Addr Wr [A] Value [A] P */
1424 static int
1425 w9968cf_i2c_adap_write_byte(struct w9968cf_device* cam,
1426 u16 address, u8 value)
1428 DBG(4, "i2c_write_byte() is an unsupported transfer mode")
1429 return -EINVAL;
1434 /****************************************************************************
1435 * I2C interface to kernel *
1436 ****************************************************************************/
1438 static int
1439 w9968cf_i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr,
1440 unsigned short flags, char read_write, u8 command,
1441 int size, union i2c_smbus_data *data)
1443 struct w9968cf_device* cam = i2c_get_adapdata(adapter);
1444 u8 i;
1445 int err = 0;
1447 switch (addr) {
1448 case OV6xx0_SID:
1449 case OV7xx0_SID:
1450 break;
1451 default:
1452 DBG(4, "Rejected slave ID 0x%04X", addr)
1453 return -EINVAL;
1456 if (size == I2C_SMBUS_BYTE) {
1457 /* Why addr <<= 1? See OVXXX0_SID defines in ovcamchip.h */
1458 addr <<= 1;
1460 if (read_write == I2C_SMBUS_WRITE)
1461 err = w9968cf_i2c_adap_write_byte(cam, addr, command);
1462 else if (read_write == I2C_SMBUS_READ)
1463 err = w9968cf_i2c_adap_read_byte(cam,addr,&data->byte);
1465 } else if (size == I2C_SMBUS_BYTE_DATA) {
1466 addr <<= 1;
1468 if (read_write == I2C_SMBUS_WRITE)
1469 err = w9968cf_i2c_adap_fastwrite_byte_data(cam, addr,
1470 command, data->byte);
1471 else if (read_write == I2C_SMBUS_READ) {
1472 for (i = 1; i <= W9968CF_I2C_RW_RETRIES; i++) {
1473 err = w9968cf_i2c_adap_read_byte_data(cam,addr,
1474 command, &data->byte);
1475 if (err) {
1476 if (w9968cf_smbus_refresh_bus(cam)) {
1477 err = -EIO;
1478 break;
1480 } else
1481 break;
1484 } else
1485 return -EINVAL;
1487 } else {
1488 DBG(4, "Unsupported I2C transfer mode (%d)", size)
1489 return -EINVAL;
1492 return err;
1496 static u32 w9968cf_i2c_func(struct i2c_adapter* adap)
1498 return I2C_FUNC_SMBUS_READ_BYTE |
1499 I2C_FUNC_SMBUS_READ_BYTE_DATA |
1500 I2C_FUNC_SMBUS_WRITE_BYTE_DATA;
1504 static int w9968cf_i2c_attach_inform(struct i2c_client* client)
1506 struct w9968cf_device* cam = i2c_get_adapdata(client->adapter);
1507 int id = client->driver->id, err = 0;
1509 if (id == I2C_DRIVERID_OVCAMCHIP) {
1510 cam->sensor_client = client;
1511 err = w9968cf_sensor_init(cam);
1512 if (err) {
1513 cam->sensor_client = NULL;
1514 return err;
1516 } else {
1517 DBG(4, "Rejected client [%s] with driver [%s]",
1518 client->name, client->driver->driver.name)
1519 return -EINVAL;
1522 DBG(5, "I2C attach client [%s] with driver [%s]",
1523 client->name, client->driver->driver.name)
1525 return 0;
1529 static int w9968cf_i2c_detach_inform(struct i2c_client* client)
1531 struct w9968cf_device* cam = i2c_get_adapdata(client->adapter);
1533 if (cam->sensor_client == client)
1534 cam->sensor_client = NULL;
1536 DBG(5, "I2C detach client [%s]", client->name)
1538 return 0;
1542 static int
1543 w9968cf_i2c_control(struct i2c_adapter* adapter, unsigned int cmd,
1544 unsigned long arg)
1546 return 0;
1550 static int w9968cf_i2c_init(struct w9968cf_device* cam)
1552 int err = 0;
1554 static struct i2c_algorithm algo = {
1555 .smbus_xfer = w9968cf_i2c_smbus_xfer,
1556 .algo_control = w9968cf_i2c_control,
1557 .functionality = w9968cf_i2c_func,
1560 static struct i2c_adapter adap = {
1561 .id = I2C_HW_SMBUS_W9968CF,
1562 .class = I2C_CLASS_CAM_DIGITAL,
1563 .owner = THIS_MODULE,
1564 .client_register = w9968cf_i2c_attach_inform,
1565 .client_unregister = w9968cf_i2c_detach_inform,
1566 .algo = &algo,
1569 memcpy(&cam->i2c_adapter, &adap, sizeof(struct i2c_adapter));
1570 strcpy(cam->i2c_adapter.name, "w9968cf");
1571 i2c_set_adapdata(&cam->i2c_adapter, cam);
1573 DBG(6, "Registering I2C adapter with kernel...")
1575 err = i2c_add_adapter(&cam->i2c_adapter);
1576 if (err)
1577 DBG(1, "Failed to register the I2C adapter")
1578 else
1579 DBG(5, "I2C adapter registered")
1581 return err;
1586 /****************************************************************************
1587 * Helper functions *
1588 ****************************************************************************/
1590 /*--------------------------------------------------------------------------
1591 Turn on the LED on some webcams. A beep should be heard too.
1592 Return 0 on success, a negative number otherwise.
1593 --------------------------------------------------------------------------*/
1594 static int w9968cf_turn_on_led(struct w9968cf_device* cam)
1596 int err = 0;
1598 err += w9968cf_write_reg(cam, 0xff00, 0x00); /* power-down */
1599 err += w9968cf_write_reg(cam, 0xbf17, 0x00); /* reset everything */
1600 err += w9968cf_write_reg(cam, 0xbf10, 0x00); /* normal operation */
1601 err += w9968cf_write_reg(cam, 0x0010, 0x01); /* serial bus, SDS high */
1602 err += w9968cf_write_reg(cam, 0x0000, 0x01); /* serial bus, SDS low */
1603 err += w9968cf_write_reg(cam, 0x0010, 0x01); /* ..high 'beep-beep' */
1605 if (err)
1606 DBG(2, "Couldn't turn on the LED")
1608 DBG(5, "LED turned on")
1610 return err;
1614 /*--------------------------------------------------------------------------
1615 Write some registers for the device initialization.
1616 This function is called once on open().
1617 Return 0 on success, a negative number otherwise.
1618 --------------------------------------------------------------------------*/
1619 static int w9968cf_init_chip(struct w9968cf_device* cam)
1621 unsigned long hw_bufsize = cam->maxwidth*cam->maxheight*2,
1622 y0 = 0x0000,
1623 u0 = y0 + hw_bufsize/2,
1624 v0 = u0 + hw_bufsize/4,
1625 y1 = v0 + hw_bufsize/4,
1626 u1 = y1 + hw_bufsize/2,
1627 v1 = u1 + hw_bufsize/4;
1628 int err = 0;
1630 err += w9968cf_write_reg(cam, 0xff00, 0x00); /* power off */
1631 err += w9968cf_write_reg(cam, 0xbf10, 0x00); /* power on */
1633 err += w9968cf_write_reg(cam, 0x405d, 0x03); /* DRAM timings */
1634 err += w9968cf_write_reg(cam, 0x0030, 0x04); /* SDRAM timings */
1636 err += w9968cf_write_reg(cam, y0 & 0xffff, 0x20); /* Y buf.0, low */
1637 err += w9968cf_write_reg(cam, y0 >> 16, 0x21); /* Y buf.0, high */
1638 err += w9968cf_write_reg(cam, u0 & 0xffff, 0x24); /* U buf.0, low */
1639 err += w9968cf_write_reg(cam, u0 >> 16, 0x25); /* U buf.0, high */
1640 err += w9968cf_write_reg(cam, v0 & 0xffff, 0x28); /* V buf.0, low */
1641 err += w9968cf_write_reg(cam, v0 >> 16, 0x29); /* V buf.0, high */
1643 err += w9968cf_write_reg(cam, y1 & 0xffff, 0x22); /* Y buf.1, low */
1644 err += w9968cf_write_reg(cam, y1 >> 16, 0x23); /* Y buf.1, high */
1645 err += w9968cf_write_reg(cam, u1 & 0xffff, 0x26); /* U buf.1, low */
1646 err += w9968cf_write_reg(cam, u1 >> 16, 0x27); /* U buf.1, high */
1647 err += w9968cf_write_reg(cam, v1 & 0xffff, 0x2a); /* V buf.1, low */
1648 err += w9968cf_write_reg(cam, v1 >> 16, 0x2b); /* V buf.1, high */
1650 err += w9968cf_write_reg(cam, y1 & 0xffff, 0x32); /* JPEG buf 0 low */
1651 err += w9968cf_write_reg(cam, y1 >> 16, 0x33); /* JPEG buf 0 high */
1653 err += w9968cf_write_reg(cam, y1 & 0xffff, 0x34); /* JPEG buf 1 low */
1654 err += w9968cf_write_reg(cam, y1 >> 16, 0x35); /* JPEG bug 1 high */
1656 err += w9968cf_write_reg(cam, 0x0000, 0x36);/* JPEG restart interval */
1657 err += w9968cf_write_reg(cam, 0x0804, 0x37);/*JPEG VLE FIFO threshold*/
1658 err += w9968cf_write_reg(cam, 0x0000, 0x38);/* disable hw up-scaling */
1659 err += w9968cf_write_reg(cam, 0x0000, 0x3f); /* JPEG/MCTL test data */
1661 err += w9968cf_set_picture(cam, cam->picture); /* this before */
1662 err += w9968cf_set_window(cam, cam->window);
1664 if (err)
1665 DBG(1, "Chip initialization failed")
1666 else
1667 DBG(5, "Chip successfully initialized")
1669 return err;
1673 /*--------------------------------------------------------------------------
1674 Return non-zero if the palette is supported, 0 otherwise.
1675 --------------------------------------------------------------------------*/
1676 static inline u16 w9968cf_valid_palette(u16 palette)
1678 u8 i = 0;
1679 while (w9968cf_formatlist[i].palette != 0) {
1680 if (palette == w9968cf_formatlist[i].palette)
1681 return palette;
1682 i++;
1684 return 0;
1688 /*--------------------------------------------------------------------------
1689 Return the depth corresponding to the given palette.
1690 Palette _must_ be supported !
1691 --------------------------------------------------------------------------*/
1692 static inline u16 w9968cf_valid_depth(u16 palette)
1694 u8 i=0;
1695 while (w9968cf_formatlist[i].palette != palette)
1696 i++;
1698 return w9968cf_formatlist[i].depth;
1702 /*--------------------------------------------------------------------------
1703 Return non-zero if the format requires decompression, 0 otherwise.
1704 --------------------------------------------------------------------------*/
1705 static inline u8 w9968cf_need_decompression(u16 palette)
1707 u8 i = 0;
1708 while (w9968cf_formatlist[i].palette != 0) {
1709 if (palette == w9968cf_formatlist[i].palette)
1710 return w9968cf_formatlist[i].compression;
1711 i++;
1713 return 0;
1717 /*--------------------------------------------------------------------------
1718 Change the picture settings of the camera.
1719 Return 0 on success, a negative number otherwise.
1720 --------------------------------------------------------------------------*/
1721 static int
1722 w9968cf_set_picture(struct w9968cf_device* cam, struct video_picture pict)
1724 u16 fmt, hw_depth, hw_palette, reg_v = 0x0000;
1725 int err = 0;
1727 /* Make sure we are using a valid depth */
1728 pict.depth = w9968cf_valid_depth(pict.palette);
1730 fmt = pict.palette;
1732 hw_depth = pict.depth; /* depth used by the winbond chip */
1733 hw_palette = pict.palette; /* palette used by the winbond chip */
1735 /* VS & HS polarities */
1736 reg_v = (cam->vs_polarity << 12) | (cam->hs_polarity << 11);
1738 switch (fmt)
1740 case VIDEO_PALETTE_UYVY:
1741 reg_v |= 0x0000;
1742 cam->vpp_flag = VPP_NONE;
1743 break;
1744 case VIDEO_PALETTE_YUV422P:
1745 reg_v |= 0x0002;
1746 cam->vpp_flag = VPP_DECOMPRESSION;
1747 break;
1748 case VIDEO_PALETTE_YUV420:
1749 case VIDEO_PALETTE_YUV420P:
1750 reg_v |= 0x0003;
1751 cam->vpp_flag = VPP_DECOMPRESSION;
1752 break;
1753 case VIDEO_PALETTE_YUYV:
1754 case VIDEO_PALETTE_YUV422:
1755 reg_v |= 0x0000;
1756 cam->vpp_flag = VPP_SWAP_YUV_BYTES;
1757 hw_palette = VIDEO_PALETTE_UYVY;
1758 break;
1759 /* Original video is used instead of RGBX palettes.
1760 Software conversion later. */
1761 case VIDEO_PALETTE_GREY:
1762 case VIDEO_PALETTE_RGB555:
1763 case VIDEO_PALETTE_RGB565:
1764 case VIDEO_PALETTE_RGB24:
1765 case VIDEO_PALETTE_RGB32:
1766 reg_v |= 0x0000; /* UYVY 16 bit is used */
1767 hw_depth = 16;
1768 hw_palette = VIDEO_PALETTE_UYVY;
1769 cam->vpp_flag = VPP_UYVY_TO_RGBX;
1770 break;
1773 /* NOTE: due to memory issues, it is better to disable the hardware
1774 double buffering during compression */
1775 if (cam->double_buffer && !(cam->vpp_flag & VPP_DECOMPRESSION))
1776 reg_v |= 0x0080;
1778 if (cam->clamping)
1779 reg_v |= 0x0020;
1781 if (cam->filter_type == 1)
1782 reg_v |= 0x0008;
1783 else if (cam->filter_type == 2)
1784 reg_v |= 0x000c;
1786 if ((err = w9968cf_write_reg(cam, reg_v, 0x16)))
1787 goto error;
1789 if ((err = w9968cf_sensor_update_picture(cam, pict)))
1790 goto error;
1792 /* If all went well, update the device data structure */
1793 memcpy(&cam->picture, &pict, sizeof(pict));
1794 cam->hw_depth = hw_depth;
1795 cam->hw_palette = hw_palette;
1797 /* Settings changed, so we clear the frame buffers */
1798 memset(cam->frame[0].buffer, 0, cam->nbuffers*cam->frame[0].size);
1800 DBG(4, "Palette is %s, depth is %u bpp",
1801 symbolic(v4l1_plist, pict.palette), pict.depth)
1803 return 0;
1805 error:
1806 DBG(1, "Failed to change picture settings")
1807 return err;
1811 /*--------------------------------------------------------------------------
1812 Change the capture area size of the camera.
1813 This function _must_ be called _after_ w9968cf_set_picture().
1814 Return 0 on success, a negative number otherwise.
1815 --------------------------------------------------------------------------*/
1816 static int
1817 w9968cf_set_window(struct w9968cf_device* cam, struct video_window win)
1819 u16 x, y, w, h, scx, scy, cw, ch, ax, ay;
1820 unsigned long fw, fh;
1821 struct ovcamchip_window s_win;
1822 int err = 0;
1824 /* Work around to avoid FP arithmetics */
1825 #define __SC(x) ((x) << 10)
1826 #define __UNSC(x) ((x) >> 10)
1828 /* Make sure we are using a supported resolution */
1829 if ((err = w9968cf_adjust_window_size(cam, (u16*)&win.width,
1830 (u16*)&win.height)))
1831 goto error;
1833 /* Scaling factors */
1834 fw = __SC(win.width) / cam->maxwidth;
1835 fh = __SC(win.height) / cam->maxheight;
1837 /* Set up the width and height values used by the chip */
1838 if ((win.width > cam->maxwidth) || (win.height > cam->maxheight)) {
1839 cam->vpp_flag |= VPP_UPSCALE;
1840 /* Calculate largest w,h mantaining the same w/h ratio */
1841 w = (fw >= fh) ? cam->maxwidth : __SC(win.width)/fh;
1842 h = (fw >= fh) ? __SC(win.height)/fw : cam->maxheight;
1843 if (w < cam->minwidth) /* just in case */
1844 w = cam->minwidth;
1845 if (h < cam->minheight) /* just in case */
1846 h = cam->minheight;
1847 } else {
1848 cam->vpp_flag &= ~VPP_UPSCALE;
1849 w = win.width;
1850 h = win.height;
1853 /* x,y offsets of the cropped area */
1854 scx = cam->start_cropx;
1855 scy = cam->start_cropy;
1857 /* Calculate cropped area manteining the right w/h ratio */
1858 if (cam->largeview && !(cam->vpp_flag & VPP_UPSCALE)) {
1859 cw = (fw >= fh) ? cam->maxwidth : __SC(win.width)/fh;
1860 ch = (fw >= fh) ? __SC(win.height)/fw : cam->maxheight;
1861 } else {
1862 cw = w;
1863 ch = h;
1866 /* Setup the window of the sensor */
1867 s_win.format = VIDEO_PALETTE_UYVY;
1868 s_win.width = cam->maxwidth;
1869 s_win.height = cam->maxheight;
1870 s_win.quarter = 0; /* full progressive video */
1872 /* Center it */
1873 s_win.x = (s_win.width - cw) / 2;
1874 s_win.y = (s_win.height - ch) / 2;
1876 /* Clock divisor */
1877 if (cam->clockdiv >= 0)
1878 s_win.clockdiv = cam->clockdiv; /* manual override */
1879 else
1880 switch (cam->sensor) {
1881 case CC_OV6620:
1882 s_win.clockdiv = 0;
1883 break;
1884 case CC_OV6630:
1885 s_win.clockdiv = 0;
1886 break;
1887 case CC_OV76BE:
1888 case CC_OV7610:
1889 case CC_OV7620:
1890 s_win.clockdiv = 0;
1891 break;
1892 default:
1893 s_win.clockdiv = W9968CF_DEF_CLOCKDIVISOR;
1896 /* We have to scale win.x and win.y offsets */
1897 if ( (cam->largeview && !(cam->vpp_flag & VPP_UPSCALE))
1898 || (cam->vpp_flag & VPP_UPSCALE) ) {
1899 ax = __SC(win.x)/fw;
1900 ay = __SC(win.y)/fh;
1901 } else {
1902 ax = win.x;
1903 ay = win.y;
1906 if ((ax + cw) > cam->maxwidth)
1907 ax = cam->maxwidth - cw;
1909 if ((ay + ch) > cam->maxheight)
1910 ay = cam->maxheight - ch;
1912 /* Adjust win.x, win.y */
1913 if ( (cam->largeview && !(cam->vpp_flag & VPP_UPSCALE))
1914 || (cam->vpp_flag & VPP_UPSCALE) ) {
1915 win.x = __UNSC(ax*fw);
1916 win.y = __UNSC(ay*fh);
1917 } else {
1918 win.x = ax;
1919 win.y = ay;
1922 /* Offsets used by the chip */
1923 x = ax + s_win.x;
1924 y = ay + s_win.y;
1926 /* Go ! */
1927 if ((err = w9968cf_sensor_cmd(cam, OVCAMCHIP_CMD_S_MODE, &s_win)))
1928 goto error;
1930 err += w9968cf_write_reg(cam, scx + x, 0x10);
1931 err += w9968cf_write_reg(cam, scy + y, 0x11);
1932 err += w9968cf_write_reg(cam, scx + x + cw, 0x12);
1933 err += w9968cf_write_reg(cam, scy + y + ch, 0x13);
1934 err += w9968cf_write_reg(cam, w, 0x14);
1935 err += w9968cf_write_reg(cam, h, 0x15);
1937 /* JPEG width & height */
1938 err += w9968cf_write_reg(cam, w, 0x30);
1939 err += w9968cf_write_reg(cam, h, 0x31);
1941 /* Y & UV frame buffer strides (in WORD) */
1942 if (cam->vpp_flag & VPP_DECOMPRESSION) {
1943 err += w9968cf_write_reg(cam, w/2, 0x2c);
1944 err += w9968cf_write_reg(cam, w/4, 0x2d);
1945 } else
1946 err += w9968cf_write_reg(cam, w, 0x2c);
1948 if (err)
1949 goto error;
1951 /* If all went well, update the device data structure */
1952 memcpy(&cam->window, &win, sizeof(win));
1953 cam->hw_width = w;
1954 cam->hw_height = h;
1956 /* Settings changed, so we clear the frame buffers */
1957 memset(cam->frame[0].buffer, 0, cam->nbuffers*cam->frame[0].size);
1959 DBG(4, "The capture area is %dx%d, Offset (x,y)=(%u,%u)",
1960 win.width, win.height, win.x, win.y)
1962 PDBGG("x=%u ,y=%u, w=%u, h=%u, ax=%u, ay=%u, s_win.x=%u, s_win.y=%u, "
1963 "cw=%u, ch=%u, win.x=%u, win.y=%u, win.width=%u, win.height=%u",
1964 x, y, w, h, ax, ay, s_win.x, s_win.y, cw, ch, win.x, win.y,
1965 win.width, win.height)
1967 return 0;
1969 error:
1970 DBG(1, "Failed to change the capture area size")
1971 return err;
1975 /*--------------------------------------------------------------------------
1976 Adjust the asked values for window width and height.
1977 Return 0 on success, -1 otherwise.
1978 --------------------------------------------------------------------------*/
1979 static int
1980 w9968cf_adjust_window_size(struct w9968cf_device* cam, u16* width, u16* height)
1982 u16 maxw, maxh;
1984 if ((*width < cam->minwidth) || (*height < cam->minheight))
1985 return -ERANGE;
1987 maxw = cam->upscaling && !(cam->vpp_flag & VPP_DECOMPRESSION) &&
1988 w9968cf_vpp ? max((u16)W9968CF_MAX_WIDTH, cam->maxwidth)
1989 : cam->maxwidth;
1990 maxh = cam->upscaling && !(cam->vpp_flag & VPP_DECOMPRESSION) &&
1991 w9968cf_vpp ? max((u16)W9968CF_MAX_HEIGHT, cam->maxheight)
1992 : cam->maxheight;
1994 if (*width > maxw)
1995 *width = maxw;
1996 if (*height > maxh)
1997 *height = maxh;
1999 if (cam->vpp_flag & VPP_DECOMPRESSION) {
2000 *width &= ~15L; /* multiple of 16 */
2001 *height &= ~15L;
2004 PDBGG("Window size adjusted w=%u, h=%u ", *width, *height)
2006 return 0;
2010 /*--------------------------------------------------------------------------
2011 Initialize the FIFO list of requested frames.
2012 --------------------------------------------------------------------------*/
2013 static void w9968cf_init_framelist(struct w9968cf_device* cam)
2015 u8 i;
2017 for (i = 0; i < cam->nbuffers; i++) {
2018 cam->requested_frame[i] = NULL;
2019 cam->frame[i].queued = 0;
2020 cam->frame[i].status = F_UNUSED;
2025 /*--------------------------------------------------------------------------
2026 Add a frame in the FIFO list of requested frames.
2027 This function is called in process context.
2028 --------------------------------------------------------------------------*/
2029 static void w9968cf_push_frame(struct w9968cf_device* cam, u8 f_num)
2031 u8 f;
2032 unsigned long lock_flags;
2034 spin_lock_irqsave(&cam->flist_lock, lock_flags);
2036 for (f=0; cam->requested_frame[f] != NULL; f++);
2037 cam->requested_frame[f] = &cam->frame[f_num];
2038 cam->frame[f_num].queued = 1;
2039 cam->frame[f_num].status = F_UNUSED; /* clear the status */
2041 spin_unlock_irqrestore(&cam->flist_lock, lock_flags);
2043 DBG(6, "Frame #%u pushed into the FIFO list. Position %u", f_num, f)
2047 /*--------------------------------------------------------------------------
2048 Read, store and remove the first pointer in the FIFO list of requested
2049 frames. This function is called in interrupt context.
2050 --------------------------------------------------------------------------*/
2051 static void
2052 w9968cf_pop_frame(struct w9968cf_device* cam, struct w9968cf_frame_t** framep)
2054 u8 i;
2056 spin_lock(&cam->flist_lock);
2058 *framep = cam->requested_frame[0];
2060 /* Shift the list of pointers */
2061 for (i = 0; i < cam->nbuffers-1; i++)
2062 cam->requested_frame[i] = cam->requested_frame[i+1];
2063 cam->requested_frame[i] = NULL;
2065 spin_unlock(&cam->flist_lock);
2067 DBG(6,"Popped frame #%d from the list", (*framep)->number)
2071 /*--------------------------------------------------------------------------
2072 High-level video post-processing routine on grabbed frames.
2073 Return 0 on success, a negative number otherwise.
2074 --------------------------------------------------------------------------*/
2075 static int
2076 w9968cf_postprocess_frame(struct w9968cf_device* cam,
2077 struct w9968cf_frame_t* fr)
2079 void *pIn = fr->buffer, *pOut = cam->frame_vpp.buffer, *tmp;
2080 u16 w = cam->window.width,
2081 h = cam->window.height,
2082 d = cam->picture.depth,
2083 fmt = cam->picture.palette,
2084 rgb = cam->force_rgb,
2085 hw_w = cam->hw_width,
2086 hw_h = cam->hw_height,
2087 hw_d = cam->hw_depth;
2088 int err = 0;
2090 #define _PSWAP(pIn, pOut) {tmp = (pIn); (pIn) = (pOut); (pOut) = tmp;}
2092 if (cam->vpp_flag & VPP_DECOMPRESSION) {
2093 memcpy(pOut, pIn, fr->length);
2094 _PSWAP(pIn, pOut)
2095 err = w9968cf_vpp->decode(pIn, fr->length, hw_w, hw_h, pOut);
2096 PDBGG("Compressed frame length: %lu",(unsigned long)fr->length)
2097 fr->length = (hw_w*hw_h*hw_d)/8;
2098 _PSWAP(pIn, pOut)
2099 if (err) {
2100 DBG(4, "An error occurred while decoding the frame: "
2101 "%s", symbolic(decoder_errlist, err))
2102 return err;
2103 } else
2104 DBG(6, "Frame decoded")
2107 if (cam->vpp_flag & VPP_SWAP_YUV_BYTES) {
2108 w9968cf_vpp->swap_yuvbytes(pIn, fr->length);
2109 DBG(6, "Original UYVY component ordering changed")
2112 if (cam->vpp_flag & VPP_UPSCALE) {
2113 w9968cf_vpp->scale_up(pIn, pOut, hw_w, hw_h, hw_d, w, h);
2114 fr->length = (w*h*hw_d)/8;
2115 _PSWAP(pIn, pOut)
2116 DBG(6, "Vertical up-scaling done: %u,%u,%ubpp->%u,%u",
2117 hw_w, hw_h, hw_d, w, h)
2120 if (cam->vpp_flag & VPP_UYVY_TO_RGBX) {
2121 w9968cf_vpp->uyvy_to_rgbx(pIn, fr->length, pOut, fmt, rgb);
2122 fr->length = (w*h*d)/8;
2123 _PSWAP(pIn, pOut)
2124 DBG(6, "UYVY-16bit to %s conversion done",
2125 symbolic(v4l1_plist, fmt))
2128 if (pOut == fr->buffer)
2129 memcpy(fr->buffer, cam->frame_vpp.buffer, fr->length);
2131 return 0;
2136 /****************************************************************************
2137 * Image sensor control routines *
2138 ****************************************************************************/
2140 static int
2141 w9968cf_sensor_set_control(struct w9968cf_device* cam, int cid, int val)
2143 struct ovcamchip_control ctl;
2144 int err;
2146 ctl.id = cid;
2147 ctl.value = val;
2149 err = w9968cf_sensor_cmd(cam, OVCAMCHIP_CMD_S_CTRL, &ctl);
2151 return err;
2155 static int
2156 w9968cf_sensor_get_control(struct w9968cf_device* cam, int cid, int* val)
2158 struct ovcamchip_control ctl;
2159 int err;
2161 ctl.id = cid;
2163 err = w9968cf_sensor_cmd(cam, OVCAMCHIP_CMD_G_CTRL, &ctl);
2164 if (!err)
2165 *val = ctl.value;
2167 return err;
2171 static int
2172 w9968cf_sensor_cmd(struct w9968cf_device* cam, unsigned int cmd, void* arg)
2174 struct i2c_client* c = cam->sensor_client;
2175 int rc = 0;
2177 if (!c || !c->driver || !c->driver->command)
2178 return -EINVAL;
2180 rc = c->driver->command(c, cmd, arg);
2181 /* The I2C driver returns -EPERM on non-supported controls */
2182 return (rc < 0 && rc != -EPERM) ? rc : 0;
2186 /*--------------------------------------------------------------------------
2187 Update some settings of the image sensor.
2188 Returns: 0 on success, a negative number otherwise.
2189 --------------------------------------------------------------------------*/
2190 static int w9968cf_sensor_update_settings(struct w9968cf_device* cam)
2192 int err = 0;
2194 /* Auto brightness */
2195 err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_AUTOBRIGHT,
2196 cam->auto_brt);
2197 if (err)
2198 return err;
2200 /* Auto exposure */
2201 err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_AUTOEXP,
2202 cam->auto_exp);
2203 if (err)
2204 return err;
2206 /* Banding filter */
2207 err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_BANDFILT,
2208 cam->bandfilt);
2209 if (err)
2210 return err;
2212 /* Light frequency */
2213 err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_FREQ,
2214 cam->lightfreq);
2215 if (err)
2216 return err;
2218 /* Back light */
2219 err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_BACKLIGHT,
2220 cam->backlight);
2221 if (err)
2222 return err;
2224 /* Mirror */
2225 err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_MIRROR,
2226 cam->mirror);
2227 if (err)
2228 return err;
2230 return 0;
2234 /*--------------------------------------------------------------------------
2235 Get some current picture settings from the image sensor and update the
2236 internal 'picture' structure of the camera.
2237 Returns: 0 on success, a negative number otherwise.
2238 --------------------------------------------------------------------------*/
2239 static int w9968cf_sensor_get_picture(struct w9968cf_device* cam)
2241 int err, v;
2243 err = w9968cf_sensor_get_control(cam, OVCAMCHIP_CID_CONT, &v);
2244 if (err)
2245 return err;
2246 cam->picture.contrast = v;
2248 err = w9968cf_sensor_get_control(cam, OVCAMCHIP_CID_BRIGHT, &v);
2249 if (err)
2250 return err;
2251 cam->picture.brightness = v;
2253 err = w9968cf_sensor_get_control(cam, OVCAMCHIP_CID_SAT, &v);
2254 if (err)
2255 return err;
2256 cam->picture.colour = v;
2258 err = w9968cf_sensor_get_control(cam, OVCAMCHIP_CID_HUE, &v);
2259 if (err)
2260 return err;
2261 cam->picture.hue = v;
2263 DBG(5, "Got picture settings from the image sensor")
2265 PDBGG("Brightness, contrast, hue, colour, whiteness are "
2266 "%u,%u,%u,%u,%u", cam->picture.brightness,cam->picture.contrast,
2267 cam->picture.hue, cam->picture.colour, cam->picture.whiteness)
2269 return 0;
2273 /*--------------------------------------------------------------------------
2274 Update picture settings of the image sensor.
2275 Returns: 0 on success, a negative number otherwise.
2276 --------------------------------------------------------------------------*/
2277 static int
2278 w9968cf_sensor_update_picture(struct w9968cf_device* cam,
2279 struct video_picture pict)
2281 int err = 0;
2283 if ((!cam->sensor_initialized)
2284 || pict.contrast != cam->picture.contrast) {
2285 err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_CONT,
2286 pict.contrast);
2287 if (err)
2288 goto fail;
2289 DBG(4, "Contrast changed from %u to %u",
2290 cam->picture.contrast, pict.contrast)
2291 cam->picture.contrast = pict.contrast;
2294 if (((!cam->sensor_initialized) ||
2295 pict.brightness != cam->picture.brightness) && (!cam->auto_brt)) {
2296 err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_BRIGHT,
2297 pict.brightness);
2298 if (err)
2299 goto fail;
2300 DBG(4, "Brightness changed from %u to %u",
2301 cam->picture.brightness, pict.brightness)
2302 cam->picture.brightness = pict.brightness;
2305 if ((!cam->sensor_initialized) || pict.colour != cam->picture.colour) {
2306 err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_SAT,
2307 pict.colour);
2308 if (err)
2309 goto fail;
2310 DBG(4, "Colour changed from %u to %u",
2311 cam->picture.colour, pict.colour)
2312 cam->picture.colour = pict.colour;
2315 if ((!cam->sensor_initialized) || pict.hue != cam->picture.hue) {
2316 err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_HUE,
2317 pict.hue);
2318 if (err)
2319 goto fail;
2320 DBG(4, "Hue changed from %u to %u",
2321 cam->picture.hue, pict.hue)
2322 cam->picture.hue = pict.hue;
2325 return 0;
2327 fail:
2328 DBG(4, "Failed to change sensor picture setting")
2329 return err;
2334 /****************************************************************************
2335 * Camera configuration *
2336 ****************************************************************************/
2338 /*--------------------------------------------------------------------------
2339 This function is called when a supported image sensor is detected.
2340 Return 0 if the initialization succeeds, a negative number otherwise.
2341 --------------------------------------------------------------------------*/
2342 static int w9968cf_sensor_init(struct w9968cf_device* cam)
2344 int err = 0;
2346 if ((err = w9968cf_sensor_cmd(cam, OVCAMCHIP_CMD_INITIALIZE,
2347 &cam->monochrome)))
2348 goto error;
2350 if ((err = w9968cf_sensor_cmd(cam, OVCAMCHIP_CMD_Q_SUBTYPE,
2351 &cam->sensor)))
2352 goto error;
2354 /* NOTE: Make sure width and height are a multiple of 16 */
2355 switch (cam->sensor_client->addr) {
2356 case OV6xx0_SID:
2357 cam->maxwidth = 352;
2358 cam->maxheight = 288;
2359 cam->minwidth = 64;
2360 cam->minheight = 48;
2361 break;
2362 case OV7xx0_SID:
2363 cam->maxwidth = 640;
2364 cam->maxheight = 480;
2365 cam->minwidth = 64;
2366 cam->minheight = 48;
2367 break;
2368 default:
2369 DBG(1, "Not supported image sensor detected for %s",
2370 symbolic(camlist, cam->id))
2371 return -EINVAL;
2374 /* These values depend on the ones in the ovxxx0.c sources */
2375 switch (cam->sensor) {
2376 case CC_OV7620:
2377 cam->start_cropx = 287;
2378 cam->start_cropy = 35;
2379 /* Seems to work around a bug in the image sensor */
2380 cam->vs_polarity = 1;
2381 cam->hs_polarity = 1;
2382 break;
2383 default:
2384 cam->start_cropx = 320;
2385 cam->start_cropy = 35;
2386 cam->vs_polarity = 1;
2387 cam->hs_polarity = 0;
2390 if ((err = w9968cf_sensor_update_settings(cam)))
2391 goto error;
2393 if ((err = w9968cf_sensor_update_picture(cam, cam->picture)))
2394 goto error;
2396 cam->sensor_initialized = 1;
2398 DBG(2, "%s image sensor initialized", symbolic(senlist, cam->sensor))
2399 return 0;
2401 error:
2402 cam->sensor_initialized = 0;
2403 cam->sensor = CC_UNKNOWN;
2404 DBG(1, "Image sensor initialization failed for %s (/dev/video%d). "
2405 "Try to detach and attach this device again",
2406 symbolic(camlist, cam->id), cam->v4ldev->minor)
2407 return err;
2411 /*--------------------------------------------------------------------------
2412 Fill some basic fields in the main device data structure.
2413 This function is called once on w9968cf_usb_probe() for each recognized
2414 camera.
2415 --------------------------------------------------------------------------*/
2416 static void
2417 w9968cf_configure_camera(struct w9968cf_device* cam,
2418 struct usb_device* udev,
2419 enum w9968cf_model_id mod_id,
2420 const unsigned short dev_nr)
2422 init_MUTEX(&cam->fileop_sem);
2423 init_waitqueue_head(&cam->open);
2424 spin_lock_init(&cam->urb_lock);
2425 spin_lock_init(&cam->flist_lock);
2427 cam->users = 0;
2428 cam->disconnected = 0;
2429 cam->id = mod_id;
2430 cam->sensor = CC_UNKNOWN;
2431 cam->sensor_initialized = 0;
2433 /* Calculate the alternate setting number (from 1 to 16)
2434 according to the 'packet_size' module parameter */
2435 if (packet_size[dev_nr] < W9968CF_MIN_PACKET_SIZE)
2436 packet_size[dev_nr] = W9968CF_MIN_PACKET_SIZE;
2437 for (cam->altsetting = 1;
2438 packet_size[dev_nr] < wMaxPacketSize[cam->altsetting-1];
2439 cam->altsetting++);
2441 cam->max_buffers = (max_buffers[dev_nr] < 2 ||
2442 max_buffers[dev_nr] > W9968CF_MAX_BUFFERS)
2443 ? W9968CF_BUFFERS : (u8)max_buffers[dev_nr];
2445 cam->double_buffer = (double_buffer[dev_nr] == 0 ||
2446 double_buffer[dev_nr] == 1)
2447 ? (u8)double_buffer[dev_nr]:W9968CF_DOUBLE_BUFFER;
2449 cam->clamping = (clamping[dev_nr] == 0 || clamping[dev_nr] == 1)
2450 ? (u8)clamping[dev_nr] : W9968CF_CLAMPING;
2452 cam->filter_type = (filter_type[dev_nr] == 0 ||
2453 filter_type[dev_nr] == 1 ||
2454 filter_type[dev_nr] == 2)
2455 ? (u8)filter_type[dev_nr] : W9968CF_FILTER_TYPE;
2457 cam->capture = 1;
2459 cam->largeview = (largeview[dev_nr] == 0 || largeview[dev_nr] == 1)
2460 ? (u8)largeview[dev_nr] : W9968CF_LARGEVIEW;
2462 cam->decompression = (decompression[dev_nr] == 0 ||
2463 decompression[dev_nr] == 1 ||
2464 decompression[dev_nr] == 2)
2465 ? (u8)decompression[dev_nr]:W9968CF_DECOMPRESSION;
2467 cam->upscaling = (upscaling[dev_nr] == 0 ||
2468 upscaling[dev_nr] == 1)
2469 ? (u8)upscaling[dev_nr] : W9968CF_UPSCALING;
2471 cam->auto_brt = (autobright[dev_nr] == 0 || autobright[dev_nr] == 1)
2472 ? (u8)autobright[dev_nr] : W9968CF_AUTOBRIGHT;
2474 cam->auto_exp = (autoexp[dev_nr] == 0 || autoexp[dev_nr] == 1)
2475 ? (u8)autoexp[dev_nr] : W9968CF_AUTOEXP;
2477 cam->lightfreq = (lightfreq[dev_nr] == 50 || lightfreq[dev_nr] == 60)
2478 ? (u8)lightfreq[dev_nr] : W9968CF_LIGHTFREQ;
2480 cam->bandfilt = (bandingfilter[dev_nr] == 0 ||
2481 bandingfilter[dev_nr] == 1)
2482 ? (u8)bandingfilter[dev_nr] : W9968CF_BANDINGFILTER;
2484 cam->backlight = (backlight[dev_nr] == 0 || backlight[dev_nr] == 1)
2485 ? (u8)backlight[dev_nr] : W9968CF_BACKLIGHT;
2487 cam->clockdiv = (clockdiv[dev_nr] == -1 || clockdiv[dev_nr] >= 0)
2488 ? (s8)clockdiv[dev_nr] : W9968CF_CLOCKDIV;
2490 cam->mirror = (mirror[dev_nr] == 0 || mirror[dev_nr] == 1)
2491 ? (u8)mirror[dev_nr] : W9968CF_MIRROR;
2493 cam->monochrome = (monochrome[dev_nr] == 0 || monochrome[dev_nr] == 1)
2494 ? monochrome[dev_nr] : W9968CF_MONOCHROME;
2496 cam->picture.brightness = (u16)brightness[dev_nr];
2497 cam->picture.hue = (u16)hue[dev_nr];
2498 cam->picture.colour = (u16)colour[dev_nr];
2499 cam->picture.contrast = (u16)contrast[dev_nr];
2500 cam->picture.whiteness = (u16)whiteness[dev_nr];
2501 if (w9968cf_valid_palette((u16)force_palette[dev_nr])) {
2502 cam->picture.palette = (u16)force_palette[dev_nr];
2503 cam->force_palette = 1;
2504 } else {
2505 cam->force_palette = 0;
2506 if (cam->decompression == 0)
2507 cam->picture.palette = W9968CF_PALETTE_DECOMP_OFF;
2508 else if (cam->decompression == 1)
2509 cam->picture.palette = W9968CF_PALETTE_DECOMP_FORCE;
2510 else
2511 cam->picture.palette = W9968CF_PALETTE_DECOMP_ON;
2513 cam->picture.depth = w9968cf_valid_depth(cam->picture.palette);
2515 cam->force_rgb = (force_rgb[dev_nr] == 0 || force_rgb[dev_nr] == 1)
2516 ? (u8)force_rgb[dev_nr] : W9968CF_FORCE_RGB;
2518 cam->window.x = 0;
2519 cam->window.y = 0;
2520 cam->window.width = W9968CF_WIDTH;
2521 cam->window.height = W9968CF_HEIGHT;
2522 cam->window.chromakey = 0;
2523 cam->window.clipcount = 0;
2524 cam->window.flags = 0;
2526 DBG(3, "%s configured with settings #%u:",
2527 symbolic(camlist, cam->id), dev_nr)
2529 DBG(3, "- Data packet size for USB isochrnous transfer: %u bytes",
2530 wMaxPacketSize[cam->altsetting-1])
2532 DBG(3, "- Number of requested video frame buffers: %u",
2533 cam->max_buffers)
2535 if (cam->double_buffer)
2536 DBG(3, "- Hardware double buffering enabled")
2537 else
2538 DBG(3, "- Hardware double buffering disabled")
2540 if (cam->filter_type == 0)
2541 DBG(3, "- Video filtering disabled")
2542 else if (cam->filter_type == 1)
2543 DBG(3, "- Video filtering enabled: type 1-2-1")
2544 else if (cam->filter_type == 2)
2545 DBG(3, "- Video filtering enabled: type 2-3-6-3-2")
2547 if (cam->clamping)
2548 DBG(3, "- Video data clamping (CCIR-601 format) enabled")
2549 else
2550 DBG(3, "- Video data clamping (CCIR-601 format) disabled")
2552 if (cam->largeview)
2553 DBG(3, "- Large view enabled")
2554 else
2555 DBG(3, "- Large view disabled")
2557 if ((cam->decompression) == 0 && (!cam->force_palette))
2558 DBG(3, "- Decompression disabled")
2559 else if ((cam->decompression) == 1 && (!cam->force_palette))
2560 DBG(3, "- Decompression forced")
2561 else if ((cam->decompression) == 2 && (!cam->force_palette))
2562 DBG(3, "- Decompression allowed")
2564 if (cam->upscaling)
2565 DBG(3, "- Software image scaling enabled")
2566 else
2567 DBG(3, "- Software image scaling disabled")
2569 if (cam->force_palette)
2570 DBG(3, "- Image palette forced to %s",
2571 symbolic(v4l1_plist, cam->picture.palette))
2573 if (cam->force_rgb)
2574 DBG(3, "- RGB component ordering will be used instead of BGR")
2576 if (cam->auto_brt)
2577 DBG(3, "- Auto brightness enabled")
2578 else
2579 DBG(3, "- Auto brightness disabled")
2581 if (cam->auto_exp)
2582 DBG(3, "- Auto exposure enabled")
2583 else
2584 DBG(3, "- Auto exposure disabled")
2586 if (cam->backlight)
2587 DBG(3, "- Backlight exposure algorithm enabled")
2588 else
2589 DBG(3, "- Backlight exposure algorithm disabled")
2591 if (cam->mirror)
2592 DBG(3, "- Mirror enabled")
2593 else
2594 DBG(3, "- Mirror disabled")
2596 if (cam->bandfilt)
2597 DBG(3, "- Banding filter enabled")
2598 else
2599 DBG(3, "- Banding filter disabled")
2601 DBG(3, "- Power lighting frequency: %u", cam->lightfreq)
2603 if (cam->clockdiv == -1)
2604 DBG(3, "- Automatic clock divisor enabled")
2605 else
2606 DBG(3, "- Clock divisor: %d", cam->clockdiv)
2608 if (cam->monochrome)
2609 DBG(3, "- Image sensor used as monochrome")
2610 else
2611 DBG(3, "- Image sensor not used as monochrome")
2615 /*--------------------------------------------------------------------------
2616 If the video post-processing module is not loaded, some parameters
2617 must be overridden.
2618 --------------------------------------------------------------------------*/
2619 static void w9968cf_adjust_configuration(struct w9968cf_device* cam)
2621 if (!w9968cf_vpp) {
2622 if (cam->decompression == 1) {
2623 cam->decompression = 2;
2624 DBG(2, "Video post-processing module not found: "
2625 "'decompression' parameter forced to 2")
2627 if (cam->upscaling) {
2628 cam->upscaling = 0;
2629 DBG(2, "Video post-processing module not found: "
2630 "'upscaling' parameter forced to 0")
2632 if (cam->picture.palette != VIDEO_PALETTE_UYVY) {
2633 cam->force_palette = 0;
2634 DBG(2, "Video post-processing module not found: "
2635 "'force_palette' parameter forced to 0")
2637 cam->picture.palette = VIDEO_PALETTE_UYVY;
2638 cam->picture.depth = w9968cf_valid_depth(cam->picture.palette);
2643 /*--------------------------------------------------------------------------
2644 Release the resources used by the driver.
2645 This function is called on disconnect
2646 (or on close if deallocation has been deferred)
2647 --------------------------------------------------------------------------*/
2648 static void w9968cf_release_resources(struct w9968cf_device* cam)
2650 down(&w9968cf_devlist_sem);
2652 DBG(2, "V4L device deregistered: /dev/video%d", cam->v4ldev->minor)
2654 video_unregister_device(cam->v4ldev);
2655 list_del(&cam->v4llist);
2656 i2c_del_adapter(&cam->i2c_adapter);
2657 w9968cf_deallocate_memory(cam);
2658 kfree(cam->control_buffer);
2659 kfree(cam->data_buffer);
2661 up(&w9968cf_devlist_sem);
2666 /****************************************************************************
2667 * Video4Linux interface *
2668 ****************************************************************************/
2670 static int w9968cf_open(struct inode* inode, struct file* filp)
2672 struct w9968cf_device* cam;
2673 int err;
2675 /* This the only safe way to prevent race conditions with disconnect */
2676 if (!down_read_trylock(&w9968cf_disconnect))
2677 return -ERESTARTSYS;
2679 cam = (struct w9968cf_device*)video_get_drvdata(video_devdata(filp));
2681 down(&cam->dev_sem);
2683 if (cam->sensor == CC_UNKNOWN) {
2684 DBG(2, "No supported image sensor has been detected by the "
2685 "'ovcamchip' module for the %s (/dev/video%d). Make "
2686 "sure it is loaded *before* (re)connecting the camera.",
2687 symbolic(camlist, cam->id), cam->v4ldev->minor)
2688 up(&cam->dev_sem);
2689 up_read(&w9968cf_disconnect);
2690 return -ENODEV;
2693 if (cam->users) {
2694 DBG(2, "%s (/dev/video%d) has been already occupied by '%s'",
2695 symbolic(camlist, cam->id),cam->v4ldev->minor,cam->command)
2696 if ((filp->f_flags & O_NONBLOCK)||(filp->f_flags & O_NDELAY)) {
2697 up(&cam->dev_sem);
2698 up_read(&w9968cf_disconnect);
2699 return -EWOULDBLOCK;
2701 up(&cam->dev_sem);
2702 err = wait_event_interruptible_exclusive(cam->open,
2703 cam->disconnected ||
2704 !cam->users);
2705 if (err) {
2706 up_read(&w9968cf_disconnect);
2707 return err;
2709 if (cam->disconnected) {
2710 up_read(&w9968cf_disconnect);
2711 return -ENODEV;
2713 down(&cam->dev_sem);
2716 DBG(5, "Opening '%s', /dev/video%d ...",
2717 symbolic(camlist, cam->id), cam->v4ldev->minor)
2719 cam->streaming = 0;
2720 cam->misconfigured = 0;
2722 w9968cf_adjust_configuration(cam);
2724 if ((err = w9968cf_allocate_memory(cam)))
2725 goto deallocate_memory;
2727 if ((err = w9968cf_init_chip(cam)))
2728 goto deallocate_memory;
2730 if ((err = w9968cf_start_transfer(cam)))
2731 goto deallocate_memory;
2733 filp->private_data = cam;
2735 cam->users++;
2736 strcpy(cam->command, current->comm);
2738 init_waitqueue_head(&cam->wait_queue);
2740 DBG(5, "Video device is open")
2742 up(&cam->dev_sem);
2743 up_read(&w9968cf_disconnect);
2745 return 0;
2747 deallocate_memory:
2748 w9968cf_deallocate_memory(cam);
2749 DBG(2, "Failed to open the video device")
2750 up(&cam->dev_sem);
2751 up_read(&w9968cf_disconnect);
2752 return err;
2756 static int w9968cf_release(struct inode* inode, struct file* filp)
2758 struct w9968cf_device* cam;
2760 cam = (struct w9968cf_device*)video_get_drvdata(video_devdata(filp));
2762 down(&cam->dev_sem); /* prevent disconnect() to be called */
2764 w9968cf_stop_transfer(cam);
2766 if (cam->disconnected) {
2767 w9968cf_release_resources(cam);
2768 up(&cam->dev_sem);
2769 kfree(cam);
2770 return 0;
2773 cam->users--;
2774 w9968cf_deallocate_memory(cam);
2775 wake_up_interruptible_nr(&cam->open, 1);
2777 DBG(5, "Video device closed")
2778 up(&cam->dev_sem);
2779 return 0;
2783 static ssize_t
2784 w9968cf_read(struct file* filp, char __user * buf, size_t count, loff_t* f_pos)
2786 struct w9968cf_device* cam;
2787 struct w9968cf_frame_t* fr;
2788 int err = 0;
2790 cam = (struct w9968cf_device*)video_get_drvdata(video_devdata(filp));
2792 if (filp->f_flags & O_NONBLOCK)
2793 return -EWOULDBLOCK;
2795 if (down_interruptible(&cam->fileop_sem))
2796 return -ERESTARTSYS;
2798 if (cam->disconnected) {
2799 DBG(2, "Device not present")
2800 up(&cam->fileop_sem);
2801 return -ENODEV;
2804 if (cam->misconfigured) {
2805 DBG(2, "The camera is misconfigured. Close and open it again.")
2806 up(&cam->fileop_sem);
2807 return -EIO;
2810 if (!cam->frame[0].queued)
2811 w9968cf_push_frame(cam, 0);
2813 if (!cam->frame[1].queued)
2814 w9968cf_push_frame(cam, 1);
2816 err = wait_event_interruptible(cam->wait_queue,
2817 cam->frame[0].status == F_READY ||
2818 cam->frame[1].status == F_READY ||
2819 cam->disconnected);
2820 if (err) {
2821 up(&cam->fileop_sem);
2822 return err;
2824 if (cam->disconnected) {
2825 up(&cam->fileop_sem);
2826 return -ENODEV;
2829 fr = (cam->frame[0].status == F_READY) ? &cam->frame[0]:&cam->frame[1];
2831 if (w9968cf_vpp)
2832 w9968cf_postprocess_frame(cam, fr);
2834 if (count > fr->length)
2835 count = fr->length;
2837 if (copy_to_user(buf, fr->buffer, count)) {
2838 fr->status = F_UNUSED;
2839 up(&cam->fileop_sem);
2840 return -EFAULT;
2842 *f_pos += count;
2844 fr->status = F_UNUSED;
2846 DBG(5, "%zu bytes read", count)
2848 up(&cam->fileop_sem);
2849 return count;
2853 static int w9968cf_mmap(struct file* filp, struct vm_area_struct *vma)
2855 struct w9968cf_device* cam = (struct w9968cf_device*)
2856 video_get_drvdata(video_devdata(filp));
2857 unsigned long vsize = vma->vm_end - vma->vm_start,
2858 psize = cam->nbuffers * cam->frame[0].size,
2859 start = vma->vm_start,
2860 pos = (unsigned long)cam->frame[0].buffer,
2861 page;
2863 if (cam->disconnected) {
2864 DBG(2, "Device not present")
2865 return -ENODEV;
2868 if (cam->misconfigured) {
2869 DBG(2, "The camera is misconfigured. Close and open it again")
2870 return -EIO;
2873 PDBGG("mmapping %lu bytes...", vsize)
2875 if (vsize > psize - (vma->vm_pgoff << PAGE_SHIFT))
2876 return -EINVAL;
2878 while (vsize > 0) {
2879 page = vmalloc_to_pfn((void *)pos);
2880 if (remap_pfn_range(vma, start, page + vma->vm_pgoff,
2881 PAGE_SIZE, vma->vm_page_prot))
2882 return -EAGAIN;
2883 start += PAGE_SIZE;
2884 pos += PAGE_SIZE;
2885 vsize -= PAGE_SIZE;
2888 DBG(5, "mmap method successfully called")
2889 return 0;
2893 static int
2894 w9968cf_ioctl(struct inode* inode, struct file* filp,
2895 unsigned int cmd, unsigned long arg)
2897 struct w9968cf_device* cam;
2898 int err;
2900 cam = (struct w9968cf_device*)video_get_drvdata(video_devdata(filp));
2902 if (down_interruptible(&cam->fileop_sem))
2903 return -ERESTARTSYS;
2905 if (cam->disconnected) {
2906 DBG(2, "Device not present")
2907 up(&cam->fileop_sem);
2908 return -ENODEV;
2911 if (cam->misconfigured) {
2912 DBG(2, "The camera is misconfigured. Close and open it again.")
2913 up(&cam->fileop_sem);
2914 return -EIO;
2917 err = w9968cf_v4l_ioctl(inode, filp, cmd, (void __user *)arg);
2919 up(&cam->fileop_sem);
2920 return err;
2924 static int w9968cf_v4l_ioctl(struct inode* inode, struct file* filp,
2925 unsigned int cmd, void __user * arg)
2927 struct w9968cf_device* cam;
2928 const char* v4l1_ioctls[] = {
2929 "?", "CGAP", "GCHAN", "SCHAN", "GTUNER", "STUNER",
2930 "GPICT", "SPICT", "CCAPTURE", "GWIN", "SWIN", "GFBUF",
2931 "SFBUF", "KEY", "GFREQ", "SFREQ", "GAUDIO", "SAUDIO",
2932 "SYNC", "MCAPTURE", "GMBUF", "GUNIT", "GCAPTURE", "SCAPTURE",
2933 "SPLAYMODE", "SWRITEMODE", "GPLAYINFO", "SMICROCODE",
2934 "GVBIFMT", "SVBIFMT"
2937 #define V4L1_IOCTL(cmd) \
2938 ((_IOC_NR((cmd)) < ARRAY_SIZE(v4l1_ioctls)) ? \
2939 v4l1_ioctls[_IOC_NR((cmd))] : "?")
2941 cam = (struct w9968cf_device*)video_get_drvdata(video_devdata(filp));
2943 switch (cmd) {
2945 case VIDIOCGCAP: /* get video capability */
2947 struct video_capability cap = {
2948 .type = VID_TYPE_CAPTURE | VID_TYPE_SCALES,
2949 .channels = 1,
2950 .audios = 0,
2951 .minwidth = cam->minwidth,
2952 .minheight = cam->minheight,
2954 sprintf(cap.name, "W996[87]CF USB Camera #%d",
2955 cam->v4ldev->minor);
2956 cap.maxwidth = (cam->upscaling && w9968cf_vpp)
2957 ? max((u16)W9968CF_MAX_WIDTH, cam->maxwidth)
2958 : cam->maxwidth;
2959 cap.maxheight = (cam->upscaling && w9968cf_vpp)
2960 ? max((u16)W9968CF_MAX_HEIGHT, cam->maxheight)
2961 : cam->maxheight;
2963 if (copy_to_user(arg, &cap, sizeof(cap)))
2964 return -EFAULT;
2966 DBG(5, "VIDIOCGCAP successfully called")
2967 return 0;
2970 case VIDIOCGCHAN: /* get video channel informations */
2972 struct video_channel chan;
2973 if (copy_from_user(&chan, arg, sizeof(chan)))
2974 return -EFAULT;
2976 if (chan.channel != 0)
2977 return -EINVAL;
2979 strcpy(chan.name, "Camera");
2980 chan.tuners = 0;
2981 chan.flags = 0;
2982 chan.type = VIDEO_TYPE_CAMERA;
2983 chan.norm = VIDEO_MODE_AUTO;
2985 if (copy_to_user(arg, &chan, sizeof(chan)))
2986 return -EFAULT;
2988 DBG(5, "VIDIOCGCHAN successfully called")
2989 return 0;
2992 case VIDIOCSCHAN: /* set active channel */
2994 struct video_channel chan;
2996 if (copy_from_user(&chan, arg, sizeof(chan)))
2997 return -EFAULT;
2999 if (chan.channel != 0)
3000 return -EINVAL;
3002 DBG(5, "VIDIOCSCHAN successfully called")
3003 return 0;
3006 case VIDIOCGPICT: /* get image properties of the picture */
3008 if (w9968cf_sensor_get_picture(cam))
3009 return -EIO;
3011 if (copy_to_user(arg, &cam->picture, sizeof(cam->picture)))
3012 return -EFAULT;
3014 DBG(5, "VIDIOCGPICT successfully called")
3015 return 0;
3018 case VIDIOCSPICT: /* change picture settings */
3020 struct video_picture pict;
3021 int err = 0;
3023 if (copy_from_user(&pict, arg, sizeof(pict)))
3024 return -EFAULT;
3026 if ( (cam->force_palette || !w9968cf_vpp)
3027 && pict.palette != cam->picture.palette ) {
3028 DBG(4, "Palette %s rejected: only %s is allowed",
3029 symbolic(v4l1_plist, pict.palette),
3030 symbolic(v4l1_plist, cam->picture.palette))
3031 return -EINVAL;
3034 if (!w9968cf_valid_palette(pict.palette)) {
3035 DBG(4, "Palette %s not supported. VIDIOCSPICT failed",
3036 symbolic(v4l1_plist, pict.palette))
3037 return -EINVAL;
3040 if (!cam->force_palette) {
3041 if (cam->decompression == 0) {
3042 if (w9968cf_need_decompression(pict.palette)) {
3043 DBG(4, "Decompression disabled: palette %s is not "
3044 "allowed. VIDIOCSPICT failed",
3045 symbolic(v4l1_plist, pict.palette))
3046 return -EINVAL;
3048 } else if (cam->decompression == 1) {
3049 if (!w9968cf_need_decompression(pict.palette)) {
3050 DBG(4, "Decompression forced: palette %s is not "
3051 "allowed. VIDIOCSPICT failed",
3052 symbolic(v4l1_plist, pict.palette))
3053 return -EINVAL;
3058 if (pict.depth != w9968cf_valid_depth(pict.palette)) {
3059 DBG(4, "Requested depth %u bpp is not valid for %s "
3060 "palette: ignored and changed to %u bpp",
3061 pict.depth, symbolic(v4l1_plist, pict.palette),
3062 w9968cf_valid_depth(pict.palette))
3063 pict.depth = w9968cf_valid_depth(pict.palette);
3066 if (pict.palette != cam->picture.palette) {
3067 if(*cam->requested_frame
3068 || cam->frame_current->queued) {
3069 err = wait_event_interruptible
3070 ( cam->wait_queue,
3071 cam->disconnected ||
3072 (!*cam->requested_frame &&
3073 !cam->frame_current->queued) );
3074 if (err)
3075 return err;
3076 if (cam->disconnected)
3077 return -ENODEV;
3080 if (w9968cf_stop_transfer(cam))
3081 goto ioctl_fail;
3083 if (w9968cf_set_picture(cam, pict))
3084 goto ioctl_fail;
3086 if (w9968cf_start_transfer(cam))
3087 goto ioctl_fail;
3089 } else if (w9968cf_sensor_update_picture(cam, pict))
3090 return -EIO;
3093 DBG(5, "VIDIOCSPICT successfully called")
3094 return 0;
3097 case VIDIOCSWIN: /* set capture area */
3099 struct video_window win;
3100 int err = 0;
3102 if (copy_from_user(&win, arg, sizeof(win)))
3103 return -EFAULT;
3105 DBG(6, "VIDIOCSWIN called: clipcount=%d, flags=%u, "
3106 "x=%u, y=%u, %ux%u", win.clipcount, win.flags,
3107 win.x, win.y, win.width, win.height)
3109 if (win.clipcount != 0 || win.flags != 0)
3110 return -EINVAL;
3112 if ((err = w9968cf_adjust_window_size(cam, (u16*)&win.width,
3113 (u16*)&win.height))) {
3114 DBG(4, "Resolution not supported (%ux%u). "
3115 "VIDIOCSWIN failed", win.width, win.height)
3116 return err;
3119 if (win.x != cam->window.x ||
3120 win.y != cam->window.y ||
3121 win.width != cam->window.width ||
3122 win.height != cam->window.height) {
3123 if(*cam->requested_frame
3124 || cam->frame_current->queued) {
3125 err = wait_event_interruptible
3126 ( cam->wait_queue,
3127 cam->disconnected ||
3128 (!*cam->requested_frame &&
3129 !cam->frame_current->queued) );
3130 if (err)
3131 return err;
3132 if (cam->disconnected)
3133 return -ENODEV;
3136 if (w9968cf_stop_transfer(cam))
3137 goto ioctl_fail;
3139 /* This _must_ be called before set_window() */
3140 if (w9968cf_set_picture(cam, cam->picture))
3141 goto ioctl_fail;
3143 if (w9968cf_set_window(cam, win))
3144 goto ioctl_fail;
3146 if (w9968cf_start_transfer(cam))
3147 goto ioctl_fail;
3150 DBG(5, "VIDIOCSWIN successfully called. ")
3151 return 0;
3154 case VIDIOCGWIN: /* get current window properties */
3156 if (copy_to_user(arg,&cam->window,sizeof(struct video_window)))
3157 return -EFAULT;
3159 DBG(5, "VIDIOCGWIN successfully called")
3160 return 0;
3163 case VIDIOCGMBUF: /* request for memory (mapped) buffer */
3165 struct video_mbuf mbuf;
3166 u8 i;
3168 mbuf.size = cam->nbuffers * cam->frame[0].size;
3169 mbuf.frames = cam->nbuffers;
3170 for (i = 0; i < cam->nbuffers; i++)
3171 mbuf.offsets[i] = (unsigned long)cam->frame[i].buffer -
3172 (unsigned long)cam->frame[0].buffer;
3174 if (copy_to_user(arg, &mbuf, sizeof(mbuf)))
3175 return -EFAULT;
3177 DBG(5, "VIDIOCGMBUF successfully called")
3178 return 0;
3181 case VIDIOCMCAPTURE: /* start the capture to a frame */
3183 struct video_mmap mmap;
3184 struct w9968cf_frame_t* fr;
3185 int err = 0;
3187 if (copy_from_user(&mmap, arg, sizeof(mmap)))
3188 return -EFAULT;
3190 DBG(6, "VIDIOCMCAPTURE called: frame #%u, format=%s, %dx%d",
3191 mmap.frame, symbolic(v4l1_plist, mmap.format),
3192 mmap.width, mmap.height)
3194 if (mmap.frame >= cam->nbuffers) {
3195 DBG(4, "Invalid frame number (%u). "
3196 "VIDIOCMCAPTURE failed", mmap.frame)
3197 return -EINVAL;
3200 if (mmap.format!=cam->picture.palette &&
3201 (cam->force_palette || !w9968cf_vpp)) {
3202 DBG(4, "Palette %s rejected: only %s is allowed",
3203 symbolic(v4l1_plist, mmap.format),
3204 symbolic(v4l1_plist, cam->picture.palette))
3205 return -EINVAL;
3208 if (!w9968cf_valid_palette(mmap.format)) {
3209 DBG(4, "Palette %s not supported. "
3210 "VIDIOCMCAPTURE failed",
3211 symbolic(v4l1_plist, mmap.format))
3212 return -EINVAL;
3215 if (!cam->force_palette) {
3216 if (cam->decompression == 0) {
3217 if (w9968cf_need_decompression(mmap.format)) {
3218 DBG(4, "Decompression disabled: palette %s is not "
3219 "allowed. VIDIOCSPICT failed",
3220 symbolic(v4l1_plist, mmap.format))
3221 return -EINVAL;
3223 } else if (cam->decompression == 1) {
3224 if (!w9968cf_need_decompression(mmap.format)) {
3225 DBG(4, "Decompression forced: palette %s is not "
3226 "allowed. VIDIOCSPICT failed",
3227 symbolic(v4l1_plist, mmap.format))
3228 return -EINVAL;
3233 if ((err = w9968cf_adjust_window_size(cam, (u16*)&mmap.width,
3234 (u16*)&mmap.height))) {
3235 DBG(4, "Resolution not supported (%dx%d). "
3236 "VIDIOCMCAPTURE failed",
3237 mmap.width, mmap.height)
3238 return err;
3241 fr = &cam->frame[mmap.frame];
3243 if (mmap.width != cam->window.width ||
3244 mmap.height != cam->window.height ||
3245 mmap.format != cam->picture.palette) {
3247 struct video_window win;
3248 struct video_picture pict;
3250 if(*cam->requested_frame
3251 || cam->frame_current->queued) {
3252 DBG(6, "VIDIOCMCAPTURE. Change settings for "
3253 "frame #%u: %dx%d, format %s. Wait...",
3254 mmap.frame, mmap.width, mmap.height,
3255 symbolic(v4l1_plist, mmap.format))
3256 err = wait_event_interruptible
3257 ( cam->wait_queue,
3258 cam->disconnected ||
3259 (!*cam->requested_frame &&
3260 !cam->frame_current->queued) );
3261 if (err)
3262 return err;
3263 if (cam->disconnected)
3264 return -ENODEV;
3267 memcpy(&win, &cam->window, sizeof(win));
3268 memcpy(&pict, &cam->picture, sizeof(pict));
3269 win.width = mmap.width;
3270 win.height = mmap.height;
3271 pict.palette = mmap.format;
3273 if (w9968cf_stop_transfer(cam))
3274 goto ioctl_fail;
3276 /* This before set_window */
3277 if (w9968cf_set_picture(cam, pict))
3278 goto ioctl_fail;
3280 if (w9968cf_set_window(cam, win))
3281 goto ioctl_fail;
3283 if (w9968cf_start_transfer(cam))
3284 goto ioctl_fail;
3286 } else if (fr->queued) {
3288 DBG(6, "Wait until frame #%u is free", mmap.frame)
3290 err = wait_event_interruptible(cam->wait_queue,
3291 cam->disconnected ||
3292 (!fr->queued));
3293 if (err)
3294 return err;
3295 if (cam->disconnected)
3296 return -ENODEV;
3299 w9968cf_push_frame(cam, mmap.frame);
3300 DBG(5, "VIDIOCMCAPTURE(%u): successfully called", mmap.frame)
3301 return 0;
3304 case VIDIOCSYNC: /* wait until the capture of a frame is finished */
3306 unsigned int f_num;
3307 struct w9968cf_frame_t* fr;
3308 int err = 0;
3310 if (copy_from_user(&f_num, arg, sizeof(f_num)))
3311 return -EFAULT;
3313 if (f_num >= cam->nbuffers) {
3314 DBG(4, "Invalid frame number (%u). "
3315 "VIDIOCMCAPTURE failed", f_num)
3316 return -EINVAL;
3319 DBG(6, "VIDIOCSYNC called for frame #%u", f_num)
3321 fr = &cam->frame[f_num];
3323 switch (fr->status) {
3324 case F_UNUSED:
3325 if (!fr->queued) {
3326 DBG(4, "VIDIOSYNC: Frame #%u not requested!",
3327 f_num)
3328 return -EFAULT;
3330 case F_ERROR:
3331 case F_GRABBING:
3332 err = wait_event_interruptible(cam->wait_queue,
3333 (fr->status == F_READY)
3334 || cam->disconnected);
3335 if (err)
3336 return err;
3337 if (cam->disconnected)
3338 return -ENODEV;
3339 break;
3340 case F_READY:
3341 break;
3344 if (w9968cf_vpp)
3345 w9968cf_postprocess_frame(cam, fr);
3347 fr->status = F_UNUSED;
3349 DBG(5, "VIDIOCSYNC(%u) successfully called", f_num)
3350 return 0;
3353 case VIDIOCGUNIT:/* report the unit numbers of the associated devices*/
3355 struct video_unit unit = {
3356 .video = cam->v4ldev->minor,
3357 .vbi = VIDEO_NO_UNIT,
3358 .radio = VIDEO_NO_UNIT,
3359 .audio = VIDEO_NO_UNIT,
3360 .teletext = VIDEO_NO_UNIT,
3363 if (copy_to_user(arg, &unit, sizeof(unit)))
3364 return -EFAULT;
3366 DBG(5, "VIDIOCGUNIT successfully called")
3367 return 0;
3370 case VIDIOCKEY:
3371 return 0;
3373 case VIDIOCGFBUF:
3375 if (clear_user(arg, sizeof(struct video_buffer)))
3376 return -EFAULT;
3378 DBG(5, "VIDIOCGFBUF successfully called")
3379 return 0;
3382 case VIDIOCGTUNER:
3384 struct video_tuner tuner;
3385 if (copy_from_user(&tuner, arg, sizeof(tuner)))
3386 return -EFAULT;
3388 if (tuner.tuner != 0)
3389 return -EINVAL;
3391 strcpy(tuner.name, "no_tuner");
3392 tuner.rangelow = 0;
3393 tuner.rangehigh = 0;
3394 tuner.flags = VIDEO_TUNER_NORM;
3395 tuner.mode = VIDEO_MODE_AUTO;
3396 tuner.signal = 0xffff;
3398 if (copy_to_user(arg, &tuner, sizeof(tuner)))
3399 return -EFAULT;
3401 DBG(5, "VIDIOCGTUNER successfully called")
3402 return 0;
3405 case VIDIOCSTUNER:
3407 struct video_tuner tuner;
3408 if (copy_from_user(&tuner, arg, sizeof(tuner)))
3409 return -EFAULT;
3411 if (tuner.tuner != 0)
3412 return -EINVAL;
3414 if (tuner.mode != VIDEO_MODE_AUTO)
3415 return -EINVAL;
3417 DBG(5, "VIDIOCSTUNER successfully called")
3418 return 0;
3421 case VIDIOCSFBUF:
3422 case VIDIOCCAPTURE:
3423 case VIDIOCGFREQ:
3424 case VIDIOCSFREQ:
3425 case VIDIOCGAUDIO:
3426 case VIDIOCSAUDIO:
3427 case VIDIOCSPLAYMODE:
3428 case VIDIOCSWRITEMODE:
3429 case VIDIOCGPLAYINFO:
3430 case VIDIOCSMICROCODE:
3431 case VIDIOCGVBIFMT:
3432 case VIDIOCSVBIFMT:
3433 DBG(4, "Unsupported V4L1 IOCtl: VIDIOC%s "
3434 "(type 0x%01X, "
3435 "n. 0x%01X, "
3436 "dir. 0x%01X, "
3437 "size 0x%02X)",
3438 V4L1_IOCTL(cmd),
3439 _IOC_TYPE(cmd),_IOC_NR(cmd),_IOC_DIR(cmd),_IOC_SIZE(cmd))
3441 return -EINVAL;
3443 default:
3444 DBG(4, "Invalid V4L1 IOCtl: VIDIOC%s "
3445 "type 0x%01X, "
3446 "n. 0x%01X, "
3447 "dir. 0x%01X, "
3448 "size 0x%02X",
3449 V4L1_IOCTL(cmd),
3450 _IOC_TYPE(cmd),_IOC_NR(cmd),_IOC_DIR(cmd),_IOC_SIZE(cmd))
3452 return -ENOIOCTLCMD;
3454 } /* end of switch */
3456 ioctl_fail:
3457 cam->misconfigured = 1;
3458 DBG(1, "VIDIOC%s failed because of hardware problems. "
3459 "To use the camera, close and open it again.", V4L1_IOCTL(cmd))
3460 return -EFAULT;
3464 static struct file_operations w9968cf_fops = {
3465 .owner = THIS_MODULE,
3466 .open = w9968cf_open,
3467 .release = w9968cf_release,
3468 .read = w9968cf_read,
3469 .ioctl = w9968cf_ioctl,
3470 .compat_ioctl = v4l_compat_ioctl32,
3471 .mmap = w9968cf_mmap,
3472 .llseek = no_llseek,
3477 /****************************************************************************
3478 * USB probe and V4L registration, disconnect and id_table[] definition *
3479 ****************************************************************************/
3481 static int
3482 w9968cf_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
3484 struct usb_device *udev = interface_to_usbdev(intf);
3485 struct w9968cf_device* cam;
3486 int err = 0;
3487 enum w9968cf_model_id mod_id;
3488 struct list_head* ptr;
3489 u8 sc = 0; /* number of simultaneous cameras */
3490 static unsigned short dev_nr = 0; /* we are handling device number n */
3492 if (le16_to_cpu(udev->descriptor.idVendor) == winbond_id_table[0].idVendor &&
3493 le16_to_cpu(udev->descriptor.idProduct) == winbond_id_table[0].idProduct)
3494 mod_id = W9968CF_MOD_CLVBWGP; /* see camlist[] table */
3495 else if (le16_to_cpu(udev->descriptor.idVendor) == winbond_id_table[1].idVendor &&
3496 le16_to_cpu(udev->descriptor.idProduct) == winbond_id_table[1].idProduct)
3497 mod_id = W9968CF_MOD_GENERIC; /* see camlist[] table */
3498 else
3499 return -ENODEV;
3501 cam = (struct w9968cf_device*)
3502 kmalloc(sizeof(struct w9968cf_device), GFP_KERNEL);
3503 if (!cam)
3504 return -ENOMEM;
3506 memset(cam, 0, sizeof(*cam));
3508 init_MUTEX(&cam->dev_sem);
3509 down(&cam->dev_sem);
3511 cam->usbdev = udev;
3512 /* NOTE: a local copy is used to avoid possible race conditions */
3513 memcpy(&cam->dev, &udev->dev, sizeof(struct device));
3515 DBG(2, "%s detected", symbolic(camlist, mod_id))
3517 if (simcams > W9968CF_MAX_DEVICES)
3518 simcams = W9968CF_SIMCAMS;
3520 /* How many cameras are connected ? */
3521 down(&w9968cf_devlist_sem);
3522 list_for_each(ptr, &w9968cf_dev_list)
3523 sc++;
3524 up(&w9968cf_devlist_sem);
3526 if (sc >= simcams) {
3527 DBG(2, "Device rejected: too many connected cameras "
3528 "(max. %u)", simcams)
3529 err = -EPERM;
3530 goto fail;
3534 /* Allocate 2 bytes of memory for camera control USB transfers */
3535 if (!(cam->control_buffer = kmalloc(2, GFP_KERNEL))) {
3536 DBG(1,"Couldn't allocate memory for camera control transfers")
3537 err = -ENOMEM;
3538 goto fail;
3540 memset(cam->control_buffer, 0, 2);
3542 /* Allocate 8 bytes of memory for USB data transfers to the FSB */
3543 if (!(cam->data_buffer = kmalloc(8, GFP_KERNEL))) {
3544 DBG(1, "Couldn't allocate memory for data "
3545 "transfers to the FSB")
3546 err = -ENOMEM;
3547 goto fail;
3549 memset(cam->data_buffer, 0, 8);
3551 /* Register the V4L device */
3552 cam->v4ldev = video_device_alloc();
3553 if (!cam->v4ldev) {
3554 DBG(1, "Could not allocate memory for a V4L structure")
3555 err = -ENOMEM;
3556 goto fail;
3559 strcpy(cam->v4ldev->name, symbolic(camlist, mod_id));
3560 cam->v4ldev->owner = THIS_MODULE;
3561 cam->v4ldev->type = VID_TYPE_CAPTURE | VID_TYPE_SCALES;
3562 cam->v4ldev->hardware = VID_HARDWARE_W9968CF;
3563 cam->v4ldev->fops = &w9968cf_fops;
3564 cam->v4ldev->minor = video_nr[dev_nr];
3565 cam->v4ldev->release = video_device_release;
3566 video_set_drvdata(cam->v4ldev, cam);
3567 cam->v4ldev->dev = &cam->dev;
3569 err = video_register_device(cam->v4ldev, VFL_TYPE_GRABBER,
3570 video_nr[dev_nr]);
3571 if (err) {
3572 DBG(1, "V4L device registration failed")
3573 if (err == -ENFILE && video_nr[dev_nr] == -1)
3574 DBG(2, "Couldn't find a free /dev/videoX node")
3575 video_nr[dev_nr] = -1;
3576 dev_nr = (dev_nr < W9968CF_MAX_DEVICES-1) ? dev_nr+1 : 0;
3577 goto fail;
3580 DBG(2, "V4L device registered as /dev/video%d", cam->v4ldev->minor)
3582 /* Set some basic constants */
3583 w9968cf_configure_camera(cam, udev, mod_id, dev_nr);
3585 /* Add a new entry into the list of V4L registered devices */
3586 down(&w9968cf_devlist_sem);
3587 list_add(&cam->v4llist, &w9968cf_dev_list);
3588 up(&w9968cf_devlist_sem);
3589 dev_nr = (dev_nr < W9968CF_MAX_DEVICES-1) ? dev_nr+1 : 0;
3591 w9968cf_turn_on_led(cam);
3593 w9968cf_i2c_init(cam);
3595 usb_set_intfdata(intf, cam);
3596 up(&cam->dev_sem);
3597 return 0;
3599 fail: /* Free unused memory */
3600 kfree(cam->control_buffer);
3601 kfree(cam->data_buffer);
3602 if (cam->v4ldev)
3603 video_device_release(cam->v4ldev);
3604 up(&cam->dev_sem);
3605 kfree(cam);
3606 return err;
3610 static void w9968cf_usb_disconnect(struct usb_interface* intf)
3612 struct w9968cf_device* cam =
3613 (struct w9968cf_device*)usb_get_intfdata(intf);
3615 down_write(&w9968cf_disconnect);
3617 if (cam) {
3618 /* Prevent concurrent accesses to data */
3619 down(&cam->dev_sem);
3621 cam->disconnected = 1;
3623 DBG(2, "Disconnecting %s...", symbolic(camlist, cam->id))
3625 wake_up_interruptible_all(&cam->open);
3627 if (cam->users) {
3628 DBG(2, "The device is open (/dev/video%d)! "
3629 "Process name: %s. Deregistration and memory "
3630 "deallocation are deferred on close.",
3631 cam->v4ldev->minor, cam->command)
3632 cam->misconfigured = 1;
3633 w9968cf_stop_transfer(cam);
3634 wake_up_interruptible(&cam->wait_queue);
3635 } else
3636 w9968cf_release_resources(cam);
3638 up(&cam->dev_sem);
3640 if (!cam->users)
3641 kfree(cam);
3644 up_write(&w9968cf_disconnect);
3648 static struct usb_driver w9968cf_usb_driver = {
3649 .name = "w9968cf",
3650 .id_table = winbond_id_table,
3651 .probe = w9968cf_usb_probe,
3652 .disconnect = w9968cf_usb_disconnect,
3657 /****************************************************************************
3658 * Module init, exit and intermodule communication *
3659 ****************************************************************************/
3661 static int __init w9968cf_module_init(void)
3663 int err;
3665 KDBG(2, W9968CF_MODULE_NAME" "W9968CF_MODULE_VERSION)
3666 KDBG(3, W9968CF_MODULE_AUTHOR)
3668 if (ovmod_load)
3669 request_module("ovcamchip");
3671 if ((err = usb_register(&w9968cf_usb_driver)))
3672 return err;
3674 return 0;
3678 static void __exit w9968cf_module_exit(void)
3680 /* w9968cf_usb_disconnect() will be called */
3681 usb_deregister(&w9968cf_usb_driver);
3683 KDBG(2, W9968CF_MODULE_NAME" deregistered")
3687 module_init(w9968cf_module_init);
3688 module_exit(w9968cf_module_exit);