aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLuca Risolia <luca.risolia@studio.unibo.it>2006-02-06 11:29:35 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2006-03-20 17:49:52 -0500
commit60f780528f3ae603eb169a221628b93b6c6929f9 (patch)
tree535b75e9eafb445c7acd85ee350cdc0efbbcdecb
parentc4a1745aa09fc110afdefea0e5d025043e348bae (diff)
[PATCH] USB: Add ZC0301 Video4Linux2 driver
This patch adds a Video4Linux2 driver for ZC0301 Image Processor and Control Chip. Signed-off-by: Luca Risolia <luca.risolia@studio.unibo.it> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--Documentation/usb/zc0301.txt250
-rw-r--r--MAINTAINERS8
-rw-r--r--drivers/usb/Makefile1
-rw-r--r--drivers/usb/media/Kconfig15
-rw-r--r--drivers/usb/media/Makefile2
-rw-r--r--drivers/usb/media/zc0301.h185
-rw-r--r--drivers/usb/media/zc0301_core.c2028
-rw-r--r--drivers/usb/media/zc0301_pas202bcb.c353
-rw-r--r--drivers/usb/media/zc0301_sensor.h98
9 files changed, 2940 insertions, 0 deletions
diff --git a/Documentation/usb/zc0301.txt b/Documentation/usb/zc0301.txt
new file mode 100644
index 000000000000..10590bf625e4
--- /dev/null
+++ b/Documentation/usb/zc0301.txt
@@ -0,0 +1,250 @@
1
2 ZC0301 Image Processor and Control Chip
3 Driver for Linux
4 =======================================
5
6 - Documentation -
7
8
9Index
10=====
111. Copyright
122. Disclaimer
133. License
144. Overview and features
155. Module dependencies
166. Module loading
177. Module parameters
188. Supported devices
199. Notes for V4L2 application developers
2010. Contact information
2111. Credits
22
23
241. Copyright
25============
26Copyright (C) 2006 by Luca Risolia <luca.risolia@studio.unibo.it>
27
28
292. Disclaimer
30=============
31This software is not developed or sponsored by Z-Star Microelectronics Corp.
32Trademarks are property of their respective owner.
33
34
353. License
36==========
37This program is free software; you can redistribute it and/or modify
38it under the terms of the GNU General Public License as published by
39the Free Software Foundation; either version 2 of the License, or
40(at your option) any later version.
41
42This program is distributed in the hope that it will be useful,
43but WITHOUT ANY WARRANTY; without even the implied warranty of
44MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
45GNU General Public License for more details.
46
47You should have received a copy of the GNU General Public License
48along with this program; if not, write to the Free Software
49Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
50
51
524. Overview and features
53========================
54This driver supports the video interface of the devices mounting the ZC0301
55Image Processor and Control Chip.
56
57The driver relies on the Video4Linux2 and USB core modules. It has been
58designed to run properly on SMP systems as well.
59
60The latest version of the ZC0301 driver can be found at the following URL:
61http://www.linux-projects.org/
62
63Some of the features of the driver are:
64
65- full compliance with the Video4Linux2 API (see also "Notes for V4L2
66 application developers" paragraph);
67- available mmap or read/poll methods for video streaming through isochronous
68 data transfers;
69- automatic detection of image sensor;
70- video formats is standard JPEG in various compression qualities
71 (see also "Notes for V4L2 application developers" paragraph);
72- full support for the capabilities of every possible image sensors that can
73 be connected to the ZC0301 bridges, including, for istance, red, green,
74 blue and global gain adjustments and exposure control (see "Supported
75 devices" paragraph for details);
76- use of default color settings for sunlight conditions;
77- dynamic driver control thanks to various module parameters (see "Module
78 parameters" paragraph);
79- up to 64 cameras can be handled at the same time; they can be connected and
80 disconnected from the host many times without turning off the computer, if
81 the system supports hotplugging;
82
83
845. Module dependencies
85======================
86For it to work properly, the driver needs kernel support for Video4Linux and
87USB.
88
89The following options of the kernel configuration file must be enabled and
90corresponding modules must be compiled:
91
92 # Multimedia devices
93 #
94 CONFIG_VIDEO_DEV=m
95
96 # USB support
97 #
98 CONFIG_USB=m
99
100In addition, depending on the hardware being used, the modules below are
101necessary:
102
103 # USB Host Controller Drivers
104 #
105 CONFIG_USB_EHCI_HCD=m
106 CONFIG_USB_UHCI_HCD=m
107 CONFIG_USB_OHCI_HCD=m
108
109The ZC0301 controller also provides a built-in microphone interface. It is
110supported by the USB Audio driver thanks to the ALSA API:
111
112 # Sound
113 #
114 CONFIG_SOUND=y
115
116 # Advanced Linux Sound Architecture
117 #
118 CONFIG_SND=m
119
120 # USB devices
121 #
122 CONFIG_SND_USB_AUDIO=m
123
124And finally:
125
126 # USB Multimedia devices
127 #
128 CONFIG_USB_ZC0301=m
129
130
1316. Module loading
132=================
133To use the driver, it is necessary to load the "zc0301" module into memory
134after every other module required: "videodev", "usbcore" and, depending on
135the USB host controller you have, "ehci-hcd", "uhci-hcd" or "ohci-hcd".
136
137Loading can be done as shown below:
138
139 [root@localhost home]# modprobe zc0301
140
141At this point the devices should be recognized. You can invoke "dmesg" to
142analyze kernel messages and verify that the loading process has gone well:
143
144 [user@localhost home]$ dmesg
145
146
1477. Module parameters
148====================
149Module parameters are listed below:
150-------------------------------------------------------------------------------
151Name: video_nr
152Type: short array (min = 0, max = 64)
153Syntax: <-1|n[,...]>
154Description: Specify V4L2 minor mode number:
155 -1 = use next available
156 n = use minor number n
157 You can specify up to 64 cameras this way.
158 For example:
159 video_nr=-1,2,-1 would assign minor number 2 to the second
160 registered camera and use auto for the first one and for every
161 other camera.
162Default: -1
163-------------------------------------------------------------------------------
164Name: force_munmap
165Type: bool array (min = 0, max = 64)
166Syntax: <0|1[,...]>
167Description: Force the application to unmap previously mapped buffer memory
168 before calling any VIDIOC_S_CROP or VIDIOC_S_FMT ioctl's. Not
169 all the applications support this feature. This parameter is
170 specific for each detected camera.
171 0 = do not force memory unmapping
172 1 = force memory unmapping (save memory)
173Default: 0
174-------------------------------------------------------------------------------
175Name: debug
176Type: ushort
177Syntax: <n>
178Description: Debugging information level, from 0 to 3:
179 0 = none (use carefully)
180 1 = critical errors
181 2 = significant informations
182 3 = more verbose messages
183 Level 3 is useful for testing only, when only one device
184 is used at the same time. It also shows some more informations
185 about the hardware being detected. This module parameter can be
186 changed at runtime thanks to the /sys filesystem interface.
187Default: 2
188-------------------------------------------------------------------------------
189
190
1918. Supported devices
192====================
193None of the names of the companies as well as their products will be mentioned
194here. They have never collaborated with the author, so no advertising.
195
196From the point of view of a driver, what unambiguously identify a device are
197its vendor and product USB identifiers. Below is a list of known identifiers of
198devices mounting the ZC0301 Image Processor and Control Chips:
199
200Vendor ID Product ID
201--------- ----------
2020x046d 0x08ae
203
204The following image sensors are supported:
205
206Model Manufacturer
207----- ------------
208PAS202BCB PixArt Imaging, Inc.
209
210All the available control settings of each image sensor are supported through
211the V4L2 interface.
212
213
2149. Notes for V4L2 application developers
215========================================
216This driver follows the V4L2 API specifications. In particular, it enforces two
217rules:
218
219- exactly one I/O method, either "mmap" or "read", is associated with each
220file descriptor. Once it is selected, the application must close and reopen the
221device to switch to the other I/O method;
222
223- although it is not mandatory, previously mapped buffer memory should always
224be unmapped before calling any "VIDIOC_S_CROP" or "VIDIOC_S_FMT" ioctl's.
225The same number of buffers as before will be allocated again to match the size
226of the new video frames, so you have to map the buffers again before any I/O
227attempts on them.
228
229This driver supports the standard JPEG video format. The current compression
230quality may vary from 0 to 3 and can be selected or queried thanks to the
231VIDIOC_S_JPEGCOMP and VIDIOC_G_JPEGCOMP V4L2 ioctl's.
232
233
23410. Contact information
235=======================
236The author may be contacted by e-mail at <luca.risolia@studio.unibo.it>.
237
238GPG/PGP encrypted e-mail's are accepted. The GPG key ID of the author is
239'FCE635A4'; the public 1024-bit key should be available at any keyserver;
240the fingerprint is: '88E8 F32F 7244 68BA 3958 5D40 99DA 5D2A FCE6 35A4'.
241
242
24311. Credits
244===========
245- Informations about the chip internals to enable the I2C protocol have been
246 taken from the documentation of the ZC030x Video4Linux1 driver written by
247 Andrew Birkett <andy@nobugs.org>;
248- Initialization values of the ZC0301 connected to the PAS202BCB image sensor
249 have been taken from the SPCA5XX driver maintained by
250 Michel Xhaard <mxhaard@magic.fr>
diff --git a/MAINTAINERS b/MAINTAINERS
index 8db5c339845d..ad0d77cbfbc3 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2902,6 +2902,14 @@ L: video4linux-list@redhat.com
2902W: http://www.linux-projects.org 2902W: http://www.linux-projects.org
2903S: Maintained 2903S: Maintained
2904 2904
2905USB ZC0301 DRIVER
2906P: Luca Risolia
2907M: luca.risolia@studio.unibo.it
2908L: linux-usb-devel@lists.sourceforge.net
2909L: video4linux-list@redhat.com
2910W: http://www.linux-projects.org
2911S: Maintained
2912
2905USB ZD1201 DRIVER 2913USB ZD1201 DRIVER
2906P: Jeroen Vreeken 2914P: Jeroen Vreeken
2907M: pe1rxq@amsat.org 2915M: pe1rxq@amsat.org
diff --git a/drivers/usb/Makefile b/drivers/usb/Makefile
index 36e476dd9123..bade87b62cf9 100644
--- a/drivers/usb/Makefile
+++ b/drivers/usb/Makefile
@@ -48,6 +48,7 @@ obj-$(CONFIG_USB_SN9C102) += media/
48obj-$(CONFIG_USB_STV680) += media/ 48obj-$(CONFIG_USB_STV680) += media/
49obj-$(CONFIG_USB_VICAM) += media/ 49obj-$(CONFIG_USB_VICAM) += media/
50obj-$(CONFIG_USB_W9968CF) += media/ 50obj-$(CONFIG_USB_W9968CF) += media/
51obj-$(CONFIG_USB_ZC0301) += media/
51 52
52obj-$(CONFIG_USB_CATC) += net/ 53obj-$(CONFIG_USB_CATC) += net/
53obj-$(CONFIG_USB_KAWETH) += net/ 54obj-$(CONFIG_USB_KAWETH) += net/
diff --git a/drivers/usb/media/Kconfig b/drivers/usb/media/Kconfig
index 0d3d2cc5d7be..189d40f96be5 100644
--- a/drivers/usb/media/Kconfig
+++ b/drivers/usb/media/Kconfig
@@ -191,6 +191,21 @@ config USB_W9968CF
191 To compile this driver as a module, choose M here: the 191 To compile this driver as a module, choose M here: the
192 module will be called w9968cf. 192 module will be called w9968cf.
193 193
194config USB_ZC0301
195 tristate "USB ZC0301 Image Processor and Control Chip support"
196 depends on USB && VIDEO_DEV
197 ---help---
198 Say Y here if you want support for cameras based on the ZC0301
199 Image Processor and Control Chip.
200
201 See <file:Documentation/usb/zc0301.txt> for more informations.
202
203 This driver uses the Video For Linux API. You must say Y or M to
204 "Video For Linux" to use this driver.
205
206 To compile this driver as a module, choose M here: the
207 module will be called zc0301.
208
194config USB_PWC 209config USB_PWC
195 tristate "USB Philips Cameras" 210 tristate "USB Philips Cameras"
196 depends on USB && VIDEO_DEV 211 depends on USB && VIDEO_DEV
diff --git a/drivers/usb/media/Makefile b/drivers/usb/media/Makefile
index 3957aa1be0f2..333bf09ca2d6 100644
--- a/drivers/usb/media/Makefile
+++ b/drivers/usb/media/Makefile
@@ -4,6 +4,7 @@
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 6et61x251-objs := et61x251_core.o et61x251_tas5130d1b.o
7zc0301-objs := zc0301_core.o zc0301_pas202bcb.o
7 8
8obj-$(CONFIG_USB_DABUSB) += dabusb.o 9obj-$(CONFIG_USB_DABUSB) += dabusb.o
9obj-$(CONFIG_USB_DSBR) += dsbr100.o 10obj-$(CONFIG_USB_DSBR) += dsbr100.o
@@ -16,4 +17,5 @@ obj-$(CONFIG_USB_SN9C102) += sn9c102.o
16obj-$(CONFIG_USB_STV680) += stv680.o 17obj-$(CONFIG_USB_STV680) += stv680.o
17obj-$(CONFIG_USB_VICAM) += vicam.o usbvideo.o 18obj-$(CONFIG_USB_VICAM) += vicam.o usbvideo.o
18obj-$(CONFIG_USB_W9968CF) += w9968cf.o 19obj-$(CONFIG_USB_W9968CF) += w9968cf.o
20obj-$(CONFIG_USB_ZC0301) += zc0301.o
19obj-$(CONFIG_USB_PWC) += pwc/ 21obj-$(CONFIG_USB_PWC) += pwc/
diff --git a/drivers/usb/media/zc0301.h b/drivers/usb/media/zc0301.h
new file mode 100644
index 000000000000..6fa5075f1e3d
--- /dev/null
+++ b/drivers/usb/media/zc0301.h
@@ -0,0 +1,185 @@
1/***************************************************************************
2 * V4L2 driver for ZC0301 Image Processor and Control Chip *
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 _ZC0301_H_
22#define _ZC0301_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/mutex.h>
36#include <linux/rwsem.h>
37#include <asm/semaphore.h>
38
39#include "zc0301_sensor.h"
40
41/*****************************************************************************/
42
43#define ZC0301_DEBUG
44#define ZC0301_DEBUG_LEVEL 2
45#define ZC0301_MAX_DEVICES 64
46#define ZC0301_FORCE_MUNMAP 0
47#define ZC0301_MAX_FRAMES 32
48#define ZC0301_COMPRESSION_QUALITY 2
49#define ZC0301_URBS 2
50#define ZC0301_ISO_PACKETS 7
51#define ZC0301_ALTERNATE_SETTING 7
52#define ZC0301_URB_TIMEOUT msecs_to_jiffies(2 * ZC0301_ISO_PACKETS)
53#define ZC0301_CTRL_TIMEOUT 100
54#define ZC0301_FRAME_TIMEOUT 2 * 1000 * msecs_to_jiffies(1)
55
56/*****************************************************************************/
57
58ZC0301_ID_TABLE
59ZC0301_SENSOR_TABLE
60
61enum zc0301_frame_state {
62 F_UNUSED,
63 F_QUEUED,
64 F_GRABBING,
65 F_DONE,
66 F_ERROR,
67};
68
69struct zc0301_frame_t {
70 void* bufmem;
71 struct v4l2_buffer buf;
72 enum zc0301_frame_state state;
73 struct list_head frame;
74 unsigned long vma_use_count;
75};
76
77enum zc0301_dev_state {
78 DEV_INITIALIZED = 0x01,
79 DEV_DISCONNECTED = 0x02,
80 DEV_MISCONFIGURED = 0x04,
81};
82
83enum zc0301_io_method {
84 IO_NONE,
85 IO_READ,
86 IO_MMAP,
87};
88
89enum zc0301_stream_state {
90 STREAM_OFF,
91 STREAM_INTERRUPT,
92 STREAM_ON,
93};
94
95struct zc0301_module_param {
96 u8 force_munmap;
97};
98
99static DECLARE_RWSEM(zc0301_disconnect);
100
101struct zc0301_device {
102 struct video_device* v4ldev;
103
104 struct zc0301_sensor* sensor;
105
106 struct usb_device* usbdev;
107 struct urb* urb[ZC0301_URBS];
108 void* transfer_buffer[ZC0301_URBS];
109 u8* control_buffer;
110
111 struct zc0301_frame_t *frame_current, frame[ZC0301_MAX_FRAMES];
112 struct list_head inqueue, outqueue;
113 u32 frame_count, nbuffers, nreadbuffers;
114
115 enum zc0301_io_method io;
116 enum zc0301_stream_state stream;
117
118 struct v4l2_jpegcompression compression;
119
120 struct zc0301_module_param module_param;
121
122 enum zc0301_dev_state state;
123 u8 users;
124
125 struct mutex dev_mutex, fileop_mutex;
126 spinlock_t queue_lock;
127 wait_queue_head_t open, wait_frame, wait_stream;
128};
129
130/*****************************************************************************/
131
132void
133zc0301_attach_sensor(struct zc0301_device* cam, struct zc0301_sensor* sensor)
134{
135 cam->sensor = sensor;
136 cam->sensor->usbdev = cam->usbdev;
137}
138
139/*****************************************************************************/
140
141#undef DBG
142#undef KDBG
143#ifdef ZC0301_DEBUG
144# define DBG(level, fmt, args...) \
145do { \
146 if (debug >= (level)) { \
147 if ((level) == 1) \
148 dev_err(&cam->usbdev->dev, fmt "\n", ## args); \
149 else if ((level) == 2) \
150 dev_info(&cam->usbdev->dev, fmt "\n", ## args); \
151 else if ((level) >= 3) \
152 dev_info(&cam->usbdev->dev, "[%s:%d] " fmt "\n", \
153 __FUNCTION__, __LINE__ , ## args); \
154 } \
155} while (0)
156# define KDBG(level, fmt, args...) \
157do { \
158 if (debug >= (level)) { \
159 if ((level) == 1 || (level) == 2) \
160 pr_info("zc0301: " fmt "\n", ## args); \
161 else if ((level) == 3) \
162 pr_debug("zc0301: [%s:%d] " fmt "\n", __FUNCTION__, \
163 __LINE__ , ## args); \
164 } \
165} while (0)
166# define V4LDBG(level, name, cmd) \
167do { \
168 if (debug >= (level)) \
169 v4l_print_ioctl(name, cmd); \
170} while (0)
171#else
172# define DBG(level, fmt, args...) do {;} while(0)
173# define KDBG(level, fmt, args...) do {;} while(0)
174# define V4LDBG(level, name, cmd) do {;} while(0)
175#endif
176
177#undef PDBG
178#define PDBG(fmt, args...) \
179dev_info(&cam->usbdev->dev, "[%s:%d] " fmt "\n", \
180 __FUNCTION__, __LINE__ , ## args)
181
182#undef PDBGG
183#define PDBGG(fmt, args...) do {;} while(0) /* placeholder */
184
185#endif /* _ZC0301_H_ */
diff --git a/drivers/usb/media/zc0301_core.c b/drivers/usb/media/zc0301_core.c
new file mode 100644
index 000000000000..238f60f7f472
--- /dev/null
+++ b/drivers/usb/media/zc0301_core.c
@@ -0,0 +1,2028 @@
1/***************************************************************************
2 * Video4Linux2 driver for ZC0301 Image Processor and Control Chip *
3 * *
4 * Copyright (C) 2006 by Luca Risolia <luca.risolia@studio.unibo.it> *
5 * *
6 * Informations about the chip internals to enable the I2C protocol have *
7 * been taken from the documentation of the ZC030x Video4Linux1 driver *
8 * written by Andrew Birkett <andy@nobugs.org> *
9 * *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the Free Software *
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
23 ***************************************************************************/
24
25#include <linux/module.h>
26#include <linux/init.h>
27#include <linux/kernel.h>
28#include <linux/param.h>
29#include <linux/moduleparam.h>
30#include <linux/errno.h>
31#include <linux/slab.h>
32#include <linux/string.h>
33#include <linux/device.h>
34#include <linux/fs.h>
35#include <linux/delay.h>
36#include <linux/stddef.h>
37#include <linux/compiler.h>
38#include <linux/ioctl.h>
39#include <linux/poll.h>
40#include <linux/stat.h>
41#include <linux/mm.h>
42#include <linux/vmalloc.h>
43#include <linux/page-flags.h>
44#include <linux/byteorder/generic.h>
45#include <asm/page.h>
46#include <asm/uaccess.h>
47
48#include "zc0301.h"
49
50/*****************************************************************************/
51
52#define ZC0301_MODULE_NAME "V4L2 driver for ZC0301 " \
53 "Image Processor and Control Chip"
54#define ZC0301_MODULE_AUTHOR "(C) 2006 Luca Risolia"
55#define ZC0301_AUTHOR_EMAIL "<luca.risolia@studio.unibo.it>"
56#define ZC0301_MODULE_LICENSE "GPL"
57#define ZC0301_MODULE_VERSION "1:1.00"
58#define ZC0301_MODULE_VERSION_CODE KERNEL_VERSION(1, 0, 0)
59
60/*****************************************************************************/
61
62MODULE_DEVICE_TABLE(usb, zc0301_id_table);
63
64MODULE_AUTHOR(ZC0301_MODULE_AUTHOR " " ZC0301_AUTHOR_EMAIL);
65MODULE_DESCRIPTION(ZC0301_MODULE_NAME);
66MODULE_VERSION(ZC0301_MODULE_VERSION);
67MODULE_LICENSE(ZC0301_MODULE_LICENSE);
68
69static short video_nr[] = {[0 ... ZC0301_MAX_DEVICES-1] = -1};
70module_param_array(video_nr, short, NULL, 0444);
71MODULE_PARM_DESC(video_nr,
72 "\n<-1|n[,...]> Specify V4L2 minor mode number."
73 "\n -1 = use next available (default)"
74 "\n n = use minor number n (integer >= 0)"
75 "\nYou can specify up to "
76 __MODULE_STRING(ZC0301_MAX_DEVICES) " cameras this way."
77 "\nFor example:"
78 "\nvideo_nr=-1,2,-1 would assign minor number 2 to"
79 "\nthe second registered camera and use auto for the first"
80 "\none and for every other camera."
81 "\n");
82
83static short force_munmap[] = {[0 ... ZC0301_MAX_DEVICES-1] =
84 ZC0301_FORCE_MUNMAP};
85module_param_array(force_munmap, bool, NULL, 0444);
86MODULE_PARM_DESC(force_munmap,
87 "\n<0|1[,...]> Force the application to unmap previously"
88 "\nmapped buffer memory before calling any VIDIOC_S_CROP or"
89 "\nVIDIOC_S_FMT ioctl's. Not all the applications support"
90 "\nthis feature. This parameter is specific for each"
91 "\ndetected camera."
92 "\n 0 = do not force memory unmapping"
93 "\n 1 = force memory unmapping (save memory)"
94 "\nDefault value is "__MODULE_STRING(SN9C102_FORCE_MUNMAP)"."
95 "\n");
96
97#ifdef ZC0301_DEBUG
98static unsigned short debug = ZC0301_DEBUG_LEVEL;
99module_param(debug, ushort, 0644);
100MODULE_PARM_DESC(debug,
101 "\n<n> Debugging information level, from 0 to 3:"
102 "\n0 = none (use carefully)"
103 "\n1 = critical errors"
104 "\n2 = significant informations"
105 "\n3 = more verbose messages"
106 "\nLevel 3 is useful for testing only, when only "
107 "one device is used."
108 "\nDefault value is "__MODULE_STRING(ZC0301_DEBUG_LEVEL)"."
109 "\n");
110#endif
111
112/*****************************************************************************/
113
114static u32
115zc0301_request_buffers(struct zc0301_device* cam, u32 count,
116 enum zc0301_io_method io)
117{
118 struct v4l2_pix_format* p = &(cam->sensor->pix_format);
119 struct v4l2_rect* r = &(cam->sensor->cropcap.bounds);
120 const size_t imagesize = cam->module_param.force_munmap ||
121 io == IO_READ ?
122 (p->width * p->height * p->priv) / 8 :
123 (r->width * r->height * p->priv) / 8;
124 void* buff = NULL;
125 u32 i;
126
127 if (count > ZC0301_MAX_FRAMES)
128 count = ZC0301_MAX_FRAMES;
129
130 cam->nbuffers = count;
131 while (cam->nbuffers > 0) {
132 if ((buff = vmalloc_32(cam->nbuffers * PAGE_ALIGN(imagesize))))
133 break;
134 cam->nbuffers--;
135 }
136
137 for (i = 0; i < cam->nbuffers; i++) {
138 cam->frame[i].bufmem = buff + i*PAGE_ALIGN(imagesize);
139 cam->frame[i].buf.index = i;
140 cam->frame[i].buf.m.offset = i*PAGE_ALIGN(imagesize);
141 cam->frame[i].buf.length = imagesize;
142 cam->frame[i].buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
143 cam->frame[i].buf.sequence = 0;
144 cam->frame[i].buf.field = V4L2_FIELD_NONE;
145 cam->frame[i].buf.memory = V4L2_MEMORY_MMAP;
146 cam->frame[i].buf.flags = 0;
147 }
148
149 return cam->nbuffers;
150}
151
152
153static void zc0301_release_buffers(struct zc0301_device* cam)
154{
155 if (cam->nbuffers) {
156 vfree(cam->frame[0].bufmem);
157 cam->nbuffers = 0;
158 }
159 cam->frame_current = NULL;
160}
161
162
163static void zc0301_empty_framequeues(struct zc0301_device* cam)
164{
165 u32 i;
166
167 INIT_LIST_HEAD(&cam->inqueue);
168 INIT_LIST_HEAD(&cam->outqueue);
169
170 for (i = 0; i < ZC0301_MAX_FRAMES; i++) {
171 cam->frame[i].state = F_UNUSED;
172 cam->frame[i].buf.bytesused = 0;
173 }
174}
175
176
177static void zc0301_requeue_outqueue(struct zc0301_device* cam)
178{
179 struct zc0301_frame_t *i;
180
181 list_for_each_entry(i, &cam->outqueue, frame) {
182 i->state = F_QUEUED;
183 list_add(&i->frame, &cam->inqueue);
184 }
185
186 INIT_LIST_HEAD(&cam->outqueue);
187}
188
189
190static void zc0301_queue_unusedframes(struct zc0301_device* cam)
191{
192 unsigned long lock_flags;
193 u32 i;
194
195 for (i = 0; i < cam->nbuffers; i++)
196 if (cam->frame[i].state == F_UNUSED) {
197 cam->frame[i].state = F_QUEUED;
198 spin_lock_irqsave(&cam->queue_lock, lock_flags);
199 list_add_tail(&cam->frame[i].frame, &cam->inqueue);
200 spin_unlock_irqrestore(&cam->queue_lock, lock_flags);
201 }
202}
203
204/*****************************************************************************/
205
206int zc0301_write_reg(struct zc0301_device* cam, u16 index, u16 value)
207{
208 struct usb_device* udev = cam->usbdev;
209 int res;
210
211 res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0xa0, 0x40,
212 value, index, NULL, 0, ZC0301_CTRL_TIMEOUT);
213 if (res < 0) {
214 DBG(3, "Failed to write a register (index 0x%04X, "
215 "value 0x%02X, error %d)",index, value, res);
216 return -1;
217 }
218
219 return 0;
220}
221
222
223int zc0301_read_reg(struct zc0301_device* cam, u16 index)
224{
225 struct usb_device* udev = cam->usbdev;
226 u8* buff = cam->control_buffer;
227 int res;
228
229 res = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0xa1, 0xc0,
230 0x0001, index, buff, 1, ZC0301_CTRL_TIMEOUT);
231 if (res < 0)
232 DBG(3, "Failed to read a register (index 0x%04X, error %d)",
233 index, res);
234
235 PDBGG("Read: index 0x%04X, value: 0x%04X", index, (int)(*buff));
236
237 return (res >= 0) ? (int)(*buff) : -1;
238}
239
240
241int zc0301_i2c_read(struct zc0301_device* cam, u16 address, u8 length)
242{
243 int err = 0, res, r0, r1;
244
245 err += zc0301_write_reg(cam, 0x0092, address);
246 err += zc0301_write_reg(cam, 0x0090, 0x02);
247
248 msleep(1);
249
250 res = zc0301_read_reg(cam, 0x0091);
251 if (res < 0)
252 err += res;
253 r0 = zc0301_read_reg(cam, 0x0095);
254 if (r0 < 0)
255 err += r0;
256 r1 = zc0301_read_reg(cam, 0x0096);
257 if (r1 < 0)
258 err += r1;
259
260 res = (length <= 1) ? r0 : r0 | (r1 << 8);
261
262 if (err)
263 DBG(3, "I2C read failed at address 0x%04X, value: 0x%04X",
264 address, res);
265
266
267 PDBGG("I2C read: address 0x%04X, value: 0x%04X", address, res);
268
269 return err ? -1 : res;
270}
271
272
273int zc0301_i2c_write(struct zc0301_device* cam, u16 address, u16 value)
274{
275 int err = 0, res;
276
277 err += zc0301_write_reg(cam, 0x0092, address);
278 err += zc0301_write_reg(cam, 0x0093, value & 0xff);
279 err += zc0301_write_reg(cam, 0x0094, value >> 8);
280 err += zc0301_write_reg(cam, 0x0090, 0x01);
281
282 msleep(1);
283
284 res = zc0301_read_reg(cam, 0x0091);
285 if (res < 0)
286 err += res;
287
288 if (err)
289 DBG(3, "I2C write failed at address 0x%04X, value: 0x%04X",
290 address, value);
291
292 PDBGG("I2C write: address 0x%04X, value: 0x%04X", address, value);
293
294 return err ? -1 : 0;
295}
296
297/*****************************************************************************/
298
299static void zc0301_urb_complete(struct urb *urb, struct pt_regs* regs)
300{
301 struct zc0301_device* cam = urb->context;
302 struct zc0301_frame_t** f;
303 size_t imagesize;
304 u8 i;
305 int err = 0;
306
307 if (urb->status == -ENOENT)
308 return;
309
310 f = &cam->frame_current;
311
312 if (cam->stream == STREAM_INTERRUPT) {
313 cam->stream = STREAM_OFF;
314 if ((*f))
315 (*f)->state = F_QUEUED;
316 DBG(3, "Stream interrupted");
317 wake_up_interruptible(&cam->wait_stream);
318 }
319
320 if (cam->state & DEV_DISCONNECTED)
321 return;
322
323 if (cam->state & DEV_MISCONFIGURED) {
324 wake_up_interruptible(&cam->wait_frame);
325 return;
326 }
327
328 if (cam->stream == STREAM_OFF || list_empty(&cam->inqueue))
329 goto resubmit_urb;
330
331 if (!(*f))
332 (*f) = list_entry(cam->inqueue.next, struct zc0301_frame_t,
333 frame);
334
335 imagesize = (cam->sensor->pix_format.width *
336 cam->sensor->pix_format.height *
337 cam->sensor->pix_format.priv) / 8;
338
339 for (i = 0; i < urb->number_of_packets; i++) {
340 unsigned int len, status;
341 void *pos;
342 u16* soi;
343 u8 sof;
344
345 len = urb->iso_frame_desc[i].actual_length;
346 status = urb->iso_frame_desc[i].status;
347 pos = urb->iso_frame_desc[i].offset + urb->transfer_buffer;
348
349 if (status) {
350 DBG(3, "Error in isochronous frame");
351 (*f)->state = F_ERROR;
352 continue;
353 }
354
355 sof = (*(soi = pos) == 0xd8ff);
356
357 PDBGG("Isochrnous frame: length %u, #%u i,", len, i);
358
359 if ((*f)->state == F_QUEUED || (*f)->state == F_ERROR)
360start_of_frame:
361 if (sof) {
362 (*f)->state = F_GRABBING;
363 (*f)->buf.bytesused = 0;
364 do_gettimeofday(&(*f)->buf.timestamp);
365 DBG(3, "SOF detected: new video frame");
366 }
367
368 if ((*f)->state == F_GRABBING) {
369 if (sof && (*f)->buf.bytesused)
370 goto end_of_frame;
371
372 if ((*f)->buf.bytesused + len > imagesize) {
373 DBG(3, "Video frame size exceeded");
374 (*f)->state = F_ERROR;
375 continue;
376 }
377
378 memcpy((*f)->bufmem+(*f)->buf.bytesused, pos, len);
379 (*f)->buf.bytesused += len;
380
381 if ((*f)->buf.bytesused == imagesize) {
382 u32 b;
383end_of_frame:
384 b = (*f)->buf.bytesused;
385 (*f)->state = F_DONE;
386 (*f)->buf.sequence= ++cam->frame_count;
387 spin_lock(&cam->queue_lock);
388 list_move_tail(&(*f)->frame, &cam->outqueue);
389 if (!list_empty(&cam->inqueue))
390 (*f) = list_entry(cam->inqueue.next,
391 struct zc0301_frame_t,
392 frame);
393 else
394 (*f) = NULL;
395 spin_unlock(&cam->queue_lock);
396 DBG(3, "Video frame captured: : %lu bytes",
397 (unsigned long)(b));
398
399 if (!(*f))
400 goto resubmit_urb;
401
402 if (sof)
403 goto start_of_frame;
404 }
405 }
406 }
407
408resubmit_urb:
409 urb->dev = cam->usbdev;
410 err = usb_submit_urb(urb, GFP_ATOMIC);
411 if (err < 0 && err != -EPERM) {
412 cam->state |= DEV_MISCONFIGURED;
413 DBG(1, "usb_submit_urb() failed");
414 }
415
416 wake_up_interruptible(&cam->wait_frame);
417}
418
419
420static int zc0301_start_transfer(struct zc0301_device* cam)
421{
422 struct usb_device *udev = cam->usbdev;
423 struct urb* urb;
424 const unsigned int wMaxPacketSize[] = {0, 128, 192, 256, 384,
425 512, 768, 1023};
426 const unsigned int psz = wMaxPacketSize[ZC0301_ALTERNATE_SETTING];
427 s8 i, j;
428 int err = 0;
429
430 for (i = 0; i < ZC0301_URBS; i++) {
431 cam->transfer_buffer[i] = kzalloc(ZC0301_ISO_PACKETS * psz,
432 GFP_KERNEL);
433 if (!cam->transfer_buffer[i]) {
434 err = -ENOMEM;
435 DBG(1, "Not enough memory");
436 goto free_buffers;
437 }
438 }
439
440 for (i = 0; i < ZC0301_URBS; i++) {
441 urb = usb_alloc_urb(ZC0301_ISO_PACKETS, GFP_KERNEL);
442 cam->urb[i] = urb;
443 if (!urb) {
444 err = -ENOMEM;
445 DBG(1, "usb_alloc_urb() failed");
446 goto free_urbs;
447 }
448 urb->dev = udev;
449 urb->context = cam;
450 urb->pipe = usb_rcvisocpipe(udev, 1);
451 urb->transfer_flags = URB_ISO_ASAP;
452 urb->number_of_packets = ZC0301_ISO_PACKETS;
453 urb->complete = zc0301_urb_complete;
454 urb->transfer_buffer = cam->transfer_buffer[i];
455 urb->transfer_buffer_length = psz * ZC0301_ISO_PACKETS;
456 urb->interval = 1;
457 for (j = 0; j < ZC0301_ISO_PACKETS; j++) {
458 urb->iso_frame_desc[j].offset = psz * j;
459 urb->iso_frame_desc[j].length = psz;
460 }
461 }
462
463 err = usb_set_interface(udev, 0, ZC0301_ALTERNATE_SETTING);
464 if (err) {
465 DBG(1, "usb_set_interface() failed");
466 goto free_urbs;
467 }
468
469 cam->frame_current = NULL;
470
471 for (i = 0; i < ZC0301_URBS; i++) {
472 err = usb_submit_urb(cam->urb[i], GFP_KERNEL);
473 if (err) {
474 for (j = i-1; j >= 0; j--)
475 usb_kill_urb(cam->urb[j]);
476 DBG(1, "usb_submit_urb() failed, error %d", err);
477 goto free_urbs;
478 }
479 }
480
481 return 0;
482
483free_urbs:
484 for (i = 0; (i < ZC0301_URBS) && cam->urb[i]; i++)
485 usb_free_urb(cam->urb[i]);
486
487free_buffers:
488 for (i = 0; (i < ZC0301_URBS) && cam->transfer_buffer[i]; i++)
489 kfree(cam->transfer_buffer[i]);
490
491 return err;
492}
493
494
495static int zc0301_stop_transfer(struct zc0301_device* cam)
496{
497 struct usb_device *udev = cam->usbdev;
498 s8 i;
499 int err = 0;
500
501 if (cam->state & DEV_DISCONNECTED)
502 return 0;
503
504 for (i = ZC0301_URBS-1; i >= 0; i--) {
505 usb_kill_urb(cam->urb[i]);
506 usb_free_urb(cam->urb[i]);
507 kfree(cam->transfer_buffer[i]);
508 }
509
510 err = usb_set_interface(udev, 0, 0); /* 0 Mb/s */
511 if (err)
512 DBG(3, "usb_set_interface() failed");
513
514 return err;
515}
516
517
518static int zc0301_stream_interrupt(struct zc0301_device* cam)
519{
520 long timeout;
521
522 cam->stream = STREAM_INTERRUPT;
523 timeout = wait_event_timeout(cam->wait_stream,
524 (cam->stream == STREAM_OFF) ||
525 (cam->state & DEV_DISCONNECTED),
526 ZC0301_URB_TIMEOUT);
527 if (cam->state & DEV_DISCONNECTED)
528 return -ENODEV;
529 else if (!timeout) {
530 cam->state |= DEV_MISCONFIGURED;
531 DBG(1, "URB timeout reached. The camera is misconfigured. To "
532 "use it, close and open /dev/video%d again.",
533 cam->v4ldev->minor);
534 return -EIO;
535 }
536
537 return 0;
538}
539
540/*****************************************************************************/
541
542static int
543zc0301_set_compression(struct zc0301_device* cam,
544 struct v4l2_jpegcompression* compression)
545{
546 int r, err = 0;
547
548 if ((r = zc0301_read_reg(cam, 0x0008)) < 0)
549 err += r;
550 err += zc0301_write_reg(cam, 0x0008,
551 r | 0x11 | (compression->quality >> 1));
552
553 return err ? -EIO : 0;
554}
555
556
557static int zc0301_init(struct zc0301_device* cam)
558{
559 struct zc0301_sensor* s = cam->sensor;
560 struct v4l2_control ctrl;
561 struct v4l2_queryctrl *qctrl;
562 struct v4l2_rect* rect;
563 u8 i = 0;
564 int err = 0;
565
566 if (!(cam->state & DEV_INITIALIZED)) {
567 init_waitqueue_head(&cam->open);
568 qctrl = s->qctrl;
569 rect = &(s->cropcap.defrect);
570 cam->compression.quality = ZC0301_COMPRESSION_QUALITY;
571 } else { /* use current values */
572 qctrl = s->_qctrl;
573 rect = &(s->_rect);
574 }
575
576 if (s->init) {
577 err = s->init(cam);
578 if (err) {
579 DBG(3, "Sensor initialization failed");
580 return err;
581 }
582 }
583
584 if ((err = zc0301_set_compression(cam, &cam->compression))) {
585 DBG(3, "set_compression() failed");
586 return err;
587 }
588
589 if (s->set_crop)
590 if ((err = s->set_crop(cam, rect))) {
591 DBG(3, "set_crop() failed");
592 return err;
593 }
594
595 if (s->set_ctrl) {
596 for (i = 0; i < ARRAY_SIZE(s->qctrl); i++)
597 if (s->qctrl[i].id != 0 &&
598 !(s->qctrl[i].flags & V4L2_CTRL_FLAG_DISABLED)) {
599 ctrl.id = s->qctrl[i].id;
600 ctrl.value = qctrl[i].default_value;
601 err = s->set_ctrl(cam, &ctrl);
602 if (err) {
603 DBG(3, "Set %s control failed",
604 s->qctrl[i].name);
605 return err;
606 }
607 DBG(3, "Image sensor supports '%s' control",
608 s->qctrl[i].name);
609 }
610 }
611
612 if (!(cam->state & DEV_INITIALIZED)) {
613 mutex_init(&cam->fileop_mutex);
614 spin_lock_init(&cam->queue_lock);
615 init_waitqueue_head(&cam->wait_frame);
616 init_waitqueue_head(&cam->wait_stream);
617 cam->nreadbuffers = 2;
618 memcpy(s->_qctrl, s->qctrl, sizeof(s->qctrl));
619 memcpy(&(s->_rect), &(s->cropcap.defrect),
620 sizeof(struct v4l2_rect));
621 cam->state |= DEV_INITIALIZED;
622 }
623
624 DBG(2, "Initialization succeeded");
625 return 0;
626}
627
628
629static void zc0301_release_resources(struct zc0301_device* cam)
630{
631 DBG(2, "V4L2 device /dev/video%d deregistered", cam->v4ldev->minor);
632 video_set_drvdata(cam->v4ldev, NULL);
633 video_unregister_device(cam->v4ldev);
634 kfree(cam->control_buffer);
635}
636
637/*****************************************************************************/
638
639static int zc0301_open(struct inode* inode, struct file* filp)
640{
641 struct zc0301_device* cam;
642 int err = 0;
643
644 /*
645 This is the only safe way to prevent race conditions with
646 disconnect
647 */
648 if (!down_read_trylock(&zc0301_disconnect))
649 return -ERESTARTSYS;
650
651 cam = video_get_drvdata(video_devdata(filp));
652
653 if (mutex_lock_interruptible(&cam->dev_mutex)) {
654 up_read(&zc0301_disconnect);
655 return -ERESTARTSYS;
656 }
657
658 if (cam->users) {
659 DBG(2, "Device /dev/video%d is busy...", cam->v4ldev->minor);
660 if ((filp->f_flags & O_NONBLOCK) ||
661 (filp->f_flags & O_NDELAY)) {
662 err = -EWOULDBLOCK;
663 goto out;
664 }
665 mutex_unlock(&cam->dev_mutex);
666 err = wait_event_interruptible_exclusive(cam->open,
667 cam->state & DEV_DISCONNECTED
668 || !cam->users);
669 if (err) {
670 up_read(&zc0301_disconnect);
671 return err;
672 }
673 if (cam->state & DEV_DISCONNECTED) {
674 up_read(&zc0301_disconnect);
675 return -ENODEV;
676 }
677 mutex_lock(&cam->dev_mutex);
678 }
679
680
681 if (cam->state & DEV_MISCONFIGURED) {
682 err = zc0301_init(cam);
683 if (err) {
684 DBG(1, "Initialization failed again. "
685 "I will retry on next open().");
686 goto out;
687 }
688 cam->state &= ~DEV_MISCONFIGURED;
689 }
690
691 if ((err = zc0301_start_transfer(cam)))
692 goto out;
693
694 filp->private_data = cam;
695 cam->users++;
696 cam->io = IO_NONE;
697 cam->stream = STREAM_OFF;
698 cam->nbuffers = 0;
699 cam->frame_count = 0;
700 zc0301_empty_framequeues(cam);
701
702 DBG(3, "Video device /dev/video%d is open", cam->v4ldev->minor);
703
704out:
705 mutex_unlock(&cam->dev_mutex);
706 up_read(&zc0301_disconnect);
707 return err;
708}
709
710
711static int zc0301_release(struct inode* inode, struct file* filp)
712{
713 struct zc0301_device* cam = video_get_drvdata(video_devdata(filp));
714
715 mutex_lock(&cam->dev_mutex); /* prevent disconnect() to be called */
716
717 zc0301_stop_transfer(cam);
718
719 zc0301_release_buffers(cam);
720
721 if (cam->state & DEV_DISCONNECTED) {
722 zc0301_release_resources(cam);
723 mutex_unlock(&cam->dev_mutex);
724 kfree(cam);
725 return 0;
726 }
727
728 cam->users--;
729 wake_up_interruptible_nr(&cam->open, 1);
730
731 DBG(3, "Video device /dev/video%d closed", cam->v4ldev->minor);
732
733 mutex_unlock(&cam->dev_mutex);
734
735 return 0;
736}
737
738
739static ssize_t
740zc0301_read(struct file* filp, char __user * buf,
741 size_t count, loff_t* f_pos)
742{
743 struct zc0301_device* cam = video_get_drvdata(video_devdata(filp));
744 struct zc0301_frame_t* f, * i;
745 unsigned long lock_flags;
746 long timeout;
747 int err = 0;
748
749 if (mutex_lock_interruptible(&cam->fileop_mutex))
750 return -ERESTARTSYS;
751
752 if (cam->state & DEV_DISCONNECTED) {
753 DBG(1, "Device not present");
754 mutex_unlock(&cam->fileop_mutex);
755 return -ENODEV;
756 }
757
758 if (cam->state & DEV_MISCONFIGURED) {
759 DBG(1, "The camera is misconfigured. Close and open it "
760 "again.");
761 mutex_unlock(&cam->fileop_mutex);
762 return -EIO;
763 }
764
765 if (cam->io == IO_MMAP) {
766 DBG(3, "Close and open the device again to choose the read "
767 "method");
768 mutex_unlock(&cam->fileop_mutex);
769 return -EINVAL;
770 }
771
772 if (cam->io == IO_NONE) {
773 if (!zc0301_request_buffers(cam, cam->nreadbuffers, IO_READ)) {
774 DBG(1, "read() failed, not enough memory");
775 mutex_unlock(&cam->fileop_mutex);
776 return -ENOMEM;
777 }
778 cam->io = IO_READ;
779 cam->stream = STREAM_ON;
780 }
781
782 if (list_empty(&cam->inqueue)) {
783 if (!list_empty(&cam->outqueue))
784 zc0301_empty_framequeues(cam);
785 zc0301_queue_unusedframes(cam);
786 }
787
788 if (!count) {
789 mutex_unlock(&cam->fileop_mutex);
790 return 0;
791 }
792
793 if (list_empty(&cam->outqueue)) {
794 if (filp->f_flags & O_NONBLOCK) {
795 mutex_unlock(&cam->fileop_mutex);
796 return -EAGAIN;
797 }
798 timeout = wait_event_interruptible_timeout
799 ( cam->wait_frame,
800 (!list_empty(&cam->outqueue)) ||
801 (cam->state & DEV_DISCONNECTED) ||
802 (cam->state & DEV_MISCONFIGURED),
803 ZC0301_FRAME_TIMEOUT );
804 if (timeout < 0) {
805 mutex_unlock(&cam->fileop_mutex);
806 return timeout;
807 }
808 if (cam->state & DEV_DISCONNECTED) {
809 mutex_unlock(&cam->fileop_mutex);
810 return -ENODEV;
811 }
812 if (!timeout || (cam->state & DEV_MISCONFIGURED)) {
813 mutex_unlock(&cam->fileop_mutex);
814 return -EIO;
815 }
816 }
817
818 f = list_entry(cam->outqueue.prev, struct zc0301_frame_t, frame);
819
820 if (count > f->buf.bytesused)
821 count = f->buf.bytesused;
822
823 if (copy_to_user(buf, f->bufmem, count)) {
824 err = -EFAULT;
825 goto exit;
826 }
827 *f_pos += count;
828
829exit:
830 spin_lock_irqsave(&cam->queue_lock, lock_flags);
831 list_for_each_entry(i, &cam->outqueue, frame)
832 i->state = F_UNUSED;
833 INIT_LIST_HEAD(&cam->outqueue);
834 spin_unlock_irqrestore(&cam->queue_lock, lock_flags);
835
836 zc0301_queue_unusedframes(cam);
837
838 PDBGG("Frame #%lu, bytes read: %zu",
839 (unsigned long)f->buf.index, count);
840
841 mutex_unlock(&cam->fileop_mutex);
842
843 return err ? err : count;
844}
845
846
847static unsigned int zc0301_poll(struct file *filp, poll_table *wait)
848{
849 struct zc0301_device* cam = video_get_drvdata(video_devdata(filp));
850 struct zc0301_frame_t* f;
851 unsigned long lock_flags;
852 unsigned int mask = 0;
853
854 if (mutex_lock_interruptible(&cam->fileop_mutex))
855 return POLLERR;
856
857 if (cam->state & DEV_DISCONNECTED) {
858 DBG(1, "Device not present");
859 goto error;
860 }
861
862 if (cam->state & DEV_MISCONFIGURED) {
863 DBG(1, "The camera is misconfigured. Close and open it "
864 "again.");
865 goto error;
866 }
867
868 if (cam->io == IO_NONE) {
869 if (!zc0301_request_buffers(cam, cam->nreadbuffers, IO_READ)) {
870 DBG(1, "poll() failed, not enough memory");
871 goto error;
872 }
873 cam->io = IO_READ;
874 cam->stream = STREAM_ON;
875 }
876
877 if (cam->io == IO_READ) {
878 spin_lock_irqsave(&cam->queue_lock, lock_flags);
879 list_for_each_entry(f, &cam->outqueue, frame)
880 f->state = F_UNUSED;
881 INIT_LIST_HEAD(&cam->outqueue);
882 spin_unlock_irqrestore(&cam->queue_lock, lock_flags);
883 zc0301_queue_unusedframes(cam);
884 }
885
886 poll_wait(filp, &cam->wait_frame, wait);
887
888 if (!list_empty(&cam->outqueue))
889 mask |= POLLIN | POLLRDNORM;
890
891 mutex_unlock(&cam->fileop_mutex);
892
893 return mask;
894
895error:
896 mutex_unlock(&cam->fileop_mutex);
897 return POLLERR;
898}
899
900
901static void zc0301_vm_open(struct vm_area_struct* vma)
902{
903 struct zc0301_frame_t* f = vma->vm_private_data;
904 f->vma_use_count++;
905}
906
907
908static void zc0301_vm_close(struct vm_area_struct* vma)
909{
910 /* NOTE: buffers are not freed here */
911 struct zc0301_frame_t* f = vma->vm_private_data;
912 f->vma_use_count--;
913}
914
915
916static struct vm_operations_struct zc0301_vm_ops = {
917 .open = zc0301_vm_open,
918 .close = zc0301_vm_close,
919};
920
921
922static int zc0301_mmap(struct file* filp, struct vm_area_struct *vma)
923{
924 struct zc0301_device* cam = video_get_drvdata(video_devdata(filp));
925 unsigned long size = vma->vm_end - vma->vm_start,
926 start = vma->vm_start;
927 void *pos;
928 u32 i;
929
930 if (mutex_lock_interruptible(&cam->fileop_mutex))
931 return -ERESTARTSYS;
932
933 if (cam->state & DEV_DISCONNECTED) {
934 DBG(1, "Device not present");
935 mutex_unlock(&cam->fileop_mutex);
936 return -ENODEV;
937 }
938
939 if (cam->state & DEV_MISCONFIGURED) {
940 DBG(1, "The camera is misconfigured. Close and open it "
941 "again.");
942 mutex_unlock(&cam->fileop_mutex);
943 return -EIO;
944 }
945
946 if (cam->io != IO_MMAP || !(vma->vm_flags & VM_WRITE) ||
947 size != PAGE_ALIGN(cam->frame[0].buf.length)) {
948 mutex_unlock(&cam->fileop_mutex);
949 return -EINVAL;
950 }
951
952 for (i = 0; i < cam->nbuffers; i++) {
953 if ((cam->frame[i].buf.m.offset>>PAGE_SHIFT) == vma->vm_pgoff)
954 break;
955 }
956 if (i == cam->nbuffers) {
957 mutex_unlock(&cam->fileop_mutex);
958 return -EINVAL;
959 }
960
961 vma->vm_flags |= VM_IO;
962 vma->vm_flags |= VM_RESERVED;
963
964 pos = cam->frame[i].bufmem;
965 while (size > 0) { /* size is page-aligned */
966 if (vm_insert_page(vma, start, vmalloc_to_page(pos))) {
967 mutex_unlock(&cam->fileop_mutex);
968 return -EAGAIN;
969 }
970 start += PAGE_SIZE;
971 pos += PAGE_SIZE;
972 size -= PAGE_SIZE;
973 }
974
975 vma->vm_ops = &zc0301_vm_ops;
976 vma->vm_private_data = &cam->frame[i];
977
978 zc0301_vm_open(vma);
979
980 mutex_unlock(&cam->fileop_mutex);
981
982 return 0;
983}
984
985/*****************************************************************************/
986
987static int
988zc0301_vidioc_querycap(struct zc0301_device* cam, void __user * arg)
989{
990 struct v4l2_capability cap = {
991 .driver = "zc0301",
992 .version = ZC0301_MODULE_VERSION_CODE,
993 .capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE |
994 V4L2_CAP_STREAMING,
995 };
996
997 strlcpy(cap.card, cam->v4ldev->name, sizeof(cap.card));
998 if (usb_make_path(cam->usbdev, cap.bus_info, sizeof(cap.bus_info)) < 0)
999 strlcpy(cap.bus_info, cam->usbdev->dev.bus_id,
1000 sizeof(cap.bus_info));
1001
1002 if (copy_to_user(arg, &cap, sizeof(cap)))
1003 return -EFAULT;
1004
1005 return 0;
1006}
1007
1008
1009static int
1010zc0301_vidioc_enuminput(struct zc0301_device* cam, void __user * arg)
1011{
1012 struct v4l2_input i;
1013
1014 if (copy_from_user(&i, arg, sizeof(i)))
1015 return -EFAULT;
1016
1017 if (i.index)
1018 return -EINVAL;
1019
1020 memset(&i, 0, sizeof(i));
1021 strcpy(i.name, "Camera");
1022
1023 if (copy_to_user(arg, &i, sizeof(i)))
1024 return -EFAULT;
1025
1026 return 0;
1027}
1028
1029
1030static int
1031zc0301_vidioc_gs_input(struct zc0301_device* cam, void __user * arg)
1032{
1033 int index;
1034
1035 if (copy_from_user(&index, arg, sizeof(index)))
1036 return -EFAULT;
1037
1038 if (index != 0)
1039 return -EINVAL;
1040
1041 return 0;
1042}
1043
1044
1045static int
1046zc0301_vidioc_query_ctrl(struct zc0301_device* cam, void __user * arg)
1047{
1048 struct zc0301_sensor* s = cam->sensor;
1049 struct v4l2_queryctrl qc;
1050 u8 i;
1051
1052 if (copy_from_user(&qc, arg, sizeof(qc)))
1053 return -EFAULT;
1054
1055 for (i = 0; i < ARRAY_SIZE(s->qctrl); i++)
1056 if (qc.id && qc.id == s->qctrl[i].id) {
1057 memcpy(&qc, &(s->qctrl[i]), sizeof(qc));
1058 if (copy_to_user(arg, &qc, sizeof(qc)))
1059 return -EFAULT;
1060 return 0;
1061 }
1062
1063 return -EINVAL;
1064}
1065
1066
1067static int
1068zc0301_vidioc_g_ctrl(struct zc0301_device* cam, void __user * arg)
1069{
1070 struct zc0301_sensor* s = cam->sensor;
1071 struct v4l2_control ctrl;
1072 int err = 0;
1073 u8 i;
1074
1075 if (!s->get_ctrl && !s->set_ctrl)
1076 return -EINVAL;
1077
1078 if (copy_from_user(&ctrl, arg, sizeof(ctrl)))
1079 return -EFAULT;
1080
1081 if (!s->get_ctrl) {
1082 for (i = 0; i < ARRAY_SIZE(s->qctrl); i++)
1083 if (ctrl.id == s->qctrl[i].id) {
1084 ctrl.value = s->_qctrl[i].default_value;
1085 goto exit;
1086 }
1087 return -EINVAL;
1088 } else
1089 err = s->get_ctrl(cam, &ctrl);
1090
1091exit:
1092 if (copy_to_user(arg, &ctrl, sizeof(ctrl)))
1093 return -EFAULT;
1094
1095 return err;
1096}
1097
1098
1099static int
1100zc0301_vidioc_s_ctrl(struct zc0301_device* cam, void __user * arg)
1101{
1102 struct zc0301_sensor* s = cam->sensor;
1103 struct v4l2_control ctrl;
1104 u8 i;
1105 int err = 0;
1106
1107 if (!s->set_ctrl)
1108 return -EINVAL;
1109
1110 if (copy_from_user(&ctrl, arg, sizeof(ctrl)))
1111 return -EFAULT;
1112
1113 for (i = 0; i < ARRAY_SIZE(s->qctrl); i++)
1114 if (ctrl.id == s->qctrl[i].id) {
1115 if (ctrl.value < s->qctrl[i].minimum ||
1116 ctrl.value > s->qctrl[i].maximum)
1117 return -ERANGE;
1118 ctrl.value -= ctrl.value % s->qctrl[i].step;
1119 break;
1120 }
1121
1122 if ((err = s->set_ctrl(cam, &ctrl)))
1123 return err;
1124
1125 s->_qctrl[i].default_value = ctrl.value;
1126
1127 return 0;
1128}
1129
1130
1131static int
1132zc0301_vidioc_cropcap(struct zc0301_device* cam, void __user * arg)
1133{
1134 struct v4l2_cropcap* cc = &(cam->sensor->cropcap);
1135
1136 cc->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1137 cc->pixelaspect.numerator = 1;
1138 cc->pixelaspect.denominator = 1;
1139
1140 if (copy_to_user(arg, cc, sizeof(*cc)))
1141 return -EFAULT;
1142
1143 return 0;
1144}
1145
1146
1147static int
1148zc0301_vidioc_g_crop(struct zc0301_device* cam, void __user * arg)
1149{
1150 struct zc0301_sensor* s = cam->sensor;
1151 struct v4l2_crop crop = {
1152 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
1153 };
1154
1155 memcpy(&(crop.c), &(s->_rect), sizeof(struct v4l2_rect));
1156
1157 if (copy_to_user(arg, &crop, sizeof(crop)))
1158 return -EFAULT;
1159
1160 return 0;
1161}
1162
1163
1164static int
1165zc0301_vidioc_s_crop(struct zc0301_device* cam, void __user * arg)
1166{
1167 struct zc0301_sensor* s = cam->sensor;
1168 struct v4l2_crop crop;
1169 struct v4l2_rect* rect;
1170 struct v4l2_rect* bounds = &(s->cropcap.bounds);
1171 const enum zc0301_stream_state stream = cam->stream;
1172 const u32 nbuffers = cam->nbuffers;
1173 u32 i;
1174 int err = 0;
1175
1176 if (copy_from_user(&crop, arg, sizeof(crop)))
1177 return -EFAULT;
1178
1179 rect = &(crop.c);
1180
1181 if (crop.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1182 return -EINVAL;
1183
1184 if (cam->module_param.force_munmap)
1185 for (i = 0; i < cam->nbuffers; i++)
1186 if (cam->frame[i].vma_use_count) {
1187 DBG(3, "VIDIOC_S_CROP failed. "
1188 "Unmap the buffers first.");
1189 return -EINVAL;
1190 }
1191
1192 if (!s->set_crop) {
1193 memcpy(rect, &(s->_rect), sizeof(*rect));
1194 if (copy_to_user(arg, &crop, sizeof(crop)))
1195 return -EFAULT;
1196 return 0;
1197 }
1198
1199 rect->left &= ~7L;
1200 rect->top &= ~7L;
1201 if (rect->width < 8)
1202 rect->width = 8;
1203 if (rect->height < 8)
1204 rect->height = 8;
1205 if (rect->width > bounds->width)
1206 rect->width = bounds->width;
1207 if (rect->height > bounds->height)
1208 rect->height = bounds->height;
1209 if (rect->left < bounds->left)
1210 rect->left = bounds->left;
1211 if (rect->top < bounds->top)
1212 rect->top = bounds->top;
1213 if (rect->left + rect->width > bounds->left + bounds->width)
1214 rect->left = bounds->left+bounds->width - rect->width;
1215 if (rect->top + rect->height > bounds->top + bounds->height)
1216 rect->top = bounds->top+bounds->height - rect->height;
1217 rect->width &= ~7L;
1218 rect->height &= ~7L;
1219
1220 if (cam->stream == STREAM_ON)
1221 if ((err = zc0301_stream_interrupt(cam)))
1222 return err;
1223
1224 if (copy_to_user(arg, &crop, sizeof(crop))) {
1225 cam->stream = stream;
1226 return -EFAULT;
1227 }
1228
1229 if (cam->module_param.force_munmap || cam->io == IO_READ)
1230 zc0301_release_buffers(cam);
1231
1232 if (s->set_crop)
1233 err += s->set_crop(cam, rect);
1234
1235 if (err) { /* atomic, no rollback in ioctl() */
1236 cam->state |= DEV_MISCONFIGURED;
1237 DBG(1, "VIDIOC_S_CROP failed because of hardware problems. To "
1238 "use the camera, close and open /dev/video%d again.",
1239 cam->v4ldev->minor);
1240 return -EIO;
1241 }
1242
1243 s->pix_format.width = rect->width;
1244 s->pix_format.height = rect->height;
1245 memcpy(&(s->_rect), rect, sizeof(*rect));
1246
1247 if ((cam->module_param.force_munmap || cam->io == IO_READ) &&
1248 nbuffers != zc0301_request_buffers(cam, nbuffers, cam->io)) {
1249 cam->state |= DEV_MISCONFIGURED;
1250 DBG(1, "VIDIOC_S_CROP failed because of not enough memory. To "
1251 "use the camera, close and open /dev/video%d again.",
1252 cam->v4ldev->minor);
1253 return -ENOMEM;
1254 }
1255
1256 if (cam->io == IO_READ)
1257 zc0301_empty_framequeues(cam);
1258 else if (cam->module_param.force_munmap)
1259 zc0301_requeue_outqueue(cam);
1260
1261 cam->stream = stream;
1262
1263 return 0;
1264}
1265
1266
1267static int
1268zc0301_vidioc_enum_fmt(struct zc0301_device* cam, void __user * arg)
1269{
1270 struct v4l2_fmtdesc fmtd;
1271
1272 if (copy_from_user(&fmtd, arg, sizeof(fmtd)))
1273 return -EFAULT;
1274
1275 if (fmtd.index == 0) {
1276 strcpy(fmtd.description, "JPEG");
1277 fmtd.pixelformat = V4L2_PIX_FMT_JPEG;
1278 fmtd.flags = V4L2_FMT_FLAG_COMPRESSED;
1279 } else
1280 return -EINVAL;
1281
1282 fmtd.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1283 memset(&fmtd.reserved, 0, sizeof(fmtd.reserved));
1284
1285 if (copy_to_user(arg, &fmtd, sizeof(fmtd)))
1286 return -EFAULT;
1287
1288 return 0;
1289}
1290
1291
1292static int
1293zc0301_vidioc_g_fmt(struct zc0301_device* cam, void __user * arg)
1294{
1295 struct v4l2_format format;
1296 struct v4l2_pix_format* pfmt = &(cam->sensor->pix_format);
1297
1298 if (copy_from_user(&format, arg, sizeof(format)))
1299 return -EFAULT;
1300
1301 if (format.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1302 return -EINVAL;
1303
1304 pfmt->bytesperline = 0;
1305 pfmt->sizeimage = pfmt->height * ((pfmt->width*pfmt->priv)/8);
1306 pfmt->field = V4L2_FIELD_NONE;
1307 memcpy(&(format.fmt.pix), pfmt, sizeof(*pfmt));
1308
1309 if (copy_to_user(arg, &format, sizeof(format)))
1310 return -EFAULT;
1311
1312 return 0;
1313}
1314
1315
1316static int
1317zc0301_vidioc_try_s_fmt(struct zc0301_device* cam, unsigned int cmd,
1318 void __user * arg)
1319{
1320 struct zc0301_sensor* s = cam->sensor;
1321 struct v4l2_format format;
1322 struct v4l2_pix_format* pix;
1323 struct v4l2_pix_format* pfmt = &(s->pix_format);
1324 struct v4l2_rect* bounds = &(s->cropcap.bounds);
1325 struct v4l2_rect rect;
1326 const enum zc0301_stream_state stream = cam->stream;
1327 const u32 nbuffers = cam->nbuffers;
1328 u32 i;
1329 int err = 0;
1330
1331 if (copy_from_user(&format, arg, sizeof(format)))
1332 return -EFAULT;
1333
1334 pix = &(format.fmt.pix);
1335
1336 if (format.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1337 return -EINVAL;
1338
1339 memcpy(&rect, &(s->_rect), sizeof(rect));
1340
1341 if (!s->set_crop) {
1342 pix->width = rect.width;
1343 pix->height = rect.height;
1344 } else {
1345 rect.width = pix->width;
1346 rect.height = pix->height;
1347 }
1348
1349 if (rect.width < 8)
1350 rect.width = 8;
1351 if (rect.height < 8)
1352 rect.height = 8;
1353 if (rect.width > bounds->left + bounds->width - rect.left)
1354 rect.width = bounds->left + bounds->width - rect.left;
1355 if (rect.height > bounds->top + bounds->height - rect.top)
1356 rect.height = bounds->top + bounds->height - rect.top;
1357 rect.width &= ~7L;
1358 rect.height &= ~7L;
1359
1360 pix->width = rect.width;
1361 pix->height = rect.height;
1362 pix->pixelformat = pfmt->pixelformat;
1363 pix->priv = pfmt->priv;
1364 pix->colorspace = pfmt->colorspace;
1365 pix->bytesperline = 0;
1366 pix->sizeimage = pix->height * ((pix->width * pix->priv) / 8);
1367 pix->field = V4L2_FIELD_NONE;
1368
1369 if (cmd == VIDIOC_TRY_FMT) {
1370 if (copy_to_user(arg, &format, sizeof(format)))
1371 return -EFAULT;
1372 return 0;
1373 }
1374
1375 if (cam->module_param.force_munmap)
1376 for (i = 0; i < cam->nbuffers; i++)
1377 if (cam->frame[i].vma_use_count) {
1378 DBG(3, "VIDIOC_S_FMT failed. "
1379 "Unmap the buffers first.");
1380 return -EINVAL;
1381 }
1382
1383 if (cam->stream == STREAM_ON)
1384 if ((err = zc0301_stream_interrupt(cam)))
1385 return err;
1386
1387 if (copy_to_user(arg, &format, sizeof(format))) {
1388 cam->stream = stream;
1389 return -EFAULT;
1390 }
1391
1392 if (cam->module_param.force_munmap || cam->io == IO_READ)
1393 zc0301_release_buffers(cam);
1394
1395 if (s->set_crop)
1396 err += s->set_crop(cam, &rect);
1397
1398 if (err) { /* atomic, no rollback in ioctl() */
1399 cam->state |= DEV_MISCONFIGURED;
1400 DBG(1, "VIDIOC_S_FMT failed because of hardware problems. To "
1401 "use the camera, close and open /dev/video%d again.",
1402 cam->v4ldev->minor);
1403 return -EIO;
1404 }
1405
1406 memcpy(pfmt, pix, sizeof(*pix));
1407 memcpy(&(s->_rect), &rect, sizeof(rect));
1408
1409 if ((cam->module_param.force_munmap || cam->io == IO_READ) &&
1410 nbuffers != zc0301_request_buffers(cam, nbuffers, cam->io)) {
1411 cam->state |= DEV_MISCONFIGURED;
1412 DBG(1, "VIDIOC_S_FMT failed because of not enough memory. To "
1413 "use the camera, close and open /dev/video%d again.",
1414 cam->v4ldev->minor);
1415 return -ENOMEM;
1416 }
1417
1418 if (cam->io == IO_READ)
1419 zc0301_empty_framequeues(cam);
1420 else if (cam->module_param.force_munmap)
1421 zc0301_requeue_outqueue(cam);
1422
1423 cam->stream = stream;
1424
1425 return 0;
1426}
1427
1428
1429static int
1430zc0301_vidioc_g_jpegcomp(struct zc0301_device* cam, void __user * arg)
1431{
1432 if (copy_to_user(arg, &cam->compression, sizeof(cam->compression)))
1433 return -EFAULT;
1434
1435 return 0;
1436}
1437
1438
1439static int
1440zc0301_vidioc_s_jpegcomp(struct zc0301_device* cam, void __user * arg)
1441{
1442 struct v4l2_jpegcompression jc;
1443 const enum zc0301_stream_state stream = cam->stream;
1444 int err = 0;
1445
1446 if (copy_from_user(&jc, arg, sizeof(jc)))
1447 return -EFAULT;
1448
1449 if (jc.quality < 0 || jc.quality > 3)
1450 return -EINVAL;
1451
1452 if (cam->stream == STREAM_ON)
1453 if ((err = zc0301_stream_interrupt(cam)))
1454 return err;
1455
1456 err += zc0301_set_compression(cam, &jc);
1457 if (err) { /* atomic, no rollback in ioctl() */
1458 cam->state |= DEV_MISCONFIGURED;
1459 DBG(1, "VIDIOC_S_JPEGCOMP failed because of hardware "
1460 "problems. To use the camera, close and open "
1461 "/dev/video%d again.", cam->v4ldev->minor);
1462 return -EIO;
1463 }
1464
1465 cam->compression.quality = jc.quality;
1466
1467 cam->stream = stream;
1468
1469 return 0;
1470}
1471
1472
1473static int
1474zc0301_vidioc_reqbufs(struct zc0301_device* cam, void __user * arg)
1475{
1476 struct v4l2_requestbuffers rb;
1477 u32 i;
1478 int err;
1479
1480 if (copy_from_user(&rb, arg, sizeof(rb)))
1481 return -EFAULT;
1482
1483 if (rb.type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
1484 rb.memory != V4L2_MEMORY_MMAP)
1485 return -EINVAL;
1486
1487 if (cam->io == IO_READ) {
1488 DBG(3, "Close and open the device again to choose the mmap "
1489 "I/O method");
1490 return -EINVAL;
1491 }
1492
1493 for (i = 0; i < cam->nbuffers; i++)
1494 if (cam->frame[i].vma_use_count) {
1495 DBG(3, "VIDIOC_REQBUFS failed. "
1496 "Previous buffers are still mapped.");
1497 return -EINVAL;
1498 }
1499
1500 if (cam->stream == STREAM_ON)
1501 if ((err = zc0301_stream_interrupt(cam)))
1502 return err;
1503
1504 zc0301_empty_framequeues(cam);
1505
1506 zc0301_release_buffers(cam);
1507 if (rb.count)
1508 rb.count = zc0301_request_buffers(cam, rb.count, IO_MMAP);
1509
1510 if (copy_to_user(arg, &rb, sizeof(rb))) {
1511 zc0301_release_buffers(cam);
1512 cam->io = IO_NONE;
1513 return -EFAULT;
1514 }
1515
1516 cam->io = rb.count ? IO_MMAP : IO_NONE;
1517
1518 return 0;
1519}
1520
1521
1522static int
1523zc0301_vidioc_querybuf(struct zc0301_device* cam, void __user * arg)
1524{
1525 struct v4l2_buffer b;
1526
1527 if (copy_from_user(&b, arg, sizeof(b)))
1528 return -EFAULT;
1529
1530 if (b.type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
1531 b.index >= cam->nbuffers || cam->io != IO_MMAP)
1532 return -EINVAL;
1533
1534 memcpy(&b, &cam->frame[b.index].buf, sizeof(b));
1535
1536 if (cam->frame[b.index].vma_use_count)
1537 b.flags |= V4L2_BUF_FLAG_MAPPED;
1538
1539 if (cam->frame[b.index].state == F_DONE)
1540 b.flags |= V4L2_BUF_FLAG_DONE;
1541 else if (cam->frame[b.index].state != F_UNUSED)
1542 b.flags |= V4L2_BUF_FLAG_QUEUED;
1543
1544 if (copy_to_user(arg, &b, sizeof(b)))
1545 return -EFAULT;
1546
1547 return 0;
1548}
1549
1550
1551static int
1552zc0301_vidioc_qbuf(struct zc0301_device* cam, void __user * arg)
1553{
1554 struct v4l2_buffer b;
1555 unsigned long lock_flags;
1556
1557 if (copy_from_user(&b, arg, sizeof(b)))
1558 return -EFAULT;
1559
1560 if (b.type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
1561 b.index >= cam->nbuffers || cam->io != IO_MMAP)
1562 return -EINVAL;
1563
1564 if (cam->frame[b.index].state != F_UNUSED)
1565 return -EINVAL;
1566
1567 cam->frame[b.index].state = F_QUEUED;
1568
1569 spin_lock_irqsave(&cam->queue_lock, lock_flags);
1570 list_add_tail(&cam->frame[b.index].frame, &cam->inqueue);
1571 spin_unlock_irqrestore(&cam->queue_lock, lock_flags);
1572
1573 PDBGG("Frame #%lu queued", (unsigned long)b.index);
1574
1575 return 0;
1576}
1577
1578
1579static int
1580zc0301_vidioc_dqbuf(struct zc0301_device* cam, struct file* filp,
1581 void __user * arg)
1582{
1583 struct v4l2_buffer b;
1584 struct zc0301_frame_t *f;
1585 unsigned long lock_flags;
1586 long timeout;
1587
1588 if (copy_from_user(&b, arg, sizeof(b)))
1589 return -EFAULT;
1590
1591 if (b.type != V4L2_BUF_TYPE_VIDEO_CAPTURE || cam->io!= IO_MMAP)
1592 return -EINVAL;
1593
1594 if (list_empty(&cam->outqueue)) {
1595 if (cam->stream == STREAM_OFF)
1596 return -EINVAL;
1597 if (filp->f_flags & O_NONBLOCK)
1598 return -EAGAIN;
1599 timeout = wait_event_interruptible_timeout
1600 ( cam->wait_frame,
1601 (!list_empty(&cam->outqueue)) ||
1602 (cam->state & DEV_DISCONNECTED) ||
1603 (cam->state & DEV_MISCONFIGURED),
1604 ZC0301_FRAME_TIMEOUT );
1605 if (timeout < 0)
1606 return timeout;
1607 if (cam->state & DEV_DISCONNECTED)
1608 return -ENODEV;
1609 if (!timeout || (cam->state & DEV_MISCONFIGURED))
1610 return -EIO;
1611 }
1612
1613 spin_lock_irqsave(&cam->queue_lock, lock_flags);
1614 f = list_entry(cam->outqueue.next, struct zc0301_frame_t, frame);
1615 list_del(cam->outqueue.next);
1616 spin_unlock_irqrestore(&cam->queue_lock, lock_flags);
1617
1618 f->state = F_UNUSED;
1619
1620 memcpy(&b, &f->buf, sizeof(b));
1621 if (f->vma_use_count)
1622 b.flags |= V4L2_BUF_FLAG_MAPPED;
1623
1624 if (copy_to_user(arg, &b, sizeof(b)))
1625 return -EFAULT;
1626
1627 PDBGG("Frame #%lu dequeued", (unsigned long)f->buf.index);
1628
1629 return 0;
1630}
1631
1632
1633static int
1634zc0301_vidioc_streamon(struct zc0301_device* cam, void __user * arg)
1635{
1636 int type;
1637
1638 if (copy_from_user(&type, arg, sizeof(type)))
1639 return -EFAULT;
1640
1641 if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE || cam->io != IO_MMAP)
1642 return -EINVAL;
1643
1644 if (list_empty(&cam->inqueue))
1645 return -EINVAL;
1646
1647 cam->stream = STREAM_ON;
1648
1649 DBG(3, "Stream on");
1650
1651 return 0;
1652}
1653
1654
1655static int
1656zc0301_vidioc_streamoff(struct zc0301_device* cam, void __user * arg)
1657{
1658 int type, err;
1659
1660 if (copy_from_user(&type, arg, sizeof(type)))
1661 return -EFAULT;
1662
1663 if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE || cam->io != IO_MMAP)
1664 return -EINVAL;
1665
1666 if (cam->stream == STREAM_ON)
1667 if ((err = zc0301_stream_interrupt(cam)))
1668 return err;
1669
1670 zc0301_empty_framequeues(cam);
1671
1672 DBG(3, "Stream off");
1673
1674 return 0;
1675}
1676
1677
1678static int
1679zc0301_vidioc_g_parm(struct zc0301_device* cam, void __user * arg)
1680{
1681 struct v4l2_streamparm sp;
1682
1683 if (copy_from_user(&sp, arg, sizeof(sp)))
1684 return -EFAULT;
1685
1686 if (sp.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1687 return -EINVAL;
1688
1689 sp.parm.capture.extendedmode = 0;
1690 sp.parm.capture.readbuffers = cam->nreadbuffers;
1691
1692 if (copy_to_user(arg, &sp, sizeof(sp)))
1693 return -EFAULT;
1694
1695 return 0;
1696}
1697
1698
1699static int
1700zc0301_vidioc_s_parm(struct zc0301_device* cam, void __user * arg)
1701{
1702 struct v4l2_streamparm sp;
1703
1704 if (copy_from_user(&sp, arg, sizeof(sp)))
1705 return -EFAULT;
1706
1707 if (sp.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1708 return -EINVAL;
1709
1710 sp.parm.capture.extendedmode = 0;
1711
1712 if (sp.parm.capture.readbuffers == 0)
1713 sp.parm.capture.readbuffers = cam->nreadbuffers;
1714
1715 if (sp.parm.capture.readbuffers > ZC0301_MAX_FRAMES)
1716 sp.parm.capture.readbuffers = ZC0301_MAX_FRAMES;
1717
1718 if (copy_to_user(arg, &sp, sizeof(sp)))
1719 return -EFAULT;
1720
1721 cam->nreadbuffers = sp.parm.capture.readbuffers;
1722
1723 return 0;
1724}
1725
1726
1727static int zc0301_ioctl_v4l2(struct inode* inode, struct file* filp,
1728 unsigned int cmd, void __user * arg)
1729{
1730 struct zc0301_device* cam = video_get_drvdata(video_devdata(filp));
1731
1732 switch (cmd) {
1733
1734 case VIDIOC_QUERYCAP:
1735 return zc0301_vidioc_querycap(cam, arg);
1736
1737 case VIDIOC_ENUMINPUT:
1738 return zc0301_vidioc_enuminput(cam, arg);
1739
1740 case VIDIOC_G_INPUT:
1741 case VIDIOC_S_INPUT:
1742 return zc0301_vidioc_gs_input(cam, arg);
1743
1744 case VIDIOC_QUERYCTRL:
1745 return zc0301_vidioc_query_ctrl(cam, arg);
1746
1747 case VIDIOC_G_CTRL:
1748 return zc0301_vidioc_g_ctrl(cam, arg);
1749
1750 case VIDIOC_S_CTRL_OLD:
1751 case VIDIOC_S_CTRL:
1752 return zc0301_vidioc_s_ctrl(cam, arg);
1753
1754 case VIDIOC_CROPCAP_OLD:
1755 case VIDIOC_CROPCAP:
1756 return zc0301_vidioc_cropcap(cam, arg);
1757
1758 case VIDIOC_G_CROP:
1759 return zc0301_vidioc_g_crop(cam, arg);
1760
1761 case VIDIOC_S_CROP:
1762 return zc0301_vidioc_s_crop(cam, arg);
1763
1764 case VIDIOC_ENUM_FMT:
1765 return zc0301_vidioc_enum_fmt(cam, arg);
1766
1767 case VIDIOC_G_FMT:
1768 return zc0301_vidioc_g_fmt(cam, arg);
1769
1770 case VIDIOC_TRY_FMT:
1771 case VIDIOC_S_FMT:
1772 return zc0301_vidioc_try_s_fmt(cam, cmd, arg);
1773
1774 case VIDIOC_G_JPEGCOMP:
1775 return zc0301_vidioc_g_jpegcomp(cam, arg);
1776
1777 case VIDIOC_S_JPEGCOMP:
1778 return zc0301_vidioc_s_jpegcomp(cam, arg);
1779
1780 case VIDIOC_REQBUFS:
1781 return zc0301_vidioc_reqbufs(cam, arg);
1782
1783 case VIDIOC_QUERYBUF:
1784 return zc0301_vidioc_querybuf(cam, arg);
1785
1786 case VIDIOC_QBUF:
1787 return zc0301_vidioc_qbuf(cam, arg);
1788
1789 case VIDIOC_DQBUF:
1790 return zc0301_vidioc_dqbuf(cam, filp, arg);
1791
1792 case VIDIOC_STREAMON:
1793 return zc0301_vidioc_streamon(cam, arg);
1794
1795 case VIDIOC_STREAMOFF:
1796 return zc0301_vidioc_streamoff(cam, arg);
1797
1798 case VIDIOC_G_PARM:
1799 return zc0301_vidioc_g_parm(cam, arg);
1800
1801 case VIDIOC_S_PARM_OLD:
1802 case VIDIOC_S_PARM:
1803 return zc0301_vidioc_s_parm(cam, arg);
1804
1805 case VIDIOC_G_STD:
1806 case VIDIOC_S_STD:
1807 case VIDIOC_QUERYSTD:
1808 case VIDIOC_ENUMSTD:
1809 case VIDIOC_QUERYMENU:
1810 return -EINVAL;
1811
1812 default:
1813 return -EINVAL;
1814
1815 }
1816}
1817
1818
1819static int zc0301_ioctl(struct inode* inode, struct file* filp,
1820 unsigned int cmd, unsigned long arg)
1821{
1822 struct zc0301_device* cam = video_get_drvdata(video_devdata(filp));
1823 int err = 0;
1824
1825 if (mutex_lock_interruptible(&cam->fileop_mutex))
1826 return -ERESTARTSYS;
1827
1828 if (cam->state & DEV_DISCONNECTED) {
1829 DBG(1, "Device not present");
1830 mutex_unlock(&cam->fileop_mutex);
1831 return -ENODEV;
1832 }
1833
1834 if (cam->state & DEV_MISCONFIGURED) {
1835 DBG(1, "The camera is misconfigured. Close and open it "
1836 "again.");
1837 mutex_unlock(&cam->fileop_mutex);
1838 return -EIO;
1839 }
1840
1841 V4LDBG(3, "zc0301", cmd);
1842
1843 err = zc0301_ioctl_v4l2(inode, filp, cmd, (void __user *)arg);
1844
1845 mutex_unlock(&cam->fileop_mutex);
1846
1847 return err;
1848}
1849
1850
1851static struct file_operations zc0301_fops = {
1852 .owner = THIS_MODULE,
1853 .open = zc0301_open,
1854 .release = zc0301_release,
1855 .ioctl = zc0301_ioctl,
1856 .read = zc0301_read,
1857 .poll = zc0301_poll,
1858 .mmap = zc0301_mmap,
1859 .llseek = no_llseek,
1860};
1861
1862/*****************************************************************************/
1863
1864static int
1865zc0301_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
1866{
1867 struct usb_device *udev = interface_to_usbdev(intf);
1868 struct zc0301_device* cam;
1869 static unsigned int dev_nr = 0;
1870 unsigned int i;
1871 int err = 0;
1872
1873 if (!(cam = kzalloc(sizeof(struct zc0301_device), GFP_KERNEL)))
1874 return -ENOMEM;
1875
1876 cam->usbdev = udev;
1877
1878 if (!(cam->control_buffer = kzalloc(4, GFP_KERNEL))) {
1879 DBG(1, "kmalloc() failed");
1880 err = -ENOMEM;
1881 goto fail;
1882 }
1883
1884 if (!(cam->v4ldev = video_device_alloc())) {
1885 DBG(1, "video_device_alloc() failed");
1886 err = -ENOMEM;
1887 goto fail;
1888 }
1889
1890 mutex_init(&cam->dev_mutex);
1891
1892 DBG(2, "ZC0301 Image Processor and Control Chip detected "
1893 "(vid/pid 0x%04X/0x%04X)",id->idVendor, id->idProduct);
1894
1895 for (i = 0; zc0301_sensor_table[i]; i++) {
1896 err = zc0301_sensor_table[i](cam);
1897 if (!err)
1898 break;
1899 }
1900
1901 if (!err && cam->sensor)
1902 DBG(2, "%s image sensor detected", cam->sensor->name);
1903 else {
1904 DBG(1, "No supported image sensor detected");
1905 err = -ENODEV;
1906 goto fail;
1907 }
1908
1909 if (zc0301_init(cam)) {
1910 DBG(1, "Initialization failed. I will retry on open().");
1911 cam->state |= DEV_MISCONFIGURED;
1912 }
1913
1914 strcpy(cam->v4ldev->name, "ZC0301 PC Camera");
1915 cam->v4ldev->owner = THIS_MODULE;
1916 cam->v4ldev->type = VID_TYPE_CAPTURE | VID_TYPE_SCALES;
1917 cam->v4ldev->hardware = 0;
1918 cam->v4ldev->fops = &zc0301_fops;
1919 cam->v4ldev->minor = video_nr[dev_nr];
1920 cam->v4ldev->release = video_device_release;
1921 video_set_drvdata(cam->v4ldev, cam);
1922
1923 mutex_lock(&cam->dev_mutex);
1924
1925 err = video_register_device(cam->v4ldev, VFL_TYPE_GRABBER,
1926 video_nr[dev_nr]);
1927 if (err) {
1928 DBG(1, "V4L2 device registration failed");
1929 if (err == -ENFILE && video_nr[dev_nr] == -1)
1930 DBG(1, "Free /dev/videoX node not found");
1931 video_nr[dev_nr] = -1;
1932 dev_nr = (dev_nr < ZC0301_MAX_DEVICES-1) ? dev_nr+1 : 0;
1933 mutex_unlock(&cam->dev_mutex);
1934 goto fail;
1935 }
1936
1937 DBG(2, "V4L2 device registered as /dev/video%d", cam->v4ldev->minor);
1938
1939 cam->module_param.force_munmap = force_munmap[dev_nr];
1940
1941 dev_nr = (dev_nr < ZC0301_MAX_DEVICES-1) ? dev_nr+1 : 0;
1942
1943 usb_set_intfdata(intf, cam);
1944
1945 mutex_unlock(&cam->dev_mutex);
1946
1947 return 0;
1948
1949fail:
1950 if (cam) {
1951 kfree(cam->control_buffer);
1952 if (cam->v4ldev)
1953 video_device_release(cam->v4ldev);
1954 kfree(cam);
1955 }
1956 return err;
1957}
1958
1959
1960static void zc0301_usb_disconnect(struct usb_interface* intf)
1961{
1962 struct zc0301_device* cam = usb_get_intfdata(intf);
1963
1964 if (!cam)
1965 return;
1966
1967 down_write(&zc0301_disconnect);
1968
1969 mutex_lock(&cam->dev_mutex);
1970
1971 DBG(2, "Disconnecting %s...", cam->v4ldev->name);
1972
1973 wake_up_interruptible_all(&cam->open);
1974
1975 if (cam->users) {
1976 DBG(2, "Device /dev/video%d is open! Deregistration and "
1977 "memory deallocation are deferred on close.",
1978 cam->v4ldev->minor);
1979 cam->state |= DEV_MISCONFIGURED;
1980 zc0301_stop_transfer(cam);
1981 cam->state |= DEV_DISCONNECTED;
1982 wake_up_interruptible(&cam->wait_frame);
1983 wake_up_interruptible(&cam->wait_stream);
1984 } else {
1985 cam->state |= DEV_DISCONNECTED;
1986 zc0301_release_resources(cam);
1987 }
1988
1989 mutex_unlock(&cam->dev_mutex);
1990
1991 if (!cam->users)
1992 kfree(cam);
1993
1994 up_write(&zc0301_disconnect);
1995}
1996
1997
1998static struct usb_driver zc0301_usb_driver = {
1999 .name = "zc0301",
2000 .id_table = zc0301_id_table,
2001 .probe = zc0301_usb_probe,
2002 .disconnect = zc0301_usb_disconnect,
2003};
2004
2005/*****************************************************************************/
2006
2007static int __init zc0301_module_init(void)
2008{
2009 int err = 0;
2010
2011 KDBG(2, ZC0301_MODULE_NAME " v" ZC0301_MODULE_VERSION);
2012 KDBG(3, ZC0301_MODULE_AUTHOR);
2013
2014 if ((err = usb_register(&zc0301_usb_driver)))
2015 KDBG(1, "usb_register() failed");
2016
2017 return err;
2018}
2019
2020
2021static void __exit zc0301_module_exit(void)
2022{
2023 usb_deregister(&zc0301_usb_driver);
2024}
2025
2026
2027module_init(zc0301_module_init);
2028module_exit(zc0301_module_exit);
diff --git a/drivers/usb/media/zc0301_pas202bcb.c b/drivers/usb/media/zc0301_pas202bcb.c
new file mode 100644
index 000000000000..83b45f1c0f4e
--- /dev/null
+++ b/drivers/usb/media/zc0301_pas202bcb.c
@@ -0,0 +1,353 @@
1/***************************************************************************
2 * Plug-in for PAS202BCB image sensor connected to the ZC030! Image *
3 * Processor and Control Chip *
4 * *
5 * Copyright (C) 2006 by Luca Risolia <luca.risolia@studio.unibo.it> *
6 * *
7 * Initialization values of the ZC0301 have been taken from the SPCA5XX *
8 * driver maintained by Michel Xhaard <mxhaard@magic.fr> *
9 * *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the Free Software *
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
23 ***************************************************************************/
24
25#include <linux/delay.h>
26#include "zc0301_sensor.h"
27
28
29static struct zc0301_sensor pas202bcb;
30
31
32static int pas202bcb_init(struct zc0301_device* cam)
33{
34 int err = 0;
35
36 err += zc0301_write_reg(cam, 0x0002, 0x00);
37 err += zc0301_write_reg(cam, 0x0003, 0x02);
38 err += zc0301_write_reg(cam, 0x0004, 0x80);
39 err += zc0301_write_reg(cam, 0x0005, 0x01);
40 err += zc0301_write_reg(cam, 0x0006, 0xE0);
41 err += zc0301_write_reg(cam, 0x0098, 0x00);
42 err += zc0301_write_reg(cam, 0x009A, 0x03);
43 err += zc0301_write_reg(cam, 0x011A, 0x00);
44 err += zc0301_write_reg(cam, 0x011C, 0x03);
45 err += zc0301_write_reg(cam, 0x009B, 0x01);
46 err += zc0301_write_reg(cam, 0x009C, 0xE6);
47 err += zc0301_write_reg(cam, 0x009D, 0x02);
48 err += zc0301_write_reg(cam, 0x009E, 0x86);
49
50 err += zc0301_i2c_write(cam, 0x02, 0x02);
51 err += zc0301_i2c_write(cam, 0x0A, 0x01);
52 err += zc0301_i2c_write(cam, 0x0B, 0x01);
53 err += zc0301_i2c_write(cam, 0x0D, 0x00);
54 err += zc0301_i2c_write(cam, 0x12, 0x05);
55 err += zc0301_i2c_write(cam, 0x13, 0x63);
56 err += zc0301_i2c_write(cam, 0x15, 0x70);
57
58 err += zc0301_write_reg(cam, 0x0101, 0xB7);
59 err += zc0301_write_reg(cam, 0x0100, 0x0D);
60 err += zc0301_write_reg(cam, 0x0189, 0x06);
61 err += zc0301_write_reg(cam, 0x01AD, 0x00);
62 err += zc0301_write_reg(cam, 0x01C5, 0x03);
63 err += zc0301_write_reg(cam, 0x01CB, 0x13);
64 err += zc0301_write_reg(cam, 0x0250, 0x08);
65 err += zc0301_write_reg(cam, 0x0301, 0x08);
66 err += zc0301_write_reg(cam, 0x018D, 0x70);
67 err += zc0301_write_reg(cam, 0x0008, 0x03);
68 err += zc0301_write_reg(cam, 0x01C6, 0x04);
69 err += zc0301_write_reg(cam, 0x01CB, 0x07);
70 err += zc0301_write_reg(cam, 0x0120, 0x11);
71 err += zc0301_write_reg(cam, 0x0121, 0x37);
72 err += zc0301_write_reg(cam, 0x0122, 0x58);
73 err += zc0301_write_reg(cam, 0x0123, 0x79);
74 err += zc0301_write_reg(cam, 0x0124, 0x91);
75 err += zc0301_write_reg(cam, 0x0125, 0xA6);
76 err += zc0301_write_reg(cam, 0x0126, 0xB8);
77 err += zc0301_write_reg(cam, 0x0127, 0xC7);
78 err += zc0301_write_reg(cam, 0x0128, 0xD3);
79 err += zc0301_write_reg(cam, 0x0129, 0xDE);
80 err += zc0301_write_reg(cam, 0x012A, 0xE6);
81 err += zc0301_write_reg(cam, 0x012B, 0xED);
82 err += zc0301_write_reg(cam, 0x012C, 0xF3);
83 err += zc0301_write_reg(cam, 0x012D, 0xF8);
84 err += zc0301_write_reg(cam, 0x012E, 0xFB);
85 err += zc0301_write_reg(cam, 0x012F, 0xFF);
86 err += zc0301_write_reg(cam, 0x0130, 0x26);
87 err += zc0301_write_reg(cam, 0x0131, 0x23);
88 err += zc0301_write_reg(cam, 0x0132, 0x20);
89 err += zc0301_write_reg(cam, 0x0133, 0x1C);
90 err += zc0301_write_reg(cam, 0x0134, 0x16);
91 err += zc0301_write_reg(cam, 0x0135, 0x13);
92 err += zc0301_write_reg(cam, 0x0136, 0x10);
93 err += zc0301_write_reg(cam, 0x0137, 0x0D);
94 err += zc0301_write_reg(cam, 0x0138, 0x0B);
95 err += zc0301_write_reg(cam, 0x0139, 0x09);
96 err += zc0301_write_reg(cam, 0x013A, 0x07);
97 err += zc0301_write_reg(cam, 0x013B, 0x06);
98 err += zc0301_write_reg(cam, 0x013C, 0x05);
99 err += zc0301_write_reg(cam, 0x013D, 0x04);
100 err += zc0301_write_reg(cam, 0x013E, 0x03);
101 err += zc0301_write_reg(cam, 0x013F, 0x02);
102 err += zc0301_write_reg(cam, 0x010A, 0x4C);
103 err += zc0301_write_reg(cam, 0x010B, 0xF5);
104 err += zc0301_write_reg(cam, 0x010C, 0xFF);
105 err += zc0301_write_reg(cam, 0x010D, 0xF9);
106 err += zc0301_write_reg(cam, 0x010E, 0x51);
107 err += zc0301_write_reg(cam, 0x010F, 0xF5);
108 err += zc0301_write_reg(cam, 0x0110, 0xFB);
109 err += zc0301_write_reg(cam, 0x0111, 0xED);
110 err += zc0301_write_reg(cam, 0x0112, 0x5F);
111 err += zc0301_write_reg(cam, 0x0180, 0x00);
112 err += zc0301_write_reg(cam, 0x0019, 0x00);
113 err += zc0301_write_reg(cam, 0x0087, 0x20);
114 err += zc0301_write_reg(cam, 0x0088, 0x21);
115
116 err += zc0301_i2c_write(cam, 0x20, 0x02);
117 err += zc0301_i2c_write(cam, 0x21, 0x1B);
118 err += zc0301_i2c_write(cam, 0x03, 0x44);
119 err += zc0301_i2c_write(cam, 0x0E, 0x01);
120 err += zc0301_i2c_write(cam, 0x0F, 0x00);
121
122 err += zc0301_write_reg(cam, 0x01A9, 0x14);
123 err += zc0301_write_reg(cam, 0x01AA, 0x24);
124 err += zc0301_write_reg(cam, 0x0190, 0x00);
125 err += zc0301_write_reg(cam, 0x0191, 0x02);
126 err += zc0301_write_reg(cam, 0x0192, 0x1B);
127 err += zc0301_write_reg(cam, 0x0195, 0x00);
128 err += zc0301_write_reg(cam, 0x0196, 0x00);
129 err += zc0301_write_reg(cam, 0x0197, 0x4D);
130 err += zc0301_write_reg(cam, 0x018C, 0x10);
131 err += zc0301_write_reg(cam, 0x018F, 0x20);
132 err += zc0301_write_reg(cam, 0x001D, 0x44);
133 err += zc0301_write_reg(cam, 0x001E, 0x6F);
134 err += zc0301_write_reg(cam, 0x001F, 0xAD);
135 err += zc0301_write_reg(cam, 0x0020, 0xEB);
136 err += zc0301_write_reg(cam, 0x0087, 0x0F);
137 err += zc0301_write_reg(cam, 0x0088, 0x0E);
138 err += zc0301_write_reg(cam, 0x0180, 0x40);
139 err += zc0301_write_reg(cam, 0x0192, 0x1B);
140 err += zc0301_write_reg(cam, 0x0191, 0x02);
141 err += zc0301_write_reg(cam, 0x0190, 0x00);
142 err += zc0301_write_reg(cam, 0x0116, 0x1D);
143 err += zc0301_write_reg(cam, 0x0117, 0x40);
144 err += zc0301_write_reg(cam, 0x0118, 0x99);
145 err += zc0301_write_reg(cam, 0x0180, 0x42);
146 err += zc0301_write_reg(cam, 0x0116, 0x1D);
147 err += zc0301_write_reg(cam, 0x0117, 0x40);
148 err += zc0301_write_reg(cam, 0x0118, 0x99);
149 err += zc0301_write_reg(cam, 0x0007, 0x00);
150
151 err += zc0301_i2c_write(cam, 0x11, 0x01);
152
153 msleep(100);
154
155 return err;
156}
157
158
159static int pas202bcb_get_ctrl(struct zc0301_device* cam,
160 struct v4l2_control* ctrl)
161{
162 switch (ctrl->id) {
163 case V4L2_CID_EXPOSURE:
164 {
165 int r1 = zc0301_i2c_read(cam, 0x04, 1),
166 r2 = zc0301_i2c_read(cam, 0x05, 1);
167 if (r1 < 0 || r2 < 0)
168 return -EIO;
169 ctrl->value = (r1 << 6) | (r2 & 0x3f);
170 }
171 return 0;
172 case V4L2_CID_RED_BALANCE:
173 if ((ctrl->value = zc0301_i2c_read(cam, 0x09, 1)) < 0)
174 return -EIO;
175 ctrl->value &= 0x0f;
176 return 0;
177 case V4L2_CID_BLUE_BALANCE:
178 if ((ctrl->value = zc0301_i2c_read(cam, 0x07, 1)) < 0)
179 return -EIO;
180 ctrl->value &= 0x0f;
181 return 0;
182 case V4L2_CID_GAIN:
183 if ((ctrl->value = zc0301_i2c_read(cam, 0x10, 1)) < 0)
184 return -EIO;
185 ctrl->value &= 0x1f;
186 return 0;
187 case ZC0301_V4L2_CID_GREEN_BALANCE:
188 if ((ctrl->value = zc0301_i2c_read(cam, 0x08, 1)) < 0)
189 return -EIO;
190 ctrl->value &= 0x0f;
191 return 0;
192 case ZC0301_V4L2_CID_DAC_MAGNITUDE:
193 if ((ctrl->value = zc0301_i2c_read(cam, 0x0c, 1)) < 0)
194 return -EIO;
195 return 0;
196 default:
197 return -EINVAL;
198 }
199}
200
201
202static int pas202bcb_set_ctrl(struct zc0301_device* cam,
203 const struct v4l2_control* ctrl)
204{
205 int err = 0;
206
207 switch (ctrl->id) {
208 case V4L2_CID_EXPOSURE:
209 err += zc0301_i2c_write(cam, 0x04, ctrl->value >> 6);
210 err += zc0301_i2c_write(cam, 0x05, ctrl->value & 0x3f);
211 break;
212 case V4L2_CID_RED_BALANCE:
213 err += zc0301_i2c_write(cam, 0x09, ctrl->value);
214 break;
215 case V4L2_CID_BLUE_BALANCE:
216 err += zc0301_i2c_write(cam, 0x07, ctrl->value);
217 break;
218 case V4L2_CID_GAIN:
219 err += zc0301_i2c_write(cam, 0x10, ctrl->value);
220 break;
221 case ZC0301_V4L2_CID_GREEN_BALANCE:
222 err += zc0301_i2c_write(cam, 0x08, ctrl->value);
223 break;
224 case ZC0301_V4L2_CID_DAC_MAGNITUDE:
225 err += zc0301_i2c_write(cam, 0x0c, ctrl->value);
226 break;
227 default:
228 return -EINVAL;
229 }
230 err += zc0301_i2c_write(cam, 0x11, 0x01);
231
232 return err ? -EIO : 0;
233}
234
235
236static struct zc0301_sensor pas202bcb = {
237 .name = "PAS202BCB",
238 .init = &pas202bcb_init,
239 .qctrl = {
240 {
241 .id = V4L2_CID_EXPOSURE,
242 .type = V4L2_CTRL_TYPE_INTEGER,
243 .name = "exposure",
244 .minimum = 0x01e5,
245 .maximum = 0x3fff,
246 .step = 0x0001,
247 .default_value = 0x01e5,
248 .flags = 0,
249 },
250 {
251 .id = V4L2_CID_GAIN,
252 .type = V4L2_CTRL_TYPE_INTEGER,
253 .name = "global gain",
254 .minimum = 0x00,
255 .maximum = 0x1f,
256 .step = 0x01,
257 .default_value = 0x0c,
258 .flags = 0,
259 },
260 {
261 .id = V4L2_CID_RED_BALANCE,
262 .type = V4L2_CTRL_TYPE_INTEGER,
263 .name = "red balance",
264 .minimum = 0x00,
265 .maximum = 0x0f,
266 .step = 0x01,
267 .default_value = 0x01,
268 .flags = 0,
269 },
270 {
271 .id = V4L2_CID_BLUE_BALANCE,
272 .type = V4L2_CTRL_TYPE_INTEGER,
273 .name = "blue balance",
274 .minimum = 0x00,
275 .maximum = 0x0f,
276 .step = 0x01,
277 .default_value = 0x05,
278 .flags = 0,
279 },
280 {
281 .id = ZC0301_V4L2_CID_GREEN_BALANCE,
282 .type = V4L2_CTRL_TYPE_INTEGER,
283 .name = "green balance",
284 .minimum = 0x00,
285 .maximum = 0x0f,
286 .step = 0x01,
287 .default_value = 0x00,
288 .flags = 0,
289 },
290 {
291 .id = ZC0301_V4L2_CID_DAC_MAGNITUDE,
292 .type = V4L2_CTRL_TYPE_INTEGER,
293 .name = "DAC magnitude",
294 .minimum = 0x00,
295 .maximum = 0xff,
296 .step = 0x01,
297 .default_value = 0x04,
298 .flags = 0,
299 },
300 },
301 .get_ctrl = &pas202bcb_get_ctrl,
302 .set_ctrl = &pas202bcb_set_ctrl,
303 .cropcap = {
304 .bounds = {
305 .left = 0,
306 .top = 0,
307 .width = 640,
308 .height = 480,
309 },
310 .defrect = {
311 .left = 0,
312 .top = 0,
313 .width = 640,
314 .height = 480,
315 },
316 },
317 .pix_format = {
318 .width = 640,
319 .height = 480,
320 .pixelformat = V4L2_PIX_FMT_JPEG,
321 .priv = 16,
322 },
323};
324
325
326int zc0301_probe_pas202bcb(struct zc0301_device* cam)
327{
328 int r0 = 0, r1 = 0, err = 0;
329 unsigned int pid = 0;
330
331 err += zc0301_write_reg(cam, 0x0000, 0x01);
332 err += zc0301_write_reg(cam, 0x0010, 0x0e);
333 err += zc0301_write_reg(cam, 0x0001, 0x01);
334 err += zc0301_write_reg(cam, 0x0012, 0x03);
335 err += zc0301_write_reg(cam, 0x0012, 0x01);
336 err += zc0301_write_reg(cam, 0x008d, 0x08);
337
338 msleep(10);
339
340 r0 = zc0301_i2c_read(cam, 0x00, 1);
341 r1 = zc0301_i2c_read(cam, 0x01, 1);
342
343 if (r0 < 0 || r1 < 0 || err)
344 return -EIO;
345
346 pid = (r0 << 4) | ((r1 & 0xf0) >> 4);
347 if (pid != 0x017)
348 return -ENODEV;
349
350 zc0301_attach_sensor(cam, &pas202bcb);
351
352 return 0;
353}
diff --git a/drivers/usb/media/zc0301_sensor.h b/drivers/usb/media/zc0301_sensor.h
new file mode 100644
index 000000000000..8890e32405d4
--- /dev/null
+++ b/drivers/usb/media/zc0301_sensor.h
@@ -0,0 +1,98 @@
1/***************************************************************************
2 * API for image sensors connected to the ZC030! Image Processor and *
3 * Control Chip *
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#ifndef _ZC0301_SENSOR_H_
23#define _ZC0301_SENSOR_H_
24
25#include <linux/usb.h>
26#include <linux/videodev.h>
27#include <linux/device.h>
28#include <linux/stddef.h>
29#include <linux/errno.h>
30#include <asm/types.h>
31
32struct zc0301_device;
33struct zc0301_sensor;
34
35/*****************************************************************************/
36
37extern int zc0301_probe_pas202bcb(struct zc0301_device* cam);
38
39#define ZC0301_SENSOR_TABLE \
40/* Weak detections must go at the end of the list */ \
41static int (*zc0301_sensor_table[])(struct zc0301_device*) = { \
42 &zc0301_probe_pas202bcb, \
43 NULL, \
44};
45
46extern void
47zc0301_attach_sensor(struct zc0301_device* cam,
48 struct zc0301_sensor* sensor);
49
50#define ZC0301_USB_DEVICE(vend, prod, intclass) \
51 .match_flags = USB_DEVICE_ID_MATCH_DEVICE | \
52 USB_DEVICE_ID_MATCH_INT_CLASS, \
53 .idVendor = (vend), \
54 .idProduct = (prod), \
55 .bInterfaceClass = (intclass)
56
57#define ZC0301_ID_TABLE \
58static const struct usb_device_id zc0301_id_table[] = { \
59 { ZC0301_USB_DEVICE(0x046d, 0x08ae, 0xff), }, /* PAS202BCB */ \
60 { } \
61};
62
63/*****************************************************************************/
64
65extern int zc0301_write_reg(struct zc0301_device*, u16 index, u16 value);
66extern int zc0301_read_reg(struct zc0301_device*, u16 index);
67extern int zc0301_i2c_write(struct zc0301_device*, u16 address, u16 value);
68extern int zc0301_i2c_read(struct zc0301_device*, u16 address, u8 length);
69
70/*****************************************************************************/
71
72#define ZC0301_MAX_CTRLS V4L2_CID_LASTP1-V4L2_CID_BASE+10
73#define ZC0301_V4L2_CID_DAC_MAGNITUDE V4L2_CID_PRIVATE_BASE
74#define ZC0301_V4L2_CID_GREEN_BALANCE V4L2_CID_PRIVATE_BASE + 1
75
76struct zc0301_sensor {
77 char name[32];
78
79 struct v4l2_queryctrl qctrl[ZC0301_MAX_CTRLS];
80 struct v4l2_cropcap cropcap;
81 struct v4l2_pix_format pix_format;
82
83 int (*init)(struct zc0301_device* cam);
84 int (*get_ctrl)(struct zc0301_device* cam,
85 struct v4l2_control* ctrl);
86 int (*set_ctrl)(struct zc0301_device* cam,
87 const struct v4l2_control* ctrl);
88 int (*set_crop)(struct zc0301_device* cam,
89 const struct v4l2_rect* rect);
90
91 const struct usb_device* usbdev;
92
93 /* Private */
94 struct v4l2_queryctrl _qctrl[ZC0301_MAX_CTRLS];
95 struct v4l2_rect _rect;
96};
97
98#endif /* _ZC0301_SENSOR_H_ */