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