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