[PATCH] USB: kzalloc in w9968cf
[linux-block.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] =
b10b4177 698 kzalloc(W9968CF_ISO_PACKETS*p_size, GFP_KERNEL))) {
1da177e4
LT
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 }
1da177e4
LT
704 }
705
706 /* Allocate memory for the temporary frame buffer */
707 if (!(cam->frame_tmp.buffer = rvmalloc(hw_bufsize))) {
708 DBG(1, "Couldn't allocate memory for the temporary "
709 "video frame buffer (%lu bytes)", hw_bufsize)
710 return -ENOMEM;
711 }
712 cam->frame_tmp.size = hw_bufsize;
713 cam->frame_tmp.number = -1;
714
715 /* Allocate memory for the helper buffer */
716 if (w9968cf_vpp) {
717 if (!(cam->frame_vpp.buffer = rvmalloc(vpp_bufsize))) {
718 DBG(1, "Couldn't allocate memory for the helper buffer"
719 " (%lu bytes)", vpp_bufsize)
720 return -ENOMEM;
721 }
722 cam->frame_vpp.size = vpp_bufsize;
723 } else
724 cam->frame_vpp.buffer = NULL;
725
726 /* Allocate memory for video frame buffers */
727 cam->nbuffers = cam->max_buffers;
728 while (cam->nbuffers >= 2) {
729 if ((buff = rvmalloc(cam->nbuffers * vpp_bufsize)))
730 break;
731 else
732 cam->nbuffers--;
733 }
734
735 if (!buff) {
736 DBG(1, "Couldn't allocate memory for the video frame buffers")
737 cam->nbuffers = 0;
738 return -ENOMEM;
739 }
740
741 if (cam->nbuffers != cam->max_buffers)
742 DBG(2, "Couldn't allocate memory for %u video frame buffers. "
743 "Only memory for %u buffers has been allocated",
744 cam->max_buffers, cam->nbuffers)
745
746 for (i = 0; i < cam->nbuffers; i++) {
747 cam->frame[i].buffer = buff + i*vpp_bufsize;
748 cam->frame[i].size = vpp_bufsize;
749 cam->frame[i].number = i;
750 /* Circular list */
751 if (i != cam->nbuffers-1)
752 cam->frame[i].next = &cam->frame[i+1];
753 else
754 cam->frame[i].next = &cam->frame[0];
755 cam->frame[i].status = F_UNUSED;
756 }
757
758 DBG(5, "Memory successfully allocated")
759 return 0;
760}
761
762
763
764/****************************************************************************
765 * USB-specific functions *
766 ****************************************************************************/
767
768/*--------------------------------------------------------------------------
769 This is an handler function which is called after the URBs are completed.
770 It collects multiple data packets coming from the camera by putting them
771 into frame buffers: one or more zero data length data packets are used to
772 mark the end of a video frame; the first non-zero data packet is the start
773 of the next video frame; if an error is encountered in a packet, the entire
774 video frame is discarded and grabbed again.
775 If there are no requested frames in the FIFO list, packets are collected into
776 a temporary buffer.
777 --------------------------------------------------------------------------*/
778static void w9968cf_urb_complete(struct urb *urb, struct pt_regs *regs)
779{
780 struct w9968cf_device* cam = (struct w9968cf_device*)urb->context;
781 struct w9968cf_frame_t** f;
782 unsigned int len, status;
783 void* pos;
784 u8 i;
785 int err = 0;
786
787 if ((!cam->streaming) || cam->disconnected) {
788 DBG(4, "Got interrupt, but not streaming")
789 return;
790 }
791
792 /* "(*f)" will be used instead of "cam->frame_current" */
793 f = &cam->frame_current;
794
795 /* If a frame has been requested and we are grabbing into
796 the temporary frame, we'll switch to that requested frame */
797 if ((*f) == &cam->frame_tmp && *cam->requested_frame) {
798 if (cam->frame_tmp.status == F_GRABBING) {
799 w9968cf_pop_frame(cam, &cam->frame_current);
800 (*f)->status = F_GRABBING;
801 (*f)->length = cam->frame_tmp.length;
802 memcpy((*f)->buffer, cam->frame_tmp.buffer,
803 (*f)->length);
804 DBG(6, "Switched from temp. frame to frame #%d",
805 (*f)->number)
806 }
807 }
808
809 for (i = 0; i < urb->number_of_packets; i++) {
810 len = urb->iso_frame_desc[i].actual_length;
811 status = urb->iso_frame_desc[i].status;
812 pos = urb->iso_frame_desc[i].offset + urb->transfer_buffer;
813
814 if (status && len != 0) {
815 DBG(4, "URB failed, error in data packet "
816 "(error #%u, %s)",
817 status, symbolic(urb_errlist, status))
818 (*f)->status = F_ERROR;
819 continue;
820 }
821
822 if (len) { /* start of frame */
823
824 if ((*f)->status == F_UNUSED) {
825 (*f)->status = F_GRABBING;
826 (*f)->length = 0;
827 }
828
829 /* Buffer overflows shouldn't happen, however...*/
830 if ((*f)->length + len > (*f)->size) {
831 DBG(4, "Buffer overflow: bad data packets")
832 (*f)->status = F_ERROR;
833 }
834
835 if ((*f)->status == F_GRABBING) {
836 memcpy((*f)->buffer + (*f)->length, pos, len);
837 (*f)->length += len;
838 }
839
840 } else if ((*f)->status == F_GRABBING) { /* end of frame */
841
842 DBG(6, "Frame #%d successfully grabbed", (*f)->number)
843
844 if (cam->vpp_flag & VPP_DECOMPRESSION) {
845 err = w9968cf_vpp->check_headers((*f)->buffer,
846 (*f)->length);
847 if (err) {
848 DBG(4, "Skip corrupted frame: %s",
849 symbolic(decoder_errlist, err))
850 (*f)->status = F_UNUSED;
851 continue; /* grab this frame again */
852 }
853 }
854
855 (*f)->status = F_READY;
856 (*f)->queued = 0;
857
858 /* Take a pointer to the new frame from the FIFO list.
859 If the list is empty,we'll use the temporary frame*/
860 if (*cam->requested_frame)
861 w9968cf_pop_frame(cam, &cam->frame_current);
862 else {
863 cam->frame_current = &cam->frame_tmp;
864 (*f)->status = F_UNUSED;
865 }
866
867 } else if ((*f)->status == F_ERROR)
868 (*f)->status = F_UNUSED; /* grab it again */
869
870 PDBGG("Frame length %lu | pack.#%u | pack.len. %u | state %d",
871 (unsigned long)(*f)->length, i, len, (*f)->status)
872
873 } /* end for */
874
875 /* Resubmit this URB */
876 urb->dev = cam->usbdev;
877 urb->status = 0;
878 spin_lock(&cam->urb_lock);
879 if (cam->streaming)
880 if ((err = usb_submit_urb(urb, GFP_ATOMIC))) {
881 cam->misconfigured = 1;
882 DBG(1, "Couldn't resubmit the URB: error %d, %s",
883 err, symbolic(urb_errlist, err))
884 }
885 spin_unlock(&cam->urb_lock);
886
887 /* Wake up the user process */
888 wake_up_interruptible(&cam->wait_queue);
889}
890
891
892/*---------------------------------------------------------------------------
893 Setup the URB structures for the isochronous transfer.
894 Submit the URBs so that the data transfer begins.
895 Return 0 on success, a negative number otherwise.
896 ---------------------------------------------------------------------------*/
897static int w9968cf_start_transfer(struct w9968cf_device* cam)
898{
899 struct usb_device *udev = cam->usbdev;
900 struct urb* urb;
901 const u16 p_size = wMaxPacketSize[cam->altsetting-1];
902 u16 w, h, d;
903 int vidcapt;
904 u32 t_size;
905 int err = 0;
906 s8 i, j;
907
908 for (i = 0; i < W9968CF_URBS; i++) {
909 urb = usb_alloc_urb(W9968CF_ISO_PACKETS, GFP_KERNEL);
910 cam->urb[i] = urb;
911 if (!urb) {
912 for (j = 0; j < i; j++)
913 usb_free_urb(cam->urb[j]);
914 DBG(1, "Couldn't allocate the URB structures")
915 return -ENOMEM;
916 }
917
918 urb->dev = udev;
919 urb->context = (void*)cam;
920 urb->pipe = usb_rcvisocpipe(udev, 1);
921 urb->transfer_flags = URB_ISO_ASAP;
922 urb->number_of_packets = W9968CF_ISO_PACKETS;
923 urb->complete = w9968cf_urb_complete;
924 urb->transfer_buffer = cam->transfer_buffer[i];
925 urb->transfer_buffer_length = p_size*W9968CF_ISO_PACKETS;
926 urb->interval = 1;
927 for (j = 0; j < W9968CF_ISO_PACKETS; j++) {
928 urb->iso_frame_desc[j].offset = p_size*j;
929 urb->iso_frame_desc[j].length = p_size;
930 }
931 }
932
933 /* Transfer size per frame, in WORD ! */
934 d = cam->hw_depth;
935 w = cam->hw_width;
936 h = cam->hw_height;
937
938 t_size = (w*h*d)/16;
939
940 err = w9968cf_write_reg(cam, 0xbf17, 0x00); /* reset everything */
941 err += w9968cf_write_reg(cam, 0xbf10, 0x00); /* normal operation */
942
943 /* Transfer size */
944 err += w9968cf_write_reg(cam, t_size & 0xffff, 0x3d); /* low bits */
945 err += w9968cf_write_reg(cam, t_size >> 16, 0x3e); /* high bits */
946
947 if (cam->vpp_flag & VPP_DECOMPRESSION)
948 err += w9968cf_upload_quantizationtables(cam);
949
950 vidcapt = w9968cf_read_reg(cam, 0x16); /* read picture settings */
951 err += w9968cf_write_reg(cam, vidcapt|0x8000, 0x16); /* capt. enable */
952
953 err += usb_set_interface(udev, 0, cam->altsetting);
954 err += w9968cf_write_reg(cam, 0x8a05, 0x3c); /* USB FIFO enable */
955
956 if (err || (vidcapt < 0)) {
957 for (i = 0; i < W9968CF_URBS; i++)
958 usb_free_urb(cam->urb[i]);
959 DBG(1, "Couldn't tell the camera to start the data transfer")
960 return err;
961 }
962
963 w9968cf_init_framelist(cam);
964
965 /* Begin to grab into the temporary buffer */
966 cam->frame_tmp.status = F_UNUSED;
967 cam->frame_tmp.queued = 0;
968 cam->frame_current = &cam->frame_tmp;
969
970 if (!(cam->vpp_flag & VPP_DECOMPRESSION))
971 DBG(5, "Isochronous transfer size: %lu bytes/frame",
972 (unsigned long)t_size*2)
973
974 DBG(5, "Starting the isochronous transfer...")
975
976 cam->streaming = 1;
977
978 /* Submit the URBs */
979 for (i = 0; i < W9968CF_URBS; i++) {
980 err = usb_submit_urb(cam->urb[i], GFP_KERNEL);
981 if (err) {
982 cam->streaming = 0;
983 for (j = i-1; j >= 0; j--) {
984 usb_kill_urb(cam->urb[j]);
985 usb_free_urb(cam->urb[j]);
986 }
987 DBG(1, "Couldn't send a transfer request to the "
988 "USB core (error #%d, %s)", err,
989 symbolic(urb_errlist, err))
990 return err;
991 }
992 }
993
994 return 0;
995}
996
997
998/*--------------------------------------------------------------------------
999 Stop the isochronous transfer and set alternate setting to 0 (0Mb/s).
1000 Return 0 on success, a negative number otherwise.
1001 --------------------------------------------------------------------------*/
1002static int w9968cf_stop_transfer(struct w9968cf_device* cam)
1003{
1004 struct usb_device *udev = cam->usbdev;
1005 unsigned long lock_flags;
1006 int err = 0;
1007 s8 i;
1008
1009 if (!cam->streaming)
1010 return 0;
1011
1012 /* This avoids race conditions with usb_submit_urb()
1013 in the URB completition handler */
1014 spin_lock_irqsave(&cam->urb_lock, lock_flags);
1015 cam->streaming = 0;
1016 spin_unlock_irqrestore(&cam->urb_lock, lock_flags);
1017
1018 for (i = W9968CF_URBS-1; i >= 0; i--)
1019 if (cam->urb[i]) {
1020 usb_kill_urb(cam->urb[i]);
1021 usb_free_urb(cam->urb[i]);
1022 cam->urb[i] = NULL;
1023 }
1024
1025 if (cam->disconnected)
1026 goto exit;
1027
1028 err = w9968cf_write_reg(cam, 0x0a05, 0x3c); /* stop USB transfer */
1029 err += usb_set_interface(udev, 0, 0); /* 0 Mb/s */
1030 err += w9968cf_write_reg(cam, 0x0000, 0x39); /* disable JPEG encoder */
1031 err += w9968cf_write_reg(cam, 0x0000, 0x16); /* stop video capture */
1032
1033 if (err) {
1034 DBG(2, "Failed to tell the camera to stop the isochronous "
1035 "transfer. However this is not a critical error.")
1036 return -EIO;
1037 }
1038
1039exit:
1040 DBG(5, "Isochronous transfer stopped")
1041 return 0;
1042}
1043
1044
1045/*--------------------------------------------------------------------------
1046 Write a W9968CF register.
1047 Return 0 on success, -1 otherwise.
1048 --------------------------------------------------------------------------*/
1049static int w9968cf_write_reg(struct w9968cf_device* cam, u16 value, u16 index)
1050{
1051 struct usb_device* udev = cam->usbdev;
1052 int res;
1053
1054 res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0,
1055 USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE,
1056 value, index, NULL, 0, W9968CF_USB_CTRL_TIMEOUT);
1057
1058 if (res < 0)
1059 DBG(4, "Failed to write a register "
1060 "(value 0x%04X, index 0x%02X, error #%d, %s)",
1061 value, index, res, symbolic(urb_errlist, res))
1062
1063 return (res >= 0) ? 0 : -1;
1064}
1065
1066
1067/*--------------------------------------------------------------------------
1068 Read a W9968CF register.
1069 Return the register value on success, -1 otherwise.
1070 --------------------------------------------------------------------------*/
1071static int w9968cf_read_reg(struct w9968cf_device* cam, u16 index)
1072{
1073 struct usb_device* udev = cam->usbdev;
1074 u16* buff = cam->control_buffer;
1075 int res;
1076
1077 res = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 1,
1078 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
1079 0, index, buff, 2, W9968CF_USB_CTRL_TIMEOUT);
1080
1081 if (res < 0)
1082 DBG(4, "Failed to read a register "
1083 "(index 0x%02X, error #%d, %s)",
1084 index, res, symbolic(urb_errlist, res))
1085
1086 return (res >= 0) ? (int)(*buff) : -1;
1087}
1088
1089
1090/*--------------------------------------------------------------------------
1091 Write 64-bit data to the fast serial bus registers.
1092 Return 0 on success, -1 otherwise.
1093 --------------------------------------------------------------------------*/
1094static int w9968cf_write_fsb(struct w9968cf_device* cam, u16* data)
1095{
1096 struct usb_device* udev = cam->usbdev;
1097 u16 value;
1098 int res;
1099
1100 value = *data++;
1101
1102 res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0,
1103 USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE,
1104 value, 0x06, data, 6, W9968CF_USB_CTRL_TIMEOUT);
1105
1106 if (res < 0)
1107 DBG(4, "Failed to write the FSB registers "
1108 "(error #%d, %s)", res, symbolic(urb_errlist, res))
1109
1110 return (res >= 0) ? 0 : -1;
1111}
1112
1113
1114/*--------------------------------------------------------------------------
1115 Write data to the serial bus control register.
1116 Return 0 on success, a negative number otherwise.
1117 --------------------------------------------------------------------------*/
1118static int w9968cf_write_sb(struct w9968cf_device* cam, u16 value)
1119{
1120 int err = 0;
1121
1122 err = w9968cf_write_reg(cam, value, 0x01);
1123 udelay(W9968CF_I2C_BUS_DELAY);
1124
1125 return err;
1126}
1127
1128
1129/*--------------------------------------------------------------------------
1130 Read data from the serial bus control register.
1131 Return 0 on success, a negative number otherwise.
1132 --------------------------------------------------------------------------*/
1133static int w9968cf_read_sb(struct w9968cf_device* cam)
1134{
1135 int v = 0;
1136
1137 v = w9968cf_read_reg(cam, 0x01);
1138 udelay(W9968CF_I2C_BUS_DELAY);
1139
1140 return v;
1141}
1142
1143
1144/*--------------------------------------------------------------------------
1145 Upload quantization tables for the JPEG compression.
1146 This function is called by w9968cf_start_transfer().
1147 Return 0 on success, a negative number otherwise.
1148 --------------------------------------------------------------------------*/
1149static int w9968cf_upload_quantizationtables(struct w9968cf_device* cam)
1150{
1151 u16 a, b;
1152 int err = 0, i, j;
1153
1154 err += w9968cf_write_reg(cam, 0x0010, 0x39); /* JPEG clock enable */
1155
1156 for (i = 0, j = 0; i < 32; i++, j += 2) {
1157 a = Y_QUANTABLE[j] | ((unsigned)(Y_QUANTABLE[j+1]) << 8);
1158 b = UV_QUANTABLE[j] | ((unsigned)(UV_QUANTABLE[j+1]) << 8);
1159 err += w9968cf_write_reg(cam, a, 0x40+i);
1160 err += w9968cf_write_reg(cam, b, 0x60+i);
1161 }
1162 err += w9968cf_write_reg(cam, 0x0012, 0x39); /* JPEG encoder enable */
1163
1164 return err;
1165}
1166
1167
1168
1169/****************************************************************************
1170 * Low-level I2C I/O functions. *
1171 * The adapter supports the following I2C transfer functions: *
1172 * i2c_adap_fastwrite_byte_data() (at 400 kHz bit frequency only) *
1173 * i2c_adap_read_byte_data() *
1174 * i2c_adap_read_byte() *
1175 ****************************************************************************/
1176
1177static int w9968cf_smbus_start(struct w9968cf_device* cam)
1178{
1179 int err = 0;
1180
1181 err += w9968cf_write_sb(cam, 0x0011); /* SDE=1, SDA=0, SCL=1 */
1182 err += w9968cf_write_sb(cam, 0x0010); /* SDE=1, SDA=0, SCL=0 */
1183
1184 return err;
1185}
1186
1187
1188static int w9968cf_smbus_stop(struct w9968cf_device* cam)
1189{
1190 int err = 0;
1191
1192 err += w9968cf_write_sb(cam, 0x0011); /* SDE=1, SDA=0, SCL=1 */
1193 err += w9968cf_write_sb(cam, 0x0013); /* SDE=1, SDA=1, SCL=1 */
1194
1195 return err;
1196}
1197
1198
1199static int w9968cf_smbus_write_byte(struct w9968cf_device* cam, u8 v)
1200{
1201 u8 bit;
1202 int err = 0, sda;
1203
1204 for (bit = 0 ; bit < 8 ; bit++) {
1205 sda = (v & 0x80) ? 2 : 0;
1206 v <<= 1;
1207 /* SDE=1, SDA=sda, SCL=0 */
1208 err += w9968cf_write_sb(cam, 0x10 | sda);
1209 /* SDE=1, SDA=sda, SCL=1 */
1210 err += w9968cf_write_sb(cam, 0x11 | sda);
1211 /* SDE=1, SDA=sda, SCL=0 */
1212 err += w9968cf_write_sb(cam, 0x10 | sda);
1213 }
1214
1215 return err;
1216}
1217
1218
1219static int w9968cf_smbus_read_byte(struct w9968cf_device* cam, u8* v)
1220{
1221 u8 bit;
1222 int err = 0;
1223
1224 *v = 0;
1225 for (bit = 0 ; bit < 8 ; bit++) {
1226 *v <<= 1;
1227 err += w9968cf_write_sb(cam, 0x0013);
1228 *v |= (w9968cf_read_sb(cam) & 0x0008) ? 1 : 0;
1229 err += w9968cf_write_sb(cam, 0x0012);
1230 }
1231
1232 return err;
1233}
1234
1235
1236static int w9968cf_smbus_write_ack(struct w9968cf_device* cam)
1237{
1238 int err = 0;
1239
1240 err += w9968cf_write_sb(cam, 0x0010); /* SDE=1, SDA=0, SCL=0 */
1241 err += w9968cf_write_sb(cam, 0x0011); /* SDE=1, SDA=0, SCL=1 */
1242 err += w9968cf_write_sb(cam, 0x0010); /* SDE=1, SDA=0, SCL=0 */
1243
1244 return err;
1245}
1246
1247
1248static int w9968cf_smbus_read_ack(struct w9968cf_device* cam)
1249{
1250 int err = 0, sda;
1251
1252 err += w9968cf_write_sb(cam, 0x0013); /* SDE=1, SDA=1, SCL=1 */
1253 sda = (w9968cf_read_sb(cam) & 0x08) ? 1 : 0; /* sda = SDA */
1254 err += w9968cf_write_sb(cam, 0x0012); /* SDE=1, SDA=1, SCL=0 */
1255 if (sda < 0)
1256 err += sda;
1257 if (sda == 1) {
1258 DBG(6, "Couldn't receive the ACK")
1259 err += -1;
1260 }
1261
1262 return err;
1263}
1264
1265
1266/* This seems to refresh the communication through the serial bus */
1267static int w9968cf_smbus_refresh_bus(struct w9968cf_device* cam)
1268{
1269 int err = 0, j;
1270
1271 for (j = 1; j <= 10; j++) {
1272 err = w9968cf_write_reg(cam, 0x0020, 0x01);
1273 err += w9968cf_write_reg(cam, 0x0000, 0x01);
1274 if (err)
1275 break;
1276 }
1277
1278 return err;
1279}
1280
1281
1282/* SMBus protocol: S Addr Wr [A] Subaddr [A] Value [A] P */
1283static int
1284w9968cf_i2c_adap_fastwrite_byte_data(struct w9968cf_device* cam,
1285 u16 address, u8 subaddress,u8 value)
1286{
1287 u16* data = cam->data_buffer;
1288 int err = 0;
1289
1290 err += w9968cf_smbus_refresh_bus(cam);
1291
1292 /* Enable SBUS outputs */
1293 err += w9968cf_write_sb(cam, 0x0020);
1294
1295 data[0] = 0x082f | ((address & 0x80) ? 0x1500 : 0x0);
1296 data[0] |= (address & 0x40) ? 0x4000 : 0x0;
1297 data[1] = 0x2082 | ((address & 0x40) ? 0x0005 : 0x0);
1298 data[1] |= (address & 0x20) ? 0x0150 : 0x0;
1299 data[1] |= (address & 0x10) ? 0x5400 : 0x0;
1300 data[2] = 0x8208 | ((address & 0x08) ? 0x0015 : 0x0);
1301 data[2] |= (address & 0x04) ? 0x0540 : 0x0;
1302 data[2] |= (address & 0x02) ? 0x5000 : 0x0;
1303 data[3] = 0x1d20 | ((address & 0x02) ? 0x0001 : 0x0);
1304 data[3] |= (address & 0x01) ? 0x0054 : 0x0;
1305
1306 err += w9968cf_write_fsb(cam, data);
1307
1308 data[0] = 0x8208 | ((subaddress & 0x80) ? 0x0015 : 0x0);
1309 data[0] |= (subaddress & 0x40) ? 0x0540 : 0x0;
1310 data[0] |= (subaddress & 0x20) ? 0x5000 : 0x0;
1311 data[1] = 0x0820 | ((subaddress & 0x20) ? 0x0001 : 0x0);
1312 data[1] |= (subaddress & 0x10) ? 0x0054 : 0x0;
1313 data[1] |= (subaddress & 0x08) ? 0x1500 : 0x0;
1314 data[1] |= (subaddress & 0x04) ? 0x4000 : 0x0;
1315 data[2] = 0x2082 | ((subaddress & 0x04) ? 0x0005 : 0x0);
1316 data[2] |= (subaddress & 0x02) ? 0x0150 : 0x0;
1317 data[2] |= (subaddress & 0x01) ? 0x5400 : 0x0;
1318 data[3] = 0x001d;
1319
1320 err += w9968cf_write_fsb(cam, data);
1321
1322 data[0] = 0x8208 | ((value & 0x80) ? 0x0015 : 0x0);
1323 data[0] |= (value & 0x40) ? 0x0540 : 0x0;
1324 data[0] |= (value & 0x20) ? 0x5000 : 0x0;
1325 data[1] = 0x0820 | ((value & 0x20) ? 0x0001 : 0x0);
1326 data[1] |= (value & 0x10) ? 0x0054 : 0x0;
1327 data[1] |= (value & 0x08) ? 0x1500 : 0x0;
1328 data[1] |= (value & 0x04) ? 0x4000 : 0x0;
1329 data[2] = 0x2082 | ((value & 0x04) ? 0x0005 : 0x0);
1330 data[2] |= (value & 0x02) ? 0x0150 : 0x0;
1331 data[2] |= (value & 0x01) ? 0x5400 : 0x0;
1332 data[3] = 0xfe1d;
1333
1334 err += w9968cf_write_fsb(cam, data);
1335
1336 /* Disable SBUS outputs */
1337 err += w9968cf_write_sb(cam, 0x0000);
1338
1339 if (!err)
1340 DBG(5, "I2C write byte data done, addr.0x%04X, subaddr.0x%02X "
1341 "value 0x%02X", address, subaddress, value)
1342 else
1343 DBG(5, "I2C write byte data failed, addr.0x%04X, "
1344 "subaddr.0x%02X, value 0x%02X",
1345 address, subaddress, value)
1346
1347 return err;
1348}
1349
1350
1351/* SMBus protocol: S Addr Wr [A] Subaddr [A] P S Addr+1 Rd [A] [Value] NA P */
1352static int
1353w9968cf_i2c_adap_read_byte_data(struct w9968cf_device* cam,
1354 u16 address, u8 subaddress,
1355 u8* value)
1356{
1357 int err = 0;
1358
1359 /* Serial data enable */
1360 err += w9968cf_write_sb(cam, 0x0013); /* don't change ! */
1361
1362 err += w9968cf_smbus_start(cam);
1363 err += w9968cf_smbus_write_byte(cam, address);
1364 err += w9968cf_smbus_read_ack(cam);
1365 err += w9968cf_smbus_write_byte(cam, subaddress);
1366 err += w9968cf_smbus_read_ack(cam);
1367 err += w9968cf_smbus_stop(cam);
1368 err += w9968cf_smbus_start(cam);
1369 err += w9968cf_smbus_write_byte(cam, address + 1);
1370 err += w9968cf_smbus_read_ack(cam);
1371 err += w9968cf_smbus_read_byte(cam, value);
1372 err += w9968cf_smbus_write_ack(cam);
1373 err += w9968cf_smbus_stop(cam);
1374
1375 /* Serial data disable */
1376 err += w9968cf_write_sb(cam, 0x0000);
1377
1378 if (!err)
1379 DBG(5, "I2C read byte data done, addr.0x%04X, "
1380 "subaddr.0x%02X, value 0x%02X",
1381 address, subaddress, *value)
1382 else
1383 DBG(5, "I2C read byte data failed, addr.0x%04X, "
1384 "subaddr.0x%02X, wrong value 0x%02X",
1385 address, subaddress, *value)
1386
1387 return err;
1388}
1389
1390
1391/* SMBus protocol: S Addr+1 Rd [A] [Value] NA P */
1392static int
1393w9968cf_i2c_adap_read_byte(struct w9968cf_device* cam,
1394 u16 address, u8* value)
1395{
1396 int err = 0;
1397
1398 /* Serial data enable */
1399 err += w9968cf_write_sb(cam, 0x0013);
1400
1401 err += w9968cf_smbus_start(cam);
1402 err += w9968cf_smbus_write_byte(cam, address + 1);
1403 err += w9968cf_smbus_read_ack(cam);
1404 err += w9968cf_smbus_read_byte(cam, value);
1405 err += w9968cf_smbus_write_ack(cam);
1406 err += w9968cf_smbus_stop(cam);
1407
1408 /* Serial data disable */
1409 err += w9968cf_write_sb(cam, 0x0000);
1410
1411 if (!err)
1412 DBG(5, "I2C read byte done, addr.0x%04X, "
1413 "value 0x%02X", address, *value)
1414 else
1415 DBG(5, "I2C read byte failed, addr.0x%04X, "
1416 "wrong value 0x%02X", address, *value)
1417
1418 return err;
1419}
1420
1421
1422/* SMBus protocol: S Addr Wr [A] Value [A] P */
1423static int
1424w9968cf_i2c_adap_write_byte(struct w9968cf_device* cam,
1425 u16 address, u8 value)
1426{
1427 DBG(4, "i2c_write_byte() is an unsupported transfer mode")
1428 return -EINVAL;
1429}
1430
1431
1432
1433/****************************************************************************
1434 * I2C interface to kernel *
1435 ****************************************************************************/
1436
1437static int
1438w9968cf_i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr,
1439 unsigned short flags, char read_write, u8 command,
1440 int size, union i2c_smbus_data *data)
1441{
1442 struct w9968cf_device* cam = i2c_get_adapdata(adapter);
1443 u8 i;
1444 int err = 0;
1445
1446 switch (addr) {
1447 case OV6xx0_SID:
1448 case OV7xx0_SID:
1449 break;
1450 default:
1451 DBG(4, "Rejected slave ID 0x%04X", addr)
1452 return -EINVAL;
1453 }
1454
1455 if (size == I2C_SMBUS_BYTE) {
1456 /* Why addr <<= 1? See OVXXX0_SID defines in ovcamchip.h */
1457 addr <<= 1;
1458
1459 if (read_write == I2C_SMBUS_WRITE)
1460 err = w9968cf_i2c_adap_write_byte(cam, addr, command);
1461 else if (read_write == I2C_SMBUS_READ)
1462 err = w9968cf_i2c_adap_read_byte(cam,addr,&data->byte);
1463
1464 } else if (size == I2C_SMBUS_BYTE_DATA) {
1465 addr <<= 1;
1466
1467 if (read_write == I2C_SMBUS_WRITE)
1468 err = w9968cf_i2c_adap_fastwrite_byte_data(cam, addr,
1469 command, data->byte);
1470 else if (read_write == I2C_SMBUS_READ) {
1471 for (i = 1; i <= W9968CF_I2C_RW_RETRIES; i++) {
1472 err = w9968cf_i2c_adap_read_byte_data(cam,addr,
1473 command, &data->byte);
1474 if (err) {
1475 if (w9968cf_smbus_refresh_bus(cam)) {
1476 err = -EIO;
1477 break;
1478 }
1479 } else
1480 break;
1481 }
1482
1483 } else
1484 return -EINVAL;
1485
1486 } else {
1487 DBG(4, "Unsupported I2C transfer mode (%d)", size)
1488 return -EINVAL;
1489 }
1490
1491 return err;
1492}
1493
1494
1495static u32 w9968cf_i2c_func(struct i2c_adapter* adap)
1496{
1497 return I2C_FUNC_SMBUS_READ_BYTE |
1498 I2C_FUNC_SMBUS_READ_BYTE_DATA |
1499 I2C_FUNC_SMBUS_WRITE_BYTE_DATA;
1500}
1501
1502
1503static int w9968cf_i2c_attach_inform(struct i2c_client* client)
1504{
1505 struct w9968cf_device* cam = i2c_get_adapdata(client->adapter);
1da177e4
LT
1506 int id = client->driver->id, err = 0;
1507
1508 if (id == I2C_DRIVERID_OVCAMCHIP) {
1509 cam->sensor_client = client;
1510 err = w9968cf_sensor_init(cam);
1511 if (err) {
1512 cam->sensor_client = NULL;
1513 return err;
1514 }
1515 } else {
1516 DBG(4, "Rejected client [%s] with driver [%s]",
604f28e2 1517 client->name, client->driver->driver.name)
1da177e4
LT
1518 return -EINVAL;
1519 }
1520
1521 DBG(5, "I2C attach client [%s] with driver [%s]",
604f28e2 1522 client->name, client->driver->driver.name)
1da177e4
LT
1523
1524 return 0;
1525}
1526
1527
1528static int w9968cf_i2c_detach_inform(struct i2c_client* client)
1529{
1530 struct w9968cf_device* cam = i2c_get_adapdata(client->adapter);
1da177e4
LT
1531
1532 if (cam->sensor_client == client)
1533 cam->sensor_client = NULL;
1534
fae91e72 1535 DBG(5, "I2C detach client [%s]", client->name)
1da177e4
LT
1536
1537 return 0;
1538}
1539
1540
1541static int
1542w9968cf_i2c_control(struct i2c_adapter* adapter, unsigned int cmd,
1543 unsigned long arg)
1544{
1545 return 0;
1546}
1547
1548
1549static int w9968cf_i2c_init(struct w9968cf_device* cam)
1550{
1551 int err = 0;
1552
1553 static struct i2c_algorithm algo = {
1da177e4
LT
1554 .smbus_xfer = w9968cf_i2c_smbus_xfer,
1555 .algo_control = w9968cf_i2c_control,
1556 .functionality = w9968cf_i2c_func,
1557 };
1558
1559 static struct i2c_adapter adap = {
c7a46533 1560 .id = I2C_HW_SMBUS_W9968CF,
1da177e4
LT
1561 .class = I2C_CLASS_CAM_DIGITAL,
1562 .owner = THIS_MODULE,
1563 .client_register = w9968cf_i2c_attach_inform,
1564 .client_unregister = w9968cf_i2c_detach_inform,
1565 .algo = &algo,
1566 };
1567
1568 memcpy(&cam->i2c_adapter, &adap, sizeof(struct i2c_adapter));
1569 strcpy(cam->i2c_adapter.name, "w9968cf");
1570 i2c_set_adapdata(&cam->i2c_adapter, cam);
1571
1572 DBG(6, "Registering I2C adapter with kernel...")
1573
1574 err = i2c_add_adapter(&cam->i2c_adapter);
1575 if (err)
1576 DBG(1, "Failed to register the I2C adapter")
1577 else
1578 DBG(5, "I2C adapter registered")
1579
1580 return err;
1581}
1582
1583
1584
1585/****************************************************************************
1586 * Helper functions *
1587 ****************************************************************************/
1588
1589/*--------------------------------------------------------------------------
1590 Turn on the LED on some webcams. A beep should be heard too.
1591 Return 0 on success, a negative number otherwise.
1592 --------------------------------------------------------------------------*/
1593static int w9968cf_turn_on_led(struct w9968cf_device* cam)
1594{
1595 int err = 0;
1596
1597 err += w9968cf_write_reg(cam, 0xff00, 0x00); /* power-down */
1598 err += w9968cf_write_reg(cam, 0xbf17, 0x00); /* reset everything */
1599 err += w9968cf_write_reg(cam, 0xbf10, 0x00); /* normal operation */
1600 err += w9968cf_write_reg(cam, 0x0010, 0x01); /* serial bus, SDS high */
1601 err += w9968cf_write_reg(cam, 0x0000, 0x01); /* serial bus, SDS low */
1602 err += w9968cf_write_reg(cam, 0x0010, 0x01); /* ..high 'beep-beep' */
1603
1604 if (err)
1605 DBG(2, "Couldn't turn on the LED")
1606
1607 DBG(5, "LED turned on")
1608
1609 return err;
1610}
1611
1612
1613/*--------------------------------------------------------------------------
1614 Write some registers for the device initialization.
1615 This function is called once on open().
1616 Return 0 on success, a negative number otherwise.
1617 --------------------------------------------------------------------------*/
1618static int w9968cf_init_chip(struct w9968cf_device* cam)
1619{
1620 unsigned long hw_bufsize = cam->maxwidth*cam->maxheight*2,
1621 y0 = 0x0000,
1622 u0 = y0 + hw_bufsize/2,
1623 v0 = u0 + hw_bufsize/4,
1624 y1 = v0 + hw_bufsize/4,
1625 u1 = y1 + hw_bufsize/2,
1626 v1 = u1 + hw_bufsize/4;
1627 int err = 0;
1628
1629 err += w9968cf_write_reg(cam, 0xff00, 0x00); /* power off */
1630 err += w9968cf_write_reg(cam, 0xbf10, 0x00); /* power on */
1631
1632 err += w9968cf_write_reg(cam, 0x405d, 0x03); /* DRAM timings */
1633 err += w9968cf_write_reg(cam, 0x0030, 0x04); /* SDRAM timings */
1634
1635 err += w9968cf_write_reg(cam, y0 & 0xffff, 0x20); /* Y buf.0, low */
1636 err += w9968cf_write_reg(cam, y0 >> 16, 0x21); /* Y buf.0, high */
1637 err += w9968cf_write_reg(cam, u0 & 0xffff, 0x24); /* U buf.0, low */
1638 err += w9968cf_write_reg(cam, u0 >> 16, 0x25); /* U buf.0, high */
1639 err += w9968cf_write_reg(cam, v0 & 0xffff, 0x28); /* V buf.0, low */
1640 err += w9968cf_write_reg(cam, v0 >> 16, 0x29); /* V buf.0, high */
1641
1642 err += w9968cf_write_reg(cam, y1 & 0xffff, 0x22); /* Y buf.1, low */
1643 err += w9968cf_write_reg(cam, y1 >> 16, 0x23); /* Y buf.1, high */
1644 err += w9968cf_write_reg(cam, u1 & 0xffff, 0x26); /* U buf.1, low */
1645 err += w9968cf_write_reg(cam, u1 >> 16, 0x27); /* U buf.1, high */
1646 err += w9968cf_write_reg(cam, v1 & 0xffff, 0x2a); /* V buf.1, low */
1647 err += w9968cf_write_reg(cam, v1 >> 16, 0x2b); /* V buf.1, high */
1648
1649 err += w9968cf_write_reg(cam, y1 & 0xffff, 0x32); /* JPEG buf 0 low */
1650 err += w9968cf_write_reg(cam, y1 >> 16, 0x33); /* JPEG buf 0 high */
1651
1652 err += w9968cf_write_reg(cam, y1 & 0xffff, 0x34); /* JPEG buf 1 low */
1653 err += w9968cf_write_reg(cam, y1 >> 16, 0x35); /* JPEG bug 1 high */
1654
1655 err += w9968cf_write_reg(cam, 0x0000, 0x36);/* JPEG restart interval */
1656 err += w9968cf_write_reg(cam, 0x0804, 0x37);/*JPEG VLE FIFO threshold*/
1657 err += w9968cf_write_reg(cam, 0x0000, 0x38);/* disable hw up-scaling */
1658 err += w9968cf_write_reg(cam, 0x0000, 0x3f); /* JPEG/MCTL test data */
1659
1660 err += w9968cf_set_picture(cam, cam->picture); /* this before */
1661 err += w9968cf_set_window(cam, cam->window);
1662
1663 if (err)
1664 DBG(1, "Chip initialization failed")
1665 else
1666 DBG(5, "Chip successfully initialized")
1667
1668 return err;
1669}
1670
1671
1672/*--------------------------------------------------------------------------
1673 Return non-zero if the palette is supported, 0 otherwise.
1674 --------------------------------------------------------------------------*/
1675static inline u16 w9968cf_valid_palette(u16 palette)
1676{
1677 u8 i = 0;
1678 while (w9968cf_formatlist[i].palette != 0) {
1679 if (palette == w9968cf_formatlist[i].palette)
1680 return palette;
1681 i++;
1682 }
1683 return 0;
1684}
1685
1686
1687/*--------------------------------------------------------------------------
1688 Return the depth corresponding to the given palette.
1689 Palette _must_ be supported !
1690 --------------------------------------------------------------------------*/
1691static inline u16 w9968cf_valid_depth(u16 palette)
1692{
1693 u8 i=0;
1694 while (w9968cf_formatlist[i].palette != palette)
1695 i++;
1696
1697 return w9968cf_formatlist[i].depth;
1698}
1699
1700
1701/*--------------------------------------------------------------------------
1702 Return non-zero if the format requires decompression, 0 otherwise.
1703 --------------------------------------------------------------------------*/
1704static inline u8 w9968cf_need_decompression(u16 palette)
1705{
1706 u8 i = 0;
1707 while (w9968cf_formatlist[i].palette != 0) {
1708 if (palette == w9968cf_formatlist[i].palette)
1709 return w9968cf_formatlist[i].compression;
1710 i++;
1711 }
1712 return 0;
1713}
1714
1715
1716/*--------------------------------------------------------------------------
1717 Change the picture settings of the camera.
1718 Return 0 on success, a negative number otherwise.
1719 --------------------------------------------------------------------------*/
1720static int
1721w9968cf_set_picture(struct w9968cf_device* cam, struct video_picture pict)
1722{
1723 u16 fmt, hw_depth, hw_palette, reg_v = 0x0000;
1724 int err = 0;
1725
1726 /* Make sure we are using a valid depth */
1727 pict.depth = w9968cf_valid_depth(pict.palette);
1728
1729 fmt = pict.palette;
1730
1731 hw_depth = pict.depth; /* depth used by the winbond chip */
1732 hw_palette = pict.palette; /* palette used by the winbond chip */
1733
1734 /* VS & HS polarities */
1735 reg_v = (cam->vs_polarity << 12) | (cam->hs_polarity << 11);
1736
1737 switch (fmt)
1738 {
1739 case VIDEO_PALETTE_UYVY:
1740 reg_v |= 0x0000;
1741 cam->vpp_flag = VPP_NONE;
1742 break;
1743 case VIDEO_PALETTE_YUV422P:
1744 reg_v |= 0x0002;
1745 cam->vpp_flag = VPP_DECOMPRESSION;
1746 break;
1747 case VIDEO_PALETTE_YUV420:
1748 case VIDEO_PALETTE_YUV420P:
1749 reg_v |= 0x0003;
1750 cam->vpp_flag = VPP_DECOMPRESSION;
1751 break;
1752 case VIDEO_PALETTE_YUYV:
1753 case VIDEO_PALETTE_YUV422:
1754 reg_v |= 0x0000;
1755 cam->vpp_flag = VPP_SWAP_YUV_BYTES;
1756 hw_palette = VIDEO_PALETTE_UYVY;
1757 break;
1758 /* Original video is used instead of RGBX palettes.
1759 Software conversion later. */
1760 case VIDEO_PALETTE_GREY:
1761 case VIDEO_PALETTE_RGB555:
1762 case VIDEO_PALETTE_RGB565:
1763 case VIDEO_PALETTE_RGB24:
1764 case VIDEO_PALETTE_RGB32:
1765 reg_v |= 0x0000; /* UYVY 16 bit is used */
1766 hw_depth = 16;
1767 hw_palette = VIDEO_PALETTE_UYVY;
1768 cam->vpp_flag = VPP_UYVY_TO_RGBX;
1769 break;
1770 }
1771
1772 /* NOTE: due to memory issues, it is better to disable the hardware
1773 double buffering during compression */
1774 if (cam->double_buffer && !(cam->vpp_flag & VPP_DECOMPRESSION))
1775 reg_v |= 0x0080;
1776
1777 if (cam->clamping)
1778 reg_v |= 0x0020;
1779
1780 if (cam->filter_type == 1)
1781 reg_v |= 0x0008;
1782 else if (cam->filter_type == 2)
1783 reg_v |= 0x000c;
1784
1785 if ((err = w9968cf_write_reg(cam, reg_v, 0x16)))
1786 goto error;
1787
1788 if ((err = w9968cf_sensor_update_picture(cam, pict)))
1789 goto error;
1790
1791 /* If all went well, update the device data structure */
1792 memcpy(&cam->picture, &pict, sizeof(pict));
1793 cam->hw_depth = hw_depth;
1794 cam->hw_palette = hw_palette;
1795
1796 /* Settings changed, so we clear the frame buffers */
1797 memset(cam->frame[0].buffer, 0, cam->nbuffers*cam->frame[0].size);
1798
1799 DBG(4, "Palette is %s, depth is %u bpp",
1800 symbolic(v4l1_plist, pict.palette), pict.depth)
1801
1802 return 0;
1803
1804error:
1805 DBG(1, "Failed to change picture settings")
1806 return err;
1807}
1808
1809
1810/*--------------------------------------------------------------------------
1811 Change the capture area size of the camera.
1812 This function _must_ be called _after_ w9968cf_set_picture().
1813 Return 0 on success, a negative number otherwise.
1814 --------------------------------------------------------------------------*/
1815static int
1816w9968cf_set_window(struct w9968cf_device* cam, struct video_window win)
1817{
1818 u16 x, y, w, h, scx, scy, cw, ch, ax, ay;
1819 unsigned long fw, fh;
1820 struct ovcamchip_window s_win;
1821 int err = 0;
1822
1823 /* Work around to avoid FP arithmetics */
1824 #define __SC(x) ((x) << 10)
1825 #define __UNSC(x) ((x) >> 10)
1826
1827 /* Make sure we are using a supported resolution */
1828 if ((err = w9968cf_adjust_window_size(cam, (u16*)&win.width,
1829 (u16*)&win.height)))
1830 goto error;
1831
1832 /* Scaling factors */
1833 fw = __SC(win.width) / cam->maxwidth;
1834 fh = __SC(win.height) / cam->maxheight;
1835
1836 /* Set up the width and height values used by the chip */
1837 if ((win.width > cam->maxwidth) || (win.height > cam->maxheight)) {
1838 cam->vpp_flag |= VPP_UPSCALE;
1839 /* Calculate largest w,h mantaining the same w/h ratio */
1840 w = (fw >= fh) ? cam->maxwidth : __SC(win.width)/fh;
1841 h = (fw >= fh) ? __SC(win.height)/fw : cam->maxheight;
1842 if (w < cam->minwidth) /* just in case */
1843 w = cam->minwidth;
1844 if (h < cam->minheight) /* just in case */
1845 h = cam->minheight;
1846 } else {
1847 cam->vpp_flag &= ~VPP_UPSCALE;
1848 w = win.width;
1849 h = win.height;
1850 }
1851
1852 /* x,y offsets of the cropped area */
1853 scx = cam->start_cropx;
1854 scy = cam->start_cropy;
1855
1856 /* Calculate cropped area manteining the right w/h ratio */
1857 if (cam->largeview && !(cam->vpp_flag & VPP_UPSCALE)) {
1858 cw = (fw >= fh) ? cam->maxwidth : __SC(win.width)/fh;
1859 ch = (fw >= fh) ? __SC(win.height)/fw : cam->maxheight;
1860 } else {
1861 cw = w;
1862 ch = h;
1863 }
1864
1865 /* Setup the window of the sensor */
1866 s_win.format = VIDEO_PALETTE_UYVY;
1867 s_win.width = cam->maxwidth;
1868 s_win.height = cam->maxheight;
1869 s_win.quarter = 0; /* full progressive video */
1870
1871 /* Center it */
1872 s_win.x = (s_win.width - cw) / 2;
1873 s_win.y = (s_win.height - ch) / 2;
1874
1875 /* Clock divisor */
1876 if (cam->clockdiv >= 0)
1877 s_win.clockdiv = cam->clockdiv; /* manual override */
1878 else
1879 switch (cam->sensor) {
1880 case CC_OV6620:
1881 s_win.clockdiv = 0;
1882 break;
1883 case CC_OV6630:
1884 s_win.clockdiv = 0;
1885 break;
1886 case CC_OV76BE:
1887 case CC_OV7610:
1888 case CC_OV7620:
1889 s_win.clockdiv = 0;
1890 break;
1891 default:
1892 s_win.clockdiv = W9968CF_DEF_CLOCKDIVISOR;
1893 }
1894
1895 /* We have to scale win.x and win.y offsets */
1896 if ( (cam->largeview && !(cam->vpp_flag & VPP_UPSCALE))
1897 || (cam->vpp_flag & VPP_UPSCALE) ) {
1898 ax = __SC(win.x)/fw;
1899 ay = __SC(win.y)/fh;
1900 } else {
1901 ax = win.x;
1902 ay = win.y;
1903 }
1904
1905 if ((ax + cw) > cam->maxwidth)
1906 ax = cam->maxwidth - cw;
1907
1908 if ((ay + ch) > cam->maxheight)
1909 ay = cam->maxheight - ch;
1910
1911 /* Adjust win.x, win.y */
1912 if ( (cam->largeview && !(cam->vpp_flag & VPP_UPSCALE))
1913 || (cam->vpp_flag & VPP_UPSCALE) ) {
1914 win.x = __UNSC(ax*fw);
1915 win.y = __UNSC(ay*fh);
1916 } else {
1917 win.x = ax;
1918 win.y = ay;
1919 }
1920
1921 /* Offsets used by the chip */
1922 x = ax + s_win.x;
1923 y = ay + s_win.y;
1924
1925 /* Go ! */
1926 if ((err = w9968cf_sensor_cmd(cam, OVCAMCHIP_CMD_S_MODE, &s_win)))
1927 goto error;
1928
1929 err += w9968cf_write_reg(cam, scx + x, 0x10);
1930 err += w9968cf_write_reg(cam, scy + y, 0x11);
1931 err += w9968cf_write_reg(cam, scx + x + cw, 0x12);
1932 err += w9968cf_write_reg(cam, scy + y + ch, 0x13);
1933 err += w9968cf_write_reg(cam, w, 0x14);
1934 err += w9968cf_write_reg(cam, h, 0x15);
1935
1936 /* JPEG width & height */
1937 err += w9968cf_write_reg(cam, w, 0x30);
1938 err += w9968cf_write_reg(cam, h, 0x31);
1939
1940 /* Y & UV frame buffer strides (in WORD) */
1941 if (cam->vpp_flag & VPP_DECOMPRESSION) {
1942 err += w9968cf_write_reg(cam, w/2, 0x2c);
1943 err += w9968cf_write_reg(cam, w/4, 0x2d);
1944 } else
1945 err += w9968cf_write_reg(cam, w, 0x2c);
1946
1947 if (err)
1948 goto error;
1949
1950 /* If all went well, update the device data structure */
1951 memcpy(&cam->window, &win, sizeof(win));
1952 cam->hw_width = w;
1953 cam->hw_height = h;
1954
1955 /* Settings changed, so we clear the frame buffers */
1956 memset(cam->frame[0].buffer, 0, cam->nbuffers*cam->frame[0].size);
1957
1958 DBG(4, "The capture area is %dx%d, Offset (x,y)=(%u,%u)",
1959 win.width, win.height, win.x, win.y)
1960
1961 PDBGG("x=%u ,y=%u, w=%u, h=%u, ax=%u, ay=%u, s_win.x=%u, s_win.y=%u, "
1962 "cw=%u, ch=%u, win.x=%u, win.y=%u, win.width=%u, win.height=%u",
1963 x, y, w, h, ax, ay, s_win.x, s_win.y, cw, ch, win.x, win.y,
1964 win.width, win.height)
1965
1966 return 0;
1967
1968error:
1969 DBG(1, "Failed to change the capture area size")
1970 return err;
1971}
1972
1973
1974/*--------------------------------------------------------------------------
1975 Adjust the asked values for window width and height.
1976 Return 0 on success, -1 otherwise.
1977 --------------------------------------------------------------------------*/
1978static int
1979w9968cf_adjust_window_size(struct w9968cf_device* cam, u16* width, u16* height)
1980{
1981 u16 maxw, maxh;
1982
1983 if ((*width < cam->minwidth) || (*height < cam->minheight))
1984 return -ERANGE;
1985
1986 maxw = cam->upscaling && !(cam->vpp_flag & VPP_DECOMPRESSION) &&
1987 w9968cf_vpp ? max((u16)W9968CF_MAX_WIDTH, cam->maxwidth)
1988 : cam->maxwidth;
1989 maxh = cam->upscaling && !(cam->vpp_flag & VPP_DECOMPRESSION) &&
1990 w9968cf_vpp ? max((u16)W9968CF_MAX_HEIGHT, cam->maxheight)
1991 : cam->maxheight;
1992
1993 if (*width > maxw)
1994 *width = maxw;
1995 if (*height > maxh)
1996 *height = maxh;
1997
1998 if (cam->vpp_flag & VPP_DECOMPRESSION) {
1999 *width &= ~15L; /* multiple of 16 */
2000 *height &= ~15L;
2001 }
2002
2003 PDBGG("Window size adjusted w=%u, h=%u ", *width, *height)
2004
2005 return 0;
2006}
2007
2008
2009/*--------------------------------------------------------------------------
2010 Initialize the FIFO list of requested frames.
2011 --------------------------------------------------------------------------*/
2012static void w9968cf_init_framelist(struct w9968cf_device* cam)
2013{
2014 u8 i;
2015
2016 for (i = 0; i < cam->nbuffers; i++) {
2017 cam->requested_frame[i] = NULL;
2018 cam->frame[i].queued = 0;
2019 cam->frame[i].status = F_UNUSED;
2020 }
2021}
2022
2023
2024/*--------------------------------------------------------------------------
2025 Add a frame in the FIFO list of requested frames.
2026 This function is called in process context.
2027 --------------------------------------------------------------------------*/
2028static void w9968cf_push_frame(struct w9968cf_device* cam, u8 f_num)
2029{
2030 u8 f;
2031 unsigned long lock_flags;
2032
2033 spin_lock_irqsave(&cam->flist_lock, lock_flags);
2034
2035 for (f=0; cam->requested_frame[f] != NULL; f++);
2036 cam->requested_frame[f] = &cam->frame[f_num];
2037 cam->frame[f_num].queued = 1;
2038 cam->frame[f_num].status = F_UNUSED; /* clear the status */
2039
2040 spin_unlock_irqrestore(&cam->flist_lock, lock_flags);
2041
2042 DBG(6, "Frame #%u pushed into the FIFO list. Position %u", f_num, f)
2043}
2044
2045
2046/*--------------------------------------------------------------------------
2047 Read, store and remove the first pointer in the FIFO list of requested
2048 frames. This function is called in interrupt context.
2049 --------------------------------------------------------------------------*/
2050static void
2051w9968cf_pop_frame(struct w9968cf_device* cam, struct w9968cf_frame_t** framep)
2052{
2053 u8 i;
2054
2055 spin_lock(&cam->flist_lock);
2056
2057 *framep = cam->requested_frame[0];
2058
2059 /* Shift the list of pointers */
2060 for (i = 0; i < cam->nbuffers-1; i++)
2061 cam->requested_frame[i] = cam->requested_frame[i+1];
2062 cam->requested_frame[i] = NULL;
2063
2064 spin_unlock(&cam->flist_lock);
2065
2066 DBG(6,"Popped frame #%d from the list", (*framep)->number)
2067}
2068
2069
2070/*--------------------------------------------------------------------------
2071 High-level video post-processing routine on grabbed frames.
2072 Return 0 on success, a negative number otherwise.
2073 --------------------------------------------------------------------------*/
2074static int
2075w9968cf_postprocess_frame(struct w9968cf_device* cam,
2076 struct w9968cf_frame_t* fr)
2077{
2078 void *pIn = fr->buffer, *pOut = cam->frame_vpp.buffer, *tmp;
2079 u16 w = cam->window.width,
2080 h = cam->window.height,
2081 d = cam->picture.depth,
2082 fmt = cam->picture.palette,
2083 rgb = cam->force_rgb,
2084 hw_w = cam->hw_width,
2085 hw_h = cam->hw_height,
2086 hw_d = cam->hw_depth;
2087 int err = 0;
2088
2089 #define _PSWAP(pIn, pOut) {tmp = (pIn); (pIn) = (pOut); (pOut) = tmp;}
2090
2091 if (cam->vpp_flag & VPP_DECOMPRESSION) {
2092 memcpy(pOut, pIn, fr->length);
2093 _PSWAP(pIn, pOut)
2094 err = w9968cf_vpp->decode(pIn, fr->length, hw_w, hw_h, pOut);
2095 PDBGG("Compressed frame length: %lu",(unsigned long)fr->length)
2096 fr->length = (hw_w*hw_h*hw_d)/8;
2097 _PSWAP(pIn, pOut)
2098 if (err) {
2099 DBG(4, "An error occurred while decoding the frame: "
2100 "%s", symbolic(decoder_errlist, err))
2101 return err;
2102 } else
2103 DBG(6, "Frame decoded")
2104 }
2105
2106 if (cam->vpp_flag & VPP_SWAP_YUV_BYTES) {
2107 w9968cf_vpp->swap_yuvbytes(pIn, fr->length);
2108 DBG(6, "Original UYVY component ordering changed")
2109 }
2110
2111 if (cam->vpp_flag & VPP_UPSCALE) {
2112 w9968cf_vpp->scale_up(pIn, pOut, hw_w, hw_h, hw_d, w, h);
2113 fr->length = (w*h*hw_d)/8;
2114 _PSWAP(pIn, pOut)
2115 DBG(6, "Vertical up-scaling done: %u,%u,%ubpp->%u,%u",
2116 hw_w, hw_h, hw_d, w, h)
2117 }
2118
2119 if (cam->vpp_flag & VPP_UYVY_TO_RGBX) {
2120 w9968cf_vpp->uyvy_to_rgbx(pIn, fr->length, pOut, fmt, rgb);
2121 fr->length = (w*h*d)/8;
2122 _PSWAP(pIn, pOut)
2123 DBG(6, "UYVY-16bit to %s conversion done",
2124 symbolic(v4l1_plist, fmt))
2125 }
2126
2127 if (pOut == fr->buffer)
2128 memcpy(fr->buffer, cam->frame_vpp.buffer, fr->length);
2129
2130 return 0;
2131}
2132
2133
2134
2135/****************************************************************************
2136 * Image sensor control routines *
2137 ****************************************************************************/
2138
2139static int
2140w9968cf_sensor_set_control(struct w9968cf_device* cam, int cid, int val)
2141{
2142 struct ovcamchip_control ctl;
2143 int err;
2144
2145 ctl.id = cid;
2146 ctl.value = val;
2147
2148 err = w9968cf_sensor_cmd(cam, OVCAMCHIP_CMD_S_CTRL, &ctl);
2149
2150 return err;
2151}
2152
2153
2154static int
2155w9968cf_sensor_get_control(struct w9968cf_device* cam, int cid, int* val)
2156{
2157 struct ovcamchip_control ctl;
2158 int err;
2159
2160 ctl.id = cid;
2161
2162 err = w9968cf_sensor_cmd(cam, OVCAMCHIP_CMD_G_CTRL, &ctl);
2163 if (!err)
2164 *val = ctl.value;
2165
2166 return err;
2167}
2168
2169
2170static int
2171w9968cf_sensor_cmd(struct w9968cf_device* cam, unsigned int cmd, void* arg)
2172{
2173 struct i2c_client* c = cam->sensor_client;
2174 int rc = 0;
2175
2176 if (!c || !c->driver || !c->driver->command)
2177 return -EINVAL;
2178
2179 rc = c->driver->command(c, cmd, arg);
2180 /* The I2C driver returns -EPERM on non-supported controls */
2181 return (rc < 0 && rc != -EPERM) ? rc : 0;
2182}
2183
2184
2185/*--------------------------------------------------------------------------
2186 Update some settings of the image sensor.
2187 Returns: 0 on success, a negative number otherwise.
2188 --------------------------------------------------------------------------*/
2189static int w9968cf_sensor_update_settings(struct w9968cf_device* cam)
2190{
2191 int err = 0;
2192
2193 /* Auto brightness */
2194 err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_AUTOBRIGHT,
2195 cam->auto_brt);
2196 if (err)
2197 return err;
2198
2199 /* Auto exposure */
2200 err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_AUTOEXP,
2201 cam->auto_exp);
2202 if (err)
2203 return err;
2204
2205 /* Banding filter */
2206 err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_BANDFILT,
2207 cam->bandfilt);
2208 if (err)
2209 return err;
2210
2211 /* Light frequency */
2212 err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_FREQ,
2213 cam->lightfreq);
2214 if (err)
2215 return err;
2216
2217 /* Back light */
2218 err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_BACKLIGHT,
2219 cam->backlight);
2220 if (err)
2221 return err;
2222
2223 /* Mirror */
2224 err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_MIRROR,
2225 cam->mirror);
2226 if (err)
2227 return err;
2228
2229 return 0;
2230}
2231
2232
2233/*--------------------------------------------------------------------------
2234 Get some current picture settings from the image sensor and update the
2235 internal 'picture' structure of the camera.
2236 Returns: 0 on success, a negative number otherwise.
2237 --------------------------------------------------------------------------*/
2238static int w9968cf_sensor_get_picture(struct w9968cf_device* cam)
2239{
2240 int err, v;
2241
2242 err = w9968cf_sensor_get_control(cam, OVCAMCHIP_CID_CONT, &v);
2243 if (err)
2244 return err;
2245 cam->picture.contrast = v;
2246
2247 err = w9968cf_sensor_get_control(cam, OVCAMCHIP_CID_BRIGHT, &v);
2248 if (err)
2249 return err;
2250 cam->picture.brightness = v;
2251
2252 err = w9968cf_sensor_get_control(cam, OVCAMCHIP_CID_SAT, &v);
2253 if (err)
2254 return err;
2255 cam->picture.colour = v;
2256
2257 err = w9968cf_sensor_get_control(cam, OVCAMCHIP_CID_HUE, &v);
2258 if (err)
2259 return err;
2260 cam->picture.hue = v;
2261
2262 DBG(5, "Got picture settings from the image sensor")
2263
2264 PDBGG("Brightness, contrast, hue, colour, whiteness are "
2265 "%u,%u,%u,%u,%u", cam->picture.brightness,cam->picture.contrast,
2266 cam->picture.hue, cam->picture.colour, cam->picture.whiteness)
2267
2268 return 0;
2269}
2270
2271
2272/*--------------------------------------------------------------------------
2273 Update picture settings of the image sensor.
2274 Returns: 0 on success, a negative number otherwise.
2275 --------------------------------------------------------------------------*/
2276static int
2277w9968cf_sensor_update_picture(struct w9968cf_device* cam,
2278 struct video_picture pict)
2279{
2280 int err = 0;
2281
2282 if ((!cam->sensor_initialized)
2283 || pict.contrast != cam->picture.contrast) {
2284 err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_CONT,
2285 pict.contrast);
2286 if (err)
2287 goto fail;
2288 DBG(4, "Contrast changed from %u to %u",
2289 cam->picture.contrast, pict.contrast)
2290 cam->picture.contrast = pict.contrast;
2291 }
2292
2293 if (((!cam->sensor_initialized) ||
2294 pict.brightness != cam->picture.brightness) && (!cam->auto_brt)) {
2295 err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_BRIGHT,
2296 pict.brightness);
2297 if (err)
2298 goto fail;
2299 DBG(4, "Brightness changed from %u to %u",
2300 cam->picture.brightness, pict.brightness)
2301 cam->picture.brightness = pict.brightness;
2302 }
2303
2304 if ((!cam->sensor_initialized) || pict.colour != cam->picture.colour) {
2305 err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_SAT,
2306 pict.colour);
2307 if (err)
2308 goto fail;
2309 DBG(4, "Colour changed from %u to %u",
2310 cam->picture.colour, pict.colour)
2311 cam->picture.colour = pict.colour;
2312 }
2313
2314 if ((!cam->sensor_initialized) || pict.hue != cam->picture.hue) {
2315 err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_HUE,
2316 pict.hue);
2317 if (err)
2318 goto fail;
2319 DBG(4, "Hue changed from %u to %u",
2320 cam->picture.hue, pict.hue)
2321 cam->picture.hue = pict.hue;
2322 }
2323
2324 return 0;
2325
2326fail:
2327 DBG(4, "Failed to change sensor picture setting")
2328 return err;
2329}
2330
2331
2332
2333/****************************************************************************
2334 * Camera configuration *
2335 ****************************************************************************/
2336
2337/*--------------------------------------------------------------------------
2338 This function is called when a supported image sensor is detected.
2339 Return 0 if the initialization succeeds, a negative number otherwise.
2340 --------------------------------------------------------------------------*/
2341static int w9968cf_sensor_init(struct w9968cf_device* cam)
2342{
2343 int err = 0;
2344
2345 if ((err = w9968cf_sensor_cmd(cam, OVCAMCHIP_CMD_INITIALIZE,
2346 &cam->monochrome)))
2347 goto error;
2348
2349 if ((err = w9968cf_sensor_cmd(cam, OVCAMCHIP_CMD_Q_SUBTYPE,
2350 &cam->sensor)))
2351 goto error;
2352
2353 /* NOTE: Make sure width and height are a multiple of 16 */
2354 switch (cam->sensor_client->addr) {
2355 case OV6xx0_SID:
2356 cam->maxwidth = 352;
2357 cam->maxheight = 288;
2358 cam->minwidth = 64;
2359 cam->minheight = 48;
2360 break;
2361 case OV7xx0_SID:
2362 cam->maxwidth = 640;
2363 cam->maxheight = 480;
2364 cam->minwidth = 64;
2365 cam->minheight = 48;
2366 break;
2367 default:
2368 DBG(1, "Not supported image sensor detected for %s",
2369 symbolic(camlist, cam->id))
2370 return -EINVAL;
2371 }
2372
2373 /* These values depend on the ones in the ovxxx0.c sources */
2374 switch (cam->sensor) {
2375 case CC_OV7620:
2376 cam->start_cropx = 287;
2377 cam->start_cropy = 35;
2378 /* Seems to work around a bug in the image sensor */
2379 cam->vs_polarity = 1;
2380 cam->hs_polarity = 1;
2381 break;
2382 default:
2383 cam->start_cropx = 320;
2384 cam->start_cropy = 35;
2385 cam->vs_polarity = 1;
2386 cam->hs_polarity = 0;
2387 }
2388
2389 if ((err = w9968cf_sensor_update_settings(cam)))
2390 goto error;
2391
2392 if ((err = w9968cf_sensor_update_picture(cam, cam->picture)))
2393 goto error;
2394
2395 cam->sensor_initialized = 1;
2396
2397 DBG(2, "%s image sensor initialized", symbolic(senlist, cam->sensor))
2398 return 0;
2399
2400error:
2401 cam->sensor_initialized = 0;
2402 cam->sensor = CC_UNKNOWN;
2403 DBG(1, "Image sensor initialization failed for %s (/dev/video%d). "
2404 "Try to detach and attach this device again",
2405 symbolic(camlist, cam->id), cam->v4ldev->minor)
2406 return err;
2407}
2408
2409
2410/*--------------------------------------------------------------------------
2411 Fill some basic fields in the main device data structure.
2412 This function is called once on w9968cf_usb_probe() for each recognized
2413 camera.
2414 --------------------------------------------------------------------------*/
2415static void
2416w9968cf_configure_camera(struct w9968cf_device* cam,
2417 struct usb_device* udev,
2418 enum w9968cf_model_id mod_id,
2419 const unsigned short dev_nr)
2420{
2421 init_MUTEX(&cam->fileop_sem);
2422 init_waitqueue_head(&cam->open);
2423 spin_lock_init(&cam->urb_lock);
2424 spin_lock_init(&cam->flist_lock);
2425
2426 cam->users = 0;
2427 cam->disconnected = 0;
2428 cam->id = mod_id;
2429 cam->sensor = CC_UNKNOWN;
2430 cam->sensor_initialized = 0;
2431
2432 /* Calculate the alternate setting number (from 1 to 16)
2433 according to the 'packet_size' module parameter */
2434 if (packet_size[dev_nr] < W9968CF_MIN_PACKET_SIZE)
2435 packet_size[dev_nr] = W9968CF_MIN_PACKET_SIZE;
2436 for (cam->altsetting = 1;
2437 packet_size[dev_nr] < wMaxPacketSize[cam->altsetting-1];
2438 cam->altsetting++);
2439
2440 cam->max_buffers = (max_buffers[dev_nr] < 2 ||
2441 max_buffers[dev_nr] > W9968CF_MAX_BUFFERS)
2442 ? W9968CF_BUFFERS : (u8)max_buffers[dev_nr];
2443
2444 cam->double_buffer = (double_buffer[dev_nr] == 0 ||
2445 double_buffer[dev_nr] == 1)
2446 ? (u8)double_buffer[dev_nr]:W9968CF_DOUBLE_BUFFER;
2447
2448 cam->clamping = (clamping[dev_nr] == 0 || clamping[dev_nr] == 1)
2449 ? (u8)clamping[dev_nr] : W9968CF_CLAMPING;
2450
2451 cam->filter_type = (filter_type[dev_nr] == 0 ||
2452 filter_type[dev_nr] == 1 ||
2453 filter_type[dev_nr] == 2)
2454 ? (u8)filter_type[dev_nr] : W9968CF_FILTER_TYPE;
2455
2456 cam->capture = 1;
2457
2458 cam->largeview = (largeview[dev_nr] == 0 || largeview[dev_nr] == 1)
2459 ? (u8)largeview[dev_nr] : W9968CF_LARGEVIEW;
2460
2461 cam->decompression = (decompression[dev_nr] == 0 ||
2462 decompression[dev_nr] == 1 ||
2463 decompression[dev_nr] == 2)
2464 ? (u8)decompression[dev_nr]:W9968CF_DECOMPRESSION;
2465
2466 cam->upscaling = (upscaling[dev_nr] == 0 ||
2467 upscaling[dev_nr] == 1)
2468 ? (u8)upscaling[dev_nr] : W9968CF_UPSCALING;
2469
2470 cam->auto_brt = (autobright[dev_nr] == 0 || autobright[dev_nr] == 1)
2471 ? (u8)autobright[dev_nr] : W9968CF_AUTOBRIGHT;
2472
2473 cam->auto_exp = (autoexp[dev_nr] == 0 || autoexp[dev_nr] == 1)
2474 ? (u8)autoexp[dev_nr] : W9968CF_AUTOEXP;
2475
2476 cam->lightfreq = (lightfreq[dev_nr] == 50 || lightfreq[dev_nr] == 60)
2477 ? (u8)lightfreq[dev_nr] : W9968CF_LIGHTFREQ;
2478
2479 cam->bandfilt = (bandingfilter[dev_nr] == 0 ||
2480 bandingfilter[dev_nr] == 1)
2481 ? (u8)bandingfilter[dev_nr] : W9968CF_BANDINGFILTER;
2482
2483 cam->backlight = (backlight[dev_nr] == 0 || backlight[dev_nr] == 1)
2484 ? (u8)backlight[dev_nr] : W9968CF_BACKLIGHT;
2485
2486 cam->clockdiv = (clockdiv[dev_nr] == -1 || clockdiv[dev_nr] >= 0)
2487 ? (s8)clockdiv[dev_nr] : W9968CF_CLOCKDIV;
2488
2489 cam->mirror = (mirror[dev_nr] == 0 || mirror[dev_nr] == 1)
2490 ? (u8)mirror[dev_nr] : W9968CF_MIRROR;
2491
2492 cam->monochrome = (monochrome[dev_nr] == 0 || monochrome[dev_nr] == 1)
2493 ? monochrome[dev_nr] : W9968CF_MONOCHROME;
2494
2495 cam->picture.brightness = (u16)brightness[dev_nr];
2496 cam->picture.hue = (u16)hue[dev_nr];
2497 cam->picture.colour = (u16)colour[dev_nr];
2498 cam->picture.contrast = (u16)contrast[dev_nr];
2499 cam->picture.whiteness = (u16)whiteness[dev_nr];
2500 if (w9968cf_valid_palette((u16)force_palette[dev_nr])) {
2501 cam->picture.palette = (u16)force_palette[dev_nr];
2502 cam->force_palette = 1;
2503 } else {
2504 cam->force_palette = 0;
2505 if (cam->decompression == 0)
2506 cam->picture.palette = W9968CF_PALETTE_DECOMP_OFF;
2507 else if (cam->decompression == 1)
2508 cam->picture.palette = W9968CF_PALETTE_DECOMP_FORCE;
2509 else
2510 cam->picture.palette = W9968CF_PALETTE_DECOMP_ON;
2511 }
2512 cam->picture.depth = w9968cf_valid_depth(cam->picture.palette);
2513
2514 cam->force_rgb = (force_rgb[dev_nr] == 0 || force_rgb[dev_nr] == 1)
2515 ? (u8)force_rgb[dev_nr] : W9968CF_FORCE_RGB;
2516
2517 cam->window.x = 0;
2518 cam->window.y = 0;
2519 cam->window.width = W9968CF_WIDTH;
2520 cam->window.height = W9968CF_HEIGHT;
2521 cam->window.chromakey = 0;
2522 cam->window.clipcount = 0;
2523 cam->window.flags = 0;
2524
2525 DBG(3, "%s configured with settings #%u:",
2526 symbolic(camlist, cam->id), dev_nr)
2527
2528 DBG(3, "- Data packet size for USB isochrnous transfer: %u bytes",
2529 wMaxPacketSize[cam->altsetting-1])
2530
2531 DBG(3, "- Number of requested video frame buffers: %u",
2532 cam->max_buffers)
2533
2534 if (cam->double_buffer)
2535 DBG(3, "- Hardware double buffering enabled")
2536 else
2537 DBG(3, "- Hardware double buffering disabled")
2538
2539 if (cam->filter_type == 0)
2540 DBG(3, "- Video filtering disabled")
2541 else if (cam->filter_type == 1)
2542 DBG(3, "- Video filtering enabled: type 1-2-1")
2543 else if (cam->filter_type == 2)
2544 DBG(3, "- Video filtering enabled: type 2-3-6-3-2")
2545
2546 if (cam->clamping)
2547 DBG(3, "- Video data clamping (CCIR-601 format) enabled")
2548 else
2549 DBG(3, "- Video data clamping (CCIR-601 format) disabled")
2550
2551 if (cam->largeview)
2552 DBG(3, "- Large view enabled")
2553 else
2554 DBG(3, "- Large view disabled")
2555
2556 if ((cam->decompression) == 0 && (!cam->force_palette))
2557 DBG(3, "- Decompression disabled")
2558 else if ((cam->decompression) == 1 && (!cam->force_palette))
2559 DBG(3, "- Decompression forced")
2560 else if ((cam->decompression) == 2 && (!cam->force_palette))
2561 DBG(3, "- Decompression allowed")
2562
2563 if (cam->upscaling)
2564 DBG(3, "- Software image scaling enabled")
2565 else
2566 DBG(3, "- Software image scaling disabled")
2567
2568 if (cam->force_palette)
2569 DBG(3, "- Image palette forced to %s",
2570 symbolic(v4l1_plist, cam->picture.palette))
2571
2572 if (cam->force_rgb)
2573 DBG(3, "- RGB component ordering will be used instead of BGR")
2574
2575 if (cam->auto_brt)
2576 DBG(3, "- Auto brightness enabled")
2577 else
2578 DBG(3, "- Auto brightness disabled")
2579
2580 if (cam->auto_exp)
2581 DBG(3, "- Auto exposure enabled")
2582 else
2583 DBG(3, "- Auto exposure disabled")
2584
2585 if (cam->backlight)
2586 DBG(3, "- Backlight exposure algorithm enabled")
2587 else
2588 DBG(3, "- Backlight exposure algorithm disabled")
2589
2590 if (cam->mirror)
2591 DBG(3, "- Mirror enabled")
2592 else
2593 DBG(3, "- Mirror disabled")
2594
2595 if (cam->bandfilt)
2596 DBG(3, "- Banding filter enabled")
2597 else
2598 DBG(3, "- Banding filter disabled")
2599
2600 DBG(3, "- Power lighting frequency: %u", cam->lightfreq)
2601
2602 if (cam->clockdiv == -1)
2603 DBG(3, "- Automatic clock divisor enabled")
2604 else
2605 DBG(3, "- Clock divisor: %d", cam->clockdiv)
2606
2607 if (cam->monochrome)
2608 DBG(3, "- Image sensor used as monochrome")
2609 else
2610 DBG(3, "- Image sensor not used as monochrome")
2611}
2612
2613
2614/*--------------------------------------------------------------------------
2615 If the video post-processing module is not loaded, some parameters
2616 must be overridden.
2617 --------------------------------------------------------------------------*/
2618static void w9968cf_adjust_configuration(struct w9968cf_device* cam)
2619{
2620 if (!w9968cf_vpp) {
2621 if (cam->decompression == 1) {
2622 cam->decompression = 2;
2623 DBG(2, "Video post-processing module not found: "
2624 "'decompression' parameter forced to 2")
2625 }
2626 if (cam->upscaling) {
2627 cam->upscaling = 0;
2628 DBG(2, "Video post-processing module not found: "
2629 "'upscaling' parameter forced to 0")
2630 }
2631 if (cam->picture.palette != VIDEO_PALETTE_UYVY) {
2632 cam->force_palette = 0;
2633 DBG(2, "Video post-processing module not found: "
2634 "'force_palette' parameter forced to 0")
2635 }
2636 cam->picture.palette = VIDEO_PALETTE_UYVY;
2637 cam->picture.depth = w9968cf_valid_depth(cam->picture.palette);
2638 }
2639}
2640
2641
2642/*--------------------------------------------------------------------------
2643 Release the resources used by the driver.
2644 This function is called on disconnect
2645 (or on close if deallocation has been deferred)
2646 --------------------------------------------------------------------------*/
2647static void w9968cf_release_resources(struct w9968cf_device* cam)
2648{
2649 down(&w9968cf_devlist_sem);
2650
2651 DBG(2, "V4L device deregistered: /dev/video%d", cam->v4ldev->minor)
2652
2653 video_unregister_device(cam->v4ldev);
2654 list_del(&cam->v4llist);
2655 i2c_del_adapter(&cam->i2c_adapter);
2656 w9968cf_deallocate_memory(cam);
2657 kfree(cam->control_buffer);
2658 kfree(cam->data_buffer);
2659
2660 up(&w9968cf_devlist_sem);
2661}
2662
2663
2664
2665/****************************************************************************
2666 * Video4Linux interface *
2667 ****************************************************************************/
2668
2669static int w9968cf_open(struct inode* inode, struct file* filp)
2670{
2671 struct w9968cf_device* cam;
2672 int err;
2673
2674 /* This the only safe way to prevent race conditions with disconnect */
2675 if (!down_read_trylock(&w9968cf_disconnect))
2676 return -ERESTARTSYS;
2677
2678 cam = (struct w9968cf_device*)video_get_drvdata(video_devdata(filp));
2679
2680 down(&cam->dev_sem);
2681
2682 if (cam->sensor == CC_UNKNOWN) {
2683 DBG(2, "No supported image sensor has been detected by the "
2684 "'ovcamchip' module for the %s (/dev/video%d). Make "
2685 "sure it is loaded *before* (re)connecting the camera.",
2686 symbolic(camlist, cam->id), cam->v4ldev->minor)
2687 up(&cam->dev_sem);
2688 up_read(&w9968cf_disconnect);
2689 return -ENODEV;
2690 }
2691
2692 if (cam->users) {
2693 DBG(2, "%s (/dev/video%d) has been already occupied by '%s'",
2694 symbolic(camlist, cam->id),cam->v4ldev->minor,cam->command)
2695 if ((filp->f_flags & O_NONBLOCK)||(filp->f_flags & O_NDELAY)) {
2696 up(&cam->dev_sem);
2697 up_read(&w9968cf_disconnect);
2698 return -EWOULDBLOCK;
2699 }
2700 up(&cam->dev_sem);
2701 err = wait_event_interruptible_exclusive(cam->open,
2702 cam->disconnected ||
2703 !cam->users);
2704 if (err) {
2705 up_read(&w9968cf_disconnect);
2706 return err;
2707 }
2708 if (cam->disconnected) {
2709 up_read(&w9968cf_disconnect);
2710 return -ENODEV;
2711 }
2712 down(&cam->dev_sem);
2713 }
2714
2715 DBG(5, "Opening '%s', /dev/video%d ...",
2716 symbolic(camlist, cam->id), cam->v4ldev->minor)
2717
2718 cam->streaming = 0;
2719 cam->misconfigured = 0;
2720
7f2c01ab 2721 w9968cf_adjust_configuration(cam);
1da177e4
LT
2722
2723 if ((err = w9968cf_allocate_memory(cam)))
2724 goto deallocate_memory;
2725
2726 if ((err = w9968cf_init_chip(cam)))
2727 goto deallocate_memory;
2728
2729 if ((err = w9968cf_start_transfer(cam)))
2730 goto deallocate_memory;
2731
2732 filp->private_data = cam;
2733
2734 cam->users++;
2735 strcpy(cam->command, current->comm);
2736
2737 init_waitqueue_head(&cam->wait_queue);
2738
2739 DBG(5, "Video device is open")
2740
2741 up(&cam->dev_sem);
2742 up_read(&w9968cf_disconnect);
2743
2744 return 0;
2745
2746deallocate_memory:
2747 w9968cf_deallocate_memory(cam);
1da177e4
LT
2748 DBG(2, "Failed to open the video device")
2749 up(&cam->dev_sem);
2750 up_read(&w9968cf_disconnect);
2751 return err;
2752}
2753
2754
2755static int w9968cf_release(struct inode* inode, struct file* filp)
2756{
2757 struct w9968cf_device* cam;
2758
2759 cam = (struct w9968cf_device*)video_get_drvdata(video_devdata(filp));
2760
2761 down(&cam->dev_sem); /* prevent disconnect() to be called */
2762
2763 w9968cf_stop_transfer(cam);
2764
1da177e4
LT
2765 if (cam->disconnected) {
2766 w9968cf_release_resources(cam);
2767 up(&cam->dev_sem);
2768 kfree(cam);
2769 return 0;
2770 }
2771
2772 cam->users--;
2773 w9968cf_deallocate_memory(cam);
2774 wake_up_interruptible_nr(&cam->open, 1);
2775
2776 DBG(5, "Video device closed")
2777 up(&cam->dev_sem);
2778 return 0;
2779}
2780
2781
2782static ssize_t
2783w9968cf_read(struct file* filp, char __user * buf, size_t count, loff_t* f_pos)
2784{
2785 struct w9968cf_device* cam;
2786 struct w9968cf_frame_t* fr;
2787 int err = 0;
2788
2789 cam = (struct w9968cf_device*)video_get_drvdata(video_devdata(filp));
2790
2791 if (filp->f_flags & O_NONBLOCK)
2792 return -EWOULDBLOCK;
2793
2794 if (down_interruptible(&cam->fileop_sem))
2795 return -ERESTARTSYS;
2796
2797 if (cam->disconnected) {
2798 DBG(2, "Device not present")
2799 up(&cam->fileop_sem);
2800 return -ENODEV;
2801 }
2802
2803 if (cam->misconfigured) {
2804 DBG(2, "The camera is misconfigured. Close and open it again.")
2805 up(&cam->fileop_sem);
2806 return -EIO;
2807 }
2808
2809 if (!cam->frame[0].queued)
2810 w9968cf_push_frame(cam, 0);
2811
2812 if (!cam->frame[1].queued)
2813 w9968cf_push_frame(cam, 1);
2814
2815 err = wait_event_interruptible(cam->wait_queue,
2816 cam->frame[0].status == F_READY ||
2817 cam->frame[1].status == F_READY ||
2818 cam->disconnected);
2819 if (err) {
2820 up(&cam->fileop_sem);
2821 return err;
2822 }
2823 if (cam->disconnected) {
2824 up(&cam->fileop_sem);
2825 return -ENODEV;
2826 }
2827
2828 fr = (cam->frame[0].status == F_READY) ? &cam->frame[0]:&cam->frame[1];
2829
2830 if (w9968cf_vpp)
2831 w9968cf_postprocess_frame(cam, fr);
2832
2833 if (count > fr->length)
2834 count = fr->length;
2835
2836 if (copy_to_user(buf, fr->buffer, count)) {
2837 fr->status = F_UNUSED;
2838 up(&cam->fileop_sem);
2839 return -EFAULT;
2840 }
2841 *f_pos += count;
2842
2843 fr->status = F_UNUSED;
2844
2845 DBG(5, "%zu bytes read", count)
2846
2847 up(&cam->fileop_sem);
2848 return count;
2849}
2850
2851
2852static int w9968cf_mmap(struct file* filp, struct vm_area_struct *vma)
2853{
2854 struct w9968cf_device* cam = (struct w9968cf_device*)
2855 video_get_drvdata(video_devdata(filp));
2856 unsigned long vsize = vma->vm_end - vma->vm_start,
2857 psize = cam->nbuffers * cam->frame[0].size,
2858 start = vma->vm_start,
2859 pos = (unsigned long)cam->frame[0].buffer,
2860 page;
2861
2862 if (cam->disconnected) {
2863 DBG(2, "Device not present")
2864 return -ENODEV;
2865 }
2866
2867 if (cam->misconfigured) {
2868 DBG(2, "The camera is misconfigured. Close and open it again")
2869 return -EIO;
2870 }
2871
2872 PDBGG("mmapping %lu bytes...", vsize)
2873
2874 if (vsize > psize - (vma->vm_pgoff << PAGE_SHIFT))
2875 return -EINVAL;
2876
2877 while (vsize > 0) {
2878 page = vmalloc_to_pfn((void *)pos);
2879 if (remap_pfn_range(vma, start, page + vma->vm_pgoff,
2880 PAGE_SIZE, vma->vm_page_prot))
2881 return -EAGAIN;
2882 start += PAGE_SIZE;
2883 pos += PAGE_SIZE;
2884 vsize -= PAGE_SIZE;
2885 }
2886
2887 DBG(5, "mmap method successfully called")
2888 return 0;
2889}
2890
2891
2892static int
2893w9968cf_ioctl(struct inode* inode, struct file* filp,
2894 unsigned int cmd, unsigned long arg)
2895{
2896 struct w9968cf_device* cam;
2897 int err;
2898
2899 cam = (struct w9968cf_device*)video_get_drvdata(video_devdata(filp));
2900
2901 if (down_interruptible(&cam->fileop_sem))
2902 return -ERESTARTSYS;
2903
2904 if (cam->disconnected) {
2905 DBG(2, "Device not present")
2906 up(&cam->fileop_sem);
2907 return -ENODEV;
2908 }
2909
2910 if (cam->misconfigured) {
2911 DBG(2, "The camera is misconfigured. Close and open it again.")
2912 up(&cam->fileop_sem);
2913 return -EIO;
2914 }
2915
2916 err = w9968cf_v4l_ioctl(inode, filp, cmd, (void __user *)arg);
2917
2918 up(&cam->fileop_sem);
2919 return err;
2920}
2921
2922
2923static int w9968cf_v4l_ioctl(struct inode* inode, struct file* filp,
2924 unsigned int cmd, void __user * arg)
2925{
2926 struct w9968cf_device* cam;
2927 const char* v4l1_ioctls[] = {
2928 "?", "CGAP", "GCHAN", "SCHAN", "GTUNER", "STUNER",
2929 "GPICT", "SPICT", "CCAPTURE", "GWIN", "SWIN", "GFBUF",
2930 "SFBUF", "KEY", "GFREQ", "SFREQ", "GAUDIO", "SAUDIO",
2931 "SYNC", "MCAPTURE", "GMBUF", "GUNIT", "GCAPTURE", "SCAPTURE",
2932 "SPLAYMODE", "SWRITEMODE", "GPLAYINFO", "SMICROCODE",
2933 "GVBIFMT", "SVBIFMT"
2934 };
2935
2936 #define V4L1_IOCTL(cmd) \
52950ed4 2937 ((_IOC_NR((cmd)) < ARRAY_SIZE(v4l1_ioctls)) ? \
1da177e4
LT
2938 v4l1_ioctls[_IOC_NR((cmd))] : "?")
2939
2940 cam = (struct w9968cf_device*)video_get_drvdata(video_devdata(filp));
2941
2942 switch (cmd) {
2943
2944 case VIDIOCGCAP: /* get video capability */
2945 {
2946 struct video_capability cap = {
2947 .type = VID_TYPE_CAPTURE | VID_TYPE_SCALES,
2948 .channels = 1,
2949 .audios = 0,
2950 .minwidth = cam->minwidth,
2951 .minheight = cam->minheight,
2952 };
2953 sprintf(cap.name, "W996[87]CF USB Camera #%d",
2954 cam->v4ldev->minor);
2955 cap.maxwidth = (cam->upscaling && w9968cf_vpp)
2956 ? max((u16)W9968CF_MAX_WIDTH, cam->maxwidth)
2957 : cam->maxwidth;
2958 cap.maxheight = (cam->upscaling && w9968cf_vpp)
2959 ? max((u16)W9968CF_MAX_HEIGHT, cam->maxheight)
2960 : cam->maxheight;
2961
2962 if (copy_to_user(arg, &cap, sizeof(cap)))
2963 return -EFAULT;
2964
2965 DBG(5, "VIDIOCGCAP successfully called")
2966 return 0;
2967 }
2968
2969 case VIDIOCGCHAN: /* get video channel informations */
2970 {
2971 struct video_channel chan;
2972 if (copy_from_user(&chan, arg, sizeof(chan)))
2973 return -EFAULT;
2974
2975 if (chan.channel != 0)
2976 return -EINVAL;
2977
2978 strcpy(chan.name, "Camera");
2979 chan.tuners = 0;
2980 chan.flags = 0;
2981 chan.type = VIDEO_TYPE_CAMERA;
2982 chan.norm = VIDEO_MODE_AUTO;
2983
2984 if (copy_to_user(arg, &chan, sizeof(chan)))
2985 return -EFAULT;
2986
2987 DBG(5, "VIDIOCGCHAN successfully called")
2988 return 0;
2989 }
2990
2991 case VIDIOCSCHAN: /* set active channel */
2992 {
2993 struct video_channel chan;
2994
2995 if (copy_from_user(&chan, arg, sizeof(chan)))
2996 return -EFAULT;
2997
2998 if (chan.channel != 0)
2999 return -EINVAL;
3000
3001 DBG(5, "VIDIOCSCHAN successfully called")
3002 return 0;
3003 }
3004
3005 case VIDIOCGPICT: /* get image properties of the picture */
3006 {
3007 if (w9968cf_sensor_get_picture(cam))
3008 return -EIO;
3009
3010 if (copy_to_user(arg, &cam->picture, sizeof(cam->picture)))
3011 return -EFAULT;
3012
3013 DBG(5, "VIDIOCGPICT successfully called")
3014 return 0;
3015 }
3016
3017 case VIDIOCSPICT: /* change picture settings */
3018 {
3019 struct video_picture pict;
3020 int err = 0;
3021
3022 if (copy_from_user(&pict, arg, sizeof(pict)))
3023 return -EFAULT;
3024
3025 if ( (cam->force_palette || !w9968cf_vpp)
3026 && pict.palette != cam->picture.palette ) {
3027 DBG(4, "Palette %s rejected: only %s is allowed",
3028 symbolic(v4l1_plist, pict.palette),
3029 symbolic(v4l1_plist, cam->picture.palette))
3030 return -EINVAL;
3031 }
3032
3033 if (!w9968cf_valid_palette(pict.palette)) {
3034 DBG(4, "Palette %s not supported. VIDIOCSPICT failed",
3035 symbolic(v4l1_plist, pict.palette))
3036 return -EINVAL;
3037 }
3038
3039 if (!cam->force_palette) {
3040 if (cam->decompression == 0) {
3041 if (w9968cf_need_decompression(pict.palette)) {
3042 DBG(4, "Decompression disabled: palette %s is not "
3043 "allowed. VIDIOCSPICT failed",
3044 symbolic(v4l1_plist, pict.palette))
3045 return -EINVAL;
3046 }
3047 } else if (cam->decompression == 1) {
3048 if (!w9968cf_need_decompression(pict.palette)) {
3049 DBG(4, "Decompression forced: palette %s is not "
3050 "allowed. VIDIOCSPICT failed",
3051 symbolic(v4l1_plist, pict.palette))
3052 return -EINVAL;
3053 }
3054 }
3055 }
3056
3057 if (pict.depth != w9968cf_valid_depth(pict.palette)) {
3058 DBG(4, "Requested depth %u bpp is not valid for %s "
3059 "palette: ignored and changed to %u bpp",
3060 pict.depth, symbolic(v4l1_plist, pict.palette),
3061 w9968cf_valid_depth(pict.palette))
3062 pict.depth = w9968cf_valid_depth(pict.palette);
3063 }
3064
3065 if (pict.palette != cam->picture.palette) {
3066 if(*cam->requested_frame
3067 || cam->frame_current->queued) {
3068 err = wait_event_interruptible
3069 ( cam->wait_queue,
3070 cam->disconnected ||
3071 (!*cam->requested_frame &&
3072 !cam->frame_current->queued) );
3073 if (err)
3074 return err;
3075 if (cam->disconnected)
3076 return -ENODEV;
3077 }
3078
3079 if (w9968cf_stop_transfer(cam))
3080 goto ioctl_fail;
3081
3082 if (w9968cf_set_picture(cam, pict))
3083 goto ioctl_fail;
3084
3085 if (w9968cf_start_transfer(cam))
3086 goto ioctl_fail;
3087
3088 } else if (w9968cf_sensor_update_picture(cam, pict))
3089 return -EIO;
3090
3091
3092 DBG(5, "VIDIOCSPICT successfully called")
3093 return 0;
3094 }
3095
3096 case VIDIOCSWIN: /* set capture area */
3097 {
3098 struct video_window win;
3099 int err = 0;
3100
3101 if (copy_from_user(&win, arg, sizeof(win)))
3102 return -EFAULT;
3103
3104 DBG(6, "VIDIOCSWIN called: clipcount=%d, flags=%u, "
3105 "x=%u, y=%u, %ux%u", win.clipcount, win.flags,
3106 win.x, win.y, win.width, win.height)
3107
3108 if (win.clipcount != 0 || win.flags != 0)
3109 return -EINVAL;
3110
3111 if ((err = w9968cf_adjust_window_size(cam, (u16*)&win.width,
3112 (u16*)&win.height))) {
3113 DBG(4, "Resolution not supported (%ux%u). "
3114 "VIDIOCSWIN failed", win.width, win.height)
3115 return err;
3116 }
3117
3118 if (win.x != cam->window.x ||
3119 win.y != cam->window.y ||
3120 win.width != cam->window.width ||
3121 win.height != cam->window.height) {
3122 if(*cam->requested_frame
3123 || cam->frame_current->queued) {
3124 err = wait_event_interruptible
3125 ( cam->wait_queue,
3126 cam->disconnected ||
3127 (!*cam->requested_frame &&
3128 !cam->frame_current->queued) );
3129 if (err)
3130 return err;
3131 if (cam->disconnected)
3132 return -ENODEV;
3133 }
3134
3135 if (w9968cf_stop_transfer(cam))
3136 goto ioctl_fail;
3137
3138 /* This _must_ be called before set_window() */
3139 if (w9968cf_set_picture(cam, cam->picture))
3140 goto ioctl_fail;
3141
3142 if (w9968cf_set_window(cam, win))
3143 goto ioctl_fail;
3144
3145 if (w9968cf_start_transfer(cam))
3146 goto ioctl_fail;
3147 }
3148
3149 DBG(5, "VIDIOCSWIN successfully called. ")
3150 return 0;
3151 }
3152
3153 case VIDIOCGWIN: /* get current window properties */
3154 {
3155 if (copy_to_user(arg,&cam->window,sizeof(struct video_window)))
3156 return -EFAULT;
3157
3158 DBG(5, "VIDIOCGWIN successfully called")
3159 return 0;
3160 }
3161
3162 case VIDIOCGMBUF: /* request for memory (mapped) buffer */
3163 {
3164 struct video_mbuf mbuf;
3165 u8 i;
3166
3167 mbuf.size = cam->nbuffers * cam->frame[0].size;
3168 mbuf.frames = cam->nbuffers;
3169 for (i = 0; i < cam->nbuffers; i++)
3170 mbuf.offsets[i] = (unsigned long)cam->frame[i].buffer -
3171 (unsigned long)cam->frame[0].buffer;
3172
3173 if (copy_to_user(arg, &mbuf, sizeof(mbuf)))
3174 return -EFAULT;
3175
3176 DBG(5, "VIDIOCGMBUF successfully called")
3177 return 0;
3178 }
3179
3180 case VIDIOCMCAPTURE: /* start the capture to a frame */
3181 {
3182 struct video_mmap mmap;
3183 struct w9968cf_frame_t* fr;
3184 int err = 0;
3185
3186 if (copy_from_user(&mmap, arg, sizeof(mmap)))
3187 return -EFAULT;
3188
3189 DBG(6, "VIDIOCMCAPTURE called: frame #%u, format=%s, %dx%d",
3190 mmap.frame, symbolic(v4l1_plist, mmap.format),
3191 mmap.width, mmap.height)
3192
3193 if (mmap.frame >= cam->nbuffers) {
3194 DBG(4, "Invalid frame number (%u). "
3195 "VIDIOCMCAPTURE failed", mmap.frame)
3196 return -EINVAL;
3197 }
3198
3199 if (mmap.format!=cam->picture.palette &&
3200 (cam->force_palette || !w9968cf_vpp)) {
3201 DBG(4, "Palette %s rejected: only %s is allowed",
3202 symbolic(v4l1_plist, mmap.format),
3203 symbolic(v4l1_plist, cam->picture.palette))
3204 return -EINVAL;
3205 }
3206
3207 if (!w9968cf_valid_palette(mmap.format)) {
3208 DBG(4, "Palette %s not supported. "
3209 "VIDIOCMCAPTURE failed",
3210 symbolic(v4l1_plist, mmap.format))
3211 return -EINVAL;
3212 }
3213
3214 if (!cam->force_palette) {
3215 if (cam->decompression == 0) {
3216 if (w9968cf_need_decompression(mmap.format)) {
3217 DBG(4, "Decompression disabled: palette %s is not "
3218 "allowed. VIDIOCSPICT failed",
3219 symbolic(v4l1_plist, mmap.format))
3220 return -EINVAL;
3221 }
3222 } else if (cam->decompression == 1) {
3223 if (!w9968cf_need_decompression(mmap.format)) {
3224 DBG(4, "Decompression forced: palette %s is not "
3225 "allowed. VIDIOCSPICT failed",
3226 symbolic(v4l1_plist, mmap.format))
3227 return -EINVAL;
3228 }
3229 }
3230 }
3231
3232 if ((err = w9968cf_adjust_window_size(cam, (u16*)&mmap.width,
3233 (u16*)&mmap.height))) {
3234 DBG(4, "Resolution not supported (%dx%d). "
3235 "VIDIOCMCAPTURE failed",
3236 mmap.width, mmap.height)
3237 return err;
3238 }
3239
3240 fr = &cam->frame[mmap.frame];
3241
3242 if (mmap.width != cam->window.width ||
3243 mmap.height != cam->window.height ||
3244 mmap.format != cam->picture.palette) {
3245
3246 struct video_window win;
3247 struct video_picture pict;
3248
3249 if(*cam->requested_frame
3250 || cam->frame_current->queued) {
3251 DBG(6, "VIDIOCMCAPTURE. Change settings for "
3252 "frame #%u: %dx%d, format %s. Wait...",
3253 mmap.frame, mmap.width, mmap.height,
3254 symbolic(v4l1_plist, mmap.format))
3255 err = wait_event_interruptible
3256 ( cam->wait_queue,
3257 cam->disconnected ||
3258 (!*cam->requested_frame &&
3259 !cam->frame_current->queued) );
3260 if (err)
3261 return err;
3262 if (cam->disconnected)
3263 return -ENODEV;
3264 }
3265
3266 memcpy(&win, &cam->window, sizeof(win));
3267 memcpy(&pict, &cam->picture, sizeof(pict));
3268 win.width = mmap.width;
3269 win.height = mmap.height;
3270 pict.palette = mmap.format;
3271
3272 if (w9968cf_stop_transfer(cam))
3273 goto ioctl_fail;
3274
3275 /* This before set_window */
3276 if (w9968cf_set_picture(cam, pict))
3277 goto ioctl_fail;
3278
3279 if (w9968cf_set_window(cam, win))
3280 goto ioctl_fail;
3281
3282 if (w9968cf_start_transfer(cam))
3283 goto ioctl_fail;
3284
3285 } else if (fr->queued) {
3286
3287 DBG(6, "Wait until frame #%u is free", mmap.frame)
3288
3289 err = wait_event_interruptible(cam->wait_queue,
3290 cam->disconnected ||
3291 (!fr->queued));
3292 if (err)
3293 return err;
3294 if (cam->disconnected)
3295 return -ENODEV;
3296 }
3297
3298 w9968cf_push_frame(cam, mmap.frame);
3299 DBG(5, "VIDIOCMCAPTURE(%u): successfully called", mmap.frame)
3300 return 0;
3301 }
3302
3303 case VIDIOCSYNC: /* wait until the capture of a frame is finished */
3304 {
3305 unsigned int f_num;
3306 struct w9968cf_frame_t* fr;
3307 int err = 0;
3308
3309 if (copy_from_user(&f_num, arg, sizeof(f_num)))
3310 return -EFAULT;
3311
3312 if (f_num >= cam->nbuffers) {
3313 DBG(4, "Invalid frame number (%u). "
3314 "VIDIOCMCAPTURE failed", f_num)
3315 return -EINVAL;
3316 }
3317
3318 DBG(6, "VIDIOCSYNC called for frame #%u", f_num)
3319
3320 fr = &cam->frame[f_num];
3321
3322 switch (fr->status) {
3323 case F_UNUSED:
3324 if (!fr->queued) {
3325 DBG(4, "VIDIOSYNC: Frame #%u not requested!",
3326 f_num)
3327 return -EFAULT;
3328 }
3329 case F_ERROR:
3330 case F_GRABBING:
3331 err = wait_event_interruptible(cam->wait_queue,
3332 (fr->status == F_READY)
3333 || cam->disconnected);
3334 if (err)
3335 return err;
3336 if (cam->disconnected)
3337 return -ENODEV;
3338 break;
3339 case F_READY:
3340 break;
3341 }
3342
3343 if (w9968cf_vpp)
3344 w9968cf_postprocess_frame(cam, fr);
3345
3346 fr->status = F_UNUSED;
3347
3348 DBG(5, "VIDIOCSYNC(%u) successfully called", f_num)
3349 return 0;
3350 }
3351
3352 case VIDIOCGUNIT:/* report the unit numbers of the associated devices*/
3353 {
3354 struct video_unit unit = {
3355 .video = cam->v4ldev->minor,
3356 .vbi = VIDEO_NO_UNIT,
3357 .radio = VIDEO_NO_UNIT,
3358 .audio = VIDEO_NO_UNIT,
3359 .teletext = VIDEO_NO_UNIT,
3360 };
3361
3362 if (copy_to_user(arg, &unit, sizeof(unit)))
3363 return -EFAULT;
3364
3365 DBG(5, "VIDIOCGUNIT successfully called")
3366 return 0;
3367 }
3368
3369 case VIDIOCKEY:
3370 return 0;
3371
3372 case VIDIOCGFBUF:
3373 {
3374 if (clear_user(arg, sizeof(struct video_buffer)))
3375 return -EFAULT;
3376
3377 DBG(5, "VIDIOCGFBUF successfully called")
3378 return 0;
3379 }
3380
3381 case VIDIOCGTUNER:
3382 {
3383 struct video_tuner tuner;
3384 if (copy_from_user(&tuner, arg, sizeof(tuner)))
3385 return -EFAULT;
3386
3387 if (tuner.tuner != 0)
3388 return -EINVAL;
3389
3390 strcpy(tuner.name, "no_tuner");
3391 tuner.rangelow = 0;
3392 tuner.rangehigh = 0;
3393 tuner.flags = VIDEO_TUNER_NORM;
3394 tuner.mode = VIDEO_MODE_AUTO;
3395 tuner.signal = 0xffff;
3396
3397 if (copy_to_user(arg, &tuner, sizeof(tuner)))
3398 return -EFAULT;
3399
3400 DBG(5, "VIDIOCGTUNER successfully called")
3401 return 0;
3402 }
3403
3404 case VIDIOCSTUNER:
3405 {
3406 struct video_tuner tuner;
3407 if (copy_from_user(&tuner, arg, sizeof(tuner)))
3408 return -EFAULT;
3409
3410 if (tuner.tuner != 0)
3411 return -EINVAL;
3412
3413 if (tuner.mode != VIDEO_MODE_AUTO)
3414 return -EINVAL;
3415
3416 DBG(5, "VIDIOCSTUNER successfully called")
3417 return 0;
3418 }
3419
3420 case VIDIOCSFBUF:
3421 case VIDIOCCAPTURE:
3422 case VIDIOCGFREQ:
3423 case VIDIOCSFREQ:
3424 case VIDIOCGAUDIO:
3425 case VIDIOCSAUDIO:
3426 case VIDIOCSPLAYMODE:
3427 case VIDIOCSWRITEMODE:
3428 case VIDIOCGPLAYINFO:
3429 case VIDIOCSMICROCODE:
3430 case VIDIOCGVBIFMT:
3431 case VIDIOCSVBIFMT:
3432 DBG(4, "Unsupported V4L1 IOCtl: VIDIOC%s "
3433 "(type 0x%01X, "
3434 "n. 0x%01X, "
3435 "dir. 0x%01X, "
3436 "size 0x%02X)",
3437 V4L1_IOCTL(cmd),
3438 _IOC_TYPE(cmd),_IOC_NR(cmd),_IOC_DIR(cmd),_IOC_SIZE(cmd))
3439
3440 return -EINVAL;
3441
3442 default:
3443 DBG(4, "Invalid V4L1 IOCtl: VIDIOC%s "
3444 "type 0x%01X, "
3445 "n. 0x%01X, "
3446 "dir. 0x%01X, "
3447 "size 0x%02X",
3448 V4L1_IOCTL(cmd),
3449 _IOC_TYPE(cmd),_IOC_NR(cmd),_IOC_DIR(cmd),_IOC_SIZE(cmd))
3450
3451 return -ENOIOCTLCMD;
3452
3453 } /* end of switch */
3454
3455ioctl_fail:
3456 cam->misconfigured = 1;
3457 DBG(1, "VIDIOC%s failed because of hardware problems. "
3458 "To use the camera, close and open it again.", V4L1_IOCTL(cmd))
3459 return -EFAULT;
3460}
3461
3462
3463static struct file_operations w9968cf_fops = {
3464 .owner = THIS_MODULE,
3465 .open = w9968cf_open,
3466 .release = w9968cf_release,
3467 .read = w9968cf_read,
3468 .ioctl = w9968cf_ioctl,
0d0fbf81 3469 .compat_ioctl = v4l_compat_ioctl32,
1da177e4
LT
3470 .mmap = w9968cf_mmap,
3471 .llseek = no_llseek,
3472};
3473
3474
3475
3476/****************************************************************************
3477 * USB probe and V4L registration, disconnect and id_table[] definition *
3478 ****************************************************************************/
3479
3480static int
3481w9968cf_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
3482{
3483 struct usb_device *udev = interface_to_usbdev(intf);
3484 struct w9968cf_device* cam;
3485 int err = 0;
3486 enum w9968cf_model_id mod_id;
3487 struct list_head* ptr;
3488 u8 sc = 0; /* number of simultaneous cameras */
3489 static unsigned short dev_nr = 0; /* we are handling device number n */
3490
3491 if (le16_to_cpu(udev->descriptor.idVendor) == winbond_id_table[0].idVendor &&
3492 le16_to_cpu(udev->descriptor.idProduct) == winbond_id_table[0].idProduct)
3493 mod_id = W9968CF_MOD_CLVBWGP; /* see camlist[] table */
3494 else if (le16_to_cpu(udev->descriptor.idVendor) == winbond_id_table[1].idVendor &&
3495 le16_to_cpu(udev->descriptor.idProduct) == winbond_id_table[1].idProduct)
3496 mod_id = W9968CF_MOD_GENERIC; /* see camlist[] table */
3497 else
3498 return -ENODEV;
3499
3500 cam = (struct w9968cf_device*)
b10b4177 3501 kzalloc(sizeof(struct w9968cf_device), GFP_KERNEL);
1da177e4
LT
3502 if (!cam)
3503 return -ENOMEM;
3504
1da177e4
LT
3505 init_MUTEX(&cam->dev_sem);
3506 down(&cam->dev_sem);
3507
3508 cam->usbdev = udev;
3509 /* NOTE: a local copy is used to avoid possible race conditions */
3510 memcpy(&cam->dev, &udev->dev, sizeof(struct device));
3511
3512 DBG(2, "%s detected", symbolic(camlist, mod_id))
3513
3514 if (simcams > W9968CF_MAX_DEVICES)
3515 simcams = W9968CF_SIMCAMS;
3516
3517 /* How many cameras are connected ? */
3518 down(&w9968cf_devlist_sem);
3519 list_for_each(ptr, &w9968cf_dev_list)
3520 sc++;
3521 up(&w9968cf_devlist_sem);
3522
3523 if (sc >= simcams) {
3524 DBG(2, "Device rejected: too many connected cameras "
3525 "(max. %u)", simcams)
3526 err = -EPERM;
3527 goto fail;
3528 }
3529
3530
3531 /* Allocate 2 bytes of memory for camera control USB transfers */
b10b4177 3532 if (!(cam->control_buffer = kzalloc(2, GFP_KERNEL))) {
1da177e4
LT
3533 DBG(1,"Couldn't allocate memory for camera control transfers")
3534 err = -ENOMEM;
3535 goto fail;
3536 }
1da177e4
LT
3537
3538 /* Allocate 8 bytes of memory for USB data transfers to the FSB */
b10b4177 3539 if (!(cam->data_buffer = kzalloc(8, GFP_KERNEL))) {
1da177e4
LT
3540 DBG(1, "Couldn't allocate memory for data "
3541 "transfers to the FSB")
3542 err = -ENOMEM;
3543 goto fail;
3544 }
1da177e4
LT
3545
3546 /* Register the V4L device */
3547 cam->v4ldev = video_device_alloc();
3548 if (!cam->v4ldev) {
3549 DBG(1, "Could not allocate memory for a V4L structure")
3550 err = -ENOMEM;
3551 goto fail;
3552 }
3553
3554 strcpy(cam->v4ldev->name, symbolic(camlist, mod_id));
3555 cam->v4ldev->owner = THIS_MODULE;
3556 cam->v4ldev->type = VID_TYPE_CAPTURE | VID_TYPE_SCALES;
3557 cam->v4ldev->hardware = VID_HARDWARE_W9968CF;
3558 cam->v4ldev->fops = &w9968cf_fops;
3559 cam->v4ldev->minor = video_nr[dev_nr];
3560 cam->v4ldev->release = video_device_release;
3561 video_set_drvdata(cam->v4ldev, cam);
3562 cam->v4ldev->dev = &cam->dev;
3563
3564 err = video_register_device(cam->v4ldev, VFL_TYPE_GRABBER,
3565 video_nr[dev_nr]);
3566 if (err) {
3567 DBG(1, "V4L device registration failed")
3568 if (err == -ENFILE && video_nr[dev_nr] == -1)
3569 DBG(2, "Couldn't find a free /dev/videoX node")
3570 video_nr[dev_nr] = -1;
3571 dev_nr = (dev_nr < W9968CF_MAX_DEVICES-1) ? dev_nr+1 : 0;
3572 goto fail;
3573 }
3574
3575 DBG(2, "V4L device registered as /dev/video%d", cam->v4ldev->minor)
3576
3577 /* Set some basic constants */
3578 w9968cf_configure_camera(cam, udev, mod_id, dev_nr);
3579
3580 /* Add a new entry into the list of V4L registered devices */
3581 down(&w9968cf_devlist_sem);
3582 list_add(&cam->v4llist, &w9968cf_dev_list);
3583 up(&w9968cf_devlist_sem);
3584 dev_nr = (dev_nr < W9968CF_MAX_DEVICES-1) ? dev_nr+1 : 0;
3585
3586 w9968cf_turn_on_led(cam);
3587
3588 w9968cf_i2c_init(cam);
3589
3590 usb_set_intfdata(intf, cam);
3591 up(&cam->dev_sem);
3592 return 0;
3593
3594fail: /* Free unused memory */
1bc3c9e1
JJ
3595 kfree(cam->control_buffer);
3596 kfree(cam->data_buffer);
1da177e4
LT
3597 if (cam->v4ldev)
3598 video_device_release(cam->v4ldev);
3599 up(&cam->dev_sem);
3600 kfree(cam);
3601 return err;
3602}
3603
3604
3605static void w9968cf_usb_disconnect(struct usb_interface* intf)
3606{
3607 struct w9968cf_device* cam =
3608 (struct w9968cf_device*)usb_get_intfdata(intf);
3609
3610 down_write(&w9968cf_disconnect);
3611
3612 if (cam) {
3613 /* Prevent concurrent accesses to data */
3614 down(&cam->dev_sem);
3615
3616 cam->disconnected = 1;
3617
3618 DBG(2, "Disconnecting %s...", symbolic(camlist, cam->id))
3619
3620 wake_up_interruptible_all(&cam->open);
3621
3622 if (cam->users) {
3623 DBG(2, "The device is open (/dev/video%d)! "
3624 "Process name: %s. Deregistration and memory "
3625 "deallocation are deferred on close.",
3626 cam->v4ldev->minor, cam->command)
3627 cam->misconfigured = 1;
3628 w9968cf_stop_transfer(cam);
3629 wake_up_interruptible(&cam->wait_queue);
3630 } else
3631 w9968cf_release_resources(cam);
3632
3633 up(&cam->dev_sem);
3634
3635 if (!cam->users)
3636 kfree(cam);
3637 }
3638
3639 up_write(&w9968cf_disconnect);
3640}
3641
3642
3643static struct usb_driver w9968cf_usb_driver = {
1da177e4
LT
3644 .name = "w9968cf",
3645 .id_table = winbond_id_table,
3646 .probe = w9968cf_usb_probe,
3647 .disconnect = w9968cf_usb_disconnect,
3648};
3649
3650
3651
3652/****************************************************************************
3653 * Module init, exit and intermodule communication *
3654 ****************************************************************************/
3655
1da177e4
LT
3656static int __init w9968cf_module_init(void)
3657{
3658 int err;
3659
3660 KDBG(2, W9968CF_MODULE_NAME" "W9968CF_MODULE_VERSION)
3661 KDBG(3, W9968CF_MODULE_AUTHOR)
3662
3663 if (ovmod_load)
3664 request_module("ovcamchip");
3665
3666 if ((err = usb_register(&w9968cf_usb_driver)))
3667 return err;
3668
3669 return 0;
3670}
3671
3672
3673static void __exit w9968cf_module_exit(void)
3674{
3675 /* w9968cf_usb_disconnect() will be called */
3676 usb_deregister(&w9968cf_usb_driver);
3677
3678 KDBG(2, W9968CF_MODULE_NAME" deregistered")
3679}
3680
3681
3682module_init(w9968cf_module_init);
3683module_exit(w9968cf_module_exit);
3684