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