byteorder: don't directly include linux/byteorder/generic.h
[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
f327ebbd
LR
1041 cam = video_get_drvdata(container_of(cd, struct video_device,
1042 class_dev));
1da177e4 1043 if (!cam) {
4186ecf8 1044 mutex_unlock(&sn9c102_sysfs_lock);
1da177e4
LT
1045 return -ENODEV;
1046 }
1047
1048 count = sprintf(buf, "%u\n", cam->sysfs.reg);
1049
4186ecf8 1050 mutex_unlock(&sn9c102_sysfs_lock);
1da177e4
LT
1051
1052 return count;
d56410e0 1053}
1da177e4
LT
1054
1055
d56410e0 1056static ssize_t
54bd5b66
KS
1057sn9c102_store_reg(struct device* cd, struct device_attribute *attr,
1058 const char* buf, size_t len)
1da177e4
LT
1059{
1060 struct sn9c102_device* cam;
f327ebbd 1061 u16 index;
1da177e4
LT
1062 ssize_t count;
1063
4186ecf8 1064 if (mutex_lock_interruptible(&sn9c102_sysfs_lock))
1da177e4
LT
1065 return -ERESTARTSYS;
1066
f327ebbd
LR
1067 cam = video_get_drvdata(container_of(cd, struct video_device,
1068 class_dev));
1da177e4 1069 if (!cam) {
4186ecf8 1070 mutex_unlock(&sn9c102_sysfs_lock);
1da177e4
LT
1071 return -ENODEV;
1072 }
1073
f327ebbd
LR
1074 index = sn9c102_strtou16(buf, len, &count);
1075 if (index >= ARRAY_SIZE(cam->reg) || !count) {
4186ecf8 1076 mutex_unlock(&sn9c102_sysfs_lock);
1da177e4
LT
1077 return -EINVAL;
1078 }
1079
1080 cam->sysfs.reg = index;
1081
f327ebbd 1082 DBG(2, "Moved SN9C1XX register index to 0x%02X", cam->sysfs.reg);
a966f3e7 1083 DBG(3, "Written bytes: %zd", count);
1da177e4 1084
4186ecf8 1085 mutex_unlock(&sn9c102_sysfs_lock);
1da177e4
LT
1086
1087 return count;
1088}
1089
1090
54bd5b66
KS
1091static ssize_t sn9c102_show_val(struct device* cd,
1092 struct device_attribute *attr, char* buf)
1da177e4
LT
1093{
1094 struct sn9c102_device* cam;
1095 ssize_t count;
1096 int val;
1097
4186ecf8 1098 if (mutex_lock_interruptible(&sn9c102_sysfs_lock))
1da177e4
LT
1099 return -ERESTARTSYS;
1100
f327ebbd
LR
1101 cam = video_get_drvdata(container_of(cd, struct video_device,
1102 class_dev));
1da177e4 1103 if (!cam) {
4186ecf8 1104 mutex_unlock(&sn9c102_sysfs_lock);
1da177e4
LT
1105 return -ENODEV;
1106 }
1107
1108 if ((val = sn9c102_read_reg(cam, cam->sysfs.reg)) < 0) {
4186ecf8 1109 mutex_unlock(&sn9c102_sysfs_lock);
1da177e4
LT
1110 return -EIO;
1111 }
1112
1113 count = sprintf(buf, "%d\n", val);
1114
f423b9a8 1115 DBG(3, "Read bytes: %zd, value: %d", count, val);
1da177e4 1116
4186ecf8 1117 mutex_unlock(&sn9c102_sysfs_lock);
1da177e4
LT
1118
1119 return count;
d56410e0 1120}
1da177e4
LT
1121
1122
1123static ssize_t
54bd5b66
KS
1124sn9c102_store_val(struct device* cd, struct device_attribute *attr,
1125 const char* buf, size_t len)
1da177e4
LT
1126{
1127 struct sn9c102_device* cam;
f327ebbd 1128 u16 value;
1da177e4
LT
1129 ssize_t count;
1130 int err;
1131
4186ecf8 1132 if (mutex_lock_interruptible(&sn9c102_sysfs_lock))
1da177e4
LT
1133 return -ERESTARTSYS;
1134
f327ebbd
LR
1135 cam = video_get_drvdata(container_of(cd, struct video_device,
1136 class_dev));
1da177e4 1137 if (!cam) {
4186ecf8 1138 mutex_unlock(&sn9c102_sysfs_lock);
1da177e4
LT
1139 return -ENODEV;
1140 }
1141
f327ebbd 1142 value = sn9c102_strtou16(buf, len, &count);
1da177e4 1143 if (!count) {
4186ecf8 1144 mutex_unlock(&sn9c102_sysfs_lock);
1da177e4
LT
1145 return -EINVAL;
1146 }
1147
1148 err = sn9c102_write_reg(cam, value, cam->sysfs.reg);
1149 if (err) {
4186ecf8 1150 mutex_unlock(&sn9c102_sysfs_lock);
1da177e4
LT
1151 return -EIO;
1152 }
1153
f327ebbd 1154 DBG(2, "Written SN9C1XX reg. 0x%02X, val. 0x%02X",
a966f3e7
LR
1155 cam->sysfs.reg, value);
1156 DBG(3, "Written bytes: %zd", count);
1da177e4 1157
4186ecf8 1158 mutex_unlock(&sn9c102_sysfs_lock);
1da177e4
LT
1159
1160 return count;
1161}
1162
1163
54bd5b66
KS
1164static ssize_t sn9c102_show_i2c_reg(struct device* cd,
1165 struct device_attribute *attr, char* buf)
1da177e4
LT
1166{
1167 struct sn9c102_device* cam;
1168 ssize_t count;
1169
4186ecf8 1170 if (mutex_lock_interruptible(&sn9c102_sysfs_lock))
1da177e4
LT
1171 return -ERESTARTSYS;
1172
f327ebbd
LR
1173 cam = video_get_drvdata(container_of(cd, struct video_device,
1174 class_dev));
1da177e4 1175 if (!cam) {
4186ecf8 1176 mutex_unlock(&sn9c102_sysfs_lock);
1da177e4
LT
1177 return -ENODEV;
1178 }
1179
1180 count = sprintf(buf, "%u\n", cam->sysfs.i2c_reg);
1181
a966f3e7 1182 DBG(3, "Read bytes: %zd", count);
1da177e4 1183
4186ecf8 1184 mutex_unlock(&sn9c102_sysfs_lock);
1da177e4
LT
1185
1186 return count;
1187}
1188
1189
d56410e0 1190static ssize_t
54bd5b66
KS
1191sn9c102_store_i2c_reg(struct device* cd, struct device_attribute *attr,
1192 const char* buf, size_t len)
1da177e4
LT
1193{
1194 struct sn9c102_device* cam;
f327ebbd 1195 u16 index;
1da177e4
LT
1196 ssize_t count;
1197
4186ecf8 1198 if (mutex_lock_interruptible(&sn9c102_sysfs_lock))
1da177e4
LT
1199 return -ERESTARTSYS;
1200
f327ebbd
LR
1201 cam = video_get_drvdata(container_of(cd, struct video_device,
1202 class_dev));
1da177e4 1203 if (!cam) {
4186ecf8 1204 mutex_unlock(&sn9c102_sysfs_lock);
1da177e4
LT
1205 return -ENODEV;
1206 }
1207
f327ebbd 1208 index = sn9c102_strtou16(buf, len, &count);
1da177e4 1209 if (!count) {
4186ecf8 1210 mutex_unlock(&sn9c102_sysfs_lock);
1da177e4
LT
1211 return -EINVAL;
1212 }
1213
1214 cam->sysfs.i2c_reg = index;
1215
a966f3e7
LR
1216 DBG(2, "Moved sensor register index to 0x%02X", cam->sysfs.i2c_reg);
1217 DBG(3, "Written bytes: %zd", count);
1da177e4 1218
4186ecf8 1219 mutex_unlock(&sn9c102_sysfs_lock);
1da177e4
LT
1220
1221 return count;
1222}
1223
1224
54bd5b66
KS
1225static ssize_t sn9c102_show_i2c_val(struct device* cd,
1226 struct device_attribute *attr, char* buf)
1da177e4
LT
1227{
1228 struct sn9c102_device* cam;
1229 ssize_t count;
1230 int val;
1231
4186ecf8 1232 if (mutex_lock_interruptible(&sn9c102_sysfs_lock))
1da177e4
LT
1233 return -ERESTARTSYS;
1234
f327ebbd
LR
1235 cam = video_get_drvdata(container_of(cd, struct video_device,
1236 class_dev));
1da177e4 1237 if (!cam) {
4186ecf8 1238 mutex_unlock(&sn9c102_sysfs_lock);
1da177e4
LT
1239 return -ENODEV;
1240 }
1241
2ffab02f 1242 if (!(cam->sensor.sysfs_ops & SN9C102_I2C_READ)) {
4186ecf8 1243 mutex_unlock(&sn9c102_sysfs_lock);
1da177e4
LT
1244 return -ENOSYS;
1245 }
1246
1247 if ((val = sn9c102_i2c_read(cam, cam->sysfs.i2c_reg)) < 0) {
4186ecf8 1248 mutex_unlock(&sn9c102_sysfs_lock);
1da177e4
LT
1249 return -EIO;
1250 }
1251
1252 count = sprintf(buf, "%d\n", val);
1253
f423b9a8 1254 DBG(3, "Read bytes: %zd, value: %d", count, val);
1da177e4 1255
4186ecf8 1256 mutex_unlock(&sn9c102_sysfs_lock);
1da177e4
LT
1257
1258 return count;
d56410e0 1259}
1da177e4
LT
1260
1261
1262static ssize_t
54bd5b66
KS
1263sn9c102_store_i2c_val(struct device* cd, struct device_attribute *attr,
1264 const char* buf, size_t len)
1da177e4
LT
1265{
1266 struct sn9c102_device* cam;
f327ebbd 1267 u16 value;
1da177e4
LT
1268 ssize_t count;
1269 int err;
1270
4186ecf8 1271 if (mutex_lock_interruptible(&sn9c102_sysfs_lock))
1da177e4
LT
1272 return -ERESTARTSYS;
1273
f327ebbd
LR
1274 cam = video_get_drvdata(container_of(cd, struct video_device,
1275 class_dev));
1da177e4 1276 if (!cam) {
4186ecf8 1277 mutex_unlock(&sn9c102_sysfs_lock);
1da177e4
LT
1278 return -ENODEV;
1279 }
1280
2ffab02f 1281 if (!(cam->sensor.sysfs_ops & SN9C102_I2C_WRITE)) {
4186ecf8 1282 mutex_unlock(&sn9c102_sysfs_lock);
1da177e4
LT
1283 return -ENOSYS;
1284 }
1285
f327ebbd 1286 value = sn9c102_strtou16(buf, len, &count);
1da177e4 1287 if (!count) {
4186ecf8 1288 mutex_unlock(&sn9c102_sysfs_lock);
1da177e4
LT
1289 return -EINVAL;
1290 }
1291
1292 err = sn9c102_i2c_write(cam, cam->sysfs.i2c_reg, value);
1293 if (err) {
4186ecf8 1294 mutex_unlock(&sn9c102_sysfs_lock);
1da177e4
LT
1295 return -EIO;
1296 }
1297
1298 DBG(2, "Written sensor reg. 0x%02X, val. 0x%02X",
a966f3e7
LR
1299 cam->sysfs.i2c_reg, value);
1300 DBG(3, "Written bytes: %zd", count);
1da177e4 1301
4186ecf8 1302 mutex_unlock(&sn9c102_sysfs_lock);
1da177e4
LT
1303
1304 return count;
1305}
1306
1307
1308static ssize_t
54bd5b66
KS
1309sn9c102_store_green(struct device* cd, struct device_attribute *attr,
1310 const char* buf, size_t len)
1da177e4
LT
1311{
1312 struct sn9c102_device* cam;
1313 enum sn9c102_bridge bridge;
1314 ssize_t res = 0;
f327ebbd 1315 u16 value;
1da177e4
LT
1316 ssize_t count;
1317
4186ecf8 1318 if (mutex_lock_interruptible(&sn9c102_sysfs_lock))
1da177e4
LT
1319 return -ERESTARTSYS;
1320
f327ebbd
LR
1321 cam = video_get_drvdata(container_of(cd, struct video_device,
1322 class_dev));
1da177e4 1323 if (!cam) {
4186ecf8 1324 mutex_unlock(&sn9c102_sysfs_lock);
1da177e4
LT
1325 return -ENODEV;
1326 }
1327
1328 bridge = cam->bridge;
1329
4186ecf8 1330 mutex_unlock(&sn9c102_sysfs_lock);
1da177e4 1331
f327ebbd 1332 value = sn9c102_strtou16(buf, len, &count);
1da177e4
LT
1333 if (!count)
1334 return -EINVAL;
1335
1336 switch (bridge) {
1337 case BRIDGE_SN9C101:
1338 case BRIDGE_SN9C102:
1339 if (value > 0x0f)
1340 return -EINVAL;
54bd5b66
KS
1341 if ((res = sn9c102_store_reg(cd, attr, "0x11", 4)) >= 0)
1342 res = sn9c102_store_val(cd, attr, buf, len);
1da177e4
LT
1343 break;
1344 case BRIDGE_SN9C103:
f327ebbd
LR
1345 case BRIDGE_SN9C105:
1346 case BRIDGE_SN9C120:
1da177e4
LT
1347 if (value > 0x7f)
1348 return -EINVAL;
54bd5b66
KS
1349 if ((res = sn9c102_store_reg(cd, attr, "0x07", 4)) >= 0)
1350 res = sn9c102_store_val(cd, attr, buf, len);
1da177e4
LT
1351 break;
1352 }
1353
1354 return res;
1355}
1356
1357
1358static ssize_t
54bd5b66
KS
1359sn9c102_store_blue(struct device* cd, struct device_attribute *attr,
1360 const char* buf, size_t len)
1da177e4
LT
1361{
1362 ssize_t res = 0;
f327ebbd 1363 u16 value;
1da177e4
LT
1364 ssize_t count;
1365
f327ebbd 1366 value = sn9c102_strtou16(buf, len, &count);
1da177e4
LT
1367 if (!count || value > 0x7f)
1368 return -EINVAL;
1369
54bd5b66
KS
1370 if ((res = sn9c102_store_reg(cd, attr, "0x06", 4)) >= 0)
1371 res = sn9c102_store_val(cd, attr, buf, len);
1da177e4
LT
1372
1373 return res;
1374}
1375
1376
1377static ssize_t
54bd5b66
KS
1378sn9c102_store_red(struct device* cd, struct device_attribute *attr,
1379 const char* buf, size_t len)
1da177e4
LT
1380{
1381 ssize_t res = 0;
f327ebbd 1382 u16 value;
1da177e4
LT
1383 ssize_t count;
1384
f327ebbd 1385 value = sn9c102_strtou16(buf, len, &count);
1da177e4
LT
1386 if (!count || value > 0x7f)
1387 return -EINVAL;
1388
54bd5b66
KS
1389 if ((res = sn9c102_store_reg(cd, attr, "0x05", 4)) >= 0)
1390 res = sn9c102_store_val(cd, attr, buf, len);
1da177e4
LT
1391
1392 return res;
1393}
1394
1395
54bd5b66
KS
1396static ssize_t sn9c102_show_frame_header(struct device* cd,
1397 struct device_attribute *attr,
1398 char* buf)
1da177e4
LT
1399{
1400 struct sn9c102_device* cam;
1401 ssize_t count;
1402
f327ebbd
LR
1403 cam = video_get_drvdata(container_of(cd, struct video_device,
1404 class_dev));
1da177e4
LT
1405 if (!cam)
1406 return -ENODEV;
1407
1408 count = sizeof(cam->sysfs.frame_header);
1409 memcpy(buf, cam->sysfs.frame_header, count);
1410
a966f3e7 1411 DBG(3, "Frame header, read bytes: %zd", count);
1da177e4
LT
1412
1413 return count;
d56410e0 1414}
1da177e4
LT
1415
1416
54bd5b66
KS
1417static DEVICE_ATTR(reg, S_IRUGO | S_IWUSR, sn9c102_show_reg, sn9c102_store_reg);
1418static DEVICE_ATTR(val, S_IRUGO | S_IWUSR, sn9c102_show_val, sn9c102_store_val);
1419static DEVICE_ATTR(i2c_reg, S_IRUGO | S_IWUSR,
1420 sn9c102_show_i2c_reg, sn9c102_store_i2c_reg);
1421static DEVICE_ATTR(i2c_val, S_IRUGO | S_IWUSR,
1422 sn9c102_show_i2c_val, sn9c102_store_i2c_val);
1423static DEVICE_ATTR(green, S_IWUGO, NULL, sn9c102_store_green);
1424static DEVICE_ATTR(blue, S_IWUGO, NULL, sn9c102_store_blue);
1425static DEVICE_ATTR(red, S_IWUGO, NULL, sn9c102_store_red);
1426static DEVICE_ATTR(frame_header, S_IRUGO, sn9c102_show_frame_header, NULL);
1da177e4
LT
1427
1428
c12e3be0 1429static int sn9c102_create_sysfs(struct sn9c102_device* cam)
1da177e4 1430{
54bd5b66 1431 struct device *classdev = &(cam->v4ldev->class_dev);
f327ebbd 1432 int err = 0;
c12e3be0 1433
54bd5b66 1434 if ((err = device_create_file(classdev, &dev_attr_reg)))
f327ebbd 1435 goto err_out;
54bd5b66 1436 if ((err = device_create_file(classdev, &dev_attr_val)))
f327ebbd 1437 goto err_reg;
54bd5b66 1438 if ((err = device_create_file(classdev, &dev_attr_frame_header)))
f327ebbd 1439 goto err_val;
1da177e4 1440
2ffab02f 1441 if (cam->sensor.sysfs_ops) {
54bd5b66 1442 if ((err = device_create_file(classdev, &dev_attr_i2c_reg)))
f327ebbd 1443 goto err_frame_header;
54bd5b66 1444 if ((err = device_create_file(classdev, &dev_attr_i2c_val)))
f327ebbd 1445 goto err_i2c_reg;
c12e3be0
JG
1446 }
1447
1448 if (cam->bridge == BRIDGE_SN9C101 || cam->bridge == BRIDGE_SN9C102) {
54bd5b66 1449 if ((err = device_create_file(classdev, &dev_attr_green)))
f327ebbd
LR
1450 goto err_i2c_val;
1451 } else {
54bd5b66 1452 if ((err = device_create_file(classdev, &dev_attr_blue)))
f327ebbd 1453 goto err_i2c_val;
54bd5b66 1454 if ((err = device_create_file(classdev, &dev_attr_red)))
f327ebbd 1455 goto err_blue;
1da177e4 1456 }
c12e3be0
JG
1457
1458 return 0;
1459
1460err_blue:
54bd5b66 1461 device_remove_file(classdev, &dev_attr_blue);
c12e3be0
JG
1462err_i2c_val:
1463 if (cam->sensor.sysfs_ops)
54bd5b66 1464 device_remove_file(classdev, &dev_attr_i2c_val);
c12e3be0
JG
1465err_i2c_reg:
1466 if (cam->sensor.sysfs_ops)
54bd5b66 1467 device_remove_file(classdev, &dev_attr_i2c_reg);
f327ebbd 1468err_frame_header:
54bd5b66 1469 device_remove_file(classdev, &dev_attr_frame_header);
c12e3be0 1470err_val:
54bd5b66 1471 device_remove_file(classdev, &dev_attr_val);
c12e3be0 1472err_reg:
54bd5b66 1473 device_remove_file(classdev, &dev_attr_reg);
f327ebbd
LR
1474err_out:
1475 return err;
1da177e4 1476}
cd6fcc55 1477#endif /* CONFIG_VIDEO_ADV_DEBUG */
1da177e4
LT
1478
1479/*****************************************************************************/
1480
1481static int
1482sn9c102_set_pix_format(struct sn9c102_device* cam, struct v4l2_pix_format* pix)
1483{
1484 int err = 0;
1485
f327ebbd
LR
1486 if (pix->pixelformat == V4L2_PIX_FMT_SN9C10X ||
1487 pix->pixelformat == V4L2_PIX_FMT_JPEG) {
1488 switch (cam->bridge) {
1489 case BRIDGE_SN9C101:
1490 case BRIDGE_SN9C102:
1491 case BRIDGE_SN9C103:
1492 err += sn9c102_write_reg(cam, cam->reg[0x18] | 0x80,
1493 0x18);
1494 break;
1495 case BRIDGE_SN9C105:
1496 case BRIDGE_SN9C120:
1497 err += sn9c102_write_reg(cam, cam->reg[0x18] & 0x7f,
1498 0x18);
1499 break;
1500 }
1501 } else {
1502 switch (cam->bridge) {
1503 case BRIDGE_SN9C101:
1504 case BRIDGE_SN9C102:
1505 case BRIDGE_SN9C103:
1506 err += sn9c102_write_reg(cam, cam->reg[0x18] & 0x7f,
1507 0x18);
1508 break;
1509 case BRIDGE_SN9C105:
1510 case BRIDGE_SN9C120:
1511 err += sn9c102_write_reg(cam, cam->reg[0x18] | 0x80,
1512 0x18);
1513 break;
1514 }
1515 }
1da177e4
LT
1516
1517 return err ? -EIO : 0;
1518}
1519
1520
1521static int
1522sn9c102_set_compression(struct sn9c102_device* cam,
d56410e0 1523 struct v4l2_jpegcompression* compression)
1da177e4 1524{
f327ebbd 1525 int i, err = 0;
1da177e4 1526
f327ebbd
LR
1527 switch (cam->bridge) {
1528 case BRIDGE_SN9C101:
1529 case BRIDGE_SN9C102:
1530 case BRIDGE_SN9C103:
f423b9a8 1531 if (compression->quality == 0)
f327ebbd
LR
1532 err += sn9c102_write_reg(cam, cam->reg[0x17] | 0x01,
1533 0x17);
f423b9a8 1534 else if (compression->quality == 1)
f327ebbd
LR
1535 err += sn9c102_write_reg(cam, cam->reg[0x17] & 0xfe,
1536 0x17);
1537 break;
1538 case BRIDGE_SN9C105:
1539 case BRIDGE_SN9C120:
1540 if (compression->quality == 0) {
1541 for (i = 0; i <= 63; i++) {
1542 err += sn9c102_write_reg(cam,
f423b9a8 1543 SN9C102_Y_QTABLE1[i],
f327ebbd
LR
1544 0x100 + i);
1545 err += sn9c102_write_reg(cam,
f423b9a8 1546 SN9C102_UV_QTABLE1[i],
f327ebbd
LR
1547 0x140 + i);
1548 }
1549 err += sn9c102_write_reg(cam, cam->reg[0x18] & 0xbf,
1550 0x18);
1551 } else if (compression->quality == 1) {
1552 for (i = 0; i <= 63; i++) {
1553 err += sn9c102_write_reg(cam,
1554 SN9C102_Y_QTABLE1[i],
1555 0x100 + i);
1556 err += sn9c102_write_reg(cam,
1557 SN9C102_UV_QTABLE1[i],
1558 0x140 + i);
1559 }
1560 err += sn9c102_write_reg(cam, cam->reg[0x18] | 0x40,
1561 0x18);
1562 }
1563 break;
1564 }
1da177e4
LT
1565
1566 return err ? -EIO : 0;
1567}
1568
1569
1570static int sn9c102_set_scale(struct sn9c102_device* cam, u8 scale)
1571{
1572 u8 r = 0;
1573 int err = 0;
1574
1575 if (scale == 1)
1576 r = cam->reg[0x18] & 0xcf;
1577 else if (scale == 2) {
1578 r = cam->reg[0x18] & 0xcf;
1579 r |= 0x10;
1580 } else if (scale == 4)
1581 r = cam->reg[0x18] | 0x20;
1582
1583 err += sn9c102_write_reg(cam, r, 0x18);
1584 if (err)
1585 return -EIO;
1586
a966f3e7 1587 PDBGG("Scaling factor: %u", scale);
1da177e4
LT
1588
1589 return 0;
1590}
1591
1592
1593static int sn9c102_set_crop(struct sn9c102_device* cam, struct v4l2_rect* rect)
1594{
2ffab02f 1595 struct sn9c102_sensor* s = &cam->sensor;
1da177e4
LT
1596 u8 h_start = (u8)(rect->left - s->cropcap.bounds.left),
1597 v_start = (u8)(rect->top - s->cropcap.bounds.top),
1598 h_size = (u8)(rect->width / 16),
1599 v_size = (u8)(rect->height / 16);
1600 int err = 0;
1601
1602 err += sn9c102_write_reg(cam, h_start, 0x12);
1603 err += sn9c102_write_reg(cam, v_start, 0x13);
1604 err += sn9c102_write_reg(cam, h_size, 0x15);
1605 err += sn9c102_write_reg(cam, v_size, 0x16);
1606 if (err)
1607 return -EIO;
1608
1609 PDBGG("h_start, v_start, h_size, v_size, ho_size, vo_size "
a966f3e7 1610 "%u %u %u %u", h_start, v_start, h_size, v_size);
1da177e4
LT
1611
1612 return 0;
1613}
1614
1615
1616static int sn9c102_init(struct sn9c102_device* cam)
1617{
2ffab02f 1618 struct sn9c102_sensor* s = &cam->sensor;
1da177e4
LT
1619 struct v4l2_control ctrl;
1620 struct v4l2_queryctrl *qctrl;
1621 struct v4l2_rect* rect;
52950ed4 1622 u8 i = 0;
1da177e4
LT
1623 int err = 0;
1624
1625 if (!(cam->state & DEV_INITIALIZED)) {
3770be34
LR
1626 mutex_init(&cam->open_mutex);
1627 init_waitqueue_head(&cam->wait_open);
1da177e4
LT
1628 qctrl = s->qctrl;
1629 rect = &(s->cropcap.defrect);
1630 } else { /* use current values */
1631 qctrl = s->_qctrl;
1632 rect = &(s->_rect);
1633 }
1634
1635 err += sn9c102_set_scale(cam, rect->width / s->pix_format.width);
1636 err += sn9c102_set_crop(cam, rect);
1637 if (err)
1638 return err;
1639
1640 if (s->init) {
1641 err = s->init(cam);
1642 if (err) {
a966f3e7 1643 DBG(3, "Sensor initialization failed");
1da177e4
LT
1644 return err;
1645 }
1646 }
1647
1648 if (!(cam->state & DEV_INITIALIZED))
f327ebbd
LR
1649 if (cam->bridge == BRIDGE_SN9C101 ||
1650 cam->bridge == BRIDGE_SN9C102 ||
1651 cam->bridge == BRIDGE_SN9C103) {
f423b9a8
LR
1652 if (s->pix_format.pixelformat == V4L2_PIX_FMT_JPEG)
1653 s->pix_format.pixelformat= V4L2_PIX_FMT_SBGGR8;
f327ebbd
LR
1654 cam->compression.quality = cam->reg[0x17] & 0x01 ?
1655 0 : 1;
1656 } else {
f423b9a8
LR
1657 if (s->pix_format.pixelformat == V4L2_PIX_FMT_SN9C10X)
1658 s->pix_format.pixelformat = V4L2_PIX_FMT_JPEG;
f327ebbd
LR
1659 cam->compression.quality = cam->reg[0x18] & 0x40 ?
1660 0 : 1;
1661 err += sn9c102_set_compression(cam, &cam->compression);
1662 }
1da177e4
LT
1663 else
1664 err += sn9c102_set_compression(cam, &cam->compression);
1665 err += sn9c102_set_pix_format(cam, &s->pix_format);
1666 if (s->set_pix_format)
1667 err += s->set_pix_format(cam, &s->pix_format);
1668 if (err)
1669 return err;
1670
f327ebbd
LR
1671 if (s->pix_format.pixelformat == V4L2_PIX_FMT_SN9C10X ||
1672 s->pix_format.pixelformat == V4L2_PIX_FMT_JPEG)
52950ed4 1673 DBG(3, "Compressed video format is active, quality %d",
a966f3e7 1674 cam->compression.quality);
1da177e4 1675 else
a966f3e7 1676 DBG(3, "Uncompressed video format is active");
1da177e4
LT
1677
1678 if (s->set_crop)
1679 if ((err = s->set_crop(cam, rect))) {
a966f3e7 1680 DBG(3, "set_crop() failed");
1da177e4
LT
1681 return err;
1682 }
1683
1684 if (s->set_ctrl) {
52950ed4
TK
1685 for (i = 0; i < ARRAY_SIZE(s->qctrl); i++)
1686 if (s->qctrl[i].id != 0 &&
1da177e4
LT
1687 !(s->qctrl[i].flags & V4L2_CTRL_FLAG_DISABLED)) {
1688 ctrl.id = s->qctrl[i].id;
1689 ctrl.value = qctrl[i].default_value;
1690 err = s->set_ctrl(cam, &ctrl);
1691 if (err) {
1692 DBG(3, "Set %s control failed",
a966f3e7 1693 s->qctrl[i].name);
1da177e4
LT
1694 return err;
1695 }
1696 DBG(3, "Image sensor supports '%s' control",
a966f3e7 1697 s->qctrl[i].name);
1da177e4
LT
1698 }
1699 }
1700
1701 if (!(cam->state & DEV_INITIALIZED)) {
4186ecf8 1702 mutex_init(&cam->fileop_mutex);
1da177e4
LT
1703 spin_lock_init(&cam->queue_lock);
1704 init_waitqueue_head(&cam->wait_frame);
1705 init_waitqueue_head(&cam->wait_stream);
1706 cam->nreadbuffers = 2;
1707 memcpy(s->_qctrl, s->qctrl, sizeof(s->qctrl));
52950ed4 1708 memcpy(&(s->_rect), &(s->cropcap.defrect),
1da177e4
LT
1709 sizeof(struct v4l2_rect));
1710 cam->state |= DEV_INITIALIZED;
1711 }
1712
a966f3e7 1713 DBG(2, "Initialization succeeded");
1da177e4
LT
1714 return 0;
1715}
1716
3770be34 1717/*****************************************************************************/
1da177e4 1718
3770be34 1719static void sn9c102_release_resources(struct kref *kref)
1da177e4 1720{
3770be34
LR
1721 struct sn9c102_device *cam;
1722
4186ecf8 1723 mutex_lock(&sn9c102_sysfs_lock);
1da177e4 1724
3770be34
LR
1725 cam = container_of(kref, struct sn9c102_device, kref);
1726
a966f3e7 1727 DBG(2, "V4L2 device /dev/video%d deregistered", cam->v4ldev->minor);
1da177e4
LT
1728 video_set_drvdata(cam->v4ldev, NULL);
1729 video_unregister_device(cam->v4ldev);
3770be34
LR
1730 usb_put_dev(cam->usbdev);
1731 kfree(cam->control_buffer);
1732 kfree(cam);
1da177e4 1733
4186ecf8 1734 mutex_unlock(&sn9c102_sysfs_lock);
1da177e4 1735
1da177e4
LT
1736}
1737
1da177e4
LT
1738
1739static int sn9c102_open(struct inode* inode, struct file* filp)
1740{
1741 struct sn9c102_device* cam;
1742 int err = 0;
1743
1744 /*
3770be34
LR
1745 A read_trylock() in open() is the only safe way to prevent race
1746 conditions with disconnect(), one close() and multiple (not
1747 necessarily simultaneous) attempts to open(). For example, it
1748 prevents from waiting for a second access, while the device
1749 structure is being deallocated, after a possible disconnect() and
1750 during a following close() holding the write lock: given that, after
1751 this deallocation, no access will be possible anymore, using the
1752 non-trylock version would have let open() gain the access to the
1753 device structure improperly.
1754 For this reason the lock must also not be per-device.
1da177e4 1755 */
3770be34 1756 if (!down_read_trylock(&sn9c102_dev_lock))
1da177e4
LT
1757 return -ERESTARTSYS;
1758
1759 cam = video_get_drvdata(video_devdata(filp));
1760
3770be34
LR
1761 if (wait_for_completion_interruptible(&cam->probe)) {
1762 up_read(&sn9c102_dev_lock);
1763 return -ERESTARTSYS;
1764 }
1765
1766 kref_get(&cam->kref);
1767
1768 /*
1769 Make sure to isolate all the simultaneous opens.
1770 */
1771 if (mutex_lock_interruptible(&cam->open_mutex)) {
1772 kref_put(&cam->kref, sn9c102_release_resources);
1773 up_read(&sn9c102_dev_lock);
1da177e4
LT
1774 return -ERESTARTSYS;
1775 }
1776
3770be34
LR
1777 if (cam->state & DEV_DISCONNECTED) {
1778 DBG(1, "Device not present");
1779 err = -ENODEV;
1780 goto out;
1781 }
1782
1da177e4 1783 if (cam->users) {
3770be34
LR
1784 DBG(2, "Device /dev/video%d is already in use",
1785 cam->v4ldev->minor);
f327ebbd 1786 DBG(3, "Simultaneous opens are not supported");
3770be34
LR
1787 /*
1788 open() must follow the open flags and should block
1789 eventually while the device is in use.
1790 */
1da177e4
LT
1791 if ((filp->f_flags & O_NONBLOCK) ||
1792 (filp->f_flags & O_NDELAY)) {
1793 err = -EWOULDBLOCK;
1794 goto out;
1795 }
3770be34
LR
1796 DBG(2, "A blocking open() has been requested. Wait for the "
1797 "device to be released...");
1798 up_read(&sn9c102_dev_lock);
1799 /*
1800 We will not release the "open_mutex" lock, so that only one
1801 process can be in the wait queue below. This way the process
1802 will be sleeping while holding the lock, without loosing its
1803 priority after any wake_up().
1804 */
1805 err = wait_event_interruptible_exclusive(cam->wait_open,
1806 (cam->state & DEV_DISCONNECTED)
d56410e0 1807 || !cam->users);
3770be34
LR
1808 down_read(&sn9c102_dev_lock);
1809 if (err)
1810 goto out;
1da177e4 1811 if (cam->state & DEV_DISCONNECTED) {
3770be34
LR
1812 err = -ENODEV;
1813 goto out;
1da177e4 1814 }
1da177e4
LT
1815 }
1816
1da177e4
LT
1817 if (cam->state & DEV_MISCONFIGURED) {
1818 err = sn9c102_init(cam);
1819 if (err) {
1820 DBG(1, "Initialization failed again. "
a966f3e7 1821 "I will retry on next open().");
1da177e4
LT
1822 goto out;
1823 }
1824 cam->state &= ~DEV_MISCONFIGURED;
1825 }
1826
1827 if ((err = sn9c102_start_transfer(cam)))
1828 goto out;
1829
1830 filp->private_data = cam;
1831 cam->users++;
1832 cam->io = IO_NONE;
1833 cam->stream = STREAM_OFF;
1834 cam->nbuffers = 0;
1835 cam->frame_count = 0;
1836 sn9c102_empty_framequeues(cam);
1837
a966f3e7 1838 DBG(3, "Video device /dev/video%d is open", cam->v4ldev->minor);
1da177e4
LT
1839
1840out:
3770be34
LR
1841 mutex_unlock(&cam->open_mutex);
1842 if (err)
1843 kref_put(&cam->kref, sn9c102_release_resources);
1844
1845 up_read(&sn9c102_dev_lock);
1da177e4
LT
1846 return err;
1847}
1848
1849
1850static int sn9c102_release(struct inode* inode, struct file* filp)
1851{
3770be34 1852 struct sn9c102_device* cam;
1da177e4 1853
3770be34 1854 down_write(&sn9c102_dev_lock);
1da177e4 1855
3770be34 1856 cam = video_get_drvdata(video_devdata(filp));
1da177e4 1857
3770be34 1858 sn9c102_stop_transfer(cam);
1da177e4 1859 sn9c102_release_buffers(cam);
1da177e4 1860 cam->users--;
3770be34 1861 wake_up_interruptible_nr(&cam->wait_open, 1);
1da177e4 1862
a966f3e7 1863 DBG(3, "Video device /dev/video%d closed", cam->v4ldev->minor);
1da177e4 1864
3770be34
LR
1865 kref_put(&cam->kref, sn9c102_release_resources);
1866
1867 up_write(&sn9c102_dev_lock);
1da177e4
LT
1868
1869 return 0;
1870}
1871
1872
1873static ssize_t
1874sn9c102_read(struct file* filp, char __user * buf, size_t count, loff_t* f_pos)
1875{
1876 struct sn9c102_device* cam = video_get_drvdata(video_devdata(filp));
1877 struct sn9c102_frame_t* f, * i;
1878 unsigned long lock_flags;
2ffab02f 1879 long timeout;
1da177e4
LT
1880 int err = 0;
1881
4186ecf8 1882 if (mutex_lock_interruptible(&cam->fileop_mutex))
1da177e4
LT
1883 return -ERESTARTSYS;
1884
1885 if (cam->state & DEV_DISCONNECTED) {
a966f3e7 1886 DBG(1, "Device not present");
4186ecf8 1887 mutex_unlock(&cam->fileop_mutex);
1da177e4
LT
1888 return -ENODEV;
1889 }
1890
1891 if (cam->state & DEV_MISCONFIGURED) {
a966f3e7
LR
1892 DBG(1, "The camera is misconfigured. Close and open it "
1893 "again.");
4186ecf8 1894 mutex_unlock(&cam->fileop_mutex);
1da177e4
LT
1895 return -EIO;
1896 }
1897
1898 if (cam->io == IO_MMAP) {
1899 DBG(3, "Close and open the device again to choose "
a966f3e7 1900 "the read method");
4186ecf8 1901 mutex_unlock(&cam->fileop_mutex);
f423b9a8 1902 return -EBUSY;
1da177e4
LT
1903 }
1904
1905 if (cam->io == IO_NONE) {
1906 if (!sn9c102_request_buffers(cam,cam->nreadbuffers, IO_READ)) {
a966f3e7 1907 DBG(1, "read() failed, not enough memory");
4186ecf8 1908 mutex_unlock(&cam->fileop_mutex);
1da177e4
LT
1909 return -ENOMEM;
1910 }
1911 cam->io = IO_READ;
1912 cam->stream = STREAM_ON;
a966f3e7
LR
1913 }
1914
1915 if (list_empty(&cam->inqueue)) {
1916 if (!list_empty(&cam->outqueue))
1917 sn9c102_empty_framequeues(cam);
1da177e4
LT
1918 sn9c102_queue_unusedframes(cam);
1919 }
1920
1921 if (!count) {
4186ecf8 1922 mutex_unlock(&cam->fileop_mutex);
1da177e4
LT
1923 return 0;
1924 }
1925
1926 if (list_empty(&cam->outqueue)) {
1927 if (filp->f_flags & O_NONBLOCK) {
4186ecf8 1928 mutex_unlock(&cam->fileop_mutex);
1da177e4
LT
1929 return -EAGAIN;
1930 }
f327ebbd
LR
1931 if (!cam->module_param.frame_timeout) {
1932 err = wait_event_interruptible
1933 ( cam->wait_frame,
1934 (!list_empty(&cam->outqueue)) ||
1935 (cam->state & DEV_DISCONNECTED) ||
1936 (cam->state & DEV_MISCONFIGURED) );
1937 if (err) {
1938 mutex_unlock(&cam->fileop_mutex);
1939 return err;
1940 }
1941 } else {
f423b9a8
LR
1942 timeout = wait_event_interruptible_timeout
1943 ( cam->wait_frame,
1944 (!list_empty(&cam->outqueue)) ||
1945 (cam->state & DEV_DISCONNECTED) ||
1946 (cam->state & DEV_MISCONFIGURED),
1947 cam->module_param.frame_timeout *
1948 1000 * msecs_to_jiffies(1) );
1949 if (timeout < 0) {
1950 mutex_unlock(&cam->fileop_mutex);
1951 return timeout;
f327ebbd
LR
1952 } else if (timeout == 0 &&
1953 !(cam->state & DEV_DISCONNECTED)) {
1954 DBG(1, "Video frame timeout elapsed");
1955 mutex_unlock(&cam->fileop_mutex);
1956 return -EIO;
1957 }
1da177e4
LT
1958 }
1959 if (cam->state & DEV_DISCONNECTED) {
4186ecf8 1960 mutex_unlock(&cam->fileop_mutex);
1da177e4
LT
1961 return -ENODEV;
1962 }
f327ebbd 1963 if (cam->state & DEV_MISCONFIGURED) {
4186ecf8 1964 mutex_unlock(&cam->fileop_mutex);
1da177e4
LT
1965 return -EIO;
1966 }
1967 }
1968
1969 f = list_entry(cam->outqueue.prev, struct sn9c102_frame_t, frame);
1970
a966f3e7
LR
1971 if (count > f->buf.bytesused)
1972 count = f->buf.bytesused;
1973
1974 if (copy_to_user(buf, f->bufmem, count)) {
1975 err = -EFAULT;
1976 goto exit;
1977 }
1978 *f_pos += count;
1979
1980exit:
1da177e4
LT
1981 spin_lock_irqsave(&cam->queue_lock, lock_flags);
1982 list_for_each_entry(i, &cam->outqueue, frame)
1983 i->state = F_UNUSED;
1984 INIT_LIST_HEAD(&cam->outqueue);
1985 spin_unlock_irqrestore(&cam->queue_lock, lock_flags);
1986
1987 sn9c102_queue_unusedframes(cam);
1988
a966f3e7
LR
1989 PDBGG("Frame #%lu, bytes read: %zu",
1990 (unsigned long)f->buf.index, count);
1da177e4 1991
4186ecf8 1992 mutex_unlock(&cam->fileop_mutex);
1da177e4
LT
1993
1994 return count;
1995}
1996
1997
1998static unsigned int sn9c102_poll(struct file *filp, poll_table *wait)
1999{
2000 struct sn9c102_device* cam = video_get_drvdata(video_devdata(filp));
a966f3e7
LR
2001 struct sn9c102_frame_t* f;
2002 unsigned long lock_flags;
1da177e4
LT
2003 unsigned int mask = 0;
2004
4186ecf8 2005 if (mutex_lock_interruptible(&cam->fileop_mutex))
1da177e4
LT
2006 return POLLERR;
2007
2008 if (cam->state & DEV_DISCONNECTED) {
a966f3e7 2009 DBG(1, "Device not present");
1da177e4
LT
2010 goto error;
2011 }
2012
2013 if (cam->state & DEV_MISCONFIGURED) {
a966f3e7
LR
2014 DBG(1, "The camera is misconfigured. Close and open it "
2015 "again.");
1da177e4
LT
2016 goto error;
2017 }
2018
2019 if (cam->io == IO_NONE) {
2020 if (!sn9c102_request_buffers(cam, cam->nreadbuffers,
d56410e0 2021 IO_READ)) {
a966f3e7 2022 DBG(1, "poll() failed, not enough memory");
1da177e4
LT
2023 goto error;
2024 }
2025 cam->io = IO_READ;
2026 cam->stream = STREAM_ON;
2027 }
2028
a966f3e7
LR
2029 if (cam->io == IO_READ) {
2030 spin_lock_irqsave(&cam->queue_lock, lock_flags);
2031 list_for_each_entry(f, &cam->outqueue, frame)
2032 f->state = F_UNUSED;
2033 INIT_LIST_HEAD(&cam->outqueue);
2034 spin_unlock_irqrestore(&cam->queue_lock, lock_flags);
1da177e4 2035 sn9c102_queue_unusedframes(cam);
a966f3e7 2036 }
1da177e4
LT
2037
2038 poll_wait(filp, &cam->wait_frame, wait);
2039
2040 if (!list_empty(&cam->outqueue))
2041 mask |= POLLIN | POLLRDNORM;
2042
4186ecf8 2043 mutex_unlock(&cam->fileop_mutex);
1da177e4
LT
2044
2045 return mask;
2046
2047error:
4186ecf8 2048 mutex_unlock(&cam->fileop_mutex);
1da177e4
LT
2049 return POLLERR;
2050}
2051
2052
2053static void sn9c102_vm_open(struct vm_area_struct* vma)
2054{
2055 struct sn9c102_frame_t* f = vma->vm_private_data;
2056 f->vma_use_count++;
2057}
2058
2059
2060static void sn9c102_vm_close(struct vm_area_struct* vma)
2061{
2062 /* NOTE: buffers are not freed here */
2063 struct sn9c102_frame_t* f = vma->vm_private_data;
2064 f->vma_use_count--;
2065}
2066
2067
2068static struct vm_operations_struct sn9c102_vm_ops = {
2069 .open = sn9c102_vm_open,
2070 .close = sn9c102_vm_close,
2071};
2072
2073
2074static int sn9c102_mmap(struct file* filp, struct vm_area_struct *vma)
2075{
2076 struct sn9c102_device* cam = video_get_drvdata(video_devdata(filp));
2077 unsigned long size = vma->vm_end - vma->vm_start,
d56410e0 2078 start = vma->vm_start;
cd6fcc55 2079 void *pos;
1da177e4
LT
2080 u32 i;
2081
4186ecf8 2082 if (mutex_lock_interruptible(&cam->fileop_mutex))
1da177e4
LT
2083 return -ERESTARTSYS;
2084
2085 if (cam->state & DEV_DISCONNECTED) {
a966f3e7 2086 DBG(1, "Device not present");
4186ecf8 2087 mutex_unlock(&cam->fileop_mutex);
1da177e4
LT
2088 return -ENODEV;
2089 }
2090
2091 if (cam->state & DEV_MISCONFIGURED) {
a966f3e7
LR
2092 DBG(1, "The camera is misconfigured. Close and open it "
2093 "again.");
4186ecf8 2094 mutex_unlock(&cam->fileop_mutex);
1da177e4
LT
2095 return -EIO;
2096 }
2097
f423b9a8
LR
2098 if (!(vma->vm_flags & (VM_WRITE | VM_READ))) {
2099 mutex_unlock(&cam->fileop_mutex);
2100 return -EACCES;
2101 }
2102
2103 if (cam->io != IO_MMAP ||
1da177e4 2104 size != PAGE_ALIGN(cam->frame[0].buf.length)) {
4186ecf8 2105 mutex_unlock(&cam->fileop_mutex);
1da177e4
LT
2106 return -EINVAL;
2107 }
2108
2109 for (i = 0; i < cam->nbuffers; i++) {
2110 if ((cam->frame[i].buf.m.offset>>PAGE_SHIFT) == vma->vm_pgoff)
2111 break;
2112 }
2113 if (i == cam->nbuffers) {
4186ecf8 2114 mutex_unlock(&cam->fileop_mutex);
1da177e4
LT
2115 return -EINVAL;
2116 }
2117
1da177e4 2118 vma->vm_flags |= VM_IO;
cd6fcc55 2119 vma->vm_flags |= VM_RESERVED;
1da177e4 2120
cd6fcc55 2121 pos = cam->frame[i].bufmem;
1da177e4 2122 while (size > 0) { /* size is page-aligned */
cd6fcc55 2123 if (vm_insert_page(vma, start, vmalloc_to_page(pos))) {
4186ecf8 2124 mutex_unlock(&cam->fileop_mutex);
1da177e4
LT
2125 return -EAGAIN;
2126 }
2127 start += PAGE_SIZE;
2128 pos += PAGE_SIZE;
2129 size -= PAGE_SIZE;
2130 }
2131
2132 vma->vm_ops = &sn9c102_vm_ops;
2133 vma->vm_private_data = &cam->frame[i];
1da177e4
LT
2134 sn9c102_vm_open(vma);
2135
4186ecf8 2136 mutex_unlock(&cam->fileop_mutex);
1da177e4
LT
2137
2138 return 0;
2139}
2140
a966f3e7 2141/*****************************************************************************/
1da177e4 2142
a966f3e7
LR
2143static int
2144sn9c102_vidioc_querycap(struct sn9c102_device* cam, void __user * arg)
1da177e4 2145{
a966f3e7
LR
2146 struct v4l2_capability cap = {
2147 .driver = "sn9c102",
2148 .version = SN9C102_MODULE_VERSION_CODE,
2149 .capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE |
d56410e0 2150 V4L2_CAP_STREAMING,
a966f3e7
LR
2151 };
2152
2153 strlcpy(cap.card, cam->v4ldev->name, sizeof(cap.card));
2154 if (usb_make_path(cam->usbdev, cap.bus_info, sizeof(cap.bus_info)) < 0)
cd6fcc55 2155 strlcpy(cap.bus_info, cam->usbdev->dev.bus_id,
d56410e0 2156 sizeof(cap.bus_info));
a966f3e7
LR
2157
2158 if (copy_to_user(arg, &cap, sizeof(cap)))
2159 return -EFAULT;
1da177e4 2160
a966f3e7
LR
2161 return 0;
2162}
1da177e4 2163
1da177e4 2164
a966f3e7
LR
2165static int
2166sn9c102_vidioc_enuminput(struct sn9c102_device* cam, void __user * arg)
2167{
2168 struct v4l2_input i;
1da177e4 2169
a966f3e7
LR
2170 if (copy_from_user(&i, arg, sizeof(i)))
2171 return -EFAULT;
1da177e4 2172
a966f3e7
LR
2173 if (i.index)
2174 return -EINVAL;
1da177e4 2175
a966f3e7 2176 memset(&i, 0, sizeof(i));
cd6fcc55 2177 strcpy(i.name, "Camera");
2ffab02f 2178 i.type = V4L2_INPUT_TYPE_CAMERA;
1da177e4 2179
a966f3e7
LR
2180 if (copy_to_user(arg, &i, sizeof(i)))
2181 return -EFAULT;
1da177e4 2182
a966f3e7
LR
2183 return 0;
2184}
1da177e4 2185
1da177e4 2186
a966f3e7 2187static int
2ffab02f
LR
2188sn9c102_vidioc_g_input(struct sn9c102_device* cam, void __user * arg)
2189{
2190 int index = 0;
2191
2192 if (copy_to_user(arg, &index, sizeof(index)))
2193 return -EFAULT;
2194
2195 return 0;
2196}
2197
2198
2199static int
2200sn9c102_vidioc_s_input(struct sn9c102_device* cam, void __user * arg)
a966f3e7
LR
2201{
2202 int index;
1da177e4 2203
a966f3e7
LR
2204 if (copy_from_user(&index, arg, sizeof(index)))
2205 return -EFAULT;
1da177e4 2206
a966f3e7 2207 if (index != 0)
1da177e4 2208 return -EINVAL;
1da177e4 2209
a966f3e7
LR
2210 return 0;
2211}
1da177e4 2212
1da177e4 2213
a966f3e7
LR
2214static int
2215sn9c102_vidioc_query_ctrl(struct sn9c102_device* cam, void __user * arg)
2216{
2ffab02f 2217 struct sn9c102_sensor* s = &cam->sensor;
a966f3e7
LR
2218 struct v4l2_queryctrl qc;
2219 u8 i;
1da177e4 2220
a966f3e7
LR
2221 if (copy_from_user(&qc, arg, sizeof(qc)))
2222 return -EFAULT;
1da177e4 2223
a966f3e7
LR
2224 for (i = 0; i < ARRAY_SIZE(s->qctrl); i++)
2225 if (qc.id && qc.id == s->qctrl[i].id) {
2226 memcpy(&qc, &(s->qctrl[i]), sizeof(qc));
2227 if (copy_to_user(arg, &qc, sizeof(qc)))
2228 return -EFAULT;
2229 return 0;
2230 }
1da177e4 2231
a966f3e7
LR
2232 return -EINVAL;
2233}
1da177e4 2234
1da177e4 2235
a966f3e7
LR
2236static int
2237sn9c102_vidioc_g_ctrl(struct sn9c102_device* cam, void __user * arg)
2238{
2ffab02f 2239 struct sn9c102_sensor* s = &cam->sensor;
a966f3e7
LR
2240 struct v4l2_control ctrl;
2241 int err = 0;
2242 u8 i;
1da177e4 2243
a966f3e7
LR
2244 if (!s->get_ctrl && !s->set_ctrl)
2245 return -EINVAL;
1da177e4 2246
a966f3e7
LR
2247 if (copy_from_user(&ctrl, arg, sizeof(ctrl)))
2248 return -EFAULT;
2249
2250 if (!s->get_ctrl) {
52950ed4 2251 for (i = 0; i < ARRAY_SIZE(s->qctrl); i++)
a966f3e7
LR
2252 if (ctrl.id && ctrl.id == s->qctrl[i].id) {
2253 ctrl.value = s->_qctrl[i].default_value;
2254 goto exit;
1da177e4 2255 }
a966f3e7
LR
2256 return -EINVAL;
2257 } else
2258 err = s->get_ctrl(cam, &ctrl);
1da177e4 2259
a966f3e7
LR
2260exit:
2261 if (copy_to_user(arg, &ctrl, sizeof(ctrl)))
2262 return -EFAULT;
1da177e4 2263
f327ebbd
LR
2264 PDBGG("VIDIOC_G_CTRL: id %lu, value %lu",
2265 (unsigned long)ctrl.id, (unsigned long)ctrl.value);
2266
a966f3e7
LR
2267 return err;
2268}
1da177e4 2269
1da177e4 2270
a966f3e7
LR
2271static int
2272sn9c102_vidioc_s_ctrl(struct sn9c102_device* cam, void __user * arg)
2273{
2ffab02f 2274 struct sn9c102_sensor* s = &cam->sensor;
a966f3e7
LR
2275 struct v4l2_control ctrl;
2276 u8 i;
2277 int err = 0;
1da177e4 2278
a966f3e7
LR
2279 if (!s->set_ctrl)
2280 return -EINVAL;
1da177e4 2281
a966f3e7
LR
2282 if (copy_from_user(&ctrl, arg, sizeof(ctrl)))
2283 return -EFAULT;
1da177e4 2284
a966f3e7
LR
2285 for (i = 0; i < ARRAY_SIZE(s->qctrl); i++)
2286 if (ctrl.id == s->qctrl[i].id) {
2ffab02f
LR
2287 if (s->qctrl[i].flags & V4L2_CTRL_FLAG_DISABLED)
2288 return -EINVAL;
a966f3e7
LR
2289 if (ctrl.value < s->qctrl[i].minimum ||
2290 ctrl.value > s->qctrl[i].maximum)
2291 return -ERANGE;
2292 ctrl.value -= ctrl.value % s->qctrl[i].step;
2293 break;
2294 }
1da177e4 2295
a966f3e7
LR
2296 if ((err = s->set_ctrl(cam, &ctrl)))
2297 return err;
1da177e4 2298
a966f3e7 2299 s->_qctrl[i].default_value = ctrl.value;
1da177e4 2300
a966f3e7
LR
2301 PDBGG("VIDIOC_S_CTRL: id %lu, value %lu",
2302 (unsigned long)ctrl.id, (unsigned long)ctrl.value);
1da177e4 2303
a966f3e7
LR
2304 return 0;
2305}
1da177e4 2306
1da177e4 2307
a966f3e7
LR
2308static int
2309sn9c102_vidioc_cropcap(struct sn9c102_device* cam, void __user * arg)
2310{
2ffab02f 2311 struct v4l2_cropcap* cc = &(cam->sensor.cropcap);
1da177e4 2312
a966f3e7
LR
2313 cc->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
2314 cc->pixelaspect.numerator = 1;
2315 cc->pixelaspect.denominator = 1;
1da177e4 2316
a966f3e7
LR
2317 if (copy_to_user(arg, cc, sizeof(*cc)))
2318 return -EFAULT;
1da177e4 2319
a966f3e7
LR
2320 return 0;
2321}
1da177e4 2322
1da177e4 2323
a966f3e7
LR
2324static int
2325sn9c102_vidioc_g_crop(struct sn9c102_device* cam, void __user * arg)
2326{
2ffab02f 2327 struct sn9c102_sensor* s = &cam->sensor;
a966f3e7
LR
2328 struct v4l2_crop crop = {
2329 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
2330 };
1da177e4 2331
a966f3e7 2332 memcpy(&(crop.c), &(s->_rect), sizeof(struct v4l2_rect));
1da177e4 2333
a966f3e7
LR
2334 if (copy_to_user(arg, &crop, sizeof(crop)))
2335 return -EFAULT;
1da177e4 2336
a966f3e7
LR
2337 return 0;
2338}
1da177e4 2339
1da177e4 2340
a966f3e7
LR
2341static int
2342sn9c102_vidioc_s_crop(struct sn9c102_device* cam, void __user * arg)
2343{
2ffab02f 2344 struct sn9c102_sensor* s = &cam->sensor;
a966f3e7
LR
2345 struct v4l2_crop crop;
2346 struct v4l2_rect* rect;
2347 struct v4l2_rect* bounds = &(s->cropcap.bounds);
2348 struct v4l2_pix_format* pix_format = &(s->pix_format);
2349 u8 scale;
2350 const enum sn9c102_stream_state stream = cam->stream;
2351 const u32 nbuffers = cam->nbuffers;
2352 u32 i;
2353 int err = 0;
1da177e4 2354
a966f3e7
LR
2355 if (copy_from_user(&crop, arg, sizeof(crop)))
2356 return -EFAULT;
1da177e4 2357
a966f3e7 2358 rect = &(crop.c);
1da177e4 2359
a966f3e7
LR
2360 if (crop.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
2361 return -EINVAL;
1da177e4 2362
a966f3e7
LR
2363 if (cam->module_param.force_munmap)
2364 for (i = 0; i < cam->nbuffers; i++)
2365 if (cam->frame[i].vma_use_count) {
2366 DBG(3, "VIDIOC_S_CROP failed. "
2367 "Unmap the buffers first.");
f423b9a8 2368 return -EBUSY;
a966f3e7 2369 }
1da177e4 2370
a966f3e7
LR
2371 /* Preserve R,G or B origin */
2372 rect->left = (s->_rect.left & 1L) ? rect->left | 1L : rect->left & ~1L;
2373 rect->top = (s->_rect.top & 1L) ? rect->top | 1L : rect->top & ~1L;
2374
2375 if (rect->width < 16)
2376 rect->width = 16;
2377 if (rect->height < 16)
2378 rect->height = 16;
2379 if (rect->width > bounds->width)
2380 rect->width = bounds->width;
2381 if (rect->height > bounds->height)
2382 rect->height = bounds->height;
2383 if (rect->left < bounds->left)
2384 rect->left = bounds->left;
2385 if (rect->top < bounds->top)
2386 rect->top = bounds->top;
2387 if (rect->left + rect->width > bounds->left + bounds->width)
2388 rect->left = bounds->left+bounds->width - rect->width;
2389 if (rect->top + rect->height > bounds->top + bounds->height)
2390 rect->top = bounds->top+bounds->height - rect->height;
2391
2392 rect->width &= ~15L;
2393 rect->height &= ~15L;
2394
2395 if (SN9C102_PRESERVE_IMGSCALE) {
2396 /* Calculate the actual scaling factor */
2397 u32 a, b;
2398 a = rect->width * rect->height;
2399 b = pix_format->width * pix_format->height;
2400 scale = b ? (u8)((a / b) < 4 ? 1 : ((a / b) < 16 ? 2 : 4)) : 1;
2401 } else
2402 scale = 1;
2403
2404 if (cam->stream == STREAM_ON)
2405 if ((err = sn9c102_stream_interrupt(cam)))
2406 return err;
1da177e4 2407
a966f3e7
LR
2408 if (copy_to_user(arg, &crop, sizeof(crop))) {
2409 cam->stream = stream;
2410 return -EFAULT;
1da177e4
LT
2411 }
2412
a966f3e7
LR
2413 if (cam->module_param.force_munmap || cam->io == IO_READ)
2414 sn9c102_release_buffers(cam);
1da177e4 2415
a966f3e7
LR
2416 err = sn9c102_set_crop(cam, rect);
2417 if (s->set_crop)
2418 err += s->set_crop(cam, rect);
2419 err += sn9c102_set_scale(cam, scale);
1da177e4 2420
a966f3e7
LR
2421 if (err) { /* atomic, no rollback in ioctl() */
2422 cam->state |= DEV_MISCONFIGURED;
2423 DBG(1, "VIDIOC_S_CROP failed because of hardware problems. To "
2424 "use the camera, close and open /dev/video%d again.",
2425 cam->v4ldev->minor);
2426 return -EIO;
2427 }
1da177e4 2428
a966f3e7
LR
2429 s->pix_format.width = rect->width/scale;
2430 s->pix_format.height = rect->height/scale;
2431 memcpy(&(s->_rect), rect, sizeof(*rect));
1da177e4 2432
a966f3e7
LR
2433 if ((cam->module_param.force_munmap || cam->io == IO_READ) &&
2434 nbuffers != sn9c102_request_buffers(cam, nbuffers, cam->io)) {
2435 cam->state |= DEV_MISCONFIGURED;
2436 DBG(1, "VIDIOC_S_CROP failed because of not enough memory. To "
2437 "use the camera, close and open /dev/video%d again.",
2438 cam->v4ldev->minor);
2439 return -ENOMEM;
1da177e4
LT
2440 }
2441
a966f3e7
LR
2442 if (cam->io == IO_READ)
2443 sn9c102_empty_framequeues(cam);
2444 else if (cam->module_param.force_munmap)
2445 sn9c102_requeue_outqueue(cam);
1da177e4 2446
a966f3e7 2447 cam->stream = stream;
1da177e4 2448
a966f3e7
LR
2449 return 0;
2450}
1da177e4 2451
1da177e4 2452
f327ebbd
LR
2453static int
2454sn9c102_vidioc_enum_framesizes(struct sn9c102_device* cam, void __user * arg)
2455{
2456 struct v4l2_frmsizeenum frmsize;
2457
2458 if (copy_from_user(&frmsize, arg, sizeof(frmsize)))
2459 return -EFAULT;
2460
2461 if (frmsize.index != 0)
2462 return -EINVAL;
2463
2464 switch (cam->bridge) {
2465 case BRIDGE_SN9C101:
2466 case BRIDGE_SN9C102:
2467 case BRIDGE_SN9C103:
2468 if (frmsize.pixel_format != V4L2_PIX_FMT_SN9C10X &&
2469 frmsize.pixel_format != V4L2_PIX_FMT_SBGGR8)
2470 return -EINVAL;
2471 case BRIDGE_SN9C105:
2472 case BRIDGE_SN9C120:
2473 if (frmsize.pixel_format != V4L2_PIX_FMT_JPEG &&
2474 frmsize.pixel_format != V4L2_PIX_FMT_SBGGR8)
2475 return -EINVAL;
2476 }
2477
2478 frmsize.type = V4L2_FRMSIZE_TYPE_STEPWISE;
2479 frmsize.stepwise.min_width = frmsize.stepwise.step_width = 16;
2480 frmsize.stepwise.min_height = frmsize.stepwise.step_height = 16;
2481 frmsize.stepwise.max_width = cam->sensor.cropcap.bounds.width;
2482 frmsize.stepwise.max_height = cam->sensor.cropcap.bounds.height;
2483 memset(&frmsize.reserved, 0, sizeof(frmsize.reserved));
2484
2485 if (copy_to_user(arg, &frmsize, sizeof(frmsize)))
2486 return -EFAULT;
2487
2488 return 0;
2489}
2490
2491
a966f3e7
LR
2492static int
2493sn9c102_vidioc_enum_fmt(struct sn9c102_device* cam, void __user * arg)
2494{
2495 struct v4l2_fmtdesc fmtd;
1da177e4 2496
a966f3e7
LR
2497 if (copy_from_user(&fmtd, arg, sizeof(fmtd)))
2498 return -EFAULT;
1da177e4 2499
f327ebbd
LR
2500 if (fmtd.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
2501 return -EINVAL;
2502
a966f3e7
LR
2503 if (fmtd.index == 0) {
2504 strcpy(fmtd.description, "bayer rgb");
2505 fmtd.pixelformat = V4L2_PIX_FMT_SBGGR8;
2506 } else if (fmtd.index == 1) {
f327ebbd
LR
2507 switch (cam->bridge) {
2508 case BRIDGE_SN9C101:
2509 case BRIDGE_SN9C102:
2510 case BRIDGE_SN9C103:
f423b9a8
LR
2511 strcpy(fmtd.description, "compressed");
2512 fmtd.pixelformat = V4L2_PIX_FMT_SN9C10X;
f327ebbd
LR
2513 break;
2514 case BRIDGE_SN9C105:
2515 case BRIDGE_SN9C120:
2516 strcpy(fmtd.description, "JPEG");
2517 fmtd.pixelformat = V4L2_PIX_FMT_JPEG;
2518 break;
2519 }
a966f3e7
LR
2520 fmtd.flags = V4L2_FMT_FLAG_COMPRESSED;
2521 } else
2522 return -EINVAL;
1da177e4 2523
a966f3e7
LR
2524 fmtd.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
2525 memset(&fmtd.reserved, 0, sizeof(fmtd.reserved));
1da177e4 2526
a966f3e7
LR
2527 if (copy_to_user(arg, &fmtd, sizeof(fmtd)))
2528 return -EFAULT;
1da177e4 2529
a966f3e7
LR
2530 return 0;
2531}
1da177e4 2532
1da177e4 2533
a966f3e7
LR
2534static int
2535sn9c102_vidioc_g_fmt(struct sn9c102_device* cam, void __user * arg)
2536{
2537 struct v4l2_format format;
2ffab02f 2538 struct v4l2_pix_format* pfmt = &(cam->sensor.pix_format);
1da177e4 2539
a966f3e7
LR
2540 if (copy_from_user(&format, arg, sizeof(format)))
2541 return -EFAULT;
1da177e4 2542
a966f3e7
LR
2543 if (format.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
2544 return -EINVAL;
1da177e4 2545
f423b9a8
LR
2546 pfmt->colorspace = (pfmt->pixelformat == V4L2_PIX_FMT_JPEG) ?
2547 V4L2_COLORSPACE_JPEG : V4L2_COLORSPACE_SRGB;
2548 pfmt->bytesperline = (pfmt->pixelformat == V4L2_PIX_FMT_SN9C10X ||
2549 pfmt->pixelformat == V4L2_PIX_FMT_JPEG)
d56410e0 2550 ? 0 : (pfmt->width * pfmt->priv) / 8;
a966f3e7
LR
2551 pfmt->sizeimage = pfmt->height * ((pfmt->width*pfmt->priv)/8);
2552 pfmt->field = V4L2_FIELD_NONE;
2553 memcpy(&(format.fmt.pix), pfmt, sizeof(*pfmt));
1da177e4 2554
a966f3e7
LR
2555 if (copy_to_user(arg, &format, sizeof(format)))
2556 return -EFAULT;
1da177e4 2557
a966f3e7
LR
2558 return 0;
2559}
1da177e4 2560
1da177e4 2561
a966f3e7
LR
2562static int
2563sn9c102_vidioc_try_s_fmt(struct sn9c102_device* cam, unsigned int cmd,
d56410e0 2564 void __user * arg)
a966f3e7 2565{
2ffab02f 2566 struct sn9c102_sensor* s = &cam->sensor;
a966f3e7
LR
2567 struct v4l2_format format;
2568 struct v4l2_pix_format* pix;
2569 struct v4l2_pix_format* pfmt = &(s->pix_format);
2570 struct v4l2_rect* bounds = &(s->cropcap.bounds);
2571 struct v4l2_rect rect;
2572 u8 scale;
2573 const enum sn9c102_stream_state stream = cam->stream;
2574 const u32 nbuffers = cam->nbuffers;
2575 u32 i;
2576 int err = 0;
1da177e4 2577
a966f3e7
LR
2578 if (copy_from_user(&format, arg, sizeof(format)))
2579 return -EFAULT;
1da177e4 2580
a966f3e7 2581 pix = &(format.fmt.pix);
1da177e4 2582
a966f3e7
LR
2583 if (format.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
2584 return -EINVAL;
1da177e4 2585
a966f3e7 2586 memcpy(&rect, &(s->_rect), sizeof(rect));
1da177e4 2587
a966f3e7
LR
2588 { /* calculate the actual scaling factor */
2589 u32 a, b;
2590 a = rect.width * rect.height;
2591 b = pix->width * pix->height;
2592 scale = b ? (u8)((a / b) < 4 ? 1 : ((a / b) < 16 ? 2 : 4)) : 1;
1da177e4
LT
2593 }
2594
a966f3e7
LR
2595 rect.width = scale * pix->width;
2596 rect.height = scale * pix->height;
1da177e4 2597
a966f3e7
LR
2598 if (rect.width < 16)
2599 rect.width = 16;
2600 if (rect.height < 16)
2601 rect.height = 16;
2602 if (rect.width > bounds->left + bounds->width - rect.left)
2603 rect.width = bounds->left + bounds->width - rect.left;
2604 if (rect.height > bounds->top + bounds->height - rect.top)
2605 rect.height = bounds->top + bounds->height - rect.top;
1da177e4 2606
a966f3e7
LR
2607 rect.width &= ~15L;
2608 rect.height &= ~15L;
1da177e4 2609
a966f3e7
LR
2610 { /* adjust the scaling factor */
2611 u32 a, b;
2612 a = rect.width * rect.height;
2613 b = pix->width * pix->height;
2614 scale = b ? (u8)((a / b) < 4 ? 1 : ((a / b) < 16 ? 2 : 4)) : 1;
2615 }
2616
2617 pix->width = rect.width / scale;
2618 pix->height = rect.height / scale;
2619
f327ebbd
LR
2620 switch (cam->bridge) {
2621 case BRIDGE_SN9C101:
2622 case BRIDGE_SN9C102:
2623 case BRIDGE_SN9C103:
f423b9a8
LR
2624 if (pix->pixelformat != V4L2_PIX_FMT_SN9C10X &&
2625 pix->pixelformat != V4L2_PIX_FMT_SBGGR8)
2626 pix->pixelformat = pfmt->pixelformat;
f327ebbd
LR
2627 break;
2628 case BRIDGE_SN9C105:
2629 case BRIDGE_SN9C120:
2630 if (pix->pixelformat != V4L2_PIX_FMT_JPEG &&
2631 pix->pixelformat != V4L2_PIX_FMT_SBGGR8)
2632 pix->pixelformat = pfmt->pixelformat;
2633 break;
2634 }
a966f3e7 2635 pix->priv = pfmt->priv; /* bpp */
f423b9a8
LR
2636 pix->colorspace = (pix->pixelformat == V4L2_PIX_FMT_JPEG) ?
2637 V4L2_COLORSPACE_JPEG : V4L2_COLORSPACE_SRGB;
f327ebbd
LR
2638 pix->bytesperline = (pix->pixelformat == V4L2_PIX_FMT_SN9C10X ||
2639 pix->pixelformat == V4L2_PIX_FMT_JPEG)
d56410e0 2640 ? 0 : (pix->width * pix->priv) / 8;
a966f3e7
LR
2641 pix->sizeimage = pix->height * ((pix->width * pix->priv) / 8);
2642 pix->field = V4L2_FIELD_NONE;
2643
2644 if (cmd == VIDIOC_TRY_FMT) {
2645 if (copy_to_user(arg, &format, sizeof(format)))
2646 return -EFAULT;
2647 return 0;
2648 }
1da177e4 2649
a966f3e7 2650 if (cam->module_param.force_munmap)
1da177e4
LT
2651 for (i = 0; i < cam->nbuffers; i++)
2652 if (cam->frame[i].vma_use_count) {
a966f3e7
LR
2653 DBG(3, "VIDIOC_S_FMT failed. Unmap the "
2654 "buffers first.");
f423b9a8 2655 return -EBUSY;
1da177e4
LT
2656 }
2657
a966f3e7
LR
2658 if (cam->stream == STREAM_ON)
2659 if ((err = sn9c102_stream_interrupt(cam)))
2660 return err;
1da177e4 2661
a966f3e7
LR
2662 if (copy_to_user(arg, &format, sizeof(format))) {
2663 cam->stream = stream;
2664 return -EFAULT;
2665 }
1da177e4 2666
a966f3e7 2667 if (cam->module_param.force_munmap || cam->io == IO_READ)
1da177e4 2668 sn9c102_release_buffers(cam);
1da177e4 2669
a966f3e7
LR
2670 err += sn9c102_set_pix_format(cam, pix);
2671 err += sn9c102_set_crop(cam, &rect);
2672 if (s->set_pix_format)
2673 err += s->set_pix_format(cam, pix);
2674 if (s->set_crop)
2675 err += s->set_crop(cam, &rect);
2676 err += sn9c102_set_scale(cam, scale);
1da177e4 2677
a966f3e7
LR
2678 if (err) { /* atomic, no rollback in ioctl() */
2679 cam->state |= DEV_MISCONFIGURED;
2680 DBG(1, "VIDIOC_S_FMT failed because of hardware problems. To "
2681 "use the camera, close and open /dev/video%d again.",
2682 cam->v4ldev->minor);
2683 return -EIO;
2684 }
1da177e4 2685
a966f3e7
LR
2686 memcpy(pfmt, pix, sizeof(*pix));
2687 memcpy(&(s->_rect), &rect, sizeof(rect));
2688
2689 if ((cam->module_param.force_munmap || cam->io == IO_READ) &&
2690 nbuffers != sn9c102_request_buffers(cam, nbuffers, cam->io)) {
2691 cam->state |= DEV_MISCONFIGURED;
2692 DBG(1, "VIDIOC_S_FMT failed because of not enough memory. To "
2693 "use the camera, close and open /dev/video%d again.",
2694 cam->v4ldev->minor);
2695 return -ENOMEM;
1da177e4
LT
2696 }
2697
a966f3e7
LR
2698 if (cam->io == IO_READ)
2699 sn9c102_empty_framequeues(cam);
2700 else if (cam->module_param.force_munmap)
2701 sn9c102_requeue_outqueue(cam);
1da177e4 2702
a966f3e7 2703 cam->stream = stream;
1da177e4 2704
a966f3e7
LR
2705 return 0;
2706}
2707
2708
2709static int
2710sn9c102_vidioc_g_jpegcomp(struct sn9c102_device* cam, void __user * arg)
2711{
f327ebbd 2712 if (copy_to_user(arg, &cam->compression, sizeof(cam->compression)))
a966f3e7 2713 return -EFAULT;
1da177e4 2714
a966f3e7
LR
2715 return 0;
2716}
1da177e4 2717
1da177e4 2718
a966f3e7
LR
2719static int
2720sn9c102_vidioc_s_jpegcomp(struct sn9c102_device* cam, void __user * arg)
2721{
2722 struct v4l2_jpegcompression jc;
2723 const enum sn9c102_stream_state stream = cam->stream;
2724 int err = 0;
1da177e4 2725
a966f3e7
LR
2726 if (copy_from_user(&jc, arg, sizeof(jc)))
2727 return -EFAULT;
1da177e4 2728
a966f3e7
LR
2729 if (jc.quality != 0 && jc.quality != 1)
2730 return -EINVAL;
2731
2732 if (cam->stream == STREAM_ON)
2733 if ((err = sn9c102_stream_interrupt(cam)))
2734 return err;
2735
2736 err += sn9c102_set_compression(cam, &jc);
2737 if (err) { /* atomic, no rollback in ioctl() */
2738 cam->state |= DEV_MISCONFIGURED;
2739 DBG(1, "VIDIOC_S_JPEGCOMP failed because of hardware "
2740 "problems. To use the camera, close and open "
2741 "/dev/video%d again.", cam->v4ldev->minor);
2742 return -EIO;
1da177e4
LT
2743 }
2744
a966f3e7 2745 cam->compression.quality = jc.quality;
1da177e4 2746
a966f3e7 2747 cam->stream = stream;
1da177e4 2748
a966f3e7
LR
2749 return 0;
2750}
1da177e4 2751
a966f3e7
LR
2752
2753static int
2754sn9c102_vidioc_reqbufs(struct sn9c102_device* cam, void __user * arg)
2755{
2756 struct v4l2_requestbuffers rb;
2757 u32 i;
2758 int err;
2759
2760 if (copy_from_user(&rb, arg, sizeof(rb)))
2761 return -EFAULT;
2762
2763 if (rb.type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
2764 rb.memory != V4L2_MEMORY_MMAP)
2765 return -EINVAL;
2766
2767 if (cam->io == IO_READ) {
2768 DBG(3, "Close and open the device again to choose the mmap "
2769 "I/O method");
f423b9a8 2770 return -EBUSY;
a966f3e7
LR
2771 }
2772
2773 for (i = 0; i < cam->nbuffers; i++)
2774 if (cam->frame[i].vma_use_count) {
2775 DBG(3, "VIDIOC_REQBUFS failed. Previous buffers are "
2776 "still mapped.");
f423b9a8 2777 return -EBUSY;
a966f3e7 2778 }
1da177e4 2779
a966f3e7
LR
2780 if (cam->stream == STREAM_ON)
2781 if ((err = sn9c102_stream_interrupt(cam)))
2782 return err;
1da177e4 2783
a966f3e7 2784 sn9c102_empty_framequeues(cam);
1da177e4 2785
a966f3e7
LR
2786 sn9c102_release_buffers(cam);
2787 if (rb.count)
2788 rb.count = sn9c102_request_buffers(cam, rb.count, IO_MMAP);
1da177e4 2789
a966f3e7
LR
2790 if (copy_to_user(arg, &rb, sizeof(rb))) {
2791 sn9c102_release_buffers(cam);
2792 cam->io = IO_NONE;
2793 return -EFAULT;
1da177e4
LT
2794 }
2795
a966f3e7 2796 cam->io = rb.count ? IO_MMAP : IO_NONE;
1da177e4 2797
a966f3e7
LR
2798 return 0;
2799}
1da177e4 2800
1da177e4 2801
a966f3e7
LR
2802static int
2803sn9c102_vidioc_querybuf(struct sn9c102_device* cam, void __user * arg)
2804{
2805 struct v4l2_buffer b;
1da177e4 2806
a966f3e7
LR
2807 if (copy_from_user(&b, arg, sizeof(b)))
2808 return -EFAULT;
1da177e4 2809
a966f3e7
LR
2810 if (b.type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
2811 b.index >= cam->nbuffers || cam->io != IO_MMAP)
2812 return -EINVAL;
1da177e4 2813
a966f3e7 2814 memcpy(&b, &cam->frame[b.index].buf, sizeof(b));
1da177e4 2815
a966f3e7
LR
2816 if (cam->frame[b.index].vma_use_count)
2817 b.flags |= V4L2_BUF_FLAG_MAPPED;
1da177e4 2818
a966f3e7
LR
2819 if (cam->frame[b.index].state == F_DONE)
2820 b.flags |= V4L2_BUF_FLAG_DONE;
2821 else if (cam->frame[b.index].state != F_UNUSED)
2822 b.flags |= V4L2_BUF_FLAG_QUEUED;
1da177e4 2823
a966f3e7
LR
2824 if (copy_to_user(arg, &b, sizeof(b)))
2825 return -EFAULT;
1da177e4 2826
a966f3e7
LR
2827 return 0;
2828}
1da177e4 2829
1da177e4 2830
a966f3e7
LR
2831static int
2832sn9c102_vidioc_qbuf(struct sn9c102_device* cam, void __user * arg)
2833{
2834 struct v4l2_buffer b;
2835 unsigned long lock_flags;
1da177e4 2836
a966f3e7
LR
2837 if (copy_from_user(&b, arg, sizeof(b)))
2838 return -EFAULT;
1da177e4 2839
a966f3e7
LR
2840 if (b.type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
2841 b.index >= cam->nbuffers || cam->io != IO_MMAP)
2842 return -EINVAL;
1da177e4 2843
a966f3e7
LR
2844 if (cam->frame[b.index].state != F_UNUSED)
2845 return -EINVAL;
1da177e4 2846
a966f3e7 2847 cam->frame[b.index].state = F_QUEUED;
1da177e4 2848
a966f3e7
LR
2849 spin_lock_irqsave(&cam->queue_lock, lock_flags);
2850 list_add_tail(&cam->frame[b.index].frame, &cam->inqueue);
2851 spin_unlock_irqrestore(&cam->queue_lock, lock_flags);
1da177e4 2852
a966f3e7 2853 PDBGG("Frame #%lu queued", (unsigned long)b.index);
1da177e4 2854
a966f3e7
LR
2855 return 0;
2856}
1da177e4 2857
1da177e4 2858
a966f3e7
LR
2859static int
2860sn9c102_vidioc_dqbuf(struct sn9c102_device* cam, struct file* filp,
d56410e0 2861 void __user * arg)
a966f3e7
LR
2862{
2863 struct v4l2_buffer b;
2864 struct sn9c102_frame_t *f;
2865 unsigned long lock_flags;
2ffab02f 2866 long timeout;
f327ebbd 2867 int err = 0;
1da177e4 2868
a966f3e7
LR
2869 if (copy_from_user(&b, arg, sizeof(b)))
2870 return -EFAULT;
1da177e4 2871
a966f3e7
LR
2872 if (b.type != V4L2_BUF_TYPE_VIDEO_CAPTURE || cam->io != IO_MMAP)
2873 return -EINVAL;
2874
2875 if (list_empty(&cam->outqueue)) {
2876 if (cam->stream == STREAM_OFF)
2877 return -EINVAL;
2878 if (filp->f_flags & O_NONBLOCK)
2879 return -EAGAIN;
f327ebbd
LR
2880 if (!cam->module_param.frame_timeout) {
2881 err = wait_event_interruptible
2882 ( cam->wait_frame,
2883 (!list_empty(&cam->outqueue)) ||
2884 (cam->state & DEV_DISCONNECTED) ||
2885 (cam->state & DEV_MISCONFIGURED) );
2886 if (err)
2887 return err;
2888 } else {
f423b9a8
LR
2889 timeout = wait_event_interruptible_timeout
2890 ( cam->wait_frame,
2891 (!list_empty(&cam->outqueue)) ||
2892 (cam->state & DEV_DISCONNECTED) ||
2893 (cam->state & DEV_MISCONFIGURED),
2894 cam->module_param.frame_timeout *
2895 1000 * msecs_to_jiffies(1) );
2896 if (timeout < 0)
2897 return timeout;
f327ebbd
LR
2898 else if (timeout == 0 &&
2899 !(cam->state & DEV_DISCONNECTED)) {
2900 DBG(1, "Video frame timeout elapsed");
2901 return -EIO;
2902 }
2903 }
a966f3e7
LR
2904 if (cam->state & DEV_DISCONNECTED)
2905 return -ENODEV;
f327ebbd 2906 if (cam->state & DEV_MISCONFIGURED)
a966f3e7 2907 return -EIO;
1da177e4
LT
2908 }
2909
a966f3e7
LR
2910 spin_lock_irqsave(&cam->queue_lock, lock_flags);
2911 f = list_entry(cam->outqueue.next, struct sn9c102_frame_t, frame);
2912 list_del(cam->outqueue.next);
2913 spin_unlock_irqrestore(&cam->queue_lock, lock_flags);
1da177e4 2914
a966f3e7 2915 f->state = F_UNUSED;
1da177e4 2916
a966f3e7
LR
2917 memcpy(&b, &f->buf, sizeof(b));
2918 if (f->vma_use_count)
2919 b.flags |= V4L2_BUF_FLAG_MAPPED;
2920
2921 if (copy_to_user(arg, &b, sizeof(b)))
2922 return -EFAULT;
2923
2924 PDBGG("Frame #%lu dequeued", (unsigned long)f->buf.index);
2925
2926 return 0;
2927}
2928
2929
2930static int
2931sn9c102_vidioc_streamon(struct sn9c102_device* cam, void __user * arg)
2932{
2933 int type;
2934
2935 if (copy_from_user(&type, arg, sizeof(type)))
2936 return -EFAULT;
2937
2938 if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE || cam->io != IO_MMAP)
2939 return -EINVAL;
2940
a966f3e7
LR
2941 cam->stream = STREAM_ON;
2942
2943 DBG(3, "Stream on");
2944
2945 return 0;
2946}
2947
2948
2949static int
2950sn9c102_vidioc_streamoff(struct sn9c102_device* cam, void __user * arg)
2951{
2952 int type, err;
2953
2954 if (copy_from_user(&type, arg, sizeof(type)))
2955 return -EFAULT;
2956
2957 if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE || cam->io != IO_MMAP)
2958 return -EINVAL;
2959
2960 if (cam->stream == STREAM_ON)
2961 if ((err = sn9c102_stream_interrupt(cam)))
2962 return err;
2963
2964 sn9c102_empty_framequeues(cam);
2965
2966 DBG(3, "Stream off");
2967
2968 return 0;
2969}
2970
2971
2972static int
2973sn9c102_vidioc_g_parm(struct sn9c102_device* cam, void __user * arg)
2974{
2975 struct v4l2_streamparm sp;
2976
2977 if (copy_from_user(&sp, arg, sizeof(sp)))
2978 return -EFAULT;
2979
2980 if (sp.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
2981 return -EINVAL;
2982
2983 sp.parm.capture.extendedmode = 0;
2984 sp.parm.capture.readbuffers = cam->nreadbuffers;
2985
2986 if (copy_to_user(arg, &sp, sizeof(sp)))
2987 return -EFAULT;
2988
2989 return 0;
2990}
2991
2992
2993static int
2994sn9c102_vidioc_s_parm(struct sn9c102_device* cam, void __user * arg)
2995{
2996 struct v4l2_streamparm sp;
2997
2998 if (copy_from_user(&sp, arg, sizeof(sp)))
2999 return -EFAULT;
3000
3001 if (sp.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
3002 return -EINVAL;
3003
3004 sp.parm.capture.extendedmode = 0;
1da177e4 3005
a966f3e7 3006 if (sp.parm.capture.readbuffers == 0)
1da177e4
LT
3007 sp.parm.capture.readbuffers = cam->nreadbuffers;
3008
a966f3e7
LR
3009 if (sp.parm.capture.readbuffers > SN9C102_MAX_FRAMES)
3010 sp.parm.capture.readbuffers = SN9C102_MAX_FRAMES;
1da177e4 3011
a966f3e7
LR
3012 if (copy_to_user(arg, &sp, sizeof(sp)))
3013 return -EFAULT;
1da177e4 3014
a966f3e7 3015 cam->nreadbuffers = sp.parm.capture.readbuffers;
1da177e4 3016
a966f3e7
LR
3017 return 0;
3018}
1da177e4 3019
1da177e4 3020
f327ebbd
LR
3021static int
3022sn9c102_vidioc_enumaudio(struct sn9c102_device* cam, void __user * arg)
3023{
3024 struct v4l2_audio audio;
3025
3026 if (cam->bridge == BRIDGE_SN9C101 || cam->bridge == BRIDGE_SN9C102)
3027 return -EINVAL;
3028
3029 if (copy_from_user(&audio, arg, sizeof(audio)))
3030 return -EFAULT;
3031
3032 if (audio.index != 0)
3033 return -EINVAL;
3034
3035 strcpy(audio.name, "Microphone");
3036 audio.capability = 0;
3037 audio.mode = 0;
3038
3039 if (copy_to_user(arg, &audio, sizeof(audio)))
3040 return -EFAULT;
3041
3042 return 0;
3043}
3044
3045
3046static int
3047sn9c102_vidioc_g_audio(struct sn9c102_device* cam, void __user * arg)
3048{
3049 struct v4l2_audio audio;
3050
3051 if (cam->bridge == BRIDGE_SN9C101 || cam->bridge == BRIDGE_SN9C102)
3052 return -EINVAL;
3053
3054 if (copy_from_user(&audio, arg, sizeof(audio)))
3055 return -EFAULT;
3056
3057 memset(&audio, 0, sizeof(audio));
3058 strcpy(audio.name, "Microphone");
3059
3060 if (copy_to_user(arg, &audio, sizeof(audio)))
3061 return -EFAULT;
3062
3063 return 0;
3064}
3065
3066
3067static int
3068sn9c102_vidioc_s_audio(struct sn9c102_device* cam, void __user * arg)
3069{
3070 struct v4l2_audio audio;
3071
3072 if (cam->bridge == BRIDGE_SN9C101 || cam->bridge == BRIDGE_SN9C102)
3073 return -EINVAL;
3074
3075 if (copy_from_user(&audio, arg, sizeof(audio)))
3076 return -EFAULT;
3077
3078 if (audio.index != 0)
3079 return -EINVAL;
3080
3081 return 0;
3082}
3083
3084
a966f3e7 3085static int sn9c102_ioctl_v4l2(struct inode* inode, struct file* filp,
d56410e0 3086 unsigned int cmd, void __user * arg)
a966f3e7
LR
3087{
3088 struct sn9c102_device* cam = video_get_drvdata(video_devdata(filp));
1da177e4 3089
a966f3e7 3090 switch (cmd) {
1da177e4 3091
a966f3e7
LR
3092 case VIDIOC_QUERYCAP:
3093 return sn9c102_vidioc_querycap(cam, arg);
1da177e4 3094
a966f3e7
LR
3095 case VIDIOC_ENUMINPUT:
3096 return sn9c102_vidioc_enuminput(cam, arg);
1da177e4 3097
a966f3e7 3098 case VIDIOC_G_INPUT:
2ffab02f
LR
3099 return sn9c102_vidioc_g_input(cam, arg);
3100
a966f3e7 3101 case VIDIOC_S_INPUT:
2ffab02f 3102 return sn9c102_vidioc_s_input(cam, arg);
1da177e4 3103
a966f3e7
LR
3104 case VIDIOC_QUERYCTRL:
3105 return sn9c102_vidioc_query_ctrl(cam, arg);
3106
3107 case VIDIOC_G_CTRL:
3108 return sn9c102_vidioc_g_ctrl(cam, arg);
3109
a966f3e7
LR
3110 case VIDIOC_S_CTRL:
3111 return sn9c102_vidioc_s_ctrl(cam, arg);
3112
a966f3e7
LR
3113 case VIDIOC_CROPCAP:
3114 return sn9c102_vidioc_cropcap(cam, arg);
3115
3116 case VIDIOC_G_CROP:
3117 return sn9c102_vidioc_g_crop(cam, arg);
3118
3119 case VIDIOC_S_CROP:
3120 return sn9c102_vidioc_s_crop(cam, arg);
3121
f327ebbd
LR
3122 case VIDIOC_ENUM_FRAMESIZES:
3123 return sn9c102_vidioc_enum_framesizes(cam, arg);
3124
a966f3e7
LR
3125 case VIDIOC_ENUM_FMT:
3126 return sn9c102_vidioc_enum_fmt(cam, arg);
3127
3128 case VIDIOC_G_FMT:
3129 return sn9c102_vidioc_g_fmt(cam, arg);
3130
3131 case VIDIOC_TRY_FMT:
3132 case VIDIOC_S_FMT:
3133 return sn9c102_vidioc_try_s_fmt(cam, cmd, arg);
3134
3135 case VIDIOC_G_JPEGCOMP:
3136 return sn9c102_vidioc_g_jpegcomp(cam, arg);
3137
3138 case VIDIOC_S_JPEGCOMP:
3139 return sn9c102_vidioc_s_jpegcomp(cam, arg);
3140
3141 case VIDIOC_REQBUFS:
3142 return sn9c102_vidioc_reqbufs(cam, arg);
3143
3144 case VIDIOC_QUERYBUF:
3145 return sn9c102_vidioc_querybuf(cam, arg);
3146
3147 case VIDIOC_QBUF:
3148 return sn9c102_vidioc_qbuf(cam, arg);
3149
3150 case VIDIOC_DQBUF:
3151 return sn9c102_vidioc_dqbuf(cam, filp, arg);
3152
3153 case VIDIOC_STREAMON:
3154 return sn9c102_vidioc_streamon(cam, arg);
3155
3156 case VIDIOC_STREAMOFF:
3157 return sn9c102_vidioc_streamoff(cam, arg);
3158
3159 case VIDIOC_G_PARM:
3160 return sn9c102_vidioc_g_parm(cam, arg);
3161
a966f3e7
LR
3162 case VIDIOC_S_PARM:
3163 return sn9c102_vidioc_s_parm(cam, arg);
1da177e4 3164
f327ebbd
LR
3165 case VIDIOC_ENUMAUDIO:
3166 return sn9c102_vidioc_enumaudio(cam, arg);
3167
3168 case VIDIOC_G_AUDIO:
3169 return sn9c102_vidioc_g_audio(cam, arg);
3170
3171 case VIDIOC_S_AUDIO:
3172 return sn9c102_vidioc_s_audio(cam, arg);
3173
1da177e4
LT
3174 case VIDIOC_G_STD:
3175 case VIDIOC_S_STD:
3176 case VIDIOC_QUERYSTD:
3177 case VIDIOC_ENUMSTD:
3178 case VIDIOC_QUERYMENU:
f327ebbd 3179 case VIDIOC_ENUM_FRAMEINTERVALS:
1da177e4
LT
3180 return -EINVAL;
3181
3182 default:
3183 return -EINVAL;
3184
3185 }
3186}
3187
3188
3189static int sn9c102_ioctl(struct inode* inode, struct file* filp,
d56410e0 3190 unsigned int cmd, unsigned long arg)
1da177e4
LT
3191{
3192 struct sn9c102_device* cam = video_get_drvdata(video_devdata(filp));
3193 int err = 0;
3194
4186ecf8 3195 if (mutex_lock_interruptible(&cam->fileop_mutex))
1da177e4
LT
3196 return -ERESTARTSYS;
3197
3198 if (cam->state & DEV_DISCONNECTED) {
a966f3e7 3199 DBG(1, "Device not present");
4186ecf8 3200 mutex_unlock(&cam->fileop_mutex);
1da177e4
LT
3201 return -ENODEV;
3202 }
3203
3204 if (cam->state & DEV_MISCONFIGURED) {
a966f3e7
LR
3205 DBG(1, "The camera is misconfigured. Close and open it "
3206 "again.");
4186ecf8 3207 mutex_unlock(&cam->fileop_mutex);
1da177e4
LT
3208 return -EIO;
3209 }
3210
cd6fcc55
LR
3211 V4LDBG(3, "sn9c102", cmd);
3212
1da177e4
LT
3213 err = sn9c102_ioctl_v4l2(inode, filp, cmd, (void __user *)arg);
3214
4186ecf8 3215 mutex_unlock(&cam->fileop_mutex);
1da177e4
LT
3216
3217 return err;
3218}
3219
a966f3e7 3220/*****************************************************************************/
1da177e4 3221
fa027c2a 3222static const struct file_operations sn9c102_fops = {
a966f3e7 3223 .owner = THIS_MODULE,
480b55c2 3224 .open = sn9c102_open,
1da177e4 3225 .release = sn9c102_release,
480b55c2 3226 .ioctl = sn9c102_ioctl,
078ff795 3227#ifdef CONFIG_COMPAT
f327ebbd 3228 .compat_ioctl = v4l_compat_ioctl32,
078ff795 3229#endif
480b55c2
LR
3230 .read = sn9c102_read,
3231 .poll = sn9c102_poll,
3232 .mmap = sn9c102_mmap,
3233 .llseek = no_llseek,
1da177e4
LT
3234};
3235
3236/*****************************************************************************/
3237
3238/* It exists a single interface only. We do not need to validate anything. */
3239static int
3240sn9c102_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
3241{
3242 struct usb_device *udev = interface_to_usbdev(intf);
3243 struct sn9c102_device* cam;
ff699e6b 3244 static unsigned int dev_nr;
a966f3e7 3245 unsigned int i;
1da177e4
LT
3246 int err = 0, r;
3247
cd6fcc55 3248 if (!(cam = kzalloc(sizeof(struct sn9c102_device), GFP_KERNEL)))
1da177e4 3249 return -ENOMEM;
1da177e4
LT
3250
3251 cam->usbdev = udev;
1da177e4 3252
cd6fcc55 3253 if (!(cam->control_buffer = kzalloc(8, GFP_KERNEL))) {
f327ebbd 3254 DBG(1, "kzalloc() failed");
1da177e4
LT
3255 err = -ENOMEM;
3256 goto fail;
3257 }
1da177e4
LT
3258
3259 if (!(cam->v4ldev = video_device_alloc())) {
a966f3e7 3260 DBG(1, "video_device_alloc() failed");
1da177e4
LT
3261 err = -ENOMEM;
3262 goto fail;
3263 }
3264
1da177e4 3265 r = sn9c102_read_reg(cam, 0x00);
f327ebbd 3266 if (r < 0 || (r != 0x10 && r != 0x11 && r != 0x12)) {
f423b9a8
LR
3267 DBG(1, "Sorry, this is not a SN9C1xx-based camera "
3268 "(vid:pid 0x%04X:0x%04X)", id->idVendor, id->idProduct);
1da177e4
LT
3269 err = -ENODEV;
3270 goto fail;
3271 }
3272
f327ebbd 3273 cam->bridge = id->driver_info;
1da177e4
LT
3274 switch (cam->bridge) {
3275 case BRIDGE_SN9C101:
3276 case BRIDGE_SN9C102:
3277 DBG(2, "SN9C10[12] PC Camera Controller detected "
f423b9a8 3278 "(vid:pid 0x%04X:0x%04X)", id->idVendor, id->idProduct);
1da177e4
LT
3279 break;
3280 case BRIDGE_SN9C103:
3281 DBG(2, "SN9C103 PC Camera Controller detected "
f423b9a8 3282 "(vid:pid 0x%04X:0x%04X)", id->idVendor, id->idProduct);
f327ebbd
LR
3283 break;
3284 case BRIDGE_SN9C105:
3285 DBG(2, "SN9C105 PC Camera Controller detected "
f423b9a8 3286 "(vid:pid 0x%04X:0x%04X)", id->idVendor, id->idProduct);
f327ebbd
LR
3287 break;
3288 case BRIDGE_SN9C120:
3289 DBG(2, "SN9C120 PC Camera Controller detected "
f423b9a8 3290 "(vid:pid 0x%04X:0x%04X)", id->idVendor, id->idProduct);
1da177e4
LT
3291 break;
3292 }
3293
480b55c2 3294 for (i = 0; i < ARRAY_SIZE(sn9c102_sensor_table); i++) {
1da177e4
LT
3295 err = sn9c102_sensor_table[i](cam);
3296 if (!err)
3297 break;
3298 }
3299
2ffab02f
LR
3300 if (!err) {
3301 DBG(2, "%s image sensor detected", cam->sensor.name);
1da177e4 3302 DBG(3, "Support for %s maintained by %s",
2ffab02f 3303 cam->sensor.name, cam->sensor.maintainer);
1da177e4 3304 } else {
480b55c2 3305 DBG(1, "No supported image sensor detected for this bridge");
1da177e4
LT
3306 err = -ENODEV;
3307 goto fail;
3308 }
3309
f327ebbd
LR
3310 if (!(cam->bridge & cam->sensor.supported_bridge)) {
3311 DBG(1, "Bridge not supported");
3312 err = -ENODEV;
3313 goto fail;
3314 }
3315
1da177e4 3316 if (sn9c102_init(cam)) {
a966f3e7 3317 DBG(1, "Initialization failed. I will retry on open().");
1da177e4
LT
3318 cam->state |= DEV_MISCONFIGURED;
3319 }
3320
f327ebbd 3321 strcpy(cam->v4ldev->name, "SN9C1xx PC Camera");
1da177e4
LT
3322 cam->v4ldev->owner = THIS_MODULE;
3323 cam->v4ldev->type = VID_TYPE_CAPTURE | VID_TYPE_SCALES;
1da177e4
LT
3324 cam->v4ldev->fops = &sn9c102_fops;
3325 cam->v4ldev->minor = video_nr[dev_nr];
3326 cam->v4ldev->release = video_device_release;
1da177e4 3327
3770be34 3328 init_completion(&cam->probe);
1da177e4
LT
3329
3330 err = video_register_device(cam->v4ldev, VFL_TYPE_GRABBER,
d56410e0 3331 video_nr[dev_nr]);
1da177e4 3332 if (err) {
a966f3e7 3333 DBG(1, "V4L2 device registration failed");
1da177e4 3334 if (err == -ENFILE && video_nr[dev_nr] == -1)
a966f3e7 3335 DBG(1, "Free /dev/videoX node not found");
f327ebbd
LR
3336 video_nr[dev_nr] = -1;
3337 dev_nr = (dev_nr < SN9C102_MAX_DEVICES-1) ? dev_nr+1 : 0;
3770be34 3338 complete_all(&cam->probe);
f327ebbd 3339 goto fail;
1da177e4
LT
3340 }
3341
a966f3e7 3342 DBG(2, "V4L2 device registered as /dev/video%d", cam->v4ldev->minor);
1da177e4 3343
ddef2dcc 3344 video_set_drvdata(cam->v4ldev, cam);
1da177e4 3345 cam->module_param.force_munmap = force_munmap[dev_nr];
2ffab02f 3346 cam->module_param.frame_timeout = frame_timeout[dev_nr];
1da177e4
LT
3347
3348 dev_nr = (dev_nr < SN9C102_MAX_DEVICES-1) ? dev_nr+1 : 0;
3349
cd6fcc55 3350#ifdef CONFIG_VIDEO_ADV_DEBUG
c12e3be0 3351 err = sn9c102_create_sysfs(cam);
f327ebbd
LR
3352 if (!err)
3353 DBG(2, "Optional device control through 'sysfs' "
3354 "interface ready");
3355 else
3356 DBG(2, "Failed to create optional 'sysfs' interface for "
3357 "device controlling. Error #%d", err);
3358#else
3359 DBG(2, "Optional device control through 'sysfs' interface disabled");
f423b9a8
LR
3360 DBG(3, "Compile the kernel with the 'CONFIG_VIDEO_ADV_DEBUG' "
3361 "configuration option to enable it.");
cd6fcc55 3362#endif
1da177e4
LT
3363
3364 usb_set_intfdata(intf, cam);
3770be34
LR
3365 kref_init(&cam->kref);
3366 usb_get_dev(cam->usbdev);
1da177e4 3367
3770be34 3368 complete_all(&cam->probe);
1da177e4
LT
3369
3370 return 0;
3371
3372fail:
3373 if (cam) {
3374 kfree(cam->control_buffer);
3375 if (cam->v4ldev)
3376 video_device_release(cam->v4ldev);
3377 kfree(cam);
3378 }
3379 return err;
3380}
3381
3382
3383static void sn9c102_usb_disconnect(struct usb_interface* intf)
3384{
3770be34 3385 struct sn9c102_device* cam;
1da177e4 3386
3770be34 3387 down_write(&sn9c102_dev_lock);
1da177e4 3388
3770be34 3389 cam = usb_get_intfdata(intf);
1da177e4 3390
a966f3e7 3391 DBG(2, "Disconnecting %s...", cam->v4ldev->name);
1da177e4 3392
1da177e4
LT
3393 if (cam->users) {
3394 DBG(2, "Device /dev/video%d is open! Deregistration and "
3770be34 3395 "memory deallocation are deferred.",
a966f3e7 3396 cam->v4ldev->minor);
1da177e4
LT
3397 cam->state |= DEV_MISCONFIGURED;
3398 sn9c102_stop_transfer(cam);
3399 cam->state |= DEV_DISCONNECTED;
3400 wake_up_interruptible(&cam->wait_frame);
2ffab02f 3401 wake_up(&cam->wait_stream);
3770be34 3402 } else
1da177e4 3403 cam->state |= DEV_DISCONNECTED;
1da177e4 3404
3770be34 3405 wake_up_interruptible_all(&cam->wait_open);
1da177e4 3406
3770be34 3407 kref_put(&cam->kref, sn9c102_release_resources);
1da177e4 3408
3770be34 3409 up_write(&sn9c102_dev_lock);
1da177e4
LT
3410}
3411
3412
3413static struct usb_driver sn9c102_usb_driver = {
1da177e4
LT
3414 .name = "sn9c102",
3415 .id_table = sn9c102_id_table,
3416 .probe = sn9c102_usb_probe,
3417 .disconnect = sn9c102_usb_disconnect,
3418};
3419
3420/*****************************************************************************/
3421
3422static int __init sn9c102_module_init(void)
3423{
3424 int err = 0;
3425
a966f3e7
LR
3426 KDBG(2, SN9C102_MODULE_NAME " v" SN9C102_MODULE_VERSION);
3427 KDBG(3, SN9C102_MODULE_AUTHOR);
1da177e4
LT
3428
3429 if ((err = usb_register(&sn9c102_usb_driver)))
a966f3e7 3430 KDBG(1, "usb_register() failed");
1da177e4
LT
3431
3432 return err;
3433}
3434
3435
3436static void __exit sn9c102_module_exit(void)
3437{
3438 usb_deregister(&sn9c102_usb_driver);
3439}
3440
3441
3442module_init(sn9c102_module_init);
3443module_exit(sn9c102_module_exit);
This page took 0.683649 seconds and 5 git commands to generate.