blob: 1d8c6b4364dd1e4e7ee1ed7e4a13d68be578cee5 [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
88#define MAX_PIPE_BUFFERS 1
89#define SYS_FRAMES 4
90/* maximum size is PAL full size plus room for the marker header(s) */
Dean Anderson14d96262008-08-25 13:58:55 -030091#define SYS_FRAMES_MAXSIZE (720*288*2*2 + 4096)
92#define DEF_USB_BLOCK S2255_USB_XFER_SIZE
Dean Anderson38f993a2008-06-26 23:15:51 -030093#define LINE_SZ_4CIFS_NTSC 640
94#define LINE_SZ_2CIFS_NTSC 640
95#define LINE_SZ_1CIFS_NTSC 320
96#define LINE_SZ_4CIFS_PAL 704
97#define LINE_SZ_2CIFS_PAL 704
98#define LINE_SZ_1CIFS_PAL 352
99#define NUM_LINES_4CIFS_NTSC 240
100#define NUM_LINES_2CIFS_NTSC 240
101#define NUM_LINES_1CIFS_NTSC 240
102#define NUM_LINES_4CIFS_PAL 288
103#define NUM_LINES_2CIFS_PAL 288
104#define NUM_LINES_1CIFS_PAL 288
105#define LINE_SZ_DEF 640
106#define NUM_LINES_DEF 240
107
108
109/* predefined settings */
110#define FORMAT_NTSC 1
111#define FORMAT_PAL 2
112
113#define SCALE_4CIFS 1 /* 640x480(NTSC) or 704x576(PAL) */
114#define SCALE_2CIFS 2 /* 640x240(NTSC) or 704x288(PAL) */
115#define SCALE_1CIFS 3 /* 320x240(NTSC) or 352x288(PAL) */
Dean Anderson7d853532009-05-15 14:32:04 -0300116/* SCALE_4CIFSI is the 2 fields interpolated into one */
117#define SCALE_4CIFSI 4 /* 640x480(NTSC) or 704x576(PAL) high quality */
Dean Anderson38f993a2008-06-26 23:15:51 -0300118
119#define COLOR_YUVPL 1 /* YUV planar */
120#define COLOR_YUVPK 2 /* YUV packed */
121#define COLOR_Y8 4 /* monochrome */
Dean Anderson14d96262008-08-25 13:58:55 -0300122#define COLOR_JPG 5 /* JPEG */
Dean Anderson38f993a2008-06-26 23:15:51 -0300123
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300124#define MASK_COLOR 0x000000ff
125#define MASK_JPG_QUALITY 0x0000ff00
126#define MASK_INPUT_TYPE 0x000f0000
Dean Anderson38f993a2008-06-26 23:15:51 -0300127/* frame decimation. Not implemented by V4L yet(experimental in V4L) */
128#define FDEC_1 1 /* capture every frame. default */
129#define FDEC_2 2 /* capture every 2nd frame */
130#define FDEC_3 3 /* capture every 3rd frame */
131#define FDEC_5 5 /* capture every 5th frame */
132
133/*-------------------------------------------------------
134 * Default mode parameters.
135 *-------------------------------------------------------*/
136#define DEF_SCALE SCALE_4CIFS
137#define DEF_COLOR COLOR_YUVPL
138#define DEF_FDEC FDEC_1
139#define DEF_BRIGHT 0
140#define DEF_CONTRAST 0x5c
141#define DEF_SATURATION 0x80
142#define DEF_HUE 0
143
144/* usb config commands */
Dean Anderson3fa00602010-03-04 20:47:33 -0300145#define IN_DATA_TOKEN cpu_to_le32(0x2255c0de)
146#define CMD_2255 cpu_to_le32(0xc2255000)
147#define CMD_SET_MODE cpu_to_le32((CMD_2255 | 0x10))
148#define CMD_START cpu_to_le32((CMD_2255 | 0x20))
149#define CMD_STOP cpu_to_le32((CMD_2255 | 0x30))
150#define CMD_STATUS cpu_to_le32((CMD_2255 | 0x40))
Dean Anderson38f993a2008-06-26 23:15:51 -0300151
152struct s2255_mode {
153 u32 format; /* input video format (NTSC, PAL) */
154 u32 scale; /* output video scale */
155 u32 color; /* output video color format */
156 u32 fdec; /* frame decimation */
157 u32 bright; /* brightness */
158 u32 contrast; /* contrast */
159 u32 saturation; /* saturation */
160 u32 hue; /* hue (NTSC only)*/
161 u32 single; /* capture 1 frame at a time (!=0), continuously (==0)*/
162 u32 usb_block; /* block size. should be 4096 of DEF_USB_BLOCK */
163 u32 restart; /* if DSP requires restart */
164};
165
Dean Anderson14d96262008-08-25 13:58:55 -0300166
167#define S2255_READ_IDLE 0
168#define S2255_READ_FRAME 1
169
Dean Anderson38f993a2008-06-26 23:15:51 -0300170/* frame structure */
Dean Anderson38f993a2008-06-26 23:15:51 -0300171struct s2255_framei {
172 unsigned long size;
Dean Anderson14d96262008-08-25 13:58:55 -0300173 unsigned long ulState; /* ulState:S2255_READ_IDLE, S2255_READ_FRAME*/
Dean Anderson38f993a2008-06-26 23:15:51 -0300174 void *lpvbits; /* image data */
175 unsigned long cur_size; /* current data copied to it */
176};
177
178/* image buffer structure */
179struct s2255_bufferi {
180 unsigned long dwFrames; /* number of frames in buffer */
181 struct s2255_framei frame[SYS_FRAMES]; /* array of FRAME structures */
182};
183
184#define DEF_MODEI_NTSC_CONT {FORMAT_NTSC, DEF_SCALE, DEF_COLOR, \
185 DEF_FDEC, DEF_BRIGHT, DEF_CONTRAST, DEF_SATURATION, \
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300186 DEF_HUE, 0, DEF_USB_BLOCK, 0}
Dean Anderson38f993a2008-06-26 23:15:51 -0300187
188struct s2255_dmaqueue {
189 struct list_head active;
Dean Anderson38f993a2008-06-26 23:15:51 -0300190 struct s2255_dev *dev;
191 int channel;
192};
193
194/* for firmware loading, fw_state */
195#define S2255_FW_NOTLOADED 0
196#define S2255_FW_LOADED_DSPWAIT 1
197#define S2255_FW_SUCCESS 2
198#define S2255_FW_FAILED 3
Dean Andersonf78d92c2008-07-22 14:43:27 -0300199#define S2255_FW_DISCONNECTING 4
Harvey Harrisondeaf53e2008-11-15 01:10:14 -0300200#define S2255_FW_MARKER cpu_to_le32(0x22552f2f)
Dean Anderson14d96262008-08-25 13:58:55 -0300201/* 2255 read states */
202#define S2255_READ_IDLE 0
203#define S2255_READ_FRAME 1
Dean Anderson38f993a2008-06-26 23:15:51 -0300204struct s2255_fw {
205 int fw_loaded;
206 int fw_size;
207 struct urb *fw_urb;
208 atomic_t fw_state;
209 void *pfw_data;
210 wait_queue_head_t wait_fw;
Dean Anderson38f993a2008-06-26 23:15:51 -0300211 const struct firmware *fw;
212};
213
214struct s2255_pipeinfo {
215 u32 max_transfer_size;
216 u32 cur_transfer_size;
217 u8 *transfer_buffer;
Dean Anderson38f993a2008-06-26 23:15:51 -0300218 u32 state;
Dean Anderson38f993a2008-06-26 23:15:51 -0300219 void *stream_urb;
220 void *dev; /* back pointer to s2255_dev struct*/
221 u32 err_count;
Dean Anderson38f993a2008-06-26 23:15:51 -0300222 u32 idx;
Dean Anderson38f993a2008-06-26 23:15:51 -0300223};
224
225struct s2255_fmt; /*forward declaration */
226
227struct s2255_dev {
228 int frames;
Dean Anderson38f993a2008-06-26 23:15:51 -0300229 struct mutex lock;
230 struct mutex open_lock;
231 int resources[MAX_CHANNELS];
232 struct usb_device *udev;
233 struct usb_interface *interface;
234 u8 read_endpoint;
235
236 struct s2255_dmaqueue vidq[MAX_CHANNELS];
237 struct video_device *vdev[MAX_CHANNELS];
Dean Anderson38f993a2008-06-26 23:15:51 -0300238 struct timer_list timer;
239 struct s2255_fw *fw_data;
Dean Anderson38f993a2008-06-26 23:15:51 -0300240 struct s2255_pipeinfo pipes[MAX_PIPE_BUFFERS];
241 struct s2255_bufferi buffer[MAX_CHANNELS];
242 struct s2255_mode mode[MAX_CHANNELS];
Dean Anderson22b88d42008-08-29 15:33:19 -0300243 /* jpeg compression */
244 struct v4l2_jpegcompression jc[MAX_CHANNELS];
Dean Anderson7d853532009-05-15 14:32:04 -0300245 /* capture parameters (for high quality mode full size) */
246 struct v4l2_captureparm cap_parm[MAX_CHANNELS];
Dean Anderson38f993a2008-06-26 23:15:51 -0300247 const struct s2255_fmt *cur_fmt[MAX_CHANNELS];
248 int cur_frame[MAX_CHANNELS];
249 int last_frame[MAX_CHANNELS];
250 u32 cc; /* current channel */
251 int b_acquire[MAX_CHANNELS];
Dean Anderson14d96262008-08-25 13:58:55 -0300252 /* allocated image size */
Dean Anderson38f993a2008-06-26 23:15:51 -0300253 unsigned long req_image_size[MAX_CHANNELS];
Dean Anderson14d96262008-08-25 13:58:55 -0300254 /* received packet size */
255 unsigned long pkt_size[MAX_CHANNELS];
Dean Anderson38f993a2008-06-26 23:15:51 -0300256 int bad_payload[MAX_CHANNELS];
257 unsigned long frame_count[MAX_CHANNELS];
258 int frame_ready;
Dean Anderson14d96262008-08-25 13:58:55 -0300259 /* if JPEG image */
260 int jpg_size[MAX_CHANNELS];
261 /* if channel configured to default state */
262 int chn_configured[MAX_CHANNELS];
263 wait_queue_head_t wait_setmode[MAX_CHANNELS];
264 int setmode_ready[MAX_CHANNELS];
Dean Anderson4de39f52010-03-03 19:39:19 -0300265 /* video status items */
266 int vidstatus[MAX_CHANNELS];
267 wait_queue_head_t wait_vidstatus[MAX_CHANNELS];
268 int vidstatus_ready[MAX_CHANNELS];
Dean Anderson14d96262008-08-25 13:58:55 -0300269 int chn_ready;
Dean Anderson38f993a2008-06-26 23:15:51 -0300270 spinlock_t slock;
Dean Anderson4de39f52010-03-03 19:39:19 -0300271 /* dsp firmware version (f2255usb.bin) */
272 int dsp_fw_ver;
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300273 u16 pid; /* product id */
274 struct kref kref;
Dean Anderson38f993a2008-06-26 23:15:51 -0300275};
276#define to_s2255_dev(d) container_of(d, struct s2255_dev, kref)
277
278struct s2255_fmt {
279 char *name;
280 u32 fourcc;
281 int depth;
282};
283
284/* buffer for one video frame */
285struct s2255_buffer {
286 /* common v4l buffer stuff -- must be first */
287 struct videobuf_buffer vb;
288 const struct s2255_fmt *fmt;
289};
290
291struct s2255_fh {
292 struct s2255_dev *dev;
Dean Anderson38f993a2008-06-26 23:15:51 -0300293 const struct s2255_fmt *fmt;
294 unsigned int width;
295 unsigned int height;
296 struct videobuf_queue vb_vidq;
297 enum v4l2_buf_type type;
298 int channel;
299 /* mode below is the desired mode.
300 mode in s2255_dev is the current mode that was last set */
301 struct s2255_mode mode;
Dean Andersonf78d92c2008-07-22 14:43:27 -0300302 int resources[MAX_CHANNELS];
Dean Anderson38f993a2008-06-26 23:15:51 -0300303};
304
Dean Andersonabce21f2009-04-23 16:04:41 -0300305/* current cypress EEPROM firmware version */
306#define S2255_CUR_USB_FWVER ((3 << 8) | 6)
Dean Anderson4de39f52010-03-03 19:39:19 -0300307/* current DSP FW version */
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300308#define S2255_CUR_DSP_FWVER 8
Dean Anderson4de39f52010-03-03 19:39:19 -0300309/* Need DSP version 5+ for video status feature */
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300310#define S2255_MIN_DSP_STATUS 5
311#define S2255_MIN_DSP_COLORFILTER 8
Dean Anderson38f993a2008-06-26 23:15:51 -0300312#define S2255_MAJOR_VERSION 1
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300313#define S2255_MINOR_VERSION 18
Dean Anderson38f993a2008-06-26 23:15:51 -0300314#define S2255_RELEASE 0
315#define S2255_VERSION KERNEL_VERSION(S2255_MAJOR_VERSION, \
316 S2255_MINOR_VERSION, \
317 S2255_RELEASE)
318
Dean Anderson38f993a2008-06-26 23:15:51 -0300319#define S2255_NORMS (V4L2_STD_PAL | V4L2_STD_NTSC)
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300320
321/* private V4L2 controls */
322
323/*
324 * The following chart displays how COLORFILTER should be set
325 * =========================================================
326 * = fourcc = COLORFILTER =
327 * = ===============================
328 * = = 0 = 1 =
329 * =========================================================
330 * = V4L2_PIX_FMT_GREY(Y8) = monochrome from = monochrome=
331 * = = s-video or = composite =
332 * = = B/W camera = input =
333 * =========================================================
334 * = other = color, svideo = color, =
335 * = = = composite =
336 * =========================================================
337 *
338 * Notes:
339 * channels 0-3 on 2255 are composite
340 * channels 0-1 on 2257 are composite, 2-3 are s-video
341 * If COLORFILTER is 0 with a composite color camera connected,
342 * the output will appear monochrome but hatching
343 * will occur.
344 * COLORFILTER is different from "color killer" and "color effects"
345 * for reasons above.
346 */
347#define S2255_V4L2_YC_ON 1
348#define S2255_V4L2_YC_OFF 0
349#define V4L2_CID_PRIVATE_COLORFILTER (V4L2_CID_PRIVATE_BASE + 0)
350
Dean Anderson38f993a2008-06-26 23:15:51 -0300351/* frame prefix size (sent once every frame) */
352#define PREFIX_SIZE 512
353
354/* Channels on box are in reverse order */
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300355static unsigned long G_chnmap[MAX_CHANNELS] = {3, 2, 1, 0};
Dean Anderson38f993a2008-06-26 23:15:51 -0300356
Dean Anderson38f993a2008-06-26 23:15:51 -0300357static int debug;
358static int *s2255_debug = &debug;
359
360static int s2255_start_readpipe(struct s2255_dev *dev);
361static void s2255_stop_readpipe(struct s2255_dev *dev);
362static int s2255_start_acquire(struct s2255_dev *dev, unsigned long chn);
363static int s2255_stop_acquire(struct s2255_dev *dev, unsigned long chn);
364static void s2255_fillbuff(struct s2255_dev *dev, struct s2255_buffer *buf,
Dean Anderson14d96262008-08-25 13:58:55 -0300365 int chn, int jpgsize);
Dean Anderson38f993a2008-06-26 23:15:51 -0300366static int s2255_set_mode(struct s2255_dev *dev, unsigned long chn,
367 struct s2255_mode *mode);
368static int s2255_board_shutdown(struct s2255_dev *dev);
Dean Anderson14d96262008-08-25 13:58:55 -0300369static void s2255_fwload_start(struct s2255_dev *dev, int reset);
370static void s2255_destroy(struct kref *kref);
371static long s2255_vendor_req(struct s2255_dev *dev, unsigned char req,
372 u16 index, u16 value, void *buf,
373 s32 buf_len, int bOut);
Dean Anderson38f993a2008-06-26 23:15:51 -0300374
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -0300375/* dev_err macro with driver name */
376#define S2255_DRIVER_NAME "s2255"
377#define s2255_dev_err(dev, fmt, arg...) \
378 dev_err(dev, S2255_DRIVER_NAME " - " fmt, ##arg)
379
Dean Anderson38f993a2008-06-26 23:15:51 -0300380#define dprintk(level, fmt, arg...) \
381 do { \
382 if (*s2255_debug >= (level)) { \
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -0300383 printk(KERN_DEBUG S2255_DRIVER_NAME \
384 ": " fmt, ##arg); \
Dean Anderson38f993a2008-06-26 23:15:51 -0300385 } \
386 } while (0)
387
Dean Anderson38f993a2008-06-26 23:15:51 -0300388static struct usb_driver s2255_driver;
389
Dean Anderson38f993a2008-06-26 23:15:51 -0300390/* Declare static vars that will be used as parameters */
391static unsigned int vid_limit = 16; /* Video memory limit, in Mb */
392
393/* start video number */
394static int video_nr = -1; /* /dev/videoN, -1 for autodetect */
395
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300396module_param(debug, int, 0644);
Dean Anderson38f993a2008-06-26 23:15:51 -0300397MODULE_PARM_DESC(debug, "Debug level(0-100) default 0");
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300398module_param(vid_limit, int, 0644);
Dean Anderson38f993a2008-06-26 23:15:51 -0300399MODULE_PARM_DESC(vid_limit, "video memory limit(Mb)");
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300400module_param(video_nr, int, 0644);
Dean Anderson38f993a2008-06-26 23:15:51 -0300401MODULE_PARM_DESC(video_nr, "start video minor(-1 default autodetect)");
402
403/* USB device table */
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300404#define USB_SENSORAY_VID 0x1943
Dean Anderson38f993a2008-06-26 23:15:51 -0300405static struct usb_device_id s2255_table[] = {
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300406 {USB_DEVICE(USB_SENSORAY_VID, 0x2255)},
407 {USB_DEVICE(USB_SENSORAY_VID, 0x2257)}, /*same family as 2255*/
Dean Anderson38f993a2008-06-26 23:15:51 -0300408 { } /* Terminating entry */
409};
410MODULE_DEVICE_TABLE(usb, s2255_table);
411
Dean Anderson38f993a2008-06-26 23:15:51 -0300412#define BUFFER_TIMEOUT msecs_to_jiffies(400)
413
Dean Anderson38f993a2008-06-26 23:15:51 -0300414/* image formats. */
415static const struct s2255_fmt formats[] = {
416 {
417 .name = "4:2:2, planar, YUV422P",
418 .fourcc = V4L2_PIX_FMT_YUV422P,
419 .depth = 16
420
421 }, {
422 .name = "4:2:2, packed, YUYV",
423 .fourcc = V4L2_PIX_FMT_YUYV,
424 .depth = 16
425
426 }, {
427 .name = "4:2:2, packed, UYVY",
428 .fourcc = V4L2_PIX_FMT_UYVY,
429 .depth = 16
430 }, {
Dean Anderson14d96262008-08-25 13:58:55 -0300431 .name = "JPG",
432 .fourcc = V4L2_PIX_FMT_JPEG,
433 .depth = 24
434 }, {
Dean Anderson38f993a2008-06-26 23:15:51 -0300435 .name = "8bpp GREY",
436 .fourcc = V4L2_PIX_FMT_GREY,
437 .depth = 8
438 }
439};
440
441static int norm_maxw(struct video_device *vdev)
442{
443 return (vdev->current_norm & V4L2_STD_NTSC) ?
444 LINE_SZ_4CIFS_NTSC : LINE_SZ_4CIFS_PAL;
445}
446
447static int norm_maxh(struct video_device *vdev)
448{
449 return (vdev->current_norm & V4L2_STD_NTSC) ?
450 (NUM_LINES_1CIFS_NTSC * 2) : (NUM_LINES_1CIFS_PAL * 2);
451}
452
453static int norm_minw(struct video_device *vdev)
454{
455 return (vdev->current_norm & V4L2_STD_NTSC) ?
456 LINE_SZ_1CIFS_NTSC : LINE_SZ_1CIFS_PAL;
457}
458
459static int norm_minh(struct video_device *vdev)
460{
461 return (vdev->current_norm & V4L2_STD_NTSC) ?
462 (NUM_LINES_1CIFS_NTSC) : (NUM_LINES_1CIFS_PAL);
463}
464
465
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300466/*
467 * TODO: fixme: move YUV reordering to hardware
468 * converts 2255 planar format to yuyv or uyvy
469 */
Dean Anderson38f993a2008-06-26 23:15:51 -0300470static void planar422p_to_yuv_packed(const unsigned char *in,
471 unsigned char *out,
472 int width, int height,
473 int fmt)
474{
475 unsigned char *pY;
476 unsigned char *pCb;
477 unsigned char *pCr;
478 unsigned long size = height * width;
479 unsigned int i;
480 pY = (unsigned char *)in;
481 pCr = (unsigned char *)in + height * width;
482 pCb = (unsigned char *)in + height * width + (height * width / 2);
483 for (i = 0; i < size * 2; i += 4) {
484 out[i] = (fmt == V4L2_PIX_FMT_YUYV) ? *pY++ : *pCr++;
485 out[i + 1] = (fmt == V4L2_PIX_FMT_YUYV) ? *pCr++ : *pY++;
486 out[i + 2] = (fmt == V4L2_PIX_FMT_YUYV) ? *pY++ : *pCb++;
487 out[i + 3] = (fmt == V4L2_PIX_FMT_YUYV) ? *pCb++ : *pY++;
488 }
489 return;
490}
491
Hans Verkuild45b9b82008-09-04 03:33:43 -0300492static void s2255_reset_dsppower(struct s2255_dev *dev)
Dean Anderson14d96262008-08-25 13:58:55 -0300493{
494 s2255_vendor_req(dev, 0x40, 0x0b0b, 0x0b0b, NULL, 0, 1);
495 msleep(10);
496 s2255_vendor_req(dev, 0x50, 0x0000, 0x0000, NULL, 0, 1);
497 return;
498}
Dean Anderson38f993a2008-06-26 23:15:51 -0300499
500/* kickstarts the firmware loading. from probe
501 */
502static void s2255_timer(unsigned long user_data)
503{
504 struct s2255_fw *data = (struct s2255_fw *)user_data;
505 dprintk(100, "s2255 timer\n");
506 if (usb_submit_urb(data->fw_urb, GFP_ATOMIC) < 0) {
507 printk(KERN_ERR "s2255: can't submit urb\n");
Dean Andersonf78d92c2008-07-22 14:43:27 -0300508 atomic_set(&data->fw_state, S2255_FW_FAILED);
509 /* wake up anything waiting for the firmware */
510 wake_up(&data->wait_fw);
Dean Anderson38f993a2008-06-26 23:15:51 -0300511 return;
512 }
513}
514
Dean Anderson38f993a2008-06-26 23:15:51 -0300515
516/* this loads the firmware asynchronously.
517 Originally this was done synchroously in probe.
518 But it is better to load it asynchronously here than block
519 inside the probe function. Blocking inside probe affects boot time.
520 FW loading is triggered by the timer in the probe function
521*/
522static void s2255_fwchunk_complete(struct urb *urb)
523{
524 struct s2255_fw *data = urb->context;
525 struct usb_device *udev = urb->dev;
526 int len;
527 dprintk(100, "udev %p urb %p", udev, urb);
Dean Anderson38f993a2008-06-26 23:15:51 -0300528 if (urb->status) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -0300529 dev_err(&udev->dev, "URB failed with status %d\n", urb->status);
Dean Andersonf78d92c2008-07-22 14:43:27 -0300530 atomic_set(&data->fw_state, S2255_FW_FAILED);
531 /* wake up anything waiting for the firmware */
532 wake_up(&data->wait_fw);
Dean Anderson38f993a2008-06-26 23:15:51 -0300533 return;
534 }
535 if (data->fw_urb == NULL) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -0300536 s2255_dev_err(&udev->dev, "disconnected\n");
Dean Andersonf78d92c2008-07-22 14:43:27 -0300537 atomic_set(&data->fw_state, S2255_FW_FAILED);
538 /* wake up anything waiting for the firmware */
539 wake_up(&data->wait_fw);
Dean Anderson38f993a2008-06-26 23:15:51 -0300540 return;
541 }
542#define CHUNK_SIZE 512
543 /* all USB transfers must be done with continuous kernel memory.
544 can't allocate more than 128k in current linux kernel, so
545 upload the firmware in chunks
546 */
547 if (data->fw_loaded < data->fw_size) {
548 len = (data->fw_loaded + CHUNK_SIZE) > data->fw_size ?
549 data->fw_size % CHUNK_SIZE : CHUNK_SIZE;
550
551 if (len < CHUNK_SIZE)
552 memset(data->pfw_data, 0, CHUNK_SIZE);
553
554 dprintk(100, "completed len %d, loaded %d \n", len,
555 data->fw_loaded);
556
557 memcpy(data->pfw_data,
558 (char *) data->fw->data + data->fw_loaded, len);
559
560 usb_fill_bulk_urb(data->fw_urb, udev, usb_sndbulkpipe(udev, 2),
561 data->pfw_data, CHUNK_SIZE,
562 s2255_fwchunk_complete, data);
563 if (usb_submit_urb(data->fw_urb, GFP_ATOMIC) < 0) {
564 dev_err(&udev->dev, "failed submit URB\n");
565 atomic_set(&data->fw_state, S2255_FW_FAILED);
566 /* wake up anything waiting for the firmware */
567 wake_up(&data->wait_fw);
568 return;
569 }
570 data->fw_loaded += len;
571 } else {
Dean Anderson38f993a2008-06-26 23:15:51 -0300572 atomic_set(&data->fw_state, S2255_FW_LOADED_DSPWAIT);
Dean Anderson38f993a2008-06-26 23:15:51 -0300573 }
574 dprintk(100, "2255 complete done\n");
575 return;
576
577}
578
Dean Anderson14d96262008-08-25 13:58:55 -0300579static int s2255_got_frame(struct s2255_dev *dev, int chn, int jpgsize)
Dean Anderson38f993a2008-06-26 23:15:51 -0300580{
581 struct s2255_dmaqueue *dma_q = &dev->vidq[chn];
582 struct s2255_buffer *buf;
583 unsigned long flags = 0;
584 int rc = 0;
585 dprintk(2, "wakeup: %p channel: %d\n", &dma_q, chn);
586 spin_lock_irqsave(&dev->slock, flags);
587
588 if (list_empty(&dma_q->active)) {
589 dprintk(1, "No active queue to serve\n");
590 rc = -1;
591 goto unlock;
592 }
593 buf = list_entry(dma_q->active.next,
594 struct s2255_buffer, vb.queue);
595
Dean Anderson38f993a2008-06-26 23:15:51 -0300596 list_del(&buf->vb.queue);
597 do_gettimeofday(&buf->vb.ts);
598 dprintk(100, "[%p/%d] wakeup\n", buf, buf->vb.i);
Dean Anderson14d96262008-08-25 13:58:55 -0300599 s2255_fillbuff(dev, buf, dma_q->channel, jpgsize);
Dean Anderson38f993a2008-06-26 23:15:51 -0300600 wake_up(&buf->vb.done);
601 dprintk(2, "wakeup [buf/i] [%p/%d]\n", buf, buf->vb.i);
602unlock:
603 spin_unlock_irqrestore(&dev->slock, flags);
604 return 0;
605}
606
Dean Anderson38f993a2008-06-26 23:15:51 -0300607static const struct s2255_fmt *format_by_fourcc(int fourcc)
608{
609 unsigned int i;
610
611 for (i = 0; i < ARRAY_SIZE(formats); i++) {
612 if (-1 == formats[i].fourcc)
613 continue;
614 if (formats[i].fourcc == fourcc)
615 return formats + i;
616 }
617 return NULL;
618}
619
Dean Anderson38f993a2008-06-26 23:15:51 -0300620/* video buffer vmalloc implementation based partly on VIVI driver which is
621 * Copyright (c) 2006 by
622 * Mauro Carvalho Chehab <mchehab--a.t--infradead.org>
623 * Ted Walther <ted--a.t--enumera.com>
624 * John Sokol <sokol--a.t--videotechnology.com>
625 * http://v4l.videotechnology.com/
626 *
627 */
628static void s2255_fillbuff(struct s2255_dev *dev, struct s2255_buffer *buf,
Dean Anderson14d96262008-08-25 13:58:55 -0300629 int chn, int jpgsize)
Dean Anderson38f993a2008-06-26 23:15:51 -0300630{
631 int pos = 0;
632 struct timeval ts;
633 const char *tmpbuf;
634 char *vbuf = videobuf_to_vmalloc(&buf->vb);
635 unsigned long last_frame;
636 struct s2255_framei *frm;
637
638 if (!vbuf)
639 return;
640
641 last_frame = dev->last_frame[chn];
642 if (last_frame != -1) {
643 frm = &dev->buffer[chn].frame[last_frame];
644 tmpbuf =
645 (const char *)dev->buffer[chn].frame[last_frame].lpvbits;
646 switch (buf->fmt->fourcc) {
647 case V4L2_PIX_FMT_YUYV:
648 case V4L2_PIX_FMT_UYVY:
649 planar422p_to_yuv_packed((const unsigned char *)tmpbuf,
650 vbuf, buf->vb.width,
651 buf->vb.height,
652 buf->fmt->fourcc);
653 break;
654 case V4L2_PIX_FMT_GREY:
655 memcpy(vbuf, tmpbuf, buf->vb.width * buf->vb.height);
656 break;
Dean Anderson14d96262008-08-25 13:58:55 -0300657 case V4L2_PIX_FMT_JPEG:
658 buf->vb.size = jpgsize;
659 memcpy(vbuf, tmpbuf, buf->vb.size);
660 break;
Dean Anderson38f993a2008-06-26 23:15:51 -0300661 case V4L2_PIX_FMT_YUV422P:
662 memcpy(vbuf, tmpbuf,
663 buf->vb.width * buf->vb.height * 2);
664 break;
665 default:
666 printk(KERN_DEBUG "s2255: unknown format?\n");
667 }
668 dev->last_frame[chn] = -1;
Dean Anderson38f993a2008-06-26 23:15:51 -0300669 } else {
670 printk(KERN_ERR "s2255: =======no frame\n");
671 return;
672
673 }
674 dprintk(2, "s2255fill at : Buffer 0x%08lx size= %d\n",
675 (unsigned long)vbuf, pos);
676 /* tell v4l buffer was filled */
677
Dean Andersona1c45302008-09-09 12:29:56 -0300678 buf->vb.field_count = dev->frame_count[chn] * 2;
Dean Anderson38f993a2008-06-26 23:15:51 -0300679 do_gettimeofday(&ts);
680 buf->vb.ts = ts;
681 buf->vb.state = VIDEOBUF_DONE;
682}
683
684
685/* ------------------------------------------------------------------
686 Videobuf operations
687 ------------------------------------------------------------------*/
688
689static int buffer_setup(struct videobuf_queue *vq, unsigned int *count,
690 unsigned int *size)
691{
692 struct s2255_fh *fh = vq->priv_data;
693
694 *size = fh->width * fh->height * (fh->fmt->depth >> 3);
695
696 if (0 == *count)
697 *count = S2255_DEF_BUFS;
698
Andreas Bombedab7e312010-03-21 16:02:45 -0300699 if (*size * *count > vid_limit * 1024 * 1024)
700 *count = (vid_limit * 1024 * 1024) / *size;
Dean Anderson38f993a2008-06-26 23:15:51 -0300701
702 return 0;
703}
704
705static void free_buffer(struct videobuf_queue *vq, struct s2255_buffer *buf)
706{
707 dprintk(4, "%s\n", __func__);
708
Dean Anderson38f993a2008-06-26 23:15:51 -0300709 videobuf_vmalloc_free(&buf->vb);
710 buf->vb.state = VIDEOBUF_NEEDS_INIT;
711}
712
713static int buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb,
714 enum v4l2_field field)
715{
716 struct s2255_fh *fh = vq->priv_data;
717 struct s2255_buffer *buf = container_of(vb, struct s2255_buffer, vb);
718 int rc;
719 dprintk(4, "%s, field=%d\n", __func__, field);
720 if (fh->fmt == NULL)
721 return -EINVAL;
722
723 if ((fh->width < norm_minw(fh->dev->vdev[fh->channel])) ||
724 (fh->width > norm_maxw(fh->dev->vdev[fh->channel])) ||
725 (fh->height < norm_minh(fh->dev->vdev[fh->channel])) ||
726 (fh->height > norm_maxh(fh->dev->vdev[fh->channel]))) {
727 dprintk(4, "invalid buffer prepare\n");
728 return -EINVAL;
729 }
730
731 buf->vb.size = fh->width * fh->height * (fh->fmt->depth >> 3);
732
733 if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size) {
734 dprintk(4, "invalid buffer prepare\n");
735 return -EINVAL;
736 }
737
738 buf->fmt = fh->fmt;
739 buf->vb.width = fh->width;
740 buf->vb.height = fh->height;
741 buf->vb.field = field;
742
743
744 if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
745 rc = videobuf_iolock(vq, &buf->vb, NULL);
746 if (rc < 0)
747 goto fail;
748 }
749
750 buf->vb.state = VIDEOBUF_PREPARED;
751 return 0;
752fail:
753 free_buffer(vq, buf);
754 return rc;
755}
756
757static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
758{
759 struct s2255_buffer *buf = container_of(vb, struct s2255_buffer, vb);
760 struct s2255_fh *fh = vq->priv_data;
761 struct s2255_dev *dev = fh->dev;
762 struct s2255_dmaqueue *vidq = &dev->vidq[fh->channel];
763
764 dprintk(1, "%s\n", __func__);
765
766 buf->vb.state = VIDEOBUF_QUEUED;
767 list_add_tail(&buf->vb.queue, &vidq->active);
768}
769
770static void buffer_release(struct videobuf_queue *vq,
771 struct videobuf_buffer *vb)
772{
773 struct s2255_buffer *buf = container_of(vb, struct s2255_buffer, vb);
774 struct s2255_fh *fh = vq->priv_data;
775 dprintk(4, "%s %d\n", __func__, fh->channel);
776 free_buffer(vq, buf);
777}
778
779static struct videobuf_queue_ops s2255_video_qops = {
780 .buf_setup = buffer_setup,
781 .buf_prepare = buffer_prepare,
782 .buf_queue = buffer_queue,
783 .buf_release = buffer_release,
784};
785
786
787static int res_get(struct s2255_dev *dev, struct s2255_fh *fh)
788{
789 /* is it free? */
790 mutex_lock(&dev->lock);
791 if (dev->resources[fh->channel]) {
792 /* no, someone else uses it */
793 mutex_unlock(&dev->lock);
794 return 0;
795 }
796 /* it's free, grab it */
797 dev->resources[fh->channel] = 1;
Dean Andersonf78d92c2008-07-22 14:43:27 -0300798 fh->resources[fh->channel] = 1;
799 dprintk(1, "s2255: res: get\n");
Dean Anderson38f993a2008-06-26 23:15:51 -0300800 mutex_unlock(&dev->lock);
801 return 1;
802}
803
804static int res_locked(struct s2255_dev *dev, struct s2255_fh *fh)
805{
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300806 return dev->resources[fh->channel];
Dean Anderson38f993a2008-06-26 23:15:51 -0300807}
808
Dean Andersonf78d92c2008-07-22 14:43:27 -0300809static int res_check(struct s2255_fh *fh)
810{
811 return fh->resources[fh->channel];
812}
813
814
Dean Anderson38f993a2008-06-26 23:15:51 -0300815static void res_free(struct s2255_dev *dev, struct s2255_fh *fh)
816{
Dean Andersonf78d92c2008-07-22 14:43:27 -0300817 mutex_lock(&dev->lock);
Dean Anderson38f993a2008-06-26 23:15:51 -0300818 dev->resources[fh->channel] = 0;
Dean Andersonf78d92c2008-07-22 14:43:27 -0300819 fh->resources[fh->channel] = 0;
820 mutex_unlock(&dev->lock);
Dean Anderson38f993a2008-06-26 23:15:51 -0300821 dprintk(1, "res: put\n");
822}
823
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300824static int vidioc_querymenu(struct file *file, void *priv,
825 struct v4l2_querymenu *qmenu)
826{
827 static const char *colorfilter[] = {
828 "Off",
829 "On",
830 NULL
831 };
832 if (qmenu->id == V4L2_CID_PRIVATE_COLORFILTER) {
833 int i;
834 const char **menu_items = colorfilter;
835 for (i = 0; i < qmenu->index && menu_items[i]; i++)
836 ; /* do nothing (from v4l2-common.c) */
837 if (menu_items[i] == NULL || menu_items[i][0] == '\0')
838 return -EINVAL;
839 strlcpy(qmenu->name, menu_items[qmenu->index],
840 sizeof(qmenu->name));
841 return 0;
842 }
843 return v4l2_ctrl_query_menu(qmenu, NULL, NULL);
844}
845
Dean Anderson38f993a2008-06-26 23:15:51 -0300846static int vidioc_querycap(struct file *file, void *priv,
847 struct v4l2_capability *cap)
848{
849 struct s2255_fh *fh = file->private_data;
850 struct s2255_dev *dev = fh->dev;
851 strlcpy(cap->driver, "s2255", sizeof(cap->driver));
852 strlcpy(cap->card, "s2255", sizeof(cap->card));
Thierry MERLEe22ed882009-01-20 18:19:25 -0300853 usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info));
Dean Anderson38f993a2008-06-26 23:15:51 -0300854 cap->version = S2255_VERSION;
855 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
856 return 0;
857}
858
859static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
860 struct v4l2_fmtdesc *f)
861{
862 int index = 0;
863 if (f)
864 index = f->index;
865
866 if (index >= ARRAY_SIZE(formats))
867 return -EINVAL;
868
869 dprintk(4, "name %s\n", formats[index].name);
870 strlcpy(f->description, formats[index].name, sizeof(f->description));
871 f->pixelformat = formats[index].fourcc;
872 return 0;
873}
874
875static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
876 struct v4l2_format *f)
877{
878 struct s2255_fh *fh = priv;
879
880 f->fmt.pix.width = fh->width;
881 f->fmt.pix.height = fh->height;
882 f->fmt.pix.field = fh->vb_vidq.field;
883 f->fmt.pix.pixelformat = fh->fmt->fourcc;
884 f->fmt.pix.bytesperline = f->fmt.pix.width * (fh->fmt->depth >> 3);
885 f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300886 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -0300887}
888
889static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
890 struct v4l2_format *f)
891{
892 const struct s2255_fmt *fmt;
893 enum v4l2_field field;
894 int b_any_field = 0;
895 struct s2255_fh *fh = priv;
896 struct s2255_dev *dev = fh->dev;
897 int is_ntsc;
898
899 is_ntsc =
900 (dev->vdev[fh->channel]->current_norm & V4L2_STD_NTSC) ? 1 : 0;
901
902 fmt = format_by_fourcc(f->fmt.pix.pixelformat);
903
904 if (fmt == NULL)
905 return -EINVAL;
906
907 field = f->fmt.pix.field;
908 if (field == V4L2_FIELD_ANY)
909 b_any_field = 1;
910
911 dprintk(4, "try format %d \n", is_ntsc);
912 /* supports 3 sizes. see s2255drv.h */
913 dprintk(50, "width test %d, height %d\n",
914 f->fmt.pix.width, f->fmt.pix.height);
915 if (is_ntsc) {
916 /* NTSC */
917 if (f->fmt.pix.height >= NUM_LINES_1CIFS_NTSC * 2) {
918 f->fmt.pix.height = NUM_LINES_1CIFS_NTSC * 2;
919 if (b_any_field) {
920 field = V4L2_FIELD_SEQ_TB;
921 } else if (!((field == V4L2_FIELD_INTERLACED) ||
922 (field == V4L2_FIELD_SEQ_TB) ||
923 (field == V4L2_FIELD_INTERLACED_TB))) {
924 dprintk(1, "unsupported field setting\n");
925 return -EINVAL;
926 }
927 } else {
928 f->fmt.pix.height = NUM_LINES_1CIFS_NTSC;
929 if (b_any_field) {
930 field = V4L2_FIELD_TOP;
931 } else if (!((field == V4L2_FIELD_TOP) ||
932 (field == V4L2_FIELD_BOTTOM))) {
933 dprintk(1, "unsupported field setting\n");
934 return -EINVAL;
935 }
936
937 }
938 if (f->fmt.pix.width >= LINE_SZ_4CIFS_NTSC)
939 f->fmt.pix.width = LINE_SZ_4CIFS_NTSC;
940 else if (f->fmt.pix.width >= LINE_SZ_2CIFS_NTSC)
941 f->fmt.pix.width = LINE_SZ_2CIFS_NTSC;
942 else if (f->fmt.pix.width >= LINE_SZ_1CIFS_NTSC)
943 f->fmt.pix.width = LINE_SZ_1CIFS_NTSC;
944 else
945 f->fmt.pix.width = LINE_SZ_1CIFS_NTSC;
946 } else {
947 /* PAL */
948 if (f->fmt.pix.height >= NUM_LINES_1CIFS_PAL * 2) {
949 f->fmt.pix.height = NUM_LINES_1CIFS_PAL * 2;
950 if (b_any_field) {
951 field = V4L2_FIELD_SEQ_TB;
952 } else if (!((field == V4L2_FIELD_INTERLACED) ||
953 (field == V4L2_FIELD_SEQ_TB) ||
954 (field == V4L2_FIELD_INTERLACED_TB))) {
955 dprintk(1, "unsupported field setting\n");
956 return -EINVAL;
957 }
958 } else {
959 f->fmt.pix.height = NUM_LINES_1CIFS_PAL;
960 if (b_any_field) {
961 field = V4L2_FIELD_TOP;
962 } else if (!((field == V4L2_FIELD_TOP) ||
963 (field == V4L2_FIELD_BOTTOM))) {
964 dprintk(1, "unsupported field setting\n");
965 return -EINVAL;
966 }
967 }
968 if (f->fmt.pix.width >= LINE_SZ_4CIFS_PAL) {
969 dprintk(50, "pal 704\n");
970 f->fmt.pix.width = LINE_SZ_4CIFS_PAL;
971 field = V4L2_FIELD_SEQ_TB;
972 } else if (f->fmt.pix.width >= LINE_SZ_2CIFS_PAL) {
973 dprintk(50, "pal 352A\n");
974 f->fmt.pix.width = LINE_SZ_2CIFS_PAL;
975 field = V4L2_FIELD_TOP;
976 } else if (f->fmt.pix.width >= LINE_SZ_1CIFS_PAL) {
977 dprintk(50, "pal 352B\n");
978 f->fmt.pix.width = LINE_SZ_1CIFS_PAL;
979 field = V4L2_FIELD_TOP;
980 } else {
981 dprintk(50, "pal 352C\n");
982 f->fmt.pix.width = LINE_SZ_1CIFS_PAL;
983 field = V4L2_FIELD_TOP;
984 }
985 }
986
987 dprintk(50, "width %d height %d field %d \n", f->fmt.pix.width,
988 f->fmt.pix.height, f->fmt.pix.field);
989 f->fmt.pix.field = field;
990 f->fmt.pix.bytesperline = (f->fmt.pix.width * fmt->depth) >> 3;
991 f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
992 return 0;
993}
994
995static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
996 struct v4l2_format *f)
997{
998 struct s2255_fh *fh = priv;
999 const struct s2255_fmt *fmt;
1000 struct videobuf_queue *q = &fh->vb_vidq;
1001 int ret;
1002 int norm;
1003
1004 ret = vidioc_try_fmt_vid_cap(file, fh, f);
1005
1006 if (ret < 0)
Dean Anderson3f8d6f72008-06-30 21:28:34 -03001007 return ret;
Dean Anderson38f993a2008-06-26 23:15:51 -03001008
1009 fmt = format_by_fourcc(f->fmt.pix.pixelformat);
1010
1011 if (fmt == NULL)
1012 return -EINVAL;
1013
1014 mutex_lock(&q->vb_lock);
1015
1016 if (videobuf_queue_is_busy(&fh->vb_vidq)) {
1017 dprintk(1, "queue busy\n");
1018 ret = -EBUSY;
1019 goto out_s_fmt;
1020 }
1021
1022 if (res_locked(fh->dev, fh)) {
1023 dprintk(1, "can't change format after started\n");
1024 ret = -EBUSY;
1025 goto out_s_fmt;
1026 }
1027
1028 fh->fmt = fmt;
1029 fh->width = f->fmt.pix.width;
1030 fh->height = f->fmt.pix.height;
1031 fh->vb_vidq.field = f->fmt.pix.field;
1032 fh->type = f->type;
1033 norm = norm_minw(fh->dev->vdev[fh->channel]);
1034 if (fh->width > norm_minw(fh->dev->vdev[fh->channel])) {
Dean Anderson7d853532009-05-15 14:32:04 -03001035 if (fh->height > norm_minh(fh->dev->vdev[fh->channel])) {
1036 if (fh->dev->cap_parm[fh->channel].capturemode &
1037 V4L2_MODE_HIGHQUALITY) {
1038 fh->mode.scale = SCALE_4CIFSI;
1039 dprintk(2, "scale 4CIFSI\n");
1040 } else {
1041 fh->mode.scale = SCALE_4CIFS;
1042 dprintk(2, "scale 4CIFS\n");
1043 }
1044 } else
Dean Anderson38f993a2008-06-26 23:15:51 -03001045 fh->mode.scale = SCALE_2CIFS;
1046
1047 } else {
1048 fh->mode.scale = SCALE_1CIFS;
1049 }
1050
1051 /* color mode */
1052 switch (fh->fmt->fourcc) {
1053 case V4L2_PIX_FMT_GREY:
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001054 fh->mode.color &= ~MASK_COLOR;
1055 fh->mode.color |= COLOR_Y8;
Dean Anderson38f993a2008-06-26 23:15:51 -03001056 break;
Dean Anderson14d96262008-08-25 13:58:55 -03001057 case V4L2_PIX_FMT_JPEG:
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001058 fh->mode.color &= ~MASK_COLOR;
1059 fh->mode.color |= COLOR_JPG;
1060 fh->mode.color |= (fh->dev->jc[fh->channel].quality << 8);
Dean Anderson14d96262008-08-25 13:58:55 -03001061 break;
Dean Anderson38f993a2008-06-26 23:15:51 -03001062 case V4L2_PIX_FMT_YUV422P:
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001063 fh->mode.color &= ~MASK_COLOR;
1064 fh->mode.color |= COLOR_YUVPL;
Dean Anderson38f993a2008-06-26 23:15:51 -03001065 break;
1066 case V4L2_PIX_FMT_YUYV:
1067 case V4L2_PIX_FMT_UYVY:
1068 default:
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001069 fh->mode.color &= ~MASK_COLOR;
1070 fh->mode.color |= COLOR_YUVPK;
Dean Anderson38f993a2008-06-26 23:15:51 -03001071 break;
1072 }
1073 ret = 0;
1074out_s_fmt:
1075 mutex_unlock(&q->vb_lock);
1076 return ret;
1077}
1078
1079static int vidioc_reqbufs(struct file *file, void *priv,
1080 struct v4l2_requestbuffers *p)
1081{
1082 int rc;
1083 struct s2255_fh *fh = priv;
1084 rc = videobuf_reqbufs(&fh->vb_vidq, p);
1085 return rc;
1086}
1087
1088static int vidioc_querybuf(struct file *file, void *priv, struct v4l2_buffer *p)
1089{
1090 int rc;
1091 struct s2255_fh *fh = priv;
1092 rc = videobuf_querybuf(&fh->vb_vidq, p);
1093 return rc;
1094}
1095
1096static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *p)
1097{
1098 int rc;
1099 struct s2255_fh *fh = priv;
1100 rc = videobuf_qbuf(&fh->vb_vidq, p);
1101 return rc;
1102}
1103
1104static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
1105{
1106 int rc;
1107 struct s2255_fh *fh = priv;
1108 rc = videobuf_dqbuf(&fh->vb_vidq, p, file->f_flags & O_NONBLOCK);
1109 return rc;
1110}
1111
1112#ifdef CONFIG_VIDEO_V4L1_COMPAT
1113static int vidioc_cgmbuf(struct file *file, void *priv, struct video_mbuf *mbuf)
1114{
1115 struct s2255_fh *fh = priv;
1116
1117 return videobuf_cgmbuf(&fh->vb_vidq, mbuf, 8);
1118}
1119#endif
1120
1121/* write to the configuration pipe, synchronously */
1122static int s2255_write_config(struct usb_device *udev, unsigned char *pbuf,
1123 int size)
1124{
1125 int pipe;
1126 int done;
1127 long retval = -1;
1128 if (udev) {
1129 pipe = usb_sndbulkpipe(udev, S2255_CONFIG_EP);
1130 retval = usb_bulk_msg(udev, pipe, pbuf, size, &done, 500);
1131 }
1132 return retval;
1133}
1134
1135static u32 get_transfer_size(struct s2255_mode *mode)
1136{
1137 int linesPerFrame = LINE_SZ_DEF;
1138 int pixelsPerLine = NUM_LINES_DEF;
1139 u32 outImageSize;
1140 u32 usbInSize;
1141 unsigned int mask_mult;
1142
1143 if (mode == NULL)
1144 return 0;
1145
1146 if (mode->format == FORMAT_NTSC) {
1147 switch (mode->scale) {
1148 case SCALE_4CIFS:
Dean Anderson7d853532009-05-15 14:32:04 -03001149 case SCALE_4CIFSI:
Dean Anderson38f993a2008-06-26 23:15:51 -03001150 linesPerFrame = NUM_LINES_4CIFS_NTSC * 2;
1151 pixelsPerLine = LINE_SZ_4CIFS_NTSC;
1152 break;
1153 case SCALE_2CIFS:
1154 linesPerFrame = NUM_LINES_2CIFS_NTSC;
1155 pixelsPerLine = LINE_SZ_2CIFS_NTSC;
1156 break;
1157 case SCALE_1CIFS:
1158 linesPerFrame = NUM_LINES_1CIFS_NTSC;
1159 pixelsPerLine = LINE_SZ_1CIFS_NTSC;
1160 break;
1161 default:
1162 break;
1163 }
1164 } else if (mode->format == FORMAT_PAL) {
1165 switch (mode->scale) {
1166 case SCALE_4CIFS:
Dean Anderson7d853532009-05-15 14:32:04 -03001167 case SCALE_4CIFSI:
Dean Anderson38f993a2008-06-26 23:15:51 -03001168 linesPerFrame = NUM_LINES_4CIFS_PAL * 2;
1169 pixelsPerLine = LINE_SZ_4CIFS_PAL;
1170 break;
1171 case SCALE_2CIFS:
1172 linesPerFrame = NUM_LINES_2CIFS_PAL;
1173 pixelsPerLine = LINE_SZ_2CIFS_PAL;
1174 break;
1175 case SCALE_1CIFS:
1176 linesPerFrame = NUM_LINES_1CIFS_PAL;
1177 pixelsPerLine = LINE_SZ_1CIFS_PAL;
1178 break;
1179 default:
1180 break;
1181 }
1182 }
1183 outImageSize = linesPerFrame * pixelsPerLine;
Dean Anderson14d96262008-08-25 13:58:55 -03001184 if ((mode->color & MASK_COLOR) != COLOR_Y8) {
Dean Anderson38f993a2008-06-26 23:15:51 -03001185 /* 2 bytes/pixel if not monochrome */
1186 outImageSize *= 2;
1187 }
1188
1189 /* total bytes to send including prefix and 4K padding;
1190 must be a multiple of USB_READ_SIZE */
1191 usbInSize = outImageSize + PREFIX_SIZE; /* always send prefix */
1192 mask_mult = 0xffffffffUL - DEF_USB_BLOCK + 1;
1193 /* if size not a multiple of USB_READ_SIZE */
1194 if (usbInSize & ~mask_mult)
1195 usbInSize = (usbInSize & mask_mult) + (DEF_USB_BLOCK);
1196 return usbInSize;
1197}
1198
1199static void dump_verify_mode(struct s2255_dev *sdev, struct s2255_mode *mode)
1200{
1201 struct device *dev = &sdev->udev->dev;
1202 dev_info(dev, "------------------------------------------------\n");
1203 dev_info(dev, "verify mode\n");
1204 dev_info(dev, "format: %d\n", mode->format);
1205 dev_info(dev, "scale: %d\n", mode->scale);
1206 dev_info(dev, "fdec: %d\n", mode->fdec);
1207 dev_info(dev, "color: %d\n", mode->color);
1208 dev_info(dev, "bright: 0x%x\n", mode->bright);
1209 dev_info(dev, "restart: 0x%x\n", mode->restart);
1210 dev_info(dev, "usb_block: 0x%x\n", mode->usb_block);
1211 dev_info(dev, "single: 0x%x\n", mode->single);
1212 dev_info(dev, "------------------------------------------------\n");
1213}
1214
1215/*
1216 * set mode is the function which controls the DSP.
1217 * the restart parameter in struct s2255_mode should be set whenever
1218 * the image size could change via color format, video system or image
1219 * size.
1220 * When the restart parameter is set, we sleep for ONE frame to allow the
1221 * DSP time to get the new frame
1222 */
1223static int s2255_set_mode(struct s2255_dev *dev, unsigned long chn,
1224 struct s2255_mode *mode)
1225{
1226 int res;
Dean Anderson3fa00602010-03-04 20:47:33 -03001227 __le32 *buffer;
Dean Anderson38f993a2008-06-26 23:15:51 -03001228 unsigned long chn_rev;
Dean Anderson14d96262008-08-25 13:58:55 -03001229 mutex_lock(&dev->lock);
Dean Anderson38f993a2008-06-26 23:15:51 -03001230 chn_rev = G_chnmap[chn];
1231 dprintk(3, "mode scale [%ld] %p %d\n", chn, mode, mode->scale);
1232 dprintk(3, "mode scale [%ld] %p %d\n", chn, &dev->mode[chn],
1233 dev->mode[chn].scale);
1234 dprintk(2, "mode contrast %x\n", mode->contrast);
1235
Dean Anderson22b88d42008-08-29 15:33:19 -03001236 /* if JPEG, set the quality */
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001237 if ((mode->color & MASK_COLOR) == COLOR_JPG) {
1238 mode->color &= ~MASK_COLOR;
1239 mode->color |= COLOR_JPG;
1240 mode->color &= ~MASK_JPG_QUALITY;
1241 mode->color |= (dev->jc[chn].quality << 8);
1242 }
Dean Anderson22b88d42008-08-29 15:33:19 -03001243
Dean Anderson38f993a2008-06-26 23:15:51 -03001244 /* save the mode */
1245 dev->mode[chn] = *mode;
1246 dev->req_image_size[chn] = get_transfer_size(mode);
1247 dprintk(1, "transfer size %ld\n", dev->req_image_size[chn]);
1248
1249 buffer = kzalloc(512, GFP_KERNEL);
1250 if (buffer == NULL) {
1251 dev_err(&dev->udev->dev, "out of mem\n");
Dean Anderson14d96262008-08-25 13:58:55 -03001252 mutex_unlock(&dev->lock);
Dean Anderson38f993a2008-06-26 23:15:51 -03001253 return -ENOMEM;
1254 }
1255
1256 /* set the mode */
1257 buffer[0] = IN_DATA_TOKEN;
Dean Anderson3fa00602010-03-04 20:47:33 -03001258 buffer[1] = (__le32) cpu_to_le32(chn_rev);
Dean Anderson38f993a2008-06-26 23:15:51 -03001259 buffer[2] = CMD_SET_MODE;
1260 memcpy(&buffer[3], &dev->mode[chn], sizeof(struct s2255_mode));
Dean Anderson9d63cec2009-04-20 19:07:44 -03001261 dev->setmode_ready[chn] = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001262 res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
1263 if (debug)
1264 dump_verify_mode(dev, mode);
1265 kfree(buffer);
1266 dprintk(1, "set mode done chn %lu, %d\n", chn, res);
1267
1268 /* wait at least 3 frames before continuing */
Dean Anderson14d96262008-08-25 13:58:55 -03001269 if (mode->restart) {
Dean Anderson14d96262008-08-25 13:58:55 -03001270 wait_event_timeout(dev->wait_setmode[chn],
1271 (dev->setmode_ready[chn] != 0),
1272 msecs_to_jiffies(S2255_SETMODE_TIMEOUT));
1273 if (dev->setmode_ready[chn] != 1) {
1274 printk(KERN_DEBUG "s2255: no set mode response\n");
1275 res = -EFAULT;
1276 }
1277 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001278
1279 /* clear the restart flag */
1280 dev->mode[chn].restart = 0;
Dean Anderson14d96262008-08-25 13:58:55 -03001281 mutex_unlock(&dev->lock);
Dean Anderson38f993a2008-06-26 23:15:51 -03001282 return res;
1283}
1284
Dean Anderson4de39f52010-03-03 19:39:19 -03001285static int s2255_cmd_status(struct s2255_dev *dev, unsigned long chn,
1286 u32 *pstatus)
1287{
1288 int res;
Dean Anderson3fa00602010-03-04 20:47:33 -03001289 __le32 *buffer;
Dean Anderson4de39f52010-03-03 19:39:19 -03001290 u32 chn_rev;
1291 mutex_lock(&dev->lock);
1292 chn_rev = G_chnmap[chn];
1293 dprintk(4, "%s chan %d\n", __func__, chn_rev);
1294 buffer = kzalloc(512, GFP_KERNEL);
1295 if (buffer == NULL) {
1296 dev_err(&dev->udev->dev, "out of mem\n");
1297 mutex_unlock(&dev->lock);
1298 return -ENOMEM;
1299 }
1300 /* form the get vid status command */
1301 buffer[0] = IN_DATA_TOKEN;
Dean Anderson3fa00602010-03-04 20:47:33 -03001302 buffer[1] = (__le32) cpu_to_le32(chn_rev);
Dean Anderson4de39f52010-03-03 19:39:19 -03001303 buffer[2] = CMD_STATUS;
1304 *pstatus = 0;
1305 dev->vidstatus_ready[chn] = 0;
1306 res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
1307 kfree(buffer);
1308 wait_event_timeout(dev->wait_vidstatus[chn],
1309 (dev->vidstatus_ready[chn] != 0),
1310 msecs_to_jiffies(S2255_VIDSTATUS_TIMEOUT));
1311 if (dev->vidstatus_ready[chn] != 1) {
1312 printk(KERN_DEBUG "s2255: no vidstatus response\n");
1313 res = -EFAULT;
1314 }
1315 *pstatus = dev->vidstatus[chn];
1316 dprintk(4, "%s, vid status %d\n", __func__, *pstatus);
1317 mutex_unlock(&dev->lock);
1318 return res;
1319}
1320
Dean Anderson38f993a2008-06-26 23:15:51 -03001321static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
1322{
1323 int res;
1324 struct s2255_fh *fh = priv;
1325 struct s2255_dev *dev = fh->dev;
1326 struct s2255_mode *new_mode;
1327 struct s2255_mode *old_mode;
1328 int chn;
1329 int j;
1330 dprintk(4, "%s\n", __func__);
1331 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1332 dev_err(&dev->udev->dev, "invalid fh type0\n");
1333 return -EINVAL;
1334 }
1335 if (i != fh->type) {
1336 dev_err(&dev->udev->dev, "invalid fh type1\n");
1337 return -EINVAL;
1338 }
1339
1340 if (!res_get(dev, fh)) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03001341 s2255_dev_err(&dev->udev->dev, "stream busy\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03001342 return -EBUSY;
1343 }
1344
1345 /* send a set mode command everytime with restart.
1346 in case we switch resolutions or other parameters */
1347 chn = fh->channel;
1348 new_mode = &fh->mode;
1349 old_mode = &fh->dev->mode[chn];
1350
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001351 if ((new_mode->color & MASK_COLOR) != (old_mode->color & MASK_COLOR))
Dean Anderson38f993a2008-06-26 23:15:51 -03001352 new_mode->restart = 1;
1353 else if (new_mode->scale != old_mode->scale)
1354 new_mode->restart = 1;
1355 else if (new_mode->format != old_mode->format)
1356 new_mode->restart = 1;
1357
1358 s2255_set_mode(dev, chn, new_mode);
1359 new_mode->restart = 0;
1360 *old_mode = *new_mode;
1361 dev->cur_fmt[chn] = fh->fmt;
1362 dprintk(1, "%s[%d]\n", __func__, chn);
1363 dev->last_frame[chn] = -1;
1364 dev->bad_payload[chn] = 0;
1365 dev->cur_frame[chn] = 0;
Dean Andersona1c45302008-09-09 12:29:56 -03001366 dev->frame_count[chn] = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001367 for (j = 0; j < SYS_FRAMES; j++) {
Dean Anderson14d96262008-08-25 13:58:55 -03001368 dev->buffer[chn].frame[j].ulState = S2255_READ_IDLE;
Dean Anderson38f993a2008-06-26 23:15:51 -03001369 dev->buffer[chn].frame[j].cur_size = 0;
1370 }
1371 res = videobuf_streamon(&fh->vb_vidq);
1372 if (res == 0) {
1373 s2255_start_acquire(dev, chn);
1374 dev->b_acquire[chn] = 1;
1375 } else {
1376 res_free(dev, fh);
1377 }
1378 return res;
1379}
1380
1381static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
1382{
Dean Anderson38f993a2008-06-26 23:15:51 -03001383 struct s2255_fh *fh = priv;
1384 struct s2255_dev *dev = fh->dev;
1385
1386 dprintk(4, "%s\n, channel: %d", __func__, fh->channel);
1387 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1388 printk(KERN_ERR "invalid fh type0\n");
1389 return -EINVAL;
1390 }
1391 if (i != fh->type) {
1392 printk(KERN_ERR "invalid type i\n");
1393 return -EINVAL;
1394 }
1395 s2255_stop_acquire(dev, fh->channel);
Dean Andersonb7732a32009-03-30 11:59:56 -03001396 videobuf_streamoff(&fh->vb_vidq);
Dean Anderson38f993a2008-06-26 23:15:51 -03001397 res_free(dev, fh);
Dean Andersonf78d92c2008-07-22 14:43:27 -03001398 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001399}
1400
1401static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *i)
1402{
1403 struct s2255_fh *fh = priv;
1404 struct s2255_mode *mode;
1405 struct videobuf_queue *q = &fh->vb_vidq;
1406 int ret = 0;
1407
1408 mutex_lock(&q->vb_lock);
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001409
Dean Anderson38f993a2008-06-26 23:15:51 -03001410 if (videobuf_queue_is_busy(q)) {
1411 dprintk(1, "queue busy\n");
1412 ret = -EBUSY;
1413 goto out_s_std;
1414 }
1415
1416 if (res_locked(fh->dev, fh)) {
1417 dprintk(1, "can't change standard after started\n");
1418 ret = -EBUSY;
1419 goto out_s_std;
1420 }
1421 mode = &fh->mode;
Dean Anderson38f993a2008-06-26 23:15:51 -03001422 if (*i & V4L2_STD_NTSC) {
Dean Andersone6b44bc2010-03-08 20:04:48 -03001423 dprintk(4, "%s NTSC\n", __func__);
1424 /* if changing format, reset frame decimation/intervals */
1425 if (mode->format != FORMAT_NTSC) {
1426 mode->format = FORMAT_NTSC;
1427 mode->fdec = FDEC_1;
1428 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001429 } else if (*i & V4L2_STD_PAL) {
Dean Andersone6b44bc2010-03-08 20:04:48 -03001430 dprintk(4, "%s PAL\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03001431 mode->format = FORMAT_PAL;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001432 if (mode->format != FORMAT_PAL) {
1433 mode->format = FORMAT_PAL;
1434 mode->fdec = FDEC_1;
1435 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001436 } else {
1437 ret = -EINVAL;
1438 }
1439out_s_std:
1440 mutex_unlock(&q->vb_lock);
1441 return ret;
1442}
1443
1444/* Sensoray 2255 is a multiple channel capture device.
1445 It does not have a "crossbar" of inputs.
1446 We use one V4L device per channel. The user must
1447 be aware that certain combinations are not allowed.
1448 For instance, you cannot do full FPS on more than 2 channels(2 videodevs)
1449 at once in color(you can do full fps on 4 channels with greyscale.
1450*/
1451static int vidioc_enum_input(struct file *file, void *priv,
1452 struct v4l2_input *inp)
1453{
Dean Anderson4de39f52010-03-03 19:39:19 -03001454 struct s2255_fh *fh = priv;
1455 struct s2255_dev *dev = fh->dev;
1456 u32 status = 0;
1457
Dean Anderson38f993a2008-06-26 23:15:51 -03001458 if (inp->index != 0)
1459 return -EINVAL;
1460
1461 inp->type = V4L2_INPUT_TYPE_CAMERA;
1462 inp->std = S2255_NORMS;
Dean Anderson4de39f52010-03-03 19:39:19 -03001463 inp->status = 0;
1464 if (dev->dsp_fw_ver >= S2255_MIN_DSP_STATUS) {
1465 int rc;
1466 rc = s2255_cmd_status(dev, fh->channel, &status);
1467 dprintk(4, "s2255_cmd_status rc: %d status %x\n", rc, status);
1468 if (rc == 0)
1469 inp->status = (status & 0x01) ? 0
1470 : V4L2_IN_ST_NO_SIGNAL;
1471 }
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001472 switch (dev->pid) {
1473 case 0x2255:
1474 default:
1475 strlcpy(inp->name, "Composite", sizeof(inp->name));
1476 break;
1477 case 0x2257:
1478 strlcpy(inp->name, (fh->channel < 2) ? "Composite" : "S-Video",
1479 sizeof(inp->name));
1480 break;
1481 }
Dean Anderson3f8d6f72008-06-30 21:28:34 -03001482 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001483}
1484
1485static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
1486{
1487 *i = 0;
1488 return 0;
1489}
1490static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
1491{
1492 if (i > 0)
1493 return -EINVAL;
1494 return 0;
1495}
1496
1497/* --- controls ---------------------------------------------- */
1498static int vidioc_queryctrl(struct file *file, void *priv,
1499 struct v4l2_queryctrl *qc)
1500{
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001501 struct s2255_fh *fh = priv;
1502 struct s2255_dev *dev = fh->dev;
Dean Anderson2e70db92010-03-05 14:29:09 -03001503 switch (qc->id) {
1504 case V4L2_CID_BRIGHTNESS:
1505 v4l2_ctrl_query_fill(qc, -127, 127, 1, DEF_BRIGHT);
1506 break;
1507 case V4L2_CID_CONTRAST:
1508 v4l2_ctrl_query_fill(qc, 0, 255, 1, DEF_CONTRAST);
1509 break;
1510 case V4L2_CID_SATURATION:
1511 v4l2_ctrl_query_fill(qc, 0, 255, 1, DEF_SATURATION);
1512 break;
1513 case V4L2_CID_HUE:
1514 v4l2_ctrl_query_fill(qc, 0, 255, 1, DEF_HUE);
1515 break;
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001516 case V4L2_CID_PRIVATE_COLORFILTER:
1517 if (dev->dsp_fw_ver < S2255_MIN_DSP_COLORFILTER)
1518 return -EINVAL;
1519 if ((dev->pid == 0x2257) && (fh->channel > 1))
1520 return -EINVAL;
1521 strlcpy(qc->name, "Color Filter", sizeof(qc->name));
1522 qc->type = V4L2_CTRL_TYPE_MENU;
1523 qc->minimum = 0;
1524 qc->maximum = 1;
1525 qc->step = 1;
1526 qc->default_value = 1;
1527 qc->flags = 0;
1528 break;
Dean Anderson2e70db92010-03-05 14:29:09 -03001529 default:
1530 return -EINVAL;
1531 }
1532 dprintk(4, "%s, id %d\n", __func__, qc->id);
1533 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001534}
1535
1536static int vidioc_g_ctrl(struct file *file, void *priv,
1537 struct v4l2_control *ctrl)
1538{
Dean Anderson2e70db92010-03-05 14:29:09 -03001539 struct s2255_fh *fh = priv;
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001540 struct s2255_dev *dev = fh->dev;
Dean Anderson2e70db92010-03-05 14:29:09 -03001541 switch (ctrl->id) {
1542 case V4L2_CID_BRIGHTNESS:
1543 ctrl->value = fh->mode.bright;
1544 break;
1545 case V4L2_CID_CONTRAST:
1546 ctrl->value = fh->mode.contrast;
1547 break;
1548 case V4L2_CID_SATURATION:
1549 ctrl->value = fh->mode.saturation;
1550 break;
1551 case V4L2_CID_HUE:
1552 ctrl->value = fh->mode.hue;
1553 break;
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001554 case V4L2_CID_PRIVATE_COLORFILTER:
1555 if (dev->dsp_fw_ver < S2255_MIN_DSP_COLORFILTER)
1556 return -EINVAL;
1557 if ((dev->pid == 0x2257) && (fh->channel > 1))
1558 return -EINVAL;
1559 ctrl->value = !((fh->mode.color & MASK_INPUT_TYPE) >> 16);
1560 break;
Dean Anderson2e70db92010-03-05 14:29:09 -03001561 default:
1562 return -EINVAL;
1563 }
1564 dprintk(4, "%s, id %d val %d\n", __func__, ctrl->id, ctrl->value);
1565 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001566}
1567
1568static int vidioc_s_ctrl(struct file *file, void *priv,
1569 struct v4l2_control *ctrl)
1570{
Dean Anderson38f993a2008-06-26 23:15:51 -03001571 struct s2255_fh *fh = priv;
1572 struct s2255_dev *dev = fh->dev;
1573 struct s2255_mode *mode;
1574 mode = &fh->mode;
Dean Anderson2e70db92010-03-05 14:29:09 -03001575 dprintk(4, "%s\n", __func__);
1576 /* update the mode to the corresponding value */
1577 switch (ctrl->id) {
1578 case V4L2_CID_BRIGHTNESS:
1579 mode->bright = ctrl->value;
1580 break;
1581 case V4L2_CID_CONTRAST:
1582 mode->contrast = ctrl->value;
1583 break;
1584 case V4L2_CID_HUE:
1585 mode->hue = ctrl->value;
1586 break;
1587 case V4L2_CID_SATURATION:
1588 mode->saturation = ctrl->value;
1589 break;
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001590 case V4L2_CID_PRIVATE_COLORFILTER:
1591 if (dev->dsp_fw_ver < S2255_MIN_DSP_COLORFILTER)
1592 return -EINVAL;
1593 if ((dev->pid == 0x2257) && (fh->channel > 1))
1594 return -EINVAL;
1595 mode->color &= ~MASK_INPUT_TYPE;
1596 mode->color |= ((ctrl->value ? 0 : 1) << 16);
1597 break;
Dean Anderson2e70db92010-03-05 14:29:09 -03001598 default:
1599 return -EINVAL;
Dean Anderson38f993a2008-06-26 23:15:51 -03001600 }
Dean Anderson2e70db92010-03-05 14:29:09 -03001601 mode->restart = 0;
1602 /* set mode here. Note: stream does not need restarted.
1603 some V4L programs restart stream unnecessarily
1604 after a s_crtl.
1605 */
1606 s2255_set_mode(dev, fh->channel, mode);
1607 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001608}
1609
Dean Anderson22b88d42008-08-29 15:33:19 -03001610static int vidioc_g_jpegcomp(struct file *file, void *priv,
1611 struct v4l2_jpegcompression *jc)
1612{
1613 struct s2255_fh *fh = priv;
1614 struct s2255_dev *dev = fh->dev;
1615 *jc = dev->jc[fh->channel];
1616 dprintk(2, "getting jpegcompression, quality %d\n", jc->quality);
1617 return 0;
1618}
1619
1620static int vidioc_s_jpegcomp(struct file *file, void *priv,
1621 struct v4l2_jpegcompression *jc)
1622{
1623 struct s2255_fh *fh = priv;
1624 struct s2255_dev *dev = fh->dev;
1625 if (jc->quality < 0 || jc->quality > 100)
1626 return -EINVAL;
1627 dev->jc[fh->channel].quality = jc->quality;
1628 dprintk(2, "setting jpeg quality %d\n", jc->quality);
1629 return 0;
1630}
Dean Anderson7d853532009-05-15 14:32:04 -03001631
1632static int vidioc_g_parm(struct file *file, void *priv,
1633 struct v4l2_streamparm *sp)
1634{
1635 struct s2255_fh *fh = priv;
1636 struct s2255_dev *dev = fh->dev;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001637 __u32 def_num, def_dem;
Dean Anderson7d853532009-05-15 14:32:04 -03001638 if (sp->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1639 return -EINVAL;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001640 memset(sp, 0, sizeof(struct v4l2_streamparm));
1641 sp->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
Dean Anderson7d853532009-05-15 14:32:04 -03001642 sp->parm.capture.capturemode = dev->cap_parm[fh->channel].capturemode;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001643 def_num = (fh->mode.format == FORMAT_NTSC) ? 1001 : 1000;
1644 def_dem = (fh->mode.format == FORMAT_NTSC) ? 30000 : 25000;
1645 sp->parm.capture.timeperframe.denominator = def_dem;
1646 switch (fh->mode.fdec) {
1647 default:
1648 case FDEC_1:
1649 sp->parm.capture.timeperframe.numerator = def_num;
1650 break;
1651 case FDEC_2:
1652 sp->parm.capture.timeperframe.numerator = def_num * 2;
1653 break;
1654 case FDEC_3:
1655 sp->parm.capture.timeperframe.numerator = def_num * 3;
1656 break;
1657 case FDEC_5:
1658 sp->parm.capture.timeperframe.numerator = def_num * 5;
1659 break;
1660 }
1661 dprintk(4, "%s capture mode, %d timeperframe %d/%d\n", __func__,
1662 sp->parm.capture.capturemode,
1663 sp->parm.capture.timeperframe.numerator,
1664 sp->parm.capture.timeperframe.denominator);
Dean Anderson7d853532009-05-15 14:32:04 -03001665 return 0;
1666}
1667
1668static int vidioc_s_parm(struct file *file, void *priv,
1669 struct v4l2_streamparm *sp)
1670{
1671 struct s2255_fh *fh = priv;
1672 struct s2255_dev *dev = fh->dev;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001673 int fdec = FDEC_1;
1674 __u32 def_num, def_dem;
Dean Anderson7d853532009-05-15 14:32:04 -03001675 if (sp->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1676 return -EINVAL;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001677 /* high quality capture mode requires a stream restart */
1678 if (dev->cap_parm[fh->channel].capturemode
1679 != sp->parm.capture.capturemode && res_locked(fh->dev, fh))
1680 return -EBUSY;
1681 def_num = (fh->mode.format == FORMAT_NTSC) ? 1001 : 1000;
1682 def_dem = (fh->mode.format == FORMAT_NTSC) ? 30000 : 25000;
1683 if (def_dem != sp->parm.capture.timeperframe.denominator)
1684 sp->parm.capture.timeperframe.numerator = def_num;
1685 else if (sp->parm.capture.timeperframe.numerator <= def_num)
1686 sp->parm.capture.timeperframe.numerator = def_num;
1687 else if (sp->parm.capture.timeperframe.numerator <= (def_num * 2)) {
1688 sp->parm.capture.timeperframe.numerator = def_num * 2;
1689 fdec = FDEC_2;
1690 } else if (sp->parm.capture.timeperframe.numerator <= (def_num * 3)) {
1691 sp->parm.capture.timeperframe.numerator = def_num * 3;
1692 fdec = FDEC_3;
1693 } else {
1694 sp->parm.capture.timeperframe.numerator = def_num * 5;
1695 fdec = FDEC_5;
1696 }
1697 fh->mode.fdec = fdec;
1698 sp->parm.capture.timeperframe.denominator = def_dem;
1699 s2255_set_mode(dev, fh->channel, &fh->mode);
1700 dprintk(4, "%s capture mode, %d timeperframe %d/%d, fdec %d\n",
1701 __func__,
1702 sp->parm.capture.capturemode,
1703 sp->parm.capture.timeperframe.numerator,
1704 sp->parm.capture.timeperframe.denominator, fdec);
Dean Anderson7d853532009-05-15 14:32:04 -03001705 return 0;
1706}
Dean Andersone6b44bc2010-03-08 20:04:48 -03001707
1708static int vidioc_enum_frameintervals(struct file *file, void *priv,
1709 struct v4l2_frmivalenum *fe)
1710{
1711 int is_ntsc = 0;
1712#define NUM_FRAME_ENUMS 4
1713 int frm_dec[NUM_FRAME_ENUMS] = {1, 2, 3, 5};
1714 if (fe->index < 0 || fe->index >= NUM_FRAME_ENUMS)
1715 return -EINVAL;
1716 switch (fe->width) {
1717 case 640:
1718 if (fe->height != 240 && fe->height != 480)
1719 return -EINVAL;
1720 is_ntsc = 1;
1721 break;
1722 case 320:
1723 if (fe->height != 240)
1724 return -EINVAL;
1725 is_ntsc = 1;
1726 break;
1727 case 704:
1728 if (fe->height != 288 && fe->height != 576)
1729 return -EINVAL;
1730 break;
1731 case 352:
1732 if (fe->height != 288)
1733 return -EINVAL;
1734 break;
1735 default:
1736 return -EINVAL;
1737 }
1738 fe->type = V4L2_FRMIVAL_TYPE_DISCRETE;
1739 fe->discrete.denominator = is_ntsc ? 30000 : 25000;
1740 fe->discrete.numerator = (is_ntsc ? 1001 : 1000) * frm_dec[fe->index];
1741 dprintk(4, "%s discrete %d/%d\n", __func__, fe->discrete.numerator,
1742 fe->discrete.denominator);
1743 return 0;
1744}
1745
Hans Verkuilbec43662008-12-30 06:58:20 -03001746static int s2255_open(struct file *file)
Dean Anderson38f993a2008-06-26 23:15:51 -03001747{
Laurent Pinchart63b0d5a2009-12-10 11:44:04 -02001748 struct video_device *vdev = video_devdata(file);
1749 struct s2255_dev *dev = video_drvdata(file);
Dean Anderson38f993a2008-06-26 23:15:51 -03001750 struct s2255_fh *fh;
Laurent Pinchart63b0d5a2009-12-10 11:44:04 -02001751 enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
Dean Anderson38f993a2008-06-26 23:15:51 -03001752 int i = 0;
1753 int cur_channel = -1;
Dean Anderson14d96262008-08-25 13:58:55 -03001754 int state;
Laurent Pinchart50462eb2009-12-10 11:47:13 -02001755 dprintk(1, "s2255: open called (dev=%s)\n",
1756 video_device_node_name(vdev));
Hans Verkuild56dc612008-07-30 08:43:36 -03001757 lock_kernel();
Dean Andersonff7e22d2010-04-08 23:38:07 -03001758 for (i = 0; i < MAX_CHANNELS; i++)
Laurent Pinchart63b0d5a2009-12-10 11:44:04 -02001759 if (dev->vdev[i] == vdev) {
1760 cur_channel = i;
1761 break;
1762 }
Dean Andersonff7e22d2010-04-08 23:38:07 -03001763 /*
1764 * open lock necessary to prevent multiple instances
1765 * of v4l-conf (or other programs) from simultaneously
1766 * reloading firmware.
1767 */
Dean Anderson38f993a2008-06-26 23:15:51 -03001768 mutex_lock(&dev->open_lock);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001769 state = atomic_read(&dev->fw_data->fw_state);
1770 switch (state) {
1771 case S2255_FW_DISCONNECTING:
1772 mutex_unlock(&dev->open_lock);
1773 unlock_kernel();
1774 return -ENODEV;
Dean Anderson14d96262008-08-25 13:58:55 -03001775 case S2255_FW_FAILED:
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03001776 s2255_dev_err(&dev->udev->dev,
1777 "firmware load failed. retrying.\n");
Dean Anderson14d96262008-08-25 13:58:55 -03001778 s2255_fwload_start(dev, 1);
Dean Anderson38f993a2008-06-26 23:15:51 -03001779 wait_event_timeout(dev->fw_data->wait_fw,
Dean Anderson14d96262008-08-25 13:58:55 -03001780 ((atomic_read(&dev->fw_data->fw_state)
1781 == S2255_FW_SUCCESS) ||
1782 (atomic_read(&dev->fw_data->fw_state)
1783 == S2255_FW_DISCONNECTING)),
Dean Anderson38f993a2008-06-26 23:15:51 -03001784 msecs_to_jiffies(S2255_LOAD_TIMEOUT));
Dean Andersonff7e22d2010-04-08 23:38:07 -03001785 /* state may have changed, re-read */
1786 state = atomic_read(&dev->fw_data->fw_state);
Dean Anderson14d96262008-08-25 13:58:55 -03001787 break;
1788 case S2255_FW_NOTLOADED:
1789 case S2255_FW_LOADED_DSPWAIT:
Dean Anderson38f993a2008-06-26 23:15:51 -03001790 /* give S2255_LOAD_TIMEOUT time for firmware to load in case
1791 driver loaded and then device immediately opened */
1792 printk(KERN_INFO "%s waiting for firmware load\n", __func__);
1793 wait_event_timeout(dev->fw_data->wait_fw,
Dean Anderson14d96262008-08-25 13:58:55 -03001794 ((atomic_read(&dev->fw_data->fw_state)
1795 == S2255_FW_SUCCESS) ||
1796 (atomic_read(&dev->fw_data->fw_state)
1797 == S2255_FW_DISCONNECTING)),
1798 msecs_to_jiffies(S2255_LOAD_TIMEOUT));
Dean Andersonff7e22d2010-04-08 23:38:07 -03001799 /* state may have changed, re-read */
1800 state = atomic_read(&dev->fw_data->fw_state);
Dean Anderson14d96262008-08-25 13:58:55 -03001801 break;
1802 case S2255_FW_SUCCESS:
1803 default:
1804 break;
1805 }
Dean Andersonff7e22d2010-04-08 23:38:07 -03001806 mutex_unlock(&dev->open_lock);
1807 /* state may have changed in above switch statement */
1808 switch (state) {
1809 case S2255_FW_SUCCESS:
1810 break;
1811 case S2255_FW_FAILED:
1812 printk(KERN_INFO "2255 firmware load failed.\n");
Dean Anderson14d96262008-08-25 13:58:55 -03001813 unlock_kernel();
Dean Andersonff7e22d2010-04-08 23:38:07 -03001814 return -ENODEV;
1815 case S2255_FW_DISCONNECTING:
1816 printk(KERN_INFO "%s: disconnecting\n", __func__);
1817 unlock_kernel();
1818 return -ENODEV;
1819 case S2255_FW_LOADED_DSPWAIT:
1820 case S2255_FW_NOTLOADED:
1821 printk(KERN_INFO "%s: firmware not loaded yet"
1822 "please try again later\n",
1823 __func__);
1824 unlock_kernel();
1825 return -EAGAIN;
1826 default:
1827 printk(KERN_INFO "%s: unknown state\n", __func__);
1828 unlock_kernel();
1829 return -EFAULT;
Dean Anderson38f993a2008-06-26 23:15:51 -03001830 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001831 /* allocate + initialize per filehandle data */
1832 fh = kzalloc(sizeof(*fh), GFP_KERNEL);
1833 if (NULL == fh) {
Hans Verkuild56dc612008-07-30 08:43:36 -03001834 unlock_kernel();
Dean Anderson38f993a2008-06-26 23:15:51 -03001835 return -ENOMEM;
1836 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001837 file->private_data = fh;
1838 fh->dev = dev;
1839 fh->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1840 fh->mode = dev->mode[cur_channel];
1841 fh->fmt = dev->cur_fmt[cur_channel];
1842 /* default 4CIF NTSC */
1843 fh->width = LINE_SZ_4CIFS_NTSC;
1844 fh->height = NUM_LINES_4CIFS_NTSC * 2;
1845 fh->channel = cur_channel;
Dean Anderson14d96262008-08-25 13:58:55 -03001846 /* configure channel to default state */
1847 if (!dev->chn_configured[cur_channel]) {
1848 s2255_set_mode(dev, cur_channel, &fh->mode);
1849 dev->chn_configured[cur_channel] = 1;
1850 }
Dean Andersonff7e22d2010-04-08 23:38:07 -03001851 dprintk(1, "s2255drv: open dev=%s type=%s\n",
1852 video_device_node_name(vdev), v4l2_type_names[type]);
Dean Anderson38f993a2008-06-26 23:15:51 -03001853 dprintk(2, "s2255drv: open: fh=0x%08lx, dev=0x%08lx, vidq=0x%08lx\n",
1854 (unsigned long)fh, (unsigned long)dev,
1855 (unsigned long)&dev->vidq[cur_channel]);
1856 dprintk(4, "s2255drv: open: list_empty active=%d\n",
1857 list_empty(&dev->vidq[cur_channel].active));
1858
1859 videobuf_queue_vmalloc_init(&fh->vb_vidq, &s2255_video_qops,
1860 NULL, &dev->slock,
1861 fh->type,
1862 V4L2_FIELD_INTERLACED,
1863 sizeof(struct s2255_buffer), fh);
Hans Verkuild56dc612008-07-30 08:43:36 -03001864 unlock_kernel();
Dean Anderson38f993a2008-06-26 23:15:51 -03001865 return 0;
1866}
1867
1868
1869static unsigned int s2255_poll(struct file *file,
1870 struct poll_table_struct *wait)
1871{
1872 struct s2255_fh *fh = file->private_data;
1873 int rc;
1874 dprintk(100, "%s\n", __func__);
1875
1876 if (V4L2_BUF_TYPE_VIDEO_CAPTURE != fh->type)
1877 return POLLERR;
1878
1879 rc = videobuf_poll_stream(file, &fh->vb_vidq, wait);
1880 return rc;
1881}
1882
1883static void s2255_destroy(struct kref *kref)
1884{
1885 struct s2255_dev *dev = to_s2255_dev(kref);
Dean Anderson38f993a2008-06-26 23:15:51 -03001886 /* board shutdown stops the read pipe if it is running */
1887 s2255_board_shutdown(dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03001888 /* make sure firmware still not trying to load */
Dean Andersonf78d92c2008-07-22 14:43:27 -03001889 del_timer(&dev->timer); /* only started in .probe and .open */
Dean Anderson38f993a2008-06-26 23:15:51 -03001890 if (dev->fw_data->fw_urb) {
1891 dprintk(2, "kill fw_urb\n");
1892 usb_kill_urb(dev->fw_data->fw_urb);
1893 usb_free_urb(dev->fw_data->fw_urb);
1894 dev->fw_data->fw_urb = NULL;
1895 }
Dean Andersonf78d92c2008-07-22 14:43:27 -03001896 if (dev->fw_data->fw)
1897 release_firmware(dev->fw_data->fw);
1898 kfree(dev->fw_data->pfw_data);
1899 kfree(dev->fw_data);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001900 /* reset the DSP so firmware can be reloaded next time */
1901 s2255_reset_dsppower(dev);
1902 mutex_destroy(&dev->open_lock);
1903 mutex_destroy(&dev->lock);
Dean Anderson38f993a2008-06-26 23:15:51 -03001904 usb_put_dev(dev->udev);
1905 dprintk(1, "%s", __func__);
Dean Andersonb7732a32009-03-30 11:59:56 -03001906 kfree(dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03001907}
1908
Dean Andersonff7e22d2010-04-08 23:38:07 -03001909static int s2255_release(struct file *file)
Dean Anderson38f993a2008-06-26 23:15:51 -03001910{
1911 struct s2255_fh *fh = file->private_data;
1912 struct s2255_dev *dev = fh->dev;
Laurent Pinchart50462eb2009-12-10 11:47:13 -02001913 struct video_device *vdev = video_devdata(file);
Dean Anderson38f993a2008-06-26 23:15:51 -03001914 if (!dev)
1915 return -ENODEV;
Dean Andersonf78d92c2008-07-22 14:43:27 -03001916 /* turn off stream */
1917 if (res_check(fh)) {
1918 if (dev->b_acquire[fh->channel])
1919 s2255_stop_acquire(dev, fh->channel);
1920 videobuf_streamoff(&fh->vb_vidq);
1921 res_free(dev, fh);
1922 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001923 videobuf_mmap_free(&fh->vb_vidq);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001924 dprintk(1, "%s (dev=%s)\n", __func__, video_device_node_name(vdev));
Dean Andersonf78d92c2008-07-22 14:43:27 -03001925 kfree(fh);
Dean Anderson38f993a2008-06-26 23:15:51 -03001926 return 0;
1927}
1928
1929static int s2255_mmap_v4l(struct file *file, struct vm_area_struct *vma)
1930{
1931 struct s2255_fh *fh = file->private_data;
1932 int ret;
1933
1934 if (!fh)
1935 return -ENODEV;
1936 dprintk(4, "mmap called, vma=0x%08lx\n", (unsigned long)vma);
1937
1938 ret = videobuf_mmap_mapper(&fh->vb_vidq, vma);
1939
1940 dprintk(4, "vma start=0x%08lx, size=%ld, ret=%d\n",
1941 (unsigned long)vma->vm_start,
1942 (unsigned long)vma->vm_end - (unsigned long)vma->vm_start, ret);
1943
1944 return ret;
1945}
1946
Hans Verkuilbec43662008-12-30 06:58:20 -03001947static const struct v4l2_file_operations s2255_fops_v4l = {
Dean Anderson38f993a2008-06-26 23:15:51 -03001948 .owner = THIS_MODULE,
1949 .open = s2255_open,
Dean Andersonff7e22d2010-04-08 23:38:07 -03001950 .release = s2255_release,
Dean Anderson38f993a2008-06-26 23:15:51 -03001951 .poll = s2255_poll,
1952 .ioctl = video_ioctl2, /* V4L2 ioctl handler */
Dean Anderson38f993a2008-06-26 23:15:51 -03001953 .mmap = s2255_mmap_v4l,
Dean Anderson38f993a2008-06-26 23:15:51 -03001954};
1955
Hans Verkuila3998102008-07-21 02:57:38 -03001956static const struct v4l2_ioctl_ops s2255_ioctl_ops = {
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001957 .vidioc_querymenu = vidioc_querymenu,
Dean Anderson38f993a2008-06-26 23:15:51 -03001958 .vidioc_querycap = vidioc_querycap,
1959 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
1960 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
1961 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
1962 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
1963 .vidioc_reqbufs = vidioc_reqbufs,
1964 .vidioc_querybuf = vidioc_querybuf,
1965 .vidioc_qbuf = vidioc_qbuf,
1966 .vidioc_dqbuf = vidioc_dqbuf,
1967 .vidioc_s_std = vidioc_s_std,
1968 .vidioc_enum_input = vidioc_enum_input,
1969 .vidioc_g_input = vidioc_g_input,
1970 .vidioc_s_input = vidioc_s_input,
1971 .vidioc_queryctrl = vidioc_queryctrl,
1972 .vidioc_g_ctrl = vidioc_g_ctrl,
1973 .vidioc_s_ctrl = vidioc_s_ctrl,
1974 .vidioc_streamon = vidioc_streamon,
1975 .vidioc_streamoff = vidioc_streamoff,
1976#ifdef CONFIG_VIDEO_V4L1_COMPAT
1977 .vidiocgmbuf = vidioc_cgmbuf,
1978#endif
Dean Anderson22b88d42008-08-29 15:33:19 -03001979 .vidioc_s_jpegcomp = vidioc_s_jpegcomp,
1980 .vidioc_g_jpegcomp = vidioc_g_jpegcomp,
Dean Anderson7d853532009-05-15 14:32:04 -03001981 .vidioc_s_parm = vidioc_s_parm,
1982 .vidioc_g_parm = vidioc_g_parm,
Dean Andersone6b44bc2010-03-08 20:04:48 -03001983 .vidioc_enum_frameintervals = vidioc_enum_frameintervals,
Hans Verkuila3998102008-07-21 02:57:38 -03001984};
1985
Dean Andersonff7e22d2010-04-08 23:38:07 -03001986static void s2255_video_device_release(struct video_device *vdev)
1987{
1988 struct s2255_dev *dev = video_get_drvdata(vdev);
1989 video_device_release(vdev);
1990 kref_put(&dev->kref, s2255_destroy);
1991 return;
1992}
1993
Hans Verkuila3998102008-07-21 02:57:38 -03001994static struct video_device template = {
1995 .name = "s2255v",
Hans Verkuila3998102008-07-21 02:57:38 -03001996 .fops = &s2255_fops_v4l,
1997 .ioctl_ops = &s2255_ioctl_ops,
Dean Andersonff7e22d2010-04-08 23:38:07 -03001998 .release = s2255_video_device_release,
Dean Anderson38f993a2008-06-26 23:15:51 -03001999 .tvnorms = S2255_NORMS,
2000 .current_norm = V4L2_STD_NTSC_M,
2001};
2002
2003static int s2255_probe_v4l(struct s2255_dev *dev)
2004{
2005 int ret;
2006 int i;
2007 int cur_nr = video_nr;
2008
2009 /* initialize all video 4 linux */
Dean Anderson38f993a2008-06-26 23:15:51 -03002010 /* register 4 video devices */
2011 for (i = 0; i < MAX_CHANNELS; i++) {
2012 INIT_LIST_HEAD(&dev->vidq[i].active);
2013 dev->vidq[i].dev = dev;
2014 dev->vidq[i].channel = i;
Dean Anderson38f993a2008-06-26 23:15:51 -03002015 /* register 4 video devices */
2016 dev->vdev[i] = video_device_alloc();
2017 memcpy(dev->vdev[i], &template, sizeof(struct video_device));
Hans Verkuil5e85e732008-07-20 06:31:39 -03002018 dev->vdev[i]->parent = &dev->interface->dev;
Laurent Pinchart63b0d5a2009-12-10 11:44:04 -02002019 video_set_drvdata(dev->vdev[i], dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03002020 if (video_nr == -1)
2021 ret = video_register_device(dev->vdev[i],
2022 VFL_TYPE_GRABBER,
2023 video_nr);
2024 else
2025 ret = video_register_device(dev->vdev[i],
2026 VFL_TYPE_GRABBER,
2027 cur_nr + i);
Hans Verkuil601e9442008-08-23 07:24:07 -03002028 video_set_drvdata(dev->vdev[i], dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03002029
2030 if (ret != 0) {
2031 dev_err(&dev->udev->dev,
2032 "failed to register video device!\n");
2033 return ret;
2034 }
2035 }
Dean Andersonabce21f2009-04-23 16:04:41 -03002036 printk(KERN_INFO "Sensoray 2255 V4L driver Revision: %d.%d\n",
2037 S2255_MAJOR_VERSION,
2038 S2255_MINOR_VERSION);
Dean Anderson38f993a2008-06-26 23:15:51 -03002039 return ret;
2040}
2041
Dean Anderson38f993a2008-06-26 23:15:51 -03002042/* this function moves the usb stream read pipe data
2043 * into the system buffers.
2044 * returns 0 on success, EAGAIN if more data to process( call this
2045 * function again).
2046 *
2047 * Received frame structure:
Dean Anderson14d96262008-08-25 13:58:55 -03002048 * bytes 0-3: marker : 0x2255DA4AL (S2255_MARKER_FRAME)
Dean Anderson38f993a2008-06-26 23:15:51 -03002049 * bytes 4-7: channel: 0-3
2050 * bytes 8-11: payload size: size of the frame
2051 * bytes 12-payloadsize+12: frame data
2052 */
2053static int save_frame(struct s2255_dev *dev, struct s2255_pipeinfo *pipe_info)
2054{
Dean Anderson38f993a2008-06-26 23:15:51 -03002055 char *pdest;
2056 u32 offset = 0;
Dean Anderson14d96262008-08-25 13:58:55 -03002057 int bframe = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03002058 char *psrc;
2059 unsigned long copy_size;
2060 unsigned long size;
2061 s32 idx = -1;
2062 struct s2255_framei *frm;
2063 unsigned char *pdata;
Dean Anderson14d96262008-08-25 13:58:55 -03002064
Dean Anderson38f993a2008-06-26 23:15:51 -03002065 dprintk(100, "buffer to user\n");
2066
2067 idx = dev->cur_frame[dev->cc];
Dean Anderson38f993a2008-06-26 23:15:51 -03002068 frm = &dev->buffer[dev->cc].frame[idx];
2069
Dean Anderson14d96262008-08-25 13:58:55 -03002070 if (frm->ulState == S2255_READ_IDLE) {
2071 int jj;
2072 unsigned int cc;
Dean Anderson3fa00602010-03-04 20:47:33 -03002073 __le32 *pdword; /*data from dsp is little endian */
Dean Anderson14d96262008-08-25 13:58:55 -03002074 int payload;
2075 /* search for marker codes */
2076 pdata = (unsigned char *)pipe_info->transfer_buffer;
Dean Anderson3fa00602010-03-04 20:47:33 -03002077 pdword = (__le32 *)pdata;
Dean Anderson14d96262008-08-25 13:58:55 -03002078 for (jj = 0; jj < (pipe_info->cur_transfer_size - 12); jj++) {
Dean Anderson3fa00602010-03-04 20:47:33 -03002079 switch (*pdword) {
Dean Anderson14d96262008-08-25 13:58:55 -03002080 case S2255_MARKER_FRAME:
Dean Anderson14d96262008-08-25 13:58:55 -03002081 dprintk(4, "found frame marker at offset:"
2082 " %d [%x %x]\n", jj, pdata[0],
2083 pdata[1]);
2084 offset = jj + PREFIX_SIZE;
2085 bframe = 1;
2086 cc = pdword[1];
2087 if (cc >= MAX_CHANNELS) {
2088 printk(KERN_ERR
2089 "bad channel\n");
2090 return -EINVAL;
2091 }
2092 /* reverse it */
2093 dev->cc = G_chnmap[cc];
2094 payload = pdword[3];
2095 if (payload > dev->req_image_size[dev->cc]) {
2096 dev->bad_payload[dev->cc]++;
2097 /* discard the bad frame */
2098 return -EINVAL;
2099 }
2100 dev->pkt_size[dev->cc] = payload;
2101 dev->jpg_size[dev->cc] = pdword[4];
2102 break;
2103 case S2255_MARKER_RESPONSE:
Dean Anderson14d96262008-08-25 13:58:55 -03002104 pdata += DEF_USB_BLOCK;
2105 jj += DEF_USB_BLOCK;
2106 if (pdword[1] >= MAX_CHANNELS)
2107 break;
2108 cc = G_chnmap[pdword[1]];
Roel Kluinf14a2972009-10-23 07:59:42 -03002109 if (cc >= MAX_CHANNELS)
Dean Anderson14d96262008-08-25 13:58:55 -03002110 break;
2111 switch (pdword[2]) {
Dean Andersonabce21f2009-04-23 16:04:41 -03002112 case S2255_RESPONSE_SETMODE:
Dean Anderson14d96262008-08-25 13:58:55 -03002113 /* check if channel valid */
2114 /* set mode ready */
2115 dev->setmode_ready[cc] = 1;
2116 wake_up(&dev->wait_setmode[cc]);
2117 dprintk(5, "setmode ready %d\n", cc);
2118 break;
Dean Andersonabce21f2009-04-23 16:04:41 -03002119 case S2255_RESPONSE_FW:
Dean Anderson14d96262008-08-25 13:58:55 -03002120
2121 dev->chn_ready |= (1 << cc);
2122 if ((dev->chn_ready & 0x0f) != 0x0f)
2123 break;
2124 /* all channels ready */
2125 printk(KERN_INFO "s2255: fw loaded\n");
2126 atomic_set(&dev->fw_data->fw_state,
2127 S2255_FW_SUCCESS);
2128 wake_up(&dev->fw_data->wait_fw);
2129 break;
Dean Anderson4de39f52010-03-03 19:39:19 -03002130 case S2255_RESPONSE_STATUS:
2131 dev->vidstatus[cc] = pdword[3];
2132 dev->vidstatus_ready[cc] = 1;
2133 wake_up(&dev->wait_vidstatus[cc]);
2134 dprintk(5, "got vidstatus %x chan %d\n",
2135 pdword[3], cc);
2136 break;
Dean Anderson14d96262008-08-25 13:58:55 -03002137 default:
André Goddard Rosaaf901ca2009-11-14 13:09:05 -02002138 printk(KERN_INFO "s2255 unknown resp\n");
Dean Anderson14d96262008-08-25 13:58:55 -03002139 }
2140 default:
2141 pdata++;
2142 break;
2143 }
2144 if (bframe)
2145 break;
2146 } /* for */
2147 if (!bframe)
2148 return -EINVAL;
2149 }
2150
2151
2152 idx = dev->cur_frame[dev->cc];
2153 frm = &dev->buffer[dev->cc].frame[idx];
2154
2155 /* search done. now find out if should be acquiring on this channel */
2156 if (!dev->b_acquire[dev->cc]) {
2157 /* we found a frame, but this channel is turned off */
2158 frm->ulState = S2255_READ_IDLE;
2159 return -EINVAL;
2160 }
2161
2162 if (frm->ulState == S2255_READ_IDLE) {
2163 frm->ulState = S2255_READ_FRAME;
Dean Anderson38f993a2008-06-26 23:15:51 -03002164 frm->cur_size = 0;
2165 }
2166
Dean Anderson14d96262008-08-25 13:58:55 -03002167 /* skip the marker 512 bytes (and offset if out of sync) */
2168 psrc = (u8 *)pipe_info->transfer_buffer + offset;
2169
Dean Anderson38f993a2008-06-26 23:15:51 -03002170
2171 if (frm->lpvbits == NULL) {
2172 dprintk(1, "s2255 frame buffer == NULL.%p %p %d %d",
2173 frm, dev, dev->cc, idx);
2174 return -ENOMEM;
2175 }
2176
2177 pdest = frm->lpvbits + frm->cur_size;
2178
Dean Anderson14d96262008-08-25 13:58:55 -03002179 copy_size = (pipe_info->cur_transfer_size - offset);
Dean Anderson38f993a2008-06-26 23:15:51 -03002180
Dean Anderson14d96262008-08-25 13:58:55 -03002181 size = dev->pkt_size[dev->cc] - PREFIX_SIZE;
Dean Anderson38f993a2008-06-26 23:15:51 -03002182
Dean Anderson14d96262008-08-25 13:58:55 -03002183 /* sanity check on pdest */
2184 if ((copy_size + frm->cur_size) < dev->req_image_size[dev->cc])
2185 memcpy(pdest, psrc, copy_size);
Dean Anderson38f993a2008-06-26 23:15:51 -03002186
Dean Anderson38f993a2008-06-26 23:15:51 -03002187 frm->cur_size += copy_size;
Dean Anderson14d96262008-08-25 13:58:55 -03002188 dprintk(4, "cur_size size %lu size %lu \n", frm->cur_size, size);
Dean Anderson38f993a2008-06-26 23:15:51 -03002189
Dean Anderson14d96262008-08-25 13:58:55 -03002190 if (frm->cur_size >= size) {
2191
Dean Anderson38f993a2008-06-26 23:15:51 -03002192 u32 cc = dev->cc;
Dean Anderson38f993a2008-06-26 23:15:51 -03002193 dprintk(2, "****************[%d]Buffer[%d]full*************\n",
2194 cc, idx);
2195 dev->last_frame[cc] = dev->cur_frame[cc];
2196 dev->cur_frame[cc]++;
2197 /* end of system frame ring buffer, start at zero */
2198 if ((dev->cur_frame[cc] == SYS_FRAMES) ||
2199 (dev->cur_frame[cc] == dev->buffer[cc].dwFrames))
2200 dev->cur_frame[cc] = 0;
Dean Anderson14d96262008-08-25 13:58:55 -03002201 /* frame ready */
Dean Anderson38f993a2008-06-26 23:15:51 -03002202 if (dev->b_acquire[cc])
Dean Anderson14d96262008-08-25 13:58:55 -03002203 s2255_got_frame(dev, cc, dev->jpg_size[cc]);
Dean Anderson38f993a2008-06-26 23:15:51 -03002204 dev->frame_count[cc]++;
Dean Anderson14d96262008-08-25 13:58:55 -03002205 frm->ulState = S2255_READ_IDLE;
2206 frm->cur_size = 0;
2207
Dean Anderson38f993a2008-06-26 23:15:51 -03002208 }
2209 /* done successfully */
2210 return 0;
2211}
2212
2213static void s2255_read_video_callback(struct s2255_dev *dev,
2214 struct s2255_pipeinfo *pipe_info)
2215{
2216 int res;
2217 dprintk(50, "callback read video \n");
2218
2219 if (dev->cc >= MAX_CHANNELS) {
2220 dev->cc = 0;
2221 dev_err(&dev->udev->dev, "invalid channel\n");
2222 return;
2223 }
2224 /* otherwise copy to the system buffers */
2225 res = save_frame(dev, pipe_info);
Dean Anderson14d96262008-08-25 13:58:55 -03002226 if (res != 0)
2227 dprintk(4, "s2255: read callback failed\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03002228
2229 dprintk(50, "callback read video done\n");
2230 return;
2231}
2232
2233static long s2255_vendor_req(struct s2255_dev *dev, unsigned char Request,
2234 u16 Index, u16 Value, void *TransferBuffer,
2235 s32 TransferBufferLength, int bOut)
2236{
2237 int r;
2238 if (!bOut) {
2239 r = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0),
2240 Request,
2241 USB_TYPE_VENDOR | USB_RECIP_DEVICE |
2242 USB_DIR_IN,
2243 Value, Index, TransferBuffer,
2244 TransferBufferLength, HZ * 5);
2245 } else {
2246 r = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0),
2247 Request, USB_TYPE_VENDOR | USB_RECIP_DEVICE,
2248 Value, Index, TransferBuffer,
2249 TransferBufferLength, HZ * 5);
2250 }
2251 return r;
2252}
2253
2254/*
2255 * retrieve FX2 firmware version. future use.
2256 * @param dev pointer to device extension
2257 * @return -1 for fail, else returns firmware version as an int(16 bits)
2258 */
2259static int s2255_get_fx2fw(struct s2255_dev *dev)
2260{
2261 int fw;
2262 int ret;
2263 unsigned char transBuffer[64];
2264 ret = s2255_vendor_req(dev, S2255_VR_FW, 0, 0, transBuffer, 2,
2265 S2255_VR_IN);
2266 if (ret < 0)
2267 dprintk(2, "get fw error: %x\n", ret);
2268 fw = transBuffer[0] + (transBuffer[1] << 8);
2269 dprintk(2, "Get FW %x %x\n", transBuffer[0], transBuffer[1]);
2270 return fw;
2271}
2272
2273/*
2274 * Create the system ring buffer to copy frames into from the
2275 * usb read pipe.
2276 */
2277static int s2255_create_sys_buffers(struct s2255_dev *dev, unsigned long chn)
2278{
2279 unsigned long i;
2280 unsigned long reqsize;
2281 dprintk(1, "create sys buffers\n");
2282 if (chn >= MAX_CHANNELS)
2283 return -1;
2284
2285 dev->buffer[chn].dwFrames = SYS_FRAMES;
2286
2287 /* always allocate maximum size(PAL) for system buffers */
2288 reqsize = SYS_FRAMES_MAXSIZE;
2289
2290 if (reqsize > SYS_FRAMES_MAXSIZE)
2291 reqsize = SYS_FRAMES_MAXSIZE;
2292
2293 for (i = 0; i < SYS_FRAMES; i++) {
2294 /* allocate the frames */
2295 dev->buffer[chn].frame[i].lpvbits = vmalloc(reqsize);
2296
2297 dprintk(1, "valloc %p chan %lu, idx %lu, pdata %p\n",
2298 &dev->buffer[chn].frame[i], chn, i,
2299 dev->buffer[chn].frame[i].lpvbits);
2300 dev->buffer[chn].frame[i].size = reqsize;
2301 if (dev->buffer[chn].frame[i].lpvbits == NULL) {
2302 printk(KERN_INFO "out of memory. using less frames\n");
2303 dev->buffer[chn].dwFrames = i;
2304 break;
2305 }
2306 }
2307
2308 /* make sure internal states are set */
2309 for (i = 0; i < SYS_FRAMES; i++) {
2310 dev->buffer[chn].frame[i].ulState = 0;
2311 dev->buffer[chn].frame[i].cur_size = 0;
2312 }
2313
2314 dev->cur_frame[chn] = 0;
2315 dev->last_frame[chn] = -1;
2316 return 0;
2317}
2318
2319static int s2255_release_sys_buffers(struct s2255_dev *dev,
2320 unsigned long channel)
2321{
2322 unsigned long i;
2323 dprintk(1, "release sys buffers\n");
2324 for (i = 0; i < SYS_FRAMES; i++) {
2325 if (dev->buffer[channel].frame[i].lpvbits) {
2326 dprintk(1, "vfree %p\n",
2327 dev->buffer[channel].frame[i].lpvbits);
2328 vfree(dev->buffer[channel].frame[i].lpvbits);
2329 }
2330 dev->buffer[channel].frame[i].lpvbits = NULL;
2331 }
2332 return 0;
2333}
2334
2335static int s2255_board_init(struct s2255_dev *dev)
2336{
2337 int j;
2338 struct s2255_mode mode_def = DEF_MODEI_NTSC_CONT;
2339 int fw_ver;
2340 dprintk(4, "board init: %p", dev);
2341
2342 for (j = 0; j < MAX_PIPE_BUFFERS; j++) {
2343 struct s2255_pipeinfo *pipe = &dev->pipes[j];
2344
2345 memset(pipe, 0, sizeof(*pipe));
2346 pipe->dev = dev;
Dean Anderson14d96262008-08-25 13:58:55 -03002347 pipe->cur_transfer_size = S2255_USB_XFER_SIZE;
2348 pipe->max_transfer_size = S2255_USB_XFER_SIZE;
Dean Anderson38f993a2008-06-26 23:15:51 -03002349
Dean Anderson38f993a2008-06-26 23:15:51 -03002350 pipe->transfer_buffer = kzalloc(pipe->max_transfer_size,
2351 GFP_KERNEL);
2352 if (pipe->transfer_buffer == NULL) {
2353 dprintk(1, "out of memory!\n");
2354 return -ENOMEM;
2355 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002356 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002357 /* query the firmware */
2358 fw_ver = s2255_get_fx2fw(dev);
2359
Dean Andersonabce21f2009-04-23 16:04:41 -03002360 printk(KERN_INFO "2255 usb firmware version %d.%d\n",
2361 (fw_ver >> 8) & 0xff,
2362 fw_ver & 0xff);
2363
2364 if (fw_ver < S2255_CUR_USB_FWVER)
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002365 dev_err(&dev->udev->dev,
Dean Andersonabce21f2009-04-23 16:04:41 -03002366 "usb firmware not up to date %d.%d\n",
2367 (fw_ver >> 8) & 0xff,
2368 fw_ver & 0xff);
Dean Anderson38f993a2008-06-26 23:15:51 -03002369
2370 for (j = 0; j < MAX_CHANNELS; j++) {
2371 dev->b_acquire[j] = 0;
2372 dev->mode[j] = mode_def;
Dean Anderson5a34d9d2010-03-05 19:59:48 -03002373 if (dev->pid == 0x2257 && j > 1)
2374 dev->mode[j].color |= (1 << 16);
Dean Anderson22b88d42008-08-29 15:33:19 -03002375 dev->jc[j].quality = S2255_DEF_JPEG_QUAL;
Dean Anderson38f993a2008-06-26 23:15:51 -03002376 dev->cur_fmt[j] = &formats[0];
2377 dev->mode[j].restart = 1;
2378 dev->req_image_size[j] = get_transfer_size(&mode_def);
2379 dev->frame_count[j] = 0;
2380 /* create the system buffers */
2381 s2255_create_sys_buffers(dev, j);
2382 }
2383 /* start read pipe */
2384 s2255_start_readpipe(dev);
2385
2386 dprintk(1, "S2255: board initialized\n");
2387 return 0;
2388}
2389
2390static int s2255_board_shutdown(struct s2255_dev *dev)
2391{
2392 u32 i;
Dean Anderson38f993a2008-06-26 23:15:51 -03002393 dprintk(1, "S2255: board shutdown: %p", dev);
2394
2395 for (i = 0; i < MAX_CHANNELS; i++) {
2396 if (dev->b_acquire[i])
2397 s2255_stop_acquire(dev, i);
2398 }
2399
2400 s2255_stop_readpipe(dev);
2401
2402 for (i = 0; i < MAX_CHANNELS; i++)
2403 s2255_release_sys_buffers(dev, i);
2404
2405 /* release transfer buffers */
2406 for (i = 0; i < MAX_PIPE_BUFFERS; i++) {
2407 struct s2255_pipeinfo *pipe = &dev->pipes[i];
2408 kfree(pipe->transfer_buffer);
2409 }
2410 return 0;
2411}
2412
2413static void read_pipe_completion(struct urb *purb)
2414{
2415 struct s2255_pipeinfo *pipe_info;
2416 struct s2255_dev *dev;
2417 int status;
2418 int pipe;
2419
2420 pipe_info = purb->context;
2421 dprintk(100, "read pipe completion %p, status %d\n", purb,
2422 purb->status);
2423 if (pipe_info == NULL) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002424 dev_err(&purb->dev->dev, "no context!\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03002425 return;
2426 }
2427
2428 dev = pipe_info->dev;
2429 if (dev == NULL) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002430 dev_err(&purb->dev->dev, "no context!\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03002431 return;
2432 }
2433 status = purb->status;
Dean Andersonb02064c2009-04-30 12:29:38 -03002434 /* if shutting down, do not resubmit, exit immediately */
2435 if (status == -ESHUTDOWN) {
2436 dprintk(2, "read_pipe_completion: err shutdown\n");
2437 pipe_info->err_count++;
Dean Anderson38f993a2008-06-26 23:15:51 -03002438 return;
2439 }
2440
2441 if (pipe_info->state == 0) {
2442 dprintk(2, "exiting USB pipe");
2443 return;
2444 }
2445
Dean Andersonb02064c2009-04-30 12:29:38 -03002446 if (status == 0)
2447 s2255_read_video_callback(dev, pipe_info);
2448 else {
2449 pipe_info->err_count++;
2450 dprintk(1, "s2255drv: failed URB %d\n", status);
2451 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002452
Dean Anderson38f993a2008-06-26 23:15:51 -03002453 pipe = usb_rcvbulkpipe(dev->udev, dev->read_endpoint);
2454 /* reuse urb */
2455 usb_fill_bulk_urb(pipe_info->stream_urb, dev->udev,
2456 pipe,
2457 pipe_info->transfer_buffer,
2458 pipe_info->cur_transfer_size,
2459 read_pipe_completion, pipe_info);
2460
2461 if (pipe_info->state != 0) {
2462 if (usb_submit_urb(pipe_info->stream_urb, GFP_KERNEL)) {
2463 dev_err(&dev->udev->dev, "error submitting urb\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03002464 }
2465 } else {
2466 dprintk(2, "read pipe complete state 0\n");
2467 }
2468 return;
2469}
2470
2471static int s2255_start_readpipe(struct s2255_dev *dev)
2472{
2473 int pipe;
2474 int retval;
2475 int i;
2476 struct s2255_pipeinfo *pipe_info = dev->pipes;
2477 pipe = usb_rcvbulkpipe(dev->udev, dev->read_endpoint);
2478 dprintk(2, "start pipe IN %d\n", dev->read_endpoint);
2479
2480 for (i = 0; i < MAX_PIPE_BUFFERS; i++) {
2481 pipe_info->state = 1;
Dean Andersonabce21f2009-04-23 16:04:41 -03002482 pipe_info->err_count = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03002483 pipe_info->stream_urb = usb_alloc_urb(0, GFP_KERNEL);
2484 if (!pipe_info->stream_urb) {
2485 dev_err(&dev->udev->dev,
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002486 "ReadStream: Unable to alloc URB\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03002487 return -ENOMEM;
2488 }
2489 /* transfer buffer allocated in board_init */
2490 usb_fill_bulk_urb(pipe_info->stream_urb, dev->udev,
2491 pipe,
2492 pipe_info->transfer_buffer,
2493 pipe_info->cur_transfer_size,
2494 read_pipe_completion, pipe_info);
2495
Dean Anderson38f993a2008-06-26 23:15:51 -03002496 dprintk(4, "submitting URB %p\n", pipe_info->stream_urb);
2497 retval = usb_submit_urb(pipe_info->stream_urb, GFP_KERNEL);
2498 if (retval) {
2499 printk(KERN_ERR "s2255: start read pipe failed\n");
2500 return retval;
2501 }
2502 }
2503
2504 return 0;
2505}
2506
2507/* starts acquisition process */
2508static int s2255_start_acquire(struct s2255_dev *dev, unsigned long chn)
2509{
2510 unsigned char *buffer;
2511 int res;
2512 unsigned long chn_rev;
2513 int j;
2514 if (chn >= MAX_CHANNELS) {
2515 dprintk(2, "start acquire failed, bad channel %lu\n", chn);
2516 return -1;
2517 }
2518
2519 chn_rev = G_chnmap[chn];
2520 dprintk(1, "S2255: start acquire %lu \n", chn);
2521
2522 buffer = kzalloc(512, GFP_KERNEL);
2523 if (buffer == NULL) {
2524 dev_err(&dev->udev->dev, "out of mem\n");
2525 return -ENOMEM;
2526 }
2527
2528 dev->last_frame[chn] = -1;
2529 dev->bad_payload[chn] = 0;
2530 dev->cur_frame[chn] = 0;
2531 for (j = 0; j < SYS_FRAMES; j++) {
2532 dev->buffer[chn].frame[j].ulState = 0;
2533 dev->buffer[chn].frame[j].cur_size = 0;
2534 }
2535
2536 /* send the start command */
Dean Anderson3fa00602010-03-04 20:47:33 -03002537 *(__le32 *) buffer = IN_DATA_TOKEN;
2538 *((__le32 *) buffer + 1) = (__le32) cpu_to_le32(chn_rev);
2539 *((__le32 *) buffer + 2) = CMD_START;
Dean Anderson38f993a2008-06-26 23:15:51 -03002540 res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
2541 if (res != 0)
2542 dev_err(&dev->udev->dev, "CMD_START error\n");
2543
2544 dprintk(2, "start acquire exit[%lu] %d \n", chn, res);
2545 kfree(buffer);
2546 return 0;
2547}
2548
2549static int s2255_stop_acquire(struct s2255_dev *dev, unsigned long chn)
2550{
2551 unsigned char *buffer;
2552 int res;
2553 unsigned long chn_rev;
Dean Anderson38f993a2008-06-26 23:15:51 -03002554 if (chn >= MAX_CHANNELS) {
2555 dprintk(2, "stop acquire failed, bad channel %lu\n", chn);
2556 return -1;
2557 }
2558 chn_rev = G_chnmap[chn];
Dean Anderson38f993a2008-06-26 23:15:51 -03002559 buffer = kzalloc(512, GFP_KERNEL);
2560 if (buffer == NULL) {
2561 dev_err(&dev->udev->dev, "out of mem\n");
2562 return -ENOMEM;
2563 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002564 /* send the stop command */
2565 dprintk(4, "stop acquire %lu\n", chn);
Dean Anderson3fa00602010-03-04 20:47:33 -03002566 *(__le32 *) buffer = IN_DATA_TOKEN;
2567 *((__le32 *) buffer + 1) = (__le32) cpu_to_le32(chn_rev);
2568 *((__le32 *) buffer + 2) = CMD_STOP;
Dean Anderson38f993a2008-06-26 23:15:51 -03002569 res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
2570
2571 if (res != 0)
2572 dev_err(&dev->udev->dev, "CMD_STOP error\n");
2573
2574 dprintk(4, "stop acquire: releasing states \n");
2575
2576 kfree(buffer);
2577 dev->b_acquire[chn] = 0;
2578
Dean Anderson14d96262008-08-25 13:58:55 -03002579 return res;
Dean Anderson38f993a2008-06-26 23:15:51 -03002580}
2581
2582static void s2255_stop_readpipe(struct s2255_dev *dev)
2583{
2584 int j;
Dean Anderson38f993a2008-06-26 23:15:51 -03002585 if (dev == NULL) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002586 s2255_dev_err(&dev->udev->dev, "invalid device\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03002587 return;
2588 }
2589 dprintk(4, "stop read pipe\n");
2590 for (j = 0; j < MAX_PIPE_BUFFERS; j++) {
2591 struct s2255_pipeinfo *pipe_info = &dev->pipes[j];
2592 if (pipe_info) {
2593 if (pipe_info->state == 0)
2594 continue;
2595 pipe_info->state = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03002596 }
2597 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002598 for (j = 0; j < MAX_PIPE_BUFFERS; j++) {
2599 struct s2255_pipeinfo *pipe_info = &dev->pipes[j];
2600 if (pipe_info->stream_urb) {
2601 /* cancel urb */
2602 usb_kill_urb(pipe_info->stream_urb);
2603 usb_free_urb(pipe_info->stream_urb);
2604 pipe_info->stream_urb = NULL;
2605 }
2606 }
2607 dprintk(2, "s2255 stop read pipe: %d\n", j);
2608 return;
2609}
2610
Dean Anderson14d96262008-08-25 13:58:55 -03002611static void s2255_fwload_start(struct s2255_dev *dev, int reset)
Dean Anderson38f993a2008-06-26 23:15:51 -03002612{
Dean Anderson14d96262008-08-25 13:58:55 -03002613 if (reset)
2614 s2255_reset_dsppower(dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03002615 dev->fw_data->fw_size = dev->fw_data->fw->size;
2616 atomic_set(&dev->fw_data->fw_state, S2255_FW_NOTLOADED);
2617 memcpy(dev->fw_data->pfw_data,
2618 dev->fw_data->fw->data, CHUNK_SIZE);
2619 dev->fw_data->fw_loaded = CHUNK_SIZE;
2620 usb_fill_bulk_urb(dev->fw_data->fw_urb, dev->udev,
2621 usb_sndbulkpipe(dev->udev, 2),
2622 dev->fw_data->pfw_data,
2623 CHUNK_SIZE, s2255_fwchunk_complete,
2624 dev->fw_data);
2625 mod_timer(&dev->timer, jiffies + HZ);
2626}
2627
2628/* standard usb probe function */
2629static int s2255_probe(struct usb_interface *interface,
2630 const struct usb_device_id *id)
2631{
2632 struct s2255_dev *dev = NULL;
2633 struct usb_host_interface *iface_desc;
2634 struct usb_endpoint_descriptor *endpoint;
2635 int i;
2636 int retval = -ENOMEM;
Dean Anderson14d96262008-08-25 13:58:55 -03002637 __le32 *pdata;
2638 int fw_size;
Dean Anderson38f993a2008-06-26 23:15:51 -03002639
2640 dprintk(2, "s2255: probe\n");
2641
2642 /* allocate memory for our device state and initialize it to zero */
2643 dev = kzalloc(sizeof(struct s2255_dev), GFP_KERNEL);
2644 if (dev == NULL) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002645 s2255_dev_err(&interface->dev, "out of memory\n");
Dean Andersonff7e22d2010-04-08 23:38:07 -03002646 return -ENOMEM;
Dean Anderson38f993a2008-06-26 23:15:51 -03002647 }
Dean Andersonff7e22d2010-04-08 23:38:07 -03002648 kref_init(&dev->kref);
Dean Anderson5a34d9d2010-03-05 19:59:48 -03002649 dev->pid = id->idProduct;
Dean Anderson38f993a2008-06-26 23:15:51 -03002650 dev->fw_data = kzalloc(sizeof(struct s2255_fw), GFP_KERNEL);
2651 if (!dev->fw_data)
Dean Andersonff7e22d2010-04-08 23:38:07 -03002652 goto errorFWDATA1;
Dean Anderson38f993a2008-06-26 23:15:51 -03002653 mutex_init(&dev->lock);
2654 mutex_init(&dev->open_lock);
Dean Anderson38f993a2008-06-26 23:15:51 -03002655 /* grab usb_device and save it */
2656 dev->udev = usb_get_dev(interface_to_usbdev(interface));
2657 if (dev->udev == NULL) {
2658 dev_err(&interface->dev, "null usb device\n");
2659 retval = -ENODEV;
Dean Andersonff7e22d2010-04-08 23:38:07 -03002660 goto errorUDEV;
Dean Anderson38f993a2008-06-26 23:15:51 -03002661 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002662 dprintk(1, "dev: %p, kref: %p udev %p interface %p\n", dev, &dev->kref,
2663 dev->udev, interface);
2664 dev->interface = interface;
2665 /* set up the endpoint information */
2666 iface_desc = interface->cur_altsetting;
2667 dprintk(1, "num endpoints %d\n", iface_desc->desc.bNumEndpoints);
2668 for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
2669 endpoint = &iface_desc->endpoint[i].desc;
2670 if (!dev->read_endpoint && usb_endpoint_is_bulk_in(endpoint)) {
2671 /* we found the bulk in endpoint */
2672 dev->read_endpoint = endpoint->bEndpointAddress;
2673 }
2674 }
2675
2676 if (!dev->read_endpoint) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002677 dev_err(&interface->dev, "Could not find bulk-in endpoint\n");
Dean Andersonff7e22d2010-04-08 23:38:07 -03002678 goto errorEP;
Dean Anderson38f993a2008-06-26 23:15:51 -03002679 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002680 /* set intfdata */
2681 usb_set_intfdata(interface, dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03002682 dprintk(100, "after intfdata %p\n", dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03002683 init_timer(&dev->timer);
2684 dev->timer.function = s2255_timer;
2685 dev->timer.data = (unsigned long)dev->fw_data;
2686
2687 init_waitqueue_head(&dev->fw_data->wait_fw);
Dean Anderson4de39f52010-03-03 19:39:19 -03002688 for (i = 0; i < MAX_CHANNELS; i++) {
Dean Anderson14d96262008-08-25 13:58:55 -03002689 init_waitqueue_head(&dev->wait_setmode[i]);
Dean Anderson4de39f52010-03-03 19:39:19 -03002690 init_waitqueue_head(&dev->wait_vidstatus[i]);
2691 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002692
2693 dev->fw_data->fw_urb = usb_alloc_urb(0, GFP_KERNEL);
Dean Anderson38f993a2008-06-26 23:15:51 -03002694 if (!dev->fw_data->fw_urb) {
2695 dev_err(&interface->dev, "out of memory!\n");
Dean Andersonff7e22d2010-04-08 23:38:07 -03002696 goto errorFWURB;
Dean Anderson38f993a2008-06-26 23:15:51 -03002697 }
Dean Andersonff7e22d2010-04-08 23:38:07 -03002698
Dean Anderson38f993a2008-06-26 23:15:51 -03002699 dev->fw_data->pfw_data = kzalloc(CHUNK_SIZE, GFP_KERNEL);
2700 if (!dev->fw_data->pfw_data) {
2701 dev_err(&interface->dev, "out of memory!\n");
Dean Andersonff7e22d2010-04-08 23:38:07 -03002702 goto errorFWDATA2;
Dean Anderson38f993a2008-06-26 23:15:51 -03002703 }
2704 /* load the first chunk */
2705 if (request_firmware(&dev->fw_data->fw,
2706 FIRMWARE_FILE_NAME, &dev->udev->dev)) {
2707 printk(KERN_ERR "sensoray 2255 failed to get firmware\n");
Dean Andersonff7e22d2010-04-08 23:38:07 -03002708 goto errorREQFW;
Dean Anderson38f993a2008-06-26 23:15:51 -03002709 }
Dean Anderson14d96262008-08-25 13:58:55 -03002710 /* check the firmware is valid */
2711 fw_size = dev->fw_data->fw->size;
2712 pdata = (__le32 *) &dev->fw_data->fw->data[fw_size - 8];
Dean Anderson38f993a2008-06-26 23:15:51 -03002713
Dean Anderson14d96262008-08-25 13:58:55 -03002714 if (*pdata != S2255_FW_MARKER) {
2715 printk(KERN_INFO "Firmware invalid.\n");
2716 retval = -ENODEV;
Dean Andersonff7e22d2010-04-08 23:38:07 -03002717 goto errorFWMARKER;
Dean Anderson14d96262008-08-25 13:58:55 -03002718 } else {
2719 /* make sure firmware is the latest */
2720 __le32 *pRel;
2721 pRel = (__le32 *) &dev->fw_data->fw->data[fw_size - 4];
2722 printk(KERN_INFO "s2255 dsp fw version %x\n", *pRel);
Dean Anderson4de39f52010-03-03 19:39:19 -03002723 dev->dsp_fw_ver = *pRel;
2724 if (*pRel < S2255_CUR_DSP_FWVER)
2725 printk(KERN_INFO "s2255: f2255usb.bin out of date.\n");
Dean Anderson5a34d9d2010-03-05 19:59:48 -03002726 if (dev->pid == 0x2257 && *pRel < S2255_MIN_DSP_COLORFILTER)
Dean Andersonff7e22d2010-04-08 23:38:07 -03002727 printk(KERN_WARNING "s2255: 2257 requires firmware %d"
2728 "or above.\n", S2255_MIN_DSP_COLORFILTER);
Dean Anderson14d96262008-08-25 13:58:55 -03002729 }
Dean Anderson14d96262008-08-25 13:58:55 -03002730 usb_reset_device(dev->udev);
Dean Anderson38f993a2008-06-26 23:15:51 -03002731 /* load 2255 board specific */
Dean Andersonabce21f2009-04-23 16:04:41 -03002732 retval = s2255_board_init(dev);
2733 if (retval)
Dean Andersonff7e22d2010-04-08 23:38:07 -03002734 goto errorBOARDINIT;
Dean Anderson38f993a2008-06-26 23:15:51 -03002735 dprintk(4, "before probe done %p\n", dev);
2736 spin_lock_init(&dev->slock);
Dean Anderson14d96262008-08-25 13:58:55 -03002737 s2255_fwload_start(dev, 0);
Dean Andersonff7e22d2010-04-08 23:38:07 -03002738 /* kref for each vdev. Released on video_device_release callback */
2739 for (i = 0; i < MAX_CHANNELS; i++)
2740 kref_get(&dev->kref);
2741 /* loads v4l specific */
2742 retval = s2255_probe_v4l(dev);
2743 if (retval)
2744 goto errorV4L;
Dean Anderson38f993a2008-06-26 23:15:51 -03002745 dev_info(&interface->dev, "Sensoray 2255 detected\n");
2746 return 0;
Dean Andersonff7e22d2010-04-08 23:38:07 -03002747errorV4L:
2748 for (i = 0; i < MAX_CHANNELS; i++)
2749 if (dev->vdev[i] && video_is_registered(dev->vdev[i]))
2750 video_unregister_device(dev->vdev[i]);
2751errorBOARDINIT:
2752 s2255_board_shutdown(dev);
2753errorFWMARKER:
2754 release_firmware(dev->fw_data->fw);
2755errorREQFW:
2756 kfree(dev->fw_data->pfw_data);
2757errorFWDATA2:
2758 usb_free_urb(dev->fw_data->fw_urb);
2759errorFWURB:
2760 del_timer(&dev->timer);
2761errorEP:
2762 usb_put_dev(dev->udev);
2763errorUDEV:
2764 kfree(dev->fw_data);
2765 mutex_destroy(&dev->open_lock);
2766 mutex_destroy(&dev->lock);
2767errorFWDATA1:
2768 kfree(dev);
2769 printk(KERN_WARNING "Sensoray 2255 driver load failed: 0x%x\n", retval);
Dean Anderson38f993a2008-06-26 23:15:51 -03002770 return retval;
2771}
2772
Dean Andersonff7e22d2010-04-08 23:38:07 -03002773
Dean Anderson38f993a2008-06-26 23:15:51 -03002774/* disconnect routine. when board is removed physically or with rmmod */
2775static void s2255_disconnect(struct usb_interface *interface)
2776{
2777 struct s2255_dev *dev = NULL;
Dean Anderson14d96262008-08-25 13:58:55 -03002778 int i;
Dean Anderson38f993a2008-06-26 23:15:51 -03002779 dprintk(1, "s2255: disconnect interface %p\n", interface);
2780 dev = usb_get_intfdata(interface);
Dean Andersonff7e22d2010-04-08 23:38:07 -03002781 /* unregister each video device. */
2782 for (i = 0; i < MAX_CHANNELS; i++)
2783 if (video_is_registered(dev->vdev[i]))
2784 video_unregister_device(dev->vdev[i]);
2785 /* wake up any of our timers */
Dean Anderson14d96262008-08-25 13:58:55 -03002786 atomic_set(&dev->fw_data->fw_state, S2255_FW_DISCONNECTING);
2787 wake_up(&dev->fw_data->wait_fw);
2788 for (i = 0; i < MAX_CHANNELS; i++) {
2789 dev->setmode_ready[i] = 1;
2790 wake_up(&dev->wait_setmode[i]);
Dean Anderson4de39f52010-03-03 19:39:19 -03002791 dev->vidstatus_ready[i] = 1;
2792 wake_up(&dev->wait_vidstatus[i]);
Dean Anderson14d96262008-08-25 13:58:55 -03002793 }
Dean Anderson14d96262008-08-25 13:58:55 -03002794 usb_set_intfdata(interface, NULL);
Dean Andersonff7e22d2010-04-08 23:38:07 -03002795 kref_put(&dev->kref, s2255_destroy);
2796 dev_info(&interface->dev, "%s\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03002797}
2798
2799static struct usb_driver s2255_driver = {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002800 .name = S2255_DRIVER_NAME,
Dean Anderson38f993a2008-06-26 23:15:51 -03002801 .probe = s2255_probe,
2802 .disconnect = s2255_disconnect,
2803 .id_table = s2255_table,
2804};
2805
2806static int __init usb_s2255_init(void)
2807{
2808 int result;
Dean Anderson38f993a2008-06-26 23:15:51 -03002809 /* register this driver with the USB subsystem */
2810 result = usb_register(&s2255_driver);
Dean Anderson38f993a2008-06-26 23:15:51 -03002811 if (result)
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002812 pr_err(KBUILD_MODNAME
Dean Andersonff7e22d2010-04-08 23:38:07 -03002813 ": usb_register failed. Error number %d\n", result);
2814 dprintk(2, "%s\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03002815 return result;
2816}
2817
2818static void __exit usb_s2255_exit(void)
2819{
2820 usb_deregister(&s2255_driver);
2821}
2822
2823module_init(usb_s2255_init);
2824module_exit(usb_s2255_exit);
2825
2826MODULE_DESCRIPTION("Sensoray 2255 Video for Linux driver");
2827MODULE_AUTHOR("Dean Anderson (Sensoray Company Inc.)");
2828MODULE_LICENSE("GPL");