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