blob: 561909b65ce6b7b083dcad61e71afcbdae45a9de [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>
Dean Anderson38f993a2008-06-26 23:15:51 -030052#include <media/videobuf-vmalloc.h>
53#include <media/v4l2-common.h>
Dean Anderson3a67b5cc2010-04-08 23:52:20 -030054#include <media/v4l2-device.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
Dean Anderson85b85482010-04-08 23:51:17 -030059#define S2255_MAJOR_VERSION 1
sensoray-dev752eb7a2011-01-19 17:41:45 -030060#define S2255_MINOR_VERSION 21
Dean Anderson85b85482010-04-08 23:51:17 -030061#define S2255_RELEASE 0
62#define S2255_VERSION KERNEL_VERSION(S2255_MAJOR_VERSION, \
63 S2255_MINOR_VERSION, \
64 S2255_RELEASE)
Dean Anderson38f993a2008-06-26 23:15:51 -030065#define FIRMWARE_FILE_NAME "f2255usb.bin"
66
Dean Anderson22b88d42008-08-29 15:33:19 -030067/* default JPEG quality */
68#define S2255_DEF_JPEG_QUAL 50
Dean Anderson38f993a2008-06-26 23:15:51 -030069/* vendor request in */
70#define S2255_VR_IN 0
71/* vendor request out */
72#define S2255_VR_OUT 1
73/* firmware query */
74#define S2255_VR_FW 0x30
75/* USB endpoint number for configuring the device */
76#define S2255_CONFIG_EP 2
77/* maximum time for DSP to start responding after last FW word loaded(ms) */
Dean Anderson14d96262008-08-25 13:58:55 -030078#define S2255_DSP_BOOTTIME 800
Dean Anderson38f993a2008-06-26 23:15:51 -030079/* maximum time to wait for firmware to load (ms) */
Dean Anderson3f8d6f72008-06-30 21:28:34 -030080#define S2255_LOAD_TIMEOUT (5000 + S2255_DSP_BOOTTIME)
Dean Anderson38f993a2008-06-26 23:15:51 -030081#define S2255_DEF_BUFS 16
Dean Anderson14d96262008-08-25 13:58:55 -030082#define S2255_SETMODE_TIMEOUT 500
Dean Anderson4de39f52010-03-03 19:39:19 -030083#define S2255_VIDSTATUS_TIMEOUT 350
Dean Anderson3fa00602010-03-04 20:47:33 -030084#define S2255_MARKER_FRAME cpu_to_le32(0x2255DA4AL)
85#define S2255_MARKER_RESPONSE cpu_to_le32(0x2255ACACL)
86#define S2255_RESPONSE_SETMODE cpu_to_le32(0x01)
87#define S2255_RESPONSE_FW cpu_to_le32(0x10)
88#define S2255_RESPONSE_STATUS cpu_to_le32(0x20)
Dean Anderson14d96262008-08-25 13:58:55 -030089#define S2255_USB_XFER_SIZE (16 * 1024)
Dean Anderson38f993a2008-06-26 23:15:51 -030090#define MAX_CHANNELS 4
Dean Anderson38f993a2008-06-26 23:15:51 -030091#define SYS_FRAMES 4
92/* maximum size is PAL full size plus room for the marker header(s) */
Dean Anderson14d96262008-08-25 13:58:55 -030093#define SYS_FRAMES_MAXSIZE (720*288*2*2 + 4096)
94#define DEF_USB_BLOCK S2255_USB_XFER_SIZE
Dean Anderson38f993a2008-06-26 23:15:51 -030095#define LINE_SZ_4CIFS_NTSC 640
96#define LINE_SZ_2CIFS_NTSC 640
97#define LINE_SZ_1CIFS_NTSC 320
98#define LINE_SZ_4CIFS_PAL 704
99#define LINE_SZ_2CIFS_PAL 704
100#define LINE_SZ_1CIFS_PAL 352
101#define NUM_LINES_4CIFS_NTSC 240
102#define NUM_LINES_2CIFS_NTSC 240
103#define NUM_LINES_1CIFS_NTSC 240
104#define NUM_LINES_4CIFS_PAL 288
105#define NUM_LINES_2CIFS_PAL 288
106#define NUM_LINES_1CIFS_PAL 288
107#define LINE_SZ_DEF 640
108#define NUM_LINES_DEF 240
109
110
111/* predefined settings */
112#define FORMAT_NTSC 1
113#define FORMAT_PAL 2
114
115#define SCALE_4CIFS 1 /* 640x480(NTSC) or 704x576(PAL) */
116#define SCALE_2CIFS 2 /* 640x240(NTSC) or 704x288(PAL) */
117#define SCALE_1CIFS 3 /* 320x240(NTSC) or 352x288(PAL) */
Dean Anderson7d853532009-05-15 14:32:04 -0300118/* SCALE_4CIFSI is the 2 fields interpolated into one */
119#define SCALE_4CIFSI 4 /* 640x480(NTSC) or 704x576(PAL) high quality */
Dean Anderson38f993a2008-06-26 23:15:51 -0300120
121#define COLOR_YUVPL 1 /* YUV planar */
122#define COLOR_YUVPK 2 /* YUV packed */
123#define COLOR_Y8 4 /* monochrome */
Dean Anderson14d96262008-08-25 13:58:55 -0300124#define COLOR_JPG 5 /* JPEG */
Dean Anderson38f993a2008-06-26 23:15:51 -0300125
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300126#define MASK_COLOR 0x000000ff
127#define MASK_JPG_QUALITY 0x0000ff00
128#define MASK_INPUT_TYPE 0x000f0000
Dean Anderson38f993a2008-06-26 23:15:51 -0300129/* frame decimation. Not implemented by V4L yet(experimental in V4L) */
130#define FDEC_1 1 /* capture every frame. default */
131#define FDEC_2 2 /* capture every 2nd frame */
132#define FDEC_3 3 /* capture every 3rd frame */
133#define FDEC_5 5 /* capture every 5th frame */
134
135/*-------------------------------------------------------
136 * Default mode parameters.
137 *-------------------------------------------------------*/
138#define DEF_SCALE SCALE_4CIFS
139#define DEF_COLOR COLOR_YUVPL
140#define DEF_FDEC FDEC_1
141#define DEF_BRIGHT 0
142#define DEF_CONTRAST 0x5c
143#define DEF_SATURATION 0x80
144#define DEF_HUE 0
145
146/* usb config commands */
Dean Anderson3fa00602010-03-04 20:47:33 -0300147#define IN_DATA_TOKEN cpu_to_le32(0x2255c0de)
148#define CMD_2255 cpu_to_le32(0xc2255000)
149#define CMD_SET_MODE cpu_to_le32((CMD_2255 | 0x10))
150#define CMD_START cpu_to_le32((CMD_2255 | 0x20))
151#define CMD_STOP cpu_to_le32((CMD_2255 | 0x30))
152#define CMD_STATUS cpu_to_le32((CMD_2255 | 0x40))
Dean Anderson38f993a2008-06-26 23:15:51 -0300153
154struct s2255_mode {
155 u32 format; /* input video format (NTSC, PAL) */
156 u32 scale; /* output video scale */
157 u32 color; /* output video color format */
158 u32 fdec; /* frame decimation */
159 u32 bright; /* brightness */
160 u32 contrast; /* contrast */
161 u32 saturation; /* saturation */
162 u32 hue; /* hue (NTSC only)*/
163 u32 single; /* capture 1 frame at a time (!=0), continuously (==0)*/
164 u32 usb_block; /* block size. should be 4096 of DEF_USB_BLOCK */
165 u32 restart; /* if DSP requires restart */
166};
167
Dean Anderson14d96262008-08-25 13:58:55 -0300168
169#define S2255_READ_IDLE 0
170#define S2255_READ_FRAME 1
171
Dean Anderson38f993a2008-06-26 23:15:51 -0300172/* frame structure */
Dean Anderson38f993a2008-06-26 23:15:51 -0300173struct s2255_framei {
174 unsigned long size;
Dean Anderson14d96262008-08-25 13:58:55 -0300175 unsigned long ulState; /* ulState:S2255_READ_IDLE, S2255_READ_FRAME*/
Dean Anderson38f993a2008-06-26 23:15:51 -0300176 void *lpvbits; /* image data */
177 unsigned long cur_size; /* current data copied to it */
178};
179
180/* image buffer structure */
181struct s2255_bufferi {
182 unsigned long dwFrames; /* number of frames in buffer */
183 struct s2255_framei frame[SYS_FRAMES]; /* array of FRAME structures */
184};
185
186#define DEF_MODEI_NTSC_CONT {FORMAT_NTSC, DEF_SCALE, DEF_COLOR, \
187 DEF_FDEC, DEF_BRIGHT, DEF_CONTRAST, DEF_SATURATION, \
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300188 DEF_HUE, 0, DEF_USB_BLOCK, 0}
Dean Anderson38f993a2008-06-26 23:15:51 -0300189
190struct s2255_dmaqueue {
191 struct list_head active;
Dean Anderson38f993a2008-06-26 23:15:51 -0300192 struct s2255_dev *dev;
Dean Anderson38f993a2008-06-26 23:15:51 -0300193};
194
195/* for firmware loading, fw_state */
196#define S2255_FW_NOTLOADED 0
197#define S2255_FW_LOADED_DSPWAIT 1
198#define S2255_FW_SUCCESS 2
199#define S2255_FW_FAILED 3
Dean Andersonf78d92c2008-07-22 14:43:27 -0300200#define S2255_FW_DISCONNECTING 4
Harvey Harrisondeaf53e2008-11-15 01:10:14 -0300201#define S2255_FW_MARKER cpu_to_le32(0x22552f2f)
Dean Anderson14d96262008-08-25 13:58:55 -0300202/* 2255 read states */
203#define S2255_READ_IDLE 0
204#define S2255_READ_FRAME 1
Dean Anderson38f993a2008-06-26 23:15:51 -0300205struct s2255_fw {
206 int fw_loaded;
207 int fw_size;
208 struct urb *fw_urb;
209 atomic_t fw_state;
210 void *pfw_data;
211 wait_queue_head_t wait_fw;
Dean Anderson38f993a2008-06-26 23:15:51 -0300212 const struct firmware *fw;
213};
214
215struct s2255_pipeinfo {
216 u32 max_transfer_size;
217 u32 cur_transfer_size;
218 u8 *transfer_buffer;
Dean Anderson38f993a2008-06-26 23:15:51 -0300219 u32 state;
Dean Anderson38f993a2008-06-26 23:15:51 -0300220 void *stream_urb;
221 void *dev; /* back pointer to s2255_dev struct*/
222 u32 err_count;
Dean Anderson38f993a2008-06-26 23:15:51 -0300223 u32 idx;
Dean Anderson38f993a2008-06-26 23:15:51 -0300224};
225
226struct s2255_fmt; /*forward declaration */
Dean Andersonfe85ce92010-06-01 19:12:07 -0300227struct s2255_dev;
228
229struct s2255_channel {
230 struct video_device vdev;
231 int resources;
232 struct s2255_dmaqueue vidq;
233 struct s2255_bufferi buffer;
234 struct s2255_mode mode;
235 /* jpeg compression */
236 struct v4l2_jpegcompression jc;
237 /* capture parameters (for high quality mode full size) */
238 struct v4l2_captureparm cap_parm;
239 int cur_frame;
240 int last_frame;
241
242 int b_acquire;
243 /* allocated image size */
244 unsigned long req_image_size;
245 /* received packet size */
246 unsigned long pkt_size;
247 int bad_payload;
248 unsigned long frame_count;
249 /* if JPEG image */
250 int jpg_size;
251 /* if channel configured to default state */
252 int configured;
253 wait_queue_head_t wait_setmode;
254 int setmode_ready;
255 /* video status items */
256 int vidstatus;
257 wait_queue_head_t wait_vidstatus;
258 int vidstatus_ready;
259 unsigned int width;
260 unsigned int height;
261 const struct s2255_fmt *fmt;
262 int idx; /* channel number on device, 0-3 */
263};
264
Dean Anderson38f993a2008-06-26 23:15:51 -0300265
266struct s2255_dev {
Dean Andersonfe85ce92010-06-01 19:12:07 -0300267 struct s2255_channel channel[MAX_CHANNELS];
Dean Anderson65c6edb2010-04-20 17:21:32 -0300268 struct v4l2_device v4l2_dev;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300269 atomic_t num_channels;
Dean Anderson38f993a2008-06-26 23:15:51 -0300270 int frames;
Pete Eberleina19a5cd2010-12-20 19:18:59 -0300271 struct mutex lock; /* channels[].vdev.lock */
Dean Anderson38f993a2008-06-26 23:15:51 -0300272 struct mutex open_lock;
Dean Anderson38f993a2008-06-26 23:15:51 -0300273 struct usb_device *udev;
274 struct usb_interface *interface;
275 u8 read_endpoint;
Dean Anderson38f993a2008-06-26 23:15:51 -0300276 struct timer_list timer;
277 struct s2255_fw *fw_data;
Dean Andersonab85c6a2010-04-08 23:39:12 -0300278 struct s2255_pipeinfo pipe;
Dean Anderson38f993a2008-06-26 23:15:51 -0300279 u32 cc; /* current channel */
Dean Anderson38f993a2008-06-26 23:15:51 -0300280 int frame_ready;
Dean Anderson14d96262008-08-25 13:58:55 -0300281 int chn_ready;
Dean Anderson38f993a2008-06-26 23:15:51 -0300282 spinlock_t slock;
Dean Anderson4de39f52010-03-03 19:39:19 -0300283 /* dsp firmware version (f2255usb.bin) */
284 int dsp_fw_ver;
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300285 u16 pid; /* product id */
Dean Anderson38f993a2008-06-26 23:15:51 -0300286};
Dean Anderson65c6edb2010-04-20 17:21:32 -0300287
Dean Anderson65c6edb2010-04-20 17:21:32 -0300288static inline struct s2255_dev *to_s2255_dev(struct v4l2_device *v4l2_dev)
289{
290 return container_of(v4l2_dev, struct s2255_dev, v4l2_dev);
291}
Dean Anderson38f993a2008-06-26 23:15:51 -0300292
293struct s2255_fmt {
294 char *name;
295 u32 fourcc;
296 int depth;
297};
298
299/* buffer for one video frame */
300struct s2255_buffer {
301 /* common v4l buffer stuff -- must be first */
302 struct videobuf_buffer vb;
303 const struct s2255_fmt *fmt;
304};
305
306struct s2255_fh {
307 struct s2255_dev *dev;
Dean Anderson38f993a2008-06-26 23:15:51 -0300308 struct videobuf_queue vb_vidq;
309 enum v4l2_buf_type type;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300310 struct s2255_channel *channel;
311 int resources;
Dean Anderson38f993a2008-06-26 23:15:51 -0300312};
313
Dean Andersonabce21f2009-04-23 16:04:41 -0300314/* current cypress EEPROM firmware version */
sensoray-dev752eb7a2011-01-19 17:41:45 -0300315#define S2255_CUR_USB_FWVER ((3 << 8) | 11)
Dean Anderson4de39f52010-03-03 19:39:19 -0300316/* current DSP FW version */
sensoray-dev752eb7a2011-01-19 17:41:45 -0300317#define S2255_CUR_DSP_FWVER 10102
Dean Anderson4de39f52010-03-03 19:39:19 -0300318/* Need DSP version 5+ for video status feature */
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300319#define S2255_MIN_DSP_STATUS 5
320#define S2255_MIN_DSP_COLORFILTER 8
Dean Anderson38f993a2008-06-26 23:15:51 -0300321#define S2255_NORMS (V4L2_STD_PAL | V4L2_STD_NTSC)
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300322
323/* private V4L2 controls */
324
325/*
326 * The following chart displays how COLORFILTER should be set
327 * =========================================================
328 * = fourcc = COLORFILTER =
329 * = ===============================
330 * = = 0 = 1 =
331 * =========================================================
332 * = V4L2_PIX_FMT_GREY(Y8) = monochrome from = monochrome=
333 * = = s-video or = composite =
334 * = = B/W camera = input =
335 * =========================================================
336 * = other = color, svideo = color, =
337 * = = = composite =
338 * =========================================================
339 *
340 * Notes:
341 * channels 0-3 on 2255 are composite
342 * channels 0-1 on 2257 are composite, 2-3 are s-video
343 * If COLORFILTER is 0 with a composite color camera connected,
344 * the output will appear monochrome but hatching
345 * will occur.
346 * COLORFILTER is different from "color killer" and "color effects"
347 * for reasons above.
348 */
349#define S2255_V4L2_YC_ON 1
350#define S2255_V4L2_YC_OFF 0
351#define V4L2_CID_PRIVATE_COLORFILTER (V4L2_CID_PRIVATE_BASE + 0)
352
Dean Anderson38f993a2008-06-26 23:15:51 -0300353/* frame prefix size (sent once every frame) */
354#define PREFIX_SIZE 512
355
356/* Channels on box are in reverse order */
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300357static unsigned long G_chnmap[MAX_CHANNELS] = {3, 2, 1, 0};
Dean Anderson38f993a2008-06-26 23:15:51 -0300358
Dean Anderson38f993a2008-06-26 23:15:51 -0300359static int debug;
360static int *s2255_debug = &debug;
361
362static int s2255_start_readpipe(struct s2255_dev *dev);
363static void s2255_stop_readpipe(struct s2255_dev *dev);
Dean Andersonfe85ce92010-06-01 19:12:07 -0300364static int s2255_start_acquire(struct s2255_channel *channel);
365static int s2255_stop_acquire(struct s2255_channel *channel);
366static void s2255_fillbuff(struct s2255_channel *chn, struct s2255_buffer *buf,
367 int jpgsize);
368static int s2255_set_mode(struct s2255_channel *chan, struct s2255_mode *mode);
Dean Anderson38f993a2008-06-26 23:15:51 -0300369static int s2255_board_shutdown(struct s2255_dev *dev);
Dean Anderson14d96262008-08-25 13:58:55 -0300370static void s2255_fwload_start(struct s2255_dev *dev, int reset);
Dean Andersond62e85a2010-04-09 19:54:26 -0300371static void s2255_destroy(struct s2255_dev *dev);
Dean Anderson14d96262008-08-25 13:58:55 -0300372static long s2255_vendor_req(struct s2255_dev *dev, unsigned char req,
373 u16 index, u16 value, void *buf,
374 s32 buf_len, int bOut);
Dean Anderson38f993a2008-06-26 23:15:51 -0300375
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -0300376/* dev_err macro with driver name */
377#define S2255_DRIVER_NAME "s2255"
378#define s2255_dev_err(dev, fmt, arg...) \
379 dev_err(dev, S2255_DRIVER_NAME " - " fmt, ##arg)
380
Dean Anderson38f993a2008-06-26 23:15:51 -0300381#define dprintk(level, fmt, arg...) \
382 do { \
383 if (*s2255_debug >= (level)) { \
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -0300384 printk(KERN_DEBUG S2255_DRIVER_NAME \
385 ": " fmt, ##arg); \
Dean Anderson38f993a2008-06-26 23:15:51 -0300386 } \
387 } while (0)
388
Dean Anderson38f993a2008-06-26 23:15:51 -0300389static struct usb_driver s2255_driver;
390
Dean Anderson38f993a2008-06-26 23:15:51 -0300391/* Declare static vars that will be used as parameters */
392static unsigned int vid_limit = 16; /* Video memory limit, in Mb */
393
394/* start video number */
395static int video_nr = -1; /* /dev/videoN, -1 for autodetect */
396
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300397module_param(debug, int, 0644);
Dean Anderson38f993a2008-06-26 23:15:51 -0300398MODULE_PARM_DESC(debug, "Debug level(0-100) default 0");
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300399module_param(vid_limit, int, 0644);
Dean Anderson38f993a2008-06-26 23:15:51 -0300400MODULE_PARM_DESC(vid_limit, "video memory limit(Mb)");
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300401module_param(video_nr, int, 0644);
Dean Anderson38f993a2008-06-26 23:15:51 -0300402MODULE_PARM_DESC(video_nr, "start video minor(-1 default autodetect)");
403
404/* USB device table */
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300405#define USB_SENSORAY_VID 0x1943
Dean Anderson38f993a2008-06-26 23:15:51 -0300406static struct usb_device_id s2255_table[] = {
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300407 {USB_DEVICE(USB_SENSORAY_VID, 0x2255)},
408 {USB_DEVICE(USB_SENSORAY_VID, 0x2257)}, /*same family as 2255*/
Dean Anderson38f993a2008-06-26 23:15:51 -0300409 { } /* Terminating entry */
410};
411MODULE_DEVICE_TABLE(usb, s2255_table);
412
Dean Anderson38f993a2008-06-26 23:15:51 -0300413#define BUFFER_TIMEOUT msecs_to_jiffies(400)
414
Dean Anderson38f993a2008-06-26 23:15:51 -0300415/* image formats. */
416static const struct s2255_fmt formats[] = {
417 {
418 .name = "4:2:2, planar, YUV422P",
419 .fourcc = V4L2_PIX_FMT_YUV422P,
420 .depth = 16
421
422 }, {
423 .name = "4:2:2, packed, YUYV",
424 .fourcc = V4L2_PIX_FMT_YUYV,
425 .depth = 16
426
427 }, {
428 .name = "4:2:2, packed, UYVY",
429 .fourcc = V4L2_PIX_FMT_UYVY,
430 .depth = 16
431 }, {
Dean Anderson14d96262008-08-25 13:58:55 -0300432 .name = "JPG",
433 .fourcc = V4L2_PIX_FMT_JPEG,
434 .depth = 24
435 }, {
Dean Anderson38f993a2008-06-26 23:15:51 -0300436 .name = "8bpp GREY",
437 .fourcc = V4L2_PIX_FMT_GREY,
438 .depth = 8
439 }
440};
441
442static int norm_maxw(struct video_device *vdev)
443{
444 return (vdev->current_norm & V4L2_STD_NTSC) ?
445 LINE_SZ_4CIFS_NTSC : LINE_SZ_4CIFS_PAL;
446}
447
448static int norm_maxh(struct video_device *vdev)
449{
450 return (vdev->current_norm & V4L2_STD_NTSC) ?
451 (NUM_LINES_1CIFS_NTSC * 2) : (NUM_LINES_1CIFS_PAL * 2);
452}
453
454static int norm_minw(struct video_device *vdev)
455{
456 return (vdev->current_norm & V4L2_STD_NTSC) ?
457 LINE_SZ_1CIFS_NTSC : LINE_SZ_1CIFS_PAL;
458}
459
460static int norm_minh(struct video_device *vdev)
461{
462 return (vdev->current_norm & V4L2_STD_NTSC) ?
463 (NUM_LINES_1CIFS_NTSC) : (NUM_LINES_1CIFS_PAL);
464}
465
466
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300467/*
468 * TODO: fixme: move YUV reordering to hardware
469 * converts 2255 planar format to yuyv or uyvy
470 */
Dean Anderson38f993a2008-06-26 23:15:51 -0300471static void planar422p_to_yuv_packed(const unsigned char *in,
472 unsigned char *out,
473 int width, int height,
474 int fmt)
475{
476 unsigned char *pY;
477 unsigned char *pCb;
478 unsigned char *pCr;
479 unsigned long size = height * width;
480 unsigned int i;
481 pY = (unsigned char *)in;
482 pCr = (unsigned char *)in + height * width;
483 pCb = (unsigned char *)in + height * width + (height * width / 2);
484 for (i = 0; i < size * 2; i += 4) {
485 out[i] = (fmt == V4L2_PIX_FMT_YUYV) ? *pY++ : *pCr++;
486 out[i + 1] = (fmt == V4L2_PIX_FMT_YUYV) ? *pCr++ : *pY++;
487 out[i + 2] = (fmt == V4L2_PIX_FMT_YUYV) ? *pY++ : *pCb++;
488 out[i + 3] = (fmt == V4L2_PIX_FMT_YUYV) ? *pCb++ : *pY++;
489 }
490 return;
491}
492
Hans Verkuild45b9b82008-09-04 03:33:43 -0300493static void s2255_reset_dsppower(struct s2255_dev *dev)
Dean Anderson14d96262008-08-25 13:58:55 -0300494{
sensoray-dev752eb7a2011-01-19 17:41:45 -0300495 s2255_vendor_req(dev, 0x40, 0x0b0b, 0x0b01, NULL, 0, 1);
Dean Anderson14d96262008-08-25 13:58:55 -0300496 msleep(10);
497 s2255_vendor_req(dev, 0x50, 0x0000, 0x0000, NULL, 0, 1);
sensoray-dev752eb7a2011-01-19 17:41:45 -0300498 msleep(600);
499 s2255_vendor_req(dev, 0x10, 0x0000, 0x0000, NULL, 0, 1);
Dean Anderson14d96262008-08-25 13:58:55 -0300500 return;
501}
Dean Anderson38f993a2008-06-26 23:15:51 -0300502
503/* kickstarts the firmware loading. from probe
504 */
505static void s2255_timer(unsigned long user_data)
506{
507 struct s2255_fw *data = (struct s2255_fw *)user_data;
Dean Anderson85b85482010-04-08 23:51:17 -0300508 dprintk(100, "%s\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -0300509 if (usb_submit_urb(data->fw_urb, GFP_ATOMIC) < 0) {
510 printk(KERN_ERR "s2255: can't submit urb\n");
Dean Andersonf78d92c2008-07-22 14:43:27 -0300511 atomic_set(&data->fw_state, S2255_FW_FAILED);
512 /* wake up anything waiting for the firmware */
513 wake_up(&data->wait_fw);
Dean Anderson38f993a2008-06-26 23:15:51 -0300514 return;
515 }
516}
517
Dean Anderson38f993a2008-06-26 23:15:51 -0300518
519/* this loads the firmware asynchronously.
520 Originally this was done synchroously in probe.
521 But it is better to load it asynchronously here than block
522 inside the probe function. Blocking inside probe affects boot time.
523 FW loading is triggered by the timer in the probe function
524*/
525static void s2255_fwchunk_complete(struct urb *urb)
526{
527 struct s2255_fw *data = urb->context;
528 struct usb_device *udev = urb->dev;
529 int len;
Dean Anderson85b85482010-04-08 23:51:17 -0300530 dprintk(100, "%s: udev %p urb %p", __func__, udev, urb);
Dean Anderson38f993a2008-06-26 23:15:51 -0300531 if (urb->status) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -0300532 dev_err(&udev->dev, "URB failed with status %d\n", urb->status);
Dean Andersonf78d92c2008-07-22 14:43:27 -0300533 atomic_set(&data->fw_state, S2255_FW_FAILED);
534 /* wake up anything waiting for the firmware */
535 wake_up(&data->wait_fw);
Dean Anderson38f993a2008-06-26 23:15:51 -0300536 return;
537 }
538 if (data->fw_urb == NULL) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -0300539 s2255_dev_err(&udev->dev, "disconnected\n");
Dean Andersonf78d92c2008-07-22 14:43:27 -0300540 atomic_set(&data->fw_state, S2255_FW_FAILED);
541 /* wake up anything waiting for the firmware */
542 wake_up(&data->wait_fw);
Dean Anderson38f993a2008-06-26 23:15:51 -0300543 return;
544 }
545#define CHUNK_SIZE 512
546 /* all USB transfers must be done with continuous kernel memory.
547 can't allocate more than 128k in current linux kernel, so
548 upload the firmware in chunks
549 */
550 if (data->fw_loaded < data->fw_size) {
551 len = (data->fw_loaded + CHUNK_SIZE) > data->fw_size ?
552 data->fw_size % CHUNK_SIZE : CHUNK_SIZE;
553
554 if (len < CHUNK_SIZE)
555 memset(data->pfw_data, 0, CHUNK_SIZE);
556
557 dprintk(100, "completed len %d, loaded %d \n", len,
558 data->fw_loaded);
559
560 memcpy(data->pfw_data,
561 (char *) data->fw->data + data->fw_loaded, len);
562
563 usb_fill_bulk_urb(data->fw_urb, udev, usb_sndbulkpipe(udev, 2),
564 data->pfw_data, CHUNK_SIZE,
565 s2255_fwchunk_complete, data);
566 if (usb_submit_urb(data->fw_urb, GFP_ATOMIC) < 0) {
567 dev_err(&udev->dev, "failed submit URB\n");
568 atomic_set(&data->fw_state, S2255_FW_FAILED);
569 /* wake up anything waiting for the firmware */
570 wake_up(&data->wait_fw);
571 return;
572 }
573 data->fw_loaded += len;
574 } else {
Dean Anderson38f993a2008-06-26 23:15:51 -0300575 atomic_set(&data->fw_state, S2255_FW_LOADED_DSPWAIT);
Dean Anderson85b85482010-04-08 23:51:17 -0300576 dprintk(100, "%s: firmware upload complete\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -0300577 }
Dean Anderson38f993a2008-06-26 23:15:51 -0300578 return;
579
580}
581
Dean Andersonfe85ce92010-06-01 19:12:07 -0300582static int s2255_got_frame(struct s2255_channel *channel, int jpgsize)
Dean Anderson38f993a2008-06-26 23:15:51 -0300583{
Dean Andersonfe85ce92010-06-01 19:12:07 -0300584 struct s2255_dmaqueue *dma_q = &channel->vidq;
Dean Anderson38f993a2008-06-26 23:15:51 -0300585 struct s2255_buffer *buf;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300586 struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev);
Dean Anderson38f993a2008-06-26 23:15:51 -0300587 unsigned long flags = 0;
588 int rc = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -0300589 spin_lock_irqsave(&dev->slock, flags);
Dean Anderson38f993a2008-06-26 23:15:51 -0300590 if (list_empty(&dma_q->active)) {
591 dprintk(1, "No active queue to serve\n");
592 rc = -1;
593 goto unlock;
594 }
595 buf = list_entry(dma_q->active.next,
596 struct s2255_buffer, vb.queue);
Dean Anderson38f993a2008-06-26 23:15:51 -0300597 list_del(&buf->vb.queue);
598 do_gettimeofday(&buf->vb.ts);
Dean Andersonfe85ce92010-06-01 19:12:07 -0300599 s2255_fillbuff(channel, buf, jpgsize);
Dean Anderson38f993a2008-06-26 23:15:51 -0300600 wake_up(&buf->vb.done);
Dean Anderson85b85482010-04-08 23:51:17 -0300601 dprintk(2, "%s: [buf/i] [%p/%d]\n", __func__, buf, buf->vb.i);
Dean Anderson38f993a2008-06-26 23:15:51 -0300602unlock:
603 spin_unlock_irqrestore(&dev->slock, flags);
Julia Lawallf2770972010-08-16 13:26:13 -0300604 return rc;
Dean Anderson38f993a2008-06-26 23:15:51 -0300605}
606
Dean Anderson38f993a2008-06-26 23:15:51 -0300607static const struct s2255_fmt *format_by_fourcc(int fourcc)
608{
609 unsigned int i;
Dean Anderson38f993a2008-06-26 23:15:51 -0300610 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 */
Dean Andersonfe85ce92010-06-01 19:12:07 -0300627static void s2255_fillbuff(struct s2255_channel *channel,
628 struct s2255_buffer *buf, 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;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300639 last_frame = channel->last_frame;
Dean Anderson38f993a2008-06-26 23:15:51 -0300640 if (last_frame != -1) {
Dean Andersonfe85ce92010-06-01 19:12:07 -0300641 frm = &channel->buffer.frame[last_frame];
Dean Anderson38f993a2008-06-26 23:15:51 -0300642 tmpbuf =
Dean Andersonfe85ce92010-06-01 19:12:07 -0300643 (const char *)channel->buffer.frame[last_frame].lpvbits;
Dean Anderson38f993a2008-06-26 23:15:51 -0300644 switch (buf->fmt->fourcc) {
645 case V4L2_PIX_FMT_YUYV:
646 case V4L2_PIX_FMT_UYVY:
647 planar422p_to_yuv_packed((const unsigned char *)tmpbuf,
648 vbuf, buf->vb.width,
649 buf->vb.height,
650 buf->fmt->fourcc);
651 break;
652 case V4L2_PIX_FMT_GREY:
653 memcpy(vbuf, tmpbuf, buf->vb.width * buf->vb.height);
654 break;
Dean Anderson14d96262008-08-25 13:58:55 -0300655 case V4L2_PIX_FMT_JPEG:
656 buf->vb.size = jpgsize;
657 memcpy(vbuf, tmpbuf, buf->vb.size);
658 break;
Dean Anderson38f993a2008-06-26 23:15:51 -0300659 case V4L2_PIX_FMT_YUV422P:
660 memcpy(vbuf, tmpbuf,
661 buf->vb.width * buf->vb.height * 2);
662 break;
663 default:
664 printk(KERN_DEBUG "s2255: unknown format?\n");
665 }
Dean Andersonfe85ce92010-06-01 19:12:07 -0300666 channel->last_frame = -1;
Dean Anderson38f993a2008-06-26 23:15:51 -0300667 } else {
668 printk(KERN_ERR "s2255: =======no frame\n");
669 return;
670
671 }
672 dprintk(2, "s2255fill at : Buffer 0x%08lx size= %d\n",
673 (unsigned long)vbuf, pos);
674 /* tell v4l buffer was filled */
675
Dean Andersonfe85ce92010-06-01 19:12:07 -0300676 buf->vb.field_count = channel->frame_count * 2;
Dean Anderson38f993a2008-06-26 23:15:51 -0300677 do_gettimeofday(&ts);
678 buf->vb.ts = ts;
679 buf->vb.state = VIDEOBUF_DONE;
680}
681
682
683/* ------------------------------------------------------------------
684 Videobuf operations
685 ------------------------------------------------------------------*/
686
687static int buffer_setup(struct videobuf_queue *vq, unsigned int *count,
688 unsigned int *size)
689{
690 struct s2255_fh *fh = vq->priv_data;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300691 struct s2255_channel *channel = fh->channel;
692 *size = channel->width * channel->height * (channel->fmt->depth >> 3);
Dean Anderson38f993a2008-06-26 23:15:51 -0300693
694 if (0 == *count)
695 *count = S2255_DEF_BUFS;
696
Andreas Bombedab7e312010-03-21 16:02:45 -0300697 if (*size * *count > vid_limit * 1024 * 1024)
698 *count = (vid_limit * 1024 * 1024) / *size;
Dean Anderson38f993a2008-06-26 23:15:51 -0300699
700 return 0;
701}
702
703static void free_buffer(struct videobuf_queue *vq, struct s2255_buffer *buf)
704{
705 dprintk(4, "%s\n", __func__);
706
Dean Anderson38f993a2008-06-26 23:15:51 -0300707 videobuf_vmalloc_free(&buf->vb);
708 buf->vb.state = VIDEOBUF_NEEDS_INIT;
709}
710
711static int buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb,
712 enum v4l2_field field)
713{
714 struct s2255_fh *fh = vq->priv_data;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300715 struct s2255_channel *channel = fh->channel;
Dean Anderson38f993a2008-06-26 23:15:51 -0300716 struct s2255_buffer *buf = container_of(vb, struct s2255_buffer, vb);
717 int rc;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300718 int w = channel->width;
719 int h = channel->height;
Dean Anderson38f993a2008-06-26 23:15:51 -0300720 dprintk(4, "%s, field=%d\n", __func__, field);
Dean Andersonfe85ce92010-06-01 19:12:07 -0300721 if (channel->fmt == NULL)
Dean Anderson38f993a2008-06-26 23:15:51 -0300722 return -EINVAL;
723
Dean Andersonfe85ce92010-06-01 19:12:07 -0300724 if ((w < norm_minw(&channel->vdev)) ||
725 (w > norm_maxw(&channel->vdev)) ||
726 (h < norm_minh(&channel->vdev)) ||
727 (h > norm_maxh(&channel->vdev))) {
Dean Anderson38f993a2008-06-26 23:15:51 -0300728 dprintk(4, "invalid buffer prepare\n");
729 return -EINVAL;
730 }
Dean Andersonfe85ce92010-06-01 19:12:07 -0300731 buf->vb.size = w * h * (channel->fmt->depth >> 3);
Dean Anderson38f993a2008-06-26 23:15:51 -0300732 if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size) {
733 dprintk(4, "invalid buffer prepare\n");
734 return -EINVAL;
735 }
736
Dean Andersonfe85ce92010-06-01 19:12:07 -0300737 buf->fmt = channel->fmt;
738 buf->vb.width = w;
739 buf->vb.height = h;
Dean Anderson38f993a2008-06-26 23:15:51 -0300740 buf->vb.field = field;
741
Dean Anderson38f993a2008-06-26 23:15:51 -0300742 if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
743 rc = videobuf_iolock(vq, &buf->vb, NULL);
744 if (rc < 0)
745 goto fail;
746 }
747
748 buf->vb.state = VIDEOBUF_PREPARED;
749 return 0;
750fail:
751 free_buffer(vq, buf);
752 return rc;
753}
754
755static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
756{
757 struct s2255_buffer *buf = container_of(vb, struct s2255_buffer, vb);
758 struct s2255_fh *fh = vq->priv_data;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300759 struct s2255_channel *channel = fh->channel;
760 struct s2255_dmaqueue *vidq = &channel->vidq;
Dean Anderson38f993a2008-06-26 23:15:51 -0300761 dprintk(1, "%s\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -0300762 buf->vb.state = VIDEOBUF_QUEUED;
763 list_add_tail(&buf->vb.queue, &vidq->active);
764}
765
766static void buffer_release(struct videobuf_queue *vq,
767 struct videobuf_buffer *vb)
768{
769 struct s2255_buffer *buf = container_of(vb, struct s2255_buffer, vb);
770 struct s2255_fh *fh = vq->priv_data;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300771 dprintk(4, "%s %d\n", __func__, fh->channel->idx);
Dean Anderson38f993a2008-06-26 23:15:51 -0300772 free_buffer(vq, buf);
773}
774
775static struct videobuf_queue_ops s2255_video_qops = {
776 .buf_setup = buffer_setup,
777 .buf_prepare = buffer_prepare,
778 .buf_queue = buffer_queue,
779 .buf_release = buffer_release,
780};
781
782
Dean Andersonfe85ce92010-06-01 19:12:07 -0300783static int res_get(struct s2255_fh *fh)
Dean Anderson38f993a2008-06-26 23:15:51 -0300784{
Dean Andersonfe85ce92010-06-01 19:12:07 -0300785 struct s2255_channel *channel = fh->channel;
Pete Eberleina19a5cd2010-12-20 19:18:59 -0300786 /* is it free? */
787 if (channel->resources)
788 return 0; /* no, someone else uses it */
Dean Anderson38f993a2008-06-26 23:15:51 -0300789 /* it's free, grab it */
Dean Andersonfe85ce92010-06-01 19:12:07 -0300790 channel->resources = 1;
791 fh->resources = 1;
Dean Andersonf78d92c2008-07-22 14:43:27 -0300792 dprintk(1, "s2255: res: get\n");
Dean Anderson38f993a2008-06-26 23:15:51 -0300793 return 1;
794}
795
Dean Andersonfe85ce92010-06-01 19:12:07 -0300796static int res_locked(struct s2255_fh *fh)
Dean Anderson38f993a2008-06-26 23:15:51 -0300797{
Dean Andersonfe85ce92010-06-01 19:12:07 -0300798 return fh->channel->resources;
Dean Anderson38f993a2008-06-26 23:15:51 -0300799}
800
Dean Andersonf78d92c2008-07-22 14:43:27 -0300801static int res_check(struct s2255_fh *fh)
802{
Dean Andersonfe85ce92010-06-01 19:12:07 -0300803 return fh->resources;
Dean Andersonf78d92c2008-07-22 14:43:27 -0300804}
805
806
Dean Andersonfe85ce92010-06-01 19:12:07 -0300807static void res_free(struct s2255_fh *fh)
Dean Anderson38f993a2008-06-26 23:15:51 -0300808{
Dean Andersonfe85ce92010-06-01 19:12:07 -0300809 struct s2255_channel *channel = fh->channel;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300810 channel->resources = 0;
811 fh->resources = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -0300812 dprintk(1, "res: put\n");
813}
814
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300815static int vidioc_querymenu(struct file *file, void *priv,
816 struct v4l2_querymenu *qmenu)
817{
818 static const char *colorfilter[] = {
819 "Off",
820 "On",
821 NULL
822 };
823 if (qmenu->id == V4L2_CID_PRIVATE_COLORFILTER) {
824 int i;
825 const char **menu_items = colorfilter;
826 for (i = 0; i < qmenu->index && menu_items[i]; i++)
827 ; /* do nothing (from v4l2-common.c) */
828 if (menu_items[i] == NULL || menu_items[i][0] == '\0')
829 return -EINVAL;
830 strlcpy(qmenu->name, menu_items[qmenu->index],
831 sizeof(qmenu->name));
832 return 0;
833 }
834 return v4l2_ctrl_query_menu(qmenu, NULL, NULL);
835}
836
Dean Anderson38f993a2008-06-26 23:15:51 -0300837static int vidioc_querycap(struct file *file, void *priv,
838 struct v4l2_capability *cap)
839{
840 struct s2255_fh *fh = file->private_data;
841 struct s2255_dev *dev = fh->dev;
842 strlcpy(cap->driver, "s2255", sizeof(cap->driver));
843 strlcpy(cap->card, "s2255", sizeof(cap->card));
Thierry MERLEe22ed882009-01-20 18:19:25 -0300844 usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info));
Dean Anderson38f993a2008-06-26 23:15:51 -0300845 cap->version = S2255_VERSION;
846 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
847 return 0;
848}
849
850static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
851 struct v4l2_fmtdesc *f)
852{
853 int index = 0;
854 if (f)
855 index = f->index;
856
857 if (index >= ARRAY_SIZE(formats))
858 return -EINVAL;
859
860 dprintk(4, "name %s\n", formats[index].name);
861 strlcpy(f->description, formats[index].name, sizeof(f->description));
862 f->pixelformat = formats[index].fourcc;
863 return 0;
864}
865
866static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
867 struct v4l2_format *f)
868{
869 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300870 struct s2255_channel *channel = fh->channel;
Dean Anderson38f993a2008-06-26 23:15:51 -0300871
Dean Andersonfe85ce92010-06-01 19:12:07 -0300872 f->fmt.pix.width = channel->width;
873 f->fmt.pix.height = channel->height;
Dean Anderson38f993a2008-06-26 23:15:51 -0300874 f->fmt.pix.field = fh->vb_vidq.field;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300875 f->fmt.pix.pixelformat = channel->fmt->fourcc;
876 f->fmt.pix.bytesperline = f->fmt.pix.width * (channel->fmt->depth >> 3);
Dean Anderson38f993a2008-06-26 23:15:51 -0300877 f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300878 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -0300879}
880
881static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
882 struct v4l2_format *f)
883{
884 const struct s2255_fmt *fmt;
885 enum v4l2_field field;
886 int b_any_field = 0;
887 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300888 struct s2255_channel *channel = fh->channel;
Dean Anderson38f993a2008-06-26 23:15:51 -0300889 int is_ntsc;
Dean Anderson38f993a2008-06-26 23:15:51 -0300890 is_ntsc =
Dean Andersonfe85ce92010-06-01 19:12:07 -0300891 (channel->vdev.current_norm & V4L2_STD_NTSC) ? 1 : 0;
Dean Anderson38f993a2008-06-26 23:15:51 -0300892
893 fmt = format_by_fourcc(f->fmt.pix.pixelformat);
894
895 if (fmt == NULL)
896 return -EINVAL;
897
898 field = f->fmt.pix.field;
899 if (field == V4L2_FIELD_ANY)
900 b_any_field = 1;
901
Dean Anderson85b85482010-04-08 23:51:17 -0300902 dprintk(50, "%s NTSC: %d suggested width: %d, height: %d\n",
903 __func__, is_ntsc, f->fmt.pix.width, f->fmt.pix.height);
Dean Anderson38f993a2008-06-26 23:15:51 -0300904 if (is_ntsc) {
905 /* NTSC */
906 if (f->fmt.pix.height >= NUM_LINES_1CIFS_NTSC * 2) {
907 f->fmt.pix.height = NUM_LINES_1CIFS_NTSC * 2;
908 if (b_any_field) {
909 field = V4L2_FIELD_SEQ_TB;
910 } else if (!((field == V4L2_FIELD_INTERLACED) ||
911 (field == V4L2_FIELD_SEQ_TB) ||
912 (field == V4L2_FIELD_INTERLACED_TB))) {
913 dprintk(1, "unsupported field setting\n");
914 return -EINVAL;
915 }
916 } else {
917 f->fmt.pix.height = NUM_LINES_1CIFS_NTSC;
918 if (b_any_field) {
919 field = V4L2_FIELD_TOP;
920 } else if (!((field == V4L2_FIELD_TOP) ||
921 (field == V4L2_FIELD_BOTTOM))) {
922 dprintk(1, "unsupported field setting\n");
923 return -EINVAL;
924 }
925
926 }
927 if (f->fmt.pix.width >= LINE_SZ_4CIFS_NTSC)
928 f->fmt.pix.width = LINE_SZ_4CIFS_NTSC;
929 else if (f->fmt.pix.width >= LINE_SZ_2CIFS_NTSC)
930 f->fmt.pix.width = LINE_SZ_2CIFS_NTSC;
931 else if (f->fmt.pix.width >= LINE_SZ_1CIFS_NTSC)
932 f->fmt.pix.width = LINE_SZ_1CIFS_NTSC;
933 else
934 f->fmt.pix.width = LINE_SZ_1CIFS_NTSC;
935 } else {
936 /* PAL */
937 if (f->fmt.pix.height >= NUM_LINES_1CIFS_PAL * 2) {
938 f->fmt.pix.height = NUM_LINES_1CIFS_PAL * 2;
939 if (b_any_field) {
940 field = V4L2_FIELD_SEQ_TB;
941 } else if (!((field == V4L2_FIELD_INTERLACED) ||
942 (field == V4L2_FIELD_SEQ_TB) ||
943 (field == V4L2_FIELD_INTERLACED_TB))) {
944 dprintk(1, "unsupported field setting\n");
945 return -EINVAL;
946 }
947 } else {
948 f->fmt.pix.height = NUM_LINES_1CIFS_PAL;
949 if (b_any_field) {
950 field = V4L2_FIELD_TOP;
951 } else if (!((field == V4L2_FIELD_TOP) ||
952 (field == V4L2_FIELD_BOTTOM))) {
953 dprintk(1, "unsupported field setting\n");
954 return -EINVAL;
955 }
956 }
957 if (f->fmt.pix.width >= LINE_SZ_4CIFS_PAL) {
Dean Anderson38f993a2008-06-26 23:15:51 -0300958 f->fmt.pix.width = LINE_SZ_4CIFS_PAL;
959 field = V4L2_FIELD_SEQ_TB;
960 } else if (f->fmt.pix.width >= LINE_SZ_2CIFS_PAL) {
Dean Anderson38f993a2008-06-26 23:15:51 -0300961 f->fmt.pix.width = LINE_SZ_2CIFS_PAL;
962 field = V4L2_FIELD_TOP;
963 } else if (f->fmt.pix.width >= LINE_SZ_1CIFS_PAL) {
Dean Anderson38f993a2008-06-26 23:15:51 -0300964 f->fmt.pix.width = LINE_SZ_1CIFS_PAL;
965 field = V4L2_FIELD_TOP;
966 } else {
Dean Anderson38f993a2008-06-26 23:15:51 -0300967 f->fmt.pix.width = LINE_SZ_1CIFS_PAL;
968 field = V4L2_FIELD_TOP;
969 }
970 }
Dean Anderson38f993a2008-06-26 23:15:51 -0300971 f->fmt.pix.field = field;
972 f->fmt.pix.bytesperline = (f->fmt.pix.width * fmt->depth) >> 3;
973 f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
Dean Anderson85b85482010-04-08 23:51:17 -0300974 dprintk(50, "%s: set width %d height %d field %d\n", __func__,
975 f->fmt.pix.width, f->fmt.pix.height, f->fmt.pix.field);
Dean Anderson38f993a2008-06-26 23:15:51 -0300976 return 0;
977}
978
979static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
980 struct v4l2_format *f)
981{
982 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300983 struct s2255_channel *channel = fh->channel;
Dean Anderson38f993a2008-06-26 23:15:51 -0300984 const struct s2255_fmt *fmt;
985 struct videobuf_queue *q = &fh->vb_vidq;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300986 struct s2255_mode mode;
Dean Anderson38f993a2008-06-26 23:15:51 -0300987 int ret;
988 int norm;
989
990 ret = vidioc_try_fmt_vid_cap(file, fh, f);
991
992 if (ret < 0)
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300993 return ret;
Dean Anderson38f993a2008-06-26 23:15:51 -0300994
995 fmt = format_by_fourcc(f->fmt.pix.pixelformat);
996
997 if (fmt == NULL)
998 return -EINVAL;
999
1000 mutex_lock(&q->vb_lock);
1001
1002 if (videobuf_queue_is_busy(&fh->vb_vidq)) {
1003 dprintk(1, "queue busy\n");
1004 ret = -EBUSY;
1005 goto out_s_fmt;
1006 }
1007
Dean Andersonfe85ce92010-06-01 19:12:07 -03001008 if (res_locked(fh)) {
Dean Anderson85b85482010-04-08 23:51:17 -03001009 dprintk(1, "%s: channel busy\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03001010 ret = -EBUSY;
1011 goto out_s_fmt;
1012 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001013 mode = channel->mode;
1014 channel->fmt = fmt;
1015 channel->width = f->fmt.pix.width;
1016 channel->height = f->fmt.pix.height;
Dean Anderson38f993a2008-06-26 23:15:51 -03001017 fh->vb_vidq.field = f->fmt.pix.field;
1018 fh->type = f->type;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001019 norm = norm_minw(&channel->vdev);
1020 if (channel->width > norm_minw(&channel->vdev)) {
1021 if (channel->height > norm_minh(&channel->vdev)) {
1022 if (channel->cap_parm.capturemode &
Dean Anderson85b85482010-04-08 23:51:17 -03001023 V4L2_MODE_HIGHQUALITY)
Dean Andersonfe85ce92010-06-01 19:12:07 -03001024 mode.scale = SCALE_4CIFSI;
Dean Anderson85b85482010-04-08 23:51:17 -03001025 else
Dean Andersonfe85ce92010-06-01 19:12:07 -03001026 mode.scale = SCALE_4CIFS;
Dean Anderson7d853532009-05-15 14:32:04 -03001027 } else
Dean Andersonfe85ce92010-06-01 19:12:07 -03001028 mode.scale = SCALE_2CIFS;
Dean Anderson38f993a2008-06-26 23:15:51 -03001029
1030 } else {
Dean Andersonfe85ce92010-06-01 19:12:07 -03001031 mode.scale = SCALE_1CIFS;
Dean Anderson38f993a2008-06-26 23:15:51 -03001032 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001033 /* color mode */
Dean Andersonfe85ce92010-06-01 19:12:07 -03001034 switch (channel->fmt->fourcc) {
Dean Anderson38f993a2008-06-26 23:15:51 -03001035 case V4L2_PIX_FMT_GREY:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001036 mode.color &= ~MASK_COLOR;
1037 mode.color |= COLOR_Y8;
Dean Anderson38f993a2008-06-26 23:15:51 -03001038 break;
Dean Anderson14d96262008-08-25 13:58:55 -03001039 case V4L2_PIX_FMT_JPEG:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001040 mode.color &= ~MASK_COLOR;
1041 mode.color |= COLOR_JPG;
1042 mode.color |= (channel->jc.quality << 8);
Dean Anderson14d96262008-08-25 13:58:55 -03001043 break;
Dean Anderson38f993a2008-06-26 23:15:51 -03001044 case V4L2_PIX_FMT_YUV422P:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001045 mode.color &= ~MASK_COLOR;
1046 mode.color |= COLOR_YUVPL;
Dean Anderson38f993a2008-06-26 23:15:51 -03001047 break;
1048 case V4L2_PIX_FMT_YUYV:
1049 case V4L2_PIX_FMT_UYVY:
1050 default:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001051 mode.color &= ~MASK_COLOR;
1052 mode.color |= COLOR_YUVPK;
Dean Anderson38f993a2008-06-26 23:15:51 -03001053 break;
1054 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001055 if ((mode.color & MASK_COLOR) != (channel->mode.color & MASK_COLOR))
1056 mode.restart = 1;
1057 else if (mode.scale != channel->mode.scale)
1058 mode.restart = 1;
1059 else if (mode.format != channel->mode.format)
1060 mode.restart = 1;
1061 channel->mode = mode;
1062 (void) s2255_set_mode(channel, &mode);
Dean Anderson38f993a2008-06-26 23:15:51 -03001063 ret = 0;
1064out_s_fmt:
1065 mutex_unlock(&q->vb_lock);
1066 return ret;
1067}
1068
1069static int vidioc_reqbufs(struct file *file, void *priv,
1070 struct v4l2_requestbuffers *p)
1071{
1072 int rc;
1073 struct s2255_fh *fh = priv;
1074 rc = videobuf_reqbufs(&fh->vb_vidq, p);
1075 return rc;
1076}
1077
1078static int vidioc_querybuf(struct file *file, void *priv, struct v4l2_buffer *p)
1079{
1080 int rc;
1081 struct s2255_fh *fh = priv;
1082 rc = videobuf_querybuf(&fh->vb_vidq, p);
1083 return rc;
1084}
1085
1086static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *p)
1087{
1088 int rc;
1089 struct s2255_fh *fh = priv;
1090 rc = videobuf_qbuf(&fh->vb_vidq, p);
1091 return rc;
1092}
1093
1094static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
1095{
1096 int rc;
1097 struct s2255_fh *fh = priv;
1098 rc = videobuf_dqbuf(&fh->vb_vidq, p, file->f_flags & O_NONBLOCK);
1099 return rc;
1100}
1101
Dean Anderson38f993a2008-06-26 23:15:51 -03001102/* write to the configuration pipe, synchronously */
1103static int s2255_write_config(struct usb_device *udev, unsigned char *pbuf,
1104 int size)
1105{
1106 int pipe;
1107 int done;
1108 long retval = -1;
1109 if (udev) {
1110 pipe = usb_sndbulkpipe(udev, S2255_CONFIG_EP);
1111 retval = usb_bulk_msg(udev, pipe, pbuf, size, &done, 500);
1112 }
1113 return retval;
1114}
1115
1116static u32 get_transfer_size(struct s2255_mode *mode)
1117{
1118 int linesPerFrame = LINE_SZ_DEF;
1119 int pixelsPerLine = NUM_LINES_DEF;
1120 u32 outImageSize;
1121 u32 usbInSize;
1122 unsigned int mask_mult;
1123
1124 if (mode == NULL)
1125 return 0;
1126
1127 if (mode->format == FORMAT_NTSC) {
1128 switch (mode->scale) {
1129 case SCALE_4CIFS:
Dean Anderson7d853532009-05-15 14:32:04 -03001130 case SCALE_4CIFSI:
Dean Anderson38f993a2008-06-26 23:15:51 -03001131 linesPerFrame = NUM_LINES_4CIFS_NTSC * 2;
1132 pixelsPerLine = LINE_SZ_4CIFS_NTSC;
1133 break;
1134 case SCALE_2CIFS:
1135 linesPerFrame = NUM_LINES_2CIFS_NTSC;
1136 pixelsPerLine = LINE_SZ_2CIFS_NTSC;
1137 break;
1138 case SCALE_1CIFS:
1139 linesPerFrame = NUM_LINES_1CIFS_NTSC;
1140 pixelsPerLine = LINE_SZ_1CIFS_NTSC;
1141 break;
1142 default:
1143 break;
1144 }
1145 } else if (mode->format == FORMAT_PAL) {
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_PAL * 2;
1150 pixelsPerLine = LINE_SZ_4CIFS_PAL;
1151 break;
1152 case SCALE_2CIFS:
1153 linesPerFrame = NUM_LINES_2CIFS_PAL;
1154 pixelsPerLine = LINE_SZ_2CIFS_PAL;
1155 break;
1156 case SCALE_1CIFS:
1157 linesPerFrame = NUM_LINES_1CIFS_PAL;
1158 pixelsPerLine = LINE_SZ_1CIFS_PAL;
1159 break;
1160 default:
1161 break;
1162 }
1163 }
1164 outImageSize = linesPerFrame * pixelsPerLine;
Dean Anderson14d96262008-08-25 13:58:55 -03001165 if ((mode->color & MASK_COLOR) != COLOR_Y8) {
Dean Anderson38f993a2008-06-26 23:15:51 -03001166 /* 2 bytes/pixel if not monochrome */
1167 outImageSize *= 2;
1168 }
1169
1170 /* total bytes to send including prefix and 4K padding;
1171 must be a multiple of USB_READ_SIZE */
1172 usbInSize = outImageSize + PREFIX_SIZE; /* always send prefix */
1173 mask_mult = 0xffffffffUL - DEF_USB_BLOCK + 1;
1174 /* if size not a multiple of USB_READ_SIZE */
1175 if (usbInSize & ~mask_mult)
1176 usbInSize = (usbInSize & mask_mult) + (DEF_USB_BLOCK);
1177 return usbInSize;
1178}
1179
Dean Anderson85b85482010-04-08 23:51:17 -03001180static void s2255_print_cfg(struct s2255_dev *sdev, struct s2255_mode *mode)
Dean Anderson38f993a2008-06-26 23:15:51 -03001181{
1182 struct device *dev = &sdev->udev->dev;
1183 dev_info(dev, "------------------------------------------------\n");
Dean Anderson85b85482010-04-08 23:51:17 -03001184 dev_info(dev, "format: %d\nscale %d\n", mode->format, mode->scale);
1185 dev_info(dev, "fdec: %d\ncolor %d\n", mode->fdec, mode->color);
Dean Anderson38f993a2008-06-26 23:15:51 -03001186 dev_info(dev, "bright: 0x%x\n", mode->bright);
Dean Anderson38f993a2008-06-26 23:15:51 -03001187 dev_info(dev, "------------------------------------------------\n");
1188}
1189
1190/*
1191 * set mode is the function which controls the DSP.
1192 * the restart parameter in struct s2255_mode should be set whenever
1193 * the image size could change via color format, video system or image
1194 * size.
1195 * When the restart parameter is set, we sleep for ONE frame to allow the
1196 * DSP time to get the new frame
1197 */
Dean Andersonfe85ce92010-06-01 19:12:07 -03001198static int s2255_set_mode(struct s2255_channel *channel,
Dean Anderson38f993a2008-06-26 23:15:51 -03001199 struct s2255_mode *mode)
1200{
1201 int res;
Dean Anderson3fa00602010-03-04 20:47:33 -03001202 __le32 *buffer;
Dean Anderson38f993a2008-06-26 23:15:51 -03001203 unsigned long chn_rev;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001204 struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001205 chn_rev = G_chnmap[channel->idx];
1206 dprintk(3, "%s channel: %d\n", __func__, channel->idx);
Dean Anderson22b88d42008-08-29 15:33:19 -03001207 /* if JPEG, set the quality */
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001208 if ((mode->color & MASK_COLOR) == COLOR_JPG) {
1209 mode->color &= ~MASK_COLOR;
1210 mode->color |= COLOR_JPG;
1211 mode->color &= ~MASK_JPG_QUALITY;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001212 mode->color |= (channel->jc.quality << 8);
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001213 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001214 /* save the mode */
Dean Andersonfe85ce92010-06-01 19:12:07 -03001215 channel->mode = *mode;
1216 channel->req_image_size = get_transfer_size(mode);
1217 dprintk(1, "%s: reqsize %ld\n", __func__, channel->req_image_size);
Dean Anderson38f993a2008-06-26 23:15:51 -03001218 buffer = kzalloc(512, GFP_KERNEL);
1219 if (buffer == NULL) {
1220 dev_err(&dev->udev->dev, "out of mem\n");
1221 return -ENOMEM;
1222 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001223 /* set the mode */
1224 buffer[0] = IN_DATA_TOKEN;
Dean Anderson3fa00602010-03-04 20:47:33 -03001225 buffer[1] = (__le32) cpu_to_le32(chn_rev);
Dean Anderson38f993a2008-06-26 23:15:51 -03001226 buffer[2] = CMD_SET_MODE;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001227 memcpy(&buffer[3], &channel->mode, sizeof(struct s2255_mode));
1228 channel->setmode_ready = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001229 res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
1230 if (debug)
Dean Anderson85b85482010-04-08 23:51:17 -03001231 s2255_print_cfg(dev, mode);
Dean Anderson38f993a2008-06-26 23:15:51 -03001232 kfree(buffer);
Dean Anderson38f993a2008-06-26 23:15:51 -03001233 /* wait at least 3 frames before continuing */
Dean Anderson14d96262008-08-25 13:58:55 -03001234 if (mode->restart) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03001235 wait_event_timeout(channel->wait_setmode,
1236 (channel->setmode_ready != 0),
Dean Anderson14d96262008-08-25 13:58:55 -03001237 msecs_to_jiffies(S2255_SETMODE_TIMEOUT));
Dean Andersonfe85ce92010-06-01 19:12:07 -03001238 if (channel->setmode_ready != 1) {
Dean Anderson14d96262008-08-25 13:58:55 -03001239 printk(KERN_DEBUG "s2255: no set mode response\n");
1240 res = -EFAULT;
1241 }
1242 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001243 /* clear the restart flag */
Dean Andersonfe85ce92010-06-01 19:12:07 -03001244 channel->mode.restart = 0;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001245 dprintk(1, "%s chn %d, result: %d\n", __func__, channel->idx, res);
Dean Anderson38f993a2008-06-26 23:15:51 -03001246 return res;
1247}
1248
Dean Andersonfe85ce92010-06-01 19:12:07 -03001249static int s2255_cmd_status(struct s2255_channel *channel, u32 *pstatus)
Dean Anderson4de39f52010-03-03 19:39:19 -03001250{
1251 int res;
Dean Anderson3fa00602010-03-04 20:47:33 -03001252 __le32 *buffer;
Dean Anderson4de39f52010-03-03 19:39:19 -03001253 u32 chn_rev;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001254 struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001255 chn_rev = G_chnmap[channel->idx];
1256 dprintk(4, "%s chan %d\n", __func__, channel->idx);
Dean Anderson4de39f52010-03-03 19:39:19 -03001257 buffer = kzalloc(512, GFP_KERNEL);
1258 if (buffer == NULL) {
1259 dev_err(&dev->udev->dev, "out of mem\n");
Dean Anderson4de39f52010-03-03 19:39:19 -03001260 return -ENOMEM;
1261 }
1262 /* form the get vid status command */
1263 buffer[0] = IN_DATA_TOKEN;
Dean Anderson3fa00602010-03-04 20:47:33 -03001264 buffer[1] = (__le32) cpu_to_le32(chn_rev);
Dean Anderson4de39f52010-03-03 19:39:19 -03001265 buffer[2] = CMD_STATUS;
1266 *pstatus = 0;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001267 channel->vidstatus_ready = 0;
Dean Anderson4de39f52010-03-03 19:39:19 -03001268 res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
1269 kfree(buffer);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001270 wait_event_timeout(channel->wait_vidstatus,
1271 (channel->vidstatus_ready != 0),
Dean Anderson4de39f52010-03-03 19:39:19 -03001272 msecs_to_jiffies(S2255_VIDSTATUS_TIMEOUT));
Dean Andersonfe85ce92010-06-01 19:12:07 -03001273 if (channel->vidstatus_ready != 1) {
Dean Anderson4de39f52010-03-03 19:39:19 -03001274 printk(KERN_DEBUG "s2255: no vidstatus response\n");
1275 res = -EFAULT;
1276 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001277 *pstatus = channel->vidstatus;
Dean Anderson4de39f52010-03-03 19:39:19 -03001278 dprintk(4, "%s, vid status %d\n", __func__, *pstatus);
Dean Anderson4de39f52010-03-03 19:39:19 -03001279 return res;
1280}
1281
Dean Anderson38f993a2008-06-26 23:15:51 -03001282static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
1283{
1284 int res;
1285 struct s2255_fh *fh = priv;
1286 struct s2255_dev *dev = fh->dev;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001287 struct s2255_channel *channel = fh->channel;
Dean Anderson38f993a2008-06-26 23:15:51 -03001288 int j;
1289 dprintk(4, "%s\n", __func__);
1290 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1291 dev_err(&dev->udev->dev, "invalid fh type0\n");
1292 return -EINVAL;
1293 }
1294 if (i != fh->type) {
1295 dev_err(&dev->udev->dev, "invalid fh type1\n");
1296 return -EINVAL;
1297 }
1298
Dean Andersonfe85ce92010-06-01 19:12:07 -03001299 if (!res_get(fh)) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03001300 s2255_dev_err(&dev->udev->dev, "stream busy\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03001301 return -EBUSY;
1302 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001303 channel->last_frame = -1;
1304 channel->bad_payload = 0;
1305 channel->cur_frame = 0;
1306 channel->frame_count = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001307 for (j = 0; j < SYS_FRAMES; j++) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03001308 channel->buffer.frame[j].ulState = S2255_READ_IDLE;
1309 channel->buffer.frame[j].cur_size = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001310 }
1311 res = videobuf_streamon(&fh->vb_vidq);
1312 if (res == 0) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03001313 s2255_start_acquire(channel);
1314 channel->b_acquire = 1;
1315 } else
1316 res_free(fh);
1317
Dean Anderson38f993a2008-06-26 23:15:51 -03001318 return res;
1319}
1320
1321static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
1322{
Dean Anderson38f993a2008-06-26 23:15:51 -03001323 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001324 dprintk(4, "%s\n, channel: %d", __func__, fh->channel->idx);
Dean Anderson38f993a2008-06-26 23:15:51 -03001325 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1326 printk(KERN_ERR "invalid fh type0\n");
1327 return -EINVAL;
1328 }
1329 if (i != fh->type) {
1330 printk(KERN_ERR "invalid type i\n");
1331 return -EINVAL;
1332 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001333 s2255_stop_acquire(fh->channel);
Dean Andersonb7732a32009-03-30 11:59:56 -03001334 videobuf_streamoff(&fh->vb_vidq);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001335 res_free(fh);
Dean Andersonf78d92c2008-07-22 14:43:27 -03001336 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001337}
1338
1339static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *i)
1340{
1341 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001342 struct s2255_mode mode;
Dean Anderson38f993a2008-06-26 23:15:51 -03001343 struct videobuf_queue *q = &fh->vb_vidq;
1344 int ret = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001345 mutex_lock(&q->vb_lock);
1346 if (videobuf_queue_is_busy(q)) {
1347 dprintk(1, "queue busy\n");
1348 ret = -EBUSY;
1349 goto out_s_std;
1350 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001351 if (res_locked(fh)) {
Dean Anderson38f993a2008-06-26 23:15:51 -03001352 dprintk(1, "can't change standard after started\n");
1353 ret = -EBUSY;
1354 goto out_s_std;
1355 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001356 mode = fh->channel->mode;
Dean Anderson38f993a2008-06-26 23:15:51 -03001357 if (*i & V4L2_STD_NTSC) {
Dean Andersone6b44bc2010-03-08 20:04:48 -03001358 dprintk(4, "%s NTSC\n", __func__);
1359 /* if changing format, reset frame decimation/intervals */
Dean Andersonfe85ce92010-06-01 19:12:07 -03001360 if (mode.format != FORMAT_NTSC) {
1361 mode.restart = 1;
1362 mode.format = FORMAT_NTSC;
1363 mode.fdec = FDEC_1;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001364 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001365 } else if (*i & V4L2_STD_PAL) {
Dean Andersone6b44bc2010-03-08 20:04:48 -03001366 dprintk(4, "%s PAL\n", __func__);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001367 if (mode.format != FORMAT_PAL) {
1368 mode.restart = 1;
1369 mode.format = FORMAT_PAL;
1370 mode.fdec = FDEC_1;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001371 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001372 } else {
1373 ret = -EINVAL;
1374 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001375 if (mode.restart)
1376 s2255_set_mode(fh->channel, &mode);
Dean Anderson38f993a2008-06-26 23:15:51 -03001377out_s_std:
1378 mutex_unlock(&q->vb_lock);
1379 return ret;
1380}
1381
1382/* Sensoray 2255 is a multiple channel capture device.
1383 It does not have a "crossbar" of inputs.
1384 We use one V4L device per channel. The user must
1385 be aware that certain combinations are not allowed.
1386 For instance, you cannot do full FPS on more than 2 channels(2 videodevs)
1387 at once in color(you can do full fps on 4 channels with greyscale.
1388*/
1389static int vidioc_enum_input(struct file *file, void *priv,
1390 struct v4l2_input *inp)
1391{
Dean Anderson4de39f52010-03-03 19:39:19 -03001392 struct s2255_fh *fh = priv;
1393 struct s2255_dev *dev = fh->dev;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001394 struct s2255_channel *channel = fh->channel;
Dean Anderson4de39f52010-03-03 19:39:19 -03001395 u32 status = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001396 if (inp->index != 0)
1397 return -EINVAL;
Dean Anderson38f993a2008-06-26 23:15:51 -03001398 inp->type = V4L2_INPUT_TYPE_CAMERA;
1399 inp->std = S2255_NORMS;
Dean Anderson4de39f52010-03-03 19:39:19 -03001400 inp->status = 0;
1401 if (dev->dsp_fw_ver >= S2255_MIN_DSP_STATUS) {
1402 int rc;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001403 rc = s2255_cmd_status(fh->channel, &status);
Dean Anderson4de39f52010-03-03 19:39:19 -03001404 dprintk(4, "s2255_cmd_status rc: %d status %x\n", rc, status);
1405 if (rc == 0)
1406 inp->status = (status & 0x01) ? 0
1407 : V4L2_IN_ST_NO_SIGNAL;
1408 }
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001409 switch (dev->pid) {
1410 case 0x2255:
1411 default:
1412 strlcpy(inp->name, "Composite", sizeof(inp->name));
1413 break;
1414 case 0x2257:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001415 strlcpy(inp->name, (channel->idx < 2) ? "Composite" : "S-Video",
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001416 sizeof(inp->name));
1417 break;
1418 }
Dean Anderson3f8d6f72008-06-30 21:28:34 -03001419 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001420}
1421
1422static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
1423{
1424 *i = 0;
1425 return 0;
1426}
1427static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
1428{
1429 if (i > 0)
1430 return -EINVAL;
1431 return 0;
1432}
1433
1434/* --- controls ---------------------------------------------- */
1435static int vidioc_queryctrl(struct file *file, void *priv,
1436 struct v4l2_queryctrl *qc)
1437{
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001438 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001439 struct s2255_channel *channel = fh->channel;
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001440 struct s2255_dev *dev = fh->dev;
Dean Anderson2e70db92010-03-05 14:29:09 -03001441 switch (qc->id) {
1442 case V4L2_CID_BRIGHTNESS:
1443 v4l2_ctrl_query_fill(qc, -127, 127, 1, DEF_BRIGHT);
1444 break;
1445 case V4L2_CID_CONTRAST:
1446 v4l2_ctrl_query_fill(qc, 0, 255, 1, DEF_CONTRAST);
1447 break;
1448 case V4L2_CID_SATURATION:
1449 v4l2_ctrl_query_fill(qc, 0, 255, 1, DEF_SATURATION);
1450 break;
1451 case V4L2_CID_HUE:
1452 v4l2_ctrl_query_fill(qc, 0, 255, 1, DEF_HUE);
1453 break;
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001454 case V4L2_CID_PRIVATE_COLORFILTER:
1455 if (dev->dsp_fw_ver < S2255_MIN_DSP_COLORFILTER)
1456 return -EINVAL;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001457 if ((dev->pid == 0x2257) && (channel->idx > 1))
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001458 return -EINVAL;
1459 strlcpy(qc->name, "Color Filter", sizeof(qc->name));
1460 qc->type = V4L2_CTRL_TYPE_MENU;
1461 qc->minimum = 0;
1462 qc->maximum = 1;
1463 qc->step = 1;
1464 qc->default_value = 1;
1465 qc->flags = 0;
1466 break;
Dean Anderson2e70db92010-03-05 14:29:09 -03001467 default:
1468 return -EINVAL;
1469 }
1470 dprintk(4, "%s, id %d\n", __func__, qc->id);
1471 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001472}
1473
1474static int vidioc_g_ctrl(struct file *file, void *priv,
1475 struct v4l2_control *ctrl)
1476{
Dean Anderson2e70db92010-03-05 14:29:09 -03001477 struct s2255_fh *fh = priv;
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001478 struct s2255_dev *dev = fh->dev;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001479 struct s2255_channel *channel = fh->channel;
Dean Anderson2e70db92010-03-05 14:29:09 -03001480 switch (ctrl->id) {
1481 case V4L2_CID_BRIGHTNESS:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001482 ctrl->value = channel->mode.bright;
Dean Anderson2e70db92010-03-05 14:29:09 -03001483 break;
1484 case V4L2_CID_CONTRAST:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001485 ctrl->value = channel->mode.contrast;
Dean Anderson2e70db92010-03-05 14:29:09 -03001486 break;
1487 case V4L2_CID_SATURATION:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001488 ctrl->value = channel->mode.saturation;
Dean Anderson2e70db92010-03-05 14:29:09 -03001489 break;
1490 case V4L2_CID_HUE:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001491 ctrl->value = channel->mode.hue;
Dean Anderson2e70db92010-03-05 14:29:09 -03001492 break;
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001493 case V4L2_CID_PRIVATE_COLORFILTER:
1494 if (dev->dsp_fw_ver < S2255_MIN_DSP_COLORFILTER)
1495 return -EINVAL;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001496 if ((dev->pid == 0x2257) && (channel->idx > 1))
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001497 return -EINVAL;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001498 ctrl->value = !((channel->mode.color & MASK_INPUT_TYPE) >> 16);
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001499 break;
Dean Anderson2e70db92010-03-05 14:29:09 -03001500 default:
1501 return -EINVAL;
1502 }
1503 dprintk(4, "%s, id %d val %d\n", __func__, ctrl->id, ctrl->value);
1504 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001505}
1506
1507static int vidioc_s_ctrl(struct file *file, void *priv,
1508 struct v4l2_control *ctrl)
1509{
Dean Anderson38f993a2008-06-26 23:15:51 -03001510 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001511 struct s2255_channel *channel = fh->channel;
1512 struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev);
1513 struct s2255_mode mode;
1514 mode = channel->mode;
Dean Anderson2e70db92010-03-05 14:29:09 -03001515 dprintk(4, "%s\n", __func__);
1516 /* update the mode to the corresponding value */
1517 switch (ctrl->id) {
1518 case V4L2_CID_BRIGHTNESS:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001519 mode.bright = ctrl->value;
Dean Anderson2e70db92010-03-05 14:29:09 -03001520 break;
1521 case V4L2_CID_CONTRAST:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001522 mode.contrast = ctrl->value;
Dean Anderson2e70db92010-03-05 14:29:09 -03001523 break;
1524 case V4L2_CID_HUE:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001525 mode.hue = ctrl->value;
Dean Anderson2e70db92010-03-05 14:29:09 -03001526 break;
1527 case V4L2_CID_SATURATION:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001528 mode.saturation = ctrl->value;
Dean Anderson2e70db92010-03-05 14:29:09 -03001529 break;
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001530 case V4L2_CID_PRIVATE_COLORFILTER:
1531 if (dev->dsp_fw_ver < S2255_MIN_DSP_COLORFILTER)
1532 return -EINVAL;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001533 if ((dev->pid == 0x2257) && (channel->idx > 1))
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001534 return -EINVAL;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001535 mode.color &= ~MASK_INPUT_TYPE;
1536 mode.color |= ((ctrl->value ? 0 : 1) << 16);
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001537 break;
Dean Anderson2e70db92010-03-05 14:29:09 -03001538 default:
1539 return -EINVAL;
Dean Anderson38f993a2008-06-26 23:15:51 -03001540 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001541 mode.restart = 0;
Dean Anderson2e70db92010-03-05 14:29:09 -03001542 /* set mode here. Note: stream does not need restarted.
1543 some V4L programs restart stream unnecessarily
1544 after a s_crtl.
1545 */
Dean Andersonfe85ce92010-06-01 19:12:07 -03001546 s2255_set_mode(fh->channel, &mode);
Dean Anderson2e70db92010-03-05 14:29:09 -03001547 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001548}
1549
Dean Anderson22b88d42008-08-29 15:33:19 -03001550static int vidioc_g_jpegcomp(struct file *file, void *priv,
1551 struct v4l2_jpegcompression *jc)
1552{
1553 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001554 struct s2255_channel *channel = fh->channel;
1555 *jc = channel->jc;
Dean Anderson85b85482010-04-08 23:51:17 -03001556 dprintk(2, "%s: quality %d\n", __func__, jc->quality);
Dean Anderson22b88d42008-08-29 15:33:19 -03001557 return 0;
1558}
1559
1560static int vidioc_s_jpegcomp(struct file *file, void *priv,
1561 struct v4l2_jpegcompression *jc)
1562{
1563 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001564 struct s2255_channel *channel = fh->channel;
Dean Anderson22b88d42008-08-29 15:33:19 -03001565 if (jc->quality < 0 || jc->quality > 100)
1566 return -EINVAL;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001567 channel->jc.quality = jc->quality;
Dean Anderson85b85482010-04-08 23:51:17 -03001568 dprintk(2, "%s: quality %d\n", __func__, jc->quality);
Dean Anderson22b88d42008-08-29 15:33:19 -03001569 return 0;
1570}
Dean Anderson7d853532009-05-15 14:32:04 -03001571
1572static int vidioc_g_parm(struct file *file, void *priv,
1573 struct v4l2_streamparm *sp)
1574{
1575 struct s2255_fh *fh = priv;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001576 __u32 def_num, def_dem;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001577 struct s2255_channel *channel = fh->channel;
Dean Anderson7d853532009-05-15 14:32:04 -03001578 if (sp->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1579 return -EINVAL;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001580 memset(sp, 0, sizeof(struct v4l2_streamparm));
1581 sp->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001582 sp->parm.capture.capturemode = channel->cap_parm.capturemode;
1583 def_num = (channel->mode.format == FORMAT_NTSC) ? 1001 : 1000;
1584 def_dem = (channel->mode.format == FORMAT_NTSC) ? 30000 : 25000;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001585 sp->parm.capture.timeperframe.denominator = def_dem;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001586 switch (channel->mode.fdec) {
Dean Andersone6b44bc2010-03-08 20:04:48 -03001587 default:
1588 case FDEC_1:
1589 sp->parm.capture.timeperframe.numerator = def_num;
1590 break;
1591 case FDEC_2:
1592 sp->parm.capture.timeperframe.numerator = def_num * 2;
1593 break;
1594 case FDEC_3:
1595 sp->parm.capture.timeperframe.numerator = def_num * 3;
1596 break;
1597 case FDEC_5:
1598 sp->parm.capture.timeperframe.numerator = def_num * 5;
1599 break;
1600 }
1601 dprintk(4, "%s capture mode, %d timeperframe %d/%d\n", __func__,
1602 sp->parm.capture.capturemode,
1603 sp->parm.capture.timeperframe.numerator,
1604 sp->parm.capture.timeperframe.denominator);
Dean Anderson7d853532009-05-15 14:32:04 -03001605 return 0;
1606}
1607
1608static int vidioc_s_parm(struct file *file, void *priv,
1609 struct v4l2_streamparm *sp)
1610{
1611 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001612 struct s2255_channel *channel = fh->channel;
1613 struct s2255_mode mode;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001614 int fdec = FDEC_1;
1615 __u32 def_num, def_dem;
Dean Anderson7d853532009-05-15 14:32:04 -03001616 if (sp->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1617 return -EINVAL;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001618 mode = channel->mode;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001619 /* high quality capture mode requires a stream restart */
Dean Andersonfe85ce92010-06-01 19:12:07 -03001620 if (channel->cap_parm.capturemode
1621 != sp->parm.capture.capturemode && res_locked(fh))
Dean Andersone6b44bc2010-03-08 20:04:48 -03001622 return -EBUSY;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001623 def_num = (mode.format == FORMAT_NTSC) ? 1001 : 1000;
1624 def_dem = (mode.format == FORMAT_NTSC) ? 30000 : 25000;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001625 if (def_dem != sp->parm.capture.timeperframe.denominator)
1626 sp->parm.capture.timeperframe.numerator = def_num;
1627 else if (sp->parm.capture.timeperframe.numerator <= def_num)
1628 sp->parm.capture.timeperframe.numerator = def_num;
1629 else if (sp->parm.capture.timeperframe.numerator <= (def_num * 2)) {
1630 sp->parm.capture.timeperframe.numerator = def_num * 2;
1631 fdec = FDEC_2;
1632 } else if (sp->parm.capture.timeperframe.numerator <= (def_num * 3)) {
1633 sp->parm.capture.timeperframe.numerator = def_num * 3;
1634 fdec = FDEC_3;
1635 } else {
1636 sp->parm.capture.timeperframe.numerator = def_num * 5;
1637 fdec = FDEC_5;
1638 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001639 mode.fdec = fdec;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001640 sp->parm.capture.timeperframe.denominator = def_dem;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001641 s2255_set_mode(channel, &mode);
Dean Andersone6b44bc2010-03-08 20:04:48 -03001642 dprintk(4, "%s capture mode, %d timeperframe %d/%d, fdec %d\n",
1643 __func__,
1644 sp->parm.capture.capturemode,
1645 sp->parm.capture.timeperframe.numerator,
1646 sp->parm.capture.timeperframe.denominator, fdec);
Dean Anderson7d853532009-05-15 14:32:04 -03001647 return 0;
1648}
Dean Andersone6b44bc2010-03-08 20:04:48 -03001649
1650static int vidioc_enum_frameintervals(struct file *file, void *priv,
1651 struct v4l2_frmivalenum *fe)
1652{
1653 int is_ntsc = 0;
1654#define NUM_FRAME_ENUMS 4
1655 int frm_dec[NUM_FRAME_ENUMS] = {1, 2, 3, 5};
1656 if (fe->index < 0 || fe->index >= NUM_FRAME_ENUMS)
1657 return -EINVAL;
1658 switch (fe->width) {
1659 case 640:
1660 if (fe->height != 240 && fe->height != 480)
1661 return -EINVAL;
1662 is_ntsc = 1;
1663 break;
1664 case 320:
1665 if (fe->height != 240)
1666 return -EINVAL;
1667 is_ntsc = 1;
1668 break;
1669 case 704:
1670 if (fe->height != 288 && fe->height != 576)
1671 return -EINVAL;
1672 break;
1673 case 352:
1674 if (fe->height != 288)
1675 return -EINVAL;
1676 break;
1677 default:
1678 return -EINVAL;
1679 }
1680 fe->type = V4L2_FRMIVAL_TYPE_DISCRETE;
1681 fe->discrete.denominator = is_ntsc ? 30000 : 25000;
1682 fe->discrete.numerator = (is_ntsc ? 1001 : 1000) * frm_dec[fe->index];
1683 dprintk(4, "%s discrete %d/%d\n", __func__, fe->discrete.numerator,
1684 fe->discrete.denominator);
1685 return 0;
1686}
1687
Hans Verkuilbec43662008-12-30 06:58:20 -03001688static int s2255_open(struct file *file)
Dean Anderson38f993a2008-06-26 23:15:51 -03001689{
Laurent Pinchart63b0d5a2009-12-10 11:44:04 -02001690 struct video_device *vdev = video_devdata(file);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001691 struct s2255_channel *channel = video_drvdata(file);
1692 struct s2255_dev *dev = to_s2255_dev(vdev->v4l2_dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03001693 struct s2255_fh *fh;
Laurent Pinchart63b0d5a2009-12-10 11:44:04 -02001694 enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
Dean Anderson14d96262008-08-25 13:58:55 -03001695 int state;
Laurent Pinchart50462eb2009-12-10 11:47:13 -02001696 dprintk(1, "s2255: open called (dev=%s)\n",
1697 video_device_node_name(vdev));
Dean Andersonff7e22d2010-04-08 23:38:07 -03001698 /*
1699 * open lock necessary to prevent multiple instances
1700 * of v4l-conf (or other programs) from simultaneously
1701 * reloading firmware.
1702 */
Dean Anderson38f993a2008-06-26 23:15:51 -03001703 mutex_lock(&dev->open_lock);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001704 state = atomic_read(&dev->fw_data->fw_state);
1705 switch (state) {
1706 case S2255_FW_DISCONNECTING:
1707 mutex_unlock(&dev->open_lock);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001708 return -ENODEV;
Dean Anderson14d96262008-08-25 13:58:55 -03001709 case S2255_FW_FAILED:
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03001710 s2255_dev_err(&dev->udev->dev,
1711 "firmware load failed. retrying.\n");
Dean Anderson14d96262008-08-25 13:58:55 -03001712 s2255_fwload_start(dev, 1);
Dean Anderson38f993a2008-06-26 23:15:51 -03001713 wait_event_timeout(dev->fw_data->wait_fw,
Dean Anderson14d96262008-08-25 13:58:55 -03001714 ((atomic_read(&dev->fw_data->fw_state)
1715 == S2255_FW_SUCCESS) ||
1716 (atomic_read(&dev->fw_data->fw_state)
1717 == S2255_FW_DISCONNECTING)),
Dean Anderson38f993a2008-06-26 23:15:51 -03001718 msecs_to_jiffies(S2255_LOAD_TIMEOUT));
Dean Andersonff7e22d2010-04-08 23:38:07 -03001719 /* state may have changed, re-read */
1720 state = atomic_read(&dev->fw_data->fw_state);
Dean Anderson14d96262008-08-25 13:58:55 -03001721 break;
1722 case S2255_FW_NOTLOADED:
1723 case S2255_FW_LOADED_DSPWAIT:
Dean Anderson38f993a2008-06-26 23:15:51 -03001724 /* give S2255_LOAD_TIMEOUT time for firmware to load in case
1725 driver loaded and then device immediately opened */
1726 printk(KERN_INFO "%s waiting for firmware load\n", __func__);
1727 wait_event_timeout(dev->fw_data->wait_fw,
Dean Anderson14d96262008-08-25 13:58:55 -03001728 ((atomic_read(&dev->fw_data->fw_state)
1729 == S2255_FW_SUCCESS) ||
1730 (atomic_read(&dev->fw_data->fw_state)
1731 == S2255_FW_DISCONNECTING)),
Dean Andersoneb78dee2010-04-12 15:05:37 -03001732 msecs_to_jiffies(S2255_LOAD_TIMEOUT));
Dean Andersonff7e22d2010-04-08 23:38:07 -03001733 /* state may have changed, re-read */
1734 state = atomic_read(&dev->fw_data->fw_state);
Dean Anderson14d96262008-08-25 13:58:55 -03001735 break;
1736 case S2255_FW_SUCCESS:
1737 default:
1738 break;
1739 }
Dean Andersonff7e22d2010-04-08 23:38:07 -03001740 /* state may have changed in above switch statement */
1741 switch (state) {
1742 case S2255_FW_SUCCESS:
1743 break;
1744 case S2255_FW_FAILED:
1745 printk(KERN_INFO "2255 firmware load failed.\n");
Dean Andersoneb78dee2010-04-12 15:05:37 -03001746 mutex_unlock(&dev->open_lock);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001747 return -ENODEV;
1748 case S2255_FW_DISCONNECTING:
1749 printk(KERN_INFO "%s: disconnecting\n", __func__);
Dean Andersoneb78dee2010-04-12 15:05:37 -03001750 mutex_unlock(&dev->open_lock);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001751 return -ENODEV;
1752 case S2255_FW_LOADED_DSPWAIT:
1753 case S2255_FW_NOTLOADED:
1754 printk(KERN_INFO "%s: firmware not loaded yet"
1755 "please try again later\n",
1756 __func__);
Dean Andersoneb78dee2010-04-12 15:05:37 -03001757 /*
1758 * Timeout on firmware load means device unusable.
1759 * Set firmware failure state.
1760 * On next s2255_open the firmware will be reloaded.
1761 */
1762 atomic_set(&dev->fw_data->fw_state,
1763 S2255_FW_FAILED);
1764 mutex_unlock(&dev->open_lock);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001765 return -EAGAIN;
1766 default:
1767 printk(KERN_INFO "%s: unknown state\n", __func__);
Dean Andersoneb78dee2010-04-12 15:05:37 -03001768 mutex_unlock(&dev->open_lock);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001769 return -EFAULT;
Dean Anderson38f993a2008-06-26 23:15:51 -03001770 }
Dean Andersoneb78dee2010-04-12 15:05:37 -03001771 mutex_unlock(&dev->open_lock);
Dean Anderson38f993a2008-06-26 23:15:51 -03001772 /* allocate + initialize per filehandle data */
1773 fh = kzalloc(sizeof(*fh), GFP_KERNEL);
Dean Andersona5ef91c2010-04-08 23:46:08 -03001774 if (NULL == fh)
Dean Anderson38f993a2008-06-26 23:15:51 -03001775 return -ENOMEM;
Dean Anderson38f993a2008-06-26 23:15:51 -03001776 file->private_data = fh;
1777 fh->dev = dev;
1778 fh->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001779 fh->channel = channel;
1780 if (!channel->configured) {
1781 /* configure channel to default state */
1782 channel->fmt = &formats[0];
1783 s2255_set_mode(channel, &channel->mode);
1784 channel->configured = 1;
Dean Anderson14d96262008-08-25 13:58:55 -03001785 }
Dean Anderson85b85482010-04-08 23:51:17 -03001786 dprintk(1, "%s: dev=%s type=%s\n", __func__,
Dean Andersonff7e22d2010-04-08 23:38:07 -03001787 video_device_node_name(vdev), v4l2_type_names[type]);
Dean Anderson85b85482010-04-08 23:51:17 -03001788 dprintk(2, "%s: fh=0x%08lx, dev=0x%08lx, vidq=0x%08lx\n", __func__,
Dean Anderson38f993a2008-06-26 23:15:51 -03001789 (unsigned long)fh, (unsigned long)dev,
Dean Andersonfe85ce92010-06-01 19:12:07 -03001790 (unsigned long)&channel->vidq);
Dean Anderson85b85482010-04-08 23:51:17 -03001791 dprintk(4, "%s: list_empty active=%d\n", __func__,
Dean Andersonfe85ce92010-06-01 19:12:07 -03001792 list_empty(&channel->vidq.active));
Dean Anderson38f993a2008-06-26 23:15:51 -03001793 videobuf_queue_vmalloc_init(&fh->vb_vidq, &s2255_video_qops,
1794 NULL, &dev->slock,
1795 fh->type,
1796 V4L2_FIELD_INTERLACED,
Pete Eberleina19a5cd2010-12-20 19:18:59 -03001797 sizeof(struct s2255_buffer),
1798 fh, vdev->lock);
Dean Anderson38f993a2008-06-26 23:15:51 -03001799 return 0;
1800}
1801
1802
1803static unsigned int s2255_poll(struct file *file,
1804 struct poll_table_struct *wait)
1805{
1806 struct s2255_fh *fh = file->private_data;
1807 int rc;
1808 dprintk(100, "%s\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03001809 if (V4L2_BUF_TYPE_VIDEO_CAPTURE != fh->type)
1810 return POLLERR;
Dean Anderson38f993a2008-06-26 23:15:51 -03001811 rc = videobuf_poll_stream(file, &fh->vb_vidq, wait);
1812 return rc;
1813}
1814
Dean Andersond62e85a2010-04-09 19:54:26 -03001815static void s2255_destroy(struct s2255_dev *dev)
Dean Anderson38f993a2008-06-26 23:15:51 -03001816{
Dean Anderson38f993a2008-06-26 23:15:51 -03001817 /* board shutdown stops the read pipe if it is running */
1818 s2255_board_shutdown(dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03001819 /* make sure firmware still not trying to load */
Dean Andersonf78d92c2008-07-22 14:43:27 -03001820 del_timer(&dev->timer); /* only started in .probe and .open */
Dean Anderson38f993a2008-06-26 23:15:51 -03001821 if (dev->fw_data->fw_urb) {
Dean Anderson38f993a2008-06-26 23:15:51 -03001822 usb_kill_urb(dev->fw_data->fw_urb);
1823 usb_free_urb(dev->fw_data->fw_urb);
1824 dev->fw_data->fw_urb = NULL;
1825 }
Dean Andersonf78d92c2008-07-22 14:43:27 -03001826 if (dev->fw_data->fw)
1827 release_firmware(dev->fw_data->fw);
1828 kfree(dev->fw_data->pfw_data);
1829 kfree(dev->fw_data);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001830 /* reset the DSP so firmware can be reloaded next time */
1831 s2255_reset_dsppower(dev);
1832 mutex_destroy(&dev->open_lock);
1833 mutex_destroy(&dev->lock);
Dean Anderson38f993a2008-06-26 23:15:51 -03001834 usb_put_dev(dev->udev);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001835 v4l2_device_unregister(&dev->v4l2_dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03001836 dprintk(1, "%s", __func__);
Dean Andersonb7732a32009-03-30 11:59:56 -03001837 kfree(dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03001838}
1839
Dean Andersonff7e22d2010-04-08 23:38:07 -03001840static int s2255_release(struct file *file)
Dean Anderson38f993a2008-06-26 23:15:51 -03001841{
1842 struct s2255_fh *fh = file->private_data;
1843 struct s2255_dev *dev = fh->dev;
Laurent Pinchart50462eb2009-12-10 11:47:13 -02001844 struct video_device *vdev = video_devdata(file);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001845 struct s2255_channel *channel = fh->channel;
Dean Anderson38f993a2008-06-26 23:15:51 -03001846 if (!dev)
1847 return -ENODEV;
Dean Andersonf78d92c2008-07-22 14:43:27 -03001848 /* turn off stream */
1849 if (res_check(fh)) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03001850 if (channel->b_acquire)
1851 s2255_stop_acquire(fh->channel);
Dean Andersonf78d92c2008-07-22 14:43:27 -03001852 videobuf_streamoff(&fh->vb_vidq);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001853 res_free(fh);
Dean Andersonf78d92c2008-07-22 14:43:27 -03001854 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001855 videobuf_mmap_free(&fh->vb_vidq);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001856 dprintk(1, "%s (dev=%s)\n", __func__, video_device_node_name(vdev));
Dean Andersonf78d92c2008-07-22 14:43:27 -03001857 kfree(fh);
Dean Anderson38f993a2008-06-26 23:15:51 -03001858 return 0;
1859}
1860
1861static int s2255_mmap_v4l(struct file *file, struct vm_area_struct *vma)
1862{
1863 struct s2255_fh *fh = file->private_data;
1864 int ret;
1865
1866 if (!fh)
1867 return -ENODEV;
Dean Anderson85b85482010-04-08 23:51:17 -03001868 dprintk(4, "%s, vma=0x%08lx\n", __func__, (unsigned long)vma);
Dean Anderson38f993a2008-06-26 23:15:51 -03001869 ret = videobuf_mmap_mapper(&fh->vb_vidq, vma);
Dean Anderson85b85482010-04-08 23:51:17 -03001870 dprintk(4, "%s vma start=0x%08lx, size=%ld, ret=%d\n", __func__,
Dean Anderson38f993a2008-06-26 23:15:51 -03001871 (unsigned long)vma->vm_start,
1872 (unsigned long)vma->vm_end - (unsigned long)vma->vm_start, ret);
Dean Anderson38f993a2008-06-26 23:15:51 -03001873 return ret;
1874}
1875
Hans Verkuilbec43662008-12-30 06:58:20 -03001876static const struct v4l2_file_operations s2255_fops_v4l = {
Dean Anderson38f993a2008-06-26 23:15:51 -03001877 .owner = THIS_MODULE,
1878 .open = s2255_open,
Dean Andersonff7e22d2010-04-08 23:38:07 -03001879 .release = s2255_release,
Dean Anderson38f993a2008-06-26 23:15:51 -03001880 .poll = s2255_poll,
Pete Eberleina19a5cd2010-12-20 19:18:59 -03001881 .unlocked_ioctl = video_ioctl2, /* V4L2 ioctl handler */
Dean Anderson38f993a2008-06-26 23:15:51 -03001882 .mmap = s2255_mmap_v4l,
Dean Anderson38f993a2008-06-26 23:15:51 -03001883};
1884
Hans Verkuila3998102008-07-21 02:57:38 -03001885static const struct v4l2_ioctl_ops s2255_ioctl_ops = {
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001886 .vidioc_querymenu = vidioc_querymenu,
Dean Anderson38f993a2008-06-26 23:15:51 -03001887 .vidioc_querycap = vidioc_querycap,
1888 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
1889 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
1890 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
1891 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
1892 .vidioc_reqbufs = vidioc_reqbufs,
1893 .vidioc_querybuf = vidioc_querybuf,
1894 .vidioc_qbuf = vidioc_qbuf,
1895 .vidioc_dqbuf = vidioc_dqbuf,
1896 .vidioc_s_std = vidioc_s_std,
1897 .vidioc_enum_input = vidioc_enum_input,
1898 .vidioc_g_input = vidioc_g_input,
1899 .vidioc_s_input = vidioc_s_input,
1900 .vidioc_queryctrl = vidioc_queryctrl,
1901 .vidioc_g_ctrl = vidioc_g_ctrl,
1902 .vidioc_s_ctrl = vidioc_s_ctrl,
1903 .vidioc_streamon = vidioc_streamon,
1904 .vidioc_streamoff = vidioc_streamoff,
Dean Anderson22b88d42008-08-29 15:33:19 -03001905 .vidioc_s_jpegcomp = vidioc_s_jpegcomp,
1906 .vidioc_g_jpegcomp = vidioc_g_jpegcomp,
Dean Anderson7d853532009-05-15 14:32:04 -03001907 .vidioc_s_parm = vidioc_s_parm,
1908 .vidioc_g_parm = vidioc_g_parm,
Dean Andersone6b44bc2010-03-08 20:04:48 -03001909 .vidioc_enum_frameintervals = vidioc_enum_frameintervals,
Hans Verkuila3998102008-07-21 02:57:38 -03001910};
1911
Dean Andersonff7e22d2010-04-08 23:38:07 -03001912static void s2255_video_device_release(struct video_device *vdev)
1913{
Dean Andersonfe85ce92010-06-01 19:12:07 -03001914 struct s2255_dev *dev = to_s2255_dev(vdev->v4l2_dev);
1915 dprintk(4, "%s, chnls: %d \n", __func__,
1916 atomic_read(&dev->num_channels));
1917 if (atomic_dec_and_test(&dev->num_channels))
Dean Andersond62e85a2010-04-09 19:54:26 -03001918 s2255_destroy(dev);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001919 return;
1920}
1921
Hans Verkuila3998102008-07-21 02:57:38 -03001922static struct video_device template = {
1923 .name = "s2255v",
Hans Verkuila3998102008-07-21 02:57:38 -03001924 .fops = &s2255_fops_v4l,
1925 .ioctl_ops = &s2255_ioctl_ops,
Dean Andersonff7e22d2010-04-08 23:38:07 -03001926 .release = s2255_video_device_release,
Dean Anderson38f993a2008-06-26 23:15:51 -03001927 .tvnorms = S2255_NORMS,
1928 .current_norm = V4L2_STD_NTSC_M,
1929};
1930
1931static int s2255_probe_v4l(struct s2255_dev *dev)
1932{
1933 int ret;
1934 int i;
1935 int cur_nr = video_nr;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001936 struct s2255_channel *channel;
Dean Anderson65c6edb2010-04-20 17:21:32 -03001937 ret = v4l2_device_register(&dev->interface->dev, &dev->v4l2_dev);
1938 if (ret)
1939 return ret;
Dean Anderson38f993a2008-06-26 23:15:51 -03001940 /* initialize all video 4 linux */
Dean Anderson38f993a2008-06-26 23:15:51 -03001941 /* register 4 video devices */
1942 for (i = 0; i < MAX_CHANNELS; i++) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03001943 channel = &dev->channel[i];
1944 INIT_LIST_HEAD(&channel->vidq.active);
1945 channel->vidq.dev = dev;
Dean Anderson38f993a2008-06-26 23:15:51 -03001946 /* register 4 video devices */
Dean Andersonfe85ce92010-06-01 19:12:07 -03001947 channel->vdev = template;
Pete Eberleina19a5cd2010-12-20 19:18:59 -03001948 channel->vdev.lock = &dev->lock;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001949 channel->vdev.v4l2_dev = &dev->v4l2_dev;
1950 video_set_drvdata(&channel->vdev, channel);
Dean Anderson38f993a2008-06-26 23:15:51 -03001951 if (video_nr == -1)
Dean Andersonfe85ce92010-06-01 19:12:07 -03001952 ret = video_register_device(&channel->vdev,
Dean Anderson38f993a2008-06-26 23:15:51 -03001953 VFL_TYPE_GRABBER,
1954 video_nr);
1955 else
Dean Andersonfe85ce92010-06-01 19:12:07 -03001956 ret = video_register_device(&channel->vdev,
Dean Anderson38f993a2008-06-26 23:15:51 -03001957 VFL_TYPE_GRABBER,
1958 cur_nr + i);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001959
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03001960 if (ret) {
Dean Anderson38f993a2008-06-26 23:15:51 -03001961 dev_err(&dev->udev->dev,
1962 "failed to register video device!\n");
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03001963 break;
Dean Anderson38f993a2008-06-26 23:15:51 -03001964 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001965 atomic_inc(&dev->num_channels);
Dean Anderson65c6edb2010-04-20 17:21:32 -03001966 v4l2_info(&dev->v4l2_dev, "V4L2 device registered as %s\n",
Dean Andersonfe85ce92010-06-01 19:12:07 -03001967 video_device_node_name(&channel->vdev));
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03001968
Dean Anderson38f993a2008-06-26 23:15:51 -03001969 }
Dean Andersonabce21f2009-04-23 16:04:41 -03001970 printk(KERN_INFO "Sensoray 2255 V4L driver Revision: %d.%d\n",
1971 S2255_MAJOR_VERSION,
1972 S2255_MINOR_VERSION);
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03001973 /* if no channels registered, return error and probe will fail*/
Dean Andersonfe85ce92010-06-01 19:12:07 -03001974 if (atomic_read(&dev->num_channels) == 0) {
Dean Anderson65c6edb2010-04-20 17:21:32 -03001975 v4l2_device_unregister(&dev->v4l2_dev);
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03001976 return ret;
Dean Anderson65c6edb2010-04-20 17:21:32 -03001977 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001978 if (atomic_read(&dev->num_channels) != MAX_CHANNELS)
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03001979 printk(KERN_WARNING "s2255: Not all channels available.\n");
1980 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001981}
1982
Dean Anderson38f993a2008-06-26 23:15:51 -03001983/* this function moves the usb stream read pipe data
1984 * into the system buffers.
1985 * returns 0 on success, EAGAIN if more data to process( call this
1986 * function again).
1987 *
1988 * Received frame structure:
Dean Anderson14d96262008-08-25 13:58:55 -03001989 * bytes 0-3: marker : 0x2255DA4AL (S2255_MARKER_FRAME)
Dean Anderson38f993a2008-06-26 23:15:51 -03001990 * bytes 4-7: channel: 0-3
1991 * bytes 8-11: payload size: size of the frame
1992 * bytes 12-payloadsize+12: frame data
1993 */
1994static int save_frame(struct s2255_dev *dev, struct s2255_pipeinfo *pipe_info)
1995{
Dean Anderson38f993a2008-06-26 23:15:51 -03001996 char *pdest;
1997 u32 offset = 0;
Dean Anderson14d96262008-08-25 13:58:55 -03001998 int bframe = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001999 char *psrc;
2000 unsigned long copy_size;
2001 unsigned long size;
2002 s32 idx = -1;
2003 struct s2255_framei *frm;
2004 unsigned char *pdata;
Dean Andersonfe85ce92010-06-01 19:12:07 -03002005 struct s2255_channel *channel;
Dean Anderson38f993a2008-06-26 23:15:51 -03002006 dprintk(100, "buffer to user\n");
Dean Andersonfe85ce92010-06-01 19:12:07 -03002007 channel = &dev->channel[dev->cc];
2008 idx = channel->cur_frame;
2009 frm = &channel->buffer.frame[idx];
Dean Anderson14d96262008-08-25 13:58:55 -03002010 if (frm->ulState == S2255_READ_IDLE) {
2011 int jj;
2012 unsigned int cc;
Dean Anderson3fa00602010-03-04 20:47:33 -03002013 __le32 *pdword; /*data from dsp is little endian */
Dean Anderson14d96262008-08-25 13:58:55 -03002014 int payload;
2015 /* search for marker codes */
2016 pdata = (unsigned char *)pipe_info->transfer_buffer;
Dean Anderson3fa00602010-03-04 20:47:33 -03002017 pdword = (__le32 *)pdata;
Dean Anderson14d96262008-08-25 13:58:55 -03002018 for (jj = 0; jj < (pipe_info->cur_transfer_size - 12); jj++) {
Dean Anderson3fa00602010-03-04 20:47:33 -03002019 switch (*pdword) {
Dean Anderson14d96262008-08-25 13:58:55 -03002020 case S2255_MARKER_FRAME:
Dean Anderson14d96262008-08-25 13:58:55 -03002021 dprintk(4, "found frame marker at offset:"
2022 " %d [%x %x]\n", jj, pdata[0],
2023 pdata[1]);
2024 offset = jj + PREFIX_SIZE;
2025 bframe = 1;
2026 cc = pdword[1];
2027 if (cc >= MAX_CHANNELS) {
2028 printk(KERN_ERR
2029 "bad channel\n");
2030 return -EINVAL;
2031 }
2032 /* reverse it */
2033 dev->cc = G_chnmap[cc];
Dean Andersonfe85ce92010-06-01 19:12:07 -03002034 channel = &dev->channel[dev->cc];
Dean Anderson14d96262008-08-25 13:58:55 -03002035 payload = pdword[3];
Dean Andersonfe85ce92010-06-01 19:12:07 -03002036 if (payload > channel->req_image_size) {
2037 channel->bad_payload++;
Dean Anderson14d96262008-08-25 13:58:55 -03002038 /* discard the bad frame */
2039 return -EINVAL;
2040 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03002041 channel->pkt_size = payload;
2042 channel->jpg_size = pdword[4];
Dean Anderson14d96262008-08-25 13:58:55 -03002043 break;
2044 case S2255_MARKER_RESPONSE:
Dean Andersonfe85ce92010-06-01 19:12:07 -03002045
Dean Anderson14d96262008-08-25 13:58:55 -03002046 pdata += DEF_USB_BLOCK;
2047 jj += DEF_USB_BLOCK;
2048 if (pdword[1] >= MAX_CHANNELS)
2049 break;
2050 cc = G_chnmap[pdword[1]];
Roel Kluinf14a2972009-10-23 07:59:42 -03002051 if (cc >= MAX_CHANNELS)
Dean Anderson14d96262008-08-25 13:58:55 -03002052 break;
Dean Andersonfe85ce92010-06-01 19:12:07 -03002053 channel = &dev->channel[cc];
Dean Anderson14d96262008-08-25 13:58:55 -03002054 switch (pdword[2]) {
Dean Andersonabce21f2009-04-23 16:04:41 -03002055 case S2255_RESPONSE_SETMODE:
Dean Anderson14d96262008-08-25 13:58:55 -03002056 /* check if channel valid */
2057 /* set mode ready */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002058 channel->setmode_ready = 1;
2059 wake_up(&channel->wait_setmode);
Dean Anderson14d96262008-08-25 13:58:55 -03002060 dprintk(5, "setmode ready %d\n", cc);
2061 break;
Dean Andersonabce21f2009-04-23 16:04:41 -03002062 case S2255_RESPONSE_FW:
Dean Anderson14d96262008-08-25 13:58:55 -03002063 dev->chn_ready |= (1 << cc);
2064 if ((dev->chn_ready & 0x0f) != 0x0f)
2065 break;
2066 /* all channels ready */
2067 printk(KERN_INFO "s2255: fw loaded\n");
2068 atomic_set(&dev->fw_data->fw_state,
2069 S2255_FW_SUCCESS);
2070 wake_up(&dev->fw_data->wait_fw);
2071 break;
Dean Anderson4de39f52010-03-03 19:39:19 -03002072 case S2255_RESPONSE_STATUS:
Dean Andersonfe85ce92010-06-01 19:12:07 -03002073 channel->vidstatus = pdword[3];
2074 channel->vidstatus_ready = 1;
2075 wake_up(&channel->wait_vidstatus);
Dean Anderson4de39f52010-03-03 19:39:19 -03002076 dprintk(5, "got vidstatus %x chan %d\n",
2077 pdword[3], cc);
2078 break;
Dean Anderson14d96262008-08-25 13:58:55 -03002079 default:
André Goddard Rosaaf901ca2009-11-14 13:09:05 -02002080 printk(KERN_INFO "s2255 unknown resp\n");
Dean Anderson14d96262008-08-25 13:58:55 -03002081 }
2082 default:
2083 pdata++;
2084 break;
2085 }
2086 if (bframe)
2087 break;
2088 } /* for */
2089 if (!bframe)
2090 return -EINVAL;
2091 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03002092 channel = &dev->channel[dev->cc];
2093 idx = channel->cur_frame;
2094 frm = &channel->buffer.frame[idx];
Dean Anderson14d96262008-08-25 13:58:55 -03002095 /* search done. now find out if should be acquiring on this channel */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002096 if (!channel->b_acquire) {
Dean Anderson14d96262008-08-25 13:58:55 -03002097 /* we found a frame, but this channel is turned off */
2098 frm->ulState = S2255_READ_IDLE;
2099 return -EINVAL;
2100 }
2101
2102 if (frm->ulState == S2255_READ_IDLE) {
2103 frm->ulState = S2255_READ_FRAME;
Dean Anderson38f993a2008-06-26 23:15:51 -03002104 frm->cur_size = 0;
2105 }
2106
Dean Anderson14d96262008-08-25 13:58:55 -03002107 /* skip the marker 512 bytes (and offset if out of sync) */
2108 psrc = (u8 *)pipe_info->transfer_buffer + offset;
2109
Dean Anderson38f993a2008-06-26 23:15:51 -03002110
2111 if (frm->lpvbits == NULL) {
2112 dprintk(1, "s2255 frame buffer == NULL.%p %p %d %d",
2113 frm, dev, dev->cc, idx);
2114 return -ENOMEM;
2115 }
2116
2117 pdest = frm->lpvbits + frm->cur_size;
2118
Dean Anderson14d96262008-08-25 13:58:55 -03002119 copy_size = (pipe_info->cur_transfer_size - offset);
Dean Anderson38f993a2008-06-26 23:15:51 -03002120
Dean Andersonfe85ce92010-06-01 19:12:07 -03002121 size = channel->pkt_size - PREFIX_SIZE;
Dean Anderson38f993a2008-06-26 23:15:51 -03002122
Dean Anderson14d96262008-08-25 13:58:55 -03002123 /* sanity check on pdest */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002124 if ((copy_size + frm->cur_size) < channel->req_image_size)
Dean Anderson14d96262008-08-25 13:58:55 -03002125 memcpy(pdest, psrc, copy_size);
Dean Anderson38f993a2008-06-26 23:15:51 -03002126
Dean Anderson38f993a2008-06-26 23:15:51 -03002127 frm->cur_size += copy_size;
Dean Anderson14d96262008-08-25 13:58:55 -03002128 dprintk(4, "cur_size size %lu size %lu \n", frm->cur_size, size);
Dean Anderson38f993a2008-06-26 23:15:51 -03002129
Dean Anderson14d96262008-08-25 13:58:55 -03002130 if (frm->cur_size >= size) {
Dean Anderson38f993a2008-06-26 23:15:51 -03002131 dprintk(2, "****************[%d]Buffer[%d]full*************\n",
Dean Andersonfe85ce92010-06-01 19:12:07 -03002132 dev->cc, idx);
2133 channel->last_frame = channel->cur_frame;
2134 channel->cur_frame++;
Dean Anderson38f993a2008-06-26 23:15:51 -03002135 /* end of system frame ring buffer, start at zero */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002136 if ((channel->cur_frame == SYS_FRAMES) ||
2137 (channel->cur_frame == channel->buffer.dwFrames))
2138 channel->cur_frame = 0;
Dean Anderson14d96262008-08-25 13:58:55 -03002139 /* frame ready */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002140 if (channel->b_acquire)
2141 s2255_got_frame(channel, channel->jpg_size);
2142 channel->frame_count++;
Dean Anderson14d96262008-08-25 13:58:55 -03002143 frm->ulState = S2255_READ_IDLE;
2144 frm->cur_size = 0;
2145
Dean Anderson38f993a2008-06-26 23:15:51 -03002146 }
2147 /* done successfully */
2148 return 0;
2149}
2150
2151static void s2255_read_video_callback(struct s2255_dev *dev,
2152 struct s2255_pipeinfo *pipe_info)
2153{
2154 int res;
2155 dprintk(50, "callback read video \n");
2156
2157 if (dev->cc >= MAX_CHANNELS) {
2158 dev->cc = 0;
2159 dev_err(&dev->udev->dev, "invalid channel\n");
2160 return;
2161 }
2162 /* otherwise copy to the system buffers */
2163 res = save_frame(dev, pipe_info);
Dean Anderson14d96262008-08-25 13:58:55 -03002164 if (res != 0)
2165 dprintk(4, "s2255: read callback failed\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03002166
2167 dprintk(50, "callback read video done\n");
2168 return;
2169}
2170
2171static long s2255_vendor_req(struct s2255_dev *dev, unsigned char Request,
2172 u16 Index, u16 Value, void *TransferBuffer,
2173 s32 TransferBufferLength, int bOut)
2174{
2175 int r;
2176 if (!bOut) {
2177 r = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0),
2178 Request,
2179 USB_TYPE_VENDOR | USB_RECIP_DEVICE |
2180 USB_DIR_IN,
2181 Value, Index, TransferBuffer,
2182 TransferBufferLength, HZ * 5);
2183 } else {
2184 r = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0),
2185 Request, USB_TYPE_VENDOR | USB_RECIP_DEVICE,
2186 Value, Index, TransferBuffer,
2187 TransferBufferLength, HZ * 5);
2188 }
2189 return r;
2190}
2191
2192/*
2193 * retrieve FX2 firmware version. future use.
2194 * @param dev pointer to device extension
2195 * @return -1 for fail, else returns firmware version as an int(16 bits)
2196 */
2197static int s2255_get_fx2fw(struct s2255_dev *dev)
2198{
2199 int fw;
2200 int ret;
2201 unsigned char transBuffer[64];
2202 ret = s2255_vendor_req(dev, S2255_VR_FW, 0, 0, transBuffer, 2,
2203 S2255_VR_IN);
2204 if (ret < 0)
2205 dprintk(2, "get fw error: %x\n", ret);
2206 fw = transBuffer[0] + (transBuffer[1] << 8);
2207 dprintk(2, "Get FW %x %x\n", transBuffer[0], transBuffer[1]);
2208 return fw;
2209}
2210
2211/*
2212 * Create the system ring buffer to copy frames into from the
2213 * usb read pipe.
2214 */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002215static int s2255_create_sys_buffers(struct s2255_channel *channel)
Dean Anderson38f993a2008-06-26 23:15:51 -03002216{
2217 unsigned long i;
2218 unsigned long reqsize;
2219 dprintk(1, "create sys buffers\n");
Dean Andersonfe85ce92010-06-01 19:12:07 -03002220 channel->buffer.dwFrames = SYS_FRAMES;
Dean Anderson38f993a2008-06-26 23:15:51 -03002221 /* always allocate maximum size(PAL) for system buffers */
2222 reqsize = SYS_FRAMES_MAXSIZE;
2223
2224 if (reqsize > SYS_FRAMES_MAXSIZE)
2225 reqsize = SYS_FRAMES_MAXSIZE;
2226
2227 for (i = 0; i < SYS_FRAMES; i++) {
2228 /* allocate the frames */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002229 channel->buffer.frame[i].lpvbits = vmalloc(reqsize);
2230 dprintk(1, "valloc %p chan %d, idx %lu, pdata %p\n",
2231 &channel->buffer.frame[i], channel->idx, i,
2232 channel->buffer.frame[i].lpvbits);
2233 channel->buffer.frame[i].size = reqsize;
2234 if (channel->buffer.frame[i].lpvbits == NULL) {
Dean Anderson38f993a2008-06-26 23:15:51 -03002235 printk(KERN_INFO "out of memory. using less frames\n");
Dean Andersonfe85ce92010-06-01 19:12:07 -03002236 channel->buffer.dwFrames = i;
Dean Anderson38f993a2008-06-26 23:15:51 -03002237 break;
2238 }
2239 }
2240
2241 /* make sure internal states are set */
2242 for (i = 0; i < SYS_FRAMES; i++) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03002243 channel->buffer.frame[i].ulState = 0;
2244 channel->buffer.frame[i].cur_size = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03002245 }
2246
Dean Andersonfe85ce92010-06-01 19:12:07 -03002247 channel->cur_frame = 0;
2248 channel->last_frame = -1;
Dean Anderson38f993a2008-06-26 23:15:51 -03002249 return 0;
2250}
2251
Dean Andersonfe85ce92010-06-01 19:12:07 -03002252static int s2255_release_sys_buffers(struct s2255_channel *channel)
Dean Anderson38f993a2008-06-26 23:15:51 -03002253{
2254 unsigned long i;
2255 dprintk(1, "release sys buffers\n");
2256 for (i = 0; i < SYS_FRAMES; i++) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03002257 if (channel->buffer.frame[i].lpvbits) {
Dean Anderson38f993a2008-06-26 23:15:51 -03002258 dprintk(1, "vfree %p\n",
Dean Andersonfe85ce92010-06-01 19:12:07 -03002259 channel->buffer.frame[i].lpvbits);
2260 vfree(channel->buffer.frame[i].lpvbits);
Dean Anderson38f993a2008-06-26 23:15:51 -03002261 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03002262 channel->buffer.frame[i].lpvbits = NULL;
Dean Anderson38f993a2008-06-26 23:15:51 -03002263 }
2264 return 0;
2265}
2266
2267static int s2255_board_init(struct s2255_dev *dev)
2268{
Dean Anderson38f993a2008-06-26 23:15:51 -03002269 struct s2255_mode mode_def = DEF_MODEI_NTSC_CONT;
2270 int fw_ver;
Dean Andersonab85c6a2010-04-08 23:39:12 -03002271 int j;
2272 struct s2255_pipeinfo *pipe = &dev->pipe;
Dean Anderson38f993a2008-06-26 23:15:51 -03002273 dprintk(4, "board init: %p", dev);
Dean Andersonab85c6a2010-04-08 23:39:12 -03002274 memset(pipe, 0, sizeof(*pipe));
2275 pipe->dev = dev;
2276 pipe->cur_transfer_size = S2255_USB_XFER_SIZE;
2277 pipe->max_transfer_size = S2255_USB_XFER_SIZE;
Dean Anderson38f993a2008-06-26 23:15:51 -03002278
Dean Andersonab85c6a2010-04-08 23:39:12 -03002279 pipe->transfer_buffer = kzalloc(pipe->max_transfer_size,
2280 GFP_KERNEL);
2281 if (pipe->transfer_buffer == NULL) {
2282 dprintk(1, "out of memory!\n");
2283 return -ENOMEM;
Dean Anderson38f993a2008-06-26 23:15:51 -03002284 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002285 /* query the firmware */
2286 fw_ver = s2255_get_fx2fw(dev);
2287
Dean Andersonabce21f2009-04-23 16:04:41 -03002288 printk(KERN_INFO "2255 usb firmware version %d.%d\n",
2289 (fw_ver >> 8) & 0xff,
2290 fw_ver & 0xff);
2291
2292 if (fw_ver < S2255_CUR_USB_FWVER)
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002293 dev_err(&dev->udev->dev,
Dean Andersonabce21f2009-04-23 16:04:41 -03002294 "usb firmware not up to date %d.%d\n",
2295 (fw_ver >> 8) & 0xff,
2296 fw_ver & 0xff);
Dean Anderson38f993a2008-06-26 23:15:51 -03002297
2298 for (j = 0; j < MAX_CHANNELS; j++) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03002299 struct s2255_channel *channel = &dev->channel[j];
2300 channel->b_acquire = 0;
2301 channel->mode = mode_def;
Dean Anderson5a34d9d2010-03-05 19:59:48 -03002302 if (dev->pid == 0x2257 && j > 1)
Dean Andersonfe85ce92010-06-01 19:12:07 -03002303 channel->mode.color |= (1 << 16);
2304 channel->jc.quality = S2255_DEF_JPEG_QUAL;
2305 channel->width = LINE_SZ_4CIFS_NTSC;
2306 channel->height = NUM_LINES_4CIFS_NTSC * 2;
2307 channel->fmt = &formats[0];
2308 channel->mode.restart = 1;
2309 channel->req_image_size = get_transfer_size(&mode_def);
2310 channel->frame_count = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03002311 /* create the system buffers */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002312 s2255_create_sys_buffers(channel);
Dean Anderson38f993a2008-06-26 23:15:51 -03002313 }
2314 /* start read pipe */
2315 s2255_start_readpipe(dev);
Dean Anderson85b85482010-04-08 23:51:17 -03002316 dprintk(1, "%s: success\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03002317 return 0;
2318}
2319
2320static int s2255_board_shutdown(struct s2255_dev *dev)
2321{
2322 u32 i;
Dean Anderson85b85482010-04-08 23:51:17 -03002323 dprintk(1, "%s: dev: %p", __func__, dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03002324
2325 for (i = 0; i < MAX_CHANNELS; i++) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03002326 if (dev->channel[i].b_acquire)
2327 s2255_stop_acquire(&dev->channel[i]);
Dean Anderson38f993a2008-06-26 23:15:51 -03002328 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002329 s2255_stop_readpipe(dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03002330 for (i = 0; i < MAX_CHANNELS; i++)
Dean Andersonfe85ce92010-06-01 19:12:07 -03002331 s2255_release_sys_buffers(&dev->channel[i]);
Dean Andersonab85c6a2010-04-08 23:39:12 -03002332 /* release transfer buffer */
2333 kfree(dev->pipe.transfer_buffer);
Dean Anderson38f993a2008-06-26 23:15:51 -03002334 return 0;
2335}
2336
2337static void read_pipe_completion(struct urb *purb)
2338{
2339 struct s2255_pipeinfo *pipe_info;
2340 struct s2255_dev *dev;
2341 int status;
2342 int pipe;
Dean Anderson38f993a2008-06-26 23:15:51 -03002343 pipe_info = purb->context;
Dean Anderson85b85482010-04-08 23:51:17 -03002344 dprintk(100, "%s: urb:%p, status %d\n", __func__, purb,
Dean Anderson38f993a2008-06-26 23:15:51 -03002345 purb->status);
2346 if (pipe_info == NULL) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002347 dev_err(&purb->dev->dev, "no context!\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03002348 return;
2349 }
2350
2351 dev = pipe_info->dev;
2352 if (dev == NULL) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002353 dev_err(&purb->dev->dev, "no context!\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03002354 return;
2355 }
2356 status = purb->status;
Dean Andersonb02064c2009-04-30 12:29:38 -03002357 /* if shutting down, do not resubmit, exit immediately */
2358 if (status == -ESHUTDOWN) {
Dean Anderson85b85482010-04-08 23:51:17 -03002359 dprintk(2, "%s: err shutdown\n", __func__);
Dean Andersonb02064c2009-04-30 12:29:38 -03002360 pipe_info->err_count++;
Dean Anderson38f993a2008-06-26 23:15:51 -03002361 return;
2362 }
2363
2364 if (pipe_info->state == 0) {
Dean Anderson85b85482010-04-08 23:51:17 -03002365 dprintk(2, "%s: exiting USB pipe", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03002366 return;
2367 }
2368
Dean Andersonb02064c2009-04-30 12:29:38 -03002369 if (status == 0)
2370 s2255_read_video_callback(dev, pipe_info);
2371 else {
2372 pipe_info->err_count++;
Dean Anderson85b85482010-04-08 23:51:17 -03002373 dprintk(1, "%s: failed URB %d\n", __func__, status);
Dean Andersonb02064c2009-04-30 12:29:38 -03002374 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002375
Dean Anderson38f993a2008-06-26 23:15:51 -03002376 pipe = usb_rcvbulkpipe(dev->udev, dev->read_endpoint);
2377 /* reuse urb */
2378 usb_fill_bulk_urb(pipe_info->stream_urb, dev->udev,
2379 pipe,
2380 pipe_info->transfer_buffer,
2381 pipe_info->cur_transfer_size,
2382 read_pipe_completion, pipe_info);
2383
2384 if (pipe_info->state != 0) {
2385 if (usb_submit_urb(pipe_info->stream_urb, GFP_KERNEL)) {
2386 dev_err(&dev->udev->dev, "error submitting urb\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03002387 }
2388 } else {
Dean Anderson85b85482010-04-08 23:51:17 -03002389 dprintk(2, "%s :complete state 0\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03002390 }
2391 return;
2392}
2393
2394static int s2255_start_readpipe(struct s2255_dev *dev)
2395{
2396 int pipe;
2397 int retval;
Dean Andersonab85c6a2010-04-08 23:39:12 -03002398 struct s2255_pipeinfo *pipe_info = &dev->pipe;
Dean Anderson38f993a2008-06-26 23:15:51 -03002399 pipe = usb_rcvbulkpipe(dev->udev, dev->read_endpoint);
Dean Anderson85b85482010-04-08 23:51:17 -03002400 dprintk(2, "%s: IN %d\n", __func__, dev->read_endpoint);
Dean Andersonab85c6a2010-04-08 23:39:12 -03002401 pipe_info->state = 1;
2402 pipe_info->err_count = 0;
2403 pipe_info->stream_urb = usb_alloc_urb(0, GFP_KERNEL);
2404 if (!pipe_info->stream_urb) {
2405 dev_err(&dev->udev->dev,
2406 "ReadStream: Unable to alloc URB\n");
2407 return -ENOMEM;
Dean Anderson38f993a2008-06-26 23:15:51 -03002408 }
Dean Andersonab85c6a2010-04-08 23:39:12 -03002409 /* transfer buffer allocated in board_init */
2410 usb_fill_bulk_urb(pipe_info->stream_urb, dev->udev,
2411 pipe,
2412 pipe_info->transfer_buffer,
2413 pipe_info->cur_transfer_size,
2414 read_pipe_completion, pipe_info);
Dean Andersonab85c6a2010-04-08 23:39:12 -03002415 retval = usb_submit_urb(pipe_info->stream_urb, GFP_KERNEL);
2416 if (retval) {
2417 printk(KERN_ERR "s2255: start read pipe failed\n");
2418 return retval;
2419 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002420 return 0;
2421}
2422
2423/* starts acquisition process */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002424static int s2255_start_acquire(struct s2255_channel *channel)
Dean Anderson38f993a2008-06-26 23:15:51 -03002425{
2426 unsigned char *buffer;
2427 int res;
2428 unsigned long chn_rev;
2429 int j;
Dean Andersonfe85ce92010-06-01 19:12:07 -03002430 struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev);
2431 chn_rev = G_chnmap[channel->idx];
Dean Anderson38f993a2008-06-26 23:15:51 -03002432 buffer = kzalloc(512, GFP_KERNEL);
2433 if (buffer == NULL) {
2434 dev_err(&dev->udev->dev, "out of mem\n");
2435 return -ENOMEM;
2436 }
2437
Dean Andersonfe85ce92010-06-01 19:12:07 -03002438 channel->last_frame = -1;
2439 channel->bad_payload = 0;
2440 channel->cur_frame = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03002441 for (j = 0; j < SYS_FRAMES; j++) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03002442 channel->buffer.frame[j].ulState = 0;
2443 channel->buffer.frame[j].cur_size = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03002444 }
2445
2446 /* send the start command */
Dean Anderson3fa00602010-03-04 20:47:33 -03002447 *(__le32 *) buffer = IN_DATA_TOKEN;
2448 *((__le32 *) buffer + 1) = (__le32) cpu_to_le32(chn_rev);
2449 *((__le32 *) buffer + 2) = CMD_START;
Dean Anderson38f993a2008-06-26 23:15:51 -03002450 res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
2451 if (res != 0)
2452 dev_err(&dev->udev->dev, "CMD_START error\n");
2453
Dean Andersonfe85ce92010-06-01 19:12:07 -03002454 dprintk(2, "start acquire exit[%d] %d \n", channel->idx, res);
Dean Anderson38f993a2008-06-26 23:15:51 -03002455 kfree(buffer);
2456 return 0;
2457}
2458
Dean Andersonfe85ce92010-06-01 19:12:07 -03002459static int s2255_stop_acquire(struct s2255_channel *channel)
Dean Anderson38f993a2008-06-26 23:15:51 -03002460{
2461 unsigned char *buffer;
2462 int res;
2463 unsigned long chn_rev;
Dean Andersonfe85ce92010-06-01 19:12:07 -03002464 struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev);
2465 chn_rev = G_chnmap[channel->idx];
Dean Anderson38f993a2008-06-26 23:15:51 -03002466 buffer = kzalloc(512, GFP_KERNEL);
2467 if (buffer == NULL) {
2468 dev_err(&dev->udev->dev, "out of mem\n");
2469 return -ENOMEM;
2470 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002471 /* send the stop command */
Dean Anderson3fa00602010-03-04 20:47:33 -03002472 *(__le32 *) buffer = IN_DATA_TOKEN;
2473 *((__le32 *) buffer + 1) = (__le32) cpu_to_le32(chn_rev);
2474 *((__le32 *) buffer + 2) = CMD_STOP;
Dean Anderson38f993a2008-06-26 23:15:51 -03002475 res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
Dean Anderson38f993a2008-06-26 23:15:51 -03002476 if (res != 0)
2477 dev_err(&dev->udev->dev, "CMD_STOP error\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03002478 kfree(buffer);
Dean Andersonfe85ce92010-06-01 19:12:07 -03002479 channel->b_acquire = 0;
2480 dprintk(4, "%s: chn %d, res %d\n", __func__, channel->idx, res);
Dean Anderson14d96262008-08-25 13:58:55 -03002481 return res;
Dean Anderson38f993a2008-06-26 23:15:51 -03002482}
2483
2484static void s2255_stop_readpipe(struct s2255_dev *dev)
2485{
Dean Andersonab85c6a2010-04-08 23:39:12 -03002486 struct s2255_pipeinfo *pipe = &dev->pipe;
Dan Carpenter8b661b52010-05-05 03:00:47 -03002487
Dean Andersonab85c6a2010-04-08 23:39:12 -03002488 pipe->state = 0;
2489 if (pipe->stream_urb) {
2490 /* cancel urb */
2491 usb_kill_urb(pipe->stream_urb);
2492 usb_free_urb(pipe->stream_urb);
2493 pipe->stream_urb = NULL;
Dean Anderson38f993a2008-06-26 23:15:51 -03002494 }
Dean Andersonab85c6a2010-04-08 23:39:12 -03002495 dprintk(4, "%s", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03002496 return;
2497}
2498
Dean Anderson14d96262008-08-25 13:58:55 -03002499static void s2255_fwload_start(struct s2255_dev *dev, int reset)
Dean Anderson38f993a2008-06-26 23:15:51 -03002500{
Dean Anderson14d96262008-08-25 13:58:55 -03002501 if (reset)
2502 s2255_reset_dsppower(dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03002503 dev->fw_data->fw_size = dev->fw_data->fw->size;
2504 atomic_set(&dev->fw_data->fw_state, S2255_FW_NOTLOADED);
2505 memcpy(dev->fw_data->pfw_data,
2506 dev->fw_data->fw->data, CHUNK_SIZE);
2507 dev->fw_data->fw_loaded = CHUNK_SIZE;
2508 usb_fill_bulk_urb(dev->fw_data->fw_urb, dev->udev,
2509 usb_sndbulkpipe(dev->udev, 2),
2510 dev->fw_data->pfw_data,
2511 CHUNK_SIZE, s2255_fwchunk_complete,
2512 dev->fw_data);
2513 mod_timer(&dev->timer, jiffies + HZ);
2514}
2515
2516/* standard usb probe function */
2517static int s2255_probe(struct usb_interface *interface,
2518 const struct usb_device_id *id)
2519{
2520 struct s2255_dev *dev = NULL;
2521 struct usb_host_interface *iface_desc;
2522 struct usb_endpoint_descriptor *endpoint;
2523 int i;
2524 int retval = -ENOMEM;
Dean Anderson14d96262008-08-25 13:58:55 -03002525 __le32 *pdata;
2526 int fw_size;
Dean Anderson85b85482010-04-08 23:51:17 -03002527 dprintk(2, "%s\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03002528 /* allocate memory for our device state and initialize it to zero */
2529 dev = kzalloc(sizeof(struct s2255_dev), GFP_KERNEL);
2530 if (dev == NULL) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002531 s2255_dev_err(&interface->dev, "out of memory\n");
Dean Andersonff7e22d2010-04-08 23:38:07 -03002532 return -ENOMEM;
Dean Anderson38f993a2008-06-26 23:15:51 -03002533 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03002534 atomic_set(&dev->num_channels, 0);
Dean Anderson5a34d9d2010-03-05 19:59:48 -03002535 dev->pid = id->idProduct;
Dean Anderson38f993a2008-06-26 23:15:51 -03002536 dev->fw_data = kzalloc(sizeof(struct s2255_fw), GFP_KERNEL);
2537 if (!dev->fw_data)
Dean Andersonff7e22d2010-04-08 23:38:07 -03002538 goto errorFWDATA1;
Dean Anderson38f993a2008-06-26 23:15:51 -03002539 mutex_init(&dev->lock);
2540 mutex_init(&dev->open_lock);
Dean Anderson38f993a2008-06-26 23:15:51 -03002541 /* grab usb_device and save it */
2542 dev->udev = usb_get_dev(interface_to_usbdev(interface));
2543 if (dev->udev == NULL) {
2544 dev_err(&interface->dev, "null usb device\n");
2545 retval = -ENODEV;
Dean Andersonff7e22d2010-04-08 23:38:07 -03002546 goto errorUDEV;
Dean Anderson38f993a2008-06-26 23:15:51 -03002547 }
Dean Andersond62e85a2010-04-09 19:54:26 -03002548 dprintk(1, "dev: %p, udev %p interface %p\n", dev,
Dean Anderson38f993a2008-06-26 23:15:51 -03002549 dev->udev, interface);
2550 dev->interface = interface;
2551 /* set up the endpoint information */
2552 iface_desc = interface->cur_altsetting;
2553 dprintk(1, "num endpoints %d\n", iface_desc->desc.bNumEndpoints);
2554 for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
2555 endpoint = &iface_desc->endpoint[i].desc;
2556 if (!dev->read_endpoint && usb_endpoint_is_bulk_in(endpoint)) {
2557 /* we found the bulk in endpoint */
2558 dev->read_endpoint = endpoint->bEndpointAddress;
2559 }
2560 }
2561
2562 if (!dev->read_endpoint) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002563 dev_err(&interface->dev, "Could not find bulk-in endpoint\n");
Dean Andersonff7e22d2010-04-08 23:38:07 -03002564 goto errorEP;
Dean Anderson38f993a2008-06-26 23:15:51 -03002565 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002566 init_timer(&dev->timer);
2567 dev->timer.function = s2255_timer;
2568 dev->timer.data = (unsigned long)dev->fw_data;
Dean Anderson38f993a2008-06-26 23:15:51 -03002569 init_waitqueue_head(&dev->fw_data->wait_fw);
Dean Anderson4de39f52010-03-03 19:39:19 -03002570 for (i = 0; i < MAX_CHANNELS; i++) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03002571 struct s2255_channel *channel = &dev->channel[i];
2572 dev->channel[i].idx = i;
2573 init_waitqueue_head(&channel->wait_setmode);
2574 init_waitqueue_head(&channel->wait_vidstatus);
Dean Anderson4de39f52010-03-03 19:39:19 -03002575 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002576
2577 dev->fw_data->fw_urb = usb_alloc_urb(0, GFP_KERNEL);
Dean Anderson38f993a2008-06-26 23:15:51 -03002578 if (!dev->fw_data->fw_urb) {
2579 dev_err(&interface->dev, "out of memory!\n");
Dean Andersonff7e22d2010-04-08 23:38:07 -03002580 goto errorFWURB;
Dean Anderson38f993a2008-06-26 23:15:51 -03002581 }
Dean Andersonff7e22d2010-04-08 23:38:07 -03002582
Dean Anderson38f993a2008-06-26 23:15:51 -03002583 dev->fw_data->pfw_data = kzalloc(CHUNK_SIZE, GFP_KERNEL);
2584 if (!dev->fw_data->pfw_data) {
2585 dev_err(&interface->dev, "out of memory!\n");
Dean Andersonff7e22d2010-04-08 23:38:07 -03002586 goto errorFWDATA2;
Dean Anderson38f993a2008-06-26 23:15:51 -03002587 }
2588 /* load the first chunk */
2589 if (request_firmware(&dev->fw_data->fw,
2590 FIRMWARE_FILE_NAME, &dev->udev->dev)) {
2591 printk(KERN_ERR "sensoray 2255 failed to get firmware\n");
Dean Andersonff7e22d2010-04-08 23:38:07 -03002592 goto errorREQFW;
Dean Anderson38f993a2008-06-26 23:15:51 -03002593 }
Dean Anderson14d96262008-08-25 13:58:55 -03002594 /* check the firmware is valid */
2595 fw_size = dev->fw_data->fw->size;
2596 pdata = (__le32 *) &dev->fw_data->fw->data[fw_size - 8];
Dean Anderson38f993a2008-06-26 23:15:51 -03002597
Dean Anderson14d96262008-08-25 13:58:55 -03002598 if (*pdata != S2255_FW_MARKER) {
2599 printk(KERN_INFO "Firmware invalid.\n");
2600 retval = -ENODEV;
Dean Andersonff7e22d2010-04-08 23:38:07 -03002601 goto errorFWMARKER;
Dean Anderson14d96262008-08-25 13:58:55 -03002602 } else {
2603 /* make sure firmware is the latest */
2604 __le32 *pRel;
2605 pRel = (__le32 *) &dev->fw_data->fw->data[fw_size - 4];
2606 printk(KERN_INFO "s2255 dsp fw version %x\n", *pRel);
Dean Anderson4de39f52010-03-03 19:39:19 -03002607 dev->dsp_fw_ver = *pRel;
2608 if (*pRel < S2255_CUR_DSP_FWVER)
2609 printk(KERN_INFO "s2255: f2255usb.bin out of date.\n");
Dean Anderson5a34d9d2010-03-05 19:59:48 -03002610 if (dev->pid == 0x2257 && *pRel < S2255_MIN_DSP_COLORFILTER)
Dean Andersonff7e22d2010-04-08 23:38:07 -03002611 printk(KERN_WARNING "s2255: 2257 requires firmware %d"
Dean Andersonfe85ce92010-06-01 19:12:07 -03002612 " or above.\n", S2255_MIN_DSP_COLORFILTER);
Dean Anderson14d96262008-08-25 13:58:55 -03002613 }
Dean Anderson14d96262008-08-25 13:58:55 -03002614 usb_reset_device(dev->udev);
Dean Anderson38f993a2008-06-26 23:15:51 -03002615 /* load 2255 board specific */
Dean Andersonabce21f2009-04-23 16:04:41 -03002616 retval = s2255_board_init(dev);
2617 if (retval)
Dean Andersonff7e22d2010-04-08 23:38:07 -03002618 goto errorBOARDINIT;
Dean Anderson38f993a2008-06-26 23:15:51 -03002619 spin_lock_init(&dev->slock);
Dean Anderson14d96262008-08-25 13:58:55 -03002620 s2255_fwload_start(dev, 0);
Dean Andersonff7e22d2010-04-08 23:38:07 -03002621 /* loads v4l specific */
2622 retval = s2255_probe_v4l(dev);
2623 if (retval)
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03002624 goto errorBOARDINIT;
Dean Anderson38f993a2008-06-26 23:15:51 -03002625 dev_info(&interface->dev, "Sensoray 2255 detected\n");
2626 return 0;
Dean Andersonff7e22d2010-04-08 23:38:07 -03002627errorBOARDINIT:
2628 s2255_board_shutdown(dev);
2629errorFWMARKER:
2630 release_firmware(dev->fw_data->fw);
2631errorREQFW:
2632 kfree(dev->fw_data->pfw_data);
2633errorFWDATA2:
2634 usb_free_urb(dev->fw_data->fw_urb);
2635errorFWURB:
2636 del_timer(&dev->timer);
2637errorEP:
2638 usb_put_dev(dev->udev);
2639errorUDEV:
2640 kfree(dev->fw_data);
2641 mutex_destroy(&dev->open_lock);
2642 mutex_destroy(&dev->lock);
2643errorFWDATA1:
2644 kfree(dev);
2645 printk(KERN_WARNING "Sensoray 2255 driver load failed: 0x%x\n", retval);
Dean Anderson38f993a2008-06-26 23:15:51 -03002646 return retval;
2647}
2648
2649/* disconnect routine. when board is removed physically or with rmmod */
2650static void s2255_disconnect(struct usb_interface *interface)
2651{
Dean Anderson65c6edb2010-04-20 17:21:32 -03002652 struct s2255_dev *dev = to_s2255_dev(usb_get_intfdata(interface));
Dean Anderson14d96262008-08-25 13:58:55 -03002653 int i;
Dean Andersonfe85ce92010-06-01 19:12:07 -03002654 int channels = atomic_read(&dev->num_channels);
Pete Eberleina19a5cd2010-12-20 19:18:59 -03002655 mutex_lock(&dev->lock);
Dean Andersonfe85ce92010-06-01 19:12:07 -03002656 v4l2_device_disconnect(&dev->v4l2_dev);
Pete Eberleina19a5cd2010-12-20 19:18:59 -03002657 mutex_unlock(&dev->lock);
Dean Andersond62e85a2010-04-09 19:54:26 -03002658 /*see comments in the uvc_driver.c usb disconnect function */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002659 atomic_inc(&dev->num_channels);
Dean Andersonff7e22d2010-04-08 23:38:07 -03002660 /* unregister each video device. */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002661 for (i = 0; i < channels; i++)
2662 video_unregister_device(&dev->channel[i].vdev);
Dean Andersonff7e22d2010-04-08 23:38:07 -03002663 /* wake up any of our timers */
Dean Anderson14d96262008-08-25 13:58:55 -03002664 atomic_set(&dev->fw_data->fw_state, S2255_FW_DISCONNECTING);
2665 wake_up(&dev->fw_data->wait_fw);
2666 for (i = 0; i < MAX_CHANNELS; i++) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03002667 dev->channel[i].setmode_ready = 1;
2668 wake_up(&dev->channel[i].wait_setmode);
2669 dev->channel[i].vidstatus_ready = 1;
2670 wake_up(&dev->channel[i].wait_vidstatus);
Dean Anderson14d96262008-08-25 13:58:55 -03002671 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03002672 if (atomic_dec_and_test(&dev->num_channels))
Dean Andersond62e85a2010-04-09 19:54:26 -03002673 s2255_destroy(dev);
Dean Andersonff7e22d2010-04-08 23:38:07 -03002674 dev_info(&interface->dev, "%s\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03002675}
2676
2677static struct usb_driver s2255_driver = {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002678 .name = S2255_DRIVER_NAME,
Dean Anderson38f993a2008-06-26 23:15:51 -03002679 .probe = s2255_probe,
2680 .disconnect = s2255_disconnect,
2681 .id_table = s2255_table,
2682};
2683
2684static int __init usb_s2255_init(void)
2685{
2686 int result;
Dean Anderson38f993a2008-06-26 23:15:51 -03002687 /* register this driver with the USB subsystem */
2688 result = usb_register(&s2255_driver);
Dean Anderson38f993a2008-06-26 23:15:51 -03002689 if (result)
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002690 pr_err(KBUILD_MODNAME
Dean Andersonff7e22d2010-04-08 23:38:07 -03002691 ": usb_register failed. Error number %d\n", result);
2692 dprintk(2, "%s\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03002693 return result;
2694}
2695
2696static void __exit usb_s2255_exit(void)
2697{
2698 usb_deregister(&s2255_driver);
2699}
2700
2701module_init(usb_s2255_init);
2702module_exit(usb_s2255_exit);
2703
2704MODULE_DESCRIPTION("Sensoray 2255 Video for Linux driver");
2705MODULE_AUTHOR("Dean Anderson (Sensoray Company Inc.)");
2706MODULE_LICENSE("GPL");