blob: f5a46c45871713df2eab2c0f43bccff5717fc05d [file] [log] [blame]
Dean Anderson38f993a2008-06-26 23:15:51 -03001/*
2 * s2255drv.c - a driver for the Sensoray 2255 USB video capture device
3 *
Dean Anderson4de39f52010-03-03 19:39:19 -03004 * Copyright (C) 2007-2010 by Sensoray Company Inc.
Dean Anderson38f993a2008-06-26 23:15:51 -03005 * Dean Anderson
6 *
7 * Some video buffer code based on vivi driver:
8 *
9 * Sensoray 2255 device supports 4 simultaneous channels.
10 * The channels are not "crossbar" inputs, they are physically
11 * attached to separate video decoders.
12 *
13 * Because of USB2.0 bandwidth limitations. There is only a
14 * certain amount of data which may be transferred at one time.
15 *
16 * Example maximum bandwidth utilization:
17 *
18 * -full size, color mode YUYV or YUV422P: 2 channels at once
19 *
20 * -full or half size Grey scale: all 4 channels at once
21 *
22 * -half size, color mode YUYV or YUV422P: all 4 channels at once
23 *
24 * -full size, color mode YUYV or YUV422P 1/2 frame rate: all 4 channels
25 * at once.
26 * (TODO: Incorporate videodev2 frame rate(FR) enumeration,
27 * which is currently experimental.)
28 *
29 * This program is free software; you can redistribute it and/or modify
30 * it under the terms of the GNU General Public License as published by
31 * the Free Software Foundation; either version 2 of the License, or
32 * (at your option) any later version.
33 *
34 * This program is distributed in the hope that it will be useful,
35 * but WITHOUT ANY WARRANTY; without even the implied warranty of
36 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
37 * GNU General Public License for more details.
38 *
39 * You should have received a copy of the GNU General Public License
40 * along with this program; if not, write to the Free Software
41 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
42 */
43
44#include <linux/module.h>
45#include <linux/firmware.h>
46#include <linux/kernel.h>
47#include <linux/mutex.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090048#include <linux/slab.h>
Dean Anderson38f993a2008-06-26 23:15:51 -030049#include <linux/videodev2.h>
50#include <linux/version.h>
Hans Verkuilfeb75f02008-07-27 06:30:21 -030051#include <linux/mm.h>
Alexey Dobriyan405f5572009-07-11 22:08:37 +040052#include <linux/smp_lock.h>
Dean Anderson38f993a2008-06-26 23:15:51 -030053#include <media/videobuf-vmalloc.h>
54#include <media/v4l2-common.h>
Dean Anderson3a67b5cc2010-04-08 23:52:20 -030055#include <media/v4l2-device.h>
Hans Verkuil35ea11f2008-07-20 08:12:02 -030056#include <media/v4l2-ioctl.h>
Dean Anderson38f993a2008-06-26 23:15:51 -030057#include <linux/vmalloc.h>
58#include <linux/usb.h>
59
Dean Anderson85b85482010-04-08 23:51:17 -030060#define S2255_MAJOR_VERSION 1
Dean Andersoneb78dee2010-04-12 15:05:37 -030061#define S2255_MINOR_VERSION 20
Dean Anderson85b85482010-04-08 23:51:17 -030062#define S2255_RELEASE 0
63#define S2255_VERSION KERNEL_VERSION(S2255_MAJOR_VERSION, \
64 S2255_MINOR_VERSION, \
65 S2255_RELEASE)
Dean Anderson38f993a2008-06-26 23:15:51 -030066#define FIRMWARE_FILE_NAME "f2255usb.bin"
67
Dean Anderson22b88d42008-08-29 15:33:19 -030068/* default JPEG quality */
69#define S2255_DEF_JPEG_QUAL 50
Dean Anderson38f993a2008-06-26 23:15:51 -030070/* vendor request in */
71#define S2255_VR_IN 0
72/* vendor request out */
73#define S2255_VR_OUT 1
74/* firmware query */
75#define S2255_VR_FW 0x30
76/* USB endpoint number for configuring the device */
77#define S2255_CONFIG_EP 2
78/* maximum time for DSP to start responding after last FW word loaded(ms) */
Dean Anderson14d96262008-08-25 13:58:55 -030079#define S2255_DSP_BOOTTIME 800
Dean Anderson38f993a2008-06-26 23:15:51 -030080/* maximum time to wait for firmware to load (ms) */
Dean Anderson3f8d6f72008-06-30 21:28:34 -030081#define S2255_LOAD_TIMEOUT (5000 + S2255_DSP_BOOTTIME)
Dean Anderson38f993a2008-06-26 23:15:51 -030082#define S2255_DEF_BUFS 16
Dean Anderson14d96262008-08-25 13:58:55 -030083#define S2255_SETMODE_TIMEOUT 500
Dean Anderson4de39f52010-03-03 19:39:19 -030084#define S2255_VIDSTATUS_TIMEOUT 350
Dean Anderson3fa00602010-03-04 20:47:33 -030085#define S2255_MARKER_FRAME cpu_to_le32(0x2255DA4AL)
86#define S2255_MARKER_RESPONSE cpu_to_le32(0x2255ACACL)
87#define S2255_RESPONSE_SETMODE cpu_to_le32(0x01)
88#define S2255_RESPONSE_FW cpu_to_le32(0x10)
89#define S2255_RESPONSE_STATUS cpu_to_le32(0x20)
Dean Anderson14d96262008-08-25 13:58:55 -030090#define S2255_USB_XFER_SIZE (16 * 1024)
Dean Anderson38f993a2008-06-26 23:15:51 -030091#define MAX_CHANNELS 4
Dean Anderson38f993a2008-06-26 23:15:51 -030092#define SYS_FRAMES 4
93/* maximum size is PAL full size plus room for the marker header(s) */
Dean Anderson14d96262008-08-25 13:58:55 -030094#define SYS_FRAMES_MAXSIZE (720*288*2*2 + 4096)
95#define DEF_USB_BLOCK S2255_USB_XFER_SIZE
Dean Anderson38f993a2008-06-26 23:15:51 -030096#define LINE_SZ_4CIFS_NTSC 640
97#define LINE_SZ_2CIFS_NTSC 640
98#define LINE_SZ_1CIFS_NTSC 320
99#define LINE_SZ_4CIFS_PAL 704
100#define LINE_SZ_2CIFS_PAL 704
101#define LINE_SZ_1CIFS_PAL 352
102#define NUM_LINES_4CIFS_NTSC 240
103#define NUM_LINES_2CIFS_NTSC 240
104#define NUM_LINES_1CIFS_NTSC 240
105#define NUM_LINES_4CIFS_PAL 288
106#define NUM_LINES_2CIFS_PAL 288
107#define NUM_LINES_1CIFS_PAL 288
108#define LINE_SZ_DEF 640
109#define NUM_LINES_DEF 240
110
111
112/* predefined settings */
113#define FORMAT_NTSC 1
114#define FORMAT_PAL 2
115
116#define SCALE_4CIFS 1 /* 640x480(NTSC) or 704x576(PAL) */
117#define SCALE_2CIFS 2 /* 640x240(NTSC) or 704x288(PAL) */
118#define SCALE_1CIFS 3 /* 320x240(NTSC) or 352x288(PAL) */
Dean Anderson7d853532009-05-15 14:32:04 -0300119/* SCALE_4CIFSI is the 2 fields interpolated into one */
120#define SCALE_4CIFSI 4 /* 640x480(NTSC) or 704x576(PAL) high quality */
Dean Anderson38f993a2008-06-26 23:15:51 -0300121
122#define COLOR_YUVPL 1 /* YUV planar */
123#define COLOR_YUVPK 2 /* YUV packed */
124#define COLOR_Y8 4 /* monochrome */
Dean Anderson14d96262008-08-25 13:58:55 -0300125#define COLOR_JPG 5 /* JPEG */
Dean Anderson38f993a2008-06-26 23:15:51 -0300126
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300127#define MASK_COLOR 0x000000ff
128#define MASK_JPG_QUALITY 0x0000ff00
129#define MASK_INPUT_TYPE 0x000f0000
Dean Anderson38f993a2008-06-26 23:15:51 -0300130/* frame decimation. Not implemented by V4L yet(experimental in V4L) */
131#define FDEC_1 1 /* capture every frame. default */
132#define FDEC_2 2 /* capture every 2nd frame */
133#define FDEC_3 3 /* capture every 3rd frame */
134#define FDEC_5 5 /* capture every 5th frame */
135
136/*-------------------------------------------------------
137 * Default mode parameters.
138 *-------------------------------------------------------*/
139#define DEF_SCALE SCALE_4CIFS
140#define DEF_COLOR COLOR_YUVPL
141#define DEF_FDEC FDEC_1
142#define DEF_BRIGHT 0
143#define DEF_CONTRAST 0x5c
144#define DEF_SATURATION 0x80
145#define DEF_HUE 0
146
147/* usb config commands */
Dean Anderson3fa00602010-03-04 20:47:33 -0300148#define IN_DATA_TOKEN cpu_to_le32(0x2255c0de)
149#define CMD_2255 cpu_to_le32(0xc2255000)
150#define CMD_SET_MODE cpu_to_le32((CMD_2255 | 0x10))
151#define CMD_START cpu_to_le32((CMD_2255 | 0x20))
152#define CMD_STOP cpu_to_le32((CMD_2255 | 0x30))
153#define CMD_STATUS cpu_to_le32((CMD_2255 | 0x40))
Dean Anderson38f993a2008-06-26 23:15:51 -0300154
155struct s2255_mode {
156 u32 format; /* input video format (NTSC, PAL) */
157 u32 scale; /* output video scale */
158 u32 color; /* output video color format */
159 u32 fdec; /* frame decimation */
160 u32 bright; /* brightness */
161 u32 contrast; /* contrast */
162 u32 saturation; /* saturation */
163 u32 hue; /* hue (NTSC only)*/
164 u32 single; /* capture 1 frame at a time (!=0), continuously (==0)*/
165 u32 usb_block; /* block size. should be 4096 of DEF_USB_BLOCK */
166 u32 restart; /* if DSP requires restart */
167};
168
Dean Anderson14d96262008-08-25 13:58:55 -0300169
170#define S2255_READ_IDLE 0
171#define S2255_READ_FRAME 1
172
Dean Anderson38f993a2008-06-26 23:15:51 -0300173/* frame structure */
Dean Anderson38f993a2008-06-26 23:15:51 -0300174struct s2255_framei {
175 unsigned long size;
Dean Anderson14d96262008-08-25 13:58:55 -0300176 unsigned long ulState; /* ulState:S2255_READ_IDLE, S2255_READ_FRAME*/
Dean Anderson38f993a2008-06-26 23:15:51 -0300177 void *lpvbits; /* image data */
178 unsigned long cur_size; /* current data copied to it */
179};
180
181/* image buffer structure */
182struct s2255_bufferi {
183 unsigned long dwFrames; /* number of frames in buffer */
184 struct s2255_framei frame[SYS_FRAMES]; /* array of FRAME structures */
185};
186
187#define DEF_MODEI_NTSC_CONT {FORMAT_NTSC, DEF_SCALE, DEF_COLOR, \
188 DEF_FDEC, DEF_BRIGHT, DEF_CONTRAST, DEF_SATURATION, \
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300189 DEF_HUE, 0, DEF_USB_BLOCK, 0}
Dean Anderson38f993a2008-06-26 23:15:51 -0300190
191struct s2255_dmaqueue {
192 struct list_head active;
Dean Anderson38f993a2008-06-26 23:15:51 -0300193 struct s2255_dev *dev;
Dean Anderson38f993a2008-06-26 23:15:51 -0300194};
195
196/* for firmware loading, fw_state */
197#define S2255_FW_NOTLOADED 0
198#define S2255_FW_LOADED_DSPWAIT 1
199#define S2255_FW_SUCCESS 2
200#define S2255_FW_FAILED 3
Dean Andersonf78d92c2008-07-22 14:43:27 -0300201#define S2255_FW_DISCONNECTING 4
Harvey Harrisondeaf53e2008-11-15 01:10:14 -0300202#define S2255_FW_MARKER cpu_to_le32(0x22552f2f)
Dean Anderson14d96262008-08-25 13:58:55 -0300203/* 2255 read states */
204#define S2255_READ_IDLE 0
205#define S2255_READ_FRAME 1
Dean Anderson38f993a2008-06-26 23:15:51 -0300206struct s2255_fw {
207 int fw_loaded;
208 int fw_size;
209 struct urb *fw_urb;
210 atomic_t fw_state;
211 void *pfw_data;
212 wait_queue_head_t wait_fw;
Dean Anderson38f993a2008-06-26 23:15:51 -0300213 const struct firmware *fw;
214};
215
216struct s2255_pipeinfo {
217 u32 max_transfer_size;
218 u32 cur_transfer_size;
219 u8 *transfer_buffer;
Dean Anderson38f993a2008-06-26 23:15:51 -0300220 u32 state;
Dean Anderson38f993a2008-06-26 23:15:51 -0300221 void *stream_urb;
222 void *dev; /* back pointer to s2255_dev struct*/
223 u32 err_count;
Dean Anderson38f993a2008-06-26 23:15:51 -0300224 u32 idx;
Dean Anderson38f993a2008-06-26 23:15:51 -0300225};
226
227struct s2255_fmt; /*forward declaration */
Dean Andersonfe85ce92010-06-01 19:12:07 -0300228struct s2255_dev;
229
230struct s2255_channel {
231 struct video_device vdev;
232 int resources;
233 struct s2255_dmaqueue vidq;
234 struct s2255_bufferi buffer;
235 struct s2255_mode mode;
236 /* jpeg compression */
237 struct v4l2_jpegcompression jc;
238 /* capture parameters (for high quality mode full size) */
239 struct v4l2_captureparm cap_parm;
240 int cur_frame;
241 int last_frame;
242
243 int b_acquire;
244 /* allocated image size */
245 unsigned long req_image_size;
246 /* received packet size */
247 unsigned long pkt_size;
248 int bad_payload;
249 unsigned long frame_count;
250 /* if JPEG image */
251 int jpg_size;
252 /* if channel configured to default state */
253 int configured;
254 wait_queue_head_t wait_setmode;
255 int setmode_ready;
256 /* video status items */
257 int vidstatus;
258 wait_queue_head_t wait_vidstatus;
259 int vidstatus_ready;
260 unsigned int width;
261 unsigned int height;
262 const struct s2255_fmt *fmt;
263 int idx; /* channel number on device, 0-3 */
264};
265
Dean Anderson38f993a2008-06-26 23:15:51 -0300266
267struct s2255_dev {
Dean Andersonfe85ce92010-06-01 19:12:07 -0300268 struct s2255_channel channel[MAX_CHANNELS];
Dean Anderson65c6edb2010-04-20 17:21:32 -0300269 struct v4l2_device v4l2_dev;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300270 atomic_t num_channels;
Dean Anderson38f993a2008-06-26 23:15:51 -0300271 int frames;
Dean Anderson38f993a2008-06-26 23:15:51 -0300272 struct mutex lock;
273 struct mutex open_lock;
Dean Anderson38f993a2008-06-26 23:15:51 -0300274 struct usb_device *udev;
275 struct usb_interface *interface;
276 u8 read_endpoint;
Dean Anderson38f993a2008-06-26 23:15:51 -0300277 struct timer_list timer;
278 struct s2255_fw *fw_data;
Dean Andersonab85c6a2010-04-08 23:39:12 -0300279 struct s2255_pipeinfo pipe;
Dean Anderson38f993a2008-06-26 23:15:51 -0300280 u32 cc; /* current channel */
Dean Anderson38f993a2008-06-26 23:15:51 -0300281 int frame_ready;
Dean Anderson14d96262008-08-25 13:58:55 -0300282 int chn_ready;
Dean Anderson38f993a2008-06-26 23:15:51 -0300283 spinlock_t slock;
Dean Anderson4de39f52010-03-03 19:39:19 -0300284 /* dsp firmware version (f2255usb.bin) */
285 int dsp_fw_ver;
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300286 u16 pid; /* product id */
Dean Anderson38f993a2008-06-26 23:15:51 -0300287};
Dean Anderson65c6edb2010-04-20 17:21:32 -0300288
Dean Anderson65c6edb2010-04-20 17:21:32 -0300289static inline struct s2255_dev *to_s2255_dev(struct v4l2_device *v4l2_dev)
290{
291 return container_of(v4l2_dev, struct s2255_dev, v4l2_dev);
292}
Dean Anderson38f993a2008-06-26 23:15:51 -0300293
294struct s2255_fmt {
295 char *name;
296 u32 fourcc;
297 int depth;
298};
299
300/* buffer for one video frame */
301struct s2255_buffer {
302 /* common v4l buffer stuff -- must be first */
303 struct videobuf_buffer vb;
304 const struct s2255_fmt *fmt;
305};
306
307struct s2255_fh {
308 struct s2255_dev *dev;
Dean Anderson38f993a2008-06-26 23:15:51 -0300309 struct videobuf_queue vb_vidq;
310 enum v4l2_buf_type type;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300311 struct s2255_channel *channel;
312 int resources;
Dean Anderson38f993a2008-06-26 23:15:51 -0300313};
314
Dean Andersonabce21f2009-04-23 16:04:41 -0300315/* current cypress EEPROM firmware version */
316#define S2255_CUR_USB_FWVER ((3 << 8) | 6)
Dean Anderson4de39f52010-03-03 19:39:19 -0300317/* current DSP FW version */
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300318#define S2255_CUR_DSP_FWVER 8
Dean Anderson4de39f52010-03-03 19:39:19 -0300319/* Need DSP version 5+ for video status feature */
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300320#define S2255_MIN_DSP_STATUS 5
321#define S2255_MIN_DSP_COLORFILTER 8
Dean Anderson38f993a2008-06-26 23:15:51 -0300322#define S2255_NORMS (V4L2_STD_PAL | V4L2_STD_NTSC)
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300323
324/* private V4L2 controls */
325
326/*
327 * The following chart displays how COLORFILTER should be set
328 * =========================================================
329 * = fourcc = COLORFILTER =
330 * = ===============================
331 * = = 0 = 1 =
332 * =========================================================
333 * = V4L2_PIX_FMT_GREY(Y8) = monochrome from = monochrome=
334 * = = s-video or = composite =
335 * = = B/W camera = input =
336 * =========================================================
337 * = other = color, svideo = color, =
338 * = = = composite =
339 * =========================================================
340 *
341 * Notes:
342 * channels 0-3 on 2255 are composite
343 * channels 0-1 on 2257 are composite, 2-3 are s-video
344 * If COLORFILTER is 0 with a composite color camera connected,
345 * the output will appear monochrome but hatching
346 * will occur.
347 * COLORFILTER is different from "color killer" and "color effects"
348 * for reasons above.
349 */
350#define S2255_V4L2_YC_ON 1
351#define S2255_V4L2_YC_OFF 0
352#define V4L2_CID_PRIVATE_COLORFILTER (V4L2_CID_PRIVATE_BASE + 0)
353
Dean Anderson38f993a2008-06-26 23:15:51 -0300354/* frame prefix size (sent once every frame) */
355#define PREFIX_SIZE 512
356
357/* Channels on box are in reverse order */
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300358static unsigned long G_chnmap[MAX_CHANNELS] = {3, 2, 1, 0};
Dean Anderson38f993a2008-06-26 23:15:51 -0300359
Dean Anderson38f993a2008-06-26 23:15:51 -0300360static int debug;
361static int *s2255_debug = &debug;
362
363static int s2255_start_readpipe(struct s2255_dev *dev);
364static void s2255_stop_readpipe(struct s2255_dev *dev);
Dean Andersonfe85ce92010-06-01 19:12:07 -0300365static int s2255_start_acquire(struct s2255_channel *channel);
366static int s2255_stop_acquire(struct s2255_channel *channel);
367static void s2255_fillbuff(struct s2255_channel *chn, struct s2255_buffer *buf,
368 int jpgsize);
369static int s2255_set_mode(struct s2255_channel *chan, struct s2255_mode *mode);
Dean Anderson38f993a2008-06-26 23:15:51 -0300370static int s2255_board_shutdown(struct s2255_dev *dev);
Dean Anderson14d96262008-08-25 13:58:55 -0300371static void s2255_fwload_start(struct s2255_dev *dev, int reset);
Dean Andersond62e85a2010-04-09 19:54:26 -0300372static void s2255_destroy(struct s2255_dev *dev);
Dean Anderson14d96262008-08-25 13:58:55 -0300373static long s2255_vendor_req(struct s2255_dev *dev, unsigned char req,
374 u16 index, u16 value, void *buf,
375 s32 buf_len, int bOut);
Dean Anderson38f993a2008-06-26 23:15:51 -0300376
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -0300377/* dev_err macro with driver name */
378#define S2255_DRIVER_NAME "s2255"
379#define s2255_dev_err(dev, fmt, arg...) \
380 dev_err(dev, S2255_DRIVER_NAME " - " fmt, ##arg)
381
Dean Anderson38f993a2008-06-26 23:15:51 -0300382#define dprintk(level, fmt, arg...) \
383 do { \
384 if (*s2255_debug >= (level)) { \
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -0300385 printk(KERN_DEBUG S2255_DRIVER_NAME \
386 ": " fmt, ##arg); \
Dean Anderson38f993a2008-06-26 23:15:51 -0300387 } \
388 } while (0)
389
Dean Anderson38f993a2008-06-26 23:15:51 -0300390static struct usb_driver s2255_driver;
391
Dean Anderson38f993a2008-06-26 23:15:51 -0300392/* Declare static vars that will be used as parameters */
393static unsigned int vid_limit = 16; /* Video memory limit, in Mb */
394
395/* start video number */
396static int video_nr = -1; /* /dev/videoN, -1 for autodetect */
397
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300398module_param(debug, int, 0644);
Dean Anderson38f993a2008-06-26 23:15:51 -0300399MODULE_PARM_DESC(debug, "Debug level(0-100) default 0");
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300400module_param(vid_limit, int, 0644);
Dean Anderson38f993a2008-06-26 23:15:51 -0300401MODULE_PARM_DESC(vid_limit, "video memory limit(Mb)");
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300402module_param(video_nr, int, 0644);
Dean Anderson38f993a2008-06-26 23:15:51 -0300403MODULE_PARM_DESC(video_nr, "start video minor(-1 default autodetect)");
404
405/* USB device table */
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300406#define USB_SENSORAY_VID 0x1943
Dean Anderson38f993a2008-06-26 23:15:51 -0300407static struct usb_device_id s2255_table[] = {
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300408 {USB_DEVICE(USB_SENSORAY_VID, 0x2255)},
409 {USB_DEVICE(USB_SENSORAY_VID, 0x2257)}, /*same family as 2255*/
Dean Anderson38f993a2008-06-26 23:15:51 -0300410 { } /* Terminating entry */
411};
412MODULE_DEVICE_TABLE(usb, s2255_table);
413
Dean Anderson38f993a2008-06-26 23:15:51 -0300414#define BUFFER_TIMEOUT msecs_to_jiffies(400)
415
Dean Anderson38f993a2008-06-26 23:15:51 -0300416/* image formats. */
417static const struct s2255_fmt formats[] = {
418 {
419 .name = "4:2:2, planar, YUV422P",
420 .fourcc = V4L2_PIX_FMT_YUV422P,
421 .depth = 16
422
423 }, {
424 .name = "4:2:2, packed, YUYV",
425 .fourcc = V4L2_PIX_FMT_YUYV,
426 .depth = 16
427
428 }, {
429 .name = "4:2:2, packed, UYVY",
430 .fourcc = V4L2_PIX_FMT_UYVY,
431 .depth = 16
432 }, {
Dean Anderson14d96262008-08-25 13:58:55 -0300433 .name = "JPG",
434 .fourcc = V4L2_PIX_FMT_JPEG,
435 .depth = 24
436 }, {
Dean Anderson38f993a2008-06-26 23:15:51 -0300437 .name = "8bpp GREY",
438 .fourcc = V4L2_PIX_FMT_GREY,
439 .depth = 8
440 }
441};
442
443static int norm_maxw(struct video_device *vdev)
444{
445 return (vdev->current_norm & V4L2_STD_NTSC) ?
446 LINE_SZ_4CIFS_NTSC : LINE_SZ_4CIFS_PAL;
447}
448
449static int norm_maxh(struct video_device *vdev)
450{
451 return (vdev->current_norm & V4L2_STD_NTSC) ?
452 (NUM_LINES_1CIFS_NTSC * 2) : (NUM_LINES_1CIFS_PAL * 2);
453}
454
455static int norm_minw(struct video_device *vdev)
456{
457 return (vdev->current_norm & V4L2_STD_NTSC) ?
458 LINE_SZ_1CIFS_NTSC : LINE_SZ_1CIFS_PAL;
459}
460
461static int norm_minh(struct video_device *vdev)
462{
463 return (vdev->current_norm & V4L2_STD_NTSC) ?
464 (NUM_LINES_1CIFS_NTSC) : (NUM_LINES_1CIFS_PAL);
465}
466
467
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300468/*
469 * TODO: fixme: move YUV reordering to hardware
470 * converts 2255 planar format to yuyv or uyvy
471 */
Dean Anderson38f993a2008-06-26 23:15:51 -0300472static void planar422p_to_yuv_packed(const unsigned char *in,
473 unsigned char *out,
474 int width, int height,
475 int fmt)
476{
477 unsigned char *pY;
478 unsigned char *pCb;
479 unsigned char *pCr;
480 unsigned long size = height * width;
481 unsigned int i;
482 pY = (unsigned char *)in;
483 pCr = (unsigned char *)in + height * width;
484 pCb = (unsigned char *)in + height * width + (height * width / 2);
485 for (i = 0; i < size * 2; i += 4) {
486 out[i] = (fmt == V4L2_PIX_FMT_YUYV) ? *pY++ : *pCr++;
487 out[i + 1] = (fmt == V4L2_PIX_FMT_YUYV) ? *pCr++ : *pY++;
488 out[i + 2] = (fmt == V4L2_PIX_FMT_YUYV) ? *pY++ : *pCb++;
489 out[i + 3] = (fmt == V4L2_PIX_FMT_YUYV) ? *pCb++ : *pY++;
490 }
491 return;
492}
493
Hans Verkuild45b9b82008-09-04 03:33:43 -0300494static void s2255_reset_dsppower(struct s2255_dev *dev)
Dean Anderson14d96262008-08-25 13:58:55 -0300495{
496 s2255_vendor_req(dev, 0x40, 0x0b0b, 0x0b0b, NULL, 0, 1);
497 msleep(10);
498 s2255_vendor_req(dev, 0x50, 0x0000, 0x0000, NULL, 0, 1);
499 return;
500}
Dean Anderson38f993a2008-06-26 23:15:51 -0300501
502/* kickstarts the firmware loading. from probe
503 */
504static void s2255_timer(unsigned long user_data)
505{
506 struct s2255_fw *data = (struct s2255_fw *)user_data;
Dean Anderson85b85482010-04-08 23:51:17 -0300507 dprintk(100, "%s\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -0300508 if (usb_submit_urb(data->fw_urb, GFP_ATOMIC) < 0) {
509 printk(KERN_ERR "s2255: can't submit urb\n");
Dean Andersonf78d92c2008-07-22 14:43:27 -0300510 atomic_set(&data->fw_state, S2255_FW_FAILED);
511 /* wake up anything waiting for the firmware */
512 wake_up(&data->wait_fw);
Dean Anderson38f993a2008-06-26 23:15:51 -0300513 return;
514 }
515}
516
Dean Anderson38f993a2008-06-26 23:15:51 -0300517
518/* this loads the firmware asynchronously.
519 Originally this was done synchroously in probe.
520 But it is better to load it asynchronously here than block
521 inside the probe function. Blocking inside probe affects boot time.
522 FW loading is triggered by the timer in the probe function
523*/
524static void s2255_fwchunk_complete(struct urb *urb)
525{
526 struct s2255_fw *data = urb->context;
527 struct usb_device *udev = urb->dev;
528 int len;
Dean Anderson85b85482010-04-08 23:51:17 -0300529 dprintk(100, "%s: udev %p urb %p", __func__, udev, urb);
Dean Anderson38f993a2008-06-26 23:15:51 -0300530 if (urb->status) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -0300531 dev_err(&udev->dev, "URB failed with status %d\n", urb->status);
Dean Andersonf78d92c2008-07-22 14:43:27 -0300532 atomic_set(&data->fw_state, S2255_FW_FAILED);
533 /* wake up anything waiting for the firmware */
534 wake_up(&data->wait_fw);
Dean Anderson38f993a2008-06-26 23:15:51 -0300535 return;
536 }
537 if (data->fw_urb == NULL) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -0300538 s2255_dev_err(&udev->dev, "disconnected\n");
Dean Andersonf78d92c2008-07-22 14:43:27 -0300539 atomic_set(&data->fw_state, S2255_FW_FAILED);
540 /* wake up anything waiting for the firmware */
541 wake_up(&data->wait_fw);
Dean Anderson38f993a2008-06-26 23:15:51 -0300542 return;
543 }
544#define CHUNK_SIZE 512
545 /* all USB transfers must be done with continuous kernel memory.
546 can't allocate more than 128k in current linux kernel, so
547 upload the firmware in chunks
548 */
549 if (data->fw_loaded < data->fw_size) {
550 len = (data->fw_loaded + CHUNK_SIZE) > data->fw_size ?
551 data->fw_size % CHUNK_SIZE : CHUNK_SIZE;
552
553 if (len < CHUNK_SIZE)
554 memset(data->pfw_data, 0, CHUNK_SIZE);
555
556 dprintk(100, "completed len %d, loaded %d \n", len,
557 data->fw_loaded);
558
559 memcpy(data->pfw_data,
560 (char *) data->fw->data + data->fw_loaded, len);
561
562 usb_fill_bulk_urb(data->fw_urb, udev, usb_sndbulkpipe(udev, 2),
563 data->pfw_data, CHUNK_SIZE,
564 s2255_fwchunk_complete, data);
565 if (usb_submit_urb(data->fw_urb, GFP_ATOMIC) < 0) {
566 dev_err(&udev->dev, "failed submit URB\n");
567 atomic_set(&data->fw_state, S2255_FW_FAILED);
568 /* wake up anything waiting for the firmware */
569 wake_up(&data->wait_fw);
570 return;
571 }
572 data->fw_loaded += len;
573 } else {
Dean Anderson38f993a2008-06-26 23:15:51 -0300574 atomic_set(&data->fw_state, S2255_FW_LOADED_DSPWAIT);
Dean Anderson85b85482010-04-08 23:51:17 -0300575 dprintk(100, "%s: firmware upload complete\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -0300576 }
Dean Anderson38f993a2008-06-26 23:15:51 -0300577 return;
578
579}
580
Dean Andersonfe85ce92010-06-01 19:12:07 -0300581static int s2255_got_frame(struct s2255_channel *channel, int jpgsize)
Dean Anderson38f993a2008-06-26 23:15:51 -0300582{
Dean Andersonfe85ce92010-06-01 19:12:07 -0300583 struct s2255_dmaqueue *dma_q = &channel->vidq;
Dean Anderson38f993a2008-06-26 23:15:51 -0300584 struct s2255_buffer *buf;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300585 struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev);
Dean Anderson38f993a2008-06-26 23:15:51 -0300586 unsigned long flags = 0;
587 int rc = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -0300588 spin_lock_irqsave(&dev->slock, flags);
Dean Anderson38f993a2008-06-26 23:15:51 -0300589 if (list_empty(&dma_q->active)) {
590 dprintk(1, "No active queue to serve\n");
591 rc = -1;
592 goto unlock;
593 }
594 buf = list_entry(dma_q->active.next,
595 struct s2255_buffer, vb.queue);
Dean Anderson38f993a2008-06-26 23:15:51 -0300596 list_del(&buf->vb.queue);
597 do_gettimeofday(&buf->vb.ts);
Dean Andersonfe85ce92010-06-01 19:12:07 -0300598 s2255_fillbuff(channel, buf, jpgsize);
Dean Anderson38f993a2008-06-26 23:15:51 -0300599 wake_up(&buf->vb.done);
Dean Anderson85b85482010-04-08 23:51:17 -0300600 dprintk(2, "%s: [buf/i] [%p/%d]\n", __func__, buf, buf->vb.i);
Dean Anderson38f993a2008-06-26 23:15:51 -0300601unlock:
602 spin_unlock_irqrestore(&dev->slock, flags);
Julia Lawallf2770972010-08-16 13:26:13 -0300603 return rc;
Dean Anderson38f993a2008-06-26 23:15:51 -0300604}
605
Dean Anderson38f993a2008-06-26 23:15:51 -0300606static const struct s2255_fmt *format_by_fourcc(int fourcc)
607{
608 unsigned int i;
Dean Anderson38f993a2008-06-26 23:15:51 -0300609 for (i = 0; i < ARRAY_SIZE(formats); i++) {
610 if (-1 == formats[i].fourcc)
611 continue;
612 if (formats[i].fourcc == fourcc)
613 return formats + i;
614 }
615 return NULL;
616}
617
Dean Anderson38f993a2008-06-26 23:15:51 -0300618/* video buffer vmalloc implementation based partly on VIVI driver which is
619 * Copyright (c) 2006 by
620 * Mauro Carvalho Chehab <mchehab--a.t--infradead.org>
621 * Ted Walther <ted--a.t--enumera.com>
622 * John Sokol <sokol--a.t--videotechnology.com>
623 * http://v4l.videotechnology.com/
624 *
625 */
Dean Andersonfe85ce92010-06-01 19:12:07 -0300626static void s2255_fillbuff(struct s2255_channel *channel,
627 struct s2255_buffer *buf, int jpgsize)
Dean Anderson38f993a2008-06-26 23:15:51 -0300628{
629 int pos = 0;
630 struct timeval ts;
631 const char *tmpbuf;
632 char *vbuf = videobuf_to_vmalloc(&buf->vb);
633 unsigned long last_frame;
634 struct s2255_framei *frm;
635
636 if (!vbuf)
637 return;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300638 last_frame = channel->last_frame;
Dean Anderson38f993a2008-06-26 23:15:51 -0300639 if (last_frame != -1) {
Dean Andersonfe85ce92010-06-01 19:12:07 -0300640 frm = &channel->buffer.frame[last_frame];
Dean Anderson38f993a2008-06-26 23:15:51 -0300641 tmpbuf =
Dean Andersonfe85ce92010-06-01 19:12:07 -0300642 (const char *)channel->buffer.frame[last_frame].lpvbits;
Dean Anderson38f993a2008-06-26 23:15:51 -0300643 switch (buf->fmt->fourcc) {
644 case V4L2_PIX_FMT_YUYV:
645 case V4L2_PIX_FMT_UYVY:
646 planar422p_to_yuv_packed((const unsigned char *)tmpbuf,
647 vbuf, buf->vb.width,
648 buf->vb.height,
649 buf->fmt->fourcc);
650 break;
651 case V4L2_PIX_FMT_GREY:
652 memcpy(vbuf, tmpbuf, buf->vb.width * buf->vb.height);
653 break;
Dean Anderson14d96262008-08-25 13:58:55 -0300654 case V4L2_PIX_FMT_JPEG:
655 buf->vb.size = jpgsize;
656 memcpy(vbuf, tmpbuf, buf->vb.size);
657 break;
Dean Anderson38f993a2008-06-26 23:15:51 -0300658 case V4L2_PIX_FMT_YUV422P:
659 memcpy(vbuf, tmpbuf,
660 buf->vb.width * buf->vb.height * 2);
661 break;
662 default:
663 printk(KERN_DEBUG "s2255: unknown format?\n");
664 }
Dean Andersonfe85ce92010-06-01 19:12:07 -0300665 channel->last_frame = -1;
Dean Anderson38f993a2008-06-26 23:15:51 -0300666 } else {
667 printk(KERN_ERR "s2255: =======no frame\n");
668 return;
669
670 }
671 dprintk(2, "s2255fill at : Buffer 0x%08lx size= %d\n",
672 (unsigned long)vbuf, pos);
673 /* tell v4l buffer was filled */
674
Dean Andersonfe85ce92010-06-01 19:12:07 -0300675 buf->vb.field_count = channel->frame_count * 2;
Dean Anderson38f993a2008-06-26 23:15:51 -0300676 do_gettimeofday(&ts);
677 buf->vb.ts = ts;
678 buf->vb.state = VIDEOBUF_DONE;
679}
680
681
682/* ------------------------------------------------------------------
683 Videobuf operations
684 ------------------------------------------------------------------*/
685
686static int buffer_setup(struct videobuf_queue *vq, unsigned int *count,
687 unsigned int *size)
688{
689 struct s2255_fh *fh = vq->priv_data;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300690 struct s2255_channel *channel = fh->channel;
691 *size = channel->width * channel->height * (channel->fmt->depth >> 3);
Dean Anderson38f993a2008-06-26 23:15:51 -0300692
693 if (0 == *count)
694 *count = S2255_DEF_BUFS;
695
Andreas Bombedab7e312010-03-21 16:02:45 -0300696 if (*size * *count > vid_limit * 1024 * 1024)
697 *count = (vid_limit * 1024 * 1024) / *size;
Dean Anderson38f993a2008-06-26 23:15:51 -0300698
699 return 0;
700}
701
702static void free_buffer(struct videobuf_queue *vq, struct s2255_buffer *buf)
703{
704 dprintk(4, "%s\n", __func__);
705
Dean Anderson38f993a2008-06-26 23:15:51 -0300706 videobuf_vmalloc_free(&buf->vb);
707 buf->vb.state = VIDEOBUF_NEEDS_INIT;
708}
709
710static int buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb,
711 enum v4l2_field field)
712{
713 struct s2255_fh *fh = vq->priv_data;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300714 struct s2255_channel *channel = fh->channel;
Dean Anderson38f993a2008-06-26 23:15:51 -0300715 struct s2255_buffer *buf = container_of(vb, struct s2255_buffer, vb);
716 int rc;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300717 int w = channel->width;
718 int h = channel->height;
Dean Anderson38f993a2008-06-26 23:15:51 -0300719 dprintk(4, "%s, field=%d\n", __func__, field);
Dean Andersonfe85ce92010-06-01 19:12:07 -0300720 if (channel->fmt == NULL)
Dean Anderson38f993a2008-06-26 23:15:51 -0300721 return -EINVAL;
722
Dean Andersonfe85ce92010-06-01 19:12:07 -0300723 if ((w < norm_minw(&channel->vdev)) ||
724 (w > norm_maxw(&channel->vdev)) ||
725 (h < norm_minh(&channel->vdev)) ||
726 (h > norm_maxh(&channel->vdev))) {
Dean Anderson38f993a2008-06-26 23:15:51 -0300727 dprintk(4, "invalid buffer prepare\n");
728 return -EINVAL;
729 }
Dean Andersonfe85ce92010-06-01 19:12:07 -0300730 buf->vb.size = w * h * (channel->fmt->depth >> 3);
Dean Anderson38f993a2008-06-26 23:15:51 -0300731 if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size) {
732 dprintk(4, "invalid buffer prepare\n");
733 return -EINVAL;
734 }
735
Dean Andersonfe85ce92010-06-01 19:12:07 -0300736 buf->fmt = channel->fmt;
737 buf->vb.width = w;
738 buf->vb.height = h;
Dean Anderson38f993a2008-06-26 23:15:51 -0300739 buf->vb.field = field;
740
Dean Anderson38f993a2008-06-26 23:15:51 -0300741 if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
742 rc = videobuf_iolock(vq, &buf->vb, NULL);
743 if (rc < 0)
744 goto fail;
745 }
746
747 buf->vb.state = VIDEOBUF_PREPARED;
748 return 0;
749fail:
750 free_buffer(vq, buf);
751 return rc;
752}
753
754static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
755{
756 struct s2255_buffer *buf = container_of(vb, struct s2255_buffer, vb);
757 struct s2255_fh *fh = vq->priv_data;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300758 struct s2255_channel *channel = fh->channel;
759 struct s2255_dmaqueue *vidq = &channel->vidq;
Dean Anderson38f993a2008-06-26 23:15:51 -0300760 dprintk(1, "%s\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -0300761 buf->vb.state = VIDEOBUF_QUEUED;
762 list_add_tail(&buf->vb.queue, &vidq->active);
763}
764
765static void buffer_release(struct videobuf_queue *vq,
766 struct videobuf_buffer *vb)
767{
768 struct s2255_buffer *buf = container_of(vb, struct s2255_buffer, vb);
769 struct s2255_fh *fh = vq->priv_data;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300770 dprintk(4, "%s %d\n", __func__, fh->channel->idx);
Dean Anderson38f993a2008-06-26 23:15:51 -0300771 free_buffer(vq, buf);
772}
773
774static struct videobuf_queue_ops s2255_video_qops = {
775 .buf_setup = buffer_setup,
776 .buf_prepare = buffer_prepare,
777 .buf_queue = buffer_queue,
778 .buf_release = buffer_release,
779};
780
781
Dean Andersonfe85ce92010-06-01 19:12:07 -0300782static int res_get(struct s2255_fh *fh)
Dean Anderson38f993a2008-06-26 23:15:51 -0300783{
Dean Andersonfe85ce92010-06-01 19:12:07 -0300784 struct s2255_dev *dev = fh->dev;
Dean Anderson38f993a2008-06-26 23:15:51 -0300785 /* is it free? */
Dean Andersonfe85ce92010-06-01 19:12:07 -0300786 struct s2255_channel *channel = fh->channel;
Dean Anderson38f993a2008-06-26 23:15:51 -0300787 mutex_lock(&dev->lock);
Dean Andersonfe85ce92010-06-01 19:12:07 -0300788 if (channel->resources) {
Dean Anderson38f993a2008-06-26 23:15:51 -0300789 /* no, someone else uses it */
790 mutex_unlock(&dev->lock);
791 return 0;
792 }
793 /* it's free, grab it */
Dean Andersonfe85ce92010-06-01 19:12:07 -0300794 channel->resources = 1;
795 fh->resources = 1;
Dean Andersonf78d92c2008-07-22 14:43:27 -0300796 dprintk(1, "s2255: res: get\n");
Dean Anderson38f993a2008-06-26 23:15:51 -0300797 mutex_unlock(&dev->lock);
798 return 1;
799}
800
Dean Andersonfe85ce92010-06-01 19:12:07 -0300801static int res_locked(struct s2255_fh *fh)
Dean Anderson38f993a2008-06-26 23:15:51 -0300802{
Dean Andersonfe85ce92010-06-01 19:12:07 -0300803 return fh->channel->resources;
Dean Anderson38f993a2008-06-26 23:15:51 -0300804}
805
Dean Andersonf78d92c2008-07-22 14:43:27 -0300806static int res_check(struct s2255_fh *fh)
807{
Dean Andersonfe85ce92010-06-01 19:12:07 -0300808 return fh->resources;
Dean Andersonf78d92c2008-07-22 14:43:27 -0300809}
810
811
Dean Andersonfe85ce92010-06-01 19:12:07 -0300812static void res_free(struct s2255_fh *fh)
Dean Anderson38f993a2008-06-26 23:15:51 -0300813{
Dean Andersonfe85ce92010-06-01 19:12:07 -0300814 struct s2255_channel *channel = fh->channel;
815 struct s2255_dev *dev = fh->dev;
Dean Andersonf78d92c2008-07-22 14:43:27 -0300816 mutex_lock(&dev->lock);
Dean Andersonfe85ce92010-06-01 19:12:07 -0300817 channel->resources = 0;
818 fh->resources = 0;
Dean Andersonf78d92c2008-07-22 14:43:27 -0300819 mutex_unlock(&dev->lock);
Dean Anderson38f993a2008-06-26 23:15:51 -0300820 dprintk(1, "res: put\n");
821}
822
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300823static int vidioc_querymenu(struct file *file, void *priv,
824 struct v4l2_querymenu *qmenu)
825{
826 static const char *colorfilter[] = {
827 "Off",
828 "On",
829 NULL
830 };
831 if (qmenu->id == V4L2_CID_PRIVATE_COLORFILTER) {
832 int i;
833 const char **menu_items = colorfilter;
834 for (i = 0; i < qmenu->index && menu_items[i]; i++)
835 ; /* do nothing (from v4l2-common.c) */
836 if (menu_items[i] == NULL || menu_items[i][0] == '\0')
837 return -EINVAL;
838 strlcpy(qmenu->name, menu_items[qmenu->index],
839 sizeof(qmenu->name));
840 return 0;
841 }
842 return v4l2_ctrl_query_menu(qmenu, NULL, NULL);
843}
844
Dean Anderson38f993a2008-06-26 23:15:51 -0300845static int vidioc_querycap(struct file *file, void *priv,
846 struct v4l2_capability *cap)
847{
848 struct s2255_fh *fh = file->private_data;
849 struct s2255_dev *dev = fh->dev;
850 strlcpy(cap->driver, "s2255", sizeof(cap->driver));
851 strlcpy(cap->card, "s2255", sizeof(cap->card));
Thierry MERLEe22ed882009-01-20 18:19:25 -0300852 usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info));
Dean Anderson38f993a2008-06-26 23:15:51 -0300853 cap->version = S2255_VERSION;
854 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
855 return 0;
856}
857
858static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
859 struct v4l2_fmtdesc *f)
860{
861 int index = 0;
862 if (f)
863 index = f->index;
864
865 if (index >= ARRAY_SIZE(formats))
866 return -EINVAL;
867
868 dprintk(4, "name %s\n", formats[index].name);
869 strlcpy(f->description, formats[index].name, sizeof(f->description));
870 f->pixelformat = formats[index].fourcc;
871 return 0;
872}
873
874static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
875 struct v4l2_format *f)
876{
877 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300878 struct s2255_channel *channel = fh->channel;
Dean Anderson38f993a2008-06-26 23:15:51 -0300879
Dean Andersonfe85ce92010-06-01 19:12:07 -0300880 f->fmt.pix.width = channel->width;
881 f->fmt.pix.height = channel->height;
Dean Anderson38f993a2008-06-26 23:15:51 -0300882 f->fmt.pix.field = fh->vb_vidq.field;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300883 f->fmt.pix.pixelformat = channel->fmt->fourcc;
884 f->fmt.pix.bytesperline = f->fmt.pix.width * (channel->fmt->depth >> 3);
Dean Anderson38f993a2008-06-26 23:15:51 -0300885 f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300886 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -0300887}
888
889static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
890 struct v4l2_format *f)
891{
892 const struct s2255_fmt *fmt;
893 enum v4l2_field field;
894 int b_any_field = 0;
895 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300896 struct s2255_channel *channel = fh->channel;
Dean Anderson38f993a2008-06-26 23:15:51 -0300897 int is_ntsc;
Dean Anderson38f993a2008-06-26 23:15:51 -0300898 is_ntsc =
Dean Andersonfe85ce92010-06-01 19:12:07 -0300899 (channel->vdev.current_norm & V4L2_STD_NTSC) ? 1 : 0;
Dean Anderson38f993a2008-06-26 23:15:51 -0300900
901 fmt = format_by_fourcc(f->fmt.pix.pixelformat);
902
903 if (fmt == NULL)
904 return -EINVAL;
905
906 field = f->fmt.pix.field;
907 if (field == V4L2_FIELD_ANY)
908 b_any_field = 1;
909
Dean Anderson85b85482010-04-08 23:51:17 -0300910 dprintk(50, "%s NTSC: %d suggested width: %d, height: %d\n",
911 __func__, is_ntsc, f->fmt.pix.width, f->fmt.pix.height);
Dean Anderson38f993a2008-06-26 23:15:51 -0300912 if (is_ntsc) {
913 /* NTSC */
914 if (f->fmt.pix.height >= NUM_LINES_1CIFS_NTSC * 2) {
915 f->fmt.pix.height = NUM_LINES_1CIFS_NTSC * 2;
916 if (b_any_field) {
917 field = V4L2_FIELD_SEQ_TB;
918 } else if (!((field == V4L2_FIELD_INTERLACED) ||
919 (field == V4L2_FIELD_SEQ_TB) ||
920 (field == V4L2_FIELD_INTERLACED_TB))) {
921 dprintk(1, "unsupported field setting\n");
922 return -EINVAL;
923 }
924 } else {
925 f->fmt.pix.height = NUM_LINES_1CIFS_NTSC;
926 if (b_any_field) {
927 field = V4L2_FIELD_TOP;
928 } else if (!((field == V4L2_FIELD_TOP) ||
929 (field == V4L2_FIELD_BOTTOM))) {
930 dprintk(1, "unsupported field setting\n");
931 return -EINVAL;
932 }
933
934 }
935 if (f->fmt.pix.width >= LINE_SZ_4CIFS_NTSC)
936 f->fmt.pix.width = LINE_SZ_4CIFS_NTSC;
937 else if (f->fmt.pix.width >= LINE_SZ_2CIFS_NTSC)
938 f->fmt.pix.width = LINE_SZ_2CIFS_NTSC;
939 else if (f->fmt.pix.width >= LINE_SZ_1CIFS_NTSC)
940 f->fmt.pix.width = LINE_SZ_1CIFS_NTSC;
941 else
942 f->fmt.pix.width = LINE_SZ_1CIFS_NTSC;
943 } else {
944 /* PAL */
945 if (f->fmt.pix.height >= NUM_LINES_1CIFS_PAL * 2) {
946 f->fmt.pix.height = NUM_LINES_1CIFS_PAL * 2;
947 if (b_any_field) {
948 field = V4L2_FIELD_SEQ_TB;
949 } else if (!((field == V4L2_FIELD_INTERLACED) ||
950 (field == V4L2_FIELD_SEQ_TB) ||
951 (field == V4L2_FIELD_INTERLACED_TB))) {
952 dprintk(1, "unsupported field setting\n");
953 return -EINVAL;
954 }
955 } else {
956 f->fmt.pix.height = NUM_LINES_1CIFS_PAL;
957 if (b_any_field) {
958 field = V4L2_FIELD_TOP;
959 } else if (!((field == V4L2_FIELD_TOP) ||
960 (field == V4L2_FIELD_BOTTOM))) {
961 dprintk(1, "unsupported field setting\n");
962 return -EINVAL;
963 }
964 }
965 if (f->fmt.pix.width >= LINE_SZ_4CIFS_PAL) {
Dean Anderson38f993a2008-06-26 23:15:51 -0300966 f->fmt.pix.width = LINE_SZ_4CIFS_PAL;
967 field = V4L2_FIELD_SEQ_TB;
968 } else if (f->fmt.pix.width >= LINE_SZ_2CIFS_PAL) {
Dean Anderson38f993a2008-06-26 23:15:51 -0300969 f->fmt.pix.width = LINE_SZ_2CIFS_PAL;
970 field = V4L2_FIELD_TOP;
971 } else if (f->fmt.pix.width >= LINE_SZ_1CIFS_PAL) {
Dean Anderson38f993a2008-06-26 23:15:51 -0300972 f->fmt.pix.width = LINE_SZ_1CIFS_PAL;
973 field = V4L2_FIELD_TOP;
974 } else {
Dean Anderson38f993a2008-06-26 23:15:51 -0300975 f->fmt.pix.width = LINE_SZ_1CIFS_PAL;
976 field = V4L2_FIELD_TOP;
977 }
978 }
Dean Anderson38f993a2008-06-26 23:15:51 -0300979 f->fmt.pix.field = field;
980 f->fmt.pix.bytesperline = (f->fmt.pix.width * fmt->depth) >> 3;
981 f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
Dean Anderson85b85482010-04-08 23:51:17 -0300982 dprintk(50, "%s: set width %d height %d field %d\n", __func__,
983 f->fmt.pix.width, f->fmt.pix.height, f->fmt.pix.field);
Dean Anderson38f993a2008-06-26 23:15:51 -0300984 return 0;
985}
986
987static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
988 struct v4l2_format *f)
989{
990 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300991 struct s2255_channel *channel = fh->channel;
Dean Anderson38f993a2008-06-26 23:15:51 -0300992 const struct s2255_fmt *fmt;
993 struct videobuf_queue *q = &fh->vb_vidq;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300994 struct s2255_mode mode;
Dean Anderson38f993a2008-06-26 23:15:51 -0300995 int ret;
996 int norm;
997
998 ret = vidioc_try_fmt_vid_cap(file, fh, f);
999
1000 if (ret < 0)
Dean Anderson3f8d6f72008-06-30 21:28:34 -03001001 return ret;
Dean Anderson38f993a2008-06-26 23:15:51 -03001002
1003 fmt = format_by_fourcc(f->fmt.pix.pixelformat);
1004
1005 if (fmt == NULL)
1006 return -EINVAL;
1007
1008 mutex_lock(&q->vb_lock);
1009
1010 if (videobuf_queue_is_busy(&fh->vb_vidq)) {
1011 dprintk(1, "queue busy\n");
1012 ret = -EBUSY;
1013 goto out_s_fmt;
1014 }
1015
Dean Andersonfe85ce92010-06-01 19:12:07 -03001016 if (res_locked(fh)) {
Dean Anderson85b85482010-04-08 23:51:17 -03001017 dprintk(1, "%s: channel busy\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03001018 ret = -EBUSY;
1019 goto out_s_fmt;
1020 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001021 mode = channel->mode;
1022 channel->fmt = fmt;
1023 channel->width = f->fmt.pix.width;
1024 channel->height = f->fmt.pix.height;
Dean Anderson38f993a2008-06-26 23:15:51 -03001025 fh->vb_vidq.field = f->fmt.pix.field;
1026 fh->type = f->type;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001027 norm = norm_minw(&channel->vdev);
1028 if (channel->width > norm_minw(&channel->vdev)) {
1029 if (channel->height > norm_minh(&channel->vdev)) {
1030 if (channel->cap_parm.capturemode &
Dean Anderson85b85482010-04-08 23:51:17 -03001031 V4L2_MODE_HIGHQUALITY)
Dean Andersonfe85ce92010-06-01 19:12:07 -03001032 mode.scale = SCALE_4CIFSI;
Dean Anderson85b85482010-04-08 23:51:17 -03001033 else
Dean Andersonfe85ce92010-06-01 19:12:07 -03001034 mode.scale = SCALE_4CIFS;
Dean Anderson7d853532009-05-15 14:32:04 -03001035 } else
Dean Andersonfe85ce92010-06-01 19:12:07 -03001036 mode.scale = SCALE_2CIFS;
Dean Anderson38f993a2008-06-26 23:15:51 -03001037
1038 } else {
Dean Andersonfe85ce92010-06-01 19:12:07 -03001039 mode.scale = SCALE_1CIFS;
Dean Anderson38f993a2008-06-26 23:15:51 -03001040 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001041 /* color mode */
Dean Andersonfe85ce92010-06-01 19:12:07 -03001042 switch (channel->fmt->fourcc) {
Dean Anderson38f993a2008-06-26 23:15:51 -03001043 case V4L2_PIX_FMT_GREY:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001044 mode.color &= ~MASK_COLOR;
1045 mode.color |= COLOR_Y8;
Dean Anderson38f993a2008-06-26 23:15:51 -03001046 break;
Dean Anderson14d96262008-08-25 13:58:55 -03001047 case V4L2_PIX_FMT_JPEG:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001048 mode.color &= ~MASK_COLOR;
1049 mode.color |= COLOR_JPG;
1050 mode.color |= (channel->jc.quality << 8);
Dean Anderson14d96262008-08-25 13:58:55 -03001051 break;
Dean Anderson38f993a2008-06-26 23:15:51 -03001052 case V4L2_PIX_FMT_YUV422P:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001053 mode.color &= ~MASK_COLOR;
1054 mode.color |= COLOR_YUVPL;
Dean Anderson38f993a2008-06-26 23:15:51 -03001055 break;
1056 case V4L2_PIX_FMT_YUYV:
1057 case V4L2_PIX_FMT_UYVY:
1058 default:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001059 mode.color &= ~MASK_COLOR;
1060 mode.color |= COLOR_YUVPK;
Dean Anderson38f993a2008-06-26 23:15:51 -03001061 break;
1062 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001063 if ((mode.color & MASK_COLOR) != (channel->mode.color & MASK_COLOR))
1064 mode.restart = 1;
1065 else if (mode.scale != channel->mode.scale)
1066 mode.restart = 1;
1067 else if (mode.format != channel->mode.format)
1068 mode.restart = 1;
1069 channel->mode = mode;
1070 (void) s2255_set_mode(channel, &mode);
Dean Anderson38f993a2008-06-26 23:15:51 -03001071 ret = 0;
1072out_s_fmt:
1073 mutex_unlock(&q->vb_lock);
1074 return ret;
1075}
1076
1077static int vidioc_reqbufs(struct file *file, void *priv,
1078 struct v4l2_requestbuffers *p)
1079{
1080 int rc;
1081 struct s2255_fh *fh = priv;
1082 rc = videobuf_reqbufs(&fh->vb_vidq, p);
1083 return rc;
1084}
1085
1086static int vidioc_querybuf(struct file *file, void *priv, struct v4l2_buffer *p)
1087{
1088 int rc;
1089 struct s2255_fh *fh = priv;
1090 rc = videobuf_querybuf(&fh->vb_vidq, p);
1091 return rc;
1092}
1093
1094static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *p)
1095{
1096 int rc;
1097 struct s2255_fh *fh = priv;
1098 rc = videobuf_qbuf(&fh->vb_vidq, p);
1099 return rc;
1100}
1101
1102static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
1103{
1104 int rc;
1105 struct s2255_fh *fh = priv;
1106 rc = videobuf_dqbuf(&fh->vb_vidq, p, file->f_flags & O_NONBLOCK);
1107 return rc;
1108}
1109
1110#ifdef CONFIG_VIDEO_V4L1_COMPAT
1111static int vidioc_cgmbuf(struct file *file, void *priv, struct video_mbuf *mbuf)
1112{
1113 struct s2255_fh *fh = priv;
1114
1115 return videobuf_cgmbuf(&fh->vb_vidq, mbuf, 8);
1116}
1117#endif
1118
1119/* write to the configuration pipe, synchronously */
1120static int s2255_write_config(struct usb_device *udev, unsigned char *pbuf,
1121 int size)
1122{
1123 int pipe;
1124 int done;
1125 long retval = -1;
1126 if (udev) {
1127 pipe = usb_sndbulkpipe(udev, S2255_CONFIG_EP);
1128 retval = usb_bulk_msg(udev, pipe, pbuf, size, &done, 500);
1129 }
1130 return retval;
1131}
1132
1133static u32 get_transfer_size(struct s2255_mode *mode)
1134{
1135 int linesPerFrame = LINE_SZ_DEF;
1136 int pixelsPerLine = NUM_LINES_DEF;
1137 u32 outImageSize;
1138 u32 usbInSize;
1139 unsigned int mask_mult;
1140
1141 if (mode == NULL)
1142 return 0;
1143
1144 if (mode->format == FORMAT_NTSC) {
1145 switch (mode->scale) {
1146 case SCALE_4CIFS:
Dean Anderson7d853532009-05-15 14:32:04 -03001147 case SCALE_4CIFSI:
Dean Anderson38f993a2008-06-26 23:15:51 -03001148 linesPerFrame = NUM_LINES_4CIFS_NTSC * 2;
1149 pixelsPerLine = LINE_SZ_4CIFS_NTSC;
1150 break;
1151 case SCALE_2CIFS:
1152 linesPerFrame = NUM_LINES_2CIFS_NTSC;
1153 pixelsPerLine = LINE_SZ_2CIFS_NTSC;
1154 break;
1155 case SCALE_1CIFS:
1156 linesPerFrame = NUM_LINES_1CIFS_NTSC;
1157 pixelsPerLine = LINE_SZ_1CIFS_NTSC;
1158 break;
1159 default:
1160 break;
1161 }
1162 } else if (mode->format == FORMAT_PAL) {
1163 switch (mode->scale) {
1164 case SCALE_4CIFS:
Dean Anderson7d853532009-05-15 14:32:04 -03001165 case SCALE_4CIFSI:
Dean Anderson38f993a2008-06-26 23:15:51 -03001166 linesPerFrame = NUM_LINES_4CIFS_PAL * 2;
1167 pixelsPerLine = LINE_SZ_4CIFS_PAL;
1168 break;
1169 case SCALE_2CIFS:
1170 linesPerFrame = NUM_LINES_2CIFS_PAL;
1171 pixelsPerLine = LINE_SZ_2CIFS_PAL;
1172 break;
1173 case SCALE_1CIFS:
1174 linesPerFrame = NUM_LINES_1CIFS_PAL;
1175 pixelsPerLine = LINE_SZ_1CIFS_PAL;
1176 break;
1177 default:
1178 break;
1179 }
1180 }
1181 outImageSize = linesPerFrame * pixelsPerLine;
Dean Anderson14d96262008-08-25 13:58:55 -03001182 if ((mode->color & MASK_COLOR) != COLOR_Y8) {
Dean Anderson38f993a2008-06-26 23:15:51 -03001183 /* 2 bytes/pixel if not monochrome */
1184 outImageSize *= 2;
1185 }
1186
1187 /* total bytes to send including prefix and 4K padding;
1188 must be a multiple of USB_READ_SIZE */
1189 usbInSize = outImageSize + PREFIX_SIZE; /* always send prefix */
1190 mask_mult = 0xffffffffUL - DEF_USB_BLOCK + 1;
1191 /* if size not a multiple of USB_READ_SIZE */
1192 if (usbInSize & ~mask_mult)
1193 usbInSize = (usbInSize & mask_mult) + (DEF_USB_BLOCK);
1194 return usbInSize;
1195}
1196
Dean Anderson85b85482010-04-08 23:51:17 -03001197static void s2255_print_cfg(struct s2255_dev *sdev, struct s2255_mode *mode)
Dean Anderson38f993a2008-06-26 23:15:51 -03001198{
1199 struct device *dev = &sdev->udev->dev;
1200 dev_info(dev, "------------------------------------------------\n");
Dean Anderson85b85482010-04-08 23:51:17 -03001201 dev_info(dev, "format: %d\nscale %d\n", mode->format, mode->scale);
1202 dev_info(dev, "fdec: %d\ncolor %d\n", mode->fdec, mode->color);
Dean Anderson38f993a2008-06-26 23:15:51 -03001203 dev_info(dev, "bright: 0x%x\n", mode->bright);
Dean Anderson38f993a2008-06-26 23:15:51 -03001204 dev_info(dev, "------------------------------------------------\n");
1205}
1206
1207/*
1208 * set mode is the function which controls the DSP.
1209 * the restart parameter in struct s2255_mode should be set whenever
1210 * the image size could change via color format, video system or image
1211 * size.
1212 * When the restart parameter is set, we sleep for ONE frame to allow the
1213 * DSP time to get the new frame
1214 */
Dean Andersonfe85ce92010-06-01 19:12:07 -03001215static int s2255_set_mode(struct s2255_channel *channel,
Dean Anderson38f993a2008-06-26 23:15:51 -03001216 struct s2255_mode *mode)
1217{
1218 int res;
Dean Anderson3fa00602010-03-04 20:47:33 -03001219 __le32 *buffer;
Dean Anderson38f993a2008-06-26 23:15:51 -03001220 unsigned long chn_rev;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001221 struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev);
Dean Anderson14d96262008-08-25 13:58:55 -03001222 mutex_lock(&dev->lock);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001223 chn_rev = G_chnmap[channel->idx];
1224 dprintk(3, "%s channel: %d\n", __func__, channel->idx);
Dean Anderson22b88d42008-08-29 15:33:19 -03001225 /* if JPEG, set the quality */
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001226 if ((mode->color & MASK_COLOR) == COLOR_JPG) {
1227 mode->color &= ~MASK_COLOR;
1228 mode->color |= COLOR_JPG;
1229 mode->color &= ~MASK_JPG_QUALITY;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001230 mode->color |= (channel->jc.quality << 8);
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001231 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001232 /* save the mode */
Dean Andersonfe85ce92010-06-01 19:12:07 -03001233 channel->mode = *mode;
1234 channel->req_image_size = get_transfer_size(mode);
1235 dprintk(1, "%s: reqsize %ld\n", __func__, channel->req_image_size);
Dean Anderson38f993a2008-06-26 23:15:51 -03001236 buffer = kzalloc(512, GFP_KERNEL);
1237 if (buffer == NULL) {
1238 dev_err(&dev->udev->dev, "out of mem\n");
Dean Anderson14d96262008-08-25 13:58:55 -03001239 mutex_unlock(&dev->lock);
Dean Anderson38f993a2008-06-26 23:15:51 -03001240 return -ENOMEM;
1241 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001242 /* set the mode */
1243 buffer[0] = IN_DATA_TOKEN;
Dean Anderson3fa00602010-03-04 20:47:33 -03001244 buffer[1] = (__le32) cpu_to_le32(chn_rev);
Dean Anderson38f993a2008-06-26 23:15:51 -03001245 buffer[2] = CMD_SET_MODE;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001246 memcpy(&buffer[3], &channel->mode, sizeof(struct s2255_mode));
1247 channel->setmode_ready = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001248 res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
1249 if (debug)
Dean Anderson85b85482010-04-08 23:51:17 -03001250 s2255_print_cfg(dev, mode);
Dean Anderson38f993a2008-06-26 23:15:51 -03001251 kfree(buffer);
Dean Anderson38f993a2008-06-26 23:15:51 -03001252 /* wait at least 3 frames before continuing */
Dean Anderson14d96262008-08-25 13:58:55 -03001253 if (mode->restart) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03001254 wait_event_timeout(channel->wait_setmode,
1255 (channel->setmode_ready != 0),
Dean Anderson14d96262008-08-25 13:58:55 -03001256 msecs_to_jiffies(S2255_SETMODE_TIMEOUT));
Dean Andersonfe85ce92010-06-01 19:12:07 -03001257 if (channel->setmode_ready != 1) {
Dean Anderson14d96262008-08-25 13:58:55 -03001258 printk(KERN_DEBUG "s2255: no set mode response\n");
1259 res = -EFAULT;
1260 }
1261 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001262 /* clear the restart flag */
Dean Andersonfe85ce92010-06-01 19:12:07 -03001263 channel->mode.restart = 0;
Dean Anderson14d96262008-08-25 13:58:55 -03001264 mutex_unlock(&dev->lock);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001265 dprintk(1, "%s chn %d, result: %d\n", __func__, channel->idx, res);
Dean Anderson38f993a2008-06-26 23:15:51 -03001266 return res;
1267}
1268
Dean Andersonfe85ce92010-06-01 19:12:07 -03001269static int s2255_cmd_status(struct s2255_channel *channel, u32 *pstatus)
Dean Anderson4de39f52010-03-03 19:39:19 -03001270{
1271 int res;
Dean Anderson3fa00602010-03-04 20:47:33 -03001272 __le32 *buffer;
Dean Anderson4de39f52010-03-03 19:39:19 -03001273 u32 chn_rev;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001274 struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev);
Dean Anderson4de39f52010-03-03 19:39:19 -03001275 mutex_lock(&dev->lock);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001276 chn_rev = G_chnmap[channel->idx];
1277 dprintk(4, "%s chan %d\n", __func__, channel->idx);
Dean Anderson4de39f52010-03-03 19:39:19 -03001278 buffer = kzalloc(512, GFP_KERNEL);
1279 if (buffer == NULL) {
1280 dev_err(&dev->udev->dev, "out of mem\n");
1281 mutex_unlock(&dev->lock);
1282 return -ENOMEM;
1283 }
1284 /* form the get vid status command */
1285 buffer[0] = IN_DATA_TOKEN;
Dean Anderson3fa00602010-03-04 20:47:33 -03001286 buffer[1] = (__le32) cpu_to_le32(chn_rev);
Dean Anderson4de39f52010-03-03 19:39:19 -03001287 buffer[2] = CMD_STATUS;
1288 *pstatus = 0;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001289 channel->vidstatus_ready = 0;
Dean Anderson4de39f52010-03-03 19:39:19 -03001290 res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
1291 kfree(buffer);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001292 wait_event_timeout(channel->wait_vidstatus,
1293 (channel->vidstatus_ready != 0),
Dean Anderson4de39f52010-03-03 19:39:19 -03001294 msecs_to_jiffies(S2255_VIDSTATUS_TIMEOUT));
Dean Andersonfe85ce92010-06-01 19:12:07 -03001295 if (channel->vidstatus_ready != 1) {
Dean Anderson4de39f52010-03-03 19:39:19 -03001296 printk(KERN_DEBUG "s2255: no vidstatus response\n");
1297 res = -EFAULT;
1298 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001299 *pstatus = channel->vidstatus;
Dean Anderson4de39f52010-03-03 19:39:19 -03001300 dprintk(4, "%s, vid status %d\n", __func__, *pstatus);
1301 mutex_unlock(&dev->lock);
1302 return res;
1303}
1304
Dean Anderson38f993a2008-06-26 23:15:51 -03001305static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
1306{
1307 int res;
1308 struct s2255_fh *fh = priv;
1309 struct s2255_dev *dev = fh->dev;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001310 struct s2255_channel *channel = fh->channel;
Dean Anderson38f993a2008-06-26 23:15:51 -03001311 int j;
1312 dprintk(4, "%s\n", __func__);
1313 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1314 dev_err(&dev->udev->dev, "invalid fh type0\n");
1315 return -EINVAL;
1316 }
1317 if (i != fh->type) {
1318 dev_err(&dev->udev->dev, "invalid fh type1\n");
1319 return -EINVAL;
1320 }
1321
Dean Andersonfe85ce92010-06-01 19:12:07 -03001322 if (!res_get(fh)) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03001323 s2255_dev_err(&dev->udev->dev, "stream busy\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03001324 return -EBUSY;
1325 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001326 channel->last_frame = -1;
1327 channel->bad_payload = 0;
1328 channel->cur_frame = 0;
1329 channel->frame_count = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001330 for (j = 0; j < SYS_FRAMES; j++) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03001331 channel->buffer.frame[j].ulState = S2255_READ_IDLE;
1332 channel->buffer.frame[j].cur_size = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001333 }
1334 res = videobuf_streamon(&fh->vb_vidq);
1335 if (res == 0) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03001336 s2255_start_acquire(channel);
1337 channel->b_acquire = 1;
1338 } else
1339 res_free(fh);
1340
Dean Anderson38f993a2008-06-26 23:15:51 -03001341 return res;
1342}
1343
1344static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
1345{
Dean Anderson38f993a2008-06-26 23:15:51 -03001346 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001347 dprintk(4, "%s\n, channel: %d", __func__, fh->channel->idx);
Dean Anderson38f993a2008-06-26 23:15:51 -03001348 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1349 printk(KERN_ERR "invalid fh type0\n");
1350 return -EINVAL;
1351 }
1352 if (i != fh->type) {
1353 printk(KERN_ERR "invalid type i\n");
1354 return -EINVAL;
1355 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001356 s2255_stop_acquire(fh->channel);
Dean Andersonb7732a32009-03-30 11:59:56 -03001357 videobuf_streamoff(&fh->vb_vidq);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001358 res_free(fh);
Dean Andersonf78d92c2008-07-22 14:43:27 -03001359 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001360}
1361
1362static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *i)
1363{
1364 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001365 struct s2255_mode mode;
Dean Anderson38f993a2008-06-26 23:15:51 -03001366 struct videobuf_queue *q = &fh->vb_vidq;
1367 int ret = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001368 mutex_lock(&q->vb_lock);
1369 if (videobuf_queue_is_busy(q)) {
1370 dprintk(1, "queue busy\n");
1371 ret = -EBUSY;
1372 goto out_s_std;
1373 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001374 if (res_locked(fh)) {
Dean Anderson38f993a2008-06-26 23:15:51 -03001375 dprintk(1, "can't change standard after started\n");
1376 ret = -EBUSY;
1377 goto out_s_std;
1378 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001379 mode = fh->channel->mode;
Dean Anderson38f993a2008-06-26 23:15:51 -03001380 if (*i & V4L2_STD_NTSC) {
Dean Andersone6b44bc2010-03-08 20:04:48 -03001381 dprintk(4, "%s NTSC\n", __func__);
1382 /* if changing format, reset frame decimation/intervals */
Dean Andersonfe85ce92010-06-01 19:12:07 -03001383 if (mode.format != FORMAT_NTSC) {
1384 mode.restart = 1;
1385 mode.format = FORMAT_NTSC;
1386 mode.fdec = FDEC_1;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001387 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001388 } else if (*i & V4L2_STD_PAL) {
Dean Andersone6b44bc2010-03-08 20:04:48 -03001389 dprintk(4, "%s PAL\n", __func__);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001390 if (mode.format != FORMAT_PAL) {
1391 mode.restart = 1;
1392 mode.format = FORMAT_PAL;
1393 mode.fdec = FDEC_1;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001394 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001395 } else {
1396 ret = -EINVAL;
1397 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001398 if (mode.restart)
1399 s2255_set_mode(fh->channel, &mode);
Dean Anderson38f993a2008-06-26 23:15:51 -03001400out_s_std:
1401 mutex_unlock(&q->vb_lock);
1402 return ret;
1403}
1404
1405/* Sensoray 2255 is a multiple channel capture device.
1406 It does not have a "crossbar" of inputs.
1407 We use one V4L device per channel. The user must
1408 be aware that certain combinations are not allowed.
1409 For instance, you cannot do full FPS on more than 2 channels(2 videodevs)
1410 at once in color(you can do full fps on 4 channels with greyscale.
1411*/
1412static int vidioc_enum_input(struct file *file, void *priv,
1413 struct v4l2_input *inp)
1414{
Dean Anderson4de39f52010-03-03 19:39:19 -03001415 struct s2255_fh *fh = priv;
1416 struct s2255_dev *dev = fh->dev;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001417 struct s2255_channel *channel = fh->channel;
Dean Anderson4de39f52010-03-03 19:39:19 -03001418 u32 status = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001419 if (inp->index != 0)
1420 return -EINVAL;
Dean Anderson38f993a2008-06-26 23:15:51 -03001421 inp->type = V4L2_INPUT_TYPE_CAMERA;
1422 inp->std = S2255_NORMS;
Dean Anderson4de39f52010-03-03 19:39:19 -03001423 inp->status = 0;
1424 if (dev->dsp_fw_ver >= S2255_MIN_DSP_STATUS) {
1425 int rc;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001426 rc = s2255_cmd_status(fh->channel, &status);
Dean Anderson4de39f52010-03-03 19:39:19 -03001427 dprintk(4, "s2255_cmd_status rc: %d status %x\n", rc, status);
1428 if (rc == 0)
1429 inp->status = (status & 0x01) ? 0
1430 : V4L2_IN_ST_NO_SIGNAL;
1431 }
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001432 switch (dev->pid) {
1433 case 0x2255:
1434 default:
1435 strlcpy(inp->name, "Composite", sizeof(inp->name));
1436 break;
1437 case 0x2257:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001438 strlcpy(inp->name, (channel->idx < 2) ? "Composite" : "S-Video",
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001439 sizeof(inp->name));
1440 break;
1441 }
Dean Anderson3f8d6f72008-06-30 21:28:34 -03001442 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001443}
1444
1445static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
1446{
1447 *i = 0;
1448 return 0;
1449}
1450static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
1451{
1452 if (i > 0)
1453 return -EINVAL;
1454 return 0;
1455}
1456
1457/* --- controls ---------------------------------------------- */
1458static int vidioc_queryctrl(struct file *file, void *priv,
1459 struct v4l2_queryctrl *qc)
1460{
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001461 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001462 struct s2255_channel *channel = fh->channel;
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001463 struct s2255_dev *dev = fh->dev;
Dean Anderson2e70db92010-03-05 14:29:09 -03001464 switch (qc->id) {
1465 case V4L2_CID_BRIGHTNESS:
1466 v4l2_ctrl_query_fill(qc, -127, 127, 1, DEF_BRIGHT);
1467 break;
1468 case V4L2_CID_CONTRAST:
1469 v4l2_ctrl_query_fill(qc, 0, 255, 1, DEF_CONTRAST);
1470 break;
1471 case V4L2_CID_SATURATION:
1472 v4l2_ctrl_query_fill(qc, 0, 255, 1, DEF_SATURATION);
1473 break;
1474 case V4L2_CID_HUE:
1475 v4l2_ctrl_query_fill(qc, 0, 255, 1, DEF_HUE);
1476 break;
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001477 case V4L2_CID_PRIVATE_COLORFILTER:
1478 if (dev->dsp_fw_ver < S2255_MIN_DSP_COLORFILTER)
1479 return -EINVAL;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001480 if ((dev->pid == 0x2257) && (channel->idx > 1))
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001481 return -EINVAL;
1482 strlcpy(qc->name, "Color Filter", sizeof(qc->name));
1483 qc->type = V4L2_CTRL_TYPE_MENU;
1484 qc->minimum = 0;
1485 qc->maximum = 1;
1486 qc->step = 1;
1487 qc->default_value = 1;
1488 qc->flags = 0;
1489 break;
Dean Anderson2e70db92010-03-05 14:29:09 -03001490 default:
1491 return -EINVAL;
1492 }
1493 dprintk(4, "%s, id %d\n", __func__, qc->id);
1494 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001495}
1496
1497static int vidioc_g_ctrl(struct file *file, void *priv,
1498 struct v4l2_control *ctrl)
1499{
Dean Anderson2e70db92010-03-05 14:29:09 -03001500 struct s2255_fh *fh = priv;
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001501 struct s2255_dev *dev = fh->dev;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001502 struct s2255_channel *channel = fh->channel;
Dean Anderson2e70db92010-03-05 14:29:09 -03001503 switch (ctrl->id) {
1504 case V4L2_CID_BRIGHTNESS:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001505 ctrl->value = channel->mode.bright;
Dean Anderson2e70db92010-03-05 14:29:09 -03001506 break;
1507 case V4L2_CID_CONTRAST:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001508 ctrl->value = channel->mode.contrast;
Dean Anderson2e70db92010-03-05 14:29:09 -03001509 break;
1510 case V4L2_CID_SATURATION:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001511 ctrl->value = channel->mode.saturation;
Dean Anderson2e70db92010-03-05 14:29:09 -03001512 break;
1513 case V4L2_CID_HUE:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001514 ctrl->value = channel->mode.hue;
Dean Anderson2e70db92010-03-05 14:29:09 -03001515 break;
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001516 case V4L2_CID_PRIVATE_COLORFILTER:
1517 if (dev->dsp_fw_ver < S2255_MIN_DSP_COLORFILTER)
1518 return -EINVAL;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001519 if ((dev->pid == 0x2257) && (channel->idx > 1))
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001520 return -EINVAL;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001521 ctrl->value = !((channel->mode.color & MASK_INPUT_TYPE) >> 16);
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001522 break;
Dean Anderson2e70db92010-03-05 14:29:09 -03001523 default:
1524 return -EINVAL;
1525 }
1526 dprintk(4, "%s, id %d val %d\n", __func__, ctrl->id, ctrl->value);
1527 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001528}
1529
1530static int vidioc_s_ctrl(struct file *file, void *priv,
1531 struct v4l2_control *ctrl)
1532{
Dean Anderson38f993a2008-06-26 23:15:51 -03001533 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001534 struct s2255_channel *channel = fh->channel;
1535 struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev);
1536 struct s2255_mode mode;
1537 mode = channel->mode;
Dean Anderson2e70db92010-03-05 14:29:09 -03001538 dprintk(4, "%s\n", __func__);
1539 /* update the mode to the corresponding value */
1540 switch (ctrl->id) {
1541 case V4L2_CID_BRIGHTNESS:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001542 mode.bright = ctrl->value;
Dean Anderson2e70db92010-03-05 14:29:09 -03001543 break;
1544 case V4L2_CID_CONTRAST:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001545 mode.contrast = ctrl->value;
Dean Anderson2e70db92010-03-05 14:29:09 -03001546 break;
1547 case V4L2_CID_HUE:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001548 mode.hue = ctrl->value;
Dean Anderson2e70db92010-03-05 14:29:09 -03001549 break;
1550 case V4L2_CID_SATURATION:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001551 mode.saturation = ctrl->value;
Dean Anderson2e70db92010-03-05 14:29:09 -03001552 break;
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001553 case V4L2_CID_PRIVATE_COLORFILTER:
1554 if (dev->dsp_fw_ver < S2255_MIN_DSP_COLORFILTER)
1555 return -EINVAL;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001556 if ((dev->pid == 0x2257) && (channel->idx > 1))
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001557 return -EINVAL;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001558 mode.color &= ~MASK_INPUT_TYPE;
1559 mode.color |= ((ctrl->value ? 0 : 1) << 16);
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001560 break;
Dean Anderson2e70db92010-03-05 14:29:09 -03001561 default:
1562 return -EINVAL;
Dean Anderson38f993a2008-06-26 23:15:51 -03001563 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001564 mode.restart = 0;
Dean Anderson2e70db92010-03-05 14:29:09 -03001565 /* set mode here. Note: stream does not need restarted.
1566 some V4L programs restart stream unnecessarily
1567 after a s_crtl.
1568 */
Dean Andersonfe85ce92010-06-01 19:12:07 -03001569 s2255_set_mode(fh->channel, &mode);
Dean Anderson2e70db92010-03-05 14:29:09 -03001570 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001571}
1572
Dean Anderson22b88d42008-08-29 15:33:19 -03001573static int vidioc_g_jpegcomp(struct file *file, void *priv,
1574 struct v4l2_jpegcompression *jc)
1575{
1576 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001577 struct s2255_channel *channel = fh->channel;
1578 *jc = channel->jc;
Dean Anderson85b85482010-04-08 23:51:17 -03001579 dprintk(2, "%s: quality %d\n", __func__, jc->quality);
Dean Anderson22b88d42008-08-29 15:33:19 -03001580 return 0;
1581}
1582
1583static int vidioc_s_jpegcomp(struct file *file, void *priv,
1584 struct v4l2_jpegcompression *jc)
1585{
1586 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001587 struct s2255_channel *channel = fh->channel;
Dean Anderson22b88d42008-08-29 15:33:19 -03001588 if (jc->quality < 0 || jc->quality > 100)
1589 return -EINVAL;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001590 channel->jc.quality = jc->quality;
Dean Anderson85b85482010-04-08 23:51:17 -03001591 dprintk(2, "%s: quality %d\n", __func__, jc->quality);
Dean Anderson22b88d42008-08-29 15:33:19 -03001592 return 0;
1593}
Dean Anderson7d853532009-05-15 14:32:04 -03001594
1595static int vidioc_g_parm(struct file *file, void *priv,
1596 struct v4l2_streamparm *sp)
1597{
1598 struct s2255_fh *fh = priv;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001599 __u32 def_num, def_dem;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001600 struct s2255_channel *channel = fh->channel;
Dean Anderson7d853532009-05-15 14:32:04 -03001601 if (sp->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1602 return -EINVAL;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001603 memset(sp, 0, sizeof(struct v4l2_streamparm));
1604 sp->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001605 sp->parm.capture.capturemode = channel->cap_parm.capturemode;
1606 def_num = (channel->mode.format == FORMAT_NTSC) ? 1001 : 1000;
1607 def_dem = (channel->mode.format == FORMAT_NTSC) ? 30000 : 25000;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001608 sp->parm.capture.timeperframe.denominator = def_dem;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001609 switch (channel->mode.fdec) {
Dean Andersone6b44bc2010-03-08 20:04:48 -03001610 default:
1611 case FDEC_1:
1612 sp->parm.capture.timeperframe.numerator = def_num;
1613 break;
1614 case FDEC_2:
1615 sp->parm.capture.timeperframe.numerator = def_num * 2;
1616 break;
1617 case FDEC_3:
1618 sp->parm.capture.timeperframe.numerator = def_num * 3;
1619 break;
1620 case FDEC_5:
1621 sp->parm.capture.timeperframe.numerator = def_num * 5;
1622 break;
1623 }
1624 dprintk(4, "%s capture mode, %d timeperframe %d/%d\n", __func__,
1625 sp->parm.capture.capturemode,
1626 sp->parm.capture.timeperframe.numerator,
1627 sp->parm.capture.timeperframe.denominator);
Dean Anderson7d853532009-05-15 14:32:04 -03001628 return 0;
1629}
1630
1631static int vidioc_s_parm(struct file *file, void *priv,
1632 struct v4l2_streamparm *sp)
1633{
1634 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001635 struct s2255_channel *channel = fh->channel;
1636 struct s2255_mode mode;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001637 int fdec = FDEC_1;
1638 __u32 def_num, def_dem;
Dean Anderson7d853532009-05-15 14:32:04 -03001639 if (sp->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1640 return -EINVAL;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001641 mode = channel->mode;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001642 /* high quality capture mode requires a stream restart */
Dean Andersonfe85ce92010-06-01 19:12:07 -03001643 if (channel->cap_parm.capturemode
1644 != sp->parm.capture.capturemode && res_locked(fh))
Dean Andersone6b44bc2010-03-08 20:04:48 -03001645 return -EBUSY;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001646 def_num = (mode.format == FORMAT_NTSC) ? 1001 : 1000;
1647 def_dem = (mode.format == FORMAT_NTSC) ? 30000 : 25000;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001648 if (def_dem != sp->parm.capture.timeperframe.denominator)
1649 sp->parm.capture.timeperframe.numerator = def_num;
1650 else if (sp->parm.capture.timeperframe.numerator <= def_num)
1651 sp->parm.capture.timeperframe.numerator = def_num;
1652 else if (sp->parm.capture.timeperframe.numerator <= (def_num * 2)) {
1653 sp->parm.capture.timeperframe.numerator = def_num * 2;
1654 fdec = FDEC_2;
1655 } else if (sp->parm.capture.timeperframe.numerator <= (def_num * 3)) {
1656 sp->parm.capture.timeperframe.numerator = def_num * 3;
1657 fdec = FDEC_3;
1658 } else {
1659 sp->parm.capture.timeperframe.numerator = def_num * 5;
1660 fdec = FDEC_5;
1661 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001662 mode.fdec = fdec;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001663 sp->parm.capture.timeperframe.denominator = def_dem;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001664 s2255_set_mode(channel, &mode);
Dean Andersone6b44bc2010-03-08 20:04:48 -03001665 dprintk(4, "%s capture mode, %d timeperframe %d/%d, fdec %d\n",
1666 __func__,
1667 sp->parm.capture.capturemode,
1668 sp->parm.capture.timeperframe.numerator,
1669 sp->parm.capture.timeperframe.denominator, fdec);
Dean Anderson7d853532009-05-15 14:32:04 -03001670 return 0;
1671}
Dean Andersone6b44bc2010-03-08 20:04:48 -03001672
1673static int vidioc_enum_frameintervals(struct file *file, void *priv,
1674 struct v4l2_frmivalenum *fe)
1675{
1676 int is_ntsc = 0;
1677#define NUM_FRAME_ENUMS 4
1678 int frm_dec[NUM_FRAME_ENUMS] = {1, 2, 3, 5};
1679 if (fe->index < 0 || fe->index >= NUM_FRAME_ENUMS)
1680 return -EINVAL;
1681 switch (fe->width) {
1682 case 640:
1683 if (fe->height != 240 && fe->height != 480)
1684 return -EINVAL;
1685 is_ntsc = 1;
1686 break;
1687 case 320:
1688 if (fe->height != 240)
1689 return -EINVAL;
1690 is_ntsc = 1;
1691 break;
1692 case 704:
1693 if (fe->height != 288 && fe->height != 576)
1694 return -EINVAL;
1695 break;
1696 case 352:
1697 if (fe->height != 288)
1698 return -EINVAL;
1699 break;
1700 default:
1701 return -EINVAL;
1702 }
1703 fe->type = V4L2_FRMIVAL_TYPE_DISCRETE;
1704 fe->discrete.denominator = is_ntsc ? 30000 : 25000;
1705 fe->discrete.numerator = (is_ntsc ? 1001 : 1000) * frm_dec[fe->index];
1706 dprintk(4, "%s discrete %d/%d\n", __func__, fe->discrete.numerator,
1707 fe->discrete.denominator);
1708 return 0;
1709}
1710
Hans Verkuilbec43662008-12-30 06:58:20 -03001711static int s2255_open(struct file *file)
Dean Anderson38f993a2008-06-26 23:15:51 -03001712{
Laurent Pinchart63b0d5a2009-12-10 11:44:04 -02001713 struct video_device *vdev = video_devdata(file);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001714 struct s2255_channel *channel = video_drvdata(file);
1715 struct s2255_dev *dev = to_s2255_dev(vdev->v4l2_dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03001716 struct s2255_fh *fh;
Laurent Pinchart63b0d5a2009-12-10 11:44:04 -02001717 enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
Dean Anderson14d96262008-08-25 13:58:55 -03001718 int state;
Laurent Pinchart50462eb2009-12-10 11:47:13 -02001719 dprintk(1, "s2255: open called (dev=%s)\n",
1720 video_device_node_name(vdev));
Dean Andersonff7e22d2010-04-08 23:38:07 -03001721 /*
1722 * open lock necessary to prevent multiple instances
1723 * of v4l-conf (or other programs) from simultaneously
1724 * reloading firmware.
1725 */
Dean Anderson38f993a2008-06-26 23:15:51 -03001726 mutex_lock(&dev->open_lock);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001727 state = atomic_read(&dev->fw_data->fw_state);
1728 switch (state) {
1729 case S2255_FW_DISCONNECTING:
1730 mutex_unlock(&dev->open_lock);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001731 return -ENODEV;
Dean Anderson14d96262008-08-25 13:58:55 -03001732 case S2255_FW_FAILED:
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03001733 s2255_dev_err(&dev->udev->dev,
1734 "firmware load failed. retrying.\n");
Dean Anderson14d96262008-08-25 13:58:55 -03001735 s2255_fwload_start(dev, 1);
Dean Anderson38f993a2008-06-26 23:15:51 -03001736 wait_event_timeout(dev->fw_data->wait_fw,
Dean Anderson14d96262008-08-25 13:58:55 -03001737 ((atomic_read(&dev->fw_data->fw_state)
1738 == S2255_FW_SUCCESS) ||
1739 (atomic_read(&dev->fw_data->fw_state)
1740 == S2255_FW_DISCONNECTING)),
Dean Anderson38f993a2008-06-26 23:15:51 -03001741 msecs_to_jiffies(S2255_LOAD_TIMEOUT));
Dean Andersonff7e22d2010-04-08 23:38:07 -03001742 /* state may have changed, re-read */
1743 state = atomic_read(&dev->fw_data->fw_state);
Dean Anderson14d96262008-08-25 13:58:55 -03001744 break;
1745 case S2255_FW_NOTLOADED:
1746 case S2255_FW_LOADED_DSPWAIT:
Dean Anderson38f993a2008-06-26 23:15:51 -03001747 /* give S2255_LOAD_TIMEOUT time for firmware to load in case
1748 driver loaded and then device immediately opened */
1749 printk(KERN_INFO "%s waiting for firmware load\n", __func__);
1750 wait_event_timeout(dev->fw_data->wait_fw,
Dean Anderson14d96262008-08-25 13:58:55 -03001751 ((atomic_read(&dev->fw_data->fw_state)
1752 == S2255_FW_SUCCESS) ||
1753 (atomic_read(&dev->fw_data->fw_state)
1754 == S2255_FW_DISCONNECTING)),
Dean Andersoneb78dee2010-04-12 15:05:37 -03001755 msecs_to_jiffies(S2255_LOAD_TIMEOUT));
Dean Andersonff7e22d2010-04-08 23:38:07 -03001756 /* state may have changed, re-read */
1757 state = atomic_read(&dev->fw_data->fw_state);
Dean Anderson14d96262008-08-25 13:58:55 -03001758 break;
1759 case S2255_FW_SUCCESS:
1760 default:
1761 break;
1762 }
Dean Andersonff7e22d2010-04-08 23:38:07 -03001763 /* state may have changed in above switch statement */
1764 switch (state) {
1765 case S2255_FW_SUCCESS:
1766 break;
1767 case S2255_FW_FAILED:
1768 printk(KERN_INFO "2255 firmware load failed.\n");
Dean Andersoneb78dee2010-04-12 15:05:37 -03001769 mutex_unlock(&dev->open_lock);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001770 return -ENODEV;
1771 case S2255_FW_DISCONNECTING:
1772 printk(KERN_INFO "%s: disconnecting\n", __func__);
Dean Andersoneb78dee2010-04-12 15:05:37 -03001773 mutex_unlock(&dev->open_lock);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001774 return -ENODEV;
1775 case S2255_FW_LOADED_DSPWAIT:
1776 case S2255_FW_NOTLOADED:
1777 printk(KERN_INFO "%s: firmware not loaded yet"
1778 "please try again later\n",
1779 __func__);
Dean Andersoneb78dee2010-04-12 15:05:37 -03001780 /*
1781 * Timeout on firmware load means device unusable.
1782 * Set firmware failure state.
1783 * On next s2255_open the firmware will be reloaded.
1784 */
1785 atomic_set(&dev->fw_data->fw_state,
1786 S2255_FW_FAILED);
1787 mutex_unlock(&dev->open_lock);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001788 return -EAGAIN;
1789 default:
1790 printk(KERN_INFO "%s: unknown state\n", __func__);
Dean Andersoneb78dee2010-04-12 15:05:37 -03001791 mutex_unlock(&dev->open_lock);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001792 return -EFAULT;
Dean Anderson38f993a2008-06-26 23:15:51 -03001793 }
Dean Andersoneb78dee2010-04-12 15:05:37 -03001794 mutex_unlock(&dev->open_lock);
Dean Anderson38f993a2008-06-26 23:15:51 -03001795 /* allocate + initialize per filehandle data */
1796 fh = kzalloc(sizeof(*fh), GFP_KERNEL);
Dean Andersona5ef91c2010-04-08 23:46:08 -03001797 if (NULL == fh)
Dean Anderson38f993a2008-06-26 23:15:51 -03001798 return -ENOMEM;
Dean Anderson38f993a2008-06-26 23:15:51 -03001799 file->private_data = fh;
1800 fh->dev = dev;
1801 fh->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001802 fh->channel = channel;
1803 if (!channel->configured) {
1804 /* configure channel to default state */
1805 channel->fmt = &formats[0];
1806 s2255_set_mode(channel, &channel->mode);
1807 channel->configured = 1;
Dean Anderson14d96262008-08-25 13:58:55 -03001808 }
Dean Anderson85b85482010-04-08 23:51:17 -03001809 dprintk(1, "%s: dev=%s type=%s\n", __func__,
Dean Andersonff7e22d2010-04-08 23:38:07 -03001810 video_device_node_name(vdev), v4l2_type_names[type]);
Dean Anderson85b85482010-04-08 23:51:17 -03001811 dprintk(2, "%s: fh=0x%08lx, dev=0x%08lx, vidq=0x%08lx\n", __func__,
Dean Anderson38f993a2008-06-26 23:15:51 -03001812 (unsigned long)fh, (unsigned long)dev,
Dean Andersonfe85ce92010-06-01 19:12:07 -03001813 (unsigned long)&channel->vidq);
Dean Anderson85b85482010-04-08 23:51:17 -03001814 dprintk(4, "%s: list_empty active=%d\n", __func__,
Dean Andersonfe85ce92010-06-01 19:12:07 -03001815 list_empty(&channel->vidq.active));
Dean Anderson38f993a2008-06-26 23:15:51 -03001816 videobuf_queue_vmalloc_init(&fh->vb_vidq, &s2255_video_qops,
1817 NULL, &dev->slock,
1818 fh->type,
1819 V4L2_FIELD_INTERLACED,
Hans Verkuil08bff032010-09-20 17:39:46 -03001820 sizeof(struct s2255_buffer), fh, NULL);
Dean Anderson38f993a2008-06-26 23:15:51 -03001821 return 0;
1822}
1823
1824
1825static unsigned int s2255_poll(struct file *file,
1826 struct poll_table_struct *wait)
1827{
1828 struct s2255_fh *fh = file->private_data;
1829 int rc;
1830 dprintk(100, "%s\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03001831 if (V4L2_BUF_TYPE_VIDEO_CAPTURE != fh->type)
1832 return POLLERR;
Dean Anderson38f993a2008-06-26 23:15:51 -03001833 rc = videobuf_poll_stream(file, &fh->vb_vidq, wait);
1834 return rc;
1835}
1836
Dean Andersond62e85a2010-04-09 19:54:26 -03001837static void s2255_destroy(struct s2255_dev *dev)
Dean Anderson38f993a2008-06-26 23:15:51 -03001838{
Dean Anderson38f993a2008-06-26 23:15:51 -03001839 /* board shutdown stops the read pipe if it is running */
1840 s2255_board_shutdown(dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03001841 /* make sure firmware still not trying to load */
Dean Andersonf78d92c2008-07-22 14:43:27 -03001842 del_timer(&dev->timer); /* only started in .probe and .open */
Dean Anderson38f993a2008-06-26 23:15:51 -03001843 if (dev->fw_data->fw_urb) {
Dean Anderson38f993a2008-06-26 23:15:51 -03001844 usb_kill_urb(dev->fw_data->fw_urb);
1845 usb_free_urb(dev->fw_data->fw_urb);
1846 dev->fw_data->fw_urb = NULL;
1847 }
Dean Andersonf78d92c2008-07-22 14:43:27 -03001848 if (dev->fw_data->fw)
1849 release_firmware(dev->fw_data->fw);
1850 kfree(dev->fw_data->pfw_data);
1851 kfree(dev->fw_data);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001852 /* reset the DSP so firmware can be reloaded next time */
1853 s2255_reset_dsppower(dev);
1854 mutex_destroy(&dev->open_lock);
1855 mutex_destroy(&dev->lock);
Dean Anderson38f993a2008-06-26 23:15:51 -03001856 usb_put_dev(dev->udev);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001857 v4l2_device_unregister(&dev->v4l2_dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03001858 dprintk(1, "%s", __func__);
Dean Andersonb7732a32009-03-30 11:59:56 -03001859 kfree(dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03001860}
1861
Dean Andersonff7e22d2010-04-08 23:38:07 -03001862static int s2255_release(struct file *file)
Dean Anderson38f993a2008-06-26 23:15:51 -03001863{
1864 struct s2255_fh *fh = file->private_data;
1865 struct s2255_dev *dev = fh->dev;
Laurent Pinchart50462eb2009-12-10 11:47:13 -02001866 struct video_device *vdev = video_devdata(file);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001867 struct s2255_channel *channel = fh->channel;
Dean Anderson38f993a2008-06-26 23:15:51 -03001868 if (!dev)
1869 return -ENODEV;
Dean Andersonf78d92c2008-07-22 14:43:27 -03001870 /* turn off stream */
1871 if (res_check(fh)) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03001872 if (channel->b_acquire)
1873 s2255_stop_acquire(fh->channel);
Dean Andersonf78d92c2008-07-22 14:43:27 -03001874 videobuf_streamoff(&fh->vb_vidq);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001875 res_free(fh);
Dean Andersonf78d92c2008-07-22 14:43:27 -03001876 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001877 videobuf_mmap_free(&fh->vb_vidq);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001878 dprintk(1, "%s (dev=%s)\n", __func__, video_device_node_name(vdev));
Dean Andersonf78d92c2008-07-22 14:43:27 -03001879 kfree(fh);
Dean Anderson38f993a2008-06-26 23:15:51 -03001880 return 0;
1881}
1882
1883static int s2255_mmap_v4l(struct file *file, struct vm_area_struct *vma)
1884{
1885 struct s2255_fh *fh = file->private_data;
1886 int ret;
1887
1888 if (!fh)
1889 return -ENODEV;
Dean Anderson85b85482010-04-08 23:51:17 -03001890 dprintk(4, "%s, vma=0x%08lx\n", __func__, (unsigned long)vma);
Dean Anderson38f993a2008-06-26 23:15:51 -03001891 ret = videobuf_mmap_mapper(&fh->vb_vidq, vma);
Dean Anderson85b85482010-04-08 23:51:17 -03001892 dprintk(4, "%s vma start=0x%08lx, size=%ld, ret=%d\n", __func__,
Dean Anderson38f993a2008-06-26 23:15:51 -03001893 (unsigned long)vma->vm_start,
1894 (unsigned long)vma->vm_end - (unsigned long)vma->vm_start, ret);
Dean Anderson38f993a2008-06-26 23:15:51 -03001895 return ret;
1896}
1897
Hans Verkuilbec43662008-12-30 06:58:20 -03001898static const struct v4l2_file_operations s2255_fops_v4l = {
Dean Anderson38f993a2008-06-26 23:15:51 -03001899 .owner = THIS_MODULE,
1900 .open = s2255_open,
Dean Andersonff7e22d2010-04-08 23:38:07 -03001901 .release = s2255_release,
Dean Anderson38f993a2008-06-26 23:15:51 -03001902 .poll = s2255_poll,
1903 .ioctl = video_ioctl2, /* V4L2 ioctl handler */
Dean Anderson38f993a2008-06-26 23:15:51 -03001904 .mmap = s2255_mmap_v4l,
Dean Anderson38f993a2008-06-26 23:15:51 -03001905};
1906
Hans Verkuila3998102008-07-21 02:57:38 -03001907static const struct v4l2_ioctl_ops s2255_ioctl_ops = {
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001908 .vidioc_querymenu = vidioc_querymenu,
Dean Anderson38f993a2008-06-26 23:15:51 -03001909 .vidioc_querycap = vidioc_querycap,
1910 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
1911 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
1912 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
1913 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
1914 .vidioc_reqbufs = vidioc_reqbufs,
1915 .vidioc_querybuf = vidioc_querybuf,
1916 .vidioc_qbuf = vidioc_qbuf,
1917 .vidioc_dqbuf = vidioc_dqbuf,
1918 .vidioc_s_std = vidioc_s_std,
1919 .vidioc_enum_input = vidioc_enum_input,
1920 .vidioc_g_input = vidioc_g_input,
1921 .vidioc_s_input = vidioc_s_input,
1922 .vidioc_queryctrl = vidioc_queryctrl,
1923 .vidioc_g_ctrl = vidioc_g_ctrl,
1924 .vidioc_s_ctrl = vidioc_s_ctrl,
1925 .vidioc_streamon = vidioc_streamon,
1926 .vidioc_streamoff = vidioc_streamoff,
1927#ifdef CONFIG_VIDEO_V4L1_COMPAT
1928 .vidiocgmbuf = vidioc_cgmbuf,
1929#endif
Dean Anderson22b88d42008-08-29 15:33:19 -03001930 .vidioc_s_jpegcomp = vidioc_s_jpegcomp,
1931 .vidioc_g_jpegcomp = vidioc_g_jpegcomp,
Dean Anderson7d853532009-05-15 14:32:04 -03001932 .vidioc_s_parm = vidioc_s_parm,
1933 .vidioc_g_parm = vidioc_g_parm,
Dean Andersone6b44bc2010-03-08 20:04:48 -03001934 .vidioc_enum_frameintervals = vidioc_enum_frameintervals,
Hans Verkuila3998102008-07-21 02:57:38 -03001935};
1936
Dean Andersonff7e22d2010-04-08 23:38:07 -03001937static void s2255_video_device_release(struct video_device *vdev)
1938{
Dean Andersonfe85ce92010-06-01 19:12:07 -03001939 struct s2255_dev *dev = to_s2255_dev(vdev->v4l2_dev);
1940 dprintk(4, "%s, chnls: %d \n", __func__,
1941 atomic_read(&dev->num_channels));
1942 if (atomic_dec_and_test(&dev->num_channels))
Dean Andersond62e85a2010-04-09 19:54:26 -03001943 s2255_destroy(dev);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001944 return;
1945}
1946
Hans Verkuila3998102008-07-21 02:57:38 -03001947static struct video_device template = {
1948 .name = "s2255v",
Hans Verkuila3998102008-07-21 02:57:38 -03001949 .fops = &s2255_fops_v4l,
1950 .ioctl_ops = &s2255_ioctl_ops,
Dean Andersonff7e22d2010-04-08 23:38:07 -03001951 .release = s2255_video_device_release,
Dean Anderson38f993a2008-06-26 23:15:51 -03001952 .tvnorms = S2255_NORMS,
1953 .current_norm = V4L2_STD_NTSC_M,
1954};
1955
1956static int s2255_probe_v4l(struct s2255_dev *dev)
1957{
1958 int ret;
1959 int i;
1960 int cur_nr = video_nr;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001961 struct s2255_channel *channel;
Dean Anderson65c6edb2010-04-20 17:21:32 -03001962 ret = v4l2_device_register(&dev->interface->dev, &dev->v4l2_dev);
1963 if (ret)
1964 return ret;
Dean Anderson38f993a2008-06-26 23:15:51 -03001965 /* initialize all video 4 linux */
Dean Anderson38f993a2008-06-26 23:15:51 -03001966 /* register 4 video devices */
1967 for (i = 0; i < MAX_CHANNELS; i++) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03001968 channel = &dev->channel[i];
1969 INIT_LIST_HEAD(&channel->vidq.active);
1970 channel->vidq.dev = dev;
Dean Anderson38f993a2008-06-26 23:15:51 -03001971 /* register 4 video devices */
Dean Andersonfe85ce92010-06-01 19:12:07 -03001972 channel->vdev = template;
1973 channel->vdev.v4l2_dev = &dev->v4l2_dev;
1974 video_set_drvdata(&channel->vdev, channel);
Dean Anderson38f993a2008-06-26 23:15:51 -03001975 if (video_nr == -1)
Dean Andersonfe85ce92010-06-01 19:12:07 -03001976 ret = video_register_device(&channel->vdev,
Dean Anderson38f993a2008-06-26 23:15:51 -03001977 VFL_TYPE_GRABBER,
1978 video_nr);
1979 else
Dean Andersonfe85ce92010-06-01 19:12:07 -03001980 ret = video_register_device(&channel->vdev,
Dean Anderson38f993a2008-06-26 23:15:51 -03001981 VFL_TYPE_GRABBER,
1982 cur_nr + i);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001983
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03001984 if (ret) {
Dean Anderson38f993a2008-06-26 23:15:51 -03001985 dev_err(&dev->udev->dev,
1986 "failed to register video device!\n");
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03001987 break;
Dean Anderson38f993a2008-06-26 23:15:51 -03001988 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001989 atomic_inc(&dev->num_channels);
Dean Anderson65c6edb2010-04-20 17:21:32 -03001990 v4l2_info(&dev->v4l2_dev, "V4L2 device registered as %s\n",
Dean Andersonfe85ce92010-06-01 19:12:07 -03001991 video_device_node_name(&channel->vdev));
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03001992
Dean Anderson38f993a2008-06-26 23:15:51 -03001993 }
Dean Andersonabce21f2009-04-23 16:04:41 -03001994 printk(KERN_INFO "Sensoray 2255 V4L driver Revision: %d.%d\n",
1995 S2255_MAJOR_VERSION,
1996 S2255_MINOR_VERSION);
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03001997 /* if no channels registered, return error and probe will fail*/
Dean Andersonfe85ce92010-06-01 19:12:07 -03001998 if (atomic_read(&dev->num_channels) == 0) {
Dean Anderson65c6edb2010-04-20 17:21:32 -03001999 v4l2_device_unregister(&dev->v4l2_dev);
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03002000 return ret;
Dean Anderson65c6edb2010-04-20 17:21:32 -03002001 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03002002 if (atomic_read(&dev->num_channels) != MAX_CHANNELS)
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03002003 printk(KERN_WARNING "s2255: Not all channels available.\n");
2004 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03002005}
2006
Dean Anderson38f993a2008-06-26 23:15:51 -03002007/* this function moves the usb stream read pipe data
2008 * into the system buffers.
2009 * returns 0 on success, EAGAIN if more data to process( call this
2010 * function again).
2011 *
2012 * Received frame structure:
Dean Anderson14d96262008-08-25 13:58:55 -03002013 * bytes 0-3: marker : 0x2255DA4AL (S2255_MARKER_FRAME)
Dean Anderson38f993a2008-06-26 23:15:51 -03002014 * bytes 4-7: channel: 0-3
2015 * bytes 8-11: payload size: size of the frame
2016 * bytes 12-payloadsize+12: frame data
2017 */
2018static int save_frame(struct s2255_dev *dev, struct s2255_pipeinfo *pipe_info)
2019{
Dean Anderson38f993a2008-06-26 23:15:51 -03002020 char *pdest;
2021 u32 offset = 0;
Dean Anderson14d96262008-08-25 13:58:55 -03002022 int bframe = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03002023 char *psrc;
2024 unsigned long copy_size;
2025 unsigned long size;
2026 s32 idx = -1;
2027 struct s2255_framei *frm;
2028 unsigned char *pdata;
Dean Andersonfe85ce92010-06-01 19:12:07 -03002029 struct s2255_channel *channel;
Dean Anderson38f993a2008-06-26 23:15:51 -03002030 dprintk(100, "buffer to user\n");
Dean Andersonfe85ce92010-06-01 19:12:07 -03002031 channel = &dev->channel[dev->cc];
2032 idx = channel->cur_frame;
2033 frm = &channel->buffer.frame[idx];
Dean Anderson14d96262008-08-25 13:58:55 -03002034 if (frm->ulState == S2255_READ_IDLE) {
2035 int jj;
2036 unsigned int cc;
Dean Anderson3fa00602010-03-04 20:47:33 -03002037 __le32 *pdword; /*data from dsp is little endian */
Dean Anderson14d96262008-08-25 13:58:55 -03002038 int payload;
2039 /* search for marker codes */
2040 pdata = (unsigned char *)pipe_info->transfer_buffer;
Dean Anderson3fa00602010-03-04 20:47:33 -03002041 pdword = (__le32 *)pdata;
Dean Anderson14d96262008-08-25 13:58:55 -03002042 for (jj = 0; jj < (pipe_info->cur_transfer_size - 12); jj++) {
Dean Anderson3fa00602010-03-04 20:47:33 -03002043 switch (*pdword) {
Dean Anderson14d96262008-08-25 13:58:55 -03002044 case S2255_MARKER_FRAME:
Dean Anderson14d96262008-08-25 13:58:55 -03002045 dprintk(4, "found frame marker at offset:"
2046 " %d [%x %x]\n", jj, pdata[0],
2047 pdata[1]);
2048 offset = jj + PREFIX_SIZE;
2049 bframe = 1;
2050 cc = pdword[1];
2051 if (cc >= MAX_CHANNELS) {
2052 printk(KERN_ERR
2053 "bad channel\n");
2054 return -EINVAL;
2055 }
2056 /* reverse it */
2057 dev->cc = G_chnmap[cc];
Dean Andersonfe85ce92010-06-01 19:12:07 -03002058 channel = &dev->channel[dev->cc];
Dean Anderson14d96262008-08-25 13:58:55 -03002059 payload = pdword[3];
Dean Andersonfe85ce92010-06-01 19:12:07 -03002060 if (payload > channel->req_image_size) {
2061 channel->bad_payload++;
Dean Anderson14d96262008-08-25 13:58:55 -03002062 /* discard the bad frame */
2063 return -EINVAL;
2064 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03002065 channel->pkt_size = payload;
2066 channel->jpg_size = pdword[4];
Dean Anderson14d96262008-08-25 13:58:55 -03002067 break;
2068 case S2255_MARKER_RESPONSE:
Dean Andersonfe85ce92010-06-01 19:12:07 -03002069
Dean Anderson14d96262008-08-25 13:58:55 -03002070 pdata += DEF_USB_BLOCK;
2071 jj += DEF_USB_BLOCK;
2072 if (pdword[1] >= MAX_CHANNELS)
2073 break;
2074 cc = G_chnmap[pdword[1]];
Roel Kluinf14a2972009-10-23 07:59:42 -03002075 if (cc >= MAX_CHANNELS)
Dean Anderson14d96262008-08-25 13:58:55 -03002076 break;
Dean Andersonfe85ce92010-06-01 19:12:07 -03002077 channel = &dev->channel[cc];
Dean Anderson14d96262008-08-25 13:58:55 -03002078 switch (pdword[2]) {
Dean Andersonabce21f2009-04-23 16:04:41 -03002079 case S2255_RESPONSE_SETMODE:
Dean Anderson14d96262008-08-25 13:58:55 -03002080 /* check if channel valid */
2081 /* set mode ready */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002082 channel->setmode_ready = 1;
2083 wake_up(&channel->wait_setmode);
Dean Anderson14d96262008-08-25 13:58:55 -03002084 dprintk(5, "setmode ready %d\n", cc);
2085 break;
Dean Andersonabce21f2009-04-23 16:04:41 -03002086 case S2255_RESPONSE_FW:
Dean Anderson14d96262008-08-25 13:58:55 -03002087 dev->chn_ready |= (1 << cc);
2088 if ((dev->chn_ready & 0x0f) != 0x0f)
2089 break;
2090 /* all channels ready */
2091 printk(KERN_INFO "s2255: fw loaded\n");
2092 atomic_set(&dev->fw_data->fw_state,
2093 S2255_FW_SUCCESS);
2094 wake_up(&dev->fw_data->wait_fw);
2095 break;
Dean Anderson4de39f52010-03-03 19:39:19 -03002096 case S2255_RESPONSE_STATUS:
Dean Andersonfe85ce92010-06-01 19:12:07 -03002097 channel->vidstatus = pdword[3];
2098 channel->vidstatus_ready = 1;
2099 wake_up(&channel->wait_vidstatus);
Dean Anderson4de39f52010-03-03 19:39:19 -03002100 dprintk(5, "got vidstatus %x chan %d\n",
2101 pdword[3], cc);
2102 break;
Dean Anderson14d96262008-08-25 13:58:55 -03002103 default:
André Goddard Rosaaf901ca2009-11-14 13:09:05 -02002104 printk(KERN_INFO "s2255 unknown resp\n");
Dean Anderson14d96262008-08-25 13:58:55 -03002105 }
2106 default:
2107 pdata++;
2108 break;
2109 }
2110 if (bframe)
2111 break;
2112 } /* for */
2113 if (!bframe)
2114 return -EINVAL;
2115 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03002116 channel = &dev->channel[dev->cc];
2117 idx = channel->cur_frame;
2118 frm = &channel->buffer.frame[idx];
Dean Anderson14d96262008-08-25 13:58:55 -03002119 /* search done. now find out if should be acquiring on this channel */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002120 if (!channel->b_acquire) {
Dean Anderson14d96262008-08-25 13:58:55 -03002121 /* we found a frame, but this channel is turned off */
2122 frm->ulState = S2255_READ_IDLE;
2123 return -EINVAL;
2124 }
2125
2126 if (frm->ulState == S2255_READ_IDLE) {
2127 frm->ulState = S2255_READ_FRAME;
Dean Anderson38f993a2008-06-26 23:15:51 -03002128 frm->cur_size = 0;
2129 }
2130
Dean Anderson14d96262008-08-25 13:58:55 -03002131 /* skip the marker 512 bytes (and offset if out of sync) */
2132 psrc = (u8 *)pipe_info->transfer_buffer + offset;
2133
Dean Anderson38f993a2008-06-26 23:15:51 -03002134
2135 if (frm->lpvbits == NULL) {
2136 dprintk(1, "s2255 frame buffer == NULL.%p %p %d %d",
2137 frm, dev, dev->cc, idx);
2138 return -ENOMEM;
2139 }
2140
2141 pdest = frm->lpvbits + frm->cur_size;
2142
Dean Anderson14d96262008-08-25 13:58:55 -03002143 copy_size = (pipe_info->cur_transfer_size - offset);
Dean Anderson38f993a2008-06-26 23:15:51 -03002144
Dean Andersonfe85ce92010-06-01 19:12:07 -03002145 size = channel->pkt_size - PREFIX_SIZE;
Dean Anderson38f993a2008-06-26 23:15:51 -03002146
Dean Anderson14d96262008-08-25 13:58:55 -03002147 /* sanity check on pdest */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002148 if ((copy_size + frm->cur_size) < channel->req_image_size)
Dean Anderson14d96262008-08-25 13:58:55 -03002149 memcpy(pdest, psrc, copy_size);
Dean Anderson38f993a2008-06-26 23:15:51 -03002150
Dean Anderson38f993a2008-06-26 23:15:51 -03002151 frm->cur_size += copy_size;
Dean Anderson14d96262008-08-25 13:58:55 -03002152 dprintk(4, "cur_size size %lu size %lu \n", frm->cur_size, size);
Dean Anderson38f993a2008-06-26 23:15:51 -03002153
Dean Anderson14d96262008-08-25 13:58:55 -03002154 if (frm->cur_size >= size) {
Dean Anderson38f993a2008-06-26 23:15:51 -03002155 dprintk(2, "****************[%d]Buffer[%d]full*************\n",
Dean Andersonfe85ce92010-06-01 19:12:07 -03002156 dev->cc, idx);
2157 channel->last_frame = channel->cur_frame;
2158 channel->cur_frame++;
Dean Anderson38f993a2008-06-26 23:15:51 -03002159 /* end of system frame ring buffer, start at zero */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002160 if ((channel->cur_frame == SYS_FRAMES) ||
2161 (channel->cur_frame == channel->buffer.dwFrames))
2162 channel->cur_frame = 0;
Dean Anderson14d96262008-08-25 13:58:55 -03002163 /* frame ready */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002164 if (channel->b_acquire)
2165 s2255_got_frame(channel, channel->jpg_size);
2166 channel->frame_count++;
Dean Anderson14d96262008-08-25 13:58:55 -03002167 frm->ulState = S2255_READ_IDLE;
2168 frm->cur_size = 0;
2169
Dean Anderson38f993a2008-06-26 23:15:51 -03002170 }
2171 /* done successfully */
2172 return 0;
2173}
2174
2175static void s2255_read_video_callback(struct s2255_dev *dev,
2176 struct s2255_pipeinfo *pipe_info)
2177{
2178 int res;
2179 dprintk(50, "callback read video \n");
2180
2181 if (dev->cc >= MAX_CHANNELS) {
2182 dev->cc = 0;
2183 dev_err(&dev->udev->dev, "invalid channel\n");
2184 return;
2185 }
2186 /* otherwise copy to the system buffers */
2187 res = save_frame(dev, pipe_info);
Dean Anderson14d96262008-08-25 13:58:55 -03002188 if (res != 0)
2189 dprintk(4, "s2255: read callback failed\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03002190
2191 dprintk(50, "callback read video done\n");
2192 return;
2193}
2194
2195static long s2255_vendor_req(struct s2255_dev *dev, unsigned char Request,
2196 u16 Index, u16 Value, void *TransferBuffer,
2197 s32 TransferBufferLength, int bOut)
2198{
2199 int r;
2200 if (!bOut) {
2201 r = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0),
2202 Request,
2203 USB_TYPE_VENDOR | USB_RECIP_DEVICE |
2204 USB_DIR_IN,
2205 Value, Index, TransferBuffer,
2206 TransferBufferLength, HZ * 5);
2207 } else {
2208 r = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0),
2209 Request, USB_TYPE_VENDOR | USB_RECIP_DEVICE,
2210 Value, Index, TransferBuffer,
2211 TransferBufferLength, HZ * 5);
2212 }
2213 return r;
2214}
2215
2216/*
2217 * retrieve FX2 firmware version. future use.
2218 * @param dev pointer to device extension
2219 * @return -1 for fail, else returns firmware version as an int(16 bits)
2220 */
2221static int s2255_get_fx2fw(struct s2255_dev *dev)
2222{
2223 int fw;
2224 int ret;
2225 unsigned char transBuffer[64];
2226 ret = s2255_vendor_req(dev, S2255_VR_FW, 0, 0, transBuffer, 2,
2227 S2255_VR_IN);
2228 if (ret < 0)
2229 dprintk(2, "get fw error: %x\n", ret);
2230 fw = transBuffer[0] + (transBuffer[1] << 8);
2231 dprintk(2, "Get FW %x %x\n", transBuffer[0], transBuffer[1]);
2232 return fw;
2233}
2234
2235/*
2236 * Create the system ring buffer to copy frames into from the
2237 * usb read pipe.
2238 */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002239static int s2255_create_sys_buffers(struct s2255_channel *channel)
Dean Anderson38f993a2008-06-26 23:15:51 -03002240{
2241 unsigned long i;
2242 unsigned long reqsize;
2243 dprintk(1, "create sys buffers\n");
Dean Andersonfe85ce92010-06-01 19:12:07 -03002244 channel->buffer.dwFrames = SYS_FRAMES;
Dean Anderson38f993a2008-06-26 23:15:51 -03002245 /* always allocate maximum size(PAL) for system buffers */
2246 reqsize = SYS_FRAMES_MAXSIZE;
2247
2248 if (reqsize > SYS_FRAMES_MAXSIZE)
2249 reqsize = SYS_FRAMES_MAXSIZE;
2250
2251 for (i = 0; i < SYS_FRAMES; i++) {
2252 /* allocate the frames */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002253 channel->buffer.frame[i].lpvbits = vmalloc(reqsize);
2254 dprintk(1, "valloc %p chan %d, idx %lu, pdata %p\n",
2255 &channel->buffer.frame[i], channel->idx, i,
2256 channel->buffer.frame[i].lpvbits);
2257 channel->buffer.frame[i].size = reqsize;
2258 if (channel->buffer.frame[i].lpvbits == NULL) {
Dean Anderson38f993a2008-06-26 23:15:51 -03002259 printk(KERN_INFO "out of memory. using less frames\n");
Dean Andersonfe85ce92010-06-01 19:12:07 -03002260 channel->buffer.dwFrames = i;
Dean Anderson38f993a2008-06-26 23:15:51 -03002261 break;
2262 }
2263 }
2264
2265 /* make sure internal states are set */
2266 for (i = 0; i < SYS_FRAMES; i++) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03002267 channel->buffer.frame[i].ulState = 0;
2268 channel->buffer.frame[i].cur_size = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03002269 }
2270
Dean Andersonfe85ce92010-06-01 19:12:07 -03002271 channel->cur_frame = 0;
2272 channel->last_frame = -1;
Dean Anderson38f993a2008-06-26 23:15:51 -03002273 return 0;
2274}
2275
Dean Andersonfe85ce92010-06-01 19:12:07 -03002276static int s2255_release_sys_buffers(struct s2255_channel *channel)
Dean Anderson38f993a2008-06-26 23:15:51 -03002277{
2278 unsigned long i;
2279 dprintk(1, "release sys buffers\n");
2280 for (i = 0; i < SYS_FRAMES; i++) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03002281 if (channel->buffer.frame[i].lpvbits) {
Dean Anderson38f993a2008-06-26 23:15:51 -03002282 dprintk(1, "vfree %p\n",
Dean Andersonfe85ce92010-06-01 19:12:07 -03002283 channel->buffer.frame[i].lpvbits);
2284 vfree(channel->buffer.frame[i].lpvbits);
Dean Anderson38f993a2008-06-26 23:15:51 -03002285 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03002286 channel->buffer.frame[i].lpvbits = NULL;
Dean Anderson38f993a2008-06-26 23:15:51 -03002287 }
2288 return 0;
2289}
2290
2291static int s2255_board_init(struct s2255_dev *dev)
2292{
Dean Anderson38f993a2008-06-26 23:15:51 -03002293 struct s2255_mode mode_def = DEF_MODEI_NTSC_CONT;
2294 int fw_ver;
Dean Andersonab85c6a2010-04-08 23:39:12 -03002295 int j;
2296 struct s2255_pipeinfo *pipe = &dev->pipe;
Dean Anderson38f993a2008-06-26 23:15:51 -03002297 dprintk(4, "board init: %p", dev);
Dean Andersonab85c6a2010-04-08 23:39:12 -03002298 memset(pipe, 0, sizeof(*pipe));
2299 pipe->dev = dev;
2300 pipe->cur_transfer_size = S2255_USB_XFER_SIZE;
2301 pipe->max_transfer_size = S2255_USB_XFER_SIZE;
Dean Anderson38f993a2008-06-26 23:15:51 -03002302
Dean Andersonab85c6a2010-04-08 23:39:12 -03002303 pipe->transfer_buffer = kzalloc(pipe->max_transfer_size,
2304 GFP_KERNEL);
2305 if (pipe->transfer_buffer == NULL) {
2306 dprintk(1, "out of memory!\n");
2307 return -ENOMEM;
Dean Anderson38f993a2008-06-26 23:15:51 -03002308 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002309 /* query the firmware */
2310 fw_ver = s2255_get_fx2fw(dev);
2311
Dean Andersonabce21f2009-04-23 16:04:41 -03002312 printk(KERN_INFO "2255 usb firmware version %d.%d\n",
2313 (fw_ver >> 8) & 0xff,
2314 fw_ver & 0xff);
2315
2316 if (fw_ver < S2255_CUR_USB_FWVER)
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002317 dev_err(&dev->udev->dev,
Dean Andersonabce21f2009-04-23 16:04:41 -03002318 "usb firmware not up to date %d.%d\n",
2319 (fw_ver >> 8) & 0xff,
2320 fw_ver & 0xff);
Dean Anderson38f993a2008-06-26 23:15:51 -03002321
2322 for (j = 0; j < MAX_CHANNELS; j++) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03002323 struct s2255_channel *channel = &dev->channel[j];
2324 channel->b_acquire = 0;
2325 channel->mode = mode_def;
Dean Anderson5a34d9d2010-03-05 19:59:48 -03002326 if (dev->pid == 0x2257 && j > 1)
Dean Andersonfe85ce92010-06-01 19:12:07 -03002327 channel->mode.color |= (1 << 16);
2328 channel->jc.quality = S2255_DEF_JPEG_QUAL;
2329 channel->width = LINE_SZ_4CIFS_NTSC;
2330 channel->height = NUM_LINES_4CIFS_NTSC * 2;
2331 channel->fmt = &formats[0];
2332 channel->mode.restart = 1;
2333 channel->req_image_size = get_transfer_size(&mode_def);
2334 channel->frame_count = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03002335 /* create the system buffers */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002336 s2255_create_sys_buffers(channel);
Dean Anderson38f993a2008-06-26 23:15:51 -03002337 }
2338 /* start read pipe */
2339 s2255_start_readpipe(dev);
Dean Anderson85b85482010-04-08 23:51:17 -03002340 dprintk(1, "%s: success\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03002341 return 0;
2342}
2343
2344static int s2255_board_shutdown(struct s2255_dev *dev)
2345{
2346 u32 i;
Dean Anderson85b85482010-04-08 23:51:17 -03002347 dprintk(1, "%s: dev: %p", __func__, dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03002348
2349 for (i = 0; i < MAX_CHANNELS; i++) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03002350 if (dev->channel[i].b_acquire)
2351 s2255_stop_acquire(&dev->channel[i]);
Dean Anderson38f993a2008-06-26 23:15:51 -03002352 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002353 s2255_stop_readpipe(dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03002354 for (i = 0; i < MAX_CHANNELS; i++)
Dean Andersonfe85ce92010-06-01 19:12:07 -03002355 s2255_release_sys_buffers(&dev->channel[i]);
Dean Andersonab85c6a2010-04-08 23:39:12 -03002356 /* release transfer buffer */
2357 kfree(dev->pipe.transfer_buffer);
Dean Anderson38f993a2008-06-26 23:15:51 -03002358 return 0;
2359}
2360
2361static void read_pipe_completion(struct urb *purb)
2362{
2363 struct s2255_pipeinfo *pipe_info;
2364 struct s2255_dev *dev;
2365 int status;
2366 int pipe;
Dean Anderson38f993a2008-06-26 23:15:51 -03002367 pipe_info = purb->context;
Dean Anderson85b85482010-04-08 23:51:17 -03002368 dprintk(100, "%s: urb:%p, status %d\n", __func__, purb,
Dean Anderson38f993a2008-06-26 23:15:51 -03002369 purb->status);
2370 if (pipe_info == NULL) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002371 dev_err(&purb->dev->dev, "no context!\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03002372 return;
2373 }
2374
2375 dev = pipe_info->dev;
2376 if (dev == NULL) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002377 dev_err(&purb->dev->dev, "no context!\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03002378 return;
2379 }
2380 status = purb->status;
Dean Andersonb02064c2009-04-30 12:29:38 -03002381 /* if shutting down, do not resubmit, exit immediately */
2382 if (status == -ESHUTDOWN) {
Dean Anderson85b85482010-04-08 23:51:17 -03002383 dprintk(2, "%s: err shutdown\n", __func__);
Dean Andersonb02064c2009-04-30 12:29:38 -03002384 pipe_info->err_count++;
Dean Anderson38f993a2008-06-26 23:15:51 -03002385 return;
2386 }
2387
2388 if (pipe_info->state == 0) {
Dean Anderson85b85482010-04-08 23:51:17 -03002389 dprintk(2, "%s: exiting USB pipe", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03002390 return;
2391 }
2392
Dean Andersonb02064c2009-04-30 12:29:38 -03002393 if (status == 0)
2394 s2255_read_video_callback(dev, pipe_info);
2395 else {
2396 pipe_info->err_count++;
Dean Anderson85b85482010-04-08 23:51:17 -03002397 dprintk(1, "%s: failed URB %d\n", __func__, status);
Dean Andersonb02064c2009-04-30 12:29:38 -03002398 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002399
Dean Anderson38f993a2008-06-26 23:15:51 -03002400 pipe = usb_rcvbulkpipe(dev->udev, dev->read_endpoint);
2401 /* reuse urb */
2402 usb_fill_bulk_urb(pipe_info->stream_urb, dev->udev,
2403 pipe,
2404 pipe_info->transfer_buffer,
2405 pipe_info->cur_transfer_size,
2406 read_pipe_completion, pipe_info);
2407
2408 if (pipe_info->state != 0) {
2409 if (usb_submit_urb(pipe_info->stream_urb, GFP_KERNEL)) {
2410 dev_err(&dev->udev->dev, "error submitting urb\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03002411 }
2412 } else {
Dean Anderson85b85482010-04-08 23:51:17 -03002413 dprintk(2, "%s :complete state 0\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03002414 }
2415 return;
2416}
2417
2418static int s2255_start_readpipe(struct s2255_dev *dev)
2419{
2420 int pipe;
2421 int retval;
Dean Andersonab85c6a2010-04-08 23:39:12 -03002422 struct s2255_pipeinfo *pipe_info = &dev->pipe;
Dean Anderson38f993a2008-06-26 23:15:51 -03002423 pipe = usb_rcvbulkpipe(dev->udev, dev->read_endpoint);
Dean Anderson85b85482010-04-08 23:51:17 -03002424 dprintk(2, "%s: IN %d\n", __func__, dev->read_endpoint);
Dean Andersonab85c6a2010-04-08 23:39:12 -03002425 pipe_info->state = 1;
2426 pipe_info->err_count = 0;
2427 pipe_info->stream_urb = usb_alloc_urb(0, GFP_KERNEL);
2428 if (!pipe_info->stream_urb) {
2429 dev_err(&dev->udev->dev,
2430 "ReadStream: Unable to alloc URB\n");
2431 return -ENOMEM;
Dean Anderson38f993a2008-06-26 23:15:51 -03002432 }
Dean Andersonab85c6a2010-04-08 23:39:12 -03002433 /* transfer buffer allocated in board_init */
2434 usb_fill_bulk_urb(pipe_info->stream_urb, dev->udev,
2435 pipe,
2436 pipe_info->transfer_buffer,
2437 pipe_info->cur_transfer_size,
2438 read_pipe_completion, pipe_info);
Dean Andersonab85c6a2010-04-08 23:39:12 -03002439 retval = usb_submit_urb(pipe_info->stream_urb, GFP_KERNEL);
2440 if (retval) {
2441 printk(KERN_ERR "s2255: start read pipe failed\n");
2442 return retval;
2443 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002444 return 0;
2445}
2446
2447/* starts acquisition process */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002448static int s2255_start_acquire(struct s2255_channel *channel)
Dean Anderson38f993a2008-06-26 23:15:51 -03002449{
2450 unsigned char *buffer;
2451 int res;
2452 unsigned long chn_rev;
2453 int j;
Dean Andersonfe85ce92010-06-01 19:12:07 -03002454 struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev);
2455 chn_rev = G_chnmap[channel->idx];
Dean Anderson38f993a2008-06-26 23:15:51 -03002456 buffer = kzalloc(512, GFP_KERNEL);
2457 if (buffer == NULL) {
2458 dev_err(&dev->udev->dev, "out of mem\n");
2459 return -ENOMEM;
2460 }
2461
Dean Andersonfe85ce92010-06-01 19:12:07 -03002462 channel->last_frame = -1;
2463 channel->bad_payload = 0;
2464 channel->cur_frame = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03002465 for (j = 0; j < SYS_FRAMES; j++) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03002466 channel->buffer.frame[j].ulState = 0;
2467 channel->buffer.frame[j].cur_size = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03002468 }
2469
2470 /* send the start command */
Dean Anderson3fa00602010-03-04 20:47:33 -03002471 *(__le32 *) buffer = IN_DATA_TOKEN;
2472 *((__le32 *) buffer + 1) = (__le32) cpu_to_le32(chn_rev);
2473 *((__le32 *) buffer + 2) = CMD_START;
Dean Anderson38f993a2008-06-26 23:15:51 -03002474 res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
2475 if (res != 0)
2476 dev_err(&dev->udev->dev, "CMD_START error\n");
2477
Dean Andersonfe85ce92010-06-01 19:12:07 -03002478 dprintk(2, "start acquire exit[%d] %d \n", channel->idx, res);
Dean Anderson38f993a2008-06-26 23:15:51 -03002479 kfree(buffer);
2480 return 0;
2481}
2482
Dean Andersonfe85ce92010-06-01 19:12:07 -03002483static int s2255_stop_acquire(struct s2255_channel *channel)
Dean Anderson38f993a2008-06-26 23:15:51 -03002484{
2485 unsigned char *buffer;
2486 int res;
2487 unsigned long chn_rev;
Dean Andersonfe85ce92010-06-01 19:12:07 -03002488 struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev);
2489 chn_rev = G_chnmap[channel->idx];
Dean Anderson38f993a2008-06-26 23:15:51 -03002490 buffer = kzalloc(512, GFP_KERNEL);
2491 if (buffer == NULL) {
2492 dev_err(&dev->udev->dev, "out of mem\n");
2493 return -ENOMEM;
2494 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002495 /* send the stop command */
Dean Anderson3fa00602010-03-04 20:47:33 -03002496 *(__le32 *) buffer = IN_DATA_TOKEN;
2497 *((__le32 *) buffer + 1) = (__le32) cpu_to_le32(chn_rev);
2498 *((__le32 *) buffer + 2) = CMD_STOP;
Dean Anderson38f993a2008-06-26 23:15:51 -03002499 res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
Dean Anderson38f993a2008-06-26 23:15:51 -03002500 if (res != 0)
2501 dev_err(&dev->udev->dev, "CMD_STOP error\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03002502 kfree(buffer);
Dean Andersonfe85ce92010-06-01 19:12:07 -03002503 channel->b_acquire = 0;
2504 dprintk(4, "%s: chn %d, res %d\n", __func__, channel->idx, res);
Dean Anderson14d96262008-08-25 13:58:55 -03002505 return res;
Dean Anderson38f993a2008-06-26 23:15:51 -03002506}
2507
2508static void s2255_stop_readpipe(struct s2255_dev *dev)
2509{
Dean Andersonab85c6a2010-04-08 23:39:12 -03002510 struct s2255_pipeinfo *pipe = &dev->pipe;
Dan Carpenter8b661b52010-05-05 03:00:47 -03002511
Dean Andersonab85c6a2010-04-08 23:39:12 -03002512 pipe->state = 0;
2513 if (pipe->stream_urb) {
2514 /* cancel urb */
2515 usb_kill_urb(pipe->stream_urb);
2516 usb_free_urb(pipe->stream_urb);
2517 pipe->stream_urb = NULL;
Dean Anderson38f993a2008-06-26 23:15:51 -03002518 }
Dean Andersonab85c6a2010-04-08 23:39:12 -03002519 dprintk(4, "%s", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03002520 return;
2521}
2522
Dean Anderson14d96262008-08-25 13:58:55 -03002523static void s2255_fwload_start(struct s2255_dev *dev, int reset)
Dean Anderson38f993a2008-06-26 23:15:51 -03002524{
Dean Anderson14d96262008-08-25 13:58:55 -03002525 if (reset)
2526 s2255_reset_dsppower(dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03002527 dev->fw_data->fw_size = dev->fw_data->fw->size;
2528 atomic_set(&dev->fw_data->fw_state, S2255_FW_NOTLOADED);
2529 memcpy(dev->fw_data->pfw_data,
2530 dev->fw_data->fw->data, CHUNK_SIZE);
2531 dev->fw_data->fw_loaded = CHUNK_SIZE;
2532 usb_fill_bulk_urb(dev->fw_data->fw_urb, dev->udev,
2533 usb_sndbulkpipe(dev->udev, 2),
2534 dev->fw_data->pfw_data,
2535 CHUNK_SIZE, s2255_fwchunk_complete,
2536 dev->fw_data);
2537 mod_timer(&dev->timer, jiffies + HZ);
2538}
2539
2540/* standard usb probe function */
2541static int s2255_probe(struct usb_interface *interface,
2542 const struct usb_device_id *id)
2543{
2544 struct s2255_dev *dev = NULL;
2545 struct usb_host_interface *iface_desc;
2546 struct usb_endpoint_descriptor *endpoint;
2547 int i;
2548 int retval = -ENOMEM;
Dean Anderson14d96262008-08-25 13:58:55 -03002549 __le32 *pdata;
2550 int fw_size;
Dean Anderson85b85482010-04-08 23:51:17 -03002551 dprintk(2, "%s\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03002552 /* allocate memory for our device state and initialize it to zero */
2553 dev = kzalloc(sizeof(struct s2255_dev), GFP_KERNEL);
2554 if (dev == NULL) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002555 s2255_dev_err(&interface->dev, "out of memory\n");
Dean Andersonff7e22d2010-04-08 23:38:07 -03002556 return -ENOMEM;
Dean Anderson38f993a2008-06-26 23:15:51 -03002557 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03002558 atomic_set(&dev->num_channels, 0);
Dean Anderson5a34d9d2010-03-05 19:59:48 -03002559 dev->pid = id->idProduct;
Dean Anderson38f993a2008-06-26 23:15:51 -03002560 dev->fw_data = kzalloc(sizeof(struct s2255_fw), GFP_KERNEL);
2561 if (!dev->fw_data)
Dean Andersonff7e22d2010-04-08 23:38:07 -03002562 goto errorFWDATA1;
Dean Anderson38f993a2008-06-26 23:15:51 -03002563 mutex_init(&dev->lock);
2564 mutex_init(&dev->open_lock);
Dean Anderson38f993a2008-06-26 23:15:51 -03002565 /* grab usb_device and save it */
2566 dev->udev = usb_get_dev(interface_to_usbdev(interface));
2567 if (dev->udev == NULL) {
2568 dev_err(&interface->dev, "null usb device\n");
2569 retval = -ENODEV;
Dean Andersonff7e22d2010-04-08 23:38:07 -03002570 goto errorUDEV;
Dean Anderson38f993a2008-06-26 23:15:51 -03002571 }
Dean Andersond62e85a2010-04-09 19:54:26 -03002572 dprintk(1, "dev: %p, udev %p interface %p\n", dev,
Dean Anderson38f993a2008-06-26 23:15:51 -03002573 dev->udev, interface);
2574 dev->interface = interface;
2575 /* set up the endpoint information */
2576 iface_desc = interface->cur_altsetting;
2577 dprintk(1, "num endpoints %d\n", iface_desc->desc.bNumEndpoints);
2578 for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
2579 endpoint = &iface_desc->endpoint[i].desc;
2580 if (!dev->read_endpoint && usb_endpoint_is_bulk_in(endpoint)) {
2581 /* we found the bulk in endpoint */
2582 dev->read_endpoint = endpoint->bEndpointAddress;
2583 }
2584 }
2585
2586 if (!dev->read_endpoint) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002587 dev_err(&interface->dev, "Could not find bulk-in endpoint\n");
Dean Andersonff7e22d2010-04-08 23:38:07 -03002588 goto errorEP;
Dean Anderson38f993a2008-06-26 23:15:51 -03002589 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002590 init_timer(&dev->timer);
2591 dev->timer.function = s2255_timer;
2592 dev->timer.data = (unsigned long)dev->fw_data;
Dean Anderson38f993a2008-06-26 23:15:51 -03002593 init_waitqueue_head(&dev->fw_data->wait_fw);
Dean Anderson4de39f52010-03-03 19:39:19 -03002594 for (i = 0; i < MAX_CHANNELS; i++) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03002595 struct s2255_channel *channel = &dev->channel[i];
2596 dev->channel[i].idx = i;
2597 init_waitqueue_head(&channel->wait_setmode);
2598 init_waitqueue_head(&channel->wait_vidstatus);
Dean Anderson4de39f52010-03-03 19:39:19 -03002599 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002600
2601 dev->fw_data->fw_urb = usb_alloc_urb(0, GFP_KERNEL);
Dean Anderson38f993a2008-06-26 23:15:51 -03002602 if (!dev->fw_data->fw_urb) {
2603 dev_err(&interface->dev, "out of memory!\n");
Dean Andersonff7e22d2010-04-08 23:38:07 -03002604 goto errorFWURB;
Dean Anderson38f993a2008-06-26 23:15:51 -03002605 }
Dean Andersonff7e22d2010-04-08 23:38:07 -03002606
Dean Anderson38f993a2008-06-26 23:15:51 -03002607 dev->fw_data->pfw_data = kzalloc(CHUNK_SIZE, GFP_KERNEL);
2608 if (!dev->fw_data->pfw_data) {
2609 dev_err(&interface->dev, "out of memory!\n");
Dean Andersonff7e22d2010-04-08 23:38:07 -03002610 goto errorFWDATA2;
Dean Anderson38f993a2008-06-26 23:15:51 -03002611 }
2612 /* load the first chunk */
2613 if (request_firmware(&dev->fw_data->fw,
2614 FIRMWARE_FILE_NAME, &dev->udev->dev)) {
2615 printk(KERN_ERR "sensoray 2255 failed to get firmware\n");
Dean Andersonff7e22d2010-04-08 23:38:07 -03002616 goto errorREQFW;
Dean Anderson38f993a2008-06-26 23:15:51 -03002617 }
Dean Anderson14d96262008-08-25 13:58:55 -03002618 /* check the firmware is valid */
2619 fw_size = dev->fw_data->fw->size;
2620 pdata = (__le32 *) &dev->fw_data->fw->data[fw_size - 8];
Dean Anderson38f993a2008-06-26 23:15:51 -03002621
Dean Anderson14d96262008-08-25 13:58:55 -03002622 if (*pdata != S2255_FW_MARKER) {
2623 printk(KERN_INFO "Firmware invalid.\n");
2624 retval = -ENODEV;
Dean Andersonff7e22d2010-04-08 23:38:07 -03002625 goto errorFWMARKER;
Dean Anderson14d96262008-08-25 13:58:55 -03002626 } else {
2627 /* make sure firmware is the latest */
2628 __le32 *pRel;
2629 pRel = (__le32 *) &dev->fw_data->fw->data[fw_size - 4];
2630 printk(KERN_INFO "s2255 dsp fw version %x\n", *pRel);
Dean Anderson4de39f52010-03-03 19:39:19 -03002631 dev->dsp_fw_ver = *pRel;
2632 if (*pRel < S2255_CUR_DSP_FWVER)
2633 printk(KERN_INFO "s2255: f2255usb.bin out of date.\n");
Dean Anderson5a34d9d2010-03-05 19:59:48 -03002634 if (dev->pid == 0x2257 && *pRel < S2255_MIN_DSP_COLORFILTER)
Dean Andersonff7e22d2010-04-08 23:38:07 -03002635 printk(KERN_WARNING "s2255: 2257 requires firmware %d"
Dean Andersonfe85ce92010-06-01 19:12:07 -03002636 " or above.\n", S2255_MIN_DSP_COLORFILTER);
Dean Anderson14d96262008-08-25 13:58:55 -03002637 }
Dean Anderson14d96262008-08-25 13:58:55 -03002638 usb_reset_device(dev->udev);
Dean Anderson38f993a2008-06-26 23:15:51 -03002639 /* load 2255 board specific */
Dean Andersonabce21f2009-04-23 16:04:41 -03002640 retval = s2255_board_init(dev);
2641 if (retval)
Dean Andersonff7e22d2010-04-08 23:38:07 -03002642 goto errorBOARDINIT;
Dean Anderson38f993a2008-06-26 23:15:51 -03002643 spin_lock_init(&dev->slock);
Dean Anderson14d96262008-08-25 13:58:55 -03002644 s2255_fwload_start(dev, 0);
Dean Andersonff7e22d2010-04-08 23:38:07 -03002645 /* loads v4l specific */
2646 retval = s2255_probe_v4l(dev);
2647 if (retval)
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03002648 goto errorBOARDINIT;
Dean Anderson38f993a2008-06-26 23:15:51 -03002649 dev_info(&interface->dev, "Sensoray 2255 detected\n");
2650 return 0;
Dean Andersonff7e22d2010-04-08 23:38:07 -03002651errorBOARDINIT:
2652 s2255_board_shutdown(dev);
2653errorFWMARKER:
2654 release_firmware(dev->fw_data->fw);
2655errorREQFW:
2656 kfree(dev->fw_data->pfw_data);
2657errorFWDATA2:
2658 usb_free_urb(dev->fw_data->fw_urb);
2659errorFWURB:
2660 del_timer(&dev->timer);
2661errorEP:
2662 usb_put_dev(dev->udev);
2663errorUDEV:
2664 kfree(dev->fw_data);
2665 mutex_destroy(&dev->open_lock);
2666 mutex_destroy(&dev->lock);
2667errorFWDATA1:
2668 kfree(dev);
2669 printk(KERN_WARNING "Sensoray 2255 driver load failed: 0x%x\n", retval);
Dean Anderson38f993a2008-06-26 23:15:51 -03002670 return retval;
2671}
2672
2673/* disconnect routine. when board is removed physically or with rmmod */
2674static void s2255_disconnect(struct usb_interface *interface)
2675{
Dean Anderson65c6edb2010-04-20 17:21:32 -03002676 struct s2255_dev *dev = to_s2255_dev(usb_get_intfdata(interface));
Dean Anderson14d96262008-08-25 13:58:55 -03002677 int i;
Dean Andersonfe85ce92010-06-01 19:12:07 -03002678 int channels = atomic_read(&dev->num_channels);
2679 v4l2_device_disconnect(&dev->v4l2_dev);
Dean Andersond62e85a2010-04-09 19:54:26 -03002680 /*see comments in the uvc_driver.c usb disconnect function */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002681 atomic_inc(&dev->num_channels);
Dean Andersonff7e22d2010-04-08 23:38:07 -03002682 /* unregister each video device. */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002683 for (i = 0; i < channels; i++)
2684 video_unregister_device(&dev->channel[i].vdev);
Dean Andersonff7e22d2010-04-08 23:38:07 -03002685 /* wake up any of our timers */
Dean Anderson14d96262008-08-25 13:58:55 -03002686 atomic_set(&dev->fw_data->fw_state, S2255_FW_DISCONNECTING);
2687 wake_up(&dev->fw_data->wait_fw);
2688 for (i = 0; i < MAX_CHANNELS; i++) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03002689 dev->channel[i].setmode_ready = 1;
2690 wake_up(&dev->channel[i].wait_setmode);
2691 dev->channel[i].vidstatus_ready = 1;
2692 wake_up(&dev->channel[i].wait_vidstatus);
Dean Anderson14d96262008-08-25 13:58:55 -03002693 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03002694 if (atomic_dec_and_test(&dev->num_channels))
Dean Andersond62e85a2010-04-09 19:54:26 -03002695 s2255_destroy(dev);
Dean Andersonff7e22d2010-04-08 23:38:07 -03002696 dev_info(&interface->dev, "%s\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03002697}
2698
2699static struct usb_driver s2255_driver = {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002700 .name = S2255_DRIVER_NAME,
Dean Anderson38f993a2008-06-26 23:15:51 -03002701 .probe = s2255_probe,
2702 .disconnect = s2255_disconnect,
2703 .id_table = s2255_table,
2704};
2705
2706static int __init usb_s2255_init(void)
2707{
2708 int result;
Dean Anderson38f993a2008-06-26 23:15:51 -03002709 /* register this driver with the USB subsystem */
2710 result = usb_register(&s2255_driver);
Dean Anderson38f993a2008-06-26 23:15:51 -03002711 if (result)
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002712 pr_err(KBUILD_MODNAME
Dean Andersonff7e22d2010-04-08 23:38:07 -03002713 ": usb_register failed. Error number %d\n", result);
2714 dprintk(2, "%s\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03002715 return result;
2716}
2717
2718static void __exit usb_s2255_exit(void)
2719{
2720 usb_deregister(&s2255_driver);
2721}
2722
2723module_init(usb_s2255_init);
2724module_exit(usb_s2255_exit);
2725
2726MODULE_DESCRIPTION("Sensoray 2255 Video for Linux driver");
2727MODULE_AUTHOR("Dean Anderson (Sensoray Company Inc.)");
2728MODULE_LICENSE("GPL");