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