aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/media
diff options
context:
space:
mode:
authorDave Kleikamp <shaggy@austin.ibm.com>2006-03-14 18:05:45 -0500
committerDave Kleikamp <shaggy@austin.ibm.com>2006-03-14 18:05:45 -0500
commitc5111f504d2a9b0d258d7c4752b4093523315989 (patch)
tree6a52864aff79691689aea21cb0cb928327d5de5b /drivers/usb/media
parent69eb66d7da7dba2696281981347698e1693c2340 (diff)
parenta488edc914aa1d766a4e2c982b5ae03d5657ec1b (diff)
Merge with /home/shaggy/git/linus-clean/
Diffstat (limited to 'drivers/usb/media')
-rw-r--r--drivers/usb/media/Kconfig17
-rw-r--r--drivers/usb/media/Makefile2
-rw-r--r--drivers/usb/media/et61x251.h220
-rw-r--r--drivers/usb/media/et61x251_core.c2605
-rw-r--r--drivers/usb/media/et61x251_sensor.h115
-rw-r--r--drivers/usb/media/et61x251_tas5130d1b.c137
-rw-r--r--drivers/usb/media/ov511.c196
-rw-r--r--drivers/usb/media/pwc/pwc-ctrl.c264
-rw-r--r--drivers/usb/media/sn9c102.h50
-rw-r--r--drivers/usb/media/sn9c102_core.c1681
-rw-r--r--drivers/usb/media/sn9c102_hv7131d.c2
-rw-r--r--drivers/usb/media/sn9c102_mi0343.c2
-rw-r--r--drivers/usb/media/sn9c102_ov7630.c8
-rw-r--r--drivers/usb/media/sn9c102_pas106b.c2
-rw-r--r--drivers/usb/media/sn9c102_sensor.h85
-rw-r--r--drivers/usb/media/sn9c102_tas5110c1b.c2
-rw-r--r--drivers/usb/media/sn9c102_tas5130d1b.c2
-rw-r--r--drivers/usb/media/w9968cf.c128
-rw-r--r--drivers/usb/media/w9968cf.h1
-rw-r--r--drivers/usb/media/w9968cf_vpp.h3
20 files changed, 4181 insertions, 1341 deletions
diff --git a/drivers/usb/media/Kconfig b/drivers/usb/media/Kconfig
index 21232ee2974c..0d3d2cc5d7be 100644
--- a/drivers/usb/media/Kconfig
+++ b/drivers/usb/media/Kconfig
@@ -53,6 +53,21 @@ config USB_DSBR
53 To compile this driver as a module, choose M here: the 53 To compile this driver as a module, choose M here: the
54 module will be called dsbr100. 54 module will be called dsbr100.
55 55
56config USB_ET61X251
57 tristate "USB ET61X[12]51 PC Camera Controller support"
58 depends on USB && VIDEO_DEV
59 ---help---
60 Say Y here if you want support for cameras based on Etoms ET61X151
61 or ET61X251 PC Camera Controllers.
62
63 See <file:Documentation/usb/et61x251.txt> for more informations.
64
65 This driver uses the Video For Linux API. You must say Y or M to
66 "Video For Linux" to use this driver.
67
68 To compile this driver as a module, choose M here: the
69 module will be called et61x251.
70
56config USB_IBMCAM 71config USB_IBMCAM
57 tristate "USB IBM (Xirlink) C-it Camera support" 72 tristate "USB IBM (Xirlink) C-it Camera support"
58 depends on USB && VIDEO_DEV 73 depends on USB && VIDEO_DEV
@@ -209,5 +224,3 @@ config USB_PWC
209 224
210 To compile this driver as a module, choose M here: the 225 To compile this driver as a module, choose M here: the
211 module will be called pwc. 226 module will be called pwc.
212
213
diff --git a/drivers/usb/media/Makefile b/drivers/usb/media/Makefile
index d83adffa925f..3957aa1be0f2 100644
--- a/drivers/usb/media/Makefile
+++ b/drivers/usb/media/Makefile
@@ -3,9 +3,11 @@
3# 3#
4 4
5sn9c102-objs := sn9c102_core.o sn9c102_hv7131d.o sn9c102_mi0343.o sn9c102_ov7630.o sn9c102_pas106b.o sn9c102_pas202bcb.o sn9c102_tas5110c1b.o sn9c102_tas5130d1b.o 5sn9c102-objs := sn9c102_core.o sn9c102_hv7131d.o sn9c102_mi0343.o sn9c102_ov7630.o sn9c102_pas106b.o sn9c102_pas202bcb.o sn9c102_tas5110c1b.o sn9c102_tas5130d1b.o
6et61x251-objs := et61x251_core.o et61x251_tas5130d1b.o
6 7
7obj-$(CONFIG_USB_DABUSB) += dabusb.o 8obj-$(CONFIG_USB_DABUSB) += dabusb.o
8obj-$(CONFIG_USB_DSBR) += dsbr100.o 9obj-$(CONFIG_USB_DSBR) += dsbr100.o
10obj-$(CONFIG_USB_ET61X251) += et61x251.o
9obj-$(CONFIG_USB_IBMCAM) += ibmcam.o usbvideo.o ultracam.o 11obj-$(CONFIG_USB_IBMCAM) += ibmcam.o usbvideo.o ultracam.o
10obj-$(CONFIG_USB_KONICAWC) += konicawc.o usbvideo.o 12obj-$(CONFIG_USB_KONICAWC) += konicawc.o usbvideo.o
11obj-$(CONFIG_USB_OV511) += ov511.o 13obj-$(CONFIG_USB_OV511) += ov511.o
diff --git a/drivers/usb/media/et61x251.h b/drivers/usb/media/et61x251.h
new file mode 100644
index 000000000000..652238f329f3
--- /dev/null
+++ b/drivers/usb/media/et61x251.h
@@ -0,0 +1,220 @@
1/***************************************************************************
2 * V4L2 driver for ET61X[12]51 PC Camera Controllers *
3 * *
4 * Copyright (C) 2006 by Luca Risolia <luca.risolia@studio.unibo.it> *
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#ifndef _ET61X251_H_
22#define _ET61X251_H_
23
24#include <linux/version.h>
25#include <linux/usb.h>
26#include <linux/videodev2.h>
27#include <media/v4l2-common.h>
28#include <linux/device.h>
29#include <linux/list.h>
30#include <linux/spinlock.h>
31#include <linux/time.h>
32#include <linux/wait.h>
33#include <linux/types.h>
34#include <linux/param.h>
35#include <linux/rwsem.h>
36#include <asm/semaphore.h>
37
38#include "et61x251_sensor.h"
39
40/*****************************************************************************/
41
42#define ET61X251_DEBUG
43#define ET61X251_DEBUG_LEVEL 2
44#define ET61X251_MAX_DEVICES 64
45#define ET61X251_PRESERVE_IMGSCALE 0
46#define ET61X251_FORCE_MUNMAP 0
47#define ET61X251_MAX_FRAMES 32
48#define ET61X251_COMPRESSION_QUALITY 0
49#define ET61X251_URBS 2
50#define ET61X251_ISO_PACKETS 7
51#define ET61X251_ALTERNATE_SETTING 13
52#define ET61X251_URB_TIMEOUT msecs_to_jiffies(2 * ET61X251_ISO_PACKETS)
53#define ET61X251_CTRL_TIMEOUT 100
54
55/*****************************************************************************/
56
57static const struct usb_device_id et61x251_id_table[] = {
58 { USB_DEVICE(0x102c, 0x6151), },
59 { USB_DEVICE(0x102c, 0x6251), },
60 { USB_DEVICE(0x102c, 0x6253), },
61 { USB_DEVICE(0x102c, 0x6254), },
62 { USB_DEVICE(0x102c, 0x6255), },
63 { USB_DEVICE(0x102c, 0x6256), },
64 { USB_DEVICE(0x102c, 0x6257), },
65 { USB_DEVICE(0x102c, 0x6258), },
66 { USB_DEVICE(0x102c, 0x6259), },
67 { USB_DEVICE(0x102c, 0x625a), },
68 { USB_DEVICE(0x102c, 0x625b), },
69 { USB_DEVICE(0x102c, 0x625c), },
70 { USB_DEVICE(0x102c, 0x625d), },
71 { USB_DEVICE(0x102c, 0x625e), },
72 { USB_DEVICE(0x102c, 0x625f), },
73 { USB_DEVICE(0x102c, 0x6260), },
74 { USB_DEVICE(0x102c, 0x6261), },
75 { USB_DEVICE(0x102c, 0x6262), },
76 { USB_DEVICE(0x102c, 0x6263), },
77 { USB_DEVICE(0x102c, 0x6264), },
78 { USB_DEVICE(0x102c, 0x6265), },
79 { USB_DEVICE(0x102c, 0x6266), },
80 { USB_DEVICE(0x102c, 0x6267), },
81 { USB_DEVICE(0x102c, 0x6268), },
82 { USB_DEVICE(0x102c, 0x6269), },
83 { }
84};
85
86ET61X251_SENSOR_TABLE
87
88/*****************************************************************************/
89
90enum et61x251_frame_state {
91 F_UNUSED,
92 F_QUEUED,
93 F_GRABBING,
94 F_DONE,
95 F_ERROR,
96};
97
98struct et61x251_frame_t {
99 void* bufmem;
100 struct v4l2_buffer buf;
101 enum et61x251_frame_state state;
102 struct list_head frame;
103 unsigned long vma_use_count;
104};
105
106enum et61x251_dev_state {
107 DEV_INITIALIZED = 0x01,
108 DEV_DISCONNECTED = 0x02,
109 DEV_MISCONFIGURED = 0x04,
110};
111
112enum et61x251_io_method {
113 IO_NONE,
114 IO_READ,
115 IO_MMAP,
116};
117
118enum et61x251_stream_state {
119 STREAM_OFF,
120 STREAM_INTERRUPT,
121 STREAM_ON,
122};
123
124struct et61x251_sysfs_attr {
125 u8 reg, i2c_reg;
126};
127
128struct et61x251_module_param {
129 u8 force_munmap;
130};
131
132static DECLARE_MUTEX(et61x251_sysfs_lock);
133static DECLARE_RWSEM(et61x251_disconnect);
134
135struct et61x251_device {
136 struct video_device* v4ldev;
137
138 struct et61x251_sensor* sensor;
139
140 struct usb_device* usbdev;
141 struct urb* urb[ET61X251_URBS];
142 void* transfer_buffer[ET61X251_URBS];
143 u8* control_buffer;
144
145 struct et61x251_frame_t *frame_current, frame[ET61X251_MAX_FRAMES];
146 struct list_head inqueue, outqueue;
147 u32 frame_count, nbuffers, nreadbuffers;
148
149 enum et61x251_io_method io;
150 enum et61x251_stream_state stream;
151
152 struct v4l2_jpegcompression compression;
153
154 struct et61x251_sysfs_attr sysfs;
155 struct et61x251_module_param module_param;
156
157 enum et61x251_dev_state state;
158 u8 users;
159
160 struct semaphore dev_sem, fileop_sem;
161 spinlock_t queue_lock;
162 wait_queue_head_t open, wait_frame, wait_stream;
163};
164
165/*****************************************************************************/
166
167void
168et61x251_attach_sensor(struct et61x251_device* cam,
169 struct et61x251_sensor* sensor)
170{
171 cam->sensor = sensor;
172 cam->sensor->usbdev = cam->usbdev;
173}
174
175/*****************************************************************************/
176
177#undef DBG
178#undef KDBG
179#ifdef ET61X251_DEBUG
180# define DBG(level, fmt, args...) \
181do { \
182 if (debug >= (level)) { \
183 if ((level) == 1) \
184 dev_err(&cam->usbdev->dev, fmt "\n", ## args); \
185 else if ((level) == 2) \
186 dev_info(&cam->usbdev->dev, fmt "\n", ## args); \
187 else if ((level) >= 3) \
188 dev_info(&cam->usbdev->dev, "[%s:%d] " fmt "\n", \
189 __FUNCTION__, __LINE__ , ## args); \
190 } \
191} while (0)
192# define KDBG(level, fmt, args...) \
193do { \
194 if (debug >= (level)) { \
195 if ((level) == 1 || (level) == 2) \
196 pr_info("et61x251: " fmt "\n", ## args); \
197 else if ((level) == 3) \
198 pr_debug("et61x251: [%s:%d] " fmt "\n", __FUNCTION__, \
199 __LINE__ , ## args); \
200 } \
201} while (0)
202# define V4LDBG(level, name, cmd) \
203do { \
204 if (debug >= (level)) \
205 v4l_print_ioctl(name, cmd); \
206} while (0)
207#else
208# define DBG(level, fmt, args...) do {;} while(0)
209# define KDBG(level, fmt, args...) do {;} while(0)
210# define V4LDBG(level, name, cmd) do {;} while(0)
211#endif
212
213#undef PDBG
214#define PDBG(fmt, args...) \
215dev_info(&cam->dev, "[%s:%d] " fmt "\n", __FUNCTION__, __LINE__ , ## args)
216
217#undef PDBGG
218#define PDBGG(fmt, args...) do {;} while(0) /* placeholder */
219
220#endif /* _ET61X251_H_ */
diff --git a/drivers/usb/media/et61x251_core.c b/drivers/usb/media/et61x251_core.c
new file mode 100644
index 000000000000..2c0171a5ad62
--- /dev/null
+++ b/drivers/usb/media/et61x251_core.c
@@ -0,0 +1,2605 @@
1/***************************************************************************
2 * V4L2 driver for ET61X[12]51 PC Camera Controllers *
3 * *
4 * Copyright (C) 2006 by Luca Risolia <luca.risolia@studio.unibo.it> *
5 * *
6 * This program is free software; you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by *
8 * the Free Software Foundation; either version 2 of the License, or *
9 * (at your option) any later version. *
10 * *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
15 * *
16 * You should have received a copy of the GNU General Public License *
17 * along with this program; if not, write to the Free Software *
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
19 ***************************************************************************/
20
21#include <linux/module.h>
22#include <linux/init.h>
23#include <linux/kernel.h>
24#include <linux/param.h>
25#include <linux/moduleparam.h>
26#include <linux/errno.h>
27#include <linux/slab.h>
28#include <linux/string.h>
29#include <linux/device.h>
30#include <linux/fs.h>
31#include <linux/delay.h>
32#include <linux/stddef.h>
33#include <linux/compiler.h>
34#include <linux/ioctl.h>
35#include <linux/poll.h>
36#include <linux/stat.h>
37#include <linux/mm.h>
38#include <linux/vmalloc.h>
39#include <linux/page-flags.h>
40#include <linux/byteorder/generic.h>
41#include <asm/page.h>
42#include <asm/uaccess.h>
43
44#include "et61x251.h"
45
46/*****************************************************************************/
47
48#define ET61X251_MODULE_NAME "V4L2 driver for ET61X[12]51 " \
49 "PC Camera Controllers"
50#define ET61X251_MODULE_AUTHOR "(C) 2006 Luca Risolia"
51#define ET61X251_AUTHOR_EMAIL "<luca.risolia@studio.unibo.it>"
52#define ET61X251_MODULE_LICENSE "GPL"
53#define ET61X251_MODULE_VERSION "1:1.01"
54#define ET61X251_MODULE_VERSION_CODE KERNEL_VERSION(1, 0, 1)
55
56/*****************************************************************************/
57
58MODULE_DEVICE_TABLE(usb, et61x251_id_table);
59
60MODULE_AUTHOR(ET61X251_MODULE_AUTHOR " " ET61X251_AUTHOR_EMAIL);
61MODULE_DESCRIPTION(ET61X251_MODULE_NAME);
62MODULE_VERSION(ET61X251_MODULE_VERSION);
63MODULE_LICENSE(ET61X251_MODULE_LICENSE);
64
65static short video_nr[] = {[0 ... ET61X251_MAX_DEVICES-1] = -1};
66module_param_array(video_nr, short, NULL, 0444);
67MODULE_PARM_DESC(video_nr,
68 "\n<-1|n[,...]> Specify V4L2 minor mode number."
69 "\n -1 = use next available (default)"
70 "\n n = use minor number n (integer >= 0)"
71 "\nYou can specify up to "
72 __MODULE_STRING(ET61X251_MAX_DEVICES) " cameras this way."
73 "\nFor example:"
74 "\nvideo_nr=-1,2,-1 would assign minor number 2 to"
75 "\nthe second registered camera and use auto for the first"
76 "\none and for every other camera."
77 "\n");
78
79static short force_munmap[] = {[0 ... ET61X251_MAX_DEVICES-1] =
80 ET61X251_FORCE_MUNMAP};
81module_param_array(force_munmap, bool, NULL, 0444);
82MODULE_PARM_DESC(force_munmap,
83 "\n<0|1[,...]> Force the application to unmap previously"
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."
88 "\n 0 = do not force memory unmapping"
89 "\n 1 = force memory unmapping (save memory)"
90 "\nDefault value is "__MODULE_STRING(SN9C102_FORCE_MUNMAP)"."
91 "\n");
92
93#ifdef ET61X251_DEBUG
94static unsigned short debug = ET61X251_DEBUG_LEVEL;
95module_param(debug, ushort, 0644);
96MODULE_PARM_DESC(debug,
97 "\n<n> Debugging information level, from 0 to 3:"
98 "\n0 = none (use carefully)"
99 "\n1 = critical errors"
100 "\n2 = significant informations"
101 "\n3 = more verbose messages"
102 "\nLevel 3 is useful for testing only, when only "
103 "one device is used."
104 "\nDefault value is "__MODULE_STRING(ET61X251_DEBUG_LEVEL)"."
105 "\n");
106#endif
107
108/*****************************************************************************/
109
110static u32
111et61x251_request_buffers(struct et61x251_device* cam, u32 count,
112 enum et61x251_io_method io)
113{
114 struct v4l2_pix_format* p = &(cam->sensor->pix_format);
115 struct v4l2_rect* r = &(cam->sensor->cropcap.bounds);
116 const size_t imagesize = cam->module_param.force_munmap ||
117 io == IO_READ ?
118 (p->width * p->height * p->priv) / 8 :
119 (r->width * r->height * p->priv) / 8;
120 void* buff = NULL;
121 u32 i;
122
123 if (count > ET61X251_MAX_FRAMES)
124 count = ET61X251_MAX_FRAMES;
125
126 cam->nbuffers = count;
127 while (cam->nbuffers > 0) {
128 if ((buff = vmalloc_32(cam->nbuffers * PAGE_ALIGN(imagesize))))
129 break;
130 cam->nbuffers--;
131 }
132
133 for (i = 0; i < cam->nbuffers; i++) {
134 cam->frame[i].bufmem = buff + i*PAGE_ALIGN(imagesize);
135 cam->frame[i].buf.index = i;
136 cam->frame[i].buf.m.offset = i*PAGE_ALIGN(imagesize);
137 cam->frame[i].buf.length = imagesize;
138 cam->frame[i].buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
139 cam->frame[i].buf.sequence = 0;
140 cam->frame[i].buf.field = V4L2_FIELD_NONE;
141 cam->frame[i].buf.memory = V4L2_MEMORY_MMAP;
142 cam->frame[i].buf.flags = 0;
143 }
144
145 return cam->nbuffers;
146}
147
148
149static void et61x251_release_buffers(struct et61x251_device* cam)
150{
151 if (cam->nbuffers) {
152 vfree(cam->frame[0].bufmem);
153 cam->nbuffers = 0;
154 }
155 cam->frame_current = NULL;
156}
157
158
159static void et61x251_empty_framequeues(struct et61x251_device* cam)
160{
161 u32 i;
162
163 INIT_LIST_HEAD(&cam->inqueue);
164 INIT_LIST_HEAD(&cam->outqueue);
165
166 for (i = 0; i < ET61X251_MAX_FRAMES; i++) {
167 cam->frame[i].state = F_UNUSED;
168 cam->frame[i].buf.bytesused = 0;
169 }
170}
171
172
173static void et61x251_requeue_outqueue(struct et61x251_device* cam)
174{
175 struct et61x251_frame_t *i;
176
177 list_for_each_entry(i, &cam->outqueue, frame) {
178 i->state = F_QUEUED;
179 list_add(&i->frame, &cam->inqueue);
180 }
181
182 INIT_LIST_HEAD(&cam->outqueue);
183}
184
185
186static void et61x251_queue_unusedframes(struct et61x251_device* cam)
187{
188 unsigned long lock_flags;
189 u32 i;
190
191 for (i = 0; i < cam->nbuffers; i++)
192 if (cam->frame[i].state == F_UNUSED) {
193 cam->frame[i].state = F_QUEUED;
194 spin_lock_irqsave(&cam->queue_lock, lock_flags);
195 list_add_tail(&cam->frame[i].frame, &cam->inqueue);
196 spin_unlock_irqrestore(&cam->queue_lock, lock_flags);
197 }
198}
199
200/*****************************************************************************/
201
202int et61x251_write_reg(struct et61x251_device* cam, u8 value, u16 index)
203{
204 struct usb_device* udev = cam->usbdev;
205 u8* buff = cam->control_buffer;
206 int res;
207
208 *buff = value;
209
210 res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x00, 0x41,
211 0, index, buff, 1, ET61X251_CTRL_TIMEOUT);
212 if (res < 0) {
213 DBG(3, "Failed to write a register (value 0x%02X, index "
214 "0x%02X, error %d)", value, index, res);
215 return -1;
216 }
217
218 return 0;
219}
220
221
222int et61x251_read_reg(struct et61x251_device* cam, u16 index)
223{
224 struct usb_device* udev = cam->usbdev;
225 u8* buff = cam->control_buffer;
226 int res;
227
228 res = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x00, 0xc1,
229 0, index, buff, 1, ET61X251_CTRL_TIMEOUT);
230 if (res < 0)
231 DBG(3, "Failed to read a register (index 0x%02X, error %d)",
232 index, res);
233
234 return (res >= 0) ? (int)(*buff) : -1;
235}
236
237
238static int
239et61x251_i2c_wait(struct et61x251_device* cam, struct et61x251_sensor* sensor)
240{
241 int i, r;
242
243 for (i = 1; i <= 8; i++) {
244 if (sensor->interface == ET61X251_I2C_3WIRES) {
245 r = et61x251_read_reg(cam, 0x8e);
246 if (!(r & 0x02) && (r >= 0))
247 return 0;
248 } else {
249 r = et61x251_read_reg(cam, 0x8b);
250 if (!(r & 0x01) && (r >= 0))
251 return 0;
252 }
253 if (r < 0)
254 return -EIO;
255 udelay(8*8); /* minimum for sensors at 400kHz */
256 }
257
258 return -EBUSY;
259}
260
261
262int
263et61x251_i2c_try_read(struct et61x251_device* cam,
264 struct et61x251_sensor* sensor, u8 address)
265{
266 struct usb_device* udev = cam->usbdev;
267 u8* data = cam->control_buffer;
268 int err = 0, res;
269
270 data[0] = address;
271 data[1] = cam->sensor->i2c_slave_id;
272 data[2] = cam->sensor->rsta | 0x10;
273 data[3] = !(et61x251_read_reg(cam, 0x8b) & 0x02);
274 res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x00, 0x41,
275 0, 0x88, data, 4, ET61X251_CTRL_TIMEOUT);
276 if (res < 0)
277 err += res;
278
279 err += et61x251_i2c_wait(cam, sensor);
280
281 res = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x00, 0xc1,
282 0, 0x80, data, 8, ET61X251_CTRL_TIMEOUT);
283 if (res < 0)
284 err += res;
285
286 if (err)
287 DBG(3, "I2C read failed for %s image sensor", sensor->name);
288
289 PDBGG("I2C read: address 0x%02X, value: 0x%02X", address, data[0]);
290
291 return err ? -1 : (int)data[0];
292}
293
294
295int
296et61x251_i2c_try_write(struct et61x251_device* cam,
297 struct et61x251_sensor* sensor, u8 address, u8 value)
298{
299 struct usb_device* udev = cam->usbdev;
300 u8* data = cam->control_buffer;
301 int err = 0, res;
302
303 data[0] = address;
304 data[1] = cam->sensor->i2c_slave_id;
305 data[2] = cam->sensor->rsta | 0x12;
306 res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x00, 0x41,
307 0, 0x88, data, 3, ET61X251_CTRL_TIMEOUT);
308 if (res < 0)
309 err += res;
310
311 data[0] = value;
312 res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x00, 0x41,
313 0, 0x80, data, 1, ET61X251_CTRL_TIMEOUT);
314 if (res < 0)
315 err += res;
316
317 err += et61x251_i2c_wait(cam, sensor);
318
319 if (err)
320 DBG(3, "I2C write failed for %s image sensor", sensor->name);
321
322 PDBGG("I2C write: address 0x%02X, value: 0x%02X", address, value);
323
324 return err ? -1 : 0;
325}
326
327
328int
329et61x251_i2c_raw_write(struct et61x251_device* cam, u8 n, u8 data1, u8 data2,
330 u8 data3, u8 data4, u8 data5, u8 data6, u8 data7,
331 u8 data8, u8 address)
332{
333 struct usb_device* udev = cam->usbdev;
334 u8* data = cam->control_buffer;
335 int err = 0, res;
336
337 if (!cam->sensor)
338 return -1;
339
340 data[0] = data2;
341 data[1] = data3;
342 data[2] = data4;
343 data[3] = data5;
344 data[4] = data6;
345 data[5] = data7;
346 data[6] = data8;
347 res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x00, 0x41,
348 0, 0x81, data, n-1, ET61X251_CTRL_TIMEOUT);
349 if (res < 0)
350 err += res;
351
352 data[0] = address;
353 data[1] = cam->sensor->i2c_slave_id;
354 data[2] = cam->sensor->rsta | 0x02 | (n << 4);
355 res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x00, 0x41,
356 0, 0x88, data, 3, ET61X251_CTRL_TIMEOUT);
357 if (res < 0)
358 err += res;
359
360 /* Start writing through the serial interface */
361 data[0] = data1;
362 res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x00, 0x41,
363 0, 0x80, data, 1, ET61X251_CTRL_TIMEOUT);
364 if (res < 0)
365 err += res;
366
367 err += et61x251_i2c_wait(cam, cam->sensor);
368
369 if (err)
370 DBG(3, "I2C raw write failed for %s image sensor",
371 cam->sensor->name);
372
373 PDBGG("I2C raw write: %u bytes, address = 0x%02X, data1 = 0x%02X, "
374 "data2 = 0x%02X, data3 = 0x%02X, data4 = 0x%02X, data5 = 0x%02X,"
375 " data6 = 0x%02X, data7 = 0x%02X, data8 = 0x%02X", n, address,
376 data1, data2, data3, data4, data5, data6, data7, data8);
377
378 return err ? -1 : 0;
379
380}
381
382
383int et61x251_i2c_read(struct et61x251_device* cam, u8 address)
384{
385 if (!cam->sensor)
386 return -1;
387
388 return et61x251_i2c_try_read(cam, cam->sensor, address);
389}
390
391
392int et61x251_i2c_write(struct et61x251_device* cam, u8 address, u8 value)
393{
394 if (!cam->sensor)
395 return -1;
396
397 return et61x251_i2c_try_write(cam, cam->sensor, address, value);
398}
399
400/*****************************************************************************/
401
402static void et61x251_urb_complete(struct urb *urb, struct pt_regs* regs)
403{
404 struct et61x251_device* cam = urb->context;
405 struct et61x251_frame_t** f;
406 size_t imagesize;
407 u8 i;
408 int err = 0;
409
410 if (urb->status == -ENOENT)
411 return;
412
413 f = &cam->frame_current;
414
415 if (cam->stream == STREAM_INTERRUPT) {
416 cam->stream = STREAM_OFF;
417 if ((*f))
418 (*f)->state = F_QUEUED;
419 DBG(3, "Stream interrupted");
420 wake_up_interruptible(&cam->wait_stream);
421 }
422
423 if (cam->state & DEV_DISCONNECTED)
424 return;
425
426 if (cam->state & DEV_MISCONFIGURED) {
427 wake_up_interruptible(&cam->wait_frame);
428 return;
429 }
430
431 if (cam->stream == STREAM_OFF || list_empty(&cam->inqueue))
432 goto resubmit_urb;
433
434 if (!(*f))
435 (*f) = list_entry(cam->inqueue.next, struct et61x251_frame_t,
436 frame);
437
438 imagesize = (cam->sensor->pix_format.width *
439 cam->sensor->pix_format.height *
440 cam->sensor->pix_format.priv) / 8;
441
442 for (i = 0; i < urb->number_of_packets; i++) {
443 unsigned int len, status;
444 void *pos;
445 u8* b1, * b2, sof;
446 const u8 VOID_BYTES = 6;
447 size_t imglen;
448
449 len = urb->iso_frame_desc[i].actual_length;
450 status = urb->iso_frame_desc[i].status;
451 pos = urb->iso_frame_desc[i].offset + urb->transfer_buffer;
452
453 if (status) {
454 DBG(3, "Error in isochronous frame");
455 (*f)->state = F_ERROR;
456 continue;
457 }
458
459 b1 = pos++;
460 b2 = pos++;
461 sof = ((*b1 & 0x3f) == 63);
462 imglen = ((*b1 & 0xc0) << 2) | *b2;
463
464 PDBGG("Isochrnous frame: length %u, #%u i, image length %zu",
465 len, i, imglen);
466
467 if ((*f)->state == F_QUEUED || (*f)->state == F_ERROR)
468start_of_frame:
469 if (sof) {
470 (*f)->state = F_GRABBING;
471 (*f)->buf.bytesused = 0;
472 do_gettimeofday(&(*f)->buf.timestamp);
473 pos += 22;
474 DBG(3, "SOF detected: new video frame");
475 }
476
477 if ((*f)->state == F_GRABBING) {
478 if (sof && (*f)->buf.bytesused) {
479 if (cam->sensor->pix_format.pixelformat ==
480 V4L2_PIX_FMT_ET61X251)
481 goto end_of_frame;
482 else {
483 DBG(3, "Not expected SOF detected "
484 "after %lu bytes",
485 (unsigned long)(*f)->buf.bytesused);
486 (*f)->state = F_ERROR;
487 continue;
488 }
489 }
490
491 if ((*f)->buf.bytesused + imglen > imagesize) {
492 DBG(3, "Video frame size exceeded");
493 (*f)->state = F_ERROR;
494 continue;
495 }
496
497 pos += VOID_BYTES;
498
499 memcpy((*f)->bufmem+(*f)->buf.bytesused, pos, imglen);
500 (*f)->buf.bytesused += imglen;
501
502 if ((*f)->buf.bytesused == imagesize) {
503 u32 b;
504end_of_frame:
505 b = (*f)->buf.bytesused;
506 (*f)->state = F_DONE;
507 (*f)->buf.sequence= ++cam->frame_count;
508 spin_lock(&cam->queue_lock);
509 list_move_tail(&(*f)->frame, &cam->outqueue);
510 if (!list_empty(&cam->inqueue))
511 (*f) = list_entry(cam->inqueue.next,
512 struct et61x251_frame_t,
513 frame);
514 else
515 (*f) = NULL;
516 spin_unlock(&cam->queue_lock);
517 DBG(3, "Video frame captured: : %lu bytes",
518 (unsigned long)(b));
519
520 if (!(*f))
521 goto resubmit_urb;
522
523 if (sof &&
524 cam->sensor->pix_format.pixelformat ==
525 V4L2_PIX_FMT_ET61X251)
526 goto start_of_frame;
527 }
528 }
529 }
530
531resubmit_urb:
532 urb->dev = cam->usbdev;
533 err = usb_submit_urb(urb, GFP_ATOMIC);
534 if (err < 0 && err != -EPERM) {
535 cam->state |= DEV_MISCONFIGURED;
536 DBG(1, "usb_submit_urb() failed");
537 }
538
539 wake_up_interruptible(&cam->wait_frame);
540}
541
542
543static int et61x251_start_transfer(struct et61x251_device* cam)
544{
545 struct usb_device *udev = cam->usbdev;
546 struct urb* urb;
547 const unsigned int wMaxPacketSize[] = {0, 256, 384, 512, 640, 768, 832,
548 864, 896, 920, 956, 980, 1000,
549 1022};
550 const unsigned int psz = wMaxPacketSize[ET61X251_ALTERNATE_SETTING];
551 s8 i, j;
552 int err = 0;
553
554 for (i = 0; i < ET61X251_URBS; i++) {
555 cam->transfer_buffer[i] = kzalloc(ET61X251_ISO_PACKETS * psz,
556 GFP_KERNEL);
557 if (!cam->transfer_buffer[i]) {
558 err = -ENOMEM;
559 DBG(1, "Not enough memory");
560 goto free_buffers;
561 }
562 }
563
564 for (i = 0; i < ET61X251_URBS; i++) {
565 urb = usb_alloc_urb(ET61X251_ISO_PACKETS, GFP_KERNEL);
566 cam->urb[i] = urb;
567 if (!urb) {
568 err = -ENOMEM;
569 DBG(1, "usb_alloc_urb() failed");
570 goto free_urbs;
571 }
572 urb->dev = udev;
573 urb->context = cam;
574 urb->pipe = usb_rcvisocpipe(udev, 1);
575 urb->transfer_flags = URB_ISO_ASAP;
576 urb->number_of_packets = ET61X251_ISO_PACKETS;
577 urb->complete = et61x251_urb_complete;
578 urb->transfer_buffer = cam->transfer_buffer[i];
579 urb->transfer_buffer_length = psz * ET61X251_ISO_PACKETS;
580 urb->interval = 1;
581 for (j = 0; j < ET61X251_ISO_PACKETS; j++) {
582 urb->iso_frame_desc[j].offset = psz * j;
583 urb->iso_frame_desc[j].length = psz;
584 }
585 }
586
587 err = et61x251_write_reg(cam, 0x01, 0x03);
588 err = et61x251_write_reg(cam, 0x00, 0x03);
589 err = et61x251_write_reg(cam, 0x08, 0x03);
590 if (err) {
591 err = -EIO;
592 DBG(1, "I/O hardware error");
593 goto free_urbs;
594 }
595
596 err = usb_set_interface(udev, 0, ET61X251_ALTERNATE_SETTING);
597 if (err) {
598 DBG(1, "usb_set_interface() failed");
599 goto free_urbs;
600 }
601
602 cam->frame_current = NULL;
603
604 for (i = 0; i < ET61X251_URBS; i++) {
605 err = usb_submit_urb(cam->urb[i], GFP_KERNEL);
606 if (err) {
607 for (j = i-1; j >= 0; j--)
608 usb_kill_urb(cam->urb[j]);
609 DBG(1, "usb_submit_urb() failed, error %d", err);
610 goto free_urbs;
611 }
612 }
613
614 return 0;
615
616free_urbs:
617 for (i = 0; (i < ET61X251_URBS) && cam->urb[i]; i++)
618 usb_free_urb(cam->urb[i]);
619
620free_buffers:
621 for (i = 0; (i < ET61X251_URBS) && cam->transfer_buffer[i]; i++)
622 kfree(cam->transfer_buffer[i]);
623
624 return err;
625}
626
627
628static int et61x251_stop_transfer(struct et61x251_device* cam)
629{
630 struct usb_device *udev = cam->usbdev;
631 s8 i;
632 int err = 0;
633
634 if (cam->state & DEV_DISCONNECTED)
635 return 0;
636
637 for (i = ET61X251_URBS-1; i >= 0; i--) {
638 usb_kill_urb(cam->urb[i]);
639 usb_free_urb(cam->urb[i]);
640 kfree(cam->transfer_buffer[i]);
641 }
642
643 err = usb_set_interface(udev, 0, 0); /* 0 Mb/s */
644 if (err)
645 DBG(3, "usb_set_interface() failed");
646
647 return err;
648}
649
650
651static int et61x251_stream_interrupt(struct et61x251_device* cam)
652{
653 int err = 0;
654
655 cam->stream = STREAM_INTERRUPT;
656 err = wait_event_timeout(cam->wait_stream,
657 (cam->stream == STREAM_OFF) ||
658 (cam->state & DEV_DISCONNECTED),
659 ET61X251_URB_TIMEOUT);
660 if (cam->state & DEV_DISCONNECTED)
661 return -ENODEV;
662 else if (err) {
663 cam->state |= DEV_MISCONFIGURED;
664 DBG(1, "URB timeout reached. The camera is misconfigured. To "
665 "use it, close and open /dev/video%d again.",
666 cam->v4ldev->minor);
667 return err;
668 }
669
670 return 0;
671}
672
673/*****************************************************************************/
674
675#ifdef CONFIG_VIDEO_ADV_DEBUG
676static u8 et61x251_strtou8(const char* buff, size_t len, ssize_t* count)
677{
678 char str[5];
679 char* endp;
680 unsigned long val;
681
682 if (len < 4) {
683 strncpy(str, buff, len);
684 str[len+1] = '\0';
685 } else {
686 strncpy(str, buff, 4);
687 str[4] = '\0';
688 }
689
690 val = simple_strtoul(str, &endp, 0);
691
692 *count = 0;
693 if (val <= 0xff)
694 *count = (ssize_t)(endp - str);
695 if ((*count) && (len == *count+1) && (buff[*count] == '\n'))
696 *count += 1;
697
698 return (u8)val;
699}
700
701/*
702 NOTE 1: being inside one of the following methods implies that the v4l
703 device exists for sure (see kobjects and reference counters)
704 NOTE 2: buffers are PAGE_SIZE long
705*/
706
707static ssize_t et61x251_show_reg(struct class_device* cd, char* buf)
708{
709 struct et61x251_device* cam;
710 ssize_t count;
711
712 if (down_interruptible(&et61x251_sysfs_lock))
713 return -ERESTARTSYS;
714
715 cam = video_get_drvdata(to_video_device(cd));
716 if (!cam) {
717 up(&et61x251_sysfs_lock);
718 return -ENODEV;
719 }
720
721 count = sprintf(buf, "%u\n", cam->sysfs.reg);
722
723 up(&et61x251_sysfs_lock);
724
725 return count;
726}
727
728
729static ssize_t
730et61x251_store_reg(struct class_device* cd, const char* buf, size_t len)
731{
732 struct et61x251_device* cam;
733 u8 index;
734 ssize_t count;
735
736 if (down_interruptible(&et61x251_sysfs_lock))
737 return -ERESTARTSYS;
738
739 cam = video_get_drvdata(to_video_device(cd));
740 if (!cam) {
741 up(&et61x251_sysfs_lock);
742 return -ENODEV;
743 }
744
745 index = et61x251_strtou8(buf, len, &count);
746 if (index > 0x8e || !count) {
747 up(&et61x251_sysfs_lock);
748 return -EINVAL;
749 }
750
751 cam->sysfs.reg = index;
752
753 DBG(2, "Moved ET61X[12]51 register index to 0x%02X", cam->sysfs.reg);
754 DBG(3, "Written bytes: %zd", count);
755
756 up(&et61x251_sysfs_lock);
757
758 return count;
759}
760
761
762static ssize_t et61x251_show_val(struct class_device* cd, char* buf)
763{
764 struct et61x251_device* cam;
765 ssize_t count;
766 int val;
767
768 if (down_interruptible(&et61x251_sysfs_lock))
769 return -ERESTARTSYS;
770
771 cam = video_get_drvdata(to_video_device(cd));
772 if (!cam) {
773 up(&et61x251_sysfs_lock);
774 return -ENODEV;
775 }
776
777 if ((val = et61x251_read_reg(cam, cam->sysfs.reg)) < 0) {
778 up(&et61x251_sysfs_lock);
779 return -EIO;
780 }
781
782 count = sprintf(buf, "%d\n", val);
783
784 DBG(3, "Read bytes: %zd", count);
785
786 up(&et61x251_sysfs_lock);
787
788 return count;
789}
790
791
792static ssize_t
793et61x251_store_val(struct class_device* cd, const char* buf, size_t len)
794{
795 struct et61x251_device* cam;
796 u8 value;
797 ssize_t count;
798 int err;
799
800 if (down_interruptible(&et61x251_sysfs_lock))
801 return -ERESTARTSYS;
802
803 cam = video_get_drvdata(to_video_device(cd));
804 if (!cam) {
805 up(&et61x251_sysfs_lock);
806 return -ENODEV;
807 }
808
809 value = et61x251_strtou8(buf, len, &count);
810 if (!count) {
811 up(&et61x251_sysfs_lock);
812 return -EINVAL;
813 }
814
815 err = et61x251_write_reg(cam, value, cam->sysfs.reg);
816 if (err) {
817 up(&et61x251_sysfs_lock);
818 return -EIO;
819 }
820
821 DBG(2, "Written ET61X[12]51 reg. 0x%02X, val. 0x%02X",
822 cam->sysfs.reg, value);
823 DBG(3, "Written bytes: %zd", count);
824
825 up(&et61x251_sysfs_lock);
826
827 return count;
828}
829
830
831static ssize_t et61x251_show_i2c_reg(struct class_device* cd, char* buf)
832{
833 struct et61x251_device* cam;
834 ssize_t count;
835
836 if (down_interruptible(&et61x251_sysfs_lock))
837 return -ERESTARTSYS;
838
839 cam = video_get_drvdata(to_video_device(cd));
840 if (!cam) {
841 up(&et61x251_sysfs_lock);
842 return -ENODEV;
843 }
844
845 count = sprintf(buf, "%u\n", cam->sysfs.i2c_reg);
846
847 DBG(3, "Read bytes: %zd", count);
848
849 up(&et61x251_sysfs_lock);
850
851 return count;
852}
853
854
855static ssize_t
856et61x251_store_i2c_reg(struct class_device* cd, const char* buf, size_t len)
857{
858 struct et61x251_device* cam;
859 u8 index;
860 ssize_t count;
861
862 if (down_interruptible(&et61x251_sysfs_lock))
863 return -ERESTARTSYS;
864
865 cam = video_get_drvdata(to_video_device(cd));
866 if (!cam) {
867 up(&et61x251_sysfs_lock);
868 return -ENODEV;
869 }
870
871 index = et61x251_strtou8(buf, len, &count);
872 if (!count) {
873 up(&et61x251_sysfs_lock);
874 return -EINVAL;
875 }
876
877 cam->sysfs.i2c_reg = index;
878
879 DBG(2, "Moved sensor register index to 0x%02X", cam->sysfs.i2c_reg);
880 DBG(3, "Written bytes: %zd", count);
881
882 up(&et61x251_sysfs_lock);
883
884 return count;
885}
886
887
888static ssize_t et61x251_show_i2c_val(struct class_device* cd, char* buf)
889{
890 struct et61x251_device* cam;
891 ssize_t count;
892 int val;
893
894 if (down_interruptible(&et61x251_sysfs_lock))
895 return -ERESTARTSYS;
896
897 cam = video_get_drvdata(to_video_device(cd));
898 if (!cam) {
899 up(&et61x251_sysfs_lock);
900 return -ENODEV;
901 }
902
903 if (!(cam->sensor->sysfs_ops & ET61X251_I2C_READ)) {
904 up(&et61x251_sysfs_lock);
905 return -ENOSYS;
906 }
907
908 if ((val = et61x251_i2c_read(cam, cam->sysfs.i2c_reg)) < 0) {
909 up(&et61x251_sysfs_lock);
910 return -EIO;
911 }
912
913 count = sprintf(buf, "%d\n", val);
914
915 DBG(3, "Read bytes: %zd", count);
916
917 up(&et61x251_sysfs_lock);
918
919 return count;
920}
921
922
923static ssize_t
924et61x251_store_i2c_val(struct class_device* cd, const char* buf, size_t len)
925{
926 struct et61x251_device* cam;
927 u8 value;
928 ssize_t count;
929 int err;
930
931 if (down_interruptible(&et61x251_sysfs_lock))
932 return -ERESTARTSYS;
933
934 cam = video_get_drvdata(to_video_device(cd));
935 if (!cam) {
936 up(&et61x251_sysfs_lock);
937 return -ENODEV;
938 }
939
940 if (!(cam->sensor->sysfs_ops & ET61X251_I2C_READ)) {
941 up(&et61x251_sysfs_lock);
942 return -ENOSYS;
943 }
944
945 value = et61x251_strtou8(buf, len, &count);
946 if (!count) {
947 up(&et61x251_sysfs_lock);
948 return -EINVAL;
949 }
950
951 err = et61x251_i2c_write(cam, cam->sysfs.i2c_reg, value);
952 if (err) {
953 up(&et61x251_sysfs_lock);
954 return -EIO;
955 }
956
957 DBG(2, "Written sensor reg. 0x%02X, val. 0x%02X",
958 cam->sysfs.i2c_reg, value);
959 DBG(3, "Written bytes: %zd", count);
960
961 up(&et61x251_sysfs_lock);
962
963 return count;
964}
965
966
967static CLASS_DEVICE_ATTR(reg, S_IRUGO | S_IWUSR,
968 et61x251_show_reg, et61x251_store_reg);
969static CLASS_DEVICE_ATTR(val, S_IRUGO | S_IWUSR,
970 et61x251_show_val, et61x251_store_val);
971static CLASS_DEVICE_ATTR(i2c_reg, S_IRUGO | S_IWUSR,
972 et61x251_show_i2c_reg, et61x251_store_i2c_reg);
973static CLASS_DEVICE_ATTR(i2c_val, S_IRUGO | S_IWUSR,
974 et61x251_show_i2c_val, et61x251_store_i2c_val);
975
976
977static void et61x251_create_sysfs(struct et61x251_device* cam)
978{
979 struct video_device *v4ldev = cam->v4ldev;
980
981 video_device_create_file(v4ldev, &class_device_attr_reg);
982 video_device_create_file(v4ldev, &class_device_attr_val);
983 if (cam->sensor && cam->sensor->sysfs_ops) {
984 video_device_create_file(v4ldev, &class_device_attr_i2c_reg);
985 video_device_create_file(v4ldev, &class_device_attr_i2c_val);
986 }
987}
988#endif /* CONFIG_VIDEO_ADV_DEBUG */
989
990/*****************************************************************************/
991
992static int
993et61x251_set_pix_format(struct et61x251_device* cam,
994 struct v4l2_pix_format* pix)
995{
996 int r, err = 0;
997
998 if ((r = et61x251_read_reg(cam, 0x12)) < 0)
999 err += r;
1000 if (pix->pixelformat == V4L2_PIX_FMT_ET61X251)
1001 err += et61x251_write_reg(cam, r & 0xfd, 0x12);
1002 else
1003 err += et61x251_write_reg(cam, r | 0x02, 0x12);
1004
1005 return err ? -EIO : 0;
1006}
1007
1008
1009static int
1010et61x251_set_compression(struct et61x251_device* cam,
1011 struct v4l2_jpegcompression* compression)
1012{
1013 int r, err = 0;
1014
1015 if ((r = et61x251_read_reg(cam, 0x12)) < 0)
1016 err += r;
1017 if (compression->quality == 0)
1018 err += et61x251_write_reg(cam, r & 0xfb, 0x12);
1019 else
1020 err += et61x251_write_reg(cam, r | 0x04, 0x12);
1021
1022 return err ? -EIO : 0;
1023}
1024
1025
1026static int et61x251_set_scale(struct et61x251_device* cam, u8 scale)
1027{
1028 int r = 0, err = 0;
1029
1030 r = et61x251_read_reg(cam, 0x12);
1031 if (r < 0)
1032 err += r;
1033
1034 if (scale == 1)
1035 err += et61x251_write_reg(cam, r & ~0x01, 0x12);
1036 else if (scale == 2)
1037 err += et61x251_write_reg(cam, r | 0x01, 0x12);
1038
1039 if (err)
1040 return -EIO;
1041
1042 PDBGG("Scaling factor: %u", scale);
1043
1044 return 0;
1045}
1046
1047
1048static int
1049et61x251_set_crop(struct et61x251_device* cam, struct v4l2_rect* rect)
1050{
1051 struct et61x251_sensor* s = cam->sensor;
1052 u16 fmw_sx = (u16)(rect->left - s->cropcap.bounds.left +
1053 s->active_pixel.left),
1054 fmw_sy = (u16)(rect->top - s->cropcap.bounds.top +
1055 s->active_pixel.top),
1056 fmw_length = (u16)(rect->width),
1057 fmw_height = (u16)(rect->height);
1058 int err = 0;
1059
1060 err += et61x251_write_reg(cam, fmw_sx & 0xff, 0x69);
1061 err += et61x251_write_reg(cam, fmw_sy & 0xff, 0x6a);
1062 err += et61x251_write_reg(cam, fmw_length & 0xff, 0x6b);
1063 err += et61x251_write_reg(cam, fmw_height & 0xff, 0x6c);
1064 err += et61x251_write_reg(cam, (fmw_sx >> 8) | ((fmw_sy & 0x300) >> 6)
1065 | ((fmw_length & 0x300) >> 4)
1066 | ((fmw_height & 0x300) >> 2), 0x6d);
1067 if (err)
1068 return -EIO;
1069
1070 PDBGG("fmw_sx, fmw_sy, fmw_length, fmw_height: %u %u %u %u",
1071 fmw_sx, fmw_sy, fmw_length, fmw_height);
1072
1073 return 0;
1074}
1075
1076
1077static int et61x251_init(struct et61x251_device* cam)
1078{
1079 struct et61x251_sensor* s = cam->sensor;
1080 struct v4l2_control ctrl;
1081 struct v4l2_queryctrl *qctrl;
1082 struct v4l2_rect* rect;
1083 u8 i = 0;
1084 int err = 0;
1085
1086 if (!(cam->state & DEV_INITIALIZED)) {
1087 init_waitqueue_head(&cam->open);
1088 qctrl = s->qctrl;
1089 rect = &(s->cropcap.defrect);
1090 cam->compression.quality = ET61X251_COMPRESSION_QUALITY;
1091 } else { /* use current values */
1092 qctrl = s->_qctrl;
1093 rect = &(s->_rect);
1094 }
1095
1096 err += et61x251_set_scale(cam, rect->width / s->pix_format.width);
1097 err += et61x251_set_crop(cam, rect);
1098 if (err)
1099 return err;
1100
1101 if (s->init) {
1102 err = s->init(cam);
1103 if (err) {
1104 DBG(3, "Sensor initialization failed");
1105 return err;
1106 }
1107 }
1108
1109 err += et61x251_set_compression(cam, &cam->compression);
1110 err += et61x251_set_pix_format(cam, &s->pix_format);
1111 if (s->set_pix_format)
1112 err += s->set_pix_format(cam, &s->pix_format);
1113 if (err)
1114 return err;
1115
1116 if (s->pix_format.pixelformat == V4L2_PIX_FMT_ET61X251)
1117 DBG(3, "Compressed video format is active, quality %d",
1118 cam->compression.quality);
1119 else
1120 DBG(3, "Uncompressed video format is active");
1121
1122 if (s->set_crop)
1123 if ((err = s->set_crop(cam, rect))) {
1124 DBG(3, "set_crop() failed");
1125 return err;
1126 }
1127
1128 if (s->set_ctrl) {
1129 for (i = 0; i < ARRAY_SIZE(s->qctrl); i++)
1130 if (s->qctrl[i].id != 0 &&
1131 !(s->qctrl[i].flags & V4L2_CTRL_FLAG_DISABLED)) {
1132 ctrl.id = s->qctrl[i].id;
1133 ctrl.value = qctrl[i].default_value;
1134 err = s->set_ctrl(cam, &ctrl);
1135 if (err) {
1136 DBG(3, "Set %s control failed",
1137 s->qctrl[i].name);
1138 return err;
1139 }
1140 DBG(3, "Image sensor supports '%s' control",
1141 s->qctrl[i].name);
1142 }
1143 }
1144
1145 if (!(cam->state & DEV_INITIALIZED)) {
1146 init_MUTEX(&cam->fileop_sem);
1147 spin_lock_init(&cam->queue_lock);
1148 init_waitqueue_head(&cam->wait_frame);
1149 init_waitqueue_head(&cam->wait_stream);
1150 cam->nreadbuffers = 2;
1151 memcpy(s->_qctrl, s->qctrl, sizeof(s->qctrl));
1152 memcpy(&(s->_rect), &(s->cropcap.defrect),
1153 sizeof(struct v4l2_rect));
1154 cam->state |= DEV_INITIALIZED;
1155 }
1156
1157 DBG(2, "Initialization succeeded");
1158 return 0;
1159}
1160
1161
1162static void et61x251_release_resources(struct et61x251_device* cam)
1163{
1164 down(&et61x251_sysfs_lock);
1165
1166 DBG(2, "V4L2 device /dev/video%d deregistered", cam->v4ldev->minor);
1167 video_set_drvdata(cam->v4ldev, NULL);
1168 video_unregister_device(cam->v4ldev);
1169
1170 up(&et61x251_sysfs_lock);
1171
1172 kfree(cam->control_buffer);
1173}
1174
1175/*****************************************************************************/
1176
1177static int et61x251_open(struct inode* inode, struct file* filp)
1178{
1179 struct et61x251_device* cam;
1180 int err = 0;
1181
1182 /*
1183 This is the only safe way to prevent race conditions with
1184 disconnect
1185 */
1186 if (!down_read_trylock(&et61x251_disconnect))
1187 return -ERESTARTSYS;
1188
1189 cam = video_get_drvdata(video_devdata(filp));
1190
1191 if (down_interruptible(&cam->dev_sem)) {
1192 up_read(&et61x251_disconnect);
1193 return -ERESTARTSYS;
1194 }
1195
1196 if (cam->users) {
1197 DBG(2, "Device /dev/video%d is busy...", cam->v4ldev->minor);
1198 if ((filp->f_flags & O_NONBLOCK) ||
1199 (filp->f_flags & O_NDELAY)) {
1200 err = -EWOULDBLOCK;
1201 goto out;
1202 }
1203 up(&cam->dev_sem);
1204 err = wait_event_interruptible_exclusive(cam->open,
1205 cam->state & DEV_DISCONNECTED
1206 || !cam->users);
1207 if (err) {
1208 up_read(&et61x251_disconnect);
1209 return err;
1210 }
1211 if (cam->state & DEV_DISCONNECTED) {
1212 up_read(&et61x251_disconnect);
1213 return -ENODEV;
1214 }
1215 down(&cam->dev_sem);
1216 }
1217
1218
1219 if (cam->state & DEV_MISCONFIGURED) {
1220 err = et61x251_init(cam);
1221 if (err) {
1222 DBG(1, "Initialization failed again. "
1223 "I will retry on next open().");
1224 goto out;
1225 }
1226 cam->state &= ~DEV_MISCONFIGURED;
1227 }
1228
1229 if ((err = et61x251_start_transfer(cam)))
1230 goto out;
1231
1232 filp->private_data = cam;
1233 cam->users++;
1234 cam->io = IO_NONE;
1235 cam->stream = STREAM_OFF;
1236 cam->nbuffers = 0;
1237 cam->frame_count = 0;
1238 et61x251_empty_framequeues(cam);
1239
1240 DBG(3, "Video device /dev/video%d is open", cam->v4ldev->minor);
1241
1242out:
1243 up(&cam->dev_sem);
1244 up_read(&et61x251_disconnect);
1245 return err;
1246}
1247
1248
1249static int et61x251_release(struct inode* inode, struct file* filp)
1250{
1251 struct et61x251_device* cam = video_get_drvdata(video_devdata(filp));
1252
1253 down(&cam->dev_sem); /* prevent disconnect() to be called */
1254
1255 et61x251_stop_transfer(cam);
1256
1257 et61x251_release_buffers(cam);
1258
1259 if (cam->state & DEV_DISCONNECTED) {
1260 et61x251_release_resources(cam);
1261 up(&cam->dev_sem);
1262 kfree(cam);
1263 return 0;
1264 }
1265
1266 cam->users--;
1267 wake_up_interruptible_nr(&cam->open, 1);
1268
1269 DBG(3, "Video device /dev/video%d closed", cam->v4ldev->minor);
1270
1271 up(&cam->dev_sem);
1272
1273 return 0;
1274}
1275
1276
1277static ssize_t
1278et61x251_read(struct file* filp, char __user * buf,
1279 size_t count, loff_t* f_pos)
1280{
1281 struct et61x251_device* cam = video_get_drvdata(video_devdata(filp));
1282 struct et61x251_frame_t* f, * i;
1283 unsigned long lock_flags;
1284 int err = 0;
1285
1286 if (down_interruptible(&cam->fileop_sem))
1287 return -ERESTARTSYS;
1288
1289 if (cam->state & DEV_DISCONNECTED) {
1290 DBG(1, "Device not present");
1291 up(&cam->fileop_sem);
1292 return -ENODEV;
1293 }
1294
1295 if (cam->state & DEV_MISCONFIGURED) {
1296 DBG(1, "The camera is misconfigured. Close and open it "
1297 "again.");
1298 up(&cam->fileop_sem);
1299 return -EIO;
1300 }
1301
1302 if (cam->io == IO_MMAP) {
1303 DBG(3, "Close and open the device again to choose the read "
1304 "method");
1305 up(&cam->fileop_sem);
1306 return -EINVAL;
1307 }
1308
1309 if (cam->io == IO_NONE) {
1310 if (!et61x251_request_buffers(cam, cam->nreadbuffers,
1311 IO_READ)) {
1312 DBG(1, "read() failed, not enough memory");
1313 up(&cam->fileop_sem);
1314 return -ENOMEM;
1315 }
1316 cam->io = IO_READ;
1317 cam->stream = STREAM_ON;
1318 }
1319
1320 if (list_empty(&cam->inqueue)) {
1321 if (!list_empty(&cam->outqueue))
1322 et61x251_empty_framequeues(cam);
1323 et61x251_queue_unusedframes(cam);
1324 }
1325
1326 if (!count) {
1327 up(&cam->fileop_sem);
1328 return 0;
1329 }
1330
1331 if (list_empty(&cam->outqueue)) {
1332 if (filp->f_flags & O_NONBLOCK) {
1333 up(&cam->fileop_sem);
1334 return -EAGAIN;
1335 }
1336 err = wait_event_interruptible
1337 ( cam->wait_frame,
1338 (!list_empty(&cam->outqueue)) ||
1339 (cam->state & DEV_DISCONNECTED) ||
1340 (cam->state & DEV_MISCONFIGURED) );
1341 if (err) {
1342 up(&cam->fileop_sem);
1343 return err;
1344 }
1345 if (cam->state & DEV_DISCONNECTED) {
1346 up(&cam->fileop_sem);
1347 return -ENODEV;
1348 }
1349 if (cam->state & DEV_MISCONFIGURED) {
1350 up(&cam->fileop_sem);
1351 return -EIO;
1352 }
1353 }
1354
1355 f = list_entry(cam->outqueue.prev, struct et61x251_frame_t, frame);
1356
1357 if (count > f->buf.bytesused)
1358 count = f->buf.bytesused;
1359
1360 if (copy_to_user(buf, f->bufmem, count)) {
1361 err = -EFAULT;
1362 goto exit;
1363 }
1364 *f_pos += count;
1365
1366exit:
1367 spin_lock_irqsave(&cam->queue_lock, lock_flags);
1368 list_for_each_entry(i, &cam->outqueue, frame)
1369 i->state = F_UNUSED;
1370 INIT_LIST_HEAD(&cam->outqueue);
1371 spin_unlock_irqrestore(&cam->queue_lock, lock_flags);
1372
1373 et61x251_queue_unusedframes(cam);
1374
1375 PDBGG("Frame #%lu, bytes read: %zu",
1376 (unsigned long)f->buf.index, count);
1377
1378 up(&cam->fileop_sem);
1379
1380 return err ? err : count;
1381}
1382
1383
1384static unsigned int et61x251_poll(struct file *filp, poll_table *wait)
1385{
1386 struct et61x251_device* cam = video_get_drvdata(video_devdata(filp));
1387 struct et61x251_frame_t* f;
1388 unsigned long lock_flags;
1389 unsigned int mask = 0;
1390
1391 if (down_interruptible(&cam->fileop_sem))
1392 return POLLERR;
1393
1394 if (cam->state & DEV_DISCONNECTED) {
1395 DBG(1, "Device not present");
1396 goto error;
1397 }
1398
1399 if (cam->state & DEV_MISCONFIGURED) {
1400 DBG(1, "The camera is misconfigured. Close and open it "
1401 "again.");
1402 goto error;
1403 }
1404
1405 if (cam->io == IO_NONE) {
1406 if (!et61x251_request_buffers(cam, cam->nreadbuffers,
1407 IO_READ)) {
1408 DBG(1, "poll() failed, not enough memory");
1409 goto error;
1410 }
1411 cam->io = IO_READ;
1412 cam->stream = STREAM_ON;
1413 }
1414
1415 if (cam->io == IO_READ) {
1416 spin_lock_irqsave(&cam->queue_lock, lock_flags);
1417 list_for_each_entry(f, &cam->outqueue, frame)
1418 f->state = F_UNUSED;
1419 INIT_LIST_HEAD(&cam->outqueue);
1420 spin_unlock_irqrestore(&cam->queue_lock, lock_flags);
1421 et61x251_queue_unusedframes(cam);
1422 }
1423
1424 poll_wait(filp, &cam->wait_frame, wait);
1425
1426 if (!list_empty(&cam->outqueue))
1427 mask |= POLLIN | POLLRDNORM;
1428
1429 up(&cam->fileop_sem);
1430
1431 return mask;
1432
1433error:
1434 up(&cam->fileop_sem);
1435 return POLLERR;
1436}
1437
1438
1439static void et61x251_vm_open(struct vm_area_struct* vma)
1440{
1441 struct et61x251_frame_t* f = vma->vm_private_data;
1442 f->vma_use_count++;
1443}
1444
1445
1446static void et61x251_vm_close(struct vm_area_struct* vma)
1447{
1448 /* NOTE: buffers are not freed here */
1449 struct et61x251_frame_t* f = vma->vm_private_data;
1450 f->vma_use_count--;
1451}
1452
1453
1454static struct vm_operations_struct et61x251_vm_ops = {
1455 .open = et61x251_vm_open,
1456 .close = et61x251_vm_close,
1457};
1458
1459
1460static int et61x251_mmap(struct file* filp, struct vm_area_struct *vma)
1461{
1462 struct et61x251_device* cam = video_get_drvdata(video_devdata(filp));
1463 unsigned long size = vma->vm_end - vma->vm_start,
1464 start = vma->vm_start;
1465 void *pos;
1466 u32 i;
1467
1468 if (down_interruptible(&cam->fileop_sem))
1469 return -ERESTARTSYS;
1470
1471 if (cam->state & DEV_DISCONNECTED) {
1472 DBG(1, "Device not present");
1473 up(&cam->fileop_sem);
1474 return -ENODEV;
1475 }
1476
1477 if (cam->state & DEV_MISCONFIGURED) {
1478 DBG(1, "The camera is misconfigured. Close and open it "
1479 "again.");
1480 up(&cam->fileop_sem);
1481 return -EIO;
1482 }
1483
1484 if (cam->io != IO_MMAP || !(vma->vm_flags & VM_WRITE) ||
1485 size != PAGE_ALIGN(cam->frame[0].buf.length)) {
1486 up(&cam->fileop_sem);
1487 return -EINVAL;
1488 }
1489
1490 for (i = 0; i < cam->nbuffers; i++) {
1491 if ((cam->frame[i].buf.m.offset>>PAGE_SHIFT) == vma->vm_pgoff)
1492 break;
1493 }
1494 if (i == cam->nbuffers) {
1495 up(&cam->fileop_sem);
1496 return -EINVAL;
1497 }
1498
1499 vma->vm_flags |= VM_IO;
1500 vma->vm_flags |= VM_RESERVED;
1501
1502 pos = cam->frame[i].bufmem;
1503 while (size > 0) { /* size is page-aligned */
1504 if (vm_insert_page(vma, start, vmalloc_to_page(pos))) {
1505 up(&cam->fileop_sem);
1506 return -EAGAIN;
1507 }
1508 start += PAGE_SIZE;
1509 pos += PAGE_SIZE;
1510 size -= PAGE_SIZE;
1511 }
1512
1513 vma->vm_ops = &et61x251_vm_ops;
1514 vma->vm_private_data = &cam->frame[i];
1515
1516 et61x251_vm_open(vma);
1517
1518 up(&cam->fileop_sem);
1519
1520 return 0;
1521}
1522
1523/*****************************************************************************/
1524
1525static int
1526et61x251_vidioc_querycap(struct et61x251_device* cam, void __user * arg)
1527{
1528 struct v4l2_capability cap = {
1529 .driver = "et61x251",
1530 .version = ET61X251_MODULE_VERSION_CODE,
1531 .capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE |
1532 V4L2_CAP_STREAMING,
1533 };
1534
1535 strlcpy(cap.card, cam->v4ldev->name, sizeof(cap.card));
1536 if (usb_make_path(cam->usbdev, cap.bus_info, sizeof(cap.bus_info)) < 0)
1537 strlcpy(cap.bus_info, cam->usbdev->dev.bus_id,
1538 sizeof(cap.bus_info));
1539
1540 if (copy_to_user(arg, &cap, sizeof(cap)))
1541 return -EFAULT;
1542
1543 return 0;
1544}
1545
1546
1547static int
1548et61x251_vidioc_enuminput(struct et61x251_device* cam, void __user * arg)
1549{
1550 struct v4l2_input i;
1551
1552 if (copy_from_user(&i, arg, sizeof(i)))
1553 return -EFAULT;
1554
1555 if (i.index)
1556 return -EINVAL;
1557
1558 memset(&i, 0, sizeof(i));
1559 strcpy(i.name, "Camera");
1560
1561 if (copy_to_user(arg, &i, sizeof(i)))
1562 return -EFAULT;
1563
1564 return 0;
1565}
1566
1567
1568static int
1569et61x251_vidioc_gs_input(struct et61x251_device* cam, void __user * arg)
1570{
1571 int index;
1572
1573 if (copy_from_user(&index, arg, sizeof(index)))
1574 return -EFAULT;
1575
1576 if (index != 0)
1577 return -EINVAL;
1578
1579 return 0;
1580}
1581
1582
1583static int
1584et61x251_vidioc_query_ctrl(struct et61x251_device* cam, void __user * arg)
1585{
1586 struct et61x251_sensor* s = cam->sensor;
1587 struct v4l2_queryctrl qc;
1588 u8 i;
1589
1590 if (copy_from_user(&qc, arg, sizeof(qc)))
1591 return -EFAULT;
1592
1593 for (i = 0; i < ARRAY_SIZE(s->qctrl); i++)
1594 if (qc.id && qc.id == s->qctrl[i].id) {
1595 memcpy(&qc, &(s->qctrl[i]), sizeof(qc));
1596 if (copy_to_user(arg, &qc, sizeof(qc)))
1597 return -EFAULT;
1598 return 0;
1599 }
1600
1601 return -EINVAL;
1602}
1603
1604
1605static int
1606et61x251_vidioc_g_ctrl(struct et61x251_device* cam, void __user * arg)
1607{
1608 struct et61x251_sensor* s = cam->sensor;
1609 struct v4l2_control ctrl;
1610 int err = 0;
1611 u8 i;
1612
1613 if (!s->get_ctrl && !s->set_ctrl)
1614 return -EINVAL;
1615
1616 if (copy_from_user(&ctrl, arg, sizeof(ctrl)))
1617 return -EFAULT;
1618
1619 if (!s->get_ctrl) {
1620 for (i = 0; i < ARRAY_SIZE(s->qctrl); i++)
1621 if (ctrl.id == s->qctrl[i].id) {
1622 ctrl.value = s->_qctrl[i].default_value;
1623 goto exit;
1624 }
1625 return -EINVAL;
1626 } else
1627 err = s->get_ctrl(cam, &ctrl);
1628
1629exit:
1630 if (copy_to_user(arg, &ctrl, sizeof(ctrl)))
1631 return -EFAULT;
1632
1633 return err;
1634}
1635
1636
1637static int
1638et61x251_vidioc_s_ctrl(struct et61x251_device* cam, void __user * arg)
1639{
1640 struct et61x251_sensor* s = cam->sensor;
1641 struct v4l2_control ctrl;
1642 u8 i;
1643 int err = 0;
1644
1645 if (!s->set_ctrl)
1646 return -EINVAL;
1647
1648 if (copy_from_user(&ctrl, arg, sizeof(ctrl)))
1649 return -EFAULT;
1650
1651 for (i = 0; i < ARRAY_SIZE(s->qctrl); i++)
1652 if (ctrl.id == s->qctrl[i].id) {
1653 if (ctrl.value < s->qctrl[i].minimum ||
1654 ctrl.value > s->qctrl[i].maximum)
1655 return -ERANGE;
1656 ctrl.value -= ctrl.value % s->qctrl[i].step;
1657 break;
1658 }
1659
1660 if ((err = s->set_ctrl(cam, &ctrl)))
1661 return err;
1662
1663 s->_qctrl[i].default_value = ctrl.value;
1664
1665 return 0;
1666}
1667
1668
1669static int
1670et61x251_vidioc_cropcap(struct et61x251_device* cam, void __user * arg)
1671{
1672 struct v4l2_cropcap* cc = &(cam->sensor->cropcap);
1673
1674 cc->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1675 cc->pixelaspect.numerator = 1;
1676 cc->pixelaspect.denominator = 1;
1677
1678 if (copy_to_user(arg, cc, sizeof(*cc)))
1679 return -EFAULT;
1680
1681 return 0;
1682}
1683
1684
1685static int
1686et61x251_vidioc_g_crop(struct et61x251_device* cam, void __user * arg)
1687{
1688 struct et61x251_sensor* s = cam->sensor;
1689 struct v4l2_crop crop = {
1690 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
1691 };
1692
1693 memcpy(&(crop.c), &(s->_rect), sizeof(struct v4l2_rect));
1694
1695 if (copy_to_user(arg, &crop, sizeof(crop)))
1696 return -EFAULT;
1697
1698 return 0;
1699}
1700
1701
1702static int
1703et61x251_vidioc_s_crop(struct et61x251_device* cam, void __user * arg)
1704{
1705 struct et61x251_sensor* s = cam->sensor;
1706 struct v4l2_crop crop;
1707 struct v4l2_rect* rect;
1708 struct v4l2_rect* bounds = &(s->cropcap.bounds);
1709 struct v4l2_pix_format* pix_format = &(s->pix_format);
1710 u8 scale;
1711 const enum et61x251_stream_state stream = cam->stream;
1712 const u32 nbuffers = cam->nbuffers;
1713 u32 i;
1714 int err = 0;
1715
1716 if (copy_from_user(&crop, arg, sizeof(crop)))
1717 return -EFAULT;
1718
1719 rect = &(crop.c);
1720
1721 if (crop.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1722 return -EINVAL;
1723
1724 if (cam->module_param.force_munmap)
1725 for (i = 0; i < cam->nbuffers; i++)
1726 if (cam->frame[i].vma_use_count) {
1727 DBG(3, "VIDIOC_S_CROP failed. "
1728 "Unmap the buffers first.");
1729 return -EINVAL;
1730 }
1731
1732 /* Preserve R,G or B origin */
1733 rect->left = (s->_rect.left & 1L) ? rect->left | 1L : rect->left & ~1L;
1734 rect->top = (s->_rect.top & 1L) ? rect->top | 1L : rect->top & ~1L;
1735
1736 if (rect->width < 4)
1737 rect->width = 4;
1738 if (rect->height < 4)
1739 rect->height = 4;
1740 if (rect->width > bounds->width)
1741 rect->width = bounds->width;
1742 if (rect->height > bounds->height)
1743 rect->height = bounds->height;
1744 if (rect->left < bounds->left)
1745 rect->left = bounds->left;
1746 if (rect->top < bounds->top)
1747 rect->top = bounds->top;
1748 if (rect->left + rect->width > bounds->left + bounds->width)
1749 rect->left = bounds->left+bounds->width - rect->width;
1750 if (rect->top + rect->height > bounds->top + bounds->height)
1751 rect->top = bounds->top+bounds->height - rect->height;
1752
1753 rect->width &= ~3L;
1754 rect->height &= ~3L;
1755
1756 if (ET61X251_PRESERVE_IMGSCALE) {
1757 /* Calculate the actual scaling factor */
1758 u32 a, b;
1759 a = rect->width * rect->height;
1760 b = pix_format->width * pix_format->height;
1761 scale = b ? (u8)((a / b) < 4 ? 1 : 2) : 1;
1762 } else
1763 scale = 1;
1764
1765 if (cam->stream == STREAM_ON)
1766 if ((err = et61x251_stream_interrupt(cam)))
1767 return err;
1768
1769 if (copy_to_user(arg, &crop, sizeof(crop))) {
1770 cam->stream = stream;
1771 return -EFAULT;
1772 }
1773
1774 if (cam->module_param.force_munmap || cam->io == IO_READ)
1775 et61x251_release_buffers(cam);
1776
1777 err = et61x251_set_crop(cam, rect);
1778 if (s->set_crop)
1779 err += s->set_crop(cam, rect);
1780 err += et61x251_set_scale(cam, scale);
1781
1782 if (err) { /* atomic, no rollback in ioctl() */
1783 cam->state |= DEV_MISCONFIGURED;
1784 DBG(1, "VIDIOC_S_CROP failed because of hardware problems. To "
1785 "use the camera, close and open /dev/video%d again.",
1786 cam->v4ldev->minor);
1787 return -EIO;
1788 }
1789
1790 s->pix_format.width = rect->width/scale;
1791 s->pix_format.height = rect->height/scale;
1792 memcpy(&(s->_rect), rect, sizeof(*rect));
1793
1794 if ((cam->module_param.force_munmap || cam->io == IO_READ) &&
1795 nbuffers != et61x251_request_buffers(cam, nbuffers, cam->io)) {
1796 cam->state |= DEV_MISCONFIGURED;
1797 DBG(1, "VIDIOC_S_CROP failed because of not enough memory. To "
1798 "use the camera, close and open /dev/video%d again.",
1799 cam->v4ldev->minor);
1800 return -ENOMEM;
1801 }
1802
1803 if (cam->io == IO_READ)
1804 et61x251_empty_framequeues(cam);
1805 else if (cam->module_param.force_munmap)
1806 et61x251_requeue_outqueue(cam);
1807
1808 cam->stream = stream;
1809
1810 return 0;
1811}
1812
1813
1814static int
1815et61x251_vidioc_enum_fmt(struct et61x251_device* cam, void __user * arg)
1816{
1817 struct v4l2_fmtdesc fmtd;
1818
1819 if (copy_from_user(&fmtd, arg, sizeof(fmtd)))
1820 return -EFAULT;
1821
1822 if (fmtd.index == 0) {
1823 strcpy(fmtd.description, "bayer rgb");
1824 fmtd.pixelformat = V4L2_PIX_FMT_SBGGR8;
1825 } else if (fmtd.index == 1) {
1826 strcpy(fmtd.description, "compressed");
1827 fmtd.pixelformat = V4L2_PIX_FMT_ET61X251;
1828 fmtd.flags = V4L2_FMT_FLAG_COMPRESSED;
1829 } else
1830 return -EINVAL;
1831
1832 fmtd.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1833 memset(&fmtd.reserved, 0, sizeof(fmtd.reserved));
1834
1835 if (copy_to_user(arg, &fmtd, sizeof(fmtd)))
1836 return -EFAULT;
1837
1838 return 0;
1839}
1840
1841
1842static int
1843et61x251_vidioc_g_fmt(struct et61x251_device* cam, void __user * arg)
1844{
1845 struct v4l2_format format;
1846 struct v4l2_pix_format* pfmt = &(cam->sensor->pix_format);
1847
1848 if (copy_from_user(&format, arg, sizeof(format)))
1849 return -EFAULT;
1850
1851 if (format.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1852 return -EINVAL;
1853
1854 pfmt->bytesperline = (pfmt->pixelformat==V4L2_PIX_FMT_ET61X251)
1855 ? 0 : (pfmt->width * pfmt->priv) / 8;
1856 pfmt->sizeimage = pfmt->height * ((pfmt->width*pfmt->priv)/8);
1857 pfmt->field = V4L2_FIELD_NONE;
1858 memcpy(&(format.fmt.pix), pfmt, sizeof(*pfmt));
1859
1860 if (copy_to_user(arg, &format, sizeof(format)))
1861 return -EFAULT;
1862
1863 return 0;
1864}
1865
1866
1867static int
1868et61x251_vidioc_try_s_fmt(struct et61x251_device* cam, unsigned int cmd,
1869 void __user * arg)
1870{
1871 struct et61x251_sensor* s = cam->sensor;
1872 struct v4l2_format format;
1873 struct v4l2_pix_format* pix;
1874 struct v4l2_pix_format* pfmt = &(s->pix_format);
1875 struct v4l2_rect* bounds = &(s->cropcap.bounds);
1876 struct v4l2_rect rect;
1877 u8 scale;
1878 const enum et61x251_stream_state stream = cam->stream;
1879 const u32 nbuffers = cam->nbuffers;
1880 u32 i;
1881 int err = 0;
1882
1883 if (copy_from_user(&format, arg, sizeof(format)))
1884 return -EFAULT;
1885
1886 pix = &(format.fmt.pix);
1887
1888 if (format.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1889 return -EINVAL;
1890
1891 memcpy(&rect, &(s->_rect), sizeof(rect));
1892
1893 { /* calculate the actual scaling factor */
1894 u32 a, b;
1895 a = rect.width * rect.height;
1896 b = pix->width * pix->height;
1897 scale = b ? (u8)((a / b) < 4 ? 1 : 2) : 1;
1898 }
1899
1900 rect.width = scale * pix->width;
1901 rect.height = scale * pix->height;
1902
1903 if (rect.width < 4)
1904 rect.width = 4;
1905 if (rect.height < 4)
1906 rect.height = 4;
1907 if (rect.width > bounds->left + bounds->width - rect.left)
1908 rect.width = bounds->left + bounds->width - rect.left;
1909 if (rect.height > bounds->top + bounds->height - rect.top)
1910 rect.height = bounds->top + bounds->height - rect.top;
1911
1912 rect.width &= ~3L;
1913 rect.height &= ~3L;
1914
1915 { /* adjust the scaling factor */
1916 u32 a, b;
1917 a = rect.width * rect.height;
1918 b = pix->width * pix->height;
1919 scale = b ? (u8)((a / b) < 4 ? 1 : 2) : 1;
1920 }
1921
1922 pix->width = rect.width / scale;
1923 pix->height = rect.height / scale;
1924
1925 if (pix->pixelformat != V4L2_PIX_FMT_ET61X251 &&
1926 pix->pixelformat != V4L2_PIX_FMT_SBGGR8)
1927 pix->pixelformat = pfmt->pixelformat;
1928 pix->priv = pfmt->priv; /* bpp */
1929 pix->colorspace = pfmt->colorspace;
1930 pix->bytesperline = (pix->pixelformat == V4L2_PIX_FMT_ET61X251)
1931 ? 0 : (pix->width * pix->priv) / 8;
1932 pix->sizeimage = pix->height * ((pix->width * pix->priv) / 8);
1933 pix->field = V4L2_FIELD_NONE;
1934
1935 if (cmd == VIDIOC_TRY_FMT) {
1936 if (copy_to_user(arg, &format, sizeof(format)))
1937 return -EFAULT;
1938 return 0;
1939 }
1940
1941 if (cam->module_param.force_munmap)
1942 for (i = 0; i < cam->nbuffers; i++)
1943 if (cam->frame[i].vma_use_count) {
1944 DBG(3, "VIDIOC_S_FMT failed. "
1945 "Unmap the buffers first.");
1946 return -EINVAL;
1947 }
1948
1949 if (cam->stream == STREAM_ON)
1950 if ((err = et61x251_stream_interrupt(cam)))
1951 return err;
1952
1953 if (copy_to_user(arg, &format, sizeof(format))) {
1954 cam->stream = stream;
1955 return -EFAULT;
1956 }
1957
1958 if (cam->module_param.force_munmap || cam->io == IO_READ)
1959 et61x251_release_buffers(cam);
1960
1961 err += et61x251_set_pix_format(cam, pix);
1962 err += et61x251_set_crop(cam, &rect);
1963 if (s->set_pix_format)
1964 err += s->set_pix_format(cam, pix);
1965 if (s->set_crop)
1966 err += s->set_crop(cam, &rect);
1967 err += et61x251_set_scale(cam, scale);
1968
1969 if (err) { /* atomic, no rollback in ioctl() */
1970 cam->state |= DEV_MISCONFIGURED;
1971 DBG(1, "VIDIOC_S_FMT failed because of hardware problems. To "
1972 "use the camera, close and open /dev/video%d again.",
1973 cam->v4ldev->minor);
1974 return -EIO;
1975 }
1976
1977 memcpy(pfmt, pix, sizeof(*pix));
1978 memcpy(&(s->_rect), &rect, sizeof(rect));
1979
1980 if ((cam->module_param.force_munmap || cam->io == IO_READ) &&
1981 nbuffers != et61x251_request_buffers(cam, nbuffers, cam->io)) {
1982 cam->state |= DEV_MISCONFIGURED;
1983 DBG(1, "VIDIOC_S_FMT failed because of not enough memory. To "
1984 "use the camera, close and open /dev/video%d again.",
1985 cam->v4ldev->minor);
1986 return -ENOMEM;
1987 }
1988
1989 if (cam->io == IO_READ)
1990 et61x251_empty_framequeues(cam);
1991 else if (cam->module_param.force_munmap)
1992 et61x251_requeue_outqueue(cam);
1993
1994 cam->stream = stream;
1995
1996 return 0;
1997}
1998
1999
2000static int
2001et61x251_vidioc_g_jpegcomp(struct et61x251_device* cam, void __user * arg)
2002{
2003 if (copy_to_user(arg, &cam->compression,
2004 sizeof(cam->compression)))
2005 return -EFAULT;
2006
2007 return 0;
2008}
2009
2010
2011static int
2012et61x251_vidioc_s_jpegcomp(struct et61x251_device* cam, void __user * arg)
2013{
2014 struct v4l2_jpegcompression jc;
2015 const enum et61x251_stream_state stream = cam->stream;
2016 int err = 0;
2017
2018 if (copy_from_user(&jc, arg, sizeof(jc)))
2019 return -EFAULT;
2020
2021 if (jc.quality != 0 && jc.quality != 1)
2022 return -EINVAL;
2023
2024 if (cam->stream == STREAM_ON)
2025 if ((err = et61x251_stream_interrupt(cam)))
2026 return err;
2027
2028 err += et61x251_set_compression(cam, &jc);
2029 if (err) { /* atomic, no rollback in ioctl() */
2030 cam->state |= DEV_MISCONFIGURED;
2031 DBG(1, "VIDIOC_S_JPEGCOMP failed because of hardware "
2032 "problems. To use the camera, close and open "
2033 "/dev/video%d again.", cam->v4ldev->minor);
2034 return -EIO;
2035 }
2036
2037 cam->compression.quality = jc.quality;
2038
2039 cam->stream = stream;
2040
2041 return 0;
2042}
2043
2044
2045static int
2046et61x251_vidioc_reqbufs(struct et61x251_device* cam, void __user * arg)
2047{
2048 struct v4l2_requestbuffers rb;
2049 u32 i;
2050 int err;
2051
2052 if (copy_from_user(&rb, arg, sizeof(rb)))
2053 return -EFAULT;
2054
2055 if (rb.type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
2056 rb.memory != V4L2_MEMORY_MMAP)
2057 return -EINVAL;
2058
2059 if (cam->io == IO_READ) {
2060 DBG(3, "Close and open the device again to choose the mmap "
2061 "I/O method");
2062 return -EINVAL;
2063 }
2064
2065 for (i = 0; i < cam->nbuffers; i++)
2066 if (cam->frame[i].vma_use_count) {
2067 DBG(3, "VIDIOC_REQBUFS failed. "
2068 "Previous buffers are still mapped.");
2069 return -EINVAL;
2070 }
2071
2072 if (cam->stream == STREAM_ON)
2073 if ((err = et61x251_stream_interrupt(cam)))
2074 return err;
2075
2076 et61x251_empty_framequeues(cam);
2077
2078 et61x251_release_buffers(cam);
2079 if (rb.count)
2080 rb.count = et61x251_request_buffers(cam, rb.count, IO_MMAP);
2081
2082 if (copy_to_user(arg, &rb, sizeof(rb))) {
2083 et61x251_release_buffers(cam);
2084 cam->io = IO_NONE;
2085 return -EFAULT;
2086 }
2087
2088 cam->io = rb.count ? IO_MMAP : IO_NONE;
2089
2090 return 0;
2091}
2092
2093
2094static int
2095et61x251_vidioc_querybuf(struct et61x251_device* cam, void __user * arg)
2096{
2097 struct v4l2_buffer b;
2098
2099 if (copy_from_user(&b, arg, sizeof(b)))
2100 return -EFAULT;
2101
2102 if (b.type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
2103 b.index >= cam->nbuffers || cam->io != IO_MMAP)
2104 return -EINVAL;
2105
2106 memcpy(&b, &cam->frame[b.index].buf, sizeof(b));
2107
2108 if (cam->frame[b.index].vma_use_count)
2109 b.flags |= V4L2_BUF_FLAG_MAPPED;
2110
2111 if (cam->frame[b.index].state == F_DONE)
2112 b.flags |= V4L2_BUF_FLAG_DONE;
2113 else if (cam->frame[b.index].state != F_UNUSED)
2114 b.flags |= V4L2_BUF_FLAG_QUEUED;
2115
2116 if (copy_to_user(arg, &b, sizeof(b)))
2117 return -EFAULT;
2118
2119 return 0;
2120}
2121
2122
2123static int
2124et61x251_vidioc_qbuf(struct et61x251_device* cam, void __user * arg)
2125{
2126 struct v4l2_buffer b;
2127 unsigned long lock_flags;
2128
2129 if (copy_from_user(&b, arg, sizeof(b)))
2130 return -EFAULT;
2131
2132 if (b.type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
2133 b.index >= cam->nbuffers || cam->io != IO_MMAP)
2134 return -EINVAL;
2135
2136 if (cam->frame[b.index].state != F_UNUSED)
2137 return -EINVAL;
2138
2139 cam->frame[b.index].state = F_QUEUED;
2140
2141 spin_lock_irqsave(&cam->queue_lock, lock_flags);
2142 list_add_tail(&cam->frame[b.index].frame, &cam->inqueue);
2143 spin_unlock_irqrestore(&cam->queue_lock, lock_flags);
2144
2145 PDBGG("Frame #%lu queued", (unsigned long)b.index);
2146
2147 return 0;
2148}
2149
2150
2151static int
2152et61x251_vidioc_dqbuf(struct et61x251_device* cam, struct file* filp,
2153 void __user * arg)
2154{
2155 struct v4l2_buffer b;
2156 struct et61x251_frame_t *f;
2157 unsigned long lock_flags;
2158 int err = 0;
2159
2160 if (copy_from_user(&b, arg, sizeof(b)))
2161 return -EFAULT;
2162
2163 if (b.type != V4L2_BUF_TYPE_VIDEO_CAPTURE || cam->io!= IO_MMAP)
2164 return -EINVAL;
2165
2166 if (list_empty(&cam->outqueue)) {
2167 if (cam->stream == STREAM_OFF)
2168 return -EINVAL;
2169 if (filp->f_flags & O_NONBLOCK)
2170 return -EAGAIN;
2171 err = wait_event_interruptible
2172 ( cam->wait_frame,
2173 (!list_empty(&cam->outqueue)) ||
2174 (cam->state & DEV_DISCONNECTED) ||
2175 (cam->state & DEV_MISCONFIGURED) );
2176 if (err)
2177 return err;
2178 if (cam->state & DEV_DISCONNECTED)
2179 return -ENODEV;
2180 if (cam->state & DEV_MISCONFIGURED)
2181 return -EIO;
2182 }
2183
2184 spin_lock_irqsave(&cam->queue_lock, lock_flags);
2185 f = list_entry(cam->outqueue.next, struct et61x251_frame_t, frame);
2186 list_del(cam->outqueue.next);
2187 spin_unlock_irqrestore(&cam->queue_lock, lock_flags);
2188
2189 f->state = F_UNUSED;
2190
2191 memcpy(&b, &f->buf, sizeof(b));
2192 if (f->vma_use_count)
2193 b.flags |= V4L2_BUF_FLAG_MAPPED;
2194
2195 if (copy_to_user(arg, &b, sizeof(b)))
2196 return -EFAULT;
2197
2198 PDBGG("Frame #%lu dequeued", (unsigned long)f->buf.index);
2199
2200 return 0;
2201}
2202
2203
2204static int
2205et61x251_vidioc_streamon(struct et61x251_device* cam, void __user * arg)
2206{
2207 int type;
2208
2209 if (copy_from_user(&type, arg, sizeof(type)))
2210 return -EFAULT;
2211
2212 if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE || cam->io != IO_MMAP)
2213 return -EINVAL;
2214
2215 if (list_empty(&cam->inqueue))
2216 return -EINVAL;
2217
2218 cam->stream = STREAM_ON;
2219
2220 DBG(3, "Stream on");
2221
2222 return 0;
2223}
2224
2225
2226static int
2227et61x251_vidioc_streamoff(struct et61x251_device* cam, void __user * arg)
2228{
2229 int type, err;
2230
2231 if (copy_from_user(&type, arg, sizeof(type)))
2232 return -EFAULT;
2233
2234 if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE || cam->io != IO_MMAP)
2235 return -EINVAL;
2236
2237 if (cam->stream == STREAM_ON)
2238 if ((err = et61x251_stream_interrupt(cam)))
2239 return err;
2240
2241 et61x251_empty_framequeues(cam);
2242
2243 DBG(3, "Stream off");
2244
2245 return 0;
2246}
2247
2248
2249static int
2250et61x251_vidioc_g_parm(struct et61x251_device* cam, void __user * arg)
2251{
2252 struct v4l2_streamparm sp;
2253
2254 if (copy_from_user(&sp, arg, sizeof(sp)))
2255 return -EFAULT;
2256
2257 if (sp.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
2258 return -EINVAL;
2259
2260 sp.parm.capture.extendedmode = 0;
2261 sp.parm.capture.readbuffers = cam->nreadbuffers;
2262
2263 if (copy_to_user(arg, &sp, sizeof(sp)))
2264 return -EFAULT;
2265
2266 return 0;
2267}
2268
2269
2270static int
2271et61x251_vidioc_s_parm(struct et61x251_device* cam, void __user * arg)
2272{
2273 struct v4l2_streamparm sp;
2274
2275 if (copy_from_user(&sp, arg, sizeof(sp)))
2276 return -EFAULT;
2277
2278 if (sp.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
2279 return -EINVAL;
2280
2281 sp.parm.capture.extendedmode = 0;
2282
2283 if (sp.parm.capture.readbuffers == 0)
2284 sp.parm.capture.readbuffers = cam->nreadbuffers;
2285
2286 if (sp.parm.capture.readbuffers > ET61X251_MAX_FRAMES)
2287 sp.parm.capture.readbuffers = ET61X251_MAX_FRAMES;
2288
2289 if (copy_to_user(arg, &sp, sizeof(sp)))
2290 return -EFAULT;
2291
2292 cam->nreadbuffers = sp.parm.capture.readbuffers;
2293
2294 return 0;
2295}
2296
2297
2298static int et61x251_ioctl_v4l2(struct inode* inode, struct file* filp,
2299 unsigned int cmd, void __user * arg)
2300{
2301 struct et61x251_device* cam = video_get_drvdata(video_devdata(filp));
2302
2303 switch (cmd) {
2304
2305 case VIDIOC_QUERYCAP:
2306 return et61x251_vidioc_querycap(cam, arg);
2307
2308 case VIDIOC_ENUMINPUT:
2309 return et61x251_vidioc_enuminput(cam, arg);
2310
2311 case VIDIOC_G_INPUT:
2312 case VIDIOC_S_INPUT:
2313 return et61x251_vidioc_gs_input(cam, arg);
2314
2315 case VIDIOC_QUERYCTRL:
2316 return et61x251_vidioc_query_ctrl(cam, arg);
2317
2318 case VIDIOC_G_CTRL:
2319 return et61x251_vidioc_g_ctrl(cam, arg);
2320
2321 case VIDIOC_S_CTRL_OLD:
2322 case VIDIOC_S_CTRL:
2323 return et61x251_vidioc_s_ctrl(cam, arg);
2324
2325 case VIDIOC_CROPCAP_OLD:
2326 case VIDIOC_CROPCAP:
2327 return et61x251_vidioc_cropcap(cam, arg);
2328
2329 case VIDIOC_G_CROP:
2330 return et61x251_vidioc_g_crop(cam, arg);
2331
2332 case VIDIOC_S_CROP:
2333 return et61x251_vidioc_s_crop(cam, arg);
2334
2335 case VIDIOC_ENUM_FMT:
2336 return et61x251_vidioc_enum_fmt(cam, arg);
2337
2338 case VIDIOC_G_FMT:
2339 return et61x251_vidioc_g_fmt(cam, arg);
2340
2341 case VIDIOC_TRY_FMT:
2342 case VIDIOC_S_FMT:
2343 return et61x251_vidioc_try_s_fmt(cam, cmd, arg);
2344
2345 case VIDIOC_G_JPEGCOMP:
2346 return et61x251_vidioc_g_jpegcomp(cam, arg);
2347
2348 case VIDIOC_S_JPEGCOMP:
2349 return et61x251_vidioc_s_jpegcomp(cam, arg);
2350
2351 case VIDIOC_REQBUFS:
2352 return et61x251_vidioc_reqbufs(cam, arg);
2353
2354 case VIDIOC_QUERYBUF:
2355 return et61x251_vidioc_querybuf(cam, arg);
2356
2357 case VIDIOC_QBUF:
2358 return et61x251_vidioc_qbuf(cam, arg);
2359
2360 case VIDIOC_DQBUF:
2361 return et61x251_vidioc_dqbuf(cam, filp, arg);
2362
2363 case VIDIOC_STREAMON:
2364 return et61x251_vidioc_streamon(cam, arg);
2365
2366 case VIDIOC_STREAMOFF:
2367 return et61x251_vidioc_streamoff(cam, arg);
2368
2369 case VIDIOC_G_PARM:
2370 return et61x251_vidioc_g_parm(cam, arg);
2371
2372 case VIDIOC_S_PARM_OLD:
2373 case VIDIOC_S_PARM:
2374 return et61x251_vidioc_s_parm(cam, arg);
2375
2376 case VIDIOC_G_STD:
2377 case VIDIOC_S_STD:
2378 case VIDIOC_QUERYSTD:
2379 case VIDIOC_ENUMSTD:
2380 case VIDIOC_QUERYMENU:
2381 return -EINVAL;
2382
2383 default:
2384 return -EINVAL;
2385
2386 }
2387}
2388
2389
2390static int et61x251_ioctl(struct inode* inode, struct file* filp,
2391 unsigned int cmd, unsigned long arg)
2392{
2393 struct et61x251_device* cam = video_get_drvdata(video_devdata(filp));
2394 int err = 0;
2395
2396 if (down_interruptible(&cam->fileop_sem))
2397 return -ERESTARTSYS;
2398
2399 if (cam->state & DEV_DISCONNECTED) {
2400 DBG(1, "Device not present");
2401 up(&cam->fileop_sem);
2402 return -ENODEV;
2403 }
2404
2405 if (cam->state & DEV_MISCONFIGURED) {
2406 DBG(1, "The camera is misconfigured. Close and open it "
2407 "again.");
2408 up(&cam->fileop_sem);
2409 return -EIO;
2410 }
2411
2412 V4LDBG(3, "et61x251", cmd);
2413
2414 err = et61x251_ioctl_v4l2(inode, filp, cmd, (void __user *)arg);
2415
2416 up(&cam->fileop_sem);
2417
2418 return err;
2419}
2420
2421
2422static struct file_operations et61x251_fops = {
2423 .owner = THIS_MODULE,
2424 .open = et61x251_open,
2425 .release = et61x251_release,
2426 .ioctl = et61x251_ioctl,
2427 .read = et61x251_read,
2428 .poll = et61x251_poll,
2429 .mmap = et61x251_mmap,
2430 .llseek = no_llseek,
2431};
2432
2433/*****************************************************************************/
2434
2435/* It exists a single interface only. We do not need to validate anything. */
2436static int
2437et61x251_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
2438{
2439 struct usb_device *udev = interface_to_usbdev(intf);
2440 struct et61x251_device* cam;
2441 static unsigned int dev_nr = 0;
2442 unsigned int i;
2443 int err = 0;
2444
2445 if (!(cam = kzalloc(sizeof(struct et61x251_device), GFP_KERNEL)))
2446 return -ENOMEM;
2447
2448 cam->usbdev = udev;
2449
2450 if (!(cam->control_buffer = kzalloc(8, GFP_KERNEL))) {
2451 DBG(1, "kmalloc() failed");
2452 err = -ENOMEM;
2453 goto fail;
2454 }
2455
2456 if (!(cam->v4ldev = video_device_alloc())) {
2457 DBG(1, "video_device_alloc() failed");
2458 err = -ENOMEM;
2459 goto fail;
2460 }
2461
2462 init_MUTEX(&cam->dev_sem);
2463
2464 DBG(2, "ET61X[12]51 PC Camera Controller detected "
2465 "(vid/pid 0x%04X/0x%04X)",id->idVendor, id->idProduct);
2466
2467 for (i = 0; et61x251_sensor_table[i]; i++) {
2468 err = et61x251_sensor_table[i](cam);
2469 if (!err)
2470 break;
2471 }
2472
2473 if (!err && cam->sensor)
2474 DBG(2, "%s image sensor detected", cam->sensor->name);
2475 else {
2476 DBG(1, "No supported image sensor detected");
2477 err = -ENODEV;
2478 goto fail;
2479 }
2480
2481 if (et61x251_init(cam)) {
2482 DBG(1, "Initialization failed. I will retry on open().");
2483 cam->state |= DEV_MISCONFIGURED;
2484 }
2485
2486 strcpy(cam->v4ldev->name, "ET61X[12]51 PC Camera");
2487 cam->v4ldev->owner = THIS_MODULE;
2488 cam->v4ldev->type = VID_TYPE_CAPTURE | VID_TYPE_SCALES;
2489 cam->v4ldev->hardware = 0;
2490 cam->v4ldev->fops = &et61x251_fops;
2491 cam->v4ldev->minor = video_nr[dev_nr];
2492 cam->v4ldev->release = video_device_release;
2493 video_set_drvdata(cam->v4ldev, cam);
2494
2495 down(&cam->dev_sem);
2496
2497 err = video_register_device(cam->v4ldev, VFL_TYPE_GRABBER,
2498 video_nr[dev_nr]);
2499 if (err) {
2500 DBG(1, "V4L2 device registration failed");
2501 if (err == -ENFILE && video_nr[dev_nr] == -1)
2502 DBG(1, "Free /dev/videoX node not found");
2503 video_nr[dev_nr] = -1;
2504 dev_nr = (dev_nr < ET61X251_MAX_DEVICES-1) ? dev_nr+1 : 0;
2505 up(&cam->dev_sem);
2506 goto fail;
2507 }
2508
2509 DBG(2, "V4L2 device registered as /dev/video%d", cam->v4ldev->minor);
2510
2511 cam->module_param.force_munmap = force_munmap[dev_nr];
2512
2513 dev_nr = (dev_nr < ET61X251_MAX_DEVICES-1) ? dev_nr+1 : 0;
2514
2515#ifdef CONFIG_VIDEO_ADV_DEBUG
2516 et61x251_create_sysfs(cam);
2517 DBG(2, "Optional device control through 'sysfs' interface ready");
2518#endif
2519
2520 usb_set_intfdata(intf, cam);
2521
2522 up(&cam->dev_sem);
2523
2524 return 0;
2525
2526fail:
2527 if (cam) {
2528 kfree(cam->control_buffer);
2529 if (cam->v4ldev)
2530 video_device_release(cam->v4ldev);
2531 kfree(cam);
2532 }
2533 return err;
2534}
2535
2536
2537static void et61x251_usb_disconnect(struct usb_interface* intf)
2538{
2539 struct et61x251_device* cam = usb_get_intfdata(intf);
2540
2541 if (!cam)
2542 return;
2543
2544 down_write(&et61x251_disconnect);
2545
2546 down(&cam->dev_sem);
2547
2548 DBG(2, "Disconnecting %s...", cam->v4ldev->name);
2549
2550 wake_up_interruptible_all(&cam->open);
2551
2552 if (cam->users) {
2553 DBG(2, "Device /dev/video%d is open! Deregistration and "
2554 "memory deallocation are deferred on close.",
2555 cam->v4ldev->minor);
2556 cam->state |= DEV_MISCONFIGURED;
2557 et61x251_stop_transfer(cam);
2558 cam->state |= DEV_DISCONNECTED;
2559 wake_up_interruptible(&cam->wait_frame);
2560 wake_up_interruptible(&cam->wait_stream);
2561 } else {
2562 cam->state |= DEV_DISCONNECTED;
2563 et61x251_release_resources(cam);
2564 }
2565
2566 up(&cam->dev_sem);
2567
2568 if (!cam->users)
2569 kfree(cam);
2570
2571 up_write(&et61x251_disconnect);
2572}
2573
2574
2575static struct usb_driver et61x251_usb_driver = {
2576 .name = "et61x251",
2577 .id_table = et61x251_id_table,
2578 .probe = et61x251_usb_probe,
2579 .disconnect = et61x251_usb_disconnect,
2580};
2581
2582/*****************************************************************************/
2583
2584static int __init et61x251_module_init(void)
2585{
2586 int err = 0;
2587
2588 KDBG(2, ET61X251_MODULE_NAME " v" ET61X251_MODULE_VERSION);
2589 KDBG(3, ET61X251_MODULE_AUTHOR);
2590
2591 if ((err = usb_register(&et61x251_usb_driver)))
2592 KDBG(1, "usb_register() failed");
2593
2594 return err;
2595}
2596
2597
2598static void __exit et61x251_module_exit(void)
2599{
2600 usb_deregister(&et61x251_usb_driver);
2601}
2602
2603
2604module_init(et61x251_module_init);
2605module_exit(et61x251_module_exit);
diff --git a/drivers/usb/media/et61x251_sensor.h b/drivers/usb/media/et61x251_sensor.h
new file mode 100644
index 000000000000..b9df91062fc0
--- /dev/null
+++ b/drivers/usb/media/et61x251_sensor.h
@@ -0,0 +1,115 @@
1/***************************************************************************
2 * API for image sensors connected to ET61X[12]51 PC Camera Controllers *
3 * *
4 * Copyright (C) 2006 by Luca Risolia <luca.risolia@studio.unibo.it> *
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#ifndef _ET61X251_SENSOR_H_
22#define _ET61X251_SENSOR_H_
23
24#include <linux/usb.h>
25#include <linux/videodev.h>
26#include <linux/device.h>
27#include <linux/stddef.h>
28#include <linux/errno.h>
29#include <asm/types.h>
30
31struct et61x251_device;
32struct et61x251_sensor;
33
34/*****************************************************************************/
35
36extern int et61x251_probe_tas5130d1b(struct et61x251_device* cam);
37
38#define ET61X251_SENSOR_TABLE \
39/* Weak detections must go at the end of the list */ \
40static int (*et61x251_sensor_table[])(struct et61x251_device*) = { \
41 &et61x251_probe_tas5130d1b, \
42 NULL, \
43};
44
45extern void
46et61x251_attach_sensor(struct et61x251_device* cam,
47 struct et61x251_sensor* sensor);
48
49/*****************************************************************************/
50
51extern int et61x251_write_reg(struct et61x251_device*, u8 value, u16 index);
52extern int et61x251_read_reg(struct et61x251_device*, u16 index);
53extern int et61x251_i2c_write(struct et61x251_device*, u8 address, u8 value);
54extern int et61x251_i2c_read(struct et61x251_device*, u8 address);
55extern int et61x251_i2c_try_write(struct et61x251_device*,
56 struct et61x251_sensor*, u8 address,
57 u8 value);
58extern int et61x251_i2c_try_read(struct et61x251_device*,
59 struct et61x251_sensor*, u8 address);
60extern int et61x251_i2c_raw_write(struct et61x251_device*, u8 n, u8 data1,
61 u8 data2, u8 data3, u8 data4, u8 data5,
62 u8 data6, u8 data7, u8 data8, u8 address);
63
64/*****************************************************************************/
65
66enum et61x251_i2c_sysfs_ops {
67 ET61X251_I2C_READ = 0x01,
68 ET61X251_I2C_WRITE = 0x02,
69};
70
71enum et61x251_i2c_interface {
72 ET61X251_I2C_2WIRES,
73 ET61X251_I2C_3WIRES,
74};
75
76/* Repeat start condition when RSTA is high */
77enum et61x251_i2c_rsta {
78 ET61X251_I2C_RSTA_STOP = 0x00, /* stop then start */
79 ET61X251_I2C_RSTA_REPEAT = 0x01, /* repeat start */
80};
81
82#define ET61X251_MAX_CTRLS V4L2_CID_LASTP1-V4L2_CID_BASE+10
83
84struct et61x251_sensor {
85 char name[32];
86
87 enum et61x251_i2c_sysfs_ops sysfs_ops;
88
89 enum et61x251_i2c_interface interface;
90 u8 i2c_slave_id;
91 enum et61x251_i2c_rsta rsta;
92 struct v4l2_rect active_pixel; /* left and top define FVSX and FVSY */
93
94 struct v4l2_queryctrl qctrl[ET61X251_MAX_CTRLS];
95 struct v4l2_cropcap cropcap;
96 struct v4l2_pix_format pix_format;
97
98 int (*init)(struct et61x251_device* cam);
99 int (*get_ctrl)(struct et61x251_device* cam,
100 struct v4l2_control* ctrl);
101 int (*set_ctrl)(struct et61x251_device* cam,
102 const struct v4l2_control* ctrl);
103 int (*set_crop)(struct et61x251_device* cam,
104 const struct v4l2_rect* rect);
105 int (*set_pix_format)(struct et61x251_device* cam,
106 const struct v4l2_pix_format* pix);
107
108 const struct usb_device* usbdev;
109
110 /* Private */
111 struct v4l2_queryctrl _qctrl[ET61X251_MAX_CTRLS];
112 struct v4l2_rect _rect;
113};
114
115#endif /* _ET61X251_SENSOR_H_ */
diff --git a/drivers/usb/media/et61x251_tas5130d1b.c b/drivers/usb/media/et61x251_tas5130d1b.c
new file mode 100644
index 000000000000..65f1ae9cf2b3
--- /dev/null
+++ b/drivers/usb/media/et61x251_tas5130d1b.c
@@ -0,0 +1,137 @@
1/***************************************************************************
2 * Plug-in for TAS5130D1B image sensor connected to the ET61X[12]51 *
3 * PC Camera Controllers *
4 * *
5 * Copyright (C) 2006 by Luca Risolia <luca.risolia@studio.unibo.it> *
6 * *
7 * This program is free software; you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation; either version 2 of the License, or *
10 * (at your option) any later version. *
11 * *
12 * This program is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU General Public License for more details. *
16 * *
17 * You should have received a copy of the GNU General Public License *
18 * along with this program; if not, write to the Free Software *
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
20 ***************************************************************************/
21
22#include "et61x251_sensor.h"
23
24
25static int tas5130d1b_init(struct et61x251_device* cam)
26{
27 int err = 0;
28
29 err += et61x251_write_reg(cam, 0x14, 0x01);
30 err += et61x251_write_reg(cam, 0x1b, 0x02);
31 err += et61x251_write_reg(cam, 0x02, 0x12);
32 err += et61x251_write_reg(cam, 0x0e, 0x60);
33 err += et61x251_write_reg(cam, 0x80, 0x61);
34 err += et61x251_write_reg(cam, 0xf0, 0x62);
35 err += et61x251_write_reg(cam, 0x03, 0x63);
36 err += et61x251_write_reg(cam, 0x14, 0x64);
37 err += et61x251_write_reg(cam, 0xf4, 0x65);
38 err += et61x251_write_reg(cam, 0x01, 0x66);
39 err += et61x251_write_reg(cam, 0x05, 0x67);
40 err += et61x251_write_reg(cam, 0x8f, 0x68);
41 err += et61x251_write_reg(cam, 0x0f, 0x8d);
42 err += et61x251_write_reg(cam, 0x08, 0x8e);
43
44 return err;
45}
46
47
48static int tas5130d1b_set_ctrl(struct et61x251_device* cam,
49 const struct v4l2_control* ctrl)
50{
51 int err = 0;
52
53 switch (ctrl->id) {
54 case V4L2_CID_GAIN:
55 err += et61x251_i2c_raw_write(cam, 2, 0x20,
56 0xf6-ctrl->value, 0, 0, 0,
57 0, 0, 0, 0);
58 break;
59 case V4L2_CID_EXPOSURE:
60 err += et61x251_i2c_raw_write(cam, 2, 0x40,
61 0x47-ctrl->value, 0, 0, 0,
62 0, 0, 0, 0);
63 break;
64 default:
65 return -EINVAL;
66 }
67
68 return err ? -EIO : 0;
69}
70
71
72static struct et61x251_sensor tas5130d1b = {
73 .name = "TAS5130D1B",
74 .interface = ET61X251_I2C_3WIRES,
75 .rsta = ET61X251_I2C_RSTA_STOP,
76 .active_pixel = {
77 .left = 106,
78 .top = 13,
79 },
80 .init = &tas5130d1b_init,
81 .qctrl = {
82 {
83 .id = V4L2_CID_GAIN,
84 .type = V4L2_CTRL_TYPE_INTEGER,
85 .name = "global gain",
86 .minimum = 0x00,
87 .maximum = 0xf6,
88 .step = 0x02,
89 .default_value = 0x0d,
90 .flags = 0,
91 },
92 {
93 .id = V4L2_CID_EXPOSURE,
94 .type = V4L2_CTRL_TYPE_INTEGER,
95 .name = "exposure",
96 .minimum = 0x00,
97 .maximum = 0x47,
98 .step = 0x01,
99 .default_value = 0x23,
100 .flags = 0,
101 },
102 },
103 .set_ctrl = &tas5130d1b_set_ctrl,
104 .cropcap = {
105 .bounds = {
106 .left = 0,
107 .top = 0,
108 .width = 640,
109 .height = 480,
110 },
111 .defrect = {
112 .left = 0,
113 .top = 0,
114 .width = 640,
115 .height = 480,
116 },
117 },
118 .pix_format = {
119 .width = 640,
120 .height = 480,
121 .pixelformat = V4L2_PIX_FMT_SBGGR8,
122 .priv = 8,
123 },
124};
125
126
127int et61x251_probe_tas5130d1b(struct et61x251_device* cam)
128{
129 /* This sensor has no identifiers, so let's attach it anyway */
130 et61x251_attach_sensor(cam, &tas5130d1b);
131
132 /* Sensor detection is based on USB pid/vid */
133 if (le16_to_cpu(tas5130d1b.usbdev->descriptor.idProduct) != 0x6251)
134 return -ENODEV;
135
136 return 0;
137}
diff --git a/drivers/usb/media/ov511.c b/drivers/usb/media/ov511.c
index 8af665bbe330..51e9cc06f7e3 100644
--- a/drivers/usb/media/ov511.c
+++ b/drivers/usb/media/ov511.c
@@ -204,22 +204,10 @@ MODULE_LICENSE("GPL");
204 204
205static struct usb_driver ov511_driver; 205static struct usb_driver ov511_driver;
206 206
207static struct ov51x_decomp_ops *ov511_decomp_ops;
208static struct ov51x_decomp_ops *ov511_mmx_decomp_ops;
209static struct ov51x_decomp_ops *ov518_decomp_ops;
210static struct ov51x_decomp_ops *ov518_mmx_decomp_ops;
211
212/* Number of times to retry a failed I2C transaction. Increase this if you 207/* Number of times to retry a failed I2C transaction. Increase this if you
213 * are getting "Failed to read sensor ID..." */ 208 * are getting "Failed to read sensor ID..." */
214static const int i2c_detect_tries = 5; 209static const int i2c_detect_tries = 5;
215 210
216/* MMX support is present in kernel and CPU. Checked upon decomp module load. */
217#if defined(__i386__) || defined(__x86_64__)
218#define ov51x_mmx_available (cpu_has_mmx)
219#else
220#define ov51x_mmx_available (0)
221#endif
222
223static struct usb_device_id device_table [] = { 211static struct usb_device_id device_table [] = {
224 { USB_DEVICE(VEND_OMNIVISION, PROD_OV511) }, 212 { USB_DEVICE(VEND_OMNIVISION, PROD_OV511) },
225 { USB_DEVICE(VEND_OMNIVISION, PROD_OV511PLUS) }, 213 { USB_DEVICE(VEND_OMNIVISION, PROD_OV511PLUS) },
@@ -3012,93 +3000,18 @@ yuv420raw_to_yuv420p(struct ov511_frame *frame,
3012 * 3000 *
3013 **********************************************************************/ 3001 **********************************************************************/
3014 3002
3015/* Chooses a decompression module, locks it, and sets ov->decomp_ops
3016 * accordingly. Returns -ENXIO if decompressor is not available, otherwise
3017 * returns 0 if no other error.
3018 */
3019static int 3003static int
3020request_decompressor(struct usb_ov511 *ov) 3004request_decompressor(struct usb_ov511 *ov)
3021{ 3005{
3022 if (!ov) 3006 if (ov->bclass == BCL_OV511 || ov->bclass == BCL_OV518) {
3023 return -ENODEV; 3007 err("No decompressor available");
3024
3025 if (ov->decomp_ops) {
3026 err("ERROR: Decompressor already requested!");
3027 return -EINVAL;
3028 }
3029
3030 lock_kernel();
3031
3032 /* Try to get MMX, and fall back on no-MMX if necessary */
3033 if (ov->bclass == BCL_OV511) {
3034 if (ov511_mmx_decomp_ops) {
3035 PDEBUG(3, "Using OV511 MMX decompressor");
3036 ov->decomp_ops = ov511_mmx_decomp_ops;
3037 } else if (ov511_decomp_ops) {
3038 PDEBUG(3, "Using OV511 decompressor");
3039 ov->decomp_ops = ov511_decomp_ops;
3040 } else {
3041 err("No decompressor available");
3042 }
3043 } else if (ov->bclass == BCL_OV518) {
3044 if (ov518_mmx_decomp_ops) {
3045 PDEBUG(3, "Using OV518 MMX decompressor");
3046 ov->decomp_ops = ov518_mmx_decomp_ops;
3047 } else if (ov518_decomp_ops) {
3048 PDEBUG(3, "Using OV518 decompressor");
3049 ov->decomp_ops = ov518_decomp_ops;
3050 } else {
3051 err("No decompressor available");
3052 }
3053 } else { 3008 } else {
3054 err("Unknown bridge"); 3009 err("Unknown bridge");
3055 } 3010 }
3056 3011
3057 if (!ov->decomp_ops)
3058 goto nosys;
3059
3060 if (!ov->decomp_ops->owner) {
3061 ov->decomp_ops = NULL;
3062 goto nosys;
3063 }
3064
3065 if (!try_module_get(ov->decomp_ops->owner))
3066 goto nosys;
3067
3068 unlock_kernel();
3069 return 0;
3070
3071 nosys:
3072 unlock_kernel();
3073 return -ENOSYS; 3012 return -ENOSYS;
3074} 3013}
3075 3014
3076/* Unlocks decompression module and nulls ov->decomp_ops. Safe to call even
3077 * if ov->decomp_ops is NULL.
3078 */
3079static void
3080release_decompressor(struct usb_ov511 *ov)
3081{
3082 int released = 0; /* Did we actually do anything? */
3083
3084 if (!ov)
3085 return;
3086
3087 lock_kernel();
3088
3089 if (ov->decomp_ops) {
3090 module_put(ov->decomp_ops->owner);
3091 released = 1;
3092 }
3093
3094 ov->decomp_ops = NULL;
3095
3096 unlock_kernel();
3097
3098 if (released)
3099 PDEBUG(3, "Decompressor released");
3100}
3101
3102static void 3015static void
3103decompress(struct usb_ov511 *ov, struct ov511_frame *frame, 3016decompress(struct usb_ov511 *ov, struct ov511_frame *frame,
3104 unsigned char *pIn0, unsigned char *pOut0) 3017 unsigned char *pIn0, unsigned char *pOut0)
@@ -3107,31 +3020,6 @@ decompress(struct usb_ov511 *ov, struct ov511_frame *frame,
3107 if (request_decompressor(ov)) 3020 if (request_decompressor(ov))
3108 return; 3021 return;
3109 3022
3110 PDEBUG(4, "Decompressing %d bytes", frame->bytes_recvd);
3111
3112 if (frame->format == VIDEO_PALETTE_GREY
3113 && ov->decomp_ops->decomp_400) {
3114 int ret = ov->decomp_ops->decomp_400(
3115 pIn0,
3116 pOut0,
3117 frame->compbuf,
3118 frame->rawwidth,
3119 frame->rawheight,
3120 frame->bytes_recvd);
3121 PDEBUG(4, "DEBUG: decomp_400 returned %d", ret);
3122 } else if (frame->format != VIDEO_PALETTE_GREY
3123 && ov->decomp_ops->decomp_420) {
3124 int ret = ov->decomp_ops->decomp_420(
3125 pIn0,
3126 pOut0,
3127 frame->compbuf,
3128 frame->rawwidth,
3129 frame->rawheight,
3130 frame->bytes_recvd);
3131 PDEBUG(4, "DEBUG: decomp_420 returned %d", ret);
3132 } else {
3133 err("Decompressor does not support this format");
3134 }
3135} 3023}
3136 3024
3137/********************************************************************** 3025/**********************************************************************
@@ -4087,8 +3975,6 @@ ov51x_v4l1_close(struct inode *inode, struct file *file)
4087 ov->user--; 3975 ov->user--;
4088 ov51x_stop_isoc(ov); 3976 ov51x_stop_isoc(ov);
4089 3977
4090 release_decompressor(ov);
4091
4092 if (ov->led_policy == LED_AUTO) 3978 if (ov->led_policy == LED_AUTO)
4093 ov51x_led_control(ov, 0); 3979 ov51x_led_control(ov, 0);
4094 3980
@@ -6021,82 +5907,6 @@ static struct usb_driver ov511_driver = {
6021 * 5907 *
6022 ***************************************************************************/ 5908 ***************************************************************************/
6023 5909
6024/* Returns 0 for success */
6025int
6026ov511_register_decomp_module(int ver, struct ov51x_decomp_ops *ops, int ov518,
6027 int mmx)
6028{
6029 if (ver != DECOMP_INTERFACE_VER) {
6030 err("Decompression module has incompatible");
6031 err("interface version %d", ver);
6032 err("Interface version %d is required", DECOMP_INTERFACE_VER);
6033 return -EINVAL;
6034 }
6035
6036 if (!ops)
6037 return -EFAULT;
6038
6039 if (mmx && !ov51x_mmx_available) {
6040 err("MMX not available on this system or kernel");
6041 return -EINVAL;
6042 }
6043
6044 lock_kernel();
6045
6046 if (ov518) {
6047 if (mmx) {
6048 if (ov518_mmx_decomp_ops)
6049 goto err_in_use;
6050 else
6051 ov518_mmx_decomp_ops = ops;
6052 } else {
6053 if (ov518_decomp_ops)
6054 goto err_in_use;
6055 else
6056 ov518_decomp_ops = ops;
6057 }
6058 } else {
6059 if (mmx) {
6060 if (ov511_mmx_decomp_ops)
6061 goto err_in_use;
6062 else
6063 ov511_mmx_decomp_ops = ops;
6064 } else {
6065 if (ov511_decomp_ops)
6066 goto err_in_use;
6067 else
6068 ov511_decomp_ops = ops;
6069 }
6070 }
6071
6072 unlock_kernel();
6073 return 0;
6074
6075err_in_use:
6076 unlock_kernel();
6077 return -EBUSY;
6078}
6079
6080void
6081ov511_deregister_decomp_module(int ov518, int mmx)
6082{
6083 lock_kernel();
6084
6085 if (ov518) {
6086 if (mmx)
6087 ov518_mmx_decomp_ops = NULL;
6088 else
6089 ov518_decomp_ops = NULL;
6090 } else {
6091 if (mmx)
6092 ov511_mmx_decomp_ops = NULL;
6093 else
6094 ov511_decomp_ops = NULL;
6095 }
6096
6097 unlock_kernel();
6098}
6099
6100static int __init 5910static int __init
6101usb_ov511_init(void) 5911usb_ov511_init(void)
6102{ 5912{
@@ -6123,5 +5933,3 @@ usb_ov511_exit(void)
6123module_init(usb_ov511_init); 5933module_init(usb_ov511_init);
6124module_exit(usb_ov511_exit); 5934module_exit(usb_ov511_exit);
6125 5935
6126EXPORT_SYMBOL(ov511_register_decomp_module);
6127EXPORT_SYMBOL(ov511_deregister_decomp_module);
diff --git a/drivers/usb/media/pwc/pwc-ctrl.c b/drivers/usb/media/pwc/pwc-ctrl.c
index 359c4b2df735..3ebb6e9cdf92 100644
--- a/drivers/usb/media/pwc/pwc-ctrl.c
+++ b/drivers/usb/media/pwc/pwc-ctrl.c
@@ -1152,45 +1152,6 @@ int pwc_get_cmos_sensor(struct pwc_device *pdev, int *sensor)
1152 /* End of Add-Ons */ 1152 /* End of Add-Ons */
1153 /* ************************************************* */ 1153 /* ************************************************* */
1154 1154
1155/* Linux 2.5.something and 2.6 pass direct pointers to arguments of
1156 ioctl() calls. With 2.4, you have to do tedious copy_from_user()
1157 and copy_to_user() calls. With these macros we circumvent this,
1158 and let me maintain only one source file. The functionality is
1159 exactly the same otherwise.
1160 */
1161
1162#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
1163
1164/* define local variable for arg */
1165#define ARG_DEF(ARG_type, ARG_name)\
1166 ARG_type *ARG_name = arg;
1167/* copy arg to local variable */
1168#define ARG_IN(ARG_name) /* nothing */
1169/* argument itself (referenced) */
1170#define ARGR(ARG_name) (*ARG_name)
1171/* argument address */
1172#define ARGA(ARG_name) ARG_name
1173/* copy local variable to arg */
1174#define ARG_OUT(ARG_name) /* nothing */
1175
1176#else
1177
1178#define ARG_DEF(ARG_type, ARG_name)\
1179 ARG_type ARG_name;
1180#define ARG_IN(ARG_name)\
1181 if (copy_from_user(&ARG_name, arg, sizeof(ARG_name))) {\
1182 ret = -EFAULT;\
1183 break;\
1184 }
1185#define ARGR(ARG_name) ARG_name
1186#define ARGA(ARG_name) &ARG_name
1187#define ARG_OUT(ARG_name)\
1188 if (copy_to_user(arg, &ARG_name, sizeof(ARG_name))) {\
1189 ret = -EFAULT;\
1190 break;\
1191 }
1192
1193#endif
1194 1155
1195int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg) 1156int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg)
1196{ 1157{
@@ -1220,243 +1181,206 @@ int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg)
1220 1181
1221 case VIDIOCPWCSCQUAL: 1182 case VIDIOCPWCSCQUAL:
1222 { 1183 {
1223 ARG_DEF(int, qual) 1184 int *qual = arg;
1224 1185
1225 ARG_IN(qual) 1186 if (*qual < 0 || *qual > 3)
1226 if (ARGR(qual) < 0 || ARGR(qual) > 3)
1227 ret = -EINVAL; 1187 ret = -EINVAL;
1228 else 1188 else
1229 ret = pwc_try_video_mode(pdev, pdev->view.x, pdev->view.y, pdev->vframes, ARGR(qual), pdev->vsnapshot); 1189 ret = pwc_try_video_mode(pdev, pdev->view.x, pdev->view.y, pdev->vframes, *qual, pdev->vsnapshot);
1230 if (ret >= 0) 1190 if (ret >= 0)
1231 pdev->vcompression = ARGR(qual); 1191 pdev->vcompression = *qual;
1232 break; 1192 break;
1233 } 1193 }
1234 1194
1235 case VIDIOCPWCGCQUAL: 1195 case VIDIOCPWCGCQUAL:
1236 { 1196 {
1237 ARG_DEF(int, qual) 1197 int *qual = arg;
1238 1198 *qual = pdev->vcompression;
1239 ARGR(qual) = pdev->vcompression;
1240 ARG_OUT(qual)
1241 break; 1199 break;
1242 } 1200 }
1243 1201
1244 case VIDIOCPWCPROBE: 1202 case VIDIOCPWCPROBE:
1245 { 1203 {
1246 ARG_DEF(struct pwc_probe, probe) 1204 struct pwc_probe *probe = arg;
1247 1205 strcpy(probe->name, pdev->vdev->name);
1248 strcpy(ARGR(probe).name, pdev->vdev->name); 1206 probe->type = pdev->type;
1249 ARGR(probe).type = pdev->type;
1250 ARG_OUT(probe)
1251 break; 1207 break;
1252 } 1208 }
1253 1209
1254 case VIDIOCPWCGSERIAL: 1210 case VIDIOCPWCGSERIAL:
1255 { 1211 {
1256 ARG_DEF(struct pwc_serial, serial) 1212 struct pwc_serial *serial = arg;
1257 1213 strcpy(serial->serial, pdev->serial);
1258 strcpy(ARGR(serial).serial, pdev->serial);
1259 ARG_OUT(serial)
1260 break; 1214 break;
1261 } 1215 }
1262 1216
1263 case VIDIOCPWCSAGC: 1217 case VIDIOCPWCSAGC:
1264 { 1218 {
1265 ARG_DEF(int, agc) 1219 int *agc = arg;
1266 1220 if (pwc_set_agc(pdev, *agc < 0 ? 1 : 0, *agc))
1267 ARG_IN(agc)
1268 if (pwc_set_agc(pdev, ARGR(agc) < 0 ? 1 : 0, ARGR(agc)))
1269 ret = -EINVAL; 1221 ret = -EINVAL;
1270 break; 1222 break;
1271 } 1223 }
1272 1224
1273 case VIDIOCPWCGAGC: 1225 case VIDIOCPWCGAGC:
1274 { 1226 {
1275 ARG_DEF(int, agc) 1227 int *agc = arg;
1276 1228
1277 if (pwc_get_agc(pdev, ARGA(agc))) 1229 if (pwc_get_agc(pdev, agc))
1278 ret = -EINVAL; 1230 ret = -EINVAL;
1279 ARG_OUT(agc)
1280 break; 1231 break;
1281 } 1232 }
1282 1233
1283 case VIDIOCPWCSSHUTTER: 1234 case VIDIOCPWCSSHUTTER:
1284 { 1235 {
1285 ARG_DEF(int, shutter_speed) 1236 int *shutter_speed = arg;
1286 1237 ret = pwc_set_shutter_speed(pdev, *shutter_speed < 0 ? 1 : 0, *shutter_speed);
1287 ARG_IN(shutter_speed)
1288 ret = pwc_set_shutter_speed(pdev, ARGR(shutter_speed) < 0 ? 1 : 0, ARGR(shutter_speed));
1289 break; 1238 break;
1290 } 1239 }
1291 1240
1292 case VIDIOCPWCSAWB: 1241 case VIDIOCPWCSAWB:
1293 { 1242 {
1294 ARG_DEF(struct pwc_whitebalance, wb) 1243 struct pwc_whitebalance *wb = arg;
1295 1244
1296 ARG_IN(wb) 1245 ret = pwc_set_awb(pdev, wb->mode);
1297 ret = pwc_set_awb(pdev, ARGR(wb).mode); 1246 if (ret >= 0 && wb->mode == PWC_WB_MANUAL) {
1298 if (ret >= 0 && ARGR(wb).mode == PWC_WB_MANUAL) { 1247 pwc_set_red_gain(pdev, wb->manual_red);
1299 pwc_set_red_gain(pdev, ARGR(wb).manual_red); 1248 pwc_set_blue_gain(pdev, wb->manual_blue);
1300 pwc_set_blue_gain(pdev, ARGR(wb).manual_blue);
1301 } 1249 }
1302 break; 1250 break;
1303 } 1251 }
1304 1252
1305 case VIDIOCPWCGAWB: 1253 case VIDIOCPWCGAWB:
1306 { 1254 {
1307 ARG_DEF(struct pwc_whitebalance, wb) 1255 struct pwc_whitebalance *wb = arg;
1308 1256
1309 memset(ARGA(wb), 0, sizeof(struct pwc_whitebalance)); 1257 memset(wb, 0, sizeof(struct pwc_whitebalance));
1310 ARGR(wb).mode = pwc_get_awb(pdev); 1258 wb->mode = pwc_get_awb(pdev);
1311 if (ARGR(wb).mode < 0) 1259 if (wb->mode < 0)
1312 ret = -EINVAL; 1260 ret = -EINVAL;
1313 else { 1261 else {
1314 if (ARGR(wb).mode == PWC_WB_MANUAL) { 1262 if (wb->mode == PWC_WB_MANUAL) {
1315 ret = pwc_get_red_gain(pdev, &ARGR(wb).manual_red); 1263 ret = pwc_get_red_gain(pdev, &wb->manual_red);
1316 if (ret < 0) 1264 if (ret < 0)
1317 break; 1265 break;
1318 ret = pwc_get_blue_gain(pdev, &ARGR(wb).manual_blue); 1266 ret = pwc_get_blue_gain(pdev, &wb->manual_blue);
1319 if (ret < 0) 1267 if (ret < 0)
1320 break; 1268 break;
1321 } 1269 }
1322 if (ARGR(wb).mode == PWC_WB_AUTO) { 1270 if (wb->mode == PWC_WB_AUTO) {
1323 ret = pwc_read_red_gain(pdev, &ARGR(wb).read_red); 1271 ret = pwc_read_red_gain(pdev, &wb->read_red);
1324 if (ret < 0) 1272 if (ret < 0)
1325 break; 1273 break;
1326 ret =pwc_read_blue_gain(pdev, &ARGR(wb).read_blue); 1274 ret = pwc_read_blue_gain(pdev, &wb->read_blue);
1327 if (ret < 0) 1275 if (ret < 0)
1328 break; 1276 break;
1329 } 1277 }
1330 } 1278 }
1331 ARG_OUT(wb)
1332 break; 1279 break;
1333 } 1280 }
1334 1281
1335 case VIDIOCPWCSAWBSPEED: 1282 case VIDIOCPWCSAWBSPEED:
1336 { 1283 {
1337 ARG_DEF(struct pwc_wb_speed, wbs) 1284 struct pwc_wb_speed *wbs = arg;
1338 1285
1339 if (ARGR(wbs).control_speed > 0) { 1286 if (wbs->control_speed > 0) {
1340 ret = pwc_set_wb_speed(pdev, ARGR(wbs).control_speed); 1287 ret = pwc_set_wb_speed(pdev, wbs->control_speed);
1341 } 1288 }
1342 if (ARGR(wbs).control_delay > 0) { 1289 if (wbs->control_delay > 0) {
1343 ret = pwc_set_wb_delay(pdev, ARGR(wbs).control_delay); 1290 ret = pwc_set_wb_delay(pdev, wbs->control_delay);
1344 } 1291 }
1345 break; 1292 break;
1346 } 1293 }
1347 1294
1348 case VIDIOCPWCGAWBSPEED: 1295 case VIDIOCPWCGAWBSPEED:
1349 { 1296 {
1350 ARG_DEF(struct pwc_wb_speed, wbs) 1297 struct pwc_wb_speed *wbs = arg;
1351 1298
1352 ret = pwc_get_wb_speed(pdev, &ARGR(wbs).control_speed); 1299 ret = pwc_get_wb_speed(pdev, &wbs->control_speed);
1353 if (ret < 0) 1300 if (ret < 0)
1354 break; 1301 break;
1355 ret = pwc_get_wb_delay(pdev, &ARGR(wbs).control_delay); 1302 ret = pwc_get_wb_delay(pdev, &wbs->control_delay);
1356 if (ret < 0) 1303 if (ret < 0)
1357 break; 1304 break;
1358 ARG_OUT(wbs)
1359 break; 1305 break;
1360 } 1306 }
1361 1307
1362 case VIDIOCPWCSLED: 1308 case VIDIOCPWCSLED:
1363 { 1309 {
1364 ARG_DEF(struct pwc_leds, leds) 1310 struct pwc_leds *leds = arg;
1365 1311 ret = pwc_set_leds(pdev, leds->led_on, leds->led_off);
1366 ARG_IN(leds)
1367 ret = pwc_set_leds(pdev, ARGR(leds).led_on, ARGR(leds).led_off);
1368 break; 1312 break;
1369 } 1313 }
1370 1314
1371 1315
1372 case VIDIOCPWCGLED: 1316 case VIDIOCPWCGLED:
1373 { 1317 {
1374 ARG_DEF(struct pwc_leds, leds) 1318 struct pwc_leds *leds = arg;
1375 1319 ret = pwc_get_leds(pdev, &leds->led_on, &leds->led_off);
1376 ret = pwc_get_leds(pdev, &ARGR(leds).led_on, &ARGR(leds).led_off);
1377 ARG_OUT(leds)
1378 break; 1320 break;
1379 } 1321 }
1380 1322
1381 case VIDIOCPWCSCONTOUR: 1323 case VIDIOCPWCSCONTOUR:
1382 { 1324 {
1383 ARG_DEF(int, contour) 1325 int *contour = arg;
1384 1326 ret = pwc_set_contour(pdev, *contour);
1385 ARG_IN(contour)
1386 ret = pwc_set_contour(pdev, ARGR(contour));
1387 break; 1327 break;
1388 } 1328 }
1389 1329
1390 case VIDIOCPWCGCONTOUR: 1330 case VIDIOCPWCGCONTOUR:
1391 { 1331 {
1392 ARG_DEF(int, contour) 1332 int *contour = arg;
1393 1333 ret = pwc_get_contour(pdev, contour);
1394 ret = pwc_get_contour(pdev, ARGA(contour));
1395 ARG_OUT(contour)
1396 break; 1334 break;
1397 } 1335 }
1398 1336
1399 case VIDIOCPWCSBACKLIGHT: 1337 case VIDIOCPWCSBACKLIGHT:
1400 { 1338 {
1401 ARG_DEF(int, backlight) 1339 int *backlight = arg;
1402 1340 ret = pwc_set_backlight(pdev, *backlight);
1403 ARG_IN(backlight)
1404 ret = pwc_set_backlight(pdev, ARGR(backlight));
1405 break; 1341 break;
1406 } 1342 }
1407 1343
1408 case VIDIOCPWCGBACKLIGHT: 1344 case VIDIOCPWCGBACKLIGHT:
1409 { 1345 {
1410 ARG_DEF(int, backlight) 1346 int *backlight = arg;
1411 1347 ret = pwc_get_backlight(pdev, backlight);
1412 ret = pwc_get_backlight(pdev, ARGA(backlight));
1413 ARG_OUT(backlight)
1414 break; 1348 break;
1415 } 1349 }
1416 1350
1417 case VIDIOCPWCSFLICKER: 1351 case VIDIOCPWCSFLICKER:
1418 { 1352 {
1419 ARG_DEF(int, flicker) 1353 int *flicker = arg;
1420 1354 ret = pwc_set_flicker(pdev, *flicker);
1421 ARG_IN(flicker)
1422 ret = pwc_set_flicker(pdev, ARGR(flicker));
1423 break; 1355 break;
1424 } 1356 }
1425 1357
1426 case VIDIOCPWCGFLICKER: 1358 case VIDIOCPWCGFLICKER:
1427 { 1359 {
1428 ARG_DEF(int, flicker) 1360 int *flicker = arg;
1429 1361 ret = pwc_get_flicker(pdev, flicker);
1430 ret = pwc_get_flicker(pdev, ARGA(flicker));
1431 ARG_OUT(flicker)
1432 break; 1362 break;
1433 } 1363 }
1434 1364
1435 case VIDIOCPWCSDYNNOISE: 1365 case VIDIOCPWCSDYNNOISE:
1436 { 1366 {
1437 ARG_DEF(int, dynnoise) 1367 int *dynnoise = arg;
1438 1368 ret = pwc_set_dynamic_noise(pdev, *dynnoise);
1439 ARG_IN(dynnoise)
1440 ret = pwc_set_dynamic_noise(pdev, ARGR(dynnoise));
1441 break; 1369 break;
1442 } 1370 }
1443 1371
1444 case VIDIOCPWCGDYNNOISE: 1372 case VIDIOCPWCGDYNNOISE:
1445 { 1373 {
1446 ARG_DEF(int, dynnoise) 1374 int *dynnoise = arg;
1447 1375 ret = pwc_get_dynamic_noise(pdev, dynnoise);
1448 ret = pwc_get_dynamic_noise(pdev, ARGA(dynnoise));
1449 ARG_OUT(dynnoise);
1450 break; 1376 break;
1451 } 1377 }
1452 1378
1453 case VIDIOCPWCGREALSIZE: 1379 case VIDIOCPWCGREALSIZE:
1454 { 1380 {
1455 ARG_DEF(struct pwc_imagesize, size) 1381 struct pwc_imagesize *size = arg;
1456 1382 size->width = pdev->image.x;
1457 ARGR(size).width = pdev->image.x; 1383 size->height = pdev->image.y;
1458 ARGR(size).height = pdev->image.y;
1459 ARG_OUT(size)
1460 break; 1384 break;
1461 } 1385 }
1462 1386
@@ -1464,10 +1388,9 @@ int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg)
1464 { 1388 {
1465 if (pdev->features & FEATURE_MOTOR_PANTILT) 1389 if (pdev->features & FEATURE_MOTOR_PANTILT)
1466 { 1390 {
1467 ARG_DEF(int, flags) 1391 int *flags = arg;
1468 1392
1469 ARG_IN(flags) 1393 ret = pwc_mpt_reset(pdev, *flags);
1470 ret = pwc_mpt_reset(pdev, ARGR(flags));
1471 if (ret >= 0) 1394 if (ret >= 0)
1472 { 1395 {
1473 pdev->pan_angle = 0; 1396 pdev->pan_angle = 0;
@@ -1485,10 +1408,8 @@ int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg)
1485 { 1408 {
1486 if (pdev->features & FEATURE_MOTOR_PANTILT) 1409 if (pdev->features & FEATURE_MOTOR_PANTILT)
1487 { 1410 {
1488 ARG_DEF(struct pwc_mpt_range, range) 1411 struct pwc_mpt_range *range = arg;
1489 1412 *range = pdev->angle_range;
1490 ARGR(range) = pdev->angle_range;
1491 ARG_OUT(range)
1492 } 1413 }
1493 else 1414 else
1494 { 1415 {
@@ -1503,21 +1424,19 @@ int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg)
1503 1424
1504 if (pdev->features & FEATURE_MOTOR_PANTILT) 1425 if (pdev->features & FEATURE_MOTOR_PANTILT)
1505 { 1426 {
1506 ARG_DEF(struct pwc_mpt_angles, angles) 1427 struct pwc_mpt_angles *angles = arg;
1507
1508 ARG_IN(angles)
1509 /* The camera can only set relative angles, so 1428 /* The camera can only set relative angles, so
1510 do some calculations when getting an absolute angle . 1429 do some calculations when getting an absolute angle .
1511 */ 1430 */
1512 if (ARGR(angles).absolute) 1431 if (angles->absolute)
1513 { 1432 {
1514 new_pan = ARGR(angles).pan; 1433 new_pan = angles->pan;
1515 new_tilt = ARGR(angles).tilt; 1434 new_tilt = angles->tilt;
1516 } 1435 }
1517 else 1436 else
1518 { 1437 {
1519 new_pan = pdev->pan_angle + ARGR(angles).pan; 1438 new_pan = pdev->pan_angle + angles->pan;
1520 new_tilt = pdev->tilt_angle + ARGR(angles).tilt; 1439 new_tilt = pdev->tilt_angle + angles->tilt;
1521 } 1440 }
1522 /* check absolute ranges */ 1441 /* check absolute ranges */
1523 if (new_pan < pdev->angle_range.pan_min || 1442 if (new_pan < pdev->angle_range.pan_min ||
@@ -1560,12 +1479,11 @@ int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg)
1560 1479
1561 if (pdev->features & FEATURE_MOTOR_PANTILT) 1480 if (pdev->features & FEATURE_MOTOR_PANTILT)
1562 { 1481 {
1563 ARG_DEF(struct pwc_mpt_angles, angles) 1482 struct pwc_mpt_angles *angles = arg;
1564 1483
1565 ARGR(angles).absolute = 1; 1484 angles->absolute = 1;
1566 ARGR(angles).pan = pdev->pan_angle; 1485 angles->pan = pdev->pan_angle;
1567 ARGR(angles).tilt = pdev->tilt_angle; 1486 angles->tilt = pdev->tilt_angle;
1568 ARG_OUT(angles)
1569 } 1487 }
1570 else 1488 else
1571 { 1489 {
@@ -1578,10 +1496,8 @@ int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg)
1578 { 1496 {
1579 if (pdev->features & FEATURE_MOTOR_PANTILT) 1497 if (pdev->features & FEATURE_MOTOR_PANTILT)
1580 { 1498 {
1581 ARG_DEF(struct pwc_mpt_status, status) 1499 struct pwc_mpt_status *status = arg;
1582 1500 ret = pwc_mpt_get_status(pdev, status);
1583 ret = pwc_mpt_get_status(pdev, ARGA(status));
1584 ARG_OUT(status)
1585 } 1501 }
1586 else 1502 else
1587 { 1503 {
@@ -1592,24 +1508,22 @@ int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg)
1592 1508
1593 case VIDIOCPWCGVIDCMD: 1509 case VIDIOCPWCGVIDCMD:
1594 { 1510 {
1595 ARG_DEF(struct pwc_video_command, cmd); 1511 struct pwc_video_command *cmd = arg;
1596 1512
1597 ARGR(cmd).type = pdev->type; 1513 cmd->type = pdev->type;
1598 ARGR(cmd).release = pdev->release; 1514 cmd->release = pdev->release;
1599 ARGR(cmd).command_len = pdev->cmd_len; 1515 cmd->command_len = pdev->cmd_len;
1600 memcpy(&ARGR(cmd).command_buf, pdev->cmd_buf, pdev->cmd_len); 1516 memcpy(&cmd->command_buf, pdev->cmd_buf, pdev->cmd_len);
1601 ARGR(cmd).bandlength = pdev->vbandlength; 1517 cmd->bandlength = pdev->vbandlength;
1602 ARGR(cmd).frame_size = pdev->frame_size; 1518 cmd->frame_size = pdev->frame_size;
1603 ARG_OUT(cmd)
1604 break; 1519 break;
1605 } 1520 }
1606 /* 1521 /*
1607 case VIDIOCPWCGVIDTABLE: 1522 case VIDIOCPWCGVIDTABLE:
1608 { 1523 {
1609 ARG_DEF(struct pwc_table_init_buffer, table); 1524 struct pwc_table_init_buffer *table = arg;
1610 ARGR(table).len = pdev->cmd_len; 1525 table->len = pdev->cmd_len;
1611 memcpy(&ARGR(table).buffer, pdev->decompress_data, pdev->decompressor->table_size); 1526 memcpy(&table->buffer, pdev->decompress_data, pdev->decompressor->table_size);
1612 ARG_OUT(table)
1613 break; 1527 break;
1614 } 1528 }
1615 */ 1529 */
diff --git a/drivers/usb/media/sn9c102.h b/drivers/usb/media/sn9c102.h
index e5cea0e2eb57..17d60c1eea7e 100644
--- a/drivers/usb/media/sn9c102.h
+++ b/drivers/usb/media/sn9c102.h
@@ -1,7 +1,7 @@
1/*************************************************************************** 1/***************************************************************************
2 * V4L2 driver for SN9C10x PC Camera Controllers * 2 * V4L2 driver for SN9C10x PC Camera Controllers *
3 * * 3 * *
4 * Copyright (C) 2004-2005 by Luca Risolia <luca.risolia@studio.unibo.it> * 4 * Copyright (C) 2004-2006 by Luca Risolia <luca.risolia@studio.unibo.it> *
5 * * 5 * *
6 * This program is free software; you can redistribute it and/or modify * 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 * 7 * it under the terms of the GNU General Public License as published by *
@@ -23,7 +23,8 @@
23 23
24#include <linux/version.h> 24#include <linux/version.h>
25#include <linux/usb.h> 25#include <linux/usb.h>
26#include <linux/videodev.h> 26#include <linux/videodev2.h>
27#include <media/v4l2-common.h>
27#include <linux/device.h> 28#include <linux/device.h>
28#include <linux/list.h> 29#include <linux/list.h>
29#include <linux/spinlock.h> 30#include <linux/spinlock.h>
@@ -52,13 +53,6 @@
52 53
53/*****************************************************************************/ 54/*****************************************************************************/
54 55
55#define SN9C102_MODULE_NAME "V4L2 driver for SN9C10x PC Camera Controllers"
56#define SN9C102_MODULE_AUTHOR "(C) 2004-2005 Luca Risolia"
57#define SN9C102_AUTHOR_EMAIL "<luca.risolia@studio.unibo.it>"
58#define SN9C102_MODULE_LICENSE "GPL"
59#define SN9C102_MODULE_VERSION "1:1.24a"
60#define SN9C102_MODULE_VERSION_CODE KERNEL_VERSION(1, 0, 24)
61
62enum sn9c102_bridge { 56enum sn9c102_bridge {
63 BRIDGE_SN9C101 = 0x01, 57 BRIDGE_SN9C101 = 0x01,
64 BRIDGE_SN9C102 = 0x02, 58 BRIDGE_SN9C102 = 0x02,
@@ -102,12 +96,13 @@ enum sn9c102_stream_state {
102 STREAM_ON, 96 STREAM_ON,
103}; 97};
104 98
99typedef char sn9c103_sof_header_t[18];
105typedef char sn9c102_sof_header_t[12]; 100typedef char sn9c102_sof_header_t[12];
106typedef char sn9c102_eof_header_t[4]; 101typedef char sn9c102_eof_header_t[4];
107 102
108struct sn9c102_sysfs_attr { 103struct sn9c102_sysfs_attr {
109 u8 reg, i2c_reg; 104 u8 reg, i2c_reg;
110 sn9c102_sof_header_t frame_header; 105 sn9c103_sof_header_t frame_header;
111}; 106};
112 107
113struct sn9c102_module_param { 108struct sn9c102_module_param {
@@ -118,8 +113,6 @@ static DECLARE_MUTEX(sn9c102_sysfs_lock);
118static DECLARE_RWSEM(sn9c102_disconnect); 113static DECLARE_RWSEM(sn9c102_disconnect);
119 114
120struct sn9c102_device { 115struct sn9c102_device {
121 struct device dev;
122
123 struct video_device* v4ldev; 116 struct video_device* v4ldev;
124 117
125 enum sn9c102_bridge bridge; 118 enum sn9c102_bridge bridge;
@@ -140,8 +133,8 @@ struct sn9c102_device {
140 struct v4l2_jpegcompression compression; 133 struct v4l2_jpegcompression compression;
141 134
142 struct sn9c102_sysfs_attr sysfs; 135 struct sn9c102_sysfs_attr sysfs;
143 sn9c102_sof_header_t sof_header; 136 sn9c103_sof_header_t sof_header;
144 u16 reg[32]; 137 u16 reg[63];
145 138
146 struct sn9c102_module_param module_param; 139 struct sn9c102_module_param module_param;
147 140
@@ -160,7 +153,6 @@ sn9c102_attach_sensor(struct sn9c102_device* cam,
160 struct sn9c102_sensor* sensor) 153 struct sn9c102_sensor* sensor)
161{ 154{
162 cam->sensor = sensor; 155 cam->sensor = sensor;
163 cam->sensor->dev = &cam->dev;
164 cam->sensor->usbdev = cam->usbdev; 156 cam->sensor->usbdev = cam->usbdev;
165} 157}
166 158
@@ -170,19 +162,24 @@ sn9c102_attach_sensor(struct sn9c102_device* cam,
170#undef KDBG 162#undef KDBG
171#ifdef SN9C102_DEBUG 163#ifdef SN9C102_DEBUG
172# define DBG(level, fmt, args...) \ 164# define DBG(level, fmt, args...) \
173{ \ 165do { \
174 if (debug >= (level)) { \ 166 if (debug >= (level)) { \
175 if ((level) == 1) \ 167 if ((level) == 1) \
176 dev_err(&cam->dev, fmt "\n", ## args); \ 168 dev_err(&cam->usbdev->dev, fmt "\n", ## args); \
177 else if ((level) == 2) \ 169 else if ((level) == 2) \
178 dev_info(&cam->dev, fmt "\n", ## args); \ 170 dev_info(&cam->usbdev->dev, fmt "\n", ## args); \
179 else if ((level) >= 3) \ 171 else if ((level) >= 3) \
180 dev_info(&cam->dev, "[%s:%d] " fmt "\n", \ 172 dev_info(&cam->usbdev->dev, "[%s:%d] " fmt "\n", \
181 __FUNCTION__, __LINE__ , ## args); \ 173 __FUNCTION__, __LINE__ , ## args); \
182 } \ 174 } \
183} 175} while (0)
176# define V4LDBG(level, name, cmd) \
177do { \
178 if (debug >= (level)) \
179 v4l_print_ioctl(name, cmd); \
180} while (0)
184# define KDBG(level, fmt, args...) \ 181# define KDBG(level, fmt, args...) \
185{ \ 182do { \
186 if (debug >= (level)) { \ 183 if (debug >= (level)) { \
187 if ((level) == 1 || (level) == 2) \ 184 if ((level) == 1 || (level) == 2) \
188 pr_info("sn9c102: " fmt "\n", ## args); \ 185 pr_info("sn9c102: " fmt "\n", ## args); \
@@ -190,17 +187,18 @@ sn9c102_attach_sensor(struct sn9c102_device* cam,
190 pr_debug("sn9c102: [%s:%d] " fmt "\n", __FUNCTION__, \ 187 pr_debug("sn9c102: [%s:%d] " fmt "\n", __FUNCTION__, \
191 __LINE__ , ## args); \ 188 __LINE__ , ## args); \
192 } \ 189 } \
193} 190} while (0)
194#else 191#else
195# define KDBG(level, fmt, args...) do {;} while(0); 192# define DBG(level, fmt, args...) do {;} while(0)
196# define DBG(level, fmt, args...) do {;} while(0); 193# define V4LDBG(level, name, cmd) do {;} while(0)
194# define KDBG(level, fmt, args...) do {;} while(0)
197#endif 195#endif
198 196
199#undef PDBG 197#undef PDBG
200#define PDBG(fmt, args...) \ 198#define PDBG(fmt, args...) \
201dev_info(&cam->dev, "[%s:%d] " fmt "\n", __FUNCTION__, __LINE__ , ## args); 199dev_info(&cam->dev, "[%s:%d] " fmt "\n", __FUNCTION__, __LINE__ , ## args)
202 200
203#undef PDBGG 201#undef PDBGG
204#define PDBGG(fmt, args...) do {;} while(0); /* placeholder */ 202#define PDBGG(fmt, args...) do {;} while(0) /* placeholder */
205 203
206#endif /* _SN9C102_H_ */ 204#endif /* _SN9C102_H_ */
diff --git a/drivers/usb/media/sn9c102_core.c b/drivers/usb/media/sn9c102_core.c
index 8d1a1c357d5a..c81397e4714b 100644
--- a/drivers/usb/media/sn9c102_core.c
+++ b/drivers/usb/media/sn9c102_core.c
@@ -1,7 +1,7 @@
1/*************************************************************************** 1/***************************************************************************
2 * V4L2 driver for SN9C10x PC Camera Controllers * 2 * V4L2 driver for SN9C10x PC Camera Controllers *
3 * * 3 * *
4 * Copyright (C) 2004-2005 by Luca Risolia <luca.risolia@studio.unibo.it> * 4 * Copyright (C) 2004-2006 by Luca Risolia <luca.risolia@studio.unibo.it> *
5 * * 5 * *
6 * This program is free software; you can redistribute it and/or modify * 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 * 7 * it under the terms of the GNU General Public License as published by *
@@ -45,6 +45,15 @@
45 45
46/*****************************************************************************/ 46/*****************************************************************************/
47 47
48#define SN9C102_MODULE_NAME "V4L2 driver for SN9C10x PC Camera Controllers"
49#define SN9C102_MODULE_AUTHOR "(C) 2004-2006 Luca Risolia"
50#define SN9C102_AUTHOR_EMAIL "<luca.risolia@studio.unibo.it>"
51#define SN9C102_MODULE_LICENSE "GPL"
52#define SN9C102_MODULE_VERSION "1:1.26"
53#define SN9C102_MODULE_VERSION_CODE KERNEL_VERSION(1, 0, 26)
54
55/*****************************************************************************/
56
48MODULE_DEVICE_TABLE(usb, sn9c102_id_table); 57MODULE_DEVICE_TABLE(usb, sn9c102_id_table);
49 58
50MODULE_AUTHOR(SN9C102_MODULE_AUTHOR " " SN9C102_AUTHOR_EMAIL); 59MODULE_AUTHOR(SN9C102_MODULE_AUTHOR " " SN9C102_AUTHOR_EMAIL);
@@ -70,10 +79,10 @@ static short force_munmap[] = {[0 ... SN9C102_MAX_DEVICES-1] =
70 SN9C102_FORCE_MUNMAP}; 79 SN9C102_FORCE_MUNMAP};
71module_param_array(force_munmap, bool, NULL, 0444); 80module_param_array(force_munmap, bool, NULL, 0444);
72MODULE_PARM_DESC(force_munmap, 81MODULE_PARM_DESC(force_munmap,
73 "\n<0|1[,...]> Force the application to unmap previously " 82 "\n<0|1[,...]> Force the application to unmap previously"
74 "\nmapped buffer memory before calling any VIDIOC_S_CROP or " 83 "\nmapped buffer memory before calling any VIDIOC_S_CROP or"
75 "\nVIDIOC_S_FMT ioctl's. Not all the applications support " 84 "\nVIDIOC_S_FMT ioctl's. Not all the applications support"
76 "\nthis feature. This parameter is specific for each " 85 "\nthis feature. This parameter is specific for each"
77 "\ndetected camera." 86 "\ndetected camera."
78 "\n 0 = do not force memory unmapping" 87 "\n 0 = do not force memory unmapping"
79 "\n 1 = force memory unmapping (save memory)" 88 "\n 1 = force memory unmapping (save memory)"
@@ -102,6 +111,9 @@ static sn9c102_sof_header_t sn9c102_sof_header[] = {
102 {0xff, 0xff, 0x00, 0xc4, 0xc4, 0x96, 0x01}, 111 {0xff, 0xff, 0x00, 0xc4, 0xc4, 0x96, 0x01},
103}; 112};
104 113
114static sn9c103_sof_header_t sn9c103_sof_header[] = {
115 {0xff, 0xff, 0x00, 0xc4, 0xc4, 0x96, 0x20},
116};
105 117
106static sn9c102_eof_header_t sn9c102_eof_header[] = { 118static sn9c102_eof_header_t sn9c102_eof_header[] = {
107 {0x00, 0x00, 0x00, 0x00}, 119 {0x00, 0x00, 0x00, 0x00},
@@ -112,50 +124,6 @@ static sn9c102_eof_header_t sn9c102_eof_header[] = {
112 124
113/*****************************************************************************/ 125/*****************************************************************************/
114 126
115static void* rvmalloc(size_t size)
116{
117 void* mem;
118 unsigned long adr;
119
120 size = PAGE_ALIGN(size);
121
122 mem = vmalloc_32((unsigned long)size);
123 if (!mem)
124 return NULL;
125
126 memset(mem, 0, size);
127
128 adr = (unsigned long)mem;
129 while (size > 0) {
130 SetPageReserved(vmalloc_to_page((void *)adr));
131 adr += PAGE_SIZE;
132 size -= PAGE_SIZE;
133 }
134
135 return mem;
136}
137
138
139static void rvfree(void* mem, size_t size)
140{
141 unsigned long adr;
142
143 if (!mem)
144 return;
145
146 size = PAGE_ALIGN(size);
147
148 adr = (unsigned long)mem;
149 while (size > 0) {
150 ClearPageReserved(vmalloc_to_page((void *)adr));
151 adr += PAGE_SIZE;
152 size -= PAGE_SIZE;
153 }
154
155 vfree(mem);
156}
157
158
159static u32 127static u32
160sn9c102_request_buffers(struct sn9c102_device* cam, u32 count, 128sn9c102_request_buffers(struct sn9c102_device* cam, u32 count,
161 enum sn9c102_io_method io) 129 enum sn9c102_io_method io)
@@ -174,7 +142,7 @@ sn9c102_request_buffers(struct sn9c102_device* cam, u32 count,
174 142
175 cam->nbuffers = count; 143 cam->nbuffers = count;
176 while (cam->nbuffers > 0) { 144 while (cam->nbuffers > 0) {
177 if ((buff = rvmalloc(cam->nbuffers * PAGE_ALIGN(imagesize)))) 145 if ((buff = vmalloc_32(cam->nbuffers * PAGE_ALIGN(imagesize))))
178 break; 146 break;
179 cam->nbuffers--; 147 cam->nbuffers--;
180 } 148 }
@@ -198,10 +166,10 @@ sn9c102_request_buffers(struct sn9c102_device* cam, u32 count,
198static void sn9c102_release_buffers(struct sn9c102_device* cam) 166static void sn9c102_release_buffers(struct sn9c102_device* cam)
199{ 167{
200 if (cam->nbuffers) { 168 if (cam->nbuffers) {
201 rvfree(cam->frame[0].bufmem, 169 vfree(cam->frame[0].bufmem);
202 cam->nbuffers * PAGE_ALIGN(cam->frame[0].buf.length));
203 cam->nbuffers = 0; 170 cam->nbuffers = 0;
204 } 171 }
172 cam->frame_current = NULL;
205} 173}
206 174
207 175
@@ -219,6 +187,19 @@ static void sn9c102_empty_framequeues(struct sn9c102_device* cam)
219} 187}
220 188
221 189
190static void sn9c102_requeue_outqueue(struct sn9c102_device* cam)
191{
192 struct sn9c102_frame_t *i;
193
194 list_for_each_entry(i, &cam->outqueue, frame) {
195 i->state = F_QUEUED;
196 list_add(&i->frame, &cam->inqueue);
197 }
198
199 INIT_LIST_HEAD(&cam->outqueue);
200}
201
202
222static void sn9c102_queue_unusedframes(struct sn9c102_device* cam) 203static void sn9c102_queue_unusedframes(struct sn9c102_device* cam)
223{ 204{
224 unsigned long lock_flags; 205 unsigned long lock_flags;
@@ -235,19 +216,46 @@ static void sn9c102_queue_unusedframes(struct sn9c102_device* cam)
235 216
236/*****************************************************************************/ 217/*****************************************************************************/
237 218
219int sn9c102_write_regs(struct sn9c102_device* cam, u8* buff, u16 index)
220{
221 struct usb_device* udev = cam->usbdev;
222 int i, res;
223
224 if (index + sizeof(buff) >= ARRAY_SIZE(cam->reg))
225 return -1;
226
227 res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x08, 0x41,
228 index, 0, buff, sizeof(buff),
229 SN9C102_CTRL_TIMEOUT*sizeof(buff));
230 if (res < 0) {
231 DBG(3, "Failed to write registers (index 0x%02X, error %d)",
232 index, res);
233 return -1;
234 }
235
236 for (i = 0; i < sizeof(buff); i++)
237 cam->reg[index+i] = buff[i];
238
239 return 0;
240}
241
242
238int sn9c102_write_reg(struct sn9c102_device* cam, u8 value, u16 index) 243int sn9c102_write_reg(struct sn9c102_device* cam, u8 value, u16 index)
239{ 244{
240 struct usb_device* udev = cam->usbdev; 245 struct usb_device* udev = cam->usbdev;
241 u8* buff = cam->control_buffer; 246 u8* buff = cam->control_buffer;
242 int res; 247 int res;
243 248
249 if (index >= ARRAY_SIZE(cam->reg))
250 return -1;
251
244 *buff = value; 252 *buff = value;
245 253
246 res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x08, 0x41, 254 res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x08, 0x41,
247 index, 0, buff, 1, SN9C102_CTRL_TIMEOUT); 255 index, 0, buff, 1, SN9C102_CTRL_TIMEOUT);
248 if (res < 0) { 256 if (res < 0) {
249 DBG(3, "Failed to write a register (value 0x%02X, index " 257 DBG(3, "Failed to write a register (value 0x%02X, index "
250 "0x%02X, error %d)", value, index, res) 258 "0x%02X, error %d)", value, index, res);
251 return -1; 259 return -1;
252 } 260 }
253 261
@@ -268,7 +276,7 @@ static int sn9c102_read_reg(struct sn9c102_device* cam, u16 index)
268 index, 0, buff, 1, SN9C102_CTRL_TIMEOUT); 276 index, 0, buff, 1, SN9C102_CTRL_TIMEOUT);
269 if (res < 0) 277 if (res < 0)
270 DBG(3, "Failed to read a register (index 0x%02X, error %d)", 278 DBG(3, "Failed to read a register (index 0x%02X, error %d)",
271 index, res) 279 index, res);
272 280
273 return (res >= 0) ? (int)(*buff) : -1; 281 return (res >= 0) ? (int)(*buff) : -1;
274} 282}
@@ -276,8 +284,8 @@ static int sn9c102_read_reg(struct sn9c102_device* cam, u16 index)
276 284
277int sn9c102_pread_reg(struct sn9c102_device* cam, u16 index) 285int sn9c102_pread_reg(struct sn9c102_device* cam, u16 index)
278{ 286{
279 if (index > 0x1f) 287 if (index >= ARRAY_SIZE(cam->reg))
280 return -EINVAL; 288 return -1;
281 289
282 return cam->reg[index]; 290 return cam->reg[index];
283} 291}
@@ -367,10 +375,10 @@ sn9c102_i2c_try_raw_read(struct sn9c102_device* cam,
367 err += sn9c102_i2c_detect_read_error(cam, sensor); 375 err += sn9c102_i2c_detect_read_error(cam, sensor);
368 376
369 PDBGG("I2C read: address 0x%02X, first read byte: 0x%02X", data1, 377 PDBGG("I2C read: address 0x%02X, first read byte: 0x%02X", data1,
370 data[4]) 378 data[4]);
371 379
372 if (err) { 380 if (err) {
373 DBG(3, "I2C read failed for %s image sensor", sensor->name) 381 DBG(3, "I2C read failed for %s image sensor", sensor->name);
374 return -1; 382 return -1;
375 } 383 }
376 384
@@ -410,11 +418,11 @@ sn9c102_i2c_try_raw_write(struct sn9c102_device* cam,
410 err += sn9c102_i2c_detect_write_error(cam, sensor); 418 err += sn9c102_i2c_detect_write_error(cam, sensor);
411 419
412 if (err) 420 if (err)
413 DBG(3, "I2C write failed for %s image sensor", sensor->name) 421 DBG(3, "I2C write failed for %s image sensor", sensor->name);
414 422
415 PDBGG("I2C raw write: %u bytes, data0 = 0x%02X, data1 = 0x%02X, " 423 PDBGG("I2C raw write: %u bytes, data0 = 0x%02X, data1 = 0x%02X, "
416 "data2 = 0x%02X, data3 = 0x%02X, data4 = 0x%02X, data5 = 0x%02X", 424 "data2 = 0x%02X, data3 = 0x%02X, data4 = 0x%02X, data5 = 0x%02X",
417 n, data0, data1, data2, data3, data4, data5) 425 n, data0, data1, data2, data3, data4, data5);
418 426
419 return err ? -1 : 0; 427 return err ? -1 : 0;
420} 428}
@@ -461,13 +469,27 @@ int sn9c102_i2c_write(struct sn9c102_device* cam, u8 address, u8 value)
461static void* 469static void*
462sn9c102_find_sof_header(struct sn9c102_device* cam, void* mem, size_t len) 470sn9c102_find_sof_header(struct sn9c102_device* cam, void* mem, size_t len)
463{ 471{
464 size_t soflen = sizeof(sn9c102_sof_header_t), i; 472 size_t soflen = 0, i;
465 u8 j, n = sizeof(sn9c102_sof_header) / soflen; 473 u8 j, n = 0;
466 474
467 for (i = 0; (len >= soflen) && (i <= len - soflen); i++) 475 switch (cam->bridge) {
476 case BRIDGE_SN9C101:
477 case BRIDGE_SN9C102:
478 soflen = sizeof(sn9c102_sof_header_t);
479 n = sizeof(sn9c102_sof_header) / soflen;
480 break;
481 case BRIDGE_SN9C103:
482 soflen = sizeof(sn9c103_sof_header_t);
483 n = sizeof(sn9c103_sof_header) / soflen;
484 }
485
486 for (i = 0; (len >= soflen) && (i <= len - soflen); i++)
468 for (j = 0; j < n; j++) 487 for (j = 0; j < n; j++)
469 /* It's enough to compare 7 bytes */ 488 /* The invariable part of the header is 6 bytes long */
470 if (!memcmp(mem + i, sn9c102_sof_header[j], 7)) { 489 if ((cam->bridge != BRIDGE_SN9C103 &&
490 !memcmp(mem + i, sn9c102_sof_header[j], 6)) ||
491 (cam->bridge == BRIDGE_SN9C103 &&
492 !memcmp(mem + i, sn9c103_sof_header[j], 6))) {
471 memcpy(cam->sof_header, mem + i, soflen); 493 memcpy(cam->sof_header, mem + i, soflen);
472 /* Skip the header */ 494 /* Skip the header */
473 return mem + i + soflen; 495 return mem + i + soflen;
@@ -499,8 +521,7 @@ static void sn9c102_urb_complete(struct urb *urb, struct pt_regs* regs)
499{ 521{
500 struct sn9c102_device* cam = urb->context; 522 struct sn9c102_device* cam = urb->context;
501 struct sn9c102_frame_t** f; 523 struct sn9c102_frame_t** f;
502 size_t imagesize; 524 size_t imagesize, soflen;
503 unsigned long lock_flags;
504 u8 i; 525 u8 i;
505 int err = 0; 526 int err = 0;
506 527
@@ -513,7 +534,7 @@ static void sn9c102_urb_complete(struct urb *urb, struct pt_regs* regs)
513 cam->stream = STREAM_OFF; 534 cam->stream = STREAM_OFF;
514 if ((*f)) 535 if ((*f))
515 (*f)->state = F_QUEUED; 536 (*f)->state = F_QUEUED;
516 DBG(3, "Stream interrupted") 537 DBG(3, "Stream interrupted");
517 wake_up_interruptible(&cam->wait_stream); 538 wake_up_interruptible(&cam->wait_stream);
518 } 539 }
519 540
@@ -536,6 +557,10 @@ static void sn9c102_urb_complete(struct urb *urb, struct pt_regs* regs)
536 cam->sensor->pix_format.height * 557 cam->sensor->pix_format.height *
537 cam->sensor->pix_format.priv) / 8; 558 cam->sensor->pix_format.priv) / 8;
538 559
560 soflen = (cam->bridge) == BRIDGE_SN9C103 ?
561 sizeof(sn9c103_sof_header_t) :
562 sizeof(sn9c102_sof_header_t);
563
539 for (i = 0; i < urb->number_of_packets; i++) { 564 for (i = 0; i < urb->number_of_packets; i++) {
540 unsigned int img, len, status; 565 unsigned int img, len, status;
541 void *pos, *sof, *eof; 566 void *pos, *sof, *eof;
@@ -545,19 +570,12 @@ static void sn9c102_urb_complete(struct urb *urb, struct pt_regs* regs)
545 pos = urb->iso_frame_desc[i].offset + urb->transfer_buffer; 570 pos = urb->iso_frame_desc[i].offset + urb->transfer_buffer;
546 571
547 if (status) { 572 if (status) {
548 DBG(3, "Error in isochronous frame") 573 DBG(3, "Error in isochronous frame");
549 (*f)->state = F_ERROR; 574 (*f)->state = F_ERROR;
550 continue; 575 continue;
551 } 576 }
552 577
553 PDBGG("Isochrnous frame: length %u, #%u i", len, i) 578 PDBGG("Isochrnous frame: length %u, #%u i", len, i);
554
555 /*
556 NOTE: It is probably correct to assume that SOF and EOF
557 headers do not occur between two consecutive packets,
558 but who knows..Whatever is the truth, this assumption
559 doesn't introduce bugs.
560 */
561 579
562redo: 580redo:
563 sof = sn9c102_find_sof_header(cam, pos, len); 581 sof = sn9c102_find_sof_header(cam, pos, len);
@@ -575,10 +593,10 @@ end_of_frame:
575 imagesize; 593 imagesize;
576 img = imagesize - (*f)->buf.bytesused; 594 img = imagesize - (*f)->buf.bytesused;
577 DBG(3, "Expected EOF not found: " 595 DBG(3, "Expected EOF not found: "
578 "video frame cut") 596 "video frame cut");
579 if (eof) 597 if (eof)
580 DBG(3, "Exceeded limit: +%u " 598 DBG(3, "Exceeded limit: +%u "
581 "bytes", (unsigned)(b)) 599 "bytes", (unsigned)(b));
582 } 600 }
583 601
584 memcpy((*f)->bufmem + (*f)->buf.bytesused, pos, 602 memcpy((*f)->bufmem + (*f)->buf.bytesused, pos,
@@ -595,8 +613,7 @@ end_of_frame:
595 u32 b = (*f)->buf.bytesused; 613 u32 b = (*f)->buf.bytesused;
596 (*f)->state = F_DONE; 614 (*f)->state = F_DONE;
597 (*f)->buf.sequence= ++cam->frame_count; 615 (*f)->buf.sequence= ++cam->frame_count;
598 spin_lock_irqsave(&cam->queue_lock, 616 spin_lock(&cam->queue_lock);
599 lock_flags);
600 list_move_tail(&(*f)->frame, 617 list_move_tail(&(*f)->frame,
601 &cam->outqueue); 618 &cam->outqueue);
602 if (!list_empty(&cam->inqueue)) 619 if (!list_empty(&cam->inqueue))
@@ -606,13 +623,11 @@ end_of_frame:
606 frame ); 623 frame );
607 else 624 else
608 (*f) = NULL; 625 (*f) = NULL;
609 spin_unlock_irqrestore(&cam->queue_lock 626 spin_unlock(&cam->queue_lock);
610 , lock_flags);
611 memcpy(cam->sysfs.frame_header, 627 memcpy(cam->sysfs.frame_header,
612 cam->sof_header, 628 cam->sof_header, soflen);
613 sizeof(sn9c102_sof_header_t)); 629 DBG(3, "Video frame captured: %lu "
614 DBG(3, "Video frame captured: " 630 "bytes", (unsigned long)(b));
615 "%lu bytes", (unsigned long)(b))
616 631
617 if (!(*f)) 632 if (!(*f))
618 goto resubmit_urb; 633 goto resubmit_urb;
@@ -621,18 +636,19 @@ end_of_frame:
621 (*f)->state = F_ERROR; 636 (*f)->state = F_ERROR;
622 DBG(3, "Not expected EOF after %lu " 637 DBG(3, "Not expected EOF after %lu "
623 "bytes of image data", 638 "bytes of image data",
624 (unsigned long)((*f)->buf.bytesused)) 639 (unsigned long)
640 ((*f)->buf.bytesused));
625 } 641 }
626 642
627 if (sof) /* (1) */ 643 if (sof) /* (1) */
628 goto start_of_frame; 644 goto start_of_frame;
629 645
630 } else if (eof) { 646 } else if (eof) {
631 DBG(3, "EOF without SOF") 647 DBG(3, "EOF without SOF");
632 continue; 648 continue;
633 649
634 } else { 650 } else {
635 PDBGG("Ignoring pointless isochronous frame") 651 PDBGG("Ignoring pointless isochronous frame");
636 continue; 652 continue;
637 } 653 }
638 654
@@ -642,7 +658,7 @@ start_of_frame:
642 (*f)->buf.bytesused = 0; 658 (*f)->buf.bytesused = 0;
643 len -= (sof - pos); 659 len -= (sof - pos);
644 pos = sof; 660 pos = sof;
645 DBG(3, "SOF detected: new video frame") 661 DBG(3, "SOF detected: new video frame");
646 if (len) 662 if (len)
647 goto redo; 663 goto redo;
648 664
@@ -653,12 +669,13 @@ start_of_frame:
653 else { 669 else {
654 if (cam->sensor->pix_format.pixelformat == 670 if (cam->sensor->pix_format.pixelformat ==
655 V4L2_PIX_FMT_SN9C10X) { 671 V4L2_PIX_FMT_SN9C10X) {
656 eof = sof-sizeof(sn9c102_sof_header_t); 672 eof = sof - soflen;
657 goto end_of_frame; 673 goto end_of_frame;
658 } else { 674 } else {
659 DBG(3, "SOF before expected EOF after " 675 DBG(3, "SOF before expected EOF after "
660 "%lu bytes of image data", 676 "%lu bytes of image data",
661 (unsigned long)((*f)->buf.bytesused)) 677 (unsigned long)
678 ((*f)->buf.bytesused));
662 goto start_of_frame; 679 goto start_of_frame;
663 } 680 }
664 } 681 }
@@ -670,7 +687,7 @@ resubmit_urb:
670 err = usb_submit_urb(urb, GFP_ATOMIC); 687 err = usb_submit_urb(urb, GFP_ATOMIC);
671 if (err < 0 && err != -EPERM) { 688 if (err < 0 && err != -EPERM) {
672 cam->state |= DEV_MISCONFIGURED; 689 cam->state |= DEV_MISCONFIGURED;
673 DBG(1, "usb_submit_urb() failed") 690 DBG(1, "usb_submit_urb() failed");
674 } 691 }
675 692
676 wake_up_interruptible(&cam->wait_frame); 693 wake_up_interruptible(&cam->wait_frame);
@@ -681,18 +698,22 @@ static int sn9c102_start_transfer(struct sn9c102_device* cam)
681{ 698{
682 struct usb_device *udev = cam->usbdev; 699 struct usb_device *udev = cam->usbdev;
683 struct urb* urb; 700 struct urb* urb;
684 const unsigned int wMaxPacketSize[] = {0, 128, 256, 384, 512, 701 const unsigned int sn9c102_wMaxPacketSize[] = {0, 128, 256, 384, 512,
685 680, 800, 900, 1023}; 702 680, 800, 900, 1023};
686 const unsigned int psz = wMaxPacketSize[SN9C102_ALTERNATE_SETTING]; 703 const unsigned int sn9c103_wMaxPacketSize[] = {0, 128, 256, 384, 512,
704 680, 800, 900, 1003};
705 const unsigned int psz = (cam->bridge == BRIDGE_SN9C103) ?
706 sn9c103_wMaxPacketSize[SN9C102_ALTERNATE_SETTING] :
707 sn9c102_wMaxPacketSize[SN9C102_ALTERNATE_SETTING];
687 s8 i, j; 708 s8 i, j;
688 int err = 0; 709 int err = 0;
689 710
690 for (i = 0; i < SN9C102_URBS; i++) { 711 for (i = 0; i < SN9C102_URBS; i++) {
691 cam->transfer_buffer[i] = kmalloc(SN9C102_ISO_PACKETS * psz, 712 cam->transfer_buffer[i] = kzalloc(SN9C102_ISO_PACKETS * psz,
692 GFP_KERNEL); 713 GFP_KERNEL);
693 if (!cam->transfer_buffer[i]) { 714 if (!cam->transfer_buffer[i]) {
694 err = -ENOMEM; 715 err = -ENOMEM;
695 DBG(1, "Not enough memory") 716 DBG(1, "Not enough memory");
696 goto free_buffers; 717 goto free_buffers;
697 } 718 }
698 } 719 }
@@ -702,7 +723,7 @@ static int sn9c102_start_transfer(struct sn9c102_device* cam)
702 cam->urb[i] = urb; 723 cam->urb[i] = urb;
703 if (!urb) { 724 if (!urb) {
704 err = -ENOMEM; 725 err = -ENOMEM;
705 DBG(1, "usb_alloc_urb() failed") 726 DBG(1, "usb_alloc_urb() failed");
706 goto free_urbs; 727 goto free_urbs;
707 } 728 }
708 urb->dev = udev; 729 urb->dev = udev;
@@ -725,14 +746,14 @@ static int sn9c102_start_transfer(struct sn9c102_device* cam)
725 err = sn9c102_write_reg(cam, cam->reg[0x01] | 0x04, 0x01); 746 err = sn9c102_write_reg(cam, cam->reg[0x01] | 0x04, 0x01);
726 if (err) { 747 if (err) {
727 err = -EIO; 748 err = -EIO;
728 DBG(1, "I/O hardware error") 749 DBG(1, "I/O hardware error");
729 goto free_urbs; 750 goto free_urbs;
730 } 751 }
731 } 752 }
732 753
733 err = usb_set_interface(udev, 0, SN9C102_ALTERNATE_SETTING); 754 err = usb_set_interface(udev, 0, SN9C102_ALTERNATE_SETTING);
734 if (err) { 755 if (err) {
735 DBG(1, "usb_set_interface() failed") 756 DBG(1, "usb_set_interface() failed");
736 goto free_urbs; 757 goto free_urbs;
737 } 758 }
738 759
@@ -743,7 +764,7 @@ static int sn9c102_start_transfer(struct sn9c102_device* cam)
743 if (err) { 764 if (err) {
744 for (j = i-1; j >= 0; j--) 765 for (j = i-1; j >= 0; j--)
745 usb_kill_urb(cam->urb[j]); 766 usb_kill_urb(cam->urb[j]);
746 DBG(1, "usb_submit_urb() failed, error %d", err) 767 DBG(1, "usb_submit_urb() failed, error %d", err);
747 goto free_urbs; 768 goto free_urbs;
748 } 769 }
749 } 770 }
@@ -779,7 +800,7 @@ static int sn9c102_stop_transfer(struct sn9c102_device* cam)
779 800
780 err = usb_set_interface(udev, 0, 0); /* 0 Mb/s */ 801 err = usb_set_interface(udev, 0, 0); /* 0 Mb/s */
781 if (err) 802 if (err)
782 DBG(3, "usb_set_interface() failed") 803 DBG(3, "usb_set_interface() failed");
783 804
784 return err; 805 return err;
785} 806}
@@ -799,7 +820,7 @@ static int sn9c102_stream_interrupt(struct sn9c102_device* cam)
799 else if (err) { 820 else if (err) {
800 cam->state |= DEV_MISCONFIGURED; 821 cam->state |= DEV_MISCONFIGURED;
801 DBG(1, "The camera is misconfigured. To use it, close and " 822 DBG(1, "The camera is misconfigured. To use it, close and "
802 "open /dev/video%d again.", cam->v4ldev->minor) 823 "open /dev/video%d again.", cam->v4ldev->minor);
803 return err; 824 return err;
804 } 825 }
805 826
@@ -808,6 +829,7 @@ static int sn9c102_stream_interrupt(struct sn9c102_device* cam)
808 829
809/*****************************************************************************/ 830/*****************************************************************************/
810 831
832#ifdef CONFIG_VIDEO_ADV_DEBUG
811static u8 sn9c102_strtou8(const char* buff, size_t len, ssize_t* count) 833static u8 sn9c102_strtou8(const char* buff, size_t len, ssize_t* count)
812{ 834{
813 char str[5]; 835 char str[5];
@@ -885,8 +907,8 @@ sn9c102_store_reg(struct class_device* cd, const char* buf, size_t len)
885 907
886 cam->sysfs.reg = index; 908 cam->sysfs.reg = index;
887 909
888 DBG(2, "Moved SN9C10X register index to 0x%02X", cam->sysfs.reg) 910 DBG(2, "Moved SN9C10X register index to 0x%02X", cam->sysfs.reg);
889 DBG(3, "Written bytes: %zd", count) 911 DBG(3, "Written bytes: %zd", count);
890 912
891 up(&sn9c102_sysfs_lock); 913 up(&sn9c102_sysfs_lock);
892 914
@@ -916,7 +938,7 @@ static ssize_t sn9c102_show_val(struct class_device* cd, char* buf)
916 938
917 count = sprintf(buf, "%d\n", val); 939 count = sprintf(buf, "%d\n", val);
918 940
919 DBG(3, "Read bytes: %zd", count) 941 DBG(3, "Read bytes: %zd", count);
920 942
921 up(&sn9c102_sysfs_lock); 943 up(&sn9c102_sysfs_lock);
922 944
@@ -954,8 +976,8 @@ sn9c102_store_val(struct class_device* cd, const char* buf, size_t len)
954 } 976 }
955 977
956 DBG(2, "Written SN9C10X reg. 0x%02X, val. 0x%02X", 978 DBG(2, "Written SN9C10X reg. 0x%02X, val. 0x%02X",
957 cam->sysfs.reg, value) 979 cam->sysfs.reg, value);
958 DBG(3, "Written bytes: %zd", count) 980 DBG(3, "Written bytes: %zd", count);
959 981
960 up(&sn9c102_sysfs_lock); 982 up(&sn9c102_sysfs_lock);
961 983
@@ -979,7 +1001,7 @@ static ssize_t sn9c102_show_i2c_reg(struct class_device* cd, char* buf)
979 1001
980 count = sprintf(buf, "%u\n", cam->sysfs.i2c_reg); 1002 count = sprintf(buf, "%u\n", cam->sysfs.i2c_reg);
981 1003
982 DBG(3, "Read bytes: %zd", count) 1004 DBG(3, "Read bytes: %zd", count);
983 1005
984 up(&sn9c102_sysfs_lock); 1006 up(&sn9c102_sysfs_lock);
985 1007
@@ -1011,8 +1033,8 @@ sn9c102_store_i2c_reg(struct class_device* cd, const char* buf, size_t len)
1011 1033
1012 cam->sysfs.i2c_reg = index; 1034 cam->sysfs.i2c_reg = index;
1013 1035
1014 DBG(2, "Moved sensor register index to 0x%02X", cam->sysfs.i2c_reg) 1036 DBG(2, "Moved sensor register index to 0x%02X", cam->sysfs.i2c_reg);
1015 DBG(3, "Written bytes: %zd", count) 1037 DBG(3, "Written bytes: %zd", count);
1016 1038
1017 up(&sn9c102_sysfs_lock); 1039 up(&sn9c102_sysfs_lock);
1018 1040
@@ -1047,7 +1069,7 @@ static ssize_t sn9c102_show_i2c_val(struct class_device* cd, char* buf)
1047 1069
1048 count = sprintf(buf, "%d\n", val); 1070 count = sprintf(buf, "%d\n", val);
1049 1071
1050 DBG(3, "Read bytes: %zd", count) 1072 DBG(3, "Read bytes: %zd", count);
1051 1073
1052 up(&sn9c102_sysfs_lock); 1074 up(&sn9c102_sysfs_lock);
1053 1075
@@ -1090,8 +1112,8 @@ sn9c102_store_i2c_val(struct class_device* cd, const char* buf, size_t len)
1090 } 1112 }
1091 1113
1092 DBG(2, "Written sensor reg. 0x%02X, val. 0x%02X", 1114 DBG(2, "Written sensor reg. 0x%02X, val. 0x%02X",
1093 cam->sysfs.i2c_reg, value) 1115 cam->sysfs.i2c_reg, value);
1094 DBG(3, "Written bytes: %zd", count) 1116 DBG(3, "Written bytes: %zd", count);
1095 1117
1096 up(&sn9c102_sysfs_lock); 1118 up(&sn9c102_sysfs_lock);
1097 1119
@@ -1193,7 +1215,7 @@ static ssize_t sn9c102_show_frame_header(struct class_device* cd, char* buf)
1193 count = sizeof(cam->sysfs.frame_header); 1215 count = sizeof(cam->sysfs.frame_header);
1194 memcpy(buf, cam->sysfs.frame_header, count); 1216 memcpy(buf, cam->sysfs.frame_header, count);
1195 1217
1196 DBG(3, "Frame header, read bytes: %zd", count) 1218 DBG(3, "Frame header, read bytes: %zd", count);
1197 1219
1198 return count; 1220 return count;
1199} 1221}
@@ -1227,11 +1249,12 @@ static void sn9c102_create_sysfs(struct sn9c102_device* cam)
1227 video_device_create_file(v4ldev, &class_device_attr_blue); 1249 video_device_create_file(v4ldev, &class_device_attr_blue);
1228 video_device_create_file(v4ldev, &class_device_attr_red); 1250 video_device_create_file(v4ldev, &class_device_attr_red);
1229 } 1251 }
1230 if (cam->sensor->sysfs_ops) { 1252 if (cam->sensor && cam->sensor->sysfs_ops) {
1231 video_device_create_file(v4ldev, &class_device_attr_i2c_reg); 1253 video_device_create_file(v4ldev, &class_device_attr_i2c_reg);
1232 video_device_create_file(v4ldev, &class_device_attr_i2c_val); 1254 video_device_create_file(v4ldev, &class_device_attr_i2c_val);
1233 } 1255 }
1234} 1256}
1257#endif /* CONFIG_VIDEO_ADV_DEBUG */
1235 1258
1236/*****************************************************************************/ 1259/*****************************************************************************/
1237 1260
@@ -1281,7 +1304,7 @@ static int sn9c102_set_scale(struct sn9c102_device* cam, u8 scale)
1281 if (err) 1304 if (err)
1282 return -EIO; 1305 return -EIO;
1283 1306
1284 PDBGG("Scaling factor: %u", scale) 1307 PDBGG("Scaling factor: %u", scale);
1285 1308
1286 return 0; 1309 return 0;
1287} 1310}
@@ -1304,7 +1327,7 @@ static int sn9c102_set_crop(struct sn9c102_device* cam, struct v4l2_rect* rect)
1304 return -EIO; 1327 return -EIO;
1305 1328
1306 PDBGG("h_start, v_start, h_size, v_size, ho_size, vo_size " 1329 PDBGG("h_start, v_start, h_size, v_size, ho_size, vo_size "
1307 "%u %u %u %u", h_start, v_start, h_size, v_size) 1330 "%u %u %u %u", h_start, v_start, h_size, v_size);
1308 1331
1309 return 0; 1332 return 0;
1310} 1333}
@@ -1336,7 +1359,7 @@ static int sn9c102_init(struct sn9c102_device* cam)
1336 if (s->init) { 1359 if (s->init) {
1337 err = s->init(cam); 1360 err = s->init(cam);
1338 if (err) { 1361 if (err) {
1339 DBG(3, "Sensor initialization failed") 1362 DBG(3, "Sensor initialization failed");
1340 return err; 1363 return err;
1341 } 1364 }
1342 } 1365 }
@@ -1353,13 +1376,13 @@ static int sn9c102_init(struct sn9c102_device* cam)
1353 1376
1354 if (s->pix_format.pixelformat == V4L2_PIX_FMT_SN9C10X) 1377 if (s->pix_format.pixelformat == V4L2_PIX_FMT_SN9C10X)
1355 DBG(3, "Compressed video format is active, quality %d", 1378 DBG(3, "Compressed video format is active, quality %d",
1356 cam->compression.quality) 1379 cam->compression.quality);
1357 else 1380 else
1358 DBG(3, "Uncompressed video format is active") 1381 DBG(3, "Uncompressed video format is active");
1359 1382
1360 if (s->set_crop) 1383 if (s->set_crop)
1361 if ((err = s->set_crop(cam, rect))) { 1384 if ((err = s->set_crop(cam, rect))) {
1362 DBG(3, "set_crop() failed") 1385 DBG(3, "set_crop() failed");
1363 return err; 1386 return err;
1364 } 1387 }
1365 1388
@@ -1372,11 +1395,11 @@ static int sn9c102_init(struct sn9c102_device* cam)
1372 err = s->set_ctrl(cam, &ctrl); 1395 err = s->set_ctrl(cam, &ctrl);
1373 if (err) { 1396 if (err) {
1374 DBG(3, "Set %s control failed", 1397 DBG(3, "Set %s control failed",
1375 s->qctrl[i].name) 1398 s->qctrl[i].name);
1376 return err; 1399 return err;
1377 } 1400 }
1378 DBG(3, "Image sensor supports '%s' control", 1401 DBG(3, "Image sensor supports '%s' control",
1379 s->qctrl[i].name) 1402 s->qctrl[i].name);
1380 } 1403 }
1381 } 1404 }
1382 1405
@@ -1392,7 +1415,7 @@ static int sn9c102_init(struct sn9c102_device* cam)
1392 cam->state |= DEV_INITIALIZED; 1415 cam->state |= DEV_INITIALIZED;
1393 } 1416 }
1394 1417
1395 DBG(2, "Initialization succeeded") 1418 DBG(2, "Initialization succeeded");
1396 return 0; 1419 return 0;
1397} 1420}
1398 1421
@@ -1401,7 +1424,7 @@ static void sn9c102_release_resources(struct sn9c102_device* cam)
1401{ 1424{
1402 down(&sn9c102_sysfs_lock); 1425 down(&sn9c102_sysfs_lock);
1403 1426
1404 DBG(2, "V4L2 device /dev/video%d deregistered", cam->v4ldev->minor) 1427 DBG(2, "V4L2 device /dev/video%d deregistered", cam->v4ldev->minor);
1405 video_set_drvdata(cam->v4ldev, NULL); 1428 video_set_drvdata(cam->v4ldev, NULL);
1406 video_unregister_device(cam->v4ldev); 1429 video_unregister_device(cam->v4ldev);
1407 1430
@@ -1432,7 +1455,7 @@ static int sn9c102_open(struct inode* inode, struct file* filp)
1432 } 1455 }
1433 1456
1434 if (cam->users) { 1457 if (cam->users) {
1435 DBG(2, "Device /dev/video%d is busy...", cam->v4ldev->minor) 1458 DBG(2, "Device /dev/video%d is busy...", cam->v4ldev->minor);
1436 if ((filp->f_flags & O_NONBLOCK) || 1459 if ((filp->f_flags & O_NONBLOCK) ||
1437 (filp->f_flags & O_NDELAY)) { 1460 (filp->f_flags & O_NDELAY)) {
1438 err = -EWOULDBLOCK; 1461 err = -EWOULDBLOCK;
@@ -1458,7 +1481,7 @@ static int sn9c102_open(struct inode* inode, struct file* filp)
1458 err = sn9c102_init(cam); 1481 err = sn9c102_init(cam);
1459 if (err) { 1482 if (err) {
1460 DBG(1, "Initialization failed again. " 1483 DBG(1, "Initialization failed again. "
1461 "I will retry on next open().") 1484 "I will retry on next open().");
1462 goto out; 1485 goto out;
1463 } 1486 }
1464 cam->state &= ~DEV_MISCONFIGURED; 1487 cam->state &= ~DEV_MISCONFIGURED;
@@ -1475,7 +1498,7 @@ static int sn9c102_open(struct inode* inode, struct file* filp)
1475 cam->frame_count = 0; 1498 cam->frame_count = 0;
1476 sn9c102_empty_framequeues(cam); 1499 sn9c102_empty_framequeues(cam);
1477 1500
1478 DBG(3, "Video device /dev/video%d is open", cam->v4ldev->minor) 1501 DBG(3, "Video device /dev/video%d is open", cam->v4ldev->minor);
1479 1502
1480out: 1503out:
1481 up(&cam->dev_sem); 1504 up(&cam->dev_sem);
@@ -1504,7 +1527,7 @@ static int sn9c102_release(struct inode* inode, struct file* filp)
1504 cam->users--; 1527 cam->users--;
1505 wake_up_interruptible_nr(&cam->open, 1); 1528 wake_up_interruptible_nr(&cam->open, 1);
1506 1529
1507 DBG(3, "Video device /dev/video%d closed", cam->v4ldev->minor) 1530 DBG(3, "Video device /dev/video%d closed", cam->v4ldev->minor);
1508 1531
1509 up(&cam->dev_sem); 1532 up(&cam->dev_sem);
1510 1533
@@ -1524,32 +1547,38 @@ sn9c102_read(struct file* filp, char __user * buf, size_t count, loff_t* f_pos)
1524 return -ERESTARTSYS; 1547 return -ERESTARTSYS;
1525 1548
1526 if (cam->state & DEV_DISCONNECTED) { 1549 if (cam->state & DEV_DISCONNECTED) {
1527 DBG(1, "Device not present") 1550 DBG(1, "Device not present");
1528 up(&cam->fileop_sem); 1551 up(&cam->fileop_sem);
1529 return -ENODEV; 1552 return -ENODEV;
1530 } 1553 }
1531 1554
1532 if (cam->state & DEV_MISCONFIGURED) { 1555 if (cam->state & DEV_MISCONFIGURED) {
1533 DBG(1, "The camera is misconfigured. Close and open it again.") 1556 DBG(1, "The camera is misconfigured. Close and open it "
1557 "again.");
1534 up(&cam->fileop_sem); 1558 up(&cam->fileop_sem);
1535 return -EIO; 1559 return -EIO;
1536 } 1560 }
1537 1561
1538 if (cam->io == IO_MMAP) { 1562 if (cam->io == IO_MMAP) {
1539 DBG(3, "Close and open the device again to choose " 1563 DBG(3, "Close and open the device again to choose "
1540 "the read method") 1564 "the read method");
1541 up(&cam->fileop_sem); 1565 up(&cam->fileop_sem);
1542 return -EINVAL; 1566 return -EINVAL;
1543 } 1567 }
1544 1568
1545 if (cam->io == IO_NONE) { 1569 if (cam->io == IO_NONE) {
1546 if (!sn9c102_request_buffers(cam,cam->nreadbuffers, IO_READ)) { 1570 if (!sn9c102_request_buffers(cam,cam->nreadbuffers, IO_READ)) {
1547 DBG(1, "read() failed, not enough memory") 1571 DBG(1, "read() failed, not enough memory");
1548 up(&cam->fileop_sem); 1572 up(&cam->fileop_sem);
1549 return -ENOMEM; 1573 return -ENOMEM;
1550 } 1574 }
1551 cam->io = IO_READ; 1575 cam->io = IO_READ;
1552 cam->stream = STREAM_ON; 1576 cam->stream = STREAM_ON;
1577 }
1578
1579 if (list_empty(&cam->inqueue)) {
1580 if (!list_empty(&cam->outqueue))
1581 sn9c102_empty_framequeues(cam);
1553 sn9c102_queue_unusedframes(cam); 1582 sn9c102_queue_unusedframes(cam);
1554 } 1583 }
1555 1584
@@ -1584,6 +1613,16 @@ sn9c102_read(struct file* filp, char __user * buf, size_t count, loff_t* f_pos)
1584 1613
1585 f = list_entry(cam->outqueue.prev, struct sn9c102_frame_t, frame); 1614 f = list_entry(cam->outqueue.prev, struct sn9c102_frame_t, frame);
1586 1615
1616 if (count > f->buf.bytesused)
1617 count = f->buf.bytesused;
1618
1619 if (copy_to_user(buf, f->bufmem, count)) {
1620 err = -EFAULT;
1621 goto exit;
1622 }
1623 *f_pos += count;
1624
1625exit:
1587 spin_lock_irqsave(&cam->queue_lock, lock_flags); 1626 spin_lock_irqsave(&cam->queue_lock, lock_flags);
1588 list_for_each_entry(i, &cam->outqueue, frame) 1627 list_for_each_entry(i, &cam->outqueue, frame)
1589 i->state = F_UNUSED; 1628 i->state = F_UNUSED;
@@ -1592,16 +1631,8 @@ sn9c102_read(struct file* filp, char __user * buf, size_t count, loff_t* f_pos)
1592 1631
1593 sn9c102_queue_unusedframes(cam); 1632 sn9c102_queue_unusedframes(cam);
1594 1633
1595 if (count > f->buf.bytesused) 1634 PDBGG("Frame #%lu, bytes read: %zu",
1596 count = f->buf.bytesused; 1635 (unsigned long)f->buf.index, count);
1597
1598 if (copy_to_user(buf, f->bufmem, count)) {
1599 up(&cam->fileop_sem);
1600 return -EFAULT;
1601 }
1602 *f_pos += count;
1603
1604 PDBGG("Frame #%lu, bytes read: %zu", (unsigned long)f->buf.index,count)
1605 1636
1606 up(&cam->fileop_sem); 1637 up(&cam->fileop_sem);
1607 1638
@@ -1612,33 +1643,42 @@ sn9c102_read(struct file* filp, char __user * buf, size_t count, loff_t* f_pos)
1612static unsigned int sn9c102_poll(struct file *filp, poll_table *wait) 1643static unsigned int sn9c102_poll(struct file *filp, poll_table *wait)
1613{ 1644{
1614 struct sn9c102_device* cam = video_get_drvdata(video_devdata(filp)); 1645 struct sn9c102_device* cam = video_get_drvdata(video_devdata(filp));
1646 struct sn9c102_frame_t* f;
1647 unsigned long lock_flags;
1615 unsigned int mask = 0; 1648 unsigned int mask = 0;
1616 1649
1617 if (down_interruptible(&cam->fileop_sem)) 1650 if (down_interruptible(&cam->fileop_sem))
1618 return POLLERR; 1651 return POLLERR;
1619 1652
1620 if (cam->state & DEV_DISCONNECTED) { 1653 if (cam->state & DEV_DISCONNECTED) {
1621 DBG(1, "Device not present") 1654 DBG(1, "Device not present");
1622 goto error; 1655 goto error;
1623 } 1656 }
1624 1657
1625 if (cam->state & DEV_MISCONFIGURED) { 1658 if (cam->state & DEV_MISCONFIGURED) {
1626 DBG(1, "The camera is misconfigured. Close and open it again.") 1659 DBG(1, "The camera is misconfigured. Close and open it "
1660 "again.");
1627 goto error; 1661 goto error;
1628 } 1662 }
1629 1663
1630 if (cam->io == IO_NONE) { 1664 if (cam->io == IO_NONE) {
1631 if (!sn9c102_request_buffers(cam, cam->nreadbuffers, 1665 if (!sn9c102_request_buffers(cam, cam->nreadbuffers,
1632 IO_READ)) { 1666 IO_READ)) {
1633 DBG(1, "poll() failed, not enough memory") 1667 DBG(1, "poll() failed, not enough memory");
1634 goto error; 1668 goto error;
1635 } 1669 }
1636 cam->io = IO_READ; 1670 cam->io = IO_READ;
1637 cam->stream = STREAM_ON; 1671 cam->stream = STREAM_ON;
1638 } 1672 }
1639 1673
1640 if (cam->io == IO_READ) 1674 if (cam->io == IO_READ) {
1675 spin_lock_irqsave(&cam->queue_lock, lock_flags);
1676 list_for_each_entry(f, &cam->outqueue, frame)
1677 f->state = F_UNUSED;
1678 INIT_LIST_HEAD(&cam->outqueue);
1679 spin_unlock_irqrestore(&cam->queue_lock, lock_flags);
1641 sn9c102_queue_unusedframes(cam); 1680 sn9c102_queue_unusedframes(cam);
1681 }
1642 1682
1643 poll_wait(filp, &cam->wait_frame, wait); 1683 poll_wait(filp, &cam->wait_frame, wait);
1644 1684
@@ -1680,22 +1720,22 @@ static int sn9c102_mmap(struct file* filp, struct vm_area_struct *vma)
1680{ 1720{
1681 struct sn9c102_device* cam = video_get_drvdata(video_devdata(filp)); 1721 struct sn9c102_device* cam = video_get_drvdata(video_devdata(filp));
1682 unsigned long size = vma->vm_end - vma->vm_start, 1722 unsigned long size = vma->vm_end - vma->vm_start,
1683 start = vma->vm_start, 1723 start = vma->vm_start;
1684 pos, 1724 void *pos;
1685 page;
1686 u32 i; 1725 u32 i;
1687 1726
1688 if (down_interruptible(&cam->fileop_sem)) 1727 if (down_interruptible(&cam->fileop_sem))
1689 return -ERESTARTSYS; 1728 return -ERESTARTSYS;
1690 1729
1691 if (cam->state & DEV_DISCONNECTED) { 1730 if (cam->state & DEV_DISCONNECTED) {
1692 DBG(1, "Device not present") 1731 DBG(1, "Device not present");
1693 up(&cam->fileop_sem); 1732 up(&cam->fileop_sem);
1694 return -ENODEV; 1733 return -ENODEV;
1695 } 1734 }
1696 1735
1697 if (cam->state & DEV_MISCONFIGURED) { 1736 if (cam->state & DEV_MISCONFIGURED) {
1698 DBG(1, "The camera is misconfigured. Close and open it again.") 1737 DBG(1, "The camera is misconfigured. Close and open it "
1738 "again.");
1699 up(&cam->fileop_sem); 1739 up(&cam->fileop_sem);
1700 return -EIO; 1740 return -EIO;
1701 } 1741 }
@@ -1715,15 +1755,12 @@ static int sn9c102_mmap(struct file* filp, struct vm_area_struct *vma)
1715 return -EINVAL; 1755 return -EINVAL;
1716 } 1756 }
1717 1757
1718 /* VM_IO is eventually going to replace PageReserved altogether */
1719 vma->vm_flags |= VM_IO; 1758 vma->vm_flags |= VM_IO;
1720 vma->vm_flags |= VM_RESERVED; /* avoid to swap out this VMA */ 1759 vma->vm_flags |= VM_RESERVED;
1721 1760
1722 pos = (unsigned long)cam->frame[i].bufmem; 1761 pos = cam->frame[i].bufmem;
1723 while (size > 0) { /* size is page-aligned */ 1762 while (size > 0) { /* size is page-aligned */
1724 page = vmalloc_to_pfn((void *)pos); 1763 if (vm_insert_page(vma, start, vmalloc_to_page(pos))) {
1725 if (remap_pfn_range(vma, start, page, PAGE_SIZE,
1726 vma->vm_page_prot)) {
1727 up(&cam->fileop_sem); 1764 up(&cam->fileop_sem);
1728 return -EAGAIN; 1765 return -EAGAIN;
1729 } 1766 }
@@ -1742,738 +1779,861 @@ static int sn9c102_mmap(struct file* filp, struct vm_area_struct *vma)
1742 return 0; 1779 return 0;
1743} 1780}
1744 1781
1782/*****************************************************************************/
1745 1783
1746static int sn9c102_ioctl_v4l2(struct inode* inode, struct file* filp, 1784static int
1747 unsigned int cmd, void __user * arg) 1785sn9c102_vidioc_querycap(struct sn9c102_device* cam, void __user * arg)
1748{ 1786{
1749 struct sn9c102_device* cam = video_get_drvdata(video_devdata(filp)); 1787 struct v4l2_capability cap = {
1788 .driver = "sn9c102",
1789 .version = SN9C102_MODULE_VERSION_CODE,
1790 .capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE |
1791 V4L2_CAP_STREAMING,
1792 };
1793
1794 strlcpy(cap.card, cam->v4ldev->name, sizeof(cap.card));
1795 if (usb_make_path(cam->usbdev, cap.bus_info, sizeof(cap.bus_info)) < 0)
1796 strlcpy(cap.bus_info, cam->usbdev->dev.bus_id,
1797 sizeof(cap.bus_info));
1798
1799 if (copy_to_user(arg, &cap, sizeof(cap)))
1800 return -EFAULT;
1750 1801
1751 switch (cmd) { 1802 return 0;
1803}
1752 1804
1753 case VIDIOC_QUERYCAP:
1754 {
1755 struct v4l2_capability cap = {
1756 .driver = "sn9c102",
1757 .version = SN9C102_MODULE_VERSION_CODE,
1758 .capabilities = V4L2_CAP_VIDEO_CAPTURE |
1759 V4L2_CAP_READWRITE |
1760 V4L2_CAP_STREAMING,
1761 };
1762
1763 strlcpy(cap.card, cam->v4ldev->name, sizeof(cap.card));
1764 if (usb_make_path(cam->usbdev, cap.bus_info,
1765 sizeof(cap.bus_info)) < 0)
1766 strlcpy(cap.bus_info, cam->dev.bus_id,
1767 sizeof(cap.bus_info));
1768
1769 if (copy_to_user(arg, &cap, sizeof(cap)))
1770 return -EFAULT;
1771 1805
1772 return 0; 1806static int
1773 } 1807sn9c102_vidioc_enuminput(struct sn9c102_device* cam, void __user * arg)
1808{
1809 struct v4l2_input i;
1774 1810
1775 case VIDIOC_ENUMINPUT: 1811 if (copy_from_user(&i, arg, sizeof(i)))
1776 { 1812 return -EFAULT;
1777 struct v4l2_input i;
1778 1813
1779 if (copy_from_user(&i, arg, sizeof(i))) 1814 if (i.index)
1780 return -EFAULT; 1815 return -EINVAL;
1781 1816
1782 if (i.index) 1817 memset(&i, 0, sizeof(i));
1783 return -EINVAL; 1818 strcpy(i.name, "Camera");
1784 1819
1785 memset(&i, 0, sizeof(i)); 1820 if (copy_to_user(arg, &i, sizeof(i)))
1786 strcpy(i.name, "USB"); 1821 return -EFAULT;
1787 1822
1788 if (copy_to_user(arg, &i, sizeof(i))) 1823 return 0;
1789 return -EFAULT; 1824}
1790 1825
1791 return 0;
1792 }
1793 1826
1794 case VIDIOC_G_INPUT: 1827static int
1795 case VIDIOC_S_INPUT: 1828sn9c102_vidioc_gs_input(struct sn9c102_device* cam, void __user * arg)
1796 { 1829{
1797 int index; 1830 int index;
1798 1831
1799 if (copy_from_user(&index, arg, sizeof(index))) 1832 if (copy_from_user(&index, arg, sizeof(index)))
1800 return -EFAULT; 1833 return -EFAULT;
1801 1834
1802 if (index != 0) 1835 if (index != 0)
1803 return -EINVAL; 1836 return -EINVAL;
1804 1837
1805 return 0; 1838 return 0;
1806 } 1839}
1807 1840
1808 case VIDIOC_QUERYCTRL:
1809 {
1810 struct sn9c102_sensor* s = cam->sensor;
1811 struct v4l2_queryctrl qc;
1812 u8 i;
1813 1841
1814 if (copy_from_user(&qc, arg, sizeof(qc))) 1842static int
1815 return -EFAULT; 1843sn9c102_vidioc_query_ctrl(struct sn9c102_device* cam, void __user * arg)
1844{
1845 struct sn9c102_sensor* s = cam->sensor;
1846 struct v4l2_queryctrl qc;
1847 u8 i;
1816 1848
1849 if (copy_from_user(&qc, arg, sizeof(qc)))
1850 return -EFAULT;
1851
1852 for (i = 0; i < ARRAY_SIZE(s->qctrl); i++)
1853 if (qc.id && qc.id == s->qctrl[i].id) {
1854 memcpy(&qc, &(s->qctrl[i]), sizeof(qc));
1855 if (copy_to_user(arg, &qc, sizeof(qc)))
1856 return -EFAULT;
1857 return 0;
1858 }
1859
1860 return -EINVAL;
1861}
1862
1863
1864static int
1865sn9c102_vidioc_g_ctrl(struct sn9c102_device* cam, void __user * arg)
1866{
1867 struct sn9c102_sensor* s = cam->sensor;
1868 struct v4l2_control ctrl;
1869 int err = 0;
1870 u8 i;
1871
1872 if (!s->get_ctrl && !s->set_ctrl)
1873 return -EINVAL;
1874
1875 if (copy_from_user(&ctrl, arg, sizeof(ctrl)))
1876 return -EFAULT;
1877
1878 if (!s->get_ctrl) {
1817 for (i = 0; i < ARRAY_SIZE(s->qctrl); i++) 1879 for (i = 0; i < ARRAY_SIZE(s->qctrl); i++)
1818 if (qc.id && qc.id == s->qctrl[i].id) { 1880 if (ctrl.id && ctrl.id == s->qctrl[i].id) {
1819 memcpy(&qc, &(s->qctrl[i]), sizeof(qc)); 1881 ctrl.value = s->_qctrl[i].default_value;
1820 if (copy_to_user(arg, &qc, sizeof(qc))) 1882 goto exit;
1821 return -EFAULT;
1822 return 0;
1823 } 1883 }
1824
1825 return -EINVAL; 1884 return -EINVAL;
1826 } 1885 } else
1886 err = s->get_ctrl(cam, &ctrl);
1827 1887
1828 case VIDIOC_G_CTRL: 1888exit:
1829 { 1889 if (copy_to_user(arg, &ctrl, sizeof(ctrl)))
1830 struct sn9c102_sensor* s = cam->sensor; 1890 return -EFAULT;
1831 struct v4l2_control ctrl;
1832 int err = 0;
1833 1891
1834 if (!s->get_ctrl) 1892 return err;
1835 return -EINVAL; 1893}
1836 1894
1837 if (copy_from_user(&ctrl, arg, sizeof(ctrl)))
1838 return -EFAULT;
1839 1895
1840 err = s->get_ctrl(cam, &ctrl); 1896static int
1897sn9c102_vidioc_s_ctrl(struct sn9c102_device* cam, void __user * arg)
1898{
1899 struct sn9c102_sensor* s = cam->sensor;
1900 struct v4l2_control ctrl;
1901 u8 i;
1902 int err = 0;
1841 1903
1842 if (copy_to_user(arg, &ctrl, sizeof(ctrl))) 1904 if (!s->set_ctrl)
1843 return -EFAULT; 1905 return -EINVAL;
1906
1907 if (copy_from_user(&ctrl, arg, sizeof(ctrl)))
1908 return -EFAULT;
1844 1909
1910 for (i = 0; i < ARRAY_SIZE(s->qctrl); i++)
1911 if (ctrl.id == s->qctrl[i].id) {
1912 if (ctrl.value < s->qctrl[i].minimum ||
1913 ctrl.value > s->qctrl[i].maximum)
1914 return -ERANGE;
1915 ctrl.value -= ctrl.value % s->qctrl[i].step;
1916 break;
1917 }
1918
1919 if ((err = s->set_ctrl(cam, &ctrl)))
1845 return err; 1920 return err;
1846 }
1847 1921
1848 case VIDIOC_S_CTRL_OLD: 1922 s->_qctrl[i].default_value = ctrl.value;
1849 case VIDIOC_S_CTRL:
1850 {
1851 struct sn9c102_sensor* s = cam->sensor;
1852 struct v4l2_control ctrl;
1853 u8 i;
1854 int err = 0;
1855 1923
1856 if (!s->set_ctrl) 1924 PDBGG("VIDIOC_S_CTRL: id %lu, value %lu",
1857 return -EINVAL; 1925 (unsigned long)ctrl.id, (unsigned long)ctrl.value);
1858 1926
1859 if (copy_from_user(&ctrl, arg, sizeof(ctrl))) 1927 return 0;
1860 return -EFAULT; 1928}
1861 1929
1862 for (i = 0; i < ARRAY_SIZE(s->qctrl); i++) 1930
1863 if (ctrl.id == s->qctrl[i].id) { 1931static int
1864 if (ctrl.value < s->qctrl[i].minimum || 1932sn9c102_vidioc_cropcap(struct sn9c102_device* cam, void __user * arg)
1865 ctrl.value > s->qctrl[i].maximum) 1933{
1866 return -ERANGE; 1934 struct v4l2_cropcap* cc = &(cam->sensor->cropcap);
1867 ctrl.value -= ctrl.value % s->qctrl[i].step; 1935
1868 break; 1936 cc->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1937 cc->pixelaspect.numerator = 1;
1938 cc->pixelaspect.denominator = 1;
1939
1940 if (copy_to_user(arg, cc, sizeof(*cc)))
1941 return -EFAULT;
1942
1943 return 0;
1944}
1945
1946
1947static int
1948sn9c102_vidioc_g_crop(struct sn9c102_device* cam, void __user * arg)
1949{
1950 struct sn9c102_sensor* s = cam->sensor;
1951 struct v4l2_crop crop = {
1952 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
1953 };
1954
1955 memcpy(&(crop.c), &(s->_rect), sizeof(struct v4l2_rect));
1956
1957 if (copy_to_user(arg, &crop, sizeof(crop)))
1958 return -EFAULT;
1959
1960 return 0;
1961}
1962
1963
1964static int
1965sn9c102_vidioc_s_crop(struct sn9c102_device* cam, void __user * arg)
1966{
1967 struct sn9c102_sensor* s = cam->sensor;
1968 struct v4l2_crop crop;
1969 struct v4l2_rect* rect;
1970 struct v4l2_rect* bounds = &(s->cropcap.bounds);
1971 struct v4l2_pix_format* pix_format = &(s->pix_format);
1972 u8 scale;
1973 const enum sn9c102_stream_state stream = cam->stream;
1974 const u32 nbuffers = cam->nbuffers;
1975 u32 i;
1976 int err = 0;
1977
1978 if (copy_from_user(&crop, arg, sizeof(crop)))
1979 return -EFAULT;
1980
1981 rect = &(crop.c);
1982
1983 if (crop.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1984 return -EINVAL;
1985
1986 if (cam->module_param.force_munmap)
1987 for (i = 0; i < cam->nbuffers; i++)
1988 if (cam->frame[i].vma_use_count) {
1989 DBG(3, "VIDIOC_S_CROP failed. "
1990 "Unmap the buffers first.");
1991 return -EINVAL;
1869 } 1992 }
1870 1993
1871 if ((err = s->set_ctrl(cam, &ctrl))) 1994 /* Preserve R,G or B origin */
1995 rect->left = (s->_rect.left & 1L) ? rect->left | 1L : rect->left & ~1L;
1996 rect->top = (s->_rect.top & 1L) ? rect->top | 1L : rect->top & ~1L;
1997
1998 if (rect->width < 16)
1999 rect->width = 16;
2000 if (rect->height < 16)
2001 rect->height = 16;
2002 if (rect->width > bounds->width)
2003 rect->width = bounds->width;
2004 if (rect->height > bounds->height)
2005 rect->height = bounds->height;
2006 if (rect->left < bounds->left)
2007 rect->left = bounds->left;
2008 if (rect->top < bounds->top)
2009 rect->top = bounds->top;
2010 if (rect->left + rect->width > bounds->left + bounds->width)
2011 rect->left = bounds->left+bounds->width - rect->width;
2012 if (rect->top + rect->height > bounds->top + bounds->height)
2013 rect->top = bounds->top+bounds->height - rect->height;
2014
2015 rect->width &= ~15L;
2016 rect->height &= ~15L;
2017
2018 if (SN9C102_PRESERVE_IMGSCALE) {
2019 /* Calculate the actual scaling factor */
2020 u32 a, b;
2021 a = rect->width * rect->height;
2022 b = pix_format->width * pix_format->height;
2023 scale = b ? (u8)((a / b) < 4 ? 1 : ((a / b) < 16 ? 2 : 4)) : 1;
2024 } else
2025 scale = 1;
2026
2027 if (cam->stream == STREAM_ON)
2028 if ((err = sn9c102_stream_interrupt(cam)))
1872 return err; 2029 return err;
1873 2030
1874 s->_qctrl[i].default_value = ctrl.value; 2031 if (copy_to_user(arg, &crop, sizeof(crop))) {
2032 cam->stream = stream;
2033 return -EFAULT;
2034 }
2035
2036 if (cam->module_param.force_munmap || cam->io == IO_READ)
2037 sn9c102_release_buffers(cam);
1875 2038
1876 PDBGG("VIDIOC_S_CTRL: id %lu, value %lu", 2039 err = sn9c102_set_crop(cam, rect);
1877 (unsigned long)ctrl.id, (unsigned long)ctrl.value) 2040 if (s->set_crop)
2041 err += s->set_crop(cam, rect);
2042 err += sn9c102_set_scale(cam, scale);
1878 2043
1879 return 0; 2044 if (err) { /* atomic, no rollback in ioctl() */
2045 cam->state |= DEV_MISCONFIGURED;
2046 DBG(1, "VIDIOC_S_CROP failed because of hardware problems. To "
2047 "use the camera, close and open /dev/video%d again.",
2048 cam->v4ldev->minor);
2049 return -EIO;
1880 } 2050 }
1881 2051
1882 case VIDIOC_CROPCAP: 2052 s->pix_format.width = rect->width/scale;
1883 { 2053 s->pix_format.height = rect->height/scale;
1884 struct v4l2_cropcap* cc = &(cam->sensor->cropcap); 2054 memcpy(&(s->_rect), rect, sizeof(*rect));
1885 2055
1886 cc->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 2056 if ((cam->module_param.force_munmap || cam->io == IO_READ) &&
1887 cc->pixelaspect.numerator = 1; 2057 nbuffers != sn9c102_request_buffers(cam, nbuffers, cam->io)) {
1888 cc->pixelaspect.denominator = 1; 2058 cam->state |= DEV_MISCONFIGURED;
2059 DBG(1, "VIDIOC_S_CROP failed because of not enough memory. To "
2060 "use the camera, close and open /dev/video%d again.",
2061 cam->v4ldev->minor);
2062 return -ENOMEM;
2063 }
1889 2064
1890 if (copy_to_user(arg, cc, sizeof(*cc))) 2065 if (cam->io == IO_READ)
1891 return -EFAULT; 2066 sn9c102_empty_framequeues(cam);
2067 else if (cam->module_param.force_munmap)
2068 sn9c102_requeue_outqueue(cam);
1892 2069
1893 return 0; 2070 cam->stream = stream;
1894 }
1895 2071
1896 case VIDIOC_G_CROP: 2072 return 0;
1897 { 2073}
1898 struct sn9c102_sensor* s = cam->sensor;
1899 struct v4l2_crop crop = {
1900 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
1901 };
1902 2074
1903 memcpy(&(crop.c), &(s->_rect), sizeof(struct v4l2_rect));
1904 2075
1905 if (copy_to_user(arg, &crop, sizeof(crop))) 2076static int
1906 return -EFAULT; 2077sn9c102_vidioc_enum_fmt(struct sn9c102_device* cam, void __user * arg)
2078{
2079 struct v4l2_fmtdesc fmtd;
1907 2080
1908 return 0; 2081 if (copy_from_user(&fmtd, arg, sizeof(fmtd)))
1909 } 2082 return -EFAULT;
1910 2083
1911 case VIDIOC_S_CROP: 2084 if (fmtd.index == 0) {
1912 { 2085 strcpy(fmtd.description, "bayer rgb");
1913 struct sn9c102_sensor* s = cam->sensor; 2086 fmtd.pixelformat = V4L2_PIX_FMT_SBGGR8;
1914 struct v4l2_crop crop; 2087 } else if (fmtd.index == 1) {
1915 struct v4l2_rect* rect; 2088 strcpy(fmtd.description, "compressed");
1916 struct v4l2_rect* bounds = &(s->cropcap.bounds); 2089 fmtd.pixelformat = V4L2_PIX_FMT_SN9C10X;
1917 struct v4l2_pix_format* pix_format = &(s->pix_format); 2090 fmtd.flags = V4L2_FMT_FLAG_COMPRESSED;
1918 u8 scale; 2091 } else
1919 const enum sn9c102_stream_state stream = cam->stream; 2092 return -EINVAL;
1920 const u32 nbuffers = cam->nbuffers;
1921 u32 i;
1922 int err = 0;
1923
1924 if (copy_from_user(&crop, arg, sizeof(crop)))
1925 return -EFAULT;
1926 2093
1927 rect = &(crop.c); 2094 fmtd.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
2095 memset(&fmtd.reserved, 0, sizeof(fmtd.reserved));
1928 2096
1929 if (crop.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 2097 if (copy_to_user(arg, &fmtd, sizeof(fmtd)))
1930 return -EINVAL; 2098 return -EFAULT;
1931 2099
1932 if (cam->module_param.force_munmap) 2100 return 0;
1933 for (i = 0; i < cam->nbuffers; i++) 2101}
1934 if (cam->frame[i].vma_use_count) {
1935 DBG(3, "VIDIOC_S_CROP failed. "
1936 "Unmap the buffers first.")
1937 return -EINVAL;
1938 }
1939 2102
1940 /* Preserve R,G or B origin */
1941 rect->left = (s->_rect.left & 1L) ?
1942 rect->left | 1L : rect->left & ~1L;
1943 rect->top = (s->_rect.top & 1L) ?
1944 rect->top | 1L : rect->top & ~1L;
1945
1946 if (rect->width < 16)
1947 rect->width = 16;
1948 if (rect->height < 16)
1949 rect->height = 16;
1950 if (rect->width > bounds->width)
1951 rect->width = bounds->width;
1952 if (rect->height > bounds->height)
1953 rect->height = bounds->height;
1954 if (rect->left < bounds->left)
1955 rect->left = bounds->left;
1956 if (rect->top < bounds->top)
1957 rect->top = bounds->top;
1958 if (rect->left + rect->width > bounds->left + bounds->width)
1959 rect->left = bounds->left+bounds->width - rect->width;
1960 if (rect->top + rect->height > bounds->top + bounds->height)
1961 rect->top = bounds->top+bounds->height - rect->height;
1962
1963 rect->width &= ~15L;
1964 rect->height &= ~15L;
1965
1966 if (SN9C102_PRESERVE_IMGSCALE) {
1967 /* Calculate the actual scaling factor */
1968 u32 a, b;
1969 a = rect->width * rect->height;
1970 b = pix_format->width * pix_format->height;
1971 scale = b ? (u8)((a / b) < 4 ? 1 :
1972 ((a / b) < 16 ? 2 : 4)) : 1;
1973 } else
1974 scale = 1;
1975
1976 if (cam->stream == STREAM_ON)
1977 if ((err = sn9c102_stream_interrupt(cam)))
1978 return err;
1979
1980 if (copy_to_user(arg, &crop, sizeof(crop))) {
1981 cam->stream = stream;
1982 return -EFAULT;
1983 }
1984 2103
1985 if (cam->module_param.force_munmap || cam->io == IO_READ) 2104static int
1986 sn9c102_release_buffers(cam); 2105sn9c102_vidioc_g_fmt(struct sn9c102_device* cam, void __user * arg)
2106{
2107 struct v4l2_format format;
2108 struct v4l2_pix_format* pfmt = &(cam->sensor->pix_format);
1987 2109
1988 err = sn9c102_set_crop(cam, rect); 2110 if (copy_from_user(&format, arg, sizeof(format)))
1989 if (s->set_crop) 2111 return -EFAULT;
1990 err += s->set_crop(cam, rect);
1991 err += sn9c102_set_scale(cam, scale);
1992 2112
1993 if (err) { /* atomic, no rollback in ioctl() */ 2113 if (format.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1994 cam->state |= DEV_MISCONFIGURED; 2114 return -EINVAL;
1995 DBG(1, "VIDIOC_S_CROP failed because of hardware "
1996 "problems. To use the camera, close and open "
1997 "/dev/video%d again.", cam->v4ldev->minor)
1998 return -EIO;
1999 }
2000 2115
2001 s->pix_format.width = rect->width/scale; 2116 pfmt->bytesperline = (pfmt->pixelformat==V4L2_PIX_FMT_SN9C10X)
2002 s->pix_format.height = rect->height/scale; 2117 ? 0 : (pfmt->width * pfmt->priv) / 8;
2003 memcpy(&(s->_rect), rect, sizeof(*rect)); 2118 pfmt->sizeimage = pfmt->height * ((pfmt->width*pfmt->priv)/8);
2004 2119 pfmt->field = V4L2_FIELD_NONE;
2005 if ((cam->module_param.force_munmap || cam->io == IO_READ) && 2120 memcpy(&(format.fmt.pix), pfmt, sizeof(*pfmt));
2006 nbuffers != sn9c102_request_buffers(cam, nbuffers,
2007 cam->io)) {
2008 cam->state |= DEV_MISCONFIGURED;
2009 DBG(1, "VIDIOC_S_CROP failed because of not enough "
2010 "memory. To use the camera, close and open "
2011 "/dev/video%d again.", cam->v4ldev->minor)
2012 return -ENOMEM;
2013 }
2014 2121
2015 cam->stream = stream; 2122 if (copy_to_user(arg, &format, sizeof(format)))
2123 return -EFAULT;
2016 2124
2017 return 0; 2125 return 0;
2018 } 2126}
2019 2127
2020 case VIDIOC_ENUM_FMT:
2021 {
2022 struct v4l2_fmtdesc fmtd;
2023 2128
2024 if (copy_from_user(&fmtd, arg, sizeof(fmtd))) 2129static int
2025 return -EFAULT; 2130sn9c102_vidioc_try_s_fmt(struct sn9c102_device* cam, unsigned int cmd,
2131 void __user * arg)
2132{
2133 struct sn9c102_sensor* s = cam->sensor;
2134 struct v4l2_format format;
2135 struct v4l2_pix_format* pix;
2136 struct v4l2_pix_format* pfmt = &(s->pix_format);
2137 struct v4l2_rect* bounds = &(s->cropcap.bounds);
2138 struct v4l2_rect rect;
2139 u8 scale;
2140 const enum sn9c102_stream_state stream = cam->stream;
2141 const u32 nbuffers = cam->nbuffers;
2142 u32 i;
2143 int err = 0;
2026 2144
2027 if (fmtd.index == 0) { 2145 if (copy_from_user(&format, arg, sizeof(format)))
2028 strcpy(fmtd.description, "bayer rgb"); 2146 return -EFAULT;
2029 fmtd.pixelformat = V4L2_PIX_FMT_SBGGR8;
2030 } else if (fmtd.index == 1) {
2031 strcpy(fmtd.description, "compressed");
2032 fmtd.pixelformat = V4L2_PIX_FMT_SN9C10X;
2033 fmtd.flags = V4L2_FMT_FLAG_COMPRESSED;
2034 } else
2035 return -EINVAL;
2036 2147
2037 fmtd.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 2148 pix = &(format.fmt.pix);
2038 memset(&fmtd.reserved, 0, sizeof(fmtd.reserved));
2039 2149
2040 if (copy_to_user(arg, &fmtd, sizeof(fmtd))) 2150 if (format.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
2041 return -EFAULT; 2151 return -EINVAL;
2042 2152
2043 return 0; 2153 memcpy(&rect, &(s->_rect), sizeof(rect));
2154
2155 { /* calculate the actual scaling factor */
2156 u32 a, b;
2157 a = rect.width * rect.height;
2158 b = pix->width * pix->height;
2159 scale = b ? (u8)((a / b) < 4 ? 1 : ((a / b) < 16 ? 2 : 4)) : 1;
2044 } 2160 }
2045 2161
2046 case VIDIOC_G_FMT: 2162 rect.width = scale * pix->width;
2047 { 2163 rect.height = scale * pix->height;
2048 struct v4l2_format format;
2049 struct v4l2_pix_format* pfmt = &(cam->sensor->pix_format);
2050 2164
2051 if (copy_from_user(&format, arg, sizeof(format))) 2165 if (rect.width < 16)
2052 return -EFAULT; 2166 rect.width = 16;
2167 if (rect.height < 16)
2168 rect.height = 16;
2169 if (rect.width > bounds->left + bounds->width - rect.left)
2170 rect.width = bounds->left + bounds->width - rect.left;
2171 if (rect.height > bounds->top + bounds->height - rect.top)
2172 rect.height = bounds->top + bounds->height - rect.top;
2053 2173
2054 if (format.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 2174 rect.width &= ~15L;
2055 return -EINVAL; 2175 rect.height &= ~15L;
2176
2177 { /* adjust the scaling factor */
2178 u32 a, b;
2179 a = rect.width * rect.height;
2180 b = pix->width * pix->height;
2181 scale = b ? (u8)((a / b) < 4 ? 1 : ((a / b) < 16 ? 2 : 4)) : 1;
2182 }
2056 2183
2057 pfmt->bytesperline = (pfmt->pixelformat==V4L2_PIX_FMT_SN9C10X) 2184 pix->width = rect.width / scale;
2058 ? 0 : (pfmt->width * pfmt->priv) / 8; 2185 pix->height = rect.height / scale;
2059 pfmt->sizeimage = pfmt->height * ((pfmt->width*pfmt->priv)/8);
2060 pfmt->field = V4L2_FIELD_NONE;
2061 memcpy(&(format.fmt.pix), pfmt, sizeof(*pfmt));
2062 2186
2187 if (pix->pixelformat != V4L2_PIX_FMT_SN9C10X &&
2188 pix->pixelformat != V4L2_PIX_FMT_SBGGR8)
2189 pix->pixelformat = pfmt->pixelformat;
2190 pix->priv = pfmt->priv; /* bpp */
2191 pix->colorspace = pfmt->colorspace;
2192 pix->bytesperline = (pix->pixelformat == V4L2_PIX_FMT_SN9C10X)
2193 ? 0 : (pix->width * pix->priv) / 8;
2194 pix->sizeimage = pix->height * ((pix->width * pix->priv) / 8);
2195 pix->field = V4L2_FIELD_NONE;
2196
2197 if (cmd == VIDIOC_TRY_FMT) {
2063 if (copy_to_user(arg, &format, sizeof(format))) 2198 if (copy_to_user(arg, &format, sizeof(format)))
2064 return -EFAULT; 2199 return -EFAULT;
2065
2066 return 0; 2200 return 0;
2067 } 2201 }
2068 2202
2069 case VIDIOC_TRY_FMT: 2203 if (cam->module_param.force_munmap)
2070 case VIDIOC_S_FMT: 2204 for (i = 0; i < cam->nbuffers; i++)
2071 { 2205 if (cam->frame[i].vma_use_count) {
2072 struct sn9c102_sensor* s = cam->sensor; 2206 DBG(3, "VIDIOC_S_FMT failed. Unmap the "
2073 struct v4l2_format format; 2207 "buffers first.");
2074 struct v4l2_pix_format* pix; 2208 return -EINVAL;
2075 struct v4l2_pix_format* pfmt = &(s->pix_format); 2209 }
2076 struct v4l2_rect* bounds = &(s->cropcap.bounds);
2077 struct v4l2_rect rect;
2078 u8 scale;
2079 const enum sn9c102_stream_state stream = cam->stream;
2080 const u32 nbuffers = cam->nbuffers;
2081 u32 i;
2082 int err = 0;
2083
2084 if (copy_from_user(&format, arg, sizeof(format)))
2085 return -EFAULT;
2086 2210
2087 pix = &(format.fmt.pix); 2211 if (cam->stream == STREAM_ON)
2212 if ((err = sn9c102_stream_interrupt(cam)))
2213 return err;
2088 2214
2089 if (format.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 2215 if (copy_to_user(arg, &format, sizeof(format))) {
2090 return -EINVAL; 2216 cam->stream = stream;
2217 return -EFAULT;
2218 }
2091 2219
2092 memcpy(&rect, &(s->_rect), sizeof(rect)); 2220 if (cam->module_param.force_munmap || cam->io == IO_READ)
2221 sn9c102_release_buffers(cam);
2093 2222
2094 { /* calculate the actual scaling factor */ 2223 err += sn9c102_set_pix_format(cam, pix);
2095 u32 a, b; 2224 err += sn9c102_set_crop(cam, &rect);
2096 a = rect.width * rect.height; 2225 if (s->set_pix_format)
2097 b = pix->width * pix->height; 2226 err += s->set_pix_format(cam, pix);
2098 scale = b ? (u8)((a / b) < 4 ? 1 : 2227 if (s->set_crop)
2099 ((a / b) < 16 ? 2 : 4)) : 1; 2228 err += s->set_crop(cam, &rect);
2100 } 2229 err += sn9c102_set_scale(cam, scale);
2101 2230
2102 rect.width = scale * pix->width; 2231 if (err) { /* atomic, no rollback in ioctl() */
2103 rect.height = scale * pix->height; 2232 cam->state |= DEV_MISCONFIGURED;
2104 2233 DBG(1, "VIDIOC_S_FMT failed because of hardware problems. To "
2105 if (rect.width < 16) 2234 "use the camera, close and open /dev/video%d again.",
2106 rect.width = 16; 2235 cam->v4ldev->minor);
2107 if (rect.height < 16) 2236 return -EIO;
2108 rect.height = 16; 2237 }
2109 if (rect.width > bounds->left + bounds->width - rect.left)
2110 rect.width = bounds->left + bounds->width - rect.left;
2111 if (rect.height > bounds->top + bounds->height - rect.top)
2112 rect.height = bounds->top + bounds->height - rect.top;
2113
2114 rect.width &= ~15L;
2115 rect.height &= ~15L;
2116
2117 { /* adjust the scaling factor */
2118 u32 a, b;
2119 a = rect.width * rect.height;
2120 b = pix->width * pix->height;
2121 scale = b ? (u8)((a / b) < 4 ? 1 :
2122 ((a / b) < 16 ? 2 : 4)) : 1;
2123 }
2124 2238
2125 pix->width = rect.width / scale; 2239 memcpy(pfmt, pix, sizeof(*pix));
2126 pix->height = rect.height / scale; 2240 memcpy(&(s->_rect), &rect, sizeof(rect));
2127
2128 if (pix->pixelformat != V4L2_PIX_FMT_SN9C10X &&
2129 pix->pixelformat != V4L2_PIX_FMT_SBGGR8)
2130 pix->pixelformat = pfmt->pixelformat;
2131 pix->priv = pfmt->priv; /* bpp */
2132 pix->colorspace = pfmt->colorspace;
2133 pix->bytesperline = (pix->pixelformat == V4L2_PIX_FMT_SN9C10X)
2134 ? 0 : (pix->width * pix->priv) / 8;
2135 pix->sizeimage = pix->height * ((pix->width * pix->priv) / 8);
2136 pix->field = V4L2_FIELD_NONE;
2137
2138 if (cmd == VIDIOC_TRY_FMT) {
2139 if (copy_to_user(arg, &format, sizeof(format)))
2140 return -EFAULT;
2141 return 0;
2142 }
2143 2241
2144 if (cam->module_param.force_munmap) 2242 if ((cam->module_param.force_munmap || cam->io == IO_READ) &&
2145 for (i = 0; i < cam->nbuffers; i++) 2243 nbuffers != sn9c102_request_buffers(cam, nbuffers, cam->io)) {
2146 if (cam->frame[i].vma_use_count) { 2244 cam->state |= DEV_MISCONFIGURED;
2147 DBG(3, "VIDIOC_S_FMT failed. " 2245 DBG(1, "VIDIOC_S_FMT failed because of not enough memory. To "
2148 "Unmap the buffers first.") 2246 "use the camera, close and open /dev/video%d again.",
2149 return -EINVAL; 2247 cam->v4ldev->minor);
2150 } 2248 return -ENOMEM;
2249 }
2151 2250
2152 if (cam->stream == STREAM_ON) 2251 if (cam->io == IO_READ)
2153 if ((err = sn9c102_stream_interrupt(cam))) 2252 sn9c102_empty_framequeues(cam);
2154 return err; 2253 else if (cam->module_param.force_munmap)
2254 sn9c102_requeue_outqueue(cam);
2155 2255
2156 if (copy_to_user(arg, &format, sizeof(format))) { 2256 cam->stream = stream;
2157 cam->stream = stream;
2158 return -EFAULT;
2159 }
2160 2257
2161 if (cam->module_param.force_munmap || cam->io == IO_READ) 2258 return 0;
2162 sn9c102_release_buffers(cam); 2259}
2163
2164 err += sn9c102_set_pix_format(cam, pix);
2165 err += sn9c102_set_crop(cam, &rect);
2166 if (s->set_pix_format)
2167 err += s->set_pix_format(cam, pix);
2168 if (s->set_crop)
2169 err += s->set_crop(cam, &rect);
2170 err += sn9c102_set_scale(cam, scale);
2171
2172 if (err) { /* atomic, no rollback in ioctl() */
2173 cam->state |= DEV_MISCONFIGURED;
2174 DBG(1, "VIDIOC_S_FMT failed because of hardware "
2175 "problems. To use the camera, close and open "
2176 "/dev/video%d again.", cam->v4ldev->minor)
2177 return -EIO;
2178 }
2179 2260
2180 memcpy(pfmt, pix, sizeof(*pix));
2181 memcpy(&(s->_rect), &rect, sizeof(rect));
2182 2261
2183 if ((cam->module_param.force_munmap || cam->io == IO_READ) && 2262static int
2184 nbuffers != sn9c102_request_buffers(cam, nbuffers, 2263sn9c102_vidioc_g_jpegcomp(struct sn9c102_device* cam, void __user * arg)
2185 cam->io)) { 2264{
2186 cam->state |= DEV_MISCONFIGURED; 2265 if (copy_to_user(arg, &cam->compression,
2187 DBG(1, "VIDIOC_S_FMT failed because of not enough " 2266 sizeof(cam->compression)))
2188 "memory. To use the camera, close and open " 2267 return -EFAULT;
2189 "/dev/video%d again.", cam->v4ldev->minor)
2190 return -ENOMEM;
2191 }
2192 2268
2193 cam->stream = stream; 2269 return 0;
2270}
2194 2271
2195 return 0;
2196 }
2197 2272
2198 case VIDIOC_G_JPEGCOMP: 2273static int
2199 { 2274sn9c102_vidioc_s_jpegcomp(struct sn9c102_device* cam, void __user * arg)
2200 if (copy_to_user(arg, &cam->compression, 2275{
2201 sizeof(cam->compression))) 2276 struct v4l2_jpegcompression jc;
2202 return -EFAULT; 2277 const enum sn9c102_stream_state stream = cam->stream;
2278 int err = 0;
2203 2279
2204 return 0; 2280 if (copy_from_user(&jc, arg, sizeof(jc)))
2205 } 2281 return -EFAULT;
2206 2282
2207 case VIDIOC_S_JPEGCOMP: 2283 if (jc.quality != 0 && jc.quality != 1)
2208 { 2284 return -EINVAL;
2209 struct v4l2_jpegcompression jc;
2210 const enum sn9c102_stream_state stream = cam->stream;
2211 int err = 0;
2212 2285
2213 if (copy_from_user(&jc, arg, sizeof(jc))) 2286 if (cam->stream == STREAM_ON)
2214 return -EFAULT; 2287 if ((err = sn9c102_stream_interrupt(cam)))
2288 return err;
2215 2289
2216 if (jc.quality != 0 && jc.quality != 1) 2290 err += sn9c102_set_compression(cam, &jc);
2217 return -EINVAL; 2291 if (err) { /* atomic, no rollback in ioctl() */
2292 cam->state |= DEV_MISCONFIGURED;
2293 DBG(1, "VIDIOC_S_JPEGCOMP failed because of hardware "
2294 "problems. To use the camera, close and open "
2295 "/dev/video%d again.", cam->v4ldev->minor);
2296 return -EIO;
2297 }
2218 2298
2219 if (cam->stream == STREAM_ON) 2299 cam->compression.quality = jc.quality;
2220 if ((err = sn9c102_stream_interrupt(cam)))
2221 return err;
2222 2300
2223 err += sn9c102_set_compression(cam, &jc); 2301 cam->stream = stream;
2224 if (err) { /* atomic, no rollback in ioctl() */
2225 cam->state |= DEV_MISCONFIGURED;
2226 DBG(1, "VIDIOC_S_JPEGCOMP failed because of hardware "
2227 "problems. To use the camera, close and open "
2228 "/dev/video%d again.", cam->v4ldev->minor)
2229 return -EIO;
2230 }
2231 2302
2232 cam->compression.quality = jc.quality; 2303 return 0;
2304}
2233 2305
2234 cam->stream = stream;
2235 2306
2236 return 0; 2307static int
2237 } 2308sn9c102_vidioc_reqbufs(struct sn9c102_device* cam, void __user * arg)
2309{
2310 struct v4l2_requestbuffers rb;
2311 u32 i;
2312 int err;
2238 2313
2239 case VIDIOC_REQBUFS: 2314 if (copy_from_user(&rb, arg, sizeof(rb)))
2240 { 2315 return -EFAULT;
2241 struct v4l2_requestbuffers rb;
2242 u32 i;
2243 int err;
2244 2316
2245 if (copy_from_user(&rb, arg, sizeof(rb))) 2317 if (rb.type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
2246 return -EFAULT; 2318 rb.memory != V4L2_MEMORY_MMAP)
2319 return -EINVAL;
2247 2320
2248 if (rb.type != V4L2_BUF_TYPE_VIDEO_CAPTURE || 2321 if (cam->io == IO_READ) {
2249 rb.memory != V4L2_MEMORY_MMAP) 2322 DBG(3, "Close and open the device again to choose the mmap "
2250 return -EINVAL; 2323 "I/O method");
2324 return -EINVAL;
2325 }
2251 2326
2252 if (cam->io == IO_READ) { 2327 for (i = 0; i < cam->nbuffers; i++)
2253 DBG(3, "Close and open the device again to choose " 2328 if (cam->frame[i].vma_use_count) {
2254 "the mmap I/O method") 2329 DBG(3, "VIDIOC_REQBUFS failed. Previous buffers are "
2330 "still mapped.");
2255 return -EINVAL; 2331 return -EINVAL;
2256 } 2332 }
2257 2333
2258 for (i = 0; i < cam->nbuffers; i++) 2334 if (cam->stream == STREAM_ON)
2259 if (cam->frame[i].vma_use_count) { 2335 if ((err = sn9c102_stream_interrupt(cam)))
2260 DBG(3, "VIDIOC_REQBUFS failed. " 2336 return err;
2261 "Previous buffers are still mapped.")
2262 return -EINVAL;
2263 }
2264 2337
2265 if (cam->stream == STREAM_ON) 2338 sn9c102_empty_framequeues(cam);
2266 if ((err = sn9c102_stream_interrupt(cam)))
2267 return err;
2268 2339
2269 sn9c102_empty_framequeues(cam); 2340 sn9c102_release_buffers(cam);
2341 if (rb.count)
2342 rb.count = sn9c102_request_buffers(cam, rb.count, IO_MMAP);
2270 2343
2344 if (copy_to_user(arg, &rb, sizeof(rb))) {
2271 sn9c102_release_buffers(cam); 2345 sn9c102_release_buffers(cam);
2272 if (rb.count) 2346 cam->io = IO_NONE;
2273 rb.count = sn9c102_request_buffers(cam, rb.count, 2347 return -EFAULT;
2274 IO_MMAP); 2348 }
2275 2349
2276 if (copy_to_user(arg, &rb, sizeof(rb))) { 2350 cam->io = rb.count ? IO_MMAP : IO_NONE;
2277 sn9c102_release_buffers(cam);
2278 cam->io = IO_NONE;
2279 return -EFAULT;
2280 }
2281 2351
2282 cam->io = rb.count ? IO_MMAP : IO_NONE; 2352 return 0;
2353}
2283 2354
2284 return 0;
2285 }
2286 2355
2287 case VIDIOC_QUERYBUF: 2356static int
2288 { 2357sn9c102_vidioc_querybuf(struct sn9c102_device* cam, void __user * arg)
2289 struct v4l2_buffer b; 2358{
2359 struct v4l2_buffer b;
2290 2360
2291 if (copy_from_user(&b, arg, sizeof(b))) 2361 if (copy_from_user(&b, arg, sizeof(b)))
2292 return -EFAULT; 2362 return -EFAULT;
2293 2363
2294 if (b.type != V4L2_BUF_TYPE_VIDEO_CAPTURE || 2364 if (b.type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
2295 b.index >= cam->nbuffers || cam->io != IO_MMAP) 2365 b.index >= cam->nbuffers || cam->io != IO_MMAP)
2296 return -EINVAL; 2366 return -EINVAL;
2297 2367
2298 memcpy(&b, &cam->frame[b.index].buf, sizeof(b)); 2368 memcpy(&b, &cam->frame[b.index].buf, sizeof(b));
2299 2369
2300 if (cam->frame[b.index].vma_use_count) 2370 if (cam->frame[b.index].vma_use_count)
2301 b.flags |= V4L2_BUF_FLAG_MAPPED; 2371 b.flags |= V4L2_BUF_FLAG_MAPPED;
2302 2372
2303 if (cam->frame[b.index].state == F_DONE) 2373 if (cam->frame[b.index].state == F_DONE)
2304 b.flags |= V4L2_BUF_FLAG_DONE; 2374 b.flags |= V4L2_BUF_FLAG_DONE;
2305 else if (cam->frame[b.index].state != F_UNUSED) 2375 else if (cam->frame[b.index].state != F_UNUSED)
2306 b.flags |= V4L2_BUF_FLAG_QUEUED; 2376 b.flags |= V4L2_BUF_FLAG_QUEUED;
2307 2377
2308 if (copy_to_user(arg, &b, sizeof(b))) 2378 if (copy_to_user(arg, &b, sizeof(b)))
2309 return -EFAULT; 2379 return -EFAULT;
2310 2380
2311 return 0; 2381 return 0;
2312 } 2382}
2313 2383
2314 case VIDIOC_QBUF:
2315 {
2316 struct v4l2_buffer b;
2317 unsigned long lock_flags;
2318 2384
2319 if (copy_from_user(&b, arg, sizeof(b))) 2385static int
2320 return -EFAULT; 2386sn9c102_vidioc_qbuf(struct sn9c102_device* cam, void __user * arg)
2387{
2388 struct v4l2_buffer b;
2389 unsigned long lock_flags;
2321 2390
2322 if (b.type != V4L2_BUF_TYPE_VIDEO_CAPTURE || 2391 if (copy_from_user(&b, arg, sizeof(b)))
2323 b.index >= cam->nbuffers || cam->io != IO_MMAP) 2392 return -EFAULT;
2324 return -EINVAL;
2325 2393
2326 if (cam->frame[b.index].state != F_UNUSED) 2394 if (b.type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
2327 return -EINVAL; 2395 b.index >= cam->nbuffers || cam->io != IO_MMAP)
2396 return -EINVAL;
2328 2397
2329 cam->frame[b.index].state = F_QUEUED; 2398 if (cam->frame[b.index].state != F_UNUSED)
2399 return -EINVAL;
2330 2400
2331 spin_lock_irqsave(&cam->queue_lock, lock_flags); 2401 cam->frame[b.index].state = F_QUEUED;
2332 list_add_tail(&cam->frame[b.index].frame, &cam->inqueue);
2333 spin_unlock_irqrestore(&cam->queue_lock, lock_flags);
2334 2402
2335 PDBGG("Frame #%lu queued", (unsigned long)b.index) 2403 spin_lock_irqsave(&cam->queue_lock, lock_flags);
2404 list_add_tail(&cam->frame[b.index].frame, &cam->inqueue);
2405 spin_unlock_irqrestore(&cam->queue_lock, lock_flags);
2336 2406
2337 return 0; 2407 PDBGG("Frame #%lu queued", (unsigned long)b.index);
2338 }
2339 2408
2340 case VIDIOC_DQBUF: 2409 return 0;
2341 { 2410}
2342 struct v4l2_buffer b;
2343 struct sn9c102_frame_t *f;
2344 unsigned long lock_flags;
2345 int err = 0;
2346 2411
2347 if (copy_from_user(&b, arg, sizeof(b)))
2348 return -EFAULT;
2349 2412
2350 if (b.type != V4L2_BUF_TYPE_VIDEO_CAPTURE || cam->io!= IO_MMAP) 2413static int
2414sn9c102_vidioc_dqbuf(struct sn9c102_device* cam, struct file* filp,
2415 void __user * arg)
2416{
2417 struct v4l2_buffer b;
2418 struct sn9c102_frame_t *f;
2419 unsigned long lock_flags;
2420 int err = 0;
2421
2422 if (copy_from_user(&b, arg, sizeof(b)))
2423 return -EFAULT;
2424
2425 if (b.type != V4L2_BUF_TYPE_VIDEO_CAPTURE || cam->io != IO_MMAP)
2426 return -EINVAL;
2427
2428 if (list_empty(&cam->outqueue)) {
2429 if (cam->stream == STREAM_OFF)
2351 return -EINVAL; 2430 return -EINVAL;
2431 if (filp->f_flags & O_NONBLOCK)
2432 return -EAGAIN;
2433 err = wait_event_interruptible
2434 ( cam->wait_frame,
2435 (!list_empty(&cam->outqueue)) ||
2436 (cam->state & DEV_DISCONNECTED) ||
2437 (cam->state & DEV_MISCONFIGURED) );
2438 if (err)
2439 return err;
2440 if (cam->state & DEV_DISCONNECTED)
2441 return -ENODEV;
2442 if (cam->state & DEV_MISCONFIGURED)
2443 return -EIO;
2444 }
2352 2445
2353 if (list_empty(&cam->outqueue)) { 2446 spin_lock_irqsave(&cam->queue_lock, lock_flags);
2354 if (cam->stream == STREAM_OFF) 2447 f = list_entry(cam->outqueue.next, struct sn9c102_frame_t, frame);
2355 return -EINVAL; 2448 list_del(cam->outqueue.next);
2356 if (filp->f_flags & O_NONBLOCK) 2449 spin_unlock_irqrestore(&cam->queue_lock, lock_flags);
2357 return -EAGAIN;
2358 err = wait_event_interruptible
2359 ( cam->wait_frame,
2360 (!list_empty(&cam->outqueue)) ||
2361 (cam->state & DEV_DISCONNECTED) ||
2362 (cam->state & DEV_MISCONFIGURED) );
2363 if (err)
2364 return err;
2365 if (cam->state & DEV_DISCONNECTED)
2366 return -ENODEV;
2367 if (cam->state & DEV_MISCONFIGURED)
2368 return -EIO;
2369 }
2370 2450
2371 spin_lock_irqsave(&cam->queue_lock, lock_flags); 2451 f->state = F_UNUSED;
2372 f = list_entry(cam->outqueue.next, struct sn9c102_frame_t,
2373 frame);
2374 list_del(cam->outqueue.next);
2375 spin_unlock_irqrestore(&cam->queue_lock, lock_flags);
2376 2452
2377 f->state = F_UNUSED; 2453 memcpy(&b, &f->buf, sizeof(b));
2454 if (f->vma_use_count)
2455 b.flags |= V4L2_BUF_FLAG_MAPPED;
2378 2456
2379 memcpy(&b, &f->buf, sizeof(b)); 2457 if (copy_to_user(arg, &b, sizeof(b)))
2380 if (f->vma_use_count) 2458 return -EFAULT;
2381 b.flags |= V4L2_BUF_FLAG_MAPPED;
2382 2459
2383 if (copy_to_user(arg, &b, sizeof(b))) 2460 PDBGG("Frame #%lu dequeued", (unsigned long)f->buf.index);
2384 return -EFAULT;
2385 2461
2386 PDBGG("Frame #%lu dequeued", (unsigned long)f->buf.index) 2462 return 0;
2463}
2387 2464
2388 return 0;
2389 }
2390 2465
2391 case VIDIOC_STREAMON: 2466static int
2392 { 2467sn9c102_vidioc_streamon(struct sn9c102_device* cam, void __user * arg)
2393 int type; 2468{
2469 int type;
2394 2470
2395 if (copy_from_user(&type, arg, sizeof(type))) 2471 if (copy_from_user(&type, arg, sizeof(type)))
2396 return -EFAULT; 2472 return -EFAULT;
2397 2473
2398 if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE || cam->io != IO_MMAP) 2474 if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE || cam->io != IO_MMAP)
2399 return -EINVAL; 2475 return -EINVAL;
2400 2476
2401 if (list_empty(&cam->inqueue)) 2477 if (list_empty(&cam->inqueue))
2402 return -EINVAL; 2478 return -EINVAL;
2403 2479
2404 cam->stream = STREAM_ON; 2480 cam->stream = STREAM_ON;
2405 2481
2406 DBG(3, "Stream on") 2482 DBG(3, "Stream on");
2407 2483
2408 return 0; 2484 return 0;
2409 } 2485}
2410 2486
2411 case VIDIOC_STREAMOFF:
2412 {
2413 int type, err;
2414 2487
2415 if (copy_from_user(&type, arg, sizeof(type))) 2488static int
2416 return -EFAULT; 2489sn9c102_vidioc_streamoff(struct sn9c102_device* cam, void __user * arg)
2490{
2491 int type, err;
2417 2492
2418 if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE || cam->io != IO_MMAP) 2493 if (copy_from_user(&type, arg, sizeof(type)))
2419 return -EINVAL; 2494 return -EFAULT;
2420 2495
2421 if (cam->stream == STREAM_ON) 2496 if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE || cam->io != IO_MMAP)
2422 if ((err = sn9c102_stream_interrupt(cam))) 2497 return -EINVAL;
2423 return err;
2424 2498
2425 sn9c102_empty_framequeues(cam); 2499 if (cam->stream == STREAM_ON)
2500 if ((err = sn9c102_stream_interrupt(cam)))
2501 return err;
2426 2502
2427 DBG(3, "Stream off") 2503 sn9c102_empty_framequeues(cam);
2428 2504
2429 return 0; 2505 DBG(3, "Stream off");
2430 }
2431 2506
2432 case VIDIOC_G_PARM: 2507 return 0;
2433 { 2508}
2434 struct v4l2_streamparm sp;
2435 2509
2436 if (copy_from_user(&sp, arg, sizeof(sp)))
2437 return -EFAULT;
2438 2510
2439 if (sp.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 2511static int
2440 return -EINVAL; 2512sn9c102_vidioc_g_parm(struct sn9c102_device* cam, void __user * arg)
2513{
2514 struct v4l2_streamparm sp;
2515
2516 if (copy_from_user(&sp, arg, sizeof(sp)))
2517 return -EFAULT;
2518
2519 if (sp.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
2520 return -EINVAL;
2521
2522 sp.parm.capture.extendedmode = 0;
2523 sp.parm.capture.readbuffers = cam->nreadbuffers;
2524
2525 if (copy_to_user(arg, &sp, sizeof(sp)))
2526 return -EFAULT;
2527
2528 return 0;
2529}
2530
2531
2532static int
2533sn9c102_vidioc_s_parm(struct sn9c102_device* cam, void __user * arg)
2534{
2535 struct v4l2_streamparm sp;
2536
2537 if (copy_from_user(&sp, arg, sizeof(sp)))
2538 return -EFAULT;
2539
2540 if (sp.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
2541 return -EINVAL;
2542
2543 sp.parm.capture.extendedmode = 0;
2441 2544
2442 sp.parm.capture.extendedmode = 0; 2545 if (sp.parm.capture.readbuffers == 0)
2443 sp.parm.capture.readbuffers = cam->nreadbuffers; 2546 sp.parm.capture.readbuffers = cam->nreadbuffers;
2444 2547
2445 if (copy_to_user(arg, &sp, sizeof(sp))) 2548 if (sp.parm.capture.readbuffers > SN9C102_MAX_FRAMES)
2446 return -EFAULT; 2549 sp.parm.capture.readbuffers = SN9C102_MAX_FRAMES;
2447 2550
2448 return 0; 2551 if (copy_to_user(arg, &sp, sizeof(sp)))
2449 } 2552 return -EFAULT;
2450 2553
2451 case VIDIOC_S_PARM_OLD: 2554 cam->nreadbuffers = sp.parm.capture.readbuffers;
2452 case VIDIOC_S_PARM:
2453 {
2454 struct v4l2_streamparm sp;
2455 2555
2456 if (copy_from_user(&sp, arg, sizeof(sp))) 2556 return 0;
2457 return -EFAULT; 2557}
2458 2558
2459 if (sp.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
2460 return -EINVAL;
2461 2559
2462 sp.parm.capture.extendedmode = 0; 2560static int sn9c102_ioctl_v4l2(struct inode* inode, struct file* filp,
2561 unsigned int cmd, void __user * arg)
2562{
2563 struct sn9c102_device* cam = video_get_drvdata(video_devdata(filp));
2564
2565 switch (cmd) {
2566
2567 case VIDIOC_QUERYCAP:
2568 return sn9c102_vidioc_querycap(cam, arg);
2463 2569
2464 if (sp.parm.capture.readbuffers == 0) 2570 case VIDIOC_ENUMINPUT:
2465 sp.parm.capture.readbuffers = cam->nreadbuffers; 2571 return sn9c102_vidioc_enuminput(cam, arg);
2466 2572
2467 if (sp.parm.capture.readbuffers > SN9C102_MAX_FRAMES) 2573 case VIDIOC_G_INPUT:
2468 sp.parm.capture.readbuffers = SN9C102_MAX_FRAMES; 2574 case VIDIOC_S_INPUT:
2575 return sn9c102_vidioc_gs_input(cam, arg);
2469 2576
2470 if (copy_to_user(arg, &sp, sizeof(sp))) 2577 case VIDIOC_QUERYCTRL:
2471 return -EFAULT; 2578 return sn9c102_vidioc_query_ctrl(cam, arg);
2472 2579
2473 cam->nreadbuffers = sp.parm.capture.readbuffers; 2580 case VIDIOC_G_CTRL:
2581 return sn9c102_vidioc_g_ctrl(cam, arg);
2474 2582
2475 return 0; 2583 case VIDIOC_S_CTRL_OLD:
2476 } 2584 case VIDIOC_S_CTRL:
2585 return sn9c102_vidioc_s_ctrl(cam, arg);
2586
2587 case VIDIOC_CROPCAP_OLD:
2588 case VIDIOC_CROPCAP:
2589 return sn9c102_vidioc_cropcap(cam, arg);
2590
2591 case VIDIOC_G_CROP:
2592 return sn9c102_vidioc_g_crop(cam, arg);
2593
2594 case VIDIOC_S_CROP:
2595 return sn9c102_vidioc_s_crop(cam, arg);
2596
2597 case VIDIOC_ENUM_FMT:
2598 return sn9c102_vidioc_enum_fmt(cam, arg);
2599
2600 case VIDIOC_G_FMT:
2601 return sn9c102_vidioc_g_fmt(cam, arg);
2602
2603 case VIDIOC_TRY_FMT:
2604 case VIDIOC_S_FMT:
2605 return sn9c102_vidioc_try_s_fmt(cam, cmd, arg);
2606
2607 case VIDIOC_G_JPEGCOMP:
2608 return sn9c102_vidioc_g_jpegcomp(cam, arg);
2609
2610 case VIDIOC_S_JPEGCOMP:
2611 return sn9c102_vidioc_s_jpegcomp(cam, arg);
2612
2613 case VIDIOC_REQBUFS:
2614 return sn9c102_vidioc_reqbufs(cam, arg);
2615
2616 case VIDIOC_QUERYBUF:
2617 return sn9c102_vidioc_querybuf(cam, arg);
2618
2619 case VIDIOC_QBUF:
2620 return sn9c102_vidioc_qbuf(cam, arg);
2621
2622 case VIDIOC_DQBUF:
2623 return sn9c102_vidioc_dqbuf(cam, filp, arg);
2624
2625 case VIDIOC_STREAMON:
2626 return sn9c102_vidioc_streamon(cam, arg);
2627
2628 case VIDIOC_STREAMOFF:
2629 return sn9c102_vidioc_streamoff(cam, arg);
2630
2631 case VIDIOC_G_PARM:
2632 return sn9c102_vidioc_g_parm(cam, arg);
2633
2634 case VIDIOC_S_PARM_OLD:
2635 case VIDIOC_S_PARM:
2636 return sn9c102_vidioc_s_parm(cam, arg);
2477 2637
2478 case VIDIOC_G_STD: 2638 case VIDIOC_G_STD:
2479 case VIDIOC_S_STD: 2639 case VIDIOC_S_STD:
@@ -2499,17 +2659,20 @@ static int sn9c102_ioctl(struct inode* inode, struct file* filp,
2499 return -ERESTARTSYS; 2659 return -ERESTARTSYS;
2500 2660
2501 if (cam->state & DEV_DISCONNECTED) { 2661 if (cam->state & DEV_DISCONNECTED) {
2502 DBG(1, "Device not present") 2662 DBG(1, "Device not present");
2503 up(&cam->fileop_sem); 2663 up(&cam->fileop_sem);
2504 return -ENODEV; 2664 return -ENODEV;
2505 } 2665 }
2506 2666
2507 if (cam->state & DEV_MISCONFIGURED) { 2667 if (cam->state & DEV_MISCONFIGURED) {
2508 DBG(1, "The camera is misconfigured. Close and open it again.") 2668 DBG(1, "The camera is misconfigured. Close and open it "
2669 "again.");
2509 up(&cam->fileop_sem); 2670 up(&cam->fileop_sem);
2510 return -EIO; 2671 return -EIO;
2511 } 2672 }
2512 2673
2674 V4LDBG(3, "sn9c102", cmd);
2675
2513 err = sn9c102_ioctl_v4l2(inode, filp, cmd, (void __user *)arg); 2676 err = sn9c102_ioctl_v4l2(inode, filp, cmd, (void __user *)arg);
2514 2677
2515 up(&cam->fileop_sem); 2678 up(&cam->fileop_sem);
@@ -2517,9 +2680,10 @@ static int sn9c102_ioctl(struct inode* inode, struct file* filp,
2517 return err; 2680 return err;
2518} 2681}
2519 2682
2683/*****************************************************************************/
2520 2684
2521static struct file_operations sn9c102_fops = { 2685static struct file_operations sn9c102_fops = {
2522 .owner = THIS_MODULE, 2686 .owner = THIS_MODULE,
2523 .open = sn9c102_open, 2687 .open = sn9c102_open,
2524 .release = sn9c102_release, 2688 .release = sn9c102_release,
2525 .ioctl = sn9c102_ioctl, 2689 .ioctl = sn9c102_ioctl,
@@ -2538,36 +2702,22 @@ sn9c102_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
2538 struct usb_device *udev = interface_to_usbdev(intf); 2702 struct usb_device *udev = interface_to_usbdev(intf);
2539 struct sn9c102_device* cam; 2703 struct sn9c102_device* cam;
2540 static unsigned int dev_nr = 0; 2704 static unsigned int dev_nr = 0;
2541 unsigned int i, n; 2705 unsigned int i;
2542 int err = 0, r; 2706 int err = 0, r;
2543 2707
2544 n = ARRAY_SIZE(sn9c102_id_table); 2708 if (!(cam = kzalloc(sizeof(struct sn9c102_device), GFP_KERNEL)))
2545 for (i = 0; i < n-1; i++)
2546 if (le16_to_cpu(udev->descriptor.idVendor) ==
2547 sn9c102_id_table[i].idVendor &&
2548 le16_to_cpu(udev->descriptor.idProduct) ==
2549 sn9c102_id_table[i].idProduct)
2550 break;
2551 if (i == n-1)
2552 return -ENODEV;
2553
2554 if (!(cam = kmalloc(sizeof(struct sn9c102_device), GFP_KERNEL)))
2555 return -ENOMEM; 2709 return -ENOMEM;
2556 memset(cam, 0, sizeof(*cam));
2557 2710
2558 cam->usbdev = udev; 2711 cam->usbdev = udev;
2559 2712
2560 memcpy(&cam->dev, &udev->dev, sizeof(struct device)); 2713 if (!(cam->control_buffer = kzalloc(8, GFP_KERNEL))) {
2561 2714 DBG(1, "kmalloc() failed");
2562 if (!(cam->control_buffer = kmalloc(8, GFP_KERNEL))) {
2563 DBG(1, "kmalloc() failed")
2564 err = -ENOMEM; 2715 err = -ENOMEM;
2565 goto fail; 2716 goto fail;
2566 } 2717 }
2567 memset(cam->control_buffer, 0, 8);
2568 2718
2569 if (!(cam->v4ldev = video_device_alloc())) { 2719 if (!(cam->v4ldev = video_device_alloc())) {
2570 DBG(1, "video_device_alloc() failed") 2720 DBG(1, "video_device_alloc() failed");
2571 err = -ENOMEM; 2721 err = -ENOMEM;
2572 goto fail; 2722 goto fail;
2573 } 2723 }
@@ -2577,25 +2727,22 @@ sn9c102_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
2577 r = sn9c102_read_reg(cam, 0x00); 2727 r = sn9c102_read_reg(cam, 0x00);
2578 if (r < 0 || r != 0x10) { 2728 if (r < 0 || r != 0x10) {
2579 DBG(1, "Sorry, this is not a SN9C10x based camera " 2729 DBG(1, "Sorry, this is not a SN9C10x based camera "
2580 "(vid/pid 0x%04X/0x%04X)", 2730 "(vid/pid 0x%04X/0x%04X)", id->idVendor, id->idProduct);
2581 sn9c102_id_table[i].idVendor,sn9c102_id_table[i].idProduct)
2582 err = -ENODEV; 2731 err = -ENODEV;
2583 goto fail; 2732 goto fail;
2584 } 2733 }
2585 2734
2586 cam->bridge = (sn9c102_id_table[i].idProduct & 0xffc0) == 0x6080 ? 2735 cam->bridge = (id->idProduct & 0xffc0) == 0x6080 ?
2587 BRIDGE_SN9C103 : BRIDGE_SN9C102; 2736 BRIDGE_SN9C103 : BRIDGE_SN9C102;
2588 switch (cam->bridge) { 2737 switch (cam->bridge) {
2589 case BRIDGE_SN9C101: 2738 case BRIDGE_SN9C101:
2590 case BRIDGE_SN9C102: 2739 case BRIDGE_SN9C102:
2591 DBG(2, "SN9C10[12] PC Camera Controller detected " 2740 DBG(2, "SN9C10[12] PC Camera Controller detected "
2592 "(vid/pid 0x%04X/0x%04X)", sn9c102_id_table[i].idVendor, 2741 "(vid/pid 0x%04X/0x%04X)", id->idVendor, id->idProduct);
2593 sn9c102_id_table[i].idProduct)
2594 break; 2742 break;
2595 case BRIDGE_SN9C103: 2743 case BRIDGE_SN9C103:
2596 DBG(2, "SN9C103 PC Camera Controller detected " 2744 DBG(2, "SN9C103 PC Camera Controller detected "
2597 "(vid/pid 0x%04X/0x%04X)", sn9c102_id_table[i].idVendor, 2745 "(vid/pid 0x%04X/0x%04X)", id->idVendor, id->idProduct);
2598 sn9c102_id_table[i].idProduct)
2599 break; 2746 break;
2600 } 2747 }
2601 2748
@@ -2606,24 +2753,24 @@ sn9c102_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
2606 } 2753 }
2607 2754
2608 if (!err && cam->sensor) { 2755 if (!err && cam->sensor) {
2609 DBG(2, "%s image sensor detected", cam->sensor->name) 2756 DBG(2, "%s image sensor detected", cam->sensor->name);
2610 DBG(3, "Support for %s maintained by %s", 2757 DBG(3, "Support for %s maintained by %s",
2611 cam->sensor->name, cam->sensor->maintainer) 2758 cam->sensor->name, cam->sensor->maintainer);
2612 } else { 2759 } else {
2613 DBG(1, "No supported image sensor detected") 2760 DBG(1, "No supported image sensor detected");
2614 err = -ENODEV; 2761 err = -ENODEV;
2615 goto fail; 2762 goto fail;
2616 } 2763 }
2617 2764
2618 if (sn9c102_init(cam)) { 2765 if (sn9c102_init(cam)) {
2619 DBG(1, "Initialization failed. I will retry on open().") 2766 DBG(1, "Initialization failed. I will retry on open().");
2620 cam->state |= DEV_MISCONFIGURED; 2767 cam->state |= DEV_MISCONFIGURED;
2621 } 2768 }
2622 2769
2623 strcpy(cam->v4ldev->name, "SN9C10x PC Camera"); 2770 strcpy(cam->v4ldev->name, "SN9C10x PC Camera");
2624 cam->v4ldev->owner = THIS_MODULE; 2771 cam->v4ldev->owner = THIS_MODULE;
2625 cam->v4ldev->type = VID_TYPE_CAPTURE | VID_TYPE_SCALES; 2772 cam->v4ldev->type = VID_TYPE_CAPTURE | VID_TYPE_SCALES;
2626 cam->v4ldev->hardware = VID_HARDWARE_SN9C102; 2773 cam->v4ldev->hardware = 0;
2627 cam->v4ldev->fops = &sn9c102_fops; 2774 cam->v4ldev->fops = &sn9c102_fops;
2628 cam->v4ldev->minor = video_nr[dev_nr]; 2775 cam->v4ldev->minor = video_nr[dev_nr];
2629 cam->v4ldev->release = video_device_release; 2776 cam->v4ldev->release = video_device_release;
@@ -2634,23 +2781,25 @@ sn9c102_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
2634 err = video_register_device(cam->v4ldev, VFL_TYPE_GRABBER, 2781 err = video_register_device(cam->v4ldev, VFL_TYPE_GRABBER,
2635 video_nr[dev_nr]); 2782 video_nr[dev_nr]);
2636 if (err) { 2783 if (err) {
2637 DBG(1, "V4L2 device registration failed") 2784 DBG(1, "V4L2 device registration failed");
2638 if (err == -ENFILE && video_nr[dev_nr] == -1) 2785 if (err == -ENFILE && video_nr[dev_nr] == -1)
2639 DBG(1, "Free /dev/videoX node not found") 2786 DBG(1, "Free /dev/videoX node not found");
2640 video_nr[dev_nr] = -1; 2787 video_nr[dev_nr] = -1;
2641 dev_nr = (dev_nr < SN9C102_MAX_DEVICES-1) ? dev_nr+1 : 0; 2788 dev_nr = (dev_nr < SN9C102_MAX_DEVICES-1) ? dev_nr+1 : 0;
2642 up(&cam->dev_sem); 2789 up(&cam->dev_sem);
2643 goto fail; 2790 goto fail;
2644 } 2791 }
2645 2792
2646 DBG(2, "V4L2 device registered as /dev/video%d", cam->v4ldev->minor) 2793 DBG(2, "V4L2 device registered as /dev/video%d", cam->v4ldev->minor);
2647 2794
2648 cam->module_param.force_munmap = force_munmap[dev_nr]; 2795 cam->module_param.force_munmap = force_munmap[dev_nr];
2649 2796
2650 dev_nr = (dev_nr < SN9C102_MAX_DEVICES-1) ? dev_nr+1 : 0; 2797 dev_nr = (dev_nr < SN9C102_MAX_DEVICES-1) ? dev_nr+1 : 0;
2651 2798
2799#ifdef CONFIG_VIDEO_ADV_DEBUG
2652 sn9c102_create_sysfs(cam); 2800 sn9c102_create_sysfs(cam);
2653 DBG(2, "Optional device control through 'sysfs' interface ready") 2801 DBG(2, "Optional device control through 'sysfs' interface ready");
2802#endif
2654 2803
2655 usb_set_intfdata(intf, cam); 2804 usb_set_intfdata(intf, cam);
2656 2805
@@ -2680,14 +2829,14 @@ static void sn9c102_usb_disconnect(struct usb_interface* intf)
2680 2829
2681 down(&cam->dev_sem); 2830 down(&cam->dev_sem);
2682 2831
2683 DBG(2, "Disconnecting %s...", cam->v4ldev->name) 2832 DBG(2, "Disconnecting %s...", cam->v4ldev->name);
2684 2833
2685 wake_up_interruptible_all(&cam->open); 2834 wake_up_interruptible_all(&cam->open);
2686 2835
2687 if (cam->users) { 2836 if (cam->users) {
2688 DBG(2, "Device /dev/video%d is open! Deregistration and " 2837 DBG(2, "Device /dev/video%d is open! Deregistration and "
2689 "memory deallocation are deferred on close.", 2838 "memory deallocation are deferred on close.",
2690 cam->v4ldev->minor) 2839 cam->v4ldev->minor);
2691 cam->state |= DEV_MISCONFIGURED; 2840 cam->state |= DEV_MISCONFIGURED;
2692 sn9c102_stop_transfer(cam); 2841 sn9c102_stop_transfer(cam);
2693 cam->state |= DEV_DISCONNECTED; 2842 cam->state |= DEV_DISCONNECTED;
@@ -2720,11 +2869,11 @@ static int __init sn9c102_module_init(void)
2720{ 2869{
2721 int err = 0; 2870 int err = 0;
2722 2871
2723 KDBG(2, SN9C102_MODULE_NAME " v" SN9C102_MODULE_VERSION) 2872 KDBG(2, SN9C102_MODULE_NAME " v" SN9C102_MODULE_VERSION);
2724 KDBG(3, SN9C102_MODULE_AUTHOR) 2873 KDBG(3, SN9C102_MODULE_AUTHOR);
2725 2874
2726 if ((err = usb_register(&sn9c102_usb_driver))) 2875 if ((err = usb_register(&sn9c102_usb_driver)))
2727 KDBG(1, "usb_register() failed") 2876 KDBG(1, "usb_register() failed");
2728 2877
2729 return err; 2878 return err;
2730} 2879}
diff --git a/drivers/usb/media/sn9c102_hv7131d.c b/drivers/usb/media/sn9c102_hv7131d.c
index 18070d5333cf..46c12ec3ca62 100644
--- a/drivers/usb/media/sn9c102_hv7131d.c
+++ b/drivers/usb/media/sn9c102_hv7131d.c
@@ -2,7 +2,7 @@
2 * Plug-in for HV7131D image sensor connected to the SN9C10x PC Camera * 2 * Plug-in for HV7131D image sensor connected to the SN9C10x PC Camera *
3 * Controllers * 3 * Controllers *
4 * * 4 * *
5 * Copyright (C) 2004-2005 by Luca Risolia <luca.risolia@studio.unibo.it> * 5 * Copyright (C) 2004-2006 by Luca Risolia <luca.risolia@studio.unibo.it> *
6 * * 6 * *
7 * This program is free software; you can redistribute it and/or modify * 7 * This program is free software; you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by * 8 * it under the terms of the GNU General Public License as published by *
diff --git a/drivers/usb/media/sn9c102_mi0343.c b/drivers/usb/media/sn9c102_mi0343.c
index 86676abf3547..d9aa7a61095d 100644
--- a/drivers/usb/media/sn9c102_mi0343.c
+++ b/drivers/usb/media/sn9c102_mi0343.c
@@ -2,7 +2,7 @@
2 * Plug-in for MI-0343 image sensor connected to the SN9C10x PC Camera * 2 * Plug-in for MI-0343 image sensor connected to the SN9C10x PC Camera *
3 * Controllers * 3 * Controllers *
4 * * 4 * *
5 * Copyright (C) 2004-2005 by Luca Risolia <luca.risolia@studio.unibo.it> * 5 * Copyright (C) 2004-2006 by Luca Risolia <luca.risolia@studio.unibo.it> *
6 * * 6 * *
7 * This program is free software; you can redistribute it and/or modify * 7 * This program is free software; you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by * 8 * it under the terms of the GNU General Public License as published by *
diff --git a/drivers/usb/media/sn9c102_ov7630.c b/drivers/usb/media/sn9c102_ov7630.c
index d27c5aedeaf8..4a36519b5af4 100644
--- a/drivers/usb/media/sn9c102_ov7630.c
+++ b/drivers/usb/media/sn9c102_ov7630.c
@@ -2,7 +2,7 @@
2 * Plug-in for OV7630 image sensor connected to the SN9C10x PC Camera * 2 * Plug-in for OV7630 image sensor connected to the SN9C10x PC Camera *
3 * Controllers * 3 * Controllers *
4 * * 4 * *
5 * Copyright (C) 2005 by Luca Risolia <luca.risolia@studio.unibo.it> * 5 * Copyright (C) 2005-2006 by Luca Risolia <luca.risolia@studio.unibo.it> *
6 * * 6 * *
7 * This program is free software; you can redistribute it and/or modify * 7 * This program is free software; you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by * 8 * it under the terms of the GNU General Public License as published by *
@@ -375,8 +375,10 @@ int sn9c102_probe_ov7630(struct sn9c102_device* cam)
375 375
376 sn9c102_attach_sensor(cam, &ov7630); 376 sn9c102_attach_sensor(cam, &ov7630);
377 377
378 if (le16_to_cpu(ov7630.usbdev->descriptor.idProduct) != 0x608f && 378 if (le16_to_cpu(ov7630.usbdev->descriptor.idProduct) != 0x602c &&
379 le16_to_cpu(ov7630.usbdev->descriptor.idProduct) != 0x602c) 379 le16_to_cpu(ov7630.usbdev->descriptor.idProduct) != 0x602d &&
380 le16_to_cpu(ov7630.usbdev->descriptor.idProduct) != 0x608f &&
381 le16_to_cpu(ov7630.usbdev->descriptor.idProduct) != 0x60b0)
380 return -ENODEV; 382 return -ENODEV;
381 383
382 err += sn9c102_write_reg(cam, 0x01, 0x01); 384 err += sn9c102_write_reg(cam, 0x01, 0x01);
diff --git a/drivers/usb/media/sn9c102_pas106b.c b/drivers/usb/media/sn9c102_pas106b.c
index 48e3ec39d4e2..b1dee78abe04 100644
--- a/drivers/usb/media/sn9c102_pas106b.c
+++ b/drivers/usb/media/sn9c102_pas106b.c
@@ -2,7 +2,7 @@
2 * Plug-in for PAS106B image sensor connected to the SN9C10x PC Camera * 2 * Plug-in for PAS106B image sensor connected to the SN9C10x PC Camera *
3 * Controllers * 3 * Controllers *
4 * * 4 * *
5 * Copyright (C) 2004-2005 by Luca Risolia <luca.risolia@studio.unibo.it> * 5 * Copyright (C) 2004-2006 by Luca Risolia <luca.risolia@studio.unibo.it> *
6 * * 6 * *
7 * This program is free software; you can redistribute it and/or modify * 7 * This program is free software; you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by * 8 * it under the terms of the GNU General Public License as published by *
diff --git a/drivers/usb/media/sn9c102_sensor.h b/drivers/usb/media/sn9c102_sensor.h
index a45166c3488c..7d953b24f2f2 100644
--- a/drivers/usb/media/sn9c102_sensor.h
+++ b/drivers/usb/media/sn9c102_sensor.h
@@ -1,7 +1,7 @@
1/*************************************************************************** 1/***************************************************************************
2 * API for image sensors connected to the SN9C10x PC Camera Controllers * 2 * API for image sensors connected to the SN9C10x PC Camera Controllers *
3 * * 3 * *
4 * Copyright (C) 2004-2005 by Luca Risolia <luca.risolia@studio.unibo.it> * 4 * Copyright (C) 2004-2006 by Luca Risolia <luca.risolia@studio.unibo.it> *
5 * * 5 * *
6 * This program is free software; you can redistribute it and/or modify * 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 * 7 * it under the terms of the GNU General Public License as published by *
@@ -92,7 +92,18 @@ extern void
92sn9c102_attach_sensor(struct sn9c102_device* cam, 92sn9c102_attach_sensor(struct sn9c102_device* cam,
93 struct sn9c102_sensor* sensor); 93 struct sn9c102_sensor* sensor);
94 94
95/* Each SN9C10X camera has proper PID/VID identifiers. Add them here in case.*/ 95/*
96 Each SN9C10x camera has proper PID/VID identifiers.
97 SN9C103 supports multiple interfaces, but we only handle the video class
98 interface.
99*/
100#define SN9C102_USB_DEVICE(vend, prod, intclass) \
101 .match_flags = USB_DEVICE_ID_MATCH_DEVICE | \
102 USB_DEVICE_ID_MATCH_INT_CLASS, \
103 .idVendor = (vend), \
104 .idProduct = (prod), \
105 .bInterfaceClass = (intclass)
106
96#define SN9C102_ID_TABLE \ 107#define SN9C102_ID_TABLE \
97static const struct usb_device_id sn9c102_id_table[] = { \ 108static const struct usb_device_id sn9c102_id_table[] = { \
98 { USB_DEVICE(0x0c45, 0x6001), }, /* TAS5110C1B */ \ 109 { USB_DEVICE(0x0c45, 0x6001), }, /* TAS5110C1B */ \
@@ -107,33 +118,34 @@ static const struct usb_device_id sn9c102_id_table[] = { \
107 { USB_DEVICE(0x0c45, 0x602b), }, /* MI-0343 */ \ 118 { USB_DEVICE(0x0c45, 0x602b), }, /* MI-0343 */ \
108 { USB_DEVICE(0x0c45, 0x602c), }, /* OV7630 */ \ 119 { USB_DEVICE(0x0c45, 0x602c), }, /* OV7630 */ \
109 { USB_DEVICE(0x0c45, 0x602d), }, \ 120 { USB_DEVICE(0x0c45, 0x602d), }, \
121 { USB_DEVICE(0x0c45, 0x602e), }, /* OV7630 */ \
110 { USB_DEVICE(0x0c45, 0x6030), }, /* MI03x */ \ 122 { USB_DEVICE(0x0c45, 0x6030), }, /* MI03x */ \
111 { USB_DEVICE(0x0c45, 0x6080), }, \ 123 { SN9C102_USB_DEVICE(0x0c45, 0x6080, 0xff), }, \
112 { USB_DEVICE(0x0c45, 0x6082), }, /* MI0343 and MI0360 */ \ 124 { SN9C102_USB_DEVICE(0x0c45, 0x6082, 0xff), }, /* MI0343 & MI0360 */ \
113 { USB_DEVICE(0x0c45, 0x6083), }, /* HV7131[D|E1] */ \ 125 { SN9C102_USB_DEVICE(0x0c45, 0x6083, 0xff), }, /* HV7131[D|E1] */ \
114 { USB_DEVICE(0x0c45, 0x6088), }, \ 126 { SN9C102_USB_DEVICE(0x0c45, 0x6088, 0xff), }, \
115 { USB_DEVICE(0x0c45, 0x608a), }, \ 127 { SN9C102_USB_DEVICE(0x0c45, 0x608a, 0xff), }, \
116 { USB_DEVICE(0x0c45, 0x608b), }, \ 128 { SN9C102_USB_DEVICE(0x0c45, 0x608b, 0xff), }, \
117 { USB_DEVICE(0x0c45, 0x608c), }, /* HV7131x */ \ 129 { SN9C102_USB_DEVICE(0x0c45, 0x608c, 0xff), }, /* HV7131x */ \
118 { USB_DEVICE(0x0c45, 0x608e), }, /* CIS-VF10 */ \ 130 { SN9C102_USB_DEVICE(0x0c45, 0x608e, 0xff), }, /* CIS-VF10 */ \
119 { USB_DEVICE(0x0c45, 0x608f), }, /* OV7630 */ \ 131 { SN9C102_USB_DEVICE(0x0c45, 0x608f, 0xff), }, /* OV7630 */ \
120 { USB_DEVICE(0x0c45, 0x60a0), }, \ 132 { SN9C102_USB_DEVICE(0x0c45, 0x60a0, 0xff), }, \
121 { USB_DEVICE(0x0c45, 0x60a2), }, \ 133 { SN9C102_USB_DEVICE(0x0c45, 0x60a2, 0xff), }, \
122 { USB_DEVICE(0x0c45, 0x60a3), }, \ 134 { SN9C102_USB_DEVICE(0x0c45, 0x60a3, 0xff), }, \
123 { USB_DEVICE(0x0c45, 0x60a8), }, /* PAS106B */ \ 135 { SN9C102_USB_DEVICE(0x0c45, 0x60a8, 0xff), }, /* PAS106B */ \
124 { USB_DEVICE(0x0c45, 0x60aa), }, /* TAS5130D1B */ \ 136 { SN9C102_USB_DEVICE(0x0c45, 0x60aa, 0xff), }, /* TAS5130D1B */ \
125 { USB_DEVICE(0x0c45, 0x60ab), }, /* TAS5110C1B */ \ 137 { SN9C102_USB_DEVICE(0x0c45, 0x60ab, 0xff), }, /* TAS5110C1B */ \
126 { USB_DEVICE(0x0c45, 0x60ac), }, \ 138 { SN9C102_USB_DEVICE(0x0c45, 0x60ac, 0xff), }, \
127 { USB_DEVICE(0x0c45, 0x60ae), }, \ 139 { SN9C102_USB_DEVICE(0x0c45, 0x60ae, 0xff), }, \
128 { USB_DEVICE(0x0c45, 0x60af), }, /* PAS202BCB */ \ 140 { SN9C102_USB_DEVICE(0x0c45, 0x60af, 0xff), }, /* PAS202BCB */ \
129 { USB_DEVICE(0x0c45, 0x60b0), }, \ 141 { SN9C102_USB_DEVICE(0x0c45, 0x60b0, 0xff), }, /* OV7630 (?) */ \
130 { USB_DEVICE(0x0c45, 0x60b2), }, \ 142 { SN9C102_USB_DEVICE(0x0c45, 0x60b2, 0xff), }, \
131 { USB_DEVICE(0x0c45, 0x60b3), }, \ 143 { SN9C102_USB_DEVICE(0x0c45, 0x60b3, 0xff), }, \
132 { USB_DEVICE(0x0c45, 0x60b8), }, \ 144 { SN9C102_USB_DEVICE(0x0c45, 0x60b8, 0xff), }, \
133 { USB_DEVICE(0x0c45, 0x60ba), }, \ 145 { SN9C102_USB_DEVICE(0x0c45, 0x60ba, 0xff), }, \
134 { USB_DEVICE(0x0c45, 0x60bb), }, \ 146 { SN9C102_USB_DEVICE(0x0c45, 0x60bb, 0xff), }, \
135 { USB_DEVICE(0x0c45, 0x60bc), }, \ 147 { SN9C102_USB_DEVICE(0x0c45, 0x60bc, 0xff), }, \
136 { USB_DEVICE(0x0c45, 0x60be), }, \ 148 { SN9C102_USB_DEVICE(0x0c45, 0x60be, 0xff), }, \
137 { } \ 149 { } \
138}; 150};
139 151
@@ -177,16 +189,18 @@ extern int sn9c102_i2c_write(struct sn9c102_device*, u8 address, u8 value);
177extern int sn9c102_i2c_read(struct sn9c102_device*, u8 address); 189extern int sn9c102_i2c_read(struct sn9c102_device*, u8 address);
178 190
179/* I/O on registers in the bridge. Could be used by the sensor methods too */ 191/* I/O on registers in the bridge. Could be used by the sensor methods too */
192extern int sn9c102_write_regs(struct sn9c102_device*, u8* buff, u16 index);
180extern int sn9c102_write_reg(struct sn9c102_device*, u8 value, u16 index); 193extern int sn9c102_write_reg(struct sn9c102_device*, u8 value, u16 index);
181extern int sn9c102_pread_reg(struct sn9c102_device*, u16 index); 194extern int sn9c102_pread_reg(struct sn9c102_device*, u16 index);
182 195
183/* 196/*
184 NOTE: there are no exported debugging functions. To uniform the output you 197 NOTE: there are no exported debugging functions. To uniform the output you
185 must use the dev_info()/dev_warn()/dev_err() macros defined in device.h, 198 must use the dev_info()/dev_warn()/dev_err() macros defined in device.h,
186 already included here, the argument being the struct device 'dev' of the 199 already included here, the argument being the struct device '&usbdev->dev'
187 sensor structure. Do NOT use these macros before the sensor is attached or 200 of the sensor structure. Do NOT use these macros before the sensor is
188 the kernel will crash! However, you should not need to notify the user about 201 attached or the kernel will crash! However, you should not need to notify
189 common errors or other messages, since this is done by the master module. 202 the user about common errors or other messages, since this is done by the
203 master module.
190*/ 204*/
191 205
192/*****************************************************************************/ 206/*****************************************************************************/
@@ -345,13 +359,6 @@ struct sn9c102_sensor {
345 error code without rolling back. 359 error code without rolling back.
346 */ 360 */
347 361
348 const struct device* dev;
349 /*
350 This is the argument for dev_err(), dev_info() and dev_warn(). It
351 is used for debugging purposes. You must not access the struct
352 before the sensor is attached.
353 */
354
355 const struct usb_device* usbdev; 362 const struct usb_device* usbdev;
356 /* 363 /*
357 Points to the usb_device struct after the sensor is attached. 364 Points to the usb_device struct after the sensor is attached.
diff --git a/drivers/usb/media/sn9c102_tas5110c1b.c b/drivers/usb/media/sn9c102_tas5110c1b.c
index 8775999b5aff..32ddf236cafe 100644
--- a/drivers/usb/media/sn9c102_tas5110c1b.c
+++ b/drivers/usb/media/sn9c102_tas5110c1b.c
@@ -2,7 +2,7 @@
2 * Plug-in for TAS5110C1B image sensor connected to the SN9C10x PC Camera * 2 * Plug-in for TAS5110C1B image sensor connected to the SN9C10x PC Camera *
3 * Controllers * 3 * Controllers *
4 * * 4 * *
5 * Copyright (C) 2004-2005 by Luca Risolia <luca.risolia@studio.unibo.it> * 5 * Copyright (C) 2004-2006 by Luca Risolia <luca.risolia@studio.unibo.it> *
6 * * 6 * *
7 * This program is free software; you can redistribute it and/or modify * 7 * This program is free software; you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by * 8 * it under the terms of the GNU General Public License as published by *
diff --git a/drivers/usb/media/sn9c102_tas5130d1b.c b/drivers/usb/media/sn9c102_tas5130d1b.c
index 927eafdd8c73..a0728f0ae00c 100644
--- a/drivers/usb/media/sn9c102_tas5130d1b.c
+++ b/drivers/usb/media/sn9c102_tas5130d1b.c
@@ -2,7 +2,7 @@
2 * Plug-in for TAS5130D1B image sensor connected to the SN9C10x PC Camera * 2 * Plug-in for TAS5130D1B image sensor connected to the SN9C10x PC Camera *
3 * Controllers * 3 * Controllers *
4 * * 4 * *
5 * Copyright (C) 2004-2005 by Luca Risolia <luca.risolia@studio.unibo.it> * 5 * Copyright (C) 2004-2006 by Luca Risolia <luca.risolia@studio.unibo.it> *
6 * * 6 * *
7 * This program is free software; you can redistribute it and/or modify * 7 * This program is free software; you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by * 8 * it under the terms of the GNU General Public License as published by *
diff --git a/drivers/usb/media/w9968cf.c b/drivers/usb/media/w9968cf.c
index bff9434c8e55..9937fc64c8bf 100644
--- a/drivers/usb/media/w9968cf.c
+++ b/drivers/usb/media/w9968cf.c
@@ -62,7 +62,6 @@ MODULE_LICENSE(W9968CF_MODULE_LICENSE);
62MODULE_SUPPORTED_DEVICE("Video"); 62MODULE_SUPPORTED_DEVICE("Video");
63 63
64static int ovmod_load = W9968CF_OVMOD_LOAD; 64static int ovmod_load = W9968CF_OVMOD_LOAD;
65static int vppmod_load = W9968CF_VPPMOD_LOAD;
66static unsigned short simcams = W9968CF_SIMCAMS; 65static unsigned short simcams = W9968CF_SIMCAMS;
67static short video_nr[]={[0 ... W9968CF_MAX_DEVICES-1] = -1}; /*-1=first free*/ 66static short video_nr[]={[0 ... W9968CF_MAX_DEVICES-1] = -1}; /*-1=first free*/
68static unsigned int packet_size[] = {[0 ... W9968CF_MAX_DEVICES-1] = 67static unsigned int packet_size[] = {[0 ... W9968CF_MAX_DEVICES-1] =
@@ -107,7 +106,6 @@ static unsigned int param_nv[24]; /* number of values per parameter */
107 106
108#ifdef CONFIG_KMOD 107#ifdef CONFIG_KMOD
109module_param(ovmod_load, bool, 0644); 108module_param(ovmod_load, bool, 0644);
110module_param(vppmod_load, bool, 0444);
111#endif 109#endif
112module_param(simcams, ushort, 0644); 110module_param(simcams, ushort, 0644);
113module_param_array(video_nr, short, &param_nv[0], 0444); 111module_param_array(video_nr, short, &param_nv[0], 0444);
@@ -150,18 +148,6 @@ MODULE_PARM_DESC(ovmod_load,
150 "\ninto memory." 148 "\ninto memory."
151 "\nDefault value is "__MODULE_STRING(W9968CF_OVMOD_LOAD)"." 149 "\nDefault value is "__MODULE_STRING(W9968CF_OVMOD_LOAD)"."
152 "\n"); 150 "\n");
153MODULE_PARM_DESC(vppmod_load,
154 "\n<0|1> Automatic 'w9968cf-vpp' module loading."
155 "\n0 disabled, 1 enabled."
156 "\nIf enabled, every time an application attempts to open a"
157 "\ncamera, 'insmod' searches for the video post-processing"
158 "\nmodule in the system and loads it automatically (if"
159 "\npresent). The optional 'w9968cf-vpp' module adds extra"
160 "\n image manipulation functions to the 'w9968cf' module,like"
161 "\nsoftware up-scaling,colour conversions and video decoding"
162 "\nfor very high frame rates."
163 "\nDefault value is "__MODULE_STRING(W9968CF_VPPMOD_LOAD)"."
164 "\n");
165#endif 151#endif
166MODULE_PARM_DESC(simcams, 152MODULE_PARM_DESC(simcams,
167 "\n<n> Number of cameras allowed to stream simultaneously." 153 "\n<n> Number of cameras allowed to stream simultaneously."
@@ -492,10 +478,6 @@ static void w9968cf_push_frame(struct w9968cf_device*, u8 f_num);
492static void w9968cf_pop_frame(struct w9968cf_device*,struct w9968cf_frame_t**); 478static void w9968cf_pop_frame(struct w9968cf_device*,struct w9968cf_frame_t**);
493static void w9968cf_release_resources(struct w9968cf_device*); 479static void w9968cf_release_resources(struct w9968cf_device*);
494 480
495/* Intermodule communication */
496static int w9968cf_vppmod_detect(struct w9968cf_device*);
497static void w9968cf_vppmod_release(struct w9968cf_device*);
498
499 481
500 482
501/**************************************************************************** 483/****************************************************************************
@@ -2737,9 +2719,7 @@ static int w9968cf_open(struct inode* inode, struct file* filp)
2737 cam->streaming = 0; 2719 cam->streaming = 0;
2738 cam->misconfigured = 0; 2720 cam->misconfigured = 0;
2739 2721
2740 if (!w9968cf_vpp) 2722 w9968cf_adjust_configuration(cam);
2741 if ((err = w9968cf_vppmod_detect(cam)))
2742 goto out;
2743 2723
2744 if ((err = w9968cf_allocate_memory(cam))) 2724 if ((err = w9968cf_allocate_memory(cam)))
2745 goto deallocate_memory; 2725 goto deallocate_memory;
@@ -2766,7 +2746,6 @@ static int w9968cf_open(struct inode* inode, struct file* filp)
2766 2746
2767deallocate_memory: 2747deallocate_memory:
2768 w9968cf_deallocate_memory(cam); 2748 w9968cf_deallocate_memory(cam);
2769out:
2770 DBG(2, "Failed to open the video device") 2749 DBG(2, "Failed to open the video device")
2771 up(&cam->dev_sem); 2750 up(&cam->dev_sem);
2772 up_read(&w9968cf_disconnect); 2751 up_read(&w9968cf_disconnect);
@@ -2784,8 +2763,6 @@ static int w9968cf_release(struct inode* inode, struct file* filp)
2784 2763
2785 w9968cf_stop_transfer(cam); 2764 w9968cf_stop_transfer(cam);
2786 2765
2787 w9968cf_vppmod_release(cam);
2788
2789 if (cam->disconnected) { 2766 if (cam->disconnected) {
2790 w9968cf_release_resources(cam); 2767 w9968cf_release_resources(cam);
2791 up(&cam->dev_sem); 2768 up(&cam->dev_sem);
@@ -3681,106 +3658,6 @@ static struct usb_driver w9968cf_usb_driver = {
3681 * Module init, exit and intermodule communication * 3658 * Module init, exit and intermodule communication *
3682 ****************************************************************************/ 3659 ****************************************************************************/
3683 3660
3684static int w9968cf_vppmod_detect(struct w9968cf_device* cam)
3685{
3686 if (!w9968cf_vpp)
3687 if (vppmod_load)
3688 request_module("w9968cf-vpp");
3689
3690 down(&w9968cf_vppmod_lock);
3691
3692 if (!w9968cf_vpp) {
3693 DBG(4, "Video post-processing module not detected")
3694 w9968cf_adjust_configuration(cam);
3695 goto out;
3696 }
3697
3698 if (!try_module_get(w9968cf_vpp->owner)) {
3699 DBG(1, "Couldn't increment the reference count of "
3700 "the video post-processing module")
3701 up(&w9968cf_vppmod_lock);
3702 return -ENOSYS;
3703 }
3704
3705 w9968cf_vpp->busy++;
3706
3707 DBG(5, "Video post-processing module detected")
3708
3709out:
3710 up(&w9968cf_vppmod_lock);
3711 return 0;
3712}
3713
3714
3715static void w9968cf_vppmod_release(struct w9968cf_device* cam)
3716{
3717 down(&w9968cf_vppmod_lock);
3718
3719 if (w9968cf_vpp && w9968cf_vpp->busy) {
3720 module_put(w9968cf_vpp->owner);
3721 w9968cf_vpp->busy--;
3722 wake_up(&w9968cf_vppmod_wait);
3723 DBG(5, "Video post-processing module released")
3724 }
3725
3726 up(&w9968cf_vppmod_lock);
3727}
3728
3729
3730int w9968cf_vppmod_register(struct w9968cf_vpp_t* vpp)
3731{
3732 down(&w9968cf_vppmod_lock);
3733
3734 if (w9968cf_vpp) {
3735 KDBG(1, "Video post-processing module already registered")
3736 up(&w9968cf_vppmod_lock);
3737 return -EINVAL;
3738 }
3739
3740 w9968cf_vpp = vpp;
3741 w9968cf_vpp->busy = 0;
3742
3743 KDBG(2, "Video post-processing module registered")
3744 up(&w9968cf_vppmod_lock);
3745 return 0;
3746}
3747
3748
3749int w9968cf_vppmod_deregister(struct w9968cf_vpp_t* vpp)
3750{
3751 down(&w9968cf_vppmod_lock);
3752
3753 if (!w9968cf_vpp) {
3754 up(&w9968cf_vppmod_lock);
3755 return -EINVAL;
3756 }
3757
3758 if (w9968cf_vpp != vpp) {
3759 KDBG(1, "Only the owner can unregister the video "
3760 "post-processing module")
3761 up(&w9968cf_vppmod_lock);
3762 return -EINVAL;
3763 }
3764
3765 if (w9968cf_vpp->busy) {
3766 KDBG(2, "Video post-processing module busy. Wait for it to be "
3767 "released...")
3768 up(&w9968cf_vppmod_lock);
3769 wait_event(w9968cf_vppmod_wait, !w9968cf_vpp->busy);
3770 w9968cf_vpp = NULL;
3771 goto out;
3772 }
3773
3774 w9968cf_vpp = NULL;
3775
3776 up(&w9968cf_vppmod_lock);
3777
3778out:
3779 KDBG(2, "Video post-processing module unregistered")
3780 return 0;
3781}
3782
3783
3784static int __init w9968cf_module_init(void) 3661static int __init w9968cf_module_init(void)
3785{ 3662{
3786 int err; 3663 int err;
@@ -3810,6 +3687,3 @@ static void __exit w9968cf_module_exit(void)
3810module_init(w9968cf_module_init); 3687module_init(w9968cf_module_init);
3811module_exit(w9968cf_module_exit); 3688module_exit(w9968cf_module_exit);
3812 3689
3813
3814EXPORT_SYMBOL(w9968cf_vppmod_register);
3815EXPORT_SYMBOL(w9968cf_vppmod_deregister);
diff --git a/drivers/usb/media/w9968cf.h b/drivers/usb/media/w9968cf.h
index 8acbfe205bc7..47a6ff794171 100644
--- a/drivers/usb/media/w9968cf.h
+++ b/drivers/usb/media/w9968cf.h
@@ -195,7 +195,6 @@ enum w9968cf_vpp_flag {
195}; 195};
196 196
197static struct w9968cf_vpp_t* w9968cf_vpp; 197static struct w9968cf_vpp_t* w9968cf_vpp;
198static DECLARE_MUTEX(w9968cf_vppmod_lock);
199static DECLARE_WAIT_QUEUE_HEAD(w9968cf_vppmod_wait); 198static DECLARE_WAIT_QUEUE_HEAD(w9968cf_vppmod_wait);
200 199
201static LIST_HEAD(w9968cf_dev_list); /* head of V4L registered cameras list */ 200static LIST_HEAD(w9968cf_dev_list); /* head of V4L registered cameras list */
diff --git a/drivers/usb/media/w9968cf_vpp.h b/drivers/usb/media/w9968cf_vpp.h
index 3f5317dc4c29..f3b91b782671 100644
--- a/drivers/usb/media/w9968cf_vpp.h
+++ b/drivers/usb/media/w9968cf_vpp.h
@@ -37,7 +37,4 @@ struct w9968cf_vpp_t {
37 u8 busy; /* read-only flag: module is/is not in use */ 37 u8 busy; /* read-only flag: module is/is not in use */
38}; 38};
39 39
40extern int w9968cf_vppmod_register(struct w9968cf_vpp_t*);
41extern int w9968cf_vppmod_deregister(struct w9968cf_vpp_t*);
42
43#endif /* _W9968CF_VPP_H_ */ 40#endif /* _W9968CF_VPP_H_ */