blob: 91f7e9538f6e3173b65a5b2387bdefdabeaf4989 [file] [log] [blame]
Dean Anderson38f993a2008-06-26 23:15:51 -03001/*
2 * s2255drv.c - a driver for the Sensoray 2255 USB video capture device
3 *
Dean Anderson4de39f52010-03-03 19:39:19 -03004 * Copyright (C) 2007-2010 by Sensoray Company Inc.
Dean Anderson38f993a2008-06-26 23:15:51 -03005 * 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 *
20 * -full or half size Grey scale: all 4 channels at once
21 *
22 * -half size, color mode YUYV or YUV422P: all 4 channels at once
23 *
24 * -full size, color mode YUYV or YUV422P 1/2 frame rate: all 4 channels
25 * at once.
26 * (TODO: Incorporate videodev2 frame rate(FR) enumeration,
27 * which is currently experimental.)
28 *
29 * This program is free software; you can redistribute it and/or modify
30 * it under the terms of the GNU General Public License as published by
31 * the Free Software Foundation; either version 2 of the License, or
32 * (at your option) any later version.
33 *
34 * This program is distributed in the hope that it will be useful,
35 * but WITHOUT ANY WARRANTY; without even the implied warranty of
36 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
37 * GNU General Public License for more details.
38 *
39 * You should have received a copy of the GNU General Public License
40 * along with this program; if not, write to the Free Software
41 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
42 */
43
44#include <linux/module.h>
45#include <linux/firmware.h>
46#include <linux/kernel.h>
47#include <linux/mutex.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090048#include <linux/slab.h>
Dean Anderson38f993a2008-06-26 23:15:51 -030049#include <linux/videodev2.h>
50#include <linux/version.h>
Hans Verkuilfeb75f02008-07-27 06:30:21 -030051#include <linux/mm.h>
Alexey Dobriyan405f5572009-07-11 22:08:37 +040052#include <linux/smp_lock.h>
Dean Anderson38f993a2008-06-26 23:15:51 -030053#include <media/videobuf-vmalloc.h>
54#include <media/v4l2-common.h>
Hans Verkuil35ea11f2008-07-20 08:12:02 -030055#include <media/v4l2-ioctl.h>
Dean Anderson38f993a2008-06-26 23:15:51 -030056#include <linux/vmalloc.h>
57#include <linux/usb.h>
58
59#define FIRMWARE_FILE_NAME "f2255usb.bin"
60
61
62
Dean Anderson22b88d42008-08-29 15:33:19 -030063/* default JPEG quality */
64#define S2255_DEF_JPEG_QUAL 50
Dean Anderson38f993a2008-06-26 23:15:51 -030065/* vendor request in */
66#define S2255_VR_IN 0
67/* vendor request out */
68#define S2255_VR_OUT 1
69/* firmware query */
70#define S2255_VR_FW 0x30
71/* USB endpoint number for configuring the device */
72#define S2255_CONFIG_EP 2
73/* maximum time for DSP to start responding after last FW word loaded(ms) */
Dean Anderson14d96262008-08-25 13:58:55 -030074#define S2255_DSP_BOOTTIME 800
Dean Anderson38f993a2008-06-26 23:15:51 -030075/* maximum time to wait for firmware to load (ms) */
Dean Anderson3f8d6f72008-06-30 21:28:34 -030076#define S2255_LOAD_TIMEOUT (5000 + S2255_DSP_BOOTTIME)
Dean Anderson38f993a2008-06-26 23:15:51 -030077#define S2255_DEF_BUFS 16
Dean Anderson14d96262008-08-25 13:58:55 -030078#define S2255_SETMODE_TIMEOUT 500
Dean Anderson4de39f52010-03-03 19:39:19 -030079#define S2255_VIDSTATUS_TIMEOUT 350
Dean Anderson38f993a2008-06-26 23:15:51 -030080#define MAX_CHANNELS 4
Dean Anderson3fa00602010-03-04 20:47:33 -030081#define S2255_MARKER_FRAME cpu_to_le32(0x2255DA4AL)
82#define S2255_MARKER_RESPONSE cpu_to_le32(0x2255ACACL)
83#define S2255_RESPONSE_SETMODE cpu_to_le32(0x01)
84#define S2255_RESPONSE_FW cpu_to_le32(0x10)
85#define S2255_RESPONSE_STATUS cpu_to_le32(0x20)
Dean Anderson14d96262008-08-25 13:58:55 -030086#define S2255_USB_XFER_SIZE (16 * 1024)
Dean Anderson38f993a2008-06-26 23:15:51 -030087#define MAX_CHANNELS 4
Dean Anderson38f993a2008-06-26 23:15:51 -030088#define SYS_FRAMES 4
89/* maximum size is PAL full size plus room for the marker header(s) */
Dean Anderson14d96262008-08-25 13:58:55 -030090#define SYS_FRAMES_MAXSIZE (720*288*2*2 + 4096)
91#define DEF_USB_BLOCK S2255_USB_XFER_SIZE
Dean Anderson38f993a2008-06-26 23:15:51 -030092#define LINE_SZ_4CIFS_NTSC 640
93#define LINE_SZ_2CIFS_NTSC 640
94#define LINE_SZ_1CIFS_NTSC 320
95#define LINE_SZ_4CIFS_PAL 704
96#define LINE_SZ_2CIFS_PAL 704
97#define LINE_SZ_1CIFS_PAL 352
98#define NUM_LINES_4CIFS_NTSC 240
99#define NUM_LINES_2CIFS_NTSC 240
100#define NUM_LINES_1CIFS_NTSC 240
101#define NUM_LINES_4CIFS_PAL 288
102#define NUM_LINES_2CIFS_PAL 288
103#define NUM_LINES_1CIFS_PAL 288
104#define LINE_SZ_DEF 640
105#define NUM_LINES_DEF 240
106
107
108/* predefined settings */
109#define FORMAT_NTSC 1
110#define FORMAT_PAL 2
111
112#define SCALE_4CIFS 1 /* 640x480(NTSC) or 704x576(PAL) */
113#define SCALE_2CIFS 2 /* 640x240(NTSC) or 704x288(PAL) */
114#define SCALE_1CIFS 3 /* 320x240(NTSC) or 352x288(PAL) */
Dean Anderson7d853532009-05-15 14:32:04 -0300115/* SCALE_4CIFSI is the 2 fields interpolated into one */
116#define SCALE_4CIFSI 4 /* 640x480(NTSC) or 704x576(PAL) high quality */
Dean Anderson38f993a2008-06-26 23:15:51 -0300117
118#define COLOR_YUVPL 1 /* YUV planar */
119#define COLOR_YUVPK 2 /* YUV packed */
120#define COLOR_Y8 4 /* monochrome */
Dean Anderson14d96262008-08-25 13:58:55 -0300121#define COLOR_JPG 5 /* JPEG */
Dean Anderson38f993a2008-06-26 23:15:51 -0300122
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300123#define MASK_COLOR 0x000000ff
124#define MASK_JPG_QUALITY 0x0000ff00
125#define MASK_INPUT_TYPE 0x000f0000
Dean Anderson38f993a2008-06-26 23:15:51 -0300126/* frame decimation. Not implemented by V4L yet(experimental in V4L) */
127#define FDEC_1 1 /* capture every frame. default */
128#define FDEC_2 2 /* capture every 2nd frame */
129#define FDEC_3 3 /* capture every 3rd frame */
130#define FDEC_5 5 /* capture every 5th frame */
131
132/*-------------------------------------------------------
133 * Default mode parameters.
134 *-------------------------------------------------------*/
135#define DEF_SCALE SCALE_4CIFS
136#define DEF_COLOR COLOR_YUVPL
137#define DEF_FDEC FDEC_1
138#define DEF_BRIGHT 0
139#define DEF_CONTRAST 0x5c
140#define DEF_SATURATION 0x80
141#define DEF_HUE 0
142
143/* usb config commands */
Dean Anderson3fa00602010-03-04 20:47:33 -0300144#define IN_DATA_TOKEN cpu_to_le32(0x2255c0de)
145#define CMD_2255 cpu_to_le32(0xc2255000)
146#define CMD_SET_MODE cpu_to_le32((CMD_2255 | 0x10))
147#define CMD_START cpu_to_le32((CMD_2255 | 0x20))
148#define CMD_STOP cpu_to_le32((CMD_2255 | 0x30))
149#define CMD_STATUS cpu_to_le32((CMD_2255 | 0x40))
Dean Anderson38f993a2008-06-26 23:15:51 -0300150
151struct s2255_mode {
152 u32 format; /* input video format (NTSC, PAL) */
153 u32 scale; /* output video scale */
154 u32 color; /* output video color format */
155 u32 fdec; /* frame decimation */
156 u32 bright; /* brightness */
157 u32 contrast; /* contrast */
158 u32 saturation; /* saturation */
159 u32 hue; /* hue (NTSC only)*/
160 u32 single; /* capture 1 frame at a time (!=0), continuously (==0)*/
161 u32 usb_block; /* block size. should be 4096 of DEF_USB_BLOCK */
162 u32 restart; /* if DSP requires restart */
163};
164
Dean Anderson14d96262008-08-25 13:58:55 -0300165
166#define S2255_READ_IDLE 0
167#define S2255_READ_FRAME 1
168
Dean Anderson38f993a2008-06-26 23:15:51 -0300169/* frame structure */
Dean Anderson38f993a2008-06-26 23:15:51 -0300170struct s2255_framei {
171 unsigned long size;
Dean Anderson14d96262008-08-25 13:58:55 -0300172 unsigned long ulState; /* ulState:S2255_READ_IDLE, S2255_READ_FRAME*/
Dean Anderson38f993a2008-06-26 23:15:51 -0300173 void *lpvbits; /* image data */
174 unsigned long cur_size; /* current data copied to it */
175};
176
177/* image buffer structure */
178struct s2255_bufferi {
179 unsigned long dwFrames; /* number of frames in buffer */
180 struct s2255_framei frame[SYS_FRAMES]; /* array of FRAME structures */
181};
182
183#define DEF_MODEI_NTSC_CONT {FORMAT_NTSC, DEF_SCALE, DEF_COLOR, \
184 DEF_FDEC, DEF_BRIGHT, DEF_CONTRAST, DEF_SATURATION, \
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300185 DEF_HUE, 0, DEF_USB_BLOCK, 0}
Dean Anderson38f993a2008-06-26 23:15:51 -0300186
187struct s2255_dmaqueue {
188 struct list_head active;
Dean Anderson38f993a2008-06-26 23:15:51 -0300189 struct s2255_dev *dev;
190 int channel;
191};
192
193/* for firmware loading, fw_state */
194#define S2255_FW_NOTLOADED 0
195#define S2255_FW_LOADED_DSPWAIT 1
196#define S2255_FW_SUCCESS 2
197#define S2255_FW_FAILED 3
Dean Andersonf78d92c2008-07-22 14:43:27 -0300198#define S2255_FW_DISCONNECTING 4
Harvey Harrisondeaf53e2008-11-15 01:10:14 -0300199#define S2255_FW_MARKER cpu_to_le32(0x22552f2f)
Dean Anderson14d96262008-08-25 13:58:55 -0300200/* 2255 read states */
201#define S2255_READ_IDLE 0
202#define S2255_READ_FRAME 1
Dean Anderson38f993a2008-06-26 23:15:51 -0300203struct s2255_fw {
204 int fw_loaded;
205 int fw_size;
206 struct urb *fw_urb;
207 atomic_t fw_state;
208 void *pfw_data;
209 wait_queue_head_t wait_fw;
Dean Anderson38f993a2008-06-26 23:15:51 -0300210 const struct firmware *fw;
211};
212
213struct s2255_pipeinfo {
214 u32 max_transfer_size;
215 u32 cur_transfer_size;
216 u8 *transfer_buffer;
Dean Anderson38f993a2008-06-26 23:15:51 -0300217 u32 state;
Dean Anderson38f993a2008-06-26 23:15:51 -0300218 void *stream_urb;
219 void *dev; /* back pointer to s2255_dev struct*/
220 u32 err_count;
Dean Anderson38f993a2008-06-26 23:15:51 -0300221 u32 idx;
Dean Anderson38f993a2008-06-26 23:15:51 -0300222};
223
224struct s2255_fmt; /*forward declaration */
225
226struct s2255_dev {
227 int frames;
Dean Anderson38f993a2008-06-26 23:15:51 -0300228 struct mutex lock;
229 struct mutex open_lock;
230 int resources[MAX_CHANNELS];
231 struct usb_device *udev;
232 struct usb_interface *interface;
233 u8 read_endpoint;
234
235 struct s2255_dmaqueue vidq[MAX_CHANNELS];
236 struct video_device *vdev[MAX_CHANNELS];
Dean Anderson38f993a2008-06-26 23:15:51 -0300237 struct timer_list timer;
238 struct s2255_fw *fw_data;
Dean Andersonab85c6a2010-04-08 23:39:12 -0300239 struct s2255_pipeinfo pipe;
240 struct s2255_bufferi buffer[MAX_CHANNELS];
Dean Anderson38f993a2008-06-26 23:15:51 -0300241 struct s2255_mode mode[MAX_CHANNELS];
Dean Anderson22b88d42008-08-29 15:33:19 -0300242 /* jpeg compression */
243 struct v4l2_jpegcompression jc[MAX_CHANNELS];
Dean Anderson7d853532009-05-15 14:32:04 -0300244 /* capture parameters (for high quality mode full size) */
245 struct v4l2_captureparm cap_parm[MAX_CHANNELS];
Dean Anderson38f993a2008-06-26 23:15:51 -0300246 const struct s2255_fmt *cur_fmt[MAX_CHANNELS];
247 int cur_frame[MAX_CHANNELS];
248 int last_frame[MAX_CHANNELS];
249 u32 cc; /* current channel */
250 int b_acquire[MAX_CHANNELS];
Dean Anderson14d96262008-08-25 13:58:55 -0300251 /* allocated image size */
Dean Anderson38f993a2008-06-26 23:15:51 -0300252 unsigned long req_image_size[MAX_CHANNELS];
Dean Anderson14d96262008-08-25 13:58:55 -0300253 /* received packet size */
254 unsigned long pkt_size[MAX_CHANNELS];
Dean Anderson38f993a2008-06-26 23:15:51 -0300255 int bad_payload[MAX_CHANNELS];
256 unsigned long frame_count[MAX_CHANNELS];
257 int frame_ready;
Dean Anderson14d96262008-08-25 13:58:55 -0300258 /* if JPEG image */
259 int jpg_size[MAX_CHANNELS];
260 /* if channel configured to default state */
261 int chn_configured[MAX_CHANNELS];
262 wait_queue_head_t wait_setmode[MAX_CHANNELS];
263 int setmode_ready[MAX_CHANNELS];
Dean Anderson4de39f52010-03-03 19:39:19 -0300264 /* video status items */
265 int vidstatus[MAX_CHANNELS];
266 wait_queue_head_t wait_vidstatus[MAX_CHANNELS];
267 int vidstatus_ready[MAX_CHANNELS];
Dean Anderson14d96262008-08-25 13:58:55 -0300268 int chn_ready;
Dean Anderson38f993a2008-06-26 23:15:51 -0300269 spinlock_t slock;
Dean Anderson4de39f52010-03-03 19:39:19 -0300270 /* dsp firmware version (f2255usb.bin) */
271 int dsp_fw_ver;
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300272 u16 pid; /* product id */
273 struct kref kref;
Dean Anderson38f993a2008-06-26 23:15:51 -0300274};
275#define to_s2255_dev(d) container_of(d, struct s2255_dev, kref)
276
277struct s2255_fmt {
278 char *name;
279 u32 fourcc;
280 int depth;
281};
282
283/* buffer for one video frame */
284struct s2255_buffer {
285 /* common v4l buffer stuff -- must be first */
286 struct videobuf_buffer vb;
287 const struct s2255_fmt *fmt;
288};
289
290struct s2255_fh {
291 struct s2255_dev *dev;
Dean Anderson38f993a2008-06-26 23:15:51 -0300292 const struct s2255_fmt *fmt;
293 unsigned int width;
294 unsigned int height;
295 struct videobuf_queue vb_vidq;
296 enum v4l2_buf_type type;
297 int channel;
298 /* mode below is the desired mode.
299 mode in s2255_dev is the current mode that was last set */
300 struct s2255_mode mode;
Dean Andersonf78d92c2008-07-22 14:43:27 -0300301 int resources[MAX_CHANNELS];
Dean Anderson38f993a2008-06-26 23:15:51 -0300302};
303
Dean Andersonabce21f2009-04-23 16:04:41 -0300304/* current cypress EEPROM firmware version */
305#define S2255_CUR_USB_FWVER ((3 << 8) | 6)
Dean Anderson4de39f52010-03-03 19:39:19 -0300306/* current DSP FW version */
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300307#define S2255_CUR_DSP_FWVER 8
Dean Anderson4de39f52010-03-03 19:39:19 -0300308/* Need DSP version 5+ for video status feature */
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300309#define S2255_MIN_DSP_STATUS 5
310#define S2255_MIN_DSP_COLORFILTER 8
Dean Anderson38f993a2008-06-26 23:15:51 -0300311#define S2255_MAJOR_VERSION 1
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300312#define S2255_MINOR_VERSION 18
Dean Anderson38f993a2008-06-26 23:15:51 -0300313#define S2255_RELEASE 0
314#define S2255_VERSION KERNEL_VERSION(S2255_MAJOR_VERSION, \
315 S2255_MINOR_VERSION, \
316 S2255_RELEASE)
317
Dean Anderson38f993a2008-06-26 23:15:51 -0300318#define S2255_NORMS (V4L2_STD_PAL | V4L2_STD_NTSC)
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300319
320/* private V4L2 controls */
321
322/*
323 * The following chart displays how COLORFILTER should be set
324 * =========================================================
325 * = fourcc = COLORFILTER =
326 * = ===============================
327 * = = 0 = 1 =
328 * =========================================================
329 * = V4L2_PIX_FMT_GREY(Y8) = monochrome from = monochrome=
330 * = = s-video or = composite =
331 * = = B/W camera = input =
332 * =========================================================
333 * = other = color, svideo = color, =
334 * = = = composite =
335 * =========================================================
336 *
337 * Notes:
338 * channels 0-3 on 2255 are composite
339 * channels 0-1 on 2257 are composite, 2-3 are s-video
340 * If COLORFILTER is 0 with a composite color camera connected,
341 * the output will appear monochrome but hatching
342 * will occur.
343 * COLORFILTER is different from "color killer" and "color effects"
344 * for reasons above.
345 */
346#define S2255_V4L2_YC_ON 1
347#define S2255_V4L2_YC_OFF 0
348#define V4L2_CID_PRIVATE_COLORFILTER (V4L2_CID_PRIVATE_BASE + 0)
349
Dean Anderson38f993a2008-06-26 23:15:51 -0300350/* frame prefix size (sent once every frame) */
351#define PREFIX_SIZE 512
352
353/* Channels on box are in reverse order */
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300354static unsigned long G_chnmap[MAX_CHANNELS] = {3, 2, 1, 0};
Dean Anderson38f993a2008-06-26 23:15:51 -0300355
Dean Anderson38f993a2008-06-26 23:15:51 -0300356static int debug;
357static int *s2255_debug = &debug;
358
359static int s2255_start_readpipe(struct s2255_dev *dev);
360static void s2255_stop_readpipe(struct s2255_dev *dev);
361static int s2255_start_acquire(struct s2255_dev *dev, unsigned long chn);
362static int s2255_stop_acquire(struct s2255_dev *dev, unsigned long chn);
363static void s2255_fillbuff(struct s2255_dev *dev, struct s2255_buffer *buf,
Dean Anderson14d96262008-08-25 13:58:55 -0300364 int chn, int jpgsize);
Dean Anderson38f993a2008-06-26 23:15:51 -0300365static int s2255_set_mode(struct s2255_dev *dev, unsigned long chn,
366 struct s2255_mode *mode);
367static int s2255_board_shutdown(struct s2255_dev *dev);
Dean Anderson14d96262008-08-25 13:58:55 -0300368static void s2255_fwload_start(struct s2255_dev *dev, int reset);
369static void s2255_destroy(struct kref *kref);
370static long s2255_vendor_req(struct s2255_dev *dev, unsigned char req,
371 u16 index, u16 value, void *buf,
372 s32 buf_len, int bOut);
Dean Anderson38f993a2008-06-26 23:15:51 -0300373
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -0300374/* dev_err macro with driver name */
375#define S2255_DRIVER_NAME "s2255"
376#define s2255_dev_err(dev, fmt, arg...) \
377 dev_err(dev, S2255_DRIVER_NAME " - " fmt, ##arg)
378
Dean Anderson38f993a2008-06-26 23:15:51 -0300379#define dprintk(level, fmt, arg...) \
380 do { \
381 if (*s2255_debug >= (level)) { \
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -0300382 printk(KERN_DEBUG S2255_DRIVER_NAME \
383 ": " fmt, ##arg); \
Dean Anderson38f993a2008-06-26 23:15:51 -0300384 } \
385 } while (0)
386
Dean Anderson38f993a2008-06-26 23:15:51 -0300387static struct usb_driver s2255_driver;
388
Dean Anderson38f993a2008-06-26 23:15:51 -0300389/* Declare static vars that will be used as parameters */
390static unsigned int vid_limit = 16; /* Video memory limit, in Mb */
391
392/* start video number */
393static int video_nr = -1; /* /dev/videoN, -1 for autodetect */
394
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300395module_param(debug, int, 0644);
Dean Anderson38f993a2008-06-26 23:15:51 -0300396MODULE_PARM_DESC(debug, "Debug level(0-100) default 0");
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300397module_param(vid_limit, int, 0644);
Dean Anderson38f993a2008-06-26 23:15:51 -0300398MODULE_PARM_DESC(vid_limit, "video memory limit(Mb)");
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300399module_param(video_nr, int, 0644);
Dean Anderson38f993a2008-06-26 23:15:51 -0300400MODULE_PARM_DESC(video_nr, "start video minor(-1 default autodetect)");
401
402/* USB device table */
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300403#define USB_SENSORAY_VID 0x1943
Dean Anderson38f993a2008-06-26 23:15:51 -0300404static struct usb_device_id s2255_table[] = {
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300405 {USB_DEVICE(USB_SENSORAY_VID, 0x2255)},
406 {USB_DEVICE(USB_SENSORAY_VID, 0x2257)}, /*same family as 2255*/
Dean Anderson38f993a2008-06-26 23:15:51 -0300407 { } /* Terminating entry */
408};
409MODULE_DEVICE_TABLE(usb, s2255_table);
410
Dean Anderson38f993a2008-06-26 23:15:51 -0300411#define BUFFER_TIMEOUT msecs_to_jiffies(400)
412
Dean Anderson38f993a2008-06-26 23:15:51 -0300413/* image formats. */
414static const struct s2255_fmt formats[] = {
415 {
416 .name = "4:2:2, planar, YUV422P",
417 .fourcc = V4L2_PIX_FMT_YUV422P,
418 .depth = 16
419
420 }, {
421 .name = "4:2:2, packed, YUYV",
422 .fourcc = V4L2_PIX_FMT_YUYV,
423 .depth = 16
424
425 }, {
426 .name = "4:2:2, packed, UYVY",
427 .fourcc = V4L2_PIX_FMT_UYVY,
428 .depth = 16
429 }, {
Dean Anderson14d96262008-08-25 13:58:55 -0300430 .name = "JPG",
431 .fourcc = V4L2_PIX_FMT_JPEG,
432 .depth = 24
433 }, {
Dean Anderson38f993a2008-06-26 23:15:51 -0300434 .name = "8bpp GREY",
435 .fourcc = V4L2_PIX_FMT_GREY,
436 .depth = 8
437 }
438};
439
440static 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
446static 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
452static 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
458static 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
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300465/*
466 * TODO: fixme: move YUV reordering to hardware
467 * converts 2255 planar format to yuyv or uyvy
468 */
Dean Anderson38f993a2008-06-26 23:15:51 -0300469static 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
Hans Verkuild45b9b82008-09-04 03:33:43 -0300491static void s2255_reset_dsppower(struct s2255_dev *dev)
Dean Anderson14d96262008-08-25 13:58:55 -0300492{
493 s2255_vendor_req(dev, 0x40, 0x0b0b, 0x0b0b, NULL, 0, 1);
494 msleep(10);
495 s2255_vendor_req(dev, 0x50, 0x0000, 0x0000, NULL, 0, 1);
496 return;
497}
Dean Anderson38f993a2008-06-26 23:15:51 -0300498
499/* kickstarts the firmware loading. from probe
500 */
501static void s2255_timer(unsigned long user_data)
502{
503 struct s2255_fw *data = (struct s2255_fw *)user_data;
504 dprintk(100, "s2255 timer\n");
505 if (usb_submit_urb(data->fw_urb, GFP_ATOMIC) < 0) {
506 printk(KERN_ERR "s2255: can't submit urb\n");
Dean Andersonf78d92c2008-07-22 14:43:27 -0300507 atomic_set(&data->fw_state, S2255_FW_FAILED);
508 /* wake up anything waiting for the firmware */
509 wake_up(&data->wait_fw);
Dean Anderson38f993a2008-06-26 23:15:51 -0300510 return;
511 }
512}
513
Dean Anderson38f993a2008-06-26 23:15:51 -0300514
515/* this loads the firmware asynchronously.
516 Originally this was done synchroously in probe.
517 But it is better to load it asynchronously here than block
518 inside the probe function. Blocking inside probe affects boot time.
519 FW loading is triggered by the timer in the probe function
520*/
521static void s2255_fwchunk_complete(struct urb *urb)
522{
523 struct s2255_fw *data = urb->context;
524 struct usb_device *udev = urb->dev;
525 int len;
526 dprintk(100, "udev %p urb %p", udev, urb);
Dean Anderson38f993a2008-06-26 23:15:51 -0300527 if (urb->status) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -0300528 dev_err(&udev->dev, "URB failed with status %d\n", urb->status);
Dean Andersonf78d92c2008-07-22 14:43:27 -0300529 atomic_set(&data->fw_state, S2255_FW_FAILED);
530 /* wake up anything waiting for the firmware */
531 wake_up(&data->wait_fw);
Dean Anderson38f993a2008-06-26 23:15:51 -0300532 return;
533 }
534 if (data->fw_urb == NULL) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -0300535 s2255_dev_err(&udev->dev, "disconnected\n");
Dean Andersonf78d92c2008-07-22 14:43:27 -0300536 atomic_set(&data->fw_state, S2255_FW_FAILED);
537 /* wake up anything waiting for the firmware */
538 wake_up(&data->wait_fw);
Dean Anderson38f993a2008-06-26 23:15:51 -0300539 return;
540 }
541#define CHUNK_SIZE 512
542 /* all USB transfers must be done with continuous kernel memory.
543 can't allocate more than 128k in current linux kernel, so
544 upload the firmware in chunks
545 */
546 if (data->fw_loaded < data->fw_size) {
547 len = (data->fw_loaded + CHUNK_SIZE) > data->fw_size ?
548 data->fw_size % CHUNK_SIZE : CHUNK_SIZE;
549
550 if (len < CHUNK_SIZE)
551 memset(data->pfw_data, 0, CHUNK_SIZE);
552
553 dprintk(100, "completed len %d, loaded %d \n", len,
554 data->fw_loaded);
555
556 memcpy(data->pfw_data,
557 (char *) data->fw->data + data->fw_loaded, len);
558
559 usb_fill_bulk_urb(data->fw_urb, udev, usb_sndbulkpipe(udev, 2),
560 data->pfw_data, CHUNK_SIZE,
561 s2255_fwchunk_complete, data);
562 if (usb_submit_urb(data->fw_urb, GFP_ATOMIC) < 0) {
563 dev_err(&udev->dev, "failed submit URB\n");
564 atomic_set(&data->fw_state, S2255_FW_FAILED);
565 /* wake up anything waiting for the firmware */
566 wake_up(&data->wait_fw);
567 return;
568 }
569 data->fw_loaded += len;
570 } else {
Dean Anderson38f993a2008-06-26 23:15:51 -0300571 atomic_set(&data->fw_state, S2255_FW_LOADED_DSPWAIT);
Dean Anderson38f993a2008-06-26 23:15:51 -0300572 }
573 dprintk(100, "2255 complete done\n");
574 return;
575
576}
577
Dean Anderson14d96262008-08-25 13:58:55 -0300578static int s2255_got_frame(struct s2255_dev *dev, int chn, int jpgsize)
Dean Anderson38f993a2008-06-26 23:15:51 -0300579{
580 struct s2255_dmaqueue *dma_q = &dev->vidq[chn];
581 struct s2255_buffer *buf;
582 unsigned long flags = 0;
583 int rc = 0;
584 dprintk(2, "wakeup: %p channel: %d\n", &dma_q, chn);
585 spin_lock_irqsave(&dev->slock, flags);
586
587 if (list_empty(&dma_q->active)) {
588 dprintk(1, "No active queue to serve\n");
589 rc = -1;
590 goto unlock;
591 }
592 buf = list_entry(dma_q->active.next,
593 struct s2255_buffer, vb.queue);
594
Dean Anderson38f993a2008-06-26 23:15:51 -0300595 list_del(&buf->vb.queue);
596 do_gettimeofday(&buf->vb.ts);
597 dprintk(100, "[%p/%d] wakeup\n", buf, buf->vb.i);
Dean Anderson14d96262008-08-25 13:58:55 -0300598 s2255_fillbuff(dev, buf, dma_q->channel, jpgsize);
Dean Anderson38f993a2008-06-26 23:15:51 -0300599 wake_up(&buf->vb.done);
600 dprintk(2, "wakeup [buf/i] [%p/%d]\n", buf, buf->vb.i);
601unlock:
602 spin_unlock_irqrestore(&dev->slock, flags);
603 return 0;
604}
605
Dean Anderson38f993a2008-06-26 23:15:51 -0300606static const struct s2255_fmt *format_by_fourcc(int fourcc)
607{
608 unsigned int i;
609
610 for (i = 0; i < ARRAY_SIZE(formats); i++) {
611 if (-1 == formats[i].fourcc)
612 continue;
613 if (formats[i].fourcc == fourcc)
614 return formats + i;
615 }
616 return NULL;
617}
618
Dean Anderson38f993a2008-06-26 23:15:51 -0300619/* video buffer vmalloc implementation based partly on VIVI driver which is
620 * Copyright (c) 2006 by
621 * Mauro Carvalho Chehab <mchehab--a.t--infradead.org>
622 * Ted Walther <ted--a.t--enumera.com>
623 * John Sokol <sokol--a.t--videotechnology.com>
624 * http://v4l.videotechnology.com/
625 *
626 */
627static void s2255_fillbuff(struct s2255_dev *dev, struct s2255_buffer *buf,
Dean Anderson14d96262008-08-25 13:58:55 -0300628 int chn, int jpgsize)
Dean Anderson38f993a2008-06-26 23:15:51 -0300629{
630 int pos = 0;
631 struct timeval ts;
632 const char *tmpbuf;
633 char *vbuf = videobuf_to_vmalloc(&buf->vb);
634 unsigned long last_frame;
635 struct s2255_framei *frm;
636
637 if (!vbuf)
638 return;
639
640 last_frame = dev->last_frame[chn];
641 if (last_frame != -1) {
642 frm = &dev->buffer[chn].frame[last_frame];
643 tmpbuf =
644 (const char *)dev->buffer[chn].frame[last_frame].lpvbits;
645 switch (buf->fmt->fourcc) {
646 case V4L2_PIX_FMT_YUYV:
647 case V4L2_PIX_FMT_UYVY:
648 planar422p_to_yuv_packed((const unsigned char *)tmpbuf,
649 vbuf, buf->vb.width,
650 buf->vb.height,
651 buf->fmt->fourcc);
652 break;
653 case V4L2_PIX_FMT_GREY:
654 memcpy(vbuf, tmpbuf, buf->vb.width * buf->vb.height);
655 break;
Dean Anderson14d96262008-08-25 13:58:55 -0300656 case V4L2_PIX_FMT_JPEG:
657 buf->vb.size = jpgsize;
658 memcpy(vbuf, tmpbuf, buf->vb.size);
659 break;
Dean Anderson38f993a2008-06-26 23:15:51 -0300660 case V4L2_PIX_FMT_YUV422P:
661 memcpy(vbuf, tmpbuf,
662 buf->vb.width * buf->vb.height * 2);
663 break;
664 default:
665 printk(KERN_DEBUG "s2255: unknown format?\n");
666 }
667 dev->last_frame[chn] = -1;
Dean Anderson38f993a2008-06-26 23:15:51 -0300668 } else {
669 printk(KERN_ERR "s2255: =======no frame\n");
670 return;
671
672 }
673 dprintk(2, "s2255fill at : Buffer 0x%08lx size= %d\n",
674 (unsigned long)vbuf, pos);
675 /* tell v4l buffer was filled */
676
Dean Andersona1c45302008-09-09 12:29:56 -0300677 buf->vb.field_count = dev->frame_count[chn] * 2;
Dean Anderson38f993a2008-06-26 23:15:51 -0300678 do_gettimeofday(&ts);
679 buf->vb.ts = ts;
680 buf->vb.state = VIDEOBUF_DONE;
681}
682
683
684/* ------------------------------------------------------------------
685 Videobuf operations
686 ------------------------------------------------------------------*/
687
688static int buffer_setup(struct videobuf_queue *vq, unsigned int *count,
689 unsigned int *size)
690{
691 struct s2255_fh *fh = vq->priv_data;
692
693 *size = fh->width * fh->height * (fh->fmt->depth >> 3);
694
695 if (0 == *count)
696 *count = S2255_DEF_BUFS;
697
Andreas Bombedab7e312010-03-21 16:02:45 -0300698 if (*size * *count > vid_limit * 1024 * 1024)
699 *count = (vid_limit * 1024 * 1024) / *size;
Dean Anderson38f993a2008-06-26 23:15:51 -0300700
701 return 0;
702}
703
704static void free_buffer(struct videobuf_queue *vq, struct s2255_buffer *buf)
705{
706 dprintk(4, "%s\n", __func__);
707
Dean Anderson38f993a2008-06-26 23:15:51 -0300708 videobuf_vmalloc_free(&buf->vb);
709 buf->vb.state = VIDEOBUF_NEEDS_INIT;
710}
711
712static int buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb,
713 enum v4l2_field field)
714{
715 struct s2255_fh *fh = vq->priv_data;
716 struct s2255_buffer *buf = container_of(vb, struct s2255_buffer, vb);
717 int rc;
718 dprintk(4, "%s, field=%d\n", __func__, field);
719 if (fh->fmt == NULL)
720 return -EINVAL;
721
722 if ((fh->width < norm_minw(fh->dev->vdev[fh->channel])) ||
723 (fh->width > norm_maxw(fh->dev->vdev[fh->channel])) ||
724 (fh->height < norm_minh(fh->dev->vdev[fh->channel])) ||
725 (fh->height > norm_maxh(fh->dev->vdev[fh->channel]))) {
726 dprintk(4, "invalid buffer prepare\n");
727 return -EINVAL;
728 }
729
730 buf->vb.size = fh->width * fh->height * (fh->fmt->depth >> 3);
731
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 = fh->fmt;
738 buf->vb.width = fh->width;
739 buf->vb.height = fh->height;
740 buf->vb.field = field;
741
742
743 if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
744 rc = videobuf_iolock(vq, &buf->vb, NULL);
745 if (rc < 0)
746 goto fail;
747 }
748
749 buf->vb.state = VIDEOBUF_PREPARED;
750 return 0;
751fail:
752 free_buffer(vq, buf);
753 return rc;
754}
755
756static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
757{
758 struct s2255_buffer *buf = container_of(vb, struct s2255_buffer, vb);
759 struct s2255_fh *fh = vq->priv_data;
760 struct s2255_dev *dev = fh->dev;
761 struct s2255_dmaqueue *vidq = &dev->vidq[fh->channel];
762
763 dprintk(1, "%s\n", __func__);
764
765 buf->vb.state = VIDEOBUF_QUEUED;
766 list_add_tail(&buf->vb.queue, &vidq->active);
767}
768
769static void buffer_release(struct videobuf_queue *vq,
770 struct videobuf_buffer *vb)
771{
772 struct s2255_buffer *buf = container_of(vb, struct s2255_buffer, vb);
773 struct s2255_fh *fh = vq->priv_data;
774 dprintk(4, "%s %d\n", __func__, fh->channel);
775 free_buffer(vq, buf);
776}
777
778static struct videobuf_queue_ops s2255_video_qops = {
779 .buf_setup = buffer_setup,
780 .buf_prepare = buffer_prepare,
781 .buf_queue = buffer_queue,
782 .buf_release = buffer_release,
783};
784
785
786static int res_get(struct s2255_dev *dev, struct s2255_fh *fh)
787{
788 /* is it free? */
789 mutex_lock(&dev->lock);
790 if (dev->resources[fh->channel]) {
791 /* no, someone else uses it */
792 mutex_unlock(&dev->lock);
793 return 0;
794 }
795 /* it's free, grab it */
796 dev->resources[fh->channel] = 1;
Dean Andersonf78d92c2008-07-22 14:43:27 -0300797 fh->resources[fh->channel] = 1;
798 dprintk(1, "s2255: res: get\n");
Dean Anderson38f993a2008-06-26 23:15:51 -0300799 mutex_unlock(&dev->lock);
800 return 1;
801}
802
803static int res_locked(struct s2255_dev *dev, struct s2255_fh *fh)
804{
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300805 return dev->resources[fh->channel];
Dean Anderson38f993a2008-06-26 23:15:51 -0300806}
807
Dean Andersonf78d92c2008-07-22 14:43:27 -0300808static int res_check(struct s2255_fh *fh)
809{
810 return fh->resources[fh->channel];
811}
812
813
Dean Anderson38f993a2008-06-26 23:15:51 -0300814static void res_free(struct s2255_dev *dev, struct s2255_fh *fh)
815{
Dean Andersonf78d92c2008-07-22 14:43:27 -0300816 mutex_lock(&dev->lock);
Dean Anderson38f993a2008-06-26 23:15:51 -0300817 dev->resources[fh->channel] = 0;
Dean Andersonf78d92c2008-07-22 14:43:27 -0300818 fh->resources[fh->channel] = 0;
819 mutex_unlock(&dev->lock);
Dean Anderson38f993a2008-06-26 23:15:51 -0300820 dprintk(1, "res: put\n");
821}
822
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300823static int vidioc_querymenu(struct file *file, void *priv,
824 struct v4l2_querymenu *qmenu)
825{
826 static const char *colorfilter[] = {
827 "Off",
828 "On",
829 NULL
830 };
831 if (qmenu->id == V4L2_CID_PRIVATE_COLORFILTER) {
832 int i;
833 const char **menu_items = colorfilter;
834 for (i = 0; i < qmenu->index && menu_items[i]; i++)
835 ; /* do nothing (from v4l2-common.c) */
836 if (menu_items[i] == NULL || menu_items[i][0] == '\0')
837 return -EINVAL;
838 strlcpy(qmenu->name, menu_items[qmenu->index],
839 sizeof(qmenu->name));
840 return 0;
841 }
842 return v4l2_ctrl_query_menu(qmenu, NULL, NULL);
843}
844
Dean Anderson38f993a2008-06-26 23:15:51 -0300845static int vidioc_querycap(struct file *file, void *priv,
846 struct v4l2_capability *cap)
847{
848 struct s2255_fh *fh = file->private_data;
849 struct s2255_dev *dev = fh->dev;
850 strlcpy(cap->driver, "s2255", sizeof(cap->driver));
851 strlcpy(cap->card, "s2255", sizeof(cap->card));
Thierry MERLEe22ed882009-01-20 18:19:25 -0300852 usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info));
Dean Anderson38f993a2008-06-26 23:15:51 -0300853 cap->version = S2255_VERSION;
854 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
855 return 0;
856}
857
858static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
859 struct v4l2_fmtdesc *f)
860{
861 int index = 0;
862 if (f)
863 index = f->index;
864
865 if (index >= ARRAY_SIZE(formats))
866 return -EINVAL;
867
868 dprintk(4, "name %s\n", formats[index].name);
869 strlcpy(f->description, formats[index].name, sizeof(f->description));
870 f->pixelformat = formats[index].fourcc;
871 return 0;
872}
873
874static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
875 struct v4l2_format *f)
876{
877 struct s2255_fh *fh = priv;
878
879 f->fmt.pix.width = fh->width;
880 f->fmt.pix.height = fh->height;
881 f->fmt.pix.field = fh->vb_vidq.field;
882 f->fmt.pix.pixelformat = fh->fmt->fourcc;
883 f->fmt.pix.bytesperline = f->fmt.pix.width * (fh->fmt->depth >> 3);
884 f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300885 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -0300886}
887
888static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
889 struct v4l2_format *f)
890{
891 const struct s2255_fmt *fmt;
892 enum v4l2_field field;
893 int b_any_field = 0;
894 struct s2255_fh *fh = priv;
895 struct s2255_dev *dev = fh->dev;
896 int is_ntsc;
897
898 is_ntsc =
899 (dev->vdev[fh->channel]->current_norm & V4L2_STD_NTSC) ? 1 : 0;
900
901 fmt = format_by_fourcc(f->fmt.pix.pixelformat);
902
903 if (fmt == NULL)
904 return -EINVAL;
905
906 field = f->fmt.pix.field;
907 if (field == V4L2_FIELD_ANY)
908 b_any_field = 1;
909
910 dprintk(4, "try format %d \n", is_ntsc);
911 /* supports 3 sizes. see s2255drv.h */
912 dprintk(50, "width test %d, height %d\n",
913 f->fmt.pix.width, f->fmt.pix.height);
914 if (is_ntsc) {
915 /* NTSC */
916 if (f->fmt.pix.height >= NUM_LINES_1CIFS_NTSC * 2) {
917 f->fmt.pix.height = NUM_LINES_1CIFS_NTSC * 2;
918 if (b_any_field) {
919 field = V4L2_FIELD_SEQ_TB;
920 } else if (!((field == V4L2_FIELD_INTERLACED) ||
921 (field == V4L2_FIELD_SEQ_TB) ||
922 (field == V4L2_FIELD_INTERLACED_TB))) {
923 dprintk(1, "unsupported field setting\n");
924 return -EINVAL;
925 }
926 } else {
927 f->fmt.pix.height = NUM_LINES_1CIFS_NTSC;
928 if (b_any_field) {
929 field = V4L2_FIELD_TOP;
930 } else if (!((field == V4L2_FIELD_TOP) ||
931 (field == V4L2_FIELD_BOTTOM))) {
932 dprintk(1, "unsupported field setting\n");
933 return -EINVAL;
934 }
935
936 }
937 if (f->fmt.pix.width >= LINE_SZ_4CIFS_NTSC)
938 f->fmt.pix.width = LINE_SZ_4CIFS_NTSC;
939 else if (f->fmt.pix.width >= LINE_SZ_2CIFS_NTSC)
940 f->fmt.pix.width = LINE_SZ_2CIFS_NTSC;
941 else if (f->fmt.pix.width >= LINE_SZ_1CIFS_NTSC)
942 f->fmt.pix.width = LINE_SZ_1CIFS_NTSC;
943 else
944 f->fmt.pix.width = LINE_SZ_1CIFS_NTSC;
945 } else {
946 /* PAL */
947 if (f->fmt.pix.height >= NUM_LINES_1CIFS_PAL * 2) {
948 f->fmt.pix.height = NUM_LINES_1CIFS_PAL * 2;
949 if (b_any_field) {
950 field = V4L2_FIELD_SEQ_TB;
951 } else if (!((field == V4L2_FIELD_INTERLACED) ||
952 (field == V4L2_FIELD_SEQ_TB) ||
953 (field == V4L2_FIELD_INTERLACED_TB))) {
954 dprintk(1, "unsupported field setting\n");
955 return -EINVAL;
956 }
957 } else {
958 f->fmt.pix.height = NUM_LINES_1CIFS_PAL;
959 if (b_any_field) {
960 field = V4L2_FIELD_TOP;
961 } else if (!((field == V4L2_FIELD_TOP) ||
962 (field == V4L2_FIELD_BOTTOM))) {
963 dprintk(1, "unsupported field setting\n");
964 return -EINVAL;
965 }
966 }
967 if (f->fmt.pix.width >= LINE_SZ_4CIFS_PAL) {
968 dprintk(50, "pal 704\n");
969 f->fmt.pix.width = LINE_SZ_4CIFS_PAL;
970 field = V4L2_FIELD_SEQ_TB;
971 } else if (f->fmt.pix.width >= LINE_SZ_2CIFS_PAL) {
972 dprintk(50, "pal 352A\n");
973 f->fmt.pix.width = LINE_SZ_2CIFS_PAL;
974 field = V4L2_FIELD_TOP;
975 } else if (f->fmt.pix.width >= LINE_SZ_1CIFS_PAL) {
976 dprintk(50, "pal 352B\n");
977 f->fmt.pix.width = LINE_SZ_1CIFS_PAL;
978 field = V4L2_FIELD_TOP;
979 } else {
980 dprintk(50, "pal 352C\n");
981 f->fmt.pix.width = LINE_SZ_1CIFS_PAL;
982 field = V4L2_FIELD_TOP;
983 }
984 }
985
986 dprintk(50, "width %d height %d field %d \n", f->fmt.pix.width,
987 f->fmt.pix.height, f->fmt.pix.field);
988 f->fmt.pix.field = field;
989 f->fmt.pix.bytesperline = (f->fmt.pix.width * fmt->depth) >> 3;
990 f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
991 return 0;
992}
993
994static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
995 struct v4l2_format *f)
996{
997 struct s2255_fh *fh = priv;
998 const struct s2255_fmt *fmt;
999 struct videobuf_queue *q = &fh->vb_vidq;
1000 int ret;
1001 int norm;
1002
1003 ret = vidioc_try_fmt_vid_cap(file, fh, f);
1004
1005 if (ret < 0)
Dean Anderson3f8d6f72008-06-30 21:28:34 -03001006 return ret;
Dean Anderson38f993a2008-06-26 23:15:51 -03001007
1008 fmt = format_by_fourcc(f->fmt.pix.pixelformat);
1009
1010 if (fmt == NULL)
1011 return -EINVAL;
1012
1013 mutex_lock(&q->vb_lock);
1014
1015 if (videobuf_queue_is_busy(&fh->vb_vidq)) {
1016 dprintk(1, "queue busy\n");
1017 ret = -EBUSY;
1018 goto out_s_fmt;
1019 }
1020
1021 if (res_locked(fh->dev, fh)) {
1022 dprintk(1, "can't change format after started\n");
1023 ret = -EBUSY;
1024 goto out_s_fmt;
1025 }
1026
1027 fh->fmt = fmt;
1028 fh->width = f->fmt.pix.width;
1029 fh->height = f->fmt.pix.height;
1030 fh->vb_vidq.field = f->fmt.pix.field;
1031 fh->type = f->type;
1032 norm = norm_minw(fh->dev->vdev[fh->channel]);
1033 if (fh->width > norm_minw(fh->dev->vdev[fh->channel])) {
Dean Anderson7d853532009-05-15 14:32:04 -03001034 if (fh->height > norm_minh(fh->dev->vdev[fh->channel])) {
1035 if (fh->dev->cap_parm[fh->channel].capturemode &
1036 V4L2_MODE_HIGHQUALITY) {
1037 fh->mode.scale = SCALE_4CIFSI;
1038 dprintk(2, "scale 4CIFSI\n");
1039 } else {
1040 fh->mode.scale = SCALE_4CIFS;
1041 dprintk(2, "scale 4CIFS\n");
1042 }
1043 } else
Dean Anderson38f993a2008-06-26 23:15:51 -03001044 fh->mode.scale = SCALE_2CIFS;
1045
1046 } else {
1047 fh->mode.scale = SCALE_1CIFS;
1048 }
1049
1050 /* color mode */
1051 switch (fh->fmt->fourcc) {
1052 case V4L2_PIX_FMT_GREY:
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001053 fh->mode.color &= ~MASK_COLOR;
1054 fh->mode.color |= COLOR_Y8;
Dean Anderson38f993a2008-06-26 23:15:51 -03001055 break;
Dean Anderson14d96262008-08-25 13:58:55 -03001056 case V4L2_PIX_FMT_JPEG:
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001057 fh->mode.color &= ~MASK_COLOR;
1058 fh->mode.color |= COLOR_JPG;
1059 fh->mode.color |= (fh->dev->jc[fh->channel].quality << 8);
Dean Anderson14d96262008-08-25 13:58:55 -03001060 break;
Dean Anderson38f993a2008-06-26 23:15:51 -03001061 case V4L2_PIX_FMT_YUV422P:
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001062 fh->mode.color &= ~MASK_COLOR;
1063 fh->mode.color |= COLOR_YUVPL;
Dean Anderson38f993a2008-06-26 23:15:51 -03001064 break;
1065 case V4L2_PIX_FMT_YUYV:
1066 case V4L2_PIX_FMT_UYVY:
1067 default:
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001068 fh->mode.color &= ~MASK_COLOR;
1069 fh->mode.color |= COLOR_YUVPK;
Dean Anderson38f993a2008-06-26 23:15:51 -03001070 break;
1071 }
1072 ret = 0;
1073out_s_fmt:
1074 mutex_unlock(&q->vb_lock);
1075 return ret;
1076}
1077
1078static int vidioc_reqbufs(struct file *file, void *priv,
1079 struct v4l2_requestbuffers *p)
1080{
1081 int rc;
1082 struct s2255_fh *fh = priv;
1083 rc = videobuf_reqbufs(&fh->vb_vidq, p);
1084 return rc;
1085}
1086
1087static int vidioc_querybuf(struct file *file, void *priv, struct v4l2_buffer *p)
1088{
1089 int rc;
1090 struct s2255_fh *fh = priv;
1091 rc = videobuf_querybuf(&fh->vb_vidq, p);
1092 return rc;
1093}
1094
1095static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *p)
1096{
1097 int rc;
1098 struct s2255_fh *fh = priv;
1099 rc = videobuf_qbuf(&fh->vb_vidq, p);
1100 return rc;
1101}
1102
1103static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
1104{
1105 int rc;
1106 struct s2255_fh *fh = priv;
1107 rc = videobuf_dqbuf(&fh->vb_vidq, p, file->f_flags & O_NONBLOCK);
1108 return rc;
1109}
1110
1111#ifdef CONFIG_VIDEO_V4L1_COMPAT
1112static int vidioc_cgmbuf(struct file *file, void *priv, struct video_mbuf *mbuf)
1113{
1114 struct s2255_fh *fh = priv;
1115
1116 return videobuf_cgmbuf(&fh->vb_vidq, mbuf, 8);
1117}
1118#endif
1119
1120/* write to the configuration pipe, synchronously */
1121static int s2255_write_config(struct usb_device *udev, unsigned char *pbuf,
1122 int size)
1123{
1124 int pipe;
1125 int done;
1126 long retval = -1;
1127 if (udev) {
1128 pipe = usb_sndbulkpipe(udev, S2255_CONFIG_EP);
1129 retval = usb_bulk_msg(udev, pipe, pbuf, size, &done, 500);
1130 }
1131 return retval;
1132}
1133
1134static u32 get_transfer_size(struct s2255_mode *mode)
1135{
1136 int linesPerFrame = LINE_SZ_DEF;
1137 int pixelsPerLine = NUM_LINES_DEF;
1138 u32 outImageSize;
1139 u32 usbInSize;
1140 unsigned int mask_mult;
1141
1142 if (mode == NULL)
1143 return 0;
1144
1145 if (mode->format == FORMAT_NTSC) {
1146 switch (mode->scale) {
1147 case SCALE_4CIFS:
Dean Anderson7d853532009-05-15 14:32:04 -03001148 case SCALE_4CIFSI:
Dean Anderson38f993a2008-06-26 23:15:51 -03001149 linesPerFrame = NUM_LINES_4CIFS_NTSC * 2;
1150 pixelsPerLine = LINE_SZ_4CIFS_NTSC;
1151 break;
1152 case SCALE_2CIFS:
1153 linesPerFrame = NUM_LINES_2CIFS_NTSC;
1154 pixelsPerLine = LINE_SZ_2CIFS_NTSC;
1155 break;
1156 case SCALE_1CIFS:
1157 linesPerFrame = NUM_LINES_1CIFS_NTSC;
1158 pixelsPerLine = LINE_SZ_1CIFS_NTSC;
1159 break;
1160 default:
1161 break;
1162 }
1163 } else if (mode->format == FORMAT_PAL) {
1164 switch (mode->scale) {
1165 case SCALE_4CIFS:
Dean Anderson7d853532009-05-15 14:32:04 -03001166 case SCALE_4CIFSI:
Dean Anderson38f993a2008-06-26 23:15:51 -03001167 linesPerFrame = NUM_LINES_4CIFS_PAL * 2;
1168 pixelsPerLine = LINE_SZ_4CIFS_PAL;
1169 break;
1170 case SCALE_2CIFS:
1171 linesPerFrame = NUM_LINES_2CIFS_PAL;
1172 pixelsPerLine = LINE_SZ_2CIFS_PAL;
1173 break;
1174 case SCALE_1CIFS:
1175 linesPerFrame = NUM_LINES_1CIFS_PAL;
1176 pixelsPerLine = LINE_SZ_1CIFS_PAL;
1177 break;
1178 default:
1179 break;
1180 }
1181 }
1182 outImageSize = linesPerFrame * pixelsPerLine;
Dean Anderson14d96262008-08-25 13:58:55 -03001183 if ((mode->color & MASK_COLOR) != COLOR_Y8) {
Dean Anderson38f993a2008-06-26 23:15:51 -03001184 /* 2 bytes/pixel if not monochrome */
1185 outImageSize *= 2;
1186 }
1187
1188 /* total bytes to send including prefix and 4K padding;
1189 must be a multiple of USB_READ_SIZE */
1190 usbInSize = outImageSize + PREFIX_SIZE; /* always send prefix */
1191 mask_mult = 0xffffffffUL - DEF_USB_BLOCK + 1;
1192 /* if size not a multiple of USB_READ_SIZE */
1193 if (usbInSize & ~mask_mult)
1194 usbInSize = (usbInSize & mask_mult) + (DEF_USB_BLOCK);
1195 return usbInSize;
1196}
1197
1198static void dump_verify_mode(struct s2255_dev *sdev, struct s2255_mode *mode)
1199{
1200 struct device *dev = &sdev->udev->dev;
1201 dev_info(dev, "------------------------------------------------\n");
1202 dev_info(dev, "verify mode\n");
1203 dev_info(dev, "format: %d\n", mode->format);
1204 dev_info(dev, "scale: %d\n", mode->scale);
1205 dev_info(dev, "fdec: %d\n", mode->fdec);
1206 dev_info(dev, "color: %d\n", mode->color);
1207 dev_info(dev, "bright: 0x%x\n", mode->bright);
1208 dev_info(dev, "restart: 0x%x\n", mode->restart);
1209 dev_info(dev, "usb_block: 0x%x\n", mode->usb_block);
1210 dev_info(dev, "single: 0x%x\n", mode->single);
1211 dev_info(dev, "------------------------------------------------\n");
1212}
1213
1214/*
1215 * set mode is the function which controls the DSP.
1216 * the restart parameter in struct s2255_mode should be set whenever
1217 * the image size could change via color format, video system or image
1218 * size.
1219 * When the restart parameter is set, we sleep for ONE frame to allow the
1220 * DSP time to get the new frame
1221 */
1222static int s2255_set_mode(struct s2255_dev *dev, unsigned long chn,
1223 struct s2255_mode *mode)
1224{
1225 int res;
Dean Anderson3fa00602010-03-04 20:47:33 -03001226 __le32 *buffer;
Dean Anderson38f993a2008-06-26 23:15:51 -03001227 unsigned long chn_rev;
Dean Anderson14d96262008-08-25 13:58:55 -03001228 mutex_lock(&dev->lock);
Dean Anderson38f993a2008-06-26 23:15:51 -03001229 chn_rev = G_chnmap[chn];
1230 dprintk(3, "mode scale [%ld] %p %d\n", chn, mode, mode->scale);
1231 dprintk(3, "mode scale [%ld] %p %d\n", chn, &dev->mode[chn],
1232 dev->mode[chn].scale);
1233 dprintk(2, "mode contrast %x\n", mode->contrast);
1234
Dean Anderson22b88d42008-08-29 15:33:19 -03001235 /* if JPEG, set the quality */
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001236 if ((mode->color & MASK_COLOR) == COLOR_JPG) {
1237 mode->color &= ~MASK_COLOR;
1238 mode->color |= COLOR_JPG;
1239 mode->color &= ~MASK_JPG_QUALITY;
1240 mode->color |= (dev->jc[chn].quality << 8);
1241 }
Dean Anderson22b88d42008-08-29 15:33:19 -03001242
Dean Anderson38f993a2008-06-26 23:15:51 -03001243 /* save the mode */
1244 dev->mode[chn] = *mode;
1245 dev->req_image_size[chn] = get_transfer_size(mode);
1246 dprintk(1, "transfer size %ld\n", dev->req_image_size[chn]);
1247
1248 buffer = kzalloc(512, GFP_KERNEL);
1249 if (buffer == NULL) {
1250 dev_err(&dev->udev->dev, "out of mem\n");
Dean Anderson14d96262008-08-25 13:58:55 -03001251 mutex_unlock(&dev->lock);
Dean Anderson38f993a2008-06-26 23:15:51 -03001252 return -ENOMEM;
1253 }
1254
1255 /* set the mode */
1256 buffer[0] = IN_DATA_TOKEN;
Dean Anderson3fa00602010-03-04 20:47:33 -03001257 buffer[1] = (__le32) cpu_to_le32(chn_rev);
Dean Anderson38f993a2008-06-26 23:15:51 -03001258 buffer[2] = CMD_SET_MODE;
1259 memcpy(&buffer[3], &dev->mode[chn], sizeof(struct s2255_mode));
Dean Anderson9d63cec2009-04-20 19:07:44 -03001260 dev->setmode_ready[chn] = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001261 res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
1262 if (debug)
1263 dump_verify_mode(dev, mode);
1264 kfree(buffer);
1265 dprintk(1, "set mode done chn %lu, %d\n", chn, res);
1266
1267 /* wait at least 3 frames before continuing */
Dean Anderson14d96262008-08-25 13:58:55 -03001268 if (mode->restart) {
Dean Anderson14d96262008-08-25 13:58:55 -03001269 wait_event_timeout(dev->wait_setmode[chn],
1270 (dev->setmode_ready[chn] != 0),
1271 msecs_to_jiffies(S2255_SETMODE_TIMEOUT));
1272 if (dev->setmode_ready[chn] != 1) {
1273 printk(KERN_DEBUG "s2255: no set mode response\n");
1274 res = -EFAULT;
1275 }
1276 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001277
1278 /* clear the restart flag */
1279 dev->mode[chn].restart = 0;
Dean Anderson14d96262008-08-25 13:58:55 -03001280 mutex_unlock(&dev->lock);
Dean Anderson38f993a2008-06-26 23:15:51 -03001281 return res;
1282}
1283
Dean Anderson4de39f52010-03-03 19:39:19 -03001284static int s2255_cmd_status(struct s2255_dev *dev, unsigned long chn,
1285 u32 *pstatus)
1286{
1287 int res;
Dean Anderson3fa00602010-03-04 20:47:33 -03001288 __le32 *buffer;
Dean Anderson4de39f52010-03-03 19:39:19 -03001289 u32 chn_rev;
1290 mutex_lock(&dev->lock);
1291 chn_rev = G_chnmap[chn];
1292 dprintk(4, "%s chan %d\n", __func__, chn_rev);
1293 buffer = kzalloc(512, GFP_KERNEL);
1294 if (buffer == NULL) {
1295 dev_err(&dev->udev->dev, "out of mem\n");
1296 mutex_unlock(&dev->lock);
1297 return -ENOMEM;
1298 }
1299 /* form the get vid status command */
1300 buffer[0] = IN_DATA_TOKEN;
Dean Anderson3fa00602010-03-04 20:47:33 -03001301 buffer[1] = (__le32) cpu_to_le32(chn_rev);
Dean Anderson4de39f52010-03-03 19:39:19 -03001302 buffer[2] = CMD_STATUS;
1303 *pstatus = 0;
1304 dev->vidstatus_ready[chn] = 0;
1305 res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
1306 kfree(buffer);
1307 wait_event_timeout(dev->wait_vidstatus[chn],
1308 (dev->vidstatus_ready[chn] != 0),
1309 msecs_to_jiffies(S2255_VIDSTATUS_TIMEOUT));
1310 if (dev->vidstatus_ready[chn] != 1) {
1311 printk(KERN_DEBUG "s2255: no vidstatus response\n");
1312 res = -EFAULT;
1313 }
1314 *pstatus = dev->vidstatus[chn];
1315 dprintk(4, "%s, vid status %d\n", __func__, *pstatus);
1316 mutex_unlock(&dev->lock);
1317 return res;
1318}
1319
Dean Anderson38f993a2008-06-26 23:15:51 -03001320static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
1321{
1322 int res;
1323 struct s2255_fh *fh = priv;
1324 struct s2255_dev *dev = fh->dev;
1325 struct s2255_mode *new_mode;
1326 struct s2255_mode *old_mode;
1327 int chn;
1328 int j;
1329 dprintk(4, "%s\n", __func__);
1330 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1331 dev_err(&dev->udev->dev, "invalid fh type0\n");
1332 return -EINVAL;
1333 }
1334 if (i != fh->type) {
1335 dev_err(&dev->udev->dev, "invalid fh type1\n");
1336 return -EINVAL;
1337 }
1338
1339 if (!res_get(dev, fh)) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03001340 s2255_dev_err(&dev->udev->dev, "stream busy\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03001341 return -EBUSY;
1342 }
1343
1344 /* send a set mode command everytime with restart.
1345 in case we switch resolutions or other parameters */
1346 chn = fh->channel;
1347 new_mode = &fh->mode;
1348 old_mode = &fh->dev->mode[chn];
1349
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001350 if ((new_mode->color & MASK_COLOR) != (old_mode->color & MASK_COLOR))
Dean Anderson38f993a2008-06-26 23:15:51 -03001351 new_mode->restart = 1;
1352 else if (new_mode->scale != old_mode->scale)
1353 new_mode->restart = 1;
1354 else if (new_mode->format != old_mode->format)
1355 new_mode->restart = 1;
1356
1357 s2255_set_mode(dev, chn, new_mode);
1358 new_mode->restart = 0;
1359 *old_mode = *new_mode;
1360 dev->cur_fmt[chn] = fh->fmt;
1361 dprintk(1, "%s[%d]\n", __func__, chn);
1362 dev->last_frame[chn] = -1;
1363 dev->bad_payload[chn] = 0;
1364 dev->cur_frame[chn] = 0;
Dean Andersona1c45302008-09-09 12:29:56 -03001365 dev->frame_count[chn] = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001366 for (j = 0; j < SYS_FRAMES; j++) {
Dean Anderson14d96262008-08-25 13:58:55 -03001367 dev->buffer[chn].frame[j].ulState = S2255_READ_IDLE;
Dean Anderson38f993a2008-06-26 23:15:51 -03001368 dev->buffer[chn].frame[j].cur_size = 0;
1369 }
1370 res = videobuf_streamon(&fh->vb_vidq);
1371 if (res == 0) {
1372 s2255_start_acquire(dev, chn);
1373 dev->b_acquire[chn] = 1;
1374 } else {
1375 res_free(dev, fh);
1376 }
1377 return res;
1378}
1379
1380static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
1381{
Dean Anderson38f993a2008-06-26 23:15:51 -03001382 struct s2255_fh *fh = priv;
1383 struct s2255_dev *dev = fh->dev;
1384
1385 dprintk(4, "%s\n, channel: %d", __func__, fh->channel);
1386 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1387 printk(KERN_ERR "invalid fh type0\n");
1388 return -EINVAL;
1389 }
1390 if (i != fh->type) {
1391 printk(KERN_ERR "invalid type i\n");
1392 return -EINVAL;
1393 }
1394 s2255_stop_acquire(dev, fh->channel);
Dean Andersonb7732a32009-03-30 11:59:56 -03001395 videobuf_streamoff(&fh->vb_vidq);
Dean Anderson38f993a2008-06-26 23:15:51 -03001396 res_free(dev, fh);
Dean Andersonf78d92c2008-07-22 14:43:27 -03001397 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001398}
1399
1400static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *i)
1401{
1402 struct s2255_fh *fh = priv;
1403 struct s2255_mode *mode;
1404 struct videobuf_queue *q = &fh->vb_vidq;
1405 int ret = 0;
1406
1407 mutex_lock(&q->vb_lock);
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001408
Dean Anderson38f993a2008-06-26 23:15:51 -03001409 if (videobuf_queue_is_busy(q)) {
1410 dprintk(1, "queue busy\n");
1411 ret = -EBUSY;
1412 goto out_s_std;
1413 }
1414
1415 if (res_locked(fh->dev, fh)) {
1416 dprintk(1, "can't change standard after started\n");
1417 ret = -EBUSY;
1418 goto out_s_std;
1419 }
1420 mode = &fh->mode;
Dean Anderson38f993a2008-06-26 23:15:51 -03001421 if (*i & V4L2_STD_NTSC) {
Dean Andersone6b44bc2010-03-08 20:04:48 -03001422 dprintk(4, "%s NTSC\n", __func__);
1423 /* if changing format, reset frame decimation/intervals */
1424 if (mode->format != FORMAT_NTSC) {
1425 mode->format = FORMAT_NTSC;
1426 mode->fdec = FDEC_1;
1427 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001428 } else if (*i & V4L2_STD_PAL) {
Dean Andersone6b44bc2010-03-08 20:04:48 -03001429 dprintk(4, "%s PAL\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03001430 mode->format = FORMAT_PAL;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001431 if (mode->format != FORMAT_PAL) {
1432 mode->format = FORMAT_PAL;
1433 mode->fdec = FDEC_1;
1434 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001435 } else {
1436 ret = -EINVAL;
1437 }
1438out_s_std:
1439 mutex_unlock(&q->vb_lock);
1440 return ret;
1441}
1442
1443/* Sensoray 2255 is a multiple channel capture device.
1444 It does not have a "crossbar" of inputs.
1445 We use one V4L device per channel. The user must
1446 be aware that certain combinations are not allowed.
1447 For instance, you cannot do full FPS on more than 2 channels(2 videodevs)
1448 at once in color(you can do full fps on 4 channels with greyscale.
1449*/
1450static int vidioc_enum_input(struct file *file, void *priv,
1451 struct v4l2_input *inp)
1452{
Dean Anderson4de39f52010-03-03 19:39:19 -03001453 struct s2255_fh *fh = priv;
1454 struct s2255_dev *dev = fh->dev;
1455 u32 status = 0;
1456
Dean Anderson38f993a2008-06-26 23:15:51 -03001457 if (inp->index != 0)
1458 return -EINVAL;
1459
1460 inp->type = V4L2_INPUT_TYPE_CAMERA;
1461 inp->std = S2255_NORMS;
Dean Anderson4de39f52010-03-03 19:39:19 -03001462 inp->status = 0;
1463 if (dev->dsp_fw_ver >= S2255_MIN_DSP_STATUS) {
1464 int rc;
1465 rc = s2255_cmd_status(dev, fh->channel, &status);
1466 dprintk(4, "s2255_cmd_status rc: %d status %x\n", rc, status);
1467 if (rc == 0)
1468 inp->status = (status & 0x01) ? 0
1469 : V4L2_IN_ST_NO_SIGNAL;
1470 }
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001471 switch (dev->pid) {
1472 case 0x2255:
1473 default:
1474 strlcpy(inp->name, "Composite", sizeof(inp->name));
1475 break;
1476 case 0x2257:
1477 strlcpy(inp->name, (fh->channel < 2) ? "Composite" : "S-Video",
1478 sizeof(inp->name));
1479 break;
1480 }
Dean Anderson3f8d6f72008-06-30 21:28:34 -03001481 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001482}
1483
1484static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
1485{
1486 *i = 0;
1487 return 0;
1488}
1489static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
1490{
1491 if (i > 0)
1492 return -EINVAL;
1493 return 0;
1494}
1495
1496/* --- controls ---------------------------------------------- */
1497static int vidioc_queryctrl(struct file *file, void *priv,
1498 struct v4l2_queryctrl *qc)
1499{
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001500 struct s2255_fh *fh = priv;
1501 struct s2255_dev *dev = fh->dev;
Dean Anderson2e70db92010-03-05 14:29:09 -03001502 switch (qc->id) {
1503 case V4L2_CID_BRIGHTNESS:
1504 v4l2_ctrl_query_fill(qc, -127, 127, 1, DEF_BRIGHT);
1505 break;
1506 case V4L2_CID_CONTRAST:
1507 v4l2_ctrl_query_fill(qc, 0, 255, 1, DEF_CONTRAST);
1508 break;
1509 case V4L2_CID_SATURATION:
1510 v4l2_ctrl_query_fill(qc, 0, 255, 1, DEF_SATURATION);
1511 break;
1512 case V4L2_CID_HUE:
1513 v4l2_ctrl_query_fill(qc, 0, 255, 1, DEF_HUE);
1514 break;
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001515 case V4L2_CID_PRIVATE_COLORFILTER:
1516 if (dev->dsp_fw_ver < S2255_MIN_DSP_COLORFILTER)
1517 return -EINVAL;
1518 if ((dev->pid == 0x2257) && (fh->channel > 1))
1519 return -EINVAL;
1520 strlcpy(qc->name, "Color Filter", sizeof(qc->name));
1521 qc->type = V4L2_CTRL_TYPE_MENU;
1522 qc->minimum = 0;
1523 qc->maximum = 1;
1524 qc->step = 1;
1525 qc->default_value = 1;
1526 qc->flags = 0;
1527 break;
Dean Anderson2e70db92010-03-05 14:29:09 -03001528 default:
1529 return -EINVAL;
1530 }
1531 dprintk(4, "%s, id %d\n", __func__, qc->id);
1532 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001533}
1534
1535static int vidioc_g_ctrl(struct file *file, void *priv,
1536 struct v4l2_control *ctrl)
1537{
Dean Anderson2e70db92010-03-05 14:29:09 -03001538 struct s2255_fh *fh = priv;
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001539 struct s2255_dev *dev = fh->dev;
Dean Anderson2e70db92010-03-05 14:29:09 -03001540 switch (ctrl->id) {
1541 case V4L2_CID_BRIGHTNESS:
1542 ctrl->value = fh->mode.bright;
1543 break;
1544 case V4L2_CID_CONTRAST:
1545 ctrl->value = fh->mode.contrast;
1546 break;
1547 case V4L2_CID_SATURATION:
1548 ctrl->value = fh->mode.saturation;
1549 break;
1550 case V4L2_CID_HUE:
1551 ctrl->value = fh->mode.hue;
1552 break;
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001553 case V4L2_CID_PRIVATE_COLORFILTER:
1554 if (dev->dsp_fw_ver < S2255_MIN_DSP_COLORFILTER)
1555 return -EINVAL;
1556 if ((dev->pid == 0x2257) && (fh->channel > 1))
1557 return -EINVAL;
1558 ctrl->value = !((fh->mode.color & MASK_INPUT_TYPE) >> 16);
1559 break;
Dean Anderson2e70db92010-03-05 14:29:09 -03001560 default:
1561 return -EINVAL;
1562 }
1563 dprintk(4, "%s, id %d val %d\n", __func__, ctrl->id, ctrl->value);
1564 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001565}
1566
1567static int vidioc_s_ctrl(struct file *file, void *priv,
1568 struct v4l2_control *ctrl)
1569{
Dean Anderson38f993a2008-06-26 23:15:51 -03001570 struct s2255_fh *fh = priv;
1571 struct s2255_dev *dev = fh->dev;
1572 struct s2255_mode *mode;
1573 mode = &fh->mode;
Dean Anderson2e70db92010-03-05 14:29:09 -03001574 dprintk(4, "%s\n", __func__);
1575 /* update the mode to the corresponding value */
1576 switch (ctrl->id) {
1577 case V4L2_CID_BRIGHTNESS:
1578 mode->bright = ctrl->value;
1579 break;
1580 case V4L2_CID_CONTRAST:
1581 mode->contrast = ctrl->value;
1582 break;
1583 case V4L2_CID_HUE:
1584 mode->hue = ctrl->value;
1585 break;
1586 case V4L2_CID_SATURATION:
1587 mode->saturation = ctrl->value;
1588 break;
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001589 case V4L2_CID_PRIVATE_COLORFILTER:
1590 if (dev->dsp_fw_ver < S2255_MIN_DSP_COLORFILTER)
1591 return -EINVAL;
1592 if ((dev->pid == 0x2257) && (fh->channel > 1))
1593 return -EINVAL;
1594 mode->color &= ~MASK_INPUT_TYPE;
1595 mode->color |= ((ctrl->value ? 0 : 1) << 16);
1596 break;
Dean Anderson2e70db92010-03-05 14:29:09 -03001597 default:
1598 return -EINVAL;
Dean Anderson38f993a2008-06-26 23:15:51 -03001599 }
Dean Anderson2e70db92010-03-05 14:29:09 -03001600 mode->restart = 0;
1601 /* set mode here. Note: stream does not need restarted.
1602 some V4L programs restart stream unnecessarily
1603 after a s_crtl.
1604 */
1605 s2255_set_mode(dev, fh->channel, mode);
1606 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001607}
1608
Dean Anderson22b88d42008-08-29 15:33:19 -03001609static int vidioc_g_jpegcomp(struct file *file, void *priv,
1610 struct v4l2_jpegcompression *jc)
1611{
1612 struct s2255_fh *fh = priv;
1613 struct s2255_dev *dev = fh->dev;
1614 *jc = dev->jc[fh->channel];
1615 dprintk(2, "getting jpegcompression, quality %d\n", jc->quality);
1616 return 0;
1617}
1618
1619static int vidioc_s_jpegcomp(struct file *file, void *priv,
1620 struct v4l2_jpegcompression *jc)
1621{
1622 struct s2255_fh *fh = priv;
1623 struct s2255_dev *dev = fh->dev;
1624 if (jc->quality < 0 || jc->quality > 100)
1625 return -EINVAL;
1626 dev->jc[fh->channel].quality = jc->quality;
1627 dprintk(2, "setting jpeg quality %d\n", jc->quality);
1628 return 0;
1629}
Dean Anderson7d853532009-05-15 14:32:04 -03001630
1631static int vidioc_g_parm(struct file *file, void *priv,
1632 struct v4l2_streamparm *sp)
1633{
1634 struct s2255_fh *fh = priv;
1635 struct s2255_dev *dev = fh->dev;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001636 __u32 def_num, def_dem;
Dean Anderson7d853532009-05-15 14:32:04 -03001637 if (sp->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1638 return -EINVAL;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001639 memset(sp, 0, sizeof(struct v4l2_streamparm));
1640 sp->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
Dean Anderson7d853532009-05-15 14:32:04 -03001641 sp->parm.capture.capturemode = dev->cap_parm[fh->channel].capturemode;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001642 def_num = (fh->mode.format == FORMAT_NTSC) ? 1001 : 1000;
1643 def_dem = (fh->mode.format == FORMAT_NTSC) ? 30000 : 25000;
1644 sp->parm.capture.timeperframe.denominator = def_dem;
1645 switch (fh->mode.fdec) {
1646 default:
1647 case FDEC_1:
1648 sp->parm.capture.timeperframe.numerator = def_num;
1649 break;
1650 case FDEC_2:
1651 sp->parm.capture.timeperframe.numerator = def_num * 2;
1652 break;
1653 case FDEC_3:
1654 sp->parm.capture.timeperframe.numerator = def_num * 3;
1655 break;
1656 case FDEC_5:
1657 sp->parm.capture.timeperframe.numerator = def_num * 5;
1658 break;
1659 }
1660 dprintk(4, "%s capture mode, %d timeperframe %d/%d\n", __func__,
1661 sp->parm.capture.capturemode,
1662 sp->parm.capture.timeperframe.numerator,
1663 sp->parm.capture.timeperframe.denominator);
Dean Anderson7d853532009-05-15 14:32:04 -03001664 return 0;
1665}
1666
1667static int vidioc_s_parm(struct file *file, void *priv,
1668 struct v4l2_streamparm *sp)
1669{
1670 struct s2255_fh *fh = priv;
1671 struct s2255_dev *dev = fh->dev;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001672 int fdec = FDEC_1;
1673 __u32 def_num, def_dem;
Dean Anderson7d853532009-05-15 14:32:04 -03001674 if (sp->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1675 return -EINVAL;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001676 /* high quality capture mode requires a stream restart */
1677 if (dev->cap_parm[fh->channel].capturemode
1678 != sp->parm.capture.capturemode && res_locked(fh->dev, fh))
1679 return -EBUSY;
1680 def_num = (fh->mode.format == FORMAT_NTSC) ? 1001 : 1000;
1681 def_dem = (fh->mode.format == FORMAT_NTSC) ? 30000 : 25000;
1682 if (def_dem != sp->parm.capture.timeperframe.denominator)
1683 sp->parm.capture.timeperframe.numerator = def_num;
1684 else if (sp->parm.capture.timeperframe.numerator <= def_num)
1685 sp->parm.capture.timeperframe.numerator = def_num;
1686 else if (sp->parm.capture.timeperframe.numerator <= (def_num * 2)) {
1687 sp->parm.capture.timeperframe.numerator = def_num * 2;
1688 fdec = FDEC_2;
1689 } else if (sp->parm.capture.timeperframe.numerator <= (def_num * 3)) {
1690 sp->parm.capture.timeperframe.numerator = def_num * 3;
1691 fdec = FDEC_3;
1692 } else {
1693 sp->parm.capture.timeperframe.numerator = def_num * 5;
1694 fdec = FDEC_5;
1695 }
1696 fh->mode.fdec = fdec;
1697 sp->parm.capture.timeperframe.denominator = def_dem;
1698 s2255_set_mode(dev, fh->channel, &fh->mode);
1699 dprintk(4, "%s capture mode, %d timeperframe %d/%d, fdec %d\n",
1700 __func__,
1701 sp->parm.capture.capturemode,
1702 sp->parm.capture.timeperframe.numerator,
1703 sp->parm.capture.timeperframe.denominator, fdec);
Dean Anderson7d853532009-05-15 14:32:04 -03001704 return 0;
1705}
Dean Andersone6b44bc2010-03-08 20:04:48 -03001706
1707static int vidioc_enum_frameintervals(struct file *file, void *priv,
1708 struct v4l2_frmivalenum *fe)
1709{
1710 int is_ntsc = 0;
1711#define NUM_FRAME_ENUMS 4
1712 int frm_dec[NUM_FRAME_ENUMS] = {1, 2, 3, 5};
1713 if (fe->index < 0 || fe->index >= NUM_FRAME_ENUMS)
1714 return -EINVAL;
1715 switch (fe->width) {
1716 case 640:
1717 if (fe->height != 240 && fe->height != 480)
1718 return -EINVAL;
1719 is_ntsc = 1;
1720 break;
1721 case 320:
1722 if (fe->height != 240)
1723 return -EINVAL;
1724 is_ntsc = 1;
1725 break;
1726 case 704:
1727 if (fe->height != 288 && fe->height != 576)
1728 return -EINVAL;
1729 break;
1730 case 352:
1731 if (fe->height != 288)
1732 return -EINVAL;
1733 break;
1734 default:
1735 return -EINVAL;
1736 }
1737 fe->type = V4L2_FRMIVAL_TYPE_DISCRETE;
1738 fe->discrete.denominator = is_ntsc ? 30000 : 25000;
1739 fe->discrete.numerator = (is_ntsc ? 1001 : 1000) * frm_dec[fe->index];
1740 dprintk(4, "%s discrete %d/%d\n", __func__, fe->discrete.numerator,
1741 fe->discrete.denominator);
1742 return 0;
1743}
1744
Hans Verkuilbec43662008-12-30 06:58:20 -03001745static int s2255_open(struct file *file)
Dean Anderson38f993a2008-06-26 23:15:51 -03001746{
Laurent Pinchart63b0d5a2009-12-10 11:44:04 -02001747 struct video_device *vdev = video_devdata(file);
1748 struct s2255_dev *dev = video_drvdata(file);
Dean Anderson38f993a2008-06-26 23:15:51 -03001749 struct s2255_fh *fh;
Laurent Pinchart63b0d5a2009-12-10 11:44:04 -02001750 enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
Dean Anderson38f993a2008-06-26 23:15:51 -03001751 int i = 0;
1752 int cur_channel = -1;
Dean Anderson14d96262008-08-25 13:58:55 -03001753 int state;
Laurent Pinchart50462eb2009-12-10 11:47:13 -02001754 dprintk(1, "s2255: open called (dev=%s)\n",
1755 video_device_node_name(vdev));
Hans Verkuild56dc612008-07-30 08:43:36 -03001756 lock_kernel();
Dean Andersonff7e22d2010-04-08 23:38:07 -03001757 for (i = 0; i < MAX_CHANNELS; i++)
Laurent Pinchart63b0d5a2009-12-10 11:44:04 -02001758 if (dev->vdev[i] == vdev) {
1759 cur_channel = i;
1760 break;
1761 }
Dean Andersonff7e22d2010-04-08 23:38:07 -03001762 /*
1763 * open lock necessary to prevent multiple instances
1764 * of v4l-conf (or other programs) from simultaneously
1765 * reloading firmware.
1766 */
Dean Anderson38f993a2008-06-26 23:15:51 -03001767 mutex_lock(&dev->open_lock);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001768 state = atomic_read(&dev->fw_data->fw_state);
1769 switch (state) {
1770 case S2255_FW_DISCONNECTING:
1771 mutex_unlock(&dev->open_lock);
1772 unlock_kernel();
1773 return -ENODEV;
Dean Anderson14d96262008-08-25 13:58:55 -03001774 case S2255_FW_FAILED:
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03001775 s2255_dev_err(&dev->udev->dev,
1776 "firmware load failed. retrying.\n");
Dean Anderson14d96262008-08-25 13:58:55 -03001777 s2255_fwload_start(dev, 1);
Dean Anderson38f993a2008-06-26 23:15:51 -03001778 wait_event_timeout(dev->fw_data->wait_fw,
Dean Anderson14d96262008-08-25 13:58:55 -03001779 ((atomic_read(&dev->fw_data->fw_state)
1780 == S2255_FW_SUCCESS) ||
1781 (atomic_read(&dev->fw_data->fw_state)
1782 == S2255_FW_DISCONNECTING)),
Dean Anderson38f993a2008-06-26 23:15:51 -03001783 msecs_to_jiffies(S2255_LOAD_TIMEOUT));
Dean Andersonff7e22d2010-04-08 23:38:07 -03001784 /* state may have changed, re-read */
1785 state = atomic_read(&dev->fw_data->fw_state);
Dean Anderson14d96262008-08-25 13:58:55 -03001786 break;
1787 case S2255_FW_NOTLOADED:
1788 case S2255_FW_LOADED_DSPWAIT:
Dean Anderson38f993a2008-06-26 23:15:51 -03001789 /* give S2255_LOAD_TIMEOUT time for firmware to load in case
1790 driver loaded and then device immediately opened */
1791 printk(KERN_INFO "%s waiting for firmware load\n", __func__);
1792 wait_event_timeout(dev->fw_data->wait_fw,
Dean Anderson14d96262008-08-25 13:58:55 -03001793 ((atomic_read(&dev->fw_data->fw_state)
1794 == S2255_FW_SUCCESS) ||
1795 (atomic_read(&dev->fw_data->fw_state)
1796 == S2255_FW_DISCONNECTING)),
1797 msecs_to_jiffies(S2255_LOAD_TIMEOUT));
Dean Andersonff7e22d2010-04-08 23:38:07 -03001798 /* state may have changed, re-read */
1799 state = atomic_read(&dev->fw_data->fw_state);
Dean Anderson14d96262008-08-25 13:58:55 -03001800 break;
1801 case S2255_FW_SUCCESS:
1802 default:
1803 break;
1804 }
Dean Andersonff7e22d2010-04-08 23:38:07 -03001805 mutex_unlock(&dev->open_lock);
1806 /* state may have changed in above switch statement */
1807 switch (state) {
1808 case S2255_FW_SUCCESS:
1809 break;
1810 case S2255_FW_FAILED:
1811 printk(KERN_INFO "2255 firmware load failed.\n");
Dean Anderson14d96262008-08-25 13:58:55 -03001812 unlock_kernel();
Dean Andersonff7e22d2010-04-08 23:38:07 -03001813 return -ENODEV;
1814 case S2255_FW_DISCONNECTING:
1815 printk(KERN_INFO "%s: disconnecting\n", __func__);
1816 unlock_kernel();
1817 return -ENODEV;
1818 case S2255_FW_LOADED_DSPWAIT:
1819 case S2255_FW_NOTLOADED:
1820 printk(KERN_INFO "%s: firmware not loaded yet"
1821 "please try again later\n",
1822 __func__);
1823 unlock_kernel();
1824 return -EAGAIN;
1825 default:
1826 printk(KERN_INFO "%s: unknown state\n", __func__);
1827 unlock_kernel();
1828 return -EFAULT;
Dean Anderson38f993a2008-06-26 23:15:51 -03001829 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001830 /* allocate + initialize per filehandle data */
1831 fh = kzalloc(sizeof(*fh), GFP_KERNEL);
1832 if (NULL == fh) {
Hans Verkuild56dc612008-07-30 08:43:36 -03001833 unlock_kernel();
Dean Anderson38f993a2008-06-26 23:15:51 -03001834 return -ENOMEM;
1835 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001836 file->private_data = fh;
1837 fh->dev = dev;
1838 fh->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1839 fh->mode = dev->mode[cur_channel];
1840 fh->fmt = dev->cur_fmt[cur_channel];
1841 /* default 4CIF NTSC */
1842 fh->width = LINE_SZ_4CIFS_NTSC;
1843 fh->height = NUM_LINES_4CIFS_NTSC * 2;
1844 fh->channel = cur_channel;
Dean Anderson14d96262008-08-25 13:58:55 -03001845 /* configure channel to default state */
1846 if (!dev->chn_configured[cur_channel]) {
1847 s2255_set_mode(dev, cur_channel, &fh->mode);
1848 dev->chn_configured[cur_channel] = 1;
1849 }
Dean Andersonff7e22d2010-04-08 23:38:07 -03001850 dprintk(1, "s2255drv: open dev=%s type=%s\n",
1851 video_device_node_name(vdev), v4l2_type_names[type]);
Dean Anderson38f993a2008-06-26 23:15:51 -03001852 dprintk(2, "s2255drv: open: fh=0x%08lx, dev=0x%08lx, vidq=0x%08lx\n",
1853 (unsigned long)fh, (unsigned long)dev,
1854 (unsigned long)&dev->vidq[cur_channel]);
1855 dprintk(4, "s2255drv: open: list_empty active=%d\n",
1856 list_empty(&dev->vidq[cur_channel].active));
1857
1858 videobuf_queue_vmalloc_init(&fh->vb_vidq, &s2255_video_qops,
1859 NULL, &dev->slock,
1860 fh->type,
1861 V4L2_FIELD_INTERLACED,
1862 sizeof(struct s2255_buffer), fh);
Hans Verkuild56dc612008-07-30 08:43:36 -03001863 unlock_kernel();
Dean Anderson38f993a2008-06-26 23:15:51 -03001864 return 0;
1865}
1866
1867
1868static unsigned int s2255_poll(struct file *file,
1869 struct poll_table_struct *wait)
1870{
1871 struct s2255_fh *fh = file->private_data;
1872 int rc;
1873 dprintk(100, "%s\n", __func__);
1874
1875 if (V4L2_BUF_TYPE_VIDEO_CAPTURE != fh->type)
1876 return POLLERR;
1877
1878 rc = videobuf_poll_stream(file, &fh->vb_vidq, wait);
1879 return rc;
1880}
1881
1882static void s2255_destroy(struct kref *kref)
1883{
1884 struct s2255_dev *dev = to_s2255_dev(kref);
Dean Anderson38f993a2008-06-26 23:15:51 -03001885 /* board shutdown stops the read pipe if it is running */
1886 s2255_board_shutdown(dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03001887 /* make sure firmware still not trying to load */
Dean Andersonf78d92c2008-07-22 14:43:27 -03001888 del_timer(&dev->timer); /* only started in .probe and .open */
Dean Anderson38f993a2008-06-26 23:15:51 -03001889 if (dev->fw_data->fw_urb) {
1890 dprintk(2, "kill fw_urb\n");
1891 usb_kill_urb(dev->fw_data->fw_urb);
1892 usb_free_urb(dev->fw_data->fw_urb);
1893 dev->fw_data->fw_urb = NULL;
1894 }
Dean Andersonf78d92c2008-07-22 14:43:27 -03001895 if (dev->fw_data->fw)
1896 release_firmware(dev->fw_data->fw);
1897 kfree(dev->fw_data->pfw_data);
1898 kfree(dev->fw_data);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001899 /* reset the DSP so firmware can be reloaded next time */
1900 s2255_reset_dsppower(dev);
1901 mutex_destroy(&dev->open_lock);
1902 mutex_destroy(&dev->lock);
Dean Anderson38f993a2008-06-26 23:15:51 -03001903 usb_put_dev(dev->udev);
1904 dprintk(1, "%s", __func__);
Dean Andersonb7732a32009-03-30 11:59:56 -03001905 kfree(dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03001906}
1907
Dean Andersonff7e22d2010-04-08 23:38:07 -03001908static int s2255_release(struct file *file)
Dean Anderson38f993a2008-06-26 23:15:51 -03001909{
1910 struct s2255_fh *fh = file->private_data;
1911 struct s2255_dev *dev = fh->dev;
Laurent Pinchart50462eb2009-12-10 11:47:13 -02001912 struct video_device *vdev = video_devdata(file);
Dean Anderson38f993a2008-06-26 23:15:51 -03001913 if (!dev)
1914 return -ENODEV;
Dean Andersonf78d92c2008-07-22 14:43:27 -03001915 /* turn off stream */
1916 if (res_check(fh)) {
1917 if (dev->b_acquire[fh->channel])
1918 s2255_stop_acquire(dev, fh->channel);
1919 videobuf_streamoff(&fh->vb_vidq);
1920 res_free(dev, fh);
1921 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001922 videobuf_mmap_free(&fh->vb_vidq);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001923 dprintk(1, "%s (dev=%s)\n", __func__, video_device_node_name(vdev));
Dean Andersonf78d92c2008-07-22 14:43:27 -03001924 kfree(fh);
Dean Anderson38f993a2008-06-26 23:15:51 -03001925 return 0;
1926}
1927
1928static int s2255_mmap_v4l(struct file *file, struct vm_area_struct *vma)
1929{
1930 struct s2255_fh *fh = file->private_data;
1931 int ret;
1932
1933 if (!fh)
1934 return -ENODEV;
1935 dprintk(4, "mmap called, vma=0x%08lx\n", (unsigned long)vma);
1936
1937 ret = videobuf_mmap_mapper(&fh->vb_vidq, vma);
1938
1939 dprintk(4, "vma start=0x%08lx, size=%ld, ret=%d\n",
1940 (unsigned long)vma->vm_start,
1941 (unsigned long)vma->vm_end - (unsigned long)vma->vm_start, ret);
1942
1943 return ret;
1944}
1945
Hans Verkuilbec43662008-12-30 06:58:20 -03001946static const struct v4l2_file_operations s2255_fops_v4l = {
Dean Anderson38f993a2008-06-26 23:15:51 -03001947 .owner = THIS_MODULE,
1948 .open = s2255_open,
Dean Andersonff7e22d2010-04-08 23:38:07 -03001949 .release = s2255_release,
Dean Anderson38f993a2008-06-26 23:15:51 -03001950 .poll = s2255_poll,
1951 .ioctl = video_ioctl2, /* V4L2 ioctl handler */
Dean Anderson38f993a2008-06-26 23:15:51 -03001952 .mmap = s2255_mmap_v4l,
Dean Anderson38f993a2008-06-26 23:15:51 -03001953};
1954
Hans Verkuila3998102008-07-21 02:57:38 -03001955static const struct v4l2_ioctl_ops s2255_ioctl_ops = {
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001956 .vidioc_querymenu = vidioc_querymenu,
Dean Anderson38f993a2008-06-26 23:15:51 -03001957 .vidioc_querycap = vidioc_querycap,
1958 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
1959 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
1960 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
1961 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
1962 .vidioc_reqbufs = vidioc_reqbufs,
1963 .vidioc_querybuf = vidioc_querybuf,
1964 .vidioc_qbuf = vidioc_qbuf,
1965 .vidioc_dqbuf = vidioc_dqbuf,
1966 .vidioc_s_std = vidioc_s_std,
1967 .vidioc_enum_input = vidioc_enum_input,
1968 .vidioc_g_input = vidioc_g_input,
1969 .vidioc_s_input = vidioc_s_input,
1970 .vidioc_queryctrl = vidioc_queryctrl,
1971 .vidioc_g_ctrl = vidioc_g_ctrl,
1972 .vidioc_s_ctrl = vidioc_s_ctrl,
1973 .vidioc_streamon = vidioc_streamon,
1974 .vidioc_streamoff = vidioc_streamoff,
1975#ifdef CONFIG_VIDEO_V4L1_COMPAT
1976 .vidiocgmbuf = vidioc_cgmbuf,
1977#endif
Dean Anderson22b88d42008-08-29 15:33:19 -03001978 .vidioc_s_jpegcomp = vidioc_s_jpegcomp,
1979 .vidioc_g_jpegcomp = vidioc_g_jpegcomp,
Dean Anderson7d853532009-05-15 14:32:04 -03001980 .vidioc_s_parm = vidioc_s_parm,
1981 .vidioc_g_parm = vidioc_g_parm,
Dean Andersone6b44bc2010-03-08 20:04:48 -03001982 .vidioc_enum_frameintervals = vidioc_enum_frameintervals,
Hans Verkuila3998102008-07-21 02:57:38 -03001983};
1984
Dean Andersonff7e22d2010-04-08 23:38:07 -03001985static void s2255_video_device_release(struct video_device *vdev)
1986{
1987 struct s2255_dev *dev = video_get_drvdata(vdev);
1988 video_device_release(vdev);
1989 kref_put(&dev->kref, s2255_destroy);
1990 return;
1991}
1992
Hans Verkuila3998102008-07-21 02:57:38 -03001993static struct video_device template = {
1994 .name = "s2255v",
Hans Verkuila3998102008-07-21 02:57:38 -03001995 .fops = &s2255_fops_v4l,
1996 .ioctl_ops = &s2255_ioctl_ops,
Dean Andersonff7e22d2010-04-08 23:38:07 -03001997 .release = s2255_video_device_release,
Dean Anderson38f993a2008-06-26 23:15:51 -03001998 .tvnorms = S2255_NORMS,
1999 .current_norm = V4L2_STD_NTSC_M,
2000};
2001
2002static int s2255_probe_v4l(struct s2255_dev *dev)
2003{
2004 int ret;
2005 int i;
2006 int cur_nr = video_nr;
2007
2008 /* initialize all video 4 linux */
Dean Anderson38f993a2008-06-26 23:15:51 -03002009 /* register 4 video devices */
2010 for (i = 0; i < MAX_CHANNELS; i++) {
2011 INIT_LIST_HEAD(&dev->vidq[i].active);
2012 dev->vidq[i].dev = dev;
2013 dev->vidq[i].channel = i;
Dean Anderson38f993a2008-06-26 23:15:51 -03002014 /* register 4 video devices */
2015 dev->vdev[i] = video_device_alloc();
2016 memcpy(dev->vdev[i], &template, sizeof(struct video_device));
Hans Verkuil5e85e732008-07-20 06:31:39 -03002017 dev->vdev[i]->parent = &dev->interface->dev;
Laurent Pinchart63b0d5a2009-12-10 11:44:04 -02002018 video_set_drvdata(dev->vdev[i], dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03002019 if (video_nr == -1)
2020 ret = video_register_device(dev->vdev[i],
2021 VFL_TYPE_GRABBER,
2022 video_nr);
2023 else
2024 ret = video_register_device(dev->vdev[i],
2025 VFL_TYPE_GRABBER,
2026 cur_nr + i);
Hans Verkuil601e9442008-08-23 07:24:07 -03002027 video_set_drvdata(dev->vdev[i], dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03002028
2029 if (ret != 0) {
2030 dev_err(&dev->udev->dev,
2031 "failed to register video device!\n");
2032 return ret;
2033 }
2034 }
Dean Andersonabce21f2009-04-23 16:04:41 -03002035 printk(KERN_INFO "Sensoray 2255 V4L driver Revision: %d.%d\n",
2036 S2255_MAJOR_VERSION,
2037 S2255_MINOR_VERSION);
Dean Anderson38f993a2008-06-26 23:15:51 -03002038 return ret;
2039}
2040
Dean Anderson38f993a2008-06-26 23:15:51 -03002041/* this function moves the usb stream read pipe data
2042 * into the system buffers.
2043 * returns 0 on success, EAGAIN if more data to process( call this
2044 * function again).
2045 *
2046 * Received frame structure:
Dean Anderson14d96262008-08-25 13:58:55 -03002047 * bytes 0-3: marker : 0x2255DA4AL (S2255_MARKER_FRAME)
Dean Anderson38f993a2008-06-26 23:15:51 -03002048 * bytes 4-7: channel: 0-3
2049 * bytes 8-11: payload size: size of the frame
2050 * bytes 12-payloadsize+12: frame data
2051 */
2052static int save_frame(struct s2255_dev *dev, struct s2255_pipeinfo *pipe_info)
2053{
Dean Anderson38f993a2008-06-26 23:15:51 -03002054 char *pdest;
2055 u32 offset = 0;
Dean Anderson14d96262008-08-25 13:58:55 -03002056 int bframe = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03002057 char *psrc;
2058 unsigned long copy_size;
2059 unsigned long size;
2060 s32 idx = -1;
2061 struct s2255_framei *frm;
2062 unsigned char *pdata;
Dean Anderson14d96262008-08-25 13:58:55 -03002063
Dean Anderson38f993a2008-06-26 23:15:51 -03002064 dprintk(100, "buffer to user\n");
2065
2066 idx = dev->cur_frame[dev->cc];
Dean Anderson38f993a2008-06-26 23:15:51 -03002067 frm = &dev->buffer[dev->cc].frame[idx];
2068
Dean Anderson14d96262008-08-25 13:58:55 -03002069 if (frm->ulState == S2255_READ_IDLE) {
2070 int jj;
2071 unsigned int cc;
Dean Anderson3fa00602010-03-04 20:47:33 -03002072 __le32 *pdword; /*data from dsp is little endian */
Dean Anderson14d96262008-08-25 13:58:55 -03002073 int payload;
2074 /* search for marker codes */
2075 pdata = (unsigned char *)pipe_info->transfer_buffer;
Dean Anderson3fa00602010-03-04 20:47:33 -03002076 pdword = (__le32 *)pdata;
Dean Anderson14d96262008-08-25 13:58:55 -03002077 for (jj = 0; jj < (pipe_info->cur_transfer_size - 12); jj++) {
Dean Anderson3fa00602010-03-04 20:47:33 -03002078 switch (*pdword) {
Dean Anderson14d96262008-08-25 13:58:55 -03002079 case S2255_MARKER_FRAME:
Dean Anderson14d96262008-08-25 13:58:55 -03002080 dprintk(4, "found frame marker at offset:"
2081 " %d [%x %x]\n", jj, pdata[0],
2082 pdata[1]);
2083 offset = jj + PREFIX_SIZE;
2084 bframe = 1;
2085 cc = pdword[1];
2086 if (cc >= MAX_CHANNELS) {
2087 printk(KERN_ERR
2088 "bad channel\n");
2089 return -EINVAL;
2090 }
2091 /* reverse it */
2092 dev->cc = G_chnmap[cc];
2093 payload = pdword[3];
2094 if (payload > dev->req_image_size[dev->cc]) {
2095 dev->bad_payload[dev->cc]++;
2096 /* discard the bad frame */
2097 return -EINVAL;
2098 }
2099 dev->pkt_size[dev->cc] = payload;
2100 dev->jpg_size[dev->cc] = pdword[4];
2101 break;
2102 case S2255_MARKER_RESPONSE:
Dean Anderson14d96262008-08-25 13:58:55 -03002103 pdata += DEF_USB_BLOCK;
2104 jj += DEF_USB_BLOCK;
2105 if (pdword[1] >= MAX_CHANNELS)
2106 break;
2107 cc = G_chnmap[pdword[1]];
Roel Kluinf14a2972009-10-23 07:59:42 -03002108 if (cc >= MAX_CHANNELS)
Dean Anderson14d96262008-08-25 13:58:55 -03002109 break;
2110 switch (pdword[2]) {
Dean Andersonabce21f2009-04-23 16:04:41 -03002111 case S2255_RESPONSE_SETMODE:
Dean Anderson14d96262008-08-25 13:58:55 -03002112 /* check if channel valid */
2113 /* set mode ready */
2114 dev->setmode_ready[cc] = 1;
2115 wake_up(&dev->wait_setmode[cc]);
2116 dprintk(5, "setmode ready %d\n", cc);
2117 break;
Dean Andersonabce21f2009-04-23 16:04:41 -03002118 case S2255_RESPONSE_FW:
Dean Anderson14d96262008-08-25 13:58:55 -03002119
2120 dev->chn_ready |= (1 << cc);
2121 if ((dev->chn_ready & 0x0f) != 0x0f)
2122 break;
2123 /* all channels ready */
2124 printk(KERN_INFO "s2255: fw loaded\n");
2125 atomic_set(&dev->fw_data->fw_state,
2126 S2255_FW_SUCCESS);
2127 wake_up(&dev->fw_data->wait_fw);
2128 break;
Dean Anderson4de39f52010-03-03 19:39:19 -03002129 case S2255_RESPONSE_STATUS:
2130 dev->vidstatus[cc] = pdword[3];
2131 dev->vidstatus_ready[cc] = 1;
2132 wake_up(&dev->wait_vidstatus[cc]);
2133 dprintk(5, "got vidstatus %x chan %d\n",
2134 pdword[3], cc);
2135 break;
Dean Anderson14d96262008-08-25 13:58:55 -03002136 default:
André Goddard Rosaaf901ca2009-11-14 13:09:05 -02002137 printk(KERN_INFO "s2255 unknown resp\n");
Dean Anderson14d96262008-08-25 13:58:55 -03002138 }
2139 default:
2140 pdata++;
2141 break;
2142 }
2143 if (bframe)
2144 break;
2145 } /* for */
2146 if (!bframe)
2147 return -EINVAL;
2148 }
2149
2150
2151 idx = dev->cur_frame[dev->cc];
2152 frm = &dev->buffer[dev->cc].frame[idx];
2153
2154 /* search done. now find out if should be acquiring on this channel */
2155 if (!dev->b_acquire[dev->cc]) {
2156 /* we found a frame, but this channel is turned off */
2157 frm->ulState = S2255_READ_IDLE;
2158 return -EINVAL;
2159 }
2160
2161 if (frm->ulState == S2255_READ_IDLE) {
2162 frm->ulState = S2255_READ_FRAME;
Dean Anderson38f993a2008-06-26 23:15:51 -03002163 frm->cur_size = 0;
2164 }
2165
Dean Anderson14d96262008-08-25 13:58:55 -03002166 /* skip the marker 512 bytes (and offset if out of sync) */
2167 psrc = (u8 *)pipe_info->transfer_buffer + offset;
2168
Dean Anderson38f993a2008-06-26 23:15:51 -03002169
2170 if (frm->lpvbits == NULL) {
2171 dprintk(1, "s2255 frame buffer == NULL.%p %p %d %d",
2172 frm, dev, dev->cc, idx);
2173 return -ENOMEM;
2174 }
2175
2176 pdest = frm->lpvbits + frm->cur_size;
2177
Dean Anderson14d96262008-08-25 13:58:55 -03002178 copy_size = (pipe_info->cur_transfer_size - offset);
Dean Anderson38f993a2008-06-26 23:15:51 -03002179
Dean Anderson14d96262008-08-25 13:58:55 -03002180 size = dev->pkt_size[dev->cc] - PREFIX_SIZE;
Dean Anderson38f993a2008-06-26 23:15:51 -03002181
Dean Anderson14d96262008-08-25 13:58:55 -03002182 /* sanity check on pdest */
2183 if ((copy_size + frm->cur_size) < dev->req_image_size[dev->cc])
2184 memcpy(pdest, psrc, copy_size);
Dean Anderson38f993a2008-06-26 23:15:51 -03002185
Dean Anderson38f993a2008-06-26 23:15:51 -03002186 frm->cur_size += copy_size;
Dean Anderson14d96262008-08-25 13:58:55 -03002187 dprintk(4, "cur_size size %lu size %lu \n", frm->cur_size, size);
Dean Anderson38f993a2008-06-26 23:15:51 -03002188
Dean Anderson14d96262008-08-25 13:58:55 -03002189 if (frm->cur_size >= size) {
2190
Dean Anderson38f993a2008-06-26 23:15:51 -03002191 u32 cc = dev->cc;
Dean Anderson38f993a2008-06-26 23:15:51 -03002192 dprintk(2, "****************[%d]Buffer[%d]full*************\n",
2193 cc, idx);
2194 dev->last_frame[cc] = dev->cur_frame[cc];
2195 dev->cur_frame[cc]++;
2196 /* end of system frame ring buffer, start at zero */
2197 if ((dev->cur_frame[cc] == SYS_FRAMES) ||
2198 (dev->cur_frame[cc] == dev->buffer[cc].dwFrames))
2199 dev->cur_frame[cc] = 0;
Dean Anderson14d96262008-08-25 13:58:55 -03002200 /* frame ready */
Dean Anderson38f993a2008-06-26 23:15:51 -03002201 if (dev->b_acquire[cc])
Dean Anderson14d96262008-08-25 13:58:55 -03002202 s2255_got_frame(dev, cc, dev->jpg_size[cc]);
Dean Anderson38f993a2008-06-26 23:15:51 -03002203 dev->frame_count[cc]++;
Dean Anderson14d96262008-08-25 13:58:55 -03002204 frm->ulState = S2255_READ_IDLE;
2205 frm->cur_size = 0;
2206
Dean Anderson38f993a2008-06-26 23:15:51 -03002207 }
2208 /* done successfully */
2209 return 0;
2210}
2211
2212static void s2255_read_video_callback(struct s2255_dev *dev,
2213 struct s2255_pipeinfo *pipe_info)
2214{
2215 int res;
2216 dprintk(50, "callback read video \n");
2217
2218 if (dev->cc >= MAX_CHANNELS) {
2219 dev->cc = 0;
2220 dev_err(&dev->udev->dev, "invalid channel\n");
2221 return;
2222 }
2223 /* otherwise copy to the system buffers */
2224 res = save_frame(dev, pipe_info);
Dean Anderson14d96262008-08-25 13:58:55 -03002225 if (res != 0)
2226 dprintk(4, "s2255: read callback failed\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03002227
2228 dprintk(50, "callback read video done\n");
2229 return;
2230}
2231
2232static long s2255_vendor_req(struct s2255_dev *dev, unsigned char Request,
2233 u16 Index, u16 Value, void *TransferBuffer,
2234 s32 TransferBufferLength, int bOut)
2235{
2236 int r;
2237 if (!bOut) {
2238 r = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0),
2239 Request,
2240 USB_TYPE_VENDOR | USB_RECIP_DEVICE |
2241 USB_DIR_IN,
2242 Value, Index, TransferBuffer,
2243 TransferBufferLength, HZ * 5);
2244 } else {
2245 r = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0),
2246 Request, USB_TYPE_VENDOR | USB_RECIP_DEVICE,
2247 Value, Index, TransferBuffer,
2248 TransferBufferLength, HZ * 5);
2249 }
2250 return r;
2251}
2252
2253/*
2254 * retrieve FX2 firmware version. future use.
2255 * @param dev pointer to device extension
2256 * @return -1 for fail, else returns firmware version as an int(16 bits)
2257 */
2258static int s2255_get_fx2fw(struct s2255_dev *dev)
2259{
2260 int fw;
2261 int ret;
2262 unsigned char transBuffer[64];
2263 ret = s2255_vendor_req(dev, S2255_VR_FW, 0, 0, transBuffer, 2,
2264 S2255_VR_IN);
2265 if (ret < 0)
2266 dprintk(2, "get fw error: %x\n", ret);
2267 fw = transBuffer[0] + (transBuffer[1] << 8);
2268 dprintk(2, "Get FW %x %x\n", transBuffer[0], transBuffer[1]);
2269 return fw;
2270}
2271
2272/*
2273 * Create the system ring buffer to copy frames into from the
2274 * usb read pipe.
2275 */
2276static int s2255_create_sys_buffers(struct s2255_dev *dev, unsigned long chn)
2277{
2278 unsigned long i;
2279 unsigned long reqsize;
2280 dprintk(1, "create sys buffers\n");
2281 if (chn >= MAX_CHANNELS)
2282 return -1;
2283
2284 dev->buffer[chn].dwFrames = SYS_FRAMES;
2285
2286 /* always allocate maximum size(PAL) for system buffers */
2287 reqsize = SYS_FRAMES_MAXSIZE;
2288
2289 if (reqsize > SYS_FRAMES_MAXSIZE)
2290 reqsize = SYS_FRAMES_MAXSIZE;
2291
2292 for (i = 0; i < SYS_FRAMES; i++) {
2293 /* allocate the frames */
2294 dev->buffer[chn].frame[i].lpvbits = vmalloc(reqsize);
2295
2296 dprintk(1, "valloc %p chan %lu, idx %lu, pdata %p\n",
2297 &dev->buffer[chn].frame[i], chn, i,
2298 dev->buffer[chn].frame[i].lpvbits);
2299 dev->buffer[chn].frame[i].size = reqsize;
2300 if (dev->buffer[chn].frame[i].lpvbits == NULL) {
2301 printk(KERN_INFO "out of memory. using less frames\n");
2302 dev->buffer[chn].dwFrames = i;
2303 break;
2304 }
2305 }
2306
2307 /* make sure internal states are set */
2308 for (i = 0; i < SYS_FRAMES; i++) {
2309 dev->buffer[chn].frame[i].ulState = 0;
2310 dev->buffer[chn].frame[i].cur_size = 0;
2311 }
2312
2313 dev->cur_frame[chn] = 0;
2314 dev->last_frame[chn] = -1;
2315 return 0;
2316}
2317
2318static int s2255_release_sys_buffers(struct s2255_dev *dev,
2319 unsigned long channel)
2320{
2321 unsigned long i;
2322 dprintk(1, "release sys buffers\n");
2323 for (i = 0; i < SYS_FRAMES; i++) {
2324 if (dev->buffer[channel].frame[i].lpvbits) {
2325 dprintk(1, "vfree %p\n",
2326 dev->buffer[channel].frame[i].lpvbits);
2327 vfree(dev->buffer[channel].frame[i].lpvbits);
2328 }
2329 dev->buffer[channel].frame[i].lpvbits = NULL;
2330 }
2331 return 0;
2332}
2333
2334static int s2255_board_init(struct s2255_dev *dev)
2335{
Dean Anderson38f993a2008-06-26 23:15:51 -03002336 struct s2255_mode mode_def = DEF_MODEI_NTSC_CONT;
2337 int fw_ver;
Dean Andersonab85c6a2010-04-08 23:39:12 -03002338 int j;
2339 struct s2255_pipeinfo *pipe = &dev->pipe;
Dean Anderson38f993a2008-06-26 23:15:51 -03002340 dprintk(4, "board init: %p", dev);
Dean Andersonab85c6a2010-04-08 23:39:12 -03002341 memset(pipe, 0, sizeof(*pipe));
2342 pipe->dev = dev;
2343 pipe->cur_transfer_size = S2255_USB_XFER_SIZE;
2344 pipe->max_transfer_size = S2255_USB_XFER_SIZE;
Dean Anderson38f993a2008-06-26 23:15:51 -03002345
Dean Andersonab85c6a2010-04-08 23:39:12 -03002346 pipe->transfer_buffer = kzalloc(pipe->max_transfer_size,
2347 GFP_KERNEL);
2348 if (pipe->transfer_buffer == NULL) {
2349 dprintk(1, "out of memory!\n");
2350 return -ENOMEM;
Dean Anderson38f993a2008-06-26 23:15:51 -03002351 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002352 /* query the firmware */
2353 fw_ver = s2255_get_fx2fw(dev);
2354
Dean Andersonabce21f2009-04-23 16:04:41 -03002355 printk(KERN_INFO "2255 usb firmware version %d.%d\n",
2356 (fw_ver >> 8) & 0xff,
2357 fw_ver & 0xff);
2358
2359 if (fw_ver < S2255_CUR_USB_FWVER)
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002360 dev_err(&dev->udev->dev,
Dean Andersonabce21f2009-04-23 16:04:41 -03002361 "usb firmware not up to date %d.%d\n",
2362 (fw_ver >> 8) & 0xff,
2363 fw_ver & 0xff);
Dean Anderson38f993a2008-06-26 23:15:51 -03002364
2365 for (j = 0; j < MAX_CHANNELS; j++) {
2366 dev->b_acquire[j] = 0;
2367 dev->mode[j] = mode_def;
Dean Anderson5a34d9d2010-03-05 19:59:48 -03002368 if (dev->pid == 0x2257 && j > 1)
2369 dev->mode[j].color |= (1 << 16);
Dean Anderson22b88d42008-08-29 15:33:19 -03002370 dev->jc[j].quality = S2255_DEF_JPEG_QUAL;
Dean Anderson38f993a2008-06-26 23:15:51 -03002371 dev->cur_fmt[j] = &formats[0];
2372 dev->mode[j].restart = 1;
2373 dev->req_image_size[j] = get_transfer_size(&mode_def);
2374 dev->frame_count[j] = 0;
2375 /* create the system buffers */
2376 s2255_create_sys_buffers(dev, j);
2377 }
2378 /* start read pipe */
2379 s2255_start_readpipe(dev);
2380
2381 dprintk(1, "S2255: board initialized\n");
2382 return 0;
2383}
2384
2385static int s2255_board_shutdown(struct s2255_dev *dev)
2386{
2387 u32 i;
Dean Anderson38f993a2008-06-26 23:15:51 -03002388 dprintk(1, "S2255: board shutdown: %p", dev);
2389
2390 for (i = 0; i < MAX_CHANNELS; i++) {
2391 if (dev->b_acquire[i])
2392 s2255_stop_acquire(dev, i);
2393 }
2394
2395 s2255_stop_readpipe(dev);
2396
2397 for (i = 0; i < MAX_CHANNELS; i++)
2398 s2255_release_sys_buffers(dev, i);
Dean Andersonab85c6a2010-04-08 23:39:12 -03002399 /* release transfer buffer */
2400 kfree(dev->pipe.transfer_buffer);
Dean Anderson38f993a2008-06-26 23:15:51 -03002401 return 0;
2402}
2403
2404static void read_pipe_completion(struct urb *purb)
2405{
2406 struct s2255_pipeinfo *pipe_info;
2407 struct s2255_dev *dev;
2408 int status;
2409 int pipe;
2410
2411 pipe_info = purb->context;
2412 dprintk(100, "read pipe completion %p, status %d\n", purb,
2413 purb->status);
2414 if (pipe_info == NULL) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002415 dev_err(&purb->dev->dev, "no context!\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03002416 return;
2417 }
2418
2419 dev = pipe_info->dev;
2420 if (dev == NULL) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002421 dev_err(&purb->dev->dev, "no context!\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03002422 return;
2423 }
2424 status = purb->status;
Dean Andersonb02064c2009-04-30 12:29:38 -03002425 /* if shutting down, do not resubmit, exit immediately */
2426 if (status == -ESHUTDOWN) {
2427 dprintk(2, "read_pipe_completion: err shutdown\n");
2428 pipe_info->err_count++;
Dean Anderson38f993a2008-06-26 23:15:51 -03002429 return;
2430 }
2431
2432 if (pipe_info->state == 0) {
2433 dprintk(2, "exiting USB pipe");
2434 return;
2435 }
2436
Dean Andersonb02064c2009-04-30 12:29:38 -03002437 if (status == 0)
2438 s2255_read_video_callback(dev, pipe_info);
2439 else {
2440 pipe_info->err_count++;
2441 dprintk(1, "s2255drv: failed URB %d\n", status);
2442 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002443
Dean Anderson38f993a2008-06-26 23:15:51 -03002444 pipe = usb_rcvbulkpipe(dev->udev, dev->read_endpoint);
2445 /* reuse urb */
2446 usb_fill_bulk_urb(pipe_info->stream_urb, dev->udev,
2447 pipe,
2448 pipe_info->transfer_buffer,
2449 pipe_info->cur_transfer_size,
2450 read_pipe_completion, pipe_info);
2451
2452 if (pipe_info->state != 0) {
2453 if (usb_submit_urb(pipe_info->stream_urb, GFP_KERNEL)) {
2454 dev_err(&dev->udev->dev, "error submitting urb\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03002455 }
2456 } else {
2457 dprintk(2, "read pipe complete state 0\n");
2458 }
2459 return;
2460}
2461
2462static int s2255_start_readpipe(struct s2255_dev *dev)
2463{
2464 int pipe;
2465 int retval;
Dean Andersonab85c6a2010-04-08 23:39:12 -03002466 struct s2255_pipeinfo *pipe_info = &dev->pipe;
Dean Anderson38f993a2008-06-26 23:15:51 -03002467 pipe = usb_rcvbulkpipe(dev->udev, dev->read_endpoint);
2468 dprintk(2, "start pipe IN %d\n", dev->read_endpoint);
Dean Andersonab85c6a2010-04-08 23:39:12 -03002469 pipe_info->state = 1;
2470 pipe_info->err_count = 0;
2471 pipe_info->stream_urb = usb_alloc_urb(0, GFP_KERNEL);
2472 if (!pipe_info->stream_urb) {
2473 dev_err(&dev->udev->dev,
2474 "ReadStream: Unable to alloc URB\n");
2475 return -ENOMEM;
Dean Anderson38f993a2008-06-26 23:15:51 -03002476 }
Dean Andersonab85c6a2010-04-08 23:39:12 -03002477 /* transfer buffer allocated in board_init */
2478 usb_fill_bulk_urb(pipe_info->stream_urb, dev->udev,
2479 pipe,
2480 pipe_info->transfer_buffer,
2481 pipe_info->cur_transfer_size,
2482 read_pipe_completion, pipe_info);
Dean Anderson38f993a2008-06-26 23:15:51 -03002483
Dean Andersonab85c6a2010-04-08 23:39:12 -03002484 dprintk(4, "submitting URB %p\n", pipe_info->stream_urb);
2485 retval = usb_submit_urb(pipe_info->stream_urb, GFP_KERNEL);
2486 if (retval) {
2487 printk(KERN_ERR "s2255: start read pipe failed\n");
2488 return retval;
2489 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002490 return 0;
2491}
2492
2493/* starts acquisition process */
2494static int s2255_start_acquire(struct s2255_dev *dev, unsigned long chn)
2495{
2496 unsigned char *buffer;
2497 int res;
2498 unsigned long chn_rev;
2499 int j;
2500 if (chn >= MAX_CHANNELS) {
2501 dprintk(2, "start acquire failed, bad channel %lu\n", chn);
2502 return -1;
2503 }
2504
2505 chn_rev = G_chnmap[chn];
2506 dprintk(1, "S2255: start acquire %lu \n", chn);
2507
2508 buffer = kzalloc(512, GFP_KERNEL);
2509 if (buffer == NULL) {
2510 dev_err(&dev->udev->dev, "out of mem\n");
2511 return -ENOMEM;
2512 }
2513
2514 dev->last_frame[chn] = -1;
2515 dev->bad_payload[chn] = 0;
2516 dev->cur_frame[chn] = 0;
2517 for (j = 0; j < SYS_FRAMES; j++) {
2518 dev->buffer[chn].frame[j].ulState = 0;
2519 dev->buffer[chn].frame[j].cur_size = 0;
2520 }
2521
2522 /* send the start command */
Dean Anderson3fa00602010-03-04 20:47:33 -03002523 *(__le32 *) buffer = IN_DATA_TOKEN;
2524 *((__le32 *) buffer + 1) = (__le32) cpu_to_le32(chn_rev);
2525 *((__le32 *) buffer + 2) = CMD_START;
Dean Anderson38f993a2008-06-26 23:15:51 -03002526 res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
2527 if (res != 0)
2528 dev_err(&dev->udev->dev, "CMD_START error\n");
2529
2530 dprintk(2, "start acquire exit[%lu] %d \n", chn, res);
2531 kfree(buffer);
2532 return 0;
2533}
2534
2535static int s2255_stop_acquire(struct s2255_dev *dev, unsigned long chn)
2536{
2537 unsigned char *buffer;
2538 int res;
2539 unsigned long chn_rev;
Dean Anderson38f993a2008-06-26 23:15:51 -03002540 if (chn >= MAX_CHANNELS) {
2541 dprintk(2, "stop acquire failed, bad channel %lu\n", chn);
2542 return -1;
2543 }
2544 chn_rev = G_chnmap[chn];
Dean Anderson38f993a2008-06-26 23:15:51 -03002545 buffer = kzalloc(512, GFP_KERNEL);
2546 if (buffer == NULL) {
2547 dev_err(&dev->udev->dev, "out of mem\n");
2548 return -ENOMEM;
2549 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002550 /* send the stop command */
2551 dprintk(4, "stop acquire %lu\n", chn);
Dean Anderson3fa00602010-03-04 20:47:33 -03002552 *(__le32 *) buffer = IN_DATA_TOKEN;
2553 *((__le32 *) buffer + 1) = (__le32) cpu_to_le32(chn_rev);
2554 *((__le32 *) buffer + 2) = CMD_STOP;
Dean Anderson38f993a2008-06-26 23:15:51 -03002555 res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
2556
2557 if (res != 0)
2558 dev_err(&dev->udev->dev, "CMD_STOP error\n");
2559
2560 dprintk(4, "stop acquire: releasing states \n");
2561
2562 kfree(buffer);
2563 dev->b_acquire[chn] = 0;
2564
Dean Anderson14d96262008-08-25 13:58:55 -03002565 return res;
Dean Anderson38f993a2008-06-26 23:15:51 -03002566}
2567
2568static void s2255_stop_readpipe(struct s2255_dev *dev)
2569{
Dean Andersonab85c6a2010-04-08 23:39:12 -03002570 struct s2255_pipeinfo *pipe = &dev->pipe;
Dean Anderson38f993a2008-06-26 23:15:51 -03002571 if (dev == NULL) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002572 s2255_dev_err(&dev->udev->dev, "invalid device\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03002573 return;
2574 }
Dean Andersonab85c6a2010-04-08 23:39:12 -03002575 pipe->state = 0;
2576 if (pipe->stream_urb) {
2577 /* cancel urb */
2578 usb_kill_urb(pipe->stream_urb);
2579 usb_free_urb(pipe->stream_urb);
2580 pipe->stream_urb = NULL;
Dean Anderson38f993a2008-06-26 23:15:51 -03002581 }
Dean Andersonab85c6a2010-04-08 23:39:12 -03002582 dprintk(4, "%s", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03002583 return;
2584}
2585
Dean Anderson14d96262008-08-25 13:58:55 -03002586static void s2255_fwload_start(struct s2255_dev *dev, int reset)
Dean Anderson38f993a2008-06-26 23:15:51 -03002587{
Dean Anderson14d96262008-08-25 13:58:55 -03002588 if (reset)
2589 s2255_reset_dsppower(dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03002590 dev->fw_data->fw_size = dev->fw_data->fw->size;
2591 atomic_set(&dev->fw_data->fw_state, S2255_FW_NOTLOADED);
2592 memcpy(dev->fw_data->pfw_data,
2593 dev->fw_data->fw->data, CHUNK_SIZE);
2594 dev->fw_data->fw_loaded = CHUNK_SIZE;
2595 usb_fill_bulk_urb(dev->fw_data->fw_urb, dev->udev,
2596 usb_sndbulkpipe(dev->udev, 2),
2597 dev->fw_data->pfw_data,
2598 CHUNK_SIZE, s2255_fwchunk_complete,
2599 dev->fw_data);
2600 mod_timer(&dev->timer, jiffies + HZ);
2601}
2602
2603/* standard usb probe function */
2604static int s2255_probe(struct usb_interface *interface,
2605 const struct usb_device_id *id)
2606{
2607 struct s2255_dev *dev = NULL;
2608 struct usb_host_interface *iface_desc;
2609 struct usb_endpoint_descriptor *endpoint;
2610 int i;
2611 int retval = -ENOMEM;
Dean Anderson14d96262008-08-25 13:58:55 -03002612 __le32 *pdata;
2613 int fw_size;
Dean Anderson38f993a2008-06-26 23:15:51 -03002614
2615 dprintk(2, "s2255: probe\n");
2616
2617 /* allocate memory for our device state and initialize it to zero */
2618 dev = kzalloc(sizeof(struct s2255_dev), GFP_KERNEL);
2619 if (dev == NULL) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002620 s2255_dev_err(&interface->dev, "out of memory\n");
Dean Andersonff7e22d2010-04-08 23:38:07 -03002621 return -ENOMEM;
Dean Anderson38f993a2008-06-26 23:15:51 -03002622 }
Dean Andersonff7e22d2010-04-08 23:38:07 -03002623 kref_init(&dev->kref);
Dean Anderson5a34d9d2010-03-05 19:59:48 -03002624 dev->pid = id->idProduct;
Dean Anderson38f993a2008-06-26 23:15:51 -03002625 dev->fw_data = kzalloc(sizeof(struct s2255_fw), GFP_KERNEL);
2626 if (!dev->fw_data)
Dean Andersonff7e22d2010-04-08 23:38:07 -03002627 goto errorFWDATA1;
Dean Anderson38f993a2008-06-26 23:15:51 -03002628 mutex_init(&dev->lock);
2629 mutex_init(&dev->open_lock);
Dean Anderson38f993a2008-06-26 23:15:51 -03002630 /* grab usb_device and save it */
2631 dev->udev = usb_get_dev(interface_to_usbdev(interface));
2632 if (dev->udev == NULL) {
2633 dev_err(&interface->dev, "null usb device\n");
2634 retval = -ENODEV;
Dean Andersonff7e22d2010-04-08 23:38:07 -03002635 goto errorUDEV;
Dean Anderson38f993a2008-06-26 23:15:51 -03002636 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002637 dprintk(1, "dev: %p, kref: %p udev %p interface %p\n", dev, &dev->kref,
2638 dev->udev, interface);
2639 dev->interface = interface;
2640 /* set up the endpoint information */
2641 iface_desc = interface->cur_altsetting;
2642 dprintk(1, "num endpoints %d\n", iface_desc->desc.bNumEndpoints);
2643 for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
2644 endpoint = &iface_desc->endpoint[i].desc;
2645 if (!dev->read_endpoint && usb_endpoint_is_bulk_in(endpoint)) {
2646 /* we found the bulk in endpoint */
2647 dev->read_endpoint = endpoint->bEndpointAddress;
2648 }
2649 }
2650
2651 if (!dev->read_endpoint) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002652 dev_err(&interface->dev, "Could not find bulk-in endpoint\n");
Dean Andersonff7e22d2010-04-08 23:38:07 -03002653 goto errorEP;
Dean Anderson38f993a2008-06-26 23:15:51 -03002654 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002655 /* set intfdata */
2656 usb_set_intfdata(interface, dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03002657 dprintk(100, "after intfdata %p\n", dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03002658 init_timer(&dev->timer);
2659 dev->timer.function = s2255_timer;
2660 dev->timer.data = (unsigned long)dev->fw_data;
2661
2662 init_waitqueue_head(&dev->fw_data->wait_fw);
Dean Anderson4de39f52010-03-03 19:39:19 -03002663 for (i = 0; i < MAX_CHANNELS; i++) {
Dean Anderson14d96262008-08-25 13:58:55 -03002664 init_waitqueue_head(&dev->wait_setmode[i]);
Dean Anderson4de39f52010-03-03 19:39:19 -03002665 init_waitqueue_head(&dev->wait_vidstatus[i]);
2666 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002667
2668 dev->fw_data->fw_urb = usb_alloc_urb(0, GFP_KERNEL);
Dean Anderson38f993a2008-06-26 23:15:51 -03002669 if (!dev->fw_data->fw_urb) {
2670 dev_err(&interface->dev, "out of memory!\n");
Dean Andersonff7e22d2010-04-08 23:38:07 -03002671 goto errorFWURB;
Dean Anderson38f993a2008-06-26 23:15:51 -03002672 }
Dean Andersonff7e22d2010-04-08 23:38:07 -03002673
Dean Anderson38f993a2008-06-26 23:15:51 -03002674 dev->fw_data->pfw_data = kzalloc(CHUNK_SIZE, GFP_KERNEL);
2675 if (!dev->fw_data->pfw_data) {
2676 dev_err(&interface->dev, "out of memory!\n");
Dean Andersonff7e22d2010-04-08 23:38:07 -03002677 goto errorFWDATA2;
Dean Anderson38f993a2008-06-26 23:15:51 -03002678 }
2679 /* load the first chunk */
2680 if (request_firmware(&dev->fw_data->fw,
2681 FIRMWARE_FILE_NAME, &dev->udev->dev)) {
2682 printk(KERN_ERR "sensoray 2255 failed to get firmware\n");
Dean Andersonff7e22d2010-04-08 23:38:07 -03002683 goto errorREQFW;
Dean Anderson38f993a2008-06-26 23:15:51 -03002684 }
Dean Anderson14d96262008-08-25 13:58:55 -03002685 /* check the firmware is valid */
2686 fw_size = dev->fw_data->fw->size;
2687 pdata = (__le32 *) &dev->fw_data->fw->data[fw_size - 8];
Dean Anderson38f993a2008-06-26 23:15:51 -03002688
Dean Anderson14d96262008-08-25 13:58:55 -03002689 if (*pdata != S2255_FW_MARKER) {
2690 printk(KERN_INFO "Firmware invalid.\n");
2691 retval = -ENODEV;
Dean Andersonff7e22d2010-04-08 23:38:07 -03002692 goto errorFWMARKER;
Dean Anderson14d96262008-08-25 13:58:55 -03002693 } else {
2694 /* make sure firmware is the latest */
2695 __le32 *pRel;
2696 pRel = (__le32 *) &dev->fw_data->fw->data[fw_size - 4];
2697 printk(KERN_INFO "s2255 dsp fw version %x\n", *pRel);
Dean Anderson4de39f52010-03-03 19:39:19 -03002698 dev->dsp_fw_ver = *pRel;
2699 if (*pRel < S2255_CUR_DSP_FWVER)
2700 printk(KERN_INFO "s2255: f2255usb.bin out of date.\n");
Dean Anderson5a34d9d2010-03-05 19:59:48 -03002701 if (dev->pid == 0x2257 && *pRel < S2255_MIN_DSP_COLORFILTER)
Dean Andersonff7e22d2010-04-08 23:38:07 -03002702 printk(KERN_WARNING "s2255: 2257 requires firmware %d"
2703 "or above.\n", S2255_MIN_DSP_COLORFILTER);
Dean Anderson14d96262008-08-25 13:58:55 -03002704 }
Dean Anderson14d96262008-08-25 13:58:55 -03002705 usb_reset_device(dev->udev);
Dean Anderson38f993a2008-06-26 23:15:51 -03002706 /* load 2255 board specific */
Dean Andersonabce21f2009-04-23 16:04:41 -03002707 retval = s2255_board_init(dev);
2708 if (retval)
Dean Andersonff7e22d2010-04-08 23:38:07 -03002709 goto errorBOARDINIT;
Dean Anderson38f993a2008-06-26 23:15:51 -03002710 dprintk(4, "before probe done %p\n", dev);
2711 spin_lock_init(&dev->slock);
Dean Anderson14d96262008-08-25 13:58:55 -03002712 s2255_fwload_start(dev, 0);
Dean Andersonff7e22d2010-04-08 23:38:07 -03002713 /* kref for each vdev. Released on video_device_release callback */
2714 for (i = 0; i < MAX_CHANNELS; i++)
2715 kref_get(&dev->kref);
2716 /* loads v4l specific */
2717 retval = s2255_probe_v4l(dev);
2718 if (retval)
2719 goto errorV4L;
Dean Anderson38f993a2008-06-26 23:15:51 -03002720 dev_info(&interface->dev, "Sensoray 2255 detected\n");
2721 return 0;
Dean Andersonff7e22d2010-04-08 23:38:07 -03002722errorV4L:
2723 for (i = 0; i < MAX_CHANNELS; i++)
2724 if (dev->vdev[i] && video_is_registered(dev->vdev[i]))
2725 video_unregister_device(dev->vdev[i]);
2726errorBOARDINIT:
2727 s2255_board_shutdown(dev);
2728errorFWMARKER:
2729 release_firmware(dev->fw_data->fw);
2730errorREQFW:
2731 kfree(dev->fw_data->pfw_data);
2732errorFWDATA2:
2733 usb_free_urb(dev->fw_data->fw_urb);
2734errorFWURB:
2735 del_timer(&dev->timer);
2736errorEP:
2737 usb_put_dev(dev->udev);
2738errorUDEV:
2739 kfree(dev->fw_data);
2740 mutex_destroy(&dev->open_lock);
2741 mutex_destroy(&dev->lock);
2742errorFWDATA1:
2743 kfree(dev);
2744 printk(KERN_WARNING "Sensoray 2255 driver load failed: 0x%x\n", retval);
Dean Anderson38f993a2008-06-26 23:15:51 -03002745 return retval;
2746}
2747
Dean Andersonff7e22d2010-04-08 23:38:07 -03002748
Dean Anderson38f993a2008-06-26 23:15:51 -03002749/* disconnect routine. when board is removed physically or with rmmod */
2750static void s2255_disconnect(struct usb_interface *interface)
2751{
2752 struct s2255_dev *dev = NULL;
Dean Anderson14d96262008-08-25 13:58:55 -03002753 int i;
Dean Anderson38f993a2008-06-26 23:15:51 -03002754 dprintk(1, "s2255: disconnect interface %p\n", interface);
2755 dev = usb_get_intfdata(interface);
Dean Andersonff7e22d2010-04-08 23:38:07 -03002756 /* unregister each video device. */
2757 for (i = 0; i < MAX_CHANNELS; i++)
2758 if (video_is_registered(dev->vdev[i]))
2759 video_unregister_device(dev->vdev[i]);
2760 /* wake up any of our timers */
Dean Anderson14d96262008-08-25 13:58:55 -03002761 atomic_set(&dev->fw_data->fw_state, S2255_FW_DISCONNECTING);
2762 wake_up(&dev->fw_data->wait_fw);
2763 for (i = 0; i < MAX_CHANNELS; i++) {
2764 dev->setmode_ready[i] = 1;
2765 wake_up(&dev->wait_setmode[i]);
Dean Anderson4de39f52010-03-03 19:39:19 -03002766 dev->vidstatus_ready[i] = 1;
2767 wake_up(&dev->wait_vidstatus[i]);
Dean Anderson14d96262008-08-25 13:58:55 -03002768 }
Dean Anderson14d96262008-08-25 13:58:55 -03002769 usb_set_intfdata(interface, NULL);
Dean Andersonff7e22d2010-04-08 23:38:07 -03002770 kref_put(&dev->kref, s2255_destroy);
2771 dev_info(&interface->dev, "%s\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03002772}
2773
2774static struct usb_driver s2255_driver = {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002775 .name = S2255_DRIVER_NAME,
Dean Anderson38f993a2008-06-26 23:15:51 -03002776 .probe = s2255_probe,
2777 .disconnect = s2255_disconnect,
2778 .id_table = s2255_table,
2779};
2780
2781static int __init usb_s2255_init(void)
2782{
2783 int result;
Dean Anderson38f993a2008-06-26 23:15:51 -03002784 /* register this driver with the USB subsystem */
2785 result = usb_register(&s2255_driver);
Dean Anderson38f993a2008-06-26 23:15:51 -03002786 if (result)
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002787 pr_err(KBUILD_MODNAME
Dean Andersonff7e22d2010-04-08 23:38:07 -03002788 ": usb_register failed. Error number %d\n", result);
2789 dprintk(2, "%s\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03002790 return result;
2791}
2792
2793static void __exit usb_s2255_exit(void)
2794{
2795 usb_deregister(&s2255_driver);
2796}
2797
2798module_init(usb_s2255_init);
2799module_exit(usb_s2255_exit);
2800
2801MODULE_DESCRIPTION("Sensoray 2255 Video for Linux driver");
2802MODULE_AUTHOR("Dean Anderson (Sensoray Company Inc.)");
2803MODULE_LICENSE("GPL");