Merge git://git.kernel.org/pub/scm/linux/kernel/git/sam/kbuild
[linux-2.6-block.git] / drivers / media / video / sn9c102 / sn9c102_core.c
CommitLineData
1da177e4 1/***************************************************************************
f327ebbd 2 * V4L2 driver for SN9C1xx PC Camera Controllers *
1da177e4 3 * *
f327ebbd 4 * Copyright (C) 2004-2007 by Luca Risolia <luca.risolia@studio.unibo.it> *
1da177e4
LT
5 * *
6 * This program is free software; you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by *
8 * the Free Software Foundation; either version 2 of the License, or *
9 * (at your option) any later version. *
10 * *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
15 * *
16 * You should have received a copy of the GNU General Public License *
17 * along with this program; if not, write to the Free Software *
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
19 ***************************************************************************/
20
21#include <linux/module.h>
22#include <linux/init.h>
23#include <linux/kernel.h>
24#include <linux/param.h>
25#include <linux/moduleparam.h>
26#include <linux/errno.h>
27#include <linux/slab.h>
1da177e4
LT
28#include <linux/device.h>
29#include <linux/fs.h>
30#include <linux/delay.h>
1da177e4
LT
31#include <linux/compiler.h>
32#include <linux/ioctl.h>
33#include <linux/poll.h>
34#include <linux/stat.h>
35#include <linux/mm.h>
36#include <linux/vmalloc.h>
37#include <linux/page-flags.h>
38#include <linux/byteorder/generic.h>
39#include <asm/page.h>
40#include <asm/uaccess.h>
41
42#include "sn9c102.h"
43
44/*****************************************************************************/
45
f327ebbd 46#define SN9C102_MODULE_NAME "V4L2 driver for SN9C1xx PC Camera Controllers"
f423b9a8
LR
47#define SN9C102_MODULE_ALIAS "sn9c1xx"
48#define SN9C102_MODULE_AUTHOR "(C) 2004-2007 Luca Risolia"
cd6fcc55
LR
49#define SN9C102_AUTHOR_EMAIL "<luca.risolia@studio.unibo.it>"
50#define SN9C102_MODULE_LICENSE "GPL"
3770be34
LR
51#define SN9C102_MODULE_VERSION "1:1.47"
52#define SN9C102_MODULE_VERSION_CODE KERNEL_VERSION(1, 1, 47)
cd6fcc55
LR
53
54/*****************************************************************************/
55
1da177e4
LT
56MODULE_DEVICE_TABLE(usb, sn9c102_id_table);
57
58MODULE_AUTHOR(SN9C102_MODULE_AUTHOR " " SN9C102_AUTHOR_EMAIL);
59MODULE_DESCRIPTION(SN9C102_MODULE_NAME);
f423b9a8 60MODULE_ALIAS(SN9C102_MODULE_ALIAS);
1da177e4
LT
61MODULE_VERSION(SN9C102_MODULE_VERSION);
62MODULE_LICENSE(SN9C102_MODULE_LICENSE);
63
64static short video_nr[] = {[0 ... SN9C102_MAX_DEVICES-1] = -1};
65module_param_array(video_nr, short, NULL, 0444);
66MODULE_PARM_DESC(video_nr,
3770be34
LR
67 " <-1|n[,...]>"
68 "\nSpecify V4L2 minor mode number."
69 "\n-1 = use next available (default)"
70 "\n n = use minor number n (integer >= 0)"
d56410e0
MCC
71 "\nYou can specify up to "__MODULE_STRING(SN9C102_MAX_DEVICES)
72 " cameras this way."
73 "\nFor example:"
74 "\nvideo_nr=-1,2,-1 would assign minor number 2 to"
75 "\nthe second camera and use auto for the first"
76 "\none and for every other camera."
77 "\n");
78
79static short force_munmap[] = {[0 ... SN9C102_MAX_DEVICES-1] =
80 SN9C102_FORCE_MUNMAP};
1da177e4
LT
81module_param_array(force_munmap, bool, NULL, 0444);
82MODULE_PARM_DESC(force_munmap,
3770be34
LR
83 " <0|1[,...]>"
84 "\nForce the application to unmap previously"
d56410e0
MCC
85 "\nmapped buffer memory before calling any VIDIOC_S_CROP or"
86 "\nVIDIOC_S_FMT ioctl's. Not all the applications support"
87 "\nthis feature. This parameter is specific for each"
88 "\ndetected camera."
3770be34
LR
89 "\n0 = do not force memory unmapping"
90 "\n1 = force memory unmapping (save memory)"
d56410e0
MCC
91 "\nDefault value is "__MODULE_STRING(SN9C102_FORCE_MUNMAP)"."
92 "\n");
1da177e4 93
2ffab02f 94static unsigned int frame_timeout[] = {[0 ... SN9C102_MAX_DEVICES-1] =
d56410e0 95 SN9C102_FRAME_TIMEOUT};
2ffab02f
LR
96module_param_array(frame_timeout, uint, NULL, 0644);
97MODULE_PARM_DESC(frame_timeout,
3770be34
LR
98 " <0|n[,...]>"
99 "\nTimeout for a video frame in seconds before"
f327ebbd 100 "\nreturning an I/O error; 0 for infinity."
d56410e0
MCC
101 "\nThis parameter is specific for each detected camera."
102 "\nDefault value is "__MODULE_STRING(SN9C102_FRAME_TIMEOUT)"."
103 "\n");
2ffab02f 104
1da177e4
LT
105#ifdef SN9C102_DEBUG
106static unsigned short debug = SN9C102_DEBUG_LEVEL;
107module_param(debug, ushort, 0644);
108MODULE_PARM_DESC(debug,
3770be34
LR
109 " <n>"
110 "\nDebugging information level, from 0 to 3:"
d56410e0
MCC
111 "\n0 = none (use carefully)"
112 "\n1 = critical errors"
113 "\n2 = significant informations"
114 "\n3 = more verbose messages"
f423b9a8 115 "\nLevel 3 is useful for testing only."
d56410e0
MCC
116 "\nDefault value is "__MODULE_STRING(SN9C102_DEBUG_LEVEL)"."
117 "\n");
1da177e4
LT
118#endif
119
120/*****************************************************************************/
121
d56410e0
MCC
122static u32
123sn9c102_request_buffers(struct sn9c102_device* cam, u32 count,
124 enum sn9c102_io_method io)
1da177e4 125{
2ffab02f
LR
126 struct v4l2_pix_format* p = &(cam->sensor.pix_format);
127 struct v4l2_rect* r = &(cam->sensor.cropcap.bounds);
f327ebbd 128 size_t imagesize = cam->module_param.force_munmap || io == IO_READ ?
f423b9a8
LR
129 (p->width * p->height * p->priv) / 8 :
130 (r->width * r->height * p->priv) / 8;
1da177e4
LT
131 void* buff = NULL;
132 u32 i;
133
134 if (count > SN9C102_MAX_FRAMES)
135 count = SN9C102_MAX_FRAMES;
136
f327ebbd
LR
137 if (cam->bridge == BRIDGE_SN9C105 || cam->bridge == BRIDGE_SN9C120)
138 imagesize += 589 + 2; /* length of JPEG header + EOI marker */
139
1da177e4
LT
140 cam->nbuffers = count;
141 while (cam->nbuffers > 0) {
f327ebbd
LR
142 if ((buff = vmalloc_32_user(cam->nbuffers *
143 PAGE_ALIGN(imagesize))))
1da177e4
LT
144 break;
145 cam->nbuffers--;
146 }
147
148 for (i = 0; i < cam->nbuffers; i++) {
149 cam->frame[i].bufmem = buff + i*PAGE_ALIGN(imagesize);
150 cam->frame[i].buf.index = i;
151 cam->frame[i].buf.m.offset = i*PAGE_ALIGN(imagesize);
152 cam->frame[i].buf.length = imagesize;
153 cam->frame[i].buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
154 cam->frame[i].buf.sequence = 0;
155 cam->frame[i].buf.field = V4L2_FIELD_NONE;
156 cam->frame[i].buf.memory = V4L2_MEMORY_MMAP;
157 cam->frame[i].buf.flags = 0;
158 }
159
160 return cam->nbuffers;
161}
162
163
164static void sn9c102_release_buffers(struct sn9c102_device* cam)
165{
166 if (cam->nbuffers) {
cd6fcc55 167 vfree(cam->frame[0].bufmem);
1da177e4
LT
168 cam->nbuffers = 0;
169 }
a966f3e7 170 cam->frame_current = NULL;
1da177e4
LT
171}
172
173
174static void sn9c102_empty_framequeues(struct sn9c102_device* cam)
175{
176 u32 i;
177
178 INIT_LIST_HEAD(&cam->inqueue);
179 INIT_LIST_HEAD(&cam->outqueue);
180
181 for (i = 0; i < SN9C102_MAX_FRAMES; i++) {
182 cam->frame[i].state = F_UNUSED;
183 cam->frame[i].buf.bytesused = 0;
184 }
185}
186
187
a966f3e7
LR
188static void sn9c102_requeue_outqueue(struct sn9c102_device* cam)
189{
190 struct sn9c102_frame_t *i;
191
192 list_for_each_entry(i, &cam->outqueue, frame) {
193 i->state = F_QUEUED;
194 list_add(&i->frame, &cam->inqueue);
195 }
196
197 INIT_LIST_HEAD(&cam->outqueue);
198}
199
200
1da177e4
LT
201static void sn9c102_queue_unusedframes(struct sn9c102_device* cam)
202{
203 unsigned long lock_flags;
204 u32 i;
205
206 for (i = 0; i < cam->nbuffers; i++)
207 if (cam->frame[i].state == F_UNUSED) {
208 cam->frame[i].state = F_QUEUED;
209 spin_lock_irqsave(&cam->queue_lock, lock_flags);
210 list_add_tail(&cam->frame[i].frame, &cam->inqueue);
211 spin_unlock_irqrestore(&cam->queue_lock, lock_flags);
212 }
213}
214
215/*****************************************************************************/
480b55c2 216
c680dd60 217/*
480b55c2
LR
218 Write a sequence of count value/register pairs. Returns -1 after the first
219 failed write, or 0 for no errors.
220*/
c680dd60
TP
221int sn9c102_write_regs(struct sn9c102_device* cam, const u8 valreg[][2],
222 int count)
a966f3e7
LR
223{
224 struct usb_device* udev = cam->usbdev;
480b55c2 225 u8* buff = cam->control_buffer;
a966f3e7
LR
226 int i, res;
227
c680dd60
TP
228 for (i = 0; i < count; i++) {
229 u8 index = valreg[i][1];
230
231 /*
480b55c2
LR
232 index is a u8, so it must be <256 and can't be out of range.
233 If we put in a check anyway, gcc annoys us with a warning
234 hat our check is useless. People get all uppity when they
235 see warnings in the kernel compile.
236 */
237
238 *buff = valreg[i][0];
239
240 res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x08,
241 0x41, index, 0, buff, 1,
242 SN9C102_CTRL_TIMEOUT);
243
c680dd60
TP
244 if (res < 0) {
245 DBG(3, "Failed to write a register (value 0x%02X, "
480b55c2 246 "index 0x%02X, error %d)", *buff, index, res);
c680dd60
TP
247 return -1;
248 }
a966f3e7 249
480b55c2 250 cam->reg[index] = *buff;
a966f3e7
LR
251 }
252
a966f3e7
LR
253 return 0;
254}
255
256
1da177e4
LT
257int sn9c102_write_reg(struct sn9c102_device* cam, u8 value, u16 index)
258{
259 struct usb_device* udev = cam->usbdev;
260 u8* buff = cam->control_buffer;
261 int res;
262
a966f3e7
LR
263 if (index >= ARRAY_SIZE(cam->reg))
264 return -1;
265
1da177e4
LT
266 *buff = value;
267
268 res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x08, 0x41,
d56410e0 269 index, 0, buff, 1, SN9C102_CTRL_TIMEOUT);
1da177e4
LT
270 if (res < 0) {
271 DBG(3, "Failed to write a register (value 0x%02X, index "
a966f3e7 272 "0x%02X, error %d)", value, index, res);
1da177e4
LT
273 return -1;
274 }
275
276 cam->reg[index] = value;
277
278 return 0;
279}
280
281
480b55c2
LR
282/* NOTE: with the SN9C10[123] reading some registers always returns 0 */
283int sn9c102_read_reg(struct sn9c102_device* cam, u16 index)
1da177e4
LT
284{
285 struct usb_device* udev = cam->usbdev;
286 u8* buff = cam->control_buffer;
287 int res;
288
289 res = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x00, 0xc1,
d56410e0 290 index, 0, buff, 1, SN9C102_CTRL_TIMEOUT);
1da177e4
LT
291 if (res < 0)
292 DBG(3, "Failed to read a register (index 0x%02X, error %d)",
a966f3e7 293 index, res);
1da177e4
LT
294
295 return (res >= 0) ? (int)(*buff) : -1;
296}
297
298
299int sn9c102_pread_reg(struct sn9c102_device* cam, u16 index)
300{
a966f3e7
LR
301 if (index >= ARRAY_SIZE(cam->reg))
302 return -1;
1da177e4
LT
303
304 return cam->reg[index];
305}
306
307
308static int
480b55c2
LR
309sn9c102_i2c_wait(struct sn9c102_device* cam,
310 const struct sn9c102_sensor* sensor)
1da177e4
LT
311{
312 int i, r;
313
314 for (i = 1; i <= 5; i++) {
315 r = sn9c102_read_reg(cam, 0x08);
316 if (r < 0)
317 return -EIO;
318 if (r & 0x04)
319 return 0;
320 if (sensor->frequency & SN9C102_I2C_400KHZ)
321 udelay(5*16);
322 else
323 udelay(16*16);
324 }
325 return -EBUSY;
326}
327
328
329static int
d56410e0 330sn9c102_i2c_detect_read_error(struct sn9c102_device* cam,
480b55c2 331 const struct sn9c102_sensor* sensor)
1da177e4 332{
f327ebbd
LR
333 int r , err = 0;
334
1da177e4 335 r = sn9c102_read_reg(cam, 0x08);
f327ebbd
LR
336 if (r < 0)
337 err += r;
338
339 if (cam->bridge == BRIDGE_SN9C101 || cam->bridge == BRIDGE_SN9C102) {
340 if (!(r & 0x08))
341 err += -1;
342 } else {
343 if (r & 0x08)
344 err += -1;
345 }
346
347 return err ? -EIO : 0;
1da177e4
LT
348}
349
350
351static int
d56410e0 352sn9c102_i2c_detect_write_error(struct sn9c102_device* cam,
480b55c2 353 const struct sn9c102_sensor* sensor)
1da177e4
LT
354{
355 int r;
356 r = sn9c102_read_reg(cam, 0x08);
357 return (r < 0 || (r >= 0 && (r & 0x08))) ? -EIO : 0;
358}
359
360
d56410e0 361int
1da177e4 362sn9c102_i2c_try_raw_read(struct sn9c102_device* cam,
480b55c2
LR
363 const struct sn9c102_sensor* sensor, u8 data0,
364 u8 data1, u8 n, u8 buffer[])
1da177e4
LT
365{
366 struct usb_device* udev = cam->usbdev;
367 u8* data = cam->control_buffer;
480b55c2 368 int i = 0, err = 0, res;
1da177e4
LT
369
370 /* Write cycle */
371 data[0] = ((sensor->interface == SN9C102_I2C_2WIRES) ? 0x80 : 0) |
d56410e0 372 ((sensor->frequency & SN9C102_I2C_400KHZ) ? 0x01 : 0) | 0x10;
1da177e4
LT
373 data[1] = data0; /* I2C slave id */
374 data[2] = data1; /* address */
375 data[7] = 0x10;
376 res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x08, 0x41,
d56410e0 377 0x08, 0, data, 8, SN9C102_CTRL_TIMEOUT);
1da177e4
LT
378 if (res < 0)
379 err += res;
380
381 err += sn9c102_i2c_wait(cam, sensor);
382
383 /* Read cycle - n bytes */
384 data[0] = ((sensor->interface == SN9C102_I2C_2WIRES) ? 0x80 : 0) |
d56410e0
MCC
385 ((sensor->frequency & SN9C102_I2C_400KHZ) ? 0x01 : 0) |
386 (n << 4) | 0x02;
1da177e4
LT
387 data[1] = data0;
388 data[7] = 0x10;
389 res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x08, 0x41,
d56410e0 390 0x08, 0, data, 8, SN9C102_CTRL_TIMEOUT);
1da177e4
LT
391 if (res < 0)
392 err += res;
393
394 err += sn9c102_i2c_wait(cam, sensor);
395
396 /* The first read byte will be placed in data[4] */
397 res = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x00, 0xc1,
d56410e0 398 0x0a, 0, data, 5, SN9C102_CTRL_TIMEOUT);
1da177e4
LT
399 if (res < 0)
400 err += res;
401
402 err += sn9c102_i2c_detect_read_error(cam, sensor);
403
404 PDBGG("I2C read: address 0x%02X, first read byte: 0x%02X", data1,
a966f3e7 405 data[4]);
1da177e4
LT
406
407 if (err) {
a966f3e7 408 DBG(3, "I2C read failed for %s image sensor", sensor->name);
1da177e4
LT
409 return -1;
410 }
411
412 if (buffer)
480b55c2
LR
413 for (i = 0; i < n && i < 5; i++)
414 buffer[n-i-1] = data[4-i];
1da177e4
LT
415
416 return (int)data[4];
417}
418
419
d56410e0 420int
1da177e4 421sn9c102_i2c_try_raw_write(struct sn9c102_device* cam,
480b55c2 422 const struct sn9c102_sensor* sensor, u8 n, u8 data0,
d56410e0 423 u8 data1, u8 data2, u8 data3, u8 data4, u8 data5)
1da177e4
LT
424{
425 struct usb_device* udev = cam->usbdev;
426 u8* data = cam->control_buffer;
427 int err = 0, res;
428
429 /* Write cycle. It usually is address + value */
430 data[0] = ((sensor->interface == SN9C102_I2C_2WIRES) ? 0x80 : 0) |
d56410e0
MCC
431 ((sensor->frequency & SN9C102_I2C_400KHZ) ? 0x01 : 0)
432 | ((n - 1) << 4);
1da177e4
LT
433 data[1] = data0;
434 data[2] = data1;
435 data[3] = data2;
436 data[4] = data3;
437 data[5] = data4;
438 data[6] = data5;
f327ebbd 439 data[7] = 0x17;
1da177e4 440 res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x08, 0x41,
d56410e0 441 0x08, 0, data, 8, SN9C102_CTRL_TIMEOUT);
1da177e4
LT
442 if (res < 0)
443 err += res;
444
445 err += sn9c102_i2c_wait(cam, sensor);
446 err += sn9c102_i2c_detect_write_error(cam, sensor);
447
448 if (err)
a966f3e7 449 DBG(3, "I2C write failed for %s image sensor", sensor->name);
1da177e4
LT
450
451 PDBGG("I2C raw write: %u bytes, data0 = 0x%02X, data1 = 0x%02X, "
452 "data2 = 0x%02X, data3 = 0x%02X, data4 = 0x%02X, data5 = 0x%02X",
a966f3e7 453 n, data0, data1, data2, data3, data4, data5);
1da177e4
LT
454
455 return err ? -1 : 0;
456}
457
458
459int
460sn9c102_i2c_try_read(struct sn9c102_device* cam,
480b55c2 461 const struct sn9c102_sensor* sensor, u8 address)
1da177e4
LT
462{
463 return sn9c102_i2c_try_raw_read(cam, sensor, sensor->i2c_slave_id,
d56410e0 464 address, 1, NULL);
1da177e4
LT
465}
466
467
b9df978f 468int
1da177e4 469sn9c102_i2c_try_write(struct sn9c102_device* cam,
480b55c2 470 const struct sn9c102_sensor* sensor, u8 address, u8 value)
1da177e4 471{
d56410e0
MCC
472 return sn9c102_i2c_try_raw_write(cam, sensor, 3,
473 sensor->i2c_slave_id, address,
474 value, 0, 0, 0);
1da177e4
LT
475}
476
477
478int sn9c102_i2c_read(struct sn9c102_device* cam, u8 address)
479{
2ffab02f 480 return sn9c102_i2c_try_read(cam, &cam->sensor, address);
1da177e4
LT
481}
482
483
484int sn9c102_i2c_write(struct sn9c102_device* cam, u8 address, u8 value)
485{
2ffab02f 486 return sn9c102_i2c_try_write(cam, &cam->sensor, address, value);
1da177e4
LT
487}
488
489/*****************************************************************************/
490
f327ebbd 491static size_t sn9c102_sof_length(struct sn9c102_device* cam)
1da177e4 492{
a966f3e7
LR
493 switch (cam->bridge) {
494 case BRIDGE_SN9C101:
495 case BRIDGE_SN9C102:
f327ebbd 496 return 12;
a966f3e7 497 case BRIDGE_SN9C103:
f327ebbd
LR
498 return 18;
499 case BRIDGE_SN9C105:
500 case BRIDGE_SN9C120:
501 return 62;
a966f3e7 502 }
1da177e4 503
f327ebbd
LR
504 return 0;
505}
506
507
508static void*
509sn9c102_find_sof_header(struct sn9c102_device* cam, void* mem, size_t len)
510{
7e81d825 511 static const char marker[6] = {0xff, 0xff, 0x00, 0xc4, 0xc4, 0x96};
f423b9a8
LR
512 const char *m = mem;
513 size_t soflen = 0, i, j;
f327ebbd
LR
514
515 soflen = sn9c102_sof_length(cam);
516
f423b9a8
LR
517 for (i = 0; i < len; i++) {
518 size_t b;
519
520 /* Read the variable part of the header */
521 if (unlikely(cam->sof.bytesread >= sizeof(marker))) {
522 cam->sof.header[cam->sof.bytesread] = *(m+i);
523 if (++cam->sof.bytesread == soflen) {
524 cam->sof.bytesread = 0;
525 return mem + i;
526 }
527 continue;
528 }
529
530 /* Search for the SOF marker (fixed part) in the header */
531 for (j = 0, b=cam->sof.bytesread; j+b < sizeof(marker); j++) {
532 if (unlikely(i+j) == len)
533 return NULL;
534 if (*(m+i+j) == marker[cam->sof.bytesread]) {
535 cam->sof.header[cam->sof.bytesread] = *(m+i+j);
536 if (++cam->sof.bytesread == sizeof(marker)) {
537 PDBGG("Bytes to analyze: %zd. SOF "
538 "starts at byte #%zd", len, i);
539 i += j+1;
540 break;
541 }
542 } else {
543 cam->sof.bytesread = 0;
544 break;
1da177e4 545 }
f423b9a8
LR
546 }
547 }
1da177e4
LT
548
549 return NULL;
550}
551
552
553static void*
554sn9c102_find_eof_header(struct sn9c102_device* cam, void* mem, size_t len)
555{
7e81d825 556 static const u8 eof_header[4][4] = {
f327ebbd
LR
557 {0x00, 0x00, 0x00, 0x00},
558 {0x40, 0x00, 0x00, 0x00},
559 {0x80, 0x00, 0x00, 0x00},
560 {0xc0, 0x00, 0x00, 0x00},
561 };
562 size_t i, j;
1da177e4 563
f423b9a8 564 /* The EOF header does not exist in compressed data */
f327ebbd
LR
565 if (cam->sensor.pix_format.pixelformat == V4L2_PIX_FMT_SN9C10X ||
566 cam->sensor.pix_format.pixelformat == V4L2_PIX_FMT_JPEG)
f423b9a8 567 return NULL;
1da177e4 568
f423b9a8
LR
569 /*
570 The EOF header might cross the packet boundary, but this is not a
571 problem, since the end of a frame is determined by checking its size
572 in the first place.
573 */
f327ebbd
LR
574 for (i = 0; (len >= 4) && (i <= len - 4); i++)
575 for (j = 0; j < ARRAY_SIZE(eof_header); j++)
576 if (!memcmp(mem + i, eof_header[j], 4))
1da177e4
LT
577 return mem + i;
578
579 return NULL;
580}
581
582
f327ebbd
LR
583static void
584sn9c102_write_jpegheader(struct sn9c102_device* cam, struct sn9c102_frame_t* f)
585{
7e81d825 586 static const u8 jpeg_header[589] = {
f327ebbd
LR
587 0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x06, 0x04, 0x05,
588 0x06, 0x05, 0x04, 0x06, 0x06, 0x05, 0x06, 0x07, 0x07, 0x06,
589 0x08, 0x0a, 0x10, 0x0a, 0x0a, 0x09, 0x09, 0x0a, 0x14, 0x0e,
590 0x0f, 0x0c, 0x10, 0x17, 0x14, 0x18, 0x18, 0x17, 0x14, 0x16,
591 0x16, 0x1a, 0x1d, 0x25, 0x1f, 0x1a, 0x1b, 0x23, 0x1c, 0x16,
592 0x16, 0x20, 0x2c, 0x20, 0x23, 0x26, 0x27, 0x29, 0x2a, 0x29,
593 0x19, 0x1f, 0x2d, 0x30, 0x2d, 0x28, 0x30, 0x25, 0x28, 0x29,
594 0x28, 0x01, 0x07, 0x07, 0x07, 0x0a, 0x08, 0x0a, 0x13, 0x0a,
595 0x0a, 0x13, 0x28, 0x1a, 0x16, 0x1a, 0x28, 0x28, 0x28, 0x28,
596 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
597 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
598 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
599 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
600 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0xff, 0xc4, 0x01, 0xa2,
601 0x00, 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
602 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02,
603 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x01,
604 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
605 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03,
606 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x10, 0x00,
607 0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03, 0x05, 0x05, 0x04,
608 0x04, 0x00, 0x00, 0x01, 0x7d, 0x01, 0x02, 0x03, 0x00, 0x04,
609 0x11, 0x05, 0x12, 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61,
610 0x07, 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08, 0x23,
611 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0, 0x24, 0x33, 0x62,
612 0x72, 0x82, 0x09, 0x0a, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x25,
613 0x26, 0x27, 0x28, 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38,
614 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a,
615 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64,
616 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76,
617 0x77, 0x78, 0x79, 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88,
618 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99,
619 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa,
620 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2,
621 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3,
622 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2, 0xe3,
623 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf1, 0xf2, 0xf3,
624 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0x11, 0x00, 0x02,
625 0x01, 0x02, 0x04, 0x04, 0x03, 0x04, 0x07, 0x05, 0x04, 0x04,
626 0x00, 0x01, 0x02, 0x77, 0x00, 0x01, 0x02, 0x03, 0x11, 0x04,
627 0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
628 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, 0xa1, 0xb1,
629 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0, 0x15, 0x62, 0x72, 0xd1,
630 0x0a, 0x16, 0x24, 0x34, 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19,
631 0x1a, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38,
632 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a,
633 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64,
634 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76,
635 0x77, 0x78, 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
636 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
637 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9,
638 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba,
639 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2,
640 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe2, 0xe3,
641 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf2, 0xf3, 0xf4,
642 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xff, 0xc0, 0x00, 0x11,
643 0x08, 0x01, 0xe0, 0x02, 0x80, 0x03, 0x01, 0x21, 0x00, 0x02,
644 0x11, 0x01, 0x03, 0x11, 0x01, 0xff, 0xda, 0x00, 0x0c, 0x03,
645 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00
646 };
647 u8 *pos = f->bufmem;
648
649 memcpy(pos, jpeg_header, sizeof(jpeg_header));
650 *(pos + 6) = 0x00;
651 *(pos + 7 + 64) = 0x01;
652 if (cam->compression.quality == 0) {
653 memcpy(pos + 7, SN9C102_Y_QTABLE0, 64);
654 memcpy(pos + 8 + 64, SN9C102_UV_QTABLE0, 64);
655 } else if (cam->compression.quality == 1) {
656 memcpy(pos + 7, SN9C102_Y_QTABLE1, 64);
657 memcpy(pos + 8 + 64, SN9C102_UV_QTABLE1, 64);
658 }
659 *(pos + 564) = cam->sensor.pix_format.width & 0xFF;
660 *(pos + 563) = (cam->sensor.pix_format.width >> 8) & 0xFF;
661 *(pos + 562) = cam->sensor.pix_format.height & 0xFF;
662 *(pos + 561) = (cam->sensor.pix_format.height >> 8) & 0xFF;
663 *(pos + 567) = 0x21;
664
665 f->buf.bytesused += sizeof(jpeg_header);
666}
667
668
7d12e780 669static void sn9c102_urb_complete(struct urb *urb)
1da177e4
LT
670{
671 struct sn9c102_device* cam = urb->context;
672 struct sn9c102_frame_t** f;
a966f3e7 673 size_t imagesize, soflen;
1da177e4
LT
674 u8 i;
675 int err = 0;
676
677 if (urb->status == -ENOENT)
678 return;
679
680 f = &cam->frame_current;
681
682 if (cam->stream == STREAM_INTERRUPT) {
683 cam->stream = STREAM_OFF;
684 if ((*f))
685 (*f)->state = F_QUEUED;
f423b9a8 686 cam->sof.bytesread = 0;
f327ebbd 687 DBG(3, "Stream interrupted by application");
2ffab02f 688 wake_up(&cam->wait_stream);
1da177e4
LT
689 }
690
691 if (cam->state & DEV_DISCONNECTED)
692 return;
693
694 if (cam->state & DEV_MISCONFIGURED) {
695 wake_up_interruptible(&cam->wait_frame);
696 return;
697 }
698
699 if (cam->stream == STREAM_OFF || list_empty(&cam->inqueue))
700 goto resubmit_urb;
701
702 if (!(*f))
703 (*f) = list_entry(cam->inqueue.next, struct sn9c102_frame_t,
d56410e0 704 frame);
1da177e4 705
2ffab02f 706 imagesize = (cam->sensor.pix_format.width *
d56410e0
MCC
707 cam->sensor.pix_format.height *
708 cam->sensor.pix_format.priv) / 8;
f327ebbd
LR
709 if (cam->sensor.pix_format.pixelformat == V4L2_PIX_FMT_JPEG)
710 imagesize += 589; /* length of jpeg header */
711 soflen = sn9c102_sof_length(cam);
a966f3e7 712
1da177e4
LT
713 for (i = 0; i < urb->number_of_packets; i++) {
714 unsigned int img, len, status;
715 void *pos, *sof, *eof;
716
717 len = urb->iso_frame_desc[i].actual_length;
718 status = urb->iso_frame_desc[i].status;
719 pos = urb->iso_frame_desc[i].offset + urb->transfer_buffer;
720
721 if (status) {
a966f3e7 722 DBG(3, "Error in isochronous frame");
1da177e4 723 (*f)->state = F_ERROR;
f423b9a8 724 cam->sof.bytesread = 0;
1da177e4
LT
725 continue;
726 }
727
a966f3e7 728 PDBGG("Isochrnous frame: length %u, #%u i", len, i);
1da177e4
LT
729
730redo:
731 sof = sn9c102_find_sof_header(cam, pos, len);
2ffab02f 732 if (likely(!sof)) {
1da177e4
LT
733 eof = sn9c102_find_eof_header(cam, pos, len);
734 if ((*f)->state == F_GRABBING) {
735end_of_frame:
736 img = len;
737
738 if (eof)
739 img = (eof > pos) ? eof - pos - 1 : 0;
740
f423b9a8 741 if ((*f)->buf.bytesused + img > imagesize) {
2ffab02f
LR
742 u32 b;
743 b = (*f)->buf.bytesused + img -
744 imagesize;
1da177e4 745 img = imagesize - (*f)->buf.bytesused;
f423b9a8
LR
746 PDBGG("Expected EOF not found: video "
747 "frame cut");
1da177e4
LT
748 if (eof)
749 DBG(3, "Exceeded limit: +%u "
a966f3e7 750 "bytes", (unsigned)(b));
1da177e4
LT
751 }
752
753 memcpy((*f)->bufmem + (*f)->buf.bytesused, pos,
754 img);
755
756 if ((*f)->buf.bytesused == 0)
757 do_gettimeofday(&(*f)->buf.timestamp);
758
759 (*f)->buf.bytesused += img;
760
761 if ((*f)->buf.bytesused == imagesize ||
f327ebbd
LR
762 ((cam->sensor.pix_format.pixelformat ==
763 V4L2_PIX_FMT_SN9C10X ||
764 cam->sensor.pix_format.pixelformat ==
765 V4L2_PIX_FMT_JPEG) && eof)) {
2ffab02f 766 u32 b;
f327ebbd 767
2ffab02f 768 b = (*f)->buf.bytesused;
1da177e4
LT
769 (*f)->state = F_DONE;
770 (*f)->buf.sequence= ++cam->frame_count;
f327ebbd 771
a966f3e7 772 spin_lock(&cam->queue_lock);
1da177e4 773 list_move_tail(&(*f)->frame,
d56410e0 774 &cam->outqueue);
1da177e4
LT
775 if (!list_empty(&cam->inqueue))
776 (*f) = list_entry(
d56410e0
MCC
777 cam->inqueue.next,
778 struct sn9c102_frame_t,
779 frame );
1da177e4
LT
780 else
781 (*f) = NULL;
a966f3e7 782 spin_unlock(&cam->queue_lock);
f327ebbd 783
1da177e4 784 memcpy(cam->sysfs.frame_header,
f423b9a8 785 cam->sof.header, soflen);
f327ebbd 786
a966f3e7
LR
787 DBG(3, "Video frame captured: %lu "
788 "bytes", (unsigned long)(b));
1da177e4
LT
789
790 if (!(*f))
791 goto resubmit_urb;
792
793 } else if (eof) {
794 (*f)->state = F_ERROR;
795 DBG(3, "Not expected EOF after %lu "
d56410e0 796 "bytes of image data",
a966f3e7
LR
797 (unsigned long)
798 ((*f)->buf.bytesused));
1da177e4
LT
799 }
800
801 if (sof) /* (1) */
802 goto start_of_frame;
803
804 } else if (eof) {
a966f3e7 805 DBG(3, "EOF without SOF");
1da177e4
LT
806 continue;
807
808 } else {
a966f3e7 809 PDBGG("Ignoring pointless isochronous frame");
1da177e4
LT
810 continue;
811 }
812
813 } else if ((*f)->state == F_QUEUED || (*f)->state == F_ERROR) {
814start_of_frame:
815 (*f)->state = F_GRABBING;
816 (*f)->buf.bytesused = 0;
817 len -= (sof - pos);
818 pos = sof;
f327ebbd
LR
819 if (cam->sensor.pix_format.pixelformat ==
820 V4L2_PIX_FMT_JPEG)
821 sn9c102_write_jpegheader(cam, (*f));
a966f3e7 822 DBG(3, "SOF detected: new video frame");
1da177e4
LT
823 if (len)
824 goto redo;
825
826 } else if ((*f)->state == F_GRABBING) {
827 eof = sn9c102_find_eof_header(cam, pos, len);
828 if (eof && eof < sof)
829 goto end_of_frame; /* (1) */
830 else {
2ffab02f 831 if (cam->sensor.pix_format.pixelformat ==
f327ebbd
LR
832 V4L2_PIX_FMT_SN9C10X ||
833 cam->sensor.pix_format.pixelformat ==
834 V4L2_PIX_FMT_JPEG) {
f423b9a8
LR
835 if (sof - pos >= soflen) {
836 eof = sof - soflen;
837 } else { /* remove header */
838 eof = pos;
839 (*f)->buf.bytesused -=
840 (soflen - (sof - pos));
841 }
1da177e4
LT
842 goto end_of_frame;
843 } else {
844 DBG(3, "SOF before expected EOF after "
d56410e0 845 "%lu bytes of image data",
a966f3e7
LR
846 (unsigned long)
847 ((*f)->buf.bytesused));
1da177e4
LT
848 goto start_of_frame;
849 }
850 }
851 }
852 }
853
854resubmit_urb:
855 urb->dev = cam->usbdev;
856 err = usb_submit_urb(urb, GFP_ATOMIC);
857 if (err < 0 && err != -EPERM) {
858 cam->state |= DEV_MISCONFIGURED;
a966f3e7 859 DBG(1, "usb_submit_urb() failed");
1da177e4
LT
860 }
861
862 wake_up_interruptible(&cam->wait_frame);
863}
864
865
866static int sn9c102_start_transfer(struct sn9c102_device* cam)
867{
868 struct usb_device *udev = cam->usbdev;
869 struct urb* urb;
f327ebbd
LR
870 struct usb_host_interface* altsetting = usb_altnum_to_altsetting(
871 usb_ifnum_to_if(udev, 0),
872 SN9C102_ALTERNATE_SETTING);
873 const unsigned int psz = le16_to_cpu(altsetting->
874 endpoint[0].desc.wMaxPacketSize);
1da177e4
LT
875 s8 i, j;
876 int err = 0;
877
878 for (i = 0; i < SN9C102_URBS; i++) {
cd6fcc55 879 cam->transfer_buffer[i] = kzalloc(SN9C102_ISO_PACKETS * psz,
d56410e0 880 GFP_KERNEL);
1da177e4
LT
881 if (!cam->transfer_buffer[i]) {
882 err = -ENOMEM;
a966f3e7 883 DBG(1, "Not enough memory");
1da177e4
LT
884 goto free_buffers;
885 }
886 }
887
888 for (i = 0; i < SN9C102_URBS; i++) {
889 urb = usb_alloc_urb(SN9C102_ISO_PACKETS, GFP_KERNEL);
890 cam->urb[i] = urb;
891 if (!urb) {
892 err = -ENOMEM;
a966f3e7 893 DBG(1, "usb_alloc_urb() failed");
1da177e4
LT
894 goto free_urbs;
895 }
896 urb->dev = udev;
897 urb->context = cam;
898 urb->pipe = usb_rcvisocpipe(udev, 1);
899 urb->transfer_flags = URB_ISO_ASAP;
900 urb->number_of_packets = SN9C102_ISO_PACKETS;
901 urb->complete = sn9c102_urb_complete;
902 urb->transfer_buffer = cam->transfer_buffer[i];
903 urb->transfer_buffer_length = psz * SN9C102_ISO_PACKETS;
904 urb->interval = 1;
905 for (j = 0; j < SN9C102_ISO_PACKETS; j++) {
906 urb->iso_frame_desc[j].offset = psz * j;
907 urb->iso_frame_desc[j].length = psz;
908 }
909 }
910
911 /* Enable video */
912 if (!(cam->reg[0x01] & 0x04)) {
913 err = sn9c102_write_reg(cam, cam->reg[0x01] | 0x04, 0x01);
914 if (err) {
915 err = -EIO;
a966f3e7 916 DBG(1, "I/O hardware error");
1da177e4
LT
917 goto free_urbs;
918 }
919 }
920
921 err = usb_set_interface(udev, 0, SN9C102_ALTERNATE_SETTING);
922 if (err) {
a966f3e7 923 DBG(1, "usb_set_interface() failed");
1da177e4
LT
924 goto free_urbs;
925 }
926
927 cam->frame_current = NULL;
f423b9a8 928 cam->sof.bytesread = 0;
1da177e4
LT
929
930 for (i = 0; i < SN9C102_URBS; i++) {
931 err = usb_submit_urb(cam->urb[i], GFP_KERNEL);
932 if (err) {
933 for (j = i-1; j >= 0; j--)
934 usb_kill_urb(cam->urb[j]);
a966f3e7 935 DBG(1, "usb_submit_urb() failed, error %d", err);
1da177e4
LT
936 goto free_urbs;
937 }
938 }
939
940 return 0;
941
942free_urbs:
f327ebbd 943 for (i = 0; (i < SN9C102_URBS) && cam->urb[i]; i++)
1da177e4
LT
944 usb_free_urb(cam->urb[i]);
945
946free_buffers:
947 for (i = 0; (i < SN9C102_URBS) && cam->transfer_buffer[i]; i++)
948 kfree(cam->transfer_buffer[i]);
949
950 return err;
951}
952
953
954static int sn9c102_stop_transfer(struct sn9c102_device* cam)
955{
956 struct usb_device *udev = cam->usbdev;
957 s8 i;
958 int err = 0;
959
960 if (cam->state & DEV_DISCONNECTED)
961 return 0;
962
963 for (i = SN9C102_URBS-1; i >= 0; i--) {
964 usb_kill_urb(cam->urb[i]);
965 usb_free_urb(cam->urb[i]);
966 kfree(cam->transfer_buffer[i]);
967 }
968
969 err = usb_set_interface(udev, 0, 0); /* 0 Mb/s */
970 if (err)
a966f3e7 971 DBG(3, "usb_set_interface() failed");
1da177e4
LT
972
973 return err;
974}
975
976
7107627b 977static int sn9c102_stream_interrupt(struct sn9c102_device* cam)
1da177e4 978{
2ffab02f 979 long timeout;
1da177e4
LT
980
981 cam->stream = STREAM_INTERRUPT;
2ffab02f 982 timeout = wait_event_timeout(cam->wait_stream,
d56410e0
MCC
983 (cam->stream == STREAM_OFF) ||
984 (cam->state & DEV_DISCONNECTED),
985 SN9C102_URB_TIMEOUT);
1da177e4
LT
986 if (cam->state & DEV_DISCONNECTED)
987 return -ENODEV;
2ffab02f 988 else if (cam->stream != STREAM_OFF) {
1da177e4 989 cam->state |= DEV_MISCONFIGURED;
2ffab02f
LR
990 DBG(1, "URB timeout reached. The camera is misconfigured. "
991 "To use it, close and open /dev/video%d again.",
992 cam->v4ldev->minor);
993 return -EIO;
1da177e4
LT
994 }
995
996 return 0;
997}
998
999/*****************************************************************************/
1000
cd6fcc55 1001#ifdef CONFIG_VIDEO_ADV_DEBUG
f327ebbd 1002static u16 sn9c102_strtou16(const char* buff, size_t len, ssize_t* count)
1da177e4 1003{
f327ebbd 1004 char str[7];
1da177e4
LT
1005 char* endp;
1006 unsigned long val;
1007
f327ebbd 1008 if (len < 6) {
1da177e4 1009 strncpy(str, buff, len);
f423b9a8 1010 str[len] = '\0';
1da177e4 1011 } else {
f423b9a8 1012 strncpy(str, buff, 6);
f327ebbd 1013 str[6] = '\0';
1da177e4
LT
1014 }
1015
1016 val = simple_strtoul(str, &endp, 0);
1017
1018 *count = 0;
f327ebbd 1019 if (val <= 0xffff)
1da177e4
LT
1020 *count = (ssize_t)(endp - str);
1021 if ((*count) && (len == *count+1) && (buff[*count] == '\n'))
1022 *count += 1;
1023
f327ebbd 1024 return (u16)val;
1da177e4
LT
1025}
1026
1027/*
1028 NOTE 1: being inside one of the following methods implies that the v4l
d56410e0 1029 device exists for sure (see kobjects and reference counters)
1da177e4
LT
1030 NOTE 2: buffers are PAGE_SIZE long
1031*/
1032
1033static ssize_t sn9c102_show_reg(struct class_device* cd, char* buf)
1034{
1035 struct sn9c102_device* cam;
1036 ssize_t count;
1037
4186ecf8 1038 if (mutex_lock_interruptible(&sn9c102_sysfs_lock))
1da177e4
LT
1039 return -ERESTARTSYS;
1040
f327ebbd
LR
1041 cam = video_get_drvdata(container_of(cd, struct video_device,
1042 class_dev));
1da177e4 1043 if (!cam) {
4186ecf8 1044 mutex_unlock(&sn9c102_sysfs_lock);
1da177e4
LT
1045 return -ENODEV;
1046 }
1047
1048 count = sprintf(buf, "%u\n", cam->sysfs.reg);
1049
4186ecf8 1050 mutex_unlock(&sn9c102_sysfs_lock);
1da177e4
LT
1051
1052 return count;
d56410e0 1053}
1da177e4
LT
1054
1055
d56410e0 1056static ssize_t
1da177e4
LT
1057sn9c102_store_reg(struct class_device* cd, const char* buf, size_t len)
1058{
1059 struct sn9c102_device* cam;
f327ebbd 1060 u16 index;
1da177e4
LT
1061 ssize_t count;
1062
4186ecf8 1063 if (mutex_lock_interruptible(&sn9c102_sysfs_lock))
1da177e4
LT
1064 return -ERESTARTSYS;
1065
f327ebbd
LR
1066 cam = video_get_drvdata(container_of(cd, struct video_device,
1067 class_dev));
1da177e4 1068 if (!cam) {
4186ecf8 1069 mutex_unlock(&sn9c102_sysfs_lock);
1da177e4
LT
1070 return -ENODEV;
1071 }
1072
f327ebbd
LR
1073 index = sn9c102_strtou16(buf, len, &count);
1074 if (index >= ARRAY_SIZE(cam->reg) || !count) {
4186ecf8 1075 mutex_unlock(&sn9c102_sysfs_lock);
1da177e4
LT
1076 return -EINVAL;
1077 }
1078
1079 cam->sysfs.reg = index;
1080
f327ebbd 1081 DBG(2, "Moved SN9C1XX register index to 0x%02X", cam->sysfs.reg);
a966f3e7 1082 DBG(3, "Written bytes: %zd", count);
1da177e4 1083
4186ecf8 1084 mutex_unlock(&sn9c102_sysfs_lock);
1da177e4
LT
1085
1086 return count;
1087}
1088
1089
1090static ssize_t sn9c102_show_val(struct class_device* cd, char* buf)
1091{
1092 struct sn9c102_device* cam;
1093 ssize_t count;
1094 int val;
1095
4186ecf8 1096 if (mutex_lock_interruptible(&sn9c102_sysfs_lock))
1da177e4
LT
1097 return -ERESTARTSYS;
1098
f327ebbd
LR
1099 cam = video_get_drvdata(container_of(cd, struct video_device,
1100 class_dev));
1da177e4 1101 if (!cam) {
4186ecf8 1102 mutex_unlock(&sn9c102_sysfs_lock);
1da177e4
LT
1103 return -ENODEV;
1104 }
1105
1106 if ((val = sn9c102_read_reg(cam, cam->sysfs.reg)) < 0) {
4186ecf8 1107 mutex_unlock(&sn9c102_sysfs_lock);
1da177e4
LT
1108 return -EIO;
1109 }
1110
1111 count = sprintf(buf, "%d\n", val);
1112
f423b9a8 1113 DBG(3, "Read bytes: %zd, value: %d", count, val);
1da177e4 1114
4186ecf8 1115 mutex_unlock(&sn9c102_sysfs_lock);
1da177e4
LT
1116
1117 return count;
d56410e0 1118}
1da177e4
LT
1119
1120
1121static ssize_t
1122sn9c102_store_val(struct class_device* cd, const char* buf, size_t len)
1123{
1124 struct sn9c102_device* cam;
f327ebbd 1125 u16 value;
1da177e4
LT
1126 ssize_t count;
1127 int err;
1128
4186ecf8 1129 if (mutex_lock_interruptible(&sn9c102_sysfs_lock))
1da177e4
LT
1130 return -ERESTARTSYS;
1131
f327ebbd
LR
1132 cam = video_get_drvdata(container_of(cd, struct video_device,
1133 class_dev));
1da177e4 1134 if (!cam) {
4186ecf8 1135 mutex_unlock(&sn9c102_sysfs_lock);
1da177e4
LT
1136 return -ENODEV;
1137 }
1138
f327ebbd 1139 value = sn9c102_strtou16(buf, len, &count);
1da177e4 1140 if (!count) {
4186ecf8 1141 mutex_unlock(&sn9c102_sysfs_lock);
1da177e4
LT
1142 return -EINVAL;
1143 }
1144
1145 err = sn9c102_write_reg(cam, value, cam->sysfs.reg);
1146 if (err) {
4186ecf8 1147 mutex_unlock(&sn9c102_sysfs_lock);
1da177e4
LT
1148 return -EIO;
1149 }
1150
f327ebbd 1151 DBG(2, "Written SN9C1XX reg. 0x%02X, val. 0x%02X",
a966f3e7
LR
1152 cam->sysfs.reg, value);
1153 DBG(3, "Written bytes: %zd", count);
1da177e4 1154
4186ecf8 1155 mutex_unlock(&sn9c102_sysfs_lock);
1da177e4
LT
1156
1157 return count;
1158}
1159
1160
1161static ssize_t sn9c102_show_i2c_reg(struct class_device* cd, char* buf)
1162{
1163 struct sn9c102_device* cam;
1164 ssize_t count;
1165
4186ecf8 1166 if (mutex_lock_interruptible(&sn9c102_sysfs_lock))
1da177e4
LT
1167 return -ERESTARTSYS;
1168
f327ebbd
LR
1169 cam = video_get_drvdata(container_of(cd, struct video_device,
1170 class_dev));
1da177e4 1171 if (!cam) {
4186ecf8 1172 mutex_unlock(&sn9c102_sysfs_lock);
1da177e4
LT
1173 return -ENODEV;
1174 }
1175
1176 count = sprintf(buf, "%u\n", cam->sysfs.i2c_reg);
1177
a966f3e7 1178 DBG(3, "Read bytes: %zd", count);
1da177e4 1179
4186ecf8 1180 mutex_unlock(&sn9c102_sysfs_lock);
1da177e4
LT
1181
1182 return count;
1183}
1184
1185
d56410e0 1186static ssize_t
1da177e4
LT
1187sn9c102_store_i2c_reg(struct class_device* cd, const char* buf, size_t len)
1188{
1189 struct sn9c102_device* cam;
f327ebbd 1190 u16 index;
1da177e4
LT
1191 ssize_t count;
1192
4186ecf8 1193 if (mutex_lock_interruptible(&sn9c102_sysfs_lock))
1da177e4
LT
1194 return -ERESTARTSYS;
1195
f327ebbd
LR
1196 cam = video_get_drvdata(container_of(cd, struct video_device,
1197 class_dev));
1da177e4 1198 if (!cam) {
4186ecf8 1199 mutex_unlock(&sn9c102_sysfs_lock);
1da177e4
LT
1200 return -ENODEV;
1201 }
1202
f327ebbd 1203 index = sn9c102_strtou16(buf, len, &count);
1da177e4 1204 if (!count) {
4186ecf8 1205 mutex_unlock(&sn9c102_sysfs_lock);
1da177e4
LT
1206 return -EINVAL;
1207 }
1208
1209 cam->sysfs.i2c_reg = index;
1210
a966f3e7
LR
1211 DBG(2, "Moved sensor register index to 0x%02X", cam->sysfs.i2c_reg);
1212 DBG(3, "Written bytes: %zd", count);
1da177e4 1213
4186ecf8 1214 mutex_unlock(&sn9c102_sysfs_lock);
1da177e4
LT
1215
1216 return count;
1217}
1218
1219
1220static ssize_t sn9c102_show_i2c_val(struct class_device* cd, char* buf)
1221{
1222 struct sn9c102_device* cam;
1223 ssize_t count;
1224 int val;
1225
4186ecf8 1226 if (mutex_lock_interruptible(&sn9c102_sysfs_lock))
1da177e4
LT
1227 return -ERESTARTSYS;
1228
f327ebbd
LR
1229 cam = video_get_drvdata(container_of(cd, struct video_device,
1230 class_dev));
1da177e4 1231 if (!cam) {
4186ecf8 1232 mutex_unlock(&sn9c102_sysfs_lock);
1da177e4
LT
1233 return -ENODEV;
1234 }
1235
2ffab02f 1236 if (!(cam->sensor.sysfs_ops & SN9C102_I2C_READ)) {
4186ecf8 1237 mutex_unlock(&sn9c102_sysfs_lock);
1da177e4
LT
1238 return -ENOSYS;
1239 }
1240
1241 if ((val = sn9c102_i2c_read(cam, cam->sysfs.i2c_reg)) < 0) {
4186ecf8 1242 mutex_unlock(&sn9c102_sysfs_lock);
1da177e4
LT
1243 return -EIO;
1244 }
1245
1246 count = sprintf(buf, "%d\n", val);
1247
f423b9a8 1248 DBG(3, "Read bytes: %zd, value: %d", count, val);
1da177e4 1249
4186ecf8 1250 mutex_unlock(&sn9c102_sysfs_lock);
1da177e4
LT
1251
1252 return count;
d56410e0 1253}
1da177e4
LT
1254
1255
1256static ssize_t
1257sn9c102_store_i2c_val(struct class_device* cd, const char* buf, size_t len)
1258{
1259 struct sn9c102_device* cam;
f327ebbd 1260 u16 value;
1da177e4
LT
1261 ssize_t count;
1262 int err;
1263
4186ecf8 1264 if (mutex_lock_interruptible(&sn9c102_sysfs_lock))
1da177e4
LT
1265 return -ERESTARTSYS;
1266
f327ebbd
LR
1267 cam = video_get_drvdata(container_of(cd, struct video_device,
1268 class_dev));
1da177e4 1269 if (!cam) {
4186ecf8 1270 mutex_unlock(&sn9c102_sysfs_lock);
1da177e4
LT
1271 return -ENODEV;
1272 }
1273
2ffab02f 1274 if (!(cam->sensor.sysfs_ops & SN9C102_I2C_WRITE)) {
4186ecf8 1275 mutex_unlock(&sn9c102_sysfs_lock);
1da177e4
LT
1276 return -ENOSYS;
1277 }
1278
f327ebbd 1279 value = sn9c102_strtou16(buf, len, &count);
1da177e4 1280 if (!count) {
4186ecf8 1281 mutex_unlock(&sn9c102_sysfs_lock);
1da177e4
LT
1282 return -EINVAL;
1283 }
1284
1285 err = sn9c102_i2c_write(cam, cam->sysfs.i2c_reg, value);
1286 if (err) {
4186ecf8 1287 mutex_unlock(&sn9c102_sysfs_lock);
1da177e4
LT
1288 return -EIO;
1289 }
1290
1291 DBG(2, "Written sensor reg. 0x%02X, val. 0x%02X",
a966f3e7
LR
1292 cam->sysfs.i2c_reg, value);
1293 DBG(3, "Written bytes: %zd", count);
1da177e4 1294
4186ecf8 1295 mutex_unlock(&sn9c102_sysfs_lock);
1da177e4
LT
1296
1297 return count;
1298}
1299
1300
1301static ssize_t
1302sn9c102_store_green(struct class_device* cd, const char* buf, size_t len)
1303{
1304 struct sn9c102_device* cam;
1305 enum sn9c102_bridge bridge;
1306 ssize_t res = 0;
f327ebbd 1307 u16 value;
1da177e4
LT
1308 ssize_t count;
1309
4186ecf8 1310 if (mutex_lock_interruptible(&sn9c102_sysfs_lock))
1da177e4
LT
1311 return -ERESTARTSYS;
1312
f327ebbd
LR
1313 cam = video_get_drvdata(container_of(cd, struct video_device,
1314 class_dev));
1da177e4 1315 if (!cam) {
4186ecf8 1316 mutex_unlock(&sn9c102_sysfs_lock);
1da177e4
LT
1317 return -ENODEV;
1318 }
1319
1320 bridge = cam->bridge;
1321
4186ecf8 1322 mutex_unlock(&sn9c102_sysfs_lock);
1da177e4 1323
f327ebbd 1324 value = sn9c102_strtou16(buf, len, &count);
1da177e4
LT
1325 if (!count)
1326 return -EINVAL;
1327
1328 switch (bridge) {
1329 case BRIDGE_SN9C101:
1330 case BRIDGE_SN9C102:
1331 if (value > 0x0f)
1332 return -EINVAL;
1333 if ((res = sn9c102_store_reg(cd, "0x11", 4)) >= 0)
1334 res = sn9c102_store_val(cd, buf, len);
1335 break;
1336 case BRIDGE_SN9C103:
f327ebbd
LR
1337 case BRIDGE_SN9C105:
1338 case BRIDGE_SN9C120:
1da177e4
LT
1339 if (value > 0x7f)
1340 return -EINVAL;
f327ebbd 1341 if ((res = sn9c102_store_reg(cd, "0x07", 4)) >= 0)
1da177e4
LT
1342 res = sn9c102_store_val(cd, buf, len);
1343 break;
1344 }
1345
1346 return res;
1347}
1348
1349
1350static ssize_t
1351sn9c102_store_blue(struct class_device* cd, const char* buf, size_t len)
1352{
1353 ssize_t res = 0;
f327ebbd 1354 u16 value;
1da177e4
LT
1355 ssize_t count;
1356
f327ebbd 1357 value = sn9c102_strtou16(buf, len, &count);
1da177e4
LT
1358 if (!count || value > 0x7f)
1359 return -EINVAL;
1360
1361 if ((res = sn9c102_store_reg(cd, "0x06", 4)) >= 0)
1362 res = sn9c102_store_val(cd, buf, len);
1363
1364 return res;
1365}
1366
1367
1368static ssize_t
1369sn9c102_store_red(struct class_device* cd, const char* buf, size_t len)
1370{
1371 ssize_t res = 0;
f327ebbd 1372 u16 value;
1da177e4
LT
1373 ssize_t count;
1374
f327ebbd 1375 value = sn9c102_strtou16(buf, len, &count);
1da177e4
LT
1376 if (!count || value > 0x7f)
1377 return -EINVAL;
1378
1379 if ((res = sn9c102_store_reg(cd, "0x05", 4)) >= 0)
1380 res = sn9c102_store_val(cd, buf, len);
1381
1382 return res;
1383}
1384
1385
1386static ssize_t sn9c102_show_frame_header(struct class_device* cd, char* buf)
1387{
1388 struct sn9c102_device* cam;
1389 ssize_t count;
1390
f327ebbd
LR
1391 cam = video_get_drvdata(container_of(cd, struct video_device,
1392 class_dev));
1da177e4
LT
1393 if (!cam)
1394 return -ENODEV;
1395
1396 count = sizeof(cam->sysfs.frame_header);
1397 memcpy(buf, cam->sysfs.frame_header, count);
1398
a966f3e7 1399 DBG(3, "Frame header, read bytes: %zd", count);
1da177e4
LT
1400
1401 return count;
d56410e0 1402}
1da177e4
LT
1403
1404
1405static CLASS_DEVICE_ATTR(reg, S_IRUGO | S_IWUSR,
d56410e0 1406 sn9c102_show_reg, sn9c102_store_reg);
1da177e4 1407static CLASS_DEVICE_ATTR(val, S_IRUGO | S_IWUSR,
d56410e0 1408 sn9c102_show_val, sn9c102_store_val);
1da177e4 1409static CLASS_DEVICE_ATTR(i2c_reg, S_IRUGO | S_IWUSR,
d56410e0 1410 sn9c102_show_i2c_reg, sn9c102_store_i2c_reg);
1da177e4 1411static CLASS_DEVICE_ATTR(i2c_val, S_IRUGO | S_IWUSR,
d56410e0 1412 sn9c102_show_i2c_val, sn9c102_store_i2c_val);
1da177e4
LT
1413static CLASS_DEVICE_ATTR(green, S_IWUGO, NULL, sn9c102_store_green);
1414static CLASS_DEVICE_ATTR(blue, S_IWUGO, NULL, sn9c102_store_blue);
1415static CLASS_DEVICE_ATTR(red, S_IWUGO, NULL, sn9c102_store_red);
1416static CLASS_DEVICE_ATTR(frame_header, S_IRUGO,
d56410e0 1417 sn9c102_show_frame_header, NULL);
1da177e4
LT
1418
1419
c12e3be0 1420static int sn9c102_create_sysfs(struct sn9c102_device* cam)
1da177e4 1421{
990e3743 1422 struct class_device *classdev = &(cam->v4ldev->class_dev);
f327ebbd 1423 int err = 0;
c12e3be0 1424
990e3743 1425 if ((err = class_device_create_file(classdev, &class_device_attr_reg)))
f327ebbd 1426 goto err_out;
990e3743 1427 if ((err = class_device_create_file(classdev, &class_device_attr_val)))
f327ebbd 1428 goto err_reg;
990e3743 1429 if ((err = class_device_create_file(classdev,
f327ebbd
LR
1430 &class_device_attr_frame_header)))
1431 goto err_val;
1da177e4 1432
2ffab02f 1433 if (cam->sensor.sysfs_ops) {
990e3743 1434 if ((err = class_device_create_file(classdev,
f327ebbd
LR
1435 &class_device_attr_i2c_reg)))
1436 goto err_frame_header;
990e3743 1437 if ((err = class_device_create_file(classdev,
f327ebbd
LR
1438 &class_device_attr_i2c_val)))
1439 goto err_i2c_reg;
c12e3be0
JG
1440 }
1441
1442 if (cam->bridge == BRIDGE_SN9C101 || cam->bridge == BRIDGE_SN9C102) {
990e3743 1443 if ((err = class_device_create_file(classdev,
f327ebbd
LR
1444 &class_device_attr_green)))
1445 goto err_i2c_val;
1446 } else {
990e3743 1447 if ((err = class_device_create_file(classdev,
f327ebbd
LR
1448 &class_device_attr_blue)))
1449 goto err_i2c_val;
990e3743 1450 if ((err = class_device_create_file(classdev,
f327ebbd
LR
1451 &class_device_attr_red)))
1452 goto err_blue;
1da177e4 1453 }
c12e3be0
JG
1454
1455 return 0;
1456
1457err_blue:
990e3743 1458 class_device_remove_file(classdev, &class_device_attr_blue);
c12e3be0
JG
1459err_i2c_val:
1460 if (cam->sensor.sysfs_ops)
990e3743 1461 class_device_remove_file(classdev, &class_device_attr_i2c_val);
c12e3be0
JG
1462err_i2c_reg:
1463 if (cam->sensor.sysfs_ops)
990e3743 1464 class_device_remove_file(classdev, &class_device_attr_i2c_reg);
f327ebbd 1465err_frame_header:
990e3743 1466 class_device_remove_file(classdev, &class_device_attr_frame_header);
c12e3be0 1467err_val:
990e3743 1468 class_device_remove_file(classdev, &class_device_attr_val);
c12e3be0 1469err_reg:
990e3743 1470 class_device_remove_file(classdev, &class_device_attr_reg);
f327ebbd
LR
1471err_out:
1472 return err;
1da177e4 1473}
cd6fcc55 1474#endif /* CONFIG_VIDEO_ADV_DEBUG */
1da177e4
LT
1475
1476/*****************************************************************************/
1477
1478static int
1479sn9c102_set_pix_format(struct sn9c102_device* cam, struct v4l2_pix_format* pix)
1480{
1481 int err = 0;
1482
f327ebbd
LR
1483 if (pix->pixelformat == V4L2_PIX_FMT_SN9C10X ||
1484 pix->pixelformat == V4L2_PIX_FMT_JPEG) {
1485 switch (cam->bridge) {
1486 case BRIDGE_SN9C101:
1487 case BRIDGE_SN9C102:
1488 case BRIDGE_SN9C103:
1489 err += sn9c102_write_reg(cam, cam->reg[0x18] | 0x80,
1490 0x18);
1491 break;
1492 case BRIDGE_SN9C105:
1493 case BRIDGE_SN9C120:
1494 err += sn9c102_write_reg(cam, cam->reg[0x18] & 0x7f,
1495 0x18);
1496 break;
1497 }
1498 } else {
1499 switch (cam->bridge) {
1500 case BRIDGE_SN9C101:
1501 case BRIDGE_SN9C102:
1502 case BRIDGE_SN9C103:
1503 err += sn9c102_write_reg(cam, cam->reg[0x18] & 0x7f,
1504 0x18);
1505 break;
1506 case BRIDGE_SN9C105:
1507 case BRIDGE_SN9C120:
1508 err += sn9c102_write_reg(cam, cam->reg[0x18] | 0x80,
1509 0x18);
1510 break;
1511 }
1512 }
1da177e4
LT
1513
1514 return err ? -EIO : 0;
1515}
1516
1517
1518static int
1519sn9c102_set_compression(struct sn9c102_device* cam,
d56410e0 1520 struct v4l2_jpegcompression* compression)
1da177e4 1521{
f327ebbd 1522 int i, err = 0;
1da177e4 1523
f327ebbd
LR
1524 switch (cam->bridge) {
1525 case BRIDGE_SN9C101:
1526 case BRIDGE_SN9C102:
1527 case BRIDGE_SN9C103:
f423b9a8 1528 if (compression->quality == 0)
f327ebbd
LR
1529 err += sn9c102_write_reg(cam, cam->reg[0x17] | 0x01,
1530 0x17);
f423b9a8 1531 else if (compression->quality == 1)
f327ebbd
LR
1532 err += sn9c102_write_reg(cam, cam->reg[0x17] & 0xfe,
1533 0x17);
1534 break;
1535 case BRIDGE_SN9C105:
1536 case BRIDGE_SN9C120:
1537 if (compression->quality == 0) {
1538 for (i = 0; i <= 63; i++) {
1539 err += sn9c102_write_reg(cam,
f423b9a8 1540 SN9C102_Y_QTABLE1[i],
f327ebbd
LR
1541 0x100 + i);
1542 err += sn9c102_write_reg(cam,
f423b9a8 1543 SN9C102_UV_QTABLE1[i],
f327ebbd
LR
1544 0x140 + i);
1545 }
1546 err += sn9c102_write_reg(cam, cam->reg[0x18] & 0xbf,
1547 0x18);
1548 } else if (compression->quality == 1) {
1549 for (i = 0; i <= 63; i++) {
1550 err += sn9c102_write_reg(cam,
1551 SN9C102_Y_QTABLE1[i],
1552 0x100 + i);
1553 err += sn9c102_write_reg(cam,
1554 SN9C102_UV_QTABLE1[i],
1555 0x140 + i);
1556 }
1557 err += sn9c102_write_reg(cam, cam->reg[0x18] | 0x40,
1558 0x18);
1559 }
1560 break;
1561 }
1da177e4
LT
1562
1563 return err ? -EIO : 0;
1564}
1565
1566
1567static int sn9c102_set_scale(struct sn9c102_device* cam, u8 scale)
1568{
1569 u8 r = 0;
1570 int err = 0;
1571
1572 if (scale == 1)
1573 r = cam->reg[0x18] & 0xcf;
1574 else if (scale == 2) {
1575 r = cam->reg[0x18] & 0xcf;
1576 r |= 0x10;
1577 } else if (scale == 4)
1578 r = cam->reg[0x18] | 0x20;
1579
1580 err += sn9c102_write_reg(cam, r, 0x18);
1581 if (err)
1582 return -EIO;
1583
a966f3e7 1584 PDBGG("Scaling factor: %u", scale);
1da177e4
LT
1585
1586 return 0;
1587}
1588
1589
1590static int sn9c102_set_crop(struct sn9c102_device* cam, struct v4l2_rect* rect)
1591{
2ffab02f 1592 struct sn9c102_sensor* s = &cam->sensor;
1da177e4
LT
1593 u8 h_start = (u8)(rect->left - s->cropcap.bounds.left),
1594 v_start = (u8)(rect->top - s->cropcap.bounds.top),
1595 h_size = (u8)(rect->width / 16),
1596 v_size = (u8)(rect->height / 16);
1597 int err = 0;
1598
1599 err += sn9c102_write_reg(cam, h_start, 0x12);
1600 err += sn9c102_write_reg(cam, v_start, 0x13);
1601 err += sn9c102_write_reg(cam, h_size, 0x15);
1602 err += sn9c102_write_reg(cam, v_size, 0x16);
1603 if (err)
1604 return -EIO;
1605
1606 PDBGG("h_start, v_start, h_size, v_size, ho_size, vo_size "
a966f3e7 1607 "%u %u %u %u", h_start, v_start, h_size, v_size);
1da177e4
LT
1608
1609 return 0;
1610}
1611
1612
1613static int sn9c102_init(struct sn9c102_device* cam)
1614{
2ffab02f 1615 struct sn9c102_sensor* s = &cam->sensor;
1da177e4
LT
1616 struct v4l2_control ctrl;
1617 struct v4l2_queryctrl *qctrl;
1618 struct v4l2_rect* rect;
52950ed4 1619 u8 i = 0;
1da177e4
LT
1620 int err = 0;
1621
1622 if (!(cam->state & DEV_INITIALIZED)) {
3770be34
LR
1623 mutex_init(&cam->open_mutex);
1624 init_waitqueue_head(&cam->wait_open);
1da177e4
LT
1625 qctrl = s->qctrl;
1626 rect = &(s->cropcap.defrect);
1627 } else { /* use current values */
1628 qctrl = s->_qctrl;
1629 rect = &(s->_rect);
1630 }
1631
1632 err += sn9c102_set_scale(cam, rect->width / s->pix_format.width);
1633 err += sn9c102_set_crop(cam, rect);
1634 if (err)
1635 return err;
1636
1637 if (s->init) {
1638 err = s->init(cam);
1639 if (err) {
a966f3e7 1640 DBG(3, "Sensor initialization failed");
1da177e4
LT
1641 return err;
1642 }
1643 }
1644
1645 if (!(cam->state & DEV_INITIALIZED))
f327ebbd
LR
1646 if (cam->bridge == BRIDGE_SN9C101 ||
1647 cam->bridge == BRIDGE_SN9C102 ||
1648 cam->bridge == BRIDGE_SN9C103) {
f423b9a8
LR
1649 if (s->pix_format.pixelformat == V4L2_PIX_FMT_JPEG)
1650 s->pix_format.pixelformat= V4L2_PIX_FMT_SBGGR8;
f327ebbd
LR
1651 cam->compression.quality = cam->reg[0x17] & 0x01 ?
1652 0 : 1;
1653 } else {
f423b9a8
LR
1654 if (s->pix_format.pixelformat == V4L2_PIX_FMT_SN9C10X)
1655 s->pix_format.pixelformat = V4L2_PIX_FMT_JPEG;
f327ebbd
LR
1656 cam->compression.quality = cam->reg[0x18] & 0x40 ?
1657 0 : 1;
1658 err += sn9c102_set_compression(cam, &cam->compression);
1659 }
1da177e4
LT
1660 else
1661 err += sn9c102_set_compression(cam, &cam->compression);
1662 err += sn9c102_set_pix_format(cam, &s->pix_format);
1663 if (s->set_pix_format)
1664 err += s->set_pix_format(cam, &s->pix_format);
1665 if (err)
1666 return err;
1667
f327ebbd
LR
1668 if (s->pix_format.pixelformat == V4L2_PIX_FMT_SN9C10X ||
1669 s->pix_format.pixelformat == V4L2_PIX_FMT_JPEG)
52950ed4 1670 DBG(3, "Compressed video format is active, quality %d",
a966f3e7 1671 cam->compression.quality);
1da177e4 1672 else
a966f3e7 1673 DBG(3, "Uncompressed video format is active");
1da177e4
LT
1674
1675 if (s->set_crop)
1676 if ((err = s->set_crop(cam, rect))) {
a966f3e7 1677 DBG(3, "set_crop() failed");
1da177e4
LT
1678 return err;
1679 }
1680
1681 if (s->set_ctrl) {
52950ed4
TK
1682 for (i = 0; i < ARRAY_SIZE(s->qctrl); i++)
1683 if (s->qctrl[i].id != 0 &&
1da177e4
LT
1684 !(s->qctrl[i].flags & V4L2_CTRL_FLAG_DISABLED)) {
1685 ctrl.id = s->qctrl[i].id;
1686 ctrl.value = qctrl[i].default_value;
1687 err = s->set_ctrl(cam, &ctrl);
1688 if (err) {
1689 DBG(3, "Set %s control failed",
a966f3e7 1690 s->qctrl[i].name);
1da177e4
LT
1691 return err;
1692 }
1693 DBG(3, "Image sensor supports '%s' control",
a966f3e7 1694 s->qctrl[i].name);
1da177e4
LT
1695 }
1696 }
1697
1698 if (!(cam->state & DEV_INITIALIZED)) {
4186ecf8 1699 mutex_init(&cam->fileop_mutex);
1da177e4
LT
1700 spin_lock_init(&cam->queue_lock);
1701 init_waitqueue_head(&cam->wait_frame);
1702 init_waitqueue_head(&cam->wait_stream);
1703 cam->nreadbuffers = 2;
1704 memcpy(s->_qctrl, s->qctrl, sizeof(s->qctrl));
52950ed4 1705 memcpy(&(s->_rect), &(s->cropcap.defrect),
1da177e4
LT
1706 sizeof(struct v4l2_rect));
1707 cam->state |= DEV_INITIALIZED;
1708 }
1709
a966f3e7 1710 DBG(2, "Initialization succeeded");
1da177e4
LT
1711 return 0;
1712}
1713
3770be34 1714/*****************************************************************************/
1da177e4 1715
3770be34 1716static void sn9c102_release_resources(struct kref *kref)
1da177e4 1717{
3770be34
LR
1718 struct sn9c102_device *cam;
1719
4186ecf8 1720 mutex_lock(&sn9c102_sysfs_lock);
1da177e4 1721
3770be34
LR
1722 cam = container_of(kref, struct sn9c102_device, kref);
1723
a966f3e7 1724 DBG(2, "V4L2 device /dev/video%d deregistered", cam->v4ldev->minor);
1da177e4
LT
1725 video_set_drvdata(cam->v4ldev, NULL);
1726 video_unregister_device(cam->v4ldev);
3770be34
LR
1727 usb_put_dev(cam->usbdev);
1728 kfree(cam->control_buffer);
1729 kfree(cam);
1da177e4 1730
4186ecf8 1731 mutex_unlock(&sn9c102_sysfs_lock);
1da177e4 1732
1da177e4
LT
1733}
1734
1da177e4
LT
1735
1736static int sn9c102_open(struct inode* inode, struct file* filp)
1737{
1738 struct sn9c102_device* cam;
1739 int err = 0;
1740
1741 /*
3770be34
LR
1742 A read_trylock() in open() is the only safe way to prevent race
1743 conditions with disconnect(), one close() and multiple (not
1744 necessarily simultaneous) attempts to open(). For example, it
1745 prevents from waiting for a second access, while the device
1746 structure is being deallocated, after a possible disconnect() and
1747 during a following close() holding the write lock: given that, after
1748 this deallocation, no access will be possible anymore, using the
1749 non-trylock version would have let open() gain the access to the
1750 device structure improperly.
1751 For this reason the lock must also not be per-device.
1da177e4 1752 */
3770be34 1753 if (!down_read_trylock(&sn9c102_dev_lock))
1da177e4
LT
1754 return -ERESTARTSYS;
1755
1756 cam = video_get_drvdata(video_devdata(filp));
1757
3770be34
LR
1758 if (wait_for_completion_interruptible(&cam->probe)) {
1759 up_read(&sn9c102_dev_lock);
1760 return -ERESTARTSYS;
1761 }
1762
1763 kref_get(&cam->kref);
1764
1765 /*
1766 Make sure to isolate all the simultaneous opens.
1767 */
1768 if (mutex_lock_interruptible(&cam->open_mutex)) {
1769 kref_put(&cam->kref, sn9c102_release_resources);
1770 up_read(&sn9c102_dev_lock);
1da177e4
LT
1771 return -ERESTARTSYS;
1772 }
1773
3770be34
LR
1774 if (cam->state & DEV_DISCONNECTED) {
1775 DBG(1, "Device not present");
1776 err = -ENODEV;
1777 goto out;
1778 }
1779
1da177e4 1780 if (cam->users) {
3770be34
LR
1781 DBG(2, "Device /dev/video%d is already in use",
1782 cam->v4ldev->minor);
f327ebbd 1783 DBG(3, "Simultaneous opens are not supported");
3770be34
LR
1784 /*
1785 open() must follow the open flags and should block
1786 eventually while the device is in use.
1787 */
1da177e4
LT
1788 if ((filp->f_flags & O_NONBLOCK) ||
1789 (filp->f_flags & O_NDELAY)) {
1790 err = -EWOULDBLOCK;
1791 goto out;
1792 }
3770be34
LR
1793 DBG(2, "A blocking open() has been requested. Wait for the "
1794 "device to be released...");
1795 up_read(&sn9c102_dev_lock);
1796 /*
1797 We will not release the "open_mutex" lock, so that only one
1798 process can be in the wait queue below. This way the process
1799 will be sleeping while holding the lock, without loosing its
1800 priority after any wake_up().
1801 */
1802 err = wait_event_interruptible_exclusive(cam->wait_open,
1803 (cam->state & DEV_DISCONNECTED)
d56410e0 1804 || !cam->users);
3770be34
LR
1805 down_read(&sn9c102_dev_lock);
1806 if (err)
1807 goto out;
1da177e4 1808 if (cam->state & DEV_DISCONNECTED) {
3770be34
LR
1809 err = -ENODEV;
1810 goto out;
1da177e4 1811 }
1da177e4
LT
1812 }
1813
1da177e4
LT
1814 if (cam->state & DEV_MISCONFIGURED) {
1815 err = sn9c102_init(cam);
1816 if (err) {
1817 DBG(1, "Initialization failed again. "
a966f3e7 1818 "I will retry on next open().");
1da177e4
LT
1819 goto out;
1820 }
1821 cam->state &= ~DEV_MISCONFIGURED;
1822 }
1823
1824 if ((err = sn9c102_start_transfer(cam)))
1825 goto out;
1826
1827 filp->private_data = cam;
1828 cam->users++;
1829 cam->io = IO_NONE;
1830 cam->stream = STREAM_OFF;
1831 cam->nbuffers = 0;
1832 cam->frame_count = 0;
1833 sn9c102_empty_framequeues(cam);
1834
a966f3e7 1835 DBG(3, "Video device /dev/video%d is open", cam->v4ldev->minor);
1da177e4
LT
1836
1837out:
3770be34
LR
1838 mutex_unlock(&cam->open_mutex);
1839 if (err)
1840 kref_put(&cam->kref, sn9c102_release_resources);
1841
1842 up_read(&sn9c102_dev_lock);
1da177e4
LT
1843 return err;
1844}
1845
1846
1847static int sn9c102_release(struct inode* inode, struct file* filp)
1848{
3770be34 1849 struct sn9c102_device* cam;
1da177e4 1850
3770be34 1851 down_write(&sn9c102_dev_lock);
1da177e4 1852
3770be34 1853 cam = video_get_drvdata(video_devdata(filp));
1da177e4 1854
3770be34 1855 sn9c102_stop_transfer(cam);
1da177e4 1856 sn9c102_release_buffers(cam);
1da177e4 1857 cam->users--;
3770be34 1858 wake_up_interruptible_nr(&cam->wait_open, 1);
1da177e4 1859
a966f3e7 1860 DBG(3, "Video device /dev/video%d closed", cam->v4ldev->minor);
1da177e4 1861
3770be34
LR
1862 kref_put(&cam->kref, sn9c102_release_resources);
1863
1864 up_write(&sn9c102_dev_lock);
1da177e4
LT
1865
1866 return 0;
1867}
1868
1869
1870static ssize_t
1871sn9c102_read(struct file* filp, char __user * buf, size_t count, loff_t* f_pos)
1872{
1873 struct sn9c102_device* cam = video_get_drvdata(video_devdata(filp));
1874 struct sn9c102_frame_t* f, * i;
1875 unsigned long lock_flags;
2ffab02f 1876 long timeout;
1da177e4
LT
1877 int err = 0;
1878
4186ecf8 1879 if (mutex_lock_interruptible(&cam->fileop_mutex))
1da177e4
LT
1880 return -ERESTARTSYS;
1881
1882 if (cam->state & DEV_DISCONNECTED) {
a966f3e7 1883 DBG(1, "Device not present");
4186ecf8 1884 mutex_unlock(&cam->fileop_mutex);
1da177e4
LT
1885 return -ENODEV;
1886 }
1887
1888 if (cam->state & DEV_MISCONFIGURED) {
a966f3e7
LR
1889 DBG(1, "The camera is misconfigured. Close and open it "
1890 "again.");
4186ecf8 1891 mutex_unlock(&cam->fileop_mutex);
1da177e4
LT
1892 return -EIO;
1893 }
1894
1895 if (cam->io == IO_MMAP) {
1896 DBG(3, "Close and open the device again to choose "
a966f3e7 1897 "the read method");
4186ecf8 1898 mutex_unlock(&cam->fileop_mutex);
f423b9a8 1899 return -EBUSY;
1da177e4
LT
1900 }
1901
1902 if (cam->io == IO_NONE) {
1903 if (!sn9c102_request_buffers(cam,cam->nreadbuffers, IO_READ)) {
a966f3e7 1904 DBG(1, "read() failed, not enough memory");
4186ecf8 1905 mutex_unlock(&cam->fileop_mutex);
1da177e4
LT
1906 return -ENOMEM;
1907 }
1908 cam->io = IO_READ;
1909 cam->stream = STREAM_ON;
a966f3e7
LR
1910 }
1911
1912 if (list_empty(&cam->inqueue)) {
1913 if (!list_empty(&cam->outqueue))
1914 sn9c102_empty_framequeues(cam);
1da177e4
LT
1915 sn9c102_queue_unusedframes(cam);
1916 }
1917
1918 if (!count) {
4186ecf8 1919 mutex_unlock(&cam->fileop_mutex);
1da177e4
LT
1920 return 0;
1921 }
1922
1923 if (list_empty(&cam->outqueue)) {
1924 if (filp->f_flags & O_NONBLOCK) {
4186ecf8 1925 mutex_unlock(&cam->fileop_mutex);
1da177e4
LT
1926 return -EAGAIN;
1927 }
f327ebbd
LR
1928 if (!cam->module_param.frame_timeout) {
1929 err = wait_event_interruptible
1930 ( cam->wait_frame,
1931 (!list_empty(&cam->outqueue)) ||
1932 (cam->state & DEV_DISCONNECTED) ||
1933 (cam->state & DEV_MISCONFIGURED) );
1934 if (err) {
1935 mutex_unlock(&cam->fileop_mutex);
1936 return err;
1937 }
1938 } else {
f423b9a8
LR
1939 timeout = wait_event_interruptible_timeout
1940 ( cam->wait_frame,
1941 (!list_empty(&cam->outqueue)) ||
1942 (cam->state & DEV_DISCONNECTED) ||
1943 (cam->state & DEV_MISCONFIGURED),
1944 cam->module_param.frame_timeout *
1945 1000 * msecs_to_jiffies(1) );
1946 if (timeout < 0) {
1947 mutex_unlock(&cam->fileop_mutex);
1948 return timeout;
f327ebbd
LR
1949 } else if (timeout == 0 &&
1950 !(cam->state & DEV_DISCONNECTED)) {
1951 DBG(1, "Video frame timeout elapsed");
1952 mutex_unlock(&cam->fileop_mutex);
1953 return -EIO;
1954 }
1da177e4
LT
1955 }
1956 if (cam->state & DEV_DISCONNECTED) {
4186ecf8 1957 mutex_unlock(&cam->fileop_mutex);
1da177e4
LT
1958 return -ENODEV;
1959 }
f327ebbd 1960 if (cam->state & DEV_MISCONFIGURED) {
4186ecf8 1961 mutex_unlock(&cam->fileop_mutex);
1da177e4
LT
1962 return -EIO;
1963 }
1964 }
1965
1966 f = list_entry(cam->outqueue.prev, struct sn9c102_frame_t, frame);
1967
a966f3e7
LR
1968 if (count > f->buf.bytesused)
1969 count = f->buf.bytesused;
1970
1971 if (copy_to_user(buf, f->bufmem, count)) {
1972 err = -EFAULT;
1973 goto exit;
1974 }
1975 *f_pos += count;
1976
1977exit:
1da177e4
LT
1978 spin_lock_irqsave(&cam->queue_lock, lock_flags);
1979 list_for_each_entry(i, &cam->outqueue, frame)
1980 i->state = F_UNUSED;
1981 INIT_LIST_HEAD(&cam->outqueue);
1982 spin_unlock_irqrestore(&cam->queue_lock, lock_flags);
1983
1984 sn9c102_queue_unusedframes(cam);
1985
a966f3e7
LR
1986 PDBGG("Frame #%lu, bytes read: %zu",
1987 (unsigned long)f->buf.index, count);
1da177e4 1988
4186ecf8 1989 mutex_unlock(&cam->fileop_mutex);
1da177e4
LT
1990
1991 return count;
1992}
1993
1994
1995static unsigned int sn9c102_poll(struct file *filp, poll_table *wait)
1996{
1997 struct sn9c102_device* cam = video_get_drvdata(video_devdata(filp));
a966f3e7
LR
1998 struct sn9c102_frame_t* f;
1999 unsigned long lock_flags;
1da177e4
LT
2000 unsigned int mask = 0;
2001
4186ecf8 2002 if (mutex_lock_interruptible(&cam->fileop_mutex))
1da177e4
LT
2003 return POLLERR;
2004
2005 if (cam->state & DEV_DISCONNECTED) {
a966f3e7 2006 DBG(1, "Device not present");
1da177e4
LT
2007 goto error;
2008 }
2009
2010 if (cam->state & DEV_MISCONFIGURED) {
a966f3e7
LR
2011 DBG(1, "The camera is misconfigured. Close and open it "
2012 "again.");
1da177e4
LT
2013 goto error;
2014 }
2015
2016 if (cam->io == IO_NONE) {
2017 if (!sn9c102_request_buffers(cam, cam->nreadbuffers,
d56410e0 2018 IO_READ)) {
a966f3e7 2019 DBG(1, "poll() failed, not enough memory");
1da177e4
LT
2020 goto error;
2021 }
2022 cam->io = IO_READ;
2023 cam->stream = STREAM_ON;
2024 }
2025
a966f3e7
LR
2026 if (cam->io == IO_READ) {
2027 spin_lock_irqsave(&cam->queue_lock, lock_flags);
2028 list_for_each_entry(f, &cam->outqueue, frame)
2029 f->state = F_UNUSED;
2030 INIT_LIST_HEAD(&cam->outqueue);
2031 spin_unlock_irqrestore(&cam->queue_lock, lock_flags);
1da177e4 2032 sn9c102_queue_unusedframes(cam);
a966f3e7 2033 }
1da177e4
LT
2034
2035 poll_wait(filp, &cam->wait_frame, wait);
2036
2037 if (!list_empty(&cam->outqueue))
2038 mask |= POLLIN | POLLRDNORM;
2039
4186ecf8 2040 mutex_unlock(&cam->fileop_mutex);
1da177e4
LT
2041
2042 return mask;
2043
2044error:
4186ecf8 2045 mutex_unlock(&cam->fileop_mutex);
1da177e4
LT
2046 return POLLERR;
2047}
2048
2049
2050static void sn9c102_vm_open(struct vm_area_struct* vma)
2051{
2052 struct sn9c102_frame_t* f = vma->vm_private_data;
2053 f->vma_use_count++;
2054}
2055
2056
2057static void sn9c102_vm_close(struct vm_area_struct* vma)
2058{
2059 /* NOTE: buffers are not freed here */
2060 struct sn9c102_frame_t* f = vma->vm_private_data;
2061 f->vma_use_count--;
2062}
2063
2064
2065static struct vm_operations_struct sn9c102_vm_ops = {
2066 .open = sn9c102_vm_open,
2067 .close = sn9c102_vm_close,
2068};
2069
2070
2071static int sn9c102_mmap(struct file* filp, struct vm_area_struct *vma)
2072{
2073 struct sn9c102_device* cam = video_get_drvdata(video_devdata(filp));
2074 unsigned long size = vma->vm_end - vma->vm_start,
d56410e0 2075 start = vma->vm_start;
cd6fcc55 2076 void *pos;
1da177e4
LT
2077 u32 i;
2078
4186ecf8 2079 if (mutex_lock_interruptible(&cam->fileop_mutex))
1da177e4
LT
2080 return -ERESTARTSYS;
2081
2082 if (cam->state & DEV_DISCONNECTED) {
a966f3e7 2083 DBG(1, "Device not present");
4186ecf8 2084 mutex_unlock(&cam->fileop_mutex);
1da177e4
LT
2085 return -ENODEV;
2086 }
2087
2088 if (cam->state & DEV_MISCONFIGURED) {
a966f3e7
LR
2089 DBG(1, "The camera is misconfigured. Close and open it "
2090 "again.");
4186ecf8 2091 mutex_unlock(&cam->fileop_mutex);
1da177e4
LT
2092 return -EIO;
2093 }
2094
f423b9a8
LR
2095 if (!(vma->vm_flags & (VM_WRITE | VM_READ))) {
2096 mutex_unlock(&cam->fileop_mutex);
2097 return -EACCES;
2098 }
2099
2100 if (cam->io != IO_MMAP ||
1da177e4 2101 size != PAGE_ALIGN(cam->frame[0].buf.length)) {
4186ecf8 2102 mutex_unlock(&cam->fileop_mutex);
1da177e4
LT
2103 return -EINVAL;
2104 }
2105
2106 for (i = 0; i < cam->nbuffers; i++) {
2107 if ((cam->frame[i].buf.m.offset>>PAGE_SHIFT) == vma->vm_pgoff)
2108 break;
2109 }
2110 if (i == cam->nbuffers) {
4186ecf8 2111 mutex_unlock(&cam->fileop_mutex);
1da177e4
LT
2112 return -EINVAL;
2113 }
2114
1da177e4 2115 vma->vm_flags |= VM_IO;
cd6fcc55 2116 vma->vm_flags |= VM_RESERVED;
1da177e4 2117
cd6fcc55 2118 pos = cam->frame[i].bufmem;
1da177e4 2119 while (size > 0) { /* size is page-aligned */
cd6fcc55 2120 if (vm_insert_page(vma, start, vmalloc_to_page(pos))) {
4186ecf8 2121 mutex_unlock(&cam->fileop_mutex);
1da177e4
LT
2122 return -EAGAIN;
2123 }
2124 start += PAGE_SIZE;
2125 pos += PAGE_SIZE;
2126 size -= PAGE_SIZE;
2127 }
2128
2129 vma->vm_ops = &sn9c102_vm_ops;
2130 vma->vm_private_data = &cam->frame[i];
1da177e4
LT
2131 sn9c102_vm_open(vma);
2132
4186ecf8 2133 mutex_unlock(&cam->fileop_mutex);
1da177e4
LT
2134
2135 return 0;
2136}
2137
a966f3e7 2138/*****************************************************************************/
1da177e4 2139
a966f3e7
LR
2140static int
2141sn9c102_vidioc_querycap(struct sn9c102_device* cam, void __user * arg)
1da177e4 2142{
a966f3e7
LR
2143 struct v4l2_capability cap = {
2144 .driver = "sn9c102",
2145 .version = SN9C102_MODULE_VERSION_CODE,
2146 .capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE |
d56410e0 2147 V4L2_CAP_STREAMING,
a966f3e7
LR
2148 };
2149
2150 strlcpy(cap.card, cam->v4ldev->name, sizeof(cap.card));
2151 if (usb_make_path(cam->usbdev, cap.bus_info, sizeof(cap.bus_info)) < 0)
cd6fcc55 2152 strlcpy(cap.bus_info, cam->usbdev->dev.bus_id,
d56410e0 2153 sizeof(cap.bus_info));
a966f3e7
LR
2154
2155 if (copy_to_user(arg, &cap, sizeof(cap)))
2156 return -EFAULT;
1da177e4 2157
a966f3e7
LR
2158 return 0;
2159}
1da177e4 2160
1da177e4 2161
a966f3e7
LR
2162static int
2163sn9c102_vidioc_enuminput(struct sn9c102_device* cam, void __user * arg)
2164{
2165 struct v4l2_input i;
1da177e4 2166
a966f3e7
LR
2167 if (copy_from_user(&i, arg, sizeof(i)))
2168 return -EFAULT;
1da177e4 2169
a966f3e7
LR
2170 if (i.index)
2171 return -EINVAL;
1da177e4 2172
a966f3e7 2173 memset(&i, 0, sizeof(i));
cd6fcc55 2174 strcpy(i.name, "Camera");
2ffab02f 2175 i.type = V4L2_INPUT_TYPE_CAMERA;
1da177e4 2176
a966f3e7
LR
2177 if (copy_to_user(arg, &i, sizeof(i)))
2178 return -EFAULT;
1da177e4 2179
a966f3e7
LR
2180 return 0;
2181}
1da177e4 2182
1da177e4 2183
a966f3e7 2184static int
2ffab02f
LR
2185sn9c102_vidioc_g_input(struct sn9c102_device* cam, void __user * arg)
2186{
2187 int index = 0;
2188
2189 if (copy_to_user(arg, &index, sizeof(index)))
2190 return -EFAULT;
2191
2192 return 0;
2193}
2194
2195
2196static int
2197sn9c102_vidioc_s_input(struct sn9c102_device* cam, void __user * arg)
a966f3e7
LR
2198{
2199 int index;
1da177e4 2200
a966f3e7
LR
2201 if (copy_from_user(&index, arg, sizeof(index)))
2202 return -EFAULT;
1da177e4 2203
a966f3e7 2204 if (index != 0)
1da177e4 2205 return -EINVAL;
1da177e4 2206
a966f3e7
LR
2207 return 0;
2208}
1da177e4 2209
1da177e4 2210
a966f3e7
LR
2211static int
2212sn9c102_vidioc_query_ctrl(struct sn9c102_device* cam, void __user * arg)
2213{
2ffab02f 2214 struct sn9c102_sensor* s = &cam->sensor;
a966f3e7
LR
2215 struct v4l2_queryctrl qc;
2216 u8 i;
1da177e4 2217
a966f3e7
LR
2218 if (copy_from_user(&qc, arg, sizeof(qc)))
2219 return -EFAULT;
1da177e4 2220
a966f3e7
LR
2221 for (i = 0; i < ARRAY_SIZE(s->qctrl); i++)
2222 if (qc.id && qc.id == s->qctrl[i].id) {
2223 memcpy(&qc, &(s->qctrl[i]), sizeof(qc));
2224 if (copy_to_user(arg, &qc, sizeof(qc)))
2225 return -EFAULT;
2226 return 0;
2227 }
1da177e4 2228
a966f3e7
LR
2229 return -EINVAL;
2230}
1da177e4 2231
1da177e4 2232
a966f3e7
LR
2233static int
2234sn9c102_vidioc_g_ctrl(struct sn9c102_device* cam, void __user * arg)
2235{
2ffab02f 2236 struct sn9c102_sensor* s = &cam->sensor;
a966f3e7
LR
2237 struct v4l2_control ctrl;
2238 int err = 0;
2239 u8 i;
1da177e4 2240
a966f3e7
LR
2241 if (!s->get_ctrl && !s->set_ctrl)
2242 return -EINVAL;
1da177e4 2243
a966f3e7
LR
2244 if (copy_from_user(&ctrl, arg, sizeof(ctrl)))
2245 return -EFAULT;
2246
2247 if (!s->get_ctrl) {
52950ed4 2248 for (i = 0; i < ARRAY_SIZE(s->qctrl); i++)
a966f3e7
LR
2249 if (ctrl.id && ctrl.id == s->qctrl[i].id) {
2250 ctrl.value = s->_qctrl[i].default_value;
2251 goto exit;
1da177e4 2252 }
a966f3e7
LR
2253 return -EINVAL;
2254 } else
2255 err = s->get_ctrl(cam, &ctrl);
1da177e4 2256
a966f3e7
LR
2257exit:
2258 if (copy_to_user(arg, &ctrl, sizeof(ctrl)))
2259 return -EFAULT;
1da177e4 2260
f327ebbd
LR
2261 PDBGG("VIDIOC_G_CTRL: id %lu, value %lu",
2262 (unsigned long)ctrl.id, (unsigned long)ctrl.value);
2263
a966f3e7
LR
2264 return err;
2265}
1da177e4 2266
1da177e4 2267
a966f3e7
LR
2268static int
2269sn9c102_vidioc_s_ctrl(struct sn9c102_device* cam, void __user * arg)
2270{
2ffab02f 2271 struct sn9c102_sensor* s = &cam->sensor;
a966f3e7
LR
2272 struct v4l2_control ctrl;
2273 u8 i;
2274 int err = 0;
1da177e4 2275
a966f3e7
LR
2276 if (!s->set_ctrl)
2277 return -EINVAL;
1da177e4 2278
a966f3e7
LR
2279 if (copy_from_user(&ctrl, arg, sizeof(ctrl)))
2280 return -EFAULT;
1da177e4 2281
a966f3e7
LR
2282 for (i = 0; i < ARRAY_SIZE(s->qctrl); i++)
2283 if (ctrl.id == s->qctrl[i].id) {
2ffab02f
LR
2284 if (s->qctrl[i].flags & V4L2_CTRL_FLAG_DISABLED)
2285 return -EINVAL;
a966f3e7
LR
2286 if (ctrl.value < s->qctrl[i].minimum ||
2287 ctrl.value > s->qctrl[i].maximum)
2288 return -ERANGE;
2289 ctrl.value -= ctrl.value % s->qctrl[i].step;
2290 break;
2291 }
1da177e4 2292
a966f3e7
LR
2293 if ((err = s->set_ctrl(cam, &ctrl)))
2294 return err;
1da177e4 2295
a966f3e7 2296 s->_qctrl[i].default_value = ctrl.value;
1da177e4 2297
a966f3e7
LR
2298 PDBGG("VIDIOC_S_CTRL: id %lu, value %lu",
2299 (unsigned long)ctrl.id, (unsigned long)ctrl.value);
1da177e4 2300
a966f3e7
LR
2301 return 0;
2302}
1da177e4 2303
1da177e4 2304
a966f3e7
LR
2305static int
2306sn9c102_vidioc_cropcap(struct sn9c102_device* cam, void __user * arg)
2307{
2ffab02f 2308 struct v4l2_cropcap* cc = &(cam->sensor.cropcap);
1da177e4 2309
a966f3e7
LR
2310 cc->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
2311 cc->pixelaspect.numerator = 1;
2312 cc->pixelaspect.denominator = 1;
1da177e4 2313
a966f3e7
LR
2314 if (copy_to_user(arg, cc, sizeof(*cc)))
2315 return -EFAULT;
1da177e4 2316
a966f3e7
LR
2317 return 0;
2318}
1da177e4 2319
1da177e4 2320
a966f3e7
LR
2321static int
2322sn9c102_vidioc_g_crop(struct sn9c102_device* cam, void __user * arg)
2323{
2ffab02f 2324 struct sn9c102_sensor* s = &cam->sensor;
a966f3e7
LR
2325 struct v4l2_crop crop = {
2326 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
2327 };
1da177e4 2328
a966f3e7 2329 memcpy(&(crop.c), &(s->_rect), sizeof(struct v4l2_rect));
1da177e4 2330
a966f3e7
LR
2331 if (copy_to_user(arg, &crop, sizeof(crop)))
2332 return -EFAULT;
1da177e4 2333
a966f3e7
LR
2334 return 0;
2335}
1da177e4 2336
1da177e4 2337
a966f3e7
LR
2338static int
2339sn9c102_vidioc_s_crop(struct sn9c102_device* cam, void __user * arg)
2340{
2ffab02f 2341 struct sn9c102_sensor* s = &cam->sensor;
a966f3e7
LR
2342 struct v4l2_crop crop;
2343 struct v4l2_rect* rect;
2344 struct v4l2_rect* bounds = &(s->cropcap.bounds);
2345 struct v4l2_pix_format* pix_format = &(s->pix_format);
2346 u8 scale;
2347 const enum sn9c102_stream_state stream = cam->stream;
2348 const u32 nbuffers = cam->nbuffers;
2349 u32 i;
2350 int err = 0;
1da177e4 2351
a966f3e7
LR
2352 if (copy_from_user(&crop, arg, sizeof(crop)))
2353 return -EFAULT;
1da177e4 2354
a966f3e7 2355 rect = &(crop.c);
1da177e4 2356
a966f3e7
LR
2357 if (crop.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
2358 return -EINVAL;
1da177e4 2359
a966f3e7
LR
2360 if (cam->module_param.force_munmap)
2361 for (i = 0; i < cam->nbuffers; i++)
2362 if (cam->frame[i].vma_use_count) {
2363 DBG(3, "VIDIOC_S_CROP failed. "
2364 "Unmap the buffers first.");
f423b9a8 2365 return -EBUSY;
a966f3e7 2366 }
1da177e4 2367
a966f3e7
LR
2368 /* Preserve R,G or B origin */
2369 rect->left = (s->_rect.left & 1L) ? rect->left | 1L : rect->left & ~1L;
2370 rect->top = (s->_rect.top & 1L) ? rect->top | 1L : rect->top & ~1L;
2371
2372 if (rect->width < 16)
2373 rect->width = 16;
2374 if (rect->height < 16)
2375 rect->height = 16;
2376 if (rect->width > bounds->width)
2377 rect->width = bounds->width;
2378 if (rect->height > bounds->height)
2379 rect->height = bounds->height;
2380 if (rect->left < bounds->left)
2381 rect->left = bounds->left;
2382 if (rect->top < bounds->top)
2383 rect->top = bounds->top;
2384 if (rect->left + rect->width > bounds->left + bounds->width)
2385 rect->left = bounds->left+bounds->width - rect->width;
2386 if (rect->top + rect->height > bounds->top + bounds->height)
2387 rect->top = bounds->top+bounds->height - rect->height;
2388
2389 rect->width &= ~15L;
2390 rect->height &= ~15L;
2391
2392 if (SN9C102_PRESERVE_IMGSCALE) {
2393 /* Calculate the actual scaling factor */
2394 u32 a, b;
2395 a = rect->width * rect->height;
2396 b = pix_format->width * pix_format->height;
2397 scale = b ? (u8)((a / b) < 4 ? 1 : ((a / b) < 16 ? 2 : 4)) : 1;
2398 } else
2399 scale = 1;
2400
2401 if (cam->stream == STREAM_ON)
2402 if ((err = sn9c102_stream_interrupt(cam)))
2403 return err;
1da177e4 2404
a966f3e7
LR
2405 if (copy_to_user(arg, &crop, sizeof(crop))) {
2406 cam->stream = stream;
2407 return -EFAULT;
1da177e4
LT
2408 }
2409
a966f3e7
LR
2410 if (cam->module_param.force_munmap || cam->io == IO_READ)
2411 sn9c102_release_buffers(cam);
1da177e4 2412
a966f3e7
LR
2413 err = sn9c102_set_crop(cam, rect);
2414 if (s->set_crop)
2415 err += s->set_crop(cam, rect);
2416 err += sn9c102_set_scale(cam, scale);
1da177e4 2417
a966f3e7
LR
2418 if (err) { /* atomic, no rollback in ioctl() */
2419 cam->state |= DEV_MISCONFIGURED;
2420 DBG(1, "VIDIOC_S_CROP failed because of hardware problems. To "
2421 "use the camera, close and open /dev/video%d again.",
2422 cam->v4ldev->minor);
2423 return -EIO;
2424 }
1da177e4 2425
a966f3e7
LR
2426 s->pix_format.width = rect->width/scale;
2427 s->pix_format.height = rect->height/scale;
2428 memcpy(&(s->_rect), rect, sizeof(*rect));
1da177e4 2429
a966f3e7
LR
2430 if ((cam->module_param.force_munmap || cam->io == IO_READ) &&
2431 nbuffers != sn9c102_request_buffers(cam, nbuffers, cam->io)) {
2432 cam->state |= DEV_MISCONFIGURED;
2433 DBG(1, "VIDIOC_S_CROP failed because of not enough memory. To "
2434 "use the camera, close and open /dev/video%d again.",
2435 cam->v4ldev->minor);
2436 return -ENOMEM;
1da177e4
LT
2437 }
2438
a966f3e7
LR
2439 if (cam->io == IO_READ)
2440 sn9c102_empty_framequeues(cam);
2441 else if (cam->module_param.force_munmap)
2442 sn9c102_requeue_outqueue(cam);
1da177e4 2443
a966f3e7 2444 cam->stream = stream;
1da177e4 2445
a966f3e7
LR
2446 return 0;
2447}
1da177e4 2448
1da177e4 2449
f327ebbd
LR
2450static int
2451sn9c102_vidioc_enum_framesizes(struct sn9c102_device* cam, void __user * arg)
2452{
2453 struct v4l2_frmsizeenum frmsize;
2454
2455 if (copy_from_user(&frmsize, arg, sizeof(frmsize)))
2456 return -EFAULT;
2457
2458 if (frmsize.index != 0)
2459 return -EINVAL;
2460
2461 switch (cam->bridge) {
2462 case BRIDGE_SN9C101:
2463 case BRIDGE_SN9C102:
2464 case BRIDGE_SN9C103:
2465 if (frmsize.pixel_format != V4L2_PIX_FMT_SN9C10X &&
2466 frmsize.pixel_format != V4L2_PIX_FMT_SBGGR8)
2467 return -EINVAL;
2468 case BRIDGE_SN9C105:
2469 case BRIDGE_SN9C120:
2470 if (frmsize.pixel_format != V4L2_PIX_FMT_JPEG &&
2471 frmsize.pixel_format != V4L2_PIX_FMT_SBGGR8)
2472 return -EINVAL;
2473 }
2474
2475 frmsize.type = V4L2_FRMSIZE_TYPE_STEPWISE;
2476 frmsize.stepwise.min_width = frmsize.stepwise.step_width = 16;
2477 frmsize.stepwise.min_height = frmsize.stepwise.step_height = 16;
2478 frmsize.stepwise.max_width = cam->sensor.cropcap.bounds.width;
2479 frmsize.stepwise.max_height = cam->sensor.cropcap.bounds.height;
2480 memset(&frmsize.reserved, 0, sizeof(frmsize.reserved));
2481
2482 if (copy_to_user(arg, &frmsize, sizeof(frmsize)))
2483 return -EFAULT;
2484
2485 return 0;
2486}
2487
2488
a966f3e7
LR
2489static int
2490sn9c102_vidioc_enum_fmt(struct sn9c102_device* cam, void __user * arg)
2491{
2492 struct v4l2_fmtdesc fmtd;
1da177e4 2493
a966f3e7
LR
2494 if (copy_from_user(&fmtd, arg, sizeof(fmtd)))
2495 return -EFAULT;
1da177e4 2496
f327ebbd
LR
2497 if (fmtd.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
2498 return -EINVAL;
2499
a966f3e7
LR
2500 if (fmtd.index == 0) {
2501 strcpy(fmtd.description, "bayer rgb");
2502 fmtd.pixelformat = V4L2_PIX_FMT_SBGGR8;
2503 } else if (fmtd.index == 1) {
f327ebbd
LR
2504 switch (cam->bridge) {
2505 case BRIDGE_SN9C101:
2506 case BRIDGE_SN9C102:
2507 case BRIDGE_SN9C103:
f423b9a8
LR
2508 strcpy(fmtd.description, "compressed");
2509 fmtd.pixelformat = V4L2_PIX_FMT_SN9C10X;
f327ebbd
LR
2510 break;
2511 case BRIDGE_SN9C105:
2512 case BRIDGE_SN9C120:
2513 strcpy(fmtd.description, "JPEG");
2514 fmtd.pixelformat = V4L2_PIX_FMT_JPEG;
2515 break;
2516 }
a966f3e7
LR
2517 fmtd.flags = V4L2_FMT_FLAG_COMPRESSED;
2518 } else
2519 return -EINVAL;
1da177e4 2520
a966f3e7
LR
2521 fmtd.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
2522 memset(&fmtd.reserved, 0, sizeof(fmtd.reserved));
1da177e4 2523
a966f3e7
LR
2524 if (copy_to_user(arg, &fmtd, sizeof(fmtd)))
2525 return -EFAULT;
1da177e4 2526
a966f3e7
LR
2527 return 0;
2528}
1da177e4 2529
1da177e4 2530
a966f3e7
LR
2531static int
2532sn9c102_vidioc_g_fmt(struct sn9c102_device* cam, void __user * arg)
2533{
2534 struct v4l2_format format;
2ffab02f 2535 struct v4l2_pix_format* pfmt = &(cam->sensor.pix_format);
1da177e4 2536
a966f3e7
LR
2537 if (copy_from_user(&format, arg, sizeof(format)))
2538 return -EFAULT;
1da177e4 2539
a966f3e7
LR
2540 if (format.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
2541 return -EINVAL;
1da177e4 2542
f423b9a8
LR
2543 pfmt->colorspace = (pfmt->pixelformat == V4L2_PIX_FMT_JPEG) ?
2544 V4L2_COLORSPACE_JPEG : V4L2_COLORSPACE_SRGB;
2545 pfmt->bytesperline = (pfmt->pixelformat == V4L2_PIX_FMT_SN9C10X ||
2546 pfmt->pixelformat == V4L2_PIX_FMT_JPEG)
d56410e0 2547 ? 0 : (pfmt->width * pfmt->priv) / 8;
a966f3e7
LR
2548 pfmt->sizeimage = pfmt->height * ((pfmt->width*pfmt->priv)/8);
2549 pfmt->field = V4L2_FIELD_NONE;
2550 memcpy(&(format.fmt.pix), pfmt, sizeof(*pfmt));
1da177e4 2551
a966f3e7
LR
2552 if (copy_to_user(arg, &format, sizeof(format)))
2553 return -EFAULT;
1da177e4 2554
a966f3e7
LR
2555 return 0;
2556}
1da177e4 2557
1da177e4 2558
a966f3e7
LR
2559static int
2560sn9c102_vidioc_try_s_fmt(struct sn9c102_device* cam, unsigned int cmd,
d56410e0 2561 void __user * arg)
a966f3e7 2562{
2ffab02f 2563 struct sn9c102_sensor* s = &cam->sensor;
a966f3e7
LR
2564 struct v4l2_format format;
2565 struct v4l2_pix_format* pix;
2566 struct v4l2_pix_format* pfmt = &(s->pix_format);
2567 struct v4l2_rect* bounds = &(s->cropcap.bounds);
2568 struct v4l2_rect rect;
2569 u8 scale;
2570 const enum sn9c102_stream_state stream = cam->stream;
2571 const u32 nbuffers = cam->nbuffers;
2572 u32 i;
2573 int err = 0;
1da177e4 2574
a966f3e7
LR
2575 if (copy_from_user(&format, arg, sizeof(format)))
2576 return -EFAULT;
1da177e4 2577
a966f3e7 2578 pix = &(format.fmt.pix);
1da177e4 2579
a966f3e7
LR
2580 if (format.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
2581 return -EINVAL;
1da177e4 2582
a966f3e7 2583 memcpy(&rect, &(s->_rect), sizeof(rect));
1da177e4 2584
a966f3e7
LR
2585 { /* calculate the actual scaling factor */
2586 u32 a, b;
2587 a = rect.width * rect.height;
2588 b = pix->width * pix->height;
2589 scale = b ? (u8)((a / b) < 4 ? 1 : ((a / b) < 16 ? 2 : 4)) : 1;
1da177e4
LT
2590 }
2591
a966f3e7
LR
2592 rect.width = scale * pix->width;
2593 rect.height = scale * pix->height;
1da177e4 2594
a966f3e7
LR
2595 if (rect.width < 16)
2596 rect.width = 16;
2597 if (rect.height < 16)
2598 rect.height = 16;
2599 if (rect.width > bounds->left + bounds->width - rect.left)
2600 rect.width = bounds->left + bounds->width - rect.left;
2601 if (rect.height > bounds->top + bounds->height - rect.top)
2602 rect.height = bounds->top + bounds->height - rect.top;
1da177e4 2603
a966f3e7
LR
2604 rect.width &= ~15L;
2605 rect.height &= ~15L;
1da177e4 2606
a966f3e7
LR
2607 { /* adjust the scaling factor */
2608 u32 a, b;
2609 a = rect.width * rect.height;
2610 b = pix->width * pix->height;
2611 scale = b ? (u8)((a / b) < 4 ? 1 : ((a / b) < 16 ? 2 : 4)) : 1;
2612 }
2613
2614 pix->width = rect.width / scale;
2615 pix->height = rect.height / scale;
2616
f327ebbd
LR
2617 switch (cam->bridge) {
2618 case BRIDGE_SN9C101:
2619 case BRIDGE_SN9C102:
2620 case BRIDGE_SN9C103:
f423b9a8
LR
2621 if (pix->pixelformat != V4L2_PIX_FMT_SN9C10X &&
2622 pix->pixelformat != V4L2_PIX_FMT_SBGGR8)
2623 pix->pixelformat = pfmt->pixelformat;
f327ebbd
LR
2624 break;
2625 case BRIDGE_SN9C105:
2626 case BRIDGE_SN9C120:
2627 if (pix->pixelformat != V4L2_PIX_FMT_JPEG &&
2628 pix->pixelformat != V4L2_PIX_FMT_SBGGR8)
2629 pix->pixelformat = pfmt->pixelformat;
2630 break;
2631 }
a966f3e7 2632 pix->priv = pfmt->priv; /* bpp */
f423b9a8
LR
2633 pix->colorspace = (pix->pixelformat == V4L2_PIX_FMT_JPEG) ?
2634 V4L2_COLORSPACE_JPEG : V4L2_COLORSPACE_SRGB;
f327ebbd
LR
2635 pix->bytesperline = (pix->pixelformat == V4L2_PIX_FMT_SN9C10X ||
2636 pix->pixelformat == V4L2_PIX_FMT_JPEG)
d56410e0 2637 ? 0 : (pix->width * pix->priv) / 8;
a966f3e7
LR
2638 pix->sizeimage = pix->height * ((pix->width * pix->priv) / 8);
2639 pix->field = V4L2_FIELD_NONE;
2640
2641 if (cmd == VIDIOC_TRY_FMT) {
2642 if (copy_to_user(arg, &format, sizeof(format)))
2643 return -EFAULT;
2644 return 0;
2645 }
1da177e4 2646
a966f3e7 2647 if (cam->module_param.force_munmap)
1da177e4
LT
2648 for (i = 0; i < cam->nbuffers; i++)
2649 if (cam->frame[i].vma_use_count) {
a966f3e7
LR
2650 DBG(3, "VIDIOC_S_FMT failed. Unmap the "
2651 "buffers first.");
f423b9a8 2652 return -EBUSY;
1da177e4
LT
2653 }
2654
a966f3e7
LR
2655 if (cam->stream == STREAM_ON)
2656 if ((err = sn9c102_stream_interrupt(cam)))
2657 return err;
1da177e4 2658
a966f3e7
LR
2659 if (copy_to_user(arg, &format, sizeof(format))) {
2660 cam->stream = stream;
2661 return -EFAULT;
2662 }
1da177e4 2663
a966f3e7 2664 if (cam->module_param.force_munmap || cam->io == IO_READ)
1da177e4 2665 sn9c102_release_buffers(cam);
1da177e4 2666
a966f3e7
LR
2667 err += sn9c102_set_pix_format(cam, pix);
2668 err += sn9c102_set_crop(cam, &rect);
2669 if (s->set_pix_format)
2670 err += s->set_pix_format(cam, pix);
2671 if (s->set_crop)
2672 err += s->set_crop(cam, &rect);
2673 err += sn9c102_set_scale(cam, scale);
1da177e4 2674
a966f3e7
LR
2675 if (err) { /* atomic, no rollback in ioctl() */
2676 cam->state |= DEV_MISCONFIGURED;
2677 DBG(1, "VIDIOC_S_FMT failed because of hardware problems. To "
2678 "use the camera, close and open /dev/video%d again.",
2679 cam->v4ldev->minor);
2680 return -EIO;
2681 }
1da177e4 2682
a966f3e7
LR
2683 memcpy(pfmt, pix, sizeof(*pix));
2684 memcpy(&(s->_rect), &rect, sizeof(rect));
2685
2686 if ((cam->module_param.force_munmap || cam->io == IO_READ) &&
2687 nbuffers != sn9c102_request_buffers(cam, nbuffers, cam->io)) {
2688 cam->state |= DEV_MISCONFIGURED;
2689 DBG(1, "VIDIOC_S_FMT failed because of not enough memory. To "
2690 "use the camera, close and open /dev/video%d again.",
2691 cam->v4ldev->minor);
2692 return -ENOMEM;
1da177e4
LT
2693 }
2694
a966f3e7
LR
2695 if (cam->io == IO_READ)
2696 sn9c102_empty_framequeues(cam);
2697 else if (cam->module_param.force_munmap)
2698 sn9c102_requeue_outqueue(cam);
1da177e4 2699
a966f3e7 2700 cam->stream = stream;
1da177e4 2701
a966f3e7
LR
2702 return 0;
2703}
2704
2705
2706static int
2707sn9c102_vidioc_g_jpegcomp(struct sn9c102_device* cam, void __user * arg)
2708{
f327ebbd 2709 if (copy_to_user(arg, &cam->compression, sizeof(cam->compression)))
a966f3e7 2710 return -EFAULT;
1da177e4 2711
a966f3e7
LR
2712 return 0;
2713}
1da177e4 2714
1da177e4 2715
a966f3e7
LR
2716static int
2717sn9c102_vidioc_s_jpegcomp(struct sn9c102_device* cam, void __user * arg)
2718{
2719 struct v4l2_jpegcompression jc;
2720 const enum sn9c102_stream_state stream = cam->stream;
2721 int err = 0;
1da177e4 2722
a966f3e7
LR
2723 if (copy_from_user(&jc, arg, sizeof(jc)))
2724 return -EFAULT;
1da177e4 2725
a966f3e7
LR
2726 if (jc.quality != 0 && jc.quality != 1)
2727 return -EINVAL;
2728
2729 if (cam->stream == STREAM_ON)
2730 if ((err = sn9c102_stream_interrupt(cam)))
2731 return err;
2732
2733 err += sn9c102_set_compression(cam, &jc);
2734 if (err) { /* atomic, no rollback in ioctl() */
2735 cam->state |= DEV_MISCONFIGURED;
2736 DBG(1, "VIDIOC_S_JPEGCOMP failed because of hardware "
2737 "problems. To use the camera, close and open "
2738 "/dev/video%d again.", cam->v4ldev->minor);
2739 return -EIO;
1da177e4
LT
2740 }
2741
a966f3e7 2742 cam->compression.quality = jc.quality;
1da177e4 2743
a966f3e7 2744 cam->stream = stream;
1da177e4 2745
a966f3e7
LR
2746 return 0;
2747}
1da177e4 2748
a966f3e7
LR
2749
2750static int
2751sn9c102_vidioc_reqbufs(struct sn9c102_device* cam, void __user * arg)
2752{
2753 struct v4l2_requestbuffers rb;
2754 u32 i;
2755 int err;
2756
2757 if (copy_from_user(&rb, arg, sizeof(rb)))
2758 return -EFAULT;
2759
2760 if (rb.type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
2761 rb.memory != V4L2_MEMORY_MMAP)
2762 return -EINVAL;
2763
2764 if (cam->io == IO_READ) {
2765 DBG(3, "Close and open the device again to choose the mmap "
2766 "I/O method");
f423b9a8 2767 return -EBUSY;
a966f3e7
LR
2768 }
2769
2770 for (i = 0; i < cam->nbuffers; i++)
2771 if (cam->frame[i].vma_use_count) {
2772 DBG(3, "VIDIOC_REQBUFS failed. Previous buffers are "
2773 "still mapped.");
f423b9a8 2774 return -EBUSY;
a966f3e7 2775 }
1da177e4 2776
a966f3e7
LR
2777 if (cam->stream == STREAM_ON)
2778 if ((err = sn9c102_stream_interrupt(cam)))
2779 return err;
1da177e4 2780
a966f3e7 2781 sn9c102_empty_framequeues(cam);
1da177e4 2782
a966f3e7
LR
2783 sn9c102_release_buffers(cam);
2784 if (rb.count)
2785 rb.count = sn9c102_request_buffers(cam, rb.count, IO_MMAP);
1da177e4 2786
a966f3e7
LR
2787 if (copy_to_user(arg, &rb, sizeof(rb))) {
2788 sn9c102_release_buffers(cam);
2789 cam->io = IO_NONE;
2790 return -EFAULT;
1da177e4
LT
2791 }
2792
a966f3e7 2793 cam->io = rb.count ? IO_MMAP : IO_NONE;
1da177e4 2794
a966f3e7
LR
2795 return 0;
2796}
1da177e4 2797
1da177e4 2798
a966f3e7
LR
2799static int
2800sn9c102_vidioc_querybuf(struct sn9c102_device* cam, void __user * arg)
2801{
2802 struct v4l2_buffer b;
1da177e4 2803
a966f3e7
LR
2804 if (copy_from_user(&b, arg, sizeof(b)))
2805 return -EFAULT;
1da177e4 2806
a966f3e7
LR
2807 if (b.type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
2808 b.index >= cam->nbuffers || cam->io != IO_MMAP)
2809 return -EINVAL;
1da177e4 2810
a966f3e7 2811 memcpy(&b, &cam->frame[b.index].buf, sizeof(b));
1da177e4 2812
a966f3e7
LR
2813 if (cam->frame[b.index].vma_use_count)
2814 b.flags |= V4L2_BUF_FLAG_MAPPED;
1da177e4 2815
a966f3e7
LR
2816 if (cam->frame[b.index].state == F_DONE)
2817 b.flags |= V4L2_BUF_FLAG_DONE;
2818 else if (cam->frame[b.index].state != F_UNUSED)
2819 b.flags |= V4L2_BUF_FLAG_QUEUED;
1da177e4 2820
a966f3e7
LR
2821 if (copy_to_user(arg, &b, sizeof(b)))
2822 return -EFAULT;
1da177e4 2823
a966f3e7
LR
2824 return 0;
2825}
1da177e4 2826
1da177e4 2827
a966f3e7
LR
2828static int
2829sn9c102_vidioc_qbuf(struct sn9c102_device* cam, void __user * arg)
2830{
2831 struct v4l2_buffer b;
2832 unsigned long lock_flags;
1da177e4 2833
a966f3e7
LR
2834 if (copy_from_user(&b, arg, sizeof(b)))
2835 return -EFAULT;
1da177e4 2836
a966f3e7
LR
2837 if (b.type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
2838 b.index >= cam->nbuffers || cam->io != IO_MMAP)
2839 return -EINVAL;
1da177e4 2840
a966f3e7
LR
2841 if (cam->frame[b.index].state != F_UNUSED)
2842 return -EINVAL;
1da177e4 2843
a966f3e7 2844 cam->frame[b.index].state = F_QUEUED;
1da177e4 2845
a966f3e7
LR
2846 spin_lock_irqsave(&cam->queue_lock, lock_flags);
2847 list_add_tail(&cam->frame[b.index].frame, &cam->inqueue);
2848 spin_unlock_irqrestore(&cam->queue_lock, lock_flags);
1da177e4 2849
a966f3e7 2850 PDBGG("Frame #%lu queued", (unsigned long)b.index);
1da177e4 2851
a966f3e7
LR
2852 return 0;
2853}
1da177e4 2854
1da177e4 2855
a966f3e7
LR
2856static int
2857sn9c102_vidioc_dqbuf(struct sn9c102_device* cam, struct file* filp,
d56410e0 2858 void __user * arg)
a966f3e7
LR
2859{
2860 struct v4l2_buffer b;
2861 struct sn9c102_frame_t *f;
2862 unsigned long lock_flags;
2ffab02f 2863 long timeout;
f327ebbd 2864 int err = 0;
1da177e4 2865
a966f3e7
LR
2866 if (copy_from_user(&b, arg, sizeof(b)))
2867 return -EFAULT;
1da177e4 2868
a966f3e7
LR
2869 if (b.type != V4L2_BUF_TYPE_VIDEO_CAPTURE || cam->io != IO_MMAP)
2870 return -EINVAL;
2871
2872 if (list_empty(&cam->outqueue)) {
2873 if (cam->stream == STREAM_OFF)
2874 return -EINVAL;
2875 if (filp->f_flags & O_NONBLOCK)
2876 return -EAGAIN;
f327ebbd
LR
2877 if (!cam->module_param.frame_timeout) {
2878 err = wait_event_interruptible
2879 ( cam->wait_frame,
2880 (!list_empty(&cam->outqueue)) ||
2881 (cam->state & DEV_DISCONNECTED) ||
2882 (cam->state & DEV_MISCONFIGURED) );
2883 if (err)
2884 return err;
2885 } else {
f423b9a8
LR
2886 timeout = wait_event_interruptible_timeout
2887 ( cam->wait_frame,
2888 (!list_empty(&cam->outqueue)) ||
2889 (cam->state & DEV_DISCONNECTED) ||
2890 (cam->state & DEV_MISCONFIGURED),
2891 cam->module_param.frame_timeout *
2892 1000 * msecs_to_jiffies(1) );
2893 if (timeout < 0)
2894 return timeout;
f327ebbd
LR
2895 else if (timeout == 0 &&
2896 !(cam->state & DEV_DISCONNECTED)) {
2897 DBG(1, "Video frame timeout elapsed");
2898 return -EIO;
2899 }
2900 }
a966f3e7
LR
2901 if (cam->state & DEV_DISCONNECTED)
2902 return -ENODEV;
f327ebbd 2903 if (cam->state & DEV_MISCONFIGURED)
a966f3e7 2904 return -EIO;
1da177e4
LT
2905 }
2906
a966f3e7
LR
2907 spin_lock_irqsave(&cam->queue_lock, lock_flags);
2908 f = list_entry(cam->outqueue.next, struct sn9c102_frame_t, frame);
2909 list_del(cam->outqueue.next);
2910 spin_unlock_irqrestore(&cam->queue_lock, lock_flags);
1da177e4 2911
a966f3e7 2912 f->state = F_UNUSED;
1da177e4 2913
a966f3e7
LR
2914 memcpy(&b, &f->buf, sizeof(b));
2915 if (f->vma_use_count)
2916 b.flags |= V4L2_BUF_FLAG_MAPPED;
2917
2918 if (copy_to_user(arg, &b, sizeof(b)))
2919 return -EFAULT;
2920
2921 PDBGG("Frame #%lu dequeued", (unsigned long)f->buf.index);
2922
2923 return 0;
2924}
2925
2926
2927static int
2928sn9c102_vidioc_streamon(struct sn9c102_device* cam, void __user * arg)
2929{
2930 int type;
2931
2932 if (copy_from_user(&type, arg, sizeof(type)))
2933 return -EFAULT;
2934
2935 if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE || cam->io != IO_MMAP)
2936 return -EINVAL;
2937
a966f3e7
LR
2938 cam->stream = STREAM_ON;
2939
2940 DBG(3, "Stream on");
2941
2942 return 0;
2943}
2944
2945
2946static int
2947sn9c102_vidioc_streamoff(struct sn9c102_device* cam, void __user * arg)
2948{
2949 int type, err;
2950
2951 if (copy_from_user(&type, arg, sizeof(type)))
2952 return -EFAULT;
2953
2954 if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE || cam->io != IO_MMAP)
2955 return -EINVAL;
2956
2957 if (cam->stream == STREAM_ON)
2958 if ((err = sn9c102_stream_interrupt(cam)))
2959 return err;
2960
2961 sn9c102_empty_framequeues(cam);
2962
2963 DBG(3, "Stream off");
2964
2965 return 0;
2966}
2967
2968
2969static int
2970sn9c102_vidioc_g_parm(struct sn9c102_device* cam, void __user * arg)
2971{
2972 struct v4l2_streamparm sp;
2973
2974 if (copy_from_user(&sp, arg, sizeof(sp)))
2975 return -EFAULT;
2976
2977 if (sp.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
2978 return -EINVAL;
2979
2980 sp.parm.capture.extendedmode = 0;
2981 sp.parm.capture.readbuffers = cam->nreadbuffers;
2982
2983 if (copy_to_user(arg, &sp, sizeof(sp)))
2984 return -EFAULT;
2985
2986 return 0;
2987}
2988
2989
2990static int
2991sn9c102_vidioc_s_parm(struct sn9c102_device* cam, void __user * arg)
2992{
2993 struct v4l2_streamparm sp;
2994
2995 if (copy_from_user(&sp, arg, sizeof(sp)))
2996 return -EFAULT;
2997
2998 if (sp.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
2999 return -EINVAL;
3000
3001 sp.parm.capture.extendedmode = 0;
1da177e4 3002
a966f3e7 3003 if (sp.parm.capture.readbuffers == 0)
1da177e4
LT
3004 sp.parm.capture.readbuffers = cam->nreadbuffers;
3005
a966f3e7
LR
3006 if (sp.parm.capture.readbuffers > SN9C102_MAX_FRAMES)
3007 sp.parm.capture.readbuffers = SN9C102_MAX_FRAMES;
1da177e4 3008
a966f3e7
LR
3009 if (copy_to_user(arg, &sp, sizeof(sp)))
3010 return -EFAULT;
1da177e4 3011
a966f3e7 3012 cam->nreadbuffers = sp.parm.capture.readbuffers;
1da177e4 3013
a966f3e7
LR
3014 return 0;
3015}
1da177e4 3016
1da177e4 3017
f327ebbd
LR
3018static int
3019sn9c102_vidioc_enumaudio(struct sn9c102_device* cam, void __user * arg)
3020{
3021 struct v4l2_audio audio;
3022
3023 if (cam->bridge == BRIDGE_SN9C101 || cam->bridge == BRIDGE_SN9C102)
3024 return -EINVAL;
3025
3026 if (copy_from_user(&audio, arg, sizeof(audio)))
3027 return -EFAULT;
3028
3029 if (audio.index != 0)
3030 return -EINVAL;
3031
3032 strcpy(audio.name, "Microphone");
3033 audio.capability = 0;
3034 audio.mode = 0;
3035
3036 if (copy_to_user(arg, &audio, sizeof(audio)))
3037 return -EFAULT;
3038
3039 return 0;
3040}
3041
3042
3043static int
3044sn9c102_vidioc_g_audio(struct sn9c102_device* cam, void __user * arg)
3045{
3046 struct v4l2_audio audio;
3047
3048 if (cam->bridge == BRIDGE_SN9C101 || cam->bridge == BRIDGE_SN9C102)
3049 return -EINVAL;
3050
3051 if (copy_from_user(&audio, arg, sizeof(audio)))
3052 return -EFAULT;
3053
3054 memset(&audio, 0, sizeof(audio));
3055 strcpy(audio.name, "Microphone");
3056
3057 if (copy_to_user(arg, &audio, sizeof(audio)))
3058 return -EFAULT;
3059
3060 return 0;
3061}
3062
3063
3064static int
3065sn9c102_vidioc_s_audio(struct sn9c102_device* cam, void __user * arg)
3066{
3067 struct v4l2_audio audio;
3068
3069 if (cam->bridge == BRIDGE_SN9C101 || cam->bridge == BRIDGE_SN9C102)
3070 return -EINVAL;
3071
3072 if (copy_from_user(&audio, arg, sizeof(audio)))
3073 return -EFAULT;
3074
3075 if (audio.index != 0)
3076 return -EINVAL;
3077
3078 return 0;
3079}
3080
3081
a966f3e7 3082static int sn9c102_ioctl_v4l2(struct inode* inode, struct file* filp,
d56410e0 3083 unsigned int cmd, void __user * arg)
a966f3e7
LR
3084{
3085 struct sn9c102_device* cam = video_get_drvdata(video_devdata(filp));
1da177e4 3086
a966f3e7 3087 switch (cmd) {
1da177e4 3088
a966f3e7
LR
3089 case VIDIOC_QUERYCAP:
3090 return sn9c102_vidioc_querycap(cam, arg);
1da177e4 3091
a966f3e7
LR
3092 case VIDIOC_ENUMINPUT:
3093 return sn9c102_vidioc_enuminput(cam, arg);
1da177e4 3094
a966f3e7 3095 case VIDIOC_G_INPUT:
2ffab02f
LR
3096 return sn9c102_vidioc_g_input(cam, arg);
3097
a966f3e7 3098 case VIDIOC_S_INPUT:
2ffab02f 3099 return sn9c102_vidioc_s_input(cam, arg);
1da177e4 3100
a966f3e7
LR
3101 case VIDIOC_QUERYCTRL:
3102 return sn9c102_vidioc_query_ctrl(cam, arg);
3103
3104 case VIDIOC_G_CTRL:
3105 return sn9c102_vidioc_g_ctrl(cam, arg);
3106
a966f3e7
LR
3107 case VIDIOC_S_CTRL:
3108 return sn9c102_vidioc_s_ctrl(cam, arg);
3109
a966f3e7
LR
3110 case VIDIOC_CROPCAP:
3111 return sn9c102_vidioc_cropcap(cam, arg);
3112
3113 case VIDIOC_G_CROP:
3114 return sn9c102_vidioc_g_crop(cam, arg);
3115
3116 case VIDIOC_S_CROP:
3117 return sn9c102_vidioc_s_crop(cam, arg);
3118
f327ebbd
LR
3119 case VIDIOC_ENUM_FRAMESIZES:
3120 return sn9c102_vidioc_enum_framesizes(cam, arg);
3121
a966f3e7
LR
3122 case VIDIOC_ENUM_FMT:
3123 return sn9c102_vidioc_enum_fmt(cam, arg);
3124
3125 case VIDIOC_G_FMT:
3126 return sn9c102_vidioc_g_fmt(cam, arg);
3127
3128 case VIDIOC_TRY_FMT:
3129 case VIDIOC_S_FMT:
3130 return sn9c102_vidioc_try_s_fmt(cam, cmd, arg);
3131
3132 case VIDIOC_G_JPEGCOMP:
3133 return sn9c102_vidioc_g_jpegcomp(cam, arg);
3134
3135 case VIDIOC_S_JPEGCOMP:
3136 return sn9c102_vidioc_s_jpegcomp(cam, arg);
3137
3138 case VIDIOC_REQBUFS:
3139 return sn9c102_vidioc_reqbufs(cam, arg);
3140
3141 case VIDIOC_QUERYBUF:
3142 return sn9c102_vidioc_querybuf(cam, arg);
3143
3144 case VIDIOC_QBUF:
3145 return sn9c102_vidioc_qbuf(cam, arg);
3146
3147 case VIDIOC_DQBUF:
3148 return sn9c102_vidioc_dqbuf(cam, filp, arg);
3149
3150 case VIDIOC_STREAMON:
3151 return sn9c102_vidioc_streamon(cam, arg);
3152
3153 case VIDIOC_STREAMOFF:
3154 return sn9c102_vidioc_streamoff(cam, arg);
3155
3156 case VIDIOC_G_PARM:
3157 return sn9c102_vidioc_g_parm(cam, arg);
3158
a966f3e7
LR
3159 case VIDIOC_S_PARM:
3160 return sn9c102_vidioc_s_parm(cam, arg);
1da177e4 3161
f327ebbd
LR
3162 case VIDIOC_ENUMAUDIO:
3163 return sn9c102_vidioc_enumaudio(cam, arg);
3164
3165 case VIDIOC_G_AUDIO:
3166 return sn9c102_vidioc_g_audio(cam, arg);
3167
3168 case VIDIOC_S_AUDIO:
3169 return sn9c102_vidioc_s_audio(cam, arg);
3170
1da177e4
LT
3171 case VIDIOC_G_STD:
3172 case VIDIOC_S_STD:
3173 case VIDIOC_QUERYSTD:
3174 case VIDIOC_ENUMSTD:
3175 case VIDIOC_QUERYMENU:
f327ebbd 3176 case VIDIOC_ENUM_FRAMEINTERVALS:
1da177e4
LT
3177 return -EINVAL;
3178
3179 default:
3180 return -EINVAL;
3181
3182 }
3183}
3184
3185
3186static int sn9c102_ioctl(struct inode* inode, struct file* filp,
d56410e0 3187 unsigned int cmd, unsigned long arg)
1da177e4
LT
3188{
3189 struct sn9c102_device* cam = video_get_drvdata(video_devdata(filp));
3190 int err = 0;
3191
4186ecf8 3192 if (mutex_lock_interruptible(&cam->fileop_mutex))
1da177e4
LT
3193 return -ERESTARTSYS;
3194
3195 if (cam->state & DEV_DISCONNECTED) {
a966f3e7 3196 DBG(1, "Device not present");
4186ecf8 3197 mutex_unlock(&cam->fileop_mutex);
1da177e4
LT
3198 return -ENODEV;
3199 }
3200
3201 if (cam->state & DEV_MISCONFIGURED) {
a966f3e7
LR
3202 DBG(1, "The camera is misconfigured. Close and open it "
3203 "again.");
4186ecf8 3204 mutex_unlock(&cam->fileop_mutex);
1da177e4
LT
3205 return -EIO;
3206 }
3207
cd6fcc55
LR
3208 V4LDBG(3, "sn9c102", cmd);
3209
1da177e4
LT
3210 err = sn9c102_ioctl_v4l2(inode, filp, cmd, (void __user *)arg);
3211
4186ecf8 3212 mutex_unlock(&cam->fileop_mutex);
1da177e4
LT
3213
3214 return err;
3215}
3216
a966f3e7 3217/*****************************************************************************/
1da177e4 3218
fa027c2a 3219static const struct file_operations sn9c102_fops = {
a966f3e7 3220 .owner = THIS_MODULE,
480b55c2 3221 .open = sn9c102_open,
1da177e4 3222 .release = sn9c102_release,
480b55c2 3223 .ioctl = sn9c102_ioctl,
f327ebbd 3224 .compat_ioctl = v4l_compat_ioctl32,
480b55c2
LR
3225 .read = sn9c102_read,
3226 .poll = sn9c102_poll,
3227 .mmap = sn9c102_mmap,
3228 .llseek = no_llseek,
1da177e4
LT
3229};
3230
3231/*****************************************************************************/
3232
3233/* It exists a single interface only. We do not need to validate anything. */
3234static int
3235sn9c102_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
3236{
3237 struct usb_device *udev = interface_to_usbdev(intf);
3238 struct sn9c102_device* cam;
3239 static unsigned int dev_nr = 0;
a966f3e7 3240 unsigned int i;
1da177e4
LT
3241 int err = 0, r;
3242
cd6fcc55 3243 if (!(cam = kzalloc(sizeof(struct sn9c102_device), GFP_KERNEL)))
1da177e4 3244 return -ENOMEM;
1da177e4
LT
3245
3246 cam->usbdev = udev;
1da177e4 3247
cd6fcc55 3248 if (!(cam->control_buffer = kzalloc(8, GFP_KERNEL))) {
f327ebbd 3249 DBG(1, "kzalloc() failed");
1da177e4
LT
3250 err = -ENOMEM;
3251 goto fail;
3252 }
1da177e4
LT
3253
3254 if (!(cam->v4ldev = video_device_alloc())) {
a966f3e7 3255 DBG(1, "video_device_alloc() failed");
1da177e4
LT
3256 err = -ENOMEM;
3257 goto fail;
3258 }
3259
1da177e4 3260 r = sn9c102_read_reg(cam, 0x00);
f327ebbd 3261 if (r < 0 || (r != 0x10 && r != 0x11 && r != 0x12)) {
f423b9a8
LR
3262 DBG(1, "Sorry, this is not a SN9C1xx-based camera "
3263 "(vid:pid 0x%04X:0x%04X)", id->idVendor, id->idProduct);
1da177e4
LT
3264 err = -ENODEV;
3265 goto fail;
3266 }
3267
f327ebbd 3268 cam->bridge = id->driver_info;
1da177e4
LT
3269 switch (cam->bridge) {
3270 case BRIDGE_SN9C101:
3271 case BRIDGE_SN9C102:
3272 DBG(2, "SN9C10[12] PC Camera Controller detected "
f423b9a8 3273 "(vid:pid 0x%04X:0x%04X)", id->idVendor, id->idProduct);
1da177e4
LT
3274 break;
3275 case BRIDGE_SN9C103:
3276 DBG(2, "SN9C103 PC Camera Controller detected "
f423b9a8 3277 "(vid:pid 0x%04X:0x%04X)", id->idVendor, id->idProduct);
f327ebbd
LR
3278 break;
3279 case BRIDGE_SN9C105:
3280 DBG(2, "SN9C105 PC Camera Controller detected "
f423b9a8 3281 "(vid:pid 0x%04X:0x%04X)", id->idVendor, id->idProduct);
f327ebbd
LR
3282 break;
3283 case BRIDGE_SN9C120:
3284 DBG(2, "SN9C120 PC Camera Controller detected "
f423b9a8 3285 "(vid:pid 0x%04X:0x%04X)", id->idVendor, id->idProduct);
1da177e4
LT
3286 break;
3287 }
3288
480b55c2 3289 for (i = 0; i < ARRAY_SIZE(sn9c102_sensor_table); i++) {
1da177e4
LT
3290 err = sn9c102_sensor_table[i](cam);
3291 if (!err)
3292 break;
3293 }
3294
2ffab02f
LR
3295 if (!err) {
3296 DBG(2, "%s image sensor detected", cam->sensor.name);
1da177e4 3297 DBG(3, "Support for %s maintained by %s",
2ffab02f 3298 cam->sensor.name, cam->sensor.maintainer);
1da177e4 3299 } else {
480b55c2 3300 DBG(1, "No supported image sensor detected for this bridge");
1da177e4
LT
3301 err = -ENODEV;
3302 goto fail;
3303 }
3304
f327ebbd
LR
3305 if (!(cam->bridge & cam->sensor.supported_bridge)) {
3306 DBG(1, "Bridge not supported");
3307 err = -ENODEV;
3308 goto fail;
3309 }
3310
1da177e4 3311 if (sn9c102_init(cam)) {
a966f3e7 3312 DBG(1, "Initialization failed. I will retry on open().");
1da177e4
LT
3313 cam->state |= DEV_MISCONFIGURED;
3314 }
3315
f327ebbd 3316 strcpy(cam->v4ldev->name, "SN9C1xx PC Camera");
1da177e4
LT
3317 cam->v4ldev->owner = THIS_MODULE;
3318 cam->v4ldev->type = VID_TYPE_CAPTURE | VID_TYPE_SCALES;
cd6fcc55 3319 cam->v4ldev->hardware = 0;
1da177e4
LT
3320 cam->v4ldev->fops = &sn9c102_fops;
3321 cam->v4ldev->minor = video_nr[dev_nr];
3322 cam->v4ldev->release = video_device_release;
3323 video_set_drvdata(cam->v4ldev, cam);
3324
3770be34 3325 init_completion(&cam->probe);
1da177e4
LT
3326
3327 err = video_register_device(cam->v4ldev, VFL_TYPE_GRABBER,
d56410e0 3328 video_nr[dev_nr]);
1da177e4 3329 if (err) {
a966f3e7 3330 DBG(1, "V4L2 device registration failed");
1da177e4 3331 if (err == -ENFILE && video_nr[dev_nr] == -1)
a966f3e7 3332 DBG(1, "Free /dev/videoX node not found");
f327ebbd
LR
3333 video_nr[dev_nr] = -1;
3334 dev_nr = (dev_nr < SN9C102_MAX_DEVICES-1) ? dev_nr+1 : 0;
3770be34 3335 complete_all(&cam->probe);
f327ebbd 3336 goto fail;
1da177e4
LT
3337 }
3338
a966f3e7 3339 DBG(2, "V4L2 device registered as /dev/video%d", cam->v4ldev->minor);
1da177e4
LT
3340
3341 cam->module_param.force_munmap = force_munmap[dev_nr];
2ffab02f 3342 cam->module_param.frame_timeout = frame_timeout[dev_nr];
1da177e4
LT
3343
3344 dev_nr = (dev_nr < SN9C102_MAX_DEVICES-1) ? dev_nr+1 : 0;
3345
cd6fcc55 3346#ifdef CONFIG_VIDEO_ADV_DEBUG
c12e3be0 3347 err = sn9c102_create_sysfs(cam);
f327ebbd
LR
3348 if (!err)
3349 DBG(2, "Optional device control through 'sysfs' "
3350 "interface ready");
3351 else
3352 DBG(2, "Failed to create optional 'sysfs' interface for "
3353 "device controlling. Error #%d", err);
3354#else
3355 DBG(2, "Optional device control through 'sysfs' interface disabled");
f423b9a8
LR
3356 DBG(3, "Compile the kernel with the 'CONFIG_VIDEO_ADV_DEBUG' "
3357 "configuration option to enable it.");
cd6fcc55 3358#endif
1da177e4
LT
3359
3360 usb_set_intfdata(intf, cam);
3770be34
LR
3361 kref_init(&cam->kref);
3362 usb_get_dev(cam->usbdev);
1da177e4 3363
3770be34 3364 complete_all(&cam->probe);
1da177e4
LT
3365
3366 return 0;
3367
3368fail:
3369 if (cam) {
3370 kfree(cam->control_buffer);
3371 if (cam->v4ldev)
3372 video_device_release(cam->v4ldev);
3373 kfree(cam);
3374 }
3375 return err;
3376}
3377
3378
3379static void sn9c102_usb_disconnect(struct usb_interface* intf)
3380{
3770be34 3381 struct sn9c102_device* cam;
1da177e4 3382
3770be34 3383 down_write(&sn9c102_dev_lock);
1da177e4 3384
3770be34 3385 cam = usb_get_intfdata(intf);
1da177e4 3386
a966f3e7 3387 DBG(2, "Disconnecting %s...", cam->v4ldev->name);
1da177e4 3388
1da177e4
LT
3389 if (cam->users) {
3390 DBG(2, "Device /dev/video%d is open! Deregistration and "
3770be34 3391 "memory deallocation are deferred.",
a966f3e7 3392 cam->v4ldev->minor);
1da177e4
LT
3393 cam->state |= DEV_MISCONFIGURED;
3394 sn9c102_stop_transfer(cam);
3395 cam->state |= DEV_DISCONNECTED;
3396 wake_up_interruptible(&cam->wait_frame);
2ffab02f 3397 wake_up(&cam->wait_stream);
3770be34 3398 } else
1da177e4 3399 cam->state |= DEV_DISCONNECTED;
1da177e4 3400
3770be34 3401 wake_up_interruptible_all(&cam->wait_open);
1da177e4 3402
3770be34 3403 kref_put(&cam->kref, sn9c102_release_resources);
1da177e4 3404
3770be34 3405 up_write(&sn9c102_dev_lock);
1da177e4
LT
3406}
3407
3408
3409static struct usb_driver sn9c102_usb_driver = {
1da177e4
LT
3410 .name = "sn9c102",
3411 .id_table = sn9c102_id_table,
3412 .probe = sn9c102_usb_probe,
3413 .disconnect = sn9c102_usb_disconnect,
3414};
3415
3416/*****************************************************************************/
3417
3418static int __init sn9c102_module_init(void)
3419{
3420 int err = 0;
3421
a966f3e7
LR
3422 KDBG(2, SN9C102_MODULE_NAME " v" SN9C102_MODULE_VERSION);
3423 KDBG(3, SN9C102_MODULE_AUTHOR);
1da177e4
LT
3424
3425 if ((err = usb_register(&sn9c102_usb_driver)))
a966f3e7 3426 KDBG(1, "usb_register() failed");
1da177e4
LT
3427
3428 return err;
3429}
3430
3431
3432static void __exit sn9c102_module_exit(void)
3433{
3434 usb_deregister(&sn9c102_usb_driver);
3435}
3436
3437
3438module_init(sn9c102_module_init);
3439module_exit(sn9c102_module_exit);