diff options
author | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-08-14 00:01:29 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-08-15 15:34:46 -0400 |
commit | 0aa77f6c2954896b132f8b6f2e9f063c52800913 (patch) | |
tree | bc1feafea586e399c0fe1b04b2efa375312bb9ba /drivers/media/video | |
parent | 0c0d06cac63ee327ceaab4b5ffe2206574ab86bd (diff) |
[media] move the remaining USB drivers to drivers/media/usb
Move the 3 remaining usb drivers to their proper space.
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video')
-rw-r--r-- | drivers/media/video/Kconfig | 50 | ||||
-rw-r--r-- | drivers/media/video/Makefile | 8 | ||||
-rw-r--r-- | drivers/media/video/s2255drv.c | 2689 | ||||
-rw-r--r-- | drivers/media/video/stk-sensor.c | 595 | ||||
-rw-r--r-- | drivers/media/video/stk-webcam.c | 1380 | ||||
-rw-r--r-- | drivers/media/video/stk-webcam.h | 134 | ||||
-rw-r--r-- | drivers/media/video/zr364xx.c | 1643 |
7 files changed, 0 insertions, 6499 deletions
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig index 097b17ced172..f52799232029 100644 --- a/drivers/media/video/Kconfig +++ b/drivers/media/video/Kconfig | |||
@@ -606,56 +606,6 @@ config VIDEO_VIVI | |||
606 | In doubt, say N. | 606 | In doubt, say N. |
607 | 607 | ||
608 | # | 608 | # |
609 | # USB Multimedia device configuration | ||
610 | # | ||
611 | |||
612 | menuconfig V4L_USB_DRIVERS | ||
613 | bool "V4L USB devices" | ||
614 | depends on USB | ||
615 | default y | ||
616 | |||
617 | if V4L_USB_DRIVERS && MEDIA_CAMERA_SUPPORT | ||
618 | |||
619 | config USB_ZR364XX | ||
620 | tristate "USB ZR364XX Camera support" | ||
621 | depends on VIDEO_V4L2 | ||
622 | select VIDEOBUF_GEN | ||
623 | select VIDEOBUF_VMALLOC | ||
624 | ---help--- | ||
625 | Say Y here if you want to connect this type of camera to your | ||
626 | computer's USB port. | ||
627 | See <file:Documentation/video4linux/zr364xx.txt> for more info | ||
628 | and list of supported cameras. | ||
629 | |||
630 | To compile this driver as a module, choose M here: the | ||
631 | module will be called zr364xx. | ||
632 | |||
633 | config USB_STKWEBCAM | ||
634 | tristate "USB Syntek DC1125 Camera support" | ||
635 | depends on VIDEO_V4L2 && EXPERIMENTAL | ||
636 | ---help--- | ||
637 | Say Y here if you want to use this type of camera. | ||
638 | Supported devices are typically found in some Asus laptops, | ||
639 | with USB id 174f:a311 and 05e1:0501. Other Syntek cameras | ||
640 | may be supported by the stk11xx driver, from which this is | ||
641 | derived, see <http://sourceforge.net/projects/syntekdriver/> | ||
642 | |||
643 | To compile this driver as a module, choose M here: the | ||
644 | module will be called stkwebcam. | ||
645 | |||
646 | config USB_S2255 | ||
647 | tristate "USB Sensoray 2255 video capture device" | ||
648 | depends on VIDEO_V4L2 | ||
649 | select VIDEOBUF_VMALLOC | ||
650 | default n | ||
651 | help | ||
652 | Say Y here if you want support for the Sensoray 2255 USB device. | ||
653 | This driver can be compiled as a module, called s2255drv. | ||
654 | |||
655 | |||
656 | endif # V4L_USB_DRIVERS && MEDIA_CAMERA_SUPPORT | ||
657 | |||
658 | # | ||
659 | # PCI drivers configuration - No devices here are for webcams | 609 | # PCI drivers configuration - No devices here are for webcams |
660 | # | 610 | # |
661 | 611 | ||
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile index a22a2580ce30..4ad5bd9246bf 100644 --- a/drivers/media/video/Makefile +++ b/drivers/media/video/Makefile | |||
@@ -4,8 +4,6 @@ | |||
4 | 4 | ||
5 | msp3400-objs := msp3400-driver.o msp3400-kthreads.o | 5 | msp3400-objs := msp3400-driver.o msp3400-kthreads.o |
6 | 6 | ||
7 | stkwebcam-objs := stk-webcam.o stk-sensor.o | ||
8 | |||
9 | omap2cam-objs := omap24xxcam.o omap24xxcam-dma.o | 7 | omap2cam-objs := omap24xxcam.o omap24xxcam-dma.o |
10 | 8 | ||
11 | # Helper modules | 9 | # Helper modules |
@@ -119,12 +117,6 @@ obj-$(CONFIG_VIDEO_VIA_CAMERA) += via-camera.o | |||
119 | 117 | ||
120 | obj-$(CONFIG_VIDEO_OMAP3) += omap3isp/ | 118 | obj-$(CONFIG_VIDEO_OMAP3) += omap3isp/ |
121 | 119 | ||
122 | obj-$(CONFIG_USB_ZR364XX) += zr364xx.o | ||
123 | obj-$(CONFIG_USB_STKWEBCAM) += stkwebcam.o | ||
124 | |||
125 | |||
126 | obj-$(CONFIG_USB_S2255) += s2255drv.o | ||
127 | |||
128 | obj-$(CONFIG_VIDEO_IVTV) += ivtv/ | 120 | obj-$(CONFIG_VIDEO_IVTV) += ivtv/ |
129 | obj-$(CONFIG_VIDEO_CX18) += cx18/ | 121 | obj-$(CONFIG_VIDEO_CX18) += cx18/ |
130 | 122 | ||
diff --git a/drivers/media/video/s2255drv.c b/drivers/media/video/s2255drv.c deleted file mode 100644 index 6c7960cc7506..000000000000 --- a/drivers/media/video/s2255drv.c +++ /dev/null | |||
@@ -1,2689 +0,0 @@ | |||
1 | /* | ||
2 | * s2255drv.c - a driver for the Sensoray 2255 USB video capture device | ||
3 | * | ||
4 | * Copyright (C) 2007-2010 by Sensoray Company Inc. | ||
5 | * Dean Anderson | ||
6 | * | ||
7 | * Some video buffer code based on vivi driver: | ||
8 | * | ||
9 | * Sensoray 2255 device supports 4 simultaneous channels. | ||
10 | * The channels are not "crossbar" inputs, they are physically | ||
11 | * attached to separate video decoders. | ||
12 | * | ||
13 | * Because of USB2.0 bandwidth limitations. There is only a | ||
14 | * certain amount of data which may be transferred at one time. | ||
15 | * | ||
16 | * Example maximum bandwidth utilization: | ||
17 | * | ||
18 | * -full size, color mode YUYV or YUV422P: 2 channels at once | ||
19 | * -full or half size Grey scale: all 4 channels at once | ||
20 | * -half size, color mode YUYV or YUV422P: all 4 channels at once | ||
21 | * -full size, color mode YUYV or YUV422P 1/2 frame rate: all 4 channels | ||
22 | * at once. | ||
23 | * | ||
24 | * This program is free software; you can redistribute it and/or modify | ||
25 | * it under the terms of the GNU General Public License as published by | ||
26 | * the Free Software Foundation; either version 2 of the License, or | ||
27 | * (at your option) any later version. | ||
28 | * | ||
29 | * This program is distributed in the hope that it will be useful, | ||
30 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
31 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
32 | * GNU General Public License for more details. | ||
33 | * | ||
34 | * You should have received a copy of the GNU General Public License | ||
35 | * along with this program; if not, write to the Free Software | ||
36 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
37 | */ | ||
38 | |||
39 | #include <linux/module.h> | ||
40 | #include <linux/firmware.h> | ||
41 | #include <linux/kernel.h> | ||
42 | #include <linux/mutex.h> | ||
43 | #include <linux/slab.h> | ||
44 | #include <linux/videodev2.h> | ||
45 | #include <linux/mm.h> | ||
46 | #include <media/videobuf-vmalloc.h> | ||
47 | #include <media/v4l2-common.h> | ||
48 | #include <media/v4l2-device.h> | ||
49 | #include <media/v4l2-ioctl.h> | ||
50 | #include <linux/vmalloc.h> | ||
51 | #include <linux/usb.h> | ||
52 | |||
53 | #define S2255_VERSION "1.22.1" | ||
54 | #define FIRMWARE_FILE_NAME "f2255usb.bin" | ||
55 | |||
56 | /* default JPEG quality */ | ||
57 | #define S2255_DEF_JPEG_QUAL 50 | ||
58 | /* vendor request in */ | ||
59 | #define S2255_VR_IN 0 | ||
60 | /* vendor request out */ | ||
61 | #define S2255_VR_OUT 1 | ||
62 | /* firmware query */ | ||
63 | #define S2255_VR_FW 0x30 | ||
64 | /* USB endpoint number for configuring the device */ | ||
65 | #define S2255_CONFIG_EP 2 | ||
66 | /* maximum time for DSP to start responding after last FW word loaded(ms) */ | ||
67 | #define S2255_DSP_BOOTTIME 800 | ||
68 | /* maximum time to wait for firmware to load (ms) */ | ||
69 | #define S2255_LOAD_TIMEOUT (5000 + S2255_DSP_BOOTTIME) | ||
70 | #define S2255_DEF_BUFS 16 | ||
71 | #define S2255_SETMODE_TIMEOUT 500 | ||
72 | #define S2255_VIDSTATUS_TIMEOUT 350 | ||
73 | #define S2255_MARKER_FRAME cpu_to_le32(0x2255DA4AL) | ||
74 | #define S2255_MARKER_RESPONSE cpu_to_le32(0x2255ACACL) | ||
75 | #define S2255_RESPONSE_SETMODE cpu_to_le32(0x01) | ||
76 | #define S2255_RESPONSE_FW cpu_to_le32(0x10) | ||
77 | #define S2255_RESPONSE_STATUS cpu_to_le32(0x20) | ||
78 | #define S2255_USB_XFER_SIZE (16 * 1024) | ||
79 | #define MAX_CHANNELS 4 | ||
80 | #define SYS_FRAMES 4 | ||
81 | /* maximum size is PAL full size plus room for the marker header(s) */ | ||
82 | #define SYS_FRAMES_MAXSIZE (720*288*2*2 + 4096) | ||
83 | #define DEF_USB_BLOCK S2255_USB_XFER_SIZE | ||
84 | #define LINE_SZ_4CIFS_NTSC 640 | ||
85 | #define LINE_SZ_2CIFS_NTSC 640 | ||
86 | #define LINE_SZ_1CIFS_NTSC 320 | ||
87 | #define LINE_SZ_4CIFS_PAL 704 | ||
88 | #define LINE_SZ_2CIFS_PAL 704 | ||
89 | #define LINE_SZ_1CIFS_PAL 352 | ||
90 | #define NUM_LINES_4CIFS_NTSC 240 | ||
91 | #define NUM_LINES_2CIFS_NTSC 240 | ||
92 | #define NUM_LINES_1CIFS_NTSC 240 | ||
93 | #define NUM_LINES_4CIFS_PAL 288 | ||
94 | #define NUM_LINES_2CIFS_PAL 288 | ||
95 | #define NUM_LINES_1CIFS_PAL 288 | ||
96 | #define LINE_SZ_DEF 640 | ||
97 | #define NUM_LINES_DEF 240 | ||
98 | |||
99 | |||
100 | /* predefined settings */ | ||
101 | #define FORMAT_NTSC 1 | ||
102 | #define FORMAT_PAL 2 | ||
103 | |||
104 | #define SCALE_4CIFS 1 /* 640x480(NTSC) or 704x576(PAL) */ | ||
105 | #define SCALE_2CIFS 2 /* 640x240(NTSC) or 704x288(PAL) */ | ||
106 | #define SCALE_1CIFS 3 /* 320x240(NTSC) or 352x288(PAL) */ | ||
107 | /* SCALE_4CIFSI is the 2 fields interpolated into one */ | ||
108 | #define SCALE_4CIFSI 4 /* 640x480(NTSC) or 704x576(PAL) high quality */ | ||
109 | |||
110 | #define COLOR_YUVPL 1 /* YUV planar */ | ||
111 | #define COLOR_YUVPK 2 /* YUV packed */ | ||
112 | #define COLOR_Y8 4 /* monochrome */ | ||
113 | #define COLOR_JPG 5 /* JPEG */ | ||
114 | |||
115 | #define MASK_COLOR 0x000000ff | ||
116 | #define MASK_JPG_QUALITY 0x0000ff00 | ||
117 | #define MASK_INPUT_TYPE 0x000f0000 | ||
118 | /* frame decimation. */ | ||
119 | #define FDEC_1 1 /* capture every frame. default */ | ||
120 | #define FDEC_2 2 /* capture every 2nd frame */ | ||
121 | #define FDEC_3 3 /* capture every 3rd frame */ | ||
122 | #define FDEC_5 5 /* capture every 5th frame */ | ||
123 | |||
124 | /*------------------------------------------------------- | ||
125 | * Default mode parameters. | ||
126 | *-------------------------------------------------------*/ | ||
127 | #define DEF_SCALE SCALE_4CIFS | ||
128 | #define DEF_COLOR COLOR_YUVPL | ||
129 | #define DEF_FDEC FDEC_1 | ||
130 | #define DEF_BRIGHT 0 | ||
131 | #define DEF_CONTRAST 0x5c | ||
132 | #define DEF_SATURATION 0x80 | ||
133 | #define DEF_HUE 0 | ||
134 | |||
135 | /* usb config commands */ | ||
136 | #define IN_DATA_TOKEN cpu_to_le32(0x2255c0de) | ||
137 | #define CMD_2255 0xc2255000 | ||
138 | #define CMD_SET_MODE cpu_to_le32((CMD_2255 | 0x10)) | ||
139 | #define CMD_START cpu_to_le32((CMD_2255 | 0x20)) | ||
140 | #define CMD_STOP cpu_to_le32((CMD_2255 | 0x30)) | ||
141 | #define CMD_STATUS cpu_to_le32((CMD_2255 | 0x40)) | ||
142 | |||
143 | struct s2255_mode { | ||
144 | u32 format; /* input video format (NTSC, PAL) */ | ||
145 | u32 scale; /* output video scale */ | ||
146 | u32 color; /* output video color format */ | ||
147 | u32 fdec; /* frame decimation */ | ||
148 | u32 bright; /* brightness */ | ||
149 | u32 contrast; /* contrast */ | ||
150 | u32 saturation; /* saturation */ | ||
151 | u32 hue; /* hue (NTSC only)*/ | ||
152 | u32 single; /* capture 1 frame at a time (!=0), continuously (==0)*/ | ||
153 | u32 usb_block; /* block size. should be 4096 of DEF_USB_BLOCK */ | ||
154 | u32 restart; /* if DSP requires restart */ | ||
155 | }; | ||
156 | |||
157 | |||
158 | #define S2255_READ_IDLE 0 | ||
159 | #define S2255_READ_FRAME 1 | ||
160 | |||
161 | /* frame structure */ | ||
162 | struct s2255_framei { | ||
163 | unsigned long size; | ||
164 | unsigned long ulState; /* ulState:S2255_READ_IDLE, S2255_READ_FRAME*/ | ||
165 | void *lpvbits; /* image data */ | ||
166 | unsigned long cur_size; /* current data copied to it */ | ||
167 | }; | ||
168 | |||
169 | /* image buffer structure */ | ||
170 | struct s2255_bufferi { | ||
171 | unsigned long dwFrames; /* number of frames in buffer */ | ||
172 | struct s2255_framei frame[SYS_FRAMES]; /* array of FRAME structures */ | ||
173 | }; | ||
174 | |||
175 | #define DEF_MODEI_NTSC_CONT {FORMAT_NTSC, DEF_SCALE, DEF_COLOR, \ | ||
176 | DEF_FDEC, DEF_BRIGHT, DEF_CONTRAST, DEF_SATURATION, \ | ||
177 | DEF_HUE, 0, DEF_USB_BLOCK, 0} | ||
178 | |||
179 | struct s2255_dmaqueue { | ||
180 | struct list_head active; | ||
181 | struct s2255_dev *dev; | ||
182 | }; | ||
183 | |||
184 | /* for firmware loading, fw_state */ | ||
185 | #define S2255_FW_NOTLOADED 0 | ||
186 | #define S2255_FW_LOADED_DSPWAIT 1 | ||
187 | #define S2255_FW_SUCCESS 2 | ||
188 | #define S2255_FW_FAILED 3 | ||
189 | #define S2255_FW_DISCONNECTING 4 | ||
190 | #define S2255_FW_MARKER cpu_to_le32(0x22552f2f) | ||
191 | /* 2255 read states */ | ||
192 | #define S2255_READ_IDLE 0 | ||
193 | #define S2255_READ_FRAME 1 | ||
194 | struct s2255_fw { | ||
195 | int fw_loaded; | ||
196 | int fw_size; | ||
197 | struct urb *fw_urb; | ||
198 | atomic_t fw_state; | ||
199 | void *pfw_data; | ||
200 | wait_queue_head_t wait_fw; | ||
201 | const struct firmware *fw; | ||
202 | }; | ||
203 | |||
204 | struct s2255_pipeinfo { | ||
205 | u32 max_transfer_size; | ||
206 | u32 cur_transfer_size; | ||
207 | u8 *transfer_buffer; | ||
208 | u32 state; | ||
209 | void *stream_urb; | ||
210 | void *dev; /* back pointer to s2255_dev struct*/ | ||
211 | u32 err_count; | ||
212 | u32 idx; | ||
213 | }; | ||
214 | |||
215 | struct s2255_fmt; /*forward declaration */ | ||
216 | struct s2255_dev; | ||
217 | |||
218 | struct s2255_channel { | ||
219 | struct video_device vdev; | ||
220 | int resources; | ||
221 | struct s2255_dmaqueue vidq; | ||
222 | struct s2255_bufferi buffer; | ||
223 | struct s2255_mode mode; | ||
224 | /* jpeg compression */ | ||
225 | struct v4l2_jpegcompression jc; | ||
226 | /* capture parameters (for high quality mode full size) */ | ||
227 | struct v4l2_captureparm cap_parm; | ||
228 | int cur_frame; | ||
229 | int last_frame; | ||
230 | |||
231 | int b_acquire; | ||
232 | /* allocated image size */ | ||
233 | unsigned long req_image_size; | ||
234 | /* received packet size */ | ||
235 | unsigned long pkt_size; | ||
236 | int bad_payload; | ||
237 | unsigned long frame_count; | ||
238 | /* if JPEG image */ | ||
239 | int jpg_size; | ||
240 | /* if channel configured to default state */ | ||
241 | int configured; | ||
242 | wait_queue_head_t wait_setmode; | ||
243 | int setmode_ready; | ||
244 | /* video status items */ | ||
245 | int vidstatus; | ||
246 | wait_queue_head_t wait_vidstatus; | ||
247 | int vidstatus_ready; | ||
248 | unsigned int width; | ||
249 | unsigned int height; | ||
250 | const struct s2255_fmt *fmt; | ||
251 | int idx; /* channel number on device, 0-3 */ | ||
252 | }; | ||
253 | |||
254 | |||
255 | struct s2255_dev { | ||
256 | struct s2255_channel channel[MAX_CHANNELS]; | ||
257 | struct v4l2_device v4l2_dev; | ||
258 | atomic_t num_channels; | ||
259 | int frames; | ||
260 | struct mutex lock; /* channels[].vdev.lock */ | ||
261 | struct usb_device *udev; | ||
262 | struct usb_interface *interface; | ||
263 | u8 read_endpoint; | ||
264 | struct timer_list timer; | ||
265 | struct s2255_fw *fw_data; | ||
266 | struct s2255_pipeinfo pipe; | ||
267 | u32 cc; /* current channel */ | ||
268 | int frame_ready; | ||
269 | int chn_ready; | ||
270 | spinlock_t slock; | ||
271 | /* dsp firmware version (f2255usb.bin) */ | ||
272 | int dsp_fw_ver; | ||
273 | u16 pid; /* product id */ | ||
274 | }; | ||
275 | |||
276 | static inline struct s2255_dev *to_s2255_dev(struct v4l2_device *v4l2_dev) | ||
277 | { | ||
278 | return container_of(v4l2_dev, struct s2255_dev, v4l2_dev); | ||
279 | } | ||
280 | |||
281 | struct s2255_fmt { | ||
282 | char *name; | ||
283 | u32 fourcc; | ||
284 | int depth; | ||
285 | }; | ||
286 | |||
287 | /* buffer for one video frame */ | ||
288 | struct s2255_buffer { | ||
289 | /* common v4l buffer stuff -- must be first */ | ||
290 | struct videobuf_buffer vb; | ||
291 | const struct s2255_fmt *fmt; | ||
292 | }; | ||
293 | |||
294 | struct s2255_fh { | ||
295 | struct s2255_dev *dev; | ||
296 | struct videobuf_queue vb_vidq; | ||
297 | enum v4l2_buf_type type; | ||
298 | struct s2255_channel *channel; | ||
299 | int resources; | ||
300 | }; | ||
301 | |||
302 | /* current cypress EEPROM firmware version */ | ||
303 | #define S2255_CUR_USB_FWVER ((3 << 8) | 12) | ||
304 | /* current DSP FW version */ | ||
305 | #define S2255_CUR_DSP_FWVER 10104 | ||
306 | /* Need DSP version 5+ for video status feature */ | ||
307 | #define S2255_MIN_DSP_STATUS 5 | ||
308 | #define S2255_MIN_DSP_COLORFILTER 8 | ||
309 | #define S2255_NORMS (V4L2_STD_PAL | V4L2_STD_NTSC) | ||
310 | |||
311 | /* private V4L2 controls */ | ||
312 | |||
313 | /* | ||
314 | * The following chart displays how COLORFILTER should be set | ||
315 | * ========================================================= | ||
316 | * = fourcc = COLORFILTER = | ||
317 | * = =============================== | ||
318 | * = = 0 = 1 = | ||
319 | * ========================================================= | ||
320 | * = V4L2_PIX_FMT_GREY(Y8) = monochrome from = monochrome= | ||
321 | * = = s-video or = composite = | ||
322 | * = = B/W camera = input = | ||
323 | * ========================================================= | ||
324 | * = other = color, svideo = color, = | ||
325 | * = = = composite = | ||
326 | * ========================================================= | ||
327 | * | ||
328 | * Notes: | ||
329 | * channels 0-3 on 2255 are composite | ||
330 | * channels 0-1 on 2257 are composite, 2-3 are s-video | ||
331 | * If COLORFILTER is 0 with a composite color camera connected, | ||
332 | * the output will appear monochrome but hatching | ||
333 | * will occur. | ||
334 | * COLORFILTER is different from "color killer" and "color effects" | ||
335 | * for reasons above. | ||
336 | */ | ||
337 | #define S2255_V4L2_YC_ON 1 | ||
338 | #define S2255_V4L2_YC_OFF 0 | ||
339 | #define V4L2_CID_PRIVATE_COLORFILTER (V4L2_CID_PRIVATE_BASE + 0) | ||
340 | |||
341 | /* frame prefix size (sent once every frame) */ | ||
342 | #define PREFIX_SIZE 512 | ||
343 | |||
344 | /* Channels on box are in reverse order */ | ||
345 | static unsigned long G_chnmap[MAX_CHANNELS] = {3, 2, 1, 0}; | ||
346 | |||
347 | static int debug; | ||
348 | static int *s2255_debug = &debug; | ||
349 | |||
350 | static int s2255_start_readpipe(struct s2255_dev *dev); | ||
351 | static void s2255_stop_readpipe(struct s2255_dev *dev); | ||
352 | static int s2255_start_acquire(struct s2255_channel *channel); | ||
353 | static int s2255_stop_acquire(struct s2255_channel *channel); | ||
354 | static void s2255_fillbuff(struct s2255_channel *chn, struct s2255_buffer *buf, | ||
355 | int jpgsize); | ||
356 | static int s2255_set_mode(struct s2255_channel *chan, struct s2255_mode *mode); | ||
357 | static int s2255_board_shutdown(struct s2255_dev *dev); | ||
358 | static void s2255_fwload_start(struct s2255_dev *dev, int reset); | ||
359 | static void s2255_destroy(struct s2255_dev *dev); | ||
360 | static long s2255_vendor_req(struct s2255_dev *dev, unsigned char req, | ||
361 | u16 index, u16 value, void *buf, | ||
362 | s32 buf_len, int bOut); | ||
363 | |||
364 | /* dev_err macro with driver name */ | ||
365 | #define S2255_DRIVER_NAME "s2255" | ||
366 | #define s2255_dev_err(dev, fmt, arg...) \ | ||
367 | dev_err(dev, S2255_DRIVER_NAME " - " fmt, ##arg) | ||
368 | |||
369 | #define dprintk(level, fmt, arg...) \ | ||
370 | do { \ | ||
371 | if (*s2255_debug >= (level)) { \ | ||
372 | printk(KERN_DEBUG S2255_DRIVER_NAME \ | ||
373 | ": " fmt, ##arg); \ | ||
374 | } \ | ||
375 | } while (0) | ||
376 | |||
377 | static struct usb_driver s2255_driver; | ||
378 | |||
379 | /* Declare static vars that will be used as parameters */ | ||
380 | static unsigned int vid_limit = 16; /* Video memory limit, in Mb */ | ||
381 | |||
382 | /* start video number */ | ||
383 | static int video_nr = -1; /* /dev/videoN, -1 for autodetect */ | ||
384 | |||
385 | /* Enable jpeg capture. */ | ||
386 | static int jpeg_enable = 1; | ||
387 | |||
388 | module_param(debug, int, 0644); | ||
389 | MODULE_PARM_DESC(debug, "Debug level(0-100) default 0"); | ||
390 | module_param(vid_limit, int, 0644); | ||
391 | MODULE_PARM_DESC(vid_limit, "video memory limit(Mb)"); | ||
392 | module_param(video_nr, int, 0644); | ||
393 | MODULE_PARM_DESC(video_nr, "start video minor(-1 default autodetect)"); | ||
394 | module_param(jpeg_enable, int, 0644); | ||
395 | MODULE_PARM_DESC(jpeg_enable, "Jpeg enable(1-on 0-off) default 1"); | ||
396 | |||
397 | /* USB device table */ | ||
398 | #define USB_SENSORAY_VID 0x1943 | ||
399 | static struct usb_device_id s2255_table[] = { | ||
400 | {USB_DEVICE(USB_SENSORAY_VID, 0x2255)}, | ||
401 | {USB_DEVICE(USB_SENSORAY_VID, 0x2257)}, /*same family as 2255*/ | ||
402 | { } /* Terminating entry */ | ||
403 | }; | ||
404 | MODULE_DEVICE_TABLE(usb, s2255_table); | ||
405 | |||
406 | #define BUFFER_TIMEOUT msecs_to_jiffies(400) | ||
407 | |||
408 | /* image formats. */ | ||
409 | /* JPEG formats must be defined last to support jpeg_enable parameter */ | ||
410 | static const struct s2255_fmt formats[] = { | ||
411 | { | ||
412 | .name = "4:2:2, planar, YUV422P", | ||
413 | .fourcc = V4L2_PIX_FMT_YUV422P, | ||
414 | .depth = 16 | ||
415 | |||
416 | }, { | ||
417 | .name = "4:2:2, packed, YUYV", | ||
418 | .fourcc = V4L2_PIX_FMT_YUYV, | ||
419 | .depth = 16 | ||
420 | |||
421 | }, { | ||
422 | .name = "4:2:2, packed, UYVY", | ||
423 | .fourcc = V4L2_PIX_FMT_UYVY, | ||
424 | .depth = 16 | ||
425 | }, { | ||
426 | .name = "8bpp GREY", | ||
427 | .fourcc = V4L2_PIX_FMT_GREY, | ||
428 | .depth = 8 | ||
429 | }, { | ||
430 | .name = "JPG", | ||
431 | .fourcc = V4L2_PIX_FMT_JPEG, | ||
432 | .depth = 24 | ||
433 | }, { | ||
434 | .name = "MJPG", | ||
435 | .fourcc = V4L2_PIX_FMT_MJPEG, | ||
436 | .depth = 24 | ||
437 | } | ||
438 | }; | ||
439 | |||
440 | static int norm_maxw(struct video_device *vdev) | ||
441 | { | ||
442 | return (vdev->current_norm & V4L2_STD_NTSC) ? | ||
443 | LINE_SZ_4CIFS_NTSC : LINE_SZ_4CIFS_PAL; | ||
444 | } | ||
445 | |||
446 | static int norm_maxh(struct video_device *vdev) | ||
447 | { | ||
448 | return (vdev->current_norm & V4L2_STD_NTSC) ? | ||
449 | (NUM_LINES_1CIFS_NTSC * 2) : (NUM_LINES_1CIFS_PAL * 2); | ||
450 | } | ||
451 | |||
452 | static int norm_minw(struct video_device *vdev) | ||
453 | { | ||
454 | return (vdev->current_norm & V4L2_STD_NTSC) ? | ||
455 | LINE_SZ_1CIFS_NTSC : LINE_SZ_1CIFS_PAL; | ||
456 | } | ||
457 | |||
458 | static int norm_minh(struct video_device *vdev) | ||
459 | { | ||
460 | return (vdev->current_norm & V4L2_STD_NTSC) ? | ||
461 | (NUM_LINES_1CIFS_NTSC) : (NUM_LINES_1CIFS_PAL); | ||
462 | } | ||
463 | |||
464 | |||
465 | /* | ||
466 | * TODO: fixme: move YUV reordering to hardware | ||
467 | * converts 2255 planar format to yuyv or uyvy | ||
468 | */ | ||
469 | static void planar422p_to_yuv_packed(const unsigned char *in, | ||
470 | unsigned char *out, | ||
471 | int width, int height, | ||
472 | int fmt) | ||
473 | { | ||
474 | unsigned char *pY; | ||
475 | unsigned char *pCb; | ||
476 | unsigned char *pCr; | ||
477 | unsigned long size = height * width; | ||
478 | unsigned int i; | ||
479 | pY = (unsigned char *)in; | ||
480 | pCr = (unsigned char *)in + height * width; | ||
481 | pCb = (unsigned char *)in + height * width + (height * width / 2); | ||
482 | for (i = 0; i < size * 2; i += 4) { | ||
483 | out[i] = (fmt == V4L2_PIX_FMT_YUYV) ? *pY++ : *pCr++; | ||
484 | out[i + 1] = (fmt == V4L2_PIX_FMT_YUYV) ? *pCr++ : *pY++; | ||
485 | out[i + 2] = (fmt == V4L2_PIX_FMT_YUYV) ? *pY++ : *pCb++; | ||
486 | out[i + 3] = (fmt == V4L2_PIX_FMT_YUYV) ? *pCb++ : *pY++; | ||
487 | } | ||
488 | return; | ||
489 | } | ||
490 | |||
491 | static void s2255_reset_dsppower(struct s2255_dev *dev) | ||
492 | { | ||
493 | s2255_vendor_req(dev, 0x40, 0x0000, 0x0001, NULL, 0, 1); | ||
494 | msleep(10); | ||
495 | s2255_vendor_req(dev, 0x50, 0x0000, 0x0000, NULL, 0, 1); | ||
496 | msleep(600); | ||
497 | s2255_vendor_req(dev, 0x10, 0x0000, 0x0000, NULL, 0, 1); | ||
498 | return; | ||
499 | } | ||
500 | |||
501 | /* kickstarts the firmware loading. from probe | ||
502 | */ | ||
503 | static void s2255_timer(unsigned long user_data) | ||
504 | { | ||
505 | struct s2255_fw *data = (struct s2255_fw *)user_data; | ||
506 | dprintk(100, "%s\n", __func__); | ||
507 | if (usb_submit_urb(data->fw_urb, GFP_ATOMIC) < 0) { | ||
508 | printk(KERN_ERR "s2255: can't submit urb\n"); | ||
509 | atomic_set(&data->fw_state, S2255_FW_FAILED); | ||
510 | /* wake up anything waiting for the firmware */ | ||
511 | wake_up(&data->wait_fw); | ||
512 | return; | ||
513 | } | ||
514 | } | ||
515 | |||
516 | |||
517 | /* this loads the firmware asynchronously. | ||
518 | Originally this was done synchroously in probe. | ||
519 | But it is better to load it asynchronously here than block | ||
520 | inside the probe function. Blocking inside probe affects boot time. | ||
521 | FW loading is triggered by the timer in the probe function | ||
522 | */ | ||
523 | static void s2255_fwchunk_complete(struct urb *urb) | ||
524 | { | ||
525 | struct s2255_fw *data = urb->context; | ||
526 | struct usb_device *udev = urb->dev; | ||
527 | int len; | ||
528 | dprintk(100, "%s: udev %p urb %p", __func__, udev, urb); | ||
529 | if (urb->status) { | ||
530 | dev_err(&udev->dev, "URB failed with status %d\n", urb->status); | ||
531 | atomic_set(&data->fw_state, S2255_FW_FAILED); | ||
532 | /* wake up anything waiting for the firmware */ | ||
533 | wake_up(&data->wait_fw); | ||
534 | return; | ||
535 | } | ||
536 | if (data->fw_urb == NULL) { | ||
537 | s2255_dev_err(&udev->dev, "disconnected\n"); | ||
538 | atomic_set(&data->fw_state, S2255_FW_FAILED); | ||
539 | /* wake up anything waiting for the firmware */ | ||
540 | wake_up(&data->wait_fw); | ||
541 | return; | ||
542 | } | ||
543 | #define CHUNK_SIZE 512 | ||
544 | /* all USB transfers must be done with continuous kernel memory. | ||
545 | can't allocate more than 128k in current linux kernel, so | ||
546 | upload the firmware in chunks | ||
547 | */ | ||
548 | if (data->fw_loaded < data->fw_size) { | ||
549 | len = (data->fw_loaded + CHUNK_SIZE) > data->fw_size ? | ||
550 | data->fw_size % CHUNK_SIZE : CHUNK_SIZE; | ||
551 | |||
552 | if (len < CHUNK_SIZE) | ||
553 | memset(data->pfw_data, 0, CHUNK_SIZE); | ||
554 | |||
555 | dprintk(100, "completed len %d, loaded %d \n", len, | ||
556 | data->fw_loaded); | ||
557 | |||
558 | memcpy(data->pfw_data, | ||
559 | (char *) data->fw->data + data->fw_loaded, len); | ||
560 | |||
561 | usb_fill_bulk_urb(data->fw_urb, udev, usb_sndbulkpipe(udev, 2), | ||
562 | data->pfw_data, CHUNK_SIZE, | ||
563 | s2255_fwchunk_complete, data); | ||
564 | if (usb_submit_urb(data->fw_urb, GFP_ATOMIC) < 0) { | ||
565 | dev_err(&udev->dev, "failed submit URB\n"); | ||
566 | atomic_set(&data->fw_state, S2255_FW_FAILED); | ||
567 | /* wake up anything waiting for the firmware */ | ||
568 | wake_up(&data->wait_fw); | ||
569 | return; | ||
570 | } | ||
571 | data->fw_loaded += len; | ||
572 | } else { | ||
573 | atomic_set(&data->fw_state, S2255_FW_LOADED_DSPWAIT); | ||
574 | dprintk(100, "%s: firmware upload complete\n", __func__); | ||
575 | } | ||
576 | return; | ||
577 | |||
578 | } | ||
579 | |||
580 | static int s2255_got_frame(struct s2255_channel *channel, int jpgsize) | ||
581 | { | ||
582 | struct s2255_dmaqueue *dma_q = &channel->vidq; | ||
583 | struct s2255_buffer *buf; | ||
584 | struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev); | ||
585 | unsigned long flags = 0; | ||
586 | int rc = 0; | ||
587 | spin_lock_irqsave(&dev->slock, flags); | ||
588 | if (list_empty(&dma_q->active)) { | ||
589 | dprintk(1, "No active queue to serve\n"); | ||
590 | rc = -1; | ||
591 | goto unlock; | ||
592 | } | ||
593 | buf = list_entry(dma_q->active.next, | ||
594 | struct s2255_buffer, vb.queue); | ||
595 | list_del(&buf->vb.queue); | ||
596 | do_gettimeofday(&buf->vb.ts); | ||
597 | s2255_fillbuff(channel, buf, jpgsize); | ||
598 | wake_up(&buf->vb.done); | ||
599 | dprintk(2, "%s: [buf/i] [%p/%d]\n", __func__, buf, buf->vb.i); | ||
600 | unlock: | ||
601 | spin_unlock_irqrestore(&dev->slock, flags); | ||
602 | return rc; | ||
603 | } | ||
604 | |||
605 | static const struct s2255_fmt *format_by_fourcc(int fourcc) | ||
606 | { | ||
607 | unsigned int i; | ||
608 | for (i = 0; i < ARRAY_SIZE(formats); i++) { | ||
609 | if (-1 == formats[i].fourcc) | ||
610 | continue; | ||
611 | if (!jpeg_enable && ((formats[i].fourcc == V4L2_PIX_FMT_JPEG) || | ||
612 | (formats[i].fourcc == V4L2_PIX_FMT_MJPEG))) | ||
613 | continue; | ||
614 | if (formats[i].fourcc == fourcc) | ||
615 | return formats + i; | ||
616 | } | ||
617 | return NULL; | ||
618 | } | ||
619 | |||
620 | /* video buffer vmalloc implementation based partly on VIVI driver which is | ||
621 | * Copyright (c) 2006 by | ||
622 | * Mauro Carvalho Chehab <mchehab--a.t--infradead.org> | ||
623 | * Ted Walther <ted--a.t--enumera.com> | ||
624 | * John Sokol <sokol--a.t--videotechnology.com> | ||
625 | * http://v4l.videotechnology.com/ | ||
626 | * | ||
627 | */ | ||
628 | static void s2255_fillbuff(struct s2255_channel *channel, | ||
629 | struct s2255_buffer *buf, int jpgsize) | ||
630 | { | ||
631 | int pos = 0; | ||
632 | struct timeval ts; | ||
633 | const char *tmpbuf; | ||
634 | char *vbuf = videobuf_to_vmalloc(&buf->vb); | ||
635 | unsigned long last_frame; | ||
636 | |||
637 | if (!vbuf) | ||
638 | return; | ||
639 | last_frame = channel->last_frame; | ||
640 | if (last_frame != -1) { | ||
641 | tmpbuf = | ||
642 | (const char *)channel->buffer.frame[last_frame].lpvbits; | ||
643 | switch (buf->fmt->fourcc) { | ||
644 | case V4L2_PIX_FMT_YUYV: | ||
645 | case V4L2_PIX_FMT_UYVY: | ||
646 | planar422p_to_yuv_packed((const unsigned char *)tmpbuf, | ||
647 | vbuf, buf->vb.width, | ||
648 | buf->vb.height, | ||
649 | buf->fmt->fourcc); | ||
650 | break; | ||
651 | case V4L2_PIX_FMT_GREY: | ||
652 | memcpy(vbuf, tmpbuf, buf->vb.width * buf->vb.height); | ||
653 | break; | ||
654 | case V4L2_PIX_FMT_JPEG: | ||
655 | case V4L2_PIX_FMT_MJPEG: | ||
656 | buf->vb.size = jpgsize; | ||
657 | memcpy(vbuf, tmpbuf, buf->vb.size); | ||
658 | break; | ||
659 | case V4L2_PIX_FMT_YUV422P: | ||
660 | memcpy(vbuf, tmpbuf, | ||
661 | buf->vb.width * buf->vb.height * 2); | ||
662 | break; | ||
663 | default: | ||
664 | printk(KERN_DEBUG "s2255: unknown format?\n"); | ||
665 | } | ||
666 | channel->last_frame = -1; | ||
667 | } else { | ||
668 | printk(KERN_ERR "s2255: =======no frame\n"); | ||
669 | return; | ||
670 | |||
671 | } | ||
672 | dprintk(2, "s2255fill at : Buffer 0x%08lx size= %d\n", | ||
673 | (unsigned long)vbuf, pos); | ||
674 | /* tell v4l buffer was filled */ | ||
675 | |||
676 | buf->vb.field_count = channel->frame_count * 2; | ||
677 | do_gettimeofday(&ts); | ||
678 | buf->vb.ts = ts; | ||
679 | buf->vb.state = VIDEOBUF_DONE; | ||
680 | } | ||
681 | |||
682 | |||
683 | /* ------------------------------------------------------------------ | ||
684 | Videobuf operations | ||
685 | ------------------------------------------------------------------*/ | ||
686 | |||
687 | static int buffer_setup(struct videobuf_queue *vq, unsigned int *count, | ||
688 | unsigned int *size) | ||
689 | { | ||
690 | struct s2255_fh *fh = vq->priv_data; | ||
691 | struct s2255_channel *channel = fh->channel; | ||
692 | *size = channel->width * channel->height * (channel->fmt->depth >> 3); | ||
693 | |||
694 | if (0 == *count) | ||
695 | *count = S2255_DEF_BUFS; | ||
696 | |||
697 | if (*size * *count > vid_limit * 1024 * 1024) | ||
698 | *count = (vid_limit * 1024 * 1024) / *size; | ||
699 | |||
700 | return 0; | ||
701 | } | ||
702 | |||
703 | static void free_buffer(struct videobuf_queue *vq, struct s2255_buffer *buf) | ||
704 | { | ||
705 | dprintk(4, "%s\n", __func__); | ||
706 | |||
707 | videobuf_vmalloc_free(&buf->vb); | ||
708 | buf->vb.state = VIDEOBUF_NEEDS_INIT; | ||
709 | } | ||
710 | |||
711 | static int buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb, | ||
712 | enum v4l2_field field) | ||
713 | { | ||
714 | struct s2255_fh *fh = vq->priv_data; | ||
715 | struct s2255_channel *channel = fh->channel; | ||
716 | struct s2255_buffer *buf = container_of(vb, struct s2255_buffer, vb); | ||
717 | int rc; | ||
718 | int w = channel->width; | ||
719 | int h = channel->height; | ||
720 | dprintk(4, "%s, field=%d\n", __func__, field); | ||
721 | if (channel->fmt == NULL) | ||
722 | return -EINVAL; | ||
723 | |||
724 | if ((w < norm_minw(&channel->vdev)) || | ||
725 | (w > norm_maxw(&channel->vdev)) || | ||
726 | (h < norm_minh(&channel->vdev)) || | ||
727 | (h > norm_maxh(&channel->vdev))) { | ||
728 | dprintk(4, "invalid buffer prepare\n"); | ||
729 | return -EINVAL; | ||
730 | } | ||
731 | buf->vb.size = w * h * (channel->fmt->depth >> 3); | ||
732 | if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size) { | ||
733 | dprintk(4, "invalid buffer prepare\n"); | ||
734 | return -EINVAL; | ||
735 | } | ||
736 | |||
737 | buf->fmt = channel->fmt; | ||
738 | buf->vb.width = w; | ||
739 | buf->vb.height = h; | ||
740 | buf->vb.field = field; | ||
741 | |||
742 | if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { | ||
743 | rc = videobuf_iolock(vq, &buf->vb, NULL); | ||
744 | if (rc < 0) | ||
745 | goto fail; | ||
746 | } | ||
747 | |||
748 | buf->vb.state = VIDEOBUF_PREPARED; | ||
749 | return 0; | ||
750 | fail: | ||
751 | free_buffer(vq, buf); | ||
752 | return rc; | ||
753 | } | ||
754 | |||
755 | static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb) | ||
756 | { | ||
757 | struct s2255_buffer *buf = container_of(vb, struct s2255_buffer, vb); | ||
758 | struct s2255_fh *fh = vq->priv_data; | ||
759 | struct s2255_channel *channel = fh->channel; | ||
760 | struct s2255_dmaqueue *vidq = &channel->vidq; | ||
761 | dprintk(1, "%s\n", __func__); | ||
762 | buf->vb.state = VIDEOBUF_QUEUED; | ||
763 | list_add_tail(&buf->vb.queue, &vidq->active); | ||
764 | } | ||
765 | |||
766 | static void buffer_release(struct videobuf_queue *vq, | ||
767 | struct videobuf_buffer *vb) | ||
768 | { | ||
769 | struct s2255_buffer *buf = container_of(vb, struct s2255_buffer, vb); | ||
770 | struct s2255_fh *fh = vq->priv_data; | ||
771 | dprintk(4, "%s %d\n", __func__, fh->channel->idx); | ||
772 | free_buffer(vq, buf); | ||
773 | } | ||
774 | |||
775 | static struct videobuf_queue_ops s2255_video_qops = { | ||
776 | .buf_setup = buffer_setup, | ||
777 | .buf_prepare = buffer_prepare, | ||
778 | .buf_queue = buffer_queue, | ||
779 | .buf_release = buffer_release, | ||
780 | }; | ||
781 | |||
782 | |||
783 | static int res_get(struct s2255_fh *fh) | ||
784 | { | ||
785 | struct s2255_channel *channel = fh->channel; | ||
786 | /* is it free? */ | ||
787 | if (channel->resources) | ||
788 | return 0; /* no, someone else uses it */ | ||
789 | /* it's free, grab it */ | ||
790 | channel->resources = 1; | ||
791 | fh->resources = 1; | ||
792 | dprintk(1, "s2255: res: get\n"); | ||
793 | return 1; | ||
794 | } | ||
795 | |||
796 | static int res_locked(struct s2255_fh *fh) | ||
797 | { | ||
798 | return fh->channel->resources; | ||
799 | } | ||
800 | |||
801 | static int res_check(struct s2255_fh *fh) | ||
802 | { | ||
803 | return fh->resources; | ||
804 | } | ||
805 | |||
806 | |||
807 | static void res_free(struct s2255_fh *fh) | ||
808 | { | ||
809 | struct s2255_channel *channel = fh->channel; | ||
810 | channel->resources = 0; | ||
811 | fh->resources = 0; | ||
812 | dprintk(1, "res: put\n"); | ||
813 | } | ||
814 | |||
815 | static int vidioc_querymenu(struct file *file, void *priv, | ||
816 | struct v4l2_querymenu *qmenu) | ||
817 | { | ||
818 | static const char *colorfilter[] = { | ||
819 | "Off", | ||
820 | "On", | ||
821 | NULL | ||
822 | }; | ||
823 | if (qmenu->id == V4L2_CID_PRIVATE_COLORFILTER) { | ||
824 | int i; | ||
825 | const char **menu_items = colorfilter; | ||
826 | for (i = 0; i < qmenu->index && menu_items[i]; i++) | ||
827 | ; /* do nothing (from v4l2-common.c) */ | ||
828 | if (menu_items[i] == NULL || menu_items[i][0] == '\0') | ||
829 | return -EINVAL; | ||
830 | strlcpy(qmenu->name, menu_items[qmenu->index], | ||
831 | sizeof(qmenu->name)); | ||
832 | return 0; | ||
833 | } | ||
834 | return v4l2_ctrl_query_menu(qmenu, NULL, NULL); | ||
835 | } | ||
836 | |||
837 | static int vidioc_querycap(struct file *file, void *priv, | ||
838 | struct v4l2_capability *cap) | ||
839 | { | ||
840 | struct s2255_fh *fh = file->private_data; | ||
841 | struct s2255_dev *dev = fh->dev; | ||
842 | strlcpy(cap->driver, "s2255", sizeof(cap->driver)); | ||
843 | strlcpy(cap->card, "s2255", sizeof(cap->card)); | ||
844 | usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info)); | ||
845 | cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; | ||
846 | return 0; | ||
847 | } | ||
848 | |||
849 | static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, | ||
850 | struct v4l2_fmtdesc *f) | ||
851 | { | ||
852 | int index = f->index; | ||
853 | |||
854 | if (index >= ARRAY_SIZE(formats)) | ||
855 | return -EINVAL; | ||
856 | if (!jpeg_enable && ((formats[index].fourcc == V4L2_PIX_FMT_JPEG) || | ||
857 | (formats[index].fourcc == V4L2_PIX_FMT_MJPEG))) | ||
858 | return -EINVAL; | ||
859 | dprintk(4, "name %s\n", formats[index].name); | ||
860 | strlcpy(f->description, formats[index].name, sizeof(f->description)); | ||
861 | f->pixelformat = formats[index].fourcc; | ||
862 | return 0; | ||
863 | } | ||
864 | |||
865 | static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, | ||
866 | struct v4l2_format *f) | ||
867 | { | ||
868 | struct s2255_fh *fh = priv; | ||
869 | struct s2255_channel *channel = fh->channel; | ||
870 | |||
871 | f->fmt.pix.width = channel->width; | ||
872 | f->fmt.pix.height = channel->height; | ||
873 | f->fmt.pix.field = fh->vb_vidq.field; | ||
874 | f->fmt.pix.pixelformat = channel->fmt->fourcc; | ||
875 | f->fmt.pix.bytesperline = f->fmt.pix.width * (channel->fmt->depth >> 3); | ||
876 | f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline; | ||
877 | return 0; | ||
878 | } | ||
879 | |||
880 | static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, | ||
881 | struct v4l2_format *f) | ||
882 | { | ||
883 | const struct s2255_fmt *fmt; | ||
884 | enum v4l2_field field; | ||
885 | int b_any_field = 0; | ||
886 | struct s2255_fh *fh = priv; | ||
887 | struct s2255_channel *channel = fh->channel; | ||
888 | int is_ntsc; | ||
889 | is_ntsc = | ||
890 | (channel->vdev.current_norm & V4L2_STD_NTSC) ? 1 : 0; | ||
891 | |||
892 | fmt = format_by_fourcc(f->fmt.pix.pixelformat); | ||
893 | |||
894 | if (fmt == NULL) | ||
895 | return -EINVAL; | ||
896 | |||
897 | field = f->fmt.pix.field; | ||
898 | if (field == V4L2_FIELD_ANY) | ||
899 | b_any_field = 1; | ||
900 | |||
901 | dprintk(50, "%s NTSC: %d suggested width: %d, height: %d\n", | ||
902 | __func__, is_ntsc, f->fmt.pix.width, f->fmt.pix.height); | ||
903 | if (is_ntsc) { | ||
904 | /* NTSC */ | ||
905 | if (f->fmt.pix.height >= NUM_LINES_1CIFS_NTSC * 2) { | ||
906 | f->fmt.pix.height = NUM_LINES_1CIFS_NTSC * 2; | ||
907 | if (b_any_field) { | ||
908 | field = V4L2_FIELD_SEQ_TB; | ||
909 | } else if (!((field == V4L2_FIELD_INTERLACED) || | ||
910 | (field == V4L2_FIELD_SEQ_TB) || | ||
911 | (field == V4L2_FIELD_INTERLACED_TB))) { | ||
912 | dprintk(1, "unsupported field setting\n"); | ||
913 | return -EINVAL; | ||
914 | } | ||
915 | } else { | ||
916 | f->fmt.pix.height = NUM_LINES_1CIFS_NTSC; | ||
917 | if (b_any_field) { | ||
918 | field = V4L2_FIELD_TOP; | ||
919 | } else if (!((field == V4L2_FIELD_TOP) || | ||
920 | (field == V4L2_FIELD_BOTTOM))) { | ||
921 | dprintk(1, "unsupported field setting\n"); | ||
922 | return -EINVAL; | ||
923 | } | ||
924 | |||
925 | } | ||
926 | if (f->fmt.pix.width >= LINE_SZ_4CIFS_NTSC) | ||
927 | f->fmt.pix.width = LINE_SZ_4CIFS_NTSC; | ||
928 | else if (f->fmt.pix.width >= LINE_SZ_2CIFS_NTSC) | ||
929 | f->fmt.pix.width = LINE_SZ_2CIFS_NTSC; | ||
930 | else if (f->fmt.pix.width >= LINE_SZ_1CIFS_NTSC) | ||
931 | f->fmt.pix.width = LINE_SZ_1CIFS_NTSC; | ||
932 | else | ||
933 | f->fmt.pix.width = LINE_SZ_1CIFS_NTSC; | ||
934 | } else { | ||
935 | /* PAL */ | ||
936 | if (f->fmt.pix.height >= NUM_LINES_1CIFS_PAL * 2) { | ||
937 | f->fmt.pix.height = NUM_LINES_1CIFS_PAL * 2; | ||
938 | if (b_any_field) { | ||
939 | field = V4L2_FIELD_SEQ_TB; | ||
940 | } else if (!((field == V4L2_FIELD_INTERLACED) || | ||
941 | (field == V4L2_FIELD_SEQ_TB) || | ||
942 | (field == V4L2_FIELD_INTERLACED_TB))) { | ||
943 | dprintk(1, "unsupported field setting\n"); | ||
944 | return -EINVAL; | ||
945 | } | ||
946 | } else { | ||
947 | f->fmt.pix.height = NUM_LINES_1CIFS_PAL; | ||
948 | if (b_any_field) { | ||
949 | field = V4L2_FIELD_TOP; | ||
950 | } else if (!((field == V4L2_FIELD_TOP) || | ||
951 | (field == V4L2_FIELD_BOTTOM))) { | ||
952 | dprintk(1, "unsupported field setting\n"); | ||
953 | return -EINVAL; | ||
954 | } | ||
955 | } | ||
956 | if (f->fmt.pix.width >= LINE_SZ_4CIFS_PAL) { | ||
957 | f->fmt.pix.width = LINE_SZ_4CIFS_PAL; | ||
958 | field = V4L2_FIELD_SEQ_TB; | ||
959 | } else if (f->fmt.pix.width >= LINE_SZ_2CIFS_PAL) { | ||
960 | f->fmt.pix.width = LINE_SZ_2CIFS_PAL; | ||
961 | field = V4L2_FIELD_TOP; | ||
962 | } else if (f->fmt.pix.width >= LINE_SZ_1CIFS_PAL) { | ||
963 | f->fmt.pix.width = LINE_SZ_1CIFS_PAL; | ||
964 | field = V4L2_FIELD_TOP; | ||
965 | } else { | ||
966 | f->fmt.pix.width = LINE_SZ_1CIFS_PAL; | ||
967 | field = V4L2_FIELD_TOP; | ||
968 | } | ||
969 | } | ||
970 | f->fmt.pix.field = field; | ||
971 | f->fmt.pix.bytesperline = (f->fmt.pix.width * fmt->depth) >> 3; | ||
972 | f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline; | ||
973 | dprintk(50, "%s: set width %d height %d field %d\n", __func__, | ||
974 | f->fmt.pix.width, f->fmt.pix.height, f->fmt.pix.field); | ||
975 | return 0; | ||
976 | } | ||
977 | |||
978 | static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, | ||
979 | struct v4l2_format *f) | ||
980 | { | ||
981 | struct s2255_fh *fh = priv; | ||
982 | struct s2255_channel *channel = fh->channel; | ||
983 | const struct s2255_fmt *fmt; | ||
984 | struct videobuf_queue *q = &fh->vb_vidq; | ||
985 | struct s2255_mode mode; | ||
986 | int ret; | ||
987 | |||
988 | ret = vidioc_try_fmt_vid_cap(file, fh, f); | ||
989 | |||
990 | if (ret < 0) | ||
991 | return ret; | ||
992 | |||
993 | fmt = format_by_fourcc(f->fmt.pix.pixelformat); | ||
994 | |||
995 | if (fmt == NULL) | ||
996 | return -EINVAL; | ||
997 | |||
998 | mutex_lock(&q->vb_lock); | ||
999 | |||
1000 | if (videobuf_queue_is_busy(&fh->vb_vidq)) { | ||
1001 | dprintk(1, "queue busy\n"); | ||
1002 | ret = -EBUSY; | ||
1003 | goto out_s_fmt; | ||
1004 | } | ||
1005 | |||
1006 | if (res_locked(fh)) { | ||
1007 | dprintk(1, "%s: channel busy\n", __func__); | ||
1008 | ret = -EBUSY; | ||
1009 | goto out_s_fmt; | ||
1010 | } | ||
1011 | mode = channel->mode; | ||
1012 | channel->fmt = fmt; | ||
1013 | channel->width = f->fmt.pix.width; | ||
1014 | channel->height = f->fmt.pix.height; | ||
1015 | fh->vb_vidq.field = f->fmt.pix.field; | ||
1016 | fh->type = f->type; | ||
1017 | if (channel->width > norm_minw(&channel->vdev)) { | ||
1018 | if (channel->height > norm_minh(&channel->vdev)) { | ||
1019 | if (channel->cap_parm.capturemode & | ||
1020 | V4L2_MODE_HIGHQUALITY) | ||
1021 | mode.scale = SCALE_4CIFSI; | ||
1022 | else | ||
1023 | mode.scale = SCALE_4CIFS; | ||
1024 | } else | ||
1025 | mode.scale = SCALE_2CIFS; | ||
1026 | |||
1027 | } else { | ||
1028 | mode.scale = SCALE_1CIFS; | ||
1029 | } | ||
1030 | /* color mode */ | ||
1031 | switch (channel->fmt->fourcc) { | ||
1032 | case V4L2_PIX_FMT_GREY: | ||
1033 | mode.color &= ~MASK_COLOR; | ||
1034 | mode.color |= COLOR_Y8; | ||
1035 | break; | ||
1036 | case V4L2_PIX_FMT_JPEG: | ||
1037 | case V4L2_PIX_FMT_MJPEG: | ||
1038 | mode.color &= ~MASK_COLOR; | ||
1039 | mode.color |= COLOR_JPG; | ||
1040 | mode.color |= (channel->jc.quality << 8); | ||
1041 | break; | ||
1042 | case V4L2_PIX_FMT_YUV422P: | ||
1043 | mode.color &= ~MASK_COLOR; | ||
1044 | mode.color |= COLOR_YUVPL; | ||
1045 | break; | ||
1046 | case V4L2_PIX_FMT_YUYV: | ||
1047 | case V4L2_PIX_FMT_UYVY: | ||
1048 | default: | ||
1049 | mode.color &= ~MASK_COLOR; | ||
1050 | mode.color |= COLOR_YUVPK; | ||
1051 | break; | ||
1052 | } | ||
1053 | if ((mode.color & MASK_COLOR) != (channel->mode.color & MASK_COLOR)) | ||
1054 | mode.restart = 1; | ||
1055 | else if (mode.scale != channel->mode.scale) | ||
1056 | mode.restart = 1; | ||
1057 | else if (mode.format != channel->mode.format) | ||
1058 | mode.restart = 1; | ||
1059 | channel->mode = mode; | ||
1060 | (void) s2255_set_mode(channel, &mode); | ||
1061 | ret = 0; | ||
1062 | out_s_fmt: | ||
1063 | mutex_unlock(&q->vb_lock); | ||
1064 | return ret; | ||
1065 | } | ||
1066 | |||
1067 | static int vidioc_reqbufs(struct file *file, void *priv, | ||
1068 | struct v4l2_requestbuffers *p) | ||
1069 | { | ||
1070 | int rc; | ||
1071 | struct s2255_fh *fh = priv; | ||
1072 | rc = videobuf_reqbufs(&fh->vb_vidq, p); | ||
1073 | return rc; | ||
1074 | } | ||
1075 | |||
1076 | static int vidioc_querybuf(struct file *file, void *priv, struct v4l2_buffer *p) | ||
1077 | { | ||
1078 | int rc; | ||
1079 | struct s2255_fh *fh = priv; | ||
1080 | rc = videobuf_querybuf(&fh->vb_vidq, p); | ||
1081 | return rc; | ||
1082 | } | ||
1083 | |||
1084 | static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *p) | ||
1085 | { | ||
1086 | int rc; | ||
1087 | struct s2255_fh *fh = priv; | ||
1088 | rc = videobuf_qbuf(&fh->vb_vidq, p); | ||
1089 | return rc; | ||
1090 | } | ||
1091 | |||
1092 | static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p) | ||
1093 | { | ||
1094 | int rc; | ||
1095 | struct s2255_fh *fh = priv; | ||
1096 | rc = videobuf_dqbuf(&fh->vb_vidq, p, file->f_flags & O_NONBLOCK); | ||
1097 | return rc; | ||
1098 | } | ||
1099 | |||
1100 | /* write to the configuration pipe, synchronously */ | ||
1101 | static int s2255_write_config(struct usb_device *udev, unsigned char *pbuf, | ||
1102 | int size) | ||
1103 | { | ||
1104 | int pipe; | ||
1105 | int done; | ||
1106 | long retval = -1; | ||
1107 | if (udev) { | ||
1108 | pipe = usb_sndbulkpipe(udev, S2255_CONFIG_EP); | ||
1109 | retval = usb_bulk_msg(udev, pipe, pbuf, size, &done, 500); | ||
1110 | } | ||
1111 | return retval; | ||
1112 | } | ||
1113 | |||
1114 | static u32 get_transfer_size(struct s2255_mode *mode) | ||
1115 | { | ||
1116 | int linesPerFrame = LINE_SZ_DEF; | ||
1117 | int pixelsPerLine = NUM_LINES_DEF; | ||
1118 | u32 outImageSize; | ||
1119 | u32 usbInSize; | ||
1120 | unsigned int mask_mult; | ||
1121 | |||
1122 | if (mode == NULL) | ||
1123 | return 0; | ||
1124 | |||
1125 | if (mode->format == FORMAT_NTSC) { | ||
1126 | switch (mode->scale) { | ||
1127 | case SCALE_4CIFS: | ||
1128 | case SCALE_4CIFSI: | ||
1129 | linesPerFrame = NUM_LINES_4CIFS_NTSC * 2; | ||
1130 | pixelsPerLine = LINE_SZ_4CIFS_NTSC; | ||
1131 | break; | ||
1132 | case SCALE_2CIFS: | ||
1133 | linesPerFrame = NUM_LINES_2CIFS_NTSC; | ||
1134 | pixelsPerLine = LINE_SZ_2CIFS_NTSC; | ||
1135 | break; | ||
1136 | case SCALE_1CIFS: | ||
1137 | linesPerFrame = NUM_LINES_1CIFS_NTSC; | ||
1138 | pixelsPerLine = LINE_SZ_1CIFS_NTSC; | ||
1139 | break; | ||
1140 | default: | ||
1141 | break; | ||
1142 | } | ||
1143 | } else if (mode->format == FORMAT_PAL) { | ||
1144 | switch (mode->scale) { | ||
1145 | case SCALE_4CIFS: | ||
1146 | case SCALE_4CIFSI: | ||
1147 | linesPerFrame = NUM_LINES_4CIFS_PAL * 2; | ||
1148 | pixelsPerLine = LINE_SZ_4CIFS_PAL; | ||
1149 | break; | ||
1150 | case SCALE_2CIFS: | ||
1151 | linesPerFrame = NUM_LINES_2CIFS_PAL; | ||
1152 | pixelsPerLine = LINE_SZ_2CIFS_PAL; | ||
1153 | break; | ||
1154 | case SCALE_1CIFS: | ||
1155 | linesPerFrame = NUM_LINES_1CIFS_PAL; | ||
1156 | pixelsPerLine = LINE_SZ_1CIFS_PAL; | ||
1157 | break; | ||
1158 | default: | ||
1159 | break; | ||
1160 | } | ||
1161 | } | ||
1162 | outImageSize = linesPerFrame * pixelsPerLine; | ||
1163 | if ((mode->color & MASK_COLOR) != COLOR_Y8) { | ||
1164 | /* 2 bytes/pixel if not monochrome */ | ||
1165 | outImageSize *= 2; | ||
1166 | } | ||
1167 | |||
1168 | /* total bytes to send including prefix and 4K padding; | ||
1169 | must be a multiple of USB_READ_SIZE */ | ||
1170 | usbInSize = outImageSize + PREFIX_SIZE; /* always send prefix */ | ||
1171 | mask_mult = 0xffffffffUL - DEF_USB_BLOCK + 1; | ||
1172 | /* if size not a multiple of USB_READ_SIZE */ | ||
1173 | if (usbInSize & ~mask_mult) | ||
1174 | usbInSize = (usbInSize & mask_mult) + (DEF_USB_BLOCK); | ||
1175 | return usbInSize; | ||
1176 | } | ||
1177 | |||
1178 | static void s2255_print_cfg(struct s2255_dev *sdev, struct s2255_mode *mode) | ||
1179 | { | ||
1180 | struct device *dev = &sdev->udev->dev; | ||
1181 | dev_info(dev, "------------------------------------------------\n"); | ||
1182 | dev_info(dev, "format: %d\nscale %d\n", mode->format, mode->scale); | ||
1183 | dev_info(dev, "fdec: %d\ncolor %d\n", mode->fdec, mode->color); | ||
1184 | dev_info(dev, "bright: 0x%x\n", mode->bright); | ||
1185 | dev_info(dev, "------------------------------------------------\n"); | ||
1186 | } | ||
1187 | |||
1188 | /* | ||
1189 | * set mode is the function which controls the DSP. | ||
1190 | * the restart parameter in struct s2255_mode should be set whenever | ||
1191 | * the image size could change via color format, video system or image | ||
1192 | * size. | ||
1193 | * When the restart parameter is set, we sleep for ONE frame to allow the | ||
1194 | * DSP time to get the new frame | ||
1195 | */ | ||
1196 | static int s2255_set_mode(struct s2255_channel *channel, | ||
1197 | struct s2255_mode *mode) | ||
1198 | { | ||
1199 | int res; | ||
1200 | __le32 *buffer; | ||
1201 | unsigned long chn_rev; | ||
1202 | struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev); | ||
1203 | chn_rev = G_chnmap[channel->idx]; | ||
1204 | dprintk(3, "%s channel: %d\n", __func__, channel->idx); | ||
1205 | /* if JPEG, set the quality */ | ||
1206 | if ((mode->color & MASK_COLOR) == COLOR_JPG) { | ||
1207 | mode->color &= ~MASK_COLOR; | ||
1208 | mode->color |= COLOR_JPG; | ||
1209 | mode->color &= ~MASK_JPG_QUALITY; | ||
1210 | mode->color |= (channel->jc.quality << 8); | ||
1211 | } | ||
1212 | /* save the mode */ | ||
1213 | channel->mode = *mode; | ||
1214 | channel->req_image_size = get_transfer_size(mode); | ||
1215 | dprintk(1, "%s: reqsize %ld\n", __func__, channel->req_image_size); | ||
1216 | buffer = kzalloc(512, GFP_KERNEL); | ||
1217 | if (buffer == NULL) { | ||
1218 | dev_err(&dev->udev->dev, "out of mem\n"); | ||
1219 | return -ENOMEM; | ||
1220 | } | ||
1221 | /* set the mode */ | ||
1222 | buffer[0] = IN_DATA_TOKEN; | ||
1223 | buffer[1] = (__le32) cpu_to_le32(chn_rev); | ||
1224 | buffer[2] = CMD_SET_MODE; | ||
1225 | memcpy(&buffer[3], &channel->mode, sizeof(struct s2255_mode)); | ||
1226 | channel->setmode_ready = 0; | ||
1227 | res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512); | ||
1228 | if (debug) | ||
1229 | s2255_print_cfg(dev, mode); | ||
1230 | kfree(buffer); | ||
1231 | /* wait at least 3 frames before continuing */ | ||
1232 | if (mode->restart) { | ||
1233 | wait_event_timeout(channel->wait_setmode, | ||
1234 | (channel->setmode_ready != 0), | ||
1235 | msecs_to_jiffies(S2255_SETMODE_TIMEOUT)); | ||
1236 | if (channel->setmode_ready != 1) { | ||
1237 | printk(KERN_DEBUG "s2255: no set mode response\n"); | ||
1238 | res = -EFAULT; | ||
1239 | } | ||
1240 | } | ||
1241 | /* clear the restart flag */ | ||
1242 | channel->mode.restart = 0; | ||
1243 | dprintk(1, "%s chn %d, result: %d\n", __func__, channel->idx, res); | ||
1244 | return res; | ||
1245 | } | ||
1246 | |||
1247 | static int s2255_cmd_status(struct s2255_channel *channel, u32 *pstatus) | ||
1248 | { | ||
1249 | int res; | ||
1250 | __le32 *buffer; | ||
1251 | u32 chn_rev; | ||
1252 | struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev); | ||
1253 | chn_rev = G_chnmap[channel->idx]; | ||
1254 | dprintk(4, "%s chan %d\n", __func__, channel->idx); | ||
1255 | buffer = kzalloc(512, GFP_KERNEL); | ||
1256 | if (buffer == NULL) { | ||
1257 | dev_err(&dev->udev->dev, "out of mem\n"); | ||
1258 | return -ENOMEM; | ||
1259 | } | ||
1260 | /* form the get vid status command */ | ||
1261 | buffer[0] = IN_DATA_TOKEN; | ||
1262 | buffer[1] = (__le32) cpu_to_le32(chn_rev); | ||
1263 | buffer[2] = CMD_STATUS; | ||
1264 | *pstatus = 0; | ||
1265 | channel->vidstatus_ready = 0; | ||
1266 | res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512); | ||
1267 | kfree(buffer); | ||
1268 | wait_event_timeout(channel->wait_vidstatus, | ||
1269 | (channel->vidstatus_ready != 0), | ||
1270 | msecs_to_jiffies(S2255_VIDSTATUS_TIMEOUT)); | ||
1271 | if (channel->vidstatus_ready != 1) { | ||
1272 | printk(KERN_DEBUG "s2255: no vidstatus response\n"); | ||
1273 | res = -EFAULT; | ||
1274 | } | ||
1275 | *pstatus = channel->vidstatus; | ||
1276 | dprintk(4, "%s, vid status %d\n", __func__, *pstatus); | ||
1277 | return res; | ||
1278 | } | ||
1279 | |||
1280 | static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i) | ||
1281 | { | ||
1282 | int res; | ||
1283 | struct s2255_fh *fh = priv; | ||
1284 | struct s2255_dev *dev = fh->dev; | ||
1285 | struct s2255_channel *channel = fh->channel; | ||
1286 | int j; | ||
1287 | dprintk(4, "%s\n", __func__); | ||
1288 | if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { | ||
1289 | dev_err(&dev->udev->dev, "invalid fh type0\n"); | ||
1290 | return -EINVAL; | ||
1291 | } | ||
1292 | if (i != fh->type) { | ||
1293 | dev_err(&dev->udev->dev, "invalid fh type1\n"); | ||
1294 | return -EINVAL; | ||
1295 | } | ||
1296 | |||
1297 | if (!res_get(fh)) { | ||
1298 | s2255_dev_err(&dev->udev->dev, "stream busy\n"); | ||
1299 | return -EBUSY; | ||
1300 | } | ||
1301 | channel->last_frame = -1; | ||
1302 | channel->bad_payload = 0; | ||
1303 | channel->cur_frame = 0; | ||
1304 | channel->frame_count = 0; | ||
1305 | for (j = 0; j < SYS_FRAMES; j++) { | ||
1306 | channel->buffer.frame[j].ulState = S2255_READ_IDLE; | ||
1307 | channel->buffer.frame[j].cur_size = 0; | ||
1308 | } | ||
1309 | res = videobuf_streamon(&fh->vb_vidq); | ||
1310 | if (res == 0) { | ||
1311 | s2255_start_acquire(channel); | ||
1312 | channel->b_acquire = 1; | ||
1313 | } else | ||
1314 | res_free(fh); | ||
1315 | |||
1316 | return res; | ||
1317 | } | ||
1318 | |||
1319 | static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i) | ||
1320 | { | ||
1321 | struct s2255_fh *fh = priv; | ||
1322 | dprintk(4, "%s\n, channel: %d", __func__, fh->channel->idx); | ||
1323 | if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { | ||
1324 | printk(KERN_ERR "invalid fh type0\n"); | ||
1325 | return -EINVAL; | ||
1326 | } | ||
1327 | if (i != fh->type) { | ||
1328 | printk(KERN_ERR "invalid type i\n"); | ||
1329 | return -EINVAL; | ||
1330 | } | ||
1331 | s2255_stop_acquire(fh->channel); | ||
1332 | videobuf_streamoff(&fh->vb_vidq); | ||
1333 | res_free(fh); | ||
1334 | return 0; | ||
1335 | } | ||
1336 | |||
1337 | static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *i) | ||
1338 | { | ||
1339 | struct s2255_fh *fh = priv; | ||
1340 | struct s2255_mode mode; | ||
1341 | struct videobuf_queue *q = &fh->vb_vidq; | ||
1342 | int ret = 0; | ||
1343 | mutex_lock(&q->vb_lock); | ||
1344 | if (videobuf_queue_is_busy(q)) { | ||
1345 | dprintk(1, "queue busy\n"); | ||
1346 | ret = -EBUSY; | ||
1347 | goto out_s_std; | ||
1348 | } | ||
1349 | if (res_locked(fh)) { | ||
1350 | dprintk(1, "can't change standard after started\n"); | ||
1351 | ret = -EBUSY; | ||
1352 | goto out_s_std; | ||
1353 | } | ||
1354 | mode = fh->channel->mode; | ||
1355 | if (*i & V4L2_STD_NTSC) { | ||
1356 | dprintk(4, "%s NTSC\n", __func__); | ||
1357 | /* if changing format, reset frame decimation/intervals */ | ||
1358 | if (mode.format != FORMAT_NTSC) { | ||
1359 | mode.restart = 1; | ||
1360 | mode.format = FORMAT_NTSC; | ||
1361 | mode.fdec = FDEC_1; | ||
1362 | } | ||
1363 | } else if (*i & V4L2_STD_PAL) { | ||
1364 | dprintk(4, "%s PAL\n", __func__); | ||
1365 | if (mode.format != FORMAT_PAL) { | ||
1366 | mode.restart = 1; | ||
1367 | mode.format = FORMAT_PAL; | ||
1368 | mode.fdec = FDEC_1; | ||
1369 | } | ||
1370 | } else { | ||
1371 | ret = -EINVAL; | ||
1372 | } | ||
1373 | if (mode.restart) | ||
1374 | s2255_set_mode(fh->channel, &mode); | ||
1375 | out_s_std: | ||
1376 | mutex_unlock(&q->vb_lock); | ||
1377 | return ret; | ||
1378 | } | ||
1379 | |||
1380 | /* Sensoray 2255 is a multiple channel capture device. | ||
1381 | It does not have a "crossbar" of inputs. | ||
1382 | We use one V4L device per channel. The user must | ||
1383 | be aware that certain combinations are not allowed. | ||
1384 | For instance, you cannot do full FPS on more than 2 channels(2 videodevs) | ||
1385 | at once in color(you can do full fps on 4 channels with greyscale. | ||
1386 | */ | ||
1387 | static int vidioc_enum_input(struct file *file, void *priv, | ||
1388 | struct v4l2_input *inp) | ||
1389 | { | ||
1390 | struct s2255_fh *fh = priv; | ||
1391 | struct s2255_dev *dev = fh->dev; | ||
1392 | struct s2255_channel *channel = fh->channel; | ||
1393 | u32 status = 0; | ||
1394 | if (inp->index != 0) | ||
1395 | return -EINVAL; | ||
1396 | inp->type = V4L2_INPUT_TYPE_CAMERA; | ||
1397 | inp->std = S2255_NORMS; | ||
1398 | inp->status = 0; | ||
1399 | if (dev->dsp_fw_ver >= S2255_MIN_DSP_STATUS) { | ||
1400 | int rc; | ||
1401 | rc = s2255_cmd_status(fh->channel, &status); | ||
1402 | dprintk(4, "s2255_cmd_status rc: %d status %x\n", rc, status); | ||
1403 | if (rc == 0) | ||
1404 | inp->status = (status & 0x01) ? 0 | ||
1405 | : V4L2_IN_ST_NO_SIGNAL; | ||
1406 | } | ||
1407 | switch (dev->pid) { | ||
1408 | case 0x2255: | ||
1409 | default: | ||
1410 | strlcpy(inp->name, "Composite", sizeof(inp->name)); | ||
1411 | break; | ||
1412 | case 0x2257: | ||
1413 | strlcpy(inp->name, (channel->idx < 2) ? "Composite" : "S-Video", | ||
1414 | sizeof(inp->name)); | ||
1415 | break; | ||
1416 | } | ||
1417 | return 0; | ||
1418 | } | ||
1419 | |||
1420 | static int vidioc_g_input(struct file *file, void *priv, unsigned int *i) | ||
1421 | { | ||
1422 | *i = 0; | ||
1423 | return 0; | ||
1424 | } | ||
1425 | static int vidioc_s_input(struct file *file, void *priv, unsigned int i) | ||
1426 | { | ||
1427 | if (i > 0) | ||
1428 | return -EINVAL; | ||
1429 | return 0; | ||
1430 | } | ||
1431 | |||
1432 | /* --- controls ---------------------------------------------- */ | ||
1433 | static int vidioc_queryctrl(struct file *file, void *priv, | ||
1434 | struct v4l2_queryctrl *qc) | ||
1435 | { | ||
1436 | struct s2255_fh *fh = priv; | ||
1437 | struct s2255_channel *channel = fh->channel; | ||
1438 | struct s2255_dev *dev = fh->dev; | ||
1439 | switch (qc->id) { | ||
1440 | case V4L2_CID_BRIGHTNESS: | ||
1441 | v4l2_ctrl_query_fill(qc, -127, 127, 1, DEF_BRIGHT); | ||
1442 | break; | ||
1443 | case V4L2_CID_CONTRAST: | ||
1444 | v4l2_ctrl_query_fill(qc, 0, 255, 1, DEF_CONTRAST); | ||
1445 | break; | ||
1446 | case V4L2_CID_SATURATION: | ||
1447 | v4l2_ctrl_query_fill(qc, 0, 255, 1, DEF_SATURATION); | ||
1448 | break; | ||
1449 | case V4L2_CID_HUE: | ||
1450 | v4l2_ctrl_query_fill(qc, 0, 255, 1, DEF_HUE); | ||
1451 | break; | ||
1452 | case V4L2_CID_PRIVATE_COLORFILTER: | ||
1453 | if (dev->dsp_fw_ver < S2255_MIN_DSP_COLORFILTER) | ||
1454 | return -EINVAL; | ||
1455 | if ((dev->pid == 0x2257) && (channel->idx > 1)) | ||
1456 | return -EINVAL; | ||
1457 | strlcpy(qc->name, "Color Filter", sizeof(qc->name)); | ||
1458 | qc->type = V4L2_CTRL_TYPE_MENU; | ||
1459 | qc->minimum = 0; | ||
1460 | qc->maximum = 1; | ||
1461 | qc->step = 1; | ||
1462 | qc->default_value = 1; | ||
1463 | qc->flags = 0; | ||
1464 | break; | ||
1465 | default: | ||
1466 | return -EINVAL; | ||
1467 | } | ||
1468 | dprintk(4, "%s, id %d\n", __func__, qc->id); | ||
1469 | return 0; | ||
1470 | } | ||
1471 | |||
1472 | static int vidioc_g_ctrl(struct file *file, void *priv, | ||
1473 | struct v4l2_control *ctrl) | ||
1474 | { | ||
1475 | struct s2255_fh *fh = priv; | ||
1476 | struct s2255_dev *dev = fh->dev; | ||
1477 | struct s2255_channel *channel = fh->channel; | ||
1478 | switch (ctrl->id) { | ||
1479 | case V4L2_CID_BRIGHTNESS: | ||
1480 | ctrl->value = channel->mode.bright; | ||
1481 | break; | ||
1482 | case V4L2_CID_CONTRAST: | ||
1483 | ctrl->value = channel->mode.contrast; | ||
1484 | break; | ||
1485 | case V4L2_CID_SATURATION: | ||
1486 | ctrl->value = channel->mode.saturation; | ||
1487 | break; | ||
1488 | case V4L2_CID_HUE: | ||
1489 | ctrl->value = channel->mode.hue; | ||
1490 | break; | ||
1491 | case V4L2_CID_PRIVATE_COLORFILTER: | ||
1492 | if (dev->dsp_fw_ver < S2255_MIN_DSP_COLORFILTER) | ||
1493 | return -EINVAL; | ||
1494 | if ((dev->pid == 0x2257) && (channel->idx > 1)) | ||
1495 | return -EINVAL; | ||
1496 | ctrl->value = !((channel->mode.color & MASK_INPUT_TYPE) >> 16); | ||
1497 | break; | ||
1498 | default: | ||
1499 | return -EINVAL; | ||
1500 | } | ||
1501 | dprintk(4, "%s, id %d val %d\n", __func__, ctrl->id, ctrl->value); | ||
1502 | return 0; | ||
1503 | } | ||
1504 | |||
1505 | static int vidioc_s_ctrl(struct file *file, void *priv, | ||
1506 | struct v4l2_control *ctrl) | ||
1507 | { | ||
1508 | struct s2255_fh *fh = priv; | ||
1509 | struct s2255_channel *channel = fh->channel; | ||
1510 | struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev); | ||
1511 | struct s2255_mode mode; | ||
1512 | mode = channel->mode; | ||
1513 | dprintk(4, "%s\n", __func__); | ||
1514 | /* update the mode to the corresponding value */ | ||
1515 | switch (ctrl->id) { | ||
1516 | case V4L2_CID_BRIGHTNESS: | ||
1517 | mode.bright = ctrl->value; | ||
1518 | break; | ||
1519 | case V4L2_CID_CONTRAST: | ||
1520 | mode.contrast = ctrl->value; | ||
1521 | break; | ||
1522 | case V4L2_CID_HUE: | ||
1523 | mode.hue = ctrl->value; | ||
1524 | break; | ||
1525 | case V4L2_CID_SATURATION: | ||
1526 | mode.saturation = ctrl->value; | ||
1527 | break; | ||
1528 | case V4L2_CID_PRIVATE_COLORFILTER: | ||
1529 | if (dev->dsp_fw_ver < S2255_MIN_DSP_COLORFILTER) | ||
1530 | return -EINVAL; | ||
1531 | if ((dev->pid == 0x2257) && (channel->idx > 1)) | ||
1532 | return -EINVAL; | ||
1533 | mode.color &= ~MASK_INPUT_TYPE; | ||
1534 | mode.color |= ((ctrl->value ? 0 : 1) << 16); | ||
1535 | break; | ||
1536 | default: | ||
1537 | return -EINVAL; | ||
1538 | } | ||
1539 | mode.restart = 0; | ||
1540 | /* set mode here. Note: stream does not need restarted. | ||
1541 | some V4L programs restart stream unnecessarily | ||
1542 | after a s_crtl. | ||
1543 | */ | ||
1544 | s2255_set_mode(fh->channel, &mode); | ||
1545 | return 0; | ||
1546 | } | ||
1547 | |||
1548 | static int vidioc_g_jpegcomp(struct file *file, void *priv, | ||
1549 | struct v4l2_jpegcompression *jc) | ||
1550 | { | ||
1551 | struct s2255_fh *fh = priv; | ||
1552 | struct s2255_channel *channel = fh->channel; | ||
1553 | *jc = channel->jc; | ||
1554 | dprintk(2, "%s: quality %d\n", __func__, jc->quality); | ||
1555 | return 0; | ||
1556 | } | ||
1557 | |||
1558 | static int vidioc_s_jpegcomp(struct file *file, void *priv, | ||
1559 | struct v4l2_jpegcompression *jc) | ||
1560 | { | ||
1561 | struct s2255_fh *fh = priv; | ||
1562 | struct s2255_channel *channel = fh->channel; | ||
1563 | if (jc->quality < 0 || jc->quality > 100) | ||
1564 | return -EINVAL; | ||
1565 | channel->jc.quality = jc->quality; | ||
1566 | dprintk(2, "%s: quality %d\n", __func__, jc->quality); | ||
1567 | return 0; | ||
1568 | } | ||
1569 | |||
1570 | static int vidioc_g_parm(struct file *file, void *priv, | ||
1571 | struct v4l2_streamparm *sp) | ||
1572 | { | ||
1573 | struct s2255_fh *fh = priv; | ||
1574 | __u32 def_num, def_dem; | ||
1575 | struct s2255_channel *channel = fh->channel; | ||
1576 | if (sp->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
1577 | return -EINVAL; | ||
1578 | memset(sp, 0, sizeof(struct v4l2_streamparm)); | ||
1579 | sp->parm.capture.capability = V4L2_CAP_TIMEPERFRAME; | ||
1580 | sp->parm.capture.capturemode = channel->cap_parm.capturemode; | ||
1581 | def_num = (channel->mode.format == FORMAT_NTSC) ? 1001 : 1000; | ||
1582 | def_dem = (channel->mode.format == FORMAT_NTSC) ? 30000 : 25000; | ||
1583 | sp->parm.capture.timeperframe.denominator = def_dem; | ||
1584 | switch (channel->mode.fdec) { | ||
1585 | default: | ||
1586 | case FDEC_1: | ||
1587 | sp->parm.capture.timeperframe.numerator = def_num; | ||
1588 | break; | ||
1589 | case FDEC_2: | ||
1590 | sp->parm.capture.timeperframe.numerator = def_num * 2; | ||
1591 | break; | ||
1592 | case FDEC_3: | ||
1593 | sp->parm.capture.timeperframe.numerator = def_num * 3; | ||
1594 | break; | ||
1595 | case FDEC_5: | ||
1596 | sp->parm.capture.timeperframe.numerator = def_num * 5; | ||
1597 | break; | ||
1598 | } | ||
1599 | dprintk(4, "%s capture mode, %d timeperframe %d/%d\n", __func__, | ||
1600 | sp->parm.capture.capturemode, | ||
1601 | sp->parm.capture.timeperframe.numerator, | ||
1602 | sp->parm.capture.timeperframe.denominator); | ||
1603 | return 0; | ||
1604 | } | ||
1605 | |||
1606 | static int vidioc_s_parm(struct file *file, void *priv, | ||
1607 | struct v4l2_streamparm *sp) | ||
1608 | { | ||
1609 | struct s2255_fh *fh = priv; | ||
1610 | struct s2255_channel *channel = fh->channel; | ||
1611 | struct s2255_mode mode; | ||
1612 | int fdec = FDEC_1; | ||
1613 | __u32 def_num, def_dem; | ||
1614 | if (sp->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
1615 | return -EINVAL; | ||
1616 | mode = channel->mode; | ||
1617 | /* high quality capture mode requires a stream restart */ | ||
1618 | if (channel->cap_parm.capturemode | ||
1619 | != sp->parm.capture.capturemode && res_locked(fh)) | ||
1620 | return -EBUSY; | ||
1621 | def_num = (mode.format == FORMAT_NTSC) ? 1001 : 1000; | ||
1622 | def_dem = (mode.format == FORMAT_NTSC) ? 30000 : 25000; | ||
1623 | if (def_dem != sp->parm.capture.timeperframe.denominator) | ||
1624 | sp->parm.capture.timeperframe.numerator = def_num; | ||
1625 | else if (sp->parm.capture.timeperframe.numerator <= def_num) | ||
1626 | sp->parm.capture.timeperframe.numerator = def_num; | ||
1627 | else if (sp->parm.capture.timeperframe.numerator <= (def_num * 2)) { | ||
1628 | sp->parm.capture.timeperframe.numerator = def_num * 2; | ||
1629 | fdec = FDEC_2; | ||
1630 | } else if (sp->parm.capture.timeperframe.numerator <= (def_num * 3)) { | ||
1631 | sp->parm.capture.timeperframe.numerator = def_num * 3; | ||
1632 | fdec = FDEC_3; | ||
1633 | } else { | ||
1634 | sp->parm.capture.timeperframe.numerator = def_num * 5; | ||
1635 | fdec = FDEC_5; | ||
1636 | } | ||
1637 | mode.fdec = fdec; | ||
1638 | sp->parm.capture.timeperframe.denominator = def_dem; | ||
1639 | s2255_set_mode(channel, &mode); | ||
1640 | dprintk(4, "%s capture mode, %d timeperframe %d/%d, fdec %d\n", | ||
1641 | __func__, | ||
1642 | sp->parm.capture.capturemode, | ||
1643 | sp->parm.capture.timeperframe.numerator, | ||
1644 | sp->parm.capture.timeperframe.denominator, fdec); | ||
1645 | return 0; | ||
1646 | } | ||
1647 | |||
1648 | static int vidioc_enum_frameintervals(struct file *file, void *priv, | ||
1649 | struct v4l2_frmivalenum *fe) | ||
1650 | { | ||
1651 | int is_ntsc = 0; | ||
1652 | #define NUM_FRAME_ENUMS 4 | ||
1653 | int frm_dec[NUM_FRAME_ENUMS] = {1, 2, 3, 5}; | ||
1654 | if (fe->index < 0 || fe->index >= NUM_FRAME_ENUMS) | ||
1655 | return -EINVAL; | ||
1656 | switch (fe->width) { | ||
1657 | case 640: | ||
1658 | if (fe->height != 240 && fe->height != 480) | ||
1659 | return -EINVAL; | ||
1660 | is_ntsc = 1; | ||
1661 | break; | ||
1662 | case 320: | ||
1663 | if (fe->height != 240) | ||
1664 | return -EINVAL; | ||
1665 | is_ntsc = 1; | ||
1666 | break; | ||
1667 | case 704: | ||
1668 | if (fe->height != 288 && fe->height != 576) | ||
1669 | return -EINVAL; | ||
1670 | break; | ||
1671 | case 352: | ||
1672 | if (fe->height != 288) | ||
1673 | return -EINVAL; | ||
1674 | break; | ||
1675 | default: | ||
1676 | return -EINVAL; | ||
1677 | } | ||
1678 | fe->type = V4L2_FRMIVAL_TYPE_DISCRETE; | ||
1679 | fe->discrete.denominator = is_ntsc ? 30000 : 25000; | ||
1680 | fe->discrete.numerator = (is_ntsc ? 1001 : 1000) * frm_dec[fe->index]; | ||
1681 | dprintk(4, "%s discrete %d/%d\n", __func__, fe->discrete.numerator, | ||
1682 | fe->discrete.denominator); | ||
1683 | return 0; | ||
1684 | } | ||
1685 | |||
1686 | static int __s2255_open(struct file *file) | ||
1687 | { | ||
1688 | struct video_device *vdev = video_devdata(file); | ||
1689 | struct s2255_channel *channel = video_drvdata(file); | ||
1690 | struct s2255_dev *dev = to_s2255_dev(vdev->v4l2_dev); | ||
1691 | struct s2255_fh *fh; | ||
1692 | enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
1693 | int state; | ||
1694 | dprintk(1, "s2255: open called (dev=%s)\n", | ||
1695 | video_device_node_name(vdev)); | ||
1696 | state = atomic_read(&dev->fw_data->fw_state); | ||
1697 | switch (state) { | ||
1698 | case S2255_FW_DISCONNECTING: | ||
1699 | return -ENODEV; | ||
1700 | case S2255_FW_FAILED: | ||
1701 | s2255_dev_err(&dev->udev->dev, | ||
1702 | "firmware load failed. retrying.\n"); | ||
1703 | s2255_fwload_start(dev, 1); | ||
1704 | wait_event_timeout(dev->fw_data->wait_fw, | ||
1705 | ((atomic_read(&dev->fw_data->fw_state) | ||
1706 | == S2255_FW_SUCCESS) || | ||
1707 | (atomic_read(&dev->fw_data->fw_state) | ||
1708 | == S2255_FW_DISCONNECTING)), | ||
1709 | msecs_to_jiffies(S2255_LOAD_TIMEOUT)); | ||
1710 | /* state may have changed, re-read */ | ||
1711 | state = atomic_read(&dev->fw_data->fw_state); | ||
1712 | break; | ||
1713 | case S2255_FW_NOTLOADED: | ||
1714 | case S2255_FW_LOADED_DSPWAIT: | ||
1715 | /* give S2255_LOAD_TIMEOUT time for firmware to load in case | ||
1716 | driver loaded and then device immediately opened */ | ||
1717 | printk(KERN_INFO "%s waiting for firmware load\n", __func__); | ||
1718 | wait_event_timeout(dev->fw_data->wait_fw, | ||
1719 | ((atomic_read(&dev->fw_data->fw_state) | ||
1720 | == S2255_FW_SUCCESS) || | ||
1721 | (atomic_read(&dev->fw_data->fw_state) | ||
1722 | == S2255_FW_DISCONNECTING)), | ||
1723 | msecs_to_jiffies(S2255_LOAD_TIMEOUT)); | ||
1724 | /* state may have changed, re-read */ | ||
1725 | state = atomic_read(&dev->fw_data->fw_state); | ||
1726 | break; | ||
1727 | case S2255_FW_SUCCESS: | ||
1728 | default: | ||
1729 | break; | ||
1730 | } | ||
1731 | /* state may have changed in above switch statement */ | ||
1732 | switch (state) { | ||
1733 | case S2255_FW_SUCCESS: | ||
1734 | break; | ||
1735 | case S2255_FW_FAILED: | ||
1736 | printk(KERN_INFO "2255 firmware load failed.\n"); | ||
1737 | return -ENODEV; | ||
1738 | case S2255_FW_DISCONNECTING: | ||
1739 | printk(KERN_INFO "%s: disconnecting\n", __func__); | ||
1740 | return -ENODEV; | ||
1741 | case S2255_FW_LOADED_DSPWAIT: | ||
1742 | case S2255_FW_NOTLOADED: | ||
1743 | printk(KERN_INFO "%s: firmware not loaded yet" | ||
1744 | "please try again later\n", | ||
1745 | __func__); | ||
1746 | /* | ||
1747 | * Timeout on firmware load means device unusable. | ||
1748 | * Set firmware failure state. | ||
1749 | * On next s2255_open the firmware will be reloaded. | ||
1750 | */ | ||
1751 | atomic_set(&dev->fw_data->fw_state, | ||
1752 | S2255_FW_FAILED); | ||
1753 | return -EAGAIN; | ||
1754 | default: | ||
1755 | printk(KERN_INFO "%s: unknown state\n", __func__); | ||
1756 | return -EFAULT; | ||
1757 | } | ||
1758 | /* allocate + initialize per filehandle data */ | ||
1759 | fh = kzalloc(sizeof(*fh), GFP_KERNEL); | ||
1760 | if (NULL == fh) | ||
1761 | return -ENOMEM; | ||
1762 | file->private_data = fh; | ||
1763 | fh->dev = dev; | ||
1764 | fh->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
1765 | fh->channel = channel; | ||
1766 | if (!channel->configured) { | ||
1767 | /* configure channel to default state */ | ||
1768 | channel->fmt = &formats[0]; | ||
1769 | s2255_set_mode(channel, &channel->mode); | ||
1770 | channel->configured = 1; | ||
1771 | } | ||
1772 | dprintk(1, "%s: dev=%s type=%s\n", __func__, | ||
1773 | video_device_node_name(vdev), v4l2_type_names[type]); | ||
1774 | dprintk(2, "%s: fh=0x%08lx, dev=0x%08lx, vidq=0x%08lx\n", __func__, | ||
1775 | (unsigned long)fh, (unsigned long)dev, | ||
1776 | (unsigned long)&channel->vidq); | ||
1777 | dprintk(4, "%s: list_empty active=%d\n", __func__, | ||
1778 | list_empty(&channel->vidq.active)); | ||
1779 | videobuf_queue_vmalloc_init(&fh->vb_vidq, &s2255_video_qops, | ||
1780 | NULL, &dev->slock, | ||
1781 | fh->type, | ||
1782 | V4L2_FIELD_INTERLACED, | ||
1783 | sizeof(struct s2255_buffer), | ||
1784 | fh, vdev->lock); | ||
1785 | return 0; | ||
1786 | } | ||
1787 | |||
1788 | static int s2255_open(struct file *file) | ||
1789 | { | ||
1790 | struct video_device *vdev = video_devdata(file); | ||
1791 | int ret; | ||
1792 | |||
1793 | if (mutex_lock_interruptible(vdev->lock)) | ||
1794 | return -ERESTARTSYS; | ||
1795 | ret = __s2255_open(file); | ||
1796 | mutex_unlock(vdev->lock); | ||
1797 | return ret; | ||
1798 | } | ||
1799 | |||
1800 | static unsigned int s2255_poll(struct file *file, | ||
1801 | struct poll_table_struct *wait) | ||
1802 | { | ||
1803 | struct s2255_fh *fh = file->private_data; | ||
1804 | struct s2255_dev *dev = fh->dev; | ||
1805 | int rc; | ||
1806 | dprintk(100, "%s\n", __func__); | ||
1807 | if (V4L2_BUF_TYPE_VIDEO_CAPTURE != fh->type) | ||
1808 | return POLLERR; | ||
1809 | mutex_lock(&dev->lock); | ||
1810 | rc = videobuf_poll_stream(file, &fh->vb_vidq, wait); | ||
1811 | mutex_unlock(&dev->lock); | ||
1812 | return rc; | ||
1813 | } | ||
1814 | |||
1815 | static void s2255_destroy(struct s2255_dev *dev) | ||
1816 | { | ||
1817 | /* board shutdown stops the read pipe if it is running */ | ||
1818 | s2255_board_shutdown(dev); | ||
1819 | /* make sure firmware still not trying to load */ | ||
1820 | del_timer(&dev->timer); /* only started in .probe and .open */ | ||
1821 | if (dev->fw_data->fw_urb) { | ||
1822 | usb_kill_urb(dev->fw_data->fw_urb); | ||
1823 | usb_free_urb(dev->fw_data->fw_urb); | ||
1824 | dev->fw_data->fw_urb = NULL; | ||
1825 | } | ||
1826 | release_firmware(dev->fw_data->fw); | ||
1827 | kfree(dev->fw_data->pfw_data); | ||
1828 | kfree(dev->fw_data); | ||
1829 | /* reset the DSP so firmware can be reloaded next time */ | ||
1830 | s2255_reset_dsppower(dev); | ||
1831 | mutex_destroy(&dev->lock); | ||
1832 | usb_put_dev(dev->udev); | ||
1833 | v4l2_device_unregister(&dev->v4l2_dev); | ||
1834 | dprintk(1, "%s", __func__); | ||
1835 | kfree(dev); | ||
1836 | } | ||
1837 | |||
1838 | static int s2255_release(struct file *file) | ||
1839 | { | ||
1840 | struct s2255_fh *fh = file->private_data; | ||
1841 | struct s2255_dev *dev = fh->dev; | ||
1842 | struct video_device *vdev = video_devdata(file); | ||
1843 | struct s2255_channel *channel = fh->channel; | ||
1844 | if (!dev) | ||
1845 | return -ENODEV; | ||
1846 | mutex_lock(&dev->lock); | ||
1847 | /* turn off stream */ | ||
1848 | if (res_check(fh)) { | ||
1849 | if (channel->b_acquire) | ||
1850 | s2255_stop_acquire(fh->channel); | ||
1851 | videobuf_streamoff(&fh->vb_vidq); | ||
1852 | res_free(fh); | ||
1853 | } | ||
1854 | videobuf_mmap_free(&fh->vb_vidq); | ||
1855 | mutex_unlock(&dev->lock); | ||
1856 | dprintk(1, "%s (dev=%s)\n", __func__, video_device_node_name(vdev)); | ||
1857 | kfree(fh); | ||
1858 | return 0; | ||
1859 | } | ||
1860 | |||
1861 | static int s2255_mmap_v4l(struct file *file, struct vm_area_struct *vma) | ||
1862 | { | ||
1863 | struct s2255_fh *fh = file->private_data; | ||
1864 | struct s2255_dev *dev = fh->dev; | ||
1865 | int ret; | ||
1866 | |||
1867 | if (!fh) | ||
1868 | return -ENODEV; | ||
1869 | dprintk(4, "%s, vma=0x%08lx\n", __func__, (unsigned long)vma); | ||
1870 | if (mutex_lock_interruptible(&dev->lock)) | ||
1871 | return -ERESTARTSYS; | ||
1872 | ret = videobuf_mmap_mapper(&fh->vb_vidq, vma); | ||
1873 | mutex_unlock(&dev->lock); | ||
1874 | dprintk(4, "%s vma start=0x%08lx, size=%ld, ret=%d\n", __func__, | ||
1875 | (unsigned long)vma->vm_start, | ||
1876 | (unsigned long)vma->vm_end - (unsigned long)vma->vm_start, ret); | ||
1877 | return ret; | ||
1878 | } | ||
1879 | |||
1880 | static const struct v4l2_file_operations s2255_fops_v4l = { | ||
1881 | .owner = THIS_MODULE, | ||
1882 | .open = s2255_open, | ||
1883 | .release = s2255_release, | ||
1884 | .poll = s2255_poll, | ||
1885 | .unlocked_ioctl = video_ioctl2, /* V4L2 ioctl handler */ | ||
1886 | .mmap = s2255_mmap_v4l, | ||
1887 | }; | ||
1888 | |||
1889 | static const struct v4l2_ioctl_ops s2255_ioctl_ops = { | ||
1890 | .vidioc_querymenu = vidioc_querymenu, | ||
1891 | .vidioc_querycap = vidioc_querycap, | ||
1892 | .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap, | ||
1893 | .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, | ||
1894 | .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap, | ||
1895 | .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap, | ||
1896 | .vidioc_reqbufs = vidioc_reqbufs, | ||
1897 | .vidioc_querybuf = vidioc_querybuf, | ||
1898 | .vidioc_qbuf = vidioc_qbuf, | ||
1899 | .vidioc_dqbuf = vidioc_dqbuf, | ||
1900 | .vidioc_s_std = vidioc_s_std, | ||
1901 | .vidioc_enum_input = vidioc_enum_input, | ||
1902 | .vidioc_g_input = vidioc_g_input, | ||
1903 | .vidioc_s_input = vidioc_s_input, | ||
1904 | .vidioc_queryctrl = vidioc_queryctrl, | ||
1905 | .vidioc_g_ctrl = vidioc_g_ctrl, | ||
1906 | .vidioc_s_ctrl = vidioc_s_ctrl, | ||
1907 | .vidioc_streamon = vidioc_streamon, | ||
1908 | .vidioc_streamoff = vidioc_streamoff, | ||
1909 | .vidioc_s_jpegcomp = vidioc_s_jpegcomp, | ||
1910 | .vidioc_g_jpegcomp = vidioc_g_jpegcomp, | ||
1911 | .vidioc_s_parm = vidioc_s_parm, | ||
1912 | .vidioc_g_parm = vidioc_g_parm, | ||
1913 | .vidioc_enum_frameintervals = vidioc_enum_frameintervals, | ||
1914 | }; | ||
1915 | |||
1916 | static void s2255_video_device_release(struct video_device *vdev) | ||
1917 | { | ||
1918 | struct s2255_dev *dev = to_s2255_dev(vdev->v4l2_dev); | ||
1919 | dprintk(4, "%s, chnls: %d \n", __func__, | ||
1920 | atomic_read(&dev->num_channels)); | ||
1921 | if (atomic_dec_and_test(&dev->num_channels)) | ||
1922 | s2255_destroy(dev); | ||
1923 | return; | ||
1924 | } | ||
1925 | |||
1926 | static struct video_device template = { | ||
1927 | .name = "s2255v", | ||
1928 | .fops = &s2255_fops_v4l, | ||
1929 | .ioctl_ops = &s2255_ioctl_ops, | ||
1930 | .release = s2255_video_device_release, | ||
1931 | .tvnorms = S2255_NORMS, | ||
1932 | .current_norm = V4L2_STD_NTSC_M, | ||
1933 | }; | ||
1934 | |||
1935 | static int s2255_probe_v4l(struct s2255_dev *dev) | ||
1936 | { | ||
1937 | int ret; | ||
1938 | int i; | ||
1939 | int cur_nr = video_nr; | ||
1940 | struct s2255_channel *channel; | ||
1941 | ret = v4l2_device_register(&dev->interface->dev, &dev->v4l2_dev); | ||
1942 | if (ret) | ||
1943 | return ret; | ||
1944 | /* initialize all video 4 linux */ | ||
1945 | /* register 4 video devices */ | ||
1946 | for (i = 0; i < MAX_CHANNELS; i++) { | ||
1947 | channel = &dev->channel[i]; | ||
1948 | INIT_LIST_HEAD(&channel->vidq.active); | ||
1949 | channel->vidq.dev = dev; | ||
1950 | /* register 4 video devices */ | ||
1951 | channel->vdev = template; | ||
1952 | channel->vdev.lock = &dev->lock; | ||
1953 | channel->vdev.v4l2_dev = &dev->v4l2_dev; | ||
1954 | video_set_drvdata(&channel->vdev, channel); | ||
1955 | if (video_nr == -1) | ||
1956 | ret = video_register_device(&channel->vdev, | ||
1957 | VFL_TYPE_GRABBER, | ||
1958 | video_nr); | ||
1959 | else | ||
1960 | ret = video_register_device(&channel->vdev, | ||
1961 | VFL_TYPE_GRABBER, | ||
1962 | cur_nr + i); | ||
1963 | |||
1964 | if (ret) { | ||
1965 | dev_err(&dev->udev->dev, | ||
1966 | "failed to register video device!\n"); | ||
1967 | break; | ||
1968 | } | ||
1969 | atomic_inc(&dev->num_channels); | ||
1970 | v4l2_info(&dev->v4l2_dev, "V4L2 device registered as %s\n", | ||
1971 | video_device_node_name(&channel->vdev)); | ||
1972 | |||
1973 | } | ||
1974 | printk(KERN_INFO "Sensoray 2255 V4L driver Revision: %s\n", | ||
1975 | S2255_VERSION); | ||
1976 | /* if no channels registered, return error and probe will fail*/ | ||
1977 | if (atomic_read(&dev->num_channels) == 0) { | ||
1978 | v4l2_device_unregister(&dev->v4l2_dev); | ||
1979 | return ret; | ||
1980 | } | ||
1981 | if (atomic_read(&dev->num_channels) != MAX_CHANNELS) | ||
1982 | printk(KERN_WARNING "s2255: Not all channels available.\n"); | ||
1983 | return 0; | ||
1984 | } | ||
1985 | |||
1986 | /* this function moves the usb stream read pipe data | ||
1987 | * into the system buffers. | ||
1988 | * returns 0 on success, EAGAIN if more data to process( call this | ||
1989 | * function again). | ||
1990 | * | ||
1991 | * Received frame structure: | ||
1992 | * bytes 0-3: marker : 0x2255DA4AL (S2255_MARKER_FRAME) | ||
1993 | * bytes 4-7: channel: 0-3 | ||
1994 | * bytes 8-11: payload size: size of the frame | ||
1995 | * bytes 12-payloadsize+12: frame data | ||
1996 | */ | ||
1997 | static int save_frame(struct s2255_dev *dev, struct s2255_pipeinfo *pipe_info) | ||
1998 | { | ||
1999 | char *pdest; | ||
2000 | u32 offset = 0; | ||
2001 | int bframe = 0; | ||
2002 | char *psrc; | ||
2003 | unsigned long copy_size; | ||
2004 | unsigned long size; | ||
2005 | s32 idx = -1; | ||
2006 | struct s2255_framei *frm; | ||
2007 | unsigned char *pdata; | ||
2008 | struct s2255_channel *channel; | ||
2009 | dprintk(100, "buffer to user\n"); | ||
2010 | channel = &dev->channel[dev->cc]; | ||
2011 | idx = channel->cur_frame; | ||
2012 | frm = &channel->buffer.frame[idx]; | ||
2013 | if (frm->ulState == S2255_READ_IDLE) { | ||
2014 | int jj; | ||
2015 | unsigned int cc; | ||
2016 | __le32 *pdword; /*data from dsp is little endian */ | ||
2017 | int payload; | ||
2018 | /* search for marker codes */ | ||
2019 | pdata = (unsigned char *)pipe_info->transfer_buffer; | ||
2020 | pdword = (__le32 *)pdata; | ||
2021 | for (jj = 0; jj < (pipe_info->cur_transfer_size - 12); jj++) { | ||
2022 | switch (*pdword) { | ||
2023 | case S2255_MARKER_FRAME: | ||
2024 | dprintk(4, "found frame marker at offset:" | ||
2025 | " %d [%x %x]\n", jj, pdata[0], | ||
2026 | pdata[1]); | ||
2027 | offset = jj + PREFIX_SIZE; | ||
2028 | bframe = 1; | ||
2029 | cc = le32_to_cpu(pdword[1]); | ||
2030 | if (cc >= MAX_CHANNELS) { | ||
2031 | printk(KERN_ERR | ||
2032 | "bad channel\n"); | ||
2033 | return -EINVAL; | ||
2034 | } | ||
2035 | /* reverse it */ | ||
2036 | dev->cc = G_chnmap[cc]; | ||
2037 | channel = &dev->channel[dev->cc]; | ||
2038 | payload = le32_to_cpu(pdword[3]); | ||
2039 | if (payload > channel->req_image_size) { | ||
2040 | channel->bad_payload++; | ||
2041 | /* discard the bad frame */ | ||
2042 | return -EINVAL; | ||
2043 | } | ||
2044 | channel->pkt_size = payload; | ||
2045 | channel->jpg_size = le32_to_cpu(pdword[4]); | ||
2046 | break; | ||
2047 | case S2255_MARKER_RESPONSE: | ||
2048 | |||
2049 | pdata += DEF_USB_BLOCK; | ||
2050 | jj += DEF_USB_BLOCK; | ||
2051 | if (le32_to_cpu(pdword[1]) >= MAX_CHANNELS) | ||
2052 | break; | ||
2053 | cc = G_chnmap[le32_to_cpu(pdword[1])]; | ||
2054 | if (cc >= MAX_CHANNELS) | ||
2055 | break; | ||
2056 | channel = &dev->channel[cc]; | ||
2057 | switch (pdword[2]) { | ||
2058 | case S2255_RESPONSE_SETMODE: | ||
2059 | /* check if channel valid */ | ||
2060 | /* set mode ready */ | ||
2061 | channel->setmode_ready = 1; | ||
2062 | wake_up(&channel->wait_setmode); | ||
2063 | dprintk(5, "setmode ready %d\n", cc); | ||
2064 | break; | ||
2065 | case S2255_RESPONSE_FW: | ||
2066 | dev->chn_ready |= (1 << cc); | ||
2067 | if ((dev->chn_ready & 0x0f) != 0x0f) | ||
2068 | break; | ||
2069 | /* all channels ready */ | ||
2070 | printk(KERN_INFO "s2255: fw loaded\n"); | ||
2071 | atomic_set(&dev->fw_data->fw_state, | ||
2072 | S2255_FW_SUCCESS); | ||
2073 | wake_up(&dev->fw_data->wait_fw); | ||
2074 | break; | ||
2075 | case S2255_RESPONSE_STATUS: | ||
2076 | channel->vidstatus = le32_to_cpu(pdword[3]); | ||
2077 | channel->vidstatus_ready = 1; | ||
2078 | wake_up(&channel->wait_vidstatus); | ||
2079 | dprintk(5, "got vidstatus %x chan %d\n", | ||
2080 | le32_to_cpu(pdword[3]), cc); | ||
2081 | break; | ||
2082 | default: | ||
2083 | printk(KERN_INFO "s2255 unknown resp\n"); | ||
2084 | } | ||
2085 | default: | ||
2086 | pdata++; | ||
2087 | break; | ||
2088 | } | ||
2089 | if (bframe) | ||
2090 | break; | ||
2091 | } /* for */ | ||
2092 | if (!bframe) | ||
2093 | return -EINVAL; | ||
2094 | } | ||
2095 | channel = &dev->channel[dev->cc]; | ||
2096 | idx = channel->cur_frame; | ||
2097 | frm = &channel->buffer.frame[idx]; | ||
2098 | /* search done. now find out if should be acquiring on this channel */ | ||
2099 | if (!channel->b_acquire) { | ||
2100 | /* we found a frame, but this channel is turned off */ | ||
2101 | frm->ulState = S2255_READ_IDLE; | ||
2102 | return -EINVAL; | ||
2103 | } | ||
2104 | |||
2105 | if (frm->ulState == S2255_READ_IDLE) { | ||
2106 | frm->ulState = S2255_READ_FRAME; | ||
2107 | frm->cur_size = 0; | ||
2108 | } | ||
2109 | |||
2110 | /* skip the marker 512 bytes (and offset if out of sync) */ | ||
2111 | psrc = (u8 *)pipe_info->transfer_buffer + offset; | ||
2112 | |||
2113 | |||
2114 | if (frm->lpvbits == NULL) { | ||
2115 | dprintk(1, "s2255 frame buffer == NULL.%p %p %d %d", | ||
2116 | frm, dev, dev->cc, idx); | ||
2117 | return -ENOMEM; | ||
2118 | } | ||
2119 | |||
2120 | pdest = frm->lpvbits + frm->cur_size; | ||
2121 | |||
2122 | copy_size = (pipe_info->cur_transfer_size - offset); | ||
2123 | |||
2124 | size = channel->pkt_size - PREFIX_SIZE; | ||
2125 | |||
2126 | /* sanity check on pdest */ | ||
2127 | if ((copy_size + frm->cur_size) < channel->req_image_size) | ||
2128 | memcpy(pdest, psrc, copy_size); | ||
2129 | |||
2130 | frm->cur_size += copy_size; | ||
2131 | dprintk(4, "cur_size size %lu size %lu \n", frm->cur_size, size); | ||
2132 | |||
2133 | if (frm->cur_size >= size) { | ||
2134 | dprintk(2, "****************[%d]Buffer[%d]full*************\n", | ||
2135 | dev->cc, idx); | ||
2136 | channel->last_frame = channel->cur_frame; | ||
2137 | channel->cur_frame++; | ||
2138 | /* end of system frame ring buffer, start at zero */ | ||
2139 | if ((channel->cur_frame == SYS_FRAMES) || | ||
2140 | (channel->cur_frame == channel->buffer.dwFrames)) | ||
2141 | channel->cur_frame = 0; | ||
2142 | /* frame ready */ | ||
2143 | if (channel->b_acquire) | ||
2144 | s2255_got_frame(channel, channel->jpg_size); | ||
2145 | channel->frame_count++; | ||
2146 | frm->ulState = S2255_READ_IDLE; | ||
2147 | frm->cur_size = 0; | ||
2148 | |||
2149 | } | ||
2150 | /* done successfully */ | ||
2151 | return 0; | ||
2152 | } | ||
2153 | |||
2154 | static void s2255_read_video_callback(struct s2255_dev *dev, | ||
2155 | struct s2255_pipeinfo *pipe_info) | ||
2156 | { | ||
2157 | int res; | ||
2158 | dprintk(50, "callback read video \n"); | ||
2159 | |||
2160 | if (dev->cc >= MAX_CHANNELS) { | ||
2161 | dev->cc = 0; | ||
2162 | dev_err(&dev->udev->dev, "invalid channel\n"); | ||
2163 | return; | ||
2164 | } | ||
2165 | /* otherwise copy to the system buffers */ | ||
2166 | res = save_frame(dev, pipe_info); | ||
2167 | if (res != 0) | ||
2168 | dprintk(4, "s2255: read callback failed\n"); | ||
2169 | |||
2170 | dprintk(50, "callback read video done\n"); | ||
2171 | return; | ||
2172 | } | ||
2173 | |||
2174 | static long s2255_vendor_req(struct s2255_dev *dev, unsigned char Request, | ||
2175 | u16 Index, u16 Value, void *TransferBuffer, | ||
2176 | s32 TransferBufferLength, int bOut) | ||
2177 | { | ||
2178 | int r; | ||
2179 | if (!bOut) { | ||
2180 | r = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0), | ||
2181 | Request, | ||
2182 | USB_TYPE_VENDOR | USB_RECIP_DEVICE | | ||
2183 | USB_DIR_IN, | ||
2184 | Value, Index, TransferBuffer, | ||
2185 | TransferBufferLength, HZ * 5); | ||
2186 | } else { | ||
2187 | r = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0), | ||
2188 | Request, USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
2189 | Value, Index, TransferBuffer, | ||
2190 | TransferBufferLength, HZ * 5); | ||
2191 | } | ||
2192 | return r; | ||
2193 | } | ||
2194 | |||
2195 | /* | ||
2196 | * retrieve FX2 firmware version. future use. | ||
2197 | * @param dev pointer to device extension | ||
2198 | * @return -1 for fail, else returns firmware version as an int(16 bits) | ||
2199 | */ | ||
2200 | static int s2255_get_fx2fw(struct s2255_dev *dev) | ||
2201 | { | ||
2202 | int fw; | ||
2203 | int ret; | ||
2204 | unsigned char transBuffer[64]; | ||
2205 | ret = s2255_vendor_req(dev, S2255_VR_FW, 0, 0, transBuffer, 2, | ||
2206 | S2255_VR_IN); | ||
2207 | if (ret < 0) | ||
2208 | dprintk(2, "get fw error: %x\n", ret); | ||
2209 | fw = transBuffer[0] + (transBuffer[1] << 8); | ||
2210 | dprintk(2, "Get FW %x %x\n", transBuffer[0], transBuffer[1]); | ||
2211 | return fw; | ||
2212 | } | ||
2213 | |||
2214 | /* | ||
2215 | * Create the system ring buffer to copy frames into from the | ||
2216 | * usb read pipe. | ||
2217 | */ | ||
2218 | static int s2255_create_sys_buffers(struct s2255_channel *channel) | ||
2219 | { | ||
2220 | unsigned long i; | ||
2221 | unsigned long reqsize; | ||
2222 | dprintk(1, "create sys buffers\n"); | ||
2223 | channel->buffer.dwFrames = SYS_FRAMES; | ||
2224 | /* always allocate maximum size(PAL) for system buffers */ | ||
2225 | reqsize = SYS_FRAMES_MAXSIZE; | ||
2226 | |||
2227 | if (reqsize > SYS_FRAMES_MAXSIZE) | ||
2228 | reqsize = SYS_FRAMES_MAXSIZE; | ||
2229 | |||
2230 | for (i = 0; i < SYS_FRAMES; i++) { | ||
2231 | /* allocate the frames */ | ||
2232 | channel->buffer.frame[i].lpvbits = vmalloc(reqsize); | ||
2233 | dprintk(1, "valloc %p chan %d, idx %lu, pdata %p\n", | ||
2234 | &channel->buffer.frame[i], channel->idx, i, | ||
2235 | channel->buffer.frame[i].lpvbits); | ||
2236 | channel->buffer.frame[i].size = reqsize; | ||
2237 | if (channel->buffer.frame[i].lpvbits == NULL) { | ||
2238 | printk(KERN_INFO "out of memory. using less frames\n"); | ||
2239 | channel->buffer.dwFrames = i; | ||
2240 | break; | ||
2241 | } | ||
2242 | } | ||
2243 | |||
2244 | /* make sure internal states are set */ | ||
2245 | for (i = 0; i < SYS_FRAMES; i++) { | ||
2246 | channel->buffer.frame[i].ulState = 0; | ||
2247 | channel->buffer.frame[i].cur_size = 0; | ||
2248 | } | ||
2249 | |||
2250 | channel->cur_frame = 0; | ||
2251 | channel->last_frame = -1; | ||
2252 | return 0; | ||
2253 | } | ||
2254 | |||
2255 | static int s2255_release_sys_buffers(struct s2255_channel *channel) | ||
2256 | { | ||
2257 | unsigned long i; | ||
2258 | dprintk(1, "release sys buffers\n"); | ||
2259 | for (i = 0; i < SYS_FRAMES; i++) { | ||
2260 | if (channel->buffer.frame[i].lpvbits) { | ||
2261 | dprintk(1, "vfree %p\n", | ||
2262 | channel->buffer.frame[i].lpvbits); | ||
2263 | vfree(channel->buffer.frame[i].lpvbits); | ||
2264 | } | ||
2265 | channel->buffer.frame[i].lpvbits = NULL; | ||
2266 | } | ||
2267 | return 0; | ||
2268 | } | ||
2269 | |||
2270 | static int s2255_board_init(struct s2255_dev *dev) | ||
2271 | { | ||
2272 | struct s2255_mode mode_def = DEF_MODEI_NTSC_CONT; | ||
2273 | int fw_ver; | ||
2274 | int j; | ||
2275 | struct s2255_pipeinfo *pipe = &dev->pipe; | ||
2276 | dprintk(4, "board init: %p", dev); | ||
2277 | memset(pipe, 0, sizeof(*pipe)); | ||
2278 | pipe->dev = dev; | ||
2279 | pipe->cur_transfer_size = S2255_USB_XFER_SIZE; | ||
2280 | pipe->max_transfer_size = S2255_USB_XFER_SIZE; | ||
2281 | |||
2282 | pipe->transfer_buffer = kzalloc(pipe->max_transfer_size, | ||
2283 | GFP_KERNEL); | ||
2284 | if (pipe->transfer_buffer == NULL) { | ||
2285 | dprintk(1, "out of memory!\n"); | ||
2286 | return -ENOMEM; | ||
2287 | } | ||
2288 | /* query the firmware */ | ||
2289 | fw_ver = s2255_get_fx2fw(dev); | ||
2290 | |||
2291 | printk(KERN_INFO "s2255: usb firmware version %d.%d\n", | ||
2292 | (fw_ver >> 8) & 0xff, | ||
2293 | fw_ver & 0xff); | ||
2294 | |||
2295 | if (fw_ver < S2255_CUR_USB_FWVER) | ||
2296 | printk(KERN_INFO "s2255: newer USB firmware available\n"); | ||
2297 | |||
2298 | for (j = 0; j < MAX_CHANNELS; j++) { | ||
2299 | struct s2255_channel *channel = &dev->channel[j]; | ||
2300 | channel->b_acquire = 0; | ||
2301 | channel->mode = mode_def; | ||
2302 | if (dev->pid == 0x2257 && j > 1) | ||
2303 | channel->mode.color |= (1 << 16); | ||
2304 | channel->jc.quality = S2255_DEF_JPEG_QUAL; | ||
2305 | channel->width = LINE_SZ_4CIFS_NTSC; | ||
2306 | channel->height = NUM_LINES_4CIFS_NTSC * 2; | ||
2307 | channel->fmt = &formats[0]; | ||
2308 | channel->mode.restart = 1; | ||
2309 | channel->req_image_size = get_transfer_size(&mode_def); | ||
2310 | channel->frame_count = 0; | ||
2311 | /* create the system buffers */ | ||
2312 | s2255_create_sys_buffers(channel); | ||
2313 | } | ||
2314 | /* start read pipe */ | ||
2315 | s2255_start_readpipe(dev); | ||
2316 | dprintk(1, "%s: success\n", __func__); | ||
2317 | return 0; | ||
2318 | } | ||
2319 | |||
2320 | static int s2255_board_shutdown(struct s2255_dev *dev) | ||
2321 | { | ||
2322 | u32 i; | ||
2323 | dprintk(1, "%s: dev: %p", __func__, dev); | ||
2324 | |||
2325 | for (i = 0; i < MAX_CHANNELS; i++) { | ||
2326 | if (dev->channel[i].b_acquire) | ||
2327 | s2255_stop_acquire(&dev->channel[i]); | ||
2328 | } | ||
2329 | s2255_stop_readpipe(dev); | ||
2330 | for (i = 0; i < MAX_CHANNELS; i++) | ||
2331 | s2255_release_sys_buffers(&dev->channel[i]); | ||
2332 | /* release transfer buffer */ | ||
2333 | kfree(dev->pipe.transfer_buffer); | ||
2334 | return 0; | ||
2335 | } | ||
2336 | |||
2337 | static void read_pipe_completion(struct urb *purb) | ||
2338 | { | ||
2339 | struct s2255_pipeinfo *pipe_info; | ||
2340 | struct s2255_dev *dev; | ||
2341 | int status; | ||
2342 | int pipe; | ||
2343 | pipe_info = purb->context; | ||
2344 | dprintk(100, "%s: urb:%p, status %d\n", __func__, purb, | ||
2345 | purb->status); | ||
2346 | if (pipe_info == NULL) { | ||
2347 | dev_err(&purb->dev->dev, "no context!\n"); | ||
2348 | return; | ||
2349 | } | ||
2350 | |||
2351 | dev = pipe_info->dev; | ||
2352 | if (dev == NULL) { | ||
2353 | dev_err(&purb->dev->dev, "no context!\n"); | ||
2354 | return; | ||
2355 | } | ||
2356 | status = purb->status; | ||
2357 | /* if shutting down, do not resubmit, exit immediately */ | ||
2358 | if (status == -ESHUTDOWN) { | ||
2359 | dprintk(2, "%s: err shutdown\n", __func__); | ||
2360 | pipe_info->err_count++; | ||
2361 | return; | ||
2362 | } | ||
2363 | |||
2364 | if (pipe_info->state == 0) { | ||
2365 | dprintk(2, "%s: exiting USB pipe", __func__); | ||
2366 | return; | ||
2367 | } | ||
2368 | |||
2369 | if (status == 0) | ||
2370 | s2255_read_video_callback(dev, pipe_info); | ||
2371 | else { | ||
2372 | pipe_info->err_count++; | ||
2373 | dprintk(1, "%s: failed URB %d\n", __func__, status); | ||
2374 | } | ||
2375 | |||
2376 | pipe = usb_rcvbulkpipe(dev->udev, dev->read_endpoint); | ||
2377 | /* reuse urb */ | ||
2378 | usb_fill_bulk_urb(pipe_info->stream_urb, dev->udev, | ||
2379 | pipe, | ||
2380 | pipe_info->transfer_buffer, | ||
2381 | pipe_info->cur_transfer_size, | ||
2382 | read_pipe_completion, pipe_info); | ||
2383 | |||
2384 | if (pipe_info->state != 0) { | ||
2385 | if (usb_submit_urb(pipe_info->stream_urb, GFP_ATOMIC)) { | ||
2386 | dev_err(&dev->udev->dev, "error submitting urb\n"); | ||
2387 | } | ||
2388 | } else { | ||
2389 | dprintk(2, "%s :complete state 0\n", __func__); | ||
2390 | } | ||
2391 | return; | ||
2392 | } | ||
2393 | |||
2394 | static int s2255_start_readpipe(struct s2255_dev *dev) | ||
2395 | { | ||
2396 | int pipe; | ||
2397 | int retval; | ||
2398 | struct s2255_pipeinfo *pipe_info = &dev->pipe; | ||
2399 | pipe = usb_rcvbulkpipe(dev->udev, dev->read_endpoint); | ||
2400 | dprintk(2, "%s: IN %d\n", __func__, dev->read_endpoint); | ||
2401 | pipe_info->state = 1; | ||
2402 | pipe_info->err_count = 0; | ||
2403 | pipe_info->stream_urb = usb_alloc_urb(0, GFP_KERNEL); | ||
2404 | if (!pipe_info->stream_urb) { | ||
2405 | dev_err(&dev->udev->dev, | ||
2406 | "ReadStream: Unable to alloc URB\n"); | ||
2407 | return -ENOMEM; | ||
2408 | } | ||
2409 | /* transfer buffer allocated in board_init */ | ||
2410 | usb_fill_bulk_urb(pipe_info->stream_urb, dev->udev, | ||
2411 | pipe, | ||
2412 | pipe_info->transfer_buffer, | ||
2413 | pipe_info->cur_transfer_size, | ||
2414 | read_pipe_completion, pipe_info); | ||
2415 | retval = usb_submit_urb(pipe_info->stream_urb, GFP_KERNEL); | ||
2416 | if (retval) { | ||
2417 | printk(KERN_ERR "s2255: start read pipe failed\n"); | ||
2418 | return retval; | ||
2419 | } | ||
2420 | return 0; | ||
2421 | } | ||
2422 | |||
2423 | /* starts acquisition process */ | ||
2424 | static int s2255_start_acquire(struct s2255_channel *channel) | ||
2425 | { | ||
2426 | unsigned char *buffer; | ||
2427 | int res; | ||
2428 | unsigned long chn_rev; | ||
2429 | int j; | ||
2430 | struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev); | ||
2431 | chn_rev = G_chnmap[channel->idx]; | ||
2432 | buffer = kzalloc(512, GFP_KERNEL); | ||
2433 | if (buffer == NULL) { | ||
2434 | dev_err(&dev->udev->dev, "out of mem\n"); | ||
2435 | return -ENOMEM; | ||
2436 | } | ||
2437 | |||
2438 | channel->last_frame = -1; | ||
2439 | channel->bad_payload = 0; | ||
2440 | channel->cur_frame = 0; | ||
2441 | for (j = 0; j < SYS_FRAMES; j++) { | ||
2442 | channel->buffer.frame[j].ulState = 0; | ||
2443 | channel->buffer.frame[j].cur_size = 0; | ||
2444 | } | ||
2445 | |||
2446 | /* send the start command */ | ||
2447 | *(__le32 *) buffer = IN_DATA_TOKEN; | ||
2448 | *((__le32 *) buffer + 1) = (__le32) cpu_to_le32(chn_rev); | ||
2449 | *((__le32 *) buffer + 2) = CMD_START; | ||
2450 | res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512); | ||
2451 | if (res != 0) | ||
2452 | dev_err(&dev->udev->dev, "CMD_START error\n"); | ||
2453 | |||
2454 | dprintk(2, "start acquire exit[%d] %d \n", channel->idx, res); | ||
2455 | kfree(buffer); | ||
2456 | return 0; | ||
2457 | } | ||
2458 | |||
2459 | static int s2255_stop_acquire(struct s2255_channel *channel) | ||
2460 | { | ||
2461 | unsigned char *buffer; | ||
2462 | int res; | ||
2463 | unsigned long chn_rev; | ||
2464 | struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev); | ||
2465 | chn_rev = G_chnmap[channel->idx]; | ||
2466 | buffer = kzalloc(512, GFP_KERNEL); | ||
2467 | if (buffer == NULL) { | ||
2468 | dev_err(&dev->udev->dev, "out of mem\n"); | ||
2469 | return -ENOMEM; | ||
2470 | } | ||
2471 | /* send the stop command */ | ||
2472 | *(__le32 *) buffer = IN_DATA_TOKEN; | ||
2473 | *((__le32 *) buffer + 1) = (__le32) cpu_to_le32(chn_rev); | ||
2474 | *((__le32 *) buffer + 2) = CMD_STOP; | ||
2475 | res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512); | ||
2476 | if (res != 0) | ||
2477 | dev_err(&dev->udev->dev, "CMD_STOP error\n"); | ||
2478 | kfree(buffer); | ||
2479 | channel->b_acquire = 0; | ||
2480 | dprintk(4, "%s: chn %d, res %d\n", __func__, channel->idx, res); | ||
2481 | return res; | ||
2482 | } | ||
2483 | |||
2484 | static void s2255_stop_readpipe(struct s2255_dev *dev) | ||
2485 | { | ||
2486 | struct s2255_pipeinfo *pipe = &dev->pipe; | ||
2487 | |||
2488 | pipe->state = 0; | ||
2489 | if (pipe->stream_urb) { | ||
2490 | /* cancel urb */ | ||
2491 | usb_kill_urb(pipe->stream_urb); | ||
2492 | usb_free_urb(pipe->stream_urb); | ||
2493 | pipe->stream_urb = NULL; | ||
2494 | } | ||
2495 | dprintk(4, "%s", __func__); | ||
2496 | return; | ||
2497 | } | ||
2498 | |||
2499 | static void s2255_fwload_start(struct s2255_dev *dev, int reset) | ||
2500 | { | ||
2501 | if (reset) | ||
2502 | s2255_reset_dsppower(dev); | ||
2503 | dev->fw_data->fw_size = dev->fw_data->fw->size; | ||
2504 | atomic_set(&dev->fw_data->fw_state, S2255_FW_NOTLOADED); | ||
2505 | memcpy(dev->fw_data->pfw_data, | ||
2506 | dev->fw_data->fw->data, CHUNK_SIZE); | ||
2507 | dev->fw_data->fw_loaded = CHUNK_SIZE; | ||
2508 | usb_fill_bulk_urb(dev->fw_data->fw_urb, dev->udev, | ||
2509 | usb_sndbulkpipe(dev->udev, 2), | ||
2510 | dev->fw_data->pfw_data, | ||
2511 | CHUNK_SIZE, s2255_fwchunk_complete, | ||
2512 | dev->fw_data); | ||
2513 | mod_timer(&dev->timer, jiffies + HZ); | ||
2514 | } | ||
2515 | |||
2516 | /* standard usb probe function */ | ||
2517 | static int s2255_probe(struct usb_interface *interface, | ||
2518 | const struct usb_device_id *id) | ||
2519 | { | ||
2520 | struct s2255_dev *dev = NULL; | ||
2521 | struct usb_host_interface *iface_desc; | ||
2522 | struct usb_endpoint_descriptor *endpoint; | ||
2523 | int i; | ||
2524 | int retval = -ENOMEM; | ||
2525 | __le32 *pdata; | ||
2526 | int fw_size; | ||
2527 | dprintk(2, "%s\n", __func__); | ||
2528 | /* allocate memory for our device state and initialize it to zero */ | ||
2529 | dev = kzalloc(sizeof(struct s2255_dev), GFP_KERNEL); | ||
2530 | if (dev == NULL) { | ||
2531 | s2255_dev_err(&interface->dev, "out of memory\n"); | ||
2532 | return -ENOMEM; | ||
2533 | } | ||
2534 | atomic_set(&dev->num_channels, 0); | ||
2535 | dev->pid = id->idProduct; | ||
2536 | dev->fw_data = kzalloc(sizeof(struct s2255_fw), GFP_KERNEL); | ||
2537 | if (!dev->fw_data) | ||
2538 | goto errorFWDATA1; | ||
2539 | mutex_init(&dev->lock); | ||
2540 | /* grab usb_device and save it */ | ||
2541 | dev->udev = usb_get_dev(interface_to_usbdev(interface)); | ||
2542 | if (dev->udev == NULL) { | ||
2543 | dev_err(&interface->dev, "null usb device\n"); | ||
2544 | retval = -ENODEV; | ||
2545 | goto errorUDEV; | ||
2546 | } | ||
2547 | dprintk(1, "dev: %p, udev %p interface %p\n", dev, | ||
2548 | dev->udev, interface); | ||
2549 | dev->interface = interface; | ||
2550 | /* set up the endpoint information */ | ||
2551 | iface_desc = interface->cur_altsetting; | ||
2552 | dprintk(1, "num endpoints %d\n", iface_desc->desc.bNumEndpoints); | ||
2553 | for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { | ||
2554 | endpoint = &iface_desc->endpoint[i].desc; | ||
2555 | if (!dev->read_endpoint && usb_endpoint_is_bulk_in(endpoint)) { | ||
2556 | /* we found the bulk in endpoint */ | ||
2557 | dev->read_endpoint = endpoint->bEndpointAddress; | ||
2558 | } | ||
2559 | } | ||
2560 | |||
2561 | if (!dev->read_endpoint) { | ||
2562 | dev_err(&interface->dev, "Could not find bulk-in endpoint\n"); | ||
2563 | goto errorEP; | ||
2564 | } | ||
2565 | init_timer(&dev->timer); | ||
2566 | dev->timer.function = s2255_timer; | ||
2567 | dev->timer.data = (unsigned long)dev->fw_data; | ||
2568 | init_waitqueue_head(&dev->fw_data->wait_fw); | ||
2569 | for (i = 0; i < MAX_CHANNELS; i++) { | ||
2570 | struct s2255_channel *channel = &dev->channel[i]; | ||
2571 | dev->channel[i].idx = i; | ||
2572 | init_waitqueue_head(&channel->wait_setmode); | ||
2573 | init_waitqueue_head(&channel->wait_vidstatus); | ||
2574 | } | ||
2575 | |||
2576 | dev->fw_data->fw_urb = usb_alloc_urb(0, GFP_KERNEL); | ||
2577 | if (!dev->fw_data->fw_urb) { | ||
2578 | dev_err(&interface->dev, "out of memory!\n"); | ||
2579 | goto errorFWURB; | ||
2580 | } | ||
2581 | |||
2582 | dev->fw_data->pfw_data = kzalloc(CHUNK_SIZE, GFP_KERNEL); | ||
2583 | if (!dev->fw_data->pfw_data) { | ||
2584 | dev_err(&interface->dev, "out of memory!\n"); | ||
2585 | goto errorFWDATA2; | ||
2586 | } | ||
2587 | /* load the first chunk */ | ||
2588 | if (request_firmware(&dev->fw_data->fw, | ||
2589 | FIRMWARE_FILE_NAME, &dev->udev->dev)) { | ||
2590 | printk(KERN_ERR "sensoray 2255 failed to get firmware\n"); | ||
2591 | goto errorREQFW; | ||
2592 | } | ||
2593 | /* check the firmware is valid */ | ||
2594 | fw_size = dev->fw_data->fw->size; | ||
2595 | pdata = (__le32 *) &dev->fw_data->fw->data[fw_size - 8]; | ||
2596 | |||
2597 | if (*pdata != S2255_FW_MARKER) { | ||
2598 | printk(KERN_INFO "Firmware invalid.\n"); | ||
2599 | retval = -ENODEV; | ||
2600 | goto errorFWMARKER; | ||
2601 | } else { | ||
2602 | /* make sure firmware is the latest */ | ||
2603 | __le32 *pRel; | ||
2604 | pRel = (__le32 *) &dev->fw_data->fw->data[fw_size - 4]; | ||
2605 | printk(KERN_INFO "s2255 dsp fw version %x\n", *pRel); | ||
2606 | dev->dsp_fw_ver = le32_to_cpu(*pRel); | ||
2607 | if (dev->dsp_fw_ver < S2255_CUR_DSP_FWVER) | ||
2608 | printk(KERN_INFO "s2255: f2255usb.bin out of date.\n"); | ||
2609 | if (dev->pid == 0x2257 && | ||
2610 | dev->dsp_fw_ver < S2255_MIN_DSP_COLORFILTER) | ||
2611 | printk(KERN_WARNING "s2255: 2257 requires firmware %d" | ||
2612 | " or above.\n", S2255_MIN_DSP_COLORFILTER); | ||
2613 | } | ||
2614 | usb_reset_device(dev->udev); | ||
2615 | /* load 2255 board specific */ | ||
2616 | retval = s2255_board_init(dev); | ||
2617 | if (retval) | ||
2618 | goto errorBOARDINIT; | ||
2619 | spin_lock_init(&dev->slock); | ||
2620 | s2255_fwload_start(dev, 0); | ||
2621 | /* loads v4l specific */ | ||
2622 | retval = s2255_probe_v4l(dev); | ||
2623 | if (retval) | ||
2624 | goto errorBOARDINIT; | ||
2625 | dev_info(&interface->dev, "Sensoray 2255 detected\n"); | ||
2626 | return 0; | ||
2627 | errorBOARDINIT: | ||
2628 | s2255_board_shutdown(dev); | ||
2629 | errorFWMARKER: | ||
2630 | release_firmware(dev->fw_data->fw); | ||
2631 | errorREQFW: | ||
2632 | kfree(dev->fw_data->pfw_data); | ||
2633 | errorFWDATA2: | ||
2634 | usb_free_urb(dev->fw_data->fw_urb); | ||
2635 | errorFWURB: | ||
2636 | del_timer(&dev->timer); | ||
2637 | errorEP: | ||
2638 | usb_put_dev(dev->udev); | ||
2639 | errorUDEV: | ||
2640 | kfree(dev->fw_data); | ||
2641 | mutex_destroy(&dev->lock); | ||
2642 | errorFWDATA1: | ||
2643 | kfree(dev); | ||
2644 | printk(KERN_WARNING "Sensoray 2255 driver load failed: 0x%x\n", retval); | ||
2645 | return retval; | ||
2646 | } | ||
2647 | |||
2648 | /* disconnect routine. when board is removed physically or with rmmod */ | ||
2649 | static void s2255_disconnect(struct usb_interface *interface) | ||
2650 | { | ||
2651 | struct s2255_dev *dev = to_s2255_dev(usb_get_intfdata(interface)); | ||
2652 | int i; | ||
2653 | int channels = atomic_read(&dev->num_channels); | ||
2654 | mutex_lock(&dev->lock); | ||
2655 | v4l2_device_disconnect(&dev->v4l2_dev); | ||
2656 | mutex_unlock(&dev->lock); | ||
2657 | /*see comments in the uvc_driver.c usb disconnect function */ | ||
2658 | atomic_inc(&dev->num_channels); | ||
2659 | /* unregister each video device. */ | ||
2660 | for (i = 0; i < channels; i++) | ||
2661 | video_unregister_device(&dev->channel[i].vdev); | ||
2662 | /* wake up any of our timers */ | ||
2663 | atomic_set(&dev->fw_data->fw_state, S2255_FW_DISCONNECTING); | ||
2664 | wake_up(&dev->fw_data->wait_fw); | ||
2665 | for (i = 0; i < MAX_CHANNELS; i++) { | ||
2666 | dev->channel[i].setmode_ready = 1; | ||
2667 | wake_up(&dev->channel[i].wait_setmode); | ||
2668 | dev->channel[i].vidstatus_ready = 1; | ||
2669 | wake_up(&dev->channel[i].wait_vidstatus); | ||
2670 | } | ||
2671 | if (atomic_dec_and_test(&dev->num_channels)) | ||
2672 | s2255_destroy(dev); | ||
2673 | dev_info(&interface->dev, "%s\n", __func__); | ||
2674 | } | ||
2675 | |||
2676 | static struct usb_driver s2255_driver = { | ||
2677 | .name = S2255_DRIVER_NAME, | ||
2678 | .probe = s2255_probe, | ||
2679 | .disconnect = s2255_disconnect, | ||
2680 | .id_table = s2255_table, | ||
2681 | }; | ||
2682 | |||
2683 | module_usb_driver(s2255_driver); | ||
2684 | |||
2685 | MODULE_DESCRIPTION("Sensoray 2255 Video for Linux driver"); | ||
2686 | MODULE_AUTHOR("Dean Anderson (Sensoray Company Inc.)"); | ||
2687 | MODULE_LICENSE("GPL"); | ||
2688 | MODULE_VERSION(S2255_VERSION); | ||
2689 | MODULE_FIRMWARE(FIRMWARE_FILE_NAME); | ||
diff --git a/drivers/media/video/stk-sensor.c b/drivers/media/video/stk-sensor.c deleted file mode 100644 index e546b014d7ad..000000000000 --- a/drivers/media/video/stk-sensor.c +++ /dev/null | |||
@@ -1,595 +0,0 @@ | |||
1 | /* stk-sensor.c: Driver for ov96xx sensor (used in some Syntek webcams) | ||
2 | * | ||
3 | * Copyright 2007-2008 Jaime Velasco Juan <jsagarribay@gmail.com> | ||
4 | * | ||
5 | * Some parts derived from ov7670.c: | ||
6 | * Copyright 2006 One Laptop Per Child Association, Inc. Written | ||
7 | * by Jonathan Corbet with substantial inspiration from Mark | ||
8 | * McClelland's ovcamchip code. | ||
9 | * | ||
10 | * Copyright 2006-7 Jonathan Corbet <corbet@lwn.net> | ||
11 | * | ||
12 | * This file may be distributed under the terms of the GNU General | ||
13 | * This program is free software; you can redistribute it and/or modify | ||
14 | * it under the terms of the GNU General Public License as published by | ||
15 | * the Free Software Foundation; either version 2 of the License, or | ||
16 | * (at your option) any later version. | ||
17 | * | ||
18 | * This program is distributed in the hope that it will be useful, | ||
19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
21 | * GNU General Public License for more details. | ||
22 | * | ||
23 | * You should have received a copy of the GNU General Public License | ||
24 | * along with this program; if not, write to the Free Software | ||
25 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
26 | */ | ||
27 | |||
28 | /* Controlling the sensor via the STK1125 vendor specific control interface: | ||
29 | * The camera uses an OmniVision sensor and the stk1125 provides an | ||
30 | * SCCB(i2c)-USB bridge which let us program the sensor. | ||
31 | * In my case the sensor id is 0x9652, it can be read from sensor's register | ||
32 | * 0x0A and 0x0B as follows: | ||
33 | * - read register #R: | ||
34 | * output #R to index 0x0208 | ||
35 | * output 0x0070 to index 0x0200 | ||
36 | * input 1 byte from index 0x0201 (some kind of status register) | ||
37 | * until its value is 0x01 | ||
38 | * input 1 byte from index 0x0209. This is the value of #R | ||
39 | * - write value V to register #R | ||
40 | * output #R to index 0x0204 | ||
41 | * output V to index 0x0205 | ||
42 | * output 0x0005 to index 0x0200 | ||
43 | * input 1 byte from index 0x0201 until its value becomes 0x04 | ||
44 | */ | ||
45 | |||
46 | /* It seems the i2c bus is controlled with these registers */ | ||
47 | |||
48 | #include "stk-webcam.h" | ||
49 | |||
50 | #define STK_IIC_BASE (0x0200) | ||
51 | # define STK_IIC_OP (STK_IIC_BASE) | ||
52 | # define STK_IIC_OP_TX (0x05) | ||
53 | # define STK_IIC_OP_RX (0x70) | ||
54 | # define STK_IIC_STAT (STK_IIC_BASE+1) | ||
55 | # define STK_IIC_STAT_TX_OK (0x04) | ||
56 | # define STK_IIC_STAT_RX_OK (0x01) | ||
57 | /* I don't know what does this register. | ||
58 | * when it is 0x00 or 0x01, we cannot talk to the sensor, | ||
59 | * other values work */ | ||
60 | # define STK_IIC_ENABLE (STK_IIC_BASE+2) | ||
61 | # define STK_IIC_ENABLE_NO (0x00) | ||
62 | /* This is what the driver writes in windows */ | ||
63 | # define STK_IIC_ENABLE_YES (0x1e) | ||
64 | /* | ||
65 | * Address of the slave. Seems like the binary driver look for the | ||
66 | * sensor in multiple places, attempting a reset sequence. | ||
67 | * We only know about the ov9650 | ||
68 | */ | ||
69 | # define STK_IIC_ADDR (STK_IIC_BASE+3) | ||
70 | # define STK_IIC_TX_INDEX (STK_IIC_BASE+4) | ||
71 | # define STK_IIC_TX_VALUE (STK_IIC_BASE+5) | ||
72 | # define STK_IIC_RX_INDEX (STK_IIC_BASE+8) | ||
73 | # define STK_IIC_RX_VALUE (STK_IIC_BASE+9) | ||
74 | |||
75 | #define MAX_RETRIES (50) | ||
76 | |||
77 | #define SENSOR_ADDRESS (0x60) | ||
78 | |||
79 | /* From ov7670.c (These registers aren't fully accurate) */ | ||
80 | |||
81 | /* Registers */ | ||
82 | #define REG_GAIN 0x00 /* Gain lower 8 bits (rest in vref) */ | ||
83 | #define REG_BLUE 0x01 /* blue gain */ | ||
84 | #define REG_RED 0x02 /* red gain */ | ||
85 | #define REG_VREF 0x03 /* Pieces of GAIN, VSTART, VSTOP */ | ||
86 | #define REG_COM1 0x04 /* Control 1 */ | ||
87 | #define COM1_CCIR656 0x40 /* CCIR656 enable */ | ||
88 | #define COM1_QFMT 0x20 /* QVGA/QCIF format */ | ||
89 | #define COM1_SKIP_0 0x00 /* Do not skip any row */ | ||
90 | #define COM1_SKIP_2 0x04 /* Skip 2 rows of 4 */ | ||
91 | #define COM1_SKIP_3 0x08 /* Skip 3 rows of 4 */ | ||
92 | #define REG_BAVE 0x05 /* U/B Average level */ | ||
93 | #define REG_GbAVE 0x06 /* Y/Gb Average level */ | ||
94 | #define REG_AECHH 0x07 /* AEC MS 5 bits */ | ||
95 | #define REG_RAVE 0x08 /* V/R Average level */ | ||
96 | #define REG_COM2 0x09 /* Control 2 */ | ||
97 | #define COM2_SSLEEP 0x10 /* Soft sleep mode */ | ||
98 | #define REG_PID 0x0a /* Product ID MSB */ | ||
99 | #define REG_VER 0x0b /* Product ID LSB */ | ||
100 | #define REG_COM3 0x0c /* Control 3 */ | ||
101 | #define COM3_SWAP 0x40 /* Byte swap */ | ||
102 | #define COM3_SCALEEN 0x08 /* Enable scaling */ | ||
103 | #define COM3_DCWEN 0x04 /* Enable downsamp/crop/window */ | ||
104 | #define REG_COM4 0x0d /* Control 4 */ | ||
105 | #define REG_COM5 0x0e /* All "reserved" */ | ||
106 | #define REG_COM6 0x0f /* Control 6 */ | ||
107 | #define REG_AECH 0x10 /* More bits of AEC value */ | ||
108 | #define REG_CLKRC 0x11 /* Clock control */ | ||
109 | #define CLK_PLL 0x80 /* Enable internal PLL */ | ||
110 | #define CLK_EXT 0x40 /* Use external clock directly */ | ||
111 | #define CLK_SCALE 0x3f /* Mask for internal clock scale */ | ||
112 | #define REG_COM7 0x12 /* Control 7 */ | ||
113 | #define COM7_RESET 0x80 /* Register reset */ | ||
114 | #define COM7_FMT_MASK 0x38 | ||
115 | #define COM7_FMT_SXGA 0x00 | ||
116 | #define COM7_FMT_VGA 0x40 | ||
117 | #define COM7_FMT_CIF 0x20 /* CIF format */ | ||
118 | #define COM7_FMT_QVGA 0x10 /* QVGA format */ | ||
119 | #define COM7_FMT_QCIF 0x08 /* QCIF format */ | ||
120 | #define COM7_RGB 0x04 /* bits 0 and 2 - RGB format */ | ||
121 | #define COM7_YUV 0x00 /* YUV */ | ||
122 | #define COM7_BAYER 0x01 /* Bayer format */ | ||
123 | #define COM7_PBAYER 0x05 /* "Processed bayer" */ | ||
124 | #define REG_COM8 0x13 /* Control 8 */ | ||
125 | #define COM8_FASTAEC 0x80 /* Enable fast AGC/AEC */ | ||
126 | #define COM8_AECSTEP 0x40 /* Unlimited AEC step size */ | ||
127 | #define COM8_BFILT 0x20 /* Band filter enable */ | ||
128 | #define COM8_AGC 0x04 /* Auto gain enable */ | ||
129 | #define COM8_AWB 0x02 /* White balance enable */ | ||
130 | #define COM8_AEC 0x01 /* Auto exposure enable */ | ||
131 | #define REG_COM9 0x14 /* Control 9 - gain ceiling */ | ||
132 | #define REG_COM10 0x15 /* Control 10 */ | ||
133 | #define COM10_HSYNC 0x40 /* HSYNC instead of HREF */ | ||
134 | #define COM10_PCLK_HB 0x20 /* Suppress PCLK on horiz blank */ | ||
135 | #define COM10_HREF_REV 0x08 /* Reverse HREF */ | ||
136 | #define COM10_VS_LEAD 0x04 /* VSYNC on clock leading edge */ | ||
137 | #define COM10_VS_NEG 0x02 /* VSYNC negative */ | ||
138 | #define COM10_HS_NEG 0x01 /* HSYNC negative */ | ||
139 | #define REG_HSTART 0x17 /* Horiz start high bits */ | ||
140 | #define REG_HSTOP 0x18 /* Horiz stop high bits */ | ||
141 | #define REG_VSTART 0x19 /* Vert start high bits */ | ||
142 | #define REG_VSTOP 0x1a /* Vert stop high bits */ | ||
143 | #define REG_PSHFT 0x1b /* Pixel delay after HREF */ | ||
144 | #define REG_MIDH 0x1c /* Manuf. ID high */ | ||
145 | #define REG_MIDL 0x1d /* Manuf. ID low */ | ||
146 | #define REG_MVFP 0x1e /* Mirror / vflip */ | ||
147 | #define MVFP_MIRROR 0x20 /* Mirror image */ | ||
148 | #define MVFP_FLIP 0x10 /* Vertical flip */ | ||
149 | |||
150 | #define REG_AEW 0x24 /* AGC upper limit */ | ||
151 | #define REG_AEB 0x25 /* AGC lower limit */ | ||
152 | #define REG_VPT 0x26 /* AGC/AEC fast mode op region */ | ||
153 | #define REG_ADVFL 0x2d /* Insert dummy lines (LSB) */ | ||
154 | #define REG_ADVFH 0x2e /* Insert dummy lines (MSB) */ | ||
155 | #define REG_HSYST 0x30 /* HSYNC rising edge delay */ | ||
156 | #define REG_HSYEN 0x31 /* HSYNC falling edge delay */ | ||
157 | #define REG_HREF 0x32 /* HREF pieces */ | ||
158 | #define REG_TSLB 0x3a /* lots of stuff */ | ||
159 | #define TSLB_YLAST 0x04 /* UYVY or VYUY - see com13 */ | ||
160 | #define TSLB_BYTEORD 0x08 /* swap bytes in 16bit mode? */ | ||
161 | #define REG_COM11 0x3b /* Control 11 */ | ||
162 | #define COM11_NIGHT 0x80 /* NIght mode enable */ | ||
163 | #define COM11_NMFR 0x60 /* Two bit NM frame rate */ | ||
164 | #define COM11_HZAUTO 0x10 /* Auto detect 50/60 Hz */ | ||
165 | #define COM11_50HZ 0x08 /* Manual 50Hz select */ | ||
166 | #define COM11_EXP 0x02 | ||
167 | #define REG_COM12 0x3c /* Control 12 */ | ||
168 | #define COM12_HREF 0x80 /* HREF always */ | ||
169 | #define REG_COM13 0x3d /* Control 13 */ | ||
170 | #define COM13_GAMMA 0x80 /* Gamma enable */ | ||
171 | #define COM13_UVSAT 0x40 /* UV saturation auto adjustment */ | ||
172 | #define COM13_CMATRIX 0x10 /* Enable color matrix for RGB or YUV */ | ||
173 | #define COM13_UVSWAP 0x01 /* V before U - w/TSLB */ | ||
174 | #define REG_COM14 0x3e /* Control 14 */ | ||
175 | #define COM14_DCWEN 0x10 /* DCW/PCLK-scale enable */ | ||
176 | #define REG_EDGE 0x3f /* Edge enhancement factor */ | ||
177 | #define REG_COM15 0x40 /* Control 15 */ | ||
178 | #define COM15_R10F0 0x00 /* Data range 10 to F0 */ | ||
179 | #define COM15_R01FE 0x80 /* 01 to FE */ | ||
180 | #define COM15_R00FF 0xc0 /* 00 to FF */ | ||
181 | #define COM15_RGB565 0x10 /* RGB565 output */ | ||
182 | #define COM15_RGBFIXME 0x20 /* FIXME */ | ||
183 | #define COM15_RGB555 0x30 /* RGB555 output */ | ||
184 | #define REG_COM16 0x41 /* Control 16 */ | ||
185 | #define COM16_AWBGAIN 0x08 /* AWB gain enable */ | ||
186 | #define REG_COM17 0x42 /* Control 17 */ | ||
187 | #define COM17_AECWIN 0xc0 /* AEC window - must match COM4 */ | ||
188 | #define COM17_CBAR 0x08 /* DSP Color bar */ | ||
189 | |||
190 | /* | ||
191 | * This matrix defines how the colors are generated, must be | ||
192 | * tweaked to adjust hue and saturation. | ||
193 | * | ||
194 | * Order: v-red, v-green, v-blue, u-red, u-green, u-blue | ||
195 | * | ||
196 | * They are nine-bit signed quantities, with the sign bit | ||
197 | * stored in 0x58. Sign for v-red is bit 0, and up from there. | ||
198 | */ | ||
199 | #define REG_CMATRIX_BASE 0x4f | ||
200 | #define CMATRIX_LEN 6 | ||
201 | #define REG_CMATRIX_SIGN 0x58 | ||
202 | |||
203 | |||
204 | #define REG_BRIGHT 0x55 /* Brightness */ | ||
205 | #define REG_CONTRAS 0x56 /* Contrast control */ | ||
206 | |||
207 | #define REG_GFIX 0x69 /* Fix gain control */ | ||
208 | |||
209 | #define REG_RGB444 0x8c /* RGB 444 control */ | ||
210 | #define R444_ENABLE 0x02 /* Turn on RGB444, overrides 5x5 */ | ||
211 | #define R444_RGBX 0x01 /* Empty nibble at end */ | ||
212 | |||
213 | #define REG_HAECC1 0x9f /* Hist AEC/AGC control 1 */ | ||
214 | #define REG_HAECC2 0xa0 /* Hist AEC/AGC control 2 */ | ||
215 | |||
216 | #define REG_BD50MAX 0xa5 /* 50hz banding step limit */ | ||
217 | #define REG_HAECC3 0xa6 /* Hist AEC/AGC control 3 */ | ||
218 | #define REG_HAECC4 0xa7 /* Hist AEC/AGC control 4 */ | ||
219 | #define REG_HAECC5 0xa8 /* Hist AEC/AGC control 5 */ | ||
220 | #define REG_HAECC6 0xa9 /* Hist AEC/AGC control 6 */ | ||
221 | #define REG_HAECC7 0xaa /* Hist AEC/AGC control 7 */ | ||
222 | #define REG_BD60MAX 0xab /* 60hz banding step limit */ | ||
223 | |||
224 | |||
225 | |||
226 | |||
227 | /* Returns 0 if OK */ | ||
228 | static int stk_sensor_outb(struct stk_camera *dev, u8 reg, u8 val) | ||
229 | { | ||
230 | int i = 0; | ||
231 | int tmpval = 0; | ||
232 | |||
233 | if (stk_camera_write_reg(dev, STK_IIC_TX_INDEX, reg)) | ||
234 | return 1; | ||
235 | if (stk_camera_write_reg(dev, STK_IIC_TX_VALUE, val)) | ||
236 | return 1; | ||
237 | if (stk_camera_write_reg(dev, STK_IIC_OP, STK_IIC_OP_TX)) | ||
238 | return 1; | ||
239 | do { | ||
240 | if (stk_camera_read_reg(dev, STK_IIC_STAT, &tmpval)) | ||
241 | return 1; | ||
242 | i++; | ||
243 | } while (tmpval == 0 && i < MAX_RETRIES); | ||
244 | if (tmpval != STK_IIC_STAT_TX_OK) { | ||
245 | if (tmpval) | ||
246 | STK_ERROR("stk_sensor_outb failed, status=0x%02x\n", | ||
247 | tmpval); | ||
248 | return 1; | ||
249 | } else | ||
250 | return 0; | ||
251 | } | ||
252 | |||
253 | static int stk_sensor_inb(struct stk_camera *dev, u8 reg, u8 *val) | ||
254 | { | ||
255 | int i = 0; | ||
256 | int tmpval = 0; | ||
257 | |||
258 | if (stk_camera_write_reg(dev, STK_IIC_RX_INDEX, reg)) | ||
259 | return 1; | ||
260 | if (stk_camera_write_reg(dev, STK_IIC_OP, STK_IIC_OP_RX)) | ||
261 | return 1; | ||
262 | do { | ||
263 | if (stk_camera_read_reg(dev, STK_IIC_STAT, &tmpval)) | ||
264 | return 1; | ||
265 | i++; | ||
266 | } while (tmpval == 0 && i < MAX_RETRIES); | ||
267 | if (tmpval != STK_IIC_STAT_RX_OK) { | ||
268 | if (tmpval) | ||
269 | STK_ERROR("stk_sensor_inb failed, status=0x%02x\n", | ||
270 | tmpval); | ||
271 | return 1; | ||
272 | } | ||
273 | |||
274 | if (stk_camera_read_reg(dev, STK_IIC_RX_VALUE, &tmpval)) | ||
275 | return 1; | ||
276 | |||
277 | *val = (u8) tmpval; | ||
278 | return 0; | ||
279 | } | ||
280 | |||
281 | static int stk_sensor_write_regvals(struct stk_camera *dev, | ||
282 | struct regval *rv) | ||
283 | { | ||
284 | int ret; | ||
285 | if (rv == NULL) | ||
286 | return 0; | ||
287 | while (rv->reg != 0xff || rv->val != 0xff) { | ||
288 | ret = stk_sensor_outb(dev, rv->reg, rv->val); | ||
289 | if (ret != 0) | ||
290 | return ret; | ||
291 | rv++; | ||
292 | } | ||
293 | return 0; | ||
294 | } | ||
295 | |||
296 | int stk_sensor_sleep(struct stk_camera *dev) | ||
297 | { | ||
298 | u8 tmp; | ||
299 | return stk_sensor_inb(dev, REG_COM2, &tmp) | ||
300 | || stk_sensor_outb(dev, REG_COM2, tmp|COM2_SSLEEP); | ||
301 | } | ||
302 | |||
303 | int stk_sensor_wakeup(struct stk_camera *dev) | ||
304 | { | ||
305 | u8 tmp; | ||
306 | return stk_sensor_inb(dev, REG_COM2, &tmp) | ||
307 | || stk_sensor_outb(dev, REG_COM2, tmp&~COM2_SSLEEP); | ||
308 | } | ||
309 | |||
310 | static struct regval ov_initvals[] = { | ||
311 | {REG_CLKRC, CLK_PLL}, | ||
312 | {REG_COM11, 0x01}, | ||
313 | {0x6a, 0x7d}, | ||
314 | {REG_AECH, 0x40}, | ||
315 | {REG_GAIN, 0x00}, | ||
316 | {REG_BLUE, 0x80}, | ||
317 | {REG_RED, 0x80}, | ||
318 | /* Do not enable fast AEC for now */ | ||
319 | /*{REG_COM8, COM8_FASTAEC|COM8_AECSTEP|COM8_BFILT|COM8_AGC|COM8_AEC},*/ | ||
320 | {REG_COM8, COM8_AECSTEP|COM8_BFILT|COM8_AGC|COM8_AEC}, | ||
321 | {0x39, 0x50}, {0x38, 0x93}, | ||
322 | {0x37, 0x00}, {0x35, 0x81}, | ||
323 | {REG_COM5, 0x20}, | ||
324 | {REG_COM1, 0x00}, | ||
325 | {REG_COM3, 0x00}, | ||
326 | {REG_COM4, 0x00}, | ||
327 | {REG_PSHFT, 0x00}, | ||
328 | {0x16, 0x07}, | ||
329 | {0x33, 0xe2}, {0x34, 0xbf}, | ||
330 | {REG_COM16, 0x00}, | ||
331 | {0x96, 0x04}, | ||
332 | /* Gamma curve values */ | ||
333 | /* { 0x7a, 0x20 }, { 0x7b, 0x10 }, | ||
334 | { 0x7c, 0x1e }, { 0x7d, 0x35 }, | ||
335 | { 0x7e, 0x5a }, { 0x7f, 0x69 }, | ||
336 | { 0x80, 0x76 }, { 0x81, 0x80 }, | ||
337 | { 0x82, 0x88 }, { 0x83, 0x8f }, | ||
338 | { 0x84, 0x96 }, { 0x85, 0xa3 }, | ||
339 | { 0x86, 0xaf }, { 0x87, 0xc4 }, | ||
340 | { 0x88, 0xd7 }, { 0x89, 0xe8 }, | ||
341 | */ | ||
342 | {REG_GFIX, 0x40}, | ||
343 | {0x8e, 0x00}, | ||
344 | {REG_COM12, 0x73}, | ||
345 | {0x8f, 0xdf}, {0x8b, 0x06}, | ||
346 | {0x8c, 0x20}, | ||
347 | {0x94, 0x88}, {0x95, 0x88}, | ||
348 | /* {REG_COM15, 0xc1}, TODO */ | ||
349 | {0x29, 0x3f}, | ||
350 | {REG_COM6, 0x42}, | ||
351 | {REG_BD50MAX, 0x80}, | ||
352 | {REG_HAECC6, 0xb8}, {REG_HAECC7, 0x92}, | ||
353 | {REG_BD60MAX, 0x0a}, | ||
354 | {0x90, 0x00}, {0x91, 0x00}, | ||
355 | {REG_HAECC1, 0x00}, {REG_HAECC2, 0x00}, | ||
356 | {REG_AEW, 0x68}, {REG_AEB, 0x5c}, | ||
357 | {REG_VPT, 0xc3}, | ||
358 | {REG_COM9, 0x2e}, | ||
359 | {0x2a, 0x00}, {0x2b, 0x00}, | ||
360 | |||
361 | {0xff, 0xff}, /* END MARKER */ | ||
362 | }; | ||
363 | |||
364 | /* Probe the I2C bus and initialise the sensor chip */ | ||
365 | int stk_sensor_init(struct stk_camera *dev) | ||
366 | { | ||
367 | u8 idl = 0; | ||
368 | u8 idh = 0; | ||
369 | |||
370 | if (stk_camera_write_reg(dev, STK_IIC_ENABLE, STK_IIC_ENABLE_YES) | ||
371 | || stk_camera_write_reg(dev, STK_IIC_ADDR, SENSOR_ADDRESS) | ||
372 | || stk_sensor_outb(dev, REG_COM7, COM7_RESET)) { | ||
373 | STK_ERROR("Sensor resetting failed\n"); | ||
374 | return -ENODEV; | ||
375 | } | ||
376 | msleep(10); | ||
377 | /* Read the manufacturer ID: ov = 0x7FA2 */ | ||
378 | if (stk_sensor_inb(dev, REG_MIDH, &idh) | ||
379 | || stk_sensor_inb(dev, REG_MIDL, &idl)) { | ||
380 | STK_ERROR("Strange error reading sensor ID\n"); | ||
381 | return -ENODEV; | ||
382 | } | ||
383 | if (idh != 0x7f || idl != 0xa2) { | ||
384 | STK_ERROR("Huh? you don't have a sensor from ovt\n"); | ||
385 | return -ENODEV; | ||
386 | } | ||
387 | if (stk_sensor_inb(dev, REG_PID, &idh) | ||
388 | || stk_sensor_inb(dev, REG_VER, &idl)) { | ||
389 | STK_ERROR("Could not read sensor model\n"); | ||
390 | return -ENODEV; | ||
391 | } | ||
392 | stk_sensor_write_regvals(dev, ov_initvals); | ||
393 | msleep(10); | ||
394 | STK_INFO("OmniVision sensor detected, id %02X%02X" | ||
395 | " at address %x\n", idh, idl, SENSOR_ADDRESS); | ||
396 | return 0; | ||
397 | } | ||
398 | |||
399 | /* V4L2_PIX_FMT_UYVY */ | ||
400 | static struct regval ov_fmt_uyvy[] = { | ||
401 | {REG_TSLB, TSLB_YLAST|0x08 }, | ||
402 | { 0x4f, 0x80 }, /* "matrix coefficient 1" */ | ||
403 | { 0x50, 0x80 }, /* "matrix coefficient 2" */ | ||
404 | { 0x51, 0 }, /* vb */ | ||
405 | { 0x52, 0x22 }, /* "matrix coefficient 4" */ | ||
406 | { 0x53, 0x5e }, /* "matrix coefficient 5" */ | ||
407 | { 0x54, 0x80 }, /* "matrix coefficient 6" */ | ||
408 | {REG_COM13, COM13_UVSAT|COM13_CMATRIX}, | ||
409 | {REG_COM15, COM15_R00FF }, | ||
410 | {0xff, 0xff}, /* END MARKER */ | ||
411 | }; | ||
412 | /* V4L2_PIX_FMT_YUYV */ | ||
413 | static struct regval ov_fmt_yuyv[] = { | ||
414 | {REG_TSLB, 0 }, | ||
415 | { 0x4f, 0x80 }, /* "matrix coefficient 1" */ | ||
416 | { 0x50, 0x80 }, /* "matrix coefficient 2" */ | ||
417 | { 0x51, 0 }, /* vb */ | ||
418 | { 0x52, 0x22 }, /* "matrix coefficient 4" */ | ||
419 | { 0x53, 0x5e }, /* "matrix coefficient 5" */ | ||
420 | { 0x54, 0x80 }, /* "matrix coefficient 6" */ | ||
421 | {REG_COM13, COM13_UVSAT|COM13_CMATRIX}, | ||
422 | {REG_COM15, COM15_R00FF }, | ||
423 | {0xff, 0xff}, /* END MARKER */ | ||
424 | }; | ||
425 | |||
426 | /* V4L2_PIX_FMT_RGB565X rrrrrggg gggbbbbb */ | ||
427 | static struct regval ov_fmt_rgbr[] = { | ||
428 | { REG_RGB444, 0 }, /* No RGB444 please */ | ||
429 | {REG_TSLB, 0x00}, | ||
430 | { REG_COM1, 0x0 }, | ||
431 | { REG_COM9, 0x38 }, /* 16x gain ceiling; 0x8 is reserved bit */ | ||
432 | { 0x4f, 0xb3 }, /* "matrix coefficient 1" */ | ||
433 | { 0x50, 0xb3 }, /* "matrix coefficient 2" */ | ||
434 | { 0x51, 0 }, /* vb */ | ||
435 | { 0x52, 0x3d }, /* "matrix coefficient 4" */ | ||
436 | { 0x53, 0xa7 }, /* "matrix coefficient 5" */ | ||
437 | { 0x54, 0xe4 }, /* "matrix coefficient 6" */ | ||
438 | { REG_COM13, COM13_GAMMA }, | ||
439 | { REG_COM15, COM15_RGB565|COM15_R00FF }, | ||
440 | { 0xff, 0xff }, | ||
441 | }; | ||
442 | |||
443 | /* V4L2_PIX_FMT_RGB565 gggbbbbb rrrrrggg */ | ||
444 | static struct regval ov_fmt_rgbp[] = { | ||
445 | { REG_RGB444, 0 }, /* No RGB444 please */ | ||
446 | {REG_TSLB, TSLB_BYTEORD }, | ||
447 | { REG_COM1, 0x0 }, | ||
448 | { REG_COM9, 0x38 }, /* 16x gain ceiling; 0x8 is reserved bit */ | ||
449 | { 0x4f, 0xb3 }, /* "matrix coefficient 1" */ | ||
450 | { 0x50, 0xb3 }, /* "matrix coefficient 2" */ | ||
451 | { 0x51, 0 }, /* vb */ | ||
452 | { 0x52, 0x3d }, /* "matrix coefficient 4" */ | ||
453 | { 0x53, 0xa7 }, /* "matrix coefficient 5" */ | ||
454 | { 0x54, 0xe4 }, /* "matrix coefficient 6" */ | ||
455 | { REG_COM13, COM13_GAMMA }, | ||
456 | { REG_COM15, COM15_RGB565|COM15_R00FF }, | ||
457 | { 0xff, 0xff }, | ||
458 | }; | ||
459 | |||
460 | /* V4L2_PIX_FMT_SRGGB8 */ | ||
461 | static struct regval ov_fmt_bayer[] = { | ||
462 | /* This changes color order */ | ||
463 | {REG_TSLB, 0x40}, /* BGGR */ | ||
464 | /* {REG_TSLB, 0x08}, */ /* BGGR with vertical image flipping */ | ||
465 | {REG_COM15, COM15_R00FF }, | ||
466 | {0xff, 0xff}, /* END MARKER */ | ||
467 | }; | ||
468 | /* | ||
469 | * Store a set of start/stop values into the camera. | ||
470 | */ | ||
471 | static int stk_sensor_set_hw(struct stk_camera *dev, | ||
472 | int hstart, int hstop, int vstart, int vstop) | ||
473 | { | ||
474 | int ret; | ||
475 | unsigned char v; | ||
476 | /* | ||
477 | * Horizontal: 11 bits, top 8 live in hstart and hstop. Bottom 3 of | ||
478 | * hstart are in href[2:0], bottom 3 of hstop in href[5:3]. There is | ||
479 | * a mystery "edge offset" value in the top two bits of href. | ||
480 | */ | ||
481 | ret = stk_sensor_outb(dev, REG_HSTART, (hstart >> 3) & 0xff); | ||
482 | ret += stk_sensor_outb(dev, REG_HSTOP, (hstop >> 3) & 0xff); | ||
483 | ret += stk_sensor_inb(dev, REG_HREF, &v); | ||
484 | v = (v & 0xc0) | ((hstop & 0x7) << 3) | (hstart & 0x7); | ||
485 | msleep(10); | ||
486 | ret += stk_sensor_outb(dev, REG_HREF, v); | ||
487 | /* | ||
488 | * Vertical: similar arrangement (note: this is different from ov7670.c) | ||
489 | */ | ||
490 | ret += stk_sensor_outb(dev, REG_VSTART, (vstart >> 3) & 0xff); | ||
491 | ret += stk_sensor_outb(dev, REG_VSTOP, (vstop >> 3) & 0xff); | ||
492 | ret += stk_sensor_inb(dev, REG_VREF, &v); | ||
493 | v = (v & 0xc0) | ((vstop & 0x7) << 3) | (vstart & 0x7); | ||
494 | msleep(10); | ||
495 | ret += stk_sensor_outb(dev, REG_VREF, v); | ||
496 | return ret; | ||
497 | } | ||
498 | |||
499 | |||
500 | int stk_sensor_configure(struct stk_camera *dev) | ||
501 | { | ||
502 | int com7; | ||
503 | /* | ||
504 | * We setup the sensor to output dummy lines in low-res modes, | ||
505 | * so we don't get absurdly hight framerates. | ||
506 | */ | ||
507 | unsigned dummylines; | ||
508 | int flip; | ||
509 | struct regval *rv; | ||
510 | |||
511 | switch (dev->vsettings.mode) { | ||
512 | case MODE_QCIF: com7 = COM7_FMT_QCIF; | ||
513 | dummylines = 604; | ||
514 | break; | ||
515 | case MODE_QVGA: com7 = COM7_FMT_QVGA; | ||
516 | dummylines = 267; | ||
517 | break; | ||
518 | case MODE_CIF: com7 = COM7_FMT_CIF; | ||
519 | dummylines = 412; | ||
520 | break; | ||
521 | case MODE_VGA: com7 = COM7_FMT_VGA; | ||
522 | dummylines = 11; | ||
523 | break; | ||
524 | case MODE_SXGA: com7 = COM7_FMT_SXGA; | ||
525 | dummylines = 0; | ||
526 | break; | ||
527 | default: STK_ERROR("Unsupported mode %d\n", dev->vsettings.mode); | ||
528 | return -EFAULT; | ||
529 | } | ||
530 | switch (dev->vsettings.palette) { | ||
531 | case V4L2_PIX_FMT_UYVY: | ||
532 | com7 |= COM7_YUV; | ||
533 | rv = ov_fmt_uyvy; | ||
534 | break; | ||
535 | case V4L2_PIX_FMT_YUYV: | ||
536 | com7 |= COM7_YUV; | ||
537 | rv = ov_fmt_yuyv; | ||
538 | break; | ||
539 | case V4L2_PIX_FMT_RGB565: | ||
540 | com7 |= COM7_RGB; | ||
541 | rv = ov_fmt_rgbp; | ||
542 | break; | ||
543 | case V4L2_PIX_FMT_RGB565X: | ||
544 | com7 |= COM7_RGB; | ||
545 | rv = ov_fmt_rgbr; | ||
546 | break; | ||
547 | case V4L2_PIX_FMT_SBGGR8: | ||
548 | com7 |= COM7_PBAYER; | ||
549 | rv = ov_fmt_bayer; | ||
550 | break; | ||
551 | default: STK_ERROR("Unsupported colorspace\n"); | ||
552 | return -EFAULT; | ||
553 | } | ||
554 | /*FIXME sometimes the sensor go to a bad state | ||
555 | stk_sensor_write_regvals(dev, ov_initvals); */ | ||
556 | stk_sensor_outb(dev, REG_COM7, com7); | ||
557 | msleep(50); | ||
558 | stk_sensor_write_regvals(dev, rv); | ||
559 | flip = (dev->vsettings.vflip?MVFP_FLIP:0) | ||
560 | | (dev->vsettings.hflip?MVFP_MIRROR:0); | ||
561 | stk_sensor_outb(dev, REG_MVFP, flip); | ||
562 | if (dev->vsettings.palette == V4L2_PIX_FMT_SBGGR8 | ||
563 | && !dev->vsettings.vflip) | ||
564 | stk_sensor_outb(dev, REG_TSLB, 0x08); | ||
565 | stk_sensor_outb(dev, REG_ADVFH, dummylines >> 8); | ||
566 | stk_sensor_outb(dev, REG_ADVFL, dummylines & 0xff); | ||
567 | msleep(50); | ||
568 | switch (dev->vsettings.mode) { | ||
569 | case MODE_VGA: | ||
570 | if (stk_sensor_set_hw(dev, 302, 1582, 6, 486)) | ||
571 | STK_ERROR("stk_sensor_set_hw failed (VGA)\n"); | ||
572 | break; | ||
573 | case MODE_SXGA: | ||
574 | case MODE_CIF: | ||
575 | case MODE_QVGA: | ||
576 | case MODE_QCIF: | ||
577 | /*FIXME These settings seem ignored by the sensor | ||
578 | if (stk_sensor_set_hw(dev, 220, 1500, 10, 1034)) | ||
579 | STK_ERROR("stk_sensor_set_hw failed (SXGA)\n"); | ||
580 | */ | ||
581 | break; | ||
582 | } | ||
583 | msleep(10); | ||
584 | return 0; | ||
585 | } | ||
586 | |||
587 | int stk_sensor_set_brightness(struct stk_camera *dev, int br) | ||
588 | { | ||
589 | if (br < 0 || br > 0xff) | ||
590 | return -EINVAL; | ||
591 | stk_sensor_outb(dev, REG_AEB, max(0x00, br - 6)); | ||
592 | stk_sensor_outb(dev, REG_AEW, min(0xff, br + 6)); | ||
593 | return 0; | ||
594 | } | ||
595 | |||
diff --git a/drivers/media/video/stk-webcam.c b/drivers/media/video/stk-webcam.c deleted file mode 100644 index 86a0fc56c330..000000000000 --- a/drivers/media/video/stk-webcam.c +++ /dev/null | |||
@@ -1,1380 +0,0 @@ | |||
1 | /* | ||
2 | * stk-webcam.c : Driver for Syntek 1125 USB webcam controller | ||
3 | * | ||
4 | * Copyright (C) 2006 Nicolas VIVIEN | ||
5 | * Copyright 2007-2008 Jaime Velasco Juan <jsagarribay@gmail.com> | ||
6 | * | ||
7 | * Some parts are inspired from cafe_ccic.c | ||
8 | * Copyright 2006-2007 Jonathan Corbet | ||
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 | * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
23 | */ | ||
24 | |||
25 | #include <linux/module.h> | ||
26 | #include <linux/init.h> | ||
27 | #include <linux/kernel.h> | ||
28 | #include <linux/errno.h> | ||
29 | #include <linux/slab.h> | ||
30 | |||
31 | #include <linux/usb.h> | ||
32 | #include <linux/mm.h> | ||
33 | #include <linux/vmalloc.h> | ||
34 | #include <linux/videodev2.h> | ||
35 | #include <media/v4l2-common.h> | ||
36 | #include <media/v4l2-ioctl.h> | ||
37 | |||
38 | #include "stk-webcam.h" | ||
39 | |||
40 | |||
41 | static bool hflip; | ||
42 | module_param(hflip, bool, 0444); | ||
43 | MODULE_PARM_DESC(hflip, "Horizontal image flip (mirror). Defaults to 0"); | ||
44 | |||
45 | static bool vflip; | ||
46 | module_param(vflip, bool, 0444); | ||
47 | MODULE_PARM_DESC(vflip, "Vertical image flip. Defaults to 0"); | ||
48 | |||
49 | static int debug; | ||
50 | module_param(debug, int, 0444); | ||
51 | MODULE_PARM_DESC(debug, "Debug v4l ioctls. Defaults to 0"); | ||
52 | |||
53 | MODULE_LICENSE("GPL"); | ||
54 | MODULE_AUTHOR("Jaime Velasco Juan <jsagarribay@gmail.com> and Nicolas VIVIEN"); | ||
55 | MODULE_DESCRIPTION("Syntek DC1125 webcam driver"); | ||
56 | |||
57 | |||
58 | /* bool for webcam LED management */ | ||
59 | int first_init = 1; | ||
60 | |||
61 | /* Some cameras have audio interfaces, we aren't interested in those */ | ||
62 | static struct usb_device_id stkwebcam_table[] = { | ||
63 | { USB_DEVICE_AND_INTERFACE_INFO(0x174f, 0xa311, 0xff, 0xff, 0xff) }, | ||
64 | { USB_DEVICE_AND_INTERFACE_INFO(0x05e1, 0x0501, 0xff, 0xff, 0xff) }, | ||
65 | { } | ||
66 | }; | ||
67 | MODULE_DEVICE_TABLE(usb, stkwebcam_table); | ||
68 | |||
69 | /* | ||
70 | * Basic stuff | ||
71 | */ | ||
72 | int stk_camera_write_reg(struct stk_camera *dev, u16 index, u8 value) | ||
73 | { | ||
74 | struct usb_device *udev = dev->udev; | ||
75 | int ret; | ||
76 | |||
77 | ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), | ||
78 | 0x01, | ||
79 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
80 | value, | ||
81 | index, | ||
82 | NULL, | ||
83 | 0, | ||
84 | 500); | ||
85 | if (ret < 0) | ||
86 | return ret; | ||
87 | else | ||
88 | return 0; | ||
89 | } | ||
90 | |||
91 | int stk_camera_read_reg(struct stk_camera *dev, u16 index, int *value) | ||
92 | { | ||
93 | struct usb_device *udev = dev->udev; | ||
94 | int ret; | ||
95 | |||
96 | ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), | ||
97 | 0x00, | ||
98 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
99 | 0x00, | ||
100 | index, | ||
101 | (u8 *) value, | ||
102 | sizeof(u8), | ||
103 | 500); | ||
104 | if (ret < 0) | ||
105 | return ret; | ||
106 | else | ||
107 | return 0; | ||
108 | } | ||
109 | |||
110 | static int stk_start_stream(struct stk_camera *dev) | ||
111 | { | ||
112 | int value; | ||
113 | int i, ret; | ||
114 | int value_116, value_117; | ||
115 | |||
116 | if (!is_present(dev)) | ||
117 | return -ENODEV; | ||
118 | if (!is_memallocd(dev) || !is_initialised(dev)) { | ||
119 | STK_ERROR("FIXME: Buffers are not allocated\n"); | ||
120 | return -EFAULT; | ||
121 | } | ||
122 | ret = usb_set_interface(dev->udev, 0, 5); | ||
123 | |||
124 | if (ret < 0) | ||
125 | STK_ERROR("usb_set_interface failed !\n"); | ||
126 | if (stk_sensor_wakeup(dev)) | ||
127 | STK_ERROR("error awaking the sensor\n"); | ||
128 | |||
129 | stk_camera_read_reg(dev, 0x0116, &value_116); | ||
130 | stk_camera_read_reg(dev, 0x0117, &value_117); | ||
131 | |||
132 | stk_camera_write_reg(dev, 0x0116, 0x0000); | ||
133 | stk_camera_write_reg(dev, 0x0117, 0x0000); | ||
134 | |||
135 | stk_camera_read_reg(dev, 0x0100, &value); | ||
136 | stk_camera_write_reg(dev, 0x0100, value | 0x80); | ||
137 | |||
138 | stk_camera_write_reg(dev, 0x0116, value_116); | ||
139 | stk_camera_write_reg(dev, 0x0117, value_117); | ||
140 | for (i = 0; i < MAX_ISO_BUFS; i++) { | ||
141 | if (dev->isobufs[i].urb) { | ||
142 | ret = usb_submit_urb(dev->isobufs[i].urb, GFP_KERNEL); | ||
143 | atomic_inc(&dev->urbs_used); | ||
144 | if (ret) | ||
145 | return ret; | ||
146 | } | ||
147 | } | ||
148 | set_streaming(dev); | ||
149 | return 0; | ||
150 | } | ||
151 | |||
152 | static int stk_stop_stream(struct stk_camera *dev) | ||
153 | { | ||
154 | int value; | ||
155 | int i; | ||
156 | if (is_present(dev)) { | ||
157 | stk_camera_read_reg(dev, 0x0100, &value); | ||
158 | stk_camera_write_reg(dev, 0x0100, value & ~0x80); | ||
159 | if (dev->isobufs != NULL) { | ||
160 | for (i = 0; i < MAX_ISO_BUFS; i++) { | ||
161 | if (dev->isobufs[i].urb) | ||
162 | usb_kill_urb(dev->isobufs[i].urb); | ||
163 | } | ||
164 | } | ||
165 | unset_streaming(dev); | ||
166 | |||
167 | if (usb_set_interface(dev->udev, 0, 0)) | ||
168 | STK_ERROR("usb_set_interface failed !\n"); | ||
169 | if (stk_sensor_sleep(dev)) | ||
170 | STK_ERROR("error suspending the sensor\n"); | ||
171 | } | ||
172 | return 0; | ||
173 | } | ||
174 | |||
175 | /* | ||
176 | * This seems to be the shortest init sequence we | ||
177 | * must do in order to find the sensor | ||
178 | * Bit 5 of reg. 0x0000 here is important, when reset to 0 the sensor | ||
179 | * is also reset. Maybe powers down it? | ||
180 | * Rest of values don't make a difference | ||
181 | */ | ||
182 | |||
183 | static struct regval stk1125_initvals[] = { | ||
184 | /*TODO: What means this sequence? */ | ||
185 | {0x0000, 0x24}, | ||
186 | {0x0100, 0x21}, | ||
187 | {0x0002, 0x68}, | ||
188 | {0x0003, 0x80}, | ||
189 | {0x0005, 0x00}, | ||
190 | {0x0007, 0x03}, | ||
191 | {0x000d, 0x00}, | ||
192 | {0x000f, 0x02}, | ||
193 | {0x0300, 0x12}, | ||
194 | {0x0350, 0x41}, | ||
195 | {0x0351, 0x00}, | ||
196 | {0x0352, 0x00}, | ||
197 | {0x0353, 0x00}, | ||
198 | {0x0018, 0x10}, | ||
199 | {0x0019, 0x00}, | ||
200 | {0x001b, 0x0e}, | ||
201 | {0x001c, 0x46}, | ||
202 | {0x0300, 0x80}, | ||
203 | {0x001a, 0x04}, | ||
204 | {0x0110, 0x00}, | ||
205 | {0x0111, 0x00}, | ||
206 | {0x0112, 0x00}, | ||
207 | {0x0113, 0x00}, | ||
208 | |||
209 | {0xffff, 0xff}, | ||
210 | }; | ||
211 | |||
212 | |||
213 | static int stk_initialise(struct stk_camera *dev) | ||
214 | { | ||
215 | struct regval *rv; | ||
216 | int ret; | ||
217 | if (!is_present(dev)) | ||
218 | return -ENODEV; | ||
219 | if (is_initialised(dev)) | ||
220 | return 0; | ||
221 | rv = stk1125_initvals; | ||
222 | while (rv->reg != 0xffff) { | ||
223 | ret = stk_camera_write_reg(dev, rv->reg, rv->val); | ||
224 | if (ret) | ||
225 | return ret; | ||
226 | rv++; | ||
227 | } | ||
228 | if (stk_sensor_init(dev) == 0) { | ||
229 | set_initialised(dev); | ||
230 | return 0; | ||
231 | } else | ||
232 | return -1; | ||
233 | } | ||
234 | |||
235 | /* *********************************************** */ | ||
236 | /* | ||
237 | * This function is called as an URB transfert is complete (Isochronous pipe). | ||
238 | * So, the traitement is done in interrupt time, so it has be fast, not crash, | ||
239 | * and not stall. Neat. | ||
240 | */ | ||
241 | static void stk_isoc_handler(struct urb *urb) | ||
242 | { | ||
243 | int i; | ||
244 | int ret; | ||
245 | int framelen; | ||
246 | unsigned long flags; | ||
247 | |||
248 | unsigned char *fill = NULL; | ||
249 | unsigned char *iso_buf = NULL; | ||
250 | |||
251 | struct stk_camera *dev; | ||
252 | struct stk_sio_buffer *fb; | ||
253 | |||
254 | dev = (struct stk_camera *) urb->context; | ||
255 | |||
256 | if (dev == NULL) { | ||
257 | STK_ERROR("isoc_handler called with NULL device !\n"); | ||
258 | return; | ||
259 | } | ||
260 | |||
261 | if (urb->status == -ENOENT || urb->status == -ECONNRESET | ||
262 | || urb->status == -ESHUTDOWN) { | ||
263 | atomic_dec(&dev->urbs_used); | ||
264 | return; | ||
265 | } | ||
266 | |||
267 | spin_lock_irqsave(&dev->spinlock, flags); | ||
268 | |||
269 | if (urb->status != -EINPROGRESS && urb->status != 0) { | ||
270 | STK_ERROR("isoc_handler: urb->status == %d\n", urb->status); | ||
271 | goto resubmit; | ||
272 | } | ||
273 | |||
274 | if (list_empty(&dev->sio_avail)) { | ||
275 | /*FIXME Stop streaming after a while */ | ||
276 | (void) (printk_ratelimit() && | ||
277 | STK_ERROR("isoc_handler without available buffer!\n")); | ||
278 | goto resubmit; | ||
279 | } | ||
280 | fb = list_first_entry(&dev->sio_avail, | ||
281 | struct stk_sio_buffer, list); | ||
282 | fill = fb->buffer + fb->v4lbuf.bytesused; | ||
283 | |||
284 | for (i = 0; i < urb->number_of_packets; i++) { | ||
285 | if (urb->iso_frame_desc[i].status != 0) { | ||
286 | if (urb->iso_frame_desc[i].status != -EXDEV) | ||
287 | STK_ERROR("Frame %d has error %d\n", i, | ||
288 | urb->iso_frame_desc[i].status); | ||
289 | continue; | ||
290 | } | ||
291 | framelen = urb->iso_frame_desc[i].actual_length; | ||
292 | iso_buf = urb->transfer_buffer + urb->iso_frame_desc[i].offset; | ||
293 | |||
294 | if (framelen <= 4) | ||
295 | continue; /* no data */ | ||
296 | |||
297 | /* | ||
298 | * we found something informational from there | ||
299 | * the isoc frames have to type of headers | ||
300 | * type1: 00 xx 00 00 or 20 xx 00 00 | ||
301 | * type2: 80 xx 00 00 00 00 00 00 or a0 xx 00 00 00 00 00 00 | ||
302 | * xx is a sequencer which has never been seen over 0x3f | ||
303 | * imho data written down looks like bayer, i see similarities | ||
304 | * after every 640 bytes | ||
305 | */ | ||
306 | if (*iso_buf & 0x80) { | ||
307 | framelen -= 8; | ||
308 | iso_buf += 8; | ||
309 | /* This marks a new frame */ | ||
310 | if (fb->v4lbuf.bytesused != 0 | ||
311 | && fb->v4lbuf.bytesused != dev->frame_size) { | ||
312 | (void) (printk_ratelimit() && | ||
313 | STK_ERROR("frame %d, " | ||
314 | "bytesused=%d, skipping\n", | ||
315 | i, fb->v4lbuf.bytesused)); | ||
316 | fb->v4lbuf.bytesused = 0; | ||
317 | fill = fb->buffer; | ||
318 | } else if (fb->v4lbuf.bytesused == dev->frame_size) { | ||
319 | if (list_is_singular(&dev->sio_avail)) { | ||
320 | /* Always reuse the last buffer */ | ||
321 | fb->v4lbuf.bytesused = 0; | ||
322 | fill = fb->buffer; | ||
323 | } else { | ||
324 | list_move_tail(dev->sio_avail.next, | ||
325 | &dev->sio_full); | ||
326 | wake_up(&dev->wait_frame); | ||
327 | fb = list_first_entry(&dev->sio_avail, | ||
328 | struct stk_sio_buffer, list); | ||
329 | fb->v4lbuf.bytesused = 0; | ||
330 | fill = fb->buffer; | ||
331 | } | ||
332 | } | ||
333 | } else { | ||
334 | framelen -= 4; | ||
335 | iso_buf += 4; | ||
336 | } | ||
337 | |||
338 | /* Our buffer is full !!! */ | ||
339 | if (framelen + fb->v4lbuf.bytesused > dev->frame_size) { | ||
340 | (void) (printk_ratelimit() && | ||
341 | STK_ERROR("Frame buffer overflow, lost sync\n")); | ||
342 | /*FIXME Do something here? */ | ||
343 | continue; | ||
344 | } | ||
345 | spin_unlock_irqrestore(&dev->spinlock, flags); | ||
346 | memcpy(fill, iso_buf, framelen); | ||
347 | spin_lock_irqsave(&dev->spinlock, flags); | ||
348 | fill += framelen; | ||
349 | |||
350 | /* New size of our buffer */ | ||
351 | fb->v4lbuf.bytesused += framelen; | ||
352 | } | ||
353 | |||
354 | resubmit: | ||
355 | spin_unlock_irqrestore(&dev->spinlock, flags); | ||
356 | urb->dev = dev->udev; | ||
357 | ret = usb_submit_urb(urb, GFP_ATOMIC); | ||
358 | if (ret != 0) { | ||
359 | STK_ERROR("Error (%d) re-submitting urb in stk_isoc_handler.\n", | ||
360 | ret); | ||
361 | } | ||
362 | } | ||
363 | |||
364 | /* -------------------------------------------- */ | ||
365 | |||
366 | static int stk_prepare_iso(struct stk_camera *dev) | ||
367 | { | ||
368 | void *kbuf; | ||
369 | int i, j; | ||
370 | struct urb *urb; | ||
371 | struct usb_device *udev; | ||
372 | |||
373 | if (dev == NULL) | ||
374 | return -ENXIO; | ||
375 | udev = dev->udev; | ||
376 | |||
377 | if (dev->isobufs) | ||
378 | STK_ERROR("isobufs already allocated. Bad\n"); | ||
379 | else | ||
380 | dev->isobufs = kcalloc(MAX_ISO_BUFS, sizeof(*dev->isobufs), | ||
381 | GFP_KERNEL); | ||
382 | if (dev->isobufs == NULL) { | ||
383 | STK_ERROR("Unable to allocate iso buffers\n"); | ||
384 | return -ENOMEM; | ||
385 | } | ||
386 | for (i = 0; i < MAX_ISO_BUFS; i++) { | ||
387 | if (dev->isobufs[i].data == NULL) { | ||
388 | kbuf = kzalloc(ISO_BUFFER_SIZE, GFP_KERNEL); | ||
389 | if (kbuf == NULL) { | ||
390 | STK_ERROR("Failed to allocate iso buffer %d\n", | ||
391 | i); | ||
392 | goto isobufs_out; | ||
393 | } | ||
394 | dev->isobufs[i].data = kbuf; | ||
395 | } else | ||
396 | STK_ERROR("isobuf data already allocated\n"); | ||
397 | if (dev->isobufs[i].urb == NULL) { | ||
398 | urb = usb_alloc_urb(ISO_FRAMES_PER_DESC, GFP_KERNEL); | ||
399 | if (urb == NULL) { | ||
400 | STK_ERROR("Failed to allocate URB %d\n", i); | ||
401 | goto isobufs_out; | ||
402 | } | ||
403 | dev->isobufs[i].urb = urb; | ||
404 | } else { | ||
405 | STK_ERROR("Killing URB\n"); | ||
406 | usb_kill_urb(dev->isobufs[i].urb); | ||
407 | urb = dev->isobufs[i].urb; | ||
408 | } | ||
409 | urb->interval = 1; | ||
410 | urb->dev = udev; | ||
411 | urb->pipe = usb_rcvisocpipe(udev, dev->isoc_ep); | ||
412 | urb->transfer_flags = URB_ISO_ASAP; | ||
413 | urb->transfer_buffer = dev->isobufs[i].data; | ||
414 | urb->transfer_buffer_length = ISO_BUFFER_SIZE; | ||
415 | urb->complete = stk_isoc_handler; | ||
416 | urb->context = dev; | ||
417 | urb->start_frame = 0; | ||
418 | urb->number_of_packets = ISO_FRAMES_PER_DESC; | ||
419 | |||
420 | for (j = 0; j < ISO_FRAMES_PER_DESC; j++) { | ||
421 | urb->iso_frame_desc[j].offset = j * ISO_MAX_FRAME_SIZE; | ||
422 | urb->iso_frame_desc[j].length = ISO_MAX_FRAME_SIZE; | ||
423 | } | ||
424 | } | ||
425 | set_memallocd(dev); | ||
426 | return 0; | ||
427 | |||
428 | isobufs_out: | ||
429 | for (i = 0; i < MAX_ISO_BUFS && dev->isobufs[i].data; i++) | ||
430 | kfree(dev->isobufs[i].data); | ||
431 | for (i = 0; i < MAX_ISO_BUFS && dev->isobufs[i].urb; i++) | ||
432 | usb_free_urb(dev->isobufs[i].urb); | ||
433 | kfree(dev->isobufs); | ||
434 | dev->isobufs = NULL; | ||
435 | return -ENOMEM; | ||
436 | } | ||
437 | |||
438 | static void stk_clean_iso(struct stk_camera *dev) | ||
439 | { | ||
440 | int i; | ||
441 | |||
442 | if (dev == NULL || dev->isobufs == NULL) | ||
443 | return; | ||
444 | |||
445 | for (i = 0; i < MAX_ISO_BUFS; i++) { | ||
446 | struct urb *urb; | ||
447 | |||
448 | urb = dev->isobufs[i].urb; | ||
449 | if (urb) { | ||
450 | if (atomic_read(&dev->urbs_used) && is_present(dev)) | ||
451 | usb_kill_urb(urb); | ||
452 | usb_free_urb(urb); | ||
453 | } | ||
454 | kfree(dev->isobufs[i].data); | ||
455 | } | ||
456 | kfree(dev->isobufs); | ||
457 | dev->isobufs = NULL; | ||
458 | unset_memallocd(dev); | ||
459 | } | ||
460 | |||
461 | static int stk_setup_siobuf(struct stk_camera *dev, int index) | ||
462 | { | ||
463 | struct stk_sio_buffer *buf = dev->sio_bufs + index; | ||
464 | INIT_LIST_HEAD(&buf->list); | ||
465 | buf->v4lbuf.length = PAGE_ALIGN(dev->frame_size); | ||
466 | buf->buffer = vmalloc_user(buf->v4lbuf.length); | ||
467 | if (buf->buffer == NULL) | ||
468 | return -ENOMEM; | ||
469 | buf->mapcount = 0; | ||
470 | buf->dev = dev; | ||
471 | buf->v4lbuf.index = index; | ||
472 | buf->v4lbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
473 | buf->v4lbuf.field = V4L2_FIELD_NONE; | ||
474 | buf->v4lbuf.memory = V4L2_MEMORY_MMAP; | ||
475 | buf->v4lbuf.m.offset = 2*index*buf->v4lbuf.length; | ||
476 | return 0; | ||
477 | } | ||
478 | |||
479 | static int stk_free_sio_buffers(struct stk_camera *dev) | ||
480 | { | ||
481 | int i; | ||
482 | int nbufs; | ||
483 | unsigned long flags; | ||
484 | if (dev->n_sbufs == 0 || dev->sio_bufs == NULL) | ||
485 | return 0; | ||
486 | /* | ||
487 | * If any buffers are mapped, we cannot free them at all. | ||
488 | */ | ||
489 | for (i = 0; i < dev->n_sbufs; i++) { | ||
490 | if (dev->sio_bufs[i].mapcount > 0) | ||
491 | return -EBUSY; | ||
492 | } | ||
493 | /* | ||
494 | * OK, let's do it. | ||
495 | */ | ||
496 | spin_lock_irqsave(&dev->spinlock, flags); | ||
497 | INIT_LIST_HEAD(&dev->sio_avail); | ||
498 | INIT_LIST_HEAD(&dev->sio_full); | ||
499 | nbufs = dev->n_sbufs; | ||
500 | dev->n_sbufs = 0; | ||
501 | spin_unlock_irqrestore(&dev->spinlock, flags); | ||
502 | for (i = 0; i < nbufs; i++) { | ||
503 | if (dev->sio_bufs[i].buffer != NULL) | ||
504 | vfree(dev->sio_bufs[i].buffer); | ||
505 | } | ||
506 | kfree(dev->sio_bufs); | ||
507 | dev->sio_bufs = NULL; | ||
508 | return 0; | ||
509 | } | ||
510 | |||
511 | static int stk_prepare_sio_buffers(struct stk_camera *dev, unsigned n_sbufs) | ||
512 | { | ||
513 | int i; | ||
514 | if (dev->sio_bufs != NULL) | ||
515 | STK_ERROR("sio_bufs already allocated\n"); | ||
516 | else { | ||
517 | dev->sio_bufs = kzalloc(n_sbufs * sizeof(struct stk_sio_buffer), | ||
518 | GFP_KERNEL); | ||
519 | if (dev->sio_bufs == NULL) | ||
520 | return -ENOMEM; | ||
521 | for (i = 0; i < n_sbufs; i++) { | ||
522 | if (stk_setup_siobuf(dev, i)) | ||
523 | return (dev->n_sbufs > 1 ? 0 : -ENOMEM); | ||
524 | dev->n_sbufs = i+1; | ||
525 | } | ||
526 | } | ||
527 | return 0; | ||
528 | } | ||
529 | |||
530 | static int stk_allocate_buffers(struct stk_camera *dev, unsigned n_sbufs) | ||
531 | { | ||
532 | int err; | ||
533 | err = stk_prepare_iso(dev); | ||
534 | if (err) { | ||
535 | stk_clean_iso(dev); | ||
536 | return err; | ||
537 | } | ||
538 | err = stk_prepare_sio_buffers(dev, n_sbufs); | ||
539 | if (err) { | ||
540 | stk_free_sio_buffers(dev); | ||
541 | return err; | ||
542 | } | ||
543 | return 0; | ||
544 | } | ||
545 | |||
546 | static void stk_free_buffers(struct stk_camera *dev) | ||
547 | { | ||
548 | stk_clean_iso(dev); | ||
549 | stk_free_sio_buffers(dev); | ||
550 | } | ||
551 | /* -------------------------------------------- */ | ||
552 | |||
553 | /* v4l file operations */ | ||
554 | |||
555 | static int v4l_stk_open(struct file *fp) | ||
556 | { | ||
557 | struct stk_camera *dev; | ||
558 | struct video_device *vdev; | ||
559 | |||
560 | vdev = video_devdata(fp); | ||
561 | dev = vdev_to_camera(vdev); | ||
562 | |||
563 | if (dev == NULL || !is_present(dev)) | ||
564 | return -ENXIO; | ||
565 | |||
566 | if (!first_init) | ||
567 | stk_camera_write_reg(dev, 0x0, 0x24); | ||
568 | else | ||
569 | first_init = 0; | ||
570 | |||
571 | fp->private_data = dev; | ||
572 | usb_autopm_get_interface(dev->interface); | ||
573 | |||
574 | return 0; | ||
575 | } | ||
576 | |||
577 | static int v4l_stk_release(struct file *fp) | ||
578 | { | ||
579 | struct stk_camera *dev = fp->private_data; | ||
580 | |||
581 | if (dev->owner == fp) { | ||
582 | stk_stop_stream(dev); | ||
583 | stk_free_buffers(dev); | ||
584 | stk_camera_write_reg(dev, 0x0, 0x49); /* turn off the LED */ | ||
585 | unset_initialised(dev); | ||
586 | dev->owner = NULL; | ||
587 | } | ||
588 | |||
589 | if (is_present(dev)) | ||
590 | usb_autopm_put_interface(dev->interface); | ||
591 | |||
592 | return 0; | ||
593 | } | ||
594 | |||
595 | static ssize_t v4l_stk_read(struct file *fp, char __user *buf, | ||
596 | size_t count, loff_t *f_pos) | ||
597 | { | ||
598 | int i; | ||
599 | int ret; | ||
600 | unsigned long flags; | ||
601 | struct stk_sio_buffer *sbuf; | ||
602 | struct stk_camera *dev = fp->private_data; | ||
603 | |||
604 | if (!is_present(dev)) | ||
605 | return -EIO; | ||
606 | if (dev->owner && dev->owner != fp) | ||
607 | return -EBUSY; | ||
608 | dev->owner = fp; | ||
609 | if (!is_streaming(dev)) { | ||
610 | if (stk_initialise(dev) | ||
611 | || stk_allocate_buffers(dev, 3) | ||
612 | || stk_start_stream(dev)) | ||
613 | return -ENOMEM; | ||
614 | spin_lock_irqsave(&dev->spinlock, flags); | ||
615 | for (i = 0; i < dev->n_sbufs; i++) { | ||
616 | list_add_tail(&dev->sio_bufs[i].list, &dev->sio_avail); | ||
617 | dev->sio_bufs[i].v4lbuf.flags = V4L2_BUF_FLAG_QUEUED; | ||
618 | } | ||
619 | spin_unlock_irqrestore(&dev->spinlock, flags); | ||
620 | } | ||
621 | if (*f_pos == 0) { | ||
622 | if (fp->f_flags & O_NONBLOCK && list_empty(&dev->sio_full)) | ||
623 | return -EWOULDBLOCK; | ||
624 | ret = wait_event_interruptible(dev->wait_frame, | ||
625 | !list_empty(&dev->sio_full) || !is_present(dev)); | ||
626 | if (ret) | ||
627 | return ret; | ||
628 | if (!is_present(dev)) | ||
629 | return -EIO; | ||
630 | } | ||
631 | if (count + *f_pos > dev->frame_size) | ||
632 | count = dev->frame_size - *f_pos; | ||
633 | spin_lock_irqsave(&dev->spinlock, flags); | ||
634 | if (list_empty(&dev->sio_full)) { | ||
635 | spin_unlock_irqrestore(&dev->spinlock, flags); | ||
636 | STK_ERROR("BUG: No siobufs ready\n"); | ||
637 | return 0; | ||
638 | } | ||
639 | sbuf = list_first_entry(&dev->sio_full, struct stk_sio_buffer, list); | ||
640 | spin_unlock_irqrestore(&dev->spinlock, flags); | ||
641 | |||
642 | if (copy_to_user(buf, sbuf->buffer + *f_pos, count)) | ||
643 | return -EFAULT; | ||
644 | |||
645 | *f_pos += count; | ||
646 | |||
647 | if (*f_pos >= dev->frame_size) { | ||
648 | *f_pos = 0; | ||
649 | spin_lock_irqsave(&dev->spinlock, flags); | ||
650 | list_move_tail(&sbuf->list, &dev->sio_avail); | ||
651 | spin_unlock_irqrestore(&dev->spinlock, flags); | ||
652 | } | ||
653 | return count; | ||
654 | } | ||
655 | |||
656 | static unsigned int v4l_stk_poll(struct file *fp, poll_table *wait) | ||
657 | { | ||
658 | struct stk_camera *dev = fp->private_data; | ||
659 | |||
660 | poll_wait(fp, &dev->wait_frame, wait); | ||
661 | |||
662 | if (!is_present(dev)) | ||
663 | return POLLERR; | ||
664 | |||
665 | if (!list_empty(&dev->sio_full)) | ||
666 | return POLLIN | POLLRDNORM; | ||
667 | |||
668 | return 0; | ||
669 | } | ||
670 | |||
671 | |||
672 | static void stk_v4l_vm_open(struct vm_area_struct *vma) | ||
673 | { | ||
674 | struct stk_sio_buffer *sbuf = vma->vm_private_data; | ||
675 | sbuf->mapcount++; | ||
676 | } | ||
677 | static void stk_v4l_vm_close(struct vm_area_struct *vma) | ||
678 | { | ||
679 | struct stk_sio_buffer *sbuf = vma->vm_private_data; | ||
680 | sbuf->mapcount--; | ||
681 | if (sbuf->mapcount == 0) | ||
682 | sbuf->v4lbuf.flags &= ~V4L2_BUF_FLAG_MAPPED; | ||
683 | } | ||
684 | static const struct vm_operations_struct stk_v4l_vm_ops = { | ||
685 | .open = stk_v4l_vm_open, | ||
686 | .close = stk_v4l_vm_close | ||
687 | }; | ||
688 | |||
689 | static int v4l_stk_mmap(struct file *fp, struct vm_area_struct *vma) | ||
690 | { | ||
691 | unsigned int i; | ||
692 | int ret; | ||
693 | unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; | ||
694 | struct stk_camera *dev = fp->private_data; | ||
695 | struct stk_sio_buffer *sbuf = NULL; | ||
696 | |||
697 | if (!(vma->vm_flags & VM_WRITE) || !(vma->vm_flags & VM_SHARED)) | ||
698 | return -EINVAL; | ||
699 | |||
700 | for (i = 0; i < dev->n_sbufs; i++) { | ||
701 | if (dev->sio_bufs[i].v4lbuf.m.offset == offset) { | ||
702 | sbuf = dev->sio_bufs + i; | ||
703 | break; | ||
704 | } | ||
705 | } | ||
706 | if (sbuf == NULL) | ||
707 | return -EINVAL; | ||
708 | ret = remap_vmalloc_range(vma, sbuf->buffer, 0); | ||
709 | if (ret) | ||
710 | return ret; | ||
711 | vma->vm_flags |= VM_DONTEXPAND; | ||
712 | vma->vm_private_data = sbuf; | ||
713 | vma->vm_ops = &stk_v4l_vm_ops; | ||
714 | sbuf->v4lbuf.flags |= V4L2_BUF_FLAG_MAPPED; | ||
715 | stk_v4l_vm_open(vma); | ||
716 | return 0; | ||
717 | } | ||
718 | |||
719 | /* v4l ioctl handlers */ | ||
720 | |||
721 | static int stk_vidioc_querycap(struct file *filp, | ||
722 | void *priv, struct v4l2_capability *cap) | ||
723 | { | ||
724 | strcpy(cap->driver, "stk"); | ||
725 | strcpy(cap->card, "stk"); | ||
726 | cap->version = DRIVER_VERSION_NUM; | ||
727 | |||
728 | cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | ||
729 | | V4L2_CAP_READWRITE | V4L2_CAP_STREAMING; | ||
730 | return 0; | ||
731 | } | ||
732 | |||
733 | static int stk_vidioc_enum_input(struct file *filp, | ||
734 | void *priv, struct v4l2_input *input) | ||
735 | { | ||
736 | if (input->index != 0) | ||
737 | return -EINVAL; | ||
738 | |||
739 | strcpy(input->name, "Syntek USB Camera"); | ||
740 | input->type = V4L2_INPUT_TYPE_CAMERA; | ||
741 | return 0; | ||
742 | } | ||
743 | |||
744 | |||
745 | static int stk_vidioc_g_input(struct file *filp, void *priv, unsigned int *i) | ||
746 | { | ||
747 | *i = 0; | ||
748 | return 0; | ||
749 | } | ||
750 | |||
751 | static int stk_vidioc_s_input(struct file *filp, void *priv, unsigned int i) | ||
752 | { | ||
753 | if (i != 0) | ||
754 | return -EINVAL; | ||
755 | else | ||
756 | return 0; | ||
757 | } | ||
758 | |||
759 | /* from vivi.c */ | ||
760 | static int stk_vidioc_s_std(struct file *filp, void *priv, v4l2_std_id *a) | ||
761 | { | ||
762 | return 0; | ||
763 | } | ||
764 | |||
765 | /* List of all V4Lv2 controls supported by the driver */ | ||
766 | static struct v4l2_queryctrl stk_controls[] = { | ||
767 | { | ||
768 | .id = V4L2_CID_BRIGHTNESS, | ||
769 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
770 | .name = "Brightness", | ||
771 | .minimum = 0, | ||
772 | .maximum = 0xffff, | ||
773 | .step = 0x0100, | ||
774 | .default_value = 0x6000, | ||
775 | }, | ||
776 | { | ||
777 | .id = V4L2_CID_HFLIP, | ||
778 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
779 | .name = "Horizontal Flip", | ||
780 | .minimum = 0, | ||
781 | .maximum = 1, | ||
782 | .step = 1, | ||
783 | .default_value = 1, | ||
784 | }, | ||
785 | { | ||
786 | .id = V4L2_CID_VFLIP, | ||
787 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
788 | .name = "Vertical Flip", | ||
789 | .minimum = 0, | ||
790 | .maximum = 1, | ||
791 | .step = 1, | ||
792 | .default_value = 1, | ||
793 | }, | ||
794 | }; | ||
795 | |||
796 | static int stk_vidioc_queryctrl(struct file *filp, | ||
797 | void *priv, struct v4l2_queryctrl *c) | ||
798 | { | ||
799 | int i; | ||
800 | int nbr; | ||
801 | nbr = ARRAY_SIZE(stk_controls); | ||
802 | |||
803 | for (i = 0; i < nbr; i++) { | ||
804 | if (stk_controls[i].id == c->id) { | ||
805 | memcpy(c, &stk_controls[i], | ||
806 | sizeof(struct v4l2_queryctrl)); | ||
807 | return 0; | ||
808 | } | ||
809 | } | ||
810 | return -EINVAL; | ||
811 | } | ||
812 | |||
813 | static int stk_vidioc_g_ctrl(struct file *filp, | ||
814 | void *priv, struct v4l2_control *c) | ||
815 | { | ||
816 | struct stk_camera *dev = priv; | ||
817 | switch (c->id) { | ||
818 | case V4L2_CID_BRIGHTNESS: | ||
819 | c->value = dev->vsettings.brightness; | ||
820 | break; | ||
821 | case V4L2_CID_HFLIP: | ||
822 | c->value = dev->vsettings.hflip; | ||
823 | break; | ||
824 | case V4L2_CID_VFLIP: | ||
825 | c->value = dev->vsettings.vflip; | ||
826 | break; | ||
827 | default: | ||
828 | return -EINVAL; | ||
829 | } | ||
830 | return 0; | ||
831 | } | ||
832 | |||
833 | static int stk_vidioc_s_ctrl(struct file *filp, | ||
834 | void *priv, struct v4l2_control *c) | ||
835 | { | ||
836 | struct stk_camera *dev = priv; | ||
837 | switch (c->id) { | ||
838 | case V4L2_CID_BRIGHTNESS: | ||
839 | dev->vsettings.brightness = c->value; | ||
840 | return stk_sensor_set_brightness(dev, c->value >> 8); | ||
841 | case V4L2_CID_HFLIP: | ||
842 | dev->vsettings.hflip = c->value; | ||
843 | return 0; | ||
844 | case V4L2_CID_VFLIP: | ||
845 | dev->vsettings.vflip = c->value; | ||
846 | return 0; | ||
847 | default: | ||
848 | return -EINVAL; | ||
849 | } | ||
850 | return 0; | ||
851 | } | ||
852 | |||
853 | |||
854 | static int stk_vidioc_enum_fmt_vid_cap(struct file *filp, | ||
855 | void *priv, struct v4l2_fmtdesc *fmtd) | ||
856 | { | ||
857 | switch (fmtd->index) { | ||
858 | case 0: | ||
859 | fmtd->pixelformat = V4L2_PIX_FMT_RGB565; | ||
860 | strcpy(fmtd->description, "r5g6b5"); | ||
861 | break; | ||
862 | case 1: | ||
863 | fmtd->pixelformat = V4L2_PIX_FMT_RGB565X; | ||
864 | strcpy(fmtd->description, "r5g6b5BE"); | ||
865 | break; | ||
866 | case 2: | ||
867 | fmtd->pixelformat = V4L2_PIX_FMT_UYVY; | ||
868 | strcpy(fmtd->description, "yuv4:2:2"); | ||
869 | break; | ||
870 | case 3: | ||
871 | fmtd->pixelformat = V4L2_PIX_FMT_SBGGR8; | ||
872 | strcpy(fmtd->description, "Raw bayer"); | ||
873 | break; | ||
874 | case 4: | ||
875 | fmtd->pixelformat = V4L2_PIX_FMT_YUYV; | ||
876 | strcpy(fmtd->description, "yuv4:2:2"); | ||
877 | break; | ||
878 | default: | ||
879 | return -EINVAL; | ||
880 | } | ||
881 | return 0; | ||
882 | } | ||
883 | |||
884 | static struct stk_size { | ||
885 | unsigned w; | ||
886 | unsigned h; | ||
887 | enum stk_mode m; | ||
888 | } stk_sizes[] = { | ||
889 | { .w = 1280, .h = 1024, .m = MODE_SXGA, }, | ||
890 | { .w = 640, .h = 480, .m = MODE_VGA, }, | ||
891 | { .w = 352, .h = 288, .m = MODE_CIF, }, | ||
892 | { .w = 320, .h = 240, .m = MODE_QVGA, }, | ||
893 | { .w = 176, .h = 144, .m = MODE_QCIF, }, | ||
894 | }; | ||
895 | |||
896 | static int stk_vidioc_g_fmt_vid_cap(struct file *filp, | ||
897 | void *priv, struct v4l2_format *f) | ||
898 | { | ||
899 | struct v4l2_pix_format *pix_format = &f->fmt.pix; | ||
900 | struct stk_camera *dev = priv; | ||
901 | int i; | ||
902 | |||
903 | for (i = 0; i < ARRAY_SIZE(stk_sizes) && | ||
904 | stk_sizes[i].m != dev->vsettings.mode; i++) | ||
905 | ; | ||
906 | if (i == ARRAY_SIZE(stk_sizes)) { | ||
907 | STK_ERROR("ERROR: mode invalid\n"); | ||
908 | return -EINVAL; | ||
909 | } | ||
910 | pix_format->width = stk_sizes[i].w; | ||
911 | pix_format->height = stk_sizes[i].h; | ||
912 | pix_format->field = V4L2_FIELD_NONE; | ||
913 | pix_format->colorspace = V4L2_COLORSPACE_SRGB; | ||
914 | pix_format->pixelformat = dev->vsettings.palette; | ||
915 | if (dev->vsettings.palette == V4L2_PIX_FMT_SBGGR8) | ||
916 | pix_format->bytesperline = pix_format->width; | ||
917 | else | ||
918 | pix_format->bytesperline = 2 * pix_format->width; | ||
919 | pix_format->sizeimage = pix_format->bytesperline | ||
920 | * pix_format->height; | ||
921 | return 0; | ||
922 | } | ||
923 | |||
924 | static int stk_vidioc_try_fmt_vid_cap(struct file *filp, | ||
925 | void *priv, struct v4l2_format *fmtd) | ||
926 | { | ||
927 | int i; | ||
928 | switch (fmtd->fmt.pix.pixelformat) { | ||
929 | case V4L2_PIX_FMT_RGB565: | ||
930 | case V4L2_PIX_FMT_RGB565X: | ||
931 | case V4L2_PIX_FMT_UYVY: | ||
932 | case V4L2_PIX_FMT_YUYV: | ||
933 | case V4L2_PIX_FMT_SBGGR8: | ||
934 | break; | ||
935 | default: | ||
936 | return -EINVAL; | ||
937 | } | ||
938 | for (i = 1; i < ARRAY_SIZE(stk_sizes); i++) { | ||
939 | if (fmtd->fmt.pix.width > stk_sizes[i].w) | ||
940 | break; | ||
941 | } | ||
942 | if (i == ARRAY_SIZE(stk_sizes) | ||
943 | || (abs(fmtd->fmt.pix.width - stk_sizes[i-1].w) | ||
944 | < abs(fmtd->fmt.pix.width - stk_sizes[i].w))) { | ||
945 | fmtd->fmt.pix.height = stk_sizes[i-1].h; | ||
946 | fmtd->fmt.pix.width = stk_sizes[i-1].w; | ||
947 | fmtd->fmt.pix.priv = i - 1; | ||
948 | } else { | ||
949 | fmtd->fmt.pix.height = stk_sizes[i].h; | ||
950 | fmtd->fmt.pix.width = stk_sizes[i].w; | ||
951 | fmtd->fmt.pix.priv = i; | ||
952 | } | ||
953 | |||
954 | fmtd->fmt.pix.field = V4L2_FIELD_NONE; | ||
955 | fmtd->fmt.pix.colorspace = V4L2_COLORSPACE_SRGB; | ||
956 | if (fmtd->fmt.pix.pixelformat == V4L2_PIX_FMT_SBGGR8) | ||
957 | fmtd->fmt.pix.bytesperline = fmtd->fmt.pix.width; | ||
958 | else | ||
959 | fmtd->fmt.pix.bytesperline = 2 * fmtd->fmt.pix.width; | ||
960 | fmtd->fmt.pix.sizeimage = fmtd->fmt.pix.bytesperline | ||
961 | * fmtd->fmt.pix.height; | ||
962 | return 0; | ||
963 | } | ||
964 | |||
965 | static int stk_setup_format(struct stk_camera *dev) | ||
966 | { | ||
967 | int i = 0; | ||
968 | int depth; | ||
969 | if (dev->vsettings.palette == V4L2_PIX_FMT_SBGGR8) | ||
970 | depth = 1; | ||
971 | else | ||
972 | depth = 2; | ||
973 | while (i < ARRAY_SIZE(stk_sizes) && | ||
974 | stk_sizes[i].m != dev->vsettings.mode) | ||
975 | i++; | ||
976 | if (i == ARRAY_SIZE(stk_sizes)) { | ||
977 | STK_ERROR("Something is broken in %s\n", __func__); | ||
978 | return -EFAULT; | ||
979 | } | ||
980 | /* This registers controls some timings, not sure of what. */ | ||
981 | stk_camera_write_reg(dev, 0x001b, 0x0e); | ||
982 | if (dev->vsettings.mode == MODE_SXGA) | ||
983 | stk_camera_write_reg(dev, 0x001c, 0x0e); | ||
984 | else | ||
985 | stk_camera_write_reg(dev, 0x001c, 0x46); | ||
986 | /* | ||
987 | * Registers 0x0115 0x0114 are the size of each line (bytes), | ||
988 | * regs 0x0117 0x0116 are the heigth of the image. | ||
989 | */ | ||
990 | stk_camera_write_reg(dev, 0x0115, | ||
991 | ((stk_sizes[i].w * depth) >> 8) & 0xff); | ||
992 | stk_camera_write_reg(dev, 0x0114, | ||
993 | (stk_sizes[i].w * depth) & 0xff); | ||
994 | stk_camera_write_reg(dev, 0x0117, | ||
995 | (stk_sizes[i].h >> 8) & 0xff); | ||
996 | stk_camera_write_reg(dev, 0x0116, | ||
997 | stk_sizes[i].h & 0xff); | ||
998 | return stk_sensor_configure(dev); | ||
999 | } | ||
1000 | |||
1001 | static int stk_vidioc_s_fmt_vid_cap(struct file *filp, | ||
1002 | void *priv, struct v4l2_format *fmtd) | ||
1003 | { | ||
1004 | int ret; | ||
1005 | struct stk_camera *dev = priv; | ||
1006 | |||
1007 | if (dev == NULL) | ||
1008 | return -ENODEV; | ||
1009 | if (!is_present(dev)) | ||
1010 | return -ENODEV; | ||
1011 | if (is_streaming(dev)) | ||
1012 | return -EBUSY; | ||
1013 | if (dev->owner && dev->owner != filp) | ||
1014 | return -EBUSY; | ||
1015 | ret = stk_vidioc_try_fmt_vid_cap(filp, priv, fmtd); | ||
1016 | if (ret) | ||
1017 | return ret; | ||
1018 | dev->owner = filp; | ||
1019 | |||
1020 | dev->vsettings.palette = fmtd->fmt.pix.pixelformat; | ||
1021 | stk_free_buffers(dev); | ||
1022 | dev->frame_size = fmtd->fmt.pix.sizeimage; | ||
1023 | dev->vsettings.mode = stk_sizes[fmtd->fmt.pix.priv].m; | ||
1024 | |||
1025 | stk_initialise(dev); | ||
1026 | return stk_setup_format(dev); | ||
1027 | } | ||
1028 | |||
1029 | static int stk_vidioc_reqbufs(struct file *filp, | ||
1030 | void *priv, struct v4l2_requestbuffers *rb) | ||
1031 | { | ||
1032 | struct stk_camera *dev = priv; | ||
1033 | |||
1034 | if (dev == NULL) | ||
1035 | return -ENODEV; | ||
1036 | if (rb->memory != V4L2_MEMORY_MMAP) | ||
1037 | return -EINVAL; | ||
1038 | if (is_streaming(dev) | ||
1039 | || (dev->owner && dev->owner != filp)) | ||
1040 | return -EBUSY; | ||
1041 | dev->owner = filp; | ||
1042 | |||
1043 | /*FIXME If they ask for zero, we must stop streaming and free */ | ||
1044 | if (rb->count < 3) | ||
1045 | rb->count = 3; | ||
1046 | /* Arbitrary limit */ | ||
1047 | else if (rb->count > 5) | ||
1048 | rb->count = 5; | ||
1049 | |||
1050 | stk_allocate_buffers(dev, rb->count); | ||
1051 | rb->count = dev->n_sbufs; | ||
1052 | return 0; | ||
1053 | } | ||
1054 | |||
1055 | static int stk_vidioc_querybuf(struct file *filp, | ||
1056 | void *priv, struct v4l2_buffer *buf) | ||
1057 | { | ||
1058 | struct stk_camera *dev = priv; | ||
1059 | struct stk_sio_buffer *sbuf; | ||
1060 | |||
1061 | if (buf->index >= dev->n_sbufs) | ||
1062 | return -EINVAL; | ||
1063 | sbuf = dev->sio_bufs + buf->index; | ||
1064 | *buf = sbuf->v4lbuf; | ||
1065 | return 0; | ||
1066 | } | ||
1067 | |||
1068 | static int stk_vidioc_qbuf(struct file *filp, | ||
1069 | void *priv, struct v4l2_buffer *buf) | ||
1070 | { | ||
1071 | struct stk_camera *dev = priv; | ||
1072 | struct stk_sio_buffer *sbuf; | ||
1073 | unsigned long flags; | ||
1074 | |||
1075 | if (buf->memory != V4L2_MEMORY_MMAP) | ||
1076 | return -EINVAL; | ||
1077 | |||
1078 | if (buf->index >= dev->n_sbufs) | ||
1079 | return -EINVAL; | ||
1080 | sbuf = dev->sio_bufs + buf->index; | ||
1081 | if (sbuf->v4lbuf.flags & V4L2_BUF_FLAG_QUEUED) | ||
1082 | return 0; | ||
1083 | sbuf->v4lbuf.flags |= V4L2_BUF_FLAG_QUEUED; | ||
1084 | sbuf->v4lbuf.flags &= ~V4L2_BUF_FLAG_DONE; | ||
1085 | spin_lock_irqsave(&dev->spinlock, flags); | ||
1086 | list_add_tail(&sbuf->list, &dev->sio_avail); | ||
1087 | *buf = sbuf->v4lbuf; | ||
1088 | spin_unlock_irqrestore(&dev->spinlock, flags); | ||
1089 | return 0; | ||
1090 | } | ||
1091 | |||
1092 | static int stk_vidioc_dqbuf(struct file *filp, | ||
1093 | void *priv, struct v4l2_buffer *buf) | ||
1094 | { | ||
1095 | struct stk_camera *dev = priv; | ||
1096 | struct stk_sio_buffer *sbuf; | ||
1097 | unsigned long flags; | ||
1098 | int ret; | ||
1099 | |||
1100 | if (!is_streaming(dev)) | ||
1101 | return -EINVAL; | ||
1102 | |||
1103 | if (filp->f_flags & O_NONBLOCK && list_empty(&dev->sio_full)) | ||
1104 | return -EWOULDBLOCK; | ||
1105 | ret = wait_event_interruptible(dev->wait_frame, | ||
1106 | !list_empty(&dev->sio_full) || !is_present(dev)); | ||
1107 | if (ret) | ||
1108 | return ret; | ||
1109 | if (!is_present(dev)) | ||
1110 | return -EIO; | ||
1111 | |||
1112 | spin_lock_irqsave(&dev->spinlock, flags); | ||
1113 | sbuf = list_first_entry(&dev->sio_full, struct stk_sio_buffer, list); | ||
1114 | list_del_init(&sbuf->list); | ||
1115 | spin_unlock_irqrestore(&dev->spinlock, flags); | ||
1116 | sbuf->v4lbuf.flags &= ~V4L2_BUF_FLAG_QUEUED; | ||
1117 | sbuf->v4lbuf.flags |= V4L2_BUF_FLAG_DONE; | ||
1118 | sbuf->v4lbuf.sequence = ++dev->sequence; | ||
1119 | do_gettimeofday(&sbuf->v4lbuf.timestamp); | ||
1120 | |||
1121 | *buf = sbuf->v4lbuf; | ||
1122 | return 0; | ||
1123 | } | ||
1124 | |||
1125 | static int stk_vidioc_streamon(struct file *filp, | ||
1126 | void *priv, enum v4l2_buf_type type) | ||
1127 | { | ||
1128 | struct stk_camera *dev = priv; | ||
1129 | if (is_streaming(dev)) | ||
1130 | return 0; | ||
1131 | if (dev->sio_bufs == NULL) | ||
1132 | return -EINVAL; | ||
1133 | dev->sequence = 0; | ||
1134 | return stk_start_stream(dev); | ||
1135 | } | ||
1136 | |||
1137 | static int stk_vidioc_streamoff(struct file *filp, | ||
1138 | void *priv, enum v4l2_buf_type type) | ||
1139 | { | ||
1140 | struct stk_camera *dev = priv; | ||
1141 | unsigned long flags; | ||
1142 | int i; | ||
1143 | stk_stop_stream(dev); | ||
1144 | spin_lock_irqsave(&dev->spinlock, flags); | ||
1145 | INIT_LIST_HEAD(&dev->sio_avail); | ||
1146 | INIT_LIST_HEAD(&dev->sio_full); | ||
1147 | for (i = 0; i < dev->n_sbufs; i++) { | ||
1148 | INIT_LIST_HEAD(&dev->sio_bufs[i].list); | ||
1149 | dev->sio_bufs[i].v4lbuf.flags = 0; | ||
1150 | } | ||
1151 | spin_unlock_irqrestore(&dev->spinlock, flags); | ||
1152 | return 0; | ||
1153 | } | ||
1154 | |||
1155 | |||
1156 | static int stk_vidioc_g_parm(struct file *filp, | ||
1157 | void *priv, struct v4l2_streamparm *sp) | ||
1158 | { | ||
1159 | /*FIXME This is not correct */ | ||
1160 | sp->parm.capture.timeperframe.numerator = 1; | ||
1161 | sp->parm.capture.timeperframe.denominator = 30; | ||
1162 | sp->parm.capture.readbuffers = 2; | ||
1163 | return 0; | ||
1164 | } | ||
1165 | |||
1166 | static int stk_vidioc_enum_framesizes(struct file *filp, | ||
1167 | void *priv, struct v4l2_frmsizeenum *frms) | ||
1168 | { | ||
1169 | if (frms->index >= ARRAY_SIZE(stk_sizes)) | ||
1170 | return -EINVAL; | ||
1171 | switch (frms->pixel_format) { | ||
1172 | case V4L2_PIX_FMT_RGB565: | ||
1173 | case V4L2_PIX_FMT_RGB565X: | ||
1174 | case V4L2_PIX_FMT_UYVY: | ||
1175 | case V4L2_PIX_FMT_YUYV: | ||
1176 | case V4L2_PIX_FMT_SBGGR8: | ||
1177 | frms->type = V4L2_FRMSIZE_TYPE_DISCRETE; | ||
1178 | frms->discrete.width = stk_sizes[frms->index].w; | ||
1179 | frms->discrete.height = stk_sizes[frms->index].h; | ||
1180 | return 0; | ||
1181 | default: return -EINVAL; | ||
1182 | } | ||
1183 | } | ||
1184 | |||
1185 | static struct v4l2_file_operations v4l_stk_fops = { | ||
1186 | .owner = THIS_MODULE, | ||
1187 | .open = v4l_stk_open, | ||
1188 | .release = v4l_stk_release, | ||
1189 | .read = v4l_stk_read, | ||
1190 | .poll = v4l_stk_poll, | ||
1191 | .mmap = v4l_stk_mmap, | ||
1192 | .ioctl = video_ioctl2, | ||
1193 | }; | ||
1194 | |||
1195 | static const struct v4l2_ioctl_ops v4l_stk_ioctl_ops = { | ||
1196 | .vidioc_querycap = stk_vidioc_querycap, | ||
1197 | .vidioc_enum_fmt_vid_cap = stk_vidioc_enum_fmt_vid_cap, | ||
1198 | .vidioc_try_fmt_vid_cap = stk_vidioc_try_fmt_vid_cap, | ||
1199 | .vidioc_s_fmt_vid_cap = stk_vidioc_s_fmt_vid_cap, | ||
1200 | .vidioc_g_fmt_vid_cap = stk_vidioc_g_fmt_vid_cap, | ||
1201 | .vidioc_enum_input = stk_vidioc_enum_input, | ||
1202 | .vidioc_s_input = stk_vidioc_s_input, | ||
1203 | .vidioc_g_input = stk_vidioc_g_input, | ||
1204 | .vidioc_s_std = stk_vidioc_s_std, | ||
1205 | .vidioc_reqbufs = stk_vidioc_reqbufs, | ||
1206 | .vidioc_querybuf = stk_vidioc_querybuf, | ||
1207 | .vidioc_qbuf = stk_vidioc_qbuf, | ||
1208 | .vidioc_dqbuf = stk_vidioc_dqbuf, | ||
1209 | .vidioc_streamon = stk_vidioc_streamon, | ||
1210 | .vidioc_streamoff = stk_vidioc_streamoff, | ||
1211 | .vidioc_queryctrl = stk_vidioc_queryctrl, | ||
1212 | .vidioc_g_ctrl = stk_vidioc_g_ctrl, | ||
1213 | .vidioc_s_ctrl = stk_vidioc_s_ctrl, | ||
1214 | .vidioc_g_parm = stk_vidioc_g_parm, | ||
1215 | .vidioc_enum_framesizes = stk_vidioc_enum_framesizes, | ||
1216 | }; | ||
1217 | |||
1218 | static void stk_v4l_dev_release(struct video_device *vd) | ||
1219 | { | ||
1220 | struct stk_camera *dev = vdev_to_camera(vd); | ||
1221 | |||
1222 | if (dev->sio_bufs != NULL || dev->isobufs != NULL) | ||
1223 | STK_ERROR("We are leaking memory\n"); | ||
1224 | usb_put_intf(dev->interface); | ||
1225 | kfree(dev); | ||
1226 | } | ||
1227 | |||
1228 | static struct video_device stk_v4l_data = { | ||
1229 | .name = "stkwebcam", | ||
1230 | .tvnorms = V4L2_STD_UNKNOWN, | ||
1231 | .current_norm = V4L2_STD_UNKNOWN, | ||
1232 | .fops = &v4l_stk_fops, | ||
1233 | .ioctl_ops = &v4l_stk_ioctl_ops, | ||
1234 | .release = stk_v4l_dev_release, | ||
1235 | }; | ||
1236 | |||
1237 | |||
1238 | static int stk_register_video_device(struct stk_camera *dev) | ||
1239 | { | ||
1240 | int err; | ||
1241 | |||
1242 | dev->vdev = stk_v4l_data; | ||
1243 | dev->vdev.debug = debug; | ||
1244 | dev->vdev.parent = &dev->interface->dev; | ||
1245 | err = video_register_device(&dev->vdev, VFL_TYPE_GRABBER, -1); | ||
1246 | if (err) | ||
1247 | STK_ERROR("v4l registration failed\n"); | ||
1248 | else | ||
1249 | STK_INFO("Syntek USB2.0 Camera is now controlling device %s\n", | ||
1250 | video_device_node_name(&dev->vdev)); | ||
1251 | return err; | ||
1252 | } | ||
1253 | |||
1254 | |||
1255 | /* USB Stuff */ | ||
1256 | |||
1257 | static int stk_camera_probe(struct usb_interface *interface, | ||
1258 | const struct usb_device_id *id) | ||
1259 | { | ||
1260 | int i; | ||
1261 | int err = 0; | ||
1262 | |||
1263 | struct stk_camera *dev = NULL; | ||
1264 | struct usb_device *udev = interface_to_usbdev(interface); | ||
1265 | struct usb_host_interface *iface_desc; | ||
1266 | struct usb_endpoint_descriptor *endpoint; | ||
1267 | |||
1268 | dev = kzalloc(sizeof(struct stk_camera), GFP_KERNEL); | ||
1269 | if (dev == NULL) { | ||
1270 | STK_ERROR("Out of memory !\n"); | ||
1271 | return -ENOMEM; | ||
1272 | } | ||
1273 | |||
1274 | spin_lock_init(&dev->spinlock); | ||
1275 | init_waitqueue_head(&dev->wait_frame); | ||
1276 | |||
1277 | dev->udev = udev; | ||
1278 | dev->interface = interface; | ||
1279 | usb_get_intf(interface); | ||
1280 | |||
1281 | dev->vsettings.vflip = vflip; | ||
1282 | dev->vsettings.hflip = hflip; | ||
1283 | dev->n_sbufs = 0; | ||
1284 | set_present(dev); | ||
1285 | |||
1286 | /* Set up the endpoint information | ||
1287 | * use only the first isoc-in endpoint | ||
1288 | * for the current alternate setting */ | ||
1289 | iface_desc = interface->cur_altsetting; | ||
1290 | |||
1291 | for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { | ||
1292 | endpoint = &iface_desc->endpoint[i].desc; | ||
1293 | |||
1294 | if (!dev->isoc_ep | ||
1295 | && usb_endpoint_is_isoc_in(endpoint)) { | ||
1296 | /* we found an isoc in endpoint */ | ||
1297 | dev->isoc_ep = usb_endpoint_num(endpoint); | ||
1298 | break; | ||
1299 | } | ||
1300 | } | ||
1301 | if (!dev->isoc_ep) { | ||
1302 | STK_ERROR("Could not find isoc-in endpoint"); | ||
1303 | err = -ENODEV; | ||
1304 | goto error; | ||
1305 | } | ||
1306 | dev->vsettings.brightness = 0x7fff; | ||
1307 | dev->vsettings.palette = V4L2_PIX_FMT_RGB565; | ||
1308 | dev->vsettings.mode = MODE_VGA; | ||
1309 | dev->frame_size = 640 * 480 * 2; | ||
1310 | |||
1311 | INIT_LIST_HEAD(&dev->sio_avail); | ||
1312 | INIT_LIST_HEAD(&dev->sio_full); | ||
1313 | |||
1314 | usb_set_intfdata(interface, dev); | ||
1315 | |||
1316 | err = stk_register_video_device(dev); | ||
1317 | if (err) | ||
1318 | goto error; | ||
1319 | |||
1320 | return 0; | ||
1321 | |||
1322 | error: | ||
1323 | kfree(dev); | ||
1324 | return err; | ||
1325 | } | ||
1326 | |||
1327 | static void stk_camera_disconnect(struct usb_interface *interface) | ||
1328 | { | ||
1329 | struct stk_camera *dev = usb_get_intfdata(interface); | ||
1330 | |||
1331 | usb_set_intfdata(interface, NULL); | ||
1332 | unset_present(dev); | ||
1333 | |||
1334 | wake_up_interruptible(&dev->wait_frame); | ||
1335 | |||
1336 | STK_INFO("Syntek USB2.0 Camera release resources device %s\n", | ||
1337 | video_device_node_name(&dev->vdev)); | ||
1338 | |||
1339 | video_unregister_device(&dev->vdev); | ||
1340 | } | ||
1341 | |||
1342 | #ifdef CONFIG_PM | ||
1343 | static int stk_camera_suspend(struct usb_interface *intf, pm_message_t message) | ||
1344 | { | ||
1345 | struct stk_camera *dev = usb_get_intfdata(intf); | ||
1346 | if (is_streaming(dev)) { | ||
1347 | stk_stop_stream(dev); | ||
1348 | /* yes, this is ugly */ | ||
1349 | set_streaming(dev); | ||
1350 | } | ||
1351 | return 0; | ||
1352 | } | ||
1353 | |||
1354 | static int stk_camera_resume(struct usb_interface *intf) | ||
1355 | { | ||
1356 | struct stk_camera *dev = usb_get_intfdata(intf); | ||
1357 | if (!is_initialised(dev)) | ||
1358 | return 0; | ||
1359 | unset_initialised(dev); | ||
1360 | stk_initialise(dev); | ||
1361 | stk_camera_write_reg(dev, 0x0, 0x49); | ||
1362 | stk_setup_format(dev); | ||
1363 | if (is_streaming(dev)) | ||
1364 | stk_start_stream(dev); | ||
1365 | return 0; | ||
1366 | } | ||
1367 | #endif | ||
1368 | |||
1369 | static struct usb_driver stk_camera_driver = { | ||
1370 | .name = "stkwebcam", | ||
1371 | .probe = stk_camera_probe, | ||
1372 | .disconnect = stk_camera_disconnect, | ||
1373 | .id_table = stkwebcam_table, | ||
1374 | #ifdef CONFIG_PM | ||
1375 | .suspend = stk_camera_suspend, | ||
1376 | .resume = stk_camera_resume, | ||
1377 | #endif | ||
1378 | }; | ||
1379 | |||
1380 | module_usb_driver(stk_camera_driver); | ||
diff --git a/drivers/media/video/stk-webcam.h b/drivers/media/video/stk-webcam.h deleted file mode 100644 index 9f6736637571..000000000000 --- a/drivers/media/video/stk-webcam.h +++ /dev/null | |||
@@ -1,134 +0,0 @@ | |||
1 | /* | ||
2 | * stk-webcam.h : Driver for Syntek 1125 USB webcam controller | ||
3 | * | ||
4 | * Copyright (C) 2006 Nicolas VIVIEN | ||
5 | * Copyright 2007-2008 Jaime Velasco Juan <jsagarribay@gmail.com> | ||
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 | * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
20 | */ | ||
21 | |||
22 | #ifndef STKWEBCAM_H | ||
23 | #define STKWEBCAM_H | ||
24 | |||
25 | #include <linux/usb.h> | ||
26 | #include <media/v4l2-common.h> | ||
27 | |||
28 | #define DRIVER_VERSION "v0.0.1" | ||
29 | #define DRIVER_VERSION_NUM 0x000001 | ||
30 | |||
31 | #define MAX_ISO_BUFS 3 | ||
32 | #define ISO_FRAMES_PER_DESC 16 | ||
33 | #define ISO_MAX_FRAME_SIZE 3 * 1024 | ||
34 | #define ISO_BUFFER_SIZE (ISO_FRAMES_PER_DESC * ISO_MAX_FRAME_SIZE) | ||
35 | |||
36 | |||
37 | #define PREFIX "stkwebcam: " | ||
38 | #define STK_INFO(str, args...) printk(KERN_INFO PREFIX str, ##args) | ||
39 | #define STK_ERROR(str, args...) printk(KERN_ERR PREFIX str, ##args) | ||
40 | #define STK_WARNING(str, args...) printk(KERN_WARNING PREFIX str, ##args) | ||
41 | |||
42 | struct stk_iso_buf { | ||
43 | void *data; | ||
44 | int length; | ||
45 | int read; | ||
46 | struct urb *urb; | ||
47 | }; | ||
48 | |||
49 | /* Streaming IO buffers */ | ||
50 | struct stk_sio_buffer { | ||
51 | struct v4l2_buffer v4lbuf; | ||
52 | char *buffer; | ||
53 | int mapcount; | ||
54 | struct stk_camera *dev; | ||
55 | struct list_head list; | ||
56 | }; | ||
57 | |||
58 | enum stk_mode {MODE_VGA, MODE_SXGA, MODE_CIF, MODE_QVGA, MODE_QCIF}; | ||
59 | |||
60 | struct stk_video { | ||
61 | enum stk_mode mode; | ||
62 | int brightness; | ||
63 | __u32 palette; | ||
64 | int hflip; | ||
65 | int vflip; | ||
66 | }; | ||
67 | |||
68 | enum stk_status { | ||
69 | S_PRESENT = 1, | ||
70 | S_INITIALISED = 2, | ||
71 | S_MEMALLOCD = 4, | ||
72 | S_STREAMING = 8, | ||
73 | }; | ||
74 | #define is_present(dev) ((dev)->status & S_PRESENT) | ||
75 | #define is_initialised(dev) ((dev)->status & S_INITIALISED) | ||
76 | #define is_streaming(dev) ((dev)->status & S_STREAMING) | ||
77 | #define is_memallocd(dev) ((dev)->status & S_MEMALLOCD) | ||
78 | #define set_present(dev) ((dev)->status = S_PRESENT) | ||
79 | #define unset_present(dev) ((dev)->status &= \ | ||
80 | ~(S_PRESENT|S_INITIALISED|S_STREAMING)) | ||
81 | #define set_initialised(dev) ((dev)->status |= S_INITIALISED) | ||
82 | #define unset_initialised(dev) ((dev)->status &= ~S_INITIALISED) | ||
83 | #define set_memallocd(dev) ((dev)->status |= S_MEMALLOCD) | ||
84 | #define unset_memallocd(dev) ((dev)->status &= ~S_MEMALLOCD) | ||
85 | #define set_streaming(dev) ((dev)->status |= S_STREAMING) | ||
86 | #define unset_streaming(dev) ((dev)->status &= ~S_STREAMING) | ||
87 | |||
88 | struct regval { | ||
89 | unsigned reg; | ||
90 | unsigned val; | ||
91 | }; | ||
92 | |||
93 | struct stk_camera { | ||
94 | struct video_device vdev; | ||
95 | struct usb_device *udev; | ||
96 | struct usb_interface *interface; | ||
97 | int webcam_model; | ||
98 | struct file *owner; | ||
99 | |||
100 | u8 isoc_ep; | ||
101 | |||
102 | /* Not sure if this is right */ | ||
103 | atomic_t urbs_used; | ||
104 | |||
105 | struct stk_video vsettings; | ||
106 | |||
107 | enum stk_status status; | ||
108 | |||
109 | spinlock_t spinlock; | ||
110 | wait_queue_head_t wait_frame; | ||
111 | |||
112 | struct stk_iso_buf *isobufs; | ||
113 | |||
114 | int frame_size; | ||
115 | /* Streaming buffers */ | ||
116 | unsigned int n_sbufs; | ||
117 | struct stk_sio_buffer *sio_bufs; | ||
118 | struct list_head sio_avail; | ||
119 | struct list_head sio_full; | ||
120 | unsigned sequence; | ||
121 | }; | ||
122 | |||
123 | #define vdev_to_camera(d) container_of(d, struct stk_camera, vdev) | ||
124 | |||
125 | int stk_camera_write_reg(struct stk_camera *, u16, u8); | ||
126 | int stk_camera_read_reg(struct stk_camera *, u16, int *); | ||
127 | |||
128 | int stk_sensor_init(struct stk_camera *); | ||
129 | int stk_sensor_configure(struct stk_camera *); | ||
130 | int stk_sensor_sleep(struct stk_camera *dev); | ||
131 | int stk_sensor_wakeup(struct stk_camera *dev); | ||
132 | int stk_sensor_set_brightness(struct stk_camera *dev, int br); | ||
133 | |||
134 | #endif | ||
diff --git a/drivers/media/video/zr364xx.c b/drivers/media/video/zr364xx.c deleted file mode 100644 index 9afab35878b4..000000000000 --- a/drivers/media/video/zr364xx.c +++ /dev/null | |||
@@ -1,1643 +0,0 @@ | |||
1 | /* | ||
2 | * Zoran 364xx based USB webcam module version 0.73 | ||
3 | * | ||
4 | * Allows you to use your USB webcam with V4L2 applications | ||
5 | * This is still in heavy developpement ! | ||
6 | * | ||
7 | * Copyright (C) 2004 Antoine Jacquet <royale@zerezo.com> | ||
8 | * http://royale.zerezo.com/zr364xx/ | ||
9 | * | ||
10 | * Heavily inspired by usb-skeleton.c, vicam.c, cpia.c and spca50x.c drivers | ||
11 | * V4L2 version inspired by meye.c driver | ||
12 | * | ||
13 | * Some video buffer code by Lamarque based on s2255drv.c and vivi.c drivers. | ||
14 | * | ||
15 | * This program is free software; you can redistribute it and/or modify | ||
16 | * it under the terms of the GNU General Public License as published by | ||
17 | * the Free Software Foundation; either version 2 of the License, or | ||
18 | * (at your option) any later version. | ||
19 | * | ||
20 | * This program is distributed in the hope that it will be useful, | ||
21 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
22 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
23 | * GNU General Public License for more details. | ||
24 | * | ||
25 | * You should have received a copy of the GNU General Public License | ||
26 | * along with this program; if not, write to the Free Software | ||
27 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
28 | */ | ||
29 | |||
30 | |||
31 | #include <linux/module.h> | ||
32 | #include <linux/init.h> | ||
33 | #include <linux/usb.h> | ||
34 | #include <linux/vmalloc.h> | ||
35 | #include <linux/slab.h> | ||
36 | #include <linux/proc_fs.h> | ||
37 | #include <linux/highmem.h> | ||
38 | #include <media/v4l2-common.h> | ||
39 | #include <media/v4l2-ioctl.h> | ||
40 | #include <media/v4l2-device.h> | ||
41 | #include <media/v4l2-ctrls.h> | ||
42 | #include <media/v4l2-fh.h> | ||
43 | #include <media/v4l2-event.h> | ||
44 | #include <media/videobuf-vmalloc.h> | ||
45 | |||
46 | |||
47 | /* Version Information */ | ||
48 | #define DRIVER_VERSION "0.7.4" | ||
49 | #define DRIVER_AUTHOR "Antoine Jacquet, http://royale.zerezo.com/" | ||
50 | #define DRIVER_DESC "Zoran 364xx" | ||
51 | |||
52 | |||
53 | /* Camera */ | ||
54 | #define FRAMES 1 | ||
55 | #define MAX_FRAME_SIZE 200000 | ||
56 | #define BUFFER_SIZE 0x1000 | ||
57 | #define CTRL_TIMEOUT 500 | ||
58 | |||
59 | #define ZR364XX_DEF_BUFS 4 | ||
60 | #define ZR364XX_READ_IDLE 0 | ||
61 | #define ZR364XX_READ_FRAME 1 | ||
62 | |||
63 | /* Debug macro */ | ||
64 | #define DBG(fmt, args...) \ | ||
65 | do { \ | ||
66 | if (debug) { \ | ||
67 | printk(KERN_INFO KBUILD_MODNAME " " fmt, ##args); \ | ||
68 | } \ | ||
69 | } while (0) | ||
70 | |||
71 | /*#define FULL_DEBUG 1*/ | ||
72 | #ifdef FULL_DEBUG | ||
73 | #define _DBG DBG | ||
74 | #else | ||
75 | #define _DBG(fmt, args...) | ||
76 | #endif | ||
77 | |||
78 | /* Init methods, need to find nicer names for these | ||
79 | * the exact names of the chipsets would be the best if someone finds it */ | ||
80 | #define METHOD0 0 | ||
81 | #define METHOD1 1 | ||
82 | #define METHOD2 2 | ||
83 | #define METHOD3 3 | ||
84 | |||
85 | |||
86 | /* Module parameters */ | ||
87 | static int debug; | ||
88 | static int mode; | ||
89 | |||
90 | |||
91 | /* Module parameters interface */ | ||
92 | module_param(debug, int, 0644); | ||
93 | MODULE_PARM_DESC(debug, "Debug level"); | ||
94 | module_param(mode, int, 0644); | ||
95 | MODULE_PARM_DESC(mode, "0 = 320x240, 1 = 160x120, 2 = 640x480"); | ||
96 | |||
97 | |||
98 | /* Devices supported by this driver | ||
99 | * .driver_info contains the init method used by the camera */ | ||
100 | static struct usb_device_id device_table[] = { | ||
101 | {USB_DEVICE(0x08ca, 0x0109), .driver_info = METHOD0 }, | ||
102 | {USB_DEVICE(0x041e, 0x4024), .driver_info = METHOD0 }, | ||
103 | {USB_DEVICE(0x0d64, 0x0108), .driver_info = METHOD0 }, | ||
104 | {USB_DEVICE(0x0546, 0x3187), .driver_info = METHOD0 }, | ||
105 | {USB_DEVICE(0x0d64, 0x3108), .driver_info = METHOD0 }, | ||
106 | {USB_DEVICE(0x0595, 0x4343), .driver_info = METHOD0 }, | ||
107 | {USB_DEVICE(0x0bb0, 0x500d), .driver_info = METHOD0 }, | ||
108 | {USB_DEVICE(0x0feb, 0x2004), .driver_info = METHOD0 }, | ||
109 | {USB_DEVICE(0x055f, 0xb500), .driver_info = METHOD0 }, | ||
110 | {USB_DEVICE(0x08ca, 0x2062), .driver_info = METHOD2 }, | ||
111 | {USB_DEVICE(0x052b, 0x1a18), .driver_info = METHOD1 }, | ||
112 | {USB_DEVICE(0x04c8, 0x0729), .driver_info = METHOD0 }, | ||
113 | {USB_DEVICE(0x04f2, 0xa208), .driver_info = METHOD0 }, | ||
114 | {USB_DEVICE(0x0784, 0x0040), .driver_info = METHOD1 }, | ||
115 | {USB_DEVICE(0x06d6, 0x0034), .driver_info = METHOD0 }, | ||
116 | {USB_DEVICE(0x0a17, 0x0062), .driver_info = METHOD2 }, | ||
117 | {USB_DEVICE(0x06d6, 0x003b), .driver_info = METHOD0 }, | ||
118 | {USB_DEVICE(0x0a17, 0x004e), .driver_info = METHOD2 }, | ||
119 | {USB_DEVICE(0x041e, 0x405d), .driver_info = METHOD2 }, | ||
120 | {USB_DEVICE(0x08ca, 0x2102), .driver_info = METHOD3 }, | ||
121 | {USB_DEVICE(0x06d6, 0x003d), .driver_info = METHOD0 }, | ||
122 | {} /* Terminating entry */ | ||
123 | }; | ||
124 | |||
125 | MODULE_DEVICE_TABLE(usb, device_table); | ||
126 | |||
127 | /* frame structure */ | ||
128 | struct zr364xx_framei { | ||
129 | unsigned long ulState; /* ulState:ZR364XX_READ_IDLE, | ||
130 | ZR364XX_READ_FRAME */ | ||
131 | void *lpvbits; /* image data */ | ||
132 | unsigned long cur_size; /* current data copied to it */ | ||
133 | }; | ||
134 | |||
135 | /* image buffer structure */ | ||
136 | struct zr364xx_bufferi { | ||
137 | unsigned long dwFrames; /* number of frames in buffer */ | ||
138 | struct zr364xx_framei frame[FRAMES]; /* array of FRAME structures */ | ||
139 | }; | ||
140 | |||
141 | struct zr364xx_dmaqueue { | ||
142 | struct list_head active; | ||
143 | struct zr364xx_camera *cam; | ||
144 | }; | ||
145 | |||
146 | struct zr364xx_pipeinfo { | ||
147 | u32 transfer_size; | ||
148 | u8 *transfer_buffer; | ||
149 | u32 state; | ||
150 | void *stream_urb; | ||
151 | void *cam; /* back pointer to zr364xx_camera struct */ | ||
152 | u32 err_count; | ||
153 | u32 idx; | ||
154 | }; | ||
155 | |||
156 | struct zr364xx_fmt { | ||
157 | char *name; | ||
158 | u32 fourcc; | ||
159 | int depth; | ||
160 | }; | ||
161 | |||
162 | /* image formats. */ | ||
163 | static const struct zr364xx_fmt formats[] = { | ||
164 | { | ||
165 | .name = "JPG", | ||
166 | .fourcc = V4L2_PIX_FMT_JPEG, | ||
167 | .depth = 24 | ||
168 | } | ||
169 | }; | ||
170 | |||
171 | /* Camera stuff */ | ||
172 | struct zr364xx_camera { | ||
173 | struct usb_device *udev; /* save off the usb device pointer */ | ||
174 | struct usb_interface *interface;/* the interface for this device */ | ||
175 | struct v4l2_device v4l2_dev; | ||
176 | struct v4l2_ctrl_handler ctrl_handler; | ||
177 | struct video_device vdev; /* v4l video device */ | ||
178 | struct v4l2_fh *owner; /* owns the streaming */ | ||
179 | int nb; | ||
180 | struct zr364xx_bufferi buffer; | ||
181 | int skip; | ||
182 | int width; | ||
183 | int height; | ||
184 | int method; | ||
185 | struct mutex lock; | ||
186 | |||
187 | spinlock_t slock; | ||
188 | struct zr364xx_dmaqueue vidq; | ||
189 | int last_frame; | ||
190 | int cur_frame; | ||
191 | unsigned long frame_count; | ||
192 | int b_acquire; | ||
193 | struct zr364xx_pipeinfo pipe[1]; | ||
194 | |||
195 | u8 read_endpoint; | ||
196 | |||
197 | const struct zr364xx_fmt *fmt; | ||
198 | struct videobuf_queue vb_vidq; | ||
199 | bool was_streaming; | ||
200 | }; | ||
201 | |||
202 | /* buffer for one video frame */ | ||
203 | struct zr364xx_buffer { | ||
204 | /* common v4l buffer stuff -- must be first */ | ||
205 | struct videobuf_buffer vb; | ||
206 | const struct zr364xx_fmt *fmt; | ||
207 | }; | ||
208 | |||
209 | /* function used to send initialisation commands to the camera */ | ||
210 | static int send_control_msg(struct usb_device *udev, u8 request, u16 value, | ||
211 | u16 index, unsigned char *cp, u16 size) | ||
212 | { | ||
213 | int status; | ||
214 | |||
215 | unsigned char *transfer_buffer = kmalloc(size, GFP_KERNEL); | ||
216 | if (!transfer_buffer) { | ||
217 | dev_err(&udev->dev, "kmalloc(%d) failed\n", size); | ||
218 | return -ENOMEM; | ||
219 | } | ||
220 | |||
221 | memcpy(transfer_buffer, cp, size); | ||
222 | |||
223 | status = usb_control_msg(udev, | ||
224 | usb_sndctrlpipe(udev, 0), | ||
225 | request, | ||
226 | USB_DIR_OUT | USB_TYPE_VENDOR | | ||
227 | USB_RECIP_DEVICE, value, index, | ||
228 | transfer_buffer, size, CTRL_TIMEOUT); | ||
229 | |||
230 | kfree(transfer_buffer); | ||
231 | return status; | ||
232 | } | ||
233 | |||
234 | |||
235 | /* Control messages sent to the camera to initialize it | ||
236 | * and launch the capture */ | ||
237 | typedef struct { | ||
238 | unsigned int value; | ||
239 | unsigned int size; | ||
240 | unsigned char *bytes; | ||
241 | } message; | ||
242 | |||
243 | /* method 0 */ | ||
244 | static unsigned char m0d1[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; | ||
245 | static unsigned char m0d2[] = { 0, 0, 0, 0, 0, 0 }; | ||
246 | static unsigned char m0d3[] = { 0, 0 }; | ||
247 | static message m0[] = { | ||
248 | {0x1f30, 0, NULL}, | ||
249 | {0xd000, 0, NULL}, | ||
250 | {0x3370, sizeof(m0d1), m0d1}, | ||
251 | {0x2000, 0, NULL}, | ||
252 | {0x2f0f, 0, NULL}, | ||
253 | {0x2610, sizeof(m0d2), m0d2}, | ||
254 | {0xe107, 0, NULL}, | ||
255 | {0x2502, 0, NULL}, | ||
256 | {0x1f70, 0, NULL}, | ||
257 | {0xd000, 0, NULL}, | ||
258 | {0x9a01, sizeof(m0d3), m0d3}, | ||
259 | {-1, -1, NULL} | ||
260 | }; | ||
261 | |||
262 | /* method 1 */ | ||
263 | static unsigned char m1d1[] = { 0xff, 0xff }; | ||
264 | static unsigned char m1d2[] = { 0x00, 0x00 }; | ||
265 | static message m1[] = { | ||
266 | {0x1f30, 0, NULL}, | ||
267 | {0xd000, 0, NULL}, | ||
268 | {0xf000, 0, NULL}, | ||
269 | {0x2000, 0, NULL}, | ||
270 | {0x2f0f, 0, NULL}, | ||
271 | {0x2650, 0, NULL}, | ||
272 | {0xe107, 0, NULL}, | ||
273 | {0x2502, sizeof(m1d1), m1d1}, | ||
274 | {0x1f70, 0, NULL}, | ||
275 | {0xd000, 0, NULL}, | ||
276 | {0xd000, 0, NULL}, | ||
277 | {0xd000, 0, NULL}, | ||
278 | {0x9a01, sizeof(m1d2), m1d2}, | ||
279 | {-1, -1, NULL} | ||
280 | }; | ||
281 | |||
282 | /* method 2 */ | ||
283 | static unsigned char m2d1[] = { 0xff, 0xff }; | ||
284 | static message m2[] = { | ||
285 | {0x1f30, 0, NULL}, | ||
286 | {0xf000, 0, NULL}, | ||
287 | {0x2000, 0, NULL}, | ||
288 | {0x2f0f, 0, NULL}, | ||
289 | {0x2650, 0, NULL}, | ||
290 | {0xe107, 0, NULL}, | ||
291 | {0x2502, sizeof(m2d1), m2d1}, | ||
292 | {0x1f70, 0, NULL}, | ||
293 | {-1, -1, NULL} | ||
294 | }; | ||
295 | |||
296 | /* init table */ | ||
297 | static message *init[4] = { m0, m1, m2, m2 }; | ||
298 | |||
299 | |||
300 | /* JPEG static data in header (Huffman table, etc) */ | ||
301 | static unsigned char header1[] = { | ||
302 | 0xFF, 0xD8, | ||
303 | /* | ||
304 | 0xFF, 0xE0, 0x00, 0x10, 'J', 'F', 'I', 'F', | ||
305 | 0x00, 0x01, 0x01, 0x00, 0x33, 0x8A, 0x00, 0x00, 0x33, 0x88, | ||
306 | */ | ||
307 | 0xFF, 0xDB, 0x00, 0x84 | ||
308 | }; | ||
309 | static unsigned char header2[] = { | ||
310 | 0xFF, 0xC4, 0x00, 0x1F, 0x00, 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, | ||
311 | 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
312 | 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, | ||
313 | 0xFF, 0xC4, 0x00, 0xB5, 0x10, 0x00, 0x02, 0x01, 0x03, 0x03, 0x02, | ||
314 | 0x04, 0x03, 0x05, 0x05, 0x04, 0x04, 0x00, 0x00, 0x01, 0x7D, 0x01, | ||
315 | 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21, 0x31, 0x41, 0x06, | ||
316 | 0x13, 0x51, 0x61, 0x07, 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xA1, | ||
317 | 0x08, 0x23, 0x42, 0xB1, 0xC1, 0x15, 0x52, 0xD1, 0xF0, 0x24, 0x33, | ||
318 | 0x62, 0x72, 0x82, 0x09, 0x0A, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x25, | ||
319 | 0x26, 0x27, 0x28, 0x29, 0x2A, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, | ||
320 | 0x3A, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x53, 0x54, | ||
321 | 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66, 0x67, | ||
322 | 0x68, 0x69, 0x6A, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, | ||
323 | 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x92, 0x93, 0x94, | ||
324 | 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, | ||
325 | 0xA7, 0xA8, 0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, | ||
326 | 0xB9, 0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, | ||
327 | 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xE1, 0xE2, | ||
328 | 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xF1, 0xF2, 0xF3, | ||
329 | 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFF, 0xC4, 0x00, 0x1F, | ||
330 | 0x01, 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, | ||
331 | 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, | ||
332 | 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0xFF, 0xC4, 0x00, 0xB5, | ||
333 | 0x11, 0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04, 0x07, 0x05, | ||
334 | 0x04, 0x04, 0x00, 0x01, 0x02, 0x77, 0x00, 0x01, 0x02, 0x03, 0x11, | ||
335 | 0x04, 0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71, | ||
336 | 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, 0xA1, 0xB1, 0xC1, | ||
337 | 0x09, 0x23, 0x33, 0x52, 0xF0, 0x15, 0x62, 0x72, 0xD1, 0x0A, 0x16, | ||
338 | 0x24, 0x34, 0xE1, 0x25, 0xF1, 0x17, 0x18, 0x19, 0x1A, 0x26, 0x27, | ||
339 | 0x28, 0x29, 0x2A, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x43, 0x44, | ||
340 | 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56, 0x57, | ||
341 | 0x58, 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, | ||
342 | 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x82, 0x83, 0x84, | ||
343 | 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x92, 0x93, 0x94, 0x95, 0x96, | ||
344 | 0x97, 0x98, 0x99, 0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, | ||
345 | 0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, | ||
346 | 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xD2, 0xD3, | ||
347 | 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xE2, 0xE3, 0xE4, 0xE5, | ||
348 | 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, | ||
349 | 0xF8, 0xF9, 0xFA, 0xFF, 0xC0, 0x00, 0x11, 0x08, 0x00, 0xF0, 0x01, | ||
350 | 0x40, 0x03, 0x01, 0x21, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, | ||
351 | 0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, | ||
352 | 0x00, 0x3F, 0x00 | ||
353 | }; | ||
354 | static unsigned char header3; | ||
355 | |||
356 | /* ------------------------------------------------------------------ | ||
357 | Videobuf operations | ||
358 | ------------------------------------------------------------------*/ | ||
359 | |||
360 | static int buffer_setup(struct videobuf_queue *vq, unsigned int *count, | ||
361 | unsigned int *size) | ||
362 | { | ||
363 | struct zr364xx_camera *cam = vq->priv_data; | ||
364 | |||
365 | *size = cam->width * cam->height * (cam->fmt->depth >> 3); | ||
366 | |||
367 | if (*count == 0) | ||
368 | *count = ZR364XX_DEF_BUFS; | ||
369 | |||
370 | if (*size * *count > ZR364XX_DEF_BUFS * 1024 * 1024) | ||
371 | *count = (ZR364XX_DEF_BUFS * 1024 * 1024) / *size; | ||
372 | |||
373 | return 0; | ||
374 | } | ||
375 | |||
376 | static void free_buffer(struct videobuf_queue *vq, struct zr364xx_buffer *buf) | ||
377 | { | ||
378 | _DBG("%s\n", __func__); | ||
379 | |||
380 | if (in_interrupt()) | ||
381 | BUG(); | ||
382 | |||
383 | videobuf_vmalloc_free(&buf->vb); | ||
384 | buf->vb.state = VIDEOBUF_NEEDS_INIT; | ||
385 | } | ||
386 | |||
387 | static int buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb, | ||
388 | enum v4l2_field field) | ||
389 | { | ||
390 | struct zr364xx_camera *cam = vq->priv_data; | ||
391 | struct zr364xx_buffer *buf = container_of(vb, struct zr364xx_buffer, | ||
392 | vb); | ||
393 | int rc; | ||
394 | |||
395 | DBG("%s, field=%d, fmt name = %s\n", __func__, field, cam->fmt != NULL ? | ||
396 | cam->fmt->name : ""); | ||
397 | if (cam->fmt == NULL) | ||
398 | return -EINVAL; | ||
399 | |||
400 | buf->vb.size = cam->width * cam->height * (cam->fmt->depth >> 3); | ||
401 | |||
402 | if (buf->vb.baddr != 0 && buf->vb.bsize < buf->vb.size) { | ||
403 | DBG("invalid buffer prepare\n"); | ||
404 | return -EINVAL; | ||
405 | } | ||
406 | |||
407 | buf->fmt = cam->fmt; | ||
408 | buf->vb.width = cam->width; | ||
409 | buf->vb.height = cam->height; | ||
410 | buf->vb.field = field; | ||
411 | |||
412 | if (buf->vb.state == VIDEOBUF_NEEDS_INIT) { | ||
413 | rc = videobuf_iolock(vq, &buf->vb, NULL); | ||
414 | if (rc < 0) | ||
415 | goto fail; | ||
416 | } | ||
417 | |||
418 | buf->vb.state = VIDEOBUF_PREPARED; | ||
419 | return 0; | ||
420 | fail: | ||
421 | free_buffer(vq, buf); | ||
422 | return rc; | ||
423 | } | ||
424 | |||
425 | static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb) | ||
426 | { | ||
427 | struct zr364xx_buffer *buf = container_of(vb, struct zr364xx_buffer, | ||
428 | vb); | ||
429 | struct zr364xx_camera *cam = vq->priv_data; | ||
430 | |||
431 | _DBG("%s\n", __func__); | ||
432 | |||
433 | buf->vb.state = VIDEOBUF_QUEUED; | ||
434 | list_add_tail(&buf->vb.queue, &cam->vidq.active); | ||
435 | } | ||
436 | |||
437 | static void buffer_release(struct videobuf_queue *vq, | ||
438 | struct videobuf_buffer *vb) | ||
439 | { | ||
440 | struct zr364xx_buffer *buf = container_of(vb, struct zr364xx_buffer, | ||
441 | vb); | ||
442 | |||
443 | _DBG("%s\n", __func__); | ||
444 | free_buffer(vq, buf); | ||
445 | } | ||
446 | |||
447 | static struct videobuf_queue_ops zr364xx_video_qops = { | ||
448 | .buf_setup = buffer_setup, | ||
449 | .buf_prepare = buffer_prepare, | ||
450 | .buf_queue = buffer_queue, | ||
451 | .buf_release = buffer_release, | ||
452 | }; | ||
453 | |||
454 | /********************/ | ||
455 | /* V4L2 integration */ | ||
456 | /********************/ | ||
457 | static int zr364xx_vidioc_streamon(struct file *file, void *priv, | ||
458 | enum v4l2_buf_type type); | ||
459 | |||
460 | static ssize_t zr364xx_read(struct file *file, char __user *buf, size_t count, | ||
461 | loff_t * ppos) | ||
462 | { | ||
463 | struct zr364xx_camera *cam = video_drvdata(file); | ||
464 | int err = 0; | ||
465 | |||
466 | _DBG("%s\n", __func__); | ||
467 | |||
468 | if (!buf) | ||
469 | return -EINVAL; | ||
470 | |||
471 | if (!count) | ||
472 | return -EINVAL; | ||
473 | |||
474 | if (mutex_lock_interruptible(&cam->lock)) | ||
475 | return -ERESTARTSYS; | ||
476 | |||
477 | err = zr364xx_vidioc_streamon(file, file->private_data, | ||
478 | V4L2_BUF_TYPE_VIDEO_CAPTURE); | ||
479 | if (err == 0) { | ||
480 | DBG("%s: reading %d bytes at pos %d.\n", __func__, | ||
481 | (int) count, (int) *ppos); | ||
482 | |||
483 | /* NoMan Sux ! */ | ||
484 | err = videobuf_read_one(&cam->vb_vidq, buf, count, ppos, | ||
485 | file->f_flags & O_NONBLOCK); | ||
486 | } | ||
487 | mutex_unlock(&cam->lock); | ||
488 | return err; | ||
489 | } | ||
490 | |||
491 | /* video buffer vmalloc implementation based partly on VIVI driver which is | ||
492 | * Copyright (c) 2006 by | ||
493 | * Mauro Carvalho Chehab <mchehab--a.t--infradead.org> | ||
494 | * Ted Walther <ted--a.t--enumera.com> | ||
495 | * John Sokol <sokol--a.t--videotechnology.com> | ||
496 | * http://v4l.videotechnology.com/ | ||
497 | * | ||
498 | */ | ||
499 | static void zr364xx_fillbuff(struct zr364xx_camera *cam, | ||
500 | struct zr364xx_buffer *buf, | ||
501 | int jpgsize) | ||
502 | { | ||
503 | int pos = 0; | ||
504 | struct timeval ts; | ||
505 | const char *tmpbuf; | ||
506 | char *vbuf = videobuf_to_vmalloc(&buf->vb); | ||
507 | unsigned long last_frame; | ||
508 | |||
509 | if (!vbuf) | ||
510 | return; | ||
511 | |||
512 | last_frame = cam->last_frame; | ||
513 | if (last_frame != -1) { | ||
514 | tmpbuf = (const char *)cam->buffer.frame[last_frame].lpvbits; | ||
515 | switch (buf->fmt->fourcc) { | ||
516 | case V4L2_PIX_FMT_JPEG: | ||
517 | buf->vb.size = jpgsize; | ||
518 | memcpy(vbuf, tmpbuf, buf->vb.size); | ||
519 | break; | ||
520 | default: | ||
521 | printk(KERN_DEBUG KBUILD_MODNAME ": unknown format?\n"); | ||
522 | } | ||
523 | cam->last_frame = -1; | ||
524 | } else { | ||
525 | printk(KERN_ERR KBUILD_MODNAME ": =======no frame\n"); | ||
526 | return; | ||
527 | } | ||
528 | DBG("%s: Buffer 0x%08lx size= %d\n", __func__, | ||
529 | (unsigned long)vbuf, pos); | ||
530 | /* tell v4l buffer was filled */ | ||
531 | |||
532 | buf->vb.field_count = cam->frame_count * 2; | ||
533 | do_gettimeofday(&ts); | ||
534 | buf->vb.ts = ts; | ||
535 | buf->vb.state = VIDEOBUF_DONE; | ||
536 | } | ||
537 | |||
538 | static int zr364xx_got_frame(struct zr364xx_camera *cam, int jpgsize) | ||
539 | { | ||
540 | struct zr364xx_dmaqueue *dma_q = &cam->vidq; | ||
541 | struct zr364xx_buffer *buf; | ||
542 | unsigned long flags = 0; | ||
543 | int rc = 0; | ||
544 | |||
545 | DBG("wakeup: %p\n", &dma_q); | ||
546 | spin_lock_irqsave(&cam->slock, flags); | ||
547 | |||
548 | if (list_empty(&dma_q->active)) { | ||
549 | DBG("No active queue to serve\n"); | ||
550 | rc = -1; | ||
551 | goto unlock; | ||
552 | } | ||
553 | buf = list_entry(dma_q->active.next, | ||
554 | struct zr364xx_buffer, vb.queue); | ||
555 | |||
556 | if (!waitqueue_active(&buf->vb.done)) { | ||
557 | /* no one active */ | ||
558 | rc = -1; | ||
559 | goto unlock; | ||
560 | } | ||
561 | list_del(&buf->vb.queue); | ||
562 | do_gettimeofday(&buf->vb.ts); | ||
563 | DBG("[%p/%d] wakeup\n", buf, buf->vb.i); | ||
564 | zr364xx_fillbuff(cam, buf, jpgsize); | ||
565 | wake_up(&buf->vb.done); | ||
566 | DBG("wakeup [buf/i] [%p/%d]\n", buf, buf->vb.i); | ||
567 | unlock: | ||
568 | spin_unlock_irqrestore(&cam->slock, flags); | ||
569 | return rc; | ||
570 | } | ||
571 | |||
572 | /* this function moves the usb stream read pipe data | ||
573 | * into the system buffers. | ||
574 | * returns 0 on success, EAGAIN if more data to process (call this | ||
575 | * function again). | ||
576 | */ | ||
577 | static int zr364xx_read_video_callback(struct zr364xx_camera *cam, | ||
578 | struct zr364xx_pipeinfo *pipe_info, | ||
579 | struct urb *purb) | ||
580 | { | ||
581 | unsigned char *pdest; | ||
582 | unsigned char *psrc; | ||
583 | s32 idx = -1; | ||
584 | struct zr364xx_framei *frm; | ||
585 | int i = 0; | ||
586 | unsigned char *ptr = NULL; | ||
587 | |||
588 | _DBG("buffer to user\n"); | ||
589 | idx = cam->cur_frame; | ||
590 | frm = &cam->buffer.frame[idx]; | ||
591 | |||
592 | /* swap bytes if camera needs it */ | ||
593 | if (cam->method == METHOD0) { | ||
594 | u16 *buf = (u16 *)pipe_info->transfer_buffer; | ||
595 | for (i = 0; i < purb->actual_length/2; i++) | ||
596 | swab16s(buf + i); | ||
597 | } | ||
598 | |||
599 | /* search done. now find out if should be acquiring */ | ||
600 | if (!cam->b_acquire) { | ||
601 | /* we found a frame, but this channel is turned off */ | ||
602 | frm->ulState = ZR364XX_READ_IDLE; | ||
603 | return -EINVAL; | ||
604 | } | ||
605 | |||
606 | psrc = (u8 *)pipe_info->transfer_buffer; | ||
607 | ptr = pdest = frm->lpvbits; | ||
608 | |||
609 | if (frm->ulState == ZR364XX_READ_IDLE) { | ||
610 | frm->ulState = ZR364XX_READ_FRAME; | ||
611 | frm->cur_size = 0; | ||
612 | |||
613 | _DBG("jpeg header, "); | ||
614 | memcpy(ptr, header1, sizeof(header1)); | ||
615 | ptr += sizeof(header1); | ||
616 | header3 = 0; | ||
617 | memcpy(ptr, &header3, 1); | ||
618 | ptr++; | ||
619 | memcpy(ptr, psrc, 64); | ||
620 | ptr += 64; | ||
621 | header3 = 1; | ||
622 | memcpy(ptr, &header3, 1); | ||
623 | ptr++; | ||
624 | memcpy(ptr, psrc + 64, 64); | ||
625 | ptr += 64; | ||
626 | memcpy(ptr, header2, sizeof(header2)); | ||
627 | ptr += sizeof(header2); | ||
628 | memcpy(ptr, psrc + 128, | ||
629 | purb->actual_length - 128); | ||
630 | ptr += purb->actual_length - 128; | ||
631 | _DBG("header : %d %d %d %d %d %d %d %d %d\n", | ||
632 | psrc[0], psrc[1], psrc[2], | ||
633 | psrc[3], psrc[4], psrc[5], | ||
634 | psrc[6], psrc[7], psrc[8]); | ||
635 | frm->cur_size = ptr - pdest; | ||
636 | } else { | ||
637 | if (frm->cur_size + purb->actual_length > MAX_FRAME_SIZE) { | ||
638 | dev_info(&cam->udev->dev, | ||
639 | "%s: buffer (%d bytes) too small to hold " | ||
640 | "frame data. Discarding frame data.\n", | ||
641 | __func__, MAX_FRAME_SIZE); | ||
642 | } else { | ||
643 | pdest += frm->cur_size; | ||
644 | memcpy(pdest, psrc, purb->actual_length); | ||
645 | frm->cur_size += purb->actual_length; | ||
646 | } | ||
647 | } | ||
648 | /*_DBG("cur_size %lu urb size %d\n", frm->cur_size, | ||
649 | purb->actual_length);*/ | ||
650 | |||
651 | if (purb->actual_length < pipe_info->transfer_size) { | ||
652 | _DBG("****************Buffer[%d]full*************\n", idx); | ||
653 | cam->last_frame = cam->cur_frame; | ||
654 | cam->cur_frame++; | ||
655 | /* end of system frame ring buffer, start at zero */ | ||
656 | if (cam->cur_frame == cam->buffer.dwFrames) | ||
657 | cam->cur_frame = 0; | ||
658 | |||
659 | /* frame ready */ | ||
660 | /* go back to find the JPEG EOI marker */ | ||
661 | ptr = pdest = frm->lpvbits; | ||
662 | ptr += frm->cur_size - 2; | ||
663 | while (ptr > pdest) { | ||
664 | if (*ptr == 0xFF && *(ptr + 1) == 0xD9 | ||
665 | && *(ptr + 2) == 0xFF) | ||
666 | break; | ||
667 | ptr--; | ||
668 | } | ||
669 | if (ptr == pdest) | ||
670 | DBG("No EOI marker\n"); | ||
671 | |||
672 | /* Sometimes there is junk data in the middle of the picture, | ||
673 | * we want to skip this bogus frames */ | ||
674 | while (ptr > pdest) { | ||
675 | if (*ptr == 0xFF && *(ptr + 1) == 0xFF | ||
676 | && *(ptr + 2) == 0xFF) | ||
677 | break; | ||
678 | ptr--; | ||
679 | } | ||
680 | if (ptr != pdest) { | ||
681 | DBG("Bogus frame ? %d\n", ++(cam->nb)); | ||
682 | } else if (cam->b_acquire) { | ||
683 | /* we skip the 2 first frames which are usually buggy */ | ||
684 | if (cam->skip) | ||
685 | cam->skip--; | ||
686 | else { | ||
687 | _DBG("jpeg(%lu): %d %d %d %d %d %d %d %d\n", | ||
688 | frm->cur_size, | ||
689 | pdest[0], pdest[1], pdest[2], pdest[3], | ||
690 | pdest[4], pdest[5], pdest[6], pdest[7]); | ||
691 | |||
692 | zr364xx_got_frame(cam, frm->cur_size); | ||
693 | } | ||
694 | } | ||
695 | cam->frame_count++; | ||
696 | frm->ulState = ZR364XX_READ_IDLE; | ||
697 | frm->cur_size = 0; | ||
698 | } | ||
699 | /* done successfully */ | ||
700 | return 0; | ||
701 | } | ||
702 | |||
703 | static int zr364xx_vidioc_querycap(struct file *file, void *priv, | ||
704 | struct v4l2_capability *cap) | ||
705 | { | ||
706 | struct zr364xx_camera *cam = video_drvdata(file); | ||
707 | |||
708 | strlcpy(cap->driver, DRIVER_DESC, sizeof(cap->driver)); | ||
709 | strlcpy(cap->card, cam->udev->product, sizeof(cap->card)); | ||
710 | strlcpy(cap->bus_info, dev_name(&cam->udev->dev), | ||
711 | sizeof(cap->bus_info)); | ||
712 | cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | | ||
713 | V4L2_CAP_READWRITE | | ||
714 | V4L2_CAP_STREAMING; | ||
715 | cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; | ||
716 | |||
717 | return 0; | ||
718 | } | ||
719 | |||
720 | static int zr364xx_vidioc_enum_input(struct file *file, void *priv, | ||
721 | struct v4l2_input *i) | ||
722 | { | ||
723 | if (i->index != 0) | ||
724 | return -EINVAL; | ||
725 | strcpy(i->name, DRIVER_DESC " Camera"); | ||
726 | i->type = V4L2_INPUT_TYPE_CAMERA; | ||
727 | return 0; | ||
728 | } | ||
729 | |||
730 | static int zr364xx_vidioc_g_input(struct file *file, void *priv, | ||
731 | unsigned int *i) | ||
732 | { | ||
733 | *i = 0; | ||
734 | return 0; | ||
735 | } | ||
736 | |||
737 | static int zr364xx_vidioc_s_input(struct file *file, void *priv, | ||
738 | unsigned int i) | ||
739 | { | ||
740 | if (i != 0) | ||
741 | return -EINVAL; | ||
742 | return 0; | ||
743 | } | ||
744 | |||
745 | static int zr364xx_s_ctrl(struct v4l2_ctrl *ctrl) | ||
746 | { | ||
747 | struct zr364xx_camera *cam = | ||
748 | container_of(ctrl->handler, struct zr364xx_camera, ctrl_handler); | ||
749 | int temp; | ||
750 | |||
751 | switch (ctrl->id) { | ||
752 | case V4L2_CID_BRIGHTNESS: | ||
753 | /* hardware brightness */ | ||
754 | send_control_msg(cam->udev, 1, 0x2001, 0, NULL, 0); | ||
755 | temp = (0x60 << 8) + 127 - ctrl->val; | ||
756 | send_control_msg(cam->udev, 1, temp, 0, NULL, 0); | ||
757 | break; | ||
758 | default: | ||
759 | return -EINVAL; | ||
760 | } | ||
761 | |||
762 | return 0; | ||
763 | } | ||
764 | |||
765 | static int zr364xx_vidioc_enum_fmt_vid_cap(struct file *file, | ||
766 | void *priv, struct v4l2_fmtdesc *f) | ||
767 | { | ||
768 | if (f->index > 0) | ||
769 | return -EINVAL; | ||
770 | f->flags = V4L2_FMT_FLAG_COMPRESSED; | ||
771 | strcpy(f->description, formats[0].name); | ||
772 | f->pixelformat = formats[0].fourcc; | ||
773 | return 0; | ||
774 | } | ||
775 | |||
776 | static char *decode_fourcc(__u32 pixelformat, char *buf) | ||
777 | { | ||
778 | buf[0] = pixelformat & 0xff; | ||
779 | buf[1] = (pixelformat >> 8) & 0xff; | ||
780 | buf[2] = (pixelformat >> 16) & 0xff; | ||
781 | buf[3] = (pixelformat >> 24) & 0xff; | ||
782 | buf[4] = '\0'; | ||
783 | return buf; | ||
784 | } | ||
785 | |||
786 | static int zr364xx_vidioc_try_fmt_vid_cap(struct file *file, void *priv, | ||
787 | struct v4l2_format *f) | ||
788 | { | ||
789 | struct zr364xx_camera *cam = video_drvdata(file); | ||
790 | char pixelformat_name[5]; | ||
791 | |||
792 | if (cam == NULL) | ||
793 | return -ENODEV; | ||
794 | |||
795 | if (f->fmt.pix.pixelformat != V4L2_PIX_FMT_JPEG) { | ||
796 | DBG("%s: unsupported pixelformat V4L2_PIX_FMT_%s\n", __func__, | ||
797 | decode_fourcc(f->fmt.pix.pixelformat, pixelformat_name)); | ||
798 | return -EINVAL; | ||
799 | } | ||
800 | |||
801 | if (!(f->fmt.pix.width == 160 && f->fmt.pix.height == 120) && | ||
802 | !(f->fmt.pix.width == 640 && f->fmt.pix.height == 480)) { | ||
803 | f->fmt.pix.width = 320; | ||
804 | f->fmt.pix.height = 240; | ||
805 | } | ||
806 | |||
807 | f->fmt.pix.field = V4L2_FIELD_NONE; | ||
808 | f->fmt.pix.bytesperline = f->fmt.pix.width * 2; | ||
809 | f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline; | ||
810 | f->fmt.pix.colorspace = V4L2_COLORSPACE_JPEG; | ||
811 | f->fmt.pix.priv = 0; | ||
812 | DBG("%s: V4L2_PIX_FMT_%s (%d) ok!\n", __func__, | ||
813 | decode_fourcc(f->fmt.pix.pixelformat, pixelformat_name), | ||
814 | f->fmt.pix.field); | ||
815 | return 0; | ||
816 | } | ||
817 | |||
818 | static int zr364xx_vidioc_g_fmt_vid_cap(struct file *file, void *priv, | ||
819 | struct v4l2_format *f) | ||
820 | { | ||
821 | struct zr364xx_camera *cam; | ||
822 | |||
823 | if (file == NULL) | ||
824 | return -ENODEV; | ||
825 | cam = video_drvdata(file); | ||
826 | |||
827 | f->fmt.pix.pixelformat = formats[0].fourcc; | ||
828 | f->fmt.pix.field = V4L2_FIELD_NONE; | ||
829 | f->fmt.pix.width = cam->width; | ||
830 | f->fmt.pix.height = cam->height; | ||
831 | f->fmt.pix.bytesperline = f->fmt.pix.width * 2; | ||
832 | f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline; | ||
833 | f->fmt.pix.colorspace = V4L2_COLORSPACE_JPEG; | ||
834 | f->fmt.pix.priv = 0; | ||
835 | return 0; | ||
836 | } | ||
837 | |||
838 | static int zr364xx_vidioc_s_fmt_vid_cap(struct file *file, void *priv, | ||
839 | struct v4l2_format *f) | ||
840 | { | ||
841 | struct zr364xx_camera *cam = video_drvdata(file); | ||
842 | struct videobuf_queue *q = &cam->vb_vidq; | ||
843 | char pixelformat_name[5]; | ||
844 | int ret = zr364xx_vidioc_try_fmt_vid_cap(file, cam, f); | ||
845 | int i; | ||
846 | |||
847 | if (ret < 0) | ||
848 | return ret; | ||
849 | |||
850 | mutex_lock(&q->vb_lock); | ||
851 | |||
852 | if (videobuf_queue_is_busy(&cam->vb_vidq)) { | ||
853 | DBG("%s queue busy\n", __func__); | ||
854 | ret = -EBUSY; | ||
855 | goto out; | ||
856 | } | ||
857 | |||
858 | if (cam->owner) { | ||
859 | DBG("%s can't change format after started\n", __func__); | ||
860 | ret = -EBUSY; | ||
861 | goto out; | ||
862 | } | ||
863 | |||
864 | cam->width = f->fmt.pix.width; | ||
865 | cam->height = f->fmt.pix.height; | ||
866 | DBG("%s: %dx%d mode selected\n", __func__, | ||
867 | cam->width, cam->height); | ||
868 | f->fmt.pix.bytesperline = f->fmt.pix.width * 2; | ||
869 | f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline; | ||
870 | f->fmt.pix.colorspace = V4L2_COLORSPACE_JPEG; | ||
871 | f->fmt.pix.priv = 0; | ||
872 | cam->vb_vidq.field = f->fmt.pix.field; | ||
873 | |||
874 | if (f->fmt.pix.width == 160 && f->fmt.pix.height == 120) | ||
875 | mode = 1; | ||
876 | else if (f->fmt.pix.width == 640 && f->fmt.pix.height == 480) | ||
877 | mode = 2; | ||
878 | else | ||
879 | mode = 0; | ||
880 | |||
881 | m0d1[0] = mode; | ||
882 | m1[2].value = 0xf000 + mode; | ||
883 | m2[1].value = 0xf000 + mode; | ||
884 | |||
885 | /* special case for METHOD3, the modes are different */ | ||
886 | if (cam->method == METHOD3) { | ||
887 | switch (mode) { | ||
888 | case 1: | ||
889 | m2[1].value = 0xf000 + 4; | ||
890 | break; | ||
891 | case 2: | ||
892 | m2[1].value = 0xf000 + 0; | ||
893 | break; | ||
894 | default: | ||
895 | m2[1].value = 0xf000 + 1; | ||
896 | break; | ||
897 | } | ||
898 | } | ||
899 | |||
900 | header2[437] = cam->height / 256; | ||
901 | header2[438] = cam->height % 256; | ||
902 | header2[439] = cam->width / 256; | ||
903 | header2[440] = cam->width % 256; | ||
904 | |||
905 | for (i = 0; init[cam->method][i].size != -1; i++) { | ||
906 | ret = | ||
907 | send_control_msg(cam->udev, 1, init[cam->method][i].value, | ||
908 | 0, init[cam->method][i].bytes, | ||
909 | init[cam->method][i].size); | ||
910 | if (ret < 0) { | ||
911 | dev_err(&cam->udev->dev, | ||
912 | "error during resolution change sequence: %d\n", i); | ||
913 | goto out; | ||
914 | } | ||
915 | } | ||
916 | |||
917 | /* Added some delay here, since opening/closing the camera quickly, | ||
918 | * like Ekiga does during its startup, can crash the webcam | ||
919 | */ | ||
920 | mdelay(100); | ||
921 | cam->skip = 2; | ||
922 | ret = 0; | ||
923 | |||
924 | out: | ||
925 | mutex_unlock(&q->vb_lock); | ||
926 | |||
927 | DBG("%s: V4L2_PIX_FMT_%s (%d) ok!\n", __func__, | ||
928 | decode_fourcc(f->fmt.pix.pixelformat, pixelformat_name), | ||
929 | f->fmt.pix.field); | ||
930 | return ret; | ||
931 | } | ||
932 | |||
933 | static int zr364xx_vidioc_reqbufs(struct file *file, void *priv, | ||
934 | struct v4l2_requestbuffers *p) | ||
935 | { | ||
936 | struct zr364xx_camera *cam = video_drvdata(file); | ||
937 | |||
938 | if (cam->owner && cam->owner != priv) | ||
939 | return -EBUSY; | ||
940 | return videobuf_reqbufs(&cam->vb_vidq, p); | ||
941 | } | ||
942 | |||
943 | static int zr364xx_vidioc_querybuf(struct file *file, | ||
944 | void *priv, | ||
945 | struct v4l2_buffer *p) | ||
946 | { | ||
947 | int rc; | ||
948 | struct zr364xx_camera *cam = video_drvdata(file); | ||
949 | rc = videobuf_querybuf(&cam->vb_vidq, p); | ||
950 | return rc; | ||
951 | } | ||
952 | |||
953 | static int zr364xx_vidioc_qbuf(struct file *file, | ||
954 | void *priv, | ||
955 | struct v4l2_buffer *p) | ||
956 | { | ||
957 | int rc; | ||
958 | struct zr364xx_camera *cam = video_drvdata(file); | ||
959 | _DBG("%s\n", __func__); | ||
960 | if (cam->owner && cam->owner != priv) | ||
961 | return -EBUSY; | ||
962 | rc = videobuf_qbuf(&cam->vb_vidq, p); | ||
963 | return rc; | ||
964 | } | ||
965 | |||
966 | static int zr364xx_vidioc_dqbuf(struct file *file, | ||
967 | void *priv, | ||
968 | struct v4l2_buffer *p) | ||
969 | { | ||
970 | int rc; | ||
971 | struct zr364xx_camera *cam = video_drvdata(file); | ||
972 | _DBG("%s\n", __func__); | ||
973 | if (cam->owner && cam->owner != priv) | ||
974 | return -EBUSY; | ||
975 | rc = videobuf_dqbuf(&cam->vb_vidq, p, file->f_flags & O_NONBLOCK); | ||
976 | return rc; | ||
977 | } | ||
978 | |||
979 | static void read_pipe_completion(struct urb *purb) | ||
980 | { | ||
981 | struct zr364xx_pipeinfo *pipe_info; | ||
982 | struct zr364xx_camera *cam; | ||
983 | int pipe; | ||
984 | |||
985 | pipe_info = purb->context; | ||
986 | _DBG("%s %p, status %d\n", __func__, purb, purb->status); | ||
987 | if (pipe_info == NULL) { | ||
988 | printk(KERN_ERR KBUILD_MODNAME ": no context!\n"); | ||
989 | return; | ||
990 | } | ||
991 | |||
992 | cam = pipe_info->cam; | ||
993 | if (cam == NULL) { | ||
994 | printk(KERN_ERR KBUILD_MODNAME ": no context!\n"); | ||
995 | return; | ||
996 | } | ||
997 | |||
998 | /* if shutting down, do not resubmit, exit immediately */ | ||
999 | if (purb->status == -ESHUTDOWN) { | ||
1000 | DBG("%s, err shutdown\n", __func__); | ||
1001 | pipe_info->err_count++; | ||
1002 | return; | ||
1003 | } | ||
1004 | |||
1005 | if (pipe_info->state == 0) { | ||
1006 | DBG("exiting USB pipe\n"); | ||
1007 | return; | ||
1008 | } | ||
1009 | |||
1010 | if (purb->actual_length < 0 || | ||
1011 | purb->actual_length > pipe_info->transfer_size) { | ||
1012 | dev_err(&cam->udev->dev, "wrong number of bytes\n"); | ||
1013 | return; | ||
1014 | } | ||
1015 | |||
1016 | if (purb->status == 0) | ||
1017 | zr364xx_read_video_callback(cam, pipe_info, purb); | ||
1018 | else { | ||
1019 | pipe_info->err_count++; | ||
1020 | DBG("%s: failed URB %d\n", __func__, purb->status); | ||
1021 | } | ||
1022 | |||
1023 | pipe = usb_rcvbulkpipe(cam->udev, cam->read_endpoint); | ||
1024 | |||
1025 | /* reuse urb */ | ||
1026 | usb_fill_bulk_urb(pipe_info->stream_urb, cam->udev, | ||
1027 | pipe, | ||
1028 | pipe_info->transfer_buffer, | ||
1029 | pipe_info->transfer_size, | ||
1030 | read_pipe_completion, pipe_info); | ||
1031 | |||
1032 | if (pipe_info->state != 0) { | ||
1033 | purb->status = usb_submit_urb(pipe_info->stream_urb, | ||
1034 | GFP_ATOMIC); | ||
1035 | |||
1036 | if (purb->status) | ||
1037 | dev_err(&cam->udev->dev, | ||
1038 | "error submitting urb (error=%i)\n", | ||
1039 | purb->status); | ||
1040 | } else | ||
1041 | DBG("read pipe complete state 0\n"); | ||
1042 | } | ||
1043 | |||
1044 | static int zr364xx_start_readpipe(struct zr364xx_camera *cam) | ||
1045 | { | ||
1046 | int pipe; | ||
1047 | int retval; | ||
1048 | struct zr364xx_pipeinfo *pipe_info = cam->pipe; | ||
1049 | pipe = usb_rcvbulkpipe(cam->udev, cam->read_endpoint); | ||
1050 | DBG("%s: start pipe IN x%x\n", __func__, cam->read_endpoint); | ||
1051 | |||
1052 | pipe_info->state = 1; | ||
1053 | pipe_info->err_count = 0; | ||
1054 | pipe_info->stream_urb = usb_alloc_urb(0, GFP_KERNEL); | ||
1055 | if (!pipe_info->stream_urb) { | ||
1056 | dev_err(&cam->udev->dev, "ReadStream: Unable to alloc URB\n"); | ||
1057 | return -ENOMEM; | ||
1058 | } | ||
1059 | /* transfer buffer allocated in board_init */ | ||
1060 | usb_fill_bulk_urb(pipe_info->stream_urb, cam->udev, | ||
1061 | pipe, | ||
1062 | pipe_info->transfer_buffer, | ||
1063 | pipe_info->transfer_size, | ||
1064 | read_pipe_completion, pipe_info); | ||
1065 | |||
1066 | DBG("submitting URB %p\n", pipe_info->stream_urb); | ||
1067 | retval = usb_submit_urb(pipe_info->stream_urb, GFP_KERNEL); | ||
1068 | if (retval) { | ||
1069 | printk(KERN_ERR KBUILD_MODNAME ": start read pipe failed\n"); | ||
1070 | return retval; | ||
1071 | } | ||
1072 | |||
1073 | return 0; | ||
1074 | } | ||
1075 | |||
1076 | static void zr364xx_stop_readpipe(struct zr364xx_camera *cam) | ||
1077 | { | ||
1078 | struct zr364xx_pipeinfo *pipe_info; | ||
1079 | |||
1080 | if (cam == NULL) { | ||
1081 | printk(KERN_ERR KBUILD_MODNAME ": invalid device\n"); | ||
1082 | return; | ||
1083 | } | ||
1084 | DBG("stop read pipe\n"); | ||
1085 | pipe_info = cam->pipe; | ||
1086 | if (pipe_info) { | ||
1087 | if (pipe_info->state != 0) | ||
1088 | pipe_info->state = 0; | ||
1089 | |||
1090 | if (pipe_info->stream_urb) { | ||
1091 | /* cancel urb */ | ||
1092 | usb_kill_urb(pipe_info->stream_urb); | ||
1093 | usb_free_urb(pipe_info->stream_urb); | ||
1094 | pipe_info->stream_urb = NULL; | ||
1095 | } | ||
1096 | } | ||
1097 | return; | ||
1098 | } | ||
1099 | |||
1100 | /* starts acquisition process */ | ||
1101 | static int zr364xx_start_acquire(struct zr364xx_camera *cam) | ||
1102 | { | ||
1103 | int j; | ||
1104 | |||
1105 | DBG("start acquire\n"); | ||
1106 | |||
1107 | cam->last_frame = -1; | ||
1108 | cam->cur_frame = 0; | ||
1109 | for (j = 0; j < FRAMES; j++) { | ||
1110 | cam->buffer.frame[j].ulState = ZR364XX_READ_IDLE; | ||
1111 | cam->buffer.frame[j].cur_size = 0; | ||
1112 | } | ||
1113 | cam->b_acquire = 1; | ||
1114 | return 0; | ||
1115 | } | ||
1116 | |||
1117 | static inline int zr364xx_stop_acquire(struct zr364xx_camera *cam) | ||
1118 | { | ||
1119 | cam->b_acquire = 0; | ||
1120 | return 0; | ||
1121 | } | ||
1122 | |||
1123 | static int zr364xx_prepare(struct zr364xx_camera *cam) | ||
1124 | { | ||
1125 | int res; | ||
1126 | int i, j; | ||
1127 | |||
1128 | for (i = 0; init[cam->method][i].size != -1; i++) { | ||
1129 | res = send_control_msg(cam->udev, 1, init[cam->method][i].value, | ||
1130 | 0, init[cam->method][i].bytes, | ||
1131 | init[cam->method][i].size); | ||
1132 | if (res < 0) { | ||
1133 | dev_err(&cam->udev->dev, | ||
1134 | "error during open sequence: %d\n", i); | ||
1135 | return res; | ||
1136 | } | ||
1137 | } | ||
1138 | |||
1139 | cam->skip = 2; | ||
1140 | cam->last_frame = -1; | ||
1141 | cam->cur_frame = 0; | ||
1142 | cam->frame_count = 0; | ||
1143 | for (j = 0; j < FRAMES; j++) { | ||
1144 | cam->buffer.frame[j].ulState = ZR364XX_READ_IDLE; | ||
1145 | cam->buffer.frame[j].cur_size = 0; | ||
1146 | } | ||
1147 | v4l2_ctrl_handler_setup(&cam->ctrl_handler); | ||
1148 | return 0; | ||
1149 | } | ||
1150 | |||
1151 | static int zr364xx_vidioc_streamon(struct file *file, void *priv, | ||
1152 | enum v4l2_buf_type type) | ||
1153 | { | ||
1154 | struct zr364xx_camera *cam = video_drvdata(file); | ||
1155 | int res; | ||
1156 | |||
1157 | DBG("%s\n", __func__); | ||
1158 | |||
1159 | if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
1160 | return -EINVAL; | ||
1161 | |||
1162 | if (cam->owner && cam->owner != priv) | ||
1163 | return -EBUSY; | ||
1164 | |||
1165 | res = zr364xx_prepare(cam); | ||
1166 | if (res) | ||
1167 | return res; | ||
1168 | res = videobuf_streamon(&cam->vb_vidq); | ||
1169 | if (res == 0) { | ||
1170 | zr364xx_start_acquire(cam); | ||
1171 | cam->owner = file->private_data; | ||
1172 | } | ||
1173 | return res; | ||
1174 | } | ||
1175 | |||
1176 | static int zr364xx_vidioc_streamoff(struct file *file, void *priv, | ||
1177 | enum v4l2_buf_type type) | ||
1178 | { | ||
1179 | struct zr364xx_camera *cam = video_drvdata(file); | ||
1180 | |||
1181 | DBG("%s\n", __func__); | ||
1182 | if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
1183 | return -EINVAL; | ||
1184 | if (cam->owner && cam->owner != priv) | ||
1185 | return -EBUSY; | ||
1186 | zr364xx_stop_acquire(cam); | ||
1187 | return videobuf_streamoff(&cam->vb_vidq); | ||
1188 | } | ||
1189 | |||
1190 | |||
1191 | /* open the camera */ | ||
1192 | static int zr364xx_open(struct file *file) | ||
1193 | { | ||
1194 | struct zr364xx_camera *cam = video_drvdata(file); | ||
1195 | int err; | ||
1196 | |||
1197 | DBG("%s\n", __func__); | ||
1198 | |||
1199 | if (mutex_lock_interruptible(&cam->lock)) | ||
1200 | return -ERESTARTSYS; | ||
1201 | |||
1202 | err = v4l2_fh_open(file); | ||
1203 | if (err) | ||
1204 | goto out; | ||
1205 | |||
1206 | /* Added some delay here, since opening/closing the camera quickly, | ||
1207 | * like Ekiga does during its startup, can crash the webcam | ||
1208 | */ | ||
1209 | mdelay(100); | ||
1210 | err = 0; | ||
1211 | |||
1212 | out: | ||
1213 | mutex_unlock(&cam->lock); | ||
1214 | DBG("%s: %d\n", __func__, err); | ||
1215 | return err; | ||
1216 | } | ||
1217 | |||
1218 | static void zr364xx_release(struct v4l2_device *v4l2_dev) | ||
1219 | { | ||
1220 | struct zr364xx_camera *cam = | ||
1221 | container_of(v4l2_dev, struct zr364xx_camera, v4l2_dev); | ||
1222 | unsigned long i; | ||
1223 | |||
1224 | v4l2_device_unregister(&cam->v4l2_dev); | ||
1225 | |||
1226 | videobuf_mmap_free(&cam->vb_vidq); | ||
1227 | |||
1228 | /* release sys buffers */ | ||
1229 | for (i = 0; i < FRAMES; i++) { | ||
1230 | if (cam->buffer.frame[i].lpvbits) { | ||
1231 | DBG("vfree %p\n", cam->buffer.frame[i].lpvbits); | ||
1232 | vfree(cam->buffer.frame[i].lpvbits); | ||
1233 | } | ||
1234 | cam->buffer.frame[i].lpvbits = NULL; | ||
1235 | } | ||
1236 | |||
1237 | v4l2_ctrl_handler_free(&cam->ctrl_handler); | ||
1238 | /* release transfer buffer */ | ||
1239 | kfree(cam->pipe->transfer_buffer); | ||
1240 | kfree(cam); | ||
1241 | } | ||
1242 | |||
1243 | /* release the camera */ | ||
1244 | static int zr364xx_close(struct file *file) | ||
1245 | { | ||
1246 | struct zr364xx_camera *cam; | ||
1247 | struct usb_device *udev; | ||
1248 | int i; | ||
1249 | |||
1250 | DBG("%s\n", __func__); | ||
1251 | cam = video_drvdata(file); | ||
1252 | |||
1253 | mutex_lock(&cam->lock); | ||
1254 | udev = cam->udev; | ||
1255 | |||
1256 | if (file->private_data == cam->owner) { | ||
1257 | /* turn off stream */ | ||
1258 | if (cam->b_acquire) | ||
1259 | zr364xx_stop_acquire(cam); | ||
1260 | videobuf_streamoff(&cam->vb_vidq); | ||
1261 | |||
1262 | for (i = 0; i < 2; i++) { | ||
1263 | send_control_msg(udev, 1, init[cam->method][i].value, | ||
1264 | 0, init[cam->method][i].bytes, | ||
1265 | init[cam->method][i].size); | ||
1266 | } | ||
1267 | cam->owner = NULL; | ||
1268 | } | ||
1269 | |||
1270 | /* Added some delay here, since opening/closing the camera quickly, | ||
1271 | * like Ekiga does during its startup, can crash the webcam | ||
1272 | */ | ||
1273 | mdelay(100); | ||
1274 | mutex_unlock(&cam->lock); | ||
1275 | return v4l2_fh_release(file); | ||
1276 | } | ||
1277 | |||
1278 | |||
1279 | static int zr364xx_mmap(struct file *file, struct vm_area_struct *vma) | ||
1280 | { | ||
1281 | struct zr364xx_camera *cam = video_drvdata(file); | ||
1282 | int ret; | ||
1283 | |||
1284 | if (cam == NULL) { | ||
1285 | DBG("%s: cam == NULL\n", __func__); | ||
1286 | return -ENODEV; | ||
1287 | } | ||
1288 | DBG("mmap called, vma=0x%08lx\n", (unsigned long)vma); | ||
1289 | |||
1290 | ret = videobuf_mmap_mapper(&cam->vb_vidq, vma); | ||
1291 | |||
1292 | DBG("vma start=0x%08lx, size=%ld, ret=%d\n", | ||
1293 | (unsigned long)vma->vm_start, | ||
1294 | (unsigned long)vma->vm_end - (unsigned long)vma->vm_start, ret); | ||
1295 | return ret; | ||
1296 | } | ||
1297 | |||
1298 | static unsigned int zr364xx_poll(struct file *file, | ||
1299 | struct poll_table_struct *wait) | ||
1300 | { | ||
1301 | struct zr364xx_camera *cam = video_drvdata(file); | ||
1302 | struct videobuf_queue *q = &cam->vb_vidq; | ||
1303 | unsigned res = v4l2_ctrl_poll(file, wait); | ||
1304 | |||
1305 | _DBG("%s\n", __func__); | ||
1306 | |||
1307 | return res | videobuf_poll_stream(file, q, wait); | ||
1308 | } | ||
1309 | |||
1310 | static const struct v4l2_ctrl_ops zr364xx_ctrl_ops = { | ||
1311 | .s_ctrl = zr364xx_s_ctrl, | ||
1312 | }; | ||
1313 | |||
1314 | static const struct v4l2_file_operations zr364xx_fops = { | ||
1315 | .owner = THIS_MODULE, | ||
1316 | .open = zr364xx_open, | ||
1317 | .release = zr364xx_close, | ||
1318 | .read = zr364xx_read, | ||
1319 | .mmap = zr364xx_mmap, | ||
1320 | .unlocked_ioctl = video_ioctl2, | ||
1321 | .poll = zr364xx_poll, | ||
1322 | }; | ||
1323 | |||
1324 | static const struct v4l2_ioctl_ops zr364xx_ioctl_ops = { | ||
1325 | .vidioc_querycap = zr364xx_vidioc_querycap, | ||
1326 | .vidioc_enum_fmt_vid_cap = zr364xx_vidioc_enum_fmt_vid_cap, | ||
1327 | .vidioc_try_fmt_vid_cap = zr364xx_vidioc_try_fmt_vid_cap, | ||
1328 | .vidioc_s_fmt_vid_cap = zr364xx_vidioc_s_fmt_vid_cap, | ||
1329 | .vidioc_g_fmt_vid_cap = zr364xx_vidioc_g_fmt_vid_cap, | ||
1330 | .vidioc_enum_input = zr364xx_vidioc_enum_input, | ||
1331 | .vidioc_g_input = zr364xx_vidioc_g_input, | ||
1332 | .vidioc_s_input = zr364xx_vidioc_s_input, | ||
1333 | .vidioc_streamon = zr364xx_vidioc_streamon, | ||
1334 | .vidioc_streamoff = zr364xx_vidioc_streamoff, | ||
1335 | .vidioc_reqbufs = zr364xx_vidioc_reqbufs, | ||
1336 | .vidioc_querybuf = zr364xx_vidioc_querybuf, | ||
1337 | .vidioc_qbuf = zr364xx_vidioc_qbuf, | ||
1338 | .vidioc_dqbuf = zr364xx_vidioc_dqbuf, | ||
1339 | .vidioc_log_status = v4l2_ctrl_log_status, | ||
1340 | .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, | ||
1341 | .vidioc_unsubscribe_event = v4l2_event_unsubscribe, | ||
1342 | }; | ||
1343 | |||
1344 | static struct video_device zr364xx_template = { | ||
1345 | .name = DRIVER_DESC, | ||
1346 | .fops = &zr364xx_fops, | ||
1347 | .ioctl_ops = &zr364xx_ioctl_ops, | ||
1348 | .release = video_device_release_empty, | ||
1349 | }; | ||
1350 | |||
1351 | |||
1352 | |||
1353 | /*******************/ | ||
1354 | /* USB integration */ | ||
1355 | /*******************/ | ||
1356 | static int zr364xx_board_init(struct zr364xx_camera *cam) | ||
1357 | { | ||
1358 | struct zr364xx_pipeinfo *pipe = cam->pipe; | ||
1359 | unsigned long i; | ||
1360 | |||
1361 | DBG("board init: %p\n", cam); | ||
1362 | memset(pipe, 0, sizeof(*pipe)); | ||
1363 | pipe->cam = cam; | ||
1364 | pipe->transfer_size = BUFFER_SIZE; | ||
1365 | |||
1366 | pipe->transfer_buffer = kzalloc(pipe->transfer_size, | ||
1367 | GFP_KERNEL); | ||
1368 | if (pipe->transfer_buffer == NULL) { | ||
1369 | DBG("out of memory!\n"); | ||
1370 | return -ENOMEM; | ||
1371 | } | ||
1372 | |||
1373 | cam->b_acquire = 0; | ||
1374 | cam->frame_count = 0; | ||
1375 | |||
1376 | /*** start create system buffers ***/ | ||
1377 | for (i = 0; i < FRAMES; i++) { | ||
1378 | /* always allocate maximum size for system buffers */ | ||
1379 | cam->buffer.frame[i].lpvbits = vmalloc(MAX_FRAME_SIZE); | ||
1380 | |||
1381 | DBG("valloc %p, idx %lu, pdata %p\n", | ||
1382 | &cam->buffer.frame[i], i, | ||
1383 | cam->buffer.frame[i].lpvbits); | ||
1384 | if (cam->buffer.frame[i].lpvbits == NULL) { | ||
1385 | printk(KERN_INFO KBUILD_MODNAME ": out of memory. " | ||
1386 | "Using less frames\n"); | ||
1387 | break; | ||
1388 | } | ||
1389 | } | ||
1390 | |||
1391 | if (i == 0) { | ||
1392 | printk(KERN_INFO KBUILD_MODNAME ": out of memory. Aborting\n"); | ||
1393 | kfree(cam->pipe->transfer_buffer); | ||
1394 | cam->pipe->transfer_buffer = NULL; | ||
1395 | return -ENOMEM; | ||
1396 | } else | ||
1397 | cam->buffer.dwFrames = i; | ||
1398 | |||
1399 | /* make sure internal states are set */ | ||
1400 | for (i = 0; i < FRAMES; i++) { | ||
1401 | cam->buffer.frame[i].ulState = ZR364XX_READ_IDLE; | ||
1402 | cam->buffer.frame[i].cur_size = 0; | ||
1403 | } | ||
1404 | |||
1405 | cam->cur_frame = 0; | ||
1406 | cam->last_frame = -1; | ||
1407 | /*** end create system buffers ***/ | ||
1408 | |||
1409 | /* start read pipe */ | ||
1410 | zr364xx_start_readpipe(cam); | ||
1411 | DBG(": board initialized\n"); | ||
1412 | return 0; | ||
1413 | } | ||
1414 | |||
1415 | static int zr364xx_probe(struct usb_interface *intf, | ||
1416 | const struct usb_device_id *id) | ||
1417 | { | ||
1418 | struct usb_device *udev = interface_to_usbdev(intf); | ||
1419 | struct zr364xx_camera *cam = NULL; | ||
1420 | struct usb_host_interface *iface_desc; | ||
1421 | struct usb_endpoint_descriptor *endpoint; | ||
1422 | struct v4l2_ctrl_handler *hdl; | ||
1423 | int err; | ||
1424 | int i; | ||
1425 | |||
1426 | DBG("probing...\n"); | ||
1427 | |||
1428 | dev_info(&intf->dev, DRIVER_DESC " compatible webcam plugged\n"); | ||
1429 | dev_info(&intf->dev, "model %04x:%04x detected\n", | ||
1430 | le16_to_cpu(udev->descriptor.idVendor), | ||
1431 | le16_to_cpu(udev->descriptor.idProduct)); | ||
1432 | |||
1433 | cam = kzalloc(sizeof(struct zr364xx_camera), GFP_KERNEL); | ||
1434 | if (cam == NULL) { | ||
1435 | dev_err(&udev->dev, "cam: out of memory !\n"); | ||
1436 | return -ENOMEM; | ||
1437 | } | ||
1438 | |||
1439 | cam->v4l2_dev.release = zr364xx_release; | ||
1440 | err = v4l2_device_register(&intf->dev, &cam->v4l2_dev); | ||
1441 | if (err < 0) { | ||
1442 | dev_err(&udev->dev, "couldn't register v4l2_device\n"); | ||
1443 | kfree(cam); | ||
1444 | return err; | ||
1445 | } | ||
1446 | hdl = &cam->ctrl_handler; | ||
1447 | v4l2_ctrl_handler_init(hdl, 1); | ||
1448 | v4l2_ctrl_new_std(hdl, &zr364xx_ctrl_ops, | ||
1449 | V4L2_CID_BRIGHTNESS, 0, 127, 1, 64); | ||
1450 | if (hdl->error) { | ||
1451 | err = hdl->error; | ||
1452 | dev_err(&udev->dev, "couldn't register control\n"); | ||
1453 | goto fail; | ||
1454 | } | ||
1455 | /* save the init method used by this camera */ | ||
1456 | cam->method = id->driver_info; | ||
1457 | mutex_init(&cam->lock); | ||
1458 | cam->vdev = zr364xx_template; | ||
1459 | cam->vdev.lock = &cam->lock; | ||
1460 | cam->vdev.v4l2_dev = &cam->v4l2_dev; | ||
1461 | cam->vdev.ctrl_handler = &cam->ctrl_handler; | ||
1462 | set_bit(V4L2_FL_USE_FH_PRIO, &cam->vdev.flags); | ||
1463 | video_set_drvdata(&cam->vdev, cam); | ||
1464 | if (debug) | ||
1465 | cam->vdev.debug = V4L2_DEBUG_IOCTL | V4L2_DEBUG_IOCTL_ARG; | ||
1466 | |||
1467 | cam->udev = udev; | ||
1468 | |||
1469 | switch (mode) { | ||
1470 | case 1: | ||
1471 | dev_info(&udev->dev, "160x120 mode selected\n"); | ||
1472 | cam->width = 160; | ||
1473 | cam->height = 120; | ||
1474 | break; | ||
1475 | case 2: | ||
1476 | dev_info(&udev->dev, "640x480 mode selected\n"); | ||
1477 | cam->width = 640; | ||
1478 | cam->height = 480; | ||
1479 | break; | ||
1480 | default: | ||
1481 | dev_info(&udev->dev, "320x240 mode selected\n"); | ||
1482 | cam->width = 320; | ||
1483 | cam->height = 240; | ||
1484 | break; | ||
1485 | } | ||
1486 | |||
1487 | m0d1[0] = mode; | ||
1488 | m1[2].value = 0xf000 + mode; | ||
1489 | m2[1].value = 0xf000 + mode; | ||
1490 | |||
1491 | /* special case for METHOD3, the modes are different */ | ||
1492 | if (cam->method == METHOD3) { | ||
1493 | switch (mode) { | ||
1494 | case 1: | ||
1495 | m2[1].value = 0xf000 + 4; | ||
1496 | break; | ||
1497 | case 2: | ||
1498 | m2[1].value = 0xf000 + 0; | ||
1499 | break; | ||
1500 | default: | ||
1501 | m2[1].value = 0xf000 + 1; | ||
1502 | break; | ||
1503 | } | ||
1504 | } | ||
1505 | |||
1506 | header2[437] = cam->height / 256; | ||
1507 | header2[438] = cam->height % 256; | ||
1508 | header2[439] = cam->width / 256; | ||
1509 | header2[440] = cam->width % 256; | ||
1510 | |||
1511 | cam->nb = 0; | ||
1512 | |||
1513 | DBG("dev: %p, udev %p interface %p\n", cam, cam->udev, intf); | ||
1514 | |||
1515 | /* set up the endpoint information */ | ||
1516 | iface_desc = intf->cur_altsetting; | ||
1517 | DBG("num endpoints %d\n", iface_desc->desc.bNumEndpoints); | ||
1518 | for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { | ||
1519 | endpoint = &iface_desc->endpoint[i].desc; | ||
1520 | if (!cam->read_endpoint && usb_endpoint_is_bulk_in(endpoint)) { | ||
1521 | /* we found the bulk in endpoint */ | ||
1522 | cam->read_endpoint = endpoint->bEndpointAddress; | ||
1523 | } | ||
1524 | } | ||
1525 | |||
1526 | if (!cam->read_endpoint) { | ||
1527 | err = -ENOMEM; | ||
1528 | dev_err(&intf->dev, "Could not find bulk-in endpoint\n"); | ||
1529 | goto fail; | ||
1530 | } | ||
1531 | |||
1532 | /* v4l */ | ||
1533 | INIT_LIST_HEAD(&cam->vidq.active); | ||
1534 | cam->vidq.cam = cam; | ||
1535 | |||
1536 | usb_set_intfdata(intf, cam); | ||
1537 | |||
1538 | /* load zr364xx board specific */ | ||
1539 | err = zr364xx_board_init(cam); | ||
1540 | if (!err) | ||
1541 | err = v4l2_ctrl_handler_setup(hdl); | ||
1542 | if (err) | ||
1543 | goto fail; | ||
1544 | |||
1545 | spin_lock_init(&cam->slock); | ||
1546 | |||
1547 | cam->fmt = formats; | ||
1548 | |||
1549 | videobuf_queue_vmalloc_init(&cam->vb_vidq, &zr364xx_video_qops, | ||
1550 | NULL, &cam->slock, | ||
1551 | V4L2_BUF_TYPE_VIDEO_CAPTURE, | ||
1552 | V4L2_FIELD_NONE, | ||
1553 | sizeof(struct zr364xx_buffer), cam, &cam->lock); | ||
1554 | |||
1555 | err = video_register_device(&cam->vdev, VFL_TYPE_GRABBER, -1); | ||
1556 | if (err) { | ||
1557 | dev_err(&udev->dev, "video_register_device failed\n"); | ||
1558 | goto fail; | ||
1559 | } | ||
1560 | |||
1561 | dev_info(&udev->dev, DRIVER_DESC " controlling device %s\n", | ||
1562 | video_device_node_name(&cam->vdev)); | ||
1563 | return 0; | ||
1564 | |||
1565 | fail: | ||
1566 | v4l2_ctrl_handler_free(hdl); | ||
1567 | v4l2_device_unregister(&cam->v4l2_dev); | ||
1568 | kfree(cam); | ||
1569 | return err; | ||
1570 | } | ||
1571 | |||
1572 | |||
1573 | static void zr364xx_disconnect(struct usb_interface *intf) | ||
1574 | { | ||
1575 | struct zr364xx_camera *cam = usb_get_intfdata(intf); | ||
1576 | |||
1577 | mutex_lock(&cam->lock); | ||
1578 | usb_set_intfdata(intf, NULL); | ||
1579 | dev_info(&intf->dev, DRIVER_DESC " webcam unplugged\n"); | ||
1580 | video_unregister_device(&cam->vdev); | ||
1581 | v4l2_device_disconnect(&cam->v4l2_dev); | ||
1582 | |||
1583 | /* stops the read pipe if it is running */ | ||
1584 | if (cam->b_acquire) | ||
1585 | zr364xx_stop_acquire(cam); | ||
1586 | |||
1587 | zr364xx_stop_readpipe(cam); | ||
1588 | mutex_unlock(&cam->lock); | ||
1589 | v4l2_device_put(&cam->v4l2_dev); | ||
1590 | } | ||
1591 | |||
1592 | |||
1593 | #ifdef CONFIG_PM | ||
1594 | static int zr364xx_suspend(struct usb_interface *intf, pm_message_t message) | ||
1595 | { | ||
1596 | struct zr364xx_camera *cam = usb_get_intfdata(intf); | ||
1597 | |||
1598 | cam->was_streaming = cam->b_acquire; | ||
1599 | if (!cam->was_streaming) | ||
1600 | return 0; | ||
1601 | zr364xx_stop_acquire(cam); | ||
1602 | zr364xx_stop_readpipe(cam); | ||
1603 | return 0; | ||
1604 | } | ||
1605 | |||
1606 | static int zr364xx_resume(struct usb_interface *intf) | ||
1607 | { | ||
1608 | struct zr364xx_camera *cam = usb_get_intfdata(intf); | ||
1609 | int res; | ||
1610 | |||
1611 | if (!cam->was_streaming) | ||
1612 | return 0; | ||
1613 | |||
1614 | zr364xx_start_readpipe(cam); | ||
1615 | res = zr364xx_prepare(cam); | ||
1616 | if (!res) | ||
1617 | zr364xx_start_acquire(cam); | ||
1618 | return res; | ||
1619 | } | ||
1620 | #endif | ||
1621 | |||
1622 | /**********************/ | ||
1623 | /* Module integration */ | ||
1624 | /**********************/ | ||
1625 | |||
1626 | static struct usb_driver zr364xx_driver = { | ||
1627 | .name = "zr364xx", | ||
1628 | .probe = zr364xx_probe, | ||
1629 | .disconnect = zr364xx_disconnect, | ||
1630 | #ifdef CONFIG_PM | ||
1631 | .suspend = zr364xx_suspend, | ||
1632 | .resume = zr364xx_resume, | ||
1633 | .reset_resume = zr364xx_resume, | ||
1634 | #endif | ||
1635 | .id_table = device_table | ||
1636 | }; | ||
1637 | |||
1638 | module_usb_driver(zr364xx_driver); | ||
1639 | |||
1640 | MODULE_AUTHOR(DRIVER_AUTHOR); | ||
1641 | MODULE_DESCRIPTION(DRIVER_DESC); | ||
1642 | MODULE_LICENSE("GPL"); | ||
1643 | MODULE_VERSION(DRIVER_VERSION); | ||