OpenCores
URL https://opencores.org/ocsvn/test_project/test_project/trunk

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [drivers/] [media/] [video/] [w9968cf.c] - Blame information for rev 62

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.