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