blob: 2dcb29b647f098b013a49f580eb17243440b4563 [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
Dean Anderson38f993a2008-06-26 23:15:51 -030019 * -full or half size Grey scale: all 4 channels at once
Dean Anderson38f993a2008-06-26 23:15:51 -030020 * -half size, color mode YUYV or YUV422P: all 4 channels at once
Dean Anderson38f993a2008-06-26 23:15:51 -030021 * -full size, color mode YUYV or YUV422P 1/2 frame rate: all 4 channels
22 * at once.
Dean Anderson38f993a2008-06-26 23:15:51 -030023 *
24 * This program is free software; you can redistribute it and/or modify
25 * it under the terms of the GNU General Public License as published by
26 * the Free Software Foundation; either version 2 of the License, or
27 * (at your option) any later version.
28 *
29 * This program is distributed in the hope that it will be useful,
30 * but WITHOUT ANY WARRANTY; without even the implied warranty of
31 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32 * GNU General Public License for more details.
33 *
34 * You should have received a copy of the GNU General Public License
35 * along with this program; if not, write to the Free Software
36 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
37 */
38
39#include <linux/module.h>
40#include <linux/firmware.h>
41#include <linux/kernel.h>
42#include <linux/mutex.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090043#include <linux/slab.h>
Dean Anderson38f993a2008-06-26 23:15:51 -030044#include <linux/videodev2.h>
Hans Verkuilfeb75f02008-07-27 06:30:21 -030045#include <linux/mm.h>
Dean Anderson38f993a2008-06-26 23:15:51 -030046#include <media/videobuf-vmalloc.h>
47#include <media/v4l2-common.h>
Dean Anderson3a67b5cc2010-04-08 23:52:20 -030048#include <media/v4l2-device.h>
Hans Verkuil35ea11f2008-07-20 08:12:02 -030049#include <media/v4l2-ioctl.h>
Hans Verkuil192f1e72013-02-15 05:51:21 -030050#include <media/v4l2-ctrls.h>
Dean Anderson38f993a2008-06-26 23:15:51 -030051#include <linux/vmalloc.h>
52#include <linux/usb.h>
53
Mauro Carvalho Chehab64dc3c12011-06-25 11:28:37 -030054#define S2255_VERSION "1.22.1"
Dean Anderson38f993a2008-06-26 23:15:51 -030055#define FIRMWARE_FILE_NAME "f2255usb.bin"
56
Dean Anderson22b88d42008-08-29 15:33:19 -030057/* default JPEG quality */
58#define S2255_DEF_JPEG_QUAL 50
Dean Anderson38f993a2008-06-26 23:15:51 -030059/* vendor request in */
60#define S2255_VR_IN 0
61/* vendor request out */
62#define S2255_VR_OUT 1
63/* firmware query */
64#define S2255_VR_FW 0x30
65/* USB endpoint number for configuring the device */
66#define S2255_CONFIG_EP 2
67/* maximum time for DSP to start responding after last FW word loaded(ms) */
Dean Anderson14d96262008-08-25 13:58:55 -030068#define S2255_DSP_BOOTTIME 800
Dean Anderson38f993a2008-06-26 23:15:51 -030069/* maximum time to wait for firmware to load (ms) */
Dean Anderson3f8d6f72008-06-30 21:28:34 -030070#define S2255_LOAD_TIMEOUT (5000 + S2255_DSP_BOOTTIME)
Dean Anderson38f993a2008-06-26 23:15:51 -030071#define S2255_DEF_BUFS 16
Dean Anderson14d96262008-08-25 13:58:55 -030072#define S2255_SETMODE_TIMEOUT 500
Dean Anderson4de39f52010-03-03 19:39:19 -030073#define S2255_VIDSTATUS_TIMEOUT 350
Dean Anderson3fa00602010-03-04 20:47:33 -030074#define S2255_MARKER_FRAME cpu_to_le32(0x2255DA4AL)
75#define S2255_MARKER_RESPONSE cpu_to_le32(0x2255ACACL)
76#define S2255_RESPONSE_SETMODE cpu_to_le32(0x01)
77#define S2255_RESPONSE_FW cpu_to_le32(0x10)
78#define S2255_RESPONSE_STATUS cpu_to_le32(0x20)
Dean Anderson14d96262008-08-25 13:58:55 -030079#define S2255_USB_XFER_SIZE (16 * 1024)
Dean Anderson38f993a2008-06-26 23:15:51 -030080#define MAX_CHANNELS 4
Dean Anderson38f993a2008-06-26 23:15:51 -030081#define SYS_FRAMES 4
82/* maximum size is PAL full size plus room for the marker header(s) */
Dean Anderson14d96262008-08-25 13:58:55 -030083#define SYS_FRAMES_MAXSIZE (720*288*2*2 + 4096)
84#define DEF_USB_BLOCK S2255_USB_XFER_SIZE
Dean Anderson38f993a2008-06-26 23:15:51 -030085#define LINE_SZ_4CIFS_NTSC 640
86#define LINE_SZ_2CIFS_NTSC 640
87#define LINE_SZ_1CIFS_NTSC 320
88#define LINE_SZ_4CIFS_PAL 704
89#define LINE_SZ_2CIFS_PAL 704
90#define LINE_SZ_1CIFS_PAL 352
91#define NUM_LINES_4CIFS_NTSC 240
92#define NUM_LINES_2CIFS_NTSC 240
93#define NUM_LINES_1CIFS_NTSC 240
94#define NUM_LINES_4CIFS_PAL 288
95#define NUM_LINES_2CIFS_PAL 288
96#define NUM_LINES_1CIFS_PAL 288
97#define LINE_SZ_DEF 640
98#define NUM_LINES_DEF 240
99
100
101/* predefined settings */
102#define FORMAT_NTSC 1
103#define FORMAT_PAL 2
104
105#define SCALE_4CIFS 1 /* 640x480(NTSC) or 704x576(PAL) */
106#define SCALE_2CIFS 2 /* 640x240(NTSC) or 704x288(PAL) */
107#define SCALE_1CIFS 3 /* 320x240(NTSC) or 352x288(PAL) */
Dean Anderson7d853532009-05-15 14:32:04 -0300108/* SCALE_4CIFSI is the 2 fields interpolated into one */
109#define SCALE_4CIFSI 4 /* 640x480(NTSC) or 704x576(PAL) high quality */
Dean Anderson38f993a2008-06-26 23:15:51 -0300110
111#define COLOR_YUVPL 1 /* YUV planar */
112#define COLOR_YUVPK 2 /* YUV packed */
113#define COLOR_Y8 4 /* monochrome */
Dean Anderson14d96262008-08-25 13:58:55 -0300114#define COLOR_JPG 5 /* JPEG */
Dean Anderson38f993a2008-06-26 23:15:51 -0300115
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300116#define MASK_COLOR 0x000000ff
117#define MASK_JPG_QUALITY 0x0000ff00
118#define MASK_INPUT_TYPE 0x000f0000
Sensoray Linux Development8a8cc952011-04-04 14:08:40 -0300119/* frame decimation. */
Dean Anderson38f993a2008-06-26 23:15:51 -0300120#define FDEC_1 1 /* capture every frame. default */
121#define FDEC_2 2 /* capture every 2nd frame */
122#define FDEC_3 3 /* capture every 3rd frame */
123#define FDEC_5 5 /* capture every 5th frame */
124
125/*-------------------------------------------------------
126 * Default mode parameters.
127 *-------------------------------------------------------*/
128#define DEF_SCALE SCALE_4CIFS
129#define DEF_COLOR COLOR_YUVPL
130#define DEF_FDEC FDEC_1
131#define DEF_BRIGHT 0
132#define DEF_CONTRAST 0x5c
133#define DEF_SATURATION 0x80
134#define DEF_HUE 0
135
136/* usb config commands */
Dean Anderson3fa00602010-03-04 20:47:33 -0300137#define IN_DATA_TOKEN cpu_to_le32(0x2255c0de)
Dan Carpenter3b2a6302012-02-17 02:44:10 -0300138#define CMD_2255 0xc2255000
Dean Anderson3fa00602010-03-04 20:47:33 -0300139#define CMD_SET_MODE cpu_to_le32((CMD_2255 | 0x10))
140#define CMD_START cpu_to_le32((CMD_2255 | 0x20))
141#define CMD_STOP cpu_to_le32((CMD_2255 | 0x30))
142#define CMD_STATUS cpu_to_le32((CMD_2255 | 0x40))
Dean Anderson38f993a2008-06-26 23:15:51 -0300143
144struct s2255_mode {
145 u32 format; /* input video format (NTSC, PAL) */
146 u32 scale; /* output video scale */
147 u32 color; /* output video color format */
148 u32 fdec; /* frame decimation */
149 u32 bright; /* brightness */
150 u32 contrast; /* contrast */
151 u32 saturation; /* saturation */
152 u32 hue; /* hue (NTSC only)*/
153 u32 single; /* capture 1 frame at a time (!=0), continuously (==0)*/
154 u32 usb_block; /* block size. should be 4096 of DEF_USB_BLOCK */
155 u32 restart; /* if DSP requires restart */
156};
157
Dean Anderson14d96262008-08-25 13:58:55 -0300158
159#define S2255_READ_IDLE 0
160#define S2255_READ_FRAME 1
161
Dean Anderson38f993a2008-06-26 23:15:51 -0300162/* frame structure */
Dean Anderson38f993a2008-06-26 23:15:51 -0300163struct s2255_framei {
164 unsigned long size;
Dean Anderson14d96262008-08-25 13:58:55 -0300165 unsigned long ulState; /* ulState:S2255_READ_IDLE, S2255_READ_FRAME*/
Dean Anderson38f993a2008-06-26 23:15:51 -0300166 void *lpvbits; /* image data */
167 unsigned long cur_size; /* current data copied to it */
168};
169
170/* image buffer structure */
171struct s2255_bufferi {
172 unsigned long dwFrames; /* number of frames in buffer */
173 struct s2255_framei frame[SYS_FRAMES]; /* array of FRAME structures */
174};
175
176#define DEF_MODEI_NTSC_CONT {FORMAT_NTSC, DEF_SCALE, DEF_COLOR, \
177 DEF_FDEC, DEF_BRIGHT, DEF_CONTRAST, DEF_SATURATION, \
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300178 DEF_HUE, 0, DEF_USB_BLOCK, 0}
Dean Anderson38f993a2008-06-26 23:15:51 -0300179
180struct s2255_dmaqueue {
181 struct list_head active;
Dean Anderson38f993a2008-06-26 23:15:51 -0300182 struct s2255_dev *dev;
Dean Anderson38f993a2008-06-26 23:15:51 -0300183};
184
185/* for firmware loading, fw_state */
186#define S2255_FW_NOTLOADED 0
187#define S2255_FW_LOADED_DSPWAIT 1
188#define S2255_FW_SUCCESS 2
189#define S2255_FW_FAILED 3
Dean Andersonf78d92c2008-07-22 14:43:27 -0300190#define S2255_FW_DISCONNECTING 4
Harvey Harrisondeaf53e2008-11-15 01:10:14 -0300191#define S2255_FW_MARKER cpu_to_le32(0x22552f2f)
Dean Anderson14d96262008-08-25 13:58:55 -0300192/* 2255 read states */
193#define S2255_READ_IDLE 0
194#define S2255_READ_FRAME 1
Dean Anderson38f993a2008-06-26 23:15:51 -0300195struct s2255_fw {
196 int fw_loaded;
197 int fw_size;
198 struct urb *fw_urb;
199 atomic_t fw_state;
200 void *pfw_data;
201 wait_queue_head_t wait_fw;
Dean Anderson38f993a2008-06-26 23:15:51 -0300202 const struct firmware *fw;
203};
204
205struct s2255_pipeinfo {
206 u32 max_transfer_size;
207 u32 cur_transfer_size;
208 u8 *transfer_buffer;
Dean Anderson38f993a2008-06-26 23:15:51 -0300209 u32 state;
Dean Anderson38f993a2008-06-26 23:15:51 -0300210 void *stream_urb;
211 void *dev; /* back pointer to s2255_dev struct*/
212 u32 err_count;
Dean Anderson38f993a2008-06-26 23:15:51 -0300213 u32 idx;
Dean Anderson38f993a2008-06-26 23:15:51 -0300214};
215
216struct s2255_fmt; /*forward declaration */
Dean Andersonfe85ce92010-06-01 19:12:07 -0300217struct s2255_dev;
218
219struct s2255_channel {
220 struct video_device vdev;
Hans Verkuil192f1e72013-02-15 05:51:21 -0300221 struct v4l2_ctrl_handler hdl;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300222 int resources;
223 struct s2255_dmaqueue vidq;
224 struct s2255_bufferi buffer;
225 struct s2255_mode mode;
226 /* jpeg compression */
227 struct v4l2_jpegcompression jc;
228 /* capture parameters (for high quality mode full size) */
229 struct v4l2_captureparm cap_parm;
230 int cur_frame;
231 int last_frame;
232
233 int b_acquire;
234 /* allocated image size */
235 unsigned long req_image_size;
236 /* received packet size */
237 unsigned long pkt_size;
238 int bad_payload;
239 unsigned long frame_count;
240 /* if JPEG image */
241 int jpg_size;
242 /* if channel configured to default state */
243 int configured;
244 wait_queue_head_t wait_setmode;
245 int setmode_ready;
246 /* video status items */
247 int vidstatus;
248 wait_queue_head_t wait_vidstatus;
249 int vidstatus_ready;
250 unsigned int width;
251 unsigned int height;
252 const struct s2255_fmt *fmt;
253 int idx; /* channel number on device, 0-3 */
254};
255
Dean Anderson38f993a2008-06-26 23:15:51 -0300256
257struct s2255_dev {
Dean Andersonfe85ce92010-06-01 19:12:07 -0300258 struct s2255_channel channel[MAX_CHANNELS];
Dean Anderson65c6edb2010-04-20 17:21:32 -0300259 struct v4l2_device v4l2_dev;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300260 atomic_t num_channels;
Dean Anderson38f993a2008-06-26 23:15:51 -0300261 int frames;
Pete Eberleina19a5cd2010-12-20 19:18:59 -0300262 struct mutex lock; /* channels[].vdev.lock */
Dean Anderson38f993a2008-06-26 23:15:51 -0300263 struct usb_device *udev;
264 struct usb_interface *interface;
265 u8 read_endpoint;
Dean Anderson38f993a2008-06-26 23:15:51 -0300266 struct timer_list timer;
267 struct s2255_fw *fw_data;
Dean Andersonab85c6a2010-04-08 23:39:12 -0300268 struct s2255_pipeinfo pipe;
Dean Anderson38f993a2008-06-26 23:15:51 -0300269 u32 cc; /* current channel */
Dean Anderson38f993a2008-06-26 23:15:51 -0300270 int frame_ready;
Dean Anderson14d96262008-08-25 13:58:55 -0300271 int chn_ready;
Dean Anderson38f993a2008-06-26 23:15:51 -0300272 spinlock_t slock;
Dean Anderson4de39f52010-03-03 19:39:19 -0300273 /* dsp firmware version (f2255usb.bin) */
274 int dsp_fw_ver;
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300275 u16 pid; /* product id */
Dean Anderson38f993a2008-06-26 23:15:51 -0300276};
Dean Anderson65c6edb2010-04-20 17:21:32 -0300277
Dean Anderson65c6edb2010-04-20 17:21:32 -0300278static inline struct s2255_dev *to_s2255_dev(struct v4l2_device *v4l2_dev)
279{
280 return container_of(v4l2_dev, struct s2255_dev, v4l2_dev);
281}
Dean Anderson38f993a2008-06-26 23:15:51 -0300282
283struct s2255_fmt {
284 char *name;
285 u32 fourcc;
286 int depth;
287};
288
289/* buffer for one video frame */
290struct s2255_buffer {
291 /* common v4l buffer stuff -- must be first */
292 struct videobuf_buffer vb;
293 const struct s2255_fmt *fmt;
294};
295
296struct s2255_fh {
297 struct s2255_dev *dev;
Dean Anderson38f993a2008-06-26 23:15:51 -0300298 struct videobuf_queue vb_vidq;
299 enum v4l2_buf_type type;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300300 struct s2255_channel *channel;
301 int resources;
Dean Anderson38f993a2008-06-26 23:15:51 -0300302};
303
Dean Andersonabce21f2009-04-23 16:04:41 -0300304/* current cypress EEPROM firmware version */
Sensoray Linux Development8a8cc952011-04-04 14:08:40 -0300305#define S2255_CUR_USB_FWVER ((3 << 8) | 12)
Dean Anderson4de39f52010-03-03 19:39:19 -0300306/* current DSP FW version */
Sensoray Linux Development8a8cc952011-04-04 14:08:40 -0300307#define S2255_CUR_DSP_FWVER 10104
Dean Anderson4de39f52010-03-03 19:39:19 -0300308/* Need DSP version 5+ for video status feature */
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300309#define S2255_MIN_DSP_STATUS 5
310#define S2255_MIN_DSP_COLORFILTER 8
Dean Anderson38f993a2008-06-26 23:15:51 -0300311#define S2255_NORMS (V4L2_STD_PAL | V4L2_STD_NTSC)
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300312
313/* private V4L2 controls */
314
315/*
316 * The following chart displays how COLORFILTER should be set
317 * =========================================================
318 * = fourcc = COLORFILTER =
319 * = ===============================
320 * = = 0 = 1 =
321 * =========================================================
322 * = V4L2_PIX_FMT_GREY(Y8) = monochrome from = monochrome=
323 * = = s-video or = composite =
324 * = = B/W camera = input =
325 * =========================================================
326 * = other = color, svideo = color, =
327 * = = = composite =
328 * =========================================================
329 *
330 * Notes:
331 * channels 0-3 on 2255 are composite
332 * channels 0-1 on 2257 are composite, 2-3 are s-video
333 * If COLORFILTER is 0 with a composite color camera connected,
334 * the output will appear monochrome but hatching
335 * will occur.
336 * COLORFILTER is different from "color killer" and "color effects"
337 * for reasons above.
338 */
339#define S2255_V4L2_YC_ON 1
340#define S2255_V4L2_YC_OFF 0
Hans Verkuil192f1e72013-02-15 05:51:21 -0300341#define V4L2_CID_S2255_COLORFILTER (V4L2_CID_USER_S2255_BASE + 0)
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300342
Dean Anderson38f993a2008-06-26 23:15:51 -0300343/* frame prefix size (sent once every frame) */
344#define PREFIX_SIZE 512
345
346/* Channels on box are in reverse order */
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300347static unsigned long G_chnmap[MAX_CHANNELS] = {3, 2, 1, 0};
Dean Anderson38f993a2008-06-26 23:15:51 -0300348
Dean Anderson38f993a2008-06-26 23:15:51 -0300349static int debug;
350static int *s2255_debug = &debug;
351
352static int s2255_start_readpipe(struct s2255_dev *dev);
353static void s2255_stop_readpipe(struct s2255_dev *dev);
Dean Andersonfe85ce92010-06-01 19:12:07 -0300354static int s2255_start_acquire(struct s2255_channel *channel);
355static int s2255_stop_acquire(struct s2255_channel *channel);
356static void s2255_fillbuff(struct s2255_channel *chn, struct s2255_buffer *buf,
357 int jpgsize);
358static int s2255_set_mode(struct s2255_channel *chan, struct s2255_mode *mode);
Dean Anderson38f993a2008-06-26 23:15:51 -0300359static int s2255_board_shutdown(struct s2255_dev *dev);
Dean Anderson14d96262008-08-25 13:58:55 -0300360static void s2255_fwload_start(struct s2255_dev *dev, int reset);
Dean Andersond62e85a2010-04-09 19:54:26 -0300361static void s2255_destroy(struct s2255_dev *dev);
Dean Anderson14d96262008-08-25 13:58:55 -0300362static long s2255_vendor_req(struct s2255_dev *dev, unsigned char req,
363 u16 index, u16 value, void *buf,
364 s32 buf_len, int bOut);
Dean Anderson38f993a2008-06-26 23:15:51 -0300365
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -0300366/* dev_err macro with driver name */
367#define S2255_DRIVER_NAME "s2255"
368#define s2255_dev_err(dev, fmt, arg...) \
369 dev_err(dev, S2255_DRIVER_NAME " - " fmt, ##arg)
370
Dean Anderson38f993a2008-06-26 23:15:51 -0300371#define dprintk(level, fmt, arg...) \
372 do { \
373 if (*s2255_debug >= (level)) { \
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -0300374 printk(KERN_DEBUG S2255_DRIVER_NAME \
375 ": " fmt, ##arg); \
Dean Anderson38f993a2008-06-26 23:15:51 -0300376 } \
377 } while (0)
378
Dean Anderson38f993a2008-06-26 23:15:51 -0300379static struct usb_driver s2255_driver;
380
Dean Anderson38f993a2008-06-26 23:15:51 -0300381/* Declare static vars that will be used as parameters */
382static unsigned int vid_limit = 16; /* Video memory limit, in Mb */
383
384/* start video number */
385static int video_nr = -1; /* /dev/videoN, -1 for autodetect */
386
Sensoray Linux Developmente42e28f2011-04-04 15:23:03 -0300387/* Enable jpeg capture. */
388static int jpeg_enable = 1;
389
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300390module_param(debug, int, 0644);
Dean Anderson38f993a2008-06-26 23:15:51 -0300391MODULE_PARM_DESC(debug, "Debug level(0-100) default 0");
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300392module_param(vid_limit, int, 0644);
Dean Anderson38f993a2008-06-26 23:15:51 -0300393MODULE_PARM_DESC(vid_limit, "video memory limit(Mb)");
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300394module_param(video_nr, int, 0644);
Dean Anderson38f993a2008-06-26 23:15:51 -0300395MODULE_PARM_DESC(video_nr, "start video minor(-1 default autodetect)");
Sensoray Linux Developmente42e28f2011-04-04 15:23:03 -0300396module_param(jpeg_enable, int, 0644);
397MODULE_PARM_DESC(jpeg_enable, "Jpeg enable(1-on 0-off) default 1");
Dean Anderson38f993a2008-06-26 23:15:51 -0300398
399/* USB device table */
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300400#define USB_SENSORAY_VID 0x1943
Dean Anderson38f993a2008-06-26 23:15:51 -0300401static struct usb_device_id s2255_table[] = {
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300402 {USB_DEVICE(USB_SENSORAY_VID, 0x2255)},
403 {USB_DEVICE(USB_SENSORAY_VID, 0x2257)}, /*same family as 2255*/
Dean Anderson38f993a2008-06-26 23:15:51 -0300404 { } /* Terminating entry */
405};
406MODULE_DEVICE_TABLE(usb, s2255_table);
407
Dean Anderson38f993a2008-06-26 23:15:51 -0300408#define BUFFER_TIMEOUT msecs_to_jiffies(400)
409
Dean Anderson38f993a2008-06-26 23:15:51 -0300410/* image formats. */
Sensoray Linux Developmente42e28f2011-04-04 15:23:03 -0300411/* JPEG formats must be defined last to support jpeg_enable parameter */
Dean Anderson38f993a2008-06-26 23:15:51 -0300412static const struct s2255_fmt formats[] = {
413 {
414 .name = "4:2:2, planar, YUV422P",
415 .fourcc = V4L2_PIX_FMT_YUV422P,
416 .depth = 16
417
418 }, {
419 .name = "4:2:2, packed, YUYV",
420 .fourcc = V4L2_PIX_FMT_YUYV,
421 .depth = 16
422
423 }, {
424 .name = "4:2:2, packed, UYVY",
425 .fourcc = V4L2_PIX_FMT_UYVY,
426 .depth = 16
427 }, {
Sensoray Linux Developmente42e28f2011-04-04 15:23:03 -0300428 .name = "8bpp GREY",
429 .fourcc = V4L2_PIX_FMT_GREY,
430 .depth = 8
431 }, {
Dean Anderson14d96262008-08-25 13:58:55 -0300432 .name = "JPG",
433 .fourcc = V4L2_PIX_FMT_JPEG,
434 .depth = 24
435 }, {
Sensoray Linux Developmentd0ef8542011-04-04 15:16:26 -0300436 .name = "MJPG",
437 .fourcc = V4L2_PIX_FMT_MJPEG,
438 .depth = 24
Dean Anderson38f993a2008-06-26 23:15:51 -0300439 }
440};
441
442static int norm_maxw(struct video_device *vdev)
443{
444 return (vdev->current_norm & V4L2_STD_NTSC) ?
445 LINE_SZ_4CIFS_NTSC : LINE_SZ_4CIFS_PAL;
446}
447
448static int norm_maxh(struct video_device *vdev)
449{
450 return (vdev->current_norm & V4L2_STD_NTSC) ?
451 (NUM_LINES_1CIFS_NTSC * 2) : (NUM_LINES_1CIFS_PAL * 2);
452}
453
454static int norm_minw(struct video_device *vdev)
455{
456 return (vdev->current_norm & V4L2_STD_NTSC) ?
457 LINE_SZ_1CIFS_NTSC : LINE_SZ_1CIFS_PAL;
458}
459
460static int norm_minh(struct video_device *vdev)
461{
462 return (vdev->current_norm & V4L2_STD_NTSC) ?
463 (NUM_LINES_1CIFS_NTSC) : (NUM_LINES_1CIFS_PAL);
464}
465
466
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300467/*
468 * TODO: fixme: move YUV reordering to hardware
469 * converts 2255 planar format to yuyv or uyvy
470 */
Dean Anderson38f993a2008-06-26 23:15:51 -0300471static void planar422p_to_yuv_packed(const unsigned char *in,
472 unsigned char *out,
473 int width, int height,
474 int fmt)
475{
476 unsigned char *pY;
477 unsigned char *pCb;
478 unsigned char *pCr;
479 unsigned long size = height * width;
480 unsigned int i;
481 pY = (unsigned char *)in;
482 pCr = (unsigned char *)in + height * width;
483 pCb = (unsigned char *)in + height * width + (height * width / 2);
484 for (i = 0; i < size * 2; i += 4) {
485 out[i] = (fmt == V4L2_PIX_FMT_YUYV) ? *pY++ : *pCr++;
486 out[i + 1] = (fmt == V4L2_PIX_FMT_YUYV) ? *pCr++ : *pY++;
487 out[i + 2] = (fmt == V4L2_PIX_FMT_YUYV) ? *pY++ : *pCb++;
488 out[i + 3] = (fmt == V4L2_PIX_FMT_YUYV) ? *pCb++ : *pY++;
489 }
490 return;
491}
492
Hans Verkuild45b9b82008-09-04 03:33:43 -0300493static void s2255_reset_dsppower(struct s2255_dev *dev)
Dean Anderson14d96262008-08-25 13:58:55 -0300494{
Sensoray Linux Development8a8cc952011-04-04 14:08:40 -0300495 s2255_vendor_req(dev, 0x40, 0x0000, 0x0001, NULL, 0, 1);
Dean Anderson14d96262008-08-25 13:58:55 -0300496 msleep(10);
497 s2255_vendor_req(dev, 0x50, 0x0000, 0x0000, NULL, 0, 1);
sensoray-dev752eb7a2011-01-19 17:41:45 -0300498 msleep(600);
499 s2255_vendor_req(dev, 0x10, 0x0000, 0x0000, NULL, 0, 1);
Dean Anderson14d96262008-08-25 13:58:55 -0300500 return;
501}
Dean Anderson38f993a2008-06-26 23:15:51 -0300502
503/* kickstarts the firmware loading. from probe
504 */
505static void s2255_timer(unsigned long user_data)
506{
507 struct s2255_fw *data = (struct s2255_fw *)user_data;
Dean Anderson85b85482010-04-08 23:51:17 -0300508 dprintk(100, "%s\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -0300509 if (usb_submit_urb(data->fw_urb, GFP_ATOMIC) < 0) {
510 printk(KERN_ERR "s2255: can't submit urb\n");
Dean Andersonf78d92c2008-07-22 14:43:27 -0300511 atomic_set(&data->fw_state, S2255_FW_FAILED);
512 /* wake up anything waiting for the firmware */
513 wake_up(&data->wait_fw);
Dean Anderson38f993a2008-06-26 23:15:51 -0300514 return;
515 }
516}
517
Dean Anderson38f993a2008-06-26 23:15:51 -0300518
519/* this loads the firmware asynchronously.
520 Originally this was done synchroously in probe.
521 But it is better to load it asynchronously here than block
522 inside the probe function. Blocking inside probe affects boot time.
523 FW loading is triggered by the timer in the probe function
524*/
525static void s2255_fwchunk_complete(struct urb *urb)
526{
527 struct s2255_fw *data = urb->context;
528 struct usb_device *udev = urb->dev;
529 int len;
Dean Anderson85b85482010-04-08 23:51:17 -0300530 dprintk(100, "%s: udev %p urb %p", __func__, udev, urb);
Dean Anderson38f993a2008-06-26 23:15:51 -0300531 if (urb->status) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -0300532 dev_err(&udev->dev, "URB failed with status %d\n", urb->status);
Dean Andersonf78d92c2008-07-22 14:43:27 -0300533 atomic_set(&data->fw_state, S2255_FW_FAILED);
534 /* wake up anything waiting for the firmware */
535 wake_up(&data->wait_fw);
Dean Anderson38f993a2008-06-26 23:15:51 -0300536 return;
537 }
538 if (data->fw_urb == NULL) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -0300539 s2255_dev_err(&udev->dev, "disconnected\n");
Dean Andersonf78d92c2008-07-22 14:43:27 -0300540 atomic_set(&data->fw_state, S2255_FW_FAILED);
541 /* wake up anything waiting for the firmware */
542 wake_up(&data->wait_fw);
Dean Anderson38f993a2008-06-26 23:15:51 -0300543 return;
544 }
545#define CHUNK_SIZE 512
546 /* all USB transfers must be done with continuous kernel memory.
547 can't allocate more than 128k in current linux kernel, so
548 upload the firmware in chunks
549 */
550 if (data->fw_loaded < data->fw_size) {
551 len = (data->fw_loaded + CHUNK_SIZE) > data->fw_size ?
552 data->fw_size % CHUNK_SIZE : CHUNK_SIZE;
553
554 if (len < CHUNK_SIZE)
555 memset(data->pfw_data, 0, CHUNK_SIZE);
556
557 dprintk(100, "completed len %d, loaded %d \n", len,
558 data->fw_loaded);
559
560 memcpy(data->pfw_data,
561 (char *) data->fw->data + data->fw_loaded, len);
562
563 usb_fill_bulk_urb(data->fw_urb, udev, usb_sndbulkpipe(udev, 2),
564 data->pfw_data, CHUNK_SIZE,
565 s2255_fwchunk_complete, data);
566 if (usb_submit_urb(data->fw_urb, GFP_ATOMIC) < 0) {
567 dev_err(&udev->dev, "failed submit URB\n");
568 atomic_set(&data->fw_state, S2255_FW_FAILED);
569 /* wake up anything waiting for the firmware */
570 wake_up(&data->wait_fw);
571 return;
572 }
573 data->fw_loaded += len;
574 } else {
Dean Anderson38f993a2008-06-26 23:15:51 -0300575 atomic_set(&data->fw_state, S2255_FW_LOADED_DSPWAIT);
Dean Anderson85b85482010-04-08 23:51:17 -0300576 dprintk(100, "%s: firmware upload complete\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -0300577 }
Dean Anderson38f993a2008-06-26 23:15:51 -0300578 return;
579
580}
581
Dean Andersonfe85ce92010-06-01 19:12:07 -0300582static int s2255_got_frame(struct s2255_channel *channel, int jpgsize)
Dean Anderson38f993a2008-06-26 23:15:51 -0300583{
Dean Andersonfe85ce92010-06-01 19:12:07 -0300584 struct s2255_dmaqueue *dma_q = &channel->vidq;
Dean Anderson38f993a2008-06-26 23:15:51 -0300585 struct s2255_buffer *buf;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300586 struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev);
Dean Anderson38f993a2008-06-26 23:15:51 -0300587 unsigned long flags = 0;
588 int rc = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -0300589 spin_lock_irqsave(&dev->slock, flags);
Dean Anderson38f993a2008-06-26 23:15:51 -0300590 if (list_empty(&dma_q->active)) {
591 dprintk(1, "No active queue to serve\n");
592 rc = -1;
593 goto unlock;
594 }
595 buf = list_entry(dma_q->active.next,
596 struct s2255_buffer, vb.queue);
Dean Anderson38f993a2008-06-26 23:15:51 -0300597 list_del(&buf->vb.queue);
Sakari Ailus8e6057b2012-09-15 15:14:42 -0300598 v4l2_get_timestamp(&buf->vb.ts);
Dean Andersonfe85ce92010-06-01 19:12:07 -0300599 s2255_fillbuff(channel, buf, jpgsize);
Dean Anderson38f993a2008-06-26 23:15:51 -0300600 wake_up(&buf->vb.done);
Dean Anderson85b85482010-04-08 23:51:17 -0300601 dprintk(2, "%s: [buf/i] [%p/%d]\n", __func__, buf, buf->vb.i);
Dean Anderson38f993a2008-06-26 23:15:51 -0300602unlock:
603 spin_unlock_irqrestore(&dev->slock, flags);
Julia Lawallf2770972010-08-16 13:26:13 -0300604 return rc;
Dean Anderson38f993a2008-06-26 23:15:51 -0300605}
606
Dean Anderson38f993a2008-06-26 23:15:51 -0300607static const struct s2255_fmt *format_by_fourcc(int fourcc)
608{
609 unsigned int i;
Dean Anderson38f993a2008-06-26 23:15:51 -0300610 for (i = 0; i < ARRAY_SIZE(formats); i++) {
611 if (-1 == formats[i].fourcc)
612 continue;
Sensoray Linux Developmente42e28f2011-04-04 15:23:03 -0300613 if (!jpeg_enable && ((formats[i].fourcc == V4L2_PIX_FMT_JPEG) ||
614 (formats[i].fourcc == V4L2_PIX_FMT_MJPEG)))
615 continue;
Dean Anderson38f993a2008-06-26 23:15:51 -0300616 if (formats[i].fourcc == fourcc)
617 return formats + i;
618 }
619 return NULL;
620}
621
Dean Anderson38f993a2008-06-26 23:15:51 -0300622/* video buffer vmalloc implementation based partly on VIVI driver which is
623 * Copyright (c) 2006 by
624 * Mauro Carvalho Chehab <mchehab--a.t--infradead.org>
625 * Ted Walther <ted--a.t--enumera.com>
626 * John Sokol <sokol--a.t--videotechnology.com>
627 * http://v4l.videotechnology.com/
628 *
629 */
Dean Andersonfe85ce92010-06-01 19:12:07 -0300630static void s2255_fillbuff(struct s2255_channel *channel,
631 struct s2255_buffer *buf, int jpgsize)
Dean Anderson38f993a2008-06-26 23:15:51 -0300632{
633 int pos = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -0300634 const char *tmpbuf;
635 char *vbuf = videobuf_to_vmalloc(&buf->vb);
636 unsigned long last_frame;
Dean Anderson38f993a2008-06-26 23:15:51 -0300637
638 if (!vbuf)
639 return;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300640 last_frame = channel->last_frame;
Dean Anderson38f993a2008-06-26 23:15:51 -0300641 if (last_frame != -1) {
Dean Anderson38f993a2008-06-26 23:15:51 -0300642 tmpbuf =
Dean Andersonfe85ce92010-06-01 19:12:07 -0300643 (const char *)channel->buffer.frame[last_frame].lpvbits;
Dean Anderson38f993a2008-06-26 23:15:51 -0300644 switch (buf->fmt->fourcc) {
645 case V4L2_PIX_FMT_YUYV:
646 case V4L2_PIX_FMT_UYVY:
647 planar422p_to_yuv_packed((const unsigned char *)tmpbuf,
648 vbuf, buf->vb.width,
649 buf->vb.height,
650 buf->fmt->fourcc);
651 break;
652 case V4L2_PIX_FMT_GREY:
653 memcpy(vbuf, tmpbuf, buf->vb.width * buf->vb.height);
654 break;
Dean Anderson14d96262008-08-25 13:58:55 -0300655 case V4L2_PIX_FMT_JPEG:
Sensoray Linux Developmentd0ef8542011-04-04 15:16:26 -0300656 case V4L2_PIX_FMT_MJPEG:
Dean Anderson14d96262008-08-25 13:58:55 -0300657 buf->vb.size = jpgsize;
658 memcpy(vbuf, tmpbuf, buf->vb.size);
659 break;
Dean Anderson38f993a2008-06-26 23:15:51 -0300660 case V4L2_PIX_FMT_YUV422P:
661 memcpy(vbuf, tmpbuf,
662 buf->vb.width * buf->vb.height * 2);
663 break;
664 default:
665 printk(KERN_DEBUG "s2255: unknown format?\n");
666 }
Dean Andersonfe85ce92010-06-01 19:12:07 -0300667 channel->last_frame = -1;
Dean Anderson38f993a2008-06-26 23:15:51 -0300668 } else {
669 printk(KERN_ERR "s2255: =======no frame\n");
670 return;
671
672 }
673 dprintk(2, "s2255fill at : Buffer 0x%08lx size= %d\n",
674 (unsigned long)vbuf, pos);
675 /* tell v4l buffer was filled */
676
Dean Andersonfe85ce92010-06-01 19:12:07 -0300677 buf->vb.field_count = channel->frame_count * 2;
Sakari Ailus8e6057b2012-09-15 15:14:42 -0300678 v4l2_get_timestamp(&buf->vb.ts);
Dean Anderson38f993a2008-06-26 23:15:51 -0300679 buf->vb.state = VIDEOBUF_DONE;
680}
681
682
683/* ------------------------------------------------------------------
684 Videobuf operations
685 ------------------------------------------------------------------*/
686
687static int buffer_setup(struct videobuf_queue *vq, unsigned int *count,
688 unsigned int *size)
689{
690 struct s2255_fh *fh = vq->priv_data;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300691 struct s2255_channel *channel = fh->channel;
692 *size = channel->width * channel->height * (channel->fmt->depth >> 3);
Dean Anderson38f993a2008-06-26 23:15:51 -0300693
694 if (0 == *count)
695 *count = S2255_DEF_BUFS;
696
Andreas Bombedab7e312010-03-21 16:02:45 -0300697 if (*size * *count > vid_limit * 1024 * 1024)
698 *count = (vid_limit * 1024 * 1024) / *size;
Dean Anderson38f993a2008-06-26 23:15:51 -0300699
700 return 0;
701}
702
703static void free_buffer(struct videobuf_queue *vq, struct s2255_buffer *buf)
704{
705 dprintk(4, "%s\n", __func__);
706
Dean Anderson38f993a2008-06-26 23:15:51 -0300707 videobuf_vmalloc_free(&buf->vb);
708 buf->vb.state = VIDEOBUF_NEEDS_INIT;
709}
710
711static int buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb,
712 enum v4l2_field field)
713{
714 struct s2255_fh *fh = vq->priv_data;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300715 struct s2255_channel *channel = fh->channel;
Dean Anderson38f993a2008-06-26 23:15:51 -0300716 struct s2255_buffer *buf = container_of(vb, struct s2255_buffer, vb);
717 int rc;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300718 int w = channel->width;
719 int h = channel->height;
Dean Anderson38f993a2008-06-26 23:15:51 -0300720 dprintk(4, "%s, field=%d\n", __func__, field);
Dean Andersonfe85ce92010-06-01 19:12:07 -0300721 if (channel->fmt == NULL)
Dean Anderson38f993a2008-06-26 23:15:51 -0300722 return -EINVAL;
723
Dean Andersonfe85ce92010-06-01 19:12:07 -0300724 if ((w < norm_minw(&channel->vdev)) ||
725 (w > norm_maxw(&channel->vdev)) ||
726 (h < norm_minh(&channel->vdev)) ||
727 (h > norm_maxh(&channel->vdev))) {
Dean Anderson38f993a2008-06-26 23:15:51 -0300728 dprintk(4, "invalid buffer prepare\n");
729 return -EINVAL;
730 }
Dean Andersonfe85ce92010-06-01 19:12:07 -0300731 buf->vb.size = w * h * (channel->fmt->depth >> 3);
Dean Anderson38f993a2008-06-26 23:15:51 -0300732 if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size) {
733 dprintk(4, "invalid buffer prepare\n");
734 return -EINVAL;
735 }
736
Dean Andersonfe85ce92010-06-01 19:12:07 -0300737 buf->fmt = channel->fmt;
738 buf->vb.width = w;
739 buf->vb.height = h;
Dean Anderson38f993a2008-06-26 23:15:51 -0300740 buf->vb.field = field;
741
Dean Anderson38f993a2008-06-26 23:15:51 -0300742 if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
743 rc = videobuf_iolock(vq, &buf->vb, NULL);
744 if (rc < 0)
745 goto fail;
746 }
747
748 buf->vb.state = VIDEOBUF_PREPARED;
749 return 0;
750fail:
751 free_buffer(vq, buf);
752 return rc;
753}
754
755static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
756{
757 struct s2255_buffer *buf = container_of(vb, struct s2255_buffer, vb);
758 struct s2255_fh *fh = vq->priv_data;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300759 struct s2255_channel *channel = fh->channel;
760 struct s2255_dmaqueue *vidq = &channel->vidq;
Dean Anderson38f993a2008-06-26 23:15:51 -0300761 dprintk(1, "%s\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -0300762 buf->vb.state = VIDEOBUF_QUEUED;
763 list_add_tail(&buf->vb.queue, &vidq->active);
764}
765
766static void buffer_release(struct videobuf_queue *vq,
767 struct videobuf_buffer *vb)
768{
769 struct s2255_buffer *buf = container_of(vb, struct s2255_buffer, vb);
770 struct s2255_fh *fh = vq->priv_data;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300771 dprintk(4, "%s %d\n", __func__, fh->channel->idx);
Dean Anderson38f993a2008-06-26 23:15:51 -0300772 free_buffer(vq, buf);
773}
774
775static struct videobuf_queue_ops s2255_video_qops = {
776 .buf_setup = buffer_setup,
777 .buf_prepare = buffer_prepare,
778 .buf_queue = buffer_queue,
779 .buf_release = buffer_release,
780};
781
782
Dean Andersonfe85ce92010-06-01 19:12:07 -0300783static int res_get(struct s2255_fh *fh)
Dean Anderson38f993a2008-06-26 23:15:51 -0300784{
Dean Andersonfe85ce92010-06-01 19:12:07 -0300785 struct s2255_channel *channel = fh->channel;
Pete Eberleina19a5cd2010-12-20 19:18:59 -0300786 /* is it free? */
787 if (channel->resources)
788 return 0; /* no, someone else uses it */
Dean Anderson38f993a2008-06-26 23:15:51 -0300789 /* it's free, grab it */
Dean Andersonfe85ce92010-06-01 19:12:07 -0300790 channel->resources = 1;
791 fh->resources = 1;
Dean Andersonf78d92c2008-07-22 14:43:27 -0300792 dprintk(1, "s2255: res: get\n");
Dean Anderson38f993a2008-06-26 23:15:51 -0300793 return 1;
794}
795
Dean Andersonfe85ce92010-06-01 19:12:07 -0300796static int res_locked(struct s2255_fh *fh)
Dean Anderson38f993a2008-06-26 23:15:51 -0300797{
Dean Andersonfe85ce92010-06-01 19:12:07 -0300798 return fh->channel->resources;
Dean Anderson38f993a2008-06-26 23:15:51 -0300799}
800
Dean Andersonf78d92c2008-07-22 14:43:27 -0300801static int res_check(struct s2255_fh *fh)
802{
Dean Andersonfe85ce92010-06-01 19:12:07 -0300803 return fh->resources;
Dean Andersonf78d92c2008-07-22 14:43:27 -0300804}
805
806
Dean Andersonfe85ce92010-06-01 19:12:07 -0300807static void res_free(struct s2255_fh *fh)
Dean Anderson38f993a2008-06-26 23:15:51 -0300808{
Dean Andersonfe85ce92010-06-01 19:12:07 -0300809 struct s2255_channel *channel = fh->channel;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300810 channel->resources = 0;
811 fh->resources = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -0300812 dprintk(1, "res: put\n");
813}
814
Dean Anderson38f993a2008-06-26 23:15:51 -0300815static int vidioc_querycap(struct file *file, void *priv,
816 struct v4l2_capability *cap)
817{
818 struct s2255_fh *fh = file->private_data;
819 struct s2255_dev *dev = fh->dev;
820 strlcpy(cap->driver, "s2255", sizeof(cap->driver));
821 strlcpy(cap->card, "s2255", sizeof(cap->card));
Thierry MERLEe22ed882009-01-20 18:19:25 -0300822 usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info));
Dean Anderson38f993a2008-06-26 23:15:51 -0300823 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
824 return 0;
825}
826
827static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
828 struct v4l2_fmtdesc *f)
829{
Dan Carpenter6c61ac632012-02-17 02:43:27 -0300830 int index = f->index;
Dean Anderson38f993a2008-06-26 23:15:51 -0300831
832 if (index >= ARRAY_SIZE(formats))
833 return -EINVAL;
Dan Carpenter6c61ac632012-02-17 02:43:27 -0300834 if (!jpeg_enable && ((formats[index].fourcc == V4L2_PIX_FMT_JPEG) ||
835 (formats[index].fourcc == V4L2_PIX_FMT_MJPEG)))
836 return -EINVAL;
Dean Anderson38f993a2008-06-26 23:15:51 -0300837 dprintk(4, "name %s\n", formats[index].name);
838 strlcpy(f->description, formats[index].name, sizeof(f->description));
839 f->pixelformat = formats[index].fourcc;
840 return 0;
841}
842
843static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
844 struct v4l2_format *f)
845{
846 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300847 struct s2255_channel *channel = fh->channel;
Dean Anderson38f993a2008-06-26 23:15:51 -0300848
Dean Andersonfe85ce92010-06-01 19:12:07 -0300849 f->fmt.pix.width = channel->width;
850 f->fmt.pix.height = channel->height;
Dean Anderson38f993a2008-06-26 23:15:51 -0300851 f->fmt.pix.field = fh->vb_vidq.field;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300852 f->fmt.pix.pixelformat = channel->fmt->fourcc;
853 f->fmt.pix.bytesperline = f->fmt.pix.width * (channel->fmt->depth >> 3);
Dean Anderson38f993a2008-06-26 23:15:51 -0300854 f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300855 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -0300856}
857
858static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
859 struct v4l2_format *f)
860{
861 const struct s2255_fmt *fmt;
862 enum v4l2_field field;
863 int b_any_field = 0;
864 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300865 struct s2255_channel *channel = fh->channel;
Dean Anderson38f993a2008-06-26 23:15:51 -0300866 int is_ntsc;
Dean Anderson38f993a2008-06-26 23:15:51 -0300867 is_ntsc =
Dean Andersonfe85ce92010-06-01 19:12:07 -0300868 (channel->vdev.current_norm & V4L2_STD_NTSC) ? 1 : 0;
Dean Anderson38f993a2008-06-26 23:15:51 -0300869
870 fmt = format_by_fourcc(f->fmt.pix.pixelformat);
871
872 if (fmt == NULL)
873 return -EINVAL;
874
875 field = f->fmt.pix.field;
876 if (field == V4L2_FIELD_ANY)
877 b_any_field = 1;
878
Dean Anderson85b85482010-04-08 23:51:17 -0300879 dprintk(50, "%s NTSC: %d suggested width: %d, height: %d\n",
880 __func__, is_ntsc, f->fmt.pix.width, f->fmt.pix.height);
Dean Anderson38f993a2008-06-26 23:15:51 -0300881 if (is_ntsc) {
882 /* NTSC */
883 if (f->fmt.pix.height >= NUM_LINES_1CIFS_NTSC * 2) {
884 f->fmt.pix.height = NUM_LINES_1CIFS_NTSC * 2;
885 if (b_any_field) {
886 field = V4L2_FIELD_SEQ_TB;
887 } else if (!((field == V4L2_FIELD_INTERLACED) ||
888 (field == V4L2_FIELD_SEQ_TB) ||
889 (field == V4L2_FIELD_INTERLACED_TB))) {
890 dprintk(1, "unsupported field setting\n");
891 return -EINVAL;
892 }
893 } else {
894 f->fmt.pix.height = NUM_LINES_1CIFS_NTSC;
895 if (b_any_field) {
896 field = V4L2_FIELD_TOP;
897 } else if (!((field == V4L2_FIELD_TOP) ||
898 (field == V4L2_FIELD_BOTTOM))) {
899 dprintk(1, "unsupported field setting\n");
900 return -EINVAL;
901 }
902
903 }
904 if (f->fmt.pix.width >= LINE_SZ_4CIFS_NTSC)
905 f->fmt.pix.width = LINE_SZ_4CIFS_NTSC;
906 else if (f->fmt.pix.width >= LINE_SZ_2CIFS_NTSC)
907 f->fmt.pix.width = LINE_SZ_2CIFS_NTSC;
908 else if (f->fmt.pix.width >= LINE_SZ_1CIFS_NTSC)
909 f->fmt.pix.width = LINE_SZ_1CIFS_NTSC;
910 else
911 f->fmt.pix.width = LINE_SZ_1CIFS_NTSC;
912 } else {
913 /* PAL */
914 if (f->fmt.pix.height >= NUM_LINES_1CIFS_PAL * 2) {
915 f->fmt.pix.height = NUM_LINES_1CIFS_PAL * 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_PAL;
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 if (f->fmt.pix.width >= LINE_SZ_4CIFS_PAL) {
Dean Anderson38f993a2008-06-26 23:15:51 -0300935 f->fmt.pix.width = LINE_SZ_4CIFS_PAL;
936 field = V4L2_FIELD_SEQ_TB;
937 } else if (f->fmt.pix.width >= LINE_SZ_2CIFS_PAL) {
Dean Anderson38f993a2008-06-26 23:15:51 -0300938 f->fmt.pix.width = LINE_SZ_2CIFS_PAL;
939 field = V4L2_FIELD_TOP;
940 } else if (f->fmt.pix.width >= LINE_SZ_1CIFS_PAL) {
Dean Anderson38f993a2008-06-26 23:15:51 -0300941 f->fmt.pix.width = LINE_SZ_1CIFS_PAL;
942 field = V4L2_FIELD_TOP;
943 } else {
Dean Anderson38f993a2008-06-26 23:15:51 -0300944 f->fmt.pix.width = LINE_SZ_1CIFS_PAL;
945 field = V4L2_FIELD_TOP;
946 }
947 }
Dean Anderson38f993a2008-06-26 23:15:51 -0300948 f->fmt.pix.field = field;
949 f->fmt.pix.bytesperline = (f->fmt.pix.width * fmt->depth) >> 3;
950 f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
Dean Anderson85b85482010-04-08 23:51:17 -0300951 dprintk(50, "%s: set width %d height %d field %d\n", __func__,
952 f->fmt.pix.width, f->fmt.pix.height, f->fmt.pix.field);
Dean Anderson38f993a2008-06-26 23:15:51 -0300953 return 0;
954}
955
956static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
957 struct v4l2_format *f)
958{
959 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300960 struct s2255_channel *channel = fh->channel;
Dean Anderson38f993a2008-06-26 23:15:51 -0300961 const struct s2255_fmt *fmt;
962 struct videobuf_queue *q = &fh->vb_vidq;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300963 struct s2255_mode mode;
Dean Anderson38f993a2008-06-26 23:15:51 -0300964 int ret;
Dean Anderson38f993a2008-06-26 23:15:51 -0300965
966 ret = vidioc_try_fmt_vid_cap(file, fh, f);
967
968 if (ret < 0)
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300969 return ret;
Dean Anderson38f993a2008-06-26 23:15:51 -0300970
971 fmt = format_by_fourcc(f->fmt.pix.pixelformat);
972
973 if (fmt == NULL)
974 return -EINVAL;
975
976 mutex_lock(&q->vb_lock);
977
978 if (videobuf_queue_is_busy(&fh->vb_vidq)) {
979 dprintk(1, "queue busy\n");
980 ret = -EBUSY;
981 goto out_s_fmt;
982 }
983
Dean Andersonfe85ce92010-06-01 19:12:07 -0300984 if (res_locked(fh)) {
Dean Anderson85b85482010-04-08 23:51:17 -0300985 dprintk(1, "%s: channel busy\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -0300986 ret = -EBUSY;
987 goto out_s_fmt;
988 }
Dean Andersonfe85ce92010-06-01 19:12:07 -0300989 mode = channel->mode;
990 channel->fmt = fmt;
991 channel->width = f->fmt.pix.width;
992 channel->height = f->fmt.pix.height;
Dean Anderson38f993a2008-06-26 23:15:51 -0300993 fh->vb_vidq.field = f->fmt.pix.field;
994 fh->type = f->type;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300995 if (channel->width > norm_minw(&channel->vdev)) {
996 if (channel->height > norm_minh(&channel->vdev)) {
997 if (channel->cap_parm.capturemode &
Dean Anderson85b85482010-04-08 23:51:17 -0300998 V4L2_MODE_HIGHQUALITY)
Dean Andersonfe85ce92010-06-01 19:12:07 -0300999 mode.scale = SCALE_4CIFSI;
Dean Anderson85b85482010-04-08 23:51:17 -03001000 else
Dean Andersonfe85ce92010-06-01 19:12:07 -03001001 mode.scale = SCALE_4CIFS;
Dean Anderson7d853532009-05-15 14:32:04 -03001002 } else
Dean Andersonfe85ce92010-06-01 19:12:07 -03001003 mode.scale = SCALE_2CIFS;
Dean Anderson38f993a2008-06-26 23:15:51 -03001004
1005 } else {
Dean Andersonfe85ce92010-06-01 19:12:07 -03001006 mode.scale = SCALE_1CIFS;
Dean Anderson38f993a2008-06-26 23:15:51 -03001007 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001008 /* color mode */
Dean Andersonfe85ce92010-06-01 19:12:07 -03001009 switch (channel->fmt->fourcc) {
Dean Anderson38f993a2008-06-26 23:15:51 -03001010 case V4L2_PIX_FMT_GREY:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001011 mode.color &= ~MASK_COLOR;
1012 mode.color |= COLOR_Y8;
Dean Anderson38f993a2008-06-26 23:15:51 -03001013 break;
Dean Anderson14d96262008-08-25 13:58:55 -03001014 case V4L2_PIX_FMT_JPEG:
Sensoray Linux Developmentd0ef8542011-04-04 15:16:26 -03001015 case V4L2_PIX_FMT_MJPEG:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001016 mode.color &= ~MASK_COLOR;
1017 mode.color |= COLOR_JPG;
1018 mode.color |= (channel->jc.quality << 8);
Dean Anderson14d96262008-08-25 13:58:55 -03001019 break;
Dean Anderson38f993a2008-06-26 23:15:51 -03001020 case V4L2_PIX_FMT_YUV422P:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001021 mode.color &= ~MASK_COLOR;
1022 mode.color |= COLOR_YUVPL;
Dean Anderson38f993a2008-06-26 23:15:51 -03001023 break;
1024 case V4L2_PIX_FMT_YUYV:
1025 case V4L2_PIX_FMT_UYVY:
1026 default:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001027 mode.color &= ~MASK_COLOR;
1028 mode.color |= COLOR_YUVPK;
Dean Anderson38f993a2008-06-26 23:15:51 -03001029 break;
1030 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001031 if ((mode.color & MASK_COLOR) != (channel->mode.color & MASK_COLOR))
1032 mode.restart = 1;
1033 else if (mode.scale != channel->mode.scale)
1034 mode.restart = 1;
1035 else if (mode.format != channel->mode.format)
1036 mode.restart = 1;
1037 channel->mode = mode;
1038 (void) s2255_set_mode(channel, &mode);
Dean Anderson38f993a2008-06-26 23:15:51 -03001039 ret = 0;
1040out_s_fmt:
1041 mutex_unlock(&q->vb_lock);
1042 return ret;
1043}
1044
1045static int vidioc_reqbufs(struct file *file, void *priv,
1046 struct v4l2_requestbuffers *p)
1047{
1048 int rc;
1049 struct s2255_fh *fh = priv;
1050 rc = videobuf_reqbufs(&fh->vb_vidq, p);
1051 return rc;
1052}
1053
1054static int vidioc_querybuf(struct file *file, void *priv, struct v4l2_buffer *p)
1055{
1056 int rc;
1057 struct s2255_fh *fh = priv;
1058 rc = videobuf_querybuf(&fh->vb_vidq, p);
1059 return rc;
1060}
1061
1062static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *p)
1063{
1064 int rc;
1065 struct s2255_fh *fh = priv;
1066 rc = videobuf_qbuf(&fh->vb_vidq, p);
1067 return rc;
1068}
1069
1070static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
1071{
1072 int rc;
1073 struct s2255_fh *fh = priv;
1074 rc = videobuf_dqbuf(&fh->vb_vidq, p, file->f_flags & O_NONBLOCK);
1075 return rc;
1076}
1077
Dean Anderson38f993a2008-06-26 23:15:51 -03001078/* write to the configuration pipe, synchronously */
1079static int s2255_write_config(struct usb_device *udev, unsigned char *pbuf,
1080 int size)
1081{
1082 int pipe;
1083 int done;
1084 long retval = -1;
1085 if (udev) {
1086 pipe = usb_sndbulkpipe(udev, S2255_CONFIG_EP);
1087 retval = usb_bulk_msg(udev, pipe, pbuf, size, &done, 500);
1088 }
1089 return retval;
1090}
1091
1092static u32 get_transfer_size(struct s2255_mode *mode)
1093{
1094 int linesPerFrame = LINE_SZ_DEF;
1095 int pixelsPerLine = NUM_LINES_DEF;
1096 u32 outImageSize;
1097 u32 usbInSize;
1098 unsigned int mask_mult;
1099
1100 if (mode == NULL)
1101 return 0;
1102
1103 if (mode->format == FORMAT_NTSC) {
1104 switch (mode->scale) {
1105 case SCALE_4CIFS:
Dean Anderson7d853532009-05-15 14:32:04 -03001106 case SCALE_4CIFSI:
Dean Anderson38f993a2008-06-26 23:15:51 -03001107 linesPerFrame = NUM_LINES_4CIFS_NTSC * 2;
1108 pixelsPerLine = LINE_SZ_4CIFS_NTSC;
1109 break;
1110 case SCALE_2CIFS:
1111 linesPerFrame = NUM_LINES_2CIFS_NTSC;
1112 pixelsPerLine = LINE_SZ_2CIFS_NTSC;
1113 break;
1114 case SCALE_1CIFS:
1115 linesPerFrame = NUM_LINES_1CIFS_NTSC;
1116 pixelsPerLine = LINE_SZ_1CIFS_NTSC;
1117 break;
1118 default:
1119 break;
1120 }
1121 } else if (mode->format == FORMAT_PAL) {
1122 switch (mode->scale) {
1123 case SCALE_4CIFS:
Dean Anderson7d853532009-05-15 14:32:04 -03001124 case SCALE_4CIFSI:
Dean Anderson38f993a2008-06-26 23:15:51 -03001125 linesPerFrame = NUM_LINES_4CIFS_PAL * 2;
1126 pixelsPerLine = LINE_SZ_4CIFS_PAL;
1127 break;
1128 case SCALE_2CIFS:
1129 linesPerFrame = NUM_LINES_2CIFS_PAL;
1130 pixelsPerLine = LINE_SZ_2CIFS_PAL;
1131 break;
1132 case SCALE_1CIFS:
1133 linesPerFrame = NUM_LINES_1CIFS_PAL;
1134 pixelsPerLine = LINE_SZ_1CIFS_PAL;
1135 break;
1136 default:
1137 break;
1138 }
1139 }
1140 outImageSize = linesPerFrame * pixelsPerLine;
Dean Anderson14d96262008-08-25 13:58:55 -03001141 if ((mode->color & MASK_COLOR) != COLOR_Y8) {
Dean Anderson38f993a2008-06-26 23:15:51 -03001142 /* 2 bytes/pixel if not monochrome */
1143 outImageSize *= 2;
1144 }
1145
1146 /* total bytes to send including prefix and 4K padding;
1147 must be a multiple of USB_READ_SIZE */
1148 usbInSize = outImageSize + PREFIX_SIZE; /* always send prefix */
1149 mask_mult = 0xffffffffUL - DEF_USB_BLOCK + 1;
1150 /* if size not a multiple of USB_READ_SIZE */
1151 if (usbInSize & ~mask_mult)
1152 usbInSize = (usbInSize & mask_mult) + (DEF_USB_BLOCK);
1153 return usbInSize;
1154}
1155
Dean Anderson85b85482010-04-08 23:51:17 -03001156static void s2255_print_cfg(struct s2255_dev *sdev, struct s2255_mode *mode)
Dean Anderson38f993a2008-06-26 23:15:51 -03001157{
1158 struct device *dev = &sdev->udev->dev;
1159 dev_info(dev, "------------------------------------------------\n");
Dean Anderson85b85482010-04-08 23:51:17 -03001160 dev_info(dev, "format: %d\nscale %d\n", mode->format, mode->scale);
1161 dev_info(dev, "fdec: %d\ncolor %d\n", mode->fdec, mode->color);
Dean Anderson38f993a2008-06-26 23:15:51 -03001162 dev_info(dev, "bright: 0x%x\n", mode->bright);
Dean Anderson38f993a2008-06-26 23:15:51 -03001163 dev_info(dev, "------------------------------------------------\n");
1164}
1165
1166/*
1167 * set mode is the function which controls the DSP.
1168 * the restart parameter in struct s2255_mode should be set whenever
1169 * the image size could change via color format, video system or image
1170 * size.
1171 * When the restart parameter is set, we sleep for ONE frame to allow the
1172 * DSP time to get the new frame
1173 */
Dean Andersonfe85ce92010-06-01 19:12:07 -03001174static int s2255_set_mode(struct s2255_channel *channel,
Dean Anderson38f993a2008-06-26 23:15:51 -03001175 struct s2255_mode *mode)
1176{
1177 int res;
Dean Anderson3fa00602010-03-04 20:47:33 -03001178 __le32 *buffer;
Dean Anderson38f993a2008-06-26 23:15:51 -03001179 unsigned long chn_rev;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001180 struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001181 chn_rev = G_chnmap[channel->idx];
1182 dprintk(3, "%s channel: %d\n", __func__, channel->idx);
Dean Anderson22b88d42008-08-29 15:33:19 -03001183 /* if JPEG, set the quality */
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001184 if ((mode->color & MASK_COLOR) == COLOR_JPG) {
1185 mode->color &= ~MASK_COLOR;
1186 mode->color |= COLOR_JPG;
1187 mode->color &= ~MASK_JPG_QUALITY;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001188 mode->color |= (channel->jc.quality << 8);
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001189 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001190 /* save the mode */
Dean Andersonfe85ce92010-06-01 19:12:07 -03001191 channel->mode = *mode;
1192 channel->req_image_size = get_transfer_size(mode);
1193 dprintk(1, "%s: reqsize %ld\n", __func__, channel->req_image_size);
Dean Anderson38f993a2008-06-26 23:15:51 -03001194 buffer = kzalloc(512, GFP_KERNEL);
1195 if (buffer == NULL) {
1196 dev_err(&dev->udev->dev, "out of mem\n");
1197 return -ENOMEM;
1198 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001199 /* set the mode */
1200 buffer[0] = IN_DATA_TOKEN;
Dean Anderson3fa00602010-03-04 20:47:33 -03001201 buffer[1] = (__le32) cpu_to_le32(chn_rev);
Dean Anderson38f993a2008-06-26 23:15:51 -03001202 buffer[2] = CMD_SET_MODE;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001203 memcpy(&buffer[3], &channel->mode, sizeof(struct s2255_mode));
1204 channel->setmode_ready = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001205 res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
1206 if (debug)
Dean Anderson85b85482010-04-08 23:51:17 -03001207 s2255_print_cfg(dev, mode);
Dean Anderson38f993a2008-06-26 23:15:51 -03001208 kfree(buffer);
Dean Anderson38f993a2008-06-26 23:15:51 -03001209 /* wait at least 3 frames before continuing */
Dean Anderson14d96262008-08-25 13:58:55 -03001210 if (mode->restart) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03001211 wait_event_timeout(channel->wait_setmode,
1212 (channel->setmode_ready != 0),
Dean Anderson14d96262008-08-25 13:58:55 -03001213 msecs_to_jiffies(S2255_SETMODE_TIMEOUT));
Dean Andersonfe85ce92010-06-01 19:12:07 -03001214 if (channel->setmode_ready != 1) {
Dean Anderson14d96262008-08-25 13:58:55 -03001215 printk(KERN_DEBUG "s2255: no set mode response\n");
1216 res = -EFAULT;
1217 }
1218 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001219 /* clear the restart flag */
Dean Andersonfe85ce92010-06-01 19:12:07 -03001220 channel->mode.restart = 0;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001221 dprintk(1, "%s chn %d, result: %d\n", __func__, channel->idx, res);
Dean Anderson38f993a2008-06-26 23:15:51 -03001222 return res;
1223}
1224
Dean Andersonfe85ce92010-06-01 19:12:07 -03001225static int s2255_cmd_status(struct s2255_channel *channel, u32 *pstatus)
Dean Anderson4de39f52010-03-03 19:39:19 -03001226{
1227 int res;
Dean Anderson3fa00602010-03-04 20:47:33 -03001228 __le32 *buffer;
Dean Anderson4de39f52010-03-03 19:39:19 -03001229 u32 chn_rev;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001230 struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001231 chn_rev = G_chnmap[channel->idx];
1232 dprintk(4, "%s chan %d\n", __func__, channel->idx);
Dean Anderson4de39f52010-03-03 19:39:19 -03001233 buffer = kzalloc(512, GFP_KERNEL);
1234 if (buffer == NULL) {
1235 dev_err(&dev->udev->dev, "out of mem\n");
Dean Anderson4de39f52010-03-03 19:39:19 -03001236 return -ENOMEM;
1237 }
1238 /* form the get vid status command */
1239 buffer[0] = IN_DATA_TOKEN;
Dean Anderson3fa00602010-03-04 20:47:33 -03001240 buffer[1] = (__le32) cpu_to_le32(chn_rev);
Dean Anderson4de39f52010-03-03 19:39:19 -03001241 buffer[2] = CMD_STATUS;
1242 *pstatus = 0;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001243 channel->vidstatus_ready = 0;
Dean Anderson4de39f52010-03-03 19:39:19 -03001244 res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
1245 kfree(buffer);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001246 wait_event_timeout(channel->wait_vidstatus,
1247 (channel->vidstatus_ready != 0),
Dean Anderson4de39f52010-03-03 19:39:19 -03001248 msecs_to_jiffies(S2255_VIDSTATUS_TIMEOUT));
Dean Andersonfe85ce92010-06-01 19:12:07 -03001249 if (channel->vidstatus_ready != 1) {
Dean Anderson4de39f52010-03-03 19:39:19 -03001250 printk(KERN_DEBUG "s2255: no vidstatus response\n");
1251 res = -EFAULT;
1252 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001253 *pstatus = channel->vidstatus;
Dean Anderson4de39f52010-03-03 19:39:19 -03001254 dprintk(4, "%s, vid status %d\n", __func__, *pstatus);
Dean Anderson4de39f52010-03-03 19:39:19 -03001255 return res;
1256}
1257
Dean Anderson38f993a2008-06-26 23:15:51 -03001258static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
1259{
1260 int res;
1261 struct s2255_fh *fh = priv;
1262 struct s2255_dev *dev = fh->dev;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001263 struct s2255_channel *channel = fh->channel;
Dean Anderson38f993a2008-06-26 23:15:51 -03001264 int j;
1265 dprintk(4, "%s\n", __func__);
1266 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1267 dev_err(&dev->udev->dev, "invalid fh type0\n");
1268 return -EINVAL;
1269 }
1270 if (i != fh->type) {
1271 dev_err(&dev->udev->dev, "invalid fh type1\n");
1272 return -EINVAL;
1273 }
1274
Dean Andersonfe85ce92010-06-01 19:12:07 -03001275 if (!res_get(fh)) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03001276 s2255_dev_err(&dev->udev->dev, "stream busy\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03001277 return -EBUSY;
1278 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001279 channel->last_frame = -1;
1280 channel->bad_payload = 0;
1281 channel->cur_frame = 0;
1282 channel->frame_count = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001283 for (j = 0; j < SYS_FRAMES; j++) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03001284 channel->buffer.frame[j].ulState = S2255_READ_IDLE;
1285 channel->buffer.frame[j].cur_size = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001286 }
1287 res = videobuf_streamon(&fh->vb_vidq);
1288 if (res == 0) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03001289 s2255_start_acquire(channel);
1290 channel->b_acquire = 1;
1291 } else
1292 res_free(fh);
1293
Dean Anderson38f993a2008-06-26 23:15:51 -03001294 return res;
1295}
1296
1297static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
1298{
Dean Anderson38f993a2008-06-26 23:15:51 -03001299 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001300 dprintk(4, "%s\n, channel: %d", __func__, fh->channel->idx);
Dean Anderson38f993a2008-06-26 23:15:51 -03001301 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1302 printk(KERN_ERR "invalid fh type0\n");
1303 return -EINVAL;
1304 }
1305 if (i != fh->type) {
1306 printk(KERN_ERR "invalid type i\n");
1307 return -EINVAL;
1308 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001309 s2255_stop_acquire(fh->channel);
Dean Andersonb7732a32009-03-30 11:59:56 -03001310 videobuf_streamoff(&fh->vb_vidq);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001311 res_free(fh);
Dean Andersonf78d92c2008-07-22 14:43:27 -03001312 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001313}
1314
1315static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *i)
1316{
1317 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001318 struct s2255_mode mode;
Dean Anderson38f993a2008-06-26 23:15:51 -03001319 struct videobuf_queue *q = &fh->vb_vidq;
1320 int ret = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001321 mutex_lock(&q->vb_lock);
1322 if (videobuf_queue_is_busy(q)) {
1323 dprintk(1, "queue busy\n");
1324 ret = -EBUSY;
1325 goto out_s_std;
1326 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001327 if (res_locked(fh)) {
Dean Anderson38f993a2008-06-26 23:15:51 -03001328 dprintk(1, "can't change standard after started\n");
1329 ret = -EBUSY;
1330 goto out_s_std;
1331 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001332 mode = fh->channel->mode;
Dean Anderson38f993a2008-06-26 23:15:51 -03001333 if (*i & V4L2_STD_NTSC) {
Dean Andersone6b44bc2010-03-08 20:04:48 -03001334 dprintk(4, "%s NTSC\n", __func__);
1335 /* if changing format, reset frame decimation/intervals */
Dean Andersonfe85ce92010-06-01 19:12:07 -03001336 if (mode.format != FORMAT_NTSC) {
1337 mode.restart = 1;
1338 mode.format = FORMAT_NTSC;
1339 mode.fdec = FDEC_1;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001340 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001341 } else if (*i & V4L2_STD_PAL) {
Dean Andersone6b44bc2010-03-08 20:04:48 -03001342 dprintk(4, "%s PAL\n", __func__);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001343 if (mode.format != FORMAT_PAL) {
1344 mode.restart = 1;
1345 mode.format = FORMAT_PAL;
1346 mode.fdec = FDEC_1;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001347 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001348 } else {
1349 ret = -EINVAL;
1350 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001351 if (mode.restart)
1352 s2255_set_mode(fh->channel, &mode);
Dean Anderson38f993a2008-06-26 23:15:51 -03001353out_s_std:
1354 mutex_unlock(&q->vb_lock);
1355 return ret;
1356}
1357
1358/* Sensoray 2255 is a multiple channel capture device.
1359 It does not have a "crossbar" of inputs.
1360 We use one V4L device per channel. The user must
1361 be aware that certain combinations are not allowed.
1362 For instance, you cannot do full FPS on more than 2 channels(2 videodevs)
1363 at once in color(you can do full fps on 4 channels with greyscale.
1364*/
1365static int vidioc_enum_input(struct file *file, void *priv,
1366 struct v4l2_input *inp)
1367{
Dean Anderson4de39f52010-03-03 19:39:19 -03001368 struct s2255_fh *fh = priv;
1369 struct s2255_dev *dev = fh->dev;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001370 struct s2255_channel *channel = fh->channel;
Dean Anderson4de39f52010-03-03 19:39:19 -03001371 u32 status = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001372 if (inp->index != 0)
1373 return -EINVAL;
Dean Anderson38f993a2008-06-26 23:15:51 -03001374 inp->type = V4L2_INPUT_TYPE_CAMERA;
1375 inp->std = S2255_NORMS;
Dean Anderson4de39f52010-03-03 19:39:19 -03001376 inp->status = 0;
1377 if (dev->dsp_fw_ver >= S2255_MIN_DSP_STATUS) {
1378 int rc;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001379 rc = s2255_cmd_status(fh->channel, &status);
Dean Anderson4de39f52010-03-03 19:39:19 -03001380 dprintk(4, "s2255_cmd_status rc: %d status %x\n", rc, status);
1381 if (rc == 0)
1382 inp->status = (status & 0x01) ? 0
1383 : V4L2_IN_ST_NO_SIGNAL;
1384 }
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001385 switch (dev->pid) {
1386 case 0x2255:
1387 default:
1388 strlcpy(inp->name, "Composite", sizeof(inp->name));
1389 break;
1390 case 0x2257:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001391 strlcpy(inp->name, (channel->idx < 2) ? "Composite" : "S-Video",
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001392 sizeof(inp->name));
1393 break;
1394 }
Dean Anderson3f8d6f72008-06-30 21:28:34 -03001395 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001396}
1397
1398static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
1399{
1400 *i = 0;
1401 return 0;
1402}
1403static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
1404{
1405 if (i > 0)
1406 return -EINVAL;
1407 return 0;
1408}
1409
Hans Verkuil192f1e72013-02-15 05:51:21 -03001410static int s2255_s_ctrl(struct v4l2_ctrl *ctrl)
Dean Anderson38f993a2008-06-26 23:15:51 -03001411{
Hans Verkuil192f1e72013-02-15 05:51:21 -03001412 struct s2255_channel *channel =
1413 container_of(ctrl->handler, struct s2255_channel, hdl);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001414 struct s2255_mode mode;
Hans Verkuil192f1e72013-02-15 05:51:21 -03001415
Dean Andersonfe85ce92010-06-01 19:12:07 -03001416 mode = channel->mode;
Dean Anderson2e70db92010-03-05 14:29:09 -03001417 dprintk(4, "%s\n", __func__);
Hans Verkuil192f1e72013-02-15 05:51:21 -03001418
Dean Anderson2e70db92010-03-05 14:29:09 -03001419 /* update the mode to the corresponding value */
1420 switch (ctrl->id) {
1421 case V4L2_CID_BRIGHTNESS:
Hans Verkuil192f1e72013-02-15 05:51:21 -03001422 mode.bright = ctrl->val;
Dean Anderson2e70db92010-03-05 14:29:09 -03001423 break;
1424 case V4L2_CID_CONTRAST:
Hans Verkuil192f1e72013-02-15 05:51:21 -03001425 mode.contrast = ctrl->val;
Dean Anderson2e70db92010-03-05 14:29:09 -03001426 break;
1427 case V4L2_CID_HUE:
Hans Verkuil192f1e72013-02-15 05:51:21 -03001428 mode.hue = ctrl->val;
Dean Anderson2e70db92010-03-05 14:29:09 -03001429 break;
1430 case V4L2_CID_SATURATION:
Hans Verkuil192f1e72013-02-15 05:51:21 -03001431 mode.saturation = ctrl->val;
Dean Anderson2e70db92010-03-05 14:29:09 -03001432 break;
Hans Verkuil192f1e72013-02-15 05:51:21 -03001433 case V4L2_CID_S2255_COLORFILTER:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001434 mode.color &= ~MASK_INPUT_TYPE;
Hans Verkuil192f1e72013-02-15 05:51:21 -03001435 mode.color |= !ctrl->val << 16;
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001436 break;
Dean Anderson2e70db92010-03-05 14:29:09 -03001437 default:
1438 return -EINVAL;
Dean Anderson38f993a2008-06-26 23:15:51 -03001439 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001440 mode.restart = 0;
Dean Anderson2e70db92010-03-05 14:29:09 -03001441 /* set mode here. Note: stream does not need restarted.
1442 some V4L programs restart stream unnecessarily
1443 after a s_crtl.
1444 */
Hans Verkuil192f1e72013-02-15 05:51:21 -03001445 s2255_set_mode(channel, &mode);
Dean Anderson2e70db92010-03-05 14:29:09 -03001446 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001447}
1448
Dean Anderson22b88d42008-08-29 15:33:19 -03001449static int vidioc_g_jpegcomp(struct file *file, void *priv,
1450 struct v4l2_jpegcompression *jc)
1451{
1452 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001453 struct s2255_channel *channel = fh->channel;
1454 *jc = channel->jc;
Dean Anderson85b85482010-04-08 23:51:17 -03001455 dprintk(2, "%s: quality %d\n", __func__, jc->quality);
Dean Anderson22b88d42008-08-29 15:33:19 -03001456 return 0;
1457}
1458
1459static int vidioc_s_jpegcomp(struct file *file, void *priv,
Hans Verkuild88aab52012-09-17 05:05:25 -03001460 const struct v4l2_jpegcompression *jc)
Dean Anderson22b88d42008-08-29 15:33:19 -03001461{
1462 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001463 struct s2255_channel *channel = fh->channel;
Dean Anderson22b88d42008-08-29 15:33:19 -03001464 if (jc->quality < 0 || jc->quality > 100)
1465 return -EINVAL;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001466 channel->jc.quality = jc->quality;
Dean Anderson85b85482010-04-08 23:51:17 -03001467 dprintk(2, "%s: quality %d\n", __func__, jc->quality);
Dean Anderson22b88d42008-08-29 15:33:19 -03001468 return 0;
1469}
Dean Anderson7d853532009-05-15 14:32:04 -03001470
1471static int vidioc_g_parm(struct file *file, void *priv,
1472 struct v4l2_streamparm *sp)
1473{
1474 struct s2255_fh *fh = priv;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001475 __u32 def_num, def_dem;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001476 struct s2255_channel *channel = fh->channel;
Dean Anderson7d853532009-05-15 14:32:04 -03001477 if (sp->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1478 return -EINVAL;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001479 memset(sp, 0, sizeof(struct v4l2_streamparm));
1480 sp->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001481 sp->parm.capture.capturemode = channel->cap_parm.capturemode;
1482 def_num = (channel->mode.format == FORMAT_NTSC) ? 1001 : 1000;
1483 def_dem = (channel->mode.format == FORMAT_NTSC) ? 30000 : 25000;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001484 sp->parm.capture.timeperframe.denominator = def_dem;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001485 switch (channel->mode.fdec) {
Dean Andersone6b44bc2010-03-08 20:04:48 -03001486 default:
1487 case FDEC_1:
1488 sp->parm.capture.timeperframe.numerator = def_num;
1489 break;
1490 case FDEC_2:
1491 sp->parm.capture.timeperframe.numerator = def_num * 2;
1492 break;
1493 case FDEC_3:
1494 sp->parm.capture.timeperframe.numerator = def_num * 3;
1495 break;
1496 case FDEC_5:
1497 sp->parm.capture.timeperframe.numerator = def_num * 5;
1498 break;
1499 }
1500 dprintk(4, "%s capture mode, %d timeperframe %d/%d\n", __func__,
1501 sp->parm.capture.capturemode,
1502 sp->parm.capture.timeperframe.numerator,
1503 sp->parm.capture.timeperframe.denominator);
Dean Anderson7d853532009-05-15 14:32:04 -03001504 return 0;
1505}
1506
1507static int vidioc_s_parm(struct file *file, void *priv,
1508 struct v4l2_streamparm *sp)
1509{
1510 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001511 struct s2255_channel *channel = fh->channel;
1512 struct s2255_mode mode;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001513 int fdec = FDEC_1;
1514 __u32 def_num, def_dem;
Dean Anderson7d853532009-05-15 14:32:04 -03001515 if (sp->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1516 return -EINVAL;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001517 mode = channel->mode;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001518 /* high quality capture mode requires a stream restart */
Dean Andersonfe85ce92010-06-01 19:12:07 -03001519 if (channel->cap_parm.capturemode
1520 != sp->parm.capture.capturemode && res_locked(fh))
Dean Andersone6b44bc2010-03-08 20:04:48 -03001521 return -EBUSY;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001522 def_num = (mode.format == FORMAT_NTSC) ? 1001 : 1000;
1523 def_dem = (mode.format == FORMAT_NTSC) ? 30000 : 25000;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001524 if (def_dem != sp->parm.capture.timeperframe.denominator)
1525 sp->parm.capture.timeperframe.numerator = def_num;
1526 else if (sp->parm.capture.timeperframe.numerator <= def_num)
1527 sp->parm.capture.timeperframe.numerator = def_num;
1528 else if (sp->parm.capture.timeperframe.numerator <= (def_num * 2)) {
1529 sp->parm.capture.timeperframe.numerator = def_num * 2;
1530 fdec = FDEC_2;
1531 } else if (sp->parm.capture.timeperframe.numerator <= (def_num * 3)) {
1532 sp->parm.capture.timeperframe.numerator = def_num * 3;
1533 fdec = FDEC_3;
1534 } else {
1535 sp->parm.capture.timeperframe.numerator = def_num * 5;
1536 fdec = FDEC_5;
1537 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001538 mode.fdec = fdec;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001539 sp->parm.capture.timeperframe.denominator = def_dem;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001540 s2255_set_mode(channel, &mode);
Dean Andersone6b44bc2010-03-08 20:04:48 -03001541 dprintk(4, "%s capture mode, %d timeperframe %d/%d, fdec %d\n",
1542 __func__,
1543 sp->parm.capture.capturemode,
1544 sp->parm.capture.timeperframe.numerator,
1545 sp->parm.capture.timeperframe.denominator, fdec);
Dean Anderson7d853532009-05-15 14:32:04 -03001546 return 0;
1547}
Dean Andersone6b44bc2010-03-08 20:04:48 -03001548
1549static int vidioc_enum_frameintervals(struct file *file, void *priv,
1550 struct v4l2_frmivalenum *fe)
1551{
1552 int is_ntsc = 0;
1553#define NUM_FRAME_ENUMS 4
1554 int frm_dec[NUM_FRAME_ENUMS] = {1, 2, 3, 5};
Mauro Carvalho Chehab199ab8f2012-10-27 16:29:34 -03001555 if (fe->index >= NUM_FRAME_ENUMS)
Dean Andersone6b44bc2010-03-08 20:04:48 -03001556 return -EINVAL;
1557 switch (fe->width) {
1558 case 640:
1559 if (fe->height != 240 && fe->height != 480)
1560 return -EINVAL;
1561 is_ntsc = 1;
1562 break;
1563 case 320:
1564 if (fe->height != 240)
1565 return -EINVAL;
1566 is_ntsc = 1;
1567 break;
1568 case 704:
1569 if (fe->height != 288 && fe->height != 576)
1570 return -EINVAL;
1571 break;
1572 case 352:
1573 if (fe->height != 288)
1574 return -EINVAL;
1575 break;
1576 default:
1577 return -EINVAL;
1578 }
1579 fe->type = V4L2_FRMIVAL_TYPE_DISCRETE;
1580 fe->discrete.denominator = is_ntsc ? 30000 : 25000;
1581 fe->discrete.numerator = (is_ntsc ? 1001 : 1000) * frm_dec[fe->index];
1582 dprintk(4, "%s discrete %d/%d\n", __func__, fe->discrete.numerator,
1583 fe->discrete.denominator);
1584 return 0;
1585}
1586
Hans Verkuil0e1f0ed2012-06-24 06:10:32 -03001587static int __s2255_open(struct file *file)
Dean Anderson38f993a2008-06-26 23:15:51 -03001588{
Laurent Pinchart63b0d5a2009-12-10 11:44:04 -02001589 struct video_device *vdev = video_devdata(file);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001590 struct s2255_channel *channel = video_drvdata(file);
1591 struct s2255_dev *dev = to_s2255_dev(vdev->v4l2_dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03001592 struct s2255_fh *fh;
Laurent Pinchart63b0d5a2009-12-10 11:44:04 -02001593 enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
Dean Anderson14d96262008-08-25 13:58:55 -03001594 int state;
Laurent Pinchart50462eb2009-12-10 11:47:13 -02001595 dprintk(1, "s2255: open called (dev=%s)\n",
1596 video_device_node_name(vdev));
Dean Andersonff7e22d2010-04-08 23:38:07 -03001597 state = atomic_read(&dev->fw_data->fw_state);
1598 switch (state) {
1599 case S2255_FW_DISCONNECTING:
Dean Andersonff7e22d2010-04-08 23:38:07 -03001600 return -ENODEV;
Dean Anderson14d96262008-08-25 13:58:55 -03001601 case S2255_FW_FAILED:
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03001602 s2255_dev_err(&dev->udev->dev,
1603 "firmware load failed. retrying.\n");
Dean Anderson14d96262008-08-25 13:58:55 -03001604 s2255_fwload_start(dev, 1);
Dean Anderson38f993a2008-06-26 23:15:51 -03001605 wait_event_timeout(dev->fw_data->wait_fw,
Dean Anderson14d96262008-08-25 13:58:55 -03001606 ((atomic_read(&dev->fw_data->fw_state)
1607 == S2255_FW_SUCCESS) ||
1608 (atomic_read(&dev->fw_data->fw_state)
1609 == S2255_FW_DISCONNECTING)),
Dean Anderson38f993a2008-06-26 23:15:51 -03001610 msecs_to_jiffies(S2255_LOAD_TIMEOUT));
Dean Andersonff7e22d2010-04-08 23:38:07 -03001611 /* state may have changed, re-read */
1612 state = atomic_read(&dev->fw_data->fw_state);
Dean Anderson14d96262008-08-25 13:58:55 -03001613 break;
1614 case S2255_FW_NOTLOADED:
1615 case S2255_FW_LOADED_DSPWAIT:
Dean Anderson38f993a2008-06-26 23:15:51 -03001616 /* give S2255_LOAD_TIMEOUT time for firmware to load in case
1617 driver loaded and then device immediately opened */
1618 printk(KERN_INFO "%s waiting for firmware load\n", __func__);
1619 wait_event_timeout(dev->fw_data->wait_fw,
Dean Anderson14d96262008-08-25 13:58:55 -03001620 ((atomic_read(&dev->fw_data->fw_state)
1621 == S2255_FW_SUCCESS) ||
1622 (atomic_read(&dev->fw_data->fw_state)
1623 == S2255_FW_DISCONNECTING)),
Dean Andersoneb78dee2010-04-12 15:05:37 -03001624 msecs_to_jiffies(S2255_LOAD_TIMEOUT));
Dean Andersonff7e22d2010-04-08 23:38:07 -03001625 /* state may have changed, re-read */
1626 state = atomic_read(&dev->fw_data->fw_state);
Dean Anderson14d96262008-08-25 13:58:55 -03001627 break;
1628 case S2255_FW_SUCCESS:
1629 default:
1630 break;
1631 }
Dean Andersonff7e22d2010-04-08 23:38:07 -03001632 /* state may have changed in above switch statement */
1633 switch (state) {
1634 case S2255_FW_SUCCESS:
1635 break;
1636 case S2255_FW_FAILED:
1637 printk(KERN_INFO "2255 firmware load failed.\n");
Dean Andersonff7e22d2010-04-08 23:38:07 -03001638 return -ENODEV;
1639 case S2255_FW_DISCONNECTING:
1640 printk(KERN_INFO "%s: disconnecting\n", __func__);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001641 return -ENODEV;
1642 case S2255_FW_LOADED_DSPWAIT:
1643 case S2255_FW_NOTLOADED:
1644 printk(KERN_INFO "%s: firmware not loaded yet"
1645 "please try again later\n",
1646 __func__);
Dean Andersoneb78dee2010-04-12 15:05:37 -03001647 /*
1648 * Timeout on firmware load means device unusable.
1649 * Set firmware failure state.
1650 * On next s2255_open the firmware will be reloaded.
1651 */
1652 atomic_set(&dev->fw_data->fw_state,
1653 S2255_FW_FAILED);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001654 return -EAGAIN;
1655 default:
1656 printk(KERN_INFO "%s: unknown state\n", __func__);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001657 return -EFAULT;
Dean Anderson38f993a2008-06-26 23:15:51 -03001658 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001659 /* allocate + initialize per filehandle data */
1660 fh = kzalloc(sizeof(*fh), GFP_KERNEL);
Dean Andersona5ef91c2010-04-08 23:46:08 -03001661 if (NULL == fh)
Dean Anderson38f993a2008-06-26 23:15:51 -03001662 return -ENOMEM;
Dean Anderson38f993a2008-06-26 23:15:51 -03001663 file->private_data = fh;
1664 fh->dev = dev;
1665 fh->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001666 fh->channel = channel;
1667 if (!channel->configured) {
1668 /* configure channel to default state */
1669 channel->fmt = &formats[0];
1670 s2255_set_mode(channel, &channel->mode);
1671 channel->configured = 1;
Dean Anderson14d96262008-08-25 13:58:55 -03001672 }
Dean Anderson85b85482010-04-08 23:51:17 -03001673 dprintk(1, "%s: dev=%s type=%s\n", __func__,
Dean Andersonff7e22d2010-04-08 23:38:07 -03001674 video_device_node_name(vdev), v4l2_type_names[type]);
Dean Anderson85b85482010-04-08 23:51:17 -03001675 dprintk(2, "%s: fh=0x%08lx, dev=0x%08lx, vidq=0x%08lx\n", __func__,
Dean Anderson38f993a2008-06-26 23:15:51 -03001676 (unsigned long)fh, (unsigned long)dev,
Dean Andersonfe85ce92010-06-01 19:12:07 -03001677 (unsigned long)&channel->vidq);
Dean Anderson85b85482010-04-08 23:51:17 -03001678 dprintk(4, "%s: list_empty active=%d\n", __func__,
Dean Andersonfe85ce92010-06-01 19:12:07 -03001679 list_empty(&channel->vidq.active));
Dean Anderson38f993a2008-06-26 23:15:51 -03001680 videobuf_queue_vmalloc_init(&fh->vb_vidq, &s2255_video_qops,
1681 NULL, &dev->slock,
1682 fh->type,
1683 V4L2_FIELD_INTERLACED,
Pete Eberleina19a5cd2010-12-20 19:18:59 -03001684 sizeof(struct s2255_buffer),
1685 fh, vdev->lock);
Dean Anderson38f993a2008-06-26 23:15:51 -03001686 return 0;
1687}
1688
Hans Verkuil0e1f0ed2012-06-24 06:10:32 -03001689static int s2255_open(struct file *file)
1690{
1691 struct video_device *vdev = video_devdata(file);
1692 int ret;
1693
1694 if (mutex_lock_interruptible(vdev->lock))
1695 return -ERESTARTSYS;
1696 ret = __s2255_open(file);
1697 mutex_unlock(vdev->lock);
1698 return ret;
1699}
Dean Anderson38f993a2008-06-26 23:15:51 -03001700
1701static unsigned int s2255_poll(struct file *file,
1702 struct poll_table_struct *wait)
1703{
1704 struct s2255_fh *fh = file->private_data;
Hans Verkuil0e1f0ed2012-06-24 06:10:32 -03001705 struct s2255_dev *dev = fh->dev;
Dean Anderson38f993a2008-06-26 23:15:51 -03001706 int rc;
1707 dprintk(100, "%s\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03001708 if (V4L2_BUF_TYPE_VIDEO_CAPTURE != fh->type)
1709 return POLLERR;
Hans Verkuil0e1f0ed2012-06-24 06:10:32 -03001710 mutex_lock(&dev->lock);
Dean Anderson38f993a2008-06-26 23:15:51 -03001711 rc = videobuf_poll_stream(file, &fh->vb_vidq, wait);
Hans Verkuil0e1f0ed2012-06-24 06:10:32 -03001712 mutex_unlock(&dev->lock);
Dean Anderson38f993a2008-06-26 23:15:51 -03001713 return rc;
1714}
1715
Dean Andersond62e85a2010-04-09 19:54:26 -03001716static void s2255_destroy(struct s2255_dev *dev)
Dean Anderson38f993a2008-06-26 23:15:51 -03001717{
Dean Anderson38f993a2008-06-26 23:15:51 -03001718 /* board shutdown stops the read pipe if it is running */
1719 s2255_board_shutdown(dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03001720 /* make sure firmware still not trying to load */
Dean Andersonf78d92c2008-07-22 14:43:27 -03001721 del_timer(&dev->timer); /* only started in .probe and .open */
Dean Anderson38f993a2008-06-26 23:15:51 -03001722 if (dev->fw_data->fw_urb) {
Dean Anderson38f993a2008-06-26 23:15:51 -03001723 usb_kill_urb(dev->fw_data->fw_urb);
1724 usb_free_urb(dev->fw_data->fw_urb);
1725 dev->fw_data->fw_urb = NULL;
1726 }
Jesper Juhl3fc82fa2012-04-09 16:50:04 -03001727 release_firmware(dev->fw_data->fw);
Dean Andersonf78d92c2008-07-22 14:43:27 -03001728 kfree(dev->fw_data->pfw_data);
1729 kfree(dev->fw_data);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001730 /* reset the DSP so firmware can be reloaded next time */
1731 s2255_reset_dsppower(dev);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001732 mutex_destroy(&dev->lock);
Dean Anderson38f993a2008-06-26 23:15:51 -03001733 usb_put_dev(dev->udev);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001734 v4l2_device_unregister(&dev->v4l2_dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03001735 dprintk(1, "%s", __func__);
Dean Andersonb7732a32009-03-30 11:59:56 -03001736 kfree(dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03001737}
1738
Dean Andersonff7e22d2010-04-08 23:38:07 -03001739static int s2255_release(struct file *file)
Dean Anderson38f993a2008-06-26 23:15:51 -03001740{
1741 struct s2255_fh *fh = file->private_data;
1742 struct s2255_dev *dev = fh->dev;
Laurent Pinchart50462eb2009-12-10 11:47:13 -02001743 struct video_device *vdev = video_devdata(file);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001744 struct s2255_channel *channel = fh->channel;
Dean Anderson38f993a2008-06-26 23:15:51 -03001745 if (!dev)
1746 return -ENODEV;
Hans Verkuil0e1f0ed2012-06-24 06:10:32 -03001747 mutex_lock(&dev->lock);
Dean Andersonf78d92c2008-07-22 14:43:27 -03001748 /* turn off stream */
1749 if (res_check(fh)) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03001750 if (channel->b_acquire)
1751 s2255_stop_acquire(fh->channel);
Dean Andersonf78d92c2008-07-22 14:43:27 -03001752 videobuf_streamoff(&fh->vb_vidq);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001753 res_free(fh);
Dean Andersonf78d92c2008-07-22 14:43:27 -03001754 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001755 videobuf_mmap_free(&fh->vb_vidq);
Hans Verkuil0e1f0ed2012-06-24 06:10:32 -03001756 mutex_unlock(&dev->lock);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001757 dprintk(1, "%s (dev=%s)\n", __func__, video_device_node_name(vdev));
Dean Andersonf78d92c2008-07-22 14:43:27 -03001758 kfree(fh);
Dean Anderson38f993a2008-06-26 23:15:51 -03001759 return 0;
1760}
1761
1762static int s2255_mmap_v4l(struct file *file, struct vm_area_struct *vma)
1763{
1764 struct s2255_fh *fh = file->private_data;
Julia Lawalle8397762012-08-14 11:49:46 -03001765 struct s2255_dev *dev;
Dean Anderson38f993a2008-06-26 23:15:51 -03001766 int ret;
1767
1768 if (!fh)
1769 return -ENODEV;
Julia Lawalle8397762012-08-14 11:49:46 -03001770 dev = fh->dev;
Dean Anderson85b85482010-04-08 23:51:17 -03001771 dprintk(4, "%s, vma=0x%08lx\n", __func__, (unsigned long)vma);
Hans Verkuil0e1f0ed2012-06-24 06:10:32 -03001772 if (mutex_lock_interruptible(&dev->lock))
1773 return -ERESTARTSYS;
Dean Anderson38f993a2008-06-26 23:15:51 -03001774 ret = videobuf_mmap_mapper(&fh->vb_vidq, vma);
Hans Verkuil0e1f0ed2012-06-24 06:10:32 -03001775 mutex_unlock(&dev->lock);
Dean Anderson85b85482010-04-08 23:51:17 -03001776 dprintk(4, "%s vma start=0x%08lx, size=%ld, ret=%d\n", __func__,
Dean Anderson38f993a2008-06-26 23:15:51 -03001777 (unsigned long)vma->vm_start,
1778 (unsigned long)vma->vm_end - (unsigned long)vma->vm_start, ret);
Dean Anderson38f993a2008-06-26 23:15:51 -03001779 return ret;
1780}
1781
Hans Verkuilbec43662008-12-30 06:58:20 -03001782static const struct v4l2_file_operations s2255_fops_v4l = {
Dean Anderson38f993a2008-06-26 23:15:51 -03001783 .owner = THIS_MODULE,
1784 .open = s2255_open,
Dean Andersonff7e22d2010-04-08 23:38:07 -03001785 .release = s2255_release,
Dean Anderson38f993a2008-06-26 23:15:51 -03001786 .poll = s2255_poll,
Pete Eberleina19a5cd2010-12-20 19:18:59 -03001787 .unlocked_ioctl = video_ioctl2, /* V4L2 ioctl handler */
Dean Anderson38f993a2008-06-26 23:15:51 -03001788 .mmap = s2255_mmap_v4l,
Dean Anderson38f993a2008-06-26 23:15:51 -03001789};
1790
Hans Verkuila3998102008-07-21 02:57:38 -03001791static const struct v4l2_ioctl_ops s2255_ioctl_ops = {
Dean Anderson38f993a2008-06-26 23:15:51 -03001792 .vidioc_querycap = vidioc_querycap,
1793 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
1794 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
1795 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
1796 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
1797 .vidioc_reqbufs = vidioc_reqbufs,
1798 .vidioc_querybuf = vidioc_querybuf,
1799 .vidioc_qbuf = vidioc_qbuf,
1800 .vidioc_dqbuf = vidioc_dqbuf,
1801 .vidioc_s_std = vidioc_s_std,
1802 .vidioc_enum_input = vidioc_enum_input,
1803 .vidioc_g_input = vidioc_g_input,
1804 .vidioc_s_input = vidioc_s_input,
Dean Anderson38f993a2008-06-26 23:15:51 -03001805 .vidioc_streamon = vidioc_streamon,
1806 .vidioc_streamoff = vidioc_streamoff,
Dean Anderson22b88d42008-08-29 15:33:19 -03001807 .vidioc_s_jpegcomp = vidioc_s_jpegcomp,
1808 .vidioc_g_jpegcomp = vidioc_g_jpegcomp,
Dean Anderson7d853532009-05-15 14:32:04 -03001809 .vidioc_s_parm = vidioc_s_parm,
1810 .vidioc_g_parm = vidioc_g_parm,
Dean Andersone6b44bc2010-03-08 20:04:48 -03001811 .vidioc_enum_frameintervals = vidioc_enum_frameintervals,
Hans Verkuila3998102008-07-21 02:57:38 -03001812};
1813
Dean Andersonff7e22d2010-04-08 23:38:07 -03001814static void s2255_video_device_release(struct video_device *vdev)
1815{
Dean Andersonfe85ce92010-06-01 19:12:07 -03001816 struct s2255_dev *dev = to_s2255_dev(vdev->v4l2_dev);
Hans Verkuil192f1e72013-02-15 05:51:21 -03001817 struct s2255_channel *channel =
1818 container_of(vdev, struct s2255_channel, vdev);
1819
1820 v4l2_ctrl_handler_free(&channel->hdl);
1821 dprintk(4, "%s, chnls: %d\n", __func__,
Dean Andersonfe85ce92010-06-01 19:12:07 -03001822 atomic_read(&dev->num_channels));
Hans Verkuil192f1e72013-02-15 05:51:21 -03001823
Dean Andersonfe85ce92010-06-01 19:12:07 -03001824 if (atomic_dec_and_test(&dev->num_channels))
Dean Andersond62e85a2010-04-09 19:54:26 -03001825 s2255_destroy(dev);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001826 return;
1827}
1828
Hans Verkuila3998102008-07-21 02:57:38 -03001829static struct video_device template = {
1830 .name = "s2255v",
Hans Verkuila3998102008-07-21 02:57:38 -03001831 .fops = &s2255_fops_v4l,
1832 .ioctl_ops = &s2255_ioctl_ops,
Dean Andersonff7e22d2010-04-08 23:38:07 -03001833 .release = s2255_video_device_release,
Dean Anderson38f993a2008-06-26 23:15:51 -03001834 .tvnorms = S2255_NORMS,
1835 .current_norm = V4L2_STD_NTSC_M,
1836};
1837
Hans Verkuil192f1e72013-02-15 05:51:21 -03001838static const struct v4l2_ctrl_ops s2255_ctrl_ops = {
1839 .s_ctrl = s2255_s_ctrl,
1840};
1841
1842static const struct v4l2_ctrl_config color_filter_ctrl = {
1843 .ops = &s2255_ctrl_ops,
1844 .name = "Color Filter",
1845 .id = V4L2_CID_S2255_COLORFILTER,
1846 .type = V4L2_CTRL_TYPE_BOOLEAN,
1847 .max = 1,
1848 .step = 1,
1849 .def = 1,
1850};
1851
Dean Anderson38f993a2008-06-26 23:15:51 -03001852static int s2255_probe_v4l(struct s2255_dev *dev)
1853{
1854 int ret;
1855 int i;
1856 int cur_nr = video_nr;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001857 struct s2255_channel *channel;
Dean Anderson65c6edb2010-04-20 17:21:32 -03001858 ret = v4l2_device_register(&dev->interface->dev, &dev->v4l2_dev);
1859 if (ret)
1860 return ret;
Dean Anderson38f993a2008-06-26 23:15:51 -03001861 /* initialize all video 4 linux */
Dean Anderson38f993a2008-06-26 23:15:51 -03001862 /* register 4 video devices */
1863 for (i = 0; i < MAX_CHANNELS; i++) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03001864 channel = &dev->channel[i];
1865 INIT_LIST_HEAD(&channel->vidq.active);
Hans Verkuil192f1e72013-02-15 05:51:21 -03001866
1867 v4l2_ctrl_handler_init(&channel->hdl, 5);
1868 v4l2_ctrl_new_std(&channel->hdl, &s2255_ctrl_ops,
1869 V4L2_CID_BRIGHTNESS, -127, 127, 1, DEF_BRIGHT);
1870 v4l2_ctrl_new_std(&channel->hdl, &s2255_ctrl_ops,
1871 V4L2_CID_CONTRAST, 0, 255, 1, DEF_CONTRAST);
1872 v4l2_ctrl_new_std(&channel->hdl, &s2255_ctrl_ops,
1873 V4L2_CID_SATURATION, 0, 255, 1, DEF_SATURATION);
1874 v4l2_ctrl_new_std(&channel->hdl, &s2255_ctrl_ops,
1875 V4L2_CID_HUE, 0, 255, 1, DEF_HUE);
1876 if (dev->dsp_fw_ver >= S2255_MIN_DSP_COLORFILTER &&
1877 (dev->pid != 0x2257 || channel->idx <= 1))
1878 v4l2_ctrl_new_custom(&channel->hdl, &color_filter_ctrl, NULL);
1879 if (channel->hdl.error) {
1880 ret = channel->hdl.error;
1881 v4l2_ctrl_handler_free(&channel->hdl);
1882 dev_err(&dev->udev->dev, "couldn't register control\n");
1883 break;
1884 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001885 channel->vidq.dev = dev;
Dean Anderson38f993a2008-06-26 23:15:51 -03001886 /* register 4 video devices */
Dean Andersonfe85ce92010-06-01 19:12:07 -03001887 channel->vdev = template;
Hans Verkuil192f1e72013-02-15 05:51:21 -03001888 channel->vdev.ctrl_handler = &channel->hdl;
Pete Eberleina19a5cd2010-12-20 19:18:59 -03001889 channel->vdev.lock = &dev->lock;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001890 channel->vdev.v4l2_dev = &dev->v4l2_dev;
1891 video_set_drvdata(&channel->vdev, channel);
Dean Anderson38f993a2008-06-26 23:15:51 -03001892 if (video_nr == -1)
Dean Andersonfe85ce92010-06-01 19:12:07 -03001893 ret = video_register_device(&channel->vdev,
Dean Anderson38f993a2008-06-26 23:15:51 -03001894 VFL_TYPE_GRABBER,
1895 video_nr);
1896 else
Dean Andersonfe85ce92010-06-01 19:12:07 -03001897 ret = video_register_device(&channel->vdev,
Dean Anderson38f993a2008-06-26 23:15:51 -03001898 VFL_TYPE_GRABBER,
1899 cur_nr + i);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001900
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03001901 if (ret) {
Dean Anderson38f993a2008-06-26 23:15:51 -03001902 dev_err(&dev->udev->dev,
1903 "failed to register video device!\n");
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03001904 break;
Dean Anderson38f993a2008-06-26 23:15:51 -03001905 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001906 atomic_inc(&dev->num_channels);
Dean Anderson65c6edb2010-04-20 17:21:32 -03001907 v4l2_info(&dev->v4l2_dev, "V4L2 device registered as %s\n",
Dean Andersonfe85ce92010-06-01 19:12:07 -03001908 video_device_node_name(&channel->vdev));
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03001909
Dean Anderson38f993a2008-06-26 23:15:51 -03001910 }
Mauro Carvalho Chehab64dc3c12011-06-25 11:28:37 -03001911 printk(KERN_INFO "Sensoray 2255 V4L driver Revision: %s\n",
1912 S2255_VERSION);
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03001913 /* if no channels registered, return error and probe will fail*/
Dean Andersonfe85ce92010-06-01 19:12:07 -03001914 if (atomic_read(&dev->num_channels) == 0) {
Dean Anderson65c6edb2010-04-20 17:21:32 -03001915 v4l2_device_unregister(&dev->v4l2_dev);
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03001916 return ret;
Dean Anderson65c6edb2010-04-20 17:21:32 -03001917 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001918 if (atomic_read(&dev->num_channels) != MAX_CHANNELS)
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03001919 printk(KERN_WARNING "s2255: Not all channels available.\n");
1920 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001921}
1922
Dean Anderson38f993a2008-06-26 23:15:51 -03001923/* this function moves the usb stream read pipe data
1924 * into the system buffers.
1925 * returns 0 on success, EAGAIN if more data to process( call this
1926 * function again).
1927 *
1928 * Received frame structure:
Dean Anderson14d96262008-08-25 13:58:55 -03001929 * bytes 0-3: marker : 0x2255DA4AL (S2255_MARKER_FRAME)
Dean Anderson38f993a2008-06-26 23:15:51 -03001930 * bytes 4-7: channel: 0-3
1931 * bytes 8-11: payload size: size of the frame
1932 * bytes 12-payloadsize+12: frame data
1933 */
1934static int save_frame(struct s2255_dev *dev, struct s2255_pipeinfo *pipe_info)
1935{
Dean Anderson38f993a2008-06-26 23:15:51 -03001936 char *pdest;
1937 u32 offset = 0;
Dean Anderson14d96262008-08-25 13:58:55 -03001938 int bframe = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001939 char *psrc;
1940 unsigned long copy_size;
1941 unsigned long size;
1942 s32 idx = -1;
1943 struct s2255_framei *frm;
1944 unsigned char *pdata;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001945 struct s2255_channel *channel;
Dean Anderson38f993a2008-06-26 23:15:51 -03001946 dprintk(100, "buffer to user\n");
Dean Andersonfe85ce92010-06-01 19:12:07 -03001947 channel = &dev->channel[dev->cc];
1948 idx = channel->cur_frame;
1949 frm = &channel->buffer.frame[idx];
Dean Anderson14d96262008-08-25 13:58:55 -03001950 if (frm->ulState == S2255_READ_IDLE) {
1951 int jj;
1952 unsigned int cc;
Dean Anderson3fa00602010-03-04 20:47:33 -03001953 __le32 *pdword; /*data from dsp is little endian */
Dean Anderson14d96262008-08-25 13:58:55 -03001954 int payload;
1955 /* search for marker codes */
1956 pdata = (unsigned char *)pipe_info->transfer_buffer;
Dean Anderson3fa00602010-03-04 20:47:33 -03001957 pdword = (__le32 *)pdata;
Dean Anderson14d96262008-08-25 13:58:55 -03001958 for (jj = 0; jj < (pipe_info->cur_transfer_size - 12); jj++) {
Dean Anderson3fa00602010-03-04 20:47:33 -03001959 switch (*pdword) {
Dean Anderson14d96262008-08-25 13:58:55 -03001960 case S2255_MARKER_FRAME:
Dean Anderson14d96262008-08-25 13:58:55 -03001961 dprintk(4, "found frame marker at offset:"
1962 " %d [%x %x]\n", jj, pdata[0],
1963 pdata[1]);
1964 offset = jj + PREFIX_SIZE;
1965 bframe = 1;
Dan Carpenter3b2a6302012-02-17 02:44:10 -03001966 cc = le32_to_cpu(pdword[1]);
Dean Anderson14d96262008-08-25 13:58:55 -03001967 if (cc >= MAX_CHANNELS) {
1968 printk(KERN_ERR
1969 "bad channel\n");
1970 return -EINVAL;
1971 }
1972 /* reverse it */
1973 dev->cc = G_chnmap[cc];
Dean Andersonfe85ce92010-06-01 19:12:07 -03001974 channel = &dev->channel[dev->cc];
Dan Carpenter3b2a6302012-02-17 02:44:10 -03001975 payload = le32_to_cpu(pdword[3]);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001976 if (payload > channel->req_image_size) {
1977 channel->bad_payload++;
Dean Anderson14d96262008-08-25 13:58:55 -03001978 /* discard the bad frame */
1979 return -EINVAL;
1980 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001981 channel->pkt_size = payload;
Dan Carpenter3b2a6302012-02-17 02:44:10 -03001982 channel->jpg_size = le32_to_cpu(pdword[4]);
Dean Anderson14d96262008-08-25 13:58:55 -03001983 break;
1984 case S2255_MARKER_RESPONSE:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001985
Dean Anderson14d96262008-08-25 13:58:55 -03001986 pdata += DEF_USB_BLOCK;
1987 jj += DEF_USB_BLOCK;
Dan Carpenter3b2a6302012-02-17 02:44:10 -03001988 if (le32_to_cpu(pdword[1]) >= MAX_CHANNELS)
Dean Anderson14d96262008-08-25 13:58:55 -03001989 break;
Dan Carpenter3b2a6302012-02-17 02:44:10 -03001990 cc = G_chnmap[le32_to_cpu(pdword[1])];
Roel Kluinf14a2972009-10-23 07:59:42 -03001991 if (cc >= MAX_CHANNELS)
Dean Anderson14d96262008-08-25 13:58:55 -03001992 break;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001993 channel = &dev->channel[cc];
Dean Anderson14d96262008-08-25 13:58:55 -03001994 switch (pdword[2]) {
Dean Andersonabce21f2009-04-23 16:04:41 -03001995 case S2255_RESPONSE_SETMODE:
Dean Anderson14d96262008-08-25 13:58:55 -03001996 /* check if channel valid */
1997 /* set mode ready */
Dean Andersonfe85ce92010-06-01 19:12:07 -03001998 channel->setmode_ready = 1;
1999 wake_up(&channel->wait_setmode);
Dean Anderson14d96262008-08-25 13:58:55 -03002000 dprintk(5, "setmode ready %d\n", cc);
2001 break;
Dean Andersonabce21f2009-04-23 16:04:41 -03002002 case S2255_RESPONSE_FW:
Dean Anderson14d96262008-08-25 13:58:55 -03002003 dev->chn_ready |= (1 << cc);
2004 if ((dev->chn_ready & 0x0f) != 0x0f)
2005 break;
2006 /* all channels ready */
2007 printk(KERN_INFO "s2255: fw loaded\n");
2008 atomic_set(&dev->fw_data->fw_state,
2009 S2255_FW_SUCCESS);
2010 wake_up(&dev->fw_data->wait_fw);
2011 break;
Dean Anderson4de39f52010-03-03 19:39:19 -03002012 case S2255_RESPONSE_STATUS:
Dan Carpenter3b2a6302012-02-17 02:44:10 -03002013 channel->vidstatus = le32_to_cpu(pdword[3]);
Dean Andersonfe85ce92010-06-01 19:12:07 -03002014 channel->vidstatus_ready = 1;
2015 wake_up(&channel->wait_vidstatus);
Dean Anderson4de39f52010-03-03 19:39:19 -03002016 dprintk(5, "got vidstatus %x chan %d\n",
Dan Carpenter3b2a6302012-02-17 02:44:10 -03002017 le32_to_cpu(pdword[3]), cc);
Dean Anderson4de39f52010-03-03 19:39:19 -03002018 break;
Dean Anderson14d96262008-08-25 13:58:55 -03002019 default:
André Goddard Rosaaf901ca2009-11-14 13:09:05 -02002020 printk(KERN_INFO "s2255 unknown resp\n");
Dean Anderson14d96262008-08-25 13:58:55 -03002021 }
2022 default:
2023 pdata++;
2024 break;
2025 }
2026 if (bframe)
2027 break;
2028 } /* for */
2029 if (!bframe)
2030 return -EINVAL;
2031 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03002032 channel = &dev->channel[dev->cc];
2033 idx = channel->cur_frame;
2034 frm = &channel->buffer.frame[idx];
Dean Anderson14d96262008-08-25 13:58:55 -03002035 /* search done. now find out if should be acquiring on this channel */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002036 if (!channel->b_acquire) {
Dean Anderson14d96262008-08-25 13:58:55 -03002037 /* we found a frame, but this channel is turned off */
2038 frm->ulState = S2255_READ_IDLE;
2039 return -EINVAL;
2040 }
2041
2042 if (frm->ulState == S2255_READ_IDLE) {
2043 frm->ulState = S2255_READ_FRAME;
Dean Anderson38f993a2008-06-26 23:15:51 -03002044 frm->cur_size = 0;
2045 }
2046
Dean Anderson14d96262008-08-25 13:58:55 -03002047 /* skip the marker 512 bytes (and offset if out of sync) */
2048 psrc = (u8 *)pipe_info->transfer_buffer + offset;
2049
Dean Anderson38f993a2008-06-26 23:15:51 -03002050
2051 if (frm->lpvbits == NULL) {
2052 dprintk(1, "s2255 frame buffer == NULL.%p %p %d %d",
2053 frm, dev, dev->cc, idx);
2054 return -ENOMEM;
2055 }
2056
2057 pdest = frm->lpvbits + frm->cur_size;
2058
Dean Anderson14d96262008-08-25 13:58:55 -03002059 copy_size = (pipe_info->cur_transfer_size - offset);
Dean Anderson38f993a2008-06-26 23:15:51 -03002060
Dean Andersonfe85ce92010-06-01 19:12:07 -03002061 size = channel->pkt_size - PREFIX_SIZE;
Dean Anderson38f993a2008-06-26 23:15:51 -03002062
Dean Anderson14d96262008-08-25 13:58:55 -03002063 /* sanity check on pdest */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002064 if ((copy_size + frm->cur_size) < channel->req_image_size)
Dean Anderson14d96262008-08-25 13:58:55 -03002065 memcpy(pdest, psrc, copy_size);
Dean Anderson38f993a2008-06-26 23:15:51 -03002066
Dean Anderson38f993a2008-06-26 23:15:51 -03002067 frm->cur_size += copy_size;
Dean Anderson14d96262008-08-25 13:58:55 -03002068 dprintk(4, "cur_size size %lu size %lu \n", frm->cur_size, size);
Dean Anderson38f993a2008-06-26 23:15:51 -03002069
Dean Anderson14d96262008-08-25 13:58:55 -03002070 if (frm->cur_size >= size) {
Dean Anderson38f993a2008-06-26 23:15:51 -03002071 dprintk(2, "****************[%d]Buffer[%d]full*************\n",
Dean Andersonfe85ce92010-06-01 19:12:07 -03002072 dev->cc, idx);
2073 channel->last_frame = channel->cur_frame;
2074 channel->cur_frame++;
Dean Anderson38f993a2008-06-26 23:15:51 -03002075 /* end of system frame ring buffer, start at zero */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002076 if ((channel->cur_frame == SYS_FRAMES) ||
2077 (channel->cur_frame == channel->buffer.dwFrames))
2078 channel->cur_frame = 0;
Dean Anderson14d96262008-08-25 13:58:55 -03002079 /* frame ready */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002080 if (channel->b_acquire)
2081 s2255_got_frame(channel, channel->jpg_size);
2082 channel->frame_count++;
Dean Anderson14d96262008-08-25 13:58:55 -03002083 frm->ulState = S2255_READ_IDLE;
2084 frm->cur_size = 0;
2085
Dean Anderson38f993a2008-06-26 23:15:51 -03002086 }
2087 /* done successfully */
2088 return 0;
2089}
2090
2091static void s2255_read_video_callback(struct s2255_dev *dev,
2092 struct s2255_pipeinfo *pipe_info)
2093{
2094 int res;
2095 dprintk(50, "callback read video \n");
2096
2097 if (dev->cc >= MAX_CHANNELS) {
2098 dev->cc = 0;
2099 dev_err(&dev->udev->dev, "invalid channel\n");
2100 return;
2101 }
2102 /* otherwise copy to the system buffers */
2103 res = save_frame(dev, pipe_info);
Dean Anderson14d96262008-08-25 13:58:55 -03002104 if (res != 0)
2105 dprintk(4, "s2255: read callback failed\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03002106
2107 dprintk(50, "callback read video done\n");
2108 return;
2109}
2110
2111static long s2255_vendor_req(struct s2255_dev *dev, unsigned char Request,
2112 u16 Index, u16 Value, void *TransferBuffer,
2113 s32 TransferBufferLength, int bOut)
2114{
2115 int r;
2116 if (!bOut) {
2117 r = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0),
2118 Request,
2119 USB_TYPE_VENDOR | USB_RECIP_DEVICE |
2120 USB_DIR_IN,
2121 Value, Index, TransferBuffer,
2122 TransferBufferLength, HZ * 5);
2123 } else {
2124 r = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0),
2125 Request, USB_TYPE_VENDOR | USB_RECIP_DEVICE,
2126 Value, Index, TransferBuffer,
2127 TransferBufferLength, HZ * 5);
2128 }
2129 return r;
2130}
2131
2132/*
2133 * retrieve FX2 firmware version. future use.
2134 * @param dev pointer to device extension
2135 * @return -1 for fail, else returns firmware version as an int(16 bits)
2136 */
2137static int s2255_get_fx2fw(struct s2255_dev *dev)
2138{
2139 int fw;
2140 int ret;
2141 unsigned char transBuffer[64];
2142 ret = s2255_vendor_req(dev, S2255_VR_FW, 0, 0, transBuffer, 2,
2143 S2255_VR_IN);
2144 if (ret < 0)
2145 dprintk(2, "get fw error: %x\n", ret);
2146 fw = transBuffer[0] + (transBuffer[1] << 8);
2147 dprintk(2, "Get FW %x %x\n", transBuffer[0], transBuffer[1]);
2148 return fw;
2149}
2150
2151/*
2152 * Create the system ring buffer to copy frames into from the
2153 * usb read pipe.
2154 */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002155static int s2255_create_sys_buffers(struct s2255_channel *channel)
Dean Anderson38f993a2008-06-26 23:15:51 -03002156{
2157 unsigned long i;
2158 unsigned long reqsize;
2159 dprintk(1, "create sys buffers\n");
Dean Andersonfe85ce92010-06-01 19:12:07 -03002160 channel->buffer.dwFrames = SYS_FRAMES;
Dean Anderson38f993a2008-06-26 23:15:51 -03002161 /* always allocate maximum size(PAL) for system buffers */
2162 reqsize = SYS_FRAMES_MAXSIZE;
2163
2164 if (reqsize > SYS_FRAMES_MAXSIZE)
2165 reqsize = SYS_FRAMES_MAXSIZE;
2166
2167 for (i = 0; i < SYS_FRAMES; i++) {
2168 /* allocate the frames */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002169 channel->buffer.frame[i].lpvbits = vmalloc(reqsize);
2170 dprintk(1, "valloc %p chan %d, idx %lu, pdata %p\n",
2171 &channel->buffer.frame[i], channel->idx, i,
2172 channel->buffer.frame[i].lpvbits);
2173 channel->buffer.frame[i].size = reqsize;
2174 if (channel->buffer.frame[i].lpvbits == NULL) {
Dean Anderson38f993a2008-06-26 23:15:51 -03002175 printk(KERN_INFO "out of memory. using less frames\n");
Dean Andersonfe85ce92010-06-01 19:12:07 -03002176 channel->buffer.dwFrames = i;
Dean Anderson38f993a2008-06-26 23:15:51 -03002177 break;
2178 }
2179 }
2180
2181 /* make sure internal states are set */
2182 for (i = 0; i < SYS_FRAMES; i++) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03002183 channel->buffer.frame[i].ulState = 0;
2184 channel->buffer.frame[i].cur_size = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03002185 }
2186
Dean Andersonfe85ce92010-06-01 19:12:07 -03002187 channel->cur_frame = 0;
2188 channel->last_frame = -1;
Dean Anderson38f993a2008-06-26 23:15:51 -03002189 return 0;
2190}
2191
Dean Andersonfe85ce92010-06-01 19:12:07 -03002192static int s2255_release_sys_buffers(struct s2255_channel *channel)
Dean Anderson38f993a2008-06-26 23:15:51 -03002193{
2194 unsigned long i;
2195 dprintk(1, "release sys buffers\n");
2196 for (i = 0; i < SYS_FRAMES; i++) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03002197 if (channel->buffer.frame[i].lpvbits) {
Dean Anderson38f993a2008-06-26 23:15:51 -03002198 dprintk(1, "vfree %p\n",
Dean Andersonfe85ce92010-06-01 19:12:07 -03002199 channel->buffer.frame[i].lpvbits);
2200 vfree(channel->buffer.frame[i].lpvbits);
Dean Anderson38f993a2008-06-26 23:15:51 -03002201 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03002202 channel->buffer.frame[i].lpvbits = NULL;
Dean Anderson38f993a2008-06-26 23:15:51 -03002203 }
2204 return 0;
2205}
2206
2207static int s2255_board_init(struct s2255_dev *dev)
2208{
Dean Anderson38f993a2008-06-26 23:15:51 -03002209 struct s2255_mode mode_def = DEF_MODEI_NTSC_CONT;
2210 int fw_ver;
Dean Andersonab85c6a2010-04-08 23:39:12 -03002211 int j;
2212 struct s2255_pipeinfo *pipe = &dev->pipe;
Dean Anderson38f993a2008-06-26 23:15:51 -03002213 dprintk(4, "board init: %p", dev);
Dean Andersonab85c6a2010-04-08 23:39:12 -03002214 memset(pipe, 0, sizeof(*pipe));
2215 pipe->dev = dev;
2216 pipe->cur_transfer_size = S2255_USB_XFER_SIZE;
2217 pipe->max_transfer_size = S2255_USB_XFER_SIZE;
Dean Anderson38f993a2008-06-26 23:15:51 -03002218
Dean Andersonab85c6a2010-04-08 23:39:12 -03002219 pipe->transfer_buffer = kzalloc(pipe->max_transfer_size,
2220 GFP_KERNEL);
2221 if (pipe->transfer_buffer == NULL) {
2222 dprintk(1, "out of memory!\n");
2223 return -ENOMEM;
Dean Anderson38f993a2008-06-26 23:15:51 -03002224 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002225 /* query the firmware */
2226 fw_ver = s2255_get_fx2fw(dev);
2227
Sensoray Linux Development8a8cc952011-04-04 14:08:40 -03002228 printk(KERN_INFO "s2255: usb firmware version %d.%d\n",
Dean Andersonabce21f2009-04-23 16:04:41 -03002229 (fw_ver >> 8) & 0xff,
2230 fw_ver & 0xff);
2231
2232 if (fw_ver < S2255_CUR_USB_FWVER)
Sensoray Linux Development8a8cc952011-04-04 14:08:40 -03002233 printk(KERN_INFO "s2255: newer USB firmware available\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03002234
2235 for (j = 0; j < MAX_CHANNELS; j++) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03002236 struct s2255_channel *channel = &dev->channel[j];
2237 channel->b_acquire = 0;
2238 channel->mode = mode_def;
Dean Anderson5a34d9d2010-03-05 19:59:48 -03002239 if (dev->pid == 0x2257 && j > 1)
Dean Andersonfe85ce92010-06-01 19:12:07 -03002240 channel->mode.color |= (1 << 16);
2241 channel->jc.quality = S2255_DEF_JPEG_QUAL;
2242 channel->width = LINE_SZ_4CIFS_NTSC;
2243 channel->height = NUM_LINES_4CIFS_NTSC * 2;
2244 channel->fmt = &formats[0];
2245 channel->mode.restart = 1;
2246 channel->req_image_size = get_transfer_size(&mode_def);
2247 channel->frame_count = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03002248 /* create the system buffers */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002249 s2255_create_sys_buffers(channel);
Dean Anderson38f993a2008-06-26 23:15:51 -03002250 }
2251 /* start read pipe */
2252 s2255_start_readpipe(dev);
Dean Anderson85b85482010-04-08 23:51:17 -03002253 dprintk(1, "%s: success\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03002254 return 0;
2255}
2256
2257static int s2255_board_shutdown(struct s2255_dev *dev)
2258{
2259 u32 i;
Dean Anderson85b85482010-04-08 23:51:17 -03002260 dprintk(1, "%s: dev: %p", __func__, dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03002261
2262 for (i = 0; i < MAX_CHANNELS; i++) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03002263 if (dev->channel[i].b_acquire)
2264 s2255_stop_acquire(&dev->channel[i]);
Dean Anderson38f993a2008-06-26 23:15:51 -03002265 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002266 s2255_stop_readpipe(dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03002267 for (i = 0; i < MAX_CHANNELS; i++)
Dean Andersonfe85ce92010-06-01 19:12:07 -03002268 s2255_release_sys_buffers(&dev->channel[i]);
Dean Andersonab85c6a2010-04-08 23:39:12 -03002269 /* release transfer buffer */
2270 kfree(dev->pipe.transfer_buffer);
Dean Anderson38f993a2008-06-26 23:15:51 -03002271 return 0;
2272}
2273
2274static void read_pipe_completion(struct urb *purb)
2275{
2276 struct s2255_pipeinfo *pipe_info;
2277 struct s2255_dev *dev;
2278 int status;
2279 int pipe;
Dean Anderson38f993a2008-06-26 23:15:51 -03002280 pipe_info = purb->context;
Dean Anderson85b85482010-04-08 23:51:17 -03002281 dprintk(100, "%s: urb:%p, status %d\n", __func__, purb,
Dean Anderson38f993a2008-06-26 23:15:51 -03002282 purb->status);
2283 if (pipe_info == NULL) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002284 dev_err(&purb->dev->dev, "no context!\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03002285 return;
2286 }
2287
2288 dev = pipe_info->dev;
2289 if (dev == NULL) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002290 dev_err(&purb->dev->dev, "no context!\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03002291 return;
2292 }
2293 status = purb->status;
Dean Andersonb02064c2009-04-30 12:29:38 -03002294 /* if shutting down, do not resubmit, exit immediately */
2295 if (status == -ESHUTDOWN) {
Dean Anderson85b85482010-04-08 23:51:17 -03002296 dprintk(2, "%s: err shutdown\n", __func__);
Dean Andersonb02064c2009-04-30 12:29:38 -03002297 pipe_info->err_count++;
Dean Anderson38f993a2008-06-26 23:15:51 -03002298 return;
2299 }
2300
2301 if (pipe_info->state == 0) {
Dean Anderson85b85482010-04-08 23:51:17 -03002302 dprintk(2, "%s: exiting USB pipe", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03002303 return;
2304 }
2305
Dean Andersonb02064c2009-04-30 12:29:38 -03002306 if (status == 0)
2307 s2255_read_video_callback(dev, pipe_info);
2308 else {
2309 pipe_info->err_count++;
Dean Anderson85b85482010-04-08 23:51:17 -03002310 dprintk(1, "%s: failed URB %d\n", __func__, status);
Dean Andersonb02064c2009-04-30 12:29:38 -03002311 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002312
Dean Anderson38f993a2008-06-26 23:15:51 -03002313 pipe = usb_rcvbulkpipe(dev->udev, dev->read_endpoint);
2314 /* reuse urb */
2315 usb_fill_bulk_urb(pipe_info->stream_urb, dev->udev,
2316 pipe,
2317 pipe_info->transfer_buffer,
2318 pipe_info->cur_transfer_size,
2319 read_pipe_completion, pipe_info);
2320
2321 if (pipe_info->state != 0) {
Pete Eberleina1b4c862011-04-01 21:21:26 -03002322 if (usb_submit_urb(pipe_info->stream_urb, GFP_ATOMIC)) {
Dean Anderson38f993a2008-06-26 23:15:51 -03002323 dev_err(&dev->udev->dev, "error submitting urb\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03002324 }
2325 } else {
Dean Anderson85b85482010-04-08 23:51:17 -03002326 dprintk(2, "%s :complete state 0\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03002327 }
2328 return;
2329}
2330
2331static int s2255_start_readpipe(struct s2255_dev *dev)
2332{
2333 int pipe;
2334 int retval;
Dean Andersonab85c6a2010-04-08 23:39:12 -03002335 struct s2255_pipeinfo *pipe_info = &dev->pipe;
Dean Anderson38f993a2008-06-26 23:15:51 -03002336 pipe = usb_rcvbulkpipe(dev->udev, dev->read_endpoint);
Dean Anderson85b85482010-04-08 23:51:17 -03002337 dprintk(2, "%s: IN %d\n", __func__, dev->read_endpoint);
Dean Andersonab85c6a2010-04-08 23:39:12 -03002338 pipe_info->state = 1;
2339 pipe_info->err_count = 0;
2340 pipe_info->stream_urb = usb_alloc_urb(0, GFP_KERNEL);
2341 if (!pipe_info->stream_urb) {
2342 dev_err(&dev->udev->dev,
2343 "ReadStream: Unable to alloc URB\n");
2344 return -ENOMEM;
Dean Anderson38f993a2008-06-26 23:15:51 -03002345 }
Dean Andersonab85c6a2010-04-08 23:39:12 -03002346 /* transfer buffer allocated in board_init */
2347 usb_fill_bulk_urb(pipe_info->stream_urb, dev->udev,
2348 pipe,
2349 pipe_info->transfer_buffer,
2350 pipe_info->cur_transfer_size,
2351 read_pipe_completion, pipe_info);
Dean Andersonab85c6a2010-04-08 23:39:12 -03002352 retval = usb_submit_urb(pipe_info->stream_urb, GFP_KERNEL);
2353 if (retval) {
2354 printk(KERN_ERR "s2255: start read pipe failed\n");
2355 return retval;
2356 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002357 return 0;
2358}
2359
2360/* starts acquisition process */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002361static int s2255_start_acquire(struct s2255_channel *channel)
Dean Anderson38f993a2008-06-26 23:15:51 -03002362{
2363 unsigned char *buffer;
2364 int res;
2365 unsigned long chn_rev;
2366 int j;
Dean Andersonfe85ce92010-06-01 19:12:07 -03002367 struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev);
2368 chn_rev = G_chnmap[channel->idx];
Dean Anderson38f993a2008-06-26 23:15:51 -03002369 buffer = kzalloc(512, GFP_KERNEL);
2370 if (buffer == NULL) {
2371 dev_err(&dev->udev->dev, "out of mem\n");
2372 return -ENOMEM;
2373 }
2374
Dean Andersonfe85ce92010-06-01 19:12:07 -03002375 channel->last_frame = -1;
2376 channel->bad_payload = 0;
2377 channel->cur_frame = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03002378 for (j = 0; j < SYS_FRAMES; j++) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03002379 channel->buffer.frame[j].ulState = 0;
2380 channel->buffer.frame[j].cur_size = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03002381 }
2382
2383 /* send the start command */
Dean Anderson3fa00602010-03-04 20:47:33 -03002384 *(__le32 *) buffer = IN_DATA_TOKEN;
2385 *((__le32 *) buffer + 1) = (__le32) cpu_to_le32(chn_rev);
2386 *((__le32 *) buffer + 2) = CMD_START;
Dean Anderson38f993a2008-06-26 23:15:51 -03002387 res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
2388 if (res != 0)
2389 dev_err(&dev->udev->dev, "CMD_START error\n");
2390
Dean Andersonfe85ce92010-06-01 19:12:07 -03002391 dprintk(2, "start acquire exit[%d] %d \n", channel->idx, res);
Dean Anderson38f993a2008-06-26 23:15:51 -03002392 kfree(buffer);
2393 return 0;
2394}
2395
Dean Andersonfe85ce92010-06-01 19:12:07 -03002396static int s2255_stop_acquire(struct s2255_channel *channel)
Dean Anderson38f993a2008-06-26 23:15:51 -03002397{
2398 unsigned char *buffer;
2399 int res;
2400 unsigned long chn_rev;
Dean Andersonfe85ce92010-06-01 19:12:07 -03002401 struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev);
2402 chn_rev = G_chnmap[channel->idx];
Dean Anderson38f993a2008-06-26 23:15:51 -03002403 buffer = kzalloc(512, GFP_KERNEL);
2404 if (buffer == NULL) {
2405 dev_err(&dev->udev->dev, "out of mem\n");
2406 return -ENOMEM;
2407 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002408 /* send the stop command */
Dean Anderson3fa00602010-03-04 20:47:33 -03002409 *(__le32 *) buffer = IN_DATA_TOKEN;
2410 *((__le32 *) buffer + 1) = (__le32) cpu_to_le32(chn_rev);
2411 *((__le32 *) buffer + 2) = CMD_STOP;
Dean Anderson38f993a2008-06-26 23:15:51 -03002412 res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
Dean Anderson38f993a2008-06-26 23:15:51 -03002413 if (res != 0)
2414 dev_err(&dev->udev->dev, "CMD_STOP error\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03002415 kfree(buffer);
Dean Andersonfe85ce92010-06-01 19:12:07 -03002416 channel->b_acquire = 0;
2417 dprintk(4, "%s: chn %d, res %d\n", __func__, channel->idx, res);
Dean Anderson14d96262008-08-25 13:58:55 -03002418 return res;
Dean Anderson38f993a2008-06-26 23:15:51 -03002419}
2420
2421static void s2255_stop_readpipe(struct s2255_dev *dev)
2422{
Dean Andersonab85c6a2010-04-08 23:39:12 -03002423 struct s2255_pipeinfo *pipe = &dev->pipe;
Dan Carpenter8b661b52010-05-05 03:00:47 -03002424
Dean Andersonab85c6a2010-04-08 23:39:12 -03002425 pipe->state = 0;
2426 if (pipe->stream_urb) {
2427 /* cancel urb */
2428 usb_kill_urb(pipe->stream_urb);
2429 usb_free_urb(pipe->stream_urb);
2430 pipe->stream_urb = NULL;
Dean Anderson38f993a2008-06-26 23:15:51 -03002431 }
Dean Andersonab85c6a2010-04-08 23:39:12 -03002432 dprintk(4, "%s", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03002433 return;
2434}
2435
Dean Anderson14d96262008-08-25 13:58:55 -03002436static void s2255_fwload_start(struct s2255_dev *dev, int reset)
Dean Anderson38f993a2008-06-26 23:15:51 -03002437{
Dean Anderson14d96262008-08-25 13:58:55 -03002438 if (reset)
2439 s2255_reset_dsppower(dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03002440 dev->fw_data->fw_size = dev->fw_data->fw->size;
2441 atomic_set(&dev->fw_data->fw_state, S2255_FW_NOTLOADED);
2442 memcpy(dev->fw_data->pfw_data,
2443 dev->fw_data->fw->data, CHUNK_SIZE);
2444 dev->fw_data->fw_loaded = CHUNK_SIZE;
2445 usb_fill_bulk_urb(dev->fw_data->fw_urb, dev->udev,
2446 usb_sndbulkpipe(dev->udev, 2),
2447 dev->fw_data->pfw_data,
2448 CHUNK_SIZE, s2255_fwchunk_complete,
2449 dev->fw_data);
2450 mod_timer(&dev->timer, jiffies + HZ);
2451}
2452
2453/* standard usb probe function */
2454static int s2255_probe(struct usb_interface *interface,
2455 const struct usb_device_id *id)
2456{
2457 struct s2255_dev *dev = NULL;
2458 struct usb_host_interface *iface_desc;
2459 struct usb_endpoint_descriptor *endpoint;
2460 int i;
2461 int retval = -ENOMEM;
Dean Anderson14d96262008-08-25 13:58:55 -03002462 __le32 *pdata;
2463 int fw_size;
Dean Anderson85b85482010-04-08 23:51:17 -03002464 dprintk(2, "%s\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03002465 /* allocate memory for our device state and initialize it to zero */
2466 dev = kzalloc(sizeof(struct s2255_dev), GFP_KERNEL);
2467 if (dev == NULL) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002468 s2255_dev_err(&interface->dev, "out of memory\n");
Dean Andersonff7e22d2010-04-08 23:38:07 -03002469 return -ENOMEM;
Dean Anderson38f993a2008-06-26 23:15:51 -03002470 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03002471 atomic_set(&dev->num_channels, 0);
Dean Anderson5a34d9d2010-03-05 19:59:48 -03002472 dev->pid = id->idProduct;
Dean Anderson38f993a2008-06-26 23:15:51 -03002473 dev->fw_data = kzalloc(sizeof(struct s2255_fw), GFP_KERNEL);
2474 if (!dev->fw_data)
Dean Andersonff7e22d2010-04-08 23:38:07 -03002475 goto errorFWDATA1;
Dean Anderson38f993a2008-06-26 23:15:51 -03002476 mutex_init(&dev->lock);
Dean Anderson38f993a2008-06-26 23:15:51 -03002477 /* grab usb_device and save it */
2478 dev->udev = usb_get_dev(interface_to_usbdev(interface));
2479 if (dev->udev == NULL) {
2480 dev_err(&interface->dev, "null usb device\n");
2481 retval = -ENODEV;
Dean Andersonff7e22d2010-04-08 23:38:07 -03002482 goto errorUDEV;
Dean Anderson38f993a2008-06-26 23:15:51 -03002483 }
Dean Andersond62e85a2010-04-09 19:54:26 -03002484 dprintk(1, "dev: %p, udev %p interface %p\n", dev,
Dean Anderson38f993a2008-06-26 23:15:51 -03002485 dev->udev, interface);
2486 dev->interface = interface;
2487 /* set up the endpoint information */
2488 iface_desc = interface->cur_altsetting;
2489 dprintk(1, "num endpoints %d\n", iface_desc->desc.bNumEndpoints);
2490 for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
2491 endpoint = &iface_desc->endpoint[i].desc;
2492 if (!dev->read_endpoint && usb_endpoint_is_bulk_in(endpoint)) {
2493 /* we found the bulk in endpoint */
2494 dev->read_endpoint = endpoint->bEndpointAddress;
2495 }
2496 }
2497
2498 if (!dev->read_endpoint) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002499 dev_err(&interface->dev, "Could not find bulk-in endpoint\n");
Dean Andersonff7e22d2010-04-08 23:38:07 -03002500 goto errorEP;
Dean Anderson38f993a2008-06-26 23:15:51 -03002501 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002502 init_timer(&dev->timer);
2503 dev->timer.function = s2255_timer;
2504 dev->timer.data = (unsigned long)dev->fw_data;
Dean Anderson38f993a2008-06-26 23:15:51 -03002505 init_waitqueue_head(&dev->fw_data->wait_fw);
Dean Anderson4de39f52010-03-03 19:39:19 -03002506 for (i = 0; i < MAX_CHANNELS; i++) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03002507 struct s2255_channel *channel = &dev->channel[i];
2508 dev->channel[i].idx = i;
2509 init_waitqueue_head(&channel->wait_setmode);
2510 init_waitqueue_head(&channel->wait_vidstatus);
Dean Anderson4de39f52010-03-03 19:39:19 -03002511 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002512
2513 dev->fw_data->fw_urb = usb_alloc_urb(0, GFP_KERNEL);
Dean Anderson38f993a2008-06-26 23:15:51 -03002514 if (!dev->fw_data->fw_urb) {
2515 dev_err(&interface->dev, "out of memory!\n");
Dean Andersonff7e22d2010-04-08 23:38:07 -03002516 goto errorFWURB;
Dean Anderson38f993a2008-06-26 23:15:51 -03002517 }
Dean Andersonff7e22d2010-04-08 23:38:07 -03002518
Dean Anderson38f993a2008-06-26 23:15:51 -03002519 dev->fw_data->pfw_data = kzalloc(CHUNK_SIZE, GFP_KERNEL);
2520 if (!dev->fw_data->pfw_data) {
2521 dev_err(&interface->dev, "out of memory!\n");
Dean Andersonff7e22d2010-04-08 23:38:07 -03002522 goto errorFWDATA2;
Dean Anderson38f993a2008-06-26 23:15:51 -03002523 }
2524 /* load the first chunk */
2525 if (request_firmware(&dev->fw_data->fw,
2526 FIRMWARE_FILE_NAME, &dev->udev->dev)) {
2527 printk(KERN_ERR "sensoray 2255 failed to get firmware\n");
Dean Andersonff7e22d2010-04-08 23:38:07 -03002528 goto errorREQFW;
Dean Anderson38f993a2008-06-26 23:15:51 -03002529 }
Dean Anderson14d96262008-08-25 13:58:55 -03002530 /* check the firmware is valid */
2531 fw_size = dev->fw_data->fw->size;
2532 pdata = (__le32 *) &dev->fw_data->fw->data[fw_size - 8];
Dean Anderson38f993a2008-06-26 23:15:51 -03002533
Dean Anderson14d96262008-08-25 13:58:55 -03002534 if (*pdata != S2255_FW_MARKER) {
2535 printk(KERN_INFO "Firmware invalid.\n");
2536 retval = -ENODEV;
Dean Andersonff7e22d2010-04-08 23:38:07 -03002537 goto errorFWMARKER;
Dean Anderson14d96262008-08-25 13:58:55 -03002538 } else {
2539 /* make sure firmware is the latest */
2540 __le32 *pRel;
2541 pRel = (__le32 *) &dev->fw_data->fw->data[fw_size - 4];
2542 printk(KERN_INFO "s2255 dsp fw version %x\n", *pRel);
Dan Carpenter3b2a6302012-02-17 02:44:10 -03002543 dev->dsp_fw_ver = le32_to_cpu(*pRel);
2544 if (dev->dsp_fw_ver < S2255_CUR_DSP_FWVER)
Dean Anderson4de39f52010-03-03 19:39:19 -03002545 printk(KERN_INFO "s2255: f2255usb.bin out of date.\n");
Dan Carpenter3b2a6302012-02-17 02:44:10 -03002546 if (dev->pid == 0x2257 &&
2547 dev->dsp_fw_ver < S2255_MIN_DSP_COLORFILTER)
Dean Andersonff7e22d2010-04-08 23:38:07 -03002548 printk(KERN_WARNING "s2255: 2257 requires firmware %d"
Dean Andersonfe85ce92010-06-01 19:12:07 -03002549 " or above.\n", S2255_MIN_DSP_COLORFILTER);
Dean Anderson14d96262008-08-25 13:58:55 -03002550 }
Dean Anderson14d96262008-08-25 13:58:55 -03002551 usb_reset_device(dev->udev);
Dean Anderson38f993a2008-06-26 23:15:51 -03002552 /* load 2255 board specific */
Dean Andersonabce21f2009-04-23 16:04:41 -03002553 retval = s2255_board_init(dev);
2554 if (retval)
Dean Andersonff7e22d2010-04-08 23:38:07 -03002555 goto errorBOARDINIT;
Dean Anderson38f993a2008-06-26 23:15:51 -03002556 spin_lock_init(&dev->slock);
Dean Anderson14d96262008-08-25 13:58:55 -03002557 s2255_fwload_start(dev, 0);
Dean Andersonff7e22d2010-04-08 23:38:07 -03002558 /* loads v4l specific */
2559 retval = s2255_probe_v4l(dev);
2560 if (retval)
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03002561 goto errorBOARDINIT;
Dean Anderson38f993a2008-06-26 23:15:51 -03002562 dev_info(&interface->dev, "Sensoray 2255 detected\n");
2563 return 0;
Dean Andersonff7e22d2010-04-08 23:38:07 -03002564errorBOARDINIT:
2565 s2255_board_shutdown(dev);
2566errorFWMARKER:
2567 release_firmware(dev->fw_data->fw);
2568errorREQFW:
2569 kfree(dev->fw_data->pfw_data);
2570errorFWDATA2:
2571 usb_free_urb(dev->fw_data->fw_urb);
2572errorFWURB:
2573 del_timer(&dev->timer);
2574errorEP:
2575 usb_put_dev(dev->udev);
2576errorUDEV:
2577 kfree(dev->fw_data);
Dean Andersonff7e22d2010-04-08 23:38:07 -03002578 mutex_destroy(&dev->lock);
2579errorFWDATA1:
2580 kfree(dev);
2581 printk(KERN_WARNING "Sensoray 2255 driver load failed: 0x%x\n", retval);
Dean Anderson38f993a2008-06-26 23:15:51 -03002582 return retval;
2583}
2584
2585/* disconnect routine. when board is removed physically or with rmmod */
2586static void s2255_disconnect(struct usb_interface *interface)
2587{
Dean Anderson65c6edb2010-04-20 17:21:32 -03002588 struct s2255_dev *dev = to_s2255_dev(usb_get_intfdata(interface));
Dean Anderson14d96262008-08-25 13:58:55 -03002589 int i;
Dean Andersonfe85ce92010-06-01 19:12:07 -03002590 int channels = atomic_read(&dev->num_channels);
Pete Eberleina19a5cd2010-12-20 19:18:59 -03002591 mutex_lock(&dev->lock);
Dean Andersonfe85ce92010-06-01 19:12:07 -03002592 v4l2_device_disconnect(&dev->v4l2_dev);
Pete Eberleina19a5cd2010-12-20 19:18:59 -03002593 mutex_unlock(&dev->lock);
Dean Andersond62e85a2010-04-09 19:54:26 -03002594 /*see comments in the uvc_driver.c usb disconnect function */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002595 atomic_inc(&dev->num_channels);
Dean Andersonff7e22d2010-04-08 23:38:07 -03002596 /* unregister each video device. */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002597 for (i = 0; i < channels; i++)
2598 video_unregister_device(&dev->channel[i].vdev);
Dean Andersonff7e22d2010-04-08 23:38:07 -03002599 /* wake up any of our timers */
Dean Anderson14d96262008-08-25 13:58:55 -03002600 atomic_set(&dev->fw_data->fw_state, S2255_FW_DISCONNECTING);
2601 wake_up(&dev->fw_data->wait_fw);
2602 for (i = 0; i < MAX_CHANNELS; i++) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03002603 dev->channel[i].setmode_ready = 1;
2604 wake_up(&dev->channel[i].wait_setmode);
2605 dev->channel[i].vidstatus_ready = 1;
2606 wake_up(&dev->channel[i].wait_vidstatus);
Dean Anderson14d96262008-08-25 13:58:55 -03002607 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03002608 if (atomic_dec_and_test(&dev->num_channels))
Dean Andersond62e85a2010-04-09 19:54:26 -03002609 s2255_destroy(dev);
Dean Andersonff7e22d2010-04-08 23:38:07 -03002610 dev_info(&interface->dev, "%s\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03002611}
2612
2613static struct usb_driver s2255_driver = {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002614 .name = S2255_DRIVER_NAME,
Dean Anderson38f993a2008-06-26 23:15:51 -03002615 .probe = s2255_probe,
2616 .disconnect = s2255_disconnect,
2617 .id_table = s2255_table,
2618};
2619
Greg Kroah-Hartmanecb3b2b2011-11-18 09:46:12 -08002620module_usb_driver(s2255_driver);
Dean Anderson38f993a2008-06-26 23:15:51 -03002621
2622MODULE_DESCRIPTION("Sensoray 2255 Video for Linux driver");
2623MODULE_AUTHOR("Dean Anderson (Sensoray Company Inc.)");
2624MODULE_LICENSE("GPL");
Mauro Carvalho Chehab64dc3c12011-06-25 11:28:37 -03002625MODULE_VERSION(S2255_VERSION);
Tim Gardner1bec9822012-07-24 16:52:27 -03002626MODULE_FIRMWARE(FIRMWARE_FILE_NAME);